Skip to contentSkip to conversation

mac80211: remove per band sta supported rates

RFC In review Stanislaw Gruszka 4 participants 11 messages Sep 27, 2011 – Oct 19, 2011

Subsystems (3)
lore
Share & tools
lore
#0 lore raw

RFC 1/1 mac80211: remove per band sta supported rates

It is not possible to connect to remote station on two bands at once, or I'm wrong?

As side effect this patch fix warning in rate_control_send_low (or rather mask the real problem):

https://bugzilla.redhat.com/show_bug.cgi?id=731365

Which may happen when we are just after disassociation and changed channel/band, but still want send some frames (namely delBA) to old sta. Right fix should prevent to change channel before we fully dissassocate, or prevent to send frames after connection is lost, or both, but I don't know how to correctly do this so far.

---
 drivers/net/wireless/ath/ath9k/htc_drv_main.c |    2 +-
 drivers/net/wireless/ath/ath9k/rc.c           |    2 +-
 drivers/net/wireless/iwlegacy/iwl-3945-rs.c   |    6 +++---
 drivers/net/wireless/iwlegacy/iwl-4965-rs.c   |    6 +++---
 drivers/net/wireless/iwlwifi/iwl-agn-rs.c     |    6 +++---
 drivers/net/wireless/mwl8k.c                  |   13 ++++++-------
 drivers/net/wireless/rtlwifi/core.c           |    8 ++++----
 drivers/net/wireless/rtlwifi/rtl8192ce/hw.c   |    8 ++++----
 drivers/net/wireless/rtlwifi/rtl8192de/hw.c   |    8 ++++----
 drivers/net/wireless/rtlwifi/rtl8192se/hw.c   |    8 ++++----
 drivers/net/wireless/wl12xx/cmd.c             |    2 +-
 drivers/net/wireless/wl12xx/main.c            |    2 +-
 include/net/mac80211.h                        |    9 ++++-----
 net/mac80211/cfg.c                            |    2 +-
 net/mac80211/ibss.c                           |    8 ++++----
 net/mac80211/mesh_plink.c                     |    4 ++--
 net/mac80211/mlme.c                           |    2 +-
 net/mac80211/rate.c                           |    2 +-
 net/mac80211/rc80211_minstrel.c               |    2 +-
 net/mac80211/rc80211_pid_algo.c               |    9 ++++-----
 20 files changed, 53 insertions(+), 56 deletions(-)
