about summary refs log tree commit diff
path: root/src/wifi/wifi-utils-nl80211.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/wifi/wifi-utils-nl80211.c')
-rw-r--r--src/wifi/wifi-utils-nl80211.c42
1 files changed, 37 insertions, 5 deletions
diff --git a/src/wifi/wifi-utils-nl80211.c b/src/wifi/wifi-utils-nl80211.c
index 4a4e661e..663cbc26 100644
--- a/src/wifi/wifi-utils-nl80211.c
+++ b/src/wifi/wifi-utils-nl80211.c
@@ -535,7 +535,9 @@ struct nl80211_device_info {
 	guint32 *freqs;
 	int num_freqs;
 	guint32 caps;
-	gboolean can_scan, can_scan_ssid;
+	gboolean can_scan;
+	gboolean can_scan_ssid;
+	gboolean supported;
 	gboolean success;
 };
 
@@ -579,11 +581,24 @@ static int nl80211_wiphy_info_handler (struct nl_msg *msg, void *arg)
 		struct nlattr *nl_cmd;
 		int i;
 
-		nla_for_each_nested (nl_cmd,
-				     tb[NL80211_ATTR_SUPPORTED_COMMANDS], i) {
-			guint32 cmd = nla_get_u32 (nl_cmd);
-			if (cmd == NL80211_CMD_TRIGGER_SCAN)
+		nla_for_each_nested (nl_cmd, tb[NL80211_ATTR_SUPPORTED_COMMANDS], i) {
+			switch (nla_get_u32 (nl_cmd)) {
+			case NL80211_CMD_TRIGGER_SCAN:
 				info->can_scan = TRUE;
+				break;
+			case NL80211_CMD_CONNECT:
+			case NL80211_CMD_AUTHENTICATE:
+				/* Only devices that support CONNECT or AUTH actually support
+				 * 802.11, unlike say ipw2x00 (up to at least kernel 3.4) which
+				 * has minimal info support, but no actual command support.
+				 * This check mirrors what wpa_supplicant does to determine
+				 * whether or not to use the nl80211 driver.
+				 */
+				info->supported = TRUE;
+				break;
+			default:
+				break;
+			}
 		}
 	}
 
@@ -650,6 +665,9 @@ static int nl80211_wiphy_info_handler (struct nl_msg *msg, void *arg)
 				info->caps |= NM_WIFI_DEVICE_CAP_CIPHER_CCMP |
 					      NM_WIFI_DEVICE_CAP_RSN;
 				break;
+			default:
+				nm_log_err (LOGD_HW | LOGD_WIFI, "Don't know the meaning of NL80211_ATTR_CIPHER_SUITES %#8.8x.", ciphers[i]);
+				break;
 			}
 		}
 	}
@@ -721,6 +739,13 @@ wifi_nl80211_init (const char *iface, int ifindex)
 		goto error;
 	}
 
+	if (!device_info.supported) {
+		nm_log_dbg (LOGD_HW | LOGD_WIFI,
+				    "(%s): driver does not fully support nl80211, falling back to WEXT",
+				    nl80211->parent.iface);
+		goto error;
+	}
+
 	if (!device_info.can_scan_ssid) {
 		nm_log_err (LOGD_HW | LOGD_WIFI,
 		            "(%s): driver does not support SSID scans",
@@ -735,6 +760,13 @@ wifi_nl80211_init (const char *iface, int ifindex)
 		goto error;
 	}
 
+	if (device_info.caps == 0) {
+		nm_log_err (LOGD_HW | LOGD_WIFI,
+		            "(%s): driver doesn't report support of any encryption",
+		            nl80211->parent.iface);
+		goto error;
+	}
+
 	nl80211->freqs = device_info.freqs;
 	nl80211->num_freqs = device_info.num_freqs;
 	nl80211->parent.can_scan_ssid = device_info.can_scan_ssid;