diff options
-rw-r--r-- | include/net/mac80211.h | 12 | ||||
-rw-r--r-- | net/mac80211/ht.c | 28 | ||||
-rw-r--r-- | net/mac80211/ieee80211_i.h | 6 | ||||
-rw-r--r-- | net/mac80211/mlme.c | 3 |
4 files changed, 48 insertions, 1 deletions
diff --git a/include/net/mac80211.h b/include/net/mac80211.h index 3a3c26f647b7..871ed1de736a 100644 --- a/include/net/mac80211.h +++ b/include/net/mac80211.h | |||
@@ -2548,6 +2548,18 @@ void ieee80211_cqm_rssi_notify(struct ieee80211_vif *vif, | |||
2548 | */ | 2548 | */ |
2549 | void ieee80211_chswitch_done(struct ieee80211_vif *vif, bool success); | 2549 | void ieee80211_chswitch_done(struct ieee80211_vif *vif, bool success); |
2550 | 2550 | ||
2551 | /** | ||
2552 | * ieee80211_request_smps - request SM PS transition | ||
2553 | * @vif: &struct ieee80211_vif pointer from the add_interface callback. | ||
2554 | * @mode: new SM PS mode | ||
2555 | * | ||
2556 | * This allows the driver to request an SM PS transition in managed | ||
2557 | * mode. This is useful when the driver has more information than | ||
2558 | * the stack about possible interference, for example by bluetooth. | ||
2559 | */ | ||
2560 | void ieee80211_request_smps(struct ieee80211_vif *vif, | ||
2561 | enum ieee80211_smps_mode smps_mode); | ||
2562 | |||
2551 | /* Rate control API */ | 2563 | /* Rate control API */ |
2552 | 2564 | ||
2553 | /** | 2565 | /** |
diff --git a/net/mac80211/ht.c b/net/mac80211/ht.c index 9d101fb33861..11f74f5f7b2f 100644 --- a/net/mac80211/ht.c +++ b/net/mac80211/ht.c | |||
@@ -265,3 +265,31 @@ int ieee80211_send_smps_action(struct ieee80211_sub_if_data *sdata, | |||
265 | 265 | ||
266 | return 0; | 266 | return 0; |
267 | } | 267 | } |
268 | |||
269 | void ieee80211_request_smps_work(struct work_struct *work) | ||
270 | { | ||
271 | struct ieee80211_sub_if_data *sdata = | ||
272 | container_of(work, struct ieee80211_sub_if_data, | ||
273 | u.mgd.request_smps_work); | ||
274 | |||
275 | mutex_lock(&sdata->u.mgd.mtx); | ||
276 | __ieee80211_request_smps(sdata, sdata->u.mgd.driver_smps_mode); | ||
277 | mutex_unlock(&sdata->u.mgd.mtx); | ||
278 | } | ||
279 | |||
280 | void ieee80211_request_smps(struct ieee80211_vif *vif, | ||
281 | enum ieee80211_smps_mode smps_mode) | ||
282 | { | ||
283 | struct ieee80211_sub_if_data *sdata = vif_to_sdata(vif); | ||
284 | |||
285 | if (WARN_ON(vif->type != NL80211_IFTYPE_STATION)) | ||
286 | return; | ||
287 | |||
288 | if (WARN_ON(smps_mode == IEEE80211_SMPS_OFF)) | ||
289 | smps_mode = IEEE80211_SMPS_AUTOMATIC; | ||
290 | |||
291 | ieee80211_queue_work(&sdata->local->hw, | ||
292 | &sdata->u.mgd.request_smps_work); | ||
293 | } | ||
294 | /* this might change ... don't want non-open drivers using it */ | ||
295 | EXPORT_SYMBOL_GPL(ieee80211_request_smps); | ||
diff --git a/net/mac80211/ieee80211_i.h b/net/mac80211/ieee80211_i.h index 98e783c6a363..1bf05bfd149d 100644 --- a/net/mac80211/ieee80211_i.h +++ b/net/mac80211/ieee80211_i.h | |||
@@ -343,7 +343,10 @@ struct ieee80211_if_managed { | |||
343 | unsigned long timers_running; /* used for quiesce/restart */ | 343 | unsigned long timers_running; /* used for quiesce/restart */ |
344 | bool powersave; /* powersave requested for this iface */ | 344 | bool powersave; /* powersave requested for this iface */ |
345 | enum ieee80211_smps_mode req_smps, /* requested smps mode */ | 345 | enum ieee80211_smps_mode req_smps, /* requested smps mode */ |
346 | ap_smps; /* smps mode AP thinks we're in */ | 346 | ap_smps, /* smps mode AP thinks we're in */ |
347 | driver_smps_mode; /* smps mode request */ | ||
348 | |||
349 | struct work_struct request_smps_work; | ||
347 | 350 | ||
348 | unsigned int flags; | 351 | unsigned int flags; |
349 | 352 | ||
@@ -1113,6 +1116,7 @@ void ieee80211_send_delba(struct ieee80211_sub_if_data *sdata, | |||
1113 | int ieee80211_send_smps_action(struct ieee80211_sub_if_data *sdata, | 1116 | int ieee80211_send_smps_action(struct ieee80211_sub_if_data *sdata, |
1114 | enum ieee80211_smps_mode smps, const u8 *da, | 1117 | enum ieee80211_smps_mode smps, const u8 *da, |
1115 | const u8 *bssid); | 1118 | const u8 *bssid); |
1119 | void ieee80211_request_smps_work(struct work_struct *work); | ||
1116 | 1120 | ||
1117 | void ___ieee80211_stop_rx_ba_session(struct sta_info *sta, u16 tid, | 1121 | void ___ieee80211_stop_rx_ba_session(struct sta_info *sta, u16 tid, |
1118 | u16 initiator, u16 reason); | 1122 | u16 initiator, u16 reason); |
diff --git a/net/mac80211/mlme.c b/net/mac80211/mlme.c index 82e7cec5179c..38996a44aa8e 100644 --- a/net/mac80211/mlme.c +++ b/net/mac80211/mlme.c | |||
@@ -1926,6 +1926,8 @@ void ieee80211_sta_quiesce(struct ieee80211_sub_if_data *sdata) | |||
1926 | * time -- the code here is properly synchronised. | 1926 | * time -- the code here is properly synchronised. |
1927 | */ | 1927 | */ |
1928 | 1928 | ||
1929 | cancel_work_sync(&ifmgd->request_smps_work); | ||
1930 | |||
1929 | cancel_work_sync(&ifmgd->beacon_connection_loss_work); | 1931 | cancel_work_sync(&ifmgd->beacon_connection_loss_work); |
1930 | if (del_timer_sync(&ifmgd->timer)) | 1932 | if (del_timer_sync(&ifmgd->timer)) |
1931 | set_bit(TMR_RUNNING_TIMER, &ifmgd->timers_running); | 1933 | set_bit(TMR_RUNNING_TIMER, &ifmgd->timers_running); |
@@ -1961,6 +1963,7 @@ void ieee80211_sta_setup_sdata(struct ieee80211_sub_if_data *sdata) | |||
1961 | INIT_WORK(&ifmgd->chswitch_work, ieee80211_chswitch_work); | 1963 | INIT_WORK(&ifmgd->chswitch_work, ieee80211_chswitch_work); |
1962 | INIT_WORK(&ifmgd->beacon_connection_loss_work, | 1964 | INIT_WORK(&ifmgd->beacon_connection_loss_work, |
1963 | ieee80211_beacon_connection_loss_work); | 1965 | ieee80211_beacon_connection_loss_work); |
1966 | INIT_WORK(&ifmgd->request_smps_work, ieee80211_request_smps_work); | ||
1964 | setup_timer(&ifmgd->timer, ieee80211_sta_timer, | 1967 | setup_timer(&ifmgd->timer, ieee80211_sta_timer, |
1965 | (unsigned long) sdata); | 1968 | (unsigned long) sdata); |
1966 | setup_timer(&ifmgd->bcn_mon_timer, ieee80211_sta_bcn_mon_timer, | 1969 | setup_timer(&ifmgd->bcn_mon_timer, ieee80211_sta_bcn_mon_timer, |