android13/external/wifi_driver/rtl8852be/phl/phl_thermal.c

163 lines
4.3 KiB
C

/******************************************************************************
*
* Copyright(c) 2020 Realtek Corporation.
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of version 2 of the GNU General Public License as
* published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
* more details.
*
*****************************************************************************/
#define _PHL_THERMAL_C_
#include "phl_headers.h"
#ifdef CONFIG_PHL_THERMAL_PROTECT
static void _phl_thermal_protect_disable_all_txop(
struct phl_info_t *phl_info,
bool disable)
{
struct rtw_phl_com_t *phl_com = phl_info->phl_com;
struct mr_ctl_t *mr_ctl = phlcom_to_mr_ctrl(phl_com);
struct rtw_wifi_role_t *wrole = NULL;
struct rtw_phl_stainfo_t *sta = NULL;
struct rtw_edca_param edca = {0};
u8 i = 0;
for (i = 0; i < MAX_WIFI_ROLE_NUMBER; i++) {
if (mr_ctl->role_map & BIT(i)) {
wrole = rtw_phl_get_wrole_by_ridx(phl_info->phl_com, i);
if(wrole){
if(wrole->mstate == MLME_LINKED)
break;
}
wrole = NULL;
continue;
}
}
if(wrole == NULL)
return;
sta = rtw_phl_get_stainfo_self(phl_info, wrole);
if(sta == NULL)
return;
for(i = 0; i < 4;i++){
edca.ac = i;
edca.param = sta->asoc_cap.edca[edca.ac].param;
if(disable)
edca.param &= 0x0000FFFF;
if(rtw_hal_set_edca(phl_info->hal, wrole, edca.ac, edca.param)
!= RTW_HAL_STATUS_SUCCESS)
PHL_ERR("%s Config edca fail\n", __FUNCTION__);
}
}
static void _phl_thermal_protect_reduce_ampdu_num(
struct phl_info_t *phl_info,
u8 ratio)
{
struct rtw_phl_com_t *phl_com = phl_info->phl_com;
struct mr_ctl_t *mr_ctl = phlcom_to_mr_ctrl(phl_com);
struct rtw_wifi_role_t *wrole = NULL;
struct rtw_phl_stainfo_t *sta = NULL;
u8 i = 0;
for (i = 0; i < MAX_WIFI_ROLE_NUMBER; i++) {
if (mr_ctl->role_map & BIT(i)) {
wrole = rtw_phl_get_wrole_by_ridx(phl_info->phl_com, i);
if(wrole){
if(wrole->mstate == MLME_LINKED)
break;
}
wrole = NULL;
continue;
}
}
if(wrole == NULL)
return;
sta = rtw_phl_get_stainfo_self(phl_info, wrole);
if(sta == NULL)
return;
if(ratio != 0){
if(rtw_hal_thermal_protect_cfg_tx_ampdu(phl_info->hal, sta, ratio)
!= RTW_HAL_STATUS_SUCCESS)
PHL_ERR("%s Thermal protect cfg tx ampdu fail\n", __FUNCTION__);
}
else{
if(sta->asoc_cap.num_ampdu_bk != 0){
sta->asoc_cap.num_ampdu = sta->asoc_cap.num_ampdu_bk;
sta->asoc_cap.num_ampdu_bk = 0;
}
if(rtw_hal_cfg_tx_ampdu(phl_info->hal, sta) !=
RTW_HAL_STATUS_SUCCESS)
PHL_ERR("%s Thermal protect restore tx ampdu fail\n", __FUNCTION__);
}
}
void phl_thermal_protect_watchdog(struct phl_info_t *phl_info)
{
struct rtw_phl_com_t *phl_com = phl_info->phl_com;
bool action_changed = false;
if(phl_com->drv_mode != RTW_DRV_MODE_NORMAL &&
phl_com->drv_mode != RTW_DRV_MODE_HIGH_THERMAL)
return;
action_changed = rtw_hal_check_thermal_protect(phl_com, phl_info->hal);
if(action_changed == false)
return;
switch (phl_com->thermal_protect_action){
case PHL_THERMAL_PROTECT_ACTION_NONE:
_phl_thermal_protect_disable_all_txop(phl_info, false);
_phl_thermal_protect_reduce_ampdu_num(phl_info, 0);
break;
case PHL_THERMAL_PROTECT_ACTION_LEVEL1:
_phl_thermal_protect_disable_all_txop(phl_info, true);
_phl_thermal_protect_reduce_ampdu_num(phl_info, 70);
break;
case PHL_THERMAL_PROTECT_ACTION_LEVEL2:
_phl_thermal_protect_reduce_ampdu_num(phl_info, 50);
break;
default:
break;
}
}
#endif /* CONFIG_PHL_THERMAL_PROTECT */
void phl_thermal_protect_cfg_tx_duty(
struct phl_info_t *phl_info,
u16 tx_duty_interval,
u8 ratio)
{
enum rtw_hal_status hal_status = RTW_HAL_STATUS_SUCCESS;
hal_status = rtw_hal_thermal_protect_cfg_tx_duty(phl_info->hal,
tx_duty_interval,
ratio);
if(hal_status != RTW_HAL_STATUS_SUCCESS)
PHL_ERR("%s Thermal protect cfg tx duty fail\n", __FUNCTION__);
}
void phl_thermal_protect_stop_tx_duty(struct phl_info_t *phl_info)
{
enum rtw_hal_status hal_status = RTW_HAL_STATUS_SUCCESS;
hal_status = rtw_hal_thermal_protect_stop_tx_duty(phl_info->hal);
if(hal_status != RTW_HAL_STATUS_SUCCESS)
PHL_ERR("%s Thermal protect stop tx duty fail\n", __FUNCTION__);
}