Commit a17a58ad authored by Ayala Beker's avatar Ayala Beker Committed by Johannes Berg
Browse files

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: default avatarAyala Beker <ayala.beker@intel.com>
Reviewed-by: default avatarJohannes Berg <johannes.berg@intel.com>
Signed-off-by: default avatarMiri Korenblit <miriam.rachel.korenblit@intel.com>
Link: https://msgid.link/20240318184907.d480cbf46fcf.Idedad472469d2c27dd2a088cf80a13a1e1cf9b78@changeid


Signed-off-by: default avatarJohannes Berg <johannes.berg@intel.com>
parent 97f8df4d
Loading
Loading
Loading
Loading
+9 −0
Original line number Diff line number Diff line
@@ -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,
				      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 ... */
int ieee80211_emulate_add_chanctx(struct ieee80211_hw *hw,
				  struct ieee80211_chanctx_conf *ctx);
+2 −0
Original line number Diff line number Diff line
@@ -89,6 +89,7 @@ enum ieee80211_status_data {
	IEEE80211_STATUS_TYPE_MASK	= 0x00f,
	IEEE80211_STATUS_TYPE_INVALID	= 0,
	IEEE80211_STATUS_TYPE_SMPS	= 1,
	IEEE80211_STATUS_TYPE_NEG_TTLM	= 2,
	IEEE80211_STATUS_SUBDATA_MASK	= 0xff0,
};

@@ -595,6 +596,7 @@ struct ieee80211_if_managed {
	/* TID-to-link mapping support */
	struct wiphy_delayed_work ttlm_work;
	struct ieee80211_adv_ttlm_info ttlm_info;
	struct wiphy_work teardown_ttlm_work;

	/* dialog token enumerator for neg TTLM request */
	u8 dialog_token_alloc;
+58 −0
Original line number Diff line number Diff line
@@ -6790,6 +6790,60 @@ void ieee80211_process_neg_ttlm_res(struct ieee80211_sub_if_data *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,
				 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);
	wiphy_delayed_work_init(&ifmgd->neg_ttlm_timeout_work,
				ieee80211_neg_ttlm_timeout_work);
	wiphy_work_init(&ifmgd->teardown_ttlm_work,
			ieee80211_teardown_ttlm_work);

	ifmgd->flags = 0;
	ifmgd->powersave = sdata->wdev.ps;
@@ -8609,6 +8665,8 @@ void ieee80211_mgd_stop(struct ieee80211_sub_if_data *sdata)
			  &ifmgd->beacon_connection_loss_work);
	wiphy_work_cancel(sdata->local->hw.wiphy,
			  &ifmgd->csa_connection_drop_work);
	wiphy_work_cancel(sdata->local->hw.wiphy,
			  &ifmgd->teardown_ttlm_work);
	wiphy_delayed_work_cancel(sdata->local->hw.wiphy,
				  &ifmgd->tdls_peer_del_work);
	wiphy_delayed_work_cancel(sdata->local->hw.wiphy,
+21 −1
Original line number Diff line number Diff line
@@ -5,7 +5,7 @@
 * Copyright 2006-2007	Jiri Benc <jbenc@suse.cz>
 * Copyright 2008-2010	Johannes Berg <johannes@sipsolutions.net>
 * Copyright 2013-2014  Intel Mobile Communications GmbH
 * Copyright 2021-2023  Intel Corporation
 * Copyright 2021-2024  Intel Corporation
 */

#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);
}

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,
				      struct sk_buff *skb, bool dropped,
				      ktime_t ack_hwtstamp)
@@ -773,6 +790,9 @@ static void ieee80211_report_used_skb(struct ieee80211_local *local,
			ieee80211_handle_smps_status(sdata, acked,
						     info->status_data);
			break;
		case IEEE80211_STATUS_TYPE_NEG_TTLM:
			ieee80211_handle_teardown_ttlm_status(sdata, acked);
			break;
		}
		rcu_read_unlock();
	}