1013 lines
		
	
	
		
			28 KiB
		
	
	
	
		
			C
		
	
	
		
			Executable File
		
	
	
	
	
			
		
		
	
	
			1013 lines
		
	
	
		
			28 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.
 | 
						|
 | 
						|
****************************************************************************/
 | 
						|
 | 
						|
/* os shim includes */
 | 
						|
#include "os_types.h"
 | 
						|
#include "os_mem.h"
 | 
						|
#include "os_task.h"
 | 
						|
#include "os_event.h"
 | 
						|
 | 
						|
/* common includes */
 | 
						|
#include "iot_module.h"
 | 
						|
#include "iot_queue.h"
 | 
						|
#include "iot_errno.h"
 | 
						|
#include "iot_bitops.h"
 | 
						|
#include "iot_io.h"
 | 
						|
#include "iot_plc_pm_api.h"
 | 
						|
#include "iot_task_api.h"
 | 
						|
 | 
						|
/* mac module internal includes */
 | 
						|
#include "mac.h"
 | 
						|
#include "mac_msg.h"
 | 
						|
#include "beacon.h"
 | 
						|
#include "mac_vdev.h"
 | 
						|
#include "mac_pdev.h"
 | 
						|
#include "sw_sched.h"
 | 
						|
#include "mac_data.h"
 | 
						|
#include "mac_rx_hw.h"
 | 
						|
#include "mac_cert_test.h"
 | 
						|
#include "mac_sched.h"
 | 
						|
#include "mac_zc.h"
 | 
						|
#include "mac_ppm_scan.h"
 | 
						|
#include "mac_reset.h"
 | 
						|
#include "mac_pm.h"
 | 
						|
#include "mac_channel.h"
 | 
						|
#include "mac_check_spur_cco.h"
 | 
						|
#include "mac_check_spur_sta.h"
 | 
						|
 | 
						|
/* public api includes */
 | 
						|
#include "plc_fr.h"
 | 
						|
 | 
						|
#include "mac_pdev.h"
 | 
						|
#include "mac_dbg_pkt_mode.h"
 | 
						|
#include "mac_hplc_ext.h"
 | 
						|
#include "mac_channel_tools.h"
 | 
						|
#include "mac_hw_tsfm.h"
 | 
						|
#include "mac_rf_cert_test.h"
 | 
						|
#include "mac_rf_scan.h"
 | 
						|
 | 
						|
#if HPLC_RF_DEV_SUPPORT
 | 
						|
#include "mac_rf_rx_hw.h"
 | 
						|
#include "mac_rf_rx_buf_ring.h"
 | 
						|
#endif
 | 
						|
 | 
						|
/* define the quota of each mac message queue. 0 means disable quota.
 | 
						|
 * quota rule:
 | 
						|
 * 1. quota disabled queues first
 | 
						|
 * 2. then quota available queues
 | 
						|
 * 3. quota exhausted queues last
 | 
						|
 */
 | 
						|
static uint8_t g_mac_msg_q_quota[MAC_MSG_QUEUE_MAX_PRIO] =
 | 
						|
{
 | 
						|
    /* MAC_MSG_QUEUE_HP */
 | 
						|
    0,
 | 
						|
    /* MAC_MSG_QUEUE_MP */
 | 
						|
    2,
 | 
						|
    /* MAC_MSG_QUEUE_LP */
 | 
						|
    1
 | 
						|
};
 | 
						|
 | 
						|
static void mac_handle_msg_mac(mac_global_t * glb,mac_msg_t * msg)
 | 
						|
{
 | 
						|
    (void)glb;
 | 
						|
 | 
						|
    switch (msg->id) {
 | 
						|
    case MAC_MSG_ID_MAC_WARM_RESET_WAR:
 | 
						|
    {
 | 
						|
        mac_warm_reset_war(msg->data1);
 | 
						|
        break;
 | 
						|
    }
 | 
						|
    case MAC_MSG_ID_MAC_DEBUG_TX_HANG:
 | 
						|
    {
 | 
						|
        mac_tx_hang_handle();
 | 
						|
        break;
 | 
						|
    }
 | 
						|
    case MAC_MSG_ID_MAC_ZC_SET_FUNC_CMD:
 | 
						|
    {
 | 
						|
        mac_zc_set_func_cmd_internal(msg->data1 & 0xFF,
 | 
						|
            (msg->data1 >> 8) & 0xFF, msg->data2);
 | 
						|
        break;
 | 
						|
    }
 | 
						|
    default:
 | 
						|
        IOT_ASSERT(0);
 | 
						|
        break;
 | 
						|
    }
 | 
						|
}
 | 
						|
