815 lines
		
	
	
		
			24 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
		
		
			
		
	
	
			815 lines
		
	
	
		
			24 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
|  | /****************************************************************************
 | ||
|  | 
 | ||
|  | Copyright(c) 2019 by Aerospace C.Power (Chongqing) Microelectronics. ALL RIGHTS RESERVED. | ||
|  | 
 | ||
|  | This Information is proprietary to Aerospace C.Power (Chongqing) Microelectronics and MAY NOT | ||
|  | be copied by any method or incorporated into another program without | ||
|  | the express written consent of Aerospace C.Power. This Information or any portion | ||
|  | thereof remains the property of Aerospace C.Power. The Information contained herein | ||
|  | is believed to be accurate and Aerospace C.Power assumes no responsibility or | ||
|  | liability for its use in any way and conveys no license or title under | ||
|  | any patent or copyright and makes no representation or warranty that this | ||
|  | Information is free from patent or copyright infringement. | ||
|  | 
 | ||
|  | ****************************************************************************/ | ||
|  | #include "chip_reg_base.h"
 | ||
|  | #include "hw_reg_api.h"
 | ||
|  | #include "plc_utils.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 "ada_reg.h"
 | ||
|  | #include "hw_phy_init.h"
 | ||
|  | #include "mac_desc_engine.h"
 | ||
|  | #include "iot_pkt_api.h"
 | ||
|  | #include "plc_const.h"
 | ||
|  | #include "os_mem.h"
 | ||
|  | #include "rx_pb_reorder.h"
 | ||
|  | #include "phy_reg.h"
 | ||
|  | #include "iot_bitops.h"
 | ||
|  | #include "phy_bb.h"
 | ||
|  | #include "hw_tonemask.h"
 | ||
|  | #if HW_PLATFORM > HW_PLATFORM_SIMU
 | ||
|  | #include "dbg_io.h"
 | ||
|  | #endif
 | ||
|  | #include "iot_io.h"
 | ||
|  | #include "phy_ana.h"
 | ||
|  | #include "mac_rx_test.h"
 | ||
|  | #include "mac_rx_buf_ring.h"
 | ||
|  | #include "iot_config.h"
 | ||
|  | #include "hw_desc.h"
 | ||
|  | #include "phy_rxtd_reg.h"
 | ||
|  | #include "phy_rx_fd_reg.h"
 | ||
|  | #include "phy_dfe_reg.h"
 | ||
|  | 
 | ||
|  | #define IPC_CONTROL
 | ||
|  | 
 | ||
|  | #ifdef IPC_CONTROL
 | ||
|  | #include "iot_errno.h"
 | ||
|  | #include "iot_mc_ipc.h"
 | ||
|  | #endif
 | ||
|  | 
 | ||
|  | #if IOT_FTM_SUPPORT == 1
 | ||
|  | uint8_t *rx_buf[RX_BUF_NUM]; | ||
|  | #else
 | ||
|  | uint8_t rx_buf[RX_BUF_NUM][RX_BUF_BYTE_SIZE]; | ||
|  | #endif
 | ||
|  | uint8_t *rx_buf_ptr_list[RX_BUF_NUM]; | ||
|  | uint32_t tmi_beacon_cnt[MAX_TMI_NUM][4] = {0}; | ||
|  | uint32_t tmi_sof_cnt[MAX_TMI_NUM][4] = {0}; | ||
|  | uint32_t tmi_sack_cnt[4] = {0}; | ||
|  | uint32_t tmi_nncco_cnt[4] = {0}; | ||
|  | int16_t gain = 0,rmi = 0; | ||
|  | uint16_t band_cnt[MAX_HW_BAND] = {0}; | ||
|  | 
 | ||
|  | uint32_t print_period_ms=4000;  /*receive 25*4 packets in 4s*/ | ||
|  | 
 | ||
|  | extern void phy_sts_get(iot_phy_sts_info_t *pkt_sts); | ||
|  | extern agc_gain_tbl_t gain_reg_tbl[]; | ||
|  | 
 | ||
|  | #ifdef IPC_CONTROL
 | ||
|  | 
 | ||
|  | #define IPC_MSG_ID_RAWDATA_START_REQ   1
 | ||
|  | 
 | ||
|  | #define REQ_TYPE_NEW    1
 | ||
|  | 
 | ||
|  | typedef struct _ipc_msg_rawdata_start_req | ||
|  | { | ||
|  |     uint8_t req_type; | ||
|  | }ipc_msg_rawdata_start_req_t; | ||
|  | 
 | ||
|  | #define IPC_MSG_ID_RAWDATA_START_CNF   2
 | ||
|  | 
 | ||
|  | #define CNF_STATUS_OK    1
 | ||
|  | #define CNF_STATUS_FAIL  2
 | ||
|  | typedef struct _ipc_msg_rawdata_start_cnf | ||
|  | { | ||
|  |     uint8_t status; | ||
|  | }ipc_msg_rawdata_cnf_t; | ||
|  | 
 | ||
|  | ipc_msg_rawdata_start_req_t start_msg; | ||
|  | ipc_msg_rawdata_cnf_t cnf_msg; | ||
|  | 
 | ||
|  | volatile uint32_t rawdata_cnf_received = 0; | ||
|  | volatile uint32_t rawdata_start_received = 0; | ||
|  | 
 | ||
|  | void scpu_recv_ipc_msg(uint32_t msg_id, void* msg_arg); | ||
|  | void acpu_recv_ipc_msg(uint32_t msg_id, void* msg_arg); | ||
|  | 
 | ||
|  | 
 | ||
|  | uint32_t iot_rawdata_init_ipc(uint8_t cpuid) | ||
|  | { | ||
|  |     if(cpuid == IOT_SECCPU_ID){ | ||
|  |         iot_mc_ipc_init(scpu_recv_ipc_msg, IOT_SECCPU_ID, INTC_MODE); | ||
|  |     }else{ | ||
|  |         iot_mc_ipc_init(acpu_recv_ipc_msg, IOT_APPCPU_ID, INTC_MODE); | ||
|  |     } | ||
|  | 
 | ||
|  |     return ERR_OK; | ||
|  | } | ||
|  | 
 | ||
