489 lines
		
	
	
		
			14 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
		
		
			
		
	
	
			489 lines
		
	
	
		
			14 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.
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								****************************************************************************/
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								/* os shim includes */
							 | 
						||
| 
								 | 
							
								#include "os_types.h"
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								/* mac module internal includes */
							 | 
						||
| 
								 | 
							
								#include "mac_vdev.h"
							 | 
						||
| 
								 | 
							
								#include "mac_pdev.h"
							 | 
						||
| 
								 | 
							
								#include "command_list.h"
							 | 
						||
| 
								 | 
							
								#include "hw_reg_api.h"
							 | 
						||
| 
								 | 
							
								#include "mac_sys_reg.h"
							 | 
						||
| 
								 | 
							
								#include "mac_hwq_reg.h"
							 | 
						||
| 
								 | 
							
								#include "os_task.h"
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								#if MAC_SCHED_HW_DEBUG || ENA_WAR_911
							 | 
						||
| 
								 | 
							
								#include "iot_io.h"
							 | 
						||
| 
								 | 
							
								#endif
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								/* public api includes */
							 | 
						||
| 
								 | 
							
								#include "plc_fr.h"
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								#include "mac_status.h"
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								#if HW_PLATFORM >= HW_PLATFORM_FPGA
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								#if ENA_WAR_440
							 | 
						||
| 
								 | 
							
								#include "phy_bb.h"
							 | 
						||
| 
								 | 
							
								#endif
							 | 
						||
| 
								 | 
							
								#include "mac_reset.h"
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								void mac_sched_enable_hw_ntb_sync(mac_vdev_t *vdev, uint8_t enable)
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
								    uint32_t value;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    /* disable irq */
							 | 
						||
| 
								 | 
							
								    os_disable_irq();
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    value = RGF_MAC_READ_REG(CFG_NTB_SYNC_0_ADDR);
							 | 
						||
