Skip to content

Commit

Permalink
cfg80211: mlme API must be able to sleep
Browse files Browse the repository at this point in the history
After the mac80211 mlme cleanup, we can require that
the MLME functions in cfg80211 can sleep. This will
simplify future work in cfg80211 a lot.

Signed-off-by: Johannes Berg <johannes@sipsolutions.net>
Signed-off-by: John W. Linville <linville@tuxdriver.com>
  • Loading branch information
Johannes Berg authored and John W. Linville committed Jul 10, 2009
1 parent c238c8a commit cb0b4be
Show file tree
Hide file tree
Showing 3 changed files with 56 additions and 51 deletions.
30 changes: 14 additions & 16 deletions include/net/cfg80211.h
Original file line number Diff line number Diff line change
Expand Up @@ -1721,70 +1721,68 @@ void cfg80211_unlink_bss(struct wiphy *wiphy, struct cfg80211_bss *bss);
* @dev: network device
* @buf: authentication frame (header + body)
* @len: length of the frame data
* @gfp: allocation flags
*
* This function is called whenever an authentication has been processed in
* station mode. The driver is required to call either this function or
* cfg80211_send_auth_timeout() to indicate the result of cfg80211_ops::auth()
* call.
* call. This function may sleep.
*/
void cfg80211_send_rx_auth(struct net_device *dev, const u8 *buf, size_t len, gfp_t gfp);
void cfg80211_send_rx_auth(struct net_device *dev, const u8 *buf, size_t len);

/**
* cfg80211_send_auth_timeout - notification of timed out authentication
* @dev: network device
* @addr: The MAC address of the device with which the authentication timed out
* @gfp: allocation flags
*
* This function may sleep.
*/
void cfg80211_send_auth_timeout(struct net_device *dev, const u8 *addr, gfp_t gfp);
void cfg80211_send_auth_timeout(struct net_device *dev, const u8 *addr);

/**
* cfg80211_send_rx_assoc - notification of processed association
* @dev: network device
* @buf: (re)association response frame (header + body)
* @len: length of the frame data
* @gfp: allocation flags
*
* This function is called whenever a (re)association response has been
* processed in station mode. The driver is required to call either this
* function or cfg80211_send_assoc_timeout() to indicate the result of
* cfg80211_ops::assoc() call.
* cfg80211_ops::assoc() call. This function may sleep.
*/
void cfg80211_send_rx_assoc(struct net_device *dev, const u8 *buf, size_t len, gfp_t gfp);
void cfg80211_send_rx_assoc(struct net_device *dev, const u8 *buf, size_t len);

/**
* cfg80211_send_assoc_timeout - notification of timed out association
* @dev: network device
* @addr: The MAC address of the device with which the association timed out
* @gfp: allocation flags
*
* This function may sleep.
*/
void cfg80211_send_assoc_timeout(struct net_device *dev, const u8 *addr, gfp_t gfp);
void cfg80211_send_assoc_timeout(struct net_device *dev, const u8 *addr);

/**
* cfg80211_send_deauth - notification of processed deauthentication
* @dev: network device
* @buf: deauthentication frame (header + body)
* @len: length of the frame data
* @gfp: allocation flags
*
* This function is called whenever deauthentication has been processed in
* station mode. This includes both received deauthentication frames and
* locally generated ones.
* locally generated ones. This function may sleep.
*/
void cfg80211_send_deauth(struct net_device *dev, const u8 *buf, size_t len, gfp_t gfp);
void cfg80211_send_deauth(struct net_device *dev, const u8 *buf, size_t len);

/**
* cfg80211_send_disassoc - notification of processed disassociation
* @dev: network device
* @buf: disassociation response frame (header + body)
* @len: length of the frame data
* @gfp: allocation flags
*
* This function is called whenever disassociation has been processed in
* station mode. This includes both received disassociation frames and locally
* generated ones.
* generated ones. This function may sleep.
*/
void cfg80211_send_disassoc(struct net_device *dev, const u8 *buf, size_t len, gfp_t gfp);
void cfg80211_send_disassoc(struct net_device *dev, const u8 *buf, size_t len);

