Files
kunlun/dtest/dtest3/mac_rx_test/hw3/hw_rx.c
2024-09-28 14:24:04 +08:00

303 lines
10 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.
*
* ****************************************************************************/
#include "chip_reg_base.h"
#include "hw_reg_api.h"
#include "phy_rx_fd_reg.h"
#include "phy_reg.h"
#include "tx_entry.h"
#include "mac_reset.h"
#include "mac_hwq_reg.h"
#include "mac_sys_reg.h"
#include "mac_rx_reg.h"
#include "mac_tmr_reg.h"
#include "mac_reset.h"
#include "iot_config.h"
#include "plc_protocol.h"
#include "hw_rx.h"
#include "os_mem.h"
#include "mac_rx_buf_ring.h"
#include "clk.h"
#include "gp_timer.h"
#include "gpio_mtx.h"
#include "iot_system.h"
#define HW_RX_ALLOC_MEM_BYTE 0x1000
static uint8_t HW_RX_ALLOC_POOL[HW_RX_ALLOC_MEM_BYTE] = {0};
void phy_rx_path_init()
{
uint32_t tmp = 0;
#if IOT_RATE_MODE_RX == IOT_SUPPORT_RATE_SR_QR || \
IOT_RATE_MODE_RX == IOT_SUPPORT_RATE_QR
phy_qr_common_init();
#elif IOT_RATE_MODE_RX == IOT_SUPPORT_RATE_XR
/* TODO: call mac set/get api */
uint32_t time_out = 0;
/* fc timeout */
tmp = RGF_RX_READ_REG(CFG_RX_TIMEOUT_3_ADDR);
time_out = REG_FIELD_GET(CFG_RX_FC_TIMEOUT, tmp);
time_out = time_out << 4;
REG_FIELD_SET(CFG_RX_FC_TIMEOUT, tmp, time_out);
RGF_RX_WRITE_REG(CFG_RX_TIMEOUT_3_ADDR, tmp);
/* pb timeout */
tmp = RGF_RX_READ_REG(CFG_RX_TIMEOUT_1_ADDR);
time_out = REG_FIELD_GET(CFG_RX_PB_TIMEOUT, tmp);
time_out = time_out << 4;
mac_rx_pb_timeout(time_out);
/* vec timeout */
tmp = RGF_RX_READ_REG(CFG_RX_TIMEOUT_0_ADDR);
time_out = REG_FIELD_GET(CFG_RX_VEC_TIMEOUT, tmp);
time_out = time_out << 4;
REG_FIELD_SET(CFG_RX_VEC_TIMEOUT, tmp, time_out);
RGF_RX_WRITE_REG(CFG_RX_TIMEOUT_0_ADDR, tmp);
#endif
/* fc err to mac */
tmp = PHY_RX_FD_READ_REG(CFG_BB_SEND_MAC_CTRL_ADDR);
REG_FIELD_SET(SW_ALWAYS_SEND_FC, tmp, 1);
REG_FIELD_SET(SW_ALWAYS_SEND_PB, tmp, 1);
//REG_FIELD_SET(SW_FC_CRC_ERR_CTRL, tmp, 1);
PHY_RX_FD_WRITE_REG(CFG_BB_SEND_MAC_CTRL_ADDR,tmp);
#if MAC_TX_TEST_ID == MAC_TX_GP_EXT
/* mix en */
phy_mix_flag_set(true);
tmp = PHY_RX_FD_READ_REG(CFG_BB_SEND_MAC_CTRL_ADDR);
REG_FIELD_SET(SW_ALWAYS_SEND_FC, tmp, 0);
PHY_RX_FD_WRITE_REG(CFG_BB_SEND_MAC_CTRL_ADDR, tmp);
#if IOT_PLC_PHY_BAND_DFT == IOT_SUPPORT_TONE_80_1228
phy_rxfd_rate0_det(80,1228);
phy_rxfd_rate1_det(80,1228);
#endif
#endif
}
void mac_burst_init()
{
uint32_t tmp = 0;
tmp = RGF_RX_READ_REG(CFG_RX_PB_OPT_ADDR);
REG_FIELD_SET(CFG_RX_PARSE_DONE_CHOS, tmp, 1);
REG_FIELD_SET(CFG_RX_BURST_FSM_PROTECT_EN, tmp, 1);
REG_FIELD_SET(CFG_BST_SND_FC_DATA_UPDATE_OPT, tmp, 0);
RGF_RX_WRITE_REG(CFG_RX_PB_OPT_ADDR, tmp);
}
void mac_rx_path_init()
{
uint32_t tmp = 0;
uint32_t symbnum_ppb = 0;
uint32_t fl_ppb = 0;
/* enable packets receive */
tmp = RGF_RX_READ_REG(CFG_RX_FILTER_0_ADDR);
//REG_FIELD_SET(CFG_FC_CRCERR_FILTER_DIS, tmp, 1);
REG_FIELD_SET(CFG_NID_FILTER_DIS, tmp, 1);
REG_FIELD_SET(CFG_MPDU_DTEI_FILTER_DIS, tmp, 1);
REG_FIELD_SET(CFG_BEACON_PHASE_FILTER_DIS, tmp, 1);
RGF_RX_WRITE_REG(CFG_RX_FILTER_0_ADDR, tmp);
/* config my nid */
tmp = RGF_MAC_READ_REG(CFG_MYNID_ADDR);
REG_FIELD_SET(CFG_MYNID, tmp, PHY_TXRX_NID_VAL);
RGF_MAC_WRITE_REG(CFG_MYNID_ADDR, tmp);
/* tei cfg */
RGF_MAC_WRITE_REG(CFG_MYTEI_ADDR, 2);
/* delete timeout for long pkt */
tmp = RGF_RX_READ_REG(CFG_RX_TIMEOUT_1_ADDR);
REG_FIELD_SET(CFG_RX_PB_TIMEOUT, tmp, 2000000);
RGF_RX_WRITE_REG(CFG_RX_TIMEOUT_1_ADDR, tmp);
/* pb framelength for gp */
if(PHY_PROTO_TYPE_GET() == PLC_PROTO_TYPE_GP){
/* tmi0 band0 */
symbnum_ppb = phy_get_sym_per_pb(PHY_PROTO_TYPE_GET(), 0, 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);
/* tmi1 band0 */
symbnum_ppb = phy_get_sym_per_pb(PHY_PROTO_TYPE_GET(), 0, 1, 0, 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);
/* tmi2 band0 */
symbnum_ppb = phy_get_sym_per_pb(PHY_PROTO_TYPE_GET(), 0, 2, 0, 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);
/* mix en from mac in the future */
tmp = RGF_MAC_READ_REG(CFG_GP_CTRL_ADDR);
REG_FIELD_SET(CFG_GP_PB_SIZE_SEL, tmp, 1);
RGF_MAC_WRITE_REG(CFG_GP_CTRL_ADDR,tmp);
/* fix pld gi1 */
if(glb_cfg.tmi == 0 || glb_cfg.tmi == 1)
{
phy_pld_gi1_set(GI_HS_ROBO);
}
else if(glb_cfg.tmi == 2)
{
phy_pld_gi1_set(GI_MINI_ROBO);
}
}
/* Multi Rate */
tmp = RGF_MAC_READ_REG(CFG_PHY_FORCE_0_ADDR);
REG_FIELD_SET(CFG_PHY_RX_RATE_MODE_FORCE_EN, tmp, 1);
REG_FIELD_SET(CFG_PHY_RX_RATE_MODE, tmp, IOT_RATE_MODE_RX);
RGF_MAC_WRITE_REG(CFG_PHY_FORCE_0_ADDR,tmp);
/* mac tx init */
/* enable DCU debug mode */
tmp = RGF_HWQ_READ_REG(CFG_SCH_ADDR);
REG_FIELD_SET(CFG_HWQ_DBG_MODE, tmp, 1); // debug enable
RGF_HWQ_WRITE_REG(CFG_SCH_ADDR, tmp);
/* set hwq 0 's config */
/* set hwq0's type, cap */
tmp = RGF_HWQ_READ_REG(CFG_HWQ0_ADDR);
REG_FIELD_SET(CFG_DBG_HWQ0_TYPE, tmp, 0); // 0:TDMA, 1:CSMA
REG_FIELD_SET(CFG_DBG_HWQ0_CAP, tmp, 1); // CAP1 as default
RGF_HWQ_WRITE_REG(CFG_HWQ0_ADDR, tmp);
/* delete timeout for long pkt */
RGF_TMR_WRITE_REG(CFG_TX_TIMEOUT_0_ADDR,0x0);
RGF_TMR_WRITE_REG(CFG_TX_TIMEOUT_1_ADDR,0x0);
RGF_TMR_WRITE_REG(CFG_TX_TIMEOUT_2_ADDR,0x0);
RGF_TMR_WRITE_REG(CFG_PHY_TX_TIMEOUT_ADDR,0x0);
/* not ack by hw */
#if PHY_RX_ACK_DIS == 1
tmp = RGF_RX_READ_REG(CFG_RESP_CTRL_ADDR);
REG_FIELD_SET(CFG_HW_RESP_EN, tmp, 0);
RGF_RX_WRITE_REG(CFG_RESP_CTRL_ADDR, tmp);
#endif
#if PHY_PPM_CAL_SUPPORT == 1
/* disable intr */
PHY_WRITE_REG(CFG_BB_INT_EN_0_ADDR, 0);
PHY_WRITE_REG(CFG_BB_INT_EN_1_ADDR, 0);
PHY_WRITE_REG(CFG_BB_INT_EN_2_ADDR, 0);
PHY_WRITE_REG(CFG_BB_INT_EN_3_ADDR, 0);
#endif
/* disable ts sync */
RGF_MAC_WRITE_REG(CFG_NTB_SYNC_0_ADDR,0);
/* mac auto trig */
mac_sw_trig_need_en(false);
mac_sw_trig_start(true);
/* burst only */
if (PHY_PROTO_TYPE_GET() == PLC_PROTO_TYPE_GP) {
mac_burst_init();
}
/* pb header transfer to pb buf */
tmp = RGF_RX_READ_REG(CFG_RX_CTRL_ADDR);
REG_FIELD_SET(CFG_PB_HDR_TO_BUFFER, tmp, 0);
RGF_RX_WRITE_REG(CFG_RX_CTRL_ADDR, tmp);
}
static void geode_gpio_init(uint32_t chip_id)
{
switch (chip_id) {
case CHIP_ID_HZ3201_V1A:
/* geode gpio init */
gpio_mtx_sig_out(GPIO_MTX_RX_EN_A, 34);
gpio_mtx_sig_out(GPIO_MTX_TX_EN_A, 35);
gpio_mtx_sig_out(GPIO_MTX_RX_EN_B, 36);
gpio_mtx_sig_out(GPIO_MTX_TX_EN_B, 37);
gpio_mtx_sig_out(GPIO_MTX_RX_EN_C, 38);
gpio_mtx_sig_out(GPIO_MTX_TX_EN_C, 39);
gpio_mtx_sig_out(GPIO_MTX_RX_GLNA_0, 7);
gpio_mtx_sig_out(GPIO_MTX_RX_GLNA_1, 8);
gpio_mtx_sig_out(GPIO_MTX_RX_GLNA_2, 26);
break;
case CHIP_ID_HZ3211_V1A:
/* geode gpio init */
gpio_mtx_sig_out(GPIO_MTX_RX_EN_A, 34);
gpio_mtx_sig_out(GPIO_MTX_TX_EN_A, 35);
gpio_mtx_sig_out(GPIO_MTX_RX_GLNA_0, 7);
gpio_mtx_sig_out(GPIO_MTX_RX_GLNA_1, 8);
gpio_mtx_sig_out(GPIO_MTX_RX_GLNA_2, 26);
break;
case CHIP_ID_WQ3031_V1A:
/* geode gpio init */
gpio_mtx_sig_out(GPIO_MTX_ENLIC_0, 80);
gpio_mtx_sig_out(GPIO_MTX_ENLIC_1, 81);
gpio_mtx_sig_out(GPIO_MTX_RX_GLNA_0, 82);
gpio_mtx_sig_out(GPIO_MTX_RX_GLNA_1, 83);
gpio_mtx_sig_out(GPIO_MTX_RX_GLNA_2, 84);
break;
default:
break;
}
}
void platform_rx_pre_init()
{
#if HW_PLATFORM > HW_PLATFORM_FPGA
uint32_t chip_id = iot_chip_get_chip_info();
#else
uint32_t chip_id = 0;
#endif
/* change clk to 150M */
clk_core_freq_set(CPU_FREQ_150M);
/* enable timer */
gp_timer_init();
gp_timer_enable(0,0,0);
/* geode gpio init */
geode_gpio_init(chip_id);
/* alloc 1K size ram */
os_mem_init((uint8_t *)HW_RX_ALLOC_POOL, HW_RX_ALLOC_MEM_BYTE);
/* reset phy */
phy_reset(PHY_RST_REASON_COLD);
/* reset mac */
mac_reset(MAC_RST_REASON_COLD);
}
uint32_t phy_get_pb_buf_ptr_from_mpdu(volatile tx_mpdu_start *mpdu)
{
return ((tx_pb_start*)mpdu->pb_list)->pb_buf_addr;
}
void mac_sts_get(iot_mac_sts_info_t *mac_sts)
{
/* get mac statistics */
mac_sts->mac_rx_ring0_dbg_cnt = RGF_RX_READ_REG(CFG_RX_RING0_DBG_CNT_ADDR);
mac_sts->mac_rx_fc_dbg_cnt = RGF_RX_READ_REG(CFG_RX_FC_DBG_CNT_ADDR);
mac_sts->mac_rx_pkt_det_cnt = RGF_RX_READ_REG(CFG_RX_PKT_DETECTED_CNT_ADDR);
/* clear cnt */
RGF_RX_WRITE_REG(CFG_DBG_CNT_CLR_ADDR,0x1f);
RGF_RX_WRITE_REG(CFG_RX_DBG_CNT_CLR_ADDR,0xf);
}