phydm_cfotracking.c 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501
  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. #include "mp_precomp.h"
  26. #include "phydm_precomp.h"
  27. s32 phydm_get_cfo_hz(void *dm_void, u32 val, u8 bit_num, u8 frac_num)
  28. {
  29. s32 val_s = 0;
  30. val_s = phydm_cnvrt_2_sign(val, bit_num);
  31. if (frac_num == 10) /*@ (X*312500)/1024 ~= X*305*/
  32. val_s *= 305;
  33. else if (frac_num == 11) /*@ (X*312500)/2048 ~= X*152*/
  34. val_s *= 152;
  35. else if (frac_num == 12) /*@ (X*312500)/4096 ~= X*76*/
  36. val_s *= 76;
  37. return val_s;
  38. }
  39. #if (ODM_IC_11AC_SERIES_SUPPORT)
  40. void phydm_get_cfo_info_ac(void *dm_void, struct phydm_cfo_rpt *cfo)
  41. {
  42. struct dm_struct *dm = (struct dm_struct *)dm_void;
  43. u8 i = 0;
  44. u32 val[4] = {0};
  45. u32 val_1[4] = {0};
  46. u32 val_2[4] = {0};
  47. u32 val_tmp = 0;
  48. val[0] = odm_read_4byte(dm, R_0xd0c);
  49. val_1[0] = odm_read_4byte(dm, R_0xd10);
  50. val_2[0] = odm_get_bb_reg(dm, R_0xd14, 0x1fff0000);
  51. #if (defined(PHYDM_COMPILE_ABOVE_2SS))
  52. val[1] = odm_read_4byte(dm, R_0xd4c);
  53. val_1[1] = odm_read_4byte(dm, R_0xd50);
  54. val_2[1] = odm_get_bb_reg(dm, R_0xd54, 0x1fff0000);
  55. #endif
  56. #if (defined(PHYDM_COMPILE_ABOVE_3SS))
  57. val[2] = odm_read_4byte(dm, R_0xd8c);
  58. val_1[2] = odm_read_4byte(dm, R_0xd90);
  59. val_2[2] = odm_get_bb_reg(dm, R_0xd94, 0x1fff0000);
  60. #endif
  61. #if (defined(PHYDM_COMPILE_ABOVE_4SS))
  62. val[3] = odm_read_4byte(dm, R_0xdcc);
  63. val_1[3] = odm_read_4byte(dm, R_0xdd0);
  64. val_2[3] = odm_get_bb_reg(dm, R_0xdd4, 0x1fff0000);
  65. #endif
  66. for (i = 0; i < dm->num_rf_path; i++) {
  67. val_tmp = val[i] & 0xfff; /*@ Short CFO, S(12,11)*/
  68. cfo->cfo_rpt_s[i] = phydm_get_cfo_hz(dm, val_tmp, 12, 11);
  69. val_tmp = val[i] >> 16; /*@ Long CFO, S(13,12)*/
  70. cfo->cfo_rpt_l[i] = phydm_get_cfo_hz(dm, val_tmp, 13, 12);
  71. val_tmp = val_1[i] & 0x7ff; /*@ SCFO, S(11,10)*/
  72. cfo->cfo_rpt_sec[i] = phydm_get_cfo_hz(dm, val_tmp, 11, 10);
  73. val_tmp = val_1[i] >> 16; /*@ Acq CFO, S(13,12)*/
  74. cfo->cfo_rpt_acq[i] = phydm_get_cfo_hz(dm, val_tmp, 13, 12);
  75. val_tmp = val_2[i]; /*@ End CFO, S(13,12)*/
  76. cfo->cfo_rpt_end[i] = phydm_get_cfo_hz(dm, val_tmp, 13, 12);
  77. }
  78. }
  79. #endif
  80. #if (ODM_IC_11N_SERIES_SUPPORT)
  81. void phydm_get_cfo_info_n(void *dm_void, struct phydm_cfo_rpt *cfo)
  82. {
  83. struct dm_struct *dm = (struct dm_struct *)dm_void;
  84. u32 val[5] = {0};
  85. u32 val_tmp = 0;
  86. odm_set_bb_reg(dm, R_0xd00, BIT(26), 1);
  87. val[0] = odm_read_4byte(dm, R_0xdac); /*@ Short CFO*/
  88. val[1] = odm_read_4byte(dm, R_0xdb0); /*@ Long CFO*/
  89. val[2] = odm_read_4byte(dm, R_0xdb8); /*@ Sec CFO*/
  90. val[3] = odm_read_4byte(dm, R_0xde0); /*@ Acq CFO*/
  91. val[4] = odm_read_4byte(dm, R_0xdbc); /*@ End CFO*/
  92. /*@[path-A]*/
  93. val_tmp = (val[0] & 0x0fff0000) >> 16; /*@ Short CFO, S(12,11)*/
  94. cfo->cfo_rpt_s[0] = phydm_get_cfo_hz(dm, val_tmp, 12, 11);
  95. val_tmp = (val[1] & 0x1fff0000) >> 16; /*@ Long CFO, S(13,12)*/
  96. cfo->cfo_rpt_l[0] = phydm_get_cfo_hz(dm, val_tmp, 13, 12);
  97. val_tmp = (val[2] & 0x7ff0000) >> 16; /*@ Sec CFO, S(11,10)*/
  98. cfo->cfo_rpt_sec[0] = phydm_get_cfo_hz(dm, val_tmp, 11, 10);
  99. val_tmp = (val[3] & 0x1fff0000) >> 16; /*@ Acq CFO, S(13,12)*/
  100. cfo->cfo_rpt_acq[0] = phydm_get_cfo_hz(dm, val_tmp, 13, 12);
  101. val_tmp = (val[4] & 0x1fff0000) >> 16; /*@ Acq CFO, S(13,12)*/
  102. cfo->cfo_rpt_end[0] = phydm_get_cfo_hz(dm, val_tmp, 13, 12);
  103. #if (defined(PHYDM_COMPILE_ABOVE_2SS))
  104. /*@[path-B]*/
  105. val_tmp = val[0] & 0xfff; /*@ Short CFO, S(12,11)*/
  106. cfo->cfo_rpt_s[1] = phydm_get_cfo_hz(dm, val_tmp, 12, 11);
  107. val_tmp = val[1] & 0x1fff; /*@ Long CFO, S(13,12)*/
  108. cfo->cfo_rpt_l[1] = phydm_get_cfo_hz(dm, val_tmp, 13, 12);
  109. val_tmp = val[2] & 0x7ff; /*@ Sec CFO, S(11,10)*/
  110. cfo->cfo_rpt_sec[1] = phydm_get_cfo_hz(dm, val_tmp, 11, 10);
  111. val_tmp = val[3] & 0x1fff; /*@ Acq CFO, S(13,12)*/
  112. cfo->cfo_rpt_acq[1] = phydm_get_cfo_hz(dm, val_tmp, 13, 12);
  113. val_tmp = val[4] & 0x1fff; /*@ Acq CFO, S(13,12)*/
  114. cfo->cfo_rpt_end[1] = phydm_get_cfo_hz(dm, val_tmp, 13, 12);
  115. #endif
  116. }
  117. void phydm_set_atc_status(void *dm_void, boolean atc_status)
  118. {
  119. struct dm_struct *dm = (struct dm_struct *)dm_void;
  120. struct phydm_cfo_track_struct *cfo_track = &dm->dm_cfo_track;
  121. u32 reg_tmp = 0;
  122. u32 mask_tmp = 0;
  123. PHYDM_DBG(dm, DBG_CFO_TRK, "[%s]ATC_en=%d\n", __func__, atc_status);
  124. if (cfo_track->is_atc_status == atc_status)
  125. return;
  126. reg_tmp = ODM_REG(BB_ATC, dm);
  127. mask_tmp = ODM_BIT(BB_ATC, dm);
  128. odm_set_bb_reg(dm, reg_tmp, mask_tmp, atc_status);
  129. cfo_track->is_atc_status = atc_status;
  130. }
  131. boolean
  132. phydm_get_atc_status(void *dm_void)
  133. {
  134. boolean atc_status = false;
  135. struct dm_struct *dm = (struct dm_struct *)dm_void;
  136. u32 reg_tmp = 0;
  137. u32 mask_tmp = 0;
  138. reg_tmp = ODM_REG(BB_ATC, dm);
  139. mask_tmp = ODM_BIT(BB_ATC, dm);
  140. atc_status = (boolean)odm_get_bb_reg(dm, reg_tmp, mask_tmp);
  141. PHYDM_DBG(dm, DBG_CFO_TRK, "[%s]atc_status=%d\n", __func__, atc_status);
  142. return atc_status;
  143. }
  144. #endif
  145. void phydm_get_cfo_info(void *dm_void, struct phydm_cfo_rpt *cfo)
  146. {
  147. struct dm_struct *dm = (struct dm_struct *)dm_void;
  148. switch (dm->ic_ip_series) {
  149. #if (ODM_IC_11N_SERIES_SUPPORT)
  150. case PHYDM_IC_N:
  151. phydm_get_cfo_info_n(dm, cfo);
  152. break;
  153. #endif
  154. #if (ODM_IC_11AC_SERIES_SUPPORT)
  155. case PHYDM_IC_AC:
  156. phydm_get_cfo_info_ac(dm, cfo);
  157. break;
  158. #endif
  159. default:
  160. break;
  161. }
  162. }
  163. void phydm_set_crystal_cap(void *dm_void, u8 crystal_cap)
  164. {
  165. struct dm_struct *dm = (struct dm_struct *)dm_void;
  166. struct phydm_cfo_track_struct *cfo_track = &dm->dm_cfo_track;
  167. u32 reg_val = 0;
  168. if (cfo_track->crystal_cap == crystal_cap)
  169. return;
  170. if (dm->support_ic_type & (ODM_RTL8822C | ODM_RTL8814B)) {
  171. crystal_cap &= 0x7F;
  172. reg_val = crystal_cap | (crystal_cap << 7);
  173. } else {
  174. crystal_cap &= 0x3F;
  175. reg_val = crystal_cap | (crystal_cap << 6);
  176. }
  177. cfo_track->crystal_cap = crystal_cap;
  178. if (dm->support_ic_type & (ODM_RTL8188E | ODM_RTL8188F)) {
  179. #if (RTL8188E_SUPPORT || RTL8188F_SUPPORT)
  180. /* write 0x24[22:17] = 0x24[16:11] = crystal_cap */
  181. odm_set_mac_reg(dm, R_0x24, 0x7ff800, reg_val);
  182. #endif
  183. }
  184. #if (RTL8812A_SUPPORT)
  185. else if (dm->support_ic_type & ODM_RTL8812) {
  186. /* write 0x2C[30:25] = 0x2C[24:19] = crystal_cap */
  187. odm_set_mac_reg(dm, R_0x2c, 0x7FF80000, reg_val);
  188. }
  189. #endif
  190. #if (RTL8703B_SUPPORT || RTL8723B_SUPPORT || RTL8192E_SUPPORT ||\
  191. RTL8821A_SUPPORT || RTL8723D_SUPPORT)
  192. else if ((dm->support_ic_type &
  193. (ODM_RTL8703B | ODM_RTL8723B | ODM_RTL8192E | ODM_RTL8821 |
  194. ODM_RTL8723D))) {
  195. /* @0x2C[23:18] = 0x2C[17:12] = crystal_cap */
  196. odm_set_mac_reg(dm, R_0x2c, 0x00FFF000, reg_val);
  197. }
  198. #endif
  199. #if (RTL8814A_SUPPORT)
  200. else if (dm->support_ic_type & ODM_RTL8814A) {
  201. /* write 0x2C[26:21] = 0x2C[20:15] = crystal_cap */
  202. odm_set_mac_reg(dm, R_0x2c, 0x07FF8000, reg_val);
  203. }
  204. #endif
  205. #if (RTL8822B_SUPPORT || RTL8821C_SUPPORT || RTL8197F_SUPPORT ||\
  206. RTL8192F_SUPPORT)
  207. else if (dm->support_ic_type & (ODM_RTL8822B | ODM_RTL8821C |
  208. ODM_RTL8197F | ODM_RTL8192F)) {
  209. /* write 0x24[30:25] = 0x28[6:1] = crystal_cap */
  210. odm_set_mac_reg(dm, R_0x24, 0x7e000000, crystal_cap);
  211. odm_set_mac_reg(dm, R_0x28, 0x7e, crystal_cap);
  212. }
  213. #endif
  214. #if (RTL8710B_SUPPORT)
  215. else if (dm->support_ic_type & (ODM_RTL8710B)) {
  216. #if (DM_ODM_SUPPORT_TYPE & (ODM_WIN | ODM_CE))
  217. /* write 0x60[29:24] = 0x60[23:18] = crystal_cap */
  218. HAL_SetSYSOnReg(dm->adapter, R_0x60, 0x3FFC0000, reg_val);
  219. #endif
  220. }
  221. #endif
  222. #if (RTL8822C_SUPPORT || RTL8814B_SUPPORT)
  223. else if (dm->support_ic_type & (ODM_RTL8822C | ODM_RTL8814B)) {
  224. /* write 0x1040[23:17] = 0x1040[16:10] = crystal_cap */
  225. odm_set_mac_reg(dm, R_0x1040, 0x00FFFC00, reg_val);
  226. }
  227. #endif
  228. PHYDM_DBG(dm, DBG_CFO_TRK, "Set rystal_cap = 0x%x\n",
  229. cfo_track->crystal_cap);
  230. }
  231. void phydm_cfo_tracking_reset(void *dm_void)
  232. {
  233. struct dm_struct *dm = (struct dm_struct *)dm_void;
  234. struct phydm_cfo_track_struct *cfo_track = &dm->dm_cfo_track;
  235. PHYDM_DBG(dm, DBG_CFO_TRK, "%s ======>\n", __func__);
  236. if (dm->support_ic_type & (ODM_RTL8822C | ODM_RTL8814B))
  237. cfo_track->def_x_cap = cfo_track->crystal_cap_default & 0x7F;
  238. else
  239. cfo_track->def_x_cap = cfo_track->crystal_cap_default & 0x3f;
  240. cfo_track->is_adjust = true;
  241. if (cfo_track->crystal_cap > cfo_track->def_x_cap) {
  242. phydm_set_crystal_cap(dm, cfo_track->crystal_cap - 1);
  243. PHYDM_DBG(dm, DBG_CFO_TRK, "approch to Init-val (0x%x)\n",
  244. cfo_track->crystal_cap);
  245. } else if (cfo_track->crystal_cap < cfo_track->def_x_cap) {
  246. phydm_set_crystal_cap(dm, cfo_track->crystal_cap + 1);
  247. PHYDM_DBG(dm, DBG_CFO_TRK, "approch to init-val 0x%x\n",
  248. cfo_track->crystal_cap);
  249. }
  250. #if ODM_IC_11N_SERIES_SUPPORT
  251. #if (DM_ODM_SUPPORT_TYPE & (ODM_WIN | ODM_CE))
  252. if (dm->support_ic_type & ODM_IC_11N_SERIES)
  253. phydm_set_atc_status(dm, true);
  254. #endif
  255. #endif
  256. }
  257. void phydm_cfo_tracking_init(void *dm_void)
  258. {
  259. struct dm_struct *dm = (struct dm_struct *)dm_void;
  260. struct phydm_cfo_track_struct *cfo_track = &dm->dm_cfo_track;
  261. PHYDM_DBG(dm, DBG_CFO_TRK, "[%s]=========>\n", __func__);
  262. if (dm->support_ic_type & (ODM_RTL8822C | ODM_RTL8814B))
  263. cfo_track->crystal_cap = cfo_track->crystal_cap_default & 0x7F;
  264. else
  265. cfo_track->crystal_cap = cfo_track->crystal_cap_default & 0x3f;
  266. cfo_track->def_x_cap = cfo_track->crystal_cap;
  267. cfo_track->is_adjust = true;
  268. PHYDM_DBG(dm, DBG_CFO_TRK, "crystal_cap=0x%x\n", cfo_track->def_x_cap);
  269. #if (RTL8822B_SUPPORT || RTL8821C_SUPPORT)
  270. /* @Crystal cap. control by WiFi */
  271. if (dm->support_ic_type & (ODM_RTL8822B | ODM_RTL8821C))
  272. odm_set_mac_reg(dm, R_0x10, 0x40, 0x1);
  273. #endif
  274. }
  275. void phydm_cfo_tracking(void *dm_void)
  276. {
  277. struct dm_struct *dm = (struct dm_struct *)dm_void;
  278. struct phydm_cfo_track_struct *cfo_track = &dm->dm_cfo_track;
  279. s32 cfo_avg = 0, cfo_path_sum = 0, cfo_abs = 0;
  280. u32 cfo_rpt_sum = 0, cfo_khz_avg[4] = {0};
  281. s8 crystal_cap = cfo_track->crystal_cap;
  282. u8 i = 0, valid_path_cnt = 0;
  283. if (!(dm->support_ability & ODM_BB_CFO_TRACKING))
  284. return;
  285. PHYDM_DBG(dm, DBG_CFO_TRK, "%s ======>\n", __func__);
  286. if (!dm->is_linked || !dm->is_one_entry_only) {
  287. phydm_cfo_tracking_reset(dm);
  288. PHYDM_DBG(dm, DBG_CFO_TRK, "is_linked=%d, one_entry_only=%d\n",
  289. dm->is_linked, dm->is_one_entry_only);
  290. } else {
  291. /* No new packet */
  292. if (cfo_track->packet_count == cfo_track->packet_count_pre) {
  293. PHYDM_DBG(dm, DBG_CFO_TRK, "Pkt cnt doesn't change\n");
  294. return;
  295. }
  296. cfo_track->packet_count_pre = cfo_track->packet_count;
  297. /*@Calculate CFO */
  298. for (i = 0; i < dm->num_rf_path; i++) {
  299. if (cfo_track->CFO_cnt[i] == 0)
  300. continue;
  301. valid_path_cnt++;
  302. if (cfo_track->CFO_tail[i] < 0)
  303. cfo_abs = 0 - cfo_track->CFO_tail[i];
  304. else
  305. cfo_abs = cfo_track->CFO_tail[i];
  306. cfo_rpt_sum = (u32)CFO_HW_RPT_2_KHZ(cfo_abs);
  307. cfo_khz_avg[i] = cfo_rpt_sum / cfo_track->CFO_cnt[i];
  308. PHYDM_DBG(dm, DBG_CFO_TRK,
  309. "[Path-%d] CFO_sum=((%d)), cnt=((%d)), CFO_avg=((%s%d))kHz\n",
  310. i, cfo_rpt_sum, cfo_track->CFO_cnt[i],
  311. ((cfo_track->CFO_tail[i] < 0) ? "-" : " "),
  312. cfo_khz_avg[i]);
  313. }
  314. for (i = 0; i < valid_path_cnt; i++) {
  315. if (cfo_track->CFO_tail[i] < 0)
  316. cfo_path_sum += (0 - (s32)cfo_khz_avg[i]);
  317. else
  318. cfo_path_sum += (s32)cfo_khz_avg[i];
  319. }
  320. if (valid_path_cnt >= 2)
  321. cfo_avg = cfo_path_sum / valid_path_cnt;
  322. else
  323. cfo_avg = cfo_path_sum;
  324. cfo_track->CFO_ave_pre = cfo_avg;
  325. PHYDM_DBG(dm, DBG_CFO_TRK, "path_cnt=%d, CFO_avg_path=%d kHz\n",
  326. valid_path_cnt, cfo_avg);
  327. /*reset counter*/
  328. for (i = 0; i < dm->num_rf_path; i++) {
  329. cfo_track->CFO_tail[i] = 0;
  330. cfo_track->CFO_cnt[i] = 0;
  331. }
  332. /* To adjust crystal cap or not */
  333. if (!cfo_track->is_adjust) {
  334. if (cfo_avg > CFO_TRK_ENABLE_TH ||
  335. cfo_avg < (-CFO_TRK_ENABLE_TH))
  336. cfo_track->is_adjust = true;
  337. } else {
  338. if (cfo_avg < CFO_TRK_STOP_TH &&
  339. cfo_avg > (-CFO_TRK_STOP_TH))
  340. cfo_track->is_adjust = false;
  341. }
  342. #ifdef ODM_CONFIG_BT_COEXIST
  343. /*@BT case: Disable CFO tracking */
  344. if (dm->bt_info_table.is_bt_enabled) {
  345. cfo_track->is_adjust = false;
  346. phydm_set_crystal_cap(dm, cfo_track->def_x_cap);
  347. PHYDM_DBG(dm, DBG_CFO_TRK, "[BT]Disable CFO_track\n");
  348. }
  349. #endif
  350. /*@Adjust Crystal Cap. */
  351. if (cfo_track->is_adjust) {
  352. if (cfo_avg > CFO_TRK_STOP_TH)
  353. crystal_cap += 1;
  354. else if (cfo_avg < (-CFO_TRK_STOP_TH))
  355. crystal_cap -= 1;
  356. if (dm->support_ic_type & (ODM_RTL8822C |
  357. ODM_RTL8814B)) {
  358. if (crystal_cap > 0x7F)
  359. crystal_cap = 0x7F;
  360. } else {
  361. if (crystal_cap > 0x3F)
  362. crystal_cap = 0x3F;
  363. }
  364. if (crystal_cap < 0)
  365. crystal_cap = 0;
  366. phydm_set_crystal_cap(dm, (u8)crystal_cap);
  367. }
  368. PHYDM_DBG(dm, DBG_CFO_TRK, "X_cap{Curr,Default}={0x%x,0x%x}\n",
  369. cfo_track->crystal_cap, cfo_track->def_x_cap);
  370. /* @Dynamic ATC switch */
  371. #if ODM_IC_11N_SERIES_SUPPORT
  372. #if (DM_ODM_SUPPORT_TYPE & (ODM_WIN | ODM_CE))
  373. if (dm->support_ic_type & ODM_IC_11N_SERIES) {
  374. if (cfo_avg < CFO_TH_ATC && cfo_avg > -CFO_TH_ATC)
  375. phydm_set_atc_status(dm, false);
  376. else
  377. phydm_set_atc_status(dm, true);
  378. }
  379. #endif
  380. #endif
  381. }
  382. }
  383. void phydm_parsing_cfo(void *dm_void, void *pktinfo_void, s8 *pcfotail,
  384. u8 num_ss)
  385. {
  386. struct dm_struct *dm = (struct dm_struct *)dm_void;
  387. struct phydm_perpkt_info_struct *pktinfo = NULL;
  388. struct phydm_cfo_track_struct *cfo_track = &dm->dm_cfo_track;
  389. boolean valid_info = false;
  390. u8 i = 0;
  391. if (!(dm->support_ability & ODM_BB_CFO_TRACKING))
  392. return;
  393. pktinfo = (struct phydm_perpkt_info_struct *)pktinfo_void;
  394. #if (DM_ODM_SUPPORT_TYPE & (ODM_WIN | ODM_CE))
  395. if (pktinfo->is_packet_match_bssid)
  396. valid_info = true;
  397. #else
  398. if (dm->number_active_client == 1)
  399. valid_info = true;
  400. #endif
  401. if (valid_info) {
  402. if (num_ss > dm->num_rf_path) /*@For fool proof*/
  403. num_ss = dm->num_rf_path;
  404. #if 0
  405. PHYDM_DBG(dm, DBG_CFO_TRK, "num_ss=%d, num_rf_path=%d\n",
  406. num_ss, dm->num_rf_path);
  407. #endif
  408. /* @ Update CFO report for path-A & path-B */
  409. /* Only paht-A and path-B have CFO tail and short CFO */
  410. for (i = 0; i < num_ss; i++) {
  411. cfo_track->CFO_tail[i] += pcfotail[i];
  412. cfo_track->CFO_cnt[i]++;
  413. #if 0
  414. PHYDM_DBG(dm, DBG_CFO_TRK,
  415. "[ID %d][path %d][rate 0x%x] CFO_tail = ((%d)), CFO_tail_sum = ((%d)), CFO_cnt = ((%d))\n",
  416. pktinfo->station_id, i, pktinfo->data_rate,
  417. pcfotail[i], cfo_track->CFO_tail[i],
  418. cfo_track->CFO_cnt[i]);
  419. #endif
  420. }
  421. /* @ Update packet counter */
  422. if (cfo_track->packet_count == 0xffffffff)
  423. cfo_track->packet_count = 0;
  424. else
  425. cfo_track->packet_count++;
  426. }
  427. }