aboutsummaryrefslogtreecommitdiffstats
path: root/net/mac80211/mlme.c
diff options
context:
space:
mode:
authorJohannes Berg <johannes.berg@intel.com>2011-07-19 04:39:53 -0400
committerJohn W. Linville <linville@tuxdriver.com>2011-07-20 15:04:35 -0400
commitb2abb6e2bcb91ae384c5857dffd0bb97b76c7a68 (patch)
tree4f6381c0a7b4dc8a1f9cd3c3bf2b94a6c971c737 /net/mac80211/mlme.c
parente0d687bd9df218ba3d97aac15919d30816d72dcb (diff)
mac80211: sync driver before TX
In P2P client mode, the GO (AP) to connect to might have periods of time where it is not available due to powersave. To allow the driver to sync with it and send frames to the GO only when it is available add a new callback tx_sync (and the corresponding finish_tx_sync). These callbacks can sleep unlike the actual TX. Signed-off-by: Johannes Berg <johannes.berg@intel.com> Signed-off-by: John W. Linville <linville@tuxdriver.com>
Diffstat (limited to 'net/mac80211/mlme.c')
-rw-r--r--net/mac80211/mlme.c24
1 files changed, 21 insertions, 3 deletions
diff --git a/net/mac80211/mlme.c b/net/mac80211/mlme.c
index fee706d39fc2..d6470c7fd6ce 100644
--- a/net/mac80211/mlme.c
+++ b/net/mac80211/mlme.c
@@ -2335,14 +2335,16 @@ static enum work_done_result
2335ieee80211_probe_auth_done(struct ieee80211_work *wk, 2335ieee80211_probe_auth_done(struct ieee80211_work *wk,
2336 struct sk_buff *skb) 2336 struct sk_buff *skb)
2337{ 2337{
2338 struct ieee80211_local *local = wk->sdata->local;
2339
2338 if (!skb) { 2340 if (!skb) {
2339 cfg80211_send_auth_timeout(wk->sdata->dev, wk->filter_ta); 2341 cfg80211_send_auth_timeout(wk->sdata->dev, wk->filter_ta);
2340 return WORK_DONE_DESTROY; 2342 goto destroy;
2341 } 2343 }
2342 2344
2343 if (wk->type == IEEE80211_WORK_AUTH) { 2345 if (wk->type == IEEE80211_WORK_AUTH) {
2344 cfg80211_send_rx_auth(wk->sdata->dev, skb->data, skb->len); 2346 cfg80211_send_rx_auth(wk->sdata->dev, skb->data, skb->len);
2345 return WORK_DONE_DESTROY; 2347 goto destroy;
2346 } 2348 }
2347 2349
2348 mutex_lock(&wk->sdata->u.mgd.mtx); 2350 mutex_lock(&wk->sdata->u.mgd.mtx);
@@ -2352,6 +2354,12 @@ ieee80211_probe_auth_done(struct ieee80211_work *wk,
2352 wk->type = IEEE80211_WORK_AUTH; 2354 wk->type = IEEE80211_WORK_AUTH;
2353 wk->probe_auth.tries = 0; 2355 wk->probe_auth.tries = 0;
2354 return WORK_DONE_REQUEUE; 2356 return WORK_DONE_REQUEUE;
2357 destroy:
2358 if (wk->probe_auth.synced)
2359 drv_finish_tx_sync(local, wk->sdata, wk->filter_ta,
2360 IEEE80211_TX_SYNC_AUTH);
2361
2362 return WORK_DONE_DESTROY;
2355} 2363}
2356 2364
2357int ieee80211_mgd_auth(struct ieee80211_sub_if_data *sdata, 2365int ieee80211_mgd_auth(struct ieee80211_sub_if_data *sdata,
@@ -2424,6 +2432,7 @@ int ieee80211_mgd_auth(struct ieee80211_sub_if_data *sdata,
2424static enum work_done_result ieee80211_assoc_done(struct ieee80211_work *wk, 2432static enum work_done_result ieee80211_assoc_done(struct ieee80211_work *wk,
2425 struct sk_buff *skb) 2433 struct sk_buff *skb)
2426{ 2434{
2435 struct ieee80211_local *local = wk->sdata->local;
2427 struct ieee80211_mgmt *mgmt; 2436 struct ieee80211_mgmt *mgmt;
2428 struct ieee80211_rx_status *rx_status; 2437 struct ieee80211_rx_status *rx_status;
2429 struct ieee802_11_elems elems; 2438 struct ieee802_11_elems elems;
@@ -2431,7 +2440,7 @@ static enum work_done_result ieee80211_assoc_done(struct ieee80211_work *wk,
2431 2440
2432 if (!skb) { 2441 if (!skb) {
2433 cfg80211_send_assoc_timeout(wk->sdata->dev, wk->filter_ta); 2442 cfg80211_send_assoc_timeout(wk->sdata->dev, wk->filter_ta);
2434 return WORK_DONE_DESTROY; 2443 goto destroy;
2435 } 2444 }
2436 2445
2437 if (wk->type == IEEE80211_WORK_ASSOC_BEACON_WAIT) { 2446 if (wk->type == IEEE80211_WORK_ASSOC_BEACON_WAIT) {
@@ -2451,6 +2460,10 @@ static enum work_done_result ieee80211_assoc_done(struct ieee80211_work *wk,
2451 status = le16_to_cpu(mgmt->u.assoc_resp.status_code); 2460 status = le16_to_cpu(mgmt->u.assoc_resp.status_code);
2452 2461
2453 if (status == WLAN_STATUS_SUCCESS) { 2462 if (status == WLAN_STATUS_SUCCESS) {
2463 if (wk->assoc.synced)
2464 drv_finish_tx_sync(local, wk->sdata, wk->filter_ta,
2465 IEEE80211_TX_SYNC_ASSOC);
2466
2454 mutex_lock(&wk->sdata->u.mgd.mtx); 2467 mutex_lock(&wk->sdata->u.mgd.mtx);
2455 if (!ieee80211_assoc_success(wk, mgmt, skb->len)) { 2468 if (!ieee80211_assoc_success(wk, mgmt, skb->len)) {
2456 mutex_unlock(&wk->sdata->u.mgd.mtx); 2469 mutex_unlock(&wk->sdata->u.mgd.mtx);
@@ -2464,6 +2477,11 @@ static enum work_done_result ieee80211_assoc_done(struct ieee80211_work *wk,
2464 } 2477 }
2465 2478
2466 cfg80211_send_rx_assoc(wk->sdata->dev, skb->data, skb->len); 2479 cfg80211_send_rx_assoc(wk->sdata->dev, skb->data, skb->len);
2480 destroy:
2481 if (wk->assoc.synced)
2482 drv_finish_tx_sync(local, wk->sdata, wk->filter_ta,
2483 IEEE80211_TX_SYNC_ASSOC);
2484
2467 return WORK_DONE_DESTROY; 2485 return WORK_DONE_DESTROY;
2468} 2486}
2469 2487