static void mac_handle_msg_cvg(mac_global_t *glb, mac_msg_t *msg)
 | 
						|
{
 | 
						|
    uint8_t pdev_id, vdev_id, tmp, sn;
 | 
						|
    uint8_t stop_band_scan_flag = 0;
 | 
						|
    (void)glb;
 | 
						|
 | 
						|
    switch (msg->id) {
 | 
						|
    case MAC_MSG_ID_CVG_START_BC:
 | 
						|
    {
 | 
						|
        pdev_id = (msg->data1 >> 8) & 0xFF;
 | 
						|
        vdev_id = msg->data1 & 0xFF;
 | 
						|
        mac_start_beacon_internal(pdev_id, vdev_id);
 | 
						|
        break;
 | 
						|
    }
 | 
						|
    case MAC_MSG_ID_CVG_STOP_BC:
 | 
						|
    {
 | 
						|
        pdev_id = (msg->data1 >> 8) & 0xFF;
 | 
						|
        vdev_id = msg->data1 & 0xFF;
 | 
						|
        mac_stop_beacon_internal(pdev_id, vdev_id);
 | 
						|
        break;
 | 
						|
    }
 | 
						|
    case MAC_MSG_ID_CVG_UPDATE_BC:
 | 
						|
    {
 | 
						|
        pdev_id = (msg->data1 >> 8) & 0xFF;
 | 
						|
        vdev_id = msg->data1 & 0xFF;
 | 
						|
        msg->data1 = mac_update_beacon_internal(pdev_id, vdev_id, msg->data2,
 | 
						|
            &tmp);
 | 
						|
        msg->data2 = (void *)((uint32_t)tmp);
 | 
						|
        break;
 | 
						|
    }
 | 
						|
    case MAC_MSG_ID_CVG_CREATE_VDEV:
 | 
						|
    {
 | 
						|
        pdev_id = (uint8_t)(msg->data1 & 0xFF);
 | 
						|
        vdev_id = msg->data1 & 0xFF;
 | 
						|
        msg->data1 = mac_create_vdev_internal(pdev_id, &vdev_id, msg->data2);
 | 
						|
#if PLC_SUPPORT_DBG_PKT_MODE
 | 
						|
        /* since the PLC_DEFAULT_VDEV == 0, then it must create cvg call
 | 
						|
         * vdev first.
 | 
						|
         */
 | 
						|
        //TODO: will fix create dbg pkt vdev in create vdev function
 | 
						|
        mac_create_dbg_pkt_vdev(pdev_id, msg->data2);
 | 
						|
#endif
 | 
						|
        msg->data2 = (void *)((uint32_t)vdev_id);
 | 
						|
        break;
 | 
						|
    }
 | 
						|
    case MAC_MSG_ID_CVG_START_VDEV:
 | 
						|
    {
 | 
						|
        pdev_id = (msg->data1 >> 8) & 0xFF;
 | 
						|
        vdev_id = msg->data1 & 0xFF;
 | 
						|
        msg->data1 = mac_start_vdev_internal(pdev_id, vdev_id, msg->data2);
 | 
						|
        break;
 | 
						|
    }
 | 
						|
    case MAC_MSG_ID_CVG_SET_VDEV_CFG:
 | 
						|
    {
 | 
						|
        pdev_id = (msg->data1 >> 8) & 0xFF;
 | 
						|
        vdev_id = msg->data1 & 0xFF;
 | 
						|
        msg->data1 = mac_set_vdev_cfg_internal(pdev_id, vdev_id, msg->data2);
 | 
						|
        break;
 | 
						|
    }
 | 
						|
    case MAC_MSG_ID_CVG_STOP_VDEV:
 | 
						|
    {
 | 
						|
        pdev_id = (msg->data1 >> 8) & 0xFF;
 | 
						|
        vdev_id = msg->data1 & 0xFF;
 | 
						|
        msg->data1 = mac_stop_vdev_internal(pdev_id, vdev_id);
 | 
						|
        break;
 | 
						|
    }
 | 
						|
    case MAC_MSG_ID_CVG_MSDU_SEND:
 | 
						|
    {
 | 
						|
        iot_pkt_t* msdu_buf;
 | 
						|
        pdev_id = (msg->data1 >> 8) & 0xFF;
 | 
						|
        vdev_id = msg->data1 & 0xFF;
 | 
						|
        msdu_buf = msg->data2;
 | 
						|
        mac_tx_info *tx_info = msg->data3;
 | 
						|
        if (tx_info->is_rf_data) {
 | 
						|
            msg->data1 = mac_send_rf_msdu_ex_internal(pdev_id, vdev_id,
 | 
						|
                msdu_buf, msg->data3);
 | 
						|
        } else {
 | 
						|
            msg->data1 = mac_send_msdu_ex_internal(pdev_id, vdev_id,
 | 
						|
                msdu_buf, msg->data3);
 | 
						|
        }
 | 
						|
        /* if no memery,then free buf */
 | 
						|
        if (ERR_OK != msg->data1) {
 | 
						|
            iot_pkt_free_tx_done(msdu_buf, IOT_PKT_STATE_TX_FAIL);
 | 
						|
            msg->data2 = NULL;
 | 
						|
        }
 | 
						|
        break;
 | 
						|
    }
 | 
						|
    case MAC_MSG_ID_CVG_CERT_MODE_SEL:
 | 
						|
    {
 | 
						|
        uint8_t mt_mode_sel = msg->data1 & 0xFF;
 | 
						|
        mac_cert_test_g_set(mt_mode_sel);
 | 
						|
        stop_band_scan_flag = 1;
 | 
						|
        break;
 | 
						|
    }
 | 
						|
    case MAC_MSG_ID_CVG_CERT_BAND:
 | 
						|
    {
 | 
						|
        uint8_t band_id;
 | 
						|
        band_id = msg->data1 & 0xFF;
 | 
						|
        mac_cert_test_band_cfg(band_id);
 | 
						|
        stop_band_scan_flag = 1;
 | 
						|
        break;
 | 
						|
    }
 | 
						|
    case MAC_MSG_ID_CVG_CERT_TONEMASK:
 | 
						|
    {
 | 
						|
        uint8_t tonemask_id;
 | 
						|
        tonemask_id = msg->data1 & 0xFF;
 | 
						|
        mac_cert_test_tonemast_cfg(tonemask_id);
 | 
						|
        stop_band_scan_flag = 1;
 | 
						|
        break;
 | 
						|
    }
 | 
						|
    case MAC_MSG_ID_CVG_SET_PDEV_CFG:
 | 
						|
    {
 | 
						|
        cfg_data_tlv *tlv = (cfg_data_tlv *)msg->data2;
 | 
						|
 | 
						|
        pdev_id = msg->data1 & 0xFF;
 | 
						|
        msg->data1 = mac_set_pdev_cfg_internal(pdev_id, msg->data2);
 | 
						|
        if (tlv->type == PLC_PDEV_CFG_SET_BAND && msg->data1 == ERR_OK) {
 | 
						|
            stop_band_scan_flag = 1;
 | 
						|
        }
 | 
						|
        break;
 | 
						|
    }
 | 
						|
    case MAC_MSG_ID_CVG_START_ZC_NTB:
 | 
						|
    {
 | 
						|
        pdev_id = (msg->data1 >> 8) & 0xFF;
 | 
						|
        vdev_id = msg->data1 & 0xFF;
 | 
						|
        msg->data1 = mac_start_zc_ntb_collect_internal(pdev_id, vdev_id,
 | 
						|
            (iot_pkt_t *)msg->data2);
 | 
						|
        break;
 | 
						|
    }
 | 
						|
    case MAC_MSG_ID_CVG_EXT_FRAME_SEND:
 | 
						|
    {
 | 
						|
        uint8_t ext_type;
 | 
						|
        pdev_id = (msg->data1 >> 24) & 0xFF;
 | 
						|
        sn = (msg->data1 >> 16) & 0xFF;
 | 
						|
        vdev_id = (msg->data1 >> 8) & 0xff;
 | 
						|
        ext_type = msg->data1 & 0xFF;
 | 
						|
 | 
						|
        mac_send_ext_frame_internal(ext_type, pdev_id, vdev_id, msg->data2,
 | 
						|
            msg->data3, sn);
 | 
						|
        break;
 | 
						|
    }
 | 
						|
    case MAC_MSG_ID_CVG_GET_PDEV_CFG:
 | 
						|
    {
 | 
						|
        pdev_id = msg->data1 & 0xFF;
 | 
						|
        msg->data1 = mac_get_pdev_cfg_internal(pdev_id, msg->data2);
 | 
						|
        break;
 | 
						|
    }
 | 
						|
    case MAC_MSG_ID_CVG_HW_TSFM_SEND:
 | 
						|
    {
 | 
						|
        pdev_id = (msg->data1 >> 8) & 0xFF;
 | 
						|
        vdev_id = msg->data1 & 0xFF;
 | 
						|
        msg->data1 = mac_hw_tsfm_send_internal(pdev_id, vdev_id, msg->data2);
 | 
						|
        break;
 | 
						|
    }
 | 
						|
    case MAC_MSG_ID_CVG_CERT_HPLC2RF:
 | 
						|
    {
 | 
						|
        uint8_t phr_mcs = (msg->data1 >> 16) & 0xFF;
 | 
						|
        uint8_t pld_mcs = (msg->data1 >> 8) & 0xFF ;
 | 
						|
        uint8_t pb_idx = msg->data1 & 0xFF;
 | 
						|
        mac_rf_cert_test_set_phy_hplc2rf_lp(phr_mcs, pld_mcs, pb_idx);
 | 
						|
        stop_band_scan_flag = 1;
 | 
						|
        break;
 | 
						|
    }
 | 
						|
    case MAC_MSG_ID_CVG_CERT_SEC_MODE:
 | 
						|
    {
 | 
						|
        mac_cert_test_sec_mode_set((uint8_t)msg->data1);
 | 
						|
        stop_band_scan_flag = 1;
 | 
						|
        break;
 | 
						|
    }
 | 
						|
    case MAC_MSG_ID_CVG_CERT_RF_CFG:
 | 
						|
    {
 | 
						|
        uint8_t rf_option, rf_channel;
 | 
						|
        rf_channel = msg->data1 & 0xFF;
 | 
						|
        rf_option = (msg->data1 >> 8) & 0xFF;
 | 
						|
        mac_rf_cert_test_option_channel_cfg(rf_option, rf_channel);
 | 
						|
        stop_band_scan_flag = 1;
 | 
						|
        break;
 | 
						|
    }
 | 
						|
    case MAC_MSG_ID_CVG_GET_VDEV_CFG:
 | 
						|
    {
 | 
						|
        pdev_id = (msg->data1 >> 8) & 0xFF;
 | 
						|
        vdev_id = msg->data1 & 0xFF;
 | 
						|
        msg->data1 = mac_get_vdev_cfg_internal(pdev_id, vdev_id, msg->data2);
 | 
						|
        break;
 | 
						|
    }
 | 
						|
    default:
 | 
						|
        IOT_ASSERT(0);
 | 
						|
        break;
 | 
						|
    }
 | 
						|
 | 
						|
    mac_pdev_t *pdev = get_pdev_ptr(PLC_PDEV_ID);
 | 
						|
    /* NOTE: if need stop band scan after some msg from cvg */
 | 
						|
    if (stop_band_scan_flag == 1 &&
 | 
						|
        !mac_scan_get_band_selected(&pdev->scan)) {
 | 
						|
#if STATIC_POWER_SAVE
 | 
						|
        /* stop power save */
 | 
						|
        mac_pm_stop(pdev);
 | 
						|
#endif
 | 
						|
        /* stop the scan to sync the bcn */
 | 
						|
        mac_scan_stop(&pdev->scan);
 | 
						|
        mac_scan_set_band_selected(&pdev->scan, true);
 | 
						|
        /* stop rf scan timer */
 | 
						|
        mac_rf_scan_stop();
 | 
						|
        /* set channel selected */
 | 
						|
        mac_rf_scan_set_channel_selected(1);
 | 
						|
    }
 | 
						|
}
 | 
						|
 | 
						|
