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

📄 swprvtb.c

📁 vt6528芯片交换机API函数和文档运行程序
💻 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:    swprvtb.c
 *
 * Purpose: Protocol based vlan operation functions
 *
 * Author:  Henry Lin
 *
 * Date:    May 20, 2005
 *
 * Functions:
 *
 * Revision History:
 *
 */


#if !defined(__STR_H__)
#include "str.h"
#endif
#if !defined(__SWITCH_H__)
#include "switch.h"
#endif
#if !defined(__SWSRAM_H__)
#include "swsram.h"
#endif
#if !defined(__SWPRVTB_H__)
#include "swprvtb.h"
#endif
#if !defined(__SWL2PTB_H__)
#include "swl2ptb.h"
#endif




/*---------------------  Static Definitions -------------------------*/
#define IP_ETHER_TYPE   0x0800

/*---------------------  Static Types  ------------------------------*/

/*---------------------  Static Macros  -----------------------------*/

/*---------------------  Static Classes  ----------------------------*/

/*---------------------  Static Variables  --------------------------*/
UINT8   au8RFC1042Ptn[]   = {0xAA, 0xAA, 0x03, 0x00, 0x00, 0x00};
UINT8   au8SNAP8021HPtn[] = {0xAA, 0xAA, 0x03, 0x00, 0x00, 0xF8};
UINT8   au8SNAPOtherPtn[] = {0xAA, 0xAA, 0x03};

/*---------------------  Static Functions  --------------------------*/

/*---------------------  Export Variables  --------------------------*/



BOOL SWPRVTB_bGetEntry(UINT8 u8EntryIdx, SProVlanEntry *pSEntry)
{
    SL2pACEntry SEntryAC;
    STcamEntry  SEntryTcam;
    BOOL        bMaskTbl = FALSE;
    UINT16      u16TmpType;


    // Get vid
    SWL2PAC_bGetEntry (u8EntryIdx, &SEntryAC);
    pSEntry->u16Vid = SEntryAC.u16L2pVid;

    // Get type, frame formate and TagPkt
    SWTCAM_bGetEntry (u8EntryIdx, &SEntryTcam, bMaskTbl);
    pSEntry->bTagPkt = SEntryTcam.bVlanTag;
#if defined(__LITTLE_ENDIAN)
        // convert SIP,DIP,IpOpt to byte array
        SWSRAM_vEndianConvert(&SEntryTcam.UCfg13B.au8AftSV[1], 4);
        SWSRAM_vEndianConvert(&SEntryTcam.UCfg13B.au8AftSV[5], 4);
        SWSRAM_vEndianConvert(&SEntryTcam.UCfg13B.au8AftSV[9], 4);
#endif

    u16TmpType = (SEntryTcam.UCfg13B.au8AftSV[0] << 8) | SEntryTcam.UCfg13B.au8AftSV[1];
    if (u16TmpType != 0){
        pSEntry->byFrameFormat = FRAME_FRMT_ETHER2;
        pSEntry->u16Type = SEntryTcam.UCfg13B.au8AftSV[OFFSET_ETHER2_TYPE] << 8 |
                           SEntryTcam.UCfg13B.au8AftSV[OFFSET_ETHER2_TYPE + 1];
    }
    else{
        if (STR_iMemcmp( &SEntryTcam.UCfg13B.au8AftSV[OFFSET_DSAP], au8RFC1042Ptn, sizeof(au8RFC1042Ptn)) == 0){
            pSEntry->byFrameFormat = FRAME_FRMT_RFC1042;
            pSEntry->u16Type = SEntryTcam.UCfg13B.au8AftSV[OFFSET_RFC1042_TYPE] << 8 | 
                               SEntryTcam.UCfg13B.au8AftSV[OFFSET_RFC1042_TYPE + 1];
        }
        else if (STR_iMemcmp( &SEntryTcam.UCfg13B.au8AftSV[OFFSET_DSAP], au8SNAP8021HPtn, sizeof(au8SNAP8021HPtn)) == 0){
            pSEntry->byFrameFormat = FRAME_FRMT_802_1H;
            pSEntry->u16Type = SEntryTcam.UCfg13B.au8AftSV[OFFSET_802_1H_TYPE] << 8 |
                               SEntryTcam.UCfg13B.au8AftSV[OFFSET_802_1H_TYPE + 1];
        }
        else if (STR_iMemcmp( &SEntryTcam.UCfg13B.au8AftSV[OFFSET_DSAP], au8SNAPOtherPtn, sizeof(au8SNAPOtherPtn)) == 0){
            pSEntry->byFrameFormat = FRAME_FRMT_SANP_OTHERS;
            pSEntry->u16Type = SEntryTcam.UCfg13B.au8AftSV[OFFSET_SANP_OTHERS_TYPE] << 8 |
                               SEntryTcam.UCfg13B.au8AftSV[OFFSET_SANP_OTHERS_TYPE + 1];
        }
        else{
            //Ipv4 or LLC
            u16TmpType = (SEntryTcam.UCfg13B.au8AftSV[OFFSET_DSAP] << 8) | SEntryTcam.UCfg13B.au8AftSV[OFFSET_DSAP + 1];
            if (u16TmpType != 0){
                pSEntry->byFrameFormat = FRAME_FRMT_LLC;
                pSEntry->u16Type = SEntryTcam.UCfg13B.au8AftSV[OFFSET_DSAP] << 8 |
                                   SEntryTcam.UCfg13B.au8AftSV[OFFSET_DSAP + 1];
            }
            else{
                pSEntry->byFrameFormat = FRAME_FRMT_ETHER2_IPV4;
                pSEntry->u16Type = IP_ETHER_TYPE;
            }
        }
    }
    

    return TRUE;
}


