1003 lines
30 KiB
C
Executable File
1003 lines
30 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.
|
|
|
|
****************************************************************************/
|
|
|
|
#include "mac_rx_buf_ring.h"
|
|
#include "iot_errno.h"
|
|
#include "iot_utils.h"
|
|
#include "iot_io.h"
|
|
#include "plc_utils.h"
|
|
#include "plc_mac_cfg.h"
|
|
#include "mac.h"
|
|
#include "plc_fr.h"
|
|
#include "mac_rx_reg.h"
|
|
#include "hw_reg_api.h"
|
|
#include "rx_mpdu_start.h"
|
|
#include "rx_mpdu_end.h"
|
|
#include "rx_pb_start.h"
|
|
#include "rx_pb_end.h"
|
|
#include "plc_const.h"
|
|
#include "mac_sys_reg.h"
|
|
#include "hw_tonemap.h"
|
|
#include "phy_bb.h"
|
|
#include "mac_pdev.h" /* for WAR */
|
|
#include "mac_tmr_reg.h"
|
|
#include "phy_bb.h"
|
|
#include "phy_txrx_pwr.h"
|
|
#if DEBUG_INVAILD_ADDR
|
|
#include "iot_system_api.h"
|
|
#endif
|
|
#include "mac_rx_hw.h"
|
|
|
|
#if HW_PLATFORM >= HW_PLATFORM_FPGA
|
|
|
|
void mac_set_trans_done_selection(uint32_t cfg)
|
|
{
|
|
/* 1- select transdone after fifo empty.
|
|
* 0- select trans done after write fifo
|
|
*/
|
|
uint32_t tmp;
|
|
tmp = RGF_MAC_READ_REG(CFG_AHB_DBG_CTRL_ADDR);
|
|
REG_FIELD_SET(CFG_AHB_TRANS_DONE_SEL0, tmp, cfg);
|
|
RGF_MAC_WRITE_REG(CFG_AHB_DBG_CTRL_ADDR, tmp);
|
|
}
|
|
|
|
void mac_rx_abort_act_hang(uint32_t enable)
|
|
{
|
|
uint32_t tmp;
|
|
tmp = RGF_RX_READ_REG(CFG_RX_TIMEOUT_ACT_ADDR);
|
|
REG_FIELD_SET(CFG_MAC_RX_ABORT_ACT, tmp, enable);
|
|
RGF_RX_WRITE_REG(CFG_RX_TIMEOUT_ACT_ADDR, tmp);
|
|
}
|
|
|
|
|
|
void mac_rx_timeout_act_hang(uint32_t enable)
|
|
{
|
|
uint32_t tmp;
|
|
tmp = RGF_RX_READ_REG(CFG_RX_TIMEOUT_ACT_ADDR);
|
|
REG_FIELD_SET(CFG_RX_TIMEOUT_ACT, tmp, enable);
|
|
RGF_RX_WRITE_REG(CFG_RX_TIMEOUT_ACT_ADDR, tmp);
|
|
}
|
|
|
|
void mac_rx_set_filter(uint32_t filter_type, uint8_t en)
|
|
{
|
|
uint32_t tmp;
|
|
tmp = RGF_RX_READ_REG(CFG_RX_FILTER_0_ADDR);
|
|
en = !!en;
|
|
|
|
switch (filter_type)
|
|
{
|
|
case CFG_BEACON_PHASE_FILTER_DIS_MASK:
|
|
{
|
|
REG_FIELD_SET(CFG_BEACON_PHASE_FILTER_DIS, tmp, en);
|
|
break;
|
|
}
|
|
case CFG_MPDU_DTEI_FILTER_DIS_MASK:
|
|
{
|
|
REG_FIELD_SET(CFG_MPDU_DTEI_FILTER_DIS, tmp, en);
|
|
break;
|
|
}
|
|
case CFG_NID_FILTER_DIS_MASK:
|
|
{
|
|
REG_FIELD_SET(CFG_NID_FILTER_DIS, tmp, en);
|
|
break;
|
|
}
|
|
case CFG_FC_CRCERR_FILTER_DIS_MASK:
|
|
{
|
|
REG_FIELD_SET(CFG_FC_CRCERR_FILTER_DIS, tmp, en);
|
|
break;
|
|
}
|
|
default:
|
|
break;
|
|
}
|
|
|
|
RGF_RX_WRITE_REG(CFG_RX_FILTER_0_ADDR, tmp);
|
|
return;
|
|
}
|
|
|
|
void mac_rx_set_sg_dt_filter(uint8_t dt0, uint8_t dt1, uint8_t dt2, uint8_t dt3)
|
|
{
|
|
uint32_t tmp;
|
|
tmp = RGF_RX_READ_REG(CFG_RX_FILTER_1_ADDR);
|
|
REG_FIELD_SET(CFG_SG_DT_FILTER_BLACKLIST_0, tmp, dt0);
|
|
REG_FIELD_SET(CFG_SG_DT_FILTER_BLACKLIST_1, tmp, dt1);
|
|
REG_FIELD_SET(CFG_SG_DT_FILTER_BLACKLIST_2, tmp, dt2);
|
|
REG_FIELD_SET(CFG_SG_DT_FILTER_BLACKLIST_3, tmp, dt3);
|
|
RGF_RX_WRITE_REG(CFG_RX_FILTER_1_ADDR, tmp);
|
|
return;
|
|
|
|
}
|
|
|
|
uint32_t mac_rx_set_fcs_by_phy(uint32_t enable)
|
|
{
|
|
uint32_t tmp;
|
|
tmp = RGF_RX_READ_REG(CFG_RX_CTRL_ADDR);
|
|
REG_FIELD_SET(CFG_RX_FC_CRC_FROM_PHY, tmp, enable);
|
|
RGF_RX_WRITE_REG(CFG_RX_CTRL_ADDR, tmp);
|
|
return 0;
|
|
}
|
|
|
|
uint32_t mac_rx_set_pbnum_from_phy(uint32_t pn_from_phy)
|
|
{
|
|
uint32_t tmp;
|
|
tmp = RGF_RX_READ_REG(CFG_RX_CTRL_ADDR);
|
|
REG_FIELD_SET(CFG_RX_PBNUM_FROM_PHY, tmp, pn_from_phy);
|
|
RGF_RX_WRITE_REG(CFG_RX_CTRL_ADDR, tmp);
|
|
return 0;
|
|
}
|
|
|
|
uint32_t mac_rx_get_bcn_swcrc_cfg(void)
|
|
{
|
|
uint32_t tmp;
|
|
uint32_t is_sw_crc;
|
|
tmp = RGF_RX_READ_REG(CFG_RX_CTRL_ADDR);
|
|
is_sw_crc = REG_FIELD_GET(CFG_RX_BEACON_PLD_CRC_BY_SW, tmp);
|
|
return is_sw_crc;
|
|
}
|
|
|
|
void mac_rx_set_bcn_swcrc_cfg(uint32_t is_by_sw)
|
|
{
|
|
uint32_t tmp;
|
|
tmp = RGF_RX_READ_REG(CFG_RX_CTRL_ADDR);
|
|
REG_FIELD_SET(CFG_RX_BEACON_PLD_CRC_BY_SW, tmp, is_by_sw);
|
|
RGF_RX_WRITE_REG(CFG_RX_CTRL_ADDR, tmp);
|
|
return;
|
|
}
|
|
|
|
uint32_t mac_rx_get_pb_hdr_to_buf_cfg(void)
|
|
{
|
|
uint32_t tmp;
|
|
uint32_t is_to_buf;
|
|
tmp = RGF_RX_READ_REG(CFG_RX_CTRL_ADDR);
|
|
is_to_buf = REG_FIELD_GET(CFG_PB_HDR_TO_BUFFER, tmp);
|
|
return is_to_buf;
|
|
}
|
|
|
|
void mac_rx_set_pb_hdr_to_buf_cfg(uint32_t is_to_buf)
|
|
{
|
|
uint32_t tmp;
|
|
tmp = RGF_RX_READ_REG(CFG_RX_CTRL_ADDR);
|
|
REG_FIELD_SET(CFG_PB_HDR_TO_BUFFER, tmp, is_to_buf);
|
|
RGF_RX_WRITE_REG(CFG_RX_CTRL_ADDR, tmp);
|
|
return;
|
|
}
|
|
|
|
uint32_t rx_ring_get_overflow_status()
|
|
{
|
|
uint32_t tmp;
|
|
tmp = RGF_MAC_READ_REG(CFG_RX_INT_CTRL_ADDR);
|
|
return REG_FIELD_GET(RO_RX_DESC_OVERFLOW_INT_STATUS, tmp);
|
|
}
|
|
|
|
void rx_ring_clr_overflow_int(uint32_t rid)
|
|
{
|
|
uint32_t tmp;
|
|
tmp = RGF_MAC_READ_REG(CFG_RX_INT_CLR_ADDR);
|
|
switch (rid) {
|
|
case 0:
|
|
REG_FIELD_SET(CFG_RX_DESC_OVERFLOW_INT_CLR_0, tmp, 1);
|
|
break;
|
|
case 1:
|
|
REG_FIELD_SET(CFG_RX_DESC_OVERFLOW_INT_CLR_1, tmp, 1);
|
|
break;
|
|
case 2:
|
|
REG_FIELD_SET(CFG_RX_DESC_OVERFLOW_INT_CLR_2, tmp, 1);
|
|
break;
|
|
case 3:
|
|
REG_FIELD_SET(CFG_RX_DESC_OVERFLOW_INT_CLR_3, tmp, 1);
|
|
break;
|
|
case 4:
|
|
REG_FIELD_SET(CFG_RX_DESC_OVERFLOW_INT_CLR_4, tmp, 1);
|
|
break;
|
|
default:
|
|
IOT_ASSERT(0);
|
|
}
|
|
RGF_MAC_WRITE_REG(CFG_RX_INT_CLR_ADDR, tmp);
|
|
}
|
|
|
|
uint32_t IRAM_ATTR rx_ring_get_mpdu_int_status()
|
|
{
|
|
uint32_t tmp;
|
|
tmp = RGF_MAC_READ_REG(CFG_RX_INT_CTRL_ADDR);
|
|
return REG_FIELD_GET(RO_RX_MPDU_INT_STATUS, tmp);
|
|
}
|
|
|
|
void rx_ring_clr_mpdu_int(uint32_t rid)
|
|
{
|
|
uint32_t tmp;
|
|
tmp = RGF_MAC_READ_REG(CFG_RX_INT_CLR_ADDR);
|
|
switch (rid){
|
|
case 0:
|
|
REG_FIELD_SET(CFG_RX_MPDU_INT_CLR_0, tmp, 1);
|
|
break;
|
|
case 1:
|
|
REG_FIELD_SET(CFG_RX_MPDU_INT_CLR_1, tmp, 1);
|
|
break;
|
|
case 2:
|
|
REG_FIELD_SET(CFG_RX_MPDU_INT_CLR_2, tmp, 1);
|
|
break;
|
|
case 3:
|
|
REG_FIELD_SET(CFG_RX_MPDU_INT_CLR_3, tmp, 1);
|
|
break;
|
|
case 4:
|
|
REG_FIELD_SET(CFG_RX_MPDU_INT_CLR_4, tmp, 1);
|
|
break;
|
|
default:
|
|
IOT_ASSERT(0);
|
|
}
|
|
RGF_MAC_WRITE_REG(CFG_RX_INT_CLR_ADDR, tmp);
|
|
}
|
|
|
|
/* get ring rd idx */
|
|
uint32_t rx_ring_get_rd_idx(rx_buf_ring_t *rx_ring)
|
|
{
|
|
IOT_ASSERT(rx_ring);
|
|
switch (rx_ring->ring_id) {
|
|
case 0:
|
|
return RX_RING_GET_RD_IDX(0);
|
|
case 1:
|
|
return RX_RING_GET_RD_IDX(1);
|
|
case 2:
|
|
return RX_RING_GET_RD_IDX(2);
|
|
case 3:
|
|
return RX_RING_GET_RD_IDX(3);
|
|
case 4:
|
|
return RX_RING_GET_RD_IDX(4);
|
|
default:
|
|
IOT_ASSERT(0);
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
/* set ring rd idx */
|
|
void rx_ring_set_rd_idx(rx_buf_ring_t *rx_ring, uint32_t value)
|
|
{
|
|
IOT_ASSERT(rx_ring);
|
|
switch (rx_ring->ring_id) {
|
|
case 0:
|
|
RX_RING_SET_RD_IDX(0, value);
|
|
break;
|
|
case 1:
|
|
RX_RING_SET_RD_IDX(1, value);
|
|
break;
|
|
case 2:
|
|
RX_RING_SET_RD_IDX(2, value);
|
|
break;
|
|
case 3:
|
|
RX_RING_SET_RD_IDX(3, value);
|
|
break;
|
|
case 4:
|
|
RX_RING_SET_RD_IDX(4, value);
|
|
break;
|
|
default:
|
|
IOT_ASSERT(0);
|
|
}
|
|
return;
|
|
}
|
|
|
|
/* get ring rd idx */
|
|
uint32_t rx_ring_get_wr_idx(rx_buf_ring_t *rx_ring)
|
|
{
|
|
IOT_ASSERT(rx_ring);
|
|
switch (rx_ring->ring_id) {
|
|
case 0:
|
|
return RX_RING_GET_MPDU_WR_IDX(0, 0);
|
|
case 1:
|
|
return RX_RING_GET_MPDU_WR_IDX(1, 0);
|
|
case 2:
|
|
return RX_RING_GET_MPDU_WR_IDX(2, 0);
|
|
case 3:
|
|
return RX_RING_GET_MPDU_WR_IDX(3, 1);
|
|
case 4:
|
|
return RX_RING_GET_MPDU_WR_IDX(4, 1);
|
|
default:
|
|
IOT_ASSERT(0);
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
/* enable rx ring */
|
|
void mac_rx_ring_enable(rx_buf_ring_t *rx_ring, uint32_t enable)
|
|
{
|
|
uint32_t tmp;
|
|
|
|
IOT_ASSERT(rx_ring);
|
|
switch (rx_ring->ring_id) {
|
|
case 0:
|
|
tmp = RGF_RX_READ_REG(CFG_BUFFER_RING0_2_ADDR);
|
|
REG_FIELD_SET(CFG_RING0_EN, tmp, enable);
|
|
RGF_RX_WRITE_REG(CFG_BUFFER_RING0_2_ADDR, tmp);
|
|
break;
|
|
case 1:
|
|
tmp = RGF_RX_READ_REG(CFG_BUFFER_RING1_2_ADDR);
|
|
REG_FIELD_SET(CFG_RING1_EN, tmp, enable);
|
|
RGF_RX_WRITE_REG(CFG_BUFFER_RING1_2_ADDR, tmp);
|
|
break;
|
|
case 2:
|
|
tmp = RGF_RX_READ_REG(CFG_BUFFER_RING2_2_ADDR);
|
|
REG_FIELD_SET(CFG_RING2_EN, tmp, enable);
|
|
RGF_RX_WRITE_REG(CFG_BUFFER_RING2_2_ADDR, tmp);
|
|
break;
|
|
case 3:
|
|
tmp = RGF_RX_READ_REG(CFG_BUFFER_RING3_2_ADDR);
|
|
REG_FIELD_SET(CFG_RING3_EN, tmp, enable);
|
|
RGF_RX_WRITE_REG(CFG_BUFFER_RING3_2_ADDR, tmp);
|
|
break;
|
|
case 4:
|
|
tmp = RGF_RX_READ_REG(CFG_BUFFER_RING4_2_ADDR);
|
|
REG_FIELD_SET(CFG_RING4_EN, tmp, enable);
|
|
RGF_RX_WRITE_REG(CFG_BUFFER_RING4_2_ADDR, tmp);
|
|
break;
|
|
default:
|
|
IOT_ASSERT(0);
|
|
}
|
|
return;
|
|
}
|
|
|
|
uint8_t rx_ring_set_filter_sel(rx_buf_ring_t *rx_ring)
|
|
{
|
|
IOT_ASSERT(rx_ring);
|
|
switch (rx_ring->ring_id) {
|
|
case 0:
|
|
RX_RING_SET_FILTER_SEL(0, rx_ring->bufsz_filter_sel);
|
|
break;
|
|
case 1:
|
|
RX_RING_SET_FILTER_SEL(1, rx_ring->bufsz_filter_sel);
|
|
break;
|
|
case 2:
|
|
RX_RING_SET_FILTER_SEL(2, rx_ring->bufsz_filter_sel);
|
|
break;
|
|
case 3:
|
|
RX_RING_SET_FILTER_SEL(3, rx_ring->bufsz_filter_sel);
|
|
break;
|
|
case 4:
|
|
RX_RING_SET_FILTER_SEL(4, rx_ring->bufsz_filter_sel);
|
|
break;
|
|
default:
|
|
IOT_ASSERT(0);
|
|
}
|
|
return 0;
|
|
}
|
|
uint8_t rx_ring_set_filter(rx_buf_ring_t *rx_ring)
|
|
{
|
|
IOT_ASSERT(rx_ring);
|
|
switch(rx_ring->ring_id){
|
|
case 0:
|
|
RX_RING_SET_FILTER(0,rx_ring->filter);
|
|
break;
|
|
case 1:
|
|
RX_RING_SET_FILTER(1,rx_ring->filter);
|
|
break;
|
|
case 2:
|
|
RX_RING_SET_FILTER(2,rx_ring->filter);
|
|
break;
|
|
case 3:
|
|
RX_RING_SET_FILTER(3,rx_ring->filter);
|
|
break;
|
|
case 4:
|
|
RX_RING_SET_FILTER(4,rx_ring->filter);
|
|
break;
|
|
default:
|
|
IOT_ASSERT(0);
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
/* fill in the ring cfg */
|
|
void rx_ring_fill_hw_cfg(rx_buf_ring_t *rx_ring)
|
|
{
|
|
IOT_ASSERT(rx_ring);
|
|
uint32_t tmp;
|
|
uint32_t offset = (CFG_BUFFER_RING1_0_ADDR - \
|
|
CFG_BUFFER_RING0_0_ADDR) * rx_ring->ring_id;
|
|
uint32_t ring_cfg_buf = CFG_BUFFER_RING0_1_ADDR + offset;
|
|
uint32_t ring_cfg_rx = CFG_BUFFER_RING0_2_ADDR + offset;
|
|
uint32_t ring_cfg_desc_pld = CFG_BUFFER_RING0_3_ADDR + offset;
|
|
|
|
/* set ring buf array ptr */
|
|
RGF_RX_WRITE_REG(CFG_BUFFER_RING0_0_ADDR + offset, \
|
|
(uint32_t)rx_ring->buf_list);
|
|
|
|
/* set ring sz and buf len */
|
|
tmp = RGF_RX_READ_REG(ring_cfg_buf);
|
|
REG_FIELD_SET(CFG_RING0_BUF_SIZE, tmp, \
|
|
iot_ceil(rx_ring->buf_sz, 4));
|
|
REG_FIELD_SET(CFG_RING0_BUF_NUM, tmp, rx_ring->ring_sz);
|
|
/* re-enable ring, disable clr wr idx */
|
|
REG_FIELD_SET(CFG_RING0_BUF_REENA_CLR_EN, tmp, 0);
|
|
RGF_RX_WRITE_REG(ring_cfg_buf, tmp);
|
|
|
|
rx_ring_set_filter_sel(rx_ring);
|
|
rx_ring_set_filter(rx_ring);
|
|
|
|
/* set rd idx = 0 as default */
|
|
tmp = RGF_RX_READ_REG(ring_cfg_rx);
|
|
REG_FIELD_SET(CFG_RING0_RD_IDX, tmp, 0);
|
|
RGF_RX_WRITE_REG(ring_cfg_rx, tmp);
|
|
|
|
/* set desc and payload offset */
|
|
tmp = RGF_RX_READ_REG(ring_cfg_desc_pld);
|
|
REG_FIELD_SET(CFG_RING0_DESC_EN, tmp, \
|
|
rx_ring->config[CONFIG_RX_DESC].enable);
|
|
REG_FIELD_SET(CFG_RING0_PAYLOAD_EN, tmp, \
|
|
rx_ring->config[CONFIG_PAYLOAD].enable);
|
|
REG_FIELD_SET(CFG_RING0_DESC_OFFSET, tmp, \
|
|
iot_ceil(rx_ring->config[CONFIG_RX_DESC].offset, 4));
|
|
REG_FIELD_SET(CFG_RING0_PAYLOAD_OFFSET, tmp, \
|
|
iot_ceil(rx_ring->config[CONFIG_PAYLOAD].offset, 4));
|
|
RGF_RX_WRITE_REG(ring_cfg_desc_pld, tmp);
|
|
|
|
}
|
|
|
|
void mac_rx_pb_timeout(uint32_t time_40ns)
|
|
{
|
|
uint32_t tmp;
|
|
tmp = RGF_RX_READ_REG(CFG_RX_TIMEOUT_1_ADDR);
|
|
REG_FIELD_SET(CFG_RX_PB_TIMEOUT, tmp, time_40ns);
|
|
RGF_RX_WRITE_REG(CFG_RX_TIMEOUT_1_ADDR, tmp);
|
|
}
|
|
|
|
void mac_set_debug_reg(uint32_t value)
|
|
{
|
|
RGF_MAC_WRITE_REG(CFG_MAC_DBG_CTRL1_ADDR, value);
|
|
}
|
|
|
|
uint32_t mac_rx_get_debug_reg()
|
|
{
|
|
return RGF_MAC_READ_REG(CFG_MAC_DBG_BUS_ADDR);
|
|
}
|
|
|
|
/* TODO: remove when muti-band test*/
|
|
void mac_rx_set_delim(uint32_t proto_band_id, uint32_t rate_id)
|
|
{
|
|
IOT_ASSERT(rate_id == 0);
|
|
(void)rate_id;
|
|
uint32_t fc_num;
|
|
uint32_t preamble_value;
|
|
if (IOT_SUPPORT_TONE_MULTI_BAND021 == proto_band_id) {
|
|
uint32_t single_proto_band;
|
|
uint32_t addr_interv = CFG_SG_DELI_R0B1_ADDR - CFG_SG_DELI_R0B0_ADDR;
|
|
for (uint32_t hw_band_idx = 0; hw_band_idx < MAX_HW_BAND;
|
|
hw_band_idx++) {
|
|
single_proto_band = phy_hw_band_to_proto_band(hw_band_idx);
|
|
fc_num = phy_get_proto_band_fc_num_from_band_table(single_proto_band);
|
|
if (!fc_num) {
|
|
IOT_ASSERT(0);
|
|
}
|
|
preamble_value = (uint32_t)(DELIMITER_LENGTH_SG(fc_num));
|
|
/* SR QR XR */
|
|
RGF_TMR_WRITE_REG(CFG_SG_DELI_R0B0_ADDR + hw_band_idx * addr_interv,
|
|
preamble_value);
|
|
RGF_TMR_WRITE_REG(CFG_SG_DELI_R1B0_ADDR + hw_band_idx * addr_interv,
|
|
4 * preamble_value);
|
|
RGF_TMR_WRITE_REG(CFG_SG_DELI_R2B0_ADDR + hw_band_idx * addr_interv,
|
|
preamble_value);
|
|
}
|
|
} else {
|
|
fc_num = phy_get_proto_band_fc_num_from_band_table(proto_band_id);
|
|
if (!fc_num) {
|
|
IOT_ASSERT(0);
|
|
}
|
|
preamble_value = (uint32_t)(DELIMITER_LENGTH_SG(fc_num));
|
|
RGF_TMR_WRITE_REG(CFG_SG_DELI_R0B0_ADDR, preamble_value);
|
|
RGF_TMR_WRITE_REG(CFG_SG_DELI_R0B1_ADDR, preamble_value);
|
|
RGF_TMR_WRITE_REG(CFG_SG_DELI_R0B2_ADDR, preamble_value);
|
|
RGF_TMR_WRITE_REG(CFG_SG_DELI_R1B0_ADDR, 4 * preamble_value);
|
|
RGF_TMR_WRITE_REG(CFG_SG_DELI_R1B1_ADDR, 4 * preamble_value);
|
|
RGF_TMR_WRITE_REG(CFG_SG_DELI_R1B2_ADDR, 4 * preamble_value);
|
|
RGF_TMR_WRITE_REG(CFG_SG_DELI_R2B0_ADDR, preamble_value);
|
|
RGF_TMR_WRITE_REG(CFG_SG_DELI_R2B1_ADDR, preamble_value);
|
|
RGF_TMR_WRITE_REG(CFG_SG_DELI_R2B2_ADDR, preamble_value);
|
|
}
|
|
}
|
|
|
|
uint32_t mac_rx_get_delim(uint8_t phy_rate_id, uint32_t hw_band_id)
|
|
{
|
|
IOT_ASSERT(phy_rate_id == 0);
|
|
|
|
uint32_t addr_interv = CFG_SG_DELI_R1B0_ADDR - CFG_SG_DELI_R0B0_ADDR;
|
|
uint32_t tmp;
|
|
switch (hw_band_id) {
|
|
case HW_FULL_BAND :{
|
|
tmp = RGF_TMR_READ_REG(CFG_SG_DELI_R0B0_ADDR + \
|
|
phy_rate_id * addr_interv);
|
|
break;
|
|
}
|
|
case HW_LOW_BAND :{
|
|
tmp = RGF_TMR_READ_REG(CFG_SG_DELI_R0B1_ADDR + \
|
|
phy_rate_id * addr_interv);
|
|
break;
|
|
}
|
|
case HW_HIGH_BAND :{
|
|
tmp = RGF_TMR_READ_REG(CFG_SG_DELI_R0B2_ADDR + \
|
|
phy_rate_id * addr_interv);
|
|
break;
|
|
}
|
|
default :
|
|
IOT_ASSERT(0);
|
|
return 0;
|
|
}
|
|
return tmp & 0xFFFFFF;
|
|
}
|
|
|
|
void mac_rx_gp_proto_band_set(void)
|
|
{
|
|
uint32_t tmp = 0;
|
|
uint32_t symbnum_ppb = 0;
|
|
uint32_t fl_ppb = 0;
|
|
/* tmi0 configration */
|
|
/* band0 */
|
|
symbnum_ppb = phy_get_symppb_from_table(0, 0, 0);
|
|
fl_ppb = (uint32_t)(FRAME_LENGTH_PER_PB_GP(symbnum_ppb, GI_STD_ROBO)/1.28);
|
|
tmp = RGF_RX_READ_REG(CFG_TMI0_BAND0_ADDR);
|
|
REG_FIELD_SET(CFG_TMI0_BAND0_PBFL,tmp,fl_ppb);
|
|
RGF_RX_WRITE_REG(CFG_TMI0_BAND0_ADDR,tmp);
|
|
/* band1 */
|
|
symbnum_ppb = phy_get_symppb_from_table(0, 0, 0);
|
|
fl_ppb = (uint32_t)(FRAME_LENGTH_PER_PB_GP(symbnum_ppb, GI_STD_ROBO)/1.28);
|
|
tmp = RGF_RX_READ_REG(CFG_TMI0_BAND1_ADDR);
|
|
REG_FIELD_SET(CFG_TMI0_BAND1_PBFL,tmp,fl_ppb);
|
|
RGF_RX_WRITE_REG(CFG_TMI0_BAND1_ADDR,tmp);
|
|
/* band2 */
|
|
symbnum_ppb = phy_get_symppb_from_table(0, 0, 0);
|
|
fl_ppb = (uint32_t)(FRAME_LENGTH_PER_PB_GP(symbnum_ppb, GI_STD_ROBO)/1.28);
|
|
tmp = RGF_RX_READ_REG(CFG_TMI0_BAND2_ADDR);
|
|
REG_FIELD_SET(CFG_TMI0_BAND2_PBFL,tmp,fl_ppb);
|
|
RGF_RX_WRITE_REG(CFG_TMI0_BAND2_ADDR,tmp);
|
|
/* band3 */
|
|
symbnum_ppb = phy_get_symppb_from_table(0, 0, 0);
|
|
fl_ppb = (uint32_t)(FRAME_LENGTH_PER_PB_GP(symbnum_ppb, GI_STD_ROBO)/1.28);
|
|
tmp = RGF_RX_READ_REG(CFG_TMI0_BAND3_ADDR);
|
|
REG_FIELD_SET(CFG_TMI0_BAND3_PBFL,tmp,fl_ppb);
|
|
RGF_RX_WRITE_REG(CFG_TMI0_BAND3_ADDR,tmp);
|
|
|
|
/* tmi1 configration */
|
|
/* band0 */
|
|
symbnum_ppb = phy_get_symppb_from_table(0, 1, 0);
|
|
fl_ppb = (uint32_t)(FRAME_LENGTH_PER_PB_GP(symbnum_ppb, GI_HS_ROBO)/1.28);
|
|
tmp = RGF_RX_READ_REG(CFG_TMI1_BAND0_ADDR);
|
|
REG_FIELD_SET(CFG_TMI1_BAND0_PBFL,tmp,fl_ppb);
|
|
RGF_RX_WRITE_REG(CFG_TMI1_BAND0_ADDR,tmp);
|
|
/* band1 */
|
|
symbnum_ppb = phy_get_symppb_from_table(0, 1, 0);
|
|
fl_ppb = (uint32_t)(FRAME_LENGTH_PER_PB_GP(symbnum_ppb, GI_HS_ROBO)/1.28);
|
|
tmp = RGF_RX_READ_REG(CFG_TMI1_BAND1_ADDR);
|
|
REG_FIELD_SET(CFG_TMI1_BAND1_PBFL,tmp,fl_ppb);
|
|
RGF_RX_WRITE_REG(CFG_TMI1_BAND1_ADDR,tmp);
|
|
/* band2 */
|
|
symbnum_ppb = phy_get_symppb_from_table(0, 1, 0);
|
|
fl_ppb = (uint32_t)(FRAME_LENGTH_PER_PB_GP(symbnum_ppb, GI_HS_ROBO)/1.28);
|
|
tmp = RGF_RX_READ_REG(CFG_TMI1_BAND2_ADDR);
|
|
REG_FIELD_SET(CFG_TMI1_BAND2_PBFL,tmp,fl_ppb);
|
|
RGF_RX_WRITE_REG(CFG_TMI1_BAND2_ADDR,tmp);
|
|
/* band3 */
|
|
symbnum_ppb = phy_get_symppb_from_table(0, 1, 0);
|
|
fl_ppb = (uint32_t)(FRAME_LENGTH_PER_PB_GP(symbnum_ppb, GI_HS_ROBO)/1.28);
|
|
tmp = RGF_RX_READ_REG(CFG_TMI1_BAND3_ADDR);
|
|
REG_FIELD_SET(CFG_TMI1_BAND3_PBFL,tmp,fl_ppb);
|
|
RGF_RX_WRITE_REG(CFG_TMI1_BAND3_ADDR,tmp);
|
|
|
|
/* tmi2 configration */
|
|
/* band0 */
|
|
symbnum_ppb = phy_get_symppb_from_table(0, 2, 0);
|
|
fl_ppb = (uint32_t)(FRAME_LENGTH_PER_PB_GP(symbnum_ppb, GI_MINI_ROBO)/1.28);
|
|
tmp = RGF_RX_READ_REG(CFG_TMI2_BAND0_ADDR);
|
|
REG_FIELD_SET(CFG_TMI2_BAND0_PBFL,tmp,fl_ppb);
|
|
RGF_RX_WRITE_REG(CFG_TMI2_BAND0_ADDR,tmp);
|
|
/* band1 */
|
|
symbnum_ppb = phy_get_symppb_from_table(0, 2, 0);
|
|
fl_ppb = (uint32_t)(FRAME_LENGTH_PER_PB_GP(symbnum_ppb, GI_MINI_ROBO)/1.28);
|
|
tmp = RGF_RX_READ_REG(CFG_TMI2_BAND1_ADDR);
|
|
REG_FIELD_SET(CFG_TMI2_BAND1_PBFL,tmp,fl_ppb);
|
|
RGF_RX_WRITE_REG(CFG_TMI2_BAND1_ADDR,tmp);
|
|
/* band2 */
|
|
symbnum_ppb = phy_get_symppb_from_table(0, 2, 0);
|
|
fl_ppb = (uint32_t)(FRAME_LENGTH_PER_PB_GP(symbnum_ppb, GI_MINI_ROBO)/1.28);
|
|
tmp = RGF_RX_READ_REG(CFG_TMI2_BAND2_ADDR);
|
|
REG_FIELD_SET(CFG_TMI2_BAND2_PBFL,tmp,fl_ppb);
|
|
RGF_RX_WRITE_REG(CFG_TMI2_BAND2_ADDR,tmp);
|
|
/* band3 */
|
|
symbnum_ppb = phy_get_symppb_from_table(0, 2, 0);
|
|
fl_ppb = (uint32_t)(FRAME_LENGTH_PER_PB_GP(symbnum_ppb, GI_MINI_ROBO)/1.28);
|
|
tmp = RGF_RX_READ_REG(CFG_TMI2_BAND3_ADDR);
|
|
REG_FIELD_SET(CFG_TMI2_BAND3_PBFL,tmp,fl_ppb);
|
|
RGF_RX_WRITE_REG(CFG_TMI2_BAND3_ADDR,tmp);
|
|
}
|
|
|
|
void mac_rx_set_phase_protection(uint32_t phy_force, uint32_t mac_force)
|
|
{
|
|
uint32_t tmp;
|
|
tmp = RGF_MAC_READ_REG(CFG_RX_PHASE_PROTECT_ADDR);
|
|
REG_FIELD_SET(CFG_RX_PHASE_FOR_PHY_PROTECT_EN, tmp, !!phy_force);
|
|
REG_FIELD_SET(CFG_RX_PHASE_FOR_MAC_PROTECT_EN, tmp, !!mac_force);
|
|
RGF_MAC_WRITE_REG(CFG_RX_PHASE_PROTECT_ADDR, tmp);
|
|
}
|
|
|
|
void mac_rx_set_last_pb_eco(uint8_t enable)
|
|
{
|
|
uint32_t tmp;
|
|
tmp = RGF_RX_READ_REG(CFG_RX_ECO_ADDR);
|
|
REG_FIELD_SET(CFG_LAST_PB_ECO_SEL, tmp, !!enable);
|
|
RGF_RX_WRITE_REG(CFG_RX_ECO_ADDR, tmp);
|
|
return;
|
|
}
|
|
|
|
void mac_rx_set_pb_hdr_crc_opt(uint8_t value)
|
|
{
|
|
uint32_t tmp;
|
|
tmp = RGF_RX_READ_REG(CFG_RX_PB_OPT_ADDR);
|
|
REG_FIELD_SET(CFG_PB_HDR_CRC_OPT, tmp, !!value);
|
|
RGF_RX_WRITE_REG(CFG_RX_PB_OPT_ADDR, tmp);
|
|
return;
|
|
}
|
|
|
|
rx_buf_ring_t *mac_rx_get_ring(void *pdev, uint32_t index)
|
|
{
|
|
if (index >= MAX_PLC_RX_RING_NUM) {
|
|
IOT_ASSERT(0);
|
|
return NULL;
|
|
}
|
|
mac_pdev_t *pdev_ptr = (mac_pdev_t *)pdev;
|
|
IOT_ASSERT(pdev_ptr);
|
|
return &pdev_ptr->ring_hdl.ring[index];
|
|
}
|
|
|
|
uint32_t mac_rx_get_ring_buf_desc_size()
|
|
{
|
|
return sizeof(uint8_t *);
|
|
}
|
|
|
|
void mac_rx_set_ring_buf_list(uint8_t **buf_list, uint32_t ring_sz,
|
|
uint32_t index, iot_pkt_t *iot_pkt)
|
|
{
|
|
IOT_ASSERT(buf_list && (index < ring_sz));
|
|
buf_list[index] = iot_pkt_data(iot_pkt);
|
|
}
|
|
|
|
iot_pkt_t *mac_rx_get_ring_buf_list(rx_buf_ring_t *rx_ring)
|
|
{
|
|
IOT_ASSERT(rx_ring->buf_list[rx_ring->read_idx]);
|
|
/* the data just start after the iot_pkt_t structure */
|
|
return (iot_pkt_t*)(rx_ring->buf_list[rx_ring->read_idx] \
|
|
- sizeof(iot_pkt_t));
|
|
/* TODO: need set the actual len here?
|
|
* pb sz maybe smaller than
|
|
* the buf sz, current len should
|
|
* be the buf sz that when init
|
|
*/
|
|
}
|
|
|
|
#endif /* HW_PLATFORM >= HW_PLATFORM_FPGA */
|
|
|
|
void mac_rx_all_ring_enable(void *pdev)
|
|
{
|
|
rx_buf_ring_t *ring;
|
|
mac_pdev_t *pdev_ptr = (mac_pdev_t *)pdev;
|
|
IOT_ASSERT(pdev_ptr);
|
|
for (uint32_t i = 0; i < MAX_PLC_RX_RING_NUM; i++){
|
|
/* get ring pointer */
|
|
ring = mac_rx_get_ring(pdev, i);
|
|
/* enable ring */
|
|
if(ring->cfg_enabled == 1) {
|
|
mac_rx_ring_enable(ring, 1);
|
|
}
|
|
}
|
|
return;
|
|
}
|
|
|
|
void mac_rx_all_ring_disable(void *pdev)
|
|
{
|
|
rx_buf_ring_t *ring;
|
|
mac_pdev_t *pdev_ptr = (mac_pdev_t *)pdev;
|
|
IOT_ASSERT(pdev_ptr);
|
|
for (uint32_t i = 0; i < MAX_PLC_RX_RING_NUM; i++){
|
|
/* get ring pointer */
|
|
ring = mac_rx_get_ring(pdev, i);
|
|
if(ring->cfg_enabled == 1){
|
|
mac_rx_ring_enable(ring, 0);
|
|
if (pdev_ptr->rx) {
|
|
mac_rx_hw_mpdu_internal(pdev_ptr, i, MAX_RX_QUOTA_MS);
|
|
}
|
|
}
|
|
}
|
|
return;
|
|
}
|
|
|
|
uint32_t mac_rx_ring_ctxt_init(mac_rx_ring_ctxt_t *ring_ctxt)
|
|
{
|
|
uint32_t ret;
|
|
/* init only one rx ring temply */
|
|
ring_config config_sof[] =
|
|
{
|
|
{ CONFIG_RX_DESC, RX_ATTENTION_OFFSET, 1 },
|
|
{ CONFIG_RX_MPDU_START, 0, 0 },
|
|
{ CONFIG_RX_MPDU_END, 0, 0 },
|
|
{ CONFIG_RX_PB_START, 0, 0 },
|
|
{ CONFIG_RX_PB_END, 0, 0 },
|
|
{ CONFIG_FC, 0, 0 },
|
|
{ CONFIG_PAYLOAD, PB_PAYLOAD_OFFSET, 1 }
|
|
};
|
|
ring_ctxt->mpdu_pb_cb = NULL;
|
|
ret = rx_buf_ring_init(&ring_ctxt->ring[PLC_RING_0], \
|
|
PLC_RING_0, \
|
|
(uint32_t)PLC_SHORT_RX_BUF_COUNT, PLC_SHORT_BUF_SIZE, NULL, \
|
|
config_sof,0,0);
|
|
if (ERR_OK != ret) {
|
|
/* return error */
|
|
goto out;
|
|
}
|
|
|
|
/*init ring1 bufsize = 136*/
|
|
ret = rx_buf_ring_init(&ring_ctxt->ring[PLC_RING_1], \
|
|
PLC_RING_1, \
|
|
(uint32_t)PLC_SMALL_RX_BUF_COUNT, PLC_SMALL_BUF_SIZE, NULL, \
|
|
config_sof, 0, 0);
|
|
|
|
out:
|
|
return ret;
|
|
}
|
|
|
|
/* 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)
|
|
{
|
|
iot_pkt_t *iot_pkt;
|
|
uint8_t *data_ptr;
|
|
|
|
if(!rx_ring->buf_list){
|
|
rx_ring->buf_list =
|
|
(uint8_t**)os_mem_malloc(PLC_MAC_RX_RING_MID,
|
|
ring_sz * mac_rx_get_ring_buf_desc_size());
|
|
if (!rx_ring->buf_list) {
|
|
return ERR_NOMEM;
|
|
}
|
|
|
|
for (uint32_t i = 0; i < ring_sz; i++) {
|
|
iot_pkt = iot_pkt_alloc(buf_sz, PLC_MAC_RX_HW_MID);
|
|
if (!iot_pkt) {
|
|
/* alloc failed */
|
|
IOT_ASSERT(0);
|
|
return ERR_NOMEM;
|
|
}
|
|
else {
|
|
/* alloc successful */
|
|
/* set and check data field len */
|
|
data_ptr = iot_pkt_put(iot_pkt, buf_sz);
|
|
IOT_ASSERT(data_ptr);
|
|
|
|
mac_rx_set_ring_buf_list(rx_ring->buf_list, ring_sz,
|
|
i, iot_pkt);
|
|
}
|
|
}
|
|
}
|
|
rx_ring->read_idx = 0;
|
|
rx_ring->write_idx = 0;
|
|
rx_ring->ring_id = ring_id;
|
|
rx_ring->water_mark_buf_num = ring_sz << 2; // 1/4 of ring_sz
|
|
rx_ring->overflow = 0;
|
|
rx_ring->bufsz_filter_sel = bufsz_filter_sel;
|
|
rx_ring->filter = filter;
|
|
rx_ring->cb = cb;
|
|
rx_ring->buf_sz = buf_sz;
|
|
rx_ring->ring_sz = ring_sz;
|
|
rx_ring->config[CONFIG_RX_DESC] = cfg[CONFIG_RX_DESC];
|
|
rx_ring->config[CONFIG_PAYLOAD] = cfg[CONFIG_PAYLOAD];
|
|
rx_ring->cur_mpdu = NULL;
|
|
rx_ring->cfg_enabled = 1;
|
|
rx_ring_fill_hw_cfg(rx_ring);
|
|
return ERR_OK;
|
|
}
|
|
|
|
uint32_t peek_buf_for_desc(void *rx_buf)
|
|
{
|
|
uint32_t ret = ERR_OK;
|
|
rx_buf_hdr_t *rx_desc = (rx_buf_hdr_t *)rx_buf;
|
|
IOT_ASSERT(rx_desc);
|
|
|
|
if (rx_desc->pb_ed.rx_pb_done && rx_desc->pb_st.first_pb) {
|
|
/* for first pb */
|
|
if (rx_desc->att.rx_mpdu_done == 0) {
|
|
/* if hw not done with the whole mpdu */
|
|
ret = ERR_AGAIN;
|
|
}
|
|
}
|
|
return ret;
|
|
}
|
|
|
|
/* FW call this to reap data down and repurnish the buf */
|
|
uint32_t pop_buf_from_ring(rx_buf_ring_t *rx_ring, uint32_t num,
|
|
iot_pkt_t **buf_array)
|
|
{
|
|
uint32_t aval_num = 0;
|
|
uint32_t read_num = 0;
|
|
iot_pkt_t *p_buf = NULL;
|
|
uint8_t *rx_buf_addr;
|
|
|
|
if (!rx_ring)
|
|
{
|
|
return read_num;
|
|
}
|
|
|
|
/* read rd and wr idx */
|
|
rx_ring->write_idx = rx_ring_get_wr_idx(rx_ring);
|
|
rx_ring->read_idx = rx_ring_get_rd_idx(rx_ring);
|
|
|
|
(aval_num = (rx_ring->write_idx - rx_ring->read_idx)) < 0 ? \
|
|
aval_num += (rx_ring->ring_sz) : aval_num;
|
|
read_num = min(aval_num, num);
|
|
|
|
for (uint32_t i = 0; i < read_num; i++)
|
|
{
|
|
/* get the iot_pkt_t ptr */
|
|
p_buf = mac_rx_get_ring_buf_list(rx_ring);
|
|
|
|
#if MAC_RX_RING_WAIT_MPDU_DONE == 1
|
|
/* sometimes, the hw is not done with the whole mpdu but
|
|
* the rx pb done == 1, we need to wait the whole mpdu done
|
|
* before pop the buf
|
|
*/
|
|
if (peek_buf_for_desc(rx_ring->buf_list[rx_ring->read_idx]))
|
|
{
|
|
break;
|
|
}
|
|
#endif
|
|
/* reap the buf */
|
|
buf_array[i] = p_buf;
|
|
/* repurnish another buf */
|
|
p_buf = iot_pkt_alloc(rx_ring->buf_sz, PLC_MAC_RX_HW_MID);
|
|
if (!p_buf) {
|
|
//IOT_ASSERT(0);
|
|
return i;
|
|
}
|
|
|
|
rx_buf_addr = iot_pkt_put(p_buf, rx_ring->buf_sz);
|
|
|
|
IOT_ASSERT(rx_buf_addr);
|
|
/* clear the mpdu_done bit, sometimes HW move the
|
|
* wr idx without write to the rx buf when rx abort
|
|
* happen
|
|
*/
|
|
((rx_attention*)(iot_pkt_data(p_buf)))->rx_mpdu_done = 0;
|
|
|
|
mac_rx_set_ring_buf_list(rx_ring->buf_list, rx_ring->ring_sz,
|
|
rx_ring->read_idx, p_buf);
|
|
|
|
if (++rx_ring->read_idx == rx_ring->ring_sz) {
|
|
rx_ring->read_idx = 0;
|
|
}
|
|
rx_ring_set_rd_idx(rx_ring, rx_ring->read_idx);
|
|
}
|
|
return read_num;
|
|
}
|
|
|
|
void rx_buf_ring_set_callback(mac_rx_ring_ctxt_t *ring_ctxt, \
|
|
mac_recv_mpdu_pb_func_t cb)
|
|
{
|
|
ring_ctxt->mpdu_pb_cb = cb;
|
|
}
|
|
|
|
uint32_t rx_ring_set_watermark(rx_buf_ring_t *rx_ring, uint32_t num)
|
|
{
|
|
if (!rx_ring)
|
|
{
|
|
return ERR_INVAL;
|
|
}
|
|
|
|
if (num >= rx_ring->ring_sz)
|
|
{
|
|
return ERR_INVAL;
|
|
}
|
|
|
|
rx_ring->water_mark_buf_num = num;
|
|
return ERR_OK;
|
|
}
|
|
|
|
uint32_t rx_ring_get_watermark(rx_buf_ring_t *rx_ring)
|
|
{
|
|
IOT_ASSERT(rx_ring);
|
|
|
|
return rx_ring->water_mark_buf_num;
|
|
}
|
|
|
|
bool_t is_rx_ring_under_watermark(rx_buf_ring_t *rx_ring)
|
|
{
|
|
uint32_t wr_idx = rx_ring->write_idx;
|
|
uint32_t rd_idx = rx_ring->read_idx;
|
|
bool_t flag = false;
|
|
if ((wr_idx == 0) && (rd_idx == 0)) return false;
|
|
|
|
flag = (rd_idx + rx_ring->ring_sz - wr_idx) % (rx_ring->ring_sz) == 1;
|
|
|
|
return flag;
|
|
}
|
|
|
|
bool_t rx_ring_space_avaliable(rx_buf_ring_t *rx_ring, uint32_t num)
|
|
{
|
|
uint32_t wr_idx = rx_ring->write_idx + num;
|
|
uint32_t rd_idx = rx_ring->read_idx;
|
|
bool_t flag = false;
|
|
|
|
flag = (rd_idx + rx_ring->ring_sz - wr_idx) % (rx_ring->ring_sz) != 1;
|
|
if (flag == 0)
|
|
{
|
|
iot_printf("no space avaliable in rx ring, wr_idx:%d, rd_idx:%d\n", wr_idx, rd_idx);
|
|
}
|
|
return flag;
|
|
}
|
|
|
|
#if DEBUG_INVAILD_ADDR
|
|
/*debug rx buf is validation*/
|
|
uint32_t IRAM_ATTR mac_judge_ring_buf_validation()
|
|
{
|
|
mac_pdev_t *pdev = get_pdev_ptr(PLC_PDEV_ID);
|
|
rx_buf_ring_t *ring;
|
|
uint32_t rx_int_status;
|
|
rx_int_status = rx_ring_get_mpdu_int_status();
|
|
for (uint32_t i = 0; i < MAX_PLC_RX_RING_NUM; i++)
|
|
{
|
|
if ((0x1 << i) & rx_int_status){
|
|
if (pdev->rx) {
|
|
ring = &pdev->ring_hdl.ring[i];
|
|
iot_pkt_t* p_buf = \
|
|
(iot_pkt_t*)(ring->buf_list[ring->read_idx] \
|
|
- sizeof(iot_pkt_t));
|
|
if (!iot_data_addr_legal(
|
|
(uint32_t) iot_pkt_block_ptr(p_buf,
|
|
IOT_PKT_BLOCK_HEAD))
|
|
|| !iot_data_addr_legal(
|
|
(uint32_t) iot_pkt_block_ptr(p_buf,
|
|
IOT_PKT_BLOCK_DATA))
|
|
|| !iot_data_addr_legal(
|
|
(uint32_t) iot_pkt_block_ptr(p_buf,
|
|
IOT_PKT_BLOCK_TAIL))
|
|
|| !iot_data_addr_legal(
|
|
(uint32_t) iot_pkt_block_ptr(p_buf,
|
|
IOT_PKT_BLOCK_END)))
|
|
{
|
|
/* record invaild addr and ring buf len */
|
|
uint32_t *p = (uint32_t *) (((uint8_t *)p_buf)
|
|
- ring->buf_sz - 16);
|
|
pdev->buf_addr = p;
|
|
pdev->buf_len = ring->buf_sz;
|
|
|
|
/* pull msg to dsr */
|
|
uint32_t value = 0;
|
|
value |= 1 << MAC_DSR_INVAILD_ADDR_ID;
|
|
|
|
if (value) {
|
|
/* deliver the DSR events to mac task context */
|
|
os_set_task_event_with_v_from_isr(p_mac_glb->task_h,\
|
|
value);
|
|
}
|
|
return ERR_INVAL;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
return ERR_OK;
|
|
}
|
|
|
|
void mac_handle_invaild_addr()
|
|
{
|
|
iot_printf("%s\n", __FUNCTION__);
|
|
mac_pdev_t *pdev = get_pdev_ptr(PLC_PDEV_ID);
|
|
IOT_ASSERT(pdev->buf_len && pdev->buf_addr);
|
|
mem_dump((uint32_t *)pdev->buf_addr, (pdev->buf_len >> 1) + 4);
|
|
IOT_ASSERT_DUMP(0, pdev->buf_addr, (pdev->buf_len >> 1) + 4);
|
|
}
|
|
|
|
#endif /* DEBUG_INVAILD_ADDR */
|
|
|