650 lines
		
	
	
		
			22 KiB
		
	
	
	
		
			C
		
	
	
		
			Executable File
		
	
	
	
	
			
		
		
	
	
			650 lines
		
	
	
		
			22 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.
 | 
						|
 | 
						|
****************************************************************************/
 | 
						|
 | 
						|
/* os shim includes */
 | 
						|
#include "iot_config.h"
 | 
						|
#include "os_types.h"
 | 
						|
 | 
						|
/* plc public api includes */
 | 
						|
#include "plc_fr.h"
 | 
						|
#include "plc_const.h"
 | 
						|
#include "iot_bitops.h"
 | 
						|
#include "iot_mem.h"
 | 
						|
 | 
						|
/* mac module internal includes */
 | 
						|
#include "mac.h"
 | 
						|
#include "mac_dsr.h"
 | 
						|
#include "mac_isr.h"
 | 
						|
#include "hw_reg_api.h"
 | 
						|
#include "mac_sys_reg.h"
 | 
						|
 | 
						|
/* driver includes */
 | 
						|
#include "iot_irq.h"
 | 
						|
 | 
						|
/* WAR */
 | 
						|
//#include "mac_tx_hw.h"
 | 
						|
 | 
						|
#include "mac_tx_power.h"
 | 
						|
#include "hw_phy_api.h"
 | 
						|
#include "mac_rx_buf_ring.h"
 | 
						|
#if HW_PLATFORM >= HW_PLATFORM_FPGA
 | 
						|
#include "mac_raw_reg.h"
 | 
						|
#include "mac_rawdata_hw.h"
 | 
						|
#include "plc_protocol.h"
 | 
						|
#include "phy_bb.h"
 | 
						|
#endif
 | 
						|
#include "mac_pdev.h"
 | 
						|
#include "mac_peer.h"
 | 
						|
#include "rx_mpdu_end.h"
 | 
						|
#include "hw_reg_api.h"
 | 
						|
#include "mac_rx_reg.h"
 | 
						|
#include "mac_rawdata_hw.h"
 | 
						|
#include "mac_sched_hw.h"
 | 
						|
#include "phy_rx_fd_reg.h"
 | 
						|
#include "phy_txrx_pwr.h"
 | 
						|
#include "phy_multi_ppm.h"
 | 
						|
 | 
						|
#include "mac_msdu.h"
 | 
						|
#include "mac_tx_power.h"
 | 
						|
#include "mpdu_header.h"
 | 
						|
#include "hw_war.h"
 | 
						|
 | 
						|
mac_isr_ctx_t   g_mac_isr_ctx_cpu1 = {0};
 | 
						|
mac_isr_ctx_t   *p_mac_isr_ctx_cpu1 = &g_mac_isr_ctx_cpu1;
 | 
						|
 | 
						|
/**
 | 
						|
 * Save sof rx information for SPG protocol
 | 
						|
 * to fix the bug responding sack error when rx a
 | 
						|
 * unicast sof frame.
 | 
						|
 */
 | 
						|
sof_rx_info_t g_sof_rx_info = {0};
 | 
						|
 | 
						|
#if ENA_WAR_244
 | 
						|
