📄 ks_config.c
字号:
{
#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 + -