[PATCH RFC wireless-next 4/7] wifi: mac80211: forward QoS Management configuration to drivers
Aishwarya R
aishwarya.r at oss.qualcomm.com
Wed Oct 14 22:54:38 PDT 2026
Add a mac80211 QoS Management driver operation and connect it to the
cfg80211 set_qos_mgmt_cfg() callback.
Pass the parsed SCS/MSCS request, including any QoS Characteristics, to
the driver together with the response descriptor array. The driver is
expected to apply the protocol-specific configuration and update each
response descriptor with the status for its corresponding request.
The accepted configuration is then retained by mac80211 for use by
subsequent data-path handling.
Co-developed-by: Arun Vikas T <arun.t at oss.qualcomm.com>
Signed-off-by: Arun Vikas T <arun.t at oss.qualcomm.com>
Signed-off-by: Aishwarya R <aishwarya.r at oss.qualcomm.com>
---
include/net/mac80211.h | 7 +++++++
net/mac80211/cfg.c | 13 +++++++++++++
net/mac80211/driver-ops.h | 28 ++++++++++++++++++++++++++++
net/mac80211/ieee80211_i.h | 4 ++++
net/mac80211/mlme.c | 17 +++++++++++++++++
net/mac80211/trace.h | 24 ++++++++++++++++++++++++
6 files changed, 93 insertions(+)
diff --git a/include/net/mac80211.h b/include/net/mac80211.h
index a1a6409b44c1..a610d6eb92b4 100644
--- a/include/net/mac80211.h
+++ b/include/net/mac80211.h
@@ -4760,6 +4760,9 @@ struct ieee80211_prep_tx_info {
* @set_eml_op_mode: Configure eMLSR/eMLMR operation mode in the underlay
* driver according to the parameter received in the EML Operating mode
* notification frame.
+ * @qos_mgmt_cfg: Configure QoS Management (QM) for a station. The request
+ * contains SCS or MSCS parameters, and the driver populates the
+ * per-descriptor response status.
*/
struct ieee80211_ops {
void (*tx)(struct ieee80211_hw *hw,
@@ -5173,6 +5176,10 @@ struct ieee80211_ops {
struct ieee80211_vif *vif,
struct ieee80211_sta *sta,
struct ieee80211_eml_params *eml_params);
+ int (*qos_mgmt_cfg)(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
+ struct ieee80211_sta *sta,
+ struct cfg80211_qm_req_data *qm_req,
+ struct cfg80211_qm_resp_data *qm_resp);
};
/**
diff --git a/net/mac80211/cfg.c b/net/mac80211/cfg.c
index 9608c07bcea7..f66f736adb92 100644
--- a/net/mac80211/cfg.c
+++ b/net/mac80211/cfg.c
@@ -6309,6 +6309,18 @@ ieee80211_set_nan_non_evac_channels(struct wiphy *wiphy,
return ieee80211_nan_set_non_evac_channels(sdata, channels);
}
+static int
+ieee80211_set_qos_mgmt_cfg(struct wiphy *wiphy, struct net_device *dev,
+ struct cfg80211_qm_req_data *qm_req,
+ struct cfg80211_qm_resp_data *qm_resp)
+{
+ struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);
+
+ lockdep_assert_wiphy(wiphy);
+
+ return ieee80211_qos_mgmt_cfg(sdata, qm_req, qm_resp);
+}
+
const struct cfg80211_ops mac80211_config_ops = {
.add_virtual_intf = ieee80211_add_iface,
.del_virtual_intf = ieee80211_del_iface,
@@ -6432,4 +6444,5 @@ const struct cfg80211_ops mac80211_config_ops = {
.nan_set_local_sched = ieee80211_set_local_nan_sched,
.nan_set_peer_sched = ieee80211_set_peer_nan_sched,
.nan_set_non_evac_channels = ieee80211_set_nan_non_evac_channels,
+ .set_qos_mgmt_cfg = ieee80211_set_qos_mgmt_cfg,
};
diff --git a/net/mac80211/driver-ops.h b/net/mac80211/driver-ops.h
index 83dd15f2daf6..f1dc9ca9f8f7 100644
--- a/net/mac80211/driver-ops.h
+++ b/net/mac80211/driver-ops.h
@@ -1804,4 +1804,32 @@ drv_nan_peer_sched_changed(struct ieee80211_local *local,
return ret;
}
+static inline int
+drv_qos_mgmt_cfg(struct ieee80211_sub_if_data *sdata,
+ struct ieee80211_local *local, struct ieee80211_sta *sta,
+ struct cfg80211_qm_req_data *qm_req,
+ struct cfg80211_qm_resp_data *qm_resp)
+{
+ int ret = -EOPNOTSUPP;
+
+ might_sleep();
+ lockdep_assert_wiphy(local->hw.wiphy);
+
+ if (!check_sdata_in_driver(sdata))
+ return ret;
+
+ /*
+ * Called only for SCS descriptors carrying a QoS Characteristics
+ * element (9.4.2.326, IEEE Std 802.11be-2024). Legacy SCS and MSCS
+ * are handled in mac80211.
+ */
+ trace_drv_qos_mgmt_cfg(local, sdata, sta, qm_req);
+ if (local->ops->qos_mgmt_cfg)
+ ret = local->ops->qos_mgmt_cfg(&local->hw, &sdata->vif,
+ sta, qm_req, qm_resp);
+ 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 1a6cbbb5a17d..63391a1fd9c6 100644
--- a/net/mac80211/ieee80211_i.h
+++ b/net/mac80211/ieee80211_i.h
@@ -3020,6 +3020,10 @@ ieee80211_uhr_cap_ie_to_sta_uhr_cap(struct ieee80211_sub_if_data *sdata,
u8 uhr_cap_len,
struct link_sta_info *link_sta);
+int ieee80211_qos_mgmt_cfg(struct ieee80211_sub_if_data *sdata,
+ struct cfg80211_qm_req_data *qm_req,
+ struct cfg80211_qm_resp_data *qm_resp);
+
#if IS_ENABLED(CONFIG_MAC80211_KUNIT_TEST)
#define EXPORT_SYMBOL_IF_MAC80211_KUNIT(sym) EXPORT_SYMBOL_IF_KUNIT(sym)
#define VISIBLE_IF_MAC80211_KUNIT
diff --git a/net/mac80211/mlme.c b/net/mac80211/mlme.c
index 6ec45a9f7221..e476c6b9cb14 100644
--- a/net/mac80211/mlme.c
+++ b/net/mac80211/mlme.c
@@ -12036,3 +12036,20 @@ void ieee80211_sta_rx_queued_frame(struct ieee80211_sub_if_data *sdata,
break;
}
}
+
+int ieee80211_qos_mgmt_cfg(struct ieee80211_sub_if_data *sdata,
+ struct cfg80211_qm_req_data *qm_req,
+ struct cfg80211_qm_resp_data *qm_resp)
+{
+ struct ieee80211_local *local = sdata->local;
+ struct sta_info *sta;
+
+ if (sdata->vif.type != NL80211_IFTYPE_AP)
+ return -EOPNOTSUPP;
+
+ sta = sta_info_get_bss(sdata, qm_req->peer_mac);
+ if (!sta)
+ return -ENOENT;
+
+ return drv_qos_mgmt_cfg(sdata, local, &sta->sta, qm_req, qm_resp);
+}
diff --git a/net/mac80211/trace.h b/net/mac80211/trace.h
index ea46c3cca21a..ce69e5edd03f 100644
--- a/net/mac80211/trace.h
+++ b/net/mac80211/trace.h
@@ -3431,6 +3431,30 @@ TRACE_EVENT(drv_nan_peer_sched_changed,
)
);
+TRACE_EVENT(drv_qos_mgmt_cfg,
+ TP_PROTO(struct ieee80211_local *local,
+ struct ieee80211_sub_if_data *sdata,
+ struct ieee80211_sta *sta,
+ struct cfg80211_qm_req_data *qm_req),
+ TP_ARGS(local, sdata, sta, qm_req),
+ TP_STRUCT__entry(LOCAL_ENTRY
+ VIF_ENTRY
+ STA_ENTRY
+ __field(u8, qm_type)
+ __field(unsigned int, num_qm_desc)
+ ),
+ TP_fast_assign(LOCAL_ASSIGN;
+ VIF_ASSIGN;
+ STA_NAMED_ASSIGN(sta);
+ __entry->qm_type = qm_req->qm_type;
+ __entry->num_qm_desc = qm_req->num_qm_desc;
+ ),
+ TP_printk(LOCAL_PR_FMT VIF_PR_FMT STA_PR_FMT
+ " qm_type:%u num_qm_desc:%u",
+ LOCAL_PR_ARG, VIF_PR_ARG, STA_PR_ARG,
+ __entry->qm_type, __entry->num_qm_desc)
+);
+
#endif /* !__MAC80211_DRIVER_TRACE || TRACE_HEADER_MULTI_READ */
#undef TRACE_INCLUDE_PATH
--
2.34.1
More information about the ath12k
mailing list