/****************************************************************************** * * Copyright(c) 2021 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_TXPWR_C_ #include "phl_headers.h" int rtw_phl_get_pw_lmt_regu_type_from_str(void *phl, const char *str) { /* 2G/5G only, TOBE REMOVED */ struct phl_info_t *phl_info = phl; return rtw_hal_get_pw_lmt_regu_type_from_str(phl_info->hal , BAND_ON_24G/* 2G and 5G use same array */, str); } const char *rtw_phl_get_pw_lmt_regu_str_from_type(void *phl, u8 regu) { /* 2G/5G only, TOBE REMOVED */ struct phl_info_t *phl_info = phl; return rtw_hal_get_pw_lmt_regu_str_from_type(phl_info->hal , BAND_ON_24G/* 2G and 5G use same array */, regu); } int rtw_phl_get_pw_lmt_regu_type_of_band_from_str(void *phl , enum band_type band, const char *str) { struct phl_info_t *phl_info = phl; return rtw_hal_get_pw_lmt_regu_type_from_str(phl_info->hal, band, str); } const char *rtw_phl_get_pw_lmt_regu_str_from_type_of_band(void *phl , enum band_type band, u8 regu) { struct phl_info_t *phl_info = phl; return rtw_hal_get_pw_lmt_regu_str_from_type(phl_info->hal, band, regu); } const char *rtw_phl_get_pw_lmt_regu_type_str(void *phl, enum band_type band) { struct phl_info_t *phl_info = phl; return rtw_hal_get_pw_lmt_regu_type_str(phl_info->hal, band); } bool rtw_phl_pw_lmt_regu_tbl_exist(void *phl, enum band_type band, u8 regu) { struct phl_info_t *phl_info = phl; return rtw_hal_pw_lmt_regu_tbl_exist(phl_info->hal, band, regu); } u8 rtw_phl_ext_reg_codemap_search(void *phl, u16 domain_code, const char *country , const char **reg_name) { /* 2G/5G only, TOBE REMOVED */ struct phl_info_t *phl_info = phl; return rtw_hal_ext_reg_codemap_search(phl_info->hal , BAND_ON_24G/* 2G and 5G use same array */ , domain_code, country, reg_name); } u8 rtw_phl_ext_reg_codemap_of_band_search(void *phl, enum band_type band , u16 domain_code, const char *country, const char **reg_name) { struct phl_info_t *phl_info = phl; return rtw_hal_ext_reg_codemap_search(phl_info->hal, band , domain_code, country, reg_name); } bool rtw_phl_get_pwr_lmt_en(void *phl, u8 band_idx) { struct phl_info_t *phl_info = phl; return rtw_hal_get_pwr_lmt_en(phl_info->hal, band_idx); } static void phl_set_embed_pwr_lmt_regu_info(void *drv , struct txpwr_regu_info_t *dst, u8 *embed_start , bool force, u8 *regu_2g, u8 regu_2g_len , u8 *regu_5g, u8 regu_5g_len, u8 *regu_6g, u8 regu_6g_len) { u8 *pos = embed_start; dst->force = force; if (regu_2g && regu_2g_len) { dst->regu_2g = pos; _os_mem_cpy(drv, pos, regu_2g, regu_2g_len); dst->regu_2g_len = regu_2g_len; pos += regu_2g_len; } else { dst->regu_2g = NULL; dst->regu_2g_len = 0; } if (regu_5g && regu_5g_len) { dst->regu_5g = pos; _os_mem_cpy(drv, pos, regu_5g, regu_5g_len); dst->regu_5g_len = regu_5g_len; pos += regu_5g_len; } else { dst->regu_5g = NULL; dst->regu_5g_len = 0; } if (regu_6g && regu_6g_len) { dst->regu_6g = pos; _os_mem_cpy(drv, pos, regu_6g, regu_6g_len); dst->regu_6g_len = regu_6g_len; pos += regu_6g_len; } else { dst->regu_6g = NULL; dst->regu_6g_len = 0; } } static void phl_set_embed_force_pwr_lmt_regu_info(void *drv , struct txpwr_regu_info_t *dst, u8 *embed_start , const struct txpwr_regu_info_t *src) { phl_set_embed_pwr_lmt_regu_info(drv, dst, embed_start , src->force , src->regu_2g, src->regu_2g_len , src->regu_5g, src->regu_5g_len , src->regu_6g, src->regu_6g_len); } static struct txpwr_regu_info_t *phl_get_embed_auto_pwr_lmt_regu_info(void *drv , struct phl_info_t *phl_info) { struct txpwr_regu_info_t *ret; size_t ret_len; u8 regu_2g; u8 regu_5g; u8 regu_6g; ret_len = sizeof(*ret) + 1 + 1 + 1; ret = _os_kmem_alloc(drv, (u32)ret_len); if (ret == NULL) { PHL_ERR("%s: alloc ret failed!\n", __func__); goto exit; } regu_2g = rtw_hal_get_pw_lmt_regu_type(phl_info->hal, BAND_ON_24G); regu_5g = rtw_hal_get_pw_lmt_regu_type(phl_info->hal, BAND_ON_5G); regu_6g = rtw_hal_get_pw_lmt_regu_type(phl_info->hal, BAND_ON_6G); phl_set_embed_pwr_lmt_regu_info(drv, ret, ((u8 *)ret) + sizeof(*ret) , false, ®u_2g, 1, ®u_5g, 1, ®u_6g, 1); exit: return ret; } static struct txpwr_regu_info_t *phl_get_embed_force_pwr_lmt_regu_info(void *drv , const struct txpwr_regu_info_t *src) { struct txpwr_regu_info_t *ret; size_t ret_len; ret_len = sizeof(*ret) + src->regu_2g_len + src->regu_5g_len + src->regu_6g_len; ret = _os_kmem_alloc(drv, (u32)ret_len); if (ret == NULL) { PHL_ERR("%s: alloc ret failed!\n", __func__); goto exit; } phl_set_embed_pwr_lmt_regu_info(drv, ret, ((u8 *)ret) + sizeof(*ret) , src->force , src->regu_2g, src->regu_2g_len , src->regu_5g, src->regu_5g_len , src->regu_6g, src->regu_6g_len); exit: return ret; } struct txpwr_regu_info_t *rtw_phl_get_pw_lmt_regu_info(void *phl) { struct phl_info_t *phl_info = phl; void *drv = phl_to_drvpriv(phl_info); struct rtw_phl_com_t *phl_com = phl_info->phl_com; struct txpwr_regu_info_t *pr_info = &phl_com->txpwr_regu_info; struct txpwr_regu_info_t *ret; if (pr_info->force) ret = phl_get_embed_force_pwr_lmt_regu_info(drv, pr_info); else ret = phl_get_embed_auto_pwr_lmt_regu_info(drv, phl_info); return ret; } void rtw_phl_free_pw_lmt_regu_info(void *phl, struct txpwr_regu_info_t *info) { struct phl_info_t *phl_info = phl; void *drv = phl_to_drvpriv(phl_info); size_t len; len = sizeof(*info); len += info->regu_2g_len + info->regu_5g_len + info->regu_6g_len; _os_kmem_free(drv, info, (u32)len); } bool rtw_phl_is_current_pwr_lmt_regu(void *phl, enum band_type band, u8 regu) { struct phl_info_t *phl_info = phl; struct rtw_phl_com_t *phl_com = phl_info->phl_com; struct txpwr_regu_info_t *pr_info = &phl_com->txpwr_regu_info; if (pr_info->force) { int i; if (band == BAND_ON_24G) { for (i = 0; i < pr_info->regu_2g_len; i++) if (pr_info->regu_2g[i] == regu) return true; } else if (band == BAND_ON_5G) { for (i = 0; i < pr_info->regu_5g_len; i++) if (pr_info->regu_5g[i] == regu) return true; } else if (band == BAND_ON_6G) { for (i = 0; i < pr_info->regu_6g_len; i++) if (pr_info->regu_6g[i] == regu) return true; } } else return regu == rtw_hal_get_pw_lmt_regu_type(phl_info->hal, band); return false; } static bool phl_set_pw_lmt_regu(struct phl_info_t *phl_info, struct txpwr_regu_info_t *conf, const char *caller) { void *drv = phl_to_drvpriv(phl_info); struct rtw_phl_com_t *phl_com = phl_info->phl_com; struct txpwr_regu_info_t *pr_info = &phl_com->txpwr_regu_info; u8 *tmp_regu_2g = NULL, *tmp_regu_5g = NULL, *tmp_regu_6g = NULL; bool config_change = false; if (conf->force) { if (conf->regu_2g_len && conf->regu_2g_len != pr_info->regu_2g_len) { tmp_regu_2g = _os_kmem_alloc(drv, conf->regu_2g_len); if (!tmp_regu_2g) { PHL_ERR("%s: alloc tmp_regu_2g failed!\n", __func__); goto exit; } } if (conf->regu_5g_len && conf->regu_5g_len != pr_info->regu_5g_len) { tmp_regu_5g = _os_kmem_alloc(drv, conf->regu_5g_len); if (!tmp_regu_5g) { PHL_ERR("%s: alloc tmp_regu_5g failed!\n", __func__); goto exit; } } if (conf->regu_6g_len && conf->regu_6g_len != pr_info->regu_6g_len) { tmp_regu_6g = _os_kmem_alloc(drv, conf->regu_6g_len); if (!tmp_regu_6g) { PHL_ERR("%s: alloc tmp_regu_6g failed!\n", __func__); goto exit; } } if (conf->regu_2g_len != pr_info->regu_2g_len || _os_mem_cmp(drv, conf->regu_2g, pr_info->regu_2g, conf->regu_2g_len) ) { config_change = true; if (pr_info->regu_2g && conf->regu_2g_len != pr_info->regu_2g_len) _os_kmem_free(drv, pr_info->regu_2g, pr_info->regu_2g_len); if (tmp_regu_2g) { pr_info->regu_2g = tmp_regu_2g; pr_info->regu_2g_len = conf->regu_2g_len; } else if (!conf->regu_2g_len) { pr_info->regu_2g = NULL; pr_info->regu_2g_len = 0; } if (conf->regu_2g_len) _os_mem_cpy(drv, pr_info->regu_2g, conf->regu_2g, conf->regu_2g_len); } if (conf->regu_5g_len != pr_info->regu_5g_len || _os_mem_cmp(drv, conf->regu_5g, pr_info->regu_5g, conf->regu_5g_len) ) { config_change = true; if (pr_info->regu_5g && conf->regu_5g_len != pr_info->regu_5g_len) _os_kmem_free(drv, pr_info->regu_5g, pr_info->regu_5g_len); if (tmp_regu_5g) { pr_info->regu_5g = tmp_regu_5g; pr_info->regu_5g_len = conf->regu_5g_len; } else if (!conf->regu_5g_len) { pr_info->regu_5g = NULL; pr_info->regu_5g_len = 0; } if (conf->regu_5g_len) _os_mem_cpy(drv, pr_info->regu_5g, conf->regu_5g, conf->regu_5g_len); } if (conf->regu_6g_len != pr_info->regu_6g_len || _os_mem_cmp(drv, conf->regu_6g, pr_info->regu_6g, conf->regu_6g_len) ) { config_change = true; if (pr_info->regu_6g && conf->regu_6g_len != pr_info->regu_6g_len) _os_kmem_free(drv, pr_info->regu_6g, pr_info->regu_6g_len); if (tmp_regu_6g) { pr_info->regu_6g = tmp_regu_6g; pr_info->regu_6g_len = conf->regu_6g_len; } else if (!conf->regu_6g_len) { pr_info->regu_6g = NULL; pr_info->regu_6g_len = 0; } if (conf->regu_6g_len) _os_mem_cpy(drv, pr_info->regu_6g, conf->regu_6g, conf->regu_6g_len); } } else { if (pr_info->regu_2g) { _os_kmem_free(drv, pr_info->regu_2g, pr_info->regu_2g_len); pr_info->regu_2g = NULL; pr_info->regu_2g_len = 0; } if (pr_info->regu_5g) { _os_kmem_free(drv, pr_info->regu_5g, pr_info->regu_5g_len); pr_info->regu_5g = NULL; pr_info->regu_5g_len = 0; } if (pr_info->regu_6g) { _os_kmem_free(drv, pr_info->regu_6g, pr_info->regu_6g_len); pr_info->regu_6g = NULL; pr_info->regu_6g_len = 0; } } if (conf->force != pr_info->force) { config_change = true; pr_info->force = conf->force; PHL_INFO("%s txpwr_regu_info force:%u is set\n", caller, conf->force); } if (!config_change) goto exit; if (!pr_info->force) rtw_hal_auto_pw_lmt_regu(phl_info->hal); else { PHL_INFO("%s txpwr_regu_info regu_2g_len:%u is set\n", caller, conf->regu_2g_len); PHL_INFO("%s txpwr_regu_info regu_5g_len:%u is set\n", caller, conf->regu_5g_len); PHL_INFO("%s txpwr_regu_info regu_6g_len:%u is set\n", caller, conf->regu_6g_len); rtw_hal_force_pw_lmt_regu(phl_info->hal, pr_info->regu_2g, pr_info->regu_2g_len , pr_info->regu_5g, pr_info->regu_5g_len, pr_info->regu_6g, pr_info->regu_6g_len); } exit: if (!config_change) { if (tmp_regu_2g) _os_kmem_free(drv, tmp_regu_2g, conf->regu_2g_len); if (tmp_regu_5g) _os_kmem_free(drv, tmp_regu_5g, conf->regu_5g_len); if (tmp_regu_6g) _os_kmem_free(drv, tmp_regu_6g, conf->regu_6g_len); } return config_change; } static u16 phl_get_pwr_constraint(struct phl_info_t *phl_info, u8 band_idx) { return rtw_hal_get_pwr_constraint(phl_info->hal, band_idx); } static enum rtw_phl_status phl_set_pwr_constraint(struct phl_info_t *phl_info, u8 band_idx, u16 mb) { enum rtw_hal_status hstatus = RTW_HAL_STATUS_FAILURE; hstatus = rtw_hal_set_pwr_constraint(phl_info->hal, band_idx, mb); if (hstatus != RTW_HAL_STATUS_SUCCESS) PHL_ERR("%s rtw_hal_set_pwr_constraint: statuts = %u\n", __func__, hstatus); return hstatus == RTW_HAL_STATUS_SUCCESS ? RTW_PHL_STATUS_SUCCESS : RTW_PHL_STATUS_FAILURE; } static enum rtw_phl_status phl_set_tx_power(void *phl, u8 band_idx) { struct phl_info_t *phl_info = phl; enum rtw_hal_status hstatus = RTW_HAL_STATUS_FAILURE; hstatus = rtw_hal_set_tx_power(phl_info->hal, band_idx, PWR_BY_RATE | PWR_LIMIT | PWR_LIMIT_RU); if (hstatus != RTW_HAL_STATUS_SUCCESS) PHL_ERR("%s rtw_hal_set_tx_power: statuts = %u\n", __func__, hstatus); return hstatus == RTW_HAL_STATUS_SUCCESS ? RTW_PHL_STATUS_SUCCESS : RTW_PHL_STATUS_FAILURE; } enum rtw_phl_status phl_cmd_txpwr_ctl_hdl(void *phl, u8 *param_buf) { struct phl_info_t *phl_info = phl; struct txpwr_ctl_param *param = (struct txpwr_ctl_param *)param_buf; u8 band_idx = param->band_idx; bool config_change = false; enum rtw_phl_status psts = RTW_PHL_STATUS_SUCCESS; if (param->pr_info_config) config_change = phl_set_pw_lmt_regu(phl_info, ¶m->pr_info, __func__); if (param->constraint_mb >= 0) { u16 constraint_mb = (u16)param->constraint_mb; if (constraint_mb != phl_get_pwr_constraint(phl_info, band_idx)) { psts = phl_set_pwr_constraint(phl_info, band_idx, constraint_mb); if (psts != RTW_PHL_STATUS_SUCCESS) goto exit; PHL_INFO("%s constraint_mb:%u is set\n", __func__, constraint_mb); config_change = true; } } if (param->force_write_txpwr && param->force_sw_config) { _os_warn_on(1); param->force_sw_config = false; } if (param->force_sw_config) goto exit; if (param->force_write_txpwr || config_change) psts = phl_set_tx_power(phl_info, band_idx); exit: return psts; } static void phl_txpwr_ctl_done(void *drv_priv, u8 *cmd, u32 cmd_len, enum rtw_phl_status status) { if (cmd) { _os_kmem_free(drv_priv, cmd, cmd_len); cmd = NULL; } } enum rtw_phl_status rtw_phl_cmd_txpwr_ctl(void *phl, struct txpwr_ctl_param *args , enum phl_cmd_type cmd_type, u32 cmd_timeout) { #ifdef CONFIG_CMD_DISP struct phl_info_t *phl_info = phl; void *drv = phl_to_drvpriv(phl_info); enum rtw_phl_status psts = RTW_PHL_STATUS_FAILURE; struct txpwr_ctl_param *param = NULL; u32 param_len; param_len = sizeof(*param); if (args->pr_info_config) { param_len += args->pr_info.regu_2g_len + args->pr_info.regu_5g_len + args->pr_info.regu_6g_len; } param = _os_kmem_alloc(drv, param_len); if (param == NULL) { PHL_ERR("%s: alloc param failed!\n", __func__); goto _exit; } _os_mem_cpy(drv, param, args, sizeof(*param)); if (args->pr_info_config) { phl_set_embed_force_pwr_lmt_regu_info(drv , ¶m->pr_info, ((u8 *)param) + sizeof(*param) , &args->pr_info); } if (cmd_type == PHL_CMD_DIRECTLY) { psts = phl_cmd_txpwr_ctl_hdl(phl_info, (u8 *)param); phl_txpwr_ctl_done(drv, (u8 *)param, param_len, psts); goto _exit; } psts = phl_cmd_enqueue(phl_info, args->band_idx, MSG_EVT_TXPWR_SETUP, (u8 *)param, param_len, phl_txpwr_ctl_done, cmd_type, cmd_timeout); if (is_cmd_failure(psts)) { /* Send cmd success, but wait cmd fail*/ psts = RTW_PHL_STATUS_FAILURE; } else if (psts != RTW_PHL_STATUS_SUCCESS) { /* Send cmd fail */ _os_kmem_free(drv, param, param_len); psts = RTW_PHL_STATUS_FAILURE; } _exit: return psts; #else PHL_ERR("%s(), CONFIG_CMD_DISP need to be enabled for MSG_EVT_TXPWR_SETUP \n",__func__); return RTW_PHL_STATUS_FAILURE; #endif } enum rtw_phl_status rtw_phl_cmd_set_pw_lmt_regu(void *phl, struct txpwr_regu_info_t *conf, bool sw_conf_only , enum phl_cmd_type cmd_type, u32 cmd_timeout) { struct phl_info_t *phl_info = phl; void *drv = phl_to_drvpriv(phl_info); struct txpwr_ctl_param args; txpwr_ctl_param_init(&args); args.band_idx = HW_BAND_0; args.force_sw_config = sw_conf_only; args.pr_info_config = true; _os_mem_cpy(drv, &args.pr_info, conf, sizeof(args.pr_info)); return rtw_phl_cmd_txpwr_ctl(phl, &args , cmd_type, cmd_timeout); } enum rtw_phl_status rtw_phl_cmd_set_tx_power_constraint(void *phl, enum phl_band_idx band_idx, u16 mb , enum phl_cmd_type cmd_type, u32 cmd_timeout) { struct txpwr_ctl_param args; txpwr_ctl_param_init(&args); args.band_idx = band_idx; args.constraint_mb = mb; return rtw_phl_cmd_txpwr_ctl(phl, &args , cmd_type, cmd_timeout); } enum rtw_phl_status rtw_phl_cmd_set_tx_power(void *phl, enum phl_band_idx band_idx , enum phl_cmd_type cmd_type, u32 cmd_timeout) { struct txpwr_ctl_param args; txpwr_ctl_param_init(&args); args.band_idx = band_idx; args.force_write_txpwr = true; return rtw_phl_cmd_txpwr_ctl(phl, &args , cmd_type, cmd_timeout); } enum rtw_phl_status rtw_phl_get_txinfo_pwr(void *phl, s16 *pwr_dbm) { struct phl_info_t *phl_info = phl; enum rtw_hal_status hstatus = RTW_HAL_STATUS_FAILURE; s16 power_dbm = 0; hstatus = rtw_hal_get_txinfo_power(phl_info->hal, &power_dbm); *pwr_dbm = power_dbm; return hstatus == RTW_HAL_STATUS_SUCCESS ? RTW_PHL_STATUS_SUCCESS : RTW_PHL_STATUS_FAILURE; } #ifdef CONFIG_CMD_DISP enum rtw_phl_status rtw_phl_cmd_get_txinfo_pwr(void *phl, s16 *pwr_dbm, enum phl_band_idx band_idx, bool direct) /* if caller already in cmd/msg, use direct = true */ { struct phl_info_t *phl_info = (struct phl_info_t *)phl; enum rtw_phl_status psts = RTW_PHL_STATUS_FAILURE; if (direct) { psts = rtw_phl_get_txinfo_pwr(phl, pwr_dbm); goto exit; } psts = phl_cmd_enqueue(phl_info, band_idx, MSG_EVT_GET_TX_PWR_DBM, (u8*)pwr_dbm, sizeof(s16), NULL, PHL_CMD_WAIT, 0); if (is_cmd_failure(psts)) { /* Send cmd success, but wait cmd fail */ psts = RTW_PHL_STATUS_FAILURE; } else if (psts != RTW_PHL_STATUS_SUCCESS) { /* Send cmd fail */ psts = RTW_PHL_STATUS_FAILURE; } exit: return psts; } #else enum rtw_phl_status rtw_phl_cmd_get_txinfo_pwr(void *phl, s16 *pwr_dbm, enum phl_band_idx band_idx, bool direct) { struct phl_info_t *phl_info = (struct phl_info_t *)phl; return rtw_phl_get_txinfo_pwr(phl, pwr_dbm); } #endif static enum rtw_phl_status _update_tpe_info(void *phl, struct rtw_tpe_info_t *tpe_info) { struct phl_info_t *phl_info = (struct phl_info_t *)phl; if (_os_mem_cmp(phl_to_drvpriv(phl_info), &phl_info->phl_com->tpe_info, tpe_info, sizeof(struct rtw_tpe_info_t)) != 0) { /* Update tpe info if contents are not the same */ _os_mem_cpy(phl_to_drvpriv(phl_info), &phl_info->phl_com->tpe_info, tpe_info, sizeof(struct rtw_tpe_info_t)); } return RTW_PHL_STATUS_SUCCESS; } #ifdef CONFIG_CMD_DISP enum rtw_phl_status phl_cmd_tpe_update_hdl(void *phl, u8 *param) { struct rtw_tpe_info_t *tpe_info = (struct rtw_tpe_info_t *)param; return _update_tpe_info(phl, tpe_info); } static void _phl_tpe_update_done(void *drv_priv, u8 *cmd, u32 cmd_len, enum rtw_phl_status status) { if (cmd) { _os_kmem_free(drv_priv, cmd, cmd_len); cmd = NULL; PHL_INFO("%s.....\n", __func__); } } enum rtw_phl_status rtw_phl_cmd_tpe_update(struct rtw_wifi_role_link_t *rlink, struct rtw_tpe_info_t *tpe_info, bool cmd_wait, u32 cmd_timeout) { enum rtw_phl_status psts = RTW_PHL_STATUS_FAILURE; struct phl_info_t *phl = rlink->wrole->phl_com->phl_priv; void *drv = phl_to_drvpriv(phl); u32 param_len = sizeof(struct rtw_tpe_info_t); struct rtw_tpe_info_t *param = _os_kmem_alloc(drv, param_len); if (param == NULL) { PHL_ERR("%s: alloc param failed!\n", __func__); goto _exit; } _os_mem_cpy(drv, param, tpe_info, sizeof(struct rtw_tpe_info_t)); psts = phl_cmd_enqueue(phl, rlink->hw_band, MSG_EVT_TPE_INFO_UPDATE, (u8 *)param, param_len, _phl_tpe_update_done, cmd_wait ? PHL_CMD_WAIT : PHL_CMD_NO_WAIT, cmd_timeout); if (psts != RTW_PHL_STATUS_SUCCESS) { PHL_INFO("%s: Fail to issue tpe info update!!\n", __func__); if (!is_cmd_failure(psts)) { /* Send cmd fail */ _os_kmem_free(drv, param, param_len); psts = RTW_PHL_STATUS_FAILURE; } goto _exit; } _exit: PHL_INFO("%s: Issue cmd, status(%d)\n", __func__, psts); return psts; } void rtw_phl_set_tx_pwr_comp(void *phl, u8 regu, s8 ag_comp_2g, s8 ag_comp_5g, s8 ag_comp_6g) { struct phl_info_t *phl_info = (struct phl_info_t *)phl; u8 tx_tbl_to_pwr_times = rtw_hal_get_tx_tbl_to_pwr_times(phl_info->hal); enum phl_phy_idx phy_idx = HW_PHY_0; struct rtw_phl_regu_dyn_ant_gain dyn_ag; PHL_INFO("%s...\n", __func__); dyn_ag.regu = regu; dyn_ag.ag_2g_comp = ag_comp_2g * tx_tbl_to_pwr_times; dyn_ag.ag_5g_comp = ag_comp_5g * tx_tbl_to_pwr_times; dyn_ag.ag_6g_comp = ag_comp_6g * tx_tbl_to_pwr_times; rtw_hal_set_tx_pwr_comp(phl_info->hal, phy_idx, &dyn_ag); } #endif s8 rtw_phl_get_power_by_rate_band(void *phl, u8 hw_band, u16 rate, u8 dcm, u8 offset, u32 band) { struct phl_info_t *phl_info = (struct phl_info_t *)phl; return rtw_hal_get_power_by_rate_band(phl_info->hal, hw_band, rate, dcm, offset, band); } s8 rtw_phl_get_power_limit_option(void *phl, u8 hw_band, u8 rf_path, u16 rate, u8 bandwidth, u8 beamforming, u8 tx_num, u8 channel, u32 band, u8 reg) { struct phl_info_t *phl_info = (struct phl_info_t *)phl; return rtw_hal_get_power_limit_option(phl_info->hal, hw_band, rf_path, rate, bandwidth, beamforming, tx_num, channel, band, reg); } s8 rtw_phl_get_power_limit_ru_option(void *phl, u8 hw_band, u8 rf_path, u16 rate, u8 bandwidth, u8 tx_num, u8 channel, u32 band, u8 reg) { struct phl_info_t *phl_info = (struct phl_info_t *)phl; return rtw_hal_get_power_limit_ru_option(phl_info->hal , hw_band, rf_path, rate, bandwidth, tx_num, channel, band, reg); } u8 rtw_phl_get_tx_tbl_to_tx_pwr_times(void *phl) { struct phl_info_t *phl_info = (struct phl_info_t *)phl; return rtw_hal_get_tx_tbl_to_tx_pwr_times(phl_info->hal); } s8 rtw_phl_get_power_limit_value_ww(void *phl) { struct phl_info_t *phl_info = (struct phl_info_t *)phl; return rtw_hal_get_power_limit_value_ww(phl_info->hal); } s8 rtw_phl_get_power_limit_value_na(void *phl) { struct phl_info_t *phl_info = (struct phl_info_t *)phl; return rtw_hal_get_power_limit_value_na(phl_info->hal); } u32 rtw_phl_get_regulation_max_num(void *phl, enum band_type band) { struct phl_info_t *phl_info = (struct phl_info_t *)phl; return rtw_hal_get_regulation_max_num(phl_info->hal, band); }