wifi: mac80211: add support for tearing down negotiated TTLM
In order to activate a link that is currently inactive due to a negotiated TTLM request, need to first tear down the negotiated TTLM request. Add support for sending TTLM teardown request and update the links state accordingly. Signed-off-by: Ayala Beker <ayala.beker@intel.com> Reviewed-by: Johannes Berg <johannes.berg@intel.com> Signed-off-by: Miri Korenblit <miriam.rachel.korenblit@intel.com> Link: https://msgid.link/20240318184907.d480cbf46fcf.Idedad472469d2c27dd2a088cf80a13a1e1cf9b78@changeid Signed-off-by: Johannes Berg <johannes.berg@intel.com>
This commit is contained in:
parent
97f8df4db4
commit
a17a58ad2f
@ -7591,6 +7591,15 @@ int ieee80211_set_active_links(struct ieee80211_vif *vif, u16 active_links);
|
|||||||
void ieee80211_set_active_links_async(struct ieee80211_vif *vif,
|
void ieee80211_set_active_links_async(struct ieee80211_vif *vif,
|
||||||
u16 active_links);
|
u16 active_links);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ieee80211_send_teardown_neg_ttlm - tear down a negotiated TTLM request
|
||||||
|
* @vif: the interface on which the tear down request should be sent.
|
||||||
|
*
|
||||||
|
* This function can be used to tear down a previously accepted negotiated
|
||||||
|
* TTLM request.
|
||||||
|
*/
|
||||||
|
void ieee80211_send_teardown_neg_ttlm(struct ieee80211_vif *vif);
|
||||||
|
|
||||||
/* for older drivers - let's not document these ... */
|
/* for older drivers - let's not document these ... */
|
||||||
int ieee80211_emulate_add_chanctx(struct ieee80211_hw *hw,
|
int ieee80211_emulate_add_chanctx(struct ieee80211_hw *hw,
|
||||||
struct ieee80211_chanctx_conf *ctx);
|
struct ieee80211_chanctx_conf *ctx);
|
||||||
|
@ -89,6 +89,7 @@ enum ieee80211_status_data {
|
|||||||
IEEE80211_STATUS_TYPE_MASK = 0x00f,
|
IEEE80211_STATUS_TYPE_MASK = 0x00f,
|
||||||
IEEE80211_STATUS_TYPE_INVALID = 0,
|
IEEE80211_STATUS_TYPE_INVALID = 0,
|
||||||
IEEE80211_STATUS_TYPE_SMPS = 1,
|
IEEE80211_STATUS_TYPE_SMPS = 1,
|
||||||
|
IEEE80211_STATUS_TYPE_NEG_TTLM = 2,
|
||||||
IEEE80211_STATUS_SUBDATA_MASK = 0xff0,
|
IEEE80211_STATUS_SUBDATA_MASK = 0xff0,
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -595,6 +596,7 @@ struct ieee80211_if_managed {
|
|||||||
/* TID-to-link mapping support */
|
/* TID-to-link mapping support */
|
||||||
struct wiphy_delayed_work ttlm_work;
|
struct wiphy_delayed_work ttlm_work;
|
||||||
struct ieee80211_adv_ttlm_info ttlm_info;
|
struct ieee80211_adv_ttlm_info ttlm_info;
|
||||||
|
struct wiphy_work teardown_ttlm_work;
|
||||||
|
|
||||||
/* dialog token enumerator for neg TTLM request */
|
/* dialog token enumerator for neg TTLM request */
|
||||||
u8 dialog_token_alloc;
|
u8 dialog_token_alloc;
|
||||||
|
@ -6790,6 +6790,60 @@ void ieee80211_process_neg_ttlm_res(struct ieee80211_sub_if_data *sdata,
|
|||||||
__ieee80211_disconnect(sdata);
|
__ieee80211_disconnect(sdata);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void ieee80211_teardown_ttlm_work(struct wiphy *wiphy,
|
||||||
|
struct wiphy_work *work)
|
||||||
|
{
|
||||||
|
u16 new_dormant_links;
|
||||||
|
struct ieee80211_sub_if_data *sdata =
|
||||||
|
container_of(work, struct ieee80211_sub_if_data,
|
||||||
|
u.mgd.neg_ttlm_timeout_work.work);
|
||||||
|
|
||||||
|
if (!sdata->vif.neg_ttlm.valid)
|
||||||
|
return;
|
||||||
|
|
||||||
|
memset(&sdata->vif.neg_ttlm, 0, sizeof(sdata->vif.neg_ttlm));
|
||||||
|
new_dormant_links =
|
||||||
|
sdata->vif.dormant_links & ~sdata->vif.suspended_links;
|
||||||
|
sdata->vif.suspended_links = 0;
|
||||||
|
ieee80211_vif_set_links(sdata, sdata->vif.valid_links,
|
||||||
|
new_dormant_links);
|
||||||
|
ieee80211_vif_cfg_change_notify(sdata, BSS_CHANGED_MLD_TTLM |
|
||||||
|
BSS_CHANGED_MLD_VALID_LINKS);
|
||||||
|
}
|
||||||
|
|
||||||
|
void ieee80211_send_teardown_neg_ttlm(struct ieee80211_vif *vif)
|
||||||
|
{
|
||||||
|
struct ieee80211_sub_if_data *sdata = vif_to_sdata(vif);
|
||||||
|
struct ieee80211_local *local = sdata->local;
|
||||||
|
struct ieee80211_mgmt *mgmt;
|
||||||
|
struct sk_buff *skb;
|
||||||
|
int frame_len = offsetofend(struct ieee80211_mgmt,
|
||||||
|
u.action.u.ttlm_tear_down);
|
||||||
|
struct ieee80211_tx_info *info;
|
||||||
|
|
||||||
|
skb = dev_alloc_skb(local->hw.extra_tx_headroom + frame_len);
|
||||||
|
if (!skb)
|
||||||
|
return;
|
||||||
|
|
||||||
|
skb_reserve(skb, local->hw.extra_tx_headroom);
|
||||||
|
mgmt = skb_put_zero(skb, frame_len);
|
||||||
|
mgmt->frame_control = cpu_to_le16(IEEE80211_FTYPE_MGMT |
|
||||||
|
IEEE80211_STYPE_ACTION);
|
||||||
|
memcpy(mgmt->da, sdata->vif.cfg.ap_addr, ETH_ALEN);
|
||||||
|
memcpy(mgmt->sa, sdata->vif.addr, ETH_ALEN);
|
||||||
|
memcpy(mgmt->bssid, sdata->vif.cfg.ap_addr, ETH_ALEN);
|
||||||
|
|
||||||
|
mgmt->u.action.category = WLAN_CATEGORY_PROTECTED_EHT;
|
||||||
|
mgmt->u.action.u.ttlm_tear_down.action_code =
|
||||||
|
WLAN_PROTECTED_EHT_ACTION_TTLM_TEARDOWN;
|
||||||
|
|
||||||
|
info = IEEE80211_SKB_CB(skb);
|
||||||
|
info->flags |= IEEE80211_TX_CTL_REQ_TX_STATUS;
|
||||||
|
info->status_data = IEEE80211_STATUS_TYPE_NEG_TTLM;
|
||||||
|
ieee80211_tx_skb(sdata, skb);
|
||||||
|
}
|
||||||
|
EXPORT_SYMBOL(ieee80211_send_teardown_neg_ttlm);
|
||||||
|
|
||||||
void ieee80211_sta_rx_queued_ext(struct ieee80211_sub_if_data *sdata,
|
void ieee80211_sta_rx_queued_ext(struct ieee80211_sub_if_data *sdata,
|
||||||
struct sk_buff *skb)
|
struct sk_buff *skb)
|
||||||
{
|
{
|
||||||
@ -7421,6 +7475,8 @@ void ieee80211_sta_setup_sdata(struct ieee80211_sub_if_data *sdata)
|
|||||||
ieee80211_tid_to_link_map_work);
|
ieee80211_tid_to_link_map_work);
|
||||||
wiphy_delayed_work_init(&ifmgd->neg_ttlm_timeout_work,
|
wiphy_delayed_work_init(&ifmgd->neg_ttlm_timeout_work,
|
||||||
ieee80211_neg_ttlm_timeout_work);
|
ieee80211_neg_ttlm_timeout_work);
|
||||||
|
wiphy_work_init(&ifmgd->teardown_ttlm_work,
|
||||||
|
ieee80211_teardown_ttlm_work);
|
||||||
|
|
||||||
ifmgd->flags = 0;
|
ifmgd->flags = 0;
|
||||||
ifmgd->powersave = sdata->wdev.ps;
|
ifmgd->powersave = sdata->wdev.ps;
|
||||||
@ -8609,6 +8665,8 @@ void ieee80211_mgd_stop(struct ieee80211_sub_if_data *sdata)
|
|||||||
&ifmgd->beacon_connection_loss_work);
|
&ifmgd->beacon_connection_loss_work);
|
||||||
wiphy_work_cancel(sdata->local->hw.wiphy,
|
wiphy_work_cancel(sdata->local->hw.wiphy,
|
||||||
&ifmgd->csa_connection_drop_work);
|
&ifmgd->csa_connection_drop_work);
|
||||||
|
wiphy_work_cancel(sdata->local->hw.wiphy,
|
||||||
|
&ifmgd->teardown_ttlm_work);
|
||||||
wiphy_delayed_work_cancel(sdata->local->hw.wiphy,
|
wiphy_delayed_work_cancel(sdata->local->hw.wiphy,
|
||||||
&ifmgd->tdls_peer_del_work);
|
&ifmgd->tdls_peer_del_work);
|
||||||
wiphy_delayed_work_cancel(sdata->local->hw.wiphy,
|
wiphy_delayed_work_cancel(sdata->local->hw.wiphy,
|
||||||
|
@ -5,7 +5,7 @@
|
|||||||
* Copyright 2006-2007 Jiri Benc <jbenc@suse.cz>
|
* Copyright 2006-2007 Jiri Benc <jbenc@suse.cz>
|
||||||
* Copyright 2008-2010 Johannes Berg <johannes@sipsolutions.net>
|
* Copyright 2008-2010 Johannes Berg <johannes@sipsolutions.net>
|
||||||
* Copyright 2013-2014 Intel Mobile Communications GmbH
|
* Copyright 2013-2014 Intel Mobile Communications GmbH
|
||||||
* Copyright 2021-2023 Intel Corporation
|
* Copyright 2021-2024 Intel Corporation
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <linux/export.h>
|
#include <linux/export.h>
|
||||||
@ -696,6 +696,23 @@ static void ieee80211_handle_smps_status(struct ieee80211_sub_if_data *sdata,
|
|||||||
wiphy_work_queue(sdata->local->hw.wiphy, &link->u.mgd.recalc_smps);
|
wiphy_work_queue(sdata->local->hw.wiphy, &link->u.mgd.recalc_smps);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
ieee80211_handle_teardown_ttlm_status(struct ieee80211_sub_if_data *sdata,
|
||||||
|
bool acked)
|
||||||
|
{
|
||||||
|
if (!sdata || !ieee80211_sdata_running(sdata))
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (!acked)
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (sdata->vif.type != NL80211_IFTYPE_STATION)
|
||||||
|
return;
|
||||||
|
|
||||||
|
wiphy_work_queue(sdata->local->hw.wiphy,
|
||||||
|
&sdata->u.mgd.teardown_ttlm_work);
|
||||||
|
}
|
||||||
|
|
||||||
static void ieee80211_report_used_skb(struct ieee80211_local *local,
|
static void ieee80211_report_used_skb(struct ieee80211_local *local,
|
||||||
struct sk_buff *skb, bool dropped,
|
struct sk_buff *skb, bool dropped,
|
||||||
ktime_t ack_hwtstamp)
|
ktime_t ack_hwtstamp)
|
||||||
@ -773,6 +790,9 @@ static void ieee80211_report_used_skb(struct ieee80211_local *local,
|
|||||||
ieee80211_handle_smps_status(sdata, acked,
|
ieee80211_handle_smps_status(sdata, acked,
|
||||||
info->status_data);
|
info->status_data);
|
||||||
break;
|
break;
|
||||||
|
case IEEE80211_STATUS_TYPE_NEG_TTLM:
|
||||||
|
ieee80211_handle_teardown_ttlm_status(sdata, acked);
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
rcu_read_unlock();
|
rcu_read_unlock();
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user