diff options
Diffstat (limited to 'net')
-rw-r--r-- | net/mac80211/ieee80211_i.h | 8 | ||||
-rw-r--r-- | net/mac80211/mlme.c | 6 | ||||
-rw-r--r-- | net/mac80211/rate.c | 12 | ||||
-rw-r--r-- | net/mac80211/rate.h | 25 | ||||
-rw-r--r-- | net/mac80211/rc80211_pid_algo.c | 6 | ||||
-rw-r--r-- | net/mac80211/tx.c | 104 | ||||
-rw-r--r-- | net/mac80211/util.c | 10 |
7 files changed, 93 insertions, 78 deletions
diff --git a/net/mac80211/ieee80211_i.h b/net/mac80211/ieee80211_i.h index ed0d9b35ae6f..a4cccd1b7d53 100644 --- a/net/mac80211/ieee80211_i.h +++ b/net/mac80211/ieee80211_i.h | |||
@@ -159,11 +159,11 @@ struct ieee80211_tx_data { | |||
159 | 159 | ||
160 | struct ieee80211_tx_control *control; | 160 | struct ieee80211_tx_control *control; |
161 | struct ieee80211_channel *channel; | 161 | struct ieee80211_channel *channel; |
162 | struct ieee80211_rate *rate; | 162 | s8 rate_idx; |
163 | /* use this rate (if set) for last fragment; rate can | 163 | /* use this rate (if set) for last fragment; rate can |
164 | * be set to lower rate for the first fragments, e.g., | 164 | * be set to lower rate for the first fragments, e.g., |
165 | * when using CTS protection with IEEE 802.11g. */ | 165 | * when using CTS protection with IEEE 802.11g. */ |
166 | struct ieee80211_rate *last_frag_rate; | 166 | s8 last_frag_rate_idx; |
167 | 167 | ||
168 | /* Extra fragments (in addition to the first fragment | 168 | /* Extra fragments (in addition to the first fragment |
169 | * in skb) */ | 169 | * in skb) */ |
@@ -225,9 +225,9 @@ struct ieee80211_tx_stored_packet { | |||
225 | struct ieee80211_tx_control control; | 225 | struct ieee80211_tx_control control; |
226 | struct sk_buff *skb; | 226 | struct sk_buff *skb; |
227 | struct sk_buff **extra_frag; | 227 | struct sk_buff **extra_frag; |
228 | struct ieee80211_rate *last_frag_rate; | 228 | s8 last_frag_rate_idx; |
229 | int num_extra_frag; | 229 | int num_extra_frag; |
230 | unsigned int last_frag_rate_ctrl_probe; | 230 | bool last_frag_rate_ctrl_probe; |
231 | }; | 231 | }; |
232 | 232 | ||
233 | struct beacon_data { | 233 | struct beacon_data { |
diff --git a/net/mac80211/mlme.c b/net/mac80211/mlme.c index 7877d3b3f4cb..604149369dc9 100644 --- a/net/mac80211/mlme.c +++ b/net/mac80211/mlme.c | |||
@@ -2406,15 +2406,15 @@ static int ieee80211_sta_join_ibss(struct net_device *dev, | |||
2406 | 2406 | ||
2407 | memset(&control, 0, sizeof(control)); | 2407 | memset(&control, 0, sizeof(control)); |
2408 | rate_control_get_rate(dev, sband, skb, &ratesel); | 2408 | rate_control_get_rate(dev, sband, skb, &ratesel); |
2409 | if (!ratesel.rate) { | 2409 | if (ratesel.rate_idx < 0) { |
2410 | printk(KERN_DEBUG "%s: Failed to determine TX rate " | 2410 | printk(KERN_DEBUG "%s: Failed to determine TX rate " |
2411 | "for IBSS beacon\n", dev->name); | 2411 | "for IBSS beacon\n", dev->name); |
2412 | break; | 2412 | break; |
2413 | } | 2413 | } |
2414 | control.vif = &sdata->vif; | 2414 | control.vif = &sdata->vif; |
2415 | control.tx_rate = ratesel.rate; | 2415 | control.tx_rate_idx = ratesel.rate_idx; |
2416 | if (sdata->bss_conf.use_short_preamble && | 2416 | if (sdata->bss_conf.use_short_preamble && |
2417 | ratesel.rate->flags & IEEE80211_RATE_SHORT_PREAMBLE) | 2417 | sband->bitrates[ratesel.rate_idx].flags & IEEE80211_RATE_SHORT_PREAMBLE) |
2418 | control.flags |= IEEE80211_TXCTL_SHORT_PREAMBLE; | 2418 | control.flags |= IEEE80211_TXCTL_SHORT_PREAMBLE; |
2419 | control.antenna_sel_tx = local->hw.conf.antenna_sel_tx; | 2419 | control.antenna_sel_tx = local->hw.conf.antenna_sel_tx; |
2420 | control.flags |= IEEE80211_TXCTL_NO_ACK; | 2420 | control.flags |= IEEE80211_TXCTL_NO_ACK; |
diff --git a/net/mac80211/rate.c b/net/mac80211/rate.c index 841df93807fc..0388c090dfe9 100644 --- a/net/mac80211/rate.c +++ b/net/mac80211/rate.c | |||
@@ -176,20 +176,24 @@ void rate_control_get_rate(struct net_device *dev, | |||
176 | rcu_read_lock(); | 176 | rcu_read_lock(); |
177 | sta = sta_info_get(local, hdr->addr1); | 177 | sta = sta_info_get(local, hdr->addr1); |
178 | 178 | ||
179 | memset(sel, 0, sizeof(struct rate_selection)); | 179 | sel->rate_idx = -1; |
180 | sel->nonerp_idx = -1; | ||
181 | sel->probe_idx = -1; | ||
180 | 182 | ||
181 | ref->ops->get_rate(ref->priv, dev, sband, skb, sel); | 183 | ref->ops->get_rate(ref->priv, dev, sband, skb, sel); |
182 | 184 | ||
185 | BUG_ON(sel->rate_idx < 0); | ||
186 | |||
183 | /* Select a non-ERP backup rate. */ | 187 | /* Select a non-ERP backup rate. */ |
184 | if (!sel->nonerp) { | 188 | if (sel->nonerp_idx < 0) { |
185 | for (i = 0; i < sband->n_bitrates; i++) { | 189 | for (i = 0; i < sband->n_bitrates; i++) { |
186 | struct ieee80211_rate *rate = &sband->bitrates[i]; | 190 | struct ieee80211_rate *rate = &sband->bitrates[i]; |
187 | if (sel->rate->bitrate < rate->bitrate) | 191 | if (sband->bitrates[sel->rate_idx].bitrate < rate->bitrate) |
188 | break; | 192 | break; |
189 | 193 | ||
190 | if (rate_supported(sta, sband->band, i) && | 194 | if (rate_supported(sta, sband->band, i) && |
191 | !(rate->flags & IEEE80211_RATE_ERP_G)) | 195 | !(rate->flags & IEEE80211_RATE_ERP_G)) |
192 | sel->nonerp = rate; | 196 | sel->nonerp_idx = i; |
193 | } | 197 | } |
194 | } | 198 | } |
195 | 199 | ||
diff --git a/net/mac80211/rate.h b/net/mac80211/rate.h index 5b45f33cb766..a29148dcca99 100644 --- a/net/mac80211/rate.h +++ b/net/mac80211/rate.h | |||
@@ -19,14 +19,15 @@ | |||
19 | #include "ieee80211_i.h" | 19 | #include "ieee80211_i.h" |
20 | #include "sta_info.h" | 20 | #include "sta_info.h" |
21 | 21 | ||
22 | /* TODO: kdoc */ | 22 | /** |
23 | * struct rate_selection - rate selection for rate control algos | ||
24 | * @rate: selected transmission rate index | ||
25 | * @nonerp: Non-ERP rate to use instead if ERP cannot be used | ||
26 | * @probe: rate for probing (or -1) | ||
27 | * | ||
28 | */ | ||
23 | struct rate_selection { | 29 | struct rate_selection { |
24 | /* Selected transmission rate */ | 30 | s8 rate_idx, nonerp_idx, probe_idx; |
25 | struct ieee80211_rate *rate; | ||
26 | /* Non-ERP rate to use if mac80211 decides it cannot use an ERP rate */ | ||
27 | struct ieee80211_rate *nonerp; | ||
28 | /* probe with this rate, or NULL for no probing */ | ||
29 | struct ieee80211_rate *probe; | ||
30 | }; | 31 | }; |
31 | 32 | ||
32 | struct rate_control_ops { | 33 | struct rate_control_ops { |
@@ -138,7 +139,7 @@ static inline int rate_supported(struct sta_info *sta, | |||
138 | return (sta == NULL || sta->supp_rates[band] & BIT(index)); | 139 | return (sta == NULL || sta->supp_rates[band] & BIT(index)); |
139 | } | 140 | } |
140 | 141 | ||
141 | static inline int | 142 | static inline s8 |
142 | rate_lowest_index(struct ieee80211_local *local, | 143 | rate_lowest_index(struct ieee80211_local *local, |
143 | struct ieee80211_supported_band *sband, | 144 | struct ieee80211_supported_band *sband, |
144 | struct sta_info *sta) | 145 | struct sta_info *sta) |
@@ -155,14 +156,6 @@ rate_lowest_index(struct ieee80211_local *local, | |||
155 | return 0; | 156 | return 0; |
156 | } | 157 | } |
157 | 158 | ||
158 | static inline struct ieee80211_rate * | ||
159 | rate_lowest(struct ieee80211_local *local, | ||
160 | struct ieee80211_supported_band *sband, | ||
161 | struct sta_info *sta) | ||
162 | { | ||
163 | return &sband->bitrates[rate_lowest_index(local, sband, sta)]; | ||
164 | } | ||
165 | |||
166 | 159 | ||
167 | /* functions for rate control related to a device */ | 160 | /* functions for rate control related to a device */ |
168 | int ieee80211_init_rate_ctrl_alg(struct ieee80211_local *local, | 161 | int ieee80211_init_rate_ctrl_alg(struct ieee80211_local *local, |
diff --git a/net/mac80211/rc80211_pid_algo.c b/net/mac80211/rc80211_pid_algo.c index a849b745bdb5..14cde36f5070 100644 --- a/net/mac80211/rc80211_pid_algo.c +++ b/net/mac80211/rc80211_pid_algo.c | |||
@@ -266,7 +266,7 @@ static void rate_control_pid_tx_status(void *priv, struct net_device *dev, | |||
266 | 266 | ||
267 | /* Ignore all frames that were sent with a different rate than the rate | 267 | /* Ignore all frames that were sent with a different rate than the rate |
268 | * we currently advise mac80211 to use. */ | 268 | * we currently advise mac80211 to use. */ |
269 | if (status->control.tx_rate != &sband->bitrates[sta->txrate_idx]) | 269 | if (status->control.tx_rate_idx != sta->txrate_idx) |
270 | goto unlock; | 270 | goto unlock; |
271 | 271 | ||
272 | spinfo = sta->rate_ctrl_priv; | 272 | spinfo = sta->rate_ctrl_priv; |
@@ -330,7 +330,7 @@ static void rate_control_pid_get_rate(void *priv, struct net_device *dev, | |||
330 | fc = le16_to_cpu(hdr->frame_control); | 330 | fc = le16_to_cpu(hdr->frame_control); |
331 | if ((fc & IEEE80211_FCTL_FTYPE) != IEEE80211_FTYPE_DATA || | 331 | if ((fc & IEEE80211_FCTL_FTYPE) != IEEE80211_FTYPE_DATA || |
332 | is_multicast_ether_addr(hdr->addr1) || !sta) { | 332 | is_multicast_ether_addr(hdr->addr1) || !sta) { |
333 | sel->rate = rate_lowest(local, sband, sta); | 333 | sel->rate_idx = rate_lowest_index(local, sband, sta); |
334 | rcu_read_unlock(); | 334 | rcu_read_unlock(); |
335 | return; | 335 | return; |
336 | } | 336 | } |
@@ -349,7 +349,7 @@ static void rate_control_pid_get_rate(void *priv, struct net_device *dev, | |||
349 | 349 | ||
350 | rcu_read_unlock(); | 350 | rcu_read_unlock(); |
351 | 351 | ||
352 | sel->rate = &sband->bitrates[rateidx]; | 352 | sel->rate_idx = rateidx; |
353 | 353 | ||
354 | #ifdef CONFIG_MAC80211_DEBUGFS | 354 | #ifdef CONFIG_MAC80211_DEBUGFS |
355 | rate_control_pid_event_tx_rate( | 355 | rate_control_pid_event_tx_rate( |
diff --git a/net/mac80211/tx.c b/net/mac80211/tx.c index aecec2a72b08..99c3860bc0e2 100644 --- a/net/mac80211/tx.c +++ b/net/mac80211/tx.c | |||
@@ -91,11 +91,12 @@ static u16 ieee80211_duration(struct ieee80211_tx_data *tx, int group_addr, | |||
91 | int next_frag_len) | 91 | int next_frag_len) |
92 | { | 92 | { |
93 | int rate, mrate, erp, dur, i; | 93 | int rate, mrate, erp, dur, i; |
94 | struct ieee80211_rate *txrate = tx->rate; | 94 | struct ieee80211_rate *txrate; |
95 | struct ieee80211_local *local = tx->local; | 95 | struct ieee80211_local *local = tx->local; |
96 | struct ieee80211_supported_band *sband; | 96 | struct ieee80211_supported_band *sband; |
97 | 97 | ||
98 | sband = local->hw.wiphy->bands[local->hw.conf.channel->band]; | 98 | sband = local->hw.wiphy->bands[tx->channel->band]; |
99 | txrate = &sband->bitrates[tx->rate_idx]; | ||
99 | 100 | ||
100 | erp = 0; | 101 | erp = 0; |
101 | if (tx->sdata->flags & IEEE80211_SDATA_OPERATING_GMODE) | 102 | if (tx->sdata->flags & IEEE80211_SDATA_OPERATING_GMODE) |
@@ -610,40 +611,40 @@ ieee80211_tx_h_rate_ctrl(struct ieee80211_tx_data *tx) | |||
610 | struct rate_selection rsel; | 611 | struct rate_selection rsel; |
611 | struct ieee80211_supported_band *sband; | 612 | struct ieee80211_supported_band *sband; |
612 | 613 | ||
613 | sband = tx->local->hw.wiphy->bands[tx->local->hw.conf.channel->band]; | 614 | sband = tx->local->hw.wiphy->bands[tx->channel->band]; |
614 | 615 | ||
615 | if (likely(!tx->rate)) { | 616 | if (likely(tx->rate_idx < 0)) { |
616 | rate_control_get_rate(tx->dev, sband, tx->skb, &rsel); | 617 | rate_control_get_rate(tx->dev, sband, tx->skb, &rsel); |
617 | tx->rate = rsel.rate; | 618 | tx->rate_idx = rsel.rate_idx; |
618 | if (unlikely(rsel.probe)) { | 619 | if (unlikely(rsel.probe_idx >= 0)) { |
619 | tx->control->flags |= | 620 | tx->control->flags |= |
620 | IEEE80211_TXCTL_RATE_CTRL_PROBE; | 621 | IEEE80211_TXCTL_RATE_CTRL_PROBE; |
621 | tx->flags |= IEEE80211_TX_PROBE_LAST_FRAG; | 622 | tx->flags |= IEEE80211_TX_PROBE_LAST_FRAG; |
622 | tx->control->alt_retry_rate = tx->rate; | 623 | tx->control->alt_retry_rate_idx = tx->rate_idx; |
623 | tx->rate = rsel.probe; | 624 | tx->rate_idx = rsel.probe_idx; |
624 | } else | 625 | } else |
625 | tx->control->alt_retry_rate = NULL; | 626 | tx->control->alt_retry_rate_idx = -1; |
626 | 627 | ||
627 | if (!tx->rate) | 628 | if (unlikely(tx->rate_idx < 0)) |
628 | return TX_DROP; | 629 | return TX_DROP; |
629 | } else | 630 | } else |
630 | tx->control->alt_retry_rate = NULL; | 631 | tx->control->alt_retry_rate_idx = -1; |
631 | 632 | ||
632 | if (tx->sdata->bss_conf.use_cts_prot && | 633 | if (tx->sdata->bss_conf.use_cts_prot && |
633 | (tx->flags & IEEE80211_TX_FRAGMENTED) && rsel.nonerp) { | 634 | (tx->flags & IEEE80211_TX_FRAGMENTED) && (rsel.nonerp_idx >= 0)) { |
634 | tx->last_frag_rate = tx->rate; | 635 | tx->last_frag_rate_idx = tx->rate_idx; |
635 | if (rsel.probe) | 636 | if (rsel.probe_idx >= 0) |
636 | tx->flags &= ~IEEE80211_TX_PROBE_LAST_FRAG; | 637 | tx->flags &= ~IEEE80211_TX_PROBE_LAST_FRAG; |
637 | else | 638 | else |
638 | tx->flags |= IEEE80211_TX_PROBE_LAST_FRAG; | 639 | tx->flags |= IEEE80211_TX_PROBE_LAST_FRAG; |
639 | tx->rate = rsel.nonerp; | 640 | tx->rate_idx = rsel.nonerp_idx; |
640 | tx->control->tx_rate = rsel.nonerp; | 641 | tx->control->tx_rate_idx = rsel.nonerp_idx; |
641 | tx->control->flags &= ~IEEE80211_TXCTL_RATE_CTRL_PROBE; | 642 | tx->control->flags &= ~IEEE80211_TXCTL_RATE_CTRL_PROBE; |
642 | } else { | 643 | } else { |
643 | tx->last_frag_rate = tx->rate; | 644 | tx->last_frag_rate_idx = tx->rate_idx; |
644 | tx->control->tx_rate = tx->rate; | 645 | tx->control->tx_rate_idx = tx->rate_idx; |
645 | } | 646 | } |
646 | tx->control->tx_rate = tx->rate; | 647 | tx->control->tx_rate_idx = tx->rate_idx; |
647 | 648 | ||
648 | return TX_CONTINUE; | 649 | return TX_CONTINUE; |
649 | } | 650 | } |
@@ -655,6 +656,9 @@ ieee80211_tx_h_misc(struct ieee80211_tx_data *tx) | |||
655 | u16 fc = le16_to_cpu(hdr->frame_control); | 656 | u16 fc = le16_to_cpu(hdr->frame_control); |
656 | u16 dur; | 657 | u16 dur; |
657 | struct ieee80211_tx_control *control = tx->control; | 658 | struct ieee80211_tx_control *control = tx->control; |
659 | struct ieee80211_supported_band *sband; | ||
660 | |||
661 | sband = tx->local->hw.wiphy->bands[tx->channel->band]; | ||
658 | 662 | ||
659 | if (!control->retry_limit) { | 663 | if (!control->retry_limit) { |
660 | if (!is_multicast_ether_addr(hdr->addr1)) { | 664 | if (!is_multicast_ether_addr(hdr->addr1)) { |
@@ -681,14 +685,14 @@ ieee80211_tx_h_misc(struct ieee80211_tx_data *tx) | |||
681 | * frames. | 685 | * frames. |
682 | * TODO: The last fragment could still use multiple retry | 686 | * TODO: The last fragment could still use multiple retry |
683 | * rates. */ | 687 | * rates. */ |
684 | control->alt_retry_rate = NULL; | 688 | control->alt_retry_rate_idx = -1; |
685 | } | 689 | } |
686 | 690 | ||
687 | /* Use CTS protection for unicast frames sent using extended rates if | 691 | /* Use CTS protection for unicast frames sent using extended rates if |
688 | * there are associated non-ERP stations and RTS/CTS is not configured | 692 | * there are associated non-ERP stations and RTS/CTS is not configured |
689 | * for the frame. */ | 693 | * for the frame. */ |
690 | if ((tx->sdata->flags & IEEE80211_SDATA_OPERATING_GMODE) && | 694 | if ((tx->sdata->flags & IEEE80211_SDATA_OPERATING_GMODE) && |
691 | (tx->rate->flags & IEEE80211_RATE_ERP_G) && | 695 | (sband->bitrates[tx->rate_idx].flags & IEEE80211_RATE_ERP_G) && |
692 | (tx->flags & IEEE80211_TX_UNICAST) && | 696 | (tx->flags & IEEE80211_TX_UNICAST) && |
693 | tx->sdata->bss_conf.use_cts_prot && | 697 | tx->sdata->bss_conf.use_cts_prot && |
694 | !(control->flags & IEEE80211_TXCTL_USE_RTS_CTS)) | 698 | !(control->flags & IEEE80211_TXCTL_USE_RTS_CTS)) |
@@ -698,7 +702,7 @@ ieee80211_tx_h_misc(struct ieee80211_tx_data *tx) | |||
698 | * short preambles at the selected rate and short preambles are | 702 | * short preambles at the selected rate and short preambles are |
699 | * available on the network at the current point in time. */ | 703 | * available on the network at the current point in time. */ |
700 | if (((fc & IEEE80211_FCTL_FTYPE) == IEEE80211_FTYPE_DATA) && | 704 | if (((fc & IEEE80211_FCTL_FTYPE) == IEEE80211_FTYPE_DATA) && |
701 | (tx->rate->flags & IEEE80211_RATE_SHORT_PREAMBLE) && | 705 | (sband->bitrates[tx->rate_idx].flags & IEEE80211_RATE_SHORT_PREAMBLE) && |
702 | tx->sdata->bss_conf.use_short_preamble && | 706 | tx->sdata->bss_conf.use_short_preamble && |
703 | (!tx->sta || test_sta_flags(tx->sta, WLAN_STA_SHORT_PREAMBLE))) { | 707 | (!tx->sta || test_sta_flags(tx->sta, WLAN_STA_SHORT_PREAMBLE))) { |
704 | tx->control->flags |= IEEE80211_TXCTL_SHORT_PREAMBLE; | 708 | tx->control->flags |= IEEE80211_TXCTL_SHORT_PREAMBLE; |
@@ -715,32 +719,32 @@ ieee80211_tx_h_misc(struct ieee80211_tx_data *tx) | |||
715 | if ((control->flags & IEEE80211_TXCTL_USE_RTS_CTS) || | 719 | if ((control->flags & IEEE80211_TXCTL_USE_RTS_CTS) || |
716 | (control->flags & IEEE80211_TXCTL_USE_CTS_PROTECT)) { | 720 | (control->flags & IEEE80211_TXCTL_USE_CTS_PROTECT)) { |
717 | struct ieee80211_supported_band *sband; | 721 | struct ieee80211_supported_band *sband; |
718 | struct ieee80211_rate *rate, *baserate; | 722 | struct ieee80211_rate *rate; |
723 | s8 baserate = -1; | ||
719 | int idx; | 724 | int idx; |
720 | 725 | ||
721 | sband = tx->local->hw.wiphy->bands[ | 726 | sband = tx->local->hw.wiphy->bands[tx->channel->band]; |
722 | tx->local->hw.conf.channel->band]; | ||
723 | 727 | ||
724 | /* Do not use multiple retry rates when using RTS/CTS */ | 728 | /* Do not use multiple retry rates when using RTS/CTS */ |
725 | control->alt_retry_rate = NULL; | 729 | control->alt_retry_rate_idx = -1; |
726 | 730 | ||
727 | /* Use min(data rate, max base rate) as CTS/RTS rate */ | 731 | /* Use min(data rate, max base rate) as CTS/RTS rate */ |
728 | rate = tx->rate; | 732 | rate = &sband->bitrates[tx->rate_idx]; |
729 | baserate = NULL; | ||
730 | 733 | ||
731 | for (idx = 0; idx < sband->n_bitrates; idx++) { | 734 | for (idx = 0; idx < sband->n_bitrates; idx++) { |
732 | if (sband->bitrates[idx].bitrate > rate->bitrate) | 735 | if (sband->bitrates[idx].bitrate > rate->bitrate) |
733 | continue; | 736 | continue; |
734 | if (tx->sdata->basic_rates & BIT(idx) && | 737 | if (tx->sdata->basic_rates & BIT(idx) && |
735 | (!baserate || | 738 | (baserate < 0 || |
736 | (baserate->bitrate < sband->bitrates[idx].bitrate))) | 739 | (sband->bitrates[baserate].bitrate |
737 | baserate = &sband->bitrates[idx]; | 740 | < sband->bitrates[idx].bitrate))) |
741 | baserate = idx; | ||
738 | } | 742 | } |
739 | 743 | ||
740 | if (baserate) | 744 | if (baserate >= 0) |
741 | control->rts_cts_rate = baserate; | 745 | control->rts_cts_rate_idx = baserate; |
742 | else | 746 | else |
743 | control->rts_cts_rate = &sband->bitrates[0]; | 747 | control->rts_cts_rate_idx = 0; |
744 | } | 748 | } |
745 | 749 | ||
746 | if (tx->sta) { | 750 | if (tx->sta) { |
@@ -768,7 +772,11 @@ ieee80211_tx_h_load_stats(struct ieee80211_tx_data *tx) | |||
768 | struct sk_buff *skb = tx->skb; | 772 | struct sk_buff *skb = tx->skb; |
769 | struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data; | 773 | struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data; |
770 | u32 load = 0, hdrtime; | 774 | u32 load = 0, hdrtime; |
771 | struct ieee80211_rate *rate = tx->rate; | 775 | struct ieee80211_rate *rate; |
776 | struct ieee80211_supported_band *sband; | ||
777 | |||
778 | sband = tx->local->hw.wiphy->bands[tx->channel->band]; | ||
779 | rate = &sband->bitrates[tx->rate_idx]; | ||
772 | 780 | ||
773 | /* TODO: this could be part of tx_status handling, so that the number | 781 | /* TODO: this could be part of tx_status handling, so that the number |
774 | * of retries would be known; TX rate should in that case be stored | 782 | * of retries would be known; TX rate should in that case be stored |
@@ -803,7 +811,7 @@ ieee80211_tx_h_load_stats(struct ieee80211_tx_data *tx) | |||
803 | for (i = 0; i < tx->num_extra_frag; i++) { | 811 | for (i = 0; i < tx->num_extra_frag; i++) { |
804 | load += 2 * hdrtime; | 812 | load += 2 * hdrtime; |
805 | load += tx->extra_frag[i]->len * | 813 | load += tx->extra_frag[i]->len * |
806 | tx->rate->bitrate; | 814 | rate->bitrate; |
807 | } | 815 | } |
808 | } | 816 | } |
809 | 817 | ||
@@ -859,7 +867,7 @@ __ieee80211_parse_tx_radiotap(struct ieee80211_tx_data *tx, | |||
859 | int ret = ieee80211_radiotap_iterator_init(&iterator, rthdr, skb->len); | 867 | int ret = ieee80211_radiotap_iterator_init(&iterator, rthdr, skb->len); |
860 | struct ieee80211_tx_control *control = tx->control; | 868 | struct ieee80211_tx_control *control = tx->control; |
861 | 869 | ||
862 | sband = tx->local->hw.wiphy->bands[tx->local->hw.conf.channel->band]; | 870 | sband = tx->local->hw.wiphy->bands[tx->channel->band]; |
863 | 871 | ||
864 | control->flags |= IEEE80211_TXCTL_DO_NOT_ENCRYPT; | 872 | control->flags |= IEEE80211_TXCTL_DO_NOT_ENCRYPT; |
865 | tx->flags |= IEEE80211_TX_INJECTED; | 873 | tx->flags |= IEEE80211_TX_INJECTED; |
@@ -899,7 +907,7 @@ __ieee80211_parse_tx_radiotap(struct ieee80211_tx_data *tx, | |||
899 | r = &sband->bitrates[i]; | 907 | r = &sband->bitrates[i]; |
900 | 908 | ||
901 | if (r->bitrate == target_rate) { | 909 | if (r->bitrate == target_rate) { |
902 | tx->rate = r; | 910 | tx->rate_idx = i; |
903 | break; | 911 | break; |
904 | } | 912 | } |
905 | } | 913 | } |
@@ -1097,7 +1105,7 @@ static int __ieee80211_tx(struct ieee80211_local *local, struct sk_buff *skb, | |||
1097 | if (__ieee80211_queue_stopped(local, control->queue)) | 1105 | if (__ieee80211_queue_stopped(local, control->queue)) |
1098 | return IEEE80211_TX_FRAG_AGAIN; | 1106 | return IEEE80211_TX_FRAG_AGAIN; |
1099 | if (i == tx->num_extra_frag) { | 1107 | if (i == tx->num_extra_frag) { |
1100 | control->tx_rate = tx->last_frag_rate; | 1108 | control->tx_rate_idx = tx->last_frag_rate_idx; |
1101 | 1109 | ||
1102 | if (tx->flags & IEEE80211_TX_PROBE_LAST_FRAG) | 1110 | if (tx->flags & IEEE80211_TX_PROBE_LAST_FRAG) |
1103 | control->flags |= | 1111 | control->flags |= |
@@ -1155,6 +1163,7 @@ static int ieee80211_tx(struct net_device *dev, struct sk_buff *skb, | |||
1155 | 1163 | ||
1156 | sta = tx.sta; | 1164 | sta = tx.sta; |
1157 | tx.channel = local->hw.conf.channel; | 1165 | tx.channel = local->hw.conf.channel; |
1166 | control->band = tx.channel->band; | ||
1158 | 1167 | ||
1159 | for (handler = ieee80211_tx_handlers; *handler != NULL; | 1168 | for (handler = ieee80211_tx_handlers; *handler != NULL; |
1160 | handler++) { | 1169 | handler++) { |
@@ -1187,7 +1196,7 @@ static int ieee80211_tx(struct net_device *dev, struct sk_buff *skb, | |||
1187 | next_len = tx.extra_frag[i + 1]->len; | 1196 | next_len = tx.extra_frag[i + 1]->len; |
1188 | } else { | 1197 | } else { |
1189 | next_len = 0; | 1198 | next_len = 0; |
1190 | tx.rate = tx.last_frag_rate; | 1199 | tx.rate_idx = tx.last_frag_rate_idx; |
1191 | } | 1200 | } |
1192 | dur = ieee80211_duration(&tx, 0, next_len); | 1201 | dur = ieee80211_duration(&tx, 0, next_len); |
1193 | hdr->duration_id = cpu_to_le16(dur); | 1202 | hdr->duration_id = cpu_to_le16(dur); |
@@ -1224,7 +1233,7 @@ retry: | |||
1224 | store->skb = skb; | 1233 | store->skb = skb; |
1225 | store->extra_frag = tx.extra_frag; | 1234 | store->extra_frag = tx.extra_frag; |
1226 | store->num_extra_frag = tx.num_extra_frag; | 1235 | store->num_extra_frag = tx.num_extra_frag; |
1227 | store->last_frag_rate = tx.last_frag_rate; | 1236 | store->last_frag_rate_idx = tx.last_frag_rate_idx; |
1228 | store->last_frag_rate_ctrl_probe = | 1237 | store->last_frag_rate_ctrl_probe = |
1229 | !!(tx.flags & IEEE80211_TX_PROBE_LAST_FRAG); | 1238 | !!(tx.flags & IEEE80211_TX_PROBE_LAST_FRAG); |
1230 | } | 1239 | } |
@@ -1685,7 +1694,7 @@ void ieee80211_tx_pending(unsigned long data) | |||
1685 | tx.control = &store->control; | 1694 | tx.control = &store->control; |
1686 | tx.extra_frag = store->extra_frag; | 1695 | tx.extra_frag = store->extra_frag; |
1687 | tx.num_extra_frag = store->num_extra_frag; | 1696 | tx.num_extra_frag = store->num_extra_frag; |
1688 | tx.last_frag_rate = store->last_frag_rate; | 1697 | tx.last_frag_rate_idx = store->last_frag_rate_idx; |
1689 | tx.flags = 0; | 1698 | tx.flags = 0; |
1690 | if (store->last_frag_rate_ctrl_probe) | 1699 | if (store->last_frag_rate_ctrl_probe) |
1691 | tx.flags |= IEEE80211_TX_PROBE_LAST_FRAG; | 1700 | tx.flags |= IEEE80211_TX_PROBE_LAST_FRAG; |
@@ -1789,9 +1798,10 @@ struct sk_buff *ieee80211_beacon_get(struct ieee80211_hw *hw, | |||
1789 | struct ieee80211_mgmt *mgmt; | 1798 | struct ieee80211_mgmt *mgmt; |
1790 | int *num_beacons; | 1799 | int *num_beacons; |
1791 | bool err = true; | 1800 | bool err = true; |
1801 | enum ieee80211_band band = local->hw.conf.channel->band; | ||
1792 | u8 *pos; | 1802 | u8 *pos; |
1793 | 1803 | ||
1794 | sband = local->hw.wiphy->bands[local->hw.conf.channel->band]; | 1804 | sband = local->hw.wiphy->bands[band]; |
1795 | 1805 | ||
1796 | rcu_read_lock(); | 1806 | rcu_read_lock(); |
1797 | 1807 | ||
@@ -1885,8 +1895,9 @@ struct sk_buff *ieee80211_beacon_get(struct ieee80211_hw *hw, | |||
1885 | } | 1895 | } |
1886 | 1896 | ||
1887 | if (control) { | 1897 | if (control) { |
1898 | control->band = band; | ||
1888 | rate_control_get_rate(local->mdev, sband, skb, &rsel); | 1899 | rate_control_get_rate(local->mdev, sband, skb, &rsel); |
1889 | if (!rsel.rate) { | 1900 | if (unlikely(rsel.rate_idx < 0)) { |
1890 | if (net_ratelimit()) { | 1901 | if (net_ratelimit()) { |
1891 | printk(KERN_DEBUG "%s: ieee80211_beacon_get: " | 1902 | printk(KERN_DEBUG "%s: ieee80211_beacon_get: " |
1892 | "no rate found\n", | 1903 | "no rate found\n", |
@@ -1898,9 +1909,9 @@ struct sk_buff *ieee80211_beacon_get(struct ieee80211_hw *hw, | |||
1898 | } | 1909 | } |
1899 | 1910 | ||
1900 | control->vif = vif; | 1911 | control->vif = vif; |
1901 | control->tx_rate = rsel.rate; | 1912 | control->tx_rate_idx = rsel.rate_idx; |
1902 | if (sdata->bss_conf.use_short_preamble && | 1913 | if (sdata->bss_conf.use_short_preamble && |
1903 | rsel.rate->flags & IEEE80211_RATE_SHORT_PREAMBLE) | 1914 | sband->bitrates[rsel.rate_idx].flags & IEEE80211_RATE_SHORT_PREAMBLE) |
1904 | control->flags |= IEEE80211_TXCTL_SHORT_PREAMBLE; | 1915 | control->flags |= IEEE80211_TXCTL_SHORT_PREAMBLE; |
1905 | control->antenna_sel_tx = local->hw.conf.antenna_sel_tx; | 1916 | control->antenna_sel_tx = local->hw.conf.antenna_sel_tx; |
1906 | control->flags |= IEEE80211_TXCTL_NO_ACK; | 1917 | control->flags |= IEEE80211_TXCTL_NO_ACK; |
@@ -2006,6 +2017,7 @@ ieee80211_get_buffered_bc(struct ieee80211_hw *hw, | |||
2006 | sta = tx.sta; | 2017 | sta = tx.sta; |
2007 | tx.flags |= IEEE80211_TX_PS_BUFFERED; | 2018 | tx.flags |= IEEE80211_TX_PS_BUFFERED; |
2008 | tx.channel = local->hw.conf.channel; | 2019 | tx.channel = local->hw.conf.channel; |
2020 | control->band = tx.channel->band; | ||
2009 | 2021 | ||
2010 | for (handler = ieee80211_tx_handlers; *handler != NULL; handler++) { | 2022 | for (handler = ieee80211_tx_handlers; *handler != NULL; handler++) { |
2011 | res = (*handler)(&tx); | 2023 | res = (*handler)(&tx); |
diff --git a/net/mac80211/util.c b/net/mac80211/util.c index 800c15aff6e7..65a34fddeb00 100644 --- a/net/mac80211/util.c +++ b/net/mac80211/util.c | |||
@@ -266,10 +266,13 @@ __le16 ieee80211_rts_duration(struct ieee80211_hw *hw, | |||
266 | bool short_preamble; | 266 | bool short_preamble; |
267 | int erp; | 267 | int erp; |
268 | u16 dur; | 268 | u16 dur; |
269 | struct ieee80211_supported_band *sband; | ||
270 | |||
271 | sband = local->hw.wiphy->bands[local->hw.conf.channel->band]; | ||
269 | 272 | ||
270 | short_preamble = sdata->bss_conf.use_short_preamble; | 273 | short_preamble = sdata->bss_conf.use_short_preamble; |
271 | 274 | ||
272 | rate = frame_txctl->rts_cts_rate; | 275 | rate = &sband->bitrates[frame_txctl->rts_cts_rate_idx]; |
273 | 276 | ||
274 | erp = 0; | 277 | erp = 0; |
275 | if (sdata->flags & IEEE80211_SDATA_OPERATING_GMODE) | 278 | if (sdata->flags & IEEE80211_SDATA_OPERATING_GMODE) |
@@ -300,10 +303,13 @@ __le16 ieee80211_ctstoself_duration(struct ieee80211_hw *hw, | |||
300 | bool short_preamble; | 303 | bool short_preamble; |
301 | int erp; | 304 | int erp; |
302 | u16 dur; | 305 | u16 dur; |
306 | struct ieee80211_supported_band *sband; | ||
307 | |||
308 | sband = local->hw.wiphy->bands[local->hw.conf.channel->band]; | ||
303 | 309 | ||
304 | short_preamble = sdata->bss_conf.use_short_preamble; | 310 | short_preamble = sdata->bss_conf.use_short_preamble; |
305 | 311 | ||
306 | rate = frame_txctl->rts_cts_rate; | 312 | rate = &sband->bitrates[frame_txctl->rts_cts_rate_idx]; |
307 | erp = 0; | 313 | erp = 0; |
308 | if (sdata->flags & IEEE80211_SDATA_OPERATING_GMODE) | 314 | if (sdata->flags & IEEE80211_SDATA_OPERATING_GMODE) |
309 | erp = rate->flags & IEEE80211_RATE_ERP_G; | 315 | erp = rate->flags & IEEE80211_RATE_ERP_G; |