1/* 2 * Copyright (c) 2010 Atheros Communications Inc. 3 * 4 * Permission to use, copy, modify, and/or distribute this software for any 5 * purpose with or without fee is hereby granted, provided that the above 6 * copyright notice and this permission notice appear in all copies. 7 * 8 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 9 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 10 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 11 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 12 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 13 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 14 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 15 */ 16 17#include "hw.h" 18#include "ar9003_phy.h" 19#include "ar9003_eeprom.h" 20 21#define COMP_HDR_LEN 4 22#define COMP_CKSUM_LEN 2 23 24#define AR_CH0_TOP (0x00016288) 25#define AR_CH0_TOP_XPABIASLVL (0x300) 26#define AR_CH0_TOP_XPABIASLVL_S (8) 27 28#define AR_CH0_THERM (0x00016290) 29#define AR_CH0_THERM_XPABIASLVL_MSB 0x3 30#define AR_CH0_THERM_XPABIASLVL_MSB_S 0 31#define AR_CH0_THERM_XPASHORT2GND 0x4 32#define AR_CH0_THERM_XPASHORT2GND_S 2 33 34#define AR_SWITCH_TABLE_COM_ALL (0xffff) 35#define AR_SWITCH_TABLE_COM_ALL_S (0) 36 37#define AR_SWITCH_TABLE_COM2_ALL (0xffffff) 38#define AR_SWITCH_TABLE_COM2_ALL_S (0) 39 40#define AR_SWITCH_TABLE_ALL (0xfff) 41#define AR_SWITCH_TABLE_ALL_S (0) 42 43#define LE16(x) __constant_cpu_to_le16(x) 44#define LE32(x) __constant_cpu_to_le32(x) 45 46/* Local defines to distinguish between extension and control CTL's */ 47#define EXT_ADDITIVE (0x8000) 48#define CTL_11A_EXT (CTL_11A | EXT_ADDITIVE) 49#define CTL_11G_EXT (CTL_11G | EXT_ADDITIVE) 50#define CTL_11B_EXT (CTL_11B | EXT_ADDITIVE) 51#define REDUCE_SCALED_POWER_BY_TWO_CHAIN 6 /* 10*log10(2)*2 */ 52#define REDUCE_SCALED_POWER_BY_THREE_CHAIN 9 /* 10*log10(3)*2 */ 53#define PWRINCR_3_TO_1_CHAIN 9 /* 10*log(3)*2 */ 54#define PWRINCR_3_TO_2_CHAIN 3 /* floor(10*log(3/2)*2) */ 55#define PWRINCR_2_TO_1_CHAIN 6 /* 10*log(2)*2 */ 56 57#define SUB_NUM_CTL_MODES_AT_5G_40 2 /* excluding HT40, EXT-OFDM */ 58#define SUB_NUM_CTL_MODES_AT_2G_40 3 /* excluding HT40, EXT-OFDM, EXT-CCK */ 59 60#define CTL(_tpower, _flag) ((_tpower) | ((_flag) << 6)) 61 62static const struct ar9300_eeprom ar9300_default = { 63 .eepromVersion = 2, 64 .templateVersion = 2, 65 .macAddr = {1, 2, 3, 4, 5, 6}, 66 .custData = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 67 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 68 .baseEepHeader = { 69 .regDmn = { LE16(0), LE16(0x1f) }, 70 .txrxMask = 0x77, /* 4 bits tx and 4 bits rx */ 71 .opCapFlags = { 72 .opFlags = AR9300_OPFLAGS_11G | AR9300_OPFLAGS_11A, 73 .eepMisc = 0, 74 }, 75 .rfSilent = 0, 76 .blueToothOptions = 0, 77 .deviceCap = 0, 78 .deviceType = 5, /* takes lower byte in eeprom location */ 79 .pwrTableOffset = AR9300_PWR_TABLE_OFFSET, 80 .params_for_tuning_caps = {0, 0}, 81 .featureEnable = 0x0c, 82 /* 83 * bit0 - enable tx temp comp - disabled 84 * bit1 - enable tx volt comp - disabled 85 * bit2 - enable fastClock - enabled 86 * bit3 - enable doubling - enabled 87 * bit4 - enable internal regulator - disabled 88 * bit5 - enable pa predistortion - disabled 89 */ 90 .miscConfiguration = 0, /* bit0 - turn down drivestrength */ 91 .eepromWriteEnableGpio = 3, 92 .wlanDisableGpio = 0, 93 .wlanLedGpio = 8, 94 .rxBandSelectGpio = 0xff, 95 .txrxgain = 0, 96 .swreg = 0, 97 }, 98 .modalHeader2G = { 99 /* ar9300_modal_eep_header 2g */ 100 /* 4 idle,t1,t2,b(4 bits per setting) */ 101 .antCtrlCommon = LE32(0x110), 102 /* 4 ra1l1, ra2l1, ra1l2, ra2l2, ra12 */ 103 .antCtrlCommon2 = LE32(0x22222), 104 105 /* 106 * antCtrlChain[AR9300_MAX_CHAINS]; 6 idle, t, r, 107 * rx1, rx12, b (2 bits each) 108 */ 109 .antCtrlChain = { LE16(0x150), LE16(0x150), LE16(0x150) }, 110 111 /* 112 * xatten1DB[AR9300_MAX_CHAINS]; 3 xatten1_db 113 * for ar9280 (0xa20c/b20c 5:0) 114 */ 115 .xatten1DB = {0, 0, 0}, 116 117 /* 118 * xatten1Margin[AR9300_MAX_CHAINS]; 3 xatten1_margin 119 * for ar9280 (0xa20c/b20c 16:12 120 */ 121 .xatten1Margin = {0, 0, 0}, 122 .tempSlope = 36, 123 .voltSlope = 0, 124 125 /* 126 * spurChans[OSPREY_EEPROM_MODAL_SPURS]; spur 127 * channels in usual fbin coding format 128 */ 129 .spurChans = {0, 0, 0, 0, 0}, 130 131 /* 132 * noiseFloorThreshCh[AR9300_MAX_CHAINS]; 3 Check 133 * if the register is per chain 134 */ 135 .noiseFloorThreshCh = {-1, 0, 0}, 136 .ob = {1, 1, 1},/* 3 chain */ 137 .db_stage2 = {1, 1, 1}, /* 3 chain */ 138 .db_stage3 = {0, 0, 0}, 139 .db_stage4 = {0, 0, 0}, 140 .xpaBiasLvl = 0, 141 .txFrameToDataStart = 0x0e, 142 .txFrameToPaOn = 0x0e, 143 .txClip = 3, /* 4 bits tx_clip, 4 bits dac_scale_cck */ 144 .antennaGain = 0, 145 .switchSettling = 0x2c, 146 .adcDesiredSize = -30, 147 .txEndToXpaOff = 0, 148 .txEndToRxOn = 0x2, 149 .txFrameToXpaOn = 0xe, 150 .thresh62 = 28, 151 .papdRateMaskHt20 = LE32(0x80c080), 152 .papdRateMaskHt40 = LE32(0x80c080), 153 .futureModal = { 154 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 155 0, 0, 0, 0, 0, 0, 0, 0 156 }, 157 }, 158 .calFreqPier2G = { 159 FREQ2FBIN(2412, 1), 160 FREQ2FBIN(2437, 1), 161 FREQ2FBIN(2472, 1), 162 }, 163 /* ar9300_cal_data_per_freq_op_loop 2g */ 164 .calPierData2G = { 165 { {0, 0, 0, 0, 0, 0}, {0, 0, 0, 0, 0, 0}, {0, 0, 0, 0, 0, 0} }, 166 { {0, 0, 0, 0, 0, 0}, {0, 0, 0, 0, 0, 0}, {0, 0, 0, 0, 0, 0} }, 167 { {0, 0, 0, 0, 0, 0}, {0, 0, 0, 0, 0, 0}, {0, 0, 0, 0, 0, 0} }, 168 }, 169 .calTarget_freqbin_Cck = { 170 FREQ2FBIN(2412, 1), 171 FREQ2FBIN(2484, 1), 172 }, 173 .calTarget_freqbin_2G = { 174 FREQ2FBIN(2412, 1), 175 FREQ2FBIN(2437, 1), 176 FREQ2FBIN(2472, 1) 177 }, 178 .calTarget_freqbin_2GHT20 = { 179 FREQ2FBIN(2412, 1), 180 FREQ2FBIN(2437, 1), 181 FREQ2FBIN(2472, 1) 182 }, 183 .calTarget_freqbin_2GHT40 = { 184 FREQ2FBIN(2412, 1), 185 FREQ2FBIN(2437, 1), 186 FREQ2FBIN(2472, 1) 187 }, 188 .calTargetPowerCck = { 189 /* 1L-5L,5S,11L,11S */ 190 { {36, 36, 36, 36} }, 191 { {36, 36, 36, 36} }, 192 }, 193 .calTargetPower2G = { 194 /* 6-24,36,48,54 */ 195 { {32, 32, 28, 24} }, 196 { {32, 32, 28, 24} }, 197 { {32, 32, 28, 24} }, 198 }, 199 .calTargetPower2GHT20 = { 200 { {32, 32, 32, 32, 28, 20, 32, 32, 28, 20, 32, 32, 28, 20} }, 201 { {32, 32, 32, 32, 28, 20, 32, 32, 28, 20, 32, 32, 28, 20} }, 202 { {32, 32, 32, 32, 28, 20, 32, 32, 28, 20, 32, 32, 28, 20} }, 203 }, 204 .calTargetPower2GHT40 = { 205 { {32, 32, 32, 32, 28, 20, 32, 32, 28, 20, 32, 32, 28, 20} }, 206 { {32, 32, 32, 32, 28, 20, 32, 32, 28, 20, 32, 32, 28, 20} }, 207 { {32, 32, 32, 32, 28, 20, 32, 32, 28, 20, 32, 32, 28, 20} }, 208 }, 209 .ctlIndex_2G = { 210 0x11, 0x12, 0x15, 0x17, 0x41, 0x42, 211 0x45, 0x47, 0x31, 0x32, 0x35, 0x37, 212 }, 213 .ctl_freqbin_2G = { 214 { 215 FREQ2FBIN(2412, 1), 216 FREQ2FBIN(2417, 1), 217 FREQ2FBIN(2457, 1), 218 FREQ2FBIN(2462, 1) 219 }, 220 { 221 FREQ2FBIN(2412, 1), 222 FREQ2FBIN(2417, 1), 223 FREQ2FBIN(2462, 1), 224 0xFF, 225 }, 226 227 { 228 FREQ2FBIN(2412, 1), 229 FREQ2FBIN(2417, 1), 230 FREQ2FBIN(2462, 1), 231 0xFF, 232 }, 233 { 234 FREQ2FBIN(2422, 1), 235 FREQ2FBIN(2427, 1), 236 FREQ2FBIN(2447, 1), 237 FREQ2FBIN(2452, 1) 238 }, 239 240 { 241 /* Data[4].ctlEdges[0].bChannel */ FREQ2FBIN(2412, 1), 242 /* Data[4].ctlEdges[1].bChannel */ FREQ2FBIN(2417, 1), 243 /* Data[4].ctlEdges[2].bChannel */ FREQ2FBIN(2472, 1), 244 /* Data[4].ctlEdges[3].bChannel */ FREQ2FBIN(2484, 1), 245 }, 246 247 { 248 /* Data[5].ctlEdges[0].bChannel */ FREQ2FBIN(2412, 1), 249 /* Data[5].ctlEdges[1].bChannel */ FREQ2FBIN(2417, 1), 250 /* Data[5].ctlEdges[2].bChannel */ FREQ2FBIN(2472, 1), 251 0, 252 }, 253 254 { 255 /* Data[6].ctlEdges[0].bChannel */ FREQ2FBIN(2412, 1), 256 /* Data[6].ctlEdges[1].bChannel */ FREQ2FBIN(2417, 1), 257 FREQ2FBIN(2472, 1), 258 0, 259 }, 260 261 { 262 /* Data[7].ctlEdges[0].bChannel */ FREQ2FBIN(2422, 1), 263 /* Data[7].ctlEdges[1].bChannel */ FREQ2FBIN(2427, 1), 264 /* Data[7].ctlEdges[2].bChannel */ FREQ2FBIN(2447, 1), 265 /* Data[7].ctlEdges[3].bChannel */ FREQ2FBIN(2462, 1), 266 }, 267 268 { 269 /* Data[8].ctlEdges[0].bChannel */ FREQ2FBIN(2412, 1), 270 /* Data[8].ctlEdges[1].bChannel */ FREQ2FBIN(2417, 1), 271 /* Data[8].ctlEdges[2].bChannel */ FREQ2FBIN(2472, 1), 272 }, 273 274 { 275 /* Data[9].ctlEdges[0].bChannel */ FREQ2FBIN(2412, 1), 276 /* Data[9].ctlEdges[1].bChannel */ FREQ2FBIN(2417, 1), 277 /* Data[9].ctlEdges[2].bChannel */ FREQ2FBIN(2472, 1), 278 0 279 }, 280 281 { 282 /* Data[10].ctlEdges[0].bChannel */ FREQ2FBIN(2412, 1), 283 /* Data[10].ctlEdges[1].bChannel */ FREQ2FBIN(2417, 1), 284 /* Data[10].ctlEdges[2].bChannel */ FREQ2FBIN(2472, 1), 285 0 286 }, 287 288 { 289 /* Data[11].ctlEdges[0].bChannel */ FREQ2FBIN(2422, 1), 290 /* Data[11].ctlEdges[1].bChannel */ FREQ2FBIN(2427, 1), 291 /* Data[11].ctlEdges[2].bChannel */ FREQ2FBIN(2447, 1), 292 /* Data[11].ctlEdges[3].bChannel */ 293 FREQ2FBIN(2462, 1), 294 } 295 }, 296 .ctlPowerData_2G = { 297 { { CTL(60, 0), CTL(60, 1), CTL(60, 0), CTL(60, 0) } }, 298 { { CTL(60, 0), CTL(60, 1), CTL(60, 0), CTL(60, 0) } }, 299 { { CTL(60, 1), CTL(60, 0), CTL(60, 0), CTL(60, 1) } }, 300 301 { { CTL(60, 1), CTL(60, 0), CTL(0, 0), CTL(0, 0) } }, 302 { { CTL(60, 0), CTL(60, 1), CTL(60, 0), CTL(60, 0) } }, 303 { { CTL(60, 0), CTL(60, 1), CTL(60, 0), CTL(60, 0) } }, 304 305 { { CTL(60, 0), CTL(60, 1), CTL(60, 1), CTL(60, 0) } }, 306 { { CTL(60, 0), CTL(60, 1), CTL(60, 0), CTL(60, 0) } }, 307 { { CTL(60, 0), CTL(60, 1), CTL(60, 0), CTL(60, 0) } }, 308 309 { { CTL(60, 0), CTL(60, 1), CTL(60, 0), CTL(60, 0) } }, 310 { { CTL(60, 0), CTL(60, 1), CTL(60, 1), CTL(60, 1) } }, 311 { { CTL(60, 0), CTL(60, 1), CTL(60, 1), CTL(60, 1) } }, 312 }, 313 .modalHeader5G = { 314 /* 4 idle,t1,t2,b (4 bits per setting) */ 315 .antCtrlCommon = LE32(0x110), 316 /* 4 ra1l1, ra2l1, ra1l2,ra2l2,ra12 */ 317 .antCtrlCommon2 = LE32(0x22222), 318 /* antCtrlChain 6 idle, t,r,rx1,rx12,b (2 bits each) */ 319 .antCtrlChain = { 320 LE16(0x000), LE16(0x000), LE16(0x000), 321 }, 322 /* xatten1DB 3 xatten1_db for AR9280 (0xa20c/b20c 5:0) */ 323 .xatten1DB = {0, 0, 0}, 324 325 /* 326 * xatten1Margin[AR9300_MAX_CHAINS]; 3 xatten1_margin 327 * for merlin (0xa20c/b20c 16:12 328 */ 329 .xatten1Margin = {0, 0, 0}, 330 .tempSlope = 68, 331 .voltSlope = 0, 332 /* spurChans spur channels in usual fbin coding format */ 333 .spurChans = {0, 0, 0, 0, 0}, 334 /* noiseFloorThreshCh Check if the register is per chain */ 335 .noiseFloorThreshCh = {-1, 0, 0}, 336 .ob = {3, 3, 3}, /* 3 chain */ 337 .db_stage2 = {3, 3, 3}, /* 3 chain */ 338 .db_stage3 = {3, 3, 3}, /* doesn't exist for 2G */ 339 .db_stage4 = {3, 3, 3}, /* don't exist for 2G */ 340 .xpaBiasLvl = 0, 341 .txFrameToDataStart = 0x0e, 342 .txFrameToPaOn = 0x0e, 343 .txClip = 3, /* 4 bits tx_clip, 4 bits dac_scale_cck */ 344 .antennaGain = 0, 345 .switchSettling = 0x2d, 346 .adcDesiredSize = -30, 347 .txEndToXpaOff = 0, 348 .txEndToRxOn = 0x2, 349 .txFrameToXpaOn = 0xe, 350 .thresh62 = 28, 351 .papdRateMaskHt20 = LE32(0xf0e0e0), 352 .papdRateMaskHt40 = LE32(0xf0e0e0), 353 .futureModal = { 354 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 355 0, 0, 0, 0, 0, 0, 0, 0 356 }, 357 }, 358 .calFreqPier5G = { 359 FREQ2FBIN(5180, 0), 360 FREQ2FBIN(5220, 0), 361 FREQ2FBIN(5320, 0), 362 FREQ2FBIN(5400, 0), 363 FREQ2FBIN(5500, 0), 364 FREQ2FBIN(5600, 0), 365 FREQ2FBIN(5725, 0), 366 FREQ2FBIN(5825, 0) 367 }, 368 .calPierData5G = { 369 { 370 {0, 0, 0, 0, 0}, 371 {0, 0, 0, 0, 0}, 372 {0, 0, 0, 0, 0}, 373 {0, 0, 0, 0, 0}, 374 {0, 0, 0, 0, 0}, 375 {0, 0, 0, 0, 0}, 376 {0, 0, 0, 0, 0}, 377 {0, 0, 0, 0, 0}, 378 }, 379 { 380 {0, 0, 0, 0, 0}, 381 {0, 0, 0, 0, 0}, 382 {0, 0, 0, 0, 0}, 383 {0, 0, 0, 0, 0}, 384 {0, 0, 0, 0, 0}, 385 {0, 0, 0, 0, 0}, 386 {0, 0, 0, 0, 0}, 387 {0, 0, 0, 0, 0}, 388 }, 389 { 390 {0, 0, 0, 0, 0}, 391 {0, 0, 0, 0, 0}, 392 {0, 0, 0, 0, 0}, 393 {0, 0, 0, 0, 0}, 394 {0, 0, 0, 0, 0}, 395 {0, 0, 0, 0, 0}, 396 {0, 0, 0, 0, 0}, 397 {0, 0, 0, 0, 0}, 398 }, 399 400 }, 401 .calTarget_freqbin_5G = { 402 FREQ2FBIN(5180, 0), 403 FREQ2FBIN(5220, 0), 404 FREQ2FBIN(5320, 0), 405 FREQ2FBIN(5400, 0), 406 FREQ2FBIN(5500, 0), 407 FREQ2FBIN(5600, 0), 408 FREQ2FBIN(5725, 0), 409 FREQ2FBIN(5825, 0) 410 }, 411 .calTarget_freqbin_5GHT20 = { 412 FREQ2FBIN(5180, 0), 413 FREQ2FBIN(5240, 0), 414 FREQ2FBIN(5320, 0), 415 FREQ2FBIN(5500, 0), 416 FREQ2FBIN(5700, 0), 417 FREQ2FBIN(5745, 0), 418 FREQ2FBIN(5725, 0), 419 FREQ2FBIN(5825, 0) 420 }, 421 .calTarget_freqbin_5GHT40 = { 422 FREQ2FBIN(5180, 0), 423 FREQ2FBIN(5240, 0), 424 FREQ2FBIN(5320, 0), 425 FREQ2FBIN(5500, 0), 426 FREQ2FBIN(5700, 0), 427 FREQ2FBIN(5745, 0), 428 FREQ2FBIN(5725, 0), 429 FREQ2FBIN(5825, 0) 430 }, 431 .calTargetPower5G = { 432 /* 6-24,36,48,54 */ 433 { {20, 20, 20, 10} }, 434 { {20, 20, 20, 10} }, 435 { {20, 20, 20, 10} }, 436 { {20, 20, 20, 10} }, 437 { {20, 20, 20, 10} }, 438 { {20, 20, 20, 10} }, 439 { {20, 20, 20, 10} }, 440 { {20, 20, 20, 10} }, 441 }, 442 .calTargetPower5GHT20 = { 443 /* 444 * 0_8_16,1-3_9-11_17-19, 445 * 4,5,6,7,12,13,14,15,20,21,22,23 446 */ 447 { {20, 20, 10, 10, 0, 0, 10, 10, 0, 0, 10, 10, 0, 0} }, 448 { {20, 20, 10, 10, 0, 0, 10, 10, 0, 0, 10, 10, 0, 0} }, 449 { {20, 20, 10, 10, 0, 0, 10, 10, 0, 0, 10, 10, 0, 0} }, 450 { {20, 20, 10, 10, 0, 0, 10, 10, 0, 0, 10, 10, 0, 0} }, 451 { {20, 20, 10, 10, 0, 0, 10, 10, 0, 0, 10, 10, 0, 0} }, 452 { {20, 20, 10, 10, 0, 0, 10, 10, 0, 0, 10, 10, 0, 0} }, 453 { {20, 20, 10, 10, 0, 0, 10, 10, 0, 0, 10, 10, 0, 0} }, 454 { {20, 20, 10, 10, 0, 0, 10, 10, 0, 0, 10, 10, 0, 0} }, 455 }, 456 .calTargetPower5GHT40 = { 457 /* 458 * 0_8_16,1-3_9-11_17-19, 459 * 4,5,6,7,12,13,14,15,20,21,22,23 460 */ 461 { {20, 20, 10, 10, 0, 0, 10, 10, 0, 0, 10, 10, 0, 0} }, 462 { {20, 20, 10, 10, 0, 0, 10, 10, 0, 0, 10, 10, 0, 0} }, 463 { {20, 20, 10, 10, 0, 0, 10, 10, 0, 0, 10, 10, 0, 0} }, 464 { {20, 20, 10, 10, 0, 0, 10, 10, 0, 0, 10, 10, 0, 0} }, 465 { {20, 20, 10, 10, 0, 0, 10, 10, 0, 0, 10, 10, 0, 0} }, 466 { {20, 20, 10, 10, 0, 0, 10, 10, 0, 0, 10, 10, 0, 0} }, 467 { {20, 20, 10, 10, 0, 0, 10, 10, 0, 0, 10, 10, 0, 0} }, 468 { {20, 20, 10, 10, 0, 0, 10, 10, 0, 0, 10, 10, 0, 0} }, 469 }, 470 .ctlIndex_5G = { 471 0x10, 0x16, 0x18, 0x40, 0x46, 472 0x48, 0x30, 0x36, 0x38 473 }, 474 .ctl_freqbin_5G = { 475 { 476 /* Data[0].ctlEdges[0].bChannel */ FREQ2FBIN(5180, 0), 477 /* Data[0].ctlEdges[1].bChannel */ FREQ2FBIN(5260, 0), 478 /* Data[0].ctlEdges[2].bChannel */ FREQ2FBIN(5280, 0), 479 /* Data[0].ctlEdges[3].bChannel */ FREQ2FBIN(5500, 0), 480 /* Data[0].ctlEdges[4].bChannel */ FREQ2FBIN(5600, 0), 481 /* Data[0].ctlEdges[5].bChannel */ FREQ2FBIN(5700, 0), 482 /* Data[0].ctlEdges[6].bChannel */ FREQ2FBIN(5745, 0), 483 /* Data[0].ctlEdges[7].bChannel */ FREQ2FBIN(5825, 0) 484 }, 485 { 486 /* Data[1].ctlEdges[0].bChannel */ FREQ2FBIN(5180, 0), 487 /* Data[1].ctlEdges[1].bChannel */ FREQ2FBIN(5260, 0), 488 /* Data[1].ctlEdges[2].bChannel */ FREQ2FBIN(5280, 0), 489 /* Data[1].ctlEdges[3].bChannel */ FREQ2FBIN(5500, 0), 490 /* Data[1].ctlEdges[4].bChannel */ FREQ2FBIN(5520, 0), 491 /* Data[1].ctlEdges[5].bChannel */ FREQ2FBIN(5700, 0), 492 /* Data[1].ctlEdges[6].bChannel */ FREQ2FBIN(5745, 0), 493 /* Data[1].ctlEdges[7].bChannel */ FREQ2FBIN(5825, 0) 494 }, 495 496 { 497 /* Data[2].ctlEdges[0].bChannel */ FREQ2FBIN(5190, 0), 498 /* Data[2].ctlEdges[1].bChannel */ FREQ2FBIN(5230, 0), 499 /* Data[2].ctlEdges[2].bChannel */ FREQ2FBIN(5270, 0), 500 /* Data[2].ctlEdges[3].bChannel */ FREQ2FBIN(5310, 0), 501 /* Data[2].ctlEdges[4].bChannel */ FREQ2FBIN(5510, 0), 502 /* Data[2].ctlEdges[5].bChannel */ FREQ2FBIN(5550, 0), 503 /* Data[2].ctlEdges[6].bChannel */ FREQ2FBIN(5670, 0), 504 /* Data[2].ctlEdges[7].bChannel */ FREQ2FBIN(5755, 0) 505 }, 506 507 { 508 /* Data[3].ctlEdges[0].bChannel */ FREQ2FBIN(5180, 0), 509 /* Data[3].ctlEdges[1].bChannel */ FREQ2FBIN(5200, 0), 510 /* Data[3].ctlEdges[2].bChannel */ FREQ2FBIN(5260, 0), 511 /* Data[3].ctlEdges[3].bChannel */ FREQ2FBIN(5320, 0), 512 /* Data[3].ctlEdges[4].bChannel */ FREQ2FBIN(5500, 0), 513 /* Data[3].ctlEdges[5].bChannel */ FREQ2FBIN(5700, 0), 514 /* Data[3].ctlEdges[6].bChannel */ 0xFF, 515 /* Data[3].ctlEdges[7].bChannel */ 0xFF, 516 }, 517 518 { 519 /* Data[4].ctlEdges[0].bChannel */ FREQ2FBIN(5180, 0), 520 /* Data[4].ctlEdges[1].bChannel */ FREQ2FBIN(5260, 0), 521 /* Data[4].ctlEdges[2].bChannel */ FREQ2FBIN(5500, 0), 522 /* Data[4].ctlEdges[3].bChannel */ FREQ2FBIN(5700, 0), 523 /* Data[4].ctlEdges[4].bChannel */ 0xFF, 524 /* Data[4].ctlEdges[5].bChannel */ 0xFF, 525 /* Data[4].ctlEdges[6].bChannel */ 0xFF, 526 /* Data[4].ctlEdges[7].bChannel */ 0xFF, 527 }, 528 529 { 530 /* Data[5].ctlEdges[0].bChannel */ FREQ2FBIN(5190, 0), 531 /* Data[5].ctlEdges[1].bChannel */ FREQ2FBIN(5270, 0), 532 /* Data[5].ctlEdges[2].bChannel */ FREQ2FBIN(5310, 0), 533 /* Data[5].ctlEdges[3].bChannel */ FREQ2FBIN(5510, 0), 534 /* Data[5].ctlEdges[4].bChannel */ FREQ2FBIN(5590, 0), 535 /* Data[5].ctlEdges[5].bChannel */ FREQ2FBIN(5670, 0), 536 /* Data[5].ctlEdges[6].bChannel */ 0xFF, 537 /* Data[5].ctlEdges[7].bChannel */ 0xFF 538 }, 539 540 { 541 /* Data[6].ctlEdges[0].bChannel */ FREQ2FBIN(5180, 0), 542 /* Data[6].ctlEdges[1].bChannel */ FREQ2FBIN(5200, 0), 543 /* Data[6].ctlEdges[2].bChannel */ FREQ2FBIN(5220, 0), 544 /* Data[6].ctlEdges[3].bChannel */ FREQ2FBIN(5260, 0), 545 /* Data[6].ctlEdges[4].bChannel */ FREQ2FBIN(5500, 0), 546 /* Data[6].ctlEdges[5].bChannel */ FREQ2FBIN(5600, 0), 547 /* Data[6].ctlEdges[6].bChannel */ FREQ2FBIN(5700, 0), 548 /* Data[6].ctlEdges[7].bChannel */ FREQ2FBIN(5745, 0) 549 }, 550 551 { 552 /* Data[7].ctlEdges[0].bChannel */ FREQ2FBIN(5180, 0), 553 /* Data[7].ctlEdges[1].bChannel */ FREQ2FBIN(5260, 0), 554 /* Data[7].ctlEdges[2].bChannel */ FREQ2FBIN(5320, 0), 555 /* Data[7].ctlEdges[3].bChannel */ FREQ2FBIN(5500, 0), 556 /* Data[7].ctlEdges[4].bChannel */ FREQ2FBIN(5560, 0), 557 /* Data[7].ctlEdges[5].bChannel */ FREQ2FBIN(5700, 0), 558 /* Data[7].ctlEdges[6].bChannel */ FREQ2FBIN(5745, 0), 559 /* Data[7].ctlEdges[7].bChannel */ FREQ2FBIN(5825, 0) 560 }, 561 562 { 563 /* Data[8].ctlEdges[0].bChannel */ FREQ2FBIN(5190, 0), 564 /* Data[8].ctlEdges[1].bChannel */ FREQ2FBIN(5230, 0), 565 /* Data[8].ctlEdges[2].bChannel */ FREQ2FBIN(5270, 0), 566 /* Data[8].ctlEdges[3].bChannel */ FREQ2FBIN(5510, 0), 567 /* Data[8].ctlEdges[4].bChannel */ FREQ2FBIN(5550, 0), 568 /* Data[8].ctlEdges[5].bChannel */ FREQ2FBIN(5670, 0), 569 /* Data[8].ctlEdges[6].bChannel */ FREQ2FBIN(5755, 0), 570 /* Data[8].ctlEdges[7].bChannel */ FREQ2FBIN(5795, 0) 571 } 572 }, 573 .ctlPowerData_5G = { 574 { 575 { 576 CTL(60, 1), CTL(60, 1), CTL(60, 1), CTL(60, 1), 577 CTL(60, 1), CTL(60, 1), CTL(60, 1), CTL(60, 0), 578 } 579 }, 580 { 581 { 582 CTL(60, 1), CTL(60, 1), CTL(60, 1), CTL(60, 1), 583 CTL(60, 1), CTL(60, 1), CTL(60, 1), CTL(60, 0), 584 } 585 }, 586 { 587 { 588 CTL(60, 0), CTL(60, 1), CTL(60, 0), CTL(60, 1), 589 CTL(60, 1), CTL(60, 1), CTL(60, 1), CTL(60, 1), 590 } 591 }, 592 { 593 { 594 CTL(60, 0), CTL(60, 1), CTL(60, 1), CTL(60, 0), 595 CTL(60, 1), CTL(60, 0), CTL(60, 0), CTL(60, 0), 596 } 597 }, 598 { 599 { 600 CTL(60, 1), CTL(60, 1), CTL(60, 1), CTL(60, 0), 601 CTL(60, 0), CTL(60, 0), CTL(60, 0), CTL(60, 0), 602 } 603 }, 604 { 605 { 606 CTL(60, 1), CTL(60, 1), CTL(60, 1), CTL(60, 1), 607 CTL(60, 1), CTL(60, 0), CTL(60, 0), CTL(60, 0), 608 } 609 }, 610 { 611 { 612 CTL(60, 1), CTL(60, 1), CTL(60, 1), CTL(60, 1), 613 CTL(60, 1), CTL(60, 1), CTL(60, 1), CTL(60, 1), 614 } 615 }, 616 { 617 { 618 CTL(60, 1), CTL(60, 1), CTL(60, 0), CTL(60, 1), 619 CTL(60, 1), CTL(60, 1), CTL(60, 1), CTL(60, 0), 620 } 621 }, 622 { 623 { 624 CTL(60, 1), CTL(60, 0), CTL(60, 1), CTL(60, 1), 625 CTL(60, 1), CTL(60, 1), CTL(60, 0), CTL(60, 1), 626 } 627 }, 628 } 629}; 630 631static u16 ath9k_hw_fbin2freq(u8 fbin, bool is2GHz) 632{ 633 if (fbin == AR9300_BCHAN_UNUSED) 634 return fbin; 635 636 return (u16) ((is2GHz) ? (2300 + fbin) : (4800 + 5 * fbin)); 637} 638 639static int ath9k_hw_ar9300_check_eeprom(struct ath_hw *ah) 640{ 641 return 0; 642} 643 644static u32 ath9k_hw_ar9300_get_eeprom(struct ath_hw *ah, 645 enum eeprom_param param) 646{ 647 struct ar9300_eeprom *eep = &ah->eeprom.ar9300_eep; 648 struct ar9300_base_eep_hdr *pBase = &eep->baseEepHeader; 649 650 switch (param) { 651 case EEP_MAC_LSW: 652 return eep->macAddr[0] << 8 | eep->macAddr[1]; 653 case EEP_MAC_MID: 654 return eep->macAddr[2] << 8 | eep->macAddr[3]; 655 case EEP_MAC_MSW: 656 return eep->macAddr[4] << 8 | eep->macAddr[5]; 657 case EEP_REG_0: 658 return le16_to_cpu(pBase->regDmn[0]); 659 case EEP_REG_1: 660 return le16_to_cpu(pBase->regDmn[1]); 661 case EEP_OP_CAP: 662 return pBase->deviceCap; 663 case EEP_OP_MODE: 664 return pBase->opCapFlags.opFlags; 665 case EEP_RF_SILENT: 666 return pBase->rfSilent; 667 case EEP_TX_MASK: 668 return (pBase->txrxMask >> 4) & 0xf; 669 case EEP_RX_MASK: 670 return pBase->txrxMask & 0xf; 671 case EEP_DRIVE_STRENGTH: 672#define AR9300_EEP_BASE_DRIV_STRENGTH 0x1 673 return pBase->miscConfiguration & AR9300_EEP_BASE_DRIV_STRENGTH; 674 case EEP_INTERNAL_REGULATOR: 675 /* Bit 4 is internal regulator flag */ 676 return (pBase->featureEnable & 0x10) >> 4; 677 case EEP_SWREG: 678 return le32_to_cpu(pBase->swreg); 679 case EEP_PAPRD: 680 return !!(pBase->featureEnable & BIT(5)); 681 default: 682 return 0; 683 } 684} 685 686static bool ar9300_eeprom_read_byte(struct ath_common *common, int address, 687 u8 *buffer) 688{ 689 u16 val; 690 691 if (unlikely(!ath9k_hw_nvram_read(common, address / 2, &val))) 692 return false; 693 694 *buffer = (val >> (8 * (address % 2))) & 0xff; 695 return true; 696} 697 698static bool ar9300_eeprom_read_word(struct ath_common *common, int address, 699 u8 *buffer) 700{ 701 u16 val; 702 703 if (unlikely(!ath9k_hw_nvram_read(common, address / 2, &val))) 704 return false; 705 706 buffer[0] = val >> 8; 707 buffer[1] = val & 0xff; 708 709 return true; 710} 711 712static bool ar9300_read_eeprom(struct ath_hw *ah, int address, u8 *buffer, 713 int count) 714{ 715 struct ath_common *common = ath9k_hw_common(ah); 716 int i; 717 718 if ((address < 0) || ((address + count) / 2 > AR9300_EEPROM_SIZE - 1)) { 719 ath_print(common, ATH_DBG_EEPROM, 720 "eeprom address not in range\n"); 721 return false; 722 } 723 724 /* 725 * Since we're reading the bytes in reverse order from a little-endian 726 * word stream, an even address means we only use the lower half of 727 * the 16-bit word at that address 728 */ 729 if (address % 2 == 0) { 730 if (!ar9300_eeprom_read_byte(common, address--, buffer++)) 731 goto error; 732 733 count--; 734 } 735 736 for (i = 0; i < count / 2; i++) { 737 if (!ar9300_eeprom_read_word(common, address, buffer)) 738 goto error; 739 740 address -= 2; 741 buffer += 2; 742 } 743 744 if (count % 2) 745 if (!ar9300_eeprom_read_byte(common, address, buffer)) 746 goto error; 747 748 return true; 749 750error: 751 ath_print(common, ATH_DBG_EEPROM, 752 "unable to read eeprom region at offset %d\n", address); 753 return false; 754} 755 756static void ar9300_comp_hdr_unpack(u8 *best, int *code, int *reference, 757 int *length, int *major, int *minor) 758{ 759 unsigned long value[4]; 760 761 value[0] = best[0]; 762 value[1] = best[1]; 763 value[2] = best[2]; 764 value[3] = best[3]; 765 *code = ((value[0] >> 5) & 0x0007); 766 *reference = (value[0] & 0x001f) | ((value[1] >> 2) & 0x0020); 767 *length = ((value[1] << 4) & 0x07f0) | ((value[2] >> 4) & 0x000f); 768 *major = (value[2] & 0x000f); 769 *minor = (value[3] & 0x00ff); 770} 771 772static u16 ar9300_comp_cksum(u8 *data, int dsize) 773{ 774 int it, checksum = 0; 775 776 for (it = 0; it < dsize; it++) { 777 checksum += data[it]; 778 checksum &= 0xffff; 779 } 780 781 return checksum; 782} 783 784static bool ar9300_uncompress_block(struct ath_hw *ah, 785 u8 *mptr, 786 int mdataSize, 787 u8 *block, 788 int size) 789{ 790 int it; 791 int spot; 792 int offset; 793 int length; 794 struct ath_common *common = ath9k_hw_common(ah); 795 796 spot = 0; 797 798 for (it = 0; it < size; it += (length+2)) { 799 offset = block[it]; 800 offset &= 0xff; 801 spot += offset; 802 length = block[it+1]; 803 length &= 0xff; 804 805 if (length > 0 && spot >= 0 && spot+length <= mdataSize) { 806 ath_print(common, ATH_DBG_EEPROM, 807 "Restore at %d: spot=%d " 808 "offset=%d length=%d\n", 809 it, spot, offset, length); 810 memcpy(&mptr[spot], &block[it+2], length); 811 spot += length; 812 } else if (length > 0) { 813 ath_print(common, ATH_DBG_EEPROM, 814 "Bad restore at %d: spot=%d " 815 "offset=%d length=%d\n", 816 it, spot, offset, length); 817 return false; 818 } 819 } 820 return true; 821} 822 823static int ar9300_compress_decision(struct ath_hw *ah, 824 int it, 825 int code, 826 int reference, 827 u8 *mptr, 828 u8 *word, int length, int mdata_size) 829{ 830 struct ath_common *common = ath9k_hw_common(ah); 831 u8 *dptr; 832 833 switch (code) { 834 case _CompressNone: 835 if (length != mdata_size) { 836 ath_print(common, ATH_DBG_EEPROM, 837 "EEPROM structure size mismatch" 838 "memory=%d eeprom=%d\n", mdata_size, length); 839 return -1; 840 } 841 memcpy(mptr, (u8 *) (word + COMP_HDR_LEN), length); 842 ath_print(common, ATH_DBG_EEPROM, "restored eeprom %d:" 843 " uncompressed, length %d\n", it, length); 844 break; 845 case _CompressBlock: 846 if (reference == 0) { 847 dptr = mptr; 848 } else { 849 if (reference != 2) { 850 ath_print(common, ATH_DBG_EEPROM, 851 "cant find reference eeprom" 852 "struct %d\n", reference); 853 return -1; 854 } 855 memcpy(mptr, &ar9300_default, mdata_size); 856 } 857 ath_print(common, ATH_DBG_EEPROM, 858 "restore eeprom %d: block, reference %d," 859 " length %d\n", it, reference, length); 860 ar9300_uncompress_block(ah, mptr, mdata_size, 861 (u8 *) (word + COMP_HDR_LEN), length); 862 break; 863 default: 864 ath_print(common, ATH_DBG_EEPROM, "unknown compression" 865 " code %d\n", code); 866 return -1; 867 } 868 return 0; 869} 870 871/* 872 * Read the configuration data from the eeprom. 873 * The data can be put in any specified memory buffer. 874 * 875 * Returns -1 on error. 876 * Returns address of next memory location on success. 877 */ 878static int ar9300_eeprom_restore_internal(struct ath_hw *ah, 879 u8 *mptr, int mdata_size) 880{ 881#define MDEFAULT 15 882#define MSTATE 100 883 int cptr; 884 u8 *word; 885 int code; 886 int reference, length, major, minor; 887 int osize; 888 int it; 889 u16 checksum, mchecksum; 890 struct ath_common *common = ath9k_hw_common(ah); 891 892 word = kzalloc(2048, GFP_KERNEL); 893 if (!word) 894 return -1; 895 896 memcpy(mptr, &ar9300_default, mdata_size); 897 898 cptr = AR9300_BASE_ADDR; 899 for (it = 0; it < MSTATE; it++) { 900 if (!ar9300_read_eeprom(ah, cptr, word, COMP_HDR_LEN)) 901 goto fail; 902 903 if ((word[0] == 0 && word[1] == 0 && word[2] == 0 && 904 word[3] == 0) || (word[0] == 0xff && word[1] == 0xff 905 && word[2] == 0xff && word[3] == 0xff)) 906 break; 907 908 ar9300_comp_hdr_unpack(word, &code, &reference, 909 &length, &major, &minor); 910 ath_print(common, ATH_DBG_EEPROM, 911 "Found block at %x: code=%d ref=%d" 912 "length=%d major=%d minor=%d\n", cptr, code, 913 reference, length, major, minor); 914 if (length >= 1024) { 915 ath_print(common, ATH_DBG_EEPROM, 916 "Skipping bad header\n"); 917 cptr -= COMP_HDR_LEN; 918 continue; 919 } 920 921 osize = length; 922 ar9300_read_eeprom(ah, cptr, word, 923 COMP_HDR_LEN + osize + COMP_CKSUM_LEN); 924 checksum = ar9300_comp_cksum(&word[COMP_HDR_LEN], length); 925 mchecksum = word[COMP_HDR_LEN + osize] | 926 (word[COMP_HDR_LEN + osize + 1] << 8); 927 ath_print(common, ATH_DBG_EEPROM, 928 "checksum %x %x\n", checksum, mchecksum); 929 if (checksum == mchecksum) { 930 ar9300_compress_decision(ah, it, code, reference, mptr, 931 word, length, mdata_size); 932 } else { 933 ath_print(common, ATH_DBG_EEPROM, 934 "skipping block with bad checksum\n"); 935 } 936 cptr -= (COMP_HDR_LEN + osize + COMP_CKSUM_LEN); 937 } 938 939 kfree(word); 940 return cptr; 941 942fail: 943 kfree(word); 944 return -1; 945} 946 947/* 948 * Restore the configuration structure by reading the eeprom. 949 * This function destroys any existing in-memory structure 950 * content. 951 */ 952static bool ath9k_hw_ar9300_fill_eeprom(struct ath_hw *ah) 953{ 954 u8 *mptr = (u8 *) &ah->eeprom.ar9300_eep; 955 956 if (ar9300_eeprom_restore_internal(ah, mptr, 957 sizeof(struct ar9300_eeprom)) < 0) 958 return false; 959 960 return true; 961} 962 963static int ath9k_hw_ar9300_get_eeprom_ver(struct ath_hw *ah) 964{ 965 return ah->eeprom.ar9300_eep.eepromVersion; 966} 967 968static int ath9k_hw_ar9300_get_eeprom_rev(struct ath_hw *ah) 969{ 970 return 0; 971} 972 973static u8 ath9k_hw_ar9300_get_num_ant_config(struct ath_hw *ah, 974 enum ieee80211_band freq_band) 975{ 976 return 1; 977} 978 979static u32 ath9k_hw_ar9300_get_eeprom_antenna_cfg(struct ath_hw *ah, 980 struct ath9k_channel *chan) 981{ 982 return -EINVAL; 983} 984 985static s32 ar9003_hw_xpa_bias_level_get(struct ath_hw *ah, bool is2ghz) 986{ 987 struct ar9300_eeprom *eep = &ah->eeprom.ar9300_eep; 988 989 if (is2ghz) 990 return eep->modalHeader2G.xpaBiasLvl; 991 else 992 return eep->modalHeader5G.xpaBiasLvl; 993} 994 995static void ar9003_hw_xpa_bias_level_apply(struct ath_hw *ah, bool is2ghz) 996{ 997 int bias = ar9003_hw_xpa_bias_level_get(ah, is2ghz); 998 REG_RMW_FIELD(ah, AR_CH0_TOP, AR_CH0_TOP_XPABIASLVL, bias); 999 REG_RMW_FIELD(ah, AR_CH0_THERM, AR_CH0_THERM_XPABIASLVL_MSB, bias >> 2); 1000 REG_RMW_FIELD(ah, AR_CH0_THERM, AR_CH0_THERM_XPASHORT2GND, 1); 1001} 1002 1003static u32 ar9003_hw_ant_ctrl_common_get(struct ath_hw *ah, bool is2ghz) 1004{ 1005 struct ar9300_eeprom *eep = &ah->eeprom.ar9300_eep; 1006 __le32 val; 1007 1008 if (is2ghz) 1009 val = eep->modalHeader2G.antCtrlCommon; 1010 else 1011 val = eep->modalHeader5G.antCtrlCommon; 1012 return le32_to_cpu(val); 1013} 1014 1015static u32 ar9003_hw_ant_ctrl_common_2_get(struct ath_hw *ah, bool is2ghz) 1016{ 1017 struct ar9300_eeprom *eep = &ah->eeprom.ar9300_eep; 1018 __le32 val; 1019 1020 if (is2ghz) 1021 val = eep->modalHeader2G.antCtrlCommon2; 1022 else 1023 val = eep->modalHeader5G.antCtrlCommon2; 1024 return le32_to_cpu(val); 1025} 1026 1027static u16 ar9003_hw_ant_ctrl_chain_get(struct ath_hw *ah, 1028 int chain, 1029 bool is2ghz) 1030{ 1031 struct ar9300_eeprom *eep = &ah->eeprom.ar9300_eep; 1032 __le16 val = 0; 1033 1034 if (chain >= 0 && chain < AR9300_MAX_CHAINS) { 1035 if (is2ghz) 1036 val = eep->modalHeader2G.antCtrlChain[chain]; 1037 else 1038 val = eep->modalHeader5G.antCtrlChain[chain]; 1039 } 1040 1041 return le16_to_cpu(val); 1042} 1043 1044static void ar9003_hw_ant_ctrl_apply(struct ath_hw *ah, bool is2ghz) 1045{ 1046 u32 value = ar9003_hw_ant_ctrl_common_get(ah, is2ghz); 1047 REG_RMW_FIELD(ah, AR_PHY_SWITCH_COM, AR_SWITCH_TABLE_COM_ALL, value); 1048 1049 value = ar9003_hw_ant_ctrl_common_2_get(ah, is2ghz); 1050 REG_RMW_FIELD(ah, AR_PHY_SWITCH_COM_2, AR_SWITCH_TABLE_COM2_ALL, value); 1051 1052 value = ar9003_hw_ant_ctrl_chain_get(ah, 0, is2ghz); 1053 REG_RMW_FIELD(ah, AR_PHY_SWITCH_CHAIN_0, AR_SWITCH_TABLE_ALL, value); 1054 1055 value = ar9003_hw_ant_ctrl_chain_get(ah, 1, is2ghz); 1056 REG_RMW_FIELD(ah, AR_PHY_SWITCH_CHAIN_1, AR_SWITCH_TABLE_ALL, value); 1057 1058 value = ar9003_hw_ant_ctrl_chain_get(ah, 2, is2ghz); 1059 REG_RMW_FIELD(ah, AR_PHY_SWITCH_CHAIN_2, AR_SWITCH_TABLE_ALL, value); 1060} 1061 1062static void ar9003_hw_drive_strength_apply(struct ath_hw *ah) 1063{ 1064 int drive_strength; 1065 unsigned long reg; 1066 1067 drive_strength = ath9k_hw_ar9300_get_eeprom(ah, EEP_DRIVE_STRENGTH); 1068 1069 if (!drive_strength) 1070 return; 1071 1072 reg = REG_READ(ah, AR_PHY_65NM_CH0_BIAS1); 1073 reg &= ~0x00ffffc0; 1074 reg |= 0x5 << 21; 1075 reg |= 0x5 << 18; 1076 reg |= 0x5 << 15; 1077 reg |= 0x5 << 12; 1078 reg |= 0x5 << 9; 1079 reg |= 0x5 << 6; 1080 REG_WRITE(ah, AR_PHY_65NM_CH0_BIAS1, reg); 1081 1082 reg = REG_READ(ah, AR_PHY_65NM_CH0_BIAS2); 1083 reg &= ~0xffffffe0; 1084 reg |= 0x5 << 29; 1085 reg |= 0x5 << 26; 1086 reg |= 0x5 << 23; 1087 reg |= 0x5 << 20; 1088 reg |= 0x5 << 17; 1089 reg |= 0x5 << 14; 1090 reg |= 0x5 << 11; 1091 reg |= 0x5 << 8; 1092 reg |= 0x5 << 5; 1093 REG_WRITE(ah, AR_PHY_65NM_CH0_BIAS2, reg); 1094 1095 reg = REG_READ(ah, AR_PHY_65NM_CH0_BIAS4); 1096 reg &= ~0xff800000; 1097 reg |= 0x5 << 29; 1098 reg |= 0x5 << 26; 1099 reg |= 0x5 << 23; 1100 REG_WRITE(ah, AR_PHY_65NM_CH0_BIAS4, reg); 1101} 1102 1103static void ar9003_hw_internal_regulator_apply(struct ath_hw *ah) 1104{ 1105 int internal_regulator = 1106 ath9k_hw_ar9300_get_eeprom(ah, EEP_INTERNAL_REGULATOR); 1107 1108 if (internal_regulator) { 1109 /* Internal regulator is ON. Write swreg register. */ 1110 int swreg = ath9k_hw_ar9300_get_eeprom(ah, EEP_SWREG); 1111 REG_WRITE(ah, AR_RTC_REG_CONTROL1, 1112 REG_READ(ah, AR_RTC_REG_CONTROL1) & 1113 (~AR_RTC_REG_CONTROL1_SWREG_PROGRAM)); 1114 REG_WRITE(ah, AR_RTC_REG_CONTROL0, swreg); 1115 /* Set REG_CONTROL1.SWREG_PROGRAM */ 1116 REG_WRITE(ah, AR_RTC_REG_CONTROL1, 1117 REG_READ(ah, 1118 AR_RTC_REG_CONTROL1) | 1119 AR_RTC_REG_CONTROL1_SWREG_PROGRAM); 1120 } else { 1121 REG_WRITE(ah, AR_RTC_SLEEP_CLK, 1122 (REG_READ(ah, 1123 AR_RTC_SLEEP_CLK) | 1124 AR_RTC_FORCE_SWREG_PRD)); 1125 } 1126} 1127 1128static void ath9k_hw_ar9300_set_board_values(struct ath_hw *ah, 1129 struct ath9k_channel *chan) 1130{ 1131 ar9003_hw_xpa_bias_level_apply(ah, IS_CHAN_2GHZ(chan)); 1132 ar9003_hw_ant_ctrl_apply(ah, IS_CHAN_2GHZ(chan)); 1133 ar9003_hw_drive_strength_apply(ah); 1134 ar9003_hw_internal_regulator_apply(ah); 1135} 1136 1137static void ath9k_hw_ar9300_set_addac(struct ath_hw *ah, 1138 struct ath9k_channel *chan) 1139{ 1140} 1141 1142/* 1143 * Returns the interpolated y value corresponding to the specified x value 1144 * from the np ordered pairs of data (px,py). 1145 * The pairs do not have to be in any order. 1146 * If the specified x value is less than any of the px, 1147 * the returned y value is equal to the py for the lowest px. 1148 * If the specified x value is greater than any of the px, 1149 * the returned y value is equal to the py for the highest px. 1150 */ 1151static int ar9003_hw_power_interpolate(int32_t x, 1152 int32_t *px, int32_t *py, u_int16_t np) 1153{ 1154 int ip = 0; 1155 int lx = 0, ly = 0, lhave = 0; 1156 int hx = 0, hy = 0, hhave = 0; 1157 int dx = 0; 1158 int y = 0; 1159 1160 lhave = 0; 1161 hhave = 0; 1162 1163 /* identify best lower and higher x calibration measurement */ 1164 for (ip = 0; ip < np; ip++) { 1165 dx = x - px[ip]; 1166 1167 /* this measurement is higher than our desired x */ 1168 if (dx <= 0) { 1169 if (!hhave || dx > (x - hx)) { 1170 /* new best higher x measurement */ 1171 hx = px[ip]; 1172 hy = py[ip]; 1173 hhave = 1; 1174 } 1175 } 1176 /* this measurement is lower than our desired x */ 1177 if (dx >= 0) { 1178 if (!lhave || dx < (x - lx)) { 1179 /* new best lower x measurement */ 1180 lx = px[ip]; 1181 ly = py[ip]; 1182 lhave = 1; 1183 } 1184 } 1185 } 1186 1187 /* the low x is good */ 1188 if (lhave) { 1189 /* so is the high x */ 1190 if (hhave) { 1191 /* they're the same, so just pick one */ 1192 if (hx == lx) 1193 y = ly; 1194 else /* interpolate */ 1195 y = ly + (((x - lx) * (hy - ly)) / (hx - lx)); 1196 } else /* only low is good, use it */ 1197 y = ly; 1198 } else if (hhave) /* only high is good, use it */ 1199 y = hy; 1200 else /* nothing is good,this should never happen unless np=0, ???? */ 1201 y = -(1 << 30); 1202 return y; 1203} 1204 1205static u8 ar9003_hw_eeprom_get_tgt_pwr(struct ath_hw *ah, 1206 u16 rateIndex, u16 freq, bool is2GHz) 1207{ 1208 u16 numPiers, i; 1209 s32 targetPowerArray[AR9300_NUM_5G_20_TARGET_POWERS]; 1210 s32 freqArray[AR9300_NUM_5G_20_TARGET_POWERS]; 1211 struct ar9300_eeprom *eep = &ah->eeprom.ar9300_eep; 1212 struct cal_tgt_pow_legacy *pEepromTargetPwr; 1213 u8 *pFreqBin; 1214 1215 if (is2GHz) { 1216 numPiers = AR9300_NUM_2G_20_TARGET_POWERS; 1217 pEepromTargetPwr = eep->calTargetPower2G; 1218 pFreqBin = eep->calTarget_freqbin_2G; 1219 } else { 1220 numPiers = AR9300_NUM_5G_20_TARGET_POWERS; 1221 pEepromTargetPwr = eep->calTargetPower5G; 1222 pFreqBin = eep->calTarget_freqbin_5G; 1223 } 1224 1225 /* 1226 * create array of channels and targetpower from 1227 * targetpower piers stored on eeprom 1228 */ 1229 for (i = 0; i < numPiers; i++) { 1230 freqArray[i] = FBIN2FREQ(pFreqBin[i], is2GHz); 1231 targetPowerArray[i] = pEepromTargetPwr[i].tPow2x[rateIndex]; 1232 } 1233 1234 /* interpolate to get target power for given frequency */ 1235 return (u8) ar9003_hw_power_interpolate((s32) freq, 1236 freqArray, 1237 targetPowerArray, numPiers); 1238} 1239 1240static u8 ar9003_hw_eeprom_get_ht20_tgt_pwr(struct ath_hw *ah, 1241 u16 rateIndex, 1242 u16 freq, bool is2GHz) 1243{ 1244 u16 numPiers, i; 1245 s32 targetPowerArray[AR9300_NUM_5G_20_TARGET_POWERS]; 1246 s32 freqArray[AR9300_NUM_5G_20_TARGET_POWERS]; 1247 struct ar9300_eeprom *eep = &ah->eeprom.ar9300_eep; 1248 struct cal_tgt_pow_ht *pEepromTargetPwr; 1249 u8 *pFreqBin; 1250 1251 if (is2GHz) { 1252 numPiers = AR9300_NUM_2G_20_TARGET_POWERS; 1253 pEepromTargetPwr = eep->calTargetPower2GHT20; 1254 pFreqBin = eep->calTarget_freqbin_2GHT20; 1255 } else { 1256 numPiers = AR9300_NUM_5G_20_TARGET_POWERS; 1257 pEepromTargetPwr = eep->calTargetPower5GHT20; 1258 pFreqBin = eep->calTarget_freqbin_5GHT20; 1259 } 1260 1261 /* 1262 * create array of channels and targetpower 1263 * from targetpower piers stored on eeprom 1264 */ 1265 for (i = 0; i < numPiers; i++) { 1266 freqArray[i] = FBIN2FREQ(pFreqBin[i], is2GHz); 1267 targetPowerArray[i] = pEepromTargetPwr[i].tPow2x[rateIndex]; 1268 } 1269 1270 /* interpolate to get target power for given frequency */ 1271 return (u8) ar9003_hw_power_interpolate((s32) freq, 1272 freqArray, 1273 targetPowerArray, numPiers); 1274} 1275 1276static u8 ar9003_hw_eeprom_get_ht40_tgt_pwr(struct ath_hw *ah, 1277 u16 rateIndex, 1278 u16 freq, bool is2GHz) 1279{ 1280 u16 numPiers, i; 1281 s32 targetPowerArray[AR9300_NUM_5G_40_TARGET_POWERS]; 1282 s32 freqArray[AR9300_NUM_5G_40_TARGET_POWERS]; 1283 struct ar9300_eeprom *eep = &ah->eeprom.ar9300_eep; 1284 struct cal_tgt_pow_ht *pEepromTargetPwr; 1285 u8 *pFreqBin; 1286 1287 if (is2GHz) { 1288 numPiers = AR9300_NUM_2G_40_TARGET_POWERS; 1289 pEepromTargetPwr = eep->calTargetPower2GHT40; 1290 pFreqBin = eep->calTarget_freqbin_2GHT40; 1291 } else { 1292 numPiers = AR9300_NUM_5G_40_TARGET_POWERS; 1293 pEepromTargetPwr = eep->calTargetPower5GHT40; 1294 pFreqBin = eep->calTarget_freqbin_5GHT40; 1295 } 1296 1297 /* 1298 * create array of channels and targetpower from 1299 * targetpower piers stored on eeprom 1300 */ 1301 for (i = 0; i < numPiers; i++) { 1302 freqArray[i] = FBIN2FREQ(pFreqBin[i], is2GHz); 1303 targetPowerArray[i] = pEepromTargetPwr[i].tPow2x[rateIndex]; 1304 } 1305 1306 /* interpolate to get target power for given frequency */ 1307 return (u8) ar9003_hw_power_interpolate((s32) freq, 1308 freqArray, 1309 targetPowerArray, numPiers); 1310} 1311 1312static u8 ar9003_hw_eeprom_get_cck_tgt_pwr(struct ath_hw *ah, 1313 u16 rateIndex, u16 freq) 1314{ 1315 u16 numPiers = AR9300_NUM_2G_CCK_TARGET_POWERS, i; 1316 s32 targetPowerArray[AR9300_NUM_2G_CCK_TARGET_POWERS]; 1317 s32 freqArray[AR9300_NUM_2G_CCK_TARGET_POWERS]; 1318 struct ar9300_eeprom *eep = &ah->eeprom.ar9300_eep; 1319 struct cal_tgt_pow_legacy *pEepromTargetPwr = eep->calTargetPowerCck; 1320 u8 *pFreqBin = eep->calTarget_freqbin_Cck; 1321 1322 /* 1323 * create array of channels and targetpower from 1324 * targetpower piers stored on eeprom 1325 */ 1326 for (i = 0; i < numPiers; i++) { 1327 freqArray[i] = FBIN2FREQ(pFreqBin[i], 1); 1328 targetPowerArray[i] = pEepromTargetPwr[i].tPow2x[rateIndex]; 1329 } 1330 1331 /* interpolate to get target power for given frequency */ 1332 return (u8) ar9003_hw_power_interpolate((s32) freq, 1333 freqArray, 1334 targetPowerArray, numPiers); 1335} 1336 1337/* Set tx power registers to array of values passed in */ 1338static int ar9003_hw_tx_power_regwrite(struct ath_hw *ah, u8 * pPwrArray) 1339{ 1340#define POW_SM(_r, _s) (((_r) & 0x3f) << (_s)) 1341 /* make sure forced gain is not set */ 1342 REG_WRITE(ah, 0xa458, 0); 1343 1344 /* Write the OFDM power per rate set */ 1345 1346 /* 6 (LSB), 9, 12, 18 (MSB) */ 1347 REG_WRITE(ah, 0xa3c0, 1348 POW_SM(pPwrArray[ALL_TARGET_LEGACY_6_24], 24) | 1349 POW_SM(pPwrArray[ALL_TARGET_LEGACY_6_24], 16) | 1350 POW_SM(pPwrArray[ALL_TARGET_LEGACY_6_24], 8) | 1351 POW_SM(pPwrArray[ALL_TARGET_LEGACY_6_24], 0)); 1352 1353 /* 24 (LSB), 36, 48, 54 (MSB) */ 1354 REG_WRITE(ah, 0xa3c4, 1355 POW_SM(pPwrArray[ALL_TARGET_LEGACY_54], 24) | 1356 POW_SM(pPwrArray[ALL_TARGET_LEGACY_48], 16) | 1357 POW_SM(pPwrArray[ALL_TARGET_LEGACY_36], 8) | 1358 POW_SM(pPwrArray[ALL_TARGET_LEGACY_6_24], 0)); 1359 1360 /* Write the CCK power per rate set */ 1361 1362 /* 1L (LSB), reserved, 2L, 2S (MSB) */ 1363 REG_WRITE(ah, 0xa3c8, 1364 POW_SM(pPwrArray[ALL_TARGET_LEGACY_1L_5L], 24) | 1365 POW_SM(pPwrArray[ALL_TARGET_LEGACY_1L_5L], 16) | 1366 /* POW_SM(txPowerTimes2, 8) | this is reserved for AR9003 */ 1367 POW_SM(pPwrArray[ALL_TARGET_LEGACY_1L_5L], 0)); 1368 1369 /* 5.5L (LSB), 5.5S, 11L, 11S (MSB) */ 1370 REG_WRITE(ah, 0xa3cc, 1371 POW_SM(pPwrArray[ALL_TARGET_LEGACY_11S], 24) | 1372 POW_SM(pPwrArray[ALL_TARGET_LEGACY_11L], 16) | 1373 POW_SM(pPwrArray[ALL_TARGET_LEGACY_5S], 8) | 1374 POW_SM(pPwrArray[ALL_TARGET_LEGACY_1L_5L], 0) 1375 ); 1376 1377 /* Write the HT20 power per rate set */ 1378 1379 /* 0/8/16 (LSB), 1-3/9-11/17-19, 4, 5 (MSB) */ 1380 REG_WRITE(ah, 0xa3d0, 1381 POW_SM(pPwrArray[ALL_TARGET_HT20_5], 24) | 1382 POW_SM(pPwrArray[ALL_TARGET_HT20_4], 16) | 1383 POW_SM(pPwrArray[ALL_TARGET_HT20_1_3_9_11_17_19], 8) | 1384 POW_SM(pPwrArray[ALL_TARGET_HT20_0_8_16], 0) 1385 ); 1386 1387 /* 6 (LSB), 7, 12, 13 (MSB) */ 1388 REG_WRITE(ah, 0xa3d4, 1389 POW_SM(pPwrArray[ALL_TARGET_HT20_13], 24) | 1390 POW_SM(pPwrArray[ALL_TARGET_HT20_12], 16) | 1391 POW_SM(pPwrArray[ALL_TARGET_HT20_7], 8) | 1392 POW_SM(pPwrArray[ALL_TARGET_HT20_6], 0) 1393 ); 1394 1395 /* 14 (LSB), 15, 20, 21 */ 1396 REG_WRITE(ah, 0xa3e4, 1397 POW_SM(pPwrArray[ALL_TARGET_HT20_21], 24) | 1398 POW_SM(pPwrArray[ALL_TARGET_HT20_20], 16) | 1399 POW_SM(pPwrArray[ALL_TARGET_HT20_15], 8) | 1400 POW_SM(pPwrArray[ALL_TARGET_HT20_14], 0) 1401 ); 1402 1403 /* Mixed HT20 and HT40 rates */ 1404 1405 /* HT20 22 (LSB), HT20 23, HT40 22, HT40 23 (MSB) */ 1406 REG_WRITE(ah, 0xa3e8, 1407 POW_SM(pPwrArray[ALL_TARGET_HT40_23], 24) | 1408 POW_SM(pPwrArray[ALL_TARGET_HT40_22], 16) | 1409 POW_SM(pPwrArray[ALL_TARGET_HT20_23], 8) | 1410 POW_SM(pPwrArray[ALL_TARGET_HT20_22], 0) 1411 ); 1412 1413 /* 1414 * Write the HT40 power per rate set 1415 * correct PAR difference between HT40 and HT20/LEGACY 1416 * 0/8/16 (LSB), 1-3/9-11/17-19, 4, 5 (MSB) 1417 */ 1418 REG_WRITE(ah, 0xa3d8, 1419 POW_SM(pPwrArray[ALL_TARGET_HT40_5], 24) | 1420 POW_SM(pPwrArray[ALL_TARGET_HT40_4], 16) | 1421 POW_SM(pPwrArray[ALL_TARGET_HT40_1_3_9_11_17_19], 8) | 1422 POW_SM(pPwrArray[ALL_TARGET_HT40_0_8_16], 0) 1423 ); 1424 1425 /* 6 (LSB), 7, 12, 13 (MSB) */ 1426 REG_WRITE(ah, 0xa3dc, 1427 POW_SM(pPwrArray[ALL_TARGET_HT40_13], 24) | 1428 POW_SM(pPwrArray[ALL_TARGET_HT40_12], 16) | 1429 POW_SM(pPwrArray[ALL_TARGET_HT40_7], 8) | 1430 POW_SM(pPwrArray[ALL_TARGET_HT40_6], 0) 1431 ); 1432 1433 /* 14 (LSB), 15, 20, 21 */ 1434 REG_WRITE(ah, 0xa3ec, 1435 POW_SM(pPwrArray[ALL_TARGET_HT40_21], 24) | 1436 POW_SM(pPwrArray[ALL_TARGET_HT40_20], 16) | 1437 POW_SM(pPwrArray[ALL_TARGET_HT40_15], 8) | 1438 POW_SM(pPwrArray[ALL_TARGET_HT40_14], 0) 1439 ); 1440 1441 return 0; 1442#undef POW_SM 1443} 1444 1445static void ar9003_hw_set_target_power_eeprom(struct ath_hw *ah, u16 freq, 1446 u8 *targetPowerValT2) 1447{ 1448 u8 ht40PowerIncForPdadc = 0; 1449 bool is2GHz = false; 1450 unsigned int i = 0; 1451 struct ath_common *common = ath9k_hw_common(ah); 1452 1453 if (freq < 4000) 1454 is2GHz = true; 1455 1456 targetPowerValT2[ALL_TARGET_LEGACY_6_24] = 1457 ar9003_hw_eeprom_get_tgt_pwr(ah, LEGACY_TARGET_RATE_6_24, freq, 1458 is2GHz); 1459 targetPowerValT2[ALL_TARGET_LEGACY_36] = 1460 ar9003_hw_eeprom_get_tgt_pwr(ah, LEGACY_TARGET_RATE_36, freq, 1461 is2GHz); 1462 targetPowerValT2[ALL_TARGET_LEGACY_48] = 1463 ar9003_hw_eeprom_get_tgt_pwr(ah, LEGACY_TARGET_RATE_48, freq, 1464 is2GHz); 1465 targetPowerValT2[ALL_TARGET_LEGACY_54] = 1466 ar9003_hw_eeprom_get_tgt_pwr(ah, LEGACY_TARGET_RATE_54, freq, 1467 is2GHz); 1468 targetPowerValT2[ALL_TARGET_LEGACY_1L_5L] = 1469 ar9003_hw_eeprom_get_cck_tgt_pwr(ah, LEGACY_TARGET_RATE_1L_5L, 1470 freq); 1471 targetPowerValT2[ALL_TARGET_LEGACY_5S] = 1472 ar9003_hw_eeprom_get_cck_tgt_pwr(ah, LEGACY_TARGET_RATE_5S, freq); 1473 targetPowerValT2[ALL_TARGET_LEGACY_11L] = 1474 ar9003_hw_eeprom_get_cck_tgt_pwr(ah, LEGACY_TARGET_RATE_11L, freq); 1475 targetPowerValT2[ALL_TARGET_LEGACY_11S] = 1476 ar9003_hw_eeprom_get_cck_tgt_pwr(ah, LEGACY_TARGET_RATE_11S, freq); 1477 targetPowerValT2[ALL_TARGET_HT20_0_8_16] = 1478 ar9003_hw_eeprom_get_ht20_tgt_pwr(ah, HT_TARGET_RATE_0_8_16, freq, 1479 is2GHz); 1480 targetPowerValT2[ALL_TARGET_HT20_1_3_9_11_17_19] = 1481 ar9003_hw_eeprom_get_ht20_tgt_pwr(ah, HT_TARGET_RATE_1_3_9_11_17_19, 1482 freq, is2GHz); 1483 targetPowerValT2[ALL_TARGET_HT20_4] = 1484 ar9003_hw_eeprom_get_ht20_tgt_pwr(ah, HT_TARGET_RATE_4, freq, 1485 is2GHz); 1486 targetPowerValT2[ALL_TARGET_HT20_5] = 1487 ar9003_hw_eeprom_get_ht20_tgt_pwr(ah, HT_TARGET_RATE_5, freq, 1488 is2GHz); 1489 targetPowerValT2[ALL_TARGET_HT20_6] = 1490 ar9003_hw_eeprom_get_ht20_tgt_pwr(ah, HT_TARGET_RATE_6, freq, 1491 is2GHz); 1492 targetPowerValT2[ALL_TARGET_HT20_7] = 1493 ar9003_hw_eeprom_get_ht20_tgt_pwr(ah, HT_TARGET_RATE_7, freq, 1494 is2GHz); 1495 targetPowerValT2[ALL_TARGET_HT20_12] = 1496 ar9003_hw_eeprom_get_ht20_tgt_pwr(ah, HT_TARGET_RATE_12, freq, 1497 is2GHz); 1498 targetPowerValT2[ALL_TARGET_HT20_13] = 1499 ar9003_hw_eeprom_get_ht20_tgt_pwr(ah, HT_TARGET_RATE_13, freq, 1500 is2GHz); 1501 targetPowerValT2[ALL_TARGET_HT20_14] = 1502 ar9003_hw_eeprom_get_ht20_tgt_pwr(ah, HT_TARGET_RATE_14, freq, 1503 is2GHz); 1504 targetPowerValT2[ALL_TARGET_HT20_15] = 1505 ar9003_hw_eeprom_get_ht20_tgt_pwr(ah, HT_TARGET_RATE_15, freq, 1506 is2GHz); 1507 targetPowerValT2[ALL_TARGET_HT20_20] = 1508 ar9003_hw_eeprom_get_ht20_tgt_pwr(ah, HT_TARGET_RATE_20, freq, 1509 is2GHz); 1510 targetPowerValT2[ALL_TARGET_HT20_21] = 1511 ar9003_hw_eeprom_get_ht20_tgt_pwr(ah, HT_TARGET_RATE_21, freq, 1512 is2GHz); 1513 targetPowerValT2[ALL_TARGET_HT20_22] = 1514 ar9003_hw_eeprom_get_ht20_tgt_pwr(ah, HT_TARGET_RATE_22, freq, 1515 is2GHz); 1516 targetPowerValT2[ALL_TARGET_HT20_23] = 1517 ar9003_hw_eeprom_get_ht20_tgt_pwr(ah, HT_TARGET_RATE_23, freq, 1518 is2GHz); 1519 targetPowerValT2[ALL_TARGET_HT40_0_8_16] = 1520 ar9003_hw_eeprom_get_ht40_tgt_pwr(ah, HT_TARGET_RATE_0_8_16, freq, 1521 is2GHz) + ht40PowerIncForPdadc; 1522 targetPowerValT2[ALL_TARGET_HT40_1_3_9_11_17_19] = 1523 ar9003_hw_eeprom_get_ht40_tgt_pwr(ah, HT_TARGET_RATE_1_3_9_11_17_19, 1524 freq, 1525 is2GHz) + ht40PowerIncForPdadc; 1526 targetPowerValT2[ALL_TARGET_HT40_4] = 1527 ar9003_hw_eeprom_get_ht40_tgt_pwr(ah, HT_TARGET_RATE_4, freq, 1528 is2GHz) + ht40PowerIncForPdadc; 1529 targetPowerValT2[ALL_TARGET_HT40_5] = 1530 ar9003_hw_eeprom_get_ht40_tgt_pwr(ah, HT_TARGET_RATE_5, freq, 1531 is2GHz) + ht40PowerIncForPdadc; 1532 targetPowerValT2[ALL_TARGET_HT40_6] = 1533 ar9003_hw_eeprom_get_ht40_tgt_pwr(ah, HT_TARGET_RATE_6, freq, 1534 is2GHz) + ht40PowerIncForPdadc; 1535 targetPowerValT2[ALL_TARGET_HT40_7] = 1536 ar9003_hw_eeprom_get_ht40_tgt_pwr(ah, HT_TARGET_RATE_7, freq, 1537 is2GHz) + ht40PowerIncForPdadc; 1538 targetPowerValT2[ALL_TARGET_HT40_12] = 1539 ar9003_hw_eeprom_get_ht40_tgt_pwr(ah, HT_TARGET_RATE_12, freq, 1540 is2GHz) + ht40PowerIncForPdadc; 1541 targetPowerValT2[ALL_TARGET_HT40_13] = 1542 ar9003_hw_eeprom_get_ht40_tgt_pwr(ah, HT_TARGET_RATE_13, freq, 1543 is2GHz) + ht40PowerIncForPdadc; 1544 targetPowerValT2[ALL_TARGET_HT40_14] = 1545 ar9003_hw_eeprom_get_ht40_tgt_pwr(ah, HT_TARGET_RATE_14, freq, 1546 is2GHz) + ht40PowerIncForPdadc; 1547 targetPowerValT2[ALL_TARGET_HT40_15] = 1548 ar9003_hw_eeprom_get_ht40_tgt_pwr(ah, HT_TARGET_RATE_15, freq, 1549 is2GHz) + ht40PowerIncForPdadc; 1550 targetPowerValT2[ALL_TARGET_HT40_20] = 1551 ar9003_hw_eeprom_get_ht40_tgt_pwr(ah, HT_TARGET_RATE_20, freq, 1552 is2GHz) + ht40PowerIncForPdadc; 1553 targetPowerValT2[ALL_TARGET_HT40_21] = 1554 ar9003_hw_eeprom_get_ht40_tgt_pwr(ah, HT_TARGET_RATE_21, freq, 1555 is2GHz) + ht40PowerIncForPdadc; 1556 targetPowerValT2[ALL_TARGET_HT40_22] = 1557 ar9003_hw_eeprom_get_ht40_tgt_pwr(ah, HT_TARGET_RATE_22, freq, 1558 is2GHz) + ht40PowerIncForPdadc; 1559 targetPowerValT2[ALL_TARGET_HT40_23] = 1560 ar9003_hw_eeprom_get_ht40_tgt_pwr(ah, HT_TARGET_RATE_23, freq, 1561 is2GHz) + ht40PowerIncForPdadc; 1562 1563 while (i < ar9300RateSize) { 1564 ath_print(common, ATH_DBG_EEPROM, 1565 "TPC[%02d] 0x%08x ", i, targetPowerValT2[i]); 1566 i++; 1567 1568 ath_print(common, ATH_DBG_EEPROM, 1569 "TPC[%02d] 0x%08x ", i, targetPowerValT2[i]); 1570 i++; 1571 1572 ath_print(common, ATH_DBG_EEPROM, 1573 "TPC[%02d] 0x%08x ", i, targetPowerValT2[i]); 1574 i++; 1575 1576 ath_print(common, ATH_DBG_EEPROM, 1577 "TPC[%02d] 0x%08x\n", i, targetPowerValT2[i]); 1578 i++; 1579 } 1580} 1581 1582static int ar9003_hw_cal_pier_get(struct ath_hw *ah, 1583 int mode, 1584 int ipier, 1585 int ichain, 1586 int *pfrequency, 1587 int *pcorrection, 1588 int *ptemperature, int *pvoltage) 1589{ 1590 u8 *pCalPier; 1591 struct ar9300_cal_data_per_freq_op_loop *pCalPierStruct; 1592 int is2GHz; 1593 struct ar9300_eeprom *eep = &ah->eeprom.ar9300_eep; 1594 struct ath_common *common = ath9k_hw_common(ah); 1595 1596 if (ichain >= AR9300_MAX_CHAINS) { 1597 ath_print(common, ATH_DBG_EEPROM, 1598 "Invalid chain index, must be less than %d\n", 1599 AR9300_MAX_CHAINS); 1600 return -1; 1601 } 1602 1603 if (mode) { /* 5GHz */ 1604 if (ipier >= AR9300_NUM_5G_CAL_PIERS) { 1605 ath_print(common, ATH_DBG_EEPROM, 1606 "Invalid 5GHz cal pier index, must " 1607 "be less than %d\n", 1608 AR9300_NUM_5G_CAL_PIERS); 1609 return -1; 1610 } 1611 pCalPier = &(eep->calFreqPier5G[ipier]); 1612 pCalPierStruct = &(eep->calPierData5G[ichain][ipier]); 1613 is2GHz = 0; 1614 } else { 1615 if (ipier >= AR9300_NUM_2G_CAL_PIERS) { 1616 ath_print(common, ATH_DBG_EEPROM, 1617 "Invalid 2GHz cal pier index, must " 1618 "be less than %d\n", AR9300_NUM_2G_CAL_PIERS); 1619 return -1; 1620 } 1621 1622 pCalPier = &(eep->calFreqPier2G[ipier]); 1623 pCalPierStruct = &(eep->calPierData2G[ichain][ipier]); 1624 is2GHz = 1; 1625 } 1626 1627 *pfrequency = FBIN2FREQ(*pCalPier, is2GHz); 1628 *pcorrection = pCalPierStruct->refPower; 1629 *ptemperature = pCalPierStruct->tempMeas; 1630 *pvoltage = pCalPierStruct->voltMeas; 1631 1632 return 0; 1633} 1634 1635static int ar9003_hw_power_control_override(struct ath_hw *ah, 1636 int frequency, 1637 int *correction, 1638 int *voltage, int *temperature) 1639{ 1640 int tempSlope = 0; 1641 struct ar9300_eeprom *eep = &ah->eeprom.ar9300_eep; 1642 1643 REG_RMW(ah, AR_PHY_TPC_11_B0, 1644 (correction[0] << AR_PHY_TPC_OLPC_GAIN_DELTA_S), 1645 AR_PHY_TPC_OLPC_GAIN_DELTA); 1646 REG_RMW(ah, AR_PHY_TPC_11_B1, 1647 (correction[1] << AR_PHY_TPC_OLPC_GAIN_DELTA_S), 1648 AR_PHY_TPC_OLPC_GAIN_DELTA); 1649 REG_RMW(ah, AR_PHY_TPC_11_B2, 1650 (correction[2] << AR_PHY_TPC_OLPC_GAIN_DELTA_S), 1651 AR_PHY_TPC_OLPC_GAIN_DELTA); 1652 1653 /* enable open loop power control on chip */ 1654 REG_RMW(ah, AR_PHY_TPC_6_B0, 1655 (3 << AR_PHY_TPC_6_ERROR_EST_MODE_S), 1656 AR_PHY_TPC_6_ERROR_EST_MODE); 1657 REG_RMW(ah, AR_PHY_TPC_6_B1, 1658 (3 << AR_PHY_TPC_6_ERROR_EST_MODE_S), 1659 AR_PHY_TPC_6_ERROR_EST_MODE); 1660 REG_RMW(ah, AR_PHY_TPC_6_B2, 1661 (3 << AR_PHY_TPC_6_ERROR_EST_MODE_S), 1662 AR_PHY_TPC_6_ERROR_EST_MODE); 1663 1664 /* 1665 * enable temperature compensation 1666 * Need to use register names 1667 */ 1668 if (frequency < 4000) 1669 tempSlope = eep->modalHeader2G.tempSlope; 1670 else 1671 tempSlope = eep->modalHeader5G.tempSlope; 1672 1673 REG_RMW_FIELD(ah, AR_PHY_TPC_19, AR_PHY_TPC_19_ALPHA_THERM, tempSlope); 1674 REG_RMW_FIELD(ah, AR_PHY_TPC_18, AR_PHY_TPC_18_THERM_CAL_VALUE, 1675 temperature[0]); 1676 1677 return 0; 1678} 1679 1680/* Apply the recorded correction values. */ 1681static int ar9003_hw_calibration_apply(struct ath_hw *ah, int frequency) 1682{ 1683 int ichain, ipier, npier; 1684 int mode; 1685 int lfrequency[AR9300_MAX_CHAINS], 1686 lcorrection[AR9300_MAX_CHAINS], 1687 ltemperature[AR9300_MAX_CHAINS], lvoltage[AR9300_MAX_CHAINS]; 1688 int hfrequency[AR9300_MAX_CHAINS], 1689 hcorrection[AR9300_MAX_CHAINS], 1690 htemperature[AR9300_MAX_CHAINS], hvoltage[AR9300_MAX_CHAINS]; 1691 int fdiff; 1692 int correction[AR9300_MAX_CHAINS], 1693 voltage[AR9300_MAX_CHAINS], temperature[AR9300_MAX_CHAINS]; 1694 int pfrequency, pcorrection, ptemperature, pvoltage; 1695 struct ath_common *common = ath9k_hw_common(ah); 1696 1697 mode = (frequency >= 4000); 1698 if (mode) 1699 npier = AR9300_NUM_5G_CAL_PIERS; 1700 else 1701 npier = AR9300_NUM_2G_CAL_PIERS; 1702 1703 for (ichain = 0; ichain < AR9300_MAX_CHAINS; ichain++) { 1704 lfrequency[ichain] = 0; 1705 hfrequency[ichain] = 100000; 1706 } 1707 /* identify best lower and higher frequency calibration measurement */ 1708 for (ichain = 0; ichain < AR9300_MAX_CHAINS; ichain++) { 1709 for (ipier = 0; ipier < npier; ipier++) { 1710 if (!ar9003_hw_cal_pier_get(ah, mode, ipier, ichain, 1711 &pfrequency, &pcorrection, 1712 &ptemperature, &pvoltage)) { 1713 fdiff = frequency - pfrequency; 1714 1715 /* 1716 * this measurement is higher than 1717 * our desired frequency 1718 */ 1719 if (fdiff <= 0) { 1720 if (hfrequency[ichain] <= 0 || 1721 hfrequency[ichain] >= 100000 || 1722 fdiff > 1723 (frequency - hfrequency[ichain])) { 1724 /* 1725 * new best higher 1726 * frequency measurement 1727 */ 1728 hfrequency[ichain] = pfrequency; 1729 hcorrection[ichain] = 1730 pcorrection; 1731 htemperature[ichain] = 1732 ptemperature; 1733 hvoltage[ichain] = pvoltage; 1734 } 1735 } 1736 if (fdiff >= 0) { 1737 if (lfrequency[ichain] <= 0 1738 || fdiff < 1739 (frequency - lfrequency[ichain])) { 1740 /* 1741 * new best lower 1742 * frequency measurement 1743 */ 1744 lfrequency[ichain] = pfrequency; 1745 lcorrection[ichain] = 1746 pcorrection; 1747 ltemperature[ichain] = 1748 ptemperature; 1749 lvoltage[ichain] = pvoltage; 1750 } 1751 } 1752 } 1753 } 1754 } 1755 1756 /* interpolate */ 1757 for (ichain = 0; ichain < AR9300_MAX_CHAINS; ichain++) { 1758 ath_print(common, ATH_DBG_EEPROM, 1759 "ch=%d f=%d low=%d %d h=%d %d\n", 1760 ichain, frequency, lfrequency[ichain], 1761 lcorrection[ichain], hfrequency[ichain], 1762 hcorrection[ichain]); 1763 /* they're the same, so just pick one */ 1764 if (hfrequency[ichain] == lfrequency[ichain]) { 1765 correction[ichain] = lcorrection[ichain]; 1766 voltage[ichain] = lvoltage[ichain]; 1767 temperature[ichain] = ltemperature[ichain]; 1768 } 1769 /* the low frequency is good */ 1770 else if (frequency - lfrequency[ichain] < 1000) { 1771 /* so is the high frequency, interpolate */ 1772 if (hfrequency[ichain] - frequency < 1000) { 1773 1774 correction[ichain] = lcorrection[ichain] + 1775 (((frequency - lfrequency[ichain]) * 1776 (hcorrection[ichain] - 1777 lcorrection[ichain])) / 1778 (hfrequency[ichain] - lfrequency[ichain])); 1779 1780 temperature[ichain] = ltemperature[ichain] + 1781 (((frequency - lfrequency[ichain]) * 1782 (htemperature[ichain] - 1783 ltemperature[ichain])) / 1784 (hfrequency[ichain] - lfrequency[ichain])); 1785 1786 voltage[ichain] = 1787 lvoltage[ichain] + 1788 (((frequency - 1789 lfrequency[ichain]) * (hvoltage[ichain] - 1790 lvoltage[ichain])) 1791 / (hfrequency[ichain] - 1792 lfrequency[ichain])); 1793 } 1794 /* only low is good, use it */ 1795 else { 1796 correction[ichain] = lcorrection[ichain]; 1797 temperature[ichain] = ltemperature[ichain]; 1798 voltage[ichain] = lvoltage[ichain]; 1799 } 1800 } 1801 /* only high is good, use it */ 1802 else if (hfrequency[ichain] - frequency < 1000) { 1803 correction[ichain] = hcorrection[ichain]; 1804 temperature[ichain] = htemperature[ichain]; 1805 voltage[ichain] = hvoltage[ichain]; 1806 } else { /* nothing is good, presume 0???? */ 1807 correction[ichain] = 0; 1808 temperature[ichain] = 0; 1809 voltage[ichain] = 0; 1810 } 1811 } 1812 1813 ar9003_hw_power_control_override(ah, frequency, correction, voltage, 1814 temperature); 1815 1816 ath_print(common, ATH_DBG_EEPROM, 1817 "for frequency=%d, calibration correction = %d %d %d\n", 1818 frequency, correction[0], correction[1], correction[2]); 1819 1820 return 0; 1821} 1822 1823static u16 ar9003_hw_get_direct_edge_power(struct ar9300_eeprom *eep, 1824 int idx, 1825 int edge, 1826 bool is2GHz) 1827{ 1828 struct cal_ctl_data_2g *ctl_2g = eep->ctlPowerData_2G; 1829 struct cal_ctl_data_5g *ctl_5g = eep->ctlPowerData_5G; 1830 1831 if (is2GHz) 1832 return CTL_EDGE_TPOWER(ctl_2g[idx].ctlEdges[edge]); 1833 else 1834 return CTL_EDGE_TPOWER(ctl_5g[idx].ctlEdges[edge]); 1835} 1836 1837static u16 ar9003_hw_get_indirect_edge_power(struct ar9300_eeprom *eep, 1838 int idx, 1839 unsigned int edge, 1840 u16 freq, 1841 bool is2GHz) 1842{ 1843 struct cal_ctl_data_2g *ctl_2g = eep->ctlPowerData_2G; 1844 struct cal_ctl_data_5g *ctl_5g = eep->ctlPowerData_5G; 1845 1846 u8 *ctl_freqbin = is2GHz ? 1847 &eep->ctl_freqbin_2G[idx][0] : 1848 &eep->ctl_freqbin_5G[idx][0]; 1849 1850 if (is2GHz) { 1851 if (ath9k_hw_fbin2freq(ctl_freqbin[edge - 1], 1) < freq && 1852 CTL_EDGE_FLAGS(ctl_2g[idx].ctlEdges[edge - 1])) 1853 return CTL_EDGE_TPOWER(ctl_2g[idx].ctlEdges[edge - 1]); 1854 } else { 1855 if (ath9k_hw_fbin2freq(ctl_freqbin[edge - 1], 0) < freq && 1856 CTL_EDGE_FLAGS(ctl_5g[idx].ctlEdges[edge - 1])) 1857 return CTL_EDGE_TPOWER(ctl_5g[idx].ctlEdges[edge - 1]); 1858 } 1859 1860 return AR9300_MAX_RATE_POWER; 1861} 1862 1863/* 1864 * Find the maximum conformance test limit for the given channel and CTL info 1865 */ 1866static u16 ar9003_hw_get_max_edge_power(struct ar9300_eeprom *eep, 1867 u16 freq, int idx, bool is2GHz) 1868{ 1869 u16 twiceMaxEdgePower = AR9300_MAX_RATE_POWER; 1870 u8 *ctl_freqbin = is2GHz ? 1871 &eep->ctl_freqbin_2G[idx][0] : 1872 &eep->ctl_freqbin_5G[idx][0]; 1873 u16 num_edges = is2GHz ? 1874 AR9300_NUM_BAND_EDGES_2G : AR9300_NUM_BAND_EDGES_5G; 1875 unsigned int edge; 1876 1877 /* Get the edge power */ 1878 for (edge = 0; 1879 (edge < num_edges) && (ctl_freqbin[edge] != AR9300_BCHAN_UNUSED); 1880 edge++) { 1881 /* 1882 * If there's an exact channel match or an inband flag set 1883 * on the lower channel use the given rdEdgePower 1884 */ 1885 if (freq == ath9k_hw_fbin2freq(ctl_freqbin[edge], is2GHz)) { 1886 twiceMaxEdgePower = 1887 ar9003_hw_get_direct_edge_power(eep, idx, 1888 edge, is2GHz); 1889 break; 1890 } else if ((edge > 0) && 1891 (freq < ath9k_hw_fbin2freq(ctl_freqbin[edge], 1892 is2GHz))) { 1893 twiceMaxEdgePower = 1894 ar9003_hw_get_indirect_edge_power(eep, idx, 1895 edge, freq, 1896 is2GHz); 1897 /* 1898 * Leave loop - no more affecting edges possible in 1899 * this monotonic increasing list 1900 */ 1901 break; 1902 } 1903 } 1904 return twiceMaxEdgePower; 1905} 1906 1907static void ar9003_hw_set_power_per_rate_table(struct ath_hw *ah, 1908 struct ath9k_channel *chan, 1909 u8 *pPwrArray, u16 cfgCtl, 1910 u8 twiceAntennaReduction, 1911 u8 twiceMaxRegulatoryPower, 1912 u16 powerLimit) 1913{ 1914 struct ath_regulatory *regulatory = ath9k_hw_regulatory(ah); 1915 struct ath_common *common = ath9k_hw_common(ah); 1916 struct ar9300_eeprom *pEepData = &ah->eeprom.ar9300_eep; 1917 u16 twiceMaxEdgePower = AR9300_MAX_RATE_POWER; 1918 static const u16 tpScaleReductionTable[5] = { 1919 0, 3, 6, 9, AR9300_MAX_RATE_POWER 1920 }; 1921 int i; 1922 int16_t twiceLargestAntenna; 1923 u16 scaledPower = 0, minCtlPower, maxRegAllowedPower; 1924 u16 ctlModesFor11a[] = { 1925 CTL_11A, CTL_5GHT20, CTL_11A_EXT, CTL_5GHT40 1926 }; 1927 u16 ctlModesFor11g[] = { 1928 CTL_11B, CTL_11G, CTL_2GHT20, CTL_11B_EXT, 1929 CTL_11G_EXT, CTL_2GHT40 1930 }; 1931 u16 numCtlModes, *pCtlMode, ctlMode, freq; 1932 struct chan_centers centers; 1933 u8 *ctlIndex; 1934 u8 ctlNum; 1935 u16 twiceMinEdgePower; 1936 bool is2ghz = IS_CHAN_2GHZ(chan); 1937 1938 ath9k_hw_get_channel_centers(ah, chan, ¢ers); 1939 1940 /* Compute TxPower reduction due to Antenna Gain */ 1941 if (is2ghz) 1942 twiceLargestAntenna = pEepData->modalHeader2G.antennaGain; 1943 else 1944 twiceLargestAntenna = pEepData->modalHeader5G.antennaGain; 1945 1946 twiceLargestAntenna = (int16_t)min((twiceAntennaReduction) - 1947 twiceLargestAntenna, 0); 1948 1949 /* 1950 * scaledPower is the minimum of the user input power level 1951 * and the regulatory allowed power level 1952 */ 1953 maxRegAllowedPower = twiceMaxRegulatoryPower + twiceLargestAntenna; 1954 1955 if (regulatory->tp_scale != ATH9K_TP_SCALE_MAX) { 1956 maxRegAllowedPower -= 1957 (tpScaleReductionTable[(regulatory->tp_scale)] * 2); 1958 } 1959 1960 scaledPower = min(powerLimit, maxRegAllowedPower); 1961 1962 /* 1963 * Reduce scaled Power by number of chains active to get 1964 * to per chain tx power level 1965 */ 1966 switch (ar5416_get_ntxchains(ah->txchainmask)) { 1967 case 1: 1968 break; 1969 case 2: 1970 scaledPower -= REDUCE_SCALED_POWER_BY_TWO_CHAIN; 1971 break; 1972 case 3: 1973 scaledPower -= REDUCE_SCALED_POWER_BY_THREE_CHAIN; 1974 break; 1975 } 1976 1977 scaledPower = max((u16)0, scaledPower); 1978 1979 /* 1980 * Get target powers from EEPROM - our baseline for TX Power 1981 */ 1982 if (is2ghz) { 1983 /* Setup for CTL modes */ 1984 /* CTL_11B, CTL_11G, CTL_2GHT20 */ 1985 numCtlModes = 1986 ARRAY_SIZE(ctlModesFor11g) - 1987 SUB_NUM_CTL_MODES_AT_2G_40; 1988 pCtlMode = ctlModesFor11g; 1989 if (IS_CHAN_HT40(chan)) 1990 /* All 2G CTL's */ 1991 numCtlModes = ARRAY_SIZE(ctlModesFor11g); 1992 } else { 1993 /* Setup for CTL modes */ 1994 /* CTL_11A, CTL_5GHT20 */ 1995 numCtlModes = ARRAY_SIZE(ctlModesFor11a) - 1996 SUB_NUM_CTL_MODES_AT_5G_40; 1997 pCtlMode = ctlModesFor11a; 1998 if (IS_CHAN_HT40(chan)) 1999 /* All 5G CTL's */ 2000 numCtlModes = ARRAY_SIZE(ctlModesFor11a); 2001 } 2002 2003 /* 2004 * For MIMO, need to apply regulatory caps individually across 2005 * dynamically running modes: CCK, OFDM, HT20, HT40 2006 * 2007 * The outer loop walks through each possible applicable runtime mode. 2008 * The inner loop walks through each ctlIndex entry in EEPROM. 2009 * The ctl value is encoded as [7:4] == test group, [3:0] == test mode. 2010 */ 2011 for (ctlMode = 0; ctlMode < numCtlModes; ctlMode++) { 2012 bool isHt40CtlMode = (pCtlMode[ctlMode] == CTL_5GHT40) || 2013 (pCtlMode[ctlMode] == CTL_2GHT40); 2014 if (isHt40CtlMode) 2015 freq = centers.synth_center; 2016 else if (pCtlMode[ctlMode] & EXT_ADDITIVE) 2017 freq = centers.ext_center; 2018 else 2019 freq = centers.ctl_center; 2020 2021 ath_print(common, ATH_DBG_REGULATORY, 2022 "LOOP-Mode ctlMode %d < %d, isHt40CtlMode %d, " 2023 "EXT_ADDITIVE %d\n", 2024 ctlMode, numCtlModes, isHt40CtlMode, 2025 (pCtlMode[ctlMode] & EXT_ADDITIVE)); 2026 2027 /* walk through each CTL index stored in EEPROM */ 2028 if (is2ghz) { 2029 ctlIndex = pEepData->ctlIndex_2G; 2030 ctlNum = AR9300_NUM_CTLS_2G; 2031 } else { 2032 ctlIndex = pEepData->ctlIndex_5G; 2033 ctlNum = AR9300_NUM_CTLS_5G; 2034 } 2035 2036 for (i = 0; (i < ctlNum) && ctlIndex[i]; i++) { 2037 ath_print(common, ATH_DBG_REGULATORY, 2038 "LOOP-Ctlidx %d: cfgCtl 0x%2.2x " 2039 "pCtlMode 0x%2.2x ctlIndex 0x%2.2x " 2040 "chan %dn", 2041 i, cfgCtl, pCtlMode[ctlMode], ctlIndex[i], 2042 chan->channel); 2043 2044 /* 2045 * compare test group from regulatory 2046 * channel list with test mode from pCtlMode 2047 * list 2048 */ 2049 if ((((cfgCtl & ~CTL_MODE_M) | 2050 (pCtlMode[ctlMode] & CTL_MODE_M)) == 2051 ctlIndex[i]) || 2052 (((cfgCtl & ~CTL_MODE_M) | 2053 (pCtlMode[ctlMode] & CTL_MODE_M)) == 2054 ((ctlIndex[i] & CTL_MODE_M) | 2055 SD_NO_CTL))) { 2056 twiceMinEdgePower = 2057 ar9003_hw_get_max_edge_power(pEepData, 2058 freq, i, 2059 is2ghz); 2060 2061 if ((cfgCtl & ~CTL_MODE_M) == SD_NO_CTL) 2062 /* 2063 * Find the minimum of all CTL 2064 * edge powers that apply to 2065 * this channel 2066 */ 2067 twiceMaxEdgePower = 2068 min(twiceMaxEdgePower, 2069 twiceMinEdgePower); 2070 else { 2071 /* specific */ 2072 twiceMaxEdgePower = 2073 twiceMinEdgePower; 2074 break; 2075 } 2076 } 2077 } 2078 2079 minCtlPower = (u8)min(twiceMaxEdgePower, scaledPower); 2080 2081 ath_print(common, ATH_DBG_REGULATORY, 2082 "SEL-Min ctlMode %d pCtlMode %d 2xMaxEdge %d " 2083 "sP %d minCtlPwr %d\n", 2084 ctlMode, pCtlMode[ctlMode], twiceMaxEdgePower, 2085 scaledPower, minCtlPower); 2086 2087 /* Apply ctl mode to correct target power set */ 2088 switch (pCtlMode[ctlMode]) { 2089 case CTL_11B: 2090 for (i = ALL_TARGET_LEGACY_1L_5L; 2091 i <= ALL_TARGET_LEGACY_11S; i++) 2092 pPwrArray[i] = 2093 (u8)min((u16)pPwrArray[i], 2094 minCtlPower); 2095 break; 2096 case CTL_11A: 2097 case CTL_11G: 2098 for (i = ALL_TARGET_LEGACY_6_24; 2099 i <= ALL_TARGET_LEGACY_54; i++) 2100 pPwrArray[i] = 2101 (u8)min((u16)pPwrArray[i], 2102 minCtlPower); 2103 break; 2104 case CTL_5GHT20: 2105 case CTL_2GHT20: 2106 for (i = ALL_TARGET_HT20_0_8_16; 2107 i <= ALL_TARGET_HT20_21; i++) 2108 pPwrArray[i] = 2109 (u8)min((u16)pPwrArray[i], 2110 minCtlPower); 2111 pPwrArray[ALL_TARGET_HT20_22] = 2112 (u8)min((u16)pPwrArray[ALL_TARGET_HT20_22], 2113 minCtlPower); 2114 pPwrArray[ALL_TARGET_HT20_23] = 2115 (u8)min((u16)pPwrArray[ALL_TARGET_HT20_23], 2116 minCtlPower); 2117 break; 2118 case CTL_5GHT40: 2119 case CTL_2GHT40: 2120 for (i = ALL_TARGET_HT40_0_8_16; 2121 i <= ALL_TARGET_HT40_23; i++) 2122 pPwrArray[i] = 2123 (u8)min((u16)pPwrArray[i], 2124 minCtlPower); 2125 break; 2126 default: 2127 break; 2128 } 2129 } /* end ctl mode checking */ 2130} 2131 2132static void ath9k_hw_ar9300_set_txpower(struct ath_hw *ah, 2133 struct ath9k_channel *chan, u16 cfgCtl, 2134 u8 twiceAntennaReduction, 2135 u8 twiceMaxRegulatoryPower, 2136 u8 powerLimit) 2137{ 2138 struct ath_common *common = ath9k_hw_common(ah); 2139 u8 targetPowerValT2[ar9300RateSize]; 2140 unsigned int i = 0; 2141 2142 ar9003_hw_set_target_power_eeprom(ah, chan->channel, targetPowerValT2); 2143 ar9003_hw_set_power_per_rate_table(ah, chan, 2144 targetPowerValT2, cfgCtl, 2145 twiceAntennaReduction, 2146 twiceMaxRegulatoryPower, 2147 powerLimit); 2148 2149 while (i < ar9300RateSize) { 2150 ath_print(common, ATH_DBG_EEPROM, 2151 "TPC[%02d] 0x%08x ", i, targetPowerValT2[i]); 2152 i++; 2153 ath_print(common, ATH_DBG_EEPROM, 2154 "TPC[%02d] 0x%08x ", i, targetPowerValT2[i]); 2155 i++; 2156 ath_print(common, ATH_DBG_EEPROM, 2157 "TPC[%02d] 0x%08x ", i, targetPowerValT2[i]); 2158 i++; 2159 ath_print(common, ATH_DBG_EEPROM, 2160 "TPC[%02d] 0x%08x\n\n", i, targetPowerValT2[i]); 2161 i++; 2162 } 2163 2164 /* Write target power array to registers */ 2165 ar9003_hw_tx_power_regwrite(ah, targetPowerValT2); 2166 2167 /* 2168 * This is the TX power we send back to driver core, 2169 * and it can use to pass to userspace to display our 2170 * currently configured TX power setting. 2171 * 2172 * Since power is rate dependent, use one of the indices 2173 * from the AR9300_Rates enum to select an entry from 2174 * targetPowerValT2[] to report. Currently returns the 2175 * power for HT40 MCS 0, HT20 MCS 0, or OFDM 6 Mbps 2176 * as CCK power is less interesting (?). 2177 */ 2178 i = ALL_TARGET_LEGACY_6_24; /* legacy */ 2179 if (IS_CHAN_HT40(chan)) 2180 i = ALL_TARGET_HT40_0_8_16; /* ht40 */ 2181 else if (IS_CHAN_HT20(chan)) 2182 i = ALL_TARGET_HT20_0_8_16; /* ht20 */ 2183 2184 ah->txpower_limit = targetPowerValT2[i]; 2185 2186 ar9003_hw_calibration_apply(ah, chan->channel); 2187} 2188 2189static u16 ath9k_hw_ar9300_get_spur_channel(struct ath_hw *ah, 2190 u16 i, bool is2GHz) 2191{ 2192 return AR_NO_SPUR; 2193} 2194 2195s32 ar9003_hw_get_tx_gain_idx(struct ath_hw *ah) 2196{ 2197 struct ar9300_eeprom *eep = &ah->eeprom.ar9300_eep; 2198 2199 return (eep->baseEepHeader.txrxgain >> 4) & 0xf; /* bits 7:4 */ 2200} 2201 2202s32 ar9003_hw_get_rx_gain_idx(struct ath_hw *ah) 2203{ 2204 struct ar9300_eeprom *eep = &ah->eeprom.ar9300_eep; 2205 2206 return (eep->baseEepHeader.txrxgain) & 0xf; /* bits 3:0 */ 2207} 2208 2209const struct eeprom_ops eep_ar9300_ops = { 2210 .check_eeprom = ath9k_hw_ar9300_check_eeprom, 2211 .get_eeprom = ath9k_hw_ar9300_get_eeprom, 2212 .fill_eeprom = ath9k_hw_ar9300_fill_eeprom, 2213 .get_eeprom_ver = ath9k_hw_ar9300_get_eeprom_ver, 2214 .get_eeprom_rev = ath9k_hw_ar9300_get_eeprom_rev, 2215 .get_num_ant_config = ath9k_hw_ar9300_get_num_ant_config, 2216 .get_eeprom_antenna_cfg = ath9k_hw_ar9300_get_eeprom_antenna_cfg, 2217 .set_board_values = ath9k_hw_ar9300_set_board_values, 2218 .set_addac = ath9k_hw_ar9300_set_addac, 2219 .set_txpower = ath9k_hw_ar9300_set_txpower, 2220 .get_spur_channel = ath9k_hw_ar9300_get_spur_channel 2221}; 2222