301 lines
9.2 KiB
C
301 lines
9.2 KiB
C
/*
|
||
* eth_vlan.c
|
||
*
|
||
* Created on: 9 мар. 2023 г.
|
||
* Author: sychev
|
||
*/
|
||
#include "free_rtos/ethernet/eth_vlan.h"
|
||
|
||
#include <networking/enet/utils/include/enet_apputils.h>
|
||
#include <networking/enet/core/include/core/enet_ioctl.h>
|
||
|
||
//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;
|
||
}*/
|