static void mac_handle_msg_dsr(mac_global_t *glb, mac_msg_t *msg)
 | 
						|
{
 | 
						|
    (void)glb;
 | 
						|
 | 
						|
    switch (msg->id) {
 | 
						|
    case MAC_MSG_ID_DSR_RX_TO_MSG:
 | 
						|
    {
 | 
						|
        void *pdev = msg->data2;
 | 
						|
        uint32_t ring_id = msg->data1 & 0xFFFF;
 | 
						|
 | 
						|
#if HPLC_RF_DEV_SUPPORT
 | 
						|
        if (msg->data1 & (1 << 16)) {
 | 
						|
            /* rf ring */
 | 
						|
            msg->data1 = mac_rf_rx_hw_mpdu_internal(pdev, ring_id,
 | 
						|
                (uint32_t)msg->data3);
 | 
						|
            rx_buf_ring_t *rf_ring; //TODO: fix to rf rx ring context
 | 
						|
#if HW_PLATFORM == HW_PLATFORM_SIMU
 | 
						|
            rf_ring = &((mac_rf_pdev_t*)pdev)->simu.rx_ring[ring_id];
 | 
						|
#else
 | 
						|
            rf_ring = &((mac_rf_pdev_t*)pdev)->ring_hdl.ring[ring_id];
 | 
						|
#endif
 | 
						|
            if (ERR_OK == msg->data1) {
 | 
						|
                /* TODO: this is assume in the same task of MAC */
 | 
						|
                rf_ring->msg_delivered = 0;
 | 
						|
            }
 | 
						|
        } else
 | 
						|
#endif /* HPLC_RF_DEV_SUPPORT */
 | 
						|
        {
 | 
						|
            /* plc ring */
 | 
						|
            msg->data1 = mac_rx_hw_mpdu_internal(pdev, ring_id,
 | 
						|
                (uint32_t)msg->data3);
 | 
						|
            rx_buf_ring_t *plc_ring;
 | 
						|
#if HW_PLATFORM == HW_PLATFORM_SIMU
 | 
						|
            plc_ring = &((mac_pdev_t*)pdev)->simu.rx_ring[ring_id];
 | 
						|
#else
 | 
						|
            plc_ring = &((mac_pdev_t*)pdev)->ring_hdl.ring[ring_id];
 | 
						|
#endif
 | 
						|
            if (ERR_OK == msg->data1) {
 | 
						|
                /* TODO: this is assume in the same task of MAC */
 | 
						|
                plc_ring->msg_delivered = 0;
 | 
						|
            }
 | 
						|
        }
 | 
						|
        break;
 | 
						|
    }
 | 
						|
    default:
 | 
						|
        IOT_ASSERT(0);
 | 
						|
        break;
 | 
						|
    }
 | 
						|
}
 | 
						|
 | 
						|
