embeddedsw/XilinxProcessorIPLib/drivers/axiethernet/examples/xaxiethernet_example_extvlan.c

1452 lines
42 KiB
C
Raw Normal View History

/******************************************************************************
*
* Copyright (C) 2010 - 2014 Xilinx, Inc. All rights reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* Use of the Software is limited solely to applications:
* (a) running on a Xilinx device, or
* (b) that interact with a Xilinx device through a bus or interconnect.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* XILINX CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
* OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*
* Except as contained in this notice, the name of the Xilinx shall not be used
* in advertising or otherwise to promote the sale, use or other dealings in
* this Software without prior written authorization from Xilinx.
*
******************************************************************************/
/**
*
* @file xaxiethernet_example_extvlan.c
*
* Implements examples that utilize the Axi Ethernet's interrupt driven SGDMA
* packet transfer mode to send and receive frames.
*
* This example demonstrates:
*
* - How to setup VLAN strip/translate/tag in TX and RX direction
* - How the VLAN tags are handled
* - What is the expected VLAN tag(s) after VLAN functions are invoked
*
* Functional guide to example:
*
* - AxiEthernetSgDmaIntrExtVlanExample demonstrates the extended VLAN
* capability. The HW must be setup for extended VLAN for this example
* to execute.
*
* <pre>
* MODIFICATION HISTORY:
*
* Ver Who Date Changes
* ----- ---- -------- -------------------------------------------------------
* 1.00a asa 4/30/10 First release based on the ll temac driver
* 1.01a asa 12/10/10 Changes made to enable the AXIDMA Tx/Rx ring interrupts
* before allocation of Tx/Rx BDs.
* 3.00a asa 6/25/12 Modifed XAxiDma_BdSetLength API call to support new
* AXI DMA driver version 7.00a.
* 3.00a bss 10/22/12 Added support for Fast Interrupt Handlers.
* 3.01a srt 02/14/13 Added support for Zynq (CR 681136)
*
* </pre>
*
******************************************************************************/
/***************************** Include Files *********************************/
#include "xaxiethernet_example.h"
#include "xaxidma.h"
#include "xil_cache.h"
#include "xil_exception.h"
#ifdef XPAR_INTC_0_DEVICE_ID
#include "xintc.h"
#else
#include "xscugic.h"
#endif
#ifdef XPAR_XUARTNS550_NUM_INSTANCES
#include "xuartns550_l.h"
#endif
/*************************** Constant Definitions ****************************/
/*
* The following constants map to the XPAR parameters created in the
* xparameters.h file. They are defined here such that a user can easily
* change all the needed parameters in one place.
*/
#ifndef TESTAPP_GEN
#define AXIETHERNET_DEVICE_ID XPAR_AXIETHERNET_0_DEVICE_ID
#define AXIDMA_DEVICE_ID XPAR_AXIDMA_0_DEVICE_ID
#ifdef XPAR_INTC_0_DEVICE_ID
#define INTC_DEVICE_ID XPAR_INTC_0_DEVICE_ID
#define AXIETHERNET_IRPT_INTR XPAR_INTC_0_AXIETHERNET_0_VEC_ID
#define DMA_RX_IRPT_INTR XPAR_AXIETHERNET_0_CONNECTED_DMARX_INTR
#define DMA_TX_IRPT_INTR XPAR_AXIETHERNET_0_CONNECTED_DMATX_INTR
#else
#define INTC_DEVICE_ID XPAR_SCUGIC_SINGLE_DEVICE_ID
#define AXIETHERNET_IRPT_INTR XPAR_FABRIC_AXIETHERNET_0_VEC_ID
#define DMA_RX_IRPT_INTR XPAR_FABRIC_AXIDMA_0_S2MM_INTROUT_VEC_ID
#define DMA_TX_IRPT_INTR XPAR_FABRIC_AXIDMA_0_MM2S_INTROUT_VEC_ID
#endif
#endif
#define RXBD_CNT 128 /* Number of RxBDs to use */
#define TXBD_CNT 128 /* Number of TxBDs to use */
#define BD_ALIGNMENT XAXIDMA_BD_MINIMUM_ALIGNMENT/*
* Byte alignment
* of BDs
*/
#define PAYLOAD_SIZE 1000 /* Payload size used in examples */
#define BD_VLAN_TPID_OFFSET 3 /* AXI4-Stream status Word offset from
* the start of app user words in BD.
* TPID is at status word 3, bits
* 31-16
*/
#define BD_VLAN_VID_OFFSET 4 /* AXI4-Stream status word offset from
* the start of app user words in BD.
* VID is at status word 4, bits
* 31-16
*/
#define TPID_MASK 0xFFFF0000 /* Mask to extract TPID from
* the AXI4 STream status
* word
*/
/*
* Number of bytes to reserve for BD space for the number of BDs desired
*/
#define RXBD_SPACE_BYTES XAxiDma_BdRingMemCalc(BD_ALIGNMENT, RXBD_CNT)
#define TXBD_SPACE_BYTES XAxiDma_BdRingMemCalc(BD_ALIGNMENT, TXBD_CNT)
/*************************** Variable Definitions ****************************/
static EthernetFrame TxFrame; /* Transmit buffer */
static EthernetFrame RxFrame; /* Receive buffer */
XAxiEthernet AxiEthernetInstance;
XAxiDma DmaInstance;
#if XPAR_INTC_0_HAS_FAST == 1
/* Variables for Fast Interrupt Handlers */
XAxiEthernet *AxiEthernetInstancePtr_Fast;
XAxiDma_BdRing *TxRingPtr_Fast;
XAxiDma_BdRing *RxRingPtr_Fast;
/****** Fast Interrupt Handlers prototypes ******/
static void AxiEthernetErrorFastHandler(void) __attribute__ ((fast_interrupt));
static void RxIntrFastHandler(void) __attribute__ ((fast_interrupt));
static void TxIntrFastHandler(void) __attribute__ ((fast_interrupt));
#else
static void AxiEthernetErrorHandler(XAxiEthernet *AxiEthernet);
static void RxIntrHandler(XAxiDma_BdRing *RxRingPtr);
static void TxIntrHandler(XAxiDma_BdRing *TxRingPtr);
#endif
/*
* Aligned memory segments to be used for buffer descriptors
*/
char RxBdSpace[RXBD_SPACE_BYTES] __attribute__ ((aligned(BD_ALIGNMENT)));
char TxBdSpace[TXBD_SPACE_BYTES] __attribute__ ((aligned(BD_ALIGNMENT)));
/*
* Counters to be incremented by callbacks
*/
static volatile int FramesRx; /* Num of frames that have been received */
static volatile int FramesTx; /* Num of frames that have been sent */
static volatile int DeviceErrors; /* Num of errors detected in the device */
#ifdef XPAR_INTC_0_DEVICE_ID
#define INTC XIntc
#define INTC_HANDLER XIntc_InterruptHandler
#else
#define INTC XScuGic
#define INTC_HANDLER XScuGic_InterruptHandler
#endif
#ifndef TESTAPP_GEN
static INTC IntcInstance;
#endif
/*************************** Function Prototypes *****************************/
/*
* Examples
*/
int AxiEthernetExtVlanExample(INTC *IntcInstancePtr,
XAxiEthernet *AxiEthernetInstancePtr,
XAxiDma *DmaInstancePtr,
u16 AxiEthernetDeviceId,
u16 AxiDmaDeviceId,
u16 AxiEthernetIntrId,
u16 DmaRxIntrId,
u16 DmaTxIntrId);
int AxiEthernetSgDmaIntrExtVlanExample(XAxiEthernet *AxiEthernetInstancePtr,
XAxiDma *DmaInstancePtr);
/*
* Interrupt setup and Callbacks for examples
*/
static int AxiEthernetSetupIntrSystem(INTC *IntcInstancePtr,
XAxiEthernet *AxiEthernetInstancePtr,
XAxiDma *DmaInstancePtr,
u16 AxiEthernetIntrId,
u16 DmaRxIntrId, u16 DmaTxIntrId);
static void AxiEthernetDisableIntrSystem(INTC *IntcInstancePtr,
u16 AxiEthernetIntrId,
u16 DmaRxIntrId, u16 DmaTxIntrId);
/*****************************************************************************/
/**
*
* This is the main function for the Axi Ethernet example. This function is not
* included if the example is generated from the TestAppGen test tool.
*
* @param None.
*
* @return - XST_SUCCESS to indicate success.
* - XST_FAILURE to indicate failure
*
* @note None.
*
****************************************************************************/
#ifndef TESTAPP_GEN
int main(void)
{
int Status;
#ifdef XPAR_XUARTNS550_NUM_INSTANCES
XUartNs550_SetBaud(STDIN_BASEADDRESS, XPAR_XUARTNS550_CLOCK_HZ, 9600);
XUartNs550_SetLineControlReg(STDIN_BASEADDRESS, XUN_LCR_8_DATA_BITS);
#endif
#if XPAR_MICROBLAZE_USE_ICACHE
Xil_ICacheInvalidate();
Xil_ICacheEnable();
#endif
#if XPAR_MICROBLAZE_USE_DCACHE
Xil_DCacheInvalidate();
Xil_DCacheEnable();
#endif
AxiEthernetUtilErrorTrap("\r\n--- Enter main() ---");
AxiEthernetUtilErrorTrap("This test may take several minutes to finish");
/*
* Call the Axi Ethernet vlan example main function
*/
Status = AxiEthernetExtVlanExample(&IntcInstance,
&AxiEthernetInstance,
&DmaInstance,
AXIETHERNET_DEVICE_ID,
AXIDMA_DEVICE_ID,
AXIETHERNET_IRPT_INTR,
DMA_RX_IRPT_INTR,
DMA_TX_IRPT_INTR);
if (Status != XST_SUCCESS) {
AxiEthernetUtilErrorTrap("Failed test intr sgdma");
AxiEthernetUtilErrorTrap("--- Exiting main() ---");
return XST_FAILURE;
}
AxiEthernetUtilErrorTrap("Test passed");
AxiEthernetUtilErrorTrap("--- Exiting main() ---");
return XST_SUCCESS;
}
#endif
/*****************************************************************************/
/**
*
* This function demonstrates the usage usage of the Axi Ethernet by sending
* and receiving frames in interrupt driven SGDMA mode.
*
*
* @param IntcInstancePtr is a pointer to the instance of the Intc
* component.
* @param AxiEthernetInstancePtr is a pointer to the instance of the
* AxiEthernet component.
* @param DmaInstancePtr is a pointer to the instance of the AXIDMA
* component.
* @param AxiEthernetDeviceId is Device ID of the Axi Ethernet Device ,
* typically XPAR_<AXIETHERNET_instance>_DEVICE_ID value from
* xparameters.h.
* @param AxiDmaDeviceId is Device ID of the Axi DMAA Device ,
* typically XPAR_<AXIDMA_instance>_DEVICE_ID value from
* xparameters.h.
* @param AxiEthernetIntrId is the Interrupt ID and is typically
* XPAR_<INTC_instance>_<AXIETHERNET_instance>_VEC_ID
* value from xparameters.h.
* @param DmaRxIntrId is the interrupt id for DMA Rx and is typically
* taken from XPAR_<AXIETHERNET_instance>_CONNECTED_DMARX_INTR
* @param DmaTxIntrId is the interrupt id for DMA Tx and is typically
* taken from XPAR_<AXIETHERNET_instance>_CONNECTED_DMATX_INTR
*
* @return -XST_SUCCESS to indicate success.
* -XST_FAILURE to indicate failure.
*
* @note AxiDma hardware must be initialized before initializing
* AxiEthernet. Since AxiDma reset line is connected to the
* AxiEthernet reset line, a reset of AxiDma hardware during its
* initialization would reset AxiEthernet.
*
******************************************************************************/
int AxiEthernetExtVlanExample(INTC *IntcInstancePtr,
XAxiEthernet *AxiEthernetInstancePtr,
XAxiDma *DmaInstancePtr,
u16 AxiEthernetDeviceId,
u16 AxiDmaDeviceId,
u16 AxiEthernetIntrId,
u16 DmaRxIntrId,
u16 DmaTxIntrId)
{
int Status;
int LoopbackSpeed;
XAxiEthernet_Config *MacCfgPtr;
XAxiDma_BdRing *RxRingPtr = XAxiDma_GetRxRing(DmaInstancePtr);
XAxiDma_BdRing *TxRingPtr = XAxiDma_GetTxRing(DmaInstancePtr);
XAxiDma_Bd BdTemplate;
XAxiDma_Config* DmaConfig;
/*************************************/
/* Setup device for first-time usage */
/*************************************/
/*
* Get the configuration of AxiEthernet hardware.
*/
MacCfgPtr = XAxiEthernet_LookupConfig(AxiEthernetDeviceId);
/*
* Check if DMA is present or not.
*/
if(MacCfgPtr->AxiDevType != XPAR_AXI_DMA) {
AxiEthernetUtilErrorTrap
("Device HW not configured for SGDMA mode\r\n");
return XST_FAILURE;
}
DmaConfig = XAxiDma_LookupConfig(AxiDmaDeviceId);
/*
* Initialize AXIDMA engine. AXIDMA engine must be initialized before
* AxiEthernet. During AXIDMA engine initialization, AXIDMA hardware is
* reset, and since AXIDMA reset line is connected to AxiEthernet, this
* would ensure a reset of AxiEthernet.
*/
Status = XAxiDma_CfgInitialize(DmaInstancePtr, DmaConfig);
if(Status != XST_SUCCESS) {
AxiEthernetUtilErrorTrap("Error initializing DMA\r\n");
return XST_FAILURE;
}
/*
* Initialize AxiEthernet hardware.
*/
Status = XAxiEthernet_CfgInitialize(AxiEthernetInstancePtr, MacCfgPtr,
MacCfgPtr->BaseAddress);
if (Status != XST_SUCCESS) {
AxiEthernetUtilErrorTrap("Error in initialize");
return XST_FAILURE;
}
/*
* Set the MAC address
*/
Status = XAxiEthernet_SetMacAddress(AxiEthernetInstancePtr,
AxiEthernetMAC);
if (Status != XST_SUCCESS) {
AxiEthernetUtilErrorTrap("Error setting MAC address");
return XST_FAILURE;
}
/*
* Setup RxBD space.
*
* We have already defined a properly aligned area of memory to store
* RxBDs at the beginning of this source code file so just pass its
* address into the function. No MMU is being used so the physical and
* virtual addresses are the same.
*
* Setup a BD template for the Rx channel. This template will be copied
* to every RxBD. We will not have to explicitly set these again.
*/
/*
* Create the RxBD ring
*/
Status = XAxiDma_BdRingCreate(RxRingPtr, (u32) &RxBdSpace,
(u32) &RxBdSpace, BD_ALIGNMENT, RXBD_CNT);
if (Status != XST_SUCCESS) {
AxiEthernetUtilErrorTrap("Error setting up RxBD space");
return XST_FAILURE;
}
XAxiDma_BdClear(&BdTemplate);
Status = XAxiDma_BdRingClone(RxRingPtr, &BdTemplate);
if (Status != XST_SUCCESS) {
AxiEthernetUtilErrorTrap("Error initializing RxBD space");
return XST_FAILURE;
}
/*
* Setup TxBD space.
*
* Like RxBD space, we have already defined a properly aligned area of
* memory to use.
*/
/*
* Create the TxBD ring
*/
Status = XAxiDma_BdRingCreate(TxRingPtr, (u32) &TxBdSpace,
(u32) &TxBdSpace, BD_ALIGNMENT, TXBD_CNT);
if (Status != XST_SUCCESS) {
AxiEthernetUtilErrorTrap("Error setting up TxBD space");
return XST_FAILURE;
}
/*
* We reuse the bd template, as the same one will work for both rx and
* tx.
*/
Status = XAxiDma_BdRingClone(TxRingPtr, &BdTemplate);
if (Status != XST_SUCCESS) {
AxiEthernetUtilErrorTrap("Error initializing TxBD space");
return XST_FAILURE;
}
/*
* Set PHY to loopback, speed depends on phy type.
* MII is 100 and all others are 1000.
*/
if (XAxiEthernet_GetPhysicalInterface(AxiEthernetInstancePtr)
== XAE_PHY_TYPE_MII){
LoopbackSpeed = AXIETHERNET_LOOPBACK_SPEED;
} else {
LoopbackSpeed = AXIETHERNET_LOOPBACK_SPEED_1G;
}
AxiEthernetUtilEnterLoopback(AxiEthernetInstancePtr, LoopbackSpeed);
/*
* Set PHY<-->MAC data clock
*/
Status = XAxiEthernet_SetOperatingSpeed(AxiEthernetInstancePtr,
(u16)LoopbackSpeed);
if (Status != XST_SUCCESS) {
return XST_FAILURE;
}
/*
* Setting the operating speed of the MAC needs a delay. There
* doesn't seem to be register to poll, so please consider this
* during your application design.
*/
AxiEthernetUtilPhyDelay(2);
/*
* Connect to the interrupt controller and enable interrupts
*/
Status = AxiEthernetSetupIntrSystem(IntcInstancePtr,
AxiEthernetInstancePtr,
DmaInstancePtr,
AxiEthernetIntrId, DmaRxIntrId,
DmaTxIntrId);
/****************************/
/* Run the example */
/****************************/
/* Run the new VLAN feature. Make sure HW has the capability */
if (XAxiEthernet_IsTxVlanTran(AxiEthernetInstancePtr) &&
XAxiEthernet_IsTxVlanStrp(AxiEthernetInstancePtr) &&
XAxiEthernet_IsTxVlanTag(AxiEthernetInstancePtr) &&
XAxiEthernet_IsRxVlanTran(AxiEthernetInstancePtr) &&
XAxiEthernet_IsRxVlanStrp(AxiEthernetInstancePtr) &&
XAxiEthernet_IsRxVlanTag(AxiEthernetInstancePtr)) {
Status = AxiEthernetSgDmaIntrExtVlanExample
(AxiEthernetInstancePtr,DmaInstancePtr);
if (Status != XST_SUCCESS) {
return XST_FAILURE;
}
}
/*
* Disable the interrupts for the AxiEthernet device
*/
AxiEthernetDisableIntrSystem(IntcInstancePtr, AxiEthernetIntrId,
DmaRxIntrId, DmaTxIntrId);
/*
* Stop the device
*/
XAxiEthernet_Stop(AxiEthernetInstancePtr);
return XST_SUCCESS;
}
/*****************************************************************************/
/**
*
* This example sends and receives a single packet in loopback mode with
* extended VLAN support.
*
* The transmit frame will have VLAN field populated.
*
* On receive, HW should pass the VLAN field to receive BDs.
*
* @param AxiEthernetInstancePtr is a pointer to the instance of the
* AxiEthernet component.
* @param DmaInstancePtr is a pointer to the instance of the Dma
* component.
*
* @return -XST_SUCCESS to indicate success.
* -XST_FAILURE to indicate failure.
*
* @note Summary of VLAN tags handling in this example
*
* Frame setup with Tpid1+Cfi1+TxPid => 0x88A83111
* Frame translated to TxTransVid => 0x88A83222
* Frame tagged to Tpid2+Cfi2+TxTagVid => 0x9100C333 + 0x88A83222
* Frame sent and loopbacked.
*
* Frame stripped with RxStrpVid(0x333) => 0x88A83222
* Frame translated (key:RxVid:0x222) RxTransVid => 0x88A83444
*
******************************************************************************/
int AxiEthernetSgDmaIntrExtVlanExample(XAxiEthernet *AxiEthernetInstancePtr,
XAxiDma *DmaInstancePtr)
{
int Status;
u32 TxFrameLength;
u32 RxFrameLength;
int PayloadSize = PAYLOAD_SIZE;
u16 Tpid1 = 0x88A8;
u16 Tpid2 = 0x9100;
u8 Cfi1 = 0x03;
u8 Cfi2 = 0x0C;
u16 TxVid = 0x0111;
u16 TxTransVid = 0x0222;
u16 TxTagVid = 0x0333;
u16 RxVid = 0x0222;
u16 RxTransVid = 0x0444;
u16 RxStrpVid = 0x0333;
u32 VTagCfiVid;
u16 RxCfiVid;
u16 RxTpid;
u32 RxStatusControlWord;
int Valid;
XAxiDma_BdRing *RxRingPtr = XAxiDma_GetRxRing(DmaInstancePtr);
XAxiDma_BdRing *TxRingPtr = XAxiDma_GetTxRing(DmaInstancePtr);
XAxiDma_Bd *BdPtr;
XAxiDma_Bd *BdCurPtr;
u32 BdSts;
/*
* Cannot run this example if extended features support is not enabled
*/
if (!(XAxiEthernet_IsTxVlanTran(AxiEthernetInstancePtr) &&
XAxiEthernet_IsTxVlanStrp(AxiEthernetInstancePtr) &&
XAxiEthernet_IsTxVlanTag(AxiEthernetInstancePtr) &&
XAxiEthernet_IsRxVlanTran(AxiEthernetInstancePtr) &&
XAxiEthernet_IsRxVlanStrp(AxiEthernetInstancePtr) &&
XAxiEthernet_IsRxVlanTag(AxiEthernetInstancePtr))) {
AxiEthernetUtilErrorTrap("Extended VLAN not available");
return XST_FAILURE;
}
/*
* Clear variables shared with callbacks
*/
FramesRx = 0;
FramesTx = 0;
DeviceErrors = 0;
memset(RxFrame,0,sizeof(RxFrame));
memset(TxFrame,0,sizeof(TxFrame));
/*
* Calculate frame length (not including FCS) plus one VLAN tag
*/
TxFrameLength = XAE_HDR_VLAN_SIZE + PayloadSize;
/*
* Setup the packet with one VALN tag = VtagCfiVid to be transmitted
* initially.
*/
VTagCfiVid = (((u32)Tpid1 << 16) | ((u32)Cfi1 << 12) | TxVid);
AxiEthernetUtilFrameMemClear(&TxFrame);
AxiEthernetUtilFrameHdrFormatMAC(&TxFrame, AxiEthernetMAC);
AxiEthernetUtilFrameHdrVlanFormatVid(&TxFrame, 0, VTagCfiVid);
AxiEthernetUtilFrameHdrVlanFormatType(&TxFrame, PayloadSize, 1);
AxiEthernetUtilFrameSetVlanPayloadData(&TxFrame, PayloadSize, 1);
/* Intended VLAN setup:
* TX translation and tagging. RX stripping and translation.
*
* Frame setup with Tpid1+Cfi1+TxPid => 0x88A83111
* Frame translated to TxTransVid => 0x88A83222
* Frame tagged to Tpid2+Cfi2+TxTagVid => 0x9100C333 + 0x88A83222
* Frame sent and loopbacked.
*
* Frame stripped with RxStrpVid(0x333) => 0x88A83222
* Frame translated (key:RxVid:0x222) RxTransVid => 0x88A83444
*/
/* Extended VLAN transmit side. Stripping->Translation->Tagging */
/*
* Configure VLAN TX tag mode, set to XAE_VTAG_SELECT.
*/
Status = XAxiEthernet_SetOptions(AxiEthernetInstancePtr,
XAE_EXT_TXVLAN_TAG_OPTION);
Status |= XAxiEthernet_SetVTagMode(AxiEthernetInstancePtr,
XAE_VTAG_SELECT, XAE_TX);
/*
* TX VLAN translation from TxVid to TxTransVid and enable tagging.
*/
Status |= XAxiEthernet_SetOptions(AxiEthernetInstancePtr,
XAE_EXT_TXVLAN_TRAN_OPTION);
Status |= XAxiEthernet_SetVidTable(AxiEthernetInstancePtr, TxVid,
TxTransVid,0, 1, XAE_TX);
/*
* TX VLAN tagging is keyed on TxVid to add one additional tag based
* on register XAE_TTAG_OFFSET value.
*/
VTagCfiVid = (((u32)Tpid2 << 16) | ((u32)Cfi2 << 12) | TxTagVid);
Status |= XAxiEthernet_SetVTagValue(AxiEthernetInstancePtr,
VTagCfiVid, XAE_TX);
if (Status != XST_SUCCESS) {
AxiEthernetUtilErrorTrap("Error setting TX VLAN");
return XST_FAILURE;
}
/* Extended VLAN receive side. Stripping->Translation->Tagging */
/*
* Configure VLAN RX strip mode, set to XAE_VSTRP_SELECT.
*/
Status = XAxiEthernet_SetOptions(AxiEthernetInstancePtr,
XAE_EXT_RXVLAN_STRP_OPTION);
Status |= XAxiEthernet_SetVStripMode(AxiEthernetInstancePtr,
XAE_VSTRP_SELECT, XAE_RX);
/*
* RX VLAN strips based on RxStrpVid and enable stripping.
*/
Status |= XAxiEthernet_SetVidTable(AxiEthernetInstancePtr, RxStrpVid,
RxStrpVid, 1, 0, XAE_RX);
/*
* RX VLAN translation from RxVid to RxTransVid only.
*/
Status |= XAxiEthernet_SetOptions(AxiEthernetInstancePtr,
XAE_EXT_RXVLAN_TRAN_OPTION);
Status |= XAxiEthernet_SetVidTable(AxiEthernetInstancePtr, RxVid,
RxTransVid, 0, 0, XAE_RX);
if (Status != XST_SUCCESS) {
AxiEthernetUtilErrorTrap("Error setting RX VLAN");
return XST_FAILURE;
}
/* Configure VLAN TPIDs for HW to recognize. */
Status = XAxiEthernet_SetTpid(AxiEthernetInstancePtr, Tpid1, 0);
Status |= XAxiEthernet_SetTpid(AxiEthernetInstancePtr, Tpid2, 1);
if (Status != XST_SUCCESS) {
AxiEthernetUtilErrorTrap("Error setting TPIDs");
return XST_FAILURE;
}
/*
* Flush the TX frame before giving it to DMA TX channel to transmit.
*/
Xil_DCacheFlushRange((u32)&TxFrame, TxFrameLength);
/*
* Clear out receive packet memory area
*/
AxiEthernetUtilFrameMemClear(&RxFrame);
/*
* Invalidate the RX frame before giving it to DMA RX channel to
* receive data.
*/
Xil_DCacheInvalidateRange((u32)&RxFrame, TxFrameLength + 4);
/*
* Interrupt coalescing parameters are set to their default settings
* which is to interrupt the processor after every frame has been
* processed by the DMA engine.
*/
Status = XAxiDma_BdRingSetCoalesce(TxRingPtr, 1, 1);
if (Status != XST_SUCCESS) {
AxiEthernetUtilErrorTrap("Error setting coalescing for transmit");
return XST_FAILURE;
}
Status = XAxiDma_BdRingSetCoalesce(RxRingPtr, 1, 1);
if (Status != XST_SUCCESS) {
AxiEthernetUtilErrorTrap("Error setting coalescing for recv");
return XST_FAILURE;
}
/*
* Make sure Tx and Rx are enabled
*/
Status = XAxiEthernet_SetOptions(AxiEthernetInstancePtr,
XAE_RECEIVER_ENABLE_OPTION |
XAE_TRANSMITTER_ENABLE_OPTION );
if (Status != XST_SUCCESS) {
AxiEthernetUtilErrorTrap("Error setting options");
return XST_FAILURE;
}
Status = XAxiEthernet_SetOptions(AxiEthernetInstancePtr,
XAE_JUMBO_OPTION);
if (Status != XST_SUCCESS) {
AxiEthernetUtilErrorTrap("Error setting options");
return XST_FAILURE;
}
/*
* Start the AxiEthernet and enable its ERROR interrupts
*/
XAxiEthernet_Start(AxiEthernetInstancePtr);
XAxiEthernet_IntEnable(&AxiEthernetInstance,
XAE_INT_RECV_ERROR_MASK);
/*
* Enable DMA receive related interrupts
*/
XAxiDma_BdRingIntEnable(RxRingPtr, XAXIDMA_IRQ_ALL_MASK);
/*
* Allocate 1 RxBD.
*/
Status = XAxiDma_BdRingAlloc(RxRingPtr, 1, &BdPtr);
if (Status != XST_SUCCESS) {
AxiEthernetUtilErrorTrap("Error allocating RxBD");
return XST_FAILURE;
}
/*
* Setup the BD.
*/
XAxiDma_BdSetBufAddr(BdPtr, (u32)&RxFrame);
#ifndef XPAR_AXIDMA_0_ENABLE_MULTI_CHANNEL
XAxiDma_BdSetLength(BdPtr, sizeof(RxFrame));
#else
XAxiDma_BdSetLength(BdPtr, sizeof(RxFrame),
RxRingPtr->MaxTransferLen);
#endif
XAxiDma_BdSetCtrl(BdPtr, 0);
/*
* Enqueue to HW
*/
Status = XAxiDma_BdRingToHw(RxRingPtr, 1, BdPtr);
if (Status != XST_SUCCESS) {
AxiEthernetUtilErrorTrap("Error committing RxBD to HW");
return XST_FAILURE;
}
/*
* Start DMA RX channel. Now it's ready to receive data.
*/
Status = XAxiDma_BdRingStart(RxRingPtr);
if (Status != XST_SUCCESS) {
return XST_FAILURE;
}
/*
* Enable DMA transmit related interrupts
*/
XAxiDma_BdRingIntEnable(TxRingPtr, XAXIDMA_IRQ_ALL_MASK);
/*
* Allocate 1 TxBD
*/
Status = XAxiDma_BdRingAlloc(TxRingPtr, 1, &BdPtr);
if (Status != XST_SUCCESS) {
AxiEthernetUtilErrorTrap("Error allocating TxBD");
return XST_FAILURE;
}
/*
* Setup the TxBD
*/
XAxiDma_BdSetBufAddr(BdPtr, (u32)&TxFrame);
#ifndef XPAR_AXIDMA_0_ENABLE_MULTI_CHANNEL
XAxiDma_BdSetLength(BdPtr, TxFrameLength);
#else
XAxiDma_BdSetLength(BdPtr, TxFrameLength,
TxRingPtr->MaxTransferLen);
#endif
XAxiDma_BdSetCtrl(BdPtr, XAXIDMA_BD_CTRL_TXSOF_MASK |
XAXIDMA_BD_CTRL_TXEOF_MASK);
/*
* Enqueue to HW
*/
Status = XAxiDma_BdRingToHw(TxRingPtr, 1, BdPtr);
if (Status != XST_SUCCESS) {
AxiEthernetUtilErrorTrap("Error committing TxBD to HW");
return XST_FAILURE;
}
/*
* Start DMA TX channel. Transmission starts at once.
*/
Status = XAxiDma_BdRingStart(TxRingPtr);
if (Status != XST_SUCCESS) {
return XST_FAILURE;
}
/*
* Wait for transmission to complete
*/
while (!FramesTx);
/*
* Now that the frame has been sent, post process our TxBDs.
* Since we have only submitted 2 to HW, then there should be only 2
* ready for post processing.
*/
if (XAxiDma_BdRingFromHw(TxRingPtr, 1, &BdPtr) == 0) {
AxiEthernetUtilErrorTrap("TxBDs were not ready for post processing");
return XST_FAILURE;
}
/*
* Examine the TxBDs.
*
* There isn't much to do. The only thing to check would be DMA
* exception bits. But this would also be caught in the error handler.
* So we just return these BDs to the free list
*/
Status = XAxiDma_BdRingFree(TxRingPtr, 1, BdPtr);
if (Status != XST_SUCCESS) {
AxiEthernetUtilErrorTrap("Error freeing up TxBDs");
return XST_FAILURE;
}
/*
* Wait for Rx indication
*/
while (!FramesRx);
/*
* Now that the frame has been received, post process our RxBD.
* Since we have only submitted 1 to HW, then there should be only 1
* ready for post processing.
*/
if (XAxiDma_BdRingFromHw(RxRingPtr, 1, &BdPtr) == 0) {
AxiEthernetUtilErrorTrap("RxBD was not ready for post processing");
return XST_FAILURE;
}
BdCurPtr = BdPtr;
BdSts = XAxiDma_BdGetSts(BdCurPtr);
if ((BdSts & XAXIDMA_BD_STS_ALL_ERR_MASK) ||
(!(BdSts & XAXIDMA_BD_STS_COMPLETE_MASK))) {
AxiEthernetUtilErrorTrap("Rx Error");
return XST_FAILURE;
}
else {
RxFrameLength =
(XAxiDma_BdRead(BdCurPtr,XAXIDMA_BD_USR4_OFFSET)) & 0x0000FFFF;
}
/* Expected RX TPID+CFI+VID !!! */
VTagCfiVid = (((u32)Tpid2 << 16) | ((u32)Cfi2 << 12) | RxStrpVid);
/* Check on the VLAN CFI and VID */
RxStatusControlWord = XAxiDma_BdGetAppWord(BdPtr,
BD_VLAN_VID_OFFSET, &Valid);
if(Valid) {
RxCfiVid = RxStatusControlWord >> 16;
RxCfiVid = Xil_Ntohs(RxCfiVid);
if(RxCfiVid != (VTagCfiVid & 0x0000FFFF)) {
AxiEthernetUtilErrorTrap("VLAN CFI and VID mismatch\n");
return XST_FAILURE;
}
}
else {
AxiEthernetUtilErrorTrap("Status words not available from AXI DMA\n");
return XST_FAILURE;
}
RxStatusControlWord = XAxiDma_BdGetAppWord(BdPtr,
BD_VLAN_TPID_OFFSET, &Valid);
if(Valid) {
RxTpid = RxStatusControlWord >> 16;
RxTpid = Xil_Ntohs(RxTpid);
VTagCfiVid = ((VTagCfiVid & TPID_MASK) >> 16);
if(RxTpid != VTagCfiVid) {
AxiEthernetUtilErrorTrap("VLAN TPID mismatch\n");
return XST_FAILURE;
}
}
else {
AxiEthernetUtilErrorTrap("Status words not available from AXI DMA\n");
return XST_FAILURE;
}
if (AxiEthernetUtilFrameVerify(&TxFrame, &RxFrame) != 0) {
AxiEthernetUtilErrorTrap("Data mismatch");
return XST_FAILURE;
}
/*
* Return the RxBD back to the channel for later allocation. Free the
* exact number we just post processed.
*/
Status = XAxiDma_BdRingFree(RxRingPtr, 1, BdPtr);
if (Status != XST_SUCCESS) {
AxiEthernetUtilErrorTrap("Error freeing up TxBDs");
return XST_FAILURE;
}
return XST_SUCCESS;
}
/*****************************************************************************/
/**
*
* This is the DMA TX callback function to be called by TX interrupt handler.
* This function handles BDs finished by hardware.
*
* @param TxRingPtr is a pointer to TX channel of the DMA engine.
*
* @return None.
*
* @note None.
*
******************************************************************************/
static void TxCallBack(XAxiDma_BdRing * TxRingPtr)
{
/*
* Disable the transmit related interrupts
*/
XAxiDma_BdRingIntDisable(TxRingPtr, XAXIDMA_IRQ_ALL_MASK);
/*
* Increment the counter so that main thread knows something happened
*/
FramesTx++;
}
/*****************************************************************************/
/**
*
* This is the DMA TX Interrupt handler function.
*
* @param TxRingPtr is a pointer to TX channel of the DMA engine.
*
* @return None.
*
* @note This Interrupt handler MUST clear pending interrupts before
* handling them by calling the call back. Otherwise the following
* corner case could raise some issue:
*
* A packet got transmitted and a TX interrupt got asserted. If
* the interrupt handler calls the callback before clearing the
* interrupt, a new packet may get transmitted in the callback.
* This new packet then can assert one more TX interrupt before
* the control comes out of the callback function. Now when
* eventually control comes out of the callback function, it will
* never know about the second new interrupt and hence while
* clearing the interrupts, would clear the new interrupt as well
* and will never process it.
* To avoid such cases, interrupts must be cleared before calling
* the callback.
*
******************************************************************************/
static void TxIntrHandler(XAxiDma_BdRing * TxRingPtr)
{
u32 IrqStatus;
/* Read pending interrupts */
IrqStatus = XAxiDma_BdRingGetIrq(TxRingPtr);
/* Acknowledge pending interrupts */
XAxiDma_BdRingAckIrq(TxRingPtr, IrqStatus);
/*
* If no interrupt is asserted, raise error flag, reset the
* hardware to recover from the error, and return with no further
* processing.
*/
if (!(IrqStatus & XAXIDMA_IRQ_ALL_MASK)) {
DeviceErrors++;
AxiEthernetUtilErrorTrap
("AXIDma: No interrupts asserted in TX status register");
XAxiDma_Reset(&DmaInstance);
if(!XAxiDma_ResetIsDone(&DmaInstance)) {
AxiEthernetUtilErrorTrap ("AxiDMA: Error: Could not reset\n");
}
return;
}
/* If error interrupt is asserted, raise error flag, reset the
* hardware to recover from the error, and return with no further
* processing.
*/
if ((IrqStatus & XAXIDMA_IRQ_ERROR_MASK)) {
AxiEthernetUtilErrorTrap("AXIDMA: TX Error interrupts\n");
/* Reset should never fail for transmit channel
*/
XAxiDma_Reset(&DmaInstance);
if(!XAxiDma_ResetIsDone(&DmaInstance)) {
AxiEthernetUtilErrorTrap ("AXIDMA: Error: Could not reset\n");
}
return;
}
/*
* If Transmit done interrupt is asserted, call TX call back function
* to handle the processed BDs and raise the according flag
*/
if ((IrqStatus & (XAXIDMA_IRQ_DELAY_MASK | XAXIDMA_IRQ_IOC_MASK))) {
TxCallBack(TxRingPtr);
}
}
/*****************************************************************************/
/**
*
* This is the DMA RX callback function to be called by RX interrupt handler.
* This function handles finished BDs by hardware, attaches new buffers to those
* BDs, and give them back to hardware to receive more incoming packets
*
* @param RxRingPtr is a pointer to RX channel of the DMA engine.
*
* @return None.
*
* @note None.
*
******************************************************************************/
static void RxCallBack(XAxiDma_BdRing * RxRingPtr)
{
/*
* Disable the receive related interrupts
*/
XAxiDma_BdRingIntDisable(RxRingPtr, XAXIDMA_IRQ_ALL_MASK);
/*
* Increment the counter so that main thread knows something
* happened
*/
FramesRx++;
}
/*****************************************************************************/
/**
*
* This is the Receive handler function for examples 1 and 2.
* It will increment a shared counter, receive and validate the frame.
*
* @param RxRingPtr is a pointer to the DMA ring instance.
*
* @return None.
*
* @note None.
*
******************************************************************************/
static void RxIntrHandler(XAxiDma_BdRing * RxRingPtr)
{
u32 IrqStatus;
/* Read pending interrupts */
IrqStatus = XAxiDma_BdRingGetIrq(RxRingPtr);
/* Acknowledge pending interrupts */
XAxiDma_BdRingAckIrq(RxRingPtr, IrqStatus);
/*
* If no interrupt is asserted, raise error flag, reset the
* hardware to recover from the error, and return with no further
* processing.
*/
if (!(IrqStatus & XAXIDMA_IRQ_ALL_MASK)) {
DeviceErrors++;
AxiEthernetUtilErrorTrap
("AXIDma: No interrupts asserted in RX status register");
XAxiDma_Reset(&DmaInstance);
if(!XAxiDma_ResetIsDone(&DmaInstance)) {
AxiEthernetUtilErrorTrap ("Could not reset\n");
}
return;
}
/* If error interrupt is asserted, raise error flag, reset the
* hardware to recover from the error, and return with no further
* processing.
*/
if ((IrqStatus & XAXIDMA_IRQ_ERROR_MASK)) {
AxiEthernetUtilErrorTrap("AXIDMA: RX Error interrupts\n");
/* Reset could fail and hang
* NEED a way to handle this or do not call it??
*/
XAxiDma_Reset(&DmaInstance);
if(!XAxiDma_ResetIsDone(&DmaInstance)) {
AxiEthernetUtilErrorTrap ("AXIDMA: Could not reset\n");
}
return;
}
/*
* If Reception done interrupt is asserted, call RX call back function
* to handle the processed BDs and then raise the according flag.
*/
if ((IrqStatus & (XAXIDMA_IRQ_DELAY_MASK | XAXIDMA_IRQ_IOC_MASK))) {
RxCallBack(RxRingPtr);
}
}
/*****************************************************************************/
/**
*
* This is the Error handler callback function and this function increments the
* the error counter so that the main thread knows the number of errors.
*
* @param AxiEthernet is a reference to the AxiEthernet device instance.
*
* @return None.
*
* @note None.
*
******************************************************************************/
static void AxiEthernetErrorHandler(XAxiEthernet * AxiEthernet)
{
u32 Pending = XAxiEthernet_IntPending(AxiEthernet);
if (Pending & XAE_INT_RXRJECT_MASK) {
AxiEthernetUtilErrorTrap("AxiEthernet: Rx packet rejected");
}
if (Pending & XAE_INT_RXFIFOOVR_MASK) {
AxiEthernetUtilErrorTrap("AxiEthernet: Rx fifo over run");
}
XAxiEthernet_IntClear(AxiEthernet, Pending);
/*
* Bump counter
*/
DeviceErrors++;
}
/*****************************************************************************/
/**
*
* This function setups the interrupt system so interrupts can occur for the
* Axi Ethernet. This function is application-specific since the actual system
* may or may not have an interrupt controller. The Axi Ethernet could be
* directly connected to a processor without an interrupt controller. The user
* should modify this function to fit the application.
*
* @param IntcInstancePtr is a pointer to the instance of the Intc
* component.
* @param AxiEthernetInstancePtr is a pointer to the instance of the
* AxiEthernet component.
* @param DmaInstancePtr is a pointer to the instance of the AXIDMA
* component.
* @param AxiEthernetDeviceId is Device ID of the Axi Ethernet Device ,
* typically XPAR_<AXIETHERNET_instance>_DEVICE_ID value from
* xparameters.h.
* @param AxiEthernetIntrId is the Interrupt ID and is typically
* XPAR_<INTC_instance>_<AXIETHERNET_instance>_VEC_ID
* value from xparameters.h.
* @param DmaRxIntrId is the interrupt id for DMA Rx and is typically
* taken from XPAR_<AXIETHERNET_instance>_CONNECTED_DMARX_INTR
* @param DmaTxIntrId is the interrupt id for DMA Tx and is typically
* taken from XPAR_<AXIETHERNET_instance>_CONNECTED_DMATX_INTR
*
* @return -XST_SUCCESS to indicate success
* -XST_FAILURE to indicate failure
*
* @note None.
*
******************************************************************************/
static int AxiEthernetSetupIntrSystem(INTC *IntcInstancePtr,
XAxiEthernet *AxiEthernetInstancePtr,
XAxiDma *DmaInstancePtr,
u16 AxiEthernetIntrId,
u16 DmaRxIntrId,
u16 DmaTxIntrId)
{
XAxiDma_BdRing * TxRingPtr = XAxiDma_GetTxRing(DmaInstancePtr);
XAxiDma_BdRing * RxRingPtr = XAxiDma_GetRxRing(DmaInstancePtr);
int Status;
#ifdef XPAR_INTC_0_DEVICE_ID
#ifndef TESTAPP_GEN
/*
* Initialize the interrupt controller and connect the ISR
*/
Status = XIntc_Initialize(IntcInstancePtr, INTC_DEVICE_ID);
if (Status != XST_SUCCESS) {
AxiEthernetUtilErrorTrap("Unable to intialize the interrupt controller");
return XST_FAILURE;
}
#endif
#if XPAR_INTC_0_HAS_FAST == 1
TxRingPtr_Fast = TxRingPtr;
RxRingPtr_Fast = RxRingPtr;
AxiEthernetInstancePtr_Fast = AxiEthernetInstancePtr;
Status = XIntc_ConnectFastHandler(IntcInstancePtr, AxiEthernetIntrId,
(XFastInterruptHandler) AxiEthernetErrorFastHandler);
Status |= XIntc_ConnectFastHandler(IntcInstancePtr, DmaTxIntrId,
(XFastInterruptHandler) TxIntrFastHandler);
Status |= XIntc_ConnectFastHandler(IntcInstancePtr, DmaRxIntrId,
(XFastInterruptHandler) RxIntrFastHandler);
#else
Status = XIntc_Connect(IntcInstancePtr, AxiEthernetIntrId,
(XInterruptHandler)
AxiEthernetErrorHandler,
AxiEthernetInstancePtr);
Status |= XIntc_Connect(IntcInstancePtr, DmaTxIntrId,
(XInterruptHandler) TxIntrHandler,
TxRingPtr);
Status |= XIntc_Connect(IntcInstancePtr, DmaRxIntrId,
(XInterruptHandler) RxIntrHandler,
RxRingPtr);
#endif
if (Status != XST_SUCCESS) {
AxiEthernetUtilErrorTrap("Unable to connect ISR to interrupt controller");
return XST_FAILURE;
}
#ifndef TESTAPP_GEN
/*
* Start the interrupt controller
*/
Status = XIntc_Start(IntcInstancePtr, XIN_REAL_MODE);
if (Status != XST_SUCCESS) {
AxiEthernetUtilErrorTrap("Error starting intc");
return XST_FAILURE;
}
#endif
/*
* Enable interrupts from the hardware
*/
XIntc_Enable(IntcInstancePtr, AxiEthernetIntrId);
XIntc_Enable(IntcInstancePtr, DmaTxIntrId);
XIntc_Enable(IntcInstancePtr, DmaRxIntrId);
#else
XScuGic_Config *IntcConfig;
/*
* Initialize the interrupt controller driver so that it is ready to
* use.
*/
IntcConfig = XScuGic_LookupConfig(INTC_DEVICE_ID);
if (NULL == IntcConfig) {
return XST_FAILURE;
}
Status = XScuGic_CfgInitialize(IntcInstancePtr, IntcConfig,
IntcConfig->CpuBaseAddress);
if (Status != XST_SUCCESS) {
return XST_FAILURE;
}
XScuGic_SetPriorityTriggerType(IntcInstancePtr, DmaTxIntrId, 0xA0, 0x3);
XScuGic_SetPriorityTriggerType(IntcInstancePtr, DmaRxIntrId, 0xA0, 0x3);
XScuGic_SetPriorityTriggerType(IntcInstancePtr, AxiEthernetIntrId, 0xA0, 0x3);
/*
* Connect the device driver handler that will be called when an
* interrupt for the device occurs, the handler defined above performs
* the specific interrupt processing for the device.
*/
Status = XScuGic_Connect(IntcInstancePtr, DmaTxIntrId,
(Xil_InterruptHandler)TxIntrHandler,
TxRingPtr);
if (Status != XST_SUCCESS) {
return Status;
}
Status = XScuGic_Connect(IntcInstancePtr, DmaRxIntrId,
(Xil_InterruptHandler)RxIntrHandler,
RxRingPtr);
if (Status != XST_SUCCESS) {
return Status;
}
Status = XScuGic_Connect(IntcInstancePtr, AxiEthernetIntrId,
(Xil_InterruptHandler)AxiEthernetErrorHandler,
AxiEthernetInstancePtr);
if (Status != XST_SUCCESS) {
return Status;
}
XScuGic_Enable(IntcInstancePtr, AxiEthernetIntrId);
XScuGic_Enable(IntcInstancePtr, DmaTxIntrId);
XScuGic_Enable(IntcInstancePtr, DmaRxIntrId);
#endif
#ifndef TESTAPP_GEN
Xil_ExceptionInit();
Xil_ExceptionRegisterHandler(XIL_EXCEPTION_ID_INT,
(Xil_ExceptionHandler)INTC_HANDLER,
(void *)(IntcInstancePtr));
Xil_ExceptionEnable();
#endif
return XST_SUCCESS;
}
/*****************************************************************************/
/**
*
* This function disables the interrupts that occur for AxiEthernet.
*
* @param IntcInstancePtr is a pointer to the instance of the Intc
* component.
* @param AxiEthernetIntrId is the Interrupt ID and is typically
* XPAR_<INTC_instance>_<AXIETHERNET_instance>_VEC_ID
* value from xparameters.h.
* @param DmaRxIntrId is the interrupt id for DMA Rx and is typically
* taken from XPAR_<AXIETHERNET_instance>_CONNECTED_DMARX_INTR
* @param DmaTxIntrId is the interrupt id for DMA Tx and is typically
* taken from XPAR_<AXIETHERNET_instance>_CONNECTED_DMATX_INTR
*
* @return None.
*
* @note None.
*
******************************************************************************/
static void AxiEthernetDisableIntrSystem(INTC *IntcInstancePtr,
u16 AxiEthernetIntrId,
u16 DmaRxIntrId,
u16 DmaTxIntrId)
{
#ifdef XPAR_INTC_0_DEVICE_ID
/*
* Disconnect the interrupts for the DMA TX and RX channels
*/
XIntc_Disconnect(IntcInstancePtr, DmaTxIntrId);
XIntc_Disconnect(IntcInstancePtr, DmaRxIntrId);
/*
* Disconnect and disable the interrupt for the AxiEthernet device
*/
XIntc_Disconnect(IntcInstancePtr, AxiEthernetIntrId);
#else
/*
* Disconnect the interrupts for the DMA TX and RX channels
*/
XScuGic_Disconnect(IntcInstancePtr, DmaTxIntrId);
XScuGic_Disconnect(IntcInstancePtr, DmaRxIntrId);
/*
* Disconnect and disable the interrupt for the AxiEthernet device
*/
XScuGic_Disconnect(IntcInstancePtr, AxiEthernetIntrId);
#endif
}
#if XPAR_INTC_0_HAS_FAST == 1
/*****************************************************************************/
/**
*
* Fast Error Handler which calls AxiEthernetErrorHandler.
*
* @param None
*
* @return None.
*
* @note None.
*
******************************************************************************/
void AxiEthernetErrorFastHandler(void)
{
AxiEthernetErrorHandler((XAxiEthernet *)AxiEthernetInstancePtr_Fast);
}
/*****************************************************************************/
/**
*
* Fast Tramsmit Handler which calls TxIntrHandler.
*
* @param None
*
* @return None.
*
* @note None.
*
******************************************************************************/
void TxIntrFastHandler(void)
{
TxIntrHandler((XAxiDma_BdRing *)TxRingPtr_Fast);
}
/*****************************************************************************/
/**
*
* Fast Receive Handler which calls RxIntrHandler.
*
* @param None
*
* @return None.
*
* @note None.
*
******************************************************************************/
void RxIntrFastHandler(void)
{
RxIntrHandler((XAxiDma_BdRing *)RxRingPtr_Fast);
}
#endif