static void mac_rawdata_sack_tx_isr_callback(void)
 | 
						|
{
 | 
						|
#if ENA_WAR_244
 | 
						|
    uint32_t fc[4] = { 0 };
 | 
						|
    uint32_t tmp;
 | 
						|
    uint32_t sack_fc_org_status;
 | 
						|
#if SUPPORT_SOUTHERN_POWER_GRID
 | 
						|
    spg_frame_control_t *spg_sack_fc;
 | 
						|
#endif
 | 
						|
 | 
						|
#if SUPPORT_SMART_GRID
 | 
						|
    frame_control_t *sg_sack_fc;
 | 
						|
#endif
 | 
						|
 | 
						|
    /* clear bb record flag to record next sof */
 | 
						|
    if (!g_phy_cpu_share_ctxt.need_record_tei) {
 | 
						|
        g_phy_cpu_share_ctxt.need_record_tei = true;
 | 
						|
    } else {
 | 
						|
        /* TODO:we should prevent BB from sending this packet */
 | 
						|
        g_phy_cpu_share_ctxt.sack_err_occur_cnt++;
 | 
						|
    }
 | 
						|
 | 
						|
#if SUPPORT_SOUTHERN_POWER_GRID
 | 
						|
    if (PLC_PROTO_TYPE_SPG == PHY_PROTO_TYPE_GET()) {
 | 
						|
        sack_fc_org_status = (iot_raw_read_reg(RAW_REG_TYPE_MAC, \
 | 
						|
            CFG_TX_RAW_FC_0_ADDR) >> 12) & 0xF;
 | 
						|
        spg_sack_fc = (spg_frame_control_t *)fc;
 | 
						|
 | 
						|
        spg_sack_fc->delimiter_type = FC_DELIM_SACK;
 | 
						|
        spg_sack_fc->access_ind     = 1;
 | 
						|
        spg_sack_fc->snid           = RGF_MAC_READ_REG(CFG_MYNID_ADDR);
 | 
						|
        spg_sack_fc->vf.sack.dtei   = g_phy_cpu_share_ctxt.sof_src_tei;
 | 
						|
        spg_sack_fc->vf.sack.rx_pb  = g_sof_rx_info.att.pb_num;
 | 
						|
        spg_sack_fc->vf.sack.rx_status = sack_fc_org_status;
 | 
						|
        spg_sack_fc->vf.sack.version = SPG_STANDARD_VERSION;
 | 
						|
        /* form sack fc result field */
 | 
						|
        switch (spg_sack_fc->vf.sack.rx_pb) {
 | 
						|
            case 1:
 | 
						|
                spg_sack_fc->vf.sack.rx_result = \
 | 
						|
                    (0x1 == (0x1 & spg_sack_fc->vf.sack.rx_status))?0:1;
 | 
						|
                break;
 | 
						|
            case 2:
 | 
						|
                spg_sack_fc->vf.sack.rx_result = \
 | 
						|
                    (0x3 == (0x3 & spg_sack_fc->vf.sack.rx_status))?0:1;
 | 
						|
                break;
 | 
						|
            case 3:
 | 
						|
                spg_sack_fc->vf.sack.rx_result = \
 | 
						|
                    (0x7 == (0x7 & spg_sack_fc->vf.sack.rx_status))?0:1;
 | 
						|
                break;
 | 
						|
            case 4:
 | 
						|
                spg_sack_fc->vf.sack.rx_result = \
 | 
						|
                    (0xF == (0xF & spg_sack_fc->vf.sack.rx_status))?0:1;
 | 
						|
                break;
 | 
						|
            default:
 | 
						|
                /* for other pb num, use the hw's result but only 1 bit */
 | 
						|
                spg_sack_fc->vf.sack.rx_result &= 0x1;
 | 
						|
                break;
 | 
						|
        }
 | 
						|
 | 
						|
        iot_raw_write_reg(RAW_REG_TYPE_MAC, CFG_TX_SW_FC_0_ADDR, fc[0]);
 | 
						|
        iot_raw_write_reg(RAW_REG_TYPE_MAC, CFG_TX_SW_FC_1_ADDR, fc[1]);
 | 
						|
        iot_raw_write_reg(RAW_REG_TYPE_MAC, CFG_TX_SW_FC_2_ADDR, fc[2]);
 | 
						|
        iot_raw_write_reg(RAW_REG_TYPE_MAC, CFG_TX_SW_FC_3_ADDR, fc[3]);
 | 
						|
    }
 | 
						|
    else
 | 
						|
#endif
 | 
						|
#if SUPPORT_SMART_GRID
 | 
						|
    if (PLC_PROTO_TYPE_SG == PHY_PROTO_TYPE_GET()) {
 | 
						|
        sack_fc_org_status = \
 | 
						|
            iot_raw_read_reg(RAW_REG_TYPE_MAC, CFG_TX_RAW_FC_1_ADDR);
 | 
						|
        sg_sack_fc = (frame_control_t *)fc;
 | 
						|
 | 
						|
        sg_sack_fc->delimiter_type = FC_DELIM_SACK;
 | 
						|
        sg_sack_fc->network_type   = 0;
 | 
						|
        sg_sack_fc->nid            = RGF_MAC_READ_REG(CFG_MYNID_ADDR);
 | 
						|
        sg_sack_fc->vf.sack.stei   = RGF_MAC_READ_REG(CFG_MYTEI_ADDR);
 | 
						|
        sg_sack_fc->vf.sack.dtei   = g_phy_cpu_share_ctxt.sof_src_tei;
 | 
						|
        sg_sack_fc->vf.sack.rx_pb  = g_sof_rx_info.att.pb_num;
 | 
						|
        sg_sack_fc->vf.sack.rx_status =
 | 
						|
            ((sack_fc_org_status & 0x000000F0) >> 4);
 | 
						|
        sg_sack_fc->vf.sack.snr    = g_sof_rx_info.snr;
 | 
						|
        sg_sack_fc->vf.sack.version = SG_STANDARD_VERSION;
 | 
						|
        tmp = RGF_MAC_READ_REG(CFG_TX_CTRL_ADDR);
 | 
						|
        sg_sack_fc->vf.sack.load = REG_FIELD_GET(CFG_SG_STA_LOADING, tmp);
 | 
						|
        sg_sack_fc->vf.sack.ext_deli = REG_FIELD_GET(CFG_SG_SACK_VER, tmp);
 | 
						|
        /* form sack fc result field */
 | 
						|
        switch (sg_sack_fc->vf.sack.rx_pb) {
 | 
						|
            case 1:
 | 
						|
                sg_sack_fc->vf.sack.rx_result = \
 | 
						|
                    (0x1 == (0x1 & sg_sack_fc->vf.sack.rx_status))?0:1;
 | 
						|
                break;
 | 
						|
            case 2:
 | 
						|
                sg_sack_fc->vf.sack.rx_result = \
 | 
						|
                    (0x3 == (0x3 & sg_sack_fc->vf.sack.rx_status))?0:1;
 | 
						|
                break;
 | 
						|
            case 3:
 | 
						|
                sg_sack_fc->vf.sack.rx_result = \
 | 
						|
                    (0x7 == (0x7 & sg_sack_fc->vf.sack.rx_status))?0:1;
 | 
						|
                break;
 | 
						|
            case 4:
 | 
						|
                sg_sack_fc->vf.sack.rx_result = \
 | 
						|
                    (0xF == (0xF & sg_sack_fc->vf.sack.rx_status))?0:1;
 | 
						|
                break;
 | 
						|
            default:
 | 
						|
                /* for other pb num, use the hw's result but only 1 bit */
 | 
						|
                sg_sack_fc->vf.sack.rx_result &= 0x1;
 | 
						|
                break;
 | 
						|
        }
 | 
						|
 | 
						|
        iot_raw_write_reg(RAW_REG_TYPE_MAC, CFG_TX_SW_FC_0_ADDR, fc[0]);
 | 
						|
        iot_raw_write_reg(RAW_REG_TYPE_MAC, CFG_TX_SW_FC_1_ADDR, fc[1]);
 | 
						|
        iot_raw_write_reg(RAW_REG_TYPE_MAC, CFG_TX_SW_FC_2_ADDR, fc[2]);
 | 
						|
        iot_raw_write_reg(RAW_REG_TYPE_MAC, CFG_TX_SW_FC_3_ADDR, fc[3]);
 | 
						|
    }
 | 
						|
    else
 | 
						|
#endif
 | 
						|
    {
 | 
						|
        //TODO: assert or don't do anything. don't del the case
 | 
						|
        (void)sack_fc_org_status;
 | 
						|
    }
 | 
						|
 | 
						|
    /* fc valid */
 | 
						|
    iot_raw_write_reg(RAW_REG_TYPE_MAC, CFG_SW_FC_VALID_ADDR, 0x1);
 | 
						|
    g_phy_cpu_share_ctxt.tx_unicast_sack_ts = mac_sched_get_ntb(NULL);
 | 
						|
    /* clear interrupt status */
 | 
						|
    tmp = iot_raw_read_reg(RAW_REG_TYPE_MAC, CFG_RAW_INT_CLR_ADDR);
 | 
						|
    tmp |= MAC_TX_SACK_INT_STATUS;
 | 
						|
    iot_raw_write_reg(RAW_REG_TYPE_MAC,CFG_RAW_INT_CLR_ADDR, tmp);
 | 
						|
#endif
 | 
						|
}
 | 
						|