drivers/net/wireless/ath/ath9k/htc_drv_main.c +1 -1
index 495fdf6..bc0af82 100644
@@ -602,7 +602,7 @@ static void ath9k_htc_setup_rate(struct ath9k_htc_priv *priv,
 	sband = priv->hw->wiphy->bands[priv->hw->conf.channel->band];
 
 	for (i = 0, j = 0; i < sband->n_bitrates; i++) {
-		if (sta->supp_rates[sband->band] & BIT(i)) {
+		if (sta->supp_rates & BIT(i)) {
 			trate->rates.legacy_rates.rs_rates[j]
 				= (sband->bitrates[i].bitrate * 2) / 10;
 			j++;
drivers/net/wireless/ath/ath9k/rc.c +1 -1
index 4f13018..6d264d5 100644
@@ -1406,7 +1406,7 @@ static void ath_rate_init(void *priv, struct ieee80211_supported_band *sband,
 	int i, j = 0;
 
 	for (i = 0; i < sband->n_bitrates; i++) {
-		if (sta->supp_rates[sband->band] & BIT(i)) {
+		if (sta->supp_rates & BIT(i)) {
 			ath_rc_priv->neg_rates.rs_rates[j]
 				= (sband->bitrates[i].bitrate * 2) / 10;
 			j++;
drivers/net/wireless/iwlegacy/iwl-3945-rs.c +3 -3
index 8faeaf2..0d65706 100644
@@ -373,13 +373,13 @@ void iwl3945_rs_rate_init(struct iwl_priv *priv, struct ieee80211_sta *sta, u8 s
 	 * after assoc.. */
 
 	for (i = sband->n_bitrates - 1; i >= 0; i--) {
-		if (sta->supp_rates[sband->band] & (1 << i)) {
+		if (sta->supp_rates & (1 << i)) {
 			rs_sta->last_txrate_idx = i;
 			break;
 		}
 	}
 
-	priv->_3945.sta_supp_rates = sta->supp_rates[sband->band];
+	priv->_3945.sta_supp_rates = sta->supp_rates;
 	/* For 5 GHz band it start at IWL_FIRST_OFDM_RATE */
 	if (sband->band == IEEE80211_BAND_5GHZ) {
 		rs_sta->last_txrate_idx += IWL_FIRST_OFDM_RATE;
@@ -659,7 +659,7 @@ static void iwl3945_rs_get_rate(void *priv_r, struct ieee80211_sta *sta,
 	if (rate_control_send_low(sta, priv_sta, txrc))
 		return;
 
-	rate_mask = sta->supp_rates[sband->band];
+	rate_mask = sta->supp_rates;
 
 	/* get user max rate if set */
 	max_rate_idx = txrc->max_rate_idx;
drivers/net/wireless/iwlegacy/iwl-4965-rs.c +3 -3
index 57ebe21..d4731fc 100644
@@ -989,7 +989,7 @@ iwl4965_rs_tx_status(void *priv_r, struct ieee80211_supported_band *sband,
 	lq_sta->last_rate_n_flags = tx_rate;
 done:
 	/* See if there's a better rate or modulation mode to try. */
-	if (sta && sta->supp_rates[sband->band])
+	if (sta && sta->supp_rates)
 		iwl4965_rs_rate_scale_perform(priv, skb, sta, lq_sta);
 }
 
@@ -1794,7 +1794,7 @@ static void iwl4965_rs_rate_scale_perform(struct iwl_priv *priv,
 	if (!sta || !lq_sta)
 		return;
 
-	lq_sta->supp_rates = sta->supp_rates[lq_sta->band];
+	lq_sta->supp_rates = sta->supp_rates;
 
 	tid = iwl4965_rs_tl_add_packet(lq_sta, hdr);
 	if ((tid != MAX_TID_COUNT) && (lq_sta->tx_agg_tid_en & (1 << tid))) {
@@ -2359,7 +2359,7 @@ iwl4965_rs_rate_init(struct iwl_priv *priv,
 					&lq_sta->lq_info[j].win[i]);
 
 	lq_sta->flush_timer = 0;
-	lq_sta->supp_rates = sta->supp_rates[sband->band];
+	lq_sta->supp_rates = sta->supp_rates;
 	for (j = 0; j < LQ_SIZE; j++)
 		for (i = 0; i < IWL_RATE_COUNT; i++)
 			iwl4965_rs_rate_scale_clear_window(
drivers/net/wireless/iwlwifi/iwl-agn-rs.c +3 -3
index c14f8d6..c2cb9f6 100644
@@ -1079,7 +1079,7 @@ static void rs_tx_status(void *priv_r, struct ieee80211_supported_band *sband,
 	lq_sta->last_rate_n_flags = tx_rate;
 done:
 	/* See if there's a better rate or modulation mode to try. */
-	if (sta && sta->supp_rates[sband->band])
+	if (sta && sta->supp_rates)
 		rs_rate_scale_perform(priv, skb, sta, lq_sta);
 
 #if defined(CONFIG_MAC80211_DEBUGFS) && defined(CONFIG_IWLWIFI_DEVICE_SVTOOL)
@@ -2276,7 +2276,7 @@ static void rs_rate_scale_perform(struct iwl_priv *priv,
 	if (!sta || !lq_sta)
 		return;
 
-	lq_sta->supp_rates = sta->supp_rates[lq_sta->band];
+	lq_sta->supp_rates = sta->supp_rates;
 
 	tid = rs_tl_add_packet(lq_sta, hdr);
 	if ((tid != IWL_MAX_TID_COUNT) &&
@@ -2848,7 +2848,7 @@ void iwl_rs_rate_init(struct iwl_priv *priv, struct ieee80211_sta *sta, u8 sta_i
 			rs_rate_scale_clear_window(&lq_sta->lq_info[j].win[i]);
 
 	lq_sta->flush_timer = 0;
-	lq_sta->supp_rates = sta->supp_rates[sband->band];
+	lq_sta->supp_rates = sta->supp_rates;
 	for (j = 0; j < LQ_SIZE; j++)
 		for (i = 0; i < IWL_RATE_COUNT; i++)
 			rs_rate_scale_clear_window(&lq_sta->lq_info[j].win[i]);
drivers/net/wireless/mwl8k.c +6 -7
index ea1395a..f6a82bd 100644
@@ -3776,9 +3776,9 @@ static int mwl8k_cmd_set_new_stn_add(struct ieee80211_hw *hw,
 	cmd->stn_id = cpu_to_le16(sta->aid);
 	cmd->action = cpu_to_le16(MWL8K_STA_ACTION_ADD);
 	if (hw->conf.channel->band == IEEE80211_BAND_2GHZ)
-		rates = sta->supp_rates[IEEE80211_BAND_2GHZ];
+		rates = sta->supp_rates;
 	else
-		rates = sta->supp_rates[IEEE80211_BAND_5GHZ] << 5;
+		rates = sta->supp_rates << 5;
 	cmd->legacy_rates = cpu_to_le32(rates);
 	if (sta->ht_cap.ht_supported) {
 		cmd->ht_rates[0] = sta->ht_cap.mcs.rx_mask[0];
@@ -4187,9 +4187,9 @@ static int mwl8k_cmd_update_stadb_add(struct ieee80211_hw *hw,
 	p->extended_ht_caps = (sta->ht_cap.ampdu_factor & 3) |
 		((sta->ht_cap.ampdu_density & 7) << 2);
 	if (hw->conf.channel->band == IEEE80211_BAND_2GHZ)
-		rates = sta->supp_rates[IEEE80211_BAND_2GHZ];
+		rates = sta->supp_rates;
 	else
-		rates = sta->supp_rates[IEEE80211_BAND_5GHZ] << 5;
+		rates = sta->supp_rates << 5;
 	legacy_rate_mask_to_array(p->legacy_rates, rates);
 	memcpy(p->ht_rates, sta->ht_cap.mcs.rx_mask, 16);
 	p->interop = 1;
@@ -4601,10 +4601,9 @@ mwl8k_bss_info_changed_sta(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
 		}
 
 		if (hw->conf.channel->band == IEEE80211_BAND_2GHZ) {
-			ap_legacy_rates = ap->supp_rates[IEEE80211_BAND_2GHZ];
+			ap_legacy_rates = ap->supp_rates;
 		} else {
-			ap_legacy_rates =
-				ap->supp_rates[IEEE80211_BAND_5GHZ] << 5;
+			ap_legacy_rates = ap->supp_rates << 5;
 		}
 		memcpy(ap_mcs_rates, ap->ht_cap.mcs.rx_mask, 16);
 
drivers/net/wireless/rtlwifi/core.c +4 -4
index 04c4e9e..67d0df2 100644
@@ -441,7 +441,7 @@ static int rtl_op_sta_add(struct ieee80211_hw *hw,
 		sta_entry = (struct rtl_sta_info *) sta->drv_priv;
 		if (rtlhal->current_bandtype == BAND_ON_2_4G) {
 			sta_entry->wireless_mode = WIRELESS_MODE_G;
-			if (sta->supp_rates[0] <= 0xf)
+			if (sta->supp_rates <= 0xf)
 				sta_entry->wireless_mode = WIRELESS_MODE_B;
 			if (sta->ht_cap.ht_supported)
 				sta_entry->wireless_mode = WIRELESS_MODE_N_24G;
@@ -699,7 +699,7 @@ static void rtl_op_bss_info_changed(struct ieee80211_hw *hw,
 		if (rtlhal->current_bandtype == BAND_ON_5G) {
 			mac->mode = WIRELESS_MODE_A;
 		} else {
-			if (sta->supp_rates[0] <= 0xf)
+			if (sta->supp_rates <= 0xf)
 				mac->mode = WIRELESS_MODE_B;
 			else
 				mac->mode = WIRELESS_MODE_G;
@@ -735,9 +735,9 @@ static void rtl_op_bss_info_changed(struct ieee80211_hw *hw,
 			/* for 5G must << RATE_6M_INDEX=4,
 			 * because 5G have no cck rate*/
 			if (rtlhal->current_bandtype == BAND_ON_5G)
-				basic_rates = sta->supp_rates[1] << 4;
+				basic_rates = sta->supp_rates << 4;
 			else
-				basic_rates = sta->supp_rates[0];
+				basic_rates = sta->supp_rates;
 
 			mac->basic_rates = basic_rates;
 			rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_BASIC_RATE,
drivers/net/wireless/rtlwifi/rtl8192ce/hw.c +4 -4
index a3deaef..49fbea6 100644
@@ -1721,9 +1721,9 @@ static void rtl92ce_update_hal_rate_table(struct ieee80211_hw *hw,
 	enum wireless_mode wirelessmode = mac->mode;
 
 	if (rtlhal->current_bandtype == BAND_ON_5G)
-		ratr_value = sta->supp_rates[1] << 4;
+		ratr_value = sta->supp_rates << 4;
 	else
-		ratr_value = sta->supp_rates[0];
+		ratr_value = sta->supp_rates;
 	ratr_value |= (sta->ht_cap.mcs.rx_mask[1] << 20 |
 			sta->ht_cap.mcs.rx_mask[0] << 12);
 	switch (wirelessmode) {
@@ -1825,9 +1825,9 @@ static void rtl92ce_update_hal_rate_mask(struct ieee80211_hw *hw,
 		macid = sta->aid + 1;
 
 	if (rtlhal->current_bandtype == BAND_ON_5G)
-		ratr_bitmap = sta->supp_rates[1] << 4;
+		ratr_bitmap = sta->supp_rates << 4;
 	else
-		ratr_bitmap = sta->supp_rates[0];
+		ratr_bitmap = sta->supp_rates;
 	ratr_bitmap |= (sta->ht_cap.mcs.rx_mask[1] << 20 |
 			sta->ht_cap.mcs.rx_mask[0] << 12);
 	switch (wirelessmode) {
drivers/net/wireless/rtlwifi/rtl8192de/hw.c +4 -4
index 0073cf1..755af01 100644
@@ -1902,9 +1902,9 @@ static void rtl92de_update_hal_rate_table(struct ieee80211_hw *hw,
 	enum wireless_mode wirelessmode = mac->mode;
 
 	if (rtlhal->current_bandtype == BAND_ON_5G)
-		ratr_value = sta->supp_rates[1] << 4;
+		ratr_value = sta->supp_rates << 4;
 	else
-		ratr_value = sta->supp_rates[0];
+		ratr_value = sta->supp_rates;
 	ratr_value |= (sta->ht_cap.mcs.rx_mask[1] << 20 |
 		       sta->ht_cap.mcs.rx_mask[0] << 12);
 	switch (wirelessmode) {
@@ -1995,9 +1995,9 @@ static void rtl92de_update_hal_rate_mask(struct ieee80211_hw *hw,
 		macid = sta->aid + 1;
 
 	if (rtlhal->current_bandtype == BAND_ON_5G)
-		ratr_bitmap = sta->supp_rates[1] << 4;
+		ratr_bitmap = sta->supp_rates << 4;
 	else
-		ratr_bitmap = sta->supp_rates[0];
+		ratr_bitmap = sta->supp_rates;
 	ratr_bitmap |= (sta->ht_cap.mcs.rx_mask[1] << 20 |
 			sta->ht_cap.mcs.rx_mask[0] << 12);
 	switch (wirelessmode) {
drivers/net/wireless/rtlwifi/rtl8192se/hw.c +4 -4
index d59f66c..a48df97 100644
@@ -1997,9 +1997,9 @@ static void rtl92se_update_hal_rate_table(struct ieee80211_hw *hw,
 	enum wireless_mode wirelessmode = mac->mode;
 
 	if (rtlhal->current_bandtype == BAND_ON_5G)
-		ratr_value = sta->supp_rates[1] << 4;
+		ratr_value = sta->supp_rates << 4;
 	else
-		ratr_value = sta->supp_rates[0];
+		ratr_value = sta->supp_rates;
 	ratr_value |= (sta->ht_cap.mcs.rx_mask[1] << 20 |
 			sta->ht_cap.mcs.rx_mask[0] << 12);
 	switch (wirelessmode) {
@@ -2111,9 +2111,9 @@ static void rtl92se_update_hal_rate_mask(struct ieee80211_hw *hw,
 		macid = sta->aid + 1;
 
 	if (rtlhal->current_bandtype == BAND_ON_5G)
-		ratr_bitmap = sta->supp_rates[1] << 4;
+		ratr_bitmap = sta->supp_rates << 4;
 	else
-		ratr_bitmap = sta->supp_rates[0];
+		ratr_bitmap = sta->supp_rates;
 	ratr_bitmap |= (sta->ht_cap.mcs.rx_mask[1] << 20 |
 			sta->ht_cap.mcs.rx_mask[0] << 12);
 	switch (wirelessmode) {
drivers/net/wireless/wl12xx/cmd.c +1 -1
index 084262f..7dc4c04 100644
@@ -1437,7 +1437,7 @@ int wl12xx_cmd_add_peer(struct wl1271 *wl, struct ieee80211_sta *sta, u8 hlid)
 		else
 			cmd->psd_type[i] = WL1271_PSD_LEGACY;
 
-	sta_rates = sta->supp_rates[wl->band];
+	sta_rates = sta->supp_rates;
 	if (sta->ht_cap.ht_supported)
 		sta_rates |= sta->ht_cap.mcs.rx_mask[0] << HW_HT_RATES_OFFSET;
 
drivers/net/wireless/wl12xx/main.c +1 -1
index 680f558..69c5c41 100644
@@ -3340,7 +3340,7 @@ static void wl1271_bss_info_changed_sta(struct wl1271 *wl,
 			goto sta_not_found;
 
 		/* save the supp_rates of the ap */
-		sta_rate_set = sta->supp_rates[wl->hw->conf.channel->band];
+		sta_rate_set = sta->supp_rates;
 		if (sta->ht_cap.ht_supported)
 			sta_rate_set |=
 			    (sta->ht_cap.mcs.rx_mask[0] << HW_HT_RATES_OFFSET);
include/net/mac80211.h +4 -5
index c0f63fd..76bc230 100644
@@ -960,7 +960,7 @@ enum set_key_cmd {
  * @max_sp: max Service Period. Only valid if wme is supported.
  */
 struct ieee80211_sta {
-	u32 supp_rates[IEEE80211_NUM_BANDS];
+	u32 supp_rates;
 	u8 addr[ETH_ALEN];
 	u16 aid;
 	struct ieee80211_sta_ht_cap ht_cap;
@@ -3322,10 +3322,9 @@ struct rate_control_ops {
 };
 
 static inline int rate_supported(struct ieee80211_sta *sta,
-				 enum ieee80211_band band,
 				 int index)
 {
-	return (sta == NULL || sta->supp_rates[band] & BIT(index));
+	return (sta == NULL || sta->supp_rates & BIT(index));
 }
 
 /**
@@ -3358,7 +3357,7 @@ rate_lowest_index(struct ieee80211_supported_band *sband,
 	int i;
 
 	for (i = 0; i < sband->n_bitrates; i++)
-		if (rate_supported(sta, sband->band, i))
+		if (rate_supported(sta, i))
 			return i;
 
 	/* warn when we cannot find a rate. */
@@ -3374,7 +3373,7 @@ bool rate_usable_index_exists(struct ieee80211_supported_band *sband,
 	unsigned int i;
 
 	for (i = 0; i < sband->n_bitrates; i++)
-		if (rate_supported(sta, sband->band, i))
+		if (rate_supported(sta, i))
 			return true;
 	return false;
 }
net/mac80211/cfg.c +1 -1
index b57ddf9..0c4649d 100644
@@ -744,7 +744,7 @@ static void sta_apply_parameters(struct ieee80211_local *local,
 					rates |= BIT(j);
 			}
 		}
-		sta->sta.supp_rates[local->oper_channel->band] = rates;
+		sta->sta.supp_rates = rates;
 	}
 
 	if (params->ht_capa)
net/mac80211/ibss.c +4 -4
index 836b275..d787092 100644
@@ -290,12 +290,12 @@ static void ieee80211_rx_bss_info(struct ieee80211_sub_if_data *sdata,
 			if (sta) {
 				u32 prev_rates;
 
-				prev_rates = sta->sta.supp_rates[band];
+				prev_rates = sta->sta.supp_rates;
 				/* make sure mandatory rates are always added */
-				sta->sta.supp_rates[band] = supp_rates |
+				sta->sta.supp_rates = supp_rates |
 					ieee80211_mandatory_rates(local, band);
 
-				if (sta->sta.supp_rates[band] != prev_rates) {
+				if (sta->sta.supp_rates != prev_rates) {
 #ifdef CONFIG_MAC80211_IBSS_DEBUG
 					printk(KERN_DEBUG
 						"%s: updated supp_rates set "
@@ -455,7 +455,7 @@ struct sta_info *ieee80211_ibss_add_sta(struct ieee80211_sub_if_data *sdata,
 	set_sta_flags(sta, WLAN_STA_AUTHORIZED);
 
 	/* make sure mandatory rates are always added */
-	sta->sta.supp_rates[band] = supp_rates |
+	sta->sta.supp_rates = supp_rates |
 			ieee80211_mandatory_rates(local, band);
 
 	rate_control_rate_init(sta);
net/mac80211/mesh_plink.c +2 -2
index 1213a23..8b1ceab 100644
@@ -93,7 +93,7 @@ static struct sta_info *mesh_plink_alloc(struct ieee80211_sub_if_data *sdata,
 		return NULL;
 
 	sta->flags = WLAN_STA_AUTHORIZED | WLAN_STA_AUTH | WLAN_STA_WME;
-	sta->sta.supp_rates[local->hw.conf.channel->band] = rates;
+	sta->sta.supp_rates = rates;
 	rate_control_rate_init(sta);
 
 	return sta;
@@ -269,7 +269,7 @@ void mesh_neighbour_update(u8 *hw_addr, u32 rates,
 	}
 
 	sta->last_rx = jiffies;
-	sta->sta.supp_rates[local->hw.conf.channel->band] = rates;
+	sta->sta.supp_rates = rates;
 	if (mesh_peer_accepts_plinks(elems) &&
 			sta->plink_state == NL80211_PLINK_LISTEN &&
 			sdata->u.mesh.accepting_plinks &&
net/mac80211/mlme.c +1 -1
index 1a59fb6..58e961e 100644
@@ -1555,7 +1555,7 @@ static bool ieee80211_assoc_success(struct ieee80211_work *wk,
 		}
 	}
 
-	sta->sta.supp_rates[wk->chan->band] = rates;
+	sta->sta.supp_rates = rates;
 	sdata->vif.bss_conf.basic_rates = basic_rates;
 
 	/* cf. IEEE 802.11 9.2.12 */
net/mac80211/rate.c +1 -1
index 3d5a2cb..aa38625 100644
@@ -331,7 +331,7 @@ void rate_control_get_rate(struct ieee80211_sub_if_data *sdata,
 	if (mask != (1 << txrc->sband->n_bitrates) - 1) {
 		if (sta) {
 			/* Filter out rates that the STA does not support */
-			mask &= sta->sta.supp_rates[info->band];
+			mask &= sta->sta.supp_rates;
 		}
 		/*
 		 * Make sure the rate index selected for each TX rate is
net/mac80211/rc80211_minstrel.c +1 -1
index 58a8955..4565a3c 100644
@@ -395,7 +395,7 @@ minstrel_rate_init(void *priv, struct ieee80211_supported_band *sband,
 		unsigned int tx_time_single;
 		unsigned int cw = mp->cw_min;
 
-		if (!rate_supported(sta, sband->band, i))
+		if (!rate_supported(sta, i))
 			continue;
 		n++;
 		memset(mr, 0, sizeof(*mr));
net/mac80211/rc80211_pid_algo.c +4 -5
index aeda654..bb235b5 100644
@@ -74,10 +74,9 @@ static void rate_control_pid_adjust_rate(struct ieee80211_supported_band *sband,
 					 struct rc_pid_sta_info *spinfo, int adj,
 					 struct rc_pid_rateinfo *rinfo)
 {
-	int cur_sorted, new_sorted, probe, tmp, n_bitrates, band;
+	int cur_sorted, new_sorted, probe, tmp, n_bitrates;
 	int cur = spinfo->txrate_idx;
 
-	band = sband->band;
 	n_bitrates = sband->n_bitrates;
 
 	/* Map passed arguments to sorted values. */
@@ -96,19 +95,19 @@ static void rate_control_pid_adjust_rate(struct ieee80211_supported_band *sband,
 		/* Ensure that the rate decrease isn't disadvantageous. */
 		for (probe = cur_sorted; probe >= new_sorted; probe--)
 			if (rinfo[probe].diff <= rinfo[cur_sorted].diff &&
-			    rate_supported(sta, band, rinfo[probe].index))
+			    rate_supported(sta, rinfo[probe].index))
 				tmp = probe;
 	} else {
 		/* Look for rate increase with zero (or below) cost. */
 		for (probe = new_sorted + 1; probe < n_bitrates; probe++)
 			if (rinfo[probe].diff <= rinfo[new_sorted].diff &&
-			    rate_supported(sta, band, rinfo[probe].index))
+			    rate_supported(sta, rinfo[probe].index))
 				tmp = probe;
 	}
 
 	/* Fit the rate found to the nearest supported rate. */
 	do {
-		if (rate_supported(sta, band, rinfo[tmp].index)) {
+		if (rate_supported(sta, rinfo[tmp].index)) {
 			spinfo->txrate_idx = rinfo[tmp].index;
 			break;
 		}
Signature · 1 line
1.7.1
maintainer
#1 lore raw
Quoted 2 lines · Stanislaw Gruszka

It is not possible to connect to remote station on two bands at once, or I'm wrong?

I don't think it is, but there could be channel switches maybe?

Quoted 10 lines

As side effect this patch fix warning in rate_control_send_low (or rather mask the real problem):

https://bugzilla.redhat.com/show_bug.cgi?id=731365

Which may happen when we are just after disassociation and changed channel/band, but still want send some frames (namely delBA) to old sta. Right fix should prevent to change channel before we fully dissassocate, or prevent to send frames after connection is lost, or both, but I don't know how to correctly do this so far.

Well, either we should simply not send the frame, or send it before disassoc, no?

johannes

#2 lore raw
Quoted 5 lines · Johannes Berg
Quoted 2 lines · Stanislaw Gruszka

It is not possible to connect to remote station on two bands at once, or I'm wrong?

I don't think it is, but there could be channel switches maybe?

If AP would like to change to different band, it will need provide new Supported Rates element, or operate on older one.

So this could be simplified, but from other hand this helps to catch bugs, so maybe would be better to keep it. As long some other warning would be added to check that we send on proper channel.

Quoted 5 lines
Quoted 5 lines

As side effect this patch fix warning in rate_control_send_low (or rather mask the real problem):

https://bugzilla.redhat.com/show_bug.cgi?id=731365

Quoted 8 lines
Quoted 5 lines

Which may happen when we are just after disassociation and changed channel/band, but still want send some frames (namely delBA) to old sta. Right fix should prevent to change channel before we fully dissassocate, or prevent to send frames after connection is lost, or both, but I don't know how to correctly do this so far.

Well, either we should simply not send the frame, or send it before disassoc, no?

I think I can fix this that way, but I'm not sure if that would be right fix either. We have few instances of warning:

1) started at ieee80211_sta_connection_lost()
https://bugzilla.redhat.com/show_bug.cgi?id=731365#c0
could be fixed by:
ieee80211_set_disassoc(..., false);
ieee80211_send_deauth_disassoc(, false);

2) started at ieee80211_tx_status()
https://bugzilla.redhat.com/show_bug.cgi?id=731365#c11
could be fixed by adding association check before
ieee80211_send_bar()

3) started at ieee80211_offchannel_return()
https://bugzilla.redhat.com/show_bug.cgi?id=737993#c0
no idea how to fix

All these problems looks like channel switching issue -
- we changed channel, whereas we should still operate on old one. Fedora 15 users start to report that WARNING after update to 3.0 from 2.6.38, so this could be related to Ben offchannel work.

Stanislaw

maintainer
#3 lore raw
Quoted 5 lines · Stanislaw Gruszka
Quoted 4 lines · Johannes Berg
Quoted 2 lines · Stanislaw Gruszka

It is not possible to connect to remote station on two bands at once, or I'm wrong?

Quoted 8 lines
Quoted 1 line

I don't think it is, but there could be channel switches maybe?

If AP would like to change to different band, it will need provide new Supported Rates element, or operate on older one.

So this could be simplified, but from other hand this helps to catch bugs, so maybe would be better to keep it. As long some other warning would be added to check that we send on proper channel.

Yeah I was going to say ... the main purpose of this these days seems to be catching this tx-on-wrong-band (which should be channel) ...

Quoted 11 lines
Quoted 8 lines
Quoted 5 lines

Which may happen when we are just after disassociation and changed channel/band, but still want send some frames (namely delBA) to old sta. Right fix should prevent to change channel before we fully dissassocate, or prevent to send frames after connection is lost, or both, but I don't know how to correctly do this so far.

Well, either we should simply not send the frame, or send it before disassoc, no?

I think I can fix this that way, but I'm not sure if that would be right fix either. We have few instances of warning:

I think that would be the right fix. In some cases, we may want to reorder things instead of just not sending frames.

Quoted 5 lines

1) started at ieee80211_sta_connection_lost()
https://bugzilla.redhat.com/show_bug.cgi?id=731365#c0
could be fixed by:
ieee80211_set_disassoc(..., false);
ieee80211_send_deauth_disassoc(, false);

Why would this trigger the problem? Can we somehow lose connection while already trying to connect to a new AP?

Quoted 4 lines

2) started at ieee80211_tx_status()
https://bugzilla.redhat.com/show_bug.cgi?id=731365#c11
could be fixed by adding association check before
ieee80211_send_bar()

That seems reasonable. No use in trying to tear down BA sessions when we're already disconnected.

Quoted 3 lines

3) started at ieee80211_offchannel_return()
https://bugzilla.redhat.com/show_bug.cgi?id=737993#c0
no idea how to fix

Hm, seems like maybe offchannel return is telling the AP that we woke up, but maybe the offchannel work disconnected or something?

Quoted 4 lines

All these problems looks like channel switching issue -
- we changed channel, whereas we should still operate on old one. Fedora 15 users start to report that WARNING after update to 3.0 from 2.6.38, so this could be related to Ben offchannel work.

That's very well possible.

Thanks for looking into all this!

johannes

#4 lore raw
Quoted 11 lines · Johannes Berg
Quoted 10 lines · Stanislaw Gruszka
Quoted 5 lines · Johannes Berg
Quoted 2 lines · Stanislaw Gruszka

It is not possible to connect to remote station on two bands at once, or I'm wrong?

I don't think it is, but there could be channel switches maybe?

If AP would like to change to different band, it will need provide new Supported Rates element, or operate on older one.

Quoted 6 lines
Quoted 3 lines

So this could be simplified, but from other hand this helps to catch bugs, so maybe would be better to keep it. As long some other warning would be added to check that we send on proper channel.

Yeah I was going to say ... the main purpose of this these days seems to be catching this tx-on-wrong-band (which should be channel) ...

There is a old patch from Luis, which add channel to sta_info,
http://www.spinics.net/lists/linux-wireless/msg56399.html
I could incorporate it into my sta->supp_rates[BAND] removal patch, so we will not loose debuggability, but event extend it.

Quoted 15 lines
Quoted 11 lines
Quoted 8 lines
Quoted 5 lines

Which may happen when we are just after disassociation and changed channel/band, but still want send some frames (namely delBA) to old sta. Right fix should prevent to change channel before we fully dissassocate, or prevent to send frames after connection is lost, or both, but I don't know how to correctly do this so far.

Well, either we should simply not send the frame, or send it before disassoc, no?

I think I can fix this that way, but I'm not sure if that would be right fix either. We have few instances of warning:

I think that would be the right fix. In some cases, we may want to reorder things instead of just not sending frames.

Quoted 8 lines
Quoted 5 lines

1) started at ieee80211_sta_connection_lost()
https://bugzilla.redhat.com/show_bug.cgi?id=731365#c0
could be fixed by:
ieee80211_set_disassoc(..., false);
ieee80211_send_deauth_disassoc(, false);

Why would this trigger the problem? Can we somehow lose connection while already trying to connect to a new AP?

Not sure if I understand. I think that change should not influence new AP connection. Also if we really loose connection to old AP, not sending deauth/disassoc frames does not matter. It can have matter if for some reason old AP start to become available again, so we properly disassociate. But for such corner case we should rather not care.

Quoted 15 lines
Quoted 4 lines

2) started at ieee80211_tx_status()
https://bugzilla.redhat.com/show_bug.cgi?id=731365#c11
could be fixed by adding association check before
ieee80211_send_bar()

That seems reasonable. No use in trying to tear down BA sessions when we're already disconnected.

Quoted 3 lines

3) started at ieee80211_offchannel_return()
https://bugzilla.redhat.com/show_bug.cgi?id=737993#c0
no idea how to fix

Hm, seems like maybe offchannel return is telling the AP that we woke up, but maybe the offchannel work disconnected or something?

Quoted 8 lines
Quoted 4 lines

All these problems looks like channel switching issue -
- we changed channel, whereas we should still operate on old one. Fedora 15 users start to report that WARNING after update to 3.0 from 2.6.38, so this could be related to Ben offchannel work.

That's very well possible.

Thanks for looking into all this!

Unfortunately problem is not reproducible for me, so I can not debug. I'm currently review channel switching on mac80211, to try to understand how things work. Hopefully I'll be able to send reasonable patches soon.

Stanislaw

maintainer
#5 lore raw
Quoted 7 lines · Stanislaw Gruszka
Quoted 2 lines

Yeah I was going to say ... the main purpose of this these days seems to be catching this tx-on-wrong-band (which should be channel) ...

There is a old patch from Luis, which add channel to sta_info,
http://www.spinics.net/lists/linux-wireless/msg56399.html
I could incorporate it into my sta->supp_rates[BAND] removal patch, so we will not loose debuggability, but event extend it.

That seems tricky with CSA, I'm not sure I'd want to go there?

Quoted 6 lines
Quoted 6 lines
Quoted 5 lines

1) started at ieee80211_sta_connection_lost()
https://bugzilla.redhat.com/show_bug.cgi?id=731365#c0
could be fixed by:
ieee80211_set_disassoc(..., false);
ieee80211_send_deauth_disassoc(, false);

Quoted 8 lines
Quoted 2 lines

Why would this trigger the problem? Can we somehow lose connection while already trying to connect to a new AP?

Not sure if I understand. I think that change should not influence new AP connection. Also if we really loose connection to old AP, not sending deauth/disassoc frames does not matter. It can have matter if for some reason old AP start to become available again, so we properly disassociate. But for such corner case we should rather not care.

True, but I'm not sure I understand how we can even run into the problem in this scenario. How can we be on a different band when detecting that the AP went away? No wonder it went away then ... we're on the wrong band?!

johannes

#6 lore raw

RFC 1/1 mac80211: properly go back to operational channel?

For local->tmp_channel == NULL and local->scan_channel == NULL ieee80211_cfg_on_oper_channel() will return false if local->oper_channel != local->hw.conf.channel,
hece we do not properly go back to oper_channel from tmp_channel.

Does patch have sense? Could it fixes problems we are talking in this thread?

net/mac80211/work.c +1 -1
index af374fa..98bf1fa 100644
@@ -1101,7 +1101,7 @@ static void ieee80211_work_work(struct work_struct *work)
 		 * we still need to do a hardware config.  Currently,
 		 * we cannot be here while scanning, however.
 		 */
-		if (ieee80211_cfg_on_oper_channel(local) && !on_oper_chan)
+		if (!on_oper_chan)
 			ieee80211_hw_config(local, 0);
 
 		/* At the least, we need to disable offchannel_ps,
maintainer
#7 lore raw

Re: [RFC] mac80211: properly go back to operational channel?

Quoted 4 lines · Stanislaw Gruszka

For local->tmp_channel == NULL and local->scan_channel == NULL ieee80211_cfg_on_oper_channel() will return false if local->oper_channel != local->hw.conf.channel,
hece we do not properly go back to oper_channel from tmp_channel.

Huh, good catch.

Quoted 1 line

Does patch have sense?

Let's see what Ben says. It seems a bit like the ieee80211_cfg_on_oper_channel() test there should be inverted instead of removed?

Quoted 2 lines

Could it fixes problems we are talking
in this thread?

Yes, could be related, also some issue Jouni and Reinette have been seeing with P2P might be related as well.

johannes

#8 lore raw

Re: [RFC] mac80211: properly go back to operational channel?

Quoted 14 lines · Johannes Berg
Quoted 4 lines · Stanislaw Gruszka

For local->tmp_channel == NULL and local->scan_channel == NULL ieee80211_cfg_on_oper_channel() will return false if local->oper_channel != local->hw.conf.channel,
hece we do not properly go back to oper_channel from tmp_channel.

Huh, good catch.

Quoted 1 line

Does patch have sense?

Let's see what Ben says. It seems a bit like the ieee80211_cfg_on_oper_channel() test there should be inverted instead of removed?

Quoted 5 lines
Quoted 2 lines

Could it fixes problems we are talking
in this thread?

Yes, could be related, also some issue Jouni and Reinette have been seeing with P2P might be related as well.

Just remembered this old patch, also related to this part:
http://news.gmane.org/find-root.php?message_id=%3c1311607763%2d12603%2d3%2dgit%2dsend%2demail%2deliad%40wizery.com%3e

- Felix

#9 lore raw

Re: [RFC] mac80211: properly go back to operational channel?

Quoted 15 lines · Felix Fietkau
Quoted 14 lines · Johannes Berg
Quoted 4 lines · Stanislaw Gruszka

For local->tmp_channel == NULL and local->scan_channel == NULL ieee80211_cfg_on_oper_channel() will return false if local->oper_channel != local->hw.conf.channel,
hece we do not properly go back to oper_channel from tmp_channel.

Huh, good catch.

Quoted 1 line

Does patch have sense?

Let's see what Ben says. It seems a bit like the ieee80211_cfg_on_oper_channel() test there should be inverted instead of removed?

Quoted 7 lines
Quoted 5 lines
Quoted 2 lines

Could it fixes problems we are talking
in this thread?

Yes, could be related, also some issue Jouni and Reinette have been seeing with P2P might be related as well.

Just remembered this old patch, also related to this part:
http://news.gmane.org/find-root.php?message_id=%3c1311607763%2d12603%2d3%2dgit%2dsend%2demail%2deliad%40wizery.com%3e

I thought that patch was going into the kernel.

I'm busy this morning, but I'm hacking on wifi later today if all goes well, so I can test out this patch.

Thanks,
Ben

Quoted 2 lines

- Felix

Signature · 2 lines
Ben Greear <[email protected]>
Candela Technologies Inc  http://www.candelatech.com
#10 lore raw

Re: [RFC] mac80211: properly go back to operational channel?

In reply to Johannes Berg
Quoted 14 lines · Johannes Berg
Quoted 4 lines · Stanislaw Gruszka

For local->tmp_channel == NULL and local->scan_channel == NULL ieee80211_cfg_on_oper_channel() will return false if local->oper_channel != local->hw.conf.channel,
hece we do not properly go back to oper_channel from tmp_channel.

Huh, good catch.

Quoted 1 line

Does patch have sense?

Let's see what Ben says. It seems a bit like the ieee80211_cfg_on_oper_channel() test there should be inverted instead of removed?

Quoted 5 lines
Quoted 2 lines

Could it fixes problems we are talking
in this thread?

Yes, could be related, also some issue Jouni and Reinette have been seeing with P2P might be related as well.

Please see the patch I just posted. I think it fixes the issue (which was originally reported by
Eliad Peller <[email protected]>, who also posted a patch). I re-worked his suggested patch to what I believe is a more proper patch.

Also, Eliad had posted another patch that seems to be good as is (which I also just re-posted).

Obviously, my tests cases are not catching all of these issues, so please review the patches and/or test them out to see if they fix the problem.

Thanks,
Ben

Quoted 3 lines

johannes

Signature · 2 lines
Ben Greear <[email protected]>
Candela Technologies Inc  http://www.candelatech.com