|  | volatile uint32_t rawdata_start_send = 0; | ||
|  | 
 | ||
|  | uint32_t acpu_start_rawdata(void) | ||
|  | { | ||
|  |     uint32_t j = 0; | ||
|  |     start_msg.req_type = REQ_TYPE_NEW; | ||
|  | 
 | ||
|  |     while(!rawdata_cnf_received){ | ||
|  |         if(!rawdata_start_send){ | ||
|  |             if(iot_mc_ipc_query_mailbox_freecredit() >0){ | ||
|  |                 iot_mc_ipc_send_msg(IPC_MSG_ID_RAWDATA_START_REQ, (void*)&start_msg); | ||
|  |                 rawdata_start_send = 1; | ||
|  |             } | ||
|  |         } | ||
|  | 
 | ||
|  |         //iot_printf("rawdata_cnf_received=%d rawdata_start_send=%d\n", rawdata_cnf_received, rawdata_start_send);
 | ||
|  |         for(j=0;j<APP_CPU_POLL_SPEED;j++); | ||
|  | 
 | ||
|  |         for(j=0;j<APP_CPU_POLL_SPEED;j++); | ||
|  | 
 | ||
|  |         for(j=0;j<APP_CPU_POLL_SPEED;j++); | ||
|  |     } | ||
|  | 
 | ||
|  |     return ERR_OK; | ||
|  | } | ||
|  | 
 | ||
|  | 
 | ||
|  | void acpu_recv_ipc_msg(uint32_t msg_id, void* msg_arg) | ||
|  | { | ||
|  | 
 | ||
|  |     ipc_msg_rawdata_cnf_t* pmsg = NULL; | ||
|  | 
 | ||
|  |     iot_printf("secpu[rec] msg_id:%x arg:%x  status:%x\n", msg_id, msg_arg, iot_mc_ipc_get_hw_stauts()); | ||
|  |     switch(msg_id) | ||
|  |     { | ||
|  |         case IPC_MSG_ID_RAWDATA_START_CNF: | ||
|  |             pmsg = (ipc_msg_rawdata_cnf_t*)msg_arg; | ||
|  |             iot_printf("IPC_MSG_ID_RAWDATA_START_CNF : %d\n", pmsg->status); | ||
|  |             if(pmsg->status == CNF_STATUS_OK){ | ||
|  |                 rawdata_cnf_received = 1; | ||
|  |             } | ||
|  |             break; | ||
|  | 
 | ||
|  | 
 | ||
|  |         default: | ||
|  |             iot_printf("unhandled msgid:0x%x\n", msg_id); | ||
|  |             break; | ||
|  |     } | ||
|  | } | ||
|  | 
 | ||
|  | 
 | ||
|  | 
 | ||
|  | 
 | ||
|  | void scpu_recv_ipc_msg(uint32_t msg_id, void* msg_arg) | ||
|  | { | ||
|  |     ipc_msg_rawdata_start_req_t* pmsg = NULL; | ||
|  | 
 | ||
|  |     iot_printf("secpu[rec] msg_id:%x arg:%x status:%x\n", msg_id, msg_arg, iot_mc_ipc_get_hw_stauts()); | ||
|  |     switch(msg_id) | ||
|  |     { | ||
|  |         case IPC_MSG_ID_RAWDATA_START_REQ: | ||
|  |             pmsg = (ipc_msg_rawdata_start_req_t*)msg_arg; | ||
|  |             iot_printf("IPC_MSG_ID_RAWDATA_START_REQ : %d\n", pmsg->req_type); | ||
|  |             cnf_msg.status = CNF_STATUS_OK; | ||
|  |             if(iot_mc_ipc_query_mailbox_freecredit() >0){ | ||
|  |                 iot_mc_ipc_send_msg(IPC_MSG_ID_RAWDATA_START_CNF, (void*)&cnf_msg); | ||
|  |                 rawdata_start_received = 1; | ||
|  |             } | ||
|  |             break; | ||
|  | 
 | ||
|  | 
 | ||
|  |         default: | ||
|  |             iot_printf("unhandled msgid:0x%x\n", msg_id); | ||
|  |             break; | ||
|  |     } | ||
|  | } | ||
|  | 
 | ||
|  | /* acpu will send ipc request to scpu to start rawmode */ | ||
|  | 
 | ||
|  | #endif
 | ||
|  | 
 | ||
|  | void mpdu_rx_cnt_callback(rx_pb_end *pb_ed, uint32_t *cnt) | ||
|  | { | ||
|  |     if (pb_ed->rx_pb_crc_err == 0) | ||
|  |         cnt += 1; | ||
|  | } | ||
|  | 
 | ||
|  | static uint32_t mac_hw_init() | ||
|  | { | ||
|  |     uint32_t tmp = 0; | ||
|  |     uint32_t symbnum_ppb = 0; | ||
|  |     uint32_t fl_ppb = 0; | ||
|  | 
 | ||
|  | #if IOT_FTM_SUPPORT == 1
 | ||
|  |     tmp = RX_BUF_NUM; | ||
|  |     while(tmp--) | ||
|  |         rx_buf[tmp] = (uint8_t *)os_mem_malloc(IOT_FTM_MID, RX_BUF_BYTE_SIZE); | ||
|  | #endif
 | ||
|  | 
 | ||
|  |     /* reset mac */ | ||
|  |     mac_reset(MAC_RST_REASON_COLD); | ||
|  |     /* reset phy */ | ||
|  |     phy_reset(PHY_RST_REASON_COLD); | ||
|  |     /* reset mac */ | ||
|  |     mac_reset(MAC_RST_REASON_COLD); | ||
|  | 
 | ||
|  |     phy_init(PLC_PROTO_TYPE_SG, \ | ||
|  |         IOT_PLC_PHY_BAND_DFT, TONE_MASK_ID_NULL, true); | ||
|  | 
 | ||
|  |     /* enable packets receive */ | ||
|  |     tmp = RGF_RX_READ_REG(CFG_RX_FILTER_0_ADDR); | ||
|  |     REG_FIELD_SET(CFG_NID_FILTER_DIS, tmp, 1); | ||
|  |     REG_FIELD_SET(CFG_MPDU_DTEI_FILTER_DIS, tmp, 1); | ||
|  |     REG_FIELD_SET(CFG_BEACON_PHASE_FILTER_DIS, tmp, 1); | ||
|  |     RGF_RX_WRITE_REG(CFG_RX_FILTER_0_ADDR, tmp); | ||
|  | 
 | ||
|  |     /* config my nid */ | ||
|  |     tmp = RGF_MAC_READ_REG(CFG_MYNID_ADDR); | ||
|  |     if(PHY_PROTO_TYPE_GET() == PLC_PROTO_TYPE_SG){ | ||
|  |         REG_FIELD_SET(CFG_MYNID, tmp, 0x123456); | ||
|  |     } | ||
|  |     else if(PHY_PROTO_TYPE_GET() == PLC_PROTO_TYPE_SPG){ | ||
|  |         REG_FIELD_SET(CFG_MYNID, tmp, 0xb); | ||
|  |     } | ||
|  |     else if(PHY_PROTO_TYPE_GET() == PLC_PROTO_TYPE_GP){ | ||
|  |         REG_FIELD_SET(CFG_MYNID, tmp, 0xb);/*11 for kunlun*/ | ||
|  |     } | ||
|  |     RGF_MAC_WRITE_REG(CFG_MYNID_ADDR, tmp); | ||
|  | 
 | ||
|  |     /* tei cfg */ | ||
|  |     RGF_MAC_WRITE_REG(CFG_MYTEI_ADDR, 2); | ||
|  | 
 | ||
|  |     /* delete timeout for long pkt */ | ||
|  |     tmp = RGF_RX_READ_REG(CFG_RX_TIMEOUT_1_ADDR); | ||
|  |     REG_FIELD_SET(CFG_RX_PB_TIMEOUT, tmp, 2000000); | ||
|  |     RGF_RX_WRITE_REG(CFG_RX_TIMEOUT_1_ADDR, tmp); | ||
|  | 
 | ||
|  |     /* pb framelength for gp */ | ||
|  |     if(PHY_PROTO_TYPE_GET() == PLC_PROTO_TYPE_GP){ | ||
|  |         /* tmi0 band0 */ | ||
|  |         symbnum_ppb = phy_get_sym_per_pb(PHY_PROTO_TYPE_GET(), 0, 0, 0, 0); | ||
|  |         fl_ppb = (uint32_t)(FRAME_LENGTH_PER_PB_GP(symbnum_ppb, GI_STD_ROBO)/1.28); | ||
|  |         tmp = RGF_RX_READ_REG(CFG_TMI0_BAND0_ADDR); | ||
|  |         REG_FIELD_SET(CFG_TMI0_BAND0_PBFL,tmp,fl_ppb); | ||
|  |         RGF_RX_WRITE_REG(CFG_TMI0_BAND0_ADDR,tmp); | ||
|  |         /* tmi1 band0 */ | ||
|  |         symbnum_ppb = phy_get_sym_per_pb(PHY_PROTO_TYPE_GET(), 0, 1, 0, 0); | ||
|  |         fl_ppb = (uint32_t)(FRAME_LENGTH_PER_PB_GP(symbnum_ppb, GI_HS_ROBO)/1.28); | ||
|  |         tmp = RGF_RX_READ_REG(CFG_TMI1_BAND0_ADDR); | ||
|  |         REG_FIELD_SET(CFG_TMI1_BAND0_PBFL,tmp,fl_ppb); | ||
|  |         RGF_RX_WRITE_REG(CFG_TMI1_BAND0_ADDR,tmp); | ||
|  |         /* tmi2 band0 */ | ||
|  |         symbnum_ppb = phy_get_sym_per_pb(PHY_PROTO_TYPE_GET(), 0, 2, 0, 0); | ||
|  |         fl_ppb = (uint32_t)(FRAME_LENGTH_PER_PB_GP(symbnum_ppb, GI_MINI_ROBO)/1.28); | ||
|  |         tmp = RGF_RX_READ_REG(CFG_TMI2_BAND0_ADDR); | ||
|  |         REG_FIELD_SET(CFG_TMI2_BAND0_PBFL,tmp,fl_ppb); | ||
|  |         RGF_RX_WRITE_REG(CFG_TMI2_BAND0_ADDR,tmp); | ||
|  |     } | ||
|  | 
 | ||
|  |     return 0; | ||
|  | } | ||
|  | 
 | ||
|  | void rx_ring_setup_hw(uint32_t ring_id, rx_ring_cfg_t *cfg) | ||
|  | { | ||
|  |     (void)ring_id; | ||
|  |     (void)cfg; | ||
|  | 
 | ||
|  |     uint32_t tmp; | ||
|  |     uint32_t i; | ||
|  | 
 | ||
|  |     /* init the rx ring buf */ | ||
|  |     for (i = 0; i < RX_BUF_NUM; i++) { | ||
|  |         rx_buf_ptr_list[i] = rx_buf[i]; | ||
|  |     } | ||
|  |     RGF_RX_WRITE_REG(CFG_BUFFER_RING0_0_ADDR, (uint32_t)rx_buf_ptr_list); | ||
|  | 
 | ||
|  |     /* set ring sz and buf len */ | ||
|  |     tmp = RGF_RX_READ_REG(CFG_BUFFER_RING0_1_ADDR); | ||
|  |     REG_FIELD_SET(CFG_RING0_BUF_SIZE, tmp, RX_BUF_DW_SIZE); | ||
|  |     REG_FIELD_SET(CFG_RING0_BUF_NUM, tmp, RX_BUF_NUM); | ||
|  |     RGF_RX_WRITE_REG(CFG_BUFFER_RING0_1_ADDR, tmp); | ||
|  | 
 | ||
|  |     /* set rd idx = 0 as default */ | ||
|  |     tmp = RGF_RX_READ_REG(CFG_BUFFER_RING0_2_ADDR); | ||
|  |     REG_FIELD_SET(CFG_RING0_RD_IDX, tmp, 0); | ||
|  |     RGF_RX_WRITE_REG(CFG_BUFFER_RING0_2_ADDR, tmp); | ||
|  | 
 | ||
|  |     /* set desc and payload offset */ | ||
|  |     tmp = RGF_RX_READ_REG(CFG_BUFFER_RING0_3_ADDR); | ||
|  |     REG_FIELD_SET(CFG_RING0_DESC_EN, tmp, 1); | ||
|  |     REG_FIELD_SET(CFG_RING0_PAYLOAD_EN, tmp, 1); | ||
|  |     REG_FIELD_SET(CFG_RING0_DESC_OFFSET, tmp, 0); | ||
|  |     REG_FIELD_SET(CFG_RING0_PAYLOAD_OFFSET, tmp, \ | ||
|  |         iot_ceil(sizeof(rx_buf_hdr_t), 4)); | ||
|  |     RGF_RX_WRITE_REG(CFG_BUFFER_RING0_3_ADDR, tmp); | ||
|  | 
 | ||
|  |     return; | ||
|  | } | ||
|  | 
 | ||
|  | void rx_ring_enable(uint32_t ring_id, uint32_t enable) | ||
|  | { | ||
|  |     (void)ring_id; | ||
|  |     uint32_t tmp; | ||
|  |     tmp = RGF_RX_READ_REG(CFG_BUFFER_RING0_2_ADDR); | ||
|  |     REG_FIELD_SET(CFG_RING0_EN, tmp, enable); | ||
|  |     RGF_RX_WRITE_REG(CFG_BUFFER_RING0_2_ADDR, tmp); | ||
|  | 
 | ||
|  |     return; | ||
|  | } | ||
|  | 
 | ||
|  | uint32_t is_rx_ring0_empty() | ||
|  | { | ||
|  |     uint32_t rd_idx, wr_idx; | ||
|  |     rd_idx = RX_RING_GET_RD_IDX(0); | ||
|  |     wr_idx = RX_RING_GET_WR_IDX(0); | ||
|  | 
 | ||
|  |     return (rd_idx == wr_idx); | ||
|  | } | ||
|  | 
 | ||
|  | uint32_t* dbg_fc = NULL; | ||
|  | uint8_t *pop_rx_buf_from_ring(uint32_t ring_id) | ||
|  | { | ||
|  |     static uint32_t enq_time = 0, cur_time = 0; | ||
|  |     static int64_t time_span = 0; | ||
|  | 
 | ||
|  |     (void)ring_id; | ||
|  |     uint32_t rd_idx = 0; | ||
|  |     static uint32_t fisrt_pb_crc_ok_cnt = 0, second_pb_crc_ok_cnt = 0, \ | ||
|  |             third_pb_crc_ok_cnt = 0, last_pb_crc_ok_cnt = 0; | ||
|  |     uint8_t *rx_buf_start; | ||
|  |     rx_buf_hdr_t *pb_buf; | ||
|  |     uint32_t gain_reg0 = 0, gain_reg1 = 0; | ||
|  | 
 | ||
|  |     rd_idx = RX_RING_GET_RD_IDX(0); | ||
|  |     rx_buf_start = rx_buf[rd_idx]; | ||
|  |     pb_buf = (rx_buf_hdr_t *)rx_buf_start; | ||
|  | 
 | ||
|  |     if ((pb_buf->att.rx_mpdu_done == 1) && (pb_buf->att.is_fcserr == 0)){ | ||
|  |         if(!pb_buf->pb_ed.rx_pb_crc_err) | ||
|  |         { | ||
|  |             if(1 == pb_buf->mpdu_ed.rx_buf_num) | ||
|  |                 fisrt_pb_crc_ok_cnt++; | ||
|  |             else if(2 == pb_buf->mpdu_ed.rx_buf_num) | ||
|  |                 second_pb_crc_ok_cnt++; | ||
|  |             else if(3 == pb_buf->mpdu_ed.rx_buf_num) | ||
|  |                 third_pb_crc_ok_cnt++; | ||
|  |             else if(4 == pb_buf->mpdu_ed.rx_buf_num) | ||
|  |                 last_pb_crc_ok_cnt++; | ||
|  | 
 | ||
|  |             if(PHY_PROTO_TYPE_GET() == PLC_PROTO_TYPE_SG) | ||
|  |             { | ||
|  |                 switch(pb_buf->mpdu_st.fc.sg_fc.delimiter_type) | ||
|  |                 { | ||
|  |                     case FC_DELIM_BEACON: | ||
|  |                         tmi_beacon_cnt[pb_buf->mpdu_st.fc.sg_fc.vf.bcn.tmi]\ | ||
|  |                         [pb_buf->mpdu_ed.rx_buf_num-1] += 1; | ||
|  |                         break; | ||
|  |                     case FC_DELIM_SOF: | ||
|  |                         dbg_fc = (uint32_t*)&pb_buf->mpdu_st.fc.sg_fc; | ||
|  |                         tmi_sof_cnt[pb_buf->mpdu_st.fc.sg_fc.vf.sof.tmi_ext + \ | ||
|  |                             pb_buf->mpdu_st.fc.sg_fc.vf.sof.tmi][pb_buf->mpdu_ed.rx_buf_num-1] += 1; | ||
|  |                         iot_printf("FC:0x%04x pb_num:%d rx_abort:%d\n", dbg_fc[0],pb_buf->att.pb_num, pb_buf->att.rx_abort); | ||
|  |                         iot_printf("FC:0x%04x 0x%04x 0x%04x\n", dbg_fc[1],dbg_fc[2],dbg_fc[3]); | ||
|  |                         break; | ||
|  |                     case FC_DELIM_SACK: | ||
|  |                         tmi_sack_cnt[pb_buf->mpdu_ed.rx_buf_num-1] += 1; | ||
|  |                         break; | ||
|  |                     case FC_DELIM_NNCCO: | ||
|  |                         tmi_nncco_cnt[pb_buf->mpdu_ed.rx_buf_num-1] += 1; | ||
|  |                         break; | ||
|  |                     default: | ||
|  |                         break; | ||
|  |                 } | ||
|  |             } | ||
|  |             else if(PHY_PROTO_TYPE_GET() == PLC_PROTO_TYPE_SPG) | ||
|  |             { | ||
|  |                 switch(pb_buf->mpdu_st.fc.spg_fc.delimiter_type) | ||
|  |                 { | ||
|  |                     case FC_DELIM_BEACON: | ||
|  |                         tmi_beacon_cnt[pb_buf->mpdu_st.fc.spg_fc.vf.bcn.tmi]\ | ||
|  |                         [pb_buf->mpdu_ed.rx_buf_num-1] += 1; | ||
|  |                         break; | ||
|  |                     case FC_DELIM_SOF: | ||
|  |                         tmi_sof_cnt[pb_buf->mpdu_st.fc.spg_fc.vf.sof.tmi_ext + \ | ||
|  |                         pb_buf->mpdu_st.fc.spg_fc.vf.sof.tmi]\ | ||
|  |                         [pb_buf->mpdu_ed.rx_buf_num-1] += 1; | ||
|  |                         break; | ||
|  |                     case FC_DELIM_SACK: | ||
|  |                         tmi_sack_cnt[pb_buf->mpdu_ed.rx_buf_num-1] += 1; | ||
|  |                         break; | ||
|  |                     case FC_DELIM_NNCCO: | ||
|  |                         tmi_nncco_cnt[pb_buf->mpdu_ed.rx_buf_num-1] += 1; | ||
|  |                         break; | ||
|  |                     default: | ||
|  |                         break; | ||
|  |                 } | ||
|  |             } | ||
|  |             else if(PHY_PROTO_TYPE_GET() == PLC_PROTO_TYPE_GP) | ||
|  |             { | ||
|  |                 switch(pb_buf->mpdu_st.fc.hpav_fc.delimiter_type) | ||
|  |                 { | ||
|  |                     case FC_DELIM_BEACON: | ||
|  |                         tmi_beacon_cnt[0][pb_buf->mpdu_ed.rx_buf_num-1] += 1; | ||
|  |                         break; | ||
|  |                     case FC_DELIM_SOF: | ||
|  |                         tmi_sof_cnt[pb_buf->mpdu_st.fc.hpav_fc.vf_av.sof.tmi_av]\ | ||
|  |                         [pb_buf->mpdu_ed.rx_buf_num-1] += 1; | ||
|  |                         break; | ||
|  |                     case FC_DELIM_SACK: | ||
|  |                         tmi_sack_cnt[pb_buf->mpdu_ed.rx_buf_num-1] += 1; | ||
|  |                         break; | ||
|  |                     case FC_DELIM_NNCCO: | ||
|  |                         tmi_nncco_cnt[pb_buf->mpdu_ed.rx_buf_num-1] += 1; | ||
|  |                         break; | ||
|  |                     default: | ||
|  |                         break; | ||
|  |                 } | ||
|  |             } | ||
|  | 
 | ||
|  |             /* fresh gain by cco */ | ||
|  |             if(pb_buf->mpdu_st.fc.spg_fc.vf.bcn.src_tei == 1 || \ | ||
|  |                 pb_buf->mpdu_st.fc.spg_fc.vf.sof.src_tei == 1 || \ | ||
|  |                 pb_buf->mpdu_st.fc.sg_fc.vf.bcn.src_tei == 1 || \ | ||
|  |                 pb_buf->mpdu_st.fc.sg_fc.vf.sof.src_tei == 1 || \ | ||
|  |                 pb_buf->mpdu_st.fc.hpav_fc.vf_av.sof.src_tei == 1 || \ | ||
|  |                 pb_buf->mpdu_st.fc.hpav_fc.vf_av.rtscts.src_tei == 1 || \ | ||
|  |                 pb_buf->mpdu_st.fc.hpav_fc.vf_av.sound.stei == 1) | ||
|  |             { | ||
|  | #if 0
 | ||
|  |                 if(pb_buf->mpdu_st.peer & 0x8000) | ||
|  |                     gain = (int16_t)(((pb_buf->mpdu_st.peer & 0xFF00)>>8)|0xFF00);/*fix char print error*/ | ||
|  |                 else | ||
|  |                     gain = (int16_t)((pb_buf->mpdu_st.peer & 0xFF00)>>8); | ||
|  |                 if(pb_buf->mpdu_st.peer & 0x80) | ||
|  |                     rmi = (int16_t)((pb_buf->mpdu_st.peer & 0xFF)|0xFF00); | ||
|  |                 else | ||
|  |                     rmi = (int16_t)(pb_buf->mpdu_st.peer & 0xFF); | ||
|  |                 gain_reg0 = all_mask_gain_table[gain] & 0xff; | ||
|  |                 gain_reg1 = (all_mask_gain_table[gain] >> 8) & 0xff; | ||
|  |                 gain = phy_gain_val_get(gain_reg0,gain_reg1); | ||
|  | #endif
 | ||
|  |                 (void)gain_reg0; | ||
|  |                 (void)gain_reg1; | ||
|  |             } | ||
|  | 
 | ||
|  |             /* rate and band info */ | ||
|  |             if(pb_buf->att.rx_band_sel < MAX_HW_BAND){ | ||
|  |                 band_cnt[pb_buf->att.rx_band_sel] += 1; | ||
|  |             } | ||
|  |             else{ | ||
|  |                 IOT_ASSERT(0); | ||
|  |             } | ||
|  |         } | ||
|  | 
 | ||
|  |         if(++rd_idx >= RX_BUF_NUM) | ||
|  |             rd_idx = 0; | ||
|  |         RX_RING_SET_RD_IDX(0, rd_idx); | ||
|  | 
 | ||
|  |         cur_time = RGF_MAC_READ_REG(CFG_RD_NTB_ADDR); | ||
|  |         time_span = cur_time - enq_time; | ||
|  |         if (time_span < 0) { // wrap around
 | ||
|  |             time_span = (0x100000000LL) - enq_time + cur_time; | ||
|  |         } | ||
|  |         /*agc gain info*/ | ||
|  |         if((uint64_t)time_span > print_period_ms*TICKS_MS) | ||
|  |         { | ||
|  |             enq_time = cur_time; | ||
|  |             iot_printf("AGC gain info: %hd-%hd, pb crc ok:1st=%d,", \ | ||
|  |                         gain, rmi, fisrt_pb_crc_ok_cnt); | ||
|  |             iot_printf("2nd=%d, 3rd=%d, 4th=%d\r\n", \ | ||
|  |                         second_pb_crc_ok_cnt, third_pb_crc_ok_cnt, last_pb_crc_ok_cnt); | ||
|  | 
 | ||
|  |             gain = -1; | ||
|  |             rmi = -1; | ||
|  |             fisrt_pb_crc_ok_cnt = 0; | ||
|  |             second_pb_crc_ok_cnt = 0; | ||
|  |             third_pb_crc_ok_cnt = 0; | ||
|  |             last_pb_crc_ok_cnt = 0; | ||
|  |         } | ||
|  | 
 | ||
|  |         return rx_buf_start; | ||
|  |     } | ||
|  |     else { | ||
|  |         if (++rd_idx >= RX_BUF_NUM) { | ||
|  |             rd_idx = 0; | ||
|  |         } | ||
|  |         RX_RING_SET_RD_IDX(0, rd_idx); | ||
|  | 
 | ||
|  |         return NULL; | ||
|  |     } | ||
|  | } | ||
|  | 
 | ||
|  | void handle_rx_buf(uint8_t *buf, uint32_t buf_byte_len) | ||
|  | { | ||
|  |     (void)buf; | ||
|  |     (void)buf_byte_len; | ||
|  |     /* print the content out */ | ||
|  |     //iot_printf("packet received.\n");
 | ||
|  |     return; | ||
|  | } | ||
|  | 
 | ||
|  | /* support mode : ftm, module, dtest scan */ | ||
|  | void rx_common_init() | ||
|  | { | ||
|  |     /* basic data struct init for bit ops */ | ||
|  |     iot_bitops_init(); | ||
|  | 
 | ||
|  |     mac_hw_init(); | ||
|  | } | ||
|  | 
 | ||
|  | /* mac rx pkt single */ | ||
|  | uint32_t mac_rx_single_mode() | ||
|  | { | ||
|  |     uint32_t start_time = 0, end_time = 0; | ||
|  |     uint64_t time_span = 0; | ||
|  |     iot_phy_sts_info_t total_sts = {0}; | ||
|  |     uint8_t tmi = 0; | ||
|  |     uint8_t tmp = 0; | ||
|  |     uint32_t i = 0; | ||
|  | 
 | ||
|  |     /* check if rx ring has content */ | ||
|  |     uint8_t *rx_buf_tmp; | ||
|  |     start_time = RGF_MAC_READ_REG(CFG_RD_NTB_ADDR); | ||
|  |     do { | ||
|  |         while (!is_rx_ring0_empty()) | ||
|  |         { | ||
|  |             rx_buf_tmp = pop_rx_buf_from_ring(0); | ||
|  |             if (rx_buf_tmp) { | ||
|  |                 handle_rx_buf(rx_buf_tmp, RX_BUF_DW_SIZE << 2); | ||
|  |             } | ||
|  |         } | ||
|  |         end_time = RGF_MAC_READ_REG(CFG_RD_NTB_ADDR); | ||
|  |         time_span = end_time - start_time; | ||
|  |         if (time_span < 0) { // wrap around
 | ||
|  |             time_span = (0x100000000LL) - start_time + end_time; | ||
|  |         } | ||
|  |         if((uint64_t)time_span > print_period_ms*TICKS_MS){ | ||
|  |             phy_sts_get(&total_sts); | ||
|  |             iot_printf("mac tx ok:%d/4s, fc_ok:%d/4s, fc_err:%d/4s,", \ | ||
|  |                 total_sts.mac_tx_ok_cnt,total_sts.fc_crc_ok_cnt,total_sts.fc_crc_fail_cnt); | ||
|  |             iot_printf("pld_ok:%d/4s, pld fail:%d/4s, sync ok:%d/4s\r\n", \ | ||
|  |                 total_sts.pld_crc_ok_cnt,total_sts.pld_crc_fail_cnt,total_sts.sync_ok_cnt); | ||
|  |             start_time = end_time; | ||
|  | 
 | ||
|  |             /* print tmi counter */ | ||
|  |             tmi = MAX_TMI_NUM; | ||
|  |             while(tmi--){ | ||
|  |                 for(i=0; i<4; i++) | ||
|  |                 { | ||
|  |                     /* beacon */ | ||
|  |                     if(tmi_beacon_cnt[tmi][i] != 0) | ||
|  |                     { | ||
|  |                         if(tmi < 15) | ||
|  |                             iot_printf("[TMI-%d][BCN][PB-%d]:%d\r\n", \ | ||
|  |                                         tmi,i,tmi_beacon_cnt[tmi][i]); | ||
|  |                         else{ | ||
|  |                             tmp = tmi - 15;/* skip optimization for next  */ | ||
|  |                             iot_printf("[EXT-TMI-%d][BCN][PB-%d]:%d\r\n", \ | ||
|  |                                         tmp,i,tmi_beacon_cnt[tmi][i]); | ||
|  |                         } | ||
|  |                         tmi_beacon_cnt[tmi][i] = 0; | ||
|  |                     } | ||
|  |                     /* sof */ | ||
|  |                     if(tmi_sof_cnt[tmi][i] != 0) | ||
|  |                     { | ||
|  |                         if(tmi < 15) | ||
|  |                             iot_printf("[TMI-%d][SOF][PB-%d]:%d\r\n", \ | ||
|  |                                         tmi,i,tmi_sof_cnt[tmi][i]); | ||
|  |                         else{ | ||
|  |                             tmp = tmi - 15;/* skip optimization for next  */ | ||
|  |                             iot_printf("[EXT-TMI-%d][SOF][PB-%d]:%d\r\n", \ | ||
|  |                                         tmp,i,tmi_sof_cnt[tmi][i]); | ||
|  |                         } | ||
|  |                         tmi_sof_cnt[tmi][i] = 0; | ||
|  |                     } | ||
|  |                 } | ||
|  |             } | ||
|  | 
 | ||
|  |             /* sack & nncco */ | ||
|  |             for(i=0; i<4; i++) | ||
|  |             { | ||
|  |                 if(tmi_sack_cnt[i] != 0){ | ||
|  |                     iot_printf("[SACK][PB-%d]:%d\r\n",i,tmi_sack_cnt[i]); | ||
|  |                     tmi_sack_cnt[i] = 0; | ||
|  |                 } | ||
|  |                 if(tmi_nncco_cnt[i] != 0){ | ||
|  |                     iot_printf("[NNCCO][PB-%d]:%d\r\n",i,tmi_nncco_cnt[i]); | ||
|  |                     tmi_nncco_cnt[i] = 0; | ||
|  |                 } | ||
|  |             } | ||
|  | 
 | ||
|  |             /* band info */ | ||
|  |             for(i=0; i<MAX_HW_BAND; i++) | ||
|  |             { | ||
|  |                 if(band_cnt[i] != 0){ | ||
|  |                     iot_printf("[BAND-%d]:%d\r\n", i, band_cnt[i]); | ||
|  |                     band_cnt[i] = 0; | ||
|  |                 } | ||
|  |             } | ||
|  |         } | ||
|  |     } while (true); /* keep check */ | ||
|  | 
 | ||
|  |     return 0; | ||
|  | } | ||
|  | 
 | ||
|  | /* mac rx snr cal */ | ||
|  | uint32_t mac_rx_snr_scan() | ||
|  | { | ||
|  |     uint32_t tone_idx = 0; | ||
|  |     int32_t snr_buf[TONE_MAX_NUM] = {0}; | ||
|  | 
 | ||
|  |     phy_rx_snr_get(0,TONE_MAX_NUM,snr_buf); | ||
|  | 
 | ||
|  |     /* cal snr for every tone */ | ||
|  |     for(tone_idx = 0; tone_idx < TONE_MAX_NUM; tone_idx++) | ||
|  |     { | ||
|  |         iot_printf("tone%d snr:%d\r\n",tone_idx, snr_buf[tone_idx]); | ||
|  |     } | ||
|  | 
 | ||
|  |     return 0; | ||
|  | } | ||
|  | 
 | ||
|  | /* mac rx csi cal */ | ||
|  | uint32_t mac_rx_csi_scan() | ||
|  | { | ||
|  |     uint32_t tone_idx = 0; | ||
|  |     uint32_t csi_buf[TONE_MAX_NUM] = {0}; | ||
|  | 
 | ||
|  |     phy_rx_csi_get(0,TONE_MAX_NUM,csi_buf); | ||
|  | 
 | ||
|  |     /* cal snr for every tone */ | ||
|  |     for(tone_idx = 0; tone_idx < TONE_MAX_NUM; tone_idx++) | ||
|  |     { | ||
|  |         iot_printf("csi power=%d\r\n", csi_buf[tone_idx]); | ||
|  |     } | ||
|  | 
 | ||
|  |     return 0; | ||
|  | } | ||
|  | 
 | ||
|  | /* mac rx noise floor cal */ | ||
|  | uint32_t mac_rx_noise_floor_scan() | ||
|  | { | ||
|  |     int32_t gain = 0; | ||
|  |     uint32_t rssi_nf = 0; | ||
|  |     uint32_t tone_idx = 0; | ||
|  |     uint32_t nf_buf[TONE_MAX_NUM] = {0}; | ||
|  | 
 | ||
|  |     phy_rx_noise_floor_get(0,TONE_MAX_NUM,nf_buf); | ||
|  | 
 | ||
|  |     /* noise floor for every tone */ | ||
|  |     for(tone_idx = 0; tone_idx < TONE_MAX_NUM; tone_idx++) | ||
|  |     { | ||
|  |         iot_printf("tone%d noise floor:%d\r\n",tone_idx, nf_buf[tone_idx]); | ||
|  |     } | ||
|  | 
 | ||
|  |     phy_rx_snr_gain_get(&gain, &rssi_nf); | ||
|  |     iot_printf("Gain-NF: %hd-%hd\r\n", gain, rssi_nf); | ||
|  | 
 | ||
|  |     return 0; | ||
|  | } | ||
|  | 
 | ||
|  | /* STA mac rx ppm cali */ | ||
|  | uint32_t mac_rx_ppm_cali() | ||
|  | { | ||
|  |     int16_t ppm_cali_rd = 0; | ||
|  |     int16_t ppm_cali_wr = 0; | ||
|  |     uint32_t start_time = 0, end_time = 0; | ||
|  |     int64_t time_span = 0; | ||
|  |     uint32_t tmp = 0; | ||
|  | 
 | ||
|  | #ifdef PHY_PPM_CAL_ON_SNR
 | ||
|  |     int32_t snr_buf[TONE_MAX_NUM] = {0}; | ||
|  |     uint32_t tone_idx = 0; | ||
|  |     uint32_t snr = 0; | ||
|  | 
 | ||
|  |     do{ | ||
|  |         phy_rx_snr_get(0,TONE_MAX_NUM,snr_buf); | ||
|  |         /* cal snr for every tone */ | ||
|  |         for(tone_idx = 0; tone_idx < TONE_MAX_NUM; tone_idx++) | ||
|  |         { | ||
|  |             iot_printf("tone%d snr:%d\r\n",tone_idx, snr_buf[tone_idx]); | ||
|  |             if(snr_buf[tone_idx] > 20){ | ||
|  |                 snr = snr_buf[tone_idx]; | ||
|  |             } | ||
|  |         } | ||
|  |     }while(!snr); | ||
|  | 
 | ||
|  |     /* shutdown self comp */ | ||
|  |     phy_freq_shift_self_comp(false,false); | ||
|  | #endif
 | ||
|  | 
 | ||
|  |     /* calibration start */ | ||
|  |     start_time = RGF_MAC_READ_REG(CFG_RD_NTB_ADDR); | ||
|  |     do { | ||
|  |         ppm_cali_rd = phy_ppm_info_get(); | ||
|  |         /* no need cal if |ppm| < 1 */ | ||
|  |         if (ppm_cali_rd > -1 && ppm_cali_rd < 1 ) | ||
|  |             break; | ||
|  | 
 | ||
|  |         if (ppm_cali_rd > 50 || ppm_cali_rd < -50){ | ||
|  |             iot_printf("calibration failed: ppm error big than 50!\r\n"); | ||
|  |         } | ||
|  | 
 | ||
|  |         /* set calibration to ppm setting reg */ | ||
|  | #if IOT_RATE_MODE_RX == IOT_SUPPORT_RATE_XR
 | ||
|  |         phy_ppm_cal_and_update_hw(PHY_CAL_UNIT_1_1, -ppm_cali_rd, \ | ||
|  |             IOT_SUPPORT_RATE_XR, BB_PPM_TXRX); | ||
|  | #elif IOT_RATE_MODE_RX == IOT_SUPPORT_RATE_QR
 | ||
|  |         phy_ppm_cal_and_update_hw(PHY_CAL_UNIT_1_4, -ppm_cali_rd, \ | ||
|  |          IOT_SUPPORT_RATE_QR, BB_PPM_TXRX); | ||
|  | #else
 | ||
|  |         phy_ppm_cal_and_update_hw(PHY_CAL_UNIT_1_16, -ppm_cali_rd, \ | ||
|  |             IOT_SUPPORT_RATE_SR, BB_PPM_TXRX); | ||
|  | #endif
 | ||
|  | 
 | ||
|  |         do{ | ||
|  |             end_time = RGF_MAC_READ_REG(CFG_RD_NTB_ADDR); | ||
|  |             time_span = end_time - start_time; | ||
|  |             if (time_span < 0) { // wrap around
 | ||
|  |                 time_span = (0x100000000LL) - start_time + end_time; | ||
|  |             } | ||
|  |         }while((uint64_t)time_span < 25000*100);//25000*0.04us=1ms
 | ||
|  |         start_time = end_time; | ||
|  |     }while (1); | ||
|  | 
 | ||
|  |     tmp = PHY_DFE_READ_REG(CFG_BB_PPM_SETTING_ADDR); | ||
|  |     ppm_cali_wr = REG_FIELD_GET(SW_RX_PPM,tmp); | ||
|  |     iot_printf("mac_rx_ppm_cali: calibration success! "); | ||
|  |     iot_printf("ppm_cali_wr=0x%x\r\n",ppm_cali_wr); | ||
|  | 
 | ||
|  |     return 0; | ||
|  | } | ||
|  | 
 | ||
|  | void mac_rx_test() | ||
|  | { | ||
|  | #if HW_PLATFORM > HW_PLATFORM_SIMU
 | ||
|  | #if EDA_SIMU_SUPPORT != 1
 | ||
|  |     /* serial init */ | ||
|  |   	dbg_uart_init(); | ||
|  | 	iot_printf("mac_rx_test begin...\n"); | ||
|  | #endif
 | ||
|  | #endif
 | ||
|  | 
 | ||
|  |     /* basic data struct init for bit ops */ | ||
|  |     iot_bitops_init(); | ||
|  | 
 | ||
|  |     mac_hw_init(); | ||
|  | 
 | ||
|  |     /* ppm calibration */ | ||
|  | #ifdef MAC_RX_PPM_SUPPORT
 | ||
|  | #if MAC_RX_TEST_ID != MAC_RX_NOISE_FLOOR_SCAN
 | ||
|  |     mac_rx_ppm_cali(); | ||
|  | #endif
 | ||
|  | #endif
 | ||
|  | 
 | ||
|  |     /* setup the rx ring */ | ||
|  |     rx_ring_setup_hw(0, NULL); | ||
|  | 
 | ||
|  |     /* enable the rx ring */ | ||
|  |     rx_ring_enable(0, true); | ||
|  | 
 | ||
|  | 
 | ||
|  | #ifdef IPC_CONTROL
 | ||
|  |         iot_rawdata_init_ipc(IOT_APPCPU_ID); | ||
|  |         acpu_start_rawdata(); | ||
|  | #endif
 | ||
|  | 
 | ||
|  | 
 | ||
|  |     switch(MAC_RX_TEST_ID) | ||
|  |     { | ||
|  |         case MAC_RX_PKT: | ||
|  |             mac_rx_single_mode(); | ||
|  |             break; | ||
|  |         case MAC_RX_SNR_SCAN: | ||
|  |             mac_rx_snr_scan(); | ||
|  |             break; | ||
|  |         case MAC_RX_CSI_SCAN: | ||
|  |             mac_rx_csi_scan(); | ||
|  |             break; | ||
|  |         case MAC_RX_NOISE_FLOOR_SCAN: | ||
|  |             mac_rx_noise_floor_scan(); | ||
|  |             break; | ||
|  |         case MAC_PPM_CALIBRATION: | ||
|  |             mac_rx_ppm_cali(); | ||
|  |             break; | ||
|  |         default: | ||
|  |             IOT_ASSERT(0); | ||
|  |     } | ||
|  | 
 | ||
|  |     return; | ||
|  | } | ||
|  | 
 | ||
|  | #ifdef __GNUC__
 | ||
|  | #if !MODULE_EN
 | ||
|  | 
 | ||
|  | int main(void) { | ||
|  |     mac_rx_test(); | ||
|  |     return 0; | ||
|  | } | ||
|  | #endif
 | ||
|  | #endif // __GCC__
 | ||
|  | 
 |