ReactOS 0.4.15-dev-7887-g64a59a1
phy.c
Go to the documentation of this file.
1/*
2 * PROJECT: ReactOS DC21x4 Driver
3 * LICENSE: GPL-2.0-or-later (https://spdx.org/licenses/GPL-2.0-or-later)
4 * PURPOSE: PHY layer setup and management
5 * COPYRIGHT: Copyright 2023 Dmitry Borisov <di.sean@protonmail.com>
6 */
7
8/* INCLUDES *******************************************************************/
9
10#include "dc21x4.h"
11
12#include <debug.h>
13
14/* GLOBALS ********************************************************************/
15
16#define MII_READ(Adapter, Data) \
17 do { \
18 *Data = DC_READ((Adapter), DcCsr9_SerialInterface); \
19 NdisStallExecution(2); \
20 } while (0)
21
22#define MII_WRITE(Adapter, Value) \
23 do { \
24 DC_WRITE((Adapter), DcCsr9_SerialInterface, Value); \
25 NdisStallExecution(2); \
26 } while (0)
27
28/* FUNCTIONS ******************************************************************/
29
30static
31VOID
33 _In_ PDC21X4_ADAPTER Adapter,
34 _In_ ULONG Sequence,
35 _In_ ULONG BitCount)
36{
37 LONG i;
38
39 for (i = BitCount - 1; i >= 0; --i)
40 {
41 ULONG Mdo = ((Sequence >> i) & 1) << DC_SERIAL_MII_MDO_SHIFT;
42
43 MII_WRITE(Adapter, Mdo);
44 MII_WRITE(Adapter, Mdo | DC_SERIAL_MII_MDC);
45 }
46}
47
48static
51 _In_ PDC21X4_ADAPTER Adapter)
52{
53 ULONG i, Csr;
54 ULONG Result = 0;
55
56 for (i = 0; i < RTL_BITS_OF(USHORT); ++i)
57 {
60
61 MII_READ(Adapter, &Csr);
62 Result = (Result << 1) | ((Csr >> DC_SERIAL_MII_MDI_SHIFT) & 1);
63 }
64
65 return Result;
66}
67
68static
69VOID
71 _In_ PDC21X4_ADAPTER Adapter)
72{
75}
76
79 _In_ PDC21X4_ADAPTER Adapter,
80 _In_ ULONG PhyAddress,
81 _In_ ULONG RegAddress,
83{
84 MiiMdioPacket(Adapter, MDIO_PREAMBLE, 32);
85 MiiMdioPacket(Adapter,
86 (MDIO_START << 30) |
87 (MDIO_WRITE << 28) |
88 (PhyAddress << 23) |
89 (RegAddress << 18) |
90 (MDIO_TA << 16) |
91 Data,
92 32);
93
94 /* Idle state */
95 MiiMdioClearExtraBits(Adapter);
96
97 return TRUE;
98}
99
102 _In_ PDC21X4_ADAPTER Adapter,
103 _In_ ULONG PhyAddress,
104 _In_ ULONG RegAddress,
106{
107 ULONG Csr;
109
110 MiiMdioPacket(Adapter, MDIO_PREAMBLE, 32);
111 MiiMdioPacket(Adapter,
112 (MDIO_START << 12) |
113 (MDIO_READ << 10) |
114 (PhyAddress << 5) |
115 RegAddress,
116 14);
117
118 /* Turnaround */
119 MiiMdioClearExtraBits(Adapter);
120
121 Csr = DC_READ(Adapter, DcCsr9_SerialInterface);
122 Success = !(Csr & DC_SERIAL_MII_MDI);
123
124 *Data = MiiMdioShiftIn(Adapter);
125
126 /* Idle state */
127 MiiMdioClearExtraBits(Adapter);
128
129 return Success;
130}
131
132static
133CODE_SEG("PAGE")
134VOID
136 _In_ PDC21X4_ADAPTER Adapter)
137{
138 PAGED_CODE();
139
140 DC_WRITE(Adapter, DcCsr9_SerialInterface, 0);
142}
143
144static
145CODE_SEG("PAGE")
146VOID
148 _In_ PDC21X4_ADAPTER Adapter,
149 _In_ ULONG Sequence,
150 _In_ ULONG BitCount)
151{
152 LONG i;
153
154 PAGED_CODE();
155
156 DC_WRITE(Adapter, DcCsr9_SerialInterface, 0);
158
159 for (i = BitCount - 1; i >= 0; --i)
160 {
161 ULONG DataIn = ((Sequence >> i) & 1) << DC_SERIAL_SPI_DI_SHIFT;
162
165 }
166
167 DC_WRITE(Adapter, DcCsr9_SerialInterface, 0);
169}
170
171static
172CODE_SEG("PAGE")
173VOID
175 _In_ PDC21X4_ADAPTER Adapter,
176 _In_ ULONG RegAddress,
178{
179 PAGED_CODE();
180
182 HpnaSpiClose(Adapter);
183
184 HpnaSpiShiftOut(Adapter,
185 (Data << 16) |
186 (RegAddress << 8) |
188 RTL_BITS_OF(UCHAR) * 3);
189 HpnaSpiClose(Adapter);
190}
191
192CODE_SEG("PAGE")
193VOID
195 _In_ PDC21X4_ADAPTER Adapter)
196{
197 ULONG SiaConn, i;
198
199 PAGED_CODE();
200
201 /* Select the HPNA interface */
202 SiaConn = DC_READ(Adapter, DcCsr13_SiaConnectivity);
203 SiaConn |= DC_SIA_CONN_HPNA;
204 DC_WRITE(Adapter, DcCsr13_SiaConnectivity, SiaConn);
205
206 for (i = 0; i < RTL_NUMBER_OF(Adapter->HpnaRegister); ++i)
207 {
208 if (Adapter->HpnaInitBitmap & (1 << i))
209 {
210 HpnaWrite(Adapter, i, Adapter->HpnaRegister[i]);
211 }
212 }
213}
214
215CODE_SEG("PAGE")
218 _In_ PDC21X4_ADAPTER Adapter)
219{
220 ULONG Phy;
221
222 PAGED_CODE();
223
224 /* Look for the first connected PHY */
225 for (Phy = 1; Phy <= MII_MAX_PHY_ADDRESSES; ++Phy)
226 {
227 ULONG PhyAddress = Phy % MII_MAX_PHY_ADDRESSES; /* Check the PHY 0 last */
228 ULONG MiiStatus;
229#if DBG
230 ULONG PhyIdLow, PhyIdHigh, MiiControl, MiiAdvertise;
231#endif
232
233 /*
234 * Read the status register. Some PHYs, such as the ML6692,
235 * don't implement the IEEE ID registers.
236 */
237 if (!MiiRead(Adapter, PhyAddress, MII_STATUS, &MiiStatus))
238 continue;
239 if (MiiStatus == 0xFFFF || MiiStatus == 0)
240 continue;
241
242#if DBG
243 MiiRead(Adapter, PhyAddress, MII_PHY_ID1, &PhyIdLow);
244 MiiRead(Adapter, PhyAddress, MII_PHY_ID2, &PhyIdHigh);
245 MiiRead(Adapter, PhyAddress, MII_CONTROL, &MiiControl);
246 MiiRead(Adapter, PhyAddress, MII_AUTONEG_ADVERTISE, &MiiAdvertise);
247
248 INFO_VERB("Found PHY at address %u: ID %04lx:%04lx, Ctrl %04lx, Status %04lx, Adv %04lx\n",
249 PhyAddress,
250 PhyIdLow,
251 PhyIdHigh,
252 MiiControl,
253 MiiStatus,
254 MiiAdvertise);
255#endif
256
257 Adapter->PhyAddress = PhyAddress;
258
259 return TRUE;
260 }
261
262 return FALSE;
263}
#define PAGED_CODE()
#define CODE_SEG(...)
unsigned char BOOLEAN
#define RTL_NUMBER_OF(x)
Definition: RtlRegistry.c:12
static VOID HpnaSpiShiftOut(_In_ PDC21X4_ADAPTER Adapter, _In_ ULONG Sequence, _In_ ULONG BitCount)
Definition: phy.c:147
#define MII_WRITE(Adapter, Value)
Definition: phy.c:22
VOID HpnaPhyInit(_In_ PDC21X4_ADAPTER Adapter)
Definition: phy.c:194
static VOID MiiMdioClearExtraBits(_In_ PDC21X4_ADAPTER Adapter)
Definition: phy.c:70
static VOID HpnaSpiClose(_In_ PDC21X4_ADAPTER Adapter)
Definition: phy.c:135
static ULONG MiiMdioShiftIn(_In_ PDC21X4_ADAPTER Adapter)
Definition: phy.c:50
BOOLEAN MiiRead(_In_ PDC21X4_ADAPTER Adapter, _In_ ULONG PhyAddress, _In_ ULONG RegAddress, _Out_ PULONG Data)
Definition: phy.c:101
static VOID MiiMdioPacket(_In_ PDC21X4_ADAPTER Adapter, _In_ ULONG Sequence, _In_ ULONG BitCount)
Definition: phy.c:32
#define MII_READ(Adapter, Data)
Definition: phy.c:16
BOOLEAN DcFindMiiPhy(_In_ PDC21X4_ADAPTER Adapter)
Definition: phy.c:217
static VOID HpnaWrite(_In_ PDC21X4_ADAPTER Adapter, _In_ ULONG RegAddress, _In_ ULONG Data)
Definition: phy.c:174
BOOLEAN MiiWrite(_In_ PDC21X4_ADAPTER Adapter, _In_ ULONG PhyAddress, _In_ ULONG RegAddress, _In_ ULONG Data)
Definition: phy.c:78
FORCEINLINE ULONG DC_READ(_In_ PDC21X4_ADAPTER Adapter, _In_ DC_CSR Register)
Definition: dc21x4.h:262
#define DC_WRITE(Adapter, Register, Value)
Definition: dc21x4.h:272
#define MDIO_PREAMBLE
Definition: dc21x4hw.h:549
#define MII_STATUS
Definition: dc21x4hw.h:566
#define MDIO_TA
Definition: dc21x4hw.h:548
#define DC_SPI_BYTE_WRITE_OPERATION
Definition: dc21x4hw.h:527
#define MDIO_START
Definition: dc21x4hw.h:545
#define DC_SERIAL_SPI_CS
Definition: dc21x4hw.h:388
#define MII_PHY_ID2
Definition: dc21x4hw.h:570
@ DcCsr9_SerialInterface
Definition: dc21x4hw.h:183
@ DcCsr13_SiaConnectivity
Definition: dc21x4hw.h:189
#define MII_MAX_PHY_ADDRESSES
Definition: dc21x4hw.h:551
#define MII_AUTONEG_ADVERTISE
Definition: dc21x4hw.h:571
#define DC_SERIAL_SPI_SK
Definition: dc21x4hw.h:389
#define DC_SIA_CONN_HPNA
Definition: dc21x4hw.h:450
#define DC_SERIAL_MII_MDI
Definition: dc21x4hw.h:385
#define DC_SERIAL_SPI_DI_SHIFT
Definition: dc21x4hw.h:397
#define DC_SPI_SET_WRITE_ENABLE
Definition: dc21x4hw.h:530
#define DC_SERIAL_MII_MDI_SHIFT
Definition: dc21x4hw.h:396
#define DC_SERIAL_MII_MDC
Definition: dc21x4hw.h:382
#define MDIO_READ
Definition: dc21x4hw.h:547
#define DC_SERIAL_MII_MDO_SHIFT
Definition: dc21x4hw.h:395
#define DC_SERIAL_MII_MII
Definition: dc21x4hw.h:384
#define MII_PHY_ID1
Definition: dc21x4hw.h:569
#define MII_CONTROL
Definition: dc21x4hw.h:556
#define MDIO_WRITE
Definition: dc21x4hw.h:546
#define TRUE
Definition: types.h:120
#define FALSE
Definition: types.h:117
#define INFO_VERB
Definition: debug.h:90
@ Success
Definition: eventcreate.c:712
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 _Out_
Definition: ms_sal.h:345
#define _In_
Definition: ms_sal.h:308
#define RTL_BITS_OF(sizeOfArg)
Definition: ntbasedef.h:668
long LONG
Definition: pedump.c:60
unsigned short USHORT
Definition: pedump.c:61
uint32_t * PULONG
Definition: typedefs.h:59
uint32_t ULONG
Definition: typedefs.h:59
_At_(*)(_In_ PWSK_CLIENT Client, _In_opt_ PUNICODE_STRING NodeName, _In_opt_ PUNICODE_STRING ServiceName, _In_opt_ ULONG NameSpace, _In_opt_ GUID *Provider, _In_opt_ PADDRINFOEXW Hints, _Outptr_ PADDRINFOEXW *Result, _In_opt_ PEPROCESS OwningProcess, _In_opt_ PETHREAD OwningThread, _Inout_ PIRP Irp Result)(Mem)) NTSTATUS(WSKAPI *PFN_WSK_GET_ADDRESS_INFO
Definition: wsk.h:409
unsigned char UCHAR
Definition: xmlstorage.h:181