net: wifi_mgmt: linearise scan_params->chan arrays

Turn the nested arrays of `scan_params->chan` into a single array.
This adds the requirement to specify the band for each channel, but
eliminates the large amount of dead memory for unused bands. Overall,
this saves 50% of the RAM space for this variable.

Signed-off-by: Jordan Yates <jordan.yates@data61.csiro.au>
This commit is contained in:
Jordan Yates 2023-09-16 15:54:28 +10:00 committed by Carles Cufí
commit b54951b86e
5 changed files with 47 additions and 17 deletions

View file

@ -209,6 +209,16 @@ enum net_event_wifi_cmd {
#define NET_EVENT_WIFI_DISCONNECT_COMPLETE \ #define NET_EVENT_WIFI_DISCONNECT_COMPLETE \
(_NET_WIFI_EVENT | NET_EVENT_WIFI_CMD_DISCONNECT_COMPLETE) (_NET_WIFI_EVENT | NET_EVENT_WIFI_CMD_DISCONNECT_COMPLETE)
/**
* @brief Wi-Fi structure to uniquely identify a band-channel pair
*/
struct wifi_band_channel {
/** Frequency band */
uint8_t band;
/** Channel */
uint8_t channel;
};
/** /**
* @brief Wi-Fi scan parameters structure. * @brief Wi-Fi scan parameters structure.
* Used to specify parameters which can control how the Wi-Fi scan * Used to specify parameters which can control how the Wi-Fi scan
@ -248,9 +258,9 @@ struct wifi_scan_params {
* band. * band.
* E.g. to scan channel 6 and 11 on the 2.4 GHz band, channel 36 on the 5 GHz band: * E.g. to scan channel 6 and 11 on the 2.4 GHz band, channel 36 on the 5 GHz band:
* @code{.c} * @code{.c}
* chan[WIFI_FREQ_BAND_2_4_GHZ][0] = 6; * chan[0] = {WIFI_FREQ_BAND_2_4_GHZ, 6};
* chan[WIFI_FREQ_BAND_2_4_GHZ][1] = 11; * chan[1] = {WIFI_FREQ_BAND_2_4_GHZ, 11};
* chan[WIFI_FREQ_BAND_5_GHZ][0] = 36; * chan[2] = {WIFI_FREQ_BAND_5_GHZ, 36};
* @endcode * @endcode
* *
* This list specifies the channels to be __considered for scan__. The underlying * This list specifies the channels to be __considered for scan__. The underlying
@ -258,7 +268,7 @@ struct wifi_scan_params {
* not conforming to regulatory restrictions etc. The invoker of the API should * not conforming to regulatory restrictions etc. The invoker of the API should
* ensure that the channels specified follow regulatory rules. * ensure that the channels specified follow regulatory rules.
*/ */
uint8_t chan[WIFI_FREQ_BAND_MAX + 1][WIFI_MGMT_SCAN_CHAN_MAX_MANUAL]; struct wifi_band_channel band_chan[WIFI_MGMT_SCAN_CHAN_MAX_MANUAL];
}; };
/** Wi-Fi scan result, each result is provided to the net_mgmt_event_callback /** Wi-Fi scan result, each result is provided to the net_mgmt_event_callback

View file

@ -95,12 +95,14 @@ int wifi_utils_parse_scan_ssids(char *scan_ssids_str,
* *
* @param scan_chan_str List of channels expressed in the format described above. * @param scan_chan_str List of channels expressed in the format described above.
* @param chan Pointer to an array where the parsed channels are to be stored. * @param chan Pointer to an array where the parsed channels are to be stored.
* @param max_channels Maximum number of channels to store
* *
* @retval 0 on success. * @retval 0 on success.
* @retval -errno value in case of failure. * @retval -errno value in case of failure.
*/ */
int wifi_utils_parse_scan_chan(char *scan_chan_str, int wifi_utils_parse_scan_chan(char *scan_chan_str,
uint8_t chan[][WIFI_CHANNEL_MAX]); struct wifi_band_channel *chan,
uint8_t max_channels);
/** /**
* @} * @}

View file

@ -48,11 +48,11 @@ config WIFI_MGMT_SCAN_SSID_FILT_MAX
This can be set based on the underlying chipsets limitations. This can be set based on the underlying chipsets limitations.
config WIFI_MGMT_SCAN_CHAN_MAX_MANUAL config WIFI_MGMT_SCAN_CHAN_MAX_MANUAL
int "Maximum number of channels that can be manually specified per-band" int "Maximum number of channels that can be manually specified"
range 1 70 range 1 110
default 3 default 3
help help
There are currently 60 channels allocated in the largest band (6GHz). There are approximately 100 channels allocated across the three supported bands.
The default of 3 allows the 3 most common channels (2.4GHz: 1, 6, 11) to be specified. The default of 3 allows the 3 most common channels (2.4GHz: 1, 6, 11) to be specified.
config WIFI_NM config WIFI_NM

View file

@ -774,7 +774,9 @@ static int wifi_scan_args_to_params(const struct shell *sh,
opt_num++; opt_num++;
break; break;
case 'c': case 'c':
if (wifi_utils_parse_scan_chan(optarg, params->chan)) { if (wifi_utils_parse_scan_chan(optarg,
params->band_chan,
ARRAY_SIZE(params->band_chan))) {
shell_fprintf(sh, shell_fprintf(sh,
SHELL_ERROR, SHELL_ERROR,
"Invalid band or channel value(s)\n"); "Invalid band or channel value(s)\n");

View file

@ -105,7 +105,7 @@ static bool wifi_utils_validate_chan(uint8_t band,
static int wifi_utils_get_all_chans_in_range(uint8_t chan_start, static int wifi_utils_get_all_chans_in_range(uint8_t chan_start,
uint8_t chan_end, uint8_t chan_end,
uint8_t chan[][WIFI_CHANNEL_MAX], struct wifi_band_channel *band_chan,
uint8_t band_idx, uint8_t band_idx,
uint8_t *chan_idx) uint8_t *chan_idx)
{ {
@ -136,7 +136,9 @@ static int wifi_utils_get_all_chans_in_range(uint8_t chan_start,
idx = *chan_idx; idx = *chan_idx;
for (i = chan_start; i <= chan_end; i++) { for (i = chan_start; i <= chan_end; i++) {
chan[band_idx][idx++] = i; band_chan[idx].band = band_idx;
band_chan[idx].channel = i;
idx++;
} }
*chan_idx = idx; *chan_idx = idx;
@ -155,7 +157,9 @@ static int wifi_utils_get_all_chans_in_range(uint8_t chan_start,
} }
if (start) { if (start) {
chan[band_idx][idx++] = valid_5g_chans_20mhz[i]; band_chan[idx].band = band_idx;
band_chan[idx].channel = valid_5g_chans_20mhz[i];
idx++;
} }
if (end) { if (end) {
@ -171,7 +175,9 @@ static int wifi_utils_get_all_chans_in_range(uint8_t chan_start,
i = chan_start; i = chan_start;
while (i <= chan_end) { while (i <= chan_end) {
chan[band_idx][idx++] = i; band_chan[idx].band = band_idx;
band_chan[idx].channel = i;
idx++;
if (i == 1) { if (i == 1) {
i++; i++;
@ -310,7 +316,8 @@ int wifi_utils_parse_scan_ssids(char *scan_ssids_str,
int wifi_utils_parse_scan_chan(char *scan_chan_str, int wifi_utils_parse_scan_chan(char *scan_chan_str,
uint8_t chan[][WIFI_CHANNEL_MAX]) struct wifi_band_channel *band_chan,
uint8_t max_channels)
{ {
char band_str[WIFI_UTILS_MAX_BAND_STR_LEN] = {0}; char band_str[WIFI_UTILS_MAX_BAND_STR_LEN] = {0};
char chan_str[WIFI_UTILS_MAX_CHAN_STR_LEN] = {0}; char chan_str[WIFI_UTILS_MAX_CHAN_STR_LEN] = {0};
@ -349,7 +356,6 @@ int wifi_utils_parse_scan_chan(char *scan_chan_str,
} }
i++; i++;
chan_idx = 0;
chan_str_start_idx = i; chan_str_start_idx = i;
valid_band = true; valid_band = true;
@ -383,9 +389,13 @@ int wifi_utils_parse_scan_chan(char *scan_chan_str,
memset(chan_str, 0, sizeof(chan_str)); memset(chan_str, 0, sizeof(chan_str));
if (chan_start) { if (chan_start) {
if ((chan_idx + (chan_val - chan_start)) >= max_channels) {
NET_ERR("Too many channels specified (%d)", max_channels);
return -EINVAL;
}
if (wifi_utils_get_all_chans_in_range(chan_start, if (wifi_utils_get_all_chans_in_range(chan_start,
chan_val, chan_val,
chan, band_chan,
band, band,
&chan_idx)) { &chan_idx)) {
NET_ERR("Channel range invalid"); NET_ERR("Channel range invalid");
@ -399,8 +409,14 @@ int wifi_utils_parse_scan_chan(char *scan_chan_str,
NET_ERR("Invalid channel %d", chan_val); NET_ERR("Invalid channel %d", chan_val);
return -EINVAL; return -EINVAL;
} }
if (chan_idx == max_channels) {
NET_ERR("Too many channels specified (%d)", max_channels);
return -EINVAL;
}
chan[band][chan_idx++] = chan_val; band_chan[chan_idx].band = band;
band_chan[chan_idx].channel = chan_val;
chan_idx++;
} }
valid_chan = true; valid_chan = true;