Files
kunlun/dtest/rawdata_test/mac_tx_test/tx_entry.c

1286 lines
42 KiB
C
Raw Normal View History

2024-09-28 14:24:04 +08:00
#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; i<MAX_MAC_TXQ_NUM; i++)
{
g_msdu[i] = \
os_mem_malloc(IOT_FTM_MID,sizeof(mac_msdu_t));
IOT_ASSERT(g_msdu[i]);
mac_msdu_init(g_msdu[i], 1, NULL, NULL);
}
#endif
return;
}
//TODO:fill mac msdu header for test
bool_t mac_fill_msdu_frame(uint32_t proto, iot_pkt_t *buf, uint16_t data_len)
{
uint16_t msdu_len = 0;
IOT_ASSERT(buf);
//TODO: no mac addr case
switch (proto)
{
#if SUPPORT_SMART_GRID
case PLC_PROTO_TYPE_SG:
{
if (iot_pkt_data_len(buf) < (data_len + SG_MAC_MSDU_CRC_LEN))
{
return false;
}
mac_header_t *sg_mac = (mac_header_t *)iot_pkt_data(buf);
msdu_len = data_len - MAC_HDR_LEN_NO_ADDR;
if (sg_mac->msdu_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;i<MAX_PLC_RX_RING_NUM;i++){
if(ring_ctxt->ring[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);
}