| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403 |
- /*
- * 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: fxmac_intr.c
- * Date: 2022-04-06 14:46:52
- * LastEditTime: 2022-04-06 14:46:58
- * Description: This file is for
- *
- * Modify History:
- * Ver Who Date Changes
- * ----- ------ -------- --------------------------------------
- */
- #include "fxmac.h"
- #include "fxmac_hw.h"
- #include "fassert.h"
- /************************** Constant Definitions *****************************/
- /**************************** Type Definitions *******************************/
- /***************** Macros (Inline Functions) Definitions *********************/
- /************************** Function Prototypes ******************************/
- /************************** Variable Definitions *****************************/
- /**
- * @name: FXmacSetHandler
- * @msg: Install an asynchronous handler function for the given handler_type:
- *
- * @param instance_p is a pointer to the instance to be worked on.
- * @param handler_type indicates what interrupt handler type is.
- * FXMAC_HANDLER_DMASEND, FXMAC_HANDLER_DMARECV and
- * FXMAC_HANDLER_ERROR.
- * @param func_pointer is the pointer to the callback function
- * @param call_back_ref is the upper layer callback reference passed back when
- * when the callback function is invoked.
- *
- * @return {FError} FT_SUCCESS set is ok
- */
- FError FXmacSetHandler(FXmac *instance_p, u32 handler_type,
- void *func_pointer, void *call_back_ref)
- {
- FError status;
- FASSERT(instance_p != NULL);
- FASSERT(func_pointer != NULL);
- FASSERT(instance_p->is_ready == (u32)FT_COMPONENT_IS_READY);
- status = (FError)(FT_SUCCESS);
- switch (handler_type)
- {
- case FXMAC_HANDLER_DMASEND:
- instance_p->send_irq_handler = ((FXmacIrqHandler)(void *)func_pointer);
- instance_p->send_args = call_back_ref;
- break;
- case FXMAC_HANDLER_DMARECV:
- instance_p->recv_irq_handler = ((FXmacIrqHandler)(void *)func_pointer);
- instance_p->recv_args = call_back_ref;
- break;
- case FXMAC_HANDLER_ERROR:
- instance_p->error_irq_handler = ((FXmacErrorIrqHandler)(void *)func_pointer);
- instance_p->error_args = call_back_ref;
- break;
- case FXMAC_HANDLER_LINKCHANGE:
- instance_p->link_change_handler = ((FXmacIrqHandler)(void *)func_pointer);
- instance_p->link_change_args = call_back_ref;
- break;
- case FXMAC_HANDLER_RESTART:
- instance_p->restart_handler = ((FXmacIrqHandler)(void *)func_pointer);
- instance_p->restart_args = call_back_ref;
- break;
- default:
- status = (FError)(FXMAC_ERR_INVALID_PARAM);
- break;
- }
- return status;
- }
- /**
- * @name: FXmacIntrHandler
- * @msg: 中断处理函数
- * @param {s32} vector is interrrupt num
- * @param {void} *args is a arguments variables
- * @return {*}
- * @note 目前中断只支持单queue的情况
- */
- void FXmacIntrHandler(s32 vector, void *args)
- {
- u32 reg_isr;
- u32 reg_qx_isr;
- u32 reg_temp;
- u32 reg_ctrl;
- u32 tx_queue_id; /* 0 ~ FT_XMAC_QUEUE_MAX_NUM ,Index queue number */
- u32 rx_queue_id; /* 0 ~ FT_XMAC_QUEUE_MAX_NUM ,Index queue number */
- FXmac *instance_p = (FXmac *)args;
- FASSERT(instance_p != NULL);
- FASSERT(instance_p->is_ready == (u32)FT_COMPONENT_IS_READY);
- tx_queue_id = instance_p->tx_bd_queue.queue_id;
- rx_queue_id = instance_p->rx_bd_queue.queue_id;
- FASSERT((rx_queue_id < FT_XMAC_QUEUE_MAX_NUM) && (tx_queue_id < FT_XMAC_QUEUE_MAX_NUM))
- /* This ISR will try to handle as many interrupts as it can in a single
- * call. However, in most of the places where the user's error handler
- * is called, this ISR exits because it is expected that the user will
- * reset the device in nearly all instances.
- */
- if ((u32)vector == instance_p->config.queue_irq_num[tx_queue_id])
- {
- if (tx_queue_id == 0)
- {
- reg_isr = FXMAC_READREG32(instance_p->config.base_address, FXMAC_ISR_OFFSET);
- if ((reg_isr & FXMAC_IXR_TXCOMPL_MASK) != 0x00000000U)
- {
- /* Clear TX status register TX complete indication but preserve
- * error bits if there is any */
- FXMAC_WRITEREG32(instance_p->config.base_address,
- FXMAC_TXSR_OFFSET,
- ((u32)FXMAC_TXSR_TXCOMPL_MASK |
- (u32)FXMAC_TXSR_USEDREAD_MASK));
- if (instance_p->send_irq_handler)
- {
- /* code */
- instance_p->send_irq_handler(instance_p->send_args);
- }
- /* add */
- FXMAC_WRITEREG32(instance_p->config.base_address, FXMAC_ISR_OFFSET, FXMAC_IXR_TXCOMPL_MASK);
- }
- /* Transmit error conditions interrupt */
- if (((reg_isr & FXMAC_IXR_TX_ERR_MASK) != 0x00000000U) &&
- (!(reg_isr & FXMAC_IXR_TXCOMPL_MASK) != 0x00000000U))
- {
- /* Clear TX status register */
- reg_temp = FXMAC_READREG32(instance_p->config.base_address, FXMAC_TXSR_OFFSET);
- FXMAC_WRITEREG32(instance_p->config.base_address, FXMAC_TXSR_OFFSET, reg_temp);
- if (instance_p->error_irq_handler)
- {
- instance_p->error_irq_handler(instance_p->error_args, FXMAC_SEND, reg_temp);
- }
- /* add */
- FXMAC_WRITEREG32(instance_p->config.base_address, FXMAC_ISR_OFFSET, FXMAC_IXR_TX_ERR_MASK);
- }
- /* add restart */
- if ((reg_isr & FXMAC_IXR_TXUSED_MASK) != 0x00000000U)
- {
- /* add */
- FXMAC_WRITEREG32(instance_p->config.base_address, FXMAC_ISR_OFFSET, FXMAC_IXR_TXUSED_MASK);
- if (instance_p->restart_handler)
- {
- instance_p->restart_handler(instance_p->restart_args);
- }
- }
- /* link chaged */
- if ((reg_isr & FXMAC_IXR_LINKCHANGE_MASK) != 0x00000000U)
- {
- if (instance_p->link_change_handler)
- {
- instance_p->link_change_handler(instance_p->link_change_args);
- }
- FXMAC_WRITEREG32(instance_p->config.base_address, FXMAC_ISR_OFFSET, FXMAC_IXR_LINKCHANGE_MASK);
- }
- }
- else /* use queue number more than 0 */
- {
- reg_isr = FXMAC_READREG32(instance_p->config.base_address,
- FXMAC_QUEUE_REGISTER_OFFSET(FXMAC_INTQ1_STS_OFFSET, tx_queue_id));
- /* Transmit Q1 complete interrupt */
- if (((reg_isr & FXMAC_INTQUESR_TXCOMPL_MASK) != 0x00000000U))
- {
- /* Clear TX status register TX complete indication but preserve
- * error bits if there is any */
- FXMAC_WRITEREG32(instance_p->config.base_address,
- FXMAC_QUEUE_REGISTER_OFFSET(FXMAC_INTQ1_STS_OFFSET, tx_queue_id),
- FXMAC_INTQUESR_TXCOMPL_MASK);
- FXMAC_WRITEREG32(instance_p->config.base_address,
- FXMAC_TXSR_OFFSET,
- ((u32)FXMAC_TXSR_TXCOMPL_MASK |
- (u32)FXMAC_TXSR_USEDREAD_MASK));
- instance_p->send_irq_handler(instance_p->send_args);
- }
- /* Transmit Q1 error conditions interrupt */
- if (((reg_isr & FXMAC_INTQ1SR_TXERR_MASK) != 0x00000000U) &&
- ((reg_isr & FXMAC_INTQ1SR_TXCOMPL_MASK) != 0x00000000U))
- {
- /* Clear Interrupt Q1 status register */
- FXMAC_WRITEREG32(instance_p->config.base_address,
- FXMAC_QUEUE_REGISTER_OFFSET(FXMAC_INTQ1_STS_OFFSET, tx_queue_id), reg_isr);
- instance_p->error_irq_handler(instance_p->error_args, FXMAC_SEND,
- reg_isr);
- }
- }
- }
- if ((u32)vector == instance_p->config.queue_irq_num[rx_queue_id])
- {
- if (rx_queue_id == 0)
- {
- reg_isr = FXMAC_READREG32(instance_p->config.base_address,
- FXMAC_ISR_OFFSET);
- /* Receive complete interrupt */
- if ((reg_isr & FXMAC_IXR_RXCOMPL_MASK) != 0x00000000U)
- {
- /* Clear RX status register RX complete indication but preserve
- * error bits if there is any */
- FXMAC_WRITEREG32(instance_p->config.base_address,
- FXMAC_RXSR_OFFSET,
- ((u32)FXMAC_RXSR_FRAMERX_MASK |
- (u32)FXMAC_RXSR_BUFFNA_MASK));
- instance_p->recv_irq_handler(instance_p->recv_args);
- /* add */
- FXMAC_WRITEREG32(instance_p->config.base_address, FXMAC_ISR_OFFSET, FXMAC_IXR_RXCOMPL_MASK);
- }
- /* Receive error conditions interrupt */
- if ((reg_isr & FXMAC_IXR_RX_ERR_MASK) != 0x00000000U)
- {
- /* Clear RX status register */
- reg_temp = FXMAC_READREG32(instance_p->config.base_address,
- FXMAC_RXSR_OFFSET);
- FXMAC_WRITEREG32(instance_p->config.base_address,
- FXMAC_RXSR_OFFSET, reg_temp);
- /* Fix for CR # 692702. Write to bit 18 of net_ctrl
- * register to flush a packet out of Rx SRAM upon
- * an error for receive buffer not available. */
- if ((reg_isr & FXMAC_IXR_RXUSED_MASK) != 0x00000000U)
- {
- reg_ctrl = FXMAC_READREG32(instance_p->config.base_address,
- FXMAC_NWCTRL_OFFSET);
- reg_ctrl |= (u32)FXMAC_NWCTRL_FLUSH_DPRAM_MASK;
- /* add */
- reg_ctrl &= (u32)(~FXMAC_NWCTRL_RXEN_MASK);
- FXMAC_WRITEREG32(instance_p->config.base_address,
- FXMAC_NWCTRL_OFFSET, reg_ctrl);
- /* add */
- reg_ctrl |= (u32)FXMAC_NWCTRL_RXEN_MASK;
- FXMAC_WRITEREG32(instance_p->config.base_address,
- FXMAC_NWCTRL_OFFSET, reg_ctrl);
- }
- /* add */
- if ((reg_isr & FXMAC_IXR_RXOVR_MASK) != 0x00000000U)
- {
- FXMAC_WRITEREG32(instance_p->config.base_address, FXMAC_ISR_OFFSET, FXMAC_IXR_RXOVR_MASK);
- }
- /* add */
- if ((reg_isr & FXMAC_IXR_HRESPNOK_MASK) != 0x00000000U)
- {
- FXMAC_WRITEREG32(instance_p->config.base_address, FXMAC_ISR_OFFSET, FXMAC_IXR_HRESPNOK_MASK);
- }
- if (reg_temp != 0)
- {
- instance_p->error_irq_handler(instance_p->error_args,
- FXMAC_RECV, reg_temp);
- }
- }
- }
- else /* use queue number more than 0 */
- {
- reg_isr = FXMAC_READREG32(instance_p->config.base_address,
- FXMAC_QUEUE_REGISTER_OFFSET(FXMAC_INTQ1_STS_OFFSET, rx_queue_id));
- /* Receive complete interrupt */
- if ((reg_isr & FXMAC_INTQUESR_RCOMP_MASK) != 0x00000000U)
- {
- /* Clear RX status register RX complete indication but preserve
- * error bits if there is any */
- FXMAC_WRITEREG32(instance_p->config.base_address,
- FXMAC_QUEUE_REGISTER_OFFSET(FXMAC_INTQ1_STS_OFFSET, rx_queue_id),
- FXMAC_INTQUESR_RCOMP_MASK);
- instance_p->recv_irq_handler(instance_p->recv_args);
- }
- /* Receive error conditions interrupt */
- if ((reg_isr & FXMAC_IXR_RX_ERR_MASK) != 0x00000000U)
- {
- reg_ctrl =
- FXMAC_READREG32(instance_p->config.base_address,
- FXMAC_NWCTRL_OFFSET);
- reg_ctrl &= ~(u32)FXMAC_NWCTRL_RXEN_MASK;
- FXMAC_WRITEREG32(instance_p->config.base_address,
- FXMAC_NWCTRL_OFFSET, reg_ctrl);
- /* Clear RX status register */
- reg_temp = FXMAC_READREG32(instance_p->config.base_address,
- FXMAC_RXSR_OFFSET);
- FXMAC_WRITEREG32(instance_p->config.base_address,
- FXMAC_RXSR_OFFSET, reg_temp);
- /* Fix for CR # 692702. Write to bit 18 of net_ctrl
- * register to flush a packet out of Rx SRAM upon
- * an error for receive buffer not available. */
- if ((reg_isr & FXMAC_IXR_RXUSED_MASK) != 0x00000000U)
- {
- reg_ctrl =
- FXMAC_READREG32(instance_p->config.base_address,
- FXMAC_NWCTRL_OFFSET);
- reg_ctrl |= (u32)FXMAC_NWCTRL_FLUSH_DPRAM_MASK;
- FXMAC_WRITEREG32(instance_p->config.base_address,
- FXMAC_NWCTRL_OFFSET, reg_ctrl);
- }
- /* Clear RX status register RX complete indication but preserve
- * error bits if there is any */
- FXMAC_WRITEREG32(instance_p->config.base_address,
- FXMAC_QUEUE_REGISTER_OFFSET(FXMAC_INTQ1_STS_OFFSET, rx_queue_id),
- FXMAC_INTQUESR_RXUBR_MASK);
- instance_p->recv_irq_handler(instance_p->recv_args);
- if (reg_temp != 0)
- {
- instance_p->error_irq_handler(instance_p->error_args,
- FXMAC_RECV, reg_temp);
- }
- }
- }
- }
- }
- /**
- * @name: FXmacQueueIrqDisable
- * @msg: Disable queue irq
- * @param {FXmac} *instance_p a pointer to the instance to be worked on.
- * @param {u32} queue_num queue number
- * @param {u32} mask is interrupt disable value mask
- */
- void FXmacQueueIrqDisable(FXmac *instance_p, u32 queue_num, u32 mask)
- {
- FXmacConfig *config_p;
- FASSERT(instance_p != NULL);
- FASSERT(instance_p->is_ready == (u32)FT_COMPONENT_IS_READY);
- FASSERT(instance_p->config.max_queue_num > queue_num);
- config_p = &instance_p->config;
- if (queue_num == 0)
- {
- FXMAC_WRITEREG32(config_p->base_address, FXMAC_IDR_OFFSET, mask & FXMAC_IXR_ALL_MASK);
- }
- else
- {
- FXMAC_WRITEREG32(config_p->base_address, FXMAC_INTQX_IDR_SIZE_OFFSET(queue_num), mask & FXMAC_IXR_ALL_MASK);
- }
- }
- /**
- * @name: FXmacQueueIrqEnable
- * @msg: Enable queue irq
- * @param {FXmac} *instance_p a pointer to the instance to be worked on.
- * @param {u32} queue_num is queue number
- * @param {u32} mask is interrupt Enable value mask
- */
- void FXmacQueueIrqEnable(FXmac *instance_p, u32 queue_num, u32 mask)
- {
- FXmacConfig *config_p;
- FASSERT(instance_p != NULL);
- FASSERT(instance_p->is_ready == (u32)FT_COMPONENT_IS_READY);
- FASSERT(instance_p->config.max_queue_num > queue_num);
- config_p = &instance_p->config;
- if (queue_num == 0)
- {
- FXMAC_WRITEREG32(config_p->base_address, FXMAC_IER_OFFSET, mask & FXMAC_IXR_ALL_MASK);
- }
- else
- {
- FXMAC_WRITEREG32(config_p->base_address, FXMAC_INTQX_IER_SIZE_OFFSET(queue_num), mask & FXMAC_IXR_ALL_MASK);
- }
- }
|