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

📄 ks_config.c

📁 MICREL 网卡驱动 FOR CE 5.0
💻 C
📖 第 1 页 / 共 2 页
字号:
{
#ifdef SH_16BIT_WRITE
    USHORT RegData;
    UCHAR  bShift = Offset & 1;

#else
    UCHAR bData;
#endif

#ifdef KS_ISA_BUS
    HardwareSelectBank( pHardware, REG_SWITCH_CTRL_BANK );
#endif

#ifdef SH_16BIT_WRITE
    Offset &= ~1;
    bBits <<= ( bShift << 3 );
    HW_READ_WORD( pHardware, Offset, &RegData );
    if ( fSet )
        RegData |= bBits;
    else
        RegData &= ~bBits;
    HW_WRITE_WORD( pHardware, Offset, RegData );

#else
    HW_READ_BYTE( pHardware, Offset, &bData );
    if ( fSet )
        bData |= bBits;
    else
        bData &= ~bBits;
    HW_WRITE_BYTE( pHardware, Offset, bData );
#endif
}  /* SwitchConfigSet */

/* -------------------------------------------------------------------------- */

/*
    SwitchGetAddress

    Description:
        This function retrieves the MAC address of the switch.

    Parameters:
        PHARDWARE pHardware
            Pointer to hardware instance.

        PUCHAR MacAddr
            Buffer to store the MAC address.

    Return (None):
*/

#ifdef KS_PCI_BUS
void SwitchGetAddress_PCI (
#else
void SwitchGetAddress_ISA (
#endif
    PHARDWARE pHardware,
    PUCHAR    MacAddr )
{
    int i;

    ASSERT( pHardware->m_bAcquire );

#ifdef KS_ISA_BUS
    HardwareSelectBank( pHardware, REG_MAC_ADDR_BANK );
#endif
    for ( i = 0; i < MAC_ADDRESS_LENGTH; i++ )
    {
        HW_READ_BYTE( pHardware, ( ULONG )( REG_MAC_ADDR_0_OFFSET + i ),
            &MacAddr[ MAC_ADDR_ORDER( i )]);
    }
}  /* SwitchGetAddress */


/*
    SwitchSetAddress

    Description:
        This function configures the MAC address of the switch.

    Parameters:
        PHARDWARE pHardware
            Pointer to hardware instance.

        PUCHAR MacAddr
            The MAC address.

    Return (None):
*/

#ifdef KS_PCI_BUS
void SwitchSetAddress_PCI (
#else
void SwitchSetAddress_ISA (
#endif
    PHARDWARE pHardware,
    PUCHAR    MacAddr )
{
    int i;

    ASSERT( pHardware->m_bAcquire );

#ifdef KS_ISA_BUS
    HardwareSelectBank( pHardware, REG_MAC_ADDR_BANK );
#endif
    for ( i = 0; i < MAC_ADDRESS_LENGTH; i++ )
    {

#ifdef SH_16BIT_WRITE
        if ( ( i & 1 ) )
        {
            HW_WRITE_WORD( pHardware, (( REG_MAC_ADDR_0_OFFSET + i ) & ~1 ),
                ( MacAddr[ MAC_ADDR_ORDER( i )] << 8 ) |
                MacAddr[ MAC_ADDR_ORDER( i - 1 )]);
        }

#else
        HW_WRITE_BYTE( pHardware, ( ULONG )( REG_MAC_ADDR_0_OFFSET + i ),
            MacAddr[ MAC_ADDR_ORDER( i )]);
#endif
    }
}  /* SwitchSetAddress */


/*
    SwitchGetLinkStatus

    Description:
        This routine reads PHY registers to determine the current link status
        of the switch ports.

    Parameters:
        PHARDWARE pHardware
            Pointer to hardware instance.

    Return (None):
*/

#ifdef KS_PCI_BUS
void SwitchGetLinkStatus_PCI (
#else
void SwitchGetLinkStatus_ISA (
#endif
    PHARDWARE pHardware )
{
    PPORT_INFO pInfo;

#ifdef KS_PCI_BUS
    ULONG      InterruptMask;

#else
    USHORT     InterruptMask;
#endif
    int        change = FALSE;
    UCHAR      bData;
    UCHAR      bStatus;
    UCHAR      bLinkStatus;
    UCHAR      bPort;

    /* Save the current interrupt mask and block all interrupts. */
    InterruptMask = HardwareBlockInterrupt( pHardware );

#ifdef DEF_KS8842
    for ( bPort = 0; bPort < SWITCH_PORT_NUM; bPort++ )
#else
    bPort = 0;
#endif
    {
        pInfo = &pHardware->m_PortInfo[ bPort ];

        /* Read Port Control Register */
        PortConfigReadByte( pHardware, bPort,
#ifdef KS_ISA_BUS
                            REG_PORT_LINK_CTRL_BANK,
#endif
                            REG_PORT_CTRL_4_OFFSET, &bData );

        /* Clean previous latch Port Operation Status Register */
        PortConfigReadByte( pHardware, bPort,
#ifdef KS_ISA_BUS
                            REG_PORT_LINK_STATUS_BANK,
#endif
                            REG_PORT_STATUS_HI_OFFSET, &bStatus );

        /* Read Port Operation Status Register */
        PortConfigReadByte( pHardware, bPort,
#ifdef KS_ISA_BUS
                            REG_PORT_LINK_STATUS_BANK,
#endif
                            REG_PORT_STATUS_HI_OFFSET, &bStatus );

#ifdef LINK_CHECK_FIX
        /* bStatus is changing all the time even when there is no cable
           connection!
        */
#endif

        /* Clean previous latch Port Link Status Register */
        PortConfigReadByte( pHardware, bPort,
#ifdef KS_ISA_BUS
                            REG_PORT_LINK_STATUS_BANK,
#endif
                            REG_PORT_STATUS_OFFSET, &bLinkStatus );

        /* Read Port Link Status Register */
        PortConfigReadByte( pHardware, bPort,
#ifdef KS_ISA_BUS
                            REG_PORT_LINK_STATUS_BANK,
#endif
                            REG_PORT_STATUS_OFFSET, &bLinkStatus );

#ifdef LINK_CHECK_FIX
        /* bLinkStatus is changing all the time even when there is no cable
           connection!
        */
        bLinkStatus &=
            PORT_AUTO_NEG_COMPLETE |
            PORT_STATUS_LINK_GOOD;
        if ( ( bLinkStatus & (UCHAR)PORT_STATUS_LINK_GOOD ) )
        {
            if ( MediaStateConnected != pInfo->ulHardwareState )
                change = TRUE;
            pInfo->ulHardwareState = MediaStateConnected;
        }
        else
        {
            if ( MediaStateDisconnected != pInfo->ulHardwareState )
                change = TRUE;
            pInfo->ulHardwareState = MediaStateDisconnected;
        }
#endif
        if ( bData != pInfo->bAdvertised  ||
                bLinkStatus != pInfo->bLinkPartner )
        {
#ifndef LINK_CHECK_FIX
            pInfo->ulHardwareState = MediaStateDisconnected;
            if ( ( bLinkStatus & (UCHAR)PORT_STATUS_LINK_GOOD ) )
                pInfo->ulHardwareState = MediaStateConnected;
#endif

#ifdef DBG
            DBG_PRINT( "advertised: %02X - %02X; partner: %02X - %02X"
                NEWLINE, bData, pInfo->bAdvertised, bLinkStatus,
                pInfo->bLinkPartner );
#endif
            change = TRUE;

            pInfo->ulSpeed = 100000;
#if 1
            if ( ( bStatus & (UCHAR)PORT_STAT_SPEED_100MBIT ) )
                pInfo->ulSpeed = 1000000;
#else
            if ( (( bData & PORT_AUTO_NEG_100BTX )  &&
                    ( bLinkStatus & PORT_REMOTE_100BTX ))  ||
                    (( bData & PORT_AUTO_NEG_100BTX_FD )  &&
                    ( bLinkStatus & PORT_REMOTE_100BTX_FD )) )
                pInfo->ulSpeed = 1000000;
#endif
            pInfo->bDuplex = 1;
#if 1
            if ( ( bStatus & (UCHAR)PORT_STAT_FULL_DUPLEX ) )
                pInfo->bDuplex = 2;

#else
            if ( (( bData & PORT_AUTO_NEG_100BTX_FD )  &&
                    ( bLinkStatus & PORT_REMOTE_100BTX_FD ))  ||
                    (( bData & PORT_AUTO_NEG_10BT_FD )  &&
                    ( bLinkStatus & PORT_REMOTE_10BT_FD )  &&
                    ( !( bData & PORT_AUTO_NEG_100BTX )  ||
                    !( bLinkStatus & PORT_REMOTE_100BTX ))) )
                pInfo->bDuplex = 2;
#endif
            pInfo->bAdvertised = bData;
            pInfo->bLinkPartner = bLinkStatus;
        }
    }

    /* Restore the interrupt mask. */
    HardwareSetInterrupt( pHardware, InterruptMask );
    if ( change )
    {
        PPORT_INFO pLinked = NULL;

#ifdef DEF_KS8842
        for ( bPort = 0; bPort < SWITCH_PORT_NUM; bPort++ )
#else
        bPort = 0;
#endif
        {
            pInfo = &pHardware->m_PortInfo[ bPort ];

            if ( MediaStateConnected == pInfo->ulHardwareState )
            {
                if ( !pLinked )
                    pLinked = pInfo;
#if ( defined( DEF_LINUX ) || defined( _WIN32 )) && defined( DBG )
                DBG_PRINT( "link %d: %d, %d"NEWLINE, bPort,
                    ( int ) pInfo->ulSpeed,
                    ( int ) pInfo->bDuplex );
#endif /* #ifdef DEF_LINUX */
            }
            else
            {
#if ( defined( DEF_LINUX ) || defined( _WIN32 )) && defined( DBG )
                DBG_PRINT( "link %d disconnected"NEWLINE, bPort );
#endif /* #ifdef DEF_LINUX */
            }

        }  /* for ( bPort = 0; bPort < SWITCH_PORT_NUM; bPort++ ) */

        if ( pLinked )
            pInfo = pLinked;
        else
            pInfo = &pHardware->m_PortInfo[ 0 ];

        pHardware->m_ulHardwareState = pInfo->ulHardwareState;
        pHardware->m_ulTransmitRate = pInfo->ulSpeed;
        pHardware->m_ulDuplex = pInfo->bDuplex;

    } /* if ( change ) */

}  /* SwitchGetLinkStatus */


#define PHY_RESET_TIMEOUT  10

/*
    SwitchSetLinkSpeed

    Description:
        This routine sets the link speed of the switch ports.

    Parameters:
        PHARDWARE pHardware
            Pointer to hardware instance.

    Return (None):
*/

#ifdef KS_PCI_BUS
void SwitchSetLinkSpeed_PCI (
#else
void SwitchSetLinkSpeed_ISA (
#endif
    PHARDWARE pHardware )
{
    USHORT usData;
    UCHAR  bPort;

#ifdef DEF_KS8842
    for ( bPort = 0; bPort < SWITCH_PORT_NUM; bPort++ )
#else
    bPort = 0;
#endif
    {
        /* Enable Flow control in the full duplex mode */
        PortConfigForceFlowCtrl ( pHardware, bPort, TRUE );

        /* Enable Back pressure in the half duplex mode */
        PortConfigBackPressure ( pHardware, bPort, TRUE );

        /* Read Port Control register 4 (PnCR4) */
        PortConfigReadWord( pHardware, bPort,
#ifdef KS_ISA_BUS
                            REG_PORT_LINK_CTRL_BANK,
#endif
                            REG_PORT_CTRL_4_OFFSET, &usData );

        usData |= PORT_AUTO_NEG_ENABLE;
        usData |= PORT_AUTO_NEG_SYM_PAUSE;
        usData |= PORT_AUTO_NEG_100BTX_FD | PORT_AUTO_NEG_100BTX |
            PORT_AUTO_NEG_10BT_FD | PORT_AUTO_NEG_10BT;

        /* Check if manual configuration is specified by the user. */
        if ( pHardware->m_bSpeed  ||  pHardware->m_bDuplex )
        {
            if ( 10 == pHardware->m_bSpeed )
            {
                usData &= ~( PORT_AUTO_NEG_100BTX_FD | PORT_AUTO_NEG_100BTX );
            }
            else if ( 100 == pHardware->m_bSpeed )
            {
                usData &= ~( PORT_AUTO_NEG_10BT_FD | PORT_AUTO_NEG_10BT );
            }
            if ( 1 == pHardware->m_bDuplex )
            {
                usData &= ~( PORT_AUTO_NEG_100BTX_FD | PORT_AUTO_NEG_10BT_FD );
            }
            else if ( 2 == pHardware->m_bDuplex )
            {
                usData &= ~( PORT_AUTO_NEG_100BTX | PORT_AUTO_NEG_10BT );
            }
        }

        /* Write Port Control register 4 (PnCR4) */
        PortConfigWriteWord( pHardware, bPort,
#ifdef KS_ISA_BUS
                             REG_PORT_LINK_CTRL_BANK,
#endif
                             REG_PORT_CTRL_4_OFFSET, usData );

        /* Restart Port auto-negotiation */
        usData |= TO_HI_BYTE( PORT_AUTO_NEG_RESTART );
        PortConfigWriteWord( pHardware, bPort,
#ifdef KS_ISA_BUS
                             REG_PORT_LINK_CTRL_BANK,
#endif
                             REG_PORT_CTRL_4_OFFSET, usData );
    }

#ifdef FIBER_100FX
    /* No auto-negotiation for link speed/duplex mode in KSZ8861/2 with 100FX fiber mode. 
       when user define "FIBER_100FX", the driver set KS8861/2 port 1 to 100BT/full duplex 
     */
    bPort = 0;

    /* Read Port Control register 4 (PnCR4) */
    PortConfigReadWord( pHardware, bPort,
#ifdef KS_ISA_BUS
                        REG_PORT_LINK_CTRL_BANK,
#endif
                        REG_PORT_CTRL_4_OFFSET, &usData );

    /* Set Port 1 to 100BT/full duplex */
    usData &= ~( PORT_AUTO_NEG_ENABLE );
    usData |= ( PORT_FORCE_100_MBIT | PORT_FORCE_FULL_DUPLEX);

                DBG_PRINT( "port %d usData %x"NEWLINE, bPort, ( int ) usData );

    PortConfigWriteWord( pHardware, bPort,
#ifdef KS_ISA_BUS
                             REG_PORT_LINK_CTRL_BANK,
#endif
                             REG_PORT_CTRL_4_OFFSET, usData );

#endif /* #ifdef FIBER_100FX */

}  /* SwitchSetLinkSpeed */


/*
    SwitchRestartAutoNego

    Description:
        This routine restart auto-negotiation when the link is down of the switch ports.

    Parameters:
        PHARDWARE pHardware
            Pointer to hardware instance.

    Return (None):
*/

#ifdef KS_PCI_BUS
void SwitchRestartAutoNego_PCI (
#else
void SwitchRestartAutoNego_ISA (
#endif
    PHARDWARE pHardware )
{
    USHORT usData;
    UCHAR  bPort;

    /* Restart Port auto-negotiation */
#ifdef DEF_KS8842
    for ( bPort = 0; bPort < SWITCH_PORT_NUM; bPort++ )
#else
    bPort = 0;
#endif
    {
        PortConfigReadWord( pHardware, bPort,
#ifdef KS_ISA_BUS
                             REG_PORT_LINK_CTRL_BANK,
#endif
                             REG_PORT_CTRL_4_OFFSET, &usData );

        usData |= TO_HI_BYTE( PORT_AUTO_NEG_RESTART );

        PortConfigWriteWord( pHardware, bPort,
#ifdef KS_ISA_BUS
                             REG_PORT_LINK_CTRL_BANK,
#endif
                             REG_PORT_CTRL_4_OFFSET, usData );

    }

    /* Wait for auto negotiation to complete. */
    DelayMillisec( 150 );

}  /* SwitchRestartAutoNego */


/*
    SwitchSetGlobalControl

    Description:
        This routine sets the global control of the switch function.

    Parameters:
        PHARDWARE pHardware
            Pointer to hardware instance.

    Return (None):
*/

#ifdef KS_PCI_BUS
void SwitchSetGlobalControl_PCI (
#else
void SwitchSetGlobalControl_ISA (
#endif
    PHARDWARE pHardware )
{
    USHORT RegData = 0;

#ifdef KS_ISA_BUS
    HardwareSelectBank( pHardware, REG_SWITCH_CTRL_BANK );
#endif

    /*
     * Set Switch Global Control Register 3 SGCR3
     */

    /* Enable Switch MII Flow Control */

    HW_READ_WORD( pHardware, REG_SWITCH_CTRL_3_OFFSET, &RegData );
    RegData |= SWITCH_FLOW_CTRL;
    HW_WRITE_WORD( pHardware, REG_SWITCH_CTRL_3_OFFSET, RegData );

    /*
     * Set Switch Global Control Register 1 SGCR1
     */

    HW_READ_WORD( pHardware, REG_SWITCH_CTRL_1_OFFSET, &RegData );

    /* Enable Aggressive back off algorithm in half duplex mode */
    RegData |= SW_BACKOFF_EN;

#ifdef AUTO_FAST_AGING
    /* Enable automic fast aging when link changed detected */
    RegData |= SW_AUTO_FAST_AGING;
#endif
    HW_WRITE_WORD( pHardware, REG_SWITCH_CTRL_1_OFFSET, RegData );

    /*
     * Set Switch Global Control Register 2 SGCR2
     */

    /* Enable No excessive collision drop */
    HW_READ_WORD( pHardware, REG_SWITCH_CTRL_2_OFFSET, &RegData );
    RegData |= SW_NO_COLLISION_DROP;

#ifdef RCV_HUGE_FRAME
    RegData |= SW_HUGE_FRAME_SIZE;
#endif
    HW_WRITE_WORD( pHardware, REG_SWITCH_CTRL_2_OFFSET, RegData );

}  /* SwitchSetGlobalControl */


#ifdef DEF_KS8842
/*
 * SwitchEnable
 *	This function is used to enable/disable Switch Engine.
 *  Only KS8842 has switch function.
 *
 * Argument(s)
 *  pHardware   Pointer to hardware instance.
 *  fEnable     1: enable switch, 0: disable switch
 *
 * Return(s)
 *	NONE.
 */
#ifdef KS_PCI_BUS
void SwitchEnable_PCI
#else
void SwitchEnable_ISA
#endif
(
    PHARDWARE  pHardware,
    BOOLEAN    fEnable
)
{

#ifdef TWO_NETWORK_INTERFACE

    /* Set Port 1 port-base vlan membership with Port 3 */
    HardwareConfigPortBaseVlan ( pHardware, 0, 0x05 );

    /* Set Port 2 port-base vlan membership with Port 3 */
    HardwareConfigPortBaseVlan ( pHardware, 1, 0x06 );

#else
    HardwareConfigPortBaseVlan( pHardware, 0, 0x07 );
    HardwareConfigPortBaseVlan( pHardware, 1, 0x07 );
#endif

#ifdef KS_ISA_BUS
    HardwareSelectBank( pHardware, REG_SWITCH_CTRL_BANK );
#endif

    /* High byte is read-only. */
    if (fEnable)
    {
        HW_WRITE_WORD( pHardware, REG_CHIP_ID_OFFSET, (UCHAR)SWITCH_START );
    }
    else
        HW_WRITE_WORD( pHardware, REG_CHIP_ID_OFFSET, 0 );

}
#endif /* #ifdef DEF_KS8842 */

⌨️ 快捷键说明

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