dm.c 40 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263
  1. /******************************************************************************
  2. *
  3. * Copyright(c) 2009-2014 Realtek Corporation.
  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. * The full GNU General Public License is included in this distribution in the
  15. * file called LICENSE.
  16. *
  17. * Contact Information:
  18. * wlanfae <wlanfae@realtek.com>
  19. * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park,
  20. * Hsinchu 300, Taiwan.
  21. *
  22. * Larry Finger <Larry.Finger@lwfinger.net>
  23. *
  24. *****************************************************************************/
  25. #include "../wifi.h"
  26. #include "../base.h"
  27. #include "../pci.h"
  28. #include "reg.h"
  29. #include "def.h"
  30. #include "phy.h"
  31. #include "dm.h"
  32. #include "fw.h"
  33. #include "trx.h"
  34. static const u32 ofdmswing_table[OFDM_TABLE_SIZE] = {
  35. 0x7f8001fe, /* 0, +6.0dB */
  36. 0x788001e2, /* 1, +5.5dB */
  37. 0x71c001c7, /* 2, +5.0dB */
  38. 0x6b8001ae, /* 3, +4.5dB */
  39. 0x65400195, /* 4, +4.0dB */
  40. 0x5fc0017f, /* 5, +3.5dB */
  41. 0x5a400169, /* 6, +3.0dB */
  42. 0x55400155, /* 7, +2.5dB */
  43. 0x50800142, /* 8, +2.0dB */
  44. 0x4c000130, /* 9, +1.5dB */
  45. 0x47c0011f, /* 10, +1.0dB */
  46. 0x43c0010f, /* 11, +0.5dB */
  47. 0x40000100, /* 12, +0dB */
  48. 0x3c8000f2, /* 13, -0.5dB */
  49. 0x390000e4, /* 14, -1.0dB */
  50. 0x35c000d7, /* 15, -1.5dB */
  51. 0x32c000cb, /* 16, -2.0dB */
  52. 0x300000c0, /* 17, -2.5dB */
  53. 0x2d4000b5, /* 18, -3.0dB */
  54. 0x2ac000ab, /* 19, -3.5dB */
  55. 0x288000a2, /* 20, -4.0dB */
  56. 0x26000098, /* 21, -4.5dB */
  57. 0x24000090, /* 22, -5.0dB */
  58. 0x22000088, /* 23, -5.5dB */
  59. 0x20000080, /* 24, -6.0dB */
  60. 0x1e400079, /* 25, -6.5dB */
  61. 0x1c800072, /* 26, -7.0dB */
  62. 0x1b00006c, /* 27. -7.5dB */
  63. 0x19800066, /* 28, -8.0dB */
  64. 0x18000060, /* 29, -8.5dB */
  65. 0x16c0005b, /* 30, -9.0dB */
  66. 0x15800056, /* 31, -9.5dB */
  67. 0x14400051, /* 32, -10.0dB */
  68. 0x1300004c, /* 33, -10.5dB */
  69. 0x12000048, /* 34, -11.0dB */
  70. 0x11000044, /* 35, -11.5dB */
  71. 0x10000040, /* 36, -12.0dB */
  72. 0x0f00003c, /* 37, -12.5dB */
  73. 0x0e400039, /* 38, -13.0dB */
  74. 0x0d800036, /* 39, -13.5dB */
  75. 0x0cc00033, /* 40, -14.0dB */
  76. 0x0c000030, /* 41, -14.5dB */
  77. 0x0b40002d, /* 42, -15.0dB */
  78. };
  79. static const u8 cckswing_table_ch1ch13[CCK_TABLE_SIZE][8] = {
  80. {0x36, 0x35, 0x2e, 0x25, 0x1c, 0x12, 0x09, 0x04}, /* 0, +0dB */
  81. {0x33, 0x32, 0x2b, 0x23, 0x1a, 0x11, 0x08, 0x04}, /* 1, -0.5dB */
  82. {0x30, 0x2f, 0x29, 0x21, 0x19, 0x10, 0x08, 0x03}, /* 2, -1.0dB */
  83. {0x2d, 0x2d, 0x27, 0x1f, 0x18, 0x0f, 0x08, 0x03}, /* 3, -1.5dB */
  84. {0x2b, 0x2a, 0x25, 0x1e, 0x16, 0x0e, 0x07, 0x03}, /* 4, -2.0dB */
  85. {0x28, 0x28, 0x22, 0x1c, 0x15, 0x0d, 0x07, 0x03}, /* 5, -2.5dB */
  86. {0x26, 0x25, 0x21, 0x1b, 0x14, 0x0d, 0x06, 0x03}, /* 6, -3.0dB */
  87. {0x24, 0x23, 0x1f, 0x19, 0x13, 0x0c, 0x06, 0x03}, /* 7, -3.5dB */
  88. {0x22, 0x21, 0x1d, 0x18, 0x11, 0x0b, 0x06, 0x02}, /* 8, -4.0dB */
  89. {0x20, 0x20, 0x1b, 0x16, 0x11, 0x08, 0x05, 0x02}, /* 9, -4.5dB */
  90. {0x1f, 0x1e, 0x1a, 0x15, 0x10, 0x0a, 0x05, 0x02}, /* 10, -5.0dB */
  91. {0x1d, 0x1c, 0x18, 0x14, 0x0f, 0x0a, 0x05, 0x02}, /* 11, -5.5dB */
  92. {0x1b, 0x1a, 0x17, 0x13, 0x0e, 0x09, 0x04, 0x02}, /* 12, -6.0dB */
  93. {0x1a, 0x19, 0x16, 0x12, 0x0d, 0x09, 0x04, 0x02}, /* 13, -6.5dB */
  94. {0x18, 0x17, 0x15, 0x11, 0x0c, 0x08, 0x04, 0x02}, /* 14, -7.0dB */
  95. {0x17, 0x16, 0x13, 0x10, 0x0c, 0x08, 0x04, 0x02}, /* 15, -7.5dB */
  96. {0x16, 0x15, 0x12, 0x0f, 0x0b, 0x07, 0x04, 0x01}, /* 16, -8.0dB */
  97. {0x14, 0x14, 0x11, 0x0e, 0x0b, 0x07, 0x03, 0x02}, /* 17, -8.5dB */
  98. {0x13, 0x13, 0x10, 0x0d, 0x0a, 0x06, 0x03, 0x01}, /* 18, -9.0dB */
  99. {0x12, 0x12, 0x0f, 0x0c, 0x09, 0x06, 0x03, 0x01}, /* 19, -9.5dB */
  100. {0x11, 0x11, 0x0f, 0x0c, 0x09, 0x06, 0x03, 0x01}, /* 20, -10.0dB */
  101. {0x10, 0x10, 0x0e, 0x0b, 0x08, 0x05, 0x03, 0x01}, /* 21, -10.5dB */
  102. {0x0f, 0x0f, 0x0d, 0x0b, 0x08, 0x05, 0x03, 0x01}, /* 22, -11.0dB */
  103. {0x0e, 0x0e, 0x0c, 0x0a, 0x08, 0x05, 0x02, 0x01}, /* 23, -11.5dB */
  104. {0x0d, 0x0d, 0x0c, 0x0a, 0x07, 0x05, 0x02, 0x01}, /* 24, -12.0dB */
  105. {0x0d, 0x0c, 0x0b, 0x09, 0x07, 0x04, 0x02, 0x01}, /* 25, -12.5dB */
  106. {0x0c, 0x0c, 0x0a, 0x09, 0x06, 0x04, 0x02, 0x01}, /* 26, -13.0dB */
  107. {0x0b, 0x0b, 0x0a, 0x08, 0x06, 0x04, 0x02, 0x01}, /* 27, -13.5dB */
  108. {0x0b, 0x0a, 0x09, 0x08, 0x06, 0x04, 0x02, 0x01}, /* 28, -14.0dB */
  109. {0x0a, 0x0a, 0x09, 0x07, 0x05, 0x03, 0x02, 0x01}, /* 29, -14.5dB */
  110. {0x0a, 0x09, 0x08, 0x07, 0x05, 0x03, 0x02, 0x01}, /* 30, -15.0dB */
  111. {0x09, 0x09, 0x08, 0x06, 0x05, 0x03, 0x01, 0x01}, /* 31, -15.5dB */
  112. {0x09, 0x08, 0x07, 0x06, 0x04, 0x03, 0x01, 0x01} /* 32, -16.0dB */
  113. };
  114. static const u8 cckswing_table_ch14[CCK_TABLE_SIZE][8] = {
  115. {0x36, 0x35, 0x2e, 0x1b, 0x00, 0x00, 0x00, 0x00}, /* 0, +0dB */
  116. {0x33, 0x32, 0x2b, 0x19, 0x00, 0x00, 0x00, 0x00}, /* 1, -0.5dB */
  117. {0x30, 0x2f, 0x29, 0x18, 0x00, 0x00, 0x00, 0x00}, /* 2, -1.0dB */
  118. {0x2d, 0x2d, 0x17, 0x17, 0x00, 0x00, 0x00, 0x00}, /* 3, -1.5dB */
  119. {0x2b, 0x2a, 0x25, 0x15, 0x00, 0x00, 0x00, 0x00}, /* 4, -2.0dB */
  120. {0x28, 0x28, 0x24, 0x14, 0x00, 0x00, 0x00, 0x00}, /* 5, -2.5dB */
  121. {0x26, 0x25, 0x21, 0x13, 0x00, 0x00, 0x00, 0x00}, /* 6, -3.0dB */
  122. {0x24, 0x23, 0x1f, 0x12, 0x00, 0x00, 0x00, 0x00}, /* 7, -3.5dB */
  123. {0x22, 0x21, 0x1d, 0x11, 0x00, 0x00, 0x00, 0x00}, /* 8, -4.0dB */
  124. {0x20, 0x20, 0x1b, 0x10, 0x00, 0x00, 0x00, 0x00}, /* 9, -4.5dB */
  125. {0x1f, 0x1e, 0x1a, 0x0f, 0x00, 0x00, 0x00, 0x00}, /* 10, -5.0dB */
  126. {0x1d, 0x1c, 0x18, 0x0e, 0x00, 0x00, 0x00, 0x00}, /* 11, -5.5dB */
  127. {0x1b, 0x1a, 0x17, 0x0e, 0x00, 0x00, 0x00, 0x00}, /* 12, -6.0dB */
  128. {0x1a, 0x19, 0x16, 0x0d, 0x00, 0x00, 0x00, 0x00}, /* 13, -6.5dB */
  129. {0x18, 0x17, 0x15, 0x0c, 0x00, 0x00, 0x00, 0x00}, /* 14, -7.0dB */
  130. {0x17, 0x16, 0x13, 0x0b, 0x00, 0x00, 0x00, 0x00}, /* 15, -7.5dB */
  131. {0x16, 0x15, 0x12, 0x0b, 0x00, 0x00, 0x00, 0x00}, /* 16, -8.0dB */
  132. {0x14, 0x14, 0x11, 0x0a, 0x00, 0x00, 0x00, 0x00}, /* 17, -8.5dB */
  133. {0x13, 0x13, 0x10, 0x0a, 0x00, 0x00, 0x00, 0x00}, /* 18, -9.0dB */
  134. {0x12, 0x12, 0x0f, 0x09, 0x00, 0x00, 0x00, 0x00}, /* 19, -9.5dB */
  135. {0x11, 0x11, 0x0f, 0x09, 0x00, 0x00, 0x00, 0x00}, /* 20, -10.0dB */
  136. {0x10, 0x10, 0x0e, 0x08, 0x00, 0x00, 0x00, 0x00}, /* 21, -10.5dB */
  137. {0x0f, 0x0f, 0x0d, 0x08, 0x00, 0x00, 0x00, 0x00}, /* 22, -11.0dB */
  138. {0x0e, 0x0e, 0x0c, 0x07, 0x00, 0x00, 0x00, 0x00}, /* 23, -11.5dB */
  139. {0x0d, 0x0d, 0x0c, 0x07, 0x00, 0x00, 0x00, 0x00}, /* 24, -12.0dB */
  140. {0x0d, 0x0c, 0x0b, 0x06, 0x00, 0x00, 0x00, 0x00}, /* 25, -12.5dB */
  141. {0x0c, 0x0c, 0x0a, 0x06, 0x00, 0x00, 0x00, 0x00}, /* 26, -13.0dB */
  142. {0x0b, 0x0b, 0x0a, 0x06, 0x00, 0x00, 0x00, 0x00}, /* 27, -13.5dB */
  143. {0x0b, 0x0a, 0x09, 0x05, 0x00, 0x00, 0x00, 0x00}, /* 28, -14.0dB */
  144. {0x0a, 0x0a, 0x09, 0x05, 0x00, 0x00, 0x00, 0x00}, /* 29, -14.5dB */
  145. {0x0a, 0x09, 0x08, 0x05, 0x00, 0x00, 0x00, 0x00}, /* 30, -15.0dB */
  146. {0x09, 0x09, 0x08, 0x05, 0x00, 0x00, 0x00, 0x00}, /* 31, -15.5dB */
  147. {0x09, 0x08, 0x07, 0x04, 0x00, 0x00, 0x00, 0x00} /* 32, -16.0dB */
  148. };
  149. static void rtl92ee_dm_diginit(struct ieee80211_hw *hw)
  150. {
  151. struct rtl_priv *rtlpriv = rtl_priv(hw);
  152. struct dig_t *dm_dig = &rtlpriv->dm_digtable;
  153. dm_dig->cur_igvalue = rtl_get_bbreg(hw, DM_REG_IGI_A_11N,
  154. DM_BIT_IGI_11N);
  155. dm_dig->rssi_lowthresh = DM_DIG_THRESH_LOW;
  156. dm_dig->rssi_highthresh = DM_DIG_THRESH_HIGH;
  157. dm_dig->fa_lowthresh = DM_FALSEALARM_THRESH_LOW;
  158. dm_dig->fa_highthresh = DM_FALSEALARM_THRESH_HIGH;
  159. dm_dig->rx_gain_max = DM_DIG_MAX;
  160. dm_dig->rx_gain_min = DM_DIG_MIN;
  161. dm_dig->back_val = DM_DIG_BACKOFF_DEFAULT;
  162. dm_dig->back_range_max = DM_DIG_BACKOFF_MAX;
  163. dm_dig->back_range_min = DM_DIG_BACKOFF_MIN;
  164. dm_dig->pre_cck_cca_thres = 0xff;
  165. dm_dig->cur_cck_cca_thres = 0x83;
  166. dm_dig->forbidden_igi = DM_DIG_MIN;
  167. dm_dig->large_fa_hit = 0;
  168. dm_dig->recover_cnt = 0;
  169. dm_dig->dig_dynamic_min = DM_DIG_MIN;
  170. dm_dig->dig_dynamic_min_1 = DM_DIG_MIN;
  171. dm_dig->media_connect_0 = false;
  172. dm_dig->media_connect_1 = false;
  173. rtlpriv->dm.dm_initialgain_enable = true;
  174. dm_dig->bt30_cur_igi = 0x32;
  175. }
  176. static void rtl92ee_dm_false_alarm_counter_statistics(struct ieee80211_hw *hw)
  177. {
  178. u32 ret_value;
  179. struct rtl_priv *rtlpriv = rtl_priv(hw);
  180. struct false_alarm_statistics *falsealm_cnt = &rtlpriv->falsealm_cnt;
  181. rtl_set_bbreg(hw, DM_REG_OFDM_FA_HOLDC_11N, BIT(31), 1);
  182. rtl_set_bbreg(hw, DM_REG_OFDM_FA_RSTD_11N, BIT(31), 1);
  183. ret_value = rtl_get_bbreg(hw, DM_REG_OFDM_FA_TYPE1_11N, MASKDWORD);
  184. falsealm_cnt->cnt_fast_fsync_fail = (ret_value & 0xffff);
  185. falsealm_cnt->cnt_sb_search_fail = ((ret_value & 0xffff0000) >> 16);
  186. ret_value = rtl_get_bbreg(hw, DM_REG_OFDM_FA_TYPE2_11N, MASKDWORD);
  187. falsealm_cnt->cnt_ofdm_cca = (ret_value & 0xffff);
  188. falsealm_cnt->cnt_parity_fail = ((ret_value & 0xffff0000) >> 16);
  189. ret_value = rtl_get_bbreg(hw, DM_REG_OFDM_FA_TYPE3_11N, MASKDWORD);
  190. falsealm_cnt->cnt_rate_illegal = (ret_value & 0xffff);
  191. falsealm_cnt->cnt_crc8_fail = ((ret_value & 0xffff0000) >> 16);
  192. ret_value = rtl_get_bbreg(hw, DM_REG_OFDM_FA_TYPE4_11N, MASKDWORD);
  193. falsealm_cnt->cnt_mcs_fail = (ret_value & 0xffff);
  194. falsealm_cnt->cnt_ofdm_fail = falsealm_cnt->cnt_parity_fail +
  195. falsealm_cnt->cnt_rate_illegal +
  196. falsealm_cnt->cnt_crc8_fail +
  197. falsealm_cnt->cnt_mcs_fail +
  198. falsealm_cnt->cnt_fast_fsync_fail +
  199. falsealm_cnt->cnt_sb_search_fail;
  200. ret_value = rtl_get_bbreg(hw, DM_REG_SC_CNT_11N, MASKDWORD);
  201. falsealm_cnt->cnt_bw_lsc = (ret_value & 0xffff);
  202. falsealm_cnt->cnt_bw_usc = ((ret_value & 0xffff0000) >> 16);
  203. rtl_set_bbreg(hw, DM_REG_CCK_FA_RST_11N, BIT(12), 1);
  204. rtl_set_bbreg(hw, DM_REG_CCK_FA_RST_11N, BIT(14), 1);
  205. ret_value = rtl_get_bbreg(hw, DM_REG_CCK_FA_LSB_11N, MASKBYTE0);
  206. falsealm_cnt->cnt_cck_fail = ret_value;
  207. ret_value = rtl_get_bbreg(hw, DM_REG_CCK_FA_MSB_11N, MASKBYTE3);
  208. falsealm_cnt->cnt_cck_fail += (ret_value & 0xff) << 8;
  209. ret_value = rtl_get_bbreg(hw, DM_REG_CCK_CCA_CNT_11N, MASKDWORD);
  210. falsealm_cnt->cnt_cck_cca = ((ret_value & 0xff) << 8) |
  211. ((ret_value & 0xFF00) >> 8);
  212. falsealm_cnt->cnt_all = falsealm_cnt->cnt_fast_fsync_fail +
  213. falsealm_cnt->cnt_sb_search_fail +
  214. falsealm_cnt->cnt_parity_fail +
  215. falsealm_cnt->cnt_rate_illegal +
  216. falsealm_cnt->cnt_crc8_fail +
  217. falsealm_cnt->cnt_mcs_fail +
  218. falsealm_cnt->cnt_cck_fail;
  219. falsealm_cnt->cnt_cca_all = falsealm_cnt->cnt_ofdm_cca +
  220. falsealm_cnt->cnt_cck_cca;
  221. /*reset false alarm counter registers*/
  222. rtl_set_bbreg(hw, DM_REG_OFDM_FA_RSTC_11N, BIT(31), 1);
  223. rtl_set_bbreg(hw, DM_REG_OFDM_FA_RSTC_11N, BIT(31), 0);
  224. rtl_set_bbreg(hw, DM_REG_OFDM_FA_RSTD_11N, BIT(27), 1);
  225. rtl_set_bbreg(hw, DM_REG_OFDM_FA_RSTD_11N, BIT(27), 0);
  226. /*update ofdm counter*/
  227. rtl_set_bbreg(hw, DM_REG_OFDM_FA_HOLDC_11N, BIT(31), 0);
  228. rtl_set_bbreg(hw, DM_REG_OFDM_FA_RSTD_11N, BIT(31), 0);
  229. /*reset CCK CCA counter*/
  230. rtl_set_bbreg(hw, DM_REG_CCK_FA_RST_11N, BIT(13) | BIT(12), 0);
  231. rtl_set_bbreg(hw, DM_REG_CCK_FA_RST_11N, BIT(13) | BIT(12), 2);
  232. /*reset CCK FA counter*/
  233. rtl_set_bbreg(hw, DM_REG_CCK_FA_RST_11N, BIT(15) | BIT(14), 0);
  234. rtl_set_bbreg(hw, DM_REG_CCK_FA_RST_11N, BIT(15) | BIT(14), 2);
  235. RT_TRACE(rtlpriv, COMP_DIG, DBG_TRACE,
  236. "cnt_parity_fail = %d, cnt_rate_illegal = %d, cnt_crc8_fail = %d, cnt_mcs_fail = %d\n",
  237. falsealm_cnt->cnt_parity_fail,
  238. falsealm_cnt->cnt_rate_illegal,
  239. falsealm_cnt->cnt_crc8_fail, falsealm_cnt->cnt_mcs_fail);
  240. RT_TRACE(rtlpriv, COMP_DIG, DBG_TRACE,
  241. "cnt_ofdm_fail = %x, cnt_cck_fail = %x, cnt_all = %x\n",
  242. falsealm_cnt->cnt_ofdm_fail,
  243. falsealm_cnt->cnt_cck_fail, falsealm_cnt->cnt_all);
  244. }
  245. static void rtl92ee_dm_cck_packet_detection_thresh(struct ieee80211_hw *hw)
  246. {
  247. struct rtl_priv *rtlpriv = rtl_priv(hw);
  248. struct dig_t *dm_dig = &rtlpriv->dm_digtable;
  249. u8 cur_cck_cca_thresh;
  250. if (rtlpriv->mac80211.link_state >= MAC80211_LINKED) {
  251. if (dm_dig->rssi_val_min > 25) {
  252. cur_cck_cca_thresh = 0xcd;
  253. } else if ((dm_dig->rssi_val_min <= 25) &&
  254. (dm_dig->rssi_val_min > 10)) {
  255. cur_cck_cca_thresh = 0x83;
  256. } else {
  257. if (rtlpriv->falsealm_cnt.cnt_cck_fail > 1000)
  258. cur_cck_cca_thresh = 0x83;
  259. else
  260. cur_cck_cca_thresh = 0x40;
  261. }
  262. } else {
  263. if (rtlpriv->falsealm_cnt.cnt_cck_fail > 1000)
  264. cur_cck_cca_thresh = 0x83;
  265. else
  266. cur_cck_cca_thresh = 0x40;
  267. }
  268. rtl92ee_dm_write_cck_cca_thres(hw, cur_cck_cca_thresh);
  269. }
  270. static void rtl92ee_dm_dig(struct ieee80211_hw *hw)
  271. {
  272. struct rtl_priv *rtlpriv = rtl_priv(hw);
  273. struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
  274. struct dig_t *dm_dig = &rtlpriv->dm_digtable;
  275. u8 dig_dynamic_min , dig_maxofmin;
  276. bool bfirstconnect , bfirstdisconnect;
  277. u8 dm_dig_max, dm_dig_min;
  278. u8 current_igi = dm_dig->cur_igvalue;
  279. u8 offset;
  280. /* AP,BT */
  281. if (mac->act_scanning)
  282. return;
  283. dig_dynamic_min = dm_dig->dig_dynamic_min;
  284. bfirstconnect = (mac->link_state >= MAC80211_LINKED) &&
  285. !dm_dig->media_connect_0;
  286. bfirstdisconnect = (mac->link_state < MAC80211_LINKED) &&
  287. dm_dig->media_connect_0;
  288. dm_dig_max = 0x5a;
  289. dm_dig_min = DM_DIG_MIN;
  290. dig_maxofmin = DM_DIG_MAX_AP;
  291. if (mac->link_state >= MAC80211_LINKED) {
  292. if ((dm_dig->rssi_val_min + 10) > dm_dig_max)
  293. dm_dig->rx_gain_max = dm_dig_max;
  294. else if ((dm_dig->rssi_val_min + 10) < dm_dig_min)
  295. dm_dig->rx_gain_max = dm_dig_min;
  296. else
  297. dm_dig->rx_gain_max = dm_dig->rssi_val_min + 10;
  298. if (rtlpriv->dm.one_entry_only) {
  299. offset = 0;
  300. if (dm_dig->rssi_val_min - offset < dm_dig_min)
  301. dig_dynamic_min = dm_dig_min;
  302. else if (dm_dig->rssi_val_min - offset >
  303. dig_maxofmin)
  304. dig_dynamic_min = dig_maxofmin;
  305. else
  306. dig_dynamic_min = dm_dig->rssi_val_min - offset;
  307. } else {
  308. dig_dynamic_min = dm_dig_min;
  309. }
  310. } else {
  311. dm_dig->rx_gain_max = dm_dig_max;
  312. dig_dynamic_min = dm_dig_min;
  313. RT_TRACE(rtlpriv, COMP_DIG, DBG_LOUD, "no link\n");
  314. }
  315. if (rtlpriv->falsealm_cnt.cnt_all > 10000) {
  316. if (dm_dig->large_fa_hit != 3)
  317. dm_dig->large_fa_hit++;
  318. if (dm_dig->forbidden_igi < current_igi) {
  319. dm_dig->forbidden_igi = current_igi;
  320. dm_dig->large_fa_hit = 1;
  321. }
  322. if (dm_dig->large_fa_hit >= 3) {
  323. if (dm_dig->forbidden_igi + 1 > dm_dig->rx_gain_max)
  324. dm_dig->rx_gain_min =
  325. dm_dig->rx_gain_max;
  326. else
  327. dm_dig->rx_gain_min =
  328. dm_dig->forbidden_igi + 1;
  329. dm_dig->recover_cnt = 3600;
  330. }
  331. } else {
  332. if (dm_dig->recover_cnt != 0) {
  333. dm_dig->recover_cnt--;
  334. } else {
  335. if (dm_dig->large_fa_hit < 3) {
  336. if ((dm_dig->forbidden_igi - 1) <
  337. dig_dynamic_min) {
  338. dm_dig->forbidden_igi = dig_dynamic_min;
  339. dm_dig->rx_gain_min =
  340. dig_dynamic_min;
  341. } else {
  342. dm_dig->forbidden_igi--;
  343. dm_dig->rx_gain_min =
  344. dm_dig->forbidden_igi + 1;
  345. }
  346. } else {
  347. dm_dig->large_fa_hit = 0;
  348. }
  349. }
  350. }
  351. if (rtlpriv->dm.dbginfo.num_qry_beacon_pkt < 5)
  352. dm_dig->rx_gain_min = dm_dig_min;
  353. if (dm_dig->rx_gain_min > dm_dig->rx_gain_max)
  354. dm_dig->rx_gain_min = dm_dig->rx_gain_max;
  355. if (mac->link_state >= MAC80211_LINKED) {
  356. if (bfirstconnect) {
  357. if (dm_dig->rssi_val_min <= dig_maxofmin)
  358. current_igi = dm_dig->rssi_val_min;
  359. else
  360. current_igi = dig_maxofmin;
  361. dm_dig->large_fa_hit = 0;
  362. } else {
  363. if (rtlpriv->falsealm_cnt.cnt_all > DM_DIG_FA_TH2)
  364. current_igi += 4;
  365. else if (rtlpriv->falsealm_cnt.cnt_all > DM_DIG_FA_TH1)
  366. current_igi += 2;
  367. else if (rtlpriv->falsealm_cnt.cnt_all < DM_DIG_FA_TH0)
  368. current_igi -= 2;
  369. if (rtlpriv->dm.dbginfo.num_qry_beacon_pkt < 5 &&
  370. rtlpriv->falsealm_cnt.cnt_all < DM_DIG_FA_TH1)
  371. current_igi = dm_dig->rx_gain_min;
  372. }
  373. } else {
  374. if (bfirstdisconnect) {
  375. current_igi = dm_dig->rx_gain_min;
  376. } else {
  377. if (rtlpriv->falsealm_cnt.cnt_all > 10000)
  378. current_igi += 4;
  379. else if (rtlpriv->falsealm_cnt.cnt_all > 8000)
  380. current_igi += 2;
  381. else if (rtlpriv->falsealm_cnt.cnt_all < 500)
  382. current_igi -= 2;
  383. }
  384. }
  385. if (current_igi > dm_dig->rx_gain_max)
  386. current_igi = dm_dig->rx_gain_max;
  387. if (current_igi < dm_dig->rx_gain_min)
  388. current_igi = dm_dig->rx_gain_min;
  389. rtl92ee_dm_write_dig(hw , current_igi);
  390. dm_dig->media_connect_0 = ((mac->link_state >= MAC80211_LINKED) ?
  391. true : false);
  392. dm_dig->dig_dynamic_min = dig_dynamic_min;
  393. }
  394. void rtl92ee_dm_write_cck_cca_thres(struct ieee80211_hw *hw, u8 cur_thres)
  395. {
  396. struct rtl_priv *rtlpriv = rtl_priv(hw);
  397. struct dig_t *dm_dig = &rtlpriv->dm_digtable;
  398. if (dm_dig->cur_cck_cca_thres != cur_thres)
  399. rtl_write_byte(rtlpriv, DM_REG_CCK_CCA_11N, cur_thres);
  400. dm_dig->pre_cck_cca_thres = dm_dig->cur_cck_cca_thres;
  401. dm_dig->cur_cck_cca_thres = cur_thres;
  402. }
  403. void rtl92ee_dm_write_dig(struct ieee80211_hw *hw, u8 current_igi)
  404. {
  405. struct rtl_priv *rtlpriv = rtl_priv(hw);
  406. struct dig_t *dm_dig = &rtlpriv->dm_digtable;
  407. if (dm_dig->stop_dig)
  408. return;
  409. if (dm_dig->cur_igvalue != current_igi) {
  410. rtl_set_bbreg(hw, ROFDM0_XAAGCCORE1, 0x7f, current_igi);
  411. if (rtlpriv->phy.rf_type != RF_1T1R)
  412. rtl_set_bbreg(hw, ROFDM0_XBAGCCORE1, 0x7f, current_igi);
  413. }
  414. dm_dig->pre_igvalue = dm_dig->cur_igvalue;
  415. dm_dig->cur_igvalue = current_igi;
  416. }
  417. static void rtl92ee_rssi_dump_to_register(struct ieee80211_hw *hw)
  418. {
  419. struct rtl_priv *rtlpriv = rtl_priv(hw);
  420. rtl_write_byte(rtlpriv, RA_RSSIDUMP,
  421. rtlpriv->stats.rx_rssi_percentage[0]);
  422. rtl_write_byte(rtlpriv, RB_RSSIDUMP,
  423. rtlpriv->stats.rx_rssi_percentage[1]);
  424. /*It seems the following values are not initialized.
  425. *According to Windows code,
  426. *these value will only be valid with JAGUAR chips
  427. */
  428. /* Rx EVM */
  429. rtl_write_byte(rtlpriv, RS1_RXEVMDUMP, rtlpriv->stats.rx_evm_dbm[0]);
  430. rtl_write_byte(rtlpriv, RS2_RXEVMDUMP, rtlpriv->stats.rx_evm_dbm[1]);
  431. /* Rx SNR */
  432. rtl_write_byte(rtlpriv, RA_RXSNRDUMP,
  433. (u8)(rtlpriv->stats.rx_snr_db[0]));
  434. rtl_write_byte(rtlpriv, RB_RXSNRDUMP,
  435. (u8)(rtlpriv->stats.rx_snr_db[1]));
  436. /* Rx Cfo_Short */
  437. rtl_write_word(rtlpriv, RA_CFOSHORTDUMP,
  438. rtlpriv->stats.rx_cfo_short[0]);
  439. rtl_write_word(rtlpriv, RB_CFOSHORTDUMP,
  440. rtlpriv->stats.rx_cfo_short[1]);
  441. /* Rx Cfo_Tail */
  442. rtl_write_word(rtlpriv, RA_CFOLONGDUMP, rtlpriv->stats.rx_cfo_tail[0]);
  443. rtl_write_word(rtlpriv, RB_CFOLONGDUMP, rtlpriv->stats.rx_cfo_tail[1]);
  444. }
  445. static void rtl92ee_dm_find_minimum_rssi(struct ieee80211_hw *hw)
  446. {
  447. struct rtl_priv *rtlpriv = rtl_priv(hw);
  448. struct dig_t *rtl_dm_dig = &rtlpriv->dm_digtable;
  449. struct rtl_mac *mac = rtl_mac(rtlpriv);
  450. /* Determine the minimum RSSI */
  451. if ((mac->link_state < MAC80211_LINKED) &&
  452. (rtlpriv->dm.entry_min_undec_sm_pwdb == 0)) {
  453. rtl_dm_dig->min_undec_pwdb_for_dm = 0;
  454. RT_TRACE(rtlpriv, COMP_BB_POWERSAVING, DBG_LOUD,
  455. "Not connected to any\n");
  456. }
  457. if (mac->link_state >= MAC80211_LINKED) {
  458. if (mac->opmode == NL80211_IFTYPE_AP ||
  459. mac->opmode == NL80211_IFTYPE_ADHOC) {
  460. rtl_dm_dig->min_undec_pwdb_for_dm =
  461. rtlpriv->dm.entry_min_undec_sm_pwdb;
  462. RT_TRACE(rtlpriv, COMP_BB_POWERSAVING, DBG_LOUD,
  463. "AP Client PWDB = 0x%lx\n",
  464. rtlpriv->dm.entry_min_undec_sm_pwdb);
  465. } else {
  466. rtl_dm_dig->min_undec_pwdb_for_dm =
  467. rtlpriv->dm.undec_sm_pwdb;
  468. RT_TRACE(rtlpriv, COMP_BB_POWERSAVING, DBG_LOUD,
  469. "STA Default Port PWDB = 0x%x\n",
  470. rtl_dm_dig->min_undec_pwdb_for_dm);
  471. }
  472. } else {
  473. rtl_dm_dig->min_undec_pwdb_for_dm =
  474. rtlpriv->dm.entry_min_undec_sm_pwdb;
  475. RT_TRACE(rtlpriv, COMP_BB_POWERSAVING, DBG_LOUD,
  476. "AP Ext Port or disconnet PWDB = 0x%x\n",
  477. rtl_dm_dig->min_undec_pwdb_for_dm);
  478. }
  479. RT_TRACE(rtlpriv, COMP_DIG, DBG_LOUD,
  480. "MinUndecoratedPWDBForDM =%d\n",
  481. rtl_dm_dig->min_undec_pwdb_for_dm);
  482. }
  483. static void rtl92ee_dm_check_rssi_monitor(struct ieee80211_hw *hw)
  484. {
  485. struct rtl_priv *rtlpriv = rtl_priv(hw);
  486. struct dig_t *dm_dig = &rtlpriv->dm_digtable;
  487. struct rtl_mac *mac = rtl_mac(rtlpriv);
  488. struct rtl_dm *dm = rtl_dm(rtlpriv);
  489. struct rtl_sta_info *drv_priv;
  490. u8 h2c[4] = { 0 };
  491. long max = 0, min = 0xff;
  492. u8 i = 0;
  493. if (mac->opmode == NL80211_IFTYPE_AP ||
  494. mac->opmode == NL80211_IFTYPE_ADHOC ||
  495. mac->opmode == NL80211_IFTYPE_MESH_POINT) {
  496. /* AP & ADHOC & MESH */
  497. spin_lock_bh(&rtlpriv->locks.entry_list_lock);
  498. list_for_each_entry(drv_priv, &rtlpriv->entry_list, list) {
  499. struct rssi_sta *stat = &drv_priv->rssi_stat;
  500. if (stat->undec_sm_pwdb < min)
  501. min = stat->undec_sm_pwdb;
  502. if (stat->undec_sm_pwdb > max)
  503. max = stat->undec_sm_pwdb;
  504. h2c[3] = 0;
  505. h2c[2] = (u8)(dm->undec_sm_pwdb & 0xFF);
  506. h2c[1] = 0x20;
  507. h2c[0] = ++i;
  508. rtl92ee_fill_h2c_cmd(hw, H2C_92E_RSSI_REPORT, 4, h2c);
  509. }
  510. spin_unlock_bh(&rtlpriv->locks.entry_list_lock);
  511. /* If associated entry is found */
  512. if (max != 0) {
  513. dm->entry_max_undec_sm_pwdb = max;
  514. RTPRINT(rtlpriv, FDM, DM_PWDB,
  515. "EntryMaxPWDB = 0x%lx(%ld)\n", max, max);
  516. } else {
  517. dm->entry_max_undec_sm_pwdb = 0;
  518. }
  519. /* If associated entry is found */
  520. if (min != 0xff) {
  521. dm->entry_min_undec_sm_pwdb = min;
  522. RTPRINT(rtlpriv, FDM, DM_PWDB,
  523. "EntryMinPWDB = 0x%lx(%ld)\n", min, min);
  524. } else {
  525. dm->entry_min_undec_sm_pwdb = 0;
  526. }
  527. }
  528. /* Indicate Rx signal strength to FW. */
  529. if (dm->useramask) {
  530. h2c[3] = 0;
  531. h2c[2] = (u8)(dm->undec_sm_pwdb & 0xFF);
  532. h2c[1] = 0x20;
  533. h2c[0] = 0;
  534. rtl92ee_fill_h2c_cmd(hw, H2C_92E_RSSI_REPORT, 4, h2c);
  535. } else {
  536. rtl_write_byte(rtlpriv, 0x4fe, dm->undec_sm_pwdb);
  537. }
  538. rtl92ee_rssi_dump_to_register(hw);
  539. rtl92ee_dm_find_minimum_rssi(hw);
  540. dm_dig->rssi_val_min = rtlpriv->dm_digtable.min_undec_pwdb_for_dm;
  541. }
  542. static void rtl92ee_dm_init_primary_cca_check(struct ieee80211_hw *hw)
  543. {
  544. struct rtl_priv *rtlpriv = rtl_priv(hw);
  545. struct rtl_hal *rtlhal = rtl_hal(rtlpriv);
  546. struct dynamic_primary_cca *primarycca = &rtlpriv->primarycca;
  547. rtlhal->rts_en = 0;
  548. primarycca->dup_rts_flag = 0;
  549. primarycca->intf_flag = 0;
  550. primarycca->intf_type = 0;
  551. primarycca->monitor_flag = 0;
  552. primarycca->ch_offset = 0;
  553. primarycca->mf_state = 0;
  554. }
  555. static bool rtl92ee_dm_is_edca_turbo_disable(struct ieee80211_hw *hw)
  556. {
  557. struct rtl_priv *rtlpriv = rtl_priv(hw);
  558. if (rtlpriv->mac80211.mode == WIRELESS_MODE_B)
  559. return true;
  560. return false;
  561. }
  562. void rtl92ee_dm_init_edca_turbo(struct ieee80211_hw *hw)
  563. {
  564. struct rtl_priv *rtlpriv = rtl_priv(hw);
  565. rtlpriv->dm.current_turbo_edca = false;
  566. rtlpriv->dm.is_cur_rdlstate = false;
  567. rtlpriv->dm.is_any_nonbepkts = false;
  568. }
  569. static void rtl92ee_dm_check_edca_turbo(struct ieee80211_hw *hw)
  570. {
  571. struct rtl_priv *rtlpriv = rtl_priv(hw);
  572. static u64 last_txok_cnt;
  573. static u64 last_rxok_cnt;
  574. u64 cur_txok_cnt = 0;
  575. u64 cur_rxok_cnt = 0;
  576. u32 edca_be_ul = 0x5ea42b;
  577. u32 edca_be_dl = 0x5ea42b; /*not sure*/
  578. u32 edca_be = 0x5ea42b;
  579. bool is_cur_rdlstate;
  580. bool b_edca_turbo_on = false;
  581. if (rtlpriv->dm.dbginfo.num_non_be_pkt > 0x100)
  582. rtlpriv->dm.is_any_nonbepkts = true;
  583. rtlpriv->dm.dbginfo.num_non_be_pkt = 0;
  584. cur_txok_cnt = rtlpriv->stats.txbytesunicast - last_txok_cnt;
  585. cur_rxok_cnt = rtlpriv->stats.rxbytesunicast - last_rxok_cnt;
  586. /*b_bias_on_rx = false;*/
  587. b_edca_turbo_on = ((!rtlpriv->dm.is_any_nonbepkts) &&
  588. (!rtlpriv->dm.disable_framebursting)) ?
  589. true : false;
  590. if (rtl92ee_dm_is_edca_turbo_disable(hw))
  591. goto check_exit;
  592. if (b_edca_turbo_on) {
  593. is_cur_rdlstate = (cur_rxok_cnt > cur_txok_cnt * 4) ?
  594. true : false;
  595. edca_be = is_cur_rdlstate ? edca_be_dl : edca_be_ul;
  596. rtl_write_dword(rtlpriv , REG_EDCA_BE_PARAM , edca_be);
  597. rtlpriv->dm.is_cur_rdlstate = is_cur_rdlstate;
  598. rtlpriv->dm.current_turbo_edca = true;
  599. } else {
  600. if (rtlpriv->dm.current_turbo_edca) {
  601. u8 tmp = AC0_BE;
  602. rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_AC_PARAM,
  603. (u8 *)(&tmp));
  604. }
  605. rtlpriv->dm.current_turbo_edca = false;
  606. }
  607. check_exit:
  608. rtlpriv->dm.is_any_nonbepkts = false;
  609. last_txok_cnt = rtlpriv->stats.txbytesunicast;
  610. last_rxok_cnt = rtlpriv->stats.rxbytesunicast;
  611. }
  612. static void rtl92ee_dm_dynamic_edcca(struct ieee80211_hw *hw)
  613. {
  614. struct rtl_priv *rtlpriv = rtl_priv(hw);
  615. u8 reg_c50 , reg_c58;
  616. bool fw_current_in_ps_mode = false;
  617. rtlpriv->cfg->ops->get_hw_reg(hw, HW_VAR_FW_PSMODE_STATUS,
  618. (u8 *)(&fw_current_in_ps_mode));
  619. if (fw_current_in_ps_mode)
  620. return;
  621. reg_c50 = rtl_get_bbreg(hw, ROFDM0_XAAGCCORE1, MASKBYTE0);
  622. reg_c58 = rtl_get_bbreg(hw, ROFDM0_XBAGCCORE1, MASKBYTE0);
  623. if (reg_c50 > 0x28 && reg_c58 > 0x28) {
  624. if (!rtlpriv->rtlhal.pre_edcca_enable) {
  625. rtl_write_byte(rtlpriv, ROFDM0_ECCATHRESHOLD, 0x03);
  626. rtl_write_byte(rtlpriv, ROFDM0_ECCATHRESHOLD + 2, 0x00);
  627. rtlpriv->rtlhal.pre_edcca_enable = true;
  628. }
  629. } else if (reg_c50 < 0x25 && reg_c58 < 0x25) {
  630. if (rtlpriv->rtlhal.pre_edcca_enable) {
  631. rtl_write_byte(rtlpriv, ROFDM0_ECCATHRESHOLD, 0x7f);
  632. rtl_write_byte(rtlpriv, ROFDM0_ECCATHRESHOLD + 2, 0x7f);
  633. rtlpriv->rtlhal.pre_edcca_enable = false;
  634. }
  635. }
  636. }
  637. static void rtl92ee_dm_adaptivity(struct ieee80211_hw *hw)
  638. {
  639. rtl92ee_dm_dynamic_edcca(hw);
  640. }
  641. static void rtl92ee_dm_write_dynamic_cca(struct ieee80211_hw *hw,
  642. u8 cur_mf_state)
  643. {
  644. struct dynamic_primary_cca *primarycca = &rtl_priv(hw)->primarycca;
  645. if (primarycca->mf_state != cur_mf_state)
  646. rtl_set_bbreg(hw, DM_REG_L1SBD_PD_CH_11N, BIT(8) | BIT(7),
  647. cur_mf_state);
  648. primarycca->mf_state = cur_mf_state;
  649. }
  650. static void rtl92ee_dm_dynamic_primary_cca_ckeck(struct ieee80211_hw *hw)
  651. {
  652. struct rtl_priv *rtlpriv = rtl_priv(hw);
  653. struct false_alarm_statistics *falsealm_cnt = &rtlpriv->falsealm_cnt;
  654. struct dynamic_primary_cca *primarycca = &rtlpriv->primarycca;
  655. bool is40mhz = false;
  656. u64 ofdm_cca, ofdm_fa, bw_usc_cnt, bw_lsc_cnt;
  657. u8 sec_ch_offset;
  658. u8 cur_mf_state;
  659. static u8 count_down = MONITOR_TIME;
  660. ofdm_cca = falsealm_cnt->cnt_ofdm_cca;
  661. ofdm_fa = falsealm_cnt->cnt_ofdm_fail;
  662. bw_usc_cnt = falsealm_cnt->cnt_bw_usc;
  663. bw_lsc_cnt = falsealm_cnt->cnt_bw_lsc;
  664. is40mhz = rtlpriv->mac80211.bw_40;
  665. sec_ch_offset = rtlpriv->mac80211.cur_40_prime_sc;
  666. /* NIC: 2: sec is below, 1: sec is above */
  667. if (rtlpriv->mac80211.opmode == NL80211_IFTYPE_AP) {
  668. cur_mf_state = MF_USC_LSC;
  669. rtl92ee_dm_write_dynamic_cca(hw, cur_mf_state);
  670. return;
  671. }
  672. if (rtlpriv->mac80211.link_state < MAC80211_LINKED)
  673. return;
  674. if (is40mhz)
  675. return;
  676. if (primarycca->pricca_flag == 0) {
  677. /* Primary channel is above
  678. * NOTE: duplicate CTS can remove this condition
  679. */
  680. if (sec_ch_offset == 2) {
  681. if ((ofdm_cca > OFDMCCA_TH) &&
  682. (bw_lsc_cnt > (bw_usc_cnt + BW_IND_BIAS)) &&
  683. (ofdm_fa > (ofdm_cca >> 1))) {
  684. primarycca->intf_type = 1;
  685. primarycca->intf_flag = 1;
  686. cur_mf_state = MF_USC;
  687. rtl92ee_dm_write_dynamic_cca(hw, cur_mf_state);
  688. primarycca->pricca_flag = 1;
  689. } else if ((ofdm_cca > OFDMCCA_TH) &&
  690. (bw_lsc_cnt > (bw_usc_cnt + BW_IND_BIAS)) &&
  691. (ofdm_fa < (ofdm_cca >> 1))) {
  692. primarycca->intf_type = 2;
  693. primarycca->intf_flag = 1;
  694. cur_mf_state = MF_USC;
  695. rtl92ee_dm_write_dynamic_cca(hw, cur_mf_state);
  696. primarycca->pricca_flag = 1;
  697. primarycca->dup_rts_flag = 1;
  698. rtlpriv->rtlhal.rts_en = 1;
  699. } else {
  700. primarycca->intf_type = 0;
  701. primarycca->intf_flag = 0;
  702. cur_mf_state = MF_USC_LSC;
  703. rtl92ee_dm_write_dynamic_cca(hw, cur_mf_state);
  704. rtlpriv->rtlhal.rts_en = 0;
  705. primarycca->dup_rts_flag = 0;
  706. }
  707. } else if (sec_ch_offset == 1) {
  708. if ((ofdm_cca > OFDMCCA_TH) &&
  709. (bw_usc_cnt > (bw_lsc_cnt + BW_IND_BIAS)) &&
  710. (ofdm_fa > (ofdm_cca >> 1))) {
  711. primarycca->intf_type = 1;
  712. primarycca->intf_flag = 1;
  713. cur_mf_state = MF_LSC;
  714. rtl92ee_dm_write_dynamic_cca(hw, cur_mf_state);
  715. primarycca->pricca_flag = 1;
  716. } else if ((ofdm_cca > OFDMCCA_TH) &&
  717. (bw_usc_cnt > (bw_lsc_cnt + BW_IND_BIAS)) &&
  718. (ofdm_fa < (ofdm_cca >> 1))) {
  719. primarycca->intf_type = 2;
  720. primarycca->intf_flag = 1;
  721. cur_mf_state = MF_LSC;
  722. rtl92ee_dm_write_dynamic_cca(hw, cur_mf_state);
  723. primarycca->pricca_flag = 1;
  724. primarycca->dup_rts_flag = 1;
  725. rtlpriv->rtlhal.rts_en = 1;
  726. } else {
  727. primarycca->intf_type = 0;
  728. primarycca->intf_flag = 0;
  729. cur_mf_state = MF_USC_LSC;
  730. rtl92ee_dm_write_dynamic_cca(hw, cur_mf_state);
  731. rtlpriv->rtlhal.rts_en = 0;
  732. primarycca->dup_rts_flag = 0;
  733. }
  734. }
  735. } else {/* PrimaryCCA->PriCCA_flag==1 */
  736. count_down--;
  737. if (count_down == 0) {
  738. count_down = MONITOR_TIME;
  739. primarycca->pricca_flag = 0;
  740. cur_mf_state = MF_USC_LSC;
  741. /* default */
  742. rtl92ee_dm_write_dynamic_cca(hw, cur_mf_state);
  743. rtlpriv->rtlhal.rts_en = 0;
  744. primarycca->dup_rts_flag = 0;
  745. primarycca->intf_type = 0;
  746. primarycca->intf_flag = 0;
  747. }
  748. }
  749. }
  750. static void rtl92ee_dm_dynamic_atc_switch(struct ieee80211_hw *hw)
  751. {
  752. struct rtl_priv *rtlpriv = rtl_priv(hw);
  753. struct rtl_dm *rtldm = rtl_dm(rtl_priv(hw));
  754. u8 crystal_cap;
  755. u32 packet_count;
  756. int cfo_khz_a , cfo_khz_b , cfo_ave = 0, adjust_xtal = 0;
  757. int cfo_ave_diff;
  758. if (rtlpriv->mac80211.link_state < MAC80211_LINKED) {
  759. if (rtldm->atc_status == ATC_STATUS_OFF) {
  760. rtl_set_bbreg(hw, ROFDM1_CFOTRACKING, BIT(11),
  761. ATC_STATUS_ON);
  762. rtldm->atc_status = ATC_STATUS_ON;
  763. }
  764. /* Disable CFO tracking for BT */
  765. if (rtlpriv->cfg->ops->get_btc_status()) {
  766. if (!rtlpriv->btcoexist.btc_ops->
  767. btc_is_bt_disabled(rtlpriv)) {
  768. RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_LOUD,
  769. "odm_DynamicATCSwitch(): Disable CFO tracking for BT!!\n");
  770. return;
  771. }
  772. }
  773. /* Reset Crystal Cap */
  774. if (rtldm->crystal_cap != rtlpriv->efuse.crystalcap) {
  775. rtldm->crystal_cap = rtlpriv->efuse.crystalcap;
  776. crystal_cap = rtldm->crystal_cap & 0x3f;
  777. rtl_set_bbreg(hw, REG_MAC_PHY_CTRL, 0xFFF000,
  778. (crystal_cap | (crystal_cap << 6)));
  779. }
  780. } else {
  781. cfo_khz_a = (int)(rtldm->cfo_tail[0] * 3125) / 1280;
  782. cfo_khz_b = (int)(rtldm->cfo_tail[1] * 3125) / 1280;
  783. packet_count = rtldm->packet_count;
  784. if (packet_count == rtldm->packet_count_pre)
  785. return;
  786. rtldm->packet_count_pre = packet_count;
  787. if (rtlpriv->phy.rf_type == RF_1T1R)
  788. cfo_ave = cfo_khz_a;
  789. else
  790. cfo_ave = (int)(cfo_khz_a + cfo_khz_b) >> 1;
  791. cfo_ave_diff = (rtldm->cfo_ave_pre >= cfo_ave) ?
  792. (rtldm->cfo_ave_pre - cfo_ave) :
  793. (cfo_ave - rtldm->cfo_ave_pre);
  794. if (cfo_ave_diff > 20 && rtldm->large_cfo_hit == 0) {
  795. rtldm->large_cfo_hit = 1;
  796. return;
  797. }
  798. rtldm->large_cfo_hit = 0;
  799. rtldm->cfo_ave_pre = cfo_ave;
  800. if (cfo_ave >= -rtldm->cfo_threshold &&
  801. cfo_ave <= rtldm->cfo_threshold && rtldm->is_freeze == 0) {
  802. if (rtldm->cfo_threshold == CFO_THRESHOLD_XTAL) {
  803. rtldm->cfo_threshold = CFO_THRESHOLD_XTAL + 10;
  804. rtldm->is_freeze = 1;
  805. } else {
  806. rtldm->cfo_threshold = CFO_THRESHOLD_XTAL;
  807. }
  808. }
  809. if (cfo_ave > rtldm->cfo_threshold && rtldm->crystal_cap < 0x3f)
  810. adjust_xtal = ((cfo_ave - CFO_THRESHOLD_XTAL) >> 2) + 1;
  811. else if ((cfo_ave < -rtlpriv->dm.cfo_threshold) &&
  812. rtlpriv->dm.crystal_cap > 0)
  813. adjust_xtal = ((cfo_ave + CFO_THRESHOLD_XTAL) >> 2) - 1;
  814. if (adjust_xtal != 0) {
  815. rtldm->is_freeze = 0;
  816. rtldm->crystal_cap += adjust_xtal;
  817. if (rtldm->crystal_cap > 0x3f)
  818. rtldm->crystal_cap = 0x3f;
  819. else if (rtldm->crystal_cap < 0)
  820. rtldm->crystal_cap = 0;
  821. crystal_cap = rtldm->crystal_cap & 0x3f;
  822. rtl_set_bbreg(hw, REG_MAC_PHY_CTRL, 0xFFF000,
  823. (crystal_cap | (crystal_cap << 6)));
  824. }
  825. if (cfo_ave < CFO_THRESHOLD_ATC &&
  826. cfo_ave > -CFO_THRESHOLD_ATC) {
  827. if (rtldm->atc_status == ATC_STATUS_ON) {
  828. rtl_set_bbreg(hw, ROFDM1_CFOTRACKING, BIT(11),
  829. ATC_STATUS_OFF);
  830. rtldm->atc_status = ATC_STATUS_OFF;
  831. }
  832. } else {
  833. if (rtldm->atc_status == ATC_STATUS_OFF) {
  834. rtl_set_bbreg(hw, ROFDM1_CFOTRACKING, BIT(11),
  835. ATC_STATUS_ON);
  836. rtldm->atc_status = ATC_STATUS_ON;
  837. }
  838. }
  839. }
  840. }
  841. static void rtl92ee_dm_init_txpower_tracking(struct ieee80211_hw *hw)
  842. {
  843. struct rtl_priv *rtlpriv = rtl_priv(hw);
  844. struct rtl_dm *dm = rtl_dm(rtlpriv);
  845. u8 path;
  846. dm->txpower_tracking = true;
  847. dm->default_ofdm_index = 30;
  848. dm->default_cck_index = 20;
  849. dm->swing_idx_cck_base = dm->default_cck_index;
  850. dm->cck_index = dm->default_cck_index;
  851. for (path = RF90_PATH_A; path < MAX_RF_PATH; path++) {
  852. dm->swing_idx_ofdm_base[path] = dm->default_ofdm_index;
  853. dm->ofdm_index[path] = dm->default_ofdm_index;
  854. dm->delta_power_index[path] = 0;
  855. dm->delta_power_index_last[path] = 0;
  856. dm->power_index_offset[path] = 0;
  857. }
  858. }
  859. void rtl92ee_dm_init_rate_adaptive_mask(struct ieee80211_hw *hw)
  860. {
  861. struct rtl_priv *rtlpriv = rtl_priv(hw);
  862. struct rate_adaptive *p_ra = &rtlpriv->ra;
  863. p_ra->ratr_state = DM_RATR_STA_INIT;
  864. p_ra->pre_ratr_state = DM_RATR_STA_INIT;
  865. if (rtlpriv->dm.dm_type == DM_TYPE_BYDRIVER)
  866. rtlpriv->dm.useramask = true;
  867. else
  868. rtlpriv->dm.useramask = false;
  869. p_ra->ldpc_thres = 35;
  870. p_ra->use_ldpc = false;
  871. p_ra->high_rssi_thresh_for_ra = 50;
  872. p_ra->low_rssi_thresh_for_ra40m = 20;
  873. }
  874. static bool _rtl92ee_dm_ra_state_check(struct ieee80211_hw *hw,
  875. s32 rssi, u8 *ratr_state)
  876. {
  877. struct rtl_priv *rtlpriv = rtl_priv(hw);
  878. struct rate_adaptive *p_ra = &rtlpriv->ra;
  879. const u8 go_up_gap = 5;
  880. u32 high_rssithresh_for_ra = p_ra->high_rssi_thresh_for_ra;
  881. u32 low_rssithresh_for_ra = p_ra->low_rssi_thresh_for_ra40m;
  882. u8 state;
  883. /* Threshold Adjustment:
  884. * when RSSI state trends to go up one or two levels,
  885. * make sure RSSI is high enough.
  886. * Here GoUpGap is added to solve
  887. * the boundary's level alternation issue.
  888. */
  889. switch (*ratr_state) {
  890. case DM_RATR_STA_INIT:
  891. case DM_RATR_STA_HIGH:
  892. break;
  893. case DM_RATR_STA_MIDDLE:
  894. high_rssithresh_for_ra += go_up_gap;
  895. break;
  896. case DM_RATR_STA_LOW:
  897. high_rssithresh_for_ra += go_up_gap;
  898. low_rssithresh_for_ra += go_up_gap;
  899. break;
  900. default:
  901. RT_TRACE(rtlpriv, COMP_RATR, DBG_DMESG,
  902. "wrong rssi level setting %d !", *ratr_state);
  903. break;
  904. }
  905. /* Decide RATRState by RSSI. */
  906. if (rssi > high_rssithresh_for_ra)
  907. state = DM_RATR_STA_HIGH;
  908. else if (rssi > low_rssithresh_for_ra)
  909. state = DM_RATR_STA_MIDDLE;
  910. else
  911. state = DM_RATR_STA_LOW;
  912. if (*ratr_state != state) {
  913. *ratr_state = state;
  914. return true;
  915. }
  916. return false;
  917. }
  918. static void rtl92ee_dm_refresh_rate_adaptive_mask(struct ieee80211_hw *hw)
  919. {
  920. struct rtl_priv *rtlpriv = rtl_priv(hw);
  921. struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
  922. struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
  923. struct rate_adaptive *p_ra = &rtlpriv->ra;
  924. struct ieee80211_sta *sta = NULL;
  925. if (is_hal_stop(rtlhal)) {
  926. RT_TRACE(rtlpriv, COMP_RATE, DBG_LOUD,
  927. "driver is going to unload\n");
  928. return;
  929. }
  930. if (!rtlpriv->dm.useramask) {
  931. RT_TRACE(rtlpriv, COMP_RATE, DBG_LOUD,
  932. "driver does not control rate adaptive mask\n");
  933. return;
  934. }
  935. if (mac->link_state == MAC80211_LINKED &&
  936. mac->opmode == NL80211_IFTYPE_STATION) {
  937. if (rtlpriv->dm.undec_sm_pwdb < p_ra->ldpc_thres) {
  938. p_ra->use_ldpc = true;
  939. p_ra->lower_rts_rate = true;
  940. } else if (rtlpriv->dm.undec_sm_pwdb >
  941. (p_ra->ldpc_thres - 5)) {
  942. p_ra->use_ldpc = false;
  943. p_ra->lower_rts_rate = false;
  944. }
  945. if (_rtl92ee_dm_ra_state_check(hw, rtlpriv->dm.undec_sm_pwdb,
  946. &p_ra->ratr_state)) {
  947. rcu_read_lock();
  948. sta = rtl_find_sta(hw, mac->bssid);
  949. if (sta)
  950. rtlpriv->cfg->ops->update_rate_tbl(hw, sta,
  951. p_ra->ratr_state);
  952. rcu_read_unlock();
  953. p_ra->pre_ratr_state = p_ra->ratr_state;
  954. }
  955. }
  956. }
  957. static void rtl92ee_dm_init_dynamic_atc_switch(struct ieee80211_hw *hw)
  958. {
  959. struct rtl_priv *rtlpriv = rtl_priv(hw);
  960. rtlpriv->dm.crystal_cap = rtlpriv->efuse.crystalcap;
  961. rtlpriv->dm.atc_status = rtl_get_bbreg(hw, ROFDM1_CFOTRACKING, BIT(11));
  962. rtlpriv->dm.cfo_threshold = CFO_THRESHOLD_XTAL;
  963. }
  964. void rtl92ee_dm_init(struct ieee80211_hw *hw)
  965. {
  966. struct rtl_priv *rtlpriv = rtl_priv(hw);
  967. rtlpriv->dm.dm_type = DM_TYPE_BYDRIVER;
  968. rtl92ee_dm_diginit(hw);
  969. rtl92ee_dm_init_rate_adaptive_mask(hw);
  970. rtl92ee_dm_init_primary_cca_check(hw);
  971. rtl92ee_dm_init_edca_turbo(hw);
  972. rtl92ee_dm_init_txpower_tracking(hw);
  973. rtl92ee_dm_init_dynamic_atc_switch(hw);
  974. }
  975. static void rtl92ee_dm_common_info_self_update(struct ieee80211_hw *hw)
  976. {
  977. struct rtl_priv *rtlpriv = rtl_priv(hw);
  978. struct rtl_sta_info *drv_priv;
  979. u8 cnt = 0;
  980. rtlpriv->dm.one_entry_only = false;
  981. if (rtlpriv->mac80211.opmode == NL80211_IFTYPE_STATION &&
  982. rtlpriv->mac80211.link_state >= MAC80211_LINKED) {
  983. rtlpriv->dm.one_entry_only = true;
  984. return;
  985. }
  986. if (rtlpriv->mac80211.opmode == NL80211_IFTYPE_AP ||
  987. rtlpriv->mac80211.opmode == NL80211_IFTYPE_ADHOC ||
  988. rtlpriv->mac80211.opmode == NL80211_IFTYPE_MESH_POINT) {
  989. spin_lock_bh(&rtlpriv->locks.entry_list_lock);
  990. list_for_each_entry(drv_priv, &rtlpriv->entry_list, list) {
  991. cnt++;
  992. }
  993. spin_unlock_bh(&rtlpriv->locks.entry_list_lock);
  994. if (cnt == 1)
  995. rtlpriv->dm.one_entry_only = true;
  996. }
  997. }
  998. void rtl92ee_dm_dynamic_arfb_select(struct ieee80211_hw *hw,
  999. u8 rate, bool collision_state)
  1000. {
  1001. struct rtl_priv *rtlpriv = rtl_priv(hw);
  1002. if (rate >= DESC92C_RATEMCS8 && rate <= DESC92C_RATEMCS12) {
  1003. if (collision_state == 1) {
  1004. if (rate == DESC92C_RATEMCS12) {
  1005. rtl_write_dword(rtlpriv, REG_DARFRC, 0x0);
  1006. rtl_write_dword(rtlpriv, REG_DARFRC + 4,
  1007. 0x07060501);
  1008. } else if (rate == DESC92C_RATEMCS11) {
  1009. rtl_write_dword(rtlpriv, REG_DARFRC, 0x0);
  1010. rtl_write_dword(rtlpriv, REG_DARFRC + 4,
  1011. 0x07070605);
  1012. } else if (rate == DESC92C_RATEMCS10) {
  1013. rtl_write_dword(rtlpriv, REG_DARFRC, 0x0);
  1014. rtl_write_dword(rtlpriv, REG_DARFRC + 4,
  1015. 0x08080706);
  1016. } else if (rate == DESC92C_RATEMCS9) {
  1017. rtl_write_dword(rtlpriv, REG_DARFRC, 0x0);
  1018. rtl_write_dword(rtlpriv, REG_DARFRC + 4,
  1019. 0x08080707);
  1020. } else {
  1021. rtl_write_dword(rtlpriv, REG_DARFRC, 0x0);
  1022. rtl_write_dword(rtlpriv, REG_DARFRC + 4,
  1023. 0x09090808);
  1024. }
  1025. } else { /* collision_state == 0 */
  1026. if (rate == DESC92C_RATEMCS12) {
  1027. rtl_write_dword(rtlpriv, REG_DARFRC,
  1028. 0x05010000);
  1029. rtl_write_dword(rtlpriv, REG_DARFRC + 4,
  1030. 0x09080706);
  1031. } else if (rate == DESC92C_RATEMCS11) {
  1032. rtl_write_dword(rtlpriv, REG_DARFRC,
  1033. 0x06050000);
  1034. rtl_write_dword(rtlpriv, REG_DARFRC + 4,
  1035. 0x09080807);
  1036. } else if (rate == DESC92C_RATEMCS10) {
  1037. rtl_write_dword(rtlpriv, REG_DARFRC,
  1038. 0x07060000);
  1039. rtl_write_dword(rtlpriv, REG_DARFRC + 4,
  1040. 0x0a090908);
  1041. } else if (rate == DESC92C_RATEMCS9) {
  1042. rtl_write_dword(rtlpriv, REG_DARFRC,
  1043. 0x07070000);
  1044. rtl_write_dword(rtlpriv, REG_DARFRC + 4,
  1045. 0x0a090808);
  1046. } else {
  1047. rtl_write_dword(rtlpriv, REG_DARFRC,
  1048. 0x08080000);
  1049. rtl_write_dword(rtlpriv, REG_DARFRC + 4,
  1050. 0x0b0a0909);
  1051. }
  1052. }
  1053. } else { /* MCS13~MCS15, 1SS, G-mode */
  1054. if (collision_state == 1) {
  1055. if (rate == DESC92C_RATEMCS15) {
  1056. rtl_write_dword(rtlpriv, REG_DARFRC,
  1057. 0x00000000);
  1058. rtl_write_dword(rtlpriv, REG_DARFRC + 4,
  1059. 0x05040302);
  1060. } else if (rate == DESC92C_RATEMCS14) {
  1061. rtl_write_dword(rtlpriv, REG_DARFRC,
  1062. 0x00000000);
  1063. rtl_write_dword(rtlpriv, REG_DARFRC + 4,
  1064. 0x06050302);
  1065. } else if (rate == DESC92C_RATEMCS13) {
  1066. rtl_write_dword(rtlpriv, REG_DARFRC,
  1067. 0x00000000);
  1068. rtl_write_dword(rtlpriv, REG_DARFRC + 4,
  1069. 0x07060502);
  1070. } else {
  1071. rtl_write_dword(rtlpriv, REG_DARFRC,
  1072. 0x00000000);
  1073. rtl_write_dword(rtlpriv, REG_DARFRC + 4,
  1074. 0x06050402);
  1075. }
  1076. } else{ /* collision_state == 0 */
  1077. if (rate == DESC92C_RATEMCS15) {
  1078. rtl_write_dword(rtlpriv, REG_DARFRC,
  1079. 0x03020000);
  1080. rtl_write_dword(rtlpriv, REG_DARFRC + 4,
  1081. 0x07060504);
  1082. } else if (rate == DESC92C_RATEMCS14) {
  1083. rtl_write_dword(rtlpriv, REG_DARFRC,
  1084. 0x03020000);
  1085. rtl_write_dword(rtlpriv, REG_DARFRC + 4,
  1086. 0x08070605);
  1087. } else if (rate == DESC92C_RATEMCS13) {
  1088. rtl_write_dword(rtlpriv, REG_DARFRC,
  1089. 0x05020000);
  1090. rtl_write_dword(rtlpriv, REG_DARFRC + 4,
  1091. 0x09080706);
  1092. } else {
  1093. rtl_write_dword(rtlpriv, REG_DARFRC,
  1094. 0x04020000);
  1095. rtl_write_dword(rtlpriv, REG_DARFRC + 4,
  1096. 0x08070605);
  1097. }
  1098. }
  1099. }
  1100. }
  1101. void rtl92ee_dm_watchdog(struct ieee80211_hw *hw)
  1102. {
  1103. struct rtl_priv *rtlpriv = rtl_priv(hw);
  1104. struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw));
  1105. bool fw_current_inpsmode = false;
  1106. bool fw_ps_awake = true;
  1107. rtlpriv->cfg->ops->get_hw_reg(hw, HW_VAR_FW_PSMODE_STATUS,
  1108. (u8 *)(&fw_current_inpsmode));
  1109. rtlpriv->cfg->ops->get_hw_reg(hw, HW_VAR_FWLPS_RF_ON,
  1110. (u8 *)(&fw_ps_awake));
  1111. if (ppsc->p2p_ps_info.p2p_ps_mode)
  1112. fw_ps_awake = false;
  1113. if ((ppsc->rfpwr_state == ERFON) &&
  1114. ((!fw_current_inpsmode) && fw_ps_awake) &&
  1115. (!ppsc->rfchange_inprogress)) {
  1116. rtl92ee_dm_common_info_self_update(hw);
  1117. rtl92ee_dm_false_alarm_counter_statistics(hw);
  1118. rtl92ee_dm_check_rssi_monitor(hw);
  1119. rtl92ee_dm_dig(hw);
  1120. rtl92ee_dm_adaptivity(hw);
  1121. rtl92ee_dm_cck_packet_detection_thresh(hw);
  1122. rtl92ee_dm_refresh_rate_adaptive_mask(hw);
  1123. rtl92ee_dm_check_edca_turbo(hw);
  1124. rtl92ee_dm_dynamic_atc_switch(hw);
  1125. rtl92ee_dm_dynamic_primary_cca_ckeck(hw);
  1126. }
  1127. }