Files
kunlun/plc/halmac/hw2/reset/mac_reset.c
2024-09-28 14:24:04 +08:00

396 lines
10 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 "chip_reg_base.h"
#include "hw_reg_api.h"
#include "plc_fr.h"
#include "mac_reset.h"
#include "mac_sys_reg.h"
#include "ahb.h"
#include "hw_desc.h"
#include "hw_phy_init.h"
#include "mac_raw_reg.h"
#include "mac_tmr_reg.h"
#include "mac_init_api.h"
/* HW WAR for cfg reg not take effect */
#include "mac_txq_hw.h"
#include "mac_status.h"
#include "mac_rx_buf_ring.h"
#include "os_task.h"
#include "phy_phase.h"
void enable_mac(uint32_t enable) {
#if HW_PLATFORM != HW_PLATFORM_SIMU
if (enable) {
ahb_mac_enable();
} else {
ahb_mac_disable();
}
#else
(void)enable;
#endif
return;
}
void warm_rst_mac_hold() {
#if HW_PLATFORM != HW_PLATFORM_SIMU
ahb_mac_reset_hold();
#endif
return;
}
void warm_rst_mac_release() {
#if HW_PLATFORM != HW_PLATFORM_SIMU
ahb_mac_reset_release();
#endif
return;
}
void mac_cfg_reg_reset()
{
#if HW_PLATFORM >= HW_PLATFORM_FPGA
ahb_mac_reset();
#endif
return;
}
void mac_reset(MAC_RST_REASON_ID rst_reason) {
(void)rst_reason;
enable_mac(true);
/* reset mac's logic */
warm_rst_mac_hold();
if (rst_reason == MAC_RST_REASON_COLD) {
/* reset mac's reg
* not reset all reg here, as the cfg reg reset
* not only reset mac reg, put it at phy_reset()
* kunlun2, we should able to reset mac's reg
*/
mac_cfg_reg_reset();
}
warm_rst_mac_release();
return;
}
void mac_warm_reset_war(uint32_t flag) {
(void)flag;
if (flag == CONT_RX_ABORT4) {
#if ENA_WAR_244
/* disable MAC RAW DATA MODE */
RGF_RAW_WRITE_REG(CFG_RAW_DATA_MODE_ADDR, 0);
/* clear pb size BB */
phy_rawdata_mode_bb_set_ps_tr(0,0,0);
#endif
} else if (flag == PHY_TX_HANG){
mac_new_phy_cfg_apply();
/* clear mac status cnt */
mac_status_cnt_clr();
}
}
void mac_set_sw_idle_mode(uint32_t ena, uint32_t is_idle) {
#if HW_PLATFORM >= HW_PLATFORM_FPGA
uint32_t tmp;
tmp = RGF_MAC_READ_REG(CFG_PHASE_BAND_SEL_ADDR);
REG_FIELD_SET(CFG_SW_IDLE_MODE_EN, tmp, ena);
REG_FIELD_SET(CFG_SW_IDLE_MODE, tmp, is_idle);
RGF_MAC_WRITE_REG(CFG_PHASE_BAND_SEL_ADDR, tmp);
#else
(void)ena;
(void)is_idle;
#endif
}
uint32_t mac_wait_phy_txrx_idle() {
#if HW_PLATFORM >= HW_PLATFORM_FPGA
/* return 0 for wait idle successful
* 1 for wait failed if timeout
*/
/* TODO: support timeout */
uint32_t tmp;
uint32_t tx_active;
uint32_t rx_active;
do {
tmp = RGF_MAC_READ_REG(CFG_RD_MACPHY_INTF_0_ADDR);
rx_active = REG_FIELD_GET(PHY_RX_ENABLE, tmp);
tx_active = REG_FIELD_GET(PHY_TX_ENABLE, tmp);
} while (tx_active && rx_active);
#else
#endif
return 0;
}
void mac_force_phy_tx_ready(uint32_t ena, uint32_t is_force_ready) {
#if HW_PLATFORM >= HW_PLATFORM_FPGA
/* make phy tx ready to 1 before mac disable hwq */
uint32_t tmp;
tmp = RGF_MAC_READ_REG(CFG_PHY_FORCE_2_ADDR);
REG_FIELD_SET(CFG_PHY_TX_READY_FORCE_EN, tmp, ena);
REG_FIELD_SET(CFG_PHY_TX_READY, tmp, is_force_ready);
RGF_MAC_WRITE_REG(CFG_PHY_FORCE_2_ADDR, tmp);
#else
(void)ena;
(void)is_force_ready;
#endif
return;
}
void mac_tx_wait_all_queue_idle() {
return;
}
void mac_sw_trig_need_en(bool_t ena)
{
#if HW_PLATFORM >= HW_PLATFORM_FPGA
uint32_t tmp;
tmp = RGF_MAC_READ_REG(CFG_MAC_TRX_START_ADDR);
REG_FIELD_SET(CFG_MAC_TRX_START_NEED_TRIG, tmp, ena);
RGF_MAC_WRITE_REG(CFG_MAC_TRX_START_ADDR, tmp);
#else
(void)ena;
(void)is_idle;
#endif
}
void mac_sw_trig_start(bool_t ena)
{
#if HW_PLATFORM >= HW_PLATFORM_FPGA
uint32_t tmp;
tmp = RGF_MAC_READ_REG(CFG_MAC_TRX_START_ADDR);
REG_FIELD_SET(CFG_MAC_TRX_START_TRIG, tmp, ena);
RGF_MAC_WRITE_REG(CFG_MAC_TRX_START_ADDR, tmp);
#else
(void)ena;
#endif
}
/* 1'b0: AHB clk and mac clk 1:1; 1'b1: 2:1 */
void mac_dma_ckl_sel(bool_t ena)
{
#if HW_PLATFORM > HW_PLATFORM_FPGA
uint32_t tmp = RGF_TMR_READ_REG(CFG_NTB_CFG_ADDR);
REG_FIELD_SET(CFG_DMA_CLK_SEL, tmp, ena);
RGF_TMR_WRITE_REG(CFG_NTB_CFG_ADDR, tmp);
#else
(void)ena;
#endif
}
uint32_t mac_get_phy_txrx_sts()
{
#if HW_PLATFORM >= HW_PLATFORM_FPGA
uint32_t tmp;
uint32_t tx_active;
uint32_t rx_active;
tmp = RGF_MAC_READ_REG(CFG_RD_MACPHY_INTF_0_ADDR);
rx_active = REG_FIELD_GET(PHY_RX_ENABLE, tmp);
tx_active = REG_FIELD_GET(PHY_TX_ENABLE, tmp);
if (rx_active == 0 && tx_active == 0) {
return MAC_PHY_IDLE_STS;
}
else if (rx_active == 1 && tx_active == 0) {
return MAC_PHY_RX_STS;
}
else if (rx_active == 0 && tx_active == 1) {
return MAC_PHY_TX_STS;
}
else if (rx_active == 1 && tx_active == 1) {
IOT_ASSERT(0);
return MAC_PHY_UNKNOW_STS;
}
#else
#endif
return 0;
}
/* NOTE: this function cannot call in interrupt */
uint32_t mac_set_sts_idle()
{
#if HW_PLATFORM >= HW_PLATFORM_FPGA
uint32_t tmp;
phy_force_0_access_require();
tmp = RGF_MAC_READ_REG(CFG_PHY_FORCE_0_ADDR);
REG_FIELD_SET(CFG_PHY_RX_FRAME_FORCE_EN, tmp, 1);
REG_FIELD_SET(CFG_PHY_RX_FRAME, tmp, 0);
REG_FIELD_SET(CFG_PHY_RX_VLD_FORCE_EN, tmp, 1);
REG_FIELD_SET(CFG_PHY_RX_VLD, tmp, 0);
REG_FIELD_SET(CFG_PHY_FC_CRC_DONE_FORCE_EN, tmp, 1);
REG_FIELD_SET(CFG_PHY_FC_CRC_DONE, tmp, 0);
REG_FIELD_SET(CFG_PHY_PB_CRC_DONE_FORCE_EN, tmp, 1);
REG_FIELD_SET(CFG_PHY_PB_CRC_DONE, tmp, 0);
RGF_MAC_WRITE_REG(CFG_PHY_FORCE_0_ADDR, tmp);
phy_force_0_access_release();
tmp = RGF_MAC_READ_REG(CFG_PHY_FORCE_1_ADDR);
REG_FIELD_SET(CFG_PHY_PB_RCV_DONE_FORCE_EN, tmp, 1);
REG_FIELD_SET(CFG_PHY_PB_RCV_DONE, tmp, 0);
REG_FIELD_SET(CFG_PHY_FC_RCV_DONE_FORCE_EN, tmp, 1);
REG_FIELD_SET(CFG_PHY_FC_RCV_DONE, tmp, 0);
RGF_MAC_WRITE_REG(CFG_PHY_FORCE_1_ADDR, tmp);
tmp = RGF_MAC_READ_REG(CFG_PHY_FORCE_2_ADDR);
REG_FIELD_SET(CFG_PHY_TX_READY_FORCE_EN, tmp, 1);
REG_FIELD_SET(CFG_PHY_TX_READY, tmp, 1);
RGF_MAC_WRITE_REG(CFG_PHY_FORCE_2_ADDR, tmp);
#else
#endif
return 0;
}
/* NOTE: this function cannot call in interrupt */
uint32_t mac_free_sts_idle()
{
#if HW_PLATFORM >= HW_PLATFORM_FPGA
uint32_t tmp;
phy_force_0_access_require();
tmp = RGF_MAC_READ_REG(CFG_PHY_FORCE_0_ADDR);
REG_FIELD_SET(CFG_PHY_RX_FRAME_FORCE_EN, tmp, 0);
REG_FIELD_SET(CFG_PHY_RX_FRAME, tmp, 0);
REG_FIELD_SET(CFG_PHY_RX_VLD_FORCE_EN, tmp, 0);
REG_FIELD_SET(CFG_PHY_RX_VLD, tmp, 0);
REG_FIELD_SET(CFG_PHY_FC_CRC_DONE_FORCE_EN, tmp, 0);
REG_FIELD_SET(CFG_PHY_FC_CRC_DONE, tmp, 0);
REG_FIELD_SET(CFG_PHY_PB_CRC_DONE_FORCE_EN, tmp, 0);
REG_FIELD_SET(CFG_PHY_PB_CRC_DONE, tmp, 0);
RGF_MAC_WRITE_REG(CFG_PHY_FORCE_0_ADDR, tmp);
phy_force_0_access_release();
tmp = RGF_MAC_READ_REG(CFG_PHY_FORCE_1_ADDR);
REG_FIELD_SET(CFG_PHY_PB_RCV_DONE_FORCE_EN, tmp, 0);
REG_FIELD_SET(CFG_PHY_PB_RCV_DONE, tmp, 0);
REG_FIELD_SET(CFG_PHY_FC_RCV_DONE_FORCE_EN, tmp, 0);
REG_FIELD_SET(CFG_PHY_FC_RCV_DONE, tmp, 0);
RGF_MAC_WRITE_REG(CFG_PHY_FORCE_1_ADDR, tmp);
tmp = RGF_MAC_READ_REG(CFG_PHY_FORCE_2_ADDR);
REG_FIELD_SET(CFG_PHY_TX_READY_FORCE_EN, tmp, 0);
REG_FIELD_SET(CFG_PHY_TX_READY, tmp, 0);
RGF_MAC_WRITE_REG(CFG_PHY_FORCE_2_ADDR, tmp);
#else
#endif
return 0;
}
uint32_t mac_dbg_bus_get_mac_sts(uint32_t value, uint32_t mask)
{
uint32_t debug_tmp;
mac_set_debug_reg(value);
debug_tmp = mac_rx_get_debug_reg();
/* if 0, then means idle */
return debug_tmp & mask;
}
/* NOTE: this function cannot call in interrupt */
uint32_t mac_set_pcs_busy(uint32_t enable, uint32_t value)
{
#if HW_PLATFORM >= HW_PLATFORM_FPGA
uint32_t tmp;
phy_force_0_access_require();
tmp = RGF_MAC_READ_REG(CFG_PHY_FORCE_0_ADDR);
REG_FIELD_SET(CFG_PHY_PCS_BUSY_FORCE_EN, tmp, enable);
REG_FIELD_SET(CFG_PHY_PCS_BUSY, tmp, value);
RGF_MAC_WRITE_REG(CFG_PHY_FORCE_0_ADDR, tmp);
phy_force_0_access_release();
#else
(void)enable;
(void)value;
#endif
return 0;
}
/* NOTE: this function cannot call in interrupt */
uint32_t mac_set_fc_crc_done(uint32_t enable, uint32_t value)
{
#if HW_PLATFORM >= HW_PLATFORM_FPGA
uint32_t tmp;
phy_force_0_access_require();
tmp = RGF_MAC_READ_REG(CFG_PHY_FORCE_0_ADDR);
REG_FIELD_SET(CFG_PHY_FC_CRC_DONE_FORCE_EN, tmp, enable);
REG_FIELD_SET(CFG_PHY_FC_CRC_DONE, tmp, value);
RGF_MAC_WRITE_REG(CFG_PHY_FORCE_0_ADDR, tmp);
phy_force_0_access_release();
#else
(void)enable;
(void)value;
#endif
return 0;
}
uint32_t mac_set_reg_tx_abort_debug_value()
{
#if HW_PLATFORM >= HW_PLATFORM_FPGA
uint32_t tmp;
tmp = RGF_MAC_READ_REG(CFG_PHY_FORCE_1_ADDR);
REG_FIELD_SET(CFG_PHY_TX_ABORT_FORCE_EN, tmp, 1);
REG_FIELD_SET(CFG_PHY_TX_ABORT, tmp, 0);
RGF_MAC_WRITE_REG(CFG_PHY_FORCE_1_ADDR, tmp);
#endif
return 0;
}
uint32_t mac_force_mac_phy_interface(uint32_t value)
{
#if HW_PLATFORM >= HW_PLATFORM_FPGA
uint32_t tmp;
tmp = RGF_MAC_READ_REG(CFG_PHY_FORCE_2_ADDR);
REG_FIELD_SET(CFG_PHY_TX_READY_FORCE_EN, tmp, value);
REG_FIELD_SET(CFG_PHY_TX_READY, tmp, value);
REG_FIELD_SET(CFG_PHY_TX_PROCESSING_FORCE_EN, tmp, value);
REG_FIELD_SET(CFG_PHY_TX_PROCESSING, tmp, value);
RGF_MAC_WRITE_REG(CFG_PHY_FORCE_2_ADDR, tmp);
#else
(void)value;
#endif
return 0;
}