687 lines
		
	
	
		
			19 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
		
		
			
		
	
	
			687 lines
		
	
	
		
			19 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_utils.h"
 | ||
|  | #include "mac.h"
 | ||
|  | #include "mac_rf_hwq_mgr.h"
 | ||
|  | #include "mac_rf_txq_hw.h"
 | ||
|  | #include "rfplc_reg_base.h"
 | ||
|  | #include "hw_reg_api.h"
 | ||
|  | #include "bb_cpu_mac_init.h"
 | ||
|  | #include "bb_cpu_mac_isr.h"
 | ||
|  | #include "bb_cpu_timer.h"
 | ||
|  | #include "bb_cpu_fsm.h"
 | ||
|  | #include "rf_mac_reg.h"
 | ||
|  | #include "mac_sys_reg.h"
 | ||
|  | #include "bb_rf_cfg.h"
 | ||
|  | #include "bb_cpu_hw_ring.h"
 | ||
|  | #include "mac_rf_common_hw.h"
 | ||
|  | #include "wmac_reg.h"
 | ||
|  | #include "bb_cpu_config.h"
 | ||
|  | #include "mpdu_header.h"
 | ||
|  | 
 | ||
|  | #define BB_CPU_CHECK_WMAC_FSM_DUE_TO_CMDLIST_DONE   1
 | ||
|  | #define BB_CPU_CHECK_WMAC_FSM_DUE_TO_EARLY_STOP     2
 | ||
|  | 
 | ||
|  | uint32_t bb_cpu_mac_get_txq_ptr() | ||
|  | { | ||
|  |     return RF_MAC_READ_REG(CFG_RF_MAC_CUR_TX_PTR_ADDR); | ||
|  | } | ||
|  | 
 | ||
|  | uint32_t bb_cpu_mac_get_rx_crc32_check() | ||
|  | { | ||
|  |     // TODO: get rx crc32 need check or not
 | ||
|  |     return 0; | ||
|  | } | ||
|  | 
 | ||
|  | uint32_t bb_cpu_mac_get_cur_hwqid() | ||
|  | { | ||
|  |     uint32_t tmp, sel_bitmap, hwq_id = MAX_MAC_RF_TXQ_NUM; | ||
|  |     tmp = RF_MAC_READ_REG(CFG_RF_MAC_DEBUG_BUS0_ADDR); | ||
|  |     sel_bitmap = REG_FIELD_GET(RF_MAC_TXQ_SEL_BIT_MAP, tmp); | ||
|  |     if (sel_bitmap) { | ||
|  |         hwq_id = iot_bitops_fls(sel_bitmap) - 1; | ||
|  |         if (sel_bitmap & (~(1 << hwq_id))) { | ||
|  |             iot_printf("selbit err:0x%x, cmdbitmap:0x%x\n", sel_bitmap, | ||
|  |                 REG_FIELD_GET(RF_MAC_TXQ_BITMAP_2CPU2, tmp)); | ||
|  |             IOT_ASSERT(0); | ||
|  |         } | ||
|  |     } else { | ||
|  |         iot_printf("selbit is 0\n"); | ||
|  |         IOT_ASSERT(0); | ||
|  |     } | ||
|  | 
 | ||
|  |     return hwq_id; | ||
|  | } | ||
|  | 
 | ||
|  | uint32_t bb_cpu_mac_judge_cur_cmd_need_tx_csma() | ||
|  | { | ||
|  |     uint32_t tmp, txq_bit_map, ret = 0; | ||
|  |     if (mac_rf_txq_is_dbg_mode()) { | ||
|  |         tmp = RF_MAC_READ_REG(CFG_RF_MAC_DEBUG_CFG_ADDR); | ||
|  |         txq_bit_map = REG_FIELD_GET(RF_MAC_DEBUG_TXQ_BITMAP, tmp); | ||
|  |     } else { | ||
|  |         tmp = RF_MAC_READ_REG(CFG_RF_MAC_DEBUG_BUS0_ADDR); | ||
|  |         txq_bit_map = REG_FIELD_GET(RF_MAC_TXQ_BITMAP_2CPU2, tmp); | ||
|  |     } | ||
|  |     if (txq_bit_map & (1 << MAC_RF_QUE_CSMA_0) || | ||
|  |         txq_bit_map & (1 << MAC_RF_QUE_CSMA_1) || | ||
|  |         txq_bit_map & (1 << MAC_RF_QUE_CSMA_2) || | ||
|  |         txq_bit_map & (1 << MAC_RF_QUE_CSMA_3) || | ||
|  |         txq_bit_map & (1 << MAC_RF_QUE_CSMA_DBG) || | ||
|  |         txq_bit_map & (1 << MAC_RF_QUE_BCSMA)) { | ||
|  |         ret = 1; | ||
|  |     } | ||
|  |     return ret; | ||
|  | } | ||
|  | 
 | ||
