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 */
 |