|
@@ -34,10 +34,11 @@ struct cfg80211_conn {
|
|
CFG80211_CONN_SCAN_AGAIN,
|
|
CFG80211_CONN_SCAN_AGAIN,
|
|
CFG80211_CONN_AUTHENTICATE_NEXT,
|
|
CFG80211_CONN_AUTHENTICATE_NEXT,
|
|
CFG80211_CONN_AUTHENTICATING,
|
|
CFG80211_CONN_AUTHENTICATING,
|
|
- CFG80211_CONN_AUTH_FAILED,
|
|
|
|
|
|
+ CFG80211_CONN_AUTH_FAILED_TIMEOUT,
|
|
CFG80211_CONN_ASSOCIATE_NEXT,
|
|
CFG80211_CONN_ASSOCIATE_NEXT,
|
|
CFG80211_CONN_ASSOCIATING,
|
|
CFG80211_CONN_ASSOCIATING,
|
|
CFG80211_CONN_ASSOC_FAILED,
|
|
CFG80211_CONN_ASSOC_FAILED,
|
|
|
|
+ CFG80211_CONN_ASSOC_FAILED_TIMEOUT,
|
|
CFG80211_CONN_DEAUTH,
|
|
CFG80211_CONN_DEAUTH,
|
|
CFG80211_CONN_ABANDON,
|
|
CFG80211_CONN_ABANDON,
|
|
CFG80211_CONN_CONNECTED,
|
|
CFG80211_CONN_CONNECTED,
|
|
@@ -140,7 +141,8 @@ static int cfg80211_conn_scan(struct wireless_dev *wdev)
|
|
return err;
|
|
return err;
|
|
}
|
|
}
|
|
|
|
|
|
-static int cfg80211_conn_do_work(struct wireless_dev *wdev)
|
|
|
|
|
|
+static int cfg80211_conn_do_work(struct wireless_dev *wdev,
|
|
|
|
+ enum nl80211_timeout_reason *treason)
|
|
{
|
|
{
|
|
struct cfg80211_registered_device *rdev = wiphy_to_rdev(wdev->wiphy);
|
|
struct cfg80211_registered_device *rdev = wiphy_to_rdev(wdev->wiphy);
|
|
struct cfg80211_connect_params *params;
|
|
struct cfg80211_connect_params *params;
|
|
@@ -171,7 +173,8 @@ static int cfg80211_conn_do_work(struct wireless_dev *wdev)
|
|
NULL, 0,
|
|
NULL, 0,
|
|
params->key, params->key_len,
|
|
params->key, params->key_len,
|
|
params->key_idx, NULL, 0);
|
|
params->key_idx, NULL, 0);
|
|
- case CFG80211_CONN_AUTH_FAILED:
|
|
|
|
|
|
+ case CFG80211_CONN_AUTH_FAILED_TIMEOUT:
|
|
|
|
+ *treason = NL80211_TIMEOUT_AUTH;
|
|
return -ENOTCONN;
|
|
return -ENOTCONN;
|
|
case CFG80211_CONN_ASSOCIATE_NEXT:
|
|
case CFG80211_CONN_ASSOCIATE_NEXT:
|
|
if (WARN_ON(!rdev->ops->assoc))
|
|
if (WARN_ON(!rdev->ops->assoc))
|
|
@@ -198,6 +201,9 @@ static int cfg80211_conn_do_work(struct wireless_dev *wdev)
|
|
WLAN_REASON_DEAUTH_LEAVING,
|
|
WLAN_REASON_DEAUTH_LEAVING,
|
|
false);
|
|
false);
|
|
return err;
|
|
return err;
|
|
|
|
+ case CFG80211_CONN_ASSOC_FAILED_TIMEOUT:
|
|
|
|
+ *treason = NL80211_TIMEOUT_ASSOC;
|
|
|
|
+ /* fall through */
|
|
case CFG80211_CONN_ASSOC_FAILED:
|
|
case CFG80211_CONN_ASSOC_FAILED:
|
|
cfg80211_mlme_deauth(rdev, wdev->netdev, params->bssid,
|
|
cfg80211_mlme_deauth(rdev, wdev->netdev, params->bssid,
|
|
NULL, 0,
|
|
NULL, 0,
|
|
@@ -223,6 +229,7 @@ void cfg80211_conn_work(struct work_struct *work)
|
|
container_of(work, struct cfg80211_registered_device, conn_work);
|
|
container_of(work, struct cfg80211_registered_device, conn_work);
|
|
struct wireless_dev *wdev;
|
|
struct wireless_dev *wdev;
|
|
u8 bssid_buf[ETH_ALEN], *bssid = NULL;
|
|
u8 bssid_buf[ETH_ALEN], *bssid = NULL;
|
|
|
|
+ enum nl80211_timeout_reason treason;
|
|
|
|
|
|
rtnl_lock();
|
|
rtnl_lock();
|
|
|
|
|
|
@@ -244,10 +251,12 @@ void cfg80211_conn_work(struct work_struct *work)
|
|
memcpy(bssid_buf, wdev->conn->params.bssid, ETH_ALEN);
|
|
memcpy(bssid_buf, wdev->conn->params.bssid, ETH_ALEN);
|
|
bssid = bssid_buf;
|
|
bssid = bssid_buf;
|
|
}
|
|
}
|
|
- if (cfg80211_conn_do_work(wdev)) {
|
|
|
|
|
|
+ treason = NL80211_TIMEOUT_UNSPECIFIED;
|
|
|
|
+ if (cfg80211_conn_do_work(wdev, &treason)) {
|
|
__cfg80211_connect_result(
|
|
__cfg80211_connect_result(
|
|
wdev->netdev, bssid,
|
|
wdev->netdev, bssid,
|
|
- NULL, 0, NULL, 0, -1, false, NULL);
|
|
|
|
|
|
+ NULL, 0, NULL, 0, -1, false, NULL,
|
|
|
|
+ treason);
|
|
}
|
|
}
|
|
wdev_unlock(wdev);
|
|
wdev_unlock(wdev);
|
|
}
|
|
}
|
|
@@ -352,7 +361,8 @@ void cfg80211_sme_rx_auth(struct wireless_dev *wdev, const u8 *buf, size_t len)
|
|
} else if (status_code != WLAN_STATUS_SUCCESS) {
|
|
} else if (status_code != WLAN_STATUS_SUCCESS) {
|
|
__cfg80211_connect_result(wdev->netdev, mgmt->bssid,
|
|
__cfg80211_connect_result(wdev->netdev, mgmt->bssid,
|
|
NULL, 0, NULL, 0,
|
|
NULL, 0, NULL, 0,
|
|
- status_code, false, NULL);
|
|
|
|
|
|
+ status_code, false, NULL,
|
|
|
|
+ NL80211_TIMEOUT_UNSPECIFIED);
|
|
} else if (wdev->conn->state == CFG80211_CONN_AUTHENTICATING) {
|
|
} else if (wdev->conn->state == CFG80211_CONN_AUTHENTICATING) {
|
|
wdev->conn->state = CFG80211_CONN_ASSOCIATE_NEXT;
|
|
wdev->conn->state = CFG80211_CONN_ASSOCIATE_NEXT;
|
|
schedule_work(&rdev->conn_work);
|
|
schedule_work(&rdev->conn_work);
|
|
@@ -400,7 +410,7 @@ void cfg80211_sme_auth_timeout(struct wireless_dev *wdev)
|
|
if (!wdev->conn)
|
|
if (!wdev->conn)
|
|
return;
|
|
return;
|
|
|
|
|
|
- wdev->conn->state = CFG80211_CONN_AUTH_FAILED;
|
|
|
|
|
|
+ wdev->conn->state = CFG80211_CONN_AUTH_FAILED_TIMEOUT;
|
|
schedule_work(&rdev->conn_work);
|
|
schedule_work(&rdev->conn_work);
|
|
}
|
|
}
|
|
|
|
|
|
@@ -422,7 +432,7 @@ void cfg80211_sme_assoc_timeout(struct wireless_dev *wdev)
|
|
if (!wdev->conn)
|
|
if (!wdev->conn)
|
|
return;
|
|
return;
|
|
|
|
|
|
- wdev->conn->state = CFG80211_CONN_ASSOC_FAILED;
|
|
|
|
|
|
+ wdev->conn->state = CFG80211_CONN_ASSOC_FAILED_TIMEOUT;
|
|
schedule_work(&rdev->conn_work);
|
|
schedule_work(&rdev->conn_work);
|
|
}
|
|
}
|
|
|
|
|
|
@@ -564,7 +574,9 @@ static int cfg80211_sme_connect(struct wireless_dev *wdev,
|
|
|
|
|
|
/* we're good if we have a matching bss struct */
|
|
/* we're good if we have a matching bss struct */
|
|
if (bss) {
|
|
if (bss) {
|
|
- err = cfg80211_conn_do_work(wdev);
|
|
|
|
|
|
+ enum nl80211_timeout_reason treason;
|
|
|
|
+
|
|
|
|
+ err = cfg80211_conn_do_work(wdev, &treason);
|
|
cfg80211_put_bss(wdev->wiphy, bss);
|
|
cfg80211_put_bss(wdev->wiphy, bss);
|
|
} else {
|
|
} else {
|
|
/* otherwise we'll need to scan for the AP first */
|
|
/* otherwise we'll need to scan for the AP first */
|
|
@@ -661,7 +673,8 @@ void __cfg80211_connect_result(struct net_device *dev, const u8 *bssid,
|
|
const u8 *req_ie, size_t req_ie_len,
|
|
const u8 *req_ie, size_t req_ie_len,
|
|
const u8 *resp_ie, size_t resp_ie_len,
|
|
const u8 *resp_ie, size_t resp_ie_len,
|
|
int status, bool wextev,
|
|
int status, bool wextev,
|
|
- struct cfg80211_bss *bss)
|
|
|
|
|
|
+ struct cfg80211_bss *bss,
|
|
|
|
+ enum nl80211_timeout_reason timeout_reason)
|
|
{
|
|
{
|
|
struct wireless_dev *wdev = dev->ieee80211_ptr;
|
|
struct wireless_dev *wdev = dev->ieee80211_ptr;
|
|
const u8 *country_ie;
|
|
const u8 *country_ie;
|
|
@@ -680,7 +693,7 @@ void __cfg80211_connect_result(struct net_device *dev, const u8 *bssid,
|
|
nl80211_send_connect_result(wiphy_to_rdev(wdev->wiphy), dev,
|
|
nl80211_send_connect_result(wiphy_to_rdev(wdev->wiphy), dev,
|
|
bssid, req_ie, req_ie_len,
|
|
bssid, req_ie, req_ie_len,
|
|
resp_ie, resp_ie_len,
|
|
resp_ie, resp_ie_len,
|
|
- status, GFP_KERNEL);
|
|
|
|
|
|
+ status, timeout_reason, GFP_KERNEL);
|
|
|
|
|
|
#ifdef CONFIG_CFG80211_WEXT
|
|
#ifdef CONFIG_CFG80211_WEXT
|
|
if (wextev) {
|
|
if (wextev) {
|
|
@@ -771,7 +784,8 @@ void __cfg80211_connect_result(struct net_device *dev, const u8 *bssid,
|
|
void cfg80211_connect_bss(struct net_device *dev, const u8 *bssid,
|
|
void cfg80211_connect_bss(struct net_device *dev, const u8 *bssid,
|
|
struct cfg80211_bss *bss, const u8 *req_ie,
|
|
struct cfg80211_bss *bss, const u8 *req_ie,
|
|
size_t req_ie_len, const u8 *resp_ie,
|
|
size_t req_ie_len, const u8 *resp_ie,
|
|
- size_t resp_ie_len, int status, gfp_t gfp)
|
|
|
|
|
|
+ size_t resp_ie_len, int status, gfp_t gfp,
|
|
|
|
+ enum nl80211_timeout_reason timeout_reason)
|
|
{
|
|
{
|
|
struct wireless_dev *wdev = dev->ieee80211_ptr;
|
|
struct wireless_dev *wdev = dev->ieee80211_ptr;
|
|
struct cfg80211_registered_device *rdev = wiphy_to_rdev(wdev->wiphy);
|
|
struct cfg80211_registered_device *rdev = wiphy_to_rdev(wdev->wiphy);
|
|
@@ -811,6 +825,7 @@ void cfg80211_connect_bss(struct net_device *dev, const u8 *bssid,
|
|
cfg80211_hold_bss(bss_from_pub(bss));
|
|
cfg80211_hold_bss(bss_from_pub(bss));
|
|
ev->cr.bss = bss;
|
|
ev->cr.bss = bss;
|
|
ev->cr.status = status;
|
|
ev->cr.status = status;
|
|
|
|
+ ev->cr.timeout_reason = timeout_reason;
|
|
|
|
|
|
spin_lock_irqsave(&wdev->event_lock, flags);
|
|
spin_lock_irqsave(&wdev->event_lock, flags);
|
|
list_add_tail(&ev->list, &wdev->event_list);
|
|
list_add_tail(&ev->list, &wdev->event_list);
|