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

📄 swport.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:    swport.c
 *
 * Purpose: Port configuration and status hardware accessing functions
 *
 * Author:  Tevin Chen
 *          Henry Lin
 *
 * Date:    Jan 08, 2002
 *          Apr 26, 2005
 *
 * Functions:
 *
 * Revision History:
 *
 */


#if !defined(__PLATFORM_H__)
#include "platform.h"
#endif
#if !defined(__SWCFG_H__)
#include "swcfg.h"
#endif
#if !defined(__SWITCH_H__)
#include "switch.h"
#endif
#if !defined(__SWMII_H__)
#include "swmii.h"
#endif
#if !defined(__SWMSG_H__)
#include "swmsg.h"
#endif
#if !defined(__SWPORT_H__)
#include "swport.h"
#endif




/*---------------------  Static Definitions  ------------------------*/
// for N-way force only
static UINT16 sg_awSpdDpxPtn[] = {
    ANAR_100TXF,
    ANAR_100TXH,
    ANAR_10TXF,
    ANAR_10TXH,
    GBTCR_1000TF,
    GBTCR_1000TH,
};

// for force mode
static UINT16 sg_awFrcSpdDpxMiiVal[] = {
    (BMCR_SPD1 | BMCR_SPD0 | BMCR_FDX | BMCR_AUTO),  // bits
    (BMCR_SPD0 | BMCR_FDX),
    BMCR_SPD0,
    BMCR_FDX,
    0,
    (BMCR_SPD1 | BMCR_FDX),
    BMCR_SPD1
};

static UINT8 sg_abyFrcSpdDpxBitOn[] = {
    (PORT_ABL_FULL_DPX | PORT_ABL_SPD100),
    PORT_ABL_SPD100,
    PORT_ABL_FULL_DPX,
    0,
    (PORT_ABL_FULL_DPX | PORT_ABL_SPD1000),
    PORT_ABL_SPD1000
};

static UINT8 sg_abyFrcSpdDpxBitOff[] = {
    PORT_ABL_SPD1000,
    (PORT_ABL_FULL_DPX | PORT_ABL_SPD1000),
    (PORT_ABL_SPD100 | PORT_ABL_SPD1000),
    (PORT_ABL_FULL_DPX | PORT_ABL_SPD100| PORT_ABL_SPD1000),
    PORT_ABL_SPD100,
    (PORT_ABL_FULL_DPX | PORT_ABL_SPD100)
};

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

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

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

/*---------------------  Static Variables  --------------------------*/

/*---------------------  Static Functions  --------------------------*/
static void s_vTBIRestartAN(UINT8 byPortId);

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




BOOL SWPORT_bIsTbiPort(UINT8 byPortId)
{
    UINT8   u8Data;
    UINT16  u16GigaStrap;
    
    
    // Get port mode
    if ((SWITCH_PORT_NUM > byPortId) && (byPortId >= SWITCH_MEGA_PORT_NUM)) {
        //Strapping override
        SWREG_vReadU8(PHYCTL_PORT24_MODE_CFG + (byPortId - SWITCH_MEGA_PORT_NUM), &u8Data);
        if (u8Data & MODE_CFG_STRAP_OVERRIDE ){
            //by bit[0]
            if (u8Data & MODE_CFG_TBI)
                return TRUE;
            return FALSE;
        }
        else
        {
            //by strapping
            // Get giga port strapping value
            SWREG_vReadU16(INITCTL_CHIP_STRAP_CFG, &u16GigaStrap);
            if (u16GigaStrap & (CHIP_CFG_GIGA0_GMII >> (byPortId - SWITCH_MEGA_PORT_NUM)) )
                return FALSE;   //GMII
            return TRUE;        //TBI
        }
    }
    else {
        // Mega ports must not be TBI mode
        return FALSE;           
    }
}


BOOL SWPORT_bGetPortEn(UINT8 byPortId)
{
    if (SWPORT_bIsTbiPort(byPortId)) {
        // Get port enable
        if (SWREG_bIsBitsOnU8(PHYCTL_OPER_CFG_BASE + byPortId, PORT_ABL_ENABLE) )
            return TRUE;
        else
            return FALSE;
    }
    else {
        return SWMII_bIsRegBitsOff(byPortId, MII_REG_BMCR, BMCR_PD);
    }
}


