Search Linux Wireless

[PATCHv4 05/18] cfg80211/mac80211: get mandatory rates based on rate flags

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

 



Mandatory rates for 5 and 10 MHz are different from the rates used for
20 MHz in 2.4 GHz mode, as they use OFDM only.

Signed-off-by: Simon Wunderlich <siwu@xxxxxxxxxxxxxxxxxx>
Signed-off-by: Mathias Kretschmer <mathias.kretschmer@xxxxxxxxxxxxxxxxxxx>
---
 include/net/cfg80211.h |    4 +++-
 net/mac80211/ibss.c    |   21 ++++++++++++++++-----
 net/wireless/mesh.c    |    5 ++++-
 net/wireless/util.c    |   14 ++++++++++----
 4 files changed, 33 insertions(+), 11 deletions(-)

diff --git a/include/net/cfg80211.h b/include/net/cfg80211.h
index 820cce5..a0c5e04 100644
--- a/include/net/cfg80211.h
+++ b/include/net/cfg80211.h
@@ -3069,11 +3069,13 @@ ieee80211_get_response_rate(struct ieee80211_supported_band *sband,
 /**
  * ieee80211_mandatory_rates - get mandatory rates for a given band
  * @sband: the band to look for rates in
+ * @rate_flags: rate flags which may limit the mandatory rates
  *
  * This function returns a bitmap of the mandatory rates for the given
  * band, bits are set according to the rate position in the bitrates array.
  */
-u32 ieee80211_mandatory_rates(struct ieee80211_supported_band *sband);
+u32 ieee80211_mandatory_rates(struct ieee80211_supported_band *sband,
+			      u32 rate_flags);
 
 /*
  * Radiotap parsing functions -- for controlled injection support
diff --git a/net/mac80211/ibss.c b/net/mac80211/ibss.c
index f3171fc..cf66ddc 100644
--- a/net/mac80211/ibss.c
+++ b/net/mac80211/ibss.c
@@ -376,6 +376,7 @@ ieee80211_ibss_add_sta(struct ieee80211_sub_if_data *sdata,
 	struct sta_info *sta;
 	struct ieee80211_chanctx_conf *chanctx_conf;
 	struct ieee80211_supported_band *sband;
+	u32 rate_flags;
 	int band;
 
 	/*
@@ -404,6 +405,7 @@ ieee80211_ibss_add_sta(struct ieee80211_sub_if_data *sdata,
 	if (WARN_ON_ONCE(!chanctx_conf))
 		return NULL;
 	band = chanctx_conf->def.chan->band;
+	rate_flags = ieee80211_chandef_rate_flags(&chanctx_conf->def);
 	rcu_read_unlock();
 
 	sta = sta_info_alloc(sdata, addr, GFP_KERNEL);
@@ -417,7 +419,7 @@ ieee80211_ibss_add_sta(struct ieee80211_sub_if_data *sdata,
 	/* make sure mandatory rates are always added */
 	sband = local->hw.wiphy->bands[band];
 	sta->sta.supp_rates[band] = supp_rates |
-			ieee80211_mandatory_rates(sband);
+			ieee80211_mandatory_rates(sband, rate_flags);
 
 	return ieee80211_ibss_finish_sta(sta, auth);
 }
