diff options
Diffstat (limited to 'cpsw/src/netif/cpsw.c')
-rwxr-xr-x | cpsw/src/netif/cpsw.c | 1545 |
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; +} + + |