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

📄 pivlngrp.c

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


// Delete a vlan group
UINT8 PIVLAN_byDelGrp (SVlanPageCfg *pSPageBuf, PUINT16 pwFailVid)
{
    UINT16   wTblPtr;

    // Init failed vid value
    *pwFailVid = UINT16_MAX;

    // Default group is not able to be deleted
    if (((pSPageBuf->byVlanMode == VLAN_MODE_8021Q) || (pSPageBuf->byVlanMode == VLAN_MODE_PROTOBASE)) &&
         (pSCurGrp->u16Vid == VLAN_DEFAULT_GROUP_VID) )
        return VLAN_OP_DEFAULT_GRP_CANNOT_DEL;

    // If group id not exist, return error code
    wTblPtr = PIVLNEEP_wSearchEntry(pSCurGrp->u16Vid);
    if (wTblPtr == UINT16_MAX)
        return VLAN_OP_GRP_NOT_EXIST;

    // Delete group from hardware
    if ((pSPageBuf->byVlanMode == VLAN_MODE_8021Q) || (pSPageBuf->byVlanMode == VLAN_MODE_PROTOBASE) ) {     // 802.1Q mode
        // Deleting operation
        if (pSPageBuf->byVlanMode == VLAN_MODE_8021Q)
            s_v8021QClearPvidOfDelMbr(wTblPtr);
        SWVLANTB_bDelEntry( pSCurGrp->u16Vid );

        // Get entry from EEPROM and transfer into config buffer format
        PIVLNEEP_vGetEntry(wTblPtr, pSCurGrp);
        VLANvTransBufFromEepToCfg();
        
        if ((pSPageBuf->byVlanMode == VLAN_MODE_PROTOBASE) && (pSCurGrp->u8ProtoIndx != 0) )          
            VLANvPrvDelEntry(pSPageBuf);
    }

    else {                                              // PortBase mode
        // Delete group and set PVID & unused group
        s_vPortBaseDelGrp(pSPageBuf, wTblPtr);
        SWVLANTB_vPortBaseSetCfgForAllGrp();
    }

    // Delete group from EEPROM and return
    PIVLNEEP_vDelEntry(wTblPtr);
    PIVLNEEP_vStatisTblInfo(pSPageBuf);

    //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;
}

static UINT32 s_u32GetOldMbrMsk(UINT16 u16Vid)
{
    SVlanPageCfg    sPageBuf;
    UINT32          u32UntagMsk, u32TagMsk;
    
    STR_pvMemset(&sPageBuf, 0, sizeof(SVlanPageCfg));
    sPageBuf.SCurGrp.u16Vid = u16Vid;
    PIVLAN_byGetGrp(&sPageBuf);
    PICFGMP_v2bLogPtrMskTo4BPhyMsk(sPageBuf.SCurGrp.abyMbrMsk, &u32TagMsk, &u32UntagMsk);

    return (u32UntagMsk | u32TagMsk);    
}

// Insert ProtocolBased entry into HW table 
void VLANvPrvInsEntry (SVlanPageCfg *pSPageBuf)
{
    SProVlanEntry   sPrvTblEntry; //TOCHECK
    UINT32          u32MskTmp1, u32MskTmp2, u32OldMsk, u32NewMsk;
    UINT8           si, sj;

    STR_pvMemset(&sPrvTblEntry, 0, sizeof(SProVlanEntry)); //TOCHECK
    PICFGMP_v2bLogPtrMskTo4BPhyMsk(pSCurGrp->abyMbrMsk, &u32MskTmp1, &u32MskTmp2);
    u32NewMsk = (u32MskTmp1 | u32MskTmp2);
    
    // Transform config bit mask into physical port mask
    u32OldMsk = s_u32GetOldMbrMsk(pSCurGrp->u16Vid);

    //need to del portmsk
    u32MskTmp1 = (u32OldMsk & ~u32NewMsk);

    for (si = 0; si < SWITCH_PORT_NUM; si++) {
        if (u32MskTmp1 & 0x00000001) {
            for (sj = 0; sj < 4; sj++)
                SWPRVTB_bDelEntry(si, (pSCurGrp->u8ProtoIndx-1), sj);
        }
        u32MskTmp1 >>= 1;

        if (u32NewMsk & 0x00000001) {
            sPrvTblEntry.u16Vid = pSCurGrp->u16Vid;
            //sPrvTblEntry.byPortId = si; //TOCHECK
            //sPrvTblEntry.byProtoIndx = (pSCurGrp->u8ProtoIndx-1); //TOCHECK

            for (sj = 0; sj < 4; sj++) {
                sPrvTblEntry.byFrameFormat = sj;
                SWPRVTB_bInsEntry(&sPrvTblEntry, 1);
            }
        }
        u32NewMsk >>= 1;
    }            
}

