📄 pivlngrp.c
字号:
//update default grp and pvid
if (pSPageBuf->byVlanMode == VLAN_MODE_PROTOBASE)
PIVLAN_vUpdateDefaultGrp(pSPageBuf);
// Find isolated port
if ((pSPageBuf->byVlanMode == VLAN_MODE_8021Q) || (pSPageBuf->byVlanMode == VLAN_MODE_PROTOBASE) )
return s_by8021QFindIsoPort(pSPageBuf, pwFailVid);
return OP_OK;
}
// Delete a vlan group
UINT8 PIVLAN_byDelGrp (SVlanPageCfg *pSPageBuf, PUINT16 pwFailVid)
{
UINT16 wTblPtr;
// Init failed vid value
*pwFailVid = UINT16_MAX;
// Default group is not able to be deleted
if (((pSPageBuf->byVlanMode == VLAN_MODE_8021Q) || (pSPageBuf->byVlanMode == VLAN_MODE_PROTOBASE)) &&
(pSCurGrp->u16Vid == VLAN_DEFAULT_GROUP_VID) )
return VLAN_OP_DEFAULT_GRP_CANNOT_DEL;
// If group id not exist, return error code
wTblPtr = PIVLNEEP_wSearchEntry(pSCurGrp->u16Vid);
if (wTblPtr == UINT16_MAX)
return VLAN_OP_GRP_NOT_EXIST;
// Delete group from hardware
if ((pSPageBuf->byVlanMode == VLAN_MODE_8021Q) || (pSPageBuf->byVlanMode == VLAN_MODE_PROTOBASE) ) { // 802.1Q mode
// Deleting operation
if (pSPageBuf->byVlanMode == VLAN_MODE_8021Q)
s_v8021QClearPvidOfDelMbr(wTblPtr);
SWVLANTB_bDelEntry( pSCurGrp->u16Vid );
// Get entry from EEPROM and transfer into config buffer format
PIVLNEEP_vGetEntry(wTblPtr, pSCurGrp);
VLANvTransBufFromEepToCfg();
if ((pSPageBuf->byVlanMode == VLAN_MODE_PROTOBASE) && (pSCurGrp->u8ProtoIndx != 0) )
VLANvPrvDelEntry(pSPageBuf);
}
else { // PortBase mode
// Delete group and set PVID & unused group
s_vPortBaseDelGrp(pSPageBuf, wTblPtr);
SWVLANTB_vPortBaseSetCfgForAllGrp();
}
// Delete group from EEPROM and return
PIVLNEEP_vDelEntry(wTblPtr);
PIVLNEEP_vStatisTblInfo(pSPageBuf);
//update default grp and pvid
if (pSPageBuf->byVlanMode == VLAN_MODE_PROTOBASE)
PIVLAN_vUpdateDefaultGrp(pSPageBuf);
// Find isolated port
if ((pSPageBuf->byVlanMode == VLAN_MODE_8021Q) || (pSPageBuf->byVlanMode == VLAN_MODE_PROTOBASE) )
return s_by8021QFindIsoPort(pSPageBuf, pwFailVid);
return OP_OK;
}
static UINT32 s_u32GetOldMbrMsk(UINT16 u16Vid)
{
SVlanPageCfg sPageBuf;
UINT32 u32UntagMsk, u32TagMsk;
STR_pvMemset(&sPageBuf, 0, sizeof(SVlanPageCfg));
sPageBuf.SCurGrp.u16Vid = u16Vid;
PIVLAN_byGetGrp(&sPageBuf);
PICFGMP_v2bLogPtrMskTo4BPhyMsk(sPageBuf.SCurGrp.abyMbrMsk, &u32TagMsk, &u32UntagMsk);
return (u32UntagMsk | u32TagMsk);
}
// Insert ProtocolBased entry into HW table
void VLANvPrvInsEntry (SVlanPageCfg *pSPageBuf)
{
SProVlanEntry sPrvTblEntry; //TOCHECK
UINT32 u32MskTmp1, u32MskTmp2, u32OldMsk, u32NewMsk;
UINT8 si, sj;
STR_pvMemset(&sPrvTblEntry, 0, sizeof(SProVlanEntry)); //TOCHECK
PICFGMP_v2bLogPtrMskTo4BPhyMsk(pSCurGrp->abyMbrMsk, &u32MskTmp1, &u32MskTmp2);
u32NewMsk = (u32MskTmp1 | u32MskTmp2);
// Transform config bit mask into physical port mask
u32OldMsk = s_u32GetOldMbrMsk(pSCurGrp->u16Vid);
//need to del portmsk
u32MskTmp1 = (u32OldMsk & ~u32NewMsk);
for (si = 0; si < SWITCH_PORT_NUM; si++) {
if (u32MskTmp1 & 0x00000001) {
for (sj = 0; sj < 4; sj++)
SWPRVTB_bDelEntry(si, (pSCurGrp->u8ProtoIndx-1), sj);
}
u32MskTmp1 >>= 1;
if (u32NewMsk & 0x00000001) {
sPrvTblEntry.u16Vid = pSCurGrp->u16Vid;
//sPrvTblEntry.byPortId = si; //TOCHECK
//sPrvTblEntry.byProtoIndx = (pSCurGrp->u8ProtoIndx-1); //TOCHECK
for (sj = 0; sj < 4; sj++) {
sPrvTblEntry.byFrameFormat = sj;
SWPRVTB_bInsEntry(&sPrvTblEntry, 1);
}
}
u32NewMsk >>= 1;
}
}
// Delete ProtocolBased entry in HW table
void VLANvPrvDelEntry (SVlanPageCfg *pSPageBuf)
{
UINT32 u32MskTmp1, u32MskTmp2, u32NewMsk;
UINT8 si, sj;
PICFGMP_v2bLogPtrMskTo4BPhyMsk(pSCurGrp->abyMbrMsk, &u32MskTmp1, &u32MskTmp2);
u32NewMsk = (u32MskTmp1 | u32MskTmp2);
for (si = 0; si < SWITCH_PORT_NUM; si++) {
if (u32NewMsk & 0x00000001) {
for (sj = 0; sj < 4; sj++)
SWPRVTB_bDelEntry(si, (pSCurGrp->u8ProtoIndx-1), sj);
}
u32NewMsk >>= 1;
}
}
// Insert 802.1Q entry into HW table and set related PVID config
void VLANv8021QInsEntry (SVlanPageCfg *pSPageBuf)
{
SVlanEntry SEntryBuf;
UINT32 dwUntagMsk, dwTagMsk, dwShftMsk = 0x00000001;
UINT8 si;
STR_pvMemset(&SEntryBuf, 0 , sizeof(SVlanEntry));
// Transform config bit mask into physical port mask
PICFGMP_v2bLogPtrMskTo4BPhyMsk(pSCurGrp->abyMbrMsk, &dwTagMsk, &dwUntagMsk);
// If a port is set to be untagged member of a group, set PVID to it's VID value.
if (pSPageBuf->byVlanMode == VLAN_MODE_8021Q) {
for (si = 0; si < SWITCH_PORT_NUM; si++) {
if (dwShftMsk & dwUntagMsk )
SWVLANTB_vPvidSet(si, (pSCurGrp->u16Vid) );
dwShftMsk <<= 1;
}
}
// Set entry into vlan table
SEntryBuf.u16Vid = pSCurGrp->u16Vid;
SEntryBuf.u16Fid = pSCurGrp->u16Vid;
SEntryBuf.u32EgrsMbrPortMsk = (dwUntagMsk | dwTagMsk);
SEntryBuf.u32TagPortMsk = dwTagMsk;
SEntryBuf.u32IngrsMbrPortMsk = SEntryBuf.u32EgrsMbrPortMsk;
// Insert entry into HW table
SWVLANTB_bSetEntry(&SEntryBuf);
}
// Clear PVID setting related to deleting entry
static void s_v8021QClearPvidOfDelMbr (UINT16 wTblPtr)
{
// NOTE: VLAN group buffer here must be local buffer
// since this function may be executed by PIVLAN_byEditGrp
// and the new content must not be overwritten
SVlanGrp SGrpBuf;
UINT32 dwUntagMsk = 0, dwTagMsk = 0;
UINT8 si;
// Get target group
PIVLNEEP_vGetEntry(wTblPtr, &SGrpBuf);
STR_pvMemcpy( (PUINT8)(&dwTagMsk)+BYTE_OFFSET_IN_DWORD_OF_CFGMASK,
SGrpBuf.abyMbrMsk+BYTE_NUM_OF_CFGBUF_BIT_MASK, BYTE_NUM_OF_CFGBUF_BIT_MASK );
STR_pvMemcpy( (PUINT8)(&dwUntagMsk)+BYTE_OFFSET_IN_DWORD_OF_CFGMASK,
SGrpBuf.abyMbrMsk, BYTE_NUM_OF_CFGBUF_BIT_MASK );
// If a port is set to be untagged member of a group, clear its PVID.
for (si = 0; si < SWITCH_PORT_NUM; si++) {
if (dwUntagMsk & 0x00000001 )
SWVLANTB_vPvidSet(si, 0);
dwUntagMsk >>= 1;
}
}
// Check if a port being untagged member of more than one group
static UINT16 s_w8021QCheckUntagMbrOverlap (SVlanPageCfg *pSPageBuf)
{
UINT32 dwUntagMsk, dwTagMsk;
UINT16 wPvidBuf = 0, sj;
UINT8 si;
// Transform config bit mask into physical port mask
PICFGMP_v2bLogPtrMskTo4BPhyMsk(pSCurGrp->abyMbrMsk, &dwTagMsk, &dwUntagMsk);
// If current PVID is already belonging to group with vid N, return GROUP INDEX of group N
for (si = 0; si < SWITCH_PORT_NUM; si++) {
if (dwUntagMsk & 0x00000001 ) {
SWVLANTB_vPvidGet(si, &wPvidBuf);
if ((wPvidBuf != 0) && (wPvidBuf != pSCurGrp->u16Vid) ) {
for (sj = 0; sj < pSPageBuf->wValidEntryNum; sj++) {
if (pSPageBuf->awValidGrpIdList[sj] == wPvidBuf )
return pSPageBuf->awValidGrpIdList[sj];
}
}
}
dwUntagMsk >>= 1;
}
// If check ok, return UINT16_MAX
return UINT16_MAX;
}
// Find 802.1Q isolated port (in format of log ptr)
static UINT8 s_by8021QFindIsoPort (SVlanPageCfg *pSPageBuf, PUINT16 pwFailVid)
{
SVlanGrp SGrpBuf;
UINT32 dwMbrMsk = 0, dwTmp = 0;
UINT16 si;
// Statistic members of all groups
for (si = 0; si < pSPageBuf->wValidEntryNum; si++) {
PIVLNEEP_vGetEntry( PIVLNEEP_wSearchEntry(pSPageBuf->awValidGrpIdList[si]), &SGrpBuf );
// Statistic untagged setting of all groups
STR_pvMemcpy( (PUINT8)(&dwTmp)+BYTE_OFFSET_IN_DWORD_OF_CFGMASK,
SGrpBuf.abyMbrMsk, BYTE_NUM_OF_CFGBUF_BIT_MASK );
dwMbrMsk |= dwTmp;
// Statistic tagged setting of non-default groups
STR_pvMemcpy( (PUINT8)(&dwTmp)+BYTE_OFFSET_IN_DWORD_OF_CFGMASK,
SGrpBuf.abyMbrMsk+BYTE_NUM_OF_CFGBUF_BIT_MASK, BYTE_NUM_OF_CFGBUF_BIT_MASK );
dwMbrMsk |= dwTmp;
}
for (si = 0; si < SWITCH_PORT_NUM; si++) {
if (!(dwMbrMsk & 0x00000001) ) {
*pwFailVid = PIPORTMP_byPhyIdToLogId(si);
if (*pwFailVid != ENTRY_END_FLAG) // may be module port is not exist
return VLAN_OP_FOUND_ISO_PORT;
}
dwMbrMsk >>= 1;
}
return OP_OK;
}
void VLANvPortBaseInsGrp (SVlanGrp *pSGrp)
{
UINT32 dwMbrMsk, dwDummy;
PICFGMP_v2bLogPtrMskTo4BPhyMsk( pSGrp->abyMbrMsk, &dwDummy, &dwMbrMsk );
SWVLANTB_vPortBaseAddGrp(dwMbrMsk);
}
static void s_vPortBaseDelGrp (SVlanPageCfg *pSPageBuf, UINT16 wTblPtr)
{
union // For reducing stack usage
{
SVlanGrp SGrp;
SVlanEntry SEntry;
} UVlanBuf;
UINT32 dwDelMbrMsk = 0, dwMbrMsk = 0;
UINT16 si, wTmp;
// Get target group and transfer config bit mask into physical port mask
PIVLNEEP_vGetEntry(wTblPtr, &UVlanBuf.SGrp);
STR_pvMemcpy( (PUINT8)(&dwDelMbrMsk)+BYTE_OFFSET_IN_DWORD_OF_CFGMASK,
UVlanBuf.SGrp.abyMbrMsk, BYTE_NUM_OF_CFGBUF_BIT_MASK );
// Remove deleting mbrs from vlan table entries containing one of deleting ports as mbr
for (si = 0; si < SWITCH_PORT_NUM; si++) {
if (SWVLANTB_bGetEntry( PORTBASE_ID_TO_VID(si), &UVlanBuf.SEntry ) &&
(UVlanBuf.SEntry.u32EgrsMbrPortMsk & dwDelMbrMsk & ~BIT_MASK_PORT_CPU) ) {
UVlanBuf.SEntry.u32EgrsMbrPortMsk &= ~dwDelMbrMsk;
UVlanBuf.SEntry.u32IngrsMbrPortMsk &= ~dwDelMbrMsk;
// If called by deleting or no more members left, delete whole entry
if (UVlanBuf.SEntry.u32EgrsMbrPortMsk == BIT_MASK_PORT_CPU)
SWVLANTB_bDelEntry( PORTBASE_ID_TO_VID(si) );
// If called by editing, keep innocent members untouched
else
SWVLANTB_bSetEntry(&UVlanBuf.SEntry);
}
}
// Add all groups back from EEPROM that containing one of deleting ports as member
// (except the deleting one)
for (si = 0; si < pSPageBuf->wValidEntryNum; si++) {
wTmp = PIVLNEEP_wSearchEntry(pSPageBuf->awValidGrpIdList[si]);
if (wTmp == wTblPtr)
continue;
PIVLNEEP_vGetEntry(wTmp, &UVlanBuf.SGrp);
STR_pvMemcpy( (PUINT8)(&dwMbrMsk)+BYTE_OFFSET_IN_DWORD_OF_CFGMASK,
UVlanBuf.SGrp.abyMbrMsk, BYTE_NUM_OF_CFGBUF_BIT_MASK );
if (dwMbrMsk & dwDelMbrMsk & ~BIT_MASK_PORT_CPU)
SWVLANTB_vPortBaseAddGrp(dwMbrMsk);
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -