modules: hostap: add 11k cmd support

Add 11k cmds support. User can issue 11k cmds to enable/disable 11k and
send Neighbor Report Request packet.

Signed-off-by: Hui Bai <hui.bai@nxp.com>
This commit is contained in:
Hui Bai 2024-09-12 14:16:22 +08:00 committed by Alberto Escolar
parent 3ca71c94df
commit 7c167c67c3
7 changed files with 237 additions and 0 deletions

View File

@ -1055,6 +1055,17 @@ static void nxp_wifi_auto_connect(void)
}
#endif
static int nxp_wifi_11k_cfg(const struct device *dev, struct wifi_11k_params *params)
{
if (params->oper == WIFI_MGMT_GET) {
params->enable_11k = wlan_get_host_11k_status();
} else {
wlan_host_11k_cfg(params->enable_11k);
}
return 0;
}
static int nxp_wifi_power_save(const struct device *dev, struct wifi_ps_params *params)
{
int status = NXP_WIFI_RET_SUCCESS;
@ -1640,6 +1651,7 @@ static const struct wifi_mgmt_ops nxp_wifi_sta_mgmt = {
#if defined(CONFIG_NET_STATISTICS_WIFI)
.get_stats = nxp_wifi_stats,
#endif
.cfg_11k = nxp_wifi_11k_cfg,
.set_power_save = nxp_wifi_power_save,
.get_power_save_config = nxp_wifi_get_power_save,
.set_twt = nxp_wifi_set_twt,

View File

@ -71,6 +71,10 @@ enum net_request_wifi_cmd {
NET_REQUEST_WIFI_CMD_AP_DISABLE,
/** Get interface status */
NET_REQUEST_WIFI_CMD_IFACE_STATUS,
/** Set or get 11k status */
NET_REQUEST_WIFI_CMD_11K_CONFIG,
/** Send 11k neighbor request */
NET_REQUEST_WIFI_CMD_11K_NEIGHBOR_REQUEST,
/** Set power save status */
NET_REQUEST_WIFI_CMD_PS,
/** Setup or teardown TWT flow */
@ -154,6 +158,16 @@ NET_MGMT_DEFINE_REQUEST_HANDLER(NET_REQUEST_WIFI_AP_DISABLE);
NET_MGMT_DEFINE_REQUEST_HANDLER(NET_REQUEST_WIFI_IFACE_STATUS);
#define NET_REQUEST_WIFI_11K_CONFIG \
(_NET_WIFI_BASE | NET_REQUEST_WIFI_CMD_11K_CONFIG)
NET_MGMT_DEFINE_REQUEST_HANDLER(NET_REQUEST_WIFI_11K_CONFIG);
#define NET_REQUEST_WIFI_11K_NEIGHBOR_REQUEST \
(_NET_WIFI_BASE | NET_REQUEST_WIFI_CMD_11K_NEIGHBOR_REQUEST)
NET_MGMT_DEFINE_REQUEST_HANDLER(NET_REQUEST_WIFI_11K_NEIGHBOR_REQUEST);
/** Request a Wi-Fi power save */
#define NET_REQUEST_WIFI_PS \
(_NET_WIFI_BASE | NET_REQUEST_WIFI_CMD_PS)
@ -769,6 +783,16 @@ enum wifi_mgmt_op {
WIFI_MGMT_SET = 1,
};
/** Wi-Fi 11k parameters */
struct wifi_11k_params {
/** 11k command operation */
enum wifi_mgmt_op oper;
/** 11k enable/disable */
bool enable_11k;
/** SSID */
uint8_t ssid[WIFI_SSID_MAX_LEN + 1];
};
/** Max regulatory channel number */
#define MAX_REG_CHAN_NUM 42
@ -1227,6 +1251,22 @@ struct wifi_mgmt_ops {
*/
int (*reset_stats)(const struct device *dev);
#endif /* CONFIG_NET_STATISTICS_WIFI */
/** Set or get 11K status
*
* @param dev Pointer to the device structure for the driver instance.
* @param params 11k parameters
*
* @return 0 if ok, < 0 if error
*/
int (*cfg_11k)(const struct device *dev, struct wifi_11k_params *params);
/** Send 11k neighbor request
*
* @param dev Pointer to the device structure for the driver instance.
* @param params 11k parameters
*
* @return 0 if ok, < 0 if error
*/
int (*send_11k_neighbor_request)(const struct device *dev, struct wifi_11k_params *params);
/** Set power save status
*
* @param dev Pointer to the device structure for the driver instance.

View File

@ -1384,6 +1384,48 @@ out:
return ret;
}
int supplicant_11k_cfg(const struct device *dev, struct wifi_11k_params *params)
{
const struct wifi_mgmt_ops *const wifi_mgmt_api = get_wifi_mgmt_api(dev);
if (!wifi_mgmt_api || !wifi_mgmt_api->cfg_11k) {
wpa_printf(MSG_ERROR, "cfg 11k not supported");
return -ENOTSUP;
}
return wifi_mgmt_api->cfg_11k(dev, params);
}
int supplicant_11k_neighbor_request(const struct device *dev, struct wifi_11k_params *params)
{
int ssid_len = strlen(params->ssid);
if (params != NULL && ssid_len > 0) {
if (ssid_len > WIFI_SSID_MAX_LEN) {
wpa_printf(MSG_ERROR, "%s: ssid too long %u",
__func__, ssid_len);
return -1;
}
if (!wpa_cli_cmd_v("neighbor_rep_request ssid %s",
params->ssid)) {
wpa_printf(MSG_ERROR,
"%s: cli cmd <neighbor_rep_request ssid %s> fail",
__func__, params->ssid);
return -1;
}
} else {
if (!wpa_cli_cmd_v("neighbor_rep_request")) {
wpa_printf(MSG_ERROR,
"%s: cli cmd <neighbor_rep_request> fail",
__func__);
return -1;
}
}
return 0;
}
int supplicant_set_power_save(const struct device *dev, struct wifi_ps_params *params)
{
const struct wifi_mgmt_ops *const wifi_mgmt_api = get_wifi_mgmt_api(dev);

View File

@ -100,6 +100,24 @@ int supplicant_reset_stats(const struct device *dev);
*/
int supplicant_pmksa_flush(const struct device *dev);
/** Set or get 11K status
*
* @param dev Pointer to the device structure for the driver instance.
* @param params 11k parameters
*
* @return 0 if ok, < 0 if error
*/
int supplicant_11k_cfg(const struct device *dev, struct wifi_11k_params *params);
/** Send 11k neighbor request
*
* @param dev Pointer to the device structure for the driver instance.
* @param params 11k parameters
*
* @return 0 if ok, < 0 if error
*/
int supplicant_11k_neighbor_request(const struct device *dev, struct wifi_11k_params *params);
/**
* @brief Set Wi-Fi power save configuration
*

View File

@ -62,6 +62,8 @@ static const struct wifi_mgmt_ops mgmt_ops = {
.get_stats = supplicant_get_stats,
.reset_stats = supplicant_reset_stats,
#endif
.cfg_11k = supplicant_11k_cfg,
.send_11k_neighbor_request = supplicant_11k_neighbor_request,
.set_power_save = supplicant_set_power_save,
.set_twt = supplicant_set_twt,
.get_power_save_config = supplicant_get_power_save_config,

View File

@ -555,6 +555,39 @@ static int wifi_iface_stats_reset(uint32_t mgmt_request, struct net_if *iface,
NET_MGMT_REGISTER_REQUEST_HANDLER(NET_REQUEST_STATS_RESET_WIFI, wifi_iface_stats_reset);
#endif /* CONFIG_NET_STATISTICS_WIFI */
static int wifi_11k_cfg(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_11k_params *params = data;
if (wifi_mgmt_api == NULL || wifi_mgmt_api->cfg_11k == NULL) {
return -ENOTSUP;
}
return wifi_mgmt_api->cfg_11k(dev, params);
}
NET_MGMT_REGISTER_REQUEST_HANDLER(NET_REQUEST_WIFI_11K_CONFIG, wifi_11k_cfg);
static int wifi_11k_neighbor_request(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_11k_params *params = data;
if (wifi_mgmt_api == NULL || wifi_mgmt_api->send_11k_neighbor_request == NULL) {
return -ENOTSUP;
}
return wifi_mgmt_api->send_11k_neighbor_request(dev, params);
}
NET_MGMT_REGISTER_REQUEST_HANDLER(NET_REQUEST_WIFI_11K_NEIGHBOR_REQUEST,
wifi_11k_neighbor_request);
static int wifi_set_power_save(uint32_t mgmt_request, struct net_if *iface,
void *data, size_t len)
{

View File

@ -1172,6 +1172,84 @@ static int cmd_wifi_stats(const struct shell *sh, size_t argc, char *argv[])
return 0;
}
static int cmd_wifi_11k(const struct shell *sh, size_t argc, char *argv[])
{
struct net_if *iface = net_if_get_first_wifi();
struct wifi_11k_params params = { 0 };
context.sh = sh;
if (argc > 2) {
PR_WARNING("Invalid number of arguments\n");
return -ENOEXEC;
}
if (argc == 1) {
params.oper = WIFI_MGMT_GET;
} else {
params.oper = WIFI_MGMT_SET;
if (!strncasecmp(argv[1], "enable", 2)) {
params.enable_11k = true;
} else if (!strncasecmp(argv[1], "disable", 3)) {
params.enable_11k = false;
} else {
PR_WARNING("Invalid argument\n");
return -ENOEXEC;
}
}
if (net_mgmt(NET_REQUEST_WIFI_11K_CONFIG, iface, &params, sizeof(params))) {
PR_WARNING("11k enable/disable failed\n");
return -ENOEXEC;
}
if (params.oper == WIFI_MGMT_GET) {
PR("11k is %s\n", params.enable_11k ? "disabled" : "enabled");
} else {
PR("%s %s requested\n", argv[0], argv[1]);
}
return 0;
}
static int cmd_wifi_11k_neighbor_request(const struct shell *sh, size_t argc, char *argv[])
{
struct net_if *iface = net_if_get_first_wifi();
struct wifi_11k_params params = { 0 };
context.sh = sh;
if ((argc != 1 && argc != 3) || (argc == 3 && !strncasecmp("ssid", argv[1], 4))) {
PR_WARNING("Invalid input arguments\n");
PR_WARNING("Usage: %s\n", argv[0]);
PR_WARNING("or %s ssid <ssid>\n", argv[0]);
return -ENOEXEC;
}
if (argc == 3) {
if (strlen(argv[2]) > (sizeof(params.ssid) - 1)) {
PR_WARNING("Error: ssid too long\n");
return -ENOEXEC;
}
(void)memcpy((void *)params.ssid, (const void *)argv[2],
(size_t)strlen(argv[2]));
}
if (net_mgmt(NET_REQUEST_WIFI_11K_NEIGHBOR_REQUEST, iface, &params, sizeof(params))) {
PR_WARNING("11k neighbor request failed\n");
return -ENOEXEC;
}
if (argc == 3) {
PR("%s %s %s requested\n", argv[0], argv[1], argv[2]);
} else {
PR("%s requested\n", argv[0]);
}
return 0;
}
static int cmd_wifi_ps(const struct shell *sh, size_t argc, char *argv[])
{
struct net_if *iface = net_if_get_first_wifi();
@ -3057,6 +3135,18 @@ SHELL_SUBCMD_ADD((wifi), dpp, &wifi_cmd_dpp,
SHELL_SUBCMD_SET_CREATE(wifi_commands, (wifi));
SHELL_SUBCMD_ADD((wifi), 11k, &wifi_commands,
"Configure 11k or get 11k status.\n"
"[enable/disable]\n",
cmd_wifi_11k,
1, 1);
SHELL_SUBCMD_ADD((wifi), 11k_neighbor_request, &wifi_commands,
"Send Neighbor Report Request frame.\n"
"[ssid <ssid>]\n",
cmd_wifi_11k_neighbor_request,
1, 2);
#ifdef CONFIG_WIFI_NM_WPA_SUPPLICANT_WNM
SHELL_SUBCMD_ADD((wifi), 11v_btm_query, &wifi_commands,
"<query_reason: The reason code for a BSS transition management query>.\n",