📄 pivlngrp.c
字号:
/*
* Copyright (c) 1996, 2003 VIA Networking Technologies, Inc.
* All rights reserved.
*
* This software is copyrighted by and is the sole property of
* VIA Networking Technologies, Inc. This software may only be used
* in accordance with the corresponding license agreement. Any unauthorized
* use, duplication, transmission, distribution, or disclosure of this
* software is expressly forbidden.
*
* This software is provided by VIA Networking Technologies, Inc. "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 VIA Networking Technologies, Inc.
* be liable for any direct, indirect, incidental, special, exemplary, or
* consequential damages.
*
*
* File: pivlngrp.c
*
* Purpose: VLAN group setting UI callback functions
*
* Author: Tevin Chen
*
* Date: Jan 08, 2002
*
* Functions:
*
* Revision History:
*
*/
#if !defined(__SWCFG_H__)
#include "swcfg.h"
#endif
#include "swreg.h"
#include "str.h"
#include "piportmp.h"
#include "picfgmp.h"
#include "pivlngrp.h"
#include "pivlnmod.h"
#include "pivlneep.h"
#include "swmsg.h"
#include "swsys.h"
#include "swprvtb.h"
/*--------------------- EEPROM Content Statement ------------------*/
/*
* NOTE: EEPROM content of all VLAN APIs are of physical 3-byte mask format.
* Thus initializing hardware config from EEPROM needs to transfer from
* 3-byte phy mask to 4-byte phy mask; on the other hand, saving current
* config into EEPROM needs to transfer from 3-byte config mask to 3-byte
* phy mask format.
*/
/*--------------------- Static Definitions -------------------------*/
// Definitions to reduce statement length
#define pSCurGrp (&pSPageBuf->SCurGrp)
/*--------------------- Static Classes ----------------------------*/
/*--------------------- Static Variables --------------------------*/
/*--------------------- Static Functions --------------------------*/
// Clear PVID setting related to deleting entry
static void s_v8021QClearPvidOfDelMbr(UINT16 wTblPtr);
// Check if a port being untagged member of more than one group
static UINT16 s_w8021QCheckUntagMbrOverlap(SVlanPageCfg *pSPageBuf);
// Find 802.1Q isolated port (in format of log ptr)
static UINT8 s_by8021QFindIsoPort(SVlanPageCfg *pSPageBuf, PUINT16 pwFailVid);
// Delete a portbase group
static void s_vPortBaseDelGrp(SVlanPageCfg *pSPageBuf, UINT16 wTblPtr);
//Get protcol-based vlan grp old portmsk
static UINT32 s_u32GetOldMbrMsk(UINT16 u16Vid);
/*--------------------- Static Macros -----------------------------*/
/*--------------------- Export Variables --------------------------*/
/*--------------------- Export Functions --------------------------*/
// Get a vlan group
UINT8 PIVLAN_byGetGrp (SVlanPageCfg *pSPageBuf)
{
UINT16 wTblPtr;
// If group id not exist, return error code
wTblPtr = PIVLNEEP_wSearchEntry(pSCurGrp->u16Vid);
if (wTblPtr == UINT16_MAX)
return VLAN_OP_GRP_NOT_EXIST;
// Get entry from EEPROM and transfer into config buffer format
PIVLNEEP_vGetEntry(wTblPtr, pSCurGrp);
VLANvTransBufFromEepToCfg();
return OP_OK;
}
// Insert a vlan group
UINT8 PIVLAN_byInsGrp (SVlanPageCfg *pSPageBuf, PUINT16 pwFailVid)
{
UINT16 u16Addr = 0;
UINT8 si;
UINT32 dwUntagMsk, dwTagMsk, dwShftMsk = 0x00000001;
// Init failed vid value
*pwFailVid = UINT16_MAX;
// If no empty group, return error code
if (pSPageBuf->wValidEntryNum == SWITCH_VLAN_GRP_NUM )
return VLAN_OP_NO_EMPTY_GRP;
// If VID invalid, return error code
if ((pSCurGrp->u16Vid < VLAN_MIN_VALID_VID) || (pSCurGrp->u16Vid > VLAN_MAX_VALID_VID_3268) )
return VLAN_OP_VID_INVALID;
// If group already exist, return error code
if (PIVLNEEP_wSearchEntry(pSCurGrp->u16Vid) != UINT16_MAX )
return VLAN_OP_GRP_EXIST;
// Insert the current group into hardware
if ((pSPageBuf->byVlanMode == VLAN_MODE_8021Q) || (pSPageBuf->byVlanMode == VLAN_MODE_PROTOBASE) ){ // 802.1Q mode
// VLAN_MODE_8021Q : Check if untagged member overlapped
if (pSPageBuf->byVlanMode == VLAN_MODE_8021Q) {
*pwFailVid = s_w8021QCheckUntagMbrOverlap(pSPageBuf);
if (*pwFailVid != UINT16_MAX)
return VLAN_OP_UNTAG_BELONG_OTHER_GRP;
}
// VLAN_MODE_PROTOBASE : Check if one port belong two the same protocol
if (pSPageBuf->byVlanMode == VLAN_MODE_PROTOBASE) {
// Transform config bit mask into physical port mask
PICFGMP_v2bLogPtrMskTo4BPhyMsk(pSPageBuf->SCurGrp.abyMbrMsk, &dwTagMsk, &dwUntagMsk);
for (si = 0; si < SWITCH_PORT_NUM; si++) {
if (dwShftMsk & dwUntagMsk ) {
// Search entry
//SWPRVTB_vSearchEntry(si, pSPageBuf->SCurGrp.u8ProtoIndx-1, 0, &u16Addr, &byEntryNo); //TOCHECK
//u16Addr = SWPRVTB_u32SearchEntry(si, pSPageBuf->SCurGrp.u8ProtoIndx-1, 0); //TOCHECK
// If search failed, return with message
if (u16Addr != UINT16_MAX)
return VLAN_OP_MEMBER_BELONG_THE_SAME_PROTOCOL;
}
dwShftMsk <<= 1;
}
}
//set content into HW table
VLANv8021QInsEntry(pSPageBuf);
//(u8ProtoIndx == none) => only need to set entry into "vlan table"
//(u8ProtoIndx != none) => set entry into "vlan table" and "protocol vlan table"
if ((pSPageBuf->byVlanMode == VLAN_MODE_PROTOBASE) && (pSCurGrp->u8ProtoIndx != 0) )
VLANvPrvInsEntry(pSPageBuf);
}
else { // PortBase mode
// Insert new group and set PVID & unused group
VLANvPortBaseInsGrp(pSCurGrp);
SWVLANTB_vPortBaseSetCfgForAllGrp();
}
// Insert current group into EEPROM and return
VLANvTransBufFromCfgToEep();
PIVLNEEP_byInsEntry(pSCurGrp);
PIVLNEEP_vStatisTblInfo(pSPageBuf);
VLANvTransBufFromEepToCfg();
//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;
}
void PIVLAN_vUpdateDefaultGrp(SVlanPageCfg *pSPageBuf)
{
UINT16 si;
SVlanEntry SEntryBuf;
UINT32 u32Tmp = 0, u32UntagMskAll = 0, u32UnTagMskDft = 0, u32TagMskDft = 0;
//except default grp => si start with "1"
for (si = 1; si < pSPageBuf->wValidEntryNum; si++) {
STR_pvMemset(pSCurGrp, 0, sizeof(SVlanGrp));
PIVLNEEP_vGetEntry( PIVLNEEP_wSearchEntry(pSPageBuf->awValidGrpIdList[si]), pSCurGrp);
//untagged
STR_pvMemcpy( (PUINT8)(&u32Tmp)+BYTE_OFFSET_IN_DWORD_OF_CFGMASK,
pSCurGrp->abyMbrMsk, BYTE_NUM_OF_CFGBUF_BIT_MASK);
u32UntagMskAll |= u32Tmp;
}
//default grp
PIVLNEEP_vGetEntry( 0, pSCurGrp);
//untag
u32UnTagMskDft = (~u32UntagMskAll);
STR_pvMemcpy( pSCurGrp->abyMbrMsk,
(PUINT8)(&u32UnTagMskDft)+BYTE_OFFSET_IN_DWORD_OF_CFGMASK, BYTE_NUM_OF_CFGBUF_BIT_MASK);
//unsetgrp => NonMbr
STR_pvMemcpy( pSCurGrp->abyMbrMsk + BYTE_NUM_OF_CFGBUF_BIT_MASK,
(PUINT8)(&u32TagMskDft)+BYTE_OFFSET_IN_DWORD_OF_CFGMASK, BYTE_NUM_OF_CFGBUF_BIT_MASK);
u32TagMskDft = u32UntagMskAll;
//set into Eep
PIVLNEEP_vEditEntry(0, pSCurGrp);
//set into HW
STR_pvMemset(&SEntryBuf, 0 , sizeof(SVlanEntry));
SEntryBuf.u16Vid = pSCurGrp->u16Vid;
//SEntryBuf.bSvl = FALSE; //TOCHECK
SEntryBuf.u16Fid = pSCurGrp->u16Vid;
SEntryBuf.u32EgrsMbrPortMsk = u32UnTagMskDft; //TOCHECK
SEntryBuf.u32TagPortMsk = 0;
SWVLANTB_bSetEntry(&SEntryBuf); //TOCHECK
//update pvid
//protocol-based all mbr ports pvid = 0, unset mbr ports pvid = 1
for (si = 0; si < SWITCH_PORT_NUM; si++) {
if (u32UnTagMskDft & 0x00000001)
SWVLANTB_vPvidSet(si, VLAN_DEFAULT_GROUP_VID);
u32UnTagMskDft >>= 1;
if (pSPageBuf->byVlanMode == VLAN_MODE_PROTOBASE) {
if (u32TagMskDft & 0x00000001)
SWVLANTB_vPvidSet(si, VLAN_PRO_GROUP_MBR_VID);
u32TagMskDft >>= 1;
}
}
}
// Edit a vlan group
UINT8 PIVLAN_byEditGrp (SVlanPageCfg *pSPageBuf, PUINT16 pwFailVid)
{
UINT16 wTblPtr;
UINT16 u16Addr = 0;
UINT8 si;
UINT32 dwOriUntagMsk, dwOriTagMsk, dwUntagMsk, dwTagMsk, dwShftMsk = 0x00000001;
SVlanGrp SGrp;
// Init failed vid value
*pwFailVid = UINT16_MAX;
// If group id not exist, return error code
wTblPtr = PIVLNEEP_wSearchEntry(pSCurGrp->u16Vid);
if (wTblPtr == UINT16_MAX)
return VLAN_OP_GRP_NOT_EXIST;
// Update the current group in hardware
if ((pSPageBuf->byVlanMode == VLAN_MODE_8021Q) || (pSPageBuf->byVlanMode == VLAN_MODE_PROTOBASE) ) { // 802.1Q mode
// Check if untagged member overlapped
if (pSPageBuf->byVlanMode == VLAN_MODE_8021Q) {
*pwFailVid = s_w8021QCheckUntagMbrOverlap(pSPageBuf);
if (*pwFailVid != UINT16_MAX)
return VLAN_OP_UNTAG_BELONG_OTHER_GRP;
// Clear PVID setting of deleting ports
s_v8021QClearPvidOfDelMbr(wTblPtr);
}
// VLAN_MODE_PROTOBASE : Check if one port belong two the same protocol
if (pSPageBuf->byVlanMode == VLAN_MODE_PROTOBASE) {
// Get original cfg from eep
PIVLNEEP_vGetEntry(wTblPtr, &SGrp);
PICFGMP_vCvt4BPhyMskTo2bLogPtrMsk(SGrp.abyMbrMsk);
// Transform config bit mask into physical port mask
PICFGMP_v2bLogPtrMskTo4BPhyMsk(SGrp.abyMbrMsk, &dwOriTagMsk, &dwOriUntagMsk);
PICFGMP_v2bLogPtrMskTo4BPhyMsk(pSPageBuf->SCurGrp.abyMbrMsk, &dwTagMsk, &dwUntagMsk);
// Filter the original member
dwUntagMsk = dwUntagMsk & (~dwOriUntagMsk);
for (si = 0; si < SWITCH_PORT_NUM; si++) {
if (dwShftMsk & dwUntagMsk ) {
// Search entry
//SWPRVTB_vSearchEntry(si, pSPageBuf->SCurGrp.u8ProtoIndx-1, 0, &u16Addr, &byEntryNo); //TOCHECK
//u16Addr = SWPRVTB_u32SearchEntry(si, pSPageBuf->SCurGrp.u8ProtoIndx-1, 0); //TOCHECK
// If search failed, return with message
if (u16Addr != UINT16_MAX)
return VLAN_OP_MEMBER_BELONG_THE_SAME_PROTOCOL;
}
dwShftMsk <<= 1;
}
}
// Set new content into HW table
VLANv8021QInsEntry(pSPageBuf);
//(u8ProtoIndx == none) => only need to set entry into "vlan table"
//(u8ProtoIndx != none) => set entry into "vlan table" and "protocol vlan table"
if ((pSPageBuf->byVlanMode == VLAN_MODE_PROTOBASE) && (pSCurGrp->u8ProtoIndx != 0) )
VLANvPrvInsEntry(pSPageBuf);
}
else { // PortBase mode
// Edit group and set PVID & unused group
s_vPortBaseDelGrp(pSPageBuf, wTblPtr);
VLANvPortBaseInsGrp(pSCurGrp);
SWVLANTB_vPortBaseSetCfgForAllGrp();
}
// Update group content in EEPROM and return
VLANvTransBufFromCfgToEep();
PIVLNEEP_vEditEntry(wTblPtr, pSCurGrp);
PIVLNEEP_vStatisTblInfo(pSPageBuf);
VLANvTransBufFromEepToCfg();
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -