haltxbf8822b.c 39 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100
  1. /*============================================================*/
  2. /* Description: */
  3. /* */
  4. /* This file is for 8814A TXBF mechanism */
  5. /* */
  6. /*============================================================*/
  7. #include "mp_precomp.h"
  8. #include "phydm_precomp.h"
  9. #if (RTL8822B_SUPPORT == 1)
  10. #if (BEAMFORMING_SUPPORT == 1)
  11. u8
  12. hal_txbf_8822b_get_ntx(
  13. void *p_dm_void
  14. )
  15. {
  16. struct PHY_DM_STRUCT *p_dm_odm = (struct PHY_DM_STRUCT *)p_dm_void;
  17. u8 ntx = 0;
  18. #if DEV_BUS_TYPE == RT_USB_INTERFACE
  19. if (p_dm_odm->support_interface == ODM_ITRF_USB) {
  20. if (*p_dm_odm->hub_usb_mode == 2) {/*USB3.0*/
  21. if (p_dm_odm->rf_type == ODM_4T4R)
  22. ntx = 3;
  23. else if (p_dm_odm->rf_type == ODM_3T3R)
  24. ntx = 2;
  25. else
  26. ntx = 1;
  27. } else if (*p_dm_odm->hub_usb_mode == 1) /*USB 2.0 always 2Tx*/
  28. ntx = 1;
  29. else
  30. ntx = 1;
  31. } else
  32. #endif
  33. {
  34. if (p_dm_odm->rf_type == ODM_4T4R)
  35. ntx = 3;
  36. else if (p_dm_odm->rf_type == ODM_3T3R)
  37. ntx = 2;
  38. else
  39. ntx = 1;
  40. }
  41. return ntx;
  42. }
  43. u8
  44. hal_txbf_8822b_get_nrx(
  45. void *p_dm_void
  46. )
  47. {
  48. struct PHY_DM_STRUCT *p_dm_odm = (struct PHY_DM_STRUCT *)p_dm_void;
  49. u8 nrx = 0;
  50. if (p_dm_odm->rf_type == ODM_4T4R)
  51. nrx = 3;
  52. else if (p_dm_odm->rf_type == ODM_3T3R)
  53. nrx = 2;
  54. else if (p_dm_odm->rf_type == ODM_2T2R)
  55. nrx = 1;
  56. else if (p_dm_odm->rf_type == ODM_2T3R)
  57. nrx = 2;
  58. else if (p_dm_odm->rf_type == ODM_2T4R)
  59. nrx = 3;
  60. else if (p_dm_odm->rf_type == ODM_1T1R)
  61. nrx = 0;
  62. else if (p_dm_odm->rf_type == ODM_1T2R)
  63. nrx = 1;
  64. else
  65. nrx = 0;
  66. return nrx;
  67. }
  68. /***************SU & MU BFee Entry********************/
  69. void
  70. hal_txbf_8822b_rf_mode(
  71. void *p_dm_void,
  72. struct _RT_BEAMFORMING_INFO *p_beamforming_info,
  73. u8 idx
  74. )
  75. {
  76. #if 0
  77. struct PHY_DM_STRUCT *p_dm_odm = (struct PHY_DM_STRUCT *)p_dm_void;
  78. u8 i, nr_index = 0;
  79. boolean is_self_beamformer = false;
  80. boolean is_self_beamformee = false;
  81. struct _RT_BEAMFORMEE_ENTRY beamformee_entry;
  82. if (idx < BEAMFORMEE_ENTRY_NUM)
  83. beamformee_entry = p_beamforming_info->beamformee_entry[idx];
  84. else
  85. return;
  86. if (p_dm_odm->rf_type == ODM_1T1R)
  87. return;
  88. for (i = ODM_RF_PATH_A; i < ODM_RF_PATH_B; i++) {
  89. odm_set_rf_reg(p_dm_odm, (enum odm_rf_radio_path_e)i, rf_welut_jaguar, 0x80000, 0x1);
  90. /*RF mode table write enable*/
  91. }
  92. if ((p_beamforming_info->beamformee_su_cnt > 0) || (p_beamforming_info->beamformee_mu_cnt > 0)) {
  93. for (i = ODM_RF_PATH_A; i < ODM_RF_PATH_B; i++) {
  94. odm_set_rf_reg(p_dm_odm, (enum odm_rf_radio_path_e)i, rf_mode_table_addr, 0xfffff, 0x18000);
  95. /*Select RX mode*/
  96. odm_set_rf_reg(p_dm_odm, (enum odm_rf_radio_path_e)i, rf_mode_table_data0, 0xfffff, 0xBE77F);
  97. /*Set Table data*/
  98. odm_set_rf_reg(p_dm_odm, (enum odm_rf_radio_path_e)i, rf_mode_table_data1, 0xfffff, 0x226BF);
  99. /*Enable TXIQGEN in RX mode*/
  100. }
  101. odm_set_rf_reg(p_dm_odm, ODM_RF_PATH_A, rf_mode_table_data1, 0xfffff, 0xE26BF);
  102. /*Enable TXIQGEN in RX mode*/
  103. }
  104. for (i = ODM_RF_PATH_A; i < ODM_RF_PATH_B; i++) {
  105. odm_set_rf_reg(p_dm_odm, (enum odm_rf_radio_path_e)i, rf_welut_jaguar, 0x80000, 0x0);
  106. /*RF mode table write disable*/
  107. }
  108. if (p_beamforming_info->beamformee_su_cnt > 0) {
  109. /*for 8814 19ac(idx 1), 19b4(idx 0), different Tx ant setting*/
  110. odm_set_bb_reg(p_dm_odm, REG_BB_TXBF_ANT_SET_BF1_8822B, BIT(28) | BIT29, 0x2); /*enable BB TxBF ant mapping register*/
  111. if (idx == 0) {
  112. /*Nsts = 2 AB*/
  113. odm_set_bb_reg(p_dm_odm, REG_BB_TXBF_ANT_SET_BF0_8822B, 0xffff, 0x0433);
  114. odm_set_bb_reg(p_dm_odm, REG_BB_TX_PATH_SEL_1_8822B, 0xfff00000, 0x043);
  115. /*odm_set_bb_reg(p_dm_odm, REG_BB_TX_PATH_SEL_2, MASKLWORD, 0x430);*/
  116. } else {/*IDX =1*/
  117. odm_set_bb_reg(p_dm_odm, REG_BB_TXBF_ANT_SET_BF1_8822B, 0xffff, 0x0433);
  118. odm_set_bb_reg(p_dm_odm, REG_BB_TX_PATH_SEL_1_8822B, 0xfff00000, 0x043);
  119. /*odm_set_bb_reg(p_dm_odm, REG_BB_TX_PATH_SEL_2, MASKLWORD, 0x430;*/
  120. }
  121. } else {
  122. odm_set_bb_reg(p_dm_odm, REG_BB_TX_PATH_SEL_1_8822B, 0xfff00000, 0x1); /*1SS by path-A*/
  123. odm_set_bb_reg(p_dm_odm, REG_BB_TX_PATH_SEL_2_8822B, MASKLWORD, 0x430); /*2SS by path-A,B*/
  124. }
  125. if (p_beamforming_info->beamformee_mu_cnt > 0) {
  126. /*MU STAs share the common setting*/
  127. odm_set_bb_reg(p_dm_odm, REG_BB_TXBF_ANT_SET_BF1_8822B, BIT(31), 1);
  128. odm_set_bb_reg(p_dm_odm, REG_BB_TXBF_ANT_SET_BF1_8822B, 0xffff, 0x0433);
  129. odm_set_bb_reg(p_dm_odm, REG_BB_TX_PATH_SEL_1_8822B, 0xfff00000, 0x043);
  130. }
  131. #endif
  132. }
  133. #if 0
  134. void
  135. hal_txbf_8822b_download_ndpa(
  136. struct _ADAPTER *adapter,
  137. u8 idx
  138. )
  139. {
  140. u8 u1b_tmp = 0, tmp_reg422 = 0;
  141. u8 bcn_valid_reg = 0, count = 0, dl_bcn_count = 0;
  142. u16 head_page = 0x7FE;
  143. boolean is_send_beacon = false;
  144. HAL_DATA_TYPE *p_hal_data = GET_HAL_DATA(adapter);
  145. u16 tx_page_bndy = LAST_ENTRY_OF_TX_PKT_BUFFER_8814A; /*default reseved 1 page for the IC type which is undefined.*/
  146. struct _RT_BEAMFORMING_INFO *p_beam_info = GET_BEAMFORM_INFO(adapter);
  147. struct _RT_BEAMFORMEE_ENTRY *p_beam_entry = p_beam_info->beamformee_entry + idx;
  148. p_hal_data->is_fw_dw_rsvd_page_in_progress = true;
  149. phydm_get_hal_def_var_handler_interface(p_dm_odm, HAL_DEF_TX_PAGE_BOUNDARY, (u16 *)&tx_page_bndy);
  150. /*Set REG_CR bit 8. DMA beacon by SW.*/
  151. u1b_tmp = platform_efio_read_1byte(adapter, REG_CR_8814A + 1);
  152. platform_efio_write_1byte(adapter, REG_CR_8814A + 1, (u1b_tmp | BIT(0)));
  153. /*Set FWHW_TXQ_CTRL 0x422[6]=0 to tell Hw the packet is not a real beacon frame.*/
  154. tmp_reg422 = platform_efio_read_1byte(adapter, REG_FWHW_TXQ_CTRL_8814A + 2);
  155. platform_efio_write_1byte(adapter, REG_FWHW_TXQ_CTRL_8814A + 2, tmp_reg422 & (~BIT(6)));
  156. if (tmp_reg422 & BIT(6)) {
  157. RT_TRACE(COMP_INIT, DBG_LOUD, ("SetBeamformDownloadNDPA_8814A(): There is an adapter is sending beacon.\n"));
  158. is_send_beacon = true;
  159. }
  160. /*0x204[11:0] Beacon Head for TXDMA*/
  161. platform_efio_write_2byte(adapter, REG_FIFOPAGE_CTRL_2_8814A, head_page);
  162. do {
  163. /*Clear beacon valid check bit.*/
  164. bcn_valid_reg = platform_efio_read_1byte(adapter, REG_FIFOPAGE_CTRL_2_8814A + 1);
  165. platform_efio_write_1byte(adapter, REG_FIFOPAGE_CTRL_2_8814A + 1, (bcn_valid_reg | BIT(7)));
  166. /*download NDPA rsvd page.*/
  167. if (p_beam_entry->beamform_entry_cap & BEAMFORMER_CAP_VHT_SU)
  168. beamforming_send_vht_ndpa_packet(p_dm_odm, p_beam_entry->mac_addr, p_beam_entry->AID, p_beam_entry->sound_bw, BEACON_QUEUE);
  169. else
  170. beamforming_send_ht_ndpa_packet(p_dm_odm, p_beam_entry->mac_addr, p_beam_entry->sound_bw, BEACON_QUEUE);
  171. /*check rsvd page download OK.*/
  172. bcn_valid_reg = platform_efio_read_1byte(adapter, REG_FIFOPAGE_CTRL_2_8814A + 1);
  173. count = 0;
  174. while (!(bcn_valid_reg & BIT(7)) && count < 20) {
  175. count++;
  176. delay_us(10);
  177. bcn_valid_reg = platform_efio_read_1byte(adapter, REG_FIFOPAGE_CTRL_2_8814A + 2);
  178. }
  179. dl_bcn_count++;
  180. } while (!(bcn_valid_reg & BIT(7)) && dl_bcn_count < 5);
  181. if (!(bcn_valid_reg & BIT(0)))
  182. RT_DISP(FBEAM, FBEAM_ERROR, ("%s Download RSVD page failed!\n", __func__));
  183. /*0x204[11:0] Beacon Head for TXDMA*/
  184. platform_efio_write_2byte(adapter, REG_FIFOPAGE_CTRL_2_8814A, tx_page_bndy);
  185. /*To make sure that if there exists an adapter which would like to send beacon.*/
  186. /*If exists, the origianl value of 0x422[6] will be 1, we should check this to*/
  187. /*prevent from setting 0x422[6] to 0 after download reserved page, or it will cause */
  188. /*the beacon cannot be sent by HW.*/
  189. /*2010.06.23. Added by tynli.*/
  190. if (is_send_beacon)
  191. platform_efio_write_1byte(adapter, REG_FWHW_TXQ_CTRL_8814A + 2, tmp_reg422);
  192. /*Do not enable HW DMA BCN or it will cause Pcie interface hang by timing issue. 2011.11.24. by tynli.*/
  193. /*Clear CR[8] or beacon packet will not be send to TxBuf anymore.*/
  194. u1b_tmp = platform_efio_read_1byte(adapter, REG_CR_8814A + 1);
  195. platform_efio_write_1byte(adapter, REG_CR_8814A + 1, (u1b_tmp & (~BIT(0))));
  196. p_beam_entry->beamform_entry_state = BEAMFORMING_ENTRY_STATE_PROGRESSED;
  197. p_hal_data->is_fw_dw_rsvd_page_in_progress = false;
  198. }
  199. void
  200. hal_txbf_8822b_fw_txbf_cmd(
  201. struct _ADAPTER *adapter
  202. )
  203. {
  204. u8 idx, period = 0;
  205. u8 PageNum0 = 0xFF, PageNum1 = 0xFF;
  206. u8 u1_tx_bf_parm[3] = {0};
  207. PMGNT_INFO p_mgnt_info = &(adapter->MgntInfo);
  208. struct _RT_BEAMFORMING_INFO *p_beam_info = GET_BEAMFORM_INFO(adapter);
  209. for (idx = 0; idx < BEAMFORMEE_ENTRY_NUM; idx++) {
  210. if (p_beam_info->beamformee_entry[idx].is_used && p_beam_info->beamformee_entry[idx].beamform_entry_state == BEAMFORMING_ENTRY_STATE_PROGRESSED) {
  211. if (p_beam_info->beamformee_entry[idx].is_sound) {
  212. PageNum0 = 0xFE;
  213. PageNum1 = 0x07;
  214. period = (u8)(p_beam_info->beamformee_entry[idx].sound_period);
  215. } else if (PageNum0 == 0xFF) {
  216. PageNum0 = 0xFF; /*stop sounding*/
  217. PageNum1 = 0x0F;
  218. }
  219. }
  220. }
  221. u1_tx_bf_parm[0] = PageNum0;
  222. u1_tx_bf_parm[1] = PageNum1;
  223. u1_tx_bf_parm[2] = period;
  224. fill_h2c_cmd(adapter, PHYDM_H2C_TXBF, 3, u1_tx_bf_parm);
  225. RT_DISP(FBEAM, FBEAM_FUN, ("@%s End, PageNum0 = 0x%x, PageNum1 = 0x%x period = %d", __func__, PageNum0, PageNum1, period));
  226. }
  227. #endif
  228. #if 0
  229. void
  230. hal_txbf_8822b_init(
  231. void *p_dm_void
  232. )
  233. {
  234. struct PHY_DM_STRUCT *p_dm_odm = (struct PHY_DM_STRUCT *)p_dm_void;
  235. u8 u1b_tmp;
  236. struct _RT_BEAMFORMING_INFO *p_beamforming_info = &p_dm_odm->beamforming_info;
  237. struct _ADAPTER *adapter = p_dm_odm->adapter;
  238. odm_set_bb_reg(p_dm_odm, 0x14c0, BIT(16), 1); /*Enable P1 aggr new packet according to P0 transfer time*/
  239. odm_set_bb_reg(p_dm_odm, 0x14c0, BIT(15) | BIT14 | BIT13 | BIT12, 10); /*MU Retry Limit*/
  240. odm_set_bb_reg(p_dm_odm, 0x14c0, BIT(7), 0); /*Disable Tx MU-MIMO until sounding done*/
  241. odm_set_bb_reg(p_dm_odm, 0x14c0, 0x3F, 0); /* Clear validity of MU STAs */
  242. odm_write_1byte(p_dm_odm, 0x167c, 0x70); /*MU-MIMO Option as default value*/
  243. odm_write_2byte(p_dm_odm, 0x1680, 0); /*MU-MIMO Control as default value*/
  244. /* Set MU NDPA rate & BW source */
  245. /* 0x42C[30] = 1 (0: from Tx desc, 1: from 0x45F) */
  246. u1b_tmp = odm_read_1byte(p_dm_odm, 0x42C);
  247. odm_write_1byte(p_dm_odm, REG_TXBF_CTRL_8822B, (u1b_tmp | BIT(6)));
  248. /* 0x45F[7:0] = 0x10 (rate=OFDM_6M, BW20) */
  249. odm_write_1byte(p_dm_odm, REG_NDPA_OPT_CTRL_8822B, 0x10);
  250. /*Temp Settings*/
  251. odm_set_bb_reg(p_dm_odm, 0x6DC, 0x3F000000, 4); /*STA2's CSI rate is fixed at 6M*/
  252. odm_set_bb_reg(p_dm_odm, 0x1C94, MASKDWORD, 0xAFFFAFFF); /*Grouping bitmap parameters*/
  253. /* Init HW variable */
  254. p_beamforming_info->reg_mu_tx_ctrl = odm_read_4byte(p_dm_odm, 0x14c0);
  255. if (p_dm_odm->rf_type == ODM_2T2R) { /*2T2R*/
  256. ODM_RT_TRACE(p_dm_odm, PHYDM_COMP_TXBF, ODM_DBG_LOUD, ("%s: rf_type is 2T2R\n", __func__));
  257. config_phydm_trx_mode_8822b(p_dm_odm, (enum odm_rf_path_e)3, (enum odm_rf_path_e)3, true);/*Tx2path*/
  258. }
  259. #if (OMNIPEEK_SNIFFER_ENABLED == 1)
  260. /* Config HW to receive packet on the user position from registry for sniffer mode. */
  261. /* odm_set_bb_reg(p_dm_odm, 0xB00, BIT(9), 1);*/ /* For A-cut only. RegB00[9] = 1 (enable PMAC Rx) */
  262. odm_set_bb_reg(p_dm_odm, 0xB54, BIT(30), 1); /* RegB54[30] = 1 (force user position) */
  263. odm_set_bb_reg(p_dm_odm, 0xB54, (BIT(29) | BIT28), adapter->MgntInfo.sniff_user_position); /* RegB54[29:28] = user position (0~3) */
  264. ODM_RT_TRACE(p_dm_odm, PHYDM_COMP_TXBF, ODM_DBG_LOUD, ("Set adapter->MgntInfo.sniff_user_position=%#X\n", adapter->MgntInfo.sniff_user_position));
  265. #endif
  266. }
  267. #endif
  268. void
  269. hal_txbf_8822b_enter(
  270. void *p_dm_void,
  271. u8 bfer_bfee_idx
  272. )
  273. {
  274. struct PHY_DM_STRUCT *p_dm_odm = (struct PHY_DM_STRUCT *)p_dm_void;
  275. u8 i = 0;
  276. u8 bfer_idx = (bfer_bfee_idx & 0xF0) >> 4;
  277. u8 bfee_idx = (bfer_bfee_idx & 0xF);
  278. u16 csi_param = 0;
  279. struct _RT_BEAMFORMING_INFO *p_beamforming_info = &p_dm_odm->beamforming_info;
  280. struct _RT_BEAMFORMEE_ENTRY *p_beamformee_entry;
  281. struct _RT_BEAMFORMER_ENTRY *p_beamformer_entry;
  282. u16 value16, sta_id = 0;
  283. u8 nc_index = 0, nr_index = 0, grouping = 0, codebookinfo = 0, coefficientsize = 0;
  284. u32 gid_valid, user_position_l, user_position_h;
  285. u32 mu_reg[6] = {0x1684, 0x1686, 0x1688, 0x168a, 0x168c, 0x168e};
  286. u8 u1b_tmp;
  287. u32 u4b_tmp;
  288. RT_DISP(FBEAM, FBEAM_FUN, ("%s: bfer_bfee_idx=%d, bfer_idx=%d, bfee_idx=%d\n", __func__, bfer_bfee_idx, bfer_idx, bfee_idx));
  289. /*************SU BFer Entry Init*************/
  290. if ((p_beamforming_info->beamformer_su_cnt > 0) && (bfer_idx < BEAMFORMER_ENTRY_NUM)) {
  291. p_beamformer_entry = &p_beamforming_info->beamformer_entry[bfer_idx];
  292. p_beamformer_entry->is_mu_ap = false;
  293. /*Sounding protocol control*/
  294. odm_write_1byte(p_dm_odm, REG_SND_PTCL_CTRL_8822B, 0xDB);
  295. for (i = 0; i < MAX_BEAMFORMER_SU; i++) {
  296. if ((p_beamforming_info->beamformer_su_reg_maping & BIT(i)) == 0) {
  297. p_beamforming_info->beamformer_su_reg_maping |= BIT(i);
  298. p_beamformer_entry->su_reg_index = i;
  299. break;
  300. }
  301. }
  302. /*MAC address/Partial AID of Beamformer*/
  303. if (p_beamformer_entry->su_reg_index == 0) {
  304. for (i = 0; i < 6 ; i++)
  305. odm_write_1byte(p_dm_odm, (REG_ASSOCIATED_BFMER0_INFO_8822B + i), p_beamformer_entry->mac_addr[i]);
  306. } else {
  307. for (i = 0; i < 6 ; i++)
  308. odm_write_1byte(p_dm_odm, (REG_ASSOCIATED_BFMER1_INFO_8822B + i), p_beamformer_entry->mac_addr[i]);
  309. }
  310. /*CSI report parameters of Beamformer*/
  311. nc_index = hal_txbf_8822b_get_nrx(p_dm_odm); /*for 8814A nrx = 3(4 ant), min=0(1 ant)*/
  312. nr_index = p_beamformer_entry->num_of_sounding_dim; /*0x718[7] = 1 use Nsts, 0x718[7] = 0 use reg setting. as Bfee, we use Nsts, so nr_index don't care*/
  313. grouping = 0;
  314. /*for ac = 1, for n = 3*/
  315. if (p_beamformer_entry->beamform_entry_cap & BEAMFORMEE_CAP_VHT_SU)
  316. codebookinfo = 1;
  317. else if (p_beamformer_entry->beamform_entry_cap & BEAMFORMEE_CAP_HT_EXPLICIT)
  318. codebookinfo = 3;
  319. coefficientsize = 3;
  320. csi_param = (u16)((coefficientsize << 10) | (codebookinfo << 8) | (grouping << 6) | (nr_index << 3) | (nc_index));
  321. if (bfer_idx == 0)
  322. odm_write_2byte(p_dm_odm, REG_TX_CSI_RPT_PARAM_BW20_8822B, csi_param);
  323. else
  324. odm_write_2byte(p_dm_odm, REG_TX_CSI_RPT_PARAM_BW20_8822B + 2, csi_param);
  325. /*ndp_rx_standby_timer, 8814 need > 0x56, suggest from Dvaid*/
  326. odm_write_1byte(p_dm_odm, REG_SND_PTCL_CTRL_8822B + 3, 0x70);
  327. }
  328. /*************SU BFee Entry Init*************/
  329. if ((p_beamforming_info->beamformee_su_cnt > 0) && (bfee_idx < BEAMFORMEE_ENTRY_NUM)) {
  330. p_beamformee_entry = &p_beamforming_info->beamformee_entry[bfee_idx];
  331. p_beamformee_entry->is_mu_sta = false;
  332. hal_txbf_8822b_rf_mode(p_dm_odm, p_beamforming_info, bfee_idx);
  333. if (phydm_acting_determine(p_dm_odm, phydm_acting_as_ibss))
  334. sta_id = p_beamformee_entry->mac_id;
  335. else
  336. sta_id = p_beamformee_entry->p_aid;
  337. for (i = 0; i < MAX_BEAMFORMEE_SU; i++) {
  338. if ((p_beamforming_info->beamformee_su_reg_maping & BIT(i)) == 0) {
  339. p_beamforming_info->beamformee_su_reg_maping |= BIT(i);
  340. p_beamformee_entry->su_reg_index = i;
  341. break;
  342. }
  343. }
  344. /*P_AID of Beamformee & enable NDPA transmission & enable NDPA interrupt*/
  345. if (p_beamformee_entry->su_reg_index == 0) {
  346. odm_write_2byte(p_dm_odm, REG_TXBF_CTRL_8822B, sta_id);
  347. odm_write_1byte(p_dm_odm, REG_TXBF_CTRL_8822B + 3, odm_read_1byte(p_dm_odm, REG_TXBF_CTRL_8822B + 3) | BIT(4) | BIT(6) | BIT(7));
  348. } else
  349. odm_write_2byte(p_dm_odm, REG_TXBF_CTRL_8822B + 2, sta_id | BIT(14) | BIT(15) | BIT(12));
  350. /*CSI report parameters of Beamformee*/
  351. if (p_beamformee_entry->su_reg_index == 0) {
  352. /*Get BIT24 & BIT25*/
  353. u8 tmp = odm_read_1byte(p_dm_odm, REG_ASSOCIATED_BFMEE_SEL_8822B + 3) & 0x3;
  354. odm_write_1byte(p_dm_odm, REG_ASSOCIATED_BFMEE_SEL_8822B + 3, tmp | 0x60);
  355. odm_write_2byte(p_dm_odm, REG_ASSOCIATED_BFMEE_SEL_8822B, sta_id | BIT(9));
  356. } else
  357. odm_write_2byte(p_dm_odm, REG_ASSOCIATED_BFMEE_SEL_8822B + 2, sta_id | 0xE200); /*Set BIT25*/
  358. phydm_beamforming_notify(p_dm_odm);
  359. }
  360. /*************MU BFer Entry Init*************/
  361. if ((p_beamforming_info->beamformer_mu_cnt > 0) && (bfer_idx < BEAMFORMER_ENTRY_NUM)) {
  362. p_beamformer_entry = &p_beamforming_info->beamformer_entry[bfer_idx];
  363. p_beamforming_info->mu_ap_index = bfer_idx;
  364. p_beamformer_entry->is_mu_ap = true;
  365. for (i = 0; i < 8; i++)
  366. p_beamformer_entry->gid_valid[i] = 0;
  367. for (i = 0; i < 16; i++)
  368. p_beamformer_entry->user_position[i] = 0;
  369. /*Sounding protocol control*/
  370. odm_write_1byte(p_dm_odm, REG_SND_PTCL_CTRL_8822B, 0xDB);
  371. /* MAC address */
  372. for (i = 0; i < 6 ; i++)
  373. odm_write_1byte(p_dm_odm, (REG_ASSOCIATED_BFMER0_INFO_8822B + i), p_beamformer_entry->mac_addr[i]);
  374. /* Set partial AID */
  375. odm_write_2byte(p_dm_odm, (REG_ASSOCIATED_BFMER0_INFO_8822B + 6), p_beamformer_entry->p_aid);
  376. /* Fill our AID to 0x1680[11:0] and [13:12] = 2b'00, BF report segment select to 3895 bytes*/
  377. u1b_tmp = odm_read_1byte(p_dm_odm, 0x1680);
  378. u1b_tmp = (p_beamformer_entry->p_aid) & 0xFFF;
  379. odm_write_1byte(p_dm_odm, 0x1680, u1b_tmp);
  380. /* Set 80us for leaving ndp_rx_standby_state */
  381. odm_write_1byte(p_dm_odm, 0x71B, 0x50);
  382. /* Set 0x6A0[14] = 1 to accept action_no_ack */
  383. u1b_tmp = odm_read_1byte(p_dm_odm, REG_RXFLTMAP0_8822B + 1);
  384. u1b_tmp |= 0x40;
  385. odm_write_1byte(p_dm_odm, REG_RXFLTMAP0_8822B + 1, u1b_tmp);
  386. /* Set 0x6A2[5:4] = 1 to NDPA and BF report poll */
  387. u1b_tmp = odm_read_1byte(p_dm_odm, REG_RXFLTMAP1_8822B);
  388. u1b_tmp |= 0x30;
  389. odm_write_1byte(p_dm_odm, REG_RXFLTMAP1_8822B, u1b_tmp);
  390. /*CSI report parameters of Beamformer*/
  391. nc_index = hal_txbf_8822b_get_nrx(p_dm_odm); /* Depend on RF type */
  392. nr_index = 1; /*0x718[7] = 1 use Nsts, 0x718[7] = 0 use reg setting. as Bfee, we use Nsts, so nr_index don't care*/
  393. grouping = 0; /*no grouping*/
  394. codebookinfo = 1; /*7 bit for psi, 9 bit for phi*/
  395. coefficientsize = 0; /*This is nothing really matter*/
  396. csi_param = (u16)((coefficientsize << 10) | (codebookinfo << 8) | (grouping << 6) | (nr_index << 3) | (nc_index));
  397. odm_write_2byte(p_dm_odm, 0x6F4, csi_param);
  398. /*for B-cut*/
  399. odm_set_bb_reg(p_dm_odm, 0x6A0, BIT(20), 0);
  400. odm_set_bb_reg(p_dm_odm, 0x688, BIT(20), 0);
  401. }
  402. /*************MU BFee Entry Init*************/
  403. if ((p_beamforming_info->beamformee_mu_cnt > 0) && (bfee_idx < BEAMFORMEE_ENTRY_NUM)) {
  404. p_beamformee_entry = &p_beamforming_info->beamformee_entry[bfee_idx];
  405. p_beamformee_entry->is_mu_sta = true;
  406. for (i = 0; i < MAX_BEAMFORMEE_MU; i++) {
  407. if ((p_beamforming_info->beamformee_mu_reg_maping & BIT(i)) == 0) {
  408. p_beamforming_info->beamformee_mu_reg_maping |= BIT(i);
  409. p_beamformee_entry->mu_reg_index = i;
  410. break;
  411. }
  412. }
  413. if (p_beamformee_entry->mu_reg_index == 0xFF) {
  414. /* There is no valid bit in beamformee_mu_reg_maping */
  415. RT_DISP(FBEAM, FBEAM_FUN, ("%s: ERROR! There is no valid bit in beamformee_mu_reg_maping!\n", __func__));
  416. return;
  417. }
  418. /*User position table*/
  419. switch (p_beamformee_entry->mu_reg_index) {
  420. case 0:
  421. gid_valid = 0x7fe;
  422. user_position_l = 0x111110;
  423. user_position_h = 0x0;
  424. break;
  425. case 1:
  426. gid_valid = 0x7f806;
  427. user_position_l = 0x11000004;
  428. user_position_h = 0x11;
  429. break;
  430. case 2:
  431. gid_valid = 0x1f81818;
  432. user_position_l = 0x400040;
  433. user_position_h = 0x11100;
  434. break;
  435. case 3:
  436. gid_valid = 0x1e186060;
  437. user_position_l = 0x4000400;
  438. user_position_h = 0x1100040;
  439. break;
  440. case 4:
  441. gid_valid = 0x66618180;
  442. user_position_l = 0x40004000;
  443. user_position_h = 0x10040400;
  444. break;
  445. case 5:
  446. gid_valid = 0x79860600;
  447. user_position_l = 0x40000;
  448. user_position_h = 0x4404004;
  449. break;
  450. }
  451. for (i = 0; i < 8; i++) {
  452. if (i < 4) {
  453. p_beamformee_entry->gid_valid[i] = (u8)(gid_valid & 0xFF);
  454. gid_valid = (gid_valid >> 8);
  455. } else
  456. p_beamformee_entry->gid_valid[i] = 0;
  457. }
  458. for (i = 0; i < 16; i++) {
  459. if (i < 4)
  460. p_beamformee_entry->user_position[i] = (u8)((user_position_l >> (i * 8)) & 0xFF);
  461. else if (i < 8)
  462. p_beamformee_entry->user_position[i] = (u8)((user_position_h >> ((i - 4) * 8)) & 0xFF);
  463. else
  464. p_beamformee_entry->user_position[i] = 0;
  465. }
  466. /*Sounding protocol control*/
  467. odm_write_1byte(p_dm_odm, REG_SND_PTCL_CTRL_8822B, 0xDB);
  468. /*select MU STA table*/
  469. p_beamforming_info->reg_mu_tx_ctrl &= ~(BIT(8) | BIT(9) | BIT(10));
  470. p_beamforming_info->reg_mu_tx_ctrl |= (p_beamformee_entry->mu_reg_index << 8) & (BIT(8) | BIT(9) | BIT(10));
  471. odm_write_4byte(p_dm_odm, 0x14c0, p_beamforming_info->reg_mu_tx_ctrl);
  472. odm_set_bb_reg(p_dm_odm, 0x14c4, MASKDWORD, 0); /*Reset gid_valid table*/
  473. odm_set_bb_reg(p_dm_odm, 0x14c8, MASKDWORD, user_position_l);
  474. odm_set_bb_reg(p_dm_odm, 0x14cc, MASKDWORD, user_position_h);
  475. /*set validity of MU STAs*/
  476. p_beamforming_info->reg_mu_tx_ctrl &= 0xFFFFFFC0;
  477. p_beamforming_info->reg_mu_tx_ctrl |= p_beamforming_info->beamformee_mu_reg_maping & 0x3F;
  478. odm_write_4byte(p_dm_odm, 0x14c0, p_beamforming_info->reg_mu_tx_ctrl);
  479. ODM_RT_TRACE(p_dm_odm, PHYDM_COMP_TXBF, ODM_DBG_LOUD, ("@%s, reg_mu_tx_ctrl = 0x%x, user_position_l = 0x%x, user_position_h = 0x%x\n",
  480. __func__, p_beamforming_info->reg_mu_tx_ctrl, user_position_l, user_position_h));
  481. value16 = odm_read_2byte(p_dm_odm, mu_reg[p_beamformee_entry->mu_reg_index]);
  482. value16 &= 0xFE00; /*Clear PAID*/
  483. value16 |= BIT(9); /*Enable MU BFee*/
  484. value16 |= p_beamformee_entry->p_aid;
  485. odm_write_2byte(p_dm_odm, mu_reg[p_beamformee_entry->mu_reg_index], value16);
  486. /* 0x42C[30] = 1 (0: from Tx desc, 1: from 0x45F) */
  487. u1b_tmp = odm_read_1byte(p_dm_odm, REG_TXBF_CTRL_8822B + 3);
  488. u1b_tmp |= 0xD0; /* Set bit 28, 30, 31 to 3b'111*/
  489. odm_write_1byte(p_dm_odm, REG_TXBF_CTRL_8822B + 3, u1b_tmp);
  490. /* Set NDPA to 6M*/
  491. odm_write_1byte(p_dm_odm, REG_NDPA_RATE_8822B, 0x4);
  492. u1b_tmp = odm_read_1byte(p_dm_odm, REG_NDPA_OPT_CTRL_8822B);
  493. u1b_tmp &= 0xFC; /* Clear bit 0, 1*/
  494. odm_write_1byte(p_dm_odm, REG_NDPA_OPT_CTRL_8822B, u1b_tmp);
  495. u4b_tmp = odm_read_4byte(p_dm_odm, REG_SND_PTCL_CTRL_8822B);
  496. u4b_tmp = ((u4b_tmp & 0xFF0000FF) | 0x020200); /* Set [23:8] to 0x0202*/
  497. odm_write_4byte(p_dm_odm, REG_SND_PTCL_CTRL_8822B, u4b_tmp);
  498. /* Set 0x6A0[14] = 1 to accept action_no_ack */
  499. u1b_tmp = odm_read_1byte(p_dm_odm, REG_RXFLTMAP0_8822B + 1);
  500. u1b_tmp |= 0x40;
  501. odm_write_1byte(p_dm_odm, REG_RXFLTMAP0_8822B + 1, u1b_tmp);
  502. /* End of MAC registers setting */
  503. hal_txbf_8822b_rf_mode(p_dm_odm, p_beamforming_info, bfee_idx);
  504. #if (SUPPORT_MU_BF == 1)
  505. /*Special for plugfest*/
  506. delay_ms(50); /* wait for 4-way handshake ending*/
  507. send_sw_vht_gid_mgnt_frame(p_dm_odm, p_beamformee_entry->mac_addr, bfee_idx);
  508. #endif
  509. phydm_beamforming_notify(p_dm_odm);
  510. #if 1
  511. {
  512. u32 ctrl_info_offset, index;
  513. /*Set Ctrl Info*/
  514. odm_write_2byte(p_dm_odm, 0x140, 0x660);
  515. ctrl_info_offset = 0x8000 + 32 * p_beamformee_entry->mac_id;
  516. /*Reset Ctrl Info*/
  517. for (index = 0; index < 8; index++)
  518. odm_write_4byte(p_dm_odm, ctrl_info_offset + index * 4, 0);
  519. odm_write_4byte(p_dm_odm, ctrl_info_offset, (p_beamformee_entry->mu_reg_index + 1) << 16);
  520. odm_write_1byte(p_dm_odm, 0x81, 0x80); /*RPTBUF ready*/
  521. ODM_RT_TRACE(p_dm_odm, PHYDM_COMP_TXBF, ODM_DBG_LOUD, ("@%s, mac_id = %d, ctrl_info_offset = 0x%x, mu_reg_index = %x\n",
  522. __func__, p_beamformee_entry->mac_id, ctrl_info_offset, p_beamformee_entry->mu_reg_index));
  523. }
  524. #endif
  525. }
  526. }
  527. void
  528. hal_txbf_8822b_leave(
  529. void *p_dm_void,
  530. u8 idx
  531. )
  532. {
  533. struct PHY_DM_STRUCT *p_dm_odm = (struct PHY_DM_STRUCT *)p_dm_void;
  534. struct _RT_BEAMFORMING_INFO *p_beamforming_info = &p_dm_odm->beamforming_info;
  535. struct _RT_BEAMFORMER_ENTRY *p_beamformer_entry;
  536. struct _RT_BEAMFORMEE_ENTRY *p_beamformee_entry;
  537. u32 mu_reg[6] = {0x1684, 0x1686, 0x1688, 0x168a, 0x168c, 0x168e};
  538. if (idx < BEAMFORMER_ENTRY_NUM) {
  539. p_beamformer_entry = &p_beamforming_info->beamformer_entry[idx];
  540. p_beamformee_entry = &p_beamforming_info->beamformee_entry[idx];
  541. } else
  542. return;
  543. /*Clear P_AID of Beamformee*/
  544. /*Clear MAC address of Beamformer*/
  545. /*Clear Associated Bfmee Sel*/
  546. if (p_beamformer_entry->beamform_entry_cap == BEAMFORMING_CAP_NONE) {
  547. odm_write_1byte(p_dm_odm, REG_SND_PTCL_CTRL_8822B, 0xD8);
  548. if (p_beamformer_entry->is_mu_ap == 0) { /*SU BFer */
  549. if (p_beamformer_entry->su_reg_index == 0) {
  550. odm_write_4byte(p_dm_odm, REG_ASSOCIATED_BFMER0_INFO_8822B, 0);
  551. odm_write_2byte(p_dm_odm, REG_ASSOCIATED_BFMER0_INFO_8822B + 4, 0);
  552. odm_write_2byte(p_dm_odm, REG_TX_CSI_RPT_PARAM_BW20_8822B, 0);
  553. } else {
  554. odm_write_4byte(p_dm_odm, REG_ASSOCIATED_BFMER1_INFO_8822B, 0);
  555. odm_write_2byte(p_dm_odm, REG_ASSOCIATED_BFMER1_INFO_8822B + 4, 0);
  556. odm_write_2byte(p_dm_odm, REG_TX_CSI_RPT_PARAM_BW20_8822B + 2, 0);
  557. }
  558. p_beamforming_info->beamformer_su_reg_maping &= ~(BIT(p_beamformer_entry->su_reg_index));
  559. p_beamformer_entry->su_reg_index = 0xFF;
  560. } else { /*MU BFer */
  561. /*set validity of MU STA0 and MU STA1*/
  562. p_beamforming_info->reg_mu_tx_ctrl &= 0xFFFFFFC0;
  563. odm_write_4byte(p_dm_odm, 0x14c0, p_beamforming_info->reg_mu_tx_ctrl);
  564. odm_memory_set(p_dm_odm, p_beamformer_entry->gid_valid, 0, 8);
  565. odm_memory_set(p_dm_odm, p_beamformer_entry->user_position, 0, 16);
  566. p_beamformer_entry->is_mu_ap = false;
  567. }
  568. }
  569. if (p_beamformee_entry->beamform_entry_cap == BEAMFORMING_CAP_NONE) {
  570. hal_txbf_8822b_rf_mode(p_dm_odm, p_beamforming_info, idx);
  571. if (p_beamformee_entry->is_mu_sta == 0) { /*SU BFee*/
  572. if (p_beamformee_entry->su_reg_index == 0) {
  573. odm_write_2byte(p_dm_odm, REG_TXBF_CTRL_8822B, 0x0);
  574. odm_write_1byte(p_dm_odm, REG_TXBF_CTRL_8822B + 3, odm_read_1byte(p_dm_odm, REG_TXBF_CTRL_8822B + 3) | BIT(4) | BIT(6) | BIT(7));
  575. odm_write_2byte(p_dm_odm, REG_ASSOCIATED_BFMEE_SEL_8822B, 0);
  576. } else {
  577. odm_write_2byte(p_dm_odm, REG_TXBF_CTRL_8822B + 2, 0x0 | BIT(14) | BIT(15) | BIT(12));
  578. odm_write_2byte(p_dm_odm, REG_ASSOCIATED_BFMEE_SEL_8822B + 2,
  579. odm_read_2byte(p_dm_odm, REG_ASSOCIATED_BFMEE_SEL_8822B + 2) & 0x60);
  580. }
  581. p_beamforming_info->beamformee_su_reg_maping &= ~(BIT(p_beamformee_entry->su_reg_index));
  582. p_beamformee_entry->su_reg_index = 0xFF;
  583. } else { /*MU BFee */
  584. /*Disable sending NDPA & BF-rpt-poll to this BFee*/
  585. odm_write_2byte(p_dm_odm, mu_reg[p_beamformee_entry->mu_reg_index], 0);
  586. /*set validity of MU STA*/
  587. p_beamforming_info->reg_mu_tx_ctrl &= ~(BIT(p_beamformee_entry->mu_reg_index));
  588. odm_write_4byte(p_dm_odm, 0x14c0, p_beamforming_info->reg_mu_tx_ctrl);
  589. p_beamformee_entry->is_mu_sta = false;
  590. p_beamforming_info->beamformee_mu_reg_maping &= ~(BIT(p_beamformee_entry->mu_reg_index));
  591. p_beamformee_entry->mu_reg_index = 0xFF;
  592. }
  593. }
  594. }
  595. /***********SU & MU BFee Entry Only when souding done****************/
  596. void
  597. hal_txbf_8822b_status(
  598. void *p_dm_void,
  599. u8 beamform_idx
  600. )
  601. {
  602. struct PHY_DM_STRUCT *p_dm_odm = (struct PHY_DM_STRUCT *)p_dm_void;
  603. u16 beam_ctrl_val, tmp_val;
  604. u32 beam_ctrl_reg;
  605. struct _RT_BEAMFORMING_INFO *p_beamforming_info = &p_dm_odm->beamforming_info;
  606. struct _RT_BEAMFORMEE_ENTRY *p_beamform_entry;
  607. boolean is_mu_sounding = p_beamforming_info->is_mu_sounding, is_bitmap_ready = false;
  608. u16 bitmap;
  609. u8 idx, gid, i;
  610. u8 id1, id0;
  611. u32 gid_valid[6] = {0};
  612. u32 user_position_lsb[6] = {0};
  613. u32 user_position_msb[6] = {0};
  614. u32 value32;
  615. boolean is_sounding_success[6] = {false};
  616. if (beamform_idx < BEAMFORMEE_ENTRY_NUM)
  617. p_beamform_entry = &p_beamforming_info->beamformee_entry[beamform_idx];
  618. else
  619. return;
  620. /*SU sounding done */
  621. if (is_mu_sounding == false) {
  622. if (phydm_acting_determine(p_dm_odm, phydm_acting_as_ibss))
  623. beam_ctrl_val = p_beamform_entry->mac_id;
  624. else
  625. beam_ctrl_val = p_beamform_entry->p_aid;
  626. ODM_RT_TRACE(p_dm_odm, PHYDM_COMP_TXBF, ODM_DBG_LOUD, ("@%s, beamform_entry.beamform_entry_state = %d", __func__, p_beamform_entry->beamform_entry_state));
  627. if (p_beamform_entry->su_reg_index == 0)
  628. beam_ctrl_reg = REG_TXBF_CTRL_8822B;
  629. else {
  630. beam_ctrl_reg = REG_TXBF_CTRL_8822B + 2;
  631. beam_ctrl_val |= BIT(12) | BIT(14) | BIT(15);
  632. }
  633. if (p_beamform_entry->beamform_entry_state == BEAMFORMING_ENTRY_STATE_PROGRESSED) {
  634. if (p_beamform_entry->sound_bw == CHANNEL_WIDTH_20)
  635. beam_ctrl_val |= BIT(9);
  636. else if (p_beamform_entry->sound_bw == CHANNEL_WIDTH_40)
  637. beam_ctrl_val |= (BIT(9) | BIT(10));
  638. else if (p_beamform_entry->sound_bw == CHANNEL_WIDTH_80)
  639. beam_ctrl_val |= (BIT(9) | BIT(10) | BIT(11));
  640. } else {
  641. ODM_RT_TRACE(p_dm_odm, PHYDM_COMP_TXBF, ODM_DBG_LOUD, ("@%s, Don't apply Vmatrix", __func__));
  642. beam_ctrl_val &= ~(BIT(9) | BIT(10) | BIT(11));
  643. }
  644. odm_write_2byte(p_dm_odm, beam_ctrl_reg, beam_ctrl_val);
  645. /*disable NDP packet use beamforming */
  646. tmp_val = odm_read_2byte(p_dm_odm, REG_TXBF_CTRL_8822B);
  647. odm_write_2byte(p_dm_odm, REG_TXBF_CTRL_8822B, tmp_val | BIT(15));
  648. } else {
  649. ODM_RT_TRACE(p_dm_odm, PHYDM_COMP_TXBF, ODM_DBG_LOUD, ("@%s, MU Sounding Done\n", __func__));
  650. /*MU sounding done */
  651. if (1) { /* (p_beamform_entry->beamform_entry_state == BEAMFORMING_ENTRY_STATE_PROGRESSED) { */
  652. ODM_RT_TRACE(p_dm_odm, PHYDM_COMP_TXBF, ODM_DBG_LOUD, ("@%s, BEAMFORMING_ENTRY_STATE_PROGRESSED\n", __func__));
  653. value32 = odm_get_bb_reg(p_dm_odm, 0x1684, MASKDWORD);
  654. is_sounding_success[0] = (value32 & BIT(10)) ? 1 : 0;
  655. is_sounding_success[1] = (value32 & BIT(26)) ? 1 : 0;
  656. value32 = odm_get_bb_reg(p_dm_odm, 0x1688, MASKDWORD);
  657. is_sounding_success[2] = (value32 & BIT(10)) ? 1 : 0;
  658. is_sounding_success[3] = (value32 & BIT(26)) ? 1 : 0;
  659. value32 = odm_get_bb_reg(p_dm_odm, 0x168C, MASKDWORD);
  660. is_sounding_success[4] = (value32 & BIT(10)) ? 1 : 0;
  661. is_sounding_success[5] = (value32 & BIT(26)) ? 1 : 0;
  662. ODM_RT_TRACE(p_dm_odm, PHYDM_COMP_TXBF, ODM_DBG_LOUD, ("@%s, is_sounding_success STA1:%d, STA2:%d, STA3:%d, STA4:%d, STA5:%d, STA6:%d\n",
  663. __func__, is_sounding_success[0], is_sounding_success[1], is_sounding_success[2], is_sounding_success[3], is_sounding_success[4], is_sounding_success[5]));
  664. value32 = odm_get_bb_reg(p_dm_odm, 0xF4C, 0xFFFF0000);
  665. /* odm_set_bb_reg(p_dm_odm, 0x19E0, MASKHWORD, 0xFFFF);Let MAC ignore bitmap */
  666. is_bitmap_ready = (boolean)((value32 & BIT(15)) >> 15);
  667. bitmap = (u16)(value32 & 0x3FFF);
  668. for (idx = 0; idx < 15; idx++) {
  669. if (idx < 5) {/*bit0~4*/
  670. id0 = 0;
  671. id1 = (u8)(idx + 1);
  672. } else if (idx < 9) { /*bit5~8*/
  673. id0 = 1;
  674. id1 = (u8)(idx - 3);
  675. } else if (idx < 12) { /*bit9~11*/
  676. id0 = 2;
  677. id1 = (u8)(idx - 6);
  678. } else if (idx < 14) { /*bit12~13*/
  679. id0 = 3;
  680. id1 = (u8)(idx - 8);
  681. } else { /*bit14*/
  682. id0 = 4;
  683. id1 = (u8)(idx - 9);
  684. }
  685. if (bitmap & BIT(idx)) {
  686. /*Pair 1*/
  687. gid = (idx << 1) + 1;
  688. gid_valid[id0] |= (BIT(gid));
  689. gid_valid[id1] |= (BIT(gid));
  690. /*Pair 2*/
  691. gid += 1;
  692. gid_valid[id0] |= (BIT(gid));
  693. gid_valid[id1] |= (BIT(gid));
  694. } else {
  695. /*Pair 1*/
  696. gid = (idx << 1) + 1;
  697. gid_valid[id0] &= ~(BIT(gid));
  698. gid_valid[id1] &= ~(BIT(gid));
  699. /*Pair 2*/
  700. gid += 1;
  701. gid_valid[id0] &= ~(BIT(gid));
  702. gid_valid[id1] &= ~(BIT(gid));
  703. }
  704. }
  705. for (i = 0; i < BEAMFORMEE_ENTRY_NUM; i++) {
  706. p_beamform_entry = &p_beamforming_info->beamformee_entry[i];
  707. if ((p_beamform_entry->is_mu_sta) && (p_beamform_entry->mu_reg_index < 6)) {
  708. value32 = gid_valid[p_beamform_entry->mu_reg_index];
  709. for (idx = 0; idx < 4; idx++) {
  710. p_beamform_entry->gid_valid[idx] = (u8)(value32 & 0xFF);
  711. value32 = (value32 >> 8);
  712. }
  713. }
  714. }
  715. for (idx = 0; idx < 6; idx++) {
  716. p_beamforming_info->reg_mu_tx_ctrl &= ~(BIT(8) | BIT(9) | BIT(10));
  717. p_beamforming_info->reg_mu_tx_ctrl |= ((idx << 8) & (BIT(8) | BIT(9) | BIT(10)));
  718. odm_write_4byte(p_dm_odm, 0x14c0, p_beamforming_info->reg_mu_tx_ctrl);
  719. odm_set_mac_reg(p_dm_odm, 0x14C4, MASKDWORD, gid_valid[idx]); /*set MU STA gid valid table*/
  720. }
  721. /*Enable TxMU PPDU*/
  722. if (p_beamforming_info->dbg_disable_mu_tx == false)
  723. p_beamforming_info->reg_mu_tx_ctrl |= BIT(7);
  724. else
  725. p_beamforming_info->reg_mu_tx_ctrl &= ~BIT(7);
  726. odm_write_4byte(p_dm_odm, 0x14c0, p_beamforming_info->reg_mu_tx_ctrl);
  727. }
  728. }
  729. }
  730. /*Only used for MU BFer Entry when get GID management frame (self is as MU STA)*/
  731. void
  732. hal_txbf_8822b_config_gtab(
  733. void *p_dm_void
  734. )
  735. {
  736. struct PHY_DM_STRUCT *p_dm_odm = (struct PHY_DM_STRUCT *)p_dm_void;
  737. struct _RT_BEAMFORMING_INFO *p_beamforming_info = &p_dm_odm->beamforming_info;
  738. struct _RT_BEAMFORMER_ENTRY *p_beamformer_entry = NULL;
  739. u32 gid_valid = 0, user_position_l = 0, user_position_h = 0, i;
  740. if (p_beamforming_info->mu_ap_index < BEAMFORMER_ENTRY_NUM)
  741. p_beamformer_entry = &p_beamforming_info->beamformer_entry[p_beamforming_info->mu_ap_index];
  742. else
  743. return;
  744. ODM_RT_TRACE(p_dm_odm, PHYDM_COMP_TXBF, ODM_DBG_LOUD, ("%s==>\n", __func__));
  745. /*For GID 0~31*/
  746. for (i = 0; i < 4; i++)
  747. gid_valid |= (p_beamformer_entry->gid_valid[i] << (i << 3));
  748. for (i = 0; i < 8; i++) {
  749. if (i < 4)
  750. user_position_l |= (p_beamformer_entry->user_position[i] << (i << 3));
  751. else
  752. user_position_h |= (p_beamformer_entry->user_position[i] << ((i - 4) << 3));
  753. }
  754. /*select MU STA0 table*/
  755. p_beamforming_info->reg_mu_tx_ctrl &= ~(BIT(8) | BIT(9) | BIT(10));
  756. odm_write_4byte(p_dm_odm, 0x14c0, p_beamforming_info->reg_mu_tx_ctrl);
  757. odm_set_bb_reg(p_dm_odm, 0x14c4, MASKDWORD, gid_valid);
  758. odm_set_bb_reg(p_dm_odm, 0x14c8, MASKDWORD, user_position_l);
  759. odm_set_bb_reg(p_dm_odm, 0x14cc, MASKDWORD, user_position_h);
  760. ODM_RT_TRACE(p_dm_odm, PHYDM_COMP_TXBF, ODM_DBG_LOUD, ("%s: STA0: gid_valid = 0x%x, user_position_l = 0x%x, user_position_h = 0x%x\n",
  761. __func__, gid_valid, user_position_l, user_position_h));
  762. gid_valid = 0;
  763. user_position_l = 0;
  764. user_position_h = 0;
  765. /*For GID 32~64*/
  766. for (i = 4; i < 8; i++)
  767. gid_valid |= (p_beamformer_entry->gid_valid[i] << ((i - 4) << 3));
  768. for (i = 8; i < 16; i++) {
  769. if (i < 4)
  770. user_position_l |= (p_beamformer_entry->user_position[i] << ((i - 8) << 3));
  771. else
  772. user_position_h |= (p_beamformer_entry->user_position[i] << ((i - 12) << 3));
  773. }
  774. /*select MU STA1 table*/
  775. p_beamforming_info->reg_mu_tx_ctrl &= ~(BIT(8) | BIT(9) | BIT(10));
  776. p_beamforming_info->reg_mu_tx_ctrl |= BIT(8);
  777. odm_write_4byte(p_dm_odm, 0x14c0, p_beamforming_info->reg_mu_tx_ctrl);
  778. odm_set_bb_reg(p_dm_odm, 0x14c4, MASKDWORD, gid_valid);
  779. odm_set_bb_reg(p_dm_odm, 0x14c8, MASKDWORD, user_position_l);
  780. odm_set_bb_reg(p_dm_odm, 0x14cc, MASKDWORD, user_position_h);
  781. ODM_RT_TRACE(p_dm_odm, PHYDM_COMP_TXBF, ODM_DBG_LOUD, ("%s: STA1: gid_valid = 0x%x, user_position_l = 0x%x, user_position_h = 0x%x\n",
  782. __func__, gid_valid, user_position_l, user_position_h));
  783. /* Set validity of MU STA0 and MU STA1*/
  784. p_beamforming_info->reg_mu_tx_ctrl &= 0xFFFFFFC0;
  785. p_beamforming_info->reg_mu_tx_ctrl |= 0x3; /* STA0, STA1*/
  786. odm_write_4byte(p_dm_odm, 0x14c0, p_beamforming_info->reg_mu_tx_ctrl);
  787. }
  788. #if 0
  789. /*This function translate the bitmap to GTAB*/
  790. void
  791. haltxbf8822b_gtab_translation(
  792. struct PHY_DM_STRUCT *p_dm_odm
  793. )
  794. {
  795. u8 idx, gid;
  796. u8 id1, id0;
  797. u32 gid_valid[6] = {0};
  798. u32 user_position_lsb[6] = {0};
  799. u32 user_position_msb[6] = {0};
  800. for (idx = 0; idx < 15; idx++) {
  801. if (idx < 5) {/*bit0~4*/
  802. id0 = 0;
  803. id1 = (u8)(idx + 1);
  804. } else if (idx < 9) { /*bit5~8*/
  805. id0 = 1;
  806. id1 = (u8)(idx - 3);
  807. } else if (idx < 12) { /*bit9~11*/
  808. id0 = 2;
  809. id1 = (u8)(idx - 6);
  810. } else if (idx < 14) { /*bit12~13*/
  811. id0 = 3;
  812. id1 = (u8)(idx - 8);
  813. } else { /*bit14*/
  814. id0 = 4;
  815. id1 = (u8)(idx - 9);
  816. }
  817. /*Pair 1*/
  818. gid = (idx << 1) + 1;
  819. gid_valid[id0] |= (1 << gid);
  820. gid_valid[id1] |= (1 << gid);
  821. if (gid < 16) {
  822. /*user_position_lsb[id0] |= (0 << (gid << 1));*/
  823. user_position_lsb[id1] |= (1 << (gid << 1));
  824. } else {
  825. /*user_position_msb[id0] |= (0 << ((gid - 16) << 1));*/
  826. user_position_msb[id1] |= (1 << ((gid - 16) << 1));
  827. }
  828. /*Pair 2*/
  829. gid += 1;
  830. gid_valid[id0] |= (1 << gid);
  831. gid_valid[id1] |= (1 << gid);
  832. if (gid < 16) {
  833. user_position_lsb[id0] |= (1 << (gid << 1));
  834. /*user_position_lsb[id1] |= (0 << (gid << 1));*/
  835. } else {
  836. user_position_msb[id0] |= (1 << ((gid - 16) << 1));
  837. /*user_position_msb[id1] |= (0 << ((gid - 16) << 1));*/
  838. }
  839. }
  840. for (idx = 0; idx < 6; idx++) {
  841. /*dbg_print("gid_valid[%d] = 0x%x\n", idx, gid_valid[idx]);
  842. dbg_print("user_position[%d] = 0x%x %x\n", idx, user_position_msb[idx], user_position_lsb[idx]);*/
  843. }
  844. }
  845. #endif
  846. void
  847. hal_txbf_8822b_fw_txbf(
  848. void *p_dm_void,
  849. u8 idx
  850. )
  851. {
  852. #if 0
  853. struct _RT_BEAMFORMING_INFO *p_beam_info = GET_BEAMFORM_INFO(adapter);
  854. struct _RT_BEAMFORMEE_ENTRY *p_beam_entry = p_beam_info->beamformee_entry + idx;
  855. if (p_beam_entry->beamform_entry_state == BEAMFORMING_ENTRY_STATE_PROGRESSING)
  856. hal_txbf_8822b_download_ndpa(adapter, idx);
  857. hal_txbf_8822b_fw_txbf_cmd(adapter);
  858. #endif
  859. }
  860. #endif
  861. #if (defined(CONFIG_BB_TXBF_API))
  862. /*this function is only used for BFer*/
  863. void
  864. phydm_8822btxbf_rfmode(
  865. void *p_dm_void,
  866. u8 su_bfee_cnt,
  867. u8 mu_bfee_cnt
  868. )
  869. {
  870. struct PHY_DM_STRUCT *p_dm_odm = (struct PHY_DM_STRUCT *)p_dm_void;
  871. u8 i, nr_index = 0;
  872. if (p_dm_odm->rf_type == ODM_1T1R)
  873. return;
  874. if ((su_bfee_cnt > 0) || (mu_bfee_cnt > 0)) {
  875. for (i = ODM_RF_PATH_A; i <= ODM_RF_PATH_B; i++) {
  876. odm_set_rf_reg(p_dm_odm, (enum odm_rf_radio_path_e)i, 0xEF, BIT(19), 0x1); /*RF mode table write enable*/
  877. odm_set_rf_reg(p_dm_odm, (enum odm_rf_radio_path_e)i, 0x33, 0xF, 3); /*Select RX mode*/
  878. odm_set_rf_reg(p_dm_odm, (enum odm_rf_radio_path_e)i, 0x3E, 0xfffff, 0x00036); /*Set Table data*/
  879. odm_set_rf_reg(p_dm_odm, (enum odm_rf_radio_path_e)i, 0x3F, 0xfffff, 0x5AFCE); /*Set Table data*/
  880. odm_set_rf_reg(p_dm_odm, (enum odm_rf_radio_path_e)i, 0xEF, BIT(19), 0x0); /*RF mode table write disable*/
  881. }
  882. }
  883. odm_set_bb_reg(p_dm_odm, REG_BB_TXBF_ANT_SET_BF1_8822B, BIT(30), 1); /*if Nsts > Nc, don't apply V matrix*/
  884. if (su_bfee_cnt > 0 || mu_bfee_cnt > 0) {
  885. /*for 8814 19ac(idx 1), 19b4(idx 0), different Tx ant setting*/
  886. odm_set_bb_reg(p_dm_odm, REG_BB_TXBF_ANT_SET_BF1_8822B, BIT(28) | BIT29, 0x2); /*enable BB TxBF ant mapping register*/
  887. odm_set_bb_reg(p_dm_odm, REG_BB_TXBF_ANT_SET_BF1_8822B, BIT(31), 1); /*ignore user since 8822B only 2Tx*/
  888. /*Nsts = 2 AB*/
  889. odm_set_bb_reg(p_dm_odm, REG_BB_TXBF_ANT_SET_BF1_8822B, 0xffff, 0x0433);
  890. odm_set_bb_reg(p_dm_odm, REG_BB_TX_PATH_SEL_1_8822B, 0xfff00000, 0x043);
  891. } else {
  892. odm_set_bb_reg(p_dm_odm, REG_BB_TXBF_ANT_SET_BF1_8822B, BIT(28) | BIT29, 0x0); /*enable BB TxBF ant mapping register*/
  893. odm_set_bb_reg(p_dm_odm, REG_BB_TXBF_ANT_SET_BF1_8822B, BIT(31), 0); /*ignore user since 8822B only 2Tx*/
  894. odm_set_bb_reg(p_dm_odm, REG_BB_TX_PATH_SEL_1_8822B, 0xfff00000, 0x1); /*1SS by path-A*/
  895. odm_set_bb_reg(p_dm_odm, REG_BB_TX_PATH_SEL_2_8822B, MASKLWORD, 0x430); /*2SS by path-A,B*/
  896. }
  897. }
  898. /*this function is for BFer bug workaround*/
  899. void
  900. phydm_8822b_sutxbfer_workaroud(
  901. void *p_dm_void,
  902. boolean enable_su_bfer,
  903. u8 nc,
  904. u8 nr,
  905. u8 ng,
  906. u8 CB,
  907. u8 BW,
  908. boolean is_vht
  909. )
  910. {
  911. struct PHY_DM_STRUCT *p_dm_odm = (struct PHY_DM_STRUCT *)p_dm_void;
  912. if (enable_su_bfer) {
  913. odm_set_bb_reg(p_dm_odm, 0x19f8, BIT(22) | BIT(21) | BIT(20), 0x1);
  914. odm_set_bb_reg(p_dm_odm, 0x19f8, BIT(25) | BIT(24) | BIT(23), 0x0);
  915. odm_set_bb_reg(p_dm_odm, 0x19f8, BIT(16), 0x1);
  916. if (is_vht)
  917. odm_set_bb_reg(p_dm_odm, 0x19f0, BIT(5) | BIT(4) | BIT(3) | BIT(2) | BIT(1) | BIT(0), 0x1f);
  918. else
  919. odm_set_bb_reg(p_dm_odm, 0x19f0, BIT(5) | BIT(4) | BIT(3) | BIT(2) | BIT(1) | BIT(0), 0x22);
  920. odm_set_bb_reg(p_dm_odm, 0x19f0, BIT(7) | BIT(6), nc);
  921. odm_set_bb_reg(p_dm_odm, 0x19f0, BIT(9) | BIT(8), nr);
  922. odm_set_bb_reg(p_dm_odm, 0x19f0, BIT(11) | BIT(10), ng);
  923. odm_set_bb_reg(p_dm_odm, 0x19f0, BIT(13) | BIT(12), CB);
  924. odm_set_bb_reg(p_dm_odm, 0xb58, BIT(3) | BIT(2), BW);
  925. odm_set_bb_reg(p_dm_odm, 0xb58, BIT(7) | BIT(6) | BIT(5) | BIT(4), 0x0);
  926. odm_set_bb_reg(p_dm_odm, 0xb58, BIT(9) | BIT(8), BW);
  927. odm_set_bb_reg(p_dm_odm, 0xb58, BIT(13) | BIT(12) | BIT(11) | BIT(10), 0x0);
  928. } else
  929. odm_set_bb_reg(p_dm_odm, 0x19f8, BIT(16), 0x0);
  930. ODM_RT_TRACE(p_dm_odm, PHYDM_COMP_TXBF, ODM_DBG_TRACE, ("[%s] enable_su_bfer = %d, is_vht = %d\n", __func__, enable_su_bfer, is_vht));
  931. ODM_RT_TRACE(p_dm_odm, PHYDM_COMP_TXBF, ODM_DBG_TRACE, ("[%s] nc = %d, nr = %d, ng = %d, CB = %d, BW = %d\n", __func__, nc, nr, ng, CB, BW));
  932. }
  933. #endif
  934. #endif /* (RTL8822B_SUPPORT == 1)*/