/**
* cfg80211_michael_mic_failure - notification of Michael MIC failure (TKIP)
Expand Down
26 changes: 9 additions & 17 deletions net/mac80211/mlme.c
Original file line number Diff line number Diff line change
Expand Up @@ -412,11 +412,9 @@ static void ieee80211_send_deauth_disassoc(struct ieee80211_sub_if_data *sdata,
mgmt->u.deauth.reason_code = cpu_to_le16(reason);

if (stype == IEEE80211_STYPE_DEAUTH)
cfg80211_send_deauth(sdata->dev, (u8 *) mgmt, skb->len,
GFP_KERNEL);
cfg80211_send_deauth(sdata->dev, (u8 *) mgmt, skb->len);
else
cfg80211_send_disassoc(sdata->dev, (u8 *) mgmt, skb->len,
GFP_KERNEL);
cfg80211_send_disassoc(sdata->dev, (u8 *) mgmt, skb->len);
ieee80211_tx_skb(sdata, skb, ifmgd->flags & IEEE80211_STA_MFP_ENABLED);
}

Expand Down Expand Up @@ -1839,12 +1837,10 @@ static void ieee80211_sta_rx_queued_mgmt(struct ieee80211_sub_if_data *sdata,
/* no action */
break;
case RX_MGMT_CFG80211_DEAUTH:
cfg80211_send_deauth(sdata->dev, (u8 *) mgmt,
skb->len, GFP_KERNEL);
cfg80211_send_deauth(sdata->dev, (u8 *)mgmt, skb->len);
break;
case RX_MGMT_CFG80211_DISASSOC:
cfg80211_send_disassoc(sdata->dev, (u8 *) mgmt,
skb->len, GFP_KERNEL);
cfg80211_send_disassoc(sdata->dev, (u8 *)mgmt, skb->len);
break;
default:
WARN(1, "unexpected: %d", rma);
Expand Down Expand Up @@ -1893,12 +1889,10 @@ static void ieee80211_sta_rx_queued_mgmt(struct ieee80211_sub_if_data *sdata,
/* no action */
break;
case RX_MGMT_CFG80211_AUTH:
cfg80211_send_rx_auth(sdata->dev, (u8 *) mgmt, skb->len,
GFP_KERNEL);
cfg80211_send_rx_auth(sdata->dev, (u8 *) mgmt, skb->len);
break;
case RX_MGMT_CFG80211_ASSOC:
cfg80211_send_rx_assoc(sdata->dev, (u8 *) mgmt, skb->len,
GFP_KERNEL);
cfg80211_send_rx_assoc(sdata->dev, (u8 *) mgmt, skb->len);
break;
default:
WARN(1, "unexpected: %d", rma);
Expand Down Expand Up @@ -2026,13 +2020,11 @@ static void ieee80211_sta_work(struct work_struct *work)
switch (wk->tries) {
case RX_MGMT_CFG80211_AUTH_TO:
cfg80211_send_auth_timeout(sdata->dev,
wk->bss->cbss.bssid,
GFP_KERNEL);
wk->bss->cbss.bssid);
break;
case RX_MGMT_CFG80211_ASSOC_TO:
cfg80211_send_auth_timeout(sdata->dev,
wk->bss->cbss.bssid,
GFP_KERNEL);
cfg80211_send_assoc_timeout(sdata->dev,
wk->bss->cbss.bssid);
break;
default:
WARN(1, "unexpected: %d", wk->tries);
Expand Down
51 changes: 33 additions & 18 deletions net/wireless/mlme.c
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
#include "core.h"
#include "nl80211.h"

void cfg80211_send_rx_auth(struct net_device *dev, const u8 *buf, size_t len, gfp_t gfp)
void cfg80211_send_rx_auth(struct net_device *dev, const u8 *buf, size_t len)
{
struct wireless_dev *wdev = dev->ieee80211_ptr;
struct wiphy *wiphy = wdev->wiphy;
Expand All @@ -23,6 +23,8 @@ void cfg80211_send_rx_auth(struct net_device *dev, const u8 *buf, size_t len, gf
u16 status = le16_to_cpu(mgmt->u.auth.status_code);
bool done = false;

might_sleep();

for (i = 0; i < MAX_AUTH_BSSES; i++) {
if (wdev->authtry_bsses[i] &&
memcmp(wdev->authtry_bsses[i]->pub.bssid, bssid,
Expand All @@ -41,12 +43,12 @@ void cfg80211_send_rx_auth(struct net_device *dev, const u8 *buf, size_t len, gf

WARN_ON(!done);

nl80211_send_rx_auth(rdev, dev, buf, len, gfp);
nl80211_send_rx_auth(rdev, dev, buf, len, GFP_KERNEL);
cfg80211_sme_rx_auth(dev, buf, len);
}
EXPORT_SYMBOL(cfg80211_send_rx_auth);

void cfg80211_send_rx_assoc(struct net_device *dev, const u8 *buf, size_t len, gfp_t gfp)
void cfg80211_send_rx_assoc(struct net_device *dev, const u8 *buf, size_t len)
{
u16 status_code;
struct wireless_dev *wdev = dev->ieee80211_ptr;
Expand All @@ -57,12 +59,14 @@ void cfg80211_send_rx_assoc(struct net_device *dev, const u8 *buf, size_t len, g
int i, ieoffs = offsetof(struct ieee80211_mgmt, u.assoc_resp.variable);
bool done;

might_sleep();

status_code = le16_to_cpu(mgmt->u.assoc_resp.status_code);

nl80211_send_rx_assoc(rdev, dev, buf, len, gfp);
nl80211_send_rx_assoc(rdev, dev, buf, len, GFP_KERNEL);

cfg80211_connect_result(dev, mgmt->bssid, NULL, 0, ie, len - ieoffs,
status_code, gfp);
status_code, GFP_KERNEL);

if (status_code == WLAN_STATUS_SUCCESS) {
for (i = 0; wdev->current_bss && i < MAX_AUTH_BSSES; i++) {
Expand All @@ -80,7 +84,7 @@ void cfg80211_send_rx_assoc(struct net_device *dev, const u8 *buf, size_t len, g
}
EXPORT_SYMBOL(cfg80211_send_rx_assoc);

void cfg80211_send_deauth(struct net_device *dev, const u8 *buf, size_t len, gfp_t gfp)
void cfg80211_send_deauth(struct net_device *dev, const u8 *buf, size_t len)
{
struct wireless_dev *wdev = dev->ieee80211_ptr;
struct wiphy *wiphy = wdev->wiphy;
Expand All @@ -90,7 +94,9 @@ void cfg80211_send_deauth(struct net_device *dev, const u8 *buf, size_t len, gfp
int i;
bool done = false;

nl80211_send_deauth(rdev, dev, buf, len, gfp);
might_sleep();

nl80211_send_deauth(rdev, dev, buf, len, GFP_KERNEL);

if (wdev->current_bss &&
memcmp(wdev->current_bss->pub.bssid, bssid, ETH_ALEN) == 0) {
Expand Down Expand Up @@ -132,16 +138,17 @@ void cfg80211_send_deauth(struct net_device *dev, const u8 *buf, size_t len, gfp
reason_code = le16_to_cpu(mgmt->u.deauth.reason_code);

from_ap = memcmp(mgmt->da, dev->dev_addr, ETH_ALEN) == 0;
__cfg80211_disconnected(dev, gfp, NULL, 0,
__cfg80211_disconnected(dev, GFP_KERNEL, NULL, 0,
reason_code, from_ap);
} else if (wdev->sme_state == CFG80211_SME_CONNECTING) {
cfg80211_connect_result(dev, mgmt->bssid, NULL, 0, NULL, 0,
WLAN_STATUS_UNSPECIFIED_FAILURE, gfp);
WLAN_STATUS_UNSPECIFIED_FAILURE,
GFP_KERNEL);
}
}
EXPORT_SYMBOL(cfg80211_send_deauth);

void cfg80211_send_disassoc(struct net_device *dev, const u8 *buf, size_t len, gfp_t gfp)
void cfg80211_send_disassoc(struct net_device *dev, const u8 *buf, size_t len)
{
struct wireless_dev *wdev = dev->ieee80211_ptr;
struct wiphy *wiphy = wdev->wiphy;
Expand All @@ -153,7 +160,9 @@ void cfg80211_send_disassoc(struct net_device *dev, const u8 *buf, size_t len, g
bool from_ap;
bool done = false;

nl80211_send_disassoc(rdev, dev, buf, len, gfp);
might_sleep();

nl80211_send_disassoc(rdev, dev, buf, len, GFP_KERNEL);

if (!wdev->sme_state == CFG80211_SME_CONNECTED)
return;
Expand All @@ -177,23 +186,26 @@ void cfg80211_send_disassoc(struct net_device *dev, const u8 *buf, size_t len, g
reason_code = le16_to_cpu(mgmt->u.disassoc.reason_code);

from_ap = memcmp(mgmt->da, dev->dev_addr, ETH_ALEN) == 0;
__cfg80211_disconnected(dev, gfp, NULL, 0,
__cfg80211_disconnected(dev, GFP_KERNEL, NULL, 0,
reason_code, from_ap);
}
EXPORT_SYMBOL(cfg80211_send_disassoc);

void cfg80211_send_auth_timeout(struct net_device *dev, const u8 *addr, gfp_t gfp)
void cfg80211_send_auth_timeout(struct net_device *dev, const u8 *addr)
{
struct wireless_dev *wdev = dev->ieee80211_ptr;
struct wiphy *wiphy = wdev->wiphy;
struct cfg80211_registered_device *rdev = wiphy_to_dev(wiphy);
int i;
bool done = false;

nl80211_send_auth_timeout(rdev, dev, addr, gfp);
might_sleep();

nl80211_send_auth_timeout(rdev, dev, addr, GFP_KERNEL);
if (wdev->sme_state == CFG80211_SME_CONNECTING)
cfg80211_connect_result(dev, addr, NULL, 0, NULL, 0,
WLAN_STATUS_UNSPECIFIED_FAILURE, gfp);
WLAN_STATUS_UNSPECIFIED_FAILURE,
GFP_KERNEL);

for (i = 0; addr && i < MAX_AUTH_BSSES; i++) {
if (wdev->authtry_bsses[i] &&
Expand All @@ -211,18 +223,21 @@ void cfg80211_send_auth_timeout(struct net_device *dev, const u8 *addr, gfp_t gf
}
EXPORT_SYMBOL(cfg80211_send_auth_timeout);

void cfg80211_send_assoc_timeout(struct net_device *dev, const u8 *addr, gfp_t gfp)
void cfg80211_send_assoc_timeout(struct net_device *dev, const u8 *addr)
{
struct wireless_dev *wdev = dev->ieee80211_ptr;
struct wiphy *wiphy = wdev->wiphy;
struct cfg80211_registered_device *rdev = wiphy_to_dev(wiphy);
int i;
bool done = false;

nl80211_send_assoc_timeout(rdev, dev, addr, gfp);
might_sleep();

nl80211_send_assoc_timeout(rdev, dev, addr, GFP_KERNEL);
if (wdev->sme_state == CFG80211_SME_CONNECTING)
cfg80211_connect_result(dev, addr, NULL, 0, NULL, 0,
WLAN_STATUS_UNSPECIFIED_FAILURE, gfp);
WLAN_STATUS_UNSPECIFIED_FAILURE,
GFP_KERNEL);

for (i = 0; addr && i < MAX_AUTH_BSSES; i++) {
if (wdev->auth_bsses[i] &&
Expand Down

0 comments on commit cb0b4be

Please sign in to comment.