hostapd: handle updated MU-EDCA params from driver

This patch handles the updating of MU-EDCA parameters indicated by
driver. Driver requests to update the parameters and Parameter Set
Update Count in beacon frames. This patch addresses only AP mode.

Three actions are taken to successfully update MU-EDCA parameters
in beacon:
	(1) Update MU-EDCA parameters stored in hostapd
	    The following Access Categories (AC) are updated:
	      VO: Voice
	      VI: Video
	      BE: Best Effort
	      BK: Background

	(2) Increment Parameter Set Update Count
	(3) Update beacon with new parameters

There aren't any options to configure, hostapd simply updates MU-EDCA
published by ath11k driver.

To verify params are getting updated, set log_level to '1' and check
logger

i.e. `uci set wireless.radio0.log_level=1`

```
Sat Jul  6 15:36:10 2024 daemon.debug hostapd: phy0-ap0: IEEE 802.11 MU-EDCA: Updated MU-EDCA parameters for AC 0: BE: 3, BK: 7, VI: 2, VO: 2
Sat Jul  6 15:36:10 2024 daemon.debug hostapd: phy0-ap0: IEEE 802.11 MU-EDCA: Updated MU-EDCA parameters for AC 1: BE: 164, BK: 164, VI: 67, VO: 50
Sat Jul  6 15:36:10 2024 daemon.debug hostapd: phy0-ap0: IEEE 802.11 MU-EDCA: Updated MU-EDCA parameters for AC 2: BE: 255, BK: 2, VI: 255, VO: 255
```

Requires the following patches applied to 'ath11k/subsys'

commit ce7f1ad354869d85abdf8e8ed8d36599e057ba5d
Author:     Sean Khan <datapronix@protonmail.com>
AuthorDate: Tue Feb 27 00:45:32 2024 -0500
Commit:     Sean Khan <datapronix@protonmail.com>
CommitDate: Sat Jul 6 15:19:26 2024 -0400

    ath11k_nss: FW Initiated Dynamic MU-EDCA

    package/kernel/mac80211/patches/nss/ath11k/203-mac80211-ath11k-fw-dynamic-muedca.patch
    package/kernel/mac80211/patches/nss/subsys/203-mac80211-ath11k-fw-dynamic-muedca.patch

Signed-off-by: Sean Khan <datapronix@protonmail.com>
This commit is contained in:
Sean Khan
2024-07-06 15:25:25 -04:00
parent 802b282b7a
commit 9e93c37609

View File

