summaryrefslogtreecommitdiff
path: root/cpsw/src/netif/cpsw.c
diff options
context:
space:
mode:
Diffstat (limited to 'cpsw/src/netif/cpsw.c')
-rwxr-xr-xcpsw/src/netif/cpsw.c1545
1 files changed, 1545 insertions, 0 deletions
diff --git a/cpsw/src/netif/cpsw.c b/cpsw/src/netif/cpsw.c
new file mode 100755
index 0000000..e82595b
--- /dev/null
+++ b/cpsw/src/netif/cpsw.c
@@ -0,0 +1,1545 @@
+/**
+ * \file cpsw.c
+ *
+ * \brief CPSW device abstraction layer APIs.
+ *
+ * This file contains the device abstraction layer APIs for CPSW RGMII.
+ */
+
+/*
+* Copyright (C) 2010 Texas Instruments Incorporated - http://www.ti.com/
+*/
+/*
+* Redistribution and use in source and binary forms, with or without
+* modification, are permitted provided that the following conditions
+* are met:
+*
+* Redistributions of source code must retain the above copyright
+* notice, this list of conditions and the following disclaimer.
+*
+* Redistributions in binary form must reproduce the above copyright
+* notice, this list of conditions and the following disclaimer in the
+* documentation and/or other materials provided with the
+* distribution.
+*
+* Neither the name of Texas Instruments Incorporated nor the names of
+* its contributors may be used to endorse or promote products derived
+* from this software without specific prior written permission.
+*
+* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*
+*/
+
+#include "hw_types.h"
+#include "cpsw.h"
+
+/*******************************************************************************
+* INTERNAL MACRO DEFINITIONS
+*******************************************************************************/
+#define CPSW_CORE_OFFSET (0x10u)
+#define CPSW_MAX_HEADER_DESC (0x08u)
+#define CPDMA_P0_DEF_TX_MAP (0x76543210u)
+#define ALE_ENTRY_WORDS (0x03u)
+#define CPDMA_ERR_CHANNEL_POS (0xFFu)
+#define CPSW_PORT_DUAL_MAC_MODE (0x01u << \
+ CPSW_PORT_P0_TX_IN_CTL_TX_IN_SEL_SHIFT)
+#define CPSW_PORT_RATE_LIM_MODE (0x02u << \
+ CPSW_PORT_P0_TX_IN_CTL_TX_IN_SEL_SHIFT)
+
+/*******************************************************************************
+* API FUNCTION DEFINITIONS
+*******************************************************************************/
+/**
+ * \brief Resets the CPSW Subsystem.
+ *
+ * \param baseAddr Base address of the CPSW Subsystem
+ *
+ * \return None
+ **/
+void CPSWSSReset(unsigned int baseAddr)
+{
+ /* Reset the CPSW */
+ HWREG(baseAddr + CPSW_SS_SOFT_RESET) = CPSW_SS_SOFT_RESET_SOFT_RESET;
+
+ while(HWREG(baseAddr + CPSW_SS_SOFT_RESET)
+ & CPSW_SS_SOFT_RESET_SOFT_RESET);
+}
+
+/**
+ * \brief Force the CPGMAC_SL into gigabit mode if the input GMII_MTCLK has
+ * been stopped by the PHY
+ *
+ * \param baseAddr Base address of the CPSW Sliver Module registers.
+ *
+ * \return None
+ *
+ **/
+void CPSWSlGigModeForceEnable(unsigned int baseAddr)
+{
+ HWREG(baseAddr + CPSW_SL_MACCONTROL) |= CPSW_SL_MACCONTROL_GIG_FORCE;
+}
+
+/**
+ * \brief Enables the fullduplex and gigabit mode to be selected
+ * from the FULLDUPLEX_IN and GIG_IN input signals and not from the
+ * fullduplex and gig bits in this register. The FULLDUPLEX_MODE bit
+ * reflects the actual fullduplex mode selected
+ *
+ * \param baseAddr Base address of the CPSW Sliver Module registers.
+ *
+ * \return None
+ *
+ **/
+void CPSWSlControlExtEnable(unsigned int baseAddr)
+{
+ HWREG(baseAddr + CPSW_SL_MACCONTROL) |= CPSW_SL_MACCONTROL_EXT_EN;
+}
+
+
+/**
+ * \brief Disables the CPGMAC_SL gigabit mode if the input GMII_MTCLK has
+ * been stopped by the PHY
+ *
+ * \param baseAddr Base address of the CPSW Sliver Module registers.
+ *
+ * \return None
+ *
+ **/
+void CPSWSlGigModeForceDisable(unsigned int baseAddr)
+{
+ HWREG(baseAddr + CPSW_SL_MACCONTROL) &= ~CPSW_SL_MACCONTROL_GIG_FORCE;
+}
+
+/**
+ * \brief Sets the Transfer mode, 10/100 or gigabit mode and the duplex
+ * mode for the sliver.
+ *
+ * \param baseAddr Base address of the CPSW Sliver Module registers.
+ * \param mode The transfer mode
+ * 'mode' can take one of the below values. \n
+ * CPSW_SLIVER_NON_GIG_HALF_DUPLEX - 10/100 Mbps mode, half duplex. \n
+ * CPSW_SLIVER_NON_GIG_FULL_DUPLEX - 10/100 Mbps mode, full duplex. \n
+ * CPSW_SLIVER_GIG_FULL_DUPLEX - 1000 Mbps mode, full duplex. \n
+ * Note: for 10Mbps mode, CPSW_SLIVER_INBAND has to be configured. \n
+ *
+ * \return None
+ *
+ **/
+void CPSWSlTransferModeSet(unsigned int baseAddr, unsigned int mode)
+{
+ HWREG(baseAddr + CPSW_SL_MACCONTROL) &= ~(CPSW_SL_MACCONTROL_GIG
+ | CPSW_SL_MACCONTROL_FULLDUPLEX);
+
+ HWREG(baseAddr + CPSW_SL_MACCONTROL) |= mode;
+}
+
+/**
+ * \brief Returns the MAC Status. The value will be the contents of the MAC
+ * status register.
+ *
+ * \param baseAddr Base address of the CPSW Sliver Module registers.
+ * \param statFlag Status flags to be read.
+ * statFlag can take an OR combination of the below values. \n
+ * CPSW_SLIVER_STATE - The Sliver state. \n
+ * CPSW_SLIVER_EXT_GIG_INPUT_BIT - The EXT_GIG input bit mask.\n
+ * CPSW_SLIVER_EXT_FULL_DUPLEX_BIT - The EXT_FULLDUPLEX input
+ * bit mask. \n
+ * CPSW_SLIVER_RX_FLOWCTRL - The receive flow control active. \n
+ * CPSW_SLIVER_TX_FLOWCTRL - The transmit flow control.
+ *
+ *
+ * \return MAC Status
+ * The MAC status register value returned can be compared against
+ * the below tokens. \n
+ * CPSW_SLIVER_STATE_IDLE - The Sliver is in idle state. \n
+ * CPSW_SLIVER_EXT_GIG_INPUT_HIGH - The EXT_GIG input
+ * bit is in HIGH state.\n
+ * CPSW_SLIVER_EXT_FULL_DUPLEX_HIGH - The EXT_FULLDUPLEX input
+ * bit is in HIGH state. \n
+ * CPSW_SLIVER_RX_FLOWCTRL_ACTIVE - The receive flow control is
+ * active. \n
+ * CPSW_SLIVER_TX_FLOWCTRL_ACTIVE - The pause time period is
+ * observed for a received
+ * pause frame
+ *
+ **/
+unsigned int CPSWSlMACStatusGet(unsigned int baseAddr, unsigned int statFlag)
+{
+ /* Return the required status only */
+ return (HWREG(baseAddr + CPSW_SL_MACSTATUS) & statFlag);
+}
+
+/**
+ * \brief Resets the CPSW Sliver Logic.
+ *
+ * \param baseAddr Base address of the CPSW Sliver Module registers.
+ *
+ * \return None
+ *
+ **/
+void CPSWSlReset(unsigned int baseAddr)
+{
+ /* Reset the sliver logic */
+ HWREG(baseAddr + CPSW_SL_SOFT_RESET) = CPSW_SL_SOFT_RESET_SOFT_RESET;
+
+ /* Wait till the reset completes */
+ while(CPSW_SL_SOFT_RESET_SOFT_RESET ==
+ ((HWREG(baseAddr + CPSW_SL_SOFT_RESET))
+ & CPSW_SL_SOFT_RESET_SOFT_RESET));
+}
+
+
+/**
+ * \brief Sets the maximum length for received frame.
+ *
+ * \param baseAddr Base address of the CPSW Sliver Module registers.
+ * \param rxMaxLen Maximum length for a received frame
+ * The default value for 'rxMaxLen' is 1518. The maximum value
+ * which can be set is 16383.
+ *
+ * \return None
+ *
+ **/
+void CPSWSlRxMaxLenSet(unsigned int baseAddr, unsigned int rxMaxLen)
+{
+ /* Set the desired maximum length */
+ HWREG(baseAddr + CPSW_SL_RX_MAXLEN) = rxMaxLen;
+}
+
+/**
+ * \brief Enables GMII for the sliver.
+ *
+ * \param baseAddr Base address of the CPSW Sliver Module registers.
+ *
+ * \return None
+ **/
+void CPSWSlGMIIEnable(unsigned int baseAddr)
+{
+ HWREG(baseAddr + CPSW_SL_MACCONTROL) |= CPSW_SL_MACCONTROL_GMII_EN;
+}
+
+/**
+ * \brief Enables RGMII for the sliver.
+ *
+ * \param baseAddr Base address of the CPSW Sliver Module registers.
+ *
+ * \return None
+ **/
+void CPSWSlRGMIIEnable(unsigned int baseAddr)
+{
+ HWREG(baseAddr + CPSW_SL_MACCONTROL) |= (CPSW_SL_MACCONTROL_GMII_EN
+ | CPSW_SL_MACCONTROL_IFCTL_A
+ | CPSW_SL_MACCONTROL_IFCTL_B);
+}
+
+/**
+ * \brief Resets the CPSW Wrapper module.
+ *
+ * \param baseAddr Base address of the CPSW Wrapper Module
+ *
+ * \return None
+ **/
+void CPSWWrReset(unsigned int baseAddr)
+{
+ /* Reset the CPSW Wrapper */
+ HWREG(baseAddr + CPSW_WR_SOFT_RESET) = CPSW_WR_SOFT_RESET_SOFT_RESET;
+
+ while(HWREG(baseAddr + CPSW_WR_SOFT_RESET)
+ & CPSW_WR_SOFT_RESET_SOFT_RESET);
+}
+
+/**
+ * \brief Resets the Control Register of CPSW Wrapper module
+ *
+ * \param baseAddr Base address of the CPSW Wrapper Module
+ *
+ * \return None
+ **/
+void CPSWWrControlRegReset(unsigned int baseAddr)
+{
+ /* Reset the CPSW Wrapper control Register */
+ HWREG(baseAddr + CPSW_WR_CONTROL) = CPSW_WR_CONTROL_MMR_RESET;
+}
+
+/**
+ * \brief Enables an interrupt for the specified core.
+ *
+ * \param baseAddr Base address of the CPSW Wrapper Module
+ * \param core Core number
+ * \param channel Channel number
+ * \param intFlag Interrupt to be enabled
+ * 'intFlag' can take one of the below values. \n
+ * CPSW_CORE_INT_RX_THRESH - RX threshold interrupt \n
+ * CPSW_CORE_INT_RX_PULSE - RX pulse interrupt \n
+ * CPSW_CORE_INT_TX_PULSE - TX pulse interrupt \n
+ * CPSW_CORE_INT_MISC - Miscellaneous interrupt
+ *
+ * \return None
+ **/
+void CPSWWrCoreIntEnable(unsigned int baseAddr, unsigned int core,
+ unsigned int channel, unsigned int intFlag)
+{
+ HWREG(baseAddr + CPSW_WR_C_RX_THRESH_EN(core) + intFlag) |= (1 << channel);
+}
+
+/**
+ * \brief Disables an interrupt for the specified core.
+ *
+ * \param baseAddr Base address of thei CPSW Wrapper Module
+ * \param core Core number
+ * \param channel Channel number
+ * \param intFlag Interrupt to be disabled
+ * 'intFlag' can take one of the below values. \n
+ * CPSW_CORE_INT_RX_THRESH - RX threshold interrupt \n
+ * CPSW_CORE_INT_RX_PULSE - RX pulse interrupt \n
+ * CPSW_CORE_INT_TX_PULSE - TX pulse interrupt \n
+ * CPSW_CORE_INT_MISC - Miscellaneous interrupt
+ *
+ * \return None
+ **/
+void CPSWWrCoreIntDisable(unsigned int baseAddr, unsigned int core,
+ unsigned int channel, unsigned int intFlag)
+{
+ HWREG(baseAddr + CPSW_WR_C_RX_THRESH_EN(core) + intFlag) &=
+ ~(1 << channel);
+}
+
+/**
+ * \brief Returns the interrupt status of the core for the specified
+ * channel
+ *
+ * \param baseAddr Base address of thei CPSW Wrapper Module
+ * \param core Core number
+ * \param channel Channel number
+ * \param intFlag Interrupt status to be read
+ * 'intFlag' can take one of the below values. \n
+ * CPSW_CORE_INT_RX_THRESH - RX threshold interrupt \n
+ * CPSW_CORE_INT_RX_PULSE - RX pulse interrupt \n
+ * CPSW_CORE_INT_TX_PULSE - TX pulse interrupt \n
+ * CPSW_CORE_INT_MISC - Miscellaneous interrupt
+ *
+ * \return same as intFlag if the status is set
+ * '0' if the status is cleared
+ **/
+unsigned int CPSWWrCoreIntStatusGet(unsigned int baseAddr, unsigned int core,
+ unsigned int channel, unsigned int intFlag)
+{
+ return (HWREG(baseAddr + CPSW_WR_C_RX_THRESH_STAT(core) + intFlag)
+ & (1 << channel));
+}
+
+/**
+ * \brief Returns the RGMII status requested.
+ *
+ * \param baseAddr Base address of the CPSW Wrapper Module
+ * \param statFlag Status to be checked
+ * 'statFlag' can take a combination of the below values. \n
+ * CPSW_RGMII2_DUPLEX - Duplex of RGMII2 \n
+ * CPSW_RGMII2_SPEED - Speed of RGMII2 \n
+ * CPSW_RGMII2_LINK_STAT - Link Status of RGMII2 \n
+ * CPSW_RGMII1_DUPLEX - Duplex of RGMII1 \n
+ * CPSW_RGMII1_SPEED - Speed of RGMII1 \n
+ * CPSW_RGMII1_LINK_STAT - Link Status of RGMII1 \n
+ *
+ * The returned value can be compared agains the below values \n
+ * CPSW_RGMII2_DUPLEX_FULL - RGMII2 full duplex \n
+ * CPSW_RGMII2_DUPLEX_HALF - RGMII2 half duplex \n
+ * CPSW_RGMII2_SPEED_10M - Speed is 10 Mbps \n
+ * CPSW_RGMII2_SPEED_100M - Speed is 100 Mbps \n
+ * CPSW_RGMII2_SPEED_1000M - Speed is 1000 Mbps \n
+ * CPSW_RGMII2_LINK_UP - RGMII2 link is up\n
+ * CPSW_RGMII2_LINK_DOWN - RGMII2 link is down \n
+ * CPSW_RGMII1_DUPLEX_FULL - RGMII1 full duplex \n
+ * CPSW_RGMII1_DUPLEX_HALF - RGMII1 half duplex \n
+ * CPSW_RGMII1_SPEED_10M - Speed is 10 Mbps \n
+ * CPSW_RGMII1_SPEED_100M - Speed is 100 Mbps \n
+ * CPSW_RGMII1_SPEED_1000M - Speed is 1000 Mbps \n
+ * CPSW_RGMII1_LINK_UP - RGMII1 link is up\n
+ * CPSW_RGMII1_LINK_DOWN - RGMII1 link is down \n
+ *
+ * \return Status of RGMII. Return value can be compared agains the same
+ * statFlag passed.
+ **/
+unsigned int CPSWWrRGMIIStatusGet(unsigned int baseAddr, unsigned int statFlag)
+{
+ return (HWREG(baseAddr + CPSW_WR_RGMII_CTL) & statFlag);
+}
+
+/**
+ * \brief Initializes the ALE. The ALE logic is reset and the ALE table
+ * entries are cleared.
+ *
+ * \param baseAddr Base address of the ALE module
+ *
+ * \return None
+ **/
+void CPSWALEInit(unsigned int baseAddr)
+{
+ HWREG(baseAddr + CPSW_ALE_CONTROL) = (CPSW_ALE_CONTROL_CLEAR_TABLE
+ | CPSW_ALE_CONTROL_ENABLE_ALE);
+}
+
+/**
+ * \brief Age Out Address Table. The Untouched ageable ALE table
+ * entries are cleared.
+ *
+ * \param baseAddr Base address of the ALE module
+ *
+ * \return None
+ **/
+void CPSWALEAgeOut(unsigned int baseAddr)
+{
+ HWREG(baseAddr + CPSW_ALE_CONTROL) |= CPSW_ALE_CONTROL_AGE_OUT_NOW;
+
+ while(CPSW_ALE_CONTROL_AGE_OUT_NOW & (HWREG(baseAddr + CPSW_ALE_CONTROL)));
+
+}
+
+/**
+ * \brief Sets the Broadcast Packet Rate Limit
+ *
+ * \param baseAddr Base Address of the ALE module
+ * \param bplVal The Broadcast Packet Rate Limit Value
+ *
+ * \return None
+ *
+ **/
+void CPSWALEBroadcastRateLimitSet(unsigned int baseAddr, unsigned int portNum,
+ unsigned int bplVal)
+{
+ HWREG(baseAddr + CPSW_ALE_PORTCTL(portNum)) &=
+ ~CPSW_ALE_PORTCTL0_BCAST_LIMIT;
+ HWREG(baseAddr + CPSW_ALE_PORTCTL(portNum)) |=
+ (bplVal << CPSW_ALE_PORTCTL0_BCAST_LIMIT_SHIFT);
+}
+
+/**
+ * \brief Sets the Multicast Packet Rate Limit
+ *
+ * \param baseAddr Base Address of the ALE module
+ * \param mplVal The Multicast Packet Rate Limit Value
+ *
+ * \return None
+ *
+ **/
+void CPSWALEMulticastRateLimitSet(unsigned int baseAddr, unsigned int portNum,
+ unsigned int mplVal)
+{
+ HWREG(baseAddr + CPSW_ALE_PORTCTL(portNum)) &=
+ ~CPSW_ALE_PORTCTL0_MCAST_LIMIT;
+ HWREG(baseAddr + CPSW_ALE_PORTCTL(portNum)) |=
+ (mplVal << CPSW_ALE_PORTCTL0_MCAST_LIMIT_SHIFT);
+}
+
+/**
+ * \brief VLAN ID Ingress Check
+ *
+ * \param baseAddr Base Address of the ALE module
+ *
+ * \return None
+ *
+ **/
+void CPSWALEVIDIngressCheckSet(unsigned int baseAddr, unsigned int portNum)
+{
+ HWREG(baseAddr + CPSW_ALE_PORTCTL(portNum)) |=
+ CPSW_ALE_PORTCTL0_MCAST_LIMIT;
+}
+
+/**
+ * \brief Sets the port state in the ALE for a given port
+ *
+ * \param baseAddr Base address of the ALE module
+ * \param portNum The port number
+ * \param portState The port state to be set
+ * 'portState' can take one of the below values \n
+ * CPSW_ALE_PORT_STATE_FWD - ALE state is Forward \n
+ * CPSW_ALE_PORT_STATE_LEARN - ALE state is Learn \n
+ * CPSW_ALE_PORT_STATE_BLOCKED - ALE state is Blocked \n
+ * CPSW_ALE_PORT_STATE_DISABLED - ALE state is Disabled
+ *
+ * \return None
+ **/
+void CPSWALEPortStateSet(unsigned int baseAddr, unsigned int portNum,
+ unsigned int portState)
+{
+ HWREG(baseAddr + CPSW_ALE_PORTCTL(portNum)) &=
+ ~CPSW_ALE_PORTCTL0_PORT_STATE;
+
+ HWREG(baseAddr + CPSW_ALE_PORTCTL(portNum)) |= portState;
+}
+
+/**
+ * \brief Sets VLAN Aware mode for ALE to Flood if VLAN not found
+ *
+ * \param baseAddr Base address of the ALE Module
+ *
+ * \return None
+ **/
+void CPSWALEVLANAwareSet(unsigned int baseAddr)
+{
+ HWREG(baseAddr + CPSW_ALE_CONTROL) |= CPSW_ALE_CONTROL_ALE_VLAN_AWARE;
+}
+
+/**
+ * \brief Clears VLAN Aware mode for ALE to drop packets
+ *
+ * \param baseAddr Base address of the ALE Module
+ *
+ * \return None
+ **/
+void CPSWALEVLANAwareClear(unsigned int baseAddr)
+{
+ HWREG(baseAddr + CPSW_ALE_CONTROL) &= ~CPSW_ALE_CONTROL_ALE_VLAN_AWARE;
+}
+
+/**
+ * \brief Configure Rate Limit to TX Mode
+ *
+ * \param baseAddr Base address of the ALE Module
+ *
+ * \return None
+ **/
+void CPSWALERateLimitTXMode(unsigned int baseAddr)
+{
+ HWREG(baseAddr + CPSW_ALE_CONTROL) |= CPSW_ALE_CONTROL_RATE_LIMIT_TX;
+}
+
+/**
+ * \brief Configure Rate Limit to RX Mode
+ *
+ * \param baseAddr Base address of the ALE Module
+ *
+ * \return None
+ **/
+void CPSWALERateLimitRXMode(unsigned int baseAddr)
+{
+ HWREG(baseAddr + CPSW_ALE_CONTROL) &= ~CPSW_ALE_CONTROL_RATE_LIMIT_TX;
+}
+
+/**
+ * \brief Enable Rate Limit for ALE
+ *
+ * \param baseAddr Base address of the ALE Module
+ *
+ * \return None
+ **/
+void CPSWALERateLimitEnable(unsigned int baseAddr)
+{
+ HWREG(baseAddr + CPSW_ALE_CONTROL) |= CPSW_ALE_CONTROL_ENABLE_RATE_LIMIT;
+}
+
+/**
+ * \brief Disable Rate Limit for ALE
+ *
+ * \param baseAddr Base address of the ALE Module
+ *
+ * \return None
+ **/
+void CPSWALERateLimitDisable(unsigned int baseAddr)
+{
+ HWREG(baseAddr + CPSW_ALE_CONTROL) &= ~CPSW_ALE_CONTROL_ENABLE_RATE_LIMIT;
+}
+
+/**
+ * \brief Enable MAC Authorization Mode for ALE
+ *
+ * \param baseAddr Base address of the ALE Module
+ *
+ * \return None
+ **/
+void CPSWALEAUTHModeSet(unsigned int baseAddr)
+{
+ HWREG(baseAddr + CPSW_ALE_CONTROL) |= CPSW_ALE_CONTROL_ENABLE_AUTH_MODE;
+}
+
+/**
+ * \brief Disable MAC Authorization Mode for ALE
+ *
+ * \param baseAddr Base address of the ALE Module
+ *
+ * \return None
+ **/
+void CPSWALEAUTHModeClear(unsigned int baseAddr)
+{
+ HWREG(baseAddr + CPSW_ALE_CONTROL) &= ~CPSW_ALE_CONTROL_ENABLE_AUTH_MODE;
+}
+
+/**
+ * \brief Sets an ALE table entry
+ *
+ * \param baseAddr Base address of the ALE Module
+ * \param aleTblIdx The Index of the table entry
+ * \param aleEntryPtr The address of the entry to be set
+ *
+ * \return None
+ **/
+void CPSWALETableEntrySet(unsigned int baseAddr, unsigned int aleTblIdx,
+ unsigned int *aleEntryPtr)
+{
+ unsigned int cnt;
+
+ for (cnt = 0; cnt < ALE_ENTRY_WORDS; cnt++)
+ {
+ HWREG(baseAddr + CPSW_ALE_TBLW(cnt)) = *(aleEntryPtr + cnt);
+ }
+
+ HWREG(baseAddr + CPSW_ALE_TBLCTL) =
+ aleTblIdx | CPSW_ALE_TBLCTL_WRITE_RDZ;
+}
+
+/**
+ * \brief Returns an ALE table entry
+ *
+ * \param baseAddr Base address of the ALE Module
+ * \param aleTblIdx The Index of the table entry
+ * \param aleEntryPtr The address where the ALE entry to be written
+ *
+ * \return None
+ **/
+void CPSWALETableEntryGet(unsigned int baseAddr, unsigned int aleTblIdx,
+ unsigned int *aleEntryPtr)
+{
+ unsigned int cnt;
+
+ HWREG(baseAddr + CPSW_ALE_TBLCTL) = aleTblIdx;
+
+ for (cnt = 0; cnt < ALE_ENTRY_WORDS; cnt++)
+ {
+ *(aleEntryPtr + cnt) = HWREG(baseAddr + CPSW_ALE_TBLW(cnt));
+ }
+}
+
+/**
+ * \brief Returns the prescale value for ALE. The input clock is divided
+ * by this value to use in the broadcast/multicast rate limiters.
+ *
+ * \param baseAddr Base Address of the ALE module
+ *
+ * \return Prescale value
+ *
+ **/
+unsigned int CPSWALEPrescaleGet(unsigned int baseAddr)
+{
+ return (HWREG(baseAddr + CPSW_ALE_PRESCALE)
+ & CPSW_ALE_PRESCALE_ALE_PRESCALE);
+}
+
+/**
+ * \brief Sets the prescale value for ALE. The input clock is divided
+ * by this value to use in the broadcast/multicast rate limiters.
+ *
+ * \param baseAddr Base Address of the ALE module
+ * \param psVal The prescale value
+ *
+ * \return None
+ *
+ **/
+void CPSWALEPrescaleSet(unsigned int baseAddr, unsigned int psVal)
+{
+ HWREG(baseAddr + CPSW_ALE_PRESCALE) |= psVal
+ & CPSW_ALE_PRESCALE_ALE_PRESCALE ;
+}
+
+/**
+ * \brief Sets the Unknown VLAN Force Untagged Egress
+ *
+ * \param baseAddr Base Address of the ALE module
+ * \param ueVal The Unknown VLAN Fornce Untagged Egress value
+ *
+ * \return None
+ *
+ **/
+void CPSWALEUnknownUntaggedEgressSet(unsigned int baseAddr, unsigned int ueVal)
+{
+ HWREG(baseAddr + CPSW_ALE_UNKNOWN_VLAN) &=
+ ~CPSW_ALE_UNKNOWN_VLAN_UNKNOWN_FORCE_UNTA;
+ HWREG(baseAddr + CPSW_ALE_UNKNOWN_VLAN) |=
+ (ueVal << CPSW_ALE_UNKNOWN_VLAN_UNKNOWN_FORCE_UNTA_SHIFT);
+}
+
+/**
+ * \brief Sets the Unknown VLAN Registered Multicast Flood Mask
+ *
+ * \param baseAddr Base Address of the ALE module
+ * \param rfmVal Unknown VLAN Registered Multicast Flood Mask Value
+ *
+ * \return None
+ *
+ **/
+void CPSWALEUnknownRegFloodMaskSet(unsigned int baseAddr, unsigned int rfmVal)
+{
+ HWREG(baseAddr + CPSW_ALE_UNKNOWN_VLAN) &=
+ ~CPSW_ALE_UNKNOWN_VLAN_UNKNOWN_MCAST_FLO;
+ HWREG(baseAddr + CPSW_ALE_UNKNOWN_VLAN) |=
+ (rfmVal << CPSW_ALE_UNKNOWN_VLAN_UNKNOWN_MCAST_FLO_SHIFT);
+}
+
+/**
+ * \brief Sets the Unknown VLAN UnRegistered Multicast Flood Mask
+ *
+ * \param baseAddr Base Address of the ALE module
+ * \param ufmVal Unknown VLAN UnRegistered Multicast Flood Mask Value
+ *
+ * \return None
+ *
+ **/
+void CPSWALEUnknownUnRegFloodMaskSet(unsigned int baseAddr, unsigned int ufmVal)
+{
+ HWREG(baseAddr + CPSW_ALE_UNKNOWN_VLAN) &=
+ ~CPSW_ALE_UNKNOWN_VLAN_UNKNOWN_REG_MCAST;
+ HWREG(baseAddr + CPSW_ALE_UNKNOWN_VLAN) |=
+ (ufmVal << CPSW_ALE_UNKNOWN_VLAN_UNKNOWN_REG_MCAST_SHIFT);
+}
+
+/**
+ * \brief Sets the Unknown VLAN Member List
+ *
+ * \param baseAddr Base Address of the ALE module
+ * \param mlVal Unknown VLAN UnRegistered Multicast Flood Mask Value
+ *
+ * \return None
+ *
+ **/
+void CPSWALEUnknownMemberListSet(unsigned int baseAddr, unsigned int mlVal)
+{
+ HWREG(baseAddr + CPSW_ALE_UNKNOWN_VLAN) &=
+ ~CPSW_ALE_UNKNOWN_VLAN_UNKNOWN_VLAN_MEM;
+ HWREG(baseAddr + CPSW_ALE_UNKNOWN_VLAN) |=
+ (mlVal << CPSW_ALE_UNKNOWN_VLAN_UNKNOWN_VLAN_MEM_SHIFT);
+}
+
+/**
+ * \brief Enables the bypassing of the ALE logic
+ *
+ * \param baseAddr Base Address of the ALE module
+ *
+ * \return None
+ *
+ **/
+void CPSWALEBypassEnable(unsigned int baseAddr)
+{
+ HWREG(baseAddr + CPSW_ALE_CONTROL) |= CPSW_ALE_CONTROL_ALE_BYPASS;
+}
+
+/**
+ * \brief Disables the bypassing of the ALE logic
+ *
+ * \param baseAddr Base Address of the ALE module
+ *
+ * \return None
+ *
+ **/
+void CPSWALEBypassDisable(unsigned int baseAddr)
+{
+ HWREG(baseAddr + CPSW_ALE_CONTROL) &= ~CPSW_ALE_CONTROL_ALE_BYPASS;
+}
+
+/**
+ * \brief Enables the receive flow control for CPSW for a given port
+ *
+ * \param baseAddr Base Address of the CPSW subsystem
+ * \param portNum The port number
+ *
+ * \return None
+ *
+ **/
+void CPSWRxFlowControlEnable(unsigned int baseAddr, unsigned int portNum)
+{
+ HWREG(baseAddr + CPSW_SS_FLOW_CONTROL) |= (1 << portNum);
+}
+
+/**
+ * \brief Disables the receive flow control for CPSW for a given port
+ *
+ * \param baseAddr Base Address of the CPSW subsystem
+ * \param portNum The port number
+ *
+ * \return None
+ *
+ **/
+void CPSWRxFlowControlDisable(unsigned int baseAddr, unsigned int portNum)
+{
+ HWREG(baseAddr + CPSW_SS_FLOW_CONTROL) &= ~(1 << portNum);
+}
+
+/**
+ * \brief Enables the software idle mode, causing the switch fabric to stop
+ * forward packets at the next start of packet.
+ *
+ * \param baseAddr Base Address of the CPSW subsystem
+ *
+ * \return None
+ *
+ **/
+void CPSWSoftwareIdleEnable(unsigned int baseAddr)
+{
+ HWREG(baseAddr + CPSW_SS_SOFT_IDLE) |= CPSW_SS_SOFT_IDLE_SOFT_IDLE;
+}
+
+/**
+ * \brief Disables the software idle mode, causing the switch fabric to
+ * forward packets at the next start of packet.
+ *
+ * \param baseAddr Base Address of the CPSW subsystem
+ *
+ * \return None
+ *
+ **/
+void CPSWSoftwareIdleDisable(unsigned int baseAddr, unsigned int portNum)
+{
+ (void) portNum;
+ HWREG(baseAddr + CPSW_SS_SOFT_IDLE) &= ~CPSW_SS_SOFT_IDLE_SOFT_IDLE;
+}
+
+/**
+ * \brief Enables the CPSW statistics for the given port
+ *
+ * \param baseAddr Base Address of the CPSW subsystem
+ * \param portNum The port number
+ *
+ * \return None
+ *
+ **/
+void CPSWStatisticsEnable(unsigned int baseAddr)
+{
+ HWREG(baseAddr + CPSW_SS_STAT_PORT_EN) = CPSW_SS_STAT_PORT_EN_P0_STAT_EN
+ | CPSW_SS_STAT_PORT_EN_P1_STAT_EN
+ | CPSW_SS_STAT_PORT_EN_P2_STAT_EN;
+}
+
+/**
+ * \brief Enables the VLAN aware mode for CPSW
+ *
+ * \param baseAddr Base Address of the CPSW subsystem
+ *
+ * \return None
+ *
+ **/
+void CPSWVLANAwareEnable(unsigned int baseAddr)
+{
+ HWREG(baseAddr + CPSW_SS_CONTROL) |= CPSW_SS_CONTROL_VLAN_AWARE;
+}
+
+/**
+ * \brief Disables the VLAN aware mode for CPSW
+ *
+ * \param baseAddr Base Address of the CPSW subsystem
+ *
+ * \return None
+ *
+ **/
+void CPSWVLANAwareDisable(unsigned int baseAddr)
+{
+ HWREG(baseAddr + CPSW_SS_CONTROL) &= ~CPSW_SS_CONTROL_VLAN_AWARE;
+}
+
+/**
+ * \brief Sets the ethernet address at the CPSW port
+ *
+ * \param baseAddr Base address of the CPSW Port Module registers
+ * \param ethAddr Start address of the 6 byte ethernet address
+ *
+ * \return None
+ *
+ **/
+void CPSWPortSrcAddrSet(unsigned int baseAddr, unsigned char *ethAddr)
+{
+
+ HWREG(baseAddr + CPSW_PORT_SA_HI) =
+ ethAddr[0]
+ | (ethAddr[1] << CPSW_PORT_P1_SA_HI_MACSRCADDR_39_32_SHIFT)
+ | (ethAddr[2] << CPSW_PORT_P1_SA_HI_MACSRCADDR_31_24_SHIFT)
+ | (ethAddr[3] << CPSW_PORT_P1_SA_HI_MACSRCADDR_23_16_SHIFT);
+ HWREG(baseAddr + CPSW_PORT_SA_LO) =
+ ethAddr[4]
+ | (ethAddr[5] << CPSW_PORT_P1_SA_LO_MACSRCADDR_7_0_SHIFT);
+}
+
+/**
+ * \brief Sets Dual Mac Mode for CPSW Port0
+ *
+ * \param baseAddr Base address of the CPSW Host Port Module registers
+ *
+ * \return None
+ *
+ **/
+void CPSWHostPortDualMacModeSet(unsigned int baseAddr)
+{
+ HWREG(baseAddr + CPSW_PORT_TX_IN_CTL) &= ~CPSW_PORT_P0_TX_IN_CTL_TX_IN_SEL;
+ HWREG(baseAddr + CPSW_PORT_TX_IN_CTL) |=
+ CPSW_PORT_P0_TX_IN_CTL_TX_IN_DUAL_MAC;
+}
+
+/**
+ * \brief Configures Port VLAN
+ *
+ * \param baseAddr Base address of the CPSW Port Module registers
+ * \param vlanId VLAN ID to be set
+ * \param cfiBit CFI value to be set
+ * \param vlanPri Port VLAN priority
+ * 'vlanId' can take a value from 0 to 0xFFF \n
+ * 'cfiBit' can be either 0 or 1. \n
+ * 'vlanPri' can be any value between and including 0 and 7.
+ *
+ * \return None
+ *
+ **/
+void CPSWPortVLANConfig(unsigned int baseAddr, unsigned int vlanId,
+ unsigned int cfiBit, unsigned int vlanPri)
+{
+ HWREG(baseAddr + CPSW_PORT_PORT_VLAN) = vlanId
+ | (cfiBit << CPSW_PORT_P2_PORT_VLAN_PORT_CFI_SHIFT)
+ | (vlanPri << CPSW_PORT_P2_PORT_VLAN_PORT_PRI_SHIFT);
+}
+
+/**
+ * \brief Returns the requested CPSW Statistics
+ *
+ * \param baseAddr Base address of the CPSW Status Module registers.
+ * \param statReg Statistics Register to be read
+ *
+ * \return The requested statistics
+ *
+ **/
+unsigned int CPSWStatisticsGet(unsigned int baseAddr, unsigned int statReg)
+{
+ return (HWREG(baseAddr + statReg));
+}
+
+/**
+ * \brief Resets the CPDMA
+ *
+ * \param baseAddr Base address of the CPDMA Module registers.
+ *
+ * \return None
+ *
+ **/
+void CPSWCPDMAReset(unsigned int baseAddr)
+{
+ unsigned int cnt;
+
+ /* Reset the CPDMA */
+ HWREG(baseAddr + CPSW_CPDMA_CPDMA_SOFT_RESET) =
+ CPSW_CPDMA_CPDMA_SOFT_RESET_SOFT_RESET;
+
+ /* Wait till the reset completes */
+ while(HWREG(baseAddr + CPSW_CPDMA_CPDMA_SOFT_RESET)
+ & CPSW_CPDMA_CPDMA_SOFT_RESET_SOFT_RESET);
+
+ /* Initialize all the header descriptor pointer registers */
+ for(cnt = 0; cnt< CPSW_MAX_HEADER_DESC; cnt++)
+ {
+ HWREG(baseAddr + CPSW_CPDMA_TX_HDP(cnt)) = 0;
+ HWREG(baseAddr + CPSW_CPDMA_RX_HDP(cnt)) = 0;
+ HWREG(baseAddr + CPSW_CPDMA_TX_CP(cnt)) = 0;
+ HWREG(baseAddr + CPSW_CPDMA_RX_CP(cnt)) = 0;
+ }
+}
+
+/**
+ * \brief Enables the TXPULSE Interrupt Generation.
+ *
+ * \param baseAddr Base address of the CPDMA Module registers.
+ * \param channel Channel number for which interrupt to be enabled
+ *
+ * \return None
+ *
+ **/
+void CPSWCPDMATxIntEnable(unsigned int baseAddr, unsigned int channel)
+{
+ HWREG(baseAddr + CPSW_CPDMA_TX_INTMASK_SET) |= (1 << channel);
+}
+
+/**
+ * \brief Enables the RXPULSE Interrupt Generation.
+ *
+ * \param baseAddr Base address of the CPDMA Module registers.
+ * \param channel Channel number for which interrupt to be enabled
+ *
+ * \return None
+ *
+ **/
+void CPSWCPDMARxIntEnable(unsigned int baseAddr, unsigned int channel)
+{
+ HWREG(baseAddr + CPSW_CPDMA_RX_INTMASK_SET) |= (1 << channel);
+}
+
+/**
+ * \brief Disables the TXPULSE Interrupt Generation.
+ *
+ * \param baseAddr Base address of the CPDMA Module registers.
+ * \param channel Channel number for which interrupt to be disabled
+ *
+ * \return None
+ *
+ **/
+void CPSWCPDMATxIntDisable(unsigned int baseAddr, unsigned int channel)
+{
+ HWREG(baseAddr + CPSW_CPDMA_TX_INTMASK_CLEAR) |= (1 << channel);
+
+}
+
+/**
+ * \brief Disables the RXPULSE Interrupt Generation.
+ *
+ * \param baseAddr Base address of the CPDMA Module registers.
+ * \param channel Channel number for which interrupt to be disabled
+ *
+ * \return None
+ *
+ **/
+void CPSWCPDMARxIntDisable(unsigned int baseAddr, unsigned int channel)
+{
+ HWREG(baseAddr + CPSW_CPDMA_RX_INTMASK_CLEAR) |= (1 << channel);
+
+}
+
+/**
+ * \brief API to enable the transmit in the TX Control Register.
+ * After the transmit is enabled, any write to TXHDP of
+ * a channel will start transmission
+ *
+ * \param baseAddr Base Address of the CPDMA module registers.
+ *
+ * \return None
+ *
+ **/
+void CPSWCPDMATxEnable(unsigned int baseAddr)
+{
+ HWREG(baseAddr + CPSW_CPDMA_TX_CONTROL) = CPSW_CPDMA_TX_CONTROL_TX_EN;
+}
+
+/**
+ * \brief API to enable the receive in the RX Control Register.
+ * After the receive is enabled, and write to RXHDP of
+ * a channel, the data can be received in the destination
+ * specified by the corresponding RX buffer descriptor.
+ *
+ * \param baseAddr Base Address of the CPDMA module registers.
+ *
+ * \return None
+ *
+ **/
+void CPSWCPDMARxEnable(unsigned int baseAddr)
+{
+ HWREG(baseAddr + CPSW_CPDMA_RX_CONTROL) = CPSW_CPDMA_RX_CONTROL_RX_EN;
+}
+
+/**
+ * \brief API to write the TX HDP register. If transmit is enabled,
+ * write to the TX HDP will immediately start transmission.
+ * The data will be taken from the buffer pointer of the TX buffer
+ * descriptor written to the TX HDP
+ *
+ * \param baseAddr Base Address of the CPDMA module registers.
+ * \param descHdr Address of the TX buffer descriptor
+ * \param channel Channel Number
+ *
+ * \return None
+ *
+ **/
+#include <bsp.h>
+void CPSWCPDMATxHdrDescPtrWrite(unsigned int baseAddr, unsigned int descHdr,
+ unsigned int channel)
+{
+ HWREG(baseAddr + CPSW_CPDMA_TX_HDP(channel)) = descHdr;
+}
+
+/**
+ * \brief API to write the RX HDP register. If receive is enabled,
+ * write to the RX HDP will enable data reception to point to
+ * the corresponding RX buffer descriptor's buffer pointer.
+ *
+ * \param baseAddr Base Address of the CPDMA module registers.
+ * \param descHdr Address of the RX buffer descriptor
+ * \param channel Channel Number
+ *
+ * \return None
+ *
+ **/
+void CPSWCPDMARxHdrDescPtrWrite(unsigned int baseAddr, unsigned int descHdr,
+ unsigned int channel)
+{
+ HWREG(baseAddr + CPSW_CPDMA_RX_HDP(channel)) = descHdr;
+}
+
+/**
+ * \brief Writes the DMA End Of Interrupt Vector.
+ *
+ * \param baseAddr Base Address of the CPDMA module registers.
+ * \param eoiFlag Type of interrupt to acknowledge to the CPDMA
+ * 'eoiFlag' can take the following values \n
+ * CPSW_EOI_TX_PULSE - TX Pulse Interrupt \n
+ * CPSW_EOI_RX_PULSE - RX Pulse Interrupt \n
+ * CPSW_EOI_RX_THRESH_PULSE - RX Pulse Threshold Interrupt \n
+ * CPSW_EOI_MISC_PULSE - Misc Interrupt \n
+ *
+ * \return None
+ *
+ **/
+void CPSWCPDMAEndOfIntVectorWrite(unsigned int baseAddr, unsigned int eoiFlag)
+{
+ /* Acknowledge the CPDMA */
+ HWREG(baseAddr + CPSW_CPDMA_CPDMA_EOI_VECTOR) = eoiFlag;
+}
+
+/**
+ * \brief Reads the RX Completion Pointer for a specific channel
+ *
+ * \param baseAddr Base Address of the CPDMA module registers.
+ * \param channel Channel Number.
+ *
+ * \return RX Completion Pointer value.
+ *
+ **/
+unsigned int CPSWCPDMATxCPRead(unsigned int baseAddr, unsigned int channel)
+{
+ return HWREG(baseAddr + CPSW_CPDMA_TX_CP(channel));
+}
+
+/**
+ * \brief Writes the the TX Completion Pointer for a specific channel
+ *
+ * \param baseAddr Base Address of the CPDMA module registers.
+ * \param channel Channel Number.
+ * \param comPtr Completion Pointer Value to be written
+ *
+ * \return None
+ *
+ **/
+void CPSWCPDMATxCPWrite(unsigned int baseAddr, unsigned int channel,
+ unsigned int comPtr)
+{
+ HWREG(baseAddr + CPSW_CPDMA_TX_CP(channel)) = comPtr;
+}
+
+/**
+ * \brief Reads the RX Completion Pointer for a specific channel
+ *
+ * \param baseAddr Base Address of the CPDMA module registers.
+ * \param channel Channel Number.
+ *
+ * \return RX Completion Pointer value.
+ *
+ **/
+unsigned int CPSWCPDMARxCPRead(unsigned int baseAddr, unsigned int channel)
+{
+ return HWREG(baseAddr + CPSW_CPDMA_RX_CP(channel));
+}
+
+/**
+ * \brief Writes the the RX Completion Pointer for a specific channel
+ *
+ * \param baseAddr Base Address of the CPDMA module registers.
+ * \param channel Channel Number.
+ * \param comPtr Completion Pointer Value to be written
+ *
+ * \return None
+ *
+ **/
+void CPSWCPDMARxCPWrite(unsigned int baseAddr, unsigned int channel,
+ unsigned int comPtr)
+{
+ HWREG(baseAddr + CPSW_CPDMA_RX_CP(channel)) = comPtr;
+}
+
+/**
+ * \brief Set the free buffers for a specific channel
+ *
+ * \param baseAddr Base Address of the CPDMA module registers.
+ * \param channel Channel Number.
+ * \param nBuf Number of free buffers
+ *
+ * \return None
+ *
+ **/
+void CPSWCPDMANumFreeBufSet(unsigned int baseAddr, unsigned int channel,
+ unsigned int nBuf)
+{
+ HWREG(baseAddr + CPSW_CPDMA_RX_FREEBUFFER(channel)) = nBuf;
+}
+
+/**
+ * \brief Returns the CPDMA Status.
+ *
+ * \param baseAddr Base Address of the CPDMA module registers.
+ * \param statFlag The status flags to be read
+ * 'statFlag' can take one of the following values \n
+ * CPDMA_STAT_IDLE - to check if CPDMA is idle. \n
+ * CPDMA_STAT_TX_HOST_ERR_CODE - TX host error code. \n
+ * CPDMA_STAT_TX_HOST_ERR_CHAN - TX host error channel. \n
+ * CPDMA_STAT_RX_HOST_ERR_CODE - RX host error code. \n
+ * CPDMA_STAT_RX_HOST_ERR_CHAN - RX host error channel. \n
+ *
+ * \return the DMA status for the status flag passed.
+ * The return values for CPDMA_STAT_IDLE are, \n
+ * CPDMA_STAT_IDLE - CPDMA is in idle state \n
+ * CPDMA_STAT_NOT_IDLE - CPDMA is not in idle state \n
+ *
+ * The return values for CPDMA_STAT_TX_HOST_ERR_CODE are, \n
+ * CPDMA_STAT_TX_NO_ERR - No error \n
+ * CPDMA_STAT_TX_SOP_ERR - SOP error \n
+ * CPDMA_STAT_TX_OWN_ERR - Ownership bit not
+ * set in SOP buffer \n
+ * CPDMA_STAT_TX_ZERO_DESC - Zero Next Buffer
+ * Descriptor Pointer Without EOP \n
+ * CPDMA_STAT_TX_ZERO_BUF_PTR - Zero Buffer Pointer \n
+ * CPDMA_STAT_TX_ZERO_BUF_LEN - Zero Buffer Length \n
+ * CPDMA_STAT_TX_PKT_LEN_ERR - Packet Length Error \n
+ *
+ * The return values for CPDMA_STAT_RX_HOST_ERR_CODE are, \n
+ * CPDMA_STAT_RXi_NO_ERR - No error \n
+ * CPDMA_STAT_RX_OWN_NOT_SET - Ownership bit not set in
+ input buffer \n
+ * CPDMA_STAT_RX_ZERO_BUF_PTR - Zero Buffer Pointer\n
+ * CPDMA_STAT_RX_ZERO_BUF_LEN - Zero Buffer Length on
+ * non-SOP descriptor \n
+ * CPDMA_STAT_RX_SOP_BUF_LEN_ERR - SOP buffer length not
+ * greater than offset\n
+ *
+ **/
+unsigned int CPSWCPDMAStatusGet(unsigned int baseAddr, unsigned int statFlag)
+{
+ return (((HWREG(baseAddr + CPSW_CPDMA_DMASTATUS)) & statFlag)
+ >> (statFlag & CPDMA_ERR_CHANNEL_POS));
+}
+
+/**
+ * \brief Configures the CPDMA module by writing the configuration value
+ * to the DMA control register.
+ *
+ * \param baseAddr Base Address of the CPDMA module registers
+ * \param cfg CPDMA configuration written to control register
+ * 'cfg' shall be CPDMA_CFG(tx_rlim, rx_cef, cmd_idle,
+ * rx_offlen_blk, rx_own, tx_ptype). \n
+ * The parameter 'tx_rlim' to CPDMA_CFG can take one of the below
+ * values, showing which all channels are rate-limited. \n
+ * CPDMA_CFG_TX_RATE_LIM_CH_7 \n
+ * CPDMA_CFG_TX_RATE_LIM_CH_7_TO_6 \n
+ * CPDMA_CFG_TX_RATE_LIM_CH_7_TO_5 \n
+ * CPDMA_CFG_TX_RATE_LIM_CH_7_TO_4 \n
+ * CPDMA_CFG_TX_RATE_LIM_CH_7_TO_3 \n
+ * CPDMA_CFG_TX_RATE_LIM_CH_7_TO_2 \n
+ * CPDMA_CFG_TX_RATE_LIM_CH_7_TO_1 \n
+ * CPDMA_CFG_TX_RATE_LIM_CH_7_TO_0 \n
+ * The parameter 'rx_cef' to CPDMA_CFG can take one of the below
+ * values \n
+ * CPDMA_CFG_COPY_ERR_FRAMES - To copy error frames to memory \n
+ * CPDMA_CFG_NO_COPY_ERR_FRAMES - Not to copy error frames \n
+ * The parameter 'cmd_idle' to CPDMA_CFG can take one of the below
+ * values \n
+ * CPDMA_CFG_IDLE_COMMAND - Idle commanded \n
+ * CPDMA_CFG_IDLE_COMMAND_NONE - Idle not commanded \n
+ * The parameter 'rx_offlen_blk' to CPDMA_CFG can take one of the below
+ * values \n
+ * CPDMA_CFG_BLOCK_RX_OFF_LEN_WRITE - Block the DMA writes to the
+ * offset/length field during
+ * packet processing. \n
+ * CPDMA_CFG_NOT_BLOCK_RX_OFF_LEN_WRITE - Do not Block the DMA writes
+ * to the offset/length field during
+ * packet processing. \n
+ * The parameter 'rx_own' to CPDMA_CFG can take one of the below
+ * values \n
+ * CPDMA_CFG_RX_OWN_1 - The CPDMA writes 1 to the ownership bit at
+ * the end of packet processing. \n
+ * CPDMA_CFG_RX_OWN_0 - The CPDMA writes 0 to the ownership bit at
+ * the end of packet processing. \n
+ * The parameter 'tx_ptype' to CPDMA_CFG can take one of the below
+ * values \n
+ * CPDMA_CFG_TX_PRI_ROUND_ROBIN - The next channel for transmit is
+ * chosen round-robin. \n
+ * CPDMA_CFG_TX_PRI_FIXED - The next channel for transmit is
+ * chosen priority based, channel 7 with the
+ * highest priority \n
+ *
+ * \return None
+ *
+ **/
+void CPSWCPDMAConfig(unsigned int baseAddr, unsigned int cfg)
+{
+ HWREG(baseAddr + CPSW_CPDMA_DMACONTROL) = cfg;
+}
+
+/**
+ * \brief Enable the command idle mode for CPDMA. When this API is called, the
+ * CPSW stops all the reception and transmission. However, if receiving
+ * the current frame will be received completely before going to the idle
+ * state. Also, while transmitting, the contents in the fifo will be sent
+ * fully.
+ *
+ * \param baseAddr Base Address of the CPDMA module registers
+ *
+ * \return None
+ *
+ **/
+void CPSWCPDMACmdIdleEnable(unsigned int baseAddr)
+{
+ HWREG(baseAddr + CPSW_CPDMA_DMACONTROL) |= CPSW_CPDMA_DMACONTROL_CMD_IDLE;
+
+ /* Wait till the state changes to idle */
+ while((HWREG(baseAddr + CPSW_CPDMA_DMASTATUS) & CPSW_CPDMA_DMASTATUS_IDLE)
+ != CPSW_CPDMA_DMASTATUS_IDLE);
+}
+
+/**
+ * \brief Disable the command idle mode for CPDMA.
+ *
+ * \param baseAddr Base Address of the CPDMA module registers
+ *
+ * \return None
+ *
+ **/
+void CPSWCPDMACmdIdleDisable(unsigned int baseAddr)
+{
+ HWREG(baseAddr + CPSW_CPDMA_DMACONTROL) &= ~CPSW_CPDMA_DMACONTROL_CMD_IDLE;
+}
+
+/**
+ * \brief Sets the RX buffer offset value. The RX buffer offset will be
+ * written by the port into each frame SOP buffer descriptor
+ * buffer_offset field. The frame data will begin after the
+ * rx_buffer_offset value of bytes. This value will be used for
+ * all the channels .
+ *
+ * \param baseAddr Base Address of the CPDMA module registers
+ * \param bufOff Buffer offset value
+ *
+ * \return None
+ *
+ **/
+void CPSWCPDMARxBufOffsetSet(unsigned int baseAddr, unsigned int bufOff)
+{
+ HWREG(baseAddr + CPSW_CPDMA_RX_BUFFER_OFFSET) = bufOff;
+}
+
+/**
+ * \brief Returns the raw transmit interrupt pending status.
+ *
+ * \param baseAddr Base Address of the CPDMA module registers
+ * \param chanMask Channel Mask
+ * 'chanMask' can be given for one or more channels. \n
+ * 0x01- for 0th channel, 0x80 for 7th channel, 0x81 for both 0th
+ * and 7th channel etc. \n
+ *
+ * \return Raw receive interrupt status \n
+ * bits for the 'chanMask' will be set if interrupt is pending \n
+ * bits for the 'chanMask' will be clear if interrupt is not
+ * pending \n
+ *
+ **/
+unsigned int CPSWCPDMATxIntStatRawGet(unsigned int baseAddr,
+ unsigned int chanMask)
+{
+ return (HWREG(baseAddr + CPSW_CPDMA_TX_INTSTAT_RAW) & chanMask);
+}
+
+/**
+ * \brief Returns the masked transmit interrupt pending status.
+ *
+ * \param baseAddr Base Address of the CPDMA module registers
+ * \param chanMask Channel Mask
+ * 'chanMask' can be given for one or more channels. \n
+ * 0x01- for 0th channel, 0x80 for 7th channel, 0x81 for both 0th
+ * and 7th channel etc. \n
+ *
+ * \return Masked transmit interrupt status \n
+ * bits for the 'chanMask' will be set if interrupt is pending \n
+ * bits for the 'chanMask' will be cleared if interrupt is not
+ * pending \n
+ *
+ **/
+unsigned int CPSWCPDMATxIntStatMaskedGet(unsigned int baseAddr,
+ unsigned int chanMask)
+{
+ return (HWREG(baseAddr + CPSW_CPDMA_TX_INTSTAT_MASKED) & chanMask);
+}
+
+/**
+ * \brief Returns the raw receive interrupt pending status.
+ *
+ * \param baseAddr Base Address of the CPDMA module registers
+ * \param chanMask Channel Mask
+ * \param intType Interrupt type
+ * 'chanMask' can be given for one or more channels. \n
+ * 0x01- for 0th channel, 0x80 for 7th channel, 0x81 for both 0th
+ * and 7th channel etc. \n
+ * 'intType' can take one of the following values. \n
+ * CPDMA_RX_INT_THRESH_PEND - RX threshold interrupt pending \n
+ * CPDMA_RX_INT_PULSE_PEND - RX pulse interrupt pending \n
+ *
+ * \return Raw receive interrupt status \n
+ * bits for the 'chanMask' will be set if interrupt is pending \n
+ * bits for the 'chanMask' will be cleared if interrupt is not
+ * pending \n
+ *
+ **/
+unsigned int CPSWCPDMARxIntStatRawGet(unsigned int baseAddr,
+ unsigned int chanMask,
+ unsigned int intType)
+{
+ return ((HWREG(baseAddr + CPSW_CPDMA_RX_INTSTAT_RAW) >> intType)
+ & chanMask);
+}
+
+/**
+ * \brief Returns the masked receive interrupt pending status.
+ *
+ * \param baseAddr Base Address of the CPDMA module registers
+ * \param chanMask Channel Mask
+ * \param intType Interrupt type
+ * 'chanMask' can be given for one or more channels. \n
+ * 0x01- for 0th channel, 0x80 for 7th channel, 0x81 for both 0th
+ * and 7th channel etc. \n
+ * 'intType' can take one of the following values. \n
+ * CPDMA_RX_INT_THRESH_PEND - RX threshold interrupt pending \n
+ * CPDMA_RX_INT_PULSE_PEND - RX pulse interrupt pending \n
+ *
+ * \return Masked receive interrupt status \n
+ * bits for the 'chanMask' will be set if interrupt is pending \n
+ * bits for the 'chanMask' will be cleared if interrupt is not
+ * pending \n
+ *
+ **/
+unsigned int CPSWCPDMARxIntStatMaskedGet(unsigned int baseAddr,
+ unsigned int chanMask,
+ unsigned int intType)
+{
+ return ((HWREG(baseAddr + CPSW_CPDMA_RX_INTSTAT_MASKED) >> intType)
+ & chanMask);
+}
+
+/**
+ * \brief Saves the CPSW register context. This can be used while going
+ * to power down mode where CPSW power will be cut down.
+ *
+ * \param contextPtr Pointer to the structure where CPSW register context
+ * need to be saved.
+ *
+ * \return None
+ *
+ **/
+void CPSWContextSave(CPSWCONTEXT *contextPtr)
+{
+ unsigned int idx;
+ unsigned int *cppiDest = (unsigned int*)contextPtr->cppiRamBase;
+
+ CPSWCPDMACmdIdleEnable(contextPtr->cpdmaBase);
+
+ /* Restore the CPPI RAM contents */
+ for(idx = 0; idx < (CPSW_SIZE_CPPI_RAM / 4); idx++, cppiDest++)
+ {
+ contextPtr->cppiRam[idx] = *cppiDest;
+ }
+
+ contextPtr->aleCtrl = HWREG(contextPtr->aleBase + CPSW_ALE_CONTROL);
+ contextPtr->alePortCtl[0] = HWREG(contextPtr->aleBase + CPSW_ALE_PORTCTL(0));
+ contextPtr->alePortCtl[1] = HWREG(contextPtr->aleBase + CPSW_ALE_PORTCTL(1));
+ contextPtr->alePortCtl[2] = HWREG(contextPtr->aleBase + CPSW_ALE_PORTCTL(2));
+
+ for(idx = 0; idx < CPSW_MAX_NUM_ALE_ENTRY; idx++)
+ {
+ CPSWALETableEntryGet(contextPtr->aleBase, idx,
+ &(contextPtr->aleEntry[idx * 3]));
+ }
+
+ contextPtr->ssStatPortEn = HWREG(contextPtr->ssBase + CPSW_SS_STAT_PORT_EN);
+ contextPtr->port1SaHi = HWREG(contextPtr->port1Base + CPSW_PORT_SA_HI);
+ contextPtr->port1SaLo = HWREG(contextPtr->port1Base + CPSW_PORT_SA_LO);
+ contextPtr->port2SaHi = HWREG(contextPtr->port2Base + CPSW_PORT_SA_HI);
+ contextPtr->port2SaLo = HWREG(contextPtr->port2Base + CPSW_PORT_SA_LO);
+ contextPtr->port1TxInCtl = HWREG(contextPtr->port1Base + CPSW_PORT_TX_IN_CTL);
+ contextPtr->port2TxInCtl = HWREG(contextPtr->port2Base + CPSW_PORT_TX_IN_CTL);
+ contextPtr->port1Vlan = HWREG(contextPtr->port1Base + CPSW_PORT_PORT_VLAN);
+ contextPtr->port2Vlan = HWREG(contextPtr->port2Base + CPSW_PORT_PORT_VLAN);
+ contextPtr->cpdmaRxFB = HWREG(contextPtr->cpdmaBase
+ + CPSW_CPDMA_RX_FREEBUFFER(0));
+ contextPtr->cpdmaTxCtl = HWREG(contextPtr->cpdmaBase
+ + CPSW_CPDMA_TX_CONTROL);
+ contextPtr->cpdmaRxCtl = HWREG(contextPtr->cpdmaBase
+ + CPSW_CPDMA_RX_CONTROL);
+ contextPtr->cpdmaRxHdp = HWREG(contextPtr->cpdmaBase
+ + CPSW_CPDMA_RX_HDP(0));
+ contextPtr->txIntMaskSet = HWREG(contextPtr->cpdmaBase
+ + CPSW_CPDMA_TX_INTMASK_SET);
+ contextPtr->wrCoreIntTxPulse = HWREG(contextPtr->wrBase
+ + CPSW_WR_C_RX_THRESH_EN(0) + 0x04);
+ contextPtr->rxIntMaskSet = HWREG(contextPtr->cpdmaBase
+ + CPSW_CPDMA_RX_INTMASK_SET);
+ contextPtr->wrCoreIntRxPulse = HWREG(contextPtr->wrBase
+ + CPSW_WR_C_RX_THRESH_EN(0) + 0x08);
+ contextPtr->sl1MacCtl = HWREG(contextPtr->sl1Base + CPSW_SL_MACCONTROL);
+ contextPtr->sl2MacCtl = HWREG(contextPtr->sl2Base + CPSW_SL_MACCONTROL);
+}
+
+/**
+ * \brief Restores the CPSW register context. This can be used while coming
+ * back from power down mode where CPSW power will be cut down.
+ *
+ * \param contextPtr Pointer to the structure where CPSW register context
+ * need to be restored from.
+ *
+ * \return None
+ *
+ **/
+void CPSWContextRestore(CPSWCONTEXT *contextPtr)
+{
+ unsigned int idx;
+ unsigned int *cppiDest = (unsigned int*)contextPtr->cppiRamBase;
+
+ /* Restore the CPPI RAM contents */
+ for(idx = 0; idx < (CPSW_SIZE_CPPI_RAM / 4); idx++, cppiDest++)
+ {
+ *cppiDest = contextPtr->cppiRam[idx] ;
+ }
+
+ HWREG(contextPtr->aleBase + CPSW_ALE_CONTROL) = contextPtr->aleCtrl;
+ HWREG(contextPtr->aleBase + CPSW_ALE_PORTCTL(0)) = contextPtr->alePortCtl[0];
+ HWREG(contextPtr->aleBase + CPSW_ALE_PORTCTL(1)) = contextPtr->alePortCtl[1];
+ HWREG(contextPtr->aleBase + CPSW_ALE_PORTCTL(2)) = contextPtr->alePortCtl[2];
+
+ for(idx = 0; idx < CPSW_MAX_NUM_ALE_ENTRY; idx++)
+ {
+ CPSWALETableEntrySet(contextPtr->aleBase, idx,
+ &(contextPtr->aleEntry[idx * 3]));
+ }
+
+ HWREG(contextPtr->ssBase + CPSW_SS_STAT_PORT_EN) = contextPtr->ssStatPortEn;
+ HWREG(contextPtr->port1Base + CPSW_PORT_SA_HI) = contextPtr->port1SaHi;
+ HWREG(contextPtr->port1Base + CPSW_PORT_SA_LO) = contextPtr->port1SaLo;
+ HWREG(contextPtr->port2Base + CPSW_PORT_SA_HI) = contextPtr->port2SaHi;
+ HWREG(contextPtr->port2Base + CPSW_PORT_SA_LO) = contextPtr->port2SaLo;
+ HWREG(contextPtr->port1Base + CPSW_PORT_TX_IN_CTL) = contextPtr->port1TxInCtl;
+ HWREG(contextPtr->port2Base + CPSW_PORT_TX_IN_CTL) = contextPtr->port2TxInCtl;
+ HWREG(contextPtr->port1Base + CPSW_PORT_PORT_VLAN) = contextPtr->port1Vlan;
+ HWREG(contextPtr->port2Base + CPSW_PORT_PORT_VLAN) = contextPtr->port2Vlan;
+ HWREG(contextPtr->cpdmaBase + CPSW_CPDMA_RX_FREEBUFFER(0)) =
+ contextPtr->cpdmaRxFB;
+ HWREG(contextPtr->cpdmaBase + CPSW_CPDMA_TX_CONTROL)
+ = contextPtr->cpdmaTxCtl;
+ HWREG(contextPtr->cpdmaBase + CPSW_CPDMA_RX_CONTROL)
+ = contextPtr->cpdmaRxCtl;
+ HWREG(contextPtr->cpdmaBase + CPSW_CPDMA_RX_HDP(0))
+ = contextPtr->cpdmaRxHdp;
+ HWREG(contextPtr->cpdmaBase + CPSW_CPDMA_TX_INTMASK_SET)
+ = contextPtr->txIntMaskSet;
+ HWREG(contextPtr->wrBase + CPSW_WR_C_RX_THRESH_EN(0) + 0x04)
+ = contextPtr->wrCoreIntTxPulse;
+ HWREG(contextPtr->cpdmaBase + CPSW_CPDMA_RX_INTMASK_SET)
+ = contextPtr->rxIntMaskSet;
+ HWREG(contextPtr->wrBase + CPSW_WR_C_RX_THRESH_EN(0) + 0x08)
+ = contextPtr->wrCoreIntRxPulse;
+ HWREG(contextPtr->sl1Base + CPSW_SL_MACCONTROL) = contextPtr->sl1MacCtl;
+ HWREG(contextPtr->sl2Base + CPSW_SL_MACCONTROL) = contextPtr->sl2MacCtl;
+}
+
+