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