431 lines
		
	
	
		
			12 KiB
		
	
	
	
		
			C
		
	
	
		
			Executable File
		
	
	
	
	
			
		
		
	
	
			431 lines
		
	
	
		
			12 KiB
		
	
	
	
		
			C
		
	
	
		
			Executable File
		
	
	
	
	
/****************************************************************************
 | 
						|
 | 
						|
Copyright(c) 2019 by Aerospace C.Power (Chongqing) Microelectronics. ALL RIGHTS RESERVED.
 | 
						|
 | 
						|
This Information is proprietary to Aerospace C.Power (Chongqing) Microelectronics and MAY NOT
 | 
						|
be copied by any method or incorporated into another program without
 | 
						|
the express written consent of Aerospace C.Power. This Information or any portion
 | 
						|
thereof remains the property of Aerospace C.Power. The Information contained herein
 | 
						|
is believed to be accurate and Aerospace C.Power assumes no responsibility or
 | 
						|
liability for its use in any way and conveys no license or title under
 | 
						|
any patent or copyright and makes no representation or warranty that this
 | 
						|
Information is free from patent or copyright infringement.
 | 
						|
 | 
						|
****************************************************************************/
 | 
						|
 | 
						|
#ifndef MAC_RX_BUF_RING_H
 | 
						|
#define MAC_RX_BUF_RING_H
 | 
						|
#include "iot_pkt_api.h"
 | 
						|
#include "os_types.h"
 | 
						|
#include "mac_dma.h"
 | 
						|
#include "plc_fr.h"
 | 
						|
#include "rx_mpdu_start.h"
 | 
						|
 | 
						|
#ifdef __cplusplus
 | 
						|
