Browse Source

HT: Let the driver advertise its supported SMPS modes for AP mode

Add smps_modes field, and let the driver fill it with its supported SMPS
modes (static/dynamic). This will let us start an AP with specific SMPS
mode (e.g., dynamic) that will allow it to reduce its power usage.

Signed-off-by: Eliad Peller <eliad@wizery.com>
Eliad Peller 10 years ago
parent
commit
04ee647d58

+ 1 - 0
hostapd/main.c

@@ -213,6 +213,7 @@ static int hostapd_driver_init(struct hostapd_iface *iface)
 	if (hapd->driver->get_capa &&
 	    hapd->driver->get_capa(hapd->drv_priv, &capa) == 0) {
 		iface->drv_flags = capa.flags;
+		iface->smps_modes = capa.smps_modes;
 		iface->probe_resp_offloads = capa.probe_resp_offloads;
 		iface->extended_capa = capa.extended_capa;
 		iface->extended_capa_mask = capa.extended_capa_mask;

+ 3 - 0
src/ap/hostapd.h

@@ -296,6 +296,9 @@ struct hostapd_iface {
 
 	unsigned int drv_flags;
 
+	/* SMPS modes supported by the driver (WPA_DRIVER_SMPS_MODE_*) */
+	unsigned int smps_modes;
+
 	/*
 	 * A bitmap of supported protocols for probe response offload. See
 	 * struct wpa_driver_capa in driver.h

+ 18 - 5
src/ap/hw_features.c

@@ -746,11 +746,24 @@ static int ieee80211n_supported_ht_capab(struct hostapd_iface *iface)
 		return 0;
 	}
 
-	if ((conf & HT_CAP_INFO_SMPS_MASK) != (hw & HT_CAP_INFO_SMPS_MASK) &&
-	    (conf & HT_CAP_INFO_SMPS_MASK) != HT_CAP_INFO_SMPS_DISABLED) {
-		wpa_printf(MSG_ERROR, "Driver does not support configured "
-			   "HT capability [SMPS-*]");
-		return 0;
+	switch (conf & HT_CAP_INFO_SMPS_MASK) {
+	case HT_CAP_INFO_SMPS_STATIC:
+		if (!(iface->smps_modes & WPA_DRIVER_SMPS_MODE_STATIC)) {
+			wpa_printf(MSG_ERROR,
+				   "Driver does not support configured HT capability [SMPS-STATIC]");
+			return 0;
+		}
+		break;
+	case HT_CAP_INFO_SMPS_DYNAMIC:
+		if (!(iface->smps_modes & WPA_DRIVER_SMPS_MODE_DYNAMIC)) {
+			wpa_printf(MSG_ERROR,
+				   "Driver does not support configured HT capability [SMPS-DYNAMIC]");
+			return 0;
+		}
+		break;
+	case HT_CAP_INFO_SMPS_DISABLED:
+	default:
+		break;
 	}
 
 	if ((conf & HT_CAP_INFO_GREEN_FIELD) &&

+ 4 - 0
src/drivers/driver.h

@@ -1056,6 +1056,10 @@ struct wpa_driver_capa {
 #define WPA_DRIVER_FLAGS_MESH			0x0000000100000000ULL
 	u64 flags;
 
+#define WPA_DRIVER_SMPS_MODE_STATIC			0x00000001
+#define WPA_DRIVER_SMPS_MODE_DYNAMIC			0x00000002
+	unsigned int smps_modes;
+
 	int max_scan_ssids;
 	int max_sched_scan_ssids;
 	int sched_scan_supported;

+ 1 - 0
wpa_supplicant/ap.c

@@ -555,6 +555,7 @@ int wpa_supplicant_create_ap(struct wpa_supplicant *wpa_s,
 		return -1;
 	hapd_iface->owner = wpa_s;
 	hapd_iface->drv_flags = wpa_s->drv_flags;
+	hapd_iface->smps_modes = wpa_s->drv_smps_modes;
 	hapd_iface->probe_resp_offloads = wpa_s->probe_resp_offloads;
 	hapd_iface->extended_capa = wpa_s->extended_capa;
 	hapd_iface->extended_capa_mask = wpa_s->extended_capa_mask;

+ 1 - 0
wpa_supplicant/wpa_supplicant.c

@@ -3804,6 +3804,7 @@ static int wpa_supplicant_init_iface(struct wpa_supplicant *wpa_s,
 		wpa_s->drv_capa_known = 1;
 		wpa_s->drv_flags = capa.flags;
 		wpa_s->drv_enc = capa.enc;
+		wpa_s->drv_smps_modes = capa.smps_modes;
 		wpa_s->probe_resp_offloads = capa.probe_resp_offloads;
 		wpa_s->max_scan_ssids = capa.max_scan_ssids;
 		wpa_s->max_sched_scan_ssids = capa.max_sched_scan_ssids;

+ 1 - 0
wpa_supplicant/wpa_supplicant_i.h

@@ -574,6 +574,7 @@ struct wpa_supplicant {
 
 	u64 drv_flags;
 	unsigned int drv_enc;
+	unsigned int drv_smps_modes;
 
 	/*
 	 * A bitmap of supported protocols for probe response offload. See