#include "chip_reg_base.h" #include "hw_reg_api.h" #include "hw_tonemask.h" #include "tx_mpdu_start.h" #include "tx_mpdu_end.h" #include "tx_pb_start.h" #include "plc_utils.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 "ada_reg.h" #include "hw_phy_init.h" #include "phy_ana.h" #include "phy_reg.h" #include "phy_bb.h" #include "mpdu_frame.h" #include "ahb.h" #include "iot_irq.h" //#include "iot_mem.h" #include "mac_tx_main.h" #include "intc_reg.h" #include "apb_glb_reg.h" #include "command_list.h" #include "dbg_io.h" #include "iot_config.h" #include "iot_io.h" #include "mac_hwq_mgr.h" #include "iot_pkt_api.h" #include "mac_desc_engine.h" #include "mac_tx_hw.h" #include "mac_rx_hw.h" #include "os_utils.h" #include "phy_rxtd_reg.h" #include "mac_crc.h" #include "mpdu_header.h" #include "mac_avln.h" #include "mac_key_hw.h" #include "mac_key.h" /* if mem fun is not ready, use global heap */ tx_mpdu_start mpdu_start; tx_mpdu_end mpdu_end; tx_pb_start pb_start,pb_second,pb_third,pb_last; 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 }; /* mac tx beacon test - with 7000 GP protocol */ #if EDA_SIMU_SUPPORT == 1 uint32_t bcn_period_ms = 6; #else uint32_t bcn_period_ms = 20 << 1; #endif iot_mac_intr_info_t mac_info; volatile bool_t mac_beacon_alert_flag = false; volatile bool_t mac_tx_complete_flag = false; /* tx cfg */ iot_tx_cfg_info_t glb_cfg = {PLC_PROTO_TYPE_SG,FC_DELIM_SOF,MAC_TX_TEST_ID, \ MAC_TMI_ID,MAC_PB_NUM_ID,IOT_PLC_PHY_BAND_DFT, \ IOT_RATE_MODE_TX}; uint32_t print_tx_period_ms=4000; //mac_msdu_t *g_msdu[MAX_MAC_TXQ_NUM] = {NULL}; uint8_t delay_time = 0; uint32_t enq_time = 0; uint8_t send_tput_flag =0; uint8_t mac_ping_enable = 0; 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 ftm_msdu_init() { #if 0 uint8_t i; for(i=0; imsdu_len != msdu_len) { iot_printf("warning: msdu len not match,fix from %d to %d\r\n", \ sg_mac->msdu_len, msdu_len); sg_mac->msdu_len = msdu_len; } break; } #endif #if SUPPORT_SOUTHERN_POWER_GRID case PLC_PROTO_TYPE_SPG: { if (iot_pkt_data_len(buf) < (data_len + SPG_MAC_MSDU_CRC_LEN)) { return false; } spg_mac_header_t *spg_mac = (spg_mac_header_t *)iot_pkt_data(buf); msdu_len = data_len - sizeof(*spg_mac); if (spg_mac->msdu_len != msdu_len) { iot_printf("warning: msdu len not match,fix from %d to %d\r\n", \ spg_mac->msdu_len, msdu_len); spg_mac->msdu_len = msdu_len; } break; } #endif #if SUPPORT_GREEN_PHY case PLC_PROTO_TYPE_GP: { if (iot_pkt_data_len(buf) < (data_len + GP_MAC_MSDU_CRC_LEN)) { return false; } gp_mac_header_t *gp_mac = (gp_mac_header_t *)iot_pkt_data(buf); msdu_len = data_len - sizeof(*gp_mac); if (gp_mac->mfl != msdu_len) { iot_printf("warning: msdu len not match,fix from %d to %d\r\n", \ gp_mac->mfl, msdu_len); gp_mac->mfl = msdu_len; } break; } #endif default: return false; } return true; } iot_pkt_t *ftm_fill_mac_data(uint8_t delimier_type,\ uint16_t buf_len, uint8_t *pkt, uint16_t pkt_len) { iot_pkt_t *buf; IOT_PKT_GET(buf, buf_len, HEAD_SIEZ_64, PLC_MAC_TX_MID); IOT_ASSERT(buf && ((pkt_len + HEAD_SIEZ_64) <= buf_len)); uint8_t *tmp = iot_pkt_put(buf, buf_len-HEAD_SIEZ_64); switch (delimier_type){ case FC_DELIM_BEACON: { IOT_ASSERT(pkt); os_mem_cpy(tmp, pkt, pkt_len); os_mem_set((tmp+pkt_len), 0, buf_len-pkt_len-HEAD_SIEZ_64); break; } case FC_DELIM_SOF: { IOT_ASSERT(pkt); os_mem_cpy(tmp, pkt, pkt_len); os_mem_set((tmp+pkt_len), 0, buf_len-pkt_len-HEAD_SIEZ_64); break; } case FC_DELIM_NNCCO: (void)pkt; (void)pkt_len; os_mem_set(tmp, 0x55, buf_len); break; case FC_DELIM_SOUND: IOT_ASSERT(pkt); os_mem_cpy(tmp, pkt, pkt_len); os_mem_set((tmp+pkt_len), 0, buf_len-pkt_len-HEAD_SIEZ_64); break; default: iot_printf("other frame\n"); break; } return buf; } void mpdu_tx_beacon_test(uint32_t proto, mac_queue_ctxt_t *tx_ctxt, uint8_t qid,\ uint8_t bcast, uint8_t delimiter_type, uint32_t nid,\ uint32_t dtei, uint32_t stei, uint8_t tmi, uint8_t ext_tmi,\ uint8_t lid, uint8_t need_encry, tx_mpdu_end *mpdu_end,\ uint16_t pkt_len, uint8_t *pkt) { tx_mpdu_start *mpdu; tx_pb_start *pb; uint32_t pb_sz; uint32_t pb_mod; uint32_t rate_mode = 0; uint8_t pb_hdr_resv_crc_len; uint32_t network = (PLC_PROTO_TYPE_SPG == proto)? 1:0; uint8_t ppdu_mode = (PLC_PROTO_TYPE_GP == proto)? \ HW_DESC_PPDU_MODE_AVONLY_1FCSYM:0; mac_desc_get(&g_mac_desc_eng,PLC_TX_MPDU_START_POOL, (void**)&mpdu); mac_desc_get(&g_mac_desc_eng,PLC_TX_PB_START_POOL, (void**)&pb); IOT_ASSERT(mpdu && pb); iot_pkt_t *test_data = \ ftm_fill_mac_data(delimiter_type, MIN_DATA_SIZE, pkt, pkt_len); phy_get_pb_size(proto, tmi, ext_tmi, &pb_sz); phy_get_pb_mod(proto, tmi, ext_tmi, &pb_mod); mac_crc_set_bcn_swcrc(proto,iot_pkt_data(test_data), pb_sz); mac_tx_mpdu_fill_pb_start(pb, NULL, iot_pkt_data(test_data), 0, 1, 1, proto); mac_crc_set_pb_swcrc(proto, pb, FC_DELIM_BEACON, pb_sz); /* get pb header + crc length */ pb_hdr_resv_crc_len = mac_get_pb_hdr_resv_crc_len(FC_DELIM_BEACON, proto); mac_tx_mpdu_fill_macinfo(mpdu, qid, 1, need_encry, 0, phy_get_sym_per_pb(proto, 0, tmi, ext_tmi, phy_get_pss_id(proto, tmi, ext_tmi)), phy_get_fl_per_pb(proto, 0, tmi, ext_tmi), 0, pb_hdr_resv_crc_len, 0, 1, 1, mpdu_end, pb, NULL, 0, (uint32_t)(iot_pkt_data(test_data) - (uint8_t*)test_data), 0, 0, 0, 0, 0); mac_tx_mpdu_fill_phyinfo(mpdu, HW_DESC_TX_PORT_PLC, \ 128, HW_DESC_TX_PHASE_ALL, 0, ppdu_mode, 0, pb_mod, rate_mode); mac_tx_mpdu_fill_fcinfo(mpdu, proto, \ 1, HW_DESC_TX_PHASE_ALL, delimiter_type, network, nid, 0, \ tmi, ext_tmi, dtei, stei, lid, bcast, 0, 0, 0, 0, NULL); mac_crc_set_fc_swcrc(proto, mpdu); { /* get tx fc message */ tx_fc_msg_t msg = {0}; mac_get_tx_msg_from_fc(proto, delimiter_type, &mpdu->fc, &msg); iot_printf("proto = %d,""hwq = %d,"\ "beacon tx:tmi = %d,"\ "pb_num = %d\n", \ proto, qid, msg.tmi, 1); } /* send */ mac_tx_hw_mpdu(tx_ctxt, qid, mpdu); } void mpdu_tx_sof_test(uint32_t proto, mac_queue_ctxt_t *tx_ctxt, uint8_t qid,\ uint8_t bcast, uint8_t delimiter_type,uint32_t nid, uint32_t dtei,\ uint32_t stei,uint8_t tmi, uint8_t ext_tmi, uint8_t lid,\ uint8_t pb_num,uint8_t need_ack, uint8_t need_encry,\ uint8_t need_decrypt, uint32_t avln_idx_in_desc,\ uint32_t key_table_idx_in_desc, uint32_t key_idx_in_desc,\ uint8_t hw_retry_cnt, tx_mpdu_end *mpdu_end,\ uint16_t pkt_len, uint8_t *pkt) { tx_mpdu_start *mpdu; tx_pb_start *pb; uint32_t pb_sz; uint32_t bitmap; uint32_t pb_mod; uint32_t rate_mode = 0; uint32_t network = (PLC_PROTO_TYPE_SPG == proto)? 1:0; uint8_t ppdu_mode = (PLC_PROTO_TYPE_GP == proto)? \ HW_DESC_PPDU_MODE_AVONLY_1FCSYM:0; iot_pkt_t *test_data = \ ftm_fill_mac_data(delimiter_type, MAX_DATA_SIZE, pkt, pkt_len); phy_get_pb_size(proto, tmi,ext_tmi,&pb_sz); phy_get_pb_mod(proto, tmi, ext_tmi, &pb_mod); bitmap = 0xffffffff >> (32 - pb_num); mac_fill_msdu_frame(proto, test_data, pkt_len); mac_crc_set_msdu_swcrc(proto, test_data); mac_desc_get(&g_mac_desc_eng,PLC_TX_MPDU_START_POOL, (void**)&mpdu); IOT_ASSERT(mpdu); mac_tx_mpdu_form_pb_list(&pb, test_data, pb_num, bitmap, pb_sz, proto); /* get header + crc length */ uint8_t pb_hdr_resv_crc_len = mac_get_pb_hdr_resv_crc_len(delimiter_type, \ proto); mac_tx_mpdu_fill_macinfo(mpdu, qid, pb_num, need_encry, need_ack,\ phy_get_sym_per_pb(proto, 0, tmi, ext_tmi, phy_get_pss_id(proto, tmi, ext_tmi)),\ phy_get_fl_per_pb(proto, 0, tmi, ext_tmi), 0,\ pb_hdr_resv_crc_len, hw_retry_cnt, 1, 1, mpdu_end, pb, NULL, 0, \ (uint32_t)(iot_pkt_data(test_data) - (uint8_t*)test_data), 0, \ avln_idx_in_desc, key_table_idx_in_desc, key_idx_in_desc, 0); mac_tx_mpdu_fill_phyinfo(mpdu, HW_DESC_TX_PORT_PLC, \ 128, HW_DESC_TX_PHASE_ALL, 0, ppdu_mode, 0, pb_mod, rate_mode); mac_tx_mpdu_fill_fcinfo(mpdu, proto, \ pb_num, HW_DESC_TX_PHASE_ALL, delimiter_type, network, nid, 0,\ tmi, ext_tmi, dtei, stei, lid, bcast, 0,need_encry,\ key_table_idx_in_desc ,key_idx_in_desc, NULL); if(!need_decrypt) { switch (proto) { case PLC_PROTO_TYPE_SG: { frame_control_t *fc = \ (frame_control_t *)&mpdu->fc.sg_fc; fc->vf.sof.decrypt_mode = 0; break; } case PLC_PROTO_TYPE_SPG: { spg_frame_control_t *fc = \ (spg_frame_control_t *)&mpdu->fc.spg_fc; fc->vf.sof.decrypt_mode = 0; break; } default: IOT_ASSERT(0); } } mac_crc_set_fc_swcrc(proto, mpdu); if(!send_tput_flag) { tx_fc_msg_t msg = {0}; mac_get_tx_msg_from_fc(proto, delimiter_type, &mpdu->fc, &msg); { iot_printf("proto = %d," \ "hwq = %d," \ "sof tx:tmi = %d," \ "sof tx:ext_tmi = %d," \ "pb_num = %d\n", \ proto, qid, msg.tmi, msg.ext_tmi, pb_num); } } /* send */ mac_tx_hw_mpdu(tx_ctxt, qid, mpdu); } void gp_mpdu_tx_rtscts_test(uint32_t proto, mac_queue_ctxt_t *tx_ctxt,\ uint8_t qid, uint8_t delimiter_type,uint32_t nid,\ uint32_t dtei, uint32_t stei,uint8_t tmi, uint8_t lid,\ uint8_t pb_num, uint8_t need_encry,\ uint8_t hw_retry_cnt, tx_mpdu_end *mpdu_end,\ uint16_t pkt_len, uint8_t *pkt) { tx_mpdu_start *mpdu; //tx_pb_start *pb; //uint32_t pb_sz; //uint32_t bitmap; uint32_t pb_mod; uint32_t rate_mode = 0; uint32_t network = (PLC_PROTO_TYPE_SPG == proto)? 1:0; uint8_t ppdu_mode = (PLC_PROTO_TYPE_GP == proto)? \ HW_DESC_PPDU_MODE_AVONLY_1FCSYM:0; iot_pkt_t *test_data = \ ftm_fill_mac_data(delimiter_type, MID_DATA_SIZE, pkt, pkt_len); //phy_get_pb_size(proto, tmi,0,&pb_sz); phy_get_pb_mod(proto, tmi, 0, &pb_mod); //bitmap = 0xffffffff >> (32 - pb_num); mac_fill_msdu_frame(proto, test_data, pkt_len); mac_crc_set_msdu_swcrc(proto, test_data); mac_desc_get(&g_mac_desc_eng,PLC_TX_MPDU_START_POOL, (void**)&mpdu); IOT_ASSERT(mpdu); //mac_tx_mpdu_form_pb_list(&pb, test_data, pb_num, bitmap, pb_sz, proto); /* get header + crc length */ uint8_t pb_hdr_resv_crc_len = mac_get_pb_hdr_resv_crc_len(delimiter_type, \ proto); mac_tx_mpdu_fill_macinfo(mpdu, qid, pb_num, need_encry, 0,\ phy_get_sym_per_pb(proto, 0, tmi, 0, phy_get_pss_id(proto, tmi, ext_tmi)), \ phy_get_fl_per_pb(proto, 0, tmi, 0), 0,\ pb_hdr_resv_crc_len, hw_retry_cnt, 1, 1, mpdu_end, NULL, NULL, 0, \ (uint32_t)(iot_pkt_data(test_data) - (uint8_t*)test_data), 0, 0, 0, 0, 0, 0); /* For RTS-CTS only */ mpdu->pb_num = 0; mac_tx_mpdu_fill_phyinfo(mpdu, HW_DESC_TX_PORT_PLC, \ 128, HW_DESC_TX_PHASE_ALL, 0, ppdu_mode, 0, pb_mod, rate_mode); mac_tx_mpdu_fill_fcinfo(mpdu, proto, \ pb_num, HW_DESC_TX_PHASE_ALL, delimiter_type, network, nid, 0, \ tmi, 0, dtei, stei, lid, 0, 0, 0, 0, 0, NULL); mac_crc_set_fc_swcrc(proto, mpdu); if(!send_tput_flag) { tx_fc_msg_t msg = {0}; mac_get_tx_msg_from_fc(proto, delimiter_type, &mpdu->fc, &msg); iot_printf("GP:proto = %d," \ "hwq = %d," \ "sof tx:tmi = %d," \ "pb_num = %d\n", \ proto, qid, msg.tmi, pb_num); } /* send */ mac_tx_hw_mpdu(tx_ctxt, qid, mpdu); } void mpdu_tx_nncco_test(uint32_t proto, mac_queue_ctxt_t *tx_ctxt, uint8_t qid,\ uint8_t bcast, uint8_t delimiter_type,uint32_t nid,\ uint32_t dtei, uint32_t stei,uint8_t lid,uint8_t need_encry,\ tx_mpdu_end *mpdu_end) { tx_mpdu_start *mpdu; uint32_t network = (PLC_PROTO_TYPE_SPG == proto)? 1:0; mac_desc_get(&g_mac_desc_eng,PLC_TX_MPDU_START_POOL, (void**)&mpdu); IOT_ASSERT(mpdu); mac_tx_mpdu_fill_macinfo(mpdu, qid, 0, 0,0,\ 0, 0, 0, 0, 0, 1, 1, mpdu_end, NULL, NULL, 0, \ 0, 0, 0, 0, 0); mac_tx_mpdu_fill_phyinfo(mpdu, HW_DESC_TX_PORT_PLC, \ 128, HW_DESC_TX_PHASE_ALL, 0, 0, 0, 1, 0); mac_tx_mpdu_fill_fcinfo(mpdu, proto, \ 0, HW_DESC_TX_PHASE_ALL, delimiter_type, network, nid, 0, \ 0, 0, dtei, stei, lid, bcast, 0, 0, 0, 0, NULL); mac_crc_set_fc_swcrc(proto, mpdu); iot_printf("hwq = %d nncco tx_done\n",qid); /* send */ mac_tx_hw_mpdu(tx_ctxt, qid, mpdu); } void mpdu_tx_sound_test(uint32_t proto, mac_queue_ctxt_t *tx_ctxt, uint8_t qid,\ uint8_t bcast, uint8_t delimiter_type,uint32_t nid,\ uint32_t dtei, uint32_t stei,uint8_t tmi, uint8_t ext_tmi,\ uint8_t lid,uint8_t need_ack, uint8_t need_encry,\ uint8_t hw_retry_cnt, tx_mpdu_end *mpdu_end,\ uint16_t pkt_len, uint8_t *pkt) { tx_mpdu_start *mpdu; tx_pb_start *pb; uint32_t pb_sz; uint32_t pb_mod; uint32_t rate_mode = 0; if(proto == PLC_PROTO_TYPE_SPG) { iot_printf("NW do not supprot sound!"); return; } iot_pkt_t *test_data = \ ftm_fill_mac_data(delimiter_type, MID_DATA_SIZE, pkt, pkt_len); phy_get_pb_size(proto, tmi, ext_tmi, &pb_sz); phy_get_pb_mod(proto, tmi, ext_tmi, &pb_mod); mac_desc_get(&g_mac_desc_eng,PLC_TX_PB_START_POOL, (void**)&pb); mac_desc_get(&g_mac_desc_eng,PLC_TX_MPDU_START_POOL, (void**)&mpdu); IOT_ASSERT(mpdu && pb); mac_tx_mpdu_fill_pb_start(pb, NULL, iot_pkt_data(test_data), 0, 1, 1, proto); uint8_t pb_hdr_resv_crc_len = mac_get_pb_hdr_resv_crc_len(delimiter_type, \ proto); mac_tx_mpdu_fill_macinfo(mpdu, qid, 1, 0, need_ack,\ phy_get_sym_per_pb(proto, 0, tmi, ext_tmi, phy_get_pss_id(proto, tmi, ext_tmi)),\ phy_get_fl_per_pb(proto, 0, tmi, ext_tmi), 0,\ pb_hdr_resv_crc_len, 0, 1, 1, mpdu_end, pb, NULL, 0, \ (uint32_t)(iot_pkt_data(test_data) - (uint8_t*)test_data), 0, 0, 0, 0, 0); mac_tx_mpdu_fill_phyinfo(mpdu, HW_DESC_TX_PORT_PLC, \ 128, HW_DESC_TX_PHASE_ALL, 0, 0, 0, pb_mod, rate_mode); mac_tx_mpdu_fill_fcinfo(mpdu, proto, \ 1, HW_DESC_TX_PHASE_ALL, delimiter_type, 0, nid, 0,\ tmi, ext_tmi, dtei, stei, lid, bcast, 0, 0, 0, 0, NULL); mac_crc_set_fc_swcrc(proto, mpdu); { tx_fc_msg_t msg = {0}; mac_get_tx_msg_from_fc(proto, delimiter_type, &mpdu->fc, &msg); { iot_printf("proto = %d," \ "hwq = %d," \ "sof tx:tmi = %d," \ "sof tx:ext_tmi = %d," \ "pb_num = %d\n", \ proto, qid, msg.tmi, msg.ext_tmi, 1); } } /* send */ mac_tx_hw_mpdu(tx_ctxt, qid, mpdu); } void gp_mpdu_tx_sound_test(uint32_t proto, mac_queue_ctxt_t *tx_ctxt, uint8_t qid,\ uint8_t delimiter_type,uint32_t nid,\ uint32_t dtei, uint32_t stei,uint8_t tmi,\ uint8_t lid,uint8_t need_ack, uint8_t need_encry,\ uint8_t hw_retry_cnt, tx_mpdu_end *mpdu_end,\ uint16_t pkt_len, uint8_t *pkt) { tx_mpdu_start *mpdu; tx_pb_start *pb; uint32_t pb_sz; uint32_t pb_mod; uint32_t rate_mode = 0; uint32_t network = (PLC_PROTO_TYPE_SPG == proto)? 1:0; uint8_t ppdu_mode = (PLC_PROTO_TYPE_GP == proto)? \ HW_DESC_PPDU_MODE_AVONLY_1FCSYM:0; iot_pkt_t *test_data = \ ftm_fill_mac_data(delimiter_type, MID_DATA_SIZE, pkt, pkt_len); phy_get_pb_size(proto, tmi,0,&pb_sz); phy_get_pb_mod(proto, tmi, 0, &pb_mod); mac_desc_get(&g_mac_desc_eng,PLC_TX_PB_START_POOL, (void**)&pb); mac_desc_get(&g_mac_desc_eng,PLC_TX_MPDU_START_POOL, (void**)&mpdu); IOT_ASSERT(mpdu && pb); mac_tx_mpdu_fill_pb_start(pb, NULL, iot_pkt_data(test_data), 0, 1, 1, proto); uint8_t pb_hdr_resv_crc_len = mac_get_pb_hdr_resv_crc_len(delimiter_type, \ proto); mac_tx_mpdu_fill_macinfo(mpdu, qid, 1, 0, 0,\ phy_get_sym_per_pb(proto, 0, tmi, 0, phy_get_pss_id(proto, tmi, ext_tmi)), \ phy_get_fl_per_pb(proto, 0, tmi, 0), 0,\ pb_hdr_resv_crc_len, 0, 1, 1, mpdu_end, pb, NULL, 0, \ (uint32_t)(iot_pkt_data(test_data) - (uint8_t*)test_data), 0, 0, 0, 0, 0); mac_tx_mpdu_fill_phyinfo(mpdu, HW_DESC_TX_PORT_PLC, \ 128, HW_DESC_TX_PHASE_ALL, 0, ppdu_mode, 0, pb_mod, rate_mode); mac_tx_mpdu_fill_fcinfo(mpdu, proto, \ 1, HW_DESC_TX_PHASE_ALL, delimiter_type, network, nid, 0,\ tmi, 0, dtei, stei, lid, 0, 0, 0, 0, 0, NULL); mac_crc_set_fc_swcrc(proto, mpdu); { tx_fc_msg_t msg = {0}; mac_get_tx_msg_from_fc(proto, delimiter_type, &mpdu->fc, &msg); iot_printf("mac_type = %d," \ "hwq = %d," \ "sound tx:tmi = %d," \ "pb_num = %d\n", \ proto, qid, msg.tmi, 1); } /* send */ mac_tx_hw_mpdu(tx_ctxt, qid, mpdu); } void mpdu_send_test(mac_queue_ctxt_t *tx_ctxt, uint8_t qid,\ uint8_t bcast, uint8_t delimiter_type,uint32_t nid,\ uint32_t dtei, uint32_t stei,uint8_t tmi, uint8_t ext_tmi,\ uint8_t lid, uint8_t pb_num, uint8_t need_ack,\ uint8_t need_encry, uint8_t need_decrypt,\ uint32_t avln_idx_in_desc, uint32_t key_table_idx_in_desc,\ uint32_t key_idx_in_desc,\ uint8_t hw_retry_cnt, uint16_t pkt_len, uint8_t *pkt) { tx_mpdu_end *end; /* mac protocol */ uint32_t proto = PHY_PROTO_TYPE_GET(); mac_desc_get(&g_mac_desc_eng, PLC_TX_MPDU_END_POOL, (void**)&end); IOT_ASSERT(end); end->tx_done = 0; end->tx_ok = 0; switch(delimiter_type){ case FC_DELIM_BEACON: (void)pb_num; (void)need_ack; (void)need_decrypt; (void)hw_retry_cnt; (void)avln_idx_in_desc; (void)key_table_idx_in_desc; (void)key_idx_in_desc; mpdu_tx_beacon_test(proto,tx_ctxt, qid, bcast, FC_DELIM_BEACON, nid,\ dtei, stei, tmi, ext_tmi,lid, need_encry, end, pkt_len, pkt); break; case FC_DELIM_SOF: mpdu_tx_sof_test(proto, tx_ctxt, qid, bcast, FC_DELIM_SOF, nid,\ dtei, stei, tmi, ext_tmi,lid, pb_num, need_ack, need_encry,\ need_decrypt, avln_idx_in_desc, key_table_idx_in_desc,\ key_idx_in_desc, hw_retry_cnt, end, pkt_len, pkt); break; case FC_DELIM_NNCCO: (void)tmi; (void)ext_tmi; (void)pb_num; (void)need_ack; (void)need_decrypt; (void)hw_retry_cnt; (void)avln_idx_in_desc; (void)key_table_idx_in_desc; (void)key_idx_in_desc; (void)pkt; (void)pkt_len; mpdu_tx_nncco_test(proto, tx_ctxt, qid, bcast, FC_DELIM_NNCCO, nid,\ dtei, stei, lid, need_encry, end); break; case FC_DELIM_SOUND: (void)pb_num; (void)need_decrypt; (void)avln_idx_in_desc; (void)key_table_idx_in_desc; (void)key_idx_in_desc; mpdu_tx_sound_test(proto, tx_ctxt, qid, bcast, FC_DELIM_SOUND,nid,\ dtei, stei, tmi, ext_tmi,lid, need_ack, need_encry, hw_retry_cnt, end,\ pkt_len, pkt); break; default: IOT_ASSERT(0); } #if 0 uint32_t enq_time = RGF_MAC_READ_REG(CFG_RD_NTB_ADDR); uint32_t cur_time, time_span; #define NTB_MS_TICK 25000 // 0.04us * 25 = 1us, 1us * 1000 = 1ms #define TX_TIMEOUT_TICK (NTB_MS_TICK << 5) // 32 ms mac_rx_ring_ctxt_t *ring_ctxt = &g_mac_pdev[0]->ring_hdl; do { 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; } if (time_span > TX_TIMEOUT_TICK) { iot_printf("tx timeout: %dms > %dms\n", \ time_span / NTB_MS_TICK, \ TX_TIMEOUT_TICK / NTB_MS_TICK); IOT_ASSERT(0); } for(uint8_t i=0;iring[i].enabled){ mac_rx_hw_mpdu(g_mac_pdev[0], i); } } } while (!end->tx_done); mac_tx_hw_mpdu_comp(qid); #endif } /* For GP protocol only */ void gp_mpdu_send_test(mac_queue_ctxt_t *tx_ctxt, uint8_t qid,\ uint8_t delimiter_type,uint32_t snid,\ uint32_t dtei, uint32_t stei,uint8_t tmi,\ uint8_t lid,uint8_t pb_num,\ uint8_t need_encry, uint8_t need_ack, uint8_t hw_retry_cnt, \ uint16_t pkt_len, uint8_t *pkt) { tx_mpdu_end *end; /* mac protocol */ uint32_t proto = PHY_PROTO_TYPE_GET(); mac_desc_get(&g_mac_desc_eng, PLC_TX_MPDU_END_POOL, (void**)&end); IOT_ASSERT(end); end->tx_done = 0; end->tx_ok = 0; switch(delimiter_type){ case DT_AV_BEACON: mpdu_tx_beacon_test(proto, tx_ctxt, qid, 0, DT_AV_BEACON, snid,\ dtei, stei, tmi, 0, lid, need_encry, end, pkt_len, pkt); break; case DT_AV_SOF: mpdu_tx_sof_test(proto, tx_ctxt, qid, 0, DT_AV_SOF, snid,\ dtei, stei, tmi, 0, lid, pb_num, need_ack, need_encry,\ 0, 0, 0, 0, hw_retry_cnt, end, pkt_len, pkt); break; case DT_AV_RTS_CTS: gp_mpdu_tx_rtscts_test(proto, tx_ctxt, qid, DT_AV_RTS_CTS, snid,\ dtei, stei, tmi, lid, pb_num, need_encry,\ 0, end, pkt_len, pkt); break; case DT_AV_SACK: break; case DT_AV_SOUND: gp_mpdu_tx_sound_test(proto, tx_ctxt, qid, DT_AV_SOUND, snid,\ dtei, stei, tmi, lid, 0, need_encry, 0, end, pkt_len, pkt); break; default: IOT_ASSERT(0); } } uint32_t test_send_sof(mac_queue_ctxt_t *tx_ctxt, uint32_t stei, uint32_t dtei, uint32_t nid,\ uint8_t tmi, uint8_t ext_tmi,\ uint8_t pb_num, uint8_t *pkt,uint8_t need_ack) { /* mac protocol */ uint32_t proto = PHY_PROTO_TYPE_GET(); tx_mpdu_end *end; mac_desc_get(&g_mac_desc_eng, PLC_TX_MPDU_END_POOL, (void**)&end); IOT_ASSERT(end); end->tx_done = 0; end->tx_ok = 0; uint8_t qid = 0; mpdu_tx_sof_test(proto,tx_ctxt, qid, 0, FC_DELIM_SOF, nid,\ dtei, stei, tmi, ext_tmi,0, pb_num, need_ack, 0, 0,\ 0, 0, 0, 0, end,100, pkt); if(mac_ping_enable) { enq_time = RGF_MAC_READ_REG(CFG_RD_NTB_ADDR); } do { mac_rx_hw_mpdu(g_mac_pdev[0], 0); } while (!end->tx_done); mac_tx_hw_mpdu_comp(qid, 1); return 0; } uint8_t loop = 0; int32_t mac_tx_mpdu_test(void *pdev, tx_mpdu_start *mpdu) { (void)pdev; uint32_t tmp = 0; uint32_t pb_size = 0; uint32_t tmi = 0, ext_tmi = 0; uint32_t pb_mod = 0; uint32_t rate_mode = glb_cfg.rate_mode; uint32_t* dbg_buf =NULL; mpdu->desc_type = DESC_TYPE_TX_MPDU_START; mpdu->proto_type = glb_cfg.m_type; mpdu->tx_port = HW_DESC_TX_PORT_PLC; mpdu->tx_phase = HW_DESC_TX_PHASE_ALL; mpdu->tx_power = 128; // 1/8 unit db if((glb_cfg.p_type == DT_AV_SOF)||(glb_cfg.p_type == FC_DELIM_SOF)) mpdu->need_ack = 1; mpdu->ppdu_mode = HW_DESC_PPDU_MODE_AVONLY_1FCSYM; mpdu->next = NULL; /* clear the mpdu_end */ if (mpdu->tx_status) { mpdu->tx_status->tx_done = 0; mpdu->tx_status->tx_ok = 0; } /* tmi info */ tmi = glb_cfg.tmi; if (tmi >= 15) { /* if use ext_tmi */ tmi = 15; ext_tmi = glb_cfg.tmi - 15; } if(glb_cfg.m_type == PLC_PROTO_TYPE_SG) { if(glb_cfg.p_type == FC_DELIM_BEACON) { mpdu->fc.sg_fc.delimiter_type = FC_DELIM_BEACON; /*beacon*/ mpdu->fc.sg_fc.vf.bcn.time_stamp = 0; mpdu->fc.sg_fc.vf.bcn.src_tei = 1; mpdu->fc.sg_fc.vf.bcn.tmi = tmi; mpdu->fc.sg_fc.vf.bcn.sym_num = 0; mpdu->fc.sg_fc.vf.bcn.phase_num = 0; mpdu->fc.sg_fc.vf.bcn.pb_num = glb_cfg.pb_num; mpdu->fc.sg_fc.vf.bcn.version = 0; } else if(glb_cfg.p_type == FC_DELIM_SOF) { mpdu->fc.sg_fc.delimiter_type = FC_DELIM_SOF; /*sof*/ mpdu->fc.sg_fc.vf.sof.src_tei = 1; mpdu->fc.sg_fc.vf.sof.dst_tei = 2; mpdu->fc.sg_fc.vf.sof.lid = 0; mpdu->fc.sg_fc.vf.sof.frame_len = 0; mpdu->fc.sg_fc.vf.sof.pb_num = glb_cfg.pb_num; mpdu->fc.sg_fc.vf.sof.sym_num = 0; mpdu->fc.sg_fc.vf.sof.bcast = 0; mpdu->fc.sg_fc.vf.sof.tmi = tmi; mpdu->fc.sg_fc.vf.sof.tmi_ext = ext_tmi; mpdu->fc.sg_fc.vf.sof.version = 0; // RAW DATA TESTING //mpdu->fc.sg_fc.vf.sof.lid = loop++; } else if(glb_cfg.p_type == FC_DELIM_SOUND) { mpdu->fc.sg_fc.delimiter_type = FC_DELIM_SOUND; /*sound*/ mpdu->fc.sg_fc.vf.sof.src_tei = 1; mpdu->fc.sg_fc.vf.sof.dst_tei = 2; mpdu->fc.sg_fc.vf.sof.lid = 0; mpdu->fc.sg_fc.vf.sof.frame_len = 0; mpdu->fc.sg_fc.vf.sof.pb_num = glb_cfg.pb_num; mpdu->fc.sg_fc.vf.sof.sym_num = 0; mpdu->fc.sg_fc.vf.sof.bcast = 0; mpdu->fc.sg_fc.vf.sof.tmi = tmi; mpdu->fc.sg_fc.vf.sof.tmi_ext = ext_tmi; mpdu->fc.sg_fc.vf.sof.version = 0; } mpdu->fc.sg_fc.network_type = 0; // RAW DATA TESTING //mpdu->fc.sg_fc.nid = 0x123456 + (loop++); mpdu->fc.sg_fc.nid = 0x123456; } else if (glb_cfg.m_type == PLC_PROTO_TYPE_SPG) { if(glb_cfg.p_type == FC_DELIM_BEACON) { mpdu->fc.spg_fc.delimiter_type = FC_DELIM_BEACON; /*beacon*/ mpdu->fc.spg_fc.vf.bcn.time_stamp = 0; mpdu->fc.spg_fc.vf.bcn.src_tei = 1; mpdu->fc.spg_fc.vf.bcn.tmi = tmi; mpdu->fc.spg_fc.vf.bcn.sym_num = 0; mpdu->fc.spg_fc.vf.bcn.phase_num = 0; mpdu->fc.spg_fc.vf.bcn.version = 0; } else if(glb_cfg.p_type == FC_DELIM_SOF) { mpdu->fc.spg_fc.delimiter_type = FC_DELIM_SOF; /*sof*/ mpdu->fc.spg_fc.vf.sof.src_tei = 1; mpdu->fc.spg_fc.vf.sof.dst_tei = 2; mpdu->fc.spg_fc.vf.sof.lid = 0; mpdu->fc.spg_fc.vf.sof.frm_len = 0; mpdu->fc.spg_fc.vf.sof.pb_num = glb_cfg.pb_num; mpdu->fc.spg_fc.vf.sof.sym_num = 0; mpdu->fc.spg_fc.vf.sof.tmi = tmi; mpdu->fc.spg_fc.vf.sof.tmi_ext = ext_tmi; mpdu->fc.spg_fc.vf.sof.version = 0; } mpdu->fc.spg_fc.access_ind = 1; mpdu->fc.spg_fc.snid = 0xb; } else{ /* AV FC */ if(glb_cfg.p_type == DT_AV_BEACON) { mpdu->fc.hpav_fc.delimiter_type = DT_AV_BEACON; } else if(glb_cfg.p_type == DT_AV_SOF) { mpdu->fc.hpav_fc.delimiter_type = DT_AV_SOF; mpdu->fc.hpav_fc.vf_av.sof.src_tei = 1; mpdu->fc.hpav_fc.vf_av.sof.dst_tei = 2; mpdu->fc.hpav_fc.vf_av.sof.lid = 0; mpdu->fc.hpav_fc.vf_av.sof.eks = 0xf; if(tmi == 0 || tmi == 1) mpdu->fc.hpav_fc.vf_av.sof.pbsz = 0; else if(tmi == 2) mpdu->fc.hpav_fc.vf_av.sof.pbsz = 1; else IOT_ASSERT(0); mpdu->fc.hpav_fc.vf_av.sof.numsym = 3; mpdu->fc.hpav_fc.vf_av.sof.tmi_av = glb_cfg.tmi; mpdu->fc.hpav_fc.vf_av.sof.fl_av = 0; } else if(glb_cfg.p_type == DT_AV_RTS_CTS) { mpdu->fc.hpav_fc.delimiter_type = DT_AV_RTS_CTS; mpdu->fc.hpav_fc.vf_av.rtscts.src_tei = 1; mpdu->fc.hpav_fc.vf_av.rtscts.dst_tei = 2; mpdu->fc.hpav_fc.vf_av.rtscts.lid = 0; mpdu->fc.hpav_fc.vf_av.rtscts.rtsf = 1; } else if(glb_cfg.p_type == DT_AV_SOUND) { mpdu->fc.hpav_fc.delimiter_type = DT_AV_SOUND; mpdu->fc.hpav_fc.vf_av.sound.stei = 1; mpdu->fc.hpav_fc.vf_av.sound.dtei = 2; mpdu->fc.hpav_fc.vf_av.sound.lid = 0; if(tmi == 0 || tmi == 1) mpdu->fc.hpav_fc.vf_av.sound.pbsz = 0; else if(tmi == 2) mpdu->fc.hpav_fc.vf_av.sound.pbsz = 1; mpdu->fc.hpav_fc.vf_av.sound.req_tm = 1; mpdu->fc.hpav_fc.vf_av.sound.fl_av = 0; mpdu->fc.hpav_fc.vf_av.sound.src = 0xFD;//as part of Initial Channel Estimation } mpdu->fc.hpav_fc.access = 1; mpdu->fc.hpav_fc.snid = 0xb; } /* band info */ #ifdef IOT_SUPPORT_MULTI_RATE_HW mpdu->sg_bandsel = RGF_MAC_READ_REG(CFG_RD_NTB_ADDR)%3; #else mpdu->sg_bandsel = 0; #endif /* only contains the pb's size */ phy_get_pb_size(glb_cfg.m_type, tmi, ext_tmi, &pb_size); mpdu->pb_num = glb_cfg.pb_num; mpdu->total_bytes = pb_size*glb_cfg.pb_num; /* start/end time, ignore in GP's case */ //mpdu->start_time = 0; //mpdu->end_time = 0; /* TODO: amplitude table select */ mpdu->tx_tone_amp = 0; mpdu->tx_symbnum_ppb = phy_get_sym_per_pb(glb_cfg.m_type, mpdu->sg_bandsel, tmi, ext_tmi, phy_get_pss_id(glb_cfg.m_type, tmi, ext_tmi)); if(mpdu->tx_symbnum_ppb*glb_cfg.pb_num >= 512){ iot_printf("[TMI-%d][PB-%d][error]:symbol size %d bigger than 512.", \ ext_tmi+tmi,glb_cfg.pb_num,mpdu->tx_symbnum_ppb*glb_cfg.pb_num); return -1; } mpdu->sw_tx_fl_ppb = (uint32_t) \ phy_get_fl_per_pb(glb_cfg.m_type, mpdu->sg_bandsel, tmi, ext_tmi); /* hw id */ mpdu->swq_id = 0; /* hw retry cnt */ mpdu->hw_retry_cnt = 0; /* set the crc hdr len, GP is 4 for bcn */ if(glb_cfg.m_type == PLC_PROTO_TYPE_SG) { if(glb_cfg.p_type == FC_DELIM_BEACON) { mpdu->pb_hdr_crc_len = 3; } else if((glb_cfg.p_type == FC_DELIM_SOF)||(glb_cfg.p_type == FC_DELIM_SOUND)) { mpdu->pb_hdr_crc_len = 4; } } else if(glb_cfg.m_type == PLC_PROTO_TYPE_SPG) { if(glb_cfg.p_type == FC_DELIM_BEACON) { mpdu->pb_hdr_crc_len = 3; } else if((glb_cfg.p_type == FC_DELIM_SOF)||(glb_cfg.p_type == FC_DELIM_SOUND)) { mpdu->pb_hdr_crc_len = 7; } } else{ if(glb_cfg.p_type == DT_AV_BEACON) { mpdu->pb_hdr_crc_len = 4; } else if(glb_cfg.p_type == DT_AV_SOF) { mpdu->pb_hdr_crc_len = 8; } } /* pb modulation and rate */ phy_get_pb_mod(glb_cfg.m_type,tmi, ext_tmi, &pb_mod); mpdu->tx_pb_modulation = pb_mod; mpdu->tx_rate_mode = rate_mode; #if 0 /* zliu test */ mpdu->proto_type = 4; mpdu->fc.sg_fc.vf.sof.frame_len = 0x1c1; mpdu->fc.sg_fc.vf.sof.pb_num =2; //0x2 is 6/30versions //zliu RAW SPECIAL mpdu->fc.sg_fc.vf.sof.sym_num = 0x15;//mpdu->tx_symbnum_ppb; #endif dbg_buf= (uint32_t*)&mpdu->fc.sg_fc.vf.sof; iot_printf("FC:0x%04x 0x%04x 0x%04x 0x%04x\n", dbg_buf[0],dbg_buf[1],dbg_buf[2],dbg_buf[3]); /* set hwq0's ptr list */ RGF_HWQ_WRITE_REG(CFG_HWQ0_PTR_ADDR, (uint32_t)mpdu); /* read NTB and fill in the start and end time * by max time span value */ tmp = RGF_MAC_READ_REG(CFG_RD_NTB_ADDR); RGF_HWQ_WRITE_REG(CFG_HWQ0_START_ADDR, tmp); RGF_HWQ_WRITE_REG(CFG_HWQ0_END_ADDR, (tmp + (0xffffffff >> 1) - 1)); /* trigger send */ tmp = RGF_HWQ_READ_REG(CFG_HWQ0_ADDR); if (REG_FIELD_GET(CFG_DBG_HWQ0_EN, tmp)) { /* if enable then disable first */ REG_FIELD_SET(CFG_DBG_HWQ0_EN, tmp, 0); // disable hwq RGF_HWQ_WRITE_REG(CFG_HWQ0_ADDR, tmp); } REG_FIELD_SET(CFG_DBG_HWQ0_EN, tmp, 1); // enable hwq RGF_HWQ_WRITE_REG(CFG_HWQ0_ADDR, tmp); return 0; } uint32_t tx_complete_handler(uint32_t vector, iot_addrword_t data) { uint32_t status; status = RGF_MAC_READ_REG(CFG_MAC_INT_STS_ADDR); //iot_printf("intc status=0x%x\r\n",status); if(status & (0x1 <<5)){ /* clear intr */ RGF_MAC_WRITE_REG(CFG_MAC_INT_CLR_ADDR, 0x1<<5); RGF_HWQ_WRITE_REG(CFG_HWQ_TX_DONE_INT_CLR_ADDR,0xf); if(!mpdu_start.tx_status->tx_done) iot_printf("Intr complete,but tx not done!\r\n"); mpdu_start.tx_status->tx_done = 0; mac_tx_complete_flag = true; } if(status & (0x1 <<0)){ /* clear intr */ RGF_MAC_WRITE_REG(CFG_MAC_INT_CLR_ADDR, 0x1<<0); mac_beacon_alert_flag = true; } if(status & (0x1 <<4)){ /* clear intr */ RGF_MAC_WRITE_REG(CFG_MAC_INT_CLR_ADDR, 0x1<<4); mac_beacon_alert_flag = true; } #if MODULE_EN /* single interrupt handler */ INTC_WRITE_REG(CFG_INT_ENA0_ADDR,0x0); #endif return 0; } void mac_interrupt_init() { uint32_t tmp = 0; os_mem_set(&mac_info, 0x0, sizeof(iot_mac_intr_info_t)); /* intc en */ INTC_WRITE_REG(CFG_INT_ENA0_ADDR,0x21); /* clr mac int */ RGF_MAC_WRITE_REG(CFG_MAC_INT_CLR_ADDR, 0x1<<(5));//tx complete RGF_MAC_WRITE_REG(CFG_MAC_INT_CLR_ADDR, 0x1<<(0));//tx beacon alert /* MPDU done intr enable */ tmp = RGF_MAC_READ_REG(CFG_INT_ENA_MASK_ADDR); if(glb_cfg.t_type == MAC_TX_INTR_MPDU_COMPLETE) REG_FIELD_SET(CFG_INT_ENABLE_MASK,tmp,(0x1<<5)); else if(glb_cfg.t_type == MAC_TX_INTR_BCN_ALT) REG_FIELD_SET(CFG_INT_ENABLE_MASK,tmp,(0x1<<0)); else if(glb_cfg.t_type == MAC_TX_SCHED_BCN_AHEAD_ALERT) REG_FIELD_SET(CFG_INT_ENABLE_MASK,tmp,(0x1<<5)); RGF_MAC_WRITE_REG(CFG_INT_ENA_MASK_ADDR, tmp); /* pri int */ tmp = RGF_MAC_READ_REG(CFG_INT_PRI1_MASK_ADDR); REG_FIELD_SET(CFG_INT_PRI1_MASK,tmp,(0x1<<0) | (0x1<<5)); RGF_MAC_WRITE_REG(CFG_INT_PRI1_MASK_ADDR, tmp); /* interrupt controller */ mac_info.int_num = HAL_VECTOR_MAC_1; mac_info.handle = iot_interrupt_create( mac_info.int_num, 0, (iot_addrword_t)&mac_info, tx_complete_handler); iot_interrupt_attach( mac_info.handle); iot_interrupt_unmask( mac_info.handle); } uint32_t mac_hw_init() { uint32_t tmp; /* 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(PLC_PROTO_TYPE_SG, IOT_PLC_PHY_BAND_DFT, TONE_MASK_ID_NULL, true); /* dtest mac interrupt cfg */ if(glb_cfg.t_type >= MAC_TX_INTR_BCN_ALT) mac_interrupt_init(); /******************************************************/ /* mac related dtest param */ /* enable DCU debug mode */ tmp = RGF_HWQ_READ_REG(CFG_SCH_ADDR); if(glb_cfg.t_type == MAC_TX_SCHED_BCN_AHEAD_ALERT) REG_FIELD_SET(CFG_HWQ_DBG_MODE, tmp, 0); // commandlist enable else 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); /* set beacon period */ RGF_MAC_WRITE_REG(CFG_BEACON_PERIOD_ADDR, bcn_period_ms * TICKS_MS); /* config my nid */ tmp = RGF_MAC_READ_REG(CFG_MYNID_ADDR); REG_FIELD_SET(CFG_MYNID, tmp, 0x123456); RGF_MAC_WRITE_REG(CFG_MYNID_ADDR, tmp); /* tei cfg */ RGF_MAC_WRITE_REG(CFG_MYTEI_ADDR, 1); /* enable and trigger the HW to load it */ tmp = RGF_MAC_READ_REG(CFG_TMI_CTRL_ADDR); REG_FIELD_SET(CFG_TONE_AMP_EN, tmp, 0); RGF_MAC_WRITE_REG(CFG_TMI_CTRL_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); return 0; } /* support mode : ftm, module, dtest scan */ void tx_common_init() { /* basic data struct init for bit ops */ iot_bitops_init(); mac_hw_init(); /* construct the desc */ #if MAC_PB_NUM_ID == 1 pb_start.next_pb = NULL; pb_start.pb_buf_addr = (uint32_t)&pb_buf[0]; #elif MAC_PB_NUM_ID == 2 pb_start.next_pb = &pb_second; pb_second.next_pb = NULL; pb_start.pb_buf_addr = (uint32_t)&pb_buf[0]; pb_second.pb_buf_addr = (uint32_t)&pb_buf_second[0]; #elif MAC_PB_NUM_ID == 3 pb_start.next_pb = &pb_second; pb_second.next_pb = &pb_third; pb_third.next_pb = NULL; pb_start.pb_buf_addr = (uint32_t)&pb_buf[0]; pb_second.pb_buf_addr = (uint32_t)&pb_buf_second[0]; pb_third.pb_buf_addr = (uint32_t)&pb_buf_third[0]; #elif MAC_PB_NUM_ID == 4 pb_start.next_pb = &pb_second; pb_second.next_pb = &pb_third; pb_third.next_pb = &pb_last; pb_last.next_pb = NULL; pb_start.pb_buf_addr = (uint32_t)&pb_buf[0]; pb_second.pb_buf_addr = (uint32_t)&pb_buf_second[0]; pb_third.pb_buf_addr = (uint32_t)&pb_buf_third[0]; pb_last.pb_buf_addr = (uint32_t)&pb_buf_last[0]; #endif if((glb_cfg.p_type == DT_AV_SOF) \ ||(glb_cfg.p_type == FC_DELIM_SOF) \ ||(glb_cfg.p_type == FC_DELIM_SOUND)) { sg_sof_pb_hdr_t sg_sof_pb_hdr; sg_sof_pb_hdr.mac_frame_start = 1; sg_sof_pb_hdr.mac_frame_end = 1; sg_sof_pb_hdr.seq = 0; pb_start.sof_pb_header = *((uint8_t *)&sg_sof_pb_hdr); pb_second.sof_pb_header = *((uint8_t *)&sg_sof_pb_hdr); pb_third.sof_pb_header = *((uint8_t *)&sg_sof_pb_hdr); pb_last.sof_pb_header = *((uint8_t *)&sg_sof_pb_hdr); } mpdu_start.next = NULL; mpdu_start.pb_list = &pb_start; mpdu_start.tx_status = &mpdu_end; /* fill in the beacon content */ hp_beacon_payload_fixed_header *tmp = (hp_beacon_payload_fixed_header *)&pb_buf[0]; tmp->nid = 0x123456; tmp->hm = 0; tmp->stei = 1; uint32_t i; tmp->bmi.opad[0] = RGF_MAC_READ_REG(CFG_RD_NTB_ADDR); for (i = 1; i < sizeof(tmp->bmi.opad)/4; i++) { //init pb_buf with 4 pb tmp->bmi.opad[i] = tmp->bmi.opad[0]+i; } } /* 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(uint32_t mac_type, uint32_t pkt_type, uint32_t num) { uint32_t tx_done = 0; uint32_t enq_time = 0, cur_time = 0; int64_t time_span = 0; bool_t period_done = false; mac_glb_map(mac_type,pkt_type,pkt_type); tx_common_init(); do { enq_time = RGF_MAC_READ_REG(CFG_RD_NTB_ADDR); mac_tx_mpdu_test(NULL, &mpdu_start); 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 = mpdu_start.tx_status->tx_done; period_done = ((uint64_t)time_span < bcn_period_ms * TICKS_MS)?0:1; if(!tx_done && period_done){ iot_printf("[Dtest][tx][timeout] Please check again!\r\n"); return; } } while (!tx_done || !period_done); if(--num == 0){ iot_printf("[Dtest][tx][done] Successfully!\r\n"); return; } } while (true); }