|  | uint32_t bb_cpu_mac_judge_cur_cmd_need_tx_tdma() | ||
|  | { | ||
|  |     uint32_t tmp, txq_bit_map, ret = 0; | ||
|  |     if (mac_rf_txq_is_dbg_mode()) { | ||
|  |         tmp = RF_MAC_READ_REG(CFG_RF_MAC_DEBUG_CFG_ADDR); | ||
|  |         txq_bit_map = REG_FIELD_GET(RF_MAC_DEBUG_TXQ_BITMAP, tmp); | ||
|  |     } else { | ||
|  |         tmp = RF_MAC_READ_REG(CFG_RF_MAC_DEBUG_BUS0_ADDR); | ||
|  |         txq_bit_map = REG_FIELD_GET(RF_MAC_TXQ_BITMAP_2CPU2, tmp); | ||
|  |     } | ||
|  |     if (txq_bit_map & (1 << MAC_RF_QUE_BCN) || | ||
|  |         txq_bit_map & (1 << MAC_RF_QUE_TDMA)) { | ||
|  |         ret = 1; | ||
|  |     } | ||
|  |     return ret; | ||
|  | } | ||
|  | 
 | ||
|  | uint32_t bb_cpu_mac_judge_next_cmd_is_vld() | ||
|  | { | ||
|  |     uint32_t tmp, is_vld; | ||
|  |     tmp = RF_MAC_READ_REG(CFG_RF_MAC_DEBUG_BUS1_ADDR); | ||
|  |     is_vld = REG_FIELD_GET(RF_MAC_NEXT_CMD_VLD_2CPU2, tmp); | ||
|  |     (void)is_vld; | ||
|  |     /* NOTE: this function is bad */ | ||
|  |     return 0; | ||
|  | } | ||
|  | 
 | ||
|  | uint32_t bb_cpu_mac_judge_next_cmd_need_tx_tdma() | ||
|  | { | ||
|  |     uint32_t tmp, is_vld, txq_bit_map, ret = 0; | ||
|  |     tmp = RF_MAC_READ_REG(CFG_RF_MAC_DEBUG_BUS1_ADDR); | ||
|  |     is_vld = REG_FIELD_GET(RF_MAC_NEXT_CMD_VLD_2CPU2, tmp); | ||
|  |     if (is_vld) { | ||
|  |         txq_bit_map = REG_FIELD_GET(RF_MAC_NEXT_TXQ_BITMAP_2CPU2, tmp); | ||
|  |         if (txq_bit_map & (1 << MAC_RF_QUE_BCN) || | ||
|  |             txq_bit_map & (1 << MAC_RF_QUE_TDMA)) { | ||
|  |             ret = 1; | ||
|  |         } | ||
|  |     } | ||
|  |     return ret; | ||
|  | } | ||
|  | 
 | ||
|  | uint32_t bb_cpu_mac_get_rest_slot_time() | ||
|  | { | ||
|  |     uint32_t remain_time = RF_MAC_READ_REG(CFG_RF_MAC_SLICE_TIME_LEFT_ADDR); | ||
|  |     /* uint us */ | ||
|  |     return remain_time/25; | ||
|  | } | ||
|  | 
 | ||
|  | void bb_cpu_mac_inter_pkt_interval(uint32_t interval) | ||
|  | { | ||
|  |     /* uint us */ | ||
|  |     RF_MAC_WRITE_REG(CFG_RF_MAC_PKT_INTERVAL_TIME_ADDR, (interval * 25)); | ||
|  | } | ||
|  | 
 | ||
|  | /* NOTE: CFG_RF_MAC_TXRX_CTL_ADDR need atomic operations
 | ||
|  |  * | ||
|  |  * this function in isr, so it do not need stop bbcpu irq. | ||
|  |  */ | ||
|  | void bb_cpu_mac_set_vcs_sts_from_isr(uint32_t is_busy) | ||
|  | { | ||
|  |     uint32_t tmp = RF_MAC_READ_REG(CFG_RF_MAC_TXRX_CTL_ADDR); | ||
|  |     REG_FIELD_SET(RF_MAC_VCS_STATUS, tmp, is_busy); | ||
|  |     RF_MAC_WRITE_REG(CFG_RF_MAC_TXRX_CTL_ADDR, tmp); | ||
|  | } | ||
|  | 
 | ||
|  | uint32_t bb_cpu_mac_get_vcs_sts() | ||
|  | { | ||
|  |     uint32_t tmp = RF_MAC_READ_REG(CFG_RF_MAC_TXRX_CTL_ADDR); | ||
|  |     return REG_FIELD_GET(RF_MAC_VCS_STATUS, tmp); | ||
|  | } | ||
|  | 
 | ||
|  | void bb_cpu_mac_set_tx_done() | ||
|  | { | ||
|  |     /* NOTE: make sure CFG_RF_MAC_TXRX_CTL_ADDR is atomic operations,
 | ||
|  |      *       we need stop bbcpu irq. | ||
|  |      */ | ||
|  |     /* disable irq */ | ||
|  |     bb_cpu_mac_isr_stop(); | ||
|  | 
 | ||
|  |     uint32_t tmp = RF_MAC_READ_REG(CFG_RF_MAC_TXRX_CTL_ADDR); | ||
|  |     REG_FIELD_SET(RF_MAC_TX_DONE_CPU2, tmp, 1); | ||
|  |     RF_MAC_WRITE_REG(CFG_RF_MAC_TXRX_CTL_ADDR, tmp); | ||
|  | 
 | ||
|  |     /* enable irq */ | ||
|  |     bb_cpu_mac_isr_start(); | ||
|  | } | ||
|  | 
 | ||
|  | void bb_cpu_mac_set_rx_done() | ||
|  | { | ||
|  |     /* NOTE: make sure CFG_RF_MAC_TXRX_CTL_ADDR is atomic operations,
 | ||
|  |      *       we need stop bbcpu irq. | ||
|  |      */ | ||
|  |     /* disable irq */ | ||
|  |     bb_cpu_mac_isr_stop(); | ||
|  | 
 | ||
|  |     uint32_t tmp = RF_MAC_READ_REG(CFG_RF_MAC_TXRX_CTL_ADDR); | ||
|  |     REG_FIELD_SET(RF_MAC_RX_DONE_CPU2, tmp, 1); | ||
|  |     RF_MAC_WRITE_REG(CFG_RF_MAC_TXRX_CTL_ADDR, tmp); | ||
|  | 
 | ||
|  |     /* enable irq */ | ||
|  |     bb_cpu_mac_isr_start(); | ||
|  | } | ||
|  | 
 | ||
|  | void bb_cpu_mac_set_tx_abort_done() | ||
|  | { | ||
|  |     /* NOTE: make sure CFG_RF_MAC_TXRX_CTL_ADDR is atomic operations,
 | ||
|  |      *       we need stop bbcpu irq. | ||
|  |      */ | ||
|  |     /* disable irq */ | ||
|  |     bb_cpu_mac_isr_stop(); | ||
|  | 
 | ||
|  |     uint32_t tmp = RF_MAC_READ_REG(CFG_RF_MAC_TXRX_CTL_ADDR); | ||
|  |     REG_FIELD_SET(RF_MAC_TX_ABORT_DONE_CPU2, tmp, 1); | ||
|  |     RF_MAC_WRITE_REG(CFG_RF_MAC_TXRX_CTL_ADDR, tmp); | ||
|  | 
 | ||
|  |     /* enable irq */ | ||
|  |     bb_cpu_mac_isr_start(); | ||
|  | } | ||
|  | 
 | ||
|  | void bb_cpu_mac_set_rx_abort_done() | ||
|  | { | ||
|  |     /* NOTE: make sure CFG_RF_MAC_TXRX_CTL_ADDR is atomic operations,
 | ||
|  |      *       we need stop bbcpu irq. | ||
|  |      */ | ||
|  |     /* disable irq */ | ||
|  |     bb_cpu_mac_isr_stop(); | ||
|  | 
 | ||
|  |     uint32_t tmp = RF_MAC_READ_REG(CFG_RF_MAC_TXRX_CTL_ADDR); | ||
|  |     REG_FIELD_SET(RF_MAC_RX_ABORT_DONE_CPU2, tmp, 1); | ||
|  |     RF_MAC_WRITE_REG(CFG_RF_MAC_TXRX_CTL_ADDR, tmp); | ||
|  | 
 | ||
|  |     /* enable irq */ | ||
|  |     bb_cpu_mac_isr_start(); | ||
|  | } | ||
|  | 
 | ||
|  | static uint32_t bb_cpu_mac_check_fsm(uint32_t reason, uint32_t is_assert) | ||
|  | { | ||
|  | #define RESET_FSM_TIME_NTB   250  // 10US * 25
 | ||
|  |     uint32_t start_ntb, cur_ntb, time_span; | ||
|  |     uint32_t wmac_fsm; | ||
|  | 
 | ||
|  |     /* wait reset fsm complete */ | ||
|  |     start_ntb = RGF_MAC_READ_REG(CFG_RD_LOCAL_TMR_ADDR); | ||
|  |     do { | ||
|  |         /* reset txrx fsm */ | ||
|  |         mac_rf_reset_txrxfsm(); | ||
|  |         cur_ntb = RGF_MAC_READ_REG(CFG_RD_LOCAL_TMR_ADDR); | ||
|  |         time_span = cur_ntb - start_ntb; | ||
|  |         wmac_fsm = mac_rf_wmac_get_fsm(); | ||
|  |     } while (wmac_fsm && time_span < RESET_FSM_TIME_NTB); | ||
|  | 
 | ||
|  |     /* just check wmac fsm */ | ||
|  |     if (wmac_fsm) { | ||
|  |         bb_cpu_printf("reason:%d, fsm:0x%x, lft:%lu\n", reason, wmac_fsm, | ||
|  |             bb_cpu_mac_get_rest_slot_time()); | ||
|  |         if (is_assert) { | ||
|  |             IOT_ASSERT(0); | ||
|  |         } | ||
|  |     } | ||
|  | 
 | ||
|  |     return wmac_fsm; | ||
|  | } | ||
|  | 
 | ||
