577 lines
17 KiB
C
577 lines
17 KiB
C
/****************************************************************************
|
|
|
|
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_pdev.h"
|
|
#include "iot_errno.h"
|
|
#if HW_PLATFORM == HW_PLATFORM_SIMU
|
|
#include "simulator_txrx.h"
|
|
#endif
|
|
#include "mac_rx_hw.h"
|
|
#include "mac_tx_hw.h"
|
|
#include "plc_const.h"
|
|
#include "mac_msg.h"
|
|
#include "mac.h"
|
|
#include "phy_chn.h"
|
|
#include "iot_io.h"
|
|
#include "iot_system.h"
|
|
#include "hw_phy_init.h"
|
|
#include "mac_status.h"
|
|
#include "mac_tx_power.h"
|
|
#include "mac_pm.h"
|
|
#include "mac_init_api.h"
|
|
#include "mac_channel.h"
|
|
#include "mac_channel_tools.h"
|
|
#include "mac_check_spur.h"
|
|
#include "hw_phy_api.h"
|
|
#include "mac_reset.h"
|
|
#include "mac_cmn_hw.h"
|
|
#include "mac_hw_tsfm.h"
|
|
#include "mac_rf.h"
|
|
|
|
mac_pdev_t* g_mac_pdev[MAX_PDEV_NUM];
|
|
static iot_mem_pool_t* g_mac_pdev_pool;
|
|
extern uint32_t g_fw_mode;
|
|
|
|
uint32_t mac_pdev_init() {
|
|
if(!g_mac_pdev[0])
|
|
{
|
|
/* create global pdev pool */
|
|
iot_mem_pool_new(PLC_MAC_PDEV_MID, MAX_PDEV_NUM, \
|
|
sizeof(mac_pdev_t), \
|
|
&g_mac_pdev_pool, 0);
|
|
}
|
|
/* init every pdev from the pool */
|
|
for (int i = 0; i < MAX_PDEV_NUM; i++) {
|
|
if(!g_mac_pdev[i]){
|
|
/* alloc a pdev */
|
|
g_mac_pdev[i] = iot_mem_pool_alloc(g_mac_pdev_pool);
|
|
g_mac_pdev[i]->pdev_id = (pdevid_t)i;
|
|
g_mac_pdev[i]->dbg_pkt_vdev_id = PLC_INV_DBG_PKT_MODE_VDEV_ID;
|
|
/* init vdev pool in the pdev */
|
|
if (iot_mem_pool_init(PLC_MAC_VDEV_MID, MAX_VDEV_NUM,
|
|
sizeof(mac_vdev_t), &g_mac_pdev[i]->vdev_pool, 0) != 0) {
|
|
return ERR_NOMEM;
|
|
}
|
|
|
|
g_mac_pdev[i]->cur_vdev_num = 0;
|
|
g_mac_pdev[i]->switch_ctxt_in_mac_isr = 0;
|
|
g_mac_pdev[i]->ena_ucast_hwretry = 0;
|
|
|
|
/* enable/disable broadcast hwretry by macro */
|
|
mac_set_bcast_hwretry_cfg(g_mac_pdev[i], MAC_BCAST_HWRETRY_ENABLE);
|
|
|
|
os_mem_set(g_mac_pdev[i]->vdev, 0,
|
|
sizeof(mac_vdev_t*) * MAX_VDEV_NUM);
|
|
|
|
os_mem_set(&g_mac_pdev[i]->mac_status, 0,
|
|
sizeof(mac_status_t));
|
|
|
|
os_mem_set(&g_mac_pdev[i]->mac_pm, 0,
|
|
sizeof(mac_pm_t));
|
|
|
|
g_mac_pdev[i]->mac_isr_rx_fc_ts_ntb = 0;
|
|
|
|
#if DEBUG_CANNOT_SENDOUT_PKT
|
|
/*create timer for cannot send out pkt*/
|
|
g_mac_pdev[i]->plc_tx_timer = \
|
|
os_create_timer(PLC_MAC_TX_HW_MID, true, \
|
|
mac_tx_hang_msg, NULL);
|
|
#endif
|
|
|
|
#if DEBUG_INVAILD_ADDR
|
|
g_mac_pdev[i]->buf_addr = NULL;
|
|
g_mac_pdev[i]->buf_len = 0;
|
|
#endif
|
|
|
|
#if (PLC_SUPPORT_CCO_ROLE && (DEBUG_CANNOT_SENDOUT_PKT || DBG_HW_DUMP))
|
|
IOT_PKT_GET(g_mac_pdev[i]->dump_pkt, 1024, 0, PLC_MAC_RX_HW_MID);
|
|
IOT_ASSERT(g_mac_pdev[i]->dump_pkt);
|
|
#endif
|
|
|
|
mac_check_spur_init(&g_mac_pdev[i]->mac_check_spur_ctxt, \
|
|
MAC_CHECK_SPUR_NTB);
|
|
|
|
mac_hw_tsfm_init((uint8_t)g_fw_mode, (uint8_t)i);
|
|
|
|
/* first time init scan */
|
|
mac_scan_init(g_mac_pdev[i], false);
|
|
}
|
|
|
|
/* INT DSR support */
|
|
mac_set_pdev_tx_comp(g_mac_pdev[i], mac_tx_hw_mpdu_comp_dsr);
|
|
|
|
if(g_fw_mode!=FTM_MODE)
|
|
{
|
|
mac_set_pdev_rx_cb(g_mac_pdev[i], mac_rx_hw_mpdu);
|
|
}
|
|
else
|
|
{
|
|
mac_set_pdev_rx_cb(g_mac_pdev[i], mac_rx_hw_mpdu_internal);
|
|
}
|
|
|
|
#if HW_PLATFORM == HW_PLATFORM_SIMU
|
|
/* init simulator layer */
|
|
simulator_init_ex(&g_mac_pdev[i]->simu, g_mac_pdev[i],
|
|
NULL, NULL, mac_tx_hw_mpdu_comp_dsr,
|
|
NULL, NULL, mac_rx_hw_mpdu, WORKMODE_PLC);
|
|
#else
|
|
/* FPGA or chip */
|
|
mac_tx_hw_init(PHY_PROTO_TYPE_GET(), g_mac_pdev[i]);
|
|
mac_rx_hw_init(g_fw_mode);
|
|
#if K48_STA_MULTI_CHANNEL_SELECT_ENABLE
|
|
iot_mac_k48sta_scan_channel_init(g_mac_pdev[i]);
|
|
#endif
|
|
#endif
|
|
mac_pm_init(g_mac_pdev[i]);
|
|
|
|
if (g_fw_mode != FTM_MODE)
|
|
{
|
|
/* init hwq & ring for each pdev */
|
|
mac_rx_ring_ctxt_init(&g_mac_pdev[i]->ring_hdl);
|
|
#if HW_PLATFORM == HW_PLATFORM_SIMU
|
|
simu_set_rx_ring_ptr(&g_mac_pdev[i]->simu,
|
|
&g_mac_pdev[i]->ring_hdl.ring[0]);
|
|
#endif
|
|
mac_q_init(&g_mac_pdev[i]->hwq_hdl);
|
|
|
|
/* put this after tx_hw init for the dbg mode setting */
|
|
/* init traffic default service */
|
|
/* BCN */
|
|
mac_q_alloc_hwq(&g_mac_pdev[i]->hwq_hdl, \
|
|
mac_q_get_swq_type(PLC_BCN_REGION_BCN, \
|
|
PLC_PHASE_A, (lid_t)0));
|
|
mac_q_alloc_hwq(&g_mac_pdev[i]->hwq_hdl, \
|
|
mac_q_get_swq_type(PLC_BCN_REGION_BCN, \
|
|
PLC_PHASE_B, (lid_t)0));
|
|
mac_q_alloc_hwq(&g_mac_pdev[i]->hwq_hdl, \
|
|
mac_q_get_swq_type(PLC_BCN_REGION_BCN, \
|
|
PLC_PHASE_C, (lid_t)0));
|
|
/* CSMA */
|
|
mac_q_alloc_hwq(&g_mac_pdev[i]->hwq_hdl, \
|
|
mac_q_get_swq_type(PLC_BCN_REGION_CSMA, \
|
|
PLC_PHASE_A, (lid_t)0));
|
|
mac_q_alloc_hwq(&g_mac_pdev[i]->hwq_hdl, \
|
|
mac_q_get_swq_type(PLC_BCN_REGION_CSMA, \
|
|
PLC_PHASE_A, (lid_t)1));
|
|
mac_q_alloc_hwq(&g_mac_pdev[i]->hwq_hdl, \
|
|
mac_q_get_swq_type(PLC_BCN_REGION_CSMA, \
|
|
PLC_PHASE_A, (lid_t)2));
|
|
mac_q_alloc_hwq(&g_mac_pdev[i]->hwq_hdl, \
|
|
mac_q_get_swq_type(PLC_BCN_REGION_CSMA, \
|
|
PLC_PHASE_A, (lid_t)3));
|
|
mac_q_alloc_hwq(&g_mac_pdev[i]->hwq_hdl, \
|
|
mac_q_get_swq_type(PLC_BCN_REGION_CSMA, \
|
|
PLC_PHASE_B, (lid_t)0));
|
|
mac_q_alloc_hwq(&g_mac_pdev[i]->hwq_hdl, \
|
|
mac_q_get_swq_type(PLC_BCN_REGION_CSMA, \
|
|
PLC_PHASE_B, (lid_t)1));
|
|
mac_q_alloc_hwq(&g_mac_pdev[i]->hwq_hdl, \
|
|
mac_q_get_swq_type(PLC_BCN_REGION_CSMA, \
|
|
PLC_PHASE_B, (lid_t)2));
|
|
mac_q_alloc_hwq(&g_mac_pdev[i]->hwq_hdl, \
|
|
mac_q_get_swq_type(PLC_BCN_REGION_CSMA, \
|
|
PLC_PHASE_B, (lid_t)3));
|
|
mac_q_alloc_hwq(&g_mac_pdev[i]->hwq_hdl, \
|
|
mac_q_get_swq_type(PLC_BCN_REGION_CSMA, \
|
|
PLC_PHASE_C, (lid_t)0));
|
|
mac_q_alloc_hwq(&g_mac_pdev[i]->hwq_hdl, \
|
|
mac_q_get_swq_type(PLC_BCN_REGION_CSMA, \
|
|
PLC_PHASE_C, (lid_t)1));
|
|
mac_q_alloc_hwq(&g_mac_pdev[i]->hwq_hdl, \
|
|
mac_q_get_swq_type(PLC_BCN_REGION_CSMA, \
|
|
PLC_PHASE_C, (lid_t)2));
|
|
mac_q_alloc_hwq(&g_mac_pdev[i]->hwq_hdl, \
|
|
mac_q_get_swq_type(PLC_BCN_REGION_CSMA, \
|
|
PLC_PHASE_C, (lid_t)3));
|
|
/* BCSMA */
|
|
mac_q_alloc_hwq(&g_mac_pdev[i]->hwq_hdl, \
|
|
mac_q_get_swq_type(PLC_BCN_REGION_BCSMA, \
|
|
PLC_PHASE_A, (lid_t)LID_BCSMA_START));
|
|
mac_q_alloc_hwq(&g_mac_pdev[i]->hwq_hdl, \
|
|
mac_q_get_swq_type(PLC_BCN_REGION_BCSMA, \
|
|
PLC_PHASE_B, (lid_t)LID_BCSMA_START));
|
|
mac_q_alloc_hwq(&g_mac_pdev[i]->hwq_hdl, \
|
|
mac_q_get_swq_type(PLC_BCN_REGION_BCSMA, \
|
|
PLC_PHASE_C, (lid_t)LID_BCSMA_START));
|
|
}
|
|
#if DBG_RX_ABORT_REASON_4 == 1
|
|
g_mac_pdev[i]->cont_rx_abort4_cnt = 0;
|
|
#endif
|
|
|
|
mac_multi_sync_init((uint8_t)i);
|
|
|
|
#if (IOT_STA_CONTROL_MODE == IOT_STA_CONTROL_TYPE_STA)
|
|
mac_channel_test_init();
|
|
#endif
|
|
|
|
/* init rf pdev */
|
|
mac_rf_pdev_init((pdevid_t)i);
|
|
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
/* get how many pdev mac supported
|
|
* pdev_num_returned - the pointer returned about the number
|
|
* return 0 for success and non-zero for failure.
|
|
*/
|
|
uint32_t mac_get_pdev_num(uint8_t *pdev_num_returned) {
|
|
*pdev_num_returned = MAX_PDEV_NUM;
|
|
return 0;
|
|
}
|
|
|
|
/*
|
|
* mac_set_pdev_cfg - pull a msg to set a pdev's config
|
|
*
|
|
* pdev_id - which pdev to config
|
|
* cfg_struct_ptr - the pointer to the param config structure
|
|
*
|
|
* return 0 for success and non-zero for failure.
|
|
*/
|
|
uint32_t mac_set_pdev_cfg(pdevid_t pdev_id, void *cfg_struct_ptr)
|
|
{
|
|
uint32_t ret = 0;
|
|
mac_msg_sync_t *msg = mac_alloc_msg_sync();
|
|
|
|
if (msg == NULL) {
|
|
IOT_ASSERT(0);
|
|
ret = ERR_NOMEM;
|
|
goto out;
|
|
}
|
|
|
|
msg->msg.type = MAC_MSG_TYPE_CVG;
|
|
msg->msg.id = MAC_MSG_ID_CVG_SET_PDEV_CFG;
|
|
msg->msg.data1 = pdev_id;
|
|
msg->msg.data2 = cfg_struct_ptr;
|
|
mac_queue_msg_sync(msg, MAC_MSG_QUEUE_HP);
|
|
ret = msg->msg.data1;
|
|
mac_free_msg_sync(msg);
|
|
|
|
out:
|
|
return ret;
|
|
}
|
|
|
|
/*
|
|
* mac_set_pdev_cfg_internal - set a pdev's config
|
|
*
|
|
* pdev_id - which pdev to config
|
|
* cfg_struct_ptr - the pointer to the param config structure
|
|
*
|
|
* return 0 for success and non-zero for failure.
|
|
*/
|
|
uint32_t mac_set_pdev_cfg_internal(pdevid_t pdev_id, void *cfg_struct_ptr)
|
|
{
|
|
uint32_t ret = 0;
|
|
cfg_data_tlv *tlv = (cfg_data_tlv *)cfg_struct_ptr;
|
|
mac_pdev_t *pdev = g_mac_pdev[pdev_id];
|
|
switch (tlv->type) {
|
|
case PLC_PDEV_CFG_SET_BAND:
|
|
{
|
|
PLC_PDEV_CFG_SET_BANDID_STRUCT *xtlv = \
|
|
(PLC_PDEV_CFG_SET_BANDID_STRUCT *)tlv;
|
|
uint32_t curr_band_id;
|
|
|
|
if (pdev == NULL) {
|
|
ret = ERR_INVAL;
|
|
goto out;
|
|
}
|
|
|
|
curr_band_id = phy_band_id_get();
|
|
uint32_t proto = PHY_PROTO_TYPE_GET();
|
|
if (PLC_PROTO_TYPE_SPG == proto && ENABLE_MULTIBAND) {
|
|
if (xtlv->band_id == IOT_SUPPORT_TONE_32_120) {
|
|
xtlv->band_id = IOT_SUPPORT_TONE_MULTI_BAND021;
|
|
}
|
|
}
|
|
|
|
if (curr_band_id != xtlv->band_id) {
|
|
iot_printf("%s proto:%d set band id=%d\n",
|
|
__FUNCTION__, proto, xtlv->band_id);
|
|
phy_band_id_to_set(xtlv->band_id);
|
|
phy_mask_id_to_set(
|
|
phy_band_to_tonemask_id_get((uint8_t)xtlv->band_id));
|
|
mac_new_phy_cfg_apply();
|
|
/* add this line for cert test may change
|
|
* band later and use the curr_band_id
|
|
*/
|
|
curr_band_id = xtlv->band_id;
|
|
|
|
/* clear mac status cnt */
|
|
mac_status_cnt_clr();
|
|
} else {
|
|
iot_printf("%s already in band id %lu\n", __FUNCTION__,
|
|
xtlv->band_id);
|
|
}
|
|
if (IOT_SUPPORT_TONE_231_490_CE == xtlv->band_id) {
|
|
uint8_t hplc_power = MAC_TX_POWER_CE_DEFAULT;
|
|
mac_set_tx_power_cap(pdev->vdev[0], &hplc_power, NULL, 0);
|
|
}
|
|
#if CPLC_IOT_CERT_ENABLE
|
|
extern uint32_t mac_cert_test_band_cfg(uint8_t band_id);
|
|
mac_cert_test_band_cfg(curr_band_id);
|
|
#endif
|
|
break;
|
|
}
|
|
case PLC_PDEV_CFG_SET_SWAGC:
|
|
{
|
|
PLC_PDEV_CFG_SET_SWAGC_STRUCT *xtlv = \
|
|
(PLC_PDEV_CFG_SET_SWAGC_STRUCT *)tlv;
|
|
phy_swagc_set(!!(xtlv->ena));
|
|
iot_printf("mac swagc:%d\n", xtlv->ena);
|
|
break;
|
|
}
|
|
case PLC_PDEV_CFG_SET_SCAN_BAND_TBL:
|
|
{
|
|
PLC_PDEV_CFG_BAND_RANGE_STRUCT *xtlv =
|
|
(PLC_PDEV_CFG_BAND_RANGE_STRUCT *)tlv;
|
|
|
|
if (pdev == NULL) {
|
|
ret = ERR_INVAL;
|
|
goto out;
|
|
}
|
|
|
|
mac_scan_set_band_info(PHY_PROTO_TYPE_GET(), xtlv->plc_scan_cnt,
|
|
xtlv->plc_scan_tbl);
|
|
break;
|
|
}
|
|
case PLC_PDEV_CFG_SET_RF_SCAN_TBL:
|
|
{
|
|
PLC_PDEV_CFG_RF_RANGE_STRUCT *xtlv =
|
|
(PLC_PDEV_CFG_RF_RANGE_STRUCT *)tlv;
|
|
|
|
if (pdev == NULL) {
|
|
ret = ERR_INVAL;
|
|
goto out;
|
|
}
|
|
|
|
mac_rf_scan_set_scan_tbl(xtlv->rf_cnt, (uint8_t *)xtlv->rf_scan_tbl);
|
|
break;
|
|
}
|
|
default:
|
|
IOT_ASSERT(0);
|
|
}
|
|
|
|
out:
|
|
return ret;
|
|
}
|
|
|
|
uint32_t mac_get_pdev_cfg(uint8_t pdev_id, void *cfg_struct_ptr)
|
|
{
|
|
uint32_t ret = 0;
|
|
mac_msg_sync_t *msg = mac_alloc_msg_sync();
|
|
|
|
if (msg == NULL) {
|
|
IOT_ASSERT(0);
|
|
ret = ERR_NOMEM;
|
|
goto out;
|
|
}
|
|
|
|
msg->msg.type = MAC_MSG_TYPE_CVG;
|
|
msg->msg.id = MAC_MSG_ID_CVG_GET_PDEV_CFG;
|
|
msg->msg.data1 = pdev_id;
|
|
msg->msg.data2 = cfg_struct_ptr;
|
|
mac_queue_msg_sync(msg, MAC_MSG_QUEUE_HP);
|
|
ret = msg->msg.data1;
|
|
mac_free_msg_sync(msg);
|
|
|
|
out:
|
|
return ret;
|
|
}
|
|
|
|
/*
|
|
* mac_set_pdev_cfg_internal - set a pdev's config
|
|
*
|
|
* pdev_id - which pdev to config
|
|
* cfg_struct_ptr - the pointer to the param config structure
|
|
*
|
|
* return 0 for success and non-zero for failure.
|
|
*/
|
|
uint32_t mac_get_pdev_cfg_internal(pdevid_t pdev_id, void *cfg_struct_ptr)
|
|
{
|
|
uint32_t ret = ERR_FAIL;
|
|
cfg_data_tlv *tlv = (cfg_data_tlv *)cfg_struct_ptr;
|
|
(void)pdev_id;
|
|
switch (tlv->type) {
|
|
case PLC_PDEV_CFG_GET_BAND_TBL:
|
|
{
|
|
PLC_PDEV_CFG_BAND_RANGE_STRUCT *xtlv =
|
|
(PLC_PDEV_CFG_BAND_RANGE_STRUCT *)tlv;
|
|
if (PLC_GET_SUPPORT_BAND == xtlv->is_scan_band) {
|
|
xtlv->plc_scan_cnt =
|
|
(uint8_t)mac_scan_get_support_band_tbl(PHY_PROTO_TYPE_GET(),
|
|
PLC_SCAN_BAND_MAX_CNT, xtlv->plc_scan_tbl);
|
|
if (xtlv->plc_scan_cnt) {
|
|
ret = ERR_OK;
|
|
}
|
|
} else if (PLC_GET_SCAN_BAND == xtlv->is_scan_band) {
|
|
xtlv->plc_scan_cnt =
|
|
(uint8_t)mac_scan_get_band_info(PHY_PROTO_TYPE_GET(),
|
|
PLC_SCAN_BAND_MAX_CNT, xtlv->plc_scan_tbl);
|
|
if (xtlv->plc_scan_cnt) {
|
|
ret = ERR_OK;
|
|
}
|
|
} else {
|
|
xtlv->plc_scan_cnt = 0;
|
|
ret = ERR_FAIL;
|
|
}
|
|
break;
|
|
}
|
|
default:
|
|
IOT_ASSERT(0);
|
|
}
|
|
|
|
return ret;
|
|
}
|
|
|
|
void mac_set_pdev_tx_comp(mac_pdev_t *pdev, \
|
|
mac_tx_hw_comp_t tx_comp_cb)
|
|
{
|
|
IOT_ASSERT(pdev);
|
|
pdev->tx_comp = tx_comp_cb;
|
|
}
|
|
|
|
void mac_set_pdev_rx_cb(mac_pdev_t *pdev, \
|
|
mac_rx_t rx_cb)
|
|
{
|
|
IOT_ASSERT(pdev);
|
|
pdev->rx = rx_cb;
|
|
}
|
|
|
|
void mac_pdev_send_reset_war_msg(mac_pdev_t *pdev, uint32_t flag)
|
|
{
|
|
if (pdev == NULL) {
|
|
return;
|
|
}
|
|
|
|
mac_msg_t *msg = mac_alloc_msg();
|
|
|
|
if (msg == NULL) {
|
|
iot_printf("WAR reset msg req failed.\n");
|
|
IOT_ASSERT(0);
|
|
return;
|
|
}
|
|
msg->type = MAC_MSG_TYPE_MAC;
|
|
msg->id = MAC_MSG_ID_MAC_WARM_RESET_WAR;
|
|
msg->data1 = flag;
|
|
mac_queue_msg(msg, MAC_MSG_QUEUE_HP);
|
|
}
|
|
|
|
mac_pdev_t * IRAM_ATTR get_pdev_ptr(uint32_t pdev_id)
|
|
{
|
|
if (pdev_id >= MAX_PDEV_NUM) {
|
|
IOT_ASSERT(0);
|
|
return NULL;
|
|
}
|
|
return g_mac_pdev[pdev_id];
|
|
}
|
|
|
|
void mac_tx_hang_msg(timer_id_t timer_id, void * arg)
|
|
{
|
|
(void)timer_id;
|
|
(void)arg;
|
|
mac_msg_t *msg = mac_alloc_msg();
|
|
|
|
if (msg == NULL) {
|
|
iot_printf("send tx_hang msg failed.\n");
|
|
IOT_ASSERT(0);
|
|
return;
|
|
}
|
|
msg->type = MAC_MSG_TYPE_MAC;
|
|
msg->id = MAC_MSG_ID_MAC_DEBUG_TX_HANG;
|
|
|
|
mac_queue_msg(msg, MAC_MSG_QUEUE_HP);
|
|
}
|
|
|
|
void mac_tx_hang_handle()
|
|
{
|
|
#if DEBUG_CANNOT_SENDOUT_PKT
|
|
iot_printf("%s, phy hang\n", __FUNCTION__);
|
|
mac_pdev_t *pdev = get_pdev_ptr(PLC_PDEV_ID);
|
|
mac_vdev_t *vdev = get_vdev_ptr(PLC_PDEV_ID, PLC_DEFAULT_VDEV);
|
|
uint8_t hwq_id;
|
|
|
|
if ((mac_vdev_cfg_get_node_role(vdev) != PLC_DEV_ROLE_CCO)
|
|
&& !(vdev->bcn_ctx.sta.allow_reuse_ts
|
|
&& vdev->bcn_ctx.time_slot.allow_reuse)) {
|
|
return;
|
|
}
|
|
|
|
pdev->plc_con_tx_timeout_cnt++;
|
|
|
|
g_phy_cpu_share_ctxt.isr_cnt0 = mac_get_isr_cnt();
|
|
|
|
/* check time */
|
|
if (pdev->plc_con_tx_timeout_cnt <= TX_HANG_HANDLE_CNT) {
|
|
phy_csma_ignore_cca(true);
|
|
mac_add_csma_ignore_cca_cnt();
|
|
mac_dump_buf(MAC_DUMP_TYPE_10, NULL, 0, NULL, 0, NULL, 0, 0);
|
|
phy_dbg_sts_print();
|
|
/* doing check spur operation */
|
|
uint32_t ret = mac_check_spur_for_txhang();
|
|
if (ret) {
|
|
iot_printf("tx hang spur failed:%d\n!", ret);
|
|
}
|
|
} else {
|
|
/*the second time, printf mac and phy info */
|
|
mac_phy_print_debug_info();
|
|
}
|
|
|
|
for (hwq_id = MAC_QUE_CSMA_A_0; hwq_id <= MAC_QUE_BCSMA_C; hwq_id++) {
|
|
mac_txq_trigger_send(hwq_id);
|
|
}
|
|
|
|
//TODO: to reset phy
|
|
//mac_warm_reset_war();
|
|
#endif
|
|
}
|
|
|
|
void mac_set_bcast_hwretry_cfg(mac_pdev_t *pdev, uint8_t ena)
|
|
{
|
|
pdev->ena_bcast_hwretry = !!ena;
|
|
}
|
|
|
|
uint32_t mac_get_bcast_hwretry_cfg(mac_pdev_t *pdev)
|
|
{
|
|
return pdev->ena_bcast_hwretry;
|
|
}
|
|
|
|
void mac_rx_hang_handle(mac_pdev_t *pdev)
|
|
{
|
|
uint32_t role, tei, nid;
|
|
role = mac_get_hw_role();
|
|
tei = mac_get_hw_tei();
|
|
nid = mac_get_hw_nid();
|
|
|
|
/* rx only mode enable */
|
|
mac_block_all_tx_ena(&pdev->hwq_hdl, true);
|
|
|
|
mac_pre_phy_reinit();
|
|
/* mac reinit */
|
|
mac_reinit(MAC_RST_REASON_COLD, PHY_PROTO_TYPE_GET(),
|
|
phy_band_id_get(), phy_mask_id_get(), mac_rf_get_self_option(),
|
|
mac_rf_get_self_channel());
|
|
|
|
mac_post_phy_reinit(0);
|
|
|
|
mac_config_nid(NULL, nid);
|
|
mac_config_tei(NULL, (uint16_t)tei);
|
|
mac_config_role(NULL, (uint8_t)role);
|
|
|
|
/* rx only mode disable */
|
|
mac_block_all_tx_ena(&pdev->hwq_hdl, false);
|
|
|
|
return;
|
|
}
|