ani.c 37 KB

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