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

📄 swmii.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:    swmii.c
 *
 * Purpose: Phy register hardware accessing functions
 *
 * Author:  Tevin Chen
 *
 * Date:    Jan 08, 2002
 *
 * Functions:
 *
 * Revision History:
 *
 */


#if !defined(__PLATFORM_H__)
#include "platform.h"
#endif
#if !defined(__SWITCH_H__)
#include "switch.h"
#endif
#if !defined(__SWREG_H__)
#include "swreg.h"
#endif
#if !defined(__SWMII_H__)
#include "swmii.h"
#endif




/*---------------------  Static Definitions  ------------------------*/

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

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

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

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

/*---------------------  Static Functions  --------------------------*/
static BOOL s_bMiiReadOp(UINT8 byPortId, UINT8 byAddr, PUINT16 pwData);
static BOOL s_bMiiWriteOp(UINT8 byPortId, UINT8 byAddr, UINT16 wData);

static UINT16 s_wPhyFeatureHandler(UINT8 byPortId, UINT8 byAddr, UINT16 wData);
static BOOL s_bRegBitsOn(UINT8 byPortId, UINT8 byAddr, UINT16 wBitPtn);
static BOOL s_bRegBitsOff(UINT8 byPortId, UINT8 byAddr, UINT16 wBitPtn);

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




static BOOL s_bMiiReadOp (UINT8 byPortId, UINT8 byAddr, PUINT16 pwData)
{
    BOOL bWasAutoPollOn, bRes = TRUE;



    // protect phy data reg from being ruined before using it
    PLAT_vCpuCriticalEnter();

    // Wait for Phy idle to issue read command
    if (!SWREG_bWaitStatus(PHYCTL_STATUS, PHY_STATUS_BUSY, FALSE)) {
        PLAT_vCpuCriticalExit();
        return FALSE;
    }

    // Record original auto-polling status and disable it
    bWasAutoPollOn = SWREG_bIsBitsOnU8(PHYCTL_CMD, PHY_CMD_EN_AUTO);

    if (bWasAutoPollOn)
        SWMII_vSetAutoPollOff();

    // Set port ID
    SWREG_vWriteU8(PHYCTL_CMD_PORTID, byPortId);
    // Set phy register address
    SWREG_vWriteU8(PHYCTL_REG_ADDR, byAddr);
    // Trigger write operation and wait for complete
    SWREG_vWriteU8(PHYCTL_CMD, PHY_CMD_READ);

    if (!SWREG_bWaitStatus(PHYCTL_STATUS, PHY_STATUS_BUSY, FALSE)) {
        bRes = FALSE;
        goto ExitFunc;
    }

    // Check command is OK or Error.
    if (SWREG_bIsBitsOnU8(PHYCTL_STATUS, PHY_STATUS_READ_ERR) ){
        bRes = FALSE;
        goto ExitFunc;
    }

    // Read register data
    SWREG_vReadU16(PHYCTL_RD_DATA, pwData);
    bRes = TRUE;                //lucas

ExitFunc:
    // Write original auto-polling status back
    if (bWasAutoPollOn)
        SWMII_vSetAutoPollOn();

    PLAT_vCpuCriticalExit();
    return bRes;
}


static BOOL s_bMiiWriteOp (UINT8 byPortId, UINT8 byAddr, UINT16 wData)
{
    BOOL    bWasAutoPollOn, bRes;


    // protect phy data reg from being ruined before using it
    PLAT_vCpuCriticalEnter();

    // Wait for Phy idle to issue write command
    if (!SWREG_bWaitStatus(PHYCTL_STATUS, PHY_STATUS_BUSY, FALSE)) {
        PLAT_vCpuCriticalExit();
        return FALSE;
    }

    // Record original auto-polling status and disable it
    bWasAutoPollOn = SWREG_bIsBitsOnU8(PHYCTL_CMD, PHY_CMD_EN_AUTO);
    if (bWasAutoPollOn)
        SWMII_vSetAutoPollOff();

    // Set port ID and switch SPI mode
    SWREG_vWriteU8(PHYCTL_CMD_PORTID, byPortId);
    // Set phy register address
    SWREG_vWriteU8(PHYCTL_REG_ADDR, byAddr);
    // Set write content
    SWREG_vWriteU16(PHYCTL_WR_DATA, wData);
    // Trigger write operation and wait for complete
    SWREG_vWriteU8(PHYCTL_CMD, PHY_CMD_WRITE);

    bRes = SWREG_bWaitStatus(PHYCTL_STATUS, PHY_STATUS_BUSY, FALSE);

    // Write original auto-polling status back
    if (bWasAutoPollOn)
        SWMII_vSetAutoPollOn();

    PLAT_vCpuCriticalExit();
    return bRes;
}


