xref: /OK3568_Linux_fs/external/rkwifibt/drivers/rtl8189fs/include/rtw_beamforming.h (revision 4882a59341e53eb6f0b4789bf948001014eff981)
1*4882a593Smuzhiyun /******************************************************************************
2*4882a593Smuzhiyun  *
3*4882a593Smuzhiyun  * Copyright(c) 2007 - 2017 Realtek Corporation.
4*4882a593Smuzhiyun  *
5*4882a593Smuzhiyun  * This program is free software; you can redistribute it and/or modify it
6*4882a593Smuzhiyun  * under the terms of version 2 of the GNU General Public License as
7*4882a593Smuzhiyun  * published by the Free Software Foundation.
8*4882a593Smuzhiyun  *
9*4882a593Smuzhiyun  * This program is distributed in the hope that it will be useful, but WITHOUT
10*4882a593Smuzhiyun  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11*4882a593Smuzhiyun  * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
12*4882a593Smuzhiyun  * more details.
13*4882a593Smuzhiyun  *
14*4882a593Smuzhiyun  *****************************************************************************/
15*4882a593Smuzhiyun #ifndef __RTW_BEAMFORMING_H_
16*4882a593Smuzhiyun #define __RTW_BEAMFORMING_H_
17*4882a593Smuzhiyun 
18*4882a593Smuzhiyun #ifdef CONFIG_BEAMFORMING
19*4882a593Smuzhiyun 
20*4882a593Smuzhiyun #ifdef RTW_BEAMFORMING_VERSION_2
21*4882a593Smuzhiyun #define MAX_NUM_BEAMFORMEE_SU	2
22*4882a593Smuzhiyun #define MAX_NUM_BEAMFORMER_SU	2
23*4882a593Smuzhiyun #define MAX_NUM_BEAMFORMEE_MU	6
24*4882a593Smuzhiyun #define MAX_NUM_BEAMFORMER_MU	1
25*4882a593Smuzhiyun 
26*4882a593Smuzhiyun #define MAX_BEAMFORMEE_ENTRY_NUM	(MAX_NUM_BEAMFORMEE_SU + MAX_NUM_BEAMFORMEE_MU)
27*4882a593Smuzhiyun #define MAX_BEAMFORMER_ENTRY_NUM	(MAX_NUM_BEAMFORMER_SU + MAX_NUM_BEAMFORMER_MU)
28*4882a593Smuzhiyun 
29*4882a593Smuzhiyun /* <Note> Need to be defined by IC */
30*4882a593Smuzhiyun #define SU_SOUNDING_TIMEOUT	5	/* unit: ms */
31*4882a593Smuzhiyun #define MU_SOUNDING_TIMEOUT	8	/* unit: ms */
32*4882a593Smuzhiyun 
33*4882a593Smuzhiyun #define GET_BEAMFORM_INFO(adapter)	(&GET_HAL_DATA(adapter)->beamforming_info)
34*4882a593Smuzhiyun #define GetInitSoundCnt(_SoundPeriod, _MinSoundPeriod)	((_SoundPeriod)/(_MinSoundPeriod))
35*4882a593Smuzhiyun 
36*4882a593Smuzhiyun enum BEAMFORMING_CTRL_TYPE {
37*4882a593Smuzhiyun 	BEAMFORMING_CTRL_ENTER = 0,
38*4882a593Smuzhiyun 	BEAMFORMING_CTRL_LEAVE = 1,
39*4882a593Smuzhiyun 	BEAMFORMING_CTRL_START_PERIOD = 2,
40*4882a593Smuzhiyun 	BEAMFORMING_CTRL_END_PERIOD = 3,
41*4882a593Smuzhiyun 	BEAMFORMING_CTRL_SOUNDING_FAIL = 4,
42*4882a593Smuzhiyun 	BEAMFORMING_CTRL_SOUNDING_CLK = 5,
43*4882a593Smuzhiyun 	BEAMFORMING_CTRL_SET_GID_TABLE = 6,
44*4882a593Smuzhiyun 	BEAMFORMING_CTRL_SET_CSI_REPORT = 7,
45*4882a593Smuzhiyun };
46*4882a593Smuzhiyun 
47*4882a593Smuzhiyun enum _BEAMFORMING_STATE {
48*4882a593Smuzhiyun 	BEAMFORMING_STATE_IDLE,
49*4882a593Smuzhiyun 	BEAMFORMING_STATE_START,
50*4882a593Smuzhiyun 	BEAMFORMING_STATE_END,
51*4882a593Smuzhiyun };
52*4882a593Smuzhiyun 
53*4882a593Smuzhiyun /*
54*4882a593Smuzhiyun  * typedef BEAMFORMING_CAP for phydm
55*4882a593Smuzhiyun  */
56*4882a593Smuzhiyun typedef enum beamforming_cap {
57*4882a593Smuzhiyun 	BEAMFORMING_CAP_NONE = 0x0,
58*4882a593Smuzhiyun 	BEAMFORMER_CAP_HT_EXPLICIT = 0x1,
59*4882a593Smuzhiyun 	BEAMFORMEE_CAP_HT_EXPLICIT = 0x2,
60*4882a593Smuzhiyun 	BEAMFORMER_CAP_VHT_SU = 0x4,			/* Self has er Cap, because Reg er  & peer ee */
61*4882a593Smuzhiyun 	BEAMFORMEE_CAP_VHT_SU = 0x8, 			/* Self has ee Cap, because Reg ee & peer er */
62*4882a593Smuzhiyun 	BEAMFORMER_CAP_VHT_MU = 0x10,			/* Self has er Cap, because Reg er & peer ee */
63*4882a593Smuzhiyun 	BEAMFORMEE_CAP_VHT_MU = 0x20,			/* Self has ee Cap, because Reg ee & peer er */
64*4882a593Smuzhiyun 	BEAMFORMER_CAP = 0x40,
65*4882a593Smuzhiyun 	BEAMFORMEE_CAP = 0x80,
66*4882a593Smuzhiyun } BEAMFORMING_CAP;
67*4882a593Smuzhiyun 
68*4882a593Smuzhiyun enum _BEAMFORM_ENTRY_HW_STATE {
69*4882a593Smuzhiyun 	BEAMFORM_ENTRY_HW_STATE_NONE,
70*4882a593Smuzhiyun 	BEAMFORM_ENTRY_HW_STATE_ADD_INIT,
71*4882a593Smuzhiyun 	BEAMFORM_ENTRY_HW_STATE_ADDING,
72*4882a593Smuzhiyun 	BEAMFORM_ENTRY_HW_STATE_ADDED,
73*4882a593Smuzhiyun 	BEAMFORM_ENTRY_HW_STATE_DELETE_INIT,
74*4882a593Smuzhiyun 	BEAMFORM_ENTRY_HW_STATE_DELETING,
75*4882a593Smuzhiyun 	BEAMFORM_ENTRY_HW_STATE_MAX
76*4882a593Smuzhiyun };
77*4882a593Smuzhiyun 
78*4882a593Smuzhiyun /* The sounding state is recorded by BFer. */
79*4882a593Smuzhiyun enum _SOUNDING_STATE {
80*4882a593Smuzhiyun 	SOUNDING_STATE_NONE		= 0,
81*4882a593Smuzhiyun 	SOUNDING_STATE_INIT		= 1,
82*4882a593Smuzhiyun 	SOUNDING_STATE_SU_START		= 2,
83*4882a593Smuzhiyun 	SOUNDING_STATE_SU_SOUNDDOWN	= 3,
84*4882a593Smuzhiyun 	SOUNDING_STATE_MU_START		= 4,
85*4882a593Smuzhiyun 	SOUNDING_STATE_MU_SOUNDDOWN	= 5,
86*4882a593Smuzhiyun 	SOUNDING_STATE_SOUNDING_TIMEOUT	= 6,
87*4882a593Smuzhiyun 	SOUNDING_STATE_MAX
88*4882a593Smuzhiyun };
89*4882a593Smuzhiyun 
90*4882a593Smuzhiyun struct beamformee_entry {
91*4882a593Smuzhiyun 	u8 used;	/* _TRUE/_FALSE */
92*4882a593Smuzhiyun 	u8 txbf;
93*4882a593Smuzhiyun 	u8 sounding;
94*4882a593Smuzhiyun 	/* Used to construct AID field of NDPA packet */
95*4882a593Smuzhiyun 	u16 aid;
96*4882a593Smuzhiyun 	/* Used to Set Reg42C in IBSS mode */
97*4882a593Smuzhiyun 	u16 mac_id;
98*4882a593Smuzhiyun 	/* Used to fill Reg42C & Reg714 to compare with P_AID of Tx DESC */
99*4882a593Smuzhiyun 	u16 p_aid;
100*4882a593Smuzhiyun 	u8 g_id;
101*4882a593Smuzhiyun 	/* Used to fill Reg6E4 to fill Mac address of CSI report frame */
102*4882a593Smuzhiyun 	u8 mac_addr[ETH_ALEN];
103*4882a593Smuzhiyun 	/* Sounding BandWidth */
104*4882a593Smuzhiyun 	enum channel_width sound_bw;
105*4882a593Smuzhiyun 	u16 sound_period;
106*4882a593Smuzhiyun 
107*4882a593Smuzhiyun 	enum beamforming_cap cap;
108*4882a593Smuzhiyun 	enum _BEAMFORM_ENTRY_HW_STATE state;
109*4882a593Smuzhiyun 
110*4882a593Smuzhiyun 	/* The BFee need to be sounded when count to zero */
111*4882a593Smuzhiyun 	u8 SoundCnt;
112*4882a593Smuzhiyun 	u8 bCandidateSoundingPeer;
113*4882a593Smuzhiyun 	u8 bSoundingTimeout;
114*4882a593Smuzhiyun 	u8 bDeleteSounding;
115*4882a593Smuzhiyun 	/* Get the result through throughput and Tx rate from BB API */
116*4882a593Smuzhiyun 	u8 bApplySounding;
117*4882a593Smuzhiyun 
118*4882a593Smuzhiyun 	/* information for sounding judgement */
119*4882a593Smuzhiyun 	systime tx_timestamp;
120*4882a593Smuzhiyun 	u64 tx_bytes;
121*4882a593Smuzhiyun 
122*4882a593Smuzhiyun 	u16 LogStatusFailCnt:5;	/* 0~21 */
123*4882a593Smuzhiyun 	u16 DefaultCSICnt:5; /* 0~21 */
124*4882a593Smuzhiyun 	u8 CSIMatrix[327];
125*4882a593Smuzhiyun 	u16 CSIMatrixLen;
126*4882a593Smuzhiyun 
127*4882a593Smuzhiyun 	u8 NumofSoundingDim;
128*4882a593Smuzhiyun 
129*4882a593Smuzhiyun 	u8 comp_steering_num_of_bfer;
130*4882a593Smuzhiyun 
131*4882a593Smuzhiyun 
132*4882a593Smuzhiyun 	/* SU-MIMO */
133*4882a593Smuzhiyun 	u8 su_reg_index;
134*4882a593Smuzhiyun 
135*4882a593Smuzhiyun 	/* MU-MIMO */
136*4882a593Smuzhiyun 	u8 mu_reg_index;
137*4882a593Smuzhiyun 	u8 gid_valid[8];
138*4882a593Smuzhiyun 	u8 user_position[16];
139*4882a593Smuzhiyun 
140*4882a593Smuzhiyun 	/* For 8822B C-cut workaround */
141*4882a593Smuzhiyun 	/* If the flag set to _TRUE, do not sound this STA */
142*4882a593Smuzhiyun 	u8 bSuspendSUCap;
143*4882a593Smuzhiyun };
144*4882a593Smuzhiyun 
145*4882a593Smuzhiyun struct beamformer_entry {
146*4882a593Smuzhiyun 	u8 used;
147*4882a593Smuzhiyun 	/* p_aid of BFer entry is probably not used */
148*4882a593Smuzhiyun 	/* Used to fill Reg42C & Reg714 to compare with p_aid of Tx DESC */
149*4882a593Smuzhiyun 	u16 p_aid;
150*4882a593Smuzhiyun 	u8 g_id;
151*4882a593Smuzhiyun 	u8 mac_addr[ETH_ALEN];
152*4882a593Smuzhiyun 
153*4882a593Smuzhiyun 	enum beamforming_cap cap;
154*4882a593Smuzhiyun 	enum _BEAMFORM_ENTRY_HW_STATE state;
155*4882a593Smuzhiyun 
156*4882a593Smuzhiyun 	u8 NumofSoundingDim;
157*4882a593Smuzhiyun 
158*4882a593Smuzhiyun 	/* SU-MIMO */
159*4882a593Smuzhiyun 	u8 su_reg_index;
160*4882a593Smuzhiyun 
161*4882a593Smuzhiyun 	/* MU-MIMO */
162*4882a593Smuzhiyun 	u8 gid_valid[8];
163*4882a593Smuzhiyun 	u8 user_position[16];
164*4882a593Smuzhiyun 	u16 aid;
165*4882a593Smuzhiyun };
166*4882a593Smuzhiyun 
167*4882a593Smuzhiyun struct sounding_info {
168*4882a593Smuzhiyun 	u8 su_sounding_list[MAX_NUM_BEAMFORMEE_SU];
169*4882a593Smuzhiyun 	u8 mu_sounding_list[MAX_NUM_BEAMFORMEE_MU];
170*4882a593Smuzhiyun 
171*4882a593Smuzhiyun 	enum _SOUNDING_STATE state;
172*4882a593Smuzhiyun 	/*
173*4882a593Smuzhiyun 	 * su_bfee_curidx is index for beamforming_info.bfee_entry[]
174*4882a593Smuzhiyun 	 * range: 0~MAX_BEAMFORMEE_ENTRY_NUM
175*4882a593Smuzhiyun 	 */
176*4882a593Smuzhiyun 	u8 su_bfee_curidx;
177*4882a593Smuzhiyun 	u8 candidate_mu_bfee_cnt;
178*4882a593Smuzhiyun 
179*4882a593Smuzhiyun 	/* For sounding schedule maintenance */
180*4882a593Smuzhiyun 	u16 min_sounding_period;
181*4882a593Smuzhiyun 	/* Get from sounding list */
182*4882a593Smuzhiyun 	/* Ex: SU STA1, SU STA2, MU STA(1~n) => the value will be 2+1=3 */
183*4882a593Smuzhiyun 	u8 sound_remain_cnt_per_period;
184*4882a593Smuzhiyun };
185*4882a593Smuzhiyun 
186*4882a593Smuzhiyun struct _RT_CSI_INFO{
187*4882a593Smuzhiyun 	u8 Nc;
188*4882a593Smuzhiyun 	u8 Nr;
189*4882a593Smuzhiyun 	u8 Ng;
190*4882a593Smuzhiyun 	u8 CodeBook;
191*4882a593Smuzhiyun 	u8 ChnlWidth;
192*4882a593Smuzhiyun 	u8 bVHT;
193*4882a593Smuzhiyun };
194*4882a593Smuzhiyun 
195*4882a593Smuzhiyun struct beamforming_info {
196*4882a593Smuzhiyun 	enum beamforming_cap beamforming_cap;
197*4882a593Smuzhiyun 	enum _BEAMFORMING_STATE beamforming_state;
198*4882a593Smuzhiyun 	struct beamformee_entry bfee_entry[MAX_BEAMFORMEE_ENTRY_NUM];
199*4882a593Smuzhiyun 	struct beamformer_entry bfer_entry[MAX_BEAMFORMER_ENTRY_NUM];
200*4882a593Smuzhiyun 	u8 sounding_sequence;
201*4882a593Smuzhiyun 	u8 beamformee_su_cnt;
202*4882a593Smuzhiyun 	u8 beamformer_su_cnt;
203*4882a593Smuzhiyun 	u32 beamformee_su_reg_maping;
204*4882a593Smuzhiyun 	u32 beamformer_su_reg_maping;
205*4882a593Smuzhiyun 	/* For MU-MINO */
206*4882a593Smuzhiyun 	u8 beamformee_mu_cnt;
207*4882a593Smuzhiyun 	u8 beamformer_mu_cnt;
208*4882a593Smuzhiyun 	u32 beamformee_mu_reg_maping;
209*4882a593Smuzhiyun 	u8 first_mu_bfee_index;
210*4882a593Smuzhiyun 	u8 mu_bfer_curidx;
211*4882a593Smuzhiyun 	u8 cur_csi_rpt_rate;
212*4882a593Smuzhiyun 
213*4882a593Smuzhiyun 	struct sounding_info sounding_info;
214*4882a593Smuzhiyun 	/* schedule regular timer for sounding */
215*4882a593Smuzhiyun 	_timer sounding_timer;
216*4882a593Smuzhiyun 	/* moniter if soudning too long */
217*4882a593Smuzhiyun 	_timer sounding_timeout_timer;
218*4882a593Smuzhiyun 
219*4882a593Smuzhiyun 	/* For HW configuration */
220*4882a593Smuzhiyun 	u8 SetHalBFEnterOnDemandCnt;
221*4882a593Smuzhiyun 	u8 SetHalBFLeaveOnDemandCnt;
222*4882a593Smuzhiyun 	u8 SetHalSoundownOnDemandCnt;
223*4882a593Smuzhiyun 	u8 bSetBFHwConfigInProgess;
224*4882a593Smuzhiyun 
225*4882a593Smuzhiyun 	/*
226*4882a593Smuzhiyun 	 * Target CSI report info.
227*4882a593Smuzhiyun 	 * Keep the first SU CSI report info for 8822B HW bug workaround.
228*4882a593Smuzhiyun 	 */
229*4882a593Smuzhiyun 	u8 bEnableSUTxBFWorkAround;
230*4882a593Smuzhiyun 	struct _RT_CSI_INFO TargetCSIInfo;
231*4882a593Smuzhiyun 	/* Only peform sounding to the first SU BFee */
232*4882a593Smuzhiyun 	struct beamformee_entry *TargetSUBFee;
233*4882a593Smuzhiyun 
234*4882a593Smuzhiyun 	/* For debug */
235*4882a593Smuzhiyun 	s8 sounding_running;
236*4882a593Smuzhiyun };
237*4882a593Smuzhiyun 
238*4882a593Smuzhiyun enum beamforming_cap rtw_bf_bfee_get_entry_cap_by_macid(void *mlmepriv, u8 mac_id);
239*4882a593Smuzhiyun struct beamformer_entry *rtw_bf_bfer_get_entry_by_addr(PADAPTER, u8 *ra);
240*4882a593Smuzhiyun struct beamformee_entry *rtw_bf_bfee_get_entry_by_addr(PADAPTER, u8 *ra);
241*4882a593Smuzhiyun void rtw_bf_get_ndpa_packet(PADAPTER, union recv_frame *);
242*4882a593Smuzhiyun u32 rtw_bf_get_report_packet(PADAPTER, union recv_frame *);
243*4882a593Smuzhiyun u8 rtw_bf_send_vht_gid_mgnt_packet(PADAPTER, u8 *ra, u8 *gid, u8 *position);
244*4882a593Smuzhiyun void rtw_bf_get_vht_gid_mgnt_packet(PADAPTER, union recv_frame *);
245*4882a593Smuzhiyun void rtw_bf_init(PADAPTER);
246*4882a593Smuzhiyun void rtw_bf_cmd_hdl(PADAPTER, u8 type, u8 *pbuf);
247*4882a593Smuzhiyun u8 rtw_bf_cmd(PADAPTER, s32 type, u8 *pbuf, s32 size, u8 enqueue);
248*4882a593Smuzhiyun void rtw_bf_update_attrib(PADAPTER, struct pkt_attrib *, struct sta_info *);
249*4882a593Smuzhiyun void rtw_bf_c2h_handler(PADAPTER, u8 id, u8 *buf, u8 buf_len);
250*4882a593Smuzhiyun void rtw_bf_update_traffic(PADAPTER);
251*4882a593Smuzhiyun 
252*4882a593Smuzhiyun /* Compatible with old function name, only for using outside rtw_beamforming.c */
253*4882a593Smuzhiyun #define beamforming_get_entry_beam_cap_by_mac_id	rtw_bf_bfee_get_entry_cap_by_macid
254*4882a593Smuzhiyun #define rtw_beamforming_get_ndpa_frame			rtw_bf_get_ndpa_packet
255*4882a593Smuzhiyun #define rtw_beamforming_get_report_frame			rtw_bf_get_report_packet
256*4882a593Smuzhiyun #define rtw_beamforming_get_vht_gid_mgnt_frame		rtw_bf_get_vht_gid_mgnt_packet
257*4882a593Smuzhiyun #define beamforming_wk_hdl				rtw_bf_cmd_hdl
258*4882a593Smuzhiyun #define beamforming_wk_cmd				rtw_bf_cmd
259*4882a593Smuzhiyun #define update_attrib_txbf_info				rtw_bf_update_attrib
260*4882a593Smuzhiyun 
261*4882a593Smuzhiyun #define HT_BF_CAP(adapter) ((adapter)->mlmepriv.htpriv.beamform_cap)
262*4882a593Smuzhiyun #define VHT_BF_CAP(adapter) ((adapter)->mlmepriv.vhtpriv.beamform_cap)
263*4882a593Smuzhiyun 
264*4882a593Smuzhiyun #define IS_HT_BEAMFORMEE(adapter) \
265*4882a593Smuzhiyun 		(HT_BF_CAP(adapter) & \
266*4882a593Smuzhiyun 		(BEAMFORMING_HT_BEAMFORMEE_ENABLE))
267*4882a593Smuzhiyun 
268*4882a593Smuzhiyun #define IS_VHT_BEAMFORMEE(adapter) \
269*4882a593Smuzhiyun 		(VHT_BF_CAP(adapter) & \
270*4882a593Smuzhiyun 		(BEAMFORMING_VHT_BEAMFORMEE_ENABLE | \
271*4882a593Smuzhiyun 		 BEAMFORMING_VHT_MU_MIMO_STA_ENABLE))
272*4882a593Smuzhiyun 
273*4882a593Smuzhiyun #define IS_BEAMFORMEE(adapter) (IS_HT_BEAMFORMEE(adapter) | \
274*4882a593Smuzhiyun 				IS_VHT_BEAMFORMEE(adapter))
275*4882a593Smuzhiyun 
276*4882a593Smuzhiyun #else /* !RTW_BEAMFORMING_VERSION_2 */
277*4882a593Smuzhiyun /*PHYDM_BF - (BEAMFORMING_SUPPORT == 1)*/
278*4882a593Smuzhiyun enum BEAMFORMING_CTRL_TYPE {
279*4882a593Smuzhiyun 	BEAMFORMING_CTRL_ENTER = 0,
280*4882a593Smuzhiyun 	BEAMFORMING_CTRL_LEAVE = 1,
281*4882a593Smuzhiyun 	BEAMFORMING_CTRL_START_PERIOD = 2,
282*4882a593Smuzhiyun 	BEAMFORMING_CTRL_END_PERIOD = 3,
283*4882a593Smuzhiyun 	BEAMFORMING_CTRL_SOUNDING_FAIL = 4,
284*4882a593Smuzhiyun 	BEAMFORMING_CTRL_SOUNDING_CLK = 5,
285*4882a593Smuzhiyun };
286*4882a593Smuzhiyun u32	rtw_beamforming_get_report_frame(PADAPTER	 Adapter, union recv_frame *precv_frame);
287*4882a593Smuzhiyun void	rtw_beamforming_get_ndpa_frame(PADAPTER	 Adapter, union recv_frame *precv_frame);
288*4882a593Smuzhiyun 
289*4882a593Smuzhiyun void	beamforming_wk_hdl(_adapter *padapter, u8 type, u8 *pbuf);
290*4882a593Smuzhiyun u8	beamforming_wk_cmd(_adapter *padapter, s32 type, u8 *pbuf, s32 size, u8 enqueue);
291*4882a593Smuzhiyun void update_attrib_txbf_info(_adapter *padapter, struct pkt_attrib *pattrib, struct sta_info *psta);
292*4882a593Smuzhiyun 
293*4882a593Smuzhiyun #endif /* !RTW_BEAMFORMING_VERSION_2 */
294*4882a593Smuzhiyun 
295*4882a593Smuzhiyun #endif /*#ifdef CONFIG_BEAMFORMING */
296*4882a593Smuzhiyun 
297*4882a593Smuzhiyun #endif /*__RTW_BEAMFORMING_H_*/
298