sitara_depot/components/free_rtos/ethernet/eth_vlan.c

301 lines
9.2 KiB
C
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

/*
* 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, &regenMap);
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;
}*/