Skip to contentSkip to conversation

set HT channel first

RFC In review Johannes Berg 2 participants 5 messages Mar 15, 2012

Subsystems (5)
lore
Share & tools
lore

Johannes Berg

author maintainer
#0 lore raw

cover set HT channel first

We talked about this before a bit, and I've started work on it. I'm not sure about the queue stop/flush but it seems very strange to do it now. Rajkumar, can you maybe look into this?

Paul, could you check this in the problem case you were running into?

johannes

author maintainer
#1 lore raw

RFC 1/3 mac80211: set HT channel before association

From: Johannes Berg <[email protected]>

Changing the channel type during operation is confusing to some drivers and will be hard to handle in multi-channel scenarios. Instead of changing the channel, set it to the right HT channel before authenticating/associating and don't change it -- just update the 20/40 MHz restrictions in rate control as needed when changed by the AP.

This also fixes a problem that Paul missed in his fix for the "regulatory makes us deaf" issue -- when we couldn't use 40 MHz we still associated saying we were using 40 MHz, which could in similarly broken APs make us never even connect successfully.

---
 Documentation/networking/mac80211-auth-assoc-deauth.txt |   10 
 net/mac80211/ht.c                                       |    9 
 net/mac80211/ieee80211_i.h                              |   10 
 net/mac80211/mlme.c                                     |  225 +++++++---------
 4 files changed, 117 insertions(+), 137 deletions(-)
net/mac80211/ieee80211_i.h +3 -7
@@ -378,6 +378,7 @@ enum ieee80211_sta_flags {
 	IEEE80211_STA_UAPSD_ENABLED	= BIT(7),
 	IEEE80211_STA_NULLFUNC_ACKED	= BIT(8),
 	IEEE80211_STA_RESET_SIGNAL_AVE	= BIT(9),
+	IEEE80211_STA_DISABLE_40MHZ	= BIT(10),
 };
 
 struct ieee80211_mgd_auth_data {
@@ -497,6 +498,8 @@ 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 */
 };
