How to configure CPSW 5G/9G to add static entries ?
This thread has been locked.
If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.
ALE stands for Address Lookup Engine and it is a module inside CPSW 5G/9G module which is used to implement features specified in IEEE 802.1 Q protocol like VLAN tagging, Learning, Forwarding, Filtering, Rate control, Mirroring etc. (A full list is beyond the scope of this guide). It is how the switch knows which packets are to be forwarded to which ports. Details about the module are described in Section 12.2.2.4.6.1 of TRM.
Programmers can use the features of ALE to setup complicated rules to:
This guide will first explain the basics of Forwarding without re-iterating what is already covered in TRM and User Guide and then explain key use-cases with examples.
NOTE : There are a lot of ALE features and not everything will be covered here, readers are expected to use this as a foundation and go through the TRM and API Guide
When a packet is received it goes through three stages, this is part of IEEE 802.3 Q protocol and not specific to the HW
If the 3 checks pass, then the packet is forwarded to the respective port (Host or Physical ports), else it gets dropped. See below:
For the CPSW IP, Host port can mean any of the cores in the SoC, either the Main R5F 2_0 which is running the Ethernet Firmware or any of the remote cores (A72, MCU R5F) which are running virtual clients. The destination is decided based on the Flow ID (Unique DMA ID) and CoreID (Unique ID for each core).
Without getting too much into concepts of Flow ID and Core ID it's enough to understand that they are required to tie any data flow to a particular core for the DMA and it is how packets are routed by CPSW within the SoC.
For this reason, whenever a rule is created in CPSW ALE to forward packets to Host Port it must also be tied to the relevant Core and Flow ID. This part is handled by the API's provided by ENET-LLD as we will later see with examples.
To know more about Flow ID's, please read the NAVSS Functional Description (Section 10.2.1.3) in TRM.
NOTE : Currently a packet can only be sent to one core as driver does not handle duplication. This is an issue for Multicast/Broadcast frames as multiple cores can subscribe to these frames, there is currently no workaround for this. So for example both Main R5F and A72 cannot receive broadcast frames but either one of them can.
This feature will be implemented in SDK 8.1 (Nov 2021)
Each Port has the following states as per IEEE 802.1 Q
They can be configured using the IOCTL 'CPSW_ALE_IOCTL_SET_PORT_STATE' ,the corresponding HW register for this is 'CPSW_Iy_ALE_PORTCTL0_y' and the corresponding field Iy_REG_Py_PORTSTATE
In addition to port states, one can also set rules like Drop Untagged, Trunk Enable, MAC Only etc. See the TRM and API Guide for more details
The ALE has multiple tables
Right now, we will just focus on VLAN tables
There are two VLAN Tables, Inner VLAN Table and Outer VLAN Table. They are identical in all respects and the two of them are used to implement dual tagging (Q in Q) feature. For single VLAN tag, users must only use Inner VLAN Table. To create a VLAN based FDB rule, users must first create a corresponding VLAN entry in the Inner VLAN Table.
The IOCTL to add a VLAN entry is 'CPSW_ALE_IOCTL_ADD_VLAN' and the IOCTL to delete is 'CPSW_ALE_IOCTL_REMOVE_VLAN'
The entries for VLAN table are shown below:
The FDB entries are of four types (classified by ENTRY_TYPE[0:1] field)
See below:
Classifiers are used to create rules using Multicast/Unicast entries, VLAN and other Table entries. They are applied per port and can be configured to look for one or multiple conditions. For example a classifier can match for a particular VLAN or DA or both.
There is currently no support to add an entry dynamically to the ALE from the remote cores (A72, MCU R5F) so one must add the entry in Ethernet Firmware and compile it before hand. This is done by adding a callback function to the MAC callback handler CpswProxyServer_registerMacHandlerCb() which adds a static configuration.
See flow-chart below:
See this reference patch for Ethernet Firmware (On top of SDK 7.3) for adding a static Multicast entry for A72 core
From 4850b72c76d1bfc1ed88b8633b9266bd32275edc Mon Sep 17 00:00:00 2001 From: Vineet Roy <vroy@ti.com> Date: Thu, 17 Jun 2021 23:32:12 +0530 Subject: [PATCH 1/4] Static Multicast configuration for Linux --- .../mcu_2_0/main_tirtos.c | 172 ++++++++++++++++++ ethfw/ethfw.h | 35 ++++ ethfw/src/ethfw.c | 18 ++ .../server/include/cpsw_proxy_server.h | 34 ++++ ethremotecfg/server/src/cpsw_proxy_server.c | 46 +++++ 5 files changed, 305 insertions(+) diff --git a/apps/app_remoteswitchcfg_server/mcu_2_0/main_tirtos.c b/apps/app_remoteswitchcfg_server/mcu_2_0/main_tirtos.c index 74cc0df..304d560 100644 --- a/apps/app_remoteswitchcfg_server/mcu_2_0/main_tirtos.c +++ b/apps/app_remoteswitchcfg_server/mcu_2_0/main_tirtos.c @@ -207,6 +207,14 @@ static void EthApp_startSwInterVlan(char *recvBuff, static void EthApp_startHwInterVlan(char *recvBuff, char *sendBuff); +static int32_t EthApp_addRemoteCoreStaticCfg(Enet_Handle hEnet, + uint32_t coreId, + uint32_t flowId); + +static void EthApp_delRemoteCoreStaticCfg(Enet_Handle hEnet, + uint32_t coreId, + uint32_t flowId); + /* ========================================================================== */ /* Extern variables */ /* ========================================================================== */ @@ -563,6 +571,11 @@ static int32_t EthApp_initEthFw(void) ethFwCfg.ports[i].portNum); } + /* Set static configuration functions */ + ethFwCfg.addStaticCfg = &EthApp_addRemoteCoreStaticCfg; + ethFwCfg.delStaticCfg = &EthApp_delRemoteCoreStaticCfg; + + /* Initialize the EthFw */ gEthAppObj.hEthFw = EthFw_init(gEthAppObj.enetType, ðFwCfg); if (gEthAppObj.hEthFw == NULL) @@ -815,3 +828,162 @@ void EthApp_traceBufCacheWb(void) } } } + + +static int32_t EthApp_addMpu10StaticCfg(Enet_Handle hEnet, + uint32_t coreId, + uint32_t flowId) +{ + const uint8_t mcastAddr[ENET_MAC_ADDR_LEN] = {0x01, 0x99, 0xc2, 0x00, 0x01, 0x0E}; + CpswAle_SetPolicerEntryInArgs polInArgs; + CpswAle_SetPolicerEntryOutArgs polOutArgs; + CpswAle_SetMcastEntryInArgs mcastInArgs; + Enet_IoctlPrms prms; + uint32_t entry; + int32_t status; + + polInArgs.policerMatch.policerMatchEnMask = 0U; + + /* Add policer entry for port 1 and dstmac */ + polInArgs.policerMatch.policerMatchEnMask = CPSW_ALE_POLICER_MATCH_PORT; + polInArgs.policerMatch.portNum = CPSW_ALE_MACPORT_TO_ALEPORT(ENET_MAC_PORT_1); + polInArgs.policerMatch.portIsTrunk = false; + + polInArgs.policerMatch.policerMatchEnMask |= CPSW_ALE_POLICER_MATCH_MACDST; + polInArgs.policerMatch.dstMacAddrInfo.portNum = CPSW_ALE_HOST_PORT_NUM; + polInArgs.policerMatch.dstMacAddrInfo.addr.vlanId = 0U; + EnetUtils_copyMacAddr(&polInArgs.policerMatch.dstMacAddrInfo.addr.addr[0], &mcastAddr[0]); + + polInArgs.threadIdEn = true; + polInArgs.threadId = flowId; + polInArgs.peakRateInBitsPerSec = 0U; + polInArgs.commitRateInBitsPerSec = 0U; + + ENET_IOCTL_SET_INOUT_ARGS(&prms, &polInArgs, &polOutArgs); + + status = Enet_ioctl(hEnet, gEthAppObj.coreId, CPSW_ALE_IOCTL_SET_POLICER, &prms); + if (status != ENET_SOK) + { + appLogPrintf("Failed to register PORT1 | MACDST policer: %d\n", status); + } + + /* Add policer entry for port 3 and dstmac */ + if (status == ENET_SOK) + { + polInArgs.policerMatch.portNum = CPSW_ALE_MACPORT_TO_ALEPORT(ENET_MAC_PORT_3); + + ENET_IOCTL_SET_INOUT_ARGS(&prms, &polInArgs, &polOutArgs); + + status = Enet_ioctl(hEnet, gEthAppObj.coreId, CPSW_ALE_IOCTL_SET_POLICER, &prms); + if (status != ENET_SOK) + { + appLogPrintf("Failed to register PORT3 | MACDST policer: %d\n", status); + } + } + + /* Add multicast entry with port mask: host port, MAC port 1 and MAC port 3 */ + if (status == ENET_SOK) + { + mcastInArgs.addr.vlanId = 0U; + EnetUtils_copyMacAddr(&mcastInArgs.addr.addr[0], &mcastAddr[0]); + + mcastInArgs.info.super = false; + mcastInArgs.info.fwdState = CPSW_ALE_FWDSTLVL_FWD; + mcastInArgs.info.portMask = (CPSW_ALE_HOST_PORT_MASK | + CPSW_ALE_MACPORT_TO_PORTMASK(ENET_MAC_PORT_1) | + CPSW_ALE_MACPORT_TO_PORTMASK(ENET_MAC_PORT_3)); + mcastInArgs.info.numIgnBits = 0U; + + ENET_IOCTL_SET_INOUT_ARGS(&prms, &mcastInArgs, &entry); + + status = Enet_ioctl(hEnet, gEthAppObj.coreId, CPSW_ALE_IOCTL_ADD_MCAST, &prms); + if (status != ENET_SOK) + { + appLogPrintf("Failed to add mcast ports: %d\n", status); + } + } + + return status; +} + +static void EthApp_delMpu10StaticCfg(Enet_Handle hEnet, + uint32_t coreId, + uint32_t flowId) +{ + const uint8_t mcastAddr[ENET_MAC_ADDR_LEN] = {0x01, 0x80, 0xc2, 0x00, 0x01, 0x0E}; + CpswAle_DelPolicerEntryInArgs polInArgs; + Enet_IoctlPrms prms; + int32_t status; + + polInArgs.policerMatch.policerMatchEnMask = 0U; + + /* Delete policer entry for port 1 and dstmac */ + polInArgs.policerMatch.policerMatchEnMask = CPSW_ALE_POLICER_MATCH_PORT; + polInArgs.policerMatch.portNum = CPSW_ALE_MACPORT_TO_ALEPORT(ENET_MAC_PORT_1); + polInArgs.policerMatch.portIsTrunk = false; + + polInArgs.policerMatch.policerMatchEnMask |= CPSW_ALE_POLICER_MATCH_MACDST; + polInArgs.policerMatch.dstMacAddrInfo.portNum = CPSW_ALE_HOST_PORT_NUM; + polInArgs.policerMatch.dstMacAddrInfo.addr.vlanId = 0U; + EnetUtils_copyMacAddr(&polInArgs.policerMatch.dstMacAddrInfo.addr.addr[0], &mcastAddr[0]); + + polInArgs.aleEntryMask = CPSW_ALE_POLICER_MATCH_PORT; + + ENET_IOCTL_SET_IN_ARGS(&prms, &polInArgs); + + status = Enet_ioctl(hEnet, gEthAppObj.coreId, CPSW_ALE_IOCTL_DEL_POLICER, &prms); + if (status != ENET_SOK) + { + appLogPrintf("Failed to delete PORT1 | MACDST policer: %d\n", status); + } + + /* Delete policer entry for port 3 and dstmac */ + if (status == ENET_SOK) + { + polInArgs.policerMatch.portNum = CPSW_ALE_MACPORT_TO_ALEPORT(ENET_MAC_PORT_3); + + ENET_IOCTL_SET_IN_ARGS(&prms, &polInArgs); + + status = Enet_ioctl(hEnet, gEthAppObj.coreId, CPSW_ALE_IOCTL_DEL_POLICER, &prms); + if (status != ENET_SOK) + { + appLogPrintf("Failed to delete PORT3 | MACDST policer: %d\n", status); + } + } +} + +static int32_t EthApp_addRemoteCoreStaticCfg(Enet_Handle hEnet, + uint32_t coreId, + uint32_t flowId) +{ + int32_t status = ENET_SOK; + + switch (coreId) + { + case IPC_MPU1_0: + appLogPrintf("Add static config for mpu1_0\n"); + status = EthApp_addMpu10StaticCfg(hEnet, coreId, flowId); + break; + + default: + break; + } + + return status; +} + +static void EthApp_delRemoteCoreStaticCfg(Enet_Handle hEnet, + uint32_t coreId, + uint32_t flowId) +{ + switch (coreId) + { + case IPC_MPU1_0: + appLogPrintf("Delete static config for mpu1_0\n"); + EthApp_delMpu10StaticCfg(hEnet, coreId, flowId); + break; + + default: + break; + } +} diff --git a/ethfw/ethfw.h b/ethfw/ethfw.h index ef4a8c9..cafab00 100644 --- a/ethfw/ethfw.h +++ b/ethfw/ethfw.h @@ -178,6 +178,35 @@ typedef struct EthFw_PortConfig_s EnetPort_VlanCfg vlanCfg; } EthFw_Port; +/*! + * \brief Add static configuration. + * + * Add static configuration that is applicable only to specific remote cores. + * + * \param hEnet Handle to Enet LLD + * \param coreId Remote core's IPC core id + * \param flowId Remote core's flow id + * + * \return 0 if no error. Negative value otherwise. + */ +typedef int32_t (*EthFw_addStaticCfg)(Enet_Handle hEnet, + uint32_t coreId, + uint32_t flowId); + +/*! + * \brief Delete static configuration. + * + * Delete static configuration that is applicable only to specific remote cores. + * + * \param hEnet Handle to Enet LLD + * \param coreId Remote core's IPC core id + * \param flowId Remote core's flow id + */ +typedef void (*EthFw_delStaticCfg)(Enet_Handle hEnet, + uint32_t coreId, + uint32_t flowId); + + /*! * \brief Ethernet Firmware configuration * @@ -195,6 +224,12 @@ typedef struct EthFw_Config_s /*! Number of MAC ports owned by EthFw, that is, the size of * EthFw_Config::ports array */ uint32_t numPorts; + + /* Add static configuration that is applicable only to specific remote cores */ + EthFw_addStaticCfg addStaticCfg; + + /* Delete static configuration that is applicable only to specific remote cores */ + EthFw_delStaticCfg delStaticCfg; } EthFw_Config; /*! diff --git a/ethfw/src/ethfw.c b/ethfw/src/ethfw.c index f8eeb7e..e12e425 100644 --- a/ethfw/src/ethfw.c +++ b/ethfw/src/ethfw.c @@ -182,6 +182,12 @@ typedef struct EthFw_Obj_s /* Handle to PTP stack */ TimeSyncPtp_Handle timeSyncPtp; + /* Add static configuration that is applicable only to specific remote cores */ + EthFw_addStaticCfg addStaticCfg; + + /* Delete static configuration that is applicable only to specific remote cores */ + EthFw_delStaticCfg delStaticCfg; + } EthFw_Obj; /* ========================================================================== */ @@ -268,6 +274,10 @@ void EthFw_initConfigParams(Enet_Type enetType, CpswHostPort_Cfg *hostPortCfg = &cpswCfg->hostPortCfg; EnetRm_ResCfg *resCfg = &cpswCfg->resCfg; + /* Initialize Static config function pointers */ + config->addStaticCfg = NULL; + config->delStaticCfg = NULL; + /* MAC port ownership */ config->ports = NULL; config->numPorts = 0U; @@ -306,6 +316,10 @@ EthFw_Handle EthFw_init(Enet_Type enetType, memset(&gEthFwObj, 0, sizeof(gEthFwObj)); + /* Save static config function pointers */ + gEthFwObj.addStaticCfg = config->addStaticCfg; + gEthFwObj.delStaticCfg = config->delStaticCfg; + /* Save config parameters */ gEthFwObj.cpswCfg = config->cpswCfg; gEthFwObj.numPorts = config->numPorts; @@ -419,6 +433,10 @@ int32_t EthFw_initRemoteConfig(EthFw_Handle hEthFw) cfg.notifyServiceRemoteCoreId[0] = IPC_MPU1_0; cfg.notifyServiceRemoteCoreId[1] = IPC_MCU2_1; + /* Static configuration callbacks */ + cfg.addStaticCfg = gEthFwObj.addStaticCfg; + cfg.delStaticCfg = gEthFwObj.delStaticCfg; + status = CpswProxyServer_init(&cfg); if (status != ENET_SOK) { diff --git a/ethremotecfg/server/include/cpsw_proxy_server.h b/ethremotecfg/server/include/cpsw_proxy_server.h index c1acfa9..23098f1 100644 --- a/ethremotecfg/server/include/cpsw_proxy_server.h +++ b/ethremotecfg/server/include/cpsw_proxy_server.h @@ -162,6 +162,34 @@ typedef struct CpswProxyServer_RemoteCoreConfig_s char serverName[ETHREMOTECFG_SERVER_MAX_NAME_LEN]; } CpswProxyServer_RemoteCoreConfig; +/*! + * \brief Add static configuration. + * + * Add static configuration that is applicable only to specific remote cores. + * + * \param hEnet Handle to Enet LLD + * \param coreId Remote core's IPC core id + * \param flowId Remote core's flow id + * + * \return 0 if no error. Negative value otherwise. + */ +typedef int32_t (*CpswProxyServer_addStaticCfg)(Enet_Handle hEnet, + uint32_t coreId, + uint32_t flowId); + +/*! + * \brief Delete static configuration. + * + * Delete static configuration that is applicable only to specific remote cores. + * + * \param hEnet Handle to Enet LLD + * \param coreId Remote core's IPC core id + * \param flowId Remote core's flow id + */ +typedef void (*CpswProxyServer_delStaticCfg)(Enet_Handle hEnet, + uint32_t coreId, + uint32_t flowId); + /*! * \brief Cpsw Proxy Server Remote Configuration structure * @@ -199,6 +227,12 @@ typedef struct CpswProxyServer_Config_s /*! Remote Core configuration */ CpswProxyServer_RemoteCoreConfig remoteCoreCfg[ETHREMOTECFG_SERVER_MAX_INSTANCES]; + + /* Add static configuration that is applicable only to specific remote cores */ + CpswProxyServer_addStaticCfg addStaticCfg; + + /* Delete static configuration that is applicable only to specific remote cores */ + CpswProxyServer_delStaticCfg delStaticCfg; } CpswProxyServer_Config_t; /*! diff --git a/ethremotecfg/server/src/cpsw_proxy_server.c b/ethremotecfg/server/src/cpsw_proxy_server.c index 4c01eaa..295b781 100644 --- a/ethremotecfg/server/src/cpsw_proxy_server.c +++ b/ethremotecfg/server/src/cpsw_proxy_server.c @@ -184,6 +184,12 @@ typedef struct CpswProxyServer_Obj_s SemaphoreP_Handle rdevStartSem; CpswProxyServer_EthDriverObj ethDrvObj; CpswProxyServer_NotifyServiceObj notifyServiceObj; + + /* Add static configuration that is applicable only to specific remote cores */ + CpswProxyServer_addStaticCfg addStaticCfg; + + /* Delete static configuration that is applicable only to specific remote cores */ + CpswProxyServer_delStaticCfg delStaticCfg; } CpswProxyServer_Obj; /* ========================================================================== */ @@ -592,10 +598,13 @@ static int32_t CpswProxyServer_registerMacHandlerCb(uint32_t host_id, u8 *mac_address, uint32_t flow_idx) { + CpswProxyServer_Obj *hProxyServer; int32_t status; Enet_Handle hEnet = (Enet_Handle)((uintptr_t)handle); uint32_t start_flow_idx, flow_idx_offset; + hProxyServer = CpswProxyServer_getHandle(); + CpswProxyServer_validateHandle(hEnet); EnetAppUtils_absFlowIdx2FlowIdxOffset(hEnet, host_id, flow_idx, &start_flow_idx, &flow_idx_offset); appLogPrintf("Function:%s,HostId:%u,Handle:%p,CoreKey:%x, MacAddress:%x:%x:%x:%x:%x:%x, FlowIdx:%u, FlowIdxOffset:%u\n", @@ -618,6 +627,23 @@ static int32_t CpswProxyServer_registerMacHandlerCb(uint32_t host_id, appLogPrintf("EnetAppUtils_regDstMacRxFlow() failed CPSW_ALE_IOCTL_SET_POLICER: %d\n", status); status = RPMSG_KDRV_TP_ETHSWITCH_CMDSTATUS_EFAIL; } + + if (ENET_SOK == status) + { + if (hProxyServer->addStaticCfg != NULL) + { + status = hProxyServer->addStaticCfg(hEnet, host_id, flow_idx_offset); + if (ENET_SOK != status) + { + appLogPrintf("Failed to add static config for coreId=%u: %d\n", host_id, status); + } + } + } + + if (status != ENET_SOK) + { + status = RPMSG_KDRV_TP_ETHSWITCH_CMDSTATUS_EFAIL; + } else { status = RPMSG_KDRV_TP_ETHSWITCH_CMDSTATUS_OK; @@ -632,10 +658,13 @@ static int32_t CpswProxyServer_unregisterMacHandlerCb(uint32_t host_id, u8 *mac_address, uint32_t flow_idx) { + CpswProxyServer_Obj *hProxyServer; int32_t status; Enet_Handle hEnet = (Enet_Handle)((uintptr_t)handle); uint32_t start_flow_idx, flow_idx_offset; + hProxyServer = CpswProxyServer_getHandle(); + CpswProxyServer_validateHandle(hEnet); EnetAppUtils_absFlowIdx2FlowIdxOffset(hEnet, host_id, flow_idx, &start_flow_idx, &flow_idx_offset); appLogPrintf("Function:%s,HostId:%u,Handle:%p,CoreKey:%x, MacAddress:%x:%x:%x:%x:%x:%x, FlowIdx:%u, FlowIdOffset:%u\n", @@ -653,6 +682,19 @@ static int32_t CpswProxyServer_unregisterMacHandlerCb(uint32_t host_id, flow_idx_offset); status = EnetAppUtils_unregDstMacRxFlow(hEnet, core_key, host_id, start_flow_idx, flow_idx_offset, mac_address); + if (status != ENET_SOK) + { + appLogPrintf("Failed EnetAppUtils_unregDstMacRxFlow: %d\n", status); + } + + if (ENET_SOK == status) + { + if (hProxyServer->delStaticCfg != NULL) + { + hProxyServer->delStaticCfg(hEnet, host_id, flow_idx_offset); + } + } + if (status != ENET_SOK) { appLogPrintf("Failed EnetAppUtils_unregDstMacRxFlow: %d\n", status); @@ -1657,6 +1699,10 @@ int32_t CpswProxyServer_init(CpswProxyServer_Config_t *cfg) hProxyServer->initDone = true; appLogPrintf("Remote demo device (core : mcu2_0) .....\r\n"); + + hProxyServer->addStaticCfg = cfg->addStaticCfg; + hProxyServer->delStaticCfg = cfg->delStaticCfg; + return ENET_SOK; } -- 2.25.1
Main Functions :
The relevant structures to understand here are CpswAle_PolicerMatchParams and CpswAle_SetMcastEntryInArgs
Note:
Refer to the patch below for adding a VLAN entry (VID = 70) for Port 1 and Host Port. This patch binds the VID TEST_VID_A72 to Port 1 and enables strict VID check (inArgs.vidIngressCheck = true) so that if this packet is received by any other port then it is dropped.
diff --git a/apps/app_remoteswitchcfg_server/mcu_2_0/main_tirtos.c b/apps/app_remoteswitchcfg_server/mcu_2_0/main_tirtos.c index 74cc0df..6e5b2c0 100644 --- a/apps/app_remoteswitchcfg_server/mcu_2_0/main_tirtos.c +++ b/apps/app_remoteswitchcfg_server/mcu_2_0/main_tirtos.c @@ -147,6 +147,8 @@ /* Define A72_QNX_OS if A72 is running Qnx. Qnx doesn't load resource table. */ /* #define A72_QNX_OS */ +#define TEST_VID_A72 (70U) + /* ========================================================================== */ /* Structure Declarations */ /* ========================================================================== */ @@ -207,6 +209,14 @@ static void EthApp_startSwInterVlan(char *recvBuff, static void EthApp_startHwInterVlan(char *recvBuff, char *sendBuff); +static int32_t EthApp_addRemoteCoreStaticCfg(Enet_Handle hEnet, + uint32_t coreId, + uint32_t flowId); + +static void EthApp_delRemoteCoreStaticCfg(Enet_Handle hEnet, + uint32_t coreId, + uint32_t flowId); + /* ========================================================================== */ /* Extern variables */ /* ========================================================================== */ @@ -563,6 +573,11 @@ static int32_t EthApp_initEthFw(void) ethFwCfg.ports[i].portNum); } + /* Set static configuration functions */ + ethFwCfg.addStaticCfg = &EthApp_addRemoteCoreStaticCfg; + ethFwCfg.delStaticCfg = &EthApp_delRemoteCoreStaticCfg; + + /* Initialize the EthFw */ gEthAppObj.hEthFw = EthFw_init(gEthAppObj.enetType, ðFwCfg); if (gEthAppObj.hEthFw == NULL) @@ -815,3 +830,148 @@ void EthApp_traceBufCacheWb(void) } } } + + +static int32_t EthApp_addMpu10StaticCfg(Enet_Handle hEnet, + uint32_t coreId, + uint32_t flowId) +{ + CpswAle_SetPolicerEntryInArgs polInArgs; + CpswAle_SetPolicerEntryOutArgs polOutArgs; + Enet_IoctlPrms prms; + int32_t status; + + CpswAle_VlanEntryInfo inArgs; + uint32_t outArgs; + + /* Add VLAN entry */ + memset(&inArgs, 0U, sizeof (CpswAle_VlanEntryInfo)); + inArgs.vlanIdInfo.vlanId = TEST_VID_A72; + inArgs.vlanIdInfo.tagType = ENET_VLAN_TAG_TYPE_INNER; + inArgs.vlanMemberList = (1 << CPSW_ALE_MACPORT_TO_ALEPORT(ENET_MAC_PORT_1)) | CPSW_ALE_HOST_PORT_MASK; + inArgs.unregMcastFloodMask = (1 << CPSW_ALE_MACPORT_TO_ALEPORT(ENET_MAC_PORT_1)) | CPSW_ALE_HOST_PORT_MASK; + inArgs.regMcastFloodMask = (1 << CPSW_ALE_MACPORT_TO_ALEPORT(ENET_MAC_PORT_1)) | CPSW_ALE_HOST_PORT_MASK; + inArgs.forceUntaggedEgressMask = 0; + inArgs.noLearnMask = 0U; + inArgs.vidIngressCheck = true; + inArgs.limitIPNxtHdr = false; + inArgs.disallowIPFrag = false; + + ENET_IOCTL_SET_INOUT_ARGS(&prms, &inArgs, &outArgs); + + status = Enet_ioctl(hEnet, gEthAppObj.coreId, CPSW_ALE_IOCTL_ADD_VLAN, &prms); + if (status != ENET_SOK) + { + appLogPrintf("%s() failed ADD_VLAN ioctl failed: %d\n", __func__, status); + } + + polInArgs.policerMatch.policerMatchEnMask = 0U; + + /* Add policer entry for port 1 and dstmac */ + polInArgs.policerMatch.policerMatchEnMask = CPSW_ALE_POLICER_MATCH_PORT; + polInArgs.policerMatch.portNum = CPSW_ALE_MACPORT_TO_ALEPORT(ENET_MAC_PORT_1); + polInArgs.policerMatch.portIsTrunk = false; + + polInArgs.policerMatch.policerMatchEnMask |= CPSW_ALE_POLICER_MATCH_IVLAN; + polInArgs.policerMatch.dstMacAddrInfo.portNum = CPSW_ALE_HOST_PORT_NUM; + polInArgs.policerMatch.dstMacAddrInfo.addr.vlanId = TEST_VID_A72; + + polInArgs.threadIdEn = true; + polInArgs.threadId = flowId; + polInArgs.peakRateInBitsPerSec = 0U; + polInArgs.commitRateInBitsPerSec = 0U; + polInArgs.policerMatch.portNum = CPSW_ALE_MACPORT_TO_ALEPORT(ENET_MAC_PORT_1); + + ENET_IOCTL_SET_INOUT_ARGS(&prms, &polInArgs, &polOutArgs); + + status = Enet_ioctl(hEnet, gEthAppObj.coreId, CPSW_ALE_IOCTL_SET_POLICER, &prms); + if (status != ENET_SOK) + { + appLogPrintf("Failed to register PORT1 | MACDST policer: %d\n", status); + } + return status; +} + +static void EthApp_delMpu10StaticCfg(Enet_Handle hEnet, + uint32_t coreId, + uint32_t flowId) +{ + const uint8_t mcastAddr[ENET_MAC_ADDR_LEN] = {0x01, 0x99, 0xc2, 0x00, 0x01, 0x0E}; + CpswAle_DelPolicerEntryInArgs polInArgs; + Enet_IoctlPrms prms; + int32_t status; + + CpswAle_VlanEntryInfo inArgs; + + /* Delete VLAN entry */ + memset(&inArgs, 0U, sizeof (CpswAle_VlanEntryInfo)); + inArgs.vlanIdInfo.vlanId = TEST_VID_A72; + inArgs.vlanIdInfo.tagType = ENET_VLAN_TAG_TYPE_INNER; + + ENET_IOCTL_SET_IN_ARGS(&prms, &inArgs); + + status = Enet_ioctl(hEnet, gEthAppObj.coreId, CPSW_ALE_IOCTL_REMOVE_VLAN, &prms); + + if (status != ENET_SOK) + { + appLogPrintf("Failed to delete VLAN entry: %d\n", status); + } + + polInArgs.policerMatch.policerMatchEnMask = 0U; + + /* Delete policer entry for port 1 and dstmac */ + polInArgs.policerMatch.policerMatchEnMask = CPSW_ALE_POLICER_MATCH_PORT; + polInArgs.policerMatch.portNum = CPSW_ALE_MACPORT_TO_ALEPORT(ENET_MAC_PORT_1); + polInArgs.policerMatch.portIsTrunk = false; + + polInArgs.policerMatch.policerMatchEnMask |= CPSW_ALE_POLICER_MATCH_MACDST; + polInArgs.policerMatch.dstMacAddrInfo.portNum = CPSW_ALE_HOST_PORT_NUM; + polInArgs.policerMatch.dstMacAddrInfo.addr.vlanId = 0U; + EnetUtils_copyMacAddr(&polInArgs.policerMatch.dstMacAddrInfo.addr.addr[0], &mcastAddr[0]); + + polInArgs.aleEntryMask = CPSW_ALE_POLICER_MATCH_PORT; + polInArgs.policerMatch.portNum = CPSW_ALE_MACPORT_TO_ALEPORT(ENET_MAC_PORT_1); + ENET_IOCTL_SET_IN_ARGS(&prms, &polInArgs); + + status = Enet_ioctl(hEnet, gEthAppObj.coreId, CPSW_ALE_IOCTL_DEL_POLICER, &prms); + if (status != ENET_SOK) + { + appLogPrintf("Failed to delete PORT1 | MACDST policer: %d\n", status); + } +} + +static int32_t EthApp_addRemoteCoreStaticCfg(Enet_Handle hEnet, + uint32_t coreId, + uint32_t flowId) +{ + int32_t status = ENET_SOK; + + switch (coreId) + { + case IPC_MPU1_0: + appLogPrintf("Add static config for mpu1_0\n"); + status = EthApp_addMpu10StaticCfg(hEnet, coreId, flowId); + break; + + default: + break; + } + + return status; +} + +static void EthApp_delRemoteCoreStaticCfg(Enet_Handle hEnet, + uint32_t coreId, + uint32_t flowId) +{ + switch (coreId) + { + case IPC_MPU1_0: + appLogPrintf("Delete static config for mpu1_0\n"); + EthApp_delMpu10StaticCfg(hEnet, coreId, flowId); + break; + + default: + break; + } +} diff --git a/ethfw/ethfw.h b/ethfw/ethfw.h index ef4a8c9..cafab00 100644 --- a/ethfw/ethfw.h +++ b/ethfw/ethfw.h @@ -178,6 +178,35 @@ typedef struct EthFw_PortConfig_s EnetPort_VlanCfg vlanCfg; } EthFw_Port; +/*! + * \brief Add static configuration. + * + * Add static configuration that is applicable only to specific remote cores. + * + * \param hEnet Handle to Enet LLD + * \param coreId Remote core's IPC core id + * \param flowId Remote core's flow id + * + * \return 0 if no error. Negative value otherwise. + */ +typedef int32_t (*EthFw_addStaticCfg)(Enet_Handle hEnet, + uint32_t coreId, + uint32_t flowId); + +/*! + * \brief Delete static configuration. + * + * Delete static configuration that is applicable only to specific remote cores. + * + * \param hEnet Handle to Enet LLD + * \param coreId Remote core's IPC core id + * \param flowId Remote core's flow id + */ +typedef void (*EthFw_delStaticCfg)(Enet_Handle hEnet, + uint32_t coreId, + uint32_t flowId); + + /*! * \brief Ethernet Firmware configuration * @@ -195,6 +224,12 @@ typedef struct EthFw_Config_s /*! Number of MAC ports owned by EthFw, that is, the size of * EthFw_Config::ports array */ uint32_t numPorts; + + /* Add static configuration that is applicable only to specific remote cores */ + EthFw_addStaticCfg addStaticCfg; + + /* Delete static configuration that is applicable only to specific remote cores */ + EthFw_delStaticCfg delStaticCfg; } EthFw_Config; /*! diff --git a/ethfw/src/ethfw.c b/ethfw/src/ethfw.c index f8eeb7e..e12e425 100644 --- a/ethfw/src/ethfw.c +++ b/ethfw/src/ethfw.c @@ -182,6 +182,12 @@ typedef struct EthFw_Obj_s /* Handle to PTP stack */ TimeSyncPtp_Handle timeSyncPtp; + /* Add static configuration that is applicable only to specific remote cores */ + EthFw_addStaticCfg addStaticCfg; + + /* Delete static configuration that is applicable only to specific remote cores */ + EthFw_delStaticCfg delStaticCfg; + } EthFw_Obj; /* ========================================================================== */ @@ -268,6 +274,10 @@ void EthFw_initConfigParams(Enet_Type enetType, CpswHostPort_Cfg *hostPortCfg = &cpswCfg->hostPortCfg; EnetRm_ResCfg *resCfg = &cpswCfg->resCfg; + /* Initialize Static config function pointers */ + config->addStaticCfg = NULL; + config->delStaticCfg = NULL; + /* MAC port ownership */ config->ports = NULL; config->numPorts = 0U; @@ -306,6 +316,10 @@ EthFw_Handle EthFw_init(Enet_Type enetType, memset(&gEthFwObj, 0, sizeof(gEthFwObj)); + /* Save static config function pointers */ + gEthFwObj.addStaticCfg = config->addStaticCfg; + gEthFwObj.delStaticCfg = config->delStaticCfg; + /* Save config parameters */ gEthFwObj.cpswCfg = config->cpswCfg; gEthFwObj.numPorts = config->numPorts; @@ -419,6 +433,10 @@ int32_t EthFw_initRemoteConfig(EthFw_Handle hEthFw) cfg.notifyServiceRemoteCoreId[0] = IPC_MPU1_0; cfg.notifyServiceRemoteCoreId[1] = IPC_MCU2_1; + /* Static configuration callbacks */ + cfg.addStaticCfg = gEthFwObj.addStaticCfg; + cfg.delStaticCfg = gEthFwObj.delStaticCfg; + status = CpswProxyServer_init(&cfg); if (status != ENET_SOK) { diff --git a/ethremotecfg/server/include/cpsw_proxy_server.h b/ethremotecfg/server/include/cpsw_proxy_server.h index c1acfa9..23098f1 100644 --- a/ethremotecfg/server/include/cpsw_proxy_server.h +++ b/ethremotecfg/server/include/cpsw_proxy_server.h @@ -162,6 +162,34 @@ typedef struct CpswProxyServer_RemoteCoreConfig_s char serverName[ETHREMOTECFG_SERVER_MAX_NAME_LEN]; } CpswProxyServer_RemoteCoreConfig; +/*! + * \brief Add static configuration. + * + * Add static configuration that is applicable only to specific remote cores. + * + * \param hEnet Handle to Enet LLD + * \param coreId Remote core's IPC core id + * \param flowId Remote core's flow id + * + * \return 0 if no error. Negative value otherwise. + */ +typedef int32_t (*CpswProxyServer_addStaticCfg)(Enet_Handle hEnet, + uint32_t coreId, + uint32_t flowId); + +/*! + * \brief Delete static configuration. + * + * Delete static configuration that is applicable only to specific remote cores. + * + * \param hEnet Handle to Enet LLD + * \param coreId Remote core's IPC core id + * \param flowId Remote core's flow id + */ +typedef void (*CpswProxyServer_delStaticCfg)(Enet_Handle hEnet, + uint32_t coreId, + uint32_t flowId); + /*! * \brief Cpsw Proxy Server Remote Configuration structure * @@ -199,6 +227,12 @@ typedef struct CpswProxyServer_Config_s /*! Remote Core configuration */ CpswProxyServer_RemoteCoreConfig remoteCoreCfg[ETHREMOTECFG_SERVER_MAX_INSTANCES]; + + /* Add static configuration that is applicable only to specific remote cores */ + CpswProxyServer_addStaticCfg addStaticCfg; + + /* Delete static configuration that is applicable only to specific remote cores */ + CpswProxyServer_delStaticCfg delStaticCfg; } CpswProxyServer_Config_t; /*! diff --git a/ethremotecfg/server/src/cpsw_proxy_server.c b/ethremotecfg/server/src/cpsw_proxy_server.c index 4c01eaa..295b781 100644 --- a/ethremotecfg/server/src/cpsw_proxy_server.c +++ b/ethremotecfg/server/src/cpsw_proxy_server.c @@ -184,6 +184,12 @@ typedef struct CpswProxyServer_Obj_s SemaphoreP_Handle rdevStartSem; CpswProxyServer_EthDriverObj ethDrvObj; CpswProxyServer_NotifyServiceObj notifyServiceObj; + + /* Add static configuration that is applicable only to specific remote cores */ + CpswProxyServer_addStaticCfg addStaticCfg; + + /* Delete static configuration that is applicable only to specific remote cores */ + CpswProxyServer_delStaticCfg delStaticCfg; } CpswProxyServer_Obj; /* ========================================================================== */ @@ -592,10 +598,13 @@ static int32_t CpswProxyServer_registerMacHandlerCb(uint32_t host_id, u8 *mac_address, uint32_t flow_idx) { + CpswProxyServer_Obj *hProxyServer; int32_t status; Enet_Handle hEnet = (Enet_Handle)((uintptr_t)handle); uint32_t start_flow_idx, flow_idx_offset; + hProxyServer = CpswProxyServer_getHandle(); + CpswProxyServer_validateHandle(hEnet); EnetAppUtils_absFlowIdx2FlowIdxOffset(hEnet, host_id, flow_idx, &start_flow_idx, &flow_idx_offset); appLogPrintf("Function:%s,HostId:%u,Handle:%p,CoreKey:%x, MacAddress:%x:%x:%x:%x:%x:%x, FlowIdx:%u, FlowIdxOffset:%u\n", @@ -618,6 +627,23 @@ static int32_t CpswProxyServer_registerMacHandlerCb(uint32_t host_id, appLogPrintf("EnetAppUtils_regDstMacRxFlow() failed CPSW_ALE_IOCTL_SET_POLICER: %d\n", status); status = RPMSG_KDRV_TP_ETHSWITCH_CMDSTATUS_EFAIL; } + + if (ENET_SOK == status) + { + if (hProxyServer->addStaticCfg != NULL) + { + status = hProxyServer->addStaticCfg(hEnet, host_id, flow_idx_offset); + if (ENET_SOK != status) + { + appLogPrintf("Failed to add static config for coreId=%u: %d\n", host_id, status); + } + } + } + + if (status != ENET_SOK) + { + status = RPMSG_KDRV_TP_ETHSWITCH_CMDSTATUS_EFAIL; + } else { status = RPMSG_KDRV_TP_ETHSWITCH_CMDSTATUS_OK; @@ -632,10 +658,13 @@ static int32_t CpswProxyServer_unregisterMacHandlerCb(uint32_t host_id, u8 *mac_address, uint32_t flow_idx) { + CpswProxyServer_Obj *hProxyServer; int32_t status; Enet_Handle hEnet = (Enet_Handle)((uintptr_t)handle); uint32_t start_flow_idx, flow_idx_offset; + hProxyServer = CpswProxyServer_getHandle(); + CpswProxyServer_validateHandle(hEnet); EnetAppUtils_absFlowIdx2FlowIdxOffset(hEnet, host_id, flow_idx, &start_flow_idx, &flow_idx_offset); appLogPrintf("Function:%s,HostId:%u,Handle:%p,CoreKey:%x, MacAddress:%x:%x:%x:%x:%x:%x, FlowIdx:%u, FlowIdOffset:%u\n", @@ -653,6 +682,19 @@ static int32_t CpswProxyServer_unregisterMacHandlerCb(uint32_t host_id, flow_idx_offset); status = EnetAppUtils_unregDstMacRxFlow(hEnet, core_key, host_id, start_flow_idx, flow_idx_offset, mac_address); + if (status != ENET_SOK) + { + appLogPrintf("Failed EnetAppUtils_unregDstMacRxFlow: %d\n", status); + } + + if (ENET_SOK == status) + { + if (hProxyServer->delStaticCfg != NULL) + { + hProxyServer->delStaticCfg(hEnet, host_id, flow_idx_offset); + } + } + if (status != ENET_SOK) { appLogPrintf("Failed EnetAppUtils_unregDstMacRxFlow: %d\n", status); @@ -1657,6 +1699,10 @@ int32_t CpswProxyServer_init(CpswProxyServer_Config_t *cfg) hProxyServer->initDone = true; appLogPrintf("Remote demo device (core : mcu2_0) .....\r\n"); + + hProxyServer->addStaticCfg = cfg->addStaticCfg; + hProxyServer->delStaticCfg = cfg->delStaticCfg; + return ENET_SOK; }
Note:
Users can either run the GEL script cpsw_ale_print_table.gel on R5F (requires CCS and JTAG) or use the script below on A72 to print it. Both of these methods scan the entire ALE table and print all populated entries.
#include <ctype.h> #include <error.h> #include <fcntl.h> #include <stdarg.h> #include <stdint.h> #include <stdio.h> #include <stdlib.h> #include <sys/mman.h> #include <unistd.h> #define MEMORY "/dev/mem" #define CPSW_9G_PORT_NUM 8 #define CPSW_5G_PORT_NUM 4 #define CPSW_2G_PORT_NUM 1 #define ALE_TBLCTL_2G 0x4603E020 #define ALE_TBLW2_2G 0x4603E034 #define ALE_TBLW1_2G 0x4603E038 #define ALE_TBLW0_2G 0x4603E03C #define ALE_TBLCTL_9G 0x0C03E020 #define ALE_TBLW2_9G 0x0C03E034 #define ALE_TBLW1_9G 0x0C03E038 #define ALE_TBLW0_9G 0x0C03E03C #define ALE_TABLE_DEPTH_2G 64 #define ALE_TABLE_DEPTH_5G 512 #define ALE_TABLE_DEPTH_9G 1024 #define ALE_ENTRY_EMTPY 0x0 #define ALE_ENTRY_ADDR 0x1 #define ALE_ENTRY_VLAN 0x2 #define ALE_ENTRY_VLAN_ADDR 0x3 int fd; unsigned page_size, mapped_size, offset_in_page; void * map_base, *virt_addr; int fd; uint32_t mmio_read_32(unsigned long int addr); void mmio_write_32(unsigned long int addr, uint32_t value); static void unmap_address(void) { if (munmap(map_base, mapped_size) == -1) fprintf(stderr, "munmap"); close(fd); } static int map_address(off_t target) { unsigned int width = 8 * sizeof(uint64_t); fd = open(MEMORY, (O_RDWR | O_SYNC)); if (fd < 0) { fprintf(stderr, "Could not open %s!\n", MEMORY); return -5; } mapped_size = page_size = getpagesize(); offset_in_page = (unsigned)target & (page_size - 1); if (offset_in_page + width > page_size) { /* * This access spans pages. * Must map two pages to make it possible: */ mapped_size *= 2; } map_base = mmap(NULL, mapped_size, (PROT_READ | PROT_WRITE), MAP_SHARED, fd, target & ~(off_t)(page_size - 1)); if (map_base == MAP_FAILED) { fprintf(stderr, "Map fail\n"); return -1; } virt_addr = (char *)map_base + offset_in_page; return 0; } static uint64_t read_reg(int width) { uint64_t read_result = 0x0; switch (width) { case 8: read_result = *(volatile uint8_t *)virt_addr; break; case 16: read_result = *(volatile uint16_t *)virt_addr; break; case 32: read_result = *(volatile uint32_t *)virt_addr; break; case 64: read_result = *(volatile uint64_t *)virt_addr; break; default: fprintf(stderr, "bad width"); } return read_result; } static void write_reg(int width, uint64_t writeval) { switch (width) { case 8: *(volatile uint8_t *)virt_addr = writeval; break; case 16: *(volatile uint16_t *)virt_addr = writeval; break; case 32: *(volatile uint32_t *)virt_addr = writeval; break; case 64: *(volatile uint64_t *)virt_addr = writeval; break; default: fprintf(stderr, "bad width"); } } uint32_t mmio_read_32(unsigned long int addr) { uint32_t v = 0; int r; r = map_address(addr); if (r) return 0; v = read_reg(32); unmap_address(); return v; } void mmio_write_32(unsigned long int addr, uint32_t value) { int r; r = map_address(addr); if (r) return; write_reg(32, value); unmap_address(); } void cpsw_print_stat_with_index_nonzero(char* regName, uint32_t portnum, uint32_t regIdx, unsigned long int regAddr) { uint32_t regVal = mmio_read_32(regAddr); if (0 != regVal) { printf("STAT_%d_%s[%d]= %x\n", portnum, regName, regIdx, regVal); } } void cpsw_print_stat_nonzero(char* regName, uint32_t portnum, unsigned long int regAddr) { uint32_t regVal = mmio_read_32(regAddr); if (0 != regVal) { printf("STAT_%d_%s= %x\n",portnum, regName, regVal); } } void cpsw_2g_statsprint_nonzero() { uint32_t i, regAddr, portnum; printf(" STATS \n"); portnum = 0; printf("--------------------------------\n"); printf(" PORT%d STATS \n",portnum); printf("--------------------------------\n"); cpsw_print_stat_nonzero("RXGOODFRAMES ", portnum, (0x4603A000U)); cpsw_print_stat_nonzero("RXBROADCASTFRAMES ", portnum, (0x4603A004U)); cpsw_print_stat_nonzero("RXMULTICASTFRAMES ", portnum, (0x4603A008U)); cpsw_print_stat_nonzero("RXCRCERRORS ", portnum, (0x4603A010U)); cpsw_print_stat_nonzero("RXOVERSIZEDFRAMES ", portnum, (0x4603A018U)); cpsw_print_stat_nonzero("RXUNDERSIZEDFRAMES ", portnum, (0x4603A020U)); cpsw_print_stat_nonzero("RXFRAGMENTS ", portnum, (0x4603A024U)); cpsw_print_stat_nonzero("ALE_DROP ", portnum, (0x4603A028U)); cpsw_print_stat_nonzero("ALE_OVERRUN_DROP ", portnum, (0x4603A02CU)); cpsw_print_stat_nonzero("RXOCTETS ", portnum, (0x4603A030U)); cpsw_print_stat_nonzero("TXGOODFRAMES ", portnum, (0x4603A034U)); cpsw_print_stat_nonzero("TXBROADCASTFRAMES ", portnum, (0x4603A038U)); cpsw_print_stat_nonzero("TXMULTICASTFRAMES ", portnum, (0x4603A03CU)); cpsw_print_stat_nonzero("TXOCTETS ", portnum, (0x4603A064U)); cpsw_print_stat_nonzero("OCTETFRAMES64 ", portnum, (0x4603A068U)); cpsw_print_stat_nonzero("OCTETFRAMES65T127 ", portnum, (0x4603A06CU)); cpsw_print_stat_nonzero("OCTETFRAMES128T255 ", portnum, (0x4603A070U)); cpsw_print_stat_nonzero("OCTETFRAMES256T511 ", portnum, (0x4603A074U)); cpsw_print_stat_nonzero("OCTETFRAMES512T1023 ", portnum, (0x4603A078U)); cpsw_print_stat_nonzero("OCTETFRAMES1024TUP ", portnum, (0x4603A07CU)); cpsw_print_stat_nonzero("NETOCTETS ", portnum, (0x4603A080U)); cpsw_print_stat_nonzero("RX_BOTTOM_OF_FIFO_DROP ", portnum, (0x4603A084U)); cpsw_print_stat_nonzero("PORTMASK_DROP ", portnum, (0x4603A088U)); cpsw_print_stat_nonzero("RX_TOP_OF_FIFO_DROP ", portnum, (0x4603A08CU)); cpsw_print_stat_nonzero("ALE_RATE_LIMIT_DROP ", portnum, (0x4603A090U)); cpsw_print_stat_nonzero("ALE_VID_INGRESS_DROP ", portnum, (0x4603A094U)); cpsw_print_stat_nonzero("ALE_DA_EQ_SA_DROP ", portnum, (0x4603A098U)); cpsw_print_stat_nonzero("ALE_BLOCK_DROP ", portnum, (0x4603A09CU)); cpsw_print_stat_nonzero("ALE_SECURE_DROP ", portnum, (0x4603A0A0U)); cpsw_print_stat_nonzero("ALE_AUTH_DROP ", portnum, (0x4603A0A4U)); cpsw_print_stat_nonzero("ALE_UNKN_UNI ", portnum, (0x4603A0A8U)); cpsw_print_stat_nonzero("ALE_UNKN_UNI_BCNT ", portnum, (0x4603A0ACU)); cpsw_print_stat_nonzero("ALE_UNKN_MLT ", portnum, (0x4603A0B0U)); cpsw_print_stat_nonzero("ALE_UNKN_MLT_BCNT ", portnum, (0x4603A0B4U)); cpsw_print_stat_nonzero("ALE_UNKN_BRD ", portnum, (0x4603A0B8U)); cpsw_print_stat_nonzero("ALE_UNKN_BRD_BCNT ", portnum, (0x4603A0BCU)); cpsw_print_stat_nonzero("ALE_POL_MATCH ", portnum, (0x4603A0C0U)); cpsw_print_stat_nonzero("ALE_POL_MATCH_RED ", portnum, (0x4603A0C4U)); cpsw_print_stat_nonzero("ALE_POL_MATCH_YELLOW ", portnum, (0x4603A0C8U)); cpsw_print_stat_nonzero("TX_MEMORY_PROTECT_ERROR ", portnum, (0x4603A17CU)); portnum = 1; printf("--------------------------------\n"); printf(" PORT%d STATS \n",portnum); printf("--------------------------------\n"); cpsw_print_stat_nonzero("RXGOODFRAMES ", portnum, (0x4603A200U)); cpsw_print_stat_nonzero("RXBROADCASTFRAMES ", portnum, (0x4603A204U)); cpsw_print_stat_nonzero("RXMULTICASTFRAMES ", portnum, (0x4603A208U)); cpsw_print_stat_nonzero("RXPAUSEFRAMES ", portnum, (0x4603A20CU)); cpsw_print_stat_nonzero("RXCRCERRORS ", portnum, (0x4603A210U)); cpsw_print_stat_nonzero("RXALIGNCODEERRORS ", portnum, (0x4603A214U)); cpsw_print_stat_nonzero("RXOVERSIZEDFRAMES ", portnum, (0x4603A218U)); cpsw_print_stat_nonzero("RXJABBERFRAMES ", portnum, (0x4603A21CU)); cpsw_print_stat_nonzero("RXUNDERSIZEDFRAMES ", portnum, (0x4603A220U)); cpsw_print_stat_nonzero("RXFRAGMENTS ", portnum, (0x4603A224U)); cpsw_print_stat_nonzero("ALE_DROP ", portnum, (0x4603A228U)); cpsw_print_stat_nonzero("ALE_OVERRUN_DROP ", portnum, (0x4603A22CU)); cpsw_print_stat_nonzero("RXOCTETS ", portnum, (0x4603A230U)); cpsw_print_stat_nonzero("TXGOODFRAMES ", portnum, (0x4603A234U)); cpsw_print_stat_nonzero("TXBROADCASTFRAMES ", portnum, (0x4603A238U)); cpsw_print_stat_nonzero("TXMULTICASTFRAMES ", portnum, (0x4603A23CU)); cpsw_print_stat_nonzero("TXPAUSEFRAMES ", portnum, (0x4603A240U)); cpsw_print_stat_nonzero("TXDEFERREDFRAMES ", portnum, (0x4603A244U)); cpsw_print_stat_nonzero("TXCOLLISIONFRAMES ", portnum, (0x4603A248U)); cpsw_print_stat_nonzero("TXSINGLECOLLFRAMES ", portnum, (0x4603A24CU)); cpsw_print_stat_nonzero("TXMULTCOLLFRAMES ", portnum, (0x4603A250U)); cpsw_print_stat_nonzero("TXEXCESSIVECOLLISIONS ", portnum, (0x4603A254U)); cpsw_print_stat_nonzero("TXLATECOLLISIONS ", portnum, (0x4603A258U)); cpsw_print_stat_nonzero("RXIPGERROR ", portnum, (0x4603A25CU)); cpsw_print_stat_nonzero("TXCARRIERSENSEERRORS ", portnum, (0x4603A260U)); cpsw_print_stat_nonzero("TXOCTETS ", portnum, (0x4603A264U)); cpsw_print_stat_nonzero("OCTETFRAMES64 ", portnum, (0x4603A268U)); cpsw_print_stat_nonzero("OCTETFRAMES65T127 ", portnum, (0x4603A26CU)); cpsw_print_stat_nonzero("OCTETFRAMES128T255 ", portnum, (0x4603A270U)); cpsw_print_stat_nonzero("OCTETFRAMES256T511 ", portnum, (0x4603A274U)); cpsw_print_stat_nonzero("OCTETFRAMES512T1023 ", portnum, (0x4603A278U)); cpsw_print_stat_nonzero("OCTETFRAMES1024TUP ", portnum, (0x4603A27CU)); cpsw_print_stat_nonzero("NETOCTETS ", portnum, (0x4603A280U)); cpsw_print_stat_nonzero("RX_BOTTOM_OF_FIFO_DROP ", portnum, (0x4603A284U)); cpsw_print_stat_nonzero("PORTMASK_DROP ", portnum, (0x4603A288U)); cpsw_print_stat_nonzero("RX_TOP_OF_FIFO_DROP ", portnum, (0x4603A28CU)); cpsw_print_stat_nonzero("ALE_RATE_LIMIT_DROP ", portnum, (0x4603A290U)); cpsw_print_stat_nonzero("ALE_VID_INGRESS_DROP ", portnum, (0x4603A294U)); cpsw_print_stat_nonzero("ALE_DA_EQ_SA_DROP ", portnum, (0x4603A298U)); cpsw_print_stat_nonzero("ALE_BLOCK_DROP ", portnum, (0x4603A29CU)); cpsw_print_stat_nonzero("ALE_SECURE_DROP ", portnum, (0x4603A2A0U)); cpsw_print_stat_nonzero("ALE_AUTH_DROP ", portnum, (0x4603A2A4U)); cpsw_print_stat_nonzero("ALE_UNKN_UNI ", portnum, (0x4603A2A8U)); cpsw_print_stat_nonzero("ALE_UNKN_UNI_BCNT ", portnum, (0x4603A2ACU)); cpsw_print_stat_nonzero("ALE_UNKN_MLT ", portnum, (0x4603A2B0U)); cpsw_print_stat_nonzero("ALE_UNKN_MLT_BCNT ", portnum, (0x4603A2B4U)); cpsw_print_stat_nonzero("ALE_UNKN_BRD ", portnum, (0x4603A2B8U)); cpsw_print_stat_nonzero("ALE_UNKN_BRD_BCNT ", portnum, (0x4603A2BCU)); cpsw_print_stat_nonzero("ALE_POL_MATCH ", portnum, (0x4603A2C0U)); cpsw_print_stat_nonzero("ALE_POL_MATCH_RED ", portnum, (0x4603A2C4U)); cpsw_print_stat_nonzero("ALE_POL_MATCH_YELLOW ", portnum, (0x4603A2C8U)); cpsw_print_stat_nonzero("TX_MEMORY_PROTECT_ERROR ", portnum, (0x4603A37CU)); for (i = 0; i < 8; i++) { regAddr = 0x4603A380U + (i * 0x4U); cpsw_print_stat_with_index_nonzero("TX_PRI_REG ", portnum, i, regAddr); } for (i = 0; i < 8; i++) { regAddr = 0x4603A3A0U + (i * 0x4U); cpsw_print_stat_with_index_nonzero("TX_PRI_BCNT_REG ", portnum, i, regAddr); } for (i = 0; i < 8; i++) { regAddr = 0x4603A3C0U + (i * 0x4U); cpsw_print_stat_with_index_nonzero("TX_PRI_DROP_REG ", portnum, i, regAddr); } for (i = 0; i < 8; i++) { regAddr = 0x4603A3E0U + (i * 0x4U); cpsw_print_stat_with_index_nonzero("TX_PRI_DROP_BCNT_REG ", portnum, i, regAddr); } } void cpsw_ng_statsprint_nonzero(uint32_t numMacPorts) { uint32_t i, regAddr, portnum; uint32_t baseAddr; printf(" STATS \n"); portnum = 0; printf("--------------------------------\n"); printf(" PORT%d STATS \n",portnum); printf("--------------------------------\n"); cpsw_print_stat_nonzero("RXGOODFRAMES ", portnum, (0x0C03A000U)); cpsw_print_stat_nonzero("RXBROADCASTFRAMES ", portnum, (0x0C03A004U)); cpsw_print_stat_nonzero("RXMULTICASTFRAMES ", portnum, (0x0C03A008U)); cpsw_print_stat_nonzero("RXCRCERRORS ", portnum, (0x0C03A010U)); cpsw_print_stat_nonzero("RXOVERSIZEDFRAMES ", portnum, (0x0C03A018U)); cpsw_print_stat_nonzero("RXUNDERSIZEDFRAMES ", portnum, (0x0C03A020U)); cpsw_print_stat_nonzero("RXFRAGMENTS ", portnum, (0x0C03A024U)); cpsw_print_stat_nonzero("ALE_DROP ", portnum, (0x0C03A028U)); cpsw_print_stat_nonzero("ALE_OVERRUN_DROP ", portnum, (0x0C03A02CU)); cpsw_print_stat_nonzero("RXOCTETS ", portnum, (0x0C03A030U)); cpsw_print_stat_nonzero("TXGOODFRAMES ", portnum, (0x0C03A034U)); cpsw_print_stat_nonzero("TXBROADCASTFRAMES ", portnum, (0x0C03A038U)); cpsw_print_stat_nonzero("TXMULTICASTFRAMES ", portnum, (0x0C03A03CU)); cpsw_print_stat_nonzero("TXOCTETS ", portnum, (0x0C03A064U)); cpsw_print_stat_nonzero("OCTETFRAMES64 ", portnum, (0x0C03A068U)); cpsw_print_stat_nonzero("OCTETFRAMES65T127 ", portnum, (0x0C03A06CU)); cpsw_print_stat_nonzero("OCTETFRAMES128T255 ", portnum, (0x0C03A070U)); cpsw_print_stat_nonzero("OCTETFRAMES256T511 ", portnum, (0x0C03A074U)); cpsw_print_stat_nonzero("OCTETFRAMES512T1023 ", portnum, (0x0C03A078U)); cpsw_print_stat_nonzero("OCTETFRAMES1024TUP ", portnum, (0x0C03A07CU)); cpsw_print_stat_nonzero("NETOCTETS ", portnum, (0x0C03A080U)); cpsw_print_stat_nonzero("RX_BOTTOM_OF_FIFO_DROP ", portnum, (0x0C03A084U)); cpsw_print_stat_nonzero("PORTMASK_DROP ", portnum, (0x0C03A088U)); cpsw_print_stat_nonzero("RX_TOP_OF_FIFO_DROP ", portnum, (0x0C03A08CU)); cpsw_print_stat_nonzero("ALE_RATE_LIMIT_DROP ", portnum, (0x0C03A090U)); cpsw_print_stat_nonzero("ALE_VID_INGRESS_DROP ", portnum, (0x0C03A094U)); cpsw_print_stat_nonzero("ALE_DA_EQ_SA_DROP ", portnum, (0x0C03A098U)); cpsw_print_stat_nonzero("ALE_BLOCK_DROP ", portnum, (0x0C03A09CU)); cpsw_print_stat_nonzero("ALE_SECURE_DROP ", portnum, (0x0C03A0A0U)); cpsw_print_stat_nonzero("ALE_AUTH_DROP ", portnum, (0x0C03A0A4U)); cpsw_print_stat_nonzero("ALE_UNKN_UNI ", portnum, (0x0C03A0A8U)); cpsw_print_stat_nonzero("ALE_UNKN_UNI_BCNT ", portnum, (0x0C03A0ACU)); cpsw_print_stat_nonzero("ALE_UNKN_MLT ", portnum, (0x0C03A0B0U)); cpsw_print_stat_nonzero("ALE_UNKN_MLT_BCNT ", portnum, (0x0C03A0B4U)); cpsw_print_stat_nonzero("ALE_UNKN_BRD ", portnum, (0x0C03A0B8U)); cpsw_print_stat_nonzero("ALE_UNKN_BRD_BCNT ", portnum, (0x0C03A0BCU)); cpsw_print_stat_nonzero("ALE_POL_MATCH ", portnum, (0x0C03A0C0U)); cpsw_print_stat_nonzero("ALE_POL_MATCH_RED ", portnum, (0x0C03A0C4U)); cpsw_print_stat_nonzero("ALE_POL_MATCH_YELLOW ", portnum, (0x0C03A0C8U)); cpsw_print_stat_nonzero("TX_MEMORY_PROTECT_ERROR ", portnum, (0x0C03A17CU)); for (i = 0; i < 8; i++) { regAddr = 0x0C03A180U + (i * 0x4U); cpsw_print_stat_with_index_nonzero("TX_PRI_REG ", portnum, i, regAddr); } for (i = 0; i < 8; i++) { regAddr = 0x0C03A1A0U + (i * 0x4U); cpsw_print_stat_with_index_nonzero("TX_PRI_BCNT_REG ", portnum, i, regAddr); } for (i = 0; i < 8; i++) { regAddr = 0x0C03A1C0U + (i * 0x4U); cpsw_print_stat_with_index_nonzero("TX_PRI_DROP_REG ", portnum, i, regAddr); } for (i = 0; i < 8; i++) { regAddr = 0x0C03A1E0U + (i * 0x4U); cpsw_print_stat_with_index_nonzero("TX_PRI_DROP_BCNT_REG ", portnum, i, regAddr); } for (portnum = 1; portnum <= numMacPorts; portnum++) { printf("--------------------------------\n"); printf(" PORT%d STATS \n",portnum); printf("--------------------------------\n"); baseAddr = 0x0C03A200U + ((portnum-1) * 0x200); cpsw_print_stat_nonzero("RXGOODFRAMES ", portnum, (baseAddr)); cpsw_print_stat_nonzero("RXBROADCASTFRAMES ", portnum, (baseAddr + 0x4U)); cpsw_print_stat_nonzero("RXMULTICASTFRAMES ", portnum, (baseAddr + 0x8U)); cpsw_print_stat_nonzero("RXPAUSEFRAMES ", portnum, (baseAddr + 0xCU)); cpsw_print_stat_nonzero("RXCRCERRORS ", portnum, (baseAddr + 0x10U)); cpsw_print_stat_nonzero("RXALIGNCODEERRORS ", portnum, (baseAddr + 0x14U)); cpsw_print_stat_nonzero("RXOVERSIZEDFRAMES ", portnum, (baseAddr + 0x18U)); cpsw_print_stat_nonzero("RXJABBERFRAMES ", portnum, (baseAddr + 0x1CU)); cpsw_print_stat_nonzero("RXUNDERSIZEDFRAMES ", portnum, (baseAddr + 0x20U)); cpsw_print_stat_nonzero("RXFRAGMENTS ", portnum, (baseAddr + 0x24U)); cpsw_print_stat_nonzero("ALE_DROP ", portnum, (baseAddr + 0x28U)); cpsw_print_stat_nonzero("ALE_OVERRUN_DROP ", portnum, (baseAddr + 0x2CU)); cpsw_print_stat_nonzero("RXOCTETS ", portnum, (baseAddr + 0x30U)); cpsw_print_stat_nonzero("TXGOODFRAMES ", portnum, (baseAddr + 0x34U)); cpsw_print_stat_nonzero("TXBROADCASTFRAMES ", portnum, (baseAddr + 0x38U)); cpsw_print_stat_nonzero("TXMULTICASTFRAMES ", portnum, (baseAddr + 0x3CU)); cpsw_print_stat_nonzero("TXPAUSEFRAMES ", portnum, (baseAddr + 0x40U)); cpsw_print_stat_nonzero("TXDEFERREDFRAMES ", portnum, (baseAddr + 0x44U)); cpsw_print_stat_nonzero("TXCOLLISIONFRAMES ", portnum, (baseAddr + 0x48U)); cpsw_print_stat_nonzero("TXSINGLECOLLFRAMES ", portnum, (baseAddr + 0x4CU)); cpsw_print_stat_nonzero("TXMULTCOLLFRAMES ", portnum, (baseAddr + 0x50U)); cpsw_print_stat_nonzero("TXEXCESSIVECOLLISIONS ", portnum, (baseAddr + 0x54U)); cpsw_print_stat_nonzero("TXLATECOLLISIONS ", portnum, (baseAddr + 0x58U)); cpsw_print_stat_nonzero("RXIPGERROR ", portnum, (baseAddr + 0x5CU)); cpsw_print_stat_nonzero("TXCARRIERSENSEERRORS ", portnum, (baseAddr + 0x60U)); cpsw_print_stat_nonzero("TXOCTETS ", portnum, (baseAddr + 0x64U)); cpsw_print_stat_nonzero("OCTETFRAMES64 ", portnum, (baseAddr + 0x68U)); cpsw_print_stat_nonzero("OCTETFRAMES65T127 ", portnum, (baseAddr + 0x6CU)); cpsw_print_stat_nonzero("OCTETFRAMES128T255 ", portnum, (baseAddr + 0x70U)); cpsw_print_stat_nonzero("OCTETFRAMES256T511 ", portnum, (baseAddr + 0x74U)); cpsw_print_stat_nonzero("OCTETFRAMES512T1023 ", portnum, (baseAddr + 0x78U)); cpsw_print_stat_nonzero("OCTETFRAMES1024TUP ", portnum, (baseAddr + 0x7CU)); cpsw_print_stat_nonzero("NETOCTETS ", portnum, (baseAddr + 0x80U)); cpsw_print_stat_nonzero("RX_BOTTOM_OF_FIFO_DROP ", portnum, (baseAddr + 0x84U)); cpsw_print_stat_nonzero("PORTMASK_DROP ", portnum, (baseAddr + 0x88U)); cpsw_print_stat_nonzero("RX_TOP_OF_FIFO_DROP ", portnum, (baseAddr + 0x8CU)); cpsw_print_stat_nonzero("ALE_RATE_LIMIT_DROP ", portnum, (baseAddr + 0x90U)); cpsw_print_stat_nonzero("ALE_VID_INGRESS_DROP ", portnum, (baseAddr + 0x94U)); cpsw_print_stat_nonzero("ALE_DA_EQ_SA_DROP ", portnum, (baseAddr + 0x98U)); cpsw_print_stat_nonzero("ALE_BLOCK_DROP ", portnum, (baseAddr + 0x9CU)); cpsw_print_stat_nonzero("ALE_SECURE_DROP ", portnum, (baseAddr + 0xA0U)); cpsw_print_stat_nonzero("ALE_AUTH_DROP ", portnum, (baseAddr + 0xA4U)); cpsw_print_stat_nonzero("ALE_UNKN_UNI ", portnum, (baseAddr + 0xA8U)); cpsw_print_stat_nonzero("ALE_UNKN_UNI_BCNT ", portnum, (baseAddr + 0xACU)); cpsw_print_stat_nonzero("ALE_UNKN_MLT ", portnum, (baseAddr + 0xB0U)); cpsw_print_stat_nonzero("ALE_UNKN_MLT_BCNT ", portnum, (baseAddr + 0xB4U)); cpsw_print_stat_nonzero("ALE_UNKN_BRD ", portnum, (baseAddr + 0xB8U)); cpsw_print_stat_nonzero("ALE_UNKN_BRD_BCNT ", portnum, (baseAddr + 0xBCU)); cpsw_print_stat_nonzero("ALE_POL_MATCH ", portnum, (baseAddr + 0xC0U)); cpsw_print_stat_nonzero("ALE_POL_MATCH_RED ", portnum, (baseAddr + 0xC4U)); cpsw_print_stat_nonzero("ALE_POL_MATCH_YELLOW ", portnum, (baseAddr + 0xC8U)); cpsw_print_stat_nonzero("TX_MEMORY_PROTECT_ERROR ", portnum, (baseAddr + 0x17CU)); for (i = 0; i < 8; i++) { regAddr = (baseAddr + 0x180U) + (i * 0x4U); cpsw_print_stat_with_index_nonzero("TX_PRI_REG ", portnum, i, regAddr); } for (i = 0; i < 8; i++) { regAddr = (baseAddr + 0x1A0U) + (i * 0x4U); cpsw_print_stat_with_index_nonzero("TX_PRI_BCNT_REG ", portnum, i, regAddr); } for (i = 0; i < 8; i++) { regAddr = (baseAddr + 0x1C0U) + (i * 0x4U); cpsw_print_stat_with_index_nonzero("TX_PRI_DROP_REG ", portnum, i, regAddr); } for (i = 0; i < 8; i++) { regAddr = (baseAddr + 0x1E0U) + (i * 0x4U); cpsw_print_stat_with_index_nonzero("TX_PRI_DROP_BCNT_REG ", portnum, i, regAddr); } } } void cpsw_5g_statsprint_nonzero() { cpsw_ng_statsprint_nonzero(CPSW_5G_PORT_NUM); } void cpsw_9g_statsprint_nonzero() { cpsw_ng_statsprint_nonzero(CPSW_9G_PORT_NUM); } void cpsw_clear_stat(uint32_t regAddr) { uint32_t regVal = mmio_read_32(regAddr); mmio_write_32(regAddr, regVal); } void cpsw_2g_clear_stats() { uint32_t portnum, baseAddr, numStats; for (portnum = 0; portnum <= CPSW_2G_PORT_NUM; portnum++) { baseAddr = 0x4603A000U + (portnum * 0x200); printf("Clearing stats for port[%d]\n", portnum); for (numStats = 0; numStats < 128U; numStats++) { cpsw_clear_stat(baseAddr + (numStats*0x4)); } } printf("--------CLEARED ALL STATS-------\n"); } void show_ale_entry_multicast_2g(uint32_t index, uint32_t word0, uint32_t word1, uint32_t word2) { printf("---------------------------------------------\n"); printf(" Entry %u - Multicast\n", index); printf("---------------------------------------------\n"); printf("PORT_MASK = %x\n", (word2 >> 2) & 0x1FF); printf("SUPER = %u\n", (word2 >> 1) & 0x1); printf("MCAST_FWD_STATE = %u\n", (word1 >> 30) & 0x3); printf("ENTRY_TYPE = %u\n", (word1 >> 28) & 0x3); printf("MULTICAST_ADDR = %x %x\n", (word1 >> 0) & 0xFFFF, word0); } void show_ale_entry_multicast_9g(uint32_t index, uint32_t word0, uint32_t word1, uint32_t word2) { printf("---------------------------------------------\n"); printf(" Entry %u - Multicast\n", index); printf("---------------------------------------------\n"); printf("PORT_MASK = %x\n", (word2 >> 2) & 0x1FF); printf("SUPER = %u\n", (word2 >> 1) & 0x1); printf("MCAST IGNORE BITS= %u\n", (word2 >> 0) & 0x1); printf("MCAST_FWD_STATE = %u\n", (word1 >> 30) & 0x3); printf("ENTRY_TYPE = %u\n", (word1 >> 28) & 0x3); printf("MULTICAST_ADDR = %x %x\n", (word1 >> 0) & 0xFFFF, word0); } void show_ale_entry_vlan_multicast_2g(uint32_t index, uint32_t word0, uint32_t word1, uint32_t word2) { printf("---------------------------------------------\n"); printf(" Entry %u - VLAN/Multicast\n", index); printf("---------------------------------------------\n"); printf("PORT_MASK = %x\n", (word2 >> 2) & 0x1FF); printf("SUPER = %u\n", (word2 >> 1) & 0x1); printf("MCAST_FWD_STATE = %u\n", (word1 >> 30) & 0x3); printf("ENTRY_TYPE = %u\n", (word1 >> 28) & 0x3); printf("VLAN_ID = %u\n", (word1 >> 16) & 0xFFF); printf("MULTICAST_ADDR = %x %x\n", (word1 >> 0) & 0xFFFF, word0); } void show_ale_entry_vlan_multicast_9g(uint32_t index, uint32_t word0, uint32_t word1, uint32_t word2) { printf("---------------------------------------------\n"); printf(" Entry %u - VLAN/Multicast\n", index); printf("---------------------------------------------\n"); printf("PORT_MASK = %x\n", (word2 >> 2) & 0x1FF); printf("SUPER = %u\n", (word2 >> 1) & 0x1); printf("MCAST_FWD_STATE = %u\n", (word1 >> 30) & 0x3); printf("ENTRY_TYPE = %u\n", (word1 >> 28) & 0x3); printf("VLAN_ID = %u\n", (word1 >> 16) & 0xFFF); printf("MULTICAST_ADDR = %x %x\n", (word1 >> 0) & 0xFFFF, word0); } void show_ale_entry_unicast_2g(uint32_t index, uint32_t word0, uint32_t word1, uint32_t word2) { printf("---------------------------------------------\n"); printf(" Entry %u - Unicast\n", index); printf("---------------------------------------------\n"); printf("PORT_NUMBER = %u\n", (word2 >> 2) & 0x1FF); printf("BLOCK = %u\n", (word2 >> 1) & 0x1); printf("SECURE = %u\n", (word2 >> 0) & 0x1); printf("UNICAST_TYPE = %u\n", (word1 >> 30) & 0x3); printf("ENTRY_TYPE = %u\n", (word1 >> 28) & 0x3); printf("UNICAST_ADDR = %x %x\n", (word1 >> 0) & 0xFFFF, word0); } void show_ale_entry_unicast_9g(uint32_t index, uint32_t word0, uint32_t word1, uint32_t word2) { printf("---------------------------------------------\n"); printf(" Entry %u - Unicast\n", index); printf("---------------------------------------------\n"); printf("TRUNK = %u\n", (word2 >> 10) & 0x1); printf("PORT_NUMBER = %u\n", (word2 >> 2) & 0xF); printf("BLOCK = %u\n", (word2 >> 1) & 0x1); printf("SECURE = %u\n", (word2 >> 0) & 0x1); printf("TOUCH = %u\n", (word1 >> 31) & 0x1); printf("AGEABLE = %u\n", (word1 >> 30) & 0x1); printf("ENTRY_TYPE = %u\n", (word1 >> 28) & 0x3); printf("UNICAST_ADDR = %x %x\n", (word1 >> 0) & 0xFFFF, word0); } void show_ale_entry_oui_unicast_2g(uint32_t index, uint32_t word0, uint32_t word1, uint32_t word2) { printf("---------------------------------------------\n"); printf(" Entry %u - OUI Unicast\n", index); printf("---------------------------------------------\n"); printf("UNICAST_TYPE = %u\n", (word1 >> 30) & 0x3); printf("ENTRY_TYPE = %u\n", (word1 >> 28) & 0x3); printf("UNICAST_OUI = %x %x\n", (word1 >> 0) & 0xFFFF, (word0 >> 24) & 0xFF); } void show_ale_entry_oui_unicast_9g(uint32_t index, uint32_t word0, uint32_t word1, uint32_t word2) { printf("---------------------------------------------\n"); printf(" Entry %u - OUI Unicast\n", index); printf("---------------------------------------------\n"); printf("ENTRY_TYPE = %u\n", (word1 >> 28) & 0x3); printf("UNICAST_OUI = %x %x\n", (word1 >> 0) & 0xFFFF, (word0 >> 24) & 0xFF); } void show_ale_entry_vlan_unicast_2g(uint32_t index, uint32_t word0, uint32_t word1, uint32_t word2) { printf("---------------------------------------------\n"); printf(" Entry %u - VLAN/Unicast\n", index); printf("---------------------------------------------\n"); printf("PORT_NUMBER = %u\n", (word2 >> 2) & 0x1FF); printf("BLOCK = %u\n", (word2 >> 1) & 0x1); printf("SECURE = %u\n", (word2 >> 0) & 0x1); printf("UNICAST_TYPE = %u\n", (word1 >> 30) & 0x3); printf("ENTRY_TYPE = %u\n", (word1 >> 28) & 0x3); printf("VLAN_ID = %u\n", (word1 >> 16) & 0xFFF); printf("UNICAST_ADDR = %x %x\n", (word1 >> 0) & 0xFFFF, word0); } void show_ale_entry_vlan_unicast_9g(uint32_t index, uint32_t word0, uint32_t word1, uint32_t word2) { printf("---------------------------------------------\n"); printf(" Entry %u - VLAN/Unicast\n", index); printf("---------------------------------------------\n"); printf("TRUNK = %u\n", (word2 >> 10) & 0x1); printf("PORT_NUMBER = %u\n", (word2 >> 2) & 0x1FF); printf("BLOCK = %u\n", (word2 >> 1) & 0x1); printf("TOUCH = %u\n", (word1 >> 31) & 0x1); printf("AGEABLE = %u\n", (word1 >> 30) & 0x1); printf("SECURE = %u\n", (word2 >> 0) & 0x1); printf("ENTRY_TYPE = %u\n", (word1 >> 28) & 0x3); printf("VLAN_ID = %u\n", (word1 >> 16) & 0xFFF); printf("UNICAST_ADDR = %x %x\n", (word1 >> 0) & 0xFFFF, word0); } void show_ale_entry_vlan_2g(uint32_t index, uint32_t word0, uint32_t word1, uint32_t word2) { printf("---------------------------------------------\n"); printf(" Entry %u - VLAN\n", index); printf("---------------------------------------------\n"); printf("ENTRY_TYPE = %u\n", (word1 >> 28) & 0x3); printf("VLAN_ID = %u\n", (word1 >> 16) & 0xFFF); printf("FORCE_UNTAG_EG = %u\n", (word0 >> 24) & 0x1FF); printf("REG_MCAST_FLOOD = %u\n", (word0 >> 16) & 0x1FF); printf("UNREG_MCAST_FLOOD = %u\n", (word0 >> 8) & 0x1FF); printf("VLAN_MEMBER_LIST = %u\n", (word0 >> 0) & 0x1FF); } void show_ale_entry_vlan_inner_9g(uint32_t index, uint32_t word0, uint32_t word1, uint32_t word2) { printf("---------------------------------------------\n"); printf(" Entry %u - VLAN INNER \n", index); printf("---------------------------------------------\n"); printf("ENTRY_TYPE = %u\n", (word1 >> 28) & 0x3); printf("IVLAN_ID = %u\n", (word1 >> 16) & 0xFFF); printf("NO FRAG = %u\n", (word1 >> 15) & 0x1); printf("REG_MCAST_FLOOD = %u\n", (word1 >> 4) & 0x1FF); printf("VLAN FWD Untagged Egress = %u\n", ((word1 >> 0U) << 0x100) + (word0 >> 24) & 0x1FF); printf("LMT NEXT HDR = %u\n", (word0 >> 23) & 0x1); printf("UNREG_MCAST_FLOOD = %u\n", (word0 >> 12) & 0x1FF); printf("VLAN_MEMBER_LIST = %u\n", (word0 >> 0) & 0x1FF); } void show_ale_entry_vlan_outer_9g(uint32_t index, uint32_t word0, uint32_t word1, uint32_t word2) { printf("---------------------------------------------\n"); printf(" Entry %u - VLAN OUTER\n", index); printf("---------------------------------------------\n"); printf("ENTRY_TYPE = %u\n", (word1 >> 28) & 0x3); printf("OVLAN_ID = %u\n", (word1 >> 16) & 0xFFF); printf("NO FRAG = %u\n", (word1 >> 15) & 0x1); printf("REG_MCAST_FLOOD = %u\n", (word1 >> 4) & 0x1FF); printf("VLAN FWD Untagged Egress = %u\n", ((word1 >> 0U) << 0x100) + (word0 >> 24) & 0x1FF); printf("LMT NEXT HDR = %u\n", (word0 >> 23) & 0x1); printf("UNREG_MCAST_FLOOD = %u\n", (word0 >> 12) & 0x1FF); printf("VLAN_MEMBER_LIST = %u\n", (word0 >> 0) & 0x1FF); } void show_ale_entry_vlan_ethertype_9g(uint32_t index, uint32_t word0, uint32_t word1, uint32_t word2) { printf("---------------------------------------------\n"); printf(" Entry %u - VLAN ETHERTYPE \n", index); printf("---------------------------------------------\n"); printf("ENTRY_TYPE = %u\n", (word1 >> 28) & 0x3); printf("ETHERTYPE = %u\n", (word0 >> 0) & 0xFFFF); } void show_ale_entry_vlan_ip4_9g(uint32_t index, uint32_t word0, uint32_t word1, uint32_t word2) { printf("---------------------------------------------\n"); printf(" Entry %u - VLAN IPV4 \n", index); printf("---------------------------------------------\n"); printf("IGNORE BITS = %u\n", (word2 >> 1) & 0x1F); printf("ENTRY_TYPE = %u\n", (word1 >> 28) & 0x3); printf("IPV4 ADDR = %u\n", word0); } void show_ale_entry_vlan_ip6_9g(uint32_t index, uint32_t word0, uint32_t word1, uint32_t word2) { printf("---------------------------------------------\n"); printf(" Entry %u - VLAN IPV6 \n", index); printf("---------------------------------------------\n"); printf("Understanding Gap hence not printing :("); } void cpsw_print_ale_table_2g() { uint32_t word0, word1, word2; uint32_t type; int i; printf("---------------------------------------------\n"); printf("-------CPSW2G ALE TABLE----------------------\n"); printf("---------------------------------------------\n"); for (i = 0; i < ALE_TABLE_DEPTH_2G; i++) { mmio_write_32(ALE_TBLCTL_2G, i); word0 = mmio_read_32(ALE_TBLW0_2G); word1 = mmio_read_32(ALE_TBLW1_2G); word2 = mmio_read_32(ALE_TBLW2_2G); if (0) { printf("WORD1 = %u\n", word0); printf("WORD1 = %u\n", word1); printf("WORD1 = %u\n", word2); } /* ENTRY_TYPE (bits 61:60) */ type = (word1 >> 28) & 0x3; if (type == ALE_ENTRY_EMTPY) { //printf(" Entry %u - Empty\n", i); } else if (type == ALE_ENTRY_ADDR) { if ((word1 >> 8) & 0x1) { show_ale_entry_multicast_2g(i, word0, word1, word2); // } else if ((word1 >> 30) & 0x3) { // show_ale_entry_oui_unicast(i, word0, word1, word2); } else { show_ale_entry_unicast_2g(i, word0, word1, word2); } } else if (type == ALE_ENTRY_VLAN) { show_ale_entry_vlan_2g(i, word0, word1, word2); } else if (type == ALE_ENTRY_VLAN_ADDR) { if ((word1 >> 8) & 0x1) { show_ale_entry_vlan_multicast_2g(i, word0, word1, word2); } else { show_ale_entry_vlan_unicast_2g(i, word0, word1, word2); } } } printf("Completed analysis of %u ALE entries\n", i); } void cpsw_print_ale_table_ng(numAleEntries) { uint32_t word0, word1, word2; uint32_t type; uint32_t vlanEntryType; int i; printf("---------------------------------------------\n"); printf("-------CPSWnG ALE TABLE----------------------\n"); printf("---------------------------------------------\n"); for (i = 0; i < numAleEntries; i++) { mmio_write_32(ALE_TBLCTL_9G, i); word0 = mmio_read_32(ALE_TBLW0_9G); word1 = mmio_read_32(ALE_TBLW1_9G); word2 = mmio_read_32(ALE_TBLW2_9G); if (0) { printf("WORD0 = %x\n", word0); printf("WORD1 = %x\n", word1); printf("WORD2 = %x\n", word2); } /* ENTRY_TYPE (bits 61:60) */ type = (word1 >> 28) & 0x3; if (type == ALE_ENTRY_EMTPY) { //printf(" Entry %u - Empty\n", i); } else if (type == ALE_ENTRY_ADDR) { if ((word1 >> 8) & 0x1) { show_ale_entry_multicast_9g(i, word0, word1, word2); } else if ( ((word1 >> 30) & 0x3) == 0x2 ) { show_ale_entry_oui_unicast_9g(i, word0, word1, word2); } else { show_ale_entry_unicast_9g(i, word0, word1, word2); } } else if (type == ALE_ENTRY_VLAN) { vlanEntryType = ((word1 >> 30) & 0x3); vlanEntryType |= ((word2 >> 0) & 0x1); if ( 0x0 == vlanEntryType) { show_ale_entry_vlan_inner_9g(i, word0, word1, word2); } else if ( 0x2 == vlanEntryType) { show_ale_entry_vlan_outer_9g(i, word0, word1, word2); } else if ( 0x4 == vlanEntryType) { show_ale_entry_vlan_ethertype_9g(i, word0, word1, word2); } else if ( 0x6 == vlanEntryType ) { show_ale_entry_vlan_ip4_9g(i, word0, word1, word2); } else if ((word1 >> 30) & 0x1) { show_ale_entry_vlan_ip6_9g(i, word0, word1, word2); } } else if (type == ALE_ENTRY_VLAN_ADDR) { if ((word1 >> 8) & 0x1) { show_ale_entry_vlan_multicast_9g(i, word0, word1, word2); } else { show_ale_entry_vlan_unicast_9g(i, word0, word1, word2); } } } printf("Completed analysis of %u ALE entries\n", i); } void cpsw_print_ale_table_5g() { cpsw_print_ale_table_ng(ALE_TABLE_DEPTH_5G); } void cpsw_print_ale_table_9g() { cpsw_print_ale_table_ng(ALE_TABLE_DEPTH_9G); } void cpsw_ng_clear_stats(uint32_t numMacPorts) { uint32_t portnum, baseAddr, numStats; for (portnum = 0; portnum <= numMacPorts; portnum++) { baseAddr = 0x0C03A000U + (portnum * 0x200); printf("Clearing stats for port[%d]\n",portnum); for (numStats = 0; numStats < 128U; numStats++) { cpsw_clear_stat(baseAddr + (numStats*0x4)); } } printf("--------CLEARED ALL STATS-------\n"); } void cpsw_5g_clear_stats() { cpsw_ng_clear_stats(CPSW_5G_PORT_NUM); } void cpsw_9g_clear_stats() { cpsw_ng_clear_stats(CPSW_9G_PORT_NUM); } int main() { //cpsw_9g_statsprint_nonzero(); cpsw_print_ale_table_5g(); }
This file needs to be compiled on the device using GCC and executed. It has functions for various tasks, from print statistics to printing ALE entries.
Regards
Vineet
Please find the updated VLAN patch for SDK 8.4 and it has fixed the following issues.
From ab6202a076f88e0990e4e782ca8b9b53dfc5e423 Mon Sep 17 00:00:00 2001 From: Sudheer Doredla <s-doredla@ti.com> Date: Wed, 4 Jan 2023 17:30:17 +0530 Subject: [PATCH] Vlan Configuration Signed-off-by: Sudheer Doredla <s-doredla@ti.com> --- .../app_remoteswitchcfg_server/mcu_2_0/main.c | 180 ++++++++++++++++++ ethfw/ethfw/ethfw.h | 37 ++++ ethfw/ethfw/src/ethfw.c | 22 +++ .../server/include/cpsw_proxy_server.h | 37 ++++ .../server/src/cpsw_proxy_server.c | 33 ++++ 5 files changed, 309 insertions(+) diff --git a/ethfw/apps/app_remoteswitchcfg_server/mcu_2_0/main.c b/ethfw/apps/app_remoteswitchcfg_server/mcu_2_0/main.c index 67b866e7..3b792d67 100644 --- a/ethfw/apps/app_remoteswitchcfg_server/mcu_2_0/main.c +++ b/ethfw/apps/app_remoteswitchcfg_server/mcu_2_0/main.c @@ -218,6 +218,8 @@ * 1 x MAC address for mcu2_1 virtual switch port (AUTOSAR) */ #define ETHAPP_MAC_ADDR_POOL_SIZE (6U) +#define TEST_VID_A72 (100U) + /* Define A72_QNX_OS if A72 is running Qnx. Qnx doesn't load resource table. */ /* #define A72_QNX_OS */ @@ -265,6 +267,14 @@ typedef struct /* Function Declarations */ /* ========================================================================== */ +static int32_t EthApp_addRemoteCoreStaticCfg(Enet_Handle hEnet, + uint32_t coreId, + uint32_t flowId); + +static void EthApp_delRemoteCoreStaticCfg(Enet_Handle hEnet, + uint32_t coreId, + uint32_t flowId); + void appLogPrintf(const char *format, ...); static void EthApp_waitForDebugger(void); @@ -854,6 +864,10 @@ static int32_t EthApp_initEthFw(void) } } + /* Set static configuration functions */ + ethFwCfg.addStaticCfg = &EthApp_addRemoteCoreStaticCfg; + ethFwCfg.delStaticCfg = &EthApp_delRemoteCoreStaticCfg; + /* Initialize the EthFw */ if (status == ETHAPP_OK) { @@ -877,6 +891,172 @@ static int32_t EthApp_initEthFw(void) return status; } +static int32_t EthApp_addMpu10StaticCfg(Enet_Handle hEnet, + uint32_t coreId, + uint32_t flowId) +{ + CpswAle_SetPolicerEntryInArgs polInArgs; + CpswAle_SetPolicerEntryOutArgs polOutArgs; + Enet_IoctlPrms prms; + int32_t status; + + CpswAle_VlanEntryInfo inArgs; + uint32_t outArgs; + + /* Add VLAN entry */ + memset(&inArgs, 0U, sizeof (CpswAle_VlanEntryInfo)); + inArgs.vlanIdInfo.vlanId = TEST_VID_A72; + inArgs.vlanIdInfo.tagType = ENET_VLAN_TAG_TYPE_INNER; + inArgs.vlanMemberList = (1 << CPSW_ALE_MACPORT_TO_ALEPORT(ENET_MAC_PORT_3)) | CPSW_ALE_HOST_PORT_MASK; + inArgs.unregMcastFloodMask = (1 << CPSW_ALE_MACPORT_TO_ALEPORT(ENET_MAC_PORT_3)) | CPSW_ALE_HOST_PORT_MASK; + inArgs.regMcastFloodMask = (1 << CPSW_ALE_MACPORT_TO_ALEPORT(ENET_MAC_PORT_3)) | CPSW_ALE_HOST_PORT_MASK; + inArgs.forceUntaggedEgressMask = 0; + inArgs.noLearnMask = 0U; + inArgs.vidIngressCheck = true; + inArgs.limitIPNxtHdr = false; + inArgs.disallowIPFrag = false; + + ENET_IOCTL_SET_INOUT_ARGS(&prms, &inArgs, &outArgs); + + status = Enet_ioctl(hEnet, gEthAppObj.coreId, CPSW_ALE_IOCTL_ADD_VLAN, &prms); + if (status != ENET_SOK) + { + appLogPrintf("%s() failed ADD_VLAN ioctl failed: %d\n", __func__, status); + } + + polInArgs.policerMatch.policerMatchEnMask = 0U; + + /* Add policer entry for port 1 and dstmac */ + polInArgs.policerMatch.policerMatchEnMask = CPSW_ALE_POLICER_MATCH_PORT; + polInArgs.policerMatch.portNum = CPSW_ALE_MACPORT_TO_ALEPORT(ENET_MAC_PORT_3); + polInArgs.policerMatch.portIsTrunk = false; + + polInArgs.policerMatch.policerMatchEnMask |= CPSW_ALE_POLICER_MATCH_IVLAN; + polInArgs.policerMatch.ivlanId = TEST_VID_A72; + + polInArgs.threadIdEn = true; + polInArgs.threadId = flowId; + polInArgs.peakRateInBitsPerSec = 0U; + polInArgs.commitRateInBitsPerSec = 0U; + + ENET_IOCTL_SET_INOUT_ARGS(&prms, &polInArgs, &polOutArgs); + + status = Enet_ioctl(hEnet, gEthAppObj.coreId, CPSW_ALE_IOCTL_SET_POLICER, &prms); + if (status != ENET_SOK) + { + appLogPrintf("Failed to register PORT3 | VLAN policer: %d\n", status); + } + return status; +} + +static void EthApp_delMpu10StaticCfg(Enet_Handle hEnet, + uint32_t coreId, + uint32_t flowId) +{ + CpswAle_DelPolicerEntryInArgs polInArgs; + Enet_IoctlPrms prms; + int32_t status; + + CpswAle_PolicerEntryOutArgs polOutArgs; + CpswAle_PolicerMatchParams policerMatch; + + CpswAle_VlanEntryInfo inArgs; + + + polInArgs.policerMatch.policerMatchEnMask = 0U; + + /* Delete policer entry for port 1 and dstmac */ + polInArgs.policerMatch.policerMatchEnMask = CPSW_ALE_POLICER_MATCH_PORT; + polInArgs.policerMatch.portNum = CPSW_ALE_MACPORT_TO_ALEPORT(ENET_MAC_PORT_3); + polInArgs.policerMatch.portIsTrunk = false; + + polInArgs.policerMatch.policerMatchEnMask |= CPSW_ALE_POLICER_MATCH_IVLAN; + polInArgs.policerMatch.ivlanId = TEST_VID_A72; + + polInArgs.aleEntryMask = CPSW_ALE_POLICER_MATCH_PORT; + polInArgs.policerMatch.portNum = CPSW_ALE_MACPORT_TO_ALEPORT(ENET_MAC_PORT_3); + ENET_IOCTL_SET_IN_ARGS(&prms, &polInArgs); + + status = Enet_ioctl(hEnet, gEthAppObj.coreId, CPSW_ALE_IOCTL_DEL_POLICER, &prms); + if (status != ENET_SOK) + { + appLogPrintf("Failed to delete PORT3 | VLAN policer: %d\n", status); + } + + /* Check if any policer entry is available with VLAN entry*/ + memset(&policerMatch, 0, sizeof(policerMatch)); + + policerMatch.policerMatchEnMask = CPSW_ALE_POLICER_MATCH_PORT; + policerMatch.portNum = CPSW_ALE_MACPORT_TO_ALEPORT(ENET_MAC_PORT_3); + policerMatch.portIsTrunk = false; + + policerMatch.policerMatchEnMask |= CPSW_ALE_POLICER_MATCH_IVLAN; + policerMatch.ivlanId = TEST_VID_A72; + + ENET_IOCTL_SET_INOUT_ARGS(&prms, &policerMatch, &polOutArgs); + + status = Enet_ioctl(hEnet, gEthAppObj.coreId, CPSW_ALE_IOCTL_GET_POLICER, &prms); + + /* Delete VLAN entry when no policer dependes on VLAN entry*/ + if(status != ENET_SOK) + { + memset(&inArgs, 0U, sizeof (CpswAle_VlanEntryInfo)); + inArgs.vlanIdInfo.vlanId = TEST_VID_A72; + inArgs.vlanIdInfo.tagType = ENET_VLAN_TAG_TYPE_INNER; + + ENET_IOCTL_SET_IN_ARGS(&prms, &inArgs); + + status = Enet_ioctl(hEnet, gEthAppObj.coreId, CPSW_ALE_IOCTL_REMOVE_VLAN, &prms); + + if (status != ENET_SOK) + { + appLogPrintf("Failed to delete VLAN entry: %d\n", status); + } + } + else + { + appLogPrintf("Found policer depends on VLAN entry, keeping entry: %d\n", status); + } + +} + + +static int32_t EthApp_addRemoteCoreStaticCfg(Enet_Handle hEnet, + uint32_t coreId, + uint32_t flowId) +{ + int32_t status = ENET_SOK; + + switch (coreId) + { + case IPC_MPU1_0: + appLogPrintf("Add static config for mpu1_0\n"); + status = EthApp_addMpu10StaticCfg(hEnet, coreId, flowId); + break; + + default: + break; + } + + return status; +} + +static void EthApp_delRemoteCoreStaticCfg(Enet_Handle hEnet, + uint32_t coreId, + uint32_t flowId) +{ + switch (coreId) + { + case IPC_MPU1_0: + appLogPrintf("Delete static config for mpu1_0\n"); + EthApp_delMpu10StaticCfg(hEnet, coreId, flowId); + break; + + default: + break; + } +} + static int32_t EthApp_initRemoteServices(void) { int32_t status; diff --git a/ethfw/ethfw/ethfw.h b/ethfw/ethfw/ethfw.h index 3efe2ede..af441fe1 100644 --- a/ethfw/ethfw/ethfw.h +++ b/ethfw/ethfw/ethfw.h @@ -260,6 +260,35 @@ typedef int32_t (*EthFw_setPortCfg)(Enet_MacPort macPort, EnetPhy_Cfg *phyCfg, EnetMacPort_LinkCfg *linkCfg); +/*! + * \brief Add static configuration. + * + * Add static configuration that is applicable only to specific remote cores. + * + * \param hEnet Handle to Enet LLD + * \param coreId Remote core's IPC core id + * \param flowId Remote core's flow id + * + * \return 0 if no error. Negative value otherwise. + */ +typedef int32_t (*EthFw_addStaticCfg)(Enet_Handle hEnet, + uint32_t coreId, + uint32_t flowId); + +/*! + * \brief Delete static configuration. + * + * Delete static configuration that is applicable only to specific remote cores. + * + * \param hEnet Handle to Enet LLD + * \param coreId Remote core's IPC core id + * \param flowId Remote core's flow id + */ +typedef void (*EthFw_delStaticCfg)(Enet_Handle hEnet, + uint32_t coreId, + uint32_t flowId); + + /*! * \brief Ethernet Firmware configuration * @@ -307,6 +336,14 @@ typedef struct EthFw_Config_s /*! Callback function for application to set port link parameters * (MII, PHY, speed, duplexity, etc) */ EthFw_setPortCfg setPortCfg; + + + /* Add static configuration that is applicable only to specific remote cores */ + EthFw_addStaticCfg addStaticCfg; + + /* Delete static configuration that is applicable only to specific remote cores */ + EthFw_delStaticCfg delStaticCfg; + } EthFw_Config; /*! diff --git a/ethfw/ethfw/src/ethfw.c b/ethfw/ethfw/src/ethfw.c index 72888d4a..dc27d58a 100644 --- a/ethfw/ethfw/src/ethfw.c +++ b/ethfw/ethfw/src/ethfw.c @@ -227,6 +227,13 @@ typedef struct EthFw_Obj_s /*! Callback function for application to set port link parameters */ EthFw_setPortCfg setPortCfg; + + /* Add static configuration that is applicable only to specific remote cores */ + EthFw_addStaticCfg addStaticCfg; + + /* Delete static configuration that is applicable only to specific remote cores */ + EthFw_delStaticCfg delStaticCfg; + } EthFw_Obj; /* ========================================================================== */ @@ -812,6 +819,11 @@ void EthFw_initConfigParams(Enet_Type enetType, memset(config, 0, sizeof(*config)); + /* Initialize Static config function pointers */ + config->addStaticCfg = NULL; + config->delStaticCfg = NULL; + + /* MAC port ownership */ config->ports = NULL; config->numPorts = 0U; @@ -874,6 +886,11 @@ EthFw_Handle EthFw_init(Enet_Type enetType, memset(&gEthFwObj, 0, sizeof(gEthFwObj)); + /* Save static config function pointers */ + gEthFwObj.addStaticCfg = config->addStaticCfg; + gEthFwObj.delStaticCfg = config->delStaticCfg; + + /* Save config parameters */ gEthFwObj.cpswCfg = config->cpswCfg; @@ -1083,6 +1100,11 @@ int32_t EthFw_initRemoteConfig(EthFw_Handle hEthFw) cfg.dfltVlanIdMacOnlyPorts = gEthFwObj.dfltVlanIdMacOnlyPorts; cfg.dfltVlanIdSwitchPorts = gEthFwObj.dfltVlanIdSwitchPorts; + /* Static configuration callbacks */ + cfg.addStaticCfg = gEthFwObj.addStaticCfg; + cfg.delStaticCfg = gEthFwObj.delStaticCfg; + + status = CpswProxyServer_init(&cfg); if (status != ENET_SOK) { diff --git a/ethfw/ethremotecfg/server/include/cpsw_proxy_server.h b/ethfw/ethremotecfg/server/include/cpsw_proxy_server.h index cc220666..4eabafc3 100644 --- a/ethfw/ethremotecfg/server/include/cpsw_proxy_server.h +++ b/ethfw/ethremotecfg/server/include/cpsw_proxy_server.h @@ -291,6 +291,36 @@ typedef struct CpswProxyServer_RsvdMcastCfg_s uint32_t numMacAddr; } CpswProxyServer_RsvdMcastCfg; +/*! + * \brief Add static configuration. + * + * Add static configuration that is applicable only to specific remote cores. + * + * \param hEnet Handle to Enet LLD + * \param coreId Remote core's IPC core id + * \param flowId Remote core's flow id + * + * \return 0 if no error. Negative value otherwise. + */ +typedef int32_t (*CpswProxyServer_addStaticCfg)(Enet_Handle hEnet, + uint32_t coreId, + uint32_t flowId); + +/*! + * \brief Delete static configuration. + * + * Delete static configuration that is applicable only to specific remote cores. + * + * \param hEnet Handle to Enet LLD + * \param coreId Remote core's IPC core id + * \param flowId Remote core's flow id + */ +typedef void (*CpswProxyServer_delStaticCfg)(Enet_Handle hEnet, + uint32_t coreId, + uint32_t flowId); + + + /*! * \brief Cpsw Proxy Server Remote Configuration structure * @@ -349,6 +379,13 @@ typedef struct CpswProxyServer_Config_s /*! Reserved multicast configuration */ CpswProxyServer_RsvdMcastCfg rsvdMcastCfg; + + /* Add static configuration that is applicable only to specific remote cores */ + CpswProxyServer_addStaticCfg addStaticCfg; + + /* Delete static configuration that is applicable only to specific remote cores */ + CpswProxyServer_delStaticCfg delStaticCfg; + } CpswProxyServer_Config_t; /*! diff --git a/ethfw/ethremotecfg/server/src/cpsw_proxy_server.c b/ethfw/ethremotecfg/server/src/cpsw_proxy_server.c index 497c2043..76f92c6f 100644 --- a/ethfw/ethremotecfg/server/src/cpsw_proxy_server.c +++ b/ethfw/ethremotecfg/server/src/cpsw_proxy_server.c @@ -189,6 +189,14 @@ typedef struct CpswProxyServer_Obj_s CpswProxyServer_SharedMcastTable sharedMcastTbl; CpswProxyServer_FilterAddMacSharedCb filterAddMacSharedCb; CpswProxyServer_FilterDelMacSharedCb filterDelMacSharedCb; + + + /* Add static configuration that is applicable only to specific remote cores */ + CpswProxyServer_addStaticCfg addStaticCfg; + + /* Delete static configuration that is applicable only to specific remote cores */ + CpswProxyServer_delStaticCfg delStaticCfg; + uint32_t alePortMask; uint32_t aleMacOnlyPortMask; uint16_t dfltVlanIdMacOnlyPorts; @@ -758,6 +766,18 @@ static int32_t CpswProxyServer_registerMacHandlerCb(EthRemoteCfg_VirtPort virtPo flow_idx_offset); } + if (ENET_SOK == status) + { + if (hProxyServer->addStaticCfg != NULL) + { + status = hProxyServer->addStaticCfg(hEnet, host_id, flow_idx_offset); + if (ENET_SOK != status) + { + appLogPrintf("Failed to add static config for coreId=%u: %d\n", host_id, status); + } + } + } + return CPSWPROXY_ENET2RPMSG_ERR(status); } @@ -768,12 +788,15 @@ static int32_t CpswProxyServer_unregisterMacHandlerCb(EthRemoteCfg_VirtPort virt u8 *mac_address, uint32_t flow_idx) { + CpswProxyServer_Obj *hProxyServer; Enet_Handle hEnet = (Enet_Handle)((uintptr_t)handle); Enet_MacPort macPort = EthRemoteCfg_getMacPort(virtPort); bool isSwitchPort = EthRemoteCfg_isSwitchPort(virtPort); uint32_t start_flow_idx, flow_idx_offset; int32_t status; + hProxyServer = CpswProxyServer_getHandle(); + CpswProxyServer_validateHandle(hEnet); EnetAppUtils_absFlowIdx2FlowIdxOffset(hEnet, host_id, flow_idx, &start_flow_idx, &flow_idx_offset); appLogPrintf("Function:%s,HostId:%u,Handle:%p,CoreKey:%x, MacAddress:%x:%x:%x:%x:%x:%x, FlowIdx:%u, FlowIdOffset:%u\n", @@ -808,6 +831,13 @@ static int32_t CpswProxyServer_unregisterMacHandlerCb(EthRemoteCfg_VirtPort virt start_flow_idx, flow_idx_offset); } + if (ENET_SOK == status) + { + if (hProxyServer->delStaticCfg != NULL) + { + hProxyServer->delStaticCfg(hEnet, host_id, flow_idx_offset); + } + } return CPSWPROXY_ENET2RPMSG_ERR(status); } @@ -2423,6 +2453,9 @@ int32_t CpswProxyServer_init(CpswProxyServer_Config_t *cfg) appLogPrintf("CpswProxyServer: initialization %s (core: mcu2_0)\r\n", (status == CPSWPROXYSERVER_SOK) ? "completed" : "failed"); + hProxyServer->addStaticCfg = cfg->addStaticCfg; + hProxyServer->delStaticCfg = cfg->delStaticCfg; + return status; } -- 2.17.1
Regards,
Sudheer
See this reference patch for Ethernet Firmware (On top of SDK 8.6) for adding a static Unicast MAC Address entry for A72 core.
From f11ac5c9c5ee404c78f46f9273a190111f70fec9 Mon Sep 17 00:00:00 2001 From: Doredla Sudheer Kumar <s-doredla@ti.com> Date: Tue, 18 Apr 2023 15:53:43 +0530 Subject: [PATCH] Adding a Unicast Destination MAC Address entry for A72 on Port 2 Signed-off-by: Doredla Sudheer Kumar <s-doredla@ti.com> --- .../app_remoteswitchcfg_server/mcu_2_0/main.c | 176 ++++++++++++++++++ ethfw/ethfw/ethfw.h | 36 ++++ ethfw/ethfw/src/ethfw.c | 19 ++ .../server/include/cpsw_proxy_server.h | 35 ++++ .../server/src/cpsw_proxy_server.c | 28 +++ 5 files changed, 294 insertions(+) diff --git a/ethfw/apps/app_remoteswitchcfg_server/mcu_2_0/main.c b/ethfw/apps/app_remoteswitchcfg_server/mcu_2_0/main.c index 75f18755..441b7011 100644 --- a/ethfw/apps/app_remoteswitchcfg_server/mcu_2_0/main.c +++ b/ethfw/apps/app_remoteswitchcfg_server/mcu_2_0/main.c @@ -275,6 +275,14 @@ typedef struct /* Function Declarations */ /* ========================================================================== */ +static int32_t EthApp_addRemoteCoreStaticCfg(Enet_Handle hEnet, + uint32_t coreId, + uint32_t flowId); + +static void EthApp_delRemoteCoreStaticCfg(Enet_Handle hEnet, + uint32_t coreId, + uint32_t flowId); + void appLogPrintf(const char *format, ...); static void EthApp_waitForDebugger(void); @@ -882,6 +890,10 @@ static int32_t EthApp_initEthFw(void) } } + /* Set static configuration functions */ + ethFwCfg.addStaticCfg = &EthApp_addRemoteCoreStaticCfg; + ethFwCfg.delStaticCfg = &EthApp_delRemoteCoreStaticCfg; + /* Initialize the EthFw */ if (status == ETHAPP_OK) { @@ -905,6 +917,170 @@ static int32_t EthApp_initEthFw(void) return status; } +static int32_t EthApp_addMpu10StaticCfg(Enet_Handle hEnet, + uint32_t coreId, + uint32_t flowId) +{ + const uint8_t dstMacAddr[ENET_MAC_ADDR_LEN] = {0x00, 0x01, 0x02, 0x03, 0x04, 0x05}; + CpswAle_SetPolicerEntryInArgs polInArgs; + CpswAle_SetPolicerEntryOutArgs polOutArgs; + CpswAle_SetUcastEntryInArgs ucastInArgs; + Enet_IoctlPrms prms; + uint32_t entry; + int32_t status; + + ucastInArgs.addr.vlanId = 0U; + EnetUtils_copyMacAddr(&ucastInArgs.addr.addr[0], &dstMacAddr[0]); + + ucastInArgs.info.portNum = CPSW_ALE_HOST_PORT_NUM; + ucastInArgs.info.blocked = false; + ucastInArgs.info.secure = false; + ucastInArgs.info.super = false; + ucastInArgs.info.ageable = false; + ucastInArgs.info.trunk = false; + + ENET_IOCTL_SET_INOUT_ARGS(&prms, &ucastInArgs, &entry); + + status = Enet_ioctl(hEnet, gEthAppObj.coreId, CPSW_ALE_IOCTL_ADD_UCAST, &prms); + if (status != ENET_SOK) + { + appLogPrintf("Failed to add ucast entry: %d\n", status); + } + + + polInArgs.policerMatch.policerMatchEnMask = 0U; + + /* Add policer entry for port 2 and dstmac */ + polInArgs.policerMatch.policerMatchEnMask = CPSW_ALE_POLICER_MATCH_PORT; + polInArgs.policerMatch.portNum = CPSW_ALE_MACPORT_TO_ALEPORT(ENET_MAC_PORT_2); + polInArgs.policerMatch.portIsTrunk = false; + + polInArgs.policerMatch.policerMatchEnMask |= CPSW_ALE_POLICER_MATCH_MACDST; + polInArgs.policerMatch.dstMacAddrInfo.portNum = CPSW_ALE_HOST_PORT_NUM; + polInArgs.policerMatch.dstMacAddrInfo.addr.vlanId = 0U; + EnetUtils_copyMacAddr(&polInArgs.policerMatch.dstMacAddrInfo.addr.addr[0], &dstMacAddr[0]); + + polInArgs.threadIdEn = true; + polInArgs.threadId = flowId; + polInArgs.peakRateInBitsPerSec = 0U; + polInArgs.commitRateInBitsPerSec = 0U; + + ENET_IOCTL_SET_INOUT_ARGS(&prms, &polInArgs, &polOutArgs); + + status = Enet_ioctl(hEnet, gEthAppObj.coreId, CPSW_ALE_IOCTL_SET_POLICER, &prms); + if (status != ENET_SOK) + { + appLogPrintf("Failed to register PORT2 | MACDST policer: %d\n", status); + } + + return status; +} + +static void EthApp_delMpu10StaticCfg(Enet_Handle hEnet, + uint32_t coreId, + uint32_t flowId) +{ + const uint8_t dstMacAddr[ENET_MAC_ADDR_LEN] = {0x00, 0x01, 0x02, 0x03, 0x04, 0x05}; + CpswAle_DelPolicerEntryInArgs polInArgs; + CpswAle_PolicerMatchParams policerMatch; + CpswAle_PolicerEntryOutArgs polOutArgs; + Enet_IoctlPrms prms; + int32_t status; + + polInArgs.policerMatch.policerMatchEnMask = 0U; + + /* Delete policer entry for port 2 and dstmac */ + polInArgs.policerMatch.policerMatchEnMask = CPSW_ALE_POLICER_MATCH_PORT; + polInArgs.policerMatch.portNum = CPSW_ALE_MACPORT_TO_ALEPORT(ENET_MAC_PORT_2); + polInArgs.policerMatch.portIsTrunk = false; + + polInArgs.policerMatch.policerMatchEnMask |= CPSW_ALE_POLICER_MATCH_MACDST; + polInArgs.policerMatch.dstMacAddrInfo.portNum = CPSW_ALE_HOST_PORT_NUM; + polInArgs.policerMatch.dstMacAddrInfo.addr.vlanId = 0U; + EnetUtils_copyMacAddr(&polInArgs.policerMatch.dstMacAddrInfo.addr.addr[0], &dstMacAddr[0]); + + polInArgs.aleEntryMask = CPSW_ALE_POLICER_MATCH_PORT; + + ENET_IOCTL_SET_IN_ARGS(&prms, &polInArgs); + + status = Enet_ioctl(hEnet, gEthAppObj.coreId, CPSW_ALE_IOCTL_DEL_POLICER, &prms); + if (status != ENET_SOK) + { + appLogPrintf("Failed to delete PORT2 | MACDST policer: %d\n", status); + } + + /* Check if any policer entry is available with DSTMAC entry*/ + memset(&policerMatch, 0, sizeof(policerMatch)); + + policerMatch.policerMatchEnMask = CPSW_ALE_POLICER_MATCH_PORT; + policerMatch.portNum = CPSW_ALE_MACPORT_TO_ALEPORT(ENET_MAC_PORT_2); + policerMatch.portIsTrunk = false; + + policerMatch.policerMatchEnMask |= CPSW_ALE_POLICER_MATCH_MACDST; + policerMatch.dstMacAddrInfo.portNum = CPSW_ALE_HOST_PORT_NUM; + policerMatch.dstMacAddrInfo.addr.vlanId = 0U; + EnetUtils_copyMacAddr(&policerMatch.dstMacAddrInfo.addr.addr[0], &dstMacAddr[0]); + + ENET_IOCTL_SET_INOUT_ARGS(&prms, &policerMatch, &polOutArgs); + + status = Enet_ioctl(hEnet, gEthAppObj.coreId, CPSW_ALE_IOCTL_GET_POLICER, &prms); + + /* Delete DSTMAC entry when no policer dependes on MAC entry*/ + if(status != ENET_SOK) + { + CpswAle_MacAddrInfo removeInArgs; + EnetUtils_copyMacAddr(&removeInArgs.addr[0U], &dstMacAddr[0U]); + removeInArgs.vlanId = 0; + + ENET_IOCTL_SET_IN_ARGS(&prms, &removeInArgs); + status = Enet_ioctl(hEnet, gEthAppObj.coreId, CPSW_ALE_IOCTL_REMOVE_ADDR, &prms); + if (status != ENET_SOK) + { + appLogPrintf("Failed to remove ucast entry: %d\n", status); + } + } + else + { + appLogPrintf("Found policer depends on DST MAC entry, keeping entry: %d\n", status); + } +} + +static int32_t EthApp_addRemoteCoreStaticCfg(Enet_Handle hEnet, + uint32_t coreId, + uint32_t flowId) +{ + int32_t status = ENET_SOK; + + switch (coreId) + { + case IPC_MPU1_0: + appLogPrintf("Add static config for mpu1_0\n"); + status = EthApp_addMpu10StaticCfg(hEnet, coreId, flowId); + break; + + default: + break; + } + + return status; +} + +static void EthApp_delRemoteCoreStaticCfg(Enet_Handle hEnet, + uint32_t coreId, + uint32_t flowId) +{ + switch (coreId) + { + case IPC_MPU1_0: + appLogPrintf("Delete static config for mpu1_0\n"); + EthApp_delMpu10StaticCfg(hEnet, coreId, flowId); + break; + + default: + break; + } +} + static int32_t EthApp_initRemoteServices(void) { int32_t status; diff --git a/ethfw/ethfw/ethfw.h b/ethfw/ethfw/ethfw.h index 3efe2ede..144794d6 100644 --- a/ethfw/ethfw/ethfw.h +++ b/ethfw/ethfw/ethfw.h @@ -260,6 +260,35 @@ typedef int32_t (*EthFw_setPortCfg)(Enet_MacPort macPort, EnetPhy_Cfg *phyCfg, EnetMacPort_LinkCfg *linkCfg); +/*! + * \brief Add static configuration. + * + * Add static configuration that is applicable only to specific remote cores. + * + * \param hEnet Handle to Enet LLD + * \param coreId Remote core's IPC core id + * \param flowId Remote core's flow id + * + * \return 0 if no error. Negative value otherwise. + */ +typedef int32_t (*EthFw_addStaticCfg)(Enet_Handle hEnet, + uint32_t coreId, + uint32_t flowId); + +/*! + * \brief Delete static configuration. + * + * Delete static configuration that is applicable only to specific remote cores. + * + * \param hEnet Handle to Enet LLD + * \param coreId Remote core's IPC core id + * \param flowId Remote core's flow id + */ +typedef void (*EthFw_delStaticCfg)(Enet_Handle hEnet, + uint32_t coreId, + uint32_t flowId); + + /*! * \brief Ethernet Firmware configuration * @@ -307,6 +336,13 @@ typedef struct EthFw_Config_s /*! Callback function for application to set port link parameters * (MII, PHY, speed, duplexity, etc) */ EthFw_setPortCfg setPortCfg; + + /* Add static configuration that is applicable only to specific remote cores */ + EthFw_addStaticCfg addStaticCfg; + + /* Delete static configuration that is applicable only to specific remote cores */ + EthFw_delStaticCfg delStaticCfg; + } EthFw_Config; /*! diff --git a/ethfw/ethfw/src/ethfw.c b/ethfw/ethfw/src/ethfw.c index 3aa264ed..d2111a55 100644 --- a/ethfw/ethfw/src/ethfw.c +++ b/ethfw/ethfw/src/ethfw.c @@ -227,6 +227,13 @@ typedef struct EthFw_Obj_s /*! Callback function for application to set port link parameters */ EthFw_setPortCfg setPortCfg; + + /* Add static configuration that is applicable only to specific remote cores */ + EthFw_addStaticCfg addStaticCfg; + + /* Delete static configuration that is applicable only to specific remote cores */ + EthFw_delStaticCfg delStaticCfg; + } EthFw_Obj; /* ========================================================================== */ @@ -812,6 +819,10 @@ void EthFw_initConfigParams(Enet_Type enetType, memset(config, 0, sizeof(*config)); + /* Initialize Static config function pointers */ + config->addStaticCfg = NULL; + config->delStaticCfg = NULL; + /* MAC port ownership */ config->ports = NULL; config->numPorts = 0U; @@ -874,6 +885,10 @@ EthFw_Handle EthFw_init(Enet_Type enetType, memset(&gEthFwObj, 0, sizeof(gEthFwObj)); + /* Save static config function pointers */ + gEthFwObj.addStaticCfg = config->addStaticCfg; + gEthFwObj.delStaticCfg = config->delStaticCfg; + /* Save config parameters */ gEthFwObj.cpswCfg = config->cpswCfg; @@ -1083,6 +1098,10 @@ int32_t EthFw_initRemoteConfig(EthFw_Handle hEthFw) cfg.dfltVlanIdMacOnlyPorts = gEthFwObj.dfltVlanIdMacOnlyPorts; cfg.dfltVlanIdSwitchPorts = gEthFwObj.dfltVlanIdSwitchPorts; + /* Static configuration callbacks */ + cfg.addStaticCfg = gEthFwObj.addStaticCfg; + cfg.delStaticCfg = gEthFwObj.delStaticCfg; + status = CpswProxyServer_init(&cfg); if (status != ENET_SOK) { diff --git a/ethfw/ethremotecfg/server/include/cpsw_proxy_server.h b/ethfw/ethremotecfg/server/include/cpsw_proxy_server.h index cc220666..ac0605fc 100644 --- a/ethfw/ethremotecfg/server/include/cpsw_proxy_server.h +++ b/ethfw/ethremotecfg/server/include/cpsw_proxy_server.h @@ -291,6 +291,34 @@ typedef struct CpswProxyServer_RsvdMcastCfg_s uint32_t numMacAddr; } CpswProxyServer_RsvdMcastCfg; +/*! + * \brief Add static configuration. + * + * Add static configuration that is applicable only to specific remote cores. + * + * \param hEnet Handle to Enet LLD + * \param coreId Remote core's IPC core id + * \param flowId Remote core's flow id + * + * \return 0 if no error. Negative value otherwise. + */ +typedef int32_t (*CpswProxyServer_addStaticCfg)(Enet_Handle hEnet, + uint32_t coreId, + uint32_t flowId); + +/*! + * \brief Delete static configuration. + * + * Delete static configuration that is applicable only to specific remote cores. + * + * \param hEnet Handle to Enet LLD + * \param coreId Remote core's IPC core id + * \param flowId Remote core's flow id + */ +typedef void (*CpswProxyServer_delStaticCfg)(Enet_Handle hEnet, + uint32_t coreId, + uint32_t flowId); + /*! * \brief Cpsw Proxy Server Remote Configuration structure * @@ -349,6 +377,13 @@ typedef struct CpswProxyServer_Config_s /*! Reserved multicast configuration */ CpswProxyServer_RsvdMcastCfg rsvdMcastCfg; + + /* Add static configuration that is applicable only to specific remote cores */ + CpswProxyServer_addStaticCfg addStaticCfg; + + /* Delete static configuration that is applicable only to specific remote cores */ + CpswProxyServer_delStaticCfg delStaticCfg; + } CpswProxyServer_Config_t; /*! diff --git a/ethfw/ethremotecfg/server/src/cpsw_proxy_server.c b/ethfw/ethremotecfg/server/src/cpsw_proxy_server.c index 341c4990..2346573c 100644 --- a/ethfw/ethremotecfg/server/src/cpsw_proxy_server.c +++ b/ethfw/ethremotecfg/server/src/cpsw_proxy_server.c @@ -194,6 +194,10 @@ typedef struct CpswProxyServer_Obj_s CpswProxyServer_SharedMcastTable sharedMcastTbl; CpswProxyServer_FilterAddMacSharedCb filterAddMacSharedCb; CpswProxyServer_FilterDelMacSharedCb filterDelMacSharedCb; + /* Add static configuration that is applicable only to specific remote cores */ + CpswProxyServer_addStaticCfg addStaticCfg; + /* Delete static configuration that is applicable only to specific remote cores */ + CpswProxyServer_delStaticCfg delStaticCfg; uint32_t alePortMask; uint32_t aleMacOnlyPortMask; uint16_t dfltVlanIdMacOnlyPorts; @@ -751,6 +755,17 @@ static int32_t CpswProxyServer_registerMacHandlerCb(EthRemoteCfg_VirtPort virtPo { appLogPrintf("EnetAppUtils_regDstMacRxFlow() failed CPSW_ALE_IOCTL_SET_POLICER: %d\n", status); } + if (ENET_SOK == status) + { + if (hProxyServer->addStaticCfg != NULL) + { + status = hProxyServer->addStaticCfg(hEnet, host_id, flow_idx_offset); + if (ENET_SOK != status) + { + appLogPrintf("Failed to add static config for coreId=%u: %d\n", host_id, status); + } + } + } } else { @@ -773,12 +788,15 @@ static int32_t CpswProxyServer_unregisterMacHandlerCb(EthRemoteCfg_VirtPort virt u8 *mac_address, uint32_t flow_idx) { + CpswProxyServer_Obj *hProxyServer; Enet_Handle hEnet = (Enet_Handle)((uintptr_t)handle); Enet_MacPort macPort = EthRemoteCfg_getMacPort(virtPort); bool isSwitchPort = EthRemoteCfg_isSwitchPort(virtPort); uint32_t start_flow_idx, flow_idx_offset; int32_t status; + hProxyServer = CpswProxyServer_getHandle(); + CpswProxyServer_validateHandle(hEnet); EnetAppUtils_absFlowIdx2FlowIdxOffset(hEnet, host_id, flow_idx, &start_flow_idx, &flow_idx_offset); appLogPrintf("Function:%s,HostId:%u,Handle:%p,CoreKey:%x, MacAddress:%x:%x:%x:%x:%x:%x, FlowIdx:%u, FlowIdOffset:%u\n", @@ -802,6 +820,13 @@ static int32_t CpswProxyServer_unregisterMacHandlerCb(EthRemoteCfg_VirtPort virt { appLogPrintf("Failed EnetAppUtils_unregDstMacRxFlow: %d\n", status); } + if (ENET_SOK == status) + { + if (hProxyServer->delStaticCfg != NULL) + { + hProxyServer->delStaticCfg(hEnet, host_id, flow_idx_offset); + } + } } else { @@ -2428,6 +2453,9 @@ int32_t CpswProxyServer_init(CpswProxyServer_Config_t *cfg) appLogPrintf("CpswProxyServer: initialization %s (core: mcu2_0)\r\n", (status == CPSWPROXYSERVER_SOK) ? "completed" : "failed"); + hProxyServer->addStaticCfg = cfg->addStaticCfg; + hProxyServer->delStaticCfg = cfg->delStaticCfg; + return status; } -- 2.17.1
See this reference patch for Ethernet Firmware (On top of SDK 8.6) for adding a static Unicast MAC Address entry for A72 core.
From 5840bd2378fb0eb7d875535b461df14fdbcff65c Mon Sep 17 00:00:00 2001 From: Doredla Sudheer Kumar <s-doredla@ti.com> Date: Tue, 18 Apr 2023 15:53:43 +0530 Subject: [PATCH] Adding a Unicast Destination MAC Address entry for A72 on Port 2 Signed-off-by: Doredla Sudheer Kumar <s-doredla@ti.com> --- .../app_remoteswitchcfg_server/mcu_2_0/main.c | 166 ++++++++++++++++++ ethfw/ethfw/ethfw.h | 36 ++++ ethfw/ethfw/src/ethfw.c | 19 ++ .../server/include/cpsw_proxy_server.h | 35 ++++ .../server/src/cpsw_proxy_server.c | 28 +++ 5 files changed, 284 insertions(+) diff --git a/ethfw/apps/app_remoteswitchcfg_server/mcu_2_0/main.c b/ethfw/apps/app_remoteswitchcfg_server/mcu_2_0/main.c index 75f18755..ccd1c634 100644 --- a/ethfw/apps/app_remoteswitchcfg_server/mcu_2_0/main.c +++ b/ethfw/apps/app_remoteswitchcfg_server/mcu_2_0/main.c @@ -275,6 +275,14 @@ typedef struct /* Function Declarations */ /* ========================================================================== */ +static int32_t EthApp_addRemoteCoreStaticCfg(Enet_Handle hEnet, + uint32_t coreId, + uint32_t flowId); + +static void EthApp_delRemoteCoreStaticCfg(Enet_Handle hEnet, + uint32_t coreId, + uint32_t flowId); + void appLogPrintf(const char *format, ...); static void EthApp_waitForDebugger(void); @@ -882,6 +890,10 @@ static int32_t EthApp_initEthFw(void) } } + /* Set static configuration functions */ + ethFwCfg.addStaticCfg = &EthApp_addRemoteCoreStaticCfg; + ethFwCfg.delStaticCfg = &EthApp_delRemoteCoreStaticCfg; + /* Initialize the EthFw */ if (status == ETHAPP_OK) { @@ -905,6 +917,160 @@ static int32_t EthApp_initEthFw(void) return status; } +static int32_t EthApp_addMpu10StaticCfg(Enet_Handle hEnet, + uint32_t coreId, + uint32_t flowId) +{ + const uint8_t dstMacAddr[ENET_MAC_ADDR_LEN] = {0x00, 0x01, 0x02, 0x03, 0x04, 0x05}; + CpswAle_SetPolicerEntryInArgs polInArgs; + CpswAle_SetPolicerEntryOutArgs polOutArgs; + CpswAle_SetUcastEntryInArgs ucastInArgs; + Enet_IoctlPrms prms; + uint32_t entry; + int32_t status; + + ucastInArgs.addr.vlanId = 0U; + EnetUtils_copyMacAddr(&ucastInArgs.addr.addr[0], &dstMacAddr[0]); + + ucastInArgs.info.portNum = CPSW_ALE_HOST_PORT_NUM; + ucastInArgs.info.blocked = false; + ucastInArgs.info.secure = false; + ucastInArgs.info.super = false; + ucastInArgs.info.ageable = false; + ucastInArgs.info.trunk = false; + + ENET_IOCTL_SET_INOUT_ARGS(&prms, &ucastInArgs, &entry); + + status = Enet_ioctl(hEnet, gEthAppObj.coreId, CPSW_ALE_IOCTL_ADD_UCAST, &prms); + if (status != ENET_SOK) + { + appLogPrintf("Failed to add ucast entry: %d\n", status); + } + + + polInArgs.policerMatch.policerMatchEnMask = 0U; + + /* Add policer entry for unicast dstmac */ + + polInArgs.policerMatch.policerMatchEnMask = CPSW_ALE_POLICER_MATCH_MACDST; + polInArgs.policerMatch.dstMacAddrInfo.portNum = CPSW_ALE_HOST_PORT_NUM; + polInArgs.policerMatch.dstMacAddrInfo.addr.vlanId = 0U; + EnetUtils_copyMacAddr(&polInArgs.policerMatch.dstMacAddrInfo.addr.addr[0], &dstMacAddr[0]); + + polInArgs.threadIdEn = true; + polInArgs.threadId = flowId; + polInArgs.peakRateInBitsPerSec = 0U; + polInArgs.commitRateInBitsPerSec = 0U; + + ENET_IOCTL_SET_INOUT_ARGS(&prms, &polInArgs, &polOutArgs); + + status = Enet_ioctl(hEnet, gEthAppObj.coreId, CPSW_ALE_IOCTL_SET_POLICER, &prms); + if (status != ENET_SOK) + { + appLogPrintf("Failed to register MACDST policer: %d\n", status); + } + + return status; +} + +static void EthApp_delMpu10StaticCfg(Enet_Handle hEnet, + uint32_t coreId, + uint32_t flowId) +{ + const uint8_t dstMacAddr[ENET_MAC_ADDR_LEN] = {0x00, 0x01, 0x02, 0x03, 0x04, 0x05}; + CpswAle_DelPolicerEntryInArgs polInArgs; + CpswAle_PolicerMatchParams policerMatch; + CpswAle_PolicerEntryOutArgs polOutArgs; + Enet_IoctlPrms prms; + int32_t status; + + polInArgs.policerMatch.policerMatchEnMask = 0U; + + /* Delete policer entry for unicast dstmac */ + + polInArgs.policerMatch.policerMatchEnMask = CPSW_ALE_POLICER_MATCH_MACDST; + polInArgs.policerMatch.dstMacAddrInfo.portNum = CPSW_ALE_HOST_PORT_NUM; + polInArgs.policerMatch.dstMacAddrInfo.addr.vlanId = 0U; + EnetUtils_copyMacAddr(&polInArgs.policerMatch.dstMacAddrInfo.addr.addr[0], &dstMacAddr[0]); + + polInArgs.aleEntryMask = CPSW_ALE_POLICER_MATCH_PORT; + + ENET_IOCTL_SET_IN_ARGS(&prms, &polInArgs); + + status = Enet_ioctl(hEnet, gEthAppObj.coreId, CPSW_ALE_IOCTL_DEL_POLICER, &prms); + if (status != ENET_SOK) + { + appLogPrintf("Failed to delete PORT2 | MACDST policer: %d\n", status); + } + + /* Check if any policer entry is available with DSTMAC entry*/ + memset(&policerMatch, 0, sizeof(policerMatch)); + + policerMatch.policerMatchEnMask = CPSW_ALE_POLICER_MATCH_MACDST; + policerMatch.dstMacAddrInfo.portNum = CPSW_ALE_HOST_PORT_NUM; + policerMatch.dstMacAddrInfo.addr.vlanId = 0U; + EnetUtils_copyMacAddr(&policerMatch.dstMacAddrInfo.addr.addr[0], &dstMacAddr[0]); + + ENET_IOCTL_SET_INOUT_ARGS(&prms, &policerMatch, &polOutArgs); + + status = Enet_ioctl(hEnet, gEthAppObj.coreId, CPSW_ALE_IOCTL_GET_POLICER, &prms); + + /* Delete DSTMAC entry when no policer dependes on MAC entry*/ + if(status != ENET_SOK) + { + CpswAle_MacAddrInfo removeInArgs; + EnetUtils_copyMacAddr(&removeInArgs.addr[0U], &dstMacAddr[0U]); + removeInArgs.vlanId = 0; + + ENET_IOCTL_SET_IN_ARGS(&prms, &removeInArgs); + status = Enet_ioctl(hEnet, gEthAppObj.coreId, CPSW_ALE_IOCTL_REMOVE_ADDR, &prms); + if (status != ENET_SOK) + { + appLogPrintf("Failed to remove ucast entry: %d\n", status); + } + } + else + { + appLogPrintf("Found policer depends on DST MAC entry, keeping entry: %d\n", status); + } +} + +static int32_t EthApp_addRemoteCoreStaticCfg(Enet_Handle hEnet, + uint32_t coreId, + uint32_t flowId) +{ + int32_t status = ENET_SOK; + + switch (coreId) + { + case IPC_MPU1_0: + appLogPrintf("Add static config for mpu1_0\n"); + status = EthApp_addMpu10StaticCfg(hEnet, coreId, flowId); + break; + + default: + break; + } + + return status; +} + +static void EthApp_delRemoteCoreStaticCfg(Enet_Handle hEnet, + uint32_t coreId, + uint32_t flowId) +{ + switch (coreId) + { + case IPC_MPU1_0: + appLogPrintf("Delete static config for mpu1_0\n"); + EthApp_delMpu10StaticCfg(hEnet, coreId, flowId); + break; + + default: + break; + } +} + static int32_t EthApp_initRemoteServices(void) { int32_t status; diff --git a/ethfw/ethfw/ethfw.h b/ethfw/ethfw/ethfw.h index 3efe2ede..144794d6 100644 --- a/ethfw/ethfw/ethfw.h +++ b/ethfw/ethfw/ethfw.h @@ -260,6 +260,35 @@ typedef int32_t (*EthFw_setPortCfg)(Enet_MacPort macPort, EnetPhy_Cfg *phyCfg, EnetMacPort_LinkCfg *linkCfg); +/*! + * \brief Add static configuration. + * + * Add static configuration that is applicable only to specific remote cores. + * + * \param hEnet Handle to Enet LLD + * \param coreId Remote core's IPC core id + * \param flowId Remote core's flow id + * + * \return 0 if no error. Negative value otherwise. + */ +typedef int32_t (*EthFw_addStaticCfg)(Enet_Handle hEnet, + uint32_t coreId, + uint32_t flowId); + +/*! + * \brief Delete static configuration. + * + * Delete static configuration that is applicable only to specific remote cores. + * + * \param hEnet Handle to Enet LLD + * \param coreId Remote core's IPC core id + * \param flowId Remote core's flow id + */ +typedef void (*EthFw_delStaticCfg)(Enet_Handle hEnet, + uint32_t coreId, + uint32_t flowId); + + /*! * \brief Ethernet Firmware configuration * @@ -307,6 +336,13 @@ typedef struct EthFw_Config_s /*! Callback function for application to set port link parameters * (MII, PHY, speed, duplexity, etc) */ EthFw_setPortCfg setPortCfg; + + /* Add static configuration that is applicable only to specific remote cores */ + EthFw_addStaticCfg addStaticCfg; + + /* Delete static configuration that is applicable only to specific remote cores */ + EthFw_delStaticCfg delStaticCfg; + } EthFw_Config; /*! diff --git a/ethfw/ethfw/src/ethfw.c b/ethfw/ethfw/src/ethfw.c index 3aa264ed..d2111a55 100644 --- a/ethfw/ethfw/src/ethfw.c +++ b/ethfw/ethfw/src/ethfw.c @@ -227,6 +227,13 @@ typedef struct EthFw_Obj_s /*! Callback function for application to set port link parameters */ EthFw_setPortCfg setPortCfg; + + /* Add static configuration that is applicable only to specific remote cores */ + EthFw_addStaticCfg addStaticCfg; + + /* Delete static configuration that is applicable only to specific remote cores */ + EthFw_delStaticCfg delStaticCfg; + } EthFw_Obj; /* ========================================================================== */ @@ -812,6 +819,10 @@ void EthFw_initConfigParams(Enet_Type enetType, memset(config, 0, sizeof(*config)); + /* Initialize Static config function pointers */ + config->addStaticCfg = NULL; + config->delStaticCfg = NULL; + /* MAC port ownership */ config->ports = NULL; config->numPorts = 0U; @@ -874,6 +885,10 @@ EthFw_Handle EthFw_init(Enet_Type enetType, memset(&gEthFwObj, 0, sizeof(gEthFwObj)); + /* Save static config function pointers */ + gEthFwObj.addStaticCfg = config->addStaticCfg; + gEthFwObj.delStaticCfg = config->delStaticCfg; + /* Save config parameters */ gEthFwObj.cpswCfg = config->cpswCfg; @@ -1083,6 +1098,10 @@ int32_t EthFw_initRemoteConfig(EthFw_Handle hEthFw) cfg.dfltVlanIdMacOnlyPorts = gEthFwObj.dfltVlanIdMacOnlyPorts; cfg.dfltVlanIdSwitchPorts = gEthFwObj.dfltVlanIdSwitchPorts; + /* Static configuration callbacks */ + cfg.addStaticCfg = gEthFwObj.addStaticCfg; + cfg.delStaticCfg = gEthFwObj.delStaticCfg; + status = CpswProxyServer_init(&cfg); if (status != ENET_SOK) { diff --git a/ethfw/ethremotecfg/server/include/cpsw_proxy_server.h b/ethfw/ethremotecfg/server/include/cpsw_proxy_server.h index cc220666..ac0605fc 100644 --- a/ethfw/ethremotecfg/server/include/cpsw_proxy_server.h +++ b/ethfw/ethremotecfg/server/include/cpsw_proxy_server.h @@ -291,6 +291,34 @@ typedef struct CpswProxyServer_RsvdMcastCfg_s uint32_t numMacAddr; } CpswProxyServer_RsvdMcastCfg; +/*! + * \brief Add static configuration. + * + * Add static configuration that is applicable only to specific remote cores. + * + * \param hEnet Handle to Enet LLD + * \param coreId Remote core's IPC core id + * \param flowId Remote core's flow id + * + * \return 0 if no error. Negative value otherwise. + */ +typedef int32_t (*CpswProxyServer_addStaticCfg)(Enet_Handle hEnet, + uint32_t coreId, + uint32_t flowId); + +/*! + * \brief Delete static configuration. + * + * Delete static configuration that is applicable only to specific remote cores. + * + * \param hEnet Handle to Enet LLD + * \param coreId Remote core's IPC core id + * \param flowId Remote core's flow id + */ +typedef void (*CpswProxyServer_delStaticCfg)(Enet_Handle hEnet, + uint32_t coreId, + uint32_t flowId); + /*! * \brief Cpsw Proxy Server Remote Configuration structure * @@ -349,6 +377,13 @@ typedef struct CpswProxyServer_Config_s /*! Reserved multicast configuration */ CpswProxyServer_RsvdMcastCfg rsvdMcastCfg; + + /* Add static configuration that is applicable only to specific remote cores */ + CpswProxyServer_addStaticCfg addStaticCfg; + + /* Delete static configuration that is applicable only to specific remote cores */ + CpswProxyServer_delStaticCfg delStaticCfg; + } CpswProxyServer_Config_t; /*! diff --git a/ethfw/ethremotecfg/server/src/cpsw_proxy_server.c b/ethfw/ethremotecfg/server/src/cpsw_proxy_server.c index 341c4990..2346573c 100644 --- a/ethfw/ethremotecfg/server/src/cpsw_proxy_server.c +++ b/ethfw/ethremotecfg/server/src/cpsw_proxy_server.c @@ -194,6 +194,10 @@ typedef struct CpswProxyServer_Obj_s CpswProxyServer_SharedMcastTable sharedMcastTbl; CpswProxyServer_FilterAddMacSharedCb filterAddMacSharedCb; CpswProxyServer_FilterDelMacSharedCb filterDelMacSharedCb; + /* Add static configuration that is applicable only to specific remote cores */ + CpswProxyServer_addStaticCfg addStaticCfg; + /* Delete static configuration that is applicable only to specific remote cores */ + CpswProxyServer_delStaticCfg delStaticCfg; uint32_t alePortMask; uint32_t aleMacOnlyPortMask; uint16_t dfltVlanIdMacOnlyPorts; @@ -751,6 +755,17 @@ static int32_t CpswProxyServer_registerMacHandlerCb(EthRemoteCfg_VirtPort virtPo { appLogPrintf("EnetAppUtils_regDstMacRxFlow() failed CPSW_ALE_IOCTL_SET_POLICER: %d\n", status); } + if (ENET_SOK == status) + { + if (hProxyServer->addStaticCfg != NULL) + { + status = hProxyServer->addStaticCfg(hEnet, host_id, flow_idx_offset); + if (ENET_SOK != status) + { + appLogPrintf("Failed to add static config for coreId=%u: %d\n", host_id, status); + } + } + } } else { @@ -773,12 +788,15 @@ static int32_t CpswProxyServer_unregisterMacHandlerCb(EthRemoteCfg_VirtPort virt u8 *mac_address, uint32_t flow_idx) { + CpswProxyServer_Obj *hProxyServer; Enet_Handle hEnet = (Enet_Handle)((uintptr_t)handle); Enet_MacPort macPort = EthRemoteCfg_getMacPort(virtPort); bool isSwitchPort = EthRemoteCfg_isSwitchPort(virtPort); uint32_t start_flow_idx, flow_idx_offset; int32_t status; + hProxyServer = CpswProxyServer_getHandle(); + CpswProxyServer_validateHandle(hEnet); EnetAppUtils_absFlowIdx2FlowIdxOffset(hEnet, host_id, flow_idx, &start_flow_idx, &flow_idx_offset); appLogPrintf("Function:%s,HostId:%u,Handle:%p,CoreKey:%x, MacAddress:%x:%x:%x:%x:%x:%x, FlowIdx:%u, FlowIdOffset:%u\n", @@ -802,6 +820,13 @@ static int32_t CpswProxyServer_unregisterMacHandlerCb(EthRemoteCfg_VirtPort virt { appLogPrintf("Failed EnetAppUtils_unregDstMacRxFlow: %d\n", status); } + if (ENET_SOK == status) + { + if (hProxyServer->delStaticCfg != NULL) + { + hProxyServer->delStaticCfg(hEnet, host_id, flow_idx_offset); + } + } } else { @@ -2428,6 +2453,9 @@ int32_t CpswProxyServer_init(CpswProxyServer_Config_t *cfg) appLogPrintf("CpswProxyServer: initialization %s (core: mcu2_0)\r\n", (status == CPSWPROXYSERVER_SOK) ? "completed" : "failed"); + hProxyServer->addStaticCfg = cfg->addStaticCfg; + hProxyServer->delStaticCfg = cfg->delStaticCfg; + return status; } -- 2.17.1