diff --git a/drivers/wifi/nxp/nxp_wifi_drv.c b/drivers/wifi/nxp/nxp_wifi_drv.c index 443426395383740..1216e47dc4f2db2 100644 --- a/drivers/wifi/nxp/nxp_wifi_drv.c +++ b/drivers/wifi/nxp/nxp_wifi_drv.c @@ -1352,10 +1352,12 @@ static int nxp_wifi_set_twt(const struct device *dev, struct wifi_twt_params *pa twt_setup_conf.implicit = params->setup.implicit; twt_setup_conf.announced = params->setup.announce; twt_setup_conf.trigger_enabled = params->setup.trigger; + twt_setup_conf.twt_info_disabled = params->setup.twt_info_disable; twt_setup_conf.negotiation_type = params->negotiation_type; twt_setup_conf.twt_wakeup_duration = params->setup.twt_wake_interval; twt_setup_conf.flow_identifier = params->flow_id; twt_setup_conf.hard_constraint = 1; + twt_setup_conf.twt_exponent = params->setup.exponent; twt_setup_conf.twt_mantissa = params->setup.twt_interval; twt_setup_conf.twt_request = params->setup.responder; ret = wlan_set_twt_setup_cfg(&twt_setup_conf); diff --git a/include/zephyr/net/wifi_mgmt.h b/include/zephyr/net/wifi_mgmt.h index 4fa161d1c06b582..e0b30654e0ff8c2 100644 --- a/include/zephyr/net/wifi_mgmt.h +++ b/include/zephyr/net/wifi_mgmt.h @@ -739,6 +739,10 @@ struct wifi_twt_params { * prepare the data before TWT SP starts. */ uint32_t twt_wake_ahead_duration; + /** TWT info enabled or disable */ + bool twt_info_disable; + /** TWT exponent */ + uint8_t exponent; } setup; /** Teardown specific parameters */ struct { @@ -758,6 +762,7 @@ struct wifi_twt_params { /* 256 (u8) * 1TU */ #define WIFI_MAX_TWT_WAKE_INTERVAL_US 262144 #define WIFI_MAX_TWT_WAKE_AHEAD_DURATION_US (LONG_MAX - 1) +#define WIFI_MAX_TWT_EXPONENT 63 /** @endcond */ diff --git a/subsys/net/l2/wifi/wifi_shell.c b/subsys/net/l2/wifi/wifi_shell.c index 171968095c775da..45e8b91c10fa4f7 100644 --- a/subsys/net/l2/wifi/wifi_shell.c +++ b/subsys/net/l2/wifi/wifi_shell.c @@ -1499,6 +1499,7 @@ static int cmd_wifi_twt_setup_quick(const struct shell *sh, size_t argc, params.setup.implicit = 1; params.setup.trigger = 0; params.setup.announce = 0; + params.setup.exponent = 10; if (!parse_number(sh, &value, argv[idx++], NULL, 1, WIFI_MAX_TWT_WAKE_INTERVAL_US)) { return -EINVAL; @@ -1526,74 +1527,149 @@ static int cmd_wifi_twt_setup_quick(const struct shell *sh, size_t argc, return 0; } -static int cmd_wifi_twt_setup(const struct shell *sh, size_t argc, - char *argv[]) +static int twt_args_to_params(const struct shell *sh, size_t argc, char *argv[], + struct wifi_twt_params *params) { - struct net_if *iface = net_if_get_first_wifi(); - struct wifi_twt_params params = { 0 }; - int idx = 1; + int opt; + int opt_index = 0; + struct getopt_state *state; long value; + static const struct option long_options[] = { + {"negotiation-type", required_argument, 0, 'n'}, + {"setup-cmd", required_argument, 0, 'c'}, + {"dialog-token", required_argument, 0, 't'}, + {"flow-id", required_argument, 0, 'f'}, + {"responder", required_argument, 0, 'r'}, + {"trigger", required_argument, 0, 'T'}, + {"implicit", required_argument, 0, 'I'}, + {"announce", required_argument, 0, 'a'}, + {"wake-interval", required_argument, 0, 'w'}, + {"interval", required_argument, 0, 'i'}, + {"wake-ahead-duration", required_argument, 0, 'D'}, + {"info-disable", required_argument, 0, 'd'}, + {"exponent", required_argument, 0, 'e'}, + {"help", no_argument, 0, 'h'}, + {0, 0, 0, 0}}; - context.sh = sh; - - params.operation = WIFI_TWT_SETUP; + params->operation = WIFI_TWT_SETUP; - if (!parse_number(sh, &value, argv[idx++], NULL, WIFI_TWT_INDIVIDUAL, - WIFI_TWT_WAKE_TBTT)) { - return -EINVAL; - } - params.negotiation_type = (enum wifi_twt_negotiation_type)value; + while ((opt = getopt_long(argc, argv, "n:c:t:f:r:T:I:a:t:w:i:D:d:e:h", + long_options, &opt_index)) != -1) { + state = getopt_state_get(); + switch (opt) { + case 'n': + if (!parse_number(sh, &value, state->optarg, NULL, WIFI_TWT_INDIVIDUAL, WIFI_TWT_WAKE_TBTT)) { + return -EINVAL; + } + params->negotiation_type = (enum wifi_twt_negotiation_type)value; + break; - if (!parse_number(sh, &value, argv[idx++], NULL, WIFI_TWT_SETUP_CMD_REQUEST, + case 'c': + if (!parse_number(sh, &value, state->optarg, NULL, WIFI_TWT_SETUP_CMD_REQUEST, WIFI_TWT_SETUP_CMD_DEMAND)) { - return -EINVAL; - } - params.setup_cmd = (enum wifi_twt_setup_cmd)value; + return -EINVAL; + } + params->setup_cmd = (enum wifi_twt_setup_cmd)value; + break; - if (!parse_number(sh, &value, argv[idx++], NULL, 1, 255)) { - return -EINVAL; - } - params.dialog_token = (uint8_t)value; + case 't': + if (!parse_number(sh, &value, state->optarg, NULL, 1, 255)) { + return -EINVAL; + } + params->dialog_token = (uint8_t)value; + break; - if (!parse_number(sh, &value, argv[idx++], NULL, 0, (WIFI_MAX_TWT_FLOWS - 1))) { - return -EINVAL; - } - params.flow_id = (uint8_t)value; + case 'f': + if (!parse_number(sh, &value, state->optarg, NULL, 0, (WIFI_MAX_TWT_FLOWS - 1))) { + return -EINVAL; + } + params->flow_id = (uint8_t)value; + break; - if (!parse_number(sh, &value, argv[idx++], NULL, 0, 1)) { - return -EINVAL; - } - params.setup.responder = (bool)value; + case 'r': + if (!parse_number(sh, &value, state->optarg, NULL, 0, 1)) { + return -EINVAL; + } + params->setup.responder = (bool)value; + break; - if (!parse_number(sh, &value, argv[idx++], NULL, 0, 1)) { - return -EINVAL; - } - params.setup.trigger = (bool)value; + case 'T': + if (!parse_number(sh, &value, state->optarg, NULL, 0, 1)) { + return -EINVAL; + } + params->setup.trigger = (bool)value; + break; - if (!parse_number(sh, &value, argv[idx++], NULL, 0, 1)) { - return -EINVAL; - } - params.setup.implicit = (bool)value; + case 'I': + if (!parse_number(sh, &value, state->optarg, NULL, 0, 1)) { + return -EINVAL; + } + params->setup.implicit = (bool)value; + break; - if (!parse_number(sh, &value, argv[idx++], NULL, 0, 1)) { - return -EINVAL; - } - params.setup.announce = (bool)value; + case 'a': + if (!parse_number(sh, &value, state->optarg, NULL, 0, 1)) { + return -EINVAL; + } + params->setup.announce = (bool)value; + break; - if (!parse_number(sh, &value, argv[idx++], NULL, 1, WIFI_MAX_TWT_WAKE_INTERVAL_US)) { - return -EINVAL; - } - params.setup.twt_wake_interval = (uint32_t)value; + case 'w': + if (!parse_number(sh, &value, state->optarg, NULL, 1, WIFI_MAX_TWT_WAKE_INTERVAL_US)) { + return -EINVAL; + } + params->setup.twt_wake_interval = (uint32_t)value; + break; - if (!parse_number(sh, &value, argv[idx++], NULL, 1, WIFI_MAX_TWT_INTERVAL_US)) { - return -EINVAL; + case 'i': + if (!parse_number(sh, &value, state->optarg, NULL, 1, WIFI_MAX_TWT_INTERVAL_US)) { + return -EINVAL; + } + params->setup.twt_interval = (uint64_t)value; + break; + + case 'D': + if (!parse_number(sh, &value, state->optarg, NULL, 0, + WIFI_MAX_TWT_WAKE_AHEAD_DURATION_US)) { + return -EINVAL; + } + params->setup.twt_wake_ahead_duration = (uint32_t)value; + break; + + case 'd': + if (!parse_number(sh, &value, state->optarg, NULL, 0, 1)) { + return -EINVAL; + } + params->setup.twt_info_disable = (bool)value; + break; + + case 'e': + if (!parse_number(sh, &value, state->optarg, NULL, 0, WIFI_MAX_TWT_EXPONENT)) { + return -EINVAL; + } + params->setup.exponent = (uint8_t)value; + break; + + case 'h': + return -ENOEXEC; + } } - params.setup.twt_interval = (uint64_t)value; - if (!parse_number(sh, &value, argv[idx++], NULL, 0, WIFI_MAX_TWT_WAKE_AHEAD_DURATION_US)) { - return -EINVAL; + return 0; +} + +static int cmd_wifi_twt_setup(const struct shell *sh, size_t argc, + char *argv[]) +{ + struct net_if *iface = net_if_get_first_wifi(); + struct wifi_twt_params params = { 0 }; + + context.sh = sh; + + if (twt_args_to_params(sh, argc, argv, ¶ms)) { + shell_help(sh); + return -ENOEXEC; } - params.setup.twt_wake_ahead_duration = (uint32_t)value; if (net_mgmt(NET_REQUEST_WIFI_TWT, iface, ¶ms, sizeof(params))) { PR_WARNING("%s with %s failed. reason : %s\n", @@ -1645,6 +1721,11 @@ static int cmd_wifi_twt_teardown(const struct shell *sh, size_t argc, } params.flow_id = (uint8_t)value; + if (!parse_number(sh, &value, argv[idx++], NULL, 0, 1)) { + return -EINVAL; + } + params.teardown.teardown_all = (bool)value; + if (net_mgmt(NET_REQUEST_WIFI_TWT, iface, ¶ms, sizeof(params))) { PR_WARNING("%s with %s failed, reason : %s\n", wifi_twt_operation_txt(params.operation), @@ -3180,19 +3261,28 @@ SHELL_STATIC_SUBCMD_SET_CREATE(wifi_twt_ops, cmd_wifi_twt_setup_quick, 3, 0), SHELL_CMD_ARG(setup, NULL, " Start a TWT flow:\n" - "\n" - "\n" - " " - " .\n" - ": 0us-2^31us>\n", + "<-n --negotiation-type>: 0: Individual, 1: Broadcast, 2: Wake TBTT\n" + "<-c --setup-cmd>: 0: Request, 1: Suggest, 2: Demand\n" + "<-t --dialog-token>: 1-255\n" + "<-f --flow-id>: 0-7\n" + "<-r --responder>: 0/1\n" + "<-T --trigger>: 0/1\n" + "<-I --implicit>:0/1\n" + "<-a --announce>: 0/1\n" + "<-w --wake-interval>: 1-262144us\n" + "<-i --interval>: 1us-2^31us\n" + "<-D --wake-ahead-duration>: 0us-2^31us\n" + "<-d --info-disable>: 0/1\n" + "<-e --exponent>: 0-63\n" + "[-h, --help]: Print out command usage.\n", cmd_wifi_twt_setup, - 12, 0), + 27, 1), SHELL_CMD_ARG(teardown, NULL, " Teardown a TWT flow:\n" "\n" "\n" - " .\n", + " .\n", cmd_wifi_twt_teardown, - 5, 0), + 6, 0), SHELL_CMD_ARG(teardown_all, NULL, " Teardown all TWT flows.\n", cmd_wifi_twt_teardown_all, 1, 0),