phydm_dig.c 81 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971197219731974197519761977197819791980198119821983198419851986198719881989199019911992199319941995199619971998199920002001200220032004200520062007200820092010201120122013201420152016201720182019202020212022202320242025202620272028202920302031203220332034203520362037203820392040204120422043204420452046204720482049205020512052205320542055205620572058205920602061206220632064206520662067206820692070207120722073207420752076207720782079208020812082208320842085208620872088208920902091209220932094209520962097209820992100210121022103210421052106210721082109211021112112211321142115211621172118211921202121212221232124212521262127212821292130213121322133213421352136213721382139214021412142214321442145214621472148214921502151215221532154215521562157215821592160216121622163216421652166216721682169217021712172217321742175217621772178217921802181218221832184218521862187218821892190219121922193219421952196219721982199220022012202220322042205220622072208220922102211221222132214221522162217221822192220222122222223222422252226222722282229223022312232223322342235223622372238223922402241224222432244224522462247224822492250225122522253225422552256225722582259226022612262226322642265
  1. /******************************************************************************
  2. *
  3. * Copyright(c) 2007 - 2011 Realtek Corporation. All rights reserved.
  4. *
  5. * This program is free software; you can redistribute it and/or modify it
  6. * under the terms of version 2 of the GNU General Public License as
  7. * published by the Free Software Foundation.
  8. *
  9. * This program is distributed in the hope that it will be useful, but WITHOUT
  10. * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  11. * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
  12. * more details.
  13. *
  14. * You should have received a copy of the GNU General Public License along with
  15. * this program; if not, write to the Free Software Foundation, Inc.,
  16. * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA
  17. *
  18. *
  19. ******************************************************************************/
  20. /* ************************************************************
  21. * include files
  22. * ************************************************************ */
  23. #include "mp_precomp.h"
  24. #include "phydm_precomp.h"
  25. void
  26. odm_change_dynamic_init_gain_thresh(
  27. void *p_dm_void,
  28. u32 dm_type,
  29. u32 dm_value
  30. )
  31. {
  32. struct PHY_DM_STRUCT *p_dm_odm = (struct PHY_DM_STRUCT *)p_dm_void;
  33. struct _dynamic_initial_gain_threshold_ *p_dm_dig_table = &p_dm_odm->dm_dig_table;
  34. if (dm_type == DIG_TYPE_THRESH_HIGH)
  35. p_dm_dig_table->rssi_high_thresh = dm_value;
  36. else if (dm_type == DIG_TYPE_THRESH_LOW)
  37. p_dm_dig_table->rssi_low_thresh = dm_value;
  38. else if (dm_type == DIG_TYPE_ENABLE)
  39. p_dm_dig_table->dig_enable_flag = true;
  40. else if (dm_type == DIG_TYPE_DISABLE)
  41. p_dm_dig_table->dig_enable_flag = false;
  42. else if (dm_type == DIG_TYPE_BACKOFF) {
  43. if (dm_value > 30)
  44. dm_value = 30;
  45. p_dm_dig_table->backoff_val = (u8)dm_value;
  46. } else if (dm_type == DIG_TYPE_RX_GAIN_MIN) {
  47. if (dm_value == 0)
  48. dm_value = 0x1;
  49. p_dm_dig_table->rx_gain_range_min = (u8)dm_value;
  50. } else if (dm_type == DIG_TYPE_RX_GAIN_MAX) {
  51. if (dm_value > 0x50)
  52. dm_value = 0x50;
  53. p_dm_dig_table->rx_gain_range_max = (u8)dm_value;
  54. }
  55. } /* dm_change_dynamic_init_gain_thresh */
  56. int
  57. get_igi_for_diff(int value_IGI)
  58. {
  59. #define ONERCCA_LOW_TH 0x30
  60. #define ONERCCA_LOW_DIFF 8
  61. if (value_IGI < ONERCCA_LOW_TH) {
  62. if ((ONERCCA_LOW_TH - value_IGI) < ONERCCA_LOW_DIFF)
  63. return ONERCCA_LOW_TH;
  64. else
  65. return value_IGI + ONERCCA_LOW_DIFF;
  66. } else
  67. return value_IGI;
  68. }
  69. void
  70. odm_fa_threshold_check(
  71. void *p_dm_void,
  72. boolean is_dfs_band,
  73. boolean is_performance,
  74. u32 rx_tp,
  75. u32 tx_tp,
  76. u32 *dm_FA_thres
  77. )
  78. {
  79. struct PHY_DM_STRUCT *p_dm_odm = (struct PHY_DM_STRUCT *)p_dm_void;
  80. if (p_dm_odm->is_linked && (is_performance || is_dfs_band)) {
  81. #if (DM_ODM_SUPPORT_TYPE & (ODM_AP))
  82. /*For AP*/
  83. #if (DIG_HW == 1)
  84. dm_FA_thres[0] = p_dm_odm->priv->pshare->rf_ft_var.dbg_dig_th1;
  85. dm_FA_thres[1] = p_dm_odm->priv->pshare->rf_ft_var.dbg_dig_th2;
  86. dm_FA_thres[2] = p_dm_odm->priv->pshare->rf_ft_var.dbg_dig_th3;
  87. #else
  88. if ((rx_tp >> 2) > tx_tp && rx_tp < 10000 && rx_tp > 500) { /*10Mbps & 0.5Mbps*/
  89. dm_FA_thres[0] = 0x080;
  90. dm_FA_thres[1] = 0x100;
  91. dm_FA_thres[2] = 0x200;
  92. } else {
  93. dm_FA_thres[0] = 0x100;
  94. dm_FA_thres[1] = 0x200;
  95. dm_FA_thres[2] = 0x300;
  96. }
  97. #endif
  98. #else
  99. /*For NIC*/
  100. dm_FA_thres[0] = DM_DIG_FA_TH0;
  101. dm_FA_thres[1] = DM_DIG_FA_TH1;
  102. dm_FA_thres[2] = DM_DIG_FA_TH2;
  103. #endif
  104. } else {
  105. #if (DM_ODM_SUPPORT_TYPE & (ODM_AP | ODM_CE))
  106. if (is_dfs_band) {
  107. /* For DFS band and no link */
  108. dm_FA_thres[0] = 250;
  109. dm_FA_thres[1] = 1000;
  110. dm_FA_thres[2] = 2000;
  111. } else
  112. #endif
  113. {
  114. dm_FA_thres[0] = 2000;
  115. dm_FA_thres[1] = 4000;
  116. dm_FA_thres[2] = 5000;
  117. }
  118. }
  119. return;
  120. }
  121. u8
  122. odm_forbidden_igi_check(
  123. void *p_dm_void,
  124. u8 dig_dynamic_min,
  125. u8 current_igi
  126. )
  127. {
  128. struct PHY_DM_STRUCT *p_dm_odm = (struct PHY_DM_STRUCT *)p_dm_void;
  129. struct _dynamic_initial_gain_threshold_ *p_dm_dig_table = &p_dm_odm->dm_dig_table;
  130. struct _FALSE_ALARM_STATISTICS *p_false_alm_cnt = (struct _FALSE_ALARM_STATISTICS *)phydm_get_structure(p_dm_odm, PHYDM_FALSEALMCNT);
  131. u8 rx_gain_range_min = p_dm_dig_table->rx_gain_range_min;
  132. if (p_dm_dig_table->large_fa_timeout) {
  133. if (--p_dm_dig_table->large_fa_timeout == 0)
  134. p_dm_dig_table->large_fa_hit = 0;
  135. }
  136. if (p_false_alm_cnt->cnt_all > 10000) {
  137. ODM_RT_TRACE(p_dm_odm, ODM_COMP_DIG, ODM_DBG_LOUD, ("odm_DIG(): Abnormally false alarm case.\n"));
  138. if (p_dm_dig_table->large_fa_hit != 3)
  139. p_dm_dig_table->large_fa_hit++;
  140. if (p_dm_dig_table->forbidden_igi < current_igi) { /* if(p_dm_dig_table->forbidden_igi < p_dm_dig_table->cur_ig_value) */
  141. p_dm_dig_table->forbidden_igi = current_igi;/* p_dm_dig_table->forbidden_igi = p_dm_dig_table->cur_ig_value; */
  142. p_dm_dig_table->large_fa_hit = 1;
  143. p_dm_dig_table->large_fa_timeout = LARGE_FA_TIMEOUT;
  144. }
  145. if (p_dm_dig_table->large_fa_hit >= 3) {
  146. if ((p_dm_dig_table->forbidden_igi + 2) > p_dm_dig_table->rx_gain_range_max)
  147. rx_gain_range_min = p_dm_dig_table->rx_gain_range_max;
  148. else
  149. rx_gain_range_min = (p_dm_dig_table->forbidden_igi + 2);
  150. p_dm_dig_table->recover_cnt = 1800;
  151. ODM_RT_TRACE(p_dm_odm, ODM_COMP_DIG, ODM_DBG_LOUD, ("odm_DIG(): Abnormally false alarm case: recover_cnt = %d\n", p_dm_dig_table->recover_cnt));
  152. }
  153. }
  154. else if (p_false_alm_cnt->cnt_all > 2000) {
  155. ODM_RT_TRACE(p_dm_odm, ODM_COMP_DIG, ODM_DBG_LOUD, ("Abnormally false alarm case.\n"));
  156. ODM_RT_TRACE(p_dm_odm, ODM_COMP_DIG, ODM_DBG_LOUD, ("cnt_all=%d, cnt_all_pre=%d, current_igi=0x%x, pre_ig_value=0x%x\n",
  157. p_false_alm_cnt->cnt_all, p_false_alm_cnt->cnt_all_pre, current_igi, p_dm_dig_table->pre_ig_value));
  158. /* p_false_alm_cnt->cnt_all = 1.1875*p_false_alm_cnt->cnt_all_pre */
  159. if ((p_false_alm_cnt->cnt_all > (p_false_alm_cnt->cnt_all_pre + (p_false_alm_cnt->cnt_all_pre >> 3) + (p_false_alm_cnt->cnt_all_pre >> 4))) && (current_igi < p_dm_dig_table->pre_ig_value)) {
  160. if (p_dm_dig_table->large_fa_hit != 3)
  161. p_dm_dig_table->large_fa_hit++;
  162. if (p_dm_dig_table->forbidden_igi < current_igi) { /*if(p_dm_dig_table->forbidden_igi < p_dm_dig_table->cur_ig_value)*/
  163. ODM_RT_TRACE(p_dm_odm, ODM_COMP_DIG, ODM_DBG_LOUD, ("Updating forbidden_igi by current_igi, forbidden_igi=0x%x, current_igi=0x%x\n",
  164. p_dm_dig_table->forbidden_igi, current_igi));
  165. p_dm_dig_table->forbidden_igi = current_igi; /*p_dm_dig_table->forbidden_igi = p_dm_dig_table->cur_ig_value;*/
  166. p_dm_dig_table->large_fa_hit = 1;
  167. p_dm_dig_table->large_fa_timeout = LARGE_FA_TIMEOUT;
  168. }
  169. }
  170. if (p_dm_dig_table->large_fa_hit >= 3) {
  171. ODM_RT_TRACE(p_dm_odm, ODM_COMP_DIG, ODM_DBG_LOUD, ("FaHit is greater than 3, rx_gain_range_max=0x%x, rx_gain_range_min=0x%x, forbidden_igi=0x%x\n",
  172. p_dm_dig_table->rx_gain_range_max, rx_gain_range_min, p_dm_dig_table->forbidden_igi));
  173. if ((p_dm_dig_table->forbidden_igi + 1) > p_dm_dig_table->rx_gain_range_max)
  174. rx_gain_range_min = p_dm_dig_table->rx_gain_range_max;
  175. else
  176. rx_gain_range_min = (p_dm_dig_table->forbidden_igi + 1);
  177. p_dm_dig_table->recover_cnt = 1200;
  178. ODM_RT_TRACE(p_dm_odm, ODM_COMP_DIG, ODM_DBG_LOUD, ("Abnormally false alarm case: recover_cnt = %d, rx_gain_range_min = 0x%x\n", p_dm_dig_table->recover_cnt, rx_gain_range_min));
  179. }
  180. }
  181. else {
  182. if (p_dm_dig_table->recover_cnt != 0) {
  183. p_dm_dig_table->recover_cnt--;
  184. ODM_RT_TRACE(p_dm_odm, ODM_COMP_DIG, ODM_DBG_LOUD, ("odm_DIG(): Normal Case: recover_cnt = %d\n", p_dm_dig_table->recover_cnt));
  185. } else {
  186. if (p_dm_dig_table->large_fa_hit < 3) {
  187. if ((p_dm_dig_table->forbidden_igi - 2) < dig_dynamic_min) { /* DM_DIG_MIN) */
  188. p_dm_dig_table->forbidden_igi = dig_dynamic_min; /* DM_DIG_MIN; */
  189. rx_gain_range_min = dig_dynamic_min; /* DM_DIG_MIN; */
  190. ODM_RT_TRACE(p_dm_odm, ODM_COMP_DIG, ODM_DBG_LOUD, ("odm_DIG(): Normal Case: At Lower Bound\n"));
  191. } else {
  192. if (p_dm_dig_table->large_fa_hit == 0) {
  193. p_dm_dig_table->forbidden_igi -= 2;
  194. rx_gain_range_min = (p_dm_dig_table->forbidden_igi + 2);
  195. ODM_RT_TRACE(p_dm_odm, ODM_COMP_DIG, ODM_DBG_LOUD, ("odm_DIG(): Normal Case: Approach Lower Bound\n"));
  196. }
  197. }
  198. } else
  199. p_dm_dig_table->large_fa_hit = 0;
  200. }
  201. }
  202. return rx_gain_range_min;
  203. }
  204. void
  205. odm_inband_noise_calculate(
  206. void *p_dm_void
  207. )
  208. {
  209. #if (DM_ODM_SUPPORT_TYPE & (ODM_AP))
  210. struct PHY_DM_STRUCT *p_dm_odm = (struct PHY_DM_STRUCT *)p_dm_void;
  211. struct _dynamic_initial_gain_threshold_ *p_dm_dig_table = &p_dm_odm->dm_dig_table;
  212. u8 igi_backup, time_cnt = 0, valid_cnt = 0;
  213. boolean is_timeout = true;
  214. s8 s_noise_a, s_noise_b;
  215. s32 noise_rpt_a = 0, noise_rpt_b = 0;
  216. u32 tmp = 0;
  217. static u8 fail_cnt = 0;
  218. if (!(p_dm_odm->support_ic_type & (ODM_RTL8192E)))
  219. return;
  220. if (p_dm_odm->rf_type == ODM_1T1R || *(p_dm_odm->p_one_path_cca) != ODM_CCA_2R)
  221. return;
  222. if (!p_dm_dig_table->is_noise_est)
  223. return;
  224. ODM_RT_TRACE(p_dm_odm, ODM_COMP_DIG, ODM_DBG_LOUD, ("odm_InbandNoiseEstimate()========>\n"));
  225. /* 1 Set initial gain. */
  226. igi_backup = p_dm_dig_table->cur_ig_value;
  227. p_dm_dig_table->igi_offset_a = 0;
  228. p_dm_dig_table->igi_offset_b = 0;
  229. odm_write_dig(p_dm_odm, 0x24);
  230. /* 1 Update idle time power report */
  231. if (p_dm_odm->support_ic_type & ODM_IC_11N_SERIES)
  232. odm_set_bb_reg(p_dm_odm, ODM_REG_TX_ANT_CTRL_11N, BIT(25), 0x0);
  233. delay_ms(2);
  234. /* 1 Get noise power level */
  235. while (1) {
  236. /* 2 Read Noise Floor Report */
  237. if (p_dm_odm->support_ic_type & ODM_IC_11N_SERIES)
  238. tmp = odm_get_bb_reg(p_dm_odm, 0x8f8, MASKLWORD);
  239. s_noise_a = (s8)(tmp & 0xff);
  240. s_noise_b = (s8)((tmp & 0xff00) >> 8);
  241. /* ODM_RT_TRACE(p_dm_odm,ODM_COMP_DIG, ODM_DBG_LOUD, ("s_noise_a = %d, s_noise_b = %d\n",s_noise_a, s_noise_b)); */
  242. if ((s_noise_a < 20 && s_noise_a >= -70) && (s_noise_b < 20 && s_noise_b >= -70)) {
  243. valid_cnt++;
  244. noise_rpt_a += s_noise_a;
  245. noise_rpt_b += s_noise_b;
  246. /* ODM_RT_TRACE(p_dm_odm,ODM_COMP_DIG, ODM_DBG_LOUD, ("s_noise_a = %d, s_noise_b = %d\n",s_noise_a, s_noise_b)); */
  247. }
  248. time_cnt++;
  249. is_timeout = (time_cnt >= 150) ? true : false;
  250. if (valid_cnt == 20 || is_timeout)
  251. break;
  252. delay_ms(2);
  253. }
  254. /* 1 Keep idle time power report */
  255. if (p_dm_odm->support_ic_type & ODM_IC_11N_SERIES)
  256. odm_set_bb_reg(p_dm_odm, ODM_REG_TX_ANT_CTRL_11N, BIT(25), 0x1);
  257. /* 1 Recover IGI */
  258. odm_write_dig(p_dm_odm, igi_backup);
  259. /* 1 Calculate Noise Floor */
  260. if (valid_cnt != 0) {
  261. noise_rpt_a /= (valid_cnt << 1);
  262. noise_rpt_b /= (valid_cnt << 1);
  263. }
  264. if (is_timeout) {
  265. noise_rpt_a = 0;
  266. noise_rpt_b = 0;
  267. fail_cnt++;
  268. ODM_RT_TRACE(p_dm_odm, ODM_COMP_DIG, ODM_DBG_LOUD, ("Noise estimate fail time = %d\n", fail_cnt));
  269. if (fail_cnt == 3) {
  270. fail_cnt = 0;
  271. p_dm_dig_table->is_noise_est = false;
  272. }
  273. } else {
  274. noise_rpt_a = -110 + 0x24 + noise_rpt_a - 6;
  275. noise_rpt_b = -110 + 0x24 + noise_rpt_b - 6;
  276. p_dm_dig_table->is_noise_est = false;
  277. fail_cnt = 0;
  278. ODM_RT_TRACE(p_dm_odm, ODM_COMP_DIG, ODM_DBG_LOUD, ("noise_rpt_a = %d, noise_rpt_b = %d\n", noise_rpt_a, noise_rpt_b));
  279. }
  280. /* 1 Calculate IGI Offset */
  281. if (noise_rpt_a > noise_rpt_b) {
  282. p_dm_dig_table->igi_offset_a = noise_rpt_a - noise_rpt_b;
  283. p_dm_dig_table->igi_offset_b = 0;
  284. } else {
  285. p_dm_dig_table->igi_offset_a = 0;
  286. p_dm_dig_table->igi_offset_b = noise_rpt_b - noise_rpt_a;
  287. }
  288. #endif
  289. return;
  290. }
  291. void
  292. odm_dig_for_bt_hs_mode(
  293. void *p_dm_void
  294. )
  295. {
  296. #if (DM_ODM_SUPPORT_TYPE == ODM_WIN)
  297. struct PHY_DM_STRUCT *p_dm_odm = (struct PHY_DM_STRUCT *)p_dm_void;
  298. struct _dynamic_initial_gain_threshold_ *p_dm_dig_table = &p_dm_odm->dm_dig_table;
  299. u8 dig_for_bt_hs = 0;
  300. u8 dig_up_bound = 0x5a;
  301. if (p_dm_odm->is_bt_connect_process)
  302. dig_for_bt_hs = 0x22;
  303. else {
  304. /* */
  305. /* Decide DIG value by BT HS RSSI. */
  306. /* */
  307. dig_for_bt_hs = p_dm_odm->bt_hs_rssi + 4;
  308. /* DIG Bound */
  309. if (dig_for_bt_hs > dig_up_bound)
  310. dig_for_bt_hs = dig_up_bound;
  311. if (dig_for_bt_hs < 0x1c)
  312. dig_for_bt_hs = 0x1c;
  313. /* update Current IGI */
  314. p_dm_dig_table->bt30_cur_igi = dig_for_bt_hs;
  315. }
  316. ODM_RT_TRACE(p_dm_odm, ODM_COMP_DIG, ODM_DBG_LOUD, ("odm_dig_for_bt_hs_mode() : set DigValue=0x%x\n", dig_for_bt_hs));
  317. #endif
  318. }
  319. void
  320. phydm_set_big_jump_step(
  321. void *p_dm_void,
  322. u8 current_igi
  323. )
  324. {
  325. #if (RTL8822B_SUPPORT == 1 || RTL8197F_SUPPORT == 1)
  326. struct PHY_DM_STRUCT *p_dm_odm = (struct PHY_DM_STRUCT *)p_dm_void;
  327. struct _dynamic_initial_gain_threshold_ *p_dm_dig_table = &p_dm_odm->dm_dig_table;
  328. u8 step1[8] = {24, 30, 40, 50, 60, 70, 80, 90};
  329. u8 i;
  330. if (p_dm_dig_table->enable_adjust_big_jump == 0)
  331. return;
  332. for (i = 0; i <= p_dm_dig_table->big_jump_step1; i++) {
  333. if ((current_igi + step1[i]) > p_dm_dig_table->big_jump_lmt[p_dm_dig_table->agc_table_idx]) {
  334. if (i != 0)
  335. i = i - 1;
  336. break;
  337. } else if (i == p_dm_dig_table->big_jump_step1)
  338. break;
  339. }
  340. if (p_dm_odm->support_ic_type & ODM_RTL8822B)
  341. odm_set_bb_reg(p_dm_odm, 0x8c8, 0xe, i);
  342. else if (p_dm_odm->support_ic_type & ODM_RTL8197F)
  343. odm_set_bb_reg(p_dm_odm, ODM_REG_BB_AGC_SET_2_11N, 0xe, i);
  344. ODM_RT_TRACE(p_dm_odm, ODM_COMP_DIG, ODM_DBG_LOUD, ("phydm_set_big_jump_step(): bigjump = %d (ori = 0x%x), LMT=0x%x\n", i, p_dm_dig_table->big_jump_step1, p_dm_dig_table->big_jump_lmt[p_dm_dig_table->agc_table_idx]));
  345. #endif
  346. }
  347. void
  348. odm_write_dig(
  349. void *p_dm_void,
  350. u8 current_igi
  351. )
  352. {
  353. struct PHY_DM_STRUCT *p_dm_odm = (struct PHY_DM_STRUCT *)p_dm_void;
  354. struct _dynamic_initial_gain_threshold_ *p_dm_dig_table = &p_dm_odm->dm_dig_table;
  355. if (p_dm_dig_table->is_stop_dig) {
  356. ODM_RT_TRACE(p_dm_odm, ODM_COMP_DIG, ODM_DBG_LOUD, ("odm_write_dig(): Stop Writing IGI\n"));
  357. return;
  358. }
  359. ODM_RT_TRACE(p_dm_odm, ODM_COMP_DIG, ODM_DBG_TRACE, ("odm_write_dig(): ODM_REG(IGI_A,p_dm_odm)=0x%x, ODM_BIT(IGI,p_dm_odm)=0x%x\n",
  360. ODM_REG(IGI_A, p_dm_odm), ODM_BIT(IGI, p_dm_odm)));
  361. /* 1 Check initial gain by upper bound */
  362. if ((!p_dm_dig_table->is_psd_in_progress) && p_dm_odm->is_linked) {
  363. if (current_igi > p_dm_dig_table->rx_gain_range_max) {
  364. ODM_RT_TRACE(p_dm_odm, ODM_COMP_DIG, ODM_DBG_TRACE, ("odm_write_dig(): current_igi(0x%02x) is larger than upper bound !!\n", current_igi));
  365. current_igi = p_dm_dig_table->rx_gain_range_max;
  366. }
  367. if (p_dm_odm->support_ability & ODM_BB_ADAPTIVITY && p_dm_odm->adaptivity_flag == true) {
  368. if (current_igi > p_dm_odm->adaptivity_igi_upper)
  369. current_igi = p_dm_odm->adaptivity_igi_upper;
  370. ODM_RT_TRACE(p_dm_odm, ODM_COMP_DIG, ODM_DBG_LOUD, ("odm_write_dig(): adaptivity case: Force upper bound to 0x%x !!!!!!\n", current_igi));
  371. }
  372. }
  373. if (p_dm_dig_table->cur_ig_value != current_igi) {
  374. #if (RTL8822B_SUPPORT == 1 || RTL8197F_SUPPORT == 1)
  375. /* Modify big jump step for 8822B and 8197F */
  376. if (p_dm_odm->support_ic_type & (ODM_RTL8822B | ODM_RTL8197F))
  377. phydm_set_big_jump_step(p_dm_odm, current_igi);
  378. #endif
  379. #if (ODM_PHY_STATUS_NEW_TYPE_SUPPORT == 1)
  380. /* Set IGI value of CCK for new CCK AGC */
  381. if (p_dm_odm->cck_new_agc) {
  382. if (p_dm_odm->support_ic_type & ODM_IC_PHY_STATUE_NEW_TYPE)
  383. odm_set_bb_reg(p_dm_odm, 0xa0c, 0x00003f00, (current_igi >> 1));
  384. }
  385. #endif
  386. /*Add by YuChen for USB IO too slow issue*/
  387. if ((p_dm_odm->support_ability & ODM_BB_ADAPTIVITY) && (current_igi > p_dm_dig_table->cur_ig_value)) {
  388. p_dm_dig_table->cur_ig_value = current_igi;
  389. phydm_adaptivity(p_dm_odm);
  390. }
  391. /* 1 Set IGI value */
  392. if (p_dm_odm->support_platform & (ODM_WIN | ODM_CE)) {
  393. odm_set_bb_reg(p_dm_odm, ODM_REG(IGI_A, p_dm_odm), ODM_BIT(IGI, p_dm_odm), current_igi);
  394. if (p_dm_odm->rf_type > ODM_1T1R)
  395. odm_set_bb_reg(p_dm_odm, ODM_REG(IGI_B, p_dm_odm), ODM_BIT(IGI, p_dm_odm), current_igi);
  396. #if (RTL8814A_SUPPORT == 1)
  397. if (p_dm_odm->support_ic_type & ODM_RTL8814A) {
  398. odm_set_bb_reg(p_dm_odm, ODM_REG(IGI_C, p_dm_odm), ODM_BIT(IGI, p_dm_odm), current_igi);
  399. odm_set_bb_reg(p_dm_odm, ODM_REG(IGI_D, p_dm_odm), ODM_BIT(IGI, p_dm_odm), current_igi);
  400. }
  401. #endif
  402. } else if (p_dm_odm->support_platform & (ODM_AP)) {
  403. switch (*(p_dm_odm->p_one_path_cca)) {
  404. case ODM_CCA_2R:
  405. odm_set_bb_reg(p_dm_odm, ODM_REG(IGI_A, p_dm_odm), ODM_BIT(IGI, p_dm_odm), current_igi);
  406. if (p_dm_odm->rf_type > ODM_1T1R)
  407. odm_set_bb_reg(p_dm_odm, ODM_REG(IGI_B, p_dm_odm), ODM_BIT(IGI, p_dm_odm), current_igi);
  408. #if (RTL8814A_SUPPORT == 1)
  409. if (p_dm_odm->support_ic_type & ODM_RTL8814A) {
  410. odm_set_bb_reg(p_dm_odm, ODM_REG(IGI_C, p_dm_odm), ODM_BIT(IGI, p_dm_odm), current_igi);
  411. odm_set_bb_reg(p_dm_odm, ODM_REG(IGI_D, p_dm_odm), ODM_BIT(IGI, p_dm_odm), current_igi);
  412. }
  413. #endif
  414. break;
  415. case ODM_CCA_1R_A:
  416. odm_set_bb_reg(p_dm_odm, ODM_REG(IGI_A, p_dm_odm), ODM_BIT(IGI, p_dm_odm), current_igi);
  417. if (p_dm_odm->rf_type != ODM_1T1R)
  418. odm_set_bb_reg(p_dm_odm, ODM_REG(IGI_B, p_dm_odm), ODM_BIT(IGI, p_dm_odm), get_igi_for_diff(current_igi));
  419. break;
  420. case ODM_CCA_1R_B:
  421. odm_set_bb_reg(p_dm_odm, ODM_REG(IGI_B, p_dm_odm), ODM_BIT(IGI, p_dm_odm), get_igi_for_diff(current_igi));
  422. if (p_dm_odm->rf_type != ODM_1T1R)
  423. odm_set_bb_reg(p_dm_odm, ODM_REG(IGI_A, p_dm_odm), ODM_BIT(IGI, p_dm_odm), current_igi);
  424. break;
  425. }
  426. }
  427. p_dm_dig_table->cur_ig_value = current_igi;
  428. }
  429. ODM_RT_TRACE(p_dm_odm, ODM_COMP_DIG, ODM_DBG_TRACE, ("odm_write_dig(): current_igi(0x%02x).\n", current_igi));
  430. }
  431. void
  432. odm_pause_dig(
  433. void *p_dm_void,
  434. enum phydm_pause_type pause_type,
  435. enum phydm_pause_level pause_level,
  436. u8 igi_value
  437. )
  438. {
  439. struct PHY_DM_STRUCT *p_dm_odm = (struct PHY_DM_STRUCT *)p_dm_void;
  440. struct _dynamic_initial_gain_threshold_ *p_dm_dig_table = &p_dm_odm->dm_dig_table;
  441. ODM_RT_TRACE(p_dm_odm, ODM_COMP_DIG, ODM_DBG_LOUD, ("odm_pause_dig()=========> level = %d\n", pause_level));
  442. if ((p_dm_dig_table->pause_dig_level == 0) && (!(p_dm_odm->support_ability & ODM_BB_DIG) || !(p_dm_odm->support_ability & ODM_BB_FA_CNT))) {
  443. ODM_RT_TRACE(p_dm_odm, ODM_COMP_DIG, ODM_DBG_LOUD,
  444. ("odm_pause_dig(): Return: support_ability DIG or FA is disabled !!\n"));
  445. return;
  446. }
  447. if (pause_level > DM_DIG_MAX_PAUSE_TYPE) {
  448. ODM_RT_TRACE(p_dm_odm, ODM_COMP_DIG, ODM_DBG_LOUD,
  449. ("odm_pause_dig(): Return: Wrong pause level !!\n"));
  450. return;
  451. }
  452. ODM_RT_TRACE(p_dm_odm, ODM_COMP_DIG, ODM_DBG_LOUD, ("odm_pause_dig(): pause level = 0x%x, Current value = 0x%x\n", p_dm_dig_table->pause_dig_level, igi_value));
  453. ODM_RT_TRACE(p_dm_odm, ODM_COMP_DIG, ODM_DBG_LOUD, ("odm_pause_dig(): pause value = 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x\n",
  454. p_dm_dig_table->pause_dig_value[7], p_dm_dig_table->pause_dig_value[6], p_dm_dig_table->pause_dig_value[5], p_dm_dig_table->pause_dig_value[4],
  455. p_dm_dig_table->pause_dig_value[3], p_dm_dig_table->pause_dig_value[2], p_dm_dig_table->pause_dig_value[1], p_dm_dig_table->pause_dig_value[0]));
  456. switch (pause_type) {
  457. /* Pause DIG */
  458. case PHYDM_PAUSE:
  459. {
  460. /* Disable DIG */
  461. odm_cmn_info_update(p_dm_odm, ODM_CMNINFO_ABILITY, p_dm_odm->support_ability & (~ODM_BB_DIG));
  462. ODM_RT_TRACE(p_dm_odm, ODM_COMP_DIG, ODM_DBG_LOUD, ("odm_pause_dig(): Pause DIG !!\n"));
  463. /* Backup IGI value */
  464. if (p_dm_dig_table->pause_dig_level == 0) {
  465. p_dm_dig_table->igi_backup = p_dm_dig_table->cur_ig_value;
  466. ODM_RT_TRACE(p_dm_odm, ODM_COMP_DIG, ODM_DBG_LOUD, ("odm_pause_dig(): Backup IGI = 0x%x, new IGI = 0x%x\n", p_dm_dig_table->igi_backup, igi_value));
  467. }
  468. /* Record IGI value */
  469. p_dm_dig_table->pause_dig_value[pause_level] = igi_value;
  470. /* Update pause level */
  471. p_dm_dig_table->pause_dig_level = (p_dm_dig_table->pause_dig_level | BIT(pause_level));
  472. /* Write new IGI value */
  473. if (BIT(pause_level + 1) > p_dm_dig_table->pause_dig_level) {
  474. odm_write_dig(p_dm_odm, igi_value);
  475. ODM_RT_TRACE(p_dm_odm, ODM_COMP_DIG, ODM_DBG_LOUD, ("odm_pause_dig(): IGI of higher level = 0x%x\n", igi_value));
  476. }
  477. break;
  478. }
  479. /* Resume DIG */
  480. case PHYDM_RESUME:
  481. {
  482. /* check if the level is illegal or not */
  483. if ((p_dm_dig_table->pause_dig_level & (BIT(pause_level))) != 0) {
  484. p_dm_dig_table->pause_dig_level = p_dm_dig_table->pause_dig_level & (~(BIT(pause_level)));
  485. p_dm_dig_table->pause_dig_value[pause_level] = 0;
  486. ODM_RT_TRACE(p_dm_odm, ODM_COMP_DIG, ODM_DBG_LOUD, ("odm_pause_dig(): Resume DIG !!\n"));
  487. } else {
  488. ODM_RT_TRACE(p_dm_odm, ODM_COMP_DIG, ODM_DBG_LOUD, ("odm_pause_dig(): Wrong resume level !!\n"));
  489. break;
  490. }
  491. /* Resume DIG */
  492. if (p_dm_dig_table->pause_dig_level == 0) {
  493. /* Write backup IGI value */
  494. odm_write_dig(p_dm_odm, p_dm_dig_table->igi_backup);
  495. p_dm_dig_table->is_ignore_dig = true;
  496. ODM_RT_TRACE(p_dm_odm, ODM_COMP_DIG, ODM_DBG_LOUD, ("odm_pause_dig(): Write original IGI = 0x%x\n", p_dm_dig_table->igi_backup));
  497. /* Enable DIG */
  498. odm_cmn_info_update(p_dm_odm, ODM_CMNINFO_ABILITY, p_dm_odm->support_ability | ODM_BB_DIG);
  499. break;
  500. }
  501. if (BIT(pause_level) > p_dm_dig_table->pause_dig_level) {
  502. s8 max_level;
  503. /* Calculate the maximum level now */
  504. for (max_level = (pause_level - 1); max_level >= 0; max_level--) {
  505. if ((p_dm_dig_table->pause_dig_level & BIT(max_level)) > 0)
  506. break;
  507. }
  508. /* write IGI of lower level */
  509. odm_write_dig(p_dm_odm, p_dm_dig_table->pause_dig_value[max_level]);
  510. ODM_RT_TRACE(p_dm_odm, ODM_COMP_DIG, ODM_DBG_LOUD, ("odm_pause_dig(): Write IGI (0x%x) of level (%d)\n",
  511. p_dm_dig_table->pause_dig_value[max_level], max_level));
  512. break;
  513. }
  514. break;
  515. }
  516. default:
  517. ODM_RT_TRACE(p_dm_odm, ODM_COMP_DIG, ODM_DBG_LOUD, ("odm_pause_dig(): Wrong type !!\n"));
  518. break;
  519. }
  520. ODM_RT_TRACE(p_dm_odm, ODM_COMP_DIG, ODM_DBG_LOUD, ("odm_pause_dig(): pause level = 0x%x, Current value = 0x%x\n", p_dm_dig_table->pause_dig_level, igi_value));
  521. ODM_RT_TRACE(p_dm_odm, ODM_COMP_DIG, ODM_DBG_LOUD, ("odm_pause_dig(): pause value = 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x\n",
  522. p_dm_dig_table->pause_dig_value[7], p_dm_dig_table->pause_dig_value[6], p_dm_dig_table->pause_dig_value[5], p_dm_dig_table->pause_dig_value[4],
  523. p_dm_dig_table->pause_dig_value[3], p_dm_dig_table->pause_dig_value[2], p_dm_dig_table->pause_dig_value[1], p_dm_dig_table->pause_dig_value[0]));
  524. }
  525. boolean
  526. odm_dig_abort(
  527. void *p_dm_void
  528. )
  529. {
  530. struct PHY_DM_STRUCT *p_dm_odm = (struct PHY_DM_STRUCT *)p_dm_void;
  531. struct _dynamic_initial_gain_threshold_ *p_dm_dig_table = &p_dm_odm->dm_dig_table;
  532. #if (DM_ODM_SUPPORT_TYPE & (ODM_AP))
  533. struct rtl8192cd_priv *priv = p_dm_odm->priv;
  534. #elif (DM_ODM_SUPPORT_TYPE & ODM_WIN)
  535. struct _ADAPTER *p_adapter = p_dm_odm->adapter;
  536. #endif
  537. /* support_ability */
  538. if (!(p_dm_odm->support_ability & ODM_BB_FA_CNT)) {
  539. ODM_RT_TRACE(p_dm_odm, ODM_COMP_DIG, ODM_DBG_LOUD, ("odm_DIG(): Return: support_ability ODM_BB_FA_CNT is disabled\n"));
  540. return true;
  541. }
  542. /* support_ability */
  543. if (!(p_dm_odm->support_ability & ODM_BB_DIG)) {
  544. ODM_RT_TRACE(p_dm_odm, ODM_COMP_DIG, ODM_DBG_LOUD, ("odm_DIG(): Return: support_ability ODM_BB_DIG is disabled\n"));
  545. return true;
  546. }
  547. /* ScanInProcess */
  548. if (*(p_dm_odm->p_is_scan_in_process)) {
  549. ODM_RT_TRACE(p_dm_odm, ODM_COMP_DIG, ODM_DBG_LOUD, ("odm_DIG(): Return: In Scan Progress\n"));
  550. return true;
  551. }
  552. if (p_dm_dig_table->is_ignore_dig) {
  553. p_dm_dig_table->is_ignore_dig = false;
  554. ODM_RT_TRACE(p_dm_odm, ODM_COMP_DIG, ODM_DBG_LOUD, ("odm_DIG(): Return: Ignore DIG\n"));
  555. return true;
  556. }
  557. /* add by Neil Chen to avoid PSD is processing */
  558. if (p_dm_odm->is_dm_initial_gain_enable == false) {
  559. ODM_RT_TRACE(p_dm_odm, ODM_COMP_DIG, ODM_DBG_LOUD, ("odm_DIG(): Return: PSD is Processing\n"));
  560. return true;
  561. }
  562. #if (DM_ODM_SUPPORT_TYPE == ODM_WIN)
  563. #if OS_WIN_FROM_WIN7(OS_VERSION)
  564. if (IsAPModeExist(p_adapter) && p_adapter->bInHctTest) {
  565. ODM_RT_TRACE(p_dm_odm, ODM_COMP_DIG, ODM_DBG_LOUD, ("odm_DIG(): Return: Is AP mode or In HCT Test\n"));
  566. return true;
  567. }
  568. #endif
  569. if (p_dm_odm->is_bt_hs_operation)
  570. odm_dig_for_bt_hs_mode(p_dm_odm);
  571. #elif (DM_ODM_SUPPORT_TYPE == ODM_CE)
  572. #ifdef CONFIG_SPECIAL_SETTING_FOR_FUNAI_TV
  573. if ((p_dm_odm->is_linked) && (p_dm_odm->adapter->registrypriv.force_igi != 0)) {
  574. printk("p_dm_odm->rssi_min=%d\n", p_dm_odm->rssi_min);
  575. odm_write_dig(p_dm_odm, p_dm_odm->adapter->registrypriv.force_igi);
  576. return true;
  577. }
  578. #endif
  579. #else
  580. if (!(priv->up_time > 5)) {
  581. ODM_RT_TRACE(p_dm_odm, ODM_COMP_DIG, ODM_DBG_LOUD, ("odm_DIG(): Return: Not In DIG operation period\n"));
  582. return true;
  583. }
  584. #endif
  585. return false;
  586. }
  587. void
  588. odm_dig_init(
  589. void *p_dm_void
  590. )
  591. {
  592. struct PHY_DM_STRUCT *p_dm_odm = (struct PHY_DM_STRUCT *)p_dm_void;
  593. struct _dynamic_initial_gain_threshold_ *p_dm_dig_table = &p_dm_odm->dm_dig_table;
  594. #if (DM_ODM_SUPPORT_TYPE & (ODM_AP))
  595. struct _FALSE_ALARM_STATISTICS *false_alm_cnt = (struct _FALSE_ALARM_STATISTICS *)phydm_get_structure(p_dm_odm, PHYDM_FALSEALMCNT);
  596. #endif
  597. u32 ret_value;
  598. u8 i;
  599. p_dm_dig_table->is_stop_dig = false;
  600. p_dm_dig_table->is_ignore_dig = false;
  601. p_dm_dig_table->is_psd_in_progress = false;
  602. p_dm_dig_table->cur_ig_value = (u8) odm_get_bb_reg(p_dm_odm, ODM_REG(IGI_A, p_dm_odm), ODM_BIT(IGI, p_dm_odm));
  603. p_dm_dig_table->pre_ig_value = 0;
  604. p_dm_dig_table->rssi_low_thresh = DM_DIG_THRESH_LOW;
  605. p_dm_dig_table->rssi_high_thresh = DM_DIG_THRESH_HIGH;
  606. p_dm_dig_table->fa_low_thresh = DM_FALSEALARM_THRESH_LOW;
  607. p_dm_dig_table->fa_high_thresh = DM_FALSEALARM_THRESH_HIGH;
  608. p_dm_dig_table->backoff_val = DM_DIG_BACKOFF_DEFAULT;
  609. p_dm_dig_table->backoff_val_range_max = DM_DIG_BACKOFF_MAX;
  610. p_dm_dig_table->backoff_val_range_min = DM_DIG_BACKOFF_MIN;
  611. p_dm_dig_table->pre_cck_cca_thres = 0xFF;
  612. p_dm_dig_table->cur_cck_cca_thres = 0x83;
  613. p_dm_dig_table->forbidden_igi = DM_DIG_MIN_NIC;
  614. p_dm_dig_table->large_fa_hit = 0;
  615. p_dm_dig_table->large_fa_timeout = 0;
  616. p_dm_dig_table->recover_cnt = 0;
  617. p_dm_dig_table->is_media_connect_0 = false;
  618. p_dm_dig_table->is_media_connect_1 = false;
  619. /* To Initialize p_dm_odm->is_dm_initial_gain_enable == false to avoid DIG error */
  620. p_dm_odm->is_dm_initial_gain_enable = true;
  621. #if (DM_ODM_SUPPORT_TYPE & (ODM_AP))
  622. p_dm_dig_table->dig_dynamic_min_0 = 0x25;
  623. p_dm_dig_table->dig_dynamic_min_1 = 0x25;
  624. /* For AP\ ADSL modified DIG */
  625. p_dm_dig_table->is_tp_target = false;
  626. p_dm_dig_table->is_noise_est = true;
  627. p_dm_dig_table->igi_offset_a = 0;
  628. p_dm_dig_table->igi_offset_b = 0;
  629. p_dm_dig_table->tp_train_th_min = 0;
  630. /* For RTL8881A */
  631. false_alm_cnt->cnt_ofdm_fail_pre = 0;
  632. /* Dyanmic EDCCA */
  633. if (p_dm_odm->support_ic_type & ODM_IC_11AC_SERIES)
  634. odm_set_bb_reg(p_dm_odm, 0xC50, 0xFFFF0000, 0xfafd);
  635. #else
  636. p_dm_dig_table->dig_dynamic_min_0 = DM_DIG_MIN_NIC;
  637. p_dm_dig_table->dig_dynamic_min_1 = DM_DIG_MIN_NIC;
  638. /* To Initi BT30 IGI */
  639. p_dm_dig_table->bt30_cur_igi = 0x32;
  640. odm_memory_set(p_dm_odm, p_dm_dig_table->pause_dig_value, 0, (DM_DIG_MAX_PAUSE_TYPE + 1));
  641. p_dm_dig_table->pause_dig_level = 0;
  642. odm_memory_set(p_dm_odm, p_dm_dig_table->pause_cckpd_value, 0, (DM_DIG_MAX_PAUSE_TYPE + 1));
  643. p_dm_dig_table->pause_cckpd_level = 0;
  644. #endif
  645. if (p_dm_odm->board_type & (ODM_BOARD_EXT_PA | ODM_BOARD_EXT_LNA)) {
  646. p_dm_dig_table->rx_gain_range_max = DM_DIG_MAX_NIC;
  647. p_dm_dig_table->rx_gain_range_min = DM_DIG_MIN_NIC;
  648. } else {
  649. p_dm_dig_table->rx_gain_range_max = DM_DIG_MAX_NIC;
  650. p_dm_dig_table->rx_gain_range_min = DM_DIG_MIN_NIC;
  651. }
  652. #if (RTL8822B_SUPPORT == 1 || RTL8197F_SUPPORT == 1)
  653. p_dm_dig_table->enable_adjust_big_jump = 1;
  654. if (p_dm_odm->support_ic_type & ODM_RTL8822B) {
  655. ret_value = odm_get_bb_reg(p_dm_odm, 0x8c8, MASKLWORD);
  656. p_dm_dig_table->big_jump_step1 = (u8)(ret_value & 0xe) >> 1;
  657. p_dm_dig_table->big_jump_step2 = (u8)(ret_value & 0x30) >> 4;
  658. p_dm_dig_table->big_jump_step3 = (u8)(ret_value & 0xc0) >> 6;
  659. } else if (p_dm_odm->support_ic_type & ODM_RTL8197F) {
  660. ret_value = odm_get_bb_reg(p_dm_odm, ODM_REG_BB_AGC_SET_2_11N, MASKLWORD);
  661. p_dm_dig_table->big_jump_step1 = (u8)(ret_value & 0xe) >> 1;
  662. p_dm_dig_table->big_jump_step2 = (u8)(ret_value & 0x30) >> 4;
  663. p_dm_dig_table->big_jump_step3 = (u8)(ret_value & 0xc0) >> 6;
  664. }
  665. if (p_dm_odm->support_ic_type & (ODM_RTL8822B | ODM_RTL8197F)) {
  666. for (i = 0; i < sizeof(p_dm_dig_table->big_jump_lmt); i++) {
  667. if (p_dm_dig_table->big_jump_lmt[i] == 0)
  668. p_dm_dig_table->big_jump_lmt[i] = 0x64; /* Set -10dBm as default value */
  669. }
  670. }
  671. #endif
  672. #if (DIG_HW == 1)
  673. p_dm_dig_table->pre_rssi_min = 0;
  674. #endif
  675. }
  676. void
  677. odm_DIG(
  678. void *p_dm_void
  679. )
  680. {
  681. struct PHY_DM_STRUCT *p_dm_odm = (struct PHY_DM_STRUCT *)p_dm_void;
  682. #if (DM_ODM_SUPPORT_TYPE & ODM_WIN)
  683. struct _ADAPTER *p_adapter = p_dm_odm->adapter;
  684. HAL_DATA_TYPE *p_hal_data = GET_HAL_DATA(p_dm_odm->adapter);
  685. #elif (DM_ODM_SUPPORT_TYPE & (ODM_AP))
  686. struct rtl8192cd_priv *priv = p_dm_odm->priv;
  687. struct sta_info *p_entry;
  688. #endif
  689. /* Common parameters */
  690. struct _dynamic_initial_gain_threshold_ *p_dm_dig_table = &p_dm_odm->dm_dig_table;
  691. struct _FALSE_ALARM_STATISTICS *p_false_alm_cnt = (struct _FALSE_ALARM_STATISTICS *)phydm_get_structure(p_dm_odm, PHYDM_FALSEALMCNT);
  692. boolean first_connect, first_dis_connect;
  693. u8 dig_max_of_min, dig_dynamic_min;
  694. u8 dm_dig_max, dm_dig_min;
  695. u8 current_igi = p_dm_dig_table->cur_ig_value;
  696. u8 offset;
  697. u32 dm_FA_thres[3];
  698. u32 tx_tp = 0, rx_tp = 0;
  699. boolean is_dfs_band = false;
  700. boolean is_performance = true, is_first_tp_target = false, is_first_coverage = false;
  701. #if (DM_ODM_SUPPORT_TYPE & (ODM_AP))
  702. u32 tp_train_th_min = dm_dig_tp_target_th0;
  703. static u8 time_cnt = 0;
  704. u8 i;
  705. #endif
  706. #if (DIG_HW == 1)
  707. boolean dig_go_up_check = true;
  708. u8 step_size_1 = 0, step_size_2 = 0, step_size_3 = 0;
  709. #endif
  710. if (odm_dig_abort(p_dm_odm) == true)
  711. return;
  712. ODM_RT_TRACE(p_dm_odm, ODM_COMP_DIG, ODM_DBG_LOUD, ("DIG Start===>\n"));
  713. #if (DIG_HW == 1)
  714. if (p_dm_odm->is_linked) {
  715. if (p_dm_dig_table->pre_rssi_min <= p_dm_odm->rssi_min) {
  716. step_size_1 = 2;
  717. step_size_2 = 1;
  718. step_size_3 = 2;
  719. } else {
  720. step_size_1 = 4;
  721. step_size_2 = 2;
  722. step_size_3 = 2;
  723. }
  724. p_dm_dig_table->pre_rssi_min = p_dm_odm->rssi_min;
  725. } else {
  726. step_size_1 = 2;
  727. step_size_2 = 1;
  728. step_size_3 = 2;
  729. }
  730. ODM_RT_TRACE(p_dm_odm, ODM_COMP_DIG, ODM_DBG_LOUD, ("rssi_min = %d, pre_rssi_min = %d\n", p_dm_odm->rssi_min, p_dm_dig_table->pre_rssi_min));
  731. ODM_RT_TRACE(p_dm_odm, ODM_COMP_DIG, ODM_DBG_LOUD, ("step_size_1 = %d, step_size_2 = %d, step_size_3 = %d\n", step_size_1, step_size_2, step_size_3));
  732. #endif
  733. /* 1 Update status */
  734. {
  735. dig_dynamic_min = p_dm_dig_table->dig_dynamic_min_0;
  736. first_connect = (p_dm_odm->is_linked) && (p_dm_dig_table->is_media_connect_0 == false);
  737. first_dis_connect = (!p_dm_odm->is_linked) && (p_dm_dig_table->is_media_connect_0 == true);
  738. }
  739. #if (DM_ODM_SUPPORT_TYPE & (ODM_AP))
  740. /* 1 Noise Floor Estimate */
  741. /* p_dm_dig_table->is_noise_est = (first_connect)?true:p_dm_dig_table->is_noise_est; */
  742. /* odm_inband_noise_calculate (p_dm_odm); */
  743. /* 1 mode decision */
  744. if (p_dm_odm->is_linked) {
  745. /* 2 Calculate total TP */
  746. for (i = 0; i < ODM_ASSOCIATE_ENTRY_NUM; i++) {
  747. p_entry = p_dm_odm->p_odm_sta_info[i];
  748. if (IS_STA_VALID(p_entry)) {
  749. rx_tp += (u32)(p_entry->rx_byte_cnt_low_maw >> 7);
  750. tx_tp += (u32)(p_entry->tx_byte_cnt_low_maw >> 7); /* Kbps */
  751. }
  752. }
  753. ODM_RT_TRACE(p_dm_odm, ODM_COMP_DIG, ODM_DBG_LOUD, ("DIG: TX TP = %dkbps, RX TP = %dkbps\n", tx_tp, rx_tp));
  754. }
  755. switch (p_dm_odm->priv->pshare->rf_ft_var.dig_cov_enable) {
  756. case 0:
  757. {
  758. is_performance = true;
  759. break;
  760. }
  761. case 1:
  762. {
  763. is_performance = false;
  764. break;
  765. }
  766. case 2:
  767. {
  768. if (p_dm_odm->is_linked) {
  769. if (p_dm_dig_table->tp_train_th_min > dm_dig_tp_target_th0)
  770. tp_train_th_min = p_dm_dig_table->tp_train_th_min;
  771. if (p_dm_dig_table->tp_train_th_min > dm_dig_tp_target_th1)
  772. tp_train_th_min = dm_dig_tp_target_th1;
  773. ODM_RT_TRACE(p_dm_odm, ODM_COMP_DIG, ODM_DBG_LOUD, ("DIG: TP training mode lower bound = %dkbps\n", tp_train_th_min));
  774. /* 2 Decide DIG mode by total TP */
  775. if ((tx_tp + rx_tp) > dm_dig_tp_target_th1) { /* change to performance mode */
  776. is_first_tp_target = (!p_dm_dig_table->is_tp_target) ? true : false;
  777. p_dm_dig_table->is_tp_target = true;
  778. is_performance = true;
  779. } else if ((tx_tp + rx_tp) < tp_train_th_min) { /* change to coverage mode */
  780. is_first_coverage = (p_dm_dig_table->is_tp_target) ? true : false;
  781. if (time_cnt < dm_dig_tp_training_period) {
  782. p_dm_dig_table->is_tp_target = false;
  783. is_performance = false;
  784. time_cnt++;
  785. } else {
  786. p_dm_dig_table->is_tp_target = true;
  787. is_performance = true;
  788. is_first_tp_target = true;
  789. time_cnt = 0;
  790. }
  791. } else { /* remain previous mode */
  792. is_performance = p_dm_dig_table->is_tp_target;
  793. if (!is_performance) {
  794. if (time_cnt < dm_dig_tp_training_period)
  795. time_cnt++;
  796. else {
  797. p_dm_dig_table->is_tp_target = true;
  798. is_performance = true;
  799. is_first_tp_target = true;
  800. time_cnt = 0;
  801. }
  802. }
  803. }
  804. if (!is_performance)
  805. p_dm_dig_table->tp_train_th_min = rx_tp + tx_tp;
  806. } else {
  807. is_performance = false;
  808. p_dm_dig_table->tp_train_th_min = 0;
  809. }
  810. break;
  811. }
  812. default:
  813. is_performance = true;
  814. }
  815. ODM_RT_TRACE(p_dm_odm, ODM_COMP_DIG, ODM_DBG_LOUD, ("====== DIG mode = %d ======\n", p_dm_odm->priv->pshare->rf_ft_var.dig_cov_enable));
  816. ODM_RT_TRACE(p_dm_odm, ODM_COMP_DIG, ODM_DBG_LOUD, ("====== is_performance = %d ======\n", is_performance));
  817. #endif
  818. /* 1 Boundary Decision */
  819. {
  820. #if (DM_ODM_SUPPORT_TYPE & (ODM_AP))
  821. /* 2 For AP\ADSL */
  822. if (!is_performance) {
  823. dm_dig_max = DM_DIG_MAX_AP_COVERAGR;
  824. dm_dig_min = DM_DIG_MIN_AP_COVERAGE;
  825. #if (DIG_HW == 1)
  826. dig_max_of_min = DM_DIG_MIN_AP_COVERAGE;
  827. #else
  828. dig_max_of_min = DM_DIG_MAX_OF_MIN_COVERAGE;
  829. #endif
  830. } else {
  831. if (p_dm_odm->rf_type == ODM_1T1R)
  832. dm_dig_max = DM_DIG_MAX_AP - 6;
  833. else
  834. dm_dig_max = DM_DIG_MAX_AP;
  835. if ((*p_dm_odm->p_band_type == ODM_BAND_2_4G) && (p_dm_odm->support_ic_type & ODM_RTL8814A)) /* for 2G 8814 */
  836. dm_dig_min = 0x1c;
  837. else if (p_dm_odm->support_ic_type & ODM_RTL8197F)
  838. dm_dig_min = 0x1e;
  839. else
  840. dm_dig_min = DM_DIG_MIN_AP;
  841. #if (DIG_HW == 1)
  842. dig_max_of_min = DM_DIG_MIN_AP_COVERAGE;
  843. #else
  844. dig_max_of_min = DM_DIG_MAX_OF_MIN;
  845. #endif
  846. }
  847. /* 4 TX2path */
  848. if (priv->pmib->dot11RFEntry.tx2path && !is_dfs_band && (*(p_dm_odm->p_wireless_mode) == ODM_WM_B))
  849. dm_dig_max = 0x2A;
  850. #if RTL8192E_SUPPORT
  851. #ifdef HIGH_POWER_EXT_LNA
  852. if ((p_dm_odm->support_ic_type & (ODM_RTL8192E)) && (p_dm_odm->ext_lna))
  853. dm_dig_max = 0x42;
  854. #endif
  855. #endif
  856. if (p_dm_odm->igi_lower_bound) {
  857. if (dm_dig_min < p_dm_odm->igi_lower_bound)
  858. dm_dig_min = p_dm_odm->igi_lower_bound;
  859. if (dig_max_of_min < p_dm_odm->igi_lower_bound)
  860. dig_max_of_min = p_dm_odm->igi_lower_bound;
  861. }
  862. if (p_dm_odm->igi_upper_bound) {
  863. if (dm_dig_max > p_dm_odm->igi_upper_bound)
  864. dm_dig_max = p_dm_odm->igi_upper_bound;
  865. if (dig_max_of_min > p_dm_odm->igi_upper_bound)
  866. dig_max_of_min = p_dm_odm->igi_upper_bound;
  867. }
  868. #else
  869. /* 2 For WIN\CE */
  870. if (p_dm_odm->support_ic_type >= ODM_RTL8188E)
  871. dm_dig_max = 0x5A;
  872. else
  873. dm_dig_max = DM_DIG_MAX_NIC;
  874. if (p_dm_odm->support_ic_type != ODM_RTL8821)
  875. dm_dig_min = DM_DIG_MIN_NIC;
  876. else
  877. dm_dig_min = 0x1C;
  878. dig_max_of_min = DM_DIG_MAX_AP;
  879. #endif
  880. #if (DM_ODM_SUPPORT_TYPE & (ODM_AP | ODM_CE))
  881. /* Modify lower bound for DFS band */
  882. if ((((*p_dm_odm->p_channel >= 52) && (*p_dm_odm->p_channel <= 64)) ||
  883. ((*p_dm_odm->p_channel >= 100) && (*p_dm_odm->p_channel <= 140)))
  884. #if (DM_ODM_SUPPORT_TYPE & (ODM_CE))
  885. && phydm_dfs_master_enabled(p_dm_odm) == true
  886. #endif
  887. ) {
  888. is_dfs_band = true;
  889. if (*p_dm_odm->p_band_width == ODM_BW20M)
  890. dm_dig_min = DM_DIG_MIN_AP_DFS + 2;
  891. else
  892. dm_dig_min = DM_DIG_MIN_AP_DFS;
  893. ODM_RT_TRACE(p_dm_odm, ODM_COMP_DIG, ODM_DBG_LOUD, ("DIG: ====== In DFS band ======\n"));
  894. }
  895. #endif
  896. }
  897. ODM_RT_TRACE(p_dm_odm, ODM_COMP_DIG, ODM_DBG_LOUD, ("DIG: Absolutly upper bound = 0x%x, lower bound = 0x%x\n", dm_dig_max, dm_dig_min));
  898. #if (DM_ODM_SUPPORT_TYPE & (ODM_WIN | ODM_CE))
  899. if (p_dm_odm->pu1_forced_igi_lb && (0 < *p_dm_odm->pu1_forced_igi_lb)) {
  900. ODM_RT_TRACE(p_dm_odm, ODM_COMP_DIG, ODM_DBG_LOUD, ("DIG: Force IGI lb to: 0x%02x\n", *p_dm_odm->pu1_forced_igi_lb));
  901. dm_dig_min = *p_dm_odm->pu1_forced_igi_lb;
  902. dm_dig_max = (dm_dig_min <= dm_dig_max) ? (dm_dig_max) : (dm_dig_min + 1);
  903. }
  904. #endif
  905. /* 1 Adjust boundary by RSSI */
  906. if (p_dm_odm->is_linked && is_performance) {
  907. /* 2 Modify DIG upper bound */
  908. #if (DM_ODM_SUPPORT_TYPE & (ODM_AP))
  909. offset = 15;
  910. #else
  911. /* 4 Modify DIG upper bound for 92E, 8723A\B, 8821 & 8812 BT */
  912. if ((p_dm_odm->support_ic_type & (ODM_RTL8192E | ODM_RTL8723B | ODM_RTL8812 | ODM_RTL8821)) && (p_dm_odm->is_bt_limited_dig == 1)) {
  913. offset = 10;
  914. ODM_RT_TRACE(p_dm_odm, ODM_COMP_DIG, ODM_DBG_LOUD, ("DIG: Coex. case: Force upper bound to RSSI + %d\n", offset));
  915. } else
  916. offset = 15;
  917. #endif
  918. if ((p_dm_odm->rssi_min + offset) > dm_dig_max)
  919. p_dm_dig_table->rx_gain_range_max = dm_dig_max;
  920. else if ((p_dm_odm->rssi_min + offset) < dm_dig_min)
  921. p_dm_dig_table->rx_gain_range_max = dm_dig_min;
  922. else
  923. p_dm_dig_table->rx_gain_range_max = p_dm_odm->rssi_min + offset;
  924. #if (DM_ODM_SUPPORT_TYPE & (ODM_WIN | ODM_CE))
  925. /* 2 Modify DIG lower bound */
  926. /* if(p_dm_odm->is_one_entry_only) */
  927. {
  928. if (p_dm_odm->rssi_min < dm_dig_min)
  929. dig_dynamic_min = dm_dig_min;
  930. else if (p_dm_odm->rssi_min > dig_max_of_min)
  931. dig_dynamic_min = dig_max_of_min;
  932. else
  933. dig_dynamic_min = p_dm_odm->rssi_min;
  934. #if (DM_ODM_SUPPORT_TYPE & ODM_CE)
  935. if (is_dfs_band) {
  936. dig_dynamic_min = dm_dig_min;
  937. ODM_RT_TRACE(p_dm_odm, ODM_COMP_DIG, ODM_DBG_LOUD, ("DIG: DFS band: Force lower bound to 0x%x after link\n", dm_dig_min));
  938. }
  939. #endif
  940. }
  941. #else
  942. {
  943. /* 4 For AP */
  944. #ifdef __ECOS
  945. HAL_REORDER_BARRIER();
  946. #else
  947. rmb();
  948. #endif
  949. if (is_dfs_band) {
  950. dig_dynamic_min = dm_dig_min;
  951. ODM_RT_TRACE(p_dm_odm, ODM_COMP_DIG, ODM_DBG_LOUD, ("DIG: DFS band: Force lower bound to 0x%x after link\n", dm_dig_min));
  952. } else {
  953. if (p_dm_odm->rssi_min < dm_dig_min)
  954. dig_dynamic_min = dm_dig_min;
  955. else if (p_dm_odm->rssi_min > dig_max_of_min)
  956. dig_dynamic_min = dig_max_of_min;
  957. else
  958. dig_dynamic_min = p_dm_odm->rssi_min;
  959. }
  960. }
  961. #endif
  962. } else {
  963. #if (DM_ODM_SUPPORT_TYPE & (ODM_AP | ODM_CE))
  964. if (is_performance && is_dfs_band) {
  965. p_dm_dig_table->rx_gain_range_max = 0x28;
  966. ODM_RT_TRACE(p_dm_odm, ODM_COMP_DIG, ODM_DBG_LOUD, ("DIG: DFS band: Force upper bound to 0x%x before link\n", p_dm_dig_table->rx_gain_range_max));
  967. } else
  968. #endif
  969. {
  970. if (is_performance)
  971. p_dm_dig_table->rx_gain_range_max = DM_DIG_MAX_OF_MIN;
  972. else
  973. p_dm_dig_table->rx_gain_range_max = dm_dig_max;
  974. }
  975. dig_dynamic_min = dm_dig_min;
  976. }
  977. /* 1 Force Lower Bound for AntDiv */
  978. if (p_dm_odm->is_linked && !p_dm_odm->is_one_entry_only) {
  979. if ((p_dm_odm->support_ic_type & ODM_ANTDIV_SUPPORT) && (p_dm_odm->support_ability & ODM_BB_ANT_DIV)) {
  980. if (p_dm_odm->ant_div_type == CG_TRX_HW_ANTDIV || p_dm_odm->ant_div_type == CG_TRX_SMART_ANTDIV) {
  981. if (p_dm_dig_table->ant_div_rssi_max > dig_max_of_min)
  982. dig_dynamic_min = dig_max_of_min;
  983. else
  984. dig_dynamic_min = (u8) p_dm_dig_table->ant_div_rssi_max;
  985. ODM_RT_TRACE(p_dm_odm, ODM_COMP_DIG, ODM_DBG_LOUD, ("DIG: AntDiv case: Force lower bound to 0x%x\n", dig_dynamic_min));
  986. ODM_RT_TRACE(p_dm_odm, ODM_COMP_DIG, ODM_DBG_LOUD, ("DIG: AntDiv case: RSSI_max = 0x%x\n", p_dm_dig_table->ant_div_rssi_max));
  987. }
  988. }
  989. }
  990. ODM_RT_TRACE(p_dm_odm, ODM_COMP_DIG, ODM_DBG_LOUD, ("DIG: Adjust boundary by RSSI Upper bound = 0x%x, Lower bound = 0x%x\n",
  991. p_dm_dig_table->rx_gain_range_max, dig_dynamic_min));
  992. ODM_RT_TRACE(p_dm_odm, ODM_COMP_DIG, ODM_DBG_LOUD, ("DIG: Link status: is_linked = %d, RSSI = %d, bFirstConnect = %d, bFirsrDisConnect = %d\n",
  993. p_dm_odm->is_linked, p_dm_odm->rssi_min, first_connect, first_dis_connect));
  994. /* 1 Modify DIG lower bound, deal with abnormal case */
  995. /* 2 Abnormal false alarm case */
  996. #if (DM_ODM_SUPPORT_TYPE & (ODM_AP | ODM_CE))
  997. if (is_dfs_band)
  998. p_dm_dig_table->rx_gain_range_min = dig_dynamic_min;
  999. else
  1000. #endif
  1001. {
  1002. if (!p_dm_odm->is_linked) {
  1003. p_dm_dig_table->rx_gain_range_min = dig_dynamic_min;
  1004. if (first_dis_connect)
  1005. p_dm_dig_table->forbidden_igi = dig_dynamic_min;
  1006. } else
  1007. p_dm_dig_table->rx_gain_range_min = odm_forbidden_igi_check(p_dm_odm, dig_dynamic_min, current_igi);
  1008. }
  1009. /* 2 Abnormal # beacon case */
  1010. #if (DM_ODM_SUPPORT_TYPE & (ODM_WIN | ODM_CE))
  1011. if (p_dm_odm->is_linked && !first_connect) {
  1012. ODM_RT_TRACE(p_dm_odm, ODM_COMP_DIG, ODM_DBG_LOUD, ("Beacon Num (%d)\n", p_dm_odm->phy_dbg_info.num_qry_beacon_pkt));
  1013. if ((p_dm_odm->phy_dbg_info.num_qry_beacon_pkt < 5) && (p_dm_odm->bsta_state)) {
  1014. p_dm_dig_table->rx_gain_range_min = 0x1c;
  1015. ODM_RT_TRACE(p_dm_odm, ODM_COMP_DIG, ODM_DBG_LOUD, ("DIG: Abnrormal #beacon (%d) case in STA mode: Force lower bound to 0x%x\n",
  1016. p_dm_odm->phy_dbg_info.num_qry_beacon_pkt, p_dm_dig_table->rx_gain_range_min));
  1017. }
  1018. }
  1019. #endif
  1020. /* 2 Abnormal lower bound case */
  1021. if (p_dm_dig_table->rx_gain_range_min > p_dm_dig_table->rx_gain_range_max) {
  1022. p_dm_dig_table->rx_gain_range_min = p_dm_dig_table->rx_gain_range_max;
  1023. ODM_RT_TRACE(p_dm_odm, ODM_COMP_DIG, ODM_DBG_LOUD, ("DIG: Abnrormal lower bound case: Force lower bound to 0x%x\n", p_dm_dig_table->rx_gain_range_min));
  1024. }
  1025. /* 1 False alarm threshold decision */
  1026. odm_fa_threshold_check(p_dm_odm, is_dfs_band, is_performance, rx_tp, tx_tp, dm_FA_thres);
  1027. ODM_RT_TRACE(p_dm_odm, ODM_COMP_DIG, ODM_DBG_LOUD, ("DIG: False alarm threshold = %d, %d, %d\n", dm_FA_thres[0], dm_FA_thres[1], dm_FA_thres[2]));
  1028. /* 1 Adjust initial gain by false alarm */
  1029. if (p_dm_odm->is_linked && is_performance) {
  1030. /* 2 After link */
  1031. ODM_RT_TRACE(p_dm_odm, ODM_COMP_DIG, ODM_DBG_LOUD, ("DIG: Adjust IGI after link\n"));
  1032. if (is_first_tp_target || (first_connect && is_performance)) {
  1033. p_dm_dig_table->large_fa_hit = 0;
  1034. #if (DM_ODM_SUPPORT_TYPE & (ODM_AP | ODM_CE))
  1035. if (is_dfs_band) {
  1036. if (p_dm_odm->rssi_min > 0x28)
  1037. current_igi = 0x28;
  1038. else
  1039. current_igi = p_dm_odm->rssi_min;
  1040. ODM_RT_TRACE(p_dm_odm, ODM_COMP_DIG, ODM_DBG_LOUD, ("DIG: DFS band: One-shot to 0x28 upmost\n"));
  1041. } else
  1042. #endif
  1043. {
  1044. if (p_dm_odm->rssi_min < dig_max_of_min) {
  1045. if (current_igi < p_dm_odm->rssi_min)
  1046. current_igi = p_dm_odm->rssi_min;
  1047. } else {
  1048. if (current_igi < dig_max_of_min)
  1049. current_igi = dig_max_of_min;
  1050. }
  1051. #if (DM_ODM_SUPPORT_TYPE & (ODM_WIN | ODM_CE))
  1052. #if (RTL8812A_SUPPORT == 1)
  1053. if (p_dm_odm->support_ic_type == ODM_RTL8812)
  1054. odm_config_bb_with_header_file(p_dm_odm, CONFIG_BB_AGC_TAB_DIFF);
  1055. #endif
  1056. #endif
  1057. }
  1058. ODM_RT_TRACE(p_dm_odm, ODM_COMP_DIG, ODM_DBG_LOUD, ("DIG: First connect case: IGI does on-shot to 0x%x\n", current_igi));
  1059. } else {
  1060. #if ((DM_ODM_SUPPORT_TYPE & (ODM_AP)) && (DIG_HW == 1))
  1061. if (priv->pshare->rf_ft_var.dig_upcheck_enable)
  1062. dig_go_up_check = phydm_dig_go_up_check(p_dm_odm);
  1063. #endif
  1064. #if (DIG_HW == 1)
  1065. if ((p_false_alm_cnt->cnt_all > dm_FA_thres[2]) && dig_go_up_check)
  1066. current_igi = current_igi + step_size_1;
  1067. else if ((p_false_alm_cnt->cnt_all > dm_FA_thres[1]) && dig_go_up_check)
  1068. current_igi = current_igi + step_size_2;
  1069. else if (p_false_alm_cnt->cnt_all < dm_FA_thres[0])
  1070. current_igi = current_igi - step_size_3;
  1071. #else
  1072. if (p_false_alm_cnt->cnt_all > dm_FA_thres[2])
  1073. current_igi = current_igi + 4;
  1074. else if (p_false_alm_cnt->cnt_all > dm_FA_thres[1])
  1075. current_igi = current_igi + 2;
  1076. else if (p_false_alm_cnt->cnt_all < dm_FA_thres[0])
  1077. current_igi = current_igi - 2;
  1078. #endif
  1079. /* 4 Abnormal # beacon case */
  1080. #if (DM_ODM_SUPPORT_TYPE & (ODM_WIN | ODM_CE))
  1081. if ((p_dm_odm->phy_dbg_info.num_qry_beacon_pkt < 5) && (p_false_alm_cnt->cnt_all < DM_DIG_FA_TH1) && (p_dm_odm->bsta_state)) {
  1082. current_igi = p_dm_dig_table->rx_gain_range_min;
  1083. ODM_RT_TRACE(p_dm_odm, ODM_COMP_DIG, ODM_DBG_LOUD, ("DIG: Abnormal #beacon (%d) case: IGI does one-shot to 0x%x\n",
  1084. p_dm_odm->phy_dbg_info.num_qry_beacon_pkt, current_igi));
  1085. }
  1086. #endif
  1087. }
  1088. } else {
  1089. /* 2 Before link */
  1090. ODM_RT_TRACE(p_dm_odm, ODM_COMP_DIG, ODM_DBG_LOUD, ("DIG: Adjust IGI before link\n"));
  1091. if (first_dis_connect || is_first_coverage) {
  1092. current_igi = dm_dig_min;
  1093. ODM_RT_TRACE(p_dm_odm, ODM_COMP_DIG, ODM_DBG_LOUD, ("DIG: First disconnect case: IGI does on-shot to lower bound\n"));
  1094. } else {
  1095. #if ((DM_ODM_SUPPORT_TYPE & (ODM_AP)) && (DIG_HW == 1))
  1096. if (priv->pshare->rf_ft_var.dig_upcheck_enable)
  1097. dig_go_up_check = phydm_dig_go_up_check(p_dm_odm);
  1098. #endif
  1099. #if (DIG_HW == 1)
  1100. if ((p_false_alm_cnt->cnt_all > dm_FA_thres[2]) && dig_go_up_check)
  1101. current_igi = current_igi + step_size_1;
  1102. else if ((p_false_alm_cnt->cnt_all > dm_FA_thres[1]) && dig_go_up_check)
  1103. current_igi = current_igi + step_size_2;
  1104. else if (p_false_alm_cnt->cnt_all < dm_FA_thres[0])
  1105. current_igi = current_igi - step_size_3;
  1106. #else
  1107. if (p_false_alm_cnt->cnt_all > dm_FA_thres[2])
  1108. current_igi = current_igi + 4;
  1109. else if (p_false_alm_cnt->cnt_all > dm_FA_thres[1])
  1110. current_igi = current_igi + 2;
  1111. else if (p_false_alm_cnt->cnt_all < dm_FA_thres[0])
  1112. current_igi = current_igi - 2;
  1113. #endif
  1114. }
  1115. }
  1116. /* 1 Check initial gain by upper/lower bound */
  1117. if (current_igi < p_dm_dig_table->rx_gain_range_min)
  1118. current_igi = p_dm_dig_table->rx_gain_range_min;
  1119. if (current_igi > p_dm_dig_table->rx_gain_range_max)
  1120. current_igi = p_dm_dig_table->rx_gain_range_max;
  1121. ODM_RT_TRACE(p_dm_odm, ODM_COMP_DIG, ODM_DBG_LOUD, ("DIG: cur_ig_value=0x%x, TotalFA = %d\n", current_igi, p_false_alm_cnt->cnt_all));
  1122. /* 1 Update status */
  1123. {
  1124. #if ((DM_ODM_SUPPORT_TYPE & ODM_WIN) || ((DM_ODM_SUPPORT_TYPE & ODM_CE) && (ODM_CONFIG_BT_COEXIST == 1)))
  1125. if (p_dm_odm->is_bt_hs_operation) {
  1126. if (p_dm_odm->is_linked) {
  1127. if (p_dm_dig_table->bt30_cur_igi > (current_igi))
  1128. odm_write_dig(p_dm_odm, current_igi);
  1129. else
  1130. odm_write_dig(p_dm_odm, p_dm_dig_table->bt30_cur_igi);
  1131. p_dm_dig_table->is_media_connect_0 = p_dm_odm->is_linked;
  1132. p_dm_dig_table->dig_dynamic_min_0 = dig_dynamic_min;
  1133. } else {
  1134. if (p_dm_odm->is_link_in_process)
  1135. odm_write_dig(p_dm_odm, 0x1c);
  1136. else if (p_dm_odm->is_bt_connect_process)
  1137. odm_write_dig(p_dm_odm, 0x28);
  1138. else
  1139. odm_write_dig(p_dm_odm, p_dm_dig_table->bt30_cur_igi);/* odm_write_dig(p_dm_odm, p_dm_dig_table->cur_ig_value); */
  1140. }
  1141. } else /* BT is not using */
  1142. #endif
  1143. {
  1144. odm_write_dig(p_dm_odm, current_igi);/* odm_write_dig(p_dm_odm, p_dm_dig_table->cur_ig_value); */
  1145. p_dm_dig_table->is_media_connect_0 = p_dm_odm->is_linked;
  1146. p_dm_dig_table->dig_dynamic_min_0 = dig_dynamic_min;
  1147. }
  1148. }
  1149. ODM_RT_TRACE(p_dm_odm, ODM_COMP_DIG, ODM_DBG_LOUD, ("DIG end\n"));
  1150. }
  1151. void
  1152. odm_dig_by_rssi_lps(
  1153. void *p_dm_void
  1154. )
  1155. {
  1156. #if (DM_ODM_SUPPORT_TYPE & (ODM_WIN | ODM_CE))
  1157. struct PHY_DM_STRUCT *p_dm_odm = (struct PHY_DM_STRUCT *)p_dm_void;
  1158. struct _FALSE_ALARM_STATISTICS *p_false_alm_cnt = (struct _FALSE_ALARM_STATISTICS *)phydm_get_structure(p_dm_odm, PHYDM_FALSEALMCNT);
  1159. u8 rssi_lower = DM_DIG_MIN_NIC; /* 0x1E or 0x1C */
  1160. u8 current_igi = p_dm_odm->rssi_min;
  1161. if (odm_dig_abort(p_dm_odm) == true)
  1162. return;
  1163. current_igi = current_igi + RSSI_OFFSET_DIG;
  1164. ODM_RT_TRACE(p_dm_odm, ODM_COMP_DIG, ODM_DBG_LOUD, ("odm_dig_by_rssi_lps()==>\n"));
  1165. /* Using FW PS mode to make IGI */
  1166. /* Adjust by FA in LPS MODE */
  1167. if (p_false_alm_cnt->cnt_all > DM_DIG_FA_TH2_LPS)
  1168. current_igi = current_igi + 4;
  1169. else if (p_false_alm_cnt->cnt_all > DM_DIG_FA_TH1_LPS)
  1170. current_igi = current_igi + 2;
  1171. else if (p_false_alm_cnt->cnt_all < DM_DIG_FA_TH0_LPS)
  1172. current_igi = current_igi - 2;
  1173. /* Lower bound checking */
  1174. /* RSSI Lower bound check */
  1175. if ((p_dm_odm->rssi_min - 10) > DM_DIG_MIN_NIC)
  1176. rssi_lower = (p_dm_odm->rssi_min - 10);
  1177. else
  1178. rssi_lower = DM_DIG_MIN_NIC;
  1179. /* Upper and Lower Bound checking */
  1180. if (current_igi > DM_DIG_MAX_NIC)
  1181. current_igi = DM_DIG_MAX_NIC;
  1182. else if (current_igi < rssi_lower)
  1183. current_igi = rssi_lower;
  1184. ODM_RT_TRACE(p_dm_odm, ODM_COMP_DIG, ODM_DBG_LOUD, ("odm_dig_by_rssi_lps(): p_false_alm_cnt->cnt_all = %d\n", p_false_alm_cnt->cnt_all));
  1185. ODM_RT_TRACE(p_dm_odm, ODM_COMP_DIG, ODM_DBG_LOUD, ("odm_dig_by_rssi_lps(): p_dm_odm->rssi_min = %d\n", p_dm_odm->rssi_min));
  1186. ODM_RT_TRACE(p_dm_odm, ODM_COMP_DIG, ODM_DBG_LOUD, ("odm_dig_by_rssi_lps(): current_igi = 0x%x\n", current_igi));
  1187. odm_write_dig(p_dm_odm, current_igi);/* odm_write_dig(p_dm_odm, p_dm_dig_table->cur_ig_value); */
  1188. #endif
  1189. }
  1190. /* 3============================================================
  1191. * 3 FASLE ALARM CHECK
  1192. * 3============================================================ */
  1193. void
  1194. odm_false_alarm_counter_statistics(
  1195. void *p_dm_void
  1196. )
  1197. {
  1198. struct PHY_DM_STRUCT *p_dm_odm = (struct PHY_DM_STRUCT *)p_dm_void;
  1199. struct _FALSE_ALARM_STATISTICS *false_alm_cnt = (struct _FALSE_ALARM_STATISTICS *)phydm_get_structure(p_dm_odm, PHYDM_FALSEALMCNT);
  1200. struct _ADAPTIVITY_STATISTICS *adaptivity = (struct _ADAPTIVITY_STATISTICS *)phydm_get_structure(p_dm_odm, PHYDM_ADAPTIVITY);
  1201. u32 ret_value;
  1202. #if (DM_ODM_SUPPORT_TYPE == ODM_AP)
  1203. /* Mark there, and check this in odm_DMWatchDog */
  1204. #if 0 /* (DM_ODM_SUPPORT_TYPE == ODM_AP) */
  1205. struct rtl8192cd_priv *priv = p_dm_odm->priv;
  1206. if ((priv->auto_channel != 0) && (priv->auto_channel != 2))
  1207. return;
  1208. #endif
  1209. #endif
  1210. if (!(p_dm_odm->support_ability & ODM_BB_FA_CNT))
  1211. return;
  1212. ODM_RT_TRACE(p_dm_odm, ODM_COMP_FA_CNT, ODM_DBG_LOUD, ("FA_Counter()======>\n"));
  1213. #if (ODM_IC_11N_SERIES_SUPPORT == 1)
  1214. if (p_dm_odm->support_ic_type & ODM_IC_11N_SERIES) {
  1215. /* hold ofdm counter */
  1216. odm_set_bb_reg(p_dm_odm, ODM_REG_OFDM_FA_HOLDC_11N, BIT(31), 1); /* hold page C counter */
  1217. odm_set_bb_reg(p_dm_odm, ODM_REG_OFDM_FA_RSTD_11N, BIT(31), 1); /* hold page D counter */
  1218. ret_value = odm_get_bb_reg(p_dm_odm, ODM_REG_OFDM_FA_TYPE1_11N, MASKDWORD);
  1219. false_alm_cnt->cnt_fast_fsync = (ret_value & 0xffff);
  1220. false_alm_cnt->cnt_sb_search_fail = ((ret_value & 0xffff0000) >> 16);
  1221. ret_value = odm_get_bb_reg(p_dm_odm, ODM_REG_OFDM_FA_TYPE2_11N, MASKDWORD);
  1222. false_alm_cnt->cnt_ofdm_cca = (ret_value & 0xffff);
  1223. false_alm_cnt->cnt_parity_fail = ((ret_value & 0xffff0000) >> 16);
  1224. ret_value = odm_get_bb_reg(p_dm_odm, ODM_REG_OFDM_FA_TYPE3_11N, MASKDWORD);
  1225. false_alm_cnt->cnt_rate_illegal = (ret_value & 0xffff);
  1226. false_alm_cnt->cnt_crc8_fail = ((ret_value & 0xffff0000) >> 16);
  1227. ret_value = odm_get_bb_reg(p_dm_odm, ODM_REG_OFDM_FA_TYPE4_11N, MASKDWORD);
  1228. false_alm_cnt->cnt_mcs_fail = (ret_value & 0xffff);
  1229. false_alm_cnt->cnt_ofdm_fail = false_alm_cnt->cnt_parity_fail + false_alm_cnt->cnt_rate_illegal +
  1230. false_alm_cnt->cnt_crc8_fail + false_alm_cnt->cnt_mcs_fail +
  1231. false_alm_cnt->cnt_fast_fsync + false_alm_cnt->cnt_sb_search_fail;
  1232. /* read CCK CRC32 counter */
  1233. false_alm_cnt->cnt_cck_crc32_error = odm_get_bb_reg(p_dm_odm, ODM_REG_CCK_CRC32_ERROR_CNT_11N, MASKDWORD);
  1234. false_alm_cnt->cnt_cck_crc32_ok = odm_get_bb_reg(p_dm_odm, ODM_REG_CCK_CRC32_OK_CNT_11N, MASKDWORD);
  1235. /* read OFDM CRC32 counter */
  1236. ret_value = odm_get_bb_reg(p_dm_odm, ODM_REG_OFDM_CRC32_CNT_11N, MASKDWORD);
  1237. false_alm_cnt->cnt_ofdm_crc32_error = (ret_value & 0xffff0000) >> 16;
  1238. false_alm_cnt->cnt_ofdm_crc32_ok = ret_value & 0xffff;
  1239. /* read HT CRC32 counter */
  1240. ret_value = odm_get_bb_reg(p_dm_odm, ODM_REG_HT_CRC32_CNT_11N, MASKDWORD);
  1241. false_alm_cnt->cnt_ht_crc32_error = (ret_value & 0xffff0000) >> 16;
  1242. false_alm_cnt->cnt_ht_crc32_ok = ret_value & 0xffff;
  1243. /* read VHT CRC32 counter */
  1244. false_alm_cnt->cnt_vht_crc32_error = 0;
  1245. false_alm_cnt->cnt_vht_crc32_ok = 0;
  1246. #if (RTL8188E_SUPPORT == 1)
  1247. if (p_dm_odm->support_ic_type == ODM_RTL8188E) {
  1248. ret_value = odm_get_bb_reg(p_dm_odm, ODM_REG_SC_CNT_11N, MASKDWORD);
  1249. false_alm_cnt->cnt_bw_lsc = (ret_value & 0xffff);
  1250. false_alm_cnt->cnt_bw_usc = ((ret_value & 0xffff0000) >> 16);
  1251. }
  1252. #endif
  1253. {
  1254. /* hold cck counter */
  1255. odm_set_bb_reg(p_dm_odm, ODM_REG_CCK_FA_RST_11N, BIT(12), 1);
  1256. odm_set_bb_reg(p_dm_odm, ODM_REG_CCK_FA_RST_11N, BIT(14), 1);
  1257. ret_value = odm_get_bb_reg(p_dm_odm, ODM_REG_CCK_FA_LSB_11N, MASKBYTE0);
  1258. false_alm_cnt->cnt_cck_fail = ret_value;
  1259. ret_value = odm_get_bb_reg(p_dm_odm, ODM_REG_CCK_FA_MSB_11N, MASKBYTE3);
  1260. false_alm_cnt->cnt_cck_fail += (ret_value & 0xff) << 8;
  1261. ret_value = odm_get_bb_reg(p_dm_odm, ODM_REG_CCK_CCA_CNT_11N, MASKDWORD);
  1262. false_alm_cnt->cnt_cck_cca = ((ret_value & 0xFF) << 8) | ((ret_value & 0xFF00) >> 8);
  1263. }
  1264. false_alm_cnt->cnt_all_pre = false_alm_cnt->cnt_all;
  1265. false_alm_cnt->cnt_all = (false_alm_cnt->cnt_fast_fsync +
  1266. false_alm_cnt->cnt_sb_search_fail +
  1267. false_alm_cnt->cnt_parity_fail +
  1268. false_alm_cnt->cnt_rate_illegal +
  1269. false_alm_cnt->cnt_crc8_fail +
  1270. false_alm_cnt->cnt_mcs_fail +
  1271. false_alm_cnt->cnt_cck_fail);
  1272. false_alm_cnt->cnt_cca_all = false_alm_cnt->cnt_ofdm_cca + false_alm_cnt->cnt_cck_cca;
  1273. if (p_dm_odm->support_ic_type >= ODM_RTL8188E) {
  1274. /*reset false alarm counter registers*/
  1275. odm_set_bb_reg(p_dm_odm, ODM_REG_OFDM_FA_RSTC_11N, BIT(31), 1);
  1276. odm_set_bb_reg(p_dm_odm, ODM_REG_OFDM_FA_RSTC_11N, BIT(31), 0);
  1277. odm_set_bb_reg(p_dm_odm, ODM_REG_OFDM_FA_RSTD_11N, BIT(27), 1);
  1278. odm_set_bb_reg(p_dm_odm, ODM_REG_OFDM_FA_RSTD_11N, BIT(27), 0);
  1279. /*update ofdm counter*/
  1280. odm_set_bb_reg(p_dm_odm, ODM_REG_OFDM_FA_HOLDC_11N, BIT(31), 0); /*update page C counter*/
  1281. odm_set_bb_reg(p_dm_odm, ODM_REG_OFDM_FA_RSTD_11N, BIT(31), 0); /*update page D counter*/
  1282. /*reset CCK CCA counter*/
  1283. odm_set_bb_reg(p_dm_odm, ODM_REG_CCK_FA_RST_11N, BIT(13) | BIT(12), 0);
  1284. odm_set_bb_reg(p_dm_odm, ODM_REG_CCK_FA_RST_11N, BIT(13) | BIT(12), 2);
  1285. /*reset CCK FA counter*/
  1286. odm_set_bb_reg(p_dm_odm, ODM_REG_CCK_FA_RST_11N, BIT(15) | BIT(14), 0);
  1287. odm_set_bb_reg(p_dm_odm, ODM_REG_CCK_FA_RST_11N, BIT(15) | BIT(14), 2);
  1288. /*reset CRC32 counter*/
  1289. odm_set_bb_reg(p_dm_odm, ODM_REG_PAGE_F_RST_11N, BIT(16), 1);
  1290. odm_set_bb_reg(p_dm_odm, ODM_REG_PAGE_F_RST_11N, BIT(16), 0);
  1291. }
  1292. ODM_RT_TRACE(p_dm_odm, ODM_COMP_FA_CNT, ODM_DBG_LOUD, ("[OFDM FA Detail] Parity_Fail = (( %d )), Rate_Illegal = (( %d )), CRC8_fail = (( %d )), Mcs_fail = (( %d )), Fast_Fsync = (( %d )), SB_Search_fail = (( %d ))\n",
  1293. false_alm_cnt->cnt_parity_fail, false_alm_cnt->cnt_rate_illegal, false_alm_cnt->cnt_crc8_fail, false_alm_cnt->cnt_mcs_fail, false_alm_cnt->cnt_fast_fsync, false_alm_cnt->cnt_sb_search_fail));
  1294. }
  1295. #endif
  1296. #if (ODM_IC_11AC_SERIES_SUPPORT == 1)
  1297. if (p_dm_odm->support_ic_type & ODM_IC_11AC_SERIES) {
  1298. u32 cck_enable;
  1299. /* read OFDM FA counter */
  1300. false_alm_cnt->cnt_ofdm_fail = odm_get_bb_reg(p_dm_odm, ODM_REG_OFDM_FA_11AC, MASKLWORD);
  1301. /* Read CCK FA counter */
  1302. false_alm_cnt->cnt_cck_fail = odm_get_bb_reg(p_dm_odm, ODM_REG_CCK_FA_11AC, MASKLWORD);
  1303. /* read CCK/OFDM CCA counter */
  1304. ret_value = odm_get_bb_reg(p_dm_odm, ODM_REG_CCK_CCA_CNT_11AC, MASKDWORD);
  1305. false_alm_cnt->cnt_ofdm_cca = (ret_value & 0xffff0000) >> 16;
  1306. false_alm_cnt->cnt_cck_cca = ret_value & 0xffff;
  1307. /* read CCK CRC32 counter */
  1308. ret_value = odm_get_bb_reg(p_dm_odm, ODM_REG_CCK_CRC32_CNT_11AC, MASKDWORD);
  1309. false_alm_cnt->cnt_cck_crc32_error = (ret_value & 0xffff0000) >> 16;
  1310. false_alm_cnt->cnt_cck_crc32_ok = ret_value & 0xffff;
  1311. /* read OFDM CRC32 counter */
  1312. ret_value = odm_get_bb_reg(p_dm_odm, ODM_REG_OFDM_CRC32_CNT_11AC, MASKDWORD);
  1313. false_alm_cnt->cnt_ofdm_crc32_error = (ret_value & 0xffff0000) >> 16;
  1314. false_alm_cnt->cnt_ofdm_crc32_ok = ret_value & 0xffff;
  1315. /* read HT CRC32 counter */
  1316. ret_value = odm_get_bb_reg(p_dm_odm, ODM_REG_HT_CRC32_CNT_11AC, MASKDWORD);
  1317. false_alm_cnt->cnt_ht_crc32_error = (ret_value & 0xffff0000) >> 16;
  1318. false_alm_cnt->cnt_ht_crc32_ok = ret_value & 0xffff;
  1319. /* read VHT CRC32 counter */
  1320. ret_value = odm_get_bb_reg(p_dm_odm, ODM_REG_VHT_CRC32_CNT_11AC, MASKDWORD);
  1321. false_alm_cnt->cnt_vht_crc32_error = (ret_value & 0xffff0000) >> 16;
  1322. false_alm_cnt->cnt_vht_crc32_ok = ret_value & 0xffff;
  1323. #if (RTL8881A_SUPPORT == 1)
  1324. /* For 8881A */
  1325. if (p_dm_odm->support_ic_type == ODM_RTL8881A) {
  1326. u32 cnt_ofdm_fail_temp = 0;
  1327. if (false_alm_cnt->cnt_ofdm_fail >= false_alm_cnt->cnt_ofdm_fail_pre) {
  1328. cnt_ofdm_fail_temp = false_alm_cnt->cnt_ofdm_fail_pre;
  1329. false_alm_cnt->cnt_ofdm_fail_pre = false_alm_cnt->cnt_ofdm_fail;
  1330. false_alm_cnt->cnt_ofdm_fail = false_alm_cnt->cnt_ofdm_fail - cnt_ofdm_fail_temp;
  1331. } else
  1332. false_alm_cnt->cnt_ofdm_fail_pre = false_alm_cnt->cnt_ofdm_fail;
  1333. ODM_RT_TRACE(p_dm_odm, ODM_COMP_FA_CNT, ODM_DBG_LOUD, ("odm_false_alarm_counter_statistics(): cnt_ofdm_fail=%d\n", false_alm_cnt->cnt_ofdm_fail_pre));
  1334. ODM_RT_TRACE(p_dm_odm, ODM_COMP_FA_CNT, ODM_DBG_LOUD, ("odm_false_alarm_counter_statistics(): cnt_ofdm_fail_pre=%d\n", cnt_ofdm_fail_temp));
  1335. /* Reset FA counter by enable/disable OFDM */
  1336. if (false_alm_cnt->cnt_ofdm_fail_pre >= 0x7fff) {
  1337. /* reset OFDM */
  1338. odm_set_bb_reg(p_dm_odm, ODM_REG_BB_RX_PATH_11AC, BIT(29), 0);
  1339. odm_set_bb_reg(p_dm_odm, ODM_REG_BB_RX_PATH_11AC, BIT(29), 1);
  1340. false_alm_cnt->cnt_ofdm_fail_pre = 0;
  1341. ODM_RT_TRACE(p_dm_odm, ODM_COMP_FA_CNT, ODM_DBG_LOUD, ("odm_false_alarm_counter_statistics(): Reset false alarm counter\n"));
  1342. }
  1343. }
  1344. #endif
  1345. /* reset OFDM FA coutner */
  1346. odm_set_bb_reg(p_dm_odm, ODM_REG_OFDM_FA_RST_11AC, BIT(17), 1);
  1347. odm_set_bb_reg(p_dm_odm, ODM_REG_OFDM_FA_RST_11AC, BIT(17), 0);
  1348. /* reset CCK FA counter */
  1349. odm_set_bb_reg(p_dm_odm, ODM_REG_CCK_FA_RST_11AC, BIT(15), 0);
  1350. odm_set_bb_reg(p_dm_odm, ODM_REG_CCK_FA_RST_11AC, BIT(15), 1);
  1351. /* reset CCA counter */
  1352. odm_set_bb_reg(p_dm_odm, ODM_REG_RST_RPT_11AC, BIT(0), 1);
  1353. odm_set_bb_reg(p_dm_odm, ODM_REG_RST_RPT_11AC, BIT(0), 0);
  1354. cck_enable = odm_get_bb_reg(p_dm_odm, ODM_REG_BB_RX_PATH_11AC, BIT(28));
  1355. if (cck_enable) { /* if(*p_dm_odm->p_band_type == ODM_BAND_2_4G) */
  1356. false_alm_cnt->cnt_all = false_alm_cnt->cnt_ofdm_fail + false_alm_cnt->cnt_cck_fail;
  1357. false_alm_cnt->cnt_cca_all = false_alm_cnt->cnt_cck_cca + false_alm_cnt->cnt_ofdm_cca;
  1358. } else {
  1359. false_alm_cnt->cnt_all = false_alm_cnt->cnt_ofdm_fail;
  1360. false_alm_cnt->cnt_cca_all = false_alm_cnt->cnt_ofdm_cca;
  1361. }
  1362. }
  1363. #endif
  1364. if (phydm_set_bb_dbg_port(p_dm_odm, BB_DBGPORT_PRIORITY_1, 0x0)) {/*set debug port to 0x0*/
  1365. false_alm_cnt->dbg_port0 = phydm_get_bb_dbg_port_value(p_dm_odm);
  1366. phydm_release_bb_dbg_port(p_dm_odm);
  1367. }
  1368. if (phydm_set_bb_dbg_port(p_dm_odm, BB_DBGPORT_PRIORITY_1, adaptivity->adaptivity_dbg_port)) {
  1369. false_alm_cnt->edcca_flag = (boolean)((phydm_get_bb_dbg_port_value(p_dm_odm) & BIT(30))>>30);
  1370. phydm_release_bb_dbg_port(p_dm_odm);
  1371. }
  1372. false_alm_cnt->cnt_crc32_error_all = false_alm_cnt->cnt_vht_crc32_error + false_alm_cnt->cnt_ht_crc32_error + false_alm_cnt->cnt_ofdm_crc32_error + false_alm_cnt->cnt_cck_crc32_error;
  1373. false_alm_cnt->cnt_crc32_ok_all = false_alm_cnt->cnt_vht_crc32_ok + false_alm_cnt->cnt_ht_crc32_ok + false_alm_cnt->cnt_ofdm_crc32_ok + false_alm_cnt->cnt_cck_crc32_ok;
  1374. ODM_RT_TRACE(p_dm_odm, ODM_COMP_FA_CNT, ODM_DBG_LOUD, ("[CCA Cnt] {CCK, OFDM, Total} = {%d, %d, %d}\n",
  1375. false_alm_cnt->cnt_cck_cca, false_alm_cnt->cnt_ofdm_cca, false_alm_cnt->cnt_cca_all));
  1376. ODM_RT_TRACE(p_dm_odm, ODM_COMP_FA_CNT, ODM_DBG_LOUD, ("[FA Cnt] {CCK, OFDM, Total} = {%d, %d, %d}\n",
  1377. false_alm_cnt->cnt_cck_fail, false_alm_cnt->cnt_ofdm_fail, false_alm_cnt->cnt_all));
  1378. ODM_RT_TRACE(p_dm_odm, ODM_COMP_FA_CNT, ODM_DBG_LOUD, ("[CCK] CRC32 {error, ok}= {%d, %d}\n", false_alm_cnt->cnt_cck_crc32_error, false_alm_cnt->cnt_cck_crc32_ok));
  1379. ODM_RT_TRACE(p_dm_odm, ODM_COMP_FA_CNT, ODM_DBG_LOUD, ("[OFDM]CRC32 {error, ok}= {%d, %d}\n", false_alm_cnt->cnt_ofdm_crc32_error, false_alm_cnt->cnt_ofdm_crc32_ok));
  1380. ODM_RT_TRACE(p_dm_odm, ODM_COMP_FA_CNT, ODM_DBG_LOUD, ("[ HT ] CRC32 {error, ok}= {%d, %d}\n", false_alm_cnt->cnt_ht_crc32_error, false_alm_cnt->cnt_ht_crc32_ok));
  1381. ODM_RT_TRACE(p_dm_odm, ODM_COMP_FA_CNT, ODM_DBG_LOUD, ("[VHT] CRC32 {error, ok}= {%d, %d}\n", false_alm_cnt->cnt_vht_crc32_error, false_alm_cnt->cnt_vht_crc32_ok));
  1382. ODM_RT_TRACE(p_dm_odm, ODM_COMP_FA_CNT, ODM_DBG_LOUD, ("[VHT] CRC32 {error, ok}= {%d, %d}\n", false_alm_cnt->cnt_crc32_error_all, false_alm_cnt->cnt_crc32_ok_all));
  1383. ODM_RT_TRACE(p_dm_odm, ODM_COMP_FA_CNT, ODM_DBG_LOUD, ("FA_Cnt: Dbg port 0x0 = 0x%x, EDCCA = %d\n\n", false_alm_cnt->dbg_port0, false_alm_cnt->edcca_flag));
  1384. }
  1385. /* 3============================================================
  1386. * 3 CCK Packet Detect threshold
  1387. * 3============================================================ */
  1388. void
  1389. odm_pause_cck_packet_detection(
  1390. void *p_dm_void,
  1391. enum phydm_pause_type pause_type,
  1392. enum phydm_pause_level pause_level,
  1393. u8 cck_pd_threshold
  1394. )
  1395. {
  1396. struct PHY_DM_STRUCT *p_dm_odm = (struct PHY_DM_STRUCT *)p_dm_void;
  1397. struct _dynamic_initial_gain_threshold_ *p_dm_dig_table = &p_dm_odm->dm_dig_table;
  1398. ODM_RT_TRACE(p_dm_odm, ODM_COMP_DIG, ODM_DBG_LOUD, ("odm_pause_cck_packet_detection()=========> level = %d\n", pause_level));
  1399. if ((p_dm_dig_table->pause_cckpd_level == 0) && (!(p_dm_odm->support_ability & ODM_BB_CCK_PD) || !(p_dm_odm->support_ability & ODM_BB_FA_CNT))) {
  1400. ODM_RT_TRACE(p_dm_odm, ODM_COMP_DIG, ODM_DBG_LOUD, ("Return: support_ability ODM_BB_CCK_PD or ODM_BB_FA_CNT is disabled\n"));
  1401. return;
  1402. }
  1403. if (pause_level > DM_DIG_MAX_PAUSE_TYPE) {
  1404. ODM_RT_TRACE(p_dm_odm, ODM_COMP_DIG, ODM_DBG_LOUD,
  1405. ("odm_pause_cck_packet_detection(): Return: Wrong pause level !!\n"));
  1406. return;
  1407. }
  1408. ODM_RT_TRACE(p_dm_odm, ODM_COMP_DIG, ODM_DBG_LOUD, ("odm_pause_cck_packet_detection(): pause level = 0x%x, Current value = 0x%x\n", p_dm_dig_table->pause_cckpd_level, cck_pd_threshold));
  1409. ODM_RT_TRACE(p_dm_odm, ODM_COMP_DIG, ODM_DBG_LOUD, ("odm_pause_cck_packet_detection(): pause value = 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x\n",
  1410. p_dm_dig_table->pause_cckpd_value[7], p_dm_dig_table->pause_cckpd_value[6], p_dm_dig_table->pause_cckpd_value[5], p_dm_dig_table->pause_cckpd_value[4],
  1411. p_dm_dig_table->pause_cckpd_value[3], p_dm_dig_table->pause_cckpd_value[2], p_dm_dig_table->pause_cckpd_value[1], p_dm_dig_table->pause_cckpd_value[0]));
  1412. switch (pause_type) {
  1413. /* Pause CCK Packet Detection threshold */
  1414. case PHYDM_PAUSE:
  1415. {
  1416. /* Disable CCK PD */
  1417. odm_cmn_info_update(p_dm_odm, ODM_CMNINFO_ABILITY, p_dm_odm->support_ability & (~ODM_BB_CCK_PD));
  1418. ODM_RT_TRACE(p_dm_odm, ODM_COMP_DIG, ODM_DBG_LOUD, ("odm_pause_cck_packet_detection(): Pause CCK packet detection threshold !!\n"));
  1419. /* Backup original CCK PD threshold decided by CCK PD mechanism */
  1420. if (p_dm_dig_table->pause_cckpd_level == 0) {
  1421. p_dm_dig_table->cck_pd_backup = p_dm_dig_table->cur_cck_cca_thres;
  1422. ODM_RT_TRACE(p_dm_odm, ODM_COMP_DIG, ODM_DBG_LOUD,
  1423. ("odm_pause_cck_packet_detection(): Backup CCKPD = 0x%x, new CCKPD = 0x%x\n", p_dm_dig_table->cck_pd_backup, cck_pd_threshold));
  1424. }
  1425. /* Update pause level */
  1426. p_dm_dig_table->pause_cckpd_level = (p_dm_dig_table->pause_cckpd_level | BIT(pause_level));
  1427. /* Record CCK PD threshold */
  1428. p_dm_dig_table->pause_cckpd_value[pause_level] = cck_pd_threshold;
  1429. /* Write new CCK PD threshold */
  1430. if (BIT(pause_level + 1) > p_dm_dig_table->pause_cckpd_level) {
  1431. odm_write_cck_cca_thres(p_dm_odm, cck_pd_threshold);
  1432. ODM_RT_TRACE(p_dm_odm, ODM_COMP_DIG, ODM_DBG_LOUD, ("odm_pause_cck_packet_detection(): CCKPD of higher level = 0x%x\n", cck_pd_threshold));
  1433. }
  1434. break;
  1435. }
  1436. /* Resume CCK Packet Detection threshold */
  1437. case PHYDM_RESUME:
  1438. {
  1439. /* check if the level is illegal or not */
  1440. if ((p_dm_dig_table->pause_cckpd_level & (BIT(pause_level))) != 0) {
  1441. p_dm_dig_table->pause_cckpd_level = p_dm_dig_table->pause_cckpd_level & (~(BIT(pause_level)));
  1442. p_dm_dig_table->pause_cckpd_value[pause_level] = 0;
  1443. ODM_RT_TRACE(p_dm_odm, ODM_COMP_DIG, ODM_DBG_LOUD, ("odm_pause_cck_packet_detection(): Resume CCK PD !!\n"));
  1444. } else {
  1445. ODM_RT_TRACE(p_dm_odm, ODM_COMP_DIG, ODM_DBG_LOUD, ("odm_pause_cck_packet_detection(): Wrong resume level !!\n"));
  1446. break;
  1447. }
  1448. /* Resume DIG */
  1449. if (p_dm_dig_table->pause_cckpd_level == 0) {
  1450. /* Write backup IGI value */
  1451. odm_write_cck_cca_thres(p_dm_odm, p_dm_dig_table->cck_pd_backup);
  1452. /* p_dm_dig_table->is_ignore_dig = true; */
  1453. ODM_RT_TRACE(p_dm_odm, ODM_COMP_DIG, ODM_DBG_LOUD, ("odm_pause_cck_packet_detection(): Write original CCKPD = 0x%x\n", p_dm_dig_table->cck_pd_backup));
  1454. /* Enable DIG */
  1455. odm_cmn_info_update(p_dm_odm, ODM_CMNINFO_ABILITY, p_dm_odm->support_ability | ODM_BB_CCK_PD);
  1456. break;
  1457. }
  1458. if (BIT(pause_level) > p_dm_dig_table->pause_cckpd_level) {
  1459. s8 max_level;
  1460. /* Calculate the maximum level now */
  1461. for (max_level = (pause_level - 1); max_level >= 0; max_level--) {
  1462. if ((p_dm_dig_table->pause_cckpd_level & BIT(max_level)) > 0)
  1463. break;
  1464. }
  1465. /* write CCKPD of lower level */
  1466. odm_write_cck_cca_thres(p_dm_odm, p_dm_dig_table->pause_cckpd_value[max_level]);
  1467. ODM_RT_TRACE(p_dm_odm, ODM_COMP_DIG, ODM_DBG_LOUD, ("odm_pause_cck_packet_detection(): Write CCKPD (0x%x) of level (%d)\n",
  1468. p_dm_dig_table->pause_cckpd_value[max_level], max_level));
  1469. break;
  1470. }
  1471. break;
  1472. }
  1473. default:
  1474. ODM_RT_TRACE(p_dm_odm, ODM_COMP_DIG, ODM_DBG_LOUD, ("odm_pause_cck_packet_detection(): Wrong type !!\n"));
  1475. break;
  1476. }
  1477. ODM_RT_TRACE(p_dm_odm, ODM_COMP_DIG, ODM_DBG_LOUD, ("odm_pause_cck_packet_detection(): pause level = 0x%x, Current value = 0x%x\n", p_dm_dig_table->pause_cckpd_level, cck_pd_threshold));
  1478. ODM_RT_TRACE(p_dm_odm, ODM_COMP_DIG, ODM_DBG_LOUD, ("odm_pause_cck_packet_detection(): pause value = 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x\n",
  1479. p_dm_dig_table->pause_cckpd_value[7], p_dm_dig_table->pause_cckpd_value[6], p_dm_dig_table->pause_cckpd_value[5], p_dm_dig_table->pause_cckpd_value[4],
  1480. p_dm_dig_table->pause_cckpd_value[3], p_dm_dig_table->pause_cckpd_value[2], p_dm_dig_table->pause_cckpd_value[1], p_dm_dig_table->pause_cckpd_value[0]));
  1481. }
  1482. void
  1483. odm_cck_packet_detection_thresh(
  1484. void *p_dm_void
  1485. )
  1486. {
  1487. struct PHY_DM_STRUCT *p_dm_odm = (struct PHY_DM_STRUCT *)p_dm_void;
  1488. struct _dynamic_initial_gain_threshold_ *p_dm_dig_table = &p_dm_odm->dm_dig_table;
  1489. struct _FALSE_ALARM_STATISTICS *false_alm_cnt = (struct _FALSE_ALARM_STATISTICS *)phydm_get_structure(p_dm_odm, PHYDM_FALSEALMCNT);
  1490. u8 cur_cck_cca_thres = p_dm_dig_table->cur_cck_cca_thres, RSSI_thd = 35;
  1491. u8 pd_th = 0, cs_ration = 0;
  1492. #if (DM_ODM_SUPPORT_TYPE == ODM_WIN)
  1493. /* modify by Guo.Mingzhi 2011-12-29 */
  1494. if (p_dm_odm->is_dual_mac_smart_concurrent == true)
  1495. return;
  1496. if (p_dm_odm->is_bt_hs_operation) {
  1497. ODM_RT_TRACE(p_dm_odm, ODM_COMP_DIG, ODM_DBG_LOUD, ("CCK_PD: 0xcd for BT HS mode!!\n"));
  1498. odm_write_cck_cca_thres(p_dm_odm, 0xcd);
  1499. return;
  1500. }
  1501. #endif
  1502. if ((!(p_dm_odm->support_ability & ODM_BB_CCK_PD)) || (!(p_dm_odm->support_ability & ODM_BB_FA_CNT))) {
  1503. ODM_RT_TRACE(p_dm_odm, ODM_COMP_DIG, ODM_DBG_LOUD, ("CCK_PD: return==========\n"));
  1504. #ifdef MCR_WIRELESS_EXTEND
  1505. odm_write_cck_cca_thres(p_dm_odm, 0x43);
  1506. #endif
  1507. return;
  1508. }
  1509. #if (DM_ODM_SUPPORT_TYPE & (ODM_WIN | ODM_CE))
  1510. if (p_dm_odm->ext_lna)
  1511. return;
  1512. #endif
  1513. ODM_RT_TRACE(p_dm_odm, ODM_COMP_DIG, ODM_DBG_LOUD, ("CCK_PD: ==========>\n"));
  1514. if (p_dm_dig_table->cck_fa_ma == 0xffffffff)
  1515. p_dm_dig_table->cck_fa_ma = false_alm_cnt->cnt_cck_fail;
  1516. else
  1517. p_dm_dig_table->cck_fa_ma = ((p_dm_dig_table->cck_fa_ma << 1) + p_dm_dig_table->cck_fa_ma + false_alm_cnt->cnt_cck_fail) >> 2;
  1518. ODM_RT_TRACE(p_dm_odm, ODM_COMP_DIG, ODM_DBG_LOUD, ("CCK_PD: CCK FA moving average = %d\n", p_dm_dig_table->cck_fa_ma));
  1519. if (p_dm_odm->is_linked) {
  1520. #if (DM_ODM_SUPPORT_TYPE & (ODM_WIN | ODM_CE))
  1521. #if 0 /*for [PCIE-1596]*/
  1522. if (p_dm_odm->rssi_min > (RSSI_thd + 14))
  1523. cur_cck_cca_thres = 0xed;
  1524. else if (p_dm_odm->rssi_min > (RSSI_thd + 6))
  1525. cur_cck_cca_thres = 0xdd;
  1526. else
  1527. #endif
  1528. #if 0 /*for LPS power consumption issue*/
  1529. if (p_dm_odm->traffic_load == TRAFFIC_ULTRA_LOW)
  1530. cur_cck_cca_thres = 0x40;
  1531. else
  1532. #endif
  1533. {
  1534. if (p_dm_odm->rssi_min > RSSI_thd)
  1535. cur_cck_cca_thres = 0xcd;
  1536. else if (p_dm_odm->rssi_min > 20) {
  1537. if (p_dm_dig_table->cck_fa_ma > ((DM_DIG_FA_TH1 >> 1) + (DM_DIG_FA_TH1 >> 3)))
  1538. cur_cck_cca_thres = 0xcd;
  1539. else if (p_dm_dig_table->cck_fa_ma < (DM_DIG_FA_TH0 >> 1))
  1540. cur_cck_cca_thres = 0x83;
  1541. } else if (p_dm_odm->rssi_min > 7)
  1542. cur_cck_cca_thres = 0x83;
  1543. else
  1544. cur_cck_cca_thres = 0x40;
  1545. }
  1546. #else /*ODM_AP*/
  1547. if (p_dm_odm->support_ic_type & ODM_RTL8197F) {
  1548. if ((p_dm_dig_table->cur_ig_value > (0x24 + 14)) || (p_dm_odm->rssi_min > 32))
  1549. cur_cck_cca_thres = 0xed;
  1550. else if ((p_dm_dig_table->cur_ig_value > (0x24 + 6)) || (p_dm_odm->rssi_min > 32))
  1551. cur_cck_cca_thres = 0xdd;
  1552. else if ((p_dm_dig_table->cur_ig_value > 0x24) || (p_dm_odm->rssi_min > 24 && p_dm_odm->rssi_min <= 30))
  1553. cur_cck_cca_thres = 0xcd;
  1554. else if ((p_dm_dig_table->cur_ig_value <= 0x24) || (p_dm_odm->rssi_min < 22)) {
  1555. if (p_dm_dig_table->cck_fa_ma > 0x400)
  1556. cur_cck_cca_thres = 0x83;
  1557. else if (p_dm_dig_table->cck_fa_ma < 0x200)
  1558. cur_cck_cca_thres = 0x40;
  1559. }
  1560. } else {
  1561. if (p_dm_dig_table->cur_ig_value > (0x24 + 14))
  1562. cur_cck_cca_thres = 0xed;
  1563. else if (p_dm_dig_table->cur_ig_value > (0x24 + 6))
  1564. cur_cck_cca_thres = 0xdd;
  1565. else if (p_dm_dig_table->cur_ig_value > 0x24)
  1566. cur_cck_cca_thres = 0xcd;
  1567. else {
  1568. #if 0
  1569. if (p_dm_dig_table->cck_fa_ma > 0x400)
  1570. cur_cck_cca_thres = 0x83;
  1571. else if (p_dm_dig_table->cck_fa_ma < 0x200)
  1572. cur_cck_cca_thres = 0x40;
  1573. #else
  1574. cur_cck_cca_thres = 0x83;
  1575. #endif
  1576. }
  1577. }
  1578. #endif
  1579. } else {
  1580. if (p_dm_dig_table->cck_fa_ma > 0x400)
  1581. cur_cck_cca_thres = 0x83;
  1582. else if (p_dm_dig_table->cck_fa_ma < 0x200)
  1583. cur_cck_cca_thres = 0x40;
  1584. }
  1585. #if (RTL8197F_SUPPORT == 1)
  1586. /*Add by Yu Chen 20160902, pd_th for 0xa0a, cs_ration for 0xaaa*/
  1587. if (p_dm_odm->support_ic_type & ODM_RTL8197F) {
  1588. switch (cur_cck_cca_thres) {
  1589. case 0xed:
  1590. cs_ration = p_dm_dig_table->aaa_default + AAA_BASE + AAA_STEP*2;
  1591. pd_th = 0xd;
  1592. break;
  1593. case 0xdd:
  1594. cs_ration = p_dm_dig_table->aaa_default + AAA_BASE + AAA_STEP;
  1595. pd_th = 0xd;
  1596. break;
  1597. case 0xcd:
  1598. cs_ration = p_dm_dig_table->aaa_default + AAA_BASE;
  1599. pd_th = 0xd;
  1600. break;
  1601. case 0x83:
  1602. cs_ration = p_dm_dig_table->aaa_default + AAA_STEP;
  1603. pd_th = 0x7;
  1604. break;
  1605. case 0x40:
  1606. cs_ration = p_dm_dig_table->aaa_default;
  1607. pd_th = 0x3;
  1608. break;
  1609. default:
  1610. cs_ration = p_dm_dig_table->aaa_default;
  1611. pd_th = 0x3;
  1612. ODM_RT_TRACE(p_dm_odm, ODM_COMP_DIG, ODM_DBG_LOUD, ("cck pd use default\n"));
  1613. break;
  1614. }
  1615. }
  1616. #endif /*#if (RTL8197F_SUPPORT == 1)*/
  1617. #if (RTL8197F_SUPPORT == 1)
  1618. if (p_dm_odm->support_ic_type & ODM_RTL8197F) {
  1619. odm_set_bb_reg(p_dm_odm, 0xa08, 0xf0000, pd_th);
  1620. odm_set_bb_reg(p_dm_odm, 0xaa8, 0x1f0000, cs_ration);
  1621. } else
  1622. #endif
  1623. {
  1624. odm_write_cck_cca_thres(p_dm_odm, cur_cck_cca_thres);
  1625. }
  1626. ODM_RT_TRACE(p_dm_odm, ODM_COMP_DIG, ODM_DBG_LOUD, ("CCK_PD: cck_cca_th=((0x%x))\n\n", cur_cck_cca_thres));
  1627. }
  1628. void
  1629. odm_write_cck_cca_thres(
  1630. void *p_dm_void,
  1631. u8 cur_cck_cca_thres
  1632. )
  1633. {
  1634. struct PHY_DM_STRUCT *p_dm_odm = (struct PHY_DM_STRUCT *)p_dm_void;
  1635. struct _dynamic_initial_gain_threshold_ *p_dm_dig_table = &p_dm_odm->dm_dig_table;
  1636. if (p_dm_dig_table->cur_cck_cca_thres != cur_cck_cca_thres) { /* modify by Guo.Mingzhi 2012-01-03 */
  1637. odm_write_1byte(p_dm_odm, ODM_REG(CCK_CCA, p_dm_odm), cur_cck_cca_thres);
  1638. p_dm_dig_table->cck_fa_ma = 0xffffffff;
  1639. }
  1640. p_dm_dig_table->pre_cck_cca_thres = p_dm_dig_table->cur_cck_cca_thres;
  1641. p_dm_dig_table->cur_cck_cca_thres = cur_cck_cca_thres;
  1642. }
  1643. boolean
  1644. phydm_dig_go_up_check(
  1645. void *p_dm_void
  1646. )
  1647. {
  1648. struct PHY_DM_STRUCT *p_dm_odm = (struct PHY_DM_STRUCT *)p_dm_void;
  1649. struct _CCX_INFO *ccx_info = &p_dm_odm->dm_ccx_info;
  1650. struct _dynamic_initial_gain_threshold_ *p_dm_dig_table = &p_dm_odm->dm_dig_table;
  1651. u8 cur_ig_value = p_dm_dig_table->cur_ig_value;
  1652. u8 max_DIG_cover_bond;
  1653. u8 current_igi_max_up_resolution;
  1654. u8 rx_gain_range_max;
  1655. u8 i = 0;
  1656. u32 total_NHM_cnt;
  1657. u32 DIG_cover_cnt;
  1658. u32 over_DIG_cover_cnt;
  1659. boolean ret = true;
  1660. #if (DM_ODM_SUPPORT_TYPE & (ODM_AP))
  1661. struct rtl8192cd_priv *priv = p_dm_odm->priv;
  1662. max_DIG_cover_bond = DM_DIG_MAX_AP - priv->pshare->rf_ft_var.dig_upcheck_initial_value;
  1663. current_igi_max_up_resolution = cur_ig_value + 6;
  1664. rx_gain_range_max = p_dm_dig_table->rx_gain_range_max;
  1665. phydm_get_nhm_result(p_dm_odm);
  1666. total_NHM_cnt = ccx_info->NHM_result[0] + ccx_info->NHM_result[1];
  1667. ODM_RT_TRACE(p_dm_odm, ODM_COMP_DIG, ODM_DBG_LOUD, ("phydm_dig_go_up_check(): *****Get NHM results*****\n"));
  1668. if (total_NHM_cnt != 0) {
  1669. /* cur_ig_value < max_DIG_cover_bond - 6 */
  1670. if (p_dm_dig_table->dig_go_up_check_level == DIG_GOUPCHECK_LEVEL_0) {
  1671. DIG_cover_cnt = ccx_info->NHM_result[1];
  1672. ret = ((priv->pshare->rf_ft_var.dig_level0_ratio_reciprocal * DIG_cover_cnt) >= total_NHM_cnt) ? true : false;
  1673. }
  1674. /* (max_DIG_cover_bond - 6) <= cur_ig_value < DM_DIG_MAX_AP */
  1675. else if (p_dm_dig_table->dig_go_up_check_level == DIG_GOUPCHECK_LEVEL_1) {
  1676. over_DIG_cover_cnt = ccx_info->NHM_result[1];
  1677. ret = (priv->pshare->rf_ft_var.dig_level1_ratio_reciprocal * over_DIG_cover_cnt < total_NHM_cnt) ? true : false;
  1678. if (!ret) {
  1679. /* update p_dm_dig_table->rx_gain_range_max */
  1680. p_dm_dig_table->rx_gain_range_max = (rx_gain_range_max >= max_DIG_cover_bond - 6) ? (max_DIG_cover_bond - 6) : rx_gain_range_max;
  1681. ODM_RT_TRACE(p_dm_odm, ODM_COMP_DIG, ODM_DBG_LOUD, ("phydm_dig_go_up_check(): Noise power is beyond DIG can filter, lock rx_gain_range_max to 0x%x\n",
  1682. p_dm_dig_table->rx_gain_range_max));
  1683. }
  1684. }
  1685. /* cur_ig_value > DM_DIG_MAX_AP, foolproof */
  1686. else if (p_dm_dig_table->dig_go_up_check_level == DIG_GOUPCHECK_LEVEL_2)
  1687. ret = true;
  1688. ODM_RT_TRACE(p_dm_odm, ODM_COMP_DIG, ODM_DBG_LOUD, ("phydm_dig_go_up_check(): DIG_GoUpCheck_level = %d\n, current_igi_max_up_resolution = 0x%x\n, max_DIG_cover_bond = 0x%x\n, rx_gain_range_max = 0x%x, ret = %d\n",
  1689. p_dm_dig_table->dig_go_up_check_level,
  1690. current_igi_max_up_resolution,
  1691. max_DIG_cover_bond,
  1692. p_dm_dig_table->rx_gain_range_max,
  1693. ret));
  1694. ODM_RT_TRACE(p_dm_odm, ODM_COMP_DIG, ODM_DBG_LOUD, ("phydm_dig_go_up_check(): NHM_result = %d, %d, %d, %d\n",
  1695. ccx_info->NHM_result[0], ccx_info->NHM_result[1], ccx_info->NHM_result[2], ccx_info->NHM_result[3]));
  1696. } else
  1697. ret = true;
  1698. for (i = 0 ; i <= 10 ; i++)
  1699. ccx_info->NHM_th[i] = 0xFF;
  1700. if (cur_ig_value < max_DIG_cover_bond - 6) {
  1701. ccx_info->NHM_th[0] = 2 * (cur_ig_value - priv->pshare->rf_ft_var.dig_upcheck_initial_value);
  1702. p_dm_dig_table->dig_go_up_check_level = DIG_GOUPCHECK_LEVEL_0;
  1703. } else if (cur_ig_value <= DM_DIG_MAX_AP) {
  1704. ccx_info->NHM_th[0] = 2 * max_DIG_cover_bond;
  1705. p_dm_dig_table->dig_go_up_check_level = DIG_GOUPCHECK_LEVEL_1;
  1706. }
  1707. /* cur_ig_value > DM_DIG_MAX_AP, foolproof */
  1708. else {
  1709. p_dm_dig_table->dig_go_up_check_level = DIG_GOUPCHECK_LEVEL_2;
  1710. ret = true;
  1711. }
  1712. ODM_RT_TRACE(p_dm_odm, ODM_COMP_DIG, ODM_DBG_LOUD, ("phydm_dig_go_up_check(): *****Set NHM settings*****\n"));
  1713. ODM_RT_TRACE(p_dm_odm, ODM_COMP_DIG, ODM_DBG_LOUD, ("phydm_dig_go_up_check(): DIG_GoUpCheck_level = %d\n",
  1714. p_dm_dig_table->dig_go_up_check_level));
  1715. ODM_RT_TRACE(p_dm_odm, ODM_COMP_DIG, ODM_DBG_LOUD, ("phydm_dig_go_up_check(): NHM_th = 0x%x, 0x%x, 0x%x\n",
  1716. ccx_info->NHM_th[0], ccx_info->NHM_th[1], ccx_info->NHM_th[2]));
  1717. ccx_info->nhm_inexclude_cca = NHM_EXCLUDE_CCA;
  1718. ccx_info->nhm_inexclude_txon = NHM_EXCLUDE_TXON;
  1719. ccx_info->NHM_period = 0xC350;
  1720. phydm_nhm_setting(p_dm_odm, SET_NHM_SETTING);
  1721. phydm_nhm_trigger(p_dm_odm);
  1722. #endif
  1723. return ret;
  1724. }
  1725. #if (DM_ODM_SUPPORT_TYPE == ODM_WIN)
  1726. /* <20130108, Kordan> E.g., With LNA used, we make the Rx power smaller to have a better EVM. (Asked by Willis) */
  1727. void
  1728. odm_rfe_control(
  1729. struct PHY_DM_STRUCT *p_dm_odm,
  1730. u64 rssi_val
  1731. )
  1732. {
  1733. struct _ADAPTER *adapter = (struct _ADAPTER *)p_dm_odm->adapter;
  1734. HAL_DATA_TYPE *p_hal_data = GET_HAL_DATA(adapter);
  1735. static u8 trsw_high_pwr = 0;
  1736. ODM_RT_TRACE(p_dm_odm, ODM_COMP_DIG, ODM_DBG_LOUD, ("===> odm_rfe_control, RSSI = %d, trsw_high_pwr = 0x%X, p_dm_odm->rfe_type = %d\n",
  1737. rssi_val, trsw_high_pwr, p_dm_odm->rfe_type));
  1738. if (p_dm_odm->rfe_type == 3) {
  1739. p_dm_odm->RSSI_TRSW = rssi_val;
  1740. if (p_dm_odm->RSSI_TRSW >= p_dm_odm->RSSI_TRSW_H) {
  1741. trsw_high_pwr = 1; /* Switch to */
  1742. odm_set_bb_reg(p_dm_odm, REG_ANTSEL_SW_JAGUAR, BIT(1) | BIT0, 0x1); /* Set ANTSW=1/ANTSWB=0 for SW control */
  1743. odm_set_bb_reg(p_dm_odm, REG_ANTSEL_SW_JAGUAR, BIT(9) | BIT8, 0x3); /* Set ANTSW=1/ANTSWB=0 for SW control */
  1744. } else if (p_dm_odm->RSSI_TRSW <= p_dm_odm->RSSI_TRSW_L) {
  1745. trsw_high_pwr = 0; /* Switched back */
  1746. odm_set_bb_reg(p_dm_odm, REG_ANTSEL_SW_JAGUAR, BIT(1) | BIT0, 0x1); /* Set ANTSW=1/ANTSWB=0 for SW control */
  1747. odm_set_bb_reg(p_dm_odm, REG_ANTSEL_SW_JAGUAR, BIT(9) | BIT8, 0x0); /* Set ANTSW=1/ANTSWB=0 for SW control */
  1748. }
  1749. }
  1750. ODM_RT_TRACE(p_dm_odm, ODM_COMP_DIG, ODM_DBG_LOUD, ("(p_dm_odm->RSSI_TRSW_H, p_dm_odm->RSSI_TRSW_L) = (%d, %d)\n", p_dm_odm->RSSI_TRSW_H, p_dm_odm->RSSI_TRSW_L));
  1751. ODM_RT_TRACE(p_dm_odm, ODM_COMP_DIG, ODM_DBG_LOUD, ("(rssi_val, rssi_val, p_dm_odm->RSSI_TRSW_iso) = (%d, %d, %d)\n",
  1752. rssi_val, p_dm_odm->RSSI_TRSW_iso, p_dm_odm->RSSI_TRSW));
  1753. ODM_RT_TRACE(p_dm_odm, ODM_COMP_DIG, ODM_DBG_LOUD, ("<=== odm_rfe_control, RSSI = %d, trsw_high_pwr = 0x%X\n", rssi_val, trsw_high_pwr));
  1754. }
  1755. void
  1756. odm_mpt_dig_work_item_callback(
  1757. void *p_context
  1758. )
  1759. {
  1760. struct _ADAPTER *adapter = (struct _ADAPTER *)p_context;
  1761. HAL_DATA_TYPE *p_hal_data = GET_HAL_DATA(adapter);
  1762. struct PHY_DM_STRUCT *p_dm_odm = &p_hal_data->DM_OutSrc;
  1763. ODM_MPT_DIG(p_dm_odm);
  1764. }
  1765. void
  1766. odm_mpt_dig_callback(
  1767. struct timer_list *p_timer
  1768. )
  1769. {
  1770. struct _ADAPTER *adapter = (struct _ADAPTER *)p_timer->Adapter;
  1771. HAL_DATA_TYPE *p_hal_data = GET_HAL_DATA(adapter);
  1772. struct PHY_DM_STRUCT *p_dm_odm = &p_hal_data->DM_OutSrc;
  1773. #if DEV_BUS_TYPE == RT_PCI_INTERFACE
  1774. #if USE_WORKITEM
  1775. odm_schedule_work_item(&p_dm_odm->mpt_dig_workitem);
  1776. #else
  1777. ODM_MPT_DIG(p_dm_odm);
  1778. #endif
  1779. #else
  1780. odm_schedule_work_item(&p_dm_odm->mpt_dig_workitem);
  1781. #endif
  1782. }
  1783. #endif
  1784. #if (DM_ODM_SUPPORT_TYPE & (ODM_AP))
  1785. void
  1786. odm_mpt_dig_callback(
  1787. void *p_dm_void
  1788. )
  1789. {
  1790. struct PHY_DM_STRUCT *p_dm_odm = (struct PHY_DM_STRUCT *)p_dm_void;
  1791. #if USE_WORKITEM
  1792. odm_schedule_work_item(&p_dm_odm->mpt_dig_workitem);
  1793. #else
  1794. ODM_MPT_DIG(p_dm_odm);
  1795. #endif
  1796. }
  1797. #endif
  1798. #if (DM_ODM_SUPPORT_TYPE != ODM_CE)
  1799. void
  1800. odm_mpt_write_dig(
  1801. void *p_dm_void,
  1802. u8 cur_ig_value
  1803. )
  1804. {
  1805. struct PHY_DM_STRUCT *p_dm_odm = (struct PHY_DM_STRUCT *)p_dm_void;
  1806. struct _dynamic_initial_gain_threshold_ *p_dm_dig_table = &p_dm_odm->dm_dig_table;
  1807. odm_write_1byte(p_dm_odm, ODM_REG(IGI_A, p_dm_odm), cur_ig_value);
  1808. #if (ODM_PHY_STATUS_NEW_TYPE_SUPPORT == 1)
  1809. /* Set IGI value of CCK for new CCK AGC */
  1810. if (p_dm_odm->cck_new_agc) {
  1811. if (p_dm_odm->support_ic_type & ODM_IC_PHY_STATUE_NEW_TYPE)
  1812. odm_set_bb_reg(p_dm_odm, 0xa0c, 0x00003f00, (cur_ig_value >> 1));
  1813. }
  1814. #endif
  1815. if (p_dm_odm->rf_type > ODM_1T1R)
  1816. odm_write_1byte(p_dm_odm, ODM_REG(IGI_B, p_dm_odm), cur_ig_value);
  1817. if ((p_dm_odm->support_ic_type & ODM_IC_11AC_SERIES) && (p_dm_odm->rf_type > ODM_2T2R)) {
  1818. odm_write_1byte(p_dm_odm, ODM_REG(IGI_C, p_dm_odm), cur_ig_value);
  1819. odm_write_1byte(p_dm_odm, ODM_REG(IGI_D, p_dm_odm), cur_ig_value);
  1820. }
  1821. p_dm_dig_table->cur_ig_value = cur_ig_value;
  1822. ODM_RT_TRACE(p_dm_odm, ODM_COMP_DIG, ODM_DBG_LOUD, ("cur_ig_value = 0x%x\n", cur_ig_value));
  1823. ODM_RT_TRACE(p_dm_odm, ODM_COMP_DIG, ODM_DBG_LOUD, ("p_dm_odm->rf_type = 0x%x\n", p_dm_odm->rf_type));
  1824. }
  1825. void
  1826. ODM_MPT_DIG(
  1827. void *p_dm_void
  1828. )
  1829. {
  1830. struct PHY_DM_STRUCT *p_dm_odm = (struct PHY_DM_STRUCT *)p_dm_void;
  1831. struct _dynamic_initial_gain_threshold_ *p_dm_dig_table = &p_dm_odm->dm_dig_table;
  1832. struct _FALSE_ALARM_STATISTICS *p_false_alm_cnt = (struct _FALSE_ALARM_STATISTICS *)phydm_get_structure(p_dm_odm, PHYDM_FALSEALMCNT);
  1833. u8 current_igi = p_dm_dig_table->cur_ig_value;
  1834. u8 dig_upper = 0x40, dig_lower = 0x20;
  1835. u32 rx_ok_cal;
  1836. u32 rx_pwdb_ave_final;
  1837. u8 IGI_A = 0x20, IGI_B = 0x20;
  1838. #if (DM_ODM_SUPPORT_TYPE == ODM_WIN)
  1839. #if ODM_FIX_2G_DIG
  1840. IGI_A = 0x22;
  1841. IGI_B = 0x24;
  1842. #endif
  1843. #else
  1844. if (!(p_dm_odm->priv->pshare->rf_ft_var.mp_specific && p_dm_odm->priv->pshare->mp_dig_on))
  1845. return;
  1846. if (*p_dm_odm->p_band_type == ODM_BAND_5G)
  1847. dig_lower = 0x22;
  1848. #endif
  1849. ODM_RT_TRACE(p_dm_odm, ODM_COMP_DIG, ODM_DBG_LOUD, ("===> ODM_MPT_DIG, p_band_type = %d\n", *p_dm_odm->p_band_type));
  1850. #if (ODM_FIX_2G_DIG || (DM_ODM_SUPPORT_TYPE & ODM_AP))
  1851. if (*p_dm_odm->p_band_type == ODM_BAND_5G || (p_dm_odm->support_ic_type & (ODM_RTL8814A | ODM_RTL8822B))) /* for 5G or 8814 */
  1852. #else
  1853. if (1) /* for both 2G/5G */
  1854. #endif
  1855. {
  1856. odm_false_alarm_counter_statistics(p_dm_odm);
  1857. rx_ok_cal = p_dm_odm->phy_dbg_info.num_qry_phy_status_cck + p_dm_odm->phy_dbg_info.num_qry_phy_status_ofdm;
  1858. rx_pwdb_ave_final = (rx_ok_cal != 0) ? p_dm_odm->rx_pwdb_ave / rx_ok_cal : 0;
  1859. p_dm_odm->phy_dbg_info.num_qry_phy_status_cck = 0;
  1860. p_dm_odm->phy_dbg_info.num_qry_phy_status_ofdm = 0;
  1861. p_dm_odm->rx_pwdb_ave = 0;
  1862. p_dm_odm->MPDIG_2G = false;
  1863. #if (DM_ODM_SUPPORT_TYPE == ODM_WIN)
  1864. p_dm_odm->times_2g = 0;
  1865. #endif
  1866. ODM_RT_TRACE(p_dm_odm, ODM_COMP_DIG, ODM_DBG_LOUD, ("RX OK = %d\n", rx_ok_cal));
  1867. ODM_RT_TRACE(p_dm_odm, ODM_COMP_DIG, ODM_DBG_LOUD, ("RSSI = %d\n", rx_pwdb_ave_final));
  1868. if (rx_ok_cal >= 70 && rx_pwdb_ave_final <= 40) {
  1869. if (current_igi > 0x24)
  1870. odm_mpt_write_dig(p_dm_odm, 0x24);
  1871. } else {
  1872. if (p_false_alm_cnt->cnt_all > 1000)
  1873. current_igi = current_igi + 8;
  1874. else if (p_false_alm_cnt->cnt_all > 200)
  1875. current_igi = current_igi + 4;
  1876. else if (p_false_alm_cnt->cnt_all > 50)
  1877. current_igi = current_igi + 2;
  1878. else if (p_false_alm_cnt->cnt_all < 2)
  1879. current_igi = current_igi - 2;
  1880. if (current_igi < dig_lower)
  1881. current_igi = dig_lower;
  1882. if (current_igi > dig_upper)
  1883. current_igi = dig_upper;
  1884. odm_mpt_write_dig(p_dm_odm, current_igi);
  1885. ODM_RT_TRACE(p_dm_odm, ODM_COMP_DIG, ODM_DBG_LOUD, ("DIG = 0x%x, cnt_all = %d, cnt_ofdm_fail = %d, cnt_cck_fail = %d\n",
  1886. current_igi, p_false_alm_cnt->cnt_all, p_false_alm_cnt->cnt_ofdm_fail, p_false_alm_cnt->cnt_cck_fail));
  1887. }
  1888. } else {
  1889. if (p_dm_odm->MPDIG_2G == false) {
  1890. if ((p_dm_odm->support_platform & ODM_WIN) && !(p_dm_odm->support_ic_type & (ODM_RTL8814A | ODM_RTL8822B))) {
  1891. ODM_RT_TRACE(p_dm_odm, ODM_COMP_DIG, ODM_DBG_LOUD, ("===> Fix IGI\n"));
  1892. odm_write_1byte(p_dm_odm, ODM_REG(IGI_A, p_dm_odm), IGI_A);
  1893. odm_write_1byte(p_dm_odm, ODM_REG(IGI_B, p_dm_odm), IGI_B);
  1894. p_dm_dig_table->cur_ig_value = IGI_B;
  1895. } else
  1896. odm_mpt_write_dig(p_dm_odm, IGI_A);
  1897. }
  1898. #if (DM_ODM_SUPPORT_TYPE == ODM_WIN)
  1899. p_dm_odm->times_2g++;
  1900. if (p_dm_odm->times_2g == 3)
  1901. #endif
  1902. {
  1903. p_dm_odm->MPDIG_2G = true;
  1904. }
  1905. }
  1906. #if (DM_ODM_SUPPORT_TYPE == ODM_WIN)
  1907. if (p_dm_odm->support_ic_type == ODM_RTL8812)
  1908. odm_rfe_control(p_dm_odm, rx_pwdb_ave_final);
  1909. #endif
  1910. odm_set_timer(p_dm_odm, &p_dm_odm->mpt_dig_timer, 700);
  1911. }
  1912. #endif