Search Linux Wireless

[RFC] mac80211: Fix STA supported rate configuration with dummy entry

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



TDLS adds a STA entry before full information about the STA is
available. This leaves rate control algorithms in pretty odd state.
Avoid this by claiming the lowest rate to be supported if no supported
rates are indicated and then update the rate control again when the rate
set changes.

Signed-off-by: Jouni Malinen <j@xxxxx>
---
 net/mac80211/cfg.c |   18 ++++++++++++++++--
 1 files changed, 16 insertions(+), 2 deletions(-)

Note: Without this, some rate control algorithms can get quite unhappy
with the TDLS entries and maybe other use cases that could result in no
supported rates. For example, minstral has a pretty horrible loop in
init_sample_table() going to n_srates = n_rates(0) - 1...

Are all rate control algorithms fine with the second
rate_control_rate_init() call? That is needed in the TDLS use case where
the supported rate set is known only after the STA entry has been
added. I guess it would be possible to delay addition of the STA entry
for TDLS until the supported rates are known, but I did not look at the
details on what exactly that would require.


diff --git a/net/mac80211/cfg.c b/net/mac80211/cfg.c
index a9ded52..b9dae9d 100644
--- a/net/mac80211/cfg.c
+++ b/net/mac80211/cfg.c
@@ -682,7 +682,7 @@ static void ieee80211_send_layer2_update(struct sta_info *sta)
 	netif_rx_ni(skb);
 }
 
-static void sta_apply_parameters(struct ieee80211_local *local,
+static bool sta_apply_parameters(struct ieee80211_local *local,
 				 struct sta_info *sta,
 				 struct station_parameters *params)
 {
@@ -691,6 +691,7 @@ static void sta_apply_parameters(struct ieee80211_local *local,
 	struct ieee80211_supported_band *sband;
 	struct ieee80211_sub_if_data *sdata = sta->sdata;
 	u32 mask, set;
+	bool supp_rates_changed = false;
 
 	sband = local->hw.wiphy->bands[local->oper_channel->band];
 
@@ -774,6 +775,16 @@ static void sta_apply_parameters(struct ieee80211_local *local,
 					rates |= BIT(j);
 			}
 		}
+		if (rates == 0) {
+			/*
+			 * Rate control algorithms may not like this.. Enable
+			 * the lowest rate even if we do not know the exact
+			 * supported rate set yet.
+			 */
+			rates = BIT(0);
+		}
+		if (sta->sta.supp_rates[local->oper_channel->band] != rates)
+			supp_rates_changed = true;
 		sta->sta.supp_rates[local->oper_channel->band] = rates;
 	}
 
@@ -806,6 +817,8 @@ static void sta_apply_parameters(struct ieee80211_local *local,
 			}
 #endif
 	}
+
+	return supp_rates_changed;
 }
 
 static int ieee80211_add_station(struct wiphy *wiphy, struct net_device *dev,
@@ -929,7 +942,8 @@ static int ieee80211_change_station(struct wiphy *wiphy,
 		ieee80211_send_layer2_update(sta);
 	}
 
-	sta_apply_parameters(local, sta, params);
+	if (sta_apply_parameters(local, sta, params))
+		rate_control_rate_init(sta);
 
 	rcu_read_unlock();
 
-- 
1.7.4.1


-- 
Jouni Malinen                                            PGP id EFC895FA
--
To unsubscribe from this list: send the line "unsubscribe linux-wireless" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[Index of Archives]     [Linux Host AP]     [ATH6KL]     [Linux Bluetooth]     [Linux Netdev]     [Kernel Newbies]     [Linux Kernel]     [IDE]     [Security]     [Git]     [Netfilter]     [Bugtraq]     [Yosemite News]     [MIPS Linux]     [ARM Linux]     [Linux Security]     [Linux RAID]     [Linux ATA RAID]     [Samba]     [Device Mapper]
  Powered by Linux