#endif
 | 
						|
 | 
						|
#if (ENA_WAR_NNCCO_FEAT)
 | 
						|
 | 
						|
void IRAM_ATTR mac_nncco_war_fill_fcinfo(void *fc)
 | 
						|
{
 | 
						|
#if HW_PLATFORM != HW_PLATFORM_SIMU
 | 
						|
    uint32_t proto = PHY_PROTO_TYPE_GET();
 | 
						|
    IOT_ASSERT(fc);
 | 
						|
#if SUPPORT_SMART_GRID
 | 
						|
        if (PLC_PROTO_TYPE_SG == proto) {
 | 
						|
            frame_control_t *cur_fc = (frame_control_t *)fc;
 | 
						|
            if (FC_DELIM_NNCCO == cur_fc->delimiter_type) {
 | 
						|
                uint32_t recv_nid;
 | 
						|
                uint64_t org_start_ntb;
 | 
						|
                uint64_t curr_start_ntb;
 | 
						|
                uint16_t curr_duration;
 | 
						|
                uint16_t sbandoffset;
 | 
						|
                uint64_t start_ntb_h24 = cur_fc->vf.nn_cco_sw.start_ntb_h24;
 | 
						|
                org_start_ntb = (uint64_t)((start_ntb_h24 & 0xFFFFFF) << 32 | \
 | 
						|
                            cur_fc->vf.nn_cco_sw.start_ntb_l32);
 | 
						|
                curr_start_ntb = mac_sched_get_ntb64(NULL);
 | 
						|
                if (curr_start_ntb >= org_start_ntb) {
 | 
						|
                    sbandoffset = 0;
 | 
						|
                    if ((curr_start_ntb - org_start_ntb) >=
 | 
						|
                        MAC_MS_TO_NTB((uint64_t)cur_fc->vf.nn_cco_sw.duration)) {
 | 
						|
                        curr_duration = 0;
 | 
						|
                    } else {
 | 
						|
                        curr_duration = cur_fc->vf.nn_cco_sw.duration -
 | 
						|
                            (uint16_t)MAC_NTB_TO_MS(curr_start_ntb - org_start_ntb);
 | 
						|
                    }
 | 
						|
                } else {
 | 
						|
                    sbandoffset =
 | 
						|
                        (uint16_t)MAC_NTB_TO_MS(org_start_ntb - curr_start_ntb);
 | 
						|
                    curr_duration = cur_fc->vf.nn_cco_sw.duration;
 | 
						|
                }
 | 
						|
 | 
						|
                recv_nid = cur_fc->vf.nn_cco_sw.receive_nid;
 | 
						|
                cur_fc->vf.nn_cco.receive_nid = recv_nid;
 | 
						|
                cur_fc->vf.nn_cco.duration    = curr_duration;
 | 
						|
                cur_fc->vf.nn_cco.sbandoffset = sbandoffset;
 | 
						|
                cur_fc->vf.nn_cco.self_rf_channel =
 | 
						|
                    g_phy_cpu_share_ctxt.rf_channel;
 | 
						|
                cur_fc->vf.nn_cco.self_rf_option =
 | 
						|
                    g_phy_cpu_share_ctxt.rf_option;
 | 
						|
                cur_fc->vf.nn_cco.resv1 = 0;
 | 
						|
                cur_fc->vf.nn_cco.version = SG_STANDARD_VERSION;
 | 
						|
            }
 | 
						|
        }
 | 
						|
#endif
 | 
						|
 | 
						|
#if SUPPORT_SOUTHERN_POWER_GRID
 | 
						|
        if (PLC_PROTO_TYPE_SPG  == proto) {
 | 
						|
            spg_frame_control_t *cur_fc = (spg_frame_control_t *)fc;
 | 
						|
            if (FC_DELIM_NNCCO == cur_fc->delimiter_type) {
 | 
						|
                uint64_t org_start_ntb;
 | 
						|
                uint64_t last_start_ntb;
 | 
						|
                uint64_t curr_start_ntb;
 | 
						|
                uint16_t curr_duration;
 | 
						|
                uint32_t bwth_end_flag;
 | 
						|
                uint32_t bwth_end_offset;
 | 
						|
                uint32_t bwth_start_offset;
 | 
						|
 | 
						|
                uint64_t start_ntb_h24 = cur_fc->vf.nn_cco_sw.start_ntb_h24;
 | 
						|
                org_start_ntb = (uint64_t)((start_ntb_h24 & 0xFFFFFF) << 32 | \
 | 
						|
                            cur_fc->vf.nn_cco_sw.start_ntb_l32);
 | 
						|
                uint64_t last_offseth = cur_fc->vf.nn_cco_sw.last_offseth;
 | 
						|
                last_start_ntb = org_start_ntb - \
 | 
						|
                    (uint64_t)((last_offseth & 0xff) << 8 | \
 | 
						|
                    cur_fc->vf.nn_cco_sw.last_offsetl);
 | 
						|
 | 
						|
                IOT_ASSERT(last_start_ntb <= org_start_ntb);
 | 
						|
 | 
						|
                curr_start_ntb = mac_sched_get_ntb64(NULL);
 | 
						|
                /* last pb is not over */
 | 
						|
                if (curr_start_ntb <= last_start_ntb) {
 | 
						|
                    bwth_end_flag = 0;
 | 
						|
 | 
						|
                    if ((last_start_ntb - curr_start_ntb) >=
 | 
						|
                        MAC_MS_TO_NTB((uint64_t)cur_fc->vf.nn_cco_sw.duration)) {
 | 
						|
                        curr_duration = 0;
 | 
						|
                    } else {
 | 
						|
                        curr_duration = cur_fc->vf.nn_cco_sw.duration -
 | 
						|
                            (uint16_t)MAC_NTB_TO_MS(last_start_ntb - curr_start_ntb);
 | 
						|
                    }
 | 
						|
                    bwth_end_offset = MAC_NTB_TO_MS(last_start_ntb - \
 | 
						|
                        curr_start_ntb) / 4;
 | 
						|
                    bwth_start_offset = MAC_NTB_TO_MS(org_start_ntb -\
 | 
						|
                        curr_start_ntb) / 4;
 | 
						|
 | 
						|
                }
 | 
						|
                /* last pb is over, but next pb is not start */
 | 
						|
                else if (curr_start_ntb <= org_start_ntb) {
 | 
						|
                    curr_duration = 0;
 | 
						|
                    bwth_end_flag = 1;
 | 
						|
                    curr_duration = cur_fc->vf.nn_cco_sw.duration;
 | 
						|
                    bwth_end_offset = MAC_NTB_TO_MS(curr_start_ntb - \
 | 
						|
                        last_start_ntb) / 4;
 | 
						|
                    bwth_start_offset = MAC_NTB_TO_MS(org_start_ntb -\
 | 
						|
                        curr_start_ntb) / 4;
 | 
						|
                }
 | 
						|
                /* next pb is starting */
 | 
						|
                else {
 | 
						|
                    bwth_end_flag = 1;
 | 
						|
                    bwth_start_offset = 0;
 | 
						|
                    bwth_end_offset = MAC_NTB_TO_MS(curr_start_ntb - \
 | 
						|
                        last_start_ntb) / 4;
 | 
						|
                    curr_duration = cur_fc->vf.nn_cco_sw.duration;
 | 
						|
                }
 | 
						|
 | 
						|
                cur_fc->vf.nn_cco.neighbor_network = \
 | 
						|
                    cur_fc->vf.nn_cco_sw.neighbor_network;
 | 
						|
                cur_fc->vf.nn_cco.resv0 = 0;
 | 
						|
                cur_fc->vf.nn_cco.conti_time = curr_duration / 40;
 | 
						|
                cur_fc->vf.nn_cco.resv1 = 0;
 | 
						|
                cur_fc->vf.nn_cco.bwth_end_flag = bwth_end_flag;
 | 
						|
                cur_fc->vf.nn_cco.resv4 = 0;
 | 
						|
                cur_fc->vf.nn_cco.bwth_end_shift = bwth_end_offset;
 | 
						|
                cur_fc->vf.nn_cco.bwth_start_shift = bwth_start_offset;
 | 
						|
                cur_fc->vf.nn_cco.resv = 0;
 | 
						|
                /* spg fc version default value = 1 */
 | 
						|
                cur_fc->vf.nn_cco.version = SPG_STANDARD_VERSION;
 | 
						|
                cur_fc->vf.nn_cco.self_rf_channel =
 | 
						|
                    g_phy_cpu_share_ctxt.rf_channel;
 | 
						|
                cur_fc->vf.nn_cco.self_rf_option =
 | 
						|
                    g_phy_cpu_share_ctxt.rf_option;
 | 
						|
            }
 | 
						|
        }
 | 
						|
#endif
 | 
						|
#else
 | 
						|
    (void)fc;
 | 
						|
#endif
 | 
						|
    return;
 | 
						|
}
 | 
						|
