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