aboutsummaryrefslogtreecommitdiffstats
path: root/net
diff options
context:
space:
mode:
authorJohannes Berg <johannes.berg@intel.com>2010-08-05 11:05:55 -0400
committerJohn W. Linville <linville@tuxdriver.com>2010-08-16 15:26:40 -0400
commitd1f5b7a34aa5ff703c4966ea2652d4212ac75940 (patch)
treeecc8f06625bf4e48334420586d7e16f9645aa1e4 /net
parent7da7cc1d42d8ce02cca16df8c021e6d657f1f8fd (diff)
mac80211: allow drivers to request SM PS mode change
Sometimes drivers have more information than the stack about how their antennas/chains are used, and may require that the SM PS mode be changed. This could happen, for example, when detecting that the user disconnected an antenna. Thus this patch introduces API to allow drivers to request SM PS mode changes. Signed-off-by: Johannes Berg <johannes.berg@intel.com> Signed-off-by: John W. Linville <linville@tuxdriver.com>
Diffstat (limited to 'net')
-rw-r--r--net/mac80211/ht.c28
-rw-r--r--net/mac80211/ieee80211_i.h6
-rw-r--r--net/mac80211/mlme.c3
3 files changed, 36 insertions, 1 deletions
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
269void 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
280void 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 */
295EXPORT_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,
1113int ieee80211_send_smps_action(struct ieee80211_sub_if_data *sdata, 1116int 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);
1119void ieee80211_request_smps_work(struct work_struct *work);
1116 1120
1117void ___ieee80211_stop_rx_ba_session(struct sta_info *sta, u16 tid, 1121void ___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,