From: Sriram R <quic_srirrama@xxxxxxxxxxx> Currently bss_info_changed callback (which is registered with ath12k_mac_op_bss_info_changed()) is used to inform vif (struct ieee80211_vif) and bss (struct ieee80211_bss_conf) level configuration changes to driver. With MLO, vif level config as well each link config changes inside vif needs to be updated and mac80211 uses vif_cfg_changed() and link_info_changed() callback ops for the same, this is also backward compatible where mac80211 will update default link conf changes in case VIF is non-MLO. Rename ath12k_mac_op_bss_info_changed() to ath12k_mac_op_link_info_changed() and register the same to link_info_changed callback. Register ath12k_mac_op_vif_cfg_changed() to vif_cfg_changed() callback and handle all vif level configuration changes there. Also, currently ath12k_mac_op_bss_info_changed() uses deflink to apply the config or to cache the config based on the availability of corresponding vdev. With MLO multiple links can be affiliated to a vif/BSS, so use the link id provided by mac80211 to fetch the corresponding link to which the bss change was intended. For non-MLO link id 0 will be provided by mac80211 and deflink (which is mapped to ahvif->links[0]) will be used. Tested-on: QCN9274 hw2.0 PCI WLAN.WBE.1.0.1-00029-QCAHKSWPL_SILICONZ-1 Tested-on: WCN7850 hw2.0 PCI WLAN.HMT.1.0.c5-00481-QCAHMTSWPL_V1.0_V2.0_SILICONZ-3 Signed-off-by: Sriram R <quic_srirrama@xxxxxxxxxxx> Co-developed-by: Rameshkumar Sundaram <quic_ramess@xxxxxxxxxxx> Signed-off-by: Rameshkumar Sundaram <quic_ramess@xxxxxxxxxxx> Signed-off-by: Kalle Valo <quic_kvalo@xxxxxxxxxxx> --- drivers/net/wireless/ath/ath12k/mac.c | 61 ++++++++++++++++++++------- 1 file changed, 46 insertions(+), 15 deletions(-) diff --git a/drivers/net/wireless/ath/ath12k/mac.c b/drivers/net/wireless/ath/ath12k/mac.c index fb4b800435f8..c8a330eb0d4b 100644 --- a/drivers/net/wireless/ath/ath12k/mac.c +++ b/drivers/net/wireless/ath/ath12k/mac.c @@ -3150,6 +3150,40 @@ static int ath12k_mac_fils_discovery(struct ath12k_link_vif *arvif, return ret; } +static void ath12k_mac_op_vif_cfg_changed(struct ieee80211_hw *hw, + struct ieee80211_vif *vif, + u64 changed) +{ + struct ath12k_vif *ahvif = ath12k_vif_to_ahvif(vif); + unsigned long links = ahvif->links_map; + struct ath12k_link_vif *arvif; + struct ath12k *ar; + u8 link_id; + + lockdep_assert_wiphy(hw->wiphy); + + if (changed & BSS_CHANGED_SSID && vif->type == NL80211_IFTYPE_AP) { + ahvif->u.ap.ssid_len = vif->cfg.ssid_len; + if (vif->cfg.ssid_len) + memcpy(ahvif->u.ap.ssid, vif->cfg.ssid, vif->cfg.ssid_len); + } + + if (changed & BSS_CHANGED_ASSOC) { + for_each_set_bit(link_id, &links, IEEE80211_MLD_MAX_NUM_LINKS) { + arvif = wiphy_dereference(hw->wiphy, ahvif->link[link_id]); + if (!arvif || !arvif->ar) + continue; + + ar = arvif->ar; + + if (vif->cfg.assoc) + ath12k_bss_assoc(ar, arvif, &vif->bss_conf); + else + ath12k_bss_disassoc(ar, arvif); + } + } +} + static void ath12k_mac_vif_setup_ps(struct ath12k_link_vif *arvif) { struct ath12k *ar = arvif->ar; @@ -3497,33 +3531,27 @@ static void ath12k_ahvif_put_link_cache(struct ath12k_vif *ahvif, u8 link_id) ahvif->cache[link_id] = NULL; } -static void ath12k_mac_op_bss_info_changed(struct ieee80211_hw *hw, - struct ieee80211_vif *vif, - struct ieee80211_bss_conf *info, - u64 changed) +static void ath12k_mac_op_link_info_changed(struct ieee80211_hw *hw, + struct ieee80211_vif *vif, + struct ieee80211_bss_conf *info, + u64 changed) { struct ath12k *ar; struct ath12k_vif *ahvif = ath12k_vif_to_ahvif(vif); struct ath12k_vif_cache *cache; struct ath12k_link_vif *arvif; + u8 link_id = info->link_id; lockdep_assert_wiphy(hw->wiphy); - /* TODO use info->link_id and fetch corresponding ahvif->link[] - * with MLO support. - */ - arvif = &ahvif->deflink; - ar = ath12k_get_ar_by_vif(hw, vif); + arvif = wiphy_dereference(hw->wiphy, ahvif->link[link_id]); /* if the vdev is not created on a certain radio, * cache the info to be updated later on vdev creation */ - if (!ar) { - /* TODO Once link vif is fetched based on link id from - * info, avoid using ATH12K_DEFAULT_LINK_ID. - */ - cache = ath12k_ahvif_get_link_cache(ahvif, ATH12K_DEFAULT_LINK_ID); + if (!arvif || !arvif->is_created) { + cache = ath12k_ahvif_get_link_cache(ahvif, link_id); if (!cache) return; @@ -3532,6 +3560,8 @@ static void ath12k_mac_op_bss_info_changed(struct ieee80211_hw *hw, return; } + ar = arvif->ar; + ath12k_mac_bss_info_changed(ar, arvif, info, changed); } @@ -8888,7 +8918,8 @@ static const struct ieee80211_ops ath12k_ops = { .remove_interface = ath12k_mac_op_remove_interface, .update_vif_offload = ath12k_mac_op_update_vif_offload, .config = ath12k_mac_op_config, - .bss_info_changed = ath12k_mac_op_bss_info_changed, + .link_info_changed = ath12k_mac_op_link_info_changed, + .vif_cfg_changed = ath12k_mac_op_vif_cfg_changed, .configure_filter = ath12k_mac_op_configure_filter, .hw_scan = ath12k_mac_op_hw_scan, .cancel_hw_scan = ath12k_mac_op_cancel_hw_scan, -- 2.39.5