summaryrefslogtreecommitdiff
path: root/drivers/net/wireless/mac80211_hwsim.c
diff options
context:
space:
mode:
authorAndrei Otcheretianski <andrei.otcheretianski@intel.com>2022-06-14 17:17:20 +0300
committerJohannes Berg <johannes.berg@intel.com>2022-07-15 11:43:24 +0200
commit2ab60f49eb4d87998be602ca09c0e88b0808142b (patch)
tree9d4f73f02f2b650e514ce17dc8ee9c6d9cdc4c91 /drivers/net/wireless/mac80211_hwsim.c
parentaea9a6088ae46e77527716496ab259ddfa320148 (diff)
wifi: mac80211_hwsim: use MLO link ID for TX
Use the link ID provided in TX frame metadata to select the correct channel. For now, always select the link with the lowest link ID and do some address translation. Signed-off-by: Andrei Otcheretianski <andrei.otcheretianski@intel.com> 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.c53
1 files changed, 51 insertions, 2 deletions
diff --git a/drivers/net/wireless/mac80211_hwsim.c b/drivers/net/wireless/mac80211_hwsim.c
index 4a3d42b3099f..36b8c95150ae 100644
--- a/drivers/net/wireless/mac80211_hwsim.c
+++ b/drivers/net/wireless/mac80211_hwsim.c
@@ -1700,6 +1700,42 @@ static bool mac80211_hwsim_tx_frame_no_nl(struct ieee80211_hw *hw,
return ack;
}
+static struct ieee80211_bss_conf *
+mac80211_hwsim_select_tx_link(struct mac80211_hwsim_data *data,
+ struct ieee80211_vif *vif,
+ struct ieee80211_sta *sta,
+ struct ieee80211_hdr *hdr)
+{
+ int i;
+
+ for (i = 0; i < ARRAY_SIZE(vif->link_conf); i++) {
+ struct ieee80211_link_sta *link_sta = NULL;
+ struct ieee80211_bss_conf *bss_conf;
+
+ bss_conf = rcu_dereference(vif->link_conf[i]);
+ if (!bss_conf)
+ continue;
+
+ if (sta) {
+ link_sta = rcu_dereference(sta->link[i]);
+ if (!link_sta)
+ continue;
+ }
+
+ if (!is_multicast_ether_addr(hdr->addr1)) {
+ if (link_sta)
+ ether_addr_copy(hdr->addr1, link_sta->addr);
+ ether_addr_copy(hdr->addr2, bss_conf->addr);
+ } else {
+ /* TODO: Handle multicast frames */
+ }
+
+ return bss_conf;
+ }
+
+ return NULL;
+}
+
static void mac80211_hwsim_tx(struct ieee80211_hw *hw,
struct ieee80211_tx_control *control,
struct sk_buff *skb)
@@ -1726,8 +1762,21 @@ static void mac80211_hwsim_tx(struct ieee80211_hw *hw,
channel = data->tmp_chan;
} else {
struct ieee80211_bss_conf *bss_conf;
-
- bss_conf = &txi->control.vif->bss_conf;
+ u8 link = u32_get_bits(IEEE80211_SKB_CB(skb)->control.flags,
+ IEEE80211_TX_CTRL_MLO_LINK);
+
+ if (link != IEEE80211_LINK_UNSPECIFIED)
+ bss_conf = rcu_dereference(txi->control.vif->link_conf[link]);
+ else
+ bss_conf = mac80211_hwsim_select_tx_link(data,
+ txi->control.vif,
+ control->sta,
+ hdr);
+
+ if (WARN_ON(!bss_conf)) {
+ ieee80211_free_txskb(hw, skb);
+ return;
+ }
chanctx_conf = rcu_dereference(bss_conf->chanctx_conf);
if (chanctx_conf) {