phydm_pathdiv.c 22 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693
  1. /******************************************************************************
  2. *
  3. * Copyright(c) 2007 - 2011 Realtek Corporation. All rights reserved.
  4. *
  5. * This program is free software; you can redistribute it and/or modify it
  6. * under the terms of version 2 of the GNU General Public License as
  7. * published by the Free Software Foundation.
  8. *
  9. * This program is distributed in the hope that it will be useful, but WITHOUT
  10. * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  11. * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
  12. * more details.
  13. *
  14. * You should have received a copy of the GNU General Public License along with
  15. * this program; if not, write to the Free Software Foundation, Inc.,
  16. * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA
  17. *
  18. *
  19. ******************************************************************************/
  20. /* ************************************************************
  21. * include files
  22. * ************************************************************ */
  23. #include "mp_precomp.h"
  24. #include "phydm_precomp.h"
  25. #if (defined(CONFIG_PATH_DIVERSITY))
  26. #if RTL8814A_SUPPORT
  27. void
  28. phydm_dtp_fix_tx_path(
  29. void *p_dm_void,
  30. u8 path
  31. )
  32. {
  33. struct PHY_DM_STRUCT *p_dm_odm = (struct PHY_DM_STRUCT *)p_dm_void;
  34. struct _ODM_PATH_DIVERSITY_ *p_dm_path_div = &p_dm_odm->dm_path_div;
  35. u8 i, num_enable_path = 0;
  36. if (path == p_dm_path_div->pre_tx_path)
  37. return;
  38. else
  39. p_dm_path_div->pre_tx_path = path;
  40. odm_set_bb_reg(p_dm_odm, 0x93c, BIT(18) | BIT(19), 3);
  41. for (i = 0; i < 4; i++) {
  42. if (path & BIT(i))
  43. num_enable_path++;
  44. }
  45. ODM_RT_TRACE(p_dm_odm, ODM_COMP_PATH_DIV, ODM_DBG_LOUD, (" number of trun-on path : (( %d ))\n", num_enable_path));
  46. if (num_enable_path == 1) {
  47. odm_set_bb_reg(p_dm_odm, 0x93c, 0xf00000, path);
  48. if (path == PHYDM_A) { /* 1-1 */
  49. ODM_RT_TRACE(p_dm_odm, ODM_COMP_PATH_DIV, ODM_DBG_LOUD, (" Trun on path (( A ))\n"));
  50. odm_set_bb_reg(p_dm_odm, 0x93c, BIT(25) | BIT(24), 0);
  51. } else if (path == PHYDM_B) { /* 1-2 */
  52. ODM_RT_TRACE(p_dm_odm, ODM_COMP_PATH_DIV, ODM_DBG_LOUD, (" Trun on path (( B ))\n"));
  53. odm_set_bb_reg(p_dm_odm, 0x93c, BIT(27) | BIT(26), 0);
  54. } else if (path == PHYDM_C) { /* 1-3 */
  55. ODM_RT_TRACE(p_dm_odm, ODM_COMP_PATH_DIV, ODM_DBG_LOUD, (" Trun on path (( C ))\n"));
  56. odm_set_bb_reg(p_dm_odm, 0x93c, BIT(29) | BIT(28), 0);
  57. } else if (path == PHYDM_D) { /* 1-4 */
  58. ODM_RT_TRACE(p_dm_odm, ODM_COMP_PATH_DIV, ODM_DBG_LOUD, (" Trun on path (( D ))\n"));
  59. odm_set_bb_reg(p_dm_odm, 0x93c, BIT(31) | BIT(30), 0);
  60. }
  61. } else if (num_enable_path == 2) {
  62. odm_set_bb_reg(p_dm_odm, 0x93c, 0xf00000, path);
  63. odm_set_bb_reg(p_dm_odm, 0x940, 0xf0, path);
  64. if (path == PHYDM_AB) { /* 2-1 */
  65. ODM_RT_TRACE(p_dm_odm, ODM_COMP_PATH_DIV, ODM_DBG_LOUD, (" Trun on path (( A B ))\n"));
  66. /* set for 1ss */
  67. odm_set_bb_reg(p_dm_odm, 0x93c, BIT(25) | BIT(24), 0);
  68. odm_set_bb_reg(p_dm_odm, 0x93c, BIT(27) | BIT(26), 1);
  69. /* set for 2ss */
  70. odm_set_bb_reg(p_dm_odm, 0x940, BIT(9) | BIT(8), 0);
  71. odm_set_bb_reg(p_dm_odm, 0x940, BIT(11) | BIT(10), 1);
  72. } else if (path == PHYDM_AC) { /* 2-2 */
  73. ODM_RT_TRACE(p_dm_odm, ODM_COMP_PATH_DIV, ODM_DBG_LOUD, (" Trun on path (( A C ))\n"));
  74. /* set for 1ss */
  75. odm_set_bb_reg(p_dm_odm, 0x93c, BIT(25) | BIT(24), 0);
  76. odm_set_bb_reg(p_dm_odm, 0x93c, BIT(29) | BIT(28), 1);
  77. /* set for 2ss */
  78. odm_set_bb_reg(p_dm_odm, 0x940, BIT(9) | BIT(8), 0);
  79. odm_set_bb_reg(p_dm_odm, 0x940, BIT(13) | BIT(12), 1);
  80. } else if (path == PHYDM_AD) { /* 2-3 */
  81. ODM_RT_TRACE(p_dm_odm, ODM_COMP_PATH_DIV, ODM_DBG_LOUD, (" Trun on path (( A D ))\n"));
  82. /* set for 1ss */
  83. odm_set_bb_reg(p_dm_odm, 0x93c, BIT(25) | BIT(24), 0);
  84. odm_set_bb_reg(p_dm_odm, 0x93c, BIT(31) | BIT(30), 1);
  85. /* set for 2ss */
  86. odm_set_bb_reg(p_dm_odm, 0x940, BIT(9) | BIT(8), 0);
  87. odm_set_bb_reg(p_dm_odm, 0x940, BIT(15) | BIT(14), 1);
  88. } else if (path == PHYDM_BC) { /* 2-4 */
  89. ODM_RT_TRACE(p_dm_odm, ODM_COMP_PATH_DIV, ODM_DBG_LOUD, (" Trun on path (( B C ))\n"));
  90. /* set for 1ss */
  91. odm_set_bb_reg(p_dm_odm, 0x93c, BIT(27) | BIT(26), 0);
  92. odm_set_bb_reg(p_dm_odm, 0x93c, BIT(29) | BIT(28), 1);
  93. /* set for 2ss */
  94. odm_set_bb_reg(p_dm_odm, 0x940, BIT(11) | BIT(10), 0);
  95. odm_set_bb_reg(p_dm_odm, 0x940, BIT(13) | BIT(12), 1);
  96. } else if (path == PHYDM_BD) { /* 2-5 */
  97. ODM_RT_TRACE(p_dm_odm, ODM_COMP_PATH_DIV, ODM_DBG_LOUD, (" Trun on path (( B D ))\n"));
  98. /* set for 1ss */
  99. odm_set_bb_reg(p_dm_odm, 0x93c, BIT(27) | BIT(26), 0);
  100. odm_set_bb_reg(p_dm_odm, 0x93c, BIT(31) | BIT(30), 1);
  101. /* set for 2ss */
  102. odm_set_bb_reg(p_dm_odm, 0x940, BIT(11) | BIT(10), 0);
  103. odm_set_bb_reg(p_dm_odm, 0x940, BIT(15) | BIT(14), 1);
  104. } else if (path == PHYDM_CD) { /* 2-6 */
  105. ODM_RT_TRACE(p_dm_odm, ODM_COMP_PATH_DIV, ODM_DBG_LOUD, (" Trun on path (( C D ))\n"));
  106. /* set for 1ss */
  107. odm_set_bb_reg(p_dm_odm, 0x93c, BIT(29) | BIT(28), 0);
  108. odm_set_bb_reg(p_dm_odm, 0x93c, BIT(31) | BIT(30), 1);
  109. /* set for 2ss */
  110. odm_set_bb_reg(p_dm_odm, 0x940, BIT(13) | BIT(12), 0);
  111. odm_set_bb_reg(p_dm_odm, 0x940, BIT(15) | BIT(14), 1);
  112. }
  113. } else if (num_enable_path == 3) {
  114. odm_set_bb_reg(p_dm_odm, 0x93c, 0xf00000, path);
  115. odm_set_bb_reg(p_dm_odm, 0x940, 0xf0, path);
  116. odm_set_bb_reg(p_dm_odm, 0x940, 0xf0000, path);
  117. if (path == PHYDM_ABC) { /* 3-1 */
  118. ODM_RT_TRACE(p_dm_odm, ODM_COMP_PATH_DIV, ODM_DBG_LOUD, (" Trun on path (( A B C))\n"));
  119. /* set for 1ss */
  120. odm_set_bb_reg(p_dm_odm, 0x93c, BIT(25) | BIT(24), 0);
  121. odm_set_bb_reg(p_dm_odm, 0x93c, BIT(27) | BIT(26), 1);
  122. odm_set_bb_reg(p_dm_odm, 0x93c, BIT(29) | BIT(28), 2);
  123. /* set for 2ss */
  124. odm_set_bb_reg(p_dm_odm, 0x940, BIT(9) | BIT(8), 0);
  125. odm_set_bb_reg(p_dm_odm, 0x940, BIT(11) | BIT(10), 1);
  126. odm_set_bb_reg(p_dm_odm, 0x940, BIT(13) | BIT(12), 2);
  127. /* set for 3ss */
  128. odm_set_bb_reg(p_dm_odm, 0x940, BIT(21) | BIT(20), 0);
  129. odm_set_bb_reg(p_dm_odm, 0x940, BIT(23) | BIT(22), 1);
  130. odm_set_bb_reg(p_dm_odm, 0x940, BIT(25) | BIT(24), 2);
  131. } else if (path == PHYDM_ABD) { /* 3-2 */
  132. ODM_RT_TRACE(p_dm_odm, ODM_COMP_PATH_DIV, ODM_DBG_LOUD, (" Trun on path (( A B D ))\n"));
  133. /* set for 1ss */
  134. odm_set_bb_reg(p_dm_odm, 0x93c, BIT(25) | BIT(24), 0);
  135. odm_set_bb_reg(p_dm_odm, 0x93c, BIT(27) | BIT(26), 1);
  136. odm_set_bb_reg(p_dm_odm, 0x93c, BIT(31) | BIT(30), 2);
  137. /* set for 2ss */
  138. odm_set_bb_reg(p_dm_odm, 0x940, BIT(9) | BIT(8), 0);
  139. odm_set_bb_reg(p_dm_odm, 0x940, BIT(11) | BIT(10), 1);
  140. odm_set_bb_reg(p_dm_odm, 0x940, BIT(15) | BIT(14), 2);
  141. /* set for 3ss */
  142. odm_set_bb_reg(p_dm_odm, 0x940, BIT(21) | BIT(20), 0);
  143. odm_set_bb_reg(p_dm_odm, 0x940, BIT(23) | BIT(22), 1);
  144. odm_set_bb_reg(p_dm_odm, 0x940, BIT(27) | BIT(26), 2);
  145. } else if (path == PHYDM_ACD) { /* 3-3 */
  146. ODM_RT_TRACE(p_dm_odm, ODM_COMP_PATH_DIV, ODM_DBG_LOUD, (" Trun on path (( A C D ))\n"));
  147. /* set for 1ss */
  148. odm_set_bb_reg(p_dm_odm, 0x93c, BIT(25) | BIT(24), 0);
  149. odm_set_bb_reg(p_dm_odm, 0x93c, BIT(29) | BIT(28), 1);
  150. odm_set_bb_reg(p_dm_odm, 0x93c, BIT(31) | BIT(30), 2);
  151. /* set for 2ss */
  152. odm_set_bb_reg(p_dm_odm, 0x940, BIT(9) | BIT(8), 0);
  153. odm_set_bb_reg(p_dm_odm, 0x940, BIT(13) | BIT(12), 1);
  154. odm_set_bb_reg(p_dm_odm, 0x940, BIT(15) | BIT(14), 2);
  155. /* set for 3ss */
  156. odm_set_bb_reg(p_dm_odm, 0x940, BIT(21) | BIT(20), 0);
  157. odm_set_bb_reg(p_dm_odm, 0x940, BIT(25) | BIT(24), 1);
  158. odm_set_bb_reg(p_dm_odm, 0x940, BIT(27) | BIT(26), 2);
  159. } else if (path == PHYDM_BCD) { /* 3-4 */
  160. ODM_RT_TRACE(p_dm_odm, ODM_COMP_PATH_DIV, ODM_DBG_LOUD, (" Trun on path (( B C D))\n"));
  161. /* set for 1ss */
  162. odm_set_bb_reg(p_dm_odm, 0x93c, BIT(27) | BIT(26), 0);
  163. odm_set_bb_reg(p_dm_odm, 0x93c, BIT(29) | BIT(28), 1);
  164. odm_set_bb_reg(p_dm_odm, 0x93c, BIT(31) | BIT(30), 2);
  165. /* set for 2ss */
  166. odm_set_bb_reg(p_dm_odm, 0x940, BIT(11) | BIT(10), 0);
  167. odm_set_bb_reg(p_dm_odm, 0x940, BIT(13) | BIT(12), 1);
  168. odm_set_bb_reg(p_dm_odm, 0x940, BIT(15) | BIT(14), 2);
  169. /* set for 3ss */
  170. odm_set_bb_reg(p_dm_odm, 0x940, BIT(23) | BIT(22), 0);
  171. odm_set_bb_reg(p_dm_odm, 0x940, BIT(25) | BIT(24), 1);
  172. odm_set_bb_reg(p_dm_odm, 0x940, BIT(27) | BIT(26), 2);
  173. }
  174. } else if (num_enable_path == 4)
  175. ODM_RT_TRACE(p_dm_odm, ODM_COMP_PATH_DIV, ODM_DBG_LOUD, (" Trun on path ((A B C D))\n"));
  176. }
  177. void
  178. phydm_find_default_path(
  179. void *p_dm_void
  180. )
  181. {
  182. struct PHY_DM_STRUCT *p_dm_odm = (struct PHY_DM_STRUCT *)p_dm_void;
  183. struct _ODM_PATH_DIVERSITY_ *p_dm_path_div = &p_dm_odm->dm_path_div;
  184. u32 rssi_avg_a = 0, rssi_avg_b = 0, rssi_avg_c = 0, rssi_avg_d = 0, rssi_avg_bcd = 0;
  185. u32 rssi_total_a = 0, rssi_total_b = 0, rssi_total_c = 0, rssi_total_d = 0;
  186. /* 2 Default path Selection By RSSI */
  187. rssi_avg_a = (p_dm_path_div->path_a_cnt_all > 0) ? (p_dm_path_div->path_a_sum_all / p_dm_path_div->path_a_cnt_all) : 0 ;
  188. rssi_avg_b = (p_dm_path_div->path_b_cnt_all > 0) ? (p_dm_path_div->path_b_sum_all / p_dm_path_div->path_b_cnt_all) : 0 ;
  189. rssi_avg_c = (p_dm_path_div->path_c_cnt_all > 0) ? (p_dm_path_div->path_c_sum_all / p_dm_path_div->path_c_cnt_all) : 0 ;
  190. rssi_avg_d = (p_dm_path_div->path_d_cnt_all > 0) ? (p_dm_path_div->path_d_sum_all / p_dm_path_div->path_d_cnt_all) : 0 ;
  191. p_dm_path_div->path_a_sum_all = 0;
  192. p_dm_path_div->path_a_cnt_all = 0;
  193. p_dm_path_div->path_b_sum_all = 0;
  194. p_dm_path_div->path_b_cnt_all = 0;
  195. p_dm_path_div->path_c_sum_all = 0;
  196. p_dm_path_div->path_c_cnt_all = 0;
  197. p_dm_path_div->path_d_sum_all = 0;
  198. p_dm_path_div->path_d_cnt_all = 0;
  199. if (p_dm_path_div->use_path_a_as_default_ant == 1) {
  200. rssi_avg_bcd = (rssi_avg_b + rssi_avg_c + rssi_avg_d) / 3;
  201. if ((rssi_avg_a + ANT_DECT_RSSI_TH) > rssi_avg_bcd) {
  202. p_dm_path_div->is_path_a_exist = true;
  203. p_dm_path_div->default_path = PATH_A;
  204. } else
  205. p_dm_path_div->is_path_a_exist = false;
  206. } else {
  207. if ((rssi_avg_a >= rssi_avg_b) && (rssi_avg_a >= rssi_avg_c) && (rssi_avg_a >= rssi_avg_d))
  208. p_dm_path_div->default_path = PATH_A;
  209. else if ((rssi_avg_b >= rssi_avg_c) && (rssi_avg_b >= rssi_avg_d))
  210. p_dm_path_div->default_path = PATH_B;
  211. else if (rssi_avg_c >= rssi_avg_d)
  212. p_dm_path_div->default_path = PATH_C;
  213. else
  214. p_dm_path_div->default_path = PATH_D;
  215. }
  216. }
  217. void
  218. phydm_candidate_dtp_update(
  219. void *p_dm_void
  220. )
  221. {
  222. struct PHY_DM_STRUCT *p_dm_odm = (struct PHY_DM_STRUCT *)p_dm_void;
  223. struct _ODM_PATH_DIVERSITY_ *p_dm_path_div = &p_dm_odm->dm_path_div;
  224. p_dm_path_div->num_candidate = 3;
  225. if (p_dm_path_div->use_path_a_as_default_ant == 1) {
  226. if (p_dm_path_div->num_tx_path == 3) {
  227. if (p_dm_path_div->is_path_a_exist) {
  228. p_dm_path_div->ant_candidate_1 = PHYDM_ABC;
  229. p_dm_path_div->ant_candidate_2 = PHYDM_ABD;
  230. p_dm_path_div->ant_candidate_3 = PHYDM_ACD;
  231. } else { /* use path BCD */
  232. p_dm_path_div->num_candidate = 1;
  233. phydm_dtp_fix_tx_path(p_dm_odm, PHYDM_BCD);
  234. return;
  235. }
  236. } else if (p_dm_path_div->num_tx_path == 2) {
  237. if (p_dm_path_div->is_path_a_exist) {
  238. p_dm_path_div->ant_candidate_1 = PHYDM_AB;
  239. p_dm_path_div->ant_candidate_2 = PHYDM_AC;
  240. p_dm_path_div->ant_candidate_3 = PHYDM_AD;
  241. } else {
  242. p_dm_path_div->ant_candidate_1 = PHYDM_BC;
  243. p_dm_path_div->ant_candidate_2 = PHYDM_BD;
  244. p_dm_path_div->ant_candidate_3 = PHYDM_CD;
  245. }
  246. }
  247. } else {
  248. /* 2 3 TX mode */
  249. if (p_dm_path_div->num_tx_path == 3) { /* choose 3 ant form 4 */
  250. if (p_dm_path_div->default_path == PATH_A) { /* choose 2 ant form 3 */
  251. p_dm_path_div->ant_candidate_1 = PHYDM_ABC;
  252. p_dm_path_div->ant_candidate_2 = PHYDM_ABD;
  253. p_dm_path_div->ant_candidate_3 = PHYDM_ACD;
  254. } else if (p_dm_path_div->default_path == PATH_B) {
  255. p_dm_path_div->ant_candidate_1 = PHYDM_ABC;
  256. p_dm_path_div->ant_candidate_2 = PHYDM_ABD;
  257. p_dm_path_div->ant_candidate_3 = PHYDM_BCD;
  258. } else if (p_dm_path_div->default_path == PATH_C) {
  259. p_dm_path_div->ant_candidate_1 = PHYDM_ABC;
  260. p_dm_path_div->ant_candidate_2 = PHYDM_ACD;
  261. p_dm_path_div->ant_candidate_3 = PHYDM_BCD;
  262. } else if (p_dm_path_div->default_path == PATH_D) {
  263. p_dm_path_div->ant_candidate_1 = PHYDM_ABD;
  264. p_dm_path_div->ant_candidate_2 = PHYDM_ACD;
  265. p_dm_path_div->ant_candidate_3 = PHYDM_BCD;
  266. }
  267. }
  268. /* 2 2 TX mode */
  269. else if (p_dm_path_div->num_tx_path == 2) { /* choose 2 ant form 4 */
  270. if (p_dm_path_div->default_path == PATH_A) { /* choose 2 ant form 3 */
  271. p_dm_path_div->ant_candidate_1 = PHYDM_AB;
  272. p_dm_path_div->ant_candidate_2 = PHYDM_AC;
  273. p_dm_path_div->ant_candidate_3 = PHYDM_AD;
  274. } else if (p_dm_path_div->default_path == PATH_B) {
  275. p_dm_path_div->ant_candidate_1 = PHYDM_AB;
  276. p_dm_path_div->ant_candidate_2 = PHYDM_BC;
  277. p_dm_path_div->ant_candidate_3 = PHYDM_BD;
  278. } else if (p_dm_path_div->default_path == PATH_C) {
  279. p_dm_path_div->ant_candidate_1 = PHYDM_AC;
  280. p_dm_path_div->ant_candidate_2 = PHYDM_BC;
  281. p_dm_path_div->ant_candidate_3 = PHYDM_CD;
  282. } else if (p_dm_path_div->default_path == PATH_D) {
  283. p_dm_path_div->ant_candidate_1 = PHYDM_AD;
  284. p_dm_path_div->ant_candidate_2 = PHYDM_BD;
  285. p_dm_path_div->ant_candidate_3 = PHYDM_CD;
  286. }
  287. }
  288. }
  289. }
  290. void
  291. phydm_dynamic_tx_path(
  292. void *p_dm_void
  293. )
  294. {
  295. struct PHY_DM_STRUCT *p_dm_odm = (struct PHY_DM_STRUCT *)p_dm_void;
  296. struct _ODM_PATH_DIVERSITY_ *p_dm_path_div = &p_dm_odm->dm_path_div;
  297. struct sta_info *p_entry;
  298. u32 i;
  299. u8 num_client = 0;
  300. u8 h2c_parameter[6] = {0};
  301. if (!p_dm_odm->is_linked) { /* is_linked==False */
  302. ODM_RT_TRACE(p_dm_odm, ODM_COMP_PATH_DIV, ODM_DBG_LOUD, ("DTP_8814 [No Link!!!]\n"));
  303. if (p_dm_path_div->is_become_linked == true) {
  304. ODM_RT_TRACE(p_dm_odm, ODM_COMP_PATH_DIV, ODM_DBG_LOUD, (" [Be disconnected]----->\n"));
  305. p_dm_path_div->is_become_linked = p_dm_odm->is_linked;
  306. }
  307. return;
  308. } else {
  309. if (p_dm_path_div->is_become_linked == false) {
  310. ODM_RT_TRACE(p_dm_odm, ODM_COMP_PATH_DIV, ODM_DBG_LOUD, (" [Be Linked !!!]----->\n"));
  311. p_dm_path_div->is_become_linked = p_dm_odm->is_linked;
  312. }
  313. }
  314. /* 2 [period CTRL] */
  315. if (p_dm_path_div->dtp_period >= 2)
  316. p_dm_path_div->dtp_period = 0;
  317. else {
  318. /* ODM_RT_TRACE(p_dm_odm,ODM_COMP_PATH_DIV, ODM_DBG_LOUD, ("Phydm_Dynamic_Tx_Path_8814A() Stay = (( %d ))\n",p_dm_path_div->dtp_period)); */
  319. p_dm_path_div->dtp_period++;
  320. return;
  321. }
  322. /* 2 [Fix path] */
  323. if (p_dm_odm->path_select != PHYDM_AUTO_PATH)
  324. return;
  325. /* 2 [Check Bfer] */
  326. #if (DM_ODM_SUPPORT_TYPE == ODM_WIN)
  327. #if (BEAMFORMING_SUPPORT == 1)
  328. {
  329. enum beamforming_cap beamform_cap = (p_dm_odm->beamforming_info.beamform_cap);
  330. if (beamform_cap & BEAMFORMER_CAP) { /* BFmer On && Div On->Div Off */
  331. if (p_dm_path_div->fix_path_bfer == 0) {
  332. ODM_RT_TRACE(p_dm_odm, ODM_COMP_PATH_DIV, ODM_DBG_LOUD, ("[ PathDiv : OFF ] BFmer ==1\n"));
  333. p_dm_path_div->fix_path_bfer = 1 ;
  334. }
  335. return;
  336. } else { /* BFmer Off && Div Off->Div On */
  337. if (p_dm_path_div->fix_path_bfer == 1) {
  338. ODM_RT_TRACE(p_dm_odm, ODM_COMP_PATH_DIV, ODM_DBG_LOUD, ("[ PathDiv : ON ] BFmer ==0\n"));
  339. p_dm_path_div->fix_path_bfer = 0;
  340. }
  341. }
  342. }
  343. #endif
  344. #endif
  345. if (p_dm_path_div->use_path_a_as_default_ant == 1) {
  346. phydm_find_default_path(p_dm_odm);
  347. phydm_candidate_dtp_update(p_dm_odm);
  348. } else {
  349. if (p_dm_path_div->phydm_dtp_state == PHYDM_DTP_INIT) {
  350. phydm_find_default_path(p_dm_odm);
  351. phydm_candidate_dtp_update(p_dm_odm);
  352. p_dm_path_div->phydm_dtp_state = PHYDM_DTP_RUNNING_1;
  353. }
  354. else if (p_dm_path_div->phydm_dtp_state == PHYDM_DTP_RUNNING_1) {
  355. p_dm_path_div->dtp_check_patha_counter++;
  356. if (p_dm_path_div->dtp_check_patha_counter >= NUM_RESET_DTP_PERIOD) {
  357. p_dm_path_div->dtp_check_patha_counter = 0;
  358. p_dm_path_div->phydm_dtp_state = PHYDM_DTP_INIT;
  359. }
  360. /* 2 Search space update */
  361. else {
  362. /* 1. find the worst candidate */
  363. /* 2. repalce the worst candidate */
  364. }
  365. }
  366. }
  367. /* 2 Dynamic path Selection H2C */
  368. if (p_dm_path_div->num_candidate == 1)
  369. return;
  370. else {
  371. h2c_parameter[0] = p_dm_path_div->num_candidate;
  372. h2c_parameter[1] = p_dm_path_div->num_tx_path;
  373. h2c_parameter[2] = p_dm_path_div->ant_candidate_1;
  374. h2c_parameter[3] = p_dm_path_div->ant_candidate_2;
  375. h2c_parameter[4] = p_dm_path_div->ant_candidate_3;
  376. odm_fill_h2c_cmd(p_dm_odm, PHYDM_H2C_DYNAMIC_TX_PATH, 6, h2c_parameter);
  377. }
  378. }
  379. void
  380. phydm_dynamic_tx_path_init(
  381. void *p_dm_void
  382. )
  383. {
  384. struct PHY_DM_STRUCT *p_dm_odm = (struct PHY_DM_STRUCT *)p_dm_void;
  385. struct _ODM_PATH_DIVERSITY_ *p_dm_path_div = &(p_dm_odm->dm_path_div);
  386. struct _ADAPTER *p_adapter = p_dm_odm->adapter;
  387. u8 search_space_2[NUM_CHOOSE2_FROM4] = {PHYDM_AB, PHYDM_AC, PHYDM_AD, PHYDM_BC, PHYDM_BD, PHYDM_CD };
  388. u8 search_space_3[NUM_CHOOSE3_FROM4] = {PHYDM_BCD, PHYDM_ACD, PHYDM_ABD, PHYDM_ABC};
  389. #if ((DM_ODM_SUPPORT_TYPE == ODM_WIN) && USB_SWITCH_SUPPORT)
  390. p_dm_path_div->is_u3_mode = (*p_dm_odm->hub_usb_mode == 2) ? 1 : 0 ;
  391. ODM_RT_TRACE(p_dm_odm, ODM_COMP_PATH_DIV, ODM_DBG_LOUD, ("[WIN USB] is_u3_mode = (( %d ))\n", p_dm_path_div->is_u3_mode));
  392. #else
  393. p_dm_path_div->is_u3_mode = 1;
  394. #endif
  395. ODM_RT_TRACE(p_dm_odm, ODM_COMP_PATH_DIV, ODM_DBG_LOUD, ("Dynamic TX path Init 8814\n"));
  396. memcpy(&(p_dm_path_div->search_space_2[0]), &(search_space_2[0]), NUM_CHOOSE2_FROM4);
  397. memcpy(&(p_dm_path_div->search_space_3[0]), &(search_space_3[0]), NUM_CHOOSE3_FROM4);
  398. p_dm_path_div->use_path_a_as_default_ant = 1;
  399. p_dm_path_div->phydm_dtp_state = PHYDM_DTP_INIT;
  400. p_dm_odm->path_select = PHYDM_AUTO_PATH;
  401. p_dm_path_div->phydm_path_div_type = PHYDM_4R_PATH_DIV;
  402. if (p_dm_path_div->is_u3_mode) {
  403. p_dm_path_div->num_tx_path = 3;
  404. phydm_dtp_fix_tx_path(p_dm_odm, PHYDM_BCD);/* 3TX Set Init TX path*/
  405. } else {
  406. p_dm_path_div->num_tx_path = 2;
  407. phydm_dtp_fix_tx_path(p_dm_odm, PHYDM_BC);/* 2TX // Set Init TX path*/
  408. }
  409. }
  410. void
  411. phydm_process_rssi_for_path_div(
  412. void *p_dm_void,
  413. void *p_phy_info_void,
  414. void *p_pkt_info_void
  415. )
  416. {
  417. struct PHY_DM_STRUCT *p_dm_odm = (struct PHY_DM_STRUCT *)p_dm_void;
  418. struct _odm_phy_status_info_ *p_phy_info = (struct _odm_phy_status_info_ *)p_phy_info_void;
  419. struct _odm_per_pkt_info_ *p_pktinfo = (struct _odm_per_pkt_info_ *)p_pkt_info_void;
  420. struct _ODM_PATH_DIVERSITY_ *p_dm_path_div = &(p_dm_odm->dm_path_div);
  421. if (p_pktinfo->is_packet_to_self || p_pktinfo->is_packet_match_bssid) {
  422. if (p_pktinfo->data_rate > ODM_RATE11M) {
  423. if (p_dm_path_div->phydm_path_div_type == PHYDM_4R_PATH_DIV) {
  424. #if RTL8814A_SUPPORT
  425. if (p_dm_odm->support_ic_type & ODM_RTL8814A) {
  426. p_dm_path_div->path_a_sum_all += p_phy_info->rx_mimo_signal_strength[0];
  427. p_dm_path_div->path_a_cnt_all++;
  428. p_dm_path_div->path_b_sum_all += p_phy_info->rx_mimo_signal_strength[1];
  429. p_dm_path_div->path_b_cnt_all++;
  430. p_dm_path_div->path_c_sum_all += p_phy_info->rx_mimo_signal_strength[2];
  431. p_dm_path_div->path_c_cnt_all++;
  432. p_dm_path_div->path_d_sum_all += p_phy_info->rx_mimo_signal_strength[3];
  433. p_dm_path_div->path_d_cnt_all++;
  434. }
  435. #endif
  436. } else {
  437. p_dm_path_div->path_a_sum[p_pktinfo->station_id] += p_phy_info->rx_mimo_signal_strength[0];
  438. p_dm_path_div->path_a_cnt[p_pktinfo->station_id]++;
  439. p_dm_path_div->path_b_sum[p_pktinfo->station_id] += p_phy_info->rx_mimo_signal_strength[1];
  440. p_dm_path_div->path_b_cnt[p_pktinfo->station_id]++;
  441. }
  442. }
  443. }
  444. }
  445. #endif /* #if RTL8814A_SUPPORT */
  446. void
  447. odm_pathdiv_debug(
  448. void *p_dm_void,
  449. u32 *const dm_value,
  450. u32 *_used,
  451. char *output,
  452. u32 *_out_len
  453. )
  454. {
  455. struct PHY_DM_STRUCT *p_dm_odm = (struct PHY_DM_STRUCT *)p_dm_void;
  456. struct _ODM_PATH_DIVERSITY_ *p_dm_path_div = &(p_dm_odm->dm_path_div);
  457. u32 used = *_used;
  458. u32 out_len = *_out_len;
  459. p_dm_odm->path_select = (dm_value[0] & 0xf);
  460. PHYDM_SNPRINTF((output + used, out_len - used, "Path_select = (( 0x%x ))\n", p_dm_odm->path_select));
  461. /* 2 [Fix path] */
  462. if (p_dm_odm->path_select != PHYDM_AUTO_PATH) {
  463. PHYDM_SNPRINTF((output + used, out_len - used, "Trun on path [%s%s%s%s]\n",
  464. ((p_dm_odm->path_select) & 0x1) ? "A" : "",
  465. ((p_dm_odm->path_select) & 0x2) ? "B" : "",
  466. ((p_dm_odm->path_select) & 0x4) ? "C" : "",
  467. ((p_dm_odm->path_select) & 0x8) ? "D" : ""));
  468. phydm_dtp_fix_tx_path(p_dm_odm, p_dm_odm->path_select);
  469. } else
  470. PHYDM_SNPRINTF((output + used, out_len - used, "%s\n", "Auto path"));
  471. }
  472. #endif /* #if(defined(CONFIG_PATH_DIVERSITY)) */
  473. void
  474. phydm_c2h_dtp_handler(
  475. void *p_dm_void,
  476. u8 *cmd_buf,
  477. u8 cmd_len
  478. )
  479. {
  480. #if (defined(CONFIG_PATH_DIVERSITY))
  481. struct PHY_DM_STRUCT *p_dm_odm = (struct PHY_DM_STRUCT *)p_dm_void;
  482. struct _ODM_PATH_DIVERSITY_ *p_dm_path_div = &(p_dm_odm->dm_path_div);
  483. u8 macid = cmd_buf[0];
  484. u8 target = cmd_buf[1];
  485. u8 nsc_1 = cmd_buf[2];
  486. u8 nsc_2 = cmd_buf[3];
  487. u8 nsc_3 = cmd_buf[4];
  488. ODM_RT_TRACE(p_dm_odm, ODM_COMP_PATH_DIV, ODM_DBG_LOUD, ("Target_candidate = (( %d ))\n", target));
  489. /*
  490. if( (nsc_1 >= nsc_2) && (nsc_1 >= nsc_3))
  491. {
  492. phydm_dtp_fix_tx_path(p_dm_odm, p_dm_path_div->ant_candidate_1);
  493. }
  494. else if( nsc_2 >= nsc_3)
  495. {
  496. phydm_dtp_fix_tx_path(p_dm_odm, p_dm_path_div->ant_candidate_2);
  497. }
  498. else
  499. {
  500. phydm_dtp_fix_tx_path(p_dm_odm, p_dm_path_div->ant_candidate_3);
  501. }
  502. */
  503. #endif
  504. }
  505. void
  506. odm_path_diversity(
  507. void *p_dm_void
  508. )
  509. {
  510. #if (defined(CONFIG_PATH_DIVERSITY))
  511. struct PHY_DM_STRUCT *p_dm_odm = (struct PHY_DM_STRUCT *)p_dm_void;
  512. if (!(p_dm_odm->support_ability & ODM_BB_PATH_DIV)) {
  513. ODM_RT_TRACE(p_dm_odm, ODM_COMP_PATH_DIV, ODM_DBG_LOUD, ("Return: Not Support PathDiv\n"));
  514. return;
  515. }
  516. #if RTL8812A_SUPPORT
  517. if (p_dm_odm->support_ic_type & ODM_RTL8812)
  518. odm_path_diversity_8812a(p_dm_odm);
  519. else
  520. #endif
  521. #if RTL8814A_SUPPORT
  522. if (p_dm_odm->support_ic_type & ODM_RTL8814A)
  523. phydm_dynamic_tx_path(p_dm_odm);
  524. else
  525. #endif
  526. {}
  527. #endif
  528. }
  529. void
  530. odm_path_diversity_init(
  531. void *p_dm_void
  532. )
  533. {
  534. #if (defined(CONFIG_PATH_DIVERSITY))
  535. struct PHY_DM_STRUCT *p_dm_odm = (struct PHY_DM_STRUCT *)p_dm_void;
  536. /*p_dm_odm->support_ability |= ODM_BB_PATH_DIV;*/
  537. if (p_dm_odm->mp_mode == true)
  538. return;
  539. if (!(p_dm_odm->support_ability & ODM_BB_PATH_DIV)) {
  540. ODM_RT_TRACE(p_dm_odm, ODM_COMP_PATH_DIV, ODM_DBG_LOUD, ("Return: Not Support PathDiv\n"));
  541. return;
  542. }
  543. #if RTL8812A_SUPPORT
  544. if (p_dm_odm->support_ic_type & ODM_RTL8812)
  545. odm_path_diversity_init_8812a(p_dm_odm);
  546. else
  547. #endif
  548. #if RTL8814A_SUPPORT
  549. if (p_dm_odm->support_ic_type & ODM_RTL8814A)
  550. phydm_dynamic_tx_path_init(p_dm_odm);
  551. else
  552. #endif
  553. {}
  554. #endif
  555. }
  556. #if (DM_ODM_SUPPORT_TYPE == ODM_WIN)
  557. /*
  558. * 2011/12/02 MH Copy from MP oursrc for temporarily test.
  559. * */
  560. void
  561. odm_path_div_chk_ant_switch_callback(
  562. struct timer_list *p_timer
  563. )
  564. {
  565. }
  566. void
  567. odm_path_div_chk_ant_switch_workitem_callback(
  568. void *p_context
  569. )
  570. {
  571. }
  572. void
  573. odm_cck_tx_path_diversity_callback(
  574. struct timer_list *p_timer
  575. )
  576. {
  577. }
  578. void
  579. odm_cck_tx_path_diversity_work_item_callback(
  580. void *p_context
  581. )
  582. {
  583. }
  584. u8
  585. odm_sw_ant_div_select_scan_chnl(
  586. struct _ADAPTER *adapter
  587. )
  588. {
  589. return 0;
  590. }
  591. void
  592. odm_sw_ant_div_construct_scan_chnl(
  593. struct _ADAPTER *adapter,
  594. u8 scan_chnl
  595. )
  596. {
  597. }
  598. #endif /* #if (DM_ODM_SUPPORT_TYPE == ODM_WIN) */