This allows us to dynamically turn TWT on and off using a nl80211 attribute. Signed-off-by: John Crispin <john@xxxxxxxxxxx> --- src/ap/beacon.c | 3 +++ src/ap/ieee802_11.h | 1 + src/ap/ieee802_11_he.c | 7 +++++++ src/common/ieee802_11_defs.h | 2 ++ src/drivers/driver.h | 5 +++++ src/drivers/driver_nl80211.c | 8 ++++++++ 6 files changed, 26 insertions(+) diff --git a/src/ap/beacon.c b/src/ap/beacon.c index 1838c1c84..7c5e4cd19 100644 --- a/src/ap/beacon.c +++ b/src/ap/beacon.c @@ -1419,6 +1419,9 @@ int ieee802_11_set_beacon(struct hostapd_data *hapd) params.proberesp_ies = proberesp; params.assocresp_ies = assocresp; params.reenable = hapd->reenable_beacon; +#ifdef CONFIG_IEEE80211AX + params.twt_responder = hostapd_get_he_twt_responder(hapd); +#endif hapd->reenable_beacon = 0; if (iface->current_mode && diff --git a/src/ap/ieee802_11.h b/src/ap/ieee802_11.h index 8822a1785..7a8ecf8a9 100644 --- a/src/ap/ieee802_11.h +++ b/src/ap/ieee802_11.h @@ -92,6 +92,7 @@ u16 set_sta_vht_opmode(struct hostapd_data *hapd, struct sta_info *sta, const u8 *vht_opmode); u16 copy_sta_he_capab(struct hostapd_data *hapd, struct sta_info *sta, const u8 *he_capab, size_t he_capab_len); +int hostapd_get_he_twt_responder(struct hostapd_data *hapd); void hostapd_tx_status(struct hostapd_data *hapd, const u8 *addr, const u8 *buf, size_t len, int ack); void hostapd_eapol_tx_status(struct hostapd_data *hapd, const u8 *dst, diff --git a/src/ap/ieee802_11_he.c b/src/ap/ieee802_11_he.c index 0c033c26d..ebb98e1aa 100644 --- a/src/ap/ieee802_11_he.c +++ b/src/ap/ieee802_11_he.c @@ -376,3 +376,10 @@ u16 copy_sta_he_capab(struct hostapd_data *hapd, struct sta_info *sta, return WLAN_STATUS_SUCCESS; } + +int hostapd_get_he_twt_responder(struct hostapd_data *hapd) +{ + u8 *mac_cap = hapd->iface->current_mode->he_capab.mac_cap; + + return mac_cap[0] & HE_MACCAP_TWT_RESPONDER; +} diff --git a/src/common/ieee802_11_defs.h b/src/common/ieee802_11_defs.h index 214ba0e0f..1d302559e 100644 --- a/src/common/ieee802_11_defs.h +++ b/src/common/ieee802_11_defs.h @@ -2139,6 +2139,8 @@ struct ieee80211_spatial_reuse { /* HE Capabilities Information defines */ +#define HE_MACCAP_TWT_RESPONDER ((u8) BIT(3)) + #define HE_PHYCAP_CHANNEL_WIDTH_SET_IDX 0 #define HE_PHYCAP_CHANNEL_WIDTH_MASK ((u8) (BIT(1) | BIT(2) | \ BIT(3) | BIT(4))) diff --git a/src/drivers/driver.h b/src/drivers/driver.h index d0f449f72..c6c87d8fb 100644 --- a/src/drivers/driver.h +++ b/src/drivers/driver.h @@ -1427,6 +1427,11 @@ struct wpa_driver_ap_params { * type 11 as defined in IEEE Std 802.11-2016, 9.4.2.22.13 */ const struct wpabuf *civic; + + /** + * twt_responder - Whether Target Wait Time responder is enabled + */ + int twt_responder; }; struct wpa_driver_mesh_bss_params { diff --git a/src/drivers/driver_nl80211.c b/src/drivers/driver_nl80211.c index 45835a21b..c9f39bee0 100644 --- a/src/drivers/driver_nl80211.c +++ b/src/drivers/driver_nl80211.c @@ -4286,6 +4286,14 @@ static int wpa_driver_nl80211_set_ap(void *priv, nla_nest_end(msg, ftm); } +#ifdef CONFIG_IEEE80211AX + if (params->twt_responder) { + wpa_printf(MSG_DEBUG, "nl80211: twt_responder=%d", + params->twt_responder); + if (nla_put_flag(msg, NL80211_ATTR_TWT_RESPONDER)) + goto fail; + } +#endif ret = send_and_recv_msgs(drv, msg, NULL, NULL); if (ret) { wpa_printf(MSG_DEBUG, "nl80211: Beacon set failed: %d (%s)", -- 2.20.1 _______________________________________________ Hostap mailing list Hostap@xxxxxxxxxxxxxxxxxxx http://lists.infradead.org/mailman/listinfo/hostap