@@ -653,12 +656,6 @@ struct ieee80211_sub_if_data {
 
 	char name[IFNAMSIZ];
 
-	/*
-	 * keep track of whether the HT opmode (stored in
-	 * vif.bss_info.ht_operation_mode) is valid.
-	 */
-	bool ht_opmode_valid;
-
 	/* to detect idle changes */
 	bool old_idle;
 
@@ -1300,7 +1297,6 @@ netdev_tx_t ieee80211_subif_start_xmit(s
 				       struct net_device *dev);
 
 /* HT */
-bool ieee80111_cfg_override_disables_ht40(struct ieee80211_sub_if_data *sdata);
 void ieee80211_apply_htcap_overrides(struct ieee80211_sub_if_data *sdata,
 				     struct ieee80211_sta_ht_cap *ht_cap);
 void ieee80211_ht_cap_ie_to_sta_ht_cap(struct ieee80211_sub_if_data *sdata,
net/mac80211/mlme.c +111 -114

321 lines not on this page · raw message

net/mac80211/ht.c +0 -9
@@ -19,15 +19,6 @@
 #include "ieee80211_i.h"
 #include "rate.h"
 
-bool ieee80111_cfg_override_disables_ht40(struct ieee80211_sub_if_data *sdata)
-{
-	const __le16 flg = cpu_to_le16(IEEE80211_HT_CAP_SUP_WIDTH_20_40);
-	if ((sdata->u.mgd.ht_capa_mask.cap_info & flg) &&
-	    !(sdata->u.mgd.ht_capa.cap_info & flg))
-		return true;
-	return false;
-}
-
 static void __check_htcap_disable(struct ieee80211_sub_if_data *sdata,
 				  struct ieee80211_sta_ht_cap *ht_cap,
 				  u16 flag)
Documentation/networking/mac80211-auth-assoc-deauth.txt +3 -7
@@ -23,7 +23,7 @@ BA session stop & deauth/disassoc frames
 end note
 end
 
-mac80211->driver: config(channel, non-HT)
+mac80211->driver: config(channel, channel type)
 mac80211->driver: bss_info_changed(set BSSID, basic rate bitmap)
 mac80211->driver: sta_state(AP, exists)
 
@@ -51,7 +51,7 @@ note over mac80211,driver: cleanup like
 end
 
 alt not previously authenticated (FT)
-mac80211->driver: config(channel, non-HT)
+mac80211->driver: config(channel, channel type)
 mac80211->driver: bss_info_changed(set BSSID, basic rate bitmap)
 mac80211->driver: sta_state(AP, exists)
 mac80211->driver: sta_state(AP, authenticated)
@@ -67,10 +67,6 @@ end
 
 mac80211->driver: set up QoS parameters
 
-alt is HT channel
-mac80211->driver: config(channel, HT params)
-end
-
 mac80211->driver: bss_info_changed(QoS, HT, associated with AID)
 mac80211->userspace: associated
 
@@ -95,5 +91,5 @@ mac80211->driver: sta_state(AP,exists)
 mac80211->driver: sta_state(AP,not-exists)
 mac80211->driver: turn off powersave
 mac80211->driver: bss_info_changed(clear BSSID, not associated, no QoS, ...)
-mac80211->driver: config(non-HT channel type)
+mac80211->driver: config(channel type to non-HT)
 mac80211->userspace: disconnected
author maintainer
#2 lore raw

RFC 2/3 mac80211: remove channel type argument from rate_update

In reply to Johannes Berg

From: Johannes Berg <[email protected]>

The channel type

---
 drivers/net/wireless/ath/ath9k/rc.c |    5 +--
 drivers/net/wireless/rtlwifi/rc.c   |    3 --
 include/net/mac80211.h              |    5 +--
 net/mac80211/chan.c                 |   26 ------------------
 net/mac80211/ieee80211_i.h          |    5 ---
 net/mac80211/mlme.c                 |   51 ++++++++++++++++++++++++------------
 net/mac80211/rate.h                 |    5 +--
 net/mac80211/rc80211_minstrel_ht.c  |   15 ++--------
 net/mac80211/rx.c                   |    7 +---
 net/mac80211/sta_info.h             |    2 +
 10 files changed, 50 insertions(+), 74 deletions(-)
include/net/mac80211.h +2 -3
@@ -3567,9 +3567,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);
 
drivers/net/wireless/ath/ath9k/rc.c +2 -3
@@ -1436,7 +1436,7 @@ static void ath_rate_init(void *priv, st
 
 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,
 		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)
net/mac80211/rx.c +2 -5
@@ -2269,11 +2269,8 @@ ieee80211_rx_h_action(struct ieee80211_r
 
 			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:
net/mac80211/mlme.c +35 -16

82 lines not on this page · raw message

net/mac80211/rate.h +2 -3
@@ -63,8 +63,7 @@ static inline void rate_control_rate_ini
 
 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_upd
 
 	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,
net/mac80211/rc80211_minstrel_ht.c +4 -11
@@ -679,8 +679,7 @@ minstrel_ht_get_rate(void *priv, struct
 
 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;
@@ -728,10 +727,6 @@ minstrel_ht_update_caps(void *priv, stru
 	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;
 
@@ -781,17 +776,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 *
drivers/net/wireless/rtlwifi/rc.c +1 -2
@@ -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)
 {
 }
 
net/mac80211/chan.c +0 -26
@@ -135,29 +135,3 @@ bool ieee80211_set_channel_type(struct i
 
 	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;
-}
net/mac80211/ieee80211_i.h +0 -5
@@ -498,8 +498,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 */
 };
@@ -1498,9 +1496,6 @@ bool ieee80211_set_channel_type(struct i
 				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
net/mac80211/sta_info.h +2 -0
@@ -365,6 +365,8 @@ struct sta_info {
 	unsigned int lost_packets;
 	unsigned int beacon_loss_count;
 
+	bool supports_40mhz;
+
 	/* keep last! */
 	struct ieee80211_sta sta;
 };
author maintainer
#3 lore raw

RFC 3/3 mac80211: remove queue stop on rate control update

In reply to Johannes Berg

From: Johannes Berg <[email protected]>

We currently stop the queue when changing the rate control between 20/40 MHz in the BSS. This seems to have been necessary when we actually changed the channel, but now that we just update the station it doesn't seem right any more. Remove it.

---
 net/mac80211/ieee80211_i.h |    1 -
 net/mac80211/mlme.c        |   19 -------------------
 2 files changed, 20 deletions(-)
net/mac80211/ieee80211_i.h +0 -1
@@ -743,7 +743,6 @@ enum queue_stop_reason {
 	IEEE80211_QUEUE_STOP_REASON_AGGREGATION,
 	IEEE80211_QUEUE_STOP_REASON_SUSPEND,
 	IEEE80211_QUEUE_STOP_REASON_SKB_ADD,
-	IEEE80211_QUEUE_STOP_REASON_CHTYPE_CHANGE,
 };
 
 #ifdef CONFIG_MAC80211_LEDS
net/mac80211/mlme.c +0 -19
@@ -212,21 +212,6 @@ static u32 ieee80211_config_ht_tx(struct
 	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
-			 * (e.g. 40 MHz intolerant) stop queues to avoid
-			 * sending out frames while the rate control is
-			 * reconfiguring.
-			 */
-			ieee80211_stop_queues_by_reason(&sdata->local->hw,
-				IEEE80211_QUEUE_STOP_REASON_CHTYPE_CHANGE);
-
-			/* flush out all packets */
-			synchronize_net();
-
-			drv_flush(local, false);
-		}
 
 		if (disable_40)
 			sta->sta.ht_cap.cap &= ~IEEE80211_HT_CAP_SUP_WIDTH_20_40;
@@ -235,10 +220,6 @@ static u32 ieee80211_config_ht_tx(struct
 
 		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);
 
#4 lore raw

RE: [RFC 3/3] mac80211: remove queue stop on rate control update

Quoted 35 lines

From: Johannes Berg <[email protected]>

We currently stop the queue when changing the rate control between 20/40 MHz in the BSS. This seems to have been necessary when we actually changed the channel, but now that we just update the station it doesn't seem right any more. Remove it.

---
 net/mac80211/ieee80211_i.h |    1 -
 net/mac80211/mlme.c        |   19 -------------------
 2 files changed, 20 deletions(-)
net/mac80211/ieee80211_i.h 2012-03-15 16:39:47.000000000 +0100 renamed from net/mac80211/ieee80211_i.h 2012-03-15 16:39:21.000000000 +0100 +0 -1
@@ -743,7 +743,6 @@ enum queue_stop_reason {
        IEEE80211_QUEUE_STOP_REASON_AGGREGATION,
        IEEE80211_QUEUE_STOP_REASON_SUSPEND,
        IEEE80211_QUEUE_STOP_REASON_SKB_ADD,
-       IEEE80211_QUEUE_STOP_REASON_CHTYPE_CHANGE,
 };
 
 #ifdef CONFIG_MAC80211_LEDS
net/mac80211/mlme.c 2012-03-15 16:39:57.000000000 +0100 renamed from net/mac80211/mlme.c 2012-03-15 16:39:21.000000000 +0100 +0 -5
@@ -212,21 +212,6 @@ static u32 ieee80211_config_ht_tx(struct
        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
-                        * (e.g. 40 MHz intolerant) stop queues to avoid
-                        * sending out frames while the rate control is

net/mac80211/mlme.c 2012-03-15 16:39:57.000000000 +0100 static u32 ieee80211_config_ht_tx(struct · line 229

Quoted 10 lines
net/mac80211/mlme.c 2012-03-15 16:39:57.000000000 +0100 renamed from net/mac80211/mlme.c 2012-03-15 16:39:21.000000000 +0100 +0 -10
-                        * reconfiguring.
-                        */
-                       ieee80211_stop_queues_by_reason(&sdata->local->hw,
-                               IEEE80211_QUEUE_STOP_REASON_CHTYPE_CHANGE);
-
-                       /* flush out all packets */
-                       synchronize_net();
-
-                       drv_flush(local, false);
-               }

The queue stop was added to avoid sending frames while the hw reconfigure is in progress. So that we can prevent differences b/w hw and rate control ht mode. But I doubt that hw_reconfig removal could not affect split drivers where the rc is offloaded.

Quoted 13 lines
net/mac80211/mlme.c 2012-03-15 16:39:57.000000000 +0100 renamed from net/mac80211/mlme.c 2012-03-15 16:39:21.000000000 +0100 +0 -4
                if (disable_40)
                        sta->sta.ht_cap.cap &= ~IEEE80211_HT_CAP_SUP_WIDTH_20_40;
@@ -235,10 +220,6 @@ static u32 ieee80211_config_ht_tx(struct
 
                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);