diff options
author | Felix Fietkau <nbd@openwrt.org> | 2011-09-14 15:24:22 -0400 |
---|---|---|
committer | John W. Linville <linville@tuxdriver.com> | 2011-09-16 16:45:40 -0400 |
commit | 493cf04fd37bf265dc3c9aad357e3e34654c86e3 (patch) | |
tree | 834da35a27d459a4ed0a8208616a51e327c29ba5 /drivers/net/wireless/ath | |
parent | 2b63a41d14245345d6c498506c5634613afa80c0 (diff) |
ath9k: use the new API for setting tx descriptors
With the new API, tx descriptors can be written in one single pass
instead of having to re-read and rewrite fields from multiple places.
This makes the code easier to read and also slightly improves performance
on embedded MIPS hardware.
Signed-off-by: Felix Fietkau <nbd@openwrt.org>
Signed-off-by: John W. Linville <linville@tuxdriver.com>
Diffstat (limited to 'drivers/net/wireless/ath')
-rw-r--r-- | drivers/net/wireless/ath/ath9k/ath9k.h | 1 | ||||
-rw-r--r-- | drivers/net/wireless/ath/ath9k/beacon.c | 52 | ||||
-rw-r--r-- | drivers/net/wireless/ath/ath9k/xmit.c | 229 |
3 files changed, 122 insertions, 160 deletions
diff --git a/drivers/net/wireless/ath/ath9k/ath9k.h b/drivers/net/wireless/ath/ath9k/ath9k.h index 4eba9577386b..94d887b65e69 100644 --- a/drivers/net/wireless/ath/ath9k/ath9k.h +++ b/drivers/net/wireless/ath/ath9k/ath9k.h | |||
@@ -228,7 +228,6 @@ struct ath_buf { | |||
228 | dma_addr_t bf_daddr; /* physical addr of desc */ | 228 | dma_addr_t bf_daddr; /* physical addr of desc */ |
229 | dma_addr_t bf_buf_addr; /* physical addr of data buffer, for DMA */ | 229 | dma_addr_t bf_buf_addr; /* physical addr of data buffer, for DMA */ |
230 | bool bf_stale; | 230 | bool bf_stale; |
231 | u16 bf_flags; | ||
232 | struct ath_buf_state bf_state; | 231 | struct ath_buf_state bf_state; |
233 | }; | 232 | }; |
234 | 233 | ||
diff --git a/drivers/net/wireless/ath/ath9k/beacon.c b/drivers/net/wireless/ath/ath9k/beacon.c index b97d01d2eece..9cdeaebc844f 100644 --- a/drivers/net/wireless/ath/ath9k/beacon.c +++ b/drivers/net/wireless/ath/ath9k/beacon.c | |||
@@ -73,45 +73,39 @@ static void ath_beacon_setup(struct ath_softc *sc, struct ath_vif *avp, | |||
73 | struct sk_buff *skb = bf->bf_mpdu; | 73 | struct sk_buff *skb = bf->bf_mpdu; |
74 | struct ath_hw *ah = sc->sc_ah; | 74 | struct ath_hw *ah = sc->sc_ah; |
75 | struct ath_common *common = ath9k_hw_common(ah); | 75 | struct ath_common *common = ath9k_hw_common(ah); |
76 | struct ath_desc *ds; | 76 | struct ath_tx_info info; |
77 | struct ath9k_11n_rate_series series[4]; | ||
78 | int flags, ctsrate = 0, ctsduration = 0; | ||
79 | struct ieee80211_supported_band *sband; | 77 | struct ieee80211_supported_band *sband; |
78 | u8 chainmask = ah->txchainmask; | ||
80 | u8 rate = 0; | 79 | u8 rate = 0; |
81 | 80 | ||
82 | ath9k_reset_beacon_status(sc); | 81 | ath9k_reset_beacon_status(sc); |
83 | 82 | ||
84 | ds = bf->bf_desc; | ||
85 | flags = ATH9K_TXDESC_NOACK; | ||
86 | |||
87 | ds->ds_link = 0; | ||
88 | |||
89 | sband = &sc->sbands[common->hw->conf.channel->band]; | 83 | sband = &sc->sbands[common->hw->conf.channel->band]; |
90 | rate = sband->bitrates[rateidx].hw_value; | 84 | rate = sband->bitrates[rateidx].hw_value; |
91 | if (sc->sc_flags & SC_OP_PREAMBLE_SHORT) | 85 | if (sc->sc_flags & SC_OP_PREAMBLE_SHORT) |
92 | rate |= sband->bitrates[rateidx].hw_value_short; | 86 | rate |= sband->bitrates[rateidx].hw_value_short; |
93 | 87 | ||
94 | ath9k_hw_set11n_txdesc(ah, ds, skb->len + FCS_LEN, | 88 | memset(&info, 0, sizeof(info)); |
95 | ATH9K_PKT_TYPE_BEACON, | 89 | info.pkt_len = skb->len + FCS_LEN; |
96 | MAX_RATE_POWER, | 90 | info.type = ATH9K_PKT_TYPE_BEACON; |
97 | ATH9K_TXKEYIX_INVALID, | 91 | info.txpower = MAX_RATE_POWER; |
98 | ATH9K_KEY_TYPE_CLEAR, | 92 | info.keyix = ATH9K_TXKEYIX_INVALID; |
99 | flags); | 93 | info.keytype = ATH9K_KEY_TYPE_CLEAR; |
100 | 94 | info.flags = ATH9K_TXDESC_NOACK; | |
101 | /* NB: beacon's BufLen must be a multiple of 4 bytes */ | 95 | |
102 | ath9k_hw_filltxdesc(ah, ds, roundup(skb->len, 4), | 96 | info.buf_addr[0] = bf->bf_buf_addr; |
103 | true, true, ds, bf->bf_buf_addr, | 97 | info.buf_len[0] = roundup(skb->len, 4); |
104 | sc->beacon.beaconq); | 98 | |
105 | 99 | info.is_first = true; | |
106 | memset(series, 0, sizeof(struct ath9k_11n_rate_series) * 4); | 100 | info.is_last = true; |
107 | series[0].Tries = 1; | 101 | |
108 | series[0].Rate = rate; | 102 | info.qcu = sc->beacon.beaconq; |
109 | series[0].ChSel = ath_txchainmask_reduction(sc, | 103 | |
110 | ah->txchainmask, series[0].Rate); | 104 | info.rates[0].Tries = 1; |
111 | series[0].RateFlags = (ctsrate) ? ATH9K_RATESERIES_RTS_CTS : 0; | 105 | info.rates[0].Rate = rate; |
112 | ath9k_hw_set11n_ratescenario(ah, ds, ds, 0, ctsrate, ctsduration, | 106 | info.rates[0].ChSel = ath_txchainmask_reduction(sc, chainmask, rate); |
113 | series, 4, 0); | 107 | |
114 | ath9k_hw_set_desc_link(ah, ds, 0); | 108 | ath9k_hw_set_txdesc(ah, bf->bf_desc, &info); |
115 | } | 109 | } |
116 | 110 | ||
117 | static void ath_tx_cabq(struct ieee80211_hw *hw, struct sk_buff *skb) | 111 | static void ath_tx_cabq(struct ieee80211_hw *hw, struct sk_buff *skb) |
diff --git a/drivers/net/wireless/ath/ath9k/xmit.c b/drivers/net/wireless/ath/ath9k/xmit.c index 485c0a3a9ce1..7f8191eddebe 100644 --- a/drivers/net/wireless/ath/ath9k/xmit.c +++ b/drivers/net/wireless/ath/ath9k/xmit.c | |||
@@ -504,7 +504,6 @@ static void ath_tx_complete_aggr(struct ath_softc *sc, struct ath_txq *txq, | |||
504 | !txfail, sendbar); | 504 | !txfail, sendbar); |
505 | } else { | 505 | } else { |
506 | /* retry the un-acked ones */ | 506 | /* retry the un-acked ones */ |
507 | ath9k_hw_set_clrdmask(sc->sc_ah, bf->bf_desc, false); | ||
508 | if (!(sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_EDMA)) { | 507 | if (!(sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_EDMA)) { |
509 | if (bf->bf_next == NULL && bf_last->bf_stale) { | 508 | if (bf->bf_next == NULL && bf_last->bf_stale) { |
510 | struct ath_buf *tbf; | 509 | struct ath_buf *tbf; |
@@ -528,16 +527,7 @@ static void ath_tx_complete_aggr(struct ath_softc *sc, struct ath_txq *txq, | |||
528 | break; | 527 | break; |
529 | } | 528 | } |
530 | 529 | ||
531 | ath9k_hw_cleartxdesc(sc->sc_ah, | ||
532 | tbf->bf_desc); | ||
533 | fi->bf = tbf; | 530 | fi->bf = tbf; |
534 | } else { | ||
535 | /* | ||
536 | * Clear descriptor status words for | ||
537 | * software retry | ||
538 | */ | ||
539 | ath9k_hw_cleartxdesc(sc->sc_ah, | ||
540 | bf->bf_desc); | ||
541 | } | 531 | } |
542 | } | 532 | } |
543 | 533 | ||
@@ -873,26 +863,25 @@ static u32 ath_pkt_duration(struct ath_softc *sc, u8 rix, int pktlen, | |||
873 | return duration; | 863 | return duration; |
874 | } | 864 | } |
875 | 865 | ||
876 | static void ath_buf_set_rate(struct ath_softc *sc, struct ath_buf *bf, int len) | 866 | static void ath_buf_set_rate(struct ath_softc *sc, struct ath_buf *bf, |
867 | struct ath_tx_info *info, int len) | ||
877 | { | 868 | { |
878 | struct ath_hw *ah = sc->sc_ah; | 869 | struct ath_hw *ah = sc->sc_ah; |
879 | struct ath9k_11n_rate_series series[4]; | ||
880 | struct sk_buff *skb; | 870 | struct sk_buff *skb; |
881 | struct ieee80211_tx_info *tx_info; | 871 | struct ieee80211_tx_info *tx_info; |
882 | struct ieee80211_tx_rate *rates; | 872 | struct ieee80211_tx_rate *rates; |
883 | const struct ieee80211_rate *rate; | 873 | const struct ieee80211_rate *rate; |
884 | struct ieee80211_hdr *hdr; | 874 | struct ieee80211_hdr *hdr; |
885 | int i, flags = 0; | 875 | int i; |
886 | u8 rix = 0, ctsrate = 0; | 876 | u8 rix = 0; |
887 | bool is_pspoll; | ||
888 | |||
889 | memset(series, 0, sizeof(struct ath9k_11n_rate_series) * 4); | ||
890 | 877 | ||
891 | skb = bf->bf_mpdu; | 878 | skb = bf->bf_mpdu; |
892 | tx_info = IEEE80211_SKB_CB(skb); | 879 | tx_info = IEEE80211_SKB_CB(skb); |
893 | rates = tx_info->control.rates; | 880 | rates = tx_info->control.rates; |
894 | hdr = (struct ieee80211_hdr *)skb->data; | 881 | hdr = (struct ieee80211_hdr *)skb->data; |
895 | is_pspoll = ieee80211_is_pspoll(hdr->frame_control); | 882 | |
883 | /* set dur_update_en for l-sig computation except for PS-Poll frames */ | ||
884 | info->dur_update = !ieee80211_is_pspoll(hdr->frame_control); | ||
896 | 885 | ||
897 | /* | 886 | /* |
898 | * We check if Short Preamble is needed for the CTS rate by | 887 | * We check if Short Preamble is needed for the CTS rate by |
@@ -900,9 +889,9 @@ static void ath_buf_set_rate(struct ath_softc *sc, struct ath_buf *bf, int len) | |||
900 | * But for the rate series, IEEE80211_TX_RC_USE_SHORT_PREAMBLE is used. | 889 | * But for the rate series, IEEE80211_TX_RC_USE_SHORT_PREAMBLE is used. |
901 | */ | 890 | */ |
902 | rate = ieee80211_get_rts_cts_rate(sc->hw, tx_info); | 891 | rate = ieee80211_get_rts_cts_rate(sc->hw, tx_info); |
903 | ctsrate = rate->hw_value; | 892 | info->rtscts_rate = rate->hw_value; |
904 | if (sc->sc_flags & SC_OP_PREAMBLE_SHORT) | 893 | if (sc->sc_flags & SC_OP_PREAMBLE_SHORT) |
905 | ctsrate |= rate->hw_value_short; | 894 | info->rtscts_rate |= rate->hw_value_short; |
906 | 895 | ||
907 | for (i = 0; i < 4; i++) { | 896 | for (i = 0; i < 4; i++) { |
908 | bool is_40, is_sgi, is_sp; | 897 | bool is_40, is_sgi, is_sp; |
@@ -912,20 +901,20 @@ static void ath_buf_set_rate(struct ath_softc *sc, struct ath_buf *bf, int len) | |||
912 | continue; | 901 | continue; |
913 | 902 | ||
914 | rix = rates[i].idx; | 903 | rix = rates[i].idx; |
915 | series[i].Tries = rates[i].count; | 904 | info->rates[i].Tries = rates[i].count; |
916 | 905 | ||
917 | if (rates[i].flags & IEEE80211_TX_RC_USE_RTS_CTS) { | 906 | if (rates[i].flags & IEEE80211_TX_RC_USE_RTS_CTS) { |
918 | series[i].RateFlags |= ATH9K_RATESERIES_RTS_CTS; | 907 | info->rates[i].RateFlags |= ATH9K_RATESERIES_RTS_CTS; |
919 | flags |= ATH9K_TXDESC_RTSENA; | 908 | info->flags |= ATH9K_TXDESC_RTSENA; |
920 | } else if (rates[i].flags & IEEE80211_TX_RC_USE_CTS_PROTECT) { | 909 | } else if (rates[i].flags & IEEE80211_TX_RC_USE_CTS_PROTECT) { |
921 | series[i].RateFlags |= ATH9K_RATESERIES_RTS_CTS; | 910 | info->rates[i].RateFlags |= ATH9K_RATESERIES_RTS_CTS; |
922 | flags |= ATH9K_TXDESC_CTSENA; | 911 | info->flags |= ATH9K_TXDESC_CTSENA; |
923 | } | 912 | } |
924 | 913 | ||
925 | if (rates[i].flags & IEEE80211_TX_RC_40_MHZ_WIDTH) | 914 | if (rates[i].flags & IEEE80211_TX_RC_40_MHZ_WIDTH) |
926 | series[i].RateFlags |= ATH9K_RATESERIES_2040; | 915 | info->rates[i].RateFlags |= ATH9K_RATESERIES_2040; |
927 | if (rates[i].flags & IEEE80211_TX_RC_SHORT_GI) | 916 | if (rates[i].flags & IEEE80211_TX_RC_SHORT_GI) |
928 | series[i].RateFlags |= ATH9K_RATESERIES_HALFGI; | 917 | info->rates[i].RateFlags |= ATH9K_RATESERIES_HALFGI; |
929 | 918 | ||
930 | is_sgi = !!(rates[i].flags & IEEE80211_TX_RC_SHORT_GI); | 919 | is_sgi = !!(rates[i].flags & IEEE80211_TX_RC_SHORT_GI); |
931 | is_40 = !!(rates[i].flags & IEEE80211_TX_RC_40_MHZ_WIDTH); | 920 | is_40 = !!(rates[i].flags & IEEE80211_TX_RC_40_MHZ_WIDTH); |
@@ -933,13 +922,13 @@ static void ath_buf_set_rate(struct ath_softc *sc, struct ath_buf *bf, int len) | |||
933 | 922 | ||
934 | if (rates[i].flags & IEEE80211_TX_RC_MCS) { | 923 | if (rates[i].flags & IEEE80211_TX_RC_MCS) { |
935 | /* MCS rates */ | 924 | /* MCS rates */ |
936 | series[i].Rate = rix | 0x80; | 925 | info->rates[i].Rate = rix | 0x80; |
937 | series[i].ChSel = ath_txchainmask_reduction(sc, | 926 | info->rates[i].ChSel = ath_txchainmask_reduction(sc, |
938 | ah->txchainmask, series[i].Rate); | 927 | ah->txchainmask, info->rates[i].Rate); |
939 | series[i].PktDuration = ath_pkt_duration(sc, rix, len, | 928 | info->rates[i].PktDuration = ath_pkt_duration(sc, rix, len, |
940 | is_40, is_sgi, is_sp); | 929 | is_40, is_sgi, is_sp); |
941 | if (rix < 8 && (tx_info->flags & IEEE80211_TX_CTL_STBC)) | 930 | if (rix < 8 && (tx_info->flags & IEEE80211_TX_CTL_STBC)) |
942 | series[i].RateFlags |= ATH9K_RATESERIES_STBC; | 931 | info->rates[i].RateFlags |= ATH9K_RATESERIES_STBC; |
943 | continue; | 932 | continue; |
944 | } | 933 | } |
945 | 934 | ||
@@ -951,74 +940,115 @@ static void ath_buf_set_rate(struct ath_softc *sc, struct ath_buf *bf, int len) | |||
951 | phy = WLAN_RC_PHY_OFDM; | 940 | phy = WLAN_RC_PHY_OFDM; |
952 | 941 | ||
953 | rate = &sc->sbands[tx_info->band].bitrates[rates[i].idx]; | 942 | rate = &sc->sbands[tx_info->band].bitrates[rates[i].idx]; |
954 | series[i].Rate = rate->hw_value; | 943 | info->rates[i].Rate = rate->hw_value; |
955 | if (rate->hw_value_short) { | 944 | if (rate->hw_value_short) { |
956 | if (rates[i].flags & IEEE80211_TX_RC_USE_SHORT_PREAMBLE) | 945 | if (rates[i].flags & IEEE80211_TX_RC_USE_SHORT_PREAMBLE) |
957 | series[i].Rate |= rate->hw_value_short; | 946 | info->rates[i].Rate |= rate->hw_value_short; |
958 | } else { | 947 | } else { |
959 | is_sp = false; | 948 | is_sp = false; |
960 | } | 949 | } |
961 | 950 | ||
962 | if (bf->bf_state.bfs_paprd) | 951 | if (bf->bf_state.bfs_paprd) |
963 | series[i].ChSel = ah->txchainmask; | 952 | info->rates[i].ChSel = ah->txchainmask; |
964 | else | 953 | else |
965 | series[i].ChSel = ath_txchainmask_reduction(sc, | 954 | info->rates[i].ChSel = ath_txchainmask_reduction(sc, |
966 | ah->txchainmask, series[i].Rate); | 955 | ah->txchainmask, info->rates[i].Rate); |
967 | 956 | ||
968 | series[i].PktDuration = ath9k_hw_computetxtime(sc->sc_ah, | 957 | info->rates[i].PktDuration = ath9k_hw_computetxtime(sc->sc_ah, |
969 | phy, rate->bitrate * 100, len, rix, is_sp); | 958 | phy, rate->bitrate * 100, len, rix, is_sp); |
970 | } | 959 | } |
971 | 960 | ||
972 | /* For AR5416 - RTS cannot be followed by a frame larger than 8K */ | 961 | /* For AR5416 - RTS cannot be followed by a frame larger than 8K */ |
973 | if (bf_isaggr(bf) && (len > sc->sc_ah->caps.rts_aggr_limit)) | 962 | if (bf_isaggr(bf) && (len > sc->sc_ah->caps.rts_aggr_limit)) |
974 | flags &= ~ATH9K_TXDESC_RTSENA; | 963 | info->flags &= ~ATH9K_TXDESC_RTSENA; |
975 | 964 | ||
976 | /* ATH9K_TXDESC_RTSENA and ATH9K_TXDESC_CTSENA are mutually exclusive. */ | 965 | /* ATH9K_TXDESC_RTSENA and ATH9K_TXDESC_CTSENA are mutually exclusive. */ |
977 | if (flags & ATH9K_TXDESC_RTSENA) | 966 | if (info->flags & ATH9K_TXDESC_RTSENA) |
978 | flags &= ~ATH9K_TXDESC_CTSENA; | 967 | info->flags &= ~ATH9K_TXDESC_CTSENA; |
968 | } | ||
979 | 969 | ||
980 | /* set dur_update_en for l-sig computation except for PS-Poll frames */ | 970 | static enum ath9k_pkt_type get_hw_packet_type(struct sk_buff *skb) |
981 | ath9k_hw_set11n_ratescenario(sc->sc_ah, bf->bf_desc, | 971 | { |
982 | bf->bf_lastbf->bf_desc, | 972 | struct ieee80211_hdr *hdr; |
983 | !is_pspoll, ctsrate, | 973 | enum ath9k_pkt_type htype; |
984 | 0, series, 4, flags); | 974 | __le16 fc; |
975 | |||
976 | hdr = (struct ieee80211_hdr *)skb->data; | ||
977 | fc = hdr->frame_control; | ||
978 | |||
979 | if (ieee80211_is_beacon(fc)) | ||
980 | htype = ATH9K_PKT_TYPE_BEACON; | ||
981 | else if (ieee80211_is_probe_resp(fc)) | ||
982 | htype = ATH9K_PKT_TYPE_PROBE_RESP; | ||
983 | else if (ieee80211_is_atim(fc)) | ||
984 | htype = ATH9K_PKT_TYPE_ATIM; | ||
985 | else if (ieee80211_is_pspoll(fc)) | ||
986 | htype = ATH9K_PKT_TYPE_PSPOLL; | ||
987 | else | ||
988 | htype = ATH9K_PKT_TYPE_NORMAL; | ||
985 | 989 | ||
990 | return htype; | ||
986 | } | 991 | } |
987 | 992 | ||
988 | static void ath_tx_fill_desc(struct ath_softc *sc, struct ath_buf *bf, int len) | 993 | static void ath_tx_fill_desc(struct ath_softc *sc, struct ath_buf *bf, |
994 | struct ath_txq *txq, int len) | ||
989 | { | 995 | { |
990 | struct ath_hw *ah = sc->sc_ah; | 996 | struct ath_hw *ah = sc->sc_ah; |
991 | struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(bf->bf_mpdu); | 997 | struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(bf->bf_mpdu); |
992 | struct ath_buf *bf_first = bf; | 998 | struct ath_buf *bf_first = bf; |
993 | 999 | struct ath_tx_info info; | |
994 | bool aggr = !!(bf->bf_state.bf_type & BUF_AGGR); | 1000 | bool aggr = !!(bf->bf_state.bf_type & BUF_AGGR); |
995 | bool clrdmask = !!(tx_info->flags & IEEE80211_TX_CTL_CLEAR_PS_FILT); | ||
996 | 1001 | ||
997 | u32 ds_next; | 1002 | memset(&info, 0, sizeof(info)); |
1003 | info.is_first = true; | ||
1004 | info.is_last = true; | ||
1005 | info.txpower = MAX_RATE_POWER; | ||
1006 | info.qcu = txq->axq_qnum; | ||
1007 | |||
1008 | info.flags = ATH9K_TXDESC_INTREQ; | ||
1009 | if (tx_info->flags & IEEE80211_TX_CTL_NO_ACK) | ||
1010 | info.flags |= ATH9K_TXDESC_NOACK; | ||
1011 | if (tx_info->flags & IEEE80211_TX_CTL_LDPC) | ||
1012 | info.flags |= ATH9K_TXDESC_LDPC; | ||
1013 | |||
1014 | ath_buf_set_rate(sc, bf, &info, len); | ||
1015 | |||
1016 | if (tx_info->flags & IEEE80211_TX_CTL_CLEAR_PS_FILT) | ||
1017 | info.flags |= ATH9K_TXDESC_CLRDMASK; | ||
1018 | |||
1019 | if (bf->bf_state.bfs_paprd) | ||
1020 | info.flags |= (u32) bf->bf_state.bfs_paprd << ATH9K_TXDESC_PAPRD_S; | ||
998 | 1021 | ||
999 | ath_buf_set_rate(sc, bf, len); | ||
1000 | 1022 | ||
1001 | while (bf) { | 1023 | while (bf) { |
1024 | struct sk_buff *skb = bf->bf_mpdu; | ||
1025 | struct ath_frame_info *fi = get_frame_info(skb); | ||
1026 | |||
1027 | info.type = get_hw_packet_type(skb); | ||
1002 | if (bf->bf_next) | 1028 | if (bf->bf_next) |
1003 | ds_next = bf->bf_next->bf_daddr; | 1029 | info.link = bf->bf_next->bf_daddr; |
1004 | else | 1030 | else |
1005 | ds_next = 0; | 1031 | info.link = 0; |
1006 | 1032 | ||
1007 | ath9k_hw_set_clrdmask(sc->sc_ah, bf->bf_desc, clrdmask); | 1033 | info.buf_addr[0] = bf->bf_buf_addr; |
1008 | if (!aggr) | 1034 | info.buf_len[0] = skb->len; |
1009 | ath9k_hw_clr11n_aggr(sc->sc_ah, bf->bf_desc); | 1035 | info.pkt_len = fi->framelen; |
1010 | else if (!bf->bf_next) | 1036 | info.keyix = fi->keyix; |
1011 | ath9k_hw_set11n_aggr_last(sc->sc_ah, bf->bf_desc); | 1037 | info.keytype = fi->keytype; |
1012 | else { | 1038 | |
1039 | if (aggr) { | ||
1013 | if (bf == bf_first) | 1040 | if (bf == bf_first) |
1014 | ath9k_hw_set11n_aggr_first(sc->sc_ah, | 1041 | info.aggr = AGGR_BUF_FIRST; |
1015 | bf->bf_desc, len); | 1042 | else if (!bf->bf_next) |
1043 | info.aggr = AGGR_BUF_LAST; | ||
1044 | else | ||
1045 | info.aggr = AGGR_BUF_MIDDLE; | ||
1016 | 1046 | ||
1017 | ath9k_hw_set11n_aggr_middle(sc->sc_ah, bf->bf_desc, | 1047 | info.ndelim = bf->bf_state.ndelim; |
1018 | bf->bf_state.ndelim); | 1048 | info.aggr_len = len; |
1019 | } | 1049 | } |
1020 | 1050 | ||
1021 | ath9k_hw_set_desc_link(ah, bf->bf_desc, ds_next); | 1051 | ath9k_hw_set_txdesc(ah, bf->bf_desc, &info); |
1022 | bf = bf->bf_next; | 1052 | bf = bf->bf_next; |
1023 | } | 1053 | } |
1024 | } | 1054 | } |
@@ -1066,7 +1096,7 @@ static void ath_tx_sched_aggr(struct ath_softc *sc, struct ath_txq *txq, | |||
1066 | TX_STAT_INC(txq->axq_qnum, a_aggr); | 1096 | TX_STAT_INC(txq->axq_qnum, a_aggr); |
1067 | } | 1097 | } |
1068 | 1098 | ||
1069 | ath_tx_fill_desc(sc, bf, aggr_len); | 1099 | ath_tx_fill_desc(sc, bf, txq, aggr_len); |
1070 | ath_tx_txqaddbuf(sc, txq, &bf_q, false); | 1100 | ath_tx_txqaddbuf(sc, txq, &bf_q, false); |
1071 | } while (txq->axq_ampdu_depth < ATH_AGGR_MIN_QDEPTH && | 1101 | } while (txq->axq_ampdu_depth < ATH_AGGR_MIN_QDEPTH && |
1072 | status != ATH_AGGR_BAW_CLOSED); | 1102 | status != ATH_AGGR_BAW_CLOSED); |
@@ -1655,7 +1685,7 @@ static void ath_tx_send_ampdu(struct ath_softc *sc, struct ath_atx_tid *tid, | |||
1655 | /* Queue to h/w without aggregation */ | 1685 | /* Queue to h/w without aggregation */ |
1656 | TX_STAT_INC(txctl->txq->axq_qnum, a_queued_hw); | 1686 | TX_STAT_INC(txctl->txq->axq_qnum, a_queued_hw); |
1657 | bf->bf_lastbf = bf; | 1687 | bf->bf_lastbf = bf; |
1658 | ath_tx_fill_desc(sc, bf, fi->framelen); | 1688 | ath_tx_fill_desc(sc, bf, txctl->txq, fi->framelen); |
1659 | ath_tx_txqaddbuf(sc, txctl->txq, &bf_head, false); | 1689 | ath_tx_txqaddbuf(sc, txctl->txq, &bf_head, false); |
1660 | } | 1690 | } |
1661 | 1691 | ||
@@ -1682,34 +1712,11 @@ static void ath_tx_send_normal(struct ath_softc *sc, struct ath_txq *txq, | |||
1682 | INCR(tid->seq_start, IEEE80211_SEQ_MAX); | 1712 | INCR(tid->seq_start, IEEE80211_SEQ_MAX); |
1683 | 1713 | ||
1684 | bf->bf_lastbf = bf; | 1714 | bf->bf_lastbf = bf; |
1685 | ath_tx_fill_desc(sc, bf, fi->framelen); | 1715 | ath_tx_fill_desc(sc, bf, txq, fi->framelen); |
1686 | ath_tx_txqaddbuf(sc, txq, &bf_head, false); | 1716 | ath_tx_txqaddbuf(sc, txq, &bf_head, false); |
1687 | TX_STAT_INC(txq->axq_qnum, queued); | 1717 | TX_STAT_INC(txq->axq_qnum, queued); |
1688 | } | 1718 | } |
1689 | 1719 | ||
1690 | static enum ath9k_pkt_type get_hw_packet_type(struct sk_buff *skb) | ||
1691 | { | ||
1692 | struct ieee80211_hdr *hdr; | ||
1693 | enum ath9k_pkt_type htype; | ||
1694 | __le16 fc; | ||
1695 | |||
1696 | hdr = (struct ieee80211_hdr *)skb->data; | ||
1697 | fc = hdr->frame_control; | ||
1698 | |||
1699 | if (ieee80211_is_beacon(fc)) | ||
1700 | htype = ATH9K_PKT_TYPE_BEACON; | ||
1701 | else if (ieee80211_is_probe_resp(fc)) | ||
1702 | htype = ATH9K_PKT_TYPE_PROBE_RESP; | ||
1703 | else if (ieee80211_is_atim(fc)) | ||
1704 | htype = ATH9K_PKT_TYPE_ATIM; | ||
1705 | else if (ieee80211_is_pspoll(fc)) | ||
1706 | htype = ATH9K_PKT_TYPE_PSPOLL; | ||
1707 | else | ||
1708 | htype = ATH9K_PKT_TYPE_NORMAL; | ||
1709 | |||
1710 | return htype; | ||
1711 | } | ||
1712 | |||
1713 | static void setup_frame_info(struct ieee80211_hw *hw, struct sk_buff *skb, | 1720 | static void setup_frame_info(struct ieee80211_hw *hw, struct sk_buff *skb, |
1714 | int framelen) | 1721 | int framelen) |
1715 | { | 1722 | { |
@@ -1737,22 +1744,6 @@ static void setup_frame_info(struct ieee80211_hw *hw, struct sk_buff *skb, | |||
1737 | fi->framelen = framelen; | 1744 | fi->framelen = framelen; |
1738 | } | 1745 | } |
1739 | 1746 | ||
1740 | static int setup_tx_flags(struct sk_buff *skb) | ||
1741 | { | ||
1742 | struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(skb); | ||
1743 | int flags = 0; | ||
1744 | |||
1745 | flags |= ATH9K_TXDESC_INTREQ; | ||
1746 | |||
1747 | if (tx_info->flags & IEEE80211_TX_CTL_NO_ACK) | ||
1748 | flags |= ATH9K_TXDESC_NOACK; | ||
1749 | |||
1750 | if (tx_info->flags & IEEE80211_TX_CTL_LDPC) | ||
1751 | flags |= ATH9K_TXDESC_LDPC; | ||
1752 | |||
1753 | return flags; | ||
1754 | } | ||
1755 | |||
1756 | u8 ath_txchainmask_reduction(struct ath_softc *sc, u8 chainmask, u32 rate) | 1747 | u8 ath_txchainmask_reduction(struct ath_softc *sc, u8 chainmask, u32 rate) |
1757 | { | 1748 | { |
1758 | struct ath_hw *ah = sc->sc_ah; | 1749 | struct ath_hw *ah = sc->sc_ah; |
@@ -1774,13 +1765,10 @@ static struct ath_buf *ath_tx_setup_buffer(struct ath_softc *sc, | |||
1774 | struct ath_atx_tid *tid, | 1765 | struct ath_atx_tid *tid, |
1775 | struct sk_buff *skb) | 1766 | struct sk_buff *skb) |
1776 | { | 1767 | { |
1777 | struct ath_hw *ah = sc->sc_ah; | ||
1778 | struct ath_common *common = ath9k_hw_common(sc->sc_ah); | 1768 | struct ath_common *common = ath9k_hw_common(sc->sc_ah); |
1779 | struct ath_frame_info *fi = get_frame_info(skb); | 1769 | struct ath_frame_info *fi = get_frame_info(skb); |
1780 | struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data; | 1770 | struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data; |
1781 | struct ath_buf *bf; | 1771 | struct ath_buf *bf; |
1782 | struct ath_desc *ds; | ||
1783 | int frm_type; | ||
1784 | u16 seqno; | 1772 | u16 seqno; |
1785 | 1773 | ||
1786 | bf = ath_tx_get_buffer(sc); | 1774 | bf = ath_tx_get_buffer(sc); |
@@ -1798,7 +1786,6 @@ static struct ath_buf *ath_tx_setup_buffer(struct ath_softc *sc, | |||
1798 | bf->bf_state.seqno = seqno; | 1786 | bf->bf_state.seqno = seqno; |
1799 | } | 1787 | } |
1800 | 1788 | ||
1801 | bf->bf_flags = setup_tx_flags(skb); | ||
1802 | bf->bf_mpdu = skb; | 1789 | bf->bf_mpdu = skb; |
1803 | 1790 | ||
1804 | bf->bf_buf_addr = dma_map_single(sc->dev, skb->data, | 1791 | bf->bf_buf_addr = dma_map_single(sc->dev, skb->data, |
@@ -1812,20 +1799,6 @@ static struct ath_buf *ath_tx_setup_buffer(struct ath_softc *sc, | |||
1812 | goto error; | 1799 | goto error; |
1813 | } | 1800 | } |
1814 | 1801 | ||
1815 | frm_type = get_hw_packet_type(skb); | ||
1816 | |||
1817 | ds = bf->bf_desc; | ||
1818 | ath9k_hw_set11n_txdesc(ah, ds, fi->framelen, frm_type, MAX_RATE_POWER, | ||
1819 | fi->keyix, fi->keytype, bf->bf_flags); | ||
1820 | |||
1821 | ath9k_hw_filltxdesc(ah, ds, | ||
1822 | skb->len, /* segment length */ | ||
1823 | true, /* first segment */ | ||
1824 | true, /* last segment */ | ||
1825 | ds, /* first descriptor */ | ||
1826 | bf->bf_buf_addr, | ||
1827 | txq->axq_qnum); | ||
1828 | |||
1829 | fi->bf = bf; | 1802 | fi->bf = bf; |
1830 | 1803 | ||
1831 | return bf; | 1804 | return bf; |
@@ -1868,10 +1841,6 @@ static void ath_tx_start_dma(struct ath_softc *sc, struct sk_buff *skb, | |||
1868 | 1841 | ||
1869 | bf->bf_state.bfs_paprd = txctl->paprd; | 1842 | bf->bf_state.bfs_paprd = txctl->paprd; |
1870 | 1843 | ||
1871 | if (bf->bf_state.bfs_paprd) | ||
1872 | ar9003_hw_set_paprd_txdesc(sc->sc_ah, bf->bf_desc, | ||
1873 | bf->bf_state.bfs_paprd); | ||
1874 | |||
1875 | if (txctl->paprd) | 1844 | if (txctl->paprd) |
1876 | bf->bf_state.bfs_paprd_timestamp = jiffies; | 1845 | bf->bf_state.bfs_paprd_timestamp = jiffies; |
1877 | 1846 | ||
@@ -2080,7 +2049,7 @@ static void ath_tx_rc_status(struct ath_softc *sc, struct ath_buf *bf, | |||
2080 | } | 2049 | } |
2081 | 2050 | ||
2082 | if ((ts->ts_status & ATH9K_TXERR_FILT) == 0 && | 2051 | if ((ts->ts_status & ATH9K_TXERR_FILT) == 0 && |
2083 | (bf->bf_flags & ATH9K_TXDESC_NOACK) == 0 && update_rc) { | 2052 | (tx_info->flags & IEEE80211_TX_CTL_NO_ACK) == 0 && update_rc) { |
2084 | /* | 2053 | /* |
2085 | * If an underrun error is seen assume it as an excessive | 2054 | * If an underrun error is seen assume it as an excessive |
2086 | * retry only if max frame trigger level has been reached | 2055 | * retry only if max frame trigger level has been reached |