📄 swvlan.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: swvlan.c
*
* Purpose: VLAN hardware accessing functions
*
* Author: Tevin Chen
*
* Date: Jan 08, 2002
*
* Functions:
*
* Revision History:
*
*/
#if !defined(__STR_H__)
#include "str.h"
#endif
#if !defined(__SWITCH_H__)
#include "switch.h"
#endif
#if !defined(__BITOP_H__)
#include "bitop.h"
#endif
#if !defined(__SWREG_H__)
#include "swreg.h"
#endif
#if !defined(__SWSRAM_H__)
#include "swsram.h"
#endif
#if !defined(__SWSYS_H__)
#include "swsys.h"
#endif
#if !defined(__SWVLAN_H__)
#include "swvlan.h"
#endif
/*--------------------- Static Definitions ------------------------*/
// Bit patterns related to VLAN table
#define VLAN_TBL_BASE_ADDR 0x9800 // For MAC 6K & VLAN 4k
// Definition for vlan operation
#define VLAN_CFG_PBASE_EN 0x40
#define VLAN_CFG_SVL_EN 0x10
#define VLAN_CFG_VLAN_EN 0x01
// Bit position for VLAN table fields
#define VLAN_BIT_FID_S 0 // 0
#define VLAN_BIT_FID_E 11 // 11
#define VLAN_BIT_MEMBER_S 12 // 12
#define VLAN_BIT_MEMBER_E 38 // 38
#define VLAN_BIT_TAG0TO24_S 39 // 39
#define VLAN_BIT_TAG0TO24_E 63 // 63
#define VLAN_BIT_TAG25_S 0 // 64
#define VLAN_BIT_TAG25_E 0 // 64
#define VLAN_BIT_VID_SPACE_S 4 // 68
#define VLAN_BIT_VID_SPACE_E 5 // 69
#define VLAN_BIT_SVL_S 6 // 70
#define VLAN_BIT_SVL_E 6 // 70
#define VLAN_BIT_VALID_S 62 // 126
#define VLAN_BIT_VALID_E 63 // 127
// Constants used for table operation
#define PTN_ENTRY_VALID 0x03 // Set Valid & VLAN bits
#define PTN_BIT_MASK_PORT25 0x2000000UL
// Pattern defined for sram operation
#define PTN_SRAM_STS_DONE 0x01
#define PTN_SRAM_STS_BUSY 0x02
#define PTN_SRAM_CMD_WRITE 0x02
// for INGRS_FILTER
#define PTN_VLAN_INFILTR_DISABLE 0
#define PTN_VLAN_INFILTR_NOTMBR 0x02 // drop not member packet, and so on.
#define PTN_VLAN_INFILTR_UNTAG 0x08
#define PTN_VLAN_INFILTR_NOTMBR_UNTAG 0x0A
// Definitions related to PortBase VLAN setting
#define PORTBASE_VLAN_GRP_VID_BASE 1
#define PORTBASE_VLAN_UNSET_GRP_VID 0x80
#define PORTBASE_VLAN_FID 0x80
// lookup table for g_aszIngrsFiltCfg
static DIRECT_MEMTYPE_CODE BYTE s_abyIngrsFilterPtn[] = {
PTN_VLAN_INFILTR_DISABLE,
PTN_VLAN_INFILTR_NOTMBR,
PTN_VLAN_INFILTR_UNTAG,
PTN_VLAN_INFILTR_NOTMBR_UNTAG
};
/*--------------------- Static Types ------------------------------*/
/*--------------------- Static Macros -----------------------------*/
#define s_wVidToAddr(wVid) (VLAN_TBL_BASE_ADDR + ((wVid & 0x0FFF) << 1))
#define s_wPortBaseGrpVid(byPortId) (UINT16)(byPortId + PORTBASE_VLAN_GRP_VID_BASE)
/*--------------------- Static Classes ----------------------------*/
/*--------------------- Static Variables --------------------------*/
/*--------------------- Static Functions --------------------------*/
/*--------------------- Export Variables --------------------------*/
void SWVLAN_vSetVlanMode(BYTE byVlanMode) DIRECT_FUNTYPE_REENT
{
switch (byVlanMode) {
case VLAN_MODE_PORTBASE:
SWREG_vWriteB(FWD_VLAN_CFG, VLAN_CFG_VLAN_EN | VLAN_CFG_SVL_EN | VLAN_CFG_PBASE_EN);
return;
case VLAN_MODE_8021Q:
SWREG_vWriteB(FWD_VLAN_CFG, VLAN_CFG_VLAN_EN);
return;
default:
SWREG_vWriteB(FWD_VLAN_CFG, 0);
return;
}
}
BOOL SWVLAN_bGetEntry(UINT16 wVid, SVlanEntry *pSEntry) DIRECT_FUNTYPE_REENT
{
BYTE abyEntryBuf[SRAM_CTRL_SLOT_SIZE], byTmp;
UINT16 wAddr;
// Read entry from sram (second slot)
wAddr = s_wVidToAddr(wVid) + 1;
SWSRAM_bReadSlot(wAddr, abyEntryBuf);
// Check if the entry valid
BITvExtractBits(abyEntryBuf, VLAN_BIT_VALID_S, VLAN_BIT_VALID_E, &byTmp);
if (byTmp != PTN_ENTRY_VALID)
return FALSE;
// Get vid value
pSEntry->wVid = wVid;
// Get svl field
BITvExtractBits( abyEntryBuf, VLAN_BIT_SVL_S, VLAN_BIT_SVL_E, (PBYTE)&(pSEntry->bSvl) );
// Get tag field of port 25 (it crosses over 8 byte sram buffer boundary)
BITvExtractBits( abyEntryBuf, VLAN_BIT_TAG25_S, VLAN_BIT_TAG25_E, &byTmp );
// Read entry from sram (first slot)
wAddr--;
SWSRAM_bReadSlot(wAddr, abyEntryBuf);
// Get fid field
BITvExtractBits( abyEntryBuf, VLAN_BIT_FID_S, VLAN_BIT_FID_E, (PBYTE)&(pSEntry->wFid) );
// Get member field
BITvExtractBits( abyEntryBuf, VLAN_BIT_MEMBER_S, VLAN_BIT_MEMBER_E, (PBYTE)&(pSEntry->dwMbrPortMsk) );
// Get tag rule field
BITvExtractBits( abyEntryBuf, VLAN_BIT_TAG0TO24_S, VLAN_BIT_TAG0TO24_E, (PBYTE)&(pSEntry->dwTagPortMsk) );
if (byTmp) // if port 25 is also tagged, add it
pSEntry->dwTagPortMsk |= PTN_BIT_MASK_PORT25;
return TRUE;
}
void SWVLAN_vSetEntry(SVlanEntry *pSEntry) DIRECT_FUNTYPE_REENT
{
BYTE abyEntryBuf[SRAM_CTRL_SLOT_SIZE], byTmp;
UINT16 wAddr;
// Set entry content and write into sram
wAddr = s_wVidToAddr(pSEntry->wVid);
STRvMemset(abyEntryBuf, 0, SRAM_CTRL_SLOT_SIZE);
// Set fid field
BITvModifyBits(abyEntryBuf, VLAN_BIT_FID_S, VLAN_BIT_FID_E, (PBYTE)&(pSEntry->wFid));
// Set member field
pSEntry->dwMbrPortMsk |= PTN_BIT_MASK_CPU_PORT; // CPU port must be vlan member
BITvModifyBits(abyEntryBuf, VLAN_BIT_MEMBER_S, VLAN_BIT_MEMBER_E, (PBYTE)&pSEntry->dwMbrPortMsk);
// Set tag rule field
BITvModifyBits(abyEntryBuf, VLAN_BIT_TAG0TO24_S, VLAN_BIT_TAG0TO24_E, (PBYTE)&pSEntry->dwTagPortMsk);
SWSRAM_bWriteSlot(wAddr, abyEntryBuf);
// Set entry content and write into sram (second sram slot)
wAddr++;
STRvMemset(abyEntryBuf, 0, SRAM_CTRL_SLOT_SIZE);
// Set tag field of port 25 (it crosses over 8 byte sram buffer boundary)
if (pSEntry->dwTagPortMsk & PTN_BIT_MASK_PORT25) { // if port 25 is also tagged, add it
byTmp = 1;
BITvModifyBits(abyEntryBuf, VLAN_BIT_TAG25_S, VLAN_BIT_TAG25_E, &byTmp);
}
// Set vid space field
byTmp = (pSEntry->wVid >> 10);
BITvModifyBits(abyEntryBuf, VLAN_BIT_VID_SPACE_S, VLAN_BIT_VID_SPACE_E, &byTmp);
// Set svl field
BITvModifyBits(abyEntryBuf, VLAN_BIT_SVL_S, VLAN_BIT_SVL_E, (PBYTE)&(pSEntry->bSvl));
// Set entry as valid
byTmp = PTN_ENTRY_VALID;
BITvModifyBits(abyEntryBuf, VLAN_BIT_VALID_S, VLAN_BIT_VALID_E, &byTmp);
SWSRAM_bWriteSlot(wAddr, abyEntryBuf);
}
void SWVLAN_vClearEntry(UINT16 wVid) DIRECT_FUNTYPE_REENT
{
// clear valid bit
SWSRAM_bSetEntryInvalid( s_wVidToAddr(wVid) + 1 );
}
void SWVLAN_vSetIngrsFilter(BYTE byPortId, BYTE byCfg) DIRECT_FUNTYPE_REENT
{
SWREG_vWriteB((UINT16)(FWD_INGRESS_FILTR_BASE + byPortId), s_abyIngrsFilterPtn[byCfg]);
}
void SWVLAN_vClearAllPortBaseGrp(void) DIRECT_FUNTYPE_REENT
{
UINT8 uu;
// Clear group of each port
for (uu = 0; uu < SWITCH_PORT_NUM; uu++)
SWVLAN_vClearEntry( s_wPortBaseGrpVid(uu) );
// Clear unused group
SWVLAN_vClearEntry(PORTBASE_VLAN_UNSET_GRP_VID);
}
void SWVLAN_vAddPortBaseGrp (UINT32 dwMbrMsk) DIRECT_FUNTYPE_REENT
{
SVlanEntry SEntryBuf;
UINT32 dwShftBuf = 0x01;
UINT8 byPortId;
// Set vlan group of each member port
for (byPortId = 0; byPortId < SWITCH_PORT_NUM; byPortId++) {
// Update members in current group
if ((dwMbrMsk & dwShftBuf) != 0) {
// If entry not exist, insert one
if ( !SWVLAN_bGetEntry(s_wPortBaseGrpVid(byPortId), &SEntryBuf) ) {
SEntryBuf.wVid = s_wPortBaseGrpVid(byPortId);
SEntryBuf.bSvl = TRUE;
SEntryBuf.wFid = PORTBASE_VLAN_FID;
SEntryBuf.dwMbrPortMsk = dwMbrMsk;
SEntryBuf.dwTagPortMsk = 0;
}
// If entry exists, modify member
else
SEntryBuf.dwMbrPortMsk |= dwMbrMsk;
// Update vlan table entry
SWVLAN_vSetEntry(&SEntryBuf);
}
dwShftBuf <<= 1;
}
}
void SWVLAN_vSetPortBaseCfgForAllGrp (void) DIRECT_FUNTYPE_REENT
{
SVlanEntry SEntryBuf;
UINT32 dwMskBuf = 0;
BYTE byPortId;
// Set PVID to each port and statistic existing member ports
for (byPortId = 0; byPortId < SWITCH_PORT_NUM; byPortId++) {
SWVLAN_vSetPvid(byPortId, s_wPortBaseGrpVid(byPortId));
if ( SWVLAN_bGetEntry(s_wPortBaseGrpVid(byPortId), &SEntryBuf) )
dwMskBuf |= SEntryBuf.dwMbrPortMsk;
}
// Set unset-group from member port statistic result
SEntryBuf.wVid = PORTBASE_VLAN_UNSET_GRP_VID;
SEntryBuf.bSvl = TRUE;
SEntryBuf.wFid = PORTBASE_VLAN_FID;
SEntryBuf.dwMbrPortMsk = ~dwMskBuf;
SEntryBuf.dwTagPortMsk = 0;
SWVLAN_vSetEntry(&SEntryBuf);
// Set Pvid of unused ports
dwMskBuf = 0x01;
for (byPortId = 0; byPortId < SWITCH_PORT_NUM; byPortId++) {
if ((SEntryBuf.dwMbrPortMsk & dwMskBuf) != 0)
SWVLAN_vSetPvid(byPortId, PORTBASE_VLAN_UNSET_GRP_VID);
dwMskBuf <<= 1;
}
}
void SWVLAN_vGetPvid(BYTE byPortId, PUINT16 pwPvid) DIRECT_FUNTYPE_REENT
{
SWREG_vReadB(FWD_PVID_BASE + byPortId, (PBYTE)pwPvid + 1);
if (CHIP_VT3221 == SWSYS_byGetChipType())
SWREG_vReadB(FWD_PVID_BASE_11_8 + byPortId, (PBYTE)pwPvid);
}
void SWVLAN_vSetPvid(BYTE byPortId, UINT16 wPvid) DIRECT_FUNTYPE_REENT
{
SWREG_vWriteB(FWD_PVID_BASE + byPortId, (BYTE)wPvid);
if (CHIP_VT3221 == SWSYS_byGetChipType())
SWREG_vWriteB(FWD_PVID_BASE_11_8 + byPortId, (BYTE)(wPvid >> 8));
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -