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: Johannes Berg <johannes.berg@intel.com>
This commit is contained in:
Johannes Berg 2022-06-09 22:05:07 +02:00
parent eef25a6679
commit 69d41b5a9c
2 changed files with 39 additions and 2 deletions

View File

@ -867,6 +867,10 @@ enum mac80211_tx_info_flags {
* @IEEE80211_TX_CTRL_DONT_REORDER: This frame should not be reordered
* relative to other frames that have this flag set, independent
* 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.
*/
@ -880,8 +884,11 @@ enum mac80211_tx_control_flags {
IEEE80211_TX_INTCFL_NEED_TXPROCESSING = BIT(6),
IEEE80211_TX_CTRL_NO_SEQNO = BIT(7),
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
*

View File

@ -2889,7 +2889,9 @@ static struct sk_buff *ieee80211_build_hdr(struct ieee80211_sub_if_data *sdata,
info->flags = info_flags;
info->ack_frame_id = info_id;
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;
free:
@ -3558,7 +3560,9 @@ static bool ieee80211_xmit_fast(struct ieee80211_sub_if_data *sdata,
info->flags = IEEE80211_TX_CTL_FIRST_FRAGMENT |
IEEE80211_TX_CTL_DONTFRAG |
(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
if (local->force_tx_status)
@ -5668,7 +5672,9 @@ void __ieee80211_tx_skb_tid_band(struct ieee80211_sub_if_data *sdata,
struct sk_buff *skb, int tid,
enum nl80211_band band)
{
const struct ieee80211_hdr *hdr = (void *)skb->data;
int ac = ieee80211_ac_from_tid(tid);
unsigned int link;
skb_reset_mac_header(skb);
skb_set_queue_mapping(skb, ac);
@ -5676,6 +5682,30 @@ void __ieee80211_tx_skb_tid_band(struct ieee80211_sub_if_data *sdata,
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,
* and while we can handle concurrent transmissions locking