diff mbox series

[RFC,v4,2/2] wifi: mac80211: Add support for link reconfigure removal

Message ID 20240807034521.2091751-3-quic_mdharane@quicinc.com (mailing list archive)
State Changes Requested
Delegated to: Johannes Berg
Headers show
Series Add Multi-Link Reconfigure link removal support | expand

Commit Message

Manish Dharanenthiran Aug. 7, 2024, 3:45 a.m. UTC
Add mac80211 routine to support sending link removal command to
offloaded driver which accepts reconfigure Multi-Link element and the TBTT
count for the link to be removed. To support this, introduce new
mac80211 ops "link_reconfig_remove" to initiate link removal procedure
in driver with Multi-Link reconfiguration element and TBTT count received
from the userspace.

Also, add mac80211 routine "ieee80211_update_link_reconfig_remove_status"
which will be used by driver for sending TSF and current TBTT count
receive from driver during the following scenarios,

  1) When first beacon with Multi-Link reconfigure element is sent out in
  air, mac80211 will notify the userspace that link removal is started and
  it can proceed with further action like BTM etc.,
  2) When last beacon with Multi-Link reconfigure element (i.e. with link
  removal tbtt count as 0) is sent out in air, mac80211 will notify the
  userspace that link removal is completed. After which, userspace shall
  initiate the disassociation of the peer(s) connected and removal of
  the link completely.

Signed-off-by: Manish Dharanenthiran <quic_mdharane@quicinc.com>
---
 include/net/mac80211.h     | 25 +++++++++++++++++++++++++
 net/mac80211/cfg.c         | 12 ++++++++++++
 net/mac80211/driver-ops.h  | 19 +++++++++++++++++++
 net/mac80211/ieee80211_i.h |  4 ++++
 net/mac80211/link.c        | 34 ++++++++++++++++++++++++++++++++++
 net/mac80211/trace.h       | 31 +++++++++++++++++++++++++++++++
 6 files changed, 125 insertions(+)

Comments

Johannes Berg Aug. 21, 2024, 8:58 a.m. UTC | #1
On Wed, 2024-08-07 at 09:15 +0530, Manish Dharanenthiran wrote:
> 
> +/* Defines for ML Reconfigure removal offload */

Not really "defines", but whatever? Is there value in this comment
anyway though? Don't see how it adds much.

> +/**
> + * ieee80211_update_link_reconfig_remove_update - Inform userspace about
> + * the removal status of link which is scheduled for removal
> + * @vif: interface in which reconfig removal status is received.
> + * @link_id: Link which is undergoing removal
> + * @tbtt_count: Current tbtt_count to be updated.
> + * @tsf: Beacon's timestamp value
> + * @cmd: Inform started or completed action to userspace
> + *
> + * For description, check cfg80211_link_reconfig_remove_update
> + */
> +int ieee80211_update_link_reconfig_remove_update(struct ieee80211_vif *vif,
> +						 unsigned int link_id,
> +						 u32 tbtt_count, u64 tsf,
> +						 enum nl80211_commands cmd);

And anyway this is a trivial wrapper, why not make it so the cfg80211
API takes the wdev, and then just call it directly in the driver with
ieee80211_vif_to_wdev(), or have a trivial inline? No reason to have the
iftype check in mac80211 either, that can be in cfg80211 and/or drivers?

Other than that it looks OK I guess, but I do wonder if you've actually
tested further than that?

It seems to me that ieee80211_del_link_station() is somewhat broken when
you remove the deflink from the STA, since we'll continue using data
from there?

johannes
Manish Dharanenthiran Aug. 27, 2024, 6:48 p.m. UTC | #2
On 8/21/2024 2:28 PM, Johannes Berg wrote:
> On Wed, 2024-08-07 at 09:15 +0530, Manish Dharanenthiran wrote:
>>
>> +/* Defines for ML Reconfigure removal offload */
> 
> Not really "defines", but whatever? Is there value in this comment
> anyway though? Don't see how it adds much.
> 
Will modify accordingly in upcoming version.

>> +/**
>> + * ieee80211_update_link_reconfig_remove_update - Inform userspace about
>> + * the removal status of link which is scheduled for removal
>> + * @vif: interface in which reconfig removal status is received.
>> + * @link_id: Link which is undergoing removal
>> + * @tbtt_count: Current tbtt_count to be updated.
>> + * @tsf: Beacon's timestamp value
>> + * @cmd: Inform started or completed action to userspace
>> + *
>> + * For description, check cfg80211_link_reconfig_remove_update
>> + */
>> +int ieee80211_update_link_reconfig_remove_update(struct ieee80211_vif *vif,
>> +						 unsigned int link_id,
>> +						 u32 tbtt_count, u64 tsf,
>> +						 enum nl80211_commands cmd);
> 
> And anyway this is a trivial wrapper, why not make it so the cfg80211
> API takes the wdev, and then just call it directly in the driver with
> ieee80211_vif_to_wdev(), or have a trivial inline? No reason to have the
> iftype check in mac80211 either, that can be in cfg80211 and/or drivers?
> 
Sure, will address this in upcoming version.

