cfg80211: Use a structure to pass connect response params
Currently the connect event from driver takes all the connection response parameters as arguments. With support for new features these response parameters can grow. Use a structure to pass these parameters rather than passing them as function arguments. Signed-off-by: Vidyullatha Kanchanapally <vkanchan@qti.qualcomm.com> Signed-off-by: Jouni Malinen <jouni@qca.qualcomm.com> [add to documentation] Signed-off-by: Johannes Berg <johannes.berg@intel.com>
This commit is contained in:
parent
667a2e6bfe
commit
5349a0f7bf
|
@ -179,6 +179,12 @@ Actions and configuration
|
|||
.. kernel-doc:: include/net/cfg80211.h
|
||||
:functions: cfg80211_ibss_joined
|
||||
|
||||
.. kernel-doc:: include/net/cfg80211.h
|
||||
:functions: cfg80211_connect_resp_params
|
||||
|
||||
.. kernel-doc:: include/net/cfg80211.h
|
||||
:functions: cfg80211_connect_done
|
||||
|
||||
.. kernel-doc:: include/net/cfg80211.h
|
||||
:functions: cfg80211_connect_result
|
||||
|
||||
|
|
|
@ -5135,6 +5135,60 @@ static inline void cfg80211_testmode_event(struct sk_buff *skb, gfp_t gfp)
|
|||
#define CFG80211_TESTMODE_DUMP(cmd)
|
||||
#endif
|
||||
|
||||
/**
|
||||
* struct cfg80211_connect_resp_params - Connection response params
|
||||
* @status: Status code, %WLAN_STATUS_SUCCESS for successful connection, use
|
||||
* %WLAN_STATUS_UNSPECIFIED_FAILURE if your device cannot give you
|
||||
* the real status code for failures. If this call is used to report a
|
||||
* failure due to a timeout (e.g., not receiving an Authentication frame
|
||||
* from the AP) instead of an explicit rejection by the AP, -1 is used to
|
||||
* indicate that this is a failure, but without a status code.
|
||||
* @timeout_reason is used to report the reason for the timeout in that
|
||||
* case.
|
||||
* @bssid: The BSSID of the AP (may be %NULL)
|
||||
* @bss: Entry of bss to which STA got connected to, can be obtained through
|
||||
* cfg80211_get_bss() (may be %NULL). Only one parameter among @bssid and
|
||||
* @bss needs to be specified.
|
||||
* @req_ie: Association request IEs (may be %NULL)
|
||||
* @req_ie_len: Association request IEs length
|
||||
* @resp_ie: Association response IEs (may be %NULL)
|
||||
* @resp_ie_len: Association response IEs length
|
||||
* @timeout_reason: Reason for connection timeout. This is used when the
|
||||
* connection fails due to a timeout instead of an explicit rejection from
|
||||
* the AP. %NL80211_TIMEOUT_UNSPECIFIED is used when the timeout reason is
|
||||
* not known. This value is used only if @status < 0 to indicate that the
|
||||
* failure is due to a timeout and not due to explicit rejection by the AP.
|
||||
* This value is ignored in other cases (@status >= 0).
|
||||
*/
|
||||
struct cfg80211_connect_resp_params {
|
||||
int status;
|
||||
const u8 *bssid;
|
||||
struct cfg80211_bss *bss;
|
||||
const u8 *req_ie;
|
||||
size_t req_ie_len;
|
||||
const u8 *resp_ie;
|
||||
size_t resp_ie_len;
|
||||
enum nl80211_timeout_reason timeout_reason;
|
||||
};
|
||||
|
||||
/**
|
||||
* cfg80211_connect_done - notify cfg80211 of connection result
|
||||
*
|
||||
* @dev: network device
|
||||
* @params: connection response parameters
|
||||
* @gfp: allocation flags
|
||||
*
|
||||
* It should be called by the underlying driver once execution of the connection
|
||||
* request from connect() has been completed. This is similar to
|
||||
* cfg80211_connect_bss(), but takes a structure pointer for connection response
|
||||
* parameters. Only one of the functions among cfg80211_connect_bss(),
|
||||
* cfg80211_connect_result(), cfg80211_connect_timeout(),
|
||||
* and cfg80211_connect_done() should be called.
|
||||
*/
|
||||
void cfg80211_connect_done(struct net_device *dev,
|
||||
struct cfg80211_connect_resp_params *params,
|
||||
gfp_t gfp);
|
||||
|
||||
/**
|
||||
* cfg80211_connect_bss - notify cfg80211 of connection result
|
||||
*
|
||||
|
@ -5165,13 +5219,31 @@ static inline void cfg80211_testmode_event(struct sk_buff *skb, gfp_t gfp)
|
|||
* It should be called by the underlying driver once execution of the connection
|
||||
* request from connect() has been completed. This is similar to
|
||||
* cfg80211_connect_result(), but with the option of identifying the exact bss
|
||||
* entry for the connection. Only one of these functions should be called.
|
||||
* entry for the connection. Only one of the functions among
|
||||
* cfg80211_connect_bss(), cfg80211_connect_result(),
|
||||
* cfg80211_connect_timeout(), and cfg80211_connect_done() should be called.
|
||||
*/
|
||||
void cfg80211_connect_bss(struct net_device *dev, const u8 *bssid,
|
||||
struct cfg80211_bss *bss, const u8 *req_ie,
|
||||
size_t req_ie_len, const u8 *resp_ie,
|
||||
size_t resp_ie_len, int status, gfp_t gfp,
|
||||
enum nl80211_timeout_reason timeout_reason);
|
||||
static inline void
|
||||
cfg80211_connect_bss(struct net_device *dev, const u8 *bssid,
|
||||
struct cfg80211_bss *bss, const u8 *req_ie,
|
||||
size_t req_ie_len, const u8 *resp_ie,
|
||||
size_t resp_ie_len, int status, gfp_t gfp,
|
||||
enum nl80211_timeout_reason timeout_reason)
|
||||
{
|
||||
struct cfg80211_connect_resp_params params;
|
||||
|
||||
memset(¶ms, 0, sizeof(params));
|
||||
params.status = status;
|
||||
params.bssid = bssid;
|
||||
params.bss = bss;
|
||||
params.req_ie = req_ie;
|
||||
params.req_ie_len = req_ie_len;
|
||||
params.resp_ie = resp_ie;
|
||||
params.resp_ie_len = resp_ie_len;
|
||||
params.timeout_reason = timeout_reason;
|
||||
|
||||
cfg80211_connect_done(dev, ¶ms, gfp);
|
||||
}
|
||||
|
||||
/**
|
||||
* cfg80211_connect_result - notify cfg80211 of connection result
|
||||
|
@ -5190,7 +5262,8 @@ void cfg80211_connect_bss(struct net_device *dev, const u8 *bssid,
|
|||
* It should be called by the underlying driver once execution of the connection
|
||||
* request from connect() has been completed. This is similar to
|
||||
* cfg80211_connect_bss() which allows the exact bss entry to be specified. Only
|
||||
* one of these functions should be called.
|
||||
* one of the functions among cfg80211_connect_bss(), cfg80211_connect_result(),
|
||||
* cfg80211_connect_timeout(), and cfg80211_connect_done() should be called.
|
||||
*/
|
||||
static inline void
|
||||
cfg80211_connect_result(struct net_device *dev, const u8 *bssid,
|
||||
|
@ -5217,7 +5290,9 @@ cfg80211_connect_result(struct net_device *dev, const u8 *bssid,
|
|||
* in a sequence where no explicit authentication/association rejection was
|
||||
* received from the AP. This could happen, e.g., due to not being able to send
|
||||
* out the Authentication or Association Request frame or timing out while
|
||||
* waiting for the response.
|
||||
* waiting for the response. Only one of the functions among
|
||||
* cfg80211_connect_bss(), cfg80211_connect_result(),
|
||||
* cfg80211_connect_timeout(), and cfg80211_connect_done() should be called.
|
||||
*/
|
||||
static inline void
|
||||
cfg80211_connect_timeout(struct net_device *dev, const u8 *bssid,
|
||||
|
|
|
@ -226,16 +226,7 @@ struct cfg80211_event {
|
|||
enum cfg80211_event_type type;
|
||||
|
||||
union {
|
||||
struct {
|
||||
u8 bssid[ETH_ALEN];
|
||||
const u8 *req_ie;
|
||||
const u8 *resp_ie;
|
||||
size_t req_ie_len;
|
||||
size_t resp_ie_len;
|
||||
struct cfg80211_bss *bss;
|
||||
int status; /* -1 = failed; 0..65535 = status code */
|
||||
enum nl80211_timeout_reason timeout_reason;
|
||||
} cr;
|
||||
struct cfg80211_connect_resp_params cr;
|
||||
struct {
|
||||
const u8 *req_ie;
|
||||
const u8 *resp_ie;
|
||||
|
@ -398,12 +389,9 @@ int cfg80211_connect(struct cfg80211_registered_device *rdev,
|
|||
struct cfg80211_connect_params *connect,
|
||||
struct cfg80211_cached_keys *connkeys,
|
||||
const u8 *prev_bssid);
|
||||
void __cfg80211_connect_result(struct net_device *dev, const u8 *bssid,
|
||||
const u8 *req_ie, size_t req_ie_len,
|
||||
const u8 *resp_ie, size_t resp_ie_len,
|
||||
int status, bool wextev,
|
||||
struct cfg80211_bss *bss,
|
||||
enum nl80211_timeout_reason timeout_reason);
|
||||
void __cfg80211_connect_result(struct net_device *dev,
|
||||
struct cfg80211_connect_resp_params *params,
|
||||
bool wextev);
|
||||
void __cfg80211_disconnected(struct net_device *dev, const u8 *ie,
|
||||
size_t ie_len, u16 reason, bool from_ap);
|
||||
int cfg80211_disconnect(struct cfg80211_registered_device *rdev,
|
||||
|
|
|
@ -26,9 +26,16 @@ void cfg80211_rx_assoc_resp(struct net_device *dev, struct cfg80211_bss *bss,
|
|||
struct wiphy *wiphy = wdev->wiphy;
|
||||
struct cfg80211_registered_device *rdev = wiphy_to_rdev(wiphy);
|
||||
struct ieee80211_mgmt *mgmt = (struct ieee80211_mgmt *)buf;
|
||||
u8 *ie = mgmt->u.assoc_resp.variable;
|
||||
int ieoffs = offsetof(struct ieee80211_mgmt, u.assoc_resp.variable);
|
||||
u16 status_code = le16_to_cpu(mgmt->u.assoc_resp.status_code);
|
||||
struct cfg80211_connect_resp_params cr;
|
||||
|
||||
memset(&cr, 0, sizeof(cr));
|
||||
cr.status = (int)le16_to_cpu(mgmt->u.assoc_resp.status_code);
|
||||
cr.bssid = mgmt->bssid;
|
||||
cr.bss = bss;
|
||||
cr.resp_ie = mgmt->u.assoc_resp.variable;
|
||||
cr.resp_ie_len =
|
||||
len - offsetof(struct ieee80211_mgmt, u.assoc_resp.variable);
|
||||
cr.timeout_reason = NL80211_TIMEOUT_UNSPECIFIED;
|
||||
|
||||
trace_cfg80211_send_rx_assoc(dev, bss);
|
||||
|
||||
|
@ -38,7 +45,7 @@ void cfg80211_rx_assoc_resp(struct net_device *dev, struct cfg80211_bss *bss,
|
|||
* and got a reject -- we only try again with an assoc
|
||||
* frame instead of reassoc.
|
||||
*/
|
||||
if (cfg80211_sme_rx_assoc_resp(wdev, status_code)) {
|
||||
if (cfg80211_sme_rx_assoc_resp(wdev, cr.status)) {
|
||||
cfg80211_unhold_bss(bss_from_pub(bss));
|
||||
cfg80211_put_bss(wiphy, bss);
|
||||
return;
|
||||
|
@ -46,10 +53,7 @@ void cfg80211_rx_assoc_resp(struct net_device *dev, struct cfg80211_bss *bss,
|
|||
|
||||
nl80211_send_rx_assoc(rdev, dev, buf, len, GFP_KERNEL, uapsd_queues);
|
||||
/* update current_bss etc., consumes the bss reference */
|
||||
__cfg80211_connect_result(dev, mgmt->bssid, NULL, 0, ie, len - ieoffs,
|
||||
status_code,
|
||||
status_code == WLAN_STATUS_SUCCESS, bss,
|
||||
NL80211_TIMEOUT_UNSPECIFIED);
|
||||
__cfg80211_connect_result(dev, &cr, cr.status == WLAN_STATUS_SUCCESS);
|
||||
}
|
||||
EXPORT_SYMBOL(cfg80211_rx_assoc_resp);
|
||||
|
||||
|
|
|
@ -13464,17 +13464,14 @@ void nl80211_send_assoc_timeout(struct cfg80211_registered_device *rdev,
|
|||
}
|
||||
|
||||
void nl80211_send_connect_result(struct cfg80211_registered_device *rdev,
|
||||
struct net_device *netdev, const u8 *bssid,
|
||||
const u8 *req_ie, size_t req_ie_len,
|
||||
const u8 *resp_ie, size_t resp_ie_len,
|
||||
int status,
|
||||
enum nl80211_timeout_reason timeout_reason,
|
||||
struct net_device *netdev,
|
||||
struct cfg80211_connect_resp_params *cr,
|
||||
gfp_t gfp)
|
||||
{
|
||||
struct sk_buff *msg;
|
||||
void *hdr;
|
||||
|
||||
msg = nlmsg_new(100 + req_ie_len + resp_ie_len, gfp);
|
||||
msg = nlmsg_new(100 + cr->req_ie_len + cr->resp_ie_len, gfp);
|
||||
if (!msg)
|
||||
return;
|
||||
|
||||
|
@ -13486,17 +13483,20 @@ void nl80211_send_connect_result(struct cfg80211_registered_device *rdev,
|
|||
|
||||
if (nla_put_u32(msg, NL80211_ATTR_WIPHY, rdev->wiphy_idx) ||
|
||||
nla_put_u32(msg, NL80211_ATTR_IFINDEX, netdev->ifindex) ||
|
||||
(bssid && nla_put(msg, NL80211_ATTR_MAC, ETH_ALEN, bssid)) ||
|
||||
(cr->bssid &&
|
||||
nla_put(msg, NL80211_ATTR_MAC, ETH_ALEN, cr->bssid)) ||
|
||||
nla_put_u16(msg, NL80211_ATTR_STATUS_CODE,
|
||||
status < 0 ? WLAN_STATUS_UNSPECIFIED_FAILURE :
|
||||
status) ||
|
||||
(status < 0 &&
|
||||
cr->status < 0 ? WLAN_STATUS_UNSPECIFIED_FAILURE :
|
||||
cr->status) ||
|
||||
(cr->status < 0 &&
|
||||
(nla_put_flag(msg, NL80211_ATTR_TIMED_OUT) ||
|
||||
nla_put_u32(msg, NL80211_ATTR_TIMEOUT_REASON, timeout_reason))) ||
|
||||
(req_ie &&
|
||||
nla_put(msg, NL80211_ATTR_REQ_IE, req_ie_len, req_ie)) ||
|
||||
(resp_ie &&
|
||||
nla_put(msg, NL80211_ATTR_RESP_IE, resp_ie_len, resp_ie)))
|
||||
nla_put_u32(msg, NL80211_ATTR_TIMEOUT_REASON,
|
||||
cr->timeout_reason))) ||
|
||||
(cr->req_ie &&
|
||||
nla_put(msg, NL80211_ATTR_REQ_IE, cr->req_ie_len, cr->req_ie)) ||
|
||||
(cr->resp_ie &&
|
||||
nla_put(msg, NL80211_ATTR_RESP_IE, cr->resp_ie_len,
|
||||
cr->resp_ie)))
|
||||
goto nla_put_failure;
|
||||
|
||||
genlmsg_end(msg, hdr);
|
||||
|
|
|
@ -53,11 +53,8 @@ void nl80211_send_assoc_timeout(struct cfg80211_registered_device *rdev,
|
|||
struct net_device *netdev,
|
||||
const u8 *addr, gfp_t gfp);
|
||||
void nl80211_send_connect_result(struct cfg80211_registered_device *rdev,
|
||||
struct net_device *netdev, const u8 *bssid,
|
||||
const u8 *req_ie, size_t req_ie_len,
|
||||
const u8 *resp_ie, size_t resp_ie_len,
|
||||
int status,
|
||||
enum nl80211_timeout_reason timeout_reason,
|
||||
struct net_device *netdev,
|
||||
struct cfg80211_connect_resp_params *params,
|
||||
gfp_t gfp);
|
||||
void nl80211_send_roamed(struct cfg80211_registered_device *rdev,
|
||||
struct net_device *netdev, const u8 *bssid,
|
||||
|
|
|
@ -253,10 +253,13 @@ void cfg80211_conn_work(struct work_struct *work)
|
|||
}
|
||||
treason = NL80211_TIMEOUT_UNSPECIFIED;
|
||||
if (cfg80211_conn_do_work(wdev, &treason)) {
|
||||
__cfg80211_connect_result(
|
||||
wdev->netdev, bssid,
|
||||
NULL, 0, NULL, 0, -1, false, NULL,
|
||||
treason);
|
||||
struct cfg80211_connect_resp_params cr;
|
||||
|
||||
memset(&cr, 0, sizeof(cr));
|
||||
cr.status = -1;
|
||||
cr.bssid = bssid;
|
||||
cr.timeout_reason = treason;
|
||||
__cfg80211_connect_result(wdev->netdev, &cr, false);
|
||||
}
|
||||
wdev_unlock(wdev);
|
||||
}
|
||||
|
@ -359,10 +362,13 @@ void cfg80211_sme_rx_auth(struct wireless_dev *wdev, const u8 *buf, size_t len)
|
|||
wdev->conn->state = CFG80211_CONN_AUTHENTICATE_NEXT;
|
||||
schedule_work(&rdev->conn_work);
|
||||
} else if (status_code != WLAN_STATUS_SUCCESS) {
|
||||
__cfg80211_connect_result(wdev->netdev, mgmt->bssid,
|
||||
NULL, 0, NULL, 0,
|
||||
status_code, false, NULL,
|
||||
NL80211_TIMEOUT_UNSPECIFIED);
|
||||
struct cfg80211_connect_resp_params cr;
|
||||
|
||||
memset(&cr, 0, sizeof(cr));
|
||||
cr.status = status_code;
|
||||
cr.bssid = mgmt->bssid;
|
||||
cr.timeout_reason = NL80211_TIMEOUT_UNSPECIFIED;
|
||||
__cfg80211_connect_result(wdev->netdev, &cr, false);
|
||||
} else if (wdev->conn->state == CFG80211_CONN_AUTHENTICATING) {
|
||||
wdev->conn->state = CFG80211_CONN_ASSOCIATE_NEXT;
|
||||
schedule_work(&rdev->conn_work);
|
||||
|
@ -669,12 +675,9 @@ static DECLARE_WORK(cfg80211_disconnect_work, disconnect_work);
|
|||
*/
|
||||
|
||||
/* This method must consume bss one way or another */
|
||||
void __cfg80211_connect_result(struct net_device *dev, const u8 *bssid,
|
||||
const u8 *req_ie, size_t req_ie_len,
|
||||
const u8 *resp_ie, size_t resp_ie_len,
|
||||
int status, bool wextev,
|
||||
struct cfg80211_bss *bss,
|
||||
enum nl80211_timeout_reason timeout_reason)
|
||||
void __cfg80211_connect_result(struct net_device *dev,
|
||||
struct cfg80211_connect_resp_params *cr,
|
||||
bool wextev)
|
||||
{
|
||||
struct wireless_dev *wdev = dev->ieee80211_ptr;
|
||||
const u8 *country_ie;
|
||||
|
@ -686,48 +689,48 @@ void __cfg80211_connect_result(struct net_device *dev, const u8 *bssid,
|
|||
|
||||
if (WARN_ON(wdev->iftype != NL80211_IFTYPE_STATION &&
|
||||
wdev->iftype != NL80211_IFTYPE_P2P_CLIENT)) {
|
||||
cfg80211_put_bss(wdev->wiphy, bss);
|
||||
cfg80211_put_bss(wdev->wiphy, cr->bss);
|
||||
return;
|
||||
}
|
||||
|
||||
nl80211_send_connect_result(wiphy_to_rdev(wdev->wiphy), dev,
|
||||
bssid, req_ie, req_ie_len,
|
||||
resp_ie, resp_ie_len,
|
||||
status, timeout_reason, GFP_KERNEL);
|
||||
nl80211_send_connect_result(wiphy_to_rdev(wdev->wiphy), dev, cr,
|
||||
GFP_KERNEL);
|
||||
|
||||
#ifdef CONFIG_CFG80211_WEXT
|
||||
if (wextev) {
|
||||
if (req_ie && status == WLAN_STATUS_SUCCESS) {
|
||||
if (cr->req_ie && cr->status == WLAN_STATUS_SUCCESS) {
|
||||
memset(&wrqu, 0, sizeof(wrqu));
|
||||
wrqu.data.length = req_ie_len;
|
||||
wireless_send_event(dev, IWEVASSOCREQIE, &wrqu, req_ie);
|
||||
wrqu.data.length = cr->req_ie_len;
|
||||
wireless_send_event(dev, IWEVASSOCREQIE, &wrqu,
|
||||
cr->req_ie);
|
||||
}
|
||||
|
||||
if (resp_ie && status == WLAN_STATUS_SUCCESS) {
|
||||
if (cr->resp_ie && cr->status == WLAN_STATUS_SUCCESS) {
|
||||
memset(&wrqu, 0, sizeof(wrqu));
|
||||
wrqu.data.length = resp_ie_len;
|
||||
wireless_send_event(dev, IWEVASSOCRESPIE, &wrqu, resp_ie);
|
||||
wrqu.data.length = cr->resp_ie_len;
|
||||
wireless_send_event(dev, IWEVASSOCRESPIE, &wrqu,
|
||||
cr->resp_ie);
|
||||
}
|
||||
|
||||
memset(&wrqu, 0, sizeof(wrqu));
|
||||
wrqu.ap_addr.sa_family = ARPHRD_ETHER;
|
||||
if (bssid && status == WLAN_STATUS_SUCCESS) {
|
||||
memcpy(wrqu.ap_addr.sa_data, bssid, ETH_ALEN);
|
||||
memcpy(wdev->wext.prev_bssid, bssid, ETH_ALEN);
|
||||
if (cr->bssid && cr->status == WLAN_STATUS_SUCCESS) {
|
||||
memcpy(wrqu.ap_addr.sa_data, cr->bssid, ETH_ALEN);
|
||||
memcpy(wdev->wext.prev_bssid, cr->bssid, ETH_ALEN);
|
||||
wdev->wext.prev_bssid_valid = true;
|
||||
}
|
||||
wireless_send_event(dev, SIOCGIWAP, &wrqu, NULL);
|
||||
}
|
||||
#endif
|
||||
|
||||
if (!bss && (status == WLAN_STATUS_SUCCESS)) {
|
||||
if (!cr->bss && (cr->status == WLAN_STATUS_SUCCESS)) {
|
||||
WARN_ON_ONCE(!wiphy_to_rdev(wdev->wiphy)->ops->connect);
|
||||
bss = cfg80211_get_bss(wdev->wiphy, NULL, bssid,
|
||||
wdev->ssid, wdev->ssid_len,
|
||||
wdev->conn_bss_type,
|
||||
IEEE80211_PRIVACY_ANY);
|
||||
if (bss)
|
||||
cfg80211_hold_bss(bss_from_pub(bss));
|
||||
cr->bss = cfg80211_get_bss(wdev->wiphy, NULL, cr->bssid,
|
||||
wdev->ssid, wdev->ssid_len,
|
||||
wdev->conn_bss_type,
|
||||
IEEE80211_PRIVACY_ANY);
|
||||
if (cr->bss)
|
||||
cfg80211_hold_bss(bss_from_pub(cr->bss));
|
||||
}
|
||||
|
||||
if (wdev->current_bss) {
|
||||
|
@ -736,29 +739,29 @@ void __cfg80211_connect_result(struct net_device *dev, const u8 *bssid,
|
|||
wdev->current_bss = NULL;
|
||||
}
|
||||
|
||||
if (status != WLAN_STATUS_SUCCESS) {
|
||||
if (cr->status != WLAN_STATUS_SUCCESS) {
|
||||
kzfree(wdev->connect_keys);
|
||||
wdev->connect_keys = NULL;
|
||||
wdev->ssid_len = 0;
|
||||
wdev->conn_owner_nlportid = 0;
|
||||
if (bss) {
|
||||
cfg80211_unhold_bss(bss_from_pub(bss));
|
||||
cfg80211_put_bss(wdev->wiphy, bss);
|
||||
if (cr->bss) {
|
||||
cfg80211_unhold_bss(bss_from_pub(cr->bss));
|
||||
cfg80211_put_bss(wdev->wiphy, cr->bss);
|
||||
}
|
||||
cfg80211_sme_free(wdev);
|
||||
return;
|
||||
}
|
||||
|
||||
if (WARN_ON(!bss))
|
||||
if (WARN_ON(!cr->bss))
|
||||
return;
|
||||
|
||||
wdev->current_bss = bss_from_pub(bss);
|
||||
wdev->current_bss = bss_from_pub(cr->bss);
|
||||
|
||||
if (!(wdev->wiphy->flags & WIPHY_FLAG_HAS_STATIC_WEP))
|
||||
cfg80211_upload_connect_keys(wdev);
|
||||
|
||||
rcu_read_lock();
|
||||
country_ie = ieee80211_bss_get_ie(bss, WLAN_EID_COUNTRY);
|
||||
country_ie = ieee80211_bss_get_ie(cr->bss, WLAN_EID_COUNTRY);
|
||||
if (!country_ie) {
|
||||
rcu_read_unlock();
|
||||
return;
|
||||
|
@ -775,64 +778,72 @@ void __cfg80211_connect_result(struct net_device *dev, const u8 *bssid,
|
|||
* - country_ie + 2, the start of the country ie data, and
|
||||
* - and country_ie[1] which is the IE length
|
||||
*/
|
||||
regulatory_hint_country_ie(wdev->wiphy, bss->channel->band,
|
||||
regulatory_hint_country_ie(wdev->wiphy, cr->bss->channel->band,
|
||||
country_ie + 2, country_ie[1]);
|
||||
kfree(country_ie);
|
||||
}
|
||||
|
||||
/* Consumes bss object one way or another */
|
||||
void cfg80211_connect_bss(struct net_device *dev, const u8 *bssid,
|
||||
struct cfg80211_bss *bss, const u8 *req_ie,
|
||||
size_t req_ie_len, const u8 *resp_ie,
|
||||
size_t resp_ie_len, int status, gfp_t gfp,
|
||||
enum nl80211_timeout_reason timeout_reason)
|
||||
void cfg80211_connect_done(struct net_device *dev,
|
||||
struct cfg80211_connect_resp_params *params,
|
||||
gfp_t gfp)
|
||||
{
|
||||
struct wireless_dev *wdev = dev->ieee80211_ptr;
|
||||
struct cfg80211_registered_device *rdev = wiphy_to_rdev(wdev->wiphy);
|
||||
struct cfg80211_event *ev;
|
||||
unsigned long flags;
|
||||
u8 *next;
|
||||
|
||||
if (bss) {
|
||||
if (params->bss) {
|
||||
/* Make sure the bss entry provided by the driver is valid. */
|
||||
struct cfg80211_internal_bss *ibss = bss_from_pub(bss);
|
||||
struct cfg80211_internal_bss *ibss = bss_from_pub(params->bss);
|
||||
|
||||
if (WARN_ON(list_empty(&ibss->list))) {
|
||||
cfg80211_put_bss(wdev->wiphy, bss);
|
||||
cfg80211_put_bss(wdev->wiphy, params->bss);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
ev = kzalloc(sizeof(*ev) + req_ie_len + resp_ie_len, gfp);
|
||||
ev = kzalloc(sizeof(*ev) + (params->bssid ? ETH_ALEN : 0) +
|
||||
params->req_ie_len + params->resp_ie_len, gfp);
|
||||
if (!ev) {
|
||||
cfg80211_put_bss(wdev->wiphy, bss);
|
||||
cfg80211_put_bss(wdev->wiphy, params->bss);
|
||||
return;
|
||||
}
|
||||
|
||||
ev->type = EVENT_CONNECT_RESULT;
|
||||
if (bssid)
|
||||
memcpy(ev->cr.bssid, bssid, ETH_ALEN);
|
||||
if (req_ie_len) {
|
||||
ev->cr.req_ie = ((u8 *)ev) + sizeof(*ev);
|
||||
ev->cr.req_ie_len = req_ie_len;
|
||||
memcpy((void *)ev->cr.req_ie, req_ie, req_ie_len);
|
||||
next = ((u8 *)ev) + sizeof(*ev);
|
||||
if (params->bssid) {
|
||||
ev->cr.bssid = next;
|
||||
memcpy((void *)ev->cr.bssid, params->bssid, ETH_ALEN);
|
||||
next += ETH_ALEN;
|
||||
}
|
||||
if (resp_ie_len) {
|
||||
ev->cr.resp_ie = ((u8 *)ev) + sizeof(*ev) + req_ie_len;
|
||||
ev->cr.resp_ie_len = resp_ie_len;
|
||||
memcpy((void *)ev->cr.resp_ie, resp_ie, resp_ie_len);
|
||||
if (params->req_ie_len) {
|
||||
ev->cr.req_ie = next;
|
||||
ev->cr.req_ie_len = params->req_ie_len;
|
||||
memcpy((void *)ev->cr.req_ie, params->req_ie,
|
||||
params->req_ie_len);
|
||||
next += params->req_ie_len;
|
||||
}
|
||||
if (bss)
|
||||
cfg80211_hold_bss(bss_from_pub(bss));
|
||||
ev->cr.bss = bss;
|
||||
ev->cr.status = status;
|
||||
ev->cr.timeout_reason = timeout_reason;
|
||||
if (params->resp_ie_len) {
|
||||
ev->cr.resp_ie = next;
|
||||
ev->cr.resp_ie_len = params->resp_ie_len;
|
||||
memcpy((void *)ev->cr.resp_ie, params->resp_ie,
|
||||
params->resp_ie_len);
|
||||
next += params->resp_ie_len;
|
||||
}
|
||||
if (params->bss)
|
||||
cfg80211_hold_bss(bss_from_pub(params->bss));
|
||||
ev->cr.bss = params->bss;
|
||||
ev->cr.status = params->status;
|
||||
ev->cr.timeout_reason = params->timeout_reason;
|
||||
|
||||
spin_lock_irqsave(&wdev->event_lock, flags);
|
||||
list_add_tail(&ev->list, &wdev->event_list);
|
||||
spin_unlock_irqrestore(&wdev->event_lock, flags);
|
||||
queue_work(cfg80211_wq, &rdev->event_work);
|
||||
}
|
||||
EXPORT_SYMBOL(cfg80211_connect_bss);
|
||||
EXPORT_SYMBOL(cfg80211_connect_done);
|
||||
|
||||
/* Consumes bss object one way or another */
|
||||
void __cfg80211_roamed(struct wireless_dev *wdev,
|
||||
|
|
|
@ -929,7 +929,6 @@ void cfg80211_process_wdev_events(struct wireless_dev *wdev)
|
|||
{
|
||||
struct cfg80211_event *ev;
|
||||
unsigned long flags;
|
||||
const u8 *bssid = NULL;
|
||||
|
||||
spin_lock_irqsave(&wdev->event_lock, flags);
|
||||
while (!list_empty(&wdev->event_list)) {
|
||||
|
@ -941,15 +940,10 @@ void cfg80211_process_wdev_events(struct wireless_dev *wdev)
|
|||
wdev_lock(wdev);
|
||||
switch (ev->type) {
|
||||
case EVENT_CONNECT_RESULT:
|
||||
if (!is_zero_ether_addr(ev->cr.bssid))
|
||||
bssid = ev->cr.bssid;
|
||||
__cfg80211_connect_result(
|
||||
wdev->netdev, bssid,
|
||||
ev->cr.req_ie, ev->cr.req_ie_len,
|
||||
ev->cr.resp_ie, ev->cr.resp_ie_len,
|
||||
ev->cr.status,
|
||||
ev->cr.status == WLAN_STATUS_SUCCESS,
|
||||
ev->cr.bss, ev->cr.timeout_reason);
|
||||
wdev->netdev,
|
||||
&ev->cr,
|
||||
ev->cr.status == WLAN_STATUS_SUCCESS);
|
||||
break;
|
||||
case EVENT_ROAMED:
|
||||
__cfg80211_roamed(wdev, ev->rm.bss, ev->rm.req_ie,
|
||||
|
|
Loading…
Reference in a new issue