-
Notifications
You must be signed in to change notification settings - Fork 7
/
link.cpp
157 lines (124 loc) · 4.34 KB
/
link.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
#include "precomp.h"
#include "trace.h"
#include "adapter.h"
#include "link.h"
#include "interrupt.h"
#define MBit 1000000ULL
static void RtlResetLink(_In_ RT_ADAPTER* adapter) {
re_softc* sc = &adapter->bsdData;
WdfInterruptAcquireLock(adapter->Interrupt->Handle);
re_stop(sc);
RtResetQueues(adapter);
// Init our MAC address
re_rar_set(sc, adapter->CurrentAddress.Address);
if (adapter->isRTL8125)
re_hw_start_unlock_8125(sc);
else
re_hw_start_unlock(sc);
WdfInterruptReleaseLock(adapter->Interrupt->Handle);
}
void RtlFirstStart(_In_ RT_ADAPTER* adapter) {
if (adapter->RxQueues[0] == NULL || adapter->TxQueues[0] == NULL) {
return;
}
RtlResetLink(adapter);
re_softc* sc = &adapter->bsdData;
if (adapter->isRTL8125) {
re_ifmedia_upd_8125(sc);
}
else {
re_ifmedia_upd(sc);
}
}
void RtlLinkUp(_In_ RT_ADAPTER* adapter) {
TraceEntryNetAdapter(adapter);
re_softc* sc = &adapter->bsdData;
re_link_on_patch(sc);
RtlResetLink(adapter);
TraceExit();
}
void RtlLinkDown(_In_ RT_ADAPTER* adapter) {
TraceEntryNetAdapter(adapter);
RtlResetLink(adapter);
TraceExit();
}
void RtlCheckLinkStatus(_In_ RT_ADAPTER* adapter) {
TraceEntryNetAdapter(adapter);
re_softc* sc = &adapter->bsdData;
if (re_link_ok(sc)) {
RtlLinkUp(adapter);
// Check Autonegotiation
BOOLEAN LinkAutoNeg = re_link_autoneg(sc);
UINT32 msr = 0;
if (adapter->isRTL8125)
msr = CSR_READ_4(sc, RE_PHY_STATUS);
else
msr = CSR_READ_1(sc, RE_PHY_STATUS);
NET_IF_MEDIA_DUPLEX_STATE duplexState = (msr & RL_PHY_STATUS_FULL_DUP) ? MediaDuplexStateFull : MediaDuplexStateHalf;
ULONG64 linkSpeed = NDIS_LINK_SPEED_UNKNOWN;
if (msr & RL_PHY_STATUS_10M)
linkSpeed = 10 * MBit;
else if (msr & RL_PHY_STATUS_100M)
linkSpeed = 100 * MBit;
else if (msr & RL_PHY_STATUS_1000MF)
linkSpeed = 1000 * MBit;
else if (msr & RL_PHY_STATUS_500MF)
linkSpeed = 1000 * MBit;
else if (msr & RL_PHY_STATUS_1250MF)
linkSpeed = 1000 * MBit;
else if (msr & RL_PHY_STATUS_2500MF)
linkSpeed = 2500 * MBit;
else if (msr & RL_PHY_STATUS_5000MF_LITE)
linkSpeed = 2500 * MBit;
else if (msr & RL_PHY_STATUS_5000MF)
linkSpeed = 5000 * MBit;
NET_ADAPTER_AUTO_NEGOTIATION_FLAGS autoNegotiationFlags = NetAdapterAutoNegotiationFlagNone;
if (LinkAutoNeg) {
autoNegotiationFlags |=
NetAdapterAutoNegotiationFlagXmitLinkSpeedAutoNegotiated |
NetAdapterAutoNegotiationFlagRcvLinkSpeedautoNegotiated |
NetAdapterAutoNegotiationFlagDuplexAutoNegotiated;
}
if (adapter->FlowControl != NoFlowControl) {
autoNegotiationFlags |=
NetAdapterAutoNegotiationFlagPauseFunctionsAutoNegotiated;
}
NET_ADAPTER_PAUSE_FUNCTION_TYPE pauseFunctions = NetAdapterPauseFunctionTypeUnknown;
switch (adapter->FlowControl) {
case NoFlowControl:
pauseFunctions = NetAdapterPauseFunctionTypeUnsupported;
break;
case FlowControlRxOnly:
pauseFunctions = NetAdapterPauseFunctionTypeReceiveOnly;
break;
case FlowControlTxOnly:
pauseFunctions = NetAdapterPauseFunctionTypeSendOnly;
break;
case FlowControlTxRx:
pauseFunctions = NetAdapterPauseFunctionTypeSendAndReceive;
break;
}
NET_ADAPTER_LINK_STATE linkState;
NET_ADAPTER_LINK_STATE_INIT(
&linkState,
linkSpeed,
MediaConnectStateConnected,
duplexState,
pauseFunctions,
autoNegotiationFlags);
NetAdapterSetLinkState(adapter->NetAdapter, &linkState);
}
else {
RtlLinkDown(adapter);
NET_ADAPTER_LINK_STATE linkState;
NET_ADAPTER_LINK_STATE_INIT(
&linkState,
NDIS_LINK_SPEED_UNKNOWN,
MediaConnectStateDisconnected,
MediaDuplexStateUnknown,
NetAdapterPauseFunctionTypeUnknown,
NetAdapterAutoNegotiationFlagNone);
NetAdapterSetLinkState(adapter->NetAdapter, &linkState);
}
TraceExit();
}