net: wireless: rockchip_wlan: add rtl8723cs support
[firefly-linux-kernel-4.4.55.git] / drivers / net / wireless / rockchip_wlan / rtl8723cs / hal / phydm / txbf / haltxbf8822b.c
1 /*============================================================*/
2 /* Description:                                              */
3 /*                                                           */
4 /* This file is for 8814A TXBF mechanism                     */
5 /*                                                           */
6 /*============================================================*/
7
8 #include "mp_precomp.h"
9 #include "phydm_precomp.h"
10
11 #if (RTL8822B_SUPPORT == 1)
12 #if (BEAMFORMING_SUPPORT == 1)
13
14 u8
15 hal_txbf_8822b_get_ntx(
16         void                    *p_dm_void
17 )
18 {
19         struct PHY_DM_STRUCT    *p_dm_odm = (struct PHY_DM_STRUCT *)p_dm_void;
20         u8                      ntx = 0;
21
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)
26                                 ntx = 3;
27                         else if (p_dm_odm->rf_type == ODM_3T3R)
28                                 ntx = 2;
29                         else
30                                 ntx = 1;
31                 } else if (*p_dm_odm->hub_usb_mode == 1)        /*USB 2.0 always 2Tx*/
32                         ntx = 1;
33                 else
34                         ntx = 1;
35         } else
36 #endif
37         {
38                 if (p_dm_odm->rf_type == ODM_4T4R)
39                         ntx = 3;
40                 else if (p_dm_odm->rf_type == ODM_3T3R)
41                         ntx = 2;
42                 else
43                         ntx = 1;
44         }
45
46         return ntx;
47
48 }
49
50 u8
51 hal_txbf_8822b_get_nrx(
52         void                    *p_dm_void
53 )
54 {
55         struct PHY_DM_STRUCT    *p_dm_odm = (struct PHY_DM_STRUCT *)p_dm_void;
56         u8                      nrx = 0;
57
58         if (p_dm_odm->rf_type == ODM_4T4R)
59                 nrx = 3;
60         else if (p_dm_odm->rf_type == ODM_3T3R)
61                 nrx = 2;
62         else if (p_dm_odm->rf_type == ODM_2T2R)
63                 nrx = 1;
64         else if (p_dm_odm->rf_type == ODM_2T3R)
65                 nrx = 2;
66         else if (p_dm_odm->rf_type == ODM_2T4R)
67                 nrx = 3;
68         else if (p_dm_odm->rf_type == ODM_1T1R)
69                 nrx = 0;
70         else if (p_dm_odm->rf_type == ODM_1T2R)
71                 nrx = 1;
72         else
73                 nrx = 0;
74
75         return nrx;
76
77 }
78
79 /***************SU & MU BFee Entry********************/
80 void
81 hal_txbf_8822b_rf_mode(
82         void                    *p_dm_void,
83         struct _RT_BEAMFORMING_INFO     *p_beamforming_info,
84         u8                                      idx
85 )
86 {
87 #if 0
88         struct PHY_DM_STRUCT    *p_dm_odm = (struct PHY_DM_STRUCT *)p_dm_void;
89         u8                              i, nr_index = 0;
90         boolean                         is_self_beamformer = false;
91         boolean                         is_self_beamformee = false;
92         struct _RT_BEAMFORMEE_ENTRY     beamformee_entry;
93
94         if (idx < BEAMFORMEE_ENTRY_NUM)
95                 beamformee_entry = p_beamforming_info->beamformee_entry[idx];
96         else
97                 return;
98
99         if (p_dm_odm->rf_type == ODM_1T1R)
100                 return;
101
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*/
105         }
106
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);
110                         /*Select RX mode*/
111                         odm_set_rf_reg(p_dm_odm, (enum odm_rf_radio_path_e)i, rf_mode_table_data0, 0xfffff, 0xBE77F);
112                         /*Set Table data*/
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*/
115                 }
116                 odm_set_rf_reg(p_dm_odm, ODM_RF_PATH_A, rf_mode_table_data1, 0xfffff, 0xE26BF);
117                 /*Enable TXIQGEN in RX mode*/
118         }
119
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*/
123         }
124
125         if (p_beamforming_info->beamformee_su_cnt > 0) {
126
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*/
129
130                 if (idx == 0) {
131                         /*Nsts = 2      AB*/
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);*/
135
136                 } else {/*IDX =1*/
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;*/
140                 }
141         } else {
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*/
144         }
145
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);
151         }
152 #endif
153 }
154 #if 0
155 void
156 hal_txbf_8822b_download_ndpa(
157         struct _ADAPTER                 *adapter,
158         u8                              idx
159 )
160 {
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;
169
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);
172
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)));
176
177
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)));
181
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;
185         }
186
187         /*0x204[11:0]   Beacon Head for TXDMA*/
188         platform_efio_write_2byte(adapter, REG_FIFOPAGE_CTRL_2_8814A, head_page);
189
190         do {
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)));
194
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);
198                 else
199                         beamforming_send_ht_ndpa_packet(p_dm_odm, p_beam_entry->mac_addr, p_beam_entry->sound_bw, BEACON_QUEUE);
200
201                 /*check rsvd page download OK.*/
202                 bcn_valid_reg = platform_efio_read_1byte(adapter, REG_FIFOPAGE_CTRL_2_8814A + 1);
203                 count = 0;
204                 while (!(bcn_valid_reg & BIT(7)) && count < 20) {
205                         count++;
206                         delay_us(10);
207                         bcn_valid_reg = platform_efio_read_1byte(adapter, REG_FIFOPAGE_CTRL_2_8814A + 2);
208                 }
209                 dl_bcn_count++;
210         } while (!(bcn_valid_reg & BIT(7)) && dl_bcn_count < 5);
211
212         if (!(bcn_valid_reg & BIT(0)))
213                 RT_DISP(FBEAM, FBEAM_ERROR, ("%s Download RSVD page failed!\n", __func__));
214
215         /*0x204[11:0]   Beacon Head for TXDMA*/
216         platform_efio_write_2byte(adapter, REG_FIFOPAGE_CTRL_2_8814A, tx_page_bndy);
217
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.*/
223         if (is_send_beacon)
224                 platform_efio_write_1byte(adapter, REG_FWHW_TXQ_CTRL_8814A + 2, tmp_reg422);
225
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))));
230
231         p_beam_entry->beamform_entry_state = BEAMFORMING_ENTRY_STATE_PROGRESSED;
232
233         p_hal_data->is_fw_dw_rsvd_page_in_progress = false;
234 }
235
236 void
237 hal_txbf_8822b_fw_txbf_cmd(
238         struct _ADAPTER *adapter
239 )
240 {
241         u8      idx, period = 0;
242         u8      PageNum0 = 0xFF, PageNum1 = 0xFF;
243         u8      u1_tx_bf_parm[3] = {0};
244
245         PMGNT_INFO                              p_mgnt_info = &(adapter->MgntInfo);
246         struct _RT_BEAMFORMING_INFO     *p_beam_info = GET_BEAMFORM_INFO(adapter);
247
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) {
251                                 PageNum0 = 0xFE;
252                                 PageNum1 = 0x07;
253                                 period = (u8)(p_beam_info->beamformee_entry[idx].sound_period);
254                         } else if (PageNum0 == 0xFF) {
255                                 PageNum0 = 0xFF; /*stop sounding*/
256                                 PageNum1 = 0x0F;
257                         }
258                 }
259         }
260
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);
265
266         RT_DISP(FBEAM, FBEAM_FUN, ("@%s End, PageNum0 = 0x%x, PageNum1 = 0x%x period = %d", __func__, PageNum0, PageNum1, period));
267 }
268 #endif
269
270 #if 0
271 void
272 hal_txbf_8822b_init(
273         void                    *p_dm_void
274 )
275 {
276         struct PHY_DM_STRUCT    *p_dm_odm = (struct PHY_DM_STRUCT *)p_dm_void;
277         u8              u1b_tmp;
278         struct _RT_BEAMFORMING_INFO             *p_beamforming_info = &p_dm_odm->beamforming_info;
279         struct _ADAPTER                         *adapter = p_dm_odm->adapter;
280
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*/
287
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);
294
295         /*Temp Settings*/
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*/
298
299         /* Init HW variable */
300         p_beamforming_info->reg_mu_tx_ctrl = odm_read_4byte(p_dm_odm, 0x14c0);
301
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*/
305         }
306
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));
313 #endif
314 }
315 #endif
316
317 void
318 hal_txbf_8822b_enter(
319         void                    *p_dm_void,
320         u8                              bfer_bfee_idx
321 )
322 {
323         struct PHY_DM_STRUCT    *p_dm_odm = (struct PHY_DM_STRUCT *)p_dm_void;
324         u8                                      i = 0;
325         u8                                      bfer_idx = (bfer_bfee_idx & 0xF0) >> 4;
326         u8                                      bfee_idx = (bfer_bfee_idx & 0xF);
327         u16                                     csi_param = 0;
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};
335         u8                                      u1b_tmp;
336         u32                                     u4b_tmp;
337
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));
339
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);
346
347
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;
352                                 break;
353                         }
354                 }
355
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]);
360                 } else {
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]);
363                 }
364
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*/
368
369                 grouping = 0;
370
371                 /*for ac = 1, for n = 3*/
372                 if (p_beamformer_entry->beamform_entry_cap & BEAMFORMEE_CAP_VHT_SU)
373                         codebookinfo = 1;
374                 else if (p_beamformer_entry->beamform_entry_cap & BEAMFORMEE_CAP_HT_EXPLICIT)
375                         codebookinfo = 3;
376
377                 coefficientsize = 3;
378
379                 csi_param = (u16)((coefficientsize << 10) | (codebookinfo << 8) | (grouping << 6) | (nr_index << 3) | (nc_index));
380
381                 if (bfer_idx == 0)
382                         odm_write_2byte(p_dm_odm, REG_TX_CSI_RPT_PARAM_BW20_8822B, csi_param);
383                 else
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);
387
388         }
389
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);
395
396                 if (phydm_acting_determine(p_dm_odm, phydm_acting_as_ibss))
397                         sta_id = p_beamformee_entry->mac_id;
398                 else
399                         sta_id = p_beamformee_entry->p_aid;
400
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;
405                                 break;
406                         }
407                 }
408
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));
413                 } else
414                         odm_write_2byte(p_dm_odm, REG_TXBF_CTRL_8822B + 2, sta_id | BIT(14) | BIT(15) | BIT(12));
415
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;
420
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));
423                 } else
424                         odm_write_2byte(p_dm_odm, REG_ASSOCIATED_BFMEE_SEL_8822B + 2, sta_id | 0xE200); /*Set BIT25*/
425
426                 phydm_beamforming_notify(p_dm_odm);
427         }
428
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;
438
439                 /*Sounding protocol control*/
440                 odm_write_1byte(p_dm_odm, REG_SND_PTCL_CTRL_8822B, 0xDB);
441
442                 /* MAC address */
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]);
445
446                 /* Set partial AID */
447                 odm_write_2byte(p_dm_odm, (REG_ASSOCIATED_BFMER0_INFO_8822B + 6), p_beamformer_entry->p_aid);
448
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);
453
454                 /* Set 80us for leaving ndp_rx_standby_state */
455                 odm_write_1byte(p_dm_odm, 0x71B, 0x50);
456
457                 /* Set 0x6A0[14] = 1 to accept action_no_ack */
458                 u1b_tmp = odm_read_1byte(p_dm_odm, REG_RXFLTMAP0_8822B + 1);
459                 u1b_tmp |= 0x40;
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);
463                 u1b_tmp |= 0x30;
464                 odm_write_1byte(p_dm_odm, REG_RXFLTMAP1_8822B, u1b_tmp);
465
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);
474
475                 /*for B-cut*/
476                 odm_set_bb_reg(p_dm_odm, 0x6A0, BIT(20), 0);
477                 odm_set_bb_reg(p_dm_odm, 0x688, BIT(20), 0);
478
479         }
480
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;
489                                 break;
490                         }
491                 }
492
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__));
496                         return;
497                 }
498
499                 /*User position table*/
500                 switch (p_beamformee_entry->mu_reg_index) {
501                 case 0:
502                         gid_valid = 0x7fe;
503                         user_position_l = 0x111110;
504                         user_position_h = 0x0;
505                         break;
506                 case 1:
507                         gid_valid = 0x7f806;
508                         user_position_l = 0x11000004;
509                         user_position_h = 0x11;
510                         break;
511                 case 2:
512                         gid_valid = 0x1f81818;
513                         user_position_l = 0x400040;
514                         user_position_h = 0x11100;
515                         break;
516                 case 3:
517                         gid_valid = 0x1e186060;
518                         user_position_l = 0x4000400;
519                         user_position_h = 0x1100040;
520                         break;
521                 case 4:
522                         gid_valid = 0x66618180;
523                         user_position_l = 0x40004000;
524                         user_position_h = 0x10040400;
525                         break;
526                 case 5:
527                         gid_valid = 0x79860600;
528                         user_position_l = 0x40000;
529                         user_position_h = 0x4404004;
530                         break;
531                 }
532
533                 for (i = 0; i < 8; i++) {
534                         if (i < 4) {
535                                 p_beamformee_entry->gid_valid[i] = (u8)(gid_valid & 0xFF);
536                                 gid_valid = (gid_valid >> 8);
537                         } else
538                                 p_beamformee_entry->gid_valid[i] = 0;
539                 }
540                 for (i = 0; i < 16; i++) {
541                         if (i < 4)
542                                 p_beamformee_entry->user_position[i] = (u8)((user_position_l >> (i * 8)) & 0xFF);
543                         else if (i < 8)
544                                 p_beamformee_entry->user_position[i] = (u8)((user_position_h >> ((i - 4) * 8)) & 0xFF);
545                         else
546                                 p_beamformee_entry->user_position[i] = 0;
547                 }
548
549                 /*Sounding protocol control*/
550                 odm_write_1byte(p_dm_odm, REG_SND_PTCL_CTRL_8822B, 0xDB);
551
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);
556
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);
560
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);
565
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));
568
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);
574
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);
579                 /* Set NDPA to 6M*/
580                 odm_write_1byte(p_dm_odm, REG_NDPA_RATE_8822B, 0x4);
581
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);
585
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);
589
590                 /* Set 0x6A0[14] = 1 to accept action_no_ack */
591                 u1b_tmp = odm_read_1byte(p_dm_odm, REG_RXFLTMAP0_8822B + 1);
592                 u1b_tmp |= 0x40;
593                 odm_write_1byte(p_dm_odm, REG_RXFLTMAP0_8822B + 1, u1b_tmp);
594                 /* End of MAC registers setting */
595
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);
601 #endif
602
603                 phydm_beamforming_notify(p_dm_odm);
604 #if 1
605                 {
606                         u32 ctrl_info_offset, index;
607                         /*Set Ctrl Info*/
608                         odm_write_2byte(p_dm_odm, 0x140, 0x660);
609                         ctrl_info_offset = 0x8000 + 32 * p_beamformee_entry->mac_id;
610                         /*Reset Ctrl Info*/
611                         for (index = 0; index < 8; index++)
612                                 odm_write_4byte(p_dm_odm, ctrl_info_offset + index * 4, 0);
613
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*/
616
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));
619                 }
620 #endif
621         }
622
623 }
624
625
626 void
627 hal_txbf_8822b_leave(
628         void                    *p_dm_void,
629         u8                              idx
630 )
631 {
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};
637
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];
641         } else
642                 return;
643
644         /*Clear P_AID of Beamformee*/
645         /*Clear MAC address of Beamformer*/
646         /*Clear Associated Bfmee Sel*/
647
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);
655                         } else {
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);
659                         }
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);
666
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;
670                 }
671         }
672
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);
680                         } else {
681                                 odm_write_2byte(p_dm_odm, REG_TXBF_CTRL_8822B + 2, 0x0 | BIT(14) | BIT(15) | BIT(12));
682
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);
685                         }
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);
694
695
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;
699                 }
700         }
701 }
702
703
704 /***********SU & MU BFee Entry Only when souding done****************/
705 void
706 hal_txbf_8822b_status(
707         void                    *p_dm_void,
708         u8                              beamform_idx
709 )
710 {
711         struct PHY_DM_STRUCT    *p_dm_odm = (struct PHY_DM_STRUCT *)p_dm_void;
712         u16                                     beam_ctrl_val, tmp_val;
713         u32                                     beam_ctrl_reg;
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;
717         u16 bitmap;
718         u8 idx, gid, i;
719         u8 id1, id0;
720         u32 gid_valid[6] = {0};
721         u32 user_position_lsb[6] = {0};
722         u32 user_position_msb[6] = {0};
723         u32 value32;
724         boolean is_sounding_success[6] = {false};
725
726         if (beamform_idx < BEAMFORMEE_ENTRY_NUM)
727                 p_beamform_entry = &p_beamforming_info->beamformee_entry[beamform_idx];
728         else
729                 return;
730
731         /*SU sounding done */
732         if (is_mu_sounding == false) {
733
734                 if (phydm_acting_determine(p_dm_odm, phydm_acting_as_ibss))
735                         beam_ctrl_val = p_beamform_entry->mac_id;
736                 else
737                         beam_ctrl_val = p_beamform_entry->p_aid;
738
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));
740
741                 if (p_beamform_entry->su_reg_index == 0)
742                         beam_ctrl_reg = REG_TXBF_CTRL_8822B;
743                 else {
744                         beam_ctrl_reg = REG_TXBF_CTRL_8822B + 2;
745                         beam_ctrl_val |= BIT(12) | BIT(14) | BIT(15);
746                 }
747
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));
755                 } else {
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));
758                 }
759
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));
764         } else {
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__));
769
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;
779
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]));
782
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 */
785
786                         is_bitmap_ready = (boolean)((value32 & BIT(15)) >> 15);
787                         bitmap = (u16)(value32 & 0x3FFF);
788
789                         for (idx = 0; idx < 15; idx++) {
790                                 if (idx < 5) {/*bit0~4*/
791                                         id0 = 0;
792                                         id1 = (u8)(idx + 1);
793                                 } else if (idx < 9) { /*bit5~8*/
794                                         id0 = 1;
795                                         id1 = (u8)(idx - 3);
796                                 } else if (idx < 12) { /*bit9~11*/
797                                         id0 = 2;
798                                         id1 = (u8)(idx - 6);
799                                 } else if (idx < 14) { /*bit12~13*/
800                                         id0 = 3;
801                                         id1 = (u8)(idx - 8);
802                                 } else { /*bit14*/
803                                         id0 = 4;
804                                         id1 = (u8)(idx - 9);
805                                 }
806                                 if (bitmap & BIT(idx)) {
807                                         /*Pair 1*/
808                                         gid = (idx << 1) + 1;
809                                         gid_valid[id0] |= (BIT(gid));
810                                         gid_valid[id1] |= (BIT(gid));
811                                         /*Pair 2*/
812                                         gid += 1;
813                                         gid_valid[id0] |= (BIT(gid));
814                                         gid_valid[id1] |= (BIT(gid));
815                                 } else {
816                                         /*Pair 1*/
817                                         gid = (idx << 1) + 1;
818                                         gid_valid[id0] &= ~(BIT(gid));
819                                         gid_valid[id1] &= ~(BIT(gid));
820                                         /*Pair 2*/
821                                         gid += 1;
822                                         gid_valid[id0] &= ~(BIT(gid));
823                                         gid_valid[id1] &= ~(BIT(gid));
824                                 }
825                         }
826
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);
834                                         }
835                                 }
836                         }
837
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*/
843                         }
844
845                         /*Enable TxMU PPDU*/
846                         if (p_beamforming_info->dbg_disable_mu_tx == false)
847                                 p_beamforming_info->reg_mu_tx_ctrl |= BIT(7);
848                         else
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);
851                 }
852         }
853 }
854
855 /*Only used for MU BFer Entry when get GID management frame (self is as MU STA)*/
856 void
857 hal_txbf_8822b_config_gtab(
858         void                    *p_dm_void
859 )
860 {
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;
865
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];
868         else
869                 return;
870
871         ODM_RT_TRACE(p_dm_odm, PHYDM_COMP_TXBF, ODM_DBG_LOUD, ("%s==>\n", __func__));
872
873         /*For GID 0~31*/
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++) {
877                 if (i < 4)
878                         user_position_l |= (p_beamformer_entry->user_position[i] << (i << 3));
879                 else
880                         user_position_h |= (p_beamformer_entry->user_position[i] << ((i - 4) << 3));
881         }
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);
888
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));
891
892         gid_valid = 0;
893         user_position_l = 0;
894         user_position_h = 0;
895
896         /*For GID 32~64*/
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++) {
900                 if (i < 4)
901                         user_position_l |= (p_beamformer_entry->user_position[i] << ((i - 8) << 3));
902                 else
903                         user_position_h |= (p_beamformer_entry->user_position[i] << ((i - 12) << 3));
904         }
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);
912
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));
915
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);
920
921 }
922
923
924
925 #if 0
926 /*This function translate the bitmap to GTAB*/
927 void
928 haltxbf8822b_gtab_translation(
929         struct PHY_DM_STRUCT                    *p_dm_odm
930 )
931 {
932         u8 idx, gid;
933         u8 id1, id0;
934         u32 gid_valid[6] = {0};
935         u32 user_position_lsb[6] = {0};
936         u32 user_position_msb[6] = {0};
937
938         for (idx = 0; idx < 15; idx++) {
939                 if (idx < 5) {/*bit0~4*/
940                         id0 = 0;
941                         id1 = (u8)(idx + 1);
942                 } else if (idx < 9) { /*bit5~8*/
943                         id0 = 1;
944                         id1 = (u8)(idx - 3);
945                 } else if (idx < 12) { /*bit9~11*/
946                         id0 = 2;
947                         id1 = (u8)(idx - 6);
948                 } else if (idx < 14) { /*bit12~13*/
949                         id0 = 3;
950                         id1 = (u8)(idx - 8);
951                 } else { /*bit14*/
952                         id0 = 4;
953                         id1 = (u8)(idx - 9);
954                 }
955
956                 /*Pair 1*/
957                 gid = (idx << 1) + 1;
958                 gid_valid[id0] |= (1 << gid);
959                 gid_valid[id1] |= (1 << gid);
960                 if (gid < 16) {
961                         /*user_position_lsb[id0] |= (0 << (gid << 1));*/
962                         user_position_lsb[id1] |= (1 << (gid << 1));
963                 } else {
964                         /*user_position_msb[id0] |= (0 << ((gid - 16) << 1));*/
965                         user_position_msb[id1] |= (1 << ((gid - 16) << 1));
966                 }
967
968                 /*Pair 2*/
969                 gid += 1;
970                 gid_valid[id0] |= (1 << gid);
971                 gid_valid[id1] |= (1 << gid);
972                 if (gid < 16) {
973                         user_position_lsb[id0] |= (1 << (gid << 1));
974                         /*user_position_lsb[id1] |= (0 << (gid << 1));*/
975                 } else {
976                         user_position_msb[id0] |= (1 << ((gid - 16) << 1));
977                         /*user_position_msb[id1] |= (0 << ((gid - 16) << 1));*/
978                 }
979
980         }
981
982
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]);*/
986         }
987 }
988 #endif
989
990 void
991 hal_txbf_8822b_fw_txbf(
992         void                    *p_dm_void,
993         u8                              idx
994 )
995 {
996 #if 0
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;
999
1000         if (p_beam_entry->beamform_entry_state == BEAMFORMING_ENTRY_STATE_PROGRESSING)
1001                 hal_txbf_8822b_download_ndpa(adapter, idx);
1002
1003         hal_txbf_8822b_fw_txbf_cmd(adapter);
1004 #endif
1005 }
1006
1007 #endif
1008
1009 #if (defined(CONFIG_BB_TXBF_API))
1010 /*this function is only used for BFer*/
1011 void
1012 phydm_8822btxbf_rfmode(
1013         void            *p_dm_void,
1014         u8      su_bfee_cnt,
1015         u8      mu_bfee_cnt
1016 )
1017 {
1018         struct PHY_DM_STRUCT    *p_dm_odm = (struct PHY_DM_STRUCT *)p_dm_void;
1019         u8              i, nr_index = 0;
1020
1021         if (p_dm_odm->rf_type == ODM_1T1R)
1022                 return;
1023
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*/
1031                 }
1032         }
1033
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*/
1035
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*/
1040                 
1041
1042                 /*Nsts = 2      AB*/
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);
1045
1046         } else {
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*/
1049
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*/
1052         }
1053
1054 }
1055
1056
1057 /*this function is for BFer bug workaround*/
1058 void
1059 phydm_8822b_sutxbfer_workaroud(
1060         void            *p_dm_void,
1061         boolean enable_su_bfer,
1062         u8      nc,
1063         u8      nr,
1064         u8      ng,
1065         u8      CB,
1066         u8      BW,
1067         boolean is_vht
1068 )
1069 {
1070         struct PHY_DM_STRUCT    *p_dm_odm = (struct PHY_DM_STRUCT *)p_dm_void;
1071
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);
1076
1077                 if (is_vht)
1078                         odm_set_bb_reg(p_dm_odm, 0x19f0, BIT(5) | BIT(4) | BIT(3) | BIT(2) | BIT(1) | BIT(0), 0x1f);
1079                 else
1080                         odm_set_bb_reg(p_dm_odm, 0x19f0, BIT(5) | BIT(4) | BIT(3) | BIT(2) | BIT(1) | BIT(0), 0x22);
1081
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);
1086
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);
1091         } else
1092                 odm_set_bb_reg(p_dm_odm, 0x19f8, BIT(16), 0x0);
1093
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));
1096
1097
1098 }
1099 #endif
1100 #endif  /* (RTL8822B_SUPPORT == 1)*/