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