diff options
author | Johannes Berg <johannes@sipsolutions.net> | 2008-05-15 06:55:27 -0400 |
---|---|---|
committer | John W. Linville <linville@tuxdriver.com> | 2008-05-21 21:48:09 -0400 |
commit | 2e92e6f2c50b4baf85cca968f0e6f1b5c0df7d39 (patch) | |
tree | e845c2f3af6d29c807c540366b97b1d886b92c91 /net/mac80211/tx.c | |
parent | 36d6825b91bc492b65b6333c369cd96a2fc8c903 (diff) |
mac80211: use rate index in TX control
This patch modifies struct ieee80211_tx_control to give band
info and the rate index (instead of rate pointers) to drivers.
This mostly serves to reduce the TX control structure size to
make it fit into skb->cb so that the fragmentation code can
put it there and we can think about passing it to drivers that
way in the future.
The rt2x00 driver update was done by Ivo, thanks.
Signed-off-by: Ivo van Doorn <IvDoorn@gmail.com>
Signed-off-by: Johannes Berg <johannes@sipsolutions.net>
Signed-off-by: John W. Linville <linville@tuxdriver.com>
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); |