diff --git a/src/drivers/driver.h b/src/drivers/driver.h index d93689586..eaaef00a3 100644 --- a/src/drivers/driver.h +++ b/src/drivers/driver.h @@ -553,6 +553,12 @@ struct wpa_driver_capa { * P2P group operations. */ #define WPA_DRIVER_FLAGS_P2P_MGMT_AND_NON_P2P 0x00002000 +/* + * Driver is known to use sane error codes, i.e., when it indicates that + * something (e.g., association) fails, there was indeed a failure and the + * operation does not end up getting completed successfully later. + */ +#define WPA_DRIVER_FLAGS_SANE_ERROR_CODES 0x00004000 unsigned int flags; int max_scan_ssids; diff --git a/src/drivers/driver_nl80211.c b/src/drivers/driver_nl80211.c index 71640fc88..f69cc712d 100644 --- a/src/drivers/driver_nl80211.c +++ b/src/drivers/driver_nl80211.c @@ -1489,6 +1489,7 @@ static int wpa_driver_nl80211_capa(struct wpa_driver_nl80211_data *drv) return -1; } + drv->capa.flags |= WPA_DRIVER_FLAGS_SANE_ERROR_CODES; drv->capa.flags |= WPA_DRIVER_FLAGS_SET_KEYS_AFTER_ASSOC_DONE; drv->capa.flags |= WPA_DRIVER_FLAGS_P2P_CAPABLE; drv->capa.max_remain_on_chan = 5000; diff --git a/wpa_supplicant/wpa_supplicant.c b/wpa_supplicant/wpa_supplicant.c index 350ad9a71..68d171fbf 100644 --- a/wpa_supplicant/wpa_supplicant.c +++ b/wpa_supplicant/wpa_supplicant.c @@ -1304,6 +1304,16 @@ void wpa_supplicant_associate(struct wpa_supplicant *wpa_s, if (ret < 0) { wpa_msg(wpa_s, MSG_INFO, "Association request to the driver " "failed"); + if (wpa_s->drv_flags & WPA_DRIVER_FLAGS_SANE_ERROR_CODES) { + /* + * The driver is known to mean what is saying, so we + * can stop right here; the association will not + * succeed. + */ + wpas_connection_failed(wpa_s, wpa_s->pending_bssid); + os_memset(wpa_s->pending_bssid, 0, ETH_ALEN); + return; + } /* try to continue anyway; new association will be tried again * after timeout */ assoc_failed = 1;