static void mac_handle_msg_timer(mac_global_t *glb, mac_msg_t *msg)
 | 
						|
{
 | 
						|
    (void)glb;
 | 
						|
    mac_vdev_t *vdev;
 | 
						|
    uint8_t pdev_id, vdev_id;
 | 
						|
 | 
						|
    switch (msg->id) {
 | 
						|
    case MAC_MSG_ID_SCHED_TX:
 | 
						|
    {
 | 
						|
        pdev_id = (msg->data1 >> 8) & 0xFF;
 | 
						|
        vdev_id = msg->data1 & 0xFF;
 | 
						|
        vdev = get_vdev_ptr(pdev_id, vdev_id);
 | 
						|
        if (vdev)
 | 
						|
            mac_sched_nn_tx(vdev);
 | 
						|
        break;
 | 
						|
    }
 | 
						|
    case MAC_MSG_ID_ZC_TRAIN_HW_TIMER:
 | 
						|
    {
 | 
						|
        mac_zc_train_hw_timeout_internal(msg->data1, msg->data2);
 | 
						|
        break;
 | 
						|
    }
 | 
						|
 | 
						|
#if !PM_USE_DSR
 | 
						|
    case MAC_MSG_ID_SYSTEM_SLEEP:
 | 
						|
    {
 | 
						|
        sleep_cfg_internal(msg->data2);
 | 
						|
        break;
 | 
						|
    }
 | 
						|
#endif
 | 
						|
 | 
						|
#if K48_STA_MULTI_CHANNEL_SELECT_ENABLE
 | 
						|
    case MAC_MSG_ID_CHANNEL_SCAN_TIMER:
 | 
						|
    {
 | 
						|
        iot_mac_k48sta_switch_next_channel(msg->data2);
 | 
						|
        break;
 | 
						|
    }
 | 
						|
#endif
 | 
						|
    case MAC_MSG_ID_CCO_CHECK_SPUR_TIMER:
 | 
						|
    {
 | 
						|
        /* msg->data2 point to pdev */
 | 
						|
        mac_cco_check_spur_start(msg->data2);
 | 
						|
        break;
 | 
						|
    }
 | 
						|
    case MAC_MSG_ID_STA_CHECK_SPUR_TIMER:
 | 
						|
    {
 | 
						|
        mac_sta_check_spur(msg->data2);
 | 
						|
        break;
 | 
						|
    }
 | 
						|
    case MAC_MSG_ID_STA_PERIOD_CHECK_SPUR:
 | 
						|
    {
 | 
						|
        mac_sta_period_check_spur();
 | 
						|
        break;
 | 
						|
    }
 | 
						|
    case MAC_MSG_ID_DEL_STREAM_TIMER:
 | 
						|
    {
 | 
						|
        mac_vdev_del_timeout_stream_internal(msg->data2, msg->data1);
 | 
						|
        break;
 | 
						|
    }
 | 
						|
    case MAC_MSG_ID_RF_SCAN_TIMER:
 | 
						|
    {
 | 
						|
        mac_rf_scan_next_target(msg->data2);
 | 
						|
        break;
 | 
						|
    }
 | 
						|
    case MAC_MSG_ID_PPM_RECORD_TIMER:
 | 
						|
    {
 | 
						|
        mac_ppm_record_refresh_handle(msg->data2);
 | 
						|
        break;
 | 
						|
    }
 | 
						|
    case MAC_MSG_ID_MAC_CERT_WAR_TIMER:
 | 
						|
    {
 | 
						|
        mac_cert_war_trans_handle();
 | 
						|
        break;
 | 
						|
    }
 | 
						|
    default:
 | 
						|
        IOT_ASSERT(0);
 | 
						|
        break;
 | 
						|
    }
 | 
						|
}
 | 
						|
 | 
						|
static void mac_handle_msg_sch(mac_global_t *glb, mac_msg_t *msg)
 | 
						|
{
 | 
						|
    (void)glb;
 | 
						|
    uint8_t pdev_id, vdev_id;
 | 
						|
 | 
						|
    switch (msg->id) {
 | 
						|
    case MAC_MSG_ID_SCH_TX:
 | 
						|
        /* call frame selection handler */
 | 
						|
        /* TODO: place call here ... */
 | 
						|
        pdev_id = (msg->data1 >> 8) & 0xFF;
 | 
						|
        vdev_id = msg->data1 & 0xFF;
 | 
						|
        mac_swsch_post_msdu(pdev_id,vdev_id);
 | 
						|
        break;
 | 
						|
    default:
 | 
						|
        IOT_ASSERT(0);
 | 
						|
        break;
 | 
						|
    }
 | 
						|
}
 | 
						|
 | 
						|
static void mac_handle_msg_pm(mac_global_t *glb, mac_msg_t *msg)
 | 
						|
{
 | 
						|
    (void)glb;
 | 
						|
    uint8_t pdev_id, vdev_id;
 | 
						|
 | 
						|
    switch (msg->id) {
 | 
						|
    case MAC_MSG_ID_PM_OFF:
 | 
						|
    {
 | 
						|
        if (msg->data1 == IOT_PLC_PM_MSG_POWER_COLLAPSED) {
 | 
						|
            for(pdev_id = 0; pdev_id < MAX_PDEV_NUM; pdev_id++) {
 | 
						|
                for(vdev_id = 0; vdev_id < MAX_VDEV_NUM; vdev_id++) {
 | 
						|
                    mac_pdev_t *pdev = get_pdev_ptr(pdev_id);
 | 
						|
                    if(pdev->vdev[vdev_id]) {
 | 
						|
                        mac_pm_rx_power_off_internal(pdev_id, vdev_id);
 | 
						|
                    }
 | 
						|
                }
 | 
						|
            }
 | 
						|
        } else if (msg->data1 == IOT_PLC_PM_MSG_POWER_RECOVERED) {
 | 
						|
            for (pdev_id = 0; pdev_id < MAX_PDEV_NUM; pdev_id++) {
 | 
						|
                for (vdev_id = 0; vdev_id < MAX_VDEV_NUM; vdev_id++) {
 | 
						|
                    mac_pdev_t *pdev = get_pdev_ptr(pdev_id);
 | 
						|
                    if (pdev->vdev[vdev_id]) {
 | 
						|
                        mac_pm_power_recover_internal(pdev_id, vdev_id);
 | 
						|
                    }
 | 
						|
                }
 | 
						|
            }
 | 
						|
        }
 | 
						|
        break;
 | 
						|
    }
 | 
						|
    case MAC_MSG_ID_PWR_CHANGE:
 | 
						|
    {
 | 
						|
        low_pwr_for_powroff_cfg_internal(msg->data1, msg->data2);
 | 
						|
        break;
 | 
						|
    }
 | 
						|
    default:
 | 
						|
        IOT_ASSERT(0);
 | 
						|
        break;
 | 
						|
    }
 | 
						|
}
 | 
						|
 | 
						|
