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;
 | |
| }
 | |
| 
 |