|  | uint32_t bb_cpu_mac_set_sched_stop_done(uint32_t times) | ||
|  | { | ||
|  |     /* NOTE: make sure CFG_RF_MAC_TXRX_CTL_ADDR is atomic operations,
 | ||
|  |      *       we need stop bbcpu irq. | ||
|  |      */ | ||
|  |     /* disable irq */ | ||
|  |     bb_cpu_mac_isr_stop(); | ||
|  | 
 | ||
|  |     uint32_t tmp = RF_MAC_READ_REG(CFG_RF_MAC_TXRX_CTL_ADDR); | ||
|  |     REG_FIELD_SET(RF_MAC_EARLY_STOP_DONE, tmp, 1); | ||
|  |     RF_MAC_WRITE_REG(CFG_RF_MAC_TXRX_CTL_ADDR, tmp); | ||
|  | 
 | ||
|  |     /* enable irq */ | ||
|  |     bb_cpu_mac_isr_start(); | ||
|  | 
 | ||
|  |     /* wmac fsm check */ | ||
|  |     return bb_cpu_mac_check_fsm(BB_CPU_CHECK_WMAC_FSM_DUE_TO_EARLY_STOP, | ||
|  |         (times > 1)); | ||
|  | } | ||
|  | 
 | ||
|  | void bb_cpu_mac_set_csma_is_ready() | ||
|  | { | ||
|  |     uint32_t tmp = RF_MAC_READ_REG(CFG_RF_MAC_PKT_INTERVAL_TIME_CTL_ADDR); | ||
|  |     REG_FIELD_SET(RF_MAC_CSMA_CPU2_READY, tmp, 1); | ||
|  |     RF_MAC_WRITE_REG(CFG_RF_MAC_PKT_INTERVAL_TIME_CTL_ADDR, tmp); | ||
|  | } | ||
|  | 
 | ||
|  | void bb_cpu_mac_set_cmdlist_done() | ||
|  | { | ||
|  |     /* rf mac cmdlist done */ | ||
|  |     uint32_t tmp = RF_MAC_READ_REG(CFG_RF_MAC_PKT_INTERVAL_TIME_CTL_ADDR); | ||
|  |     REG_FIELD_SET(RF_MAC_CMDLIST_EARLY_STOP_DONE, tmp, 1); | ||
|  |     RF_MAC_WRITE_REG(CFG_RF_MAC_PKT_INTERVAL_TIME_CTL_ADDR, tmp); | ||
|  | 
 | ||
|  |     /* wmac cmdlist done */ | ||
|  |     tmp = WMAC_READ_REG(CFG_WMAC_CTRL_ADDR); | ||
|  |     REG_FIELD_SET(SW_CMDLIST_DONE_CPU2_IDLE_PLS, tmp, 1); | ||
|  |     WMAC_WRITE_REG(CFG_WMAC_CTRL_ADDR, tmp); | ||
|  | 
 | ||
|  |     /* check wmac fsm */ | ||
|  |     bb_cpu_mac_check_fsm(BB_CPU_CHECK_WMAC_FSM_DUE_TO_CMDLIST_DONE, 1); | ||
|  | } | ||
|  | 
 | ||
|  | void bb_cpu_mac_tx_timer_en(uint32_t enable) | ||
|  | { | ||
|  |     /* start rf mac tx timer */ | ||
|  |     uint32_t tmp = RF_MAC_READ_REG(CFG_RF_MAC_BB_EVT_CTL_ADDR); | ||
|  |     REG_FIELD_SET(RF_MAC_BB_TX_TIMER_EN, tmp, enable); | ||
|  |     RF_MAC_WRITE_REG(CFG_RF_MAC_BB_EVT_CTL_ADDR, tmp); | ||
|  | } | ||
|  | 
 | ||
|  | void bb_cpu_mac_stop_listen_timer_en(uint32_t enable) | ||
|  | { | ||
|  |     /* start rf mac stop listen timer */ | ||
|  |     uint32_t tmp = RF_MAC_READ_REG(CFG_RF_MAC_BB_EVT_CTL_ADDR); | ||
|  |     REG_FIELD_SET(RF_MAC_BB_EVT4_TIMER_EN, tmp, enable); | ||
|  |     RF_MAC_WRITE_REG(CFG_RF_MAC_BB_EVT_CTL_ADDR, tmp); | ||
|  | } | ||
|  | 
 | ||