BOOL SWMII_bReadU16 (UINT8 byPortId, UINT8 byAddr, PUINT16 pwData)
{
    return s_bMiiReadOp(byPortId, byAddr, pwData);
}


BOOL SWMII_bWriteU16 (UINT8 byPortId, UINT8 byAddr, UINT16 wData)
{
    wData = s_wPhyFeatureHandler (byPortId, byAddr, wData);
    return s_bMiiWriteOp (byPortId, byAddr, wData);
}


BOOL SWMII_bIsRegBitsOn (UINT8 byPortId, UINT8 byAddr, UINT16 wBitPtn)
{
    UINT16 wOrgData;

    SWMII_bReadU16(byPortId, byAddr, &wOrgData);
    return ((wOrgData & wBitPtn) == wBitPtn);
}

BOOL SWMII_bIsRegBitsOff (UINT8 byPortId, UINT8 byAddr, UINT16 wBitPtn)
{
    UINT16 wOrgData;

    SWMII_bReadU16(byPortId, byAddr, &wOrgData);
    return ((wOrgData & wBitPtn) == 0);
}


static UINT16 s_wPhyFeatureHandler (UINT8 byPortId, UINT8 byAddr, UINT16 wData)
{
    UINT16  wTmp;
    UINT8   byPhyType;

    // Handle different feature of different phy module
    byPhyType = SWMII_byGetPhyType(byPortId);
    switch (byPhyType) {
        case PHYTYPE_CICADA_GIGA:
             s_bRegBitsOn (byPortId, MII_REG_CICADA_ACSR, CICADA_ACSR_MODE_SEL);
             break;

        case PHYTYPE_MARVELL_GIGA:
        case PHYTYPE_MARVELL_MEGA: {
            // If not toggle BMCR, do nothing
            if (byAddr != MII_REG_BMCR)
                break;

            // If toggle [AUTO], toggle MDI bits and OR [RESET]/[REAUTO]
            SWMII_bReadU16(byPortId, MII_REG_BMCR, &wTmp);
            if (((wTmp^wData) & BMCR_AUTO) != 0 ) {
                // Toggle GIGA MDI/MDIX & OR [RESET]
                if (byPhyType == PHYTYPE_MARVELL_GIGA) {
                wData = wData | BMCR_RESET;
                    if ((wData & BMCR_AUTO) != 0 )     // Auto => auto crossover MDI/MDIX
                        s_bRegBitsOn ( byPortId, MII_REG_MARVELL_PSCR,
                                       MARVELL_PSCR_MDI0_GIGA | MARVELL_PSCR_MDI1_GIGA );
                    else                                // Force => manual MDI
                        s_bRegBitsOff( byPortId, MII_REG_MARVELL_PSCR,
                                       MARVELL_PSCR_MDI0_GIGA | MARVELL_PSCR_MDI1_GIGA );
                }
                // Toggle MEGA MDI/MDIX & OR [REAUTO]
                else {
                    wData = wData | BMCR_REAUTO;
                    if ((wData & BMCR_AUTO) != 0 ) {   // Auto => auto crossover MDI/MDIX
                        s_bRegBitsOff(byPortId, MII_REG_MARVELL_PSCR, MARVELL_PSCR_MDI0_MEGA);
                        s_bRegBitsOn (byPortId, MII_REG_MARVELL_PSCR, MARVELL_PSCR_MDI1_MEGA);
                    }
                    else {                              // Force => manual MDI
                        s_bRegBitsOn (byPortId, MII_REG_MARVELL_PSCR, MARVELL_PSCR_MDI0_MEGA);
                        s_bRegBitsOff(byPortId, MII_REG_MARVELL_PSCR, MARVELL_PSCR_MDI1_MEGA);
                    }
                }
            }

            // If toggle spd/dpx bits, OR [REAUTO]
            else if (((wTmp^wData) & (BMCR_SPD0 | BMCR_FDX | BMCR_SPD1)) !=0 )
                wData = wData | BMCR_REAUTO;
        } break;
    }

    return wData;
}


