1 /* 2 * Copyright 2010 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 #include <sys/net80211_ht.h> 26 27 #include "arn_core.h" 28 #include "arn_hw.h" 29 #include "arn_reg.h" 30 31 static struct ath_rate_table ar5416_11na_ratetable = { 32 42, 33 {0}, 34 { 35 { VALID, VALID, WLAN_RC_PHY_OFDM, 6000, /* 6 Mb */ 36 5400, 0x0b, 0x00, 12, 37 0, 2, 1, 0, 0, 0, 0, 0 }, 38 { VALID, VALID, WLAN_RC_PHY_OFDM, 9000, /* 9 Mb */ 39 7800, 0x0f, 0x00, 18, 40 0, 3, 1, 1, 1, 1, 1, 0 }, 41 { VALID, VALID, WLAN_RC_PHY_OFDM, 12000, /* 12 Mb */ 42 10000, 0x0a, 0x00, 24, 43 2, 4, 2, 2, 2, 2, 2, 0 }, 44 { VALID, VALID, WLAN_RC_PHY_OFDM, 18000, /* 18 Mb */ 45 13900, 0x0e, 0x00, 36, 46 2, 6, 2, 3, 3, 3, 3, 0 }, 47 { VALID, VALID, WLAN_RC_PHY_OFDM, 24000, /* 24 Mb */ 48 17300, 0x09, 0x00, 48, 49 4, 10, 3, 4, 4, 4, 4, 0 }, 50 { VALID, VALID, WLAN_RC_PHY_OFDM, 36000, /* 36 Mb */ 51 23000, 0x0d, 0x00, 72, 52 4, 14, 3, 5, 5, 5, 5, 0 }, 53 { VALID, VALID, WLAN_RC_PHY_OFDM, 48000, /* 48 Mb */ 54 27400, 0x08, 0x00, 96, 55 4, 20, 3, 6, 6, 6, 6, 0 }, 56 { VALID, VALID, WLAN_RC_PHY_OFDM, 54000, /* 54 Mb */ 57 29300, 0x0c, 0x00, 108, 58 4, 23, 3, 7, 7, 7, 7, 0 }, 59 { VALID_20, VALID_20, WLAN_RC_PHY_HT_20_SS, 6500, /* 6.5 Mb */ 60 6400, 0x80, 0x00, 0, 61 0, 2, 3, 8, 24, 8, 24, 3216 }, 62 { VALID_20, VALID_20, WLAN_RC_PHY_HT_20_SS, 13000, /* 13 Mb */ 63 12700, 0x81, 0x00, 1, 64 2, 4, 3, 9, 25, 9, 25, 6434 }, 65 { VALID_20, VALID_20, WLAN_RC_PHY_HT_20_SS, 19500, /* 19.5 Mb */ 66 18800, 0x82, 0x00, 2, 67 2, 6, 3, 10, 26, 10, 26, 9650 }, 68 { VALID_20, VALID_20, WLAN_RC_PHY_HT_20_SS, 26000, /* 26 Mb */ 69 25000, 0x83, 0x00, 3, 70 4, 10, 3, 11, 27, 11, 27, 12868 }, 71 { VALID_20, VALID_20, WLAN_RC_PHY_HT_20_SS, 39000, /* 39 Mb */ 72 36700, 0x84, 0x00, 4, 73 4, 14, 3, 12, 28, 12, 28, 19304 }, 74 { INVALID, VALID_20, WLAN_RC_PHY_HT_20_SS, 52000, /* 52 Mb */ 75 48100, 0x85, 0x00, 5, 76 4, 20, 3, 13, 29, 13, 29, 25740 }, 77 { INVALID, VALID_20, WLAN_RC_PHY_HT_20_SS, 58500, /* 58.5 Mb */ 78 53500, 0x86, 0x00, 6, 79 4, 23, 3, 14, 30, 14, 30, 28956 }, 80 { INVALID, VALID_20, WLAN_RC_PHY_HT_20_SS, 65000, /* 65 Mb */ 81 59000, 0x87, 0x00, 7, 82 4, 25, 3, 15, 31, 15, 32, 32180 }, 83 { INVALID, INVALID, WLAN_RC_PHY_HT_20_DS, 13000, /* 13 Mb */ 84 12700, 0x88, 0x00, 85 8, 0, 2, 3, 16, 33, 16, 33, 6430 }, 86 { INVALID, INVALID, WLAN_RC_PHY_HT_20_DS, 26000, /* 26 Mb */ 87 24800, 0x89, 0x00, 9, 88 2, 4, 3, 17, 34, 17, 34, 12860 }, 89 { INVALID, INVALID, WLAN_RC_PHY_HT_20_DS, 39000, /* 39 Mb */ 90 36600, 0x8a, 0x00, 10, 91 2, 6, 3, 18, 35, 18, 35, 19300 }, 92 { VALID_20, INVALID, WLAN_RC_PHY_HT_20_DS, 52000, /* 52 Mb */ 93 48100, 0x8b, 0x00, 11, 94 4, 10, 3, 19, 36, 19, 36, 25736 }, 95 { VALID_20, INVALID, WLAN_RC_PHY_HT_20_DS, 78000, /* 78 Mb */ 96 69500, 0x8c, 0x00, 12, 97 4, 14, 3, 20, 37, 20, 37, 38600 }, 98 { VALID_20, INVALID, WLAN_RC_PHY_HT_20_DS, 104000, /* 104 Mb */ 99 89500, 0x8d, 0x00, 13, 100 4, 20, 3, 21, 38, 21, 38, 51472 }, 101 { VALID_20, INVALID, WLAN_RC_PHY_HT_20_DS, 117000, /* 117 Mb */ 102 98900, 0x8e, 0x00, 14, 103 4, 23, 3, 22, 39, 22, 39, 57890 }, 104 { VALID_20, INVALID, WLAN_RC_PHY_HT_20_DS, 130000, /* 130 Mb */ 105 108300, 0x8f, 0x00, 15, 106 4, 25, 3, 23, 40, 23, 41, 64320 }, 107 { VALID_40, VALID_40, WLAN_RC_PHY_HT_40_SS, 13500, /* 13.5 Mb */ 108 13200, 0x80, 0x00, 0, 109 0, 2, 3, 8, 24, 24, 24, 6684 }, 110 { VALID_40, VALID_40, WLAN_RC_PHY_HT_40_SS, 27500, /* 27.0 Mb */ 111 25900, 0x81, 0x00, 1, 112 2, 4, 3, 9, 25, 25, 25, 13368 }, 113 { VALID_40, VALID_40, WLAN_RC_PHY_HT_40_SS, 40500, /* 40.5 Mb */ 114 38600, 0x82, 0x00, 2, 115 2, 6, 3, 10, 26, 26, 26, 20052 }, 116 { VALID_40, VALID_40, WLAN_RC_PHY_HT_40_SS, 54000, /* 54 Mb */ 117 49800, 0x83, 0x00, 3, 118 4, 10, 3, 11, 27, 27, 27, 26738 }, 119 { VALID_40, VALID_40, WLAN_RC_PHY_HT_40_SS, 81500, /* 81 Mb */ 120 72200, 0x84, 0x00, 4, 121 4, 14, 3, 12, 28, 28, 28, 40104 }, 122 { INVALID, VALID_40, WLAN_RC_PHY_HT_40_SS, 108000, /* 108 Mb */ 123 92900, 0x85, 0x00, 5, 124 4, 20, 3, 13, 29, 29, 29, 53476 }, 125 { INVALID, VALID_40, WLAN_RC_PHY_HT_40_SS, 121500, /* 121.5Mb */ 126 102700, 0x86, 0x00, 6, 127 4, 23, 3, 14, 30, 30, 30, 60156 }, 128 { INVALID, VALID_40, WLAN_RC_PHY_HT_40_SS, 135000, /* 135 Mb */ 129 112000, 0x87, 0x00, 7, 130 4, 25, 3, 15, 31, 32, 32, 66840 }, 131 { INVALID, VALID_40, WLAN_RC_PHY_HT_40_SS_HGI, 132 150000, /* 150Mb */ 133 122000, 0x87, 0x00, 7, 134 4, 25, 3, 15, 31, 32, 32, 74200 }, 135 { INVALID, INVALID, WLAN_RC_PHY_HT_40_DS, 27000, /* 27 Mb */ 136 25800, 0x88, 0x00, 8, 137 0, 2, 3, 16, 33, 33, 33, 13360 }, 138 { INVALID, INVALID, WLAN_RC_PHY_HT_40_DS, 54000, /* 54 Mb */ 139 49800, 0x89, 0x00, 9, 140 2, 4, 3, 17, 34, 34, 34, 26720 }, 141 { INVALID, INVALID, WLAN_RC_PHY_HT_40_DS, 81000, /* 81 Mb */ 142 71900, 0x8a, 0x00, 10, 143 2, 6, 3, 18, 35, 35, 35, 40080 }, 144 { VALID_40, INVALID, WLAN_RC_PHY_HT_40_DS, 108000, /* 108 Mb */ 145 92500, 0x8b, 0x00, 11, 146 4, 10, 3, 19, 36, 36, 36, 53440 }, 147 { VALID_40, INVALID, WLAN_RC_PHY_HT_40_DS, 162000, /* 162 Mb */ 148 130300, 0x8c, 0x00, 12, 149 4, 14, 3, 20, 37, 37, 37, 80160 }, 150 { VALID_40, INVALID, WLAN_RC_PHY_HT_40_DS, 216000, /* 216 Mb */ 151 162800, 0x8d, 0x00, 13, 152 4, 20, 3, 21, 38, 38, 38, 106880 }, 153 { VALID_40, INVALID, WLAN_RC_PHY_HT_40_DS, 243000, /* 243 Mb */ 154 178200, 0x8e, 0x00, 14, 155 4, 23, 3, 22, 39, 39, 39, 120240 }, 156 { VALID_40, INVALID, WLAN_RC_PHY_HT_40_DS, 270000, /* 270 Mb */ 157 192100, 0x8f, 0x00, 15, 158 4, 25, 3, 23, 40, 41, 41, 133600 }, 159 { VALID_40, INVALID, WLAN_RC_PHY_HT_40_DS_HGI, 160 300000, /* 300 Mb */ 161 207000, 0x8f, 0x00, 15, 162 4, 25, 3, 23, 40, 41, 41, 148400 }, 163 }, 164 50, /* probe interval */ 165 50, /* rssi reduce interval */ 166 WLAN_RC_HT_FLAG, /* Phy rates allowed initially */ 167 }; 168 169 /* 170 * 4ms frame limit not used for NG mode. The values filled 171 * for HT are the 64K max aggregate limit 172 */ 173 174 static struct ath_rate_table ar5416_11ng_ratetable = { 175 46, 176 {0}, 177 { 178 { VALID_ALL, VALID_ALL, WLAN_RC_PHY_CCK, 1000, /* 1 Mb */ 179 900, 0x1b, 0x00, 2, 180 0, 0, 1, 0, 0, 0, 0, 0 }, 181 { VALID_ALL, VALID_ALL, WLAN_RC_PHY_CCK, 2000, /* 2 Mb */ 182 1900, 0x1a, 0x04, 4, 183 1, 1, 1, 1, 1, 1, 1, 0 }, 184 { VALID_ALL, VALID_ALL, WLAN_RC_PHY_CCK, 5500, /* 5.5 Mb */ 185 4900, 0x19, 0x04, 11, 186 2, 2, 2, 2, 2, 2, 2, 0 }, 187 { VALID_ALL, VALID_ALL, WLAN_RC_PHY_CCK, 11000, /* 11 Mb */ 188 8100, 0x18, 0x04, 22, 189 3, 3, 2, 3, 3, 3, 3, 0 }, 190 { INVALID, INVALID, WLAN_RC_PHY_OFDM, 6000, /* 6 Mb */ 191 5400, 0x0b, 0x00, 12, 192 4, 2, 1, 4, 4, 4, 4, 0 }, 193 { INVALID, INVALID, WLAN_RC_PHY_OFDM, 9000, /* 9 Mb */ 194 7800, 0x0f, 0x00, 18, 195 4, 3, 1, 5, 5, 5, 5, 0 }, 196 { VALID, VALID, WLAN_RC_PHY_OFDM, 12000, /* 12 Mb */ 197 10100, 0x0a, 0x00, 24, 198 6, 4, 1, 6, 6, 6, 6, 0 }, 199 { VALID, VALID, WLAN_RC_PHY_OFDM, 18000, /* 18 Mb */ 200 14100, 0x0e, 0x00, 36, 201 6, 6, 2, 7, 7, 7, 7, 0 }, 202 { VALID, VALID, WLAN_RC_PHY_OFDM, 24000, /* 24 Mb */ 203 17700, 0x09, 0x00, 48, 204 8, 10, 3, 8, 8, 8, 8, 0 }, 205 { VALID, VALID, WLAN_RC_PHY_OFDM, 36000, /* 36 Mb */ 206 23700, 0x0d, 0x00, 72, 207 8, 14, 3, 9, 9, 9, 9, 0 }, 208 { VALID, VALID, WLAN_RC_PHY_OFDM, 48000, /* 48 Mb */ 209 27400, 0x08, 0x00, 96, 210 8, 20, 3, 10, 10, 10, 10, 0 }, 211 { VALID, VALID, WLAN_RC_PHY_OFDM, 54000, /* 54 Mb */ 212 30900, 0x0c, 0x00, 108, 213 8, 23, 3, 11, 11, 11, 11, 0 }, 214 { INVALID, INVALID, WLAN_RC_PHY_HT_20_SS, 6500, /* 6.5 Mb */ 215 6400, 0x80, 0x00, 0, 216 4, 2, 3, 12, 28, 12, 28, 3216 }, 217 { VALID_20, VALID_20, WLAN_RC_PHY_HT_20_SS, 13000, /* 13 Mb */ 218 12700, 0x81, 0x00, 1, 219 6, 4, 3, 13, 29, 13, 29, 6434 }, 220 { VALID_20, VALID_20, WLAN_RC_PHY_HT_20_SS, 19500, /* 19.5 Mb */ 221 18800, 0x82, 0x00, 2, 222 6, 6, 3, 14, 30, 14, 30, 9650 }, 223 { VALID_20, VALID_20, WLAN_RC_PHY_HT_20_SS, 26000, /* 26 Mb */ 224 25000, 0x83, 0x00, 3, 225 8, 10, 3, 15, 31, 15, 31, 12868 }, 226 { VALID_20, VALID_20, WLAN_RC_PHY_HT_20_SS, 39000, /* 39 Mb */ 227 36700, 0x84, 0x00, 4, 228 8, 14, 3, 16, 32, 16, 32, 19304 }, 229 { INVALID, VALID_20, WLAN_RC_PHY_HT_20_SS, 52000, /* 52 Mb */ 230 48100, 0x85, 0x00, 5, 231 8, 20, 3, 17, 33, 17, 33, 25740 }, 232 { INVALID, VALID_20, WLAN_RC_PHY_HT_20_SS, 58500, /* 58.5 Mb */ 233 53500, 0x86, 0x00, 6, 234 8, 23, 3, 18, 34, 18, 34, 28956 }, 235 { INVALID, VALID_20, WLAN_RC_PHY_HT_20_SS, 65000, /* 65 Mb */ 236 59000, 0x87, 0x00, 7, 237 8, 25, 3, 19, 35, 19, 36, 32180 }, 238 { INVALID, INVALID, WLAN_RC_PHY_HT_20_DS, 13000, /* 13 Mb */ 239 12700, 0x88, 0x00, 8, 240 4, 2, 3, 20, 37, 20, 37, 6430 }, 241 { INVALID, INVALID, WLAN_RC_PHY_HT_20_DS, 26000, /* 26 Mb */ 242 24800, 0x89, 0x00, 9, 243 6, 4, 3, 21, 38, 21, 38, 12860 }, 244 { INVALID, INVALID, WLAN_RC_PHY_HT_20_DS, 39000, /* 39 Mb */ 245 36600, 0x8a, 0x00, 10, 246 6, 6, 3, 22, 39, 22, 39, 19300 }, 247 { VALID_20, INVALID, WLAN_RC_PHY_HT_20_DS, 52000, /* 52 Mb */ 248 48100, 0x8b, 0x00, 11, 249 8, 10, 3, 23, 40, 23, 40, 25736 }, 250 { VALID_20, INVALID, WLAN_RC_PHY_HT_20_DS, 78000, /* 78 Mb */ 251 69500, 0x8c, 0x00, 12, 252 8, 14, 3, 24, 41, 24, 41, 38600 }, 253 { VALID_20, INVALID, WLAN_RC_PHY_HT_20_DS, 104000, /* 104 Mb */ 254 89500, 0x8d, 0x00, 13, 255 8, 20, 3, 25, 42, 25, 42, 51472 }, 256 { VALID_20, INVALID, WLAN_RC_PHY_HT_20_DS, 117000, /* 117 Mb */ 257 98900, 0x8e, 0x00, 14, 258 8, 23, 3, 26, 43, 26, 44, 57890 }, 259 { VALID_20, INVALID, WLAN_RC_PHY_HT_20_DS, 130000, /* 130 Mb */ 260 108300, 0x8f, 0x00, 15, 261 8, 25, 3, 27, 44, 27, 45, 64320 }, 262 { VALID_40, VALID_40, WLAN_RC_PHY_HT_40_SS, 13500, /* 13.5 Mb */ 263 13200, 0x80, 0x00, 0, 264 8, 2, 3, 12, 28, 28, 28, 6684 }, 265 { VALID_40, VALID_40, WLAN_RC_PHY_HT_40_SS, 27500, /* 27.0 Mb */ 266 25900, 0x81, 0x00, 1, 267 8, 4, 3, 13, 29, 29, 29, 13368 }, 268 { VALID_40, VALID_40, WLAN_RC_PHY_HT_40_SS, 40500, /* 40.5 Mb */ 269 38600, 0x82, 0x00, 2, 270 8, 6, 3, 14, 30, 30, 30, 20052 }, 271 { VALID_40, VALID_40, WLAN_RC_PHY_HT_40_SS, 54000, /* 54 Mb */ 272 49800, 0x83, 0x00, 3, 273 8, 10, 3, 15, 31, 31, 31, 26738 }, 274 { VALID_40, VALID_40, WLAN_RC_PHY_HT_40_SS, 81500, /* 81 Mb */ 275 72200, 0x84, 0x00, 4, 276 8, 14, 3, 16, 32, 32, 32, 40104 }, 277 { INVALID, VALID_40, WLAN_RC_PHY_HT_40_SS, 108000, /* 108 Mb */ 278 92900, 0x85, 0x00, 5, 279 8, 20, 3, 17, 33, 33, 33, 53476 }, 280 { INVALID, VALID_40, WLAN_RC_PHY_HT_40_SS, 281 121500, /* 121.5 Mb */ 282 102700, 0x86, 0x00, 6, 283 8, 23, 3, 18, 34, 34, 34, 60156 }, 284 { INVALID, VALID_40, WLAN_RC_PHY_HT_40_SS, 135000, /* 135 Mb */ 285 112000, 0x87, 0x00, 7, 286 8, 23, 3, 19, 35, 36, 36, 66840 }, 287 { INVALID, VALID_40, WLAN_RC_PHY_HT_40_SS_HGI, 288 150000, /* 150 Mb */ 289 122000, 0x87, 0x00, 7, 290 8, 25, 3, 19, 35, 36, 36, 74200 }, 291 { INVALID, INVALID, WLAN_RC_PHY_HT_40_DS, 27000, /* 27 Mb */ 292 25800, 0x88, 0x00, 8, 293 8, 2, 3, 20, 37, 37, 37, 13360 }, 294 { INVALID, INVALID, WLAN_RC_PHY_HT_40_DS, 54000, /* 54 Mb */ 295 49800, 0x89, 0x00, 9, 296 8, 4, 3, 21, 38, 38, 38, 26720 }, 297 { INVALID, INVALID, WLAN_RC_PHY_HT_40_DS, 81000, /* 81 Mb */ 298 71900, 0x8a, 0x00, 10, 299 8, 6, 3, 22, 39, 39, 39, 40080 }, 300 { VALID_40, INVALID, WLAN_RC_PHY_HT_40_DS, 108000, /* 108 Mb */ 301 92500, 0x8b, 0x00, 11, 302 8, 10, 3, 23, 40, 40, 40, 53440 }, 303 { VALID_40, INVALID, WLAN_RC_PHY_HT_40_DS, 162000, /* 162 Mb */ 304 130300, 0x8c, 0x00, 12, 305 8, 14, 3, 24, 41, 41, 41, 80160 }, 306 { VALID_40, INVALID, WLAN_RC_PHY_HT_40_DS, 216000, /* 216 Mb */ 307 162800, 0x8d, 0x00, 13, 308 8, 20, 3, 25, 42, 42, 42, 106880 }, 309 { VALID_40, INVALID, WLAN_RC_PHY_HT_40_DS, 243000, /* 243 Mb */ 310 178200, 0x8e, 0x00, 14, 311 8, 23, 3, 26, 43, 43, 43, 120240 }, 312 { VALID_40, INVALID, WLAN_RC_PHY_HT_40_DS, 270000, /* 270 Mb */ 313 192100, 0x8f, 0x00, 15, 314 8, 23, 3, 27, 44, 45, 45, 133600 }, 315 { VALID_40, INVALID, WLAN_RC_PHY_HT_40_DS_HGI, 316 300000, /* 300 Mb */ 317 207000, 0x8f, 0x00, 15, 318 8, 25, 3, 27, 44, 45, 45, 148400 }, 319 }, 320 50, /* probe interval */ 321 50, /* rssi reduce interval */ 322 WLAN_RC_HT_FLAG, /* Phy rates allowed initially */ 323 }; 324 325 static struct ath_rate_table ar5416_11a_ratetable = { 326 8, 327 {0}, 328 { 329 { VALID, VALID, WLAN_RC_PHY_OFDM, 6000, /* 6 Mb */ 330 5400, 0x0b, 0x00, (0x80|12), 331 0, 2, 1, 0, 0 }, 332 { VALID, VALID, WLAN_RC_PHY_OFDM, 9000, /* 9 Mb */ 333 7800, 0x0f, 0x00, 18, 334 0, 3, 1, 1, 0 }, 335 { VALID, VALID, WLAN_RC_PHY_OFDM, 12000, /* 12 Mb */ 336 10000, 0x0a, 0x00, (0x80|24), 337 2, 4, 2, 2, 0 }, 338 { VALID, VALID, WLAN_RC_PHY_OFDM, 18000, /* 18 Mb */ 339 13900, 0x0e, 0x00, 36, 340 2, 6, 2, 3, 0 }, 341 { VALID, VALID, WLAN_RC_PHY_OFDM, 24000, /* 24 Mb */ 342 17300, 0x09, 0x00, (0x80|48), 343 4, 10, 3, 4, 0 }, 344 { VALID, VALID, WLAN_RC_PHY_OFDM, 36000, /* 36 Mb */ 345 23000, 0x0d, 0x00, 72, 346 4, 14, 3, 5, 0 }, 347 { VALID, VALID, WLAN_RC_PHY_OFDM, 48000, /* 48 Mb */ 348 27400, 0x08, 0x00, 96, 349 4, 19, 3, 6, 0 }, 350 { VALID, VALID, WLAN_RC_PHY_OFDM, 54000, /* 54 Mb */ 351 29300, 0x0c, 0x00, 108, 352 4, 23, 3, 7, 0 }, 353 }, 354 50, /* probe interval */ 355 50, /* rssi reduce interval */ 356 0, /* Phy rates allowed initially */ 357 }; 358 359 static struct ath_rate_table ar5416_11g_ratetable = { 360 12, 361 {0}, 362 { 363 { VALID, VALID, WLAN_RC_PHY_CCK, 1000, /* 1 Mb */ 364 900, 0x1b, 0x00, 2, 365 0, 0, 1, 0, 0 }, 366 { VALID, VALID, WLAN_RC_PHY_CCK, 2000, /* 2 Mb */ 367 1900, 0x1a, 0x04, 4, 368 1, 1, 1, 1, 0 }, 369 { VALID, VALID, WLAN_RC_PHY_CCK, 5500, /* 5.5 Mb */ 370 4900, 0x19, 0x04, 11, 371 2, 2, 2, 2, 0 }, 372 { VALID, VALID, WLAN_RC_PHY_CCK, 11000, /* 11 Mb */ 373 8100, 0x18, 0x04, 22, 374 3, 3, 2, 3, 0 }, 375 { INVALID, INVALID, WLAN_RC_PHY_OFDM, 6000, /* 6 Mb */ 376 5400, 0x0b, 0x00, 12, 377 4, 2, 1, 4, 0 }, 378 { INVALID, INVALID, WLAN_RC_PHY_OFDM, 9000, /* 9 Mb */ 379 7800, 0x0f, 0x00, 18, 380 4, 3, 1, 5, 0 }, 381 { VALID, VALID, WLAN_RC_PHY_OFDM, 12000, /* 12 Mb */ 382 10000, 0x0a, 0x00, 24, 383 6, 4, 1, 6, 0 }, 384 { VALID, VALID, WLAN_RC_PHY_OFDM, 18000, /* 18 Mb */ 385 13900, 0x0e, 0x00, 36, 386 6, 6, 2, 7, 0 }, 387 { VALID, VALID, WLAN_RC_PHY_OFDM, 24000, /* 24 Mb */ 388 17300, 0x09, 0x00, 48, 389 8, 10, 3, 8, 0 }, 390 { VALID, VALID, WLAN_RC_PHY_OFDM, 36000, /* 36 Mb */ 391 23000, 0x0d, 0x00, 72, 392 8, 14, 3, 9, 0 }, 393 { VALID, VALID, WLAN_RC_PHY_OFDM, 48000, /* 48 Mb */ 394 27400, 0x08, 0x00, 96, 395 8, 19, 3, 10, 0 }, 396 { VALID, VALID, WLAN_RC_PHY_OFDM, 54000, /* 54 Mb */ 397 29300, 0x0c, 0x00, 108, 398 8, 23, 3, 11, 0 }, 399 }, 400 50, /* probe interval */ 401 50, /* rssi reduce interval */ 402 0, /* Phy rates allowed initially */ 403 }; 404 405 static struct ath_rate_table ar5416_11b_ratetable = { 406 4, 407 {0}, 408 { 409 { VALID, VALID, WLAN_RC_PHY_CCK, 1000, /* 1 Mb */ 410 900, 0x1b, 0x00, (0x80|2), 411 0, 0, 1, 0, 0 }, 412 { VALID, VALID, WLAN_RC_PHY_CCK, 2000, /* 2 Mb */ 413 1800, 0x1a, 0x04, (0x80|4), 414 1, 1, 1, 1, 0 }, 415 { VALID, VALID, WLAN_RC_PHY_CCK, 5500, /* 5.5 Mb */ 416 4300, 0x19, 0x04, (0x80|11), 417 1, 2, 2, 2, 0 }, 418 { VALID, VALID, WLAN_RC_PHY_CCK, 11000, /* 11 Mb */ 419 7100, 0x18, 0x04, (0x80|22), 420 1, 4, 100, 3, 0 }, 421 }, 422 100, /* probe interval */ 423 100, /* rssi reduce interval */ 424 0, /* Phy rates allowed initially */ 425 }; 426 427 static inline int8_t 428 median(int8_t a, int8_t b, int8_t c) 429 { 430 if (a >= b) { 431 if (b >= c) 432 return (b); 433 else if (a > c) 434 return (c); 435 else 436 return (a); 437 } else { 438 if (a >= c) 439 return (a); 440 else if (b >= c) 441 return (c); 442 else 443 return (b); 444 } 445 } 446 447 static void 448 arn_rc_sort_validrates(struct ath_rate_table *rate_table, 449 struct ath_rate_priv *ath_rc_priv) 450 { 451 uint8_t i, j, idx, idx_next; 452 453 for (i = ath_rc_priv->max_valid_rate - 1; i > 0; i--) { 454 for (j = 0; j <= i-1; j++) { 455 idx = ath_rc_priv->valid_rate_index[j]; 456 idx_next = ath_rc_priv->valid_rate_index[j+1]; 457 458 if (rate_table->info[idx].ratekbps > 459 rate_table->info[idx_next].ratekbps) { 460 ath_rc_priv->valid_rate_index[j] = idx_next; 461 ath_rc_priv->valid_rate_index[j+1] = idx; 462 } 463 } 464 } 465 } 466 467 static void 468 arn_rc_init_valid_txmask(struct ath_rate_priv *ath_rc_priv) 469 { 470 uint8_t i; 471 472 for (i = 0; i < ath_rc_priv->rate_table_size; i++) 473 ath_rc_priv->valid_rate_index[i] = 0; 474 } 475 476 static inline void 477 arn_rc_set_valid_txmask(struct ath_rate_priv *ath_rc_priv, 478 uint8_t index, int valid_tx_rate) 479 { 480 ASSERT(index <= ath_rc_priv->rate_table_size); 481 ath_rc_priv->valid_rate_index[index] = valid_tx_rate ? 1 : 0; 482 } 483 484 static inline int 485 /* LINTED E_STATIC_UNUSED */ 486 arn_rc_isvalid_txmask(struct ath_rate_priv *ath_rc_priv, uint8_t index) 487 { 488 ASSERT(index <= ath_rc_priv->rate_table_size); 489 return (ath_rc_priv->valid_rate_index[index]); 490 } 491 492 /* ARGSUSED */ 493 static inline int 494 arn_rc_get_nextvalid_txrate(struct ath_rate_table *rate_table, 495 struct ath_rate_priv *ath_rc_priv, 496 uint8_t cur_valid_txrate, 497 uint8_t *next_idx) 498 { 499 uint8_t i; 500 501 for (i = 0; i < ath_rc_priv->max_valid_rate - 1; i++) { 502 if (ath_rc_priv->valid_rate_index[i] == cur_valid_txrate) { 503 *next_idx = ath_rc_priv->valid_rate_index[i+1]; 504 return (1); 505 } 506 } 507 508 /* No more valid rates */ 509 *next_idx = 0; 510 511 return (0); 512 } 513 514 /* Return true only for single stream */ 515 static int 516 arn_rc_valid_phyrate(uint32_t phy, uint32_t capflag, int ignore_cw) 517 { 518 if (WLAN_RC_PHY_HT(phy) && !(capflag & WLAN_RC_HT_FLAG)) 519 return (0); 520 if (WLAN_RC_PHY_DS(phy) && !(capflag & WLAN_RC_DS_FLAG)) 521 return (0); 522 if (WLAN_RC_PHY_SGI(phy) && !(capflag & WLAN_RC_SGI_FLAG)) 523 return (0); 524 if (!ignore_cw && WLAN_RC_PHY_HT(phy)) { 525 if (WLAN_RC_PHY_40(phy) && !(capflag & WLAN_RC_40_FLAG)) 526 return (0); 527 if (!WLAN_RC_PHY_40(phy) && (capflag & WLAN_RC_40_FLAG)) 528 return (0); 529 } 530 return (1); 531 } 532 533 /* ARGSUSED */ 534 static inline int 535 arn_rc_get_nextlowervalid_txrate(struct ath_rate_table *rate_table, 536 struct ath_rate_priv *ath_rc_priv, 537 uint8_t cur_valid_txrate, uint8_t *next_idx) 538 { 539 int8_t i; 540 541 for (i = 1; i < ath_rc_priv->max_valid_rate; i++) { 542 if (ath_rc_priv->valid_rate_index[i] == cur_valid_txrate) { 543 *next_idx = ath_rc_priv->valid_rate_index[i-1]; 544 return (1); 545 } 546 } 547 548 return (0); 549 } 550 551 static uint8_t 552 arn_rc_init_validrates(struct ath_rate_priv *ath_rc_priv, 553 struct ath_rate_table *rate_table, uint32_t capflag) 554 { 555 uint8_t i, hi = 0; 556 uint32_t valid; 557 558 for (i = 0; i < rate_table->rate_cnt; i++) { 559 valid = (ath_rc_priv->single_stream ? 560 rate_table->info[i].valid_single_stream : 561 rate_table->info[i].valid); 562 if (valid == 1) { 563 uint32_t phy = rate_table->info[i].phy; 564 uint8_t valid_rate_count = 0; 565 566 if (!arn_rc_valid_phyrate(phy, capflag, 0)) 567 continue; 568 569 valid_rate_count = ath_rc_priv->valid_phy_ratecnt[phy]; 570 571 ath_rc_priv-> 572 valid_phy_rateidx[phy][valid_rate_count] = i; 573 ath_rc_priv->valid_phy_ratecnt[phy] += 1; 574 arn_rc_set_valid_txmask(ath_rc_priv, i, 1); 575 hi = A_MAX(hi, i); 576 } 577 } 578 579 return (hi); 580 } 581 582 static uint8_t 583 arn_rc_setvalid_rates(struct ath_rate_priv *ath_rc_priv, 584 struct ath_rate_table *rate_table, 585 struct ath_rateset *rateset, 586 uint32_t capflag) 587 { 588 uint8_t i, j, hi = 0; 589 590 /* Use intersection of working rates and valid rates */ 591 for (i = 0; i < rateset->rs_nrates; i++) { 592 for (j = 0; j < rate_table->rate_cnt; j++) { 593 uint32_t phy = rate_table->info[j].phy; 594 uint32_t valid = (ath_rc_priv->single_stream ? 595 rate_table->info[j].valid_single_stream : 596 rate_table->info[j].valid); 597 uint8_t rate = rateset->rs_rates[i]; 598 uint8_t dot11rate = rate_table->info[j].dot11rate; 599 600 /* 601 * We allow a rate only if its valid and the 602 * capflag matches one of the validity 603 * (VALID/VALID_20/VALID_40) flags 604 */ 605 if (((rate & 0x7F) == (dot11rate & 0x7F)) && 606 ((valid & WLAN_RC_CAP_MODE(capflag)) == 607 WLAN_RC_CAP_MODE(capflag)) && 608 !WLAN_RC_PHY_HT(phy)) { 609 uint8_t valid_rate_count = 0; 610 611 if (!arn_rc_valid_phyrate(phy, capflag, 0)) 612 continue; 613 614 valid_rate_count = 615 ath_rc_priv->valid_phy_ratecnt[phy]; 616 617 ath_rc_priv->valid_phy_rateidx[phy] 618 [valid_rate_count] = j; 619 ath_rc_priv->valid_phy_ratecnt[phy] += 1; 620 arn_rc_set_valid_txmask(ath_rc_priv, j, 1); 621 hi = A_MAX(hi, j); 622 } 623 } 624 } 625 626 return (hi); 627 } 628 629 static uint8_t 630 arn_rc_setvalid_htrates(struct ath_rate_priv *ath_rc_priv, 631 struct ath_rate_table *rate_table, 632 uint8_t *mcs_set, uint32_t capflag) 633 { 634 struct ath_rateset *rateset = (struct ath_rateset *)mcs_set; 635 636 uint8_t i, j, hi = 0; 637 638 /* Use intersection of working rates and valid rates */ 639 for (i = 0; i < rateset->rs_nrates; i++) { 640 for (j = 0; j < rate_table->rate_cnt; j++) { 641 uint32_t phy = rate_table->info[j].phy; 642 uint32_t valid = (ath_rc_priv->single_stream ? 643 rate_table->info[j].valid_single_stream : 644 rate_table->info[j].valid); 645 uint8_t rate = rateset->rs_rates[i]; 646 uint8_t dot11rate = rate_table->info[j].dot11rate; 647 648 if (((rate & 0x7F) != (dot11rate & 0x7F)) || 649 !WLAN_RC_PHY_HT(phy) || 650 !WLAN_RC_PHY_HT_VALID(valid, capflag)) 651 continue; 652 653 if (!arn_rc_valid_phyrate(phy, capflag, 0)) 654 continue; 655 656 ath_rc_priv->valid_phy_rateidx[phy] 657 [ath_rc_priv->valid_phy_ratecnt[phy]] = j; 658 ath_rc_priv->valid_phy_ratecnt[phy] += 1; 659 arn_rc_set_valid_txmask(ath_rc_priv, j, 1); 660 hi = A_MAX(hi, j); 661 } 662 } 663 664 return (hi); 665 } 666 667 /* ARGSUSED */ 668 static uint8_t 669 arn_rc_ratefind_ht(struct arn_softc *sc, 670 struct ath_rate_priv *ath_rc_priv, 671 struct ath_rate_table *rate_table, 672 int probe_allowed, int *is_probing, 673 int is_retry) 674 { 675 uint32_t dt, best_thruput, this_thruput, now_msec; 676 uint8_t rate, next_rate, best_rate, maxindex, minindex; 677 int8_t rssi_last, rssi_reduce = 0, index = 0; 678 679 *is_probing = 0; 680 681 rssi_last = median(ath_rc_priv->rssi_last, 682 ath_rc_priv->rssi_last_prev, 683 ath_rc_priv->rssi_last_prev2); 684 685 /* 686 * Age (reduce) last ack rssi based on how old it is. 687 * The bizarre numbers are so the delta is 160msec, 688 * meaning we divide by 16. 689 * 0msec <= dt <= 25msec: don't derate 690 * 25msec <= dt <= 185msec: derate linearly from 0 to 10dB 691 * 185msec <= dt: derate by 10dB 692 */ 693 694 /* now_msec = jiffies_to_msecs(jiffies); */ 695 now_msec = drv_hztousec(ddi_get_lbolt())/1000; /* mescs ? */ 696 dt = now_msec - ath_rc_priv->rssi_time; 697 698 if (dt >= 185) 699 rssi_reduce = 10; 700 else if (dt >= 25) 701 rssi_reduce = (uint8_t)((dt - 25) >> 4); 702 703 /* Now reduce rssi_last by rssi_reduce */ 704 if (rssi_last < rssi_reduce) 705 rssi_last = 0; 706 else 707 rssi_last -= rssi_reduce; 708 709 /* 710 * Now look up the rate in the rssi table and return it. 711 * If no rates match then we return 0 (lowest rate) 712 */ 713 714 best_thruput = 0; 715 maxindex = ath_rc_priv->max_valid_rate-1; 716 717 minindex = 0; 718 best_rate = minindex; 719 720 /* 721 * Try the higher rate first. It will reduce memory moving time 722 * if we have very good channel characteristics. 723 */ 724 for (index = maxindex; index >= minindex; index--) { 725 uint8_t per_thres; 726 727 rate = ath_rc_priv->valid_rate_index[index]; 728 if (rate > ath_rc_priv->rate_max_phy) 729 continue; 730 731 /* 732 * For TCP the average collision rate is around 11%, 733 * so we ignore PERs less than this. This is to 734 * prevent the rate we are currently using (whose 735 * PER might be in the 10-15 range because of TCP 736 * collisions) looking worse than the next lower 737 * rate whose PER has decayed close to 0. If we 738 * used to next lower rate, its PER would grow to 739 * 10-15 and we would be worse off then staying 740 * at the current rate. 741 */ 742 per_thres = ath_rc_priv->state[rate].per; 743 if (per_thres < 12) 744 per_thres = 12; 745 746 this_thruput = rate_table->info[rate].user_ratekbps * 747 (100 - per_thres); 748 749 if (best_thruput <= this_thruput) { 750 best_thruput = this_thruput; 751 best_rate = rate; 752 } 753 } 754 755 rate = best_rate; 756 757 /* 758 * if we are retrying for more than half the number 759 * of max retries, use the min rate for the next retry 760 */ 761 if (is_retry) 762 rate = ath_rc_priv->valid_rate_index[minindex]; 763 764 ath_rc_priv->rssi_last_lookup = rssi_last; 765 766 /* 767 * Must check the actual rate (ratekbps) to account for 768 * non-monoticity of 11g's rate table 769 */ 770 771 if (rate >= ath_rc_priv->rate_max_phy && probe_allowed) { 772 rate = ath_rc_priv->rate_max_phy; 773 774 /* Probe the next allowed phy state */ 775 /* FIXME:XXXX Check to make sure ratMax is checked properly */ 776 if (arn_rc_get_nextvalid_txrate(rate_table, 777 ath_rc_priv, rate, &next_rate) && 778 (now_msec - ath_rc_priv->probe_time > 779 rate_table->probe_interval) && 780 (ath_rc_priv->hw_maxretry_pktcnt >= 1)) { 781 rate = next_rate; 782 ath_rc_priv->probe_rate = rate; 783 ath_rc_priv->probe_time = now_msec; 784 ath_rc_priv->hw_maxretry_pktcnt = 0; 785 *is_probing = 1; 786 } 787 } 788 789 if (rate > (ath_rc_priv->rate_table_size - 1)) 790 rate = ath_rc_priv->rate_table_size - 1; 791 792 ASSERT((rate_table->info[rate].valid && !ath_rc_priv->single_stream) || 793 (rate_table->info[rate].valid_single_stream && 794 ath_rc_priv->single_stream)); 795 796 return (rate); 797 } 798 799 static void 800 arn_rc_rate_set_series(struct ath_rate_table *rate_table, 801 struct ath9k_tx_rate *rate, 802 uint8_t tries, 803 uint8_t rix, 804 int rtsctsenable) 805 { 806 #if 0 807 struct ieee80211_node *in; 808 ieee80211com_t *ic = (ieee80211com_t *)sc; 809 #endif 810 rate->count = tries; 811 rate->idx = rix; 812 813 if (rtsctsenable) 814 rate->flags |= ATH9K_TX_RC_USE_RTS_CTS; 815 #if 0 816 if ((ic->ic_flags & IEEE80211_F_SHPREAMBLE) && 817 (in->in_capinfo & IEEE80211_CAPINFO_SHORT_PREAMBLE)) { 818 rate->flags |= ATH9K_TX_RC_USE_SHORT_PREAMBLE; 819 } 820 #endif 821 if (WLAN_RC_PHY_40(rate_table->info[rix].phy)) 822 rate->flags |= ATH9K_TX_RC_40_MHZ_WIDTH; 823 if (WLAN_RC_PHY_SGI(rate_table->info[rix].phy)) 824 rate->flags |= ATH9K_TX_RC_SHORT_GI; 825 if (WLAN_RC_PHY_HT(rate_table->info[rix].phy)) 826 rate->flags |= ATH9K_TX_RC_MCS; 827 } 828 829 /* ARGSUSED */ 830 static uint8_t 831 arn_rc_rate_getidx(struct arn_softc *sc, 832 struct ath_rate_priv *ath_rc_priv, 833 struct ath_rate_table *rate_table, 834 uint8_t rix, uint16_t stepdown, 835 uint16_t min_rate) 836 { 837 uint32_t j; 838 uint8_t nextindex; 839 840 if (min_rate) { 841 for (j = RATE_TABLE_SIZE; j > 0; j--) { 842 if (arn_rc_get_nextlowervalid_txrate(rate_table, 843 ath_rc_priv, rix, &nextindex)) 844 rix = nextindex; 845 else 846 break; 847 } 848 } else { 849 for (j = stepdown; j > 0; j--) { 850 if (arn_rc_get_nextlowervalid_txrate(rate_table, 851 ath_rc_priv, rix, &nextindex)) 852 rix = nextindex; 853 else 854 break; 855 } 856 } 857 return (rix); 858 } 859 860 static void 861 arn_rc_ratefind(struct arn_softc *sc, struct ath_rate_priv *ath_rc_priv, 862 struct ath_buf *bf, int num_tries, int num_rates, int *is_probe, 863 boolean_t is_retry) 864 { 865 uint8_t try_per_rate = 0, i = 0, rix, nrix; 866 struct ath_rate_table *rate_table; 867 struct ath9k_tx_rate *rates = bf->rates; 868 ieee80211com_t *ic = (ieee80211com_t *)sc; 869 870 rate_table = sc->sc_currates; 871 rix = arn_rc_ratefind_ht(sc, ath_rc_priv, rate_table, 1, 872 is_probe, is_retry); 873 nrix = rix; 874 875 if (*is_probe) { 876 /* 877 * set one try for probe rates. For the 878 * probes don't enable rts 879 */ 880 arn_rc_rate_set_series(rate_table, 881 &rates[i++], 1, nrix, 0); 882 883 try_per_rate = (num_tries/num_rates); 884 /* 885 * Get the next tried/allowed rate. No RTS for the next series 886 * after the probe rate 887 */ 888 nrix = arn_rc_rate_getidx(sc, 889 ath_rc_priv, rate_table, nrix, 1, 0); 890 arn_rc_rate_set_series(rate_table, 891 &rates[i++], try_per_rate, nrix, 0); 892 } else { 893 try_per_rate = (num_tries/num_rates); 894 /* Set the choosen rate. No RTS for first series entry. */ 895 arn_rc_rate_set_series(rate_table, 896 &rates[i++], try_per_rate, nrix, 0); 897 } 898 899 /* Fill in the other rates for multirate retry */ 900 for (; i < num_rates; i++) { 901 uint8_t try_num; 902 uint8_t min_rate; 903 904 try_num = ((i + 1) == num_rates) ? 905 num_tries - (try_per_rate * i) : try_per_rate; 906 /* LINTED E_FALSE_LOGICAL_EXPR */ 907 min_rate = (((i + 1) == num_rates) && 0); 908 909 nrix = arn_rc_rate_getidx(sc, ath_rc_priv, 910 rate_table, nrix, 1, min_rate); 911 /* All other rates in the series have RTS enabled */ 912 arn_rc_rate_set_series(rate_table, &rates[i], try_num, nrix, 1); 913 } 914 915 /* 916 * NB:Change rate series to enable aggregation when operating 917 * at lower MCS rates. When first rate in series is MCS2 918 * in HT40 @ 2.4GHz, series should look like: 919 * 920 * {MCS2, MCS1, MCS0, MCS0}. 921 * 922 * When first rate in series is MCS3 in HT20 @ 2.4GHz, series should 923 * look like: 924 * 925 * {MCS3, MCS2, MCS1, MCS1} 926 * 927 * So, set fourth rate in series to be same as third one for 928 * above conditions. 929 */ 930 931 if (IEEE80211_IS_CHAN_HTG(ic->ic_curchan)) { 932 uint8_t dot11rate = rate_table->info[rix].dot11rate; 933 uint8_t phy = rate_table->info[rix].phy; 934 if (i == 4 && 935 ((dot11rate == 2 && phy == WLAN_RC_PHY_HT_40_SS) || 936 (dot11rate == 3 && phy == WLAN_RC_PHY_HT_20_SS))) { 937 rates[3].idx = rates[2].idx; 938 rates[3].flags = rates[2].flags; 939 } 940 } 941 } 942 943 /* ARGSUSED */ 944 static boolean_t 945 arn_rc_update_per(struct arn_softc *sc, 946 struct ath_rate_table *rate_table, 947 struct ath_rate_priv *ath_rc_priv, 948 struct ath_tx_info_priv *tx_info_priv, 949 int tx_rate, int xretries, int retries, 950 uint32_t now_msec) 951 { 952 boolean_t state_change = B_FALSE; 953 int count; 954 uint8_t last_per; 955 static uint32_t nretry_to_per_lookup[10] = { 956 100 * 0 / 1, 957 100 * 1 / 4, 958 100 * 1 / 2, 959 100 * 3 / 4, 960 100 * 4 / 5, 961 100 * 5 / 6, 962 100 * 6 / 7, 963 100 * 7 / 8, 964 100 * 8 / 9, 965 100 * 9 / 10 966 }; 967 968 last_per = ath_rc_priv->state[tx_rate].per; 969 970 if (xretries) { 971 if (xretries == 1) { 972 ath_rc_priv->state[tx_rate].per += 30; 973 if (ath_rc_priv->state[tx_rate].per > 100) 974 ath_rc_priv->state[tx_rate].per = 100; 975 } else { 976 /* xretries == 2 */ 977 count = ARRAY_SIZE(nretry_to_per_lookup); 978 if (retries >= count) 979 retries = count - 1; 980 981 /* new_PER = 7/8*old_PER + 1/8*(currentPER) */ 982 ath_rc_priv->state[tx_rate].per = 983 (uint8_t)(last_per - (last_per >> 3) + (100 >> 3)); 984 } 985 986 /* xretries == 1 or 2 */ 987 988 if (ath_rc_priv->probe_rate == tx_rate) 989 ath_rc_priv->probe_rate = 0; 990 991 } else { /* xretries == 0 */ 992 count = ARRAY_SIZE(nretry_to_per_lookup); 993 if (retries >= count) 994 retries = count - 1; 995 996 if (tx_info_priv->n_bad_frames) { 997 /* 998 * new_PER = 7/8*old_PER + 1/8*(currentPER) 999 * Assuming that n_frames is not 0. The current PER 1000 * from the retries is 100 * retries / (retries+1), 1001 * since the first retries attempts failed, and the 1002 * next one worked. For the one that worked, 1003 * n_bad_frames subframes out of n_frames wored, 1004 * so the PER for that part is 1005 * 100 * n_bad_frames / n_frames, and it contributes 1006 * 100 * n_bad_frames / (n_frames * (retries+1)) to 1007 * the above PER. The expression below is a 1008 * simplified version of the sum of these two terms. 1009 */ 1010 if (tx_info_priv->n_frames > 0) { 1011 int n_frames, n_bad_frames; 1012 uint8_t cur_per, new_per; 1013 1014 n_bad_frames = retries * 1015 tx_info_priv->n_frames + 1016 tx_info_priv->n_bad_frames; 1017 n_frames = 1018 tx_info_priv->n_frames * (retries + 1); 1019 cur_per = 1020 (100 * n_bad_frames / n_frames) >> 3; 1021 new_per = (uint8_t) 1022 (last_per - (last_per >> 3) + cur_per); 1023 ath_rc_priv->state[tx_rate].per = new_per; 1024 } 1025 } else { 1026 ath_rc_priv->state[tx_rate].per = 1027 (uint8_t)(last_per - (last_per >> 3) + 1028 (nretry_to_per_lookup[retries] >> 3)); 1029 } 1030 1031 ath_rc_priv->rssi_last_prev2 = ath_rc_priv->rssi_last_prev; 1032 ath_rc_priv->rssi_last_prev = ath_rc_priv->rssi_last; 1033 ath_rc_priv->rssi_last = tx_info_priv->tx.ts_rssi; 1034 ath_rc_priv->rssi_time = now_msec; 1035 1036 /* 1037 * If we got at most one retry then increase the max rate if 1038 * this was a probe. Otherwise, ignore the probe. 1039 */ 1040 if (ath_rc_priv->probe_rate && 1041 ath_rc_priv->probe_rate == tx_rate) { 1042 if (retries > 0 || 2 * tx_info_priv->n_bad_frames > 1043 tx_info_priv->n_frames) { 1044 /* 1045 * Since we probed with just a single attempt, 1046 * any retries means the probe failed. Also, 1047 * if the attempt worked, but more than half 1048 * the subframes were bad then also consider 1049 * the probe a failure. 1050 */ 1051 ath_rc_priv->probe_rate = 0; 1052 } else { 1053 uint8_t probe_rate = 0; 1054 1055 ath_rc_priv->rate_max_phy = 1056 ath_rc_priv->probe_rate; 1057 probe_rate = ath_rc_priv->probe_rate; 1058 1059 if (ath_rc_priv->state[probe_rate].per > 30) 1060 ath_rc_priv->state[probe_rate].per = 20; 1061 1062 ath_rc_priv->probe_rate = 0; 1063 1064 /* 1065 * Since this probe succeeded, we allow the next 1066 * probe twice as soon. This allows the maxRate 1067 * to move up faster if the probes are 1068 * succesful. 1069 */ 1070 ath_rc_priv->probe_time = 1071 now_msec - rate_table->probe_interval / 2; 1072 } 1073 } 1074 1075 if (retries > 0) { 1076 /* 1077 * Don't update anything. We don't know if 1078 * this was because of collisions or poor signal. 1079 * 1080 * Later: if rssi_ack is close to 1081 * ath_rc_priv->state[txRate].rssi_thres and we see lots 1082 * of retries, then we could increase 1083 * ath_rc_priv->state[txRate].rssi_thres. 1084 */ 1085 ath_rc_priv->hw_maxretry_pktcnt = 0; 1086 } else { 1087 int32_t rssi_ackAvg; 1088 int8_t rssi_thres; 1089 int8_t rssi_ack_vmin; 1090 1091 /* 1092 * It worked with no retries. First ignore bogus (small) 1093 * rssi_ack values. 1094 */ 1095 if (tx_rate == ath_rc_priv->rate_max_phy && 1096 ath_rc_priv->hw_maxretry_pktcnt < 255) { 1097 ath_rc_priv->hw_maxretry_pktcnt++; 1098 } 1099 1100 if (tx_info_priv->tx.ts_rssi < 1101 rate_table->info[tx_rate].rssi_ack_validmin) 1102 goto exit; 1103 1104 /* Average the rssi */ 1105 if (tx_rate != ath_rc_priv->rssi_sum_rate) { 1106 ath_rc_priv->rssi_sum_rate = tx_rate; 1107 ath_rc_priv->rssi_sum = 1108 ath_rc_priv->rssi_sum_cnt = 0; 1109 } 1110 1111 ath_rc_priv->rssi_sum += tx_info_priv->tx.ts_rssi; 1112 ath_rc_priv->rssi_sum_cnt++; 1113 1114 if (ath_rc_priv->rssi_sum_cnt < 4) 1115 goto exit; 1116 1117 rssi_ackAvg = 1118 (ath_rc_priv->rssi_sum + 2) / 4; 1119 rssi_thres = 1120 ath_rc_priv->state[tx_rate].rssi_thres; 1121 rssi_ack_vmin = 1122 rate_table->info[tx_rate].rssi_ack_validmin; 1123 1124 ath_rc_priv->rssi_sum = 1125 ath_rc_priv->rssi_sum_cnt = 0; 1126 1127 /* Now reduce the current rssi threshold */ 1128 if ((rssi_ackAvg < rssi_thres + 2) && 1129 (rssi_thres > rssi_ack_vmin)) { 1130 ath_rc_priv->state[tx_rate].rssi_thres--; 1131 } 1132 1133 state_change = B_TRUE; 1134 } 1135 } 1136 exit: 1137 return (state_change); 1138 } 1139 1140 /* 1141 * Update PER, RSSI and whatever else that the code thinks 1142 * it is doing. If you can make sense of all this, you really 1143 * need to go out more. 1144 */ 1145 static void 1146 arn_rc_update_ht(struct arn_softc *sc, 1147 struct ath_rate_priv *ath_rc_priv, 1148 struct ath_tx_info_priv *tx_info_priv, 1149 int tx_rate, int xretries, int retries) 1150 { 1151 #define CHK_RSSI(rate) \ 1152 ((ath_rc_priv->state[(rate)].rssi_thres + \ 1153 rate_table->info[(rate)].rssi_ack_deltamin) > \ 1154 ath_rc_priv->state[(rate)+1].rssi_thres) 1155 1156 /* u32 now_msec = jiffies_to_msecs(jiffies); */ 1157 uint32_t now_msec = drv_hztousec(ddi_get_lbolt())/1000; /* mescs ? */ 1158 int rate; 1159 uint8_t last_per; 1160 boolean_t state_change = B_FALSE; 1161 struct ath_rate_table *rate_table = sc->sc_currates; 1162 int size = ath_rc_priv->rate_table_size; 1163 1164 if ((tx_rate < 0) || (tx_rate > rate_table->rate_cnt)) 1165 return; 1166 1167 /* To compensate for some imbalance between ctrl and ext. channel */ 1168 1169 if (WLAN_RC_PHY_40(rate_table->info[tx_rate].phy)) 1170 tx_info_priv->tx.ts_rssi = 1171 tx_info_priv->tx.ts_rssi < 3 ? 0 : 1172 tx_info_priv->tx.ts_rssi - 3; 1173 1174 last_per = ath_rc_priv->state[tx_rate].per; 1175 1176 /* Update PER first */ 1177 state_change = arn_rc_update_per(sc, rate_table, ath_rc_priv, 1178 tx_info_priv, tx_rate, xretries, 1179 retries, now_msec); 1180 1181 /* 1182 * If this rate looks bad (high PER) then stop using it for 1183 * a while (except if we are probing). 1184 */ 1185 if (ath_rc_priv->state[tx_rate].per >= 55 && tx_rate > 0 && 1186 rate_table->info[tx_rate].ratekbps <= 1187 rate_table->info[ath_rc_priv->rate_max_phy].ratekbps) { 1188 (void) arn_rc_get_nextlowervalid_txrate(rate_table, 1189 ath_rc_priv, 1190 (uint8_t)tx_rate, 1191 &ath_rc_priv->rate_max_phy); 1192 1193 /* Don't probe for a little while. */ 1194 ath_rc_priv->probe_time = now_msec; 1195 } 1196 1197 if (state_change) { 1198 /* 1199 * Make sure the rates above this have higher rssi thresholds. 1200 * (Note: Monotonicity is kept within the OFDM rates and 1201 * within the CCK rates. However, no adjustment is 1202 * made to keep the rssi thresholds monotonically 1203 * increasing between the CCK and OFDM rates.) 1204 */ 1205 for (rate = tx_rate; rate < size - 1; rate++) { 1206 if (rate_table->info[rate+1].phy != 1207 rate_table->info[tx_rate].phy) 1208 break; 1209 1210 if (CHK_RSSI(rate)) { 1211 ath_rc_priv->state[rate+1].rssi_thres = 1212 ath_rc_priv->state[rate].rssi_thres + 1213 rate_table->info[rate].rssi_ack_deltamin; 1214 } 1215 } 1216 1217 /* Make sure the rates below this have lower rssi thresholds. */ 1218 for (rate = tx_rate - 1; rate >= 0; rate--) { 1219 if (rate_table->info[rate].phy != 1220 rate_table->info[tx_rate].phy) 1221 break; 1222 1223 if (CHK_RSSI(rate)) { 1224 if (ath_rc_priv->state[rate+1].rssi_thres < 1225 rate_table->info[rate].rssi_ack_deltamin) 1226 ath_rc_priv->state[rate].rssi_thres = 0; 1227 else { 1228 ath_rc_priv->state[rate].rssi_thres = 1229 ath_rc_priv->state[rate+1]. 1230 rssi_thres - 1231 rate_table->info[rate]. 1232 rssi_ack_deltamin; 1233 } 1234 1235 if (ath_rc_priv->state[rate].rssi_thres < 1236 rate_table->info[rate].rssi_ack_validmin) { 1237 ath_rc_priv->state[rate].rssi_thres = 1238 rate_table->info[rate]. 1239 rssi_ack_validmin; 1240 } 1241 } 1242 } 1243 } 1244 1245 /* Make sure the rates below this have lower PER */ 1246 /* Monotonicity is kept only for rates below the current rate. */ 1247 if (ath_rc_priv->state[tx_rate].per < last_per) { 1248 for (rate = tx_rate - 1; rate >= 0; rate--) { 1249 if (rate_table->info[rate].phy != 1250 rate_table->info[tx_rate].phy) 1251 break; 1252 1253 if (ath_rc_priv->state[rate].per > 1254 ath_rc_priv->state[rate+1].per) { 1255 ath_rc_priv->state[rate].per = 1256 ath_rc_priv->state[rate+1].per; 1257 } 1258 } 1259 } 1260 1261 /* Maintain monotonicity for rates above the current rate */ 1262 for (rate = tx_rate; rate < size - 1; rate++) { 1263 if (ath_rc_priv->state[rate+1].per < 1264 ath_rc_priv->state[rate].per) 1265 ath_rc_priv->state[rate+1].per = 1266 ath_rc_priv->state[rate].per; 1267 } 1268 1269 /* 1270 * Every so often, we reduce the thresholds and 1271 * PER (different for CCK and OFDM). 1272 */ 1273 if (now_msec - ath_rc_priv->rssi_down_time >= 1274 rate_table->rssi_reduce_interval) { 1275 1276 for (rate = 0; rate < size; rate++) { 1277 if (ath_rc_priv->state[rate].rssi_thres > 1278 rate_table->info[rate].rssi_ack_validmin) 1279 ath_rc_priv->state[rate].rssi_thres -= 1; 1280 } 1281 ath_rc_priv->rssi_down_time = now_msec; 1282 } 1283 1284 /* 1285 * Every so often, we reduce the thresholds 1286 * and PER (different for CCK and OFDM). 1287 */ 1288 if (now_msec - ath_rc_priv->per_down_time >= 1289 rate_table->rssi_reduce_interval) { 1290 for (rate = 0; rate < size; rate++) { 1291 ath_rc_priv->state[rate].per = 1292 7 * ath_rc_priv->state[rate].per / 8; 1293 } 1294 1295 ath_rc_priv->per_down_time = now_msec; 1296 } 1297 1298 #undef CHK_RSSI 1299 } 1300 1301 static int 1302 ath_rc_get_rateindex(struct ath_rate_table *rate_table, 1303 struct ath9k_tx_rate *rate) 1304 { 1305 int rix; 1306 1307 if ((rate->flags & ATH9K_TX_RC_40_MHZ_WIDTH) && 1308 (rate->flags & ATH9K_TX_RC_SHORT_GI)) 1309 rix = rate_table->info[rate->idx].ht_index; 1310 else if (rate->flags & ATH9K_TX_RC_SHORT_GI) 1311 rix = rate_table->info[rate->idx].sgi_index; 1312 else if (rate->flags & ATH9K_TX_RC_40_MHZ_WIDTH) 1313 rix = rate_table->info[rate->idx].cw40index; 1314 else 1315 rix = rate_table->info[rate->idx].base_index; 1316 1317 return (rix); 1318 } 1319 1320 static void 1321 ath_rc_tx_status(struct arn_softc *sc, struct ath_rate_priv *ath_rc_priv, 1322 struct ath_buf *bf, int final_ts_idx, int xretries, int long_retry) 1323 { 1324 struct ath_tx_info_priv *tx_info_priv = 1325 (struct ath_tx_info_priv *)&bf->tx_info_priv; 1326 struct ath9k_tx_rate *rates = bf->rates; 1327 struct ath_rate_table *rate_table; 1328 uint32_t i = 0, rix; 1329 uint8_t flags; 1330 1331 rate_table = sc->sc_currates; 1332 1333 /* 1334 * If the first rate is not the final index, there 1335 * are intermediate rate failures to be processed. 1336 */ 1337 if (final_ts_idx != 0) { 1338 /* Process intermediate rates that failed. */ 1339 for (i = 0; i < final_ts_idx; i++) { 1340 if (rates[i].count != 0 && (rates[i].idx >= 0)) { 1341 flags = rates[i].flags; 1342 1343 /* 1344 * If HT40 and we have switched mode from 1345 * 40 to 20 => don't update 1346 */ 1347 1348 if ((flags & ATH9K_TX_RC_40_MHZ_WIDTH) && 1349 (ath_rc_priv->rc_phy_mode != 1350 WLAN_RC_40_FLAG)) 1351 return; 1352 1353 rix = 1354 ath_rc_get_rateindex(rate_table, &rates[i]); 1355 arn_rc_update_ht(sc, ath_rc_priv, 1356 tx_info_priv, rix, 1357 xretries ? 1 : 2, 1358 rates[i].count); 1359 } 1360 } 1361 } else { 1362 /* 1363 * Handle the special case of MIMO PS burst, where the second 1364 * aggregate is sent out with only one rate and one try. 1365 * Treating it as an excessive retry penalizes the rate 1366 * inordinately. 1367 */ 1368 if (rates[0].count == 1 && xretries == 1) 1369 xretries = 2; 1370 } 1371 1372 flags = rates[i].flags; 1373 1374 /* If HT40 and we have switched mode from 40 to 20 => don't update */ 1375 if ((flags & ATH9K_TX_RC_40_MHZ_WIDTH) && 1376 (ath_rc_priv->rc_phy_mode != WLAN_RC_40_FLAG)) { 1377 return; 1378 } 1379 1380 rix = ath_rc_get_rateindex(rate_table, &rates[i]); 1381 arn_rc_update_ht(sc, ath_rc_priv, tx_info_priv, rix, 1382 xretries, long_retry); 1383 } 1384 1385 static struct ath_rate_table * 1386 arn_choose_rate_table(struct arn_softc *sc, uint32_t cur_mode, 1387 boolean_t is_ht, boolean_t is_cw_40) 1388 { 1389 int ath9k_mode; 1390 switch (cur_mode) { 1391 case IEEE80211_MODE_11A: 1392 case IEEE80211_MODE_11NA: 1393 ath9k_mode = ATH9K_MODE_11A; 1394 if (is_ht) 1395 ath9k_mode = ATH9K_MODE_11NA_HT20; 1396 if (is_cw_40) 1397 ath9k_mode = ATH9K_MODE_11NA_HT40PLUS; 1398 break; 1399 case IEEE80211_MODE_11B: 1400 ath9k_mode = ATH9K_MODE_11B; 1401 break; 1402 case IEEE80211_MODE_11G: 1403 case IEEE80211_MODE_11NG: 1404 ath9k_mode = ATH9K_MODE_11G; 1405 if (is_ht) 1406 ath9k_mode = ATH9K_MODE_11NG_HT20; 1407 if (is_cw_40) 1408 ath9k_mode = ATH9K_MODE_11NG_HT40PLUS; 1409 break; 1410 default: 1411 ARN_DBG((ARN_DBG_RATE, "Invalid band\n")); 1412 return (NULL); 1413 } 1414 1415 switch (ath9k_mode) { 1416 case ATH9K_MODE_11A: 1417 ARN_DBG((ARN_DBG_RATE, "choose rate table:ATH9K_MODE_11A\n")); 1418 break; 1419 case ATH9K_MODE_11B: 1420 ARN_DBG((ARN_DBG_RATE, "choose rate table:ATH9K_MODE_11B\n")); 1421 break; 1422 case ATH9K_MODE_11G: 1423 ARN_DBG((ARN_DBG_RATE, "choose rate table:ATH9K_MODE_11G\n")); 1424 break; 1425 case ATH9K_MODE_11NA_HT20: 1426 ARN_DBG((ARN_DBG_RATE, 1427 "choose rate table:ATH9K_MODE_11NA_HT20\n")); 1428 break; 1429 case ATH9K_MODE_11NA_HT40PLUS: 1430 ARN_DBG((ARN_DBG_RATE, 1431 "choose rate table:ATH9K_MODE_11NA_HT40PLUS\n")); 1432 break; 1433 case ATH9K_MODE_11NG_HT20: 1434 ARN_DBG((ARN_DBG_RATE, 1435 "choose rate table:ATH9K_MODE_11NG_HT20\n")); 1436 break; 1437 case ATH9K_MODE_11NG_HT40PLUS: 1438 ARN_DBG((ARN_DBG_RATE, 1439 "choose rate table:ATH9K_MODE_11NG_HT40PLUS\n")); 1440 break; 1441 default: 1442 arn_problem("Invalid band\n"); 1443 break; 1444 } 1445 1446 ARN_DBG((ARN_DBG_RATE, "Choosing rate table for mode: %d\n", 1447 ath9k_mode)); 1448 return (sc->hw_rate_table[ath9k_mode]); 1449 } 1450 1451 /* Private rate contral initialization */ 1452 static void 1453 arn_rc_init(struct arn_softc *sc, 1454 struct ath_rate_priv *ath_rc_priv, 1455 struct ieee80211_node *in) 1456 { 1457 struct ath_rate_table *rate_table = NULL; 1458 struct ath_rateset *rateset = &ath_rc_priv->neg_rates; 1459 ieee80211com_t *ic = (ieee80211com_t *)sc; 1460 uint32_t cur_mode = ic->ic_curmode; 1461 uint8_t *ht_mcs = (uint8_t *)&ath_rc_priv->neg_ht_rates; 1462 uint8_t i, j, k, hi = 0, hthi = 0; 1463 boolean_t is_rc_ds; 1464 1465 /* FIXME: Adhoc */ 1466 if ((sc->sc_ah->ah_opmode == ATH9K_M_STA) || 1467 (sc->sc_ah->ah_opmode == ATH9K_M_IBSS)) { 1468 boolean_t is_ht = in->in_flags & IEEE80211_NODE_HT; 1469 /* 20/40 support */ 1470 boolean_t is_cw_40 = 1471 in->in_htcap & IEEE80211_HTCAP_CHWIDTH40; 1472 rate_table = 1473 arn_choose_rate_table(sc, cur_mode, is_ht, is_cw_40); 1474 } else if (sc->sc_ah->ah_opmode == ATH9K_M_HOSTAP) { 1475 /* cur_rate_table would be set on init */ 1476 rate_table = sc->sc_currates; 1477 } 1478 1479 if (!rate_table) { 1480 ARN_DBG((ARN_DBG_FATAL, "Rate table not initialized\n")); 1481 return; 1482 } 1483 1484 if (in->in_flags & IEEE80211_NODE_HT) { 1485 /* 2.6.30 */ 1486 ath_rc_priv->ht_cap = WLAN_RC_HT_FLAG; 1487 is_rc_ds = (AR_SREV_9280_20_OR_LATER(sc->sc_ah) && 1488 (ath9k_hw_get_eeprom(sc->sc_ah, EEP_RC_CHAIN_MASK) == 1)) ? 1489 B_FALSE: B_TRUE; 1490 if (sc->sc_ah->ah_caps.tx_chainmask != 1 && is_rc_ds) { 1491 if (sc->sc_ht_conf.rx_mcs_mask[1]) { 1492 ath_rc_priv->ht_cap |= WLAN_RC_DS_FLAG; 1493 } 1494 } 1495 1496 if (in->in_htcap & IEEE80211_HTCAP_CHWIDTH40) 1497 ath_rc_priv->ht_cap |= WLAN_RC_40_FLAG; 1498 if (in->in_htcap & IEEE80211_HTCAP_SHORTGI40) 1499 ath_rc_priv->ht_cap |= WLAN_RC_SGI_FLAG; 1500 } 1501 1502 /* 1503 * Initial rate table size. Will change depending 1504 * on the working rate set 1505 */ 1506 ath_rc_priv->rate_table_size = RATE_TABLE_SIZE; 1507 1508 /* Initialize thresholds according to the global rate table */ 1509 for (i = 0; i < ath_rc_priv->rate_table_size; i++) { 1510 ath_rc_priv->state[i].rssi_thres = 1511 rate_table->info[i].rssi_ack_validmin; 1512 ath_rc_priv->state[i].per = 0; 1513 } 1514 1515 /* Determine the valid rates */ 1516 arn_rc_init_valid_txmask(ath_rc_priv); 1517 1518 for (i = 0; i < WLAN_RC_PHY_MAX; i++) { 1519 for (j = 0; j < MAX_TX_RATE_PHY; j++) 1520 ath_rc_priv->valid_phy_rateidx[i][j] = 0; 1521 ath_rc_priv->valid_phy_ratecnt[i] = 0; 1522 } 1523 ath_rc_priv->rc_phy_mode = (ath_rc_priv->ht_cap & WLAN_RC_40_FLAG); 1524 1525 /* Set stream capability */ 1526 ath_rc_priv->single_stream = 1527 (ath_rc_priv->ht_cap & WLAN_RC_DS_FLAG) ? 0 : 1; 1528 1529 if (!rateset->rs_nrates) { 1530 /* No working rate, just initialize valid rates */ 1531 hi = arn_rc_init_validrates(ath_rc_priv, rate_table, 1532 ath_rc_priv->ht_cap); 1533 } else { 1534 /* Use intersection of working rates and valid rates */ 1535 hi = arn_rc_setvalid_rates(ath_rc_priv, rate_table, 1536 rateset, ath_rc_priv->ht_cap); 1537 if (ath_rc_priv->ht_cap & WLAN_RC_HT_FLAG) { 1538 hthi = arn_rc_setvalid_htrates(ath_rc_priv, 1539 rate_table, 1540 ht_mcs, 1541 ath_rc_priv->ht_cap); 1542 } 1543 hi = A_MAX(hi, hthi); 1544 } 1545 1546 ath_rc_priv->rate_table_size = hi + 1; 1547 ath_rc_priv->rate_max_phy = 0; 1548 ASSERT(ath_rc_priv->rate_table_size <= RATE_TABLE_SIZE); 1549 1550 for (i = 0, k = 0; i < WLAN_RC_PHY_MAX; i++) { 1551 for (j = 0; j < ath_rc_priv->valid_phy_ratecnt[i]; j++) { 1552 ath_rc_priv->valid_rate_index[k++] = 1553 ath_rc_priv->valid_phy_rateidx[i][j]; 1554 } 1555 1556 if (!arn_rc_valid_phyrate(i, rate_table->initial_ratemax, 1) || 1557 !ath_rc_priv->valid_phy_ratecnt[i]) 1558 continue; 1559 1560 ath_rc_priv->rate_max_phy = 1561 ath_rc_priv->valid_phy_rateidx[i][j-1]; 1562 } 1563 ASSERT(ath_rc_priv->rate_table_size <= RATE_TABLE_SIZE); 1564 ASSERT(k <= RATE_TABLE_SIZE); 1565 1566 ath_rc_priv->max_valid_rate = k; 1567 arn_rc_sort_validrates(rate_table, ath_rc_priv); 1568 ath_rc_priv->rate_max_phy = ath_rc_priv->valid_rate_index[k-4]; 1569 sc->sc_currates = rate_table; 1570 } 1571 1572 void 1573 arn_tx_status(struct arn_softc *sc, struct ath_buf *bf, boolean_t is_data) 1574 { 1575 struct ieee80211_node *in = (struct ieee80211_node *)(bf->bf_in); 1576 struct ath_node *an = ATH_NODE(in); 1577 struct ath_rate_priv *ath_rc_priv = 1578 (struct ath_rate_priv *)&an->rate_priv; 1579 struct ath_tx_info_priv *tx_info_priv = 1580 (struct ath_tx_info_priv *)&bf->tx_info_priv; 1581 int final_ts_idx, tx_status = 0, is_underrun = 0; 1582 1583 final_ts_idx = tx_info_priv->tx.ts_rateindex; 1584 1585 if (!is_data || !tx_info_priv->update_rc) 1586 return; 1587 1588 if (tx_info_priv->tx.ts_status & ATH9K_TXERR_FILT) 1589 return; 1590 1591 /* 1592 * If underrun error is seen assume it as an excessive retry only 1593 * if prefetch trigger level have reached the max (0x3f for 5416) 1594 * Adjust the long retry as if the frame was tried ATH_11N_TXMAXTRY 1595 * times. This affects how ratectrl updates PER for the failed rate. 1596 */ 1597 if (tx_info_priv->tx.ts_flags & 1598 (ATH9K_TX_DATA_UNDERRUN | ATH9K_TX_DELIM_UNDERRUN) && 1599 ((sc->sc_ah->ah_txTrigLevel) >= ath_rc_priv->tx_triglevel_max)) { 1600 tx_status = 1; 1601 is_underrun = 1; 1602 } 1603 1604 if ((tx_info_priv->tx.ts_status & ATH9K_TXERR_XRETRY) || 1605 (tx_info_priv->tx.ts_status & ATH9K_TXERR_FIFO)) 1606 tx_status = 1; 1607 1608 ath_rc_tx_status(sc, 1609 ath_rc_priv, 1610 bf, 1611 final_ts_idx, 1612 tx_status, 1613 (is_underrun) ? ATH_11N_TXMAXTRY : tx_info_priv->tx.ts_longretry); 1614 } 1615 1616 void 1617 arn_get_rate(struct arn_softc *sc, struct ath_buf *bf, 1618 struct ieee80211_frame *wh) 1619 { 1620 struct ieee80211_node *in = (struct ieee80211_node *)(bf->bf_in); 1621 struct ath_node *an = ATH_NODE(in); 1622 struct ath_rate_priv *ath_rc_priv = 1623 (struct ath_rate_priv *)&an->rate_priv; 1624 struct ath_rate_table *rt = sc->sc_currates; 1625 ieee80211com_t *ic = (ieee80211com_t *)sc; 1626 int is_probe = 0; 1627 uint8_t i; 1628 1629 /* lowest rate for management and multicast/broadcast frames */ 1630 if (!IEEE80211_IS_DATA(wh) || IEEE80211_IS_MULTICAST(wh->i_addr1)) { 1631 bf->rates[0].idx = 0; /* xxx Fix me */ 1632 bf->rates[0].count = 1633 IEEE80211_IS_MULTICAST(wh->i_addr1) ? 1634 1 : ATH_MGT_TXMAXTRY; 1635 return; 1636 } 1637 1638 /* Find tx rate for unicast frames */ 1639 arn_rc_ratefind(sc, ath_rc_priv, bf, ATH_11N_TXMAXTRY, 4, 1640 &is_probe, B_FALSE); 1641 1642 /* Temporary workaround for 'dladm show-wifi' */ 1643 for (i = 0; i < in->in_rates.ir_nrates; i++) { 1644 ARN_DBG((ARN_DBG_RATE, "arn: arn_get_rate(): " 1645 "in->in_rates.ir_rates[%d] = %d," 1646 "bf->rates[0].idx = %d," 1647 "rt->info[bf->rates[0].idx].dot11rate = %d\n", 1648 i, 1649 in->in_rates.ir_rates[i], 1650 bf->rates[0].idx, 1651 rt->info[bf->rates[0].idx].dot11rate)); 1652 if (rt->info[bf->rates[0].idx].dot11rate == 1653 in->in_rates.ir_rates[i]) 1654 break; 1655 } 1656 in->in_txrate = i; 1657 if (ic->ic_curmode == IEEE80211_MODE_11NA || 1658 ic->ic_curmode == IEEE80211_MODE_11NG) 1659 in->in_txrate = in->in_rates.ir_nrates - 1; 1660 1661 /* Check if aggregation has to be enabled for this tid */ 1662 #ifdef ARN_TX_AGGREGATION 1663 /* should check if enabled, not supported */ 1664 if (sc->sc_ht_conf.ht_supported) { 1665 if (ieee80211_is_data_qos(wh)) { 1666 uint8_t *qc, tid; 1667 struct ath_node *an; 1668 struct ieee80211_qosframe *qwh = NULL; 1669 1670 qwh = (struct ieee80211_qosframe *)wh; 1671 tid = qc[0] & 0xf; 1672 an = (struct ath_node *)sta->drv_priv; 1673 1674 if (arn_tx_aggr_check(sc, an, tid)) 1675 /* to do */ 1676 } 1677 } 1678 #endif /* ARN_TX_AGGREGATION */ 1679 } 1680 1681 void 1682 arn_rate_init(struct arn_softc *sc, struct ieee80211_node *in) 1683 { 1684 int i; 1685 struct ath_node *an = ATH_NODE(in); 1686 struct ath_rate_priv *ath_rc_priv = 1687 (struct ath_rate_priv *)&an->rate_priv; 1688 1689 /* should be moved to arn_node_init later */ 1690 ath_rc_priv->rssi_down_time = 1691 drv_hztousec(ddi_get_lbolt())/1000; /* mesc */ 1692 ath_rc_priv->tx_triglevel_max = 1693 sc->sc_ah->ah_caps.tx_triglevel_max; 1694 1695 for (i = 0; i < in->in_rates.ir_nrates; i++) { 1696 ath_rc_priv->neg_rates.rs_rates[i] = in->in_rates.ir_rates[i]; 1697 ARN_DBG((ARN_DBG_RATE, "arn:arn_rate_init()" 1698 "ath_rc_priv->neg_rates.rs_rates[%d] = %d\n", 1699 i, ath_rc_priv->neg_rates.rs_rates[i])); 1700 } 1701 ath_rc_priv->neg_rates.rs_nrates = in->in_rates.ir_nrates; 1702 1703 /* negotiated ht rate set ??? */ 1704 if (in->in_flags & IEEE80211_NODE_HT) { 1705 for (i = 0; i < in->in_htrates.rs_nrates; i++) { 1706 ath_rc_priv->neg_ht_rates.rs_rates[i] = 1707 in->in_htrates.rs_rates[i]; 1708 ARN_DBG((ARN_DBG_RATE, "arn:arn_rate_init()" 1709 "ath_rc_priv->neg_ht_rates.rs_rates[%d] = %d\n", 1710 i, ath_rc_priv->neg_ht_rates.rs_rates[i])); 1711 } 1712 ath_rc_priv->neg_ht_rates.rs_nrates = in->in_htrates.rs_nrates; 1713 1714 /* arn_update_chainmask(sc); */ 1715 } 1716 1717 #ifdef ARN_TX_AGGREGATION 1718 /* Temply put the following ht info init here */ 1719 uint8_t ampdu_factor, ampdu_density; 1720 if (sc->sc_ht_conf.ht_support && 1721 (in->in_htcap_ie != NULL) && 1722 (in->in_htcap != 0) && 1723 (in->in_htparam != 0)) { 1724 ampdu_factor = in->in_htparam & HT_RX_AMPDU_FACTOR_MSK; 1725 ampdu_density = (in->in_htparam & HT_MPDU_DENSITY_MSK) >> 1726 HT_MPDU_DENSITY_POS; 1727 an->maxampdu = 1728 1 << (IEEE80211_HTCAP_MAXRXAMPDU_FACTOR + ampdu_factor); 1729 an->mpdudensity = parse_mpdudensity(ampdu_density); 1730 } 1731 /* end */ 1732 #endif /* ARN_TX_AGGREGATION */ 1733 1734 arn_rc_init(sc, ath_rc_priv, in); 1735 } 1736 1737 static void 1738 arn_setup_rate_table(struct arn_softc *sc, 1739 struct ath_rate_table *rate_table) 1740 { 1741 int i; 1742 1743 for (i = 0; i < 256; i++) 1744 rate_table->rateCodeToIndex[i] = (uint8_t)-1; 1745 1746 for (i = 0; i < rate_table->rate_cnt; i++) { 1747 uint8_t code = rate_table->info[i].ratecode; 1748 uint8_t cix = rate_table->info[i].ctrl_rate; 1749 uint8_t sh = rate_table->info[i].short_preamble; 1750 1751 rate_table->rateCodeToIndex[code] = (int)i; 1752 rate_table->rateCodeToIndex[code | sh] = (int)i; 1753 1754 rate_table->info[i].lpAckDuration = 1755 ath9k_hw_computetxtime(sc->sc_ah, rate_table, 1756 WLAN_CTRL_FRAME_SIZE, 1757 cix, 1758 B_FALSE); 1759 rate_table->info[i].spAckDuration = 1760 ath9k_hw_computetxtime(sc->sc_ah, rate_table, 1761 WLAN_CTRL_FRAME_SIZE, 1762 cix, 1763 B_TRUE); 1764 } 1765 } 1766 1767 void 1768 arn_rate_attach(struct arn_softc *sc) 1769 { 1770 sc->hw_rate_table[ATH9K_MODE_11B] = 1771 &ar5416_11b_ratetable; 1772 sc->hw_rate_table[ATH9K_MODE_11A] = 1773 &ar5416_11a_ratetable; 1774 sc->hw_rate_table[ATH9K_MODE_11G] = 1775 &ar5416_11g_ratetable; 1776 sc->hw_rate_table[ATH9K_MODE_11NA_HT20] = 1777 &ar5416_11na_ratetable; 1778 sc->hw_rate_table[ATH9K_MODE_11NG_HT20] = 1779 &ar5416_11ng_ratetable; 1780 sc->hw_rate_table[ATH9K_MODE_11NA_HT40PLUS] = 1781 &ar5416_11na_ratetable; 1782 sc->hw_rate_table[ATH9K_MODE_11NA_HT40MINUS] = 1783 &ar5416_11na_ratetable; 1784 sc->hw_rate_table[ATH9K_MODE_11NG_HT40PLUS] = 1785 &ar5416_11ng_ratetable; 1786 sc->hw_rate_table[ATH9K_MODE_11NG_HT40MINUS] = 1787 &ar5416_11ng_ratetable; 1788 1789 arn_setup_rate_table(sc, &ar5416_11b_ratetable); 1790 arn_setup_rate_table(sc, &ar5416_11a_ratetable); 1791 arn_setup_rate_table(sc, &ar5416_11g_ratetable); 1792 arn_setup_rate_table(sc, &ar5416_11na_ratetable); 1793 arn_setup_rate_table(sc, &ar5416_11ng_ratetable); 1794 } 1795 1796 #ifdef ARN_LEGACY_RC 1797 void 1798 arn_rate_update(struct arn_softc *sc, struct ieee80211_node *in, int32_t rate) 1799 { 1800 struct ath_node *an = ATH_NODE(in); 1801 const struct ath_rate_table *rt = sc->sc_currates; 1802 uint8_t rix; 1803 1804 ASSERT(rt != NULL); 1805 1806 in->in_txrate = rate; 1807 1808 /* management/control frames always go at the lowest speed */ 1809 an->an_tx_mgtrate = rt->info[0].ratecode; 1810 an->an_tx_mgtratesp = an->an_tx_mgtrate | rt->info[0].short_preamble; 1811 1812 ARN_DBG((ARN_DBG_RATE, "arn: arn_rate_update(): " 1813 "mgtrate=%d mgtratesp=%d\n", 1814 an->an_tx_mgtrate, an->an_tx_mgtratesp)); 1815 1816 /* 1817 * Before associating a node has no rate set setup 1818 * so we can't calculate any transmit codes to use. 1819 * This is ok since we should never be sending anything 1820 * but management frames and those always go at the 1821 * lowest hardware rate. 1822 */ 1823 if (in->in_rates.ir_nrates == 0) 1824 goto done; 1825 an->an_tx_rix0 = sc->asc_rixmap[ 1826 in->in_rates.ir_rates[rate] & IEEE80211_RATE_VAL]; 1827 an->an_tx_rate0 = rt->info[an->an_tx_rix0].ratecode; 1828 an->an_tx_rate0sp = an->an_tx_rate0 | 1829 rt->info[an->an_tx_rix0].short_preamble; 1830 if (sc->sc_mrretry) { 1831 /* 1832 * Hardware supports multi-rate retry; setup two 1833 * step-down retry rates and make the lowest rate 1834 * be the ``last chance''. We use 4, 2, 2, 2 tries 1835 * respectively (4 is set here, the rest are fixed 1836 * in the xmit routine). 1837 */ 1838 an->an_tx_try0 = 1 + 3; /* 4 tries at rate 0 */ 1839 if (--rate >= 0) { 1840 rix = sc->asc_rixmap[ 1841 in->in_rates.ir_rates[rate]&IEEE80211_RATE_VAL]; 1842 an->an_tx_rate1 = rt->info[rix].ratecode; 1843 an->an_tx_rate1sp = an->an_tx_rate1 | 1844 rt->info[rix].short_preamble; 1845 } else { 1846 an->an_tx_rate1 = an->an_tx_rate1sp = 0; 1847 } 1848 if (--rate >= 0) { 1849 rix = sc->asc_rixmap[ 1850 in->in_rates.ir_rates[rate]&IEEE80211_RATE_VAL]; 1851 an->an_tx_rate2 = rt->info[rix].ratecode; 1852 an->an_tx_rate2sp = an->an_tx_rate2 | 1853 rt->info[rix].short_preamble; 1854 } else { 1855 an->an_tx_rate2 = an->an_tx_rate2sp = 0; 1856 } 1857 if (rate > 0) { 1858 an->an_tx_rate3 = rt->info[0].ratecode; 1859 an->an_tx_rate3sp = 1860 an->an_tx_mgtrate | rt->info[0].short_preamble; 1861 } else { 1862 an->an_tx_rate3 = an->an_tx_rate3sp = 0; 1863 } 1864 } else { 1865 an->an_tx_try0 = ATH_TXMAXTRY; /* max tries at rate 0 */ 1866 an->an_tx_rate1 = an->an_tx_rate1sp = 0; 1867 an->an_tx_rate2 = an->an_tx_rate2sp = 0; 1868 an->an_tx_rate3 = an->an_tx_rate3sp = 0; 1869 } 1870 done: 1871 an->an_tx_ok = an->an_tx_err = an->an_tx_retr = an->an_tx_upper = 0; 1872 } 1873 1874 /* 1875 * Set the starting transmit rate for a node. 1876 */ 1877 void 1878 arn_rate_ctl_start(struct arn_softc *sc, struct ieee80211_node *in) 1879 { 1880 ieee80211com_t *ic = (ieee80211com_t *)sc; 1881 int32_t srate; 1882 1883 if (ic->ic_fixed_rate == IEEE80211_FIXED_RATE_NONE) { 1884 /* 1885 * No fixed rate is requested. For 11b start with 1886 * the highest negotiated rate; otherwise, for 11g 1887 * and 11a, we start "in the middle" at 24Mb or 36Mb. 1888 */ 1889 srate = in->in_rates.ir_nrates - 1; 1890 if (sc->sc_curmode != IEEE80211_MODE_11B) { 1891 /* 1892 * Scan the negotiated rate set to find the 1893 * closest rate. 1894 */ 1895 /* NB: the rate set is assumed sorted */ 1896 for (; srate >= 0 && IEEE80211_RATE(srate) > 72; 1897 srate--) {} 1898 } 1899 } else { 1900 /* 1901 * A fixed rate is to be used; We know the rate is 1902 * there because the rate set is checked when the 1903 * station associates. 1904 */ 1905 /* NB: the rate set is assumed sorted */ 1906 srate = in->in_rates.ir_nrates - 1; 1907 for (; srate >= 0 && IEEE80211_RATE(srate) != ic->ic_fixed_rate; 1908 srate--) {} 1909 } 1910 1911 ARN_DBG((ARN_DBG_RATE, "arn: arn_rate_ctl_start(): " 1912 "srate=%d rate=%d\n", srate, IEEE80211_RATE(srate))); 1913 1914 arn_rate_update(sc, in, srate); 1915 } 1916 1917 void 1918 arn_rate_cb(void *arg, struct ieee80211_node *in) 1919 { 1920 arn_rate_update((struct arn_softc *)arg, in, 0); 1921 } 1922 #endif /* ARN_LEGACY_RC */ 1923 /* 1924 * Reset the rate control state for each 802.11 state transition. 1925 */ 1926 void 1927 arn_rate_ctl_reset(struct arn_softc *sc, enum ieee80211_state state) 1928 { 1929 ieee80211com_t *ic = (ieee80211com_t *)sc; 1930 struct ieee80211_node *in; 1931 1932 if (ic->ic_opmode == IEEE80211_M_STA) { 1933 /* 1934 * Reset local xmit state; this is really only 1935 * meaningful when operating in station mode. 1936 */ 1937 in = (struct ieee80211_node *)ic->ic_bss; 1938 1939 #ifdef ARN_LEGACY_RC 1940 if (state == IEEE80211_S_RUN) { 1941 arn_rate_ctl_start(sc, in); 1942 } else { 1943 arn_rate_update(sc, in, 0); 1944 } 1945 #else 1946 if (state == IEEE80211_S_RUN) 1947 arn_rate_init(sc, in); 1948 #endif 1949 /* LINTED E_NOP_ELSE_STMT */ 1950 } else { 1951 /* 1952 * When operating as a station the node table holds 1953 * the AP's that were discovered during scanning. 1954 * For any other operating mode we want to reset the 1955 * tx rate state of each node. 1956 */ 1957 #ifdef ARN_LEGACY_RC 1958 ieee80211_iterate_nodes(&ic->ic_sta, arn_rate_cb, sc); 1959 #endif 1960 } 1961 } 1962 1963 #ifdef ARN_LEGACY_RC 1964 /* 1965 * Examine and potentially adjust the transmit rate. 1966 */ 1967 void 1968 arn_rate_ctl(void *arg, struct ieee80211_node *in) 1969 { 1970 struct arn_softc *sc = arg; 1971 struct ath_node *an = ATH_NODE(in); 1972 struct ieee80211_rateset *rs = &in->in_rates; 1973 int32_t mod = 0, nrate, enough; 1974 1975 /* 1976 * Rate control(very primitive version). 1977 */ 1978 sc->sc_stats.ast_rate_calls++; 1979 1980 enough = (an->an_tx_ok + an->an_tx_err >= 10); 1981 1982 /* no packet reached -> down */ 1983 if (an->an_tx_err > 0 && an->an_tx_ok == 0) 1984 mod = -1; 1985 1986 /* all packets needs retry in average -> down */ 1987 if (enough && an->an_tx_ok < an->an_tx_retr) 1988 mod = -1; 1989 1990 /* no error and less than 10% of packets needs retry -> up */ 1991 if (enough && an->an_tx_err == 0 && an->an_tx_ok > an->an_tx_retr * 10) 1992 mod = 1; 1993 1994 nrate = in->in_txrate; 1995 switch (mod) { 1996 case 0: 1997 if (enough && an->an_tx_upper > 0) 1998 an->an_tx_upper--; 1999 break; 2000 case -1: 2001 if (nrate > 0) { 2002 nrate--; 2003 sc->sc_stats.ast_rate_drop++; 2004 } 2005 an->an_tx_upper = 0; 2006 break; 2007 case 1: 2008 if (++an->an_tx_upper < 10) 2009 break; 2010 an->an_tx_upper = 0; 2011 if (nrate + 1 < rs->ir_nrates) { 2012 nrate++; 2013 sc->sc_stats.ast_rate_raise++; 2014 } 2015 break; 2016 } 2017 2018 if (nrate != in->in_txrate) { 2019 ARN_DBG((ARN_DBG_RATE, "arn: arn_rate_ctl(): %dM -> %dM " 2020 "(%d ok, %d err, %d retr)\n", 2021 (rs->ir_rates[in->in_txrate] & IEEE80211_RATE_VAL) / 2, 2022 (rs->ir_rates[nrate] & IEEE80211_RATE_VAL) / 2, 2023 an->an_tx_ok, an->an_tx_err, an->an_tx_retr)); 2024 arn_rate_update(sc, in, nrate); 2025 } else if (enough) 2026 an->an_tx_ok = an->an_tx_err = an->an_tx_retr = 0; 2027 } 2028 #endif /* ARN_LEGACY_RC */ 2029