Commit 8f500fbc authored by Ayala Beker's avatar Ayala Beker Committed by Johannes Berg

wifi: mac80211: process and save negotiated TID to Link mapping request

An MLD may send TID-to-Link mapping request frame to negotiate
TID to link mapping with a peer MLD.
Support handling negotiated TID-to-Link mapping request frame
by parsing the frame, asking the driver whether it supports the
received mapping or not, and sending a TID-to-Link mapping response
to the AP MLD.
Theoretically, links that became inactive due to the received TID-to-Link
mapping request, can be selected to be activated but this would require
tearing down the negotiated TID-to-Link mapping, which is still not
supported.
Signed-off-by: default avatarAyala Beker <ayala.beker@intel.com>
Reviewed-by: default avatarJohannes Berg <johannes.berg@intel.com>
Reviewed-by: default avatarGregory Greenman <gregory.greenman@intel.com>
Signed-off-by: default avatarMiri Korenblit <miriam.rachel.korenblit@intel.com>
Link: https://msgid.link/20240102213313.0bc1a24fcc9d.Ie72e47dc6f8c77d4a2f0947b775ef6367fe0edac@changeidSigned-off-by: default avatarJohannes Berg <johannes.berg@intel.com>
parent 83e897a9
......@@ -342,6 +342,7 @@ struct ieee80211_vif_chanctx_switch {
* status changed.
* @BSS_CHANGED_EHT_PUNCTURING: The channel puncturing bitmap changed.
* @BSS_CHANGED_MLD_VALID_LINKS: MLD valid links status changed.
* @BSS_CHANGED_MLD_TTLM: TID to link mapping was changed
*/
enum ieee80211_bss_change {
BSS_CHANGED_ASSOC = 1<<0,
......@@ -378,6 +379,7 @@ enum ieee80211_bss_change {
BSS_CHANGED_UNSOL_BCAST_PROBE_RESP = 1<<31,
BSS_CHANGED_EHT_PUNCTURING = BIT_ULL(32),
BSS_CHANGED_MLD_VALID_LINKS = BIT_ULL(33),
BSS_CHANGED_MLD_TTLM = BIT_ULL(34),
/* when adding here, make sure to change ieee80211_reconfig */
};
......@@ -1845,6 +1847,35 @@ struct ieee80211_vif_cfg {
u8 ap_addr[ETH_ALEN] __aligned(2);
};
#define IEEE80211_TTLM_NUM_TIDS 8
/**
* struct ieee80211_neg_ttlm - negotiated TID to link map info
*
* @downlink: bitmap of active links per TID for downlink, or 0 if mapping for
* this TID is not included.
* @uplink: bitmap of active links per TID for uplink, or 0 if mapping for this
* TID is not included.
* @valid: info is valid or not.
*/
struct ieee80211_neg_ttlm {
u16 downlink[IEEE80211_TTLM_NUM_TIDS];
u16 uplink[IEEE80211_TTLM_NUM_TIDS];
bool valid;
};
/**
* enum ieee80211_neg_ttlm_res - return value for negotiated TTLM handling
* @NEG_TTLM_RES_ACCEPT: accept the request
* @NEG_TTLM_RES_REJECT: reject the request
* @NEG_TTLM_RES_SUGGEST_PREFERRED: reject and suggest a new mapping
*/
enum ieee80211_neg_ttlm_res {
NEG_TTLM_RES_ACCEPT,
NEG_TTLM_RES_REJECT,
NEG_TTLM_RES_SUGGEST_PREFERRED
};
/**
* struct ieee80211_vif - per-interface data
*
......@@ -1863,6 +1894,11 @@ struct ieee80211_vif_cfg {
* API calls meant for that purpose.
* @dormant_links: bitmap of valid but disabled links, or 0 for non-MLO.
* Must be a subset of valid_links.
* @suspended_links: subset of dormant_links representing links that are
* suspended.
* 0 for non-MLO.
* @neg_ttlm: negotiated TID to link mapping info.
* see &struct ieee80211_neg_ttlm.
* @addr: address of this interface
* @p2p: indicates whether this AP or STA interface is a p2p
* interface, i.e. a GO or p2p-sta respectively
......@@ -1900,7 +1936,8 @@ struct ieee80211_vif {
struct ieee80211_vif_cfg cfg;
struct ieee80211_bss_conf bss_conf;
struct ieee80211_bss_conf __rcu *link_conf[IEEE80211_MLD_MAX_NUM_LINKS];
u16 valid_links, active_links, dormant_links;
u16 valid_links, active_links, dormant_links, suspended_links;
struct ieee80211_neg_ttlm neg_ttlm;
u8 addr[ETH_ALEN] __aligned(2);
bool p2p;
......@@ -4293,6 +4330,10 @@ struct ieee80211_prep_tx_info {
* flow offloading for flows originating from the vif.
* Note that the driver must not assume that the vif driver_data is valid
* at this point, since the callback can be called during netdev teardown.
* @can_neg_ttlm: for managed interface, requests the driver to determine
* if the requested TID-To-Link mapping can be accepted or not.
* If it's not accepted the driver may suggest a preferred mapping and
* modify @ttlm parameter with the suggested TID-to-Link mapping.
*/
struct ieee80211_ops {
void (*tx)(struct ieee80211_hw *hw,
......@@ -4673,6 +4714,9 @@ struct ieee80211_ops {
struct net_device *dev,
enum tc_setup_type type,
void *type_data);
enum ieee80211_neg_ttlm_res
(*can_neg_ttlm)(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
struct ieee80211_neg_ttlm *ttlm);
};
/**
......
......@@ -1695,4 +1695,23 @@ int drv_change_sta_links(struct ieee80211_local *local,
struct ieee80211_sta *sta,
u16 old_links, u16 new_links);
static inline enum ieee80211_neg_ttlm_res
drv_can_neg_ttlm(struct ieee80211_local *local,
struct ieee80211_sub_if_data *sdata,
struct ieee80211_neg_ttlm *neg_ttlm)
{
enum ieee80211_neg_ttlm_res res = NEG_TTLM_RES_REJECT;
might_sleep();
if (!check_sdata_in_driver(sdata))
return -EIO;
trace_drv_can_neg_ttlm(local, sdata, neg_ttlm);
if (local->ops->can_neg_ttlm)
res = local->ops->can_neg_ttlm(&local->hw, &sdata->vif,
neg_ttlm);
trace_drv_neg_ttlm_res(local, sdata, res, neg_ttlm);
return res;
}
#endif /* __MAC80211_DRIVER_OPS */
......@@ -2603,6 +2603,8 @@ ieee80211_eht_cap_ie_to_sta_eht_cap(struct ieee80211_sub_if_data *sdata,
const struct ieee80211_eht_cap_elem *eht_cap_ie_elem,
u8 eht_cap_len,
struct link_sta_info *link_sta);
void ieee80211_process_neg_ttlm_req(struct ieee80211_sub_if_data *sdata,
struct ieee80211_mgmt *mgmt, size_t len);
void ieee80211_check_wbrf_support(struct ieee80211_local *local);
void ieee80211_add_wbrf(struct ieee80211_local *local, struct cfg80211_chan_def *chandef);
......
......@@ -1546,6 +1546,18 @@ static void ieee80211_iface_process_skb(struct ieee80211_local *local,
default:
break;
}
} else if (ieee80211_is_action(mgmt->frame_control) &&
mgmt->u.action.category == WLAN_CATEGORY_PROTECTED_EHT) {
if (sdata->vif.type == NL80211_IFTYPE_STATION) {
switch (mgmt->u.action.u.ttlm_req.action_code) {
case WLAN_PROTECTED_EHT_ACTION_TTLM_REQ:
ieee80211_process_neg_ttlm_req(sdata, mgmt,
skb->len);
break;
default:
break;
}
}
} else if (ieee80211_is_ext(mgmt->frame_control)) {
if (sdata->vif.type == NL80211_IFTYPE_STATION)
ieee80211_sta_rx_queued_ext(sdata, skb);
......
......@@ -208,7 +208,8 @@ int ieee80211_hw_config(struct ieee80211_local *local, u32 changed)
BSS_CHANGED_IBSS |\
BSS_CHANGED_ARP_FILTER |\
BSS_CHANGED_SSID |\
BSS_CHANGED_MLD_VALID_LINKS)
BSS_CHANGED_MLD_VALID_LINKS |\
BSS_CHANGED_MLD_TTLM)
void ieee80211_bss_info_change_notify(struct ieee80211_sub_if_data *sdata,
u64 changed)
......
This diff is collapsed.
......@@ -3763,6 +3763,20 @@ ieee80211_rx_h_action(struct ieee80211_rx_data *rx)
break;
}
break;
case WLAN_CATEGORY_PROTECTED_EHT:
switch (mgmt->u.action.u.ttlm_req.action_code) {
case WLAN_PROTECTED_EHT_ACTION_TTLM_REQ:
if (sdata->vif.type != NL80211_IFTYPE_STATION)
break;
if (len < offsetofend(typeof(*mgmt),
u.action.u.ttlm_req))
goto invalid;
goto queue;
default:
break;
}
break;
}
return RX_CONTINUE;
......
......@@ -3088,6 +3088,58 @@ TRACE_EVENT(stop_queue,
)
);
TRACE_EVENT(drv_can_neg_ttlm,
TP_PROTO(struct ieee80211_local *local,
struct ieee80211_sub_if_data *sdata,
struct ieee80211_neg_ttlm *neg_ttlm),
TP_ARGS(local, sdata, neg_ttlm),
TP_STRUCT__entry(LOCAL_ENTRY
VIF_ENTRY
__array(u16, downlink, sizeof(u16) * 8)
__array(u16, uplink, sizeof(u16) * 8)
),
TP_fast_assign(LOCAL_ASSIGN;
VIF_ASSIGN;
memcpy(__entry->downlink, neg_ttlm->downlink,
sizeof(neg_ttlm->downlink));
memcpy(__entry->uplink, neg_ttlm->uplink,
sizeof(neg_ttlm->uplink));
),
TP_printk(LOCAL_PR_FMT ", " VIF_PR_FMT, LOCAL_PR_ARG, VIF_PR_ARG)
);
TRACE_EVENT(drv_neg_ttlm_res,
TP_PROTO(struct ieee80211_local *local,
struct ieee80211_sub_if_data *sdata,
enum ieee80211_neg_ttlm_res res,
struct ieee80211_neg_ttlm *neg_ttlm),
TP_ARGS(local, sdata, res, neg_ttlm),
TP_STRUCT__entry(LOCAL_ENTRY
VIF_ENTRY
__field(u32, res)
__array(u16, downlink, sizeof(u16) * 8)
__array(u16, uplink, sizeof(u16) * 8)
),
TP_fast_assign(LOCAL_ASSIGN;
VIF_ASSIGN;
__entry->res = res;
memcpy(__entry->downlink, neg_ttlm->downlink,
sizeof(neg_ttlm->downlink));
memcpy(__entry->uplink, neg_ttlm->uplink,
sizeof(neg_ttlm->uplink));
),
TP_printk(LOCAL_PR_FMT VIF_PR_FMT " response: %d\n ",
LOCAL_PR_ARG, VIF_PR_ARG, __entry->res
)
);
#endif /* !__MAC80211_DRIVER_TRACE || TRACE_HEADER_MULTI_READ */
#undef TRACE_INCLUDE_PATH
......
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