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

📄 pivlngrp.c

📁 vt6528芯片交换机API函数和文档运行程序
💻 C
📖 第 1 页 / 共 2 页
字号:
/*
 * 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 + -