void SWPORT_vSetPortEn(UINT8 byPortId, BOOL bPortEn)
{
    if (SWPORT_bIsTbiPort(byPortId)) {
        // Set port enable
        if (bPortEn) {
            // Enable Auto-polling
            SWREG_vSpecBitOn(PHYCTL_AUTO_POLLING_EN, byPortId);
        }
        else {
            // Disable Auto-polling
            SWREG_vSpecBitOff(PHYCTL_AUTO_POLLING_EN, byPortId);
            // Disable MAC I/O
            SWREG_vBitsOffU8(PHYCTL_OPER_CFG_BASE + byPortId, PORT_ABL_ENABLE);
        }
    }
    else {
        // Set port enable
        if (bPortEn) {
            SWMII_bRegBitsOff(byPortId, MII_REG_BMCR, BMCR_PD);
        }
        else {
            if (SWMII_bIsRegBitsOff(byPortId, MII_REG_BMCR, BMCR_PD))
                SWMII_bRegBitsOn(byPortId, MII_REG_BMCR, BMCR_PD);
        }
    }
}


UINT8 SWPORT_byGetSpdDpx (UINT8 byPortId)
{
    UINT8   byData;
    
    SWREG_vReadU8(PHYCTL_OPER_CFG_BASE + byPortId, &byData);
    if (byData & PORT_ABL_FULL_DPX) {
        if (byData & PORT_ABL_SPD1000)
            return PORT_SPDPX_1000M_FULL;
        else if (byData & PORT_ABL_SPD100)
            return PORT_SPDPX_100M_FULL;
        else
            return PORT_SPDPX_10M_FULL;
    }
    else {
        if (byData & PORT_ABL_SPD1000)
            return PORT_SPDPX_1000M_HALF;
        else if (byData & PORT_ABL_SPD100)
            return PORT_SPDPX_100M_HALF;
        else
            return PORT_SPDPX_10M_HALF;
    }
}


UINT8 SWPORT_bySetSpdDpx(UINT8 byPortId, BOOL bAuto, UINT8 byPortAbl)
{
    BOOL    bIsTBIPort = SWPORT_bIsTbiPort(byPortId);


    if (bAuto == 0 && byPortAbl == PORT_SPDPX_AUTO)
        return PORT_OP_WRONG_AUTO_ABY;

    if (bIsTBIPort) {
        // In TBI mode, MAC only supports auto and force-1000F.
        if (byPortAbl == PORT_SPDPX_AUTO) {
            SWREG_vBitsOnU8(PHYCTL_PORT24_MODE_CFG + byPortId - SWITCH_MEGA_PORT_NUM, MODE_CFG_TBI_ABL_NWAY);
            //restart AN
            s_vTBIRestartAN(byPortId);
            return OP_OK;
        }

        // If TBI force mode, it must be 1000Full
        if ((bAuto == 0) && (byPortAbl != PORT_SPDPX_1000M_FULL) )
            return OP_OK;

        SWREG_vBitsOffU8(PHYCTL_PORT24_MODE_CFG + byPortId - SWITCH_MEGA_PORT_NUM, MODE_CFG_TBI_ABL_NWAY);
        //restart AN
        s_vTBIRestartAN(byPortId);
        // then goto force mode to set ability
    }
    // set special Nway ability for via octo-phy only
    else if (PHYTYPE_VIA_MEGA == SWMII_byGetPhyType(byPortId) && byPortId < SWITCH_MEGA_PORT_NUM) {
        // nway-force only
        if ((bAuto) && (byPortAbl != PORT_SPDPX_AUTO))    
            SWMII_bRegBitsOn(byPortId, MII_REG_VIA_NWAYFRC, (0x0100 << ((byPortId % 8))));
        else
            SWMII_bRegBitsOff(byPortId, MII_REG_VIA_NWAYFRC, (0x0100 << ((byPortId % 8))));
    }
    
    // Set port auto port ability
    if (byPortAbl == PORT_SPDPX_AUTO) {
        SWMII_bRegBitsOn(byPortId, MII_REG_ANAR, ANAR_ABL_MEGA);

        if (byPortId >= SWITCH_GIGA_PORT_ID_BASE)
            SWMII_bRegBitsOn(byPortId, MII_REG_GBTCR, GBTCR_ABL_GIGA);

        SWMII_bRegBitsOn(byPortId, MII_REG_BMCR, BMCR_AUTO | BMCR_REAUTO);
    }
    // Set Nway forced port ability
    else if (bAuto) {
        SWMII_bRegBitsOff(byPortId, MII_REG_ANAR, ANAR_ABL_MEGA);

        if (byPortId >= SWITCH_GIGA_PORT_ID_BASE)
            SWMII_bRegBitsOff(byPortId, MII_REG_GBTCR, GBTCR_ABL_GIGA);

        if ((byPortId >= SWITCH_GIGA_PORT_ID_BASE) &&
            (byPortAbl == PORT_SPDPX_1000M_FULL || byPortAbl == PORT_SPDPX_1000M_HALF))
            SWMII_bRegBitsOn(byPortId, MII_REG_GBTCR, sg_awSpdDpxPtn[byPortAbl - 1]);
        else
            SWMII_bRegBitsOn(byPortId, MII_REG_ANAR, sg_awSpdDpxPtn[byPortAbl - 1]);

        SWMII_bRegBitsOn(byPortId, MII_REG_BMCR, BMCR_AUTO|BMCR_REAUTO);
    }
    // force mode
    else {
        SWREG_vBitsOnU8((PHYCTL_OPER_CFG_BASE + byPortId), sg_abyFrcSpdDpxBitOn[byPortAbl - 1]);
        SWREG_vBitsOffU8((PHYCTL_OPER_CFG_BASE + byPortId), sg_abyFrcSpdDpxBitOff[byPortAbl - 1]);

        if (!bIsTBIPort) {
            SWMII_bRegBitsOff(byPortId, MII_REG_BMCR, sg_awFrcSpdDpxMiiVal[0]);
            SWMII_bRegBitsOn(byPortId, MII_REG_BMCR, sg_awFrcSpdDpxMiiVal[byPortAbl]);

            // PATCH Braodcom phy: can not use Power-Down(bit11) to let phy link down
            if ((byPortId >= SWITCH_GIGA_PORT_ID_BASE) && (PHYTYPE_BROADCOM_GIGA == SWMII_byGetPhyType(byPortId)) ) {
                //BCM5421 can not use Power Down(bit11) to reach link down then link up.
                SWMII_bRegBitsOn(byPortId, MII_REG_BMCR, BMCR_LBK);
                // delay 200ms
                PLAT_vDelayLoop(200);
                SWMII_bRegBitsOff(byPortId, MII_REG_BMCR, BMCR_LBK);
            }
            else {
                // link down then link up to trigger remote port to change mode
                // note: some phy may not work or phy registers will be reset.
                // if port enable
                if (SWMII_bIsRegBitsOff(byPortId, MII_REG_BMCR, BMCR_PD)) {
                    SWMII_bRegBitsOn(byPortId, MII_REG_BMCR, BMCR_PD);
                    // delay 200ms
                    PLAT_vDelayLoop(200);
                    SWMII_bRegBitsOff(byPortId, MII_REG_BMCR, BMCR_PD);
                }
            }

        }
    }
    return OP_OK;
}