// Delete ProtocolBased entry in HW table 
void VLANvPrvDelEntry (SVlanPageCfg *pSPageBuf)
{
    UINT32          u32MskTmp1, u32MskTmp2, u32NewMsk;
    UINT8           si, sj;

    PICFGMP_v2bLogPtrMskTo4BPhyMsk(pSCurGrp->abyMbrMsk, &u32MskTmp1, &u32MskTmp2);
    u32NewMsk = (u32MskTmp1 | u32MskTmp2);
    
    for (si = 0; si < SWITCH_PORT_NUM; si++) {
        if (u32NewMsk & 0x00000001) {
            for (sj = 0; sj < 4; sj++)
                SWPRVTB_bDelEntry(si, (pSCurGrp->u8ProtoIndx-1), sj);
        }
        u32NewMsk >>= 1;
    }            
}

// Insert 802.1Q entry into HW table and set related PVID config
void VLANv8021QInsEntry (SVlanPageCfg *pSPageBuf)
{
    SVlanEntry  SEntryBuf;
    UINT32      dwUntagMsk, dwTagMsk, dwShftMsk = 0x00000001;
    UINT8       si;


    STR_pvMemset(&SEntryBuf, 0 , sizeof(SVlanEntry));
    // Transform config bit mask into physical port mask
    PICFGMP_v2bLogPtrMskTo4BPhyMsk(pSCurGrp->abyMbrMsk, &dwTagMsk, &dwUntagMsk);

    // If a port is set to be untagged member of a group, set PVID to it's VID value.
    if (pSPageBuf->byVlanMode == VLAN_MODE_8021Q) {
        for (si = 0; si < SWITCH_PORT_NUM; si++) {
            if (dwShftMsk & dwUntagMsk )
                SWVLANTB_vPvidSet(si, (pSCurGrp->u16Vid) );
            dwShftMsk <<= 1;
        }
    }

    // Set entry into vlan table
    SEntryBuf.u16Vid = pSCurGrp->u16Vid;
    SEntryBuf.u16Fid = pSCurGrp->u16Vid;
    SEntryBuf.u32EgrsMbrPortMsk = (dwUntagMsk | dwTagMsk);
    SEntryBuf.u32TagPortMsk = dwTagMsk;
    SEntryBuf.u32IngrsMbrPortMsk = SEntryBuf.u32EgrsMbrPortMsk;

    // Insert entry into HW table
    SWVLANTB_bSetEntry(&SEntryBuf);
}


// Clear PVID setting related to deleting entry
static void s_v8021QClearPvidOfDelMbr (UINT16 wTblPtr)
{
    // NOTE: VLAN group buffer here must be local buffer
    //       since this function may be executed by PIVLAN_byEditGrp
    //       and the new content must not be overwritten
    SVlanGrp    SGrpBuf;
    UINT32      dwUntagMsk = 0, dwTagMsk = 0;
    UINT8       si;

    // Get target group
    PIVLNEEP_vGetEntry(wTblPtr, &SGrpBuf);
    STR_pvMemcpy( (PUINT8)(&dwTagMsk)+BYTE_OFFSET_IN_DWORD_OF_CFGMASK,
                SGrpBuf.abyMbrMsk+BYTE_NUM_OF_CFGBUF_BIT_MASK, BYTE_NUM_OF_CFGBUF_BIT_MASK );
    STR_pvMemcpy( (PUINT8)(&dwUntagMsk)+BYTE_OFFSET_IN_DWORD_OF_CFGMASK,
                SGrpBuf.abyMbrMsk, BYTE_NUM_OF_CFGBUF_BIT_MASK );

    // If a port is set to be untagged member of a group, clear its PVID.
    for (si = 0; si < SWITCH_PORT_NUM; si++) {
        if (dwUntagMsk & 0x00000001 )
            SWVLANTB_vPvidSet(si, 0);
        dwUntagMsk >>= 1;
    }
}


// Check if a port being untagged member of more than one group
static UINT16 s_w8021QCheckUntagMbrOverlap (SVlanPageCfg *pSPageBuf)
{
    UINT32  dwUntagMsk, dwTagMsk;
    UINT16  wPvidBuf = 0, sj;
    UINT8   si;


    // Transform config bit mask into physical port mask
    PICFGMP_v2bLogPtrMskTo4BPhyMsk(pSCurGrp->abyMbrMsk, &dwTagMsk, &dwUntagMsk);

    // If current PVID is already belonging to group with vid N, return GROUP INDEX of group N
    for (si = 0; si < SWITCH_PORT_NUM; si++) {
        if (dwUntagMsk & 0x00000001 ) {
            SWVLANTB_vPvidGet(si, &wPvidBuf);
            if ((wPvidBuf != 0) && (wPvidBuf != pSCurGrp->u16Vid) ) {
                for (sj = 0; sj < pSPageBuf->wValidEntryNum; sj++) {
                    if (pSPageBuf->awValidGrpIdList[sj] == wPvidBuf )
                        return pSPageBuf->awValidGrpIdList[sj];
                }
            }
        }
        dwUntagMsk >>= 1;
    }

    // If check ok, return UINT16_MAX
    return UINT16_MAX;
}


