mac80211: Fix HT rate control configuration
authorSujith <Sujith.Manoharan@atheros.com>
Mon, 1 Mar 2010 09:12:57 +0000 (14:42 +0530)
committerJohn W. Linville <linville@tuxdriver.com>
Wed, 3 Mar 2010 20:39:21 +0000 (15:39 -0500)
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>
drivers/net/wireless/ath/ath9k/rc.c
include/net/mac80211.h
net/mac80211/mlme.c
net/mac80211/rate.h

index ac34a055c713269c1b6b3cd50aeeb209dbbaedad..0e79e58cf4c96fb4704390645b0974516d995828 100644 (file)
@@ -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,
                            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_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)
                        return;
 
-               if (sc->hw->conf.channel_type == NL80211_CHAN_HT40MINUS ||
-                   sc->hw->conf.channel_type == NL80211_CHAN_HT40PLUS)
+               if (oper_chan_type == NL80211_CHAN_HT40MINUS ||
+                   oper_chan_type == NL80211_CHAN_HT40PLUS)
                        oper_cw40 = true;
 
                oper_sgi40 = (sta->ht_cap.cap & IEEE80211_HT_CAP_SGI_40) ?
index 80eb7cc42ce94760385537455cbc495d6c3a483c..45d7d44d7cbe401ff92050f31531c2526a774b30 100644 (file)
@@ -2426,7 +2426,8 @@ struct rate_control_ops {
                          struct ieee80211_sta *sta, void *priv_sta);
        void (*rate_update)(void *priv, struct ieee80211_supported_band *sband,
                            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 *priv_sta);
 
index 5a268761e4c5653b541a12f98cc9a96270d1c67e..0ab284c32135b42072da7e409a1856fe871bbd57 100644 (file)
@@ -177,7 +177,8 @@ static u32 ieee80211_enable_ht(struct ieee80211_sub_if_data *sdata,
                sta = sta_info_get(sdata, bssid);
                if (sta)
                        rate_control_rate_update(local, sband, sta,
-                                                IEEE80211_RC_HT_CHANGED);
+                                                IEEE80211_RC_HT_CHANGED,
+                                                local->oper_channel_type);
                rcu_read_unlock();
         }
 
index b6108bca96d4818d9beb23d381986274446ce282..065a96190e32a28409dda91110d929f9690c2f64 100644 (file)
@@ -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,
                                    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 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)
                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,