@@ -0,0 +1,299 @@
--- a/hostapd/ctrl_iface.c
+++ b/hostapd/ctrl_iface.c
@@ -1314,6 +1314,11 @@ static int hostapd_ctrl_iface_set(struct
} else if (os_strncmp(cmd, "wme_ac_", 7) == 0 ||
os_strncmp(cmd, "wmm_ac_", 7) == 0) {
hapd->parameter_set_count++;
+ /* Incrementing MU-EDCA Parameter Set Update Count*/
+ hapd->iface->conf->he_mu_edca.he_qos_info =
+ (hapd->iface->conf->he_mu_edca.he_qos_info & 0xf0) |
+ ((hapd->iface->conf->he_mu_edca.he_qos_info + 1) &
+ 0xf);
if (ieee802_11_update_beacons(hapd->iface))
wpa_printf(MSG_DEBUG,
"Failed to update beacons with WMM parameters");
--- a/src/ap/drv_callbacks.c
+++ b/src/ap/drv_callbacks.c
@@ -20,6 +20,7 @@
#include "common/hw_features_common.h"
#include "crypto/random.h"
#include "p2p/p2p.h"
+#include "wpa_debug.h"
#include "wps/wps.h"
#include "fst/fst.h"
#include "wnm_ap.h"
@@ -2267,6 +2268,47 @@ static void hostapd_event_wds_sta_interf
ifname, MAC2STR(addr));
}
+static void hostapd_event_update_muedca_params(struct hostapd_data *hapd,
+ struct update_muedca *params)
+{
+ int i;
+ u8 updated_count;
+
+ /* Update current MU-EDCA parameters */
+ for (i = 0; i < 3; i++) {
+ hapd->iface->conf->he_mu_edca.he_mu_ac_be_param[i] =
+ params->he_mu_ac_be_param[i];
+ hapd->iface->conf->he_mu_edca.he_mu_ac_bk_param[i] =
+ params->he_mu_ac_bk_param[i];
+ hapd->iface->conf->he_mu_edca.he_mu_ac_vo_param[i] =
+ params->he_mu_ac_vo_param[i];
+ hapd->iface->conf->he_mu_edca.he_mu_ac_vi_param[i] =
+ params->he_mu_ac_vi_param[i];
+ hostapd_logger(hapd, NULL, HOSTAPD_MODULE_IEEE80211,
+ HOSTAPD_LEVEL_DEBUG,
+ "MU-EDCA: Updated MU-EDCA parameters for AC %d: "
+ "BE: %d, BK: %d, VI: %d, VO: %d",
+ i, params->he_mu_ac_be_param[i],
+ params->he_mu_ac_bk_param[i],
+ params->he_mu_ac_vi_param[i],
+ params->he_mu_ac_vo_param[i]);
+ }
+
+ /* Increment Parameter Set Update Count for MU-EDCA and WME EDCA only
+ * if any STA is connected
+ */
+ if (hapd->num_sta) {
+ updated_count = (hapd->iface->conf->he_mu_edca.he_qos_info + 1) & 0xf;
+ hapd->iface->conf->he_mu_edca.he_qos_info &= 0xf0;
+ hapd->iface->conf->he_mu_edca.he_qos_info |= updated_count;
+ hapd->parameter_set_count++;
+ }
+
+ /* Update beacon with updated MU-EDCA parameters */
+ if (ieee802_11_update_beacons(hapd->iface))
+ wpa_printf(MSG_WARNING,
+ "Failed to update beacons with MU-EDCA parameters");
+}
#ifdef CONFIG_OWE
static int hostapd_notif_update_dh_ie(struct hostapd_data *hapd,
@@ -2677,6 +2719,9 @@ void hostapd_wpa_event(void *ctx, enum w
hostapd_cleanup_cca_params(hapd);
break;
#endif /* CONFIG_IEEE80211AX */
+ case EVENT_UPDATE_MUEDCA_PARAMS:
+ hostapd_event_update_muedca_params(hapd, &data->update_muedca);
+ break;
default:
wpa_printf(MSG_DEBUG, "Unknown event %d", event);
break;
--- a/src/ap/hostapd.c
+++ b/src/ap/hostapd.c
@@ -4100,6 +4100,10 @@ static int hostapd_fill_csa_settings(str
hapd->cs_count = settings->cs_count;
hapd->cs_block_tx = settings->block_tx;
+ /* reset MU-EDCA and WME EDCA parameter set count */
+ hapd->iface->conf->he_mu_edca.he_qos_info &= 0xfff0;
+ hapd->parameter_set_count = 0;
+
ret = hostapd_build_beacon_data(hapd, &settings->beacon_csa);
if (ret) {
free_beacon_data(&settings->beacon_after);
--- a/src/ap/ieee802_11_he.c
+++ b/src/ap/ieee802_11_he.c
@@ -19,6 +19,7 @@
#include "sta_info.h"
#include "ieee802_11.h"
#include "dfs.h"
+#include "wmm.h"
static u8 ieee80211_he_ppet_size(u8 ppe_thres_hdr, const u8 *phy_cap_info)
{
@@ -291,9 +292,16 @@ u8 * hostapd_eid_he_operation(struct hos
u8 * hostapd_eid_he_mu_edca_parameter_set(struct hostapd_data *hapd, u8 *eid)
{
struct ieee80211_he_mu_edca_parameter_set *edca;
+ struct hostapd_wmm_ac_params wmmp[WMM_AC_NUM];
u8 *pos;
size_t i;
+ /* Updating WME Parameter Set Count to avoid mismatch */
+ os_memset(wmmp, 0, sizeof(wmmp));
+
+ if (hapd->conf->wmm_enabled)
+ wmm_calc_regulatory_limit(hapd, wmmp);
+
pos = (u8 *) &hapd->iface->conf->he_mu_edca;
for (i = 0; i < sizeof(*edca); i++) {
if (pos[i])
--- a/src/ap/wmm.c
+++ b/src/ap/wmm.c
@@ -61,8 +61,8 @@ wmm_set_regulatory_limit(const struct ho
/*
* Calculate WMM regulatory limit if any.
*/
-static void wmm_calc_regulatory_limit(struct hostapd_data *hapd,
- struct hostapd_wmm_ac_params *acp)
+void wmm_calc_regulatory_limit(struct hostapd_data *hapd,
+ struct hostapd_wmm_ac_params *acp)
{
struct hostapd_hw_modes *mode = hapd->iface->current_mode;
int c;
@@ -91,6 +91,10 @@ static void wmm_calc_regulatory_limit(st
os_memcpy(hapd->iface->prev_wmm, acp,
sizeof(hapd->iconf->wmm_ac_params));
hapd->parameter_set_count++;
+ /* Incrementing MU-EDCA Parameter Set Update Count*/
+ hapd->iface->conf->he_mu_edca.he_qos_info =
+ (hapd->iface->conf->he_mu_edca.he_qos_info & 0xf0) |
+ ((hapd->iface->conf->he_mu_edca.he_qos_info + 1) & 0xf);
}
}
--- a/src/ap/wmm.h
+++ b/src/ap/wmm.h
@@ -13,6 +13,8 @@
struct ieee80211_mgmt;
struct wmm_tspec_element;
+void wmm_calc_regulatory_limit(struct hostapd_data *hapd,
+ struct hostapd_wmm_ac_params *acp);
u8 * hostapd_eid_wmm(struct hostapd_data *hapd, u8 *eid);
int hostapd_eid_wmm_valid(struct hostapd_data *hapd, const u8 *eid,
size_t len);
--- a/src/drivers/driver.h
+++ b/src/drivers/driver.h
@@ -5786,6 +5786,16 @@ enum wpa_event_type {
EVENT_LINK_CH_SWITCH_STARTED,
/**
+ * EVENT_UPDATE_MUEDCA_PARAMS - Updated MU-EDCA parameters received
+ *
+ * this event is emitted when updated MU-EDCA parameters from driver
+ * are received. updated MU-EDCA parameters need to be updated in
+ * beacon.
+ */
+ EVENT_UPDATE_MUEDCA_PARAMS,
+
+
+ /**
* EVENT_TID_LINK_MAP - MLD event to set TID-to-link mapping
*
* This event is used by the driver to indicate the received TID-to-link
@@ -6752,6 +6762,16 @@ union wpa_event_data {
struct pasn_auth pasn_auth;
/**
+ * struct update_muedca - Data for EVENT_UPDATE_MU_EDCA_PARAMS
+ */
+ struct update_muedca {
+ u8 he_mu_ac_be_param[3];
+ u8 he_mu_ac_bk_param[3];
+ u8 he_mu_ac_vi_param[3];
+ u8 he_mu_ac_vo_param[3];
+ } update_muedca;
+
+ /**
* struct port_authorized - Data for EVENT_PORT_AUTHORIZED
* @td_bitmap: For STA mode, transition disable bitmap, if received in
* EAPOL-Key msg 3/4
--- a/src/drivers/driver_common.c
+++ b/src/drivers/driver_common.c
@@ -98,6 +98,7 @@ const char * event_to_string(enum wpa_ev
E2S(PASN_AUTH);
E2S(LINK_CH_SWITCH);
E2S(LINK_CH_SWITCH_STARTED);
+ E2S(UPDATE_MUEDCA_PARAMS);
E2S(TID_LINK_MAP);
E2S(LINK_RECONFIG);
}
--- a/src/drivers/driver_nl80211_event.c
+++ b/src/drivers/driver_nl80211_event.c
@@ -184,6 +184,7 @@ static const char * nl80211_command_to_s
C2S(NL80211_CMD_ADD_LINK_STA)
C2S(NL80211_CMD_MODIFY_LINK_STA)
C2S(NL80211_CMD_REMOVE_LINK_STA)
+ C2S(NL80211_CMD_UPDATE_HE_MUEDCA_PARAMS)
C2S(NL80211_CMD_SET_HW_TIMESTAMP)
C2S(NL80211_CMD_LINKS_REMOVED)
C2S(__NL80211_CMD_AFTER_LAST)
@@ -3644,6 +3645,35 @@ static void nl80211_sta_opmode_change_ev
wpa_supplicant_event(drv->ctx, EVENT_STATION_OPMODE_CHANGED, &ed);
}
+static void nl80211_update_muedca_params_event(struct wpa_driver_nl80211_data *drv,
+ struct nlattr **tb)
+{
+ struct host_update_muedca {
+ u8 mu_qos_info;
+ u8 ac_be[3];
+ u8 ac_bk[3];
+ u8 ac_vi[3];
+ u8 ac_vo[3];
+ };
+
+ struct host_update_muedca *rx_muedca_params;
+ union wpa_event_data ed;
+ int i;
+
+ if (!tb[NL80211_ATTR_HE_MUEDCA_PARAMS])
+ return;
+
+ rx_muedca_params = nla_data(tb[NL80211_ATTR_HE_MUEDCA_PARAMS]);
+
+ for (i = 0; i< 3; i++) {
+ ed.update_muedca.he_mu_ac_be_param[i] = rx_muedca_params->ac_be[i];
+ ed.update_muedca.he_mu_ac_bk_param[i] = rx_muedca_params->ac_bk[i];
+ ed.update_muedca.he_mu_ac_vi_param[i] = rx_muedca_params->ac_vi[i];
+ ed.update_muedca.he_mu_ac_vo_param[i] = rx_muedca_params->ac_vo[i];
+ }
+
+ wpa_supplicant_event(drv->ctx, EVENT_UPDATE_MUEDCA_PARAMS, &ed);
+}
static void nl80211_control_port_frame(struct wpa_driver_nl80211_data *drv,
struct nlattr **tb)
@@ -4090,6 +4120,9 @@ static void do_process_drv_event(struct
case NL80211_CMD_LINKS_REMOVED:
wpa_supplicant_event(drv->ctx, EVENT_LINK_RECONFIG, NULL);
break;
+ case NL80211_CMD_UPDATE_HE_MUEDCA_PARAMS:
+ nl80211_update_muedca_params_event(drv, tb);
+ break;
default:
wpa_dbg(drv->ctx, MSG_DEBUG, "nl80211: Ignored unknown event "
"(cmd=%d)", cmd);
--- a/src/drivers/nl80211_copy.h
+++ b/src/drivers/nl80211_copy.h
@@ -1323,6 +1323,11 @@
* Multi-Link reconfiguration. %NL80211_ATTR_MLO_LINKS is used to provide
* information about the removed STA MLD setup links.
*
+ * @NL80211_CMD_UPDATE_HE_MUEDCA_PARAMS: Updated MU-EDCA parameters from driver.
+ * This event is used to update MU-EDCA parameters in Beacon frame, which
+ * were indicated by driver and now need to be reflected in
+ * Beacon frame.
+ *
* @NL80211_CMD_MAX: highest used command number
* @__NL80211_CMD_AFTER_LAST: internal use
*/
@@ -1578,6 +1583,7 @@ enum nl80211_commands {
NL80211_CMD_LINKS_REMOVED,
+ NL80211_CMD_UPDATE_HE_MUEDCA_PARAMS,
/* add new commands above here */
/* used to define NL80211_CMD_MAX below */
@@ -2799,6 +2805,9 @@ enum nl80211_commands {
* the incoming frame RX timestamp.
* @NL80211_ATTR_TD_BITMAP: Transition Disable bitmap, for subsequent
* (re)associations.
+ * @NL80211_ATTR_HE_MUEDCA_PARAMS: MU-EDCA AC parameters for the
+ * NL80211_CMD_UPDATE_HE_MUEDCA_PARAMS command.
+ *
*
* @NL80211_ATTR_PUNCT_BITMAP: (u32) Preamble puncturing bitmap, lowest
* bit corresponds to the lowest 20 MHz channel. Each bit set to 1
@@ -3364,6 +3373,7 @@ enum nl80211_attrs {
NL80211_ATTR_MLO_LINK_DISABLED,
+ NL80211_ATTR_HE_MUEDCA_PARAMS,
/* add attributes here, update the policy in nl80211.c */
__NL80211_ATTR_AFTER_LAST,