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