aboutsummaryrefslogtreecommitdiffstats
path: root/net/mac80211/mlme.c
diff options
context:
space:
mode:
authorJohannes Berg <johannes@sipsolutions.net>2009-07-06 21:56:11 -0400
committerJohn W. Linville <linville@tuxdriver.com>2009-07-10 15:02:32 -0400
commit667503ddcb96f3b10211f997fe55907fa7509841 (patch)
tree5e2559e94a716bb81bfc7566e3e3a05267810c31 /net/mac80211/mlme.c
parent4f5dadcebb55fccef34722bbbf6401d39124c8a4 (diff)
cfg80211: fix locking
Over time, a lot of locking issues have crept into the smarts of cfg80211, so e.g. scan completion can race against a new scan, IBSS join can race against leaving an IBSS, etc. Introduce a new per-interface lock that protects most of the per-interface data that we need to keep track of, and sprinkle assertions about that lock everywhere. Some things now need to be offloaded to work structs so that we don't require being able to sleep in functions the drivers call. The exception to that are the MLME callbacks (rx_auth etc.) that currently only mac80211 calls because it was easier to do that there instead of in cfg80211, and future drivers implementing those calls will, if they ever exist, probably need to use a similar scheme like mac80211 anyway... In order to be able to handle _deauth and _disassoc properly, introduce a cookie passed to it that will determine locking requirements. Signed-off-by: Johannes Berg <johannes@sipsolutions.net> Signed-off-by: John W. Linville <linville@tuxdriver.com>
Diffstat (limited to 'net/mac80211/mlme.c')
-rw-r--r--net/mac80211/mlme.c25
1 files changed, 16 insertions, 9 deletions
diff --git a/net/mac80211/mlme.c b/net/mac80211/mlme.c
index 15dbb57ab55e..c9db9646025b 100644
--- a/net/mac80211/mlme.c
+++ b/net/mac80211/mlme.c
@@ -386,7 +386,8 @@ static void ieee80211_send_assoc(struct ieee80211_sub_if_data *sdata,
386 386
387 387
388static void ieee80211_send_deauth_disassoc(struct ieee80211_sub_if_data *sdata, 388static void ieee80211_send_deauth_disassoc(struct ieee80211_sub_if_data *sdata,
389 const u8 *bssid, u16 stype, u16 reason) 389 const u8 *bssid, u16 stype, u16 reason,
390 void *cookie)
390{ 391{
391 struct ieee80211_local *local = sdata->local; 392 struct ieee80211_local *local = sdata->local;
392 struct ieee80211_if_managed *ifmgd = &sdata->u.mgd; 393 struct ieee80211_if_managed *ifmgd = &sdata->u.mgd;
@@ -412,9 +413,9 @@ static void ieee80211_send_deauth_disassoc(struct ieee80211_sub_if_data *sdata,
412 mgmt->u.deauth.reason_code = cpu_to_le16(reason); 413 mgmt->u.deauth.reason_code = cpu_to_le16(reason);
413 414
414 if (stype == IEEE80211_STYPE_DEAUTH) 415 if (stype == IEEE80211_STYPE_DEAUTH)
415 cfg80211_send_deauth(sdata->dev, (u8 *) mgmt, skb->len); 416 cfg80211_send_deauth(sdata->dev, (u8 *)mgmt, skb->len, cookie);
416 else 417 else
417 cfg80211_send_disassoc(sdata->dev, (u8 *) mgmt, skb->len); 418 cfg80211_send_disassoc(sdata->dev, (u8 *)mgmt, skb->len, cookie);
418 ieee80211_tx_skb(sdata, skb, ifmgd->flags & IEEE80211_STA_MFP_ENABLED); 419 ieee80211_tx_skb(sdata, skb, ifmgd->flags & IEEE80211_STA_MFP_ENABLED);
419} 420}
420 421
@@ -1837,10 +1838,12 @@ static void ieee80211_sta_rx_queued_mgmt(struct ieee80211_sub_if_data *sdata,
1837 /* no action */ 1838 /* no action */
1838 break; 1839 break;
1839 case RX_MGMT_CFG80211_DEAUTH: 1840 case RX_MGMT_CFG80211_DEAUTH:
1840 cfg80211_send_deauth(sdata->dev, (u8 *)mgmt, skb->len); 1841 cfg80211_send_deauth(sdata->dev, (u8 *)mgmt, skb->len,
1842 NULL);
1841 break; 1843 break;
1842 case RX_MGMT_CFG80211_DISASSOC: 1844 case RX_MGMT_CFG80211_DISASSOC:
1843 cfg80211_send_disassoc(sdata->dev, (u8 *)mgmt, skb->len); 1845 cfg80211_send_disassoc(sdata->dev, (u8 *)mgmt, skb->len,
1846 NULL);
1844 break; 1847 break;
1845 default: 1848 default:
1846 WARN(1, "unexpected: %d", rma); 1849 WARN(1, "unexpected: %d", rma);
@@ -2273,7 +2276,8 @@ int ieee80211_mgd_assoc(struct ieee80211_sub_if_data *sdata,
2273} 2276}
2274 2277
2275int ieee80211_mgd_deauth(struct ieee80211_sub_if_data *sdata, 2278int ieee80211_mgd_deauth(struct ieee80211_sub_if_data *sdata,
2276 struct cfg80211_deauth_request *req) 2279 struct cfg80211_deauth_request *req,
2280 void *cookie)
2277{ 2281{
2278 struct ieee80211_if_managed *ifmgd = &sdata->u.mgd; 2282 struct ieee80211_if_managed *ifmgd = &sdata->u.mgd;
2279 struct ieee80211_mgd_work *wk; 2283 struct ieee80211_mgd_work *wk;
@@ -2305,13 +2309,15 @@ int ieee80211_mgd_deauth(struct ieee80211_sub_if_data *sdata,
2305 mutex_unlock(&ifmgd->mtx); 2309 mutex_unlock(&ifmgd->mtx);
2306 2310
2307 ieee80211_send_deauth_disassoc(sdata, bssid, 2311 ieee80211_send_deauth_disassoc(sdata, bssid,
2308 IEEE80211_STYPE_DEAUTH, req->reason_code); 2312 IEEE80211_STYPE_DEAUTH, req->reason_code,
2313 cookie);
2309 2314
2310 return 0; 2315 return 0;
2311} 2316}
2312 2317
2313int ieee80211_mgd_disassoc(struct ieee80211_sub_if_data *sdata, 2318int ieee80211_mgd_disassoc(struct ieee80211_sub_if_data *sdata,
2314 struct cfg80211_disassoc_request *req) 2319 struct cfg80211_disassoc_request *req,
2320 void *cookie)
2315{ 2321{
2316 struct ieee80211_if_managed *ifmgd = &sdata->u.mgd; 2322 struct ieee80211_if_managed *ifmgd = &sdata->u.mgd;
2317 2323
@@ -2331,6 +2337,7 @@ int ieee80211_mgd_disassoc(struct ieee80211_sub_if_data *sdata,
2331 mutex_unlock(&ifmgd->mtx); 2337 mutex_unlock(&ifmgd->mtx);
2332 2338
2333 ieee80211_send_deauth_disassoc(sdata, req->bss->bssid, 2339 ieee80211_send_deauth_disassoc(sdata, req->bss->bssid,
2334 IEEE80211_STYPE_DISASSOC, req->reason_code); 2340 IEEE80211_STYPE_DISASSOC, req->reason_code,
2341 cookie);
2335 return 0; 2342 return 0;
2336} 2343}