538 lines
18 KiB
C
538 lines
18 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 "beacon_frame.h"
|
||
|
#include "mac_reset.h"
|
||
|
#include "mac_sched.h"
|
||
|
#include "mac_sched_htbus.h"
|
||
|
#include "mac_cmn_hw.h"
|
||
|
#include "mac_crc.h"
|
||
|
#include "mpdu_header.h"
|
||
|
#include "rate_control.h"
|
||
|
#include "phy_txrx_pwr.h"
|
||
|
#include "plc_beacon_htbus.h"
|
||
|
#include "iot_config_api.h"
|
||
|
#include "iot_bitmap_api.h"
|
||
|
#include "iot_io_api.h"
|
||
|
#include "iot_dbglog_api.h"
|
||
|
#include "iot_dbglog_parser.h"
|
||
|
|
||
|
#if IOT_HTBUS_EN
|
||
|
|
||
|
static void mac_beacon_fill_buf_htbus(mac_beacon_ctx_t *bcn, uint8_t **tmp)
|
||
|
{
|
||
|
uint8_t *data = *tmp;
|
||
|
beacon_htbus_payload_fixed_header_t *plh;
|
||
|
beacon_htbus_entry_ts_t *tsh;
|
||
|
beacon_htbus_entry_ud_t *udh;
|
||
|
/* fill FC */
|
||
|
frame_control_t *fc = (frame_control_t *)data;
|
||
|
data += sizeof(frame_control_t);
|
||
|
if (bcn->beacon_component_enable[MAC_BC_FC_INFO]) {
|
||
|
fc->delimiter_type = FC_DELIM_BEACON;
|
||
|
fc->network_type = bcn->fc.net_type;
|
||
|
fc->nid = bcn->fc.nid;
|
||
|
fc->vf.bcn.time_stamp =
|
||
|
mac_sched_get_ntb((mac_vdev_t *)bcn->ref_vdev_ptr);
|
||
|
#if (MAC_SCHED_DEBUG || RUNTIME_DEBUG)
|
||
|
iot_printf("%s curr ntb:%lu, start ntb %lu, nid %lu phase %lu\n",
|
||
|
__FUNCTION__, fc->vf.bcn.time_stamp, bcn->ts_htbus.start_ntb,
|
||
|
bcn->fc.nid, bcn->fc.phase);
|
||
|
iot_dbglog_input(PLC_MAC_BEACON_MID, DBGLOG_INFO,
|
||
|
IOT_MAC_BEACON_TX_NTB_INFO, 4, fc->vf.bcn.time_stamp,
|
||
|
bcn->ts_htbus.start_ntb, bcn->fc.nid, bcn->fc.phase);
|
||
|
#endif
|
||
|
|
||
|
fc->vf.bcn.src_tei = vdev_get_tei(bcn->ref_vdev_ptr);
|
||
|
fc->vf.bcn.sym_num = 0; /* filled by HW */
|
||
|
fc->vf.bcn.phase_num = bcn->fc.phase;
|
||
|
} else {
|
||
|
IOT_ASSERT(0);
|
||
|
}
|
||
|
|
||
|
/* fill in beacon payload fixed header */
|
||
|
plh = (beacon_htbus_payload_fixed_header_t *)data;
|
||
|
data += sizeof(*plh);
|
||
|
if (bcn->beacon_component_enable[MAC_BC_BMI_HTBUS_FIX_P]) {
|
||
|
plh->type = bcn->fp_htbus.type;
|
||
|
plh->reboot_cnt = bcn->fp_htbus.reboot_cnt;
|
||
|
plh->period_cnt = bcn->fp_htbus.req_period_cnt;
|
||
|
plh->beacon_entry_num = 0;
|
||
|
} else {
|
||
|
IOT_ASSERT(0);
|
||
|
}
|
||
|
|
||
|
/* fill in the time slot entry info */
|
||
|
if (bcn->beacon_component_enable[MAC_BC_BMI_HTBUS_TIME_SLOT] &&
|
||
|
mac_vdev_cfg_get_node_role(bcn->ref_vdev_ptr) == PLC_DEV_ROLE_CCO) {
|
||
|
tsh = (beacon_htbus_entry_ts_t *)data;
|
||
|
tsh->hdr.entry_type = MAC_BCN_HTBUS_ENTRY_TYPE_ID_TS;
|
||
|
|
||
|
tsh->cco_slot_dur = bcn->ts_htbus.cco_slot;
|
||
|
tsh->sta_slot_dur = bcn->ts_htbus.sta_slot;
|
||
|
tsh->start_ntb = bcn->ts_htbus.start_ntb;
|
||
|
|
||
|
tsh->bm_len = (iot_bitmap_fls(bcn->ts_htbus.rsp_bm,
|
||
|
sizeof(bcn->ts_htbus.rsp_bm)) + 7) >> 3;
|
||
|
os_mem_cpy(tsh->rsp_bm, bcn->ts_htbus.rsp_bm, tsh->bm_len);
|
||
|
|
||
|
tsh->hdr.entry_len = sizeof(*tsh) + tsh->bm_len;
|
||
|
data += tsh->hdr.entry_len;
|
||
|
plh->beacon_entry_num++;
|
||
|
}
|
||
|
|
||
|
/* fill user data entry info */
|
||
|
if (bcn->beacon_component_enable[MAC_BC_BMI_HTBUS_USER_DATA]) {
|
||
|
udh = (beacon_htbus_entry_ud_t *)data;
|
||
|
udh->hdr.entry_type = MAC_BCN_HTBUS_ENTRY_TYPE_ID_UD;
|
||
|
os_mem_cpy(udh->data, bcn->ud_htbus.data_ptr, bcn->ud_htbus.len);
|
||
|
udh->hdr.entry_len = sizeof(*udh) + bcn->ud_htbus.len;
|
||
|
data += udh->hdr.entry_len;
|
||
|
plh->beacon_entry_num++;
|
||
|
}
|
||
|
*tmp = data;
|
||
|
}
|
||
|
|
||
|
static void mac_beacon_fill_pld_icv_htbus(uint32_t proto,
|
||
|
uint8_t *data, iot_pkt_t *bcn_buf)
|
||
|
{
|
||
|
IOT_ASSERT(data);
|
||
|
uint8_t fc_len = mac_get_mpdu_fc_len(proto);
|
||
|
|
||
|
switch (proto) {
|
||
|
case PLC_PROTO_TYPE_SG:
|
||
|
{
|
||
|
beacon_payload_icv_t *icv = NULL;
|
||
|
icv = (beacon_payload_icv_t *)data;
|
||
|
icv->icv = iot_getcrc32(iot_pkt_data(bcn_buf) + fc_len,
|
||
|
(uint32_t)(data - iot_pkt_data(bcn_buf) - fc_len));
|
||
|
break;
|
||
|
}
|
||
|
default:
|
||
|
IOT_ASSERT(0);
|
||
|
break;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
static void mac_beacon_fill_fc_tmi_htbus(uint32_t proto, frame_control_t *fc,
|
||
|
uint32_t tmi)
|
||
|
{
|
||
|
IOT_ASSERT(fc);
|
||
|
|
||
|
switch (proto) {
|
||
|
case PLC_PROTO_TYPE_SG:
|
||
|
{
|
||
|
fc->vf.bcn.tmi = tmi & 0xf;
|
||
|
break;
|
||
|
}
|
||
|
default:
|
||
|
IOT_ASSERT(0);
|
||
|
break;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
static void mac_beacon_calc_rate_htbus(uint32_t beacon_len,
|
||
|
uint32_t *tmi, uint32_t *pb_size, uint32_t *rate_mode)
|
||
|
{
|
||
|
if (beacon_len > 136) {
|
||
|
*tmi = 1;
|
||
|
*pb_size = 520;
|
||
|
} else {
|
||
|
*tmi = 2;
|
||
|
*pb_size = 136;
|
||
|
}
|
||
|
*rate_mode = 0;
|
||
|
}
|
||
|
|
||
|
static uint8_t mac_beacon_tx_htbus(uint32_t proto, uint32_t proto_band_id,
|
||
|
mac_beacon_ctx_t *bcn, iot_pkt_t *bcn_buf)
|
||
|
{
|
||
|
uint32_t tmi;
|
||
|
uint32_t rate_mode;
|
||
|
uint32_t tx_power = PHY_FULL_PWR_DBUV;
|
||
|
uint32_t pb_size;
|
||
|
uint8_t *tmp = iot_pkt_data(bcn_buf);
|
||
|
uint8_t bc_pb_crc_len = mac_get_pb_crc_len(FC_DELIM_BEACON, proto);
|
||
|
uint8_t bc_pld_icv_len = 0;
|
||
|
uint8_t fc_len = mac_get_mpdu_fc_len(proto);
|
||
|
void *fc = (void *)tmp;
|
||
|
os_mem_set(tmp, 0, iot_pkt_block_len(bcn_buf, IOT_PKT_BLOCK_DATA) +
|
||
|
iot_pkt_block_len(bcn_buf, IOT_PKT_BLOCK_TAIL));
|
||
|
mac_beacon_fill_buf_htbus(bcn, &tmp);
|
||
|
bc_pld_icv_len = sizeof(beacon_payload_icv_t);
|
||
|
|
||
|
uint32_t bcn_len;
|
||
|
/* bcn_len is payload length for mac_bcn_get_rate, not including FC */
|
||
|
bcn_len = tmp - iot_pkt_data(bcn_buf) + bc_pld_icv_len +
|
||
|
bc_pb_crc_len - fc_len;
|
||
|
|
||
|
mac_beacon_calc_rate_htbus(bcn_len, &tmi, &pb_size, &rate_mode);
|
||
|
|
||
|
IOT_ASSERT(bcn_len <= pb_size);
|
||
|
|
||
|
tmp = iot_pkt_data(bcn_buf) + fc_len + pb_size -
|
||
|
bc_pb_crc_len - bc_pld_icv_len;
|
||
|
|
||
|
/* fill icv */
|
||
|
mac_beacon_fill_pld_icv_htbus(proto, tmp, bcn_buf);
|
||
|
tmp += bc_pld_icv_len;
|
||
|
/* fill the correct tmi now, as the bcn len is got into consideration */
|
||
|
mac_beacon_fill_fc_tmi_htbus(proto, fc, tmi);
|
||
|
|
||
|
IOT_ASSERT(iot_pkt_set_tail(bcn_buf, tmp));
|
||
|
|
||
|
mac_send_bcn(proto, proto_band_id,
|
||
|
((mac_vdev_t *)bcn->ref_vdev_ptr)->ref_pdev_id,
|
||
|
bcn_buf, rate_mode, bcn->fc.phase, 0, tx_power);
|
||
|
|
||
|
return 1;
|
||
|
}
|
||
|
|
||
|
#if PLC_SUPPORT_CCO_ROLE
|
||
|
|
||
|
/* htbus cco only beacon update handling */
|
||
|
static uint8_t mac_update_beacon_cco_htbus(uint32_t proto, mac_vdev_t *vdev,
|
||
|
mac_bc_update_t *ent)
|
||
|
{
|
||
|
uint64_t tmp;
|
||
|
uint8_t tx_cnt = 0;
|
||
|
|
||
|
/* below fields need to be updated for every beacon by mac layer
|
||
|
* 1. request period count
|
||
|
* 2. request period start ntb
|
||
|
*/
|
||
|
if (ent->new_bp_req) {
|
||
|
if (!vdev->bcn_ctx.cco.started) {
|
||
|
mac_sched_stop(vdev);
|
||
|
vdev->bcn_ctx.cco.started = 1;
|
||
|
mac_config_tei(vdev, vdev_get_tei(vdev));
|
||
|
}
|
||
|
/* apply the next beacon period schedule into HW */
|
||
|
tmp = mac_sched_get_ntb64(vdev);
|
||
|
tmp += MAC_MS_TO_NTB(MAC_BP_AHEAD_NEXT_BP_DUR);
|
||
|
|
||
|
/* config scheduler for next beacon period */
|
||
|
mac_sched_cco_set_htbus(vdev, &vdev->bcn_ctx.ts_htbus, tmp);
|
||
|
|
||
|
/* update request period count */
|
||
|
vdev->bcn_ctx.cco.curr_bp_cnt++;
|
||
|
if (vdev->bcn_ctx.cco.curr_bp_cnt > 0xFFFF) {
|
||
|
vdev->bcn_ctx.cco.curr_bp_cnt = 1;
|
||
|
}
|
||
|
vdev->bcn_ctx.fp_htbus.req_period_cnt =
|
||
|
(uint16_t)vdev->bcn_ctx.cco.curr_bp_cnt;
|
||
|
|
||
|
/* update start ntb */
|
||
|
vdev->bcn_ctx.ts_htbus.start_ntb = tmp;
|
||
|
|
||
|
/* update tx phase */
|
||
|
vdev->bcn_ctx.fc.phase = vdev->l_phase1;
|
||
|
|
||
|
/* trigger new beacon tx */
|
||
|
tx_cnt = mac_beacon_tx_htbus(proto, phy_proto_single_band_id_get(),
|
||
|
&vdev->bcn_ctx, vdev->bcn_ctx.mac_beacon_buffer[0]);
|
||
|
}
|
||
|
return tx_cnt;
|
||
|
}
|
||
|
|
||
|
#else /* PLC_SUPPORT_CCO_ROLE */
|
||
|
|
||
|
#define mac_update_beacon_cco_htbus(proto, vdev, ent) (0)
|
||
|
|
||
|
#endif /* PLC_SUPPORT_CCO_ROLE */
|
||
|
|
||
|
/* sta only beacon update handling */
|
||
|
static uint8_t mac_update_beacon_sta_htbus(uint32_t proto, mac_vdev_t *vdev,
|
||
|
mac_bc_update_t *ent)
|
||
|
{
|
||
|
uint64_t curr_ntb;
|
||
|
uint32_t end_ntb;
|
||
|
uint8_t tx_cnt = 0;
|
||
|
uint32_t resp_slot_cnt;
|
||
|
mac_beacon_ctx_t *bcn_ctx = &vdev->bcn_ctx;
|
||
|
|
||
|
#if DEBUG_HWQ_SHCED_HANG
|
||
|
mac_pdev_t *pdev = get_pdev_ptr(PLC_PDEV_ID);
|
||
|
pdev->dbg_status = MAC_TX_HANG_STATUS_4;
|
||
|
#endif
|
||
|
/* stop HW scheduler first if it's running */
|
||
|
mac_sched_stop(vdev);
|
||
|
|
||
|
#if DEBUG_HWQ_SHCED_HANG
|
||
|
pdev->dbg_status = MACC_TX_HANG_STATUS_MAX;
|
||
|
#endif
|
||
|
|
||
|
if (bcn_ctx->sta.ntb_sync_done == 0) {
|
||
|
/* config HW to sync up the NTB with the preferred network. */
|
||
|
if (bcn_ctx->fc.delta_ntb) {
|
||
|
mac_sched_sync_ntb(vdev, 0, bcn_ctx->fc.delta_ntb);
|
||
|
}
|
||
|
mac_zc_set_func_cmd(vdev->ref_pdev_id, MAC_ZC_FUNC_CMD_RESET_HW, NULL);
|
||
|
bcn_ctx->sta.ntb_sync_done = 1;
|
||
|
} else if (bcn_ctx->sta.force_sw_sync) {
|
||
|
/* config HW to sync up the NTB with the preferred network. */
|
||
|
if (bcn_ctx->fc.delta_ntb) {
|
||
|
mac_sched_sync_ntb(vdev, 0, bcn_ctx->fc.delta_ntb);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
curr_ntb = mac_sched_get_ntb64(vdev);
|
||
|
resp_slot_cnt = iot_bitmap_cbs((uint8_t *)&bcn_ctx->ts_htbus.rsp_bm,
|
||
|
sizeof(bcn_ctx->ts_htbus.rsp_bm));
|
||
|
end_ntb = bcn_ctx->ts_htbus.start_ntb +
|
||
|
MAC_MS_TO_NTB(bcn_ctx->ts_htbus.cco_slot +
|
||
|
resp_slot_cnt * bcn_ctx->ts_htbus.sta_slot);
|
||
|
|
||
|
if ((end_ntb - iot_uint64_lower32(curr_ntb)) >= 0x7FFFFFFF) {
|
||
|
/* current beacon period is obsolete */
|
||
|
iot_printf("%s bp already expired start_ntb %lu, "
|
||
|
"end_ntb %lu, curr_ntb %lu\n", __FUNCTION__,
|
||
|
bcn_ctx->ts_htbus.start_ntb, end_ntb,
|
||
|
iot_uint64_lower32(curr_ntb));
|
||
|
/* config a csma only command list to enable scheduler */
|
||
|
mac_sched_set_csma_only(vdev, curr_ntb, 0);
|
||
|
} else {
|
||
|
/* apply the next beacon period schedule into HW, at least enable tx
|
||
|
* for local logical phase.
|
||
|
*/
|
||
|
mac_sched_sta_set_htbus(vdev, &vdev->bcn_ctx.ts_htbus,
|
||
|
bcn_ctx->ts_htbus.start_ntb);
|
||
|
|
||
|
/* check if a new beacon tx is required for the update beacon
|
||
|
* template. for cco role device, always delay the new beacon tx
|
||
|
* to the periodical beacon phase.
|
||
|
*/
|
||
|
if (ent->tx_req) {
|
||
|
/* always use local phase for beacon tx */
|
||
|
vdev->bcn_ctx.fc.phase = vdev->l_phase1;
|
||
|
tx_cnt = mac_beacon_tx_htbus(proto, phy_proto_single_band_id_get(),
|
||
|
&vdev->bcn_ctx, vdev->bcn_ctx.mac_beacon_buffer[0]);
|
||
|
}
|
||
|
}
|
||
|
return tx_cnt;
|
||
|
}
|
||
|
|
||
|
static uint32_t mac_beacon_rx_icv_get_htbus(uint8_t proto, iot_pkt_t* buf)
|
||
|
{
|
||
|
uint32_t bcn_icv = 0;
|
||
|
IOT_ASSERT(buf);
|
||
|
|
||
|
switch (proto) {
|
||
|
#if SUPPORT_SMART_GRID
|
||
|
case PLC_PROTO_TYPE_SG:
|
||
|
{
|
||
|
beacon_payload_icv_t *icv;
|
||
|
icv = (beacon_payload_icv_t*)(iot_pkt_block_ptr(buf, IOT_PKT_BLOCK_TAIL)
|
||
|
- sizeof(beacon_payload_icv_t) - SG_BCN_PB_CRC_LEN);
|
||
|
bcn_icv = icv->icv;
|
||
|
break;
|
||
|
}
|
||
|
#endif
|
||
|
default:
|
||
|
break;
|
||
|
}
|
||
|
|
||
|
return bcn_icv;
|
||
|
}
|
||
|
|
||
|
static void mac_beacon_rx_plh_get_htbus(uint8_t proto,
|
||
|
bcn_pld_hdr_t *msg, uint8_t *tmp)
|
||
|
{
|
||
|
IOT_ASSERT(msg);
|
||
|
beacon_htbus_payload_fixed_header_t *plh_htbus =
|
||
|
(beacon_htbus_payload_fixed_header_t *)tmp;
|
||
|
msg->beacon_type = plh_htbus->type;
|
||
|
msg->beacon_seq_num = (uint32_t)plh_htbus->period_cnt;
|
||
|
}
|
||
|
|
||
|
uint32_t mac_beacon_rx(uint8_t proto, void *vdev_ptr, iot_pkt_t *buf)
|
||
|
{
|
||
|
mac_vdev_t *vdev = (mac_vdev_t *)vdev_ptr;
|
||
|
uint8_t *tmp, new_bp = 0;
|
||
|
uint32_t i = 0;
|
||
|
uint32_t crc = 0;
|
||
|
uint32_t bcn_len, bcn_icv = 0;
|
||
|
mac_rx_info_t *rx_info;
|
||
|
uint32_t ret = ERR_OK;
|
||
|
bcn_pld_hdr_t plh = { 0 };
|
||
|
rx_fc_msg_t rx_fc = { 0 };
|
||
|
uint32_t bc_period_cnt;
|
||
|
|
||
|
if (!vdev || !buf) {
|
||
|
IOT_ASSERT(0);
|
||
|
ret = ERR_INVAL;
|
||
|
goto err;
|
||
|
}
|
||
|
|
||
|
if (vdev->start_cfg.mac_bc_rx_func == NULL) {
|
||
|
ret = ERR_NOT_READY;
|
||
|
goto err;
|
||
|
}
|
||
|
|
||
|
tmp = iot_pkt_block_ptr(buf, IOT_PKT_BLOCK_DATA);
|
||
|
rx_info = (mac_rx_info_t *)(tmp - sizeof(*rx_info));
|
||
|
|
||
|
/* check crc */
|
||
|
bcn_len = iot_pkt_block_len(buf, IOT_PKT_BLOCK_DATA);
|
||
|
#if PLC_MAC_RX_DEBUG_LOG
|
||
|
iot_printf("rx bcn len %d on band %d\n", bcn_len, rx_info->phy.band_id);
|
||
|
#endif
|
||
|
/* check beacon payload crc */
|
||
|
bcn_icv = mac_beacon_rx_icv_get_htbus(proto, buf);
|
||
|
ret = mac_crc_get_bcn_swcrc(proto, iot_pkt_data(buf), bcn_len, &crc);
|
||
|
if (ret == ERR_CRC_LEN) {
|
||
|
mem_dump((uint32_t *)buf, 21); // 4iot_pkt addr + 16desc + 1DW plod
|
||
|
goto err;
|
||
|
}
|
||
|
if (crc != bcn_icv) {
|
||
|
/* TODO: check with accurate len,
|
||
|
*/
|
||
|
mac_add_rx_bcn_err_cnt();
|
||
|
iot_printf("bcn crcerrcnt: %lu, bcn_icv=0x%x, crc_cal=0x%x \n",
|
||
|
mac_get_rx_bcn_err_cnt(), bcn_icv, crc);
|
||
|
#if PLC_HW_ISSUE_ASSERT_LEVEL <= PLC_HW_ISSUE_ASSERT_ALL
|
||
|
IOT_ASSERT(0);
|
||
|
#endif
|
||
|
ret = ERR_CRC_FAIL;
|
||
|
goto err;
|
||
|
}
|
||
|
|
||
|
/* get fixed header and fc info */
|
||
|
mac_beacon_rx_plh_get_htbus(proto, &plh, tmp);
|
||
|
mac_beacon_rx_fc_info_get(proto, rx_info, &rx_fc);
|
||
|
/* sync sta/pco's timestamp */
|
||
|
if ((mac_vdev_cfg_get_node_role(vdev) != PLC_DEV_ROLE_CCO) &&
|
||
|
(rx_fc.nid == vdev->bcn_ctx.fc.nid)) {
|
||
|
bc_period_cnt = vdev->bcn_ctx.fp_htbus.req_period_cnt;
|
||
|
|
||
|
if (bc_period_cnt == 0) {
|
||
|
/* always accept the first beacon */
|
||
|
i = 1;
|
||
|
} else {
|
||
|
i = plh.beacon_seq_num - bc_period_cnt;
|
||
|
}
|
||
|
if (i && i <= PLC_BCN_DUPLICATE_GUARD) {
|
||
|
/* new beacon period, sync up the time stamp and save the
|
||
|
* start ntb
|
||
|
*/
|
||
|
new_bp = 1;
|
||
|
#if (MAC_SCHED_DEBUG || RUNTIME_DEBUG)
|
||
|
iot_printf("%s bc recv ntb %lu, bc send ntb %lu, bp cnt %lu\n",
|
||
|
__FUNCTION__, mac_sched_get_ntb(vdev), rx_fc.time_stamp,
|
||
|
bc_period_cnt);
|
||
|
iot_dbglog_input(PLC_MAC_DATA_MID, DBGLOG_INFO,
|
||
|
IOT_MAC_BEACON_RX_NTB_INFO, 3, mac_sched_get_ntb(vdev),
|
||
|
rx_fc.time_stamp, bc_period_cnt);
|
||
|
#endif
|
||
|
}
|
||
|
}
|
||
|
|
||
|
mac_add_rx_bcn_upload_cnt();
|
||
|
vdev->start_cfg.mac_bc_rx_func(vdev->start_cfg.mac_callback_arg,
|
||
|
buf, new_bp);
|
||
|
|
||
|
goto out;
|
||
|
err:
|
||
|
iot_printf("%s error reason %d\n", __FUNCTION__, ret);
|
||
|
iot_pkt_free(buf);
|
||
|
out:
|
||
|
return ret;
|
||
|
}
|
||
|
|
||
|
uint32_t mac_update_beacon_internal(uint8_t pdev_id, uint8_t vdev_id,
|
||
|
mac_bc_update_t *ent, uint8_t *tx_cnt)
|
||
|
{
|
||
|
uint32_t ret = ERR_OK;
|
||
|
uint32_t i;
|
||
|
mac_vdev_t *vdev = NULL;
|
||
|
uint32_t proto = PHY_PROTO_TYPE_GET();
|
||
|
mac_beacon_ctx_t *bcn_ctxt;
|
||
|
|
||
|
*tx_cnt = 0;
|
||
|
vdev = get_vdev_ptr(pdev_id, vdev_id);
|
||
|
if (vdev == NULL) {
|
||
|
ret = ERR_INVAL;
|
||
|
goto out;
|
||
|
}
|
||
|
bcn_ctxt = &vdev->bcn_ctx;
|
||
|
|
||
|
/* alwasy disable optional beacon entry for each update by default */
|
||
|
bcn_ctxt->beacon_component_enable[MAC_BC_FC_INFO] = 0;
|
||
|
bcn_ctxt->beacon_component_enable[MAC_BC_BMI_HTBUS_FIX_P] = 0;
|
||
|
bcn_ctxt->beacon_component_enable[MAC_BC_BMI_HTBUS_TIME_SLOT] = 0;
|
||
|
bcn_ctxt->beacon_component_enable[MAC_BC_BMI_HTBUS_USER_DATA] = 0;
|
||
|
|
||
|
for (i = 0; i < ent->count; i++) {
|
||
|
switch (ent->entry[i].type) {
|
||
|
case MAC_BC_FC_INFO:
|
||
|
{
|
||
|
if (ent->action[i] == MAC_BC_ACT_ADD) {
|
||
|
os_mem_cpy(&bcn_ctxt->fc, ent->entry[i].data,
|
||
|
sizeof(bcn_ctxt->fc));
|
||
|
bcn_ctxt->fc.nid = mac_mask_input_nid(bcn_ctxt->fc.nid);
|
||
|
bcn_ctxt->beacon_component_enable[ent->entry[i].type] = 1;
|
||
|
}
|
||
|
break;
|
||
|
}
|
||
|
case MAC_BC_BMI_HTBUS_FIX_P:
|
||
|
{
|
||
|
if (ent->action[i] == MAC_BC_ACT_ADD) {
|
||
|
os_mem_cpy(&bcn_ctxt->fp_htbus, ent->entry[i].data,
|
||
|
sizeof(bcn_ctxt->fp_htbus));
|
||
|
bcn_ctxt->beacon_component_enable[ent->entry[i].type] = 1;
|
||
|
}
|
||
|
break;
|
||
|
}
|
||
|
case MAC_BC_BMI_HTBUS_TIME_SLOT:
|
||
|
{
|
||
|
if (ent->action[i] == MAC_BC_ACT_ADD) {
|
||
|
os_mem_cpy(&bcn_ctxt->ts_htbus, ent->entry[i].data,
|
||
|
sizeof(bcn_ctxt->ts_htbus));
|
||
|
bcn_ctxt->beacon_component_enable[ent->entry[i].type] = 1;
|
||
|
}
|
||
|
break;
|
||
|
}
|
||
|
case MAC_BC_BMI_HTBUS_USER_DATA:
|
||
|
{
|
||
|
if (ent->action[i] == MAC_BC_ACT_ADD) {
|
||
|
os_mem_cpy(&bcn_ctxt->ud_htbus, ent->entry[i].data,
|
||
|
sizeof(bcn_ctxt->ud_htbus));
|
||
|
bcn_ctxt->beacon_component_enable[ent->entry[i].type] = 1;
|
||
|
}
|
||
|
break;
|
||
|
}
|
||
|
default:
|
||
|
IOT_ASSERT(0);
|
||
|
break;
|
||
|
}
|
||
|
}
|
||
|
/* config NID to HW once the NID is available */
|
||
|
vdev_set_nid(vdev, bcn_ctxt->fc.nid);
|
||
|
|
||
|
if (mac_vdev_cfg_get_node_role(vdev) != PLC_DEV_ROLE_CCO) {
|
||
|
*tx_cnt = mac_update_beacon_sta_htbus(proto, vdev, ent);
|
||
|
} else {
|
||
|
*tx_cnt = mac_update_beacon_cco_htbus(proto, vdev, ent);
|
||
|
}
|
||
|
#if PLC_SUPPORT_DBG_PKT_MODE
|
||
|
vdev_set_block_dbg_pkt_4_rx_only(vdev, true);
|
||
|
#endif
|
||
|
|
||
|
out:
|
||
|
return ret;
|
||
|
}
|
||
|
|
||
|
#endif /* IOT_HTBUS_EN */
|