mac80211: Fix HT rate control configuration
Handling HT configuration changes involved setting the channel with the new HT parameters and then issuing a rate_update() notification to the driver. This behavior changed after the off-channel changes. Now, the channel is not updated with the new HT params in enable_ht() - instead, it is now done when the scan work terminates. This results in the driver depending on stale information, defaulting to non-HT mode always. Fix this by passing the new channel type to the driver. Cc: stable@kernel.org Signed-off-by: Sujith <Sujith.Manoharan@atheros.com> Signed-off-by: John W. Linville <linville@tuxdriver.com>
This commit is contained in:
parent
b08dfd0435
commit
4fa0043731
|
@ -1323,7 +1323,7 @@ static void ath_rate_init(void *priv, struct ieee80211_supported_band *sband,
|
||||||
|
|
||||||
static void ath_rate_update(void *priv, struct ieee80211_supported_band *sband,
|
static void ath_rate_update(void *priv, struct ieee80211_supported_band *sband,
|
||||||
struct ieee80211_sta *sta, void *priv_sta,
|
struct ieee80211_sta *sta, void *priv_sta,
|
||||||
u32 changed)
|
u32 changed, enum nl80211_channel_type oper_chan_type)
|
||||||
{
|
{
|
||||||
struct ath_softc *sc = priv;
|
struct ath_softc *sc = priv;
|
||||||
struct ath_rate_priv *ath_rc_priv = priv_sta;
|
struct ath_rate_priv *ath_rc_priv = priv_sta;
|
||||||
|
@ -1340,8 +1340,8 @@ static void ath_rate_update(void *priv, struct ieee80211_supported_band *sband,
|
||||||
if (sc->sc_ah->opmode != NL80211_IFTYPE_STATION)
|
if (sc->sc_ah->opmode != NL80211_IFTYPE_STATION)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (sc->hw->conf.channel_type == NL80211_CHAN_HT40MINUS ||
|
if (oper_chan_type == NL80211_CHAN_HT40MINUS ||
|
||||||
sc->hw->conf.channel_type == NL80211_CHAN_HT40PLUS)
|
oper_chan_type == NL80211_CHAN_HT40PLUS)
|
||||||
oper_cw40 = true;
|
oper_cw40 = true;
|
||||||
|
|
||||||
oper_sgi40 = (sta->ht_cap.cap & IEEE80211_HT_CAP_SGI_40) ?
|
oper_sgi40 = (sta->ht_cap.cap & IEEE80211_HT_CAP_SGI_40) ?
|
||||||
|
|
|
@ -2426,7 +2426,8 @@ struct rate_control_ops {
|
||||||
struct ieee80211_sta *sta, void *priv_sta);
|
struct ieee80211_sta *sta, void *priv_sta);
|
||||||
void (*rate_update)(void *priv, struct ieee80211_supported_band *sband,
|
void (*rate_update)(void *priv, struct ieee80211_supported_band *sband,
|
||||||
struct ieee80211_sta *sta,
|
struct ieee80211_sta *sta,
|
||||||
void *priv_sta, u32 changed);
|
void *priv_sta, u32 changed,
|
||||||
|
enum nl80211_channel_type oper_chan_type);
|
||||||
void (*free_sta)(void *priv, struct ieee80211_sta *sta,
|
void (*free_sta)(void *priv, struct ieee80211_sta *sta,
|
||||||
void *priv_sta);
|
void *priv_sta);
|
||||||
|
|
||||||
|
|
|
@ -177,7 +177,8 @@ static u32 ieee80211_enable_ht(struct ieee80211_sub_if_data *sdata,
|
||||||
sta = sta_info_get(sdata, bssid);
|
sta = sta_info_get(sdata, bssid);
|
||||||
if (sta)
|
if (sta)
|
||||||
rate_control_rate_update(local, sband, sta,
|
rate_control_rate_update(local, sband, sta,
|
||||||
IEEE80211_RC_HT_CHANGED);
|
IEEE80211_RC_HT_CHANGED,
|
||||||
|
local->oper_channel_type);
|
||||||
rcu_read_unlock();
|
rcu_read_unlock();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -66,7 +66,8 @@ static inline void rate_control_rate_init(struct sta_info *sta)
|
||||||
|
|
||||||
static inline void rate_control_rate_update(struct ieee80211_local *local,
|
static inline void rate_control_rate_update(struct ieee80211_local *local,
|
||||||
struct ieee80211_supported_band *sband,
|
struct ieee80211_supported_band *sband,
|
||||||
struct sta_info *sta, u32 changed)
|
struct sta_info *sta, u32 changed,
|
||||||
|
enum nl80211_channel_type oper_chan_type)
|
||||||
{
|
{
|
||||||
struct rate_control_ref *ref = local->rate_ctrl;
|
struct rate_control_ref *ref = local->rate_ctrl;
|
||||||
struct ieee80211_sta *ista = &sta->sta;
|
struct ieee80211_sta *ista = &sta->sta;
|
||||||
|
@ -74,7 +75,7 @@ static inline void rate_control_rate_update(struct ieee80211_local *local,
|
||||||
|
|
||||||
if (ref && ref->ops->rate_update)
|
if (ref && ref->ops->rate_update)
|
||||||
ref->ops->rate_update(ref->priv, sband, ista,
|
ref->ops->rate_update(ref->priv, sband, ista,
|
||||||
priv_sta, changed);
|
priv_sta, changed, oper_chan_type);
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline void *rate_control_alloc_sta(struct rate_control_ref *ref,
|
static inline void *rate_control_alloc_sta(struct rate_control_ref *ref,
|
||||||
|
|
Loading…
Reference in New Issue