ani.c 37 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297
  1. /*
  2. * Copyright (c) 2008-2010 Atheros Communications Inc.
  3. *
  4. * Permission to use, copy, modify, and/or distribute this software for any
  5. * purpose with or without fee is hereby granted, provided that the above
  6. * copyright notice and this permission notice appear in all copies.
  7. *
  8. * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
  9. * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
  10. * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
  11. * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
  12. * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
  13. * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
  14. * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
  15. */
  16. #include <linux/kernel.h>
  17. #include "hw.h"
  18. #include "hw-ops.h"
  19. struct ani_ofdm_level_entry {
  20. int spur_immunity_level;
  21. int fir_step_level;
  22. int ofdm_weak_signal_on;
  23. };
  24. /* values here are relative to the INI */
  25. /*
  26. * Legend:
  27. *
  28. * SI: Spur immunity
  29. * FS: FIR Step
  30. * WS: OFDM / CCK Weak Signal detection
  31. * MRC-CCK: Maximal Ratio Combining for CCK
  32. */
  33. static const struct ani_ofdm_level_entry ofdm_level_table[] = {
  34. /* SI FS WS */
  35. { 0, 0, 1 }, /* lvl 0 */
  36. { 1, 1, 1 }, /* lvl 1 */
  37. { 2, 2, 1 }, /* lvl 2 */
  38. { 3, 2, 1 }, /* lvl 3 (default) */
  39. { 4, 3, 1 }, /* lvl 4 */
  40. { 5, 4, 1 }, /* lvl 5 */
  41. { 6, 5, 1 }, /* lvl 6 */
  42. { 7, 6, 1 }, /* lvl 7 */
  43. { 7, 7, 1 }, /* lvl 8 */
  44. { 7, 8, 0 } /* lvl 9 */
  45. };
  46. #define ATH9K_ANI_OFDM_NUM_LEVEL \
  47. ARRAY_SIZE(ofdm_level_table)
  48. #define ATH9K_ANI_OFDM_MAX_LEVEL \
  49. (ATH9K_ANI_OFDM_NUM_LEVEL-1)
  50. #define ATH9K_ANI_OFDM_DEF_LEVEL \
  51. 3 /* default level - matches the INI settings */
  52. /*
  53. * MRC (Maximal Ratio Combining) has always been used with multi-antenna ofdm.
  54. * With OFDM for single stream you just add up all antenna inputs, you're
  55. * only interested in what you get after FFT. Signal aligment is also not
  56. * required for OFDM because any phase difference adds up in the frequency
  57. * domain.
  58. *
  59. * MRC requires extra work for use with CCK. You need to align the antenna
  60. * signals from the different antenna before you can add the signals together.
  61. * You need aligment of signals as CCK is in time domain, so addition can cancel
  62. * your signal completely if phase is 180 degrees (think of adding sine waves).
  63. * You also need to remove noise before the addition and this is where ANI
  64. * MRC CCK comes into play. One of the antenna inputs may be stronger but
  65. * lower SNR, so just adding after alignment can be dangerous.
  66. *
  67. * Regardless of alignment in time, the antenna signals add constructively after
  68. * FFT and improve your reception. For more information:
  69. *
  70. * http://en.wikipedia.org/wiki/Maximal-ratio_combining
  71. */
  72. struct ani_cck_level_entry {
  73. int fir_step_level;
  74. int mrc_cck_on;
  75. };
  76. static const struct ani_cck_level_entry cck_level_table[] = {
  77. /* FS MRC-CCK */
  78. { 0, 1 }, /* lvl 0 */
  79. { 1, 1 }, /* lvl 1 */
  80. { 2, 1 }, /* lvl 2 (default) */
  81. { 3, 1 }, /* lvl 3 */
  82. { 4, 0 }, /* lvl 4 */
  83. { 5, 0 }, /* lvl 5 */
  84. { 6, 0 }, /* lvl 6 */
  85. { 7, 0 }, /* lvl 7 (only for high rssi) */
  86. { 8, 0 } /* lvl 8 (only for high rssi) */
  87. };
  88. #define ATH9K_ANI_CCK_NUM_LEVEL \
  89. ARRAY_SIZE(cck_level_table)
  90. #define ATH9K_ANI_CCK_MAX_LEVEL \
  91. (ATH9K_ANI_CCK_NUM_LEVEL-1)
  92. #define ATH9K_ANI_CCK_MAX_LEVEL_LOW_RSSI \
  93. (ATH9K_ANI_CCK_NUM_LEVEL-3)
  94. #define ATH9K_ANI_CCK_DEF_LEVEL \
  95. 2 /* default level - matches the INI settings */
  96. /* Private to ani.c */
  97. static void ath9k_hw_ani_lower_immunity(struct ath_hw *ah)
  98. {
  99. ath9k_hw_private_ops(ah)->ani_lower_immunity(ah);
  100. }
  101. static bool use_new_ani(struct ath_hw *ah)
  102. {
  103. return AR_SREV_9300_20_OR_LATER(ah) || modparam_force_new_ani;
  104. }
  105. int ath9k_hw_get_ani_channel_idx(struct ath_hw *ah,
  106. struct ath9k_channel *chan)
  107. {
  108. int i;
  109. for (i = 0; i < ARRAY_SIZE(ah->ani); i++) {
  110. if (ah->ani[i].c &&
  111. ah->ani[i].c->channel == chan->channel)
  112. return i;
  113. if (ah->ani[i].c == NULL) {
  114. ah->ani[i].c = chan;
  115. return i;
  116. }
  117. }
  118. ath_print(ath9k_hw_common(ah), ATH_DBG_ANI,
  119. "No more channel states left. Using channel 0\n");
  120. return 0;
  121. }
  122. static void ath9k_hw_update_mibstats(struct ath_hw *ah,
  123. struct ath9k_mib_stats *stats)
  124. {
  125. stats->ackrcv_bad += REG_READ(ah, AR_ACK_FAIL);
  126. stats->rts_bad += REG_READ(ah, AR_RTS_FAIL);
  127. stats->fcs_bad += REG_READ(ah, AR_FCS_FAIL);
  128. stats->rts_good += REG_READ(ah, AR_RTS_OK);
  129. stats->beacons += REG_READ(ah, AR_BEACON_CNT);
  130. }
  131. static void ath9k_ani_restart_old(struct ath_hw *ah)
  132. {
  133. struct ar5416AniState *aniState;
  134. struct ath_common *common = ath9k_hw_common(ah);
  135. if (!DO_ANI(ah))
  136. return;
  137. aniState = ah->curani;
  138. aniState->listenTime = 0;
  139. if (aniState->ofdmTrigHigh > AR_PHY_COUNTMAX) {
  140. aniState->ofdmPhyErrBase = 0;
  141. ath_print(common, ATH_DBG_ANI,
  142. "OFDM Trigger is too high for hw counters\n");
  143. } else {
  144. aniState->ofdmPhyErrBase =
  145. AR_PHY_COUNTMAX - aniState->ofdmTrigHigh;
  146. }
  147. if (aniState->cckTrigHigh > AR_PHY_COUNTMAX) {
  148. aniState->cckPhyErrBase = 0;
  149. ath_print(common, ATH_DBG_ANI,
  150. "CCK Trigger is too high for hw counters\n");
  151. } else {
  152. aniState->cckPhyErrBase =
  153. AR_PHY_COUNTMAX - aniState->cckTrigHigh;
  154. }
  155. ath_print(common, ATH_DBG_ANI,
  156. "Writing ofdmbase=%u cckbase=%u\n",
  157. aniState->ofdmPhyErrBase,
  158. aniState->cckPhyErrBase);
  159. ENABLE_REGWRITE_BUFFER(ah);
  160. REG_WRITE(ah, AR_PHY_ERR_1, aniState->ofdmPhyErrBase);
  161. REG_WRITE(ah, AR_PHY_ERR_2, aniState->cckPhyErrBase);
  162. REG_WRITE(ah, AR_PHY_ERR_MASK_1, AR_PHY_ERR_OFDM_TIMING);
  163. REG_WRITE(ah, AR_PHY_ERR_MASK_2, AR_PHY_ERR_CCK_TIMING);
  164. REGWRITE_BUFFER_FLUSH(ah);
  165. ath9k_hw_update_mibstats(ah, &ah->ah_mibStats);
  166. aniState->ofdmPhyErrCount = 0;
  167. aniState->cckPhyErrCount = 0;
  168. }
  169. static void ath9k_ani_restart_new(struct ath_hw *ah)
  170. {
  171. struct ar5416AniState *aniState;
  172. struct ath_common *common = ath9k_hw_common(ah);
  173. if (!DO_ANI(ah))
  174. return;
  175. aniState = ah->curani;
  176. aniState->listenTime = 0;
  177. aniState->ofdmPhyErrBase = 0;
  178. aniState->cckPhyErrBase = 0;
  179. ath_print(common, ATH_DBG_ANI,
  180. "Writing ofdmbase=%08x cckbase=%08x\n",
  181. aniState->ofdmPhyErrBase,
  182. aniState->cckPhyErrBase);
  183. ENABLE_REGWRITE_BUFFER(ah);
  184. REG_WRITE(ah, AR_PHY_ERR_1, aniState->ofdmPhyErrBase);
  185. REG_WRITE(ah, AR_PHY_ERR_2, aniState->cckPhyErrBase);
  186. REG_WRITE(ah, AR_PHY_ERR_MASK_1, AR_PHY_ERR_OFDM_TIMING);
  187. REG_WRITE(ah, AR_PHY_ERR_MASK_2, AR_PHY_ERR_CCK_TIMING);
  188. REGWRITE_BUFFER_FLUSH(ah);
  189. ath9k_hw_update_mibstats(ah, &ah->ah_mibStats);
  190. aniState->ofdmPhyErrCount = 0;
  191. aniState->cckPhyErrCount = 0;
  192. }
  193. static void ath9k_hw_ani_ofdm_err_trigger_old(struct ath_hw *ah)
  194. {
  195. struct ieee80211_conf *conf = &ath9k_hw_common(ah)->hw->conf;
  196. struct ar5416AniState *aniState;
  197. int32_t rssi;
  198. if (!DO_ANI(ah))
  199. return;
  200. aniState = ah->curani;
  201. if (aniState->noiseImmunityLevel < HAL_NOISE_IMMUNE_MAX) {
  202. if (ath9k_hw_ani_control(ah, ATH9K_ANI_NOISE_IMMUNITY_LEVEL,
  203. aniState->noiseImmunityLevel + 1)) {
  204. return;
  205. }
  206. }
  207. if (aniState->spurImmunityLevel < HAL_SPUR_IMMUNE_MAX) {
  208. if (ath9k_hw_ani_control(ah, ATH9K_ANI_SPUR_IMMUNITY_LEVEL,
  209. aniState->spurImmunityLevel + 1)) {
  210. return;
  211. }
  212. }
  213. if (ah->opmode == NL80211_IFTYPE_AP) {
  214. if (aniState->firstepLevel < HAL_FIRST_STEP_MAX) {
  215. ath9k_hw_ani_control(ah, ATH9K_ANI_FIRSTEP_LEVEL,
  216. aniState->firstepLevel + 1);
  217. }
  218. return;
  219. }
  220. rssi = BEACON_RSSI(ah);
  221. if (rssi > aniState->rssiThrHigh) {
  222. if (!aniState->ofdmWeakSigDetectOff) {
  223. if (ath9k_hw_ani_control(ah,
  224. ATH9K_ANI_OFDM_WEAK_SIGNAL_DETECTION,
  225. false)) {
  226. ath9k_hw_ani_control(ah,
  227. ATH9K_ANI_SPUR_IMMUNITY_LEVEL, 0);
  228. return;
  229. }
  230. }
  231. if (aniState->firstepLevel < HAL_FIRST_STEP_MAX) {
  232. ath9k_hw_ani_control(ah, ATH9K_ANI_FIRSTEP_LEVEL,
  233. aniState->firstepLevel + 1);
  234. return;
  235. }
  236. } else if (rssi > aniState->rssiThrLow) {
  237. if (aniState->ofdmWeakSigDetectOff)
  238. ath9k_hw_ani_control(ah,
  239. ATH9K_ANI_OFDM_WEAK_SIGNAL_DETECTION,
  240. true);
  241. if (aniState->firstepLevel < HAL_FIRST_STEP_MAX)
  242. ath9k_hw_ani_control(ah, ATH9K_ANI_FIRSTEP_LEVEL,
  243. aniState->firstepLevel + 1);
  244. return;
  245. } else {
  246. if ((conf->channel->band == IEEE80211_BAND_2GHZ) &&
  247. !conf_is_ht(conf)) {
  248. if (!aniState->ofdmWeakSigDetectOff)
  249. ath9k_hw_ani_control(ah,
  250. ATH9K_ANI_OFDM_WEAK_SIGNAL_DETECTION,
  251. false);
  252. if (aniState->firstepLevel > 0)
  253. ath9k_hw_ani_control(ah,
  254. ATH9K_ANI_FIRSTEP_LEVEL, 0);
  255. return;
  256. }
  257. }
  258. }
  259. static void ath9k_hw_ani_cck_err_trigger_old(struct ath_hw *ah)
  260. {
  261. struct ieee80211_conf *conf = &ath9k_hw_common(ah)->hw->conf;
  262. struct ar5416AniState *aniState;
  263. int32_t rssi;
  264. if (!DO_ANI(ah))
  265. return;
  266. aniState = ah->curani;
  267. if (aniState->noiseImmunityLevel < HAL_NOISE_IMMUNE_MAX) {
  268. if (ath9k_hw_ani_control(ah, ATH9K_ANI_NOISE_IMMUNITY_LEVEL,
  269. aniState->noiseImmunityLevel + 1)) {
  270. return;
  271. }
  272. }
  273. if (ah->opmode == NL80211_IFTYPE_AP) {
  274. if (aniState->firstepLevel < HAL_FIRST_STEP_MAX) {
  275. ath9k_hw_ani_control(ah, ATH9K_ANI_FIRSTEP_LEVEL,
  276. aniState->firstepLevel + 1);
  277. }
  278. return;
  279. }
  280. rssi = BEACON_RSSI(ah);
  281. if (rssi > aniState->rssiThrLow) {
  282. if (aniState->firstepLevel < HAL_FIRST_STEP_MAX)
  283. ath9k_hw_ani_control(ah, ATH9K_ANI_FIRSTEP_LEVEL,
  284. aniState->firstepLevel + 1);
  285. } else {
  286. if ((conf->channel->band == IEEE80211_BAND_2GHZ) &&
  287. !conf_is_ht(conf)) {
  288. if (aniState->firstepLevel > 0)
  289. ath9k_hw_ani_control(ah,
  290. ATH9K_ANI_FIRSTEP_LEVEL, 0);
  291. }
  292. }
  293. }
  294. /* Adjust the OFDM Noise Immunity Level */
  295. static void ath9k_hw_set_ofdm_nil(struct ath_hw *ah, u8 immunityLevel)
  296. {
  297. struct ar5416AniState *aniState = ah->curani;
  298. struct ath_common *common = ath9k_hw_common(ah);
  299. const struct ani_ofdm_level_entry *entry_ofdm;
  300. const struct ani_cck_level_entry *entry_cck;
  301. aniState->noiseFloor = BEACON_RSSI(ah);
  302. ath_print(common, ATH_DBG_ANI,
  303. "**** ofdmlevel %d=>%d, rssi=%d[lo=%d hi=%d]\n",
  304. aniState->ofdmNoiseImmunityLevel,
  305. immunityLevel, aniState->noiseFloor,
  306. aniState->rssiThrLow, aniState->rssiThrHigh);
  307. aniState->ofdmNoiseImmunityLevel = immunityLevel;
  308. entry_ofdm = &ofdm_level_table[aniState->ofdmNoiseImmunityLevel];
  309. entry_cck = &cck_level_table[aniState->cckNoiseImmunityLevel];
  310. if (aniState->spurImmunityLevel != entry_ofdm->spur_immunity_level)
  311. ath9k_hw_ani_control(ah,
  312. ATH9K_ANI_SPUR_IMMUNITY_LEVEL,
  313. entry_ofdm->spur_immunity_level);
  314. if (aniState->firstepLevel != entry_ofdm->fir_step_level &&
  315. entry_ofdm->fir_step_level >= entry_cck->fir_step_level)
  316. ath9k_hw_ani_control(ah,
  317. ATH9K_ANI_FIRSTEP_LEVEL,
  318. entry_ofdm->fir_step_level);
  319. if ((ah->opmode != NL80211_IFTYPE_STATION &&
  320. ah->opmode != NL80211_IFTYPE_ADHOC) ||
  321. aniState->noiseFloor <= aniState->rssiThrHigh) {
  322. if (aniState->ofdmWeakSigDetectOff)
  323. /* force on ofdm weak sig detect */
  324. ath9k_hw_ani_control(ah,
  325. ATH9K_ANI_OFDM_WEAK_SIGNAL_DETECTION,
  326. true);
  327. else if (aniState->ofdmWeakSigDetectOff ==
  328. entry_ofdm->ofdm_weak_signal_on)
  329. ath9k_hw_ani_control(ah,
  330. ATH9K_ANI_OFDM_WEAK_SIGNAL_DETECTION,
  331. entry_ofdm->ofdm_weak_signal_on);
  332. }
  333. }
  334. static void ath9k_hw_ani_ofdm_err_trigger_new(struct ath_hw *ah)
  335. {
  336. struct ar5416AniState *aniState;
  337. if (!DO_ANI(ah))
  338. return;
  339. aniState = ah->curani;
  340. if (aniState->ofdmNoiseImmunityLevel < ATH9K_ANI_OFDM_MAX_LEVEL)
  341. ath9k_hw_set_ofdm_nil(ah, aniState->ofdmNoiseImmunityLevel + 1);
  342. }
  343. /*
  344. * Set the ANI settings to match an CCK level.
  345. */
  346. static void ath9k_hw_set_cck_nil(struct ath_hw *ah, u_int8_t immunityLevel)
  347. {
  348. struct ar5416AniState *aniState = ah->curani;
  349. struct ath_common *common = ath9k_hw_common(ah);
  350. const struct ani_ofdm_level_entry *entry_ofdm;
  351. const struct ani_cck_level_entry *entry_cck;
  352. aniState->noiseFloor = BEACON_RSSI(ah);
  353. ath_print(common, ATH_DBG_ANI,
  354. "**** ccklevel %d=>%d, rssi=%d[lo=%d hi=%d]\n",
  355. aniState->cckNoiseImmunityLevel, immunityLevel,
  356. aniState->noiseFloor, aniState->rssiThrLow,
  357. aniState->rssiThrHigh);
  358. if ((ah->opmode == NL80211_IFTYPE_STATION ||
  359. ah->opmode == NL80211_IFTYPE_ADHOC) &&
  360. aniState->noiseFloor <= aniState->rssiThrLow &&
  361. immunityLevel > ATH9K_ANI_CCK_MAX_LEVEL_LOW_RSSI)
  362. immunityLevel = ATH9K_ANI_CCK_MAX_LEVEL_LOW_RSSI;
  363. aniState->cckNoiseImmunityLevel = immunityLevel;
  364. entry_ofdm = &ofdm_level_table[aniState->ofdmNoiseImmunityLevel];
  365. entry_cck = &cck_level_table[aniState->cckNoiseImmunityLevel];
  366. if (aniState->firstepLevel != entry_cck->fir_step_level &&
  367. entry_cck->fir_step_level >= entry_ofdm->fir_step_level)
  368. ath9k_hw_ani_control(ah,
  369. ATH9K_ANI_FIRSTEP_LEVEL,
  370. entry_cck->fir_step_level);
  371. /* Skip MRC CCK for pre AR9003 families */
  372. if (!AR_SREV_9300_20_OR_LATER(ah))
  373. return;
  374. if (aniState->mrcCCKOff == entry_cck->mrc_cck_on)
  375. ath9k_hw_ani_control(ah,
  376. ATH9K_ANI_MRC_CCK,
  377. entry_cck->mrc_cck_on);
  378. }
  379. static void ath9k_hw_ani_cck_err_trigger_new(struct ath_hw *ah)
  380. {
  381. struct ar5416AniState *aniState;
  382. if (!DO_ANI(ah))
  383. return;
  384. aniState = ah->curani;
  385. if (aniState->cckNoiseImmunityLevel < ATH9K_ANI_CCK_MAX_LEVEL)
  386. ath9k_hw_set_cck_nil(ah, aniState->cckNoiseImmunityLevel + 1);
  387. }
  388. static void ath9k_hw_ani_lower_immunity_old(struct ath_hw *ah)
  389. {
  390. struct ar5416AniState *aniState;
  391. int32_t rssi;
  392. aniState = ah->curani;
  393. if (ah->opmode == NL80211_IFTYPE_AP) {
  394. if (aniState->firstepLevel > 0) {
  395. if (ath9k_hw_ani_control(ah, ATH9K_ANI_FIRSTEP_LEVEL,
  396. aniState->firstepLevel - 1))
  397. return;
  398. }
  399. } else {
  400. rssi = BEACON_RSSI(ah);
  401. if (rssi > aniState->rssiThrHigh) {
  402. /* XXX: Handle me */
  403. } else if (rssi > aniState->rssiThrLow) {
  404. if (aniState->ofdmWeakSigDetectOff) {
  405. if (ath9k_hw_ani_control(ah,
  406. ATH9K_ANI_OFDM_WEAK_SIGNAL_DETECTION,
  407. true) == true)
  408. return;
  409. }
  410. if (aniState->firstepLevel > 0) {
  411. if (ath9k_hw_ani_control(ah,
  412. ATH9K_ANI_FIRSTEP_LEVEL,
  413. aniState->firstepLevel - 1) == true)
  414. return;
  415. }
  416. } else {
  417. if (aniState->firstepLevel > 0) {
  418. if (ath9k_hw_ani_control(ah,
  419. ATH9K_ANI_FIRSTEP_LEVEL,
  420. aniState->firstepLevel - 1) == true)
  421. return;
  422. }
  423. }
  424. }
  425. if (aniState->spurImmunityLevel > 0) {
  426. if (ath9k_hw_ani_control(ah, ATH9K_ANI_SPUR_IMMUNITY_LEVEL,
  427. aniState->spurImmunityLevel - 1))
  428. return;
  429. }
  430. if (aniState->noiseImmunityLevel > 0) {
  431. ath9k_hw_ani_control(ah, ATH9K_ANI_NOISE_IMMUNITY_LEVEL,
  432. aniState->noiseImmunityLevel - 1);
  433. return;
  434. }
  435. }
  436. /*
  437. * only lower either OFDM or CCK errors per turn
  438. * we lower the other one next time
  439. */
  440. static void ath9k_hw_ani_lower_immunity_new(struct ath_hw *ah)
  441. {
  442. struct ar5416AniState *aniState;
  443. aniState = ah->curani;
  444. /* lower OFDM noise immunity */
  445. if (aniState->ofdmNoiseImmunityLevel > 0 &&
  446. (aniState->ofdmsTurn || aniState->cckNoiseImmunityLevel == 0)) {
  447. ath9k_hw_set_ofdm_nil(ah, aniState->ofdmNoiseImmunityLevel - 1);
  448. return;
  449. }
  450. /* lower CCK noise immunity */
  451. if (aniState->cckNoiseImmunityLevel > 0)
  452. ath9k_hw_set_cck_nil(ah, aniState->cckNoiseImmunityLevel - 1);
  453. }
  454. static u8 ath9k_hw_chan_2_clockrate_mhz(struct ath_hw *ah)
  455. {
  456. struct ath9k_channel *chan = ah->curchan;
  457. struct ieee80211_conf *conf = &ath9k_hw_common(ah)->hw->conf;
  458. u8 clockrate; /* in MHz */
  459. if (!ah->curchan) /* should really check for CCK instead */
  460. clockrate = ATH9K_CLOCK_RATE_CCK;
  461. else if (conf->channel->band == IEEE80211_BAND_2GHZ)
  462. clockrate = ATH9K_CLOCK_RATE_2GHZ_OFDM;
  463. else if (IS_CHAN_A_FAST_CLOCK(ah, chan))
  464. clockrate = ATH9K_CLOCK_FAST_RATE_5GHZ_OFDM;
  465. else
  466. clockrate = ATH9K_CLOCK_RATE_5GHZ_OFDM;
  467. if (conf_is_ht40(conf))
  468. return clockrate * 2;
  469. return clockrate;
  470. }
  471. static int32_t ath9k_hw_ani_get_listen_time(struct ath_hw *ah)
  472. {
  473. int32_t listen_time;
  474. int32_t clock_rate;
  475. ath9k_hw_update_cycle_counters(ah);
  476. clock_rate = ath9k_hw_chan_2_clockrate_mhz(ah) * 1000;
  477. listen_time = ah->listen_time / clock_rate;
  478. ah->listen_time = 0;
  479. return listen_time;
  480. }
  481. static void ath9k_ani_reset_old(struct ath_hw *ah, bool is_scanning)
  482. {
  483. struct ar5416AniState *aniState;
  484. struct ath9k_channel *chan = ah->curchan;
  485. struct ath_common *common = ath9k_hw_common(ah);
  486. int index;
  487. if (!DO_ANI(ah))
  488. return;
  489. index = ath9k_hw_get_ani_channel_idx(ah, chan);
  490. aniState = &ah->ani[index];
  491. ah->curani = aniState;
  492. if (DO_ANI(ah) && ah->opmode != NL80211_IFTYPE_STATION
  493. && ah->opmode != NL80211_IFTYPE_ADHOC) {
  494. ath_print(common, ATH_DBG_ANI,
  495. "Reset ANI state opmode %u\n", ah->opmode);
  496. ah->stats.ast_ani_reset++;
  497. if (ah->opmode == NL80211_IFTYPE_AP) {
  498. /*
  499. * ath9k_hw_ani_control() will only process items set on
  500. * ah->ani_function
  501. */
  502. if (IS_CHAN_2GHZ(chan))
  503. ah->ani_function = (ATH9K_ANI_SPUR_IMMUNITY_LEVEL |
  504. ATH9K_ANI_FIRSTEP_LEVEL);
  505. else
  506. ah->ani_function = 0;
  507. }
  508. ath9k_hw_ani_control(ah, ATH9K_ANI_NOISE_IMMUNITY_LEVEL, 0);
  509. ath9k_hw_ani_control(ah, ATH9K_ANI_SPUR_IMMUNITY_LEVEL, 0);
  510. ath9k_hw_ani_control(ah, ATH9K_ANI_FIRSTEP_LEVEL, 0);
  511. ath9k_hw_ani_control(ah, ATH9K_ANI_OFDM_WEAK_SIGNAL_DETECTION,
  512. !ATH9K_ANI_USE_OFDM_WEAK_SIG);
  513. ath9k_hw_ani_control(ah, ATH9K_ANI_CCK_WEAK_SIGNAL_THR,
  514. ATH9K_ANI_CCK_WEAK_SIG_THR);
  515. ath9k_hw_setrxfilter(ah, ath9k_hw_getrxfilter(ah) |
  516. ATH9K_RX_FILTER_PHYERR);
  517. if (ah->opmode == NL80211_IFTYPE_AP) {
  518. ah->curani->ofdmTrigHigh =
  519. ah->config.ofdm_trig_high;
  520. ah->curani->ofdmTrigLow =
  521. ah->config.ofdm_trig_low;
  522. ah->curani->cckTrigHigh =
  523. ah->config.cck_trig_high;
  524. ah->curani->cckTrigLow =
  525. ah->config.cck_trig_low;
  526. }
  527. ath9k_ani_restart_old(ah);
  528. return;
  529. }
  530. if (aniState->noiseImmunityLevel != 0)
  531. ath9k_hw_ani_control(ah, ATH9K_ANI_NOISE_IMMUNITY_LEVEL,
  532. aniState->noiseImmunityLevel);
  533. if (aniState->spurImmunityLevel != 0)
  534. ath9k_hw_ani_control(ah, ATH9K_ANI_SPUR_IMMUNITY_LEVEL,
  535. aniState->spurImmunityLevel);
  536. if (aniState->ofdmWeakSigDetectOff)
  537. ath9k_hw_ani_control(ah, ATH9K_ANI_OFDM_WEAK_SIGNAL_DETECTION,
  538. !aniState->ofdmWeakSigDetectOff);
  539. if (aniState->cckWeakSigThreshold)
  540. ath9k_hw_ani_control(ah, ATH9K_ANI_CCK_WEAK_SIGNAL_THR,
  541. aniState->cckWeakSigThreshold);
  542. if (aniState->firstepLevel != 0)
  543. ath9k_hw_ani_control(ah, ATH9K_ANI_FIRSTEP_LEVEL,
  544. aniState->firstepLevel);
  545. ath9k_hw_setrxfilter(ah, ath9k_hw_getrxfilter(ah) &
  546. ~ATH9K_RX_FILTER_PHYERR);
  547. ath9k_ani_restart_old(ah);
  548. ENABLE_REGWRITE_BUFFER(ah);
  549. REG_WRITE(ah, AR_PHY_ERR_MASK_1, AR_PHY_ERR_OFDM_TIMING);
  550. REG_WRITE(ah, AR_PHY_ERR_MASK_2, AR_PHY_ERR_CCK_TIMING);
  551. REGWRITE_BUFFER_FLUSH(ah);
  552. }
  553. /*
  554. * Restore the ANI parameters in the HAL and reset the statistics.
  555. * This routine should be called for every hardware reset and for
  556. * every channel change.
  557. */
  558. static void ath9k_ani_reset_new(struct ath_hw *ah, bool is_scanning)
  559. {
  560. struct ar5416AniState *aniState = ah->curani;
  561. struct ath9k_channel *chan = ah->curchan;
  562. struct ath_common *common = ath9k_hw_common(ah);
  563. if (!DO_ANI(ah))
  564. return;
  565. BUG_ON(aniState == NULL);
  566. ah->stats.ast_ani_reset++;
  567. /* only allow a subset of functions in AP mode */
  568. if (ah->opmode == NL80211_IFTYPE_AP) {
  569. if (IS_CHAN_2GHZ(chan)) {
  570. ah->ani_function = (ATH9K_ANI_SPUR_IMMUNITY_LEVEL |
  571. ATH9K_ANI_FIRSTEP_LEVEL);
  572. if (AR_SREV_9300_20_OR_LATER(ah))
  573. ah->ani_function |= ATH9K_ANI_MRC_CCK;
  574. } else
  575. ah->ani_function = 0;
  576. }
  577. /* always allow mode (on/off) to be controlled */
  578. ah->ani_function |= ATH9K_ANI_MODE;
  579. if (is_scanning ||
  580. (ah->opmode != NL80211_IFTYPE_STATION &&
  581. ah->opmode != NL80211_IFTYPE_ADHOC)) {
  582. /*
  583. * If we're scanning or in AP mode, the defaults (ini)
  584. * should be in place. For an AP we assume the historical
  585. * levels for this channel are probably outdated so start
  586. * from defaults instead.
  587. */
  588. if (aniState->ofdmNoiseImmunityLevel !=
  589. ATH9K_ANI_OFDM_DEF_LEVEL ||
  590. aniState->cckNoiseImmunityLevel !=
  591. ATH9K_ANI_CCK_DEF_LEVEL) {
  592. ath_print(common, ATH_DBG_ANI,
  593. "Restore defaults: opmode %u "
  594. "chan %d Mhz/0x%x is_scanning=%d "
  595. "ofdm:%d cck:%d\n",
  596. ah->opmode,
  597. chan->channel,
  598. chan->channelFlags,
  599. is_scanning,
  600. aniState->ofdmNoiseImmunityLevel,
  601. aniState->cckNoiseImmunityLevel);
  602. ath9k_hw_set_ofdm_nil(ah, ATH9K_ANI_OFDM_DEF_LEVEL);
  603. ath9k_hw_set_cck_nil(ah, ATH9K_ANI_CCK_DEF_LEVEL);
  604. }
  605. } else {
  606. /*
  607. * restore historical levels for this channel
  608. */
  609. ath_print(common, ATH_DBG_ANI,
  610. "Restore history: opmode %u "
  611. "chan %d Mhz/0x%x is_scanning=%d "
  612. "ofdm:%d cck:%d\n",
  613. ah->opmode,
  614. chan->channel,
  615. chan->channelFlags,
  616. is_scanning,
  617. aniState->ofdmNoiseImmunityLevel,
  618. aniState->cckNoiseImmunityLevel);
  619. ath9k_hw_set_ofdm_nil(ah,
  620. aniState->ofdmNoiseImmunityLevel);
  621. ath9k_hw_set_cck_nil(ah,
  622. aniState->cckNoiseImmunityLevel);
  623. }
  624. /*
  625. * enable phy counters if hw supports or if not, enable phy
  626. * interrupts (so we can count each one)
  627. */
  628. ath9k_ani_restart_new(ah);
  629. ENABLE_REGWRITE_BUFFER(ah);
  630. REG_WRITE(ah, AR_PHY_ERR_MASK_1, AR_PHY_ERR_OFDM_TIMING);
  631. REG_WRITE(ah, AR_PHY_ERR_MASK_2, AR_PHY_ERR_CCK_TIMING);
  632. REGWRITE_BUFFER_FLUSH(ah);
  633. }
  634. static void ath9k_hw_ani_monitor_old(struct ath_hw *ah,
  635. struct ath9k_channel *chan)
  636. {
  637. struct ar5416AniState *aniState;
  638. struct ath_common *common = ath9k_hw_common(ah);
  639. int32_t listenTime;
  640. u32 phyCnt1, phyCnt2;
  641. u32 ofdmPhyErrCnt, cckPhyErrCnt;
  642. if (!DO_ANI(ah))
  643. return;
  644. aniState = ah->curani;
  645. listenTime = ath9k_hw_ani_get_listen_time(ah);
  646. if (listenTime < 0) {
  647. ah->stats.ast_ani_lneg++;
  648. ath9k_ani_restart_old(ah);
  649. return;
  650. }
  651. aniState->listenTime += listenTime;
  652. ath9k_hw_update_mibstats(ah, &ah->ah_mibStats);
  653. phyCnt1 = REG_READ(ah, AR_PHY_ERR_1);
  654. phyCnt2 = REG_READ(ah, AR_PHY_ERR_2);
  655. if (phyCnt1 < aniState->ofdmPhyErrBase ||
  656. phyCnt2 < aniState->cckPhyErrBase) {
  657. if (phyCnt1 < aniState->ofdmPhyErrBase) {
  658. ath_print(common, ATH_DBG_ANI,
  659. "phyCnt1 0x%x, resetting "
  660. "counter value to 0x%x\n",
  661. phyCnt1,
  662. aniState->ofdmPhyErrBase);
  663. REG_WRITE(ah, AR_PHY_ERR_1,
  664. aniState->ofdmPhyErrBase);
  665. REG_WRITE(ah, AR_PHY_ERR_MASK_1,
  666. AR_PHY_ERR_OFDM_TIMING);
  667. }
  668. if (phyCnt2 < aniState->cckPhyErrBase) {
  669. ath_print(common, ATH_DBG_ANI,
  670. "phyCnt2 0x%x, resetting "
  671. "counter value to 0x%x\n",
  672. phyCnt2,
  673. aniState->cckPhyErrBase);
  674. REG_WRITE(ah, AR_PHY_ERR_2,
  675. aniState->cckPhyErrBase);
  676. REG_WRITE(ah, AR_PHY_ERR_MASK_2,
  677. AR_PHY_ERR_CCK_TIMING);
  678. }
  679. return;
  680. }
  681. ofdmPhyErrCnt = phyCnt1 - aniState->ofdmPhyErrBase;
  682. ah->stats.ast_ani_ofdmerrs +=
  683. ofdmPhyErrCnt - aniState->ofdmPhyErrCount;
  684. aniState->ofdmPhyErrCount = ofdmPhyErrCnt;
  685. cckPhyErrCnt = phyCnt2 - aniState->cckPhyErrBase;
  686. ah->stats.ast_ani_cckerrs +=
  687. cckPhyErrCnt - aniState->cckPhyErrCount;
  688. aniState->cckPhyErrCount = cckPhyErrCnt;
  689. if (aniState->listenTime > 5 * ah->aniperiod) {
  690. if (aniState->ofdmPhyErrCount <= aniState->listenTime *
  691. aniState->ofdmTrigLow / 1000 &&
  692. aniState->cckPhyErrCount <= aniState->listenTime *
  693. aniState->cckTrigLow / 1000)
  694. ath9k_hw_ani_lower_immunity(ah);
  695. ath9k_ani_restart_old(ah);
  696. } else if (aniState->listenTime > ah->aniperiod) {
  697. if (aniState->ofdmPhyErrCount > aniState->listenTime *
  698. aniState->ofdmTrigHigh / 1000) {
  699. ath9k_hw_ani_ofdm_err_trigger_old(ah);
  700. ath9k_ani_restart_old(ah);
  701. } else if (aniState->cckPhyErrCount >
  702. aniState->listenTime * aniState->cckTrigHigh /
  703. 1000) {
  704. ath9k_hw_ani_cck_err_trigger_old(ah);
  705. ath9k_ani_restart_old(ah);
  706. }
  707. }
  708. }
  709. static void ath9k_hw_ani_monitor_new(struct ath_hw *ah,
  710. struct ath9k_channel *chan)
  711. {
  712. struct ar5416AniState *aniState;
  713. struct ath_common *common = ath9k_hw_common(ah);
  714. int32_t listenTime;
  715. u32 phyCnt1, phyCnt2;
  716. u32 ofdmPhyErrCnt, cckPhyErrCnt;
  717. u32 ofdmPhyErrRate, cckPhyErrRate;
  718. if (!DO_ANI(ah))
  719. return;
  720. aniState = ah->curani;
  721. if (WARN_ON(!aniState))
  722. return;
  723. listenTime = ath9k_hw_ani_get_listen_time(ah);
  724. if (listenTime <= 0) {
  725. ah->stats.ast_ani_lneg++;
  726. /* restart ANI period if listenTime is invalid */
  727. ath_print(common, ATH_DBG_ANI,
  728. "listenTime=%d - on new ani monitor\n",
  729. listenTime);
  730. ath9k_ani_restart_new(ah);
  731. return;
  732. }
  733. aniState->listenTime += listenTime;
  734. ath9k_hw_update_mibstats(ah, &ah->ah_mibStats);
  735. phyCnt1 = REG_READ(ah, AR_PHY_ERR_1);
  736. phyCnt2 = REG_READ(ah, AR_PHY_ERR_2);
  737. if (phyCnt1 < aniState->ofdmPhyErrBase ||
  738. phyCnt2 < aniState->cckPhyErrBase) {
  739. if (phyCnt1 < aniState->ofdmPhyErrBase) {
  740. ath_print(common, ATH_DBG_ANI,
  741. "phyCnt1 0x%x, resetting "
  742. "counter value to 0x%x\n",
  743. phyCnt1,
  744. aniState->ofdmPhyErrBase);
  745. REG_WRITE(ah, AR_PHY_ERR_1,
  746. aniState->ofdmPhyErrBase);
  747. REG_WRITE(ah, AR_PHY_ERR_MASK_1,
  748. AR_PHY_ERR_OFDM_TIMING);
  749. }
  750. if (phyCnt2 < aniState->cckPhyErrBase) {
  751. ath_print(common, ATH_DBG_ANI,
  752. "phyCnt2 0x%x, resetting "
  753. "counter value to 0x%x\n",
  754. phyCnt2,
  755. aniState->cckPhyErrBase);
  756. REG_WRITE(ah, AR_PHY_ERR_2,
  757. aniState->cckPhyErrBase);
  758. REG_WRITE(ah, AR_PHY_ERR_MASK_2,
  759. AR_PHY_ERR_CCK_TIMING);
  760. }
  761. return;
  762. }
  763. ofdmPhyErrCnt = phyCnt1 - aniState->ofdmPhyErrBase;
  764. ah->stats.ast_ani_ofdmerrs +=
  765. ofdmPhyErrCnt - aniState->ofdmPhyErrCount;
  766. aniState->ofdmPhyErrCount = ofdmPhyErrCnt;
  767. cckPhyErrCnt = phyCnt2 - aniState->cckPhyErrBase;
  768. ah->stats.ast_ani_cckerrs +=
  769. cckPhyErrCnt - aniState->cckPhyErrCount;
  770. aniState->cckPhyErrCount = cckPhyErrCnt;
  771. ath_print(common, ATH_DBG_ANI,
  772. "Errors: OFDM=0x%08x-0x%08x=%d "
  773. "CCK=0x%08x-0x%08x=%d\n",
  774. phyCnt1,
  775. aniState->ofdmPhyErrBase,
  776. ofdmPhyErrCnt,
  777. phyCnt2,
  778. aniState->cckPhyErrBase,
  779. cckPhyErrCnt);
  780. ofdmPhyErrRate = aniState->ofdmPhyErrCount * 1000 /
  781. aniState->listenTime;
  782. cckPhyErrRate = aniState->cckPhyErrCount * 1000 /
  783. aniState->listenTime;
  784. ath_print(common, ATH_DBG_ANI,
  785. "listenTime=%d OFDM:%d errs=%d/s CCK:%d "
  786. "errs=%d/s ofdm_turn=%d\n",
  787. listenTime, aniState->ofdmNoiseImmunityLevel,
  788. ofdmPhyErrRate, aniState->cckNoiseImmunityLevel,
  789. cckPhyErrRate, aniState->ofdmsTurn);
  790. if (aniState->listenTime > 5 * ah->aniperiod) {
  791. if (ofdmPhyErrRate <= aniState->ofdmTrigLow &&
  792. cckPhyErrRate <= aniState->cckTrigLow) {
  793. ath_print(common, ATH_DBG_ANI,
  794. "1. listenTime=%d OFDM:%d errs=%d/s(<%d) "
  795. "CCK:%d errs=%d/s(<%d) -> "
  796. "ath9k_hw_ani_lower_immunity()\n",
  797. aniState->listenTime,
  798. aniState->ofdmNoiseImmunityLevel,
  799. ofdmPhyErrRate,
  800. aniState->ofdmTrigLow,
  801. aniState->cckNoiseImmunityLevel,
  802. cckPhyErrRate,
  803. aniState->cckTrigLow);
  804. ath9k_hw_ani_lower_immunity(ah);
  805. aniState->ofdmsTurn = !aniState->ofdmsTurn;
  806. }
  807. ath_print(common, ATH_DBG_ANI,
  808. "1 listenTime=%d ofdm=%d/s cck=%d/s - "
  809. "calling ath9k_ani_restart_new()\n",
  810. aniState->listenTime, ofdmPhyErrRate, cckPhyErrRate);
  811. ath9k_ani_restart_new(ah);
  812. } else if (aniState->listenTime > ah->aniperiod) {
  813. /* check to see if need to raise immunity */
  814. if (ofdmPhyErrRate > aniState->ofdmTrigHigh &&
  815. (cckPhyErrRate <= aniState->cckTrigHigh ||
  816. aniState->ofdmsTurn)) {
  817. ath_print(common, ATH_DBG_ANI,
  818. "2 listenTime=%d OFDM:%d errs=%d/s(>%d) -> "
  819. "ath9k_hw_ani_ofdm_err_trigger_new()\n",
  820. aniState->listenTime,
  821. aniState->ofdmNoiseImmunityLevel,
  822. ofdmPhyErrRate,
  823. aniState->ofdmTrigHigh);
  824. ath9k_hw_ani_ofdm_err_trigger_new(ah);
  825. ath9k_ani_restart_new(ah);
  826. aniState->ofdmsTurn = false;
  827. } else if (cckPhyErrRate > aniState->cckTrigHigh) {
  828. ath_print(common, ATH_DBG_ANI,
  829. "3 listenTime=%d CCK:%d errs=%d/s(>%d) -> "
  830. "ath9k_hw_ani_cck_err_trigger_new()\n",
  831. aniState->listenTime,
  832. aniState->cckNoiseImmunityLevel,
  833. cckPhyErrRate,
  834. aniState->cckTrigHigh);
  835. ath9k_hw_ani_cck_err_trigger_new(ah);
  836. ath9k_ani_restart_new(ah);
  837. aniState->ofdmsTurn = true;
  838. }
  839. }
  840. }
  841. void ath9k_enable_mib_counters(struct ath_hw *ah)
  842. {
  843. struct ath_common *common = ath9k_hw_common(ah);
  844. ath_print(common, ATH_DBG_ANI, "Enable MIB counters\n");
  845. ath9k_hw_update_mibstats(ah, &ah->ah_mibStats);
  846. ENABLE_REGWRITE_BUFFER(ah);
  847. REG_WRITE(ah, AR_FILT_OFDM, 0);
  848. REG_WRITE(ah, AR_FILT_CCK, 0);
  849. REG_WRITE(ah, AR_MIBC,
  850. ~(AR_MIBC_COW | AR_MIBC_FMC | AR_MIBC_CMC | AR_MIBC_MCS)
  851. & 0x0f);
  852. REG_WRITE(ah, AR_PHY_ERR_MASK_1, AR_PHY_ERR_OFDM_TIMING);
  853. REG_WRITE(ah, AR_PHY_ERR_MASK_2, AR_PHY_ERR_CCK_TIMING);
  854. REGWRITE_BUFFER_FLUSH(ah);
  855. }
  856. /* Freeze the MIB counters, get the stats and then clear them */
  857. void ath9k_hw_disable_mib_counters(struct ath_hw *ah)
  858. {
  859. struct ath_common *common = ath9k_hw_common(ah);
  860. ath_print(common, ATH_DBG_ANI, "Disable MIB counters\n");
  861. REG_WRITE(ah, AR_MIBC, AR_MIBC_FMC);
  862. ath9k_hw_update_mibstats(ah, &ah->ah_mibStats);
  863. REG_WRITE(ah, AR_MIBC, AR_MIBC_CMC);
  864. REG_WRITE(ah, AR_FILT_OFDM, 0);
  865. REG_WRITE(ah, AR_FILT_CCK, 0);
  866. }
  867. EXPORT_SYMBOL(ath9k_hw_disable_mib_counters);
  868. void ath9k_hw_update_cycle_counters(struct ath_hw *ah)
  869. {
  870. struct ath_cycle_counters cc;
  871. bool clear;
  872. memcpy(&cc, &ah->cc, sizeof(cc));
  873. /* freeze counters */
  874. REG_WRITE(ah, AR_MIBC, AR_MIBC_FMC);
  875. ah->cc.cycles = REG_READ(ah, AR_CCCNT);
  876. if (ah->cc.cycles < cc.cycles) {
  877. clear = true;
  878. goto skip;
  879. }
  880. ah->cc.rx_clear = REG_READ(ah, AR_RCCNT);
  881. ah->cc.rx_frame = REG_READ(ah, AR_RFCNT);
  882. ah->cc.tx_frame = REG_READ(ah, AR_TFCNT);
  883. /* prevent wraparound */
  884. if (ah->cc.cycles & BIT(31))
  885. clear = true;
  886. #define CC_DELTA(_field, _reg) ah->cc_delta._field += ah->cc._field - cc._field
  887. CC_DELTA(cycles, AR_CCCNT);
  888. CC_DELTA(rx_frame, AR_RFCNT);
  889. CC_DELTA(rx_clear, AR_RCCNT);
  890. CC_DELTA(tx_frame, AR_TFCNT);
  891. #undef CC_DELTA
  892. ah->listen_time += (ah->cc.cycles - cc.cycles) -
  893. ((ah->cc.rx_frame - cc.rx_frame) +
  894. (ah->cc.tx_frame - cc.tx_frame));
  895. skip:
  896. if (clear) {
  897. REG_WRITE(ah, AR_CCCNT, 0);
  898. REG_WRITE(ah, AR_RFCNT, 0);
  899. REG_WRITE(ah, AR_RCCNT, 0);
  900. REG_WRITE(ah, AR_TFCNT, 0);
  901. memset(&ah->cc, 0, sizeof(ah->cc));
  902. }
  903. /* unfreeze counters */
  904. REG_WRITE(ah, AR_MIBC, 0);
  905. }
  906. /*
  907. * Process a MIB interrupt. We may potentially be invoked because
  908. * any of the MIB counters overflow/trigger so don't assume we're
  909. * here because a PHY error counter triggered.
  910. */
  911. static void ath9k_hw_proc_mib_event_old(struct ath_hw *ah)
  912. {
  913. u32 phyCnt1, phyCnt2;
  914. /* Reset these counters regardless */
  915. REG_WRITE(ah, AR_FILT_OFDM, 0);
  916. REG_WRITE(ah, AR_FILT_CCK, 0);
  917. if (!(REG_READ(ah, AR_SLP_MIB_CTRL) & AR_SLP_MIB_PENDING))
  918. REG_WRITE(ah, AR_SLP_MIB_CTRL, AR_SLP_MIB_CLEAR);
  919. /* Clear the mib counters and save them in the stats */
  920. ath9k_hw_update_mibstats(ah, &ah->ah_mibStats);
  921. if (!DO_ANI(ah)) {
  922. /*
  923. * We must always clear the interrupt cause by
  924. * resetting the phy error regs.
  925. */
  926. REG_WRITE(ah, AR_PHY_ERR_1, 0);
  927. REG_WRITE(ah, AR_PHY_ERR_2, 0);
  928. return;
  929. }
  930. /* NB: these are not reset-on-read */
  931. phyCnt1 = REG_READ(ah, AR_PHY_ERR_1);
  932. phyCnt2 = REG_READ(ah, AR_PHY_ERR_2);
  933. if (((phyCnt1 & AR_MIBCNT_INTRMASK) == AR_MIBCNT_INTRMASK) ||
  934. ((phyCnt2 & AR_MIBCNT_INTRMASK) == AR_MIBCNT_INTRMASK)) {
  935. struct ar5416AniState *aniState = ah->curani;
  936. u32 ofdmPhyErrCnt, cckPhyErrCnt;
  937. /* NB: only use ast_ani_*errs with AH_PRIVATE_DIAG */
  938. ofdmPhyErrCnt = phyCnt1 - aniState->ofdmPhyErrBase;
  939. ah->stats.ast_ani_ofdmerrs +=
  940. ofdmPhyErrCnt - aniState->ofdmPhyErrCount;
  941. aniState->ofdmPhyErrCount = ofdmPhyErrCnt;
  942. cckPhyErrCnt = phyCnt2 - aniState->cckPhyErrBase;
  943. ah->stats.ast_ani_cckerrs +=
  944. cckPhyErrCnt - aniState->cckPhyErrCount;
  945. aniState->cckPhyErrCount = cckPhyErrCnt;
  946. /*
  947. * NB: figure out which counter triggered. If both
  948. * trigger we'll only deal with one as the processing
  949. * clobbers the error counter so the trigger threshold
  950. * check will never be true.
  951. */
  952. if (aniState->ofdmPhyErrCount > aniState->ofdmTrigHigh)
  953. ath9k_hw_ani_ofdm_err_trigger_new(ah);
  954. if (aniState->cckPhyErrCount > aniState->cckTrigHigh)
  955. ath9k_hw_ani_cck_err_trigger_old(ah);
  956. /* NB: always restart to insure the h/w counters are reset */
  957. ath9k_ani_restart_old(ah);
  958. }
  959. }
  960. /*
  961. * Process a MIB interrupt. We may potentially be invoked because
  962. * any of the MIB counters overflow/trigger so don't assume we're
  963. * here because a PHY error counter triggered.
  964. */
  965. static void ath9k_hw_proc_mib_event_new(struct ath_hw *ah)
  966. {
  967. u32 phyCnt1, phyCnt2;
  968. /* Reset these counters regardless */
  969. REG_WRITE(ah, AR_FILT_OFDM, 0);
  970. REG_WRITE(ah, AR_FILT_CCK, 0);
  971. if (!(REG_READ(ah, AR_SLP_MIB_CTRL) & AR_SLP_MIB_PENDING))
  972. REG_WRITE(ah, AR_SLP_MIB_CTRL, AR_SLP_MIB_CLEAR);
  973. /* Clear the mib counters and save them in the stats */
  974. ath9k_hw_update_mibstats(ah, &ah->ah_mibStats);
  975. if (!DO_ANI(ah)) {
  976. /*
  977. * We must always clear the interrupt cause by
  978. * resetting the phy error regs.
  979. */
  980. REG_WRITE(ah, AR_PHY_ERR_1, 0);
  981. REG_WRITE(ah, AR_PHY_ERR_2, 0);
  982. return;
  983. }
  984. /* NB: these are not reset-on-read */
  985. phyCnt1 = REG_READ(ah, AR_PHY_ERR_1);
  986. phyCnt2 = REG_READ(ah, AR_PHY_ERR_2);
  987. /* NB: always restart to insure the h/w counters are reset */
  988. if (((phyCnt1 & AR_MIBCNT_INTRMASK) == AR_MIBCNT_INTRMASK) ||
  989. ((phyCnt2 & AR_MIBCNT_INTRMASK) == AR_MIBCNT_INTRMASK))
  990. ath9k_ani_restart_new(ah);
  991. }
  992. void ath9k_hw_ani_setup(struct ath_hw *ah)
  993. {
  994. int i;
  995. const int totalSizeDesired[] = { -55, -55, -55, -55, -62 };
  996. const int coarseHigh[] = { -14, -14, -14, -14, -12 };
  997. const int coarseLow[] = { -64, -64, -64, -64, -70 };
  998. const int firpwr[] = { -78, -78, -78, -78, -80 };
  999. for (i = 0; i < 5; i++) {
  1000. ah->totalSizeDesired[i] = totalSizeDesired[i];
  1001. ah->coarse_high[i] = coarseHigh[i];
  1002. ah->coarse_low[i] = coarseLow[i];
  1003. ah->firpwr[i] = firpwr[i];
  1004. }
  1005. }
  1006. void ath9k_hw_ani_init(struct ath_hw *ah)
  1007. {
  1008. struct ath_common *common = ath9k_hw_common(ah);
  1009. int i;
  1010. ath_print(common, ATH_DBG_ANI, "Initialize ANI\n");
  1011. memset(ah->ani, 0, sizeof(ah->ani));
  1012. for (i = 0; i < ARRAY_SIZE(ah->ani); i++) {
  1013. if (use_new_ani(ah)) {
  1014. ah->ani[i].ofdmTrigHigh = ATH9K_ANI_OFDM_TRIG_HIGH_NEW;
  1015. ah->ani[i].ofdmTrigLow = ATH9K_ANI_OFDM_TRIG_LOW_NEW;
  1016. ah->ani[i].cckTrigHigh = ATH9K_ANI_CCK_TRIG_HIGH_NEW;
  1017. ah->ani[i].cckTrigLow = ATH9K_ANI_CCK_TRIG_LOW_NEW;
  1018. ah->ani[i].spurImmunityLevel =
  1019. ATH9K_ANI_SPUR_IMMUNE_LVL_NEW;
  1020. ah->ani[i].firstepLevel = ATH9K_ANI_FIRSTEP_LVL_NEW;
  1021. ah->ani[i].ofdmPhyErrBase = 0;
  1022. ah->ani[i].cckPhyErrBase = 0;
  1023. if (AR_SREV_9300_20_OR_LATER(ah))
  1024. ah->ani[i].mrcCCKOff =
  1025. !ATH9K_ANI_ENABLE_MRC_CCK;
  1026. else
  1027. ah->ani[i].mrcCCKOff = true;
  1028. ah->ani[i].ofdmsTurn = true;
  1029. } else {
  1030. ah->ani[i].ofdmTrigHigh = ATH9K_ANI_OFDM_TRIG_HIGH_OLD;
  1031. ah->ani[i].ofdmTrigLow = ATH9K_ANI_OFDM_TRIG_LOW_OLD;
  1032. ah->ani[i].cckTrigHigh = ATH9K_ANI_CCK_TRIG_HIGH_OLD;
  1033. ah->ani[i].cckTrigLow = ATH9K_ANI_CCK_TRIG_LOW_OLD;
  1034. ah->ani[i].spurImmunityLevel =
  1035. ATH9K_ANI_SPUR_IMMUNE_LVL_OLD;
  1036. ah->ani[i].firstepLevel = ATH9K_ANI_FIRSTEP_LVL_OLD;
  1037. ah->ani[i].ofdmPhyErrBase =
  1038. AR_PHY_COUNTMAX - ATH9K_ANI_OFDM_TRIG_HIGH_OLD;
  1039. ah->ani[i].cckPhyErrBase =
  1040. AR_PHY_COUNTMAX - ATH9K_ANI_CCK_TRIG_HIGH_OLD;
  1041. ah->ani[i].cckWeakSigThreshold =
  1042. ATH9K_ANI_CCK_WEAK_SIG_THR;
  1043. }
  1044. ah->ani[i].rssiThrHigh = ATH9K_ANI_RSSI_THR_HIGH;
  1045. ah->ani[i].rssiThrLow = ATH9K_ANI_RSSI_THR_LOW;
  1046. ah->ani[i].ofdmWeakSigDetectOff =
  1047. !ATH9K_ANI_USE_OFDM_WEAK_SIG;
  1048. ah->ani[i].cckNoiseImmunityLevel = ATH9K_ANI_CCK_DEF_LEVEL;
  1049. }
  1050. /*
  1051. * since we expect some ongoing maintenance on the tables, let's sanity
  1052. * check here default level should not modify INI setting.
  1053. */
  1054. if (use_new_ani(ah)) {
  1055. const struct ani_ofdm_level_entry *entry_ofdm;
  1056. const struct ani_cck_level_entry *entry_cck;
  1057. entry_ofdm = &ofdm_level_table[ATH9K_ANI_OFDM_DEF_LEVEL];
  1058. entry_cck = &cck_level_table[ATH9K_ANI_CCK_DEF_LEVEL];
  1059. ah->aniperiod = ATH9K_ANI_PERIOD_NEW;
  1060. ah->config.ani_poll_interval = ATH9K_ANI_POLLINTERVAL_NEW;
  1061. } else {
  1062. ah->aniperiod = ATH9K_ANI_PERIOD_OLD;
  1063. ah->config.ani_poll_interval = ATH9K_ANI_POLLINTERVAL_OLD;
  1064. }
  1065. ath_print(common, ATH_DBG_ANI,
  1066. "Setting OfdmErrBase = 0x%08x\n",
  1067. ah->ani[0].ofdmPhyErrBase);
  1068. ath_print(common, ATH_DBG_ANI, "Setting cckErrBase = 0x%08x\n",
  1069. ah->ani[0].cckPhyErrBase);
  1070. ENABLE_REGWRITE_BUFFER(ah);
  1071. REG_WRITE(ah, AR_PHY_ERR_1, ah->ani[0].ofdmPhyErrBase);
  1072. REG_WRITE(ah, AR_PHY_ERR_2, ah->ani[0].cckPhyErrBase);
  1073. REGWRITE_BUFFER_FLUSH(ah);
  1074. ath9k_enable_mib_counters(ah);
  1075. if (ah->config.enable_ani)
  1076. ah->proc_phyerr |= HAL_PROCESS_ANI;
  1077. }
  1078. void ath9k_hw_attach_ani_ops_old(struct ath_hw *ah)
  1079. {
  1080. struct ath_hw_private_ops *priv_ops = ath9k_hw_private_ops(ah);
  1081. struct ath_hw_ops *ops = ath9k_hw_ops(ah);
  1082. priv_ops->ani_reset = ath9k_ani_reset_old;
  1083. priv_ops->ani_lower_immunity = ath9k_hw_ani_lower_immunity_old;
  1084. ops->ani_proc_mib_event = ath9k_hw_proc_mib_event_old;
  1085. ops->ani_monitor = ath9k_hw_ani_monitor_old;
  1086. ath_print(ath9k_hw_common(ah), ATH_DBG_ANY, "Using ANI v1\n");
  1087. }
  1088. void ath9k_hw_attach_ani_ops_new(struct ath_hw *ah)
  1089. {
  1090. struct ath_hw_private_ops *priv_ops = ath9k_hw_private_ops(ah);
  1091. struct ath_hw_ops *ops = ath9k_hw_ops(ah);
  1092. priv_ops->ani_reset = ath9k_ani_reset_new;
  1093. priv_ops->ani_lower_immunity = ath9k_hw_ani_lower_immunity_new;
  1094. ops->ani_proc_mib_event = ath9k_hw_proc_mib_event_new;
  1095. ops->ani_monitor = ath9k_hw_ani_monitor_new;
  1096. ath_print(ath9k_hw_common(ah), ATH_DBG_ANY, "Using ANI v2\n");
  1097. }