// Find 802.1Q isolated port (in format of log ptr)
static UINT8 s_by8021QFindIsoPort (SVlanPageCfg *pSPageBuf, PUINT16 pwFailVid)
{
    SVlanGrp    SGrpBuf;
    UINT32      dwMbrMsk = 0, dwTmp = 0;
    UINT16      si;

    // Statistic members of all groups
    for (si = 0; si < pSPageBuf->wValidEntryNum; si++) {
        PIVLNEEP_vGetEntry( PIVLNEEP_wSearchEntry(pSPageBuf->awValidGrpIdList[si]), &SGrpBuf );

        // Statistic untagged setting of all groups
        STR_pvMemcpy( (PUINT8)(&dwTmp)+BYTE_OFFSET_IN_DWORD_OF_CFGMASK,
                    SGrpBuf.abyMbrMsk, BYTE_NUM_OF_CFGBUF_BIT_MASK );
        dwMbrMsk |= dwTmp;

        // Statistic tagged setting of non-default groups
        STR_pvMemcpy( (PUINT8)(&dwTmp)+BYTE_OFFSET_IN_DWORD_OF_CFGMASK,
                    SGrpBuf.abyMbrMsk+BYTE_NUM_OF_CFGBUF_BIT_MASK, BYTE_NUM_OF_CFGBUF_BIT_MASK );
        dwMbrMsk |= dwTmp;
    }

    for (si = 0; si < SWITCH_PORT_NUM; si++) {
        if (!(dwMbrMsk & 0x00000001) ) {
            *pwFailVid = PIPORTMP_byPhyIdToLogId(si);
            if (*pwFailVid != ENTRY_END_FLAG)   // may be module port is not exist
                return VLAN_OP_FOUND_ISO_PORT;
        }
        dwMbrMsk >>= 1;
    }

    return OP_OK;
}



void VLANvPortBaseInsGrp (SVlanGrp *pSGrp)
{
    UINT32  dwMbrMsk, dwDummy;

    PICFGMP_v2bLogPtrMskTo4BPhyMsk( pSGrp->abyMbrMsk, &dwDummy, &dwMbrMsk );
    SWVLANTB_vPortBaseAddGrp(dwMbrMsk);
}


static void s_vPortBaseDelGrp (SVlanPageCfg *pSPageBuf, UINT16 wTblPtr)
{
    union   // For reducing stack usage
    {
        SVlanGrp    SGrp;
        SVlanEntry  SEntry;
    } UVlanBuf;

    UINT32      dwDelMbrMsk = 0, dwMbrMsk = 0;
    UINT16      si, wTmp;

    // Get target group and transfer config bit mask into physical port mask
    PIVLNEEP_vGetEntry(wTblPtr, &UVlanBuf.SGrp);
    STR_pvMemcpy( (PUINT8)(&dwDelMbrMsk)+BYTE_OFFSET_IN_DWORD_OF_CFGMASK,
                UVlanBuf.SGrp.abyMbrMsk, BYTE_NUM_OF_CFGBUF_BIT_MASK );

    // Remove deleting mbrs from vlan table entries containing one of deleting ports as mbr
    for (si = 0; si < SWITCH_PORT_NUM; si++) {
        if (SWVLANTB_bGetEntry( PORTBASE_ID_TO_VID(si), &UVlanBuf.SEntry ) &&
                (UVlanBuf.SEntry.u32EgrsMbrPortMsk & dwDelMbrMsk & ~BIT_MASK_PORT_CPU) ) {
            UVlanBuf.SEntry.u32EgrsMbrPortMsk &= ~dwDelMbrMsk;
            UVlanBuf.SEntry.u32IngrsMbrPortMsk &= ~dwDelMbrMsk;
            // If called by deleting or no more members left, delete whole entry
            if (UVlanBuf.SEntry.u32EgrsMbrPortMsk == BIT_MASK_PORT_CPU)
                SWVLANTB_bDelEntry( PORTBASE_ID_TO_VID(si) );
            // If called by editing, keep innocent members untouched
            else
                SWVLANTB_bSetEntry(&UVlanBuf.SEntry);
        }
    }

    // Add all groups back from EEPROM that containing one of deleting ports as member
    // (except the deleting one)
    for (si = 0; si < pSPageBuf->wValidEntryNum; si++) {

        wTmp = PIVLNEEP_wSearchEntry(pSPageBuf->awValidGrpIdList[si]);
        if (wTmp == wTblPtr)
            continue;

        PIVLNEEP_vGetEntry(wTmp, &UVlanBuf.SGrp);
        STR_pvMemcpy( (PUINT8)(&dwMbrMsk)+BYTE_OFFSET_IN_DWORD_OF_CFGMASK,
                    UVlanBuf.SGrp.abyMbrMsk, BYTE_NUM_OF_CFGBUF_BIT_MASK );

        if (dwMbrMsk & dwDelMbrMsk & ~BIT_MASK_PORT_CPU)
            SWVLANTB_vPortBaseAddGrp(dwMbrMsk);
    }
}


⌨️ 快捷键说明

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