haltxbf8822b.c 38 KB

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