Files
kunlun/dtest/mac_tx_test/hw/tx_entry.c
2024-09-28 14:24:04 +08:00

508 lines
16 KiB
C
Executable File

#include "chip_reg_base.h"
#include "hw_reg_api.h"
#include "hw_tonemask.h"
#include "tx_mpdu_end.h"
#include "tx_pb_start.h"
#include "plc_utils.h"
#include "ada_reg.h"
#include "hw_phy_init.h"
#include "phy_reg.h"
#include "mpdu_frame.h"
#include "ahb.h"
#include "iot_irq.h"
#include "os_mem.h"
#include "apb_glb_reg.h"
#include "command_list.h"
#include "dbg_io.h"
#include "iot_config.h"
#include "iot_io.h"
#include "iot_pkt_api.h"
#include "mac_tx_hw.h"
#include "mac_rx_hw.h"
#include "os_utils.h"
#include "tx_entry.h"
#include "hal_rx.h"
#include "iot_crc_api.h"
#include "hw_tx.h"
#include "mac_sys_reg.h"
#include "mac_reset.h"
#include "mac_key_hw.h"
#include "phy_chn.h"
/* if mem fun is not ready, use global heap */
volatile tx_mpdu_start *mpdu_start;
tx_mpdu_end *mpdu_end;
tx_pb_start *pb_start,*pb_second,*pb_third,*pb_last;
#if IOT_DTEST_ONLY_SUPPORT == 1
tx_mpdu_start mpdu_start_tmp;
tx_mpdu_end mpdu_end_tmp;
tx_pb_start pb_start_tmp,pb_second_tmp,pb_third_tmp,pb_last_tmp;
uint8_t pb_buf[MAC_PB_SIZE_MAX] = { 0 };
uint8_t pb_buf_second[MAC_PB_SIZE_MAX] = { 0 };
uint8_t pb_buf_third[MAC_PB_SIZE_MAX] = { 0 };
uint8_t pb_buf_last[MAC_PB_SIZE_MAX] = { 0 };
uint16_t band_cnt[MAC_BB_MAX_RATE][MAX_HW_BAND] = {0};
#else
uint8_t *pb_buf;
uint8_t *pb_buf_second;
uint8_t *pb_buf_third;
uint8_t *pb_buf_last;
uint16_t *band_cnt[MAC_BB_MAX_RATE];
#endif
/* mac tx beacon test - with 7000 GP protocol */
#if EDA_SIMU_SUPPORT == 1
uint32_t bcn_period_ms = 6;
#elif MAC_TX_TEST_ID == MAC_TX_BURN
uint32_t bcn_period_ms = 12;
#else
uint32_t bcn_period_ms = 20 << 1;
#endif
uint32_t print_tx_period_ms=4000; /*receive 25*4 packets in 4s*/
uint8_t delay_time = 0;
volatile bool_t mac_beacon_alert_flag = false;
volatile bool_t mac_tx_complete_flag = false;
/* tx glb cfg */
iot_tx_cfg_info_t glb_cfg = {
PHY_PHASE_OVR_A, \
PLC_PROTO_TYPE_SG, \
FC_DELIM_SOF , \
MAC_TX_TEST_ID, \
MAC_TMI_ID, \
MAC_PB_NUM_ID, \
IOT_PLC_PHY_BAND_DFT, \
/* tmap gi */
0,
1, \
2, \
1,
HW_DESC_PPDU_MODE_AVONLY_1FCSYM, \
/* mpdu number */
1, \
/* tmap turbo rate */
0, \
/* modulation */
0, \
/* nid */
PHY_TXRX_NID_VAL, \
IOT_RATE_MODE_TX, \
false};
void mac_encry_mode_init_test(uint8_t vlan_num, \
uint8_t key_tbl_num, uint8_t key_num)
{
uint8_t vlan_idx, key_tbl_idx, key_idx;
mac_avln_t *avln_ptr;
mac_key_table_t *key_tbl;
mac_key_entry *key;
mac_avln_ctxt_init(vlan_num);
for(vlan_idx = 0; vlan_idx < vlan_num; vlan_idx++)
{
mac_avln_init(vlan_idx, key_tbl_num);
avln_ptr = (g_mac_avln_ctxt.mac_avln_array + vlan_idx);
for(key_tbl_idx = 0; key_tbl_idx < key_tbl_num; key_tbl_idx++)
{
key_tbl = (avln_ptr->key_tbl + key_tbl_idx);
mac_key_tbl_init(key_tbl, key_num);
}
}
for(vlan_idx = 0; vlan_idx < vlan_num; vlan_idx++)
{
avln_ptr = (g_mac_avln_ctxt.mac_avln_array + vlan_idx);
for(key_tbl_idx = 0; key_tbl_idx < key_tbl_num; key_tbl_idx++)
{
key_tbl = (avln_ptr->key_tbl + key_tbl_idx);
for(key_idx = 0; key_idx < key_num; key_idx++)
{
key = (key_tbl->key_array + key_idx);
mac_key_set(key, 0, vlan_idx, key_tbl_idx, key_idx);
}
}
}
key = g_mac_avln_ctxt.mac_avln_array->key_tbl->key_array;
mac_key_set(key, 0x12345678, 0x23456789, 0x3456789a, 0x456789ab);
for(vlan_idx = 0; vlan_idx < vlan_num; vlan_idx++)
{
avln_ptr = (g_mac_avln_ctxt.mac_avln_array + vlan_idx);
mac_key_hw_set_avln_key_tlb(vlan_idx, avln_ptr);
}
for(vlan_idx = 0; vlan_idx < vlan_num; vlan_idx++)
{
mac_key_hw_set_avln_nid(vlan_idx, 0x1);
}
}
void tx_send_packet_interval(uint32_t interval)
{
uint32_t start_time = 0, end_time = 0;
uint64_t time_span = 0;
start_time = RGF_MAC_READ_REG(CFG_RD_NTB_ADDR);
/*send packet */
mac_tx_mpdu_test(NULL, mpdu_start);
dt_mac_tx_hwq0_re_trig();
do{
end_time = RGF_MAC_READ_REG(CFG_RD_NTB_ADDR);
time_span = end_time - start_time;
if (time_span < 0) { // wrap around
time_span = (0x100000000LL) - start_time + end_time;
}
}while((uint64_t)time_span < interval * TICKS_MS);
}
uint32_t mac_tx_init(uint32_t band_id) {
#if IOT_DTEST_ONLY_SUPPORT == 1
/* reset mac */
mac_reset(MAC_RST_REASON_COLD);
/* reset phy */
phy_reset(PHY_RST_REASON_COLD);
/* reset mac */
mac_reset(MAC_RST_REASON_COLD);
/* init */
phy_init(glb_cfg.m_type, band_id, phy_band_to_tonemask_id_get(band_id),
true);
/* dtest mac interrupt cfg */
if(glb_cfg.t_type >= MAC_TX_INTR_BCN_ALT)
mac_interrupt_init();
/* init glb parameters */
mpdu_start = &mpdu_start_tmp;
mpdu_end = &mpdu_end_tmp;
pb_start = &pb_start_tmp;
pb_second = &pb_second_tmp;
pb_third = &pb_third_tmp;
pb_last = &pb_last_tmp;
#else
static volatile uint8_t first_tx_init_flag = 0;
if(!first_tx_init_flag)
{
uint32_t tmp = MAC_BB_MAX_RATE;
iot_pkt_t *pkt_buf = NULL;
while (tmp--) {
IOT_PKT_GET(pkt_buf, MAX_HW_BAND, 0, IOT_FTM_MID);
if (!pkt_buf) {
iot_printf("iot_pkt_get band_cnt fail\n");
return ERR_FAIL;
}
band_cnt[tmp] = (uint16_t *)iot_pkt_put(pkt_buf, MAX_HW_BAND);
}
IOT_PKT_GET(pkt_buf, sizeof(tx_mpdu_start), 0, IOT_FTM_MID);
if (!pkt_buf) {
iot_printf("iot_pkt_get mpdu_start fail\n");
return ERR_FAIL;
}
mpdu_start = (tx_mpdu_start *)iot_pkt_put(pkt_buf, sizeof(tx_mpdu_start));
IOT_PKT_GET(pkt_buf, sizeof(tx_mpdu_end), 0, IOT_FTM_MID);
if (!pkt_buf) {
iot_printf("iot_pkt_get mpdu_end fail\n");
return ERR_FAIL;
}
mpdu_end = (tx_mpdu_end *)iot_pkt_put(pkt_buf, sizeof(tx_mpdu_end));
IOT_PKT_GET(pkt_buf, sizeof(tx_pb_start), 0, IOT_FTM_MID);
if (!pkt_buf) {
iot_printf("iot_pkt_get pb_start fail\n");
return ERR_FAIL;
}
pb_start = (tx_pb_start *)iot_pkt_put(pkt_buf, sizeof(tx_pb_start));
IOT_PKT_GET(pkt_buf, MAC_PB_SIZE_MAX, 0, IOT_FTM_MID);
if (!pkt_buf) {
iot_printf("iot_pkt_get pb_buf fail\n");
return ERR_FAIL;
}
pb_buf = (uint8_t *)iot_pkt_put(pkt_buf, MAC_PB_SIZE_MAX);
#if MAC_PB_NUM_ID >= 2
IOT_PKT_GET(pkt_buf, sizeof(tx_pb_start), 0, IOT_FTM_MID);
if (!pkt_buf) {
iot_printf("iot_pkt_get pb_second fail\n");
return ERR_FAIL;
}
pb_second = (tx_pb_start *)iot_pkt_put(pkt_buf, sizeof(tx_pb_start));
IOT_PKT_GET(pkt_buf, MAC_PB_SIZE_MAX, 0, IOT_FTM_MID);
if (!pkt_buf) {
iot_printf("iot_pkt_get pb_buf_second fail\n");
return ERR_FAIL;
}
pb_buf_second = (uint8_t *)iot_pkt_put(pkt_buf, MAC_PB_SIZE_MAX);
#endif
#if MAC_PB_NUM_ID >= 3
IOT_PKT_GET(pkt_buf, sizeof(tx_pb_start), 0, IOT_FTM_MID);
if (!pkt_buf) {
iot_printf("iot_pkt_get pb_third fail\n");
return ERR_FAIL;
}
pb_third = (tx_pb_start *)iot_pkt_put(pkt_buf, sizeof(tx_pb_start));
IOT_PKT_GET(pkt_buf, MAC_PB_SIZE_MAX, 0, IOT_FTM_MID);
if (!pkt_buf) {
iot_printf("iot_pkt_get pb_buf_third fail\n");
return ERR_FAIL;
}
pb_buf_third = (uint8_t *)iot_pkt_put(pkt_buf, MAC_PB_SIZE_MAX);
#endif
#if MAC_PB_NUM_ID == 4
IOT_PKT_GET(pkt_buf, sizeof(tx_pb_start), 0, IOT_FTM_MID);
if (!pkt_buf) {
iot_printf("iot_pkt_get pb_last fail\n");
return ERR_FAIL;
}
pb_last = (tx_pb_start *)iot_pkt_put(pkt_buf, sizeof(tx_pb_start));
IOT_PKT_GET(pkt_buf, MAC_PB_SIZE_MAX, 0, IOT_FTM_MID);
if (!pkt_buf) {
iot_printf("iot_pkt_get pb_buf_last fail\n");
return ERR_FAIL;
}
pb_buf_last = (uint8_t *)iot_pkt_put(pkt_buf, MAC_PB_SIZE_MAX);
#endif
first_tx_init_flag = 1;
}
#endif
mac_tx_path_init();
return 0;
}
/* support mode : ftm, module, dtest scan */
void tx_common_init(uint32_t band_idx)
{
/* basic data struct init for bit ops */
iot_bitops_init();
#if SUPPORT_SMART_GRID
glb_cfg.m_type = PLC_PROTO_TYPE_SG;
#elif SUPPORT_SOUTHERN_POWER_GRID
glb_cfg.m_type = PLC_PROTO_TYPE_SPG;
#endif
mac_tx_init(band_idx);
/* construct the desc */
if((glb_cfg.p_type == DT_AV_SOF) \
||(glb_cfg.p_type == FC_DELIM_SOF) \
||(glb_cfg.p_type == FC_DELIM_SOUND))
{
uint32_t proto = phy_proto_type_get();
uint32_t pb_num = MAC_PB_NUM_ID;
switch (pb_num) {
case 4:
mac_tx_mpdu_fill_pb_start(pb_last, MPDU_PB_NULL, &pb_buf_last[0], 0, 1, 1, proto);
mac_tx_mpdu_fill_pb_start(pb_third, pb_last, &pb_buf_third[0], 0, 1, 1, proto);
mac_tx_mpdu_fill_pb_start(pb_second, pb_third, &pb_buf_second[0], 0, 1, 1, proto);
mac_tx_mpdu_fill_pb_start(pb_start, pb_second, &pb_buf[0], 0, 1, 1, proto);
break;
case 3:
mac_tx_mpdu_fill_pb_start(pb_third, MPDU_PB_NULL, &pb_buf_third[0], 0, 1, 1, proto);
mac_tx_mpdu_fill_pb_start(pb_second, pb_third, &pb_buf_second[0], 0, 1, 1, proto);
mac_tx_mpdu_fill_pb_start(pb_start, pb_second, &pb_buf[0], 0, 1, 1, proto);
break;
case 2:
mac_tx_mpdu_fill_pb_start(pb_second, MPDU_PB_NULL, &pb_buf_second[0], 0, 1, 1, proto);
mac_tx_mpdu_fill_pb_start(pb_start, pb_second, &pb_buf[0], 0, 1, 1, proto);
break;
case 1:
mac_tx_mpdu_fill_pb_start(pb_start, MPDU_PB_NULL, &pb_buf[0], 0, 1, 1, proto);
break;
default:
IOT_ASSERT(0);
break;
}
}
mpdu_start->next = MPDU_PB_NULL;
mpdu_start->pb_list = mpdu_pb_list_get_from_pb_start(pb_start);
mpdu_start->tx_status = mpdu_tx_status_get_from_mpdu_end(mpdu_end);
}
/* fresh all the cfg */
void mac_glb_map(uint32_t mac_type, uint32_t pkt_type, uint32_t test_type)
{
glb_cfg.m_type = mac_type;
glb_cfg.p_type = pkt_type;
glb_cfg.t_type = test_type;
}
/* cli api */
void mac_tx_handle(PHY_PHASE_OVR_ID phase, \
uint32_t mac_type, \
uint32_t pkt_type, \
uint32_t num, \
bool_t wait_rx)
{
volatile uint32_t tx_done = 0;
uint32_t enq_time = 0, cur_time = 0;
uint32_t start_time = 0, end_time = 0;
int64_t time_span = 0, time_span_print = 0;
volatile bool_t period_done = false;
iot_phy_sts_info_t total_sts = {0};
uint32_t rate_idx = 0;
uint32_t band_idx = 0;
/* phase select */
glb_cfg.phase = phase;
/* force rx phase */
phy_rx_phase_force_set(true, glb_cfg.phase);
/* update mac, pkt and test type */
mac_glb_map(mac_type,pkt_type,pkt_type);
start_time = RGF_MAC_READ_REG(CFG_RD_NTB_ADDR);
do {
enq_time = RGF_MAC_READ_REG(CFG_RD_NTB_ADDR);
/* step1: tx packet */
mac_tx_mpdu_test(NULL, mpdu_start);
dt_mac_tx_hwq0_re_trig();
do { // wait for tx done and hwq disable
cur_time = RGF_MAC_READ_REG(CFG_RD_NTB_ADDR);
time_span = cur_time - enq_time;
if (time_span < 0) { // wrap around
time_span = (0x100000000LL) - enq_time + cur_time;
}
tx_done = phy_get_tx_done_from_mpdu(mpdu_start);
period_done = ((uint64_t)time_span < bcn_period_ms * TICKS_MS)?0:1;
if(!tx_done && period_done){
iot_printf("[Dtest][tx][timeout] tx timeout!\r\n");
break;
}
} while (!tx_done || !period_done);
/* step2: wait to receive packt */
if(wait_rx)
{
while (is_rx_ring0_empty())
{
end_time = RGF_MAC_READ_REG(CFG_RD_NTB_ADDR);
time_span = end_time - start_time;
if (time_span < 0) { // wrap around
time_span = (0x100000000LL) - start_time + end_time;
}
if((uint64_t)time_span > 5000*TICKS_MS){
iot_printf("[Dtest][tx][timeout] wait rx timeout!\r\n");
break;
}
}
/* parse pkt */
#if SUPPORT_SMART_GRID
rx_buf_hdr_t *pb_buf_ptr = NULL;
uint8_t *rx_buf_tmp = pop_rx_buf_from_ring(0);
if(rx_buf_tmp) /* check valid */
{
/* TODO: please refer low mac, use API to get nid from FC */
pb_buf_ptr = (rx_buf_hdr_t *)rx_buf_tmp;
if((pb_buf_ptr->att.rx_mpdu_done == 1) \
&& (pb_buf_ptr->att.is_fcserr == 0) \
&& (pb_buf_ptr->pb_ed.rx_pb_crc_err == 0) \
&& (pb_buf_ptr->mpdu_st.fc.sg_fc.nid == PHY_TXRX_NID_VAL)) /* check nid */
{
iot_printf("[rx] pb crc:%d, nid:%x\n",pb_buf_ptr->pb_ed.rx_pb_crc_err, \
pb_buf_ptr->mpdu_st.fc.sg_fc.nid);
/* check snr */
iot_printf("loopback nid:%x gain:%d, rmi:%d, dc:%d, snr:%d, ppm:%d\n", \
pb_buf_ptr->mpdu_st.fc.sg_fc.nid, \
(int8_t)(*(rx_buf_tmp+64)), \
(int8_t)(*(rx_buf_tmp+65)), \
(int8_t)(*(rx_buf_tmp+66)), \
(int8_t)(*(rx_buf_tmp+69)), \
(int16_t)(*(rx_buf_tmp+67) | (*(rx_buf_tmp+68) << 8)));
iot_printf("loopback local rx phase:%x dc:%d, ppm:%d, snr:%d\n", \
pb_buf_ptr->mpdu_st.rx_phase, \
(int8_t)(pb_buf_ptr->mpdu_st.phy.est_dc), \
(int8_t)(pb_buf_ptr->mpdu_st.phy.est_ppm), \
(int8_t)(pb_buf_ptr->mpdu_st.phy.avg_snr));
}
}
else
{
iot_printf("don't receive any valid packet!\n");
}
#endif
}
/* step3: print cnt */
end_time = RGF_MAC_READ_REG(CFG_RD_NTB_ADDR);
time_span_print = end_time - start_time;
if (time_span_print < 0) { // wrap around
time_span_print = (0x100000000LL) - start_time + end_time;
}
if((uint64_t)time_span_print > print_tx_period_ms*TICKS_MS){
phy_sts_get(&total_sts);
iot_printf("mac tx ok:%d/4s, fc_ok:%d/4s, fc_err:%d/4s,", \
total_sts.mac_tx_ok_cnt,total_sts.fc_crc_ok_cnt,total_sts.fc_crc_fail_cnt);
iot_printf("pld_ok:%d/4s, pld fail:%d/4s, sync ok:%d/4s\r\n", \
total_sts.pld_crc_ok_cnt,total_sts.pld_crc_fail_cnt,total_sts.sync_ok_cnt);
start_time = end_time;
/* band info */
for(rate_idx=0; rate_idx<MAC_BB_MAX_RATE; rate_idx++)
{
for(band_idx=0; band_idx<MAX_HW_BAND; band_idx++)
{
if(band_cnt[rate_idx][band_idx] != 0){
iot_printf("[RATE-%d][BAND-%d]:%d\r\n", \
rate_idx, band_idx, band_cnt[rate_idx][band_idx]);
band_cnt[rate_idx][band_idx] = 0;
}
}
}
}
/* check tx num if zero */
if(--num == 0){
iot_printf("[Dtest][tx][done] Successfully!\r\n");
return;
}
} while (true);
}
void phy_tx_gain_rms_set(uint8_t para_int)
{
uint8_t para_frac = 0;
/* rate0 band0/1/2 */
phy_tx_rms_set(0, HW_FULL_BAND, para_int, para_frac);
phy_tx_rms_set(0, HW_LOW_BAND, para_int, para_frac);
phy_tx_rms_set(0, HW_HIGH_BAND, para_int, para_frac);
/* rate1 band0/1/2 */
phy_tx_rms_set(1, HW_FULL_BAND, para_int, para_frac);
phy_tx_rms_set(1, HW_LOW_BAND, para_int, para_frac);
phy_tx_rms_set(1, HW_HIGH_BAND, para_int, para_frac);
if(phy_proto_type_get() == PLC_PROTO_TYPE_SG)
{
/* short band rms for mix mode */
phy_tx_rms_set(2, 0, para_int, para_frac);
}
}
void phy_tmap_common_init()
{
/* not support for kunlun1 */
}
void phy_tmap_self_tmi_set(uint8_t tmi)
{
(void)tmi;
/* not support for kunlun1 */
}
void phy_tmap_init()
{
/* not support for kunlun1 */
}