Files
kunlun/plc/halmac/mac_check_spur/mac_check_spur.c
2024-09-28 14:24:04 +08:00

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