static void mac_handle_msg_phy(mac_global_t *glb, mac_msg_t *msg)
 | 
						|
{
 | 
						|
    (void)glb;
 | 
						|
 | 
						|
    switch (msg->id) {
 | 
						|
#if (IOT_STA_CONTROL_MODE == IOT_STA_CONTROL_TYPE_STA)
 | 
						|
    case MAC_MSG_ID_CHANNEL_TEST_STOP:
 | 
						|
        mac_channel_test_end_internal();
 | 
						|
        break;
 | 
						|
#endif
 | 
						|
    case MAC_MSG_ID_CHANNEL_ESTIMATED:
 | 
						|
        mac_check_spur_cert(msg->data1);
 | 
						|
        break;
 | 
						|
    default:
 | 
						|
        IOT_ASSERT(0);
 | 
						|
        break;
 | 
						|
    }
 | 
						|
}
 | 
						|
 | 
						|
static void mac_handle_msg_cli(mac_global_t *glb, mac_msg_t *msg)
 | 
						|
{
 | 
						|
    (void)glb;
 | 
						|
 | 
						|
    switch (msg->id) {
 | 
						|
#if (IOT_STA_CONTROL_MODE == IOT_STA_CONTROL_TYPE_STA)
 | 
						|
    case MAC_MSG_ID_CHANNEL_DUMP_TEST:
 | 
						|
        mac_channel_dump_start_internal(msg->data2);
 | 
						|
        break;
 | 
						|
#endif
 | 
						|
    default:
 | 
						|
        IOT_ASSERT(0);
 | 
						|
        break;
 | 
						|
    }
 | 
						|
}
 | 
						|
 | 
						|
/* mac msg handling function */
 | 
						|
static inline void mac_handle_msg(mac_global_t *glb, mac_msg_t *msg)
 | 
						|
{
 | 
						|
    switch (msg->type) {
 | 
						|
    case MAC_MSG_TYPE_CVG:
 | 
						|
        mac_handle_msg_cvg(glb, msg);
 | 
						|
        break;
 | 
						|
    case MAC_MSG_TYPE_DSR:
 | 
						|
        mac_handle_msg_dsr(glb, msg);
 | 
						|
        break;
 | 
						|
    case MAC_MSG_TYPE_TIMER:
 | 
						|
        mac_handle_msg_timer(glb, msg);
 | 
						|
        break;
 | 
						|
    case MAC_MSG_TYPE_SCH:
 | 
						|
        mac_handle_msg_sch(glb, msg);
 | 
						|
        break;
 | 
						|
    case MAC_MSG_TYPE_MAC:
 | 
						|
        mac_handle_msg_mac(glb, msg);
 | 
						|
        break;
 | 
						|
    case MAC_MSG_TYPE_PM:
 | 
						|
        mac_handle_msg_pm(glb, msg);
 | 
						|
        break;
 | 
						|
    case MAC_MSG_TYPE_PHY:
 | 
						|
        mac_handle_msg_phy(glb, msg);
 | 
						|
        break;
 | 
						|
    case MAC_MSG_TYPE_CLI:
 | 
						|
        mac_handle_msg_cli(glb, msg);
 | 
						|
        break;
 | 
						|
    default:
 | 
						|
        IOT_ASSERT(0);
 | 
						|
        break;
 | 
						|
    }
 | 
						|
 | 
						|
    if (msg->sync) {
 | 
						|
        /* notify message sender that message handling is done. */
 | 
						|
        mac_msg_sync_t *msg_sync = (mac_msg_sync_t *)msg;
 | 
						|
        os_set_event(msg_sync->event);
 | 
						|
    } else {
 | 
						|
        /* free non-sync message. for sync message, message sender will
 | 
						|
         * free it.
 | 
						|
         */
 | 
						|
        mac_free_msg(msg);
 | 
						|
    }
 | 
						|
}
 | 
						|
 | 
						|
static void mac_handle_msg_cvg_cancel(mac_global_t *glb, mac_msg_t *msg)
 | 
						|
{
 | 
						|
    iot_printf("%s glb %p msg %lu\n", __FUNCTION__, glb, msg->id);
 | 
						|
 | 
						|
    switch (msg->id) {
 | 
						|
    case MAC_MSG_ID_CVG_START_BC:
 | 
						|
    case MAC_MSG_ID_CVG_STOP_BC:
 | 
						|
    case MAC_MSG_ID_CVG_UPDATE_BC:
 | 
						|
    case MAC_MSG_ID_CVG_CREATE_VDEV:
 | 
						|
    case MAC_MSG_ID_CVG_START_VDEV:
 | 
						|
    case MAC_MSG_ID_CVG_SET_VDEV_CFG:
 | 
						|
    case MAC_MSG_ID_CVG_STOP_VDEV:
 | 
						|
    case MAC_MSG_ID_CVG_MSDU_SEND:
 | 
						|
    case MAC_MSG_ID_CVG_CERT_MODE_SEL:
 | 
						|
    case MAC_MSG_ID_CVG_CERT_BAND:
 | 
						|
    case MAC_MSG_ID_CVG_CERT_TONEMASK:
 | 
						|
    case MAC_MSG_ID_CVG_SET_PDEV_CFG:
 | 
						|
    case MAC_MSG_ID_CVG_START_ZC_NTB:
 | 
						|
    case MAC_MSG_ID_CVG_EXT_FRAME_SEND:
 | 
						|
    case MAC_MSG_ID_CVG_GET_PDEV_CFG:
 | 
						|
    case MAC_MSG_ID_CVG_HW_TSFM_SEND:
 | 
						|
    case MAC_MSG_ID_CVG_CERT_HPLC2RF:
 | 
						|
    case MAC_MSG_ID_CVG_CERT_SEC_MODE:
 | 
						|
    case MAC_MSG_ID_CVG_CERT_RF_CFG:
 | 
						|
    case MAC_MSG_ID_CVG_GET_VDEV_CFG:
 | 
						|
    {
 | 
						|
        break;
 | 
						|
    }
 | 
						|
    default:
 | 
						|
        IOT_ASSERT(0);
 | 
						|
        break;
 | 
						|
    }
 | 
						|
}
 | 
						|
 | 
						|
