[PATCH 1/2] wpa_supplicant: Unify hardware feature data

Christian Lamparter chunkeey at googlemail.com
Wed Oct 19 06:54:29 EDT 2011


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 at googlemail.com>
---
 wpa_supplicant/ap.c               |   15 +++----------
 wpa_supplicant/bgscan_learn.c     |   12 +++-------
 wpa_supplicant/mlme.c             |   28 +++++++++-----------------
 wpa_supplicant/p2p_supplicant.c   |   10 ++------
 wpa_supplicant/wpa_supplicant.c   |   39 ++++++++++++++++++++----------------
 wpa_supplicant/wpa_supplicant_i.h |   10 +++++---
 wpa_supplicant/wps_supplicant.c   |    7 ++---
 7 files changed, 52 insertions(+), 69 deletions(-)

diff --git a/wpa_supplicant/ap.c b/wpa_supplicant/ap.c
index 7b0cd21..ae3c940 100644
--- a/wpa_supplicant/ap.c
+++ b/wpa_supplicant/ap.c
@@ -56,10 +56,6 @@ static int wpa_supplicant_conf_ap(struct wpa_supplicant *wpa_s,
 {
 	struct hostapd_bss_config *bss = &conf->bss[0];
 	int pairwise;
-#ifdef CONFIG_IEEE80211N
-	struct hostapd_hw_modes *modes;
-	u16 num_modes, flags;
-#endif /* CONFIG_IEEE80211N */
 
 	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,
 	 * conf->ht_capab, conf->secondary_channel, conf->require_ht
 	 */
-	modes = wpa_drv_get_hw_feature_data(wpa_s, &num_modes, &flags);
-	if (modes) {
+	if (wpa_s->hw.modes) {
 		struct hostapd_hw_modes *mode = NULL;
 		int i;
-		for (i = 0; i < num_modes; i++) {
-			if (modes[i].mode == conf->hw_mode) {
-				mode = &modes[i];
+		for (i = 0; i < wpa_s->hw.num_modes; i++) {
+			if (wpa_s->hw.modes[i].mode == conf->hw_mode) {
+				mode = &wpa_s->hw.modes[i];
 				break;
 			}
 		}
 		if (mode && mode->ht_capab)
 			conf->ieee80211n = 1;
-		ieee80211_sta_free_hw_features(modes, num_modes);
-		modes = NULL;
 	}
 #endif /* CONFIG_IEEE80211N */
 
diff --git a/wpa_supplicant/bgscan_learn.c b/wpa_supplicant/bgscan_learn.c
index ee79511..5385cce 100644
--- a/wpa_supplicant/bgscan_learn.c
+++ b/wpa_supplicant/bgscan_learn.c
@@ -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)
 {
 	struct hostapd_hw_modes *modes;
-	u16 num_modes, flags;
 	int i, j, *freqs = NULL, *n;
 	size_t count = 0;
 
-	modes = wpa_drv_get_hw_feature_data(wpa_s, &num_modes, &flags);
-	if (!modes)
+	modes = wpa_s->hw.modes;
+	if (modes == 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++) {
 			if (modes[i].channels[j].flag & HOSTAPD_CHAN_DISABLED)
 				continue;
 			n = os_realloc(freqs, (count + 2) * sizeof(int));
-			if (!n)
+			if (n == NULL)
 				continue;
 
 			freqs = n;
@@ -376,10 +375,7 @@ static int * bgscan_learn_get_supp_freqs(struct wpa_supplicant *wpa_s)
 			count++;
 			freqs[count] = 0;
 		}
-		os_free(modes[i].channels);
-		os_free(modes[i].rates);
 	}
-	os_free(modes);
 
 	return freqs;
 }
diff --git a/wpa_supplicant/mlme.c b/wpa_supplicant/mlme.c
index 49713f5..73eaeeb 100644
--- a/wpa_supplicant/mlme.c
+++ b/wpa_supplicant/mlme.c
@@ -107,8 +107,8 @@ static int ieee80211_sta_set_channel(struct wpa_supplicant *wpa_s,
 	size_t i;
 	struct hostapd_hw_modes *mode;
 
-	for (i = 0; i < wpa_s->mlme.num_modes; i++) {
-		mode = &wpa_s->mlme.modes[i];
+	for (i = 0; i < wpa_s->hw.num_modes; i++) {
+		mode = &wpa_s->hw.modes[i];
 		if (mode->mode == phymode) {
 			wpa_s->mlme.curr_rates = mode->rates;
 			wpa_s->mlme.num_curr_rates = mode->num_rates;
@@ -2673,8 +2673,8 @@ static int ieee80211_active_scan(struct wpa_supplicant *wpa_s)
 	size_t m;
 	int c;
 
-	for (m = 0; m < wpa_s->mlme.num_modes; m++) {
-		struct hostapd_hw_modes *mode = &wpa_s->mlme.modes[m];
+	for (m = 0; m < wpa_s->hw.num_modes; m++) {
+		struct hostapd_hw_modes *mode = &wpa_s->hw.modes[m];
 		if ((int) mode->mode != (int) wpa_s->mlme.phymode)
 			continue;
 		for (c = 0; c < mode->num_channels; c++) {
@@ -2702,18 +2702,18 @@ static void ieee80211_sta_scan_timer(void *eloop_ctx, void *timeout_ctx)
 	struct wpa_ssid *ssid = wpa_s->current_ssid;
 	int adhoc;
 
-	if (!wpa_s->mlme.sta_scanning || wpa_s->mlme.modes == NULL)
+	if (!wpa_s->mlme.sta_scanning || wpa_s->hw.modes == NULL)
 		return;
 
 	adhoc = ssid && ssid->mode == 1;
 
 	switch (wpa_s->mlme.scan_state) {
 	case SCAN_SET_CHANNEL:
-		mode = &wpa_s->mlme.modes[wpa_s->mlme.scan_hw_mode_idx];
+		mode = &wpa_s->hw.modes[wpa_s->mlme.scan_hw_mode_idx];
 		if (wpa_s->mlme.scan_hw_mode_idx >=
-		    (int) wpa_s->mlme.num_modes ||
+		    (int) wpa_s->hw.num_modes ||
 		    (wpa_s->mlme.scan_hw_mode_idx + 1 ==
-		     (int) wpa_s->mlme.num_modes
+		     (int) wpa_s->hw.num_modes
 		     && wpa_s->mlme.scan_channel_idx >= mode->num_channels)) {
 			if (ieee80211_sta_restore_oper_chan(wpa_s)) {
 				wpa_printf(MSG_DEBUG, "MLME: failed to "
@@ -2773,7 +2773,7 @@ static void ieee80211_sta_scan_timer(void *eloop_ctx, void *timeout_ctx)
 
 		wpa_s->mlme.scan_channel_idx++;
 		if (wpa_s->mlme.scan_channel_idx >=
-		    wpa_s->mlme.modes[wpa_s->mlme.scan_hw_mode_idx].
+		    wpa_s->hw.modes[wpa_s->mlme.scan_hw_mode_idx].
 		    num_channels) {
 			wpa_s->mlme.scan_hw_mode_idx++;
 			wpa_s->mlme.scan_channel_idx = 0;
@@ -3032,18 +3032,12 @@ void ieee80211_sta_rx(struct wpa_supplicant *wpa_s, const u8 *buf, size_t len,
 
 int ieee80211_sta_init(struct wpa_supplicant *wpa_s)
 {
-	u16 num_modes, flags;
-
-	wpa_s->mlme.modes = wpa_drv_get_hw_feature_data(wpa_s, &num_modes,
-							&flags);
-	if (wpa_s->mlme.modes == NULL) {
+	if (wpa_s->hw.modes == NULL) {
 		wpa_printf(MSG_ERROR, "MLME: Failed to read supported "
 			   "channels and rates from the driver");
 		return -1;
 	}
 
-	wpa_s->mlme.num_modes = num_modes;
-
 	wpa_s->mlme.hw_modes = 1 << HOSTAPD_MODE_IEEE80211A;
 	wpa_s->mlme.hw_modes |= 1 << HOSTAPD_MODE_IEEE80211B;
 	wpa_s->mlme.hw_modes |= 1 << HOSTAPD_MODE_IEEE80211G;
@@ -3067,8 +3061,6 @@ void ieee80211_sta_deinit(struct wpa_supplicant *wpa_s)
 	os_free(wpa_s->mlme.assocresp_ies);
 	wpa_s->mlme.assocresp_ies = NULL;
 	ieee80211_bss_list_deinit(wpa_s);
-	ieee80211_sta_free_hw_features(wpa_s->mlme.modes,
-				       wpa_s->mlme.num_modes);
 #ifdef CONFIG_IEEE80211R
 	os_free(wpa_s->mlme.ft_ies);
 	wpa_s->mlme.ft_ies = NULL;
diff --git a/wpa_supplicant/p2p_supplicant.c b/wpa_supplicant/p2p_supplicant.c
index 9af1839..8d24ff3 100644
--- a/wpa_supplicant/p2p_supplicant.c
+++ b/wpa_supplicant/p2p_supplicant.c
@@ -2055,8 +2055,7 @@ struct p2p_oper_class_map {
 static int wpas_p2p_setup_channels(struct wpa_supplicant *wpa_s,
 				   struct p2p_channels *chan)
 {
-	struct hostapd_hw_modes *modes, *mode;
-	u16 num_modes, flags;
+	struct hostapd_hw_modes *mode;
 	int cla, op;
 	struct p2p_oper_class_map op_class[] = {
 		{ HOSTAPD_MODE_IEEE80211G, 81, 1, 13, 1, BW20 },
@@ -2074,8 +2073,7 @@ static int wpas_p2p_setup_channels(struct wpa_supplicant *wpa_s,
 		{ -1, 0, 0, 0, 0, BW20 }
 	};
 
-	modes = wpa_drv_get_hw_feature_data(wpa_s, &num_modes, &flags);
-	if (modes == NULL) {
+	if (wpa_s->hw.modes == NULL) {
 		wpa_printf(MSG_DEBUG, "P2P: Driver did not support fetching "
 			   "of all supported channels; assume dualband "
 			   "support");
@@ -2089,7 +2087,7 @@ static int wpas_p2p_setup_channels(struct wpa_supplicant *wpa_s,
 		u8 ch;
 		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)
 			continue;
 		for (ch = o->min_chan; ch <= o->max_chan; ch += o->inc) {
@@ -2122,8 +2120,6 @@ static int wpas_p2p_setup_channels(struct wpa_supplicant *wpa_s,
 
 	chan->reg_classes = cla;
 
-	ieee80211_sta_free_hw_features(modes, num_modes);
-
 	return 0;
 }
 
diff --git a/wpa_supplicant/wpa_supplicant.c b/wpa_supplicant/wpa_supplicant.c
index a778f3a..401a25f 100644
--- a/wpa_supplicant/wpa_supplicant.c
+++ b/wpa_supplicant/wpa_supplicant.c
@@ -371,6 +371,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)
 {
 	bgscan_deinit(wpa_s);
@@ -453,6 +469,8 @@ static void wpa_supplicant_cleanup(struct wpa_supplicant *wpa_s)
 
 	gas_query_deinit(wpa_s->gas);
 	wpa_s->gas = NULL;
+
+	free_hw_features(wpa_s);
 }
 
 
@@ -2294,6 +2312,10 @@ next_driver:
 		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) {
 		wpa_s->drv_flags = capa.flags;
 		if (capa.flags & WPA_DRIVER_FLAGS_USER_SPACE_MLME) {
@@ -2773,23 +2795,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)
 {
 	int i;
diff --git a/wpa_supplicant/wpa_supplicant_i.h b/wpa_supplicant/wpa_supplicant_i.h
index b327f4c..031ff7a 100644
--- a/wpa_supplicant/wpa_supplicant_i.h
+++ b/wpa_supplicant/wpa_supplicant_i.h
@@ -298,8 +298,6 @@ struct wpa_client_mlme {
 	int cts_protect_erp_frames;
 
 	enum hostapd_hw_mode phymode; /* current mode */
-	struct hostapd_hw_modes *modes;
-	size_t num_modes;
 	unsigned int hw_modes; /* bitfield of allowed hardware modes;
 				* (1 << HOSTAPD_MODE_*) */
 	int num_curr_rates;
@@ -595,6 +593,12 @@ struct wpa_supplicant {
 	int network_select:1;
 	int auto_select:1;
 #endif /* CONFIG_INTERWORKING */
+
+	struct {
+		struct hostapd_hw_modes *modes;
+		u16 num_modes;
+		u16 flags;
+	} hw;
 };
 
 
@@ -664,8 +668,6 @@ enum wpa_key_mgmt key_mgmt2driver(int key_mgmt);
 enum wpa_cipher cipher_suite2driver(int cipher);
 void wpa_supplicant_update_config(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);
 int wpas_driver_bss_selection(struct wpa_supplicant *wpa_s);
 
diff --git a/wpa_supplicant/wps_supplicant.c b/wpa_supplicant/wps_supplicant.c
index 3400365..8a6c247 100644
--- a/wpa_supplicant/wps_supplicant.c
+++ b/wpa_supplicant/wps_supplicant.c
@@ -1117,7 +1117,7 @@ int wpas_wps_init(struct wpa_supplicant *wpa_s)
 	struct wps_context *wps;
 	struct wps_registrar_config rcfg;
 	struct hostapd_hw_modes *modes;
-	u16 num_modes, flags, m;
+	u16 m;
 
 	wps = os_zalloc(sizeof(*wps));
 	if (wps == NULL)
@@ -1151,16 +1151,15 @@ int wpas_wps_init(struct wpa_supplicant *wpa_s)
 		  WPS_DEV_TYPE_LEN * wps->dev.num_sec_dev_types);
 
 	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) {
-		for (m = 0; m < num_modes; m++) {
+		for (m = 0; m < wpa_s->hw.num_modes; m++) {
 			if (modes[m].mode == HOSTAPD_MODE_IEEE80211B ||
 			    modes[m].mode == HOSTAPD_MODE_IEEE80211G)
 				wps->dev.rf_bands |= WPS_RF_24GHZ;
 			else if (modes[m].mode == HOSTAPD_MODE_IEEE80211A)
 				wps->dev.rf_bands |= WPS_RF_50GHZ;
 		}
-		ieee80211_sta_free_hw_features(modes, num_modes);
 	}
 	if (wps->dev.rf_bands == 0) {
 		/*
-- 
1.7.7



More information about the HostAP mailing list