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