diff options
-rw-r--r-- | include/net/mac80211.h | 6 | ||||
-rw-r--r-- | net/mac80211/ieee80211_i.h | 7 | ||||
-rw-r--r-- | net/mac80211/iface.c | 4 | ||||
-rw-r--r-- | net/mac80211/mlme.c | 40 | ||||
-rw-r--r-- | net/mac80211/tx.c | 4 | ||||
-rw-r--r-- | net/mac80211/util.c | 28 |
6 files changed, 50 insertions, 39 deletions
diff --git a/include/net/mac80211.h b/include/net/mac80211.h index d67882dd3604..c81e579c17f3 100644 --- a/include/net/mac80211.h +++ b/include/net/mac80211.h | |||
@@ -160,6 +160,7 @@ struct ieee80211_low_level_stats { | |||
160 | * @BSS_CHANGED_ERP_PREAMBLE: preamble changed | 160 | * @BSS_CHANGED_ERP_PREAMBLE: preamble changed |
161 | * @BSS_CHANGED_ERP_SLOT: slot timing changed | 161 | * @BSS_CHANGED_ERP_SLOT: slot timing changed |
162 | * @BSS_CHANGED_HT: 802.11n parameters changed | 162 | * @BSS_CHANGED_HT: 802.11n parameters changed |
163 | * @BSS_CHANGED_BASIC_RATES: Basic rateset changed | ||
163 | */ | 164 | */ |
164 | enum ieee80211_bss_change { | 165 | enum ieee80211_bss_change { |
165 | BSS_CHANGED_ASSOC = 1<<0, | 166 | BSS_CHANGED_ASSOC = 1<<0, |
@@ -167,6 +168,7 @@ enum ieee80211_bss_change { | |||
167 | BSS_CHANGED_ERP_PREAMBLE = 1<<2, | 168 | BSS_CHANGED_ERP_PREAMBLE = 1<<2, |
168 | BSS_CHANGED_ERP_SLOT = 1<<3, | 169 | BSS_CHANGED_ERP_SLOT = 1<<3, |
169 | BSS_CHANGED_HT = 1<<4, | 170 | BSS_CHANGED_HT = 1<<4, |
171 | BSS_CHANGED_BASIC_RATES = 1<<5, | ||
170 | }; | 172 | }; |
171 | 173 | ||
172 | /** | 174 | /** |
@@ -187,6 +189,9 @@ enum ieee80211_bss_change { | |||
187 | * @assoc_ht: association in HT mode | 189 | * @assoc_ht: association in HT mode |
188 | * @ht_conf: ht capabilities | 190 | * @ht_conf: ht capabilities |
189 | * @ht_bss_conf: ht extended capabilities | 191 | * @ht_bss_conf: ht extended capabilities |
192 | * @basic_rates: bitmap of basic rates, each bit stands for an | ||
193 | * index into the rate table configured by the driver in | ||
194 | * the current band. | ||
190 | */ | 195 | */ |
191 | struct ieee80211_bss_conf { | 196 | struct ieee80211_bss_conf { |
192 | /* association related data */ | 197 | /* association related data */ |
@@ -200,6 +205,7 @@ struct ieee80211_bss_conf { | |||
200 | u16 beacon_int; | 205 | u16 beacon_int; |
201 | u16 assoc_capability; | 206 | u16 assoc_capability; |
202 | u64 timestamp; | 207 | u64 timestamp; |
208 | u64 basic_rates; | ||
203 | /* ht related data */ | 209 | /* ht related data */ |
204 | bool assoc_ht; | 210 | bool assoc_ht; |
205 | struct ieee80211_ht_info *ht_conf; | 211 | struct ieee80211_ht_info *ht_conf; |
diff --git a/net/mac80211/ieee80211_i.h b/net/mac80211/ieee80211_i.h index 1f9336a30e3b..21cc6d07b020 100644 --- a/net/mac80211/ieee80211_i.h +++ b/net/mac80211/ieee80211_i.h | |||
@@ -433,11 +433,6 @@ struct ieee80211_sub_if_data { | |||
433 | 433 | ||
434 | int drop_unencrypted; | 434 | int drop_unencrypted; |
435 | 435 | ||
436 | /* | ||
437 | * basic rates of this AP or the AP we're associated to | ||
438 | */ | ||
439 | u64 basic_rates; | ||
440 | |||
441 | /* Fragment table for host-based reassembly */ | 436 | /* Fragment table for host-based reassembly */ |
442 | struct ieee80211_fragment_entry fragments[IEEE80211_FRAGMENT_MAX]; | 437 | struct ieee80211_fragment_entry fragments[IEEE80211_FRAGMENT_MAX]; |
443 | unsigned int fragment_next; | 438 | unsigned int fragment_next; |
@@ -1017,6 +1012,8 @@ void ieee80211_tx_skb(struct ieee80211_sub_if_data *sdata, struct sk_buff *skb, | |||
1017 | void ieee802_11_parse_elems(u8 *start, size_t len, | 1012 | void ieee802_11_parse_elems(u8 *start, size_t len, |
1018 | struct ieee802_11_elems *elems); | 1013 | struct ieee802_11_elems *elems); |
1019 | int ieee80211_set_freq(struct ieee80211_sub_if_data *sdata, int freq); | 1014 | int ieee80211_set_freq(struct ieee80211_sub_if_data *sdata, int freq); |
1015 | u64 ieee80211_mandatory_rates(struct ieee80211_local *local, | ||
1016 | enum ieee80211_band band); | ||
1020 | 1017 | ||
1021 | #ifdef CONFIG_MAC80211_NOINLINE | 1018 | #ifdef CONFIG_MAC80211_NOINLINE |
1022 | #define debug_noinline noinline | 1019 | #define debug_noinline noinline |
diff --git a/net/mac80211/iface.c b/net/mac80211/iface.c index 61b19340488c..dab8eba2602f 100644 --- a/net/mac80211/iface.c +++ b/net/mac80211/iface.c | |||
@@ -144,7 +144,9 @@ int ieee80211_if_change_type(struct ieee80211_sub_if_data *sdata, | |||
144 | ieee80211_setup_sdata(sdata, type); | 144 | ieee80211_setup_sdata(sdata, type); |
145 | 145 | ||
146 | /* reset some values that shouldn't be kept across type changes */ | 146 | /* reset some values that shouldn't be kept across type changes */ |
147 | sdata->basic_rates = 0; | 147 | sdata->bss_conf.basic_rates = |
148 | ieee80211_mandatory_rates(sdata->local, | ||
149 | sdata->local->hw.conf.channel->band); | ||
148 | sdata->drop_unencrypted = 0; | 150 | sdata->drop_unencrypted = 0; |
149 | 151 | ||
150 | return 0; | 152 | return 0; |
diff --git a/net/mac80211/mlme.c b/net/mac80211/mlme.c index 5b748447eb7d..55bc60713937 100644 --- a/net/mac80211/mlme.c +++ b/net/mac80211/mlme.c | |||
@@ -710,6 +710,12 @@ static void ieee80211_set_associated(struct ieee80211_sub_if_data *sdata, | |||
710 | ieee80211_led_assoc(local, 1); | 710 | ieee80211_led_assoc(local, 1); |
711 | 711 | ||
712 | sdata->bss_conf.assoc = 1; | 712 | sdata->bss_conf.assoc = 1; |
713 | /* | ||
714 | * For now just always ask the driver to update the basic rateset | ||
715 | * when we have associated, we aren't checking whether it actually | ||
716 | * changed or not. | ||
717 | */ | ||
718 | changed |= BSS_CHANGED_BASIC_RATES; | ||
713 | ieee80211_bss_info_change_notify(sdata, changed); | 719 | ieee80211_bss_info_change_notify(sdata, changed); |
714 | 720 | ||
715 | netif_tx_start_all_queues(sdata->dev); | 721 | 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 | } | 1302 | } |
1297 | 1303 | ||
1298 | sta->supp_rates[local->hw.conf.channel->band] = rates; | 1304 | sta->supp_rates[local->hw.conf.channel->band] = rates; |
1299 | sdata->basic_rates = basic_rates; | 1305 | sdata->bss_conf.basic_rates = basic_rates; |
1300 | 1306 | ||
1301 | /* cf. IEEE 802.11 9.2.12 */ | 1307 | /* cf. IEEE 802.11 9.2.12 */ |
1302 | if (local->hw.conf.channel->band == IEEE80211_BAND_2GHZ && | 1308 | 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 | return res; | 1459 | return res; |
1454 | } | 1460 | } |
1455 | 1461 | ||
1456 | static u64 ieee80211_sta_get_mandatory_rates(struct ieee80211_local *local, | ||
1457 | enum ieee80211_band band) | ||
1458 | { | ||
1459 | struct ieee80211_supported_band *sband; | ||
1460 | struct ieee80211_rate *bitrates; | ||
1461 | u64 mandatory_rates; | ||
1462 | enum ieee80211_rate_flags mandatory_flag; | ||
1463 | int i; | ||
1464 | |||
1465 | sband = local->hw.wiphy->bands[band]; | ||
1466 | if (!sband) { | ||
1467 | WARN_ON(1); | ||
1468 | sband = local->hw.wiphy->bands[local->hw.conf.channel->band]; | ||
1469 | } | ||
1470 | |||
1471 | if (band == IEEE80211_BAND_2GHZ) | ||
1472 | mandatory_flag = IEEE80211_RATE_MANDATORY_B; | ||
1473 | else | ||
1474 | mandatory_flag = IEEE80211_RATE_MANDATORY_A; | ||
1475 | |||
1476 | bitrates = sband->bitrates; | ||
1477 | mandatory_rates = 0; | ||
1478 | for (i = 0; i < sband->n_bitrates; i++) | ||
1479 | if (bitrates[i].flags & mandatory_flag) | ||
1480 | mandatory_rates |= BIT(i); | ||
1481 | return mandatory_rates; | ||
1482 | } | ||
1483 | |||
1484 | static void ieee80211_rx_bss_info(struct ieee80211_sub_if_data *sdata, | 1462 | static void ieee80211_rx_bss_info(struct ieee80211_sub_if_data *sdata, |
1485 | struct ieee80211_mgmt *mgmt, | 1463 | struct ieee80211_mgmt *mgmt, |
1486 | size_t len, | 1464 | size_t len, |
@@ -1522,7 +1500,7 @@ static void ieee80211_rx_bss_info(struct ieee80211_sub_if_data *sdata, | |||
1522 | prev_rates = sta->supp_rates[band]; | 1500 | prev_rates = sta->supp_rates[band]; |
1523 | /* make sure mandatory rates are always added */ | 1501 | /* make sure mandatory rates are always added */ |
1524 | sta->supp_rates[band] = supp_rates | | 1502 | sta->supp_rates[band] = supp_rates | |
1525 | ieee80211_sta_get_mandatory_rates(local, band); | 1503 | ieee80211_mandatory_rates(local, band); |
1526 | 1504 | ||
1527 | #ifdef CONFIG_MAC80211_IBSS_DEBUG | 1505 | #ifdef CONFIG_MAC80211_IBSS_DEBUG |
1528 | if (sta->supp_rates[band] != prev_rates) | 1506 | 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 | 2339 | ||
2362 | /* make sure mandatory rates are always added */ | 2340 | /* make sure mandatory rates are always added */ |
2363 | sta->supp_rates[band] = supp_rates | | 2341 | sta->supp_rates[band] = supp_rates | |
2364 | ieee80211_sta_get_mandatory_rates(local, band); | 2342 | ieee80211_mandatory_rates(local, band); |
2365 | 2343 | ||
2366 | rate_control_rate_init(sta, local); | 2344 | rate_control_rate_init(sta, local); |
2367 | 2345 | ||
diff --git a/net/mac80211/tx.c b/net/mac80211/tx.c index 1bed3be01c26..a523189f10c4 100644 --- a/net/mac80211/tx.c +++ b/net/mac80211/tx.c | |||
@@ -153,7 +153,7 @@ static __le16 ieee80211_duration(struct ieee80211_tx_data *tx, int group_addr, | |||
153 | if (r->bitrate > txrate->bitrate) | 153 | if (r->bitrate > txrate->bitrate) |
154 | break; | 154 | break; |
155 | 155 | ||
156 | if (tx->sdata->basic_rates & BIT(i)) | 156 | if (tx->sdata->bss_conf.basic_rates & BIT(i)) |
157 | rate = r->bitrate; | 157 | rate = r->bitrate; |
158 | 158 | ||
159 | switch (sband->band) { | 159 | switch (sband->band) { |
@@ -594,7 +594,7 @@ ieee80211_tx_h_misc(struct ieee80211_tx_data *tx) | |||
594 | for (idx = 0; idx < sband->n_bitrates; idx++) { | 594 | for (idx = 0; idx < sband->n_bitrates; idx++) { |
595 | if (sband->bitrates[idx].bitrate > rate->bitrate) | 595 | if (sband->bitrates[idx].bitrate > rate->bitrate) |
596 | continue; | 596 | continue; |
597 | if (tx->sdata->basic_rates & BIT(idx) && | 597 | if (tx->sdata->bss_conf.basic_rates & BIT(idx) && |
598 | (baserate < 0 || | 598 | (baserate < 0 || |
599 | (sband->bitrates[baserate].bitrate | 599 | (sband->bitrates[baserate].bitrate |
600 | < sband->bitrates[idx].bitrate))) | 600 | < sband->bitrates[idx].bitrate))) |
diff --git a/net/mac80211/util.c b/net/mac80211/util.c index a7968df9dacb..d6aca91e612d 100644 --- a/net/mac80211/util.c +++ b/net/mac80211/util.c | |||
@@ -640,3 +640,31 @@ int ieee80211_set_freq(struct ieee80211_sub_if_data *sdata, int freqMHz) | |||
640 | 640 | ||
641 | return ret; | 641 | return ret; |
642 | } | 642 | } |
643 | |||
644 | u64 ieee80211_mandatory_rates(struct ieee80211_local *local, | ||
645 | enum ieee80211_band band) | ||
646 | { | ||
647 | struct ieee80211_supported_band *sband; | ||
648 | struct ieee80211_rate *bitrates; | ||
649 | u64 mandatory_rates; | ||
650 | enum ieee80211_rate_flags mandatory_flag; | ||
651 | int i; | ||
652 | |||
653 | sband = local->hw.wiphy->bands[band]; | ||
654 | if (!sband) { | ||
655 | WARN_ON(1); | ||
656 | sband = local->hw.wiphy->bands[local->hw.conf.channel->band]; | ||
657 | } | ||
658 | |||
659 | if (band == IEEE80211_BAND_2GHZ) | ||
660 | mandatory_flag = IEEE80211_RATE_MANDATORY_B; | ||
661 | else | ||
662 | mandatory_flag = IEEE80211_RATE_MANDATORY_A; | ||
663 | |||
664 | bitrates = sband->bitrates; | ||
665 | mandatory_rates = 0; | ||
666 | for (i = 0; i < sband->n_bitrates; i++) | ||
667 | if (bitrates[i].flags & mandatory_flag) | ||
668 | mandatory_rates |= BIT(i); | ||
669 | return mandatory_rates; | ||
670 | } | ||