diff options
Diffstat (limited to 'net/mac80211/tx.c')
-rw-r--r-- | net/mac80211/tx.c | 104 |
1 files changed, 58 insertions, 46 deletions
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); |