ani.c 37 KB

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