void SWPORT_vSetFlowCtrlEn(UINT8 byPortId, BOOL bFC)
{
    if (bFC) {
        // Set flow control ability
        SWREG_vSpecBitOn(PHYCTL_FLOW_CTRL_ABL, byPortId * 2);
        SWREG_vSpecBitOn(PHYCTL_FLOW_CTRL_ABL, byPortId * 2 + 1);
        // Set back pressure ability
        SWREG_vSpecBitOn(PHYCTL_BACK_PRESSURE_EN, byPortId);
    }
    else {
        // Set flow control ability
        SWREG_vSpecBitOff(PHYCTL_FLOW_CTRL_ABL, byPortId * 2);
        SWREG_vSpecBitOff(PHYCTL_FLOW_CTRL_ABL, byPortId * 2 + 1);
        // Set back pressure ability
        SWREG_vSpecBitOff(PHYCTL_BACK_PRESSURE_EN, byPortId);
    }

    // check if NWay ability is on
    // If TBI mode port
    if (SWPORT_bIsTbiPort(byPortId)) {
        // if auto mode
        if (SWREG_bIsBitsOnU8(PHYCTL_PORT24_MODE_CFG + byPortId - SWITCH_MEGA_PORT_NUM, MODE_CFG_TBI_ABL_NWAY)) {
            //restart AN
            s_vTBIRestartAN(byPortId);
        }
        return;
    }

    // If Auto/Nway-force mode
    if (SWMII_bIsRegBitsOn(byPortId, MII_REG_BMCR, BMCR_AUTO))
        SWMII_bRegBitsOn(byPortId, MII_REG_BMCR, BMCR_REAUTO);
}


static void s_vTBIRestartAN(UINT8 byPortId)
{
    SWREG_vBitsOnU8(PHYCTL_PORT24_MODE_CFG + byPortId - SWITCH_MEGA_PORT_NUM, MODE_CFG_TBI_LNK_DOWN);
    SWREG_vBitsOffU8(PHYCTL_PORT24_MODE_CFG + byPortId - SWITCH_MEGA_PORT_NUM, MODE_CFG_TBI_LNK_DOWN);
}


BOOL SWPORT_bGetLinkSts(UINT8 byPortId)
{
    UINT32 u32LnkChgSts = 0, u32Msk = 0x01;


    SWREG_vReadU32(PHYCTL_LINK_STATUS, &u32LnkChgSts);
    if (u32LnkChgSts & (u32Msk << byPortId) )
        return TRUE;
    
    return FALSE;
}


⌨️ 快捷键说明

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