#endif
 | 
						|
 | 
						|
#if (ENA_WAR_NNCCO_FEAT || ENA_WAR_SPG_TX_OK || ENA_MAC_TX_START_INT)
 | 
						|
static void mac_rawdata_tx_start_isr_callback(void)
 | 
						|
{
 | 
						|
    uint32_t fc[4];
 | 
						|
    /* tx fc need update */
 | 
						|
    iot_raw_write_reg(RAW_REG_TYPE_MAC, CFG_TX_FC_NEED_UPD_ADDR, 0x1);
 | 
						|
    /* get original tx fc */
 | 
						|
    fc[0] = iot_raw_read_reg(RAW_REG_TYPE_MAC, CFG_TX_RAW_FC_0_ADDR);
 | 
						|
    fc[1] = iot_raw_read_reg(RAW_REG_TYPE_MAC, CFG_TX_RAW_FC_1_ADDR);
 | 
						|
    fc[2] = iot_raw_read_reg(RAW_REG_TYPE_MAC, CFG_TX_RAW_FC_2_ADDR);
 | 
						|
    fc[3] = iot_raw_read_reg(RAW_REG_TYPE_MAC, CFG_TX_RAW_FC_3_ADDR);
 | 
						|
 | 
						|
    uint32_t proto = PHY_PROTO_TYPE_GET();
 | 
						|
    uint8_t delimiter = \
 | 
						|
        (uint8_t)mac_get_delimi_from_fc(proto, fc);
 | 
						|
 | 
						|
    /* modify original tx fc */
 | 
						|
    if (FC_DELIM_BEACON == delimiter) {
 | 
						|
        //considering 40us delay between tx start and first sample on power line
 | 
						|
        mac_set_bcn_st(fc, (mac_sched_get_ntb(NULL) + \
 | 
						|
            MAC_SW_TX_BTS_DLY_NTB));
 | 
						|
    }
 | 
						|
 | 
						|
    /* for sack ext type, sync frame */
 | 
						|
    if (FC_DELIM_SACK == delimiter) {
 | 
						|
        mac_set_sync_st(fc, (mac_sched_get_ntb(NULL) + \
 | 
						|
            MAC_SW_TX_BTS_DLY_NTB));
 | 
						|
    }
 | 
						|
 | 
						|
#if ENA_WAR_NNCCO_FEAT
 | 
						|
    /* modify original tx fc */
 | 
						|
    mac_nncco_war_fill_fcinfo(fc);
 | 
						|
#endif
 | 
						|
 | 
						|
#if ENA_SYNC_DIFF_CCO_PPM
 | 
						|
    int32_t ppm_step = mac_get_clear_dbg_pkt_ppm_step(fc);
 | 
						|
    if (ppm_step) {
 | 
						|
        mac_modify_dbg_pkt_tx_ppm(ppm_step);
 | 
						|
    }
 | 
						|
#endif
 | 
						|
 | 
						|
    iot_raw_write_reg(RAW_REG_TYPE_MAC, CFG_TX_SW_FC_0_ADDR, fc[0]);
 | 
						|
    iot_raw_write_reg(RAW_REG_TYPE_MAC, CFG_TX_SW_FC_1_ADDR, fc[1]);
 | 
						|
    iot_raw_write_reg(RAW_REG_TYPE_MAC, CFG_TX_SW_FC_2_ADDR, fc[2]);
 | 
						|
    iot_raw_write_reg(RAW_REG_TYPE_MAC, CFG_TX_SW_FC_3_ADDR, fc[3]);
 | 
						|
 | 
						|
    iot_raw_write_reg(RAW_REG_TYPE_MAC, CFG_TX_FC_DATA0_ADDR, fc[0]);
 | 
						|
    iot_raw_write_reg(RAW_REG_TYPE_MAC, CFG_TX_FC_DATA1_ADDR, fc[1]);
 | 
						|
    iot_raw_write_reg(RAW_REG_TYPE_MAC, CFG_TX_FC_DATA2_ADDR, fc[2]);
 | 
						|
    iot_raw_write_reg(RAW_REG_TYPE_MAC, CFG_TX_FC_DATA3_ADDR, fc[3]);
 | 
						|
 | 
						|
    /* set sw fc valid */
 | 
						|
    iot_raw_write_reg(RAW_REG_TYPE_MAC, CFG_SW_FC_VALID_ADDR, 0x1);
 | 
						|
    /* clear interrupt status */
 | 
						|
    mac_rawdata_tx_start_isr_clr();
 | 
						|
}
 | 
						|
