695 lines
		
	
	
		
			19 KiB
		
	
	
	
		
			C
		
	
	
		
			Executable File
		
	
	
	
	
			
		
		
	
	
			695 lines
		
	
	
		
			19 KiB
		
	
	
	
		
			C
		
	
	
		
			Executable File
		
	
	
	
	
/****************************************************************************
 | 
						|
 | 
						|
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;
 | 
						|
}
 | 
						|
 |