Parcourir la source

IBSS: Add WPA_DRIVER_FLAGS_HT_IBSS

Add WPA_DRIVER_FLAGS_HT_IBSS driver feature flag. Some drivers could not
set this feature and next could fail when we will enable HT support for
IBSS with error message: nl80211: Join IBSS failed: ret=-22 (Invalid
argument).

Signed-off-by: Janusz Dziedzic <janusz.dziedzic@tieto.com>
Janusz Dziedzic il y a 10 ans
Parent
commit
1830817ece
3 fichiers modifiés avec 38 ajouts et 17 suppressions
  1. 2 0
      src/drivers/driver.h
  2. 3 0
      src/drivers/driver_nl80211_capa.c
  3. 33 17
      wpa_supplicant/wpa_supplicant.c

+ 2 - 0
src/drivers/driver.h

@@ -1182,6 +1182,8 @@ struct wpa_driver_capa {
 #define WPA_DRIVER_FLAGS_KEY_MGMT_OFFLOAD	0x0000000400000000ULL
 /** Driver supports TDLS channel switching */
 #define WPA_DRIVER_FLAGS_TDLS_CHANNEL_SWITCH	0x0000000800000000ULL
+/** Driver supports IBSS with HT datarates */
+#define WPA_DRIVER_FLAGS_HT_IBSS		0x0000001000000000ULL
 	u64 flags;
 
 #define WPA_DRIVER_SMPS_MODE_STATIC			0x00000001

+ 3 - 0
src/drivers/driver_nl80211_capa.c

@@ -394,6 +394,9 @@ static void wiphy_info_feature_flags(struct wiphy_info_data *info,
 
 	if (flags & NL80211_FEATURE_TX_POWER_INSERTION)
 		capa->rrm_flags |= WPA_DRIVER_FLAGS_TX_POWER_INSERTION;
+
+	if (flags & NL80211_FEATURE_HT_IBSS)
+		capa->flags |= WPA_DRIVER_FLAGS_HT_IBSS;
 }
 
 

+ 33 - 17
wpa_supplicant/wpa_supplicant.c

@@ -1649,6 +1649,37 @@ void wpa_supplicant_associate(struct wpa_supplicant *wpa_s,
 }
 
 
+static void ibss_mesh_setup_freq(struct wpa_supplicant *wpa_s,
+				 const struct wpa_ssid *ssid,
+				 struct hostapd_freq_params *freq)
+{
+	enum hostapd_hw_mode hw_mode;
+	struct hostapd_hw_modes *mode = NULL;
+	u8 channel;
+	int i;
+
+	freq->freq = ssid->frequency;
+
+	/* For IBSS check HT_IBSS flag */
+	if (ssid->mode == WPAS_MODE_IBSS &&
+	    !(wpa_s->drv_flags & WPA_DRIVER_FLAGS_HT_IBSS))
+		return;
+
+	hw_mode = ieee80211_freq_to_chan(ssid->frequency, &channel);
+	for (i = 0; wpa_s->hw.modes && i < wpa_s->hw.num_modes; i++) {
+		if (wpa_s->hw.modes[i].mode == hw_mode) {
+			mode = &wpa_s->hw.modes[i];
+			break;
+		}
+	}
+
+	if (!mode)
+		return;
+
+	freq->ht_enabled = ht_supported(mode);
+}
+
+
 static void wpas_start_assoc_cb(struct wpa_radio_work *work, int deinit)
 {
 	struct wpa_connect_work *cwork = work->ctx;
@@ -1962,23 +1993,8 @@ static void wpas_start_assoc_cb(struct wpa_radio_work *work, int deinit)
 
 	/* Initial frequency for IBSS/mesh */
 	if ((ssid->mode == WPAS_MODE_IBSS || ssid->mode == WPAS_MODE_MESH) &&
-	    ssid->frequency > 0 && params.freq.freq == 0) {
-		enum hostapd_hw_mode hw_mode;
-		u8 channel;
-
-		params.freq.freq = ssid->frequency;
-
-		hw_mode = ieee80211_freq_to_chan(ssid->frequency, &channel);
-		for (i = 0; wpa_s->hw.modes && i < wpa_s->hw.num_modes; i++) {
-			if (wpa_s->hw.modes[i].mode == hw_mode) {
-				struct hostapd_hw_modes *mode;
-
-				mode = &wpa_s->hw.modes[i];
-				params.freq.ht_enabled = ht_supported(mode);
-				break;
-			}
-		}
-	}
+	    ssid->frequency > 0 && params.freq.freq == 0)
+		ibss_mesh_setup_freq(wpa_s, ssid, &params.freq);
 
 	if (ssid->mode == WPAS_MODE_IBSS) {
 		if (ssid->beacon_int)