|  | uint32_t bb_cpu_mac_trigger_tx(uint32_t *phr) | ||
|  | { | ||
|  |     uint32_t tmp, is_beacon = 0, recorc_ntb, tmp_ntb, tx_gap; | ||
|  | 
 | ||
|  |     /* start bb tx timer every time */ | ||
|  |     bb_rf_tx_timer_en(1); | ||
|  | 
 | ||
|  |     /* start rf mac tx timer */ | ||
|  |     bb_cpu_mac_tx_timer_en(1); | ||
|  | 
 | ||
|  |     /* set tx rf timer, unit ntb */ | ||
|  |     RF_MAC_WRITE_REG(CFG_RF_MAC_BB_TX_RF_TIMER_VALUE_ADDR, BB_CPU_AOTX_TIME); | ||
|  |     /* tx bb time - tx rf time > 50us */ | ||
|  |     /* set tx bb timer, unit ntb */ | ||
|  |     RF_MAC_WRITE_REG(CFG_RF_MAC_BB_TX_BB_TIMER_VALUE_ADDR, BB_CPU_SOTX_TIME); | ||
|  | 
 | ||
|  |     /* start rf mac stop listen timer */ | ||
|  |     bb_cpu_mac_stop_listen_timer_en(1); | ||
|  |     /* set evt bit4 timer, unit ntb */ | ||
|  |     RF_MAC_WRITE_REG(CFG_RF_MAC_BB_EVT4_TIMER_VALUE_ADDR, | ||
|  |         BB_CPU_NOTX_TIME); | ||
|  | 
 | ||
|  |     if (phr) { | ||
|  |         bb_cpu_rf_fc_t fc_msg = {0}; | ||
|  |         bb_cpu_mac_get_msg_from_phr(bb_cpu_get_proto(), phr, &fc_msg); | ||
|  |         is_beacon = (fc_msg.delimiter == FC_DELIM_BEACON); | ||
|  |         if (is_beacon) { | ||
|  |             /* disable irq */ | ||
|  |             bb_cpu_mac_isr_stop(); | ||
|  |         } | ||
|  |     } | ||
|  | 
 | ||
|  |     /* record rx stop ntb */ | ||
|  |     recorc_ntb = bb_cpu_mac_get_stop_rx_evt_ntb(); | ||
|  | 
 | ||
|  |     /* start tx */ | ||
|  |     tmp = RF_MAC_READ_REG(CFG_RF_MAC_BB_EVT_CTL_ADDR); | ||
|  |     REG_FIELD_SET(RF_MAC_BB_EVT_BIT4, tmp, 1); | ||
|  |     REG_FIELD_SET(RF_MAC_BB_EVT_BIT01, tmp, 1); | ||
|  |     RF_MAC_WRITE_REG(CFG_RF_MAC_BB_EVT_CTL_ADDR, tmp); | ||
|  | 
 | ||
|  |     /* make sure rx stop has triggered */ | ||
|  |     do { | ||
|  |         tmp_ntb = bb_cpu_mac_get_stop_rx_evt_ntb(); | ||
|  |     } while (recorc_ntb == tmp_ntb); | ||
|  | 
 | ||
|  |     /* config beacon timestamp */ | ||
|  |     tx_gap = bb_cpu_get_tx_golden_gap(mac_rf_get_option()); | ||
|  |     if (phr && is_beacon) { | ||
|  |         /* update timestamp */ | ||
|  |         switch (bb_cpu_get_proto()) { | ||
|  | #if SUPPORT_SMART_GRID
 | ||
|  |         case PLC_PROTO_TYPE_SG: | ||
|  |         { | ||
|  |             frame_control_t *phr_t = (frame_control_t *)phr; | ||
|  |             phr_t->vf.rf_bcn.time_stamp = tx_gap + tmp_ntb; | ||
|  |             break; | ||
|  |         } | ||
|  | #endif
 | ||
|  | #if SUPPORT_SOUTHERN_POWER_GRID
 | ||
|  |         case PLC_PROTO_TYPE_SPG: | ||
|  |         { | ||
|  |             spg_frame_control_t *phr_t = (spg_frame_control_t *)phr; | ||
|  |             phr_t->vf.rf_bcn.time_stamp = tx_gap + tmp_ntb; | ||
|  |             break; | ||
|  |         } | ||
|  | #endif
 | ||
|  |         default: | ||
|  |             IOT_ASSERT(0); | ||
|  |             break; | ||
|  |         } | ||
|  | 
 | ||
|  |         /* set phr */ | ||
|  |         bb_rf_set_tx_phr((uint32_t *)phr); | ||
|  |         /* enable irq */ | ||
|  |         bb_cpu_mac_isr_start(); | ||
|  |     } | ||
|  |     return tx_gap + tmp_ntb; | ||
|  | } | ||
|  | 
 | ||
|  | void bb_cpu_mac_rx_timer_en(uint32_t enable) | ||
|  | { | ||
|  |     /* start rf mac rx timer */ | ||
|  |     uint32_t tmp = RF_MAC_READ_REG(CFG_RF_MAC_BB_EVT_CTL_ADDR); | ||
|  |     REG_FIELD_SET(RF_MAC_BB_RX_TIMER_EN, tmp, enable); | ||
|  |     RF_MAC_WRITE_REG(CFG_RF_MAC_BB_EVT_CTL_ADDR, tmp); | ||
|  | } | ||
|  | 
 | ||
