aboutsummaryrefslogtreecommitdiffstats
path: root/net/mac80211
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
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')
-rw-r--r--net/mac80211/cfg.c21
-rw-r--r--net/mac80211/driver-ops.h7
-rw-r--r--net/mac80211/ieee80211_i.h1
-rw-r--r--net/mac80211/offchannel.c2
-rw-r--r--net/mac80211/trace.h11
5 files changed, 28 insertions, 14 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:
diff --git a/net/mac80211/driver-ops.h b/net/mac80211/driver-ops.h
index ee56d0779d8b..832acea4a5cb 100644
--- a/net/mac80211/driver-ops.h
+++ b/net/mac80211/driver-ops.h
@@ -787,15 +787,16 @@ static inline int drv_get_antenna(struct ieee80211_local *local,
787static inline int drv_remain_on_channel(struct ieee80211_local *local, 787static inline int drv_remain_on_channel(struct ieee80211_local *local,
788 struct ieee80211_sub_if_data *sdata, 788 struct ieee80211_sub_if_data *sdata,
789 struct ieee80211_channel *chan, 789 struct ieee80211_channel *chan,
790 unsigned int duration) 790 unsigned int duration,
791 enum ieee80211_roc_type type)
791{ 792{
792 int ret; 793 int ret;
793 794
794 might_sleep(); 795 might_sleep();
795 796
796 trace_drv_remain_on_channel(local, sdata, chan, duration); 797 trace_drv_remain_on_channel(local, sdata, chan, duration, type);
797 ret = local->ops->remain_on_channel(&local->hw, &sdata->vif, 798 ret = local->ops->remain_on_channel(&local->hw, &sdata->vif,
798 chan, duration); 799 chan, duration, type);
799 trace_drv_return_int(local, ret); 800 trace_drv_return_int(local, ret);
800 801
801 return ret; 802 return ret;
diff --git a/net/mac80211/ieee80211_i.h b/net/mac80211/ieee80211_i.h
index 8da53a067306..2518f0429b87 100644
--- a/net/mac80211/ieee80211_i.h
+++ b/net/mac80211/ieee80211_i.h
@@ -315,6 +315,7 @@ struct ieee80211_roc_work {
315 u32 duration, req_duration; 315 u32 duration, req_duration;
316 struct sk_buff *frame; 316 struct sk_buff *frame;
317 u64 cookie, mgmt_tx_cookie; 317 u64 cookie, mgmt_tx_cookie;
318 enum ieee80211_roc_type type;
318}; 319};
319 320
320/* flags used in struct ieee80211_if_managed.flags */ 321/* flags used in struct ieee80211_if_managed.flags */
diff --git a/net/mac80211/offchannel.c b/net/mac80211/offchannel.c
index cc79b4a2e821..db547fceaeb9 100644
--- a/net/mac80211/offchannel.c
+++ b/net/mac80211/offchannel.c
@@ -277,7 +277,7 @@ void ieee80211_start_next_roc(struct ieee80211_local *local)
277 duration = 10; 277 duration = 10;
278 278
279 ret = drv_remain_on_channel(local, roc->sdata, roc->chan, 279 ret = drv_remain_on_channel(local, roc->sdata, roc->chan,
280 duration); 280 duration, roc->type);
281 281
282 roc->started = true; 282 roc->started = true;
283 283
diff --git a/net/mac80211/trace.h b/net/mac80211/trace.h
index 3d7cd2a0582f..e7db2b804e0c 100644
--- a/net/mac80211/trace.h
+++ b/net/mac80211/trace.h
@@ -1042,15 +1042,17 @@ TRACE_EVENT(drv_remain_on_channel,
1042 TP_PROTO(struct ieee80211_local *local, 1042 TP_PROTO(struct ieee80211_local *local,
1043 struct ieee80211_sub_if_data *sdata, 1043 struct ieee80211_sub_if_data *sdata,
1044 struct ieee80211_channel *chan, 1044 struct ieee80211_channel *chan,
1045 unsigned int duration), 1045 unsigned int duration,
1046 enum ieee80211_roc_type type),
1046 1047
1047 TP_ARGS(local, sdata, chan, duration), 1048 TP_ARGS(local, sdata, chan, duration, type),
1048 1049
1049 TP_STRUCT__entry( 1050 TP_STRUCT__entry(
1050 LOCAL_ENTRY 1051 LOCAL_ENTRY
1051 VIF_ENTRY 1052 VIF_ENTRY
1052 __field(int, center_freq) 1053 __field(int, center_freq)
1053 __field(unsigned int, duration) 1054 __field(unsigned int, duration)
1055 __field(u32, type)
1054 ), 1056 ),
1055 1057
1056 TP_fast_assign( 1058 TP_fast_assign(
@@ -1058,12 +1060,13 @@ TRACE_EVENT(drv_remain_on_channel,
1058 VIF_ASSIGN; 1060 VIF_ASSIGN;
1059 __entry->center_freq = chan->center_freq; 1061 __entry->center_freq = chan->center_freq;
1060 __entry->duration = duration; 1062 __entry->duration = duration;
1063 __entry->type = type;
1061 ), 1064 ),
1062 1065
1063 TP_printk( 1066 TP_printk(
1064 LOCAL_PR_FMT VIF_PR_FMT " freq:%dMHz duration:%dms", 1067 LOCAL_PR_FMT VIF_PR_FMT " freq:%dMHz duration:%dms type=%d",
1065 LOCAL_PR_ARG, VIF_PR_ARG, 1068 LOCAL_PR_ARG, VIF_PR_ARG,
1066 __entry->center_freq, __entry->duration 1069 __entry->center_freq, __entry->duration, __entry->type
1067 ) 1070 )
1068); 1071);
1069 1072