168 lines
5.4 KiB
C
Executable File
168 lines
5.4 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_config.h"
|
|
#include "nn_cco.h"
|
|
#include "iot_errno.h"
|
|
#include "iot_io.h"
|
|
#include "mac_tx_hw.h"
|
|
#include "tx_desc_reg_api.h"
|
|
#include "mpdu_header.h"
|
|
#include "phy_chn.h"
|
|
#include "mac_sched.h"
|
|
#include "beacon_frame.h"
|
|
#include "phy_txrx_pwr.h"
|
|
|
|
uint32_t mac_tx_nncco(pdevid_t pdev_id, \
|
|
uint32_t nid, /* if gp, fill in snid */\
|
|
uint32_t delimiter_type, \
|
|
uint32_t network_type, \
|
|
lid_t lid, \
|
|
uint32_t duration,\
|
|
uint64_t last_start_ntb,\
|
|
uint64_t start_ntb,\
|
|
uint32_t receive_nid,\
|
|
phase_t phase)
|
|
{
|
|
#if PLC_MAC_TX_DEBUG_LOG
|
|
iot_printf("%s\n", __FUNCTION__);
|
|
#endif
|
|
|
|
uint32_t proto = PHY_PROTO_TYPE_GET();
|
|
uint8_t is_tx_3phase;
|
|
uint32_t tx_power = PHY_FULL_PWR_DBUV;
|
|
tx_mpdu_end *mpdu_end;
|
|
tx_mpdu_start *mpdu;
|
|
mac_queue_t swq_id;
|
|
uint8_t hwqid;
|
|
mac_pdev_t *pdev = g_mac_pdev[pdev_id];
|
|
mac_vdev_t *vdev = pdev->vdev[PLC_DEFAULT_VDEV];
|
|
|
|
/* But we need to select the biggest csma phase
|
|
* quota if PLC_PHASE_ALL
|
|
*/
|
|
if (phase == PLC_PHASE_ALL) {
|
|
is_tx_3phase = true;
|
|
if (ERR_OK
|
|
!= mac_beacon_cal_biggest_csma_phase(&vdev->bcn_ctx, &phase)) {
|
|
// if not ready, use A for default phase
|
|
phase = PLC_PHASE_A;
|
|
} else {
|
|
if (phase == PLC_PHASE_ALL) {
|
|
// should not ALL is the biggest
|
|
IOT_ASSERT(0);
|
|
phase = PLC_PHASE_A;
|
|
}
|
|
}
|
|
} else {
|
|
is_tx_3phase = false;
|
|
}
|
|
|
|
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 swq type id */
|
|
swq_id = mac_q_get_swq_type(PLC_BCN_REGION_CSMA, \
|
|
phase, lid);
|
|
/* check if swq type is support */
|
|
if (swq_id == MAX_MAC_QUE_NUM)
|
|
{
|
|
/* swq type error */
|
|
IOT_ASSERT(0);
|
|
}
|
|
/* check if the hwq already enabled */
|
|
hwqid = mac_q_get_hwqid(&pdev->hwq_hdl, swq_id);
|
|
if (hwqid == INV_MAC_HWQ_ID) {
|
|
/* hw queue is not enabled, try to alloc it */
|
|
hwqid = mac_q_alloc_hwq(&pdev->hwq_hdl, swq_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, tx_power,
|
|
is_tx_3phase ? PLC_PHASE_ALL : phase, \
|
|
phy_def_hw_band_id_get(), \
|
|
0, 0, 0, 0);
|
|
|
|
uint32_t rec_nid = receive_nid;
|
|
uint32_t net_tp = network_type;
|
|
|
|
if (PLC_PROTO_TYPE_SPG == proto) {
|
|
/* NW meas bitmap*/
|
|
rec_nid = mac_sched_get_nidmap(pdev->vdev[0]);
|
|
/* NW this field always 1, means whether in broadband */
|
|
net_tp = 1;
|
|
}
|
|
|
|
/* rawdata fc */
|
|
nncco_fc_info_t nn_fc_info = { 0 };
|
|
nn_fc_info.delimiter = delimiter_type;
|
|
|
|
/* for war nncco */
|
|
#if ENA_WAR_NNCCO_FEAT
|
|
uint8_t fc_rawdata[16] = {0};
|
|
|
|
nn_fc_info.start_ntb_h24 = ((uint32_t)(start_ntb >> 32) & 0xFFFFFF);
|
|
nn_fc_info.start_ntb_l32 = (uint32_t)(start_ntb & 0xFFFFFFFF);
|
|
nn_fc_info.sw_receive_nid = rec_nid;
|
|
nn_fc_info.sw_duration = duration;
|
|
nn_fc_info.last_offset = (uint32_t)(start_ntb - last_start_ntb);
|
|
|
|
/* fill fcinfo variable region */
|
|
mac_fill_nncco_variable_fcinfo(proto, fc_rawdata, &nn_fc_info);
|
|
|
|
/*fill fcinfo rawdata*/
|
|
mac_tx_mpdu_fill_fcinfo(\
|
|
mpdu, proto, 0, phase, delimiter_type, \
|
|
net_tp, nid, 0, 0, 0, \
|
|
0xfff, 0, 0, 0, 0, 0, 0 , 0, fc_rawdata);
|
|
#else
|
|
/* for kl2, we use this field for next protection region
|
|
* start ntb; for kl1, this field is no effect for SG/PSG
|
|
*/
|
|
void *fc = mac_tx_mpdu_start_get_fc_ptr(mpdu);
|
|
mac_tx_mpdu_start_set_hp10_fc(mpdu, start_ntb & 0xFFFFFFFF);
|
|
mac_tx_mpdu_start_set_ts_high_bit(mpdu, (start_ntb >> 32));
|
|
|
|
nn_fc_info.duration = duration;
|
|
nn_fc_info.receive_nid = rec_nid;
|
|
nn_fc_info.sbandoffset = 0;
|
|
nn_fc_info.self_rf_channel = mac_rf_get_self_channel(vdev->mac_rf);
|
|
nn_fc_info.self_rf_option = mac_rf_get_self_option(vdev->mac_rf);
|
|
|
|
mac_tx_mpdu_start_set_pre_low_ntb(mpdu, last_start_ntb & 0xFFFFFFFF);
|
|
mac_tx_mpdu_start_set_pre_high_ntb(mpdu, (last_start_ntb >> 32));
|
|
mac_fill_nncco_variable_fcinfo(proto, fc, &nn_fc_info);
|
|
|
|
/* fill fcinfo */
|
|
mac_tx_mpdu_fill_fcinfo(\
|
|
mpdu, proto, 0, phase, delimiter_type, \
|
|
net_tp, nid, 0, 0, 0, \
|
|
0xfff, 0, 0, 0, 0, 0, 0 , 0, NULL);
|
|
#endif
|
|
|
|
return mac_tx_hw_mpdu(&pdev->hwq_hdl, \
|
|
hwqid, mpdu);
|
|
}
|
|
|