aboutsummaryrefslogtreecommitdiffstats
path: root/net/mac80211/tx.c
diff options
context:
space:
mode:
authorJohannes Berg <johannes@sipsolutions.net>2008-05-15 06:55:27 -0400
committerJohn W. Linville <linville@tuxdriver.com>2008-05-21 21:48:09 -0400
commit2e92e6f2c50b4baf85cca968f0e6f1b5c0df7d39 (patch)
treee845c2f3af6d29c807c540366b97b1d886b92c91 /net/mac80211/tx.c
parent36d6825b91bc492b65b6333c369cd96a2fc8c903 (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.c104
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);