aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/wireless/ath/ath9k/rc.c
diff options
context:
space:
mode:
authorAndrea Bastoni <bastoni@cs.unc.edu>2010-05-30 19:16:45 -0400
committerAndrea Bastoni <bastoni@cs.unc.edu>2010-05-30 19:16:45 -0400
commitada47b5fe13d89735805b566185f4885f5a3f750 (patch)
tree644b88f8a71896307d71438e9b3af49126ffb22b /drivers/net/wireless/ath/ath9k/rc.c
parent43e98717ad40a4ae64545b5ba047c7b86aa44f4f (diff)
parent3280f21d43ee541f97f8cda5792150d2dbec20d5 (diff)
Merge branch 'wip-2.6.34' into old-private-masterarchived-private-master
Diffstat (limited to 'drivers/net/wireless/ath/ath9k/rc.c')
-rw-r--r--drivers/net/wireless/ath/ath9k/rc.c572
1 files changed, 236 insertions, 336 deletions
diff --git a/drivers/net/wireless/ath/ath9k/rc.c b/drivers/net/wireless/ath/ath9k/rc.c
index 1895d63aad0a..244e1c629177 100644
--- a/drivers/net/wireless/ath/ath9k/rc.c
+++ b/drivers/net/wireless/ath/ath9k/rc.c
@@ -15,137 +15,98 @@
15 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 15 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
16 */ 16 */
17 17
18#include <linux/slab.h>
19
18#include "ath9k.h" 20#include "ath9k.h"
19 21
20static const struct ath_rate_table ar5416_11na_ratetable = { 22static const struct ath_rate_table ar5416_11na_ratetable = {
21 42, 23 42,
24 8, /* MCS start */
22 { 25 {
23 { VALID, VALID, WLAN_RC_PHY_OFDM, 6000, /* 6 Mb */ 26 { VALID, VALID, WLAN_RC_PHY_OFDM, 6000, /* 6 Mb */
24 5400, 0x0b, 0x00, 12, 27 5400, 0, 12, 0, 0, 0, 0, 0 },
25 0, 0, 0, 0, 0, 0 },
26 { VALID, VALID, WLAN_RC_PHY_OFDM, 9000, /* 9 Mb */ 28 { VALID, VALID, WLAN_RC_PHY_OFDM, 9000, /* 9 Mb */
27 7800, 0x0f, 0x00, 18, 29 7800, 1, 18, 0, 1, 1, 1, 1 },
28 0, 1, 1, 1, 1, 0 },
29 { VALID, VALID, WLAN_RC_PHY_OFDM, 12000, /* 12 Mb */ 30 { VALID, VALID, WLAN_RC_PHY_OFDM, 12000, /* 12 Mb */
30 10000, 0x0a, 0x00, 24, 31 10000, 2, 24, 2, 2, 2, 2, 2 },
31 2, 2, 2, 2, 2, 0 },
32 { VALID, VALID, WLAN_RC_PHY_OFDM, 18000, /* 18 Mb */ 32 { VALID, VALID, WLAN_RC_PHY_OFDM, 18000, /* 18 Mb */
33 13900, 0x0e, 0x00, 36, 33 13900, 3, 36, 2, 3, 3, 3, 3 },
34 2, 3, 3, 3, 3, 0 },
35 { VALID, VALID, WLAN_RC_PHY_OFDM, 24000, /* 24 Mb */ 34 { VALID, VALID, WLAN_RC_PHY_OFDM, 24000, /* 24 Mb */
36 17300, 0x09, 0x00, 48, 35 17300, 4, 48, 4, 4, 4, 4, 4 },
37 4, 4, 4, 4, 4, 0 },
38 { VALID, VALID, WLAN_RC_PHY_OFDM, 36000, /* 36 Mb */ 36 { VALID, VALID, WLAN_RC_PHY_OFDM, 36000, /* 36 Mb */
39 23000, 0x0d, 0x00, 72, 37 23000, 5, 72, 4, 5, 5, 5, 5 },
40 4, 5, 5, 5, 5, 0 },
41 { VALID, VALID, WLAN_RC_PHY_OFDM, 48000, /* 48 Mb */ 38 { VALID, VALID, WLAN_RC_PHY_OFDM, 48000, /* 48 Mb */
42 27400, 0x08, 0x00, 96, 39 27400, 6, 96, 4, 6, 6, 6, 6 },
43 4, 6, 6, 6, 6, 0 },
44 { VALID, VALID, WLAN_RC_PHY_OFDM, 54000, /* 54 Mb */ 40 { VALID, VALID, WLAN_RC_PHY_OFDM, 54000, /* 54 Mb */
45 29300, 0x0c, 0x00, 108, 41 29300, 7, 108, 4, 7, 7, 7, 7 },
46 4, 7, 7, 7, 7, 0 },
47 { VALID_2040, VALID_2040, WLAN_RC_PHY_HT_20_SS, 6500, /* 6.5 Mb */ 42 { VALID_2040, VALID_2040, WLAN_RC_PHY_HT_20_SS, 6500, /* 6.5 Mb */
48 6400, 0x80, 0x00, 0, 43 6400, 0, 0, 0, 8, 24, 8, 24 },
49 0, 8, 24, 8, 24, 3216 },
50 { VALID_20, VALID_20, WLAN_RC_PHY_HT_20_SS, 13000, /* 13 Mb */ 44 { VALID_20, VALID_20, WLAN_RC_PHY_HT_20_SS, 13000, /* 13 Mb */
51 12700, 0x81, 0x00, 1, 45 12700, 1, 1, 2, 9, 25, 9, 25 },
52 2, 9, 25, 9, 25, 6434 },
53 { VALID_20, VALID_20, WLAN_RC_PHY_HT_20_SS, 19500, /* 19.5 Mb */ 46 { VALID_20, VALID_20, WLAN_RC_PHY_HT_20_SS, 19500, /* 19.5 Mb */
54 18800, 0x82, 0x00, 2, 47 18800, 2, 2, 2, 10, 26, 10, 26 },
55 2, 10, 26, 10, 26, 9650 },
56 { VALID_20, VALID_20, WLAN_RC_PHY_HT_20_SS, 26000, /* 26 Mb */ 48 { VALID_20, VALID_20, WLAN_RC_PHY_HT_20_SS, 26000, /* 26 Mb */
57 25000, 0x83, 0x00, 3, 49 25000, 3, 3, 4, 11, 27, 11, 27 },
58 4, 11, 27, 11, 27, 12868 },
59 { VALID_20, VALID_20, WLAN_RC_PHY_HT_20_SS, 39000, /* 39 Mb */ 50 { VALID_20, VALID_20, WLAN_RC_PHY_HT_20_SS, 39000, /* 39 Mb */
60 36700, 0x84, 0x00, 4, 51 36700, 4, 4, 4, 12, 28, 12, 28 },
61 4, 12, 28, 12, 28, 19304 },
62 { INVALID, VALID_20, WLAN_RC_PHY_HT_20_SS, 52000, /* 52 Mb */ 52 { INVALID, VALID_20, WLAN_RC_PHY_HT_20_SS, 52000, /* 52 Mb */
63 48100, 0x85, 0x00, 5, 53 48100, 5, 5, 4, 13, 29, 13, 29 },
64 4, 13, 29, 13, 29, 25740 },
65 { INVALID, VALID_20, WLAN_RC_PHY_HT_20_SS, 58500, /* 58.5 Mb */ 54 { INVALID, VALID_20, WLAN_RC_PHY_HT_20_SS, 58500, /* 58.5 Mb */
66 53500, 0x86, 0x00, 6, 55 53500, 6, 6, 4, 14, 30, 14, 30 },
67 4, 14, 30, 14, 30, 28956 },
68 { INVALID, VALID_20, WLAN_RC_PHY_HT_20_SS, 65000, /* 65 Mb */ 56 { INVALID, VALID_20, WLAN_RC_PHY_HT_20_SS, 65000, /* 65 Mb */
69 59000, 0x87, 0x00, 7, 57 59000, 7, 7, 4, 15, 31, 15, 32 },
70 4, 15, 31, 15, 32, 32180 },
71 { INVALID, INVALID, WLAN_RC_PHY_HT_20_DS, 13000, /* 13 Mb */ 58 { INVALID, INVALID, WLAN_RC_PHY_HT_20_DS, 13000, /* 13 Mb */
72 12700, 0x88, 0x00, 59 12700, 8, 8, 3, 16, 33, 16, 33 },
73 8, 3, 16, 33, 16, 33, 6430 },
74 { INVALID, INVALID, WLAN_RC_PHY_HT_20_DS, 26000, /* 26 Mb */ 60 { INVALID, INVALID, WLAN_RC_PHY_HT_20_DS, 26000, /* 26 Mb */
75 24800, 0x89, 0x00, 9, 61 24800, 9, 9, 2, 17, 34, 17, 34 },
76 2, 17, 34, 17, 34, 12860 },
77 { INVALID, INVALID, WLAN_RC_PHY_HT_20_DS, 39000, /* 39 Mb */ 62 { INVALID, INVALID, WLAN_RC_PHY_HT_20_DS, 39000, /* 39 Mb */
78 36600, 0x8a, 0x00, 10, 63 36600, 10, 10, 2, 18, 35, 18, 35 },
79 2, 18, 35, 18, 35, 19300 },
80 { VALID_20, INVALID, WLAN_RC_PHY_HT_20_DS, 52000, /* 52 Mb */ 64 { VALID_20, INVALID, WLAN_RC_PHY_HT_20_DS, 52000, /* 52 Mb */
81 48100, 0x8b, 0x00, 11, 65 48100, 11, 11, 4, 19, 36, 19, 36 },
82 4, 19, 36, 19, 36, 25736 },
83 { VALID_20, INVALID, WLAN_RC_PHY_HT_20_DS, 78000, /* 78 Mb */ 66 { VALID_20, INVALID, WLAN_RC_PHY_HT_20_DS, 78000, /* 78 Mb */
84 69500, 0x8c, 0x00, 12, 67 69500, 12, 12, 4, 20, 37, 20, 37 },
85 4, 20, 37, 20, 37, 38600 },
86 { VALID_20, INVALID, WLAN_RC_PHY_HT_20_DS, 104000, /* 104 Mb */ 68 { VALID_20, INVALID, WLAN_RC_PHY_HT_20_DS, 104000, /* 104 Mb */
87 89500, 0x8d, 0x00, 13, 69 89500, 13, 13, 4, 21, 38, 21, 38 },
88 4, 21, 38, 21, 38, 51472 },
89 { VALID_20, INVALID, WLAN_RC_PHY_HT_20_DS, 117000, /* 117 Mb */ 70 { VALID_20, INVALID, WLAN_RC_PHY_HT_20_DS, 117000, /* 117 Mb */
90 98900, 0x8e, 0x00, 14, 71 98900, 14, 14, 4, 22, 39, 22, 39 },
91 4, 22, 39, 22, 39, 57890 },
92 { VALID_20, INVALID, WLAN_RC_PHY_HT_20_DS, 130000, /* 130 Mb */ 72 { VALID_20, INVALID, WLAN_RC_PHY_HT_20_DS, 130000, /* 130 Mb */
93 108300, 0x8f, 0x00, 15, 73 108300, 15, 15, 4, 23, 40, 23, 41 },
94 4, 23, 40, 23, 41, 64320 },
95 { VALID_40, VALID_40, WLAN_RC_PHY_HT_40_SS, 13500, /* 13.5 Mb */ 74 { VALID_40, VALID_40, WLAN_RC_PHY_HT_40_SS, 13500, /* 13.5 Mb */
96 13200, 0x80, 0x00, 0, 75 13200, 0, 0, 0, 8, 24, 24, 24 },
97 0, 8, 24, 24, 24, 6684 },
98 { VALID_40, VALID_40, WLAN_RC_PHY_HT_40_SS, 27500, /* 27.0 Mb */ 76 { VALID_40, VALID_40, WLAN_RC_PHY_HT_40_SS, 27500, /* 27.0 Mb */
99 25900, 0x81, 0x00, 1, 77 25900, 1, 1, 2, 9, 25, 25, 25 },
100 2, 9, 25, 25, 25, 13368 },
101 { VALID_40, VALID_40, WLAN_RC_PHY_HT_40_SS, 40500, /* 40.5 Mb */ 78 { VALID_40, VALID_40, WLAN_RC_PHY_HT_40_SS, 40500, /* 40.5 Mb */
102 38600, 0x82, 0x00, 2, 79 38600, 2, 2, 2, 10, 26, 26, 26 },
103 2, 10, 26, 26, 26, 20052 },
104 { VALID_40, VALID_40, WLAN_RC_PHY_HT_40_SS, 54000, /* 54 Mb */ 80 { VALID_40, VALID_40, WLAN_RC_PHY_HT_40_SS, 54000, /* 54 Mb */
105 49800, 0x83, 0x00, 3, 81 49800, 3, 3, 4, 11, 27, 27, 27 },
106 4, 11, 27, 27, 27, 26738 },
107 { VALID_40, VALID_40, WLAN_RC_PHY_HT_40_SS, 81500, /* 81 Mb */ 82 { VALID_40, VALID_40, WLAN_RC_PHY_HT_40_SS, 81500, /* 81 Mb */
108 72200, 0x84, 0x00, 4, 83 72200, 4, 4, 4, 12, 28, 28, 28 },
109 4, 12, 28, 28, 28, 40104 },
110 { INVALID, VALID_40, WLAN_RC_PHY_HT_40_SS, 108000, /* 108 Mb */ 84 { INVALID, VALID_40, WLAN_RC_PHY_HT_40_SS, 108000, /* 108 Mb */
111 92900, 0x85, 0x00, 5, 85 92900, 5, 5, 4, 13, 29, 29, 29 },
112 4, 13, 29, 29, 29, 53476 },
113 { INVALID, VALID_40, WLAN_RC_PHY_HT_40_SS, 121500, /* 121.5 Mb */ 86 { INVALID, VALID_40, WLAN_RC_PHY_HT_40_SS, 121500, /* 121.5 Mb */
114 102700, 0x86, 0x00, 6, 87 102700, 6, 6, 4, 14, 30, 30, 30 },
115 4, 14, 30, 30, 30, 60156 },
116 { INVALID, VALID_40, WLAN_RC_PHY_HT_40_SS, 135000, /* 135 Mb */ 88 { INVALID, VALID_40, WLAN_RC_PHY_HT_40_SS, 135000, /* 135 Mb */
117 112000, 0x87, 0x00, 7, 89 112000, 7, 7, 4, 15, 31, 32, 32 },
118 4, 15, 31, 32, 32, 66840 },
119 { INVALID, VALID_40, WLAN_RC_PHY_HT_40_SS_HGI, 150000, /* 150 Mb */ 90 { INVALID, VALID_40, WLAN_RC_PHY_HT_40_SS_HGI, 150000, /* 150 Mb */
120 122000, 0x87, 0x00, 7, 91 122000, 7, 7, 4, 15, 31, 32, 32 },
121 4, 15, 31, 32, 32, 74200 },
122 { INVALID, INVALID, WLAN_RC_PHY_HT_40_DS, 27000, /* 27 Mb */ 92 { INVALID, INVALID, WLAN_RC_PHY_HT_40_DS, 27000, /* 27 Mb */
123 25800, 0x88, 0x00, 8, 93 25800, 8, 8, 0, 16, 33, 33, 33 },
124 0, 16, 33, 33, 33, 13360 },
125 { INVALID, INVALID, WLAN_RC_PHY_HT_40_DS, 54000, /* 54 Mb */ 94 { INVALID, INVALID, WLAN_RC_PHY_HT_40_DS, 54000, /* 54 Mb */
126 49800, 0x89, 0x00, 9, 95 49800, 9, 9, 2, 17, 34, 34, 34 },
127 2, 17, 34, 34, 34, 26720 },
128 { INVALID, INVALID, WLAN_RC_PHY_HT_40_DS, 81000, /* 81 Mb */ 96 { INVALID, INVALID, WLAN_RC_PHY_HT_40_DS, 81000, /* 81 Mb */
129 71900, 0x8a, 0x00, 10, 97 71900, 10, 10, 2, 18, 35, 35, 35 },
130 2, 18, 35, 35, 35, 40080 },
131 { VALID_40, INVALID, WLAN_RC_PHY_HT_40_DS, 108000, /* 108 Mb */ 98 { VALID_40, INVALID, WLAN_RC_PHY_HT_40_DS, 108000, /* 108 Mb */
132 92500, 0x8b, 0x00, 11, 99 92500, 11, 11, 4, 19, 36, 36, 36 },
133 4, 19, 36, 36, 36, 53440 },
134 { VALID_40, INVALID, WLAN_RC_PHY_HT_40_DS, 162000, /* 162 Mb */ 100 { VALID_40, INVALID, WLAN_RC_PHY_HT_40_DS, 162000, /* 162 Mb */
135 130300, 0x8c, 0x00, 12, 101 130300, 12, 12, 4, 20, 37, 37, 37 },
136 4, 20, 37, 37, 37, 80160 },
137 { VALID_40, INVALID, WLAN_RC_PHY_HT_40_DS, 216000, /* 216 Mb */ 102 { VALID_40, INVALID, WLAN_RC_PHY_HT_40_DS, 216000, /* 216 Mb */
138 162800, 0x8d, 0x00, 13, 103 162800, 13, 13, 4, 21, 38, 38, 38 },
139 4, 21, 38, 38, 38, 106880 },
140 { VALID_40, INVALID, WLAN_RC_PHY_HT_40_DS, 243000, /* 243 Mb */ 104 { VALID_40, INVALID, WLAN_RC_PHY_HT_40_DS, 243000, /* 243 Mb */
141 178200, 0x8e, 0x00, 14, 105 178200, 14, 14, 4, 22, 39, 39, 39 },
142 4, 22, 39, 39, 39, 120240 },
143 { VALID_40, INVALID, WLAN_RC_PHY_HT_40_DS, 270000, /* 270 Mb */ 106 { VALID_40, INVALID, WLAN_RC_PHY_HT_40_DS, 270000, /* 270 Mb */
144 192100, 0x8f, 0x00, 15, 107 192100, 15, 15, 4, 23, 40, 41, 41 },
145 4, 23, 40, 41, 41, 133600 },
146 { VALID_40, INVALID, WLAN_RC_PHY_HT_40_DS_HGI, 300000, /* 300 Mb */ 108 { VALID_40, INVALID, WLAN_RC_PHY_HT_40_DS_HGI, 300000, /* 300 Mb */
147 207000, 0x8f, 0x00, 15, 109 207000, 15, 15, 4, 23, 40, 41, 41 },
148 4, 23, 40, 41, 41, 148400 },
149 }, 110 },
150 50, /* probe interval */ 111 50, /* probe interval */
151 WLAN_RC_HT_FLAG, /* Phy rates allowed initially */ 112 WLAN_RC_HT_FLAG, /* Phy rates allowed initially */
@@ -156,177 +117,125 @@ static const struct ath_rate_table ar5416_11na_ratetable = {
156 117
157static const struct ath_rate_table ar5416_11ng_ratetable = { 118static const struct ath_rate_table ar5416_11ng_ratetable = {
158 46, 119 46,
120 12, /* MCS start */
159 { 121 {
160 { VALID_ALL, VALID_ALL, WLAN_RC_PHY_CCK, 1000, /* 1 Mb */ 122 { VALID_ALL, VALID_ALL, WLAN_RC_PHY_CCK, 1000, /* 1 Mb */
161 900, 0x1b, 0x00, 2, 123 900, 0, 2, 0, 0, 0, 0, 0 },
162 0, 0, 0, 0, 0, 0 },
163 { VALID_ALL, VALID_ALL, WLAN_RC_PHY_CCK, 2000, /* 2 Mb */ 124 { VALID_ALL, VALID_ALL, WLAN_RC_PHY_CCK, 2000, /* 2 Mb */
164 1900, 0x1a, 0x04, 4, 125 1900, 1, 4, 1, 1, 1, 1, 1 },
165 1, 1, 1, 1, 1, 0 },
166 { VALID_ALL, VALID_ALL, WLAN_RC_PHY_CCK, 5500, /* 5.5 Mb */ 126 { VALID_ALL, VALID_ALL, WLAN_RC_PHY_CCK, 5500, /* 5.5 Mb */
167 4900, 0x19, 0x04, 11, 127 4900, 2, 11, 2, 2, 2, 2, 2 },
168 2, 2, 2, 2, 2, 0 },
169 { VALID_ALL, VALID_ALL, WLAN_RC_PHY_CCK, 11000, /* 11 Mb */ 128 { VALID_ALL, VALID_ALL, WLAN_RC_PHY_CCK, 11000, /* 11 Mb */
170 8100, 0x18, 0x04, 22, 129 8100, 3, 22, 3, 3, 3, 3, 3 },
171 3, 3, 3, 3, 3, 0 },
172 { INVALID, INVALID, WLAN_RC_PHY_OFDM, 6000, /* 6 Mb */ 130 { INVALID, INVALID, WLAN_RC_PHY_OFDM, 6000, /* 6 Mb */
173 5400, 0x0b, 0x00, 12, 131 5400, 4, 12, 4, 4, 4, 4, 4 },
174 4, 4, 4, 4, 4, 0 },
175 { INVALID, INVALID, WLAN_RC_PHY_OFDM, 9000, /* 9 Mb */ 132 { INVALID, INVALID, WLAN_RC_PHY_OFDM, 9000, /* 9 Mb */
176 7800, 0x0f, 0x00, 18, 133 7800, 5, 18, 4, 5, 5, 5, 5 },
177 4, 5, 5, 5, 5, 0 },
178 { VALID, VALID, WLAN_RC_PHY_OFDM, 12000, /* 12 Mb */ 134 { VALID, VALID, WLAN_RC_PHY_OFDM, 12000, /* 12 Mb */
179 10100, 0x0a, 0x00, 24, 135 10100, 6, 24, 6, 6, 6, 6, 6 },
180 6, 6, 6, 6, 6, 0 },
181 { VALID, VALID, WLAN_RC_PHY_OFDM, 18000, /* 18 Mb */ 136 { VALID, VALID, WLAN_RC_PHY_OFDM, 18000, /* 18 Mb */
182 14100, 0x0e, 0x00, 36, 137 14100, 7, 36, 6, 7, 7, 7, 7 },
183 6, 7, 7, 7, 7, 0 },
184 { VALID, VALID, WLAN_RC_PHY_OFDM, 24000, /* 24 Mb */ 138 { VALID, VALID, WLAN_RC_PHY_OFDM, 24000, /* 24 Mb */
185 17700, 0x09, 0x00, 48, 139 17700, 8, 48, 8, 8, 8, 8, 8 },
186 8, 8, 8, 8, 8, 0 },
187 { VALID, VALID, WLAN_RC_PHY_OFDM, 36000, /* 36 Mb */ 140 { VALID, VALID, WLAN_RC_PHY_OFDM, 36000, /* 36 Mb */
188 23700, 0x0d, 0x00, 72, 141 23700, 9, 72, 8, 9, 9, 9, 9 },
189 8, 9, 9, 9, 9, 0 },
190 { VALID, VALID, WLAN_RC_PHY_OFDM, 48000, /* 48 Mb */ 142 { VALID, VALID, WLAN_RC_PHY_OFDM, 48000, /* 48 Mb */
191 27400, 0x08, 0x00, 96, 143 27400, 10, 96, 8, 10, 10, 10, 10 },
192 8, 10, 10, 10, 10, 0 },
193 { VALID, VALID, WLAN_RC_PHY_OFDM, 54000, /* 54 Mb */ 144 { VALID, VALID, WLAN_RC_PHY_OFDM, 54000, /* 54 Mb */
194 30900, 0x0c, 0x00, 108, 145 30900, 11, 108, 8, 11, 11, 11, 11 },
195 8, 11, 11, 11, 11, 0 },
196 { INVALID, INVALID, WLAN_RC_PHY_HT_20_SS, 6500, /* 6.5 Mb */ 146 { INVALID, INVALID, WLAN_RC_PHY_HT_20_SS, 6500, /* 6.5 Mb */
197 6400, 0x80, 0x00, 0, 147 6400, 0, 0, 4, 12, 28, 12, 28 },
198 4, 12, 28, 12, 28, 3216 },
199 { VALID_20, VALID_20, WLAN_RC_PHY_HT_20_SS, 13000, /* 13 Mb */ 148 { VALID_20, VALID_20, WLAN_RC_PHY_HT_20_SS, 13000, /* 13 Mb */
200 12700, 0x81, 0x00, 1, 149 12700, 1, 1, 6, 13, 29, 13, 29 },
201 6, 13, 29, 13, 29, 6434 },
202 { VALID_20, VALID_20, WLAN_RC_PHY_HT_20_SS, 19500, /* 19.5 Mb */ 150 { VALID_20, VALID_20, WLAN_RC_PHY_HT_20_SS, 19500, /* 19.5 Mb */
203 18800, 0x82, 0x00, 2, 151 18800, 2, 2, 6, 14, 30, 14, 30 },
204 6, 14, 30, 14, 30, 9650 },
205 { VALID_20, VALID_20, WLAN_RC_PHY_HT_20_SS, 26000, /* 26 Mb */ 152 { VALID_20, VALID_20, WLAN_RC_PHY_HT_20_SS, 26000, /* 26 Mb */
206 25000, 0x83, 0x00, 3, 153 25000, 3, 3, 8, 15, 31, 15, 31 },
207 8, 15, 31, 15, 31, 12868 },
208 { VALID_20, VALID_20, WLAN_RC_PHY_HT_20_SS, 39000, /* 39 Mb */ 154 { VALID_20, VALID_20, WLAN_RC_PHY_HT_20_SS, 39000, /* 39 Mb */
209 36700, 0x84, 0x00, 4, 155 36700, 4, 4, 8, 16, 32, 16, 32 },
210 8, 16, 32, 16, 32, 19304 },
211 { INVALID, VALID_20, WLAN_RC_PHY_HT_20_SS, 52000, /* 52 Mb */ 156 { INVALID, VALID_20, WLAN_RC_PHY_HT_20_SS, 52000, /* 52 Mb */
212 48100, 0x85, 0x00, 5, 157 48100, 5, 5, 8, 17, 33, 17, 33 },
213 8, 17, 33, 17, 33, 25740 },
214 { INVALID, VALID_20, WLAN_RC_PHY_HT_20_SS, 58500, /* 58.5 Mb */ 158 { INVALID, VALID_20, WLAN_RC_PHY_HT_20_SS, 58500, /* 58.5 Mb */
215 53500, 0x86, 0x00, 6, 159 53500, 6, 6, 8, 18, 34, 18, 34 },
216 8, 18, 34, 18, 34, 28956 },
217 { INVALID, VALID_20, WLAN_RC_PHY_HT_20_SS, 65000, /* 65 Mb */ 160 { INVALID, VALID_20, WLAN_RC_PHY_HT_20_SS, 65000, /* 65 Mb */
218 59000, 0x87, 0x00, 7, 161 59000, 7, 7, 8, 19, 35, 19, 36 },
219 8, 19, 35, 19, 36, 32180 },
220 { INVALID, INVALID, WLAN_RC_PHY_HT_20_DS, 13000, /* 13 Mb */ 162 { INVALID, INVALID, WLAN_RC_PHY_HT_20_DS, 13000, /* 13 Mb */
221 12700, 0x88, 0x00, 8, 163 12700, 8, 8, 4, 20, 37, 20, 37 },
222 4, 20, 37, 20, 37, 6430 },
223 { INVALID, INVALID, WLAN_RC_PHY_HT_20_DS, 26000, /* 26 Mb */ 164 { INVALID, INVALID, WLAN_RC_PHY_HT_20_DS, 26000, /* 26 Mb */
224 24800, 0x89, 0x00, 9, 165 24800, 9, 9, 6, 21, 38, 21, 38 },
225 6, 21, 38, 21, 38, 12860 },
226 { INVALID, INVALID, WLAN_RC_PHY_HT_20_DS, 39000, /* 39 Mb */ 166 { INVALID, INVALID, WLAN_RC_PHY_HT_20_DS, 39000, /* 39 Mb */
227 36600, 0x8a, 0x00, 10, 167 36600, 10, 10, 6, 22, 39, 22, 39 },
228 6, 22, 39, 22, 39, 19300 },
229 { VALID_20, INVALID, WLAN_RC_PHY_HT_20_DS, 52000, /* 52 Mb */ 168 { VALID_20, INVALID, WLAN_RC_PHY_HT_20_DS, 52000, /* 52 Mb */
230 48100, 0x8b, 0x00, 11, 169 48100, 11, 11, 8, 23, 40, 23, 40 },
231 8, 23, 40, 23, 40, 25736 },
232 { VALID_20, INVALID, WLAN_RC_PHY_HT_20_DS, 78000, /* 78 Mb */ 170 { VALID_20, INVALID, WLAN_RC_PHY_HT_20_DS, 78000, /* 78 Mb */
233 69500, 0x8c, 0x00, 12, 171 69500, 12, 12, 8, 24, 41, 24, 41 },
234 8, 24, 41, 24, 41, 38600 },
235 { VALID_20, INVALID, WLAN_RC_PHY_HT_20_DS, 104000, /* 104 Mb */ 172 { VALID_20, INVALID, WLAN_RC_PHY_HT_20_DS, 104000, /* 104 Mb */
236 89500, 0x8d, 0x00, 13, 173 89500, 13, 13, 8, 25, 42, 25, 42 },
237 8, 25, 42, 25, 42, 51472 },
238 { VALID_20, INVALID, WLAN_RC_PHY_HT_20_DS, 117000, /* 117 Mb */ 174 { VALID_20, INVALID, WLAN_RC_PHY_HT_20_DS, 117000, /* 117 Mb */
239 98900, 0x8e, 0x00, 14, 175 98900, 14, 14, 8, 26, 43, 26, 44 },
240 8, 26, 43, 26, 44, 57890 },
241 { VALID_20, INVALID, WLAN_RC_PHY_HT_20_DS, 130000, /* 130 Mb */ 176 { VALID_20, INVALID, WLAN_RC_PHY_HT_20_DS, 130000, /* 130 Mb */
242 108300, 0x8f, 0x00, 15, 177 108300, 15, 15, 8, 27, 44, 27, 45 },
243 8, 27, 44, 27, 45, 64320 },
244 { VALID_40, VALID_40, WLAN_RC_PHY_HT_40_SS, 13500, /* 13.5 Mb */ 178 { VALID_40, VALID_40, WLAN_RC_PHY_HT_40_SS, 13500, /* 13.5 Mb */
245 13200, 0x80, 0x00, 0, 179 13200, 0, 0, 8, 12, 28, 28, 28 },
246 8, 12, 28, 28, 28, 6684 },
247 { VALID_40, VALID_40, WLAN_RC_PHY_HT_40_SS, 27500, /* 27.0 Mb */ 180 { VALID_40, VALID_40, WLAN_RC_PHY_HT_40_SS, 27500, /* 27.0 Mb */
248 25900, 0x81, 0x00, 1, 181 25900, 1, 1, 8, 13, 29, 29, 29 },
249 8, 13, 29, 29, 29, 13368 },
250 { VALID_40, VALID_40, WLAN_RC_PHY_HT_40_SS, 40500, /* 40.5 Mb */ 182 { VALID_40, VALID_40, WLAN_RC_PHY_HT_40_SS, 40500, /* 40.5 Mb */
251 38600, 0x82, 0x00, 2, 183 38600, 2, 2, 8, 14, 30, 30, 30 },
252 8, 14, 30, 30, 30, 20052 },
253 { VALID_40, VALID_40, WLAN_RC_PHY_HT_40_SS, 54000, /* 54 Mb */ 184 { VALID_40, VALID_40, WLAN_RC_PHY_HT_40_SS, 54000, /* 54 Mb */
254 49800, 0x83, 0x00, 3, 185 49800, 3, 3, 8, 15, 31, 31, 31 },
255 8, 15, 31, 31, 31, 26738 },
256 { VALID_40, VALID_40, WLAN_RC_PHY_HT_40_SS, 81500, /* 81 Mb */ 186 { VALID_40, VALID_40, WLAN_RC_PHY_HT_40_SS, 81500, /* 81 Mb */
257 72200, 0x84, 0x00, 4, 187 72200, 4, 4, 8, 16, 32, 32, 32 },
258 8, 16, 32, 32, 32, 40104 },
259 { INVALID, VALID_40, WLAN_RC_PHY_HT_40_SS, 108000, /* 108 Mb */ 188 { INVALID, VALID_40, WLAN_RC_PHY_HT_40_SS, 108000, /* 108 Mb */
260 92900, 0x85, 0x00, 5, 189 92900, 5, 5, 8, 17, 33, 33, 33 },
261 8, 17, 33, 33, 33, 53476 },
262 { INVALID, VALID_40, WLAN_RC_PHY_HT_40_SS, 121500, /* 121.5 Mb */ 190 { INVALID, VALID_40, WLAN_RC_PHY_HT_40_SS, 121500, /* 121.5 Mb */
263 102700, 0x86, 0x00, 6, 191 102700, 6, 6, 8, 18, 34, 34, 34 },
264 8, 18, 34, 34, 34, 60156 },
265 { INVALID, VALID_40, WLAN_RC_PHY_HT_40_SS, 135000, /* 135 Mb */ 192 { INVALID, VALID_40, WLAN_RC_PHY_HT_40_SS, 135000, /* 135 Mb */
266 112000, 0x87, 0x00, 7, 193 112000, 7, 7, 8, 19, 35, 36, 36 },
267 8, 19, 35, 36, 36, 66840 },
268 { INVALID, VALID_40, WLAN_RC_PHY_HT_40_SS_HGI, 150000, /* 150 Mb */ 194 { INVALID, VALID_40, WLAN_RC_PHY_HT_40_SS_HGI, 150000, /* 150 Mb */
269 122000, 0x87, 0x00, 7, 195 122000, 7, 7, 8, 19, 35, 36, 36 },
270 8, 19, 35, 36, 36, 74200 },
271 { INVALID, INVALID, WLAN_RC_PHY_HT_40_DS, 27000, /* 27 Mb */ 196 { INVALID, INVALID, WLAN_RC_PHY_HT_40_DS, 27000, /* 27 Mb */
272 25800, 0x88, 0x00, 8, 197 25800, 8, 8, 8, 20, 37, 37, 37 },
273 8, 20, 37, 37, 37, 13360 },
274 { INVALID, INVALID, WLAN_RC_PHY_HT_40_DS, 54000, /* 54 Mb */ 198 { INVALID, INVALID, WLAN_RC_PHY_HT_40_DS, 54000, /* 54 Mb */
275 49800, 0x89, 0x00, 9, 199 49800, 9, 9, 8, 21, 38, 38, 38 },
276 8, 21, 38, 38, 38, 26720 },
277 { INVALID, INVALID, WLAN_RC_PHY_HT_40_DS, 81000, /* 81 Mb */ 200 { INVALID, INVALID, WLAN_RC_PHY_HT_40_DS, 81000, /* 81 Mb */
278 71900, 0x8a, 0x00, 10, 201 71900, 10, 10, 8, 22, 39, 39, 39 },
279 8, 22, 39, 39, 39, 40080 },
280 { VALID_40, INVALID, WLAN_RC_PHY_HT_40_DS, 108000, /* 108 Mb */ 202 { VALID_40, INVALID, WLAN_RC_PHY_HT_40_DS, 108000, /* 108 Mb */
281 92500, 0x8b, 0x00, 11, 203 92500, 11, 11, 8, 23, 40, 40, 40 },
282 8, 23, 40, 40, 40, 53440 },
283 { VALID_40, INVALID, WLAN_RC_PHY_HT_40_DS, 162000, /* 162 Mb */ 204 { VALID_40, INVALID, WLAN_RC_PHY_HT_40_DS, 162000, /* 162 Mb */
284 130300, 0x8c, 0x00, 12, 205 130300, 12, 12, 8, 24, 41, 41, 41 },
285 8, 24, 41, 41, 41, 80160 },
286 { VALID_40, INVALID, WLAN_RC_PHY_HT_40_DS, 216000, /* 216 Mb */ 206 { VALID_40, INVALID, WLAN_RC_PHY_HT_40_DS, 216000, /* 216 Mb */
287 162800, 0x8d, 0x00, 13, 207 162800, 13, 13, 8, 25, 42, 42, 42 },
288 8, 25, 42, 42, 42, 106880 },
289 { VALID_40, INVALID, WLAN_RC_PHY_HT_40_DS, 243000, /* 243 Mb */ 208 { VALID_40, INVALID, WLAN_RC_PHY_HT_40_DS, 243000, /* 243 Mb */
290 178200, 0x8e, 0x00, 14, 209 178200, 14, 14, 8, 26, 43, 43, 43 },
291 8, 26, 43, 43, 43, 120240 },
292 { VALID_40, INVALID, WLAN_RC_PHY_HT_40_DS, 270000, /* 270 Mb */ 210 { VALID_40, INVALID, WLAN_RC_PHY_HT_40_DS, 270000, /* 270 Mb */
293 192100, 0x8f, 0x00, 15, 211 192100, 15, 15, 8, 27, 44, 45, 45 },
294 8, 27, 44, 45, 45, 133600 },
295 { VALID_40, INVALID, WLAN_RC_PHY_HT_40_DS_HGI, 300000, /* 300 Mb */ 212 { VALID_40, INVALID, WLAN_RC_PHY_HT_40_DS_HGI, 300000, /* 300 Mb */
296 207000, 0x8f, 0x00, 15, 213 207000, 15, 15, 8, 27, 44, 45, 45 },
297 8, 27, 44, 45, 45, 148400 }, 214 },
298 },
299 50, /* probe interval */ 215 50, /* probe interval */
300 WLAN_RC_HT_FLAG, /* Phy rates allowed initially */ 216 WLAN_RC_HT_FLAG, /* Phy rates allowed initially */
301}; 217};
302 218
303static const struct ath_rate_table ar5416_11a_ratetable = { 219static const struct ath_rate_table ar5416_11a_ratetable = {
304 8, 220 8,
221 0,
305 { 222 {
306 { VALID, VALID, WLAN_RC_PHY_OFDM, 6000, /* 6 Mb */ 223 { VALID, VALID, WLAN_RC_PHY_OFDM, 6000, /* 6 Mb */
307 5400, 0x0b, 0x00, (0x80|12), 224 5400, 0, 12, 0, 0, 0 },
308 0, 0, 0 },
309 { VALID, VALID, WLAN_RC_PHY_OFDM, 9000, /* 9 Mb */ 225 { VALID, VALID, WLAN_RC_PHY_OFDM, 9000, /* 9 Mb */
310 7800, 0x0f, 0x00, 18, 226 7800, 1, 18, 0, 1, 0 },
311 0, 1, 0 },
312 { VALID, VALID, WLAN_RC_PHY_OFDM, 12000, /* 12 Mb */ 227 { VALID, VALID, WLAN_RC_PHY_OFDM, 12000, /* 12 Mb */
313 10000, 0x0a, 0x00, (0x80|24), 228 10000, 2, 24, 2, 2, 0 },
314 2, 2, 0 },
315 { VALID, VALID, WLAN_RC_PHY_OFDM, 18000, /* 18 Mb */ 229 { VALID, VALID, WLAN_RC_PHY_OFDM, 18000, /* 18 Mb */
316 13900, 0x0e, 0x00, 36, 230 13900, 3, 36, 2, 3, 0 },
317 2, 3, 0 },
318 { VALID, VALID, WLAN_RC_PHY_OFDM, 24000, /* 24 Mb */ 231 { VALID, VALID, WLAN_RC_PHY_OFDM, 24000, /* 24 Mb */
319 17300, 0x09, 0x00, (0x80|48), 232 17300, 4, 48, 4, 4, 0 },
320 4, 4, 0 },
321 { VALID, VALID, WLAN_RC_PHY_OFDM, 36000, /* 36 Mb */ 233 { VALID, VALID, WLAN_RC_PHY_OFDM, 36000, /* 36 Mb */
322 23000, 0x0d, 0x00, 72, 234 23000, 5, 72, 4, 5, 0 },
323 4, 5, 0 },
324 { VALID, VALID, WLAN_RC_PHY_OFDM, 48000, /* 48 Mb */ 235 { VALID, VALID, WLAN_RC_PHY_OFDM, 48000, /* 48 Mb */
325 27400, 0x08, 0x00, 96, 236 27400, 6, 96, 4, 6, 0 },
326 4, 6, 0 },
327 { VALID, VALID, WLAN_RC_PHY_OFDM, 54000, /* 54 Mb */ 237 { VALID, VALID, WLAN_RC_PHY_OFDM, 54000, /* 54 Mb */
328 29300, 0x0c, 0x00, 108, 238 29300, 7, 108, 4, 7, 0 },
329 4, 7, 0 },
330 }, 239 },
331 50, /* probe interval */ 240 50, /* probe interval */
332 0, /* Phy rates allowed initially */ 241 0, /* Phy rates allowed initially */
@@ -334,48 +243,51 @@ static const struct ath_rate_table ar5416_11a_ratetable = {
334 243
335static const struct ath_rate_table ar5416_11g_ratetable = { 244static const struct ath_rate_table ar5416_11g_ratetable = {
336 12, 245 12,
246 0,
337 { 247 {
338 { VALID, VALID, WLAN_RC_PHY_CCK, 1000, /* 1 Mb */ 248 { VALID, VALID, WLAN_RC_PHY_CCK, 1000, /* 1 Mb */
339 900, 0x1b, 0x00, 2, 249 900, 0, 2, 0, 0, 0 },
340 0, 0, 0 },
341 { VALID, VALID, WLAN_RC_PHY_CCK, 2000, /* 2 Mb */ 250 { VALID, VALID, WLAN_RC_PHY_CCK, 2000, /* 2 Mb */
342 1900, 0x1a, 0x04, 4, 251 1900, 1, 4, 1, 1, 0 },
343 1, 1, 0 },
344 { VALID, VALID, WLAN_RC_PHY_CCK, 5500, /* 5.5 Mb */ 252 { VALID, VALID, WLAN_RC_PHY_CCK, 5500, /* 5.5 Mb */
345 4900, 0x19, 0x04, 11, 253 4900, 2, 11, 2, 2, 0 },
346 2, 2, 0 },
347 { VALID, VALID, WLAN_RC_PHY_CCK, 11000, /* 11 Mb */ 254 { VALID, VALID, WLAN_RC_PHY_CCK, 11000, /* 11 Mb */
348 8100, 0x18, 0x04, 22, 255 8100, 3, 22, 3, 3, 0 },
349 3, 3, 0 },
350 { INVALID, INVALID, WLAN_RC_PHY_OFDM, 6000, /* 6 Mb */ 256 { INVALID, INVALID, WLAN_RC_PHY_OFDM, 6000, /* 6 Mb */
351 5400, 0x0b, 0x00, 12, 257 5400, 4, 12, 4, 4, 0 },
352 4, 4, 0 },
353 { INVALID, INVALID, WLAN_RC_PHY_OFDM, 9000, /* 9 Mb */ 258 { INVALID, INVALID, WLAN_RC_PHY_OFDM, 9000, /* 9 Mb */
354 7800, 0x0f, 0x00, 18, 259 7800, 5, 18, 4, 5, 0 },
355 4, 5, 0 },
356 { VALID, VALID, WLAN_RC_PHY_OFDM, 12000, /* 12 Mb */ 260 { VALID, VALID, WLAN_RC_PHY_OFDM, 12000, /* 12 Mb */
357 10000, 0x0a, 0x00, 24, 261 10000, 6, 24, 6, 6, 0 },
358 6, 6, 0 },
359 { VALID, VALID, WLAN_RC_PHY_OFDM, 18000, /* 18 Mb */ 262 { VALID, VALID, WLAN_RC_PHY_OFDM, 18000, /* 18 Mb */
360 13900, 0x0e, 0x00, 36, 263 13900, 7, 36, 6, 7, 0 },
361 6, 7, 0 },
362 { VALID, VALID, WLAN_RC_PHY_OFDM, 24000, /* 24 Mb */ 264 { VALID, VALID, WLAN_RC_PHY_OFDM, 24000, /* 24 Mb */
363 17300, 0x09, 0x00, 48, 265 17300, 8, 48, 8, 8, 0 },
364 8, 8, 0 },
365 { VALID, VALID, WLAN_RC_PHY_OFDM, 36000, /* 36 Mb */ 266 { VALID, VALID, WLAN_RC_PHY_OFDM, 36000, /* 36 Mb */
366 23000, 0x0d, 0x00, 72, 267 23000, 9, 72, 8, 9, 0 },
367 8, 9, 0 },
368 { VALID, VALID, WLAN_RC_PHY_OFDM, 48000, /* 48 Mb */ 268 { VALID, VALID, WLAN_RC_PHY_OFDM, 48000, /* 48 Mb */
369 27400, 0x08, 0x00, 96, 269 27400, 10, 96, 8, 10, 0 },
370 8, 10, 0 },
371 { VALID, VALID, WLAN_RC_PHY_OFDM, 54000, /* 54 Mb */ 270 { VALID, VALID, WLAN_RC_PHY_OFDM, 54000, /* 54 Mb */
372 29300, 0x0c, 0x00, 108, 271 29300, 11, 108, 8, 11, 0 },
373 8, 11, 0 },
374 }, 272 },
375 50, /* probe interval */ 273 50, /* probe interval */
376 0, /* Phy rates allowed initially */ 274 0, /* Phy rates allowed initially */
377}; 275};
378 276
277static const struct ath_rate_table *hw_rate_table[ATH9K_MODE_MAX] = {
278 [ATH9K_MODE_11A] = &ar5416_11a_ratetable,
279 [ATH9K_MODE_11G] = &ar5416_11g_ratetable,
280 [ATH9K_MODE_11NA_HT20] = &ar5416_11na_ratetable,
281 [ATH9K_MODE_11NG_HT20] = &ar5416_11ng_ratetable,
282 [ATH9K_MODE_11NA_HT40PLUS] = &ar5416_11na_ratetable,
283 [ATH9K_MODE_11NA_HT40MINUS] = &ar5416_11na_ratetable,
284 [ATH9K_MODE_11NG_HT40PLUS] = &ar5416_11ng_ratetable,
285 [ATH9K_MODE_11NG_HT40MINUS] = &ar5416_11ng_ratetable,
286};
287
288static int ath_rc_get_rateindex(const struct ath_rate_table *rate_table,
289 struct ieee80211_tx_rate *rate);
290
379static inline int8_t median(int8_t a, int8_t b, int8_t c) 291static inline int8_t median(int8_t a, int8_t b, int8_t c)
380{ 292{
381 if (a >= b) { 293 if (a >= b) {
@@ -425,7 +337,7 @@ static void ath_rc_init_valid_txmask(struct ath_rate_priv *ath_rc_priv)
425static inline void ath_rc_set_valid_txmask(struct ath_rate_priv *ath_rc_priv, 337static inline void ath_rc_set_valid_txmask(struct ath_rate_priv *ath_rc_priv,
426 u8 index, int valid_tx_rate) 338 u8 index, int valid_tx_rate)
427{ 339{
428 ASSERT(index <= ath_rc_priv->rate_table_size); 340 BUG_ON(index > ath_rc_priv->rate_table_size);
429 ath_rc_priv->valid_rate_index[index] = valid_tx_rate ? 1 : 0; 341 ath_rc_priv->valid_rate_index[index] = valid_tx_rate ? 1 : 0;
430} 342}
431 343
@@ -534,7 +446,7 @@ static u8 ath_rc_setvalid_rates(struct ath_rate_priv *ath_rc_priv,
534 * capflag matches one of the validity 446 * capflag matches one of the validity
535 * (VALID/VALID_20/VALID_40) flags */ 447 * (VALID/VALID_20/VALID_40) flags */
536 448
537 if (((rate & 0x7F) == (dot11rate & 0x7F)) && 449 if ((rate == dot11rate) &&
538 ((valid & WLAN_RC_CAP_MODE(capflag)) == 450 ((valid & WLAN_RC_CAP_MODE(capflag)) ==
539 WLAN_RC_CAP_MODE(capflag)) && 451 WLAN_RC_CAP_MODE(capflag)) &&
540 !WLAN_RC_PHY_HT(phy)) { 452 !WLAN_RC_PHY_HT(phy)) {
@@ -576,8 +488,7 @@ static u8 ath_rc_setvalid_htrates(struct ath_rate_priv *ath_rc_priv,
576 u8 rate = rateset->rs_rates[i]; 488 u8 rate = rateset->rs_rates[i];
577 u8 dot11rate = rate_table->info[j].dot11rate; 489 u8 dot11rate = rate_table->info[j].dot11rate;
578 490
579 if (((rate & 0x7F) != (dot11rate & 0x7F)) || 491 if ((rate != dot11rate) || !WLAN_RC_PHY_HT(phy) ||
580 !WLAN_RC_PHY_HT(phy) ||
581 !WLAN_RC_PHY_HT_VALID(valid, capflag)) 492 !WLAN_RC_PHY_HT_VALID(valid, capflag))
582 continue; 493 continue;
583 494
@@ -696,18 +607,20 @@ static void ath_rc_rate_set_series(const struct ath_rate_table *rate_table,
696 u8 tries, u8 rix, int rtsctsenable) 607 u8 tries, u8 rix, int rtsctsenable)
697{ 608{
698 rate->count = tries; 609 rate->count = tries;
699 rate->idx = rix; 610 rate->idx = rate_table->info[rix].ratecode;
700 611
701 if (txrc->short_preamble) 612 if (txrc->short_preamble)
702 rate->flags |= IEEE80211_TX_RC_USE_SHORT_PREAMBLE; 613 rate->flags |= IEEE80211_TX_RC_USE_SHORT_PREAMBLE;
703 if (txrc->rts || rtsctsenable) 614 if (txrc->rts || rtsctsenable)
704 rate->flags |= IEEE80211_TX_RC_USE_RTS_CTS; 615 rate->flags |= IEEE80211_TX_RC_USE_RTS_CTS;
705 if (WLAN_RC_PHY_40(rate_table->info[rix].phy)) 616
706 rate->flags |= IEEE80211_TX_RC_40_MHZ_WIDTH; 617 if (WLAN_RC_PHY_HT(rate_table->info[rix].phy)) {
707 if (WLAN_RC_PHY_SGI(rate_table->info[rix].phy))
708 rate->flags |= IEEE80211_TX_RC_SHORT_GI;
709 if (WLAN_RC_PHY_HT(rate_table->info[rix].phy))
710 rate->flags |= IEEE80211_TX_RC_MCS; 618 rate->flags |= IEEE80211_TX_RC_MCS;
619 if (WLAN_RC_PHY_40(rate_table->info[rix].phy))
620 rate->flags |= IEEE80211_TX_RC_40_MHZ_WIDTH;
621 if (WLAN_RC_PHY_SGI(rate_table->info[rix].phy))
622 rate->flags |= IEEE80211_TX_RC_SHORT_GI;
623 }
711} 624}
712 625
713static void ath_rc_rate_set_rtscts(struct ath_softc *sc, 626static void ath_rc_rate_set_rtscts(struct ath_softc *sc,
@@ -720,7 +633,7 @@ static void ath_rc_rate_set_rtscts(struct ath_softc *sc,
720 /* get the cix for the lowest valid rix */ 633 /* get the cix for the lowest valid rix */
721 for (i = 3; i >= 0; i--) { 634 for (i = 3; i >= 0; i--) {
722 if (rates[i].count && (rates[i].idx >= 0)) { 635 if (rates[i].count && (rates[i].idx >= 0)) {
723 rix = rates[i].idx; 636 rix = ath_rc_get_rateindex(rate_table, &rates[i]);
724 break; 637 break;
725 } 638 }
726 } 639 }
@@ -757,7 +670,7 @@ static void ath_get_rate(void *priv, struct ieee80211_sta *sta, void *priv_sta,
757 struct ieee80211_tx_rate *rates = tx_info->control.rates; 670 struct ieee80211_tx_rate *rates = tx_info->control.rates;
758 struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data; 671 struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data;
759 __le16 fc = hdr->frame_control; 672 __le16 fc = hdr->frame_control;
760 u8 try_per_rate, i = 0, rix, nrix; 673 u8 try_per_rate, i = 0, rix;
761 int is_probe = 0; 674 int is_probe = 0;
762 675
763 if (rate_control_send_low(sta, priv_sta, txrc)) 676 if (rate_control_send_low(sta, priv_sta, txrc))
@@ -767,48 +680,47 @@ static void ath_get_rate(void *priv, struct ieee80211_sta *sta, void *priv_sta,
767 * For Multi Rate Retry we use a different number of 680 * For Multi Rate Retry we use a different number of
768 * retry attempt counts. This ends up looking like this: 681 * retry attempt counts. This ends up looking like this:
769 * 682 *
770 * MRR[0] = 2 683 * MRR[0] = 4
771 * MRR[1] = 2 684 * MRR[1] = 4
772 * MRR[2] = 2 685 * MRR[2] = 4
773 * MRR[3] = 4 686 * MRR[3] = 8
774 * 687 *
775 */ 688 */
776 try_per_rate = sc->hw->max_rate_tries; 689 try_per_rate = 4;
777 690
778 rate_table = sc->cur_rate_table; 691 rate_table = sc->cur_rate_table;
779 rix = ath_rc_get_highest_rix(sc, ath_rc_priv, rate_table, &is_probe); 692 rix = ath_rc_get_highest_rix(sc, ath_rc_priv, rate_table, &is_probe);
780 nrix = rix;
781 693
782 if (is_probe) { 694 if (is_probe) {
783 /* set one try for probe rates. For the 695 /* set one try for probe rates. For the
784 * probes don't enable rts */ 696 * probes don't enable rts */
785 ath_rc_rate_set_series(rate_table, &rates[i++], txrc, 697 ath_rc_rate_set_series(rate_table, &rates[i++], txrc,
786 1, nrix, 0); 698 1, rix, 0);
787 699
788 /* Get the next tried/allowed rate. No RTS for the next series 700 /* Get the next tried/allowed rate. No RTS for the next series
789 * after the probe rate 701 * after the probe rate
790 */ 702 */
791 ath_rc_get_lower_rix(rate_table, ath_rc_priv, rix, &nrix); 703 ath_rc_get_lower_rix(rate_table, ath_rc_priv, rix, &rix);
792 ath_rc_rate_set_series(rate_table, &rates[i++], txrc, 704 ath_rc_rate_set_series(rate_table, &rates[i++], txrc,
793 try_per_rate, nrix, 0); 705 try_per_rate, rix, 0);
794 706
795 tx_info->flags |= IEEE80211_TX_CTL_RATE_CTRL_PROBE; 707 tx_info->flags |= IEEE80211_TX_CTL_RATE_CTRL_PROBE;
796 } else { 708 } else {
797 /* Set the choosen rate. No RTS for first series entry. */ 709 /* Set the choosen rate. No RTS for first series entry. */
798 ath_rc_rate_set_series(rate_table, &rates[i++], txrc, 710 ath_rc_rate_set_series(rate_table, &rates[i++], txrc,
799 try_per_rate, nrix, 0); 711 try_per_rate, rix, 0);
800 } 712 }
801 713
802 /* Fill in the other rates for multirate retry */ 714 /* Fill in the other rates for multirate retry */
803 for ( ; i < 4; i++) { 715 for ( ; i < 4; i++) {
804 /* Use twice the number of tries for the last MRR segment. */ 716 /* Use twice the number of tries for the last MRR segment. */
805 if (i + 1 == 4) 717 if (i + 1 == 4)
806 try_per_rate = 4; 718 try_per_rate = 8;
807 719
808 ath_rc_get_lower_rix(rate_table, ath_rc_priv, rix, &nrix); 720 ath_rc_get_lower_rix(rate_table, ath_rc_priv, rix, &rix);
809 /* All other rates in the series have RTS enabled */ 721 /* All other rates in the series have RTS enabled */
810 ath_rc_rate_set_series(rate_table, &rates[i], txrc, 722 ath_rc_rate_set_series(rate_table, &rates[i], txrc,
811 try_per_rate, nrix, 1); 723 try_per_rate, rix, 1);
812 } 724 }
813 725
814 /* 726 /*
@@ -859,12 +771,12 @@ static void ath_get_rate(void *priv, struct ieee80211_sta *sta, void *priv_sta,
859static bool ath_rc_update_per(struct ath_softc *sc, 771static bool ath_rc_update_per(struct ath_softc *sc,
860 const struct ath_rate_table *rate_table, 772 const struct ath_rate_table *rate_table,
861 struct ath_rate_priv *ath_rc_priv, 773 struct ath_rate_priv *ath_rc_priv,
862 struct ath_tx_info_priv *tx_info_priv, 774 struct ieee80211_tx_info *tx_info,
863 int tx_rate, int xretries, int retries, 775 int tx_rate, int xretries, int retries,
864 u32 now_msec) 776 u32 now_msec)
865{ 777{
866 bool state_change = false; 778 bool state_change = false;
867 int count; 779 int count, n_bad_frames;
868 u8 last_per; 780 u8 last_per;
869 static u32 nretry_to_per_lookup[10] = { 781 static u32 nretry_to_per_lookup[10] = {
870 100 * 0 / 1, 782 100 * 0 / 1,
@@ -880,6 +792,7 @@ static bool ath_rc_update_per(struct ath_softc *sc,
880 }; 792 };
881 793
882 last_per = ath_rc_priv->per[tx_rate]; 794 last_per = ath_rc_priv->per[tx_rate];
795 n_bad_frames = tx_info->status.ampdu_len - tx_info->status.ampdu_ack_len;
883 796
884 if (xretries) { 797 if (xretries) {
885 if (xretries == 1) { 798 if (xretries == 1) {
@@ -907,7 +820,7 @@ static bool ath_rc_update_per(struct ath_softc *sc,
907 if (retries >= count) 820 if (retries >= count)
908 retries = count - 1; 821 retries = count - 1;
909 822
910 if (tx_info_priv->n_bad_frames) { 823 if (n_bad_frames) {
911 /* new_PER = 7/8*old_PER + 1/8*(currentPER) 824 /* new_PER = 7/8*old_PER + 1/8*(currentPER)
912 * Assuming that n_frames is not 0. The current PER 825 * Assuming that n_frames is not 0. The current PER
913 * from the retries is 100 * retries / (retries+1), 826 * from the retries is 100 * retries / (retries+1),
@@ -920,14 +833,14 @@ static bool ath_rc_update_per(struct ath_softc *sc,
920 * the above PER. The expression below is a 833 * the above PER. The expression below is a
921 * simplified version of the sum of these two terms. 834 * simplified version of the sum of these two terms.
922 */ 835 */
923 if (tx_info_priv->n_frames > 0) { 836 if (tx_info->status.ampdu_len > 0) {
924 int n_frames, n_bad_frames; 837 int n_frames, n_bad_tries;
925 u8 cur_per, new_per; 838 u8 cur_per, new_per;
926 839
927 n_bad_frames = retries * tx_info_priv->n_frames + 840 n_bad_tries = retries * tx_info->status.ampdu_len +
928 tx_info_priv->n_bad_frames; 841 n_bad_frames;
929 n_frames = tx_info_priv->n_frames * (retries + 1); 842 n_frames = tx_info->status.ampdu_len * (retries + 1);
930 cur_per = (100 * n_bad_frames / n_frames) >> 3; 843 cur_per = (100 * n_bad_tries / n_frames) >> 3;
931 new_per = (u8)(last_per - (last_per >> 3) + cur_per); 844 new_per = (u8)(last_per - (last_per >> 3) + cur_per);
932 ath_rc_priv->per[tx_rate] = new_per; 845 ath_rc_priv->per[tx_rate] = new_per;
933 } 846 }
@@ -943,8 +856,7 @@ static bool ath_rc_update_per(struct ath_softc *sc,
943 * this was a probe. Otherwise, ignore the probe. 856 * this was a probe. Otherwise, ignore the probe.
944 */ 857 */
945 if (ath_rc_priv->probe_rate && ath_rc_priv->probe_rate == tx_rate) { 858 if (ath_rc_priv->probe_rate && ath_rc_priv->probe_rate == tx_rate) {
946 if (retries > 0 || 2 * tx_info_priv->n_bad_frames > 859 if (retries > 0 || 2 * n_bad_frames > tx_info->status.ampdu_len) {
947 tx_info_priv->n_frames) {
948 /* 860 /*
949 * Since we probed with just a single attempt, 861 * Since we probed with just a single attempt,
950 * any retries means the probe failed. Also, 862 * any retries means the probe failed. Also,
@@ -969,7 +881,7 @@ static bool ath_rc_update_per(struct ath_softc *sc,
969 * Since this probe succeeded, we allow the next 881 * Since this probe succeeded, we allow the next
970 * probe twice as soon. This allows the maxRate 882 * probe twice as soon. This allows the maxRate
971 * to move up faster if the probes are 883 * to move up faster if the probes are
972 * succesful. 884 * successful.
973 */ 885 */
974 ath_rc_priv->probe_time = 886 ath_rc_priv->probe_time =
975 now_msec - rate_table->probe_interval / 2; 887 now_msec - rate_table->probe_interval / 2;
@@ -1003,7 +915,7 @@ static bool ath_rc_update_per(struct ath_softc *sc,
1003 915
1004static void ath_rc_update_ht(struct ath_softc *sc, 916static void ath_rc_update_ht(struct ath_softc *sc,
1005 struct ath_rate_priv *ath_rc_priv, 917 struct ath_rate_priv *ath_rc_priv,
1006 struct ath_tx_info_priv *tx_info_priv, 918 struct ieee80211_tx_info *tx_info,
1007 int tx_rate, int xretries, int retries) 919 int tx_rate, int xretries, int retries)
1008{ 920{
1009 u32 now_msec = jiffies_to_msecs(jiffies); 921 u32 now_msec = jiffies_to_msecs(jiffies);
@@ -1020,7 +932,7 @@ static void ath_rc_update_ht(struct ath_softc *sc,
1020 932
1021 /* Update PER first */ 933 /* Update PER first */
1022 state_change = ath_rc_update_per(sc, rate_table, ath_rc_priv, 934 state_change = ath_rc_update_per(sc, rate_table, ath_rc_priv,
1023 tx_info_priv, tx_rate, xretries, 935 tx_info, tx_rate, xretries,
1024 retries, now_msec); 936 retries, now_msec);
1025 937
1026 /* 938 /*
@@ -1080,15 +992,19 @@ static int ath_rc_get_rateindex(const struct ath_rate_table *rate_table,
1080{ 992{
1081 int rix; 993 int rix;
1082 994
995 if (!(rate->flags & IEEE80211_TX_RC_MCS))
996 return rate->idx;
997
998 rix = rate->idx + rate_table->mcs_start;
1083 if ((rate->flags & IEEE80211_TX_RC_40_MHZ_WIDTH) && 999 if ((rate->flags & IEEE80211_TX_RC_40_MHZ_WIDTH) &&
1084 (rate->flags & IEEE80211_TX_RC_SHORT_GI)) 1000 (rate->flags & IEEE80211_TX_RC_SHORT_GI))
1085 rix = rate_table->info[rate->idx].ht_index; 1001 rix = rate_table->info[rix].ht_index;
1086 else if (rate->flags & IEEE80211_TX_RC_SHORT_GI) 1002 else if (rate->flags & IEEE80211_TX_RC_SHORT_GI)
1087 rix = rate_table->info[rate->idx].sgi_index; 1003 rix = rate_table->info[rix].sgi_index;
1088 else if (rate->flags & IEEE80211_TX_RC_40_MHZ_WIDTH) 1004 else if (rate->flags & IEEE80211_TX_RC_40_MHZ_WIDTH)
1089 rix = rate_table->info[rate->idx].cw40index; 1005 rix = rate_table->info[rix].cw40index;
1090 else 1006 else
1091 rix = rate_table->info[rate->idx].base_index; 1007 rix = rate_table->info[rix].base_index;
1092 1008
1093 return rix; 1009 return rix;
1094} 1010}
@@ -1098,7 +1014,6 @@ static void ath_rc_tx_status(struct ath_softc *sc,
1098 struct ieee80211_tx_info *tx_info, 1014 struct ieee80211_tx_info *tx_info,
1099 int final_ts_idx, int xretries, int long_retry) 1015 int final_ts_idx, int xretries, int long_retry)
1100{ 1016{
1101 struct ath_tx_info_priv *tx_info_priv = ATH_TX_INFO_PRIV(tx_info);
1102 const struct ath_rate_table *rate_table; 1017 const struct ath_rate_table *rate_table;
1103 struct ieee80211_tx_rate *rates = tx_info->status.rates; 1018 struct ieee80211_tx_rate *rates = tx_info->status.rates;
1104 u8 flags; 1019 u8 flags;
@@ -1124,9 +1039,8 @@ static void ath_rc_tx_status(struct ath_softc *sc,
1124 return; 1039 return;
1125 1040
1126 rix = ath_rc_get_rateindex(rate_table, &rates[i]); 1041 rix = ath_rc_get_rateindex(rate_table, &rates[i]);
1127 ath_rc_update_ht(sc, ath_rc_priv, 1042 ath_rc_update_ht(sc, ath_rc_priv, tx_info,
1128 tx_info_priv, rix, 1043 rix, xretries ? 1 : 2,
1129 xretries ? 1 : 2,
1130 rates[i].count); 1044 rates[i].count);
1131 } 1045 }
1132 } 1046 }
@@ -1149,8 +1063,7 @@ static void ath_rc_tx_status(struct ath_softc *sc,
1149 return; 1063 return;
1150 1064
1151 rix = ath_rc_get_rateindex(rate_table, &rates[i]); 1065 rix = ath_rc_get_rateindex(rate_table, &rates[i]);
1152 ath_rc_update_ht(sc, ath_rc_priv, tx_info_priv, rix, 1066 ath_rc_update_ht(sc, ath_rc_priv, tx_info, rix, xretries, long_retry);
1153 xretries, long_retry);
1154} 1067}
1155 1068
1156static const 1069static const
@@ -1160,6 +1073,7 @@ struct ath_rate_table *ath_choose_rate_table(struct ath_softc *sc,
1160 bool is_cw_40) 1073 bool is_cw_40)
1161{ 1074{
1162 int mode = 0; 1075 int mode = 0;
1076 struct ath_common *common = ath9k_hw_common(sc->sc_ah);
1163 1077
1164 switch(band) { 1078 switch(band) {
1165 case IEEE80211_BAND_2GHZ: 1079 case IEEE80211_BAND_2GHZ:
@@ -1177,14 +1091,17 @@ struct ath_rate_table *ath_choose_rate_table(struct ath_softc *sc,
1177 mode = ATH9K_MODE_11NA_HT40PLUS; 1091 mode = ATH9K_MODE_11NA_HT40PLUS;
1178 break; 1092 break;
1179 default: 1093 default:
1180 DPRINTF(sc, ATH_DBG_CONFIG, "Invalid band\n"); 1094 ath_print(common, ATH_DBG_CONFIG, "Invalid band\n");
1181 return NULL; 1095 return NULL;
1182 } 1096 }
1183 1097
1184 BUG_ON(mode >= ATH9K_MODE_MAX); 1098 BUG_ON(mode >= ATH9K_MODE_MAX);
1185 1099
1186 DPRINTF(sc, ATH_DBG_CONFIG, "Choosing rate table for mode: %d\n", mode); 1100 ath_print(common, ATH_DBG_CONFIG,
1187 return sc->hw_rate_table[mode]; 1101 "Choosing rate table for mode: %d\n", mode);
1102
1103 sc->cur_rate_mode = mode;
1104 return hw_rate_table[mode];
1188} 1105}
1189 1106
1190static void ath_rc_init(struct ath_softc *sc, 1107static void ath_rc_init(struct ath_softc *sc,
@@ -1194,14 +1111,10 @@ static void ath_rc_init(struct ath_softc *sc,
1194 const struct ath_rate_table *rate_table) 1111 const struct ath_rate_table *rate_table)
1195{ 1112{
1196 struct ath_rateset *rateset = &ath_rc_priv->neg_rates; 1113 struct ath_rateset *rateset = &ath_rc_priv->neg_rates;
1114 struct ath_common *common = ath9k_hw_common(sc->sc_ah);
1197 u8 *ht_mcs = (u8 *)&ath_rc_priv->neg_ht_rates; 1115 u8 *ht_mcs = (u8 *)&ath_rc_priv->neg_ht_rates;
1198 u8 i, j, k, hi = 0, hthi = 0; 1116 u8 i, j, k, hi = 0, hthi = 0;
1199 1117
1200 if (!rate_table) {
1201 DPRINTF(sc, ATH_DBG_FATAL, "Rate table not initialized\n");
1202 return;
1203 }
1204
1205 /* Initial rate table size. Will change depending 1118 /* Initial rate table size. Will change depending
1206 * on the working rate set */ 1119 * on the working rate set */
1207 ath_rc_priv->rate_table_size = RATE_TABLE_SIZE; 1120 ath_rc_priv->rate_table_size = RATE_TABLE_SIZE;
@@ -1239,7 +1152,7 @@ static void ath_rc_init(struct ath_softc *sc,
1239 1152
1240 ath_rc_priv->rate_table_size = hi + 1; 1153 ath_rc_priv->rate_table_size = hi + 1;
1241 ath_rc_priv->rate_max_phy = 0; 1154 ath_rc_priv->rate_max_phy = 0;
1242 ASSERT(ath_rc_priv->rate_table_size <= RATE_TABLE_SIZE); 1155 BUG_ON(ath_rc_priv->rate_table_size > RATE_TABLE_SIZE);
1243 1156
1244 for (i = 0, k = 0; i < WLAN_RC_PHY_MAX; i++) { 1157 for (i = 0, k = 0; i < WLAN_RC_PHY_MAX; i++) {
1245 for (j = 0; j < ath_rc_priv->valid_phy_ratecnt[i]; j++) { 1158 for (j = 0; j < ath_rc_priv->valid_phy_ratecnt[i]; j++) {
@@ -1253,16 +1166,17 @@ static void ath_rc_init(struct ath_softc *sc,
1253 1166
1254 ath_rc_priv->rate_max_phy = ath_rc_priv->valid_phy_rateidx[i][j-1]; 1167 ath_rc_priv->rate_max_phy = ath_rc_priv->valid_phy_rateidx[i][j-1];
1255 } 1168 }
1256 ASSERT(ath_rc_priv->rate_table_size <= RATE_TABLE_SIZE); 1169 BUG_ON(ath_rc_priv->rate_table_size > RATE_TABLE_SIZE);
1257 ASSERT(k <= RATE_TABLE_SIZE); 1170 BUG_ON(k > RATE_TABLE_SIZE);
1258 1171
1259 ath_rc_priv->max_valid_rate = k; 1172 ath_rc_priv->max_valid_rate = k;
1260 ath_rc_sort_validrates(rate_table, ath_rc_priv); 1173 ath_rc_sort_validrates(rate_table, ath_rc_priv);
1261 ath_rc_priv->rate_max_phy = ath_rc_priv->valid_rate_index[k-4]; 1174 ath_rc_priv->rate_max_phy = ath_rc_priv->valid_rate_index[k-4];
1262 sc->cur_rate_table = rate_table; 1175 sc->cur_rate_table = rate_table;
1263 1176
1264 DPRINTF(sc, ATH_DBG_CONFIG, "RC Initialized with capabilities: 0x%x\n", 1177 ath_print(common, ATH_DBG_CONFIG,
1265 ath_rc_priv->ht_cap); 1178 "RC Initialized with capabilities: 0x%x\n",
1179 ath_rc_priv->ht_cap);
1266} 1180}
1267 1181
1268static u8 ath_rc_build_ht_caps(struct ath_softc *sc, struct ieee80211_sta *sta, 1182static u8 ath_rc_build_ht_caps(struct ath_softc *sc, struct ieee80211_sta *sta,
@@ -1296,44 +1210,52 @@ static void ath_tx_status(void *priv, struct ieee80211_supported_band *sband,
1296{ 1210{
1297 struct ath_softc *sc = priv; 1211 struct ath_softc *sc = priv;
1298 struct ath_rate_priv *ath_rc_priv = priv_sta; 1212 struct ath_rate_priv *ath_rc_priv = priv_sta;
1299 struct ath_tx_info_priv *tx_info_priv = NULL;
1300 struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(skb); 1213 struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(skb);
1301 struct ieee80211_hdr *hdr; 1214 struct ieee80211_hdr *hdr;
1302 int final_ts_idx, tx_status = 0, is_underrun = 0; 1215 int final_ts_idx = 0, tx_status = 0, is_underrun = 0;
1216 int long_retry = 0;
1303 __le16 fc; 1217 __le16 fc;
1218 int i;
1304 1219
1305 hdr = (struct ieee80211_hdr *)skb->data; 1220 hdr = (struct ieee80211_hdr *)skb->data;
1306 fc = hdr->frame_control; 1221 fc = hdr->frame_control;
1307 tx_info_priv = ATH_TX_INFO_PRIV(tx_info); 1222 for (i = 0; i < IEEE80211_TX_MAX_RATES; i++) {
1308 final_ts_idx = tx_info_priv->tx.ts_rateindex; 1223 struct ieee80211_tx_rate *rate = &tx_info->status.rates[i];
1224 if (!rate->count)
1225 break;
1226
1227 final_ts_idx = i;
1228 long_retry = rate->count - 1;
1229 }
1309 1230
1310 if (!priv_sta || !ieee80211_is_data(fc) || 1231 if (!priv_sta || !ieee80211_is_data(fc) ||
1311 !tx_info_priv->update_rc) 1232 !(tx_info->pad[0] & ATH_TX_INFO_UPDATE_RC))
1312 goto exit; 1233 return;
1313 1234
1314 if (tx_info_priv->tx.ts_status & ATH9K_TXERR_FILT) 1235 if (tx_info->flags & IEEE80211_TX_STAT_TX_FILTERED)
1315 goto exit; 1236 return;
1316 1237
1317 /* 1238 /*
1318 * If underrun error is seen assume it as an excessive retry only 1239 * If an underrun error is seen assume it as an excessive retry only
1319 * if prefetch trigger level have reached the max (0x3f for 5416) 1240 * if max frame trigger level has been reached (2 KB for singel stream,
1320 * Adjust the long retry as if the frame was tried hw->max_rate_tries 1241 * and 4 KB for dual stream). Adjust the long retry as if the frame was
1321 * times. This affects how ratectrl updates PER for the failed rate. 1242 * tried hw->max_rate_tries times to affect how ratectrl updates PER for
1243 * the failed rate. In case of congestion on the bus penalizing these
1244 * type of underruns should help hardware actually transmit new frames
1245 * successfully by eventually preferring slower rates. This itself
1246 * should also alleviate congestion on the bus.
1322 */ 1247 */
1323 if (tx_info_priv->tx.ts_flags & 1248 if ((tx_info->pad[0] & ATH_TX_INFO_UNDERRUN) &&
1324 (ATH9K_TX_DATA_UNDERRUN | ATH9K_TX_DELIM_UNDERRUN) && 1249 (sc->sc_ah->tx_trig_level >= ath_rc_priv->tx_triglevel_max)) {
1325 ((sc->sc_ah->tx_trig_level) >= ath_rc_priv->tx_triglevel_max)) {
1326 tx_status = 1; 1250 tx_status = 1;
1327 is_underrun = 1; 1251 is_underrun = 1;
1328 } 1252 }
1329 1253
1330 if ((tx_info_priv->tx.ts_status & ATH9K_TXERR_XRETRY) || 1254 if (tx_info->pad[0] & ATH_TX_INFO_XRETRY)
1331 (tx_info_priv->tx.ts_status & ATH9K_TXERR_FIFO))
1332 tx_status = 1; 1255 tx_status = 1;
1333 1256
1334 ath_rc_tx_status(sc, ath_rc_priv, tx_info, final_ts_idx, tx_status, 1257 ath_rc_tx_status(sc, ath_rc_priv, tx_info, final_ts_idx, tx_status,
1335 (is_underrun) ? sc->hw->max_rate_tries : 1258 (is_underrun) ? sc->hw->max_rate_tries : long_retry);
1336 tx_info_priv->tx.ts_longretry);
1337 1259
1338 /* Check if aggregation has to be enabled for this tid */ 1260 /* Check if aggregation has to be enabled for this tid */
1339 if (conf_is_ht(&sc->hw->conf) && 1261 if (conf_is_ht(&sc->hw->conf) &&
@@ -1347,13 +1269,12 @@ static void ath_tx_status(void *priv, struct ieee80211_supported_band *sband,
1347 an = (struct ath_node *)sta->drv_priv; 1269 an = (struct ath_node *)sta->drv_priv;
1348 1270
1349 if(ath_tx_aggr_check(sc, an, tid)) 1271 if(ath_tx_aggr_check(sc, an, tid))
1350 ieee80211_start_tx_ba_session(sc->hw, hdr->addr1, tid); 1272 ieee80211_start_tx_ba_session(sta, tid);
1351 } 1273 }
1352 } 1274 }
1353 1275
1354 ath_debug_stat_rc(sc, skb); 1276 ath_debug_stat_rc(sc, ath_rc_get_rateindex(sc->cur_rate_table,
1355exit: 1277 &tx_info->status.rates[final_ts_idx]));
1356 kfree(tx_info_priv);
1357} 1278}
1358 1279
1359static void ath_rate_init(void *priv, struct ieee80211_supported_band *sband, 1280static void ath_rate_init(void *priv, struct ieee80211_supported_band *sband,
@@ -1361,7 +1282,7 @@ static void ath_rate_init(void *priv, struct ieee80211_supported_band *sband,
1361{ 1282{
1362 struct ath_softc *sc = priv; 1283 struct ath_softc *sc = priv;
1363 struct ath_rate_priv *ath_rc_priv = priv_sta; 1284 struct ath_rate_priv *ath_rc_priv = priv_sta;
1364 const struct ath_rate_table *rate_table = NULL; 1285 const struct ath_rate_table *rate_table;
1365 bool is_cw40, is_sgi40; 1286 bool is_cw40, is_sgi40;
1366 int i, j = 0; 1287 int i, j = 0;
1367 1288
@@ -1393,11 +1314,9 @@ static void ath_rate_init(void *priv, struct ieee80211_supported_band *sband,
1393 (sc->sc_ah->opmode == NL80211_IFTYPE_MESH_POINT) || 1314 (sc->sc_ah->opmode == NL80211_IFTYPE_MESH_POINT) ||
1394 (sc->sc_ah->opmode == NL80211_IFTYPE_ADHOC)) { 1315 (sc->sc_ah->opmode == NL80211_IFTYPE_ADHOC)) {
1395 rate_table = ath_choose_rate_table(sc, sband->band, 1316 rate_table = ath_choose_rate_table(sc, sband->band,
1396 sta->ht_cap.ht_supported, 1317 sta->ht_cap.ht_supported, is_cw40);
1397 is_cw40); 1318 } else {
1398 } else if (sc->sc_ah->opmode == NL80211_IFTYPE_AP) { 1319 rate_table = hw_rate_table[sc->cur_rate_mode];
1399 /* cur_rate_table would be set on init through config() */
1400 rate_table = sc->cur_rate_table;
1401 } 1320 }
1402 1321
1403 ath_rc_priv->ht_cap = ath_rc_build_ht_caps(sc, sta, is_cw40, is_sgi40); 1322 ath_rc_priv->ht_cap = ath_rc_build_ht_caps(sc, sta, is_cw40, is_sgi40);
@@ -1406,7 +1325,7 @@ static void ath_rate_init(void *priv, struct ieee80211_supported_band *sband,
1406 1325
1407static void ath_rate_update(void *priv, struct ieee80211_supported_band *sband, 1326static void ath_rate_update(void *priv, struct ieee80211_supported_band *sband,
1408 struct ieee80211_sta *sta, void *priv_sta, 1327 struct ieee80211_sta *sta, void *priv_sta,
1409 u32 changed) 1328 u32 changed, enum nl80211_channel_type oper_chan_type)
1410{ 1329{
1411 struct ath_softc *sc = priv; 1330 struct ath_softc *sc = priv;
1412 struct ath_rate_priv *ath_rc_priv = priv_sta; 1331 struct ath_rate_priv *ath_rc_priv = priv_sta;
@@ -1423,8 +1342,8 @@ static void ath_rate_update(void *priv, struct ieee80211_supported_band *sband,
1423 if (sc->sc_ah->opmode != NL80211_IFTYPE_STATION) 1342 if (sc->sc_ah->opmode != NL80211_IFTYPE_STATION)
1424 return; 1343 return;
1425 1344
1426 if (sc->hw->conf.channel_type == NL80211_CHAN_HT40MINUS || 1345 if (oper_chan_type == NL80211_CHAN_HT40MINUS ||
1427 sc->hw->conf.channel_type == NL80211_CHAN_HT40PLUS) 1346 oper_chan_type == NL80211_CHAN_HT40PLUS)
1428 oper_cw40 = true; 1347 oper_cw40 = true;
1429 1348
1430 oper_sgi40 = (sta->ht_cap.cap & IEEE80211_HT_CAP_SGI_40) ? 1349 oper_sgi40 = (sta->ht_cap.cap & IEEE80211_HT_CAP_SGI_40) ?
@@ -1438,9 +1357,10 @@ static void ath_rate_update(void *priv, struct ieee80211_supported_band *sband,
1438 oper_cw40, oper_sgi40); 1357 oper_cw40, oper_sgi40);
1439 ath_rc_init(sc, priv_sta, sband, sta, rate_table); 1358 ath_rc_init(sc, priv_sta, sband, sta, rate_table);
1440 1359
1441 DPRINTF(sc, ATH_DBG_CONFIG, 1360 ath_print(ath9k_hw_common(sc->sc_ah), ATH_DBG_CONFIG,
1442 "Operating HT Bandwidth changed to: %d\n", 1361 "Operating HT Bandwidth changed to: %d\n",
1443 sc->hw->conf.channel_type); 1362 sc->hw->conf.channel_type);
1363 sc->cur_rate_table = hw_rate_table[sc->cur_rate_mode];
1444 } 1364 }
1445 } 1365 }
1446} 1366}
@@ -1463,8 +1383,8 @@ static void *ath_rate_alloc_sta(void *priv, struct ieee80211_sta *sta, gfp_t gfp
1463 1383
1464 rate_priv = kzalloc(sizeof(struct ath_rate_priv), gfp); 1384 rate_priv = kzalloc(sizeof(struct ath_rate_priv), gfp);
1465 if (!rate_priv) { 1385 if (!rate_priv) {
1466 DPRINTF(sc, ATH_DBG_FATAL, 1386 ath_print(ath9k_hw_common(sc->sc_ah), ATH_DBG_FATAL,
1467 "Unable to allocate private rc structure\n"); 1387 "Unable to allocate private rc structure\n");
1468 return NULL; 1388 return NULL;
1469 } 1389 }
1470 1390
@@ -1493,26 +1413,6 @@ static struct rate_control_ops ath_rate_ops = {
1493 .free_sta = ath_rate_free_sta, 1413 .free_sta = ath_rate_free_sta,
1494}; 1414};
1495 1415
1496void ath_rate_attach(struct ath_softc *sc)
1497{
1498 sc->hw_rate_table[ATH9K_MODE_11A] =
1499 &ar5416_11a_ratetable;
1500 sc->hw_rate_table[ATH9K_MODE_11G] =
1501 &ar5416_11g_ratetable;
1502 sc->hw_rate_table[ATH9K_MODE_11NA_HT20] =
1503 &ar5416_11na_ratetable;
1504 sc->hw_rate_table[ATH9K_MODE_11NG_HT20] =
1505 &ar5416_11ng_ratetable;
1506 sc->hw_rate_table[ATH9K_MODE_11NA_HT40PLUS] =
1507 &ar5416_11na_ratetable;
1508 sc->hw_rate_table[ATH9K_MODE_11NA_HT40MINUS] =
1509 &ar5416_11na_ratetable;
1510 sc->hw_rate_table[ATH9K_MODE_11NG_HT40PLUS] =
1511 &ar5416_11ng_ratetable;
1512 sc->hw_rate_table[ATH9K_MODE_11NG_HT40MINUS] =
1513 &ar5416_11ng_ratetable;
1514}
1515
1516int ath_rate_control_register(void) 1416int ath_rate_control_register(void)
1517{ 1417{
1518 return ieee80211_rate_control_register(&ath_rate_ops); 1418 return ieee80211_rate_control_register(&ath_rate_ops);