1 /*============================================================*/
4 /* This file is for 8814A TXBF mechanism */
6 /*============================================================*/
8 #include "mp_precomp.h"
9 #include "phydm_precomp.h"
11 #if (RTL8822B_SUPPORT == 1)
12 #if (BEAMFORMING_SUPPORT == 1)
15 hal_txbf_8822b_get_ntx(
19 struct PHY_DM_STRUCT *p_dm_odm = (struct PHY_DM_STRUCT *)p_dm_void;
22 #if DEV_BUS_TYPE == RT_USB_INTERFACE
23 if (p_dm_odm->support_interface == ODM_ITRF_USB) {
24 if (*p_dm_odm->hub_usb_mode == 2) {/*USB3.0*/
25 if (p_dm_odm->rf_type == ODM_4T4R)
27 else if (p_dm_odm->rf_type == ODM_3T3R)
31 } else if (*p_dm_odm->hub_usb_mode == 1) /*USB 2.0 always 2Tx*/
38 if (p_dm_odm->rf_type == ODM_4T4R)
40 else if (p_dm_odm->rf_type == ODM_3T3R)
51 hal_txbf_8822b_get_nrx(
55 struct PHY_DM_STRUCT *p_dm_odm = (struct PHY_DM_STRUCT *)p_dm_void;
58 if (p_dm_odm->rf_type == ODM_4T4R)
60 else if (p_dm_odm->rf_type == ODM_3T3R)
62 else if (p_dm_odm->rf_type == ODM_2T2R)
64 else if (p_dm_odm->rf_type == ODM_2T3R)
66 else if (p_dm_odm->rf_type == ODM_2T4R)
68 else if (p_dm_odm->rf_type == ODM_1T1R)
70 else if (p_dm_odm->rf_type == ODM_1T2R)
79 /***************SU & MU BFee Entry********************/
81 hal_txbf_8822b_rf_mode(
83 struct _RT_BEAMFORMING_INFO *p_beamforming_info,
88 struct PHY_DM_STRUCT *p_dm_odm = (struct PHY_DM_STRUCT *)p_dm_void;
90 boolean is_self_beamformer = false;
91 boolean is_self_beamformee = false;
92 struct _RT_BEAMFORMEE_ENTRY beamformee_entry;
94 if (idx < BEAMFORMEE_ENTRY_NUM)
95 beamformee_entry = p_beamforming_info->beamformee_entry[idx];
99 if (p_dm_odm->rf_type == ODM_1T1R)
102 for (i = ODM_RF_PATH_A; i < ODM_RF_PATH_B; i++) {
103 odm_set_rf_reg(p_dm_odm, (enum odm_rf_radio_path_e)i, rf_welut_jaguar, 0x80000, 0x1);
104 /*RF mode table write enable*/
107 if ((p_beamforming_info->beamformee_su_cnt > 0) || (p_beamforming_info->beamformee_mu_cnt > 0)) {
108 for (i = ODM_RF_PATH_A; i < ODM_RF_PATH_B; i++) {
109 odm_set_rf_reg(p_dm_odm, (enum odm_rf_radio_path_e)i, rf_mode_table_addr, 0xfffff, 0x18000);
111 odm_set_rf_reg(p_dm_odm, (enum odm_rf_radio_path_e)i, rf_mode_table_data0, 0xfffff, 0xBE77F);
113 odm_set_rf_reg(p_dm_odm, (enum odm_rf_radio_path_e)i, rf_mode_table_data1, 0xfffff, 0x226BF);
114 /*Enable TXIQGEN in RX mode*/
116 odm_set_rf_reg(p_dm_odm, ODM_RF_PATH_A, rf_mode_table_data1, 0xfffff, 0xE26BF);
117 /*Enable TXIQGEN in RX mode*/
120 for (i = ODM_RF_PATH_A; i < ODM_RF_PATH_B; i++) {
121 odm_set_rf_reg(p_dm_odm, (enum odm_rf_radio_path_e)i, rf_welut_jaguar, 0x80000, 0x0);
122 /*RF mode table write disable*/
125 if (p_beamforming_info->beamformee_su_cnt > 0) {
127 /*for 8814 19ac(idx 1), 19b4(idx 0), different Tx ant setting*/
128 odm_set_bb_reg(p_dm_odm, REG_BB_TXBF_ANT_SET_BF1_8822B, BIT(28) | BIT29, 0x2); /*enable BB TxBF ant mapping register*/
132 odm_set_bb_reg(p_dm_odm, REG_BB_TXBF_ANT_SET_BF0_8822B, 0xffff, 0x0433);
133 odm_set_bb_reg(p_dm_odm, REG_BB_TX_PATH_SEL_1_8822B, 0xfff00000, 0x043);
134 /*odm_set_bb_reg(p_dm_odm, REG_BB_TX_PATH_SEL_2, MASKLWORD, 0x430);*/
137 odm_set_bb_reg(p_dm_odm, REG_BB_TXBF_ANT_SET_BF1_8822B, 0xffff, 0x0433);
138 odm_set_bb_reg(p_dm_odm, REG_BB_TX_PATH_SEL_1_8822B, 0xfff00000, 0x043);
139 /*odm_set_bb_reg(p_dm_odm, REG_BB_TX_PATH_SEL_2, MASKLWORD, 0x430;*/
142 odm_set_bb_reg(p_dm_odm, REG_BB_TX_PATH_SEL_1_8822B, 0xfff00000, 0x1); /*1SS by path-A*/
143 odm_set_bb_reg(p_dm_odm, REG_BB_TX_PATH_SEL_2_8822B, MASKLWORD, 0x430); /*2SS by path-A,B*/
146 if (p_beamforming_info->beamformee_mu_cnt > 0) {
147 /*MU STAs share the common setting*/
148 odm_set_bb_reg(p_dm_odm, REG_BB_TXBF_ANT_SET_BF1_8822B, BIT(31), 1);
149 odm_set_bb_reg(p_dm_odm, REG_BB_TXBF_ANT_SET_BF1_8822B, 0xffff, 0x0433);
150 odm_set_bb_reg(p_dm_odm, REG_BB_TX_PATH_SEL_1_8822B, 0xfff00000, 0x043);
156 hal_txbf_8822b_download_ndpa(
157 struct _ADAPTER *adapter,
161 u8 u1b_tmp = 0, tmp_reg422 = 0;
162 u8 bcn_valid_reg = 0, count = 0, dl_bcn_count = 0;
163 u16 head_page = 0x7FE;
164 boolean is_send_beacon = false;
165 HAL_DATA_TYPE *p_hal_data = GET_HAL_DATA(adapter);
166 u16 tx_page_bndy = LAST_ENTRY_OF_TX_PKT_BUFFER_8814A; /*default reseved 1 page for the IC type which is undefined.*/
167 struct _RT_BEAMFORMING_INFO *p_beam_info = GET_BEAMFORM_INFO(adapter);
168 struct _RT_BEAMFORMEE_ENTRY *p_beam_entry = p_beam_info->beamformee_entry + idx;
170 p_hal_data->is_fw_dw_rsvd_page_in_progress = true;
171 phydm_get_hal_def_var_handler_interface(p_dm_odm, HAL_DEF_TX_PAGE_BOUNDARY, (u16 *)&tx_page_bndy);
173 /*Set REG_CR bit 8. DMA beacon by SW.*/
174 u1b_tmp = platform_efio_read_1byte(adapter, REG_CR_8814A + 1);
175 platform_efio_write_1byte(adapter, REG_CR_8814A + 1, (u1b_tmp | BIT(0)));
178 /*Set FWHW_TXQ_CTRL 0x422[6]=0 to tell Hw the packet is not a real beacon frame.*/
179 tmp_reg422 = platform_efio_read_1byte(adapter, REG_FWHW_TXQ_CTRL_8814A + 2);
180 platform_efio_write_1byte(adapter, REG_FWHW_TXQ_CTRL_8814A + 2, tmp_reg422 & (~BIT(6)));
182 if (tmp_reg422 & BIT(6)) {
183 RT_TRACE(COMP_INIT, DBG_LOUD, ("SetBeamformDownloadNDPA_8814A(): There is an adapter is sending beacon.\n"));
184 is_send_beacon = true;
187 /*0x204[11:0] Beacon Head for TXDMA*/
188 platform_efio_write_2byte(adapter, REG_FIFOPAGE_CTRL_2_8814A, head_page);
191 /*Clear beacon valid check bit.*/
192 bcn_valid_reg = platform_efio_read_1byte(adapter, REG_FIFOPAGE_CTRL_2_8814A + 1);
193 platform_efio_write_1byte(adapter, REG_FIFOPAGE_CTRL_2_8814A + 1, (bcn_valid_reg | BIT(7)));
195 /*download NDPA rsvd page.*/
196 if (p_beam_entry->beamform_entry_cap & BEAMFORMER_CAP_VHT_SU)
197 beamforming_send_vht_ndpa_packet(p_dm_odm, p_beam_entry->mac_addr, p_beam_entry->AID, p_beam_entry->sound_bw, BEACON_QUEUE);
199 beamforming_send_ht_ndpa_packet(p_dm_odm, p_beam_entry->mac_addr, p_beam_entry->sound_bw, BEACON_QUEUE);
201 /*check rsvd page download OK.*/
202 bcn_valid_reg = platform_efio_read_1byte(adapter, REG_FIFOPAGE_CTRL_2_8814A + 1);
204 while (!(bcn_valid_reg & BIT(7)) && count < 20) {
207 bcn_valid_reg = platform_efio_read_1byte(adapter, REG_FIFOPAGE_CTRL_2_8814A + 2);
210 } while (!(bcn_valid_reg & BIT(7)) && dl_bcn_count < 5);
212 if (!(bcn_valid_reg & BIT(0)))
213 RT_DISP(FBEAM, FBEAM_ERROR, ("%s Download RSVD page failed!\n", __func__));
215 /*0x204[11:0] Beacon Head for TXDMA*/
216 platform_efio_write_2byte(adapter, REG_FIFOPAGE_CTRL_2_8814A, tx_page_bndy);
218 /*To make sure that if there exists an adapter which would like to send beacon.*/
219 /*If exists, the origianl value of 0x422[6] will be 1, we should check this to*/
220 /*prevent from setting 0x422[6] to 0 after download reserved page, or it will cause */
221 /*the beacon cannot be sent by HW.*/
222 /*2010.06.23. Added by tynli.*/
224 platform_efio_write_1byte(adapter, REG_FWHW_TXQ_CTRL_8814A + 2, tmp_reg422);
226 /*Do not enable HW DMA BCN or it will cause Pcie interface hang by timing issue. 2011.11.24. by tynli.*/
227 /*Clear CR[8] or beacon packet will not be send to TxBuf anymore.*/
228 u1b_tmp = platform_efio_read_1byte(adapter, REG_CR_8814A + 1);
229 platform_efio_write_1byte(adapter, REG_CR_8814A + 1, (u1b_tmp & (~BIT(0))));
231 p_beam_entry->beamform_entry_state = BEAMFORMING_ENTRY_STATE_PROGRESSED;
233 p_hal_data->is_fw_dw_rsvd_page_in_progress = false;
237 hal_txbf_8822b_fw_txbf_cmd(
238 struct _ADAPTER *adapter
242 u8 PageNum0 = 0xFF, PageNum1 = 0xFF;
243 u8 u1_tx_bf_parm[3] = {0};
245 PMGNT_INFO p_mgnt_info = &(adapter->MgntInfo);
246 struct _RT_BEAMFORMING_INFO *p_beam_info = GET_BEAMFORM_INFO(adapter);
248 for (idx = 0; idx < BEAMFORMEE_ENTRY_NUM; idx++) {
249 if (p_beam_info->beamformee_entry[idx].is_used && p_beam_info->beamformee_entry[idx].beamform_entry_state == BEAMFORMING_ENTRY_STATE_PROGRESSED) {
250 if (p_beam_info->beamformee_entry[idx].is_sound) {
253 period = (u8)(p_beam_info->beamformee_entry[idx].sound_period);
254 } else if (PageNum0 == 0xFF) {
255 PageNum0 = 0xFF; /*stop sounding*/
261 u1_tx_bf_parm[0] = PageNum0;
262 u1_tx_bf_parm[1] = PageNum1;
263 u1_tx_bf_parm[2] = period;
264 fill_h2c_cmd(adapter, PHYDM_H2C_TXBF, 3, u1_tx_bf_parm);
266 RT_DISP(FBEAM, FBEAM_FUN, ("@%s End, PageNum0 = 0x%x, PageNum1 = 0x%x period = %d", __func__, PageNum0, PageNum1, period));
276 struct PHY_DM_STRUCT *p_dm_odm = (struct PHY_DM_STRUCT *)p_dm_void;
278 struct _RT_BEAMFORMING_INFO *p_beamforming_info = &p_dm_odm->beamforming_info;
279 struct _ADAPTER *adapter = p_dm_odm->adapter;
281 odm_set_bb_reg(p_dm_odm, 0x14c0, BIT(16), 1); /*Enable P1 aggr new packet according to P0 transfer time*/
282 odm_set_bb_reg(p_dm_odm, 0x14c0, BIT(15) | BIT14 | BIT13 | BIT12, 10); /*MU Retry Limit*/
283 odm_set_bb_reg(p_dm_odm, 0x14c0, BIT(7), 0); /*Disable Tx MU-MIMO until sounding done*/
284 odm_set_bb_reg(p_dm_odm, 0x14c0, 0x3F, 0); /* Clear validity of MU STAs */
285 odm_write_1byte(p_dm_odm, 0x167c, 0x70); /*MU-MIMO Option as default value*/
286 odm_write_2byte(p_dm_odm, 0x1680, 0); /*MU-MIMO Control as default value*/
288 /* Set MU NDPA rate & BW source */
289 /* 0x42C[30] = 1 (0: from Tx desc, 1: from 0x45F) */
290 u1b_tmp = odm_read_1byte(p_dm_odm, 0x42C);
291 odm_write_1byte(p_dm_odm, REG_TXBF_CTRL_8822B, (u1b_tmp | BIT(6)));
292 /* 0x45F[7:0] = 0x10 (rate=OFDM_6M, BW20) */
293 odm_write_1byte(p_dm_odm, REG_NDPA_OPT_CTRL_8822B, 0x10);
296 odm_set_bb_reg(p_dm_odm, 0x6DC, 0x3F000000, 4); /*STA2's CSI rate is fixed at 6M*/
297 odm_set_bb_reg(p_dm_odm, 0x1C94, MASKDWORD, 0xAFFFAFFF); /*Grouping bitmap parameters*/
299 /* Init HW variable */
300 p_beamforming_info->reg_mu_tx_ctrl = odm_read_4byte(p_dm_odm, 0x14c0);
302 if (p_dm_odm->rf_type == ODM_2T2R) { /*2T2R*/
303 ODM_RT_TRACE(p_dm_odm, PHYDM_COMP_TXBF, ODM_DBG_LOUD, ("%s: rf_type is 2T2R\n", __func__));
304 config_phydm_trx_mode_8822b(p_dm_odm, (enum odm_rf_path_e)3, (enum odm_rf_path_e)3, true);/*Tx2path*/
307 #if (OMNIPEEK_SNIFFER_ENABLED == 1)
308 /* Config HW to receive packet on the user position from registry for sniffer mode. */
309 /* odm_set_bb_reg(p_dm_odm, 0xB00, BIT(9), 1);*/ /* For A-cut only. RegB00[9] = 1 (enable PMAC Rx) */
310 odm_set_bb_reg(p_dm_odm, 0xB54, BIT(30), 1); /* RegB54[30] = 1 (force user position) */
311 odm_set_bb_reg(p_dm_odm, 0xB54, (BIT(29) | BIT28), adapter->MgntInfo.sniff_user_position); /* RegB54[29:28] = user position (0~3) */
312 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));
318 hal_txbf_8822b_enter(
323 struct PHY_DM_STRUCT *p_dm_odm = (struct PHY_DM_STRUCT *)p_dm_void;
325 u8 bfer_idx = (bfer_bfee_idx & 0xF0) >> 4;
326 u8 bfee_idx = (bfer_bfee_idx & 0xF);
328 struct _RT_BEAMFORMING_INFO *p_beamforming_info = &p_dm_odm->beamforming_info;
329 struct _RT_BEAMFORMEE_ENTRY *p_beamformee_entry;
330 struct _RT_BEAMFORMER_ENTRY *p_beamformer_entry;
331 u16 value16, sta_id = 0;
332 u8 nc_index = 0, nr_index = 0, grouping = 0, codebookinfo = 0, coefficientsize = 0;
333 u32 gid_valid, user_position_l, user_position_h;
334 u32 mu_reg[6] = {0x1684, 0x1686, 0x1688, 0x168a, 0x168c, 0x168e};
338 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));
340 /*************SU BFer Entry Init*************/
341 if ((p_beamforming_info->beamformer_su_cnt > 0) && (bfer_idx < BEAMFORMER_ENTRY_NUM)) {
342 p_beamformer_entry = &p_beamforming_info->beamformer_entry[bfer_idx];
343 p_beamformer_entry->is_mu_ap = false;
344 /*Sounding protocol control*/
345 odm_write_1byte(p_dm_odm, REG_SND_PTCL_CTRL_8822B, 0xDB);
348 for (i = 0; i < MAX_BEAMFORMER_SU; i++) {
349 if ((p_beamforming_info->beamformer_su_reg_maping & BIT(i)) == 0) {
350 p_beamforming_info->beamformer_su_reg_maping |= BIT(i);
351 p_beamformer_entry->su_reg_index = i;
356 /*MAC address/Partial AID of Beamformer*/
357 if (p_beamformer_entry->su_reg_index == 0) {
358 for (i = 0; i < 6 ; i++)
359 odm_write_1byte(p_dm_odm, (REG_ASSOCIATED_BFMER0_INFO_8822B + i), p_beamformer_entry->mac_addr[i]);
361 for (i = 0; i < 6 ; i++)
362 odm_write_1byte(p_dm_odm, (REG_ASSOCIATED_BFMER1_INFO_8822B + i), p_beamformer_entry->mac_addr[i]);
365 /*CSI report parameters of Beamformer*/
366 nc_index = hal_txbf_8822b_get_nrx(p_dm_odm); /*for 8814A nrx = 3(4 ant), min=0(1 ant)*/
367 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*/
371 /*for ac = 1, for n = 3*/
372 if (p_beamformer_entry->beamform_entry_cap & BEAMFORMEE_CAP_VHT_SU)
374 else if (p_beamformer_entry->beamform_entry_cap & BEAMFORMEE_CAP_HT_EXPLICIT)
379 csi_param = (u16)((coefficientsize << 10) | (codebookinfo << 8) | (grouping << 6) | (nr_index << 3) | (nc_index));
382 odm_write_2byte(p_dm_odm, REG_TX_CSI_RPT_PARAM_BW20_8822B, csi_param);
384 odm_write_2byte(p_dm_odm, REG_TX_CSI_RPT_PARAM_BW20_8822B + 2, csi_param);
385 /*ndp_rx_standby_timer, 8814 need > 0x56, suggest from Dvaid*/
386 odm_write_1byte(p_dm_odm, REG_SND_PTCL_CTRL_8822B + 3, 0x70);
390 /*************SU BFee Entry Init*************/
391 if ((p_beamforming_info->beamformee_su_cnt > 0) && (bfee_idx < BEAMFORMEE_ENTRY_NUM)) {
392 p_beamformee_entry = &p_beamforming_info->beamformee_entry[bfee_idx];
393 p_beamformee_entry->is_mu_sta = false;
394 hal_txbf_8822b_rf_mode(p_dm_odm, p_beamforming_info, bfee_idx);
396 if (phydm_acting_determine(p_dm_odm, phydm_acting_as_ibss))
397 sta_id = p_beamformee_entry->mac_id;
399 sta_id = p_beamformee_entry->p_aid;
401 for (i = 0; i < MAX_BEAMFORMEE_SU; i++) {
402 if ((p_beamforming_info->beamformee_su_reg_maping & BIT(i)) == 0) {
403 p_beamforming_info->beamformee_su_reg_maping |= BIT(i);
404 p_beamformee_entry->su_reg_index = i;
409 /*P_AID of Beamformee & enable NDPA transmission & enable NDPA interrupt*/
410 if (p_beamformee_entry->su_reg_index == 0) {
411 odm_write_2byte(p_dm_odm, REG_TXBF_CTRL_8822B, sta_id);
412 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));
414 odm_write_2byte(p_dm_odm, REG_TXBF_CTRL_8822B + 2, sta_id | BIT(14) | BIT(15) | BIT(12));
416 /*CSI report parameters of Beamformee*/
417 if (p_beamformee_entry->su_reg_index == 0) {
418 /*Get BIT24 & BIT25*/
419 u8 tmp = odm_read_1byte(p_dm_odm, REG_ASSOCIATED_BFMEE_SEL_8822B + 3) & 0x3;
421 odm_write_1byte(p_dm_odm, REG_ASSOCIATED_BFMEE_SEL_8822B + 3, tmp | 0x60);
422 odm_write_2byte(p_dm_odm, REG_ASSOCIATED_BFMEE_SEL_8822B, sta_id | BIT(9));
424 odm_write_2byte(p_dm_odm, REG_ASSOCIATED_BFMEE_SEL_8822B + 2, sta_id | 0xE200); /*Set BIT25*/
426 phydm_beamforming_notify(p_dm_odm);
429 /*************MU BFer Entry Init*************/
430 if ((p_beamforming_info->beamformer_mu_cnt > 0) && (bfer_idx < BEAMFORMER_ENTRY_NUM)) {
431 p_beamformer_entry = &p_beamforming_info->beamformer_entry[bfer_idx];
432 p_beamforming_info->mu_ap_index = bfer_idx;
433 p_beamformer_entry->is_mu_ap = true;
434 for (i = 0; i < 8; i++)
435 p_beamformer_entry->gid_valid[i] = 0;
436 for (i = 0; i < 16; i++)
437 p_beamformer_entry->user_position[i] = 0;
439 /*Sounding protocol control*/
440 odm_write_1byte(p_dm_odm, REG_SND_PTCL_CTRL_8822B, 0xDB);
443 for (i = 0; i < 6 ; i++)
444 odm_write_1byte(p_dm_odm, (REG_ASSOCIATED_BFMER0_INFO_8822B + i), p_beamformer_entry->mac_addr[i]);
446 /* Set partial AID */
447 odm_write_2byte(p_dm_odm, (REG_ASSOCIATED_BFMER0_INFO_8822B + 6), p_beamformer_entry->p_aid);
449 /* Fill our AID to 0x1680[11:0] and [13:12] = 2b'00, BF report segment select to 3895 bytes*/
450 u1b_tmp = odm_read_1byte(p_dm_odm, 0x1680);
451 u1b_tmp = (p_beamformer_entry->p_aid) & 0xFFF;
452 odm_write_1byte(p_dm_odm, 0x1680, u1b_tmp);
454 /* Set 80us for leaving ndp_rx_standby_state */
455 odm_write_1byte(p_dm_odm, 0x71B, 0x50);
457 /* Set 0x6A0[14] = 1 to accept action_no_ack */
458 u1b_tmp = odm_read_1byte(p_dm_odm, REG_RXFLTMAP0_8822B + 1);
460 odm_write_1byte(p_dm_odm, REG_RXFLTMAP0_8822B + 1, u1b_tmp);
461 /* Set 0x6A2[5:4] = 1 to NDPA and BF report poll */
462 u1b_tmp = odm_read_1byte(p_dm_odm, REG_RXFLTMAP1_8822B);
464 odm_write_1byte(p_dm_odm, REG_RXFLTMAP1_8822B, u1b_tmp);
466 /*CSI report parameters of Beamformer*/
467 nc_index = hal_txbf_8822b_get_nrx(p_dm_odm); /* Depend on RF type */
468 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*/
469 grouping = 0; /*no grouping*/
470 codebookinfo = 1; /*7 bit for psi, 9 bit for phi*/
471 coefficientsize = 0; /*This is nothing really matter*/
472 csi_param = (u16)((coefficientsize << 10) | (codebookinfo << 8) | (grouping << 6) | (nr_index << 3) | (nc_index));
473 odm_write_2byte(p_dm_odm, 0x6F4, csi_param);
476 odm_set_bb_reg(p_dm_odm, 0x6A0, BIT(20), 0);
477 odm_set_bb_reg(p_dm_odm, 0x688, BIT(20), 0);
481 /*************MU BFee Entry Init*************/
482 if ((p_beamforming_info->beamformee_mu_cnt > 0) && (bfee_idx < BEAMFORMEE_ENTRY_NUM)) {
483 p_beamformee_entry = &p_beamforming_info->beamformee_entry[bfee_idx];
484 p_beamformee_entry->is_mu_sta = true;
485 for (i = 0; i < MAX_BEAMFORMEE_MU; i++) {
486 if ((p_beamforming_info->beamformee_mu_reg_maping & BIT(i)) == 0) {
487 p_beamforming_info->beamformee_mu_reg_maping |= BIT(i);
488 p_beamformee_entry->mu_reg_index = i;
493 if (p_beamformee_entry->mu_reg_index == 0xFF) {
494 /* There is no valid bit in beamformee_mu_reg_maping */
495 RT_DISP(FBEAM, FBEAM_FUN, ("%s: ERROR! There is no valid bit in beamformee_mu_reg_maping!\n", __func__));
499 /*User position table*/
500 switch (p_beamformee_entry->mu_reg_index) {
503 user_position_l = 0x111110;
504 user_position_h = 0x0;
508 user_position_l = 0x11000004;
509 user_position_h = 0x11;
512 gid_valid = 0x1f81818;
513 user_position_l = 0x400040;
514 user_position_h = 0x11100;
517 gid_valid = 0x1e186060;
518 user_position_l = 0x4000400;
519 user_position_h = 0x1100040;
522 gid_valid = 0x66618180;
523 user_position_l = 0x40004000;
524 user_position_h = 0x10040400;
527 gid_valid = 0x79860600;
528 user_position_l = 0x40000;
529 user_position_h = 0x4404004;
533 for (i = 0; i < 8; i++) {
535 p_beamformee_entry->gid_valid[i] = (u8)(gid_valid & 0xFF);
536 gid_valid = (gid_valid >> 8);
538 p_beamformee_entry->gid_valid[i] = 0;
540 for (i = 0; i < 16; i++) {
542 p_beamformee_entry->user_position[i] = (u8)((user_position_l >> (i * 8)) & 0xFF);
544 p_beamformee_entry->user_position[i] = (u8)((user_position_h >> ((i - 4) * 8)) & 0xFF);
546 p_beamformee_entry->user_position[i] = 0;
549 /*Sounding protocol control*/
550 odm_write_1byte(p_dm_odm, REG_SND_PTCL_CTRL_8822B, 0xDB);
552 /*select MU STA table*/
553 p_beamforming_info->reg_mu_tx_ctrl &= ~(BIT(8) | BIT(9) | BIT(10));
554 p_beamforming_info->reg_mu_tx_ctrl |= (p_beamformee_entry->mu_reg_index << 8) & (BIT(8) | BIT(9) | BIT(10));
555 odm_write_4byte(p_dm_odm, 0x14c0, p_beamforming_info->reg_mu_tx_ctrl);
557 odm_set_bb_reg(p_dm_odm, 0x14c4, MASKDWORD, 0); /*Reset gid_valid table*/
558 odm_set_bb_reg(p_dm_odm, 0x14c8, MASKDWORD, user_position_l);
559 odm_set_bb_reg(p_dm_odm, 0x14cc, MASKDWORD, user_position_h);
561 /*set validity of MU STAs*/
562 p_beamforming_info->reg_mu_tx_ctrl &= 0xFFFFFFC0;
563 p_beamforming_info->reg_mu_tx_ctrl |= p_beamforming_info->beamformee_mu_reg_maping & 0x3F;
564 odm_write_4byte(p_dm_odm, 0x14c0, p_beamforming_info->reg_mu_tx_ctrl);
566 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",
567 __func__, p_beamforming_info->reg_mu_tx_ctrl, user_position_l, user_position_h));
569 value16 = odm_read_2byte(p_dm_odm, mu_reg[p_beamformee_entry->mu_reg_index]);
570 value16 &= 0xFE00; /*Clear PAID*/
571 value16 |= BIT(9); /*Enable MU BFee*/
572 value16 |= p_beamformee_entry->p_aid;
573 odm_write_2byte(p_dm_odm, mu_reg[p_beamformee_entry->mu_reg_index], value16);
575 /* 0x42C[30] = 1 (0: from Tx desc, 1: from 0x45F) */
576 u1b_tmp = odm_read_1byte(p_dm_odm, REG_TXBF_CTRL_8822B + 3);
577 u1b_tmp |= 0xD0; /* Set bit 28, 30, 31 to 3b'111*/
578 odm_write_1byte(p_dm_odm, REG_TXBF_CTRL_8822B + 3, u1b_tmp);
580 odm_write_1byte(p_dm_odm, REG_NDPA_RATE_8822B, 0x4);
582 u1b_tmp = odm_read_1byte(p_dm_odm, REG_NDPA_OPT_CTRL_8822B);
583 u1b_tmp &= 0xFC; /* Clear bit 0, 1*/
584 odm_write_1byte(p_dm_odm, REG_NDPA_OPT_CTRL_8822B, u1b_tmp);
586 u4b_tmp = odm_read_4byte(p_dm_odm, REG_SND_PTCL_CTRL_8822B);
587 u4b_tmp = ((u4b_tmp & 0xFF0000FF) | 0x020200); /* Set [23:8] to 0x0202*/
588 odm_write_4byte(p_dm_odm, REG_SND_PTCL_CTRL_8822B, u4b_tmp);
590 /* Set 0x6A0[14] = 1 to accept action_no_ack */
591 u1b_tmp = odm_read_1byte(p_dm_odm, REG_RXFLTMAP0_8822B + 1);
593 odm_write_1byte(p_dm_odm, REG_RXFLTMAP0_8822B + 1, u1b_tmp);
594 /* End of MAC registers setting */
596 hal_txbf_8822b_rf_mode(p_dm_odm, p_beamforming_info, bfee_idx);
597 #if (SUPPORT_MU_BF == 1)
598 /*Special for plugfest*/
599 delay_ms(50); /* wait for 4-way handshake ending*/
600 send_sw_vht_gid_mgnt_frame(p_dm_odm, p_beamformee_entry->mac_addr, bfee_idx);
603 phydm_beamforming_notify(p_dm_odm);
606 u32 ctrl_info_offset, index;
608 odm_write_2byte(p_dm_odm, 0x140, 0x660);
609 ctrl_info_offset = 0x8000 + 32 * p_beamformee_entry->mac_id;
611 for (index = 0; index < 8; index++)
612 odm_write_4byte(p_dm_odm, ctrl_info_offset + index * 4, 0);
614 odm_write_4byte(p_dm_odm, ctrl_info_offset, (p_beamformee_entry->mu_reg_index + 1) << 16);
615 odm_write_1byte(p_dm_odm, 0x81, 0x80); /*RPTBUF ready*/
617 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",
618 __func__, p_beamformee_entry->mac_id, ctrl_info_offset, p_beamformee_entry->mu_reg_index));
627 hal_txbf_8822b_leave(
632 struct PHY_DM_STRUCT *p_dm_odm = (struct PHY_DM_STRUCT *)p_dm_void;
633 struct _RT_BEAMFORMING_INFO *p_beamforming_info = &p_dm_odm->beamforming_info;
634 struct _RT_BEAMFORMER_ENTRY *p_beamformer_entry;
635 struct _RT_BEAMFORMEE_ENTRY *p_beamformee_entry;
636 u32 mu_reg[6] = {0x1684, 0x1686, 0x1688, 0x168a, 0x168c, 0x168e};
638 if (idx < BEAMFORMER_ENTRY_NUM) {
639 p_beamformer_entry = &p_beamforming_info->beamformer_entry[idx];
640 p_beamformee_entry = &p_beamforming_info->beamformee_entry[idx];
644 /*Clear P_AID of Beamformee*/
645 /*Clear MAC address of Beamformer*/
646 /*Clear Associated Bfmee Sel*/
648 if (p_beamformer_entry->beamform_entry_cap == BEAMFORMING_CAP_NONE) {
649 odm_write_1byte(p_dm_odm, REG_SND_PTCL_CTRL_8822B, 0xD8);
650 if (p_beamformer_entry->is_mu_ap == 0) { /*SU BFer */
651 if (p_beamformer_entry->su_reg_index == 0) {
652 odm_write_4byte(p_dm_odm, REG_ASSOCIATED_BFMER0_INFO_8822B, 0);
653 odm_write_2byte(p_dm_odm, REG_ASSOCIATED_BFMER0_INFO_8822B + 4, 0);
654 odm_write_2byte(p_dm_odm, REG_TX_CSI_RPT_PARAM_BW20_8822B, 0);
656 odm_write_4byte(p_dm_odm, REG_ASSOCIATED_BFMER1_INFO_8822B, 0);
657 odm_write_2byte(p_dm_odm, REG_ASSOCIATED_BFMER1_INFO_8822B + 4, 0);
658 odm_write_2byte(p_dm_odm, REG_TX_CSI_RPT_PARAM_BW20_8822B + 2, 0);
660 p_beamforming_info->beamformer_su_reg_maping &= ~(BIT(p_beamformer_entry->su_reg_index));
661 p_beamformer_entry->su_reg_index = 0xFF;
662 } else { /*MU BFer */
663 /*set validity of MU STA0 and MU STA1*/
664 p_beamforming_info->reg_mu_tx_ctrl &= 0xFFFFFFC0;
665 odm_write_4byte(p_dm_odm, 0x14c0, p_beamforming_info->reg_mu_tx_ctrl);
667 odm_memory_set(p_dm_odm, p_beamformer_entry->gid_valid, 0, 8);
668 odm_memory_set(p_dm_odm, p_beamformer_entry->user_position, 0, 16);
669 p_beamformer_entry->is_mu_ap = false;
673 if (p_beamformee_entry->beamform_entry_cap == BEAMFORMING_CAP_NONE) {
674 hal_txbf_8822b_rf_mode(p_dm_odm, p_beamforming_info, idx);
675 if (p_beamformee_entry->is_mu_sta == 0) { /*SU BFee*/
676 if (p_beamformee_entry->su_reg_index == 0) {
677 odm_write_2byte(p_dm_odm, REG_TXBF_CTRL_8822B, 0x0);
678 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));
679 odm_write_2byte(p_dm_odm, REG_ASSOCIATED_BFMEE_SEL_8822B, 0);
681 odm_write_2byte(p_dm_odm, REG_TXBF_CTRL_8822B + 2, 0x0 | BIT(14) | BIT(15) | BIT(12));
683 odm_write_2byte(p_dm_odm, REG_ASSOCIATED_BFMEE_SEL_8822B + 2,
684 odm_read_2byte(p_dm_odm, REG_ASSOCIATED_BFMEE_SEL_8822B + 2) & 0x60);
686 p_beamforming_info->beamformee_su_reg_maping &= ~(BIT(p_beamformee_entry->su_reg_index));
687 p_beamformee_entry->su_reg_index = 0xFF;
688 } else { /*MU BFee */
689 /*Disable sending NDPA & BF-rpt-poll to this BFee*/
690 odm_write_2byte(p_dm_odm, mu_reg[p_beamformee_entry->mu_reg_index], 0);
691 /*set validity of MU STA*/
692 p_beamforming_info->reg_mu_tx_ctrl &= ~(BIT(p_beamformee_entry->mu_reg_index));
693 odm_write_4byte(p_dm_odm, 0x14c0, p_beamforming_info->reg_mu_tx_ctrl);
696 p_beamformee_entry->is_mu_sta = false;
697 p_beamforming_info->beamformee_mu_reg_maping &= ~(BIT(p_beamformee_entry->mu_reg_index));
698 p_beamformee_entry->mu_reg_index = 0xFF;
704 /***********SU & MU BFee Entry Only when souding done****************/
706 hal_txbf_8822b_status(
711 struct PHY_DM_STRUCT *p_dm_odm = (struct PHY_DM_STRUCT *)p_dm_void;
712 u16 beam_ctrl_val, tmp_val;
714 struct _RT_BEAMFORMING_INFO *p_beamforming_info = &p_dm_odm->beamforming_info;
715 struct _RT_BEAMFORMEE_ENTRY *p_beamform_entry;
716 boolean is_mu_sounding = p_beamforming_info->is_mu_sounding, is_bitmap_ready = false;
720 u32 gid_valid[6] = {0};
721 u32 user_position_lsb[6] = {0};
722 u32 user_position_msb[6] = {0};
724 boolean is_sounding_success[6] = {false};
726 if (beamform_idx < BEAMFORMEE_ENTRY_NUM)
727 p_beamform_entry = &p_beamforming_info->beamformee_entry[beamform_idx];
731 /*SU sounding done */
732 if (is_mu_sounding == false) {
734 if (phydm_acting_determine(p_dm_odm, phydm_acting_as_ibss))
735 beam_ctrl_val = p_beamform_entry->mac_id;
737 beam_ctrl_val = p_beamform_entry->p_aid;
739 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));
741 if (p_beamform_entry->su_reg_index == 0)
742 beam_ctrl_reg = REG_TXBF_CTRL_8822B;
744 beam_ctrl_reg = REG_TXBF_CTRL_8822B + 2;
745 beam_ctrl_val |= BIT(12) | BIT(14) | BIT(15);
748 if (p_beamform_entry->beamform_entry_state == BEAMFORMING_ENTRY_STATE_PROGRESSED) {
749 if (p_beamform_entry->sound_bw == CHANNEL_WIDTH_20)
750 beam_ctrl_val |= BIT(9);
751 else if (p_beamform_entry->sound_bw == CHANNEL_WIDTH_40)
752 beam_ctrl_val |= (BIT(9) | BIT(10));
753 else if (p_beamform_entry->sound_bw == CHANNEL_WIDTH_80)
754 beam_ctrl_val |= (BIT(9) | BIT(10) | BIT(11));
756 ODM_RT_TRACE(p_dm_odm, PHYDM_COMP_TXBF, ODM_DBG_LOUD, ("@%s, Don't apply Vmatrix", __func__));
757 beam_ctrl_val &= ~(BIT(9) | BIT(10) | BIT(11));
760 odm_write_2byte(p_dm_odm, beam_ctrl_reg, beam_ctrl_val);
761 /*disable NDP packet use beamforming */
762 tmp_val = odm_read_2byte(p_dm_odm, REG_TXBF_CTRL_8822B);
763 odm_write_2byte(p_dm_odm, REG_TXBF_CTRL_8822B, tmp_val | BIT(15));
765 ODM_RT_TRACE(p_dm_odm, PHYDM_COMP_TXBF, ODM_DBG_LOUD, ("@%s, MU Sounding Done\n", __func__));
766 /*MU sounding done */
767 if (1) { /* (p_beamform_entry->beamform_entry_state == BEAMFORMING_ENTRY_STATE_PROGRESSED) { */
768 ODM_RT_TRACE(p_dm_odm, PHYDM_COMP_TXBF, ODM_DBG_LOUD, ("@%s, BEAMFORMING_ENTRY_STATE_PROGRESSED\n", __func__));
770 value32 = odm_get_bb_reg(p_dm_odm, 0x1684, MASKDWORD);
771 is_sounding_success[0] = (value32 & BIT(10)) ? 1 : 0;
772 is_sounding_success[1] = (value32 & BIT(26)) ? 1 : 0;
773 value32 = odm_get_bb_reg(p_dm_odm, 0x1688, MASKDWORD);
774 is_sounding_success[2] = (value32 & BIT(10)) ? 1 : 0;
775 is_sounding_success[3] = (value32 & BIT(26)) ? 1 : 0;
776 value32 = odm_get_bb_reg(p_dm_odm, 0x168C, MASKDWORD);
777 is_sounding_success[4] = (value32 & BIT(10)) ? 1 : 0;
778 is_sounding_success[5] = (value32 & BIT(26)) ? 1 : 0;
780 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",
781 __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]));
783 value32 = odm_get_bb_reg(p_dm_odm, 0xF4C, 0xFFFF0000);
784 /* odm_set_bb_reg(p_dm_odm, 0x19E0, MASKHWORD, 0xFFFF);Let MAC ignore bitmap */
786 is_bitmap_ready = (boolean)((value32 & BIT(15)) >> 15);
787 bitmap = (u16)(value32 & 0x3FFF);
789 for (idx = 0; idx < 15; idx++) {
790 if (idx < 5) {/*bit0~4*/
793 } else if (idx < 9) { /*bit5~8*/
796 } else if (idx < 12) { /*bit9~11*/
799 } else if (idx < 14) { /*bit12~13*/
806 if (bitmap & BIT(idx)) {
808 gid = (idx << 1) + 1;
809 gid_valid[id0] |= (BIT(gid));
810 gid_valid[id1] |= (BIT(gid));
813 gid_valid[id0] |= (BIT(gid));
814 gid_valid[id1] |= (BIT(gid));
817 gid = (idx << 1) + 1;
818 gid_valid[id0] &= ~(BIT(gid));
819 gid_valid[id1] &= ~(BIT(gid));
822 gid_valid[id0] &= ~(BIT(gid));
823 gid_valid[id1] &= ~(BIT(gid));
827 for (i = 0; i < BEAMFORMEE_ENTRY_NUM; i++) {
828 p_beamform_entry = &p_beamforming_info->beamformee_entry[i];
829 if ((p_beamform_entry->is_mu_sta) && (p_beamform_entry->mu_reg_index < 6)) {
830 value32 = gid_valid[p_beamform_entry->mu_reg_index];
831 for (idx = 0; idx < 4; idx++) {
832 p_beamform_entry->gid_valid[idx] = (u8)(value32 & 0xFF);
833 value32 = (value32 >> 8);
838 for (idx = 0; idx < 6; idx++) {
839 p_beamforming_info->reg_mu_tx_ctrl &= ~(BIT(8) | BIT(9) | BIT(10));
840 p_beamforming_info->reg_mu_tx_ctrl |= ((idx << 8) & (BIT(8) | BIT(9) | BIT(10)));
841 odm_write_4byte(p_dm_odm, 0x14c0, p_beamforming_info->reg_mu_tx_ctrl);
842 odm_set_mac_reg(p_dm_odm, 0x14C4, MASKDWORD, gid_valid[idx]); /*set MU STA gid valid table*/
846 if (p_beamforming_info->dbg_disable_mu_tx == false)
847 p_beamforming_info->reg_mu_tx_ctrl |= BIT(7);
849 p_beamforming_info->reg_mu_tx_ctrl &= ~BIT(7);
850 odm_write_4byte(p_dm_odm, 0x14c0, p_beamforming_info->reg_mu_tx_ctrl);
855 /*Only used for MU BFer Entry when get GID management frame (self is as MU STA)*/
857 hal_txbf_8822b_config_gtab(
861 struct PHY_DM_STRUCT *p_dm_odm = (struct PHY_DM_STRUCT *)p_dm_void;
862 struct _RT_BEAMFORMING_INFO *p_beamforming_info = &p_dm_odm->beamforming_info;
863 struct _RT_BEAMFORMER_ENTRY *p_beamformer_entry = NULL;
864 u32 gid_valid = 0, user_position_l = 0, user_position_h = 0, i;
866 if (p_beamforming_info->mu_ap_index < BEAMFORMER_ENTRY_NUM)
867 p_beamformer_entry = &p_beamforming_info->beamformer_entry[p_beamforming_info->mu_ap_index];
871 ODM_RT_TRACE(p_dm_odm, PHYDM_COMP_TXBF, ODM_DBG_LOUD, ("%s==>\n", __func__));
874 for (i = 0; i < 4; i++)
875 gid_valid |= (p_beamformer_entry->gid_valid[i] << (i << 3));
876 for (i = 0; i < 8; i++) {
878 user_position_l |= (p_beamformer_entry->user_position[i] << (i << 3));
880 user_position_h |= (p_beamformer_entry->user_position[i] << ((i - 4) << 3));
882 /*select MU STA0 table*/
883 p_beamforming_info->reg_mu_tx_ctrl &= ~(BIT(8) | BIT(9) | BIT(10));
884 odm_write_4byte(p_dm_odm, 0x14c0, p_beamforming_info->reg_mu_tx_ctrl);
885 odm_set_bb_reg(p_dm_odm, 0x14c4, MASKDWORD, gid_valid);
886 odm_set_bb_reg(p_dm_odm, 0x14c8, MASKDWORD, user_position_l);
887 odm_set_bb_reg(p_dm_odm, 0x14cc, MASKDWORD, user_position_h);
889 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",
890 __func__, gid_valid, user_position_l, user_position_h));
897 for (i = 4; i < 8; i++)
898 gid_valid |= (p_beamformer_entry->gid_valid[i] << ((i - 4) << 3));
899 for (i = 8; i < 16; i++) {
901 user_position_l |= (p_beamformer_entry->user_position[i] << ((i - 8) << 3));
903 user_position_h |= (p_beamformer_entry->user_position[i] << ((i - 12) << 3));
905 /*select MU STA1 table*/
906 p_beamforming_info->reg_mu_tx_ctrl &= ~(BIT(8) | BIT(9) | BIT(10));
907 p_beamforming_info->reg_mu_tx_ctrl |= BIT(8);
908 odm_write_4byte(p_dm_odm, 0x14c0, p_beamforming_info->reg_mu_tx_ctrl);
909 odm_set_bb_reg(p_dm_odm, 0x14c4, MASKDWORD, gid_valid);
910 odm_set_bb_reg(p_dm_odm, 0x14c8, MASKDWORD, user_position_l);
911 odm_set_bb_reg(p_dm_odm, 0x14cc, MASKDWORD, user_position_h);
913 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",
914 __func__, gid_valid, user_position_l, user_position_h));
916 /* Set validity of MU STA0 and MU STA1*/
917 p_beamforming_info->reg_mu_tx_ctrl &= 0xFFFFFFC0;
918 p_beamforming_info->reg_mu_tx_ctrl |= 0x3; /* STA0, STA1*/
919 odm_write_4byte(p_dm_odm, 0x14c0, p_beamforming_info->reg_mu_tx_ctrl);
926 /*This function translate the bitmap to GTAB*/
928 haltxbf8822b_gtab_translation(
929 struct PHY_DM_STRUCT *p_dm_odm
934 u32 gid_valid[6] = {0};
935 u32 user_position_lsb[6] = {0};
936 u32 user_position_msb[6] = {0};
938 for (idx = 0; idx < 15; idx++) {
939 if (idx < 5) {/*bit0~4*/
942 } else if (idx < 9) { /*bit5~8*/
945 } else if (idx < 12) { /*bit9~11*/
948 } else if (idx < 14) { /*bit12~13*/
957 gid = (idx << 1) + 1;
958 gid_valid[id0] |= (1 << gid);
959 gid_valid[id1] |= (1 << gid);
961 /*user_position_lsb[id0] |= (0 << (gid << 1));*/
962 user_position_lsb[id1] |= (1 << (gid << 1));
964 /*user_position_msb[id0] |= (0 << ((gid - 16) << 1));*/
965 user_position_msb[id1] |= (1 << ((gid - 16) << 1));
970 gid_valid[id0] |= (1 << gid);
971 gid_valid[id1] |= (1 << gid);
973 user_position_lsb[id0] |= (1 << (gid << 1));
974 /*user_position_lsb[id1] |= (0 << (gid << 1));*/
976 user_position_msb[id0] |= (1 << ((gid - 16) << 1));
977 /*user_position_msb[id1] |= (0 << ((gid - 16) << 1));*/
983 for (idx = 0; idx < 6; idx++) {
984 /*dbg_print("gid_valid[%d] = 0x%x\n", idx, gid_valid[idx]);
985 dbg_print("user_position[%d] = 0x%x %x\n", idx, user_position_msb[idx], user_position_lsb[idx]);*/
991 hal_txbf_8822b_fw_txbf(
997 struct _RT_BEAMFORMING_INFO *p_beam_info = GET_BEAMFORM_INFO(adapter);
998 struct _RT_BEAMFORMEE_ENTRY *p_beam_entry = p_beam_info->beamformee_entry + idx;
1000 if (p_beam_entry->beamform_entry_state == BEAMFORMING_ENTRY_STATE_PROGRESSING)
1001 hal_txbf_8822b_download_ndpa(adapter, idx);
1003 hal_txbf_8822b_fw_txbf_cmd(adapter);
1009 #if (defined(CONFIG_BB_TXBF_API))
1010 /*this function is only used for BFer*/
1012 phydm_8822btxbf_rfmode(
1018 struct PHY_DM_STRUCT *p_dm_odm = (struct PHY_DM_STRUCT *)p_dm_void;
1021 if (p_dm_odm->rf_type == ODM_1T1R)
1024 if ((su_bfee_cnt > 0) || (mu_bfee_cnt > 0)) {
1025 for (i = ODM_RF_PATH_A; i <= ODM_RF_PATH_B; i++) {
1026 odm_set_rf_reg(p_dm_odm, (enum odm_rf_radio_path_e)i, 0xEF, BIT(19), 0x1); /*RF mode table write enable*/
1027 odm_set_rf_reg(p_dm_odm, (enum odm_rf_radio_path_e)i, 0x33, 0xF, 3); /*Select RX mode*/
1028 odm_set_rf_reg(p_dm_odm, (enum odm_rf_radio_path_e)i, 0x3E, 0xfffff, 0x00036); /*Set Table data*/
1029 odm_set_rf_reg(p_dm_odm, (enum odm_rf_radio_path_e)i, 0x3F, 0xfffff, 0x5AFCE); /*Set Table data*/
1030 odm_set_rf_reg(p_dm_odm, (enum odm_rf_radio_path_e)i, 0xEF, BIT(19), 0x0); /*RF mode table write disable*/
1034 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*/
1036 if (su_bfee_cnt > 0 || mu_bfee_cnt > 0) {
1037 /*for 8814 19ac(idx 1), 19b4(idx 0), different Tx ant setting*/
1038 odm_set_bb_reg(p_dm_odm, REG_BB_TXBF_ANT_SET_BF1_8822B, BIT(28) | BIT29, 0x2); /*enable BB TxBF ant mapping register*/
1039 odm_set_bb_reg(p_dm_odm, REG_BB_TXBF_ANT_SET_BF1_8822B, BIT(31), 1); /*ignore user since 8822B only 2Tx*/
1043 odm_set_bb_reg(p_dm_odm, REG_BB_TXBF_ANT_SET_BF1_8822B, 0xffff, 0x0433);
1044 odm_set_bb_reg(p_dm_odm, REG_BB_TX_PATH_SEL_1_8822B, 0xfff00000, 0x043);
1047 odm_set_bb_reg(p_dm_odm, REG_BB_TXBF_ANT_SET_BF1_8822B, BIT(28) | BIT29, 0x0); /*enable BB TxBF ant mapping register*/
1048 odm_set_bb_reg(p_dm_odm, REG_BB_TXBF_ANT_SET_BF1_8822B, BIT(31), 0); /*ignore user since 8822B only 2Tx*/
1050 odm_set_bb_reg(p_dm_odm, REG_BB_TX_PATH_SEL_1_8822B, 0xfff00000, 0x1); /*1SS by path-A*/
1051 odm_set_bb_reg(p_dm_odm, REG_BB_TX_PATH_SEL_2_8822B, MASKLWORD, 0x430); /*2SS by path-A,B*/
1057 /*this function is for BFer bug workaround*/
1059 phydm_8822b_sutxbfer_workaroud(
1061 boolean enable_su_bfer,
1070 struct PHY_DM_STRUCT *p_dm_odm = (struct PHY_DM_STRUCT *)p_dm_void;
1072 if (enable_su_bfer) {
1073 odm_set_bb_reg(p_dm_odm, 0x19f8, BIT(22) | BIT(21) | BIT(20), 0x1);
1074 odm_set_bb_reg(p_dm_odm, 0x19f8, BIT(25) | BIT(24) | BIT(23), 0x0);
1075 odm_set_bb_reg(p_dm_odm, 0x19f8, BIT(16), 0x1);
1078 odm_set_bb_reg(p_dm_odm, 0x19f0, BIT(5) | BIT(4) | BIT(3) | BIT(2) | BIT(1) | BIT(0), 0x1f);
1080 odm_set_bb_reg(p_dm_odm, 0x19f0, BIT(5) | BIT(4) | BIT(3) | BIT(2) | BIT(1) | BIT(0), 0x22);
1082 odm_set_bb_reg(p_dm_odm, 0x19f0, BIT(7) | BIT(6), nc);
1083 odm_set_bb_reg(p_dm_odm, 0x19f0, BIT(9) | BIT(8), nr);
1084 odm_set_bb_reg(p_dm_odm, 0x19f0, BIT(11) | BIT(10), ng);
1085 odm_set_bb_reg(p_dm_odm, 0x19f0, BIT(13) | BIT(12), CB);
1087 odm_set_bb_reg(p_dm_odm, 0xb58, BIT(3) | BIT(2), BW);
1088 odm_set_bb_reg(p_dm_odm, 0xb58, BIT(7) | BIT(6) | BIT(5) | BIT(4), 0x0);
1089 odm_set_bb_reg(p_dm_odm, 0xb58, BIT(9) | BIT(8), BW);
1090 odm_set_bb_reg(p_dm_odm, 0xb58, BIT(13) | BIT(12) | BIT(11) | BIT(10), 0x0);
1092 odm_set_bb_reg(p_dm_odm, 0x19f8, BIT(16), 0x0);
1094 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));
1095 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));
1100 #endif /* (RTL8822B_SUPPORT == 1)*/