Files
kunlun/plc/halmac/hplc_ext/mac_hplc_ext.c
2024-09-28 14:24:04 +08:00

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