ReactOS 0.4.15-dev-7934-g1dc8d80
phy.c File Reference
#include "nvnet.h"
#include "debug.h"
Include dependency graph for phy.c:

Go to the source code of this file.

Macros

#define NDEBUG
 

Functions

BOOLEAN MiiWrite (_In_ PNVNET_ADAPTER Adapter, _In_ ULONG PhyAddress, _In_ ULONG RegAddress, _In_ ULONG Data)
 
BOOLEAN MiiRead (_In_ PNVNET_ADAPTER Adapter, _In_ ULONG PhyAddress, _In_ ULONG RegAddress, _Out_ PULONG Data)
 
static BOOLEAN PhyInitRealtek8211b (_In_ PNVNET_ADAPTER Adapter)
 
static BOOLEAN PhyInitRealtek8211c (_In_ PNVNET_ADAPTER Adapter)
 
static BOOLEAN PhyInitRealtek8201 (_In_ PNVNET_ADAPTER Adapter, _In_ BOOLEAN DisableCrossoverDetection)
 
static BOOLEAN PhyInitCicadaSemiconductor (_In_ PNVNET_ADAPTER Adapter, _In_ ULONG PhyInterface)
 
static BOOLEAN PhyInitVitesseSemiconductor (_In_ PNVNET_ADAPTER Adapter)
 
static BOOLEAN PhyReset (_In_ PNVNET_ADAPTER Adapter, _In_ ULONG ControlSetup)
 
static NDIS_STATUS PhyInit (_In_ PNVNET_ADAPTER Adapter)
 
static BOOLEAN FindPhyDevice (_Inout_ PNVNET_ADAPTER Adapter)
 
static BOOLEAN SidebandUnitAcquireSemaphore (_Inout_ PNVNET_ADAPTER Adapter)
 
VOID SidebandUnitReleaseSemaphore (_In_ PNVNET_ADAPTER Adapter)
 
static BOOLEAN SidebandUnitGetVersion (_In_ PNVNET_ADAPTER Adapter, _Out_ PULONG Version)
 
static BOOLEAN MiiGetSpeedAndDuplex (_In_ PNVNET_ADAPTER Adapter, _Out_ PULONG MiiAdvertise, _Out_ PULONG MiiLinkPartnerAbility, _Out_ PULONG LinkSpeed, _Out_ PBOOLEAN FullDuplex)
 
static VOID NvNetSetSpeedAndDuplex (_In_ PNVNET_ADAPTER Adapter, _In_ ULONG MiiAdvertise, _In_ ULONG MiiLinkPartnerAbility)
 
BOOLEAN NvNetUpdateLinkSpeed (_In_ PNVNET_ADAPTER Adapter)
 
NDIS_STATUS NvNetPhyInit (_In_ PNVNET_ADAPTER Adapter)
 

Macro Definition Documentation

◆ NDEBUG

#define NDEBUG

Definition at line 20 of file phy.c.

Function Documentation

◆ FindPhyDevice()

static BOOLEAN FindPhyDevice ( _Inout_ PNVNET_ADAPTER  Adapter)
static

Definition at line 562 of file phy.c.

564{
565 ULONG Phy;
566
567 PAGED_CODE();
568
569 NDIS_DbgPrint(MIN_TRACE, ("()\n"));
570
571 for (Phy = 1; Phy <= 32; ++Phy)
572 {
573 ULONG PhyAddress = Phy & 0x1F; /* Check the PHY 0 last */
574 ULONG PhyIdLow, PhyIdHigh;
575
576 if (!MiiRead(Adapter, PhyAddress, MII_PHY_ID1, &PhyIdLow))
577 continue;
578 if (PhyIdLow == 0xFFFF)
579 continue;
580
581 if (!MiiRead(Adapter, PhyAddress, MII_PHY_ID2, &PhyIdHigh))
582 continue;
583 if (PhyIdHigh == 0xFFFF)
584 continue;
585
586 Adapter->PhyAddress = PhyAddress;
587 Adapter->PhyModel = PhyIdHigh & PHYID2_MODEL_MASK;
588 Adapter->PhyOui = ((PhyIdLow & PHYID1_OUI_MASK) << PHYID1_OUI_SHFT) |
589 ((PhyIdHigh & PHYID2_OUI_MASK) >> PHYID2_OUI_SHFT);
590
591 /* Realtek hardcoded PhyIdLow to all zero's on certain PHYs */
592 if (Adapter->PhyOui == PHY_OUI_REALTEK2)
593 Adapter->PhyOui = PHY_OUI_REALTEK;
594
595 /* Setup PHY revision for Realtek */
596 if (Adapter->PhyOui == PHY_OUI_REALTEK && Adapter->PhyModel == PHY_MODEL_REALTEK_8211)
597 {
598 ULONG PhyRevision;
599
600 MiiRead(Adapter, PhyAddress, PHY_REALTEK_REVISION, &PhyRevision);
601 Adapter->PhyRevision = PhyRevision & PHY_REV_MASK;
602 }
603
604 NDIS_DbgPrint(MIN_TRACE, ("Found PHY %X %X %X\n",
605 Adapter->PhyAddress,
606 Adapter->PhyModel,
607 Adapter->PhyOui));
608 break;
609 }
610 if (Phy == 33)
611 {
612 return FALSE;
613 }
614
615 return TRUE;
616}
#define PAGED_CODE()
#define MIN_TRACE
Definition: debug.h:14
BOOLEAN MiiRead(_In_ PDC21X4_ADAPTER Adapter, _In_ ULONG PhyAddress, _In_ ULONG RegAddress, _Out_ PULONG Data)
Definition: phy.c:101
#define MII_PHY_ID2
Definition: dc21x4hw.h:570
#define MII_PHY_ID1
Definition: dc21x4hw.h:569
#define TRUE
Definition: types.h:120
#define FALSE
Definition: types.h:117
#define NDIS_DbgPrint(_t_, _x_)
Definition: debug.h:40
#define PHY_MODEL_REALTEK_8211
Definition: nic.h:480
#define PHYID1_OUI_MASK
Definition: nic.h:484
#define PHY_OUI_REALTEK
Definition: nic.h:478
#define PHY_REV_MASK
Definition: nic.h:529
#define PHY_REALTEK_REVISION
Definition: nic.h:528
#define PHY_OUI_REALTEK2
Definition: nic.h:479
#define PHYID1_OUI_SHFT
Definition: nic.h:485
#define PHYID2_OUI_MASK
Definition: nic.h:487
#define PHYID2_MODEL_MASK
Definition: nic.h:486
#define PHYID2_OUI_SHFT
Definition: nic.h:488
uint32_t ULONG
Definition: typedefs.h:59

Referenced by NvNetPhyInit().

◆ MiiGetSpeedAndDuplex()

static BOOLEAN MiiGetSpeedAndDuplex ( _In_ PNVNET_ADAPTER  Adapter,
_Out_ PULONG  MiiAdvertise,
_Out_ PULONG  MiiLinkPartnerAbility,
_Out_ PULONG  LinkSpeed,
_Out_ PBOOLEAN  FullDuplex 
)
static

Definition at line 721 of file phy.c.

