diff options
Diffstat (limited to 'net/wireless/sme.c')
| -rw-r--r-- | net/wireless/sme.c | 24 |
1 files changed, 22 insertions, 2 deletions
diff --git a/net/wireless/sme.c b/net/wireless/sme.c index 93c3ed329204..9f0b2800a9d7 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_buf[ETH_ALEN], *bssid = NULL; | ||
| 161 | 169 | ||
| 162 | rtnl_lock(); | 170 | rtnl_lock(); |
| 163 | cfg80211_lock_rdev(rdev); | 171 | cfg80211_lock_rdev(rdev); |
| @@ -173,10 +181,13 @@ void cfg80211_conn_work(struct work_struct *work) | |||
| 173 | wdev_unlock(wdev); | 181 | wdev_unlock(wdev); |
| 174 | continue; | 182 | continue; |
| 175 | } | 183 | } |
| 184 | if (wdev->conn->params.bssid) { | ||
| 185 | memcpy(bssid_buf, wdev->conn->params.bssid, ETH_ALEN); | ||
| 186 | bssid = bssid_buf; | ||
| 187 | } | ||
| 176 | if (cfg80211_conn_do_work(wdev)) | 188 | if (cfg80211_conn_do_work(wdev)) |
| 177 | __cfg80211_connect_result( | 189 | __cfg80211_connect_result( |
| 178 | wdev->netdev, | 190 | wdev->netdev, bssid, |
| 179 | wdev->conn->params.bssid, | ||
| 180 | NULL, 0, NULL, 0, | 191 | NULL, 0, NULL, 0, |
| 181 | WLAN_STATUS_UNSPECIFIED_FAILURE, | 192 | WLAN_STATUS_UNSPECIFIED_FAILURE, |
| 182 | false, NULL); | 193 | false, NULL); |
| @@ -337,6 +348,15 @@ bool cfg80211_sme_failed_reassoc(struct wireless_dev *wdev) | |||
| 337 | return true; | 348 | return true; |
| 338 | } | 349 | } |
| 339 | 350 | ||
| 351 | void cfg80211_sme_failed_assoc(struct wireless_dev *wdev) | ||
| 352 | { | ||
| 353 | struct wiphy *wiphy = wdev->wiphy; | ||
| 354 | struct cfg80211_registered_device *rdev = wiphy_to_dev(wiphy); | ||
| 355 | |||
| 356 | wdev->conn->state = CFG80211_CONN_DEAUTH_ASSOC_FAIL; | ||
| 357 | schedule_work(&rdev->conn_work); | ||
| 358 | } | ||
| 359 | |||
| 340 | void __cfg80211_connect_result(struct net_device *dev, const u8 *bssid, | 360 | void __cfg80211_connect_result(struct net_device *dev, const u8 *bssid, |
| 341 | const u8 *req_ie, size_t req_ie_len, | 361 | const u8 *req_ie, size_t req_ie_len, |
| 342 | const u8 *resp_ie, size_t resp_ie_len, | 362 | const u8 *resp_ie, size_t resp_ie_len, |
