1*4882a593Smuzhiyun /****************************************************************************** 2*4882a593Smuzhiyun * 3*4882a593Smuzhiyun * Copyright(c) 2015 - 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 #ifdef CONFIG_MCC_MODE 16*4882a593Smuzhiyun 17*4882a593Smuzhiyun #ifndef _RTW_MCC_H_ 18*4882a593Smuzhiyun #define _RTW_MCC_H_ 19*4882a593Smuzhiyun 20*4882a593Smuzhiyun #include <drv_types.h> /* PADAPTER */ 21*4882a593Smuzhiyun 22*4882a593Smuzhiyun #define MCC_STATUS_PROCESS_MCC_START_SETTING BIT0 23*4882a593Smuzhiyun #define MCC_STATUS_PROCESS_MCC_STOP_SETTING BIT1 24*4882a593Smuzhiyun #define MCC_STATUS_NEED_MCC BIT2 25*4882a593Smuzhiyun #define MCC_STATUS_DOING_MCC BIT3 26*4882a593Smuzhiyun 27*4882a593Smuzhiyun 28*4882a593Smuzhiyun #define MCC_SWCH_FW_EARLY_TIME 10 /* ms */ 29*4882a593Smuzhiyun #define MCC_EXPIRE_TIME 50 /* ms */ 30*4882a593Smuzhiyun #define MCC_TOLERANCE_TIME 2 /* 2*2 = 4s */ 31*4882a593Smuzhiyun #define MCC_UPDATE_PARAMETER_THRESHOLD 5 /* ms */ 32*4882a593Smuzhiyun 33*4882a593Smuzhiyun #define MCC_ROLE_STA_GC_MGMT_QUEUE_MACID 0 34*4882a593Smuzhiyun #define MCC_ROLE_SOFTAP_GO_MGMT_QUEUE_MACID 1 35*4882a593Smuzhiyun 36*4882a593Smuzhiyun /* Lower for stop, Higher for start */ 37*4882a593Smuzhiyun #define MCC_SETCMD_STATUS_STOP_DISCONNECT 0x0 38*4882a593Smuzhiyun #define MCC_SETCMD_STATUS_STOP_SCAN_START 0x1 39*4882a593Smuzhiyun #define MCC_SETCMD_STATUS_START_CONNECT 0x80 40*4882a593Smuzhiyun #define MCC_SETCMD_STATUS_START_SCAN_DONE 0x81 41*4882a593Smuzhiyun 42*4882a593Smuzhiyun /* 43*4882a593Smuzhiyun * depenad platform or customer requirement(TP unit:Mbps), 44*4882a593Smuzhiyun * must be provided by PM or sales or product document 45*4882a593Smuzhiyun * too large value means not to limit tx bytes (current for ap mode) 46*4882a593Smuzhiyun * NOTE: following values ref from test results 47*4882a593Smuzhiyun */ 48*4882a593Smuzhiyun #define MCC_AP_BW20_TARGET_TX_TP (300) 49*4882a593Smuzhiyun #define MCC_AP_BW40_TARGET_TX_TP (300) 50*4882a593Smuzhiyun #define MCC_AP_BW80_TARGET_TX_TP (300) 51*4882a593Smuzhiyun #define MCC_STA_BW20_TARGET_TX_TP (35) 52*4882a593Smuzhiyun #define MCC_STA_BW40_TARGET_TX_TP (70) 53*4882a593Smuzhiyun #define MCC_STA_BW80_TARGET_TX_TP (140) 54*4882a593Smuzhiyun #define MCC_SINGLE_TX_CRITERIA 5 /* Mbps */ 55*4882a593Smuzhiyun 56*4882a593Smuzhiyun #define MAX_MCC_NUM 2 57*4882a593Smuzhiyun #ifdef CONFIG_RTL8822C 58*4882a593Smuzhiyun #define DBG_MCC_REG_NUM 3 59*4882a593Smuzhiyun #else 60*4882a593Smuzhiyun #define DBG_MCC_REG_NUM 4 61*4882a593Smuzhiyun #endif 62*4882a593Smuzhiyun #define DBG_MCC_RF_REG_NUM 1 63*4882a593Smuzhiyun 64*4882a593Smuzhiyun #define MCC_STOP(adapter) (adapter->mcc_adapterpriv.mcc_tx_stop) 65*4882a593Smuzhiyun #define MCC_EN(adapter) (adapter_to_dvobj(adapter)->mcc_objpriv.en_mcc) 66*4882a593Smuzhiyun #define adapter_to_mccobjpriv(adapter) (&(adapter_to_dvobj(adapter)->mcc_objpriv)) 67*4882a593Smuzhiyun #define SET_MCC_EN_FLAG(adapter, flag)\ 68*4882a593Smuzhiyun do { \ 69*4882a593Smuzhiyun adapter_to_dvobj(adapter)->mcc_objpriv.en_mcc = (flag); \ 70*4882a593Smuzhiyun } while (0) 71*4882a593Smuzhiyun #define SET_MCC_DURATION(adapter, val)\ 72*4882a593Smuzhiyun do { \ 73*4882a593Smuzhiyun adapter_to_dvobj(adapter)->mcc_objpriv.duration = (val); \ 74*4882a593Smuzhiyun } while (0) 75*4882a593Smuzhiyun #define SET_MCC_RUNTIME_DURATION(adapter, flag)\ 76*4882a593Smuzhiyun do { \ 77*4882a593Smuzhiyun adapter_to_dvobj(adapter)->mcc_objpriv.enable_runtime_duration = (flag); \ 78*4882a593Smuzhiyun } while (0) 79*4882a593Smuzhiyun 80*4882a593Smuzhiyun #define SET_MCC_PHYDM_OFFLOAD(adapter, flag)\ 81*4882a593Smuzhiyun do { \ 82*4882a593Smuzhiyun adapter_to_dvobj(adapter)->mcc_objpriv.mcc_phydm_offload = (flag); \ 83*4882a593Smuzhiyun } while (0) 84*4882a593Smuzhiyun 85*4882a593Smuzhiyun #ifdef CONFIG_MCC_PHYDM_OFFLOAD 86*4882a593Smuzhiyun enum mcc_cfg_phydm_ops { 87*4882a593Smuzhiyun MCC_CFG_PHYDM_OFFLOAD = 0, 88*4882a593Smuzhiyun MCC_CFG_PHYDM_RF_CH, 89*4882a593Smuzhiyun MCC_CFG_PHYDM_ADD_CLIENT, 90*4882a593Smuzhiyun MCC_CFG_PHYDM_REMOVE_CLIENT, 91*4882a593Smuzhiyun MCC_CFG_PHYDM_START, 92*4882a593Smuzhiyun MCC_CFG_PHYDM_STOP, 93*4882a593Smuzhiyun MCC_CFG_PHYDM_DUMP, 94*4882a593Smuzhiyun MCC_CFG_PHYDM_MAX, 95*4882a593Smuzhiyun }; 96*4882a593Smuzhiyun #endif 97*4882a593Smuzhiyun 98*4882a593Smuzhiyun enum rtw_mcc_cmd_id { 99*4882a593Smuzhiyun MCC_CMD_WK_CID = 0, 100*4882a593Smuzhiyun MCC_SET_DURATION_WK_CID, 101*4882a593Smuzhiyun MCC_GET_DBG_REG_WK_CID, 102*4882a593Smuzhiyun #ifdef CONFIG_MCC_PHYDM_OFFLOAD 103*4882a593Smuzhiyun MCC_SET_PHYDM_OFFLOAD_WK_CID, 104*4882a593Smuzhiyun #endif 105*4882a593Smuzhiyun }; 106*4882a593Smuzhiyun 107*4882a593Smuzhiyun /* Represent Channel Tx Null setting */ 108*4882a593Smuzhiyun enum mcc_channel_tx_null { 109*4882a593Smuzhiyun MCC_ENABLE_TX_NULL = 0, 110*4882a593Smuzhiyun MCC_DISABLE_TX_NULL = 1, 111*4882a593Smuzhiyun }; 112*4882a593Smuzhiyun 113*4882a593Smuzhiyun /* Represent C2H Report setting */ 114*4882a593Smuzhiyun enum mcc_c2h_report { 115*4882a593Smuzhiyun MCC_C2H_REPORT_DISABLE = 0, 116*4882a593Smuzhiyun MCC_C2H_REPORT_FAIL_STATUS = 1, 117*4882a593Smuzhiyun MCC_C2H_REPORT_ALL_STATUS = 2, 118*4882a593Smuzhiyun }; 119*4882a593Smuzhiyun 120*4882a593Smuzhiyun /* Represent Channel Scan */ 121*4882a593Smuzhiyun enum mcc_channel_scan { 122*4882a593Smuzhiyun MCC_CHIDX = 0, 123*4882a593Smuzhiyun MCC_SCANCH_RSVD_LOC = 1, 124*4882a593Smuzhiyun }; 125*4882a593Smuzhiyun 126*4882a593Smuzhiyun /* Represent FW status report of channel switch */ 127*4882a593Smuzhiyun enum mcc_status_rpt { 128*4882a593Smuzhiyun MCC_RPT_SUCCESS = 0, 129*4882a593Smuzhiyun MCC_RPT_TXNULL_FAIL = 1, 130*4882a593Smuzhiyun MCC_RPT_STOPMCC = 2, 131*4882a593Smuzhiyun MCC_RPT_READY = 3, 132*4882a593Smuzhiyun MCC_RPT_SWICH_CHANNEL_NOTIFY = 7, 133*4882a593Smuzhiyun MCC_RPT_UPDATE_NOA_START_TIME = 8, 134*4882a593Smuzhiyun MCC_RPT_TSF = 9, 135*4882a593Smuzhiyun MCC_RPT_MAX, 136*4882a593Smuzhiyun }; 137*4882a593Smuzhiyun 138*4882a593Smuzhiyun enum mcc_role { 139*4882a593Smuzhiyun MCC_ROLE_STA = 0, 140*4882a593Smuzhiyun MCC_ROLE_AP = 1, 141*4882a593Smuzhiyun MCC_ROLE_GC = 2, 142*4882a593Smuzhiyun MCC_ROLE_GO = 3, 143*4882a593Smuzhiyun MCC_ROLE_MAX, 144*4882a593Smuzhiyun }; 145*4882a593Smuzhiyun 146*4882a593Smuzhiyun struct mcc_iqk_backup { 147*4882a593Smuzhiyun u16 TX_X; 148*4882a593Smuzhiyun u16 TX_Y; 149*4882a593Smuzhiyun u16 RX_X; 150*4882a593Smuzhiyun u16 RX_Y; 151*4882a593Smuzhiyun }; 152*4882a593Smuzhiyun 153*4882a593Smuzhiyun enum mcc_duration_setting { 154*4882a593Smuzhiyun MCC_DURATION_MAPPING = 0, 155*4882a593Smuzhiyun MCC_DURATION_DIRECET = 1, 156*4882a593Smuzhiyun }; 157*4882a593Smuzhiyun 158*4882a593Smuzhiyun enum mcc_sched_mode { 159*4882a593Smuzhiyun MCC_FAIR_SCHEDULE = 0, 160*4882a593Smuzhiyun MCC_FAVOR_STA = 1, 161*4882a593Smuzhiyun MCC_FAVOR_P2P = 2, 162*4882a593Smuzhiyun }; 163*4882a593Smuzhiyun 164*4882a593Smuzhiyun /* mcc data for adapter */ 165*4882a593Smuzhiyun struct mcc_adapter_priv { 166*4882a593Smuzhiyun u8 order; /* FW document, softap/AP must be 0 */ 167*4882a593Smuzhiyun enum mcc_role role; /* MCC role(AP,STA,GO,GC) */ 168*4882a593Smuzhiyun u8 mcc_duration; /* channel stay period, UNIT:1TU */ 169*4882a593Smuzhiyun 170*4882a593Smuzhiyun /* flow control */ 171*4882a593Smuzhiyun u8 mcc_tx_stop; /* check if tp stop or not */ 172*4882a593Smuzhiyun u8 mcc_tp_limit; /* check if tp limit or not */ 173*4882a593Smuzhiyun u32 mcc_target_tx_bytes_to_port; /* customer require */ 174*4882a593Smuzhiyun u32 mcc_tx_bytes_to_port; /* already tx to tx fifo (write port) */ 175*4882a593Smuzhiyun 176*4882a593Smuzhiyun /* data from kernel to check if enqueue data or netif stop queue */ 177*4882a593Smuzhiyun u32 mcc_tp; 178*4882a593Smuzhiyun u64 mcc_tx_bytes_from_kernel; 179*4882a593Smuzhiyun u64 mcc_last_tx_bytes_from_kernel; 180*4882a593Smuzhiyun 181*4882a593Smuzhiyun /* Backup IQK value for MCC */ 182*4882a593Smuzhiyun struct mcc_iqk_backup mcc_iqk_arr[MAX_RF_PATH]; 183*4882a593Smuzhiyun 184*4882a593Smuzhiyun /* mgmt queue macid to avoid RA issue */ 185*4882a593Smuzhiyun u8 mgmt_queue_macid; 186*4882a593Smuzhiyun 187*4882a593Smuzhiyun /* set macid bitmap to let fw know which macid should be tx pause */ 188*4882a593Smuzhiyun /* all interface share total 16 macid */ 189*4882a593Smuzhiyun u16 mcc_macid_bitmap; 190*4882a593Smuzhiyun 191*4882a593Smuzhiyun /* use for NoA start time (unit: mircoseconds) */ 192*4882a593Smuzhiyun u32 noa_start_time; 193*4882a593Smuzhiyun 194*4882a593Smuzhiyun u8 p2p_go_noa_ie[MAX_P2P_IE_LEN]; 195*4882a593Smuzhiyun u32 p2p_go_noa_ie_len; 196*4882a593Smuzhiyun u64 tsf; 197*4882a593Smuzhiyun #ifdef CONFIG_TDLS 198*4882a593Smuzhiyun u8 backup_tdls_en; 199*4882a593Smuzhiyun #endif /* CONFIG_TDLS */ 200*4882a593Smuzhiyun 201*4882a593Smuzhiyun u8 null_early; 202*4882a593Smuzhiyun u8 null_rty_num; 203*4882a593Smuzhiyun }; 204*4882a593Smuzhiyun 205*4882a593Smuzhiyun struct mcc_obj_priv { 206*4882a593Smuzhiyun u8 en_mcc; /* enable MCC or not */ 207*4882a593Smuzhiyun u8 duration; /* store duration(%) from registry, for primary adapter */ 208*4882a593Smuzhiyun u8 interval; 209*4882a593Smuzhiyun u8 start_time; 210*4882a593Smuzhiyun u8 mcc_c2h_status; 211*4882a593Smuzhiyun u8 cur_mcc_success_cnt; /* used for check mcc switch channel success */ 212*4882a593Smuzhiyun u8 prev_mcc_success_cnt; /* used for check mcc switch channel success */ 213*4882a593Smuzhiyun u8 mcc_tolerance_time; /* used for detect mcc switch channel success */ 214*4882a593Smuzhiyun u8 mcc_loc_rsvd_paga[MAX_MCC_NUM]; /* mcc rsvd page */ 215*4882a593Smuzhiyun u8 mcc_status; /* mcc status stop or start .... */ 216*4882a593Smuzhiyun u8 policy_index; 217*4882a593Smuzhiyun u8 mcc_stop_threshold; 218*4882a593Smuzhiyun u8 current_order; 219*4882a593Smuzhiyun u8 last_tsfdiff; 220*4882a593Smuzhiyun systime mcc_launch_time; /* mcc launch time, used for starting detect mcc switch channel success */ 221*4882a593Smuzhiyun _mutex mcc_mutex; 222*4882a593Smuzhiyun _lock mcc_lock; 223*4882a593Smuzhiyun PADAPTER iface[MAX_MCC_NUM]; /* by order, use for mcc parameter cmd */ 224*4882a593Smuzhiyun struct submit_ctx mcc_sctx; 225*4882a593Smuzhiyun struct submit_ctx mcc_tsf_req_sctx; 226*4882a593Smuzhiyun _mutex mcc_tsf_req_mutex; 227*4882a593Smuzhiyun u8 mcc_tsf_req_sctx_order; /* record current order for mcc_tsf_req_sctx */ 228*4882a593Smuzhiyun #ifdef CONFIG_MCC_MODE_V2 229*4882a593Smuzhiyun u8 mcc_iqk_value_rsvd_page[3]; 230*4882a593Smuzhiyun #endif /* CONFIG_MCC_MODE_V2 */ 231*4882a593Smuzhiyun u8 mcc_pwr_idx_rsvd_page[MAX_MCC_NUM]; 232*4882a593Smuzhiyun u8 enable_runtime_duration; 233*4882a593Smuzhiyun /* for LG */ 234*4882a593Smuzhiyun u8 mchan_sched_mode; 235*4882a593Smuzhiyun 236*4882a593Smuzhiyun _mutex mcc_dbg_reg_mutex; 237*4882a593Smuzhiyun u32 dbg_reg[DBG_MCC_REG_NUM]; 238*4882a593Smuzhiyun u32 dbg_reg_val[DBG_MCC_REG_NUM]; 239*4882a593Smuzhiyun u32 dbg_rf_reg[DBG_MCC_RF_REG_NUM]; 240*4882a593Smuzhiyun u32 dbg_rf_reg_val[DBG_MCC_RF_REG_NUM][MAX_RF_PATH]; 241*4882a593Smuzhiyun u8 mcc_phydm_offload; 242*4882a593Smuzhiyun }; 243*4882a593Smuzhiyun 244*4882a593Smuzhiyun /* backup IQK val */ 245*4882a593Smuzhiyun void rtw_hal_mcc_restore_iqk_val(PADAPTER padapter); 246*4882a593Smuzhiyun 247*4882a593Smuzhiyun /* check mcc status */ 248*4882a593Smuzhiyun u8 rtw_hal_check_mcc_status(PADAPTER padapter, u8 mcc_status); 249*4882a593Smuzhiyun 250*4882a593Smuzhiyun /* set mcc status */ 251*4882a593Smuzhiyun void rtw_hal_set_mcc_status(PADAPTER padapter, u8 mcc_status); 252*4882a593Smuzhiyun 253*4882a593Smuzhiyun /* clear mcc status */ 254*4882a593Smuzhiyun void rtw_hal_clear_mcc_status(PADAPTER padapter, u8 mcc_status); 255*4882a593Smuzhiyun 256*4882a593Smuzhiyun /* dl mcc rsvd page */ 257*4882a593Smuzhiyun u8 rtw_hal_dl_mcc_fw_rsvd_page(_adapter *adapter, u8 *pframe, u16 *index 258*4882a593Smuzhiyun , u8 tx_desc, u32 page_size, u8 *total_page_num, RSVDPAGE_LOC *rsvd_page_loc, u8 *page_num); 259*4882a593Smuzhiyun 260*4882a593Smuzhiyun /* handle C2H */ 261*4882a593Smuzhiyun void rtw_hal_mcc_c2h_handler(PADAPTER padapter, u8 buflen, u8 *tmpBuf); 262*4882a593Smuzhiyun 263*4882a593Smuzhiyun /* switch channel successfully or not */ 264*4882a593Smuzhiyun void rtw_hal_mcc_sw_status_check(PADAPTER padapter); 265*4882a593Smuzhiyun 266*4882a593Smuzhiyun /* change some scan flags under site survey */ 267*4882a593Smuzhiyun u8 rtw_hal_mcc_change_scan_flag(PADAPTER padapter, u8 *ch, u8 *bw, u8 *offset); 268*4882a593Smuzhiyun 269*4882a593Smuzhiyun /* record data kernel TX to driver to check MCC concurrent TX */ 270*4882a593Smuzhiyun void rtw_hal_mcc_calc_tx_bytes_from_kernel(PADAPTER padapter, u32 len); 271*4882a593Smuzhiyun 272*4882a593Smuzhiyun /* record data to port to let driver do flow ctrl */ 273*4882a593Smuzhiyun void rtw_hal_mcc_calc_tx_bytes_to_port(PADAPTER padapter, u32 len); 274*4882a593Smuzhiyun 275*4882a593Smuzhiyun /* check stop write port or not */ 276*4882a593Smuzhiyun u8 rtw_hal_mcc_stop_tx_bytes_to_port(PADAPTER padapter); 277*4882a593Smuzhiyun 278*4882a593Smuzhiyun u8 rtw_hal_set_mcc_setting_scan_start(PADAPTER padapter); 279*4882a593Smuzhiyun 280*4882a593Smuzhiyun u8 rtw_hal_set_mcc_setting_scan_complete(PADAPTER padapter); 281*4882a593Smuzhiyun 282*4882a593Smuzhiyun u8 rtw_hal_set_mcc_setting_start_bss_network(PADAPTER padapter, u8 chbw_grouped); 283*4882a593Smuzhiyun 284*4882a593Smuzhiyun u8 rtw_hal_set_mcc_setting_disconnect(PADAPTER padapter); 285*4882a593Smuzhiyun 286*4882a593Smuzhiyun u8 rtw_hal_set_mcc_setting_join_done_chk_ch(PADAPTER padapter); 287*4882a593Smuzhiyun 288*4882a593Smuzhiyun u8 rtw_hal_set_mcc_setting_chk_start_clnt_join(PADAPTER padapter, u8 *ch, u8 *bw, u8 *offset, u8 chbw_allow); 289*4882a593Smuzhiyun 290*4882a593Smuzhiyun void rtw_hal_dump_mcc_info(void *sel, struct dvobj_priv *dvobj); 291*4882a593Smuzhiyun 292*4882a593Smuzhiyun void update_mcc_mgntframe_attrib(_adapter *padapter, struct pkt_attrib *pattrib); 293*4882a593Smuzhiyun 294*4882a593Smuzhiyun u8 rtw_hal_mcc_link_status_chk(_adapter *padapter, const char *msg); 295*4882a593Smuzhiyun 296*4882a593Smuzhiyun void rtw_hal_mcc_issue_null_data(_adapter *padapter, u8 chbw_allow, u8 ps_mode); 297*4882a593Smuzhiyun 298*4882a593Smuzhiyun u8 *rtw_hal_mcc_append_go_p2p_ie(PADAPTER padapter, u8 *pframe, u32 *len); 299*4882a593Smuzhiyun 300*4882a593Smuzhiyun void rtw_hal_dump_mcc_policy_table(void *sel); 301*4882a593Smuzhiyun 302*4882a593Smuzhiyun void rtw_hal_mcc_update_macid_bitmap(PADAPTER padapter, int mac_id, u8 add); 303*4882a593Smuzhiyun 304*4882a593Smuzhiyun void rtw_hal_mcc_process_noa(PADAPTER padapter); 305*4882a593Smuzhiyun 306*4882a593Smuzhiyun void rtw_hal_mcc_parameter_init(PADAPTER padapter); 307*4882a593Smuzhiyun 308*4882a593Smuzhiyun u8 rtw_mcc_cmd_hdl(PADAPTER adapter, u8 type, const u8 *val); 309*4882a593Smuzhiyun 310*4882a593Smuzhiyun u8 rtw_set_mcc_duration_cmd(_adapter *adapter, u8 type, u8 val); 311*4882a593Smuzhiyun #ifdef CONFIG_MCC_PHYDM_OFFLOAD 312*4882a593Smuzhiyun u8 rtw_set_mcc_phydm_offload_enable_cmd(PADAPTER adapter, u8 enable, u8 enqueue); 313*4882a593Smuzhiyun #endif /* CONFIG_MCC_PHYDM_OFFLOAD */ 314*4882a593Smuzhiyun #endif /* _RTW_MCC_H_ */ 315*4882a593Smuzhiyun #endif /* CONFIG_MCC_MODE */ 316