192 lines
		
	
	
		
			6.0 KiB
		
	
	
	
		
			C
		
	
	
		
			Executable File
		
	
	
	
	
			
		
		
	
	
			192 lines
		
	
	
		
			6.0 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_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);
 | 
						|
}
 |