1 /* 2 * Copyright (c) 2013 Qualcomm Atheros, 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 WITH 9 * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY 10 * AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, 11 * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM 12 * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR 13 * OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR 14 * PERFORMANCE OF THIS SOFTWARE. 15 */ 16 17 18 #include "opt_ah.h" 19 20 #include "ah.h" 21 #include "ah_desc.h" 22 #include "ah_internal.h" 23 24 #include "ar9300/ar9300.h" 25 #include "ar9300/ar9300phy.h" 26 #include "ar9300/ar9300reg.h" 27 28 /* 29 * Default 5413/9300 radar phy parameters 30 * Values adjusted to fix EV76432/EV76320 31 */ 32 #define AR9300_DFS_FIRPWR -28 33 #define AR9300_DFS_RRSSI 0 34 #define AR9300_DFS_HEIGHT 10 35 #define AR9300_DFS_PRSSI 6 36 #define AR9300_DFS_INBAND 8 37 #define AR9300_DFS_RELPWR 8 38 #define AR9300_DFS_RELSTEP 12 39 #define AR9300_DFS_MAXLEN 255 40 41 /* 42 * This PRSSI value should be used during CAC. 43 */ 44 #define AR9300_DFS_PRSSI_CAC 10 45 46 /* 47 * make sure that value matches value in ar9300_osprey_2p2_mac_core[][2] 48 * for register 0x1040 to 0x104c 49 */ 50 #define AR9300_DEFAULT_DIFS 0x002ffc0f 51 #define AR9300_FCC_RADARS_FCC_OFFSET 4 52 53 struct dfs_pulse ar9300_etsi_radars[] = { 54 55 /* for short pulses, RSSI threshold should be smaller than 56 * Kquick-drop. The chip has only one chance to drop the gain which 57 * will be reported as the estimated RSSI */ 58 59 /* TYPE staggered pulse */ 60 /* 0.8-2us, 2-3 bursts,300-400 PRF, 10 pulses each */ 61 {30, 2, 300, 400, 2, 30, 3, 0, 5, 15, 0, 0, 1, 31}, /* Type 5*/ 62 /* 0.8-2us, 2-3 bursts, 400-1200 PRF, 15 pulses each */ 63 {30, 2, 400, 1200, 2, 30, 7, 0, 5, 15, 0, 0, 0, 32}, /* Type 6 */ 64 65 /* constant PRF based */ 66 /* 0.8-5us, 200 300 PRF, 10 pulses */ 67 {10, 5, 200, 400, 0, 24, 5, 0, 8, 15, 0, 0, 2, 33}, /* Type 1 */ 68 {10, 5, 400, 600, 0, 24, 5, 0, 8, 15, 0, 0, 2, 37}, /* Type 1 */ 69 {10, 5, 600, 800, 0, 24, 5, 0, 8, 15, 0, 0, 2, 38}, /* Type 1 */ 70 {10, 5, 800, 1000, 0, 24, 5, 0, 8, 15, 0, 0, 2, 39}, /* Type 1 */ 71 // {10, 5, 200, 1000, 0, 24, 5, 0, 8, 15, 0, 0, 2, 33}, 72 73 /* 0.8-15us, 200-1600 PRF, 15 pulses */ 74 {15, 15, 200, 1600, 0, 24, 8, 0, 18, 24, 0, 0, 0, 34}, /* Type 2 */ 75 76 /* 0.8-15us, 2300-4000 PRF, 25 pulses*/ 77 {25, 15, 2300, 4000, 0, 24, 10, 0, 18, 24, 0, 0, 0, 35}, /* Type 3 */ 78 79 /* 20-30us, 2000-4000 PRF, 20 pulses*/ 80 {20, 30, 2000, 4000, 0, 24, 8, 19, 33, 24, 0, 0, 0, 36}, /* Type 4 */ 81 }; 82 83 84 /* The following are for FCC Bin 1-4 pulses */ 85 struct dfs_pulse ar9300_fcc_radars[] = { 86 87 /* following two filters are specific to Japan/MKK4 */ 88 // {18, 1, 720, 720, 1, 6, 6, 0, 1, 18, 0, 3, 0, 17}, // 1389 +/- 6 us 89 // {18, 4, 250, 250, 1, 10, 5, 1, 6, 18, 0, 3, 0, 18}, // 4000 +/- 6 us 90 // {18, 5, 260, 260, 1, 10, 6, 1, 6, 18, 0, 3, 0, 19}, // 3846 +/- 7 us 91 {18, 1, 720, 720, 0, 6, 6, 0, 1, 18, 0, 3, 0, 17}, // 1389 +/- 6 us 92 {18, 4, 250, 250, 0, 10, 5, 1, 6, 18, 0, 3, 0, 18}, // 4000 +/- 6 us 93 {18, 5, 260, 260, 0, 10, 6, 1, 6, 18, 0, 3, 1, 19}, // 3846 +/- 7 us 94 // {18, 5, 260, 260, 1, 10, 6, 1, 6, 18, 0, 3, 1, 20}, // 3846 +/- 7 us 95 96 {18, 5, 260, 260, 1, 10, 6, 1, 6, 18, 0, 3, 1, 20}, // 3846 +/- 7 us 97 98 99 /* following filters are common to both FCC and JAPAN */ 100 101 // FCC TYPE 1 102 // {18, 1, 325, 1930, 0, 6, 7, 0, 1, 18, 0, 3, 0, 0}, // 518 to 3066 103 {18, 1, 700, 700, 0, 6, 5, 0, 1, 18, 0, 3, 1, 8}, 104 {18, 1, 350, 350, 0, 6, 5, 0, 1, 18, 0, 3, 0, 0}, 105 106 107 // FCC TYPE 6 108 // {9, 1, 3003, 3003, 1, 7, 5, 0, 1, 18, 0, 0, 0, 1}, // 333 +/- 7 us 109 //{9, 1, 3003, 3003, 1, 7, 5, 0, 1, 18, 0, 0, 0, 1}, 110 {9, 1, 3003, 3003, 0, 7, 5, 0, 1, 18, 0, 0, 1, 1}, 111 112 // FCC TYPE 2 113 {23, 5, 4347, 6666, 0, 18, 11, 0, 7, 22, 0, 3, 0, 2}, 114 115 // FCC TYPE 3 116 {18, 10, 2000, 5000, 0, 23, 8, 6, 13, 22, 0, 3, 0, 5}, 117 118 // FCC TYPE 4 119 {16, 15, 2000, 5000, 0, 25, 7, 11, 23, 22, 0, 3, 0, 11}, 120 121 }; 122 123 struct dfs_bin5pulse ar9300_bin5pulses[] = { 124 {2, 28, 105, 12, 22, 5}, 125 }; 126 127 128 #if 0 129 /* 130 * Find the internal HAL channel corresponding to the 131 * public HAL channel specified in c 132 */ 133 134 static HAL_CHANNEL_INTERNAL * 135 getchannel(struct ath_hal *ah, const struct ieee80211_channel *c) 136 { 137 #define CHAN_FLAGS (CHANNEL_ALL | CHANNEL_HALF | CHANNEL_QUARTER) 138 HAL_CHANNEL_INTERNAL *base, *cc; 139 int flags = c->channel_flags & CHAN_FLAGS; 140 int n, lim; 141 142 /* 143 * Check current channel to avoid the lookup. 144 */ 145 cc = AH_PRIVATE(ah)->ah_curchan; 146 if (cc != AH_NULL && cc->channel == c->channel && 147 (cc->channel_flags & CHAN_FLAGS) == flags) { 148 return cc; 149 } 150 151 /* binary search based on known sorting order */ 152 base = AH_TABLES(ah)->ah_channels; 153 n = AH_PRIVATE(ah)->ah_nchan; 154 /* binary search based on known sorting order */ 155 for (lim = n; lim != 0; lim >>= 1) { 156 int d; 157 cc = &base[lim >> 1]; 158 d = c->channel - cc->channel; 159 if (d == 0) { 160 if ((cc->channel_flags & CHAN_FLAGS) == flags) { 161 return cc; 162 } 163 d = flags - (cc->channel_flags & CHAN_FLAGS); 164 } 165 HALDEBUG(ah, HAL_DEBUG_DFS, "%s: channel %u/0x%x d %d\n", __func__, 166 cc->channel, cc->channel_flags, d); 167 if (d > 0) { 168 base = cc + 1; 169 lim--; 170 } 171 } 172 HALDEBUG(ah, HAL_DEBUG_DFS, "%s: no match for %u/0x%x\n", 173 __func__, c->channel, c->channel_flags); 174 return AH_NULL; 175 #undef CHAN_FLAGS 176 } 177 178 /* 179 * Check the internal channel list to see if the desired channel 180 * is ok to release from the NOL. If not, then do nothing. If so, 181 * mark the channel as clear and reset the internal tsf time 182 */ 183 void 184 ar9300_check_dfs(struct ath_hal *ah, struct ieee80211_channel *chan) 185 { 186 HAL_CHANNEL_INTERNAL *ichan = AH_NULL; 187 188 ichan = getchannel(ah, chan); 189 if (ichan == AH_NULL) { 190 return; 191 } 192 if (!(ichan->priv_flags & CHANNEL_INTERFERENCE)) { 193 return; 194 } 195 196 ichan->priv_flags &= ~CHANNEL_INTERFERENCE; 197 ichan->dfs_tsf = 0; 198 } 199 200 /* 201 * This function marks the channel as having found a dfs event 202 * It also marks the end time that the dfs event should be cleared 203 * If the channel is already marked, then tsf end time can only 204 * be increased 205 */ 206 void 207 ar9300_dfs_found(struct ath_hal *ah, struct ieee80211_channel *chan, u_int64_t nol_time) 208 { 209 HAL_CHANNEL_INTERNAL *ichan; 210 211 ichan = getchannel(ah, chan); 212 if (ichan == AH_NULL) { 213 return; 214 } 215 if (!(ichan->priv_flags & CHANNEL_INTERFERENCE)) { 216 ichan->dfs_tsf = ar9300_get_tsf64(ah); 217 } 218 ichan->dfs_tsf += nol_time; 219 ichan->priv_flags |= CHANNEL_INTERFERENCE; 220 chan->priv_flags |= CHANNEL_INTERFERENCE; 221 } 222 #endif 223 224 /* 225 * Enable radar detection and set the radar parameters per the 226 * values in pe 227 */ 228 void 229 ar9300_enable_dfs(struct ath_hal *ah, HAL_PHYERR_PARAM *pe) 230 { 231 u_int32_t val; 232 struct ath_hal_private *ahp = AH_PRIVATE(ah); 233 const struct ieee80211_channel *chan = ahp->ah_curchan; 234 struct ath_hal_9300 *ah9300 = AH9300(ah); 235 int reg_writes = 0; 236 237 val = OS_REG_READ(ah, AR_PHY_RADAR_0); 238 val |= AR_PHY_RADAR_0_FFT_ENA; 239 240 241 if (pe->pe_enabled != HAL_PHYERR_PARAM_NOVAL) { 242 val &= ~AR_PHY_RADAR_0_ENA; 243 val |= SM(pe->pe_enabled, AR_PHY_RADAR_0_ENA); 244 } 245 246 if (pe->pe_firpwr != HAL_PHYERR_PARAM_NOVAL) { 247 val &= ~AR_PHY_RADAR_0_FIRPWR; 248 val |= SM(pe->pe_firpwr, AR_PHY_RADAR_0_FIRPWR); 249 } 250 if (pe->pe_rrssi != HAL_PHYERR_PARAM_NOVAL) { 251 val &= ~AR_PHY_RADAR_0_RRSSI; 252 val |= SM(pe->pe_rrssi, AR_PHY_RADAR_0_RRSSI); 253 } 254 if (pe->pe_height != HAL_PHYERR_PARAM_NOVAL) { 255 val &= ~AR_PHY_RADAR_0_HEIGHT; 256 val |= SM(pe->pe_height, AR_PHY_RADAR_0_HEIGHT); 257 } 258 if (pe->pe_prssi != HAL_PHYERR_PARAM_NOVAL) { 259 val &= ~AR_PHY_RADAR_0_PRSSI; 260 if (AR_SREV_AR9580(ah) || AR_SREV_WASP(ah) || AR_SREV_SCORPION(ah)) { 261 #if 0 262 if (ah->ah_use_cac_prssi) { 263 val |= SM(AR9300_DFS_PRSSI_CAC, AR_PHY_RADAR_0_PRSSI); 264 } else { 265 #endif 266 val |= SM(pe->pe_prssi, AR_PHY_RADAR_0_PRSSI); 267 // } 268 } else { 269 val |= SM(pe->pe_prssi, AR_PHY_RADAR_0_PRSSI); 270 } 271 } 272 if (pe->pe_inband != HAL_PHYERR_PARAM_NOVAL) { 273 val &= ~AR_PHY_RADAR_0_INBAND; 274 val |= SM(pe->pe_inband, AR_PHY_RADAR_0_INBAND); 275 } 276 OS_REG_WRITE(ah, AR_PHY_RADAR_0, val); 277 278 val = OS_REG_READ(ah, AR_PHY_RADAR_1); 279 val |= AR_PHY_RADAR_1_MAX_RRSSI | AR_PHY_RADAR_1_BLOCK_CHECK; 280 if (pe->pe_maxlen != HAL_PHYERR_PARAM_NOVAL) { 281 val &= ~AR_PHY_RADAR_1_MAXLEN; 282 val |= SM(pe->pe_maxlen, AR_PHY_RADAR_1_MAXLEN); 283 } 284 if (pe->pe_relstep != HAL_PHYERR_PARAM_NOVAL) { 285 val &= ~AR_PHY_RADAR_1_RELSTEP_THRESH; 286 val |= SM(pe->pe_relstep, AR_PHY_RADAR_1_RELSTEP_THRESH); 287 } 288 if (pe->pe_relpwr != HAL_PHYERR_PARAM_NOVAL) { 289 val &= ~AR_PHY_RADAR_1_RELPWR_THRESH; 290 val |= SM(pe->pe_relpwr, AR_PHY_RADAR_1_RELPWR_THRESH); 291 } 292 OS_REG_WRITE(ah, AR_PHY_RADAR_1, val); 293 294 if (ath_hal_getcapability(ah, HAL_CAP_EXT_CHAN_DFS, 0, 0) == HAL_OK) { 295 val = OS_REG_READ(ah, AR_PHY_RADAR_EXT); 296 if (IEEE80211_IS_CHAN_HT40(chan)) { 297 /* Enable extension channel radar detection */ 298 OS_REG_WRITE(ah, AR_PHY_RADAR_EXT, val | AR_PHY_RADAR_EXT_ENA); 299 } else { 300 /* HT20 mode, disable extension channel radar detect */ 301 OS_REG_WRITE(ah, AR_PHY_RADAR_EXT, val & ~AR_PHY_RADAR_EXT_ENA); 302 } 303 } 304 /* 305 apply DFS postamble array from INI 306 column 0 is register ID, column 1 is HT20 value, colum2 is HT40 value 307 */ 308 309 if (AR_SREV_AR9580(ah) || AR_SREV_WASP(ah) || AR_SREV_OSPREY_22(ah) || AR_SREV_SCORPION(ah)) { 310 REG_WRITE_ARRAY(&ah9300->ah_ini_dfs, IEEE80211_IS_CHAN_HT40(chan)? 2:1, reg_writes); 311 } 312 #ifdef ATH_HAL_DFS_CHIRPING_FIX_APH128 313 ath_hal_printf(ah, "DFS change the timing value\n"); 314 if (AR_SREV_AR9580(ah) && IEEE80211_IS_CHAN_HT40(chan)) { 315 OS_REG_WRITE(ah, AR_PHY_TIMING6, 0x3140c00a); 316 } 317 #endif 318 319 } 320 321 /* 322 * Get the radar parameter values and return them in the pe 323 * structure 324 */ 325 void 326 ar9300_get_dfs_thresh(struct ath_hal *ah, HAL_PHYERR_PARAM *pe) 327 { 328 u_int32_t val, temp; 329 330 val = OS_REG_READ(ah, AR_PHY_RADAR_0); 331 temp = MS(val, AR_PHY_RADAR_0_FIRPWR); 332 temp |= ~(AR_PHY_RADAR_0_FIRPWR >> AR_PHY_RADAR_0_FIRPWR_S); 333 pe->pe_firpwr = temp; 334 pe->pe_rrssi = MS(val, AR_PHY_RADAR_0_RRSSI); 335 pe->pe_height = MS(val, AR_PHY_RADAR_0_HEIGHT); 336 pe->pe_prssi = MS(val, AR_PHY_RADAR_0_PRSSI); 337 pe->pe_inband = MS(val, AR_PHY_RADAR_0_INBAND); 338 pe->pe_enabled = !! MS(val, AR_PHY_RADAR_0_ENA); 339 340 val = OS_REG_READ(ah, AR_PHY_RADAR_1); 341 342 pe->pe_relpwr = MS(val, AR_PHY_RADAR_1_RELPWR_THRESH); 343 pe->pe_enrelpwr = !! (val & AR_PHY_RADAR_1_RELPWR_ENA); 344 345 pe->pe_relstep = MS(val, AR_PHY_RADAR_1_RELSTEP_THRESH); 346 pe->pe_en_relstep_check = !! (val & AR_PHY_RADAR_1_RELSTEP_CHECK); 347 348 pe->pe_maxlen = MS(val, AR_PHY_RADAR_1_MAXLEN); 349 } 350 351 #if 0 352 HAL_BOOL 353 ar9300_radar_wait(struct ath_hal *ah, struct ieee80211_channel *chan) 354 { 355 struct ath_hal_private *ahp = AH_PRIVATE(ah); 356 357 if (!ahp->ah_curchan) { 358 return AH_TRUE; 359 } 360 361 /* 362 * Rely on the upper layers to determine that we have spent 363 * enough time waiting. 364 */ 365 chan->channel = ahp->ah_curchan->channel; 366 chan->channel_flags = ahp->ah_curchan->channel_flags; 367 chan->max_reg_tx_power = ahp->ah_curchan->max_reg_tx_power; 368 369 ahp->ah_curchan->priv_flags |= CHANNEL_DFS_CLEAR; 370 chan->priv_flags = ahp->ah_curchan->priv_flags; 371 return AH_FALSE; 372 373 } 374 #endif 375 376 struct dfs_pulse * 377 ar9300_get_dfs_radars( 378 struct ath_hal *ah, 379 u_int32_t dfsdomain, 380 int *numradars, 381 struct dfs_bin5pulse **bin5pulses, 382 int *numb5radars, 383 HAL_PHYERR_PARAM *pe) 384 { 385 struct dfs_pulse *dfs_radars = AH_NULL; 386 switch (dfsdomain) { 387 case HAL_DFS_FCC_DOMAIN: 388 dfs_radars = &ar9300_fcc_radars[AR9300_FCC_RADARS_FCC_OFFSET]; 389 *numradars = 390 ARRAY_LENGTH(ar9300_fcc_radars) - AR9300_FCC_RADARS_FCC_OFFSET; 391 *bin5pulses = &ar9300_bin5pulses[0]; 392 *numb5radars = ARRAY_LENGTH(ar9300_bin5pulses); 393 HALDEBUG(ah, HAL_DEBUG_DFS, "%s: DFS_FCC_DOMAIN_9300\n", __func__); 394 break; 395 case HAL_DFS_ETSI_DOMAIN: 396 dfs_radars = &ar9300_etsi_radars[0]; 397 *numradars = ARRAY_LENGTH(ar9300_etsi_radars); 398 *bin5pulses = &ar9300_bin5pulses[0]; 399 *numb5radars = ARRAY_LENGTH(ar9300_bin5pulses); 400 HALDEBUG(ah, HAL_DEBUG_DFS, "%s: DFS_ETSI_DOMAIN_9300\n", __func__); 401 break; 402 case HAL_DFS_MKK4_DOMAIN: 403 dfs_radars = &ar9300_fcc_radars[0]; 404 *numradars = ARRAY_LENGTH(ar9300_fcc_radars); 405 *bin5pulses = &ar9300_bin5pulses[0]; 406 *numb5radars = ARRAY_LENGTH(ar9300_bin5pulses); 407 HALDEBUG(ah, HAL_DEBUG_DFS, "%s: DFS_MKK4_DOMAIN_9300\n", __func__); 408 break; 409 default: 410 HALDEBUG(ah, HAL_DEBUG_DFS, "%s: no domain\n", __func__); 411 return AH_NULL; 412 } 413 /* Set the default phy parameters per chip */ 414 pe->pe_firpwr = AR9300_DFS_FIRPWR; 415 pe->pe_rrssi = AR9300_DFS_RRSSI; 416 pe->pe_height = AR9300_DFS_HEIGHT; 417 pe->pe_prssi = AR9300_DFS_PRSSI; 418 /* 419 we have an issue with PRSSI. 420 For normal operation we use AR9300_DFS_PRSSI, which is set to 6. 421 Please refer to EV91563, 94164. 422 However, this causes problem during CAC as no radar is detected 423 during that period with PRSSI=6. Only PRSSI= 10 seems to fix this. 424 We use this flag to keep track of change in PRSSI. 425 */ 426 427 // ah->ah_use_cac_prssi = 0; 428 429 pe->pe_inband = AR9300_DFS_INBAND; 430 pe->pe_relpwr = AR9300_DFS_RELPWR; 431 pe->pe_relstep = AR9300_DFS_RELSTEP; 432 pe->pe_maxlen = AR9300_DFS_MAXLEN; 433 return dfs_radars; 434 } 435 436 HAL_BOOL 437 ar9300_get_default_dfs_thresh(struct ath_hal *ah, HAL_PHYERR_PARAM *pe) 438 { 439 440 pe->pe_firpwr = AR9300_DFS_FIRPWR; 441 pe->pe_rrssi = AR9300_DFS_RRSSI; 442 pe->pe_height = AR9300_DFS_HEIGHT; 443 pe->pe_prssi = AR9300_DFS_PRSSI; 444 /* see prssi comment above */ 445 446 pe->pe_inband = AR9300_DFS_INBAND; 447 pe->pe_relpwr = AR9300_DFS_RELPWR; 448 pe->pe_relstep = AR9300_DFS_RELSTEP; 449 pe->pe_maxlen = AR9300_DFS_MAXLEN; 450 return (AH_TRUE); 451 } 452 453 void ar9300_adjust_difs(struct ath_hal *ah, u_int32_t val) 454 { 455 if (val == 0) { 456 /* 457 * EV 116936: 458 * Restore the register values with that of the HAL structure. 459 * Do not assume and overwrite these values to whatever 460 * is in ar9300_osprey22.ini. 461 */ 462 struct ath_hal_9300 *ahp = AH9300(ah); 463 HAL_TX_QUEUE_INFO *qi; 464 int q; 465 466 AH9300(ah)->ah_fccaifs = 0; 467 HALDEBUG(ah, HAL_DEBUG_DFS, "%s: restore DIFS \n", __func__); 468 for (q = 0; q < 4; q++) { 469 qi = &ahp->ah_txq[q]; 470 OS_REG_WRITE(ah, AR_DLCL_IFS(q), 471 SM(qi->tqi_cwmin, AR_D_LCL_IFS_CWMIN) 472 | SM(qi->tqi_cwmax, AR_D_LCL_IFS_CWMAX) 473 | SM(qi->tqi_aifs, AR_D_LCL_IFS_AIFS)); 474 } 475 } else { 476 /* 477 * These are values from George Lai and are specific to 478 * FCC domain. They are yet to be determined for other domains. 479 */ 480 481 AH9300(ah)->ah_fccaifs = 1; 482 HALDEBUG(ah, HAL_DEBUG_DFS, "%s: set DIFS to default\n", __func__); 483 /*printk("%s: modify DIFS\n", __func__);*/ 484 485 OS_REG_WRITE(ah, AR_DLCL_IFS(0), 0x05fffc0f); 486 OS_REG_WRITE(ah, AR_DLCL_IFS(1), 0x05f0fc0f); 487 OS_REG_WRITE(ah, AR_DLCL_IFS(2), 0x05f03c07); 488 OS_REG_WRITE(ah, AR_DLCL_IFS(3), 0x05f01c03); 489 } 490 } 491 492 u_int32_t ar9300_dfs_config_fft(struct ath_hal *ah, HAL_BOOL is_enable) 493 { 494 u_int32_t val; 495 496 val = OS_REG_READ(ah, AR_PHY_RADAR_0); 497 498 if (is_enable) { 499 val |= AR_PHY_RADAR_0_FFT_ENA; 500 } else { 501 val &= ~AR_PHY_RADAR_0_FFT_ENA; 502 } 503 504 OS_REG_WRITE(ah, AR_PHY_RADAR_0, val); 505 val = OS_REG_READ(ah, AR_PHY_RADAR_0); 506 return val; 507 } 508 /* 509 function to adjust PRSSI value for CAC problem 510 511 */ 512 void 513 ar9300_dfs_cac_war(struct ath_hal *ah, u_int32_t start) 514 { 515 u_int32_t val; 516 517 if (AR_SREV_AR9580(ah) || AR_SREV_WASP(ah) || AR_SREV_SCORPION(ah)) { 518 val = OS_REG_READ(ah, AR_PHY_RADAR_0); 519 if (start) { 520 val &= ~AR_PHY_RADAR_0_PRSSI; 521 val |= SM(AR9300_DFS_PRSSI_CAC, AR_PHY_RADAR_0_PRSSI); 522 } else { 523 val &= ~AR_PHY_RADAR_0_PRSSI; 524 val |= SM(AR9300_DFS_PRSSI, AR_PHY_RADAR_0_PRSSI); 525 } 526 OS_REG_WRITE(ah, AR_PHY_RADAR_0, val | AR_PHY_RADAR_0_ENA); 527 // ah->ah_use_cac_prssi = start; 528 } 529 } 530 531 #if 0 532 struct ieee80211_channel * 533 ar9300_get_extension_channel(struct ath_hal *ah) 534 { 535 struct ath_hal_private *ahp = AH_PRIVATE(ah); 536 struct ath_hal_private_tables *aht = AH_TABLES(ah); 537 int i = 0; 538 539 HAL_CHANNEL_INTERNAL *ichan = AH_NULL; 540 CHAN_CENTERS centers; 541 542 ichan = ahp->ah_curchan; 543 ar9300_get_channel_centers(ah, ichan, ¢ers); 544 if (centers.ctl_center == centers.ext_center) { 545 return AH_NULL; 546 } 547 for (i = 0; i < ahp->ah_nchan; i++) { 548 ichan = &aht->ah_channels[i]; 549 if (ichan->channel == centers.ext_center) { 550 return (struct ieee80211_channel*)ichan; 551 } 552 } 553 return AH_NULL; 554 } 555 #endif 556 557 HAL_BOOL 558 ar9300_is_fast_clock_enabled(struct ath_hal *ah) 559 { 560 struct ath_hal_private *ahp = AH_PRIVATE(ah); 561 562 if (IS_5GHZ_FAST_CLOCK_EN(ah, ahp->ah_curchan)) { 563 return AH_TRUE; 564 } 565 return AH_FALSE; 566 } 567 568 /* 569 * This should be enabled and linked into the build once 570 * radar support is enabled. 571 */ 572 #if 0 573 HAL_BOOL 574 ar9300_handle_radar_bb_panic(struct ath_hal *ah) 575 { 576 u_int32_t status; 577 u_int32_t val; 578 #ifdef AH_DEBUG 579 struct ath_hal_9300 *ahp = AH9300(ah); 580 #endif 581 582 status = AH_PRIVATE(ah)->ah_bb_panic_last_status; 583 584 if ( status == 0x04000539 ) { 585 /* recover from this BB panic without reset*/ 586 /* set AR9300_DFS_FIRPWR to -1 */ 587 val = OS_REG_READ(ah, AR_PHY_RADAR_0); 588 val &= (~AR_PHY_RADAR_0_FIRPWR); 589 val |= SM( 0x7f, AR_PHY_RADAR_0_FIRPWR); 590 OS_REG_WRITE(ah, AR_PHY_RADAR_0, val); 591 OS_DELAY(1); 592 /* set AR9300_DFS_FIRPWR to its default value */ 593 val = OS_REG_READ(ah, AR_PHY_RADAR_0); 594 val &= ~AR_PHY_RADAR_0_FIRPWR; 595 val |= SM( AR9300_DFS_FIRPWR, AR_PHY_RADAR_0_FIRPWR); 596 OS_REG_WRITE(ah, AR_PHY_RADAR_0, val); 597 return AH_TRUE; 598 } else if (status == 0x0400000a) { 599 /* EV 92527 : reset required if we see this signature */ 600 HALDEBUG(ah, HAL_DEBUG_DFS, "%s: BB Panic -- 0x0400000a\n", __func__); 601 return AH_FALSE; 602 } else if (status == 0x1300000a) { 603 /* EV92527: we do not need a reset if we see this signature */ 604 HALDEBUG(ah, HAL_DEBUG_DFS, "%s: BB Panic -- 0x1300000a\n", __func__); 605 return AH_TRUE; 606 } else if ((AR_SREV_WASP(ah) || AR_SREV_HONEYBEE(ah)) && (status == 0x04000409)) { 607 return AH_TRUE; 608 } else { 609 if (ar9300_get_capability(ah, HAL_CAP_LDPCWAR, 0, AH_NULL) == HAL_OK && 610 (status & 0xff00000f) == 0x04000009 && 611 status != 0x04000409 && 612 status != 0x04000b09 && 613 status != 0x04000e09 && 614 (status & 0x0000ff00)) 615 { 616 /* disable RIFS Rx */ 617 #ifdef AH_DEBUG 618 HALDEBUG(ah, HAL_DEBUG_UNMASKABLE, "%s: BB status=0x%08x rifs=%d - disable\n", 619 __func__, status, ahp->ah_rifs_enabled); 620 ar9300_set_rifs_delay(ah, AH_FALSE); 621 } 622 return AH_FALSE; 623 } 624 } 625 #endif 626 #endif 627