Files
kunlun/bb_cpu/mac/bb_cpu_hw_ring.c
2024-09-28 14:24:04 +08:00

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