diff --git a/drivers/wifi/nxp/nxp_wifi_drv.c b/drivers/wifi/nxp/nxp_wifi_drv.c index 1216e47dc4f2db2..52a77d5570dbe62 100644 --- a/drivers/wifi/nxp/nxp_wifi_drv.c +++ b/drivers/wifi/nxp/nxp_wifi_drv.c @@ -1370,6 +1370,25 @@ static int nxp_wifi_set_twt(const struct device *dev, struct wifi_twt_params *pa return ret; } + +static int nxp_wifi_set_btwt(const struct device *dev, struct wifi_twt_params *params) +{ + wlan_btwt_config_t btwt_config; + int ret = -1; + + btwt_config.action = 1; + btwt_config.sub_id = params->btwt.sub_id; + btwt_config.nominal_wake = params->btwt.nominal_wake; + btwt_config.max_sta_support = params->btwt.max_sta_support; + btwt_config.twt_mantissa = params->btwt.twt_interval; + btwt_config.twt_offset = params->btwt.twt_offset; + btwt_config.twt_exponent = params->btwt.twt_exponent; + btwt_config.sp_gap = params->btwt.sp_gap; + + ret = wlan_set_btwt_cfg(&btwt_config); + + return ret; +} #endif static void nxp_wifi_sta_init(struct net_if *iface) @@ -1731,6 +1750,9 @@ static const struct wifi_mgmt_ops nxp_wifi_uap_mgmt = { .set_power_save = nxp_wifi_power_save, .get_power_save_config = nxp_wifi_get_power_save, .ap_config_params = nxp_wifi_ap_config_params, +#ifdef CONFIG_NXP_WIFI_11AX_TWT + .set_btwt = nxp_wifi_set_btwt, +#endif }; static const struct net_wifi_mgmt_offload nxp_wifi_uap_apis = { diff --git a/include/zephyr/net/wifi_mgmt.h b/include/zephyr/net/wifi_mgmt.h index e0b30654e0ff8c2..d455b23c1d99f06 100644 --- a/include/zephyr/net/wifi_mgmt.h +++ b/include/zephyr/net/wifi_mgmt.h @@ -85,6 +85,8 @@ enum net_request_wifi_cmd { NET_REQUEST_WIFI_CMD_PS, /** Setup or teardown TWT flow */ NET_REQUEST_WIFI_CMD_TWT, + /** Setup BTWT flow */ + NET_REQUEST_WIFI_CMD_BTWT, /** Get power save config */ NET_REQUEST_WIFI_CMD_PS_CONFIG, /** Set or get regulatory domain */ @@ -194,6 +196,11 @@ NET_MGMT_DEFINE_REQUEST_HANDLER(NET_REQUEST_WIFI_PS); NET_MGMT_DEFINE_REQUEST_HANDLER(NET_REQUEST_WIFI_TWT); +#define NET_REQUEST_WIFI_BTWT \ + (_NET_WIFI_BASE | NET_REQUEST_WIFI_CMD_BTWT) + +NET_MGMT_DEFINE_REQUEST_HANDLER(NET_REQUEST_WIFI_BTWT); + /** Request a Wi-Fi power save configuration */ #define NET_REQUEST_WIFI_PS_CONFIG \ (_NET_WIFI_BASE | NET_REQUEST_WIFI_CMD_PS_CONFIG) @@ -744,6 +751,23 @@ struct wifi_twt_params { /** TWT exponent */ uint8_t exponent; } setup; + /** Setup specific parameters */ + struct { + /** Broadcast TWT AP config */ + uint16_t sub_id; + /** Range 64-255 */ + uint8_t nominal_wake; + /** Max STA support */ + uint8_t max_sta_support; + /** TWT interval */ + uint16_t twt_interval; + /** TWT offset */ + uint16_t twt_offset; + /** TWT exponent */ + uint8_t twt_exponent; + /** SP gap */ + uint8_t sp_gap; + } btwt; /** Teardown specific parameters */ struct { /** Teardown all flows */ @@ -1350,6 +1374,14 @@ struct wifi_mgmt_ops { * @return 0 if ok, < 0 if error */ int (*set_twt)(const struct device *dev, struct wifi_twt_params *params); + /** Setup BTWT flow + * + * @param dev Pointer to the device structure for the driver instance. + * @param params BTWT parameters + * + * @return 0 if ok, < 0 if error + */ + int (*set_btwt)(const struct device *dev, struct wifi_twt_params *params); /** Get power save config * * @param dev Pointer to the device structure for the driver instance. diff --git a/modules/hostap/src/supp_api.c b/modules/hostap/src/supp_api.c index 13155af5cf3b228..e7d11ff5fed94bb 100644 --- a/modules/hostap/src/supp_api.c +++ b/modules/hostap/src/supp_api.c @@ -1808,6 +1808,18 @@ int supplicant_set_twt(const struct device *dev, struct wifi_twt_params *params) return wifi_mgmt_api->set_twt(dev, params); } +int supplicant_set_btwt(const struct device *dev, struct wifi_twt_params *params) +{ + const struct wifi_mgmt_ops *const wifi_mgmt_api = get_wifi_mgmt_api(dev); + + if (!wifi_mgmt_api || !wifi_mgmt_api->set_btwt) { + wpa_printf(MSG_ERROR, "Set TWT not supported"); + return -ENOTSUP; + } + + return wifi_mgmt_api->set_btwt(dev, params); +} + int supplicant_get_power_save_config(const struct device *dev, struct wifi_ps_config *config) { diff --git a/modules/hostap/src/supp_api.h b/modules/hostap/src/supp_api.h index ab1e6c014eb1c5a..f817e2939a979e9 100644 --- a/modules/hostap/src/supp_api.h +++ b/modules/hostap/src/supp_api.h @@ -156,6 +156,15 @@ int supplicant_set_power_save(const struct device *dev, struct wifi_ps_params *p */ int supplicant_set_twt(const struct device *dev, struct wifi_twt_params *params); +/** + * @brief Set Wi-Fi BTWT parameters + * + * @param dev Wi-Fi interface name to use + * @param params BTWT parameters to set + * @return 0 for OK; -1 for ERROR + */ +int supplicant_set_btwt(const struct device *dev, struct wifi_twt_params *params); + /** * @brief Get Wi-Fi power save configuration * diff --git a/modules/hostap/src/supp_main.c b/modules/hostap/src/supp_main.c index 5ac548034693ed5..b90f69ba41eafc4 100644 --- a/modules/hostap/src/supp_main.c +++ b/modules/hostap/src/supp_main.c @@ -114,6 +114,7 @@ static const struct wifi_mgmt_ops mgmt_ap_ops = { #ifdef CONFIG_WIFI_NM_HOSTAPD_CRYPTO_ENTERPRISE .enterprise_creds = supplicant_add_enterprise_creds, #endif + .set_btwt = supplicant_set_btwt, }; DEFINE_WIFI_NM_INSTANCE(hostapd, &mgmt_ap_ops); diff --git a/subsys/net/l2/wifi/wifi_mgmt.c b/subsys/net/l2/wifi/wifi_mgmt.c index 659b13fb81c14c3..2ee322f98530ce3 100644 --- a/subsys/net/l2/wifi/wifi_mgmt.c +++ b/subsys/net/l2/wifi/wifi_mgmt.c @@ -901,6 +901,35 @@ static int wifi_set_twt(uint32_t mgmt_request, struct net_if *iface, NET_MGMT_REGISTER_REQUEST_HANDLER(NET_REQUEST_WIFI_TWT, wifi_set_twt); +static int wifi_set_btwt(uint32_t mgmt_request, struct net_if *iface, + void *data, size_t len) +{ + const struct device *dev = net_if_get_device(iface); + const struct wifi_mgmt_ops *const wifi_mgmt_api = get_wifi_api(iface); + struct wifi_twt_params *twt_params = data; + struct wifi_iface_status info = { 0 }; + + if (wifi_mgmt_api == NULL || wifi_mgmt_api->set_btwt == NULL) { + twt_params->fail_reason = + WIFI_TWT_FAIL_OPERATION_NOT_SUPPORTED; + return -ENOTSUP; + } + + if (net_mgmt(NET_REQUEST_WIFI_IFACE_STATUS, iface, &info, + sizeof(struct wifi_iface_status))) { + twt_params->fail_reason = + WIFI_TWT_FAIL_UNABLE_TO_GET_IFACE_STATUS; + goto fail; + } + + return wifi_mgmt_api->set_btwt(dev, twt_params); +fail: + return -ENOEXEC; + +} + +NET_MGMT_REGISTER_REQUEST_HANDLER(NET_REQUEST_WIFI_BTWT, wifi_set_btwt); + void wifi_mgmt_raise_twt_event(struct net_if *iface, struct wifi_twt_params *twt_params) { net_mgmt_event_notify_with_info(NET_EVENT_WIFI_TWT, diff --git a/subsys/net/l2/wifi/wifi_shell.c b/subsys/net/l2/wifi/wifi_shell.c index 45e8b91c10fa4f7..730b8bc643426a9 100644 --- a/subsys/net/l2/wifi/wifi_shell.c +++ b/subsys/net/l2/wifi/wifi_shell.c @@ -1527,6 +1527,45 @@ static int cmd_wifi_twt_setup_quick(const struct shell *sh, size_t argc, return 0; } +static int cmd_wifi_btwt_setup(const struct shell *sh, size_t argc, char *argv[]) +{ + struct net_if *iface = net_if_get_wifi_sap(); + struct wifi_twt_params params = {0}; + int idx = 1; + long value; + + context.sh = sh; + + params.btwt.sub_id = (uint16_t)strtol(argv[idx++], NULL, 10); + params.btwt.nominal_wake = (uint8_t)strtol(argv[idx++], NULL, 10); + params.btwt.max_sta_support = (uint8_t)strtol(argv[idx++], NULL, 10); + + if (!parse_number(sh, &value, argv[idx++], NULL, 1, WIFI_MAX_TWT_INTERVAL_US)) { + return -EINVAL; + } + params.btwt.twt_interval = (uint16_t)value; + + params.btwt.twt_offset = (uint16_t)strtol(argv[idx++], NULL, 10); + + if (!parse_number(sh, &value, argv[idx++], NULL, 0, WIFI_MAX_TWT_EXPONENT)) { + return -EINVAL; + } + params.btwt.twt_exponent = (uint8_t)value; + + params.btwt.sp_gap = (uint8_t)strtol(argv[idx++], NULL, 10); + + if (net_mgmt(NET_REQUEST_WIFI_BTWT, iface, ¶ms, sizeof(params))) { + PR_WARNING("Failed reason : %s\n", + wifi_twt_get_err_code_str(params.fail_reason)); + + return -ENOEXEC; + } + + PR("BTWT setup\n"); + + return 0; +} + static int twt_args_to_params(const struct shell *sh, size_t argc, char *argv[], struct wifi_twt_params *params) { @@ -3277,6 +3316,13 @@ SHELL_STATIC_SUBCMD_SET_CREATE(wifi_twt_ops, "[-h, --help]: Print out command usage.\n", cmd_wifi_twt_setup, 27, 1), + SHELL_CMD_ARG( + btwt_setup, NULL, + " Start a BTWT flow:\n" + " " + " .\n", + cmd_wifi_btwt_setup, + 8, 0), SHELL_CMD_ARG(teardown, NULL, " Teardown a TWT flow:\n" "\n" "\n"