extern "C" {
 | 
						|
#endif
 | 
						|
 | 
						|
#define MAC_RX_DEBUG_CFG            0x320
 | 
						|
#define MAC_SG_DELIM_TMR_BAND0      770
 | 
						|
#define MAC_SG_DELIM_TMR_BAND1      1220
 | 
						|
 | 
						|
/* max wait time ms for rx mpdu handler
 | 
						|
 * this can be very large, means wait for ever
 | 
						|
 * currently set to max for only used when stop vdev
 | 
						|
 */
 | 
						|
#define MAX_RX_QUOTA_MS             (0xffffffff)
 | 
						|
 | 
						|
/* for rx msdu */
 | 
						|
#define RX_MSDU_END_OFFSET sizeof(rx_msdu_start)
 | 
						|
#define RX_FC_OFFSET (RX_MSDU_END_OFFSET + sizeof(rx_msdu_end))
 | 
						|
#define RX_PAYLOAD_OFFSET (RX_FC_OFFSET + FC_LEN)
 | 
						|
/* for rx mpdu */
 | 
						|
#define RX_ATTENTION_OFFSET 0
 | 
						|
#define MPDU_START_OFFSET (RX_ATTENTION_OFFSET + sizeof(rx_attention))
 | 
						|
#define MPDU_END_OFFSET (MPDU_START_OFFSET + sizeof(rx_mpdu_start))
 | 
						|
#define PB_START_OFFSET (MPDU_END_OFFSET + sizeof(rx_mpdu_end))
 | 
						|
#define PB_END_OFFSET (PB_START_OFFSET + sizeof(rx_pb_start))
 | 
						|
#define PB_PAYLOAD_OFFSET (PB_END_OFFSET + sizeof(rx_pb_end))
 | 
						|
 | 
						|
#define RX_RING_GET_RD_IDX(ring_id) \
 | 
						|
     REG_FIELD_GET(CFG_RING##ring_id##_RD_IDX, \
 | 
						|
        RGF_RX_READ_REG(CFG_BUFFER_RING##ring_id##_2_ADDR))
 | 
						|
 | 
						|
#define RX_RING_SET_RD_IDX(ring_id, value) \
 | 
						|
    do { \
 | 
						|
        uint32_t tmp = RGF_RX_READ_REG( \
 | 
						|
            CFG_BUFFER_RING##ring_id##_2_ADDR); \
 | 
						|
        REG_FIELD_SET(CFG_RING##ring_id##_RD_IDX, \
 | 
						|
            tmp, value); \
 | 
						|
        RGF_RX_WRITE_REG(CFG_BUFFER_RING##ring_id##_2_ADDR, tmp); \
 | 
						|
    } while (0)
 | 
						|
 | 
						|
#define RX_RING_GET_WR_IDX(ring_id) \
 | 
						|
     REG_FIELD_GET(RO_RING##ring_id##_WR_IDX, \
 | 
						|
        RGF_RX_READ_REG(CFG_BUFFER_RING##ring_id##_2_ADDR))
 | 
						|
 | 
						|
#define rx_ring_get_wr_idx_macro(rid) \
 | 
						|
    REG_FIELD_GET(RO_RING0_WR_IDX, \
 | 
						|
        (RGF_RX_READ_REG(CFG_BUFFER_RING0_2_ADDR + \
 | 
						|
            (rid) * (CFG_BUFFER_RING1_2_ADDR - CFG_BUFFER_RING0_2_ADDR))))
 | 
						|
 | 
						|
#define RX_RING_GET_MPDU_WR_IDX(rid, reg_idx) \
 | 
						|
    REG_FIELD_GET(RO_RING##rid##_MPDU_BUF_WR_IDX, \
 | 
						|
        RGF_RX_READ_REG(CFG_RX_BUF_MPDU_WR_IDX_##reg_idx##_ADDR))
 | 
						|
 | 
						|
#define RX_RING_GET_RING_PTR(ring_id) \
 | 
						|
    REG_FIELD_GET(CFG_RING##ring_id##_PTR, \
 | 
						|
        RGF_RX_READ_REG(CFG_BUFFER_RING##ring_id##_0_ADDR))
 | 
						|
 | 
						|
#define RX_RING_SET_FILTER_SEL(ring_id, value) \
 | 
						|
    do { \
 | 
						|
        uint32_t tmp = RGF_RX_READ_REG( \
 | 
						|
            CFG_BUFFER_RING##ring_id##_1_ADDR); \
 | 
						|
        REG_FIELD_SET(CFG_RING##ring_id##_BUF_SIZE_FILTER_SEL, \
 | 
						|
            tmp, value); \
 | 
						|
        RGF_RX_WRITE_REG(CFG_BUFFER_RING##ring_id##_1_ADDR, tmp); \
 | 
						|
    } while (0)
 | 
						|
#define RX_RING_SET_FILTER(ring_id, value) \
 | 
						|
        do { \
 | 
						|
            uint32_t tmp = RGF_RX_READ_REG( \
 | 
						|
                CFG_BUFFER_RING##ring_id##_1_ADDR); \
 | 
						|
            REG_FIELD_SET(CFG_RING##ring_id##_FILTER, \
 | 
						|
                tmp, value); \
 | 
						|
            RGF_RX_WRITE_REG(CFG_BUFFER_RING##ring_id##_1_ADDR, tmp); \
 | 
						|
        } while (0)
 | 
						|
 | 
						|
typedef enum _ring_id {
 | 
						|
    PLC_RING_0 = 0,  //0
 | 
						|
 | 
						|
    PLC_RING_1 ,    //1
 | 
						|
    PLC_CONTROL_RING = PLC_RING_1,
 | 
						|
 | 
						|
    PLC_RING_2 ,    //2
 | 
						|
    PLC_SOF_RING = PLC_RING_2,
 | 
						|
 | 
						|
    PLC_RING_3 ,    //3
 | 
						|
    PLC_RING_4 ,    //4
 | 
						|
    MAX_PLC_RX_RING_NUM ,
 | 
						|
} ring_id_t;
 | 
						|
 | 
						|
typedef uint32_t (*rx_low_watermark_callback)(void *ring);
 | 
						|
 | 
						|
typedef enum _config_type {
 | 
						|
    CONFIG_RX_DESC = 0,
 | 
						|
    CONFIG_RX_ATTENTION = 0,
 | 
						|
    CONFIG_RX_MPDU_START,
 | 
						|
    CONFIG_RX_MPDU_END,
 | 
						|
    CONFIG_RX_PB_START,
 | 
						|
    CONFIG_RX_PB_END,
 | 
						|
    CONFIG_RX_MSDU_START = CONFIG_RX_MPDU_START,
 | 
						|
    CONFIG_RX_MSDU_END = CONFIG_RX_MPDU_END,
 | 
						|
    CONFIG_FC = CONFIG_RX_PB_END + 1,
 | 
						|
    CONFIG_PAYLOAD,
 | 
						|
    CONFIG_MAX_NUM,
 | 
						|
} config_type;
 | 
						|
 | 
						|
typedef struct _ring_config {
 | 
						|
    config_type type;
 | 
						|
    /*offset of this type in rx ring buffer*/
 | 
						|
    uint32_t offset;
 | 
						|
    /*this type enabled or not*/
 | 
						|
    uint8_t enable;
 | 
						|
}ring_config;
 | 
						|
 | 
						|
/* rx buf overall desc structure */
 | 
						|
typedef struct _rx_buf_hdr {
 | 
						|
    rx_attention att;
 | 
						|
    rx_mpdu_start mpdu_st;
 | 
						|
    rx_mpdu_end mpdu_ed;
 | 
						|
    rx_pb_start pb_st;
 | 
						|
    rx_pb_end pb_ed;
 | 
						|
} rx_buf_hdr_t;
 | 
						|
 | 
						|
/* save sof information for sack interrupting  */
 | 
						|
typedef struct _sof_rx_info {
 | 
						|
    uint32_t  fc[4];
 | 
						|
    rx_attention att;
 | 
						|
    int8_t snr;
 | 
						|
} sof_rx_info_t;
 | 
						|
 | 
						|
typedef struct _rx_buf_ring {
 | 
						|
#if HW_PLATFORM == HW_PLATFORM_SIMU
 | 
						|
    uint32_t enabled;
 | 
						|
#endif
 | 
						|
    /* buffer ring/simulator hw implementation */
 | 
						|
    uint8_t **buf_list;
 | 
						|
    /* hw ring id */
 | 
						|
    uint32_t ring_id;
 | 
						|
    /* ring size */
 | 
						|
    uint32_t ring_sz;
 | 
						|
    /* read index */
 | 
						|
    uint32_t read_idx;
 | 
						|
    /* write index */
 | 
						|
    uint32_t write_idx;
 | 
						|
    /* size for attached buf on this ring */
 | 
						|
    uint32_t buf_sz;
 | 
						|
    /* water mark */
 | 
						|
    uint32_t water_mark_buf_num : 16,
 | 
						|
        overflow : 1,
 | 
						|
        cfg_enabled : 1,
 | 
						|
        bufsz_filter_sel : 1,
 | 
						|
        filter : 4,
 | 
						|
        msg_delivered : 1,
 | 
						|
        not_done : 4,
 | 
						|
        resv : 4;
 | 
						|
    /*ring config*/
 | 
						|
    ring_config config[CONFIG_MAX_NUM];
 | 
						|
    /* low buf alert callback */
 | 
						|
    rx_low_watermark_callback cb;
 | 
						|
    /* rx ctxt, for storing mpdu's first pb */
 | 
						|
    rx_mpdu_start *cur_mpdu;
 | 
						|
    rx_mpdu_start saved_mpdu_st;
 | 
						|
} rx_buf_ring_t;
 | 
						|
 | 
						|
typedef uint32_t(*mac_recv_mpdu_pb_func_t)(void *arg, iot_pkt_t *rx_buf);
 | 
						|
 | 
						|
typedef struct _mac_rx_ring_ctxt
 | 
						|
{
 | 
						|
    rx_buf_ring_t ring[MAX_PLC_RX_RING_NUM];
 | 
						|
    mac_recv_mpdu_pb_func_t mpdu_pb_cb;
 | 
						|
} mac_rx_ring_ctxt_t;
 | 
						|
 | 
						|
void rx_buf_ring_set_callback(mac_rx_ring_ctxt_t *ring_ctxt, \
 | 
						|
    mac_recv_mpdu_pb_func_t cb);
 | 
						|
 | 
						|
/* init and put on the buf_list */
 | 
						|
uint32_t rx_buf_ring_init(rx_buf_ring_t *rx_ring, uint32_t ring_id,
 | 
						|
    uint32_t ring_sz, uint32_t buf_sz, rx_low_watermark_callback cb,
 | 
						|
    ring_config *cfg,uint8_t bufsz_filter_sel, uint8_t filter);
 | 
						|
 | 
						|
/* reap an buf from the ring
 | 
						|
 * (IN) rx_ring
 | 
						|
 * (IN) num - the num plc buf to get, it should <= sizeof(buf_array)
 | 
						|
 * (OUT) buf_array - iot_pkt_t pointer's array to get from the ring
 | 
						|
 * return - the num of buf popped out
 | 
						|
 */
 | 
						|
uint32_t pop_buf_from_ring(rx_buf_ring_t *rx_ring, uint32_t num,
 | 
						|
    iot_pkt_t **buf_array);
 | 
						|
 | 
						|
#if HW_PLATFORM == HW_PLATFORM_SIMU
 | 
						|
/* push an buf to the ring
 | 
						|
 * (IN) rx_ring
 | 
						|
 * (IN) buf_array - an array of bufs to write into the rx_ring
 | 
						|
 * (IN) num - how many of the array item
 | 
						|
 * return - 0 for good, others for error
 | 
						|
 */
 | 
						|
uint32_t push_buf_to_ring(rx_buf_ring_t *rx_ring,
 | 
						|
    dma_frag_t **buf_array, uint32_t num);
 | 
						|
 | 
						|
/* push an offset buf to the ring
 | 
						|
* (IN) rx_ring
 | 
						|
* (IN) index - write index
 | 
						|
* (IN) offset - the offset of rx ring buffer to receive the content
 | 
						|
* (IN) data - the source content
 | 
						|
* (IN) len - the length of the source content
 | 
						|
* return - 0 for good, others for error
 | 
						|
*/
 | 
						|
uint32_t push_data_to_ring_with_offset(rx_buf_ring_t *rx_ring, uint32_t index,
 | 
						|
    uint32_t offset, void* data, uint32_t len);
 | 
						|
 | 
						|
#endif
 | 
						|
 | 
						|
uint32_t mac_rx_get_bcn_swcrc_cfg(void);
 | 
						|
 | 
						|
void mac_rx_set_bcn_swcrc_cfg(uint32_t is_by_sw);
 | 
						|
 | 
						|
uint32_t mac_rx_get_pb_hdr_to_buf_cfg(void);
 | 
						|
 | 
						|
void mac_rx_set_pb_hdr_to_buf_cfg(uint32_t is_to_buf);
 | 
						|
 | 
						|
/* set water mark */
 | 
						|
uint32_t rx_ring_set_watermark(rx_buf_ring_t *rx_ring, uint32_t num);
 | 
						|
 | 
						|
/* get water mark
 | 
						|
 * retrun - water mark value
 | 
						|
 */
 | 
						|
uint32_t rx_ring_get_watermark(rx_buf_ring_t *rx_ring);
 | 
						|
 | 
						|
 | 
						|
bool_t is_rx_ring_under_watermark(rx_buf_ring_t *rx_ring);
 | 
						|
 | 
						|
bool_t rx_ring_space_avaliable(rx_buf_ring_t *rx_ring, uint32_t num);
 | 
						|
 | 
						|
void mac_rx_ring_enable(rx_buf_ring_t *rx_ring, uint32_t enable);
 | 
						|
 | 
						|
void mac_rx_all_ring_enable(void *pdev_ptr);
 | 
						|
void mac_rx_all_ring_disable(void *pdev_ptr);
 | 
						|
 | 
						|
 | 
						|
/* get ring rd idx */
 | 
						|
uint32_t rx_ring_get_rd_idx(rx_buf_ring_t *rx_ring);
 | 
						|
 | 
						|
/* set ring rd idx */
 | 
						|
void rx_ring_set_rd_idx(rx_buf_ring_t *rx_ring, uint32_t value);
 | 
						|
 | 
						|
/* get ring rd idx */
 | 
						|
uint32_t rx_ring_get_wr_idx(rx_buf_ring_t *rx_ring);
 | 
						|
 | 
						|
/* init the ctxt of rx ring */
 | 
						|
uint32_t mac_rx_ring_ctxt_init(mac_rx_ring_ctxt_t *ring_ctxt);
 | 
						|
 | 
						|
uint32_t rx_ring_get_mpdu_int_status();
 | 
						|
 | 
						|
void mac_rx_set_filter(uint32_t filter_type, uint8_t en);
 | 
						|
 | 
						|
/* clear the mpdu rx int */
 | 
						|
void rx_ring_clr_mpdu_int(uint32_t rid);
 | 
						|
 | 
						|
uint32_t rx_ring_get_overflow_status();
 | 
						|
 | 
						|
void rx_ring_clr_overflow_int(uint32_t rid);
 | 
						|
 | 
						|
uint8_t rx_ring_set_filter_sel(rx_buf_ring_t *rx_ring);
 | 
						|
uint8_t rx_ring_set_filter(rx_buf_ring_t *rx_ring);
 | 
						|
 | 
						|
void mac_rx_timeout_act_hang(uint32_t enable);
 | 
						|
 | 
						|
void mac_rx_abort_act_hang(uint32_t enable);
 | 
						|
 | 
						|
void mac_set_trans_done_selection(uint32_t cfg);
 | 
						|
 | 
						|
void mac_rx_pb_timeout(uint32_t time_40ns);
 | 
						|
 | 
						|
void mac_rx_gp_proto_band_set(void);
 | 
						|
 | 
						|
/* called in the isr for WAR */
 | 
						|
uint32_t mac_rx_hw_isr_callback();
 | 
						|
 | 
						|
/**
 | 
						|
 * @brief mac_set_debug_reg(uint32_t value) - config debug register.
 | 
						|
 * @param  null
 | 
						|
 */
 | 
						|
void mac_set_debug_reg(uint32_t value);
 | 
						|
 | 
						|
/**
 | 
						|
 * @brief mac_rx_get_debug_reg - get debug register.
 | 
						|
 * @param  value      value
 | 
						|
 */
 | 
						|
uint32_t mac_rx_get_debug_reg();
 | 
						|
 | 
						|
/**
 | 
						|
 * @brief mac_rx_set_delim()             - set delimiter timer rob0.
 | 
						|
 * @param  proto_band_id                   proto_band_id
 | 
						|
 * @param  phy_rate_id                     rate_id,
 | 
						|
 */
 | 
						|
void mac_rx_set_delim(uint32_t proto_band_id, uint32_t rate_id);
 | 
						|
 | 
						|
/**
 | 
						|
 * @brief  mac_rx_get_delim()            - get sg delimiter timer
 | 
						|
 * @param  phy_rate_id                     rate_id,
 | 
						|
 * @param  hw_band_id                      hw_band_id
 | 
						|
 * @return                                 delimiter timer
 | 
						|
 */
 | 
						|
uint32_t mac_rx_get_delim(uint8_t phy_rate_id, uint32_t hw_band_id);
 | 
						|
 | 
						|
/**
 | 
						|
 * @brief mac_rx_set_pbnum_from_phy() - config pb num from phy or fc.
 | 
						|
 * @param   pn_from_phy 0: pb num form fc ,1: pb num from phy
 | 
						|
 * @return  0:success
 | 
						|
 */
 | 
						|
uint32_t mac_rx_set_pbnum_from_phy(uint32_t pn_from_phy);
 | 
						|
 | 
						|
/**
 | 
						|
 * @brief mac_rx_set_fcs_by_phy() - config fcs from pb or mac hw.
 | 
						|
 * @param   enable 0: fcs from mac ,1: fcs from phy
 | 
						|
 * @return  0:success
 | 
						|
 */
 | 
						|
uint32_t mac_rx_set_fcs_by_phy(uint32_t enable);
 | 
						|
 | 
						|
void mac_rx_set_sg_dt_filter(uint8_t dt0, uint8_t dt1, \
 | 
						|
        uint8_t dt2, uint8_t dt3);
 | 
						|
 | 
						|
/**
 | 
						|
 * @brief   mac_rx_get_ring() - get ring pointer.
 | 
						|
 * @param   pdev              - point to pdev.
 | 
						|
 * @param   index             - ring index.
 | 
						|
 * @return  ring pointer
 | 
						|
 */
 | 
						|
rx_buf_ring_t *mac_rx_get_ring(void *pdev, uint32_t index);
 | 
						|
 | 
						|
/**
 | 
						|
 * @brief   mac_rx_get_ring_buf_desc_size() - get ring buf desc size.
 | 
						|
 * @param   none              - none.
 | 
						|
 * @return  ring buf desc size
 | 
						|
 */
 | 
						|
uint32_t mac_rx_get_ring_buf_desc_size();
 | 
						|
 | 
						|
/**
 | 
						|
 * @brief   mac_rx_set_ring_buf_list()    - set ring buf list.
 | 
						|
 * @param   buf_list                      - buf list.
 | 
						|
 * @param   ring_sz                       - ring sz.
 | 
						|
 * @param   index                         - index of ring.
 | 
						|
 * @param   iot_pkt                       - the pkt to point to buf list.
 | 
						|
 * @return  none.
 | 
						|
 */
 | 
						|
void mac_rx_set_ring_buf_list(uint8_t **buf_list, uint32_t ring_sz,
 | 
						|
    uint32_t index, iot_pkt_t *iot_pkt);
 | 
						|
 | 
						|
/**
 | 
						|
 * @brief   mac_rx_get_ring_buf_list()    - get ring buf list.
 | 
						|
 * @param   rx_ring                       - rx ring.
 | 
						|
 * @return  buf list.
 | 
						|
 */
 | 
						|
iot_pkt_t *mac_rx_get_ring_buf_list(rx_buf_ring_t *rx_ring);
 | 
						|
 | 
						|
/**
 | 
						|
 * @brief   rx_ring_fill_hw_cfg()         - fill hw cfg.
 | 
						|
 * @param   rx_ring                       - rx ring.
 | 
						|
 * @return  void.
 | 
						|
 */
 | 
						|
void rx_ring_fill_hw_cfg(rx_buf_ring_t *rx_ring);
 | 
						|
 | 
						|
#if DEBUG_INVAILD_ADDR
 | 
						|
 | 
						|
/**
 | 
						|
 *@brief mac_judge_ring_buf_validation.
 | 
						|
 *                                judge ring buf if invaild.
 | 
						|
 *
 | 
						|
 *@return                   0: vaild, 1: invaild
 | 
						|
*/
 | 
						|
uint32_t mac_judge_ring_buf_validation();
 | 
						|
 | 
						|
/**
 | 
						|
 *@brief mac_handle_invaild_addr.
 | 
						|
 *                        handle invaild addr.
 | 
						|
 *
 | 
						|
 *@return                  [null]
 | 
						|
*/
 | 
						|
void mac_handle_invaild_addr();
 | 
						|
 | 
						|
#endif
 | 
						|
 | 
						|
/**
 | 
						|
 * @brief mac_rx_set_phase_protection() - protect rx frame from phase
 | 
						|
 *          change from cmd list
 | 
						|
 * @param   phy_force: force phy phase
 | 
						|
 * @param   mac_force: force mac phase
 | 
						|
 * @return  none
 | 
						|
 */
 | 
						|
void mac_rx_set_phase_protection(uint32_t phy_force, uint32_t mac_force);
 | 
						|
 | 
						|
/**
 | 
						|
 * @brief   enable/disable rx last pb eco
 | 
						|
 * @return  none
 | 
						|
 */
 | 
						|
void mac_rx_set_last_pb_eco(uint8_t enable);
 | 
						|
 | 
						|
/**
 | 
						|
 * @brief mac_rx_set_pb_hdr_crc_opt   set pb_hdr_crc_opt
 | 
						|
 * @param   value:                    set the value
 | 
						|
 * @return  none
 | 
						|
 */
 | 
						|
void mac_rx_set_pb_hdr_crc_opt(uint8_t value);
 | 
						|
 | 
						|
 | 
						|
#ifdef __cplusplus
 | 
						|
}
 | 
						|
#endif
 | 
						|
 | 
						|
#endif // !MAC_RX_BUF_RING_H
 |