Files
kunlun/plc/common/src/plc_mpdu_header.c
2024-09-28 14:24:04 +08:00

1860 lines
49 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 "rx_mpdu_start.h"
#include "hw_desc.h"
#include "mpdu_header.h"
#include "rx_pb_start.h"
#include "plc_protocol.h"
#include "mac_data_api.h"
#include "phy_bb.h"
#include "iot_io.h"
#include "mac_sched_hw.h"
#include "mac_tx_hw.h"
#include "mac_hplc_ext_api.h"
uint32_t mac_get_nncco_protect_region_offset(uint32_t proto, void *fc)
{
uint32_t ret = 0;
switch (proto)
{
#if SUPPORT_SMART_GRID
case PLC_PROTO_TYPE_SG:
ret = ((frame_control_t *)fc)->vf.nn_cco.sbandoffset;
break;
#endif
#if SUPPORT_SOUTHERN_POWER_GRID
case PLC_PROTO_TYPE_SPG:
ret = ((spg_frame_control_t *)fc)->vf.nn_cco.bwth_start_shift;
break;
#endif
#if SUPPORT_GREEN_PHY
case PLC_PROTO_TYPE_GP:
/* GP has no this feature */
IOT_ASSERT(0);
break;
#endif
default:
// todo
break;
}
return ret;
}
uint32_t mac_get_nncco_received_nid(uint32_t proto, void *fc)
{
uint32_t ret = 0;
switch (proto)
{
#if SUPPORT_SMART_GRID
case PLC_PROTO_TYPE_SG:
ret = ((frame_control_t *)fc)->vf.nn_cco.receive_nid;
break;
#endif
#if SUPPORT_SOUTHERN_POWER_GRID
case PLC_PROTO_TYPE_SPG:
ret = ((spg_frame_control_t *)fc)->vf.nn_cco.neighbor_network;
break;
#endif
#if SUPPORT_GREEN_PHY
case PLC_PROTO_TYPE_GP:
/* GP has no this feature */
IOT_ASSERT(0);
break;
#endif
default:
// todo
break;
}
return ret;
}
uint32_t mac_is_unicast(uint32_t proto, void *fc, uint8_t is_rf)
{
uint32_t ret = 0;
(void)is_rf;
switch (proto) {
#if SUPPORT_SMART_GRID
case PLC_PROTO_TYPE_SG:
if (is_rf) {
ret = (((frame_control_t *)fc)->vf.rf_sof.dst_tei != 0xfff);
} else {
ret = (((frame_control_t *)fc)->vf.sof.dst_tei != 0xfff);
}
break;
#endif
#if SUPPORT_SOUTHERN_POWER_GRID
case PLC_PROTO_TYPE_SPG:
ret = (((spg_frame_control_t *)fc)->vf.sof.dst_tei != 0xfff);
break;
#endif
#if SUPPORT_GREEN_PHY
case PLC_PROTO_TYPE_GP:
ret = (((hpav_frame_control *)fc)->vf_av.sof.dst_tei != 0xff);
break;
#endif
default:
// todo
IOT_ASSERT(0);
break;
}
return ret;
}
uint32_t mac_get_nncco_protect_dur(uint32_t proto, void *fc)
{
uint32_t ret = 0;
switch (proto)
{
#if SUPPORT_SMART_GRID
case PLC_PROTO_TYPE_SG:
ret = ((frame_control_t *)fc)->vf.nn_cco.duration;
break;
#endif
#if SUPPORT_SOUTHERN_POWER_GRID
case PLC_PROTO_TYPE_SPG:
ret = ((spg_frame_control_t *)fc)->vf.nn_cco.conti_time;
break;
#endif
#if SUPPORT_GREEN_PHY
case PLC_PROTO_TYPE_GP:
/* GP has no this feature */
IOT_ASSERT(0);
break;
#endif
default:
// todo
break;
}
return ret;
}
uint8_t mac_get_nncco_self_ch_id(uint32_t proto, void *fc)
{
uint8_t rf_channel;
#if HPLC_RF_SUPPORT
switch (proto) {
#if SUPPORT_SMART_GRID
case PLC_PROTO_TYPE_SG:
{
rf_channel =
(uint8_t)((frame_control_t *)fc)->vf.nn_cco.self_rf_channel;
break;
}
#endif
#if SUPPORT_SOUTHERN_POWER_GRID
case PLC_PROTO_TYPE_SPG:
{
rf_channel =
(uint8_t)((spg_frame_control_t *)fc)->vf.nn_cco.self_rf_channel;
break;
}
#endif
default:
rf_channel = RF_CHANNEL_ID_INVALID;
break;
}
#else
(void)proto;
(void)fc;
rf_channel = RF_CHANNEL_ID_INVALID;
#endif
return rf_channel;
}
uint8_t mac_get_nncco_self_option(uint32_t proto, void *fc)
{
uint8_t rf_option;
#if HPLC_RF_SUPPORT
switch (proto) {
#if SUPPORT_SMART_GRID
case PLC_PROTO_TYPE_SG:
{
rf_option = (uint8_t)((frame_control_t *)fc)->vf.nn_cco.self_rf_option;
break;
}
#endif
#if SUPPORT_SOUTHERN_POWER_GRID
case PLC_PROTO_TYPE_SPG:
{
rf_option = ((spg_frame_control_t *)fc)->vf.nn_cco.self_rf_option;
break;
}
#endif
default:
rf_option = RF_OPTION_INVALID;
break;
}
#else
(void)proto;
(void)fc;
rf_option = RF_OPTION_INVALID;
#endif
return rf_option;
}
uint32_t mac_get_rx_delimiter_from_fc(uint32_t proto, void *fc)
{
uint32_t deimiter = 0xFF;
switch (proto) {
#if SUPPORT_SMART_GRID
case PLC_PROTO_TYPE_SG:
deimiter = ((frame_control_t *)fc)->delimiter_type;
break;
#endif
#if SUPPORT_SOUTHERN_POWER_GRID
case PLC_PROTO_TYPE_SPG:
deimiter = ((spg_frame_control_t *)fc)->delimiter_type;
break;
#endif
#if SUPPORT_GREEN_PHY
case PLC_PROTO_TYPE_GP:
deimiter = ((hpav_frame_control *)fc)->delimiter_type;
break;
#endif
default:
// todo
break;
}
return deimiter;
}
uint32_t mac_get_nid_from_fc(uint32_t proto, void *fc)
{
uint32_t nid = 0xFFFFFFFF;
switch (proto) {
#if SUPPORT_SMART_GRID
case PLC_PROTO_TYPE_SG:
nid = ((frame_control_t *)fc)->nid;
break;
#endif
#if SUPPORT_SOUTHERN_POWER_GRID
case PLC_PROTO_TYPE_SPG:
nid = ((spg_frame_control_t *)fc)->snid;
break;
#endif
#if SUPPORT_GREEN_PHY
case PLC_PROTO_TYPE_GP:
nid = ((hpav_frame_control *)fc)->snid;
break;
#endif
default:
// todo
break;
}
return nid;
}
void IRAM_ATTR mac_get_rx_frm_msg_from_fc(uint32_t proto,
void *fc, rx_fc_msg_t *msg)
{
uint8_t delimiter = (uint8_t)mac_get_delimi_from_fc(proto, fc);
switch (proto) {
#if SUPPORT_SMART_GRID
case PLC_PROTO_TYPE_SG:
{
/* nid share the same place for SG */
frame_control_t *sg_fc = (frame_control_t *)fc;
msg->nid = sg_fc->nid;
msg->delimiter = delimiter;
switch (delimiter) {
case FC_DELIM_BEACON:
{
msg->tmi = sg_fc->vf.bcn.tmi;
msg->fccs = sg_fc->vf.bcn.fccs;
msg->src_tei = sg_fc->vf.bcn.src_tei;
msg->time_stamp = sg_fc->vf.bcn.time_stamp;
msg->phase = sg_fc->vf.bcn.phase_num;
msg->pb_num = 1;
msg->rf_mcs = (uint8_t)sg_fc->vf.rf_bcn.mcs;
msg->rf_pb_sz_idx = (uint8_t)sg_fc->vf.rf_bcn.pb_sz_idx;
msg->numsym = sg_fc->vf.bcn.sym_num;
break;
}
case FC_DELIM_SOF:
{
msg->bcast = sg_fc->vf.sof.bcast;
msg->src_tei = sg_fc->vf.sof.src_tei;
msg->dst_tei = sg_fc->vf.sof.dst_tei;
msg->tmi = sg_fc->vf.sof.tmi;
msg->lid = sg_fc->vf.sof.lid;
msg->retry = sg_fc->vf.sof.retry;
msg->tmi_ext = sg_fc->vf.sof.tmi_ext;
msg->fccs = sg_fc->vf.sof.fccs;
msg->pb_num = (uint8_t)sg_fc->vf.sof.pb_num;
msg->rf_mcs = (uint8_t)sg_fc->vf.rf_sof.mcs;
msg->rf_pb_sz_idx = (uint8_t)sg_fc->vf.rf_sof.pb_sz_idx;
msg->numsym = sg_fc->vf.sof.sym_num;
break;
}
case FC_DELIM_NNCCO:
{
msg->pb_num = 0;
msg->fccs = sg_fc->vf.nn_cco.fccs;
break;
}
case FC_DELIM_SACK:
{
msg->dst_tei = sg_fc->vf.sack.dtei;
msg->src_tei = sg_fc->vf.sack.stei;
msg->snr_in_sack = (int8_t)sg_fc->vf.sack.snr;
msg->bitmap_in_sack = sg_fc->vf.sack.rx_status;
msg->load_in_sack = sg_fc->vf.sack.load;
msg->result_in_sack = sg_fc->vf.sack.rx_result;
msg->pb_num = (uint8_t)sg_fc->vf.sack.rx_pb;
msg->sack_ext_deli = sg_fc->vf.sack.ext_deli;
msg->time_stamp = sg_fc->vf.sync.time_stamp;
msg->fccs = sg_fc->vf.sack.fccs;
break;
}
case I1901_RTS_CTS:
{
i1901_frame_control_t *i1901_fc = (i1901_frame_control_t *)fc;
msg->pb_num = 0;
msg->dst_tei = i1901_fc->vf.rts_cts.dtei;
msg->src_tei = i1901_fc->vf.rts_cts.stei;
msg->rtsf = i1901_fc->vf.rts_cts.rtsf;
break;
}
default:
break;
}
break;
}
#endif
#if SUPPORT_GREEN_PHY
case PLC_PROTO_TYPE_GP:
{
hpav_frame_control *gp_fc = (hpav_frame_control *)fc;
msg->nid = gp_fc->snid;
switch (delimiter) {
case DT_AV_BEACON:
{
msg->time_stamp = gp_fc->vf_av.bcn.bts;
/* bcn pb size of GP has fixed 136 bytes */
msg->tmi = 2;
break;
}
case DT_AV_SOF:
{
msg->src_tei = gp_fc->vf_av.sof.src_tei;
msg->dst_tei = gp_fc->vf_av.sof.dst_tei;
msg->tmi = gp_fc->vf_av.sof.tmi_av;
msg->lid = gp_fc->vf_av.sof.lid;
msg->fccs = gp_fc->fccs_av.fccs_av0;
msg->fccs |= gp_fc->fccs_av.fccs_av1 << 8;
msg->fccs |= gp_fc->fccs_av.fccs_av2 << 16;
msg->numsym = gp_fc->vf_av.sof.numsym;
break;
}
case DT_AV_SACK:
{
break;
}
case DT_AV_RTS_CTS:
{
msg->src_tei = gp_fc->vf_av.rtscts.src_tei;
msg->dst_tei = gp_fc->vf_av.rtscts.dst_tei;
msg->lid = gp_fc->vf_av.rtscts.lid;
msg->rtsf = gp_fc->vf_av.rtscts.rtsf;
break;
}
case DT_AV_SOUND:
{
msg->src_tei = gp_fc->vf_av.sound.stei;
msg->dst_tei = gp_fc->vf_av.sound.dtei;
msg->lid = gp_fc->vf_av.sound.lid;
msg->saf = gp_fc->vf_av.sound.saf;
break;
}
case DT_AV_RSOF:
{
break;
}
default:
break;
}
break;
}
#endif
#if SUPPORT_GREEN_PHY //Av SUPPORT_GREEN_PHY
case PLC_PROTO_TYPE_AV:
{
// TO BE DONE
break;
}
#endif
#if SUPPORT_SOUTHERN_POWER_GRID
case PLC_PROTO_TYPE_SPG:
{
spg_frame_control_t *spg_fc = (spg_frame_control_t *)fc;
msg->nid = spg_fc->snid;
msg->delimiter = delimiter;
switch (delimiter) {
case FC_DELIM_BEACON:
{
uint8_t *fccs = spg_fc->vf.bcn.fccs;
msg->tmi = spg_fc->vf.bcn.tmi;
msg->fccs = fccs[0];
msg->fccs |= fccs[1] << 8;
msg->fccs |= fccs[2] << 16;
msg->time_stamp = spg_fc->vf.bcn.time_stamp;
msg->src_tei = spg_fc->vf.bcn.src_tei;
msg->phase = spg_fc->vf.bcn.phase_num;
msg->numsym = spg_fc->vf.bcn.sym_num;
break;
}
case FC_DELIM_SOF:
{
msg->src_tei = spg_fc->vf.sof.src_tei;
msg->dst_tei = spg_fc->vf.sof.dst_tei;
msg->tmi = spg_fc->vf.sof.tmi;
msg->lid = spg_fc->vf.sof.lid;
msg->retry = spg_fc->vf.sof.retry;
msg->tmi_ext = spg_fc->vf.sof.tmi_ext;
msg->fccs = spg_fc->vf.sof.fccs;
msg->pb_num = (uint8_t)spg_fc->vf.sof.pb_num;
msg->numsym = spg_fc->vf.sof.sym_num;
break;
}
case FC_DELIM_SACK:
{
msg->dst_tei = spg_fc->vf.sack.dtei;
msg->bitmap_in_sack = spg_fc->vf.sack.rx_status;
msg->result_in_sack = spg_fc->vf.sack.rx_result;
msg->pb_num = (uint8_t)spg_fc->vf.sack.rx_pb;
msg->sack_ext_deli = spg_fc->vf.sack.ext_deli;
msg->time_stamp = spg_fc->vf.sync.time_stamp;
msg->fccs = spg_fc->vf.sack.fccs;
break;
}
case FC_DELIM_NNCCO:
{
msg->fccs = spg_fc->vf.nn_cco.fccs;
break;
}
case FC_DELIM_SOUND:
{
break;
}
default:
break;
}
break;
}
#endif
default:
break;
}
return;
}
void mac_rf_get_rx_frm_msg_from_fc(uint32_t proto,
void *fc, rx_fc_msg_t *msg)
{
uint8_t delimiter = (uint8_t)mac_get_delimi_from_fc(proto, fc);
msg->delimiter = delimiter;
switch (proto) {
#if SUPPORT_SMART_GRID
case PLC_PROTO_TYPE_SG:
{
/* nid share the same place for SG */
frame_control_t *sg_fc = (frame_control_t *)fc;
msg->nid = sg_fc->nid;
switch (delimiter) {
case FC_DELIM_BEACON:
{
msg->time_stamp = sg_fc->vf.rf_bcn.time_stamp;
msg->src_tei = sg_fc->vf.rf_bcn.src_tei;
msg->rf_mcs = (uint8_t)sg_fc->vf.rf_bcn.mcs;
msg->rf_pb_sz_idx = (uint8_t)sg_fc->vf.rf_bcn.pb_sz_idx;
msg->pb_num = 1;
msg->fccs = sg_fc->vf.rf_bcn.fccs;
break;
}
case FC_DELIM_SOF:
{
msg->src_tei = sg_fc->vf.rf_sof.src_tei;
msg->dst_tei = sg_fc->vf.rf_sof.dst_tei;
msg->lid = sg_fc->vf.rf_sof.lid;
msg->rf_pb_sz_idx = (uint8_t)sg_fc->vf.rf_sof.pb_sz_idx;
msg->bcast = sg_fc->vf.rf_sof.bcast;
msg->retry = sg_fc->vf.rf_sof.retry;
msg->rf_mcs = (uint8_t)sg_fc->vf.rf_sof.mcs;
msg->pb_num = 1;
msg->fccs = sg_fc->vf.rf_sof.fccs;
break;
}
case FC_DELIM_SACK:
{
msg->result_in_sack = sg_fc->vf.rf_sack.rx_result;
msg->src_tei = sg_fc->vf.rf_sack.stei;
msg->dst_tei = sg_fc->vf.rf_sack.dtei;
msg->snr_in_sack = (int8_t)sg_fc->vf.rf_sack.snr;
msg->load_in_sack = sg_fc->vf.rf_sack.load;
msg->sack_ext_deli = sg_fc->vf.rf_sack.ext_deli;
msg->fccs = sg_fc->vf.rf_sack.fccs;
break;
}
default:
break;
}
break;
}
#endif
#if SUPPORT_SOUTHERN_POWER_GRID
case PLC_PROTO_TYPE_SPG:
{
spg_frame_control_t *spg_fc = (spg_frame_control_t *)fc;
msg->nid = spg_fc->snid;
switch (delimiter) {
case FC_DELIM_BEACON:
{
msg->time_stamp = spg_fc->vf.rf_bcn.time_stamp;
msg->src_tei = spg_fc->vf.rf_bcn.src_tei;
msg->rf_mcs = (uint8_t)spg_fc->vf.rf_bcn.mcs;
msg->rf_pb_sz_idx = (uint8_t)spg_fc->vf.rf_bcn.pb_sz_idx;
msg->pb_num = 1;
msg->fccs = spg_fc->vf.rf_bcn.fccs[0];
msg->fccs |= spg_fc->vf.rf_bcn.fccs[1] << 8;
msg->fccs |= spg_fc->vf.rf_bcn.fccs[2] << 16;
break;
}
case FC_DELIM_SOF:
{
msg->src_tei = spg_fc->vf.rf_sof.src_tei;
msg->dst_tei = spg_fc->vf.rf_sof.dst_tei;
msg->lid = spg_fc->vf.rf_sof.lid;
msg->rf_pb_sz_idx = (uint8_t)spg_fc->vf.rf_sof.pb_sz_idx;
msg->retry = spg_fc->vf.rf_sof.retry;
msg->rf_mcs = (uint8_t)spg_fc->vf.rf_sof.mcs;
msg->pb_num = 1;
msg->fccs = spg_fc->vf.rf_sof.fccs;
break;
}
case FC_DELIM_SACK:
{
msg->result_in_sack = spg_fc->vf.rf_sack.rx_result;
msg->dst_tei = spg_fc->vf.rf_sack.dtei;
msg->sack_ext_deli = spg_fc->vf.rf_sack.ext_deli;
msg->fccs = spg_fc->vf.rf_sack.fccs[0];
msg->fccs |= spg_fc->vf.rf_sack.fccs[1] << 8;
msg->fccs |= spg_fc->vf.rf_sack.fccs[2] << 16;
break;
}
default:
break;
}
break;
}
#endif
default:
(void)proto;
(void)fc;
(void)msg;
break;
}
return;
}
void IRAM_ATTR mac_get_tx_msg_from_fc(uint32_t proto, uint32_t delimiter,
void *fc, tx_fc_msg_t *msg)
{
switch (proto) {
#if SUPPORT_SMART_GRID
case PLC_PROTO_TYPE_SG:
{
switch (delimiter) {
case FC_DELIM_BEACON:
{
frame_control_t *sg_fc = (frame_control_t *)fc;
msg->network_type = (uint8_t)sg_fc->network_type;
msg->nid = sg_fc->nid;
msg->tmi = (uint8_t)sg_fc->vf.bcn.tmi;
msg->src_tei = (tei_t)sg_fc->vf.bcn.src_tei;
msg->rf_mcs = (uint8_t)sg_fc->vf.rf_bcn.mcs;
msg->rf_pb_sz_idx = (uint8_t)sg_fc->vf.rf_bcn.pb_sz_idx;
break;
}
case FC_DELIM_SOF:
{
frame_control_t *sg_fc = (frame_control_t *)fc;
msg->tmi = (uint8_t)sg_fc->vf.sof.tmi;
msg->ext_tmi = (uint8_t)sg_fc->vf.sof.tmi_ext;
msg->rf_mcs = (uint8_t)sg_fc->vf.rf_sof.mcs;
msg->rf_pb_sz_idx = (uint8_t)sg_fc->vf.rf_sof.pb_sz_idx;
break;
}
case FC_DELIM_NNCCO:
{
break;
}
case FC_DELIM_SOUND:
{
break;
}
default:
break;
}
break;
}
#endif
#if SUPPORT_GREEN_PHY
case PLC_PROTO_TYPE_GP:
{
switch (delimiter) {
case DT_AV_BEACON:
{
hpav_frame_control *gp_fc = (hpav_frame_control *)fc;
(void)gp_fc;
break;
}
case DT_AV_SOF:
{
hpav_frame_control *gp_fc = (hpav_frame_control *)fc;
msg->tmi = (uint8_t)gp_fc->vf_av.sof.tmi_av;
break;
}
case DT_AV_SACK:
{
break;
}
case DT_AV_RTS_CTS:
{
break;
}
case DT_AV_SOUND:
{
break;
}
case DT_AV_RSOF:
{
break;
}
default:
break;
}
break;
}
#endif
#if SUPPORT_GREEN_PHY //Av use SUPPORT_GREEN_PHY
case PLC_PROTO_TYPE_AV:
{
// TO BE DONE
}break;
#endif
#if SUPPORT_SOUTHERN_POWER_GRID
case PLC_PROTO_TYPE_SPG:
{
switch (delimiter) {
case FC_DELIM_BEACON:
{
spg_frame_control_t *spg_fc = (spg_frame_control_t *)fc;
msg->network_type = (uint8_t)spg_fc->access_ind;
msg->nid = spg_fc->snid;
msg->tmi = (uint8_t)spg_fc->vf.bcn.tmi;
msg->src_tei = (tei_t)spg_fc->vf.bcn.src_tei;
msg->bcn_period_cnt = spg_fc->vf.bcn.bcn_period_cnt;
msg->rf_mcs = (uint8_t)spg_fc->vf.rf_bcn.mcs;
msg->rf_pb_sz_idx = (uint8_t)spg_fc->vf.rf_bcn.pb_sz_idx;
break;
}
case FC_DELIM_SOF:
{
spg_frame_control_t *spg_fc = (spg_frame_control_t *)fc;
msg->tmi = (uint8_t)spg_fc->vf.sof.tmi;
msg->ext_tmi = (uint8_t)spg_fc->vf.sof.tmi_ext;
msg->rf_mcs = (uint8_t)spg_fc->vf.rf_sof.mcs;
msg->rf_pb_sz_idx = (uint8_t)spg_fc->vf.rf_sof.pb_sz_idx;
break;
}
case FC_DELIM_NNCCO:
{
break;
}
case FC_DELIM_SOUND:
{
break;
}
default:
break;
}
break;
}
#endif
default:
break;
}
return;
}
uint32_t IRAM_ATTR mac_get_delimi_from_fc(uint32_t proto, void *fc)
{
uint32_t deimiter = 0xFF;
switch (proto) {
#if SUPPORT_SMART_GRID
case PLC_PROTO_TYPE_SG:
{
#if SUPPORT_IEEE_1901
i1901_frame_control_t *i1901_fc = (i1901_frame_control_t *)fc;
deimiter = i1901_fc->delimiter_type;
#else
frame_control_t *sg_fc = (frame_control_t *)fc;
deimiter = sg_fc->delimiter_type;
#endif
break;
}
#endif
#if SUPPORT_SOUTHERN_POWER_GRID
case PLC_PROTO_TYPE_SPG:
{
spg_frame_control_t *spg_fc = (spg_frame_control_t *)fc;
deimiter = spg_fc->delimiter_type;
break;
}
#endif
#if SUPPORT_GREEN_PHY
case PLC_PROTO_TYPE_GP:
{
hpav_frame_control *gp_fc = (hpav_frame_control *)fc;
deimiter = gp_fc->delimiter_type;
break;
}
#endif
default:
// todo
break;
}
return deimiter;
}
void mac_beacon_rx_fc_info_get(uint8_t proto, mac_rx_info_t *rx_info,
rx_fc_msg_t *msg)
{
IOT_ASSERT(msg);
switch(proto) {
#if SUPPORT_SMART_GRID
case PLC_PROTO_TYPE_SG:
{
frame_control_t *fc = (frame_control_t *)rx_info->fc;
msg->nid = fc->nid;
if (rx_info->phy.is_rf) {
msg->time_stamp = fc->vf.rf_bcn.time_stamp;
} else {
msg->time_stamp = fc->vf.bcn.time_stamp;
}
break;
}
#endif
#if SUPPORT_SOUTHERN_POWER_GRID
case PLC_PROTO_TYPE_SPG:
{
spg_frame_control_t *fc =
(spg_frame_control_t *)rx_info->fc;
msg->nid = fc->snid;
msg->time_stamp = fc->vf.bcn.time_stamp;
break;
}
#endif
default:
break;
}
}
uint8_t mac_get_mpdu_fc_len(uint32_t proto)
{
uint8_t mpdu_fc_len = 0;
switch (proto) {
#if (SUPPORT_SMART_GRID || SUPPORT_SOUTHERN_POWER_GRID || SUPPORT_GREEN_PHY)
case PLC_PROTO_TYPE_SG:
case PLC_PROTO_TYPE_SPG:
case PLC_PROTO_TYPE_GP:
mpdu_fc_len = PLC_MPDU_FC_LEN;
break;
#endif
default:
// todo
break;
}
return mpdu_fc_len;
}
uint8_t mac_get_mpdu_fccs_len(uint32_t proto)
{
uint8_t mpdu_fccs_len = 0;
switch (proto) {
#if (SUPPORT_SMART_GRID || SUPPORT_SOUTHERN_POWER_GRID || SUPPORT_GREEN_PHY)
case PLC_PROTO_TYPE_SG:
case PLC_PROTO_TYPE_SPG:
case PLC_PROTO_TYPE_GP:
mpdu_fccs_len = PLC_MPDU_FCCS_LEN;
break;
#endif
default:
// todo
break;
}
return mpdu_fccs_len;
}
uint8_t mac_get_pb_hdr_crc_len(uint32_t delimiter, uint32_t proto)
{
uint8_t pb_hdr_crc_len = 0;
switch (proto) {
#if SUPPORT_SMART_GRID
case PLC_PROTO_TYPE_SG:
switch (delimiter) {
case FC_DELIM_BEACON:
#if SUPPORT_IEEE_1901
pb_hdr_crc_len = I1901_BCN_PB_HDR_CRC_LEN;
#else
pb_hdr_crc_len = SG_BCN_PB_HDR_CRC_LEN;
#endif
break;
case FC_DELIM_SOF:
#if SUPPORT_IEEE_1901
pb_hdr_crc_len = I1901_SOF_PB_HDR_CRC_LEN;
#else
pb_hdr_crc_len = SG_SOF_PB_HDR_CRC_LEN;
#endif
break;
case FC_DELIM_NNCCO:
pb_hdr_crc_len = 0;
break;
case FC_DELIM_SOUND:
pb_hdr_crc_len = SG_SOF_PB_HDR_CRC_LEN;
break;
default:
pb_hdr_crc_len = 0;
break;
}
break;
#endif
#if SUPPORT_GREEN_PHY
case PLC_PROTO_TYPE_GP:
switch (delimiter) {
case DT_AV_BEACON:
pb_hdr_crc_len = GP_BCN_PB_HDR_CRC_LEN;
break;
case DT_AV_SOF:
pb_hdr_crc_len = GP_SOF_PB_HDR_CRC_LEN;
break;
case DT_AV_SACK:
case DT_AV_RTS_CTS:
pb_hdr_crc_len = 0;
break;
case DT_AV_SOUND:
pb_hdr_crc_len = GP_SOUND_PB_HDR_CRC_LEN;
break;
default:
pb_hdr_crc_len = 0;
break;
}
break;
#endif
#if SUPPORT_GREEN_PHY //Av SUPPORT_GREEN_PHY
case PLC_PROTO_TYPE_AV:
{
// TO BE DONE
break;
}
#endif
#if SUPPORT_SOUTHERN_POWER_GRID
case PLC_PROTO_TYPE_SPG:
{
switch (delimiter) {
case FC_DELIM_BEACON:
pb_hdr_crc_len = SPG_BCN_PB_HDR_CRC_LEN;
break;
case FC_DELIM_SOF:
pb_hdr_crc_len = SPG_SOF_PB_HDR_CRC_LEN;
break;
case FC_DELIM_NNCCO:
pb_hdr_crc_len = 0;
break;
case FC_DELIM_SOUND:
pb_hdr_crc_len = SPG_SOF_PB_HDR_CRC_LEN;
break;
default:
pb_hdr_crc_len = 0;
break;
}
break;
}
#endif
default:
break;
}
return pb_hdr_crc_len;
}
uint8_t mac_get_pb_hdr_resv_crc_len(uint32_t delimiter, uint32_t proto)
{
uint8_t pb_hdr_resv_crc_len = 0;
switch (proto) {
#if (SUPPORT_SMART_GRID || SUPPORT_GREEN_PHY)
case PLC_PROTO_TYPE_SG:
case PLC_PROTO_TYPE_GP:
case PLC_PROTO_TYPE_AV:
pb_hdr_resv_crc_len = mac_get_pb_hdr_crc_len(delimiter, proto);
break;
#endif
#if SUPPORT_SOUTHERN_POWER_GRID
case PLC_PROTO_TYPE_SPG:
switch (delimiter) {
case FC_DELIM_BEACON:
pb_hdr_resv_crc_len += SPG_BCN_PB_HDR_CRC_LEN + SPG_BCN_PB_RESV_LEN;
break;
case FC_DELIM_SOF:
pb_hdr_resv_crc_len = SPG_SOF_PB_HDR_CRC_LEN + SPG_SOF_PB_RESV_LEN;
break;
case FC_DELIM_NNCCO:
pb_hdr_resv_crc_len = 0;
break;
case FC_DELIM_SOUND:
pb_hdr_resv_crc_len = SPG_SOF_PB_HDR_CRC_LEN + SPG_SOF_PB_RESV_LEN;
break;
default:
pb_hdr_resv_crc_len = 0;
break;
}
break;
#endif
default:
break;
}
return pb_hdr_resv_crc_len;
}
uint8_t mac_get_pb_pld_crc_len(uint32_t delimiter, uint32_t proto)
{
uint8_t pb_pld_crc_len = 0;
switch (proto) {
#if SUPPORT_SMART_GRID
case PLC_PROTO_TYPE_SG:
{
switch (delimiter) {
case FC_DELIM_BEACON:
#if SUPPORT_IEEE_1901
pb_pld_crc_len = I1901_BCN_PB_PAYLOAD_CRC_LEN;
#else
pb_pld_crc_len = SG_BCN_PB_PAYLOAD_CRC_LEN;
#endif
break;
case FC_DELIM_SOF:
pb_pld_crc_len = 0;
break;
case FC_DELIM_NNCCO:
pb_pld_crc_len = 0;
break;
case FC_DELIM_SOUND:
pb_pld_crc_len = 0;
break;
default:
pb_pld_crc_len = 0;
break;
}
break;
}
#endif
#if SUPPORT_GREEN_PHY
case PLC_PROTO_TYPE_GP:
{
switch (delimiter) {
case DT_AV_BEACON:
pb_pld_crc_len = 0;
break;
case DT_AV_SOF:
pb_pld_crc_len = 0;
break;
case DT_AV_SACK:
pb_pld_crc_len = 0;
break;
case DT_AV_RTS_CTS:
pb_pld_crc_len = 0;
break;
case DT_AV_SOUND:
pb_pld_crc_len = 0;
break;
default:
pb_pld_crc_len = 0;
break;
}
break;
}
#endif
#if SUPPORT_GREEN_PHY //Av SUPPORT_GREEN_PHY
case PLC_PROTO_TYPE_AV:
{
// TO BE DONE
break;
}
#endif
#if SUPPORT_SOUTHERN_POWER_GRID
case PLC_PROTO_TYPE_SPG:
{
switch (delimiter) {
case FC_DELIM_BEACON:
pb_pld_crc_len = SPG_BCN_PB_PAYLOAD_CRC_LEN;
break;
case FC_DELIM_SOF:
pb_pld_crc_len = 0;
break;
case FC_DELIM_NNCCO:
pb_pld_crc_len = 0;
break;
case FC_DELIM_SOUND:
pb_pld_crc_len = 0;
break;
default:
pb_pld_crc_len = 0;
break;
}
break;
}
#endif
default:
break;
}
return pb_pld_crc_len;
}
uint8_t mac_get_pb_crc_len(uint32_t delimiter, uint32_t proto)
{
uint8_t pb_pb_crc_len = 0;
switch (proto) {
#if SUPPORT_SMART_GRID
case PLC_PROTO_TYPE_SG:
{
switch (delimiter) {
case FC_DELIM_BEACON:
#if SUPPORT_IEEE_1901
pb_pb_crc_len = I1901_BCN_PB_CRC_LEN;
#else
pb_pb_crc_len = SG_BCN_PB_CRC_LEN;
#endif
break;
case FC_DELIM_SOF:
#if SUPPORT_IEEE_1901
pb_pb_crc_len = I1901_SOF_PB_CRC_LEN;
#else
pb_pb_crc_len = SG_SOF_PB_CRC_LEN;
#endif
break;
case FC_DELIM_NNCCO:
pb_pb_crc_len = 0;
break;
case FC_DELIM_SOUND:
pb_pb_crc_len = SG_SOF_PB_CRC_LEN;
break;
default:
pb_pb_crc_len = 0;
break;
}
break;
}
#endif
#if SUPPORT_GREEN_PHY
case PLC_PROTO_TYPE_GP:
{
switch (delimiter) {
case DT_AV_BEACON:
pb_pb_crc_len = GP_BCN_PB_CRC_LEN;
break;
case DT_AV_SOF:
pb_pb_crc_len = GP_SOF_PB_CRC_LEN;
break;
case DT_AV_SACK:
case DT_AV_RTS_CTS:
pb_pb_crc_len = 0;
break;
case DT_AV_SOUND:
pb_pb_crc_len = GP_SOUND_PB_CRC_LEN;
break;
default:
pb_pb_crc_len = 0;
break;
}
break;
}
#endif
#if SUPPORT_GREEN_PHY //Av use macor of SUPPORT_GREEN_PHY
case PLC_PROTO_TYPE_AV:
{
// TO BE DONE
break;
}
#endif
#if SUPPORT_SOUTHERN_POWER_GRID
case PLC_PROTO_TYPE_SPG:
{
switch (delimiter) {
case FC_DELIM_BEACON:
pb_pb_crc_len = SPG_BCN_PB_CRC_LEN;
break;
case FC_DELIM_SOF:
pb_pb_crc_len = SPG_SOF_PB_CRC_LEN;
break;
case FC_DELIM_NNCCO:
pb_pb_crc_len = 0;
break;
case FC_DELIM_SOUND:
pb_pb_crc_len = SPG_SOF_PB_CRC_LEN;
break;
default:
pb_pb_crc_len = 0;
break;
}
break;
}
#endif
default:
break;
}
return pb_pb_crc_len;
}
uint8_t mac_get_pb_hdr_len(uint32_t delimiter, uint32_t proto)
{
uint8_t pb_hdr_len = 0;
switch (proto) {
#if SUPPORT_SMART_GRID
case PLC_PROTO_TYPE_SG:
{
switch (delimiter) {
case FC_DELIM_BEACON:
pb_hdr_len = 0;
break;
case FC_DELIM_SOF:
#if SUPPORT_IEEE_1901
pb_hdr_len = I1901_SOF_PB_HDR_LEN;
#else
pb_hdr_len = SG_SOF_PB_HDR_LEN;
#endif
break;
default:
pb_hdr_len = 0;
break;
}
break;
}
#endif
#if SUPPORT_GREEN_PHY
case PLC_PROTO_TYPE_GP:
{
switch (delimiter) {
case DT_AV_BEACON:
pb_hdr_len = 0;
break;
case DT_AV_SOF:
pb_hdr_len = GP_SOF_PB_HDR_LEN;
break;
case DT_AV_SACK:
case DT_AV_RTS_CTS:
pb_hdr_len = 0;
break;
case DT_AV_SOUND:
pb_hdr_len = 0;
break;
default:
break;
}
break;
}
#endif
#if SUPPORT_GREEN_PHY //Av use macor of SUPPORT_GREEN_PHY
case PLC_PROTO_TYPE_AV:
{
// TO BE DONE
break;
}
#endif
#if SUPPORT_SOUTHERN_POWER_GRID
case PLC_PROTO_TYPE_SPG:
{
switch (delimiter) {
case FC_DELIM_BEACON:
pb_hdr_len = 0;
break;
case FC_DELIM_SOF:
pb_hdr_len = SPG_SOF_PB_HDR_LEN;
break;
default:
pb_hdr_len = 0;
break;
}
break;
}
#endif
default:
break;
}
return pb_hdr_len;
}
uint32_t mac_get_sof_pb_valid_payload_sz(uint32_t proto, uint32_t pb_size)
{
switch (proto) {
#if SUPPORT_SMART_GRID
case PLC_PROTO_TYPE_SG:
#if SUPPORT_IEEE_1901
if (!((72 == pb_size) || (136 == pb_size) || (520 == pb_size))) {
/* invalid pb size */
return 0;
}
#else /* SUPPORT_IEEE_1901 */
if (!((72 == pb_size) || (136 == pb_size)
|| (264 == pb_size) || (520 == pb_size))) {
/* invalid pb size */
return 0;
}
#endif /* SUPPORT_IEEE_1901 */
break;
#endif /* SUPPORT_SMART_GRID */
#if SUPPORT_SOUTHERN_POWER_GRID
case PLC_PROTO_TYPE_SPG:
if (!((136 == pb_size) || (520 == pb_size))) {
/* invalid pb size */
return 0;
}
break;
#endif /* SUPPORT_SOUTHERN_POWER_GRID */
default:
return 0;
}
return (uint32_t)(pb_size - mac_get_pb_hdr_resv_crc_len(FC_DELIM_SOF,
proto));
}
void IRAM_ATTR mac_get_nncco_info_from_fc(void *fc, nncco_fc_info_t *nn_fc_info)
{
IOT_ASSERT(fc);
uint32_t proto = PHY_PROTO_TYPE_GET();
uint8_t delimiter = (uint8_t)mac_get_delimi_from_fc(proto, fc);
switch (proto) {
#if SUPPORT_SMART_GRID
case PLC_PROTO_TYPE_SG:
{
/* nid share the same place for SG */
frame_control_t *sg_fc = (frame_control_t *)fc;
nn_fc_info->nid = sg_fc->nid;
nn_fc_info->delimiter = delimiter;
switch (delimiter) {
case FC_DELIM_NNCCO:
{
nn_fc_info->receive_nid = sg_fc->vf.nn_cco.receive_nid;
nn_fc_info->duration = sg_fc->vf.nn_cco.duration;
nn_fc_info->sbandoffset = sg_fc->vf.nn_cco.sbandoffset;
nn_fc_info->self_rf_channel =
(uint8_t)sg_fc->vf.nn_cco.self_rf_channel;
nn_fc_info->self_rf_option =
(uint8_t)sg_fc->vf.nn_cco.self_rf_option;
break;
}
default:
IOT_ASSERT(0);
break;
}
break;
}
#endif
#if SUPPORT_SOUTHERN_POWER_GRID
case PLC_PROTO_TYPE_SPG:
{
spg_frame_control_t *spg_fc = (spg_frame_control_t *)fc;
nn_fc_info->nid = spg_fc->snid;
nn_fc_info->delimiter = delimiter;
switch (delimiter) {
case FC_DELIM_NNCCO:
{
/* nncco info */
nn_fc_info->receive_nid = spg_fc->vf.nn_cco.neighbor_network;
nn_fc_info->duration = spg_fc->vf.nn_cco.conti_time;
nn_fc_info->bwth_end_flag = spg_fc->vf.nn_cco.bwth_end_flag;
nn_fc_info->bwth_end_shift = spg_fc->vf.nn_cco.bwth_end_shift;
nn_fc_info->sbandoffset = spg_fc->vf.nn_cco.bwth_start_shift;
nn_fc_info->self_rf_channel =
spg_fc->vf.nn_cco.self_rf_channel;
nn_fc_info->self_rf_option =
spg_fc->vf.nn_cco.self_rf_option;
break;
}
default:
IOT_ASSERT(0);
break;
}
break;
}
#endif
default:
break;
}
(void)proto;
(void)delimiter;
return;
}
/* judge receive nid whether is mynid */
uint32_t mac_nncco_nid_compare(uint32_t nid_in_nncco, uint32_t nid_to_check)
{
uint32_t proto = PHY_PROTO_TYPE_GET();
if (PLC_PROTO_TYPE_SG == proto) {
if (nid_in_nncco == nid_to_check) {
return 1;
}
}
else if (PLC_PROTO_TYPE_SPG == proto) {
if (nid_in_nncco & (1 << (nid_to_check - 1))) {
return 1;
}
}
return 0;
}
uint32_t mac_debug_nncco_info(void *fc, uint32_t ntb)
{
uint32_t proto = PHY_PROTO_TYPE_GET();
#if HW_PLATFORM == HW_PLATFORM_SIMU
nncco_fc_info_t nn_fc_info = { 0 };
mac_get_nncco_sw_info_from_fc(fc, &nn_fc_info);
if (PLC_PROTO_TYPE_SG == proto) {
iot_printf("%s proto:%d, nid %lu dur %lu start_ntb %lu, nn nid %lu, "
"local ntb %lu\n", __FUNCTION__, proto, nn_fc_info.nid,
(uint32_t)nn_fc_info.sw_duration,
nn_fc_info.start_ntb_l32,
(uint32_t)nn_fc_info.sw_receive_nid, ntb);
}
else if (PLC_PROTO_TYPE_SPG == proto) {
iot_printf("%s proto:%d, nid %lu, dur:%lu, start_ntb:%lu, "
"last_ntb_offset:%lu, rece nid %lu, local ntb %lu\n",
__FUNCTION__, proto, nn_fc_info.nid,
(uint32_t)nn_fc_info.sw_duration,
nn_fc_info.start_ntb_l32,
nn_fc_info.last_offset,
(uint32_t)nn_fc_info.sw_receive_nid, ntb);
}
#else /* HW_PLATFORM == HW_PLATFORM_SIMU */
nncco_fc_info_t nn_fc_info = { 0 };
mac_get_nncco_info_from_fc(fc, &nn_fc_info);
#if SUPPORT_SMART_GRID
if (PLC_PROTO_TYPE_SG == proto) {
iot_printf("nncco p:%d, n:%lu, d:%lu, ef:%d, es:%d,"
" so:%lu, nbm:%lu, ln:%lu\n",
proto, nn_fc_info.nid,
nn_fc_info.duration,
nn_fc_info.sbandoffset,
nn_fc_info.receive_nid, ntb);
}
#endif
#if SUPPORT_SOUTHERN_POWER_GRID
if (PLC_PROTO_TYPE_SPG == proto) {
iot_printf("nncco p:%d, n:%lu, d40:%lu, ef:%d, lo4:%lu, "
"nsto4:%lu, nbm:%lu, ln %lu\n",
proto, nn_fc_info.nid,
nn_fc_info.duration,
nn_fc_info.bwth_end_flag,
nn_fc_info.bwth_end_shift,
nn_fc_info.sbandoffset,
nn_fc_info.receive_nid, ntb);
}
#endif
#endif /* HW_PLATFORM == HW_PLATFORM_SIMU */
(void)proto;
return 0;
}
void IRAM_ATTR mac_set_bcn_st(void *fc, uint32_t ntb)
{
#if HW_PLATFORM != HW_PLATFORM_SIMU
IOT_ASSERT(fc);
uint32_t proto = PHY_PROTO_TYPE_GET();
#if SUPPORT_SMART_GRID
frame_control_t *cur_fc_sg;
if (PLC_PROTO_TYPE_SG == proto) {
cur_fc_sg = (frame_control_t *)fc;
cur_fc_sg->vf.bcn.time_stamp = ntb;
}
#endif
#if SUPPORT_SOUTHERN_POWER_GRID
spg_frame_control_t *cur_fc_spg;
if (PLC_PROTO_TYPE_SPG == proto) {
cur_fc_spg = (spg_frame_control_t *)fc;
cur_fc_spg->vf.bcn.time_stamp = ntb;
}
#endif
(void)proto;
#else
(void)fc;
(void)ntb;
#endif
return;
}
void IRAM_ATTR mac_set_sync_st(void *fc, uint32_t ntb)
{
#if HW_PLATFORM != HW_PLATFORM_SIMU
IOT_ASSERT(fc);
uint32_t proto = PHY_PROTO_TYPE_GET();
#if SUPPORT_SMART_GRID
if (PLC_PROTO_TYPE_SG == proto) {
frame_control_t *cur_fc_sg = (frame_control_t *)fc;
if (cur_fc_sg->vf.sync.ext_type == SACK_EXT_TYPE_SYNC) {
cur_fc_sg->vf.sync.time_stamp = ntb;
}
}
#endif
#if SUPPORT_SOUTHERN_POWER_GRID
if (PLC_PROTO_TYPE_SPG == proto) {
spg_frame_control_t *cur_fc_spg = (spg_frame_control_t *)fc;
if (cur_fc_spg->vf.sync.ext_type == SACK_EXT_TYPE_SYNC) {
cur_fc_spg->vf.sync.time_stamp = ntb;
}
}
#endif
#else
(void)fc;
(void)ntb;
#endif
return;
}
uint32_t mac_get_sof_frame_len(uint32_t proto, void *fc)
{
(void)fc;
switch(proto)
{
#if SUPPORT_SMART_GRID
case PLC_PROTO_TYPE_SG:
{
frame_control_t *sg_fc = fc;
return sg_fc->vf.sof.frame_len;
}
#endif
#if SUPPORT_SOUTHERN_POWER_GRID
case PLC_PROTO_TYPE_SPG:
{
spg_frame_control_t *spg_fc = fc;
return spg_fc->vf.sof.frm_len;
}
#endif
#if SUPPORT_GREEN_PHY
case PLC_PROTO_TYPE_AV:
case PLC_PROTO_TYPE_GP:
{
hpav_frame_control *av_fc = fc;
return av_fc->vf_av.sof.fl_av;
}
#endif
default:
IOT_ASSERT(0);
return ERR_FAIL;
}
}
uint32_t mac_get_sof_pbnum(uint32_t proto, void *fc)
{
(void)fc;
switch(proto)
{
#if SUPPORT_SMART_GRID
case PLC_PROTO_TYPE_SG:
{
frame_control_t *sg_fc = fc;
return sg_fc->vf.sof.pb_num;
}
#endif
#if SUPPORT_SOUTHERN_POWER_GRID
case PLC_PROTO_TYPE_SPG:
{
spg_frame_control_t *spg_fc = fc;
return spg_fc->vf.sof.pb_num;
}
#endif
default:
IOT_ASSERT(0);
return ERR_FAIL;
}
}
uint32_t mac_mask_input_nid(uint32_t nid)
{
/* TODO: sometimes, cvg not clear the higher part of nid
* so we need to clean the higher part, remove the
* following if cvg clean the higher part
*/
uint32_t proto = PHY_PROTO_TYPE_GET();
if (proto == PLC_PROTO_TYPE_SG) {
/* 24 bit for SG */
nid &= 0xffffff;
}
else if (proto == PLC_PROTO_TYPE_SPG) {
/* 4 bit for SPG */
nid &= 0xf;
}
else {
IOT_ASSERT(0);
}
return nid;
}
uint32_t mac_get_bcn_st(uint32_t proto, void *fc)
{
uint32_t st = 0x0;
switch (proto) {
#if SUPPORT_SMART_GRID
case PLC_PROTO_TYPE_SG:
st = ((frame_control_t *)fc)->vf.bcn.time_stamp;
break;
#endif
#if SUPPORT_SOUTHERN_POWER_GRID
case PLC_PROTO_TYPE_SPG:
st = ((spg_frame_control_t *)fc)->vf.bcn.time_stamp;
break;
#endif
#if SUPPORT_GREEN_PHY
case PLC_PROTO_TYPE_GP:
st = ((hpav_frame_control *)fc)->vf_av.bcn.bts;
break;
#endif
default:
// todo
break;
}
return st;
}
uint32_t mac_get_fc_dtei(uint32_t proto, void *fc)
{
(void)fc;
switch(proto)
{
#if SUPPORT_SMART_GRID
case PLC_PROTO_TYPE_SG:
{
frame_control_t *sg_fc = fc;
return sg_fc->vf.sof.dst_tei;
}
#endif
#if SUPPORT_SOUTHERN_POWER_GRID
case PLC_PROTO_TYPE_SPG:
{
spg_frame_control_t *spg_fc = fc;
return spg_fc->vf.sof.dst_tei;
}
#endif
default:
IOT_ASSERT(0);
return ERR_FAIL;
}
}
uint32_t mac_get_unicast_sack_ts(void)
{
#if ENA_WAR_244
return g_phy_cpu_share_ctxt.tx_unicast_sack_ts;
#else
//TODO: add get sack ts code
return 0;
#endif
}
void mac_fc_i1901_to_sg(uint32_t proto, void *fc)
{
#if (SUPPORT_SMART_GRID && SUPPORT_IEEE_1901)
uint32_t tmi, tmi_ext;
i1901_frame_control_t *fc_1901 = (i1901_frame_control_t *)fc;
frame_control_t sg_fc = {0};
if (PLC_PROTO_TYPE_SG != proto) {
iot_printf("1901 to sg proto error %d\n", proto);
return;
}
sg_fc.delimiter_type = fc_1901->delimiter_type;
sg_fc.network_type = fc_1901->network_type;
sg_fc.nid = fc_1901->nid;
switch (fc_1901->delimiter_type) {
case FC_DELIM_BEACON:
phy_tmi_i1901_to_sg(fc_1901->vf.bcn.tmi, !I1901_IS_EXT_TMI_MODE,
&tmi, &tmi_ext);
sg_fc.vf.bcn.time_stamp = fc_1901->vf.bcn.time_stamp;
sg_fc.vf.bcn.src_tei = fc_1901->vf.bcn.stei;
sg_fc.vf.bcn.tmi = (uint16_t)tmi;
sg_fc.vf.bcn.sym_num = fc_1901->vf.bcn.pss;
sg_fc.vf.bcn.phase_num = fc_1901->vf.bcn.phase_num;
sg_fc.vf.bcn.version = fc_1901->vf.bcn.version;
sg_fc.vf.bcn.fccs = fc_1901->vf.bcn.fccs;
break;
case FC_DELIM_SOF:
phy_tmi_i1901_to_sg(fc_1901->vf.sof.tmi, fc_1901->vf.sof.tmi_ext,
&tmi, &tmi_ext);
sg_fc.vf.sof.src_tei = fc_1901->vf.sof.stei;
sg_fc.vf.sof.dst_tei = fc_1901->vf.sof.dtei;
sg_fc.vf.sof.lid = fc_1901->vf.sof.lid;
sg_fc.vf.sof.frame_len = fc_1901->vf.sof.frame_len;
sg_fc.vf.sof.pb_num = fc_1901->vf.sof.pb_num;
sg_fc.vf.sof.sym_num = fc_1901->vf.sof.pss;
sg_fc.vf.sof.bcast = fc_1901->vf.sof.bcast;
sg_fc.vf.sof.retry = fc_1901->vf.sof.retry;
/* ieee1901: 0x00 cco managed NEKS, 0x03 MPDU unencryed */
sg_fc.vf.sof.encry = !fc_1901->vf.sof.encry;
sg_fc.vf.sof.tmi = (uint16_t)tmi;
sg_fc.vf.sof.tmi_ext = tmi_ext;
sg_fc.vf.sof.version = fc_1901->vf.sof.version;
sg_fc.vf.sof.fccs = fc_1901->vf.sof.fccs;
break;
case FC_DELIM_SACK:
if (fc_1901->vf.sack.rx_pb) {
sg_fc.vf.sack.rx_result = !(((1 << fc_1901->vf.sack.rx_pb) - 1)
& fc_1901->vf.sack.result);
}
sg_fc.vf.sack.rx_status = fc_1901->vf.sack.result;
sg_fc.vf.sack.stei = fc_1901->vf.sack.stei;
sg_fc.vf.sack.dtei = fc_1901->vf.sack.dtei;
sg_fc.vf.sack.rx_pb = fc_1901->vf.sack.rx_pb;
sg_fc.vf.sack.snr = fc_1901->vf.sack.snr;
sg_fc.vf.sack.load = fc_1901->vf.sack.load;
sg_fc.vf.sack.ext_deli = fc_1901->vf.sack.ext_deli;
sg_fc.vf.sack.version = fc_1901->vf.sack.version;
sg_fc.vf.sack.fccs = fc_1901->vf.sack.fccs;
break;
case FC_DELIM_NNCCO:
#if (HW_PLATFORM >= HW_PLATFORM_FPGA)
/* sg unit: 1ms, ieee1901 unit: 40ms */
sg_fc.vf.nn_cco.duration = fc_1901->vf.nn_cco.duration * 40;
/* sg and ieee1901 unit: 1ms */
sg_fc.vf.nn_cco.sbandoffset = fc_1901->vf.nn_cco.sbandoffset;
sg_fc.vf.nn_cco.receive_nid = fc_1901->vf.nn_cco.receive_nid;
sg_fc.vf.nn_cco.self_rf_channel = RF_CHANNEL_ID_INVALID;
sg_fc.vf.nn_cco.self_rf_option = RF_OPTION_INVALID;
sg_fc.vf.nn_cco.version = fc_1901->vf.nn_cco.version;
sg_fc.vf.nn_cco.fccs = fc_1901->vf.nn_cco.fccs;
break;
#else
return;
#endif
case I1901_RTS_CTS:
default:
return;
}
os_mem_cpy(fc_1901, &sg_fc, sizeof(sg_fc));
#else
(void)proto;
(void)fc;
#endif
}
void mac_fc_sg_to_i1901(uint32_t proto, void *fc)
{
#if (SUPPORT_SMART_GRID && SUPPORT_IEEE_1901)
uint32_t tmi, tmi_ext;
frame_control_t *sg_fc = (frame_control_t *)fc;
i1901_frame_control_t fc_1901 = {0};
if (PLC_PROTO_TYPE_SG != proto) {
iot_printf("sg to 1901 proto error %d\n", proto);
return;
}
fc_1901.delimiter_type = sg_fc->delimiter_type;
fc_1901.network_type = sg_fc->network_type;
fc_1901.nid = sg_fc->nid;
switch (sg_fc->delimiter_type) {
case FC_DELIM_BEACON:
phy_tmi_sg_to_i1901(sg_fc->vf.bcn.tmi, !I1901_IS_EXT_TMI_MODE,
&tmi, &tmi_ext);
fc_1901.vf.bcn.time_stamp = sg_fc->vf.bcn.time_stamp;
fc_1901.vf.bcn.stei = sg_fc->vf.bcn.src_tei;
fc_1901.vf.bcn.tmi = (uint16_t)tmi;
fc_1901.vf.bcn.pss = (uint16_t)phy_get_pss_id(proto, tmi, tmi_ext);
fc_1901.vf.bcn.phase_num = sg_fc->vf.bcn.phase_num;
fc_1901.vf.bcn.version = sg_fc->vf.bcn.version;
fc_1901.vf.bcn.fccs = sg_fc->vf.bcn.fccs;
break;
case FC_DELIM_SOF:
phy_tmi_sg_to_i1901(sg_fc->vf.sof.tmi, sg_fc->vf.sof.tmi_ext,
&tmi, &tmi_ext);
fc_1901.vf.sof.stei = sg_fc->vf.sof.src_tei;
fc_1901.vf.sof.dtei = sg_fc->vf.sof.dst_tei;
fc_1901.vf.sof.lid = sg_fc->vf.sof.lid;
fc_1901.vf.sof.frame_len = sg_fc->vf.sof.frame_len;
fc_1901.vf.sof.pb_num = sg_fc->vf.sof.pb_num;
fc_1901.vf.sof.pss = (uint16_t)phy_get_pss_id(proto, tmi, tmi_ext);
fc_1901.vf.sof.bcast = sg_fc->vf.sof.bcast;
fc_1901.vf.sof.retry = sg_fc->vf.sof.retry;
/* ieee1901: 0x00 cco managed NEKS, 0x03 MPDU unencryed */
fc_1901.vf.sof.encry = sg_fc->vf.sof.encry ? 0x00 : 0x03;
fc_1901.vf.sof.tmi = (uint16_t)tmi;
fc_1901.vf.sof.tmi_ext = (uint16_t)tmi_ext;
fc_1901.vf.sof.version = sg_fc->vf.sof.version;
fc_1901.vf.sof.fccs = sg_fc->vf.sof.fccs;
break;
case FC_DELIM_SACK:
fc_1901.vf.sack.result = sg_fc->vf.sack.rx_status;
fc_1901.vf.sack.stei = sg_fc->vf.sack.stei;
fc_1901.vf.sack.dtei = sg_fc->vf.sack.dtei;
fc_1901.vf.sack.rx_pb = sg_fc->vf.sack.rx_pb;
fc_1901.vf.sack.snr = sg_fc->vf.sack.snr;
fc_1901.vf.sack.load = sg_fc->vf.sack.load;
fc_1901.vf.sack.ext_deli = sg_fc->vf.sack.ext_deli;
fc_1901.vf.sack.version = sg_fc->vf.sack.version;
fc_1901.vf.sack.fccs = sg_fc->vf.sack.fccs;
break;
case FC_DELIM_NNCCO:
#if (HW_PLATFORM >= HW_PLATFORM_FPGA)
/* sg unit: 1ms, ieee1901 unit: 40ms */
fc_1901.vf.nn_cco.duration = sg_fc->vf.nn_cco.duration / 40;
/* sg and ieee1901 unit: 1ms */
fc_1901.vf.nn_cco.sbandoffset = sg_fc->vf.nn_cco.sbandoffset;
fc_1901.vf.nn_cco.receive_nid = sg_fc->vf.nn_cco.receive_nid;
fc_1901.vf.nn_cco.version = sg_fc->vf.nn_cco.version;
fc_1901.vf.nn_cco.fccs = sg_fc->vf.nn_cco.fccs;
break;
#else
return;
#endif
case I1901_RTS_CTS:
default:
return;
}
os_mem_cpy(sg_fc, &fc_1901, sizeof(fc_1901));
#else
(void)proto;
(void)fc;
#endif
}
#if (ENA_HW_SYNC_PPM_WAR || ENA_SW_SYNC_PPM_WAR)
int32_t IRAM_ATTR mac_get_clear_dbg_pkt_ppm_step(void *fc)
{
int32_t ppm_step = 0;
uint32_t proto = PHY_PROTO_TYPE_GET();
uint32_t dbg_pkt_version = 0;
if (phy_get_g_mt_mode_sel()) {
return 0;
}
#if SUPPORT_SMART_GRID
if (proto == PLC_PROTO_TYPE_SG) {
frame_control_t *sg_fc = (frame_control_t*)fc;
if (FC_DELIM_BEACON == sg_fc->delimiter_type) {
dbg_pkt_version = sg_fc->vf.bcn.version;
ppm_step = (int8_t)sg_fc->vf.bcn.fccs;
sg_fc->vf.bcn.fccs = 0;
sg_fc->vf.bcn.version = SG_STANDARD_VERSION;
} else if (FC_DELIM_SOF == sg_fc->delimiter_type) {
dbg_pkt_version = sg_fc->vf.sof.version;
ppm_step = (int8_t)sg_fc->vf.sof.fccs;
sg_fc->vf.sof.fccs = 0;
sg_fc->vf.sof.version = SG_STANDARD_VERSION;
}
} else
#endif /* SUPPORT_SMART_GRID */
#if SUPPORT_SOUTHERN_POWER_GRID
if (proto == PLC_PROTO_TYPE_SPG) {
spg_frame_control_t *spg_fc = (spg_frame_control_t*)fc;
if (FC_DELIM_BEACON == spg_fc->delimiter_type) {
dbg_pkt_version = spg_fc->vf.bcn.version;
ppm_step = (int8_t)spg_fc->vf.bcn.fccs[0];
spg_fc->vf.bcn.fccs[0] = 0;
spg_fc->vf.bcn.version = SPG_STANDARD_VERSION;
} else if (FC_DELIM_SOF == spg_fc->delimiter_type) {
dbg_pkt_version = spg_fc->vf.bcn.version;
ppm_step = (int8_t)spg_fc->vf.sof.fccs;
spg_fc->vf.sof.fccs = 0;
spg_fc->vf.sof.version = SPG_STANDARD_VERSION;
}
}
#endif /* SUPPORT_SOUTHERN_POWER_GRID */
{
(void)fc;
(void)proto;
}
return (int32_t)((dbg_pkt_version == DBG_PKT_VERSION) ? ppm_step : 0);
}
void IRAM_ATTR mac_modify_dbg_pkt_tx_ppm(int32_t step)
{
phy_ppm_status_ctxt_t *ppm_sts_ctxt = &g_phy_cpu_share_ctxt.ppm_status;
BUILD_BUG_ON(PLC_NTB_PPM_SHIFT >= 4);
ppm_sts_ctxt->ppm_status[0].ppm_err =
(int16_t)((-g_phy_cpu_share_ctxt.phy_ppm_init << (PLC_NTB_PPM_SHIFT
- PLC_REG_PPM_SHIFT)) + (step << PLC_NTB_PPM_SHIFT));
}
#endif /* (ENA_HW_SYNC_PPM_WAR || ENA_SW_SYNC_PPM_WAR) */