444 lines
14 KiB
C
Executable File
444 lines
14 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 "mac_check_spur.h"
|
|
#include "mac_check_spur_cco.h"
|
|
#include "mac_check_spur_sta.h"
|
|
#include "mac_pdev.h"
|
|
#include "iot_io.h"
|
|
#include "mac_msg.h"
|
|
#include "mac_reset.h"
|
|
#include "mac_bcm_api.h"
|
|
#include "mac_vdev.h"
|
|
#include "iot_utils_api.h"
|
|
#include "mac_sched.h"
|
|
#include "mac_tx_hw.h"
|
|
#include "mac_init_api.h"
|
|
#include "mac_cert_test.h"
|
|
|
|
#include "os_utils_api.h"
|
|
|
|
#include "mac_sched_hw.h"
|
|
#include "mac_hwq_reg.h"
|
|
#include "chip_reg_base.h"
|
|
#include "hw_reg_api.h"
|
|
#include "iot_bitmap_api.h"
|
|
#include "iot_dbglog_api.h"
|
|
#include "iot_dbglog.h"
|
|
|
|
#if (CCO_CHECK_SPUR_SUPPORT || STA_CHECK_SPUR_SUPPORT)
|
|
|
|
uint32_t mac_check_value(uint32_t value1, uint32_t value2, \
|
|
uint32_t value3, uint32_t value4)
|
|
{
|
|
uint32_t bit_map = 0;
|
|
/* 0-7 bit : if valuex == 0, set bitx = 1 */
|
|
if (value1 == 0) {
|
|
bit_map |= 0x1 << 0;
|
|
}
|
|
if (value2 == 0) {
|
|
bit_map |= 0x1 << 1;
|
|
}
|
|
if (value3 == 0) {
|
|
bit_map |= 0x1 << 2;
|
|
}
|
|
if (value4 == 0) {
|
|
bit_map |= 0x1 << 3;
|
|
}
|
|
|
|
/* 8-15 bit : if valuex == 0, set bitx = 1 */
|
|
if (value1 == 2) {
|
|
bit_map |= 0x1 << 8;
|
|
}
|
|
if (value2 == 2) {
|
|
bit_map |= 0x1 << 9;
|
|
}
|
|
if (value3 == 2) {
|
|
bit_map |= 0x1 << 10;
|
|
}
|
|
if (value4 == 2) {
|
|
bit_map |= 0x1 << 11;
|
|
}
|
|
return bit_map;
|
|
}
|
|
|
|
void mac_print_dbg_bus(uint8_t save_flash)
|
|
{
|
|
uint32_t dump_value[] =
|
|
{0x02, 0x12, 0x22, 0x32, 0x42, 0x50, 0x61, 0x100,
|
|
0x200, 0x320, 0x400, 0x401, 0x402, 0x404, 0x405, 0xb00};
|
|
|
|
for (uint8_t i = 0; i < IOT_ARRAY_CNT(dump_value); i++) {
|
|
mac_set_debug_reg(dump_value[i]);
|
|
dump_value[i] = mac_rx_get_debug_reg();
|
|
}
|
|
iot_printf("mac_sts, dbg_reg0 get 0x%x, 0x%x, 0x%x, 0x%x, 0x%x, 0x%x, "
|
|
"0x%x, 0x%x\n",
|
|
dump_value[0], dump_value[1], dump_value[2], dump_value[3],
|
|
dump_value[4], dump_value[5], dump_value[6], dump_value[7]);
|
|
|
|
iot_printf("mac_sts, dbg_reg1 get 0x%x, 0x%x, 0x%x, 0x%x, 0x%x, 0x%x, "
|
|
"0x%x, 0x%x\n",
|
|
dump_value[8], dump_value[9], dump_value[10], dump_value[11],
|
|
dump_value[12], dump_value[13], dump_value[14], dump_value[15]);
|
|
|
|
if (save_flash) {
|
|
iot_dbglog_input(PLC_MAC_STATUSE_MID, DBGLOG_ERR,
|
|
IOT_MAC_STATUS14_ID, 8,
|
|
dump_value[0], dump_value[1], dump_value[2], dump_value[3],
|
|
dump_value[4], dump_value[5], dump_value[6], dump_value[7]);
|
|
|
|
iot_dbglog_input(PLC_MAC_STATUSE_MID, DBGLOG_ERR,
|
|
IOT_MAC_STATUS15_ID, 8,
|
|
dump_value[8], dump_value[9], dump_value[10], dump_value[11],
|
|
dump_value[12], dump_value[13], dump_value[14], dump_value[15]);
|
|
}
|
|
}
|
|
|
|
uint32_t mac_check_spur_en(mac_check_spur_ctxt_t *spur_ctxt, uint32_t enable)
|
|
{
|
|
#if (MAC_CHECK_SPUR_DEBUG >= PLC_MAC_LOG_LEVEL_2)
|
|
iot_printf("%s, [mac_check_dbg], enable:%d\n", __FUNCTION__, enable);
|
|
#endif
|
|
if ((mac_get_cert_test_flag() && enable) ||
|
|
spur_ctxt->check_spur_en == (!!enable)) {
|
|
return 0;
|
|
}
|
|
spur_ctxt->check_spur_en = !!enable;
|
|
if (!enable) {
|
|
spur_ctxt->is_check_spur_sts = MAC_CHECK_SPUR_INIT;
|
|
spur_ctxt->con_spur_cnt = 0;
|
|
spur_ctxt->do_checkspur_cnt = 0;
|
|
spur_ctxt->do_checkspur_success_cnt = 0;
|
|
#if CCO_CHECK_SPUR_SUPPORT
|
|
os_stop_timer(spur_ctxt->cco_check_spur_timer);
|
|
#else
|
|
os_stop_timer(spur_ctxt->sta_check_spur_timer);
|
|
#endif
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
uint32_t mac_check_spur(mac_check_spur_ctxt_t *spur_ctxt, \
|
|
void *pdev, uint32_t time_ms, bool_t is_check_slot)
|
|
{
|
|
#if (MAC_CHECK_SPUR_DEBUG >= PLC_MAC_LOG_LEVEL_2)
|
|
iot_printf("%s \n", __FUNCTION__);
|
|
#endif
|
|
mac_pdev_t *pdev_t = (mac_pdev_t *)pdev;
|
|
mac_vdev_t *vdev = pdev_t->vdev[PLC_DEFAULT_VDEV];
|
|
uint32_t ret = ERR_FAIL;
|
|
|
|
spur_ctxt->do_checkspur_cnt++;
|
|
|
|
uint64_t cur_ntb_64 = mac_sched_get_ntb64(vdev);
|
|
|
|
/* if phy hang, do not check beacon slot */
|
|
if (is_check_slot) {
|
|
time_ms = min(MAC_NTB_TO_MS(spur_ctxt->next_bcn_start_ntb \
|
|
- cur_ntb_64), time_ms);
|
|
}
|
|
|
|
if (time_ms < MAC_CHECK_SPUR_MS) {
|
|
iot_printf("mac spur req ms: %d < %d\n", time_ms, MAC_CHECK_SPUR_MS);
|
|
return ERR_FAIL;
|
|
}
|
|
mac_set_pcs_busy(1, 1);
|
|
uint32_t sts = mac_get_phy_txrx_sts();
|
|
if (MAC_PHY_RX_STS == sts) {
|
|
uint32_t mac_sts = mac_dbg_bus_get_mac_sts(MAC_DEBUG_VALUE_320, \
|
|
MAC_DEBUG_VALUE_MASK_BIT_15_17);
|
|
#if (MAC_CHECK_SPUR_DEBUG >= PLC_MAC_LOG_LEVEL_2)
|
|
iot_printf("[mac_check_dbg] %s phy_sts:%d, mac_sts:%d\n", \
|
|
__FUNCTION__, mac_sts);
|
|
#endif
|
|
uint32_t bkoff1 = 0xffffffff;
|
|
uint32_t bkoff2 = 0xffffffff;
|
|
uint32_t bkoff3 = 0xffffffff;
|
|
uint32_t bkoff4 = 0xffffffff;
|
|
/* mac status -> listen status */
|
|
if (MAC_RX_LISTEN_STS == mac_sts) {
|
|
/* check */
|
|
bkoff1 = mac_dbg_bus_get_mac_sts(MAC_DEBUG_VALUE_2, \
|
|
MAC_DEBUG_VALUE_MASK_BIT_13_18);
|
|
bkoff2 = mac_dbg_bus_get_mac_sts(MAC_DEBUG_VALUE_12, \
|
|
MAC_DEBUG_VALUE_MASK_BIT_13_18);
|
|
bkoff3 = mac_dbg_bus_get_mac_sts(MAC_DEBUG_VALUE_22, \
|
|
MAC_DEBUG_VALUE_MASK_BIT_13_18);
|
|
bkoff4 = mac_dbg_bus_get_mac_sts(MAC_DEBUG_VALUE_32, \
|
|
MAC_DEBUG_VALUE_MASK_BIT_13_18);
|
|
uint32_t bit_map = mac_check_value(bkoff1, bkoff2, bkoff3, bkoff4);
|
|
|
|
if (iot_bitmap_cbs((uint8_t *)&bit_map, sizeof(uint32_t)) == 0) {
|
|
/* bkoffx != 2 and bkoffx != 0 , do not check spur */
|
|
mac_sts = MAC_DO_NOT_BBAI_STS;
|
|
}
|
|
uint32_t bit_map_0_7 = bit_map & 0xf;
|
|
uint32_t bit_map_8_15 = bit_map & 0xf0;
|
|
if (iot_bitmap_cbs((uint8_t *)&bit_map_0_7, sizeof(uint32_t)) \
|
|
== 3 && \
|
|
iot_bitmap_cbs((uint8_t *)&bit_map_8_15, sizeof(uint32_t)) \
|
|
== 1) {
|
|
/* mac in tx cca wait status, check spur */
|
|
mac_sts = MAC_TX_CCA_WAIT_STS;
|
|
}
|
|
else if (iot_bitmap_cbs((uint8_t *)&bit_map_0_7, sizeof(uint32_t))\
|
|
== 4 && \
|
|
iot_bitmap_cbs((uint8_t *)&bit_map_8_15, sizeof(uint32_t)) \
|
|
== 0) {
|
|
/* mac in rx listen status */
|
|
mac_sts = MAC_RX_LISTEN_STS;
|
|
}
|
|
}
|
|
|
|
/* mac status -> rx fc status */
|
|
if (MAC_RX_FC_STS == mac_sts) {
|
|
mac_set_sts_idle();
|
|
while (mac_sts) {
|
|
#if (MAC_CHECK_SPUR_DEBUG >= PLC_MAC_LOG_LEVEL_2)
|
|
iot_printf("[mac_check_dbg] polling!\n");
|
|
#endif
|
|
mac_sts = mac_dbg_bus_get_mac_sts(MAC_DEBUG_VALUE_320, \
|
|
MAC_DEBUG_VALUE_MASK_BIT_15_17);
|
|
}
|
|
}
|
|
|
|
if ( MAC_RX_LISTEN_STS == mac_sts || \
|
|
MAC_TX_CCA_WAIT_STS == mac_sts ) {
|
|
mac_set_sts_idle();
|
|
phy_reset(PHY_RST_REASON_WARM);
|
|
ret = phy_chn_est_ai_by_time(time_ms);
|
|
if (ret) {
|
|
spur_ctxt->do_checkspur_success_cnt++;
|
|
ret = ERR_OK;
|
|
}
|
|
else {
|
|
ret = ERR_FAIL;
|
|
}
|
|
phy_reset(PHY_RST_REASON_WARM);
|
|
mac_free_sts_idle();
|
|
}
|
|
else {
|
|
mac_free_sts_idle();
|
|
iot_printf("[mac_check_dbg] mac_sts:0x%x, bkoff1:0x%x, bkoff2:0x%x, "\
|
|
"bkoff3:0x%x, bkoff4:0x%x\n", mac_sts, bkoff1, bkoff2,\
|
|
bkoff3, bkoff4);
|
|
mac_print_dbg_bus(0);
|
|
}
|
|
}
|
|
else {
|
|
iot_printf("[mac_check_dbg] phy_sts:0x%x\n", sts);
|
|
mac_print_dbg_bus(0);
|
|
}
|
|
mac_set_pcs_busy(0, 0);
|
|
|
|
iot_printf("[mac_check_dbg] ratio:%d%%\n", \
|
|
(spur_ctxt->do_checkspur_success_cnt*100 )/spur_ctxt->do_checkspur_cnt);
|
|
|
|
uint64_t cur_ntb_out = mac_sched_get_ntb64(vdev);
|
|
|
|
/* if phy hang, do not check beacon slot */
|
|
if (is_check_slot && \
|
|
cur_ntb_out > spur_ctxt->next_bcn_start_ntb) {
|
|
mac_vdev_t *vdev_ptr = pdev_t->vdev[PLC_DEFAULT_VDEV];
|
|
mac_bc_time_slot_t *t_slot = &vdev_ptr->bcn_ctx.time_slot;
|
|
iot_printf("slot bad: cur_ntb_h:%lu, cur_ntb_h:%lu, "\
|
|
"start_ntb_h:%lu, start_ntb_l:%lu, slot_dur:%lu, start_ntb:%lu, "\
|
|
"start_ntb_reg:%lu, dur_reg:%lu\n", \
|
|
iot_uint64_higher32(cur_ntb_64), \
|
|
iot_uint64_lower32(cur_ntb_64), \
|
|
iot_uint64_higher32(spur_ctxt->next_bcn_start_ntb), \
|
|
iot_uint64_lower32(spur_ctxt->next_bcn_start_ntb),\
|
|
t_slot->bc_period, t_slot->bp_start_ntb,\
|
|
mac_sched_get_bp_start_ntb(), \
|
|
mac_sched_get_bp_dur());
|
|
IOT_ASSERT(0);
|
|
}
|
|
|
|
#if (MAC_CHECK_SPUR_DEBUG >= PLC_MAC_LOG_LEVEL_2)
|
|
iot_printf("[mac_check_dbg] start_ntb_h:%d, start_ntb_h:%d,"
|
|
"cur_ntb_h:%d, cur_ntb_l:%d,"\
|
|
"cur_ntb_out_h:%d, cur_ntb_out_l:%d\n",\
|
|
iot_uint64_higher32(spur_ctxt->next_bcn_start_ntb),
|
|
iot_uint64_lower32(spur_ctxt->next_bcn_start_ntb),
|
|
iot_uint64_higher32(cur_ntb_64),
|
|
iot_uint64_lower32(cur_ntb_64),
|
|
iot_uint64_higher32(cur_ntb_out),
|
|
iot_uint64_lower32(cur_ntb_out));
|
|
#endif
|
|
return ret;
|
|
}
|
|
|
|
uint32_t mac_check_spur_for_txhang()
|
|
{
|
|
uint32_t ret = ERR_FAIL;
|
|
uint32_t mac_sts;
|
|
|
|
mac_set_pcs_busy(1, 1);
|
|
uint32_t sts = mac_get_phy_txrx_sts();
|
|
if (MAC_PHY_RX_STS == sts) {
|
|
mac_sts = mac_dbg_bus_get_mac_sts(MAC_DEBUG_VALUE_320,
|
|
MAC_DEBUG_VALUE_MASK_BIT_15_17);
|
|
iot_printf("%s phy_sts:%d, mac_sts:%d\n", __FUNCTION__, mac_sts);
|
|
|
|
uint32_t bkoff1 = 0xffffffff;
|
|
uint32_t bkoff2 = 0xffffffff;
|
|
uint32_t bkoff3 = 0xffffffff;
|
|
uint32_t bkoff4 = 0xffffffff;
|
|
/* mac status -> listen status */
|
|
if (MAC_RX_LISTEN_STS == mac_sts) {
|
|
/* check */
|
|
bkoff1 = mac_dbg_bus_get_mac_sts(MAC_DEBUG_VALUE_2,
|
|
MAC_DEBUG_VALUE_MASK_BIT_13_18);
|
|
bkoff2 = mac_dbg_bus_get_mac_sts(MAC_DEBUG_VALUE_12,
|
|
MAC_DEBUG_VALUE_MASK_BIT_13_18);
|
|
bkoff3 = mac_dbg_bus_get_mac_sts(MAC_DEBUG_VALUE_22,
|
|
MAC_DEBUG_VALUE_MASK_BIT_13_18);
|
|
bkoff4 = mac_dbg_bus_get_mac_sts(MAC_DEBUG_VALUE_32,
|
|
MAC_DEBUG_VALUE_MASK_BIT_13_18);
|
|
uint32_t bit_map = mac_check_value(bkoff1, bkoff2, bkoff3, bkoff4);
|
|
|
|
if (iot_bitmap_cbs((uint8_t *)&bit_map, sizeof(uint32_t)) == 0) {
|
|
/* bkoffx != 2 and bkoffx != 0 , do not check spur */
|
|
mac_sts = MAC_DO_NOT_BBAI_STS;
|
|
}
|
|
uint32_t bit_map_0_7 = bit_map & 0xf;
|
|
uint32_t bit_map_8_15 = bit_map & 0xf0;
|
|
if (iot_bitmap_cbs((uint8_t *)&bit_map_0_7, sizeof(uint32_t))
|
|
== 3 &&
|
|
iot_bitmap_cbs((uint8_t *)&bit_map_8_15, sizeof(uint32_t))
|
|
== 1) {
|
|
/* mac in tx cca wait status, check spur */
|
|
mac_sts = MAC_TX_CCA_WAIT_STS;
|
|
} else if (iot_bitmap_cbs((uint8_t *)&bit_map_0_7, sizeof(uint32_t))
|
|
== 4 &&
|
|
iot_bitmap_cbs((uint8_t *)&bit_map_8_15, sizeof(uint32_t))
|
|
== 0) {
|
|
/* mac in rx listen status */
|
|
mac_sts = MAC_RX_LISTEN_STS;
|
|
}
|
|
}
|
|
|
|
/* mac status -> rx fc status */
|
|
if (MAC_RX_FC_STS == mac_sts) {
|
|
mac_set_sts_idle();
|
|
while (mac_sts) {
|
|
mac_sts = mac_dbg_bus_get_mac_sts(MAC_DEBUG_VALUE_320,
|
|
MAC_DEBUG_VALUE_MASK_BIT_15_17);
|
|
}
|
|
}
|
|
|
|
if (MAC_RX_LISTEN_STS == mac_sts || MAC_TX_CCA_WAIT_STS == mac_sts) {
|
|
mac_set_sts_idle();
|
|
phy_reset(PHY_RST_REASON_WARM);
|
|
iot_printf("txhang, phy reset\n");
|
|
ret = ERR_OK;
|
|
phy_reset(PHY_RST_REASON_WARM);
|
|
mac_free_sts_idle();
|
|
} else {
|
|
mac_free_sts_idle();
|
|
iot_printf("txhang mac_sts:0x%x, bkoff1:0x%x, "
|
|
"bkoff2:0x%x, bkoff3:0x%x, bkoff4:0x%x\n", mac_sts, bkoff1,
|
|
bkoff2, bkoff3, bkoff4);
|
|
mac_print_dbg_bus(0);
|
|
}
|
|
} else {
|
|
iot_printf("txhang phy_sts:0x%x\n", sts);
|
|
mac_print_dbg_bus(0);
|
|
}
|
|
mac_set_pcs_busy(0, 0);
|
|
|
|
return ret;
|
|
}
|
|
|
|
uint32_t mac_check_spur_cert(uint32_t time_ms)
|
|
{
|
|
mac_pdev_t *pdev = get_pdev_ptr(PLC_PDEV_ID);
|
|
|
|
return mac_check_spur(&pdev->mac_check_spur_ctxt, pdev, time_ms, false);
|
|
}
|
|
|
|
uint32_t mac_phy_channel_est_msg(uint32_t time_ms)
|
|
{
|
|
uint32_t ret = 0;
|
|
mac_msg_t *msg = mac_alloc_msg();
|
|
|
|
if (msg == NULL) {
|
|
IOT_ASSERT(0);
|
|
ret = ERR_NOMEM;
|
|
goto out;
|
|
}
|
|
|
|
msg->type = MAC_MSG_TYPE_PHY;
|
|
msg->id = MAC_MSG_ID_CHANNEL_ESTIMATED;
|
|
msg->data1 = time_ms;
|
|
mac_queue_msg(msg, MAC_MSG_QUEUE_HP);
|
|
|
|
out:
|
|
return ret;
|
|
}
|
|
|
|
#else
|
|
|
|
uint32_t mac_check_spur_init(mac_check_spur_ctxt_t *spur_ctxt, \
|
|
uint32_t check_spur_time_ntb)
|
|
{
|
|
(void)spur_ctxt;
|
|
(void)check_spur_time_ntb;
|
|
return 0;
|
|
}
|
|
|
|
uint32_t mac_check_spur_en(mac_check_spur_ctxt_t *spur_ctxt, uint32_t enable)
|
|
{
|
|
(void)spur_ctxt;
|
|
(void)enable;
|
|
return 0;
|
|
}
|
|
|
|
uint32_t mac_check_spur(mac_check_spur_ctxt_t *spur_ctxt, \
|
|
void *pdev, uint32_t time_ms, bool_t is_check_slot)
|
|
|
|
{
|
|
(void)spur_ctxt;
|
|
(void)pdev;
|
|
(void)time_ms;
|
|
(void)is_check_slot;
|
|
return 0;
|
|
}
|
|
|
|
uint32_t mac_check_spur_cert(uint32_t time_ms)
|
|
{
|
|
(void)time_ms;
|
|
return 0;
|
|
}
|
|
|
|
void mac_print_dbg_bus(uint8_t save_flash)
|
|
{
|
|
(void)save_flash;
|
|
}
|
|
|
|
uint32_t mac_phy_channel_est_msg(uint32_t time_ms)
|
|
{
|
|
(void)time_ms;
|
|
return 0;
|
|
}
|
|
|
|
uint32_t mac_check_spur_for_txhang()
|
|
{
|
|
return 0;
|
|
}
|
|
|
|
#endif
|