mac80211: remove channel type argument from rate_update
authorJohannes Berg <johannes.berg@intel.com>
Wed, 28 Mar 2012 08:58:37 +0000 (10:58 +0200)
committerJohn W. Linville <linville@tuxdriver.com>
Tue, 10 Apr 2012 18:54:08 +0000 (14:54 -0400)
The channel type argument to the rate_update()
callback isn't really the correct way to give
the rate control algorithm about the desired
RX bandwidth of the peer.

Remove this argument, and instead update the
STA capabilities with 20/40 appropriately. The
SMPS update done by this callback works in the
same way, so this makes the callback cleaner.

Signed-off-by: Johannes Berg <johannes.berg@intel.com>
Signed-off-by: John W. Linville <linville@tuxdriver.com>
drivers/net/wireless/ath/ath9k/rc.c
drivers/net/wireless/rtlwifi/rc.c
include/net/mac80211.h
net/mac80211/chan.c
net/mac80211/ieee80211_i.h
net/mac80211/mlme.c
net/mac80211/rate.h
net/mac80211/rc80211_minstrel_ht.c
net/mac80211/rx.c
net/mac80211/sta_info.h

index 4f848493fece320edb8d8ce45619fb4a5f09538a..4e39f27af07737be4f3647cf5d91b5d7102f9463 100644 (file)
@@ -1436,7 +1436,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, enum nl80211_channel_type oper_chan_type)
+                           u32 changed)
 {
        struct ath_softc *sc = priv;
        struct ath_rate_priv *ath_rc_priv = priv_sta;
@@ -1451,8 +1451,7 @@ static void ath_rate_update(void *priv, struct ieee80211_supported_band *sband,
                if (sc->sc_ah->opmode != NL80211_IFTYPE_STATION)
                        return;
 
-               if (oper_chan_type == NL80211_CHAN_HT40MINUS ||
-                   oper_chan_type == NL80211_CHAN_HT40PLUS)
+               if (sta->ht_cap.cap & IEEE80211_HT_CAP_SUP_WIDTH_20_40)
                        oper_cw40 = true;
 
                if (oper_cw40)
index c66f08a0524ac6f839c7b69ae7c6d6c16884d157..d5cbf01da8ac0de8a1d04fd2ae7502b67d03ab47 100644 (file)
@@ -225,8 +225,7 @@ static void rtl_rate_init(void *ppriv,
 static void rtl_rate_update(void *ppriv,
                            struct ieee80211_supported_band *sband,
                            struct ieee80211_sta *sta, void *priv_sta,
-                           u32 changed,
-                           enum nl80211_channel_type oper_chan_type)
+                           u32 changed)
 {
 }
 
index 81cb66c3989ed1b0c91debeb34e40a6455b3662a..21c653415d8495e0b7220a6b77e620ce976600e8 100644 (file)
@@ -3569,9 +3569,8 @@ struct rate_control_ops {
        void (*rate_init)(void *priv, struct ieee80211_supported_band *sband,
                          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,
-                           enum nl80211_channel_type oper_chan_type);
+                           struct ieee80211_sta *sta, void *priv_sta,
+                           u32 changed);
        void (*free_sta)(void *priv, struct ieee80211_sta *sta,
                         void *priv_sta);
 
index e00ce8c3e28e431c4232a1441ee2b0b2eeb3d480..c76cf7230c7db06c646c4b13b14b46bf670a0afa 100644 (file)
@@ -135,29 +135,3 @@ bool ieee80211_set_channel_type(struct ieee80211_local *local,
 
        return result;
 }
-
-/*
- * ieee80211_get_tx_channel_type returns the channel type we should
- * use for packet transmission, given the channel capability and
- * whatever regulatory flags we have been given.
- */
-enum nl80211_channel_type ieee80211_get_tx_channel_type(
-                               struct ieee80211_local *local,
-                               enum nl80211_channel_type channel_type)
-{
-       switch (channel_type) {
-       case NL80211_CHAN_HT40PLUS:
-               if (local->hw.conf.channel->flags &
-                               IEEE80211_CHAN_NO_HT40PLUS)
-                       return NL80211_CHAN_HT20;
-               break;
-       case NL80211_CHAN_HT40MINUS:
-               if (local->hw.conf.channel->flags &
-                               IEEE80211_CHAN_NO_HT40MINUS)
-                       return NL80211_CHAN_HT20;
-               break;
-       default:
-               break;
-       }
-       return channel_type;
-}
index a67ba7c85a1ed49864038105a087e90078e5c6fa..867b8eec1e9e8516ccf45c547808170502af0aa7 100644 (file)
@@ -512,8 +512,6 @@ struct ieee80211_if_managed {
        int rssi_min_thold, rssi_max_thold;
        int last_ave_beacon_signal;
 
-       enum nl80211_channel_type tx_chantype;
-
        struct ieee80211_ht_cap ht_capa; /* configured ht-cap over-rides */
        struct ieee80211_ht_cap ht_capa_mask; /* Valid parts of ht_capa */
 };
@@ -1501,9 +1499,6 @@ bool ieee80211_set_channel_type(struct ieee80211_local *local,
                                enum nl80211_channel_type chantype);
 enum nl80211_channel_type
 ieee80211_ht_oper_to_channel_type(struct ieee80211_ht_operation *ht_oper);
-enum nl80211_channel_type ieee80211_get_tx_channel_type(
-                                       struct ieee80211_local *local,
-                                       enum nl80211_channel_type channel_type);
 
 #ifdef CONFIG_MAC80211_NOINLINE
 #define debug_noinline noinline
index 30259a73195c5ea01896e8a118c29be839f46269..9cc5dda682191af3d66e30f7d49f18d53586087e 100644 (file)
@@ -180,21 +180,38 @@ static u32 ieee80211_config_ht_tx(struct ieee80211_sub_if_data *sdata,
        struct sta_info *sta;
        u32 changed = 0;
        u16 ht_opmode;
-       enum nl80211_channel_type channel_type;
+       bool disable_40 = false;
 
        sband = local->hw.wiphy->bands[local->hw.conf.channel->band];
-       channel_type = local->hw.conf.channel_type;
 
-       if (WARN_ON_ONCE(channel_type == NL80211_CHAN_NO_HT))
-               return 0;
-
-       channel_type = ieee80211_get_tx_channel_type(local, channel_type);
+       switch (sdata->vif.bss_conf.channel_type) {
+       case NL80211_CHAN_HT40PLUS:
+               if (local->hw.conf.channel->flags & IEEE80211_CHAN_NO_HT40PLUS)
+                       disable_40 = true;
+               break;
+       case NL80211_CHAN_HT40MINUS:
+               if (local->hw.conf.channel->flags & IEEE80211_CHAN_NO_HT40MINUS)
+                       disable_40 = true;
+               break;
+       default:
+               break;
+       }
 
        /* This can change during the lifetime of the BSS */
        if (!(ht_oper->ht_param & IEEE80211_HT_PARAM_CHAN_WIDTH_ANY))
-               channel_type = NL80211_CHAN_HT20;
+               disable_40 = true;
 
-       if (!reconfig || (sdata->u.mgd.tx_chantype != channel_type)) {
+       mutex_lock(&local->sta_mtx);
+       sta = sta_info_get(sdata, bssid);
+
+       WARN_ON_ONCE(!sta);
+
+       if (sta && !sta->supports_40mhz)
+               disable_40 = true;
+
+       if (sta && (!reconfig ||
+                   (disable_40 != !!(sta->sta.ht_cap.cap &
+                                       IEEE80211_HT_CAP_SUP_WIDTH_20_40)))) {
                if (reconfig) {
                        /*
                         * Whenever the AP announces the HT mode changed
@@ -211,20 +228,19 @@ static u32 ieee80211_config_ht_tx(struct ieee80211_sub_if_data *sdata,
                        drv_flush(local, false);
                }
 
-               rcu_read_lock();
-               sta = sta_info_get(sdata, bssid);
-               if (sta)
-                       rate_control_rate_update(local, sband, sta,
-                                                IEEE80211_RC_HT_CHANGED,
-                                                channel_type);
-               rcu_read_unlock();
+               if (disable_40)
+                       sta->sta.ht_cap.cap &= ~IEEE80211_HT_CAP_SUP_WIDTH_20_40;
+               else
+                       sta->sta.ht_cap.cap |= IEEE80211_HT_CAP_SUP_WIDTH_20_40;
 
-               sdata->u.mgd.tx_chantype = channel_type;
+               rate_control_rate_update(local, sband, sta,
+                                        IEEE80211_RC_HT_CHANGED);
 
                if (reconfig)
                        ieee80211_wake_queues_by_reason(&sdata->local->hw,
                                IEEE80211_QUEUE_STOP_REASON_CHTYPE_CHANGE);
        }
+       mutex_unlock(&local->sta_mtx);
 
        ht_opmode = le16_to_cpu(ht_oper->operation_mode);
 
@@ -2006,6 +2022,9 @@ static bool ieee80211_assoc_success(struct ieee80211_sub_if_data *sdata,
                ieee80211_ht_cap_ie_to_sta_ht_cap(sdata, sband,
                                elems.ht_cap_elem, &sta->sta.ht_cap);
 
+       sta->supports_40mhz =
+               sta->sta.ht_cap.cap & IEEE80211_HT_CAP_SUP_WIDTH_20_40;
+
        rate_control_rate_init(sta);
 
        if (ifmgd->flags & IEEE80211_STA_MFP_ENABLED)
index fbb1efdc4d04152237648c0faf48a887a4eab65d..27b66be8ac8f0e8e3de553bec386729b46f4424e 100644 (file)
@@ -63,8 +63,7 @@ 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,
-                                   enum nl80211_channel_type oper_chan_type)
+                                   struct sta_info *sta, u32 changed)
 {
        struct rate_control_ref *ref = local->rate_ctrl;
        struct ieee80211_sta *ista = &sta->sta;
@@ -72,7 +71,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, oper_chan_type);
+                                     priv_sta, changed);
 }
 
 static inline void *rate_control_alloc_sta(struct rate_control_ref *ref,
index 16e0b277b9a865f440a734f2ff1f44ec267d0219..3b3dcae13bbc77bbd9280955eda1321a1b6a4729 100644 (file)
@@ -686,8 +686,7 @@ minstrel_ht_get_rate(void *priv, struct ieee80211_sta *sta, void *priv_sta,
 
 static void
 minstrel_ht_update_caps(void *priv, struct ieee80211_supported_band *sband,
-                        struct ieee80211_sta *sta, void *priv_sta,
-                       enum nl80211_channel_type oper_chan_type)
+                        struct ieee80211_sta *sta, void *priv_sta)
 {
        struct minstrel_priv *mp = priv;
        struct minstrel_ht_sta_priv *msp = priv_sta;
@@ -735,10 +734,6 @@ minstrel_ht_update_caps(void *priv, struct ieee80211_supported_band *sband,
        if (sta_cap & IEEE80211_HT_CAP_LDPC_CODING)
                mi->tx_flags |= IEEE80211_TX_CTL_LDPC;
 
-       if (oper_chan_type != NL80211_CHAN_HT40MINUS &&
-           oper_chan_type != NL80211_CHAN_HT40PLUS)
-               sta_cap &= ~IEEE80211_HT_CAP_SUP_WIDTH_20_40;
-
        smps = (sta_cap & IEEE80211_HT_CAP_SM_PS) >>
                IEEE80211_HT_CAP_SM_PS_SHIFT;
 
@@ -788,17 +783,15 @@ static void
 minstrel_ht_rate_init(void *priv, struct ieee80211_supported_band *sband,
                       struct ieee80211_sta *sta, void *priv_sta)
 {
-       struct minstrel_priv *mp = priv;
-
-       minstrel_ht_update_caps(priv, sband, sta, priv_sta, mp->hw->conf.channel_type);
+       minstrel_ht_update_caps(priv, sband, sta, priv_sta);
 }
 
 static void
 minstrel_ht_rate_update(void *priv, struct ieee80211_supported_band *sband,
                         struct ieee80211_sta *sta, void *priv_sta,
-                        u32 changed, enum nl80211_channel_type oper_chan_type)
+                        u32 changed)
 {
-       minstrel_ht_update_caps(priv, sband, sta, priv_sta, oper_chan_type);
+       minstrel_ht_update_caps(priv, sband, sta, priv_sta);
 }
 
 static void *
index 8da3b36c287aa12020443863b74c4fa34a92d148..54a049123a60c5747bda8b0b1f1913205e1f12da 100644 (file)
@@ -2268,11 +2268,8 @@ ieee80211_rx_h_action(struct ieee80211_rx_data *rx)
 
                        sband = rx->local->hw.wiphy->bands[status->band];
 
-                       rate_control_rate_update(
-                               local, sband, rx->sta,
-                               IEEE80211_RC_SMPS_CHANGED,
-                               ieee80211_get_tx_channel_type(
-                                       local, local->_oper_channel_type));
+                       rate_control_rate_update(local, sband, rx->sta,
+                                                IEEE80211_RC_SMPS_CHANGED);
                        goto handled;
                }
                default:
index e21652bccf7cb798f92107cbc9898acd4078cd33..b1b4b1413c74c5a64660f7a339ffe2f7e385bf96 100644 (file)
@@ -369,6 +369,8 @@ struct sta_info {
        unsigned int lost_packets;
        unsigned int beacon_loss_count;
 
+       bool supports_40mhz;
+
        /* keep last! */
        struct ieee80211_sta sta;
 };