717 lines
22 KiB
C
717 lines
22 KiB
C
/****************************************************************************
|
|
|
|
Copyright(c) 2019 by Aerospace C.Power (Chongqing) Microelectronics. ALL RIGHTS RESERVED.
|
|
|
|
This Information is proprietary to Aerospace C.Power (Chongqing) Microelectronics and MAY NOT
|
|
be copied by any method or incorporated into another program without
|
|
the express written consent of Aerospace C.Power. This Information or any portion
|
|
thereof remains the property of Aerospace C.Power. The Information contained herein
|
|
is believed to be accurate and Aerospace C.Power assumes no responsibility or
|
|
liability for its use in any way and conveys no license or title under
|
|
any patent or copyright and makes no representation or warranty that this
|
|
Information is free from patent or copyright infringement.
|
|
|
|
****************************************************************************/
|
|
#include "mac_rf_cert_test.h"
|
|
#include "mac_cert_test.h"
|
|
#include "mac_tx_hw.h"
|
|
#include "iot_io.h"
|
|
#include "mac_desc_engine.h"
|
|
#include "iot_bitops.h"
|
|
#include "os_utils.h"
|
|
#include "tx_test_lib.h"
|
|
#include "mac_msg.h"
|
|
#include "mac.h"
|
|
#include "plc_cert_test.h"
|
|
#include "mpdu_header.h"
|
|
#include "mac_rx_hw.h"
|
|
#include "iot_board.h"
|
|
|
|
#include "mac_sys_reg.h"
|
|
#include "hw_reg_api.h"
|
|
#include "hw_phy_api.h"
|
|
|
|
#include "hw_phy_init.h"
|
|
#include "mac_pdev.h"
|
|
#include "phy_phase.h"
|
|
#include "mac_rf.h"
|
|
#include "phy_pm.h"
|
|
|
|
#if CRF_IOT_CERT_SUPPORT
|
|
|
|
#include "mac_rf_common_hw.h"
|
|
#include "mac_rf_sched_hw.h"
|
|
#include "mac_rf_sched.h"
|
|
#include "mac_rf_tx_hw.h"
|
|
#include "mac_rf_rx_hw.h"
|
|
#include "rf_hw_tonemap.h"
|
|
#include "mac_rf_rx_buf_ring.h"
|
|
#include "mac_rf_txq_hw.h"
|
|
|
|
void mac_rf_mm_to_lp_cert_switch()
|
|
{
|
|
mac_rf_pdev_t *rf_pdev = get_rf_pdev_ptr(PLC_PDEV_ID, RF_PDEV_ID);
|
|
mac_rf_vdev_t *rf_vdev = get_rf_vdev_ptr(PLC_PDEV_ID, rf_pdev->rf_pdev_id,
|
|
PLC_DEFAULT_VDEV);
|
|
|
|
mac_rf_sched_stop(rf_vdev);
|
|
/* flush all tdma/csma queue */
|
|
mac_rf_tx_flush_all_queue(&rf_pdev->hwq_hdl);
|
|
|
|
/* switch hwq to debug mode, tdma */
|
|
mac_rf_txq_set_dbg_mode(1, RF_MT_MODE_HWQ);
|
|
}
|
|
|
|
void mac_rf_cert_desc_init()
|
|
{
|
|
rf_tx_mpdu_start *rf_mpdu = NULL;
|
|
rf_tx_mpdu_end *rf_end = NULL;
|
|
rf_tx_pb_start *rf_pb = NULL;
|
|
|
|
mac_desc_get(&g_mac_desc_eng, PLC_TX_MPDU_START_POOL,
|
|
(void**)&rf_mpdu);
|
|
mac_desc_get(&g_mac_desc_eng, PLC_TX_MPDU_END_POOL,
|
|
(void**)&rf_end);
|
|
mac_desc_get(&g_mac_desc_eng, PLC_TX_PB_START_POOL,
|
|
(void**)&rf_pb);
|
|
IOT_ASSERT(rf_mpdu && rf_end && rf_pb);
|
|
|
|
/*
|
|
* base on the reg set fill the descriptor
|
|
* NOTE: fill mac info would refer the following
|
|
* cfg to fill the desc, so the following function
|
|
* must be placed before the mac info filling
|
|
*/
|
|
uint32_t tx_power = 128;
|
|
mac_rf_tx_mpdu_fill_macinfo(rf_mpdu, NULL, rf_pb,
|
|
rf_end, PHY_PROTO_TYPE_GET(), 0, 0, tx_power,
|
|
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, RF_MT_MODE_HWQ, 0, 0, 0);
|
|
|
|
mac_rf_tx_mpdu_fill_phyinfo(rf_mpdu, 0);
|
|
|
|
g_mt_ctxt->rf_mpdu = rf_mpdu;
|
|
|
|
g_mt_ctxt->rf_pb_st = rf_pb;
|
|
}
|
|
|
|
void mac_rf_cert_test_option_channel_cfg(uint8_t rf_option,
|
|
uint8_t rf_channel)
|
|
{
|
|
uint32_t cur_option = mac_rf_get_self_option();
|
|
uint32_t cur_channel = mac_rf_get_self_channel();
|
|
|
|
/* the flag for cert mode */
|
|
g_mt_ctxt->g_mt_mode_flag = 1;
|
|
|
|
iot_printf("old option = %d, channel:%d, will to set option = %d, "
|
|
"channel:%d\n", cur_option, cur_channel, rf_option, rf_channel);
|
|
|
|
/* update option/channel */
|
|
mac_rf_set_self_option_channel(rf_option, rf_channel);
|
|
|
|
/* cert mode, disable cco check check */
|
|
mac_pdev_t *pdev_t = get_pdev_ptr(PLC_PDEV_ID);
|
|
mac_check_spur_en(&pdev_t->mac_check_spur_ctxt, false);
|
|
|
|
/* info pm module that we need stay awake on cert test mode */
|
|
req_stay_awake(MAC_PM_CERT_TEST_MODULE_ID, true);
|
|
|
|
/* set rf cert flag */
|
|
mac_rf_cert_flag_cfg();
|
|
|
|
/* check phy pwr sts */
|
|
phy_pm_pwr_update(PHY_PM_PWR_STS_TXRX);
|
|
}
|
|
|
|
extern uint32_t mac_cert_test_phy_passthrough(iot_pkt_t *pkt_data);
|
|
|
|
uint32_t mac_rf_cert_test_handle(void *pdev, iot_pkt_t *mt_pkt)
|
|
{
|
|
#if HW_PLATFORM >= HW_PLATFORM_FPGA
|
|
IOT_ASSERT(mt_pkt);
|
|
#if CERT_TEST_DEBUG
|
|
iot_printf("%s\n", __FUNCTION__);
|
|
#endif
|
|
uint32_t pkt_len = 0;
|
|
uint32_t pb_size = 0;
|
|
uint32_t pb_idx = 0, pb_num = 1;
|
|
rx_fc_msg_t rx_fc_msg = { 0 };
|
|
|
|
rf_rx_buf_hdr_t *rx_buf_t = (rf_rx_buf_hdr_t *)iot_pkt_data(mt_pkt);
|
|
rf_rx_attention *att = &(rx_buf_t->att);
|
|
rf_rx_mpdu_start *rx_mpdu_st = &(rx_buf_t->mpdu_st);
|
|
rf_rx_pb_start *pb_st = &(rx_buf_t->pb_st);
|
|
rf_rx_pb_end *pb_ed = &(rx_buf_t->pb_ed);
|
|
void *fc = NULL;
|
|
|
|
if(att->rx_status || att->sig_crc_err || att->phr_crc_err) {
|
|
iot_printf("rf rx err sts:%d, sigerr:%d, phrerr:%d, pberr:%d\n",
|
|
att->rx_status, att->sig_crc_err, att->phr_crc_err,
|
|
pb_ed->rx_pb_crc_err);
|
|
return CON_PKT_NOT_CARE;
|
|
}
|
|
|
|
fc = mac_rf_rx_mpdu_st_get_phr_addr(rx_mpdu_st);
|
|
os_mem_cpy(g_mt_ctxt->tmp_fc, fc, PLC_FC_LEN);
|
|
|
|
mac_rf_get_rx_frm_msg_from_fc(PHY_PROTO_TYPE_GET(), fc, &rx_fc_msg);
|
|
|
|
uint8_t *tmp_src = iot_pkt_block_ptr(mt_pkt, IOT_PKT_BLOCK_DATA);
|
|
|
|
switch(rx_fc_msg.delimiter){
|
|
case FC_DELIM_BEACON:
|
|
{
|
|
iot_printf("this is a beacon! , phase:%d\n",
|
|
rx_fc_msg.phase);
|
|
return CON_PKT_NOT_CARE;
|
|
}
|
|
case FC_DELIM_SOF:
|
|
{
|
|
#if 1//CERT_TEST_DEBUG
|
|
rf_rx_mpdu_end *rx_mpdu_ed = &(rx_buf_t->mpdu_ed);
|
|
mac_rf_rx_debug_log_sof_info(rx_fc_msg, rx_mpdu_st, rx_mpdu_ed,
|
|
pb_st, pb_ed, att);
|
|
#endif
|
|
pb_idx = pb_st->pb_sz_idx;
|
|
pb_size = phy_rf_get_pbsz(pb_idx);
|
|
|
|
IOT_ASSERT(g_mt_ctxt->data_pkt);
|
|
iot_pkt_push(g_mt_ctxt->data_pkt, PLC_FC_LEN);
|
|
/*fc pull into pkt*/
|
|
uint8_t *tmp_fc = iot_pkt_block_ptr(g_mt_ctxt->data_pkt,
|
|
IOT_PKT_BLOCK_DATA);
|
|
os_mem_cpy((uint8_t *)(tmp_fc), (uint8_t *)fc, PLC_FC_LEN);
|
|
/*record fc and pull */
|
|
iot_pkt_pull(g_mt_ctxt->data_pkt, PLC_FC_LEN);
|
|
pkt_len = pb_num * pb_size;
|
|
/* set tail = data */
|
|
iot_pkt_set_tail(g_mt_ctxt->data_pkt,
|
|
iot_pkt_data(g_mt_ctxt->data_pkt));
|
|
/*put the pkt len*/
|
|
iot_pkt_put(g_mt_ctxt->data_pkt, pkt_len);
|
|
|
|
/*put mutil-pb together and complete mpdu*/
|
|
IOT_ASSERT(g_mt_ctxt->data_pkt);
|
|
uint8_t *tmp_data =
|
|
iot_pkt_block_ptr(g_mt_ctxt->data_pkt, IOT_PKT_BLOCK_DATA);
|
|
os_mem_cpy((uint8_t *)tmp_data,
|
|
(uint8_t *)(tmp_src + sizeof(rf_rx_buf_hdr_t)), pb_size);
|
|
break;
|
|
}
|
|
case FC_DELIM_SACK:
|
|
{
|
|
#if CERT_TEST_DEBUG
|
|
iot_printf("this is a NNCCO or ACK!\n");
|
|
#endif
|
|
IOT_ASSERT(g_mt_ctxt->data_pkt);
|
|
iot_pkt_push(g_mt_ctxt->data_pkt, PLC_FC_LEN);
|
|
/*fc pull into pkt*/
|
|
uint8_t *tmp_fc = iot_pkt_block_ptr(g_mt_ctxt->data_pkt,
|
|
IOT_PKT_BLOCK_DATA);
|
|
os_mem_cpy((uint8_t *)(tmp_fc), (uint8_t *)fc, PLC_FC_LEN);
|
|
/*record fc and pull */
|
|
iot_pkt_pull(g_mt_ctxt->data_pkt, PLC_FC_LEN);
|
|
/* set tail = data */
|
|
iot_pkt_set_tail(g_mt_ctxt->data_pkt,
|
|
iot_pkt_data(g_mt_ctxt->data_pkt));
|
|
break;
|
|
}
|
|
default:
|
|
{
|
|
iot_printf("No frame type detected\n");
|
|
return CON_PKT_NOT_CARE;
|
|
}
|
|
}
|
|
|
|
/* send data to uart */
|
|
mac_cert_test_phy_passthrough(g_mt_ctxt->data_pkt);
|
|
#else
|
|
(void)pdev;
|
|
(void)mt_pkt;
|
|
#endif
|
|
return CON_PKT_FREE;
|
|
}
|
|
|
|
uint32_t mac_rf_cert_loopback_handle(void *pdev, iot_pkt_t *mt_pkt)
|
|
{
|
|
#if HW_PLATFORM >= HW_PLATFORM_FPGA
|
|
IOT_ASSERT(mt_pkt);
|
|
|
|
#if CERT_TEST_DEBUG
|
|
iot_printf("%s\n", __FUNCTION__);
|
|
#endif
|
|
uint32_t phr_mcs = 0, pld_mcs = 0, pb_idx = 0;
|
|
uint32_t pb_num = 1;
|
|
uint8_t *tmp_src = NULL;
|
|
uint8_t *buf_addr = NULL;
|
|
|
|
rf_rx_buf_hdr_t *rx_buf_t = (rf_rx_buf_hdr_t *)iot_pkt_data(mt_pkt);
|
|
rf_rx_attention *att = &(rx_buf_t->att);
|
|
rf_rx_mpdu_start *rx_mpdu_st = &(rx_buf_t->mpdu_st);
|
|
rf_rx_pb_start *pb_st = &(rx_buf_t->pb_st);
|
|
rf_rx_pb_end *pb_ed = &(rx_buf_t->pb_ed);
|
|
void *fc = NULL;
|
|
rx_fc_msg_t rx_fc_msg = { 0 };
|
|
|
|
if(att->rx_status || att->sig_crc_err || att->phr_crc_err) {
|
|
iot_printf("rf rx err sts:%d, sigerr:%d, phrerr:%d, pberr:%d\n",
|
|
att->rx_status, att->sig_crc_err, att->phr_crc_err,
|
|
pb_ed->rx_pb_crc_err);
|
|
return CON_PKT_NOT_CARE;
|
|
}
|
|
|
|
fc = mac_rf_rx_mpdu_st_get_phr_addr(rx_mpdu_st);
|
|
mac_rf_get_rx_frm_msg_from_fc(PHY_PROTO_TYPE_GET(), fc, &rx_fc_msg);
|
|
|
|
if (!mac_cert_is_nid_valid((nid_t)rx_fc_msg.nid)) {
|
|
return CON_PKT_FREE;
|
|
}
|
|
|
|
phr_mcs = att->phr_mcs;
|
|
pld_mcs = att->pld_mcs;
|
|
pb_idx = pb_st->pb_sz_idx;
|
|
|
|
tmp_src = iot_pkt_block_ptr(mt_pkt, IOT_PKT_BLOCK_DATA);
|
|
buf_addr = tmp_src + sizeof(rf_rx_buf_hdr_t);
|
|
|
|
switch(rx_fc_msg.delimiter) {
|
|
case FC_DELIM_BEACON:
|
|
{
|
|
iot_printf("this is a beacon!, phase:%d\n", rx_fc_msg.phase);
|
|
return CON_PKT_NOT_CARE;
|
|
break;
|
|
}
|
|
case FC_DELIM_SOF:
|
|
{
|
|
#if CERT_TEST_DEBUG
|
|
rf_rx_mpdu_end *rx_mpdu_ed = &(rx_buf_t->mpdu_ed);
|
|
mac_rf_rx_debug_log_sof_info(rx_fc_msg, rx_mpdu_st, rx_mpdu_ed,
|
|
pb_st, pb_ed, att);
|
|
#endif
|
|
|
|
/* NOTE: cur mpdu all pb offset should be the same, or tx_comp will err */
|
|
if (g_mt_ctxt->rf_sw_buf_offset == 0) {
|
|
g_mt_ctxt->rf_sw_buf_offset = (uint32_t)(buf_addr - (uint8_t*)mt_pkt);
|
|
}
|
|
|
|
g_mt_ctxt->rf_pb_st->next_pb = NULL;
|
|
|
|
rf_tx_pb_start *pb = g_mt_ctxt->rf_pb_st;
|
|
pb->next_pb = NULL;
|
|
|
|
mac_rf_tx_mpdu_fill_pb_start(pb, buf_addr, pb_st->ssn,
|
|
pb_st->msdu_start, pb_st->msdu_end, PHY_PROTO_TYPE_GET());
|
|
break;
|
|
}
|
|
case FC_DELIM_SACK:
|
|
{
|
|
#if CERT_TEST_DEBUG
|
|
iot_printf("this is a NNCCO or ACK!\n");
|
|
#endif
|
|
g_mt_ctxt->rf_mpdu->pb = NULL;
|
|
break;
|
|
}
|
|
default:
|
|
{
|
|
iot_printf("No frame type detected\n");
|
|
return CON_PKT_NOT_CARE;
|
|
}
|
|
}
|
|
|
|
rf_tx_mpdu_start *rf_mpdu = g_mt_ctxt->rf_mpdu;
|
|
rf_tx_dummy_node *next = NULL;
|
|
mac_desc_get(&g_mac_desc_eng, PLC_TX_DUMMY_NODE_POOL,
|
|
(void**)&next);
|
|
rf_tx_mpdu_end *end = rf_mpdu->tx_status;
|
|
IOT_ASSERT(rf_mpdu && next && end);
|
|
|
|
mac_rf_tx_mpdu_fill_dummy((rf_tx_dummy_node *)next);
|
|
|
|
uint32_t sw_buf_offset = g_mt_ctxt->rf_sw_buf_offset;
|
|
/* just sof and beacon need check sw_buf_offset */
|
|
if (rx_fc_msg.delimiter == FC_DELIM_SOF ||
|
|
rx_fc_msg.delimiter == FC_DELIM_BEACON) {
|
|
IOT_ASSERT(sw_buf_offset);
|
|
}
|
|
|
|
uint32_t tx_power = 128;
|
|
uint32_t option = mac_rf_get_self_option();
|
|
mac_rf_tx_mpdu_fill_macinfo(rf_mpdu, /* rf_mpdu_start */
|
|
(rf_tx_mpdu_start *)next, /* next */
|
|
g_mt_ctxt->rf_pb_st, /* pb_start */
|
|
end, /* end */
|
|
PHY_PROTO_TYPE_GET(), /* protocol type */
|
|
0, /* need_ack */
|
|
0, /* retry_cnt */
|
|
tx_power, /* tx_power */
|
|
0, /* retry_bit_en */
|
|
0, /* is_msdu */
|
|
0, /* pb_buf_reuse */
|
|
1, /* tx_desc_reuse */
|
|
sw_buf_offset, /* sw_buf_offset */
|
|
1, /* is_list_start */
|
|
1, /* is_list_end */
|
|
phr_mcs, /* phr_mcs */
|
|
0, /* pts */
|
|
0, /* pts_off */
|
|
pld_mcs, /* pld_mcs */
|
|
pb_idx, /* blkz */
|
|
1, /* crc32_en */
|
|
0, /* crc32_ofs */
|
|
RF_MT_MODE_HWQ, /* hwq_id */
|
|
option, /* option */
|
|
pb_num, /* pb_num */
|
|
0 /* tx_frame_len */
|
|
);
|
|
|
|
mac_rf_tx_mpdu_fill_phyinfo(rf_mpdu, 0);
|
|
|
|
os_mem_cpy(&rf_mpdu->phr0, fc, PLC_FC_LEN);
|
|
|
|
mac_rf_queue_ctxt_t *rf_hwq_ctxt = &g_mac_pdev[0]->mac_rf_pdev->hwq_hdl;
|
|
|
|
mac_rf_tx_hw_mpdu(rf_hwq_ctxt, RF_MT_MODE_HWQ, rf_mpdu);
|
|
|
|
#else
|
|
(void)pdev;
|
|
(void)mt_pkt;
|
|
#endif
|
|
return CON_PKT_NOT_FREE;
|
|
}
|
|
|
|
uint32_t mac_rf_cert_test_set_phy_hplc2rf_lp(uint8_t phr_mcs, uint8_t pld_mcs,
|
|
uint8_t pb_idx) {
|
|
g_mt_ctxt->phr_mcs = phr_mcs;
|
|
g_mt_ctxt->pld_mcs = pld_mcs;
|
|
g_mt_ctxt->pb_idx = pb_idx;
|
|
if (phr_mcs == MCS_ID_5 || phr_mcs == MCS_ID_6 ||
|
|
pld_mcs == MCS_ID_5 || pld_mcs == MCS_ID_6) {
|
|
/* mcs 5/6 need special config */
|
|
mac_rf_set_cert_16qam_flag(1);
|
|
} else {
|
|
mac_rf_set_cert_16qam_flag(0);
|
|
}
|
|
iot_printf("%s phr_mcs:%d, pld_mcs:%d, pb_idx:%d\n", __FUNCTION__,
|
|
g_mt_ctxt->phr_mcs, g_mt_ctxt->pld_mcs, g_mt_ctxt->pb_idx);
|
|
return 0;
|
|
}
|
|
|
|
uint32_t mac_rf_cert_loopback_hplc2rf(void *pdev, iot_pkt_t *mt_pkt)
|
|
{
|
|
#if HW_PLATFORM >= HW_PLATFORM_FPGA
|
|
IOT_ASSERT(mt_pkt);
|
|
|
|
#if CERT_TEST_DEBUG
|
|
iot_printf("%s\n", __FUNCTION__);
|
|
#endif
|
|
uint32_t option = mac_rf_get_self_option();
|
|
uint32_t tmi = 0, ext_tmi = 0;
|
|
uint32_t pb_num = 0;
|
|
uint8_t phase;
|
|
uint32_t proto = PHY_PROTO_TYPE_GET();
|
|
|
|
if (option == PHY_RF_OPTION3_200K) {
|
|
if (g_mt_ctxt->phr_mcs < MCS_ID_2 || g_mt_ctxt->phr_mcs >= MCS_ID_MAX) {
|
|
iot_printf("hplc2rf error, set phr mcs:%d\n", g_mt_ctxt->phr_mcs);
|
|
g_mt_ctxt->phr_mcs = MCS_ID_6;
|
|
}
|
|
if (g_mt_ctxt->pld_mcs < MCS_ID_1 || g_mt_ctxt->pld_mcs >= MCS_ID_MAX) {
|
|
iot_printf("hplc2rf error, set pld mcs:%d\n", g_mt_ctxt->pld_mcs);
|
|
g_mt_ctxt->pld_mcs = MCS_ID_6;
|
|
}
|
|
if (g_mt_ctxt->pb_idx >= BLOCK_SIZE_MAX) {
|
|
iot_printf("hplc2rf error, set pbidx mcs:%d\n", g_mt_ctxt->pb_idx);
|
|
g_mt_ctxt->pb_idx = BLOCK_SIZE_5;
|
|
}
|
|
} else {
|
|
if (g_mt_ctxt->phr_mcs >= MCS_ID_MAX) {
|
|
iot_printf("hplc2rf error, set phr mcs:%d\n", g_mt_ctxt->phr_mcs);
|
|
g_mt_ctxt->phr_mcs = MCS_ID_6;
|
|
}
|
|
if (g_mt_ctxt->pld_mcs >= MCS_ID_MAX) {
|
|
iot_printf("hplc2rf error, set pld mcs:%d\n", g_mt_ctxt->pld_mcs);
|
|
g_mt_ctxt->pld_mcs = MCS_ID_6;
|
|
}
|
|
if (g_mt_ctxt->pb_idx >= BLOCK_SIZE_MAX) {
|
|
iot_printf("hplc2rf error, set pbidx mcs:%d\n", g_mt_ctxt->pb_idx);
|
|
g_mt_ctxt->pb_idx = BLOCK_SIZE_5;
|
|
}
|
|
}
|
|
|
|
rx_buf_hdr_t *rx_buf_t = (rx_buf_hdr_t *)iot_pkt_data(mt_pkt);
|
|
rx_mpdu_start *rx_mpdu_st = &(rx_buf_t->mpdu_st);
|
|
rx_pb_start *pb_st = &(rx_buf_t->pb_st);
|
|
rx_pb_end *pb_ed = &(rx_buf_t->pb_ed);
|
|
void *fc = NULL;
|
|
rx_fc_msg_t rx_fc_msg = { 0 };
|
|
uint32_t pb_size;
|
|
|
|
if(pb_ed->rx_pb_crc_err) {
|
|
iot_printf("rx a error pb! pb_ed_rxpbcrc = %d\n", pb_ed->rx_pb_crc_err);
|
|
return CON_PKT_NOT_CARE;
|
|
}
|
|
|
|
fc = mac_rx_mpdu_st_get_fc_addr(rx_mpdu_st);
|
|
mac_get_rx_frm_msg_from_fc(PHY_PROTO_TYPE_GET(),
|
|
fc, &rx_fc_msg);
|
|
|
|
if (!mac_cert_is_nid_valid((nid_t)rx_fc_msg.nid)) {
|
|
return CON_PKT_FREE;
|
|
}
|
|
|
|
uint8_t *tmp_src = iot_pkt_block_ptr(mt_pkt, IOT_PKT_BLOCK_DATA);
|
|
uint8_t *buf_addr = tmp_src + sizeof(rx_buf_hdr_t);
|
|
|
|
switch (rx_fc_msg.delimiter) {
|
|
case FC_DELIM_BEACON:
|
|
{
|
|
iot_printf("this is a beacon!, phase:%d\n", rx_fc_msg.phase);
|
|
/*record beacon phase*/
|
|
g_mt_ctxt->rx_phase = rx_fc_msg.phase;
|
|
if (mac_cert_is_nid_valid(rx_fc_msg.nid)) {
|
|
if (rx_fc_msg.phase == PLC_PHASE_ALL) {
|
|
phase = PLC_PHASE_A;
|
|
} else {
|
|
phase = rx_fc_msg.phase;
|
|
}
|
|
phy_rx_phase_force_set(1, PLC_PHASE_TO_HW_PHASE(phase));
|
|
}
|
|
return CON_PKT_NOT_CARE;
|
|
break;
|
|
}
|
|
case FC_DELIM_SOF:
|
|
{
|
|
#if CERT_TEST_DEBUG
|
|
iot_printf("this is a sof!\n");
|
|
#endif
|
|
pb_num = rx_fc_msg.pb_num;
|
|
|
|
tmi = rx_fc_msg.tmi;
|
|
ext_tmi = rx_fc_msg.tmi_ext;
|
|
|
|
phy_get_pb_size(PHY_PROTO_TYPE_GET(), tmi, ext_tmi, &pb_size);
|
|
#if CERT_TEST_DEBUG
|
|
if (1 == pb_st->first_pb) {
|
|
g_mt_ctxt->raw_snr = mac_rx_mpdu_st_get_avg_snr(rx_mpdu_st);
|
|
mac_rx_mpdu_st_set_avg_snr(rx_mpdu_st, phy_rx_snr_cal(
|
|
mac_rx_mpdu_st_get_phy_info_addr(rx_mpdu_st),
|
|
mac_rx_mpdu_st_get_rx_phase(rx_mpdu_st)));
|
|
}
|
|
mac_rx_debug_log_sof_uicast_info(rx_fc_msg, rx_mpdu_st,
|
|
(rx_mpdu_end *)&(rx_buf_t->mpdu_ed), pb_st, g_mt_ctxt->raw_snr);
|
|
#endif
|
|
if (pb_st->ssn != 0) {
|
|
iot_printf("hplc2rf ssn error ssn:%d, current not support"
|
|
" multipb\n", pb_st->ssn);
|
|
/* if ssn not match sg standard, need free this pkt */
|
|
pb_ed->rx_pb_crc_err = 1;
|
|
return CON_PKT_NOT_CARE;
|
|
}
|
|
/* NOTE: cur mpdu all pb offset should be the same, or tx_comp will err */
|
|
if (g_mt_ctxt->rf_sw_buf_offset == 0) {
|
|
g_mt_ctxt->rf_sw_buf_offset =
|
|
(uint32_t)(buf_addr - (uint8_t*)mt_pkt);
|
|
}
|
|
|
|
if (1 == pb_st->first_pb && 1 == pb_st->last_pb) {
|
|
g_mt_ctxt->rf_pb_st->next_pb = NULL;
|
|
} else {
|
|
iot_printf("hplc2rf error firstpb:%d, lastpb:%d\n",
|
|
pb_st->first_pb, pb_st->last_pb);
|
|
pb_ed->rx_pb_crc_err = 1;
|
|
return CON_PKT_NOT_CARE;
|
|
}
|
|
uint32_t rf_pbsz = phy_rf_get_pbsz(g_mt_ctxt->pb_idx);
|
|
if (pb_num != 1
|
|
|| rf_pbsz < pb_size) {
|
|
iot_printf("hplc2rf error, msdustart:%d, msduend:%d, pb_num:%d, "
|
|
"pb_size:%d\n",
|
|
pb_st->msdu_start, pb_st->msdu_end, pb_num, pb_size);
|
|
pb_ed->rx_pb_crc_err = 1;
|
|
return CON_PKT_NOT_CARE;
|
|
}
|
|
if (g_mt_ctxt->hplc2rf_ing) {
|
|
iot_printf("hplc2rf error:last packet is in transmit!!!");
|
|
pb_ed->rx_pb_crc_err = 1;
|
|
return CON_PKT_NOT_CARE;
|
|
}
|
|
rf_tx_pb_start *pb = g_mt_ctxt->rf_pb_st;
|
|
pb->next_pb = NULL;
|
|
mac_rf_tx_mpdu_fill_pb_start(pb, buf_addr, pb_st->ssn,
|
|
pb_st->msdu_start, pb_st->msdu_end, proto);
|
|
break;
|
|
}
|
|
case FC_DELIM_SACK:
|
|
case FC_DELIM_NNCCO:
|
|
{
|
|
iot_printf("this is a NNCCO or ACK!\n");
|
|
g_mt_ctxt->rf_mpdu->pb = NULL;
|
|
return CON_PKT_NOT_CARE;
|
|
break;
|
|
}
|
|
default:
|
|
{
|
|
iot_printf("No frame type detected\n");
|
|
return CON_PKT_NOT_CARE;
|
|
}
|
|
}
|
|
|
|
if (1 == pb_st->last_pb) {
|
|
rf_tx_mpdu_start *rf_mpdu = g_mt_ctxt->rf_mpdu;
|
|
rf_tx_dummy_node *next = NULL;
|
|
mac_desc_get(&g_mac_desc_eng, PLC_TX_DUMMY_NODE_POOL,
|
|
(void**)&next);
|
|
rf_tx_mpdu_end *end = rf_mpdu->tx_status;
|
|
IOT_ASSERT(rf_mpdu && next && end);
|
|
|
|
mac_rf_tx_mpdu_fill_dummy((rf_tx_dummy_node *)next);
|
|
|
|
uint32_t sw_buf_offset = g_mt_ctxt->rf_sw_buf_offset;
|
|
/* just sof and beacon need check sw_buf_offset */
|
|
if (rx_fc_msg.delimiter == FC_DELIM_SOF) {
|
|
IOT_ASSERT(sw_buf_offset);
|
|
}
|
|
|
|
uint32_t tx_power = 128;
|
|
mac_rf_tx_mpdu_fill_macinfo(rf_mpdu, /* rf_mpdu_start */
|
|
(rf_tx_mpdu_start *)next, /* next */
|
|
g_mt_ctxt->rf_pb_st, /* pb_start */
|
|
end, /* end */
|
|
PHY_PROTO_TYPE_GET(), /* protocol type */
|
|
0, /* need_ack */
|
|
0, /* retry_cnt */
|
|
tx_power, /* tx_power */
|
|
0, /* retry_bit_en */
|
|
0, /* is_msdu */
|
|
0, /* pb_buf_reuse */
|
|
1, /* tx_desc_reuse */
|
|
sw_buf_offset, /* sw_buf_offset */
|
|
1, /* is_list_start */
|
|
1, /* is_list_end */
|
|
g_mt_ctxt->phr_mcs, /* phr_mcs */
|
|
0, /* pts */
|
|
0, /* pts_off */
|
|
g_mt_ctxt->pld_mcs, /* pld_mcs */
|
|
g_mt_ctxt->pb_idx, /* blkz */
|
|
1, /* crc32_en */
|
|
0, /* crc32_ofs */
|
|
RF_MT_MODE_HWQ, /* hwq_id */
|
|
option, /* option */
|
|
pb_num, /* pb_num */
|
|
0 /* tx_frame_len */
|
|
);
|
|
|
|
mac_rf_tx_mpdu_fill_phyinfo(rf_mpdu, 0);
|
|
os_mem_cpy(&rf_mpdu->phr0, fc, PLC_FC_LEN);
|
|
#if SUPPORT_SMART_GRID
|
|
if (PLC_PROTO_TYPE_SG == proto) {
|
|
/* fill pbszidx and mcs */
|
|
frame_control_t *fc = (frame_control_t*)&rf_mpdu->phr0;
|
|
fc->vf.rf_sof.pb_sz_idx = (uint16_t)g_mt_ctxt->pb_idx;
|
|
fc->vf.rf_sof.mcs = (uint16_t)g_mt_ctxt->pld_mcs;
|
|
} else
|
|
#endif
|
|
#if SUPPORT_SOUTHERN_POWER_GRID
|
|
if (PLC_PROTO_TYPE_SPG == proto) {
|
|
/* fill pbszidx and mcs */
|
|
spg_frame_control_t *fc = (spg_frame_control_t*)&rf_mpdu->phr0;
|
|
fc->vf.rf_sof.pb_sz_idx = (uint16_t)g_mt_ctxt->pb_idx;
|
|
fc->vf.rf_sof.mcs = g_mt_ctxt->pld_mcs;
|
|
} else
|
|
#endif
|
|
{
|
|
IOT_ASSERT(0);
|
|
}
|
|
mac_rf_queue_ctxt_t *rf_hwq_ctxt = &g_mac_pdev[0]->mac_rf_pdev->hwq_hdl;
|
|
|
|
mac_rf_tx_hw_mpdu(rf_hwq_ctxt, RF_MT_MODE_HWQ, rf_mpdu);
|
|
g_mt_ctxt->hplc2rf_ing = 1;
|
|
}
|
|
#else
|
|
(void)pdev;
|
|
(void)mt_pkt;
|
|
#endif
|
|
|
|
return CON_PKT_NOT_FREE;
|
|
}
|
|
|
|
void mac_rf_cert_mode_cfg(uint32_t cert_mode)
|
|
{
|
|
/* mac rf set certification mode */
|
|
mac_rf_set_cert_mode(cert_mode);
|
|
}
|
|
|
|
void mac_rf_cert_flag_cfg()
|
|
{
|
|
/* mac rf set certification flag */
|
|
mac_rf_set_cert_flag();
|
|
}
|
|
|
|
void mac_rf_cert_set_pb_hdr_to_buf(uint32_t value)
|
|
{
|
|
mac_rf_set_pb_hdr_to_buf(value);
|
|
}
|
|
|
|
#else /* CRF_IOT_CERT_SUPPORT */
|
|
|
|
void mac_rf_mm_to_lp_cert_switch()
|
|
{
|
|
}
|
|
|
|
void mac_rf_cert_desc_init()
|
|
{
|
|
}
|
|
|
|
void mac_rf_cert_test_option_channel_cfg(uint8_t rf_option,
|
|
uint8_t rf_channel)
|
|
{
|
|
(void)rf_option;
|
|
(void)rf_channel;
|
|
}
|
|
|
|
uint32_t mac_rf_cert_loopback_handle(void *pdev, iot_pkt_t *mt_pkt)
|
|
{
|
|
(void)pdev;
|
|
(void)mt_pkt;
|
|
return CON_PKT_NOT_FREE;
|
|
}
|
|
|
|
uint32_t mac_rf_cert_test_handle(void *pdev, iot_pkt_t *mt_pkt)
|
|
{
|
|
(void)pdev;
|
|
(void)mt_pkt;
|
|
return CON_PKT_NOT_FREE;
|
|
}
|
|
|
|
uint32_t mac_rf_cert_test_set_phy_hplc2rf_lp(uint8_t phr_mcs, uint8_t pld_mcs,
|
|
uint8_t pb_idx) {
|
|
(void)phr_mcs;
|
|
(void)pld_mcs;
|
|
(void)pb_idx;
|
|
return CON_PKT_NOT_FREE;
|
|
}
|
|
|
|
uint32_t mac_rf_cert_loopback_hplc2rf(void *pdev, iot_pkt_t *mt_pkt)
|
|
{
|
|
(void)pdev;
|
|
(void)mt_pkt;
|
|
return CON_PKT_NOT_FREE;
|
|
}
|
|
|
|
void mac_rf_cert_mode_cfg(uint32_t cert_mode)
|
|
{
|
|
(void)cert_mode;
|
|
}
|
|
|
|
void mac_rf_cert_flag_cfg()
|
|
{
|
|
}
|
|
|
|
void mac_rf_cert_set_pb_hdr_to_buf(uint32_t value)
|
|
{
|
|
(void)value;
|
|
}
|
|
|
|
#endif /* CRF_IOT_CERT_SUPPORT */
|
|
|