#endif
 | 
						|
 | 
						|
#if ENA_WAR_244
 | 
						|
#define RING_BASE_ADDR      (CFG_BUFFER_RING0_0_ADDR)
 | 
						|
#define RING_BASE_OFFSET    (CFG_BUFFER_RING1_0_ADDR - CFG_BUFFER_RING0_0_ADDR)
 | 
						|
#define RING_X_1_OFFSET     (CFG_BUFFER_RING0_1_ADDR - CFG_BUFFER_RING0_0_ADDR)
 | 
						|
#define RING_X_2_OFFSET     (CFG_BUFFER_RING0_2_ADDR - CFG_BUFFER_RING0_0_ADDR)
 | 
						|
#define RING_X_3_OFFSET     (CFG_BUFFER_RING0_3_ADDR - CFG_BUFFER_RING0_0_ADDR)
 | 
						|
 | 
						|
static uint32_t mac_rx_hw_isr_callback_cpu1(void)
 | 
						|
{
 | 
						|
#if HW_PLATFORM != HW_PLATFORM_SIMU
 | 
						|
    uint32_t rx_int_status = 0;
 | 
						|
    int32_t wid;
 | 
						|
    iot_pkt_t *p_buf;
 | 
						|
    uint8_t *tmp;
 | 
						|
    int8_t snr;
 | 
						|
    rx_mpdu_start *mpdu_st;
 | 
						|
    rx_mpdu_end *mpdu_ed;
 | 
						|
    uint8_t rx_pb_num;
 | 
						|
    rx_attention *att;
 | 
						|
#if SUPPORT_SOUTHERN_POWER_GRID
 | 
						|
    spg_frame_control_t *spg_fc;
 | 
						|
#endif
 | 
						|
#if SUPPORT_SMART_GRID
 | 
						|
    frame_control_t *sg_fc;
 | 
						|
#endif
 | 
						|
    uint8_t **buf_list;
 | 
						|
    uint32_t ring_sz;
 | 
						|
    uint32_t reg_value, reg_addr_base;
 | 
						|
 | 
						|
    rx_int_status = rx_ring_get_mpdu_int_status();
 | 
						|
 | 
						|
    /* call different ring's callback handler */
 | 
						|
    /* TODO: use pri order */
 | 
						|
    for (uint32_t i = 0; i < MAX_PLC_RX_RING_NUM; i++)
 | 
						|
    {
 | 
						|
        if ((0x1 << i) & rx_int_status) {
 | 
						|
            reg_value = RGF_RX_READ_REG(RING_BASE_ADDR
 | 
						|
                + (i * RING_BASE_OFFSET) + RING_X_2_OFFSET);
 | 
						|
            if (0 == REG_FIELD_GET(CFG_RING0_EN, reg_value)) {
 | 
						|
                continue;
 | 
						|
            }
 | 
						|
            reg_addr_base = RING_BASE_ADDR + (i * RING_BASE_OFFSET);
 | 
						|
            buf_list = (uint8_t **)RGF_RX_READ_REG(reg_addr_base);
 | 
						|
            wid = rx_ring_get_wr_idx_macro(i);
 | 
						|
            reg_value = RGF_RX_READ_REG(reg_addr_base + RING_X_1_OFFSET);
 | 
						|
            ring_sz = REG_FIELD_GET(CFG_RING0_BUF_NUM, reg_value);
 | 
						|
 | 
						|
            if (wid == 0) {
 | 
						|
                /* handle wrap around */
 | 
						|
                wid = ring_sz - 1;
 | 
						|
            }
 | 
						|
            else {
 | 
						|
                /* get the last wr id */
 | 
						|
                wid--;
 | 
						|
            }
 | 
						|
            if (!(wid < ring_sz)) {
 | 
						|
                // get assert file and line
 | 
						|
                assert_failed((unsigned char *)__FILE__, __LINE__);
 | 
						|
            }
 | 
						|
            p_buf = (iot_pkt_t*)(buf_list[wid] - sizeof(iot_pkt_t));
 | 
						|
            tmp = iot_pkt_data(p_buf);
 | 
						|
            mpdu_ed = (rx_mpdu_end *)(tmp + MPDU_END_OFFSET);
 | 
						|
            rx_pb_num = mpdu_ed->rx_buf_num;
 | 
						|
            if (rx_pb_num == 1) {
 | 
						|
                mpdu_st = (rx_mpdu_start *)(tmp + MPDU_START_OFFSET);
 | 
						|
                snr = mpdu_st->phy.avg_snr;
 | 
						|
            }
 | 
						|
            else if (rx_pb_num > 1) {
 | 
						|
                /* multi-pb case */
 | 
						|
                wid -= (rx_pb_num - 1);
 | 
						|
                if (wid >= 0) {
 | 
						|
                }
 | 
						|
                else {
 | 
						|
                    /* wid < 0*/
 | 
						|
                    wid = wid + ring_sz;
 | 
						|
                }
 | 
						|
                if (!(wid < ring_sz)) {
 | 
						|
                    // get assert file and line
 | 
						|
                    assert_failed((unsigned char *)__FILE__, __LINE__);
 | 
						|
                }
 | 
						|
 | 
						|
                p_buf = (iot_pkt_t*)(buf_list[wid] - sizeof(iot_pkt_t));
 | 
						|
                tmp = iot_pkt_data(p_buf);
 | 
						|
                mpdu_st = (rx_mpdu_start *)(tmp + MPDU_START_OFFSET);
 | 
						|
                snr = mpdu_st->phy.avg_snr;
 | 
						|
            }
 | 
						|
            else {
 | 
						|
                /* abnormal case */
 | 
						|
                break;
 | 
						|
            }
 | 
						|
            att = (rx_attention *)(tmp + RX_ATTENTION_OFFSET);
 | 
						|
            /* WAR:for bugid 244, fix sack result field always 0xf bug */
 | 
						|
#if SUPPORT_SOUTHERN_POWER_GRID
 | 
						|
            if (PLC_PROTO_TYPE_SPG == mpdu_st->rx_proto) {
 | 
						|
                spg_fc = &mpdu_st->fc.spg_fc;
 | 
						|
                g_sof_rx_info.fc[0] = *(uint32_t *)spg_fc;
 | 
						|
                g_sof_rx_info.fc[1] = *((uint32_t *)spg_fc + 1);
 | 
						|
                g_sof_rx_info.fc[2] = *((uint32_t *)spg_fc + 2);
 | 
						|
                g_sof_rx_info.fc[3] = *((uint32_t *)spg_fc + 3);
 | 
						|
            }
 | 
						|
            else
 | 
						|
#endif
 | 
						|
#if SUPPORT_SMART_GRID
 | 
						|
            if (PLC_PROTO_TYPE_SG == mpdu_st->rx_proto) {
 | 
						|
                sg_fc = &mpdu_st->fc.sg_fc;
 | 
						|
                g_sof_rx_info.fc[0] = *(uint32_t *)sg_fc;
 | 
						|
                g_sof_rx_info.fc[1] = *((uint32_t *)sg_fc + 1);
 | 
						|
                g_sof_rx_info.fc[2] = *((uint32_t *)sg_fc + 2);
 | 
						|
                g_sof_rx_info.fc[3] = *((uint32_t *)sg_fc + 3);
 | 
						|
            }
 | 
						|
            else
 | 
						|
#endif
 | 
						|
            {
 | 
						|
                //TODO: assert or don't do anything. don't del the case
 | 
						|
            }
 | 
						|
 | 
						|
            g_sof_rx_info.att = *att;
 | 
						|
            g_sof_rx_info.snr = snr;
 | 
						|
 | 
						|
            break;
 | 
						|
        }
 | 
						|
    }
 | 
						|
    return 0;
 | 
						|
#else
 | 
						|
    return 0;
 | 
						|
#endif
 | 
						|
}
 | 
						|