@@ -497,7 +499,7 @@ static void ieee80211_rx_bss_info(struct ieee80211_sub_if_data *sdata,
 	struct sta_info *sta;
 	struct ieee80211_channel *channel;
 	u64 beacon_timestamp, rx_timestamp;
-	u32 supp_rates = 0;
+	u32 rate_flags, supp_rates = 0;
 	enum ieee80211_band band = rx_status->band;
 	struct ieee80211_supported_band *sband = local->hw.wiphy->bands[band];
 	bool rates_updated = false;
@@ -522,14 +524,21 @@ static void ieee80211_rx_bss_info(struct ieee80211_sub_if_data *sdata,
 		if (elems->supp_rates) {
 			supp_rates = ieee80211_sta_get_rates(sdata, elems,
 							     band, NULL);
+			rate_flags = 0;
+			if (rx_status->flag & RX_FLAG_5MHZ)
+				rate_flags = IEEE80211_RATE_SUPPORTS_5MHZ;
+			if (rx_status->flag & RX_FLAG_10MHZ)
+				rate_flags = IEEE80211_RATE_SUPPORTS_10MHZ;
+
 			if (sta) {
 				u32 prev_rates;
 
 				prev_rates = sta->sta.supp_rates[band];
 				/* make sure mandatory rates are always added */
+
 				sta->sta.supp_rates[band] = supp_rates |
-					ieee80211_mandatory_rates(sband);
-
+					ieee80211_mandatory_rates(sband,
+								  rate_flags);
 				if (sta->sta.supp_rates[band] != prev_rates) {
 					ibss_dbg(sdata,
 						 "updated supp_rates set for %pM based on beacon/probe_resp (0x%x -> 0x%x)\n",
@@ -663,6 +672,7 @@ void ieee80211_ibss_rx_no_sta(struct ieee80211_sub_if_data *sdata,
 	struct sta_info *sta;
 	struct ieee80211_chanctx_conf *chanctx_conf;
 	struct ieee80211_supported_band *sband;
+	u32 rate_flags;
 	int band;
 
 	/*
@@ -688,6 +698,7 @@ void ieee80211_ibss_rx_no_sta(struct ieee80211_sub_if_data *sdata,
 		return;
 	}
 	band = chanctx_conf->def.chan->band;
+	rate_flags = ieee80211_chandef_rate_flags(&chanctx_conf->def);
 	rcu_read_unlock();
 
 	sta = sta_info_alloc(sdata, addr, GFP_ATOMIC);
@@ -699,7 +710,7 @@ void ieee80211_ibss_rx_no_sta(struct ieee80211_sub_if_data *sdata,
 	/* make sure mandatory rates are always added */
 	sband = local->hw.wiphy->bands[band];
 	sta->sta.supp_rates[band] = supp_rates |
-			ieee80211_mandatory_rates(sband);
+			ieee80211_mandatory_rates(sband, rate_flags);
 
 	spin_lock(&ifibss->incomplete_lock);
 	list_add(&sta->list, &ifibss->incomplete_stations);
diff --git a/net/wireless/mesh.c b/net/wireless/mesh.c
index 30c4920..9a529c9 100644
--- a/net/wireless/mesh.c
+++ b/net/wireless/mesh.c
@@ -167,9 +167,12 @@ int __cfg80211_join_mesh(struct cfg80211_registered_device *rdev,
 	 * basic rates
 	 */
 	if (!setup->basic_rates) {
+		u32 rate_flags;
 		struct ieee80211_supported_band *sband =
 				rdev->wiphy.bands[setup->chandef.chan->band];
-		setup->basic_rates = ieee80211_mandatory_rates(sband);
+		rate_flags = ieee80211_chandef_rate_flags(&setup->chandef);
+		setup->basic_rates = ieee80211_mandatory_rates(sband,
+							       rate_flags);
 	}
 
 	if (!cfg80211_reg_can_beacon(&rdev->wiphy, &setup->chandef))
diff --git a/net/wireless/util.c b/net/wireless/util.c
index 74458b7..5f42ab3 100644
--- a/net/wireless/util.c
+++ b/net/wireless/util.c
@@ -33,7 +33,8 @@ ieee80211_get_response_rate(struct ieee80211_supported_band *sband,
 }
 EXPORT_SYMBOL(ieee80211_get_response_rate);
 
-u32 ieee80211_mandatory_rates(struct ieee80211_supported_band *sband)
+u32 ieee80211_mandatory_rates(struct ieee80211_supported_band *sband,
+			      u32 rate_flags)
 {
 	struct ieee80211_rate *bitrates;
 	u32 mandatory_rates = 0;
@@ -43,10 +44,15 @@ u32 ieee80211_mandatory_rates(struct ieee80211_supported_band *sband)
 	if (WARN_ON(!sband))
 		return 1;
 
-	if (sband->band == IEEE80211_BAND_2GHZ)
-		mandatory_flag = IEEE80211_RATE_MANDATORY_B;
-	else
+	if (sband->band == IEEE80211_BAND_2GHZ) {
+		if ((rate_flags & (IEEE80211_RATE_SUPPORTS_5MHZ |
+				   IEEE80211_RATE_SUPPORTS_10MHZ)))
+			mandatory_flag = IEEE80211_RATE_MANDATORY_G;
+		else
+			mandatory_flag = IEEE80211_RATE_MANDATORY_B;
+	} else {
 		mandatory_flag = IEEE80211_RATE_MANDATORY_A;
+	}
 
 	bitrates = sband->bitrates;
 	for (i = 0; i < sband->n_bitrates; i++)
-- 
1.7.10.4

--
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 Wireless Personal Area Network]     [Linux Bluetooth]     [Linux Netdev]     [Kernel Newbies]     [Linux Kernel]     [IDE]     [Git]     [Netfilter]     [Bugtraq]     [Yosemite Hiking]     [MIPS Linux]     [ARM Linux]     [Linux RAID]

  Powered by Linux