2011-09-27 11:14:16

by Stanislaw Gruszka

[permalink] [raw]
Subject: [RFC] 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.

Signed-off-by: Stanislaw Gruszka <[email protected]>
---
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(-)

diff --git a/drivers/net/wireless/ath/ath9k/htc_drv_main.c b/drivers/net/wireless/ath/ath9k/htc_drv_main.c
index 495fdf6..bc0af82 100644
--- a/drivers/net/wireless/ath/ath9k/htc_drv_main.c
+++ b/drivers/net/wireless/ath/ath9k/htc_drv_main.c
@@ -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++;
diff --git a/drivers/net/wireless/ath/ath9k/rc.c b/drivers/net/wireless/ath/ath9k/rc.c
index 4f13018..6d264d5 100644
--- a/drivers/net/wireless/ath/ath9k/rc.c
+++ b/drivers/net/wireless/ath/ath9k/rc.c
@@ -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++;
diff --git a/drivers/net/wireless/iwlegacy/iwl-3945-rs.c b/drivers/net/wireless/iwlegacy/iwl-3945-rs.c
index 8faeaf2..0d65706 100644
--- a/drivers/net/wireless/iwlegacy/iwl-3945-rs.c
+++ b/drivers/net/wireless/iwlegacy/iwl-3945-rs.c
@@ -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;
diff --git a/drivers/net/wireless/iwlegacy/iwl-4965-rs.c b/drivers/net/wireless/iwlegacy/iwl-4965-rs.c
index 57ebe21..d4731fc 100644
--- a/drivers/net/wireless/iwlegacy/iwl-4965-rs.c
+++ b/drivers/net/wireless/iwlegacy/iwl-4965-rs.c
@@ -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(
diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-rs.c b/drivers/net/wireless/iwlwifi/iwl-agn-rs.c
index c14f8d6..c2cb9f6 100644
--- a/drivers/net/wireless/iwlwifi/iwl-agn-rs.c
+++ b/drivers/net/wireless/iwlwifi/iwl-agn-rs.c
@@ -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]);
diff --git a/drivers/net/wireless/mwl8k.c b/drivers/net/wireless/mwl8k.c
index ea1395a..f6a82bd 100644
--- a/drivers/net/wireless/mwl8k.c
+++ b/drivers/net/wireless/mwl8k.c
@@ -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);

diff --git a/drivers/net/wireless/rtlwifi/core.c b/drivers/net/wireless/rtlwifi/core.c
index 04c4e9e..67d0df2 100644
--- a/drivers/net/wireless/rtlwifi/core.c
+++ b/drivers/net/wireless/rtlwifi/core.c
@@ -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,
diff --git a/drivers/net/wireless/rtlwifi/rtl8192ce/hw.c b/drivers/net/wireless/rtlwifi/rtl8192ce/hw.c
index a3deaef..49fbea6 100644
--- a/drivers/net/wireless/rtlwifi/rtl8192ce/hw.c
+++ b/drivers/net/wireless/rtlwifi/rtl8192ce/hw.c
@@ -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) {
diff --git a/drivers/net/wireless/rtlwifi/rtl8192de/hw.c b/drivers/net/wireless/rtlwifi/rtl8192de/hw.c
index 0073cf1..755af01 100644
--- a/drivers/net/wireless/rtlwifi/rtl8192de/hw.c
+++ b/drivers/net/wireless/rtlwifi/rtl8192de/hw.c
@@ -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) {
diff --git a/drivers/net/wireless/rtlwifi/rtl8192se/hw.c b/drivers/net/wireless/rtlwifi/rtl8192se/hw.c
index d59f66c..a48df97 100644
--- a/drivers/net/wireless/rtlwifi/rtl8192se/hw.c
+++ b/drivers/net/wireless/rtlwifi/rtl8192se/hw.c
@@ -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) {
diff --git a/drivers/net/wireless/wl12xx/cmd.c b/drivers/net/wireless/wl12xx/cmd.c
index 084262f..7dc4c04 100644
--- a/drivers/net/wireless/wl12xx/cmd.c
+++ b/drivers/net/wireless/wl12xx/cmd.c
@@ -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;

diff --git a/drivers/net/wireless/wl12xx/main.c b/drivers/net/wireless/wl12xx/main.c
index 680f558..69c5c41 100644
--- a/drivers/net/wireless/wl12xx/main.c
+++ b/drivers/net/wireless/wl12xx/main.c
@@ -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);
diff --git a/include/net/mac80211.h b/include/net/mac80211.h
index c0f63fd..76bc230 100644
--- a/include/net/mac80211.h
+++ b/include/net/mac80211.h
@@ -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;
}
diff --git a/net/mac80211/cfg.c b/net/mac80211/cfg.c
index b57ddf9..0c4649d 100644
--- a/net/mac80211/cfg.c
+++ b/net/mac80211/cfg.c
@@ -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)
diff --git a/net/mac80211/ibss.c b/net/mac80211/ibss.c
index 836b275..d787092 100644
--- a/net/mac80211/ibss.c
+++ b/net/mac80211/ibss.c
@@ -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);
diff --git a/net/mac80211/mesh_plink.c b/net/mac80211/mesh_plink.c
index 1213a23..8b1ceab 100644
--- a/net/mac80211/mesh_plink.c
+++ b/net/mac80211/mesh_plink.c
@@ -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 &&
diff --git a/net/mac80211/mlme.c b/net/mac80211/mlme.c
index 1a59fb6..58e961e 100644
--- a/net/mac80211/mlme.c
+++ b/net/mac80211/mlme.c
@@ -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 */
diff --git a/net/mac80211/rate.c b/net/mac80211/rate.c
index 3d5a2cb..aa38625 100644
--- a/net/mac80211/rate.c
+++ b/net/mac80211/rate.c
@@ -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
diff --git a/net/mac80211/rc80211_minstrel.c b/net/mac80211/rc80211_minstrel.c
index 58a8955..4565a3c 100644
--- a/net/mac80211/rc80211_minstrel.c
+++ b/net/mac80211/rc80211_minstrel.c
@@ -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));
diff --git a/net/mac80211/rc80211_pid_algo.c b/net/mac80211/rc80211_pid_algo.c
index aeda654..bb235b5 100644
--- a/net/mac80211/rc80211_pid_algo.c
+++ b/net/mac80211/rc80211_pid_algo.c
@@ -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;
}
--
1.7.1



