544 lines
16 KiB
C
Executable File
544 lines
16 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 "sw_sched.h"
|
|
#include "iot_errno.h"
|
|
#include "mac_msg.h"
|
|
#include "mac.h"
|
|
#include "mac_hwq_mgr.h"
|
|
#include "mac_stream.h"
|
|
#include "mac_pdev.h"
|
|
#include "mac_desc_engine.h"
|
|
#include "hw_tonemap.h"
|
|
#include "rate_control.h"
|
|
#include "mac_tx_hw.h"
|
|
#include "mac_msdu.h"
|
|
#include "iot_bitops.h"
|
|
#include "phy_chn.h"
|
|
#include "iot_io.h"
|
|
#include "mac_peer.h"
|
|
#include "mac_tx_power.h"
|
|
#include "mac_rf.h"
|
|
|
|
mac_swq_t * g_mac_swq[MAX_MAC_QUE_NUM]={0};
|
|
|
|
#if HPLC_RF_DEV_SUPPORT
|
|
|
|
#include "mac_rf_common_hw.h"
|
|
#include "rf_hw_tonemap.h"
|
|
#include "rf_rate_control.h"
|
|
|
|
mac_swq_t * g_mac_rf_swq[MAX_MAC_RF_QUE_NUM] = {0};
|
|
|
|
uint32_t mac_rf_swsch_init()
|
|
{
|
|
uint32_t type;
|
|
iot_printf("%s\n", __FUNCTION__);
|
|
|
|
for (type = 0; type < MAX_MAC_RF_QUE_NUM; type++) {
|
|
g_mac_rf_swq[type] = os_mem_malloc(PLC_MAC_SHC_MID,
|
|
sizeof(mac_swq_t));
|
|
IOT_ASSERT(g_mac_rf_swq[type]);
|
|
g_mac_rf_swq[type]->q_depth = 0;
|
|
iot_list_init(&g_mac_rf_swq[type]->stream_list);
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
uint32_t mac_rf_swsch_trigger_tx(pdevid_t rf_pdev_id, vdevid_t rf_vdev_id)
|
|
{
|
|
uint32_t ret = ERR_OK;
|
|
mac_rf_vdev_t *rf_vdev = get_rf_vdev_ptr(PLC_PDEV_ID, rf_pdev_id,
|
|
rf_vdev_id);
|
|
|
|
IOT_ASSERT(rf_vdev);
|
|
if (rf_vdev->stop_flag == 0) {
|
|
//iot_printf("%s\n", __FUNCTION__);
|
|
mac_msg_t *msg = mac_alloc_msg();
|
|
if (msg == NULL) {
|
|
IOT_ASSERT(0);
|
|
ret = ERR_NOMEM;
|
|
goto out;
|
|
}
|
|
msg->type = MAC_MSG_TYPE_SCH;
|
|
msg->id = MAC_MSG_ID_SCH_TX;
|
|
msg->data1 = (((uint32_t)rf_pdev_id) << 8) | rf_vdev_id;
|
|
msg->data2 = NULL;
|
|
msg->data3 = NULL;
|
|
|
|
mac_queue_msg(msg, MAC_MSG_QUEUE_HP);
|
|
} else {
|
|
ret = ERR_FAIL;
|
|
}
|
|
out:
|
|
return ret;
|
|
}
|
|
|
|
uint32_t mac_rf_swsch_tx_msdu(mac_rf_pdev_t *rf_pdev, mac_msdu_t *msdu,
|
|
uint32_t delimiter_type, tei_t dtei, lid_t lid, uint8_t is_bcast)
|
|
{
|
|
uint8_t blkz = 0;
|
|
uint32_t pbsz = 0;
|
|
uint8_t phr_mcs = 0;
|
|
uint8_t mcs = 0;
|
|
nid_t nid = 0;
|
|
mac_vdev_t *vdev = NULL;
|
|
uint32_t option = mac_rf_get_self_option();
|
|
/* get msdu len && all pb num */
|
|
uint32_t msdu_len = iot_pkt_data_len(msdu->buf);
|
|
/* get block size, pb size, phy header mcs , plc mcs */
|
|
mac_rf_data_get_rate(msdu_len, option, is_bcast, &blkz, &phr_mcs, &mcs,
|
|
msdu->retry_cnt, dtei);
|
|
|
|
pbsz = phy_rf_get_pbsz(blkz);
|
|
|
|
if (msdu->is_dbg_pkt) {
|
|
mac_pdev_t *pdev = get_pdev_ptr(rf_pdev->parent_pdev_id);
|
|
vdev = get_vdev_ptr(rf_pdev->parent_pdev_id, pdev->dbg_pkt_vdev_id);
|
|
} else {
|
|
vdev = get_vdev_ptr(rf_pdev->parent_pdev_id, PLC_DEFAULT_VDEV);
|
|
}
|
|
|
|
tei_t stei = vdev_get_tei(vdev);
|
|
|
|
/* get nid */
|
|
vdev_get_nid(vdev, &nid);
|
|
|
|
return mac_tx_rf_msdu(rf_pdev, msdu, option, delimiter_type, dtei,
|
|
lid, is_bcast, nid, stei, blkz, pbsz, phr_mcs, mcs, msdu_len);
|
|
}
|
|
|
|
#endif /* HPLC_RF_DEV_SUPPORT */
|
|
|
|
mac_swq_t * mac_swsch_get_g_swq(uint32_t swq_id, uint32_t is_rf)
|
|
{
|
|
mac_swq_t *swq = NULL;
|
|
|
|
#if HPLC_RF_DEV_SUPPORT
|
|
swq = ((is_rf) ? g_mac_rf_swq[(swq_id)] : g_mac_swq[(swq_id)]);
|
|
#else /* HPLC_RF_DEV_SUPPORT */
|
|
swq = ((is_rf) ? NULL : g_mac_swq[(swq_id)]);
|
|
#endif /* HPLC_RF_DEV_SUPPORT */
|
|
|
|
return swq;
|
|
}
|
|
|
|
uint32_t mac_swsch_init()
|
|
{
|
|
uint32_t type;
|
|
iot_printf("%s\n", __FUNCTION__);
|
|
#if 1
|
|
for(type = 0; type < MAX_MAC_QUE_NUM; type++)
|
|
{
|
|
g_mac_swq[type] = os_mem_malloc(PLC_MAC_SHC_MID,sizeof(mac_swq_t));
|
|
IOT_ASSERT(g_mac_swq[type]);
|
|
g_mac_swq[type]->q_depth = 0;
|
|
iot_list_init(&g_mac_swq[type]->stream_list);
|
|
}
|
|
#endif
|
|
return 0;
|
|
}
|
|
|
|
uint32_t mac_swsch_trigger_tx(pdevid_t pdev_id, vdevid_t vdev_id)
|
|
{
|
|
/* send a MAC_MSG_TYPE_SCH : MAC_MSG_ID_SCH_TX*/
|
|
|
|
uint32_t ret = 0;
|
|
mac_vdev_t * vdev = g_mac_pdev[pdev_id]->vdev[vdev_id];
|
|
if(vdev->stop_flag == 0){
|
|
//iot_printf("%s\n", __FUNCTION__);
|
|
mac_msg_t *msg = mac_alloc_msg();
|
|
if (msg == NULL) {
|
|
IOT_ASSERT(0);
|
|
ret = ERR_NOMEM;
|
|
goto out;
|
|
}
|
|
msg->type = MAC_MSG_TYPE_SCH;
|
|
msg->id = MAC_MSG_ID_SCH_TX;
|
|
msg->data1 = (((uint32_t)pdev_id) << 8) | vdev_id;
|
|
msg->data2 = NULL;
|
|
msg->data3 = NULL;
|
|
|
|
mac_queue_msg(msg, MAC_MSG_QUEUE_HP);
|
|
}
|
|
out:
|
|
return ret;
|
|
|
|
}
|
|
|
|
uint32_t mac_swsch_append(mac_swq_t *swq, phase_t phase, mac_stream_t *node)
|
|
{
|
|
/* TODO: */
|
|
IOT_ASSERT(swq && node);
|
|
|
|
if (iot_list_empty(&swq->stream_list))
|
|
{
|
|
/* if empty */
|
|
IOT_ASSERT(0 == swq->q_depth);
|
|
}
|
|
if (node->in_swq == 0) {
|
|
/* add prev head, i.e. put to the last */
|
|
iot_list_add_prev(&node->msdu.tx.swq_node, &swq->stream_list);
|
|
swq->q_depth++;
|
|
node->phase_in_swq = phase;
|
|
node->in_swq = 1;
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
uint32_t mac_swsch_remove(mac_swq_t *swq, mac_stream_t *node)
|
|
{
|
|
/* TODO: */
|
|
IOT_ASSERT(swq && node);
|
|
if (!iot_list_empty(&swq->stream_list))
|
|
{
|
|
/* if not empty */
|
|
IOT_ASSERT(swq->q_depth > 0 && node->in_swq == 1);
|
|
iot_list_del(&node->msdu.tx.swq_node);
|
|
swq->q_depth--;
|
|
node->in_swq = 0;
|
|
node->phase_in_swq = PLC_PHASE_ALL;
|
|
}
|
|
else {
|
|
/* already empty */
|
|
IOT_ASSERT(0);
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
uint32_t mac_swsch_del_stream(void *stream)
|
|
{
|
|
mac_stream_t *str = (mac_stream_t *)stream;
|
|
mac_swq_t *swq_ptr = NULL;
|
|
uint32_t swq_id;
|
|
|
|
if(str->in_swq == 1) {
|
|
str->in_swq = 0;
|
|
uint32_t bcn_region_type = mac_get_bcn_region_type(str->lid);
|
|
if (str->is_rf) {
|
|
swq_id = (uint32_t)mac_rf_q_get_swq_type(bcn_region_type,
|
|
str->lid, (str->is_tx == IS_DBG_TX_STREAM));
|
|
} else {
|
|
swq_id = (uint32_t)mac_q_get_swq_type(bcn_region_type,
|
|
str->phase_in_swq, str->lid);
|
|
}
|
|
swq_ptr = mac_swsch_get_g_swq(swq_id, str->is_rf);
|
|
IOT_ASSERT(swq_ptr);
|
|
if (swq_ptr->q_depth > 0) {
|
|
//TODO: focus on the reason
|
|
swq_ptr->q_depth--;
|
|
iot_list_del(&str->msdu.tx.swq_node);
|
|
str->in_swq = 0;
|
|
str->phase_in_swq = PLC_PHASE_ALL;
|
|
}
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
uint32_t mac_swsch_tx_msdu(pdevid_t pdev_id, vdevid_t vdev_id,
|
|
mac_msdu_t *msdu,uint32_t delimiter_type,
|
|
uint32_t proto,uint32_t port)
|
|
{
|
|
mac_pdev_t *pdev;
|
|
mac_vdev_t *vdev;
|
|
uint32_t ret;
|
|
uint32_t pb_num_per_mpdu;
|
|
uint32_t mpdu_num_to_send;
|
|
uint32_t tmi, ext_tmi;
|
|
uint8_t rid;
|
|
uint32_t rate_mode;
|
|
uint32_t pb_sz, old_pb_sz;
|
|
uint32_t nid;
|
|
tei_t stei;
|
|
mac_stream_t *stream = msdu->ref_mac_stream;
|
|
mac_peer_t *peer = stream->peer;
|
|
tei_t dtei = (tei_t)peer->tei;
|
|
uint32_t lid = stream->lid;
|
|
uint32_t single_proto_band;
|
|
uint8_t is_fixed_rate;
|
|
uint32_t is_fixed_pbsz;
|
|
uint32_t hw_band_id;
|
|
|
|
pdev = get_pdev_ptr(pdev_id);
|
|
if (msdu->is_dbg_pkt) {
|
|
vdev = get_vdev_ptr(pdev_id, pdev->dbg_pkt_vdev_id);
|
|
} else {
|
|
vdev = get_vdev_ptr(pdev_id, vdev_id);
|
|
}
|
|
|
|
stei = vdev_get_tei(vdev);
|
|
|
|
IOT_ASSERT(stream->msdu.tx.cur_tx_msdu);
|
|
uint8_t is_bcast =\
|
|
(uint8_t)stream->msdu.tx.cur_tx_msdu->is_bcast;
|
|
phase_t phase =\
|
|
(uint8_t)stream->msdu.tx.cur_tx_msdu->phase;
|
|
uint32_t pkt_len = iot_pkt_data_len(msdu->buf);
|
|
|
|
/* get nid */
|
|
ret = vdev_get_nid(vdev, &nid);
|
|
//TODO: need fix swsch trigger logic, need check vdev.
|
|
//IOT_ASSERT(ERR_OK == ret);
|
|
|
|
hw_band_id = mac_tx_hw_band_id_get(vdev,
|
|
phy_band_id_get(), msdu->retry_cnt);
|
|
single_proto_band = phy_hw_band_to_proto_band(hw_band_id);
|
|
|
|
/* get the rate for this mpdu */
|
|
if (!is_bcast) {
|
|
/* if uni-cast */
|
|
if (!vdev_get_fixed_rate(vdev)) {
|
|
is_fixed_rate = false;
|
|
} else {
|
|
is_fixed_rate = true;
|
|
}
|
|
if (msdu->fix_rate) {
|
|
is_fixed_rate = true;
|
|
}
|
|
#if (PLC_SUPPORT_STA_TX_3_PHASE)
|
|
if (dtei == PLC_TEI_CCO) {
|
|
is_fixed_rate = true;
|
|
}
|
|
#endif
|
|
/* only first send, allow choose the pbsz */
|
|
is_fixed_pbsz = (msdu->retry)?1:0;
|
|
ret = mac_data_get_rate(vdev, peer, proto, is_fixed_rate, pkt_len,\
|
|
single_proto_band, is_fixed_pbsz, &rid, &pb_num_per_mpdu, \
|
|
&mpdu_num_to_send, &rate_mode, (uint8_t)msdu->retry_cnt);
|
|
}
|
|
else
|
|
{
|
|
ret = mac_data_get_bcast_rate(vdev, proto, true, pkt_len,
|
|
single_proto_band, msdu->retry_cnt, &rid, &rate_mode,
|
|
&mpdu_num_to_send, &pb_num_per_mpdu, msdu->is_dbg_pkt,
|
|
msdu->retry, msdu->rd_retry_cnt);
|
|
}
|
|
IOT_ASSERT(ret == 0);
|
|
|
|
/* get pbsz, tmi and ext emi if not GP */
|
|
phy_get_tmi_by_rid(proto, rid, &tmi, &ext_tmi);
|
|
phy_get_rt_pbsz(proto, rid, &pb_sz);
|
|
|
|
#if SUPPORT_SOUTHERN_POWER_GRID
|
|
if (PLC_PROTO_TYPE_SPG == proto) {
|
|
/* for spg, one mpdu should accommodate the msdu */
|
|
IOT_ASSERT((mac_get_sof_pb_valid_payload_sz(proto, pb_sz) \
|
|
* pb_num_per_mpdu * mpdu_num_to_send) >= pkt_len);
|
|
}
|
|
#endif
|
|
|
|
#if DBG_MAC_TX_RID
|
|
iot_printf("tx msdu 0x%x's r%d->r%d, bmp=0x%x\n",
|
|
msdu, msdu->rate_idx, rid, msdu->send_bitmap);
|
|
#endif
|
|
if (msdu->send_bitmap == 0xffffffff || msdu->rate_idx == MAX_RATE_IDX) {
|
|
/* first send */
|
|
msdu->rate_idx = rid;
|
|
}
|
|
else
|
|
{
|
|
if (msdu->rate_idx != rid) {
|
|
/* if selected tmi is not the same to
|
|
* the previous one, restart the send
|
|
*/
|
|
phy_get_rt_pbsz(proto, (uint8_t)msdu->rate_idx, &old_pb_sz);
|
|
|
|
if (pb_sz != old_pb_sz) {
|
|
msdu->retry = 0;
|
|
msdu->send_bitmap = 0xffffffff;
|
|
msdu->last_pos = 0;
|
|
iot_printf("change msdu 0x%x's pbsz %d->%d\n",
|
|
msdu, old_pb_sz, pb_sz);
|
|
}
|
|
msdu->rate_idx = rid;
|
|
}
|
|
}
|
|
|
|
if (!is_bcast && msdu->retry == 0) {
|
|
/* only one mpdu for the first send of ucast */
|
|
mpdu_num_to_send = 1;
|
|
}
|
|
|
|
return mac_tx_msdu(pdev, msdu, \
|
|
pb_sz, pb_num_per_mpdu, \
|
|
mpdu_num_to_send, \
|
|
delimiter_type, nid, \
|
|
stei, dtei, lid, is_bcast, \
|
|
phase, proto, port, \
|
|
tmi, ext_tmi, rate_mode, single_proto_band);
|
|
}
|
|
|
|
//load mac_frame_list to cur_msdu
|
|
uint32_t mac_load_msdu(mac_msdu_t * cur_msdu,
|
|
mac_stream_t *stream)
|
|
{
|
|
IOT_ASSERT(cur_msdu && stream);
|
|
mac_msdu_frame_t *msdu_list = \
|
|
stream->msdu.tx.mac_frame_list;
|
|
|
|
if (msdu_list && msdu_list->buf) {
|
|
/* if has frame in the queue */
|
|
mac_msdu_init(cur_msdu, 1, stream, \
|
|
msdu_list->buf, (uint8_t)msdu_list->retry_cnt);
|
|
cur_msdu->is_bcast = \
|
|
msdu_list->is_bcast;
|
|
cur_msdu->phase = \
|
|
msdu_list->phase;
|
|
cur_msdu->tx_3phase = msdu_list->tx_3phase;
|
|
cur_msdu->is_dbg_pkt = msdu_list->is_dbg_pkt;
|
|
cur_msdu->fix_rate = msdu_list->fix_rate;
|
|
cur_msdu->ppm_step = msdu_list->ppm_step;
|
|
cur_msdu->ppm_step_type = (uint8_t)msdu_list->ppm_step_type;
|
|
cur_msdu->need_encrypt = (uint8_t)msdu_list->need_encrypt;
|
|
cur_msdu->key_idx = msdu_list->key_idx;
|
|
/* remove the loaded mac_frame_t */
|
|
if (msdu_list->next == NULL) {
|
|
stream->msdu.tx.last_mac_frame = NULL;
|
|
}
|
|
stream->msdu.tx.mac_frame_list = msdu_list->next;
|
|
IOT_ASSERT(stream->msdu.tx.mac_frame_num > 0);
|
|
stream->msdu.tx.mac_frame_num--;
|
|
|
|
/* increase token number */
|
|
uint32_t bcn_region_type;
|
|
bcn_region_type = \
|
|
mac_get_bcn_region_type(stream->lid);
|
|
mac_token_free(bcn_region_type, stream->lid, stream->is_rf);
|
|
|
|
mac_desc_free(&g_mac_desc_eng, \
|
|
PLC_MAC_MSDU_FRAME_POOL, \
|
|
msdu_list);
|
|
return ERR_OK;
|
|
}
|
|
/* empty queue */
|
|
return ERR_FAIL;
|
|
}
|
|
|
|
static uint32_t mac_swsch_post_msdu_internal(uint32_t is_rf)
|
|
{
|
|
mac_stream_t *stream = NULL;
|
|
uint32_t ret = 0;
|
|
uint32_t swq_id;
|
|
uint32_t proto = PHY_PROTO_TYPE_GET();
|
|
uint32_t max_mac_queue_num = 0;
|
|
mac_swq_t *p_mac_swq = NULL;
|
|
pdevid_t pdev_id = PLC_PDEV_ID;
|
|
vdevid_t vdev_id = PLC_DEFAULT_VDEV;
|
|
|
|
mac_rf_pdev_t *rf_pdev = get_rf_pdev_ptr(pdev_id, RF_PDEV_ID);
|
|
|
|
max_mac_queue_num = is_rf ? MAX_MAC_RF_QUE_NUM : MAX_MAC_QUE_NUM;
|
|
for (swq_id = 0; swq_id < max_mac_queue_num; swq_id++) //go through all swq
|
|
{
|
|
nextstream:
|
|
p_mac_swq = mac_swsch_get_g_swq(swq_id, is_rf);
|
|
if (p_mac_swq->q_depth > 0) //swq have stream pending
|
|
{
|
|
iot_list_head_t * curr_swq_head = \
|
|
&p_mac_swq->stream_list;
|
|
/* should not empty */
|
|
IOT_ASSERT_DUMP(!iot_list_empty(curr_swq_head), \
|
|
&p_mac_swq->q_depth, 1);
|
|
|
|
/* get stream through list_head, get one node just after
|
|
* the head node
|
|
*/
|
|
stream = iot_list_entry(curr_swq_head->next, \
|
|
mac_stream_t, msdu.tx.swq_node);
|
|
|
|
if (NULL == stream->msdu.tx.cur_tx_msdu) {
|
|
/* not sending msdu before, alloc the msdu */
|
|
ret = \
|
|
mac_desc_get(&g_mac_desc_eng, PLC_MAC_MSDU_POOL, \
|
|
(void**)&stream->msdu.tx.cur_tx_msdu);
|
|
IOT_ASSERT(ret == 0);
|
|
}
|
|
|
|
mac_msdu_t *msdu = stream->msdu.tx.cur_tx_msdu;
|
|
if (msdu->buf)
|
|
{
|
|
if (!msdu->in_hwq) {
|
|
/* if not in hwq, retry the msdu */
|
|
if (!is_rf) {
|
|
ret = mac_swsch_tx_msdu(pdev_id, vdev_id, \
|
|
msdu, FC_DELIM_SOF, \
|
|
proto, \
|
|
HW_DESC_TX_PORT_PLC);
|
|
} else {
|
|
ret = mac_rf_swsch_tx_msdu(rf_pdev, msdu, FC_DELIM_SOF,
|
|
stream->peer->tei, stream->lid,
|
|
(uint8_t)msdu->is_bcast);
|
|
}
|
|
}
|
|
else {
|
|
/* if already in hwq, continue for next stream */
|
|
continue;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
/* first time sending of the packet */
|
|
ret = mac_load_msdu(msdu, stream);
|
|
if (ret == ERR_FAIL) {
|
|
/* if no msdu in this stream left, free
|
|
* the msdu desc in the stream to save
|
|
* some memory
|
|
*/
|
|
mac_msdu_deinit(msdu);
|
|
stream->msdu.tx.cur_tx_msdu = NULL;
|
|
/* if empty, remove the stream from the queue and
|
|
* then sch next swq. if the peer can del ,del it
|
|
*/
|
|
mac_peer_t *peer = stream->peer;
|
|
mac_swsch_remove(p_mac_swq, stream);
|
|
|
|
//TODO: confirm do we need delete temp peer when rf msdu ?
|
|
mac_peer_del_temp_peer(peer);
|
|
if(p_mac_swq->q_depth)
|
|
goto nextstream;
|
|
continue;
|
|
}
|
|
if (!is_rf) {
|
|
ret = mac_swsch_tx_msdu(pdev_id, vdev_id, \
|
|
msdu, FC_DELIM_SOF, \
|
|
proto, \
|
|
HW_DESC_TX_PORT_PLC);
|
|
} else {
|
|
ret = mac_rf_swsch_tx_msdu(rf_pdev, msdu, FC_DELIM_SOF,
|
|
stream->peer->tei, stream->lid,
|
|
(uint8_t)msdu->is_bcast);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
return ret;
|
|
}
|
|
|
|
uint32_t mac_swsch_post_msdu(pdevid_t pdev_id, vdevid_t vdev_id)
|
|
{
|
|
uint32_t ret = 0;
|
|
(void)pdev_id;
|
|
(void)vdev_id;
|
|
ret = mac_swsch_post_msdu_internal(0);
|
|
|
|
#if HPLC_RF_DEV_SUPPORT
|
|
ret = mac_swsch_post_msdu_internal(1);
|
|
#endif
|
|
|
|
return ret;
|
|
}
|
|
|