|  | void bb_cpu_mac_trigger_rx() | ||
|  | { | ||
|  |     uint32_t tmp; | ||
|  | 
 | ||
|  |     /* start bb rx timer every time */ | ||
|  |     bb_rf_rx_timer_en(1); | ||
|  | 
 | ||
|  |     /* start rf mac rx timer */ | ||
|  |     bb_cpu_mac_rx_timer_en(1); | ||
|  | 
 | ||
|  |     /* set tx rf timer, unit ntb */ | ||
|  |     RF_MAC_WRITE_REG(CFG_RF_MAC_BB_RX_RF_TIMER_VALUE_ADDR, 2); | ||
|  |     /* tx bb time - tx rf time > 50us */ | ||
|  |     /* set tx bb timer, unit ntb */ | ||
|  |     RF_MAC_WRITE_REG(CFG_RF_MAC_BB_RX_BB_TIMER_VALUE_ADDR, (51 * 25)); | ||
|  | 
 | ||
|  |     /* start rx */ | ||
|  |     tmp = RF_MAC_READ_REG(CFG_RF_MAC_BB_EVT_CTL_ADDR); | ||
|  |     REG_FIELD_SET(RF_MAC_BB_EVT_BIT23, tmp, 1); | ||
|  |     RF_MAC_WRITE_REG(CFG_RF_MAC_BB_EVT_CTL_ADDR, tmp); | ||
|  | } | ||
|  | 
 | ||
|  | void bb_cpu_mac_trigger_stop_listen() | ||
|  | { | ||
|  |     uint32_t tmp; | ||
|  | 
 | ||
|  |     /* start bb stop listen timer every time */ | ||
|  |     bb_rf_stop_listen_timer_en(1); | ||
|  | 
 | ||
|  |     /* start rf mac stop listen timer */ | ||
|  |     bb_cpu_mac_stop_listen_timer_en(1); | ||
|  | 
 | ||
|  |     /* set evt bit4 timer, unit ntb */ | ||
|  |     RF_MAC_WRITE_REG(CFG_RF_MAC_BB_EVT4_TIMER_VALUE_ADDR, 2); | ||
|  | 
 | ||
|  |     /* stop listen */ | ||
|  |     tmp = RF_MAC_READ_REG(CFG_RF_MAC_BB_EVT_CTL_ADDR); | ||
|  |     REG_FIELD_SET(RF_MAC_BB_EVT_BIT4, tmp, 1); | ||
|  |     RF_MAC_WRITE_REG(CFG_RF_MAC_BB_EVT_CTL_ADDR, tmp); | ||
|  | } | ||
|  | 
 | ||
|  | uint32_t bb_cpu_mac_get_tx_complete_ntb() | ||
|  | { | ||
|  |     return RF_MAC_READ_REG(CFG_RF_MAC_BB_DEBUG_NTB_TMR_0_REG_ADDR); | ||
|  | } | ||
|  | 
 | ||
|  | uint32_t bb_cpu_mac_get_tx_complete_local_ntb() | ||
|  | { | ||
|  |     return RF_MAC_READ_REG(CFG_RF_MAC_BB_DEBUG_LOCAL_TMR_0_REG_ADDR); | ||
|  | } | ||
|  | 
 | ||
|  | uint32_t bb_cpu_mac_get_stop_listen_ntb() | ||
|  | { | ||
|  |     return RF_MAC_READ_REG(CFG_RF_MAC_BB_DEBUG_NTB_TMR_1_REG_ADDR); | ||
|  | } | ||
|  | 
 | ||
|  | uint32_t bb_cpu_mac_get_stop_listen_local_ntb() | ||
|  | { | ||
|  |     return RF_MAC_READ_REG(CFG_RF_MAC_BB_DEBUG_LOCAL_TMR_1_REG_ADDR); | ||
|  | } | ||
|  | 
 | ||
|  | uint32_t bb_cpu_mac_get_rx_stf_ntb() | ||
|  | { | ||
|  |     return RF_MAC_READ_REG(CFG_RF_MAC_BB_DEBUG_NTB_TMR_2_REG_ADDR); | ||
|  | } | ||
|  | 
 | ||
|  | uint32_t bb_cpu_mac_get_rx_stf_local_ntb() | ||
|  | { | ||
|  |     return RF_MAC_READ_REG(CFG_RF_MAC_BB_DEBUG_LOCAL_TMR_2_REG_ADDR); | ||
|  | } | ||
|  | 
 | ||
|  | uint32_t bb_cpu_mac_get_rx_sig_ntb() | ||
|  | { | ||
|  |     return RF_MAC_READ_REG(CFG_RF_MAC_BB_DEBUG_NTB_TMR_3_REG_ADDR); | ||
|  | } | ||
|  | 
 | ||
|  | uint32_t bb_cpu_mac_get_rx_sig_local_ntb() | ||
|  | { | ||
|  |     return RF_MAC_READ_REG(CFG_RF_MAC_BB_DEBUG_LOCAL_TMR_3_REG_ADDR); | ||
|  | } | ||
|  | 
 | ||
|  | uint32_t bb_cpu_mac_get_rx_phr_ntb() | ||
|  | { | ||
|  |     return RF_MAC_READ_REG(CFG_RF_MAC_BB_DEBUG_NTB_TMR_4_REG_ADDR); | ||
|  | } | ||
|  | 
 | ||
