aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--include/net/mac80211.h19
-rw-r--r--net/mac80211/mlme.c20
2 files changed, 32 insertions, 7 deletions
diff --git a/include/net/mac80211.h b/include/net/mac80211.h
index 183956e4930a..446dbf75a1c5 100644
--- a/include/net/mac80211.h
+++ b/include/net/mac80211.h
@@ -517,7 +517,7 @@ struct ieee80211_rx_status {
517 * Flags to define PHY configuration options 517 * Flags to define PHY configuration options
518 * 518 *
519 * @IEEE80211_CONF_RADIOTAP: add radiotap header at receive time (if supported) 519 * @IEEE80211_CONF_RADIOTAP: add radiotap header at receive time (if supported)
520 * @IEEE80211_CONF_PS: Enable 802.11 power save mode 520 * @IEEE80211_CONF_PS: Enable 802.11 power save mode (managed mode only)
521 */ 521 */
522enum ieee80211_conf_flags { 522enum ieee80211_conf_flags {
523 IEEE80211_CONF_RADIOTAP = (1<<0), 523 IEEE80211_CONF_RADIOTAP = (1<<0),
@@ -553,14 +553,26 @@ enum ieee80211_conf_changed {
553 * 553 *
554 * This struct indicates how the driver shall configure the hardware. 554 * This struct indicates how the driver shall configure the hardware.
555 * 555 *
556 * @flags: configuration flags defined above
557 *
556 * @radio_enabled: when zero, driver is required to switch off the radio. 558 * @radio_enabled: when zero, driver is required to switch off the radio.
557 * @beacon_int: beacon interval (TODO make interface config) 559 * @beacon_int: beacon interval (TODO make interface config)
560 *
558 * @listen_interval: listen interval in units of beacon interval 561 * @listen_interval: listen interval in units of beacon interval
559 * @flags: configuration flags defined above 562 * @max_sleep_interval: the maximum number of beacon intervals to sleep for
563 * before checking the beacon for a TIM bit (managed mode only); this
564 * value will be only achievable between DTIM frames, the hardware
565 * needs to check for the multicast traffic bit in DTIM beacons.
566 * This variable is valid only when the CONF_PS flag is set.
567 * @dynamic_ps_timeout: The dynamic powersave timeout (in ms), see the
568 * powersave documentation below. This variable is valid only when
569 * the CONF_PS flag is set.
570 *
560 * @power_level: requested transmit power (in dBm) 571 * @power_level: requested transmit power (in dBm)
561 * @dynamic_ps_timeout: dynamic powersave timeout (in ms) 572 *
562 * @channel: the channel to tune to 573 * @channel: the channel to tune to
563 * @channel_type: the channel (HT) type 574 * @channel_type: the channel (HT) type
575 *
564 * @long_frame_max_tx_count: Maximum number of transmissions for a "long" frame 576 * @long_frame_max_tx_count: Maximum number of transmissions for a "long" frame
565 * (a frame not RTS protected), called "dot11LongRetryLimit" in 802.11, 577 * (a frame not RTS protected), called "dot11LongRetryLimit" in 802.11,
566 * but actually means the number of transmissions not the number of retries 578 * but actually means the number of transmissions not the number of retries
@@ -572,6 +584,7 @@ struct ieee80211_conf {
572 int beacon_int; 584 int beacon_int;
573 u32 flags; 585 u32 flags;
574 int power_level, dynamic_ps_timeout; 586 int power_level, dynamic_ps_timeout;
587 int max_sleep_interval;
575 588
576 u16 listen_interval; 589 u16 listen_interval;
577 bool radio_enabled; 590 bool radio_enabled;
diff --git a/net/mac80211/mlme.c b/net/mac80211/mlme.c
index e819c02d13f0..df27c68620c9 100644
--- a/net/mac80211/mlme.c
+++ b/net/mac80211/mlme.c
@@ -545,10 +545,19 @@ void ieee80211_recalc_ps(struct ieee80211_local *local, s32 latency)
545 beaconint_us = ieee80211_tu_to_usec( 545 beaconint_us = ieee80211_tu_to_usec(
546 found->vif.bss_conf.beacon_int); 546 found->vif.bss_conf.beacon_int);
547 547
548 if (beaconint_us > latency) 548 if (beaconint_us > latency) {
549 local->ps_sdata = NULL; 549 local->ps_sdata = NULL;
550 else 550 } else {
551 u8 dtimper = found->vif.bss_conf.dtim_period;
552 int maxslp = 1;
553
554 if (dtimper > 1)
555 maxslp = min_t(int, dtimper,
556 latency / beaconint_us);
557
558 local->hw.conf.max_sleep_interval = maxslp;
551 local->ps_sdata = found; 559 local->ps_sdata = found;
560 }
552 } else { 561 } else {
553 local->ps_sdata = NULL; 562 local->ps_sdata = NULL;
554 } 563 }
@@ -851,8 +860,11 @@ static void ieee80211_set_associated(struct ieee80211_sub_if_data *sdata,
851 ieee80211_bss_info_change_notify(sdata, bss_info_changed); 860 ieee80211_bss_info_change_notify(sdata, bss_info_changed);
852 861
853 /* will be same as sdata */ 862 /* will be same as sdata */
854 if (local->ps_sdata) 863 if (local->ps_sdata) {
855 ieee80211_enable_ps(local, sdata); 864 mutex_lock(&local->iflist_mtx);
865 ieee80211_recalc_ps(local, -1);
866 mutex_unlock(&local->iflist_mtx);
867 }
856 868
857 netif_tx_start_all_queues(sdata->dev); 869 netif_tx_start_all_queues(sdata->dev);
858 netif_carrier_on(sdata->dev); 870 netif_carrier_on(sdata->dev);