1 1.1 alc /* 2 1.1 alc * Copyright (c) 2002-2008 Sam Leffler, Errno Consulting 3 1.1 alc * Copyright (c) 2002-2008 Atheros Communications, Inc. 4 1.1 alc * 5 1.1 alc * Permission to use, copy, modify, and/or distribute this software for any 6 1.1 alc * purpose with or without fee is hereby granted, provided that the above 7 1.1 alc * copyright notice and this permission notice appear in all copies. 8 1.1 alc * 9 1.1 alc * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 10 1.1 alc * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 11 1.1 alc * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 12 1.1 alc * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 13 1.1 alc * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 14 1.1 alc * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 15 1.1 alc * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 16 1.1 alc * 17 1.5 mrg * $Id: ah_eeprom_v3.c,v 1.5 2021/04/13 03:27:13 mrg Exp $ 18 1.1 alc */ 19 1.1 alc #include "opt_ah.h" 20 1.1 alc 21 1.1 alc #include "ah.h" 22 1.1 alc #include "ah_internal.h" 23 1.1 alc #include "ah_eeprom_v3.h" 24 1.1 alc 25 1.1 alc static void 26 1.1 alc getPcdacInterceptsFromPcdacMinMax(HAL_EEPROM *ee, 27 1.1 alc uint16_t pcdacMin, uint16_t pcdacMax, uint16_t *vp) 28 1.1 alc { 29 1.2 alc static const uint16_t intercepts3[] = 30 1.1 alc { 0, 5, 10, 20, 30, 50, 70, 85, 90, 95, 100 }; 31 1.2 alc static const uint16_t intercepts3_2[] = 32 1.1 alc { 0, 10, 20, 30, 40, 50, 60, 70, 80, 90, 100 }; 33 1.1 alc const uint16_t *ip = ee->ee_version < AR_EEPROM_VER3_2 ? 34 1.1 alc intercepts3 : intercepts3_2; 35 1.1 alc int i; 36 1.1 alc 37 1.1 alc /* loop for the percentages in steps or 5 */ 38 1.1 alc for (i = 0; i < NUM_INTERCEPTS; i++ ) 39 1.1 alc *vp++ = (ip[i] * pcdacMax + (100 - ip[i]) * pcdacMin) / 100; 40 1.1 alc } 41 1.1 alc 42 1.1 alc /* 43 1.1 alc * Get channel value from binary representation held in eeprom 44 1.1 alc */ 45 1.1 alc static uint16_t 46 1.1 alc fbin2freq(HAL_EEPROM *ee, uint16_t fbin) 47 1.1 alc { 48 1.1 alc if (fbin == CHANNEL_UNUSED) /* reserved value, don't convert */ 49 1.1 alc return fbin; 50 1.1 alc return ee->ee_version <= AR_EEPROM_VER3_2 ? 51 1.1 alc (fbin > 62 ? 5100 + 10*62 + 5*(fbin-62) : 5100 + 10*fbin) : 52 1.1 alc 4800 + 5*fbin; 53 1.1 alc } 54 1.1 alc 55 1.1 alc static uint16_t 56 1.1 alc fbin2freq_2p4(HAL_EEPROM *ee, uint16_t fbin) 57 1.1 alc { 58 1.1 alc if (fbin == CHANNEL_UNUSED) /* reserved value, don't convert */ 59 1.1 alc return fbin; 60 1.1 alc return ee->ee_version <= AR_EEPROM_VER3_2 ? 61 1.1 alc 2400 + fbin : 62 1.1 alc 2300 + fbin; 63 1.1 alc } 64 1.1 alc 65 1.1 alc /* 66 1.1 alc * Now copy EEPROM frequency pier contents into the allocated space 67 1.1 alc */ 68 1.1 alc static HAL_BOOL 69 1.1 alc readEepromFreqPierInfo(struct ath_hal *ah, HAL_EEPROM *ee) 70 1.1 alc { 71 1.1 alc #define EEREAD(_off) do { \ 72 1.1 alc if (!ath_hal_eepromRead(ah, _off, &eeval)) \ 73 1.1 alc return AH_FALSE; \ 74 1.1 alc } while (0) 75 1.1 alc uint16_t eeval, off; 76 1.1 alc int i; 77 1.1 alc 78 1.1 alc if (ee->ee_version >= AR_EEPROM_VER4_0 && 79 1.1 alc ee->ee_eepMap && !ee->ee_Amode) { 80 1.1 alc /* 81 1.1 alc * V4.0 EEPROMs with map type 1 have frequency pier 82 1.1 alc * data only when 11a mode is supported. 83 1.1 alc */ 84 1.1 alc return AH_TRUE; 85 1.1 alc } 86 1.1 alc if (ee->ee_version >= AR_EEPROM_VER3_3) { 87 1.1 alc off = GROUPS_OFFSET3_3 + GROUP1_OFFSET; 88 1.1 alc for (i = 0; i < ee->ee_numChannels11a; i += 2) { 89 1.1 alc EEREAD(off++); 90 1.1 alc ee->ee_channels11a[i] = (eeval >> 8) & FREQ_MASK_3_3; 91 1.1 alc ee->ee_channels11a[i+1] = eeval & FREQ_MASK_3_3; 92 1.1 alc } 93 1.1 alc } else { 94 1.1 alc off = GROUPS_OFFSET3_2 + GROUP1_OFFSET; 95 1.1 alc 96 1.1 alc EEREAD(off++); 97 1.1 alc ee->ee_channels11a[0] = (eeval >> 9) & FREQ_MASK; 98 1.1 alc ee->ee_channels11a[1] = (eeval >> 2) & FREQ_MASK; 99 1.1 alc ee->ee_channels11a[2] = (eeval << 5) & FREQ_MASK; 100 1.1 alc 101 1.1 alc EEREAD(off++); 102 1.1 alc ee->ee_channels11a[2] |= (eeval >> 11) & 0x1f; 103 1.1 alc ee->ee_channels11a[3] = (eeval >> 4) & FREQ_MASK; 104 1.1 alc ee->ee_channels11a[4] = (eeval << 3) & FREQ_MASK; 105 1.1 alc 106 1.1 alc EEREAD(off++); 107 1.1 alc ee->ee_channels11a[4] |= (eeval >> 13) & 0x7; 108 1.1 alc ee->ee_channels11a[5] = (eeval >> 6) & FREQ_MASK; 109 1.1 alc ee->ee_channels11a[6] = (eeval << 1) & FREQ_MASK; 110 1.1 alc 111 1.1 alc EEREAD(off++); 112 1.1 alc ee->ee_channels11a[6] |= (eeval >> 15) & 0x1; 113 1.1 alc ee->ee_channels11a[7] = (eeval >> 8) & FREQ_MASK; 114 1.1 alc ee->ee_channels11a[8] = (eeval >> 1) & FREQ_MASK; 115 1.1 alc ee->ee_channels11a[9] = (eeval << 6) & FREQ_MASK; 116 1.1 alc 117 1.1 alc EEREAD(off++); 118 1.1 alc ee->ee_channels11a[9] |= (eeval >> 10) & 0x3f; 119 1.1 alc } 120 1.1 alc 121 1.1 alc for (i = 0; i < ee->ee_numChannels11a; i++) 122 1.1 alc ee->ee_channels11a[i] = fbin2freq(ee, ee->ee_channels11a[i]); 123 1.1 alc 124 1.1 alc return AH_TRUE; 125 1.1 alc #undef EEREAD 126 1.1 alc } 127 1.1 alc 128 1.1 alc /* 129 1.1 alc * Rev 4 Eeprom 5112 Power Extract Functions 130 1.1 alc */ 131 1.1 alc 132 1.1 alc /* 133 1.1 alc * Allocate the power information based on the number of channels 134 1.1 alc * recorded by the calibration. These values are then initialized. 135 1.1 alc */ 136 1.1 alc static HAL_BOOL 137 1.1 alc eepromAllocExpnPower5112(struct ath_hal *ah, 138 1.1 alc const EEPROM_POWER_5112 *pCalDataset, 139 1.1 alc EEPROM_POWER_EXPN_5112 *pPowerExpn) 140 1.1 alc { 141 1.1 alc uint16_t numChannels = pCalDataset->numChannels; 142 1.1 alc const uint16_t *pChanList = pCalDataset->pChannels; 143 1.1 alc void *data; 144 1.1 alc int i, j; 145 1.1 alc 146 1.1 alc /* Allocate the channel and Power Data arrays together */ 147 1.1 alc data = ath_hal_malloc( 148 1.1 alc roundup(sizeof(uint16_t) * numChannels, sizeof(uint32_t)) + 149 1.1 alc sizeof(EXPN_DATA_PER_CHANNEL_5112) * numChannels); 150 1.1 alc if (data == AH_NULL) { 151 1.1 alc HALDEBUG(ah, HAL_DEBUG_ANY, 152 1.1 alc "%s unable to allocate raw data struct (gen3)\n", __func__); 153 1.1 alc return AH_FALSE; 154 1.1 alc } 155 1.1 alc pPowerExpn->pChannels = data; 156 1.1 alc pPowerExpn->pDataPerChannel = (void *)(((char *)data) + 157 1.1 alc roundup(sizeof(uint16_t) * numChannels, sizeof(uint32_t))); 158 1.1 alc 159 1.1 alc pPowerExpn->numChannels = numChannels; 160 1.1 alc for (i = 0; i < numChannels; i++) { 161 1.1 alc pPowerExpn->pChannels[i] = 162 1.1 alc pPowerExpn->pDataPerChannel[i].channelValue = 163 1.1 alc pChanList[i]; 164 1.1 alc for (j = 0; j < NUM_XPD_PER_CHANNEL; j++) { 165 1.1 alc pPowerExpn->pDataPerChannel[i].pDataPerXPD[j].xpd_gain = j; 166 1.1 alc pPowerExpn->pDataPerChannel[i].pDataPerXPD[j].numPcdacs = 0; 167 1.1 alc } 168 1.1 alc pPowerExpn->pDataPerChannel[i].pDataPerXPD[0].numPcdacs = 4; 169 1.1 alc pPowerExpn->pDataPerChannel[i].pDataPerXPD[3].numPcdacs = 3; 170 1.1 alc } 171 1.1 alc return AH_TRUE; 172 1.1 alc } 173 1.1 alc 174 1.1 alc /* 175 1.1 alc * Expand the dataSet from the calibration information into the 176 1.1 alc * final power structure for 5112 177 1.1 alc */ 178 1.1 alc static HAL_BOOL 179 1.1 alc eepromExpandPower5112(struct ath_hal *ah, 180 1.1 alc const EEPROM_POWER_5112 *pCalDataset, 181 1.1 alc EEPROM_POWER_EXPN_5112 *pPowerExpn) 182 1.1 alc { 183 1.1 alc int ii, jj, kk; 184 1.1 alc EXPN_DATA_PER_XPD_5112 *pExpnXPD; 185 1.1 alc /* ptr to array of info held per channel */ 186 1.1 alc const EEPROM_DATA_PER_CHANNEL_5112 *pCalCh; 187 1.1 alc uint16_t xgainList[2], xpdMask; 188 1.1 alc 189 1.1 alc pPowerExpn->xpdMask = pCalDataset->xpdMask; 190 1.1 alc 191 1.1 alc xgainList[0] = 0xDEAD; 192 1.1 alc xgainList[1] = 0xDEAD; 193 1.1 alc 194 1.1 alc kk = 0; 195 1.1 alc xpdMask = pPowerExpn->xpdMask; 196 1.1 alc for (jj = 0; jj < NUM_XPD_PER_CHANNEL; jj++) { 197 1.1 alc if (((xpdMask >> jj) & 1) > 0) { 198 1.1 alc if (kk > 1) { 199 1.1 alc HALDEBUG(ah, HAL_DEBUG_ANY, 200 1.1 alc "%s: too many xpdGains in dataset: %u\n", 201 1.1 alc __func__, kk); 202 1.1 alc return AH_FALSE; 203 1.1 alc } 204 1.1 alc xgainList[kk++] = jj; 205 1.1 alc } 206 1.1 alc } 207 1.1 alc 208 1.1 alc pPowerExpn->numChannels = pCalDataset->numChannels; 209 1.1 alc if (pPowerExpn->numChannels == 0) { 210 1.1 alc HALDEBUG(ah, HAL_DEBUG_ANY, "%s: no channels\n", __func__); 211 1.1 alc return AH_FALSE; 212 1.1 alc } 213 1.1 alc 214 1.1 alc for (ii = 0; ii < pPowerExpn->numChannels; ii++) { 215 1.1 alc pCalCh = &pCalDataset->pDataPerChannel[ii]; 216 1.1 alc pPowerExpn->pDataPerChannel[ii].channelValue = 217 1.1 alc pCalCh->channelValue; 218 1.1 alc pPowerExpn->pDataPerChannel[ii].maxPower_t4 = 219 1.1 alc pCalCh->maxPower_t4; 220 1.1 alc 221 1.1 alc for (jj = 0; jj < NUM_XPD_PER_CHANNEL; jj++) 222 1.1 alc pPowerExpn->pDataPerChannel[ii].pDataPerXPD[jj].numPcdacs = 0; 223 1.1 alc if (xgainList[1] == 0xDEAD) { 224 1.1 alc jj = xgainList[0]; 225 1.1 alc pExpnXPD = &pPowerExpn->pDataPerChannel[ii].pDataPerXPD[jj]; 226 1.1 alc pExpnXPD->numPcdacs = 4; 227 1.1 alc pExpnXPD->pcdac[0] = pCalCh->pcd1_xg0; 228 1.1 alc pExpnXPD->pcdac[1] = (uint16_t) 229 1.1 alc (pExpnXPD->pcdac[0] + pCalCh->pcd2_delta_xg0); 230 1.1 alc pExpnXPD->pcdac[2] = (uint16_t) 231 1.1 alc (pExpnXPD->pcdac[1] + pCalCh->pcd3_delta_xg0); 232 1.1 alc pExpnXPD->pcdac[3] = (uint16_t) 233 1.1 alc (pExpnXPD->pcdac[2] + pCalCh->pcd4_delta_xg0); 234 1.1 alc 235 1.1 alc pExpnXPD->pwr_t4[0] = pCalCh->pwr1_xg0; 236 1.1 alc pExpnXPD->pwr_t4[1] = pCalCh->pwr2_xg0; 237 1.1 alc pExpnXPD->pwr_t4[2] = pCalCh->pwr3_xg0; 238 1.1 alc pExpnXPD->pwr_t4[3] = pCalCh->pwr4_xg0; 239 1.1 alc 240 1.1 alc } else { 241 1.1 alc pPowerExpn->pDataPerChannel[ii].pDataPerXPD[xgainList[0]].pcdac[0] = pCalCh->pcd1_xg0; 242 1.1 alc pPowerExpn->pDataPerChannel[ii].pDataPerXPD[xgainList[1]].pcdac[0] = 20; 243 1.1 alc pPowerExpn->pDataPerChannel[ii].pDataPerXPD[xgainList[1]].pcdac[1] = 35; 244 1.1 alc pPowerExpn->pDataPerChannel[ii].pDataPerXPD[xgainList[1]].pcdac[2] = 63; 245 1.1 alc 246 1.1 alc jj = xgainList[0]; 247 1.1 alc pExpnXPD = &pPowerExpn->pDataPerChannel[ii].pDataPerXPD[jj]; 248 1.1 alc pExpnXPD->numPcdacs = 4; 249 1.1 alc pExpnXPD->pcdac[1] = (uint16_t) 250 1.1 alc (pExpnXPD->pcdac[0] + pCalCh->pcd2_delta_xg0); 251 1.1 alc pExpnXPD->pcdac[2] = (uint16_t) 252 1.1 alc (pExpnXPD->pcdac[1] + pCalCh->pcd3_delta_xg0); 253 1.1 alc pExpnXPD->pcdac[3] = (uint16_t) 254 1.1 alc (pExpnXPD->pcdac[2] + pCalCh->pcd4_delta_xg0); 255 1.1 alc pExpnXPD->pwr_t4[0] = pCalCh->pwr1_xg0; 256 1.1 alc pExpnXPD->pwr_t4[1] = pCalCh->pwr2_xg0; 257 1.1 alc pExpnXPD->pwr_t4[2] = pCalCh->pwr3_xg0; 258 1.1 alc pExpnXPD->pwr_t4[3] = pCalCh->pwr4_xg0; 259 1.1 alc 260 1.1 alc jj = xgainList[1]; 261 1.1 alc pExpnXPD = &pPowerExpn->pDataPerChannel[ii].pDataPerXPD[jj]; 262 1.1 alc pExpnXPD->numPcdacs = 3; 263 1.1 alc 264 1.1 alc pExpnXPD->pwr_t4[0] = pCalCh->pwr1_xg3; 265 1.1 alc pExpnXPD->pwr_t4[1] = pCalCh->pwr2_xg3; 266 1.1 alc pExpnXPD->pwr_t4[2] = pCalCh->pwr3_xg3; 267 1.1 alc } 268 1.1 alc } 269 1.1 alc return AH_TRUE; 270 1.1 alc } 271 1.1 alc 272 1.1 alc static HAL_BOOL 273 1.1 alc readEepromRawPowerCalInfo5112(struct ath_hal *ah, HAL_EEPROM *ee) 274 1.1 alc { 275 1.1 alc #define EEREAD(_off) do { \ 276 1.1 alc if (!ath_hal_eepromRead(ah, _off, &eeval)) \ 277 1.1 alc return AH_FALSE; \ 278 1.1 alc } while (0) 279 1.1 alc const uint16_t dbmmask = 0xff; 280 1.1 alc const uint16_t pcdac_delta_mask = 0x1f; 281 1.1 alc const uint16_t pcdac_mask = 0x3f; 282 1.1 alc const uint16_t freqmask = 0xff; 283 1.1 alc 284 1.1 alc int i, mode, numPiers; 285 1.1 alc uint32_t off; 286 1.1 alc uint16_t eeval; 287 1.1 alc uint16_t freq[NUM_11A_EEPROM_CHANNELS]; 288 1.1 alc EEPROM_POWER_5112 eePower; 289 1.1 alc 290 1.1 alc HALASSERT(ee->ee_version >= AR_EEPROM_VER4_0); 291 1.1 alc off = GROUPS_OFFSET3_3; 292 1.1 alc for (mode = headerInfo11A; mode <= headerInfo11G; mode++) { 293 1.1 alc numPiers = 0; 294 1.1 alc switch (mode) { 295 1.1 alc case headerInfo11A: 296 1.1 alc if (!ee->ee_Amode) /* no 11a calibration data */ 297 1.1 alc continue; 298 1.1 alc while (numPiers < NUM_11A_EEPROM_CHANNELS) { 299 1.1 alc EEREAD(off++); 300 1.1 alc if ((eeval & freqmask) == 0) 301 1.1 alc break; 302 1.1 alc freq[numPiers++] = fbin2freq(ee, 303 1.1 alc eeval & freqmask); 304 1.1 alc 305 1.1 alc if (((eeval >> 8) & freqmask) == 0) 306 1.1 alc break; 307 1.1 alc freq[numPiers++] = fbin2freq(ee, 308 1.1 alc (eeval>>8) & freqmask); 309 1.1 alc } 310 1.1 alc break; 311 1.1 alc case headerInfo11B: 312 1.1 alc if (!ee->ee_Bmode) /* no 11b calibration data */ 313 1.1 alc continue; 314 1.1 alc for (i = 0; i < NUM_2_4_EEPROM_CHANNELS; i++) 315 1.1 alc if (ee->ee_calPier11b[i] != CHANNEL_UNUSED) 316 1.1 alc freq[numPiers++] = ee->ee_calPier11b[i]; 317 1.1 alc break; 318 1.1 alc case headerInfo11G: 319 1.1 alc if (!ee->ee_Gmode) /* no 11g calibration data */ 320 1.1 alc continue; 321 1.1 alc for (i = 0; i < NUM_2_4_EEPROM_CHANNELS; i++) 322 1.1 alc if (ee->ee_calPier11g[i] != CHANNEL_UNUSED) 323 1.1 alc freq[numPiers++] = ee->ee_calPier11g[i]; 324 1.1 alc break; 325 1.1 alc default: 326 1.1 alc HALDEBUG(ah, HAL_DEBUG_ANY, "%s: invalid mode 0x%x\n", 327 1.1 alc __func__, mode); 328 1.1 alc return AH_FALSE; 329 1.1 alc } 330 1.1 alc 331 1.1 alc OS_MEMZERO(&eePower, sizeof(eePower)); 332 1.1 alc eePower.numChannels = numPiers; 333 1.1 alc 334 1.1 alc for (i = 0; i < numPiers; i++) { 335 1.1 alc eePower.pChannels[i] = freq[i]; 336 1.1 alc eePower.pDataPerChannel[i].channelValue = freq[i]; 337 1.1 alc 338 1.1 alc EEREAD(off++); 339 1.1 alc eePower.pDataPerChannel[i].pwr1_xg0 = (int16_t) 340 1.1 alc ((eeval & dbmmask) - ((eeval >> 7) & 0x1)*256); 341 1.1 alc eePower.pDataPerChannel[i].pwr2_xg0 = (int16_t) 342 1.1 alc (((eeval >> 8) & dbmmask) - ((eeval >> 15) & 0x1)*256); 343 1.1 alc 344 1.1 alc EEREAD(off++); 345 1.1 alc eePower.pDataPerChannel[i].pwr3_xg0 = (int16_t) 346 1.1 alc ((eeval & dbmmask) - ((eeval >> 7) & 0x1)*256); 347 1.1 alc eePower.pDataPerChannel[i].pwr4_xg0 = (int16_t) 348 1.1 alc (((eeval >> 8) & dbmmask) - ((eeval >> 15) & 0x1)*256); 349 1.1 alc 350 1.1 alc EEREAD(off++); 351 1.1 alc eePower.pDataPerChannel[i].pcd2_delta_xg0 = (uint16_t) 352 1.1 alc (eeval & pcdac_delta_mask); 353 1.1 alc eePower.pDataPerChannel[i].pcd3_delta_xg0 = (uint16_t) 354 1.1 alc ((eeval >> 5) & pcdac_delta_mask); 355 1.1 alc eePower.pDataPerChannel[i].pcd4_delta_xg0 = (uint16_t) 356 1.1 alc ((eeval >> 10) & pcdac_delta_mask); 357 1.1 alc 358 1.1 alc EEREAD(off++); 359 1.1 alc eePower.pDataPerChannel[i].pwr1_xg3 = (int16_t) 360 1.1 alc ((eeval & dbmmask) - ((eeval >> 7) & 0x1)*256); 361 1.1 alc eePower.pDataPerChannel[i].pwr2_xg3 = (int16_t) 362 1.1 alc (((eeval >> 8) & dbmmask) - ((eeval >> 15) & 0x1)*256); 363 1.1 alc 364 1.1 alc EEREAD(off++); 365 1.1 alc eePower.pDataPerChannel[i].pwr3_xg3 = (int16_t) 366 1.1 alc ((eeval & dbmmask) - ((eeval >> 7) & 0x1)*256); 367 1.1 alc if (ee->ee_version >= AR_EEPROM_VER4_3) { 368 1.1 alc eePower.pDataPerChannel[i].maxPower_t4 = 369 1.1 alc eePower.pDataPerChannel[i].pwr4_xg0; 370 1.1 alc eePower.pDataPerChannel[i].pcd1_xg0 = (uint16_t) 371 1.1 alc ((eeval >> 8) & pcdac_mask); 372 1.1 alc } else { 373 1.1 alc eePower.pDataPerChannel[i].maxPower_t4 = (int16_t) 374 1.1 alc (((eeval >> 8) & dbmmask) - 375 1.1 alc ((eeval >> 15) & 0x1)*256); 376 1.1 alc eePower.pDataPerChannel[i].pcd1_xg0 = 1; 377 1.1 alc } 378 1.1 alc } 379 1.1 alc eePower.xpdMask = ee->ee_xgain[mode]; 380 1.1 alc 381 1.1 alc if (!eepromAllocExpnPower5112(ah, &eePower, &ee->ee_modePowerArray5112[mode])) { 382 1.1 alc HALDEBUG(ah, HAL_DEBUG_ANY, 383 1.1 alc "%s: did not allocate power struct\n", __func__); 384 1.1 alc return AH_FALSE; 385 1.1 alc } 386 1.1 alc if (!eepromExpandPower5112(ah, &eePower, &ee->ee_modePowerArray5112[mode])) { 387 1.1 alc HALDEBUG(ah, HAL_DEBUG_ANY, 388 1.1 alc "%s: did not expand power struct\n", __func__); 389 1.1 alc return AH_FALSE; 390 1.1 alc } 391 1.1 alc } 392 1.1 alc return AH_TRUE; 393 1.1 alc #undef EEREAD 394 1.1 alc } 395 1.1 alc 396 1.1 alc static void 397 1.1 alc freeEepromRawPowerCalInfo5112(struct ath_hal *ah, HAL_EEPROM *ee) 398 1.1 alc { 399 1.1 alc int mode; 400 1.1 alc void *data; 401 1.1 alc 402 1.1 alc for (mode = headerInfo11A; mode <= headerInfo11G; mode++) { 403 1.1 alc EEPROM_POWER_EXPN_5112 *pPowerExpn = 404 1.1 alc &ee->ee_modePowerArray5112[mode]; 405 1.1 alc data = pPowerExpn->pChannels; 406 1.1 alc if (data != AH_NULL) { 407 1.1 alc pPowerExpn->pChannels = AH_NULL; 408 1.1 alc ath_hal_free(data); 409 1.1 alc } 410 1.1 alc } 411 1.1 alc } 412 1.1 alc 413 1.1 alc static void 414 1.1 alc ar2413SetupEEPROMDataset(EEPROM_DATA_STRUCT_2413 *pEEPROMDataset2413, 415 1.1 alc uint16_t myNumRawChannels, uint16_t *pMyRawChanList) 416 1.1 alc { 417 1.1 alc uint16_t i, channelValue; 418 1.1 alc uint32_t xpd_mask; 419 1.1 alc uint16_t numPdGainsUsed; 420 1.1 alc 421 1.1 alc pEEPROMDataset2413->numChannels = myNumRawChannels; 422 1.1 alc 423 1.1 alc xpd_mask = pEEPROMDataset2413->xpd_mask; 424 1.1 alc numPdGainsUsed = 0; 425 1.1 alc if ((xpd_mask >> 0) & 0x1) numPdGainsUsed++; 426 1.1 alc if ((xpd_mask >> 1) & 0x1) numPdGainsUsed++; 427 1.1 alc if ((xpd_mask >> 2) & 0x1) numPdGainsUsed++; 428 1.1 alc if ((xpd_mask >> 3) & 0x1) numPdGainsUsed++; 429 1.1 alc 430 1.1 alc for (i = 0; i < myNumRawChannels; i++) { 431 1.1 alc channelValue = pMyRawChanList[i]; 432 1.1 alc pEEPROMDataset2413->pChannels[i] = channelValue; 433 1.1 alc pEEPROMDataset2413->pDataPerChannel[i].channelValue = channelValue; 434 1.1 alc pEEPROMDataset2413->pDataPerChannel[i].numPdGains = numPdGainsUsed; 435 1.1 alc } 436 1.1 alc } 437 1.1 alc 438 1.1 alc static HAL_BOOL 439 1.1 alc ar2413ReadCalDataset(struct ath_hal *ah, HAL_EEPROM *ee, 440 1.1 alc EEPROM_DATA_STRUCT_2413 *pCalDataset, 441 1.1 alc uint32_t start_offset, uint32_t maxPiers, uint8_t mode) 442 1.1 alc { 443 1.1 alc #define EEREAD(_off) do { \ 444 1.1 alc if (!ath_hal_eepromRead(ah, _off, &eeval)) \ 445 1.1 alc return AH_FALSE; \ 446 1.1 alc } while (0) 447 1.1 alc const uint16_t dbm_I_mask = 0x1F; /* 5-bits. 1dB step. */ 448 1.1 alc const uint16_t dbm_delta_mask = 0xF; /* 4-bits. 0.5dB step. */ 449 1.1 alc const uint16_t Vpd_I_mask = 0x7F; /* 7-bits. 0-128 */ 450 1.1 alc const uint16_t Vpd_delta_mask = 0x3F; /* 6-bits. 0-63 */ 451 1.1 alc const uint16_t freqmask = 0xff; 452 1.1 alc 453 1.1 alc uint16_t ii, eeval; 454 1.1 alc uint16_t idx, numPiers; 455 1.1 alc uint16_t freq[NUM_11A_EEPROM_CHANNELS]; 456 1.1 alc 457 1.1 alc idx = start_offset; 458 1.1 alc for (numPiers = 0; numPiers < maxPiers;) { 459 1.1 alc EEREAD(idx++); 460 1.1 alc if ((eeval & freqmask) == 0) 461 1.1 alc break; 462 1.1 alc if (mode == headerInfo11A) 463 1.1 alc freq[numPiers++] = fbin2freq(ee, (eeval & freqmask)); 464 1.1 alc else 465 1.1 alc freq[numPiers++] = fbin2freq_2p4(ee, (eeval & freqmask)); 466 1.1 alc 467 1.1 alc if (((eeval >> 8) & freqmask) == 0) 468 1.1 alc break; 469 1.1 alc if (mode == headerInfo11A) 470 1.1 alc freq[numPiers++] = fbin2freq(ee, (eeval >> 8) & freqmask); 471 1.1 alc else 472 1.1 alc freq[numPiers++] = fbin2freq_2p4(ee, (eeval >> 8) & freqmask); 473 1.1 alc } 474 1.1 alc ar2413SetupEEPROMDataset(pCalDataset, numPiers, &freq[0]); 475 1.1 alc 476 1.1 alc idx = start_offset + (maxPiers / 2); 477 1.1 alc for (ii = 0; ii < pCalDataset->numChannels; ii++) { 478 1.1 alc EEPROM_DATA_PER_CHANNEL_2413 *currCh = 479 1.1 alc &(pCalDataset->pDataPerChannel[ii]); 480 1.1 alc 481 1.1 alc if (currCh->numPdGains > 0) { 482 1.1 alc /* 483 1.1 alc * Read the first NUM_POINTS_OTHER_PDGAINS pwr 484 1.1 alc * and Vpd values for pdgain_0 485 1.1 alc */ 486 1.1 alc EEREAD(idx++); 487 1.1 alc currCh->pwr_I[0] = eeval & dbm_I_mask; 488 1.1 alc currCh->Vpd_I[0] = (eeval >> 5) & Vpd_I_mask; 489 1.1 alc currCh->pwr_delta_t2[0][0] = 490 1.1 alc (eeval >> 12) & dbm_delta_mask; 491 1.1 alc 492 1.1 alc EEREAD(idx++); 493 1.1 alc currCh->Vpd_delta[0][0] = eeval & Vpd_delta_mask; 494 1.1 alc currCh->pwr_delta_t2[1][0] = 495 1.1 alc (eeval >> 6) & dbm_delta_mask; 496 1.1 alc currCh->Vpd_delta[1][0] = 497 1.1 alc (eeval >> 10) & Vpd_delta_mask; 498 1.1 alc 499 1.1 alc EEREAD(idx++); 500 1.1 alc currCh->pwr_delta_t2[2][0] = eeval & dbm_delta_mask; 501 1.1 alc currCh->Vpd_delta[2][0] = (eeval >> 4) & Vpd_delta_mask; 502 1.1 alc } 503 1.1 alc 504 1.1 alc if (currCh->numPdGains > 1) { 505 1.1 alc /* 506 1.1 alc * Read the first NUM_POINTS_OTHER_PDGAINS pwr 507 1.1 alc * and Vpd values for pdgain_1 508 1.1 alc */ 509 1.1 alc currCh->pwr_I[1] = (eeval >> 10) & dbm_I_mask; 510 1.1 alc currCh->Vpd_I[1] = (eeval >> 15) & 0x1; 511 1.1 alc 512 1.1 alc EEREAD(idx++); 513 1.1 alc /* upper 6 bits */ 514 1.1 alc currCh->Vpd_I[1] |= (eeval & 0x3F) << 1; 515 1.1 alc currCh->pwr_delta_t2[0][1] = 516 1.1 alc (eeval >> 6) & dbm_delta_mask; 517 1.1 alc currCh->Vpd_delta[0][1] = 518 1.1 alc (eeval >> 10) & Vpd_delta_mask; 519 1.1 alc 520 1.1 alc EEREAD(idx++); 521 1.1 alc currCh->pwr_delta_t2[1][1] = eeval & dbm_delta_mask; 522 1.1 alc currCh->Vpd_delta[1][1] = (eeval >> 4) & Vpd_delta_mask; 523 1.1 alc currCh->pwr_delta_t2[2][1] = 524 1.1 alc (eeval >> 10) & dbm_delta_mask; 525 1.1 alc currCh->Vpd_delta[2][1] = (eeval >> 14) & 0x3; 526 1.1 alc 527 1.1 alc EEREAD(idx++); 528 1.1 alc /* upper 4 bits */ 529 1.1 alc currCh->Vpd_delta[2][1] |= (eeval & 0xF) << 2; 530 1.1 alc } else if (currCh->numPdGains == 1) { 531 1.1 alc /* 532 1.1 alc * Read the last pwr and Vpd values for pdgain_0 533 1.1 alc */ 534 1.1 alc currCh->pwr_delta_t2[3][0] = 535 1.1 alc (eeval >> 10) & dbm_delta_mask; 536 1.1 alc currCh->Vpd_delta[3][0] = (eeval >> 14) & 0x3; 537 1.1 alc 538 1.1 alc EEREAD(idx++); 539 1.1 alc /* upper 4 bits */ 540 1.1 alc currCh->Vpd_delta[3][0] |= (eeval & 0xF) << 2; 541 1.1 alc 542 1.1 alc /* 4 words if numPdGains == 1 */ 543 1.1 alc } 544 1.1 alc 545 1.1 alc if (currCh->numPdGains > 2) { 546 1.1 alc /* 547 1.1 alc * Read the first NUM_POINTS_OTHER_PDGAINS pwr 548 1.1 alc * and Vpd values for pdgain_2 549 1.1 alc */ 550 1.1 alc currCh->pwr_I[2] = (eeval >> 4) & dbm_I_mask; 551 1.1 alc currCh->Vpd_I[2] = (eeval >> 9) & Vpd_I_mask; 552 1.1 alc 553 1.1 alc EEREAD(idx++); 554 1.1 alc currCh->pwr_delta_t2[0][2] = 555 1.1 alc (eeval >> 0) & dbm_delta_mask; 556 1.1 alc currCh->Vpd_delta[0][2] = (eeval >> 4) & Vpd_delta_mask; 557 1.1 alc currCh->pwr_delta_t2[1][2] = 558 1.1 alc (eeval >> 10) & dbm_delta_mask; 559 1.1 alc currCh->Vpd_delta[1][2] = (eeval >> 14) & 0x3; 560 1.1 alc 561 1.1 alc EEREAD(idx++); 562 1.1 alc /* upper 4 bits */ 563 1.1 alc currCh->Vpd_delta[1][2] |= (eeval & 0xF) << 2; 564 1.1 alc currCh->pwr_delta_t2[2][2] = 565 1.1 alc (eeval >> 4) & dbm_delta_mask; 566 1.1 alc currCh->Vpd_delta[2][2] = (eeval >> 8) & Vpd_delta_mask; 567 1.1 alc } else if (currCh->numPdGains == 2) { 568 1.1 alc /* 569 1.1 alc * Read the last pwr and Vpd values for pdgain_1 570 1.1 alc */ 571 1.1 alc currCh->pwr_delta_t2[3][1] = 572 1.1 alc (eeval >> 4) & dbm_delta_mask; 573 1.1 alc currCh->Vpd_delta[3][1] = (eeval >> 8) & Vpd_delta_mask; 574 1.1 alc 575 1.1 alc /* 6 words if numPdGains == 2 */ 576 1.1 alc } 577 1.1 alc 578 1.1 alc if (currCh->numPdGains > 3) { 579 1.1 alc /* 580 1.1 alc * Read the first NUM_POINTS_OTHER_PDGAINS pwr 581 1.1 alc * and Vpd values for pdgain_3 582 1.1 alc */ 583 1.1 alc currCh->pwr_I[3] = (eeval >> 14) & 0x3; 584 1.1 alc 585 1.1 alc EEREAD(idx++); 586 1.1 alc /* upper 3 bits */ 587 1.1 alc currCh->pwr_I[3] |= ((eeval >> 0) & 0x7) << 2; 588 1.1 alc currCh->Vpd_I[3] = (eeval >> 3) & Vpd_I_mask; 589 1.1 alc currCh->pwr_delta_t2[0][3] = 590 1.1 alc (eeval >> 10) & dbm_delta_mask; 591 1.1 alc currCh->Vpd_delta[0][3] = (eeval >> 14) & 0x3; 592 1.1 alc 593 1.1 alc EEREAD(idx++); 594 1.1 alc /* upper 4 bits */ 595 1.1 alc currCh->Vpd_delta[0][3] |= (eeval & 0xF) << 2; 596 1.1 alc currCh->pwr_delta_t2[1][3] = 597 1.1 alc (eeval >> 4) & dbm_delta_mask; 598 1.1 alc currCh->Vpd_delta[1][3] = (eeval >> 8) & Vpd_delta_mask; 599 1.1 alc currCh->pwr_delta_t2[2][3] = (eeval >> 14) & 0x3; 600 1.1 alc 601 1.1 alc EEREAD(idx++); 602 1.1 alc /* upper 2 bits */ 603 1.1 alc currCh->pwr_delta_t2[2][3] |= ((eeval >> 0) & 0x3) << 2; 604 1.1 alc currCh->Vpd_delta[2][3] = (eeval >> 2) & Vpd_delta_mask; 605 1.1 alc currCh->pwr_delta_t2[3][3] = 606 1.1 alc (eeval >> 8) & dbm_delta_mask; 607 1.1 alc currCh->Vpd_delta[3][3] = (eeval >> 12) & 0xF; 608 1.1 alc 609 1.1 alc EEREAD(idx++); 610 1.1 alc /* upper 2 bits */ 611 1.1 alc currCh->Vpd_delta[3][3] |= ((eeval >> 0) & 0x3) << 4; 612 1.1 alc 613 1.1 alc /* 12 words if numPdGains == 4 */ 614 1.1 alc } else if (currCh->numPdGains == 3) { 615 1.1 alc /* read the last pwr and Vpd values for pdgain_2 */ 616 1.1 alc currCh->pwr_delta_t2[3][2] = (eeval >> 14) & 0x3; 617 1.1 alc 618 1.1 alc EEREAD(idx++); 619 1.1 alc /* upper 2 bits */ 620 1.1 alc currCh->pwr_delta_t2[3][2] |= ((eeval >> 0) & 0x3) << 2; 621 1.1 alc currCh->Vpd_delta[3][2] = (eeval >> 2) & Vpd_delta_mask; 622 1.1 alc 623 1.1 alc /* 9 words if numPdGains == 3 */ 624 1.1 alc } 625 1.1 alc } 626 1.1 alc return AH_TRUE; 627 1.1 alc #undef EEREAD 628 1.1 alc } 629 1.1 alc 630 1.1 alc static void 631 1.1 alc ar2413SetupRawDataset(RAW_DATA_STRUCT_2413 *pRaw, EEPROM_DATA_STRUCT_2413 *pCal) 632 1.1 alc { 633 1.1 alc uint16_t i, j, kk, channelValue; 634 1.1 alc uint16_t xpd_mask; 635 1.1 alc uint16_t numPdGainsUsed; 636 1.1 alc 637 1.1 alc pRaw->numChannels = pCal->numChannels; 638 1.1 alc 639 1.1 alc xpd_mask = pRaw->xpd_mask; 640 1.1 alc numPdGainsUsed = 0; 641 1.1 alc if ((xpd_mask >> 0) & 0x1) numPdGainsUsed++; 642 1.1 alc if ((xpd_mask >> 1) & 0x1) numPdGainsUsed++; 643 1.1 alc if ((xpd_mask >> 2) & 0x1) numPdGainsUsed++; 644 1.1 alc if ((xpd_mask >> 3) & 0x1) numPdGainsUsed++; 645 1.1 alc 646 1.1 alc for (i = 0; i < pCal->numChannels; i++) { 647 1.1 alc channelValue = pCal->pChannels[i]; 648 1.1 alc 649 1.1 alc pRaw->pChannels[i] = channelValue; 650 1.1 alc 651 1.1 alc pRaw->pDataPerChannel[i].channelValue = channelValue; 652 1.1 alc pRaw->pDataPerChannel[i].numPdGains = numPdGainsUsed; 653 1.1 alc 654 1.1 alc kk = 0; 655 1.1 alc for (j = 0; j < MAX_NUM_PDGAINS_PER_CHANNEL; j++) { 656 1.1 alc pRaw->pDataPerChannel[i].pDataPerPDGain[j].pd_gain = j; 657 1.1 alc if ((xpd_mask >> j) & 0x1) { 658 1.1 alc pRaw->pDataPerChannel[i].pDataPerPDGain[j].numVpd = NUM_POINTS_OTHER_PDGAINS; 659 1.1 alc kk++; 660 1.1 alc if (kk == 1) { 661 1.1 alc /* 662 1.1 alc * lowest pd_gain corresponds 663 1.1 alc * to highest power and thus, 664 1.1 alc * has one more point 665 1.1 alc */ 666 1.1 alc pRaw->pDataPerChannel[i].pDataPerPDGain[j].numVpd = NUM_POINTS_LAST_PDGAIN; 667 1.1 alc } 668 1.1 alc } else { 669 1.1 alc pRaw->pDataPerChannel[i].pDataPerPDGain[j].numVpd = 0; 670 1.1 alc } 671 1.1 alc } 672 1.1 alc } 673 1.1 alc } 674 1.1 alc 675 1.1 alc static HAL_BOOL 676 1.1 alc ar2413EepromToRawDataset(struct ath_hal *ah, 677 1.1 alc EEPROM_DATA_STRUCT_2413 *pCal, RAW_DATA_STRUCT_2413 *pRaw) 678 1.1 alc { 679 1.1 alc uint16_t ii, jj, kk, ss; 680 1.1 alc RAW_DATA_PER_PDGAIN_2413 *pRawXPD; 681 1.1 alc /* ptr to array of info held per channel */ 682 1.1 alc EEPROM_DATA_PER_CHANNEL_2413 *pCalCh; 683 1.1 alc uint16_t xgain_list[MAX_NUM_PDGAINS_PER_CHANNEL]; 684 1.1 alc uint16_t xpd_mask; 685 1.1 alc uint32_t numPdGainsUsed; 686 1.1 alc 687 1.1 alc HALASSERT(pRaw->xpd_mask == pCal->xpd_mask); 688 1.1 alc 689 1.1 alc xgain_list[0] = 0xDEAD; 690 1.1 alc xgain_list[1] = 0xDEAD; 691 1.1 alc xgain_list[2] = 0xDEAD; 692 1.1 alc xgain_list[3] = 0xDEAD; 693 1.1 alc 694 1.1 alc numPdGainsUsed = 0; 695 1.1 alc xpd_mask = pRaw->xpd_mask; 696 1.1 alc for (jj = 0; jj < MAX_NUM_PDGAINS_PER_CHANNEL; jj++) { 697 1.1 alc if ((xpd_mask >> (MAX_NUM_PDGAINS_PER_CHANNEL-jj-1)) & 1) 698 1.1 alc xgain_list[numPdGainsUsed++] = MAX_NUM_PDGAINS_PER_CHANNEL-jj-1; 699 1.1 alc } 700 1.1 alc 701 1.1 alc pRaw->numChannels = pCal->numChannels; 702 1.1 alc for (ii = 0; ii < pRaw->numChannels; ii++) { 703 1.1 alc pCalCh = &(pCal->pDataPerChannel[ii]); 704 1.1 alc pRaw->pDataPerChannel[ii].channelValue = pCalCh->channelValue; 705 1.1 alc 706 1.1 alc /* numVpd has already been setup appropriately for the relevant pdGains */ 707 1.1 alc for (jj = 0; jj < numPdGainsUsed; jj++) { 708 1.1 alc /* use jj for calDataset and ss for rawDataset */ 709 1.1 alc ss = xgain_list[jj]; 710 1.1 alc pRawXPD = &(pRaw->pDataPerChannel[ii].pDataPerPDGain[ss]); 711 1.1 alc HALASSERT(pRawXPD->numVpd >= 1); 712 1.1 alc 713 1.1 alc pRawXPD->pwr_t4[0] = (uint16_t)(4*pCalCh->pwr_I[jj]); 714 1.1 alc pRawXPD->Vpd[0] = pCalCh->Vpd_I[jj]; 715 1.1 alc 716 1.1 alc for (kk = 1; kk < pRawXPD->numVpd; kk++) { 717 1.1 alc pRawXPD->pwr_t4[kk] = (int16_t)(pRawXPD->pwr_t4[kk-1] + 2*pCalCh->pwr_delta_t2[kk-1][jj]); 718 1.1 alc pRawXPD->Vpd[kk] = (uint16_t)(pRawXPD->Vpd[kk-1] + pCalCh->Vpd_delta[kk-1][jj]); 719 1.1 alc } 720 1.1 alc /* loop over Vpds */ 721 1.1 alc } 722 1.1 alc /* loop over pd_gains */ 723 1.1 alc } 724 1.1 alc /* loop over channels */ 725 1.1 alc return AH_TRUE; 726 1.1 alc } 727 1.1 alc 728 1.1 alc static HAL_BOOL 729 1.1 alc readEepromRawPowerCalInfo2413(struct ath_hal *ah, HAL_EEPROM *ee) 730 1.1 alc { 731 1.1 alc /* NB: index is 1 less than numPdgains */ 732 1.1 alc static const uint16_t wordsForPdgains[] = { 4, 6, 9, 12 }; 733 1.1 alc EEPROM_DATA_STRUCT_2413 *pCal = AH_NULL; 734 1.1 alc RAW_DATA_STRUCT_2413 *pRaw; 735 1.1 alc int numEEPROMWordsPerChannel; 736 1.1 alc uint32_t off; 737 1.1 alc HAL_BOOL ret = AH_FALSE; 738 1.1 alc 739 1.1 alc HALASSERT(ee->ee_version >= AR_EEPROM_VER5_0); 740 1.1 alc HALASSERT(ee->ee_eepMap == 2); 741 1.1 alc 742 1.1 alc pCal = ath_hal_malloc(sizeof(EEPROM_DATA_STRUCT_2413)); 743 1.1 alc if (pCal == AH_NULL) 744 1.1 alc goto exit; 745 1.1 alc 746 1.1 alc off = ee->ee_eepMap2PowerCalStart; 747 1.1 alc if (ee->ee_Amode) { 748 1.1 alc OS_MEMZERO(pCal, sizeof(EEPROM_DATA_STRUCT_2413)); 749 1.1 alc pCal->xpd_mask = ee->ee_xgain[headerInfo11A]; 750 1.1 alc if (!ar2413ReadCalDataset(ah, ee, pCal, off, 751 1.1 alc NUM_11A_EEPROM_CHANNELS_2413, headerInfo11A)) { 752 1.1 alc goto exit; 753 1.1 alc } 754 1.1 alc pRaw = &ee->ee_rawDataset2413[headerInfo11A]; 755 1.1 alc pRaw->xpd_mask = ee->ee_xgain[headerInfo11A]; 756 1.1 alc ar2413SetupRawDataset(pRaw, pCal); 757 1.1 alc if (!ar2413EepromToRawDataset(ah, pCal, pRaw)) { 758 1.1 alc goto exit; 759 1.1 alc } 760 1.1 alc /* setup offsets for mode_11a next */ 761 1.1 alc numEEPROMWordsPerChannel = wordsForPdgains[ 762 1.1 alc pCal->pDataPerChannel[0].numPdGains - 1]; 763 1.1 alc off += pCal->numChannels * numEEPROMWordsPerChannel + 5; 764 1.1 alc } 765 1.1 alc if (ee->ee_Bmode) { 766 1.1 alc OS_MEMZERO(pCal, sizeof(EEPROM_DATA_STRUCT_2413)); 767 1.1 alc pCal->xpd_mask = ee->ee_xgain[headerInfo11B]; 768 1.1 alc if (!ar2413ReadCalDataset(ah, ee, pCal, off, 769 1.1 alc NUM_2_4_EEPROM_CHANNELS_2413 , headerInfo11B)) { 770 1.1 alc goto exit; 771 1.1 alc } 772 1.1 alc pRaw = &ee->ee_rawDataset2413[headerInfo11B]; 773 1.1 alc pRaw->xpd_mask = ee->ee_xgain[headerInfo11B]; 774 1.1 alc ar2413SetupRawDataset(pRaw, pCal); 775 1.1 alc if (!ar2413EepromToRawDataset(ah, pCal, pRaw)) { 776 1.1 alc goto exit; 777 1.1 alc } 778 1.1 alc /* setup offsets for mode_11g next */ 779 1.1 alc numEEPROMWordsPerChannel = wordsForPdgains[ 780 1.1 alc pCal->pDataPerChannel[0].numPdGains - 1]; 781 1.1 alc off += pCal->numChannels * numEEPROMWordsPerChannel + 2; 782 1.1 alc } 783 1.1 alc if (ee->ee_Gmode) { 784 1.1 alc OS_MEMZERO(pCal, sizeof(EEPROM_DATA_STRUCT_2413)); 785 1.1 alc pCal->xpd_mask = ee->ee_xgain[headerInfo11G]; 786 1.1 alc if (!ar2413ReadCalDataset(ah, ee, pCal, off, 787 1.1 alc NUM_2_4_EEPROM_CHANNELS_2413, headerInfo11G)) { 788 1.1 alc goto exit; 789 1.1 alc } 790 1.1 alc pRaw = &ee->ee_rawDataset2413[headerInfo11G]; 791 1.1 alc pRaw->xpd_mask = ee->ee_xgain[headerInfo11G]; 792 1.1 alc ar2413SetupRawDataset(pRaw, pCal); 793 1.1 alc if (!ar2413EepromToRawDataset(ah, pCal, pRaw)) { 794 1.1 alc goto exit; 795 1.1 alc } 796 1.1 alc } 797 1.1 alc ret = AH_TRUE; 798 1.1 alc exit: 799 1.1 alc if (pCal != AH_NULL) 800 1.1 alc ath_hal_free(pCal); 801 1.1 alc return ret; 802 1.1 alc } 803 1.1 alc 804 1.1 alc /* 805 1.1 alc * Now copy EEPROM Raw Power Calibration per frequency contents 806 1.1 alc * into the allocated space 807 1.1 alc */ 808 1.1 alc static HAL_BOOL 809 1.1 alc readEepromRawPowerCalInfo(struct ath_hal *ah, HAL_EEPROM *ee) 810 1.1 alc { 811 1.1 alc #define EEREAD(_off) do { \ 812 1.1 alc if (!ath_hal_eepromRead(ah, _off, &eeval)) \ 813 1.1 alc return AH_FALSE; \ 814 1.1 alc } while (0) 815 1.1 alc uint16_t eeval, nchan; 816 1.1 alc uint32_t off; 817 1.1 alc int i, j, mode; 818 1.1 alc 819 1.1 alc if (ee->ee_version >= AR_EEPROM_VER4_0 && ee->ee_eepMap == 1) 820 1.1 alc return readEepromRawPowerCalInfo5112(ah, ee); 821 1.1 alc if (ee->ee_version >= AR_EEPROM_VER5_0 && ee->ee_eepMap == 2) 822 1.1 alc return readEepromRawPowerCalInfo2413(ah, ee); 823 1.1 alc 824 1.1 alc /* 825 1.1 alc * Group 2: read raw power data for all frequency piers 826 1.1 alc * 827 1.1 alc * NOTE: Group 2 contains the raw power calibration 828 1.1 alc * information for each of the channels that 829 1.1 alc * we recorded above. 830 1.1 alc */ 831 1.1 alc for (mode = headerInfo11A; mode <= headerInfo11G; mode++) { 832 1.1 alc uint16_t *pChannels = AH_NULL; 833 1.1 alc DATA_PER_CHANNEL *pChannelData = AH_NULL; 834 1.1 alc 835 1.1 alc off = ee->ee_version >= AR_EEPROM_VER3_3 ? 836 1.1 alc GROUPS_OFFSET3_3 : GROUPS_OFFSET3_2; 837 1.1 alc switch (mode) { 838 1.1 alc case headerInfo11A: 839 1.1 alc off += GROUP2_OFFSET; 840 1.1 alc nchan = ee->ee_numChannels11a; 841 1.1 alc pChannelData = ee->ee_dataPerChannel11a; 842 1.1 alc pChannels = ee->ee_channels11a; 843 1.1 alc break; 844 1.1 alc case headerInfo11B: 845 1.1 alc if (!ee->ee_Bmode) 846 1.1 alc continue; 847 1.1 alc off += GROUP3_OFFSET; 848 1.1 alc nchan = ee->ee_numChannels2_4; 849 1.1 alc pChannelData = ee->ee_dataPerChannel11b; 850 1.1 alc pChannels = ee->ee_channels11b; 851 1.1 alc break; 852 1.1 alc case headerInfo11G: 853 1.1 alc if (!ee->ee_Gmode) 854 1.1 alc continue; 855 1.1 alc off += GROUP4_OFFSET; 856 1.1 alc nchan = ee->ee_numChannels2_4; 857 1.1 alc pChannelData = ee->ee_dataPerChannel11g; 858 1.1 alc pChannels = ee->ee_channels11g; 859 1.1 alc break; 860 1.1 alc default: 861 1.1 alc HALDEBUG(ah, HAL_DEBUG_ANY, "%s: invalid mode 0x%x\n", 862 1.1 alc __func__, mode); 863 1.1 alc return AH_FALSE; 864 1.1 alc } 865 1.1 alc for (i = 0; i < nchan; i++) { 866 1.1 alc pChannelData->channelValue = pChannels[i]; 867 1.1 alc 868 1.1 alc EEREAD(off++); 869 1.1 alc pChannelData->pcdacMax = (uint16_t)((eeval >> 10) & PCDAC_MASK); 870 1.1 alc pChannelData->pcdacMin = (uint16_t)((eeval >> 4) & PCDAC_MASK); 871 1.1 alc pChannelData->PwrValues[0] = (uint16_t)((eeval << 2) & POWER_MASK); 872 1.1 alc 873 1.1 alc EEREAD(off++); 874 1.1 alc pChannelData->PwrValues[0] |= (uint16_t)((eeval >> 14) & 0x3); 875 1.1 alc pChannelData->PwrValues[1] = (uint16_t)((eeval >> 8) & POWER_MASK); 876 1.1 alc pChannelData->PwrValues[2] = (uint16_t)((eeval >> 2) & POWER_MASK); 877 1.1 alc pChannelData->PwrValues[3] = (uint16_t)((eeval << 4) & POWER_MASK); 878 1.1 alc 879 1.1 alc EEREAD(off++); 880 1.1 alc pChannelData->PwrValues[3] |= (uint16_t)((eeval >> 12) & 0xf); 881 1.1 alc pChannelData->PwrValues[4] = (uint16_t)((eeval >> 6) & POWER_MASK); 882 1.1 alc pChannelData->PwrValues[5] = (uint16_t)(eeval & POWER_MASK); 883 1.1 alc 884 1.1 alc EEREAD(off++); 885 1.1 alc pChannelData->PwrValues[6] = (uint16_t)((eeval >> 10) & POWER_MASK); 886 1.1 alc pChannelData->PwrValues[7] = (uint16_t)((eeval >> 4) & POWER_MASK); 887 1.1 alc pChannelData->PwrValues[8] = (uint16_t)((eeval << 2) & POWER_MASK); 888 1.1 alc 889 1.1 alc EEREAD(off++); 890 1.1 alc pChannelData->PwrValues[8] |= (uint16_t)((eeval >> 14) & 0x3); 891 1.1 alc pChannelData->PwrValues[9] = (uint16_t)((eeval >> 8) & POWER_MASK); 892 1.1 alc pChannelData->PwrValues[10] = (uint16_t)((eeval >> 2) & POWER_MASK); 893 1.1 alc 894 1.1 alc getPcdacInterceptsFromPcdacMinMax(ee, 895 1.1 alc pChannelData->pcdacMin, pChannelData->pcdacMax, 896 1.1 alc pChannelData->PcdacValues) ; 897 1.1 alc 898 1.1 alc for (j = 0; j < pChannelData->numPcdacValues; j++) { 899 1.1 alc pChannelData->PwrValues[j] = (uint16_t)( 900 1.1 alc PWR_STEP * pChannelData->PwrValues[j]); 901 1.1 alc /* Note these values are scaled up. */ 902 1.1 alc } 903 1.1 alc pChannelData++; 904 1.1 alc } 905 1.1 alc } 906 1.1 alc return AH_TRUE; 907 1.1 alc #undef EEREAD 908 1.1 alc } 909 1.1 alc 910 1.1 alc /* 911 1.1 alc * Copy EEPROM Target Power Calbration per rate contents 912 1.1 alc * into the allocated space 913 1.1 alc */ 914 1.1 alc static HAL_BOOL 915 1.1 alc readEepromTargetPowerCalInfo(struct ath_hal *ah, HAL_EEPROM *ee) 916 1.1 alc { 917 1.1 alc #define EEREAD(_off) do { \ 918 1.1 alc if (!ath_hal_eepromRead(ah, _off, &eeval)) \ 919 1.1 alc return AH_FALSE; \ 920 1.1 alc } while (0) 921 1.1 alc uint16_t eeval, enable24; 922 1.1 alc uint32_t off; 923 1.1 alc int i, mode, nchan; 924 1.1 alc 925 1.1 alc enable24 = ee->ee_Bmode || ee->ee_Gmode; 926 1.1 alc for (mode = headerInfo11A; mode <= headerInfo11G; mode++) { 927 1.1 alc TRGT_POWER_INFO *pPowerInfo; 928 1.1 alc uint16_t *pNumTrgtChannels; 929 1.1 alc 930 1.1 alc off = ee->ee_version >= AR_EEPROM_VER4_0 ? 931 1.1 alc ee->ee_targetPowersStart - GROUP5_OFFSET : 932 1.1 alc ee->ee_version >= AR_EEPROM_VER3_3 ? 933 1.1 alc GROUPS_OFFSET3_3 : GROUPS_OFFSET3_2; 934 1.1 alc switch (mode) { 935 1.1 alc case headerInfo11A: 936 1.1 alc off += GROUP5_OFFSET; 937 1.1 alc nchan = NUM_TEST_FREQUENCIES; 938 1.1 alc pPowerInfo = ee->ee_trgtPwr_11a; 939 1.1 alc pNumTrgtChannels = &ee->ee_numTargetPwr_11a; 940 1.1 alc break; 941 1.1 alc case headerInfo11B: 942 1.1 alc if (!enable24) 943 1.1 alc continue; 944 1.1 alc off += GROUP6_OFFSET; 945 1.1 alc nchan = 2; 946 1.1 alc pPowerInfo = ee->ee_trgtPwr_11b; 947 1.1 alc pNumTrgtChannels = &ee->ee_numTargetPwr_11b; 948 1.1 alc break; 949 1.1 alc case headerInfo11G: 950 1.1 alc if (!enable24) 951 1.1 alc continue; 952 1.1 alc off += GROUP7_OFFSET; 953 1.1 alc nchan = 3; 954 1.1 alc pPowerInfo = ee->ee_trgtPwr_11g; 955 1.1 alc pNumTrgtChannels = &ee->ee_numTargetPwr_11g; 956 1.1 alc break; 957 1.1 alc default: 958 1.1 alc HALDEBUG(ah, HAL_DEBUG_ANY, "%s: invalid mode 0x%x\n", 959 1.1 alc __func__, mode); 960 1.1 alc return AH_FALSE; 961 1.1 alc } 962 1.1 alc *pNumTrgtChannels = 0; 963 1.1 alc for (i = 0; i < nchan; i++) { 964 1.1 alc EEREAD(off++); 965 1.1 alc if (ee->ee_version >= AR_EEPROM_VER3_3) { 966 1.1 alc pPowerInfo->testChannel = (eeval >> 8) & 0xff; 967 1.1 alc } else { 968 1.1 alc pPowerInfo->testChannel = (eeval >> 9) & 0x7f; 969 1.1 alc } 970 1.1 alc 971 1.1 alc if (pPowerInfo->testChannel != 0) { 972 1.1 alc /* get the channel value and read rest of info */ 973 1.1 alc if (mode == headerInfo11A) { 974 1.1 alc pPowerInfo->testChannel = fbin2freq(ee, pPowerInfo->testChannel); 975 1.1 alc } else { 976 1.1 alc pPowerInfo->testChannel = fbin2freq_2p4(ee, pPowerInfo->testChannel); 977 1.1 alc } 978 1.1 alc 979 1.1 alc if (ee->ee_version >= AR_EEPROM_VER3_3) { 980 1.1 alc pPowerInfo->twicePwr6_24 = (eeval >> 2) & POWER_MASK; 981 1.1 alc pPowerInfo->twicePwr36 = (eeval << 4) & POWER_MASK; 982 1.1 alc } else { 983 1.1 alc pPowerInfo->twicePwr6_24 = (eeval >> 3) & POWER_MASK; 984 1.1 alc pPowerInfo->twicePwr36 = (eeval << 3) & POWER_MASK; 985 1.1 alc } 986 1.1 alc 987 1.1 alc EEREAD(off++); 988 1.1 alc if (ee->ee_version >= AR_EEPROM_VER3_3) { 989 1.1 alc pPowerInfo->twicePwr36 |= (eeval >> 12) & 0xf; 990 1.1 alc pPowerInfo->twicePwr48 = (eeval >> 6) & POWER_MASK; 991 1.1 alc pPowerInfo->twicePwr54 = eeval & POWER_MASK; 992 1.1 alc } else { 993 1.1 alc pPowerInfo->twicePwr36 |= (eeval >> 13) & 0x7; 994 1.1 alc pPowerInfo->twicePwr48 = (eeval >> 7) & POWER_MASK; 995 1.1 alc pPowerInfo->twicePwr54 = (eeval >> 1) & POWER_MASK; 996 1.1 alc } 997 1.1 alc (*pNumTrgtChannels)++; 998 1.1 alc } 999 1.1 alc pPowerInfo++; 1000 1.1 alc } 1001 1.1 alc } 1002 1.1 alc return AH_TRUE; 1003 1.1 alc #undef EEREAD 1004 1.1 alc } 1005 1.1 alc 1006 1.1 alc /* 1007 1.1 alc * Now copy EEPROM Coformance Testing Limits contents 1008 1.1 alc * into the allocated space 1009 1.1 alc */ 1010 1.1 alc static HAL_BOOL 1011 1.1 alc readEepromCTLInfo(struct ath_hal *ah, HAL_EEPROM *ee) 1012 1.1 alc { 1013 1.1 alc #define EEREAD(_off) do { \ 1014 1.1 alc if (!ath_hal_eepromRead(ah, _off, &eeval)) \ 1015 1.1 alc return AH_FALSE; \ 1016 1.1 alc } while (0) 1017 1.1 alc RD_EDGES_POWER *rep; 1018 1.1 alc uint16_t eeval; 1019 1.1 alc uint32_t off; 1020 1.1 alc int i, j; 1021 1.1 alc 1022 1.1 alc rep = ee->ee_rdEdgesPower; 1023 1.1 alc 1024 1.1 alc off = GROUP8_OFFSET + 1025 1.1 alc (ee->ee_version >= AR_EEPROM_VER4_0 ? 1026 1.1 alc ee->ee_targetPowersStart - GROUP5_OFFSET : 1027 1.1 alc ee->ee_version >= AR_EEPROM_VER3_3 ? 1028 1.1 alc GROUPS_OFFSET3_3 : GROUPS_OFFSET3_2); 1029 1.1 alc for (i = 0; i < ee->ee_numCtls; i++) { 1030 1.1 alc if (ee->ee_ctl[i] == 0) { 1031 1.1 alc /* Move offset and edges */ 1032 1.1 alc off += (ee->ee_version >= AR_EEPROM_VER3_3 ? 8 : 7); 1033 1.1 alc rep += NUM_EDGES; 1034 1.1 alc continue; 1035 1.1 alc } 1036 1.1 alc if (ee->ee_version >= AR_EEPROM_VER3_3) { 1037 1.1 alc for (j = 0; j < NUM_EDGES; j += 2) { 1038 1.1 alc EEREAD(off++); 1039 1.1 alc rep[j].rdEdge = (eeval >> 8) & FREQ_MASK_3_3; 1040 1.1 alc rep[j+1].rdEdge = eeval & FREQ_MASK_3_3; 1041 1.1 alc } 1042 1.1 alc for (j = 0; j < NUM_EDGES; j += 2) { 1043 1.1 alc EEREAD(off++); 1044 1.1 alc rep[j].twice_rdEdgePower = 1045 1.1 alc (eeval >> 8) & POWER_MASK; 1046 1.1 alc rep[j].flag = (eeval >> 14) & 1; 1047 1.1 alc rep[j+1].twice_rdEdgePower = eeval & POWER_MASK; 1048 1.1 alc rep[j+1].flag = (eeval >> 6) & 1; 1049 1.1 alc } 1050 1.1 alc } else { 1051 1.1 alc EEREAD(off++); 1052 1.1 alc rep[0].rdEdge = (eeval >> 9) & FREQ_MASK; 1053 1.1 alc rep[1].rdEdge = (eeval >> 2) & FREQ_MASK; 1054 1.1 alc rep[2].rdEdge = (eeval << 5) & FREQ_MASK; 1055 1.1 alc 1056 1.1 alc EEREAD(off++); 1057 1.1 alc rep[2].rdEdge |= (eeval >> 11) & 0x1f; 1058 1.1 alc rep[3].rdEdge = (eeval >> 4) & FREQ_MASK; 1059 1.1 alc rep[4].rdEdge = (eeval << 3) & FREQ_MASK; 1060 1.1 alc 1061 1.1 alc EEREAD(off++); 1062 1.1 alc rep[4].rdEdge |= (eeval >> 13) & 0x7; 1063 1.1 alc rep[5].rdEdge = (eeval >> 6) & FREQ_MASK; 1064 1.1 alc rep[6].rdEdge = (eeval << 1) & FREQ_MASK; 1065 1.1 alc 1066 1.1 alc EEREAD(off++); 1067 1.1 alc rep[6].rdEdge |= (eeval >> 15) & 0x1; 1068 1.1 alc rep[7].rdEdge = (eeval >> 8) & FREQ_MASK; 1069 1.1 alc 1070 1.1 alc rep[0].twice_rdEdgePower = (eeval >> 2) & POWER_MASK; 1071 1.1 alc rep[1].twice_rdEdgePower = (eeval << 4) & POWER_MASK; 1072 1.1 alc 1073 1.1 alc EEREAD(off++); 1074 1.1 alc rep[1].twice_rdEdgePower |= (eeval >> 12) & 0xf; 1075 1.1 alc rep[2].twice_rdEdgePower = (eeval >> 6) & POWER_MASK; 1076 1.1 alc rep[3].twice_rdEdgePower = eeval & POWER_MASK; 1077 1.1 alc 1078 1.1 alc EEREAD(off++); 1079 1.1 alc rep[4].twice_rdEdgePower = (eeval >> 10) & POWER_MASK; 1080 1.1 alc rep[5].twice_rdEdgePower = (eeval >> 4) & POWER_MASK; 1081 1.1 alc rep[6].twice_rdEdgePower = (eeval << 2) & POWER_MASK; 1082 1.1 alc 1083 1.1 alc EEREAD(off++); 1084 1.1 alc rep[6].twice_rdEdgePower |= (eeval >> 14) & 0x3; 1085 1.1 alc rep[7].twice_rdEdgePower = (eeval >> 8) & POWER_MASK; 1086 1.1 alc } 1087 1.1 alc 1088 1.1 alc for (j = 0; j < NUM_EDGES; j++ ) { 1089 1.1 alc if (rep[j].rdEdge != 0 || rep[j].twice_rdEdgePower != 0) { 1090 1.1 alc if ((ee->ee_ctl[i] & CTL_MODE_M) == CTL_11A || 1091 1.1 alc (ee->ee_ctl[i] & CTL_MODE_M) == CTL_TURBO) { 1092 1.1 alc rep[j].rdEdge = fbin2freq(ee, rep[j].rdEdge); 1093 1.1 alc } else { 1094 1.1 alc rep[j].rdEdge = fbin2freq_2p4(ee, rep[j].rdEdge); 1095 1.1 alc } 1096 1.1 alc } 1097 1.1 alc } 1098 1.1 alc rep += NUM_EDGES; 1099 1.1 alc } 1100 1.1 alc return AH_TRUE; 1101 1.1 alc #undef EEREAD 1102 1.1 alc } 1103 1.1 alc 1104 1.1 alc /* 1105 1.1 alc * Read the individual header fields for a Rev 3 EEPROM 1106 1.1 alc */ 1107 1.1 alc static HAL_BOOL 1108 1.1 alc readHeaderInfo(struct ath_hal *ah, HAL_EEPROM *ee) 1109 1.1 alc { 1110 1.1 alc #define EEREAD(_off) do { \ 1111 1.1 alc if (!ath_hal_eepromRead(ah, _off, &eeval)) \ 1112 1.1 alc return AH_FALSE; \ 1113 1.1 alc } while (0) 1114 1.1 alc static const uint32_t headerOffset3_0[] = { 1115 1.1 alc 0x00C2, /* 0 - Mode bits, device type, max turbo power */ 1116 1.1 alc 0x00C4, /* 1 - 2.4 and 5 antenna gain */ 1117 1.1 alc 0x00C5, /* 2 - Begin 11A modal section */ 1118 1.1 alc 0x00D0, /* 3 - Begin 11B modal section */ 1119 1.1 alc 0x00DA, /* 4 - Begin 11G modal section */ 1120 1.1 alc 0x00E4 /* 5 - Begin CTL section */ 1121 1.1 alc }; 1122 1.1 alc static const uint32_t headerOffset3_3[] = { 1123 1.1 alc 0x00C2, /* 0 - Mode bits, device type, max turbo power */ 1124 1.1 alc 0x00C3, /* 1 - 2.4 and 5 antenna gain */ 1125 1.1 alc 0x00D4, /* 2 - Begin 11A modal section */ 1126 1.1 alc 0x00F2, /* 3 - Begin 11B modal section */ 1127 1.1 alc 0x010D, /* 4 - Begin 11G modal section */ 1128 1.1 alc 0x0128 /* 5 - Begin CTL section */ 1129 1.1 alc }; 1130 1.1 alc 1131 1.1 alc static const uint32_t regCapOffsetPre4_0 = 0x00CF; 1132 1.1 alc static const uint32_t regCapOffsetPost4_0 = 0x00CA; 1133 1.1 alc 1134 1.1 alc const uint32_t *header; 1135 1.1 alc uint32_t off; 1136 1.1 alc uint16_t eeval; 1137 1.1 alc int i; 1138 1.1 alc 1139 1.1 alc /* initialize cckOfdmGainDelta for < 4.2 eeprom */ 1140 1.1 alc ee->ee_cckOfdmGainDelta = CCK_OFDM_GAIN_DELTA; 1141 1.1 alc ee->ee_scaledCh14FilterCckDelta = TENX_CH14_FILTER_CCK_DELTA_INIT; 1142 1.1 alc 1143 1.1 alc if (ee->ee_version >= AR_EEPROM_VER3_3) { 1144 1.1 alc header = headerOffset3_3; 1145 1.1 alc ee->ee_numCtls = NUM_CTLS_3_3; 1146 1.1 alc } else { 1147 1.1 alc header = headerOffset3_0; 1148 1.1 alc ee->ee_numCtls = NUM_CTLS; 1149 1.1 alc } 1150 1.1 alc HALASSERT(ee->ee_numCtls <= NUM_CTLS_MAX); 1151 1.1 alc 1152 1.1 alc EEREAD(header[0]); 1153 1.1 alc ee->ee_turbo5Disable = (eeval >> 15) & 0x01; 1154 1.1 alc ee->ee_rfKill = (eeval >> 14) & 0x01; 1155 1.1 alc ee->ee_deviceType = (eeval >> 11) & 0x07; 1156 1.1 alc ee->ee_turbo2WMaxPower5 = (eeval >> 4) & 0x7F; 1157 1.1 alc if (ee->ee_version >= AR_EEPROM_VER4_0) 1158 1.1 alc ee->ee_turbo2Disable = (eeval >> 3) & 0x01; 1159 1.1 alc else 1160 1.1 alc ee->ee_turbo2Disable = 1; 1161 1.1 alc ee->ee_Gmode = (eeval >> 2) & 0x01; 1162 1.1 alc ee->ee_Bmode = (eeval >> 1) & 0x01; 1163 1.1 alc ee->ee_Amode = (eeval & 0x01); 1164 1.1 alc 1165 1.1 alc off = header[1]; 1166 1.1 alc EEREAD(off++); 1167 1.1 alc ee->ee_antennaGainMax[0] = (int8_t)((eeval >> 8) & 0xFF); 1168 1.1 alc ee->ee_antennaGainMax[1] = (int8_t)(eeval & 0xFF); 1169 1.1 alc if (ee->ee_version >= AR_EEPROM_VER4_0) { 1170 1.1 alc EEREAD(off++); 1171 1.1 alc ee->ee_eepMap = (eeval>>14) & 0x3; 1172 1.1 alc ee->ee_disableXr5 = (eeval>>13) & 0x1; 1173 1.1 alc ee->ee_disableXr2 = (eeval>>12) & 0x1; 1174 1.1 alc ee->ee_earStart = eeval & 0xfff; 1175 1.1 alc 1176 1.1 alc EEREAD(off++); 1177 1.1 alc ee->ee_targetPowersStart = eeval & 0xfff; 1178 1.1 alc ee->ee_exist32kHzCrystal = (eeval>>14) & 0x1; 1179 1.1 alc 1180 1.1 alc if (ee->ee_version >= AR_EEPROM_VER5_0) { 1181 1.1 alc off += 2; 1182 1.1 alc EEREAD(off); 1183 1.1 alc ee->ee_eepMap2PowerCalStart = (eeval >> 4) & 0xfff; 1184 1.1 alc /* Properly cal'ed 5.0 devices should be non-zero */ 1185 1.1 alc } 1186 1.1 alc } 1187 1.1 alc 1188 1.1 alc /* Read the moded sections of the EEPROM header in the order A, B, G */ 1189 1.1 alc for (i = headerInfo11A; i <= headerInfo11G; i++) { 1190 1.1 alc /* Set the offset via the index */ 1191 1.1 alc off = header[2 + i]; 1192 1.1 alc 1193 1.1 alc EEREAD(off++); 1194 1.1 alc ee->ee_switchSettling[i] = (eeval >> 8) & 0x7f; 1195 1.1 alc ee->ee_txrxAtten[i] = (eeval >> 2) & 0x3f; 1196 1.1 alc ee->ee_antennaControl[0][i] = (eeval << 4) & 0x3f; 1197 1.1 alc 1198 1.1 alc EEREAD(off++); 1199 1.1 alc ee->ee_antennaControl[0][i] |= (eeval >> 12) & 0x0f; 1200 1.1 alc ee->ee_antennaControl[1][i] = (eeval >> 6) & 0x3f; 1201 1.1 alc ee->ee_antennaControl[2][i] = eeval & 0x3f; 1202 1.1 alc 1203 1.1 alc EEREAD(off++); 1204 1.1 alc ee->ee_antennaControl[3][i] = (eeval >> 10) & 0x3f; 1205 1.1 alc ee->ee_antennaControl[4][i] = (eeval >> 4) & 0x3f; 1206 1.1 alc ee->ee_antennaControl[5][i] = (eeval << 2) & 0x3f; 1207 1.1 alc 1208 1.1 alc EEREAD(off++); 1209 1.1 alc ee->ee_antennaControl[5][i] |= (eeval >> 14) & 0x03; 1210 1.1 alc ee->ee_antennaControl[6][i] = (eeval >> 8) & 0x3f; 1211 1.1 alc ee->ee_antennaControl[7][i] = (eeval >> 2) & 0x3f; 1212 1.1 alc ee->ee_antennaControl[8][i] = (eeval << 4) & 0x3f; 1213 1.1 alc 1214 1.1 alc EEREAD(off++); 1215 1.1 alc ee->ee_antennaControl[8][i] |= (eeval >> 12) & 0x0f; 1216 1.1 alc ee->ee_antennaControl[9][i] = (eeval >> 6) & 0x3f; 1217 1.1 alc ee->ee_antennaControl[10][i] = eeval & 0x3f; 1218 1.1 alc 1219 1.1 alc EEREAD(off++); 1220 1.1 alc ee->ee_adcDesiredSize[i] = (int8_t)((eeval >> 8) & 0xff); 1221 1.1 alc switch (i) { 1222 1.1 alc case headerInfo11A: 1223 1.1 alc ee->ee_ob4 = (eeval >> 5) & 0x07; 1224 1.1 alc ee->ee_db4 = (eeval >> 2) & 0x07; 1225 1.1 alc ee->ee_ob3 = (eeval << 1) & 0x07; 1226 1.1 alc break; 1227 1.1 alc case headerInfo11B: 1228 1.1 alc ee->ee_obFor24 = (eeval >> 4) & 0x07; 1229 1.1 alc ee->ee_dbFor24 = eeval & 0x07; 1230 1.1 alc break; 1231 1.1 alc case headerInfo11G: 1232 1.1 alc ee->ee_obFor24g = (eeval >> 4) & 0x07; 1233 1.1 alc ee->ee_dbFor24g = eeval & 0x07; 1234 1.1 alc break; 1235 1.1 alc } 1236 1.1 alc 1237 1.1 alc if (i == headerInfo11A) { 1238 1.1 alc EEREAD(off++); 1239 1.1 alc ee->ee_ob3 |= (eeval >> 15) & 0x01; 1240 1.1 alc ee->ee_db3 = (eeval >> 12) & 0x07; 1241 1.1 alc ee->ee_ob2 = (eeval >> 9) & 0x07; 1242 1.1 alc ee->ee_db2 = (eeval >> 6) & 0x07; 1243 1.1 alc ee->ee_ob1 = (eeval >> 3) & 0x07; 1244 1.1 alc ee->ee_db1 = eeval & 0x07; 1245 1.1 alc } 1246 1.1 alc 1247 1.1 alc EEREAD(off++); 1248 1.1 alc ee->ee_txEndToXLNAOn[i] = (eeval >> 8) & 0xff; 1249 1.1 alc ee->ee_thresh62[i] = eeval & 0xff; 1250 1.1 alc 1251 1.1 alc EEREAD(off++); 1252 1.1 alc ee->ee_txEndToXPAOff[i] = (eeval >> 8) & 0xff; 1253 1.1 alc ee->ee_txFrameToXPAOn[i] = eeval & 0xff; 1254 1.1 alc 1255 1.1 alc EEREAD(off++); 1256 1.1 alc ee->ee_pgaDesiredSize[i] = (int8_t)((eeval >> 8) & 0xff); 1257 1.1 alc ee->ee_noiseFloorThresh[i] = eeval & 0xff; 1258 1.1 alc if (ee->ee_noiseFloorThresh[i] & 0x80) { 1259 1.1 alc ee->ee_noiseFloorThresh[i] = 0 - 1260 1.1 alc ((ee->ee_noiseFloorThresh[i] ^ 0xff) + 1); 1261 1.1 alc } 1262 1.1 alc 1263 1.1 alc EEREAD(off++); 1264 1.1 alc ee->ee_xlnaGain[i] = (eeval >> 5) & 0xff; 1265 1.1 alc ee->ee_xgain[i] = (eeval >> 1) & 0x0f; 1266 1.1 alc ee->ee_xpd[i] = eeval & 0x01; 1267 1.1 alc if (ee->ee_version >= AR_EEPROM_VER4_0) { 1268 1.1 alc switch (i) { 1269 1.1 alc case headerInfo11A: 1270 1.1 alc ee->ee_fixedBias5 = (eeval >> 13) & 0x1; 1271 1.1 alc break; 1272 1.1 alc case headerInfo11G: 1273 1.1 alc ee->ee_fixedBias2 = (eeval >> 13) & 0x1; 1274 1.1 alc break; 1275 1.1 alc } 1276 1.1 alc } 1277 1.1 alc 1278 1.1 alc if (ee->ee_version >= AR_EEPROM_VER3_3) { 1279 1.1 alc EEREAD(off++); 1280 1.1 alc ee->ee_falseDetectBackoff[i] = (eeval >> 6) & 0x7F; 1281 1.1 alc switch (i) { 1282 1.1 alc case headerInfo11B: 1283 1.1 alc ee->ee_ob2GHz[0] = eeval & 0x7; 1284 1.1 alc ee->ee_db2GHz[0] = (eeval >> 3) & 0x7; 1285 1.1 alc break; 1286 1.1 alc case headerInfo11G: 1287 1.1 alc ee->ee_ob2GHz[1] = eeval & 0x7; 1288 1.1 alc ee->ee_db2GHz[1] = (eeval >> 3) & 0x7; 1289 1.1 alc break; 1290 1.1 alc case headerInfo11A: 1291 1.1 alc ee->ee_xrTargetPower5 = eeval & 0x3f; 1292 1.1 alc break; 1293 1.1 alc } 1294 1.1 alc } 1295 1.1 alc if (ee->ee_version >= AR_EEPROM_VER3_4) { 1296 1.1 alc ee->ee_gainI[i] = (eeval >> 13) & 0x07; 1297 1.1 alc 1298 1.1 alc EEREAD(off++); 1299 1.1 alc ee->ee_gainI[i] |= (eeval << 3) & 0x38; 1300 1.1 alc if (i == headerInfo11G) { 1301 1.1 alc ee->ee_cckOfdmPwrDelta = (eeval >> 3) & 0xFF; 1302 1.1 alc if (ee->ee_version >= AR_EEPROM_VER4_6) 1303 1.1 alc ee->ee_scaledCh14FilterCckDelta = 1304 1.1 alc (eeval >> 11) & 0x1f; 1305 1.1 alc } 1306 1.1 alc if (i == headerInfo11A && 1307 1.1 alc ee->ee_version >= AR_EEPROM_VER4_0) { 1308 1.1 alc ee->ee_iqCalI[0] = (eeval >> 8 ) & 0x3f; 1309 1.1 alc ee->ee_iqCalQ[0] = (eeval >> 3 ) & 0x1f; 1310 1.1 alc } 1311 1.1 alc } else { 1312 1.1 alc ee->ee_gainI[i] = 10; 1313 1.1 alc ee->ee_cckOfdmPwrDelta = TENX_OFDM_CCK_DELTA_INIT; 1314 1.1 alc } 1315 1.1 alc if (ee->ee_version >= AR_EEPROM_VER4_0) { 1316 1.1 alc switch (i) { 1317 1.1 alc case headerInfo11B: 1318 1.1 alc EEREAD(off++); 1319 1.1 alc ee->ee_calPier11b[0] = 1320 1.1 alc fbin2freq_2p4(ee, eeval&0xff); 1321 1.1 alc ee->ee_calPier11b[1] = 1322 1.1 alc fbin2freq_2p4(ee, (eeval >> 8)&0xff); 1323 1.1 alc EEREAD(off++); 1324 1.1 alc ee->ee_calPier11b[2] = 1325 1.1 alc fbin2freq_2p4(ee, eeval&0xff); 1326 1.1 alc if (ee->ee_version >= AR_EEPROM_VER4_1) 1327 1.1 alc ee->ee_rxtxMargin[headerInfo11B] = 1328 1.1 alc (eeval >> 8) & 0x3f; 1329 1.1 alc break; 1330 1.1 alc case headerInfo11G: 1331 1.1 alc EEREAD(off++); 1332 1.1 alc ee->ee_calPier11g[0] = 1333 1.1 alc fbin2freq_2p4(ee, eeval & 0xff); 1334 1.1 alc ee->ee_calPier11g[1] = 1335 1.1 alc fbin2freq_2p4(ee, (eeval >> 8) & 0xff); 1336 1.1 alc 1337 1.1 alc EEREAD(off++); 1338 1.1 alc ee->ee_turbo2WMaxPower2 = eeval & 0x7F; 1339 1.1 alc ee->ee_xrTargetPower2 = (eeval >> 7) & 0x3f; 1340 1.1 alc 1341 1.1 alc EEREAD(off++); 1342 1.1 alc ee->ee_calPier11g[2] = 1343 1.1 alc fbin2freq_2p4(ee, eeval & 0xff); 1344 1.1 alc if (ee->ee_version >= AR_EEPROM_VER4_1) 1345 1.1 alc ee->ee_rxtxMargin[headerInfo11G] = 1346 1.1 alc (eeval >> 8) & 0x3f; 1347 1.1 alc 1348 1.1 alc EEREAD(off++); 1349 1.1 alc ee->ee_iqCalI[1] = (eeval >> 5) & 0x3F; 1350 1.1 alc ee->ee_iqCalQ[1] = eeval & 0x1F; 1351 1.1 alc 1352 1.1 alc if (ee->ee_version >= AR_EEPROM_VER4_2) { 1353 1.1 alc EEREAD(off++); 1354 1.1 alc ee->ee_cckOfdmGainDelta = 1355 1.1 alc (uint8_t)(eeval & 0xFF); 1356 1.1 alc if (ee->ee_version >= AR_EEPROM_VER5_0) { 1357 1.1 alc ee->ee_switchSettlingTurbo[1] = 1358 1.1 alc (eeval >> 8) & 0x7f; 1359 1.1 alc ee->ee_txrxAttenTurbo[1] = 1360 1.1 alc (eeval >> 15) & 0x1; 1361 1.1 alc EEREAD(off++); 1362 1.1 alc ee->ee_txrxAttenTurbo[1] |= 1363 1.1 alc (eeval & 0x1F) << 1; 1364 1.1 alc ee->ee_rxtxMarginTurbo[1] = 1365 1.1 alc (eeval >> 5) & 0x3F; 1366 1.1 alc ee->ee_adcDesiredSizeTurbo[1] = 1367 1.1 alc (eeval >> 11) & 0x1F; 1368 1.1 alc EEREAD(off++); 1369 1.1 alc ee->ee_adcDesiredSizeTurbo[1] |= 1370 1.1 alc (eeval & 0x7) << 5; 1371 1.1 alc ee->ee_pgaDesiredSizeTurbo[1] = 1372 1.1 alc (eeval >> 3) & 0xFF; 1373 1.1 alc } 1374 1.1 alc } 1375 1.1 alc break; 1376 1.1 alc case headerInfo11A: 1377 1.1 alc if (ee->ee_version >= AR_EEPROM_VER4_1) { 1378 1.1 alc EEREAD(off++); 1379 1.1 alc ee->ee_rxtxMargin[headerInfo11A] = 1380 1.1 alc eeval & 0x3f; 1381 1.1 alc if (ee->ee_version >= AR_EEPROM_VER5_0) { 1382 1.1 alc ee->ee_switchSettlingTurbo[0] = 1383 1.1 alc (eeval >> 6) & 0x7f; 1384 1.1 alc ee->ee_txrxAttenTurbo[0] = 1385 1.1 alc (eeval >> 13) & 0x7; 1386 1.1 alc EEREAD(off++); 1387 1.1 alc ee->ee_txrxAttenTurbo[0] |= 1388 1.1 alc (eeval & 0x7) << 3; 1389 1.1 alc ee->ee_rxtxMarginTurbo[0] = 1390 1.1 alc (eeval >> 3) & 0x3F; 1391 1.1 alc ee->ee_adcDesiredSizeTurbo[0] = 1392 1.1 alc (eeval >> 9) & 0x7F; 1393 1.1 alc EEREAD(off++); 1394 1.1 alc ee->ee_adcDesiredSizeTurbo[0] |= 1395 1.1 alc (eeval & 0x1) << 7; 1396 1.1 alc ee->ee_pgaDesiredSizeTurbo[0] = 1397 1.1 alc (eeval >> 1) & 0xFF; 1398 1.1 alc } 1399 1.1 alc } 1400 1.1 alc break; 1401 1.1 alc } 1402 1.1 alc } 1403 1.1 alc } 1404 1.1 alc if (ee->ee_version < AR_EEPROM_VER3_3) { 1405 1.1 alc /* Version 3.1+ specific parameters */ 1406 1.1 alc EEREAD(0xec); 1407 1.1 alc ee->ee_ob2GHz[0] = eeval & 0x7; 1408 1.1 alc ee->ee_db2GHz[0] = (eeval >> 3) & 0x7; 1409 1.1 alc 1410 1.1 alc EEREAD(0xed); 1411 1.1 alc ee->ee_ob2GHz[1] = eeval & 0x7; 1412 1.1 alc ee->ee_db2GHz[1] = (eeval >> 3) & 0x7; 1413 1.1 alc } 1414 1.1 alc 1415 1.1 alc /* Initialize corner cal (thermal tx gain adjust parameters) */ 1416 1.1 alc ee->ee_cornerCal.clip = 4; 1417 1.1 alc ee->ee_cornerCal.pd90 = 1; 1418 1.1 alc ee->ee_cornerCal.pd84 = 1; 1419 1.1 alc ee->ee_cornerCal.gSel = 0; 1420 1.1 alc 1421 1.1 alc /* 1422 1.1 alc * Read the conformance test limit identifiers 1423 1.1 alc * These are used to match regulatory domain testing needs with 1424 1.1 alc * the RD-specific tests that have been calibrated in the EEPROM. 1425 1.1 alc */ 1426 1.1 alc off = header[5]; 1427 1.1 alc for (i = 0; i < ee->ee_numCtls; i += 2) { 1428 1.1 alc EEREAD(off++); 1429 1.1 alc ee->ee_ctl[i] = (eeval >> 8) & 0xff; 1430 1.1 alc ee->ee_ctl[i+1] = eeval & 0xff; 1431 1.1 alc } 1432 1.1 alc 1433 1.1 alc if (ee->ee_version < AR_EEPROM_VER5_3) { 1434 1.1 alc /* XXX only for 5413? */ 1435 1.1 alc ee->ee_spurChans[0][1] = AR_SPUR_5413_1; 1436 1.1 alc ee->ee_spurChans[1][1] = AR_SPUR_5413_2; 1437 1.1 alc ee->ee_spurChans[2][1] = AR_NO_SPUR; 1438 1.1 alc ee->ee_spurChans[0][0] = AR_NO_SPUR; 1439 1.1 alc } else { 1440 1.1 alc /* Read spur mitigation data */ 1441 1.1 alc for (i = 0; i < AR_EEPROM_MODAL_SPURS; i++) { 1442 1.1 alc EEREAD(off); 1443 1.1 alc ee->ee_spurChans[i][0] = eeval; 1444 1.1 alc EEREAD(off+AR_EEPROM_MODAL_SPURS); 1445 1.1 alc ee->ee_spurChans[i][1] = eeval; 1446 1.1 alc off++; 1447 1.1 alc } 1448 1.1 alc } 1449 1.1 alc 1450 1.1 alc /* for recent changes to NF scale */ 1451 1.1 alc if (ee->ee_version <= AR_EEPROM_VER3_2) { 1452 1.1 alc ee->ee_noiseFloorThresh[headerInfo11A] = -54; 1453 1.1 alc ee->ee_noiseFloorThresh[headerInfo11B] = -1; 1454 1.1 alc ee->ee_noiseFloorThresh[headerInfo11G] = -1; 1455 1.1 alc } 1456 1.1 alc /* to override thresh62 for better 2.4 and 5 operation */ 1457 1.1 alc if (ee->ee_version <= AR_EEPROM_VER3_2) { 1458 1.1 alc ee->ee_thresh62[headerInfo11A] = 15; /* 11A */ 1459 1.1 alc ee->ee_thresh62[headerInfo11B] = 28; /* 11B */ 1460 1.1 alc ee->ee_thresh62[headerInfo11G] = 28; /* 11G */ 1461 1.1 alc } 1462 1.1 alc 1463 1.1 alc /* Check for regulatory capabilities */ 1464 1.1 alc if (ee->ee_version >= AR_EEPROM_VER4_0) { 1465 1.1 alc EEREAD(regCapOffsetPost4_0); 1466 1.1 alc } else { 1467 1.1 alc EEREAD(regCapOffsetPre4_0); 1468 1.1 alc } 1469 1.1 alc 1470 1.1 alc ee->ee_regCap = eeval; 1471 1.1 alc 1472 1.1 alc if (ee->ee_Amode == 0) { 1473 1.1 alc /* Check for valid Amode in upgraded h/w */ 1474 1.1 alc if (ee->ee_version >= AR_EEPROM_VER4_0) { 1475 1.1 alc ee->ee_Amode = (ee->ee_regCap & AR_EEPROM_EEREGCAP_EN_KK_NEW_11A)?1:0; 1476 1.1 alc } else { 1477 1.1 alc ee->ee_Amode = (ee->ee_regCap & AR_EEPROM_EEREGCAP_EN_KK_NEW_11A_PRE4_0)?1:0; 1478 1.1 alc } 1479 1.1 alc } 1480 1.1 alc 1481 1.1 alc if (ee->ee_version >= AR_EEPROM_VER5_1) 1482 1.1 alc EEREAD(AR_EEPROM_CAPABILITIES_OFFSET); 1483 1.1 alc else 1484 1.1 alc eeval = 0; 1485 1.1 alc ee->ee_opCap = eeval; 1486 1.1 alc 1487 1.1 alc EEREAD(AR_EEPROM_REG_DOMAIN); 1488 1.1 alc ee->ee_regdomain = eeval; 1489 1.1 alc 1490 1.1 alc return AH_TRUE; 1491 1.1 alc #undef EEREAD 1492 1.1 alc } 1493 1.1 alc 1494 1.1 alc /* 1495 1.1 alc * Now verify and copy EEPROM contents into the allocated space 1496 1.1 alc */ 1497 1.1 alc static HAL_BOOL 1498 1.1 alc legacyEepromReadContents(struct ath_hal *ah, HAL_EEPROM *ee) 1499 1.1 alc { 1500 1.1 alc /* Read the header information here */ 1501 1.1 alc if (!readHeaderInfo(ah, ee)) 1502 1.1 alc return AH_FALSE; 1503 1.1 alc #if 0 1504 1.1 alc /* Require 5112 devices to have EEPROM 4.0 EEP_MAP set */ 1505 1.1 alc if (IS_5112(ah) && !ee->ee_eepMap) { 1506 1.1 alc HALDEBUG(ah, HAL_DEBUG_ANY, 1507 1.1 alc "%s: 5112 devices must have EEPROM 4.0 with the " 1508 1.1 alc "EEP_MAP set\n", __func__); 1509 1.1 alc return AH_FALSE; 1510 1.1 alc } 1511 1.1 alc #endif 1512 1.1 alc /* 1513 1.1 alc * Group 1: frequency pier locations readback 1514 1.1 alc * check that the structure has been populated 1515 1.1 alc * with enough space to hold the channels 1516 1.1 alc * 1517 1.1 alc * NOTE: Group 1 contains the 5 GHz channel numbers 1518 1.1 alc * that have dBm->pcdac calibrated information. 1519 1.1 alc */ 1520 1.1 alc if (!readEepromFreqPierInfo(ah, ee)) 1521 1.1 alc return AH_FALSE; 1522 1.1 alc 1523 1.1 alc /* 1524 1.1 alc * Group 2: readback data for all frequency piers 1525 1.1 alc * 1526 1.1 alc * NOTE: Group 2 contains the raw power calibration 1527 1.1 alc * information for each of the channels that we 1528 1.1 alc * recorded above. 1529 1.1 alc */ 1530 1.1 alc if (!readEepromRawPowerCalInfo(ah, ee)) 1531 1.1 alc return AH_FALSE; 1532 1.1 alc 1533 1.1 alc /* 1534 1.1 alc * Group 5: target power values per rate 1535 1.1 alc * 1536 1.1 alc * NOTE: Group 5 contains the recorded maximum power 1537 1.1 alc * in dB that can be attained for the given rate. 1538 1.1 alc */ 1539 1.1 alc /* Read the power per rate info for test channels */ 1540 1.1 alc if (!readEepromTargetPowerCalInfo(ah, ee)) 1541 1.1 alc return AH_FALSE; 1542 1.1 alc 1543 1.1 alc /* 1544 1.1 alc * Group 8: Conformance Test Limits information 1545 1.1 alc * 1546 1.1 alc * NOTE: Group 8 contains the values to limit the 1547 1.1 alc * maximum transmit power value based on any 1548 1.1 alc * band edge violations. 1549 1.1 alc */ 1550 1.1 alc /* Read the RD edge power limits */ 1551 1.1 alc return readEepromCTLInfo(ah, ee); 1552 1.1 alc } 1553 1.1 alc 1554 1.1 alc static HAL_STATUS 1555 1.1 alc legacyEepromGet(struct ath_hal *ah, int param, void *val) 1556 1.1 alc { 1557 1.1 alc HAL_EEPROM *ee = AH_PRIVATE(ah)->ah_eeprom; 1558 1.1 alc uint8_t *macaddr; 1559 1.1 alc uint16_t eeval; 1560 1.1 alc uint32_t sum; 1561 1.1 alc int i; 1562 1.1 alc 1563 1.1 alc switch (param) { 1564 1.1 alc case AR_EEP_OPCAP: 1565 1.1 alc *(uint16_t *) val = ee->ee_opCap; 1566 1.1 alc return HAL_OK; 1567 1.1 alc case AR_EEP_REGDMN_0: 1568 1.1 alc *(uint16_t *) val = ee->ee_regdomain; 1569 1.1 alc return HAL_OK; 1570 1.1 alc case AR_EEP_RFSILENT: 1571 1.1 alc if (!ath_hal_eepromRead(ah, AR_EEPROM_RFSILENT, &eeval)) 1572 1.1 alc return HAL_EEREAD; 1573 1.1 alc *(uint16_t *) val = eeval; 1574 1.1 alc return HAL_OK; 1575 1.1 alc case AR_EEP_MACADDR: 1576 1.1 alc sum = 0; 1577 1.1 alc macaddr = val; 1578 1.1 alc for (i = 0; i < 3; i++) { 1579 1.1 alc if (!ath_hal_eepromRead(ah, AR_EEPROM_MAC(2-i), &eeval)) { 1580 1.1 alc HALDEBUG(ah, HAL_DEBUG_ANY, 1581 1.1 alc "%s: cannot read EEPROM location %u\n", 1582 1.1 alc __func__, i); 1583 1.1 alc return HAL_EEREAD; 1584 1.1 alc } 1585 1.1 alc sum += eeval; 1586 1.1 alc macaddr[2*i] = eeval >> 8; 1587 1.1 alc macaddr[2*i + 1] = eeval & 0xff; 1588 1.1 alc } 1589 1.1 alc if (sum == 0 || sum == 0xffff*3) { 1590 1.1 alc HALDEBUG(ah, HAL_DEBUG_ANY, 1591 1.1 alc "%s: mac address read failed: %s\n", __func__, 1592 1.1 alc ath_hal_ether_sprintf(macaddr)); 1593 1.1 alc return HAL_EEBADMAC; 1594 1.1 alc } 1595 1.1 alc return HAL_OK; 1596 1.1 alc case AR_EEP_RFKILL: 1597 1.1 alc HALASSERT(val == AH_NULL); 1598 1.1 alc return ee->ee_rfKill ? HAL_OK : HAL_EIO; 1599 1.1 alc case AR_EEP_AMODE: 1600 1.1 alc HALASSERT(val == AH_NULL); 1601 1.1 alc return ee->ee_Amode ? HAL_OK : HAL_EIO; 1602 1.1 alc case AR_EEP_BMODE: 1603 1.1 alc HALASSERT(val == AH_NULL); 1604 1.1 alc return ee->ee_Bmode ? HAL_OK : HAL_EIO; 1605 1.1 alc case AR_EEP_GMODE: 1606 1.1 alc HALASSERT(val == AH_NULL); 1607 1.1 alc return ee->ee_Gmode ? HAL_OK : HAL_EIO; 1608 1.1 alc case AR_EEP_TURBO5DISABLE: 1609 1.1 alc HALASSERT(val == AH_NULL); 1610 1.1 alc return ee->ee_turbo5Disable ? HAL_OK : HAL_EIO; 1611 1.1 alc case AR_EEP_TURBO2DISABLE: 1612 1.1 alc HALASSERT(val == AH_NULL); 1613 1.1 alc return ee->ee_turbo2Disable ? HAL_OK : HAL_EIO; 1614 1.1 alc case AR_EEP_ISTALON: /* Talon detect */ 1615 1.1 alc HALASSERT(val == AH_NULL); 1616 1.1 alc return (ee->ee_version >= AR_EEPROM_VER5_4 && 1617 1.1 alc ath_hal_eepromRead(ah, 0x0b, &eeval) && eeval == 1) ? 1618 1.1 alc HAL_OK : HAL_EIO; 1619 1.1 alc case AR_EEP_32KHZCRYSTAL: 1620 1.1 alc HALASSERT(val == AH_NULL); 1621 1.1 alc return ee->ee_exist32kHzCrystal ? HAL_OK : HAL_EIO; 1622 1.1 alc case AR_EEP_COMPRESS: 1623 1.1 alc HALASSERT(val == AH_NULL); 1624 1.1 alc return (ee->ee_opCap & AR_EEPROM_EEPCAP_COMPRESS_DIS) == 0 ? 1625 1.1 alc HAL_OK : HAL_EIO; 1626 1.1 alc case AR_EEP_FASTFRAME: 1627 1.1 alc HALASSERT(val == AH_NULL); 1628 1.1 alc return (ee->ee_opCap & AR_EEPROM_EEPCAP_FASTFRAME_DIS) == 0 ? 1629 1.1 alc HAL_OK : HAL_EIO; 1630 1.1 alc case AR_EEP_AES: 1631 1.1 alc HALASSERT(val == AH_NULL); 1632 1.1 alc return (ee->ee_opCap & AR_EEPROM_EEPCAP_AES_DIS) == 0 ? 1633 1.1 alc HAL_OK : HAL_EIO; 1634 1.1 alc case AR_EEP_BURST: 1635 1.1 alc HALASSERT(val == AH_NULL); 1636 1.1 alc return (ee->ee_opCap & AR_EEPROM_EEPCAP_BURST_DIS) == 0 ? 1637 1.1 alc HAL_OK : HAL_EIO; 1638 1.1 alc case AR_EEP_MAXQCU: 1639 1.1 alc if (ee->ee_opCap & AR_EEPROM_EEPCAP_MAXQCU) { 1640 1.1 alc *(uint16_t *) val = 1641 1.1 alc MS(ee->ee_opCap, AR_EEPROM_EEPCAP_MAXQCU); 1642 1.1 alc return HAL_OK; 1643 1.1 alc } else 1644 1.1 alc return HAL_EIO; 1645 1.1 alc case AR_EEP_KCENTRIES: 1646 1.1 alc if (ee->ee_opCap & AR_EEPROM_EEPCAP_KC_ENTRIES) { 1647 1.1 alc *(uint16_t *) val = 1648 1.1 alc 1 << MS(ee->ee_opCap, AR_EEPROM_EEPCAP_KC_ENTRIES); 1649 1.1 alc return HAL_OK; 1650 1.1 alc } else 1651 1.1 alc return HAL_EIO; 1652 1.1 alc case AR_EEP_ANTGAINMAX_5: 1653 1.1 alc *(int8_t *) val = ee->ee_antennaGainMax[0]; 1654 1.1 alc return HAL_OK; 1655 1.1 alc case AR_EEP_ANTGAINMAX_2: 1656 1.1 alc *(int8_t *) val = ee->ee_antennaGainMax[1]; 1657 1.1 alc return HAL_OK; 1658 1.1 alc case AR_EEP_WRITEPROTECT: 1659 1.1 alc HALASSERT(val == AH_NULL); 1660 1.1 alc return (ee->ee_protect & AR_EEPROM_PROTECT_WP_128_191) ? 1661 1.1 alc HAL_OK : HAL_EIO; 1662 1.1 alc } 1663 1.1 alc return HAL_EINVAL; 1664 1.1 alc } 1665 1.1 alc 1666 1.1 alc static HAL_BOOL 1667 1.1 alc legacyEepromSet(struct ath_hal *ah, int param, int v) 1668 1.1 alc { 1669 1.1 alc HAL_EEPROM *ee = AH_PRIVATE(ah)->ah_eeprom; 1670 1.1 alc 1671 1.1 alc switch (param) { 1672 1.1 alc case AR_EEP_AMODE: 1673 1.1 alc ee->ee_Amode = v; 1674 1.5 mrg return AH_TRUE; 1675 1.1 alc case AR_EEP_BMODE: 1676 1.1 alc ee->ee_Bmode = v; 1677 1.5 mrg return AH_TRUE; 1678 1.1 alc case AR_EEP_GMODE: 1679 1.1 alc ee->ee_Gmode = v; 1680 1.5 mrg return AH_TRUE; 1681 1.1 alc case AR_EEP_TURBO5DISABLE: 1682 1.1 alc ee->ee_turbo5Disable = v; 1683 1.5 mrg return AH_TRUE; 1684 1.1 alc case AR_EEP_TURBO2DISABLE: 1685 1.1 alc ee->ee_turbo2Disable = v; 1686 1.5 mrg return AH_TRUE; 1687 1.1 alc case AR_EEP_COMPRESS: 1688 1.1 alc if (v) 1689 1.1 alc ee->ee_opCap &= ~AR_EEPROM_EEPCAP_COMPRESS_DIS; 1690 1.1 alc else 1691 1.1 alc ee->ee_opCap |= AR_EEPROM_EEPCAP_COMPRESS_DIS; 1692 1.5 mrg return AH_TRUE; 1693 1.1 alc case AR_EEP_FASTFRAME: 1694 1.1 alc if (v) 1695 1.1 alc ee->ee_opCap &= ~AR_EEPROM_EEPCAP_FASTFRAME_DIS; 1696 1.1 alc else 1697 1.1 alc ee->ee_opCap |= AR_EEPROM_EEPCAP_FASTFRAME_DIS; 1698 1.5 mrg return AH_TRUE; 1699 1.1 alc case AR_EEP_AES: 1700 1.1 alc if (v) 1701 1.1 alc ee->ee_opCap &= ~AR_EEPROM_EEPCAP_AES_DIS; 1702 1.1 alc else 1703 1.1 alc ee->ee_opCap |= AR_EEPROM_EEPCAP_AES_DIS; 1704 1.5 mrg return AH_TRUE; 1705 1.1 alc case AR_EEP_BURST: 1706 1.1 alc if (v) 1707 1.1 alc ee->ee_opCap &= ~AR_EEPROM_EEPCAP_BURST_DIS; 1708 1.1 alc else 1709 1.1 alc ee->ee_opCap |= AR_EEPROM_EEPCAP_BURST_DIS; 1710 1.5 mrg return AH_TRUE; 1711 1.1 alc } 1712 1.5 mrg return AH_FALSE; 1713 1.1 alc } 1714 1.1 alc 1715 1.1 alc static HAL_BOOL 1716 1.1 alc legacyEepromDiag(struct ath_hal *ah, int request, 1717 1.1 alc const void *args, uint32_t argsize, void **result, uint32_t *resultsize) 1718 1.1 alc { 1719 1.1 alc HAL_EEPROM *ee = AH_PRIVATE(ah)->ah_eeprom; 1720 1.1 alc const EEPROM_POWER_EXPN_5112 *pe; 1721 1.1 alc 1722 1.1 alc switch (request) { 1723 1.1 alc case HAL_DIAG_EEPROM: 1724 1.1 alc *result = ee; 1725 1.1 alc *resultsize = sizeof(*ee); 1726 1.1 alc return AH_TRUE; 1727 1.1 alc case HAL_DIAG_EEPROM_EXP_11A: 1728 1.1 alc case HAL_DIAG_EEPROM_EXP_11B: 1729 1.1 alc case HAL_DIAG_EEPROM_EXP_11G: 1730 1.1 alc pe = &ee->ee_modePowerArray5112[ 1731 1.1 alc request - HAL_DIAG_EEPROM_EXP_11A]; 1732 1.1 alc *result = pe->pChannels; 1733 1.1 alc *resultsize = (*result == AH_NULL) ? 0 : 1734 1.1 alc roundup(sizeof(uint16_t) * pe->numChannels, 1735 1.1 alc sizeof(uint32_t)) + 1736 1.1 alc sizeof(EXPN_DATA_PER_CHANNEL_5112) * pe->numChannels; 1737 1.1 alc return AH_TRUE; 1738 1.1 alc } 1739 1.1 alc return AH_FALSE; 1740 1.1 alc } 1741 1.1 alc 1742 1.1 alc static uint16_t 1743 1.1 alc legacyEepromGetSpurChan(struct ath_hal *ah, int ix, HAL_BOOL is2GHz) 1744 1.1 alc { 1745 1.1 alc HAL_EEPROM *ee = AH_PRIVATE(ah)->ah_eeprom; 1746 1.1 alc 1747 1.1 alc HALASSERT(0 <= ix && ix < AR_EEPROM_MODAL_SPURS); 1748 1.1 alc return ee->ee_spurChans[ix][is2GHz]; 1749 1.1 alc } 1750 1.1 alc 1751 1.1 alc /* 1752 1.1 alc * Reclaim any EEPROM-related storage. 1753 1.1 alc */ 1754 1.1 alc static void 1755 1.1 alc legacyEepromDetach(struct ath_hal *ah) 1756 1.1 alc { 1757 1.1 alc HAL_EEPROM *ee = AH_PRIVATE(ah)->ah_eeprom; 1758 1.1 alc 1759 1.1 alc if (ee->ee_version >= AR_EEPROM_VER4_0 && ee->ee_eepMap == 1) 1760 1.3 cegger freeEepromRawPowerCalInfo5112(ah, ee); 1761 1.1 alc ath_hal_free(ee); 1762 1.1 alc AH_PRIVATE(ah)->ah_eeprom = AH_NULL; 1763 1.1 alc } 1764 1.1 alc 1765 1.1 alc /* 1766 1.1 alc * These are not valid 2.4 channels, either we change 'em 1767 1.1 alc * or we need to change the coding to accept them. 1768 1.1 alc */ 1769 1.1 alc static const uint16_t channels11b[] = { 2412, 2447, 2484 }; 1770 1.1 alc static const uint16_t channels11g[] = { 2312, 2412, 2484 }; 1771 1.1 alc 1772 1.1 alc HAL_STATUS 1773 1.1 alc ath_hal_legacyEepromAttach(struct ath_hal *ah) 1774 1.1 alc { 1775 1.1 alc HAL_EEPROM *ee = AH_PRIVATE(ah)->ah_eeprom; 1776 1.1 alc uint32_t sum, eepMax; 1777 1.1 alc uint16_t eeversion, eeprotect, eeval; 1778 1.1 alc u_int i; 1779 1.1 alc 1780 1.1 alc HALASSERT(ee == AH_NULL); 1781 1.1 alc 1782 1.1 alc if (!ath_hal_eepromRead(ah, AR_EEPROM_VERSION, &eeversion)) { 1783 1.1 alc HALDEBUG(ah, HAL_DEBUG_ANY, 1784 1.1 alc "%s: unable to read EEPROM version\n", __func__); 1785 1.1 alc return HAL_EEREAD; 1786 1.1 alc } 1787 1.1 alc if (eeversion < AR_EEPROM_VER3) { 1788 1.1 alc HALDEBUG(ah, HAL_DEBUG_ANY, "%s: unsupported EEPROM version " 1789 1.1 alc "%u (0x%x) found\n", __func__, eeversion, eeversion); 1790 1.1 alc return HAL_EEVERSION; 1791 1.1 alc } 1792 1.1 alc 1793 1.1 alc if (!ath_hal_eepromRead(ah, AR_EEPROM_PROTECT, &eeprotect)) { 1794 1.1 alc HALDEBUG(ah, HAL_DEBUG_ANY, "%s: cannot read EEPROM protection " 1795 1.1 alc "bits; read locked?\n", __func__); 1796 1.1 alc return HAL_EEREAD; 1797 1.1 alc } 1798 1.1 alc HALDEBUG(ah, HAL_DEBUG_ATTACH, "EEPROM protect 0x%x\n", eeprotect); 1799 1.1 alc /* XXX check proper access before continuing */ 1800 1.1 alc 1801 1.1 alc /* 1802 1.1 alc * Read the Atheros EEPROM entries and calculate the checksum. 1803 1.1 alc */ 1804 1.1 alc if (!ath_hal_eepromRead(ah, AR_EEPROM_SIZE_UPPER, &eeval)) { 1805 1.1 alc HALDEBUG(ah, HAL_DEBUG_ANY, 1806 1.1 alc "%s: cannot read EEPROM upper size\n" , __func__); 1807 1.1 alc return HAL_EEREAD; 1808 1.1 alc } 1809 1.1 alc if (eeval != 0) { 1810 1.1 alc eepMax = (eeval & AR_EEPROM_SIZE_UPPER_MASK) << 1811 1.1 alc AR_EEPROM_SIZE_ENDLOC_SHIFT; 1812 1.1 alc if (!ath_hal_eepromRead(ah, AR_EEPROM_SIZE_LOWER, &eeval)) { 1813 1.1 alc HALDEBUG(ah, HAL_DEBUG_ANY, 1814 1.1 alc "%s: cannot read EEPROM lower size\n" , __func__); 1815 1.1 alc return HAL_EEREAD; 1816 1.1 alc } 1817 1.1 alc eepMax = (eepMax | eeval) - AR_EEPROM_ATHEROS_BASE; 1818 1.1 alc } else 1819 1.1 alc eepMax = AR_EEPROM_ATHEROS_MAX; 1820 1.1 alc sum = 0; 1821 1.1 alc for (i = 0; i < eepMax; i++) { 1822 1.1 alc if (!ath_hal_eepromRead(ah, AR_EEPROM_ATHEROS(i), &eeval)) { 1823 1.1 alc return HAL_EEREAD; 1824 1.1 alc } 1825 1.1 alc sum ^= eeval; 1826 1.1 alc } 1827 1.1 alc if (sum != 0xffff) { 1828 1.1 alc HALDEBUG(ah, HAL_DEBUG_ANY, "%s: bad EEPROM checksum 0x%x\n", 1829 1.1 alc __func__, sum); 1830 1.1 alc return HAL_EEBADSUM; 1831 1.1 alc } 1832 1.1 alc 1833 1.1 alc ee = ath_hal_malloc(sizeof(HAL_EEPROM)); 1834 1.1 alc if (ee == AH_NULL) { 1835 1.1 alc /* XXX message */ 1836 1.1 alc return HAL_ENOMEM; 1837 1.1 alc } 1838 1.1 alc 1839 1.1 alc ee->ee_protect = eeprotect; 1840 1.1 alc ee->ee_version = eeversion; 1841 1.1 alc 1842 1.1 alc ee->ee_numChannels11a = NUM_11A_EEPROM_CHANNELS; 1843 1.1 alc ee->ee_numChannels2_4 = NUM_2_4_EEPROM_CHANNELS; 1844 1.1 alc 1845 1.1 alc for (i = 0; i < NUM_11A_EEPROM_CHANNELS; i ++) 1846 1.1 alc ee->ee_dataPerChannel11a[i].numPcdacValues = NUM_PCDAC_VALUES; 1847 1.1 alc 1848 1.1 alc /* the channel list for 2.4 is fixed, fill this in here */ 1849 1.1 alc for (i = 0; i < NUM_2_4_EEPROM_CHANNELS; i++) { 1850 1.1 alc ee->ee_channels11b[i] = channels11b[i]; 1851 1.1 alc /* XXX 5211 requires a hack though we don't support 11g */ 1852 1.1 alc if (ah->ah_magic == 0x19570405) 1853 1.1 alc ee->ee_channels11g[i] = channels11b[i]; 1854 1.1 alc else 1855 1.1 alc ee->ee_channels11g[i] = channels11g[i]; 1856 1.1 alc ee->ee_dataPerChannel11b[i].numPcdacValues = NUM_PCDAC_VALUES; 1857 1.1 alc ee->ee_dataPerChannel11g[i].numPcdacValues = NUM_PCDAC_VALUES; 1858 1.1 alc } 1859 1.1 alc 1860 1.1 alc if (!legacyEepromReadContents(ah, ee)) { 1861 1.1 alc /* XXX message */ 1862 1.1 alc ath_hal_free(ee); 1863 1.1 alc return HAL_EEREAD; /* XXX */ 1864 1.1 alc } 1865 1.1 alc 1866 1.1 alc AH_PRIVATE(ah)->ah_eeprom = ee; 1867 1.1 alc AH_PRIVATE(ah)->ah_eeversion = eeversion; 1868 1.1 alc AH_PRIVATE(ah)->ah_eepromDetach = legacyEepromDetach; 1869 1.1 alc AH_PRIVATE(ah)->ah_eepromGet = legacyEepromGet; 1870 1.1 alc AH_PRIVATE(ah)->ah_eepromSet = legacyEepromSet; 1871 1.1 alc AH_PRIVATE(ah)->ah_getSpurChan = legacyEepromGetSpurChan; 1872 1.1 alc AH_PRIVATE(ah)->ah_eepromDiag = legacyEepromDiag; 1873 1.1 alc return HAL_OK; 1874 1.1 alc } 1875