static void mac_handle_msg_mac_cancel(mac_global_t *glb, mac_msg_t *msg)
 | 
						|
{
 | 
						|
    iot_printf("%s glb %p msg %lu\n", __FUNCTION__, glb, msg->id);
 | 
						|
 | 
						|
    switch (msg->id) {
 | 
						|
    case MAC_MSG_ID_MAC_WARM_RESET_WAR:
 | 
						|
    case MAC_MSG_ID_MAC_DEBUG_TX_HANG:
 | 
						|
    case MAC_MSG_ID_MAC_ZC_SET_FUNC_CMD:
 | 
						|
        break;
 | 
						|
    default:
 | 
						|
        IOT_ASSERT(0);
 | 
						|
        break;
 | 
						|
    }
 | 
						|
}
 | 
						|
 | 
						|
static void mac_handle_msg_dsr_cancel(mac_global_t *glb, mac_msg_t *msg)
 | 
						|
{
 | 
						|
    iot_printf("%s glb %p msg %lu\n", __FUNCTION__, glb, msg->id);
 | 
						|
 | 
						|
    switch (msg->id) {
 | 
						|
    case MAC_MSG_ID_DSR_RX_TO_MSG:
 | 
						|
        break;
 | 
						|
    default:
 | 
						|
        IOT_ASSERT(0);
 | 
						|
        break;
 | 
						|
    }
 | 
						|
}
 | 
						|
 | 
						|
static void mac_handle_msg_timer_cancel(mac_global_t *glb,
 | 
						|
    mac_msg_t *msg)
 | 
						|
{
 | 
						|
    iot_printf("%s glb %p msg %lu\n", __FUNCTION__, glb, msg->id);
 | 
						|
 | 
						|
    switch (msg->id) {
 | 
						|
    case MAC_MSG_ID_SCHED_TX:
 | 
						|
        break;
 | 
						|
#if !PM_USE_DSR
 | 
						|
    case MAC_MSG_ID_SYSTEM_SLEEP:
 | 
						|
        break;
 | 
						|
#endif
 | 
						|
    case MAC_MSG_ID_ZC_TRAIN_HW_TIMER:
 | 
						|
        break;
 | 
						|
#if K48_STA_MULTI_CHANNEL_SELECT_ENABLE
 | 
						|
    case MAC_MSG_ID_CHANNEL_SCAN_TIMER:
 | 
						|
        break;
 | 
						|
#endif
 | 
						|
    case MAC_MSG_ID_CCO_CHECK_SPUR_TIMER:
 | 
						|
        break;
 | 
						|
    case MAC_MSG_ID_STA_CHECK_SPUR_TIMER:
 | 
						|
        break;
 | 
						|
    case MAC_MSG_ID_STA_PERIOD_CHECK_SPUR:
 | 
						|
        break;
 | 
						|
    case MAC_MSG_ID_DEL_STREAM_TIMER:
 | 
						|
        break;
 | 
						|
    case MAC_MSG_ID_RF_SCAN_TIMER:
 | 
						|
        break;
 | 
						|
    case MAC_MSG_ID_PPM_RECORD_TIMER:
 | 
						|
        break;
 | 
						|
    case MAC_MSG_ID_MAC_CERT_WAR_TIMER:
 | 
						|
        break;
 | 
						|
    default:
 | 
						|
        IOT_ASSERT(0);
 | 
						|
        break;
 | 
						|
    }
 | 
						|
}
 | 
						|
 | 
						|
static void mac_handle_msg_sch_cancel(mac_global_t *glb,
 | 
						|
    mac_msg_t *msg)
 | 
						|
{
 | 
						|
    iot_printf("%s glb %p msg %lu\n", __FUNCTION__, glb, msg->id);
 | 
						|
 | 
						|
    switch (msg->id) {
 | 
						|
    case MAC_MSG_ID_SCH_TX:
 | 
						|
        break;
 | 
						|
    default:
 | 
						|
        IOT_ASSERT(0);
 | 
						|
        break;
 | 
						|
    }
 | 
						|
}
 | 
						|
 | 
						|
static void mac_handle_msg_pm_cancel(mac_global_t *glb, mac_msg_t *msg)
 | 
						|
{
 | 
						|
    iot_printf("%s glb %p msg %lu\n", __FUNCTION__, glb, msg->id);
 | 
						|
 | 
						|
    switch (msg->id) {
 | 
						|
    case MAC_MSG_ID_PM_OFF:
 | 
						|
    case MAC_MSG_ID_PWR_CHANGE:
 | 
						|
        break;
 | 
						|
    default:
 | 
						|
        IOT_ASSERT(0);
 | 
						|
        break;
 | 
						|
    }
 | 
						|
}
 | 
						|
 | 
						|
static void mac_handle_msg_phy_cancel(mac_global_t *glb, mac_msg_t *msg)
 | 
						|
{
 | 
						|
    iot_printf("%s glb %p msg %lu\n", __FUNCTION__, glb, msg->id);
 | 
						|
 | 
						|
    switch (msg->id) {
 | 
						|
    case MAC_MSG_ID_CHANNEL_TEST_STOP:
 | 
						|
        break;
 | 
						|
    case MAC_MSG_ID_CHANNEL_ESTIMATED:
 | 
						|
        break;
 | 
						|
    default:
 | 
						|
        IOT_ASSERT(0);
 | 
						|
        break;
 | 
						|
    }
 | 
						|
}
 | 
						|
 | 
						|
static void mac_handle_msg_cli_cancel(mac_global_t *glb, mac_msg_t *msg)
 | 
						|
{
 | 
						|
    iot_printf("%s glb %p msg %lu\n", __FUNCTION__, glb, msg->id);
 | 
						|
 | 
						|
    switch (msg->id) {
 | 
						|
    case MAC_MSG_ID_CHANNEL_DUMP_TEST:
 | 
						|
        break;
 | 
						|
    default:
 | 
						|
        IOT_ASSERT(0);
 | 
						|
        break;
 | 
						|
    }
 | 
						|
}
 | 
						|
 | 
						|
 | 
						|
/* handle msg canceled case. message can be canceled due to various reasons.
 | 
						|
 * each message may have different cancelation operation required.
 | 
						|
 */
 | 
						|
void mac_handle_msg_cancel(mac_global_t *glb, mac_msg_t *msg)
 | 
						|
{
 | 
						|
    switch (msg->type) {
 | 
						|
    case MAC_MSG_TYPE_CVG:
 | 
						|
        mac_handle_msg_cvg_cancel(glb, msg);
 | 
						|
        break;
 | 
						|
    case MAC_MSG_TYPE_MAC:
 | 
						|
        mac_handle_msg_mac_cancel(glb, msg);
 | 
						|
        break;
 | 
						|
    case MAC_MSG_TYPE_DSR:
 | 
						|
        mac_handle_msg_dsr_cancel(glb, msg);
 | 
						|
        break;
 | 
						|
    case MAC_MSG_TYPE_TIMER:
 | 
						|
        mac_handle_msg_timer_cancel(glb, msg);
 | 
						|
        break;
 | 
						|
    case MAC_MSG_TYPE_SCH:
 | 
						|
        mac_handle_msg_sch_cancel(glb, msg);
 | 
						|
        break;
 | 
						|
    case MAC_MSG_TYPE_PM:
 | 
						|
        mac_handle_msg_pm_cancel(glb, msg);
 | 
						|
        break;
 | 
						|
    case MAC_MSG_TYPE_PHY:
 | 
						|
        mac_handle_msg_phy_cancel(glb, msg);
 | 
						|
        break;
 | 
						|
    case MAC_MSG_TYPE_CLI:
 | 
						|
        mac_handle_msg_cli_cancel(glb, msg);
 | 
						|
        break;
 | 
						|
    default:
 | 
						|
        IOT_ASSERT(0);
 | 
						|
        break;
 | 
						|
    }
 | 
						|
 | 
						|
    mac_free_msg(msg);
 | 
						|
}
 | 
						|
 | 
						|
extern uint8_t mac_log_print_en;
 | 
						|
extern void mac_tx_csma_dump();
 | 
						|
 | 
						|
static void mac_main_task(void* arg)
 | 
						|
{
 | 
						|
    uint8_t i, j, tmp;
 | 
						|
    uint32_t dsr_event;
 | 
						|
    mac_global_t *glb = arg;
 | 
						|
    iot_msg_entry_t *entry;
 | 
						|
    mac_msg_t *msg;
 | 
						|
    mac_dsr_func_t dsr;
 | 
						|
    mac_msg_queue_t *pq;
 | 
						|
    uint8_t quota_disbled_q_cnt = 0;
 | 
						|
    uint8_t quota_enabled_q_cnt = 0;
 | 
						|
    uint8_t quota_exhausted_q_cnt = 0;
 | 
						|
    mac_msg_queue_t *quota_disbled_q[MAC_MSG_QUEUE_MAX_PRIO];
 | 
						|
    mac_msg_queue_t *quota_enabled_q[MAC_MSG_QUEUE_MAX_PRIO];
 | 
						|
    mac_msg_queue_t *quota_exhausted_q[MAC_MSG_QUEUE_MAX_PRIO];
 | 
						|
 | 
						|
    iot_printf("%s glb %p\n", __FUNCTION__, glb);
 | 
						|
 | 
						|
    /* check if quota enabled and disabled queue exist */
 | 
						|
    for (i = 0; i < MAC_MSG_QUEUE_MAX_PRIO; i++) {
 | 
						|
        pq = &glb->msg_q[i];
 | 
						|
        if (pq->quota_en) {
 | 
						|
            quota_enabled_q[quota_enabled_q_cnt] = pq;
 | 
						|
            quota_enabled_q_cnt++;
 | 
						|
        } else {
 | 
						|
            quota_disbled_q[quota_disbled_q_cnt] = pq;
 | 
						|
            quota_disbled_q_cnt++;
 | 
						|
        }
 | 
						|
    }
 | 
						|
 | 
						|
    for (;;) {
 | 
						|
        /* waiting for messages from various modules and dsr events from isr.
 | 
						|
         * always handle dsr event firstly.
 | 
						|
         */
 | 
						|
        dsr_event = os_wait_task_event_with_v(MAX_TIME);
 | 
						|
 | 
						|
handle_dsr:
 | 
						|
        i = 0;
 | 
						|
        while (dsr_event) {
 | 
						|
            tmp = dsr_event & 0xFF;
 | 
						|
            while (tmp) {
 | 
						|
                j = iot_bitops_fls(tmp) - 1;
 | 
						|
                tmp &= ~(0x1 << j);
 | 
						|
                dsr = glb->dsr_table.entry[i + j].dsr;
 | 
						|
                if (dsr) {
 | 
						|
                    dsr();
 | 
						|
                }
 | 
						|
            }
 | 
						|
            dsr_event >>= 8;
 | 
						|
            i += 8;
 | 
						|
        }
 | 
						|
 | 
						|
handle_msg:
 | 
						|
        /* check quota disabled queue */
 | 
						|
        if (quota_disbled_q_cnt) {
 | 
						|
            /* check message queues based on priority */
 | 
						|
            for (i = 0; i < quota_disbled_q_cnt; i++) {
 | 
						|
                pq = quota_disbled_q[i];
 | 
						|
                entry = iot_msg_queue_get(&pq->q);
 | 
						|
                if (entry) {
 | 
						|
                    /* get message and handle it */
 | 
						|
                    msg = container_of(entry, mac_msg_t, link);
 | 
						|
                    mac_handle_msg(glb, msg);
 | 
						|
                    /* check if any dsr event pending */
 | 
						|
                    dsr_event = os_wait_task_event_with_v(0);
 | 
						|
                    if (dsr_event)
 | 
						|
                        goto handle_dsr;
 | 
						|
                    /* always search from highest priority queue with quota
 | 
						|
                     * disabled.
 | 
						|
                     */
 | 
						|
                    goto handle_msg;
 | 
						|
                }
 | 
						|
            }
 | 
						|
        }
 | 
						|
 | 
						|
        /* check quota enabled queue */
 | 
						|
        if (quota_enabled_q_cnt) {
 | 
						|
            quota_exhausted_q_cnt = 0;
 | 
						|
            /* check message queues based on priority */
 | 
						|
            for (i = 0; i < quota_enabled_q_cnt; i++) {
 | 
						|
                pq = quota_enabled_q[i];
 | 
						|
                /* check if quota available for this queue */
 | 
						|
                if (pq->curr_quota == 0) {
 | 
						|
                    quota_exhausted_q[quota_exhausted_q_cnt] = pq;
 | 
						|
                    quota_exhausted_q_cnt++;
 | 
						|
                    continue;
 | 
						|
                }
 | 
						|
                entry = iot_msg_queue_get(&pq->q);
 | 
						|
                if (entry) {
 | 
						|
                    /* get message and handle it */
 | 
						|
                    msg = container_of(entry, mac_msg_t, link);
 | 
						|
                    mac_handle_msg(glb, msg);
 | 
						|
                    pq->curr_quota--;
 | 
						|
                    /* check if any dsr event pending */
 | 
						|
                    dsr_event = os_wait_task_event_with_v(0);
 | 
						|
                    if (dsr_event)
 | 
						|
                        goto handle_dsr;
 | 
						|
                    /* always search from highest priority queue with quota
 | 
						|
                     * disabled.
 | 
						|
                     */
 | 
						|
                    goto handle_msg;
 | 
						|
                }
 | 
						|
            }
 | 
						|
 | 
						|
            if (quota_exhausted_q_cnt == quota_enabled_q_cnt) {
 | 
						|
                /* no quota available queue exist, re-assign quota */
 | 
						|
                for (i = 0; i < quota_enabled_q_cnt; i++) {
 | 
						|
                    pq = quota_enabled_q[i];
 | 
						|
                    pq->curr_quota = pq->quota;
 | 
						|
                }
 | 
						|
                /* always search from highest priority queue with quota
 | 
						|
                 * disabled.
 | 
						|
                 */
 | 
						|
                goto handle_msg;
 | 
						|
            } else {
 | 
						|
                /* check if any quota exhausted queue exist */
 | 
						|
                for (i = 0; i < quota_exhausted_q_cnt; i++) {
 | 
						|
                    pq = quota_exhausted_q[i];
 | 
						|
                    entry = iot_msg_queue_get(&pq->q);
 | 
						|
                    if (entry) {
 | 
						|
                        /* get message and handle it */
 | 
						|
                        msg = container_of(entry, mac_msg_t, link);
 | 
						|
                        mac_handle_msg(glb, msg);
 | 
						|
                        /* check if any dsr event pending */
 | 
						|
                        dsr_event = os_wait_task_event_with_v(0);
 | 
						|
                        if (dsr_event)
 | 
						|
                            goto handle_dsr;
 | 
						|
                        /* always search from highest priority queue with
 | 
						|
                         * quota disabled.
 | 
						|
                         */
 | 
						|
                        goto handle_msg;
 | 
						|
                    }
 | 
						|
                }
 | 
						|
            }
 | 
						|
        }
 | 
						|
        if (mac_log_print_en) {
 | 
						|
            mac_tx_csma_dump();
 | 
						|
            mac_log_print_en = 0;
 | 
						|
        }
 | 
						|
    }
 | 
						|
}
 | 
						|
 | 
						|