UINT16 SWPRVTB_u16SearchEntry(UINT16 u16Type, UINT16 u16Vid, UINT8 byFrameFormat)
{
    UINT16      u16Idx, u16TmpType;
    UINT8       u8Off;
    BOOL        bMaskTbl = FALSE;
    SL2pACEntry SEntryAC;
    STcamEntry  SEntryTcam;
    

    for (u16Idx = 0 ; u16Idx < TCAM_ENTRY_NUM; u16Idx++)
    {
        // Get vid, and compare
        if (!SWL2PAC_bGetEntry (u16Idx, &SEntryAC) )
            continue;
        if (SEntryAC.u16L2pVid != u16Vid)
            continue;
        
        // Compare Type
        SWTCAM_bGetEntry (u16Idx, &SEntryTcam, bMaskTbl);
#if defined(__LITTLE_ENDIAN)
        // convert SIP,DIP,IpOpt to byte array
        SWSRAM_vEndianConvert(&SEntryTcam.UCfg13B.au8AftSV[1], 4);
        SWSRAM_vEndianConvert(&SEntryTcam.UCfg13B.au8AftSV[5], 4);
        SWSRAM_vEndianConvert(&SEntryTcam.UCfg13B.au8AftSV[9], 4);
#endif
        switch(byFrameFormat)
        {
            case FRAME_FRMT_ETHER2_IPV4:
                // if ipv4, ether type not compare.
                // compare is IPv4
                if (SEntryTcam.bIpv4 == TRUE)
                    return u16Idx;
                continue;
                
            case FRAME_FRMT_ETHER2:
                u8Off = OFFSET_ETHER2_TYPE;
                break;

            case FRAME_FRMT_RFC1042:
            case FRAME_FRMT_802_1H:
            case FRAME_FRMT_SANP_OTHERS:
                u8Off = OFFSET_RFC1042_TYPE;
                break;
        
            case FRAME_FRMT_LLC:
                u8Off = OFFSET_DSAP;
                break;
    
            default:
                continue;   // unknow frame format
        }
        u16TmpType = (SEntryTcam.UCfg13B.au8AftSV[u8Off] << 8) | SEntryTcam.UCfg13B.au8AftSV[u8Off+1];
        if (u16TmpType == u16Type)
            return u16Idx;
    }

    return UINT16_MAX;
}


BOOL SWPRVTB_bInsEntry(SProVlanEntry *pSInsEntry, BOOL bIsOverWrite)
{
    UINT16      u16EntryIdx, u16ByteMsk, u16MskType;
    UINT8       u8Off;
    BOOL        bIsIpv4;
    UINT8       byTmpType[2];
    STcamEntry  SEntryTcam;
    SL2pACEntry SEntryAC;


    u16EntryIdx = SWPRVTB_u16SearchEntry(pSInsEntry->u16Type, pSInsEntry->u16Vid, pSInsEntry->byFrameFormat);
    
    // If entry already exist and can't be overwrote, then return operate fail.
    if ((u16EntryIdx != UINT16_MAX) && (!bIsOverWrite) )
        return FALSE;

    if (u16EntryIdx == UINT16_MAX){
        u16EntryIdx = SWL2PTB_u16FindEmptyEntry();
        if (u16EntryIdx == UINT16_MAX)
            return FALSE;   //TCAM table is full
    }


    //
    //  1.Insert L2+ value array
    //
    STR_pvMemset(&SEntryTcam, 0, sizeof(STcamEntry));

    // Incoming packet is VLAN-tagged packet
    SEntryTcam.bVlanTag = pSInsEntry->bTagPkt;

    *((PUINT16)byTmpType) =  pSInsEntry->u16Type;
#if defined(__LITTLE_ENDIAN)
    // convert u16Type to byte array
    SWSRAM_vEndianConvert(byTmpType, 2);
#endif

    SEntryTcam.bIpv4 = FALSE;
    bIsIpv4 = FALSE;
    u16MskType = MSK_IPV4 | MSK_VLAN_TYPE;
    u16ByteMsk = 0;     //13bytes mask after SMAC or VLAN-tag
    
    // Check frame format
    switch(pSInsEntry->byFrameFormat){
        case FRAME_FRMT_ETHER2_IPV4:
            SEntryTcam.bIpv4 = TRUE;
            bIsIpv4 = TRUE;
            break;

        case FRAME_FRMT_ETHER2:
            u8Off = OFFSET_ETHER2_TYPE;
            SEntryTcam.UCfg13B.au8AftSV[u8Off++] = byTmpType[0];
            SEntryTcam.UCfg13B.au8AftSV[u8Off++] = byTmpType[1];
            u16ByteMsk = 0x003;    //unmaked 1st,2nd octet after SMAC or VLAN-tag (0000 0000 0000 0011 b)
            break;

        case FRAME_FRMT_RFC1042:
            STR_pvMemcpy(&SEntryTcam.UCfg13B.au8AftSV[2], au8RFC1042Ptn, sizeof(au8RFC1042Ptn));
            u8Off = OFFSET_RFC1042_TYPE;
            SEntryTcam.UCfg13B.au8AftSV[u8Off++] = byTmpType[0];
            SEntryTcam.UCfg13B.au8AftSV[u8Off++] = byTmpType[1];
            u16ByteMsk = 0x03FC;    //unmaked 3rd,4th,5,6,7,8,9,10 octet after SMAC or VLAN-tag (0000 0011 1111 1100 b)
            break;

        case FRAME_FRMT_802_1H:
            STR_pvMemcpy(&SEntryTcam.UCfg13B.au8AftSV[2], au8SNAP8021HPtn, sizeof(au8SNAP8021HPtn));
            u8Off = OFFSET_802_1H_TYPE;
            SEntryTcam.UCfg13B.au8AftSV[u8Off++] = byTmpType[0];
            SEntryTcam.UCfg13B.au8AftSV[u8Off++] = byTmpType[1];
            u16ByteMsk = 0x03FC;
            break;

        case FRAME_FRMT_SANP_OTHERS:
            STR_pvMemcpy(&SEntryTcam.UCfg13B.au8AftSV[2], au8SNAPOtherPtn, sizeof(au8SNAPOtherPtn));
            u8Off = OFFSET_SANP_OTHERS_OUI;
            SEntryTcam.UCfg13B.au8AftSV[u8Off++] = pSInsEntry->abyOUI[0];
            SEntryTcam.UCfg13B.au8AftSV[u8Off++] = pSInsEntry->abyOUI[1];
            SEntryTcam.UCfg13B.au8AftSV[u8Off++] = pSInsEntry->abyOUI[2];
            SEntryTcam.UCfg13B.au8AftSV[u8Off++] = byTmpType[0];
            SEntryTcam.UCfg13B.au8AftSV[u8Off++] = byTmpType[1];
            u16ByteMsk = 0x03FC;
            break;

        case FRAME_FRMT_LLC:
            u8Off = OFFSET_DSAP;
            SEntryTcam.UCfg13B.au8AftSV[u8Off++] = byTmpType[0];
            SEntryTcam.UCfg13B.au8AftSV[u8Off++] = byTmpType[1];
            u16ByteMsk = 0x000C;    //unmaked 3rd,4th octet after SMAC or VLAN-tag (0000 0000 0000 1100 b)
            break;

        default:
            return FALSE;   // unknow frame format
    }
#if defined(__LITTLE_ENDIAN)
    // convert byte array to SIP,DIP,IpOpt
    SWSRAM_vEndianConvert(&SEntryTcam.UCfg13B.au8AftSV[1],4);
    SWSRAM_vEndianConvert(&SEntryTcam.UCfg13B.au8AftSV[5],4);
    SWSRAM_vEndianConvert(&SEntryTcam.UCfg13B.au8AftSV[9],4);
#endif
    SWTCAM_bInsEntry((UINT8)u16EntryIdx, &SEntryTcam, FALSE);
    
    
    //
    //  2.Insert L2+ masks array
    //
    STR_pvMemset(&SEntryTcam, 0, sizeof(STcamEntry));

    SWTCAM_vUnMskEntry(&SEntryTcam, bIsIpv4, u16MskType, u16ByteMsk);
#if defined(__LITTLE_ENDIAN)
    // convert byte array to SIP,DIP,IpOpt
    SWSRAM_vEndianConvert(&SEntryTcam.UCfg13B.au8AftSV[1],4);
    SWSRAM_vEndianConvert(&SEntryTcam.UCfg13B.au8AftSV[5],4);
    SWSRAM_vEndianConvert(&SEntryTcam.UCfg13B.au8AftSV[9],4);
#endif
    SWTCAM_bInsEntry((UINT8)u16EntryIdx, &SEntryTcam, TRUE);


    //
    //  3.Insert L2+ action array
    //
    STR_pvMemset(&SEntryAC, 0, sizeof(SL2pACEntry));
    SEntryAC.bL2pVidValid = TRUE;
    SEntryAC.u16L2pVid = pSInsEntry->u16Vid;
    SWL2PAC_bInsEntry((UINT8)u16EntryIdx, &SEntryAC);


    return TRUE;
}


BOOL SWPRVTB_bDelEntry(UINT16 u16Type, UINT16 u16Vid, UINT8 byFrameFormat)
{
    UINT16  u16EntryIdx;


    u16EntryIdx = SWPRVTB_u16SearchEntry(u16Type, u16Vid, byFrameFormat);
    
    if (u16EntryIdx == UINT16_MAX )
        return FALSE;   // Entry not exist , then return operate fail.

    SWL2PTB_vSetEntryInValidByIndex(u16EntryIdx);

    return TRUE;
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -