192 lines
		
	
	
		
			6.0 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
		
		
			
		
	
	
			192 lines
		
	
	
		
			6.0 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_vdev.h"
							 | 
						||
| 
								 | 
							
								#include "mac_pdev.h"
							 | 
						||
| 
								 | 
							
								#include "iot_utils_api.h"
							 | 
						||
| 
								 | 
							
								#include "mac_tx_hw.h"
							 | 
						||
| 
								 | 
							
								#include "tx_desc_reg_api.h"
							 | 
						||
| 
								 | 
							
								#include "phy_chn.h"
							 | 
						||
| 
								 | 
							
								#include "mac_hplc_ext.h"
							 | 
						||
| 
								 | 
							
								#include "mac_desc_engine.h"
							 | 
						||
| 
								 | 
							
								#include "mac_rx_hw.h"
							 | 
						||
| 
								 | 
							
								#include "plc_mpdu_header.h"
							 | 
						||
| 
								 | 
							
								#include "mac_hplc_ext_api.h"
							 | 
						||
| 
								 | 
							
								#include "mac_task.h"
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								uint32_t mac_send_ext_frame_internal(uint8_t ext_type,
							 | 
						||
| 
								 | 
							
								    pdevid_t pdev_id, vdevid_t vdev_id, mac_tx_info *tx_info, uint8_t *addr,
							 | 
						||
| 
								 | 
							
								    uint8_t sn)
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
								#if PLC_MAC_TX_DEBUG_LOG
							 | 
						||
| 
								 | 
							
								    iot_printf("%s\n", __FUNCTION__);
							 | 
						||
| 
								 | 
							
								#endif
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    tx_mpdu_end *mpdu_end;
							 | 
						||
| 
								 | 
							
								    tx_mpdu_start *mpdu;
							 | 
						||
| 
								 | 
							
								    mac_queue_t swq_id;
							 | 
						||
| 
								 | 
							
								    uint32_t hwqid;
							 | 
						||
| 
								 | 
							
								    nid_t nid;
							 | 
						||
| 
								 | 
							
								    uint32_t proto = PHY_PROTO_TYPE_GET();
							 | 
						||
| 
								 | 
							
								    void *fc;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    mac_pdev_t *pdev = g_mac_pdev[pdev_id];
							 | 
						||
| 
								 | 
							
								    mac_vdev_t *vdev = get_vdev_ptr(pdev_id, vdev_id);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    mac_desc_get(&g_mac_desc_eng, PLC_TX_MPDU_END_POOL, (void **)&mpdu_end);
							 | 
						||
| 
								 | 
							
								    mac_desc_get(&g_mac_desc_eng, PLC_TX_MPDU_START_POOL, (void **)&mpdu);
							 | 
						||
| 
								 | 
							
								    if (!(mpdu && mpdu_end)) {
							 | 
						||
| 
								 | 
							
								        IOT_ASSERT(0);
							 | 
						||
| 
								 | 
							
								        return ERR_NOMEM;
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    /* get nid */
							 | 
						||
| 
								 | 
							
								    vdev_get_nid(vdev, &nid);
							 | 
						||
| 
								 | 
							
								    /* get swq type id */
							 | 
						||
| 
								 | 
							
								    if (!vdev_get_block_dbg_pkt_4_rx_only(vdev) && tx_info->is_dbg_pkt) {
							 | 
						||
| 
								 | 
							
								        tx_info->link_id += LID_BCSMA_START;
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								    swq_id = mac_q_get_swqid_from_phase_lid(&pdev->hwq_hdl, \
							 | 
						||
| 
								 | 
							
								        tx_info->phase, tx_info->link_id);
							 | 
						||
| 
								 | 
							
								    /* check if the hwq already enabled */
							 | 
						||
| 
								 | 
							
								    hwqid = mac_q_create_hwqid_from_swqid(&pdev->hwq_hdl, swq_id);
							 | 
						||
| 
								 | 
							
								    IOT_ASSERT(hwqid != INV_MAC_HWQ_ID);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    mac_tx_mpdu_fill_macinfo(mpdu, swq_id, 0, \
							 | 
						||
| 
								 | 
							
								        0, 0, 0, 0, 0, 0, 0,\
							 | 
						||
| 
								 | 
							
								        0, 0, mpdu_end, NULL, NULL, \
							 | 
						||
| 
								 | 
							
								        0, 0, 0, 0, 0, 0, 0);
							 | 
						||
| 
								 | 
							
								    mac_tx_mpdu_fill_phyinfo(\
							 | 
						||
| 
								 | 
							
								        mpdu, HW_DESC_TX_PORT_PLC, 128, tx_info->phase, \
							 | 
						||
| 
								 | 
							
								        phy_def_hw_band_id_get(), 0, 0, 0, 0);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    /* fill fc info */
							 | 
						||
| 
								 | 
							
								    fc = mac_tx_mpdu_start_get_fc_ptr(mpdu);
							 | 
						||
| 
								 | 
							
								    mac_tx_mpdu_fill_proto(mpdu, PLC_PROTO_TYPE_RAWDATA);
							 | 
						||
| 
								 | 
							
								    mac_tx_fill_extsackinfo(proto, fc, FC_DELIM_SACK, nid, ext_type, \
							 | 
						||
| 
								 | 
							
								        addr, vdev_get_tei(vdev), sn);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    return mac_tx_hw_mpdu(&pdev->hwq_hdl, \
							 | 
						||
| 
								 | 
							
								        hwqid, mpdu);
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								uint32_t mac_send_ext_frame(uint8_t ext_type, pdevid_t pdev_id,
							 | 
						||
| 
								 | 
							
								    vdevid_t vdev_id, mac_tx_info *tx_info, uint8_t *addr, uint8_t sn)
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
								    uint32_t ret = 0;
							 | 
						||
| 
								 | 
							
								    mac_msg_t *msg = mac_alloc_msg();
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    if (msg == NULL) {
							 | 
						||
| 
								 | 
							
								        IOT_ASSERT(0);
							 | 
						||
| 
								 | 
							
								        ret = ERR_NOMEM;
							 | 
						||
| 
								 | 
							
								        goto out;
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    msg->type = MAC_MSG_TYPE_CVG;
							 | 
						||
| 
								 | 
							
								    msg->id = MAC_MSG_ID_CVG_EXT_FRAME_SEND;
							 | 
						||
| 
								 | 
							
								    msg->data1 = (((uint32_t)pdev_id) << 24) | (((uint32_t)sn) << 16) | \
							 | 
						||
| 
								 | 
							
								        (((uint32_t)vdev_id) << 8) | ext_type;
							 | 
						||
| 
								 | 
							
								    msg->data2 = tx_info;
							 | 
						||
| 
								 | 
							
								    msg->data3 = addr;
							 | 
						||
| 
								 | 
							
								    mac_queue_msg(msg, MAC_MSG_QUEUE_HP);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								out:
							 | 
						||
| 
								 | 
							
								    return ret;
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								uint32_t static mac_rx_ext_frame(mac_vdev_t *vdev, iot_pkt_t* buf)
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
								    if (vdev == NULL)
							 | 
						||
| 
								 | 
							
								        goto err;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    if (vdev->start_cfg.mac_data_rx_func == NULL)
							 | 
						||
| 
								 | 
							
								        goto err;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    if (buf == NULL) {
							 | 
						||
| 
								 | 
							
								            IOT_ASSERT(0);
							 | 
						||
| 
								 | 
							
								            return ERR_FAIL;
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    rx_buf_hdr_t *hdr = (rx_buf_hdr_t *)iot_pkt_data(buf);
							 | 
						||
| 
								 | 
							
								    iot_pkt_pull(buf, sizeof(rx_buf_hdr_t));
							 | 
						||
| 
								 | 
							
								    rx_mpdu_start *mpdu_st = &hdr->mpdu_st;
							 | 
						||
| 
								 | 
							
								    int8_t snr = mac_rx_mpdu_st_get_avg_snr(mpdu_st);
							 | 
						||
| 
								 | 
							
								    uint8_t phase = mac_rx_mpdu_st_get_rx_phase(mpdu_st);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    mac_rx_info_t *rx_info = (mac_rx_info_t *)(iot_pkt_data(buf) - \
							 | 
						||
| 
								 | 
							
								        sizeof(mac_rx_info_t));
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    os_mem_cpy(rx_info->fc, mac_rx_mpdu_st_get_fc_addr(mpdu_st), \
							 | 
						||
| 
								 | 
							
								        sizeof(rx_info->fc));
							 | 
						||
| 
								 | 
							
								    rx_info->phy.snr = snr;
							 | 
						||
| 
								 | 
							
								    rx_info->phy.phase = phase;
							 | 
						||
| 
								 | 
							
								    rx_info->phy.band_id = (uint8_t)phy_band_id_get();
							 | 
						||
| 
								 | 
							
								    rx_info->phy.is_rf = 0; //TODO:
							 | 
						||
| 
								 | 
							
								    rx_info->phy.channel_id = 0; //TODO:
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    vdev->start_cfg.mac_data_rx_func(vdev->start_cfg.mac_callback_arg,
							 | 
						||
| 
								 | 
							
								            buf);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    return ERR_OK;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    err:
							 | 
						||
| 
								 | 
							
								    iot_pkt_free(buf);
							 | 
						||
| 
								 | 
							
								    return ERR_INVAL;
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								uint32_t mac_ckq_rx_and_ppm_sync(mac_pdev_t *pdev, mac_vdev_t *vdev,
							 | 
						||
| 
								 | 
							
								    rx_fc_msg_t *rx_fc_msg, iot_pkt_t *rx_buf)
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
								    if (!vdev) {
							 | 
						||
| 
								 | 
							
								        vdev = pdev->vdev[PLC_DEFAULT_VDEV];
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    /* ppm sync */
							 | 
						||
| 
								 | 
							
								#if (PLC_SUPPORT_CCO_ROLE == 0)
							 | 
						||
| 
								 | 
							
								    uint8_t *tmp = iot_pkt_block_ptr(rx_buf, IOT_PKT_BLOCK_DATA);
							 | 
						||
| 
								 | 
							
								    rx_mpdu_start *mpdu_st = (rx_mpdu_start *)(tmp + MPDU_START_OFFSET);
							 | 
						||
| 
								 | 
							
								    rx_mpdu_end *mpdu_ed = (rx_mpdu_end *)(tmp + MPDU_END_OFFSET);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    if (rx_fc_msg->sack_ext_deli == SACK_EXT_TYPE_SYNC
							 | 
						||
| 
								 | 
							
								        && vdev_get_tei(vdev) == PLC_TEI_CTRL) {
							 | 
						||
| 
								 | 
							
								        int16_t ppm_err = PLC_MAX_PPM_SUPPORT;
							 | 
						||
| 
								 | 
							
								        uint32_t rate_mode = \
							 | 
						||
| 
								 | 
							
								            mac_rx_mpdu_st_get_rx_rate_mode(mpdu_st);
							 | 
						||
| 
								 | 
							
								        uint32_t local_ts = \
							 | 
						||
| 
								 | 
							
								            mac_rx_mpdu_end_get_local_timestamp(mpdu_ed);
							 | 
						||
| 
								 | 
							
								        uint8_t est_ppm = \
							 | 
						||
| 
								 | 
							
								            mac_rx_mpdu_st_get_estimated_ppm(mpdu_st);
							 | 
						||
| 
								 | 
							
								        uint32_t ntb_ts = \
							 | 
						||
| 
								 | 
							
								            mac_rx_mpdu_end_get_ntb_timestamp(mpdu_ed);
							 | 
						||
| 
								 | 
							
								        (void)ntb_ts;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        mac_ntb_ppm_sync(&vdev->mac_ppm, rate_mode, \
							 | 
						||
| 
								 | 
							
								            rx_fc_msg->time_stamp, local_ts, ntb_ts,\
							 | 
						||
| 
								 | 
							
								            est_ppm, &ppm_err, SYNC_PERIOD_MS, true);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        nid_t my_nid = 0;
							 | 
						||
| 
								 | 
							
								        vdev_get_nid(vdev, &my_nid);
							 | 
						||
| 
								 | 
							
								        (void)mac_multi_ppm_record(pdev->pdev_id,
							 | 
						||
| 
								 | 
							
								            rx_fc_msg->nid, my_nid, rate_mode,
							 | 
						||
| 
								 | 
							
								            rx_fc_msg->time_stamp, local_ts,
							 | 
						||
| 
								 | 
							
								            ntb_ts, SYNC_PERIOD_MS, ppm_err);
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								#else
							 | 
						||
| 
								 | 
							
								    (void)rx_fc_msg;
							 | 
						||
| 
								 | 
							
								#endif
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    return mac_rx_ext_frame(vdev, rx_buf);
							 | 
						||
| 
								 | 
							
								}
							 |