1 /* 2 * Copyright 2009 Sun Microsystems, Inc. All rights reserved. 3 * Use is subject to license terms. 4 */ 5 6 /* 7 * Copyright (c) 2004 Video54 Technologies, Inc. 8 * Copyright (c) 2004-2008 Atheros Communications, Inc. 9 * 10 * Permission to use, copy, modify, and/or distribute this software for any 11 * purpose with or without fee is hereby granted, provided that the above 12 * copyright notice and this permission notice appear in all copies. 13 * 14 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 15 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 16 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 17 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 18 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 19 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 20 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 21 */ 22 #include <sys/time.h> 23 #include <sys/types.h> 24 #include <sys/ddi.h> 25 26 #include "arn_core.h" 27 28 static struct ath_rate_table ar5416_11na_ratetable = { 29 42, 30 {0}, 31 { 32 { VALID, VALID, WLAN_RC_PHY_OFDM, 6000, /* 6 Mb */ 33 5400, 0x0b, 0x00, 12, 34 0, 2, 1, 0, 0, 0, 0, 0 }, 35 { VALID, VALID, WLAN_RC_PHY_OFDM, 9000, /* 9 Mb */ 36 7800, 0x0f, 0x00, 18, 37 0, 3, 1, 1, 1, 1, 1, 0 }, 38 { VALID, VALID, WLAN_RC_PHY_OFDM, 12000, /* 12 Mb */ 39 10000, 0x0a, 0x00, 24, 40 2, 4, 2, 2, 2, 2, 2, 0 }, 41 { VALID, VALID, WLAN_RC_PHY_OFDM, 18000, /* 18 Mb */ 42 13900, 0x0e, 0x00, 36, 43 2, 6, 2, 3, 3, 3, 3, 0 }, 44 { VALID, VALID, WLAN_RC_PHY_OFDM, 24000, /* 24 Mb */ 45 17300, 0x09, 0x00, 48, 46 4, 10, 3, 4, 4, 4, 4, 0 }, 47 { VALID, VALID, WLAN_RC_PHY_OFDM, 36000, /* 36 Mb */ 48 23000, 0x0d, 0x00, 72, 49 4, 14, 3, 5, 5, 5, 5, 0 }, 50 { VALID, VALID, WLAN_RC_PHY_OFDM, 48000, /* 48 Mb */ 51 27400, 0x08, 0x00, 96, 52 4, 20, 3, 6, 6, 6, 6, 0 }, 53 { VALID, VALID, WLAN_RC_PHY_OFDM, 54000, /* 54 Mb */ 54 29300, 0x0c, 0x00, 108, 55 4, 23, 3, 7, 7, 7, 7, 0 }, 56 { VALID_20, VALID_20, WLAN_RC_PHY_HT_20_SS, 6500, /* 6.5 Mb */ 57 6400, 0x80, 0x00, 0, 58 0, 2, 3, 8, 24, 8, 24, 3216 }, 59 { VALID_20, VALID_20, WLAN_RC_PHY_HT_20_SS, 13000, /* 13 Mb */ 60 12700, 0x81, 0x00, 1, 61 2, 4, 3, 9, 25, 9, 25, 6434 }, 62 { VALID_20, VALID_20, WLAN_RC_PHY_HT_20_SS, 19500, /* 19.5 Mb */ 63 18800, 0x82, 0x00, 2, 64 2, 6, 3, 10, 26, 10, 26, 9650 }, 65 { VALID_20, VALID_20, WLAN_RC_PHY_HT_20_SS, 26000, /* 26 Mb */ 66 25000, 0x83, 0x00, 3, 67 4, 10, 3, 11, 27, 11, 27, 12868 }, 68 { VALID_20, VALID_20, WLAN_RC_PHY_HT_20_SS, 39000, /* 39 Mb */ 69 36700, 0x84, 0x00, 4, 70 4, 14, 3, 12, 28, 12, 28, 19304 }, 71 { INVALID, VALID_20, WLAN_RC_PHY_HT_20_SS, 52000, /* 52 Mb */ 72 48100, 0x85, 0x00, 5, 73 4, 20, 3, 13, 29, 13, 29, 25740 }, 74 { INVALID, VALID_20, WLAN_RC_PHY_HT_20_SS, 58500, /* 58.5 Mb */ 75 53500, 0x86, 0x00, 6, 76 4, 23, 3, 14, 30, 14, 30, 28956 }, 77 { INVALID, VALID_20, WLAN_RC_PHY_HT_20_SS, 65000, /* 65 Mb */ 78 59000, 0x87, 0x00, 7, 79 4, 25, 3, 15, 31, 15, 32, 32180 }, 80 { INVALID, INVALID, WLAN_RC_PHY_HT_20_DS, 13000, /* 13 Mb */ 81 12700, 0x88, 0x00, 82 8, 0, 2, 3, 16, 33, 16, 33, 6430 }, 83 { INVALID, INVALID, WLAN_RC_PHY_HT_20_DS, 26000, /* 26 Mb */ 84 24800, 0x89, 0x00, 9, 85 2, 4, 3, 17, 34, 17, 34, 12860 }, 86 { INVALID, INVALID, WLAN_RC_PHY_HT_20_DS, 39000, /* 39 Mb */ 87 36600, 0x8a, 0x00, 10, 88 2, 6, 3, 18, 35, 18, 35, 19300 }, 89 { VALID_20, INVALID, WLAN_RC_PHY_HT_20_DS, 52000, /* 52 Mb */ 90 48100, 0x8b, 0x00, 11, 91 4, 10, 3, 19, 36, 19, 36, 25736 }, 92 { VALID_20, INVALID, WLAN_RC_PHY_HT_20_DS, 78000, /* 78 Mb */ 93 69500, 0x8c, 0x00, 12, 94 4, 14, 3, 20, 37, 20, 37, 38600 }, 95 { VALID_20, INVALID, WLAN_RC_PHY_HT_20_DS, 104000, /* 104 Mb */ 96 89500, 0x8d, 0x00, 13, 97 4, 20, 3, 21, 38, 21, 38, 51472 }, 98 { VALID_20, INVALID, WLAN_RC_PHY_HT_20_DS, 117000, /* 117 Mb */ 99 98900, 0x8e, 0x00, 14, 100 4, 23, 3, 22, 39, 22, 39, 57890 }, 101 { VALID_20, INVALID, WLAN_RC_PHY_HT_20_DS, 130000, /* 130 Mb */ 102 108300, 0x8f, 0x00, 15, 103 4, 25, 3, 23, 40, 23, 41, 64320 }, 104 { VALID_40, VALID_40, WLAN_RC_PHY_HT_40_SS, 13500, /* 13.5 Mb */ 105 13200, 0x80, 0x00, 0, 106 0, 2, 3, 8, 24, 24, 24, 6684 }, 107 { VALID_40, VALID_40, WLAN_RC_PHY_HT_40_SS, 27500, /* 27.0 Mb */ 108 25900, 0x81, 0x00, 1, 109 2, 4, 3, 9, 25, 25, 25, 13368 }, 110 { VALID_40, VALID_40, WLAN_RC_PHY_HT_40_SS, 40500, /* 40.5 Mb */ 111 38600, 0x82, 0x00, 2, 112 2, 6, 3, 10, 26, 26, 26, 20052 }, 113 { VALID_40, VALID_40, WLAN_RC_PHY_HT_40_SS, 54000, /* 54 Mb */ 114 49800, 0x83, 0x00, 3, 115 4, 10, 3, 11, 27, 27, 27, 26738 }, 116 { VALID_40, VALID_40, WLAN_RC_PHY_HT_40_SS, 81500, /* 81 Mb */ 117 72200, 0x84, 0x00, 4, 118 4, 14, 3, 12, 28, 28, 28, 40104 }, 119 { INVALID, VALID_40, WLAN_RC_PHY_HT_40_SS, 108000, /* 108 Mb */ 120 92900, 0x85, 0x00, 5, 121 4, 20, 3, 13, 29, 29, 29, 53476 }, 122 { INVALID, VALID_40, WLAN_RC_PHY_HT_40_SS, 121500, /* 121.5Mb */ 123 102700, 0x86, 0x00, 6, 124 4, 23, 3, 14, 30, 30, 30, 60156 }, 125 { INVALID, VALID_40, WLAN_RC_PHY_HT_40_SS, 135000, /* 135 Mb */ 126 112000, 0x87, 0x00, 7, 127 4, 25, 3, 15, 31, 32, 32, 66840 }, 128 { INVALID, VALID_40, WLAN_RC_PHY_HT_40_SS_HGI, 129 150000, /* 150Mb */ 130 122000, 0x87, 0x00, 7, 131 4, 25, 3, 15, 31, 32, 32, 74200 }, 132 { INVALID, INVALID, WLAN_RC_PHY_HT_40_DS, 27000, /* 27 Mb */ 133 25800, 0x88, 0x00, 8, 134 0, 2, 3, 16, 33, 33, 33, 13360 }, 135 { INVALID, INVALID, WLAN_RC_PHY_HT_40_DS, 54000, /* 54 Mb */ 136 49800, 0x89, 0x00, 9, 137 2, 4, 3, 17, 34, 34, 34, 26720 }, 138 { INVALID, INVALID, WLAN_RC_PHY_HT_40_DS, 81000, /* 81 Mb */ 139 71900, 0x8a, 0x00, 10, 140 2, 6, 3, 18, 35, 35, 35, 40080 }, 141 { VALID_40, INVALID, WLAN_RC_PHY_HT_40_DS, 108000, /* 108 Mb */ 142 92500, 0x8b, 0x00, 11, 143 4, 10, 3, 19, 36, 36, 36, 53440 }, 144 { VALID_40, INVALID, WLAN_RC_PHY_HT_40_DS, 162000, /* 162 Mb */ 145 130300, 0x8c, 0x00, 12, 146 4, 14, 3, 20, 37, 37, 37, 80160 }, 147 { VALID_40, INVALID, WLAN_RC_PHY_HT_40_DS, 216000, /* 216 Mb */ 148 162800, 0x8d, 0x00, 13, 149 4, 20, 3, 21, 38, 38, 38, 106880 }, 150 { VALID_40, INVALID, WLAN_RC_PHY_HT_40_DS, 243000, /* 243 Mb */ 151 178200, 0x8e, 0x00, 14, 152 4, 23, 3, 22, 39, 39, 39, 120240 }, 153 { VALID_40, INVALID, WLAN_RC_PHY_HT_40_DS, 270000, /* 270 Mb */ 154 192100, 0x8f, 0x00, 15, 155 4, 25, 3, 23, 40, 41, 41, 133600 }, 156 { VALID_40, INVALID, WLAN_RC_PHY_HT_40_DS_HGI, 157 300000, /* 300 Mb */ 158 207000, 0x8f, 0x00, 15, 159 4, 25, 3, 23, 40, 41, 41, 148400 }, 160 }, 161 50, /* probe interval */ 162 50, /* rssi reduce interval */ 163 WLAN_RC_HT_FLAG, /* Phy rates allowed initially */ 164 }; 165 166 /* 167 * 4ms frame limit not used for NG mode. The values filled 168 * for HT are the 64K max aggregate limit 169 */ 170 171 static struct ath_rate_table ar5416_11ng_ratetable = { 172 46, 173 {0}, 174 { 175 { VALID_ALL, VALID_ALL, WLAN_RC_PHY_CCK, 1000, /* 1 Mb */ 176 900, 0x1b, 0x00, 2, 177 0, 0, 1, 0, 0, 0, 0, 0 }, 178 { VALID_ALL, VALID_ALL, WLAN_RC_PHY_CCK, 2000, /* 2 Mb */ 179 1900, 0x1a, 0x04, 4, 180 1, 1, 1, 1, 1, 1, 1, 0 }, 181 { VALID_ALL, VALID_ALL, WLAN_RC_PHY_CCK, 5500, /* 5.5 Mb */ 182 4900, 0x19, 0x04, 11, 183 2, 2, 2, 2, 2, 2, 2, 0 }, 184 { VALID_ALL, VALID_ALL, WLAN_RC_PHY_CCK, 11000, /* 11 Mb */ 185 8100, 0x18, 0x04, 22, 186 3, 3, 2, 3, 3, 3, 3, 0 }, 187 { INVALID, INVALID, WLAN_RC_PHY_OFDM, 6000, /* 6 Mb */ 188 5400, 0x0b, 0x00, 12, 189 4, 2, 1, 4, 4, 4, 4, 0 }, 190 { INVALID, INVALID, WLAN_RC_PHY_OFDM, 9000, /* 9 Mb */ 191 7800, 0x0f, 0x00, 18, 192 4, 3, 1, 5, 5, 5, 5, 0 }, 193 { VALID, VALID, WLAN_RC_PHY_OFDM, 12000, /* 12 Mb */ 194 10100, 0x0a, 0x00, 24, 195 6, 4, 1, 6, 6, 6, 6, 0 }, 196 { VALID, VALID, WLAN_RC_PHY_OFDM, 18000, /* 18 Mb */ 197 14100, 0x0e, 0x00, 36, 198 6, 6, 2, 7, 7, 7, 7, 0 }, 199 { VALID, VALID, WLAN_RC_PHY_OFDM, 24000, /* 24 Mb */ 200 17700, 0x09, 0x00, 48, 201 8, 10, 3, 8, 8, 8, 8, 0 }, 202 { VALID, VALID, WLAN_RC_PHY_OFDM, 36000, /* 36 Mb */ 203 23700, 0x0d, 0x00, 72, 204 8, 14, 3, 9, 9, 9, 9, 0 }, 205 { VALID, VALID, WLAN_RC_PHY_OFDM, 48000, /* 48 Mb */ 206 27400, 0x08, 0x00, 96, 207 8, 20, 3, 10, 10, 10, 10, 0 }, 208 { VALID, VALID, WLAN_RC_PHY_OFDM, 54000, /* 54 Mb */ 209 30900, 0x0c, 0x00, 108, 210 8, 23, 3, 11, 11, 11, 11, 0 }, 211 { INVALID, INVALID, WLAN_RC_PHY_HT_20_SS, 6500, /* 6.5 Mb */ 212 6400, 0x80, 0x00, 0, 213 4, 2, 3, 12, 28, 12, 28, 3216 }, 214 { VALID_20, VALID_20, WLAN_RC_PHY_HT_20_SS, 13000, /* 13 Mb */ 215 12700, 0x81, 0x00, 1, 216 6, 4, 3, 13, 29, 13, 29, 6434 }, 217 { VALID_20, VALID_20, WLAN_RC_PHY_HT_20_SS, 19500, /* 19.5 Mb */ 218 18800, 0x82, 0x00, 2, 219 6, 6, 3, 14, 30, 14, 30, 9650 }, 220 { VALID_20, VALID_20, WLAN_RC_PHY_HT_20_SS, 26000, /* 26 Mb */ 221 25000, 0x83, 0x00, 3, 222 8, 10, 3, 15, 31, 15, 31, 12868 }, 223 { VALID_20, VALID_20, WLAN_RC_PHY_HT_20_SS, 39000, /* 39 Mb */ 224 36700, 0x84, 0x00, 4, 225 8, 14, 3, 16, 32, 16, 32, 19304 }, 226 { INVALID, VALID_20, WLAN_RC_PHY_HT_20_SS, 52000, /* 52 Mb */ 227 48100, 0x85, 0x00, 5, 228 8, 20, 3, 17, 33, 17, 33, 25740 }, 229 { INVALID, VALID_20, WLAN_RC_PHY_HT_20_SS, 58500, /* 58.5 Mb */ 230 53500, 0x86, 0x00, 6, 231 8, 23, 3, 18, 34, 18, 34, 28956 }, 232 { INVALID, VALID_20, WLAN_RC_PHY_HT_20_SS, 65000, /* 65 Mb */ 233 59000, 0x87, 0x00, 7, 234 8, 25, 3, 19, 35, 19, 36, 32180 }, 235 { INVALID, INVALID, WLAN_RC_PHY_HT_20_DS, 13000, /* 13 Mb */ 236 12700, 0x88, 0x00, 8, 237 4, 2, 3, 20, 37, 20, 37, 6430 }, 238 { INVALID, INVALID, WLAN_RC_PHY_HT_20_DS, 26000, /* 26 Mb */ 239 24800, 0x89, 0x00, 9, 240 6, 4, 3, 21, 38, 21, 38, 12860 }, 241 { INVALID, INVALID, WLAN_RC_PHY_HT_20_DS, 39000, /* 39 Mb */ 242 36600, 0x8a, 0x00, 10, 243 6, 6, 3, 22, 39, 22, 39, 19300 }, 244 { VALID_20, INVALID, WLAN_RC_PHY_HT_20_DS, 52000, /* 52 Mb */ 245 48100, 0x8b, 0x00, 11, 246 8, 10, 3, 23, 40, 23, 40, 25736 }, 247 { VALID_20, INVALID, WLAN_RC_PHY_HT_20_DS, 78000, /* 78 Mb */ 248 69500, 0x8c, 0x00, 12, 249 8, 14, 3, 24, 41, 24, 41, 38600 }, 250 { VALID_20, INVALID, WLAN_RC_PHY_HT_20_DS, 104000, /* 104 Mb */ 251 89500, 0x8d, 0x00, 13, 252 8, 20, 3, 25, 42, 25, 42, 51472 }, 253 { VALID_20, INVALID, WLAN_RC_PHY_HT_20_DS, 117000, /* 117 Mb */ 254 98900, 0x8e, 0x00, 14, 255 8, 23, 3, 26, 43, 26, 44, 57890 }, 256 { VALID_20, INVALID, WLAN_RC_PHY_HT_20_DS, 130000, /* 130 Mb */ 257 108300, 0x8f, 0x00, 15, 258 8, 25, 3, 27, 44, 27, 45, 64320 }, 259 { VALID_40, VALID_40, WLAN_RC_PHY_HT_40_SS, 13500, /* 13.5 Mb */ 260 13200, 0x80, 0x00, 0, 261 8, 2, 3, 12, 28, 28, 28, 6684 }, 262 { VALID_40, VALID_40, WLAN_RC_PHY_HT_40_SS, 27500, /* 27.0 Mb */ 263 25900, 0x81, 0x00, 1, 264 8, 4, 3, 13, 29, 29, 29, 13368 }, 265 { VALID_40, VALID_40, WLAN_RC_PHY_HT_40_SS, 40500, /* 40.5 Mb */ 266 38600, 0x82, 0x00, 2, 267 8, 6, 3, 14, 30, 30, 30, 20052 }, 268 { VALID_40, VALID_40, WLAN_RC_PHY_HT_40_SS, 54000, /* 54 Mb */ 269 49800, 0x83, 0x00, 3, 270 8, 10, 3, 15, 31, 31, 31, 26738 }, 271 { VALID_40, VALID_40, WLAN_RC_PHY_HT_40_SS, 81500, /* 81 Mb */ 272 72200, 0x84, 0x00, 4, 273 8, 14, 3, 16, 32, 32, 32, 40104 }, 274 { INVALID, VALID_40, WLAN_RC_PHY_HT_40_SS, 108000, /* 108 Mb */ 275 92900, 0x85, 0x00, 5, 276 8, 20, 3, 17, 33, 33, 33, 53476 }, 277 { INVALID, VALID_40, WLAN_RC_PHY_HT_40_SS, 278 121500, /* 121.5 Mb */ 279 102700, 0x86, 0x00, 6, 280 8, 23, 3, 18, 34, 34, 34, 60156 }, 281 { INVALID, VALID_40, WLAN_RC_PHY_HT_40_SS, 135000, /* 135 Mb */ 282 112000, 0x87, 0x00, 7, 283 8, 23, 3, 19, 35, 36, 36, 66840 }, 284 { INVALID, VALID_40, WLAN_RC_PHY_HT_40_SS_HGI, 285 150000, /* 150 Mb */ 286 122000, 0x87, 0x00, 7, 287 8, 25, 3, 19, 35, 36, 36, 74200 }, 288 { INVALID, INVALID, WLAN_RC_PHY_HT_40_DS, 27000, /* 27 Mb */ 289 25800, 0x88, 0x00, 8, 290 8, 2, 3, 20, 37, 37, 37, 13360 }, 291 { INVALID, INVALID, WLAN_RC_PHY_HT_40_DS, 54000, /* 54 Mb */ 292 49800, 0x89, 0x00, 9, 293 8, 4, 3, 21, 38, 38, 38, 26720 }, 294 { INVALID, INVALID, WLAN_RC_PHY_HT_40_DS, 81000, /* 81 Mb */ 295 71900, 0x8a, 0x00, 10, 296 8, 6, 3, 22, 39, 39, 39, 40080 }, 297 { VALID_40, INVALID, WLAN_RC_PHY_HT_40_DS, 108000, /* 108 Mb */ 298 92500, 0x8b, 0x00, 11, 299 8, 10, 3, 23, 40, 40, 40, 53440 }, 300 { VALID_40, INVALID, WLAN_RC_PHY_HT_40_DS, 162000, /* 162 Mb */ 301 130300, 0x8c, 0x00, 12, 302 8, 14, 3, 24, 41, 41, 41, 80160 }, 303 { VALID_40, INVALID, WLAN_RC_PHY_HT_40_DS, 216000, /* 216 Mb */ 304 162800, 0x8d, 0x00, 13, 305 8, 20, 3, 25, 42, 42, 42, 106880 }, 306 { VALID_40, INVALID, WLAN_RC_PHY_HT_40_DS, 243000, /* 243 Mb */ 307 178200, 0x8e, 0x00, 14, 308 8, 23, 3, 26, 43, 43, 43, 120240 }, 309 { VALID_40, INVALID, WLAN_RC_PHY_HT_40_DS, 270000, /* 270 Mb */ 310 192100, 0x8f, 0x00, 15, 311 8, 23, 3, 27, 44, 45, 45, 133600 }, 312 { VALID_40, INVALID, WLAN_RC_PHY_HT_40_DS_HGI, 313 300000, /* 300 Mb */ 314 207000, 0x8f, 0x00, 15, 315 8, 25, 3, 27, 44, 45, 45, 148400 }, 316 }, 317 50, /* probe interval */ 318 50, /* rssi reduce interval */ 319 WLAN_RC_HT_FLAG, /* Phy rates allowed initially */ 320 }; 321 322 static struct ath_rate_table ar5416_11a_ratetable = { 323 8, 324 {0}, 325 { 326 { VALID, VALID, WLAN_RC_PHY_OFDM, 6000, /* 6 Mb */ 327 5400, 0x0b, 0x00, (0x80|12), 328 0, 2, 1, 0, 0 }, 329 { VALID, VALID, WLAN_RC_PHY_OFDM, 9000, /* 9 Mb */ 330 7800, 0x0f, 0x00, 18, 331 0, 3, 1, 1, 0 }, 332 { VALID, VALID, WLAN_RC_PHY_OFDM, 12000, /* 12 Mb */ 333 10000, 0x0a, 0x00, (0x80|24), 334 2, 4, 2, 2, 0 }, 335 { VALID, VALID, WLAN_RC_PHY_OFDM, 18000, /* 18 Mb */ 336 13900, 0x0e, 0x00, 36, 337 2, 6, 2, 3, 0 }, 338 { VALID, VALID, WLAN_RC_PHY_OFDM, 24000, /* 24 Mb */ 339 17300, 0x09, 0x00, (0x80|48), 340 4, 10, 3, 4, 0 }, 341 { VALID, VALID, WLAN_RC_PHY_OFDM, 36000, /* 36 Mb */ 342 23000, 0x0d, 0x00, 72, 343 4, 14, 3, 5, 0 }, 344 { VALID, VALID, WLAN_RC_PHY_OFDM, 48000, /* 48 Mb */ 345 27400, 0x08, 0x00, 96, 346 4, 19, 3, 6, 0 }, 347 { VALID, VALID, WLAN_RC_PHY_OFDM, 54000, /* 54 Mb */ 348 29300, 0x0c, 0x00, 108, 349 4, 23, 3, 7, 0 }, 350 }, 351 50, /* probe interval */ 352 50, /* rssi reduce interval */ 353 0, /* Phy rates allowed initially */ 354 }; 355 356 static struct ath_rate_table ar5416_11g_ratetable = { 357 12, 358 {0}, 359 { 360 { VALID, VALID, WLAN_RC_PHY_CCK, 1000, /* 1 Mb */ 361 900, 0x1b, 0x00, 2, 362 0, 0, 1, 0, 0 }, 363 { VALID, VALID, WLAN_RC_PHY_CCK, 2000, /* 2 Mb */ 364 1900, 0x1a, 0x04, 4, 365 1, 1, 1, 1, 0 }, 366 { VALID, VALID, WLAN_RC_PHY_CCK, 5500, /* 5.5 Mb */ 367 4900, 0x19, 0x04, 11, 368 2, 2, 2, 2, 0 }, 369 { VALID, VALID, WLAN_RC_PHY_CCK, 11000, /* 11 Mb */ 370 8100, 0x18, 0x04, 22, 371 3, 3, 2, 3, 0 }, 372 { INVALID, INVALID, WLAN_RC_PHY_OFDM, 6000, /* 6 Mb */ 373 5400, 0x0b, 0x00, 12, 374 4, 2, 1, 4, 0 }, 375 { INVALID, INVALID, WLAN_RC_PHY_OFDM, 9000, /* 9 Mb */ 376 7800, 0x0f, 0x00, 18, 377 4, 3, 1, 5, 0 }, 378 { VALID, VALID, WLAN_RC_PHY_OFDM, 12000, /* 12 Mb */ 379 10000, 0x0a, 0x00, 24, 380 6, 4, 1, 6, 0 }, 381 { VALID, VALID, WLAN_RC_PHY_OFDM, 18000, /* 18 Mb */ 382 13900, 0x0e, 0x00, 36, 383 6, 6, 2, 7, 0 }, 384 { VALID, VALID, WLAN_RC_PHY_OFDM, 24000, /* 24 Mb */ 385 17300, 0x09, 0x00, 48, 386 8, 10, 3, 8, 0 }, 387 { VALID, VALID, WLAN_RC_PHY_OFDM, 36000, /* 36 Mb */ 388 23000, 0x0d, 0x00, 72, 389 8, 14, 3, 9, 0 }, 390 { VALID, VALID, WLAN_RC_PHY_OFDM, 48000, /* 48 Mb */ 391 27400, 0x08, 0x00, 96, 392 8, 19, 3, 10, 0 }, 393 { VALID, VALID, WLAN_RC_PHY_OFDM, 54000, /* 54 Mb */ 394 29300, 0x0c, 0x00, 108, 395 8, 23, 3, 11, 0 }, 396 }, 397 50, /* probe interval */ 398 50, /* rssi reduce interval */ 399 0, /* Phy rates allowed initially */ 400 }; 401 402 static struct ath_rate_table ar5416_11b_ratetable = { 403 4, 404 {0}, 405 { 406 { VALID, VALID, WLAN_RC_PHY_CCK, 1000, /* 1 Mb */ 407 900, 0x1b, 0x00, (0x80|2), 408 0, 0, 1, 0, 0 }, 409 { VALID, VALID, WLAN_RC_PHY_CCK, 2000, /* 2 Mb */ 410 1800, 0x1a, 0x04, (0x80|4), 411 1, 1, 1, 1, 0 }, 412 { VALID, VALID, WLAN_RC_PHY_CCK, 5500, /* 5.5 Mb */ 413 4300, 0x19, 0x04, (0x80|11), 414 1, 2, 2, 2, 0 }, 415 { VALID, VALID, WLAN_RC_PHY_CCK, 11000, /* 11 Mb */ 416 7100, 0x18, 0x04, (0x80|22), 417 1, 4, 100, 3, 0 }, 418 }, 419 100, /* probe interval */ 420 100, /* rssi reduce interval */ 421 0, /* Phy rates allowed initially */ 422 }; 423 424 static void 425 arn_setup_rate_table(struct arn_softc *sc, 426 struct ath_rate_table *rate_table) 427 { 428 int i; 429 430 for (i = 0; i < 256; i++) 431 rate_table->rateCodeToIndex[i] = (uint8_t)-1; 432 433 for (i = 0; i < rate_table->rate_cnt; i++) { 434 uint8_t code = rate_table->info[i].ratecode; 435 uint8_t cix = rate_table->info[i].ctrl_rate; 436 uint8_t sh = rate_table->info[i].short_preamble; 437 438 rate_table->rateCodeToIndex[code] = (int)i; 439 rate_table->rateCodeToIndex[code | sh] = (int)i; 440 441 rate_table->info[i].lpAckDuration = 442 ath9k_hw_computetxtime(sc->sc_ah, rate_table, 443 WLAN_CTRL_FRAME_SIZE, 444 cix, 445 B_FALSE); 446 rate_table->info[i].spAckDuration = 447 ath9k_hw_computetxtime(sc->sc_ah, rate_table, 448 WLAN_CTRL_FRAME_SIZE, 449 cix, 450 B_TRUE); 451 } 452 } 453 454 void 455 arn_rate_attach(struct arn_softc *sc) 456 { 457 sc->hw_rate_table[ATH9K_MODE_11B] = 458 &ar5416_11b_ratetable; 459 sc->hw_rate_table[ATH9K_MODE_11A] = 460 &ar5416_11a_ratetable; 461 sc->hw_rate_table[ATH9K_MODE_11G] = 462 &ar5416_11g_ratetable; 463 sc->hw_rate_table[ATH9K_MODE_11NA_HT20] = 464 &ar5416_11na_ratetable; 465 sc->hw_rate_table[ATH9K_MODE_11NG_HT20] = 466 &ar5416_11ng_ratetable; 467 sc->hw_rate_table[ATH9K_MODE_11NA_HT40PLUS] = 468 &ar5416_11na_ratetable; 469 sc->hw_rate_table[ATH9K_MODE_11NA_HT40MINUS] = 470 &ar5416_11na_ratetable; 471 sc->hw_rate_table[ATH9K_MODE_11NG_HT40PLUS] = 472 &ar5416_11ng_ratetable; 473 sc->hw_rate_table[ATH9K_MODE_11NG_HT40MINUS] = 474 &ar5416_11ng_ratetable; 475 476 arn_setup_rate_table(sc, &ar5416_11b_ratetable); 477 arn_setup_rate_table(sc, &ar5416_11a_ratetable); 478 arn_setup_rate_table(sc, &ar5416_11g_ratetable); 479 arn_setup_rate_table(sc, &ar5416_11na_ratetable); 480 arn_setup_rate_table(sc, &ar5416_11ng_ratetable); 481 } 482 483 void 484 arn_rate_update(struct arn_softc *sc, struct ieee80211_node *in, int32_t rate) 485 { 486 struct ath_node *an = ATH_NODE(in); 487 const struct ath_rate_table *rt = sc->sc_currates; 488 uint8_t rix; 489 490 ASSERT(rt != NULL); 491 492 in->in_txrate = rate; 493 494 /* management/control frames always go at the lowest speed */ 495 an->an_tx_mgtrate = rt->info[0].ratecode; 496 an->an_tx_mgtratesp = an->an_tx_mgtrate | rt->info[0].short_preamble; 497 498 ARN_DBG((ARN_DBG_RATE, "arn: arn_rate_update(): " 499 "mgtrate=%d mgtratesp=%d\n", 500 an->an_tx_mgtrate, an->an_tx_mgtratesp)); 501 502 /* 503 * Before associating a node has no rate set setup 504 * so we can't calculate any transmit codes to use. 505 * This is ok since we should never be sending anything 506 * but management frames and those always go at the 507 * lowest hardware rate. 508 */ 509 if (in->in_rates.ir_nrates == 0) 510 goto done; 511 an->an_tx_rix0 = sc->asc_rixmap[ 512 in->in_rates.ir_rates[rate] & IEEE80211_RATE_VAL]; 513 an->an_tx_rate0 = rt->info[an->an_tx_rix0].ratecode; 514 an->an_tx_rate0sp = an->an_tx_rate0 | 515 rt->info[an->an_tx_rix0].short_preamble; 516 if (sc->sc_mrretry) { 517 /* 518 * Hardware supports multi-rate retry; setup two 519 * step-down retry rates and make the lowest rate 520 * be the ``last chance''. We use 4, 2, 2, 2 tries 521 * respectively (4 is set here, the rest are fixed 522 * in the xmit routine). 523 */ 524 an->an_tx_try0 = 1 + 3; /* 4 tries at rate 0 */ 525 if (--rate >= 0) { 526 rix = sc->asc_rixmap[ 527 in->in_rates.ir_rates[rate]&IEEE80211_RATE_VAL]; 528 an->an_tx_rate1 = rt->info[rix].ratecode; 529 an->an_tx_rate1sp = an->an_tx_rate1 | 530 rt->info[rix].short_preamble; 531 } else { 532 an->an_tx_rate1 = an->an_tx_rate1sp = 0; 533 } 534 if (--rate >= 0) { 535 rix = sc->asc_rixmap[ 536 in->in_rates.ir_rates[rate]&IEEE80211_RATE_VAL]; 537 an->an_tx_rate2 = rt->info[rix].ratecode; 538 an->an_tx_rate2sp = an->an_tx_rate2 | 539 rt->info[rix].short_preamble; 540 } else { 541 an->an_tx_rate2 = an->an_tx_rate2sp = 0; 542 } 543 if (rate > 0) { 544 an->an_tx_rate3 = rt->info[0].ratecode; 545 an->an_tx_rate3sp = 546 an->an_tx_mgtrate | rt->info[0].short_preamble; 547 } else { 548 an->an_tx_rate3 = an->an_tx_rate3sp = 0; 549 } 550 } else { 551 an->an_tx_try0 = ATH_TXMAXTRY; /* max tries at rate 0 */ 552 an->an_tx_rate1 = an->an_tx_rate1sp = 0; 553 an->an_tx_rate2 = an->an_tx_rate2sp = 0; 554 an->an_tx_rate3 = an->an_tx_rate3sp = 0; 555 } 556 done: 557 an->an_tx_ok = an->an_tx_err = an->an_tx_retr = an->an_tx_upper = 0; 558 } 559 560 /* 561 * Set the starting transmit rate for a node. 562 */ 563 void 564 arn_rate_ctl_start(struct arn_softc *sc, struct ieee80211_node *in) 565 { 566 ieee80211com_t *ic = (ieee80211com_t *)sc; 567 int32_t srate; 568 569 if (ic->ic_fixed_rate == IEEE80211_FIXED_RATE_NONE) { 570 /* 571 * No fixed rate is requested. For 11b start with 572 * the highest negotiated rate; otherwise, for 11g 573 * and 11a, we start "in the middle" at 24Mb or 36Mb. 574 */ 575 srate = in->in_rates.ir_nrates - 1; 576 if (sc->sc_curmode != IEEE80211_MODE_11B) { 577 /* 578 * Scan the negotiated rate set to find the 579 * closest rate. 580 */ 581 /* NB: the rate set is assumed sorted */ 582 for (; srate >= 0 && IEEE80211_RATE(srate) > 72; 583 srate--) {} 584 } 585 } else { 586 /* 587 * A fixed rate is to be used; We know the rate is 588 * there because the rate set is checked when the 589 * station associates. 590 */ 591 /* NB: the rate set is assumed sorted */ 592 srate = in->in_rates.ir_nrates - 1; 593 for (; srate >= 0 && IEEE80211_RATE(srate) != ic->ic_fixed_rate; 594 srate--) {} 595 } 596 597 ARN_DBG((ARN_DBG_RATE, "arn: arn_rate_ctl_start(): " 598 "srate=%d rate=%d\n", srate, IEEE80211_RATE(srate))); 599 600 arn_rate_update(sc, in, srate); 601 } 602 603 void 604 arn_rate_cb(void *arg, struct ieee80211_node *in) 605 { 606 arn_rate_update((struct arn_softc *)arg, in, 0); 607 } 608 609 /* 610 * Reset the rate control state for each 802.11 state transition. 611 */ 612 void 613 arn_rate_ctl_reset(struct arn_softc *sc, enum ieee80211_state state) 614 { 615 ieee80211com_t *ic = (ieee80211com_t *)sc; 616 struct ieee80211_node *in; 617 618 if (ic->ic_opmode == IEEE80211_M_STA) { 619 /* 620 * Reset local xmit state; this is really only 621 * meaningful when operating in station mode. 622 */ 623 in = (struct ieee80211_node *)ic->ic_bss; 624 if (state == IEEE80211_S_RUN) { 625 arn_rate_ctl_start(sc, in); 626 } else { 627 arn_rate_update(sc, in, 0); 628 } 629 } else { 630 /* 631 * When operating as a station the node table holds 632 * the AP's that were discovered during scanning. 633 * For any other operating mode we want to reset the 634 * tx rate state of each node. 635 */ 636 ieee80211_iterate_nodes(&ic->ic_sta, arn_rate_cb, sc); 637 arn_rate_update(sc, ic->ic_bss, 0); 638 } 639 } 640 641 /* 642 * Examine and potentially adjust the transmit rate. 643 */ 644 void 645 arn_rate_ctl(void *arg, struct ieee80211_node *in) 646 { 647 struct arn_softc *sc = arg; 648 struct ath_node *an = ATH_NODE(in); 649 struct ieee80211_rateset *rs = &in->in_rates; 650 int32_t mod = 0, nrate, enough; 651 652 /* 653 * Rate control(very primitive version). 654 */ 655 sc->sc_stats.ast_rate_calls++; 656 657 enough = (an->an_tx_ok + an->an_tx_err >= 10); 658 659 /* no packet reached -> down */ 660 if (an->an_tx_err > 0 && an->an_tx_ok == 0) 661 mod = -1; 662 663 /* all packets needs retry in average -> down */ 664 if (enough && an->an_tx_ok < an->an_tx_retr) 665 mod = -1; 666 667 /* no error and less than 10% of packets needs retry -> up */ 668 if (enough && an->an_tx_err == 0 && an->an_tx_ok > an->an_tx_retr * 10) 669 mod = 1; 670 671 nrate = in->in_txrate; 672 switch (mod) { 673 case 0: 674 if (enough && an->an_tx_upper > 0) 675 an->an_tx_upper--; 676 break; 677 case -1: 678 if (nrate > 0) { 679 nrate--; 680 sc->sc_stats.ast_rate_drop++; 681 } 682 an->an_tx_upper = 0; 683 break; 684 case 1: 685 if (++an->an_tx_upper < 10) 686 break; 687 an->an_tx_upper = 0; 688 if (nrate + 1 < rs->ir_nrates) { 689 nrate++; 690 sc->sc_stats.ast_rate_raise++; 691 } 692 break; 693 } 694 695 if (nrate != in->in_txrate) { 696 ARN_DBG((ARN_DBG_RATE, "arn: arn_rate_ctl(): %dM -> %dM " 697 "(%d ok, %d err, %d retr)\n", 698 (rs->ir_rates[in->in_txrate] & IEEE80211_RATE_VAL) / 2, 699 (rs->ir_rates[nrate] & IEEE80211_RATE_VAL) / 2, 700 an->an_tx_ok, an->an_tx_err, an->an_tx_retr)); 701 arn_rate_update(sc, in, nrate); 702 } else if (enough) 703 an->an_tx_ok = an->an_tx_err = an->an_tx_retr = 0; 704 } 705