695 lines
19 KiB
C
695 lines
19 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 "iot_io.h"
|
||
|
#include "mac_rx_buf_ring.h"
|
||
|
#include "hw_tonemap.h"
|
||
|
#include "iot_config.h"
|
||
|
#include "mac_txq_hw.h"
|
||
|
#include "plc_mac_header.h"
|
||
|
#include "plc_const.h"
|
||
|
#include "mac_tx_hw.h"
|
||
|
#include "rx_pb_reorder.h"
|
||
|
#include "mac_crc.h"
|
||
|
|
||
|
#include "mac_rx_hw.h"
|
||
|
#include "hw_tonemap.h"
|
||
|
#include "mpdu_header.h"
|
||
|
|
||
|
#include "mac_sched_hw.h"
|
||
|
#include "iot_system_api.h"
|
||
|
|
||
|
const uint32_t mac_crc24_init_proto_tab[] = {
|
||
|
CRC24_INIT_VECT_SG, /* 0: PLC_PROTO_TYPE_SG */
|
||
|
CRC24_INIT_VECT_GP, /* 1: PLC_PROTO_TYPE_GP */ //TODO: need to confirm
|
||
|
CRC24_INIT_VECT_GP, /* 2: PLC_PROTO_TYPE_AV */ //TODO: need to confirm
|
||
|
CRC24_INIT_VECT_SPG /* 3: PLC_PROTO_TYPE_SPG */
|
||
|
};
|
||
|
|
||
|
/* fc crc */
|
||
|
uint32_t mac_crc_get_fc_swcrc(uint32_t proto, void *fc)
|
||
|
{
|
||
|
IOT_ASSERT(fc);
|
||
|
|
||
|
uint8_t mpdu_fc_len = mac_get_mpdu_fc_len(proto);
|
||
|
uint8_t mpdu_fccs_len = mac_get_mpdu_fccs_len(proto);
|
||
|
|
||
|
IOT_ASSERT(mpdu_fc_len > mpdu_fccs_len);
|
||
|
|
||
|
return iot_getcrc24((uint8_t *)fc, (uint8_t)(mpdu_fc_len - mpdu_fccs_len));
|
||
|
}
|
||
|
|
||
|
/* pb crc */
|
||
|
/**
|
||
|
* if fw set pb_header fill in payload, pb_head = NULL;
|
||
|
* otherwise pb_head = actual pb header buffer point
|
||
|
*/
|
||
|
uint32_t mac_crc_get_pb_swcrc(uint32_t proto, void *pb_head, uint8_t *payload,
|
||
|
uint32_t pb_sz, uint8_t delimiter)
|
||
|
{
|
||
|
uint32_t crc = 0;
|
||
|
uint8_t pb_crc_len = 0, pb_hdr_crc_len = 0, pb_hdr_len = 0;
|
||
|
|
||
|
#if IOT_CRC_DBG_ENABLE
|
||
|
uint32_t buffer[4] = {0};
|
||
|
buffer[0] = pb_sz;
|
||
|
buffer[1] = (uint32_t)pb_head;
|
||
|
buffer[2] = (uint32_t)payload;
|
||
|
IOT_ASSERT_DUMP(((pb_sz >= PB_SIZE_72 && pb_sz <= PB_SIZE_520)
|
||
|
&& (iot_data_addr_legal((uint32_t)pb_head))
|
||
|
&& (iot_data_addr_legal((uint32_t)payload))), buffer, 4);
|
||
|
#endif
|
||
|
switch(delimiter)
|
||
|
{
|
||
|
case FC_DELIM_BEACON:
|
||
|
pb_hdr_crc_len = mac_get_pb_hdr_crc_len(FC_DELIM_BEACON, proto);
|
||
|
#if SUPPORT_IEEE_1901
|
||
|
crc = iot_getcrc32_update(CRC32_INIT_VECT_I1901, payload,
|
||
|
pb_sz - pb_hdr_crc_len);
|
||
|
#else
|
||
|
crc = iot_getcrc24((uint8_t *)payload, pb_sz - pb_hdr_crc_len);
|
||
|
#endif
|
||
|
break;
|
||
|
|
||
|
case FC_DELIM_SOF:
|
||
|
pb_crc_len = mac_get_pb_crc_len(FC_DELIM_SOF, proto);
|
||
|
pb_hdr_crc_len = mac_get_pb_hdr_crc_len(FC_DELIM_SOF, proto);
|
||
|
pb_hdr_len = mac_get_pb_hdr_len(FC_DELIM_SOF, proto);
|
||
|
|
||
|
if (NULL == pb_head)
|
||
|
{
|
||
|
#if SUPPORT_IEEE_1901
|
||
|
crc = iot_getcrc32_update(CRC32_INIT_VECT_I1901, payload,
|
||
|
pb_sz - pb_crc_len);
|
||
|
#else
|
||
|
crc = iot_getcrc24(payload, pb_sz - pb_crc_len);
|
||
|
#endif
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
#if IOT_CRC_DBG_ENABLE
|
||
|
buffer[3] = pb_hdr_crc_len;
|
||
|
IOT_ASSERT_DUMP((pb_sz > pb_hdr_crc_len), buffer, 4);
|
||
|
#endif
|
||
|
#if SUPPORT_IEEE_1901
|
||
|
crc = iot_getcrc32_update(CRC32_INIT_VECT_I1901, (uint8_t *)pb_head,
|
||
|
pb_hdr_len);
|
||
|
crc = iot_getcrc32_update(crc, payload, pb_sz - pb_hdr_crc_len);
|
||
|
#else
|
||
|
crc = iot_getcrc24_update(mac_crc24_init_proto_tab[proto],
|
||
|
(uint8_t *)pb_head, pb_hdr_len);
|
||
|
crc = iot_getcrc24_update(crc, payload, pb_sz - pb_hdr_crc_len);
|
||
|
#endif
|
||
|
}
|
||
|
break;
|
||
|
|
||
|
default:
|
||
|
crc = (uint32_t)CRC_INIT_VECT_DEFAULT;
|
||
|
break;
|
||
|
}
|
||
|
|
||
|
return crc;
|
||
|
}
|
||
|
|
||
|
/* bcn crc */
|
||
|
uint32_t mac_crc_get_bcn_swcrc(uint32_t proto, void *payload, uint32_t pb_sz,
|
||
|
uint32_t *crc_value)
|
||
|
{
|
||
|
IOT_ASSERT(payload);
|
||
|
|
||
|
uint8_t pb_pld_crc_len = mac_get_pb_pld_crc_len(FC_DELIM_BEACON, proto);
|
||
|
uint8_t pb_crc_len = mac_get_pb_crc_len(FC_DELIM_BEACON, proto);
|
||
|
uint8_t pb_resv_len = 0;
|
||
|
|
||
|
if (PLC_PROTO_TYPE_SPG == proto)
|
||
|
pb_resv_len = 1;
|
||
|
int32_t sl = pb_sz - pb_crc_len - pb_pld_crc_len - pb_resv_len;
|
||
|
if(sl < 0)
|
||
|
{
|
||
|
return ERR_CRC_LEN;
|
||
|
}
|
||
|
#if SUPPORT_IEEE_1901
|
||
|
*crc_value = iot_getcrc32_update(CRC32_INIT_VECT_I1901, (uint8_t *)payload,
|
||
|
(uint32_t)sl);
|
||
|
#else
|
||
|
*crc_value = iot_getcrc32((uint8_t *)payload, (uint32_t)sl);
|
||
|
#endif
|
||
|
return ERR_OK;
|
||
|
}
|
||
|
|
||
|
uint8_t mac_crc_set_bcn_swcrc(uint32_t proto, void *payload, uint32_t pb_sz)
|
||
|
{
|
||
|
uint32_t crc = 0, data_len = 0;
|
||
|
uint8_t pb_crc_len = 0;
|
||
|
uint8_t pb_pld_crc_len = 0;
|
||
|
uint8_t pb_resv_len = 0;
|
||
|
IOT_ASSERT(payload);
|
||
|
|
||
|
switch (proto)
|
||
|
{
|
||
|
#if SUPPORT_SMART_GRID
|
||
|
case PLC_PROTO_TYPE_SG:
|
||
|
break;
|
||
|
|
||
|
#endif
|
||
|
#if SUPPORT_SOUTHERN_POWER_GRID
|
||
|
case PLC_PROTO_TYPE_SPG:
|
||
|
pb_resv_len = 1;
|
||
|
break;
|
||
|
#endif
|
||
|
|
||
|
default:
|
||
|
return ERR_NOSUPP;
|
||
|
}
|
||
|
|
||
|
pb_crc_len = mac_get_pb_crc_len(FC_DELIM_BEACON, proto);
|
||
|
pb_pld_crc_len = mac_get_pb_pld_crc_len(FC_DELIM_BEACON, proto);
|
||
|
|
||
|
if (mac_tx_hw_get_bcn_swcrc_cfg())
|
||
|
{
|
||
|
IOT_ASSERT(payload);
|
||
|
uint32_t ret = 0;
|
||
|
ret = mac_crc_get_bcn_swcrc(proto, payload, pb_sz, &crc);
|
||
|
if(ret){
|
||
|
return (uint8_t)ret;
|
||
|
}
|
||
|
data_len = pb_sz - pb_crc_len - pb_pld_crc_len - pb_resv_len;
|
||
|
os_mem_cpy((uint8_t *)payload + data_len, &crc,
|
||
|
pb_pld_crc_len);
|
||
|
}
|
||
|
|
||
|
return ERR_OK;
|
||
|
}
|
||
|
|
||
|
uint32_t mac_crc_get_msdu_swcrc(uint32_t proto, iot_pkt_t *msdu)
|
||
|
{
|
||
|
uint8_t *data = NULL, crc_len = 0;
|
||
|
uint16_t msdu_len = 0;
|
||
|
uint32_t crc = 0;
|
||
|
|
||
|
IOT_ASSERT(msdu);
|
||
|
|
||
|
switch (proto)
|
||
|
{
|
||
|
#if SUPPORT_SMART_GRID
|
||
|
case PLC_PROTO_TYPE_SG:
|
||
|
{
|
||
|
mac_header_t *sg_mac = (mac_header_t *)iot_pkt_data(msdu);
|
||
|
data = (uint8_t *)sg_mac;
|
||
|
if (sg_mac->mac_exist_flag)
|
||
|
{
|
||
|
data += MAC_HDR_LEN_WITH_ADDR;
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
data += MAC_HDR_LEN_NO_ADDR;
|
||
|
}
|
||
|
msdu_len = sg_mac->msdu_len;
|
||
|
crc_len = SG_MAC_MSDU_CRC_LEN;
|
||
|
break;
|
||
|
}
|
||
|
#endif
|
||
|
|
||
|
#if SUPPORT_SOUTHERN_POWER_GRID
|
||
|
case PLC_PROTO_TYPE_SPG:
|
||
|
{
|
||
|
spg_mac_header_t *spg_mac = (spg_mac_header_t *)iot_pkt_data(msdu);
|
||
|
data = (uint8_t *)spg_mac;
|
||
|
if (spg_mac->mac_hdr_type)
|
||
|
{
|
||
|
data += sizeof(spg_mac_header_t);
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
data += sizeof(spg_mac_header_t) + sizeof(spg_mac_lheader_tail_t);
|
||
|
}
|
||
|
msdu_len = spg_mac->msdu_len;
|
||
|
crc_len = SPG_MAC_MSDU_CRC_LEN;
|
||
|
break;
|
||
|
}
|
||
|
#endif
|
||
|
#if SUPPORT_GREEN_PHY
|
||
|
case PLC_PROTO_TYPE_GP:
|
||
|
{
|
||
|
gp_mac_header_t *gp_mac = (gp_mac_header_t *)iot_pkt_data(msdu);
|
||
|
data = (uint8_t *)gp_mac;
|
||
|
if (gp_mac->mft == 0 || gp_mac->mft == 1)
|
||
|
{
|
||
|
data += sizeof(gp_mac_header_t);
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
data += sizeof(gp_mac_header_t) + sizeof(gp_ats_or_cfder_t);
|
||
|
}
|
||
|
msdu_len = gp_mac->mfl;
|
||
|
crc_len = GP_MAC_MSDU_CRC_LEN;
|
||
|
break;
|
||
|
}
|
||
|
#endif
|
||
|
|
||
|
default:
|
||
|
return (uint32_t)CRC_INIT_VECT_DEFAULT;
|
||
|
}
|
||
|
|
||
|
if (iot_pkt_data_len(msdu) < (uint32_t)((uint32_t)msdu_len +
|
||
|
(uint32_t)crc_len + (uint32_t)(data - iot_pkt_data(msdu))))
|
||
|
{
|
||
|
return (uint32_t)CRC_INIT_VECT_DEFAULT;
|
||
|
}
|
||
|
|
||
|
crc = iot_getcrc32(data, msdu_len);
|
||
|
|
||
|
return crc;
|
||
|
}
|
||
|
|
||
|
uint32_t mac_crc_get_msdu_srccrc(uint32_t proto, iot_pkt_t *msdu)
|
||
|
{
|
||
|
uint8_t *data = NULL, crc_len = 0;
|
||
|
uint16_t msdu_len = 0;
|
||
|
uint32_t crc = 0;
|
||
|
|
||
|
IOT_ASSERT(msdu);
|
||
|
|
||
|
switch (proto)
|
||
|
{
|
||
|
#if SUPPORT_SMART_GRID
|
||
|
case PLC_PROTO_TYPE_SG:
|
||
|
{
|
||
|
mac_header_t *sg_mac = (mac_header_t *)iot_pkt_data(msdu);
|
||
|
data = (uint8_t *)sg_mac;
|
||
|
if (sg_mac->mac_exist_flag)
|
||
|
{
|
||
|
data += MAC_HDR_LEN_WITH_ADDR;
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
data += MAC_HDR_LEN_NO_ADDR;
|
||
|
}
|
||
|
msdu_len = sg_mac->msdu_len;
|
||
|
crc_len = SG_MAC_MSDU_CRC_LEN;
|
||
|
break;
|
||
|
}
|
||
|
#endif
|
||
|
|
||
|
#if SUPPORT_SOUTHERN_POWER_GRID
|
||
|
case PLC_PROTO_TYPE_SPG:
|
||
|
{
|
||
|
spg_mac_header_t *spg_mac = (spg_mac_header_t *)iot_pkt_data(msdu);
|
||
|
data = (uint8_t *)spg_mac;
|
||
|
if (spg_mac->mac_hdr_type)
|
||
|
{
|
||
|
data += sizeof(spg_mac_header_t);
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
data += sizeof(spg_mac_header_t) + sizeof(spg_mac_lheader_tail_t);
|
||
|
}
|
||
|
msdu_len = spg_mac->msdu_len;
|
||
|
crc_len = SPG_MAC_MSDU_CRC_LEN;
|
||
|
break;
|
||
|
}
|
||
|
#endif
|
||
|
|
||
|
#if SUPPORT_GREEN_PHY
|
||
|
case PLC_PROTO_TYPE_GP:
|
||
|
{
|
||
|
gp_mac_header_t *gp_mac = (gp_mac_header_t *)iot_pkt_data(msdu);
|
||
|
data = (uint8_t *)gp_mac;
|
||
|
if (gp_mac->mft == 0 || gp_mac->mft == 1)
|
||
|
{
|
||
|
data += sizeof(gp_mac_header_t);
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
data += sizeof(gp_mac_header_t) + sizeof(gp_ats_or_cfder_t);
|
||
|
}
|
||
|
msdu_len = gp_mac->mfl;
|
||
|
crc_len = GP_MAC_MSDU_CRC_LEN;
|
||
|
break;
|
||
|
}
|
||
|
#endif
|
||
|
|
||
|
default:
|
||
|
return (uint32_t)CRC_INIT_VECT_DEFAULT;
|
||
|
}
|
||
|
|
||
|
if (iot_pkt_data_len(msdu) < (uint32_t)((uint32_t)msdu_len +
|
||
|
(uint32_t)crc_len + (uint32_t)(data - iot_pkt_data(msdu))))
|
||
|
|
||
|
{
|
||
|
return (uint32_t)CRC_INIT_VECT_DEFAULT;
|
||
|
}
|
||
|
|
||
|
os_mem_cpy(&crc, data + msdu_len, crc_len);
|
||
|
|
||
|
return crc;
|
||
|
}
|
||
|
|
||
|
uint8_t mac_crc_set_msdu_swcrc(uint32_t proto, iot_pkt_t *msdu)
|
||
|
{
|
||
|
uint8_t *data = NULL, crc_len = 0;
|
||
|
uint16_t msdu_len = 0;
|
||
|
uint32_t crc = 0;
|
||
|
|
||
|
IOT_ASSERT(msdu);
|
||
|
|
||
|
switch (proto)
|
||
|
{
|
||
|
#if SUPPORT_SMART_GRID
|
||
|
case PLC_PROTO_TYPE_SG:
|
||
|
{
|
||
|
#if SUPPORT_IEEE_1901
|
||
|
i1901_mac_header_t *i1901_mac;
|
||
|
|
||
|
i1901_mac = (i1901_mac_header_t *)iot_pkt_data(msdu);
|
||
|
data = (uint8_t *)i1901_mac;
|
||
|
|
||
|
if (i1901_mac_hdr_var_is_valid(i1901_mac)) {
|
||
|
if (i1901_mac_hdr_var_addr_is_valid(i1901_mac)) {
|
||
|
data += MAC_HDR_LEN_WITH_VAR_ADDR_I1901;
|
||
|
} else {
|
||
|
data += MAC_HDR_LEN_WITH_VAR_I1901;
|
||
|
}
|
||
|
} else {
|
||
|
data += MAC_HDR_LEN_NO_VAR_I1901;
|
||
|
}
|
||
|
msdu_len = i1901_mac->msdu_len;
|
||
|
crc_len = I1901_MAC_MSDU_CRC_LEN;
|
||
|
#else /* SUPPORT_IEEE_1901 */
|
||
|
mac_header_t *sg_mac = (mac_header_t *)iot_pkt_data(msdu);
|
||
|
data = (uint8_t *)sg_mac;
|
||
|
if (sg_mac->version == MAC_HEADER_SHORT_VER) {
|
||
|
mac_short_header_t *sg_mac_s =
|
||
|
(mac_short_header_t *)iot_pkt_data(msdu);
|
||
|
data += MAC_HDR_LEN_SHORT;
|
||
|
msdu_len = sg_mac_s->msdu_len;
|
||
|
} else {
|
||
|
if (sg_mac->mac_exist_flag)
|
||
|
{
|
||
|
data += MAC_HDR_LEN_WITH_ADDR;
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
data += MAC_HDR_LEN_NO_ADDR;
|
||
|
}
|
||
|
msdu_len = sg_mac->msdu_len;
|
||
|
#if SIMU_DBG == 1
|
||
|
if (sg_mac->msdu_type == 48)
|
||
|
{
|
||
|
iot_printf("mac sending msdu_type = 48, iot_pkt=0x%x\n",
|
||
|
msdu);
|
||
|
}
|
||
|
#endif
|
||
|
}
|
||
|
crc_len = SG_MAC_MSDU_CRC_LEN;
|
||
|
#endif /* SUPPORT_IEEE_1901 */
|
||
|
break;
|
||
|
}
|
||
|
#endif
|
||
|
|
||
|
#if SUPPORT_SOUTHERN_POWER_GRID
|
||
|
case PLC_PROTO_TYPE_SPG:
|
||
|
{
|
||
|
spg_mac_header_t *spg_mac = (spg_mac_header_t *)iot_pkt_data(msdu);
|
||
|
data = (uint8_t *)spg_mac;
|
||
|
if (spg_mac->version == SPG_MAC_HEADER_SHORT_VER) {
|
||
|
spg_mac_short_header_t *spg_mac_s =
|
||
|
(spg_mac_short_header_t *)iot_pkt_data(msdu);
|
||
|
data += MAC_SINGLE_HOP_HDR_LEN_SPG;
|
||
|
msdu_len = spg_mac_s->msdu_len;
|
||
|
} else {
|
||
|
if (spg_mac->mac_hdr_type) {
|
||
|
data += sizeof(spg_mac_header_t);
|
||
|
} else {
|
||
|
data += sizeof(spg_mac_header_t) +
|
||
|
sizeof(spg_mac_lheader_tail_t);
|
||
|
}
|
||
|
msdu_len = spg_mac->msdu_len;
|
||
|
}
|
||
|
crc_len = SPG_MAC_MSDU_CRC_LEN;
|
||
|
break;
|
||
|
}
|
||
|
#endif
|
||
|
|
||
|
#if SUPPORT_GREEN_PHY
|
||
|
case PLC_PROTO_TYPE_GP:
|
||
|
{
|
||
|
gp_mac_header_t *gp_mac = (gp_mac_header_t *)iot_pkt_data(msdu);
|
||
|
data = (uint8_t *)gp_mac;
|
||
|
if (gp_mac->mft == 0 || gp_mac->mft == 1)
|
||
|
{
|
||
|
data += sizeof(gp_mac_header_t);
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
data += sizeof(gp_mac_header_t) + sizeof(gp_ats_or_cfder_t);
|
||
|
}
|
||
|
msdu_len = gp_mac->mfl;
|
||
|
crc_len = GP_MAC_MSDU_CRC_LEN;
|
||
|
break;
|
||
|
}
|
||
|
#endif
|
||
|
|
||
|
default:
|
||
|
return ERR_NOSUPP;
|
||
|
}
|
||
|
|
||
|
if (iot_pkt_data_len(msdu) < (uint32_t)((uint32_t)msdu_len +
|
||
|
(uint32_t)crc_len + (uint32_t)(data - iot_pkt_data(msdu))))
|
||
|
{
|
||
|
return ERR_INVAL;
|
||
|
}
|
||
|
IOT_ASSERT(msdu_len);
|
||
|
#if SUPPORT_IEEE_1901
|
||
|
crc = iot_getcrc32_update(CRC32_INIT_VECT_I1901, data, msdu_len);
|
||
|
#else
|
||
|
crc = iot_getcrc32(data, msdu_len);
|
||
|
#endif
|
||
|
os_mem_cpy(data + msdu_len, &crc, crc_len);
|
||
|
|
||
|
return ERR_OK;
|
||
|
}
|
||
|
|
||
|
uint8_t mac_crc_mpdu_swcrc_verify(uint32_t proto, rx_buf_hdr_t *rx_buf_hdr,
|
||
|
uint8_t bit_mask)
|
||
|
{
|
||
|
uint8_t crc_ret = 0;
|
||
|
uint32_t pb_sz = 0;
|
||
|
uint32_t crc_src = 0, crc_cal = 0;
|
||
|
uint8_t *pb_payload = NULL;
|
||
|
uint8_t *tmp = NULL;
|
||
|
|
||
|
IOT_ASSERT(rx_buf_hdr);
|
||
|
|
||
|
pb_payload = (uint8_t *)rx_buf_hdr + PB_PAYLOAD_OFFSET;
|
||
|
|
||
|
uint8_t delimiter = (uint8_t)mac_get_rx_delimiter_from_fc(proto,
|
||
|
mac_rx_mpdu_st_get_fc_addr(&rx_buf_hdr->mpdu_st));
|
||
|
/* get rx fc message */
|
||
|
rx_fc_msg_t rx_fc_msg = {0};
|
||
|
mac_get_rx_frm_msg_from_fc(proto,
|
||
|
mac_rx_mpdu_st_get_fc_addr(&rx_buf_hdr->mpdu_st), &rx_fc_msg);
|
||
|
|
||
|
/* get pb size */
|
||
|
switch (delimiter)
|
||
|
{
|
||
|
case FC_DELIM_BEACON:
|
||
|
{
|
||
|
phy_get_pb_size(proto, rx_fc_msg.tmi, 0, &pb_sz);
|
||
|
break;
|
||
|
}
|
||
|
case FC_DELIM_SOF:
|
||
|
{
|
||
|
phy_get_pb_size(proto, rx_fc_msg.tmi, rx_fc_msg.tmi_ext, &pb_sz);
|
||
|
break;
|
||
|
}
|
||
|
default:
|
||
|
pb_sz = 0;
|
||
|
break;
|
||
|
}
|
||
|
|
||
|
/* debug msg */
|
||
|
#if (MAC_CRC_DEBUG_LEVEL > 1)
|
||
|
iot_printf("pb_sz = 0x%X, pb data is:\r\n", pb_sz);
|
||
|
uint32_t i = 0;
|
||
|
for (i = 0; i < pb_sz; i++)
|
||
|
{
|
||
|
iot_printf("0x%02X ", *(pb_payload + i));
|
||
|
}
|
||
|
iot_printf("\r\n");
|
||
|
#endif
|
||
|
|
||
|
/* fc - crc24 */
|
||
|
if (bit_mask & FC_CRC_ERR_MASK)
|
||
|
{
|
||
|
tmp = (uint8_t *)mac_rx_mpdu_st_get_fc_addr(&rx_buf_hdr->mpdu_st);
|
||
|
crc_cal = mac_crc_get_fc_swcrc(proto, tmp);
|
||
|
crc_src = rx_fc_msg.fccs;
|
||
|
|
||
|
if (crc_src != crc_cal)
|
||
|
{
|
||
|
crc_ret |= FC_CRC_ERR_MASK;
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
crc_ret &= ~FC_CRC_ERR_MASK;
|
||
|
}
|
||
|
#if (MAC_CRC_DEBUG_LEVEL)
|
||
|
iot_printf("fc crc, src=0x%08X, cal=0x%08X\r\n", crc_src, crc_cal);
|
||
|
#endif
|
||
|
}
|
||
|
|
||
|
/* pb crc - crc24 */
|
||
|
if (bit_mask & PB_CRC_ERR_MASK)
|
||
|
{
|
||
|
crc_src = mac_rx_pb_end_get_pb_crc(&rx_buf_hdr->pb_ed);
|
||
|
if (mac_rx_get_pb_hdr_to_buf_cfg())
|
||
|
{
|
||
|
crc_cal = mac_crc_get_pb_swcrc(proto, NULL,
|
||
|
pb_payload, pb_sz, delimiter);
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
switch (proto)
|
||
|
{
|
||
|
#if SUPPORT_SMART_GRID
|
||
|
case PLC_PROTO_TYPE_SG:
|
||
|
{
|
||
|
sg_sof_pb_hdr_t sg_pb_head = {0};
|
||
|
sg_pb_head.mac_frame_start =
|
||
|
(uint8_t)rx_buf_hdr->pb_st.first_pb;
|
||
|
sg_pb_head.mac_frame_end =
|
||
|
(uint8_t)rx_buf_hdr->pb_st.last_pb;
|
||
|
sg_pb_head.seq = (uint8_t)rx_buf_hdr->pb_st.ssn;
|
||
|
crc_cal = mac_crc_get_pb_swcrc(proto, &sg_pb_head,
|
||
|
pb_payload, pb_sz, delimiter);
|
||
|
break;
|
||
|
}
|
||
|
#endif
|
||
|
|
||
|
#if SUPPORT_SOUTHERN_POWER_GRID
|
||
|
case PLC_PROTO_TYPE_SPG:
|
||
|
{
|
||
|
spg_sof_pb_hdr_t spg_pb_head = {0};
|
||
|
spg_pb_head.seq = (uint16_t)rx_buf_hdr->pb_st.ssn;
|
||
|
spg_pb_head.resv = 0;
|
||
|
crc_cal = mac_crc_get_pb_swcrc(proto, &spg_pb_head,
|
||
|
pb_payload, pb_sz, delimiter);
|
||
|
break;
|
||
|
}
|
||
|
#endif
|
||
|
|
||
|
#if SUPPORT_GREEN_PHY
|
||
|
case PLC_PROTO_TYPE_GP:
|
||
|
{
|
||
|
gp_sof_pb_hdr_t gp_pb_head = {0};
|
||
|
gp_pb_head.ssn = (uint16_t)rx_buf_hdr->pb_st.ssn;
|
||
|
crc_cal = mac_crc_get_pb_swcrc(proto, &gp_pb_head,
|
||
|
pb_payload, pb_sz, delimiter);
|
||
|
break;
|
||
|
}
|
||
|
#endif
|
||
|
default:
|
||
|
crc_cal = 0;
|
||
|
break;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
if (crc_src != crc_cal)
|
||
|
{
|
||
|
crc_ret |= PB_CRC_ERR_MASK;
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
crc_ret &= ~PB_CRC_ERR_MASK;
|
||
|
}
|
||
|
#if (MAC_CRC_DEBUG_LEVEL)
|
||
|
iot_printf("pb crc, src=0x%08X, cal=0x%08X\r\n",
|
||
|
crc_src, crc_cal);
|
||
|
#endif
|
||
|
}
|
||
|
|
||
|
/* payload crc - crc32 */
|
||
|
if ((bit_mask & PAYLOAD_CRC_ERR_MASK) && (FC_DELIM_BEACON == delimiter))
|
||
|
{
|
||
|
uint8_t pb_hdr_resv_crc_len = mac_get_pb_hdr_resv_crc_len(FC_DELIM_BEACON, proto);
|
||
|
uint8_t pb_pld_crc_len = mac_get_pb_pld_crc_len(FC_DELIM_BEACON, proto);
|
||
|
|
||
|
tmp = pb_payload + pb_sz - pb_hdr_resv_crc_len - pb_pld_crc_len;
|
||
|
|
||
|
os_mem_cpy(&crc_src, tmp, pb_pld_crc_len);
|
||
|
mac_crc_get_bcn_swcrc(proto, pb_payload, pb_sz, &crc_cal);
|
||
|
|
||
|
if (crc_src != crc_cal)
|
||
|
{
|
||
|
crc_ret |= PAYLOAD_CRC_ERR_MASK;
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
crc_ret &= ~PAYLOAD_CRC_ERR_MASK;
|
||
|
}
|
||
|
#if (MAC_CRC_DEBUG_LEVEL)
|
||
|
iot_printf("bcn payload crc, src=0x%08X, cal=0x%08X\r\n",
|
||
|
crc_src, crc_cal);
|
||
|
#endif
|
||
|
}
|
||
|
|
||
|
#if (MAC_CRC_DEBUG_LEVEL)
|
||
|
if (NULL != rx_buf_hdr)
|
||
|
{
|
||
|
iot_printf("hw crc:bcn_crc=%d,pb_crc=%d,fc_crc=%d\r\n",
|
||
|
rx_buf_hdr->pb_ed.rx_beacon_pld_crc_err,
|
||
|
rx_buf_hdr->pb_ed.rx_pb_crc_err,
|
||
|
rx_buf_hdr->att.is_fcserr);
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
iot_printf("None rx pb\r\n");
|
||
|
}
|
||
|
iot_printf("sw crc cfg bit_mask = 0x%02X\r\n", bit_mask);
|
||
|
iot_printf("sw crc:payload_crc=%d,pb_crc=%d,fc_crc=%d\r\n",
|
||
|
(crc_ret & PAYLOAD_CRC_ERR_MASK) ? 1 : 0,
|
||
|
(crc_ret & PB_CRC_ERR_MASK) ? 1 : 0,
|
||
|
(crc_ret & FC_CRC_ERR_MASK) ? 1 : 0);
|
||
|
#endif
|
||
|
|
||
|
return crc_ret;
|
||
|
}
|
||
|
|
||
|
uint8_t mac_crc_msdu_swcrc_verify(uint32_t proto, iot_pkt_t *msdu)
|
||
|
{
|
||
|
uint8_t crc_ret = 0;
|
||
|
uint32_t crc_src, crc_cal;
|
||
|
IOT_ASSERT(msdu);
|
||
|
|
||
|
crc_src = mac_crc_get_msdu_srccrc(proto, msdu);
|
||
|
crc_cal = mac_crc_get_msdu_swcrc(proto, msdu);
|
||
|
|
||
|
if (crc_src != crc_cal)
|
||
|
{
|
||
|
crc_ret |= PAYLOAD_CRC_ERR_MASK;
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
crc_ret &= ~PAYLOAD_CRC_ERR_MASK;
|
||
|
}
|
||
|
#if (MAC_CRC_DEBUG_LEVEL)
|
||
|
iot_printf("msdu crc, src=0x%08X, cal=0x%08X\r\n",
|
||
|
crc_src, crc_cal);
|
||
|
#endif
|
||
|
|
||
|
return crc_ret;
|
||
|
}
|
||
|
|