uint32_t mac_start_task(mac_global_t *glb)
 | 
						|
{
 | 
						|
    uint8_t i;
 | 
						|
    uint32_t ret = 0;
 | 
						|
    os_task_h handle;
 | 
						|
 | 
						|
    /* initialize mac message queue */
 | 
						|
    for (i = 0; i < MAC_MSG_QUEUE_MAX_PRIO; i++) {
 | 
						|
        ret = iot_msg_queue_init(&glb->msg_q[i].q);
 | 
						|
        if (g_mac_msg_q_quota[i]) {
 | 
						|
            /* enable quota for this queue */
 | 
						|
            glb->msg_q[i].quota_en = 1;
 | 
						|
            glb->msg_q[i].quota = g_mac_msg_q_quota[i];
 | 
						|
            glb->msg_q[i].curr_quota = glb->msg_q[i].quota;
 | 
						|
        } else {
 | 
						|
            /* disable quota for this queue */
 | 
						|
            glb->msg_q[i].quota_en = 0;
 | 
						|
            glb->msg_q[i].quota = 0;
 | 
						|
            glb->msg_q[i].curr_quota = 0;
 | 
						|
        }
 | 
						|
        if (ret) {
 | 
						|
            for (; i > 0; i--) {
 | 
						|
                iot_msg_queue_deinit(&glb->msg_q[i - 1].q);
 | 
						|
            }
 | 
						|
            goto out;
 | 
						|
        }
 | 
						|
    }
 | 
						|
 | 
						|
    /* start mac main task */
 | 
						|
    handle = os_create_task_ext(mac_main_task, glb, PLC_MAC_TASK_PRIO,
 | 
						|
        PLC_MAC_STACK_SIZE, __FUNCTION__);
 | 
						|
 | 
						|
    iot_printf("%s glb %p\n", __FUNCTION__, glb);
 | 
						|
 | 
						|
    if (handle == NULL) {
 | 
						|
        ret = ERR_NOMEM;
 | 
						|
        goto err_task;
 | 
						|
    } else {
 | 
						|
        glb->task_h = handle;
 | 
						|
    }
 | 
						|
 | 
						|
    goto out;
 | 
						|
 | 
						|
err_task:
 | 
						|
    for (i = 0; i < MAC_MSG_QUEUE_MAX_PRIO; i++)
 | 
						|
        iot_msg_queue_deinit(&glb->msg_q[i].q);
 | 
						|
out:
 | 
						|
    return ret;
 | 
						|
}
 | 
						|
 | 
						|
void mac_stop_task(mac_global_t *glb)
 | 
						|
{
 | 
						|
    iot_msg_entry_t *entry;
 | 
						|
    mac_msg_t *msg;
 | 
						|
    iot_msg_queue_t *pq;
 | 
						|
    uint8_t i;
 | 
						|
 | 
						|
    if (glb->task_h) {
 | 
						|
        /* delete mac main task */
 | 
						|
        os_delete_task(glb->task_h);
 | 
						|
        glb->task_h = NULL;
 | 
						|
 | 
						|
        for (i = 0; i < MAC_MSG_QUEUE_MAX_PRIO; i++) {
 | 
						|
            pq = &glb->msg_q[i].q;
 | 
						|
            entry = iot_msg_queue_get(pq);
 | 
						|
            while (entry) {
 | 
						|
                /* get messages */
 | 
						|
                msg = container_of(entry, mac_msg_t, link);
 | 
						|
                mac_handle_msg_cancel(glb, msg);
 | 
						|
                entry = iot_msg_queue_get(pq);
 | 
						|
            }
 | 
						|
 | 
						|
            /* deinit the mac message queue */
 | 
						|
            iot_msg_queue_deinit(pq);
 | 
						|
        }
 | 
						|
    }
 | 
						|
 | 
						|
    iot_printf("%s glb %p\n", __FUNCTION__, glb);
 | 
						|
}
 | 
						|
 | 
						|
void mac_boost_task_prio()
 | 
						|
{
 | 
						|
    os_set_task_prio_ext(p_mac_glb->task_h, PLC_TASK_HIGHEST_PRIO);
 | 
						|
}
 | 
						|
 | 
						|
void mac_restore_task_prio()
 | 
						|
{
 | 
						|
    os_set_task_prio_ext(p_mac_glb->task_h, PLC_MAC_TASK_PRIO);
 | 
						|
}
 |