Files
kunlun/dtest/mac_tx_test/hw/hw_tx.c
2024-09-28 14:24:04 +08:00

827 lines
26 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.
****************************************************************************/
#include "chip_reg_base.h"
#include "hw_reg_api.h"
#include "mac_desc_engine.h"
#include "mac_hwq_mgr.h"
#include "mac_crc.h"
#include "mpdu_header.h"
#include "mac_reset.h"
#include "mac_hwq_reg.h"
#include "mac_sys_reg.h"
#include "mac_rx_reg.h"
#include "mac_tmr_reg.h"
#include "mac_avln.h"
#include "mac_key_hw.h"
#include "mac_key.h"
#include "phy_pm.h"
#include "hw_tx.h"
#include "tx_entry.h"
#include "iot_io.h"
#include "clk.h"
#include "os_mem.h"
#include "intc_reg.h"
#include "phy_int.h"
#include "mac_raw_reg.h"
#include "phy_reg.h"
#include "rgf_mac_int.h"
extern tonemap_table_entry gp_tonemap_table[];
uint32_t mac_tx_mpdu_test(void *pdev, volatile tx_mpdu_start *mpdu) {
(void)pdev;
uint32_t tmp = 0;
uint32_t pb_size = 0;
uint32_t tmi = 0, ext_tmi = 0;
uint32_t pb_mod = 0;
uint32_t rate_mode = glb_cfg.rate_mode;
mpdu->desc_type = DESC_TYPE_TX_MPDU_START;
mpdu->proto_type = glb_cfg.m_type;
mpdu->tx_port = HW_DESC_TX_PORT_PLC;
mpdu->tx_phase = glb_cfg.phase;
mpdu->tx_power = 128; // 1/8 unit db
if(glb_cfg.ack_en == true)
mpdu->need_ack = 1;
mpdu->ppdu_mode = HW_DESC_PPDU_MODE_AVONLY_1FCSYM;
mpdu->next = NULL;
/* clear the mpdu_end */
if (mpdu->tx_status) {
mpdu->tx_status->tx_done = 0;
mpdu->tx_status->tx_ok = 0;
}
/* tmi info */
tmi = glb_cfg.tmi;
if(glb_cfg.m_type == PLC_PROTO_TYPE_SG)
{
if (tmi >= 15) {
/* if use ext_tmi */
tmi = 15;
ext_tmi = glb_cfg.tmi - 15;
}
} else if (glb_cfg.m_type == PLC_PROTO_TYPE_SPG) {
IOT_ASSERT(tmi <= 10 || tmi >= 16 );
if (tmi > 10) {
/* if use ext_tmi */
tmi = 13;
ext_tmi = glb_cfg.tmi - 15;
}
}
/* only contains the pb's size */
phy_get_pb_size(glb_cfg.m_type, tmi, ext_tmi, &pb_size);
mpdu->pb_num = glb_cfg.pb_num;
mpdu->total_bytes = pb_size*glb_cfg.pb_num;
/* start/end time, ignore in GP's case */
//mpdu->start_time = 0;
//mpdu->end_time = 0;
/* TODO: amplitude table select */
mpdu->tx_tone_amp = 0;
/* band info */
#if MAC_MULTI_BAND_SUPPORT == 1
mpdu->sg_bandsel = RGF_MAC_READ_REG(CFG_RD_NTB_ADDR)%3;
#else
mpdu->sg_bandsel = 0;
#endif
mpdu->tx_symbnum_ppb = phy_get_sym_per_pb( \
glb_cfg.m_type, mpdu->sg_bandsel, tmi, ext_tmi,
phy_get_pss_id(glb_cfg.m_type, tmi, ext_tmi));
if(mpdu->tx_symbnum_ppb*glb_cfg.pb_num >= 512){
iot_printf("[TMI-%d][PB-%d][error]:symbol size %d bigger than 512.", \
ext_tmi+tmi,glb_cfg.pb_num,mpdu->tx_symbnum_ppb*glb_cfg.pb_num);
return ERR_INVAL;
}
mpdu->sw_tx_fl_ppb = (uint32_t) \
phy_get_fl_per_pb(glb_cfg.m_type, mpdu->sg_bandsel, tmi, ext_tmi);
#if (SUPPORT_SMART_GRID)
if(glb_cfg.m_type == PLC_PROTO_TYPE_SG)
{
frame_control_t *sg_fc = (frame_control_t *)(&(mpdu->fc));
if(glb_cfg.p_type == FC_DELIM_BEACON)
{
sg_fc->delimiter_type = FC_DELIM_BEACON; /*beacon*/
sg_fc->vf.bcn.time_stamp = 0;
sg_fc->vf.bcn.src_tei = 1;
sg_fc->vf.bcn.tmi = tmi;
sg_fc->vf.bcn.sym_num = 0;
sg_fc->vf.bcn.phase_num = 0;
sg_fc->vf.bcn.version = 0;
}
else if(glb_cfg.p_type == FC_DELIM_SOF)
{
sg_fc->delimiter_type = FC_DELIM_SOF; /*sof*/
sg_fc->vf.sof.src_tei = 1;
sg_fc->vf.sof.dst_tei = 2;
sg_fc->vf.sof.lid = 0;
sg_fc->vf.sof.frame_len = 0;
sg_fc->vf.sof.pb_num = glb_cfg.pb_num;
sg_fc->vf.sof.sym_num = 0;
sg_fc->vf.sof.bcast = 0;
sg_fc->vf.sof.tmi = tmi;
sg_fc->vf.sof.tmi_ext = ext_tmi;
sg_fc->vf.sof.version = 0;
}
else if(glb_cfg.p_type == FC_DELIM_SOUND)
{
sg_fc->delimiter_type = FC_DELIM_SOUND; /*sound*/
sg_fc->vf.sof.src_tei = 1;
sg_fc->vf.sof.dst_tei = 2;
sg_fc->vf.sof.lid = 0;
sg_fc->vf.sof.frame_len = 0;
sg_fc->vf.sof.pb_num = glb_cfg.pb_num;
sg_fc->vf.sof.sym_num = 0;
sg_fc->vf.sof.bcast = 0;
sg_fc->vf.sof.tmi = tmi;
sg_fc->vf.sof.tmi_ext = ext_tmi;
sg_fc->vf.sof.version = 0;
}
sg_fc->network_type = 0;
sg_fc->nid = glb_cfg.nid;
}
else
#endif //
#if (SUPPORT_SOUTHERN_POWER_GRID)
if (glb_cfg.m_type == PLC_PROTO_TYPE_SPG)
{
spg_frame_control_t *spg_fc = (spg_frame_control_t *)(&mpdu->fc);
if(glb_cfg.p_type == FC_DELIM_BEACON)
{
spg_fc->delimiter_type = FC_DELIM_BEACON; /*beacon*/
spg_fc->vf.bcn.time_stamp = 0;
spg_fc->vf.bcn.src_tei = 1;
spg_fc->vf.bcn.tmi = tmi;
spg_fc->vf.bcn.sym_num = 0;
spg_fc->vf.bcn.phase_num = 0;
spg_fc->vf.bcn.version = 0;
}
else if(glb_cfg.p_type == FC_DELIM_SOF)
{
spg_fc->delimiter_type = FC_DELIM_SOF; /*sof*/
spg_fc->vf.sof.src_tei = 1;
spg_fc->vf.sof.dst_tei = 2;
spg_fc->vf.sof.lid = 0;
spg_fc->vf.sof.frm_len = 0;
spg_fc->vf.sof.pb_num = glb_cfg.pb_num;
spg_fc->vf.sof.sym_num = 0;
spg_fc->vf.sof.tmi = tmi;
spg_fc->vf.sof.tmi_ext = ext_tmi;
spg_fc->vf.sof.version = 0;
}
spg_fc->access_ind = 1;
spg_fc->snid = glb_cfg.nid;
}
else
#endif //SUPPORT_SOUTHERN_POWER_GRID
#if SUPPORT_GREEN_PHY
{
/* AV FC */
hpav_frame_control *hpav_fc = (hpav_frame_control *)(&mpdu->fc);
if(glb_cfg.p_type == DT_AV_BEACON)
{
hpav_fc->delimiter_type = DT_AV_BEACON;
}
else if(glb_cfg.p_type == DT_AV_SOF)
{
hpav_fc->delimiter_type = DT_AV_SOF;
hpav_fc->vf_av.sof.src_tei = 1;
hpav_fc->vf_av.sof.dst_tei = 2;
hpav_fc->vf_av.sof.lid = 0;
hpav_fc->vf_av.sof.eks = 0xf;
if(gp_tonemap_table[tmi].pb_size == 520)
hpav_fc->vf_av.sof.pbsz = 0;
else if(gp_tonemap_table[tmi].pb_size == 136)
hpav_fc->vf_av.sof.pbsz = 1;
else
IOT_ASSERT(0);
hpav_fc->vf_av.sof.numsym = 3;
hpav_fc->vf_av.sof.tmi_av = glb_cfg.tmi;
hpav_fc->vf_av.sof.fl_av = (mpdu->sw_tx_fl_ppb*mpdu->pb_num+160)/1.28;
}
else if(glb_cfg.p_type == DT_AV_RTS_CTS)
{
hpav_fc->delimiter_type = DT_AV_RTS_CTS;
hpav_fc->vf_av.rtscts.src_tei = 1;
hpav_fc->vf_av.rtscts.dst_tei = 2;
hpav_fc->vf_av.rtscts.lid = 0;
hpav_fc->vf_av.rtscts.rtsf = 1;
}
else if(glb_cfg.p_type == DT_AV_SOUND)
{
hpav_fc->delimiter_type = DT_AV_SOUND;
hpav_fc->vf_av.sound.stei = 1;
hpav_fc->vf_av.sound.dtei = 2;
hpav_fc->vf_av.sound.lid = 0;
if(tmi == 0 || tmi == 1)
{
hpav_fc->vf_av.sound.pbsz = 0;
phy_pld_gi1_set(GI_HS_ROBO);
}
else if(tmi == 2)
{
hpav_fc->vf_av.sound.pbsz = 1;
phy_pld_gi1_set(GI_MINI_ROBO);
}
hpav_fc->vf_av.sound.req_tm = 1;
hpav_fc->vf_av.sound.fl_av = 0;
hpav_fc->vf_av.sound.src = 0xFD;//as part of Initial Channel Estimation
}
hpav_fc->access = 1;
hpav_fc->snid = glb_cfg.nid;
}
#endif //SUPPORT_GREEN_PHY
{
//do not delete this case
}
/* hw id */
mpdu->swq_id = 0;
/* hw retry cnt */
mpdu->hw_retry_cnt = 0;
/* set the crc hdr len, GP is 4 for bcn */
if(glb_cfg.m_type == PLC_PROTO_TYPE_SG)
{
if(glb_cfg.p_type == FC_DELIM_BEACON)
{
mpdu->pb_hdr_crc_len = 3;
}
else if((glb_cfg.p_type == FC_DELIM_SOF)||(glb_cfg.p_type == FC_DELIM_SOUND))
{
mpdu->pb_hdr_crc_len = 4;
}
}
else if(glb_cfg.m_type == PLC_PROTO_TYPE_SPG)
{
if(glb_cfg.p_type == FC_DELIM_BEACON)
{
mpdu->pb_hdr_crc_len = 3;
}
else if((glb_cfg.p_type == FC_DELIM_SOF)||(glb_cfg.p_type == FC_DELIM_SOUND))
{
mpdu->pb_hdr_crc_len = 7;
}
}
else{
if(glb_cfg.p_type == DT_AV_BEACON)
{
mpdu->pb_hdr_crc_len = 4;
}
else if(glb_cfg.p_type == DT_AV_SOF)
{
mpdu->pb_hdr_crc_len = 8;
}
}
/* pb modulation and rate */
phy_get_pb_mod(glb_cfg.m_type,tmi, ext_tmi, &pb_mod);
mpdu->tx_pb_modulation = pb_mod;
#if MAC_RATE_RANDOM_SUPPORT == 1
mpdu->tx_rate_mode = RGF_MAC_READ_REG(CFG_RD_NTB_ADDR)%2;
(void)rate_mode;
#else
mpdu->tx_rate_mode = (rate_mode == 2)?1:rate_mode;
#endif
/* QR optimize */
if(rate_mode == IOT_SUPPORT_RATE_QR){
phy_qr_common_init();
}
else if(rate_mode == IOT_SUPPORT_RATE_XR){
tmp = RGF_MAC_READ_REG(CFG_PHY_CTRL_ADDR);
REG_FIELD_SET(CFG_MULTI_RATE_BASE_SPEED, tmp, 1);
RGF_MAC_WRITE_REG(CFG_PHY_CTRL_ADDR,tmp);
}
/* update cnt */
band_cnt[mpdu->tx_rate_mode][mpdu->sg_bandsel] += 1;
/* set hwq0's ptr list */
RGF_HWQ_WRITE_REG(CFG_HWQ0_PTR_ADDR, (uint32_t)mpdu);
/* read NTB and fill in the start and end time
* by max time span value
*/
tmp = RGF_MAC_READ_REG(CFG_RD_NTB_ADDR);
RGF_HWQ_WRITE_REG(CFG_HWQ0_START_ADDR, tmp);
RGF_HWQ_WRITE_REG(CFG_HWQ0_END_ADDR, (tmp + (0xffffffff >> 1) - 1));
#if IOT_DTEST_ONLY_SUPPORT == 1
/* update the beacon content */
uint32_t i = 0, j = 0;
if(glb_cfg.p_type == FC_DELIM_BEACON) {
hp_beacon_payload_fixed_header *pb_addr =
(hp_beacon_payload_fixed_header *)(mpdu->pb_list->pb_buf_addr);
pb_addr->nid = PHY_TXRX_NID_VAL;
pb_addr->hm = 0;
pb_addr->stei = 1;
/* pb crc */
pb_addr->bmi.opad[0] = \
iot_getcrc32((uint8_t *)(pb_addr->bmi.opad), \
sizeof(pb_addr->bmi.opad) - 4);
/* init pb_buf with 4 pb */
for (i = 1; i < sizeof(pb_addr->bmi.opad)/4 - 1; i++)
{
pb_addr->bmi.opad[i] = pb_addr->bmi.opad[0]+i;
}
} else {
tx_pb_start *current_pb_ptr = mpdu->pb_list;
uint32_t *pb_other_buf = (uint32_t *)(current_pb_ptr->pb_buf_addr);
uint8_t pb_idx = MAC_PB_NUM_ID;
for (j = 0; j < pb_idx; j++)
{
for (i = 1; i < pb_size >> 2; i++)
{
pb_other_buf[i] = 0x55555555;//tmp + i;
}
pb_other_buf[0] = \
iot_getcrc32((uint8_t *)(pb_other_buf + 1), pb_size - 8);
/* update the next pb */
current_pb_ptr = current_pb_ptr->next_pb;
if(current_pb_ptr) {
pb_other_buf = (uint32_t *)(current_pb_ptr->pb_buf_addr);
}
}
}
#endif
return ERR_OK;
}
void dt_mac_tx_hwq0_re_trig()
{
uint32_t tmp = 0;
/* trigger hwq0 send */
tmp = RGF_HWQ_READ_REG(CFG_HWQ0_ADDR);
if (REG_FIELD_GET(CFG_DBG_HWQ0_EN, tmp)) {
/* if enable then disable first */
REG_FIELD_SET(CFG_DBG_HWQ0_EN, tmp, 0); // disable hwq
RGF_HWQ_WRITE_REG(CFG_HWQ0_ADDR, tmp);
}
REG_FIELD_SET(CFG_DBG_HWQ0_EN, tmp, 1); // enable hwq
RGF_HWQ_WRITE_REG(CFG_HWQ0_ADDR, tmp);
}
void dt_mac_hwq0_ptr_set(uint32_t addr)
{
/* set hwq0's ptr list */
RGF_HWQ_WRITE_REG(CFG_HWQ0_PTR_ADDR, addr);
}
void dt_mac_hwq1_ptr_set(uint32_t addr)
{
/* set hwq1's ptr list */
RGF_HWQ_WRITE_REG(CFG_HWQ1_PTR_ADDR, addr);
}
void dtest_mac_bifs_set(uint16_t bifs)
{
(void)bifs;
}
void mac_tx_path_init()
{
uint32_t tmp = 0;
/* mac related dtest param */
/* enable DCU debug mode */
tmp = RGF_HWQ_READ_REG(CFG_SCH_ADDR);
if(glb_cfg.t_type == MAC_TX_SCHED_BCN_AHEAD_ALERT)
REG_FIELD_SET(CFG_HWQ_DBG_MODE, tmp, 0); // commandlist enable
else
REG_FIELD_SET(CFG_HWQ_DBG_MODE, tmp, 1); // debug enable
RGF_HWQ_WRITE_REG(CFG_SCH_ADDR, tmp);
/* set hwq 0 's config */
/* set hwq0's type, cap */
tmp = RGF_HWQ_READ_REG(CFG_HWQ0_ADDR);
REG_FIELD_SET(CFG_DBG_HWQ0_TYPE, tmp, 0); // 0:TDMA, 1:CSMA
REG_FIELD_SET(CFG_DBG_HWQ0_CAP, tmp, 1); // CAP1 as default
RGF_HWQ_WRITE_REG(CFG_HWQ0_ADDR, tmp);
/* set beacon period */
RGF_MAC_WRITE_REG(CFG_BEACON_PERIOD_ADDR, bcn_period_ms * TICKS_MS);
/* config my nid */
tmp = RGF_MAC_READ_REG(CFG_MYNID_ADDR);
REG_FIELD_SET(CFG_MYNID, tmp, PHY_TXRX_NID_VAL);
RGF_MAC_WRITE_REG(CFG_MYNID_ADDR, tmp);
/* tei cfg */
RGF_MAC_WRITE_REG(CFG_MYTEI_ADDR, 1);
/* enable and trigger the HW to load it */
tmp = RGF_MAC_READ_REG(CFG_TMI_CTRL_ADDR);
REG_FIELD_SET(CFG_TONE_AMP_EN, tmp, 0);
RGF_MAC_WRITE_REG(CFG_TMI_CTRL_ADDR, tmp);
/* delete timeout for long pkt */
RGF_TMR_WRITE_REG(CFG_TX_TIMEOUT_0_ADDR,0x0);
RGF_TMR_WRITE_REG(CFG_TX_TIMEOUT_1_ADDR,0x0);
RGF_TMR_WRITE_REG(CFG_TX_TIMEOUT_2_ADDR,0x0);
RGF_TMR_WRITE_REG(CFG_PHY_TX_TIMEOUT_ADDR,0x0);
#if MAC_TX_TEST_ID == MAC_TX_BURN
/* force tx */
#if 0
phy_txrx_ovr_set(1,2);
phy_gain_shift_set(0, 0, 0, 10);
#else
tmp = RGF_MAC_READ_REG(CFG_PHY_FORCE_0_ADDR);
REG_FIELD_SET(CFG_PHY_PCS_BUSY, tmp, 0);
REG_FIELD_SET(CFG_PHY_PCS_BUSY_FORCE_EN, tmp, 1);
REG_FIELD_SET(CFG_PHY_RX_VLD, tmp, 0);
REG_FIELD_SET(CFG_PHY_RX_VLD_FORCE_EN, tmp, 1);
REG_FIELD_SET(CFG_PHY_RX_FRAME, tmp, 0);
REG_FIELD_SET(CFG_PHY_RX_FRAME_FORCE_EN, tmp, 1);
REG_FIELD_SET(CFG_PHY_RX_READY, tmp, 1);
REG_FIELD_SET(CFG_PHY_RX_READY_FORCE_EN, tmp, 1);
REG_FIELD_SET(CFG_PHY_RX_ENABLE, tmp, 0);
REG_FIELD_SET(CFG_PHY_RX_ENABLE_FORCE_EN, tmp, 1);
RGF_MAC_WRITE_REG(CFG_PHY_FORCE_0_ADDR, tmp);
tmp = RGF_MAC_READ_REG(CFG_PHY_FORCE_1_ADDR);
REG_FIELD_SET(CFG_PHY_TX_ENABLE, tmp, 1);
REG_FIELD_SET(CFG_PHY_TX_ENABLE_FORCE_EN, tmp, 1);
RGF_MAC_WRITE_REG(CFG_PHY_FORCE_1_ADDR, tmp);
tmp = RGF_MAC_READ_REG(CFG_PHY_FORCE_2_ADDR);
REG_FIELD_SET(CFG_PHY_TX_PHASE_SEL, tmp, 1);
REG_FIELD_SET(CFG_PHY_TX_PHASE_SEL_FORCE_EN, tmp, 1);
RGF_MAC_WRITE_REG(CFG_PHY_FORCE_2_ADDR, tmp);
/* en analog tx/rx */
uint8_t reg_id = ANA_GRANITE_TOP_REG;
uint32_t wdata = TOP_EN_TX_MASK | TOP_EN_DAC_MASK | \
TOP_EN_RX_MASK | TOP_EN_ADC_MASK | TOP_ENLIC_MASK;
uint32_t wmask = TOP_EN_TX_MASK | TOP_EN_DAC_MASK | \
TOP_EN_RX_MASK | TOP_EN_ADC_MASK | TOP_ENLIC_MASK;
phy_ana_i2c_write(reg_id,wdata,wmask);
#endif
#endif
/* check phy pwr sts */
phy_pm_pwr_update(PHY_PM_PWR_STS_TXRX);
}
void platform_tx_pre_init()
{
/* change clk to 150M */
clk_core_freq_set(CPU_FREQ_150M);
/* alloc 1K size ram */
os_mem_init((uint8_t *)0xfff000,0x1000);
}
bool_t phy_get_tx_done_from_mpdu(volatile tx_mpdu_start *mpdu)
{
return mpdu->tx_status->tx_done;
}
void phy_tx_done_clr(volatile tx_mpdu_start *mpdu)
{
mpdu->tx_status->tx_done = 0;
}
tx_pb_start *mpdu_pb_list_get_from_pb_start(tx_pb_start *pb_start)
{
return pb_start;
}
tx_mpdu_end *mpdu_tx_status_get_from_mpdu_end(tx_mpdu_end *mpdu_end)
{
return mpdu_end;
}
uint32_t tx_complete_handler(uint32_t vector, iot_addrword_t data)
{
#if IOT_DTEST_ONLY_SUPPORT == 1
uint32_t status;
status = RGF_MAC_READ_REG(CFG_MAC_INT_STS_ADDR);
//iot_printf("intc status=0x%x\r\n",status);
if(status & (0x1 <<5)){
/* clear intr */
RGF_MAC_WRITE_REG(CFG_MAC_INT_CLR_ADDR, 0x1<<5);
RGF_HWQ_WRITE_REG(CFG_HWQ_TX_DONE_INT_CLR_ADDR,0xf);
if(!phy_get_tx_done_from_mpdu(mpdu_start))
iot_printf("Intr complete,but tx not done!\r\n");
phy_tx_done_clr(mpdu_start);
mac_tx_complete_flag = true;
}
if(status & (0x1 <<0)){
/* clear intr */
RGF_MAC_WRITE_REG(CFG_MAC_INT_CLR_ADDR, 0x1<<0);
mac_beacon_alert_flag = true;
}
if(status & (0x1 <<4)){
/* clear intr */
RGF_MAC_WRITE_REG(CFG_MAC_INT_CLR_ADDR, 0x1<<4);
mac_beacon_alert_flag = true;
}
#if MODULE_EN
/* single interrupt handler */
INTC_WRITE_REG(CFG_INT_ENA0_ADDR,0x0);
#endif
#endif
return 0;
}
void mac_interrupt_init()
{
#if IOT_DTEST_ONLY_SUPPORT == 1
uint32_t tmp = 0;
iot_mac_intr_info_t mac_info;
os_mem_set(&mac_info, 0x0, sizeof(iot_mac_intr_info_t));
/* intc en */
INTC_WRITE_REG(CFG_INT_ENA0_ADDR,MPDU_TX_DONE_MASK | BEACON_ALERT_MASK);
/* clr mac int */
RGF_MAC_WRITE_REG(CFG_MAC_INT_CLR_ADDR, MPDU_TX_DONE_MASK);//tx complete
RGF_MAC_WRITE_REG(CFG_MAC_INT_CLR_ADDR, BEACON_ALERT_MASK);//tx beacon alert
/* MPDU done intr enable */
tmp = RGF_MAC_READ_REG(CFG_INT_ENA_MASK_ADDR);
if(glb_cfg.t_type == MAC_TX_INTR_MPDU_COMPLETE)
REG_FIELD_SET(CFG_INT_ENABLE_MASK,tmp,MPDU_TX_DONE_MASK);
else if(glb_cfg.t_type == MAC_TX_INTR_BCN_ALT)
REG_FIELD_SET(CFG_INT_ENABLE_MASK,tmp,BEACON_ALERT_MASK);
else if(glb_cfg.t_type == MAC_TX_SCHED_BCN_AHEAD_ALERT)
REG_FIELD_SET(CFG_INT_ENABLE_MASK,tmp,MPDU_TX_DONE_MASK);
RGF_MAC_WRITE_REG(CFG_INT_ENA_MASK_ADDR, tmp);
/* pri int */
tmp = RGF_MAC_READ_REG(CFG_INT_PRI1_MASK_ADDR);
REG_FIELD_SET(CFG_INT_PRI1_MASK,tmp,BEACON_ALERT_MASK | MPDU_TX_DONE_MASK);
RGF_MAC_WRITE_REG(CFG_INT_PRI1_MASK_ADDR, tmp);
/* interrupt controller */
mac_info.int_num = HAL_VECTOR_MAC_1;
mac_info.handle = iot_interrupt_create( mac_info.int_num, 0, \
(iot_addrword_t)&mac_info, tx_complete_handler);
iot_interrupt_attach( mac_info.handle);
iot_interrupt_unmask( mac_info.handle);
#endif
}
/* handle gp war interrupt request */
void phy_intr_gp_handler(void)
{
uint32_t reg_int = 0;
uint32_t irq_type_reg = 0;
uint32_t tmp = 0;
hpav_frame_control *fc = NULL;
/* get int status */
irq_type_reg = PHY_READ_REG(CFG_BB_INT_MASK_0_ADDR);
/* disable phy int */
reg_int = PHY_READ_REG(CFG_BB_INT_EN_0_ADDR);
reg_int &= ~(PHY_INT_TX_TD_START_MASK | PHY_INT_RX_FD_FC_OK_MASK );
PHY_WRITE_REG(CFG_BB_INT_EN_0_ADDR, reg_int);
/* clr intr */
tmp = PHY_INT_TX_TD_START_MASK | PHY_INT_RX_FD_FC_OK_MASK;
PHY_WRITE_REG(CFG_BB_INT_CLR_0_ADDR, tmp);
/* GP config tmi */
if(irq_type_reg & (1 << PHY_INT_TX_TD_START_OFFSET))
{
fc = (hpav_frame_control *)(RGF_RAW_BASEADDR + CFG_TX_FC_DATA0_ADDR);
}
else if(irq_type_reg & (1 << PHY_INT_RX_FD_FC_OK_OFFSET)){
fc = (hpav_frame_control *)(PHY_BASEADDR + CFG_BB_RX_FC_RAW_0_ADDR);
}
if(fc->delimiter_type == 1)
{
switch(fc->vf_av.sof.tmi_av)
{
case 0:
phy_pld_gi1_set(GI_STD_ROBO);
break;
case 1:
phy_pld_gi1_set(GI_HS_ROBO);
break;
case 2:
phy_pld_gi1_set(GI_MINI_ROBO);
break;
default:
break;
}
}
/* enable intr */
reg_int = PHY_READ_REG(CFG_BB_INT_EN_0_ADDR);
reg_int |= (PHY_INT_TX_TD_START_MASK | PHY_INT_RX_FD_FC_OK_MASK );
PHY_WRITE_REG(CFG_BB_INT_EN_0_ADDR, reg_int);
}
/* handle spg war interrupt request */
void phy_intr_spg_handler(void)
{
uint32_t reg_int = 0;
uint32_t irq_type_reg = 0;
uint32_t tmp = 0;
uint8_t dt, fc_tmp;
uint32_t bb_tx_fc[4];
/* get int status */
irq_type_reg = PHY_READ_REG(CFG_BB_INT_MASK_0_ADDR);
/* disable phy int */
reg_int = PHY_READ_REG(CFG_BB_INT_EN_0_ADDR);
reg_int &= ~(PHY_INT_TX_FD_INSERT_PREAM_DONE_MASK | PHY_INT_RX_FD_CH_EST_DONE_MASK| \
PHY_INT_RX_FD_PB_OK_MASK | PHY_INT_RX_FD_PB_FAIL_MASK | \
PHY_INT_RX_FC_RAW_RECEIVE_MASK);
PHY_WRITE_REG(CFG_BB_INT_EN_0_ADDR, reg_int);
/* clr intr */
tmp = PHY_INT_TX_FD_INSERT_PREAM_DONE_MASK | PHY_INT_RX_FD_CH_EST_DONE_MASK| \
PHY_INT_RX_FD_PB_OK_MASK | PHY_INT_RX_FD_PB_FAIL_MASK | \
PHY_INT_RX_FC_RAW_RECEIVE_MASK;
PHY_WRITE_REG(CFG_BB_INT_CLR_0_ADDR, tmp);
/*SPG tmi*/
if (irq_type_reg & (1 << PHY_INT_TX_FD_INSERT_PREAM_DONE_OFFSET)) {
bb_tx_fc[0] = RGF_RAW_READ_REG(CFG_TX_FC_DATA0_ADDR);
spg_frame_control_t *spg_fc = (spg_frame_control_t *)bb_tx_fc;
dt = spg_fc->delimiter_type;
//dt = (uint8_t)mac_get_delimi_from_fc(PLC_PROTO_TYPE_SPG, bb_tx_fc);
if (FC_DELIM_SOF == dt) {
bb_tx_fc[1] = RGF_RAW_READ_REG(CFG_TX_FC_DATA1_ADDR);
bb_tx_fc[2] = RGF_RAW_READ_REG(CFG_TX_FC_DATA2_ADDR);
bb_tx_fc[3] = RGF_RAW_READ_REG(CFG_TX_FC_DATA3_ADDR);
fc_tmp = (uint8_t)bb_tx_fc[3];
bb_tx_fc[3] = (bb_tx_fc[3] & 0xfffffff0) |\
(((fc_tmp >> 4) & 0xf) | ((fc_tmp << 4) & 0xf0));
RGF_RAW_WRITE_REG(CFG_TX_SW_FC_0_ADDR, bb_tx_fc[0]);
RGF_RAW_WRITE_REG(CFG_TX_SW_FC_1_ADDR, bb_tx_fc[1]);
RGF_RAW_WRITE_REG(CFG_TX_SW_FC_2_ADDR, bb_tx_fc[2]);
RGF_RAW_WRITE_REG(CFG_TX_SW_FC_3_ADDR, bb_tx_fc[3]);
RGF_RAW_WRITE_REG(CFG_SW_FC_VALID_ADDR, 1);
PHY_WRITE_REG(CFG_BB_RAW_DATA_MODE_CTRL_ADDR, 1);
}
}
/* spg rx */
if (irq_type_reg & (1 << PHY_INT_RX_FD_CH_EST_DONE_OFFSET)) {
PHY_WRITE_REG(CFG_BB_RAW_DATA_MODE_CTRL_ADDR, 1);
}
if (irq_type_reg & (1 << PHY_INT_RX_FC_RAW_RECEIVE_OFFSET)) {
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);
spg_frame_control_t *spg_fc = (spg_frame_control_t *)bb_rx_fc;
rx_dt = spg_fc->delimiter_type;
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 ((irq_type_reg & (1 << PHY_INT_RX_FD_PB_OK_OFFSET)) || \
(irq_type_reg & (1 << PHY_INT_RX_FD_PB_FAIL_OFFSET))) {
PHY_WRITE_REG(CFG_BB_RAW_DATA_MODE_CTRL_ADDR, 0);
}
/* enable intr */
reg_int = PHY_READ_REG(CFG_BB_INT_EN_0_ADDR);
reg_int |= (PHY_INT_TX_FD_INSERT_PREAM_DONE_MASK | \
PHY_INT_RX_FD_CH_EST_DONE_MASK | \
PHY_INT_RX_FD_PB_OK_MASK | PHY_INT_RX_FD_PB_FAIL_MASK | \
PHY_INT_RX_FC_RAW_RECEIVE_MASK);
PHY_WRITE_REG(CFG_BB_INT_EN_0_ADDR, reg_int);
}
uint32_t IRAM_ATTR phy_intr_handler(uint32_t vector, iot_addrword_t data)
{
uint32_t proto = 0;
proto = phy_proto_type_get();
if (PLC_PROTO_TYPE_GP == proto) {
phy_intr_gp_handler();
} else if (PLC_PROTO_TYPE_SPG == proto){
phy_intr_spg_handler();
}
return 0;
}
/* set gp war interrupt bit */
void phy_set_gp_war_int(void)
{
uint32_t tmp;
/* clr phy int */
PHY_WRITE_REG(CFG_BB_INT_CLR_0_ADDR, PHY_INT_TX_TD_START_MASK | \
PHY_INT_RX_FD_FC_OK_MASK);
/* enable intr */
tmp = PHY_READ_REG(CFG_BB_INT_EN_0_ADDR);
tmp |= (PHY_INT_TX_TD_START_MASK | PHY_INT_RX_FD_FC_OK_MASK);
PHY_WRITE_REG(CFG_BB_INT_EN_0_ADDR, tmp);
}
/* set spg war interrupt bit */
void phy_set_spg_war_int(void)
{
uint32_t tmp;
/* clr phy int */
PHY_WRITE_REG(CFG_BB_INT_CLR_0_ADDR, PHY_INT_TX_FD_INSERT_PREAM_DONE_MASK | \
PHY_INT_RX_FD_CH_EST_DONE_MASK| PHY_INT_RX_FD_PB_OK_MASK | \
PHY_INT_RX_FD_PB_FAIL_MASK | PHY_INT_RX_FC_RAW_RECEIVE_MASK);
/* enable intr */
tmp = PHY_READ_REG(CFG_BB_INT_EN_0_ADDR);
tmp |= (PHY_INT_TX_FD_INSERT_PREAM_DONE_MASK | PHY_INT_RX_FD_CH_EST_DONE_MASK| \
PHY_INT_RX_FD_PB_OK_MASK | PHY_INT_RX_FD_PB_FAIL_MASK | \
PHY_INT_RX_FC_RAW_RECEIVE_MASK);
PHY_WRITE_REG(CFG_BB_INT_EN_0_ADDR, tmp);
}
void phy_interrupt_init()
{
#if (IOT_DTEST_ONLY_SUPPORT == 1)
uint32_t proto = 0;
iot_irq_t phy_td_start_irqhdl;
/* intc en */
INTC_WRITE_REG(CFG_INT_ENA0_ADDR, 1 << 10);//phy intc0
proto = phy_proto_type_get();
if (PLC_PROTO_TYPE_GP == proto) {
phy_set_gp_war_int();
} else if (PLC_PROTO_TYPE_SPG == proto){
phy_set_spg_war_int();
}
/* interrupt controller */
phy_td_start_irqhdl = iot_interrupt_create( HAL_VECTOR_PHY_0, HAL_INTR_PRI_0, \
0, phy_intr_handler);
iot_interrupt_attach(phy_td_start_irqhdl);
iot_interrupt_unmask(phy_td_start_irqhdl);
#endif
}
void mac_tmap_init()
{
/* not support for kunlun1 */
}