+++ /dev/null
-/******************************************************************************
-*
-* Copyright (C) 2010 - 2015 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
-* XILINX 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 xemacps.c
-* @addtogroup emacps_v3_1
-* @{
-*
-* The XEmacPs driver. Functions in this file are the minimum required functions
-* for this driver. See xemacps.h for a detailed description of the driver.
-*
-* <pre>
-* MODIFICATION HISTORY:
-*
-* Ver Who Date Changes
-* ----- ---- -------- -------------------------------------------------------
-* 1.00a wsy 01/10/10 First release
-* 2.1 srt 07/15/14 Add support for Zynq Ultrascale Mp GEM specification and
-* 64-bit changes.
-* 3.00 kvn 02/13/15 Modified code for MISRA-C:2012 compliance.
-* 3.0 hk 02/20/15 Added support for jumbo frames. Increase AHB burst.
-* Disable extended mode. Perform all 64 bit changes under
-* check for arch64.
-* 3.1 hk 08/10/15 Update upper 32 bit tx and rx queue ptr registers
-*
-* </pre>
-******************************************************************************/
-
-/***************************** Include Files *********************************/
-
-#include "xemacps.h"
-
-/************************** Constant Definitions *****************************/
-
-
-/**************************** Type Definitions *******************************/
-
-
-/***************** Macros (Inline Functions) Definitions *********************/
-
-
-/************************** Function Prototypes ******************************/
-
-void XEmacPs_StubHandler(void); /* Default handler routine */
-
-/************************** Variable Definitions *****************************/
-
-
-/*****************************************************************************/
-/**
-* Initialize a specific XEmacPs instance/driver. The initialization entails:
-* - Initialize fields of the XEmacPs instance structure
-* - Reset hardware and apply default options
-* - Configure the DMA channels
-*
-* The PHY is setup independently from the device. Use the MII or whatever other
-* interface may be present for setup.
-*
-* @param InstancePtr is a pointer to the instance to be worked on.
-* @param CfgPtr is the device configuration structure containing required
-* hardware build data.
-* @param EffectiveAddress is the base address of the device. If address
-* translation is not utilized, this parameter can be passed in using
-* CfgPtr->Config.BaseAddress to specify the physical base address.
-*
-* @return
-* - XST_SUCCESS if initialization was successful
-*
-******************************************************************************/
-LONG XEmacPs_CfgInitialize(XEmacPs *InstancePtr, XEmacPs_Config * CfgPtr,
- UINTPTR EffectiveAddress)
-{
- /* Verify arguments */
- Xil_AssertNonvoid(InstancePtr != NULL);
- Xil_AssertNonvoid(CfgPtr != NULL);
-
- /* Set device base address and ID */
- InstancePtr->Config.DeviceId = CfgPtr->DeviceId;
- InstancePtr->Config.BaseAddress = EffectiveAddress;
-
- /* Set callbacks to an initial stub routine */
- InstancePtr->SendHandler = ((XEmacPs_Handler)((void*)XEmacPs_StubHandler));
- InstancePtr->RecvHandler = ((XEmacPs_Handler)(void*)XEmacPs_StubHandler);
- InstancePtr->ErrorHandler = ((XEmacPs_ErrHandler)(void*)XEmacPs_StubHandler);
-
- /* Reset the hardware and set default options */
- InstancePtr->IsReady = XIL_COMPONENT_IS_READY;
- XEmacPs_Reset(InstancePtr);
-
- return (LONG)(XST_SUCCESS);
-}
-
-
-/*****************************************************************************/
-/**
-* Start the Ethernet controller as follows:
-* - Enable transmitter if XTE_TRANSMIT_ENABLE_OPTION is set
-* - Enable receiver if XTE_RECEIVER_ENABLE_OPTION is set
-* - Start the SG DMA send and receive channels and enable the device
-* interrupt
-*
-* @param InstancePtr is a pointer to the instance to be worked on.
-*
-* @return N/A
-*
-* @note
-* Hardware is configured with scatter-gather DMA, the driver expects to start
-* the scatter-gather channels and expects that the user has previously set up
-* the buffer descriptor lists.
-*
-* This function makes use of internal resources that are shared between the
-* Start, Stop, and Set/ClearOptions functions. So if one task might be setting
-* device options while another is trying to start the device, the user is
-* required to provide protection of this shared data (typically using a
-* semaphore).
-*
-* This function must not be preempted by an interrupt that may service the
-* device.
-*
-******************************************************************************/
-void XEmacPs_Start(XEmacPs *InstancePtr)
-{
- u32 Reg;
-
- /* Assert bad arguments and conditions */
- Xil_AssertVoid(InstancePtr != NULL);
- Xil_AssertVoid(InstancePtr->IsReady == (u32)XIL_COMPONENT_IS_READY);
-
- /* Start DMA */
- /* When starting the DMA channels, both transmit and receive sides
- * need an initialized BD list.
- */
- if (InstancePtr->Version == 2) {
- Xil_AssertVoid(InstancePtr->RxBdRing.BaseBdAddr != 0);
- Xil_AssertVoid(InstancePtr->TxBdRing.BaseBdAddr != 0);
- XEmacPs_WriteReg(InstancePtr->Config.BaseAddress,
- XEMACPS_RXQBASE_OFFSET,
- InstancePtr->RxBdRing.BaseBdAddr);
-
- XEmacPs_WriteReg(InstancePtr->Config.BaseAddress,
- XEMACPS_TXQBASE_OFFSET,
- InstancePtr->TxBdRing.BaseBdAddr);
- }
-
- /* clear any existed int status */
- XEmacPs_WriteReg(InstancePtr->Config.BaseAddress, XEMACPS_ISR_OFFSET,
- XEMACPS_IXR_ALL_MASK);
-
- /* Enable transmitter if not already enabled */
- if ((InstancePtr->Options & (u32)XEMACPS_TRANSMITTER_ENABLE_OPTION)!=0x00000000U) {
- Reg = XEmacPs_ReadReg(InstancePtr->Config.BaseAddress,
- XEMACPS_NWCTRL_OFFSET);
- if ((!(Reg & XEMACPS_NWCTRL_TXEN_MASK))==TRUE) {
- XEmacPs_WriteReg(InstancePtr->Config.BaseAddress,
- XEMACPS_NWCTRL_OFFSET,
- Reg | (u32)XEMACPS_NWCTRL_TXEN_MASK);
- }
- }
-
- /* Enable receiver if not already enabled */
- if ((InstancePtr->Options & XEMACPS_RECEIVER_ENABLE_OPTION) != 0x00000000U) {
- Reg = XEmacPs_ReadReg(InstancePtr->Config.BaseAddress,
- XEMACPS_NWCTRL_OFFSET);
- if ((!(Reg & XEMACPS_NWCTRL_RXEN_MASK))==TRUE) {
- XEmacPs_WriteReg(InstancePtr->Config.BaseAddress,
- XEMACPS_NWCTRL_OFFSET,
- Reg | (u32)XEMACPS_NWCTRL_RXEN_MASK);
- }
- }
-
- /* Enable TX and RX interrupts */
- XEmacPs_IntEnable(InstancePtr, (XEMACPS_IXR_TX_ERR_MASK |
- XEMACPS_IXR_RX_ERR_MASK | (u32)XEMACPS_IXR_FRAMERX_MASK |
- (u32)XEMACPS_IXR_TXCOMPL_MASK));
-
- /* Enable TX Q1 Interrupts */
- if (InstancePtr->Version > 2)
- XEmacPs_IntQ1Enable(InstancePtr, XEMACPS_INTQ1_IXR_ALL_MASK);
-
- /* Mark as started */
- InstancePtr->IsStarted = XIL_COMPONENT_IS_STARTED;
-
- return;
-}
-
-
-/*****************************************************************************/
-/**
-* Gracefully stop the Ethernet MAC as follows:
-* - Disable all interrupts from this device
-* - Stop DMA channels
-* - Disable the tansmitter and receiver
-*
-* Device options currently in effect are not changed.
-*
-* This function will disable all interrupts. Default interrupts settings that
-* had been enabled will be restored when XEmacPs_Start() is called.
-*
-* @param InstancePtr is a pointer to the instance to be worked on.
-*
-* @note
-* This function makes use of internal resources that are shared between the
-* Start, Stop, SetOptions, and ClearOptions functions. So if one task might be
-* setting device options while another is trying to start the device, the user
-* is required to provide protection of this shared data (typically using a
-* semaphore).
-*
-* Stopping the DMA channels causes this function to block until the DMA
-* operation is complete.
-*
-******************************************************************************/
-void XEmacPs_Stop(XEmacPs *InstancePtr)
-{
- u32 Reg;
-
- Xil_AssertVoid(InstancePtr != NULL);
- Xil_AssertVoid(InstancePtr->IsReady == (u32)XIL_COMPONENT_IS_READY);
-
- /* Disable all interrupts */
- XEmacPs_WriteReg(InstancePtr->Config.BaseAddress, XEMACPS_IDR_OFFSET,
- XEMACPS_IXR_ALL_MASK);
-
- /* Disable the receiver & transmitter */
- Reg = XEmacPs_ReadReg(InstancePtr->Config.BaseAddress,
- XEMACPS_NWCTRL_OFFSET);
- Reg &= (u32)(~XEMACPS_NWCTRL_RXEN_MASK);
- Reg &= (u32)(~XEMACPS_NWCTRL_TXEN_MASK);
- XEmacPs_WriteReg(InstancePtr->Config.BaseAddress,
- XEMACPS_NWCTRL_OFFSET, Reg);
-
- /* Mark as stopped */
- InstancePtr->IsStarted = 0U;
-}
-
-
-/*****************************************************************************/
-/**
-* Perform a graceful reset of the Ethernet MAC. Resets the DMA channels, the
-* transmitter, and the receiver.
-*
-* Steps to reset
-* - Stops transmit and receive channels
-* - Stops DMA
-* - Configure transmit and receive buffer size to default
-* - Clear transmit and receive status register and counters
-* - Clear all interrupt sources
-* - Clear phy (if there is any previously detected) address
-* - Clear MAC addresses (1-4) as well as Type IDs and hash value
-*
-* All options are placed in their default state. Any frames in the
-* descriptor lists will remain in the lists. The side effect of doing
-* this is that after a reset and following a restart of the device, frames
-* were in the list before the reset may be transmitted or received.
-*
-* The upper layer software is responsible for re-configuring (if necessary)
-* and restarting the MAC after the reset. Note also that driver statistics
-* are not cleared on reset. It is up to the upper layer software to clear the
-* statistics if needed.
-*
-* When a reset is required, the driver notifies the upper layer software of
-* this need through the ErrorHandler callback and specific status codes.
-* The upper layer software is responsible for calling this Reset function
-* and then re-configuring the device.
-*
-* @param InstancePtr is a pointer to the instance to be worked on.
-*
-******************************************************************************/
-void XEmacPs_Reset(XEmacPs *InstancePtr)
-{
- u32 Reg;
- u8 i;
- s8 EmacPs_zero_MAC[6] = { 0x0, 0x0, 0x0, 0x0, 0x0, 0x0 };
-
- Xil_AssertVoid(InstancePtr != NULL);
- Xil_AssertVoid(InstancePtr->IsReady == (u32)XIL_COMPONENT_IS_READY);
-
- /* Stop the device and reset hardware */
- XEmacPs_Stop(InstancePtr);
- InstancePtr->Options = XEMACPS_DEFAULT_OPTIONS;
-
- InstancePtr->Version = XEmacPs_ReadReg(InstancePtr->Config.BaseAddress, 0xFC);
-
- InstancePtr->Version = (InstancePtr->Version >> 16) & 0xFFF;
-
- InstancePtr->MaxMtuSize = XEMACPS_MTU;
- InstancePtr->MaxFrameSize = XEMACPS_MTU + XEMACPS_HDR_SIZE +
- XEMACPS_TRL_SIZE;
- InstancePtr->MaxVlanFrameSize = InstancePtr->MaxFrameSize +
- XEMACPS_HDR_VLAN_SIZE;
- InstancePtr->RxBufMask = XEMACPS_RXBUF_LEN_MASK;
-
- /* Setup hardware with default values */
- XEmacPs_WriteReg(InstancePtr->Config.BaseAddress,
- XEMACPS_NWCTRL_OFFSET,
- (XEMACPS_NWCTRL_STATCLR_MASK |
- XEMACPS_NWCTRL_MDEN_MASK) &
- (u32)(~XEMACPS_NWCTRL_LOOPEN_MASK));
-
- Reg = XEmacPs_ReadReg(InstancePtr->Config.BaseAddress,
- XEMACPS_NWCFG_OFFSET);
- Reg &= XEMACPS_NWCFG_MDCCLKDIV_MASK;
-
- Reg = Reg | (u32)XEMACPS_NWCFG_100_MASK |
- (u32)XEMACPS_NWCFG_FDEN_MASK |
- (u32)XEMACPS_NWCFG_UCASTHASHEN_MASK;
-
- XEmacPs_WriteReg(InstancePtr->Config.BaseAddress,
- XEMACPS_NWCFG_OFFSET, Reg);
- if (InstancePtr->Version > 2) {
- XEmacPs_WriteReg(InstancePtr->Config.BaseAddress, XEMACPS_NWCFG_OFFSET,
- (XEmacPs_ReadReg(InstancePtr->Config.BaseAddress, XEMACPS_NWCFG_OFFSET) |
- XEMACPS_NWCFG_DWIDTH_64_MASK));
- }
-
- XEmacPs_WriteReg(InstancePtr->Config.BaseAddress,
- XEMACPS_DMACR_OFFSET,
- (((((u32)XEMACPS_RX_BUF_SIZE / (u32)XEMACPS_RX_BUF_UNIT) +
- (((((u32)XEMACPS_RX_BUF_SIZE %
- (u32)XEMACPS_RX_BUF_UNIT))!=(u32)0) ? 1U : 0U)) <<
- (u32)(XEMACPS_DMACR_RXBUF_SHIFT)) &
- (u32)(XEMACPS_DMACR_RXBUF_MASK)) |
- (u32)XEMACPS_DMACR_RXSIZE_MASK |
- (u32)XEMACPS_DMACR_TXSIZE_MASK);
-
-
- /* Single bursts */
- /* FIXME: Why Single bursts? */
- if (InstancePtr->Version > 2) {
- XEmacPs_WriteReg(InstancePtr->Config.BaseAddress, XEMACPS_DMACR_OFFSET,
- (XEmacPs_ReadReg(InstancePtr->Config.BaseAddress, XEMACPS_DMACR_OFFSET) |
-#ifdef __aarch64__
- (u32)XEMACPS_DMACR_ADDR_WIDTH_64 |
-#endif
- (u32)XEMACPS_DMACR_INCR16_AHB_BURST));
- }
-
- XEmacPs_WriteReg(InstancePtr->Config.BaseAddress,
- XEMACPS_TXSR_OFFSET, 0x0U);
-
- XEmacPs_SetQueuePtr(InstancePtr, 0, 0x00U, (u16)XEMACPS_SEND);
- if (InstancePtr->Version > 2)
- XEmacPs_SetQueuePtr(InstancePtr, 0, 0x01U, (u16)XEMACPS_SEND);
- XEmacPs_SetQueuePtr(InstancePtr, 0, 0x00U, (u16)XEMACPS_RECV);
-
- XEmacPs_WriteReg(InstancePtr->Config.BaseAddress,
- XEMACPS_RXSR_OFFSET, 0x0U);
-
- XEmacPs_WriteReg(InstancePtr->Config.BaseAddress, XEMACPS_IDR_OFFSET,
- XEMACPS_IXR_ALL_MASK);
-
- Reg = XEmacPs_ReadReg(InstancePtr->Config.BaseAddress,
- XEMACPS_ISR_OFFSET);
- XEmacPs_WriteReg(InstancePtr->Config.BaseAddress, XEMACPS_ISR_OFFSET,
- Reg);
-
- XEmacPs_ClearHash(InstancePtr);
-
- for (i = 1U; i < 5U; i++) {
- (void)XEmacPs_SetMacAddress(InstancePtr, EmacPs_zero_MAC, i);
- (void)XEmacPs_SetTypeIdCheck(InstancePtr, 0x00000000U, i);
- }
-
- /* clear all counters */
- for (i = 0U; i < (u8)((XEMACPS_LAST_OFFSET - XEMACPS_OCTTXL_OFFSET) / 4U);
- i++) {
- (void)XEmacPs_ReadReg(InstancePtr->Config.BaseAddress,
- XEMACPS_OCTTXL_OFFSET + (u32)(((u32)i) * ((u32)4)));
- }
-
- /* Disable the receiver */
- Reg = XEmacPs_ReadReg(InstancePtr->Config.BaseAddress,
- XEMACPS_NWCTRL_OFFSET);
- Reg &= (u32)(~XEMACPS_NWCTRL_RXEN_MASK);
- XEmacPs_WriteReg(InstancePtr->Config.BaseAddress,
- XEMACPS_NWCTRL_OFFSET, Reg);
-
- /* Sync default options with hardware but leave receiver and
- * transmitter disabled. They get enabled with XEmacPs_Start() if
- * XEMACPS_TRANSMITTER_ENABLE_OPTION and
- * XEMACPS_RECEIVER_ENABLE_OPTION are set.
- */
- (void)XEmacPs_SetOptions(InstancePtr, InstancePtr->Options &
- ~((u32)XEMACPS_TRANSMITTER_ENABLE_OPTION |
- (u32)XEMACPS_RECEIVER_ENABLE_OPTION));
-
- (void)XEmacPs_ClearOptions(InstancePtr, ~InstancePtr->Options);
-}
-
-
-/******************************************************************************/
-/**
- * This is a stub for the asynchronous callbacks. The stub is here in case the
- * upper layer forgot to set the handler(s). On initialization, all handlers are
- * set to this callback. It is considered an error for this handler to be
- * invoked.
- *
- ******************************************************************************/
-void XEmacPs_StubHandler(void)
-{
- Xil_AssertVoidAlways();
-}
-
-/*****************************************************************************/
-/**
-* This function sets the start address of the transmit/receive buffer queue.
-*
-* @param InstancePtr is a pointer to the instance to be worked on.
-* @QPtr Address of the Queue to be written
-* @QueueNum Buffer Queue Index
-* @Direction Transmit/Recive
-*
-* @note
-* The buffer queue addresses has to be set before starting the transfer, so
-* this function has to be called in prior to XEmacPs_Start()
-*
-******************************************************************************/
-void XEmacPs_SetQueuePtr(XEmacPs *InstancePtr, UINTPTR QPtr, u8 QueueNum,
- u16 Direction)
-{
- /* Assert bad arguments and conditions */
- Xil_AssertVoid(InstancePtr != NULL);
- Xil_AssertVoid(InstancePtr->IsReady == (u32)XIL_COMPONENT_IS_READY);
-
- /* If already started, then there is nothing to do */
- if (InstancePtr->IsStarted == (u32)XIL_COMPONENT_IS_STARTED) {
- return;
- }
-
- if (QueueNum == 0x00U) {
- if (Direction == XEMACPS_SEND) {
- XEmacPs_WriteReg(InstancePtr->Config.BaseAddress,
- XEMACPS_TXQBASE_OFFSET,
- (QPtr & ULONG64_LO_MASK));
- } else {
- XEmacPs_WriteReg(InstancePtr->Config.BaseAddress,
- XEMACPS_RXQBASE_OFFSET,
- (QPtr & ULONG64_LO_MASK));
- }
- }
- else {
- XEmacPs_WriteReg(InstancePtr->Config.BaseAddress,
- XEMACPS_TXQ1BASE_OFFSET,
- (QPtr & ULONG64_LO_MASK));
- }
-#ifdef __aarch64__
- if (Direction == XEMACPS_SEND) {
- /* Set the MSB of TX Queue start address */
- XEmacPs_WriteReg(InstancePtr->Config.BaseAddress,
- XEMACPS_MSBBUF_TXQBASE_OFFSET,
- (u32)((QPtr & ULONG64_HI_MASK) >> 32U));
- } else {
- /* Set the MSB of RX Queue start address */
- XEmacPs_WriteReg(InstancePtr->Config.BaseAddress,
- XEMACPS_MSBBUF_RXQBASE_OFFSET,
- (u32)((QPtr & ULONG64_HI_MASK) >> 32U));
- }
-#endif
-}
-/** @} */