#endif
 | 
						|
 | 
						|
#if ENA_WAR_CTL
 | 
						|
static uint32_t mac_isr_handler_cpu1(uint32_t vector, iot_addrword_t data)
 | 
						|
{
 | 
						|
    (void)vector;
 | 
						|
    (void)data;
 | 
						|
 | 
						|
#if ENA_WAR_244
 | 
						|
    if (g_phy_cpu_share_ctxt.need_record_sof)
 | 
						|
    {
 | 
						|
        g_phy_cpu_share_ctxt.need_record_sof = 0;
 | 
						|
        mac_rx_hw_isr_callback_cpu1();
 | 
						|
    }
 | 
						|
#endif
 | 
						|
    return 0;
 | 
						|
}
 | 
						|
#endif
 | 
						|
 | 
						|
#if ENA_WAR_CTL
 | 
						|
static uint32_t mac_war_isr_handler_cpu1(uint32_t vector, iot_addrword_t data)
 | 
						|
{
 | 
						|
    uint32_t sack_int_status;
 | 
						|
    (void)vector;
 | 
						|
    (void)data;
 | 
						|
 | 
						|
    /* read pending sack tx interrupt status and do handler */
 | 
						|
    sack_int_status = RGF_RAW_READ_REG(CFG_RAW_INT_STATUS_ADDR);
 | 
						|
#if ENA_WAR_244
 | 
						|
    if (MAC_TX_SACK_INT_STATUS & sack_int_status) {
 | 
						|
        mac_rawdata_sack_tx_isr_callback();
 | 
						|
    }
 | 
						|
#endif
 | 
						|
 | 
						|
#if (ENA_WAR_NNCCO_FEAT || ENA_WAR_SPG_TX_OK || ENA_MAC_TX_START_INT)
 | 
						|
    if (MAC_TX_START_INT_STATUS & sack_int_status) {
 | 
						|
        mac_rawdata_tx_start_isr_callback();
 | 
						|
    }
 | 
						|
#endif
 | 
						|
 | 
						|
    return 0;
 | 
						|
}
 | 
						|
