aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--include/net/mac80211.h39
-rw-r--r--net/mac80211/ieee80211_i.h2
-rw-r--r--net/mac80211/mlme.c39
3 files changed, 79 insertions, 1 deletions
diff --git a/include/net/mac80211.h b/include/net/mac80211.h
index fe1a3a60337..7f256e23c57 100644
--- a/include/net/mac80211.h
+++ b/include/net/mac80211.h
@@ -1271,6 +1271,15 @@ ieee80211_get_alt_retry_rate(const struct ieee80211_hw *hw,
1271 * dynamic PS feature in stack and will just keep %IEEE80211_CONF_PS 1271 * dynamic PS feature in stack and will just keep %IEEE80211_CONF_PS
1272 * enabled whenever user has enabled powersave. 1272 * enabled whenever user has enabled powersave.
1273 * 1273 *
1274 * Some hardware need to toggle a single shared antenna between WLAN and
1275 * Bluetooth to facilitate co-existence. These types of hardware set
1276 * limitations on the use of host controlled dynamic powersave whenever there
1277 * is simultaneous WLAN and Bluetooth traffic. For these types of hardware, the
1278 * driver may request temporarily going into full power save, in order to
1279 * enable toggling the antenna between BT and WLAN. If the driver requests
1280 * disabling dynamic powersave, the @dynamic_ps_timeout value will be
1281 * temporarily set to zero until the driver re-enables dynamic powersave.
1282 *
1274 * Driver informs U-APSD client support by enabling 1283 * Driver informs U-APSD client support by enabling
1275 * %IEEE80211_HW_SUPPORTS_UAPSD flag. The mode is configured through the 1284 * %IEEE80211_HW_SUPPORTS_UAPSD flag. The mode is configured through the
1276 * uapsd paramater in conf_tx() operation. Hardware needs to send the QoS 1285 * uapsd paramater in conf_tx() operation. Hardware needs to send the QoS
@@ -2447,6 +2456,36 @@ void ieee80211_beacon_loss(struct ieee80211_vif *vif);
2447void ieee80211_connection_loss(struct ieee80211_vif *vif); 2456void ieee80211_connection_loss(struct ieee80211_vif *vif);
2448 2457
2449/** 2458/**
2459 * ieee80211_disable_dyn_ps - force mac80211 to temporarily disable dynamic psm
2460 *
2461 * @vif: &struct ieee80211_vif pointer from the add_interface callback.
2462 *
2463 * Some hardware require full power save to manage simultaneous BT traffic
2464 * on the WLAN frequency. Full PSM is required periodically, whenever there are
2465 * burst of BT traffic. The hardware gets information of BT traffic via
2466 * hardware co-existence lines, and consequentially requests mac80211 to
2467 * (temporarily) enter full psm.
2468 * This function will only temporarily disable dynamic PS, not enable PSM if
2469 * it was not already enabled.
2470 * The driver must make sure to re-enable dynamic PS using
2471 * ieee80211_enable_dyn_ps() if the driver has disabled it.
2472 *
2473 */
2474void ieee80211_disable_dyn_ps(struct ieee80211_vif *vif);
2475
2476/**
2477 * ieee80211_enable_dyn_ps - restore dynamic psm after being disabled
2478 *
2479 * @vif: &struct ieee80211_vif pointer from the add_interface callback.
2480 *
2481 * This function restores dynamic PS after being temporarily disabled via
2482 * ieee80211_disable_dyn_ps(). Each ieee80211_disable_dyn_ps() call must
2483 * be coupled with an eventual call to this function.
2484 *
2485 */
2486void ieee80211_enable_dyn_ps(struct ieee80211_vif *vif);
2487
2488/**
2450 * ieee80211_cqm_rssi_notify - inform a configured connection quality monitoring 2489 * ieee80211_cqm_rssi_notify - inform a configured connection quality monitoring
2451 * rssi threshold triggered 2490 * rssi threshold triggered
2452 * 2491 *
diff --git a/net/mac80211/ieee80211_i.h b/net/mac80211/ieee80211_i.h
index fb5430188e8..f9251d50192 100644
--- a/net/mac80211/ieee80211_i.h
+++ b/net/mac80211/ieee80211_i.h
@@ -855,6 +855,8 @@ struct ieee80211_local {
855 * this will override whatever chosen by mac80211 internally. 855 * this will override whatever chosen by mac80211 internally.
856 */ 856 */
857 int dynamic_ps_forced_timeout; 857 int dynamic_ps_forced_timeout;
858 int dynamic_ps_user_timeout;
859 bool disable_dynamic_ps;
858 860
859 int user_power_level; /* in dBm */ 861 int user_power_level; /* in dBm */
860 int power_constr_level; /* in dBm */ 862 int power_constr_level; /* in dBm */
diff --git a/net/mac80211/mlme.c b/net/mac80211/mlme.c
index 85c3ca33333..d1962650b25 100644
--- a/net/mac80211/mlme.c
+++ b/net/mac80211/mlme.c
@@ -478,6 +478,39 @@ static void ieee80211_handle_pwr_constr(struct ieee80211_sub_if_data *sdata,
478 } 478 }
479} 479}
480 480
481void ieee80211_enable_dyn_ps(struct ieee80211_vif *vif)
482{
483 struct ieee80211_sub_if_data *sdata = vif_to_sdata(vif);
484 struct ieee80211_local *local = sdata->local;
485 struct ieee80211_conf *conf = &local->hw.conf;
486
487 WARN_ON(sdata->vif.type != NL80211_IFTYPE_STATION ||
488 !(local->hw.flags & IEEE80211_HW_SUPPORTS_PS) ||
489 (local->hw.flags & IEEE80211_HW_SUPPORTS_DYNAMIC_PS));
490
491 local->disable_dynamic_ps = false;
492 conf->dynamic_ps_timeout = local->dynamic_ps_user_timeout;
493}
494EXPORT_SYMBOL(ieee80211_enable_dyn_ps);
495
496void ieee80211_disable_dyn_ps(struct ieee80211_vif *vif)
497{
498 struct ieee80211_sub_if_data *sdata = vif_to_sdata(vif);
499 struct ieee80211_local *local = sdata->local;
500 struct ieee80211_conf *conf = &local->hw.conf;
501
502 WARN_ON(sdata->vif.type != NL80211_IFTYPE_STATION ||
503 !(local->hw.flags & IEEE80211_HW_SUPPORTS_PS) ||
504 (local->hw.flags & IEEE80211_HW_SUPPORTS_DYNAMIC_PS));
505
506 local->disable_dynamic_ps = true;
507 conf->dynamic_ps_timeout = 0;
508 del_timer_sync(&local->dynamic_ps_timer);
509 ieee80211_queue_work(&local->hw,
510 &local->dynamic_ps_enable_work);
511}
512EXPORT_SYMBOL(ieee80211_disable_dyn_ps);
513
481/* powersave */ 514/* powersave */
482static void ieee80211_enable_ps(struct ieee80211_local *local, 515static void ieee80211_enable_ps(struct ieee80211_local *local,
483 struct ieee80211_sub_if_data *sdata) 516 struct ieee80211_sub_if_data *sdata)
@@ -553,6 +586,7 @@ void ieee80211_recalc_ps(struct ieee80211_local *local, s32 latency)
553 found->u.mgd.associated->beacon_ies && 586 found->u.mgd.associated->beacon_ies &&
554 !(found->u.mgd.flags & (IEEE80211_STA_BEACON_POLL | 587 !(found->u.mgd.flags & (IEEE80211_STA_BEACON_POLL |
555 IEEE80211_STA_CONNECTION_POLL))) { 588 IEEE80211_STA_CONNECTION_POLL))) {
589 struct ieee80211_conf *conf = &local->hw.conf;
556 s32 beaconint_us; 590 s32 beaconint_us;
557 591
558 if (latency < 0) 592 if (latency < 0)
@@ -575,7 +609,10 @@ void ieee80211_recalc_ps(struct ieee80211_local *local, s32 latency)
575 else 609 else
576 timeout = 100; 610 timeout = 100;
577 } 611 }
578 local->hw.conf.dynamic_ps_timeout = timeout; 612 local->dynamic_ps_user_timeout = timeout;
613 if (!local->disable_dynamic_ps)
614 conf->dynamic_ps_timeout =
615 local->dynamic_ps_user_timeout;
579 616
580 if (beaconint_us > latency) { 617 if (beaconint_us > latency) {
581 local->ps_sdata = NULL; 618 local->ps_sdata = NULL;