727{
728 ULONG MiiStatus, AdvLpa;
729
730 *MiiAdvertise = 0;
731 *MiiLinkPartnerAbility = 0;
732
733 /* Link status is a latched-low bit, read it twice */
734 MiiRead(Adapter, Adapter->PhyAddress, MII_STATUS, &MiiStatus);
735 MiiRead(Adapter, Adapter->PhyAddress, MII_STATUS, &MiiStatus);
736
737 /* Check link status */
738 if (!(MiiStatus & MII_SR_LINK_STATUS))
739 {
740 /* No link detected - configure NIC for 10 MB HD */
741 *LinkSpeed = NVREG_LINKSPEED_10;
742 *FullDuplex = FALSE;
743 return FALSE;
744 }
745
746 /* If we are forcing speed and duplex */
747 if (Adapter->Flags & NV_FORCE_SPEED_AND_DUPLEX)
748 {
749 if (Adapter->Flags & NV_USER_SPEED_100)
750 {
751 *LinkSpeed = NVREG_LINKSPEED_100;
752 }
753 else
754 {
755 *LinkSpeed = NVREG_LINKSPEED_10;
756 }
757 *FullDuplex = !!(Adapter->Flags & NV_FORCE_FULL_DUPLEX);
758 return TRUE;
759 }
760
761 /* Check auto-negotiation is complete */
762 if (!(MiiStatus & MII_SR_AUTONEG_COMPLETE))
763 {
764 /* Still in auto-negotiation - configure NIC for 10 MBit HD and wait */
765 *LinkSpeed = NVREG_LINKSPEED_10;
766 *FullDuplex = FALSE;
767 return FALSE;
768 }
769
770 MiiRead(Adapter, Adapter->PhyAddress, MII_AUTONEG_ADVERTISE, MiiAdvertise);
771 MiiRead(Adapter, Adapter->PhyAddress, MII_AUTONEG_LINK_PARTNER, MiiLinkPartnerAbility);
772
773 /* Gigabit ethernet */
774 if (Adapter->Flags & NV_GIGABIT_PHY)
775 {
776 ULONG MiiControl1000, MiiStatus1000;
777
778 MiiRead(Adapter, Adapter->PhyAddress, MII_MASTER_SLAVE_CONTROL, &MiiControl1000);
779 MiiRead(Adapter, Adapter->PhyAddress, MII_MASTER_SLAVE_STATUS, &MiiStatus1000);
780
781 if ((MiiControl1000 & MII_MS_CR_1000T_FD) && (MiiStatus1000 & MII_MS_SR_1000T_FD))
782 {
783 *LinkSpeed = NVREG_LINKSPEED_1000;
784 *FullDuplex = TRUE;
785 return TRUE;
786 }
787 }
788
789 AdvLpa = (*MiiAdvertise) & (*MiiLinkPartnerAbility);
790 if (AdvLpa & MII_LP_100T_FD)
791 {
792 *LinkSpeed = NVREG_LINKSPEED_100;
793 *FullDuplex = TRUE;
794 }
795 else if (AdvLpa & MII_LP_100T_HD)
796 {
797 *LinkSpeed = NVREG_LINKSPEED_100;
798 *FullDuplex = FALSE;
799 }
800 else if (AdvLpa & MII_LP_10T_FD)
801 {
802 *LinkSpeed = NVREG_LINKSPEED_10;
803 *FullDuplex = TRUE;
804 }
805 else if (AdvLpa & MII_LP_10T_HD)
806 {
807 *LinkSpeed = NVREG_LINKSPEED_10;
808 *FullDuplex = FALSE;
809 }
810 else
811 {
812 *LinkSpeed = NVREG_LINKSPEED_10;
813 *FullDuplex = FALSE;
814 }
815
816 return TRUE;
817}
#define MII_STATUS
Definition: dc21x4hw.h:566
#define MII_LP_10T_HD
Definition: dc21x4hw.h:581
#define MII_MASTER_SLAVE_STATUS
Definition: dc21x4hw.h:593
#define MII_SR_AUTONEG_COMPLETE
Definition: dc21x4hw.h:568
#define MII_MS_SR_1000T_FD
Definition: dc21x4hw.h:594
#define MII_LP_100T_HD
Definition: dc21x4hw.h:583
#define MII_AUTONEG_ADVERTISE
Definition: dc21x4hw.h:571
#define MII_SR_LINK_STATUS
Definition: dc21x4hw.h:567
#define MII_LP_10T_FD
Definition: dc21x4hw.h:582
#define MII_MS_CR_1000T_FD
Definition: dc21x4hw.h:592
#define MII_LP_100T_FD
Definition: dc21x4hw.h:584
#define MII_AUTONEG_LINK_PARTNER
Definition: dc21x4hw.h:580
#define MII_MASTER_SLAVE_CONTROL
Definition: dc21x4hw.h:590
#define NVREG_LINKSPEED_1000
Definition: nic.h:189
#define NVREG_LINKSPEED_100
Definition: nic.h:188
#define NVREG_LINKSPEED_10
Definition: nic.h:187
#define NV_FORCE_SPEED_AND_DUPLEX
Definition: nvnet.h:295
#define NV_GIGABIT_PHY
Definition: nvnet.h:292
#define NV_FORCE_FULL_DUPLEX
Definition: nvnet.h:296
#define NV_USER_SPEED_100
Definition: nvnet.h:297

Referenced by NvNetUpdateLinkSpeed().

◆ MiiRead()

BOOLEAN MiiRead ( _In_ PNVNET_ADAPTER  Adapter,
_In_ ULONG  PhyAddress,
_In_ ULONG  RegAddress,
_Out_ PULONG  Data 
)

Definition at line 62 of file phy.c.

67{
68 ULONG i;
69
71
73 {
76 }
77
78 NV_WRITE(Adapter, NvRegMIIControl, (PhyAddress << NVREG_MIICTL_ADDRSHIFT) | RegAddress);
79
80 for (i = NV_MIIPHY_DELAYMAX; i > 0; --i)
81 {
83
85 break;
86 }
87 if (i == 0)
88 {
89 *Data = 0;
90 return FALSE;
91 }
92
94 {
95 *Data = 0;
96 return FALSE;
97 }
98
99 *Data = NV_READ(Adapter, NvRegMIIData);
100 return TRUE;
101}
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint i
Definition: glfuncs.h:248
#define NdisStallExecution
Definition: ndis.h:4453
#define NV_MIIBUSY_DELAY
Definition: nic.h:460
#define NVREG_MIISTAT_MASK_RW
Definition: nic.h:228
#define NV_MIIPHY_DELAY
Definition: nic.h:461
#define NVREG_MIICTL_INUSE
Definition: nic.h:246
#define NV_MIIPHY_DELAYMAX
Definition: nic.h:462
#define NVREG_MIICTL_ADDRSHIFT
Definition: nic.h:248
#define NVREG_MIISTAT_ERROR
Definition: nic.h:226
@ NvRegMIIData
Definition: nic.h:250
@ NvRegMIIStatus
Definition: nic.h:225
@ NvRegMIIControl
Definition: nic.h:245
FORCEINLINE VOID NV_WRITE(_In_ PNVNET_ADAPTER Adapter, _In_ NVNET_REGISTER Register, _In_ ULONG Value)
Definition: nvnet.h:646
FORCEINLINE ULONG NV_READ(_In_ PNVNET_ADAPTER Adapter, _In_ NVNET_REGISTER Register)
Definition: nvnet.h:656

◆ MiiWrite()

BOOLEAN MiiWrite ( _In_ PNVNET_ADAPTER  Adapter,
_In_ ULONG  PhyAddress,
_In_ ULONG  RegAddress,
_In_ ULONG  Data 
)

Definition at line 26 of file phy.c.

31{
32 ULONG i;
33
35
37 {
40 }
41
42 NV_WRITE(Adapter, NvRegMIIData, Data);
44 NVREG_MIICTL_WRITE | (PhyAddress << NVREG_MIICTL_ADDRSHIFT) | RegAddress);
45
46 for (i = NV_MIIPHY_DELAYMAX; i > 0; --i)
47 {
49
51 break;
52 }
53 if (i == 0)
54 {
55 return FALSE;
56 }
57
58 return TRUE;
59}
#define NVREG_MIICTL_WRITE
Definition: nic.h:247

◆ NvNetPhyInit()

NDIS_STATUS NvNetPhyInit ( _In_ PNVNET_ADAPTER  Adapter)

Definition at line 1036 of file phy.c.

1038{
1039 ULONG PhyState;
1040 BOOLEAN RestorePhyState = FALSE, PhyInitialized = FALSE;
1041
1042 PAGED_CODE();
1043
1044 NDIS_DbgPrint(MIN_TRACE, ("()\n"));
1045
1046 /* Take PHY and NIC out of low power mode */
1047 if (Adapter->Features & DEV_HAS_POWER_CNTRL)
1048 {
1050
1051 PowerState &= ~NVREG_POWERSTATE2_POWERUP_MASK;
1052 if ((Adapter->Features & DEV_NEED_LOW_POWER_FIX) && Adapter->RevisionId >= 0xA3)
1053 {
1055 }
1057 }
1058
1059 /* Clear PHY state and temporarily halt PHY interrupts */
1060 NV_WRITE(Adapter, NvRegMIIMask, 0);
1061 PhyState = NV_READ(Adapter, NvRegAdapterControl);
1062 if (PhyState & NVREG_ADAPTCTL_RUNNING)
1063 {
1064 RestorePhyState = TRUE;
1065
1066 PhyState &= ~NVREG_ADAPTCTL_RUNNING;
1067 NV_WRITE(Adapter, NvRegAdapterControl, PhyState);
1068 }
1070
1071 if (Adapter->Features & DEV_HAS_MGMT_UNIT)
1072 {
1073 ULONG UnitVersion;
1074
1075 /* Management unit running on the MAC? */
1079 SidebandUnitGetVersion(Adapter, &UnitVersion))
1080 {
1081 if (UnitVersion > 0)
1082 {
1084 Adapter->Flags |= NV_MAC_IN_USE;
1085 else
1086 Adapter->Flags &= ~NV_MAC_IN_USE;
1087 }
1088 else
1089 {
1090 Adapter->Flags |= NV_MAC_IN_USE;
1091 }
1092
1093 NDIS_DbgPrint(MIN_TRACE, ("Management unit is running. MAC in use\n"));
1094
1095 /* Management unit setup the PHY already? */
1096 if ((Adapter->Flags & NV_MAC_IN_USE) &&
1099 {
1100 /* PHY is inited by management unit */
1101 PhyInitialized = TRUE;
1102
1103 NDIS_DbgPrint(MIN_TRACE, ("PHY already initialized by management unit\n"));
1104 }
1105 }
1106 }
1107
1108 /* Find a suitable PHY */
1109 if (!FindPhyDevice(Adapter))
1110 {
1111 NDIS_DbgPrint(MAX_TRACE, ("Could not find a valid PHY\n"));
1112 goto Failure;
1113 }
1114
1115 /* We need to init the PHY */
1116 if (!PhyInitialized)
1117 {
1118 if (!PhyInit(Adapter))
1119 {
1120 /* It's not critical for init, continue */
1121 }
1122 }
1123 else
1124 {
1125 ULONG MiiStatus;
1126
1127 /* See if it is a gigabit PHY */
1128 MiiRead(Adapter, Adapter->PhyAddress, MII_STATUS, &MiiStatus);
1129 if (MiiStatus & PHY_GIGABIT)
1130 {
1131 Adapter->Flags |= NV_GIGABIT_PHY;
1132 }
1133 }
1134
1135 return NDIS_STATUS_SUCCESS;
1136
1137Failure:
1138 if (RestorePhyState)
1139 {
1141 }
1142
1143 return NDIS_STATUS_FAILURE;
1144}
unsigned char BOOLEAN
#define MAX_TRACE
Definition: debug.h:16
#define NDIS_STATUS_FAILURE
Definition: ndis.h:465
#define NDIS_STATUS_SUCCESS
Definition: ndis.h:346
#define DEV_HAS_POWER_CNTRL
Definition: nic.h:26
#define NVREG_XMITCTL_SYNC_MASK
Definition: nic.h:97
#define PHY_GIGABIT
Definition: nic.h:490
#define NVREG_XMITCTL_MGMT_ST
Definition: nic.h:96
#define NVREG_POWERSTATE2_POWERUP_REV_A3
Definition: nic.h:336
#define NVREG_ADAPTCTL_RUNNING
Definition: nic.h:238
#define NVREG_MGMTUNITCONTROL_INUSE
Definition: nic.h:297
#define NVREG_MIISTAT_MASK_ALL
Definition: nic.h:229
#define DEV_HAS_MGMT_UNIT
Definition: nic.h:31
#define NVREG_XMITCTL_SYNC_PHY_INIT
Definition: nic.h:99
#define DEV_NEED_LOW_POWER_FIX
Definition: nic.h:41
@ NvRegAdapterControl
Definition: nic.h:234
@ NvRegPowerState2
Definition: nic.h:334
@ NvRegMIIMask
Definition: nic.h:231
@ NvRegMgmtUnitControl
Definition: nic.h:296
@ NvRegTransmitterControl
Definition: nic.h:94
static BOOLEAN FindPhyDevice(_Inout_ PNVNET_ADAPTER Adapter)
Definition: phy.c:562
static BOOLEAN SidebandUnitAcquireSemaphore(_Inout_ PNVNET_ADAPTER Adapter)
Definition: phy.c:621
static BOOLEAN SidebandUnitGetVersion(_In_ PNVNET_ADAPTER Adapter, _Out_ PULONG Version)
Definition: phy.c:683
static NDIS_STATUS PhyInit(_In_ PNVNET_ADAPTER Adapter)
Definition: phy.c:358
#define NV_MAC_IN_USE
Definition: nvnet.h:291
_Must_inspect_result_ _In_ PWDFDEVICE_INIT _In_ WDF_DEVICE_POWER_STATE PowerState
Definition: wdfdevice.h:3034

Referenced by NvNetInitNIC().

◆ NvNetSetSpeedAndDuplex()

static VOID NvNetSetSpeedAndDuplex ( _In_ PNVNET_ADAPTER  Adapter,
_In_ ULONG  MiiAdvertise,
_In_ ULONG  MiiLinkPartnerAbility 
)
static

Definition at line 821 of file phy.c.

825{
826 ULONG PhyRegister, TxDeferral, PauseFlags, MiiExpansion;
827 BOOLEAN RestartTransmitter = FALSE, RestartReceiver = FALSE;
828
829 /* The transmitter and receiver must be restarted for safe update */
831 {
832 RestartTransmitter = TRUE;
833 NvNetStopTransmitter(Adapter);
834 }
836 {
837 RestartReceiver = TRUE;
838 NvNetStopReceiver(Adapter);
839 }
840
841 if (Adapter->Flags & NV_GIGABIT_PHY)
842 {
843 PhyRegister = NV_READ(Adapter, NvRegSlotTime);
844 PhyRegister &= ~NVREG_SLOTTIME_1000_FULL;
845 if ((Adapter->LinkSpeed == NVREG_LINKSPEED_10) ||
846 (Adapter->LinkSpeed == NVREG_LINKSPEED_100))
847 {
848 PhyRegister |= NVREG_SLOTTIME_10_100_FULL;
849 }
850 else if (Adapter->LinkSpeed == NVREG_LINKSPEED_1000)
851 {
852 PhyRegister |= NVREG_SLOTTIME_1000_FULL;
853 }
854 NV_WRITE(Adapter, NvRegSlotTime, PhyRegister);
855 }
856
857 PhyRegister = NV_READ(Adapter, NvRegPhyInterface);
858 PhyRegister &= ~(PHY_HALF | PHY_100 | PHY_1000);
859 if (!Adapter->FullDuplex)
860 {
861 PhyRegister |= PHY_HALF;
862 }
863 if (Adapter->LinkSpeed == NVREG_LINKSPEED_100)
864 PhyRegister |= PHY_100;
865 else if (Adapter->LinkSpeed == NVREG_LINKSPEED_1000)
866 PhyRegister |= PHY_1000;
867 NV_WRITE(Adapter, NvRegPhyInterface, PhyRegister);
868
869 /* Setup the deferral register */
870 MiiRead(Adapter, Adapter->PhyAddress, MII_AUTONEG_EXPANSION, &MiiExpansion);
871 if (PhyRegister & PHY_RGMII)
872 {
873 if (Adapter->LinkSpeed == NVREG_LINKSPEED_1000)
874 {
875 TxDeferral = NVREG_TX_DEFERRAL_RGMII_1000;
876 }
877 else
878 {
879 if (!(MiiExpansion & MII_EXP_LP_AUTONEG) && !Adapter->FullDuplex &&
880 (Adapter->Features & DEV_HAS_COLLISION_FIX))
881 {
883 }
884 else
885 {
887 }
888 }
889 }
890 else
891 {
892 if (!(MiiExpansion & MII_EXP_LP_AUTONEG) && !Adapter->FullDuplex &&
893 (Adapter->Features & DEV_HAS_COLLISION_FIX))
894 {
896 }
897 else
898 {
899 TxDeferral = NVREG_TX_DEFERRAL_DEFAULT;
900 }
901 }
902 NV_WRITE(Adapter, NvRegTxDeferral, TxDeferral);
903
904 /* Setup the watermark register */
905 if (Adapter->Features & (DEV_HAS_HIGH_DMA | DEV_HAS_LARGEDESC))
906 {
907 if (Adapter->LinkSpeed == NVREG_LINKSPEED_1000)
909 else
911 }
912 else
913 {
915 }
916
917 NV_WRITE(Adapter, NvRegMisc1, NVREG_MISC1_FORCE | (Adapter->FullDuplex ? 0 : NVREG_MISC1_HD));
918 NV_WRITE(Adapter, NvRegLinkSpeed, Adapter->LinkSpeed | NVREG_LINKSPEED_FORCE);
919
920 PauseFlags = 0;
921
922 /* Setup pause frames */
923 if (Adapter->FullDuplex)
924 {
925 if (!(Adapter->Flags & NV_FORCE_SPEED_AND_DUPLEX) &&
926 (Adapter->PauseFlags & NV_PAUSEFRAME_AUTONEG))
927 {
928 ULONG AdvPause = MiiAdvertise & (MII_ADV_PAUSE_SYM | MII_ADV_PAUSE_ASYM);
929 ULONG LpaPause = MiiLinkPartnerAbility & (MII_LP_PAUSE_SYM | MII_LP_PAUSE_ASYM);
930
931 switch (AdvPause)
932 {
934 {
935 if (LpaPause & MII_LP_PAUSE_SYM)
936 {
937 PauseFlags |= NV_PAUSEFRAME_RX_ENABLE;
938
939 if (Adapter->PauseFlags & NV_PAUSEFRAME_TX_REQ)
940 PauseFlags |= NV_PAUSEFRAME_TX_ENABLE;
941 }
942 break;
943 }
945 {
946 if (LpaPause == (MII_LP_PAUSE_SYM | MII_LP_PAUSE_ASYM))
947 {
948 PauseFlags |= NV_PAUSEFRAME_TX_ENABLE;
949 }
950 break;
951 }
953 {
954 if (LpaPause & MII_LP_PAUSE_SYM)
955 {
956 PauseFlags |= NV_PAUSEFRAME_RX_ENABLE;
957
958 if (Adapter->PauseFlags & NV_PAUSEFRAME_TX_REQ)
959 PauseFlags |= NV_PAUSEFRAME_TX_ENABLE;
960 }
961 if (LpaPause == MII_LP_PAUSE_ASYM)
962 {
963 PauseFlags |= NV_PAUSEFRAME_RX_ENABLE;
964 }
965 break;
966 }
967
968 default:
969 break;
970 }
971 }
972 else
973 {
974 PauseFlags = Adapter->PauseFlags;
975 }
976 }
977 NvNetUpdatePauseFrame(Adapter, PauseFlags);
978
979 if (RestartTransmitter)
980 {
981 NvNetStartTransmitter(Adapter);
982 }
983 if (RestartReceiver)
984 {
985 NvNetStartReceiver(Adapter);
986 }
987}
#define MII_EXP_LP_AUTONEG
Definition: dc21x4hw.h:589
#define MII_ADV_PAUSE_SYM
Definition: dc21x4hw.h:578
#define MII_ADV_PAUSE_ASYM
Definition: dc21x4hw.h:579
#define MII_AUTONEG_EXPANSION
Definition: dc21x4hw.h:588
#define MII_LP_PAUSE_ASYM
Definition: dc21x4hw.h:587
#define MII_LP_PAUSE_SYM
Definition: dc21x4hw.h:586
VOID NvNetStartTransmitter(_In_ PNVNET_ADAPTER Adapter)
Definition: nic.c:130
VOID NvNetStartReceiver(_In_ PNVNET_ADAPTER Adapter)
Definition: nic.c:104
VOID NvNetStopReceiver(_In_ PNVNET_ADAPTER Adapter)
Definition: nic.c:147
VOID NvNetStopTransmitter(_In_ PNVNET_ADAPTER Adapter)
Definition: nic.c:178
VOID NvNetUpdatePauseFrame(_Inout_ PNVNET_ADAPTER Adapter, _In_ ULONG PauseFlags)
Definition: nic.c:242
#define NVREG_RCVCTL_START
Definition: nic.h:125
#define NV_PAUSEFRAME_TX_REQ
Definition: nic.h:548
#define PHY_1000
Definition: nic.h:165
#define NVREG_MISC1_FORCE
Definition: nic.h:92
#define NVREG_XMITCTL_START
Definition: nic.h:95
#define NV_PAUSEFRAME_AUTONEG
Definition: nic.h:549
#define NVREG_TX_WM_DESC1_DEFAULT
Definition: nic.h:196
#define DEV_HAS_LARGEDESC
Definition: nic.h:20
#define NVREG_SLOTTIME_1000_FULL
Definition: nic.h:134
#define PHY_HALF
Definition: nic.h:166
#define NVREG_SLOTTIME_10_100_FULL
Definition: nic.h:133
#define DEV_HAS_COLLISION_FIX
Definition: nic.h:33
#define NVREG_TX_DEFERRAL_DEFAULT
Definition: nic.h:140
#define NV_PAUSEFRAME_RX_ENABLE
Definition: nic.h:545
#define NVREG_TX_DEFERRAL_RGMII_STRETCH_100
Definition: nic.h:144
#define PHY_100
Definition: nic.h:164
#define NVREG_TX_WM_DESC2_3_DEFAULT
Definition: nic.h:197
#define NVREG_TX_WM_DESC2_3_1000
Definition: nic.h:198
#define NV_PAUSEFRAME_TX_ENABLE
Definition: nic.h:546
#define DEV_HAS_HIGH_DMA
Definition: nic.h:21
#define NVREG_TX_DEFERRAL_MII_STRETCH
Definition: nic.h:145
#define NVREG_TX_DEFERRAL_RGMII_STRETCH_10
Definition: nic.h:143
#define PHY_RGMII
Definition: nic.h:167
#define NVREG_LINKSPEED_FORCE
Definition: nic.h:186
#define NVREG_MISC1_HD
Definition: nic.h:91
@ NvRegTxWatermark
Definition: nic.h:195
@ NvRegSlotTime
Definition: nic.h:131
@ NvRegTxDeferral
Definition: nic.h:139
@ NvRegReceiverControl
Definition: nic.h:124
@ NvRegLinkSpeed
Definition: nic.h:185
@ NvRegPhyInterface
Definition: nic.h:163
@ NvRegMisc1
Definition: nic.h:89
#define NVREG_TX_DEFERRAL_RGMII_1000
Definition: nic.h:142

Referenced by NvNetUpdateLinkSpeed().

◆ NvNetUpdateLinkSpeed()

BOOLEAN NvNetUpdateLinkSpeed ( _In_ PNVNET_ADAPTER  Adapter)

Definition at line 990 of file phy.c.

992{
993 ULONG MiiAdvertise, MiiLinkPartnerAbility, LinkSpeed;
994 BOOLEAN FullDuplex, LinkUp;
995
996 NDIS_DbgPrint(MIN_TRACE, ("()\n"));
997
999 &MiiAdvertise,
1000 &MiiLinkPartnerAbility,
1001 &LinkSpeed,
1002 &FullDuplex);
1003 if (Adapter->FullDuplex == FullDuplex && Adapter->LinkSpeed == LinkSpeed)
1004 {
1005 return LinkUp;
1006 }
1007
1008 NDIS_DbgPrint(MIN_TRACE, ("Configuring MAC from '%lx %s-duplex' to '%lx %s-duplex'\n",
1009 Adapter->LinkSpeed,
1010 Adapter->FullDuplex ? "full" : "half",
1011 LinkSpeed,
1012 FullDuplex ? "full" : "half"));
1013
1014 Adapter->FullDuplex = FullDuplex;
1015 Adapter->LinkSpeed = LinkSpeed;
1016
1017 if (Adapter->Flags & NV_ACTIVE)
1018 {
1019 NdisDprAcquireSpinLock(&Adapter->Send.Lock);
1020 NdisDprAcquireSpinLock(&Adapter->Receive.Lock);
1021 }
1022
1023 NvNetSetSpeedAndDuplex(Adapter, MiiAdvertise, MiiLinkPartnerAbility);
1024
1025 if (Adapter->Flags & NV_ACTIVE)
1026 {
1027 NdisDprReleaseSpinLock(&Adapter->Receive.Lock);
1028 NdisDprReleaseSpinLock(&Adapter->Send.Lock);
1029 }
1030
1031 return LinkUp;
1032}
#define NdisDprReleaseSpinLock(_SpinLock)
Definition: ndis.h:4133
#define NdisDprAcquireSpinLock(_SpinLock)
Definition: ndis.h:4124
static VOID NvNetSetSpeedAndDuplex(_In_ PNVNET_ADAPTER Adapter, _In_ ULONG MiiAdvertise, _In_ ULONG MiiLinkPartnerAbility)
Definition: phy.c:821
static BOOLEAN MiiGetSpeedAndDuplex(_In_ PNVNET_ADAPTER Adapter, _Out_ PULONG MiiAdvertise, _Out_ PULONG MiiLinkPartnerAbility, _Out_ PULONG LinkSpeed, _Out_ PBOOLEAN FullDuplex)
Definition: phy.c:721
#define NV_ACTIVE
Definition: nvnet.h:286
@ LinkUp
Definition: srb.h:741

Referenced by HandleLinkStateChange(), NvNetInitPhaseSynchronized(), and NvNetMediaDetectionDpc().

◆ PhyInit()

static NDIS_STATUS PhyInit ( _In_ PNVNET_ADAPTER  Adapter)
static

Definition at line 358 of file phy.c.

