phydm_soml.c 38 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963
  1. /******************************************************************************
  2. *
  3. * Copyright(c) 2007 - 2017 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. /*************************************************************
  26. * include files
  27. ************************************************************/
  28. #include "mp_precomp.h"
  29. #include "phydm_precomp.h"
  30. #ifdef CONFIG_ADAPTIVE_SOML
  31. void phydm_dynamicsoftmletting(void *dm_void)
  32. {
  33. struct dm_struct *dm = (struct dm_struct *)dm_void;
  34. u32 ret_val;
  35. #if (RTL8822B_SUPPORT == 1)
  36. if (!*dm->mp_mode) {
  37. if (dm->support_ic_type & ODM_RTL8822B) {
  38. if (!dm->is_linked | dm->iot_table.is_linked_cmw500)
  39. return;
  40. if (dm->bsomlenabled) {
  41. PHYDM_DBG(dm, ODM_COMP_API,
  42. "PHYDM_DynamicSoftMLSetting(): SoML has been enable, skip dynamic SoML switch\n");
  43. return;
  44. }
  45. ret_val = odm_get_bb_reg(dm, R_0xf8c, MASKBYTE0);
  46. PHYDM_DBG(dm, ODM_COMP_API,
  47. "PHYDM_DynamicSoftMLSetting(): Read 0xF8C = 0x%08X\n",
  48. ret_val);
  49. if (ret_val < 0x16) {
  50. PHYDM_DBG(dm, ODM_COMP_API,
  51. "PHYDM_DynamicSoftMLSetting(): 0xF8C(== 0x%08X) < 0x16, enable SoML\n",
  52. ret_val);
  53. phydm_somlrxhp_setting(dm, true);
  54. #if 0
  55. /*odm_set_bb_reg(dm, R_0x19a8, MASKDWORD, 0xc10a0000);*/
  56. #endif
  57. dm->bsomlenabled = true;
  58. }
  59. }
  60. }
  61. #endif
  62. }
  63. void phydm_soml_on_off(
  64. void *dm_void,
  65. u8 swch)
  66. {
  67. struct dm_struct *dm = (struct dm_struct *)dm_void;
  68. struct adaptive_soml *dm_soml_table = &dm->dm_soml_table;
  69. if (swch == SOML_ON) {
  70. PHYDM_DBG(dm, DBG_ADPTV_SOML, "(( Turn on )) SOML\n");
  71. if (dm->support_ic_type & (ODM_RTL8197F | ODM_RTL8192F))
  72. odm_set_bb_reg(dm, R_0x998, BIT(6), swch);
  73. #if (RTL8822B_SUPPORT == 1)
  74. else if (dm->support_ic_type == ODM_RTL8822B)
  75. phydm_somlrxhp_setting(dm, true);
  76. #endif
  77. } else if (swch == SOML_OFF) {
  78. PHYDM_DBG(dm, DBG_ADPTV_SOML, "(( Turn off )) SOML\n");
  79. if (dm->support_ic_type & (ODM_RTL8197F | ODM_RTL8192F))
  80. odm_set_bb_reg(dm, R_0x998, BIT(6), swch);
  81. #if (RTL8822B_SUPPORT == 1)
  82. else if (dm->support_ic_type == ODM_RTL8822B)
  83. phydm_somlrxhp_setting(dm, false);
  84. #endif
  85. }
  86. dm_soml_table->soml_on_off = swch;
  87. }
  88. #if (DM_ODM_SUPPORT_TYPE == ODM_WIN)
  89. void phydm_adaptive_soml_callback(
  90. struct phydm_timer_list *timer)
  91. {
  92. void *adapter = (void *)timer->Adapter;
  93. HAL_DATA_TYPE *hal_data = GET_HAL_DATA(((PADAPTER)adapter));
  94. struct dm_struct *dm = &hal_data->DM_OutSrc;
  95. struct adaptive_soml *dm_soml_table = &dm->dm_soml_table;
  96. #if DEV_BUS_TYPE == RT_PCI_INTERFACE
  97. #if USE_WORKITEM
  98. odm_schedule_work_item(&dm_soml_table->phydm_adaptive_soml_workitem);
  99. #else
  100. {
  101. #if 0
  102. /*@dbg_print("%s\n",__func__);*/
  103. #endif
  104. phydm_adsl(dm);
  105. }
  106. #endif
  107. #else
  108. odm_schedule_work_item(&dm_soml_table->phydm_adaptive_soml_workitem);
  109. #endif
  110. }
  111. void phydm_adaptive_soml_workitem_callback(
  112. void *context)
  113. {
  114. #ifdef CONFIG_ADAPTIVE_SOML
  115. void *adapter = (void *)context;
  116. HAL_DATA_TYPE *hal_data = GET_HAL_DATA(((PADAPTER)adapter));
  117. struct dm_struct *dm = &hal_data->DM_OutSrc;
  118. #if 0
  119. /*@dbg_print("%s\n",__func__);*/
  120. #endif
  121. phydm_adsl(dm);
  122. #endif
  123. }
  124. #elif (DM_ODM_SUPPORT_TYPE == ODM_CE)
  125. void phydm_adaptive_soml_callback(
  126. void *dm_void)
  127. {
  128. struct dm_struct *dm = (struct dm_struct *)dm_void;
  129. void *padapter = dm->adapter;
  130. if (*dm->is_net_closed == true)
  131. return;
  132. if (dm->support_interface == ODM_ITRF_PCIE)
  133. phydm_adsl(dm);
  134. else {
  135. /* @Can't do I/O in timer callback*/
  136. phydm_run_in_thread_cmd(dm,
  137. phydm_adaptive_soml_workitem_callback,
  138. dm);
  139. }
  140. }
  141. void phydm_adaptive_soml_workitem_callback(
  142. void *context)
  143. {
  144. struct dm_struct *dm = (void *)context;
  145. #if 0
  146. /*@dbg_print("%s\n",__func__);*/
  147. #endif
  148. phydm_adsl(dm);
  149. }
  150. #else
  151. void phydm_adaptive_soml_callback(
  152. void *dm_void)
  153. {
  154. struct dm_struct *dm = (struct dm_struct *)dm_void;
  155. PHYDM_DBG(dm, DBG_ADPTV_SOML, "******SOML_Callback******\n");
  156. phydm_adsl(dm);
  157. }
  158. #endif
  159. void phydm_rx_rate_for_soml(
  160. void *dm_void,
  161. void *pkt_info_void)
  162. {
  163. struct dm_struct *dm = (struct dm_struct *)dm_void;
  164. struct adaptive_soml *dm_soml_table = &dm->dm_soml_table;
  165. struct phydm_perpkt_info_struct *pktinfo = (struct phydm_perpkt_info_struct *)pkt_info_void;
  166. u8 data_rate = (pktinfo->data_rate & 0x7f);
  167. if (pktinfo->data_rate >= ODM_RATEMCS0 && pktinfo->data_rate <= ODM_RATEMCS31)
  168. dm_soml_table->num_ht_cnt[data_rate - ODM_RATEMCS0]++;
  169. else if ((pktinfo->data_rate >= ODM_RATEVHTSS1MCS0) && (pktinfo->data_rate <= ODM_RATEVHTSS4MCS9))
  170. dm_soml_table->num_vht_cnt[data_rate - ODM_RATEVHTSS1MCS0]++;
  171. }
  172. void phydm_rx_qam_for_soml(
  173. void *dm_void,
  174. void *pkt_info_void)
  175. {
  176. struct dm_struct *dm = (struct dm_struct *)dm_void;
  177. struct adaptive_soml *dm_soml_table = &dm->dm_soml_table;
  178. struct phydm_perpkt_info_struct *pktinfo = (struct phydm_perpkt_info_struct *)pkt_info_void;
  179. u8 date_rate = (pktinfo->data_rate & 0x7f);
  180. if (dm_soml_table->soml_state_cnt < (dm_soml_table->soml_train_num << 1)) {
  181. if (dm_soml_table->soml_on_off == SOML_ON)
  182. return;
  183. else if (dm_soml_table->soml_on_off == SOML_OFF) {
  184. if (date_rate >= ODM_RATEMCS8 && date_rate <= ODM_RATEMCS10)
  185. dm_soml_table->num_ht_qam[BPSK_QPSK]++;
  186. else if ((date_rate >= ODM_RATEMCS11) && (date_rate <= ODM_RATEMCS12))
  187. dm_soml_table->num_ht_qam[QAM16]++;
  188. else if ((date_rate >= ODM_RATEMCS13) && (date_rate <= ODM_RATEMCS15))
  189. dm_soml_table->num_ht_qam[QAM64]++;
  190. else if ((date_rate >= ODM_RATEVHTSS2MCS0) && (date_rate <= ODM_RATEVHTSS2MCS2))
  191. dm_soml_table->num_vht_qam[BPSK_QPSK]++;
  192. else if ((date_rate >= ODM_RATEVHTSS2MCS3) && (date_rate <= ODM_RATEVHTSS2MCS4))
  193. dm_soml_table->num_vht_qam[QAM16]++;
  194. else if ((date_rate >= ODM_RATEVHTSS2MCS5) && (date_rate <= ODM_RATEVHTSS2MCS5))
  195. dm_soml_table->num_vht_qam[QAM64]++;
  196. else if ((date_rate >= ODM_RATEVHTSS2MCS8) && (date_rate <= ODM_RATEVHTSS2MCS9))
  197. dm_soml_table->num_vht_qam[QAM256]++;
  198. }
  199. }
  200. }
  201. void phydm_soml_reset_rx_rate(
  202. void *dm_void)
  203. {
  204. struct dm_struct *dm = (struct dm_struct *)dm_void;
  205. struct adaptive_soml *dm_soml_table = &dm->dm_soml_table;
  206. u8 order;
  207. for (order = 0; order < HT_RATE_IDX; order++)
  208. dm_soml_table->num_ht_cnt[order] = 0;
  209. for (order = 0; order < VHT_RATE_IDX; order++)
  210. dm_soml_table->num_vht_cnt[order] = 0;
  211. }
  212. void phydm_soml_reset_qam(
  213. void *dm_void)
  214. {
  215. struct dm_struct *dm = (struct dm_struct *)dm_void;
  216. struct adaptive_soml *dm_soml_table = &dm->dm_soml_table;
  217. u8 order;
  218. for (order = 0; order < HT_ORDER_TYPE; order++)
  219. dm_soml_table->num_ht_qam[order] = 0;
  220. for (order = 0; order < VHT_ORDER_TYPE; order++)
  221. dm_soml_table->num_vht_qam[order] = 0;
  222. }
  223. void phydm_soml_cfo_process(
  224. void *dm_void,
  225. s32 *diff_a,
  226. s32 *diff_b)
  227. {
  228. struct dm_struct *dm = (struct dm_struct *)dm_void;
  229. u32 value32, value32_1, value32_2, value32_3;
  230. s32 cfo_acq_a, cfo_acq_b, cfo_end_a, cfo_end_b;
  231. value32 = odm_get_bb_reg(dm, R_0xd10, MASKDWORD);
  232. value32_1 = odm_get_bb_reg(dm, R_0xd14, MASKDWORD);
  233. value32_2 = odm_get_bb_reg(dm, R_0xd50, MASKDWORD);
  234. value32_3 = odm_get_bb_reg(dm, R_0xd54, MASKDWORD);
  235. cfo_acq_a = (s32)((value32 & 0x1fff0000) >> 16);
  236. cfo_end_a = (s32)((value32_1 & 0x1fff0000) >> 16);
  237. cfo_acq_b = (s32)((value32_2 & 0x1fff0000) >> 16);
  238. cfo_end_b = (s32)((value32_3 & 0x1fff0000) >> 16);
  239. *diff_a = ((cfo_acq_a >= cfo_end_a) ? (cfo_acq_a - cfo_end_a) : (cfo_end_a - cfo_acq_a));
  240. *diff_b = ((cfo_acq_b >= cfo_end_b) ? (cfo_acq_b - cfo_end_b) : (cfo_end_b - cfo_acq_b));
  241. *diff_a = ((*diff_a * 312) + (*diff_a >> 1)) >> 12; /* @312.5/2^12 */
  242. *diff_b = ((*diff_b * 312) + (*diff_b >> 1)) >> 12; /* @312.5/2^12 */
  243. }
  244. void phydm_soml_debug(void *dm_void, char input[][16], u32 *_used,
  245. char *output, u32 *_out_len)
  246. {
  247. struct dm_struct *dm = (struct dm_struct *)dm_void;
  248. struct adaptive_soml *dm_soml_table = &dm->dm_soml_table;
  249. u32 used = *_used;
  250. u32 out_len = *_out_len;
  251. u32 dm_value[10] = {0};
  252. u8 i = 0, input_idx = 0;
  253. for (i = 0; i < 5; i++) {
  254. if (input[i + 1]) {
  255. PHYDM_SSCANF(input[i + 1], DCMD_DECIMAL, &dm_value[i]);
  256. input_idx++;
  257. }
  258. }
  259. if (input_idx == 0)
  260. return;
  261. if (dm_value[0] == 1) { /*Turn on/off SOML*/
  262. dm_soml_table->soml_select = (u8)dm_value[1];
  263. } else if (dm_value[0] == 2) { /*training number for SOML*/
  264. dm_soml_table->soml_train_num = (u8)dm_value[1];
  265. PDM_SNPF(out_len, used, output + used, out_len - used,
  266. "soml_train_num = ((%d))\n",
  267. dm_soml_table->soml_train_num);
  268. } else if (dm_value[0] == 3) { /*training interval for SOML*/
  269. dm_soml_table->soml_intvl = (u8)dm_value[1];
  270. PDM_SNPF(out_len, used, output + used, out_len - used,
  271. "soml_intvl = ((%d))\n", dm_soml_table->soml_intvl);
  272. } else if (dm_value[0] == 4) { /*@function period for SOML*/
  273. dm_soml_table->soml_period = (u8)dm_value[1];
  274. PDM_SNPF(out_len, used, output + used, out_len - used,
  275. "soml_period = ((%d))\n", dm_soml_table->soml_period);
  276. } else if (dm_value[0] == 5) { /*@delay_time for SOML*/
  277. dm_soml_table->soml_delay_time = (u8)dm_value[1];
  278. PDM_SNPF(out_len, used, output + used, out_len - used,
  279. "soml_delay_time = ((%d))\n",
  280. dm_soml_table->soml_delay_time);
  281. } else if (dm_value[0] == 6) { /* @for SOML Rx QAM distribution th*/
  282. if (dm_value[1] == 256) {
  283. dm_soml_table->qam256_dist_th = (u8)dm_value[2];
  284. PDM_SNPF(out_len, used, output + used, out_len - used,
  285. "qam256_dist_th = ((%d))\n",
  286. dm_soml_table->qam256_dist_th);
  287. } else if (dm_value[1] == 64) {
  288. dm_soml_table->qam64_dist_th = (u8)dm_value[2];
  289. PDM_SNPF(out_len, used, output + used, out_len - used,
  290. "qam64_dist_th = ((%d))\n",
  291. dm_soml_table->qam64_dist_th);
  292. } else if (dm_value[1] == 16) {
  293. dm_soml_table->qam16_dist_th = (u8)dm_value[2];
  294. PDM_SNPF(out_len, used, output + used, out_len - used,
  295. "qam16_dist_th = ((%d))\n",
  296. dm_soml_table->qam16_dist_th);
  297. } else if (dm_value[1] == 4) {
  298. dm_soml_table->bpsk_qpsk_dist_th = (u8)dm_value[2];
  299. PDM_SNPF(out_len, used, output + used, out_len - used,
  300. "bpsk_qpsk_dist_th = ((%d))\n",
  301. dm_soml_table->bpsk_qpsk_dist_th);
  302. }
  303. } else if (dm_value[0] == 7) { /* @for SOML cfo th*/
  304. if (dm_value[1] == 256) {
  305. dm_soml_table->cfo_qam256_th = (u8)dm_value[2];
  306. PDM_SNPF(out_len, used, output + used, out_len - used,
  307. "cfo_qam256_th = ((%d KHz))\n",
  308. dm_soml_table->cfo_qam256_th);
  309. } else if (dm_value[1] == 64) {
  310. dm_soml_table->cfo_qam64_th = (u8)dm_value[2];
  311. PDM_SNPF(out_len, used, output + used, out_len - used,
  312. "cfo_qam64_th = ((%d KHz))\n",
  313. dm_soml_table->cfo_qam64_th);
  314. } else if (dm_value[1] == 16) {
  315. dm_soml_table->cfo_qam16_th = (u8)dm_value[2];
  316. PDM_SNPF(out_len, used, output + used, out_len - used,
  317. "cfo_qam16_th = ((%d KHz))\n",
  318. dm_soml_table->cfo_qam16_th);
  319. } else if (dm_value[1] == 4) {
  320. dm_soml_table->cfo_qpsk_th = (u8)dm_value[2];
  321. PDM_SNPF(out_len, used, output + used, out_len - used,
  322. "cfo_qpsk_th = ((%d KHz))\n",
  323. dm_soml_table->cfo_qpsk_th);
  324. }
  325. } else if (dm_value[0] == 100) { /*show parameters*/
  326. PDM_SNPF(out_len, used, output + used, out_len - used,
  327. "soml_select = ((%d))\n", dm_soml_table->soml_select);
  328. PDM_SNPF(out_len, used, output + used, out_len - used,
  329. "soml_train_num = ((%d))\n",
  330. dm_soml_table->soml_train_num);
  331. PDM_SNPF(out_len, used, output + used, out_len - used,
  332. "soml_intvl = ((%d))\n", dm_soml_table->soml_intvl);
  333. PDM_SNPF(out_len, used, output + used, out_len - used,
  334. "soml_period = ((%d))\n", dm_soml_table->soml_period);
  335. PDM_SNPF(out_len, used, output + used, out_len - used,
  336. "soml_delay_time = ((%d))\n\n",
  337. dm_soml_table->soml_delay_time);
  338. PDM_SNPF(out_len, used, output + used, out_len - used,
  339. "qam256_dist_th = ((%d)), qam64_dist_th = ((%d)), ",
  340. dm_soml_table->qam256_dist_th,
  341. dm_soml_table->qam64_dist_th);
  342. PDM_SNPF(out_len, used, output + used, out_len - used,
  343. "qam16_dist_th = ((%d)), bpsk_qpsk_dist_th = ((%d))\n",
  344. dm_soml_table->qam16_dist_th,
  345. dm_soml_table->bpsk_qpsk_dist_th);
  346. PDM_SNPF(out_len, used, output + used, out_len - used,
  347. "cfo_qam256_th = ((%d KHz)), cfo_qam64_th = ((%d KHz)), ",
  348. dm_soml_table->cfo_qam256_th,
  349. dm_soml_table->cfo_qam64_th);
  350. PDM_SNPF(out_len, used, output + used, out_len - used,
  351. "cfo_qam16_th = ((%d KHz)), cfo_qpsk_th = ((%d KHz))\n",
  352. dm_soml_table->cfo_qam16_th,
  353. dm_soml_table->cfo_qpsk_th);
  354. }
  355. *_used = used;
  356. *_out_len = out_len;
  357. }
  358. void phydm_soml_statistics(
  359. void *dm_void,
  360. u8 on_off_state
  361. )
  362. {
  363. struct dm_struct *dm = (struct dm_struct *)dm_void;
  364. struct adaptive_soml *dm_soml_table = &dm->dm_soml_table;
  365. u8 i, j;
  366. u32 num_bytes_diff, num_rate_diff;
  367. if (on_off_state == SOML_ON) {
  368. if (*dm->channel <= 14) {
  369. for (i = ODM_RATEMCS0; i <= ODM_RATEMCS15; i++) {
  370. num_rate_diff = dm_soml_table->num_ht_cnt[i - ODM_RATEMCS0] - dm_soml_table->pre_num_ht_cnt[i - ODM_RATEMCS0];
  371. dm_soml_table->num_ht_cnt_on[i - ODM_RATEMCS0] += num_rate_diff;
  372. dm_soml_table->pre_num_ht_cnt[i - ODM_RATEMCS0] = dm_soml_table->num_ht_cnt[i - ODM_RATEMCS0];
  373. num_bytes_diff = dm_soml_table->num_ht_bytes[i - ODM_RATEMCS0] - dm_soml_table->pre_num_ht_bytes[i - ODM_RATEMCS0];
  374. dm_soml_table->num_ht_bytes_on[i - ODM_RATEMCS0] += num_bytes_diff;
  375. dm_soml_table->pre_num_ht_bytes[i - ODM_RATEMCS0] = dm_soml_table->num_ht_bytes[i - ODM_RATEMCS0];
  376. }
  377. }
  378. if (dm->support_ic_type == ODM_RTL8822B) {
  379. for (j = ODM_RATEVHTSS1MCS0; j <= ODM_RATEVHTSS2MCS9; j++) {
  380. num_rate_diff = dm_soml_table->num_vht_cnt[j - ODM_RATEVHTSS1MCS0] - dm_soml_table->pre_num_vht_cnt[j - ODM_RATEVHTSS1MCS0];
  381. dm_soml_table->num_vht_cnt_on[j - ODM_RATEVHTSS1MCS0] += num_rate_diff;
  382. dm_soml_table->pre_num_vht_cnt[j - ODM_RATEVHTSS1MCS0] = dm_soml_table->num_vht_cnt[j - ODM_RATEVHTSS1MCS0];
  383. num_bytes_diff = dm_soml_table->num_vht_bytes[j - ODM_RATEVHTSS1MCS0] - dm_soml_table->pre_num_vht_bytes[j - ODM_RATEVHTSS1MCS0];
  384. dm_soml_table->num_vht_bytes_on[j - ODM_RATEVHTSS1MCS0] += num_bytes_diff;
  385. dm_soml_table->pre_num_vht_bytes[j - ODM_RATEVHTSS1MCS0] = dm_soml_table->num_vht_bytes[j - ODM_RATEVHTSS1MCS0];
  386. }
  387. }
  388. } else if (on_off_state == SOML_OFF) {
  389. if (*dm->channel <= 14) {
  390. for (i = ODM_RATEMCS0; i <= ODM_RATEMCS15; i++) {
  391. num_rate_diff = dm_soml_table->num_ht_cnt[i - ODM_RATEMCS0] - dm_soml_table->pre_num_ht_cnt[i - ODM_RATEMCS0];
  392. dm_soml_table->num_ht_cnt_off[i - ODM_RATEMCS0] += num_rate_diff;
  393. dm_soml_table->pre_num_ht_cnt[i - ODM_RATEMCS0] = dm_soml_table->num_ht_cnt[i - ODM_RATEMCS0];
  394. num_bytes_diff = dm_soml_table->num_ht_bytes[i - ODM_RATEMCS0] - dm_soml_table->pre_num_ht_bytes[i - ODM_RATEMCS0];
  395. dm_soml_table->num_ht_bytes_off[i - ODM_RATEMCS0] += num_bytes_diff;
  396. dm_soml_table->pre_num_ht_bytes[i - ODM_RATEMCS0] = dm_soml_table->num_ht_bytes[i - ODM_RATEMCS0];
  397. }
  398. }
  399. if (dm->support_ic_type == ODM_RTL8822B) {
  400. for (j = ODM_RATEVHTSS1MCS0; j <= ODM_RATEVHTSS2MCS9; j++) {
  401. num_rate_diff = dm_soml_table->num_vht_cnt[j - ODM_RATEVHTSS1MCS0] - dm_soml_table->pre_num_vht_cnt[j - ODM_RATEVHTSS1MCS0];
  402. dm_soml_table->num_vht_cnt_off[j - ODM_RATEVHTSS1MCS0] += num_rate_diff;
  403. dm_soml_table->pre_num_vht_cnt[j - ODM_RATEVHTSS1MCS0] = dm_soml_table->num_vht_cnt[j - ODM_RATEVHTSS1MCS0];
  404. num_bytes_diff = dm_soml_table->num_vht_bytes[j - ODM_RATEVHTSS1MCS0] - dm_soml_table->pre_num_vht_bytes[j - ODM_RATEVHTSS1MCS0];
  405. dm_soml_table->num_vht_bytes_off[j - ODM_RATEVHTSS1MCS0] += num_bytes_diff;
  406. dm_soml_table->pre_num_vht_bytes[j - ODM_RATEVHTSS1MCS0] = dm_soml_table->num_vht_bytes[j - ODM_RATEVHTSS1MCS0];
  407. }
  408. }
  409. }
  410. }
  411. void phydm_adsl(
  412. void *dm_void)
  413. {
  414. struct dm_struct *dm = (struct dm_struct *)dm_void;
  415. struct adaptive_soml *dm_soml_table = &dm->dm_soml_table;
  416. u8 i;
  417. u8 next_on_off;
  418. u8 rate_num = 1, rate_ss_shift = 0;
  419. u32 num_total_qam = 0;
  420. u32 num_ht_total_cnt_on = 0, num_ht_total_cnt_off = 0, total_ht_rate_on = 0, total_ht_rate_off = 0;
  421. u32 num_vht_total_cnt_on = 0, num_vht_total_cnt_off = 0, total_vht_rate_on = 0, total_vht_rate_off = 0;
  422. u32 rate_per_pkt_on = 0, rate_per_pkt_off = 0;
  423. u32 ht_reset[HT_RATE_IDX] = {0}, vht_reset[VHT_RATE_IDX] = {0};
  424. u8 size = sizeof(ht_reset[0]);
  425. u16 vht_phy_rate_table[] = {
  426. /*@20M*/
  427. 6, 13, 19, 26, 39, 52, 58, 65, 78, 90, /*@1SS MCS0~9*/
  428. 13, 26, 39, 52, 78, 104, 117, 130, 156, 180 /*@2SSMCS0~9*/
  429. };
  430. if (dm->support_ic_type & ODM_IC_4SS)
  431. rate_num = 4;
  432. else if (dm->support_ic_type & ODM_IC_3SS)
  433. rate_num = 3;
  434. else if (dm->support_ic_type & ODM_IC_2SS)
  435. rate_num = 2;
  436. if (dm->support_ic_type & ODM_ADAPTIVE_SOML_SUPPORT_IC) {
  437. PHYDM_DBG(dm, DBG_ADPTV_SOML, "soml_state_cnt =((%d))\n",
  438. dm_soml_table->soml_state_cnt);
  439. /*Traning state: 0(alt) 1(ori) 2(alt) 3(ori)============================================================*/
  440. if (dm_soml_table->soml_state_cnt < (dm_soml_table->soml_train_num << 1)) {
  441. if (dm_soml_table->soml_state_cnt == 0) {
  442. phydm_soml_reset_rx_rate(dm);
  443. odm_move_memory(dm, dm_soml_table->num_ht_bytes, ht_reset, HT_RATE_IDX * size);
  444. odm_move_memory(dm, dm_soml_table->num_ht_bytes_on, ht_reset, HT_RATE_IDX * size);
  445. odm_move_memory(dm, dm_soml_table->num_ht_bytes_off, ht_reset, HT_RATE_IDX * size);
  446. odm_move_memory(dm, dm_soml_table->num_vht_bytes, vht_reset, VHT_RATE_IDX * size);
  447. odm_move_memory(dm, dm_soml_table->num_vht_bytes_on, vht_reset, VHT_RATE_IDX * size);
  448. odm_move_memory(dm, dm_soml_table->num_vht_bytes_off, vht_reset, VHT_RATE_IDX * size);
  449. if (dm->support_ic_type == ODM_RTL8822B) {
  450. dm_soml_table->cfo_counter++;
  451. phydm_soml_cfo_process(dm,
  452. &dm_soml_table->cfo_diff_a,
  453. &dm_soml_table->cfo_diff_b);
  454. PHYDM_DBG(dm, DBG_ADPTV_SOML, "[ (%d) cfo_diff_a = %d KHz; cfo_diff_b = %d KHz ]\n", dm_soml_table->cfo_counter, dm_soml_table->cfo_diff_a, dm_soml_table->cfo_diff_b);
  455. dm_soml_table->cfo_diff_sum_a += dm_soml_table->cfo_diff_a;
  456. dm_soml_table->cfo_diff_sum_b += dm_soml_table->cfo_diff_b;
  457. }
  458. dm_soml_table->is_soml_method_enable = 1;
  459. dm_soml_table->soml_state_cnt++;
  460. next_on_off = (dm_soml_table->soml_on_off == SOML_ON) ? SOML_ON : SOML_OFF;
  461. phydm_soml_on_off(dm, next_on_off);
  462. odm_set_timer(dm, &dm_soml_table->phydm_adaptive_soml_timer, dm_soml_table->soml_delay_time); /*@ms*/
  463. } else if ((dm_soml_table->soml_state_cnt % 2) != 0) {
  464. dm_soml_table->soml_state_cnt++;
  465. odm_move_memory(dm, dm_soml_table->pre_num_ht_cnt, dm_soml_table->num_ht_cnt, HT_RATE_IDX * size);
  466. odm_move_memory(dm, dm_soml_table->pre_num_vht_cnt, dm_soml_table->num_vht_cnt, VHT_RATE_IDX * size);
  467. odm_move_memory(dm, dm_soml_table->pre_num_ht_bytes, dm_soml_table->num_ht_bytes, HT_RATE_IDX * size);
  468. odm_move_memory(dm, dm_soml_table->pre_num_vht_bytes, dm_soml_table->num_vht_bytes, VHT_RATE_IDX * size);
  469. if (dm->support_ic_type == ODM_RTL8822B) {
  470. dm_soml_table->cfo_counter++;
  471. phydm_soml_cfo_process(dm,
  472. &dm_soml_table->cfo_diff_a,
  473. &dm_soml_table->cfo_diff_b);
  474. PHYDM_DBG(dm, DBG_ADPTV_SOML, "[ (%d) cfo_diff_a = %d KHz; cfo_diff_b = %d KHz ]\n", dm_soml_table->cfo_counter, dm_soml_table->cfo_diff_a, dm_soml_table->cfo_diff_b);
  475. dm_soml_table->cfo_diff_sum_a += dm_soml_table->cfo_diff_a;
  476. dm_soml_table->cfo_diff_sum_b += dm_soml_table->cfo_diff_b;
  477. }
  478. odm_set_timer(dm, &dm_soml_table->phydm_adaptive_soml_timer, dm_soml_table->soml_intvl); /*@ms*/
  479. } else if ((dm_soml_table->soml_state_cnt % 2) == 0) {
  480. if (dm->support_ic_type == ODM_RTL8822B) {
  481. dm_soml_table->cfo_counter++;
  482. phydm_soml_cfo_process(dm,
  483. &dm_soml_table->cfo_diff_a,
  484. &dm_soml_table->cfo_diff_b);
  485. PHYDM_DBG(dm, DBG_ADPTV_SOML, "[ (%d) cfo_diff_a = %d KHz; cfo_diff_b = %d KHz ]\n", dm_soml_table->cfo_counter, dm_soml_table->cfo_diff_a, dm_soml_table->cfo_diff_b);
  486. dm_soml_table->cfo_diff_sum_a += dm_soml_table->cfo_diff_a;
  487. dm_soml_table->cfo_diff_sum_b += dm_soml_table->cfo_diff_b;
  488. }
  489. dm_soml_table->soml_state_cnt++;
  490. phydm_soml_statistics(dm, dm_soml_table->soml_on_off);
  491. next_on_off = (dm_soml_table->soml_on_off == SOML_ON) ? SOML_OFF : SOML_ON;
  492. phydm_soml_on_off(dm, next_on_off);
  493. odm_set_timer(dm, &dm_soml_table->phydm_adaptive_soml_timer, dm_soml_table->soml_delay_time); /*@ms*/
  494. }
  495. }
  496. /*@Decision state: ==============================================================*/
  497. else {
  498. PHYDM_DBG(dm, DBG_ADPTV_SOML, "[Decisoin state ]\n");
  499. phydm_soml_statistics(dm, dm_soml_table->soml_on_off);
  500. if (*dm->channel <= 14) {
  501. /* @[Search 1st and 2nd rate by counter] */
  502. for (i = 0; i < rate_num; i++) {
  503. rate_ss_shift = (i << 3);
  504. PHYDM_DBG(dm, DBG_ADPTV_SOML, "*num_ht_cnt_on HT MCS[%d :%d ] = {%d, %d, %d, %d, %d, %d, %d, %d}\n",
  505. (rate_ss_shift), (rate_ss_shift + 7),
  506. dm_soml_table->num_ht_cnt_on[rate_ss_shift + 0], dm_soml_table->num_ht_cnt_on[rate_ss_shift + 1],
  507. dm_soml_table->num_ht_cnt_on[rate_ss_shift + 2], dm_soml_table->num_ht_cnt_on[rate_ss_shift + 3],
  508. dm_soml_table->num_ht_cnt_on[rate_ss_shift + 4], dm_soml_table->num_ht_cnt_on[rate_ss_shift + 5],
  509. dm_soml_table->num_ht_cnt_on[rate_ss_shift + 6], dm_soml_table->num_ht_cnt_on[rate_ss_shift + 7]);
  510. }
  511. for (i = 0; i < rate_num; i++) {
  512. rate_ss_shift = (i << 3);
  513. PHYDM_DBG(dm, DBG_ADPTV_SOML, "*num_ht_bytes_off HT MCS[%d :%d ] = {%d, %d, %d, %d, %d, %d, %d, %d}\n",
  514. (rate_ss_shift), (rate_ss_shift + 7),
  515. dm_soml_table->num_ht_cnt_off[rate_ss_shift + 0], dm_soml_table->num_ht_cnt_off[rate_ss_shift + 1],
  516. dm_soml_table->num_ht_cnt_off[rate_ss_shift + 2], dm_soml_table->num_ht_cnt_off[rate_ss_shift + 3],
  517. dm_soml_table->num_ht_cnt_off[rate_ss_shift + 4], dm_soml_table->num_ht_cnt_off[rate_ss_shift + 5],
  518. dm_soml_table->num_ht_cnt_off[rate_ss_shift + 6], dm_soml_table->num_ht_cnt_off[rate_ss_shift + 7]);
  519. }
  520. for (i = ODM_RATEMCS8; i <= ODM_RATEMCS15; i++) {
  521. num_ht_total_cnt_on += dm_soml_table->num_ht_cnt_on[i - ODM_RATEMCS0];
  522. num_ht_total_cnt_off += dm_soml_table->num_ht_cnt_off[i - ODM_RATEMCS0];
  523. total_ht_rate_on += (dm_soml_table->num_ht_cnt_on[i - ODM_RATEMCS0] * phy_rate_table[i]);
  524. total_ht_rate_off += (dm_soml_table->num_ht_cnt_off[i - ODM_RATEMCS0] * phy_rate_table[i]);
  525. }
  526. rate_per_pkt_on = (num_ht_total_cnt_on != 0) ? ((total_ht_rate_on << 3) / num_ht_total_cnt_on) : 0;
  527. rate_per_pkt_off = (num_ht_total_cnt_off != 0) ? ((total_ht_rate_off << 3) / num_ht_total_cnt_off) : 0;
  528. }
  529. #if 0
  530. if (*dm->channel <= 14) {
  531. /* @[Search 1st and 2ed rate by counter] */
  532. for (i = 0; i < rate_num; i++) {
  533. rate_ss_shift = (i << 3);
  534. PHYDM_DBG(dm, DBG_ADPTV_SOML, "*num_ht_bytes_on HT MCS[%d :%d ] = {%d, %d, %d, %d, %d, %d, %d, %d}\n",
  535. (rate_ss_shift), (rate_ss_shift + 7),
  536. dm_soml_table->num_ht_bytes_on[rate_ss_shift + 0], dm_soml_table->num_ht_bytes_on[rate_ss_shift + 1],
  537. dm_soml_table->num_ht_bytes_on[rate_ss_shift + 2], dm_soml_table->num_ht_bytes_on[rate_ss_shift + 3],
  538. dm_soml_table->num_ht_bytes_on[rate_ss_shift + 4], dm_soml_table->num_ht_bytes_on[rate_ss_shift + 5],
  539. dm_soml_table->num_ht_bytes_on[rate_ss_shift + 6], dm_soml_table->num_ht_bytes_on[rate_ss_shift + 7]);
  540. }
  541. for (i = 0; i < rate_num; i++) {
  542. rate_ss_shift = (i << 3);
  543. PHYDM_DBG(dm, DBG_ADPTV_SOML, "*num_ht_bytes_off HT MCS[%d :%d ] = {%d, %d, %d, %d, %d, %d, %d, %d}\n",
  544. (rate_ss_shift), (rate_ss_shift + 7),
  545. dm_soml_table->num_ht_bytes_off[rate_ss_shift + 0], dm_soml_table->num_ht_bytes_off[rate_ss_shift + 1],
  546. dm_soml_table->num_ht_bytes_off[rate_ss_shift + 2], dm_soml_table->num_ht_bytes_off[rate_ss_shift + 3],
  547. dm_soml_table->num_ht_bytes_off[rate_ss_shift + 4], dm_soml_table->num_ht_bytes_off[rate_ss_shift + 5],
  548. dm_soml_table->num_ht_bytes_off[rate_ss_shift + 6], dm_soml_table->num_ht_bytes_off[rate_ss_shift + 7]);
  549. }
  550. for (i = ODM_RATEMCS8; i <= ODM_RATEMCS15; i++) {
  551. byte_total_on += dm_soml_table->num_ht_bytes_on[i - ODM_RATEMCS0];
  552. byte_total_off += dm_soml_table->num_ht_bytes_off[i - ODM_RATEMCS0];
  553. }
  554. }
  555. #endif
  556. if (dm->support_ic_type == ODM_RTL8822B) {
  557. dm_soml_table->cfo_diff_avg_a = (dm_soml_table->cfo_counter != 0) ? (dm_soml_table->cfo_diff_sum_a / dm_soml_table->cfo_counter) : 0;
  558. dm_soml_table->cfo_diff_avg_b = (dm_soml_table->cfo_counter != 0) ? (dm_soml_table->cfo_diff_sum_b / dm_soml_table->cfo_counter) : 0;
  559. PHYDM_DBG(dm, DBG_ADPTV_SOML,
  560. "[ cfo_diff_avg_a = %d KHz; cfo_diff_avg_b = %d KHz]\n",
  561. dm_soml_table->cfo_diff_avg_a,
  562. dm_soml_table->cfo_diff_avg_b);
  563. for (i = 0; i < VHT_ORDER_TYPE; i++)
  564. num_total_qam += dm_soml_table->num_vht_qam[i];
  565. PHYDM_DBG(dm, DBG_ADPTV_SOML,
  566. "[ ((2SS)) BPSK_QPSK_count = %d ; 16QAM_count = %d ; 64QAM_count = %d ; 256QAM_count = %d ; num_total_qam = %d]\n",
  567. dm_soml_table->num_vht_qam[BPSK_QPSK],
  568. dm_soml_table->num_vht_qam[QAM16],
  569. dm_soml_table->num_vht_qam[QAM64],
  570. dm_soml_table->num_vht_qam[QAM256],
  571. num_total_qam);
  572. if (((dm_soml_table->num_vht_qam[QAM256] * 100) > (num_total_qam * dm_soml_table->qam256_dist_th)) && dm_soml_table->cfo_diff_avg_a > dm_soml_table->cfo_qam256_th && dm_soml_table->cfo_diff_avg_b > dm_soml_table->cfo_qam256_th) {
  573. PHYDM_DBG(dm, DBG_ADPTV_SOML, "[ QAM256_ratio > %d ; cfo_diff_avg_a > %d KHz ==> SOML_OFF]\n", dm_soml_table->qam256_dist_th, dm_soml_table->cfo_qam256_th);
  574. PHYDM_DBG(dm, DBG_ADPTV_SOML, "[ Final decisoin ] : ");
  575. phydm_soml_on_off(dm, SOML_OFF);
  576. return;
  577. } else if (((dm_soml_table->num_vht_qam[QAM64] * 100) > (num_total_qam * dm_soml_table->qam64_dist_th)) && (dm_soml_table->cfo_diff_avg_a > dm_soml_table->cfo_qam64_th) && (dm_soml_table->cfo_diff_avg_b > dm_soml_table->cfo_qam64_th)) {
  578. PHYDM_DBG(dm, DBG_ADPTV_SOML, "[ QAM64_ratio > %d ; cfo_diff_avg_a > %d KHz ==> SOML_OFF]\n", dm_soml_table->qam64_dist_th, dm_soml_table->cfo_qam64_th);
  579. PHYDM_DBG(dm, DBG_ADPTV_SOML, "[ Final decisoin ] : ");
  580. phydm_soml_on_off(dm, SOML_OFF);
  581. return;
  582. } else if (((dm_soml_table->num_vht_qam[QAM16] * 100) > (num_total_qam * dm_soml_table->qam16_dist_th)) && (dm_soml_table->cfo_diff_avg_a > dm_soml_table->cfo_qam16_th) && (dm_soml_table->cfo_diff_avg_b > dm_soml_table->cfo_qam16_th)) {
  583. PHYDM_DBG(dm, DBG_ADPTV_SOML, "[ QAM16_ratio > %d ; cfo_diff_avg_a > %d KHz ==> SOML_OFF]\n", dm_soml_table->qam16_dist_th, dm_soml_table->cfo_qam16_th);
  584. PHYDM_DBG(dm, DBG_ADPTV_SOML, "[ Final decisoin ] : ");
  585. phydm_soml_on_off(dm, SOML_OFF);
  586. return;
  587. } else if (((dm_soml_table->num_vht_qam[BPSK_QPSK] * 100) > (num_total_qam * dm_soml_table->bpsk_qpsk_dist_th)) && (dm_soml_table->cfo_diff_avg_a > dm_soml_table->cfo_qpsk_th) && (dm_soml_table->cfo_diff_avg_b > dm_soml_table->cfo_qpsk_th)) {
  588. PHYDM_DBG(dm, DBG_ADPTV_SOML, "[ BPSK_QPSK_ratio > %d ; cfo_diff_avg_a > %d KHz ==> SOML_OFF]\n", dm_soml_table->bpsk_qpsk_dist_th, dm_soml_table->cfo_qpsk_th);
  589. PHYDM_DBG(dm, DBG_ADPTV_SOML, "[ Final decisoin ] : ");
  590. phydm_soml_on_off(dm, SOML_OFF);
  591. return;
  592. }
  593. for (i = 0; i < rate_num; i++) {
  594. rate_ss_shift = 10 * i;
  595. PHYDM_DBG(dm, DBG_ADPTV_SOML, "[ num_vht_cnt_on VHT-%d ss MCS[0:9] = {%d, %d, %d, %d, %d, %d, %d, %d, %d, %d} ]\n",
  596. (i + 1),
  597. dm_soml_table->num_vht_cnt_on[rate_ss_shift + 0], dm_soml_table->num_vht_cnt_on[rate_ss_shift + 1],
  598. dm_soml_table->num_vht_cnt_on[rate_ss_shift + 2], dm_soml_table->num_vht_cnt_on[rate_ss_shift + 3],
  599. dm_soml_table->num_vht_cnt_on[rate_ss_shift + 4], dm_soml_table->num_vht_cnt_on[rate_ss_shift + 5],
  600. dm_soml_table->num_vht_cnt_on[rate_ss_shift + 6], dm_soml_table->num_vht_cnt_on[rate_ss_shift + 7],
  601. dm_soml_table->num_vht_cnt_on[rate_ss_shift + 8], dm_soml_table->num_vht_cnt_on[rate_ss_shift + 9]);
  602. }
  603. for (i = 0; i < rate_num; i++) {
  604. rate_ss_shift = 10 * i;
  605. PHYDM_DBG(dm, DBG_ADPTV_SOML, "[ num_vht_cnt_off VHT-%d ss MCS[0:9] = {%d, %d, %d, %d, %d, %d, %d, %d, %d, %d} ]\n",
  606. (i + 1),
  607. dm_soml_table->num_vht_cnt_off[rate_ss_shift + 0], dm_soml_table->num_vht_cnt_off[rate_ss_shift + 1],
  608. dm_soml_table->num_vht_cnt_off[rate_ss_shift + 2], dm_soml_table->num_vht_cnt_off[rate_ss_shift + 3],
  609. dm_soml_table->num_vht_cnt_off[rate_ss_shift + 4], dm_soml_table->num_vht_cnt_off[rate_ss_shift + 5],
  610. dm_soml_table->num_vht_cnt_off[rate_ss_shift + 6], dm_soml_table->num_vht_cnt_off[rate_ss_shift + 7],
  611. dm_soml_table->num_vht_cnt_off[rate_ss_shift + 8], dm_soml_table->num_vht_cnt_off[rate_ss_shift + 9]);
  612. }
  613. for (i = ODM_RATEVHTSS2MCS0; i <= ODM_RATEVHTSS2MCS9; i++) {
  614. num_vht_total_cnt_on += dm_soml_table->num_vht_cnt_on[i - ODM_RATEVHTSS1MCS0];
  615. num_vht_total_cnt_off += dm_soml_table->num_vht_cnt_off[i - ODM_RATEVHTSS1MCS0];
  616. total_vht_rate_on += (dm_soml_table->num_vht_cnt_on[i - ODM_RATEVHTSS1MCS0] * vht_phy_rate_table[i - ODM_RATEVHTSS1MCS0]);
  617. total_vht_rate_off += (dm_soml_table->num_vht_cnt_off[i - ODM_RATEVHTSS1MCS0] * vht_phy_rate_table[i - ODM_RATEVHTSS1MCS0]);
  618. }
  619. rate_per_pkt_on = (num_vht_total_cnt_on != 0) ? ((total_vht_rate_on << 3) / num_vht_total_cnt_on) : 0;
  620. rate_per_pkt_off = (num_vht_total_cnt_off != 0) ? ((total_vht_rate_off << 3) / num_vht_total_cnt_off) : 0;
  621. #if 0
  622. for (i = 0; i < rate_num; i++) {
  623. rate_ss_shift = 10 * i;
  624. PHYDM_DBG(dm, DBG_ADPTV_SOML, "[ num_vht_bytes_on VHT-%d ss MCS[0:9] = {%d, %d, %d, %d, %d, %d, %d, %d, %d, %d} ]\n",
  625. (i + 1),
  626. dm_soml_table->num_vht_bytes_on[rate_ss_shift + 0], dm_soml_table->num_vht_bytes_on[rate_ss_shift + 1],
  627. dm_soml_table->num_vht_bytes_on[rate_ss_shift + 2], dm_soml_table->num_vht_bytes_on[rate_ss_shift + 3],
  628. dm_soml_table->num_vht_bytes_on[rate_ss_shift + 4], dm_soml_table->num_vht_bytes_on[rate_ss_shift + 5],
  629. dm_soml_table->num_vht_bytes_on[rate_ss_shift + 6], dm_soml_table->num_vht_bytes_on[rate_ss_shift + 7],
  630. dm_soml_table->num_vht_bytes_on[rate_ss_shift + 8], dm_soml_table->num_vht_bytes_on[rate_ss_shift + 9]);
  631. }
  632. for (i = 0; i < rate_num; i++) {
  633. rate_ss_shift = 10 * i;
  634. PHYDM_DBG(dm, DBG_ADPTV_SOML, "[ num_vht_bytes_off VHT-%d ss MCS[0:9] = {%d, %d, %d, %d, %d, %d, %d, %d, %d, %d} ]\n",
  635. (i + 1),
  636. dm_soml_table->num_vht_bytes_off[rate_ss_shift + 0], dm_soml_table->num_vht_bytes_off[rate_ss_shift + 1],
  637. dm_soml_table->num_vht_bytes_off[rate_ss_shift + 2], dm_soml_table->num_vht_bytes_off[rate_ss_shift + 3],
  638. dm_soml_table->num_vht_bytes_off[rate_ss_shift + 4], dm_soml_table->num_vht_bytes_off[rate_ss_shift + 5],
  639. dm_soml_table->num_vht_bytes_off[rate_ss_shift + 6], dm_soml_table->num_vht_bytes_off[rate_ss_shift + 7],
  640. dm_soml_table->num_vht_bytes_off[rate_ss_shift + 8], dm_soml_table->num_vht_bytes_off[rate_ss_shift + 9]);
  641. }
  642. for (i = ODM_RATEVHTSS2MCS0; i <= ODM_RATEVHTSS2MCS9; i++) {
  643. byte_total_on += dm_soml_table->num_vht_bytes_on[i - ODM_RATEVHTSS1MCS0];
  644. byte_total_off += dm_soml_table->num_vht_bytes_off[i - ODM_RATEVHTSS1MCS0];
  645. }
  646. #endif
  647. }
  648. /* @[Decision] */
  649. PHYDM_DBG(dm, DBG_ADPTV_SOML,
  650. "[ rate_per_pkt_on = %d ; rate_per_pkt_off = %d ]\n",
  651. rate_per_pkt_on, rate_per_pkt_off);
  652. if (rate_per_pkt_on > rate_per_pkt_off) {
  653. next_on_off = SOML_ON;
  654. PHYDM_DBG(dm, DBG_ADPTV_SOML,
  655. "[ rate_per_pkt_on > rate_per_pkt_off ==> SOML_ON ]\n");
  656. } else if (rate_per_pkt_on < rate_per_pkt_off) {
  657. next_on_off = SOML_OFF;
  658. PHYDM_DBG(dm, DBG_ADPTV_SOML,
  659. "[ rate_per_pkt_on < rate_per_pkt_off ==> SOML_OFF ]\n");
  660. } else {
  661. PHYDM_DBG(dm, DBG_ADPTV_SOML,
  662. "[ stay at soml_last_state ]\n");
  663. next_on_off = dm_soml_table->soml_last_state;
  664. }
  665. #if 0
  666. PHYDM_DBG(dm, DBG_ADPTV_SOML,
  667. "[ byte_total_on = %d ; byte_total_off = %d ]\n",
  668. byte_total_on, byte_total_off);
  669. if (byte_total_on > byte_total_off) {
  670. next_on_off = SOML_ON;
  671. PHYDM_DBG(dm, DBG_ADPTV_SOML,
  672. "[ byte_total_on > byte_total_off ==> SOML_ON ]\n");
  673. } else if (byte_total_on < byte_total_off) {
  674. next_on_off = SOML_OFF;
  675. PHYDM_DBG(dm, DBG_ADPTV_SOML,
  676. "[ byte_total_on < byte_total_off ==> SOML_OFF ]\n");
  677. } else {
  678. PHYDM_DBG(dm, DBG_ADPTV_SOML,
  679. "[ stay at soml_last_state ]\n");
  680. next_on_off = dm_soml_table->soml_last_state;
  681. }
  682. #endif
  683. PHYDM_DBG(dm, DBG_ADPTV_SOML, "[ Final decisoin ] : ");
  684. phydm_soml_on_off(dm, next_on_off);
  685. dm_soml_table->soml_last_state = next_on_off;
  686. }
  687. }
  688. }
  689. void phydm_adaptive_soml_reset(
  690. void *dm_void)
  691. {
  692. struct dm_struct *dm = (struct dm_struct *)dm_void;
  693. struct adaptive_soml *dm_soml_table = &dm->dm_soml_table;
  694. dm_soml_table->soml_state_cnt = 0;
  695. dm_soml_table->is_soml_method_enable = 0;
  696. dm_soml_table->soml_counter = 0;
  697. }
  698. void phydm_set_adsl_val(
  699. void *dm_void,
  700. u32 *val_buf,
  701. u8 val_len)
  702. {
  703. struct dm_struct *dm = (struct dm_struct *)dm_void;
  704. if (val_len != 1) {
  705. PHYDM_DBG(dm, ODM_COMP_API, "[Error][ADSL]Need val_len=1\n");
  706. return;
  707. }
  708. phydm_soml_on_off(dm, (u8)val_buf[1]);
  709. }
  710. void phydm_soml_bytes_acq(void *dm_void, u8 rate_id, u32 length)
  711. {
  712. struct dm_struct *dm = (struct dm_struct *)dm_void;
  713. struct adaptive_soml *dm_soml_table = &dm->dm_soml_table;
  714. if (rate_id >= ODM_RATEMCS0 && rate_id <= ODM_RATEMCS31)
  715. dm_soml_table->num_ht_bytes[rate_id - ODM_RATEMCS0] += length;
  716. else if ((rate_id >= ODM_RATEVHTSS1MCS0) && (rate_id <= ODM_RATEVHTSS4MCS9))
  717. dm_soml_table->num_vht_bytes[rate_id - ODM_RATEVHTSS1MCS0] += length;
  718. }
  719. void phydm_adaptive_soml_timers(void *dm_void, u8 state)
  720. {
  721. struct dm_struct *dm = (struct dm_struct *)dm_void;
  722. struct adaptive_soml *dm_soml_table = &dm->dm_soml_table;
  723. if (state == INIT_SOML_TIMMER) {
  724. odm_initialize_timer(dm, &dm_soml_table->phydm_adaptive_soml_timer,
  725. (void *)phydm_adaptive_soml_callback, NULL, "phydm_adaptive_soml_timer");
  726. } else if (state == CANCEL_SOML_TIMMER) {
  727. odm_cancel_timer(dm, &dm_soml_table->phydm_adaptive_soml_timer);
  728. } else if (state == RELEASE_SOML_TIMMER) {
  729. odm_release_timer(dm, &dm_soml_table->phydm_adaptive_soml_timer);
  730. }
  731. }
  732. void phydm_adaptive_soml_init(void *dm_void)
  733. {
  734. struct dm_struct *dm = (struct dm_struct *)dm_void;
  735. struct adaptive_soml *dm_soml_table = &dm->dm_soml_table;
  736. #if 0
  737. if (!(dm->support_ability & ODM_BB_ADAPTIVE_SOML)) {
  738. PHYDM_DBG(dm, DBG_ADPTV_SOML,
  739. "[Return] Not Support Adaptive SOML\n");
  740. return;
  741. }
  742. #endif
  743. PHYDM_DBG(dm, DBG_ADPTV_SOML, "%s\n", __func__);
  744. dm_soml_table->soml_state_cnt = 0;
  745. dm_soml_table->soml_delay_time = 40;
  746. dm_soml_table->soml_intvl = 150;
  747. dm_soml_table->soml_train_num = 4;
  748. dm_soml_table->is_soml_method_enable = 0;
  749. dm_soml_table->soml_counter = 0;
  750. dm_soml_table->soml_period = 1;
  751. dm_soml_table->soml_select = 0;
  752. dm_soml_table->cfo_counter = 0;
  753. dm_soml_table->cfo_diff_sum_a = 0;
  754. dm_soml_table->cfo_diff_sum_b = 0;
  755. dm_soml_table->cfo_qpsk_th = 94;
  756. dm_soml_table->cfo_qam16_th = 38;
  757. dm_soml_table->cfo_qam64_th = 17;
  758. dm_soml_table->cfo_qam256_th = 7;
  759. dm_soml_table->bpsk_qpsk_dist_th = 20;
  760. dm_soml_table->qam16_dist_th = 20;
  761. dm_soml_table->qam64_dist_th = 20;
  762. dm_soml_table->qam256_dist_th = 20;
  763. if (dm->support_ic_type & (ODM_RTL8197F | ODM_RTL8192F))
  764. odm_set_bb_reg(dm, 0x988, BIT(25), 1);
  765. }
  766. void phydm_adaptive_soml(void *dm_void)
  767. {
  768. struct dm_struct *dm = (struct dm_struct *)dm_void;
  769. struct adaptive_soml *dm_soml_table = &dm->dm_soml_table;
  770. if (!(dm->support_ability & ODM_BB_ADAPTIVE_SOML)) {
  771. PHYDM_DBG(dm, DBG_ADPTV_SOML,
  772. "[Return!!!] Not Support Adaptive SOML Function\n");
  773. return;
  774. }
  775. if (dm->pause_ability & ODM_BB_ADAPTIVE_SOML) {
  776. PHYDM_DBG(dm, DBG_ADPTV_SOML, "Return: Pause ADSL in LV=%d\n",
  777. dm->pause_lv_table.lv_adsl);
  778. return;
  779. }
  780. if (dm_soml_table->soml_counter < dm_soml_table->soml_period) {
  781. dm_soml_table->soml_counter++;
  782. return;
  783. }
  784. dm_soml_table->soml_counter = 0;
  785. dm_soml_table->soml_state_cnt = 0;
  786. dm_soml_table->cfo_counter = 0;
  787. dm_soml_table->cfo_diff_sum_a = 0;
  788. dm_soml_table->cfo_diff_sum_b = 0;
  789. phydm_soml_reset_qam(dm);
  790. if (dm_soml_table->soml_select == 0) {
  791. PHYDM_DBG(dm, DBG_ADPTV_SOML,
  792. "[ Adaptive SOML Training !!!]\n");
  793. } else if (dm_soml_table->soml_select == 1) {
  794. PHYDM_DBG(dm, DBG_ADPTV_SOML, "[ Stop Adaptive SOML !!!]\n");
  795. phydm_soml_on_off(dm, SOML_ON);
  796. return;
  797. } else if (dm_soml_table->soml_select == 2) {
  798. PHYDM_DBG(dm, DBG_ADPTV_SOML, "[ Stop Adaptive SOML !!!]\n");
  799. phydm_soml_on_off(dm, SOML_OFF);
  800. return;
  801. }
  802. if (dm->support_ic_type & ODM_ADAPTIVE_SOML_SUPPORT_IC)
  803. phydm_adsl(dm);
  804. }
  805. void phydm_enable_adaptive_soml(void *dm_void)
  806. {
  807. struct dm_struct *dm = (struct dm_struct *)dm_void;
  808. PHYDM_DBG(dm, DBG_ADPTV_SOML, "[%s]\n", __func__);
  809. dm->support_ability |= ODM_BB_ADAPTIVE_SOML;
  810. phydm_soml_on_off(dm, SOML_ON);
  811. }
  812. void phydm_stop_adaptive_soml(void *dm_void)
  813. {
  814. struct dm_struct *dm = (struct dm_struct *)dm_void;
  815. PHYDM_DBG(dm, DBG_ADPTV_SOML, "[%s]\n", __func__);
  816. dm->support_ability &= ~ODM_BB_ADAPTIVE_SOML;
  817. phydm_soml_on_off(dm, SOML_ON);
  818. }
  819. void phydm_adaptive_soml_para_set(void *dm_void, u8 train_num, u8 intvl,
  820. u8 period, u8 delay_time)
  821. {
  822. struct dm_struct *dm = (struct dm_struct *)dm_void;
  823. struct adaptive_soml *dm_soml_table = &dm->dm_soml_table;
  824. dm_soml_table->soml_train_num = train_num;
  825. dm_soml_table->soml_intvl = intvl;
  826. dm_soml_table->soml_period = period;
  827. dm_soml_table->soml_delay_time = delay_time;
  828. }
  829. #endif /* @end of CONFIG_ADAPTIVE_SOML*/
  830. void phydm_init_soft_ml_setting(void *dm_void)
  831. {
  832. struct dm_struct *dm = (struct dm_struct *)dm_void;
  833. u32 soml_mask = BIT(31) | BIT(30) | BIT(29) | BIT(28);
  834. #if (RTL8822B_SUPPORT == 1)
  835. if (!*dm->mp_mode) {
  836. if (dm->support_ic_type & ODM_RTL8822B) {
  837. #if 0
  838. /*odm_set_bb_reg(dm, R_0x19a8, MASKDWORD, 0xd10a0000);*/
  839. #endif
  840. phydm_somlrxhp_setting(dm, true);
  841. dm->bsomlenabled = true;
  842. }
  843. }
  844. #endif
  845. #if (RTL8821C_SUPPORT == 1)
  846. if (!*dm->mp_mode) {
  847. if (dm->support_ic_type & ODM_RTL8821C)
  848. odm_set_bb_reg(dm, R_0x19a8, soml_mask, 0xd);
  849. }
  850. #endif
  851. #if (RTL8195B_SUPPORT == 1)
  852. if (!*dm->mp_mode) {
  853. if (dm->support_ic_type & ODM_RTL8195B)
  854. odm_set_bb_reg(dm, R_0x19a8, soml_mask, 0xd);
  855. }
  856. #endif
  857. }