diff options
Diffstat (limited to 'net/mac80211/util.c')
-rw-r--r-- | net/mac80211/util.c | 82 |
1 files changed, 27 insertions, 55 deletions
diff --git a/net/mac80211/util.c b/net/mac80211/util.c index 7d737071dedb..b732e219b107 100644 --- a/net/mac80211/util.c +++ b/net/mac80211/util.c | |||
@@ -1618,68 +1618,24 @@ void ieee80211_resume_disconnect(struct ieee80211_vif *vif) | |||
1618 | } | 1618 | } |
1619 | EXPORT_SYMBOL_GPL(ieee80211_resume_disconnect); | 1619 | EXPORT_SYMBOL_GPL(ieee80211_resume_disconnect); |
1620 | 1620 | ||
1621 | static int check_mgd_smps(struct ieee80211_if_managed *ifmgd, | 1621 | void ieee80211_recalc_smps(struct ieee80211_sub_if_data *sdata) |
1622 | enum ieee80211_smps_mode *smps_mode) | ||
1623 | { | 1622 | { |
1624 | if (ifmgd->associated) { | 1623 | struct ieee80211_local *local = sdata->local; |
1625 | *smps_mode = ifmgd->ap_smps; | 1624 | struct ieee80211_chanctx_conf *chanctx_conf; |
1626 | 1625 | struct ieee80211_chanctx *chanctx; | |
1627 | if (*smps_mode == IEEE80211_SMPS_AUTOMATIC) { | ||
1628 | if (ifmgd->powersave) | ||
1629 | *smps_mode = IEEE80211_SMPS_DYNAMIC; | ||
1630 | else | ||
1631 | *smps_mode = IEEE80211_SMPS_OFF; | ||
1632 | } | ||
1633 | |||
1634 | return 1; | ||
1635 | } | ||
1636 | |||
1637 | return 0; | ||
1638 | } | ||
1639 | |||
1640 | void ieee80211_recalc_smps(struct ieee80211_local *local) | ||
1641 | { | ||
1642 | struct ieee80211_sub_if_data *sdata; | ||
1643 | enum ieee80211_smps_mode smps_mode = IEEE80211_SMPS_OFF; | ||
1644 | int count = 0; | ||
1645 | |||
1646 | mutex_lock(&local->iflist_mtx); | ||
1647 | |||
1648 | /* | ||
1649 | * This function could be improved to handle multiple | ||
1650 | * interfaces better, but right now it makes any | ||
1651 | * non-station interfaces force SM PS to be turned | ||
1652 | * off. If there are multiple station interfaces it | ||
1653 | * could also use the best possible mode, e.g. if | ||
1654 | * one is in static and the other in dynamic then | ||
1655 | * dynamic is ok. | ||
1656 | */ | ||
1657 | |||
1658 | list_for_each_entry(sdata, &local->interfaces, list) { | ||
1659 | if (!ieee80211_sdata_running(sdata)) | ||
1660 | continue; | ||
1661 | if (sdata->vif.type == NL80211_IFTYPE_P2P_DEVICE) | ||
1662 | continue; | ||
1663 | if (sdata->vif.type != NL80211_IFTYPE_STATION) | ||
1664 | goto set; | ||
1665 | 1626 | ||
1666 | count += check_mgd_smps(&sdata->u.mgd, &smps_mode); | 1627 | mutex_lock(&local->chanctx_mtx); |
1667 | 1628 | ||
1668 | if (count > 1) { | 1629 | chanctx_conf = rcu_dereference_protected(sdata->vif.chanctx_conf, |
1669 | smps_mode = IEEE80211_SMPS_OFF; | 1630 | lockdep_is_held(&local->chanctx_mtx)); |
1670 | break; | ||
1671 | } | ||
1672 | } | ||
1673 | 1631 | ||
1674 | if (smps_mode == local->smps_mode) | 1632 | if (WARN_ON_ONCE(!chanctx_conf)) |
1675 | goto unlock; | 1633 | goto unlock; |
1676 | 1634 | ||
1677 | set: | 1635 | chanctx = container_of(chanctx_conf, struct ieee80211_chanctx, conf); |
1678 | local->smps_mode = smps_mode; | 1636 | ieee80211_recalc_smps_chanctx(local, chanctx); |
1679 | /* changed flag is auto-detected for this */ | ||
1680 | ieee80211_hw_config(local, 0); | ||
1681 | unlock: | 1637 | unlock: |
1682 | mutex_unlock(&local->iflist_mtx); | 1638 | mutex_unlock(&local->chanctx_mtx); |
1683 | } | 1639 | } |
1684 | 1640 | ||
1685 | static bool ieee80211_id_in_list(const u8 *ids, int n_ids, u8 id) | 1641 | static bool ieee80211_id_in_list(const u8 *ids, int n_ids, u8 id) |
@@ -1978,3 +1934,19 @@ int ieee80211_ave_rssi(struct ieee80211_vif *vif) | |||
1978 | return ifmgd->ave_beacon_signal; | 1934 | return ifmgd->ave_beacon_signal; |
1979 | } | 1935 | } |
1980 | EXPORT_SYMBOL_GPL(ieee80211_ave_rssi); | 1936 | EXPORT_SYMBOL_GPL(ieee80211_ave_rssi); |
1937 | |||
1938 | u8 ieee80211_mcs_to_chains(const struct ieee80211_mcs_info *mcs) | ||
1939 | { | ||
1940 | if (!mcs) | ||
1941 | return 1; | ||
1942 | |||
1943 | /* TODO: consider rx_highest */ | ||
1944 | |||
1945 | if (mcs->rx_mask[3]) | ||
1946 | return 4; | ||
1947 | if (mcs->rx_mask[2]) | ||
1948 | return 3; | ||
1949 | if (mcs->rx_mask[1]) | ||
1950 | return 2; | ||
1951 | return 1; | ||
1952 | } | ||