#endif
 | 
						|
 | 
						|
static void mac_isr_reset_cpu1(void)
 | 
						|
{
 | 
						|
#if ENA_WAR_CTL
 | 
						|
    /* CPU1 don't call disable interrupt & clean up pending interrupt */
 | 
						|
    return;
 | 
						|
#else
 | 
						|
    return;
 | 
						|
#endif
 | 
						|
}
 | 
						|
 | 
						|
void mac_isr_enable_cpu1(uint8_t id)
 | 
						|
{
 | 
						|
    uint32_t int_mask;
 | 
						|
 | 
						|
    if (id <= MAC_ISR_MAX_ID) {
 | 
						|
        int_mask = 1 << (CFG_INT_ENABLE_MASK_OFFSET + id);
 | 
						|
        if (!(p_mac_isr_ctx_cpu1->isr_mask & int_mask)) {
 | 
						|
            p_mac_isr_ctx_cpu1->isr_mask |= int_mask;
 | 
						|
            RGF_MAC_WRITE_REG(CFG_INT_ENA_MASK_ADDR, \
 | 
						|
                p_mac_isr_ctx_cpu1->isr_mask);
 | 
						|
        }
 | 
						|
    }
 | 
						|
}
 | 
						|
 | 
						|
void mac_isr_disable_cpu1(uint8_t id)
 | 
						|
{
 | 
						|
    uint32_t int_mask;
 | 
						|
 | 
						|
    if (id <= MAC_ISR_MAX_ID) {
 | 
						|
        int_mask = 1 << (CFG_INT_ENABLE_MASK_OFFSET + id);
 | 
						|
        if (p_mac_isr_ctx_cpu1->isr_mask & int_mask) {
 | 
						|
            p_mac_isr_ctx_cpu1->isr_mask &= ~int_mask;
 | 
						|
            RGF_MAC_WRITE_REG(CFG_INT_ENA_MASK_ADDR, p_mac_isr_ctx_cpu1->isr_mask);
 | 
						|
        }
 | 
						|
    }
 | 
						|
}
 | 
						|
 | 
						|
