cfg80211/mac80211: get mandatory rates based on scan width
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@hrz.tu-chemnitz.de> Signed-off-by: Mathias Kretschmer <mathias.kretschmer@fokus.fraunhofer.de> Signed-off-by: Johannes Berg <johannes@sipsolutions.net>
This commit is contained in:
committed by
Johannes Berg
parent
2103dec147
commit
74608aca4d
@@ -3128,11 +3128,13 @@ ieee80211_get_response_rate(struct ieee80211_supported_band *sband,
|
|||||||
/**
|
/**
|
||||||
* ieee80211_mandatory_rates - get mandatory rates for a given band
|
* ieee80211_mandatory_rates - get mandatory rates for a given band
|
||||||
* @sband: the band to look for rates in
|
* @sband: the band to look for rates in
|
||||||
|
* @scan_width: width of the control channel
|
||||||
*
|
*
|
||||||
* This function returns a bitmap of the mandatory rates for the given
|
* 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.
|
* 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,
|
||||||
|
enum nl80211_bss_scan_width scan_width);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Radiotap parsing functions -- for controlled injection support
|
* Radiotap parsing functions -- for controlled injection support
|
||||||
|
@@ -371,6 +371,7 @@ ieee80211_ibss_add_sta(struct ieee80211_sub_if_data *sdata, const u8 *bssid,
|
|||||||
struct sta_info *sta;
|
struct sta_info *sta;
|
||||||
struct ieee80211_chanctx_conf *chanctx_conf;
|
struct ieee80211_chanctx_conf *chanctx_conf;
|
||||||
struct ieee80211_supported_band *sband;
|
struct ieee80211_supported_band *sband;
|
||||||
|
enum nl80211_bss_scan_width scan_width;
|
||||||
int band;
|
int band;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -399,6 +400,7 @@ ieee80211_ibss_add_sta(struct ieee80211_sub_if_data *sdata, const u8 *bssid,
|
|||||||
if (WARN_ON_ONCE(!chanctx_conf))
|
if (WARN_ON_ONCE(!chanctx_conf))
|
||||||
return NULL;
|
return NULL;
|
||||||
band = chanctx_conf->def.chan->band;
|
band = chanctx_conf->def.chan->band;
|
||||||
|
scan_width = cfg80211_chandef_to_scan_width(&chanctx_conf->def);
|
||||||
rcu_read_unlock();
|
rcu_read_unlock();
|
||||||
|
|
||||||
sta = sta_info_alloc(sdata, addr, GFP_KERNEL);
|
sta = sta_info_alloc(sdata, addr, GFP_KERNEL);
|
||||||
@@ -412,7 +414,7 @@ ieee80211_ibss_add_sta(struct ieee80211_sub_if_data *sdata, const u8 *bssid,
|
|||||||
/* make sure mandatory rates are always added */
|
/* make sure mandatory rates are always added */
|
||||||
sband = local->hw.wiphy->bands[band];
|
sband = local->hw.wiphy->bands[band];
|
||||||
sta->sta.supp_rates[band] = supp_rates |
|
sta->sta.supp_rates[band] = supp_rates |
|
||||||
ieee80211_mandatory_rates(sband);
|
ieee80211_mandatory_rates(sband, scan_width);
|
||||||
|
|
||||||
return ieee80211_ibss_finish_sta(sta);
|
return ieee80211_ibss_finish_sta(sta);
|
||||||
}
|
}
|
||||||
@@ -476,6 +478,7 @@ static void ieee80211_rx_bss_info(struct ieee80211_sub_if_data *sdata,
|
|||||||
u64 beacon_timestamp, rx_timestamp;
|
u64 beacon_timestamp, rx_timestamp;
|
||||||
u32 supp_rates = 0;
|
u32 supp_rates = 0;
|
||||||
enum ieee80211_band band = rx_status->band;
|
enum ieee80211_band band = rx_status->band;
|
||||||
|
enum nl80211_bss_scan_width scan_width;
|
||||||
struct ieee80211_supported_band *sband = local->hw.wiphy->bands[band];
|
struct ieee80211_supported_band *sband = local->hw.wiphy->bands[band];
|
||||||
bool rates_updated = false;
|
bool rates_updated = false;
|
||||||
|
|
||||||
@@ -504,9 +507,15 @@ static void ieee80211_rx_bss_info(struct ieee80211_sub_if_data *sdata,
|
|||||||
|
|
||||||
prev_rates = sta->sta.supp_rates[band];
|
prev_rates = sta->sta.supp_rates[band];
|
||||||
/* make sure mandatory rates are always added */
|
/* make sure mandatory rates are always added */
|
||||||
sta->sta.supp_rates[band] = supp_rates |
|
scan_width = NL80211_BSS_CHAN_WIDTH_20;
|
||||||
ieee80211_mandatory_rates(sband);
|
if (rx_status->flag & RX_FLAG_5MHZ)
|
||||||
|
scan_width = NL80211_BSS_CHAN_WIDTH_5;
|
||||||
|
if (rx_status->flag & RX_FLAG_10MHZ)
|
||||||
|
scan_width = NL80211_BSS_CHAN_WIDTH_10;
|
||||||
|
|
||||||
|
sta->sta.supp_rates[band] = supp_rates |
|
||||||
|
ieee80211_mandatory_rates(sband,
|
||||||
|
scan_width);
|
||||||
if (sta->sta.supp_rates[band] != prev_rates) {
|
if (sta->sta.supp_rates[band] != prev_rates) {
|
||||||
ibss_dbg(sdata,
|
ibss_dbg(sdata,
|
||||||
"updated supp_rates set for %pM based on beacon/probe_resp (0x%x -> 0x%x)\n",
|
"updated supp_rates set for %pM based on beacon/probe_resp (0x%x -> 0x%x)\n",
|
||||||
@@ -640,6 +649,7 @@ void ieee80211_ibss_rx_no_sta(struct ieee80211_sub_if_data *sdata,
|
|||||||
struct sta_info *sta;
|
struct sta_info *sta;
|
||||||
struct ieee80211_chanctx_conf *chanctx_conf;
|
struct ieee80211_chanctx_conf *chanctx_conf;
|
||||||
struct ieee80211_supported_band *sband;
|
struct ieee80211_supported_band *sband;
|
||||||
|
enum nl80211_bss_scan_width scan_width;
|
||||||
int band;
|
int band;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -665,6 +675,7 @@ void ieee80211_ibss_rx_no_sta(struct ieee80211_sub_if_data *sdata,
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
band = chanctx_conf->def.chan->band;
|
band = chanctx_conf->def.chan->band;
|
||||||
|
scan_width = cfg80211_chandef_to_scan_width(&chanctx_conf->def);
|
||||||
rcu_read_unlock();
|
rcu_read_unlock();
|
||||||
|
|
||||||
sta = sta_info_alloc(sdata, addr, GFP_ATOMIC);
|
sta = sta_info_alloc(sdata, addr, GFP_ATOMIC);
|
||||||
@@ -676,7 +687,7 @@ void ieee80211_ibss_rx_no_sta(struct ieee80211_sub_if_data *sdata,
|
|||||||
/* make sure mandatory rates are always added */
|
/* make sure mandatory rates are always added */
|
||||||
sband = local->hw.wiphy->bands[band];
|
sband = local->hw.wiphy->bands[band];
|
||||||
sta->sta.supp_rates[band] = supp_rates |
|
sta->sta.supp_rates[band] = supp_rates |
|
||||||
ieee80211_mandatory_rates(sband);
|
ieee80211_mandatory_rates(sband, scan_width);
|
||||||
|
|
||||||
spin_lock(&ifibss->incomplete_lock);
|
spin_lock(&ifibss->incomplete_lock);
|
||||||
list_add(&sta->list, &ifibss->incomplete_stations);
|
list_add(&sta->list, &ifibss->incomplete_stations);
|
||||||
|
@@ -167,9 +167,12 @@ int __cfg80211_join_mesh(struct cfg80211_registered_device *rdev,
|
|||||||
* basic rates
|
* basic rates
|
||||||
*/
|
*/
|
||||||
if (!setup->basic_rates) {
|
if (!setup->basic_rates) {
|
||||||
|
enum nl80211_bss_scan_width scan_width;
|
||||||
struct ieee80211_supported_band *sband =
|
struct ieee80211_supported_band *sband =
|
||||||
rdev->wiphy.bands[setup->chandef.chan->band];
|
rdev->wiphy.bands[setup->chandef.chan->band];
|
||||||
setup->basic_rates = ieee80211_mandatory_rates(sband);
|
scan_width = cfg80211_chandef_to_scan_width(&setup->chandef);
|
||||||
|
setup->basic_rates = ieee80211_mandatory_rates(sband,
|
||||||
|
scan_width);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!cfg80211_reg_can_beacon(&rdev->wiphy, &setup->chandef))
|
if (!cfg80211_reg_can_beacon(&rdev->wiphy, &setup->chandef))
|
||||||
|
@@ -33,7 +33,8 @@ ieee80211_get_response_rate(struct ieee80211_supported_band *sband,
|
|||||||
}
|
}
|
||||||
EXPORT_SYMBOL(ieee80211_get_response_rate);
|
EXPORT_SYMBOL(ieee80211_get_response_rate);
|
||||||
|
|
||||||
u32 ieee80211_mandatory_rates(struct ieee80211_supported_band *sband)
|
u32 ieee80211_mandatory_rates(struct ieee80211_supported_band *sband,
|
||||||
|
enum nl80211_bss_scan_width scan_width)
|
||||||
{
|
{
|
||||||
struct ieee80211_rate *bitrates;
|
struct ieee80211_rate *bitrates;
|
||||||
u32 mandatory_rates = 0;
|
u32 mandatory_rates = 0;
|
||||||
@@ -43,10 +44,15 @@ u32 ieee80211_mandatory_rates(struct ieee80211_supported_band *sband)
|
|||||||
if (WARN_ON(!sband))
|
if (WARN_ON(!sband))
|
||||||
return 1;
|
return 1;
|
||||||
|
|
||||||
if (sband->band == IEEE80211_BAND_2GHZ)
|
if (sband->band == IEEE80211_BAND_2GHZ) {
|
||||||
mandatory_flag = IEEE80211_RATE_MANDATORY_B;
|
if (scan_width == NL80211_BSS_CHAN_WIDTH_5 ||
|
||||||
|
scan_width == NL80211_BSS_CHAN_WIDTH_10)
|
||||||
|
mandatory_flag = IEEE80211_RATE_MANDATORY_G;
|
||||||
else
|
else
|
||||||
|
mandatory_flag = IEEE80211_RATE_MANDATORY_B;
|
||||||
|
} else {
|
||||||
mandatory_flag = IEEE80211_RATE_MANDATORY_A;
|
mandatory_flag = IEEE80211_RATE_MANDATORY_A;
|
||||||
|
}
|
||||||
|
|
||||||
bitrates = sband->bitrates;
|
bitrates = sband->bitrates;
|
||||||
for (i = 0; i < sband->n_bitrates; i++)
|
for (i = 0; i < sband->n_bitrates; i++)
|
||||||
|
Reference in New Issue
Block a user