summaryrefslogtreecommitdiffstats
path: root/drivers/net/wireless/mac80211_hwsim.c
diff options
context:
space:
mode:
authorJohannes Berg <johannes.berg@intel.com>2022-07-20 22:35:44 +0200
committerJohannes Berg <johannes.berg@intel.com>2022-07-22 14:28:20 +0200
commitc204d9df02020e2ed762d159112a4b15f6580e28 (patch)
tree3056e7eda1d6dbe8dc4460b34f5aaf128897350c /drivers/net/wireless/mac80211_hwsim.c
parent177577dbd2235a3a65f34a6cd618fe961a4dcaba (diff)
downloadlinux-c204d9df02020e2ed762d159112a4b15f6580e28.tar.bz2
wifi: mac80211_hwsim: handle links for wmediumd/virtio
For wmediumd/virtio, handle both the RX channel for links, as well as the link addresses when links are added/removed. Signed-off-by: Johannes Berg <johannes.berg@intel.com>
Diffstat (limited to 'drivers/net/wireless/mac80211_hwsim.c')
-rw-r--r--drivers/net/wireless/mac80211_hwsim.c40
1 files changed, 35 insertions, 5 deletions
diff --git a/drivers/net/wireless/mac80211_hwsim.c b/drivers/net/wireless/mac80211_hwsim.c
index 39dd437207ca..6e55f153ff26 100644
--- a/drivers/net/wireless/mac80211_hwsim.c
+++ b/drivers/net/wireless/mac80211_hwsim.c
@@ -2995,6 +2995,24 @@ static int mac80211_hwsim_change_vif_links(struct ieee80211_hw *hw,
u16 old_links, u16 new_links,
struct ieee80211_bss_conf *old[IEEE80211_MLD_MAX_NUM_LINKS])
{
+ unsigned long rem = old_links & ~new_links ?: BIT(0);
+ unsigned long add = new_links & ~old_links;
+ int i;
+
+ for_each_set_bit(i, &rem, IEEE80211_MLD_MAX_NUM_LINKS)
+ mac80211_hwsim_config_mac_nl(hw, old[i]->addr, false);
+
+ for_each_set_bit(i, &add, IEEE80211_MLD_MAX_NUM_LINKS) {
+ struct ieee80211_bss_conf *link_conf;
+
+ /* FIXME: figure out how to get the locking here */
+ link_conf = rcu_dereference_protected(vif->link_conf[i], 1);
+ if (WARN_ON(!link_conf))
+ continue;
+
+ mac80211_hwsim_config_mac_nl(hw, link_conf->addr, true);
+ }
+
return 0;
}
@@ -4478,16 +4496,28 @@ static int hwsim_cloned_frame_received_nl(struct sk_buff *skb_2,
/* A frame is received from user space */
memset(&rx_status, 0, sizeof(rx_status));
if (info->attrs[HWSIM_ATTR_FREQ]) {
+ struct tx_iter_data iter_data = {};
+
/* throw away off-channel packets, but allow both the temporary
- * ("hw" scan/remain-on-channel) and regular channel, since the
- * internal datapath also allows this
+ * ("hw" scan/remain-on-channel), regular channels and links,
+ * since the internal datapath also allows this
*/
- mutex_lock(&data2->mutex);
rx_status.freq = nla_get_u32(info->attrs[HWSIM_ATTR_FREQ]);
- if (rx_status.freq != channel->center_freq) {
- mutex_unlock(&data2->mutex);
+ iter_data.channel = ieee80211_get_channel(data2->hw->wiphy,
+ rx_status.freq);
+ if (!iter_data.channel)
goto out;
+
+ mutex_lock(&data2->mutex);
+ if (!hwsim_chans_compat(iter_data.channel, channel)) {
+ ieee80211_iterate_active_interfaces_atomic(
+ data2->hw, IEEE80211_IFACE_ITER_NORMAL,
+ mac80211_hwsim_tx_iter, &iter_data);
+ if (!iter_data.receive) {
+ mutex_unlock(&data2->mutex);
+ goto out;
+ }
}
mutex_unlock(&data2->mutex);
} else {