292 lines
8.6 KiB
C
Executable File
292 lines
8.6 KiB
C
Executable File
/****************************************************************************
|
|
|
|
Copyright(c) 2019 by Aerospace C.Power (Chongqing) Microelectronics. ALL RIGHTS RESERVED.
|
|
|
|
This Information is proprietary to Aerospace C.Power (Chongqing) Microelectronics and MAY NOT
|
|
be copied by any method or incorporated into another program without
|
|
the express written consent of Aerospace C.Power. This Information or any portion
|
|
thereof remains the property of Aerospace C.Power. The Information contained herein
|
|
is believed to be accurate and Aerospace C.Power assumes no responsibility or
|
|
liability for its use in any way and conveys no license or title under
|
|
any patent or copyright and makes no representation or warranty that this
|
|
Information is free from patent or copyright infringement.
|
|
|
|
****************************************************************************/
|
|
#include "iot_config.h"
|
|
#include "phy_bb.h"
|
|
#include "mac_tx_power.h"
|
|
#include "os_types.h"
|
|
#include "os_utils_api.h"
|
|
#include "plc_protocol.h"
|
|
#include "hw_phy_api.h"
|
|
#include "mac_sched_hw.h"
|
|
#include "mac_vdev_api.h"
|
|
#include "mac_vdev.h"
|
|
#include "mac_pdev.h"
|
|
#include "mac_peer.h"
|
|
#include "mac_msdu.h"
|
|
#include "mac_dsr.h"
|
|
#include "mac_cfg.h"
|
|
#include "iot_io.h"
|
|
#include "iot_board.h"
|
|
#include "mac.h"
|
|
#include "phy_isr.h"
|
|
#include "iot_utils_api.h"
|
|
#include "iot_oem_api.h"
|
|
#include "mac_tx_hw.h"
|
|
#include "tx_mpdu_start.h"
|
|
#include "phy_txrx_pwr.h"
|
|
#include "iot_dbglog_api.h"
|
|
#include "iot_dbglog_parser.h"
|
|
#include "phy_txrx_pwr.h"
|
|
#include "phy_overstress.h"
|
|
#include "mac_rf_tx_power.h"
|
|
|
|
void IRAM_ATTR mac_over_stress_isr_handle(void *param, uint8_t is_from_isr)
|
|
{
|
|
(void)param;
|
|
|
|
uint32_t value = 0;
|
|
value |= 1 << MAC_DSR_OVER_STRESS_ID;
|
|
|
|
if (value) {
|
|
if (is_from_isr) {
|
|
/* deliver the DSR events to mac task context */
|
|
os_set_task_event_with_v_from_isr(p_mac_glb->task_h, value);
|
|
} else {
|
|
os_set_task_event_with_v(p_mac_glb->task_h, value);
|
|
}
|
|
}
|
|
}
|
|
|
|
void mac_over_stress_dsr_handle()
|
|
{
|
|
phy_overstress_ctxt_t *ovs_ctxt = &g_phy_ctxt.indep.ovs_ctxt;
|
|
if (ovs_ctxt->ovr_stress) {
|
|
phy_overstress_power_down(PHY_OVR_STRESS_PWR_DOWN_VAL);
|
|
} else {
|
|
phy_overstress_power_up();
|
|
}
|
|
iot_printf("overstress:%d, over_pwr:%d, cnt:%d\n", ovs_ctxt->ovr_stress,
|
|
ovs_ctxt->ovr_pwr, ovs_ctxt->os_cnt);
|
|
}
|
|
|
|
uint32_t mac_get_def_tx_power(uint32_t proto, uint32_t proto_band_id,
|
|
uint32_t *ret_tx_power)
|
|
{
|
|
uint8_t tx_power_int, tx_power_frac;
|
|
(void)proto;
|
|
(void)proto_band_id;
|
|
phy_get_def_tx_power(0, HW_FULL_BAND, &tx_power_int, &tx_power_frac);
|
|
*ret_tx_power = tx_power_int;
|
|
return 0;
|
|
}
|
|
|
|
static uint8_t mac_plc_high_power_check(void *vdev_ptr)
|
|
{
|
|
mac_vdev_t *vdev = (mac_vdev_t*)vdev_ptr;
|
|
if (!vdev->high_power_plc_allow) {
|
|
if (iot_oem_get_module_type() == MODULE_TYPE_CCO
|
|
&& iot_board_is_5v_power_in()
|
|
&& os_boot_time64() < (15 * 60 * 1000)) {
|
|
vdev->high_power_plc_allow = 0;
|
|
} else {
|
|
vdev->high_power_plc_allow = 1;
|
|
}
|
|
}
|
|
return (uint8_t)vdev->high_power_plc_allow;
|
|
}
|
|
|
|
void mac_fix_power_apply(void *vdev_ptr)
|
|
{
|
|
IOT_ASSERT(vdev_ptr);
|
|
mac_vdev_t *vdev = (mac_vdev_t*)vdev_ptr;
|
|
|
|
/* only for lp ver
|
|
* and cert ver return
|
|
*/
|
|
if (g_phy_cpu_share_ctxt.tx_pwr_ctl_ena || CPLC_IOT_CERT_ENABLE) {
|
|
return;
|
|
}
|
|
|
|
if (vdev->fixed_power_cap_flag) {
|
|
phy_pwr_adjust_set((uint8_t)vdev->power_cap);
|
|
} else {
|
|
if (phy_band_id_get() == IOT_SUPPORT_TONE_231_490_CE) {
|
|
return;
|
|
}
|
|
|
|
if (vdev->high_power_req_ena == 0) {
|
|
phy_pwr_adjust_set(0);
|
|
} else {
|
|
if (vdev->high_power_req_reason_bitmap != 0
|
|
&& mac_plc_high_power_check(vdev_ptr)) {
|
|
#if PLC_MAC_TX_DEBUG_LOG >= PLC_MAC_LOG_LEVEL_2
|
|
iot_dbglog_input(PLC_MAC_TX_MID, DBGLOG_INFO_LVL_2, \
|
|
IOT_MAC_TX_POWER_CHANGE_ID, 1, \
|
|
vdev->high_power_req_reason_bitmap);
|
|
#endif
|
|
phy_pwr_adjust_set(mac_cfg_get_auto_high_power_dbuv());
|
|
} else {
|
|
phy_pwr_adjust_set(0);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
void mac_high_power_req_ena(void *vdev_ptr, uint8_t ena)
|
|
{
|
|
IOT_ASSERT(vdev_ptr);
|
|
mac_vdev_t *vdev = (mac_vdev_t*)vdev_ptr;
|
|
if (g_phy_cpu_share_ctxt.tx_pwr_ctl_ena == 0) {
|
|
vdev->high_power_req_ena = !!ena;
|
|
mac_fix_power_apply(vdev);
|
|
}
|
|
}
|
|
|
|
void mac_check_power_by_level(void *vdev_ptr, uint8_t sta_level)
|
|
{
|
|
|
|
IOT_ASSERT(vdev_ptr);
|
|
mac_vdev_t *vdev = (mac_vdev_t*)vdev_ptr;
|
|
mac_peer_t *self_peer = (mac_peer_t *)vdev->self_peer;
|
|
|
|
if (self_peer == NULL || self_peer->tei == 0) {
|
|
return;
|
|
}
|
|
|
|
if (sta_level >= HIGH_PWR_LVL_THRE) {
|
|
mac_high_power_req(vdev, HIGH_PWR_REQ_BY_STA_LVL, true);
|
|
} else {
|
|
mac_high_power_req(vdev, HIGH_PWR_REQ_BY_STA_LVL, false);
|
|
}
|
|
}
|
|
void mac_high_power_req(void *vdev, uint8_t reason, uint8_t flag)
|
|
{
|
|
if (g_phy_cpu_share_ctxt.tx_pwr_ctl_ena == 0) {
|
|
IOT_ASSERT(vdev);
|
|
mac_vdev_t *vdev_ptr = (mac_vdev_t*)vdev;
|
|
|
|
IOT_ASSERT(reason < 32);
|
|
uint32_t reason_bitmap = 1 << reason;
|
|
if (!!flag) {
|
|
vdev_ptr->high_power_req_reason_bitmap |= reason_bitmap;
|
|
} else {
|
|
vdev_ptr->high_power_req_reason_bitmap &= ~reason_bitmap;
|
|
}
|
|
|
|
mac_fix_power_apply(vdev_ptr);
|
|
/* rf high power */
|
|
mac_rf_fix_power_apply();
|
|
}
|
|
|
|
}
|
|
|
|
uint8_t mac_get_final_min_tx_power(uint8_t band_id)
|
|
{
|
|
uint8_t power_dbuv;
|
|
|
|
switch (band_id) {
|
|
case IOT_SUPPORT_TONE_231_490_CE:
|
|
power_dbuv = MAC_TX_POWER_CE_MIN;
|
|
break;
|
|
|
|
//TODO: add code
|
|
default:
|
|
power_dbuv = MIN_TX_POWER;
|
|
break;
|
|
}
|
|
|
|
return power_dbuv;
|
|
}
|
|
|
|
void mac_set_tx_power_cap(void *vdev_ptr, uint8_t *hplc_power,
|
|
int8_t *rf_power, uint8_t is_force)
|
|
{
|
|
IOT_ASSERT(vdev_ptr);
|
|
uint8_t band_id;
|
|
mac_vdev_t *vdev = (mac_vdev_t*)vdev_ptr;
|
|
if (hplc_power) {
|
|
/* is hplc set power */
|
|
uint8_t power = *hplc_power;
|
|
mac_pdev_t *pdev_ptr = get_pdev_ptr(vdev->ref_pdev_id);
|
|
if (!is_force && pdev_ptr->mac_pm.mac_pm_flag) {
|
|
/* if power off happen, not care set power cap */
|
|
return;
|
|
}
|
|
|
|
if (g_phy_cpu_share_ctxt.tx_pwr_ctl_ena == 0) {
|
|
band_id = (uint8_t)phy_band_id_get();
|
|
if (power == 0) {
|
|
/* clear power cap */
|
|
vdev->fixed_power_cap_flag = 0;
|
|
} else if (power >= PHY_FULL_PWR_DBUV) {
|
|
/* high power */
|
|
vdev->fixed_power_cap_flag = 1;
|
|
vdev->power_cap = PHY_FULL_PWR_DBUV;
|
|
} else {
|
|
/* low power */
|
|
vdev->fixed_power_cap_flag = 1;
|
|
vdev->power_cap = max(power,
|
|
mac_get_final_min_tx_power(band_id));
|
|
}
|
|
mac_fix_power_apply(vdev);
|
|
}
|
|
}
|
|
|
|
if (rf_power) {
|
|
int8_t tmp_powre = *rf_power;
|
|
mac_rf_vdev_t *rf_vdev = get_rf_vdev_ptr(vdev->ref_pdev_id,
|
|
RF_PDEV_ID, vdev->rf_vdev_id);
|
|
mac_rf_set_tx_power_cap(rf_vdev, tmp_powre, is_force);
|
|
}
|
|
}
|
|
|
|
void mac_fix_power_init(void *vdev_ptr)
|
|
{
|
|
IOT_ASSERT(vdev_ptr);
|
|
mac_vdev_t *vdev = (mac_vdev_t*)vdev_ptr;
|
|
#if CPLC_IOT_CERT_ENABLE
|
|
vdev->high_power_req_ena = 0;
|
|
#else
|
|
vdev->high_power_req_ena = mac_cfg_get_auto_high_power_req_ena();
|
|
#endif
|
|
vdev->fixed_power_cap_flag = 0;
|
|
vdev->high_power_req_reason_bitmap = 0;
|
|
}
|
|
|
|
#if CERT_WAR_TX_PWR == 1
|
|
uint32_t mac_cert_war_tx_pwr(uint8_t *mac_addr)
|
|
{
|
|
IOT_ASSERT(mac_addr);
|
|
uint32_t is_pwr_rise = 0;
|
|
const uint8_t box3[6]={0x01,0x12,0x01,0x00,0x00,0x01};
|
|
const uint8_t box4[6]={0x01,0x11,0x00,0x01,0x00,0x01};
|
|
const uint8_t box5[6]={0x01,0x14,0x00,0x01,0x00,0x01};
|
|
const uint8_t box4_1[6]={0x01,0x11,0x01,0x00,0x00,0x01};
|
|
const uint8_t box5_1[6]={0x01,0x14,0x01,0x00,0x00,0x01};
|
|
iot_printf("---%s:"
|
|
"0x%02x:0x%02x:0x%02x:0x%02x:0x%02x:0x%02x\n",
|
|
__FUNCTION__,
|
|
mac_addr[0],
|
|
mac_addr[1],
|
|
mac_addr[2],
|
|
mac_addr[3],
|
|
mac_addr[4],
|
|
mac_addr[5]
|
|
);
|
|
if (iot_mac_addr_cmp(mac_addr, box4) || iot_mac_addr_cmp(mac_addr, box5) ||
|
|
iot_mac_addr_cmp(mac_addr, box4_1) ||
|
|
iot_mac_addr_cmp(mac_addr, box5_1) ||
|
|
iot_mac_addr_cmp(mac_addr, box3)) {
|
|
/* if box4 or box5, rise the power */
|
|
phy_pwr_adjust_set(PHY_FULL_PWR_DBUV);
|
|
is_pwr_rise = 1;
|
|
phy_rise_pwr_flag_set(true);
|
|
iot_printf("***tx power calculated:%d.***\n", is_pwr_rise);
|
|
}
|
|
|
|
return is_pwr_rise;
|
|
}
|
|
#endif
|