sdk-hwV1.3/lichee/linux-4.9/drivers/net/phy/rtl8363_nb/interrupt.c

515 lines
14 KiB
C
Executable File

/*
* Copyright (C) 2013 Realtek Semiconductor Corp.
* All Rights Reserved.
*
* This program is the proprietary software of Realtek Semiconductor
* Corporation and/or its licensors, and only be used, duplicated,
* modified or distributed under the authorized license from Realtek.
*
* ANY USE OF THE SOFTWARE OTHER THAN AS AUTHORIZED UNDER
* THIS LICENSE OR COPYRIGHT LAW IS PROHIBITED.
*
* $Revision: 79629 $
* $Date: 2017-06-14 18:08:03 +0800 (週三, 14 六月 2017) $
*
* Purpose : RTK switch high-level API for RTL8367/RTL8367C
* Feature : Here is a list of all functions and variables in Interrupt module.
*
*/
#include <rtk_switch.h>
#include <rtk_error.h>
#include <interrupt.h>
#include <linux/string.h>
#include <rtl8367c_asicdrv.h>
#include <rtl8367c_asicdrv_interrupt.h>
static rtk_api_ret_t _rtk_int_polarity_set(rtk_int_polarity_t type)
{
rtk_api_ret_t retVal;
/* Check initialization state */
RTK_CHK_INIT_STATE();
if(type >= INT_POLAR_END)
return RT_ERR_INPUT;
if ((retVal = rtl8367c_setAsicInterruptPolarity(type)) != RT_ERR_OK)
return retVal;
return RT_ERR_OK;
}
static rtk_api_ret_t _rtk_int_polarity_get(rtk_int_polarity_t *pType)
{
rtk_api_ret_t retVal;
/* Check initialization state */
RTK_CHK_INIT_STATE();
if(NULL == pType)
return RT_ERR_NULL_POINTER;
if ((retVal = rtl8367c_getAsicInterruptPolarity(pType)) != RT_ERR_OK)
return retVal;
return RT_ERR_OK;
}
static rtk_api_ret_t _rtk_int_control_set(rtk_int_type_t type, rtk_enable_t enable)
{
rtk_api_ret_t retVal;
rtk_uint32 mask;
/* Check initialization state */
RTK_CHK_INIT_STATE();
if (type >= INT_TYPE_END)
return RT_ERR_INPUT;
if (type == INT_TYPE_RESERVED)
return RT_ERR_INPUT;
if ((retVal = rtl8367c_getAsicInterruptMask(&mask)) != RT_ERR_OK)
return retVal;
if (ENABLED == enable)
mask = mask | (1<<type);
else if (DISABLED == enable)
mask = mask & ~(1<<type);
else
return RT_ERR_INPUT;
if ((retVal = rtl8367c_setAsicInterruptMask(mask)) != RT_ERR_OK)
return retVal;
return RT_ERR_OK;
}
static rtk_api_ret_t _rtk_int_control_get(rtk_int_type_t type, rtk_enable_t *pEnable)
{
rtk_api_ret_t retVal;
rtk_uint32 mask;
/* Check initialization state */
RTK_CHK_INIT_STATE();
if(NULL == pEnable)
return RT_ERR_NULL_POINTER;
if ((retVal = rtl8367c_getAsicInterruptMask(&mask)) != RT_ERR_OK)
return retVal;
if (0 == (mask&(1<<type)))
*pEnable=DISABLED;
else
*pEnable=ENABLED;
return RT_ERR_OK;
}
static rtk_api_ret_t _rtk_int_status_set(rtk_int_status_t *pStatusMask)
{
rtk_api_ret_t retVal;
/* Check initialization state */
RTK_CHK_INIT_STATE();
if(NULL == pStatusMask)
return RT_ERR_NULL_POINTER;
if(pStatusMask->value[0] & (0x0001 << INT_TYPE_RESERVED))
return RT_ERR_INPUT;
if(pStatusMask->value[0] >= (0x0001 << INT_TYPE_END))
return RT_ERR_INPUT;
if ((retVal = rtl8367c_setAsicInterruptStatus((rtk_uint32)pStatusMask->value[0]))!=RT_ERR_OK)
return retVal;
return RT_ERR_OK;
}
static rtk_api_ret_t _rtk_int_status_get(rtk_int_status_t* pStatusMask)
{
rtk_api_ret_t retVal;
rtk_uint32 ims_mask;
/* Check initialization state */
RTK_CHK_INIT_STATE();
if(NULL == pStatusMask)
return RT_ERR_NULL_POINTER;
if ((retVal = rtl8367c_getAsicInterruptStatus(&ims_mask)) != RT_ERR_OK)
return retVal;
pStatusMask->value[0] = (ims_mask & 0x00000FFF);
return RT_ERR_OK;
}
#define ADV_NOT_SUPPORT (0xFFFF)
static rtk_api_ret_t _rtk_int_Advidx_get(rtk_int_advType_t adv_type, rtk_uint32 *pAsic_idx)
{
rtk_uint32 asic_idx[ADV_END] =
{
INTRST_L2_LEARN,
INTRST_SPEED_CHANGE,
INTRST_SPECIAL_CONGESTION,
INTRST_PORT_LINKDOWN,
INTRST_PORT_LINKUP,
ADV_NOT_SUPPORT,
INTRST_RLDP_LOOPED,
INTRST_RLDP_RELEASED,
};
if(adv_type >= ADV_END)
return RT_ERR_INPUT;
if(asic_idx[adv_type] == ADV_NOT_SUPPORT)
return RT_ERR_CHIP_NOT_SUPPORTED;
*pAsic_idx = asic_idx[adv_type];
return RT_ERR_OK;
}
static rtk_api_ret_t _rtk_int_advanceInfo_get(rtk_int_advType_t adv_type, rtk_int_info_t *pInfo)
{
rtk_api_ret_t retVal;
rtk_uint32 data;
rtk_uint32 intAdvType;
/* Check initialization state */
RTK_CHK_INIT_STATE();
if(adv_type >= ADV_END)
return RT_ERR_INPUT;
if(NULL == pInfo)
return RT_ERR_NULL_POINTER;
if(adv_type != ADV_METER_EXCEED_MASK)
{
if((retVal = _rtk_int_Advidx_get(adv_type, &intAdvType)) != RT_ERR_OK)
return retVal;
}
switch(adv_type)
{
case ADV_L2_LEARN_PORT_MASK:
/* Get physical portmask */
if((retVal = rtl8367c_getAsicInterruptRelatedStatus(intAdvType, &data)) != RT_ERR_OK)
return retVal;
/* Clear Advanced Info */
if((retVal = rtl8367c_setAsicInterruptRelatedStatus(intAdvType, 0xFFFF)) != RT_ERR_OK)
return retVal;
/* Translate to logical portmask */
if((retVal = rtk_switch_portmask_P2L_get(data, &(pInfo->portMask))) != RT_ERR_OK)
return retVal;
/* Get system learn */
if((retVal = rtl8367c_getAsicInterruptRelatedStatus(INTRST_SYS_LEARN, &data)) != RT_ERR_OK)
return retVal;
/* Clear system learn */
if((retVal = rtl8367c_setAsicInterruptRelatedStatus(INTRST_SYS_LEARN, 0x0001)) != RT_ERR_OK)
return retVal;
pInfo->systemLearnOver = data;
break;
case ADV_SPEED_CHANGE_PORT_MASK:
case ADV_SPECIAL_CONGESTION_PORT_MASK:
case ADV_PORT_LINKDOWN_PORT_MASK:
case ADV_PORT_LINKUP_PORT_MASK:
case ADV_RLDP_LOOPED:
case ADV_RLDP_RELEASED:
/* Get physical portmask */
if((retVal = rtl8367c_getAsicInterruptRelatedStatus(intAdvType, &data)) != RT_ERR_OK)
return retVal;
/* Clear Advanced Info */
if((retVal = rtl8367c_setAsicInterruptRelatedStatus(intAdvType, 0xFFFF)) != RT_ERR_OK)
return retVal;
/* Translate to logical portmask */
if((retVal = rtk_switch_portmask_P2L_get(data, &(pInfo->portMask))) != RT_ERR_OK)
return retVal;
break;
case ADV_METER_EXCEED_MASK:
/* Get Meter Mask */
if((retVal = rtl8367c_getAsicInterruptRelatedStatus(INTRST_METER0_15, &data)) != RT_ERR_OK)
return retVal;
/* Clear Advanced Info */
if((retVal = rtl8367c_setAsicInterruptRelatedStatus(INTRST_METER0_15, 0xFFFF)) != RT_ERR_OK)
return retVal;
pInfo->meterMask = data & 0xFFFF;
/* Get Meter Mask */
if((retVal = rtl8367c_getAsicInterruptRelatedStatus(INTRST_METER16_31, &data)) != RT_ERR_OK)
return retVal;
/* Clear Advanced Info */
if((retVal = rtl8367c_setAsicInterruptRelatedStatus(INTRST_METER16_31, 0xFFFF)) != RT_ERR_OK)
return retVal;
pInfo->meterMask = pInfo->meterMask | ((data << 16) & 0xFFFF0000);
break;
default:
return RT_ERR_INPUT;
}
return RT_ERR_OK;
}
/* Function Name:
* rtk_int_polarity_set
* Description:
* Set interrupt polarity configuration.
* Input:
* type - Interruptpolarity type.
* Output:
* None
* Return:
* RT_ERR_OK - OK
* RT_ERR_FAILED - Failed
* RT_ERR_SMI - SMI access error
* RT_ERR_INPUT - Invalid input parameters.
* Note:
* The API can set interrupt polarity configuration.
*/
rtk_api_ret_t rtk_int_polarity_set(rtk_int_polarity_t type)
{
rtk_api_ret_t retVal;
RTK_API_LOCK();
retVal = _rtk_int_polarity_set(type);
RTK_API_UNLOCK();
return retVal;
}
/* Function Name:
* rtk_int_polarity_get
* Description:
* Get interrupt polarity configuration.
* Input:
* None
* Output:
* pType - Interruptpolarity type.
* Return:
* RT_ERR_OK - OK
* RT_ERR_FAILED - Failed
* RT_ERR_SMI - SMI access error
* Note:
* The API can get interrupt polarity configuration.
*/
rtk_api_ret_t rtk_int_polarity_get(rtk_int_polarity_t *pType)
{
rtk_api_ret_t retVal;
RTK_API_LOCK();
retVal = _rtk_int_polarity_get(pType);
RTK_API_UNLOCK();
return retVal;
}
/* Function Name:
* rtk_int_control_set
* Description:
* Set interrupt trigger status configuration.
* Input:
* type - Interrupt type.
* enable - Interrupt status.
* Output:
* None
* Return:
* RT_ERR_OK - OK
* RT_ERR_FAILED - Failed
* RT_ERR_SMI - SMI access error
* RT_ERR_INPUT - Invalid input parameters.
* RT_ERR_ENABLE - Invalid enable input.
* Note:
* The API can set interrupt status configuration.
* The interrupt trigger status is shown in the following:
* - INT_TYPE_LINK_STATUS
* - INT_TYPE_METER_EXCEED
* - INT_TYPE_LEARN_LIMIT
* - INT_TYPE_LINK_SPEED
* - INT_TYPE_CONGEST
* - INT_TYPE_GREEN_FEATURE
* - INT_TYPE_LOOP_DETECT
* - INT_TYPE_8051,
* - INT_TYPE_CABLE_DIAG,
* - INT_TYPE_ACL,
* - INT_TYPE_SLIENT
*/
rtk_api_ret_t rtk_int_control_set(rtk_int_type_t type, rtk_enable_t enable)
{
rtk_api_ret_t retVal;
RTK_API_LOCK();
retVal = _rtk_int_control_set(type, enable);
RTK_API_UNLOCK();
return retVal;
}
/* Function Name:
* rtk_int_control_get
* Description:
* Get interrupt trigger status configuration.
* Input:
* type - Interrupt type.
* Output:
* pEnable - Interrupt status.
* Return:
* RT_ERR_OK - OK
* RT_ERR_FAILED - Failed
* RT_ERR_SMI - SMI access error
* RT_ERR_INPUT - Invalid input parameters.
* Note:
* The API can get interrupt status configuration.
* The interrupt trigger status is shown in the following:
* - INT_TYPE_LINK_STATUS
* - INT_TYPE_METER_EXCEED
* - INT_TYPE_LEARN_LIMIT
* - INT_TYPE_LINK_SPEED
* - INT_TYPE_CONGEST
* - INT_TYPE_GREEN_FEATURE
* - INT_TYPE_LOOP_DETECT
* - INT_TYPE_8051,
* - INT_TYPE_CABLE_DIAG,
* - INT_TYPE_ACL,
* - INT_TYPE_UPS,
* - INT_TYPE_SLIENT
*/
rtk_api_ret_t rtk_int_control_get(rtk_int_type_t type, rtk_enable_t *pEnable)
{
rtk_api_ret_t retVal;
RTK_API_LOCK();
retVal = _rtk_int_control_get(type, pEnable);
RTK_API_UNLOCK();
return retVal;
}
/* Function Name:
* rtk_int_status_set
* Description:
* Set interrupt trigger status to clean.
* Input:
* None
* Output:
* pStatusMask - Interrupt status bit mask.
* Return:
* RT_ERR_OK - OK
* RT_ERR_FAILED - Failed
* RT_ERR_SMI - SMI access error
* RT_ERR_INPUT - Invalid input parameters.
* Note:
* The API can clean interrupt trigger status when interrupt happened.
* The interrupt trigger status is shown in the following:
* - INT_TYPE_LINK_STATUS (value[0] (Bit0))
* - INT_TYPE_METER_EXCEED (value[0] (Bit1))
* - INT_TYPE_LEARN_LIMIT (value[0] (Bit2))
* - INT_TYPE_LINK_SPEED (value[0] (Bit3))
* - INT_TYPE_CONGEST (value[0] (Bit4))
* - INT_TYPE_GREEN_FEATURE (value[0] (Bit5))
* - INT_TYPE_LOOP_DETECT (value[0] (Bit6))
* - INT_TYPE_8051 (value[0] (Bit7))
* - INT_TYPE_CABLE_DIAG (value[0] (Bit8))
* - INT_TYPE_ACL (value[0] (Bit9))
* - INT_TYPE_SLIENT (value[0] (Bit11))
* The status will be cleared after execute this API.
*/
rtk_api_ret_t rtk_int_status_set(rtk_int_status_t *pStatusMask)
{
rtk_api_ret_t retVal;
RTK_API_LOCK();
retVal = _rtk_int_status_set(pStatusMask);
RTK_API_UNLOCK();
return retVal;
}
/* Function Name:
* rtk_int_status_get
* Description:
* Get interrupt trigger status.
* Input:
* None
* Output:
* pStatusMask - Interrupt status bit mask.
* Return:
* RT_ERR_OK - OK
* RT_ERR_FAILED - Failed
* RT_ERR_SMI - SMI access error
* RT_ERR_INPUT - Invalid input parameters.
* Note:
* The API can get interrupt trigger status when interrupt happened.
* The interrupt trigger status is shown in the following:
* - INT_TYPE_LINK_STATUS (value[0] (Bit0))
* - INT_TYPE_METER_EXCEED (value[0] (Bit1))
* - INT_TYPE_LEARN_LIMIT (value[0] (Bit2))
* - INT_TYPE_LINK_SPEED (value[0] (Bit3))
* - INT_TYPE_CONGEST (value[0] (Bit4))
* - INT_TYPE_GREEN_FEATURE (value[0] (Bit5))
* - INT_TYPE_LOOP_DETECT (value[0] (Bit6))
* - INT_TYPE_8051 (value[0] (Bit7))
* - INT_TYPE_CABLE_DIAG (value[0] (Bit8))
* - INT_TYPE_ACL (value[0] (Bit9))
* - INT_TYPE_SLIENT (value[0] (Bit11))
*
*/
rtk_api_ret_t rtk_int_status_get(rtk_int_status_t* pStatusMask)
{
rtk_api_ret_t retVal;
RTK_API_LOCK();
retVal = _rtk_int_status_get(pStatusMask);
RTK_API_UNLOCK();
return retVal;
}
/* Function Name:
* rtk_int_advanceInfo_get
* Description:
* Get interrupt advanced information.
* Input:
* adv_type - Advanced interrupt type.
* Output:
* info - Information per type.
* Return:
* RT_ERR_OK - OK
* RT_ERR_FAILED - Failed
* RT_ERR_SMI - SMI access error
* RT_ERR_INPUT - Invalid input parameters.
* Note:
* This API can get advanced information when interrupt happened.
* The status will be cleared after execute this API.
*/
rtk_api_ret_t rtk_int_advanceInfo_get(rtk_int_advType_t adv_type, rtk_int_info_t *pInfo)
{
rtk_api_ret_t retVal;
RTK_API_LOCK();
retVal = _rtk_int_advanceInfo_get(adv_type, pInfo);
RTK_API_UNLOCK();
return retVal;
}