Commit 69d41b5a authored by Johannes Berg's avatar Johannes Berg

wifi: mac80211: add MLO link ID to TX frame metadata

Take a few bits out of the control.flags to add the link ID
to TX frame metadata, so drivers don't need to look it up
by the address themselves. Implement that lookup where it's
needed, for internal frame TX, and set it to "unspecified"
for data transmissions.
Signed-off-by: default avatarJohannes Berg <johannes.berg@intel.com>
parent eef25a66
...@@ -867,6 +867,10 @@ enum mac80211_tx_info_flags { ...@@ -867,6 +867,10 @@ enum mac80211_tx_info_flags {
* @IEEE80211_TX_CTRL_DONT_REORDER: This frame should not be reordered * @IEEE80211_TX_CTRL_DONT_REORDER: This frame should not be reordered
* relative to other frames that have this flag set, independent * relative to other frames that have this flag set, independent
* of their QoS TID or other priority field values. * of their QoS TID or other priority field values.
* @IEEE80211_TX_CTRL_MLO_LINK: If not @IEEE80211_LINK_UNSPECIFIED, this
* frame should be transmitted on the specific link. This really is
* only relevant for frames that do not have data present, and is
* also not used for 802.3 format frames.
* *
* These flags are used in tx_info->control.flags. * These flags are used in tx_info->control.flags.
*/ */
...@@ -880,8 +884,11 @@ enum mac80211_tx_control_flags { ...@@ -880,8 +884,11 @@ enum mac80211_tx_control_flags {
IEEE80211_TX_INTCFL_NEED_TXPROCESSING = BIT(6), IEEE80211_TX_INTCFL_NEED_TXPROCESSING = BIT(6),
IEEE80211_TX_CTRL_NO_SEQNO = BIT(7), IEEE80211_TX_CTRL_NO_SEQNO = BIT(7),
IEEE80211_TX_CTRL_DONT_REORDER = BIT(8), IEEE80211_TX_CTRL_DONT_REORDER = BIT(8),
IEEE80211_TX_CTRL_MLO_LINK = 0xf0000000,
}; };
#define IEEE80211_LINK_UNSPECIFIED 0xf
/** /**
* enum mac80211_tx_status_flags - flags to describe transmit status * enum mac80211_tx_status_flags - flags to describe transmit status
* *
......
...@@ -2889,7 +2889,9 @@ static struct sk_buff *ieee80211_build_hdr(struct ieee80211_sub_if_data *sdata, ...@@ -2889,7 +2889,9 @@ static struct sk_buff *ieee80211_build_hdr(struct ieee80211_sub_if_data *sdata,
info->flags = info_flags; info->flags = info_flags;
info->ack_frame_id = info_id; info->ack_frame_id = info_id;
info->band = band; info->band = band;
info->control.flags = ctrl_flags; info->control.flags = ctrl_flags |
u32_encode_bits(IEEE80211_LINK_UNSPECIFIED,
IEEE80211_TX_CTRL_MLO_LINK);
return skb; return skb;
free: free:
...@@ -3558,7 +3560,9 @@ static bool ieee80211_xmit_fast(struct ieee80211_sub_if_data *sdata, ...@@ -3558,7 +3560,9 @@ static bool ieee80211_xmit_fast(struct ieee80211_sub_if_data *sdata,
info->flags = IEEE80211_TX_CTL_FIRST_FRAGMENT | info->flags = IEEE80211_TX_CTL_FIRST_FRAGMENT |
IEEE80211_TX_CTL_DONTFRAG | IEEE80211_TX_CTL_DONTFRAG |
(tid_tx ? IEEE80211_TX_CTL_AMPDU : 0); (tid_tx ? IEEE80211_TX_CTL_AMPDU : 0);
info->control.flags = IEEE80211_TX_CTRL_FAST_XMIT; info->control.flags = IEEE80211_TX_CTRL_FAST_XMIT |
u32_encode_bits(IEEE80211_LINK_UNSPECIFIED,
IEEE80211_TX_CTRL_MLO_LINK);
#ifdef CONFIG_MAC80211_DEBUGFS #ifdef CONFIG_MAC80211_DEBUGFS
if (local->force_tx_status) if (local->force_tx_status)
...@@ -5668,7 +5672,9 @@ void __ieee80211_tx_skb_tid_band(struct ieee80211_sub_if_data *sdata, ...@@ -5668,7 +5672,9 @@ void __ieee80211_tx_skb_tid_band(struct ieee80211_sub_if_data *sdata,
struct sk_buff *skb, int tid, struct sk_buff *skb, int tid,
enum nl80211_band band) enum nl80211_band band)
{ {
const struct ieee80211_hdr *hdr = (void *)skb->data;
int ac = ieee80211_ac_from_tid(tid); int ac = ieee80211_ac_from_tid(tid);
unsigned int link;
skb_reset_mac_header(skb); skb_reset_mac_header(skb);
skb_set_queue_mapping(skb, ac); skb_set_queue_mapping(skb, ac);
...@@ -5676,6 +5682,30 @@ void __ieee80211_tx_skb_tid_band(struct ieee80211_sub_if_data *sdata, ...@@ -5676,6 +5682,30 @@ void __ieee80211_tx_skb_tid_band(struct ieee80211_sub_if_data *sdata,
skb->dev = sdata->dev; skb->dev = sdata->dev;
BUILD_BUG_ON(IEEE80211_LINK_UNSPECIFIED < IEEE80211_MLD_MAX_NUM_LINKS);
BUILD_BUG_ON(!FIELD_FIT(IEEE80211_TX_CTRL_MLO_LINK,
IEEE80211_LINK_UNSPECIFIED));
if (!sdata->vif.valid_links) {
link = 0;
} else if (memcmp(sdata->vif.addr, hdr->addr2, ETH_ALEN) == 0) {
/* address from the MLD */
link = IEEE80211_LINK_UNSPECIFIED;
} else {
/* otherwise must be addressed from a link */
for (link = 0; link < ARRAY_SIZE(sdata->vif.link_conf); link++) {
if (memcmp(sdata->vif.link_conf[link]->addr,
hdr->addr2, ETH_ALEN) == 0)
break;
}
if (WARN_ON_ONCE(link == ARRAY_SIZE(sdata->vif.link_conf)))
link = ffs(sdata->vif.valid_links) - 1;
}
IEEE80211_SKB_CB(skb)->control.flags |=
u32_encode_bits(link, IEEE80211_TX_CTRL_MLO_LINK);
/* /*
* The other path calling ieee80211_xmit is from the tasklet, * The other path calling ieee80211_xmit is from the tasklet,
* and while we can handle concurrent transmissions locking * and while we can handle concurrent transmissions locking
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment