797 lines
		
	
	
		
			23 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
		
		
			
		
	
	
			797 lines
		
	
	
		
			23 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. | ||
|  | 
 | ||
|  | ****************************************************************************/ | ||
|  | 
 | ||
|  | /* os shim includes */ | ||
|  | #include "iot_config.h"
 | ||
|  | #include "os_types.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 "iot_io.h"
 | ||
|  | 
 | ||
|  | #include "bb_cpu_hw_ring.h"
 | ||
|  | #include "mac.h"
 | ||
|  | #include "mac_rf_hwq_mgr.h"
 | ||
|  | #include "rfplc_reg_base.h"
 | ||
|  | #include "hw_reg_api.h"
 | ||
|  | #include "bb_cpu_mac_isr.h"
 | ||
|  | #include "bb_cpu_timer.h"
 | ||
|  | #include "rf_mac_reg.h"
 | ||
|  | #include "mac_sys_reg.h"
 | ||
|  | #include "mac_cmn_hw.h"
 | ||
|  | 
 | ||
|  | #include "bb_cpu_config.h"
 | ||
|  | #include "bb_rf_cfg.h"
 | ||
|  | #include "rf_mac_int.h"
 | ||
|  | #include "rf_hw_tonemap.h"
 | ||
|  | #include "rf_mac_rx_reg.h"
 | ||
|  | #include "mac_rf_rx_buf_ring.h"
 | ||
|  | #include "bb_cpu_hw_ring.h"
 | ||
|  | #include "mac_rf_common_hw.h"
 | ||
|  | #include "bb_cpu_mac_init.h"
 | ||
|  | #include "bb_cpu_fsm.h"
 | ||
|  | 
 | ||
|  | #define BB_CPU_HW_RING_ID_INVALID           MAX_RF_RX_RING_NUM
 | ||
|  | 
 | ||
|  | #define RF_BUF_RINGX_OFFSET                 \
 | ||
|  |     (RF_BUFFER_RING1_0_ADDR - RF_BUFFER_RING0_0_ADDR) | ||
|  | 
 | ||
|  | /* get hw ring rx buffer list address */ | ||
|  | #define bb_cpu_hw_ring_list_get(r_id)     \
 | ||
|  |     ((uint8_t **)REG_FIELD_GET(CFG_RF_RING0_PTR, \ | ||
|  |     RGF_RF_RX_READ_REG(RF_BUFFER_RING0_0_ADDR + (r_id * RF_BUF_RINGX_OFFSET)))) | ||
|  | 
 | ||
|  | /* get hw ring is enable or disable */ | ||
|  | #define bb_cpu_hw_ring_is_enable(r_id)    \
 | ||
|  |     (REG_FIELD_GET(CFG_RF_RING0_EN, RGF_RF_RX_READ_REG(RF_BUFFER_RING0_2_ADDR \ | ||
|  |     + ((r_id) * RF_BUF_RINGX_OFFSET)))) | ||
|  | 
 | ||
|  | /* get hw ring buffer size, unit: 1byte */ | ||
|  | #define bb_cpu_hw_ring_sz_get(r_id)       \
 | ||
|  |     (REG_FIELD_GET(CFG_RF_RING0_BUF_SIZE, \ | ||
|  |     RGF_RF_RX_READ_REG(RF_BUFFER_RING0_1_ADDR \ | ||
|  |     + ((r_id) * RF_BUF_RINGX_OFFSET))) << 2) | ||
|  | 
 | ||
|  | /* get hw rfmac hw ring read index */ | ||
|  | #define bb_cpu_hw_ring_ridx_get(r_id)     \
 | ||
|  |     (REG_FIELD_GET(CFG_RF_RING0_RD_IDX, \ | ||
|  |     RGF_RF_RX_READ_REG(RF_BUFFER_RING0_2_ADDR + (r_id * RF_BUF_RINGX_OFFSET)))) | ||
|  | 
 | ||
|  | /* get rf ring buffer write index */ | ||
|  | #define bb_cpu_hw_ring_reg_wr_idx_get(r_id, reg_idx) \
 | ||
|  |     REG_FIELD_GET(RO_RF_RING##r_id##_MPDU_BUF_WR_IDX, \ | ||
|  |     RGF_RF_RX_READ_REG(RX_BUF_RING_WR_IDX_##reg_idx##_ADDR)) | ||
|  | 
 | ||
|  | typedef struct _mac_hw_ring_ctxt { | ||
|  |     /* current select ring id */ | ||
|  |     uint8_t ring_id; | ||
|  |     /* ring is enable or disable */ | ||
|  |     uint8_t enable; | ||
|  |     /* reserved */ | ||
|  |     uint16_t rsvd1; | ||
|  |     /* current ring rx desc address */ | ||
|  |     uint8_t *rx_desc; | ||
|  | } bb_cpu_hw_ring_ctxt_t; | ||
|  | 
 | ||
|  | /* tmp buf */ | ||
|  | uint8_t bb_cpu_buf[520] = { 0 }; | ||
|  | 
 | ||
|  | #if BB_CPU_HW_RING_ENABLE
 | ||
|  | 
 | ||
|  | static bb_cpu_hw_ring_ctxt_t hw_ring_ctxt = {0}; | ||
|  | 
 | ||
|  | static uint8_t bb_cpu_hw_ring_id_get(uint32_t payload_len, uint8_t *ring_id) | ||
|  | { | ||
|  |     uint8_t id; | ||
|  |     uint8_t target_id; | ||
|  |     uint32_t target_ring_sz; | ||
|  |     uint32_t ring_sz; | ||
|  | 
 | ||
|  |     target_id = BB_CPU_HW_RING_ID_INVALID; | ||
|  |     target_ring_sz = 0; | ||
|  |     for (id = 0; id < MAX_RF_RX_RING_NUM; id++) { | ||
|  |         /* check ring is enable */ | ||
|  |         if (!bb_cpu_hw_ring_is_enable(id)) { | ||
|  |             continue; | ||
|  |         } | ||
|  | 
 | ||
|  |         /* check rx buffer valid */ | ||
|  |         if (!bb_cpu_hw_ring_list_get(id)) { | ||
|  |             continue; | ||
|  |         } | ||
|  | 
 | ||
|  |         /* get ring buffer byte size */ | ||
|  |         ring_sz = bb_cpu_hw_ring_sz_get(id); | ||
|  | 
 | ||
|  |         if (payload_len <= ring_sz) { | ||
|  |             if (target_id == BB_CPU_HW_RING_ID_INVALID) { | ||
|  |                 target_id = id; | ||
|  |                 target_ring_sz = ring_sz; | ||
|  |             } else { | ||
|  |                 if (ring_sz < target_ring_sz) { | ||
|  |                     target_id = id; | ||
|  |                     target_ring_sz = ring_sz; | ||
|  |                 } | ||
|  |             } | ||
|  |         } | ||
|  | 
 | ||
|  |         /* TODO: add more select ring buffer method */ | ||
|  |     } | ||
|  | 
 | ||
|  |     if (target_id == BB_CPU_HW_RING_ID_INVALID) { | ||
|  |         return ERR_FAIL; | ||
|  |     } | ||
|  | 
 | ||
|  |     *ring_id = target_id; | ||
|  | 
 | ||
|  |     return ERR_OK; | ||
|  | } | ||
|  | 
 | ||
|  | static uint32_t bb_cpu_hw_ring_widx_get(uint8_t ring_id) | ||
|  | { | ||
|  |     uint32_t widx; | ||
|  | 
 | ||
|  |     switch (ring_id) { | ||
|  |     case 0: | ||
|  |         widx = bb_cpu_hw_ring_reg_wr_idx_get(0, 0); | ||
|  |         break; | ||
|  |     case 1: | ||
|  |         widx = bb_cpu_hw_ring_reg_wr_idx_get(1, 0); | ||
|  |         break; | ||
|  |     case 2: | ||
|  |         widx = bb_cpu_hw_ring_reg_wr_idx_get(2, 0); | ||
|  |         break; | ||
|  |     case 3: | ||
|  |         widx = bb_cpu_hw_ring_reg_wr_idx_get(3, 1); | ||
|  |         break; | ||
|  |     case 4: | ||
|  |         widx = bb_cpu_hw_ring_reg_wr_idx_get(4, 1); | ||
|  |         break; | ||
|  |     case 5: | ||
|  |         widx = bb_cpu_hw_ring_reg_wr_idx_get(5, 1); | ||
|  |         break; | ||
|  |     default: | ||
|  |         IOT_ASSERT(0); | ||
|  |         widx = 0; | ||
|  |         break; | ||
|  |     } | ||
|  | 
 | ||
|  |     return widx; | ||
|  | } | ||
|  | 
 | ||
|  | static void bb_cpu_hw_ring_widx_set(uint8_t ring_id, int32_t offset) | ||
|  | { | ||
|  |     uint32_t tmp, buf_num; | ||
|  | 
 | ||
|  |     int32_t widx; | ||
|  | 
 | ||
|  |     switch (ring_id) { | ||
|  |     case 0: | ||
|  |         tmp = RGF_RF_RX_READ_REG(RX_BUF_RING_WR_IDX_0_ADDR); | ||
|  |         widx = REG_FIELD_GET(RO_RF_RING0_MPDU_BUF_WR_IDX, tmp) + offset; | ||
|  |         buf_num = REG_FIELD_GET(CFG_RF_RING0_BUF_NUM, | ||
|  |             RGF_RF_RX_READ_REG(RF_BUFFER_RING0_1_ADDR)); | ||
|  |         if (widx >= buf_num) { | ||
|  |             widx = 0; | ||
|  |         } | ||
|  |         REG_FIELD_SET(RO_RF_RING0_MPDU_BUF_WR_IDX, tmp, widx); | ||
|  |         RGF_RF_RX_WRITE_REG(RX_BUF_RING_WR_IDX_0_ADDR, tmp); | ||
|  |         break; | ||
|  |     case 1: | ||
|  |         tmp = RGF_RF_RX_READ_REG(RX_BUF_RING_WR_IDX_0_ADDR); | ||
|  |         widx = REG_FIELD_GET(RO_RF_RING1_MPDU_BUF_WR_IDX, tmp) + offset; | ||
|  |         buf_num = REG_FIELD_GET(CFG_RF_RING1_BUF_NUM, | ||
|  |             RGF_RF_RX_READ_REG(RF_BUFFER_RING1_1_ADDR)); | ||
|  |         if (widx >= buf_num) { | ||
|  |             widx = 0; | ||
|  |         } | ||
|  |         REG_FIELD_SET(RO_RF_RING1_MPDU_BUF_WR_IDX, tmp, widx); | ||
|  |         RGF_RF_RX_WRITE_REG(RX_BUF_RING_WR_IDX_0_ADDR, tmp); | ||
|  |         break; | ||
|  |     case 2: | ||
|  |         tmp = RGF_RF_RX_READ_REG(RX_BUF_RING_WR_IDX_0_ADDR); | ||
|  |         widx = REG_FIELD_GET(RO_RF_RING2_MPDU_BUF_WR_IDX, tmp) + offset; | ||
|  |         buf_num = REG_FIELD_GET(CFG_RF_RING2_BUF_NUM, | ||
|  |             RGF_RF_RX_READ_REG(RF_BUFFER_RING2_1_ADDR)); | ||
|  |         if (widx >= buf_num) { | ||
|  |             widx = 0; | ||
|  |         } | ||
|  |         REG_FIELD_SET(RO_RF_RING2_MPDU_BUF_WR_IDX, tmp, widx); | ||
|  |         RGF_RF_RX_WRITE_REG(RX_BUF_RING_WR_IDX_0_ADDR, tmp); | ||
|  |         break; | ||
|  |     case 3: | ||
|  |         tmp = RGF_RF_RX_READ_REG(RX_BUF_RING_WR_IDX_1_ADDR); | ||
|  |         widx = REG_FIELD_GET(RO_RF_RING3_MPDU_BUF_WR_IDX, tmp) + offset; | ||
|  |         buf_num = REG_FIELD_GET(CFG_RF_RING3_BUF_NUM, | ||
|  |             RGF_RF_RX_READ_REG(RF_BUFFER_RING3_1_ADDR)); | ||
|  |         if (widx >= buf_num) { | ||
|  |             widx = 0; | ||
|  |         } | ||
|  |         REG_FIELD_SET(RO_RF_RING3_MPDU_BUF_WR_IDX, tmp, widx); | ||
|  |         RGF_RF_RX_WRITE_REG(RX_BUF_RING_WR_IDX_1_ADDR, tmp); | ||
|  |         break; | ||
|  |     case 4: | ||
|  |         tmp = RGF_RF_RX_READ_REG(RX_BUF_RING_WR_IDX_1_ADDR); | ||
|  |         widx = REG_FIELD_GET(RO_RF_RING4_MPDU_BUF_WR_IDX, tmp) + offset; | ||
|  |         buf_num = REG_FIELD_GET(CFG_RF_RING4_BUF_NUM, | ||
|  |             RGF_RF_RX_READ_REG(RF_BUFFER_RING4_1_ADDR)); | ||
|  |         if (widx >= buf_num) { | ||
|  |             widx = 0; | ||
|  |         } | ||
|  |         REG_FIELD_SET(RO_RF_RING4_MPDU_BUF_WR_IDX, tmp, widx); | ||
|  |         RGF_RF_RX_WRITE_REG(RX_BUF_RING_WR_IDX_1_ADDR, tmp); | ||
|  |         break; | ||
|  |     case 5: | ||
|  |         tmp = RGF_RF_RX_READ_REG(RX_BUF_RING_WR_IDX_1_ADDR); | ||
|  |         widx = REG_FIELD_GET(RO_RF_RING5_MPDU_BUF_WR_IDX, tmp) + offset; | ||
|  |         buf_num = REG_FIELD_GET(CFG_RF_RING5_BUF_NUM, | ||
|  |             RGF_RF_RX_READ_REG(RF_BUFFER_RING5_1_ADDR)); | ||
|  |         if (widx >= buf_num) { | ||
|  |             widx = 0; | ||
|  |         } | ||
|  |         REG_FIELD_SET(RO_RF_RING5_MPDU_BUF_WR_IDX, tmp, widx); | ||
|  |         RGF_RF_RX_WRITE_REG(RX_BUF_RING_WR_IDX_1_ADDR, tmp); | ||
|  |         break; | ||
|  |     default: | ||
|  |         IOT_ASSERT(0); | ||
|  |         break; | ||
|  |     } | ||
|  | } | ||
|  | 
 | ||
|  | static uint8_t *bb_cpu_hw_ring_rx_desc_get(uint8_t ring_id) | ||
|  | { | ||
|  |     uint32_t r_idx, w_idx; | ||
|  |     uint8_t **list; | ||
|  | 
 | ||
|  |     w_idx = bb_cpu_hw_ring_widx_get(ring_id); | ||
|  |     r_idx = bb_cpu_hw_ring_ridx_get(ring_id); | ||
|  | 
 | ||
|  |     /* check watermake */ | ||
|  |     (void)r_idx; | ||
|  | 
 | ||
|  |     list = bb_cpu_hw_ring_list_get(ring_id); | ||
|  | 
 | ||
|  |     return list[w_idx]; | ||
|  | } | ||
|  | 
 | ||
|  | static uint32_t bb_cpu_hw_ring_ctxt_reset(void) | ||
|  | { | ||
|  |     hw_ring_ctxt.ring_id = BB_CPU_HW_RING_ID_INVALID; | ||
|  |     hw_ring_ctxt.enable = 0; | ||
|  |     hw_ring_ctxt.rx_desc = NULL; | ||
|  | 
 | ||
|  |     return ERR_OK; | ||
|  | } | ||
|  | 
 | ||
|  | uint8_t *bb_cpu_hw_ring_select(void *phr_info) | ||
|  | { | ||
|  |     uint8_t ring_id; | ||
|  |     uint32_t pb_sz, pb_num, ret, is_sack = 0; | ||
|  |     uint8_t *rx_desc, *payload_addr = NULL; | ||
|  |     rf_rx_attention *att; | ||
|  |     rf_rx_mpdu_start *mpdu_st; | ||
|  |     rf_rx_mpdu_end *mpdu_ed; | ||
|  |     rf_rx_pb_end *pb_ed; | ||
|  | 
 | ||
|  |     /* reset hw ring context */ | ||
|  |     bb_cpu_hw_ring_ctxt_reset(); | ||
|  | 
 | ||
|  |     if (phr_info) { | ||
|  |         bb_cpu_rf_fc_t fc_msg = {0}; | ||
|  |         bb_cpu_mac_get_msg_from_phr(bb_cpu_get_proto(), phr_info, &fc_msg); | ||
|  | 
 | ||
|  |         if (fc_msg.delimiter == FC_DELIM_BEACON || | ||
|  |             fc_msg.delimiter == FC_DELIM_SOF) { | ||
|  |             pb_num = 1; | ||
|  |             pb_sz = phy_rf_get_pbsz(fc_msg.rf_pb_sz_idx); | ||
|  |         } else if (fc_msg.delimiter == FC_DELIM_SACK) { | ||
|  |             is_sack = 1; | ||
|  |             pb_num = 0; | ||
|  |             pb_sz = 0; | ||
|  |         } else { | ||
|  |             pb_num = 0; | ||
|  |             pb_sz = 0; | ||
|  |         } | ||
|  |     } else { | ||
|  |         pb_num = 0; | ||
|  |         pb_sz = 0; | ||
|  |     } | ||
|  | 
 | ||
|  |     /* sta sack need ring */ | ||
|  |     if (mac_get_hw_role() && is_sack && !mac_rf_get_cert_mode()) { | ||
|  |         return bb_cpu_buf; | ||
|  |     } | ||
|  | 
 | ||
|  |     /* base on phr get ring id */ | ||
|  |     ret = bb_cpu_hw_ring_id_get(pb_num * pb_sz, &ring_id); | ||
|  |     if (ret) { | ||
|  |         /* ring is not enable, not care data.
 | ||
|  |          * use bb_cpu_buf. | ||
|  |          */ | ||
|  |         return bb_cpu_buf; | ||
|  |     } | ||
|  | 
 | ||
|  |     /* get desc address base on ring id */ | ||
|  |     rx_desc = bb_cpu_hw_ring_rx_desc_get(ring_id); | ||
|  | 
 | ||
|  |     IOT_ASSERT(rx_desc); | ||
|  |     att = (rf_rx_attention *)(rx_desc + RF_RX_ATTENTION_OFFSET); | ||
|  |     mpdu_st = (rf_rx_mpdu_start *)(rx_desc + RF_RX_MPDU_START_OFFSET); | ||
|  |     mpdu_ed = (rf_rx_mpdu_end *)(rx_desc + RF_RX_MPDU_END_OFFSET); | ||
|  |     pb_ed = (rf_rx_pb_end *)(rx_desc + RF_RX_PB_END_OFFSET); | ||
|  | 
 | ||
|  |     IOT_ASSERT(att->rx_mpdu_done == 0); | ||
|  |     IOT_ASSERT(mpdu_ed->rx_mpdu_done == 0); | ||
|  |     IOT_ASSERT(pb_ed->rx_pb_done == 0); | ||
|  | 
 | ||
|  |     if (phr_info) { | ||
|  |         /* update info to mpdu start desc */ | ||
|  |         mac_rf_rx_mpdu_st_set_phr(mpdu_st, (uint8_t *)phr_info); | ||
|  |     } | ||
|  | 
 | ||
|  |     hw_ring_ctxt.ring_id = ring_id; | ||
|  |     hw_ring_ctxt.rx_desc = rx_desc; | ||
|  | 
 | ||
|  |     if (pb_num) { | ||
|  |         payload_addr = rx_desc + RF_RX_PB_PAYLOAD_OFFSET; | ||
|  |     } else { | ||
|  |         payload_addr = NULL; | ||
|  |     } | ||
|  | 
 | ||
|  |     hw_ring_ctxt.enable = 1; | ||
|  | 
 | ||
|  |     return payload_addr; | ||
|  | } | ||
|  | 
 | ||
|  | uint32_t bb_cpu_hw_ring_set_rx_status(uint32_t rx_status) | ||
|  | { | ||
|  |     uint8_t *rx_desc; | ||
|  |     rf_rx_attention *att; | ||
|  | 
 | ||
|  |     if (!hw_ring_ctxt.enable) { | ||
|  |         return ERR_FAIL; | ||
|  |     } | ||
|  | 
 | ||
|  |     IOT_ASSERT(hw_ring_ctxt.ring_id != BB_CPU_HW_RING_ID_INVALID); | ||
|  |     rx_desc = hw_ring_ctxt.rx_desc; | ||
|  |     IOT_ASSERT(rx_desc); | ||
|  | 
 | ||
|  |     att = (rf_rx_attention *)(rx_desc + RF_RX_ATTENTION_OFFSET); | ||
|  | 
 | ||
|  |     /* update att status */ | ||
|  |     mac_rf_rx_att_set_rx_status(att, rx_status); | ||
|  | 
 | ||
|  |     return ERR_OK; | ||
|  | } | ||
|  | 
 | ||
|  | uint32_t bb_cpu_hw_ring_set_tx_sack_status(uint32_t tx_sack_status) | ||
|  | { | ||
|  |     uint8_t *rx_desc; | ||
|  |     rf_rx_attention *att; | ||
|  | 
 | ||
|  |     if (!hw_ring_ctxt.enable) { | ||
|  |         return ERR_FAIL; | ||
|  |     } | ||
|  | 
 | ||
|  |     IOT_ASSERT(hw_ring_ctxt.ring_id != BB_CPU_HW_RING_ID_INVALID); | ||
|  |     rx_desc = hw_ring_ctxt.rx_desc; | ||
|  |     IOT_ASSERT(rx_desc); | ||
|  | 
 | ||
|  |     att = (rf_rx_attention *)(rx_desc + RF_RX_ATTENTION_OFFSET); | ||
|  | 
 | ||
|  |     /* update att status */ | ||
|  |     mac_rf_rx_att_set_tx_sack_status(att, tx_sack_status); | ||
|  | 
 | ||
|  |     return ERR_OK; | ||
|  | } | ||
|  | 
 | ||
|  | static uint32_t bb_cpu_hw_judge_pld_ok(void *phr, int16_t *dlt) | ||
|  | { | ||
|  |     int16_t dlt_tmp; | ||
|  |     uint32_t pld_crc = 1, pld_fl_from_rd, pld_fl_from_phr = 0; | ||
|  |     /* pld fl from record, interrupt pld - interrupt phr */ | ||
|  |     pld_fl_from_rd = bb_cpu_mac_get_rx_pld_start_local_ntb() - | ||
|  |         bb_cpu_mac_get_rx_phr_local_ntb(); | ||
|  | 
 | ||
|  |     bb_cpu_rf_fc_t fc_msg = {0}; | ||
|  |     bb_cpu_mac_get_msg_from_phr(bb_cpu_get_proto(), phr, &fc_msg); | ||
|  | 
 | ||
|  |     if (FC_DELIM_BEACON == fc_msg.delimiter || | ||
|  |         FC_DELIM_SOF == fc_msg.delimiter) { | ||
|  |         pld_fl_from_phr = phy_rf_get_g_psdu_fl_ntb(fc_msg.rf_mcs, | ||
|  |             fc_msg.rf_pb_sz_idx); | ||
|  |     } else { | ||
|  |         IOT_ASSERT(0); | ||
|  |     } | ||
|  | 
 | ||
|  |     /* judge */ | ||
|  |     dlt_tmp = pld_fl_from_rd - pld_fl_from_phr; | ||
|  |     if (IOT_ABS(dlt_tmp) <= 5) { | ||
|  |         pld_crc = 0; | ||
|  |     } | ||
|  |     *dlt = dlt_tmp; | ||
|  | 
 | ||
|  |     return pld_crc; | ||
|  | } | ||
|  | 
 | ||
|  | uint32_t bb_cpu_hw_ring_rx_complete_cfg_desc(void) | ||
|  | { | ||
|  |     uint32_t pb_size = 0, pb_crc_invaild = 0; | ||
|  |     uint8_t *rx_desc; | ||
|  |     rf_rx_attention *att; | ||
|  |     rf_rx_mpdu_start *mpdu_st; | ||
|  |     rf_rx_mpdu_end *mpdu_ed; | ||
|  |     rf_rx_pb_start *pb_st; | ||
|  |     rf_rx_pb_end *pb_ed; | ||
|  |     uint8_t *payload, *crc_addr; | ||
|  |     int16_t dlt; | ||
|  | 
 | ||
|  |     if (!hw_ring_ctxt.enable) { | ||
|  |         return ERR_FAIL; | ||
|  |     } | ||
|  | 
 | ||
|  |     IOT_ASSERT(hw_ring_ctxt.ring_id != BB_CPU_HW_RING_ID_INVALID); | ||
|  |     rx_desc = hw_ring_ctxt.rx_desc; | ||
|  |     IOT_ASSERT(rx_desc); | ||
|  | 
 | ||
|  |     att = (rf_rx_attention *)(rx_desc + RF_RX_ATTENTION_OFFSET); | ||
|  |     mpdu_st = (rf_rx_mpdu_start *)(rx_desc + RF_RX_MPDU_START_OFFSET); | ||
|  |     mpdu_ed = (rf_rx_mpdu_end *)(rx_desc + RF_RX_MPDU_END_OFFSET); | ||
|  |     pb_st = (rf_rx_pb_start *)(rx_desc + RF_RX_PB_START_OFFSET); | ||
|  |     pb_ed = (rf_rx_pb_end *)(rx_desc + RF_RX_PB_END_OFFSET); | ||
|  |     payload = (uint8_t *)(rx_desc + RF_RX_PB_PAYLOAD_OFFSET); | ||
|  | 
 | ||
|  |     /* update att desc */ | ||
|  |     switch (mac_rf_rx_att_get_rx_status(att)) { | ||
|  |     case BB_CPU_RX_RING_SIG_ERR: | ||
|  |         att->sig_crc_err = 1; | ||
|  |         break; | ||
|  |     case BB_CPU_RX_RING_PHR_ERR: | ||
|  |     case BB_CPU_RX_RING_PHR_TIMEOUT: | ||
|  |     case BB_CPU_RX_RING_WAIT_PHR_RX_ABORT: | ||
|  |     case BB_CPU_RX_RING_WAIT_PHR_RESET: | ||
|  |         att->phr_crc_err = 1; | ||
|  |         break; | ||
|  |     case BB_CPU_RX_RING_WAIT_PLD_TIMEOUT: | ||
|  |     case BB_CPU_RX_RING_WAIT_PLD_RX_ABORT: | ||
|  |     case BB_CPU_RX_RING_WAIT_PLD_RESET: | ||
|  |     case BB_CPU_RX_RING_WAIT_PLD_RESET_TIMEOUT: | ||
|  |         pb_crc_invaild = 1; | ||
|  |         break; | ||
|  |     default: | ||
|  |         att->sig_crc_err = 0; | ||
|  |         att->phr_crc_err = 0; | ||
|  |         break; | ||
|  |     } | ||
|  | 
 | ||
|  |     if (!att->sig_crc_err) { | ||
|  |         /* SIG info */ | ||
|  |         mac_rf_rx_att_set_phr_mcs(att, bb_rf_get_rx_sig_info()); | ||
|  |     } | ||
|  | 
 | ||
|  |     if (!att->phr_crc_err) { | ||
|  |         /* update mpdu start desc */ | ||
|  |         void *phr = mac_rf_rx_mpdu_st_get_phr_addr(mpdu_st); | ||
|  |         bb_cpu_rf_fc_t fc_msg = {0}; | ||
|  |         bb_cpu_mac_get_msg_from_phr(bb_cpu_get_proto(), phr, &fc_msg); | ||
|  |         /* update pb end desc */ | ||
|  |         switch (fc_msg.delimiter) { | ||
|  |         case FC_DELIM_BEACON: | ||
|  |             mac_rf_rx_att_set_pb_num(att, 1); | ||
|  |             mac_rf_rx_att_set_pld_mcs(att, fc_msg.rf_mcs); | ||
|  |             mac_rf_rx_pb_st_set_rx_pb_cnt(pb_st, 1); | ||
|  |             mac_rf_rx_pb_st_set_pb_sz_idx(pb_st, fc_msg.rf_pb_sz_idx); | ||
|  |             if (pb_crc_invaild) { | ||
|  |                 pb_ed->rx_beacon_pld_crc_err = 1; | ||
|  |                 pb_ed->rx_pb_crc_err = 1; | ||
|  |                 mac_rf_rx_pb_end_set_mismatch_dlt(pb_ed, 0); | ||
|  |             } else { | ||
|  |                 pb_size = phy_rf_get_pbsz(fc_msg.rf_pb_sz_idx); | ||
|  |                 crc_addr = (uint8_t *)(payload + pb_size - SG_BCN_PB_CRC_LEN); | ||
|  |                 pb_ed->pb_crc = (uint32_t)crc_addr[0] + | ||
|  |                     ((uint32_t)crc_addr[1] << 8) + ((uint32_t)crc_addr[2] << 16); | ||
|  |                 pb_ed->rx_beacon_pld_crc_err = !!bb_rf_get_pld_crc32_err(); | ||
|  |                 pb_ed->rx_pb_crc_err = !!bb_rf_get_pld_crc24_err(); | ||
|  |                 if (pb_ed->rx_pb_crc_err == 0) { | ||
|  |                     //pb_ed->rx_pb_crc_err = bb_cpu_hw_judge_pld_ok(phr, &dlt);
 | ||
|  |                     bb_cpu_hw_judge_pld_ok(phr, &dlt); | ||
|  |                     mac_rf_rx_pb_end_set_mismatch_dlt(pb_ed, dlt); | ||
|  |                 } | ||
|  |             } | ||
|  |             break; | ||
|  |         case FC_DELIM_SOF: | ||
|  |             mac_rf_rx_att_set_pb_num(att, 1); | ||
|  |             mac_rf_rx_att_set_pld_mcs(att, fc_msg.rf_mcs); | ||
|  |             mac_rf_rx_pb_st_set_rx_pb_cnt(pb_st, 1); | ||
|  |             mac_rf_rx_pb_st_set_pb_sz_idx(pb_st, fc_msg.rf_pb_sz_idx); | ||
|  |             mac_rf_rx_pb_st_set_first_pb(pb_st, 1); | ||
|  |             mac_rf_rx_pb_st_set_last_pb(pb_st, 1); | ||
|  |             if (pb_crc_invaild) { | ||
|  |                 pb_ed->rx_pb_crc_err = 1; | ||
|  |                 mac_rf_rx_pb_end_set_mismatch_dlt(pb_ed, 0); | ||
|  |             } else { | ||
|  |                 /* update pb start desc */ | ||
|  |                 pb_size = phy_rf_get_pbsz(fc_msg.rf_pb_sz_idx); | ||
|  | #if SUPPORT_SMART_GRID
 | ||
|  |                 if (PLC_PROTO_TYPE_SG == bb_cpu_get_proto()) { | ||
|  |                     sg_sof_pb_hdr_t *pb_hdr = (sg_sof_pb_hdr_t *)payload; | ||
|  |                     mac_rf_rx_pb_st_set_pb_ssn(pb_st, pb_hdr->seq); | ||
|  |                     mac_rf_rx_pb_st_set_msdu_start(pb_st, | ||
|  |                         pb_hdr->mac_frame_start); | ||
|  |                     mac_rf_rx_pb_st_set_msdu_end(pb_st, pb_hdr->mac_frame_end); | ||
|  |                     crc_addr = | ||
|  |                         (uint8_t *)(payload + pb_size - SG_SOF_PB_CRC_LEN); | ||
|  |                     pb_ed->pb_crc = (uint32_t)crc_addr[0] + | ||
|  |                         ((uint32_t)crc_addr[1] << 8) + | ||
|  |                         ((uint32_t)crc_addr[2] << 16); | ||
|  |                     if (!mac_rf_get_pb_hdr_to_buf()) { | ||
|  |                         os_mem_cpy(payload, payload + SG_SOF_PB_HDR_LEN, | ||
|  |                             pb_size - SG_SOF_PB_HDR_LEN); | ||
|  |                     } | ||
|  |                 } else | ||
|  | #endif
 | ||
|  | #if SUPPORT_SOUTHERN_POWER_GRID
 | ||
|  |                 if (PLC_PROTO_TYPE_SPG == bb_cpu_get_proto()) { | ||
|  |                     /* update pb start desc */ | ||
|  |                     spg_sof_pb_hdr_t *pb_hdr = (spg_sof_pb_hdr_t *)payload; | ||
|  |                     mac_rf_rx_pb_st_set_pb_ssn(pb_st, pb_hdr->seq); | ||
|  |                     mac_rf_rx_pb_st_set_msdu_start(pb_st, 1); | ||
|  |                     mac_rf_rx_pb_st_set_msdu_end(pb_st, 1); | ||
|  |                     crc_addr = | ||
|  |                         (uint8_t *)(payload + pb_size - SPG_SOF_PB_CRC_LEN); | ||
|  |                     pb_ed->pb_crc = (uint32_t)crc_addr[0] + | ||
|  |                         ((uint32_t)crc_addr[1] << 8) + | ||
|  |                         ((uint32_t)crc_addr[2] << 16); | ||
|  |                     if (!mac_rf_get_pb_hdr_to_buf()) { | ||
|  |                         os_mem_cpy(payload, payload + SPG_SOF_PB_HDR_LEN, | ||
|  |                             pb_size - SPG_SOF_PB_HDR_LEN); | ||
|  |                     } | ||
|  |                 } else | ||
|  | #endif
 | ||
|  |                 { | ||
|  |                     //do not delete this case
 | ||
|  |                 } | ||
|  | 
 | ||
|  |                 pb_ed->rx_pb_crc_err = !!bb_rf_get_pld_crc24_err(); | ||
|  |                 if (pb_ed->rx_pb_crc_err == 0) { | ||
|  |                     //pb_ed->rx_pb_crc_err = bb_cpu_hw_judge_pld_ok(phr, &dlt);
 | ||
|  |                     bb_cpu_hw_judge_pld_ok(phr, &dlt); | ||
|  |                     mac_rf_rx_pb_end_set_mismatch_dlt(pb_ed, dlt); | ||
|  |                 } | ||
|  |             } | ||
|  |             break; | ||
|  |         case FC_DELIM_SACK: | ||
|  |             pb_ed->rx_beacon_pld_crc_err = 0; | ||
|  |             pb_ed->rx_pb_crc_err = 0; | ||
|  |             pb_ed->pb_crc = 0; | ||
|  |             break; | ||
|  |         default: | ||
|  |             break; | ||
|  |         } | ||
|  |     } | ||
|  |     mac_rf_rx_att_set_channel_id(att, mac_rf_get_cur_channel_id()); | ||
|  |     mac_rf_rx_att_set_option(att, mac_rf_get_option()); | ||
|  | 
 | ||
|  |     /* update mpdu end desc */ | ||
|  |     mpdu_ed->ntb_timestamp = bb_cpu_mac_get_rx_stf_ntb() - | ||
|  |         BB_CPU_RX_GOLDEN_GAP(mac_rf_get_option()); | ||
|  |     mpdu_ed->local_timestamp = bb_cpu_mac_get_rx_stf_local_ntb() - | ||
|  |         BB_CPU_RX_GOLDEN_GAP(mac_rf_get_option()); | ||
|  | 
 | ||
|  |     return ERR_OK; | ||
|  | } | ||
|  | 
 | ||
|  | uint32_t bb_cpu_hw_ring_rx_done_set(void) | ||
|  | { | ||
|  |     rf_rx_attention *att; | ||
|  |     rf_rx_mpdu_end *mpdu_ed; | ||
|  |     rf_rx_pb_end *pb_ed; | ||
|  | 
 | ||
|  |     if (!hw_ring_ctxt.enable) { | ||
|  |         bb_cpu_hw_ring_ctxt_reset(); | ||
|  |         return ERR_FAIL; | ||
|  |     } | ||
|  | 
 | ||
|  |     IOT_ASSERT(hw_ring_ctxt.ring_id != BB_CPU_HW_RING_ID_INVALID); | ||
|  | 
 | ||
|  |     /* update rx done */ | ||
|  |     att = (rf_rx_attention *)(hw_ring_ctxt.rx_desc + RF_RX_ATTENTION_OFFSET); | ||
|  |     mpdu_ed = (rf_rx_mpdu_end *)(hw_ring_ctxt.rx_desc + RF_RX_MPDU_END_OFFSET); | ||
|  |     pb_ed = (rf_rx_pb_end *)(hw_ring_ctxt.rx_desc + RF_RX_PB_END_OFFSET); | ||
|  | 
 | ||
|  |     att->rx_mpdu_done = 1; | ||
|  |     mpdu_ed->rx_mpdu_done = 1; | ||
|  |     pb_ed->rx_pb_done = 1; | ||
|  | 
 | ||
|  |     /* update write idx */ | ||
|  |     bb_cpu_hw_ring_widx_set(hw_ring_ctxt.ring_id, 1); | ||
|  | 
 | ||
|  |     /* notify plc cpu rx done */ | ||
|  |     bb_cpu_mac_set_share_irq_to_maincpu(hw_ring_ctxt.ring_id + | ||
|  |         RF_MAC_INT_RX_RING_BIT_OFFSET); | ||
|  |     bb_cpu_mac_set_sw_irq_to_maincpu(RF_MAC_SW_ISR_RX_MPDU_COMPLETE); | ||
|  | 
 | ||
|  |     bb_cpu_hw_ring_ctxt_reset(); | ||
|  | 
 | ||
|  |     return ERR_OK; | ||
|  | } | ||
|  | 
 | ||
|  | #if HPLC_BBCPU_CALC_SNR_RSSI
 | ||
|  | 
 | ||
|  | void bb_cpu_hw_ring_snr_set(int8_t snr) | ||
|  | { | ||
|  |     rf_rx_mpdu_start *mpdu_st; | ||
|  | 
 | ||
|  |     if (!hw_ring_ctxt.enable) { | ||
|  |         return; | ||
|  |     } | ||
|  | 
 | ||
|  |     mpdu_st = (rf_rx_mpdu_start *)(hw_ring_ctxt.rx_desc | ||
|  |         + RF_RX_MPDU_START_OFFSET); | ||
|  |     mac_rf_rx_mpdu_st_set_avg_snr(mpdu_st, snr); | ||
|  | } | ||
|  | 
 | ||
|  | void bb_cpu_hw_ring_raw_snr_set(uint16_t snr) | ||
|  | { | ||
|  |     rf_rx_mpdu_start *mpdu_st; | ||
|  | 
 | ||
|  |     if (!hw_ring_ctxt.enable) { | ||
|  |         return; | ||
|  |     } | ||
|  | 
 | ||
|  |     mpdu_st = (rf_rx_mpdu_start *)(hw_ring_ctxt.rx_desc | ||
|  |         + RF_RX_MPDU_START_OFFSET); | ||
|  |     mac_rf_rx_mpdu_st_set_raw_snr(mpdu_st, snr); | ||
|  | } | ||
|  | 
 | ||
|  | void bb_cpu_hw_ring_rssi_set(int8_t rssi) | ||
|  | { | ||
|  |     rf_rx_mpdu_start *mpdu_st; | ||
|  | 
 | ||
|  |     if (!hw_ring_ctxt.enable) { | ||
|  |         return; | ||
|  |     } | ||
|  | 
 | ||
|  |     mpdu_st = (rf_rx_mpdu_start *)(hw_ring_ctxt.rx_desc | ||
|  |         + RF_RX_MPDU_START_OFFSET); | ||
|  |     mac_rf_rx_mpdu_st_set_rssi(mpdu_st, rssi); | ||
|  | } | ||
|  | 
 | ||
|  | void bb_cpu_hw_ring_rx_gain_set(uint8_t rx_gain) | ||
|  | { | ||
|  |     rf_rx_mpdu_start *mpdu_st; | ||
|  | 
 | ||
|  |     if (!hw_ring_ctxt.enable) { | ||
|  |         return; | ||
|  |     } | ||
|  | 
 | ||
|  |     mpdu_st = (rf_rx_mpdu_start *)(hw_ring_ctxt.rx_desc | ||
|  |         + RF_RX_MPDU_START_OFFSET); | ||
|  |     mac_rf_rx_mpdu_st_set_rx_gain(mpdu_st, rx_gain); | ||
|  | } | ||
|  | 
 | ||
|  | #else /* HPLC_BBCPU_CALC_SNR_RSSI */
 | ||
|  | 
 | ||
|  | void bb_cpu_hw_ring_raw_snr_rssi_set(uint32_t raw_snr_rssi_reg1, | ||
|  |     uint32_t raw_snr_rssi_reg2, uint32_t raw_snr_rssi_reg3) | ||
|  | { | ||
|  |     rf_rx_mpdu_start *mpdu_st; | ||
|  | 
 | ||
|  |     if (!hw_ring_ctxt.enable) { | ||
|  |         return; | ||
|  |     } | ||
|  | 
 | ||
|  |     mpdu_st = (rf_rx_mpdu_start *)(hw_ring_ctxt.rx_desc | ||
|  |         + RF_RX_MPDU_START_OFFSET); | ||
|  |     mac_rf_rx_mpdu_st_set_raw_snr_rssi_reg1(mpdu_st, raw_snr_rssi_reg1); | ||
|  |     mac_rf_rx_mpdu_st_set_raw_snr_rssi_reg2(mpdu_st, raw_snr_rssi_reg2); | ||
|  |     mac_rf_rx_mpdu_st_set_raw_snr_rssi_reg3(mpdu_st, raw_snr_rssi_reg3); | ||
|  | } | ||
|  | 
 | ||
|  | #endif /* HPLC_BBCPU_CALC_SNR_RSSI */
 | ||
|  | 
 | ||
|  | void bb_cpu_hw_ring_rx_ppmhz_set(int32_t rx_ppm_hz) | ||
|  | { | ||
|  |     rf_rx_mpdu_start *mpdu_st; | ||
|  | 
 | ||
|  |     if (!hw_ring_ctxt.enable) { | ||
|  |         return; | ||
|  |     } | ||
|  | 
 | ||
|  |     mpdu_st = (rf_rx_mpdu_start *)(hw_ring_ctxt.rx_desc | ||
|  |         + RF_RX_MPDU_START_OFFSET); | ||
|  |     mac_rf_rx_mpdu_st_set_rx_ppmhz(mpdu_st, rx_ppm_hz); | ||
|  | } | ||
|  | 
 | ||
|  | void bb_cpu_hw_ring_init(void) | ||
|  | { | ||
|  |     //TODO: add init ring buffer reg code
 | ||
|  | 
 | ||
|  |     bb_cpu_hw_ring_ctxt_reset(); | ||
|  | } | ||
|  | 
 | ||
|  | #else /* !BB_CPU_HW_RING_ENABLE */
 | ||
|  | 
 | ||
|  | uint8_t *bb_cpu_hw_ring_select(void *phr_info) | ||
|  | { | ||
|  |     (void)phr_info; | ||
|  |     return bb_cpu_buf; | ||
|  | } | ||
|  | 
 | ||
|  | uint32_t bb_cpu_hw_ring_set_rx_status(uint32_t rx_status) | ||
|  | { | ||
|  |     (void)rx_status; | ||
|  |     return ERR_OK; | ||
|  | } | ||
|  | 
 | ||
|  | uint32_t bb_cpu_hw_ring_set_tx_sack_status(uint32_t tx_sack_status) | ||
|  | { | ||
|  |     (void)rx_status; | ||
|  |     return ERR_OK; | ||
|  | } | ||
|  | 
 | ||
|  | uint32_t bb_cpu_hw_ring_rx_complete_cfg_desc(void) | ||
|  | { | ||
|  |     return ERR_OK; | ||
|  | } | ||
|  | 
 | ||
|  | uint32_t bb_cpu_hw_ring_rx_done_set(void) | ||
|  | { | ||
|  |     uint32_t ring_id = 0; | ||
|  |     bb_cpu_mac_set_share_irq_to_maincpu(ring_id + RF_MAC_INT_RX_RING_BIT_OFFSET); | ||
|  |     bb_cpu_mac_set_sw_irq_to_maincpu(RF_MAC_SW_ISR_RX_MPDU_COMPLETE); | ||
|  |     return ERR_OK; | ||
|  | } | ||
|  | 
 | ||
|  | void bb_cpu_hw_ring_snr_set(int8_t snr) | ||
|  | { | ||
|  |     (void)snr; | ||
|  | } | ||
|  | 
 | ||
|  | void bb_cpu_hw_ring_raw_snr_set(uint16_t snr) | ||
|  | { | ||
|  |     (void)snr; | ||
|  | } | ||
|  | 
 | ||
|  | void bb_cpu_hw_ring_rssi_set(int8_t rssi) | ||
|  | { | ||
|  |     (void)rssi; | ||
|  | } | ||
|  | 
 | ||
|  | void bb_cpu_hw_ring_rx_gain_set(uint8_t rx_gain) | ||
|  | { | ||
|  |     (void)rx_gain; | ||
|  | } | ||
|  | 
 | ||
|  | void bb_cpu_hw_ring_rx_ppmhz_set(int32_t rx_ppm_hz) | ||
|  | { | ||
|  |     (void)rx_ppm_hz; | ||
|  | } | ||
|  | 
 | ||
|  | void bb_cpu_hw_ring_init(void) | ||
|  | { | ||
|  | } | ||
|  | 
 | ||
|  | #endif /* BB_CPU_HW_RING_ENABLE */
 |