> Other than that it looks OK I guess, but I do wonder if you've actually
> tested further than that?
> Yes, have tested this along with the driver changes. But, as you 
mentioned it needs further more changes to make this work in real time. 
Will update all the changes in next version as a patch series.

> It seems to me that ieee80211_del_link_station() is somewhat broken when
> you remove the deflink from the STA, since we'll continue using data
> from there?
> 
Yes, link sta delete has to be handled where we would move the deflink 
sta to next valid link, if its available.

> johannes

Thanks Johannes for the review. Will incorporate the comments given in 
this RFC, also add the other necessary changes which are tested and 
update them as patch series.

Regards
Manish Dharanenthiran
diff mbox series

Patch

diff --git a/include/net/mac80211.h b/include/net/mac80211.h
index 0a04eaf5343c..c3d6d3c3ba56 100644
--- a/include/net/mac80211.h
+++ b/include/net/mac80211.h
@@ -4430,6 +4430,10 @@  struct ieee80211_prep_tx_info {
  *	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.
+ * @link_reconfig_remove: Notifies the driver about the link to be
+ *	scheduled for removal with ML reconfigure element built for that particular
+ *	link along with the TBTT count until which the beacon with ML
+ *	reconfigure element should be sent.
  */
 struct ieee80211_ops {
 	void (*tx)(struct ieee80211_hw *hw,
@@ -4814,6 +4818,9 @@  struct ieee80211_ops {
 	enum ieee80211_neg_ttlm_res
 	(*can_neg_ttlm)(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
 			struct ieee80211_neg_ttlm *ttlm);
+	int (*link_reconfig_remove)(struct ieee80211_hw *hw,
+				    struct ieee80211_vif *vif,
+				    const struct cfg80211_link_reconfig_removal_params *params);
 };
 
 /**
@@ -7646,6 +7653,24 @@  void ieee80211_set_active_links_async(struct ieee80211_vif *vif,
  */
 void ieee80211_send_teardown_neg_ttlm(struct ieee80211_vif *vif);
 
+/* Defines for ML Reconfigure removal offload */
+
+/**
+ * ieee80211_update_link_reconfig_remove_update - Inform userspace about
+ * the removal status of link which is scheduled for removal
+ * @vif: interface in which reconfig removal status is received.
+ * @link_id: Link which is undergoing removal
+ * @tbtt_count: Current tbtt_count to be updated.
+ * @tsf: Beacon's timestamp value
+ * @cmd: Inform started or completed action to userspace
+ *
+ * For description, check cfg80211_link_reconfig_remove_update
+ */
+int ieee80211_update_link_reconfig_remove_update(struct ieee80211_vif *vif,
+						 unsigned int link_id,
+						 u32 tbtt_count, u64 tsf,
+						 enum nl80211_commands cmd);
+
 /* for older drivers - let's not document these ... */
 int ieee80211_emulate_add_chanctx(struct ieee80211_hw *hw,
 				  struct ieee80211_chanctx_conf *ctx);
diff --git a/net/mac80211/cfg.c b/net/mac80211/cfg.c
index 85cb71de370f..a1a2b4f61d8c 100644
--- a/net/mac80211/cfg.c
+++ b/net/mac80211/cfg.c
@@ -5090,6 +5090,17 @@  ieee80211_set_ttlm(struct wiphy *wiphy, struct net_device *dev,
 	return ieee80211_req_neg_ttlm(sdata, params);
 }
 
+static int
+ieee80211_link_reconfig_remove(struct wiphy *wiphy,
+			       struct net_device *dev,
+			       const struct cfg80211_link_reconfig_removal_params *params)
+{
+	struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);
+	struct ieee80211_local *local = wiphy_priv(wiphy);
+
+	return __ieee80211_link_reconfig_remove(local, sdata, params);
+}
+
 const struct cfg80211_ops mac80211_config_ops = {
 	.add_virtual_intf = ieee80211_add_iface,
 	.del_virtual_intf = ieee80211_del_iface,
@@ -5204,4 +5215,5 @@  const struct cfg80211_ops mac80211_config_ops = {
 	.set_hw_timestamp = ieee80211_set_hw_timestamp,
 	.set_ttlm = ieee80211_set_ttlm,
 	.get_radio_mask = ieee80211_get_radio_mask,
+	.link_reconfig_remove = ieee80211_link_reconfig_remove,
 };
diff --git a/net/mac80211/driver-ops.h b/net/mac80211/driver-ops.h
index d382d9729e85..d3976d0e51c6 100644
--- a/net/mac80211/driver-ops.h
+++ b/net/mac80211/driver-ops.h
@@ -1728,4 +1728,23 @@  drv_can_neg_ttlm(struct ieee80211_local *local,
 
 	return res;
 }
+
+static inline int
+drv_link_reconfig_remove(struct ieee80211_local *local,
+			 struct ieee80211_sub_if_data *sdata,
+			 const struct cfg80211_link_reconfig_removal_params *params)
+{
+	int ret = -EOPNOTSUPP;
+
+	trace_drv_link_reconfig_remove(local, sdata, params);
+
+	if (local->ops->link_reconfig_remove)
+		ret = local->ops->link_reconfig_remove(&local->hw,
+						       &sdata->vif,
+						       params);
+	trace_drv_return_int(local, ret);
+
+	return ret;
+}
+
 #endif /* __MAC80211_DRIVER_OPS */
diff --git a/net/mac80211/ieee80211_i.h b/net/mac80211/ieee80211_i.h
index a3485e4c6132..11c673d17648 100644
--- a/net/mac80211/ieee80211_i.h
+++ b/net/mac80211/ieee80211_i.h
@@ -2058,6 +2058,10 @@  static inline void ieee80211_vif_clear_links(struct ieee80211_sub_if_data *sdata
 	ieee80211_vif_set_links(sdata, 0, 0);
 }
 
+int __ieee80211_link_reconfig_remove(struct ieee80211_local *local,
+				     struct ieee80211_sub_if_data *sdata,
+				     const struct cfg80211_link_reconfig_removal_params *params);
+
 /* tx handling */
 void ieee80211_clear_tx_pending(struct ieee80211_local *local);
 void ieee80211_tx_pending(struct tasklet_struct *t);
diff --git a/net/mac80211/link.c b/net/mac80211/link.c
index 1a211b8d4057..e59a38809fa6 100644
--- a/net/mac80211/link.c
+++ b/net/mac80211/link.c
@@ -528,3 +528,37 @@  void ieee80211_set_active_links_async(struct ieee80211_vif *vif,
 	wiphy_work_queue(sdata->local->hw.wiphy, &sdata->activate_links_work);
 }
 EXPORT_SYMBOL_GPL(ieee80211_set_active_links_async);
+
+int __ieee80211_link_reconfig_remove(struct ieee80211_local *local,
+				     struct ieee80211_sub_if_data *sdata,
+				     const struct cfg80211_link_reconfig_removal_params *params)
+{
+	struct ieee80211_link_data *link;
+
+	if (!ieee80211_sdata_running(sdata))
+		return -ENETDOWN;
+
+	if (sdata->vif.type != NL80211_IFTYPE_AP)
+		return -EINVAL;
+
+	link = sdata_dereference(sdata->link[params->link_id], sdata);
+	if (!link)
+		return -ENOLINK;
+
+	return drv_link_reconfig_remove(local, sdata, params);
+}
+
+int ieee80211_update_link_reconfig_remove_update(struct ieee80211_vif *vif,
+						 unsigned int link_id,
+						 u32 tbtt_count, u64 tsf,
+						 enum nl80211_commands cmd)
+{
+	struct ieee80211_sub_if_data *sdata = vif_to_sdata(vif);
+
+	if (vif->type == NL80211_IFTYPE_AP)
+		return cfg80211_update_link_reconfig_remove_update(sdata->dev, link_id,
+								   tbtt_count, tsf,
+								   cmd);
+	return -EINVAL;
+}
+EXPORT_SYMBOL(ieee80211_update_link_reconfig_remove_update);
diff --git a/net/mac80211/trace.h b/net/mac80211/trace.h
index dc498cd8cd91..8103eb7377a4 100644
--- a/net/mac80211/trace.h
+++ b/net/mac80211/trace.h
@@ -3154,6 +3154,37 @@  TRACE_EVENT(drv_neg_ttlm_res,
 		  LOCAL_PR_ARG, VIF_PR_ARG, __entry->res
 	)
 );
+
+TRACE_EVENT(drv_link_reconfig_remove,
+	TP_PROTO(struct ieee80211_local *local,
+		 struct ieee80211_sub_if_data *sdata,
+		 const struct cfg80211_link_reconfig_removal_params *params),
+
+	TP_ARGS(local, sdata, params),
+
+	TP_STRUCT__entry(
+		LOCAL_ENTRY
+		VIF_ENTRY
+		__field(u32, link_id)
+		__field(u32, count)
+		__dynamic_array(u8, frame, params->elem_len)
+	),
+
+	TP_fast_assign(
+		LOCAL_ASSIGN;
+		VIF_ASSIGN;
+		__entry->link_id = params->link_id;
+		memcpy(__get_dynamic_array(frame), params->reconfigure_elem,
+		       params->elem_len);
+		__entry->count = params->link_removal_cntdown;
+	),
+
+	TP_printk(
+		LOCAL_PR_FMT ", " VIF_PR_FMT ", link_id :%u count:%d",
+		LOCAL_PR_ARG, VIF_PR_ARG,
+		__entry->link_id, __entry->count)
+);
+
 #endif /* !__MAC80211_DRIVER_TRACE || TRACE_HEADER_MULTI_READ */
 
 #undef TRACE_INCLUDE_PATH