| 
								 | 
							
								    if (enable) {
							 | 
						||
| 
								 | 
							
								        REG_FIELD_SET(CFG_HW_NTB_SYNC_EN, value, 1);
							 | 
						||
| 
								 | 
							
								        REG_FIELD_SET(CFG_NTB_SW_SYNC_CLR, value, 1);
							 | 
						||
| 
								 | 
							
								    } else {
							 | 
						||
| 
								 | 
							
								        REG_FIELD_SET(CFG_HW_NTB_SYNC_EN, value, 0);
							 | 
						||
| 
								 | 
							
								        REG_FIELD_SET(CFG_NTB_HW_SYNC_CLR, value, 1);
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								    RGF_MAC_WRITE_REG(CFG_NTB_SYNC_0_ADDR, value);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    /* enable irq */
							 | 
						||
| 
								 | 
							
								    os_enable_irq();
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								void mac_record_sync_ntb_overflow(uint64_t st_ntb, uint32_t result)
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
								/* bitmap 0 1 3 4 */
							 | 
						||
| 
								 | 
							
								#define SYNC_OVERFLOW_NTB_WAY_1    0x1B
							 | 
						||
| 
								 | 
							
								/* bitmap 0 1 3 5 */
							 | 
						||
| 
								 | 
							
								#define SYNC_OVERFLOW_NTB_WAY_2    0x2B
							 | 
						||
| 
								 | 
							
								/* bitmap 0 2 3 4 */
							 | 
						||
| 
								 | 
							
								#define SYNC_OVERFLOW_NTB_WAY_3    0x1D
							 | 
						||
| 
								 | 
							
								/* bitmap 0 2 3 5 */
							 | 
						||
| 
								 | 
							
								#define SYNC_OVERFLOW_NTB_WAY_4    0x2D
							 | 
						||
| 
								 | 
							
								/* bitmap 6 */
							 | 
						||
| 
								 | 
							
								#define SYNC_OVERFLOW_NTB_WAY_5    0x40
							 | 
						||
| 
								 | 
							
								    mac_pdev_t *pdev = get_pdev_ptr(PLC_PDEV_ID);
							 | 
						||
| 
								 | 
							
								    mac_sync_ntb_record_t *sync_ntb_record = &pdev->mac_status.sync_ntb_record;
							 | 
						||
| 
								 | 
							
								    uint64_t cur_ntb = mac_sched_get_ntb64(NULL);
							 | 
						||
| 
								 | 
							
								    switch (result) {
							 | 
						||
| 
								 | 
							
								    case SYNC_OVERFLOW_NTB_WAY_1 :
							 | 
						||
| 
								 | 
							
								        sync_ntb_record->sync_ntb_ovf_way1_cnt++;
							 | 
						||
| 
								 | 
							
								        if (iot_uint64_higher32(cur_ntb) - iot_uint64_higher32(st_ntb) == 1) {
							 | 
						||
| 
								 | 
							
								            sync_ntb_record->way1_success_cnt++;
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								        break;
							 | 
						||
| 
								 | 
							
								    case SYNC_OVERFLOW_NTB_WAY_2 :
							 | 
						||
| 
								 | 
							
								        sync_ntb_record->sync_ntb_ovf_way2_cnt++;
							 | 
						||
| 
								 | 
							
								        if (iot_uint64_higher32(cur_ntb) - iot_uint64_higher32(st_ntb) == 1) {
							 | 
						||
| 
								 | 
							
								            sync_ntb_record->way2_success_cnt++;
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								        break;
							 | 
						||
| 
								 | 
							
								    case SYNC_OVERFLOW_NTB_WAY_3 :
							 | 
						||
| 
								 | 
							
								        sync_ntb_record->sync_ntb_ovf_way3_cnt++;
							 | 
						||
| 
								 | 
							
								        if (iot_uint64_higher32(cur_ntb) - iot_uint64_higher32(st_ntb) == 1) {
							 | 
						||
| 
								 | 
							
								            sync_ntb_record->way3_success_cnt++;
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								        break;
							 | 
						||
| 
								 | 
							
								    case SYNC_OVERFLOW_NTB_WAY_4 :
							 | 
						||
| 
								 | 
							
								        sync_ntb_record->sync_ntb_ovf_way4_cnt++;
							 | 
						||
| 
								 | 
							
								        if (iot_uint64_higher32(cur_ntb) - iot_uint64_higher32(st_ntb) == 1) {
							 | 
						||
| 
								 | 
							
								            sync_ntb_record->way4_success_cnt++;
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								        break;
							 | 
						||
| 
								 | 
							
								    case SYNC_OVERFLOW_NTB_WAY_5 :
							 | 
						||
| 
								 | 
							
								        sync_ntb_record->sync_ntb_ovf_way5_cnt++;
							 | 
						||
| 
								 | 
							
								        break;
							 | 
						||
| 
								 | 
							
								    default:
							 | 
						||
| 
								 | 
							
								        sync_ntb_record->sync_ntb_ovf_way6_cnt++;
							 | 
						||
| 
								 | 
							
								        break;
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								void mac_sched_sync_ntb(mac_vdev_t *vdev, uint16_t golden_gap,
							 | 
						||
| 
								 | 
							
								    int32_t ntb_delta)
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
								    uint32_t value;
							 | 
						||
| 
								 | 
							
								    (void)vdev;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    /* disable irq */
							 | 
						||
| 
								 | 
							
								    os_disable_irq();
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    value = RGF_MAC_READ_REG(CFG_NTB_SYNC_0_ADDR);
							 | 
						||
| 
								 | 
							
								    value |= CFG_NTB_DELTA_VAL_SIGN_MASK | CFG_MODIFY_NTB_EN_MASK;
							 | 
						||
| 
								 | 
							
								    if (golden_gap) {
							 | 
						||
| 
								 | 
							
								        /* set golden gap only when it's non-zero, this value shouldn't be
							 | 
						||
| 
								 | 
							
								         * changed once set.
							 | 
						||
| 
								 | 
							
								         */
							 | 
						||
| 
								 | 
							
								        value &= ~CFG_NTB_GOLDEN_GAP_MASK;
							 | 
						||
| 
								 | 
							
								        value |= (((uint32_t)golden_gap) << CFG_NTB_GOLDEN_GAP_OFFSET)
							 | 
						||
| 
								 | 
							
								            & CFG_NTB_GOLDEN_GAP_MASK;
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								    if (!(value & CFG_HW_NTB_SYNC_EN_MASK)) {
							 | 
						||
| 
								 | 
							
								        /* make sure HW don't sync NTB blindly */
							 | 
						||
| 
								 | 
							
								        IOT_ASSERT(RGF_MAC_READ_REG(CFG_RO_NTB_HW_SYNC_VAL_ADDR) == 0);
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    uint32_t u_ntb_delta = 0;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								#if ENA_WAR_911
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    uint32_t result = 0;
							 | 
						||
| 
								 | 
							
								    /* war for hw bug, low bit overflow high bit not + 1 */
							 | 
						||
| 
								 | 
							
								    uint32_t ntb_delta_a = 0;
							 | 
						||
| 
								 | 
							
								    uint32_t ntb_delta_b = 0;
							 | 
						||
| 
								 | 
							
								    uint64_t cur_ntb = mac_sched_get_ntb64(NULL);
							 | 
						||
| 
								 | 
							
								    if (ntb_delta >= 0) {
							 | 
						||
| 
								 | 
							
								        /* positive */
							 | 
						||
| 
								 | 
							
								        uint64_t temp_ntb = (uint64_t)iot_uint64_lower32(cur_ntb) + ntb_delta;
							 | 
						||
| 
								 | 
							
								        /* if overflow */
							 | 
						||
| 
								 | 
							
								        if (iot_uint64_higher32(temp_ntb) >= 1) {
							 | 
						||
| 
								 | 
							
								            result |= 1 << 0;
							 | 
						||
| 
								 | 
							
								            /* set delta part a */
							 | 
						||
| 
								 | 
							
								            ntb_delta_a = MAX_UINT32_NTB - iot_uint64_lower32(cur_ntb);
							 | 
						||
| 
								 | 
							
								            if (ntb_delta_a > (RESERVE_NTB + (RESERVE_NTB >> 1))) {
							 | 
						||
| 
								 | 
							
								                result |= 1 << 1;
							 | 
						||
| 
								 | 
							
								                ntb_delta_a = ntb_delta_a - RESERVE_NTB;
							 | 
						||
| 
								 | 
							
								                /* set part a to register */
							 | 
						||
| 
								 | 
							
								                RGF_MAC_WRITE_REG(CFG_NTB_SYNC_1_ADDR, ntb_delta_a);
							 | 
						||
| 
								 | 
							
								                RGF_MAC_WRITE_REG(CFG_NTB_SYNC_0_ADDR, value);
							 | 
						||
| 
								 | 
							
								            } else {
							 | 
						||
| 
								 | 
							
								                result |= 1 << 2;
							 | 
						||
| 
								 | 
							
								                ntb_delta_a = 0;
							 | 
						||
| 
								 | 
							
								            }
							 | 
						||
| 
								 | 
							
								            IOT_ASSERT(ntb_delta >= ntb_delta_a);
							 | 
						||
| 
								 | 
							
								            /* set delta part b */
							 | 
						||
| 
								 | 
							
								            ntb_delta_b = ntb_delta - ntb_delta_a;
							 | 
						||
| 
								 | 
							
								            /* delay to wait hight bit +1 */
							 | 
						||
| 
								 | 
							
								            temp_ntb = mac_sched_get_ntb64(NULL);
							 | 
						||
| 
								 | 
							
								            /* check ntb is normal */
							 | 
						||
| 
								 | 
							
								            if (iot_uint64_higher32(temp_ntb) >= iot_uint64_higher32(cur_ntb)) {
							 | 
						||
| 
								 | 
							
								                result |= 1 << 3;
							 | 
						||
| 
								 | 
							
								                /* wait overflow happen */
							 | 
						||
| 
								 | 
							
								                uint32_t time_span = 0;
							 | 
						||
| 
								 | 
							
								                uint32_t cur_ntb_temp = 0;
							 | 
						||
| 
								 | 
							
								                do {
							 | 
						||
| 
								 | 
							
								                    cur_ntb_temp = mac_sched_get_ntb(NULL);
							 | 
						||
| 
								 | 
							
								                    time_span = cur_ntb_temp - iot_uint64_lower32(temp_ntb);
							 | 
						||
| 
								 | 
							
								                } while (cur_ntb_temp > (MAX_UINT32_NTB >> 1) &&
							 | 
						||
| 
								 | 
							
								                time_span < DELAY_MAX_NTB);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								                /* check which condition jumps out of the while */
							 | 
						||
| 
								 | 
							
								                if (cur_ntb_temp < (MAX_UINT32_NTB >> 1)) {
							 | 
						||
| 
								 | 
							
								                    result |= 1 << 4;
							 | 
						||
| 
								 | 
							
								                    /* set delta next part */
							 | 
						||
| 
								 | 
							
								                    u_ntb_delta = ntb_delta_b;
							 | 
						||
| 
								 | 
							
								                } else {
							 | 
						||
| 
								 | 
							
								                    result |= 1 << 5;
							 | 
						||
| 
								 | 
							
								                    /* timeout and give up this sync part b */
							 | 
						||
| 
								 | 
							
								                    u_ntb_delta = 0;
							 | 
						||
| 
								 | 
							
								                    iot_printf("%s wait overflow timeout\n", __FUNCTION__);
							 | 
						||
| 
								 | 
							
								                }
							 | 
						||
| 
								 | 
							
								            } else {
							 | 
						||
| 
								 | 
							
								                iot_printf("%s sync ntb error\n", __FUNCTION__);
							 | 
						||
| 
								 | 
							
								                IOT_ASSERT(0);
							 | 
						||
| 
								 | 
							
								            }
							 | 
						||
| 
								 | 
							
								        }else {
							 | 
						||
| 
								 | 
							
								            u_ntb_delta = ntb_delta;
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								    } else {
							 | 
						||
| 
								 | 
							
								        /* negative */
							 | 
						||
| 
								 | 
							
								        if ((iot_uint64_lower32(cur_ntb) < (-ntb_delta)) &&
							 | 
						||
| 
								 | 
							
								            (vdev_get_tei(vdev) != PLC_TEI_INVAL)) {
							 | 
						||
| 
								 | 
							
								            result |= 1 << 6;
							 | 
						||
| 
								 | 
							
								            u_ntb_delta = iot_uint64_lower32(cur_ntb);
							 | 
						||
| 
								 | 
							
								        } else {
							 | 
						||
| 
								 | 
							
								            u_ntb_delta = MAX_UINT32_NTB + ntb_delta;
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    /* launch ntb delta first as enable NTB modify bit will cause HW
							 | 
						||
| 
								 | 
							
								     * launch the delta value right away.
							 | 
						||
| 
								 | 
							
								     */
							 | 
						||
| 
								 | 
							
								    RGF_MAC_WRITE_REG(CFG_NTB_SYNC_1_ADDR, u_ntb_delta);
							 | 
						||
| 
								 | 
							
								    RGF_MAC_WRITE_REG(CFG_NTB_SYNC_0_ADDR, value);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    /* enable irq */
							 | 
						||
| 
								 | 
							
								    os_enable_irq();
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    if (result) {
							 | 
						||
| 
								 | 
							
								        mac_record_sync_ntb_overflow(cur_ntb, result);
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								#else
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    if (ntb_delta < 0) {
							 | 
						||
| 
								 | 
							
								        u_ntb_delta = MAX_UINT32_NTB + ntb_delta;
							 | 
						||
| 
								 | 
							
								    } else {
							 | 
						||
| 
								 | 
							
								        u_ntb_delta = ntb_delta;
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								    /* launch ntb delta first as enable NTB modify bit will cause HW
							 | 
						||
| 
								 | 
							
								     * launch the delta value right away.
							 | 
						||
| 
								 | 
							
								     */
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    RGF_MAC_WRITE_REG(CFG_NTB_SYNC_1_ADDR, u_ntb_delta);
							 | 
						||
| 
								 | 
							
								    RGF_MAC_WRITE_REG(CFG_NTB_SYNC_0_ADDR, value);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    /* enable irq */
							 | 
						||
| 
								 | 
							
								    os_enable_irq();
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								#endif
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								#if MAC_SCHED_HW_DEBUG
							 | 
						||
| 
								 | 
							
								    iot_printf("MAC_SCHED_HW ---%s--- CFG_NTB_SYNC_0_ADDR %x\n", __FUNCTION__,
							 | 
						||
| 
								 | 
							
								        value);
							 | 
						||
| 
								 | 
							
								    iot_printf("MAC_SCHED_HW ---%s--- CFG_NTB_SYNC_1_ADDR %d\n", __FUNCTION__,
							 | 
						||
| 
								 | 
							
								        ntb_delta);
							 | 
						||
| 
								 | 
							
								#endif
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								uint32_t IRAM_ATTR mac_sched_get_ntb(mac_vdev_t *vdev)
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
								    (void)vdev;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								   return RGF_MAC_READ_REG(CFG_RD_NTB_ADDR);
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								uint32_t IRAM_ATTR mac_sched_get_lts()
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
								    return RGF_MAC_READ_REG(CFG_RD_LOCAL_TMR_ADDR);
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								uint64_t IRAM_ATTR mac_sched_get_ntb64(mac_vdev_t *vdev)
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
								    uint32_t ntb;
							 | 
						||
| 
								 | 
							
								    uint64_t ntb64_a, ntb64_b;
							 | 
						||
| 
								 | 
							
								    (void)vdev;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    ntb64_a = RGF_MAC_READ_REG(CFG_RO_NTB_TMR_WRAP_ADDR);
							 | 
						||
| 
								 | 
							
								    ntb = RGF_MAC_READ_REG(CFG_RD_NTB_ADDR);
							 | 
						||
| 
								 | 
							
								    ntb64_b = RGF_MAC_READ_REG(CFG_RO_NTB_TMR_WRAP_ADDR);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    if (ntb64_b != ntb64_a) {
							 | 
						||
| 
								 | 
							
								        /* wrap round happened */
							 | 
						||
| 
								 | 
							
								        ntb = RGF_MAC_READ_REG(CFG_RD_NTB_ADDR);
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								    ntb64_b = (ntb64_b << 32) | ntb;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    return ntb64_b;
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								void mac_sched_set_bp_ahead_alert(mac_vdev_t *vdev, uint16_t ahead)
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
								    uint32_t value;
							 | 
						||
| 
								 | 
							
								    (void)vdev;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    value = (((uint32_t)ahead) << CFG_BCN_ALERT_AHEAD_OFFSET)
							 | 
						||
| 
								 | 
							
								        & CFG_BCN_ALERT_AHEAD_MASK;
							 | 
						||
| 
								 | 
							
								    RGF_MAC_WRITE_REG(CFG_BEACON_ADDR, value);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								#if MAC_SCHED_HW_DEBUG
							 | 
						||
| 
								 | 
							
								    iot_printf("MAC_SCHED_HW ---%s--- CFG_BEACON_ADDR %x\n", __FUNCTION__,
							 | 
						||
| 
								 | 
							
								        value);
							 | 
						||
| 
								 | 
							
								#endif
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								void mac_sched_set_recursive_mode(mac_vdev_t *vdev, uint8_t enable)
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
								    uint32_t value;
							 | 
						||
| 
								 | 
							
								    (void)vdev;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    value = RGF_HWQ_READ_REG(CFG_SCHEDULE_ADDR);
							 | 
						||
| 
								 | 
							
								    value &= ~CFG_SCH_SELF_RECUR_EN_MASK;
							 | 
						||
| 
								 | 
							
								    value |= ((uint32_t)(enable & 0x01)) << CFG_SCH_SELF_RECUR_EN_OFFSET;
							 | 
						||
| 
								 | 
							
								    RGF_HWQ_WRITE_REG(CFG_SCHEDULE_ADDR, value);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								#if MAC_SCHED_HW_DEBUG
							 | 
						||
| 
								 | 
							
								    iot_printf("MAC_SCHED_HW ---%s--- CFG_SCHEDULE_ADDR %x\n", __FUNCTION__,
							 | 
						||
| 
								 | 
							
								        value);
							 | 
						||
| 
								 | 
							
								#endif
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								/* config start ntb of next beacon period */
							 | 
						||
| 
								 | 
							
								void mac_sched_set_bp_start_ntb(mac_vdev_t *vdev,
							 | 
						||
| 
								 | 
							
								    uint32_t start_ntb)
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
								    (void)vdev;
							 | 
						||
| 
								 | 
							
								#if ENA_WAR_440
							 | 
						||
| 
								 | 
							
								    g_phy_cpu_share_ctxt.bcn_start_update_ntb = \
							 | 
						||
| 
								 | 
							
								        RGF_MAC_READ_REG(CFG_RD_NTB_ADDR);
							 | 
						||
| 
								 | 
							
								#endif
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    RGF_MAC_WRITE_REG(CFG_BCN_START_NTB_ADDR, start_ntb);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								#if MAC_SCHED_HW_DEBUG
							 | 
						||
| 
								 | 
							
								    iot_printf("MAC_SCHED_HW ---%s--- CFG_BCN_START_NTB_ADDR %x\n",
							 | 
						||
| 
								 | 
							
								        __FUNCTION__, start_ntb);
							 | 
						||
| 
								 | 
							
								#endif
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								uint32_t mac_sched_get_bp_start_ntb()
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
								    return RGF_MAC_READ_REG(CFG_BCN_START_NTB_ADDR);
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								uint32_t mac_sched_get_bp_dur()
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
								    uint32_t tmp = RGF_MAC_READ_REG(CFG_BEACON_PERIOD_ADDR);
							 | 
						||
| 
								 | 
							
								    return REG_FIELD_GET(CFG_BEACON_PERIOD, tmp);
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								/* config next beacon period duration */
							 | 
						||
| 
								 | 
							
								void mac_sched_set_bp_dur(mac_vdev_t *vdev, uint16_t bp)
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
								    uint32_t value;
							 | 
						||
| 
								 | 
							
								    (void)vdev;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    value = (((uint32_t)bp) << CFG_BEACON_PERIOD_OFFSET)
							 | 
						||
| 
								 | 
							
								        & CFG_BEACON_PERIOD_MASK;
							 | 
						||
| 
								 | 
							
								    RGF_MAC_WRITE_REG(CFG_BEACON_PERIOD_ADDR, value);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								#if MAC_SCHED_HW_DEBUG
							 | 
						||
| 
								 | 
							
								    iot_printf("MAC_SCHED_HW ---%s--- CFG_BEACON_PERIOD_ADDR %x\n",
							 | 
						||
| 
								 | 
							
								        __FUNCTION__, value);
							 | 
						||
| 
								 | 
							
								#endif
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								/* config scheduler of next beacon period */
							 | 
						||
| 
								 | 
							
								void mac_sched_set_bp_cmd_list(mac_vdev_t *vdev, hw_sched_cmd_t *cmd,
							 | 
						||
| 
								 | 
							
								    uint16_t cnt)
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
								    uint32_t value;
							 | 
						||
| 
								 | 
							
								    (void)vdev;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    value = RGF_HWQ_READ_REG(CFG_SCHEDULE_ADDR);
							 | 
						||
| 
								 | 
							
								    value &= ~CFG_SCH_CMD_NUM_MASK;
							 | 
						||
| 
								 | 
							
								    value |= (((uint32_t)cnt << 1) << CFG_SCH_CMD_NUM_OFFSET)
							 | 
						||
| 
								 | 
							
								        & CFG_SCH_CMD_NUM_MASK;
							 | 
						||
| 
								 | 
							
								    RGF_HWQ_WRITE_REG(CFG_SCHEDULE_ADDR, value);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    RGF_HWQ_WRITE_REG(CFG_SCH_PTR_ADDR, (uint32_t)cmd);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								#if MAC_SCHED_HW_DEBUG
							 | 
						||
| 
								 | 
							
								    iot_printf("MAC_SCHED_HW ---%s--- CFG_SCHEDULE_ADDR %x\n", __FUNCTION__,
							 | 
						||
| 
								 | 
							
								        value);
							 | 
						||
| 
								 | 
							
								    iot_printf("MAC_SCHED_HW ---%s--- CFG_SCH_PTR_ADDR %x\n", __FUNCTION__,
							 | 
						||
| 
								 | 
							
								        cmd);
							 | 
						||
| 
								 | 
							
								#endif
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								/* get cmd list cnt being used by HW */
							 | 
						||
| 
								 | 
							
								uint8_t mac_sched_get_cmd_list_cnt(mac_vdev_t *vdev)
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
								    uint32_t value;
							 | 
						||
| 
								 | 
							
								    (void)vdev;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    value = RGF_HWQ_READ_REG(CFG_SCHEDULE_ADDR);
							 | 
						||
| 
								 | 
							
								    value &= SCH_CUR_NUM_MASK;
							 | 
						||
| 
								 | 
							
								    value >>= SCH_CUR_NUM_OFFSET;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    return (uint8_t)value;
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								/* write trigger for the next beacon period */
							 | 
						||
| 
								 | 
							
								void mac_sched_trigger_bp(mac_vdev_t *vdev)
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
								    uint32_t value;
							 | 
						||
| 
								 | 
							
								    (void)vdev;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    value = RGF_HWQ_READ_REG(CFG_SCHEDULE_ADDR);
							 | 
						||
| 
								 | 
							
								    if (value & SCH_WR_TRIG_ENABLE_MASK) {
							 | 
						||
| 
								 | 
							
								        value |= 1 << CFG_SCH_WR_TRIG_OFFSET;
							 | 
						||
| 
								 | 
							
								        RGF_HWQ_WRITE_REG(CFG_SCHEDULE_ADDR, value);
							 | 
						||
| 
								 | 
							
								    } else {
							 | 
						||
| 
								 | 
							
								        IOT_ASSERT(0);
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								#if MAC_SCHED_HW_DEBUG
							 | 
						||
| 
								 | 
							
								    iot_printf("MAC_SCHED_HW ---%s--- CFG_SCHEDULE_ADDR %x\n", __FUNCTION__,
							 | 
						||
| 
								 | 
							
								        value);
							 | 
						||
| 
								 | 
							
								#endif
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								#define SCHED_ENABLE_SYNC_MAX_LOOP      0xFFFFFFFE
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								/* enable or disable scheduler of next beacon period */
							 | 
						||
| 
								 | 
							
								void mac_sched_enable_bp(mac_vdev_t *vdev, uint8_t enable)
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
								    uint32_t i, value;
							 | 
						||
| 
								 | 
							
								    (void)vdev;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    value = RGF_HWQ_READ_REG(CFG_SCHEDULE_ADDR);
							 | 
						||
| 
								 | 
							
								    /* check if HW scheduler already enabled or disabled */
							 | 
						||
| 
								 | 
							
								    if ((!!(value & SCH_STATUS_MASK)) == (!!enable))
							 | 
						||
| 
								 | 
							
								        return;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    /* enable or disable HW scheduler */
							 | 
						||
| 
								 | 
							
								    value &= ~CFG_SCH_EN_MASK;
							 | 
						||
| 
								 | 
							
								    value |= (((uint32_t)(enable & 0x01)) << CFG_SCH_EN_OFFSET)
							 | 
						||
| 
								 | 
							
								        & CFG_SCH_EN_MASK;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								#if DEBUG_HWQ_SHCED_HANG
							 | 
						||
| 
								 | 
							
								    /* WAR: if TX in progress, stop SCH would make hw tx hang
							 | 
						||
| 
								 | 
							
								     * to avoid this happen, we need to poll till we're not
							 | 
						||
| 
								 | 
							
								     * in TX process
							 | 
						||
| 
								 | 
							
								     */
							 | 
						||
| 
								 | 
							
								    if (!!enable == 0) {
							 | 
						||
| 
								 | 
							
								        /* if to disable SCH */
							 | 
						||
| 
								 | 
							
								        uint32_t iscco = (PLC_DEV_ROLE_CCO == mac_vdev_cfg_get_node_role(vdev));
							 | 
						||
| 
								 | 
							
								        mac_tx_wait_all_queue_idle(iscco, MAC_WAIT_TX_IDLE_TIEM_MS);
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								#endif
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    RGF_HWQ_WRITE_REG(CFG_SCHEDULE_ADDR, value);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								#if MAC_SCHED_HW_DEBUG
							 | 
						||
| 
								 | 
							
								    iot_printf("MAC_SCHED_HW ---%s--- CFG_SCHEDULE_ADDR %x\n", __FUNCTION__,
							 | 
						||
| 
								 | 
							
								        value);
							 | 
						||
| 
								 | 
							
								#endif
							 | 
						||
| 
								 | 
							
								#if DEBUG_HWQ_SHCED_HANG
							 | 
						||
| 
								 | 
							
								    uint32_t debug_cnt = 0;
							 | 
						||
| 
								 | 
							
								#endif
							 | 
						||
| 
								 | 
							
								    if (!mac_txq_is_dbg_mode()) {
							 | 
						||
| 
								 | 
							
								        /* if sch mode */
							 | 
						||
| 
								 | 
							
								        /* make sure the HW scheduler status is in sync */
							 | 
						||
| 
								 | 
							
								        for (i = 0; i < SCHED_ENABLE_SYNC_MAX_LOOP; i++) {
							 | 
						||
| 
								 | 
							
								            value = RGF_HWQ_READ_REG(CFG_SCHEDULE_ADDR);
							 | 
						||
| 
								 | 
							
								            if ((!!(value & SCH_STATUS_MASK)) == (!!enable)) {
							 | 
						||
| 
								 | 
							
								                break;
							 | 
						||
| 
								 | 
							
								            }
							 | 
						||
| 
								 | 
							
								            if (i & 0x100) {
							 | 
						||
| 
								 | 
							
								                /* try to enable or disable again */
							 | 
						||
| 
								 | 
							
								                REG_FIELD_SET(CFG_SCH_EN, value, enable & 0x01);
							 | 
						||
| 
								 | 
							
								                RGF_HWQ_WRITE_REG(CFG_SCHEDULE_ADDR, value);
							 | 
						||
| 
								 | 
							
								            }
							 | 
						||
| 
								 | 
							
								#if DEBUG_HWQ_SHCED_HANG
							 | 
						||
| 
								 | 
							
								            debug_cnt++;
							 | 
						||
| 
								 | 
							
								            if(debug_cnt > MAX_WAIT_DUMP_CNT)
							 | 
						||
| 
								 | 
							
								            {
							 | 
						||
| 
								 | 
							
								                mac_dump_buf(MAC_DUMP_TYPE_5, NULL, 0, \
							 | 
						||
| 
								 | 
							
								                    (uint32_t *)RGF_HWQ_BASEADDR, 108, \
							 | 
						||
| 
								 | 
							
								                    (uint32_t *)RGF_RX_BASEADDR, 69, true);
							 | 
						||
| 
								 | 
							
								            }
							 | 
						||
| 
								 | 
							
								#endif
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								        if (i >= SCHED_ENABLE_SYNC_MAX_LOOP)
							 | 
						||
| 
								 | 
							
								            IOT_ASSERT(0);
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    if (!enable) {
							 | 
						||
| 
								 | 
							
								        /* clear schduler command list if scheduler disabled */
							 | 
						||
| 
								 | 
							
								        value = RGF_HWQ_READ_REG(CFG_SCHEDULE_ADDR);
							 | 
						||
| 
								 | 
							
								        value |= CFG_SCH_CLR_MASK;
							 | 
						||
| 
								 | 
							
								        RGF_HWQ_WRITE_REG(CFG_SCHEDULE_ADDR, value);
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								#endif /* HW_PLATFORM >= HW_PLATFORM_FPGA */
							 |