To indicate userspace the early termination of the DL draining period,
define an API for drivers to invoke the SMD Drain Completion event. This
API makes sure that the non-AP MLD is already in the DL Drain sub-state
(4c) in the first place to being able to terminate it.
Suggested-by: Rohan Dutta <redacted>
Signed-off-by: Pooventhiran G <redacted>
---
include/net/mac80211.h | 16 ++++++++++++++++
net/mac80211/cfg.c | 18 ++++++++++++++++++
2 files changed, 34 insertions(+)
diff --git a/include/net/mac80211.h b/include/net/mac80211.h
index d78b7e897230..7dc7d1a7a1f8 100644
--- a/include/net/mac80211.h
+++ b/include/net/mac80211.h
@@ -8331,4 +8331,20 @@ int ieee80211_encrypt_tx_skb(struct sk_buff *skb);
void ieee80211_get_smd_ctx_done(struct ieee80211_vif *vif,
const u8 *sta_addr,
struct cfg80211_smd_transition_info *st_info);
+
+/**
+ * ieee80211_notify_smd_drain_completion - notify downlink drain completion for
+ * an SMD station.
+ * @vif: virtual interface
+ * @station: non-AP MLD object
+ *
+ * The start of DL draining will have moved the station to SMD sub-state
+ * %IEEE80211_STA_SMD_DRAIN. Hence, drain completion is valid only if the
+ * station is already in this state. Should be called under wiphy_lock.
+ *
+ * Return: 0 if success, -EINVAL otherwise
+ */
+int ieee80211_notify_smd_drain_completion(struct ieee80211_vif *vif,
+ struct ieee80211_sta *station);
+
#endif /* MAC80211_H */
diff --git a/net/mac80211/cfg.c b/net/mac80211/cfg.c
index 26ebbc27dac0..0aafc7ac771c 100644
--- a/net/mac80211/cfg.c
+++ b/net/mac80211/cfg.c
@@ -6423,6 +6423,24 @@ void ieee80211_get_smd_ctx_done(struct ieee80211_vif *vif,
}
EXPORT_SYMBOL(ieee80211_get_smd_ctx_done);
+int ieee80211_notify_smd_drain_completion(struct ieee80211_vif *vif,
+ struct ieee80211_sta *station)
+{
+ struct ieee80211_sub_if_data *sdata = vif_to_sdata(vif);
+ struct sta_info *sta = container_of(station, struct sta_info, sta);
+
+ lockdep_assert_wiphy(sdata->local->hw.wiphy);
+
+ /* doesn't make sense to terminate if we are not draining already */
+ if (sta->smd_state != IEEE80211_STA_SMD_DRAIN)
+ return -EINVAL;
+
+ cfg80211_notify_smd_drain_completion(&sdata->wdev, sta->addr);
+
+ return 0;
+}
+EXPORT_SYMBOL(ieee80211_notify_smd_drain_completion);
+
const struct cfg80211_ops mac80211_config_ops = {
.add_virtual_intf = ieee80211_add_iface,
.del_virtual_intf = ieee80211_del_iface,
--
2.34.1