^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1) // SPDX-License-Identifier: GPL-2.0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3) * SME code for cfg80211
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4) * both driver SME event handling and the SME implementation
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5) * (for nl80211's connect() and wext)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7) * Copyright 2009 Johannes Berg <johannes@sipsolutions.net>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8) * Copyright (C) 2009, 2020 Intel Corporation. All rights reserved.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9) * Copyright 2017 Intel Deutschland GmbH
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12) #include <linux/etherdevice.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13) #include <linux/if_arp.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14) #include <linux/slab.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15) #include <linux/workqueue.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16) #include <linux/wireless.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17) #include <linux/export.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18) #include <net/iw_handler.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19) #include <net/cfg80211.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20) #include <net/rtnetlink.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21) #include "nl80211.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22) #include "reg.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23) #include "rdev-ops.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26) * Software SME in cfg80211, using auth/assoc/deauth calls to the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27) * driver. This is for implementing nl80211's connect/disconnect
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28) * and wireless extensions (if configured.)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31) struct cfg80211_conn {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32) struct cfg80211_connect_params params;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33) /* these are sub-states of the _CONNECTING sme_state */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34) enum {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35) CFG80211_CONN_SCANNING,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36) CFG80211_CONN_SCAN_AGAIN,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37) CFG80211_CONN_AUTHENTICATE_NEXT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38) CFG80211_CONN_AUTHENTICATING,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39) CFG80211_CONN_AUTH_FAILED_TIMEOUT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40) CFG80211_CONN_ASSOCIATE_NEXT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41) CFG80211_CONN_ASSOCIATING,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42) CFG80211_CONN_ASSOC_FAILED,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43) CFG80211_CONN_ASSOC_FAILED_TIMEOUT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44) CFG80211_CONN_DEAUTH,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45) CFG80211_CONN_ABANDON,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46) CFG80211_CONN_CONNECTED,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47) } state;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48) u8 bssid[ETH_ALEN], prev_bssid[ETH_ALEN];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49) const u8 *ie;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50) size_t ie_len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51) bool auto_auth, prev_bssid_valid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54) static void cfg80211_sme_free(struct wireless_dev *wdev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56) if (!wdev->conn)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59) kfree(wdev->conn->ie);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60) kfree(wdev->conn);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61) wdev->conn = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64) static int cfg80211_conn_scan(struct wireless_dev *wdev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66) struct cfg80211_registered_device *rdev = wiphy_to_rdev(wdev->wiphy);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67) struct cfg80211_scan_request *request;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68) int n_channels, err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70) ASSERT_RTNL();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71) ASSERT_WDEV_LOCK(wdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73) if (rdev->scan_req || rdev->scan_msg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74) return -EBUSY;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76) if (wdev->conn->params.channel)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77) n_channels = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79) n_channels = ieee80211_get_num_supported_channels(wdev->wiphy);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81) request = kzalloc(sizeof(*request) + sizeof(request->ssids[0]) +
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82) sizeof(request->channels[0]) * n_channels,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83) GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84) if (!request)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87) if (wdev->conn->params.channel) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88) enum nl80211_band band = wdev->conn->params.channel->band;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89) struct ieee80211_supported_band *sband =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90) wdev->wiphy->bands[band];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92) if (!sband) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93) kfree(request);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 95) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 96) request->channels[0] = wdev->conn->params.channel;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 97) request->rates[band] = (1 << sband->n_bitrates) - 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 98) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 99) int i = 0, j;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) enum nl80211_band band;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) struct ieee80211_supported_band *bands;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) struct ieee80211_channel *channel;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) for (band = 0; band < NUM_NL80211_BANDS; band++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) bands = wdev->wiphy->bands[band];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) if (!bands)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) for (j = 0; j < bands->n_channels; j++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) channel = &bands->channels[j];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) if (channel->flags & IEEE80211_CHAN_DISABLED)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) request->channels[i++] = channel;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) request->rates[band] = (1 << bands->n_bitrates) - 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) n_channels = i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) request->n_channels = n_channels;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) request->ssids = (void *)&request->channels[n_channels];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) request->n_ssids = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) memcpy(request->ssids[0].ssid, wdev->conn->params.ssid,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) wdev->conn->params.ssid_len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) request->ssids[0].ssid_len = wdev->conn->params.ssid_len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) eth_broadcast_addr(request->bssid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) request->wdev = wdev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) request->wiphy = &rdev->wiphy;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) request->scan_start = jiffies;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) rdev->scan_req = request;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) err = rdev_scan(rdev, request);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) if (!err) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) wdev->conn->state = CFG80211_CONN_SCANNING;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) nl80211_send_scan_start(rdev, wdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) dev_hold(wdev->netdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) rdev->scan_req = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) kfree(request);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) static int cfg80211_conn_do_work(struct wireless_dev *wdev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) enum nl80211_timeout_reason *treason)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) struct cfg80211_registered_device *rdev = wiphy_to_rdev(wdev->wiphy);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) struct cfg80211_connect_params *params;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) struct cfg80211_assoc_request req = {};
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152) int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) ASSERT_WDEV_LOCK(wdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) if (!wdev->conn)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159) params = &wdev->conn->params;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161) switch (wdev->conn->state) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) case CFG80211_CONN_SCANNING:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163) /* didn't find it during scan ... */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164) return -ENOENT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165) case CFG80211_CONN_SCAN_AGAIN:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166) return cfg80211_conn_scan(wdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167) case CFG80211_CONN_AUTHENTICATE_NEXT:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168) if (WARN_ON(!rdev->ops->auth))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169) return -EOPNOTSUPP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170) wdev->conn->state = CFG80211_CONN_AUTHENTICATING;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171) return cfg80211_mlme_auth(rdev, wdev->netdev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172) params->channel, params->auth_type,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173) params->bssid,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174) params->ssid, params->ssid_len,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175) NULL, 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176) params->key, params->key_len,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177) params->key_idx, NULL, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178) case CFG80211_CONN_AUTH_FAILED_TIMEOUT:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179) *treason = NL80211_TIMEOUT_AUTH;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180) return -ENOTCONN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181) case CFG80211_CONN_ASSOCIATE_NEXT:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182) if (WARN_ON(!rdev->ops->assoc))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183) return -EOPNOTSUPP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184) wdev->conn->state = CFG80211_CONN_ASSOCIATING;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185) if (wdev->conn->prev_bssid_valid)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186) req.prev_bssid = wdev->conn->prev_bssid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187) req.ie = params->ie;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188) req.ie_len = params->ie_len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189) req.use_mfp = params->mfp != NL80211_MFP_NO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190) req.crypto = params->crypto;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191) req.flags = params->flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192) req.ht_capa = params->ht_capa;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193) req.ht_capa_mask = params->ht_capa_mask;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194) req.vht_capa = params->vht_capa;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195) req.vht_capa_mask = params->vht_capa_mask;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197) err = cfg80211_mlme_assoc(rdev, wdev->netdev, params->channel,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198) params->bssid, params->ssid,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199) params->ssid_len, &req);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200) if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201) cfg80211_mlme_deauth(rdev, wdev->netdev, params->bssid,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202) NULL, 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203) WLAN_REASON_DEAUTH_LEAVING,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204) false);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206) case CFG80211_CONN_ASSOC_FAILED_TIMEOUT:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207) *treason = NL80211_TIMEOUT_ASSOC;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208) fallthrough;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209) case CFG80211_CONN_ASSOC_FAILED:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210) cfg80211_mlme_deauth(rdev, wdev->netdev, params->bssid,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211) NULL, 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212) WLAN_REASON_DEAUTH_LEAVING, false);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213) return -ENOTCONN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214) case CFG80211_CONN_DEAUTH:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215) cfg80211_mlme_deauth(rdev, wdev->netdev, params->bssid,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216) NULL, 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217) WLAN_REASON_DEAUTH_LEAVING, false);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218) fallthrough;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219) case CFG80211_CONN_ABANDON:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220) /* free directly, disconnected event already sent */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221) cfg80211_sme_free(wdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228) void cfg80211_conn_work(struct work_struct *work)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230) struct cfg80211_registered_device *rdev =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231) container_of(work, struct cfg80211_registered_device, conn_work);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232) struct wireless_dev *wdev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 233) u8 bssid_buf[ETH_ALEN], *bssid = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 234) enum nl80211_timeout_reason treason;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 235)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 236) rtnl_lock();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 237)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 238) list_for_each_entry(wdev, &rdev->wiphy.wdev_list, list) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 239) if (!wdev->netdev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 240) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 241)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 242) wdev_lock(wdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 243) if (!netif_running(wdev->netdev)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 244) wdev_unlock(wdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 245) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 246) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 247) if (!wdev->conn ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 248) wdev->conn->state == CFG80211_CONN_CONNECTED) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 249) wdev_unlock(wdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 250) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 251) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 252) if (wdev->conn->params.bssid) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 253) memcpy(bssid_buf, wdev->conn->params.bssid, ETH_ALEN);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 254) bssid = bssid_buf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 255) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 256) treason = NL80211_TIMEOUT_UNSPECIFIED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 257) if (cfg80211_conn_do_work(wdev, &treason)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 258) struct cfg80211_connect_resp_params cr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 259)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 260) memset(&cr, 0, sizeof(cr));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 261) cr.status = -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 262) cr.bssid = bssid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 263) cr.timeout_reason = treason;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 264) __cfg80211_connect_result(wdev->netdev, &cr, false);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 265) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 266) wdev_unlock(wdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 267) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 268)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 269) rtnl_unlock();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 270) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 271)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 272) /* Returned bss is reference counted and must be cleaned up appropriately. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 273) static struct cfg80211_bss *cfg80211_get_conn_bss(struct wireless_dev *wdev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 274) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 275) struct cfg80211_registered_device *rdev = wiphy_to_rdev(wdev->wiphy);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 276) struct cfg80211_bss *bss;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 277)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 278) ASSERT_WDEV_LOCK(wdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 279)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 280) bss = cfg80211_get_bss(wdev->wiphy, wdev->conn->params.channel,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 281) wdev->conn->params.bssid,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 282) wdev->conn->params.ssid,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 283) wdev->conn->params.ssid_len,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 284) wdev->conn_bss_type,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 285) IEEE80211_PRIVACY(wdev->conn->params.privacy));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 286) if (!bss)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 287) return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 288)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 289) memcpy(wdev->conn->bssid, bss->bssid, ETH_ALEN);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 290) wdev->conn->params.bssid = wdev->conn->bssid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 291) wdev->conn->params.channel = bss->channel;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 292) wdev->conn->state = CFG80211_CONN_AUTHENTICATE_NEXT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 293) schedule_work(&rdev->conn_work);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 294)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 295) return bss;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 296) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 297)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 298) static void __cfg80211_sme_scan_done(struct net_device *dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 299) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 300) struct wireless_dev *wdev = dev->ieee80211_ptr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 301) struct cfg80211_registered_device *rdev = wiphy_to_rdev(wdev->wiphy);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 302) struct cfg80211_bss *bss;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 303)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 304) ASSERT_WDEV_LOCK(wdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 305)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 306) if (!wdev->conn)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 307) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 308)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 309) if (wdev->conn->state != CFG80211_CONN_SCANNING &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 310) wdev->conn->state != CFG80211_CONN_SCAN_AGAIN)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 311) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 312)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 313) bss = cfg80211_get_conn_bss(wdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 314) if (bss)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 315) cfg80211_put_bss(&rdev->wiphy, bss);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 316) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 317) schedule_work(&rdev->conn_work);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 318) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 319)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 320) void cfg80211_sme_scan_done(struct net_device *dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 321) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 322) struct wireless_dev *wdev = dev->ieee80211_ptr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 323)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 324) wdev_lock(wdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 325) __cfg80211_sme_scan_done(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 326) wdev_unlock(wdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 327) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 328)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 329) void cfg80211_sme_rx_auth(struct wireless_dev *wdev, const u8 *buf, size_t len)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 330) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 331) struct wiphy *wiphy = wdev->wiphy;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 332) struct cfg80211_registered_device *rdev = wiphy_to_rdev(wiphy);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 333) struct ieee80211_mgmt *mgmt = (struct ieee80211_mgmt *)buf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 334) u16 status_code = le16_to_cpu(mgmt->u.auth.status_code);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 335)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 336) ASSERT_WDEV_LOCK(wdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 337)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 338) if (!wdev->conn || wdev->conn->state == CFG80211_CONN_CONNECTED)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 339) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 340)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 341) if (status_code == WLAN_STATUS_NOT_SUPPORTED_AUTH_ALG &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 342) wdev->conn->auto_auth &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 343) wdev->conn->params.auth_type != NL80211_AUTHTYPE_NETWORK_EAP) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 344) /* select automatically between only open, shared, leap */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 345) switch (wdev->conn->params.auth_type) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 346) case NL80211_AUTHTYPE_OPEN_SYSTEM:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 347) if (wdev->connect_keys)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 348) wdev->conn->params.auth_type =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 349) NL80211_AUTHTYPE_SHARED_KEY;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 350) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 351) wdev->conn->params.auth_type =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 352) NL80211_AUTHTYPE_NETWORK_EAP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 353) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 354) case NL80211_AUTHTYPE_SHARED_KEY:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 355) wdev->conn->params.auth_type =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 356) NL80211_AUTHTYPE_NETWORK_EAP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 357) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 358) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 359) /* huh? */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 360) wdev->conn->params.auth_type =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 361) NL80211_AUTHTYPE_OPEN_SYSTEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 362) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 363) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 364) wdev->conn->state = CFG80211_CONN_AUTHENTICATE_NEXT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 365) schedule_work(&rdev->conn_work);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 366) } else if (status_code != WLAN_STATUS_SUCCESS) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 367) struct cfg80211_connect_resp_params cr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 368)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 369) memset(&cr, 0, sizeof(cr));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 370) cr.status = status_code;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 371) cr.bssid = mgmt->bssid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 372) cr.timeout_reason = NL80211_TIMEOUT_UNSPECIFIED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 373) __cfg80211_connect_result(wdev->netdev, &cr, false);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 374) } else if (wdev->conn->state == CFG80211_CONN_AUTHENTICATING) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 375) wdev->conn->state = CFG80211_CONN_ASSOCIATE_NEXT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 376) schedule_work(&rdev->conn_work);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 377) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 378) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 379)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 380) bool cfg80211_sme_rx_assoc_resp(struct wireless_dev *wdev, u16 status)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 381) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 382) struct cfg80211_registered_device *rdev = wiphy_to_rdev(wdev->wiphy);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 383)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 384) if (!wdev->conn)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 385) return false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 386)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 387) if (status == WLAN_STATUS_SUCCESS) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 388) wdev->conn->state = CFG80211_CONN_CONNECTED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 389) return false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 390) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 391)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 392) if (wdev->conn->prev_bssid_valid) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 393) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 394) * Some stupid APs don't accept reassoc, so we
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 395) * need to fall back to trying regular assoc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 396) * return true so no event is sent to userspace.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 397) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 398) wdev->conn->prev_bssid_valid = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 399) wdev->conn->state = CFG80211_CONN_ASSOCIATE_NEXT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 400) schedule_work(&rdev->conn_work);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 401) return true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 402) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 403)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 404) wdev->conn->state = CFG80211_CONN_ASSOC_FAILED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 405) schedule_work(&rdev->conn_work);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 406) return false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 407) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 408)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 409) void cfg80211_sme_deauth(struct wireless_dev *wdev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 410) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 411) cfg80211_sme_free(wdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 412) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 413)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 414) void cfg80211_sme_auth_timeout(struct wireless_dev *wdev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 415) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 416) struct cfg80211_registered_device *rdev = wiphy_to_rdev(wdev->wiphy);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 417)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 418) if (!wdev->conn)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 419) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 420)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 421) wdev->conn->state = CFG80211_CONN_AUTH_FAILED_TIMEOUT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 422) schedule_work(&rdev->conn_work);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 423) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 424)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 425) void cfg80211_sme_disassoc(struct wireless_dev *wdev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 426) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 427) struct cfg80211_registered_device *rdev = wiphy_to_rdev(wdev->wiphy);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 428)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 429) if (!wdev->conn)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 430) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 431)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 432) wdev->conn->state = CFG80211_CONN_DEAUTH;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 433) schedule_work(&rdev->conn_work);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 434) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 435)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 436) void cfg80211_sme_assoc_timeout(struct wireless_dev *wdev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 437) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 438) struct cfg80211_registered_device *rdev = wiphy_to_rdev(wdev->wiphy);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 439)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 440) if (!wdev->conn)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 441) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 442)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 443) wdev->conn->state = CFG80211_CONN_ASSOC_FAILED_TIMEOUT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 444) schedule_work(&rdev->conn_work);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 445) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 446)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 447) void cfg80211_sme_abandon_assoc(struct wireless_dev *wdev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 448) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 449) struct cfg80211_registered_device *rdev = wiphy_to_rdev(wdev->wiphy);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 450)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 451) if (!wdev->conn)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 452) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 453)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 454) wdev->conn->state = CFG80211_CONN_ABANDON;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 455) schedule_work(&rdev->conn_work);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 456) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 457)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 458) static int cfg80211_sme_get_conn_ies(struct wireless_dev *wdev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 459) const u8 *ies, size_t ies_len,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 460) const u8 **out_ies, size_t *out_ies_len)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 461) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 462) struct cfg80211_registered_device *rdev = wiphy_to_rdev(wdev->wiphy);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 463) u8 *buf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 464) size_t offs;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 465)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 466) if (!rdev->wiphy.extended_capabilities_len ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 467) (ies && cfg80211_find_ie(WLAN_EID_EXT_CAPABILITY, ies, ies_len))) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 468) *out_ies = kmemdup(ies, ies_len, GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 469) if (!*out_ies)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 470) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 471) *out_ies_len = ies_len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 472) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 473) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 474)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 475) buf = kmalloc(ies_len + rdev->wiphy.extended_capabilities_len + 2,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 476) GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 477) if (!buf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 478) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 479)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 480) if (ies_len) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 481) static const u8 before_extcapa[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 482) /* not listing IEs expected to be created by driver */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 483) WLAN_EID_RSN,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 484) WLAN_EID_QOS_CAPA,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 485) WLAN_EID_RRM_ENABLED_CAPABILITIES,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 486) WLAN_EID_MOBILITY_DOMAIN,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 487) WLAN_EID_SUPPORTED_REGULATORY_CLASSES,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 488) WLAN_EID_BSS_COEX_2040,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 489) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 490)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 491) offs = ieee80211_ie_split(ies, ies_len, before_extcapa,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 492) ARRAY_SIZE(before_extcapa), 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 493) memcpy(buf, ies, offs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 494) /* leave a whole for extended capabilities IE */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 495) memcpy(buf + offs + rdev->wiphy.extended_capabilities_len + 2,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 496) ies + offs, ies_len - offs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 497) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 498) offs = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 499) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 500)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 501) /* place extended capabilities IE (with only driver capabilities) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 502) buf[offs] = WLAN_EID_EXT_CAPABILITY;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 503) buf[offs + 1] = rdev->wiphy.extended_capabilities_len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 504) memcpy(buf + offs + 2,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 505) rdev->wiphy.extended_capabilities,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 506) rdev->wiphy.extended_capabilities_len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 507)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 508) *out_ies = buf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 509) *out_ies_len = ies_len + rdev->wiphy.extended_capabilities_len + 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 510)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 511) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 512) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 513)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 514) static int cfg80211_sme_connect(struct wireless_dev *wdev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 515) struct cfg80211_connect_params *connect,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 516) const u8 *prev_bssid)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 517) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 518) struct cfg80211_registered_device *rdev = wiphy_to_rdev(wdev->wiphy);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 519) struct cfg80211_bss *bss;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 520) int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 521)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 522) if (!rdev->ops->auth || !rdev->ops->assoc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 523) return -EOPNOTSUPP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 524)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 525) if (wdev->current_bss) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 526) cfg80211_unhold_bss(wdev->current_bss);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 527) cfg80211_put_bss(wdev->wiphy, &wdev->current_bss->pub);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 528) wdev->current_bss = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 529)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 530) cfg80211_sme_free(wdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 531) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 532)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 533) if (wdev->conn)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 534) return -EINPROGRESS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 535)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 536) wdev->conn = kzalloc(sizeof(*wdev->conn), GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 537) if (!wdev->conn)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 538) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 539)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 540) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 541) * Copy all parameters, and treat explicitly IEs, BSSID, SSID.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 542) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 543) memcpy(&wdev->conn->params, connect, sizeof(*connect));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 544) if (connect->bssid) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 545) wdev->conn->params.bssid = wdev->conn->bssid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 546) memcpy(wdev->conn->bssid, connect->bssid, ETH_ALEN);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 547) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 548)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 549) if (cfg80211_sme_get_conn_ies(wdev, connect->ie, connect->ie_len,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 550) &wdev->conn->ie,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 551) &wdev->conn->params.ie_len)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 552) kfree(wdev->conn);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 553) wdev->conn = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 554) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 555) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 556) wdev->conn->params.ie = wdev->conn->ie;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 557)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 558) if (connect->auth_type == NL80211_AUTHTYPE_AUTOMATIC) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 559) wdev->conn->auto_auth = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 560) /* start with open system ... should mostly work */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 561) wdev->conn->params.auth_type =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 562) NL80211_AUTHTYPE_OPEN_SYSTEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 563) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 564) wdev->conn->auto_auth = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 565) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 566)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 567) wdev->conn->params.ssid = wdev->ssid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 568) wdev->conn->params.ssid_len = wdev->ssid_len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 569)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 570) /* see if we have the bss already */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 571) bss = cfg80211_get_conn_bss(wdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 572)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 573) if (prev_bssid) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 574) memcpy(wdev->conn->prev_bssid, prev_bssid, ETH_ALEN);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 575) wdev->conn->prev_bssid_valid = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 576) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 577)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 578) /* we're good if we have a matching bss struct */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 579) if (bss) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 580) enum nl80211_timeout_reason treason;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 581)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 582) err = cfg80211_conn_do_work(wdev, &treason);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 583) cfg80211_put_bss(wdev->wiphy, bss);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 584) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 585) /* otherwise we'll need to scan for the AP first */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 586) err = cfg80211_conn_scan(wdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 587)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 588) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 589) * If we can't scan right now, then we need to scan again
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 590) * after the current scan finished, since the parameters
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 591) * changed (unless we find a good AP anyway).
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 592) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 593) if (err == -EBUSY) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 594) err = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 595) wdev->conn->state = CFG80211_CONN_SCAN_AGAIN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 596) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 597) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 598)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 599) if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 600) cfg80211_sme_free(wdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 601)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 602) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 603) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 604)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 605) static int cfg80211_sme_disconnect(struct wireless_dev *wdev, u16 reason)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 606) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 607) struct cfg80211_registered_device *rdev = wiphy_to_rdev(wdev->wiphy);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 608) int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 609)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 610) if (!wdev->conn)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 611) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 612)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 613) if (!rdev->ops->deauth)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 614) return -EOPNOTSUPP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 615)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 616) if (wdev->conn->state == CFG80211_CONN_SCANNING ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 617) wdev->conn->state == CFG80211_CONN_SCAN_AGAIN) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 618) err = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 619) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 620) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 621)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 622) /* wdev->conn->params.bssid must be set if > SCANNING */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 623) err = cfg80211_mlme_deauth(rdev, wdev->netdev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 624) wdev->conn->params.bssid,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 625) NULL, 0, reason, false);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 626) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 627) cfg80211_sme_free(wdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 628) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 629) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 630)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 631) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 632) * code shared for in-device and software SME
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 633) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 634)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 635) static bool cfg80211_is_all_idle(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 636) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 637) struct cfg80211_registered_device *rdev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 638) struct wireless_dev *wdev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 639) bool is_all_idle = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 640)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 641) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 642) * All devices must be idle as otherwise if you are actively
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 643) * scanning some new beacon hints could be learned and would
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 644) * count as new regulatory hints.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 645) * Also if there is any other active beaconing interface we
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 646) * need not issue a disconnect hint and reset any info such
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 647) * as chan dfs state, etc.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 648) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 649) list_for_each_entry(rdev, &cfg80211_rdev_list, list) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 650) list_for_each_entry(wdev, &rdev->wiphy.wdev_list, list) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 651) wdev_lock(wdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 652) if (wdev->conn || wdev->current_bss ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 653) cfg80211_beaconing_iface_active(wdev))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 654) is_all_idle = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 655) wdev_unlock(wdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 656) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 657) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 658)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 659) return is_all_idle;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 660) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 661)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 662) static void disconnect_work(struct work_struct *work)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 663) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 664) rtnl_lock();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 665) if (cfg80211_is_all_idle())
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 666) regulatory_hint_disconnect();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 667) rtnl_unlock();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 668) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 669)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 670) DECLARE_WORK(cfg80211_disconnect_work, disconnect_work);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 671)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 672)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 673) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 674) * API calls for drivers implementing connect/disconnect and
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 675) * SME event handling
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 676) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 677)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 678) /* This method must consume bss one way or another */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 679) void __cfg80211_connect_result(struct net_device *dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 680) struct cfg80211_connect_resp_params *cr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 681) bool wextev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 682) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 683) struct wireless_dev *wdev = dev->ieee80211_ptr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 684) const u8 *country_ie;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 685) #ifdef CONFIG_CFG80211_WEXT
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 686) union iwreq_data wrqu;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 687) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 688)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 689) ASSERT_WDEV_LOCK(wdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 690)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 691) if (WARN_ON(wdev->iftype != NL80211_IFTYPE_STATION &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 692) wdev->iftype != NL80211_IFTYPE_P2P_CLIENT)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 693) cfg80211_put_bss(wdev->wiphy, cr->bss);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 694) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 695) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 696)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 697) wdev->unprot_beacon_reported = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 698) nl80211_send_connect_result(wiphy_to_rdev(wdev->wiphy), dev, cr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 699) GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 700)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 701) #ifdef CONFIG_CFG80211_WEXT
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 702) if (wextev) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 703) if (cr->req_ie && cr->status == WLAN_STATUS_SUCCESS) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 704) memset(&wrqu, 0, sizeof(wrqu));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 705) wrqu.data.length = cr->req_ie_len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 706) wireless_send_event(dev, IWEVASSOCREQIE, &wrqu,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 707) cr->req_ie);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 708) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 709)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 710) if (cr->resp_ie && cr->status == WLAN_STATUS_SUCCESS) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 711) memset(&wrqu, 0, sizeof(wrqu));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 712) wrqu.data.length = cr->resp_ie_len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 713) wireless_send_event(dev, IWEVASSOCRESPIE, &wrqu,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 714) cr->resp_ie);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 715) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 716)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 717) memset(&wrqu, 0, sizeof(wrqu));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 718) wrqu.ap_addr.sa_family = ARPHRD_ETHER;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 719) if (cr->bssid && cr->status == WLAN_STATUS_SUCCESS) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 720) memcpy(wrqu.ap_addr.sa_data, cr->bssid, ETH_ALEN);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 721) memcpy(wdev->wext.prev_bssid, cr->bssid, ETH_ALEN);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 722) wdev->wext.prev_bssid_valid = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 723) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 724) wireless_send_event(dev, SIOCGIWAP, &wrqu, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 725) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 726) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 727)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 728) if (!cr->bss && (cr->status == WLAN_STATUS_SUCCESS)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 729) WARN_ON_ONCE(!wiphy_to_rdev(wdev->wiphy)->ops->connect);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 730) cr->bss = cfg80211_get_bss(wdev->wiphy, NULL, cr->bssid,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 731) wdev->ssid, wdev->ssid_len,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 732) wdev->conn_bss_type,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 733) IEEE80211_PRIVACY_ANY);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 734) if (cr->bss)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 735) cfg80211_hold_bss(bss_from_pub(cr->bss));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 736) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 737)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 738) if (wdev->current_bss) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 739) cfg80211_unhold_bss(wdev->current_bss);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 740) cfg80211_put_bss(wdev->wiphy, &wdev->current_bss->pub);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 741) wdev->current_bss = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 742) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 743)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 744) if (cr->status != WLAN_STATUS_SUCCESS) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 745) kfree_sensitive(wdev->connect_keys);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 746) wdev->connect_keys = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 747) wdev->ssid_len = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 748) wdev->conn_owner_nlportid = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 749) if (cr->bss) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 750) cfg80211_unhold_bss(bss_from_pub(cr->bss));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 751) cfg80211_put_bss(wdev->wiphy, cr->bss);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 752) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 753) cfg80211_sme_free(wdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 754) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 755) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 756)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 757) if (WARN_ON(!cr->bss))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 758) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 759)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 760) wdev->current_bss = bss_from_pub(cr->bss);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 761)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 762) if (!(wdev->wiphy->flags & WIPHY_FLAG_HAS_STATIC_WEP))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 763) cfg80211_upload_connect_keys(wdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 764)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 765) rcu_read_lock();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 766) country_ie = ieee80211_bss_get_ie(cr->bss, WLAN_EID_COUNTRY);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 767) if (!country_ie) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 768) rcu_read_unlock();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 769) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 770) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 771)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 772) country_ie = kmemdup(country_ie, 2 + country_ie[1], GFP_ATOMIC);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 773) rcu_read_unlock();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 774)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 775) if (!country_ie)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 776) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 777)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 778) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 779) * ieee80211_bss_get_ie() ensures we can access:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 780) * - country_ie + 2, the start of the country ie data, and
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 781) * - and country_ie[1] which is the IE length
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 782) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 783) regulatory_hint_country_ie(wdev->wiphy, cr->bss->channel->band,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 784) country_ie + 2, country_ie[1]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 785) kfree(country_ie);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 786) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 787)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 788) /* Consumes bss object one way or another */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 789) void cfg80211_connect_done(struct net_device *dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 790) struct cfg80211_connect_resp_params *params,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 791) gfp_t gfp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 792) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 793) struct wireless_dev *wdev = dev->ieee80211_ptr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 794) struct cfg80211_registered_device *rdev = wiphy_to_rdev(wdev->wiphy);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 795) struct cfg80211_event *ev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 796) unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 797) u8 *next;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 798)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 799) if (params->bss) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 800) struct cfg80211_internal_bss *ibss = bss_from_pub(params->bss);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 801)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 802) if (list_empty(&ibss->list)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 803) struct cfg80211_bss *found = NULL, *tmp = params->bss;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 804)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 805) found = cfg80211_get_bss(wdev->wiphy, NULL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 806) params->bss->bssid,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 807) wdev->ssid, wdev->ssid_len,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 808) wdev->conn_bss_type,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 809) IEEE80211_PRIVACY_ANY);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 810) if (found) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 811) /* The same BSS is already updated so use it
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 812) * instead, as it has latest info.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 813) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 814) params->bss = found;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 815) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 816) /* Update with BSS provided by driver, it will
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 817) * be freshly added and ref cnted, we can free
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 818) * the old one.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 819) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 820) * signal_valid can be false, as we are not
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 821) * expecting the BSS to be found.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 822) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 823) * keep the old timestamp to avoid confusion
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 824) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 825) cfg80211_bss_update(rdev, ibss, false,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 826) ibss->ts);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 827) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 828)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 829) cfg80211_put_bss(wdev->wiphy, tmp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 830) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 831) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 832)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 833) ev = kzalloc(sizeof(*ev) + (params->bssid ? ETH_ALEN : 0) +
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 834) params->req_ie_len + params->resp_ie_len +
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 835) params->fils.kek_len + params->fils.pmk_len +
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 836) (params->fils.pmkid ? WLAN_PMKID_LEN : 0), gfp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 837) if (!ev) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 838) cfg80211_put_bss(wdev->wiphy, params->bss);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 839) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 840) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 841)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 842) ev->type = EVENT_CONNECT_RESULT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 843) next = ((u8 *)ev) + sizeof(*ev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 844) if (params->bssid) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 845) ev->cr.bssid = next;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 846) memcpy((void *)ev->cr.bssid, params->bssid, ETH_ALEN);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 847) next += ETH_ALEN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 848) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 849) if (params->req_ie_len) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 850) ev->cr.req_ie = next;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 851) ev->cr.req_ie_len = params->req_ie_len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 852) memcpy((void *)ev->cr.req_ie, params->req_ie,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 853) params->req_ie_len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 854) next += params->req_ie_len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 855) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 856) if (params->resp_ie_len) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 857) ev->cr.resp_ie = next;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 858) ev->cr.resp_ie_len = params->resp_ie_len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 859) memcpy((void *)ev->cr.resp_ie, params->resp_ie,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 860) params->resp_ie_len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 861) next += params->resp_ie_len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 862) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 863) if (params->fils.kek_len) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 864) ev->cr.fils.kek = next;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 865) ev->cr.fils.kek_len = params->fils.kek_len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 866) memcpy((void *)ev->cr.fils.kek, params->fils.kek,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 867) params->fils.kek_len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 868) next += params->fils.kek_len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 869) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 870) if (params->fils.pmk_len) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 871) ev->cr.fils.pmk = next;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 872) ev->cr.fils.pmk_len = params->fils.pmk_len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 873) memcpy((void *)ev->cr.fils.pmk, params->fils.pmk,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 874) params->fils.pmk_len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 875) next += params->fils.pmk_len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 876) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 877) if (params->fils.pmkid) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 878) ev->cr.fils.pmkid = next;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 879) memcpy((void *)ev->cr.fils.pmkid, params->fils.pmkid,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 880) WLAN_PMKID_LEN);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 881) next += WLAN_PMKID_LEN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 882) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 883) ev->cr.fils.update_erp_next_seq_num = params->fils.update_erp_next_seq_num;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 884) if (params->fils.update_erp_next_seq_num)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 885) ev->cr.fils.erp_next_seq_num = params->fils.erp_next_seq_num;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 886) if (params->bss)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 887) cfg80211_hold_bss(bss_from_pub(params->bss));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 888) ev->cr.bss = params->bss;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 889) ev->cr.status = params->status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 890) ev->cr.timeout_reason = params->timeout_reason;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 891)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 892) spin_lock_irqsave(&wdev->event_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 893) list_add_tail(&ev->list, &wdev->event_list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 894) spin_unlock_irqrestore(&wdev->event_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 895) queue_work(cfg80211_wq, &rdev->event_work);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 896) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 897) EXPORT_SYMBOL(cfg80211_connect_done);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 898)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 899) /* Consumes bss object one way or another */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 900) void __cfg80211_roamed(struct wireless_dev *wdev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 901) struct cfg80211_roam_info *info)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 902) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 903) #ifdef CONFIG_CFG80211_WEXT
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 904) union iwreq_data wrqu;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 905) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 906) ASSERT_WDEV_LOCK(wdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 907)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 908) if (WARN_ON(wdev->iftype != NL80211_IFTYPE_STATION &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 909) wdev->iftype != NL80211_IFTYPE_P2P_CLIENT))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 910) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 911)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 912) if (WARN_ON(!wdev->current_bss))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 913) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 914)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 915) cfg80211_unhold_bss(wdev->current_bss);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 916) cfg80211_put_bss(wdev->wiphy, &wdev->current_bss->pub);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 917) wdev->current_bss = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 918)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 919) if (WARN_ON(!info->bss))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 920) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 921)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 922) cfg80211_hold_bss(bss_from_pub(info->bss));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 923) wdev->current_bss = bss_from_pub(info->bss);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 924)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 925) wdev->unprot_beacon_reported = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 926) nl80211_send_roamed(wiphy_to_rdev(wdev->wiphy),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 927) wdev->netdev, info, GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 928)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 929) #ifdef CONFIG_CFG80211_WEXT
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 930) if (info->req_ie) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 931) memset(&wrqu, 0, sizeof(wrqu));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 932) wrqu.data.length = info->req_ie_len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 933) wireless_send_event(wdev->netdev, IWEVASSOCREQIE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 934) &wrqu, info->req_ie);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 935) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 936)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 937) if (info->resp_ie) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 938) memset(&wrqu, 0, sizeof(wrqu));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 939) wrqu.data.length = info->resp_ie_len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 940) wireless_send_event(wdev->netdev, IWEVASSOCRESPIE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 941) &wrqu, info->resp_ie);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 942) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 943)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 944) memset(&wrqu, 0, sizeof(wrqu));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 945) wrqu.ap_addr.sa_family = ARPHRD_ETHER;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 946) memcpy(wrqu.ap_addr.sa_data, info->bss->bssid, ETH_ALEN);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 947) memcpy(wdev->wext.prev_bssid, info->bss->bssid, ETH_ALEN);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 948) wdev->wext.prev_bssid_valid = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 949) wireless_send_event(wdev->netdev, SIOCGIWAP, &wrqu, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 950) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 951)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 952) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 953) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 954) cfg80211_put_bss(wdev->wiphy, info->bss);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 955) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 956)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 957) /* Consumes info->bss object one way or another */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 958) void cfg80211_roamed(struct net_device *dev, struct cfg80211_roam_info *info,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 959) gfp_t gfp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 960) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 961) struct wireless_dev *wdev = dev->ieee80211_ptr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 962) struct cfg80211_registered_device *rdev = wiphy_to_rdev(wdev->wiphy);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 963) struct cfg80211_event *ev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 964) unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 965) u8 *next;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 966)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 967) if (!info->bss) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 968) info->bss = cfg80211_get_bss(wdev->wiphy, info->channel,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 969) info->bssid, wdev->ssid,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 970) wdev->ssid_len,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 971) wdev->conn_bss_type,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 972) IEEE80211_PRIVACY_ANY);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 973) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 974)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 975) if (WARN_ON(!info->bss))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 976) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 977)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 978) ev = kzalloc(sizeof(*ev) + info->req_ie_len + info->resp_ie_len +
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 979) info->fils.kek_len + info->fils.pmk_len +
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 980) (info->fils.pmkid ? WLAN_PMKID_LEN : 0), gfp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 981) if (!ev) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 982) cfg80211_put_bss(wdev->wiphy, info->bss);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 983) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 984) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 985)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 986) ev->type = EVENT_ROAMED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 987) next = ((u8 *)ev) + sizeof(*ev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 988) if (info->req_ie_len) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 989) ev->rm.req_ie = next;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 990) ev->rm.req_ie_len = info->req_ie_len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 991) memcpy((void *)ev->rm.req_ie, info->req_ie, info->req_ie_len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 992) next += info->req_ie_len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 993) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 994) if (info->resp_ie_len) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 995) ev->rm.resp_ie = next;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 996) ev->rm.resp_ie_len = info->resp_ie_len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 997) memcpy((void *)ev->rm.resp_ie, info->resp_ie,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 998) info->resp_ie_len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 999) next += info->resp_ie_len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1000) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1001) if (info->fils.kek_len) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1002) ev->rm.fils.kek = next;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1003) ev->rm.fils.kek_len = info->fils.kek_len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1004) memcpy((void *)ev->rm.fils.kek, info->fils.kek,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1005) info->fils.kek_len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1006) next += info->fils.kek_len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1007) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1008) if (info->fils.pmk_len) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1009) ev->rm.fils.pmk = next;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1010) ev->rm.fils.pmk_len = info->fils.pmk_len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1011) memcpy((void *)ev->rm.fils.pmk, info->fils.pmk,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1012) info->fils.pmk_len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1013) next += info->fils.pmk_len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1014) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1015) if (info->fils.pmkid) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1016) ev->rm.fils.pmkid = next;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1017) memcpy((void *)ev->rm.fils.pmkid, info->fils.pmkid,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1018) WLAN_PMKID_LEN);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1019) next += WLAN_PMKID_LEN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1020) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1021) ev->rm.fils.update_erp_next_seq_num = info->fils.update_erp_next_seq_num;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1022) if (info->fils.update_erp_next_seq_num)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1023) ev->rm.fils.erp_next_seq_num = info->fils.erp_next_seq_num;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1024) ev->rm.bss = info->bss;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1025)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1026) spin_lock_irqsave(&wdev->event_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1027) list_add_tail(&ev->list, &wdev->event_list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1028) spin_unlock_irqrestore(&wdev->event_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1029) queue_work(cfg80211_wq, &rdev->event_work);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1030) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1031) EXPORT_SYMBOL(cfg80211_roamed);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1032)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1033) void __cfg80211_port_authorized(struct wireless_dev *wdev, const u8 *bssid)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1034) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1035) ASSERT_WDEV_LOCK(wdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1036)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1037) if (WARN_ON(wdev->iftype != NL80211_IFTYPE_STATION))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1038) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1039)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1040) if (WARN_ON(!wdev->current_bss) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1041) WARN_ON(!ether_addr_equal(wdev->current_bss->pub.bssid, bssid)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1042) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1043)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1044) nl80211_send_port_authorized(wiphy_to_rdev(wdev->wiphy), wdev->netdev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1045) bssid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1046) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1047)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1048) void cfg80211_port_authorized(struct net_device *dev, const u8 *bssid,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1049) gfp_t gfp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1050) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1051) struct wireless_dev *wdev = dev->ieee80211_ptr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1052) struct cfg80211_registered_device *rdev = wiphy_to_rdev(wdev->wiphy);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1053) struct cfg80211_event *ev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1054) unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1055)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1056) if (WARN_ON(!bssid))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1057) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1058)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1059) ev = kzalloc(sizeof(*ev), gfp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1060) if (!ev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1061) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1062)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1063) ev->type = EVENT_PORT_AUTHORIZED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1064) memcpy(ev->pa.bssid, bssid, ETH_ALEN);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1065)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1066) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1067) * Use the wdev event list so that if there are pending
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1068) * connected/roamed events, they will be reported first.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1069) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1070) spin_lock_irqsave(&wdev->event_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1071) list_add_tail(&ev->list, &wdev->event_list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1072) spin_unlock_irqrestore(&wdev->event_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1073) queue_work(cfg80211_wq, &rdev->event_work);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1074) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1075) EXPORT_SYMBOL(cfg80211_port_authorized);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1076)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1077) void __cfg80211_disconnected(struct net_device *dev, const u8 *ie,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1078) size_t ie_len, u16 reason, bool from_ap)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1079) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1080) struct wireless_dev *wdev = dev->ieee80211_ptr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1081) struct cfg80211_registered_device *rdev = wiphy_to_rdev(wdev->wiphy);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1082) int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1083) #ifdef CONFIG_CFG80211_WEXT
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1084) union iwreq_data wrqu;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1085) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1086)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1087) ASSERT_WDEV_LOCK(wdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1088)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1089) if (WARN_ON(wdev->iftype != NL80211_IFTYPE_STATION &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1090) wdev->iftype != NL80211_IFTYPE_P2P_CLIENT))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1091) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1092)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1093) if (wdev->current_bss) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1094) cfg80211_unhold_bss(wdev->current_bss);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1095) cfg80211_put_bss(wdev->wiphy, &wdev->current_bss->pub);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1096) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1097)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1098) wdev->current_bss = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1099) wdev->ssid_len = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1100) wdev->conn_owner_nlportid = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1101) kfree_sensitive(wdev->connect_keys);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1102) wdev->connect_keys = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1103)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1104) nl80211_send_disconnected(rdev, dev, reason, ie, ie_len, from_ap);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1105)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1106) /* stop critical protocol if supported */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1107) if (rdev->ops->crit_proto_stop && rdev->crit_proto_nlportid) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1108) rdev->crit_proto_nlportid = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1109) rdev_crit_proto_stop(rdev, wdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1110) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1111)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1112) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1113) * Delete all the keys ... pairwise keys can't really
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1114) * exist any more anyway, but default keys might.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1115) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1116) if (rdev->ops->del_key) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1117) int max_key_idx = 5;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1118)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1119) if (wiphy_ext_feature_isset(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1120) wdev->wiphy,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1121) NL80211_EXT_FEATURE_BEACON_PROTECTION) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1122) wiphy_ext_feature_isset(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1123) wdev->wiphy,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1124) NL80211_EXT_FEATURE_BEACON_PROTECTION_CLIENT))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1125) max_key_idx = 7;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1126) for (i = 0; i <= max_key_idx; i++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1127) rdev_del_key(rdev, dev, i, false, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1128) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1129)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1130) rdev_set_qos_map(rdev, dev, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1131)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1132) #ifdef CONFIG_CFG80211_WEXT
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1133) memset(&wrqu, 0, sizeof(wrqu));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1134) wrqu.ap_addr.sa_family = ARPHRD_ETHER;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1135) wireless_send_event(dev, SIOCGIWAP, &wrqu, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1136) wdev->wext.connect.ssid_len = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1137) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1138)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1139) schedule_work(&cfg80211_disconnect_work);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1140) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1141)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1142) void cfg80211_disconnected(struct net_device *dev, u16 reason,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1143) const u8 *ie, size_t ie_len,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1144) bool locally_generated, gfp_t gfp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1145) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1146) struct wireless_dev *wdev = dev->ieee80211_ptr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1147) struct cfg80211_registered_device *rdev = wiphy_to_rdev(wdev->wiphy);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1148) struct cfg80211_event *ev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1149) unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1150)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1151) ev = kzalloc(sizeof(*ev) + ie_len, gfp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1152) if (!ev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1153) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1154)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1155) ev->type = EVENT_DISCONNECTED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1156) ev->dc.ie = ((u8 *)ev) + sizeof(*ev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1157) ev->dc.ie_len = ie_len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1158) memcpy((void *)ev->dc.ie, ie, ie_len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1159) ev->dc.reason = reason;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1160) ev->dc.locally_generated = locally_generated;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1161)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1162) spin_lock_irqsave(&wdev->event_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1163) list_add_tail(&ev->list, &wdev->event_list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1164) spin_unlock_irqrestore(&wdev->event_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1165) queue_work(cfg80211_wq, &rdev->event_work);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1166) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1167) EXPORT_SYMBOL(cfg80211_disconnected);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1168)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1169) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1170) * API calls for nl80211/wext compatibility code
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1171) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1172) int cfg80211_connect(struct cfg80211_registered_device *rdev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1173) struct net_device *dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1174) struct cfg80211_connect_params *connect,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1175) struct cfg80211_cached_keys *connkeys,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1176) const u8 *prev_bssid)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1177) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1178) struct wireless_dev *wdev = dev->ieee80211_ptr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1179) int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1180)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1181) ASSERT_WDEV_LOCK(wdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1182)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1183) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1184) * If we have an ssid_len, we're trying to connect or are
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1185) * already connected, so reject a new SSID unless it's the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1186) * same (which is the case for re-association.)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1187) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1188) if (wdev->ssid_len &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1189) (wdev->ssid_len != connect->ssid_len ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1190) memcmp(wdev->ssid, connect->ssid, wdev->ssid_len)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1191) return -EALREADY;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1192)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1193) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1194) * If connected, reject (re-)association unless prev_bssid
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1195) * matches the current BSSID.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1196) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1197) if (wdev->current_bss) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1198) if (!prev_bssid)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1199) return -EALREADY;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1200) if (!ether_addr_equal(prev_bssid, wdev->current_bss->pub.bssid))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1201) return -ENOTCONN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1202) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1203)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1204) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1205) * Reject if we're in the process of connecting with WEP,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1206) * this case isn't very interesting and trying to handle
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1207) * it would make the code much more complex.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1208) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1209) if (wdev->connect_keys)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1210) return -EINPROGRESS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1211)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1212) cfg80211_oper_and_ht_capa(&connect->ht_capa_mask,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1213) rdev->wiphy.ht_capa_mod_mask);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1214) cfg80211_oper_and_vht_capa(&connect->vht_capa_mask,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1215) rdev->wiphy.vht_capa_mod_mask);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1216)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1217) if (connkeys && connkeys->def >= 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1218) int idx;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1219) u32 cipher;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1220)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1221) idx = connkeys->def;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1222) cipher = connkeys->params[idx].cipher;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1223) /* If given a WEP key we may need it for shared key auth */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1224) if (cipher == WLAN_CIPHER_SUITE_WEP40 ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1225) cipher == WLAN_CIPHER_SUITE_WEP104) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1226) connect->key_idx = idx;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1227) connect->key = connkeys->params[idx].key;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1228) connect->key_len = connkeys->params[idx].key_len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1229)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1230) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1231) * If ciphers are not set (e.g. when going through
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1232) * iwconfig), we have to set them appropriately here.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1233) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1234) if (connect->crypto.cipher_group == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1235) connect->crypto.cipher_group = cipher;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1236)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1237) if (connect->crypto.n_ciphers_pairwise == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1238) connect->crypto.n_ciphers_pairwise = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1239) connect->crypto.ciphers_pairwise[0] = cipher;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1240) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1241) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1242)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1243) connect->crypto.wep_keys = connkeys->params;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1244) connect->crypto.wep_tx_key = connkeys->def;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1245) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1246) if (WARN_ON(connkeys))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1247) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1248) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1249)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1250) wdev->connect_keys = connkeys;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1251) memcpy(wdev->ssid, connect->ssid, connect->ssid_len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1252) wdev->ssid_len = connect->ssid_len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1253)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1254) wdev->conn_bss_type = connect->pbss ? IEEE80211_BSS_TYPE_PBSS :
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1255) IEEE80211_BSS_TYPE_ESS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1256)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1257) if (!rdev->ops->connect)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1258) err = cfg80211_sme_connect(wdev, connect, prev_bssid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1259) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1260) err = rdev_connect(rdev, dev, connect);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1261)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1262) if (err) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1263) wdev->connect_keys = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1264) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1265) * This could be reassoc getting refused, don't clear
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1266) * ssid_len in that case.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1267) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1268) if (!wdev->current_bss)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1269) wdev->ssid_len = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1270) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1271) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1272)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1273) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1274) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1275)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1276) int cfg80211_disconnect(struct cfg80211_registered_device *rdev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1277) struct net_device *dev, u16 reason, bool wextev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1278) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1279) struct wireless_dev *wdev = dev->ieee80211_ptr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1280) int err = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1281)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1282) ASSERT_WDEV_LOCK(wdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1283)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1284) kfree_sensitive(wdev->connect_keys);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1285) wdev->connect_keys = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1286)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1287) wdev->conn_owner_nlportid = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1288)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1289) if (wdev->conn)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1290) err = cfg80211_sme_disconnect(wdev, reason);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1291) else if (!rdev->ops->disconnect)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1292) cfg80211_mlme_down(rdev, dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1293) else if (wdev->ssid_len)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1294) err = rdev_disconnect(rdev, dev, reason);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1295)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1296) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1297) * Clear ssid_len unless we actually were fully connected,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1298) * in which case cfg80211_disconnected() will take care of
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1299) * this later.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1300) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1301) if (!wdev->current_bss)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1302) wdev->ssid_len = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1303)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1304) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1305) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1306)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1307) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1308) * Used to clean up after the connection / connection attempt owner socket
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1309) * disconnects
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1310) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1311) void cfg80211_autodisconnect_wk(struct work_struct *work)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1312) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1313) struct wireless_dev *wdev =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1314) container_of(work, struct wireless_dev, disconnect_wk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1315) struct cfg80211_registered_device *rdev = wiphy_to_rdev(wdev->wiphy);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1316)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1317) wdev_lock(wdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1318)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1319) if (wdev->conn_owner_nlportid) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1320) switch (wdev->iftype) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1321) case NL80211_IFTYPE_ADHOC:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1322) __cfg80211_leave_ibss(rdev, wdev->netdev, false);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1323) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1324) case NL80211_IFTYPE_AP:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1325) case NL80211_IFTYPE_P2P_GO:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1326) __cfg80211_stop_ap(rdev, wdev->netdev, false);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1327) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1328) case NL80211_IFTYPE_MESH_POINT:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1329) __cfg80211_leave_mesh(rdev, wdev->netdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1330) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1331) case NL80211_IFTYPE_STATION:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1332) case NL80211_IFTYPE_P2P_CLIENT:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1333) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1334) * Use disconnect_bssid if still connecting and
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1335) * ops->disconnect not implemented. Otherwise we can
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1336) * use cfg80211_disconnect.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1337) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1338) if (rdev->ops->disconnect || wdev->current_bss)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1339) cfg80211_disconnect(rdev, wdev->netdev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1340) WLAN_REASON_DEAUTH_LEAVING,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1341) true);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1342) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1343) cfg80211_mlme_deauth(rdev, wdev->netdev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1344) wdev->disconnect_bssid,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1345) NULL, 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1346) WLAN_REASON_DEAUTH_LEAVING,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1347) false);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1348) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1349) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1350) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1351) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1352) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1353)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1354) wdev_unlock(wdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1355) }