haltxbfjaguar.c 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526
  1. /* ************************************************************
  2. * Description:
  3. *
  4. * This file is for 8812/8821/8811 TXBF mechanism
  5. *
  6. * ************************************************************ */
  7. #include "mp_precomp.h"
  8. #include "../phydm_precomp.h"
  9. #if (BEAMFORMING_SUPPORT == 1)
  10. #if ((RTL8812A_SUPPORT == 1) || (RTL8821A_SUPPORT == 1))
  11. void
  12. hal_txbf_8812a_set_ndpa_rate(
  13. void *p_dm_void,
  14. u8 BW,
  15. u8 rate
  16. )
  17. {
  18. struct PHY_DM_STRUCT *p_dm_odm = (struct PHY_DM_STRUCT *)p_dm_void;
  19. odm_write_1byte(p_dm_odm, REG_NDPA_OPT_CTRL_8812A, (rate << 2 | BW));
  20. }
  21. void
  22. hal_txbf_jaguar_rf_mode(
  23. void *p_dm_void,
  24. struct _RT_BEAMFORMING_INFO *p_beam_info
  25. )
  26. {
  27. struct PHY_DM_STRUCT *p_dm_odm = (struct PHY_DM_STRUCT *)p_dm_void;
  28. if (p_dm_odm->rf_type == ODM_1T1R)
  29. return;
  30. ODM_RT_TRACE(p_dm_odm, PHYDM_COMP_TXBF, ODM_DBG_LOUD, ("[%s] set TxIQGen\n", __func__));
  31. odm_set_rf_reg(p_dm_odm, ODM_RF_PATH_A, 0xef, 0x80000, 0x1); /*RF mode table write enable*/
  32. odm_set_rf_reg(p_dm_odm, ODM_RF_PATH_B, 0xef, 0x80000, 0x1); /*RF mode table write enable*/
  33. if (p_beam_info->beamformee_su_cnt > 0) {
  34. /* Paath_A */
  35. odm_set_rf_reg(p_dm_odm, ODM_RF_PATH_A, 0x30, 0x78000, 0x3); /*Select RX mode*/
  36. odm_set_rf_reg(p_dm_odm, ODM_RF_PATH_A, 0x31, 0xfffff, 0x3F7FF); /*Set Table data*/
  37. odm_set_rf_reg(p_dm_odm, ODM_RF_PATH_A, 0x32, 0xfffff, 0xE26BF); /*Enable TXIQGEN in RX mode*/
  38. /* Path_B */
  39. odm_set_rf_reg(p_dm_odm, ODM_RF_PATH_B, 0x30, 0x78000, 0x3); /*Select RX mode*/
  40. odm_set_rf_reg(p_dm_odm, ODM_RF_PATH_B, 0x31, 0xfffff, 0x3F7FF); /*Set Table data*/
  41. odm_set_rf_reg(p_dm_odm, ODM_RF_PATH_B, 0x32, 0xfffff, 0xE26BF); /*Enable TXIQGEN in RX mode*/
  42. } else {
  43. /* Paath_A */
  44. odm_set_rf_reg(p_dm_odm, ODM_RF_PATH_A, 0x30, 0x78000, 0x3); /*Select RX mode*/
  45. odm_set_rf_reg(p_dm_odm, ODM_RF_PATH_A, 0x31, 0xfffff, 0x3F7FF); /*Set Table data*/
  46. odm_set_rf_reg(p_dm_odm, ODM_RF_PATH_A, 0x32, 0xfffff, 0xC26BF); /*Disable TXIQGEN in RX mode*/
  47. /* Path_B */
  48. odm_set_rf_reg(p_dm_odm, ODM_RF_PATH_B, 0x30, 0x78000, 0x3); /*Select RX mode*/
  49. odm_set_rf_reg(p_dm_odm, ODM_RF_PATH_B, 0x31, 0xfffff, 0x3F7FF); /*Set Table data*/
  50. odm_set_rf_reg(p_dm_odm, ODM_RF_PATH_B, 0x32, 0xfffff, 0xC26BF); /*Disable TXIQGEN in RX mode*/
  51. }
  52. odm_set_rf_reg(p_dm_odm, ODM_RF_PATH_A, 0xef, 0x80000, 0x0); /*RF mode table write disable*/
  53. odm_set_rf_reg(p_dm_odm, ODM_RF_PATH_B, 0xef, 0x80000, 0x0); /*RF mode table write disable*/
  54. if (p_beam_info->beamformee_su_cnt > 0)
  55. odm_set_bb_reg(p_dm_odm, 0x80c, MASKBYTE1, 0x33);
  56. else
  57. odm_set_bb_reg(p_dm_odm, 0x80c, MASKBYTE1, 0x11);
  58. }
  59. void
  60. hal_txbf_jaguar_download_ndpa(
  61. void *p_dm_void,
  62. u8 idx
  63. )
  64. {
  65. struct PHY_DM_STRUCT *p_dm_odm = (struct PHY_DM_STRUCT *)p_dm_void;
  66. u8 u1b_tmp = 0, tmp_reg422 = 0, head_page;
  67. u8 bcn_valid_reg = 0, count = 0, dl_bcn_count = 0;
  68. boolean is_send_beacon = false;
  69. u8 tx_page_bndy = LAST_ENTRY_OF_TX_PKT_BUFFER_8812; /*default reseved 1 page for the IC type which is undefined.*/
  70. struct _RT_BEAMFORMING_INFO *p_beam_info = &p_dm_odm->beamforming_info;
  71. struct _RT_BEAMFORMEE_ENTRY *p_beam_entry = p_beam_info->beamformee_entry + idx;
  72. struct _ADAPTER *adapter = p_dm_odm->adapter;
  73. #if (DM_ODM_SUPPORT_TYPE == ODM_WIN)
  74. *p_dm_odm->p_is_fw_dw_rsvd_page_in_progress = true;
  75. #endif
  76. ODM_RT_TRACE(p_dm_odm, PHYDM_COMP_TXBF, ODM_DBG_LOUD, ("[%s] Start!\n", __func__));
  77. if (idx == 0)
  78. head_page = 0xFE;
  79. else
  80. head_page = 0xFE;
  81. phydm_get_hal_def_var_handler_interface(p_dm_odm, HAL_DEF_TX_PAGE_BOUNDARY, (u8 *)&tx_page_bndy);
  82. /*Set REG_CR bit 8. DMA beacon by SW.*/
  83. u1b_tmp = odm_read_1byte(p_dm_odm, REG_CR_8812A + 1);
  84. odm_write_1byte(p_dm_odm, REG_CR_8812A + 1, (u1b_tmp | BIT(0)));
  85. /*Set FWHW_TXQ_CTRL 0x422[6]=0 to tell Hw the packet is not a real beacon frame.*/
  86. tmp_reg422 = odm_read_1byte(p_dm_odm, REG_FWHW_TXQ_CTRL_8812A + 2);
  87. odm_write_1byte(p_dm_odm, REG_FWHW_TXQ_CTRL_8812A + 2, tmp_reg422 & (~BIT(6)));
  88. if (tmp_reg422 & BIT(6)) {
  89. ODM_RT_TRACE(p_dm_odm, PHYDM_COMP_TXBF, ODM_DBG_LOUD, ("SetBeamformDownloadNDPA_8812(): There is an adapter is sending beacon.\n"));
  90. is_send_beacon = true;
  91. }
  92. /*TDECTRL[15:8] 0x209[7:0] = 0xF6 Beacon Head for TXDMA*/
  93. odm_write_1byte(p_dm_odm, REG_TDECTRL_8812A + 1, head_page);
  94. do {
  95. /*Clear beacon valid check bit.*/
  96. bcn_valid_reg = odm_read_1byte(p_dm_odm, REG_TDECTRL_8812A + 2);
  97. odm_write_1byte(p_dm_odm, REG_TDECTRL_8812A + 2, (bcn_valid_reg | BIT(0)));
  98. /*download NDPA rsvd page.*/
  99. if (p_beam_entry->beamform_entry_cap & BEAMFORMER_CAP_VHT_SU)
  100. beamforming_send_vht_ndpa_packet(p_dm_odm, p_beam_entry->mac_addr, p_beam_entry->aid, p_beam_entry->sound_bw, BEACON_QUEUE);
  101. else
  102. beamforming_send_ht_ndpa_packet(p_dm_odm, p_beam_entry->mac_addr, p_beam_entry->sound_bw, BEACON_QUEUE);
  103. /*check rsvd page download OK.*/
  104. bcn_valid_reg = odm_read_1byte(p_dm_odm, REG_TDECTRL_8812A + 2);
  105. count = 0;
  106. while (!(bcn_valid_reg & BIT(0)) && count < 20) {
  107. count++;
  108. ODM_delay_ms(10);
  109. bcn_valid_reg = odm_read_1byte(p_dm_odm, REG_TDECTRL_8812A + 2);
  110. }
  111. dl_bcn_count++;
  112. } while (!(bcn_valid_reg & BIT(0)) && dl_bcn_count < 5);
  113. if (!(bcn_valid_reg & BIT(0)))
  114. ODM_RT_TRACE(p_dm_odm, PHYDM_COMP_TXBF, ODM_DBG_LOUD, ("%s Download RSVD page failed!\n", __func__));
  115. /*TDECTRL[15:8] 0x209[7:0] = 0xF6 Beacon Head for TXDMA*/
  116. odm_write_1byte(p_dm_odm, REG_TDECTRL_8812A + 1, tx_page_bndy);
  117. /*To make sure that if there exists an adapter which would like to send beacon.*/
  118. /*If exists, the origianl value of 0x422[6] will be 1, we should check this to*/
  119. /*prevent from setting 0x422[6] to 0 after download reserved page, or it will cause*/
  120. /*the beacon cannot be sent by HW.*/
  121. /*2010.06.23. Added by tynli.*/
  122. if (is_send_beacon)
  123. odm_write_1byte(p_dm_odm, REG_FWHW_TXQ_CTRL_8812A + 2, tmp_reg422);
  124. /*Do not enable HW DMA BCN or it will cause Pcie interface hang by timing issue. 2011.11.24. by tynli.*/
  125. /*Clear CR[8] or beacon packet will not be send to TxBuf anymore.*/
  126. u1b_tmp = odm_read_1byte(p_dm_odm, REG_CR_8812A + 1);
  127. odm_write_1byte(p_dm_odm, REG_CR_8812A + 1, (u1b_tmp & (~BIT(0))));
  128. p_beam_entry->beamform_entry_state = BEAMFORMING_ENTRY_STATE_PROGRESSED;
  129. #if (DM_ODM_SUPPORT_TYPE == ODM_WIN)
  130. *p_dm_odm->p_is_fw_dw_rsvd_page_in_progress = false;
  131. #endif
  132. }
  133. void
  134. hal_txbf_jaguar_fw_txbf_cmd(
  135. void *p_dm_void
  136. )
  137. {
  138. struct PHY_DM_STRUCT *p_dm_odm = (struct PHY_DM_STRUCT *)p_dm_void;
  139. u8 idx, period0 = 0, period1 = 0;
  140. u8 PageNum0 = 0xFF, PageNum1 = 0xFF;
  141. u8 u1_tx_bf_parm[3] = {0};
  142. struct _RT_BEAMFORMING_INFO *p_beam_info = &p_dm_odm->beamforming_info;
  143. for (idx = 0; idx < BEAMFORMEE_ENTRY_NUM; idx++) {
  144. /*Modified by David*/
  145. if (p_beam_info->beamformee_entry[idx].is_used && p_beam_info->beamformee_entry[idx].beamform_entry_state == BEAMFORMING_ENTRY_STATE_PROGRESSED) {
  146. if (idx == 0) {
  147. if (p_beam_info->beamformee_entry[idx].is_sound)
  148. PageNum0 = 0xFE;
  149. else
  150. PageNum0 = 0xFF; /*stop sounding*/
  151. period0 = (u8)(p_beam_info->beamformee_entry[idx].sound_period);
  152. } else if (idx == 1) {
  153. if (p_beam_info->beamformee_entry[idx].is_sound)
  154. PageNum1 = 0xFE;
  155. else
  156. PageNum1 = 0xFF; /*stop sounding*/
  157. period1 = (u8)(p_beam_info->beamformee_entry[idx].sound_period);
  158. }
  159. }
  160. }
  161. u1_tx_bf_parm[0] = PageNum0;
  162. u1_tx_bf_parm[1] = PageNum1;
  163. u1_tx_bf_parm[2] = (period1 << 4) | period0;
  164. odm_fill_h2c_cmd(p_dm_odm, PHYDM_H2C_TXBF, 3, u1_tx_bf_parm);
  165. ODM_RT_TRACE(p_dm_odm, PHYDM_COMP_TXBF, ODM_DBG_LOUD,
  166. ("[%s] PageNum0 = %d period0 = %d, PageNum1 = %d period1 %d\n", __func__, PageNum0, period0, PageNum1, period1));
  167. }
  168. void
  169. hal_txbf_jaguar_enter(
  170. void *p_dm_void,
  171. u8 bfer_bfee_idx
  172. )
  173. {
  174. struct PHY_DM_STRUCT *p_dm_odm = (struct PHY_DM_STRUCT *)p_dm_void;
  175. u8 i = 0;
  176. u8 bfer_idx = (bfer_bfee_idx & 0xF0) >> 4;
  177. u8 bfee_idx = (bfer_bfee_idx & 0xF);
  178. u32 csi_param;
  179. struct _RT_BEAMFORMING_INFO *p_beamforming_info = &p_dm_odm->beamforming_info;
  180. struct _RT_BEAMFORMEE_ENTRY beamformee_entry;
  181. struct _RT_BEAMFORMER_ENTRY beamformer_entry;
  182. u16 sta_id = 0;
  183. ODM_RT_TRACE(p_dm_odm, PHYDM_COMP_TXBF, ODM_DBG_LOUD, ("[%s]Start!\n", __func__));
  184. hal_txbf_jaguar_rf_mode(p_dm_odm, p_beamforming_info);
  185. if (p_dm_odm->rf_type == ODM_2T2R)
  186. odm_set_bb_reg(p_dm_odm, ODM_REG_CSI_CONTENT_VALUE, MASKDWORD, 0x00000000); /*nc =2*/
  187. else
  188. odm_set_bb_reg(p_dm_odm, ODM_REG_CSI_CONTENT_VALUE, MASKDWORD, 0x01081008); /*nc =1*/
  189. if ((p_beamforming_info->beamformer_su_cnt > 0) && (bfer_idx < BEAMFORMER_ENTRY_NUM)) {
  190. beamformer_entry = p_beamforming_info->beamformer_entry[bfer_idx];
  191. /*Sounding protocol control*/
  192. odm_write_1byte(p_dm_odm, REG_SND_PTCL_CTRL_8812A, 0xCB);
  193. /*MAC address/Partial AID of Beamformer*/
  194. if (bfer_idx == 0) {
  195. for (i = 0; i < 6 ; i++)
  196. odm_write_1byte(p_dm_odm, (REG_BFMER0_INFO_8812A + i), beamformer_entry.mac_addr[i]);
  197. /*CSI report use legacy ofdm so don't need to fill P_AID. */
  198. /*platform_efio_write_2byte(adapter, REG_BFMER0_INFO_8812A+6, beamform_entry.P_AID); */
  199. } else {
  200. for (i = 0; i < 6 ; i++)
  201. odm_write_1byte(p_dm_odm, (REG_BFMER1_INFO_8812A + i), beamformer_entry.mac_addr[i]);
  202. /*CSI report use legacy ofdm so don't need to fill P_AID.*/
  203. /*platform_efio_write_2byte(adapter, REG_BFMER1_INFO_8812A+6, beamform_entry.P_AID);*/
  204. }
  205. /*CSI report parameters of Beamformee*/
  206. if (beamformer_entry.beamform_entry_cap & BEAMFORMEE_CAP_VHT_SU) {
  207. if (p_dm_odm->rf_type == ODM_2T2R)
  208. csi_param = 0x01090109;
  209. else
  210. csi_param = 0x01080108;
  211. } else {
  212. if (p_dm_odm->rf_type == ODM_2T2R)
  213. csi_param = 0x03090309;
  214. else
  215. csi_param = 0x03080308;
  216. }
  217. odm_write_4byte(p_dm_odm, REG_CSI_RPT_PARAM_BW20_8812A, csi_param);
  218. odm_write_4byte(p_dm_odm, REG_CSI_RPT_PARAM_BW40_8812A, csi_param);
  219. odm_write_4byte(p_dm_odm, REG_CSI_RPT_PARAM_BW80_8812A, csi_param);
  220. /*Timeout value for MAC to leave NDP_RX_standby_state (60 us, Test chip) (80 us, MP chip)*/
  221. odm_write_1byte(p_dm_odm, REG_SND_PTCL_CTRL_8812A + 3, 0x50);
  222. }
  223. if ((p_beamforming_info->beamformee_su_cnt > 0) && (bfee_idx < BEAMFORMEE_ENTRY_NUM)) {
  224. beamformee_entry = p_beamforming_info->beamformee_entry[bfee_idx];
  225. if (phydm_acting_determine(p_dm_odm, phydm_acting_as_ibss))
  226. sta_id = beamformee_entry.mac_id;
  227. else
  228. sta_id = beamformee_entry.p_aid;
  229. /*P_AID of Beamformee & enable NDPA transmission & enable NDPA interrupt*/
  230. if (bfee_idx == 0) {
  231. odm_write_2byte(p_dm_odm, REG_TXBF_CTRL_8812A, sta_id);
  232. odm_write_1byte(p_dm_odm, REG_TXBF_CTRL_8812A + 3, odm_read_1byte(p_dm_odm, REG_TXBF_CTRL_8812A + 3) | BIT(4) | BIT(6) | BIT(7));
  233. } else
  234. odm_write_2byte(p_dm_odm, REG_TXBF_CTRL_8812A + 2, sta_id | BIT(12) | BIT(14) | BIT(15));
  235. /*CSI report parameters of Beamformee*/
  236. if (bfee_idx == 0) {
  237. /*Get BIT24 & BIT25*/
  238. u8 tmp = odm_read_1byte(p_dm_odm, REG_BFMEE_SEL_8812A + 3) & 0x3;
  239. odm_write_1byte(p_dm_odm, REG_BFMEE_SEL_8812A + 3, tmp | 0x60);
  240. odm_write_2byte(p_dm_odm, REG_BFMEE_SEL_8812A, sta_id | BIT(9));
  241. } else {
  242. /*Set BIT25*/
  243. odm_write_2byte(p_dm_odm, REG_BFMEE_SEL_8812A + 2, sta_id | 0xE200);
  244. }
  245. phydm_beamforming_notify(p_dm_odm);
  246. }
  247. }
  248. void
  249. hal_txbf_jaguar_leave(
  250. void *p_dm_void,
  251. u8 idx
  252. )
  253. {
  254. struct PHY_DM_STRUCT *p_dm_odm = (struct PHY_DM_STRUCT *)p_dm_void;
  255. struct _RT_BEAMFORMING_INFO *p_beamforming_info = &p_dm_odm->beamforming_info;
  256. struct _RT_BEAMFORMER_ENTRY beamformer_entry;
  257. struct _RT_BEAMFORMEE_ENTRY beamformee_entry;
  258. if (idx < BEAMFORMER_ENTRY_NUM) {
  259. beamformer_entry = p_beamforming_info->beamformer_entry[idx];
  260. beamformee_entry = p_beamforming_info->beamformee_entry[idx];
  261. } else
  262. return;
  263. ODM_RT_TRACE(p_dm_odm, PHYDM_COMP_TXBF, ODM_DBG_LOUD, ("[%s]Start!, IDx = %d\n", __func__, idx));
  264. /*Clear P_AID of Beamformee*/
  265. /*Clear MAC address of Beamformer*/
  266. /*Clear Associated Bfmee Sel*/
  267. if (beamformer_entry.beamform_entry_cap == BEAMFORMING_CAP_NONE) {
  268. odm_write_1byte(p_dm_odm, REG_SND_PTCL_CTRL_8812A, 0xC8);
  269. if (idx == 0) {
  270. odm_write_4byte(p_dm_odm, REG_BFMER0_INFO_8812A, 0);
  271. odm_write_2byte(p_dm_odm, REG_BFMER0_INFO_8812A + 4, 0);
  272. odm_write_2byte(p_dm_odm, REG_CSI_RPT_PARAM_BW20_8812A, 0);
  273. odm_write_2byte(p_dm_odm, REG_CSI_RPT_PARAM_BW40_8812A, 0);
  274. odm_write_2byte(p_dm_odm, REG_CSI_RPT_PARAM_BW80_8812A, 0);
  275. } else {
  276. odm_write_4byte(p_dm_odm, REG_BFMER1_INFO_8812A, 0);
  277. odm_write_2byte(p_dm_odm, REG_BFMER1_INFO_8812A + 4, 0);
  278. odm_write_2byte(p_dm_odm, REG_CSI_RPT_PARAM_BW20_8812A, 0);
  279. odm_write_2byte(p_dm_odm, REG_CSI_RPT_PARAM_BW40_8812A, 0);
  280. odm_write_2byte(p_dm_odm, REG_CSI_RPT_PARAM_BW80_8812A, 0);
  281. }
  282. }
  283. if (beamformee_entry.beamform_entry_cap == BEAMFORMING_CAP_NONE) {
  284. hal_txbf_jaguar_rf_mode(p_dm_odm, p_beamforming_info);
  285. if (idx == 0) {
  286. odm_write_2byte(p_dm_odm, REG_TXBF_CTRL_8812A, 0x0);
  287. odm_write_2byte(p_dm_odm, REG_BFMEE_SEL_8812A, 0);
  288. } else {
  289. odm_write_2byte(p_dm_odm, REG_TXBF_CTRL_8812A + 2, odm_read_2byte(p_dm_odm, REG_TXBF_CTRL_8812A + 2) & 0xF000);
  290. odm_write_2byte(p_dm_odm, REG_BFMEE_SEL_8812A + 2, odm_read_2byte(p_dm_odm, REG_BFMEE_SEL_8812A + 2) & 0x60);
  291. }
  292. }
  293. }
  294. void
  295. hal_txbf_jaguar_status(
  296. void *p_dm_void,
  297. u8 idx
  298. )
  299. {
  300. struct PHY_DM_STRUCT *p_dm_odm = (struct PHY_DM_STRUCT *)p_dm_void;
  301. u16 beam_ctrl_val;
  302. u32 beam_ctrl_reg;
  303. struct _RT_BEAMFORMING_INFO *p_beam_info = &p_dm_odm->beamforming_info;
  304. struct _RT_BEAMFORMEE_ENTRY beamform_entry = p_beam_info->beamformee_entry[idx];
  305. if (phydm_acting_determine(p_dm_odm, phydm_acting_as_ibss))
  306. beam_ctrl_val = beamform_entry.mac_id;
  307. else
  308. beam_ctrl_val = beamform_entry.p_aid;
  309. if (idx == 0)
  310. beam_ctrl_reg = REG_TXBF_CTRL_8812A;
  311. else {
  312. beam_ctrl_reg = REG_TXBF_CTRL_8812A + 2;
  313. beam_ctrl_val |= BIT(12) | BIT(14) | BIT(15);
  314. }
  315. if ((beamform_entry.beamform_entry_state == BEAMFORMING_ENTRY_STATE_PROGRESSED) && (p_beam_info->apply_v_matrix == true)) {
  316. if (beamform_entry.sound_bw == CHANNEL_WIDTH_20)
  317. beam_ctrl_val |= BIT(9);
  318. else if (beamform_entry.sound_bw == CHANNEL_WIDTH_40)
  319. beam_ctrl_val |= (BIT(9) | BIT(10));
  320. else if (beamform_entry.sound_bw == CHANNEL_WIDTH_80)
  321. beam_ctrl_val |= (BIT(9) | BIT(10) | BIT(11));
  322. } else
  323. beam_ctrl_val &= ~(BIT(9) | BIT(10) | BIT(11));
  324. ODM_RT_TRACE(p_dm_odm, PHYDM_COMP_TXBF, ODM_DBG_LOUD, ("[%s] beam_ctrl_val = 0x%x!\n", __func__, beam_ctrl_val));
  325. odm_write_2byte(p_dm_odm, beam_ctrl_reg, beam_ctrl_val);
  326. }
  327. void
  328. hal_txbf_jaguar_fw_txbf(
  329. void *p_dm_void,
  330. u8 idx
  331. )
  332. {
  333. struct PHY_DM_STRUCT *p_dm_odm = (struct PHY_DM_STRUCT *)p_dm_void;
  334. struct _RT_BEAMFORMING_INFO *p_beam_info = &p_dm_odm->beamforming_info;
  335. struct _RT_BEAMFORMEE_ENTRY *p_beam_entry = p_beam_info->beamformee_entry + idx;
  336. ODM_RT_TRACE(p_dm_odm, PHYDM_COMP_TXBF, ODM_DBG_LOUD, ("[%s] Start!\n", __func__));
  337. if (p_beam_entry->beamform_entry_state == BEAMFORMING_ENTRY_STATE_PROGRESSING)
  338. hal_txbf_jaguar_download_ndpa(p_dm_odm, idx);
  339. hal_txbf_jaguar_fw_txbf_cmd(p_dm_odm);
  340. }
  341. void
  342. hal_txbf_jaguar_patch(
  343. void *p_dm_void,
  344. u8 operation
  345. )
  346. {
  347. struct PHY_DM_STRUCT *p_dm_odm = (struct PHY_DM_STRUCT *)p_dm_void;
  348. struct _RT_BEAMFORMING_INFO *p_beam_info = &p_dm_odm->beamforming_info;
  349. ODM_RT_TRACE(p_dm_odm, PHYDM_COMP_TXBF, ODM_DBG_LOUD, ("[%s] Start!\n", __func__));
  350. if (p_beam_info->beamform_cap == BEAMFORMING_CAP_NONE)
  351. return;
  352. #if (DM_ODM_SUPPORT_TYPE == ODM_WIN)
  353. if (operation == SCAN_OPT_BACKUP_BAND0)
  354. odm_write_1byte(p_dm_odm, REG_SND_PTCL_CTRL_8812A, 0xC8);
  355. else if (operation == SCAN_OPT_RESTORE)
  356. odm_write_1byte(p_dm_odm, REG_SND_PTCL_CTRL_8812A, 0xCB);
  357. #endif
  358. }
  359. void
  360. hal_txbf_jaguar_clk_8812a(
  361. void *p_dm_void
  362. )
  363. {
  364. struct PHY_DM_STRUCT *p_dm_odm = (struct PHY_DM_STRUCT *)p_dm_void;
  365. u16 u2btmp;
  366. u8 count = 0, u1btmp;
  367. struct _ADAPTER *adapter = p_dm_odm->adapter;
  368. ODM_RT_TRACE(p_dm_odm, PHYDM_COMP_TXBF, ODM_DBG_LOUD, ("[%s] Start!\n", __func__));
  369. if (*(p_dm_odm->p_is_scan_in_process)) {
  370. ODM_RT_TRACE(p_dm_odm, PHYDM_COMP_TXBF, ODM_DBG_LOUD, ("[%s] return by Scan\n", __func__));
  371. return;
  372. }
  373. #if DEV_BUS_TYPE == RT_PCI_INTERFACE
  374. /*Stop PCIe TxDMA*/
  375. odm_write_1byte(p_dm_odm, REG_PCIE_CTRL_REG_8812A + 1, 0xFE);
  376. #endif
  377. /*Stop Usb TxDMA*/
  378. #if (DM_ODM_SUPPORT_TYPE == ODM_WIN)
  379. RT_DISABLE_FUNC(adapter, DF_TX_BIT);
  380. PlatformReturnAllPendingTxPackets(adapter);
  381. #else
  382. rtw_write_port_cancel(adapter);
  383. #endif
  384. /*Wait TXFF empty*/
  385. for (count = 0; count < 100; count++) {
  386. u2btmp = odm_read_2byte(p_dm_odm, REG_TXPKT_EMPTY_8812A);
  387. u2btmp = u2btmp & 0xfff;
  388. if (u2btmp != 0xfff) {
  389. ODM_delay_ms(10);
  390. continue;
  391. } else
  392. break;
  393. }
  394. /*TX pause*/
  395. odm_write_1byte(p_dm_odm, REG_TXPAUSE_8812A, 0xFF);
  396. /*Wait TX state Machine OK*/
  397. for (count = 0; count < 100; count++) {
  398. if (odm_read_4byte(p_dm_odm, REG_SCH_TXCMD_8812A) != 0)
  399. continue;
  400. else
  401. break;
  402. }
  403. /*Stop RX DMA path*/
  404. u1btmp = odm_read_1byte(p_dm_odm, REG_RXDMA_CONTROL_8812A);
  405. odm_write_1byte(p_dm_odm, REG_RXDMA_CONTROL_8812A, u1btmp | BIT(2));
  406. for (count = 0; count < 100; count++) {
  407. u1btmp = odm_read_1byte(p_dm_odm, REG_RXDMA_CONTROL_8812A);
  408. if (u1btmp & BIT(1))
  409. break;
  410. else
  411. ODM_delay_ms(10);
  412. }
  413. /*Disable clock*/
  414. odm_write_1byte(p_dm_odm, REG_SYS_CLKR_8812A + 1, 0xf0);
  415. /*Disable 320M*/
  416. odm_write_1byte(p_dm_odm, REG_AFE_PLL_CTRL_8812A + 3, 0x8);
  417. /*Enable 320M*/
  418. odm_write_1byte(p_dm_odm, REG_AFE_PLL_CTRL_8812A + 3, 0xa);
  419. /*Enable clock*/
  420. odm_write_1byte(p_dm_odm, REG_SYS_CLKR_8812A + 1, 0xfc);
  421. /*Release Tx pause*/
  422. odm_write_1byte(p_dm_odm, REG_TXPAUSE_8812A, 0);
  423. /*Enable RX DMA path*/
  424. u1btmp = odm_read_1byte(p_dm_odm, REG_RXDMA_CONTROL_8812A);
  425. odm_write_1byte(p_dm_odm, REG_RXDMA_CONTROL_8812A, u1btmp & (~BIT(2)));
  426. #if DEV_BUS_TYPE == RT_PCI_INTERFACE
  427. /*Enable PCIe TxDMA*/
  428. odm_write_1byte(p_dm_odm, REG_PCIE_CTRL_REG_8812A + 1, 0);
  429. #endif
  430. /*Start Usb TxDMA*/
  431. RT_ENABLE_FUNC(adapter, DF_TX_BIT);
  432. }
  433. #endif
  434. #endif