⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 swvlan.c

📁 VIA VT6524 8口网管交换机源码
💻 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 + -