|  | uint32_t bb_cpu_mac_get_rx_phr_local_ntb() | ||
|  | { | ||
|  |     return RF_MAC_READ_REG(CFG_RF_MAC_BB_DEBUG_LOCAL_TMR_4_REG_ADDR); | ||
|  | } | ||
|  | 
 | ||
|  | uint32_t bb_cpu_mac_get_rx_pld_start_ntb() | ||
|  | { | ||
|  |     return RF_MAC_READ_REG(CFG_RF_MAC_BB_DEBUG_NTB_TMR_5_REG_ADDR); | ||
|  | } | ||
|  | 
 | ||
|  | uint32_t bb_cpu_mac_get_rx_pld_start_local_ntb() | ||
|  | { | ||
|  |     return RF_MAC_READ_REG(CFG_RF_MAC_BB_DEBUG_LOCAL_TMR_5_REG_ADDR); | ||
|  | } | ||
|  | 
 | ||
|  | uint32_t bb_cpu_mac_get_rf_tx_ntb() | ||
|  | { | ||
|  |     return WMAC_READ_REG(CFG_WMAC_EVT_I_0_NTB_TMR_STS_ADDR); | ||
|  | } | ||
|  | 
 | ||
|  | uint32_t bb_cpu_mac_get_bb_tx_ntb() | ||
|  | { | ||
|  |     return WMAC_READ_REG(CFG_WMAC_EVT_I_1_NTB_TMR_STS_ADDR); | ||
|  | } | ||
|  | 
 | ||
|  | uint32_t bb_cpu_mac_get_rf_rx_ntb() | ||
|  | { | ||
|  |     return WMAC_READ_REG(CFG_WMAC_EVT_I_2_NTB_TMR_STS_ADDR); | ||
|  | } | ||
|  | 
 | ||
|  | uint32_t bb_cpu_mac_get_bb_rx_ntb() | ||
|  | { | ||
|  |     return WMAC_READ_REG(CFG_WMAC_EVT_I_3_NTB_TMR_STS_ADDR); | ||
|  | } | ||
|  | 
 | ||
|  | uint32_t bb_cpu_mac_get_stop_rx_evt_ntb() | ||
|  | { | ||
|  |     return WMAC_READ_REG(CFG_WMAC_EVT_I_4_NTB_TMR_STS_ADDR); | ||
|  | } | ||
|  | 
 | ||
|  | uint32_t bb_cpu_mac_get_rf_tx_local_ntb() | ||
|  | { | ||
|  |     return WMAC_READ_REG(CFG_WMAC_EVT_I_0_LOCAL_TMR_STS_ADDR); | ||
|  | } | ||
|  | 
 | ||
|  | uint32_t bb_cpu_mac_get_bb_tx_local_ntb() | ||
|  | { | ||
|  |     return WMAC_READ_REG(CFG_WMAC_EVT_I_1_LOCAL_TMR_STS_ADDR); | ||
|  | } | ||
|  | 
 | ||
|  | uint32_t bb_cpu_mac_get_rf_rx_local_ntb() | ||
|  | { | ||
|  |     return WMAC_READ_REG(CFG_WMAC_EVT_I_2_LOCAL_TMR_STS_ADDR); | ||
|  | } | ||
|  | 
 | ||
|  | uint32_t bb_cpu_mac_get_bb_rx_local_ntb() | ||
|  | { | ||
|  |     return WMAC_READ_REG(CFG_WMAC_EVT_I_3_LOCAL_TMR_STS_ADDR); | ||
|  | } | ||
|  | 
 | ||
|  | uint32_t bb_cpu_mac_get_stop_rx_evt_local_ntb() | ||
|  | { | ||
|  |     return WMAC_READ_REG(CFG_WMAC_EVT_I_4_LOCAL_TMR_STS_ADDR); | ||
|  | } | ||
|  | 
 | ||
|  | uint32_t bb_cpu_mac_get_hwq_cur_ptr(uint32_t hwqid) | ||
|  | { | ||
|  |     uint32_t cur_ptr_dlt = CFG_WMAC_WMAC_CURRENT_TX_PTR1_ADDR - | ||
|  |         CFG_WMAC_WMAC_CURRENT_TX_PTR0_ADDR; | ||
|  | 
 | ||
|  |     return WMAC_READ_REG(CFG_WMAC_WMAC_CURRENT_TX_PTR0_ADDR + | ||
|  |         hwqid * cur_ptr_dlt); | ||
|  | } | ||
|  | 
 | ||
|  | uint32_t bb_cpu_mac_get_hwqfsm() | ||
|  | { | ||
|  |     return WMAC_READ_REG(CFG_WMAC_TXQ_FSM_STS_ADDR); | ||
|  | } | ||
|  | 
 | ||
|  | void bb_cpu_dma_start(uint32_t bb_addr, uint32_t pb_addr, uint32_t byte_size) | ||
|  | { | ||
|  |     (void)bb_addr; | ||
|  |     (void)pb_addr; | ||
|  |     (void)byte_size; | ||
|  | } | ||
|  | 
 | ||
|  | void bb_cpu_dma_stop() | ||
|  | { | ||
|  | } | ||
|  | 
 | ||
|  | void bb_cpu_mac_init(void) | ||
|  | { | ||
|  |     bb_cpu_hw_ring_init(); | ||
|  |     bb_cpu_mac_isr_init(); | ||
|  |     bb_cpu_mac_isr_enable(); | ||
|  |     bb_cpu_timer_enable(); | ||
|  |     bb_cpu_mac_isr_start(); | ||
|  | } | ||
|  | 
 | ||
|  | void bb_cpu_mac_get_msg_from_phr(uint32_t proto, void *phr, bb_cpu_rf_fc_t *msg) | ||
|  | { | ||
|  |     switch (proto) { | ||
|  | #if SUPPORT_SMART_GRID
 | ||
|  |     case PLC_PROTO_TYPE_SG: | ||
|  |     { | ||
|  |         /* nid share the same place for SG */ | ||
|  |         frame_control_t *sg_phr = (frame_control_t *)phr; | ||
|  |         msg->nid = sg_phr->nid; | ||
|  |         msg->delimiter = sg_phr->delimiter_type; | ||
|  |         switch (sg_phr->delimiter_type) { | ||
|  |         case FC_DELIM_BEACON: | ||
|  |         { | ||
|  |             msg->rf_mcs = (uint8_t)sg_phr->vf.rf_bcn.mcs; | ||
|  |             msg->rf_pb_sz_idx = (uint8_t)sg_phr->vf.rf_bcn.pb_sz_idx; | ||
|  |             msg->src_tei = sg_phr->vf.rf_bcn.src_tei; | ||
|  |             break; | ||
|  |         } | ||
|  |         case FC_DELIM_SOF: | ||
|  |         { | ||
|  |             msg->dst_tei = sg_phr->vf.rf_sof.dst_tei; | ||
|  |             msg->src_tei = sg_phr->vf.rf_sof.src_tei; | ||
|  |             msg->rf_pb_sz_idx = (uint8_t)sg_phr->vf.rf_sof.pb_sz_idx; | ||
|  |             msg->rf_mcs = (uint8_t)sg_phr->vf.rf_sof.mcs; | ||
|  |             break; | ||
|  |         } | ||
|  |         case FC_DELIM_SACK: | ||
|  |         { | ||
|  |             msg->result_in_sack = sg_phr->vf.rf_sack.rx_result; | ||
|  |             msg->dst_tei = sg_phr->vf.rf_sack.dtei; | ||
|  |             msg->src_tei = sg_phr->vf.rf_sack.stei; | ||
|  |             break; | ||
|  |         } | ||
|  |         default: | ||
|  |             break; | ||
|  |         } | ||
|  |         break; | ||
|  |     } | ||
|  | #endif
 | ||
|  | 
 | ||
|  | #if SUPPORT_SOUTHERN_POWER_GRID
 | ||
|  |     case PLC_PROTO_TYPE_SPG: | ||
|  |     { | ||
|  |         spg_frame_control_t *spg_phr = (spg_frame_control_t *)phr; | ||
|  |         msg->nid = spg_phr->snid; | ||
|  |         msg->delimiter = spg_phr->delimiter_type; | ||
|  |         switch (spg_phr->delimiter_type) { | ||
|  |         case FC_DELIM_BEACON: | ||
|  |         { | ||
|  |             msg->rf_mcs = (uint8_t)spg_phr->vf.rf_bcn.mcs; | ||
|  |             msg->rf_pb_sz_idx = (uint8_t)spg_phr->vf.rf_bcn.pb_sz_idx; | ||
|  |             msg->src_tei = spg_phr->vf.rf_bcn.src_tei; | ||
|  |             break; | ||
|  |         } | ||
|  |         case FC_DELIM_SOF: | ||
|  |         { | ||
|  |             msg->dst_tei = spg_phr->vf.rf_sof.dst_tei; | ||
|  |             msg->src_tei = spg_phr->vf.rf_sof.src_tei; | ||
|  |             msg->rf_pb_sz_idx = (uint8_t)spg_phr->vf.rf_sof.pb_sz_idx; | ||
|  |             msg->rf_mcs = (uint8_t)spg_phr->vf.rf_sof.mcs; | ||
|  |             break; | ||
|  |         } | ||
|  |         case FC_DELIM_SACK: | ||
|  |         { | ||
|  |             msg->result_in_sack = spg_phr->vf.rf_sack.rx_result; | ||
|  |             msg->dst_tei = spg_phr->vf.rf_sack.dtei; | ||
|  |             break; | ||
|  |         } | ||
|  |         default: | ||
|  |             break; | ||
|  |         } | ||
|  |         break; | ||
|  |     } | ||
|  | #endif
 | ||
|  |     default: | ||
|  |         (void)proto; | ||
|  |         (void)phr; | ||
|  |         (void)msg; | ||
|  |         break; | ||
|  |     } | ||
|  | 
 | ||
|  |     return; | ||
|  | } | ||
|  | 
 |