void mac_isr_start_cpu1(void)
 | 
						|
{
 | 
						|
#if ENA_WAR_CTL
 | 
						|
    iot_interrupt_unmask(p_mac_isr_ctx_cpu1->isr_0_h);
 | 
						|
    iot_interrupt_unmask(p_mac_isr_ctx_cpu1->isr_3_h);
 | 
						|
#endif
 | 
						|
}
 | 
						|
 | 
						|
void mac_isr_stop_cpu1(void)
 | 
						|
{
 | 
						|
#if ENA_WAR_CTL
 | 
						|
    iot_interrupt_mask(p_mac_isr_ctx_cpu1->isr_0_h);
 | 
						|
    iot_interrupt_mask(p_mac_isr_ctx_cpu1->isr_3_h);
 | 
						|
#endif
 | 
						|
}
 | 
						|
 | 
						|
void mac_isr_init_cpu1(void)
 | 
						|
{
 | 
						|
    iot_memset(p_mac_isr_ctx_cpu1, 0, sizeof(*p_mac_isr_ctx_cpu1));
 | 
						|
 | 
						|
    p_mac_isr_ctx_cpu1->dsr_callback = NULL;
 | 
						|
 | 
						|
    mac_isr_reset_cpu1();
 | 
						|
 | 
						|
#if ENA_WAR_CTL
 | 
						|
    /* allocate soc irq resource */
 | 
						|
    p_mac_isr_ctx_cpu1->isr_0_h = iot_interrupt_create(HAL_VECTOR_MAC_0,
 | 
						|
        HAL_INTR_PRI_7, (iot_addrword_t)NULL, mac_isr_handler_cpu1);
 | 
						|
#endif
 | 
						|
 | 
						|
#if ENA_WAR_CTL
 | 
						|
    p_mac_isr_ctx_cpu1->isr_3_h = iot_interrupt_create(HAL_VECTOR_MAC_3,
 | 
						|
        HAL_INTR_PRI_7, (iot_addrword_t)NULL, mac_war_isr_handler_cpu1);
 | 
						|
#endif
 | 
						|
 | 
						|
    /* set interrupt to cpu1 */
 | 
						|
    iot_interrupt_set_cpu(p_mac_isr_ctx_cpu1->isr_0_h, HAL_INTR_CPU_1);
 | 
						|
    iot_interrupt_set_cpu(p_mac_isr_ctx_cpu1->isr_3_h, HAL_INTR_CPU_1);
 | 
						|
 | 
						|
    /* attach soc irq resource */
 | 
						|
    iot_interrupt_attach(p_mac_isr_ctx_cpu1->isr_0_h);
 | 
						|
    iot_interrupt_attach(p_mac_isr_ctx_cpu1->isr_3_h);
 | 
						|
}
 |