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;
 | 
						|
}
 |