From dff406bfd7dd391e7d6b5edaec7b29807e7d96a4 Mon Sep 17 00:00:00 2001 From: Cameron Gutman Date: Thu, 23 Jul 2009 04:21:06 +0000 Subject: [PATCH] - Implement link speed and duplex detection - Fix LED programming (we didn't set LEDPE so all our programming was ignored) - Add some other LED programming - Fixes bug 4703 svn path=/trunk/; revision=42152 --- reactos/drivers/network/dd/pcnet/pcnet.c | 55 +++++++++++++++++++-- reactos/drivers/network/dd/pcnet/pcnet.h | 10 ++++ reactos/drivers/network/dd/pcnet/pcnethw.h | 5 ++ reactos/drivers/network/dd/pcnet/requests.c | 2 +- 4 files changed, 68 insertions(+), 4 deletions(-) diff --git a/reactos/drivers/network/dd/pcnet/pcnet.c b/reactos/drivers/network/dd/pcnet/pcnet.c index 9637036fcaf..6f3c9f33863 100644 --- a/reactos/drivers/network/dd/pcnet/pcnet.c +++ b/reactos/drivers/network/dd/pcnet/pcnet.c @@ -607,12 +607,18 @@ MiSyncMediaDetection( { PADAPTER Adapter = (PADAPTER)SynchronizeContext; NDIS_MEDIA_STATE MediaState = MiGetMediaState(Adapter); + UINT MediaSpeed = MiGetMediaSpeed(Adapter); + BOOLEAN FullDuplex = MiGetMediaDuplex(Adapter); DPRINT("Called\n"); DPRINT("MediaState: %d\n", MediaState); - if (MediaState != Adapter->MediaState) + if (MediaState != Adapter->MediaState || + MediaSpeed != Adapter->MediaSpeed || + FullDuplex != Adapter->FullDuplex) { Adapter->MediaState = MediaState; + Adapter->MediaSpeed = MediaSpeed; + Adapter->FullDuplex = FullDuplex; return TRUE; } return FALSE; @@ -721,10 +727,29 @@ MiInitChip( NdisRawWritePortUshort(Adapter->PortOffset + RAP, CSR0); NdisRawWritePortUshort(Adapter->PortOffset + RDP, CSR0_STRT|CSR0_INIT|CSR0_IENA); - /* detect the media state */ + /* Allow LED programming */ + NdisRawWritePortUshort(Adapter->PortOffset + RAP, BCR2); + NdisRawWritePortUshort(Adapter->PortOffset + BDP, BCR2_LEDPE); + + /* LED0 is configured for link status (on = up, off = down) */ NdisRawWritePortUshort(Adapter->PortOffset + RAP, BCR4); - NdisRawWritePortUshort(Adapter->PortOffset + BDP, BCR4_LNKSTE|BCR4_FDLSE); + NdisRawWritePortUshort(Adapter->PortOffset + BDP, BCR4_LNKSTE | BCR4_PSE); + + /* LED1 is configured for link duplex (on = full, off = half) */ + NdisRawWritePortUshort(Adapter->PortOffset + RAP, BCR5); + NdisRawWritePortUshort(Adapter->PortOffset + BDP, BCR5_FDLSE | BCR5_PSE); + + /* LED2 is configured for link speed (on = 100M, off = 10M) */ + NdisRawWritePortUshort(Adapter->PortOffset + RAP, BCR6); + NdisRawWritePortUshort(Adapter->PortOffset + BDP, BCR6_E100 | BCR6_PSE); + + /* LED3 is configured for trasmit/receive activity */ + NdisRawWritePortUshort(Adapter->PortOffset + RAP, BCR7); + NdisRawWritePortUshort(Adapter->PortOffset + BDP, BCR7_XMTE | BCR7_RCVE | BCR7_PSE); + Adapter->MediaState = MiGetMediaState(Adapter); + Adapter->FullDuplex = MiGetMediaDuplex(Adapter); + Adapter->MediaSpeed = MiGetMediaSpeed(Adapter); DPRINT("card started\n"); @@ -1240,6 +1265,30 @@ MiSetMulticast( return NDIS_STATUS_SUCCESS; } +BOOLEAN +NTAPI +MiGetMediaDuplex(PADAPTER Adapter) +{ + ULONG Data; + + NdisRawWritePortUshort(Adapter->PortOffset + RAP, BCR5); + NdisRawReadPortUshort(Adapter->PortOffset + BDP, &Data); + + return Data & BCR5_LEDOUT; +} + +UINT +NTAPI +MiGetMediaSpeed(PADAPTER Adapter) +{ + ULONG Data; + + NdisRawWritePortUshort(Adapter->PortOffset + RAP, BCR4); + NdisRawReadPortUshort(Adapter->PortOffset + BDP, &Data); + + return Data & BCR6_LEDOUT ? 100 : 10; +} + NDIS_MEDIA_STATE NTAPI MiGetMediaState(PADAPTER Adapter) diff --git a/reactos/drivers/network/dd/pcnet/pcnet.h b/reactos/drivers/network/dd/pcnet/pcnet.h index 54abdfa9ea9..818b055cb04 100644 --- a/reactos/drivers/network/dd/pcnet/pcnet.h +++ b/reactos/drivers/network/dd/pcnet/pcnet.h @@ -60,6 +60,8 @@ typedef struct _ADAPTER ULONG_PTR PortOffset; NDIS_MINIPORT_INTERRUPT InterruptObject; NDIS_MEDIA_STATE MediaState; + UINT MediaSpeed; + BOOLEAN FullDuplex; NDIS_MINIPORT_TIMER MediaDetectionTimer; ULONG CurrentReceiveDescriptorIndex; ULONG CurrentPacketFilter; @@ -129,6 +131,14 @@ NDIS_MEDIA_STATE NTAPI MiGetMediaState(PADAPTER Adapter); +UINT +NTAPI +MiGetMediaSpeed(PADAPTER Adapter); + +BOOLEAN +NTAPI +MiGetMediaDuplex(PADAPTER Adapter); + /* operational constants */ #define NUMBER_OF_BUFFERS 0x20 #define LOG_NUMBER_OF_BUFFERS 5 /* log2(NUMBER_OF_BUFFERS) */ diff --git a/reactos/drivers/network/dd/pcnet/pcnethw.h b/reactos/drivers/network/dd/pcnet/pcnethw.h index d961ad2996a..7fe4d10b6d4 100644 --- a/reactos/drivers/network/dd/pcnet/pcnethw.h +++ b/reactos/drivers/network/dd/pcnet/pcnethw.h @@ -250,6 +250,7 @@ #define BCR2_DXCVRCTL 0x20 /* dxcvr control */ #define BCR2_INTLEVEL 0x80 /* interrupt level/edge */ #define BCR2_APROMWE 0x100 /* address prom write enable */ +#define BCR2_LEDPE 0x1000 /* LED programming enable */ #define BCR2_TMAULOOP 0x4000 /* t-mau transmit on loopback */ /* BCR4 bits */ @@ -263,6 +264,7 @@ #define BCR4_PSE 0x80 /* pulse stretcher enable */ #define BCR4_FDLSE 0x100 /* full-duplex link status enable */ #define BCR4_MPSE 0x200 /* magic packet status enable */ +#define BCR4_E100 0x1000 /* link speed */ #define BCR4_LEDDIS 0x2000 /* led disable */ #define BCR4_LEDPOL 0x4000 /* led polarity */ #define BCR4_LEDOUT 0x8000 /* led output pin value */ @@ -278,6 +280,7 @@ #define BCR5_PSE 0x80 /* pulse stretcher enable */ #define BCR5_FDLSE 0x100 /* full-duplex link status enable */ #define BCR5_MPSE 0x200 /* magic packet status enable */ +#define BCR5_E100 0x1000 /* link speed */ #define BCR5_LEDDIS 0x2000 /* led disable */ #define BCR5_LEDPOL 0x4000 /* led polarity */ #define BCR5_LEDOUT 0x8000 /* led output pin value */ @@ -293,6 +296,7 @@ #define BCR6_PSE 0x80 /* pulse stretcher enable */ #define BCR6_FDLSE 0x100 /* full-duplex link status enable */ #define BCR6_MPSE 0x200 /* magic packet status enable */ +#define BCR6_E100 0x1000 /* link speed */ #define BCR6_LEDDIS 0x2000 /* led disable */ #define BCR6_LEDPOL 0x4000 /* led polarity */ #define BCR6_LEDOUT 0x8000 /* led output pin value */ @@ -308,6 +312,7 @@ #define BCR7_PSE 0x80 /* pulse stretcher enable */ #define BCR7_FDLSE 0x100 /* full-duplex link status enable */ #define BCR7_MPSE 0x200 /* magic packet status enable */ +#define BCR7_E100 0x1000 /* link speed */ #define BCR7_LEDDIS 0x2000 /* led disable */ #define BCR7_LEDPOL 0x4000 /* led polarity */ #define BCR7_LEDOUT 0x8000 /* led output pin value */ diff --git a/reactos/drivers/network/dd/pcnet/requests.c b/reactos/drivers/network/dd/pcnet/requests.c index 6ff06ae9dd3..b7bd8104dcb 100644 --- a/reactos/drivers/network/dd/pcnet/requests.c +++ b/reactos/drivers/network/dd/pcnet/requests.c @@ -173,7 +173,7 @@ MiniportQueryInformation( case OID_GEN_LINK_SPEED: { - GenericULONG = 100000; /* 10Mbps */ + GenericULONG = Adapter->MediaSpeed * 10000; break; }