360{
361 ULONG PhyInterface, MiiRegister, MiiStatus, MiiControl;
362
363 PAGED_CODE();
364
365 NDIS_DbgPrint(MIN_TRACE, ("()\n"));
366
367 /* PHY errata for E3016 PHY */
368 if (Adapter->PhyModel == PHY_MODEL_MARVELL_E3016)
369 {
370 MiiRead(Adapter, Adapter->PhyAddress, PHY_MARVELL_INIT_REG1, &MiiRegister);
371 MiiRegister &= ~PHY_MARVELL_E3016_INITMASK;
372 if (!MiiWrite(Adapter, Adapter->PhyAddress, PHY_MARVELL_INIT_REG1, MiiRegister))
373 {
374 NDIS_DbgPrint(MAX_TRACE, ("PHY init failed\n"));
375 return NDIS_STATUS_FAILURE;
376 }
377 }
378
379 if (Adapter->PhyOui == PHY_OUI_REALTEK)
380 {
381 if (Adapter->PhyModel == PHY_MODEL_REALTEK_8211 &&
382 Adapter->PhyRevision == PHY_REV_REALTEK_8211B)
383 {
384 if (!PhyInitRealtek8211b(Adapter))
385 {
386 NDIS_DbgPrint(MAX_TRACE, ("PHY init failed\n"));
387 return NDIS_STATUS_FAILURE;
388 }
389 }
390 else if (Adapter->PhyModel == PHY_MODEL_REALTEK_8211 &&
391 Adapter->PhyRevision == PHY_REV_REALTEK_8211C)
392 {
393 if (!PhyInitRealtek8211c(Adapter))
394 {
395 NDIS_DbgPrint(MAX_TRACE, ("PHY init failed\n"));
396 return NDIS_STATUS_FAILURE;
397 }
398 }
399 else if (Adapter->PhyModel == PHY_MODEL_REALTEK_8201)
400 {
401 if (!PhyInitRealtek8201(Adapter, FALSE))
402 {
403 NDIS_DbgPrint(MAX_TRACE, ("PHY init failed\n"));
404 return NDIS_STATUS_FAILURE;
405 }
406 }
407 }
408
409 /* Set advertise register */
410 MiiRead(Adapter, Adapter->PhyAddress, MII_AUTONEG_ADVERTISE, &MiiRegister);
411 if (Adapter->Flags & NV_FORCE_SPEED_AND_DUPLEX)
412 {
415
416 if (Adapter->Flags & NV_USER_SPEED_100)
417 {
418 if (Adapter->Flags & NV_FORCE_FULL_DUPLEX)
419 MiiRegister |= MII_ADV_100T_FD;
420 else
421 MiiRegister |= MII_ADV_100T_HD;
422 }
423 else
424 {
425 if (Adapter->Flags & NV_FORCE_FULL_DUPLEX)
426 MiiRegister |= MII_ADV_10T_FD;
427 else
428 MiiRegister |= MII_ADV_10T_HD;
429 }
430
431 Adapter->PauseFlags &= ~(NV_PAUSEFRAME_AUTONEG | NV_PAUSEFRAME_RX_ENABLE |
433 if (Adapter->PauseFlags & NV_PAUSEFRAME_RX_REQ)
434 {
435 /* For RX we set both advertisements but disable TX pause */
436 MiiRegister |= MII_ADV_PAUSE_SYM | MII_ADV_PAUSE_ASYM;
437 Adapter->PauseFlags |= NV_PAUSEFRAME_RX_ENABLE;
438 }
439 if (Adapter->PauseFlags & NV_PAUSEFRAME_TX_REQ)
440 {
441 MiiRegister |= MII_ADV_PAUSE_ASYM;
442 Adapter->PauseFlags |= NV_PAUSEFRAME_TX_ENABLE;
443 }
444 }
445 else
446 {
449 }
450 if (!MiiWrite(Adapter, Adapter->PhyAddress, MII_AUTONEG_ADVERTISE, MiiRegister))
451 {
452 NDIS_DbgPrint(MAX_TRACE, ("PHY init failed!\n"));
453 return NDIS_STATUS_FAILURE;
454 }
455
456 /* Get PHY interface type */
457 PhyInterface = NV_READ(Adapter, NvRegPhyInterface);
458
459 /* See if gigabit PHY */
460 MiiRead(Adapter, Adapter->PhyAddress, MII_STATUS, &MiiStatus);
461 if (MiiStatus & PHY_GIGABIT)
462 {
463 ULONG MiiControl1000;
464
465 Adapter->Flags |= NV_GIGABIT_PHY;
466
467 MiiRead(Adapter, Adapter->PhyAddress, MII_MASTER_SLAVE_CONTROL, &MiiControl1000);
468 MiiControl1000 &= ~MII_MS_CR_1000T_HD;
469 if ((PhyInterface & PHY_RGMII) && !(Adapter->Flags & NV_FORCE_SPEED_AND_DUPLEX))
470 MiiControl1000 |= MII_MS_CR_1000T_FD;
471 else
472 MiiControl1000 &= ~MII_MS_CR_1000T_FD;
473 if (!MiiWrite(Adapter, Adapter->PhyAddress, MII_MASTER_SLAVE_CONTROL, MiiControl1000))
474 {
475 NDIS_DbgPrint(MAX_TRACE, ("PHY init failed\n"));
476 return NDIS_STATUS_FAILURE;
477 }
478 }
479 else
480 {
481 Adapter->Flags &= ~NV_GIGABIT_PHY;
482 }
483
484 MiiRead(Adapter, Adapter->PhyAddress, MII_CONTROL, &MiiControl);
485 MiiControl |= MII_CR_AUTONEG;
486 if (Adapter->PhyOui == PHY_OUI_REALTEK &&
487 Adapter->PhyModel == PHY_MODEL_REALTEK_8211 &&
488 Adapter->PhyRevision == PHY_REV_REALTEK_8211C)
489 {
490 /* Start auto-negation since we already performed HW reset above */
491 MiiControl |= MII_CR_AUTONEG_RESTART;
492 if (!MiiWrite(Adapter, Adapter->PhyAddress, MII_CONTROL, MiiControl))
493 {
494 NDIS_DbgPrint(MAX_TRACE, ("PHY init failed\n"));
495 return NDIS_STATUS_FAILURE;
496 }
497 }
498 else
499 {
500 /* Reset the PHY (certain PHYs need BMCR to be setup with reset) */
501 if (!PhyReset(Adapter, MiiControl))
502 {
503 NDIS_DbgPrint(MAX_TRACE, ("PHY reset failed\n"));
504 return NDIS_STATUS_FAILURE;
505 }
506 }
507
508 /* PHY vendor specific configuration */
509 if (Adapter->PhyOui == PHY_OUI_CICADA)
510 {
511 if (!PhyInitCicadaSemiconductor(Adapter, PhyInterface))
512 {
513 NDIS_DbgPrint(MAX_TRACE, ("PHY init failed\n"));
514 return NDIS_STATUS_FAILURE;
515 }
516 }
517 else if (Adapter->PhyOui == PHY_OUI_VITESSE)
518 {
519 if (!PhyInitVitesseSemiconductor(Adapter))
520 {
521 NDIS_DbgPrint(MAX_TRACE, ("PHY init failed\n"));
522 return NDIS_STATUS_FAILURE;
523 }
524 }
525 else if (Adapter->PhyOui == PHY_OUI_REALTEK)
526 {
527 if (Adapter->PhyModel == PHY_MODEL_REALTEK_8211 &&
528 Adapter->PhyRevision == PHY_REV_REALTEK_8211B)
529 {
530 /* Reset could have cleared these out, set them back */
531 if (!PhyInitRealtek8211b(Adapter))
532 {
533 NDIS_DbgPrint(MAX_TRACE, ("PHY init failed\n"));
534 return NDIS_STATUS_FAILURE;
535 }
536 }
537 else if (Adapter->PhyModel == PHY_MODEL_REALTEK_8201)
538 {
539 if (!PhyInitRealtek8201(Adapter, TRUE))
540 {
541 NDIS_DbgPrint(MAX_TRACE, ("PHY init failed\n"));
542 return NDIS_STATUS_FAILURE;
543 }
544 }
545 }
546
547 /* Some PHYs clear out pause advertisement on reset, set it back */
548 MiiWrite(Adapter, Adapter->PhyAddress, MII_AUTONEG_ADVERTISE, MiiRegister);
549
550 /* Restart auto-negotiation */
551 MiiRead(Adapter, Adapter->PhyAddress, MII_CONTROL, &MiiControl);
552 MiiControl |= (MII_CR_AUTONEG_RESTART | MII_CR_AUTONEG);
553 if (!MiiWrite(Adapter, Adapter->PhyAddress, MII_CONTROL, MiiControl))
554 return NDIS_STATUS_FAILURE;
555
556 return NDIS_STATUS_SUCCESS;
557}
#define MII_ADV_10T_FD
Definition: dc21x4hw.h:574
#define MII_ADV_100T4
Definition: dc21x4hw.h:577
#define MII_CR_AUTONEG
Definition: dc21x4hw.h:562
#define MII_CR_AUTONEG_RESTART
Definition: dc21x4hw.h:559
#define MII_ADV_100T_HD
Definition: dc21x4hw.h:575
#define MII_ADV_100T_FD
Definition: dc21x4hw.h:576
#define MII_ADV_10T_HD
Definition: dc21x4hw.h:573
#define MII_CONTROL
Definition: dc21x4hw.h:556
#define PHY_MODEL_MARVELL_E3016
Definition: nic.h:482
#define PHY_MODEL_REALTEK_8201
Definition: nic.h:481
#define PHY_REV_REALTEK_8211B
Definition: nic.h:530
#define PHY_MARVELL_INIT_REG1
Definition: nic.h:501
#define PHY_OUI_CICADA
Definition: nic.h:476
#define PHY_OUI_VITESSE
Definition: nic.h:477
#define PHY_REV_REALTEK_8211C
Definition: nic.h:531
#define NV_PAUSEFRAME_RX_REQ
Definition: nic.h:547
static BOOLEAN PhyInitRealtek8211c(_In_ PNVNET_ADAPTER Adapter)
Definition: phy.c:141
static BOOLEAN PhyInitRealtek8211b(_In_ PNVNET_ADAPTER Adapter)
Definition: phy.c:106
static BOOLEAN PhyInitRealtek8201(_In_ PNVNET_ADAPTER Adapter, _In_ BOOLEAN DisableCrossoverDetection)
Definition: phy.c:183
static BOOLEAN PhyInitVitesseSemiconductor(_In_ PNVNET_ADAPTER Adapter)
Definition: phy.c:257
static BOOLEAN PhyInitCicadaSemiconductor(_In_ PNVNET_ADAPTER Adapter, _In_ ULONG PhyInterface)
Definition: phy.c:222
static BOOLEAN PhyReset(_In_ PNVNET_ADAPTER Adapter, _In_ ULONG ControlSetup)
Definition: phy.c:326
BOOLEAN MiiWrite(_In_ PNVNET_ADAPTER Adapter, _In_ ULONG PhyAddress, _In_ ULONG RegAddress, _In_ ULONG Data)
Definition: phy.c:26

Referenced by NvNetPhyInit().

◆ PhyInitCicadaSemiconductor()

static BOOLEAN PhyInitCicadaSemiconductor ( _In_ PNVNET_ADAPTER  Adapter,
_In_ ULONG  PhyInterface 
)
static

Definition at line 222 of file phy.c.

225{
226 ULONG MiiRegister;
227
228 PAGED_CODE();
229
230 NDIS_DbgPrint(MIN_TRACE, ("()\n"));
231
232 if (PhyInterface & PHY_RGMII)
233 {
234 MiiRead(Adapter, Adapter->PhyAddress, PHY_CICADA_INIT_REG2, &MiiRegister);
235 MiiRegister &= ~(PHY_CICADA_INIT1 | PHY_CICADA_INIT2);
236 MiiRegister |= (PHY_CICADA_INIT3 | PHY_CICADA_INIT4);
237 if (!MiiWrite(Adapter, Adapter->PhyAddress, PHY_CICADA_INIT_REG2, MiiRegister))
238 return FALSE;
239
240 MiiRead(Adapter, Adapter->PhyAddress, PHY_CICADA_INIT_REG3, &MiiRegister);
241 MiiRegister |= PHY_CICADA_INIT5;
242 if (!MiiWrite(Adapter, Adapter->PhyAddress, PHY_CICADA_INIT_REG3, MiiRegister))
243 return FALSE;
244 }
245
246 MiiRead(Adapter, Adapter->PhyAddress, PHY_CICADA_INIT_REG1, &MiiRegister);
247 MiiRegister |= PHY_CICADA_INIT6;
248 if (!MiiWrite(Adapter, Adapter->PhyAddress, PHY_CICADA_INIT_REG1, MiiRegister))
249 return FALSE;
250
251 return TRUE;
252}
#define PHY_CICADA_INIT1
Definition: nic.h:495
#define PHY_CICADA_INIT_REG3
Definition: nic.h:499
#define PHY_CICADA_INIT3
Definition: nic.h:497
#define PHY_CICADA_INIT5
Definition: nic.h:500
#define PHY_CICADA_INIT4
Definition: nic.h:498
#define PHY_CICADA_INIT2
Definition: nic.h:496
#define PHY_CICADA_INIT_REG1
Definition: nic.h:492
#define PHY_CICADA_INIT_REG2
Definition: nic.h:494
#define PHY_CICADA_INIT6
Definition: nic.h:493

Referenced by PhyInit().

◆ PhyInitRealtek8201()

static BOOLEAN PhyInitRealtek8201 ( _In_ PNVNET_ADAPTER  Adapter,
_In_ BOOLEAN  DisableCrossoverDetection 
)
static

Definition at line 183 of file phy.c.

186{
187 ULONG MiiRegister;
188
189 PAGED_CODE();
190
191 NDIS_DbgPrint(MIN_TRACE, ("()\n"));
192
193 if (Adapter->Features & DEV_NEED_PHY_INIT_FIX)
194 {
195 MiiRead(Adapter, Adapter->PhyAddress, PHY_REALTEK_INIT_REG6, &MiiRegister);
196 MiiRegister |= PHY_REALTEK_INIT7;
197 if (!MiiWrite(Adapter, Adapter->PhyAddress, PHY_REALTEK_INIT_REG6, MiiRegister))
198 return FALSE;
199 }
200
201 if (DisableCrossoverDetection)
202 {
203 if (!MiiWrite(Adapter, Adapter->PhyAddress, PHY_REALTEK_INIT_REG1, PHY_REALTEK_INIT3))
204 return FALSE;
205
206 MiiRead(Adapter, Adapter->PhyAddress, PHY_REALTEK_INIT_REG2, &MiiRegister);
207 MiiRegister &= ~PHY_REALTEK_INIT_MSK1;
208 MiiRegister |= PHY_REALTEK_INIT3;
209 if (!MiiWrite(Adapter, Adapter->PhyAddress, PHY_REALTEK_INIT_REG2, MiiRegister))
210 return FALSE;
211
212 if (!MiiWrite(Adapter, Adapter->PhyAddress, PHY_REALTEK_INIT_REG1, PHY_REALTEK_INIT1))
213 return FALSE;
214 }
215
216 return TRUE;
217}
#define PHY_REALTEK_INIT_REG6
Definition: nic.h:521
#define DEV_NEED_PHY_INIT_FIX
Definition: nic.h:40
#define PHY_REALTEK_INIT1
Definition: nic.h:539
#define PHY_REALTEK_INIT3
Definition: nic.h:540
#define PHY_REALTEK_INIT_REG2
Definition: nic.h:534
#define PHY_REALTEK_INIT_REG1
Definition: nic.h:538
#define PHY_REALTEK_INIT7
Definition: nic.h:522

Referenced by PhyInit().

◆ PhyInitRealtek8211b()

static BOOLEAN PhyInitRealtek8211b ( _In_ PNVNET_ADAPTER  Adapter)
static

Definition at line 106 of file phy.c.

108{
109 ULONG i;
110 const struct
111 {
113 ULONG Data;
114 } Sequence[] =
115 {
123 };
124
125 PAGED_CODE();
126
127 NDIS_DbgPrint(MIN_TRACE, ("()\n"));
128
129 for (i = 0; i < RTL_NUMBER_OF(Sequence); ++i)
130 {
131 if (!MiiWrite(Adapter, Adapter->PhyAddress, Sequence[i].Register, Sequence[i].Data))
132 return FALSE;
133 }
134
135 return TRUE;
136}
#define RTL_NUMBER_OF(x)
Definition: RtlRegistry.c:12
#define PHY_REALTEK_INIT2
Definition: nic.h:535
#define PHY_REALTEK_INIT_REG3
Definition: nic.h:524
#define PHY_REALTEK_INIT5
Definition: nic.h:527
#define PHY_REALTEK_INIT4
Definition: nic.h:525
#define PHY_REALTEK_INIT6
Definition: nic.h:533
#define PHY_REALTEK_INIT_REG4
Definition: nic.h:526
#define PHY_REALTEK_INIT_REG5
Definition: nic.h:532

Referenced by PhyInit().

◆ PhyInitRealtek8211c()

static BOOLEAN PhyInitRealtek8211c ( _In_ PNVNET_ADAPTER  Adapter)
static

Definition at line 141 of file phy.c.

143{
144 ULONG PowerState, MiiRegister;
145
146 PAGED_CODE();
147
148 NDIS_DbgPrint(MIN_TRACE, ("()\n"));
149
151
153 NdisMSleep(25000);
154
156 NdisMSleep(25000);
157
158 MiiRead(Adapter, Adapter->PhyAddress, PHY_REALTEK_INIT_REG6, &MiiRegister);
159 MiiRegister |= PHY_REALTEK_INIT9;
160 if (!MiiWrite(Adapter, Adapter->PhyAddress, PHY_REALTEK_INIT_REG6, MiiRegister))
161 return FALSE;
162
163 if (!MiiWrite(Adapter, Adapter->PhyAddress, PHY_REALTEK_INIT_REG1, PHY_REALTEK_INIT10))
164 return FALSE;
165
166 MiiRead(Adapter, Adapter->PhyAddress, PHY_REALTEK_INIT_REG7, &MiiRegister);
167 if (!(MiiRegister & PHY_REALTEK_INIT11))
168 {
169 MiiRegister |= PHY_REALTEK_INIT11;
170 if (!MiiWrite(Adapter, Adapter->PhyAddress, PHY_REALTEK_INIT_REG7, MiiRegister))
171 return FALSE;
172 }
173
174 if (!MiiWrite(Adapter, Adapter->PhyAddress, PHY_REALTEK_INIT_REG1, PHY_REALTEK_INIT1))
175 return FALSE;
176
177 return TRUE;
178}
VOID EXPORT NdisMSleep(IN ULONG MicrosecondsToSleep)
Definition: miniport.c:2928
#define PHY_REALTEK_INIT11
Definition: nic.h:520
#define PHY_REALTEK_INIT_REG7
Definition: nic.h:519
#define NVREG_POWERSTATE2_PHY_RESET
Definition: nic.h:337
#define PHY_REALTEK_INIT9
Definition: nic.h:523
#define PHY_REALTEK_INIT10
Definition: nic.h:541

Referenced by PhyInit().

◆ PhyInitVitesseSemiconductor()

static BOOLEAN PhyInitVitesseSemiconductor ( _In_ PNVNET_ADAPTER  Adapter)
static

Definition at line 257 of file phy.c.

259{
260 ULONG MiiRegister;
261
262 PAGED_CODE();
263
264 NDIS_DbgPrint(MIN_TRACE, ("()\n"));
265
266 if (!MiiWrite(Adapter, Adapter->PhyAddress, PHY_VITESSE_INIT_REG1, PHY_VITESSE_INIT1))
267 return FALSE;
268
269 if (!MiiWrite(Adapter, Adapter->PhyAddress, PHY_VITESSE_INIT_REG2, PHY_VITESSE_INIT2))
270 return FALSE;
271
272 MiiRead(Adapter, Adapter->PhyAddress, PHY_VITESSE_INIT_REG4, &MiiRegister);
273 if (!MiiWrite(Adapter, Adapter->PhyAddress, PHY_VITESSE_INIT_REG4, MiiRegister))
274 return FALSE;
275
276 MiiRead(Adapter, Adapter->PhyAddress, PHY_VITESSE_INIT_REG3, &MiiRegister);
277 MiiRegister &= ~PHY_VITESSE_INIT_MSK1;
278 MiiRegister |= PHY_VITESSE_INIT3;
279 if (!MiiWrite(Adapter, Adapter->PhyAddress, PHY_VITESSE_INIT_REG3, MiiRegister))
280 return FALSE;
281
282 if (!MiiWrite(Adapter, Adapter->PhyAddress, PHY_VITESSE_INIT_REG2, PHY_VITESSE_INIT4))
283 return FALSE;
284
285 if (!MiiWrite(Adapter, Adapter->PhyAddress, PHY_VITESSE_INIT_REG2, PHY_VITESSE_INIT5))
286 return FALSE;
287
288 MiiRead(Adapter, Adapter->PhyAddress, PHY_VITESSE_INIT_REG4, &MiiRegister);
289 MiiRegister &= ~PHY_VITESSE_INIT_MSK1;
290 MiiRegister |= PHY_VITESSE_INIT3;
291 if (!MiiWrite(Adapter, Adapter->PhyAddress, PHY_VITESSE_INIT_REG4, MiiRegister))
292 return FALSE;
293
294 MiiRead(Adapter, Adapter->PhyAddress, PHY_VITESSE_INIT_REG3, &MiiRegister);
295 if (!MiiWrite(Adapter, Adapter->PhyAddress, PHY_VITESSE_INIT_REG3, MiiRegister))
296 return FALSE;
297
298 if (!MiiWrite(Adapter, Adapter->PhyAddress, PHY_VITESSE_INIT_REG2, PHY_VITESSE_INIT6))
299 return FALSE;
300
301 if (!MiiWrite(Adapter, Adapter->PhyAddress, PHY_VITESSE_INIT_REG2, PHY_VITESSE_INIT7))
302 return FALSE;
303
304 MiiRead(Adapter, Adapter->PhyAddress, PHY_VITESSE_INIT_REG4, &MiiRegister);
305 if (!MiiWrite(Adapter, Adapter->PhyAddress, PHY_VITESSE_INIT_REG4, MiiRegister))
306 return FALSE;
307
308 MiiRead(Adapter, Adapter->PhyAddress, PHY_VITESSE_INIT_REG3, &MiiRegister);
309 MiiRegister &= ~PHY_VITESSE_INIT_MSK2;
310 MiiRegister |= PHY_VITESSE_INIT8;
311 if (!MiiWrite(Adapter, Adapter->PhyAddress, PHY_VITESSE_INIT_REG3, MiiRegister))
312 return FALSE;
313
314 if (!MiiWrite(Adapter, Adapter->PhyAddress, PHY_VITESSE_INIT_REG2, PHY_VITESSE_INIT9))
315 return FALSE;
316
317 if (!MiiWrite(Adapter, Adapter->PhyAddress, PHY_VITESSE_INIT_REG1, PHY_VITESSE_INIT10))
318 return FALSE;
319
320 return TRUE;
321}
#define PHY_VITESSE_INIT8
Definition: nic.h:515
#define PHY_VITESSE_INIT10
Definition: nic.h:518
#define PHY_VITESSE_INIT_REG3
Definition: nic.h:510
#define PHY_VITESSE_INIT1
Definition: nic.h:517
#define PHY_VITESSE_INIT2
Definition: nic.h:504
#define PHY_VITESSE_INIT5
Definition: nic.h:506
#define PHY_VITESSE_INIT_REG4
Definition: nic.h:511
#define PHY_VITESSE_INIT7
Definition: nic.h:508
#define PHY_VITESSE_INIT6
Definition: nic.h:507
#define PHY_VITESSE_INIT9
Definition: nic.h:509
#define PHY_VITESSE_INIT_REG1
Definition: nic.h:516
#define PHY_VITESSE_INIT3
Definition: nic.h:513
#define PHY_VITESSE_INIT4
Definition: nic.h:505
#define PHY_VITESSE_INIT_REG2
Definition: nic.h:503

Referenced by PhyInit().

◆ PhyReset()

static BOOLEAN PhyReset ( _In_ PNVNET_ADAPTER  Adapter,
_In_ ULONG  ControlSetup 
)
static

Definition at line 326 of file phy.c.

329{
330 ULONG Tries = 0, MiiControl = MII_CR_RESET | ControlSetup;
331
332 PAGED_CODE();
333
334 NDIS_DbgPrint(MIN_TRACE, ("()\n"));
335
336 if (!MiiWrite(Adapter, Adapter->PhyAddress, MII_CONTROL, MiiControl))
337 return FALSE;
338
339 NdisMSleep(500000);
340
341 do
342 {
343 NdisMSleep(10000);
344
345 MiiRead(Adapter, Adapter->PhyAddress, MII_CONTROL, &MiiControl);
346
347 if (Tries++ > 100)
348 return FALSE;
349 }
350 while (MiiControl & MII_CR_RESET);
351
352 return TRUE;
353}
#define MII_CR_RESET
Definition: dc21x4hw.h:565

Referenced by PhyInit().

◆ SidebandUnitAcquireSemaphore()

static BOOLEAN SidebandUnitAcquireSemaphore ( _Inout_ PNVNET_ADAPTER  Adapter)
static

Definition at line 621 of file phy.c.

623{
624 ULONG i;
625
626 PAGED_CODE();
627
628 NDIS_DbgPrint(MIN_TRACE, ("()\n"));
629
630 for (i = 10; i > 0; --i)
631 {
634 {
635 break;
636 }
637
638 NdisMSleep(500000);
639 }
640 if (i == 0)
641 {
642 return FALSE;
643 }
644
645 for (i = 0; i < 2; ++i)
646 {
647 ULONG TxControl = NV_READ(Adapter, NvRegTransmitterControl);
648
650
651 /* Verify that the semaphore was acquired */
652 TxControl = NV_READ(Adapter, NvRegTransmitterControl);
655 {
656 Adapter->Flags |= NV_UNIT_SEMAPHORE_ACQUIRED;
657 return TRUE;
658 }
659
661 }
662
663 return FALSE;
664}
#define NVREG_XMITCTL_HOST_SEMA_ACQ
Definition: nic.h:103
#define NVREG_XMITCTL_HOST_SEMA_MASK
Definition: nic.h:102
#define NVREG_XMITCTL_MGMT_SEMA_MASK
Definition: nic.h:100
#define NVREG_XMITCTL_MGMT_SEMA_FREE
Definition: nic.h:101
#define NV_UNIT_SEMAPHORE_ACQUIRED
Definition: nvnet.h:293

Referenced by NvNetPhyInit().

◆ SidebandUnitGetVersion()

static BOOLEAN SidebandUnitGetVersion ( _In_ PNVNET_ADAPTER  Adapter,
_Out_ PULONG  Version 
)
static

Definition at line 683 of file phy.c.

686{
687 ULONG i, DataReady, DataReady2;
688
689 PAGED_CODE();
690
691 NDIS_DbgPrint(MIN_TRACE, ("()\n"));
692
693 DataReady = NV_READ(Adapter, NvRegTransmitterControl);
694
697
698 for (i = 100000; i > 0; --i)
699 {
700 DataReady2 = NV_READ(Adapter, NvRegTransmitterControl);
701
702 if ((DataReady & NVREG_XMITCTL_DATA_READY) != (DataReady2 & NVREG_XMITCTL_DATA_READY))
703 {
704 break;
705 }
706
708 }
709 if (i == 0 || DataReady2 & NVREG_XMITCTL_DATA_ERROR)
710 {
711 return FALSE;
712 }
713
715
716 return TRUE;
717}
#define NVREG_MGMTUNITVERSION
Definition: nic.h:280
#define NVREG_MGMTUNITGETVERSION
Definition: nic.h:277
#define NVREG_XMITCTL_DATA_START
Definition: nic.h:106
#define NVREG_XMITCTL_DATA_ERROR
Definition: nic.h:108
@ NvRegMgmtUnitGetVersion
Definition: nic.h:276
@ NvRegMgmtUnitVersion
Definition: nic.h:279
#define NVREG_XMITCTL_DATA_READY
Definition: nic.h:107
_Must_inspect_result_ _In_ WDFDEVICE _In_ LPCGUID _Out_ PINTERFACE _In_ USHORT _In_ USHORT Version
Definition: wdffdo.h:469

Referenced by NvNetPhyInit().

◆ SidebandUnitReleaseSemaphore()

VOID SidebandUnitReleaseSemaphore ( _In_ PNVNET_ADAPTER  Adapter)

Definition at line 667 of file phy.c.

669{
670 if (Adapter->Flags & NV_UNIT_SEMAPHORE_ACQUIRED)
671 {
672 ULONG TxControl;
673
674 TxControl = NV_READ(Adapter, NvRegTransmitterControl);
675 TxControl &= ~NVREG_XMITCTL_HOST_SEMA_ACQ;
676 NV_WRITE(Adapter, NvRegTransmitterControl, TxControl);
677 }
678}

Referenced by MiniportHalt(), and MiniportShutdown().