aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--include/net/mac80211.h13
-rw-r--r--net/mac80211/ht.c13
-rw-r--r--net/mac80211/rate.h12
3 files changed, 38 insertions, 0 deletions
diff --git a/include/net/mac80211.h b/include/net/mac80211.h
index 31fd8bab2173..e01c63aad66c 100644
--- a/include/net/mac80211.h
+++ b/include/net/mac80211.h
@@ -1975,6 +1975,16 @@ struct ieee80211_sta *ieee80211_find_sta(struct ieee80211_hw *hw,
1975/* Rate control API */ 1975/* Rate control API */
1976 1976
1977/** 1977/**
1978 * enum rate_control_changed - flags to indicate which parameter changed
1979 *
1980 * @IEEE80211_RC_HT_CHANGED: The HT parameters of the operating channel have
1981 * changed, rate control algorithm can update its internal state if needed.
1982 */
1983enum rate_control_changed {
1984 IEEE80211_RC_HT_CHANGED = BIT(0)
1985};
1986
1987/**
1978 * struct ieee80211_tx_rate_control - rate control information for/from RC algo 1988 * struct ieee80211_tx_rate_control - rate control information for/from RC algo
1979 * 1989 *
1980 * @hw: The hardware the algorithm is invoked for. 1990 * @hw: The hardware the algorithm is invoked for.
@@ -2010,6 +2020,9 @@ struct rate_control_ops {
2010 void *(*alloc_sta)(void *priv, struct ieee80211_sta *sta, gfp_t gfp); 2020 void *(*alloc_sta)(void *priv, struct ieee80211_sta *sta, gfp_t gfp);
2011 void (*rate_init)(void *priv, struct ieee80211_supported_band *sband, 2021 void (*rate_init)(void *priv, struct ieee80211_supported_band *sband,
2012 struct ieee80211_sta *sta, void *priv_sta); 2022 struct ieee80211_sta *sta, void *priv_sta);
2023 void (*rate_update)(void *priv, struct ieee80211_supported_band *sband,
2024 struct ieee80211_sta *sta,
2025 void *priv_sta, u32 changed);
2013 void (*free_sta)(void *priv, struct ieee80211_sta *sta, 2026 void (*free_sta)(void *priv, struct ieee80211_sta *sta,
2014 void *priv_sta); 2027 void *priv_sta);
2015 2028
diff --git a/net/mac80211/ht.c b/net/mac80211/ht.c
index 69b6e9a4df3d..4e3c72f20de7 100644
--- a/net/mac80211/ht.c
+++ b/net/mac80211/ht.c
@@ -17,6 +17,7 @@
17#include <net/wireless.h> 17#include <net/wireless.h>
18#include <net/mac80211.h> 18#include <net/mac80211.h>
19#include "ieee80211_i.h" 19#include "ieee80211_i.h"
20#include "rate.h"
20 21
21void ieee80211_ht_cap_ie_to_sta_ht_cap(struct ieee80211_supported_band *sband, 22void ieee80211_ht_cap_ie_to_sta_ht_cap(struct ieee80211_supported_band *sband,
22 struct ieee80211_ht_cap *ht_cap_ie, 23 struct ieee80211_ht_cap *ht_cap_ie,
@@ -93,7 +94,9 @@ u32 ieee80211_enable_ht(struct ieee80211_sub_if_data *sdata,
93{ 94{
94 struct ieee80211_local *local = sdata->local; 95 struct ieee80211_local *local = sdata->local;
95 struct ieee80211_supported_band *sband; 96 struct ieee80211_supported_band *sband;
97 struct ieee80211_if_managed *ifmgd = &sdata->u.mgd;
96 struct ieee80211_bss_ht_conf ht; 98 struct ieee80211_bss_ht_conf ht;
99 struct sta_info *sta;
97 u32 changed = 0; 100 u32 changed = 0;
98 bool enable_ht = true, ht_changed; 101 bool enable_ht = true, ht_changed;
99 enum nl80211_channel_type channel_type = NL80211_CHAN_NO_HT; 102 enum nl80211_channel_type channel_type = NL80211_CHAN_NO_HT;
@@ -136,6 +139,16 @@ u32 ieee80211_enable_ht(struct ieee80211_sub_if_data *sdata,
136 if (ht_changed) { 139 if (ht_changed) {
137 /* channel_type change automatically detected */ 140 /* channel_type change automatically detected */
138 ieee80211_hw_config(local, 0); 141 ieee80211_hw_config(local, 0);
142
143 rcu_read_lock();
144
145 sta = sta_info_get(local, ifmgd->bssid);
146 if (sta)
147 rate_control_rate_update(local, sband, sta,
148 IEEE80211_RC_HT_CHANGED);
149
150 rcu_read_unlock();
151
139 } 152 }
140 153
141 /* disable HT */ 154 /* disable HT */
diff --git a/net/mac80211/rate.h b/net/mac80211/rate.h
index 928da625e281..b9164c9a9563 100644
--- a/net/mac80211/rate.h
+++ b/net/mac80211/rate.h
@@ -62,6 +62,18 @@ static inline void rate_control_rate_init(struct sta_info *sta)
62 ref->ops->rate_init(ref->priv, sband, ista, priv_sta); 62 ref->ops->rate_init(ref->priv, sband, ista, priv_sta);
63} 63}
64 64
65static inline void rate_control_rate_update(struct ieee80211_local *local,
66 struct ieee80211_supported_band *sband,
67 struct sta_info *sta, u32 changed)
68{
69 struct rate_control_ref *ref = local->rate_ctrl;
70 struct ieee80211_sta *ista = &sta->sta;
71 void *priv_sta = sta->rate_ctrl_priv;
72
73 if (ref->ops->rate_update)
74 ref->ops->rate_update(ref->priv, sband, ista,
75 priv_sta, changed);
76}
65 77
66static inline void *rate_control_alloc_sta(struct rate_control_ref *ref, 78static inline void *rate_control_alloc_sta(struct rate_control_ref *ref,
67 struct ieee80211_sta *sta, 79 struct ieee80211_sta *sta,