Commit 96dd22ac authored by Johannes Berg's avatar Johannes Berg Committed by John W. Linville
Browse files

mac80211: inform driver of basic rateset



Drivers need to know the basic rateset to be able to configure
the ACK/CTS programming in hardware correctly.
Signed-off-by: default avatarJohannes Berg <johannes@sipsolutions.net>
Signed-off-by: default avatarJohn W. Linville <linville@tuxdriver.com>
parent ccd7b362
...@@ -160,6 +160,7 @@ struct ieee80211_low_level_stats { ...@@ -160,6 +160,7 @@ struct ieee80211_low_level_stats {
* @BSS_CHANGED_ERP_PREAMBLE: preamble changed * @BSS_CHANGED_ERP_PREAMBLE: preamble changed
* @BSS_CHANGED_ERP_SLOT: slot timing changed * @BSS_CHANGED_ERP_SLOT: slot timing changed
* @BSS_CHANGED_HT: 802.11n parameters changed * @BSS_CHANGED_HT: 802.11n parameters changed
* @BSS_CHANGED_BASIC_RATES: Basic rateset changed
*/ */
enum ieee80211_bss_change { enum ieee80211_bss_change {
BSS_CHANGED_ASSOC = 1<<0, BSS_CHANGED_ASSOC = 1<<0,
...@@ -167,6 +168,7 @@ enum ieee80211_bss_change { ...@@ -167,6 +168,7 @@ enum ieee80211_bss_change {
BSS_CHANGED_ERP_PREAMBLE = 1<<2, BSS_CHANGED_ERP_PREAMBLE = 1<<2,
BSS_CHANGED_ERP_SLOT = 1<<3, BSS_CHANGED_ERP_SLOT = 1<<3,
BSS_CHANGED_HT = 1<<4, BSS_CHANGED_HT = 1<<4,
BSS_CHANGED_BASIC_RATES = 1<<5,
}; };
/** /**
...@@ -187,6 +189,9 @@ enum ieee80211_bss_change { ...@@ -187,6 +189,9 @@ enum ieee80211_bss_change {
* @assoc_ht: association in HT mode * @assoc_ht: association in HT mode
* @ht_conf: ht capabilities * @ht_conf: ht capabilities
* @ht_bss_conf: ht extended capabilities * @ht_bss_conf: ht extended capabilities
* @basic_rates: bitmap of basic rates, each bit stands for an
* index into the rate table configured by the driver in
* the current band.
*/ */
struct ieee80211_bss_conf { struct ieee80211_bss_conf {
/* association related data */ /* association related data */
...@@ -200,6 +205,7 @@ struct ieee80211_bss_conf { ...@@ -200,6 +205,7 @@ struct ieee80211_bss_conf {
u16 beacon_int; u16 beacon_int;
u16 assoc_capability; u16 assoc_capability;
u64 timestamp; u64 timestamp;
u64 basic_rates;
/* ht related data */ /* ht related data */
bool assoc_ht; bool assoc_ht;
struct ieee80211_ht_info *ht_conf; struct ieee80211_ht_info *ht_conf;
......
...@@ -433,11 +433,6 @@ struct ieee80211_sub_if_data { ...@@ -433,11 +433,6 @@ struct ieee80211_sub_if_data {
int drop_unencrypted; int drop_unencrypted;
/*
* basic rates of this AP or the AP we're associated to
*/
u64 basic_rates;
/* Fragment table for host-based reassembly */ /* Fragment table for host-based reassembly */
struct ieee80211_fragment_entry fragments[IEEE80211_FRAGMENT_MAX]; struct ieee80211_fragment_entry fragments[IEEE80211_FRAGMENT_MAX];
unsigned int fragment_next; unsigned int fragment_next;
...@@ -1017,6 +1012,8 @@ void ieee80211_tx_skb(struct ieee80211_sub_if_data *sdata, struct sk_buff *skb, ...@@ -1017,6 +1012,8 @@ void ieee80211_tx_skb(struct ieee80211_sub_if_data *sdata, struct sk_buff *skb,
void ieee802_11_parse_elems(u8 *start, size_t len, void ieee802_11_parse_elems(u8 *start, size_t len,
struct ieee802_11_elems *elems); struct ieee802_11_elems *elems);
int ieee80211_set_freq(struct ieee80211_sub_if_data *sdata, int freq); int ieee80211_set_freq(struct ieee80211_sub_if_data *sdata, int freq);
u64 ieee80211_mandatory_rates(struct ieee80211_local *local,
enum ieee80211_band band);
#ifdef CONFIG_MAC80211_NOINLINE #ifdef CONFIG_MAC80211_NOINLINE
#define debug_noinline noinline #define debug_noinline noinline
......
...@@ -144,7 +144,9 @@ int ieee80211_if_change_type(struct ieee80211_sub_if_data *sdata, ...@@ -144,7 +144,9 @@ int ieee80211_if_change_type(struct ieee80211_sub_if_data *sdata,
ieee80211_setup_sdata(sdata, type); ieee80211_setup_sdata(sdata, type);
/* reset some values that shouldn't be kept across type changes */ /* reset some values that shouldn't be kept across type changes */
sdata->basic_rates = 0; sdata->bss_conf.basic_rates =
ieee80211_mandatory_rates(sdata->local,
sdata->local->hw.conf.channel->band);
sdata->drop_unencrypted = 0; sdata->drop_unencrypted = 0;
return 0; return 0;
......
...@@ -710,6 +710,12 @@ static void ieee80211_set_associated(struct ieee80211_sub_if_data *sdata, ...@@ -710,6 +710,12 @@ static void ieee80211_set_associated(struct ieee80211_sub_if_data *sdata,
ieee80211_led_assoc(local, 1); ieee80211_led_assoc(local, 1);
sdata->bss_conf.assoc = 1; sdata->bss_conf.assoc = 1;
/*
* For now just always ask the driver to update the basic rateset
* when we have associated, we aren't checking whether it actually
* changed or not.
*/
changed |= BSS_CHANGED_BASIC_RATES;
ieee80211_bss_info_change_notify(sdata, changed); ieee80211_bss_info_change_notify(sdata, changed);
netif_tx_start_all_queues(sdata->dev); netif_tx_start_all_queues(sdata->dev);
...@@ -1296,7 +1302,7 @@ static void ieee80211_rx_mgmt_assoc_resp(struct ieee80211_sub_if_data *sdata, ...@@ -1296,7 +1302,7 @@ static void ieee80211_rx_mgmt_assoc_resp(struct ieee80211_sub_if_data *sdata,
} }
sta->supp_rates[local->hw.conf.channel->band] = rates; sta->supp_rates[local->hw.conf.channel->band] = rates;
sdata->basic_rates = basic_rates; sdata->bss_conf.basic_rates = basic_rates;
/* cf. IEEE 802.11 9.2.12 */ /* cf. IEEE 802.11 9.2.12 */
if (local->hw.conf.channel->band == IEEE80211_BAND_2GHZ && if (local->hw.conf.channel->band == IEEE80211_BAND_2GHZ &&
...@@ -1453,34 +1459,6 @@ static int ieee80211_sta_join_ibss(struct ieee80211_sub_if_data *sdata, ...@@ -1453,34 +1459,6 @@ static int ieee80211_sta_join_ibss(struct ieee80211_sub_if_data *sdata,
return res; return res;
} }
static u64 ieee80211_sta_get_mandatory_rates(struct ieee80211_local *local,
enum ieee80211_band band)
{
struct ieee80211_supported_band *sband;
struct ieee80211_rate *bitrates;
u64 mandatory_rates;
enum ieee80211_rate_flags mandatory_flag;
int i;
sband = local->hw.wiphy->bands[band];
if (!sband) {
WARN_ON(1);
sband = local->hw.wiphy->bands[local->hw.conf.channel->band];
}
if (band == IEEE80211_BAND_2GHZ)
mandatory_flag = IEEE80211_RATE_MANDATORY_B;
else
mandatory_flag = IEEE80211_RATE_MANDATORY_A;
bitrates = sband->bitrates;
mandatory_rates = 0;
for (i = 0; i < sband->n_bitrates; i++)
if (bitrates[i].flags & mandatory_flag)
mandatory_rates |= BIT(i);
return mandatory_rates;
}
static void ieee80211_rx_bss_info(struct ieee80211_sub_if_data *sdata, static void ieee80211_rx_bss_info(struct ieee80211_sub_if_data *sdata,
struct ieee80211_mgmt *mgmt, struct ieee80211_mgmt *mgmt,
size_t len, size_t len,
...@@ -1522,7 +1500,7 @@ static void ieee80211_rx_bss_info(struct ieee80211_sub_if_data *sdata, ...@@ -1522,7 +1500,7 @@ static void ieee80211_rx_bss_info(struct ieee80211_sub_if_data *sdata,
prev_rates = sta->supp_rates[band]; prev_rates = sta->supp_rates[band];
/* make sure mandatory rates are always added */ /* make sure mandatory rates are always added */
sta->supp_rates[band] = supp_rates | sta->supp_rates[band] = supp_rates |
ieee80211_sta_get_mandatory_rates(local, band); ieee80211_mandatory_rates(local, band);
#ifdef CONFIG_MAC80211_IBSS_DEBUG #ifdef CONFIG_MAC80211_IBSS_DEBUG
if (sta->supp_rates[band] != prev_rates) if (sta->supp_rates[band] != prev_rates)
...@@ -2361,7 +2339,7 @@ struct sta_info *ieee80211_ibss_add_sta(struct ieee80211_sub_if_data *sdata, ...@@ -2361,7 +2339,7 @@ struct sta_info *ieee80211_ibss_add_sta(struct ieee80211_sub_if_data *sdata,
/* make sure mandatory rates are always added */ /* make sure mandatory rates are always added */
sta->supp_rates[band] = supp_rates | sta->supp_rates[band] = supp_rates |
ieee80211_sta_get_mandatory_rates(local, band); ieee80211_mandatory_rates(local, band);
rate_control_rate_init(sta, local); rate_control_rate_init(sta, local);
......
...@@ -153,7 +153,7 @@ static __le16 ieee80211_duration(struct ieee80211_tx_data *tx, int group_addr, ...@@ -153,7 +153,7 @@ static __le16 ieee80211_duration(struct ieee80211_tx_data *tx, int group_addr,
if (r->bitrate > txrate->bitrate) if (r->bitrate > txrate->bitrate)
break; break;
if (tx->sdata->basic_rates & BIT(i)) if (tx->sdata->bss_conf.basic_rates & BIT(i))
rate = r->bitrate; rate = r->bitrate;
switch (sband->band) { switch (sband->band) {
...@@ -594,7 +594,7 @@ ieee80211_tx_h_misc(struct ieee80211_tx_data *tx) ...@@ -594,7 +594,7 @@ ieee80211_tx_h_misc(struct ieee80211_tx_data *tx)
for (idx = 0; idx < sband->n_bitrates; idx++) { for (idx = 0; idx < sband->n_bitrates; idx++) {
if (sband->bitrates[idx].bitrate > rate->bitrate) if (sband->bitrates[idx].bitrate > rate->bitrate)
continue; continue;
if (tx->sdata->basic_rates & BIT(idx) && if (tx->sdata->bss_conf.basic_rates & BIT(idx) &&
(baserate < 0 || (baserate < 0 ||
(sband->bitrates[baserate].bitrate (sband->bitrates[baserate].bitrate
< sband->bitrates[idx].bitrate))) < sband->bitrates[idx].bitrate)))
......
...@@ -640,3 +640,31 @@ int ieee80211_set_freq(struct ieee80211_sub_if_data *sdata, int freqMHz) ...@@ -640,3 +640,31 @@ int ieee80211_set_freq(struct ieee80211_sub_if_data *sdata, int freqMHz)
return ret; return ret;
} }
u64 ieee80211_mandatory_rates(struct ieee80211_local *local,
enum ieee80211_band band)
{
struct ieee80211_supported_band *sband;
struct ieee80211_rate *bitrates;
u64 mandatory_rates;
enum ieee80211_rate_flags mandatory_flag;
int i;
sband = local->hw.wiphy->bands[band];
if (!sband) {
WARN_ON(1);
sband = local->hw.wiphy->bands[local->hw.conf.channel->band];
}
if (band == IEEE80211_BAND_2GHZ)
mandatory_flag = IEEE80211_RATE_MANDATORY_B;
else
mandatory_flag = IEEE80211_RATE_MANDATORY_A;
bitrates = sband->bitrates;
mandatory_rates = 0;
for (i = 0; i < sband->n_bitrates; i++)
if (bitrates[i].flags & mandatory_flag)
mandatory_rates |= BIT(i);
return mandatory_rates;
}
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment