
This patch updates the copy right to 2015. Signed-off-by: Kedareswara rao Appana <appanad@xilinx.com>
1713 lines
54 KiB
C
Executable file
1713 lines
54 KiB
C
Executable file
/******************************************************************************
|
|
*
|
|
* Copyright (C) 2010 - 2015 Xilinx, Inc. All rights reserved.
|
|
*
|
|
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
* of this software and associated documentation files (the "Software"), to deal
|
|
* in the Software without restriction, including without limitation the rights
|
|
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
* copies of the Software, and to permit persons to whom the Software is
|
|
* furnished to do so, subject to the following conditions:
|
|
*
|
|
* The above copyright notice and this permission notice shall be included in
|
|
* all copies or substantial portions of the Software.
|
|
*
|
|
* Use of the Software is limited solely to applications:
|
|
* (a) running on a Xilinx device, or
|
|
* (b) that interact with a Xilinx device through a bus or interconnect.
|
|
*
|
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
* XILINX CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
|
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
|
|
* OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
* SOFTWARE.
|
|
*
|
|
* Except as contained in this notice, the name of the Xilinx shall not be used
|
|
* in advertising or otherwise to promote the sale, use or other dealings in
|
|
* this Software without prior written authorization from Xilinx.
|
|
*
|
|
******************************************************************************/
|
|
/**
|
|
*
|
|
* @file xaxiethernet_control.c
|
|
*
|
|
* This file has driver APIs related to the controlling of the extended
|
|
* features of the AXI Ethernet device. Please note that APIs for turning on/off
|
|
* any of the driver features are present in axiethernet.c. This file takes care
|
|
* of controlling these features.
|
|
* - Normal/extended multicast filtering
|
|
* - Normal/extended VLAN features
|
|
* - RGMII/SGMII features
|
|
*
|
|
* See xaxiethernet.h for a detailed description of the driver.
|
|
*
|
|
* <pre>
|
|
* MODIFICATION HISTORY:
|
|
*
|
|
* Ver Who Date Changes
|
|
* ----- ---- -------- -------------------------------------------------------
|
|
* 1.00a asa 6/30/10 First release based on the ll temac driver
|
|
* </pre>
|
|
*****************************************************************************/
|
|
|
|
/***************************** Include Files *********************************/
|
|
|
|
#include "xaxiethernet.h"
|
|
|
|
/************************** Constant Definitions *****************************/
|
|
|
|
|
|
/**************************** Type Definitions *******************************/
|
|
|
|
|
|
/***************** Macros (Inline Functions) Definitions *********************/
|
|
|
|
|
|
/************************** Function Prototypes ******************************/
|
|
|
|
|
|
/************************** Variable Definitions *****************************/
|
|
|
|
/*****************************************************************************/
|
|
/**
|
|
* XAxiEthernet_MulticastAdd adds the Ethernet address, <i>AddressPtr</i> to the
|
|
* Axi Ethernet device's multicast filter list, at list index <i>Entry</i>. The
|
|
* address referenced by <i>AddressPtr</i> may be of any unicast, multicast, or
|
|
* broadcast address form. The hardware for the Axi Ethernet device can hold up
|
|
* to XAE_MULTI_MAT_ENTRIES addresses in this filter list.<br><br>
|
|
*
|
|
* The device must be stopped to use this function.<br><br>
|
|
*
|
|
* Once an Ethernet address is programmed, the Axi Ethernet device will begin
|
|
* receiving data sent from that address. The Axi Ethernet hardware does not
|
|
* have a control bit to disable multicast filtering. The only way to prevent
|
|
* the Axi Ethernet device from receiving messages from an Ethernet address in
|
|
* the Multicast Address Table (MAT) is to clear it with
|
|
* XAxiEthernet_MulticastClear().
|
|
*
|
|
* @param InstancePtr is a pointer to the Axi Ethernet instance to be
|
|
* worked on.
|
|
* @param AddressPtr is a pointer to the 6-byte Ethernet address to set.
|
|
* The previous address at the location <i>Entry</i> (if any) is
|
|
* overwritten with the value at <i>AddressPtr</i>.
|
|
* @param Entry is the hardware storage location to program this address
|
|
* and must be between 0 to (XAE_MULTI_MAT_ENTRIES - 1).
|
|
*
|
|
* @return
|
|
* - XST_SUCCESS on successful completion.
|
|
* - XST_DEVICE_IS_STARTED.if the Axi Ethernet device is not
|
|
* stopped.
|
|
*
|
|
* @note
|
|
*
|
|
* This routine works only with normal multicast filtering feature. A maximum
|
|
* of 4 multicast addresses can be stored in the HW provided multicast table.
|
|
*
|
|
* To use the extended multicast feature, extended multicast filtering must
|
|
* be enabled by using driver API XAxiEthernet_SetOptions with proper option
|
|
* fields set. Once extended multicast filtering is enabled, the APIs
|
|
* XAxiEthernet_[Add|Clear|Get]ExtMulticastGroup() must be used to manage
|
|
* multicast address groups.
|
|
*
|
|
******************************************************************************/
|
|
int XAxiEthernet_MulticastAdd(XAxiEthernet *InstancePtr, void *AddressPtr,
|
|
int Entry)
|
|
{
|
|
u32 Af0Reg;
|
|
u32 Af1Reg;
|
|
u32 FmiReg;
|
|
u8 *Aptr = (u8 *) AddressPtr;
|
|
|
|
Xil_AssertNonvoid(InstancePtr != NULL);
|
|
Xil_AssertNonvoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY);
|
|
Xil_AssertNonvoid(AddressPtr != NULL);
|
|
Xil_AssertNonvoid(Entry < XAE_MULTI_MAT_ENTRIES);
|
|
|
|
|
|
xdbg_printf(XDBG_DEBUG_GENERAL, "XAxiEthernet_MulticastAdd\n");
|
|
|
|
/* The device must be stopped before clearing the multicast hash
|
|
* table.
|
|
*/
|
|
if (InstancePtr->IsStarted == XIL_COMPONENT_IS_STARTED) {
|
|
xdbg_printf(XDBG_DEBUG_GENERAL,
|
|
"XAxiEthernet_MulticastAdd: returning DEVICE_IS_STARTED\n");
|
|
return (XST_DEVICE_IS_STARTED);
|
|
}
|
|
|
|
/* Set MAC bits [31:0] */
|
|
Af0Reg = Aptr[0];
|
|
Af0Reg |= Aptr[1] << 8;
|
|
Af0Reg |= Aptr[2] << 16;
|
|
Af0Reg |= Aptr[3] << 24;
|
|
|
|
/* Set MAC bits [47:32] */
|
|
Af1Reg = Aptr[4];
|
|
Af1Reg |= Aptr[5] << 8;
|
|
|
|
|
|
FmiReg = XAxiEthernet_ReadReg(InstancePtr->Config.BaseAddress,
|
|
XAE_FMI_OFFSET);
|
|
FmiReg &= 0xFFFFFF00;
|
|
FmiReg |= (Entry);
|
|
XAxiEthernet_WriteReg(InstancePtr->Config.BaseAddress,
|
|
XAE_FMI_OFFSET, FmiReg);
|
|
|
|
/* Add in MAT address */
|
|
xdbg_printf(XDBG_DEBUG_GENERAL, "Setting MAT entry: %d\n", Entry);
|
|
XAxiEthernet_WriteReg(InstancePtr->Config.BaseAddress,
|
|
XAE_AF0_OFFSET, Af0Reg);
|
|
|
|
XAxiEthernet_WriteReg(InstancePtr->Config.BaseAddress,
|
|
XAE_AF1_OFFSET, Af1Reg);
|
|
|
|
return (XST_SUCCESS);
|
|
}
|
|
|
|
|
|
/*****************************************************************************/
|
|
/**
|
|
* XAxiEthernet_MulticastGet gets the Ethernet address stored at
|
|
* index <i>Entry</i> in the Axi Ethernet device's multicast filter list.<br><br>
|
|
*
|
|
* @param InstancePtr is a pointer to the Axi Ethernet instance to be
|
|
* worked on.
|
|
* @param AddressPtr references the memory buffer to store the retrieved
|
|
* Ethernet address. This memory buffer must be at least 6 bytes
|
|
* in length.
|
|
* @param Entry is the hardware storage location from which to retrieve
|
|
* the address and must be between 0 to (XAE_MULTI_MAT_ENTRIES - 1)
|
|
*
|
|
* @return None.
|
|
*
|
|
* @note
|
|
*
|
|
* This routine works only with normal multicast filtering feature. A maximum
|
|
* of 4 multicast addresses can be stored in the HW provided multicast table.
|
|
*
|
|
* To use the extended multicast feature, extended multicast filtering must
|
|
* be enabled by using driver API XAxiEthernet_SetOptions with proper option
|
|
* fields set. Once extended multicast filtering is enabled, the APIs
|
|
* XAxiEthernet_[Add|Clear|Get]ExtMulticastGroup() must be used to manage
|
|
* multicast address groups.
|
|
*
|
|
******************************************************************************/
|
|
void XAxiEthernet_MulticastGet(XAxiEthernet *InstancePtr, void *AddressPtr,
|
|
int Entry)
|
|
{
|
|
u32 Af0Reg;
|
|
u32 Af1Reg;
|
|
u32 FmiReg;
|
|
u8 *Aptr = (u8 *) AddressPtr;
|
|
|
|
Xil_AssertVoid(InstancePtr != NULL);
|
|
Xil_AssertVoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY);
|
|
Xil_AssertVoid(AddressPtr != NULL);
|
|
Xil_AssertVoid(Entry < XAE_MULTI_MAT_ENTRIES);
|
|
|
|
xdbg_printf(XDBG_DEBUG_GENERAL, "XAxiEthernet_MulticastGet\n");
|
|
|
|
|
|
FmiReg = XAxiEthernet_ReadReg(InstancePtr->Config.BaseAddress,
|
|
XAE_FMI_OFFSET);
|
|
FmiReg &= 0xFFFFFF00;
|
|
FmiReg |= (Entry);
|
|
XAxiEthernet_WriteReg(InstancePtr->Config.BaseAddress,
|
|
XAE_FMI_OFFSET, FmiReg);
|
|
|
|
|
|
Af0Reg = XAxiEthernet_ReadReg(InstancePtr->Config.BaseAddress,
|
|
XAE_AF0_OFFSET);
|
|
Af1Reg = XAxiEthernet_ReadReg(InstancePtr->Config.BaseAddress,
|
|
XAE_AF1_OFFSET);
|
|
|
|
/* Copy the address to the user buffer */
|
|
Aptr[0] = (u8) Af0Reg;
|
|
Aptr[1] = (u8) (Af0Reg >> 8);
|
|
Aptr[2] = (u8) (Af0Reg >> 16);
|
|
Aptr[3] = (u8) (Af0Reg >> 24);
|
|
Aptr[4] = (u8) Af1Reg;
|
|
Aptr[5] = (u8) (Af1Reg >> 8);
|
|
|
|
xdbg_printf(XDBG_DEBUG_GENERAL, "XAxiEthernet_MulticastGet: done\n");
|
|
}
|
|
|
|
/*****************************************************************************/
|
|
/**
|
|
* XAxiEthernet_MulticastClear clears the Ethernet address stored at index
|
|
* <i>Entry</i> in the Axi Ethernet device's multicast filter list.<br><br>
|
|
*
|
|
* The device must be stopped to use this function.<br><br>
|
|
*
|
|
* @param InstancePtr is a pointer to the Axi Ethernet instance to be
|
|
* worked on.
|
|
* @param Entry is the HW storage location used when this address was
|
|
* added. It must be between 0 to (XAE_MULTI_MAT_ENTRIES - 1).
|
|
*
|
|
* @return
|
|
* - XST_SUCCESS on successful completion.
|
|
* - XST_DEVICE_IS_STARTED.if the Axi Ethernet device is not
|
|
* stopped.
|
|
*
|
|
* @note
|
|
*
|
|
* This routine works only with normal multicast filtering feature. A maximum
|
|
* of 4 multicast addresses can be stored in the HW provided multicast table.
|
|
*
|
|
* To use the extended multicast feature, extended multicast filtering must
|
|
* be enabled by using driver API XAxiEthernet_SetOptions with proper option
|
|
* fields set. Once extended multicast filtering is enabled, the APIs
|
|
* XAxiEthernet_[Add|Clear|Get]ExtMulticastGroup() must be used to manage
|
|
* multicast address groups.
|
|
*
|
|
******************************************************************************/
|
|
int XAxiEthernet_MulticastClear(XAxiEthernet *InstancePtr, int Entry)
|
|
{
|
|
u32 FmiReg;
|
|
|
|
Xil_AssertNonvoid(InstancePtr != NULL);
|
|
Xil_AssertNonvoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY);
|
|
Xil_AssertNonvoid(Entry < XAE_MULTI_MAT_ENTRIES);
|
|
|
|
xdbg_printf(XDBG_DEBUG_GENERAL, "XAxiEthernet_MulticastClear\n");
|
|
|
|
/*
|
|
* The device must be stopped before clearing the multicast hash
|
|
* table.
|
|
*/
|
|
if (InstancePtr->IsStarted == XIL_COMPONENT_IS_STARTED) {
|
|
xdbg_printf(XDBG_DEBUG_GENERAL,
|
|
"XAxiEthernet_MulticastClear:returning DEVICE_IS_STARTED\n");
|
|
return (XST_DEVICE_IS_STARTED);
|
|
}
|
|
|
|
FmiReg = XAxiEthernet_ReadReg(InstancePtr->Config.BaseAddress,
|
|
XAE_FMI_OFFSET);
|
|
FmiReg &= 0xFFFFFF00;
|
|
FmiReg |= (Entry);
|
|
XAxiEthernet_WriteReg(InstancePtr->Config.BaseAddress,
|
|
XAE_FMI_OFFSET, FmiReg);
|
|
|
|
|
|
/* Clear the entry by writing 0:0:0:0:0:0 to it */
|
|
XAxiEthernet_WriteReg(InstancePtr->Config.BaseAddress,
|
|
XAE_AF0_OFFSET, 0);
|
|
|
|
XAxiEthernet_WriteReg(InstancePtr->Config.BaseAddress,
|
|
XAE_AF1_OFFSET, 0);
|
|
|
|
xdbg_printf(XDBG_DEBUG_GENERAL,
|
|
"XAxiEthernet_MulticastClear: returning SUCCESS\n");
|
|
return (XST_SUCCESS);
|
|
}
|
|
|
|
|
|
/*****************************************************************************/
|
|
/**
|
|
* XAxiEthernet_SetMacPauseAddress sets the MAC address used for pause frames
|
|
* to <i>AddressPtr</i>. <i>AddressPtr</i> will be the address the Axi Ethernet
|
|
* device will recognize as being for pause frames. Pause frames transmitted
|
|
* with XAxiEthernet_SendPausePacket() will also use this address.
|
|
*
|
|
* @param InstancePtr is a pointer to the Axi Ethernet instance to be
|
|
* worked on.
|
|
* @param AddressPtr is a pointer to the 6-byte Ethernet address to set.
|
|
*
|
|
* @return
|
|
* - XST_SUCCESS on successful completion.
|
|
* - XST_DEVICE_IS_STARTED if the Axi Ethernet device is not
|
|
* stopped.
|
|
*
|
|
* @note None.
|
|
*
|
|
******************************************************************************/
|
|
int XAxiEthernet_SetMacPauseAddress(XAxiEthernet *InstancePtr,
|
|
void *AddressPtr)
|
|
{
|
|
u32 MacAddr;
|
|
u8 *Aptr = (u8 *) AddressPtr;
|
|
|
|
Xil_AssertNonvoid(InstancePtr != NULL);
|
|
Xil_AssertNonvoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY);
|
|
Xil_AssertNonvoid(AddressPtr != NULL);
|
|
|
|
xdbg_printf(XDBG_DEBUG_GENERAL, "XAxiEthernet_SetMacPauseAddress\n");
|
|
|
|
/* Be sure device has been stopped */
|
|
if (InstancePtr->IsStarted == XIL_COMPONENT_IS_STARTED) {
|
|
xdbg_printf(XDBG_DEBUG_GENERAL,
|
|
"XAxiEthernet_SetMacPauseAddress:returning DEVICE_IS_STARTED\n");
|
|
return (XST_DEVICE_IS_STARTED);
|
|
}
|
|
|
|
/* Set the MAC bits [31:0] in RCW0 register */
|
|
MacAddr = Aptr[0];
|
|
MacAddr |= Aptr[1] << 8;
|
|
MacAddr |= Aptr[2] << 16;
|
|
MacAddr |= Aptr[3] << 24;
|
|
XAxiEthernet_WriteReg(InstancePtr->Config.BaseAddress,
|
|
XAE_RCW0_OFFSET, MacAddr);
|
|
|
|
/* RCW1 contains other info that must be preserved */
|
|
MacAddr = XAxiEthernet_ReadReg(InstancePtr->Config.BaseAddress,
|
|
XAE_RCW1_OFFSET);
|
|
MacAddr &= ~XAE_RCW1_PAUSEADDR_MASK;
|
|
|
|
/* Set MAC bits [47:32] */
|
|
MacAddr |= Aptr[4];
|
|
MacAddr |= Aptr[5] << 8;
|
|
XAxiEthernet_WriteReg(InstancePtr->Config.BaseAddress,
|
|
XAE_RCW1_OFFSET, MacAddr);
|
|
|
|
xdbg_printf(XDBG_DEBUG_GENERAL,
|
|
"XAxiEthernet_SetMacPauseAddress: returning SUCCESS\n");
|
|
|
|
return (XST_SUCCESS);
|
|
}
|
|
|
|
|
|
/*****************************************************************************/
|
|
/**
|
|
* XAxiEthernet_GetMacPauseAddress gets the MAC address used for pause frames
|
|
* for the Axi Ethernet device specified by <i>InstancePtr</i>.
|
|
*
|
|
* @param InstancePtr is a pointer to the Axi Ethernet instance to be
|
|
* worked on.
|
|
* @param AddressPtr references the memory buffer to store the retrieved
|
|
* MAC address. This memory buffer must be at least 6 bytes in
|
|
* length.
|
|
*
|
|
* @return None.
|
|
*
|
|
* @note None.
|
|
*
|
|
******************************************************************************/
|
|
void XAxiEthernet_GetMacPauseAddress(XAxiEthernet *InstancePtr,
|
|
void *AddressPtr)
|
|
{
|
|
u32 MacAddr;
|
|
u8 *Aptr = (u8 *) AddressPtr;
|
|
|
|
Xil_AssertVoid(InstancePtr != NULL);
|
|
Xil_AssertVoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY);
|
|
Xil_AssertVoid(AddressPtr != NULL);
|
|
|
|
|
|
xdbg_printf(XDBG_DEBUG_GENERAL, "XAxiEthernet_SetMacPauseAddress\n");
|
|
|
|
/* Read MAC bits [31:0] in ERXC0 */
|
|
MacAddr = XAxiEthernet_ReadReg(InstancePtr->Config.BaseAddress,
|
|
XAE_RCW0_OFFSET);
|
|
Aptr[0] = (u8) MacAddr;
|
|
Aptr[1] = (u8) (MacAddr >> 8);
|
|
Aptr[2] = (u8) (MacAddr >> 16);
|
|
Aptr[3] = (u8) (MacAddr >> 24);
|
|
|
|
/* Read MAC bits [47:32] in RCW1 */
|
|
MacAddr = XAxiEthernet_ReadReg(InstancePtr->Config.BaseAddress,
|
|
XAE_RCW1_OFFSET);
|
|
Aptr[4] = (u8) MacAddr;
|
|
Aptr[5] = (u8) (MacAddr >> 8);
|
|
|
|
xdbg_printf(XDBG_DEBUG_GENERAL,
|
|
"XAxiEthernet_SetMacPauseAddress: done\n");
|
|
}
|
|
|
|
/*****************************************************************************/
|
|
/**
|
|
* XAxiEthernet_SendPausePacket sends a pause packet with the value of
|
|
* <i>PauseValue</i>.
|
|
*
|
|
* @param InstancePtr is a pointer to the Axi Ethernet instance to be
|
|
* worked on.
|
|
* @param PauseValue is the pause value in units of 512 bit times.
|
|
*
|
|
* @return
|
|
* - XST_SUCCESS on successful completion.
|
|
* - XST_DEVICE_IS_STARTED if the Axi Ethernet device is not
|
|
* stopped.
|
|
*
|
|
* @note None.
|
|
*
|
|
******************************************************************************/
|
|
int XAxiEthernet_SendPausePacket(XAxiEthernet *InstancePtr, u16 PauseValue)
|
|
{
|
|
Xil_AssertNonvoid(InstancePtr != NULL);
|
|
Xil_AssertNonvoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY);
|
|
|
|
|
|
xdbg_printf(XDBG_DEBUG_GENERAL, "XAxiEthernet_SetMacPauseAddress\n");
|
|
|
|
/* Make sure device is ready for this operation */
|
|
if (InstancePtr->IsStarted != XIL_COMPONENT_IS_STARTED) {
|
|
xdbg_printf(XDBG_DEBUG_GENERAL,
|
|
"XAxiEthernet_SendPausePacket:returning DEVICE_IS_STOPPED\n");
|
|
return (XST_DEVICE_IS_STOPPED);
|
|
}
|
|
|
|
/* Send flow control frame */
|
|
XAxiEthernet_WriteReg(InstancePtr->Config.BaseAddress, XAE_TPF_OFFSET,
|
|
(u32) PauseValue & XAE_TPF_TPFV_MASK);
|
|
|
|
xdbg_printf(XDBG_DEBUG_GENERAL,
|
|
"XAxiEthernet_SendPausePacket: returning SUCCESS\n");
|
|
return (XST_SUCCESS);
|
|
}
|
|
|
|
/*****************************************************************************/
|
|
/**
|
|
* XAxiEthernet_GetSgmiiStatus get the state of the link when using the SGMII
|
|
* media interface.
|
|
*
|
|
* @param InstancePtr is a pointer to the Axi Ethernet instance to be
|
|
* worked on.
|
|
* @param SpeedPtr references the location to store the result, which is
|
|
* the auto negotiated link speed in units of Mbits/sec, either 0,
|
|
* 10, 100, or 1000.
|
|
*
|
|
* @return
|
|
* - XST_SUCCESS on successful completion.
|
|
* - XST_NO_FEATURE if the Axi Ethernet device is not using an
|
|
* SGMII interface,
|
|
*
|
|
* @note Currently SGMII PHY does not support half duplex mode.
|
|
*
|
|
******************************************************************************/
|
|
int XAxiEthernet_GetSgmiiStatus(XAxiEthernet *InstancePtr, u16 *SpeedPtr)
|
|
{
|
|
int PhyType;
|
|
u32 EgmicReg;
|
|
|
|
Xil_AssertNonvoid(InstancePtr != NULL);
|
|
Xil_AssertNonvoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY);
|
|
Xil_AssertNonvoid(SpeedPtr != NULL);
|
|
|
|
xdbg_printf(XDBG_DEBUG_GENERAL, "XAxiEthernet_GetSgmiiStatus\n");
|
|
|
|
/* Make sure PHY is SGMII */
|
|
PhyType = XAxiEthernet_GetPhysicalInterface(InstancePtr);
|
|
if (PhyType != XAE_PHY_TYPE_SGMII) {
|
|
xdbg_printf(XDBG_DEBUG_GENERAL,
|
|
"XAxiEthernet_GetSgmiiStatus: returning NO_FEATURE\n");
|
|
return (XST_NO_FEATURE);
|
|
}
|
|
|
|
/* Get the current contents of RGMII/SGMII config register */
|
|
EgmicReg = XAxiEthernet_ReadReg(InstancePtr->Config.BaseAddress,
|
|
XAE_PHYC_OFFSET);
|
|
|
|
/* Extract speed */
|
|
switch (EgmicReg & XAE_PHYC_SGMIILINKSPEED_MASK) {
|
|
case XAE_PHYC_SGLINKSPD_10:
|
|
*SpeedPtr = XAE_SPEED_10_MBPS;
|
|
break;
|
|
|
|
case XAE_PHYC_SGLINKSPD_100:
|
|
*SpeedPtr = XAE_SPEED_100_MBPS;
|
|
break;
|
|
|
|
case XAE_PHYC_SGLINKSPD_1000:
|
|
*SpeedPtr = XAE_SPEED_1000_MBPS;
|
|
break;
|
|
|
|
default:
|
|
*SpeedPtr = 0;
|
|
}
|
|
|
|
xdbg_printf(XDBG_DEBUG_GENERAL,
|
|
"XAxiEthernet_GetSgmiiStatus: returning SUCCESS\n");
|
|
return (XST_SUCCESS);
|
|
}
|
|
|
|
|
|
/*****************************************************************************/
|
|
/**
|
|
* XAxiEthernet_GetRgmiiStatus get the state of the link when using the RGMII
|
|
* media interface.
|
|
*
|
|
* @param InstancePtr is a pointer to the Axi Ethernet instance to be
|
|
* worked on.
|
|
* @param SpeedPtr references the location to store the result, which is
|
|
* the auto negotiated link speed in units of Mbits/sec,
|
|
* either 0, 10, 100, or 1000.
|
|
* @param IsFullDuplexPtr references the value that is set by this
|
|
* function to indicate full duplex operation.
|
|
* <i>IsFullDuplexPtr</i> is set to TRUE when the RGMII link is
|
|
* operating in full duplex mode, otherwise it is set to FALSE.
|
|
* @param IsLinkUpPtr references the value that is set by this function
|
|
* to indicate the link status.<i>IsLinkUpPtr</i> is set to TRUE
|
|
* when the RGMII link up, otherwise it is set to FALSE.
|
|
*
|
|
* @return
|
|
* - XST_SUCCESS on successful completion.
|
|
* - XST_NO_FEATURE if the Axi Ethernet device is not using an
|
|
* RGMII interface,
|
|
*
|
|
* @note None.
|
|
*
|
|
******************************************************************************/
|
|
int XAxiEthernet_GetRgmiiStatus(XAxiEthernet *InstancePtr, u16 *SpeedPtr,
|
|
int *IsFullDuplexPtr, int *IsLinkUpPtr)
|
|
{
|
|
int PhyType;
|
|
u32 EgmicReg;
|
|
|
|
Xil_AssertNonvoid(InstancePtr != NULL);
|
|
Xil_AssertNonvoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY);
|
|
Xil_AssertNonvoid(SpeedPtr != NULL);
|
|
Xil_AssertNonvoid(IsFullDuplexPtr != NULL);
|
|
Xil_AssertNonvoid(IsLinkUpPtr != NULL);
|
|
|
|
|
|
xdbg_printf(XDBG_DEBUG_GENERAL, "XAxiEthernet_GetRgmiiStatus\n");
|
|
|
|
/* Make sure PHY is RGMII */
|
|
PhyType = XAxiEthernet_GetPhysicalInterface(InstancePtr);
|
|
if ((PhyType != XAE_PHY_TYPE_RGMII_1_3) &&
|
|
(PhyType != XAE_PHY_TYPE_RGMII_2_0)) {
|
|
xdbg_printf(XDBG_DEBUG_GENERAL,
|
|
"XAxiEthernet_GetRgmiiStatus: returning NO_FEATURE\n");
|
|
return (XST_NO_FEATURE);
|
|
}
|
|
|
|
/* Get the current contents of RGMII/SGMII config register */
|
|
EgmicReg = XAxiEthernet_ReadReg(InstancePtr->Config.BaseAddress,
|
|
XAE_PHYC_OFFSET);
|
|
|
|
/* Extract speed */
|
|
switch (EgmicReg & XAE_PHYC_RGMIILINKSPEED_MASK) {
|
|
case XAE_PHYC_RGLINKSPD_10:
|
|
*SpeedPtr = XAE_SPEED_10_MBPS;
|
|
break;
|
|
|
|
case XAE_PHYC_RGLINKSPD_100:
|
|
*SpeedPtr = XAE_SPEED_100_MBPS;
|
|
break;
|
|
|
|
case XAE_PHYC_RGLINKSPD_1000:
|
|
*SpeedPtr = XAE_SPEED_1000_MBPS;
|
|
break;
|
|
|
|
default:
|
|
*SpeedPtr = 0;
|
|
}
|
|
|
|
/* Extract duplex and link status */
|
|
if (EgmicReg & XAE_PHYC_RGMIIHD_MASK) {
|
|
*IsFullDuplexPtr = FALSE;
|
|
} else {
|
|
*IsFullDuplexPtr = TRUE;
|
|
}
|
|
|
|
if (EgmicReg & XAE_PHYC_RGMIILINK_MASK) {
|
|
*IsLinkUpPtr = TRUE;
|
|
} else {
|
|
*IsLinkUpPtr = FALSE;
|
|
}
|
|
|
|
xdbg_printf(XDBG_DEBUG_GENERAL,
|
|
"XAxiEthernet_GetRgmiiStatus: returning SUCCESS\n");
|
|
return (XST_SUCCESS);
|
|
}
|
|
|
|
|
|
/*****************************************************************************/
|
|
/**
|
|
* XAxiEthernet_SetTpid sets the VLAN Tag Protocol Identifier(TPID).
|
|
*
|
|
* Four values can be configured - 0x8100, 0x9100, 0x9200, 0x88A8.
|
|
*
|
|
* @param InstancePtr is a pointer to the Axi Ethernet instance to be
|
|
* worked on.
|
|
* @param Tpid is a hex value to be added to the TPID table. The four
|
|
* values that can be added are 0x8100, 0x9100, 0x9200, 0x88A8.
|
|
* @param Entry is the hardware storage location to program this address
|
|
* and must be between 0..XAE_TPID_MAX_ENTRIES.
|
|
*
|
|
* @return
|
|
* - XST_SUCCESS on successful completion.
|
|
* - XST_DEVICE_IS_STARTED, if the Axi Ethernet device is not
|
|
* stopped.
|
|
* - XST_NO_FEATURE if the Axi Ethernet does not enable or have
|
|
* the VLAN tag capability.
|
|
* - XST_INVALID_PARAM if Tpid is not one of supported values.
|
|
*
|
|
* @note The device must be stopped to use this function.
|
|
*
|
|
*****************************************************************************/
|
|
int XAxiEthernet_SetTpid(XAxiEthernet *InstancePtr, u16 Tpid, u8 Entry)
|
|
{
|
|
u32 RegTpid;
|
|
u32 RegTpidOffset;
|
|
Xil_AssertNonvoid(InstancePtr != NULL);
|
|
Xil_AssertNonvoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY);
|
|
Xil_AssertNonvoid(Entry < XAE_TPID_MAX_ENTRIES);
|
|
|
|
/* The device must be stopped before modify VLAN TPID */
|
|
if (InstancePtr->IsStarted == XIL_COMPONENT_IS_STARTED) {
|
|
xdbg_printf(XDBG_DEBUG_GENERAL,
|
|
"XAxiEthernet_SetTpid: returning DEVICE_IS_STARTED\n");
|
|
return (XST_DEVICE_IS_STARTED);
|
|
}
|
|
|
|
/* Check hw capability */
|
|
if (!XAxiEthernet_IsExtFuncCap(InstancePtr)) {
|
|
xdbg_printf(XDBG_DEBUG_GENERAL,
|
|
"XAxiEthernet_SetTpid: returning DEVICE_NO_FEATURE\n");
|
|
return (XST_NO_FEATURE);
|
|
}
|
|
|
|
xdbg_printf(XDBG_DEBUG_GENERAL, "XAxiEthernet_SetTpid\n");
|
|
|
|
/* Verify TPID */
|
|
switch (Tpid) {
|
|
case 0x8100:
|
|
case 0x88a8:
|
|
case 0x9100:
|
|
case 0x9200:
|
|
break;
|
|
default:
|
|
return (XST_INVALID_PARAM);
|
|
}
|
|
|
|
/* Determine which register to operate on */
|
|
if (Entry < 2) {
|
|
RegTpidOffset = XAE_TPID0_OFFSET;
|
|
} else {
|
|
RegTpidOffset = XAE_TPID1_OFFSET;
|
|
}
|
|
|
|
RegTpid = XAxiEthernet_ReadReg(InstancePtr->Config.BaseAddress,
|
|
RegTpidOffset);
|
|
|
|
/* Determine upper/lower 16 bits to operate on */
|
|
if (Entry % 2) {
|
|
/* Program HW */
|
|
XAxiEthernet_WriteReg(InstancePtr->Config.BaseAddress,
|
|
RegTpidOffset, (RegTpid & XAE_TPID_0_MASK) |
|
|
(Tpid << 16));
|
|
} else {
|
|
/* Program HW */
|
|
XAxiEthernet_WriteReg(InstancePtr->Config.BaseAddress,
|
|
RegTpidOffset, (RegTpid & XAE_TPID_1_MASK) |
|
|
Tpid);
|
|
}
|
|
xdbg_printf(XDBG_DEBUG_GENERAL,
|
|
"XAxiEthernet_SetTpid: returning SUCCESS\n");
|
|
return (XST_SUCCESS);
|
|
}
|
|
|
|
/*****************************************************************************/
|
|
/**
|
|
* XAxiEthernet_ClearTpid clears the VLAN Tag Protocol Identifier(TPID).
|
|
*
|
|
*
|
|
* @param InstancePtr is a pointer to the Axi Ethernet instance to be
|
|
* worked on.
|
|
* @param Entry is the hardware storage location to program this address
|
|
* and must be between 0..XAE_TPID_MAX_ENTRIES.
|
|
*
|
|
* @return
|
|
* - XST_SUCCESS on successful completion.
|
|
* - XST_DEVICE_IS_STARTED if the Axi Ethernet device is not
|
|
* stopped.
|
|
* - XST_NO_FEATURE if the Axi Ethernet does not enable or have
|
|
* the VLAN tag capability.
|
|
*
|
|
* @note The device must be stopped to use this function.
|
|
*
|
|
*****************************************************************************/
|
|
int XAxiEthernet_ClearTpid(XAxiEthernet *InstancePtr, u8 Entry)
|
|
{
|
|
u32 RegTpid;
|
|
u32 RegTpidOffset;
|
|
|
|
Xil_AssertNonvoid(InstancePtr != NULL);
|
|
Xil_AssertNonvoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY);
|
|
Xil_AssertNonvoid(Entry < XAE_TPID_MAX_ENTRIES);
|
|
|
|
/* The device must be stopped before modify VLAN TPID */
|
|
if (InstancePtr->IsStarted == XIL_COMPONENT_IS_STARTED) {
|
|
xdbg_printf(XDBG_DEBUG_GENERAL,
|
|
"XAxiEthernet_ClearTpid: returning DEVICE_IS_STARTED\n");
|
|
return (XST_DEVICE_IS_STARTED);
|
|
}
|
|
|
|
/* Check hw capability */
|
|
if (!XAxiEthernet_IsExtFuncCap(InstancePtr)) {
|
|
xdbg_printf(XDBG_DEBUG_GENERAL,
|
|
"XAxiEthernet_ClearTpid: returning DEVICE_NO_FEATURE\n");
|
|
return (XST_NO_FEATURE);
|
|
}
|
|
|
|
xdbg_printf(XDBG_DEBUG_GENERAL, "XAxiEthernet_ClearExtTpid\n");
|
|
|
|
/* Determine which register to operate on */
|
|
if (Entry < 2) {
|
|
RegTpidOffset = XAE_TPID0_OFFSET;
|
|
} else {
|
|
RegTpidOffset = XAE_TPID1_OFFSET;
|
|
}
|
|
|
|
RegTpid = XAxiEthernet_ReadReg(InstancePtr->Config.BaseAddress,
|
|
RegTpidOffset);
|
|
|
|
/* Determine upper/lower 16 bits to operate on */
|
|
if (Entry % 2) {
|
|
/* Program HW */
|
|
XAxiEthernet_WriteReg(InstancePtr->Config.BaseAddress,
|
|
RegTpidOffset, (RegTpid & XAE_TPID_1_MASK));
|
|
} else {
|
|
/* Program HW */
|
|
XAxiEthernet_WriteReg(InstancePtr->Config.BaseAddress,
|
|
RegTpidOffset, (RegTpid & XAE_TPID_0_MASK));
|
|
}
|
|
xdbg_printf(XDBG_DEBUG_GENERAL,
|
|
"XAxiEthernet_ClearTpid: returning SUCCESS\n");
|
|
|
|
return (XST_SUCCESS);
|
|
}
|
|
|
|
|
|
/*****************************************************************************/
|
|
/**
|
|
* XAxiEthernet_GetTpid gets the VLAN Tag Protocol Identifier value (TPID).
|
|
*
|
|
* @param InstancePtr is a pointer to the Axi Ethernet instance to be
|
|
* worked on.
|
|
* @param TpidPtr references the location to store the result.
|
|
* @param Entry is the hardware storage location to program this address
|
|
* and must be between 0..XAE_TPID_MAX_ENTRIES.
|
|
*
|
|
* @return None.
|
|
*
|
|
* @note None.
|
|
*
|
|
*****************************************************************************/
|
|
void XAxiEthernet_GetTpid(XAxiEthernet *InstancePtr, u16 *TpidPtr, u8 Entry)
|
|
{
|
|
u32 RegTpid;
|
|
Xil_AssertVoid(InstancePtr != NULL);
|
|
Xil_AssertVoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY);
|
|
Xil_AssertVoid(TpidPtr != NULL);
|
|
Xil_AssertVoid(Entry < XAE_TPID_MAX_ENTRIES);
|
|
|
|
xdbg_printf(XDBG_DEBUG_GENERAL, "XAxiEthernet_GetTpid\n");
|
|
|
|
if (Entry < 2) {
|
|
RegTpid = XAxiEthernet_ReadReg(InstancePtr->Config.BaseAddress,
|
|
XAE_TPID0_OFFSET);
|
|
} else {
|
|
RegTpid = XAxiEthernet_ReadReg(InstancePtr->Config.BaseAddress,
|
|
XAE_TPID1_OFFSET);
|
|
}
|
|
|
|
if (Entry % 2) {
|
|
*TpidPtr = (RegTpid >> 16);
|
|
} else {
|
|
*TpidPtr = (RegTpid & XAE_TPID_0_MASK);
|
|
}
|
|
xdbg_printf(XDBG_DEBUG_GENERAL, "XAxiEthernet_GetTpid: done\n");
|
|
}
|
|
|
|
|
|
/*****************************************************************************/
|
|
/**
|
|
* XAxiEthernet_SetVTagMode configures the VLAN tagging mode.
|
|
*
|
|
* Four modes can be configured,
|
|
* - XAE_VTAG_NONE for no tagging.
|
|
* - XAE_VTAG_ALL to tag all frames.
|
|
* - XAE_VTAG_EXISTED to tag already tagged frames.
|
|
* - XAE_VTAG_SELECT to tag selected already tagged frames based on VID
|
|
* value.
|
|
*
|
|
* @param InstancePtr is a pointer to the Axi Ethernet instance to be
|
|
* worked on.
|
|
* @param Mode is the VLAN tag mode. Value must be between b'00-b'11.
|
|
* @param Dir must be either XAE_TX or XAE_RX.
|
|
*
|
|
* @return
|
|
* - XST_SUCCESS. on successful completion.
|
|
* - XST_DEVICE_IS_STARTED if the Axi Ethernet device is not
|
|
* stopped.
|
|
* - XST_NO_FEATURE if the Axi Ethernet does not enable or have
|
|
* the TX VLAN tag capability.
|
|
* - XST_INVALID_PARAM if Mode is not one of supported modes.
|
|
*
|
|
* @note
|
|
*
|
|
* The device must be stopped to use this function.<br><br>
|
|
*
|
|
* The fourth mode (specified by XAE_VTAG_SELECT) requires a method for
|
|
* specifying which tagged frames should receive an additional VLAN tag.
|
|
* The VLAN translation table 'tag enabled' is referenced. That configuration
|
|
* is handled in XAxiEthernet_SetVidTable().
|
|
*
|
|
* Mode value shifting is handled in this function. No shifting is required to
|
|
* call this function.
|
|
*
|
|
*****************************************************************************/
|
|
int XAxiEthernet_SetVTagMode(XAxiEthernet *InstancePtr, u32 Mode, int Dir)
|
|
{
|
|
u32 RegRaf;
|
|
|
|
Xil_AssertNonvoid(InstancePtr != NULL);
|
|
Xil_AssertNonvoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY);
|
|
Xil_AssertNonvoid((Dir == XAE_TX) || (Dir == XAE_RX));
|
|
|
|
/* The device must be stopped before modify TX VLAN Tag mode */
|
|
if (InstancePtr->IsStarted == XIL_COMPONENT_IS_STARTED) {
|
|
xdbg_printf(XDBG_DEBUG_GENERAL,
|
|
"XAxiEthernet_SetVTagMode:returning DEVICE_IS_STARTED\n");
|
|
return (XST_DEVICE_IS_STARTED);
|
|
}
|
|
|
|
/* Check hw capability */
|
|
if (!XAxiEthernet_IsExtFuncCap(InstancePtr)) {
|
|
xdbg_printf(XDBG_DEBUG_GENERAL,
|
|
"XAxiEthernet_SetVTagMode: returning DEVICE_NO_FEATURE\n");
|
|
return (XST_NO_FEATURE);
|
|
}
|
|
|
|
/* Mode has to be one of the supported values */
|
|
switch (Mode) {
|
|
case XAE_VTAG_NONE:
|
|
case XAE_VTAG_ALL:
|
|
case XAE_VTAG_EXISTED:
|
|
case XAE_VTAG_SELECT:
|
|
break;
|
|
default:
|
|
return (XST_INVALID_PARAM);
|
|
}
|
|
|
|
xdbg_printf(XDBG_DEBUG_GENERAL, "XAxiEthernet_SetVTagMode\n");
|
|
|
|
/* Program HW */
|
|
RegRaf = XAxiEthernet_ReadReg(InstancePtr->Config.BaseAddress,
|
|
XAE_RAF_OFFSET);
|
|
/* Transmit direction */
|
|
if (XAE_TX == Dir) {
|
|
XAxiEthernet_WriteReg(InstancePtr->Config.BaseAddress,
|
|
XAE_RAF_OFFSET, ((RegRaf & ~XAE_RAF_TXVTAGMODE_MASK) |
|
|
(Mode << XAE_RAF_TXVTAGMODE_SHIFT)));
|
|
} else { /* Receive direction */
|
|
XAxiEthernet_WriteReg(InstancePtr->Config.BaseAddress,
|
|
XAE_RAF_OFFSET, ((RegRaf & ~XAE_RAF_RXVTAGMODE_MASK) |
|
|
(Mode << XAE_RAF_RXVTAGMODE_SHIFT)));
|
|
}
|
|
|
|
xdbg_printf(XDBG_DEBUG_GENERAL,
|
|
"XAxiEthernet_SetVTagMode: returning SUCCESS\n");
|
|
|
|
return (XST_SUCCESS);
|
|
}
|
|
|
|
/*****************************************************************************/
|
|
/**
|
|
* XAxiEthernet_GetVTagMode gets VLAN tagging mode.
|
|
*
|
|
* @param InstancePtr is a pointer to the Axi Ethernet instance to be
|
|
worked on.
|
|
* @param ModePtr references the location to store the VLAN tag mode.
|
|
* Value is between b'00-b'11.
|
|
* @param Dir must be either XAE_TX or XAE_RX.
|
|
*
|
|
* @return None.
|
|
*
|
|
* @note
|
|
*
|
|
* The device must be stopped to use this function.<br><br>
|
|
* Mode value shifting is handled in this function. No shifting is required to
|
|
* call this function.
|
|
*
|
|
*****************************************************************************/
|
|
void XAxiEthernet_GetVTagMode(XAxiEthernet *InstancePtr, u8 *ModePtr, int Dir)
|
|
{
|
|
u32 RegRaf;
|
|
|
|
Xil_AssertVoid(InstancePtr != NULL);
|
|
Xil_AssertVoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY);
|
|
Xil_AssertVoid(ModePtr != NULL);
|
|
Xil_AssertVoid((Dir == XAE_TX) || (Dir == XAE_RX));
|
|
|
|
xdbg_printf(XDBG_DEBUG_GENERAL, "XAxiEthernet_GetVTagMode\n");
|
|
|
|
/* Access HW configuration */
|
|
RegRaf = XAxiEthernet_ReadReg(InstancePtr->Config.BaseAddress,
|
|
XAE_RAF_OFFSET);
|
|
/* Transmit direction */
|
|
if (XAE_TX == Dir) {
|
|
*ModePtr = (RegRaf & XAE_RAF_TXVTAGMODE_MASK) >>
|
|
XAE_RAF_TXVTAGMODE_SHIFT;
|
|
} else { /* Receive direction */
|
|
*ModePtr = (RegRaf & XAE_RAF_RXVTAGMODE_MASK) >>
|
|
XAE_RAF_RXVTAGMODE_SHIFT;
|
|
}
|
|
|
|
xdbg_printf(XDBG_DEBUG_GENERAL, "XAxiEthernet_GetVTagMode: done\n");
|
|
|
|
}
|
|
|
|
|
|
/*****************************************************************************/
|
|
/**
|
|
* XAxiEthernet_SetVStripMode configures the VLAN strip mode.
|
|
*
|
|
* Three modes can be configured :
|
|
* - XAE_VSTRP_NONE for no stripping.
|
|
* - XAE_VSTRP_ALL to strip one tag from all frames.
|
|
* - XAE_VSTRP_SELECT to strip one tag from already selected tagged frames
|
|
* based on VID value.
|
|
*
|
|
* @param InstancePtr is a pointer to the Axi Ethernet instance to be
|
|
* worked on.
|
|
* @param Mode is the VLAN strip mode. Value must be b'00, b'01, or b'11.
|
|
* @param Dir must be either XAE_TX or XAE_RX.
|
|
*
|
|
* @return
|
|
* - XST_SUCCESS on successful completion., returns XST_SUCCESS.
|
|
* - XST_DEVICE_IS_STARTED if the Axi Ethernet device is not
|
|
* stopped.
|
|
* - XST_NO_FEATURE if the Axi Ethernet does not enable or have
|
|
* the TX VLAN strip capability.
|
|
* - XST_INVALID_PARAM if Mode is not one of supported modes.
|
|
*
|
|
* @note
|
|
*
|
|
* The device must be stopped to use this function.<br><br>
|
|
* The third mode (specified by XAE_VSTRP_SELECT) requires a method for
|
|
* specifying which tagged frames should be stripped. The VLAN translation
|
|
* table 'stripped enabled' is referenced. That configuration is handled in
|
|
* XAxiEthernet_SetVidTable().
|
|
*
|
|
* Mode value shifting is handled in this function. No shifting is required to
|
|
* call this function.
|
|
*
|
|
*****************************************************************************/
|
|
int XAxiEthernet_SetVStripMode(XAxiEthernet *InstancePtr, u32 Mode, int Dir)
|
|
{
|
|
u32 RegRaf;
|
|
|
|
Xil_AssertNonvoid(InstancePtr != NULL);
|
|
Xil_AssertNonvoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY);
|
|
Xil_AssertNonvoid((Dir == XAE_TX) || (Dir == XAE_RX));
|
|
|
|
/* The device must be stopped before modify TX VLAN Tag mode */
|
|
if (InstancePtr->IsStarted == XIL_COMPONENT_IS_STARTED) {
|
|
xdbg_printf(XDBG_DEBUG_GENERAL,
|
|
"XAxiEthernet_SetVStripMode: returning DEVICE_IS_STARTED\n");
|
|
return (XST_DEVICE_IS_STARTED);
|
|
}
|
|
|
|
/* Check HW capability */
|
|
if (!XAxiEthernet_IsExtFuncCap(InstancePtr)) {
|
|
xdbg_printf(XDBG_DEBUG_GENERAL,
|
|
"XAxiEthernet_SetVStripMode:returning DEVICE_NO_FEATURE\n");
|
|
return (XST_NO_FEATURE);
|
|
}
|
|
|
|
/* Mode has to be one of the supported values */
|
|
switch (Mode) {
|
|
case XAE_VSTRP_NONE:
|
|
case XAE_VSTRP_ALL:
|
|
case XAE_VSTRP_SELECT:
|
|
break;
|
|
default:
|
|
return (XST_INVALID_PARAM);
|
|
}
|
|
|
|
xdbg_printf(XDBG_DEBUG_GENERAL, "XAxiEthernet_SetStripMode\n");
|
|
|
|
/* Program HW */
|
|
RegRaf = XAxiEthernet_ReadReg(InstancePtr->Config.BaseAddress,
|
|
XAE_RAF_OFFSET);
|
|
/* Transmit direction */
|
|
if (XAE_TX == Dir) {
|
|
XAxiEthernet_WriteReg(InstancePtr->Config.BaseAddress,
|
|
XAE_RAF_OFFSET, ((RegRaf & ~XAE_RAF_TXVSTRPMODE_MASK) |
|
|
(Mode << XAE_RAF_TXVSTRPMODE_SHIFT)));
|
|
} else { /* Receive direction */
|
|
XAxiEthernet_WriteReg(InstancePtr->Config.BaseAddress,
|
|
XAE_RAF_OFFSET, ((RegRaf & ~XAE_RAF_RXVSTRPMODE_MASK) |
|
|
(Mode << XAE_RAF_RXVSTRPMODE_SHIFT)));
|
|
}
|
|
|
|
xdbg_printf(XDBG_DEBUG_GENERAL,
|
|
"XAxiEthernet_SetVStripMode:returning SUCCESS\n");
|
|
|
|
return (XST_SUCCESS);
|
|
}
|
|
|
|
|
|
/*****************************************************************************/
|
|
/**
|
|
* XAxiEthernet_GetVStripMode gets the VLAN stripping mode.
|
|
*
|
|
*
|
|
* @param InstancePtr is a pointer to the Axi Ethernet instance to be
|
|
* worked on.
|
|
* @param ModePtr references the location to store the VLAN strip mode
|
|
* returned by this function. Value is b'00, b'01 or b'11.
|
|
* Refer XAE_VTSRAP_* in xaxiethernet.h file for the details.
|
|
* @param Dir must be either XAE_TX or XAE_RX.
|
|
*
|
|
* @return None.
|
|
*
|
|
* @note
|
|
*
|
|
* Mode value shifting is handled in this function. No shifting is required to
|
|
* call this function.
|
|
*
|
|
*****************************************************************************/
|
|
void XAxiEthernet_GetVStripMode(XAxiEthernet *InstancePtr, u8 *ModePtr,
|
|
int Dir)
|
|
{
|
|
u32 RegRaf;
|
|
|
|
Xil_AssertVoid(InstancePtr != NULL);
|
|
Xil_AssertVoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY);
|
|
Xil_AssertVoid(ModePtr != NULL);
|
|
Xil_AssertVoid((Dir == XAE_TX) || (Dir == XAE_RX));
|
|
|
|
xdbg_printf(XDBG_DEBUG_GENERAL, "XAxiEthernet_GetVStripMode\n");
|
|
|
|
/* Access HW configuration */
|
|
RegRaf = XAxiEthernet_ReadReg(InstancePtr->Config.BaseAddress,
|
|
XAE_RAF_OFFSET);
|
|
/* Transmit direction */
|
|
if (XAE_TX == Dir) {
|
|
*ModePtr = (RegRaf & XAE_RAF_TXVSTRPMODE_MASK) >>
|
|
XAE_RAF_TXVSTRPMODE_SHIFT;
|
|
} else { /* Receive direction */
|
|
*ModePtr = (RegRaf & XAE_RAF_RXVSTRPMODE_MASK) >>
|
|
XAE_RAF_RXVSTRPMODE_SHIFT;
|
|
}
|
|
|
|
xdbg_printf(XDBG_DEBUG_GENERAL, "XAxiEthernet_GetVStripMode: done\n");
|
|
}
|
|
|
|
|
|
/*****************************************************************************/
|
|
/**
|
|
* XAxiEthernet_SetVTagValue configures the VLAN tagging value.
|
|
*
|
|
* The device must be stopped to use this function.<br><br>
|
|
*
|
|
* @param InstancePtr is a pointer to the Axi Ethernet instance to be
|
|
* worked on.
|
|
* @param VTagValue is the VLAN tag value to be configured. A 32bit
|
|
* value.
|
|
* TPID, one of the following 16 bit values,
|
|
* 0x8100, 0x88a8, 0x9100, 0x9200.
|
|
* Priority, 3 bits
|
|
* CFI, 1 bit
|
|
* VID, 12 bits
|
|
* @param Dir must be either XAE_TX or XAE_RX.
|
|
*
|
|
* @return
|
|
* - XST_SUCCESS on successful completion, returns .
|
|
* - XST_DEVICE_IS_STARTED if the Axi Ethernet device is not
|
|
* stopped.
|
|
* - XST_NO_FEATURE if the Axi Ethernet does not enable/have
|
|
* TX VLAN tag capability.
|
|
* - XST_INVALID_PARAM, if the TPID is not one the four supported
|
|
* values.
|
|
*
|
|
* @note
|
|
*
|
|
* The four supported TPID values are 0x8100, 0x88a8, 0x9100, 0x9200.
|
|
* XAxiEthernet_SetVTagValue performs verification on TPID only.
|
|
*
|
|
* Ethernet VLAN frames' VLAN type/length(2B) and tag control information(2B).
|
|
* Bit layout : bbbb bbbb bbbb bbbb bbb b bbbb bbbb bbbb
|
|
* \ / | | \ VID (12b) /
|
|
* \ / | CFI bit (1b)
|
|
* TPID (16b) priority bit (3b)
|
|
*
|
|
*****************************************************************************/
|
|
int XAxiEthernet_SetVTagValue(XAxiEthernet *InstancePtr, u32 VTagValue,
|
|
int Dir)
|
|
{
|
|
Xil_AssertNonvoid(InstancePtr != NULL);
|
|
Xil_AssertNonvoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY);
|
|
Xil_AssertNonvoid((Dir == XAE_TX) || (Dir == XAE_RX));
|
|
|
|
/* The device must be stopped before modifying TX VLAN Tag value */
|
|
if (InstancePtr->IsStarted == XIL_COMPONENT_IS_STARTED) {
|
|
xdbg_printf(XDBG_DEBUG_GENERAL,
|
|
"XAxiEthernet_SetVTagValue:returning DEVICE_IS_STARTED\n");
|
|
return (XST_DEVICE_IS_STARTED);
|
|
}
|
|
|
|
/* Check HW capability */
|
|
if (!XAxiEthernet_IsExtFuncCap(InstancePtr)) {
|
|
xdbg_printf(XDBG_DEBUG_GENERAL,
|
|
"XAxiEthernet_SetVTagValue:returning DEVICE_NO_FEATURE\n");
|
|
return (XST_NO_FEATURE);
|
|
}
|
|
|
|
/* Verify TPID */
|
|
switch (VTagValue >> 16) {
|
|
case 0x8100:
|
|
case 0x88a8:
|
|
case 0x9100:
|
|
case 0x9200:
|
|
break;
|
|
default:
|
|
return (XST_INVALID_PARAM);
|
|
}
|
|
|
|
xdbg_printf(XDBG_DEBUG_GENERAL, "XAxiEthernet_SetVTagValue\n");
|
|
|
|
/* Program HW */
|
|
/* Transmit direction */
|
|
if (XAE_TX == Dir) {
|
|
XAxiEthernet_WriteReg(InstancePtr->Config.BaseAddress,
|
|
XAE_TTAG_OFFSET, VTagValue);
|
|
} else { /* Receive direction */
|
|
XAxiEthernet_WriteReg(InstancePtr->Config.BaseAddress,
|
|
XAE_RTAG_OFFSET, VTagValue);
|
|
}
|
|
|
|
xdbg_printf(XDBG_DEBUG_GENERAL,
|
|
"XAxiEthernet_SetVTagValue:returning SUCCESS\n");
|
|
|
|
return (XST_SUCCESS);
|
|
}
|
|
|
|
|
|
/*****************************************************************************/
|
|
/**
|
|
* XAxiEthernet_GetVTagValue gets the configured VLAN tagging value.
|
|
*
|
|
*
|
|
* @param InstancePtr is a pointer to the Axi Ethernet instance to be
|
|
* worked on.
|
|
* @param VTagValuePtr references the location to store the result.
|
|
* Format is TPID, one of the following 16 bit values,
|
|
* 0x8100, 0x88a8, 0x9100, 0x9200.
|
|
* Priority, 3 bits
|
|
* CFI, 1 bit
|
|
* VID, 12 bits
|
|
* @param Dir must be either XAE_TX or XAE_RX.
|
|
*
|
|
* @return None.
|
|
*
|
|
* @note
|
|
*
|
|
* Ethernet VLAN frames' VLAN type/length(2B) and tag control information(2B).
|
|
* Bit layout : bbbb bbbb bbbb bbbb bbb b bbbb bbbb bbbb
|
|
* \ / | | \ VID (12b) /
|
|
* \ / | CFI bit (1b)
|
|
* TPID (16b) priority bit (3b)
|
|
*
|
|
*****************************************************************************/
|
|
void XAxiEthernet_GetVTagValue(XAxiEthernet *InstancePtr, u32 *VTagValuePtr,
|
|
int Dir)
|
|
{
|
|
Xil_AssertVoid(InstancePtr != NULL);
|
|
Xil_AssertVoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY);
|
|
Xil_AssertVoid(VTagValuePtr != NULL);
|
|
Xil_AssertVoid((Dir == XAE_TX) || (Dir == XAE_RX));
|
|
|
|
xdbg_printf(XDBG_DEBUG_GENERAL, "XAxiEthernet_GetVTagValue\n");
|
|
|
|
/* Transmit direction */
|
|
if (XAE_TX == Dir) {
|
|
*VTagValuePtr = XAxiEthernet_ReadReg
|
|
(InstancePtr->Config.BaseAddress,
|
|
XAE_TTAG_OFFSET);
|
|
}
|
|
else { /* Receive direction */
|
|
*VTagValuePtr = XAxiEthernet_ReadReg(
|
|
InstancePtr->Config.BaseAddress,
|
|
XAE_RTAG_OFFSET);
|
|
}
|
|
|
|
xdbg_printf(XDBG_DEBUG_GENERAL, "XAxiEthernet_GetVTagValue: done\n");
|
|
}
|
|
|
|
|
|
/*****************************************************************************/
|
|
/**
|
|
* XAxiEthernet_SetVidTable sets VID table includes new VLAN ID, strip
|
|
* and tag enable bits.
|
|
*
|
|
* The device must be stopped to use this function.<br><br>
|
|
*
|
|
* @param InstancePtr is a pointer to the Axi Ethernet instance to be
|
|
* worked on.
|
|
* @param Entry is the hardware storage location/index to program updated
|
|
* VID value, strip, or tag value.
|
|
* The value must be between 0..0xFFF.
|
|
* @param Vid is updated/translated Vid value to be programmed.
|
|
* @param Strip is strip enable indication for Vid.
|
|
* @param Tag is tag enable indication for Vid.
|
|
* @param Dir must be either XAE_TX or XAE_RX.
|
|
*
|
|
* @return
|
|
* - XST_SUCCESS on successful completion.
|
|
* - XST_DEVICE_IS_STARTED if the Axi Ethernet device is not
|
|
* stopped.
|
|
* - XST_NO_FEATURE if the Axi Ethernet does not enable/have
|
|
* extended functionalities.
|
|
*
|
|
* @note
|
|
*
|
|
* The hardware requires the table to be 'indexed' with Entry and must be
|
|
* 0x000..0xFFF.
|
|
*
|
|
* Bits layout is bbbb bbbb bbbb b b
|
|
* VLAN ID (12b), | |
|
|
* | VLAN double tag enable bit
|
|
* VLAN strip enable bit
|
|
*
|
|
* To disable translation indexed by Entry, Set Vid = Entry.
|
|
*
|
|
*****************************************************************************/
|
|
int XAxiEthernet_SetVidTable(XAxiEthernet *InstancePtr, u32 Entry, u32 Vid,
|
|
u8 Strip, u8 Tag, int Dir)
|
|
{
|
|
u32 Reg;
|
|
|
|
Xil_AssertNonvoid(InstancePtr != NULL);
|
|
Xil_AssertNonvoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY);
|
|
Xil_AssertNonvoid(Entry <= XAE_MAX_VLAN_TABL_ENTRY);
|
|
Xil_AssertNonvoid((Dir == XAE_TX) || (Dir == XAE_RX));
|
|
Xil_AssertNonvoid(Vid <= XAE_MAX_VLAN_TABL_ENTRY);
|
|
Xil_AssertNonvoid(Strip <= XAE_VLAN_TABL_STRP_FLD_LEN);
|
|
Xil_AssertNonvoid(Tag <= XAE_VLAN_TABL_TAG_FLD_LEN);
|
|
|
|
/* The device must be stopped before modify TX VLAN Tag value */
|
|
if (InstancePtr->IsStarted == XIL_COMPONENT_IS_STARTED) {
|
|
xdbg_printf(XDBG_DEBUG_GENERAL,
|
|
"XAxiEthernet_SetVidTable:returning DEVICE_IS_STARTED\n");
|
|
return (XST_DEVICE_IS_STARTED);
|
|
}
|
|
|
|
/* Check HW capability */
|
|
if (!XAxiEthernet_IsExtFuncCap(InstancePtr)) {
|
|
xdbg_printf(XDBG_DEBUG_GENERAL,
|
|
"XAxiEthernet_SetVidTable:returning DEVICE_NO_FEATURE\n");
|
|
return (XST_NO_FEATURE);
|
|
}
|
|
|
|
xdbg_printf(XDBG_DEBUG_GENERAL, "XAxiEthernet_SetVidTable\n");
|
|
|
|
/* Program HW */
|
|
Reg = (Vid << XAE_VLAN_TABL_VID_START_OFFSET) |
|
|
(Strip << XAE_VLAN_TABL_STRP_STRT_OFFSET) | Tag;
|
|
/* Transmit direction */
|
|
if (XAE_TX == Dir) {
|
|
XAxiEthernet_WriteReg(InstancePtr->Config.BaseAddress,
|
|
XAE_TX_VLAN_DATA_OFFSET +
|
|
(Entry << XAE_VLAN_TABL_VID_START_OFFSET), Reg);
|
|
} else { /* Receive direction */
|
|
XAxiEthernet_WriteReg(InstancePtr->Config.BaseAddress,
|
|
XAE_RX_VLAN_DATA_OFFSET +
|
|
(Entry << XAE_VLAN_TABL_VID_START_OFFSET), Reg);
|
|
}
|
|
|
|
xdbg_printf(XDBG_DEBUG_GENERAL,
|
|
"XAxiEthernet_SetVidTable: returning SUCCESS\n");
|
|
return (XST_SUCCESS);
|
|
}
|
|
|
|
/*****************************************************************************/
|
|
/**
|
|
* XAxiEthernet_GetVidTable gets VID table content includes new VLAN ID, strip
|
|
* and tag enable bits.
|
|
*
|
|
* The device must be stopped to use this function.<br><br>
|
|
*
|
|
* @param InstancePtr is a pointer to the Axi Ethernet instance to be
|
|
* worked on.
|
|
* @param Entry is the hardware storage location/index to program
|
|
* updated VID value, strip, or tag value. The value must be
|
|
* between 0..0xFFF.
|
|
* @param VidPtr references the location to store the result.
|
|
* This function stores the Vid value indexed by Entry into
|
|
* this location.
|
|
* @param StripPtr references the location to store the result.
|
|
* This function stores the strip enable bit value indexed
|
|
* by Entry into this location.
|
|
* @param TagPtr references the location to store the result. This
|
|
* function stores the tag enable bit value indexed by Entry
|
|
* into this location.
|
|
* @param Dir must be either XAE_TX or XAE_RX.
|
|
*
|
|
* @return None.
|
|
*
|
|
* @note
|
|
*
|
|
* The hardware requires the table to be 'indexed' with Entry and
|
|
* must be 0x000..0xFFF.
|
|
*
|
|
* Bits layout is bbbb bbbb bbbb b b
|
|
* VLAN ID (12b), | |
|
|
* | VLAN double tag enable bit
|
|
* VLAN strip enable bit
|
|
*
|
|
*****************************************************************************/
|
|
void XAxiEthernet_GetVidTable(XAxiEthernet *InstancePtr, u32 Entry,
|
|
u32 *VidPtr, u8 *StripPtr, u8 *TagPtr, int Dir)
|
|
{
|
|
u32 Reg;
|
|
|
|
Xil_AssertVoid(InstancePtr != NULL);
|
|
Xil_AssertVoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY);
|
|
Xil_AssertVoid(Entry <= XAE_MAX_VLAN_TABL_ENTRY);
|
|
Xil_AssertVoid(VidPtr != NULL);
|
|
Xil_AssertVoid(StripPtr != NULL);
|
|
Xil_AssertVoid(TagPtr != NULL);
|
|
Xil_AssertVoid((Dir == XAE_TX) || (Dir == XAE_RX));
|
|
|
|
xdbg_printf(XDBG_DEBUG_GENERAL, "XAxiEthernet_GetVidTable\n");
|
|
|
|
/* Transmit direction */
|
|
if (XAE_TX == Dir) {
|
|
Reg = XAxiEthernet_ReadReg(InstancePtr->Config.BaseAddress,
|
|
XAE_TX_VLAN_DATA_OFFSET +
|
|
(Entry << XAE_VLAN_TABL_VID_START_OFFSET));
|
|
} else { /* Receive direction */
|
|
Reg = XAxiEthernet_ReadReg(InstancePtr->Config.BaseAddress,
|
|
XAE_RX_VLAN_DATA_OFFSET +
|
|
(Entry << XAE_VLAN_TABL_VID_START_OFFSET));
|
|
}
|
|
|
|
*VidPtr = (Reg >> XAE_VLAN_TABL_VID_START_OFFSET);
|
|
*StripPtr = (Reg >> XAE_VLAN_TABL_STRP_STRT_OFFSET) &
|
|
XAE_VLAN_TABL_STRP_ENTRY_MASK;
|
|
*TagPtr = Reg & XAE_VLAN_TABL_TAG_ENTRY_MASK;
|
|
|
|
xdbg_printf(XDBG_DEBUG_GENERAL, "XAxiEthernet_GetVidTable: done\n");
|
|
}
|
|
|
|
|
|
/*****************************************************************************/
|
|
/**
|
|
* XAxiEthernet_AddExtMulticastGroup adds an entry to the multicast Ethernet
|
|
* address table. The new entry, represents a group of MAC addresses
|
|
* based on the contents of AddressPtr. AddressPtr is one member of the MAC
|
|
* address set in the newly added entry.
|
|
*
|
|
* The device must be stopped to use this function.<br><br>
|
|
*
|
|
* Once an Ethernet address is programmed, the Axi Ethernet device will begin
|
|
* receiving data sent from that address. The Axi Ethernet hardware does not
|
|
* have a control bit to disable multicast filtering. The only way to prevent
|
|
* the Axi Ethernet device from receiving messages from an Ethernet address in
|
|
* the multicast table is to clear it with
|
|
* XAxiEthernet_ClearExtMulticastGroup().
|
|
*
|
|
* @param InstancePtr is a pointer to the Axi Ethernet instance to be
|
|
* worked on.
|
|
* @param AddressPtr is a pointer to the 6-byte Ethernet address to add.
|
|
*
|
|
* @return
|
|
* - XST_SUCCESS.on successful completion.
|
|
* - XST_DEVICE_IS_STARTED if the Axi Ethernet device is not
|
|
* stopped.
|
|
* - XST_INVALID_PARAM if the input MAC address is not between
|
|
* 01:00:5E:00:00:00 and 01:00:5E:7F:FF:FF per RFC1112.
|
|
*
|
|
* @note
|
|
*
|
|
* This routine consider all 2**23 possible multicast Ethernet addresses to be
|
|
* 8Mx1 bit or 1M bytes memory area. All defined multicast addresses are from
|
|
* 01.00.5E.00.00.00 to 01.00.5E.7F.FF.FF
|
|
* The most significant 25 bit out of 48 bit are static, so they will not be
|
|
* part of calculation.
|
|
*
|
|
* The hardware requires to 'index' with bit 22-8, 15 bits in
|
|
* total. The least significant byte/8 bits are considered a group.
|
|
*
|
|
* This API operates at a group (256 MAC addresses) for hardware to do the
|
|
* first layer address filtering. It is user's responsibility to provision
|
|
* this table appropriately.
|
|
*
|
|
*****************************************************************************/
|
|
int XAxiEthernet_AddExtMulticastGroup(XAxiEthernet *InstancePtr,
|
|
void *AddressPtr)
|
|
{
|
|
u8 *Aptr = (u8 *) AddressPtr;
|
|
u32 Loc;
|
|
|
|
Xil_AssertNonvoid(InstancePtr != NULL);
|
|
Xil_AssertNonvoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY);
|
|
Xil_AssertNonvoid(AddressPtr != NULL);
|
|
|
|
xdbg_printf(XDBG_DEBUG_GENERAL, "XAxiEthernet_AddExtMulticastGroup\n");
|
|
|
|
/*
|
|
* The device must be stopped before setting the multicast table.
|
|
*/
|
|
if (InstancePtr->IsStarted == XIL_COMPONENT_IS_STARTED) {
|
|
xdbg_printf(XDBG_DEBUG_GENERAL,
|
|
"XAxiEthernet_AddExtMulticastGroup:returning DEVICE_IS_STARTED\n");
|
|
|
|
return (XST_DEVICE_IS_STARTED);
|
|
}
|
|
|
|
/* Check HW capability */
|
|
if (!XAxiEthernet_IsExtFuncCap(InstancePtr) ||
|
|
!XAxiEthernet_IsExtMcastEnable(InstancePtr)) {
|
|
xdbg_printf(XDBG_DEBUG_GENERAL,
|
|
"XAxiEthernet_AddExtMulticastGroup:returning DEVICE_NO_FEATURE\n");
|
|
return (XST_NO_FEATURE);
|
|
}
|
|
|
|
/*
|
|
* Verify if address is a good/valid multicast address, between
|
|
* 01:00:5E:00:00:00 to 01:00:5E:7F:FF:FF per RFC1112.
|
|
* This address is referenced to be index to the table.
|
|
*/
|
|
if ((0x01 != Aptr[0]) || (0x00 != Aptr[1]) || (0x5e != Aptr[2]) ||
|
|
(0x0 != (Aptr[3] & 0x80)))
|
|
return (XST_INVALID_PARAM);
|
|
|
|
/*
|
|
* Program hardware table, index : bit 22-8. Bit 23 is 0,
|
|
* when passed the if statement above.
|
|
* note: if the index/bits changed, need to revisit calculation.
|
|
*/
|
|
Loc = Aptr[3];
|
|
Loc = Loc << 8;
|
|
Loc |= Aptr[4];
|
|
|
|
/* Word aligned address access */
|
|
Loc = Loc << 2;
|
|
|
|
XAxiEthernet_WriteReg(InstancePtr->Config.BaseAddress,
|
|
XAE_MCAST_TABLE_OFFSET + Loc, 0x01);
|
|
|
|
xdbg_printf(XDBG_DEBUG_GENERAL,
|
|
"XAxiEthernet_AddExtMulticastGroup: returning SUCCESS\n");
|
|
|
|
return (XST_SUCCESS);
|
|
}
|
|
|
|
|
|
/*****************************************************************************/
|
|
/**
|
|
* XAxiEthernet_ClearExtMulticastGroup clears input multicast Ethernet address
|
|
* group from table.
|
|
*
|
|
*
|
|
* @param InstancePtr is a pointer to the Axi Ethernet instance to be
|
|
* worked on.
|
|
* @param AddressPtr is a pointer to the 6-byte Ethernet address to clear.
|
|
*
|
|
* @return
|
|
* - XST_SUCCESS on successful completion, returns XST_SUCCESS.
|
|
* - XST_DEVICE_IS_STARTED if the Axi Ethernet device is not
|
|
* stopped
|
|
* - XST_INVALID_PARAM if input MAC address is not between
|
|
* 01:00:5E:00:00:00 and 01:00:5E:7F:FF:FF per RFC1112.
|
|
*
|
|
* @note
|
|
*
|
|
* Please reference XAxiEthernet_AddExtMulticastGroup for multicast address
|
|
* index and bit value calculation.
|
|
*
|
|
* In table, hardware requires to 'index' with bit 22-8, 15 bits in
|
|
* total. The least significant byte/8 bits are considered a group.
|
|
*
|
|
* There is a scenario that might introduce issues:
|
|
* When multicast tables are programmed initially to accept
|
|
* 01:00:5E:12:34:56 and 01:00:5E:12:34:78 but later decided to clear
|
|
* 01:00:5E:12:34:78. Without validating all possible combinations at the
|
|
* indexed entry, multicast table might be misconfigured and drop
|
|
* frames.
|
|
*
|
|
* When clearing a multicast address table entry, note that a whole group of
|
|
* mac addresses will no longer be accepted - this because an entry in the
|
|
* table represents multiple(256) mac addresses.
|
|
*
|
|
* The device must be stopped to use this function.<br><br>
|
|
* This API operates at a group (256 MAC addresses) level for hardware to
|
|
* perform the first layer address filtering. It is user's responsibility to
|
|
* provision this table appropriately.
|
|
*
|
|
*****************************************************************************/
|
|
int XAxiEthernet_ClearExtMulticastGroup(XAxiEthernet *InstancePtr,
|
|
void *AddressPtr)
|
|
{
|
|
u8 *Aptr = (u8 *) AddressPtr;
|
|
u32 Loc;
|
|
|
|
Xil_AssertNonvoid(InstancePtr != NULL);
|
|
Xil_AssertNonvoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY);
|
|
Xil_AssertNonvoid(AddressPtr != NULL);
|
|
|
|
xdbg_printf(XDBG_DEBUG_GENERAL,
|
|
"XAxiEthernet_ClearExtMulticastGroup\n");
|
|
|
|
/*
|
|
* The device must be stopped before clearing the multicast table.
|
|
*/
|
|
if (InstancePtr->IsStarted == XIL_COMPONENT_IS_STARTED) {
|
|
xdbg_printf(XDBG_DEBUG_GENERAL,
|
|
"XAxiEthernet_ClearExtMulticastGroup:returning DEVICE_IS_STARTED\n");
|
|
return (XST_DEVICE_IS_STARTED);
|
|
}
|
|
|
|
/* Check HW capability */
|
|
if (!XAxiEthernet_IsExtFuncCap(InstancePtr) ||
|
|
!XAxiEthernet_IsExtMcastEnable(InstancePtr)) {
|
|
xdbg_printf(XDBG_DEBUG_GENERAL,
|
|
"XAxiEthernet_ClearExtMulticastGroup:returning DEVICE_NO_FEATURE\n");
|
|
return (XST_NO_FEATURE);
|
|
}
|
|
|
|
/*
|
|
* Verify if address is a good/valid multicast address, between
|
|
* 01:00:5E:00:00:00 to 01:00:5E:7F:FF:FF per RFC1112.
|
|
* This address is referenced to be index to the table.
|
|
*/
|
|
if ((0x01 != Aptr[0]) || (0x00 != Aptr[1]) || (0x5e != Aptr[2]) ||
|
|
(0x0 != (Aptr[3] & 0x80)))
|
|
return (XST_INVALID_PARAM);
|
|
|
|
Loc = Aptr[3];
|
|
Loc = Loc << 8;
|
|
Loc |= Aptr[4];
|
|
|
|
/* Word aligned address access */
|
|
Loc = Loc << 2;
|
|
|
|
XAxiEthernet_WriteReg(InstancePtr->Config.BaseAddress,
|
|
XAE_MCAST_TABLE_OFFSET + Loc, 0x00);
|
|
|
|
xdbg_printf(XDBG_DEBUG_GENERAL,
|
|
"XAxiEthernet_ClearExtMulticastGroup: returning SUCCESS\n");
|
|
|
|
return (XST_SUCCESS);
|
|
}
|
|
|
|
|
|
/*****************************************************************************/
|
|
/**
|
|
* XAxiEthernet_GetExtMulticastGroup returns whether the given Ethernet address
|
|
* group is stored in the table.
|
|
*
|
|
* @param InstancePtr is a pointer to the Axi Ethernet instance to be
|
|
* worked on.
|
|
* @param AddressPtr is a pointer to the 6-byte Ethernet address.
|
|
*
|
|
* @return
|
|
* - TRUE if it is an acceptable multicast MAC address
|
|
* and the group is present in the table.
|
|
* - FALSE if it is not a valid multicast MAC address
|
|
* or the group was not found in the table.
|
|
*
|
|
* @note
|
|
*
|
|
* In the table, hardware requires to 'index' with bit 22-8, 15 bits in
|
|
* total. The least significant byte/8 bits are considered a group.
|
|
* This API operates at a group (256 MAC addresses) level.
|
|
*
|
|
*****************************************************************************/
|
|
int XAxiEthernet_GetExtMulticastGroup(XAxiEthernet *InstancePtr,
|
|
void *AddressPtr)
|
|
{
|
|
u8 *Aptr = (u8 *) AddressPtr;
|
|
u32 Loc;
|
|
u8 Bit;
|
|
|
|
Xil_AssertNonvoid(InstancePtr != NULL);
|
|
Xil_AssertNonvoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY);
|
|
Xil_AssertNonvoid(AddressPtr != NULL);
|
|
|
|
xdbg_printf(XDBG_DEBUG_GENERAL, "XAxiEthernet_GetExtMulticastGroup\n");
|
|
|
|
/*
|
|
* Verify if address is a good/valid multicast address, between
|
|
* 01:00:5E:00:00:00 to 01:00:5E:7F:FF:FF per RFC1112.
|
|
* This address is referenced to be index to the table.
|
|
*/
|
|
if ((0x01 != Aptr[0]) || (0x00 != Aptr[1]) || (0x5e != Aptr[2]) ||
|
|
(0x0 != (Aptr[3] & 0x80)))
|
|
return (FALSE);
|
|
|
|
Loc = Aptr[3];
|
|
Loc = Loc << 8;
|
|
Loc |= Aptr[4];
|
|
|
|
/*
|
|
* Word aligned address access
|
|
*/
|
|
Loc = Loc << 2;
|
|
|
|
Bit = XAxiEthernet_ReadReg(InstancePtr->Config.BaseAddress,
|
|
XAE_MCAST_TABLE_OFFSET + Loc);
|
|
|
|
if (Bit) {
|
|
return (TRUE);
|
|
} else {
|
|
return (FALSE);
|
|
}
|
|
xdbg_printf(XDBG_DEBUG_GENERAL,
|
|
"XAxiEthernet_GetExtMulticastGroup:done\n");
|
|
}
|
|
|
|
|
|
/*****************************************************************************/
|
|
/**
|
|
* XAxiEthernet_DumpExtMulticastGroup dumps ALL provisioned acceptable multicast
|
|
* MAC in the Axi Ethernet device's multicast table.
|
|
*
|
|
* @param InstancePtr is a pointer to the Axi Ethernet instance to be
|
|
* worked on.
|
|
*
|
|
* @return None.
|
|
*
|
|
* @note
|
|
*
|
|
* Hardware requires to 'index' with bit 22-8, 15 bits in
|
|
* total. The least significant byte/8 bits are considered a set.
|
|
*
|
|
* This API operates at a set (256 MAC addresses) level.
|
|
*
|
|
*****************************************************************************/
|
|
void XAxiEthernet_DumpExtMulticastGroup(XAxiEthernet *InstancePtr)
|
|
{
|
|
u32 Loc;
|
|
u32 Index;
|
|
u8 Bit;
|
|
char MacAddr[6];
|
|
|
|
Xil_AssertVoid(InstancePtr != NULL);
|
|
|
|
/*
|
|
* Pre-populated these bytes, we know and guarantee these if
|
|
* provisioned through the XAxiEthernet_AddExtMulticastGroup().
|
|
*/
|
|
MacAddr[0] = 0x01;
|
|
MacAddr[1] = 0x00;
|
|
MacAddr[2] = 0x5E;
|
|
|
|
for (Index = 0; Index < (1 << 15); Index++) {
|
|
MacAddr[3] = Index << 16;
|
|
MacAddr[4] = Index << 8;
|
|
MacAddr[5] = 0;
|
|
|
|
Loc = MacAddr[3];
|
|
Loc |= MacAddr[4] << 8;
|
|
|
|
/* Word aligned address access */
|
|
Loc = Loc << 2;
|
|
|
|
Bit = XAxiEthernet_ReadReg(InstancePtr->Config.BaseAddress,
|
|
XAE_MCAST_TABLE_OFFSET + Loc);
|
|
if (Bit) {
|
|
xdbg_printf(XDBG_DEBUG_GENERAL,
|
|
"%x:%x:%x:%x:%x:%x\n", MacAddr[5], MacAddr[4],
|
|
MacAddr[3], MacAddr[2], MacAddr[1], MacAddr[0]);
|
|
}
|
|
}
|
|
}
|
|
|