diff options
| -rw-r--r-- | net/wireless/core.h | 1 | ||||
| -rw-r--r-- | net/wireless/mlme.c | 9 | ||||
| -rw-r--r-- | net/wireless/sme.c | 21 |
3 files changed, 29 insertions, 2 deletions
diff --git a/net/wireless/core.h b/net/wireless/core.h index 2a33d8bc886b..68b321997d4c 100644 --- a/net/wireless/core.h +++ b/net/wireless/core.h | |||
| @@ -358,6 +358,7 @@ int cfg80211_mgd_wext_connect(struct cfg80211_registered_device *rdev, | |||
| 358 | struct wireless_dev *wdev); | 358 | struct wireless_dev *wdev); |
| 359 | 359 | ||
| 360 | void cfg80211_conn_work(struct work_struct *work); | 360 | void cfg80211_conn_work(struct work_struct *work); |
| 361 | void cfg80211_sme_failed_assoc(struct wireless_dev *wdev); | ||
| 361 | bool cfg80211_sme_failed_reassoc(struct wireless_dev *wdev); | 362 | bool cfg80211_sme_failed_reassoc(struct wireless_dev *wdev); |
| 362 | 363 | ||
| 363 | /* internal helpers */ | 364 | /* internal helpers */ |
diff --git a/net/wireless/mlme.c b/net/wireless/mlme.c index 79d2eec54cec..0a6b7a0eca6b 100644 --- a/net/wireless/mlme.c +++ b/net/wireless/mlme.c | |||
| @@ -62,6 +62,7 @@ void cfg80211_send_rx_assoc(struct net_device *dev, const u8 *buf, size_t len) | |||
| 62 | u8 *ie = mgmt->u.assoc_resp.variable; | 62 | u8 *ie = mgmt->u.assoc_resp.variable; |
| 63 | int i, ieoffs = offsetof(struct ieee80211_mgmt, u.assoc_resp.variable); | 63 | int i, ieoffs = offsetof(struct ieee80211_mgmt, u.assoc_resp.variable); |
| 64 | struct cfg80211_internal_bss *bss = NULL; | 64 | struct cfg80211_internal_bss *bss = NULL; |
| 65 | bool need_connect_result = true; | ||
| 65 | 66 | ||
| 66 | wdev_lock(wdev); | 67 | wdev_lock(wdev); |
| 67 | 68 | ||
| @@ -94,6 +95,14 @@ void cfg80211_send_rx_assoc(struct net_device *dev, const u8 *buf, size_t len) | |||
| 94 | } | 95 | } |
| 95 | 96 | ||
| 96 | WARN_ON(!bss); | 97 | WARN_ON(!bss); |
| 98 | } else if (wdev->conn) { | ||
| 99 | cfg80211_sme_failed_assoc(wdev); | ||
| 100 | need_connect_result = false; | ||
| 101 | /* | ||
| 102 | * do not call connect_result() now because the | ||
| 103 | * sme will schedule work that does it later. | ||
| 104 | */ | ||
| 105 | goto out; | ||
| 97 | } | 106 | } |
| 98 | 107 | ||
| 99 | if (!wdev->conn && wdev->sme_state == CFG80211_SME_IDLE) { | 108 | if (!wdev->conn && wdev->sme_state == CFG80211_SME_IDLE) { |
diff --git a/net/wireless/sme.c b/net/wireless/sme.c index 93c3ed329204..ece378d531ef 100644 --- a/net/wireless/sme.c +++ b/net/wireless/sme.c | |||
| @@ -26,6 +26,7 @@ struct cfg80211_conn { | |||
| 26 | CFG80211_CONN_AUTHENTICATING, | 26 | CFG80211_CONN_AUTHENTICATING, |
| 27 | CFG80211_CONN_ASSOCIATE_NEXT, | 27 | CFG80211_CONN_ASSOCIATE_NEXT, |
| 28 | CFG80211_CONN_ASSOCIATING, | 28 | CFG80211_CONN_ASSOCIATING, |
| 29 | CFG80211_CONN_DEAUTH_ASSOC_FAIL, | ||
| 29 | } state; | 30 | } state; |
| 30 | u8 bssid[ETH_ALEN], prev_bssid[ETH_ALEN]; | 31 | u8 bssid[ETH_ALEN], prev_bssid[ETH_ALEN]; |
| 31 | u8 *ie; | 32 | u8 *ie; |
| @@ -148,6 +149,12 @@ static int cfg80211_conn_do_work(struct wireless_dev *wdev) | |||
| 148 | NULL, 0, | 149 | NULL, 0, |
| 149 | WLAN_REASON_DEAUTH_LEAVING); | 150 | WLAN_REASON_DEAUTH_LEAVING); |
| 150 | return err; | 151 | return err; |
| 152 | case CFG80211_CONN_DEAUTH_ASSOC_FAIL: | ||
| 153 | __cfg80211_mlme_deauth(rdev, wdev->netdev, params->bssid, | ||
| 154 | NULL, 0, | ||
| 155 | WLAN_REASON_DEAUTH_LEAVING); | ||
| 156 | /* return an error so that we call __cfg80211_connect_result() */ | ||
| 157 | return -EINVAL; | ||
| 151 | default: | 158 | default: |
| 152 | return 0; | 159 | return 0; |
| 153 | } | 160 | } |
| @@ -158,6 +165,7 @@ void cfg80211_conn_work(struct work_struct *work) | |||
| 158 | struct cfg80211_registered_device *rdev = | 165 | struct cfg80211_registered_device *rdev = |
| 159 | container_of(work, struct cfg80211_registered_device, conn_work); | 166 | container_of(work, struct cfg80211_registered_device, conn_work); |
| 160 | struct wireless_dev *wdev; | 167 | struct wireless_dev *wdev; |
| 168 | u8 bssid[ETH_ALEN]; | ||
| 161 | 169 | ||
| 162 | rtnl_lock(); | 170 | rtnl_lock(); |
| 163 | cfg80211_lock_rdev(rdev); | 171 | cfg80211_lock_rdev(rdev); |
| @@ -173,10 +181,10 @@ void cfg80211_conn_work(struct work_struct *work) | |||
| 173 | wdev_unlock(wdev); | 181 | wdev_unlock(wdev); |
| 174 | continue; | 182 | continue; |
| 175 | } | 183 | } |
| 184 | memcpy(bssid, wdev->conn->params.bssid, ETH_ALEN); | ||
| 176 | if (cfg80211_conn_do_work(wdev)) | 185 | if (cfg80211_conn_do_work(wdev)) |
| 177 | __cfg80211_connect_result( | 186 | __cfg80211_connect_result( |
| 178 | wdev->netdev, | 187 | wdev->netdev, bssid, |
| 179 | wdev->conn->params.bssid, | ||
| 180 | NULL, 0, NULL, 0, | 188 | NULL, 0, NULL, 0, |
| 181 | WLAN_STATUS_UNSPECIFIED_FAILURE, | 189 | WLAN_STATUS_UNSPECIFIED_FAILURE, |
| 182 | false, NULL); | 190 | false, NULL); |
| @@ -337,6 +345,15 @@ bool cfg80211_sme_failed_reassoc(struct wireless_dev *wdev) | |||
| 337 | return true; | 345 | return true; |
| 338 | } | 346 | } |
| 339 | 347 | ||
| 348 | void cfg80211_sme_failed_assoc(struct wireless_dev *wdev) | ||
| 349 | { | ||
| 350 | struct wiphy *wiphy = wdev->wiphy; | ||
| 351 | struct cfg80211_registered_device *rdev = wiphy_to_dev(wiphy); | ||
| 352 | |||
| 353 | wdev->conn->state = CFG80211_CONN_DEAUTH_ASSOC_FAIL; | ||
| 354 | schedule_work(&rdev->conn_work); | ||
| 355 | } | ||
| 356 | |||
| 340 | void __cfg80211_connect_result(struct net_device *dev, const u8 *bssid, | 357 | void __cfg80211_connect_result(struct net_device *dev, const u8 *bssid, |
| 341 | const u8 *req_ie, size_t req_ie_len, | 358 | const u8 *req_ie, size_t req_ie_len, |
| 342 | const u8 *resp_ie, size_t resp_ie_len, | 359 | const u8 *resp_ie, size_t resp_ie_len, |
