📄 ixethdbnpeadaptor.c
字号:
/** * @file IxEthDBDBNPEAdaptor.c * * @brief Routines that read and write learning/search trees in NPE-specific format * * @par * IXP400 SW Release version 2.1 * * -- Copyright Notice -- * * @par * Copyright (c) 2001-2005, Intel Corporation. * All rights reserved. * * @par * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. Neither the name of the Intel Corporation nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * * * @par * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * * * @par * -- End of Copyright Notice -- */#include "IxEthDB_p.h"#include "IxEthDBLog_p.h"/* forward prototype declarations */IX_ETH_DB_PUBLIC void ixEthDBELTShow(IxEthDBPortId portID);IX_ETH_DB_PUBLIC void ixEthDBShowNpeMsgHistory(void);/* data */UINT8* ixEthDBNPEUpdateArea[IX_ETH_DB_NUMBER_OF_PORTS];UINT32 dumpEltSize;/* private data */IX_ETH_DB_PRIVATE IxEthDBNoteWriteFn ixEthDBNPENodeWrite[IX_ETH_DB_MAX_RECORD_TYPE_INDEX + 1];#define IX_ETH_DB_MAX_DELTA_ZONES (6) /* at most 6 EP Delta zones, according to NPE FS */IX_ETH_DB_PRIVATE UINT32 ixEthDBEPDeltaOffset[IX_ETH_DB_MAX_RECORD_TYPE_INDEX + 1][IX_ETH_DB_MAX_DELTA_ZONES]; IX_ETH_DB_PRIVATE UINT32 ixEthDBEPDelta[IX_ETH_DB_MAX_RECORD_TYPE_INDEX + 1][IX_ETH_DB_MAX_DELTA_ZONES];/** * @brief allocates non-cached or contiguous NPE tree update areas for all the ports * * This function is called only once at initialization time from * @ref ixEthDBInit(). * * @warning do not call manually * * @see ixEthDBInit() * * @internal */IX_ETH_DB_PUBLICvoid ixEthDBNPEUpdateAreasInit(void){ UINT32 portIndex; PortUpdateMethod *update; for (portIndex = 0 ; portIndex < IX_ETH_DB_NUMBER_OF_PORTS ; portIndex++) { update = &ixEthDBPortInfo[portIndex].updateMethod; if (ixEthDBPortDefinitions[portIndex].type == IX_ETH_NPE) { update->npeUpdateZone = IX_OSAL_CACHE_DMA_MALLOC(FULL_ELT_BYTE_SIZE); if (update->npeUpdateZone == NULL) { ERROR_LOG("Fatal error: IX_ACC_DRV_DMA_MALLOC() returned NULL, no NPE update zones available\n"); } else { memset(update->npeUpdateZone, 0, FULL_ELT_BYTE_SIZE); } update->npeGwUpdateZone = IX_OSAL_CACHE_DMA_MALLOC(FULL_GW_BYTE_SIZE); if (update->npeGwUpdateZone == NULL) { ERROR_LOG("Fatal error: IX_ACC_DRV_DMA_MALLOC() returned NULL, no gateway update zones available\n"); } else { memset(update->npeGwUpdateZone, 0, FULL_GW_BYTE_SIZE); } update->npeBssidUpdateZone = IX_OSAL_CACHE_DMA_MALLOC(FULL_BSSID_BYTE_SIZE); if (update->npeBssidUpdateZone == NULL) { ERROR_LOG("Fatal error: IX_ACC_DRV_DMA_MALLOC() returned NULL, no bssid update zones available\n"); } else { memset(update->npeBssidUpdateZone, 0, FULL_BSSID_BYTE_SIZE); } update->vlanUpdateZone = IX_OSAL_CACHE_DMA_MALLOC(FULL_VLAN_BYTE_SIZE); if (update->vlanUpdateZone == NULL) { ERROR_LOG("Fatal error: IX_ACC_DRV_DMA_MALLOC() returned NULL, no vlan update zones available\n"); } else { memset(update->vlanUpdateZone, 0, FULL_VLAN_BYTE_SIZE); } } else { /* unused */ update->npeUpdateZone = NULL; update->npeGwUpdateZone = NULL; update->npeBssidUpdateZone = NULL; update->vlanUpdateZone = NULL; } }}/** * @brief deallocates the NPE update areas for all the ports * * This function is called at component de-initialization time * by @ref ixEthDBUnload(). * * @warning do not call manually * * @internal */IX_ETH_DB_PUBLICvoid ixEthDBNPEUpdateAreasUnload(void){ UINT32 portIndex; PortUpdateMethod *update; for (portIndex = 0 ; portIndex < IX_ETH_DB_NUMBER_OF_PORTS ; portIndex++) { update = &ixEthDBPortInfo[portIndex].updateMethod; if (ixEthDBPortDefinitions[portIndex].type == IX_ETH_NPE) { if (update->npeUpdateZone != NULL) { IX_OSAL_CACHE_DMA_FREE(update->npeUpdateZone); } if (update->npeGwUpdateZone != NULL) { IX_OSAL_CACHE_DMA_FREE(update->npeGwUpdateZone); } if (update->npeBssidUpdateZone != NULL) { IX_OSAL_CACHE_DMA_FREE(update->npeBssidUpdateZone); } if (update->vlanUpdateZone != NULL) { IX_OSAL_CACHE_DMA_FREE(update->vlanUpdateZone); } } }}/** * @brief general-purpose NPE callback function * * @param npeID NPE ID * @param msg NPE message * * This function will unblock the caller by unlocking * the npeAckLock mutex defined for each NPE port * * @internal */IX_ETH_DB_PUBLICvoid ixEthDBNpeMsgAck(IxNpeMhNpeId npeID, IxNpeMhMessage msg){ IxEthDBPortId portID = IX_ETHNPE_NODE_AND_PORT_TO_PHYSICAL_ID(npeID,0); PortInfo *portInfo; if (portID >= IX_ETH_DB_NUMBER_OF_PORTS) { /* invalid port */ return; } if (ixEthDBPortDefinitions[portID].type != IX_ETH_NPE) { /* not an NPE */ return; } portInfo = &ixEthDBPortInfo[portID]; ixOsalMutexUnlock(&portInfo->npeAckLock);}/** * @brief synchronizes the database with tree * * @param portID port ID of the NPE whose tree is to be scanned * @param eltBaseAddress memory base address of the NPE serialized tree * @param eltSize size in bytes of the NPE serialized tree * * Scans the NPE learning tree and resets the age of active database records. * * @internal */IX_ETH_DB_PUBLICvoid ixEthDBNPESyncScan(IxEthDBPortId portID, void *eltBaseAddress, UINT32 eltSize){ UINT32 eltEntryOffset; UINT32 entryPortID; /* invalidate cache */ IX_OSAL_CACHE_INVALIDATE(eltBaseAddress, eltSize); for (eltEntryOffset = ELT_ROOT_OFFSET ; eltEntryOffset < eltSize ; eltEntryOffset += ELT_ENTRY_SIZE) { /* (eltBaseAddress + eltEntryOffset) points to a valid NPE tree node * * the format of the node is MAC[6 bytes]:PortID[1 byte]:Reserved[6 bits]:Active[1 bit]:Valid[1 bit] * therefore we can just use the pointer for database searches as only the first 6 bytes are checked */ void *eltNodeAddress = (void *) ((UINT32) eltBaseAddress + eltEntryOffset); /* debug */ IX_ETH_DB_NPE_VERBOSE_TRACE("DB: (NPEAdaptor) checking node at offset %d...\n", eltEntryOffset / ELT_ENTRY_SIZE); if (IX_EDB_NPE_NODE_VALID(eltNodeAddress) != TRUE) { IX_ETH_DB_NPE_VERBOSE_TRACE("\t... node is empty\n"); } else if (eltEntryOffset == ELT_ROOT_OFFSET) { IX_ETH_DB_NPE_VERBOSE_TRACE("\t... node is root\n"); } if (IX_EDB_NPE_NODE_VALID(eltNodeAddress)) { entryPortID = IX_ETHNPE_LOGICAL_ID_TO_PHYSICAL_ID(IX_EDB_NPE_NODE_PORT_ID(eltNodeAddress)); /* check only active entries belonging to this port */ if (ixEthDBPortInfo[portID].agingEnabled && IX_EDB_NPE_NODE_ACTIVE(eltNodeAddress) && (portID == entryPortID) && ((ixEthDBPortDefinitions[portID].capabilities & IX_ETH_ENTRY_AGING) == 0)) { /* search record */ HashNode *node = ixEthDBSearch((IxEthDBMacAddr *) eltNodeAddress, IX_ETH_DB_ALL_FILTERING_RECORDS); /* safety check, maybe user deleted record right before sync? */ if (node != NULL) { /* found record */ MacDescriptor *descriptor = (MacDescriptor *) node->data; IX_ETH_DB_NPE_VERBOSE_TRACE("DB: (NPEAdaptor) synced entry [%s] already in the database, updating fields\n", mac2string(eltNodeAddress)); /* reset age - set to -1 so that maintenance will restore it to 0 (or more) when incrementing */ if (!descriptor->recordData.filteringData.staticEntry) { if (descriptor->type == IX_ETH_DB_FILTERING_RECORD) { descriptor->recordData.filteringData.age = AGE_RESET; } else if (descriptor->type == IX_ETH_DB_FILTERING_VLAN_RECORD) { descriptor->recordData.filteringVlanData.age = AGE_RESET; } } /* end transaction */ ixEthDBReleaseHashNode(node); } } else { IX_ETH_DB_NPE_VERBOSE_TRACE("\t... found portID %d, we check only port %d\n", entryPortID, portID); } } }}/** * @brief writes a search tree in NPE format * * @param type type of records to be written into the NPE update zone * @param totalSize maximum size of the linearized tree * @param baseAddress memory base address where to write the NPE tree into * @param tree search tree to write in NPE format * @param blocks number of written 64-byte blocks * @param startIndex optimal binary search start index * * Serializes the given tree in NPE linear format
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -