2022-11-10 22:22:48 +08:00
|
|
|
|
/*
|
|
|
|
|
* Copyright : (C) 2022 Phytium Information Technology, Inc.
|
|
|
|
|
* All Rights Reserved.
|
|
|
|
|
*
|
|
|
|
|
* This program is OPEN SOURCE software: you can redistribute it and/or modify it
|
|
|
|
|
* under the terms of the Phytium Public License as published by the Phytium Technology Co.,Ltd,
|
|
|
|
|
* either version 1.0 of the License, or (at your option) any later version.
|
|
|
|
|
*
|
|
|
|
|
* This program is distributed in the hope that it will be useful,but WITHOUT ANY WARRANTY;
|
|
|
|
|
* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
|
|
|
|
* See the Phytium Public License for more details.
|
|
|
|
|
*
|
|
|
|
|
*
|
|
|
|
|
* FilePath: fgmac_intr.c
|
|
|
|
|
* Date: 2022-04-06 14:46:52
|
|
|
|
|
* LastEditTime: 2022-04-06 14:46:58
|
2023-05-11 10:25:21 +08:00
|
|
|
|
* Description: Functions in this file implement general purpose interrupt processing related
|
|
|
|
|
* functionality.
|
2022-11-10 22:22:48 +08:00
|
|
|
|
*
|
|
|
|
|
* Modify History:
|
|
|
|
|
* Ver Who Date Changes
|
|
|
|
|
* ----- ------ -------- --------------------------------------
|
2023-05-11 10:25:21 +08:00
|
|
|
|
* 1.0 huanghe 2021/07/13 first release
|
2022-11-10 22:22:48 +08:00
|
|
|
|
*/
|
|
|
|
|
|
|
|
|
|
/***************************** Include Files *********************************/
|
|
|
|
|
|
|
|
|
|
#include "fgmac.h"
|
|
|
|
|
#include "fgmac_hw.h"
|
|
|
|
|
|
|
|
|
|
/************************** Constant Definitions *****************************/
|
|
|
|
|
|
|
|
|
|
/**************************** Type Definitions *******************************/
|
|
|
|
|
|
|
|
|
|
/***************** Macros (Inline Functions) Definitions *********************/
|
|
|
|
|
#define FGMAC_CALL_EVT_HANDLER(instance_p, evt) \
|
|
|
|
|
{\
|
|
|
|
|
if (NULL != (instance_p)->evt_handler[(evt)]) \
|
|
|
|
|
{ \
|
|
|
|
|
(instance_p)->evt_handler[evt]((void *)(instance_p)); \
|
|
|
|
|
}\
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/************************** Variable Definitions *****************************/
|
|
|
|
|
|
|
|
|
|
/************************** Function Prototypes ******************************/
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* @name: FGmacInterruptHandler
|
|
|
|
|
* @msg: FGMAC中断处理函数
|
|
|
|
|
* @return {*}
|
|
|
|
|
* @param {s32} vector, 中断向量号,此处没有用到
|
|
|
|
|
{void} *param, 中断输入参数,此处传入的是FGMAC的驱动控制数据
|
|
|
|
|
* @note 此函数运行在中断上下文
|
|
|
|
|
*/
|
|
|
|
|
void FGmacInterruptHandler(s32 vector, void *param)
|
|
|
|
|
{
|
|
|
|
|
FASSERT(param);
|
|
|
|
|
FGmac *instance_p = (FGmac *)param;
|
|
|
|
|
uintptr base_addr = instance_p->config.base_addr;
|
|
|
|
|
u32 status = 0;
|
|
|
|
|
|
|
|
|
|
/* dma interrupt */
|
|
|
|
|
status = FGMAC_READ_REG32(base_addr, FGMAC_DMA_STATUS_OFFSET);
|
|
|
|
|
|
|
|
|
|
if (FGMAC_DMA_STATUS_GLI & status)
|
|
|
|
|
{
|
|
|
|
|
FGMAC_CALL_EVT_HANDLER(instance_p, FGMAC_PHY_STATUS_EVT);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (FGMAC_DMA_STATUS_RI & status)
|
|
|
|
|
{
|
|
|
|
|
FGMAC_CALL_EVT_HANDLER(instance_p, FGMAC_RX_COMPLETE_EVT);
|
|
|
|
|
FGMAC_SET_REG32(base_addr, FGMAC_DMA_STATUS_OFFSET, FGMAC_DMA_STATUS_RI); /* write to clear */
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (FGMAC_DMA_STATUS_TI & status)
|
|
|
|
|
{
|
|
|
|
|
FGMAC_CALL_EVT_HANDLER(instance_p, FGMAC_TX_COMPLETE_EVT);
|
|
|
|
|
FGMAC_SET_REG32(base_addr, FGMAC_DMA_STATUS_OFFSET, FGMAC_DMA_STATUS_TI); /* write to clear */
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (FGMAC_DMA_STATUS_AIS & status)
|
|
|
|
|
{
|
|
|
|
|
FGMAC_CALL_EVT_HANDLER(instance_p, FGMAC_DMA_ERR_EVT);
|
|
|
|
|
FGMAC_SET_REG32(base_addr, FGMAC_DMA_STATUS_OFFSET, FGMAC_DMA_STATUS_CLR_ABLE);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
FGMAC_WRITE_REG32(base_addr, FGMAC_DMA_STATUS_OFFSET, status); /* write to clear */
|
|
|
|
|
|
|
|
|
|
/* RGMII/SGMII Interrupt */
|
|
|
|
|
status = FGMAC_READ_REG32(base_addr, FGMAC_INTR_STATUS_OFFSET);
|
|
|
|
|
if (status & FGMAC_ISR_STATUS_RSIS)
|
|
|
|
|
{
|
|
|
|
|
/* status changed, read SGMII register to clear */
|
|
|
|
|
FGMAC_READ_REG32(base_addr, FGMAC_MAC_PHY_STATUS);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* @name: FGmacRegisterEvtHandler
|
|
|
|
|
* @msg: 注册FGMAC中断事件响应函数
|
|
|
|
|
* @return {*}
|
|
|
|
|
* @param {FGmac} *instance_p 驱动控制数据
|
|
|
|
|
* @param {u32} evt 中断事件类型
|
|
|
|
|
* @param {FGmacEvtHandler} handler 中断事件响应函数
|
|
|
|
|
* @note 注册的函数handler会在中断上下文执行
|
|
|
|
|
*/
|
|
|
|
|
void FGmacRegisterEvtHandler(FGmac *instance_p, u32 evt, FGmacEvtHandler handler)
|
|
|
|
|
{
|
|
|
|
|
FASSERT((NULL != instance_p) && (FGMAC_INTR_EVT_NUM > evt));
|
|
|
|
|
instance_p->evt_handler[evt] = handler;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* @name: FGmacSetInterruptMask
|
|
|
|
|
* @msg: 屏蔽FGMAC中断
|
|
|
|
|
* @return {*}
|
|
|
|
|
* @param {FGmac} *instance_p 驱动控制数据
|
|
|
|
|
* @param {u32} intr_type 中断类型 GMAC中断/DMA中断
|
|
|
|
|
* @param {u32} mask 中断屏蔽位
|
|
|
|
|
* @note 在FGMAC驱动初始化成功后调用此函数
|
|
|
|
|
*/
|
|
|
|
|
void FGmacSetInterruptMask(FGmac *instance_p, u32 intr_type, u32 mask)
|
|
|
|
|
{
|
|
|
|
|
FASSERT(instance_p);
|
|
|
|
|
FASSERT(FGMAC_MAX_INTR_TYPE > intr_type);
|
|
|
|
|
u32 cur_mask = 0;
|
|
|
|
|
uintptr base_addr = instance_p->config.base_addr;
|
|
|
|
|
|
|
|
|
|
if (FGMAC_CTRL_INTR == intr_type)
|
|
|
|
|
{
|
|
|
|
|
cur_mask = FGMAC_READ_REG32(base_addr, FGMAC_INTR_MASK_OFFSET);
|
|
|
|
|
cur_mask |= mask;
|
|
|
|
|
FGMAC_WRITE_REG32(base_addr, FGMAC_INTR_MASK_OFFSET, cur_mask);
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
cur_mask = FGMAC_READ_REG32(base_addr, FGMAC_DMA_INTR_OFFSET);
|
|
|
|
|
cur_mask &= (~mask);
|
|
|
|
|
FGMAC_WRITE_REG32(base_addr, FGMAC_DMA_INTR_OFFSET, cur_mask);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* @name: FGmacSetInterruptUmask
|
|
|
|
|
* @msg: 使能FGMAC中断
|
|
|
|
|
* @return {*}
|
|
|
|
|
* @param {FGmac} *instance_p 驱动控制数据
|
|
|
|
|
* @param {u32} intr_type 中断类型 GMAC中断/DMA中断
|
|
|
|
|
* @param {u32} mask 中断使能标志位
|
|
|
|
|
* @note 在FGMAC驱动初始化成功后调用此函数
|
|
|
|
|
*/
|
|
|
|
|
void FGmacSetInterruptUmask(FGmac *instance_p, u32 intr_type, u32 mask)
|
|
|
|
|
{
|
|
|
|
|
FASSERT(instance_p);
|
|
|
|
|
FASSERT(FGMAC_MAX_INTR_TYPE > intr_type);
|
|
|
|
|
u32 cur_mask = 0;
|
|
|
|
|
uintptr base_addr = instance_p->config.base_addr;
|
|
|
|
|
|
|
|
|
|
if (FGMAC_CTRL_INTR == intr_type)
|
|
|
|
|
{
|
|
|
|
|
cur_mask = FGMAC_READ_REG32(base_addr, FGMAC_INTR_MASK_OFFSET);
|
|
|
|
|
cur_mask &= (~mask);
|
|
|
|
|
FGMAC_WRITE_REG32(base_addr, FGMAC_INTR_MASK_OFFSET, cur_mask);
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
cur_mask = FGMAC_READ_REG32(base_addr, FGMAC_DMA_INTR_OFFSET);
|
|
|
|
|
cur_mask |= mask;
|
|
|
|
|
FGMAC_WRITE_REG32(base_addr, FGMAC_DMA_INTR_OFFSET, cur_mask);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return;
|
|
|
|
|
}
|