ReactOS 0.4.15-dev-7961-gdcf9eb0
media143.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: 21142/21143/21145 media support code
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/* FUNCTIONS ******************************************************************/
15
16static
17VOID
19 _In_ PDC21X4_ADAPTER Adapter)
20{
21 ULONG MediaNumber;
22
23 MediaNumber = Adapter->MediaNumber;
24
25 /* The HMR media isn't checked as HMR boards use it instead of AUI and BNC */
26 if (MediaNumber == MEDIA_AUI || MediaNumber == MEDIA_BNC)
27 {
28 if (MediaNumber == MEDIA_AUI)
29 Adapter->ModeFlags |= DC_MODE_AUI_FAILED;
30 else if (MediaNumber == MEDIA_BNC)
31 Adapter->ModeFlags |= DC_MODE_BNC_FAILED;
32
33 if ((Adapter->ModeFlags & (DC_MODE_AUI_FAILED | DC_MODE_BNC_FAILED)) !=
35 {
36 MediaNumber = (MEDIA_BNC + MEDIA_AUI) - MediaNumber;
37
38 if (Adapter->MediaBitmap & (1 << MediaNumber))
39 {
40 Adapter->MediaNumber = MediaNumber;
41 MediaSiaSelect(Adapter);
42 return;
43 }
44 }
45 }
46
47 if (Adapter->Features & DC_HAS_MII)
48 {
49 Adapter->MediaNumber = MEDIA_MII;
50
51 DcStopTxRxProcess(Adapter);
52 MediaSelectMiiPort(Adapter, FALSE);
53 MediaMiiSelect(Adapter);
54 }
55 else
56 {
57 Adapter->MediaNumber = MEDIA_10T;
58 MediaSiaSelect(Adapter);
59 }
60}
61
62static
63VOID
65 _In_ PDC21X4_ADAPTER Adapter,
66 _In_ ULONG SiaStatus)
67{
68 ULONG MediaBitmap, MediaNumber;
69
71
72 MediaBitmap = Adapter->MediaBitmap;
73
74 if (MediaBitmap & (1 << MEDIA_HMR))
75 {
76 MediaNumber = MEDIA_HMR;
77 }
78 else if ((MediaBitmap & MEDIA_AUI_BNC_MASK) == MEDIA_AUI_BNC_MASK)
79 {
80 if (SiaStatus & DC_SIA_STATUS_AUI_ACTIVITY)
81 {
82 MediaNumber = MEDIA_AUI;
83 }
84 else
85 {
86 MediaNumber = MEDIA_BNC;
87 }
88 }
89 else if (MediaBitmap & (1 << MEDIA_AUI))
90 {
91 MediaNumber = MEDIA_AUI;
92 }
93 else if (MediaBitmap & (1 << MEDIA_BNC))
94 {
95 MediaNumber = MEDIA_BNC;
96 }
97 else
98 {
99 MediaNumber = MEDIA_10T;
100 }
101
102 Adapter->ModeFlags &= ~DC_MODE_AUTONEG_MASK;
103 Adapter->ModeFlags |= DC_MODE_AUTONEG_NONE;
104 NdisMSetTimer(&Adapter->MediaMonitorTimer, 3000);
105
106 if (Adapter->MediaNumber != MediaNumber)
107 {
108 Adapter->MediaNumber = MediaNumber;
109 MediaSiaSelect(Adapter);
110 }
111
112 Adapter->ModeFlags &= ~(DC_MODE_TEST_PACKET |
115 Adapter->LastReceiveActivity = (ULONG)Adapter->Statistics.ReceiveOk;
116}
117
118static
119VOID
121 _In_ PDC21X4_ADAPTER Adapter,
122 _In_ ULONG SiaStatus)
123{
124 INFO_VERB("Link failed, CSR12 %08lx\n", SiaStatus);
125
126 /* 10Base-T link is down */
127 MediaIndicateConnect(Adapter, FALSE);
128
129 /* Select the other port */
130 if (!MEDIA_IS_FIXED(Adapter))
131 {
132 Media143SelectNextMedia(Adapter, SiaStatus);
133 }
134}
135
136static
137VOID
139 _In_ PDC21X4_ADAPTER Adapter,
140 _In_ ULONG SiaStatus)
141{
142 INFO_VERB("Link passed, CSR12 %08lx\n", SiaStatus);
143
144 /* 10Base-T is the active port now */
145 if (!MEDIA_IS_10T(Adapter->MediaNumber))
146 {
147 /* Switch to TP medium */
148 if (!MEDIA_IS_FIXED(Adapter))
149 {
150 Adapter->MediaNumber = MEDIA_10T;
151 MediaSiaSelect(Adapter);
152
153 /* Wait for a link pass interrupt to signal the link test completed */
154 Adapter->ModeFlags &= ~DC_MODE_AUTONEG_MASK;
155 Adapter->ModeFlags |= DC_MODE_AUTONEG_WAIT_INTERRUPT;
156 NdisMSetTimer(&Adapter->MediaMonitorTimer, 3000);
157 }
158 }
159 else
160 {
161 /* 10Base-T link is up */
162 MediaIndicateConnect(Adapter, TRUE);
163 }
164}
165
166static
167VOID
169 _In_ PDC21X4_ADAPTER Adapter,
170 _In_ ULONG SiaStatus)
171{
173
174 INFO_VERB("Link changed, CSR12 %08lx\n", SiaStatus);
175
176 LinkUp = !(SiaStatus & DC_SIA_STATUS_100T_LINK_FAIL);
177
178 if (MEDIA_IS_FIXED(Adapter))
179 {
181 }
182 else
183 {
184 /* Select the other port */
185 if (!LinkUp)
186 {
187 Media143SelectNextMedia(Adapter, SiaStatus);
188 }
189 else
190 {
191 /* Ignore this hint */
192 }
193 }
194}
195
196static
197VOID
199 _In_ PDC21X4_ADAPTER Adapter,
200 _In_ ULONG SiaStatus)
201{
202 ULONG MediaNumber, AdvLpa;
203
204 /* Select media according to auto-negotiation result */
206 {
207 INFO_VERB("Auto-negotiation has completed, LPA %08lx ADV %08lx\n",
208 SiaStatus, Adapter->SymAdvertising);
209
210 AdvLpa = (SiaStatus >> DC_SIA_STATUS_LP_CODE_WORD_SHIFT) & Adapter->SymAdvertising;
211 if (AdvLpa & MII_ADV_100T_FD)
212 {
213 MediaNumber = MEDIA_100TX_FD;
214 }
215 else if (AdvLpa & MII_ADV_100T4)
216 {
217 MediaNumber = MEDIA_100T4;
218 }
219 else if (AdvLpa & MII_ADV_100T_HD)
220 {
221 MediaNumber = MEDIA_100TX_HD;
222 }
223 else if (AdvLpa & MII_ADV_10T_FD)
224 {
225 MediaNumber = MEDIA_10T_FD;
226 }
227 else if (AdvLpa & MII_ADV_10T_HD)
228 {
229 MediaNumber = MEDIA_10T;
230 }
231 else
232 {
233 INFO_VERB("No common mode\n");
234
235 /* No common mode, select the other port */
236 Media143SelectNextMedia(Adapter, SiaStatus);
237 return;
238 }
239 }
240 else
241 {
242 INFO_VERB("Link partner does not support auto-negotiation, CSR12 %08lx\n", SiaStatus);
243
244 /* Check the results of parallel detection */
245 if (!(SiaStatus & DC_SIA_STATUS_100T_LINK_FAIL))
246 {
247 MediaNumber = MEDIA_100TX_HD;
248 }
249 else if (!(SiaStatus & DC_SIA_STATUS_10T_LINK_FAIL))
250 {
251 MediaNumber = MEDIA_10T;
252 }
253 else
254 {
255 /* No link detected, select the other port */
256 Media143SelectNextMedia(Adapter, SiaStatus);
257 return;
258 }
259 }
260
261 if (MEDIA_IS_10T(MediaNumber) && (MediaNumber != Adapter->MediaNumber))
262 {
263 /* Set the time limit for auto-negotiation */
264 Adapter->ModeFlags &= ~DC_MODE_AUTONEG_MASK;
265 Adapter->ModeFlags |= DC_MODE_AUTONEG_WAIT_INTERRUPT;
266 NdisMSetTimer(&Adapter->MediaMonitorTimer, 5000);
267 }
268 else
269 {
270 /* Wait for the link integrity test to complete before we can read the link status */
271 Adapter->ModeFlags &= ~DC_MODE_AUTONEG_MASK;
272 Adapter->ModeFlags |= DC_MODE_AUTONEG_LINK_STATUS_CHECK;
273 NdisMSetTimer(&Adapter->MediaMonitorTimer, 1000);
274 }
275
276 if (Adapter->MediaNumber != MediaNumber)
277 {
278 Adapter->MediaNumber = MediaNumber;
279 MediaSiaSelect(Adapter);
280 }
281}
282
283VOID
285 _In_ PDC21X4_ADAPTER Adapter,
286 _In_ ULONG InterruptStatus)
287{
288 ULONG SiaStatus;
289
290 INFO_VERB("Link interrupt, CSR5 %08lx\n", InterruptStatus);
291
292 NdisDprAcquireSpinLock(&Adapter->ModeLock);
293
294 /* Ignore link changes caused by media being estabilished */
295 if ((Adapter->ModeFlags & DC_MODE_AUTONEG_MASK) == DC_MODE_AUTONEG_LINK_STATUS_CHECK)
296 {
297 NdisDprReleaseSpinLock(&Adapter->ModeLock);
298 return;
299 }
300
301 SiaStatus = DC_READ(Adapter, DcCsr12_SiaStatus);
302
303 if ((InterruptStatus & DC_IRQ_LINK_FAIL) && MEDIA_IS_10T(Adapter->MediaNumber))
304 {
305 /* Link has failed */
306 Media143Handle10LinkFail(Adapter, SiaStatus);
307 }
308 else if (InterruptStatus & DC_IRQ_LINK_PASS)
309 {
311 {
312 /* Auto-negotiation has completed */
313 Media143HandleNWayComplete(Adapter, SiaStatus);
314 }
315 else
316 {
317 /* Link has passed */
318 Media143Handle10LinkPass(Adapter, SiaStatus);
319 }
320 }
321 else
322 {
323 /* NOTE: The Link Changed bit is reserved on the 21142 and always reads as 1 */
324 if (InterruptStatus & Adapter->LinkStateChangeMask & DC_IRQ_LINK_CHANGED)
325 {
326 /* Link has changed */
327 Media143Handle100LinkChange(Adapter, SiaStatus);
328 }
329 }
330
331 NdisDprReleaseSpinLock(&Adapter->ModeLock);
332}
333
334static
337 _In_ PDC21X4_ADAPTER Adapter,
338 _In_ ULONG SiaStatus)
339{
340 if (MEDIA_IS_100(Adapter->MediaNumber))
341 {
342 if (SiaStatus & DC_SIA_STATUS_100T_LINK_FAIL)
343 return FALSE;
344 }
345 else
346 {
347 /* The auto-negotiation process can be restarted upon link failure in 10Base-T mode */
349 return FALSE;
350
351 if (SiaStatus & DC_SIA_STATUS_10T_LINK_FAIL)
352 return FALSE;
353 }
354
355 return TRUE;
356}
357
358static
359VOID
361 _In_ PDC21X4_ADAPTER Adapter)
362{
363 ULONG SiaStatus;
365
366 SiaStatus = DC_READ(Adapter, DcCsr12_SiaStatus);
367
368 switch (Adapter->ModeFlags & DC_MODE_AUTONEG_MASK)
369 {
371 {
372 /* Timeout, select the other port */
373 Media143SelectNextMedia(Adapter, SiaStatus);
374 break;
375 }
376
378 {
379 /* Check the link status */
380 LinkUp = Media143CheckLink(Adapter, SiaStatus);
381 if (LinkUp)
382 {
383 Adapter->ModeFlags &= ~DC_MODE_AUTONEG_MASK;
384 Adapter->ModeFlags |= DC_MODE_AUTONEG_NONE;
385
386 MediaIndicateConnect(Adapter, TRUE);
387 }
388 else
389 {
390 /* No link detected, select the other port */
391 Media143SelectNextMedia(Adapter, SiaStatus);
392 }
393 break;
394 }
395
397 {
398 break;
399 }
400
401 default:
402 ASSERT(FALSE);
404 break;
405 }
406}
407
408VOID
409NTAPI
411 _In_ PVOID SystemSpecific1,
415{
417 ULONG DelayMs;
419
420 UNREFERENCED_PARAMETER(SystemSpecific1);
423
424 if (!(Adapter->Flags & DC_ACTIVE))
425 return;
426
428
429 switch (Adapter->MediaNumber)
430 {
431 case MEDIA_MII:
432 {
433 LinkUp = MediaMiiCheckLink(Adapter);
434
436
437 NdisMSetTimer(&Adapter->MediaMonitorTimer, 5000);
438 break;
439 }
440
441 case MEDIA_AUI:
442 case MEDIA_BNC:
443 case MEDIA_HMR:
444 {
446
447 if (!(Adapter->ModeFlags & DC_MODE_TEST_PACKET))
448 {
449 if ((Adapter->MediaNumber == MEDIA_AUI || Adapter->MediaNumber == MEDIA_HMR) &&
451 {
452 /* Clear the AUI/HMR port activity bit */
454
455 MediaIndicateConnect(Adapter, TRUE);
456
457 DelayMs = 5000;
458 }
459 /* Check for any received packets */
460 else if (ReceiveActivity != Adapter->LastReceiveActivity)
461 {
462 MediaIndicateConnect(Adapter, TRUE);
463
464 DelayMs = 3000;
465 }
466 else
467 {
468 /* Send a loopback packet */
470 DcTestPacket(Adapter);
472
473 DelayMs = 3000;
474 }
475 }
476 else
477 {
478 Adapter->ModeFlags &= ~DC_MODE_TEST_PACKET;
479
480 LinkUp = !!Adapter->MediaTestStatus;
481
483
484 /* Select the other port */
485 if (!LinkUp && !MEDIA_IS_FIXED(Adapter))
486 {
488
489 DelayMs = 3000;
490 }
491 else
492 {
493 DelayMs = 5000;
494 }
495 }
497
498 NdisMSetTimer(&Adapter->MediaMonitorTimer, DelayMs);
499 break;
500 }
501
502 default:
503 {
504 MediaMonitor143(Adapter);
505 break;
506 }
507 }
508
510}
unsigned char BOOLEAN
#define DC_MODE_AUTONEG_WAIT_INTERRUPT
Definition: dc21x4.h:170
VOID MediaSelectMiiPort(_In_ PDC21X4_ADAPTER Adapter, _In_ BOOLEAN ResetPhy)
Definition: media.c:215
MEDIA_HANDLE_LINK_STATE_CHANGE MediaLinkStateChange21143
Definition: dc21x4.h:504
VOID MediaMiiSelect(_In_ PDC21X4_ADAPTER Adapter)
Definition: media.c:197
#define DC_ACTIVE
Definition: dc21x4.h:120
FORCEINLINE ULONG DC_READ(_In_ PDC21X4_ADAPTER Adapter, _In_ DC_CSR Register)
Definition: dc21x4.h:262
#define DC_MODE_AUI_FAILED
Definition: dc21x4.h:166
VOID DcStopTxRxProcess(_In_ PDC21X4_ADAPTER Adapter)
Definition: hardware.c:38
NDIS_TIMER_FUNCTION MediaMonitor21143Dpc
Definition: dc21x4.h:500
#define DC_HAS_MII
Definition: dc21x4.h:113
#define DC_MODE_AUTONEG_LINK_STATUS_CHECK
Definition: dc21x4.h:171
#define DC_MODE_BNC_FAILED
Definition: dc21x4.h:167
VOID MediaIndicateConnect(_In_ PDC21X4_ADAPTER Adapter, _In_ BOOLEAN LinkUp)
Definition: media.c:17
#define DC_MODE_TEST_PACKET
Definition: dc21x4.h:165
BOOLEAN MediaMiiCheckLink(_In_ PDC21X4_ADAPTER Adapter)
Definition: media.c:141
#define DC_WRITE(Adapter, Register, Value)
Definition: dc21x4.h:272
VOID DcTestPacket(_In_ PDC21X4_ADAPTER Adapter)
Definition: hardware.c:135
VOID MediaSiaSelect(_In_ PDC21X4_ADAPTER Adapter)
Definition: media.c:268
#define DC_MODE_AUTONEG_MASK
Definition: dc21x4.h:163
#define DC_MODE_AUTONEG_NONE
Definition: dc21x4.h:169
#define DC_IRQ_LINK_CHANGED
Definition: dc21x4hw.h:290
#define MII_ADV_10T_FD
Definition: dc21x4hw.h:574
#define DC_SIA_STATUS_ANS_AUTONEG_COMPLETE
Definition: dc21x4hw.h:439
#define DC_SIA_STATUS_ANS_MASK
Definition: dc21x4hw.h:430
#define MII_ADV_100T4
Definition: dc21x4hw.h:577
#define DC_SIA_STATUS_LP_CODE_WORD_SHIFT
Definition: dc21x4hw.h:442
#define DC_SIA_STATUS_LP_AUTONED_SUPPORTED
Definition: dc21x4hw.h:431
@ DcCsr14_SiaTxRx
Definition: dc21x4hw.h:190
@ DcCsr12_SiaStatus
Definition: dc21x4hw.h:188
#define DC_SIA_STATUS_100T_LINK_FAIL
Definition: dc21x4hw.h:421
#define DC_SIA_STATUS_10T_LINK_FAIL
Definition: dc21x4hw.h:422
#define DC_SIA_TXRX_AUTONEG
Definition: dc21x4hw.h:461
#define DC_IRQ_LINK_PASS
Definition: dc21x4hw.h:271
#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 DC_SIA_STATUS_AUI_ACTIVITY
Definition: dc21x4hw.h:424
#define DC_IRQ_LINK_FAIL
Definition: dc21x4hw.h:281
#define TRUE
Definition: types.h:120
#define FALSE
Definition: types.h:117
#define INFO_VERB
Definition: debug.h:90
VOID EXPORT NdisMSetTimer(IN PNDIS_MINIPORT_TIMER Timer, IN UINT MillisecondsToDelay)
Definition: time.c:272
if(dx< 0)
Definition: linetemp.h:194
static VOID Media143Handle10LinkFail(_In_ PDC21X4_ADAPTER Adapter, _In_ ULONG SiaStatus)
Definition: media143.c:120
static VOID MediaMonitor143(_In_ PDC21X4_ADAPTER Adapter)
Definition: media143.c:360
static BOOLEAN Media143CheckLink(_In_ PDC21X4_ADAPTER Adapter, _In_ ULONG SiaStatus)
Definition: media143.c:336
static VOID Media143Handle10LinkPass(_In_ PDC21X4_ADAPTER Adapter, _In_ ULONG SiaStatus)
Definition: media143.c:138
static VOID Media143Handle100LinkChange(_In_ PDC21X4_ADAPTER Adapter, _In_ ULONG SiaStatus)
Definition: media143.c:168
static VOID Media143SelectNextMedia(_In_ PDC21X4_ADAPTER Adapter, _In_ ULONG SiaStatus)
Definition: media143.c:64
static VOID Media143HandleNWayComplete(_In_ PDC21X4_ADAPTER Adapter, _In_ ULONG SiaStatus)
Definition: media143.c:198
static VOID Media143SelectNextSerialMedia(_In_ PDC21X4_ADAPTER Adapter)
Definition: media143.c:18
#define MEDIA_AUI_BNC_MASK
Definition: media.h:82
#define MEDIA_AUI
Definition: media.h:48
#define MEDIA_MII
Definition: media.h:67
#define MEDIA_100TX_FD
Definition: media.h:52
#define MEDIA_IS_FIXED(Adapter)
Definition: media.h:126
#define MEDIA_IS_10T(MediaNumber)
Definition: media.h:114
#define MEDIA_IS_100(MediaNumber)
Definition: media.h:118
#define MEDIA_10T_FD
Definition: media.h:51
#define MEDIA_10T
Definition: media.h:46
#define MEDIA_HMR
Definition: media.h:56
#define MEDIA_100T4
Definition: media.h:53
#define MEDIA_BNC
Definition: media.h:47
#define MEDIA_100TX_HD
Definition: media.h:49
#define ASSERT(a)
Definition: mode.c:44
#define _In_
Definition: ms_sal.h:308
_In_ PVOID _In_ PVOID SystemSpecific2
Definition: ndis.h:638
#define NdisDprReleaseSpinLock(_SpinLock)
Definition: ndis.h:4133
_In_ PVOID FunctionContext
Definition: ndis.h:637
#define NdisDprAcquireSpinLock(_SpinLock)
Definition: ndis.h:4124
_In_ PVOID _In_ PVOID _In_ PVOID SystemSpecific3
Definition: ndis.h:639
static NTSTATUS ReceiveActivity(PAFD_FCB FCB, PIRP Irp)
Definition: read.c:151
#define UNREACHABLE
#define UNREFERENCED_PARAMETER(P)
Definition: ntbasedef.h:317
@ LinkUp
Definition: srb.h:741
volatile LONG MediaTestStatus
Definition: dc21x4.h:180
ULONG ModeFlags
Definition: dc21x4.h:162
DECLSPEC_CACHEALIGN NDIS_SPIN_LOCK ModeLock
Definition: dc21x4.h:161
ULONG LastReceiveActivity
Definition: dc21x4.h:179
ULONG MediaNumber
Definition: dc21x4.h:174
NDIS_MINIPORT_TIMER MediaMonitorTimer
Definition: dc21x4.h:181
DECLSPEC_CACHEALIGN NDIS_SPIN_LOCK SendLock
Definition: dc21x4.h:129
DC_STATISTICS Statistics
Definition: dc21x4.h:156
ULONG Flags
Definition: dc21x4.h:119
ULONG64 ReceiveOk
Definition: dc21x4.h:90
#define NTAPI
Definition: typedefs.h:36
uint32_t ULONG
Definition: typedefs.h:59