/**************************************************************************** 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" #include "hw_reg_api.h" #include "iot_mem.h" /* plc public api includes */ #include "plc_fr.h" #include "plc_const.h" #include "iot_bitops.h" /* driver includes */ #include "iot_irq.h" #include "iot_gpio_api.h" #include "iot_board_api.h" #include "pin_rf.h" #include "mpdu_header.h" #include "mac_sys_reg.h" #include "plc_protocol.h" #include "mac_raw_reg.h" #include "mac_rawdata_hw.h" #include "phy_reg.h" #include "phy_bb.h" #include "phy_phase.h" #include "phy_isr.h" #include "ahb.h" #include "cpl_types_api.h" #include "phy_api_cpu1.h" #include "hw_phy_api.h" #if ENA_WAR_440 #include "mac_hwq_reg.h" #include "command_list.h" #include "mac_hwq_mgr.h" #include "mac_rx_buf_ring.h" #endif #include "mac_txq_hw.h" #if ENA_SW_SYNC_PPM_WAR #include "phy_multi_ppm.h" #endif #include "mac_cmn_hw.h" phy_cpu_share_ctxt_t g_phy_cpu_share_ctxt = {0}; void phy_get_original_fc(uint32_t *fc) { *(fc + 0) = RGF_RAW_READ_REG(CFG_TX_RAW_FC_0_ADDR); *(fc + 1) = RGF_RAW_READ_REG(CFG_TX_RAW_FC_1_ADDR); *(fc + 2) = RGF_RAW_READ_REG(CFG_TX_RAW_FC_2_ADDR); *(fc + 3) = RGF_RAW_READ_REG(CFG_TX_RAW_FC_3_ADDR); } void phy_get_after_war_fc(uint32_t *fc) { *(fc + 0) = RGF_RAW_READ_REG(CFG_TX_FC_DATA0_ADDR); *(fc + 1) = RGF_RAW_READ_REG(CFG_TX_FC_DATA1_ADDR); *(fc + 2) = RGF_RAW_READ_REG(CFG_TX_FC_DATA2_ADDR); *(fc + 3) = RGF_RAW_READ_REG(CFG_TX_FC_DATA3_ADDR); } void phy_rawdata_war_phy_pbsz(void) { #if HW_PLATFORM >= HW_PLATFORM_FPGA uint32_t fc[4]; uint32_t delimiter_type = 0; uint32_t proto = PHY_PROTO_TYPE_GET(); tx_fc_msg_t msg; iot_memset(&msg, 0, sizeof(tx_fc_msg_t)); /* get original tx fc */ phy_get_original_fc(fc); delimiter_type = mac_get_delimi_from_fc(proto, fc); if (FC_DELIM_BEACON == delimiter_type || \ FC_DELIM_SOF == delimiter_type) { mac_get_tx_msg_from_fc(proto, delimiter_type, fc, &msg); phy_rawdata_bb_set_tmi(proto, msg.tmi, msg.ext_tmi); } #endif } //TODO: this function may be in mac layer, then phy layer code callback it #if ENA_WAR_440 static volatile uint64_t g_pre_bcn_end_ntb = 0; void phy_war_tx_fl_overflow(void) { hw_sched_cmd_t *cmd; uint32_t cur_ntb, bcn_start_ntb; uint32_t fl = 0; uint32_t fc[4]; uint64_t slot_end_ntb = 0, mpdu_end_ntb = 0, tmp; #if SUPPORT_SMART_GRID frame_control_t *sg_fc; #endif do { /* first get current ntb */ cur_ntb = RGF_MAC_READ_REG(CFG_RD_NTB_ADDR); cmd = (hw_sched_cmd_t *)RGF_HWQ_READ_REG(CFG_SCH_CUR_PTR_ADDR); bcn_start_ntb = RGF_MAC_READ_REG(CFG_BCN_START_NTB_ADDR); fc[0] = RGF_RAW_READ_REG(CFG_TX_FC_DATA0_ADDR); fc[1] = RGF_RAW_READ_REG(CFG_TX_FC_DATA1_ADDR); fc[2] = RGF_RAW_READ_REG(CFG_TX_FC_DATA2_ADDR); fc[3] = RGF_RAW_READ_REG(CFG_TX_FC_DATA3_ADDR); //TODO: will check all sch cmd list. only endtime sch cmd now. tmp = cmd->t_info.e.end_t;//unit: 1ms //slot_end_ntb = bcn_start_ntb + (slot_end * 1000 * 25) slot_end_ntb = (tmp << 14) + (tmp << 13) + (tmp << 8) \ + (tmp << 7) + (tmp << 5) + (tmp << 3) + bcn_start_ntb; //get frame len, unit:us #if SUPPORT_SMART_GRID sg_fc = (frame_control_t *)fc; if (FC_DELIM_SOF == sg_fc->delimiter_type) { /* TODO: this way not yet test. if start this war, need test!! */ /* get the real hw band id * 1. get hwq id. * 2. get desc. */ /* 1.get hwq id */ mac_set_debug_reg(0x50); uint32_t reg = mac_rx_get_debug_reg(); uint32_t hwq_id = iot_bitops_ffs(reg & 0x1f) - 1; IOT_ASSERT(hwq_id >= 0 && hwq_id <= 4) /* 2.get desc */ uint32_t addr_step = CFG_RO_DCU1_CUR_PTR_ADDR - CFG_RO_DCU0_CUR_PTR_ADDR; uint32_t desc_addr = CFG_RO_DCU0_CUR_PTR_ADDR + hwq_id * addr_step; tx_mpdu_start *desc = (tx_mpdu_start *)desc_addr; uint32_t hw_band_id = desc->sg_bandsel; /* sof packet frame len = preamble + fc + payload + sof.frame_len*/ /* broadcast: sof.frame_len = payload + cifs */ /* unicast: sof.frame_len = payload + rifs + sack_frame_len + cifs*/ /* for sof, the sof.frame_len has been filled in by sw/hw, */ /* and function mac_rx_get_delim() returns the */ /* (preamble + fc) len in different rate mod */ //TODO: maybe not rate0 always! fl = (sg_fc->vf.sof.frame_len * 10) + \ mac_rx_get_delim(0, hw_band_id); } else { //TODO: maybe need check beacon/nncco/sack break; } #endif #if SUPPORT_SOUTHERN_POWER_GRID //TODO: add code #endif #if SUPPORT_GREEN_PHY //TODO: add code #endif mpdu_end_ntb = cur_ntb; //check bcn slot update if (cur_ntb < bcn_start_ntb) { /* cur ntb < bcn start reg update ntb < new bcn start ntb */ if ((cur_ntb < g_phy_cpu_share_ctxt.bcn_start_update_ntb) && \ (g_phy_cpu_share_ctxt.bcn_start_update_ntb < bcn_start_ntb)) { /* cur ntb around */ mpdu_end_ntb <<= 32; } else { /* the bcn slot has been updated, use old slot end time */ slot_end_ntb = g_pre_bcn_end_ntb; } } //mpdu_end_ntb = cur_ntb + fl * 25 tmp = fl; mpdu_end_ntb += (tmp << 4) + (tmp << 3) + tmp; if (mpdu_end_ntb > slot_end_ntb) { g_phy_cpu_share_ctxt.tx_underflow_cnt++; mac_cfg_phy_tx_underflow_force(); } } while (0); g_pre_bcn_end_ntb = slot_end_ntb; } #endif /* TODO: use macro distinguish WARID, as WAR_BUGID_244 in iot_config.h */ uint32_t phy_get_hw_interrupt_type_cpu1(void) { #if HW_PLATFORM >= HW_PLATFORM_FPGA uint32_t irq_type_reg = 0; uint32_t irq_type = 0; /* get int 3 mask */ irq_type_reg = PHY_READ_REG(CFG_BB_INT_MASK_3_ADDR); if (irq_type_reg & PHY_RECV_FD_FC_OK) { irq_type |= INTR_TYPE_PHY_FD_FC_OK; } if (irq_type_reg & PHY_RECV_FD_FC_FAIL) { irq_type |= INTR_TYPE_PHY_FD_FC_FAIL; } if (irq_type_reg & PHY_TX_FD_TX_DONE) { irq_type |= INTR_TYPE_PHY_TX_FD_TX_DONE;; } if (irq_type_reg & PHY_FD_TX_ABORT) { irq_type |= INTR_TYPE_PHY_FD_TX_ABORT;; } #if ENA_WAR_244 if (irq_type_reg & PHY_FD_TX_STUCK) { irq_type |= INTR_TYPE_PHY_FD_TX_STUCK;; } if (irq_type_reg & PHY_TX_TD_START) { irq_type |= INTR_TYPE_PHY_TX_TD_START;; } #endif #if ENA_WAR_NSG_EXTMI || MAC_SYM_NUM_FIX if (irq_type_reg & PHY_RECV_FD_CH_EST_DONE) { irq_type |= INTR_TYPE_PHY_FD_CH_EST_DONE; } #endif/* ENA_WAR_NSG_EXTMI || MAC_SYM_NUM_FIX */ #if ENA_WAR_NSG_EXTMI if (irq_type_reg & PHY_RECV_FD_PB_OK) { irq_type |= INTR_TYPE_PHY_FD_PB_OK; } if (irq_type_reg & PHY_RECV_FD_PB_FAIL) { irq_type |= INTR_TYPE_PHY_FD_PB_FAIL; } if (irq_type_reg & PHY_RECV_FC_RAW_RECEIVE) { irq_type |= INTR_TYPE_PHY_FC_RAW_RECEIVE; } #endif/* ENA_WAR_NSG_EXTMI */ #if (ENA_WAR_NSG_EXTMI || ENA_SW_SYNC_PPM_WAR) if (irq_type_reg & PHY_TX_FD_INSERT_PREAM_DONE) { irq_type |= INTR_TYPE_PHY_INSERT_PREAM_DONE; } #endif if (irq_type_reg & PHY_TX_TD_FC_DONE) { irq_type |= INTR_TYPE_PHY_TX_TD_FC_DONE; } #if MAC_SYM_NUM_FIX || MAC_TIMESTAMPING || ENA_CCO_RX_THR_PHASE_CHANGE if (irq_type_reg & PHY_RECV_FD_PLD_OK) { irq_type |= INTR_TYPE_PHY_FD_PLD_OK; } if (irq_type_reg & PHY_RECV_FD_PLD_FAIL) { irq_type |= INTR_TYPE_PHY_FD_PLD_FAIL; } #endif return irq_type; #else return 0; #endif } void phy_disable_hw_interrupt_cpu1(uint32_t irq_type) { #if HW_PLATFORM >= HW_PLATFORM_FPGA uint32_t reg_int = 0; /* disable int 3 */ reg_int = PHY_READ_REG(CFG_BB_INT_EN_3_ADDR); if (irq_type & INTR_TYPE_PHY_FD_FC_OK) { reg_int &= (~PHY_RECV_FD_FC_OK); } if (irq_type & INTR_TYPE_PHY_FD_FC_FAIL) { reg_int &= (~PHY_RECV_FD_FC_FAIL); } if (irq_type & INTR_TYPE_PHY_TX_FD_TX_DONE) { reg_int &= (~PHY_TX_FD_TX_DONE); } if (irq_type & INTR_TYPE_PHY_FD_TX_ABORT) { reg_int &= (~PHY_FD_TX_ABORT); } #if ENA_WAR_244 if (irq_type & INTR_TYPE_PHY_FD_TX_STUCK) { reg_int &= (~PHY_FD_TX_STUCK); } if (irq_type & INTR_TYPE_PHY_TX_TD_START) { reg_int &= (~PHY_TX_TD_START); } #endif #if ENA_WAR_NSG_EXTMI || MAC_SYM_NUM_FIX if (irq_type & INTR_TYPE_PHY_FD_CH_EST_DONE) { reg_int &= (~PHY_RECV_FD_CH_EST_DONE); } #endif/* ENA_WAR_NSG_EXTMI || MAC_SYM_NUM_FIX */ #if ENA_WAR_NSG_EXTMI if (irq_type & INTR_TYPE_PHY_FD_PB_OK) { reg_int &= (~PHY_RECV_FD_PB_OK); } if (irq_type & INTR_TYPE_PHY_FD_PB_FAIL) { reg_int &= (~PHY_RECV_FD_PB_FAIL); } if (irq_type & INTR_TYPE_PHY_FC_RAW_RECEIVE) { reg_int &= (~PHY_RECV_FC_RAW_RECEIVE); } #endif/* ENA_WAR_NSG_EXTMI */ #if (ENA_WAR_NSG_EXTMI || ENA_SW_SYNC_PPM_WAR) if (irq_type & INTR_TYPE_PHY_INSERT_PREAM_DONE) { reg_int &= (~PHY_TX_FD_INSERT_PREAM_DONE); } #endif if (irq_type & INTR_TYPE_PHY_TX_TD_FC_DONE) { reg_int &= (~PHY_TX_TD_FC_DONE); } #if MAC_SYM_NUM_FIX || MAC_TIMESTAMPING || ENA_CCO_RX_THR_PHASE_CHANGE if (irq_type & INTR_TYPE_PHY_FD_PLD_OK) { reg_int &= (~PHY_RECV_FD_PLD_OK); } if (irq_type & INTR_TYPE_PHY_FD_PLD_FAIL) { reg_int &= (~PHY_RECV_FD_PLD_FAIL); } #endif PHY_WRITE_REG(CFG_BB_INT_EN_3_ADDR, reg_int); #else (void)irq_type; #endif return; } void phy_clear_hw_interrupt_cpu1(uint32_t irq_type) { #if HW_PLATFORM >= HW_PLATFORM_FPGA uint32_t reg_int = 0; /* clear int 3 */ reg_int = PHY_READ_REG(CFG_BB_INT_CLR_3_ADDR); if (irq_type & INTR_TYPE_PHY_FD_FC_OK) { reg_int |= PHY_RECV_FD_FC_OK; } if (irq_type & INTR_TYPE_PHY_FD_FC_FAIL) { reg_int |= PHY_RECV_FD_FC_FAIL; } if (irq_type & INTR_TYPE_PHY_TX_FD_TX_DONE) { reg_int |= PHY_TX_FD_TX_DONE; } if (irq_type & INTR_TYPE_PHY_FD_TX_ABORT) { reg_int |= PHY_FD_TX_ABORT; } #if ENA_WAR_244 if (irq_type & INTR_TYPE_PHY_FD_TX_STUCK) { reg_int |= PHY_FD_TX_STUCK; } if (irq_type & INTR_TYPE_PHY_TX_TD_START) { reg_int |= PHY_TX_TD_START; } #endif #if ENA_WAR_NSG_EXTMI || MAC_SYM_NUM_FIX if (irq_type & INTR_TYPE_PHY_FD_CH_EST_DONE) { reg_int |= PHY_RECV_FD_CH_EST_DONE; } #endif/* ENA_WAR_NSG_EXTMI || MAC_SYM_NUM_FIX */ #if ENA_WAR_NSG_EXTMI if (irq_type & INTR_TYPE_PHY_FD_PB_OK) { reg_int |= PHY_RECV_FD_PB_OK; } if (irq_type & INTR_TYPE_PHY_FD_PB_FAIL) { reg_int |= PHY_RECV_FD_PB_FAIL; } if (irq_type & INTR_TYPE_PHY_FC_RAW_RECEIVE) { reg_int |= PHY_RECV_FC_RAW_RECEIVE; } #endif/* ENA_WAR_NSG_EXTMI */ #if (ENA_WAR_NSG_EXTMI || ENA_SW_SYNC_PPM_WAR) if (irq_type & INTR_TYPE_PHY_INSERT_PREAM_DONE) { reg_int |= PHY_TX_FD_INSERT_PREAM_DONE; } #endif if (irq_type & INTR_TYPE_PHY_TX_TD_FC_DONE) { reg_int |= PHY_TX_TD_FC_DONE; } #if MAC_SYM_NUM_FIX || MAC_TIMESTAMPING || ENA_CCO_RX_THR_PHASE_CHANGE if (irq_type & INTR_TYPE_PHY_FD_PLD_OK) { reg_int |=PHY_RECV_FD_PLD_OK; } if (irq_type & INTR_TYPE_PHY_FD_PLD_FAIL) { reg_int |= PHY_RECV_FD_PLD_FAIL; } #endif PHY_WRITE_REG(CFG_BB_INT_CLR_3_ADDR, reg_int); #else (void)irq_type; #endif } void phy_enable_hw_interrupt_cpu1(uint32_t irq_type) { #if HW_PLATFORM >= HW_PLATFORM_FPGA uint32_t reg_int = 0; /* enable int 3 */ reg_int = PHY_READ_REG(CFG_BB_INT_EN_3_ADDR); if (irq_type & INTR_TYPE_PHY_FD_FC_OK) { reg_int |= PHY_RECV_FD_FC_OK; } if (irq_type & INTR_TYPE_PHY_FD_FC_FAIL) { reg_int |= PHY_RECV_FD_FC_FAIL; } if (irq_type & INTR_TYPE_PHY_TX_FD_TX_DONE) { reg_int |= PHY_TX_FD_TX_DONE; } if (irq_type & INTR_TYPE_PHY_FD_TX_ABORT) { reg_int |= PHY_FD_TX_ABORT; } #if ENA_WAR_244 if (irq_type & INTR_TYPE_PHY_FD_TX_STUCK) { reg_int |= PHY_FD_TX_STUCK; } if (irq_type & INTR_TYPE_PHY_TX_TD_START) { reg_int |= PHY_TX_TD_START; } #endif #if ENA_WAR_NSG_EXTMI || MAC_SYM_NUM_FIX if (irq_type & INTR_TYPE_PHY_FD_CH_EST_DONE) { reg_int |= PHY_RECV_FD_CH_EST_DONE; } #endif/* ENA_WAR_NSG_EXTMI || MAC_SYM_NUM_FIX */ #if ENA_WAR_NSG_EXTMI if (irq_type & INTR_TYPE_PHY_FD_PB_OK) { reg_int |= PHY_RECV_FD_PB_OK; } if (irq_type & INTR_TYPE_PHY_FD_PB_FAIL) { reg_int |= PHY_RECV_FD_PB_FAIL; } if (irq_type & INTR_TYPE_PHY_FC_RAW_RECEIVE) { reg_int |= PHY_RECV_FC_RAW_RECEIVE; } #endif/* ENA_WAR_NSG_EXTMI */ #if (ENA_WAR_NSG_EXTMI || ENA_SW_SYNC_PPM_WAR) if (irq_type & INTR_TYPE_PHY_INSERT_PREAM_DONE) { reg_int |= PHY_TX_FD_INSERT_PREAM_DONE; } #endif if (irq_type & INTR_TYPE_PHY_TX_TD_FC_DONE) { reg_int |= PHY_TX_TD_FC_DONE; } #if MAC_SYM_NUM_FIX || MAC_TIMESTAMPING || ENA_CCO_RX_THR_PHASE_CHANGE if (irq_type & INTR_TYPE_PHY_FD_PLD_OK) { reg_int |=PHY_RECV_FD_PLD_OK; } if (irq_type & INTR_TYPE_PHY_FD_PLD_FAIL) { reg_int |= PHY_RECV_FD_PLD_FAIL; } #endif PHY_WRITE_REG(CFG_BB_INT_EN_3_ADDR, reg_int); #else (void)irq_type; #endif return; } uint32_t phy_get_hw_interrupt_status_cpu1(uint32_t irq_type) { #if HW_PLATFORM >= HW_PLATFORM_FPGA uint32_t irq_type_reg = 0; /* get int 3 mask */ irq_type_reg = PHY_READ_REG(CFG_BB_INT_EN_3_ADDR); if (irq_type_reg & CFG_BB_INT_EN_3_ADDR) { //enable return 1; } else { //disable return 0; } #else return 0; #endif } uint32_t phy_interrupt_handler_cpu1(uint32_t vector, iot_addrword_t data) { #if HW_PLATFORM >= HW_PLATFORM_FPGA rx_fc_msg_t msg; uint32_t proto = PHY_PROTO_TYPE_GET(); uint32_t bb_fc[4] = {0}; uint8_t delimeter = 0xFF; (void)delimeter; (void)vector; (void)data; #if WAR_TIMEOUT_TX_ABORT //TODO:to make sure trigger phy isr, move to cpu0 if((g_phy_cpu_share_ctxt.timeout_tx_abort_flag == false) || \ (!phy_get_hw_interrupt_status_cpu1(INTR_TYPE_PHY_FD_TX_ABORT))) { phy_enable_hw_interrupt_cpu1(INTR_TYPE_PHY_FD_TX_ABORT); } #endif uint32_t isr_flag = 0; uint32_t ul_fdfc = PHY_READ_REG(CFG_BB_RX_FC_CFG_3_ADDR); isr_flag = phy_get_hw_interrupt_type_cpu1(); /* disable interrupt mask */ //phy_disable_hw_interrupt_cpu1(isr_flag); if (isr_flag & INTR_TYPE_PHY_INSERT_PREAM_DONE) { /* get current tx fc */ phy_get_after_war_fc(bb_fc); #if ENA_WAR_NSG_EXTMI /* spg tx */ uint8_t dt, fc_tmp; dt = (uint8_t)mac_get_delimi_from_fc(PLC_PROTO_TYPE_SPG, bb_fc); if (FC_DELIM_SOF == dt) { fc_tmp = (uint8_t)bb_fc[3]; bb_fc[3] = (bb_fc[3] & 0xfffffff0) |\ (((fc_tmp >> 4) & 0xf) | ((fc_tmp << 4) & 0xf0)); RGF_RAW_WRITE_REG(CFG_TX_SW_FC_0_ADDR, bb_fc[0]); RGF_RAW_WRITE_REG(CFG_TX_SW_FC_1_ADDR, bb_fc[1]); RGF_RAW_WRITE_REG(CFG_TX_SW_FC_2_ADDR, bb_fc[2]); RGF_RAW_WRITE_REG(CFG_TX_SW_FC_3_ADDR, bb_fc[3]); RGF_RAW_WRITE_REG(CFG_SW_FC_VALID_ADDR, 1); PHY_WRITE_REG(CFG_BB_RAW_DATA_MODE_CTRL_ADDR, 1); } #endif /* fix tx ppm */ #if ENA_SW_SYNC_PPM_WAR phy_ppm_status_ctxt_t *ppm_ctxt = phy_multi_sync_get_ppm_status(); mac_get_rx_frm_msg_from_fc(proto, bb_fc, &msg); phy_multi_sync_apply_bb_ppm(ppm_ctxt, msg.nid, BB_PPM_TX_ONLY); #endif } #if ENA_WAR_NSG_EXTMI || MAC_SYM_NUM_FIX /* spg rx */ if (isr_flag & INTR_TYPE_PHY_FD_CH_EST_DONE) { #if MAC_SYM_NUM_FIX if (!g_phy_cpu_share_ctxt.sym_num_fix_dis) { uint32_t tmp = RGF_MAC_READ_REG(CFG_RD_MACPHY_INTF_0_ADDR); g_phy_cpu_share_ctxt.multiband = REG_FIELD_GET(PHY_RX_BANDSEL, tmp); } #endif/* MAC_SYM_NUM_FIX */ #if ENA_WAR_NSG_EXTMI PHY_WRITE_REG(CFG_BB_RAW_DATA_MODE_CTRL_ADDR, 1); #endif/* ENA_WAR_NSG_EXTMI */ } #endif/* ENA_WAR_NSG_EXTMI || MAC_SYM_NUM_FIX */ #if ENA_WAR_NSG_EXTMI if (isr_flag & INTR_TYPE_PHY_FC_RAW_RECEIVE) { uint8_t rx_dt, rx_fc_tmp; uint32_t bb_rx_fc[4], tmp; bb_rx_fc[0] = PHY_READ_REG(CFG_BB_RX_FC_RAW_0_ADDR); rx_dt = (uint8_t)mac_get_delimi_from_fc(PLC_PROTO_TYPE_SPG, bb_rx_fc); if (rx_dt == FC_DELIM_SOF) { bb_rx_fc[1] = PHY_READ_REG(CFG_BB_RX_FC_RAW_1_ADDR); bb_rx_fc[2] = PHY_READ_REG(CFG_BB_RX_FC_RAW_2_ADDR); bb_rx_fc[3] = PHY_READ_REG(CFG_BB_RX_FC_RAW_3_ADDR); rx_fc_tmp = (uint8_t)bb_rx_fc[3]; rx_fc_tmp = ((rx_fc_tmp >> 4) & 0xf) | ((rx_fc_tmp << 4) & 0xf0); PHY_WRITE_REG(CFG_BB_RX_FC_CFG_0_ADDR, bb_rx_fc[0]); PHY_WRITE_REG(CFG_BB_RX_FC_CFG_1_ADDR, bb_rx_fc[1]); PHY_WRITE_REG(CFG_BB_RX_FC_CFG_2_ADDR, bb_rx_fc[2]); tmp = PHY_READ_REG(CFG_BB_RX_FC_CFG_3_ADDR); REG_FIELD_SET(SW_RX_FC_NOW_CFG_WORD3, tmp, rx_fc_tmp); REG_FIELD_SET(SW_RX_FC_NOW_CFG_VLD, tmp, 1); PHY_WRITE_REG(CFG_BB_RX_FC_CFG_3_ADDR, tmp); } else { bb_rx_fc[1] = PHY_READ_REG(CFG_BB_RX_FC_RAW_1_ADDR); bb_rx_fc[2] = PHY_READ_REG(CFG_BB_RX_FC_RAW_2_ADDR); bb_rx_fc[3] = PHY_READ_REG(CFG_BB_RX_FC_RAW_3_ADDR); PHY_WRITE_REG(CFG_BB_RX_FC_CFG_0_ADDR, bb_rx_fc[0]); PHY_WRITE_REG(CFG_BB_RX_FC_CFG_1_ADDR, bb_rx_fc[1]); PHY_WRITE_REG(CFG_BB_RX_FC_CFG_2_ADDR, bb_rx_fc[2]); tmp = PHY_READ_REG(CFG_BB_RX_FC_CFG_3_ADDR); REG_FIELD_SET(SW_RX_FC_NOW_CFG_WORD3, tmp, (uint8_t)bb_rx_fc[3]); REG_FIELD_SET(SW_RX_FC_NOW_CFG_VLD, tmp, 1); PHY_WRITE_REG(CFG_BB_RX_FC_CFG_3_ADDR, tmp); PHY_WRITE_REG(CFG_BB_RAW_DATA_MODE_CTRL_ADDR, 0); } } if ((isr_flag & INTR_TYPE_PHY_FD_PB_OK) || (isr_flag & INTR_TYPE_PHY_FD_PB_FAIL)) { PHY_WRITE_REG(CFG_BB_RAW_DATA_MODE_CTRL_ADDR, 0); } #endif/* ENA_WAR_NSG_EXTMI */ if(isr_flag & INTR_TYPE_PHY_FD_FC_OK \ || isr_flag & INTR_TYPE_PHY_FD_FC_FAIL) { ul_fdfc |= ((uint32_t)(1 << SW_RX_FC_NOW_CFG_VLD_OFFSET)); PHY_WRITE_REG(CFG_BB_RX_FC_CFG_3_ADDR, ul_fdfc); /* when recv fc,if my sof,enable rawdata mode. */ if (isr_flag & INTR_TYPE_PHY_FD_FC_OK) { #if MAC_SYM_NUM_FIX if (!g_phy_cpu_share_ctxt.sym_num_fix_dis) { bb_fc[0] = PHY_READ_REG(CFG_BB_RX_FC_RAW_0_ADDR); bb_fc[1] = PHY_READ_REG(CFG_BB_RX_FC_RAW_1_ADDR); bb_fc[2] = PHY_READ_REG(CFG_BB_RX_FC_RAW_2_ADDR); bb_fc[3] = PHY_READ_REG(CFG_BB_RX_FC_RAW_3_ADDR); mac_get_rx_frm_msg_from_fc(proto, bb_fc, &msg); if (((msg.delimiter == FC_DELIM_SOF) || (msg.delimiter == FC_DELIM_BEACON))) { uint16_t total_sym_num, sym_num; uint16_t *p_symppb = (uint16_t *)g_phy_cpu_share_ctxt.p_g_symppb; uint8_t tmi = msg.tmi; if (msg.delimiter == FC_DELIM_SOF) { tmi += msg.tmi_ext; } sym_num = *(p_symppb + g_phy_cpu_share_ctxt.multiband * SG_OFDM_MAX + tmi); if (sym_num != msg.numsym) { if (msg.delimiter == FC_DELIM_SOF) { total_sym_num = sym_num * msg.pb_num; } else { total_sym_num = sym_num; } uint32_t tmp = PHY_READ_REG(CFG_BB_CONFIG_FC_PARSE_0_ADDR); REG_FIELD_SET(SW_CONFIG_PB_SYMB_NUM, tmp, sym_num); REG_FIELD_SET(SW_CONFIG_PLD_SYMB_NUM, tmp, total_sym_num); REG_FIELD_SET(SW_CONFIG_PB_SYMB_NUM_EN, tmp, 1); REG_FIELD_SET(SW_CONFIG_PLD_SYMB_NUM_EN, tmp, 1); PHY_WRITE_REG(CFG_BB_CONFIG_FC_PARSE_0_ADDR, tmp); } } } #endif /* MAC_SYM_NUM_FIX */ #if MAC_WAR_244_TIMESTAMPING g_phy_cpu_share_ctxt._3_rx_fc_ok_ts = \ RGF_MAC_READ_REG(CFG_RD_NTB_ADDR); #endif iot_memset(&msg, 0, sizeof(rx_fc_msg_t)); bb_fc[0] = PHY_READ_REG(CFG_BB_RX_FC_RAW_0_ADDR); bb_fc[1] = PHY_READ_REG(CFG_BB_RX_FC_RAW_1_ADDR); bb_fc[2] = PHY_READ_REG(CFG_BB_RX_FC_RAW_2_ADDR); bb_fc[3] = PHY_READ_REG(CFG_BB_RX_FC_RAW_3_ADDR); delimeter = (uint8_t)mac_get_delimi_from_fc(proto, bb_fc); mac_get_rx_frm_msg_from_fc(proto, bb_fc, &msg); if (FC_DELIM_SOF == delimeter || FC_DELIM_BEACON == delimeter) { #if ENA_CCO_RX_THR_PHASE_CHANGE phy_set_rx_abort_rx_phase_force_from_isr(true, true, phy_get_hw_phy_rx_phase_sel()); #endif #if ENA_SW_SYNC_PPM_WAR #if ENA_SYNC_DIFF_CCO_PPM if (msg.nid == 0) { /* maybe recover init ppm */ mac_modify_dbg_pkt_tx_ppm(0); } #endif phy_ppm_status_ctxt_t *ctxt = phy_multi_sync_get_ppm_status(); phy_multi_sync_apply_bb_ppm(ctxt, msg.nid, BB_PPM_RX_ONLY); #endif } #if ENA_WAR_244 if((msg.dst_tei != 0 || msg.src_tei != 0) && (FC_DELIM_SOF == delimeter || FC_DELIM_BEACON == delimeter)) { /* fc ok found flag */ g_phy_cpu_share_ctxt.pm_status.fc_ok_found = 1; } if (RGF_RAW_READ_REG(CFG_RAW_DATA_MODE_ADDR)) { /* for some case, PHY info is not set correctly * if RAWDATA mode */ phy_rawdata_bb_set_tmi(proto, 0, 0); } if ((FC_DELIM_SOF == delimeter) && (msg.dst_tei == RGF_MAC_READ_REG(CFG_MYTEI_ADDR)) && (msg.nid == RGF_MAC_READ_REG(CFG_MYNID_ADDR))) { #if MAC_WAR_SPLIT_TX_RX_RIFS /* this is kunlun1 war * make tx rx rifs separate */ mac_tx_rifs_tmr_set(mac_cfg_tx_rifs_get()); #endif #if MAC_WAR_244_TIMESTAMPING g_phy_cpu_share_ctxt._1_rx_fd_fc_ts = \ RGF_MAC_READ_REG(CFG_RD_NTB_ADDR); #endif /* enable raw data mode */ RGF_RAW_WRITE_REG(CFG_RAW_DATA_MODE_ADDR, 1); if (g_phy_cpu_share_ctxt.need_record_tei) { g_phy_cpu_share_ctxt.sof_src_tei = msg.src_tei; g_phy_cpu_share_ctxt.need_record_tei = false; } else { g_phy_cpu_share_ctxt.sack_miss_cnt++; } if (!g_phy_cpu_share_ctxt.need_record_sof) { g_phy_cpu_share_ctxt.need_record_sof = 1; } } else { /* disable raw data mode? */ } #endif } g_phy_cpu_share_ctxt.reg_phase = phy_get_mac_rx_phase(); g_phy_cpu_share_ctxt.phy_force_0 = \ RGF_MAC_READ_REG(CFG_PHY_FORCE_0_ADDR); } #if DEBUG_NID_ERR if (isr_flag & INTR_TYPE_PHY_TX_TD_FC_DONE) { uint32_t cur_nid, config_nid; uint32_t bb_tx_fc = RGF_RAW_READ_REG(CFG_TX_FC_DATA0_ADDR); cur_nid = mac_get_nid_from_fc(proto, &bb_tx_fc); config_nid = mac_get_hw_nid(); /* tx nid = 0, maybe this is dbg/cert packet */ if ((config_nid != 0) && (0 != cur_nid) && (cur_nid != config_nid)) { g_phy_cpu_share_ctxt.nid_err_cnt++; g_phy_cpu_share_ctxt.cur_nid = cur_nid; g_phy_cpu_share_ctxt.config_nid = config_nid; } } #endif if (isr_flag & INTR_TYPE_PHY_TX_TD_FC_DONE) { bb_fc[0] = RGF_RAW_READ_REG(CFG_TX_SW_FC_0_ADDR); bb_fc[1] = RGF_RAW_READ_REG(CFG_TX_SW_FC_1_ADDR); bb_fc[2] = RGF_RAW_READ_REG(CFG_TX_SW_FC_2_ADDR); bb_fc[3] = RGF_RAW_READ_REG(CFG_TX_SW_FC_3_ADDR); delimeter = (uint8_t)mac_get_delimi_from_fc(proto, bb_fc); #if ENA_WAR_SPG_TX_OK if (FC_DELIM_SOF == delimeter) { rx_fc_msg_t tx_msg = { 0 }; mac_get_rx_frm_msg_from_fc(PLC_PROTO_TYPE_SPG, bb_fc, &tx_msg); if (tx_msg.dst_tei != 0xfff) { spg_frame_control_t *spg_fc_t = (spg_frame_control_t *)bb_fc; spg_fc_t->vf.sof.dst_tei = 0; RGF_RAW_WRITE_REG(CFG_TX_SW_FC_0_ADDR, bb_fc[0]); RGF_RAW_WRITE_REG(CFG_TX_SW_FC_1_ADDR, bb_fc[1]); RGF_RAW_WRITE_REG(CFG_TX_SW_FC_2_ADDR, bb_fc[2]); RGF_RAW_WRITE_REG(CFG_TX_SW_FC_3_ADDR, bb_fc[3]); } } #endif #if ENA_CCO_RX_THR_PHASE_CHANGE if (FC_DELIM_SACK == delimeter) { phy_set_rx_abort_rx_phase_force_from_isr(false, g_phy_cpu_share_ctxt.rx_phase_force_en, g_phy_cpu_share_ctxt.rx_phase_force); } #endif g_phy_cpu_share_ctxt.tx_td_fc_done_cnt++; } if (isr_flag & INTR_TYPE_PHY_TX_FD_TX_DONE \ || isr_flag & INTR_TYPE_PHY_FD_TX_ABORT \ || isr_flag & INTR_TYPE_PHY_FD_TX_STUCK) { #if ENA_WAR_NSG_EXTMI RGF_RAW_WRITE_REG(CFG_SW_FC_VALID_ADDR, 0); PHY_WRITE_REG(CFG_BB_RAW_DATA_MODE_CTRL_ADDR, 0); #endif if(isr_flag & INTR_TYPE_PHY_TX_FD_TX_DONE) { #if MAC_WAR_SPLIT_TX_RX_RIFS /* this is kunlun1 war * make tx rx rifs separate */ mac_rx_rifs_tmr_set(mac_cfg_rx_rifs_get()); #endif } if(isr_flag & INTR_TYPE_PHY_FD_TX_ABORT) { g_phy_cpu_share_ctxt.phy_tx_abort_cnt++; #if WAR_TIMEOUT_TX_ABORT //1. clear tx abort interrupt phy_clear_hw_interrupt_cpu1(INTR_TYPE_PHY_FD_TX_ABORT); //2. get phy interrupte status uint32_t isr_flag_again = 0; isr_flag_again = phy_get_hw_interrupt_type_cpu1(); //3. if tx abort still equal 1, mask tx abort if(isr_flag_again & INTR_TYPE_PHY_FD_TX_ABORT) { g_phy_cpu_share_ctxt.timeout_tx_abort_flag = true; phy_disable_hw_interrupt_cpu1(INTR_TYPE_PHY_FD_TX_ABORT); } #endif } if (isr_flag & INTR_TYPE_PHY_FD_TX_STUCK) { g_phy_cpu_share_ctxt.tx_fd_stuck_cnt++; } #if MAC_WAR_244_TIMESTAMPING g_phy_cpu_share_ctxt._2_tx_fd_ts = RGF_MAC_READ_REG(CFG_RD_NTB_ADDR); #endif #if (ENA_WAR_CTL) /* disable MAC RAW DATA MODE */ RGF_RAW_WRITE_REG(CFG_RAW_DATA_MODE_ADDR, 0); /* clear pb size BB */ phy_rawdata_mode_bb_set_ps_tr(0,0,0); #endif } if (isr_flag & INTR_TYPE_PHY_TX_TD_START) { uint32_t dbg_value = 0; /* bit[2:0] - 3bit*/ dbg_value |= PHY_READ_REG(CFG_BB_TX_TD_DBG_BUS_ADDR) & 0x07; /* bit[4:0] - 5bit */ dbg_value |= (PHY_READ_REG(CFG_BB_TX_FD_FSM_DBG_BUS_ADDR) & 0x1F) << 3; g_phy_cpu_share_ctxt.tx_td_start_status = dbg_value; g_phy_cpu_share_ctxt.tx_td_start_cnt++; #if ENA_WAR_440 phy_war_tx_fl_overflow(); #endif #if (ENA_WAR_244 && MAC_WAR_244_TIMESTAMPING) g_phy_cpu_share_ctxt._2_tx_td_st_ts = RGF_MAC_READ_REG(CFG_RD_NTB_ADDR); #endif #if (ENA_WAR_CTL) phy_rawdata_war_phy_pbsz(); #endif #if DEBUG_CANNOT_SENDOUT_PKT phy_get_after_war_fc(g_phy_cpu_share_ctxt.tx_fc); #endif } #if MAC_SYM_NUM_FIX || MAC_TIMESTAMPING || ENA_CCO_RX_THR_PHASE_CHANGE /* PLD ok or fail interrupt */ if (isr_flag & INTR_TYPE_PHY_FD_PLD_OK || isr_flag & INTR_TYPE_PHY_FD_PLD_FAIL) { #if MAC_SYM_NUM_FIX uint32_t tmp = PHY_READ_REG(CFG_BB_CONFIG_FC_PARSE_0_ADDR); if (REG_FIELD_GET(SW_CONFIG_PB_SYMB_NUM_EN, tmp) || REG_FIELD_GET(SW_CONFIG_PLD_SYMB_NUM_EN, tmp)) { REG_FIELD_SET(SW_CONFIG_PB_SYMB_NUM_EN, tmp, 0); REG_FIELD_SET(SW_CONFIG_PLD_SYMB_NUM_EN, tmp, 0); PHY_WRITE_REG(CFG_BB_CONFIG_FC_PARSE_0_ADDR, tmp); } #endif /* MAC_SYM_NUM_FIX */ #if MAC_TIMESTAMPING g_phy_cpu_share_ctxt.phy_pld_int_ntb = RGF_MAC_READ_REG(CFG_RD_NTB_ADDR); #endif #if ENA_CCO_RX_THR_PHASE_CHANGE iot_memset(&msg, 0, sizeof(rx_fc_msg_t)); bb_fc[0] = PHY_READ_REG(CFG_BB_RX_FC_RAW_0_ADDR); bb_fc[1] = PHY_READ_REG(CFG_BB_RX_FC_RAW_1_ADDR); bb_fc[2] = PHY_READ_REG(CFG_BB_RX_FC_RAW_2_ADDR); bb_fc[3] = PHY_READ_REG(CFG_BB_RX_FC_RAW_3_ADDR); delimeter = (uint8_t)mac_get_delimi_from_fc(proto, bb_fc); mac_get_rx_frm_msg_from_fc(proto, bb_fc, &msg); if (FC_DELIM_BEACON == delimeter) { phy_set_rx_abort_rx_phase_force_from_isr(false, g_phy_cpu_share_ctxt.rx_phase_force_en, g_phy_cpu_share_ctxt.rx_phase_force); } else if (!((FC_DELIM_SOF == delimeter) && (msg.dst_tei == RGF_MAC_READ_REG(CFG_MYTEI_ADDR)) && (msg.nid == RGF_MAC_READ_REG(CFG_MYNID_ADDR)))) { phy_set_rx_abort_rx_phase_force_from_isr(false, g_phy_cpu_share_ctxt.rx_phase_force_en, g_phy_cpu_share_ctxt.rx_phase_force); } #endif } #endif /* clear interrupt mask */ phy_clear_hw_interrupt_cpu1(isr_flag); /* enable interrupt mask */ //phy_enable_hw_interrupt_cpu1(isr_flag); #else (void)vector; (void)data; #endif return ERR_OK; } void phy_isr_init_cpu1(void) { #if HW_PLATFORM >= HW_PLATFORM_FPGA iot_irq_t phy_irq_int_3; /* move clean cpu1 phy interrupt to cpu1 phy start function */ phy_irq_int_3 = \ iot_interrupt_create(HAL_VECTOR_PHY_3, HAL_INTR_PRI_6, 0, phy_interrupt_handler_cpu1); /* set to cpu1 */ iot_interrupt_set_cpu(phy_irq_int_3, HAL_INTR_CPU_1); iot_interrupt_attach(phy_irq_int_3); iot_interrupt_unmask(phy_irq_int_3); #endif return; }