xref: /OK3568_Linux_fs/external/rkwifibt/drivers/rtl8852be/phl/phl_thermal.c (revision 4882a59341e53eb6f0b4789bf948001014eff981)
1 /******************************************************************************
2  *
3  * Copyright(c) 2020 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 #define _PHL_THERMAL_C_
16 #include "phl_headers.h"
17 
18 #ifdef CONFIG_PHL_THERMAL_PROTECT
19 
_phl_thermal_protect_disable_all_txop(struct phl_info_t * phl_info,bool disable)20 static void _phl_thermal_protect_disable_all_txop(
21 	struct phl_info_t *phl_info,
22 	bool disable)
23 {
24 	struct rtw_phl_com_t *phl_com = phl_info->phl_com;
25 	struct mr_ctl_t *mr_ctl = phlcom_to_mr_ctrl(phl_com);
26 	struct rtw_wifi_role_t *wrole = NULL;
27 	struct rtw_phl_stainfo_t *sta = NULL;
28 	struct rtw_edca_param edca = {0};
29 	u8 i = 0;
30 
31 	for (i = 0; i < MAX_WIFI_ROLE_NUMBER; i++) {
32 		if (mr_ctl->role_map & BIT(i)) {
33 			wrole = rtw_phl_get_wrole_by_ridx(phl_info->phl_com, i);
34 			if(wrole){
35 				if(wrole->mstate == MLME_LINKED)
36 					break;
37 			}
38 			wrole = NULL;
39 			continue;
40 		}
41 	}
42 
43 	if(wrole == NULL)
44 		return;
45 
46 	sta = rtw_phl_get_stainfo_self(phl_info, wrole);
47 
48 	if(sta == NULL)
49 		return;
50 
51 	for(i = 0; i < 4;i++){
52 		edca.ac = i;
53 		edca.param = sta->asoc_cap.edca[edca.ac].param;
54 		if(disable)
55 			edca.param &= 0x0000FFFF;
56 		if(rtw_hal_set_edca(phl_info->hal, wrole, edca.ac, edca.param)
57 		   != RTW_HAL_STATUS_SUCCESS)
58 			PHL_ERR("%s Config edca fail\n", __FUNCTION__);
59 	}
60 }
61 
_phl_thermal_protect_reduce_ampdu_num(struct phl_info_t * phl_info,u8 ratio)62 static void _phl_thermal_protect_reduce_ampdu_num(
63 	struct phl_info_t *phl_info,
64 	u8 ratio)
65 {
66 	struct rtw_phl_com_t *phl_com = phl_info->phl_com;
67 	struct mr_ctl_t *mr_ctl = phlcom_to_mr_ctrl(phl_com);
68 	struct rtw_wifi_role_t *wrole = NULL;
69 	struct rtw_phl_stainfo_t *sta = NULL;
70 	u8 i = 0;
71 
72 	for (i = 0; i < MAX_WIFI_ROLE_NUMBER; i++) {
73 		if (mr_ctl->role_map & BIT(i)) {
74 			wrole = rtw_phl_get_wrole_by_ridx(phl_info->phl_com, i);
75 			if(wrole){
76 				if(wrole->mstate == MLME_LINKED)
77 					break;
78 			}
79 			wrole = NULL;
80 			continue;
81 		}
82 	}
83 
84 	if(wrole == NULL)
85 		return;
86 
87 	sta = rtw_phl_get_stainfo_self(phl_info, wrole);
88 
89 	if(sta == NULL)
90 		return;
91 
92 	if(ratio != 0){
93 		if(rtw_hal_thermal_protect_cfg_tx_ampdu(phl_info->hal, sta, ratio)
94 		   != RTW_HAL_STATUS_SUCCESS)
95 			PHL_ERR("%s Thermal protect cfg tx ampdu fail\n", __FUNCTION__);
96 	}
97 	else{
98 		if(sta->asoc_cap.num_ampdu_bk != 0){
99 			sta->asoc_cap.num_ampdu = sta->asoc_cap.num_ampdu_bk;
100 			sta->asoc_cap.num_ampdu_bk = 0;
101 		}
102 		if(rtw_hal_cfg_tx_ampdu(phl_info->hal, sta) !=
103 		   RTW_HAL_STATUS_SUCCESS)
104 			PHL_ERR("%s Thermal protect restore tx ampdu fail\n", __FUNCTION__);
105 	}
106 
107 }
108 
phl_thermal_protect_watchdog(struct phl_info_t * phl_info)109 void phl_thermal_protect_watchdog(struct phl_info_t *phl_info)
110 {
111 	struct rtw_phl_com_t *phl_com = phl_info->phl_com;
112 	bool action_changed = false;
113 
114 	if(phl_com->drv_mode != RTW_DRV_MODE_NORMAL &&
115 	   phl_com->drv_mode != RTW_DRV_MODE_HIGH_THERMAL)
116 		return;
117 
118 	action_changed = rtw_hal_check_thermal_protect(phl_com, phl_info->hal);
119 
120 	if(action_changed == false)
121 		return;
122 
123 	switch (phl_com->thermal_protect_action){
124 		case PHL_THERMAL_PROTECT_ACTION_NONE:
125 			_phl_thermal_protect_disable_all_txop(phl_info, false);
126 			_phl_thermal_protect_reduce_ampdu_num(phl_info, 0);
127 			break;
128 		case PHL_THERMAL_PROTECT_ACTION_LEVEL1:
129 			_phl_thermal_protect_disable_all_txop(phl_info, true);
130 			_phl_thermal_protect_reduce_ampdu_num(phl_info, 70);
131 			break;
132 		case PHL_THERMAL_PROTECT_ACTION_LEVEL2:
133 			_phl_thermal_protect_reduce_ampdu_num(phl_info, 50);
134 			break;
135 		default:
136 			break;
137 	}
138 }
139 
140 #endif /* CONFIG_PHL_THERMAL_PROTECT */
141 
phl_thermal_protect_cfg_tx_duty(struct phl_info_t * phl_info,u16 tx_duty_interval,u8 ratio)142 void phl_thermal_protect_cfg_tx_duty(
143 	struct phl_info_t *phl_info,
144 	u16 tx_duty_interval,
145 	u8 ratio)
146 {
147 	enum rtw_hal_status hal_status = RTW_HAL_STATUS_SUCCESS;
148 
149 	hal_status = rtw_hal_thermal_protect_cfg_tx_duty(phl_info->hal,
150 							 tx_duty_interval,
151 							 ratio);
152 	if(hal_status != RTW_HAL_STATUS_SUCCESS)
153 		PHL_ERR("%s Thermal protect cfg tx duty fail\n", __FUNCTION__);
154 }
155 
phl_thermal_protect_stop_tx_duty(struct phl_info_t * phl_info)156 void phl_thermal_protect_stop_tx_duty(struct phl_info_t *phl_info)
157 {
158 	enum rtw_hal_status hal_status = RTW_HAL_STATUS_SUCCESS;
159 
160 	hal_status = rtw_hal_thermal_protect_stop_tx_duty(phl_info->hal);
161 	if(hal_status != RTW_HAL_STATUS_SUCCESS)
162 		PHL_ERR("%s Thermal protect stop tx duty fail\n", __FUNCTION__);
163 }