2011-09-29 15:02:03

by Stanislaw Gruszka

[permalink] [raw]
Subject: Re: [RFC] mac80211: remove per band sta supported rates

On Tue, Sep 27, 2011 at 01:34:49PM +0200, Johannes Berg wrote:
> On Tue, 2011-09-27 at 13:12 +0200, Stanislaw Gruszka wrote:
> > 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.

> > 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?

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


2011-09-27 11:34:54

by Johannes Berg

[permalink] [raw]
Subject: Re: [RFC] mac80211: remove per band sta supported rates

On Tue, 2011-09-27 at 13:12 +0200, Stanislaw Gruszka wrote:
> 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?

> 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


2011-10-18 14:54:07

by Felix Fietkau

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

On 2011-10-18 4:30 PM, Johannes Berg wrote:
> On Tue, 2011-10-18 at 16:19 +0200, Stanislaw Gruszka wrote:
>> 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.
>
>> 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?
>
>> 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

2011-10-19 18:48:18

by Ben Greear

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

On 10/18/2011 07:30 AM, Johannes Berg wrote:
> On Tue, 2011-10-18 at 16:19 +0200, Stanislaw Gruszka wrote:
>> 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.
>
>> 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?
>
>> 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

>
> johannes
>


--
Ben Greear <[email protected]>
Candela Technologies Inc http://www.candelatech.com


2011-10-04 15:07:08

by Johannes Berg

[permalink] [raw]
Subject: Re: [RFC] mac80211: remove per band sta supported rates

On Thu, 2011-09-29 at 17:00 +0200, Stanislaw Gruszka wrote:
> On Tue, Sep 27, 2011 at 01:34:49PM +0200, Johannes Berg wrote:
> > On Tue, 2011-09-27 at 13:12 +0200, Stanislaw Gruszka wrote:
> > > 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.

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) ...

> > > 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.

> 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?

> 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.

> 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?

> 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


2011-10-05 11:22:46

by Johannes Berg

[permalink] [raw]
Subject: Re: [RFC] mac80211: remove per band sta supported rates

On Wed, 2011-10-05 at 13:15 +0200, Stanislaw Gruszka wrote:

> > 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?

> > > 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.

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


2011-10-18 16:03:21

by Ben Greear

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

On 10/18/2011 07:53 AM, Felix Fietkau wrote:
> On 2011-10-18 4:30 PM, Johannes Berg wrote:
>> On Tue, 2011-10-18 at 16:19 +0200, Stanislaw Gruszka wrote:
>>> 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.
>>
>>> 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?
>>
>>> 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

>
> - Felix


--
Ben Greear <[email protected]>
Candela Technologies Inc http://www.candelatech.com


2011-10-05 11:17:25

by Stanislaw Gruszka

[permalink] [raw]
Subject: Re: [RFC] mac80211: remove per band sta supported rates

On Tue, Oct 04, 2011 at 05:07:04PM +0200, Johannes Berg wrote:
> On Thu, 2011-09-29 at 17:00 +0200, Stanislaw Gruszka wrote:
> > On Tue, Sep 27, 2011 at 01:34:49PM +0200, Johannes Berg wrote:
> > > On Tue, 2011-09-27 at 13:12 +0200, Stanislaw Gruszka wrote:
> > > > 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.
>
> 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.

> > > > 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.
>
> > 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.

> > 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.
>
> > 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?
>
> > 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

2011-10-18 14:20:11

by Stanislaw Gruszka

[permalink] [raw]
Subject: [RFC] 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?

diff --git a/net/mac80211/work.c b/net/mac80211/work.c
index af374fa..98bf1fa 100644
--- a/net/mac80211/work.c
+++ b/net/mac80211/work.c
@@ -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,

2011-10-18 14:30:56

by Johannes Berg

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

On Tue, 2011-10-18 at 16:19 +0200, Stanislaw Gruszka wrote:
> 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.

> 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?

> 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