diff --git a/mt7925/main.c b/mt7925/main.c index 5ea13289..39c08e21 100644 --- a/mt7925/main.c +++ b/mt7925/main.c @@ -964,6 +964,21 @@ static int mt7925_mac_link_sta_add(struct mt76_dev *mdev, link_conf = mt792x_vif_to_bss_conf(vif, link_id); + /* NAN_DATA (NDI) peers skip association - fill link_sta caps + * from sband and push BSS_INFO with correct phymode + RLM. + */ + if (vif->type == NL80211_IFTYPE_NAN_DATA) { + struct ieee80211_chanctx_conf *nan_ctx; + + nan_ctx = mt7925_nan_seed_link_sta(dev, link_sta); + mconf->mt76.ctx = nan_ctx; + + ret = mt7925_mcu_add_bss_info(&dev->phy, nan_ctx, + link_conf, link_sta, true); + if (ret) + goto out_pm; + } + /* should update bss info before STA add */ if (vif->type == NL80211_IFTYPE_STATION && !link_sta->sta->tdls) { struct mt792x_link_sta *mlink_bc; @@ -2587,8 +2602,8 @@ static int mt7925_start_nan(struct ieee80211_hw *hw, cfg80211_chandef_create(&link_conf->chanreq.oper, chan, NL80211_CHAN_NO_HT); - err = mt7925_mcu_add_bss_info(&dev->phy, NULL, link_conf, - NULL, true); + err = mt7925_mcu_add_bss_info(&dev->phy, NULL, + link_conf, NULL, true); if (err < 0) goto out; diff --git a/mt7925/nan.c b/mt7925/nan.c index 5fa0f11d..1adef4d5 100644 --- a/mt7925/nan.c +++ b/mt7925/nan.c @@ -267,6 +267,68 @@ int mt7925_nan_update_phy_setting(struct mt792x_dev *dev) &req, sizeof(req), true); } +struct ieee80211_chanctx_conf * +mt7925_nan_seed_link_sta(struct mt792x_dev *dev, + struct ieee80211_link_sta *link_sta) +{ + struct ieee80211_supported_band *sband_2g, *sband_5g; + struct ieee80211_chanctx_conf *nan_ctx = NULL; + struct ieee80211_vif *nan_vif = dev->nan_vif; + + /* Fill HT cap from 2G sband */ + sband_2g = dev->mphy.hw->wiphy->bands[NL80211_BAND_2GHZ]; + sband_5g = dev->mphy.hw->wiphy->bands[NL80211_BAND_5GHZ]; + if (sband_2g) + link_sta->ht_cap = sband_2g->ht_cap; + + link_sta->sta->wme = true; + link_sta->rx_nss = hweight8(dev->mphy.antenna_mask); + + /* Get chanctx from NAN schedule. + * Prefer 5G committed slot for wider BW (VHT), fallback + * to first valid slot if no 5G data slot is scheduled. + */ + if (nan_vif) { + struct ieee80211_nan_channel **slots = + nan_vif->cfg.nan_sched.schedule; + int i; + + for (i = 0; i < CFG80211_NAN_SCHED_NUM_TIME_SLOTS; i++) { + struct ieee80211_chanctx_conf *ctx; + + if (!slots[i] || IS_ERR(slots[i]) || + !slots[i]->chanctx_conf) + continue; + + ctx = slots[i]->chanctx_conf; + if (!nan_ctx) + nan_ctx = ctx; + if (ctx->def.chan->band == NL80211_BAND_5GHZ) { + nan_ctx = ctx; + break; + } + } + } + + /* Capability describes what the device can do and must not be + * filtered by the current schedule - firmware gates the VHT rate + * mode per the data schedule and re-derives it on schedule + * change, which only works if the caps are present up front. + */ + if (sband_5g) + link_sta->vht_cap = sband_5g->vht_cap; + + /* Bandwidth here is the capability ceiling, not the operating + * width - the per-slot operating bandwidth follows the current + * slot channel via the firmware RLM sync, so deriving it from + * the schedule at STA-add time would cap a later 5 GHz schedule + * at the bring-up width. + */ + link_sta->bandwidth = IEEE80211_STA_RX_BW_80; + + return nan_ctx; +} + int mt7925_nan_enable(struct ieee80211_vif *vif, struct mt792x_dev *dev, struct cfg80211_nan_conf *conf) diff --git a/mt7925/nan.h b/mt7925/nan.h index f9644945..9a0cd1d0 100644 --- a/mt7925/nan.h +++ b/mt7925/nan.h @@ -479,6 +479,10 @@ struct mt7925_nan_update_phy_setting_tlv { int mt7925_nan_update_phy_setting(struct mt792x_dev *dev); +struct ieee80211_chanctx_conf * +mt7925_nan_seed_link_sta(struct mt792x_dev *dev, + struct ieee80211_link_sta *link_sta); + int mt7925_nan_enable(struct ieee80211_vif *vif, struct mt792x_dev *dev, struct cfg80211_nan_conf *conf);