#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