aboutsummaryrefslogtreecommitdiffstats
path: root/net/mac80211/cfg.c
diff options
context:
space:
mode:
authorIlan Peer <ilan.peer@intel.com>2013-02-12 02:34:13 -0500
committerJohannes Berg <johannes.berg@intel.com>2013-03-06 10:35:49 -0500
commitd339d5ca8eee34f3c70386cf2545edc53e546a13 (patch)
tree30587aa1e41343adcf10b0716e54964410d86edf /net/mac80211/cfg.c
parentf62fab735e99af2190eba03f565adaca5c002882 (diff)
mac80211: Allow drivers to differentiate between ROC types
Some devices can handle remain on channel requests differently based on the request type/priority. Add support to differentiate between different ROC types, i.e., indicate that the ROC is required for sending managment frames. Signed-off-by: Ilan Peer <ilan.peer@intel.com> Reviewed-by: Emmanuel Grumbach <emmanuel.grumbach@intel.com> Signed-off-by: Johannes Berg <johannes.berg@intel.com>
Diffstat (limited to 'net/mac80211/cfg.c')
-rw-r--r--net/mac80211/cfg.c21
1 files changed, 15 insertions, 6 deletions
diff --git a/net/mac80211/cfg.c b/net/mac80211/cfg.c
index c115f82c037c..f9cbdc29946d 100644
--- a/net/mac80211/cfg.c
+++ b/net/mac80211/cfg.c
@@ -2410,7 +2410,8 @@ static int ieee80211_start_roc_work(struct ieee80211_local *local,
2410 struct ieee80211_sub_if_data *sdata, 2410 struct ieee80211_sub_if_data *sdata,
2411 struct ieee80211_channel *channel, 2411 struct ieee80211_channel *channel,
2412 unsigned int duration, u64 *cookie, 2412 unsigned int duration, u64 *cookie,
2413 struct sk_buff *txskb) 2413 struct sk_buff *txskb,
2414 enum ieee80211_roc_type type)
2414{ 2415{
2415 struct ieee80211_roc_work *roc, *tmp; 2416 struct ieee80211_roc_work *roc, *tmp;
2416 bool queued = false; 2417 bool queued = false;
@@ -2429,6 +2430,7 @@ static int ieee80211_start_roc_work(struct ieee80211_local *local,
2429 roc->duration = duration; 2430 roc->duration = duration;
2430 roc->req_duration = duration; 2431 roc->req_duration = duration;
2431 roc->frame = txskb; 2432 roc->frame = txskb;
2433 roc->type = type;
2432 roc->mgmt_tx_cookie = (unsigned long)txskb; 2434 roc->mgmt_tx_cookie = (unsigned long)txskb;
2433 roc->sdata = sdata; 2435 roc->sdata = sdata;
2434 INIT_DELAYED_WORK(&roc->work, ieee80211_sw_roc_work); 2436 INIT_DELAYED_WORK(&roc->work, ieee80211_sw_roc_work);
@@ -2459,7 +2461,7 @@ static int ieee80211_start_roc_work(struct ieee80211_local *local,
2459 if (!duration) 2461 if (!duration)
2460 duration = 10; 2462 duration = 10;
2461 2463
2462 ret = drv_remain_on_channel(local, sdata, channel, duration); 2464 ret = drv_remain_on_channel(local, sdata, channel, duration, type);
2463 if (ret) { 2465 if (ret) {
2464 kfree(roc); 2466 kfree(roc);
2465 return ret; 2467 return ret;
@@ -2478,10 +2480,13 @@ static int ieee80211_start_roc_work(struct ieee80211_local *local,
2478 * 2480 *
2479 * If it hasn't started yet, just increase the duration 2481 * If it hasn't started yet, just increase the duration
2480 * and add the new one to the list of dependents. 2482 * and add the new one to the list of dependents.
2483 * If the type of the new ROC has higher priority, modify the
2484 * type of the previous one to match that of the new one.
2481 */ 2485 */
2482 if (!tmp->started) { 2486 if (!tmp->started) {
2483 list_add_tail(&roc->list, &tmp->dependents); 2487 list_add_tail(&roc->list, &tmp->dependents);
2484 tmp->duration = max(tmp->duration, roc->duration); 2488 tmp->duration = max(tmp->duration, roc->duration);
2489 tmp->type = max(tmp->type, roc->type);
2485 queued = true; 2490 queued = true;
2486 break; 2491 break;
2487 } 2492 }
@@ -2493,16 +2498,18 @@ static int ieee80211_start_roc_work(struct ieee80211_local *local,
2493 /* 2498 /*
2494 * In the offloaded ROC case, if it hasn't begun, add 2499 * In the offloaded ROC case, if it hasn't begun, add
2495 * this new one to the dependent list to be handled 2500 * this new one to the dependent list to be handled
2496 * when the the master one begins. If it has begun, 2501 * when the master one begins. If it has begun,
2497 * check that there's still a minimum time left and 2502 * check that there's still a minimum time left and
2498 * if so, start this one, transmitting the frame, but 2503 * if so, start this one, transmitting the frame, but
2499 * add it to the list directly after this one with a 2504 * add it to the list directly after this one with
2500 * a reduced time so we'll ask the driver to execute 2505 * a reduced time so we'll ask the driver to execute
2501 * it right after finishing the previous one, in the 2506 * it right after finishing the previous one, in the
2502 * hope that it'll also be executed right afterwards, 2507 * hope that it'll also be executed right afterwards,
2503 * effectively extending the old one. 2508 * effectively extending the old one.
2504 * If there's no minimum time left, just add it to the 2509 * If there's no minimum time left, just add it to the
2505 * normal list. 2510 * normal list.
2511 * TODO: the ROC type is ignored here, assuming that it
2512 * is better to immediately use the current ROC.
2506 */ 2513 */
2507 if (!tmp->hw_begun) { 2514 if (!tmp->hw_begun) {
2508 list_add_tail(&roc->list, &tmp->dependents); 2515 list_add_tail(&roc->list, &tmp->dependents);
@@ -2596,7 +2603,8 @@ static int ieee80211_remain_on_channel(struct wiphy *wiphy,
2596 2603
2597 mutex_lock(&local->mtx); 2604 mutex_lock(&local->mtx);
2598 ret = ieee80211_start_roc_work(local, sdata, chan, 2605 ret = ieee80211_start_roc_work(local, sdata, chan,
2599 duration, cookie, NULL); 2606 duration, cookie, NULL,
2607 IEEE80211_ROC_TYPE_NORMAL);
2600 mutex_unlock(&local->mtx); 2608 mutex_unlock(&local->mtx);
2601 2609
2602 return ret; 2610 return ret;
@@ -2829,7 +2837,8 @@ static int ieee80211_mgmt_tx(struct wiphy *wiphy, struct wireless_dev *wdev,
2829 2837
2830 /* This will handle all kinds of coalescing and immediate TX */ 2838 /* This will handle all kinds of coalescing and immediate TX */
2831 ret = ieee80211_start_roc_work(local, sdata, chan, 2839 ret = ieee80211_start_roc_work(local, sdata, chan,
2832 wait, cookie, skb); 2840 wait, cookie, skb,
2841 IEEE80211_ROC_TYPE_MGMT_TX);
2833 if (ret) 2842 if (ret)
2834 kfree_skb(skb); 2843 kfree_skb(skb);
2835 out_unlock: 2844 out_unlock: