wpa_supplicant: Unify hardware feature data
The hardware feature data is required in several different places throughout the code. Previously, the data was acquired and freed on demand, but with this patch wpa_supplicant will keep a single copy around at runtime for everyone to use. Signed-off-by: Christian Lamparter <chunkeey@googlemail.com>
This commit is contained in:
parent
e3b473eb4e
commit
6bf731e8ce
6 changed files with 42 additions and 49 deletions
|
@ -56,10 +56,6 @@ static int wpa_supplicant_conf_ap(struct wpa_supplicant *wpa_s,
|
||||||
{
|
{
|
||||||
struct hostapd_bss_config *bss = &conf->bss[0];
|
struct hostapd_bss_config *bss = &conf->bss[0];
|
||||||
int pairwise;
|
int pairwise;
|
||||||
#ifdef CONFIG_IEEE80211N
|
|
||||||
struct hostapd_hw_modes *modes;
|
|
||||||
u16 num_modes, flags;
|
|
||||||
#endif /* CONFIG_IEEE80211N */
|
|
||||||
|
|
||||||
conf->driver = wpa_s->driver;
|
conf->driver = wpa_s->driver;
|
||||||
|
|
||||||
|
@ -91,20 +87,17 @@ static int wpa_supplicant_conf_ap(struct wpa_supplicant *wpa_s,
|
||||||
* Using default config settings for: conf->ht_op_mode_fixed,
|
* Using default config settings for: conf->ht_op_mode_fixed,
|
||||||
* conf->ht_capab, conf->secondary_channel, conf->require_ht
|
* conf->ht_capab, conf->secondary_channel, conf->require_ht
|
||||||
*/
|
*/
|
||||||
modes = wpa_drv_get_hw_feature_data(wpa_s, &num_modes, &flags);
|
if (wpa_s->hw.modes) {
|
||||||
if (modes) {
|
|
||||||
struct hostapd_hw_modes *mode = NULL;
|
struct hostapd_hw_modes *mode = NULL;
|
||||||
int i;
|
int i;
|
||||||
for (i = 0; i < num_modes; i++) {
|
for (i = 0; i < wpa_s->hw.num_modes; i++) {
|
||||||
if (modes[i].mode == conf->hw_mode) {
|
if (wpa_s->hw.modes[i].mode == conf->hw_mode) {
|
||||||
mode = &modes[i];
|
mode = &wpa_s->hw.modes[i];
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (mode && mode->ht_capab)
|
if (mode && mode->ht_capab)
|
||||||
conf->ieee80211n = 1;
|
conf->ieee80211n = 1;
|
||||||
ieee80211_sta_free_hw_features(modes, num_modes);
|
|
||||||
modes = NULL;
|
|
||||||
}
|
}
|
||||||
#endif /* CONFIG_IEEE80211N */
|
#endif /* CONFIG_IEEE80211N */
|
||||||
|
|
||||||
|
|
|
@ -355,20 +355,19 @@ static int bgscan_learn_get_params(struct bgscan_learn_data *data,
|
||||||
static int * bgscan_learn_get_supp_freqs(struct wpa_supplicant *wpa_s)
|
static int * bgscan_learn_get_supp_freqs(struct wpa_supplicant *wpa_s)
|
||||||
{
|
{
|
||||||
struct hostapd_hw_modes *modes;
|
struct hostapd_hw_modes *modes;
|
||||||
u16 num_modes, flags;
|
|
||||||
int i, j, *freqs = NULL, *n;
|
int i, j, *freqs = NULL, *n;
|
||||||
size_t count = 0;
|
size_t count = 0;
|
||||||
|
|
||||||
modes = wpa_drv_get_hw_feature_data(wpa_s, &num_modes, &flags);
|
modes = wpa_s->hw.modes;
|
||||||
if (!modes)
|
if (modes == NULL)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
for (i = 0; i < num_modes; i++) {
|
for (i = 0; i < wpa_s->hw.num_modes; i++) {
|
||||||
for (j = 0; j < modes[i].num_channels; j++) {
|
for (j = 0; j < modes[i].num_channels; j++) {
|
||||||
if (modes[i].channels[j].flag & HOSTAPD_CHAN_DISABLED)
|
if (modes[i].channels[j].flag & HOSTAPD_CHAN_DISABLED)
|
||||||
continue;
|
continue;
|
||||||
n = os_realloc(freqs, (count + 2) * sizeof(int));
|
n = os_realloc(freqs, (count + 2) * sizeof(int));
|
||||||
if (!n)
|
if (n == NULL)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
freqs = n;
|
freqs = n;
|
||||||
|
@ -376,10 +375,7 @@ static int * bgscan_learn_get_supp_freqs(struct wpa_supplicant *wpa_s)
|
||||||
count++;
|
count++;
|
||||||
freqs[count] = 0;
|
freqs[count] = 0;
|
||||||
}
|
}
|
||||||
os_free(modes[i].channels);
|
|
||||||
os_free(modes[i].rates);
|
|
||||||
}
|
}
|
||||||
os_free(modes);
|
|
||||||
|
|
||||||
return freqs;
|
return freqs;
|
||||||
}
|
}
|
||||||
|
|
|
@ -2030,8 +2030,7 @@ struct p2p_oper_class_map {
|
||||||
static int wpas_p2p_setup_channels(struct wpa_supplicant *wpa_s,
|
static int wpas_p2p_setup_channels(struct wpa_supplicant *wpa_s,
|
||||||
struct p2p_channels *chan)
|
struct p2p_channels *chan)
|
||||||
{
|
{
|
||||||
struct hostapd_hw_modes *modes, *mode;
|
struct hostapd_hw_modes *mode;
|
||||||
u16 num_modes, flags;
|
|
||||||
int cla, op;
|
int cla, op;
|
||||||
struct p2p_oper_class_map op_class[] = {
|
struct p2p_oper_class_map op_class[] = {
|
||||||
{ HOSTAPD_MODE_IEEE80211G, 81, 1, 13, 1, BW20 },
|
{ HOSTAPD_MODE_IEEE80211G, 81, 1, 13, 1, BW20 },
|
||||||
|
@ -2049,8 +2048,7 @@ static int wpas_p2p_setup_channels(struct wpa_supplicant *wpa_s,
|
||||||
{ -1, 0, 0, 0, 0, BW20 }
|
{ -1, 0, 0, 0, 0, BW20 }
|
||||||
};
|
};
|
||||||
|
|
||||||
modes = wpa_drv_get_hw_feature_data(wpa_s, &num_modes, &flags);
|
if (wpa_s->hw.modes == NULL) {
|
||||||
if (modes == NULL) {
|
|
||||||
wpa_printf(MSG_DEBUG, "P2P: Driver did not support fetching "
|
wpa_printf(MSG_DEBUG, "P2P: Driver did not support fetching "
|
||||||
"of all supported channels; assume dualband "
|
"of all supported channels; assume dualband "
|
||||||
"support");
|
"support");
|
||||||
|
@ -2064,7 +2062,7 @@ static int wpas_p2p_setup_channels(struct wpa_supplicant *wpa_s,
|
||||||
u8 ch;
|
u8 ch;
|
||||||
struct p2p_reg_class *reg = NULL;
|
struct p2p_reg_class *reg = NULL;
|
||||||
|
|
||||||
mode = get_mode(modes, num_modes, o->mode);
|
mode = get_mode(wpa_s->hw.modes, wpa_s->hw.num_modes, o->mode);
|
||||||
if (mode == NULL)
|
if (mode == NULL)
|
||||||
continue;
|
continue;
|
||||||
for (ch = o->min_chan; ch <= o->max_chan; ch += o->inc) {
|
for (ch = o->min_chan; ch <= o->max_chan; ch += o->inc) {
|
||||||
|
@ -2097,8 +2095,6 @@ static int wpas_p2p_setup_channels(struct wpa_supplicant *wpa_s,
|
||||||
|
|
||||||
chan->reg_classes = cla;
|
chan->reg_classes = cla;
|
||||||
|
|
||||||
ieee80211_sta_free_hw_features(modes, num_modes);
|
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -370,6 +370,22 @@ void wpa_supplicant_set_non_wpa_policy(struct wpa_supplicant *wpa_s,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static void free_hw_features(struct wpa_supplicant *wpa_s)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
if (wpa_s->hw.modes == NULL)
|
||||||
|
return;
|
||||||
|
|
||||||
|
for (i = 0; i < wpa_s->hw.num_modes; i++) {
|
||||||
|
os_free(wpa_s->hw.modes[i].channels);
|
||||||
|
os_free(wpa_s->hw.modes[i].rates);
|
||||||
|
}
|
||||||
|
|
||||||
|
os_free(wpa_s->hw.modes);
|
||||||
|
wpa_s->hw.modes = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
static void wpa_supplicant_cleanup(struct wpa_supplicant *wpa_s)
|
static void wpa_supplicant_cleanup(struct wpa_supplicant *wpa_s)
|
||||||
{
|
{
|
||||||
bgscan_deinit(wpa_s);
|
bgscan_deinit(wpa_s);
|
||||||
|
@ -450,6 +466,8 @@ static void wpa_supplicant_cleanup(struct wpa_supplicant *wpa_s)
|
||||||
|
|
||||||
gas_query_deinit(wpa_s->gas);
|
gas_query_deinit(wpa_s->gas);
|
||||||
wpa_s->gas = NULL;
|
wpa_s->gas = NULL;
|
||||||
|
|
||||||
|
free_hw_features(wpa_s);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -2295,6 +2313,10 @@ next_driver:
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
wpa_s->hw.modes = wpa_drv_get_hw_feature_data(wpa_s,
|
||||||
|
&wpa_s->hw.num_modes,
|
||||||
|
&wpa_s->hw.flags);
|
||||||
|
|
||||||
if (wpa_drv_get_capa(wpa_s, &capa) == 0) {
|
if (wpa_drv_get_capa(wpa_s, &capa) == 0) {
|
||||||
wpa_s->drv_flags = capa.flags;
|
wpa_s->drv_flags = capa.flags;
|
||||||
wpa_s->max_scan_ssids = capa.max_scan_ssids;
|
wpa_s->max_scan_ssids = capa.max_scan_ssids;
|
||||||
|
@ -2759,23 +2781,6 @@ void wpa_supplicant_update_config(struct wpa_supplicant *wpa_s)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void ieee80211_sta_free_hw_features(struct hostapd_hw_modes *hw_features,
|
|
||||||
size_t num_hw_features)
|
|
||||||
{
|
|
||||||
size_t i;
|
|
||||||
|
|
||||||
if (hw_features == NULL)
|
|
||||||
return;
|
|
||||||
|
|
||||||
for (i = 0; i < num_hw_features; i++) {
|
|
||||||
os_free(hw_features[i].channels);
|
|
||||||
os_free(hw_features[i].rates);
|
|
||||||
}
|
|
||||||
|
|
||||||
os_free(hw_features);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
static void add_freq(int *freqs, int *num_freqs, int freq)
|
static void add_freq(int *freqs, int *num_freqs, int freq)
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
|
|
|
@ -500,6 +500,12 @@ struct wpa_supplicant {
|
||||||
unsigned int network_select:1;
|
unsigned int network_select:1;
|
||||||
unsigned int auto_select:1;
|
unsigned int auto_select:1;
|
||||||
#endif /* CONFIG_INTERWORKING */
|
#endif /* CONFIG_INTERWORKING */
|
||||||
|
|
||||||
|
struct {
|
||||||
|
struct hostapd_hw_modes *modes;
|
||||||
|
u16 num_modes;
|
||||||
|
u16 flags;
|
||||||
|
} hw;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
@ -569,8 +575,6 @@ enum wpa_key_mgmt key_mgmt2driver(int key_mgmt);
|
||||||
enum wpa_cipher cipher_suite2driver(int cipher);
|
enum wpa_cipher cipher_suite2driver(int cipher);
|
||||||
void wpa_supplicant_update_config(struct wpa_supplicant *wpa_s);
|
void wpa_supplicant_update_config(struct wpa_supplicant *wpa_s);
|
||||||
void wpa_supplicant_clear_status(struct wpa_supplicant *wpa_s);
|
void wpa_supplicant_clear_status(struct wpa_supplicant *wpa_s);
|
||||||
void ieee80211_sta_free_hw_features(struct hostapd_hw_modes *hw_features,
|
|
||||||
size_t num_hw_features);
|
|
||||||
void wpas_connection_failed(struct wpa_supplicant *wpa_s, const u8 *bssid);
|
void wpas_connection_failed(struct wpa_supplicant *wpa_s, const u8 *bssid);
|
||||||
int wpas_driver_bss_selection(struct wpa_supplicant *wpa_s);
|
int wpas_driver_bss_selection(struct wpa_supplicant *wpa_s);
|
||||||
|
|
||||||
|
|
|
@ -1121,7 +1121,7 @@ int wpas_wps_init(struct wpa_supplicant *wpa_s)
|
||||||
struct wps_context *wps;
|
struct wps_context *wps;
|
||||||
struct wps_registrar_config rcfg;
|
struct wps_registrar_config rcfg;
|
||||||
struct hostapd_hw_modes *modes;
|
struct hostapd_hw_modes *modes;
|
||||||
u16 num_modes, flags, m;
|
u16 m;
|
||||||
|
|
||||||
wps = os_zalloc(sizeof(*wps));
|
wps = os_zalloc(sizeof(*wps));
|
||||||
if (wps == NULL)
|
if (wps == NULL)
|
||||||
|
@ -1155,16 +1155,15 @@ int wpas_wps_init(struct wpa_supplicant *wpa_s)
|
||||||
WPS_DEV_TYPE_LEN * wps->dev.num_sec_dev_types);
|
WPS_DEV_TYPE_LEN * wps->dev.num_sec_dev_types);
|
||||||
|
|
||||||
wps->dev.os_version = WPA_GET_BE32(wpa_s->conf->os_version);
|
wps->dev.os_version = WPA_GET_BE32(wpa_s->conf->os_version);
|
||||||
modes = wpa_drv_get_hw_feature_data(wpa_s, &num_modes, &flags);
|
modes = wpa_s->hw.modes;
|
||||||
if (modes) {
|
if (modes) {
|
||||||
for (m = 0; m < num_modes; m++) {
|
for (m = 0; m < wpa_s->hw.num_modes; m++) {
|
||||||
if (modes[m].mode == HOSTAPD_MODE_IEEE80211B ||
|
if (modes[m].mode == HOSTAPD_MODE_IEEE80211B ||
|
||||||
modes[m].mode == HOSTAPD_MODE_IEEE80211G)
|
modes[m].mode == HOSTAPD_MODE_IEEE80211G)
|
||||||
wps->dev.rf_bands |= WPS_RF_24GHZ;
|
wps->dev.rf_bands |= WPS_RF_24GHZ;
|
||||||
else if (modes[m].mode == HOSTAPD_MODE_IEEE80211A)
|
else if (modes[m].mode == HOSTAPD_MODE_IEEE80211A)
|
||||||
wps->dev.rf_bands |= WPS_RF_50GHZ;
|
wps->dev.rf_bands |= WPS_RF_50GHZ;
|
||||||
}
|
}
|
||||||
ieee80211_sta_free_hw_features(modes, num_modes);
|
|
||||||
}
|
}
|
||||||
if (wps->dev.rf_bands == 0) {
|
if (wps->dev.rf_bands == 0) {
|
||||||
/*
|
/*
|
||||||
|
|
Loading…
Reference in a new issue