Files
kunlun/plc/halmac/hw/inc/mac_rx_buf_ring.h

423 lines
12 KiB
C
Raw Permalink Normal View History

2024-09-28 14:24:04 +08:00
/****************************************************************************
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