static BOOL s_bRegBitsOn (UINT8 byPortId, UINT8 byAddr, UINT16 wBitPtn)
{
    UINT16 wOrgData;

    SWMII_bReadU16(byPortId, byAddr, &wOrgData);
    return s_bMiiWriteOp(byPortId, byAddr, (UINT16)(wOrgData | wBitPtn));
}


static BOOL s_bRegBitsOff (UINT8 byPortId, UINT8 byAddr, UINT16 wBitPtn)
{
    UINT16 wOrgData;

    SWMII_bReadU16(byPortId, byAddr, &wOrgData);
    return s_bMiiWriteOp(byPortId, byAddr, (UINT16)(wOrgData & (~wBitPtn)));
}


BOOL SWMII_bRegBitsOn (UINT8 byPortId, UINT8 byAddr, UINT16 wBitPtn)
{
    UINT16 wOrgData, wNewData;

    if (!SWMII_bReadU16(byPortId, byAddr, &wOrgData))
        return FALSE;

    wNewData = s_wPhyFeatureHandler(byPortId, byAddr, (UINT16)(wOrgData | wBitPtn));
    return s_bMiiWriteOp(byPortId, byAddr, wNewData);
}


BOOL SWMII_bRegBitsOff (UINT8 byPortId, UINT8 byAddr, UINT16 wBitPtn)
{
    UINT16 wOrgData, wNewData;

    if (!SWMII_bReadU16(byPortId, byAddr, &wOrgData))
        return FALSE;

    wNewData = s_wPhyFeatureHandler(byPortId, byAddr, (UINT16)(wOrgData & (~wBitPtn)));
    return s_bMiiWriteOp(byPortId, byAddr, wNewData);
}


void SWMII_vSetAutoPollOn (void)
{
    SWREG_vWriteU8(PHYCTL_CMD, PHY_CMD_EN_AUTO);
    SWREG_bWaitStatus(PHYCTL_STATUS, PHY_STATUS_AUTOPOLL, TRUE);
}


void SWMII_vSetAutoPollOff (void)
{
    SWREG_vWriteU8(PHYCTL_CMD, PHY_CMD_DIS_AUTO);
    SWREG_bWaitStatus(PHYCTL_STATUS, PHY_STATUS_AUTOPOLL, FALSE);
}


UINT8 SWMII_byGetPhyType(UINT8 byPortId)
{
    UINT16  wPhyId1, wPhyId2;


    SWMII_bReadU16(byPortId, MII_REG_PHYID1, &wPhyId1);
    SWMII_bReadU16(byPortId, MII_REG_PHYID2, &wPhyId2);

    switch(wPhyId1) {

    case CID_MARVELL:
        if ((wPhyId2 & PHYID2_MOD_ID_MSK) == MID_MARVELL_88E1000)
            return PHYTYPE_MARVELL_GIGA;
        else
            return PHYTYPE_MARVELL_MEGA;

    case CID_CICADA:
        if ((wPhyId2 & PHYID2_MOD_ID_MSK) == MID_CICADA_CIS8201)
            return PHYTYPE_CICADA_GIGA;

    case CID_VIA:
        if ((wPhyId2 & PHYID2_MOD_ID_MSK) == MID_VIA_VT6108)
            return PHYTYPE_VIA_MEGA;

    case CID_BROADCOM:
        if ((wPhyId2 & PHYID2_MOD_ID_MSK) == MID_BROADCOM_BCM5421)
            return PHYTYPE_BROADCOM_GIGA;

    default:
        return PHYTYPE_STANDARD;
    }
}


⌨️ 快捷键说明

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