/* * eth_vlan.c * * Created on: 9 мар. 2023 г. * Author: sychev */ #include "free_rtos/ethernet/eth_vlan.h" #include #include //using namespace free_rtos; /* Bit#0 Indicates host ownership (indicates Host egress) */ #define FDB_ENTRY_HOST_BIT (0) /* Bit#1 Indicates that MAC ID is connected to Physical Port 1 */ #define FDB_ENTRY_PORT1_BIT (1) /* Bit#2 Indicates that MAC ID is connected to Physical Port 2 */ #define FDB_ENTRY_PORT2_BIT (2) /* Bit#3 This is set to 1 for all learnt entries. 0 for static entries. */ #define FDB_ENTRY_LEARNT_ENTRY_BIT (3) /* Bit#4 If set for SA then packet is dropped (can be used to implement a blacklist). * If set for DA then packet is determined to be a special packet */ #define FDB_ENTRY_BLOCK_BIT (4) /* Bit#5 If set for DA then the SA from the packet is not learnt */ /* Bit#6 if set, it means packet has been seen recently with source address + * FID matching MAC address/FID of entry. */ #define FDB_ENTRY_TOUCH_BIT (6) /* Bit#7 set if entry is valid */ #define FDB_ENTRY_VALID_BIT (7) int32_t eth_vlan_setPriorityRegMapping(Enet_Handle handle, uint32_t core_id, Enet_MacPort macPort, uint32_t *prioRegenMap) { EnetMacPort_SetPriorityRegenMapInArgs regenMap; Enet_IoctlPrms prms; int32_t status = ENET_SOK; int32_t i; regenMap.macPort = macPort; for (i = 0; i < ENET_PRI_NUM; i++) { regenMap.priorityRegenMap.priorityMap[i] = prioRegenMap[i]; } ENET_IOCTL_SET_IN_ARGS(&prms, ®enMap); ENET_IOCTL(handle, core_id, ENET_MACPORT_IOCTL_SET_PRI_REGEN_MAP, &prms, status); if (status != ENET_SOK) { EnetAppUtils_print("ERROR: IOCTL command for priority regeneration for PORT = %u\r\n", macPort); status = ENET_EFAIL; } return status; } int32_t eth_vlan_setPriorityMapping(Enet_Handle handle, uint32_t core_id, Enet_MacPort macPort, uint32_t *prioMap) { EnetMacPort_SetEgressPriorityMapInArgs priMap; Enet_IoctlPrms prms; int32_t status = ENET_SOK; int32_t i; priMap.macPort = macPort; for (i = 0; i < ENET_PRI_NUM; i++) { priMap.priorityMap.priorityMap[i] = prioMap[i]; } ENET_IOCTL_SET_IN_ARGS(&prms, &priMap); ENET_IOCTL(handle, core_id, ENET_MACPORT_IOCTL_SET_EGRESS_QOS_PRI_MAP, &prms, status); if (status != ENET_SOK) { EnetAppUtils_print("ERROR: IOCTL command for priority mapping for PORT = %u\r\n", macPort); status = ENET_EFAIL; } return status; } int32_t eth_vlan_addDefaultHostVid(Enet_Handle handle, uint32_t core_id, uint8_t pcp, uint16_t vlan_id) { Enet_IoctlPrms prms; EnetPort_VlanCfg vlanDefaultEntry; int32_t status = ENET_SOK; vlanDefaultEntry.portVID = vlan_id; vlanDefaultEntry.portPri = pcp; ENET_IOCTL_SET_IN_ARGS(&prms, &vlanDefaultEntry); ENET_IOCTL(handle, core_id, ICSSG_PER_IOCTL_VLAN_SET_HOSTPORT_DFLT_VID, &prms, status); if (status != ENET_SOK) { EnetAppUtils_print("Failed to set default VID"); } return status; } int32_t eth_vlan_addDefaultPortVid(Enet_Handle handle, uint32_t core_id, Enet_MacPort macPort, uint8_t pcp, uint16_t vlanId) { int32_t status = ENET_SOK; Enet_IoctlPrms prms; Icssg_MacPortDfltVlanCfgInArgs vlanDefaultEntry; vlanDefaultEntry.macPort = macPort; vlanDefaultEntry.vlanCfg.portVID = vlanId; vlanDefaultEntry.vlanCfg.portPri = pcp; ENET_IOCTL_SET_IN_ARGS(&prms, &vlanDefaultEntry); ENET_IOCTL(handle, core_id, ICSSG_PER_IOCTL_VLAN_SET_MACPORT_DFLT_VID, &prms, status); if (status != ENET_SOK) { EnetAppUtils_print("Failed to set default VID"); } return status; } int32_t eth_vlan_init(Enet_Handle handle, uint32_t core_id, uint16_t vlanId, Enet_Type enetType) { int32_t status = ENET_SOK; Enet_IoctlPrms prms; uint32_t i; uint32_t prioRegenMap[ENET_PRI_NUM]; uint32_t prioMap[ENET_PRI_NUM]; Icssg_VlanFidEntry vlanEntry; Icssg_VlanFidParams vlanParams = { .fid = 0, .hostMember = 1, .p1Member = 1, .p2Member = 1, .hostTagged = 0, .p1Tagged = 0, .p2Tagged = 0, .streamVid = 0, .floodToHost = 0 }; Icssg_VlanFidParams vlanParamsForPrioTag = { .fid = 0, .hostMember = 1, .p1Member = 1, .p2Member = 1, .hostTagged = 0, .p1Tagged = 1, .p2Tagged = 1, .streamVid = 0, .floodToHost = 0 }; vlanParams.fid = vlanId; for (i = 0; i < ENET_PRI_NUM; i++) { prioRegenMap[i] = (uint32_t)(ENET_PRI_NUM-1-i); prioMap[i] = 0U; } /* Установите команду IOCTL, чтобы сделать PORT1 граничным портом, а PORT2 принимать все типы пакетов. */ eth_vlan_setPriorityRegMapping(handle, core_id, ENET_MAC_PORT_1, prioRegenMap); eth_vlan_setPriorityMapping(handle, core_id, ENET_MAC_PORT_1, prioMap); if (enetType == ENET_ICSSG_SWITCH) { eth_vlan_setPriorityRegMapping(handle, core_id, ENET_MAC_PORT_2, prioRegenMap); eth_vlan_setPriorityMapping(handle, core_id, ENET_MAC_PORT_2, prioMap); } /* Make an entry for common vlan id * Update table for default entry */ vlanEntry.vlanFidParams = vlanParams; vlanEntry.vlanId = (uint16_t)vlanId; ENET_IOCTL_SET_IN_ARGS(&prms, &vlanEntry); ENET_IOCTL(handle, core_id, ICSSG_PER_IOCTL_VLAN_SET_ENTRY, &prms, status); if (status != ENET_SOK) { EnetAppUtils_print("FID VLAN entry for HOST is FAILED = %u : FAILED\r\n", status); return status; } /* -----------------Make an entry for Priority tag----------------- */ vlanEntry.vlanFidParams = vlanParamsForPrioTag; vlanEntry.vlanId = (uint16_t)0; ENET_IOCTL_SET_IN_ARGS(&prms, &vlanEntry); ENET_IOCTL(handle, core_id, ICSSG_PER_IOCTL_VLAN_SET_ENTRY, &prms, status); if (status != ENET_SOK) { EnetAppUtils_print("FID VLAN entry for VID = 0: FAILED = %u : FAILED\r\n", status); return status; } /* -----------------Make a default entry for Host port----------------- */ status = eth_vlan_addDefaultHostVid(handle, core_id, 0, vlanId); if (status != ENET_SOK) { EnetAppUtils_print("\n ERROR: In updating default VLAN for Host : %d\r\n", status); } /* -----------------Make a default entry for P1 port----------------- */ status = eth_vlan_addDefaultPortVid(handle, core_id, ENET_MAC_PORT_1, 1, vlanId); if (status != ENET_SOK) { EnetAppUtils_print("\n ERROR: In updating default VLAN for P1 \r\n\r"); return status; } if (enetType == ENET_ICSSG_SWITCH) { /* -----------------Make a default entry for P2 port----------------- */ status = eth_vlan_addDefaultPortVid(handle, core_id, ENET_MAC_PORT_2, 2, vlanId); if (status != ENET_SOK) { EnetAppUtils_print("\n ERROR: In updating default VLAN for P2 \r\n\r"); return status; } } return status; } /*int32_t eth_vlan_addMacFdbEntry(Enet_Handle handle, uint32_t core_id, Semaphore& ioctl_sem, Icssg_MacAddr mac, int16_t vlanId, uint8_t fdbEntryPort) { int32_t status = ENET_EFAIL; int32_t semStatus; Enet_IoctlPrms prms; Icssg_FdbEntry fdbEntry; int i = 0; // Now make an entry in FDB for the HOST MAC address using Asynchronous IOCTL for (i = 0; i < ENET_MAC_ADDR_LEN; i++) { fdbEntry.macAddr[i] = mac.macAddr[i]; } fdbEntry.vlanId = vlanId; fdbEntry.fdbEntry[0] = fdbEntryPort; fdbEntry.fdbEntry[1] = fdbEntryPort; ENET_IOCTL_SET_IN_ARGS(&prms, &fdbEntry); ENET_IOCTL(handle, core_id, ICSSG_FDB_IOCTL_ADD_ENTRY, &prms, status); if (status == ENET_SINPROGRESS) { EnetAppUtils_print("Success: IOCTL command sent for making MAC entry in FDB \r\n"); // Wait for asyc ioctl to complete do { Enet_poll(handle, ENET_EVT_ASYNC_CMD_RESP, NULL, 0U); semStatus = ioctl_sem.pend(1U); } while (semStatus != SystemP_SUCCESS); status = ENET_SOK; } else { EnetAppUtils_print("ERROR: IOCTL command sent for making MAC entry in FDB failed as vlanId out of range \r\n"); EnetAppUtils_print("ERROR: IOCTL command sent for making MAC entry in FDB \r\n"); } return status; }*/