423 lines
12 KiB
C
423 lines
12 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.
|
|
|
|
****************************************************************************/
|
|
|
|
#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"
|
|
#include "rx_pb_start.h"
|
|
#include "rx_mpdu_end.h"
|
|
#include "rx_pb_end.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_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 ,
|
|
|
|
/* rf ring define */
|
|
RF_RING_0 = PLC_RING_0,
|
|
RF_RING_1 = PLC_RING_1,
|
|
RF_RING_2 = PLC_RING_2,
|
|
RF_RING_3 = PLC_RING_3,
|
|
RF_RING_4 = PLC_RING_4,
|
|
RF_RING_5 = RF_RING_4 + 1,
|
|
MAX_RF_RX_RING_NUM = RF_RING_5 +1,
|
|
} 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 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);
|
|
|
|
#if HPLC_RF_DEV_SUPPORT
|
|
#define RX_RING_NUM_MAX (max(MAX_PLC_RX_RING_NUM, MAX_RF_RX_RING_NUM))
|
|
#else
|
|
#define RX_RING_NUM_MAX MAX_PLC_RX_RING_NUM
|
|
#endif
|
|
|
|
typedef struct _mac_rx_ring_ctxt
|
|
{
|
|
rx_buf_ring_t ring[RX_RING_NUM_MAX];
|
|
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
|
|
|
|
|
|
#ifdef __cplusplus
|
|
}
|
|
#endif
|
|
|
|
#endif // !MAC_RX_BUF_RING_H
|