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