xref: /reactos/drivers/network/dd/dc21x4/requests.c (revision 59d8a77d)
1*59d8a77dSDmitry Borisov /*
2*59d8a77dSDmitry Borisov  * PROJECT:     ReactOS DC21x4 Driver
3*59d8a77dSDmitry Borisov  * LICENSE:     GPL-2.0-or-later (https://spdx.org/licenses/GPL-2.0-or-later)
4*59d8a77dSDmitry Borisov  * PURPOSE:     Miniport information callbacks
5*59d8a77dSDmitry Borisov  * COPYRIGHT:   Copyright 2023 Dmitry Borisov <di.sean@protonmail.com>
6*59d8a77dSDmitry Borisov  */
7*59d8a77dSDmitry Borisov 
8*59d8a77dSDmitry Borisov /* INCLUDES *******************************************************************/
9*59d8a77dSDmitry Borisov 
10*59d8a77dSDmitry Borisov #include "dc21x4.h"
11*59d8a77dSDmitry Borisov 
12*59d8a77dSDmitry Borisov #include <debug.h>
13*59d8a77dSDmitry Borisov 
14*59d8a77dSDmitry Borisov /* GLOBALS ********************************************************************/
15*59d8a77dSDmitry Borisov 
16*59d8a77dSDmitry Borisov static const NDIS_OID DcpSupportedOidList[] =
17*59d8a77dSDmitry Borisov {
18*59d8a77dSDmitry Borisov     OID_GEN_SUPPORTED_LIST,
19*59d8a77dSDmitry Borisov     OID_GEN_CURRENT_PACKET_FILTER,
20*59d8a77dSDmitry Borisov     OID_GEN_HARDWARE_STATUS,
21*59d8a77dSDmitry Borisov     OID_GEN_MEDIA_SUPPORTED,
22*59d8a77dSDmitry Borisov     OID_GEN_MEDIA_IN_USE,
23*59d8a77dSDmitry Borisov     OID_GEN_MAXIMUM_LOOKAHEAD,
24*59d8a77dSDmitry Borisov     OID_GEN_MAXIMUM_FRAME_SIZE,
25*59d8a77dSDmitry Borisov     OID_GEN_MAXIMUM_SEND_PACKETS,
26*59d8a77dSDmitry Borisov     OID_GEN_LINK_SPEED,
27*59d8a77dSDmitry Borisov     OID_GEN_TRANSMIT_BUFFER_SPACE,
28*59d8a77dSDmitry Borisov     OID_GEN_RECEIVE_BUFFER_SPACE,
29*59d8a77dSDmitry Borisov     OID_GEN_RECEIVE_BLOCK_SIZE,
30*59d8a77dSDmitry Borisov     OID_GEN_TRANSMIT_BLOCK_SIZE,
31*59d8a77dSDmitry Borisov     OID_GEN_VENDOR_ID,
32*59d8a77dSDmitry Borisov     OID_GEN_VENDOR_DESCRIPTION,
33*59d8a77dSDmitry Borisov     OID_GEN_VENDOR_DRIVER_VERSION,
34*59d8a77dSDmitry Borisov     OID_GEN_CURRENT_LOOKAHEAD,
35*59d8a77dSDmitry Borisov     OID_GEN_DRIVER_VERSION,
36*59d8a77dSDmitry Borisov     OID_GEN_MAXIMUM_TOTAL_SIZE,
37*59d8a77dSDmitry Borisov     OID_GEN_MAC_OPTIONS,
38*59d8a77dSDmitry Borisov     OID_GEN_MEDIA_CONNECT_STATUS,
39*59d8a77dSDmitry Borisov     OID_802_3_PERMANENT_ADDRESS,
40*59d8a77dSDmitry Borisov     OID_802_3_CURRENT_ADDRESS,
41*59d8a77dSDmitry Borisov     OID_802_3_MULTICAST_LIST,
42*59d8a77dSDmitry Borisov     OID_802_3_MAXIMUM_LIST_SIZE,
43*59d8a77dSDmitry Borisov 
44*59d8a77dSDmitry Borisov     /* Statistics */
45*59d8a77dSDmitry Borisov     OID_GEN_XMIT_OK,
46*59d8a77dSDmitry Borisov     OID_GEN_RCV_OK,
47*59d8a77dSDmitry Borisov     OID_GEN_XMIT_ERROR,
48*59d8a77dSDmitry Borisov     OID_GEN_RCV_ERROR,
49*59d8a77dSDmitry Borisov     OID_GEN_RCV_NO_BUFFER,
50*59d8a77dSDmitry Borisov     OID_GEN_DIRECTED_FRAMES_RCV,
51*59d8a77dSDmitry Borisov     OID_GEN_MULTICAST_FRAMES_RCV,
52*59d8a77dSDmitry Borisov     OID_GEN_BROADCAST_FRAMES_RCV,
53*59d8a77dSDmitry Borisov     OID_GEN_RCV_CRC_ERROR,
54*59d8a77dSDmitry Borisov     OID_GEN_TRANSMIT_QUEUE_LENGTH,
55*59d8a77dSDmitry Borisov     OID_802_3_RCV_ERROR_ALIGNMENT,
56*59d8a77dSDmitry Borisov     OID_802_3_XMIT_ONE_COLLISION,
57*59d8a77dSDmitry Borisov     OID_802_3_XMIT_MORE_COLLISIONS,
58*59d8a77dSDmitry Borisov     OID_802_3_XMIT_DEFERRED,
59*59d8a77dSDmitry Borisov     OID_802_3_XMIT_MAX_COLLISIONS,
60*59d8a77dSDmitry Borisov     OID_802_3_RCV_OVERRUN,
61*59d8a77dSDmitry Borisov     OID_802_3_XMIT_UNDERRUN,
62*59d8a77dSDmitry Borisov     OID_802_3_XMIT_HEARTBEAT_FAILURE,
63*59d8a77dSDmitry Borisov     OID_802_3_XMIT_TIMES_CRS_LOST,
64*59d8a77dSDmitry Borisov     OID_802_3_XMIT_LATE_COLLISIONS,
65*59d8a77dSDmitry Borisov 
66*59d8a77dSDmitry Borisov     /* Power management */
67*59d8a77dSDmitry Borisov     OID_PNP_CAPABILITIES,
68*59d8a77dSDmitry Borisov     OID_PNP_SET_POWER,
69*59d8a77dSDmitry Borisov     OID_PNP_QUERY_POWER,
70*59d8a77dSDmitry Borisov     OID_PNP_ADD_WAKE_UP_PATTERN,
71*59d8a77dSDmitry Borisov     OID_PNP_REMOVE_WAKE_UP_PATTERN,
72*59d8a77dSDmitry Borisov     OID_PNP_ENABLE_WAKE_UP
73*59d8a77dSDmitry Borisov };
74*59d8a77dSDmitry Borisov 
75*59d8a77dSDmitry Borisov /* FUNCTIONS ******************************************************************/
76*59d8a77dSDmitry Borisov 
77*59d8a77dSDmitry Borisov static
78*59d8a77dSDmitry Borisov VOID
DcQueryStatisticCounter(_In_ PDC21X4_ADAPTER Adapter,_In_ NDIS_OID Oid,_Out_ PULONG64 Counter)79*59d8a77dSDmitry Borisov DcQueryStatisticCounter(
80*59d8a77dSDmitry Borisov     _In_ PDC21X4_ADAPTER Adapter,
81*59d8a77dSDmitry Borisov     _In_ NDIS_OID Oid,
82*59d8a77dSDmitry Borisov     _Out_ PULONG64 Counter)
83*59d8a77dSDmitry Borisov {
84*59d8a77dSDmitry Borisov     /* When there is no workaround, this function is used to read the hardware RX counters */
85*59d8a77dSDmitry Borisov     if (!(Adapter->Features & DC_NEED_RX_OVERFLOW_WORKAROUND))
86*59d8a77dSDmitry Borisov     {
87*59d8a77dSDmitry Borisov         ULONG RxCounters;
88*59d8a77dSDmitry Borisov 
89*59d8a77dSDmitry Borisov         /*
90*59d8a77dSDmitry Borisov          * Read the RX missed frame counter. Note that the RX overflow counter is not supported
91*59d8a77dSDmitry Borisov          * on older chips without the workaround enabled and reads will return 0xFFFE****.
92*59d8a77dSDmitry Borisov          */
93*59d8a77dSDmitry Borisov         RxCounters = DC_READ(Adapter, DcCsr8_RxCounters);
94*59d8a77dSDmitry Borisov 
95*59d8a77dSDmitry Borisov         Adapter->Statistics.ReceiveNoBuffers += RxCounters & DC_COUNTER_RX_NO_BUFFER_MASK;
96*59d8a77dSDmitry Borisov     }
97*59d8a77dSDmitry Borisov 
98*59d8a77dSDmitry Borisov     switch (Oid)
99*59d8a77dSDmitry Borisov     {
100*59d8a77dSDmitry Borisov         case OID_GEN_XMIT_OK:
101*59d8a77dSDmitry Borisov             *Counter = Adapter->Statistics.TransmitOk;
102*59d8a77dSDmitry Borisov             break;
103*59d8a77dSDmitry Borisov         case OID_GEN_RCV_OK:
104*59d8a77dSDmitry Borisov             *Counter = Adapter->Statistics.ReceiveOk;
105*59d8a77dSDmitry Borisov             break;
106*59d8a77dSDmitry Borisov         case OID_GEN_XMIT_ERROR:
107*59d8a77dSDmitry Borisov             *Counter = Adapter->Statistics.TransmitErrors;
108*59d8a77dSDmitry Borisov             break;
109*59d8a77dSDmitry Borisov         case OID_GEN_RCV_ERROR:
110*59d8a77dSDmitry Borisov             *Counter = Adapter->Statistics.ReceiveErrors;
111*59d8a77dSDmitry Borisov             break;
112*59d8a77dSDmitry Borisov         case OID_GEN_RCV_NO_BUFFER:
113*59d8a77dSDmitry Borisov             *Counter = Adapter->Statistics.ReceiveNoBuffers;
114*59d8a77dSDmitry Borisov             break;
115*59d8a77dSDmitry Borisov         case OID_GEN_DIRECTED_FRAMES_RCV:
116*59d8a77dSDmitry Borisov             *Counter = Adapter->Statistics.ReceiveUnicast;
117*59d8a77dSDmitry Borisov             break;
118*59d8a77dSDmitry Borisov         case OID_GEN_MULTICAST_FRAMES_RCV:
119*59d8a77dSDmitry Borisov             *Counter = Adapter->Statistics.ReceiveMulticast;
120*59d8a77dSDmitry Borisov             break;
121*59d8a77dSDmitry Borisov         case OID_GEN_BROADCAST_FRAMES_RCV:
122*59d8a77dSDmitry Borisov             *Counter = Adapter->Statistics.ReceiveBroadcast;
123*59d8a77dSDmitry Borisov             break;
124*59d8a77dSDmitry Borisov         case OID_GEN_RCV_CRC_ERROR:
125*59d8a77dSDmitry Borisov             *Counter = Adapter->Statistics.ReceiveCrcErrors;
126*59d8a77dSDmitry Borisov             break;
127*59d8a77dSDmitry Borisov         case OID_802_3_RCV_ERROR_ALIGNMENT:
128*59d8a77dSDmitry Borisov             *Counter = Adapter->Statistics.ReceiveAlignmentErrors;
129*59d8a77dSDmitry Borisov             break;
130*59d8a77dSDmitry Borisov         case OID_802_3_XMIT_ONE_COLLISION:
131*59d8a77dSDmitry Borisov             *Counter = Adapter->Statistics.TransmitOneRetry;
132*59d8a77dSDmitry Borisov             break;
133*59d8a77dSDmitry Borisov         case OID_802_3_XMIT_MORE_COLLISIONS:
134*59d8a77dSDmitry Borisov             *Counter = Adapter->Statistics.TransmitMoreCollisions;
135*59d8a77dSDmitry Borisov             break;
136*59d8a77dSDmitry Borisov         case OID_802_3_XMIT_DEFERRED:
137*59d8a77dSDmitry Borisov             *Counter = Adapter->Statistics.TransmitDeferred;
138*59d8a77dSDmitry Borisov             break;
139*59d8a77dSDmitry Borisov         case OID_802_3_XMIT_MAX_COLLISIONS:
140*59d8a77dSDmitry Borisov             *Counter = Adapter->Statistics.TransmitExcessiveCollisions;
141*59d8a77dSDmitry Borisov             break;
142*59d8a77dSDmitry Borisov         case OID_802_3_RCV_OVERRUN:
143*59d8a77dSDmitry Borisov             *Counter = Adapter->Statistics.ReceiveOverrunErrors;
144*59d8a77dSDmitry Borisov             break;
145*59d8a77dSDmitry Borisov         case OID_802_3_XMIT_UNDERRUN:
146*59d8a77dSDmitry Borisov             *Counter = Adapter->Statistics.TransmitUnderrunErrors;
147*59d8a77dSDmitry Borisov             break;
148*59d8a77dSDmitry Borisov         case OID_802_3_XMIT_HEARTBEAT_FAILURE:
149*59d8a77dSDmitry Borisov             *Counter = Adapter->Statistics.TransmitHeartbeatErrors;
150*59d8a77dSDmitry Borisov             break;
151*59d8a77dSDmitry Borisov         case OID_802_3_XMIT_TIMES_CRS_LOST:
152*59d8a77dSDmitry Borisov             *Counter = Adapter->Statistics.TransmitLostCarrierSense;
153*59d8a77dSDmitry Borisov             break;
154*59d8a77dSDmitry Borisov         case OID_802_3_XMIT_LATE_COLLISIONS:
155*59d8a77dSDmitry Borisov             *Counter = Adapter->Statistics.TransmitLateCollisions;
156*59d8a77dSDmitry Borisov             break;
157*59d8a77dSDmitry Borisov 
158*59d8a77dSDmitry Borisov         default:
159*59d8a77dSDmitry Borisov             ASSERT(FALSE);
160*59d8a77dSDmitry Borisov             UNREACHABLE;
161*59d8a77dSDmitry Borisov             break;
162*59d8a77dSDmitry Borisov     }
163*59d8a77dSDmitry Borisov }
164*59d8a77dSDmitry Borisov 
165*59d8a77dSDmitry Borisov static
166*59d8a77dSDmitry Borisov ULONG
DcGetLinkSpeed(_In_ PDC21X4_ADAPTER Adapter)167*59d8a77dSDmitry Borisov DcGetLinkSpeed(
168*59d8a77dSDmitry Borisov     _In_ PDC21X4_ADAPTER Adapter)
169*59d8a77dSDmitry Borisov {
170*59d8a77dSDmitry Borisov     ULONG LinkSpeedMbps;
171*59d8a77dSDmitry Borisov 
172*59d8a77dSDmitry Borisov     switch (Adapter->MediaNumber)
173*59d8a77dSDmitry Borisov     {
174*59d8a77dSDmitry Borisov         case MEDIA_HMR:
175*59d8a77dSDmitry Borisov             LinkSpeedMbps = 1;
176*59d8a77dSDmitry Borisov             break;
177*59d8a77dSDmitry Borisov 
178*59d8a77dSDmitry Borisov         case MEDIA_10T:
179*59d8a77dSDmitry Borisov         case MEDIA_BNC:
180*59d8a77dSDmitry Borisov         case MEDIA_AUI:
181*59d8a77dSDmitry Borisov         case MEDIA_10T_FD:
182*59d8a77dSDmitry Borisov             LinkSpeedMbps = 10;
183*59d8a77dSDmitry Borisov             break;
184*59d8a77dSDmitry Borisov 
185*59d8a77dSDmitry Borisov         case MEDIA_100TX_HD:
186*59d8a77dSDmitry Borisov         case MEDIA_100TX_FD:
187*59d8a77dSDmitry Borisov         case MEDIA_100T4:
188*59d8a77dSDmitry Borisov         case MEDIA_100FX_HD:
189*59d8a77dSDmitry Borisov         case MEDIA_100FX_FD:
190*59d8a77dSDmitry Borisov             LinkSpeedMbps = 100;
191*59d8a77dSDmitry Borisov             break;
192*59d8a77dSDmitry Borisov 
193*59d8a77dSDmitry Borisov         case MEDIA_MII:
194*59d8a77dSDmitry Borisov             LinkSpeedMbps = Adapter->LinkSpeedMbps;
195*59d8a77dSDmitry Borisov             break;
196*59d8a77dSDmitry Borisov 
197*59d8a77dSDmitry Borisov         default:
198*59d8a77dSDmitry Borisov             ASSERT(FALSE);
199*59d8a77dSDmitry Borisov             UNREACHABLE;
200*59d8a77dSDmitry Borisov             break;
201*59d8a77dSDmitry Borisov     }
202*59d8a77dSDmitry Borisov 
203*59d8a77dSDmitry Borisov     return LinkSpeedMbps;
204*59d8a77dSDmitry Borisov }
205*59d8a77dSDmitry Borisov 
206*59d8a77dSDmitry Borisov NDIS_STATUS
207*59d8a77dSDmitry Borisov NTAPI
DcQueryInformation(_In_ NDIS_HANDLE MiniportAdapterContext,_In_ NDIS_OID Oid,_In_ PVOID InformationBuffer,_In_ ULONG InformationBufferLength,_Out_ PULONG BytesWritten,_Out_ PULONG BytesNeeded)208*59d8a77dSDmitry Borisov DcQueryInformation(
209*59d8a77dSDmitry Borisov     _In_ NDIS_HANDLE MiniportAdapterContext,
210*59d8a77dSDmitry Borisov     _In_ NDIS_OID Oid,
211*59d8a77dSDmitry Borisov     _In_ PVOID InformationBuffer,
212*59d8a77dSDmitry Borisov     _In_ ULONG InformationBufferLength,
213*59d8a77dSDmitry Borisov     _Out_ PULONG BytesWritten,
214*59d8a77dSDmitry Borisov     _Out_ PULONG BytesNeeded)
215*59d8a77dSDmitry Borisov {
216*59d8a77dSDmitry Borisov     PDC21X4_ADAPTER Adapter = (PDC21X4_ADAPTER)MiniportAdapterContext;
217*59d8a77dSDmitry Borisov     NDIS_STATUS Status = NDIS_STATUS_SUCCESS;
218*59d8a77dSDmitry Borisov     ULONG InfoLength;
219*59d8a77dSDmitry Borisov     PVOID InfoPtr;
220*59d8a77dSDmitry Borisov     union _GENERIC_INFORMATION
221*59d8a77dSDmitry Borisov     {
222*59d8a77dSDmitry Borisov         USHORT Ushort;
223*59d8a77dSDmitry Borisov         ULONG Ulong;
224*59d8a77dSDmitry Borisov         ULONG64 Ulong64;
225*59d8a77dSDmitry Borisov         NDIS_MEDIUM Medium;
226*59d8a77dSDmitry Borisov         NDIS_HARDWARE_STATUS Status;
227*59d8a77dSDmitry Borisov         NDIS_DEVICE_POWER_STATE PowerState;
228*59d8a77dSDmitry Borisov     } GenericInfo;
229*59d8a77dSDmitry Borisov 
230*59d8a77dSDmitry Borisov     InfoLength = sizeof(ULONG);
231*59d8a77dSDmitry Borisov     InfoPtr = &GenericInfo;
232*59d8a77dSDmitry Borisov 
233*59d8a77dSDmitry Borisov     switch (Oid)
234*59d8a77dSDmitry Borisov     {
235*59d8a77dSDmitry Borisov         case OID_GEN_SUPPORTED_LIST:
236*59d8a77dSDmitry Borisov             InfoPtr = (PVOID)&DcpSupportedOidList;
237*59d8a77dSDmitry Borisov             InfoLength = sizeof(DcpSupportedOidList);
238*59d8a77dSDmitry Borisov             break;
239*59d8a77dSDmitry Borisov 
240*59d8a77dSDmitry Borisov         case OID_GEN_CURRENT_PACKET_FILTER:
241*59d8a77dSDmitry Borisov             GenericInfo.Ulong = Adapter->PacketFilter;
242*59d8a77dSDmitry Borisov             break;
243*59d8a77dSDmitry Borisov 
244*59d8a77dSDmitry Borisov         case OID_802_3_MULTICAST_LIST:
245*59d8a77dSDmitry Borisov             InfoPtr = Adapter->MulticastList;
246*59d8a77dSDmitry Borisov             InfoLength = Adapter->MulticastCount * ETH_LENGTH_OF_ADDRESS;
247*59d8a77dSDmitry Borisov             break;
248*59d8a77dSDmitry Borisov 
249*59d8a77dSDmitry Borisov         case OID_802_3_MAXIMUM_LIST_SIZE:
250*59d8a77dSDmitry Borisov             GenericInfo.Ulong = Adapter->MulticastMaxEntries;
251*59d8a77dSDmitry Borisov             break;
252*59d8a77dSDmitry Borisov 
253*59d8a77dSDmitry Borisov         case OID_GEN_MEDIA_SUPPORTED:
254*59d8a77dSDmitry Borisov         case OID_GEN_MEDIA_IN_USE:
255*59d8a77dSDmitry Borisov         {
256*59d8a77dSDmitry Borisov             GenericInfo.Medium = NdisMedium802_3;
257*59d8a77dSDmitry Borisov             InfoLength = sizeof(NDIS_MEDIUM);
258*59d8a77dSDmitry Borisov             break;
259*59d8a77dSDmitry Borisov         }
260*59d8a77dSDmitry Borisov 
261*59d8a77dSDmitry Borisov         case OID_GEN_HARDWARE_STATUS:
262*59d8a77dSDmitry Borisov         {
263*59d8a77dSDmitry Borisov             ULONG InterruptStatus;
264*59d8a77dSDmitry Borisov 
265*59d8a77dSDmitry Borisov             /* NOTE: Reading the status register has no effect on the events */
266*59d8a77dSDmitry Borisov             InterruptStatus = DC_READ(Adapter, DcCsr5_Status);
267*59d8a77dSDmitry Borisov 
268*59d8a77dSDmitry Borisov             /* Inserted into the motherboard */
269*59d8a77dSDmitry Borisov             if (InterruptStatus != 0xFFFFFFFF)
270*59d8a77dSDmitry Borisov                 GenericInfo.Status = NdisHardwareStatusReady;
271*59d8a77dSDmitry Borisov             else
272*59d8a77dSDmitry Borisov                 GenericInfo.Status = NdisHardwareStatusNotReady;
273*59d8a77dSDmitry Borisov 
274*59d8a77dSDmitry Borisov             InfoLength = sizeof(NDIS_HARDWARE_STATUS);
275*59d8a77dSDmitry Borisov             break;
276*59d8a77dSDmitry Borisov         }
277*59d8a77dSDmitry Borisov 
278*59d8a77dSDmitry Borisov         case OID_GEN_MAXIMUM_FRAME_SIZE:
279*59d8a77dSDmitry Borisov         case OID_GEN_MAXIMUM_LOOKAHEAD:
280*59d8a77dSDmitry Borisov         case OID_GEN_CURRENT_LOOKAHEAD:
281*59d8a77dSDmitry Borisov             GenericInfo.Ulong = DC_MAXIMUM_FRAME_SIZE - DC_ETHERNET_HEADER_SIZE;
282*59d8a77dSDmitry Borisov             break;
283*59d8a77dSDmitry Borisov 
284*59d8a77dSDmitry Borisov         case OID_GEN_MAXIMUM_TOTAL_SIZE:
285*59d8a77dSDmitry Borisov             GenericInfo.Ulong = DC_MAXIMUM_FRAME_SIZE;
286*59d8a77dSDmitry Borisov             break;
287*59d8a77dSDmitry Borisov 
288*59d8a77dSDmitry Borisov         case OID_GEN_TRANSMIT_BLOCK_SIZE:
289*59d8a77dSDmitry Borisov             GenericInfo.Ulong = DC_TRANSMIT_BLOCK_SIZE;
290*59d8a77dSDmitry Borisov             break;
291*59d8a77dSDmitry Borisov 
292*59d8a77dSDmitry Borisov         case OID_GEN_TRANSMIT_BUFFER_SPACE:
293*59d8a77dSDmitry Borisov             GenericInfo.Ulong = DC_TRANSMIT_BLOCK_SIZE * DC_TRANSMIT_BLOCKS;
294*59d8a77dSDmitry Borisov             break;
295*59d8a77dSDmitry Borisov 
296*59d8a77dSDmitry Borisov         case OID_GEN_RECEIVE_BLOCK_SIZE:
297*59d8a77dSDmitry Borisov             GenericInfo.Ulong = DC_RECEIVE_BLOCK_SIZE;
298*59d8a77dSDmitry Borisov             break;
299*59d8a77dSDmitry Borisov 
300*59d8a77dSDmitry Borisov         case OID_GEN_RECEIVE_BUFFER_SPACE:
301*59d8a77dSDmitry Borisov             GenericInfo.Ulong = DC_RECEIVE_BLOCK_SIZE * Adapter->RcbCount;
302*59d8a77dSDmitry Borisov             break;
303*59d8a77dSDmitry Borisov 
304*59d8a77dSDmitry Borisov         case OID_GEN_LINK_SPEED:
305*59d8a77dSDmitry Borisov             GenericInfo.Ulong = DcGetLinkSpeed(Adapter) * 10000;
306*59d8a77dSDmitry Borisov             break;
307*59d8a77dSDmitry Borisov 
308*59d8a77dSDmitry Borisov         case OID_GEN_VENDOR_ID:
309*59d8a77dSDmitry Borisov             GenericInfo.Ulong = 0;
310*59d8a77dSDmitry Borisov             GenericInfo.Ulong |= (Adapter->PermanentMacAddress[0] << 16);
311*59d8a77dSDmitry Borisov             GenericInfo.Ulong |= (Adapter->PermanentMacAddress[1] << 8);
312*59d8a77dSDmitry Borisov             GenericInfo.Ulong |= (Adapter->PermanentMacAddress[2] & 0xFF);
313*59d8a77dSDmitry Borisov             break;
314*59d8a77dSDmitry Borisov 
315*59d8a77dSDmitry Borisov         case OID_GEN_VENDOR_DESCRIPTION:
316*59d8a77dSDmitry Borisov         {
317*59d8a77dSDmitry Borisov             static const CHAR VendorDesc[] = "DC21x4 compatible Ethernet Adapter";
318*59d8a77dSDmitry Borisov             InfoPtr = (PVOID)&VendorDesc;
319*59d8a77dSDmitry Borisov             InfoLength = sizeof(VendorDesc);
320*59d8a77dSDmitry Borisov             break;
321*59d8a77dSDmitry Borisov         }
322*59d8a77dSDmitry Borisov 
323*59d8a77dSDmitry Borisov         case OID_GEN_VENDOR_DRIVER_VERSION:
324*59d8a77dSDmitry Borisov             /* 1.0.0 */
325*59d8a77dSDmitry Borisov             GenericInfo.Ulong = 0x100;
326*59d8a77dSDmitry Borisov             break;
327*59d8a77dSDmitry Borisov 
328*59d8a77dSDmitry Borisov         case OID_GEN_DRIVER_VERSION:
329*59d8a77dSDmitry Borisov         {
330*59d8a77dSDmitry Borisov             InfoLength = sizeof(USHORT);
331*59d8a77dSDmitry Borisov             GenericInfo.Ushort = (NDIS_MINIPORT_MAJOR_VERSION << 8) | NDIS_MINIPORT_MINOR_VERSION;
332*59d8a77dSDmitry Borisov             break;
333*59d8a77dSDmitry Borisov         }
334*59d8a77dSDmitry Borisov 
335*59d8a77dSDmitry Borisov         case OID_GEN_MAXIMUM_SEND_PACKETS:
336*59d8a77dSDmitry Borisov             GenericInfo.Ulong = DC_TRANSMIT_BLOCKS - DC_TCB_RESERVE;
337*59d8a77dSDmitry Borisov             break;
338*59d8a77dSDmitry Borisov 
339*59d8a77dSDmitry Borisov         case OID_GEN_MAC_OPTIONS:
340*59d8a77dSDmitry Borisov             GenericInfo.Ulong = NDIS_MAC_OPTION_COPY_LOOKAHEAD_DATA |
341*59d8a77dSDmitry Borisov                                 NDIS_MAC_OPTION_TRANSFERS_NOT_PEND |
342*59d8a77dSDmitry Borisov                                 NDIS_MAC_OPTION_NO_LOOPBACK;
343*59d8a77dSDmitry Borisov             break;
344*59d8a77dSDmitry Borisov 
345*59d8a77dSDmitry Borisov         case OID_GEN_MEDIA_CONNECT_STATUS:
346*59d8a77dSDmitry Borisov             GenericInfo.Ulong = Adapter->LinkUp ? NdisMediaStateConnected
347*59d8a77dSDmitry Borisov                                                 : NdisMediaStateDisconnected;
348*59d8a77dSDmitry Borisov             break;
349*59d8a77dSDmitry Borisov 
350*59d8a77dSDmitry Borisov         case OID_802_3_PERMANENT_ADDRESS:
351*59d8a77dSDmitry Borisov             InfoPtr = Adapter->PermanentMacAddress;
352*59d8a77dSDmitry Borisov             InfoLength = ETH_LENGTH_OF_ADDRESS;
353*59d8a77dSDmitry Borisov             break;
354*59d8a77dSDmitry Borisov 
355*59d8a77dSDmitry Borisov         case OID_802_3_CURRENT_ADDRESS:
356*59d8a77dSDmitry Borisov             InfoPtr = Adapter->CurrentMacAddress;
357*59d8a77dSDmitry Borisov             InfoLength = ETH_LENGTH_OF_ADDRESS;
358*59d8a77dSDmitry Borisov             break;
359*59d8a77dSDmitry Borisov 
360*59d8a77dSDmitry Borisov         case OID_GEN_XMIT_OK:
361*59d8a77dSDmitry Borisov         case OID_GEN_RCV_OK:
362*59d8a77dSDmitry Borisov         case OID_GEN_XMIT_ERROR:
363*59d8a77dSDmitry Borisov         case OID_GEN_RCV_ERROR:
364*59d8a77dSDmitry Borisov         case OID_GEN_RCV_NO_BUFFER:
365*59d8a77dSDmitry Borisov         case OID_GEN_DIRECTED_FRAMES_RCV:
366*59d8a77dSDmitry Borisov         case OID_GEN_MULTICAST_FRAMES_RCV:
367*59d8a77dSDmitry Borisov         case OID_GEN_BROADCAST_FRAMES_RCV:
368*59d8a77dSDmitry Borisov         case OID_GEN_RCV_CRC_ERROR:
369*59d8a77dSDmitry Borisov         case OID_802_3_RCV_ERROR_ALIGNMENT:
370*59d8a77dSDmitry Borisov         case OID_802_3_XMIT_ONE_COLLISION:
371*59d8a77dSDmitry Borisov         case OID_802_3_XMIT_MORE_COLLISIONS:
372*59d8a77dSDmitry Borisov         case OID_802_3_XMIT_DEFERRED:
373*59d8a77dSDmitry Borisov         case OID_802_3_XMIT_MAX_COLLISIONS:
374*59d8a77dSDmitry Borisov         case OID_802_3_RCV_OVERRUN:
375*59d8a77dSDmitry Borisov         case OID_802_3_XMIT_UNDERRUN:
376*59d8a77dSDmitry Borisov         case OID_802_3_XMIT_HEARTBEAT_FAILURE:
377*59d8a77dSDmitry Borisov         case OID_802_3_XMIT_TIMES_CRS_LOST:
378*59d8a77dSDmitry Borisov         case OID_802_3_XMIT_LATE_COLLISIONS:
379*59d8a77dSDmitry Borisov         {
380*59d8a77dSDmitry Borisov             DcQueryStatisticCounter(Adapter, Oid, &GenericInfo.Ulong64);
381*59d8a77dSDmitry Borisov 
382*59d8a77dSDmitry Borisov             *BytesNeeded = sizeof(ULONG64);
383*59d8a77dSDmitry Borisov             if (InformationBufferLength < sizeof(ULONG))
384*59d8a77dSDmitry Borisov             {
385*59d8a77dSDmitry Borisov                 *BytesWritten = 0;
386*59d8a77dSDmitry Borisov                 return NDIS_STATUS_BUFFER_TOO_SHORT;
387*59d8a77dSDmitry Borisov             }
388*59d8a77dSDmitry Borisov             if (InformationBufferLength >= sizeof(ULONG64))
389*59d8a77dSDmitry Borisov             {
390*59d8a77dSDmitry Borisov                 *BytesWritten = sizeof(ULONG64);
391*59d8a77dSDmitry Borisov                 NdisMoveMemory(InformationBuffer, InfoPtr, sizeof(ULONG64));
392*59d8a77dSDmitry Borisov             }
393*59d8a77dSDmitry Borisov             else
394*59d8a77dSDmitry Borisov             {
395*59d8a77dSDmitry Borisov                 *BytesWritten = sizeof(ULONG);
396*59d8a77dSDmitry Borisov                 NdisMoveMemory(InformationBuffer, InfoPtr, sizeof(ULONG));
397*59d8a77dSDmitry Borisov             }
398*59d8a77dSDmitry Borisov 
399*59d8a77dSDmitry Borisov             return NDIS_STATUS_SUCCESS;
400*59d8a77dSDmitry Borisov         }
401*59d8a77dSDmitry Borisov 
402*59d8a77dSDmitry Borisov         case OID_GEN_TRANSMIT_QUEUE_LENGTH:
403*59d8a77dSDmitry Borisov             GenericInfo.Ulong = (DC_TRANSMIT_BLOCKS - DC_TCB_RESERVE) - Adapter->TcbSlots;
404*59d8a77dSDmitry Borisov             break;
405*59d8a77dSDmitry Borisov 
406*59d8a77dSDmitry Borisov         case OID_PNP_CAPABILITIES:
407*59d8a77dSDmitry Borisov         {
408*59d8a77dSDmitry Borisov             PNDIS_PNP_CAPABILITIES Capabilities;
409*59d8a77dSDmitry Borisov 
410*59d8a77dSDmitry Borisov             InfoLength = sizeof(NDIS_PNP_CAPABILITIES);
411*59d8a77dSDmitry Borisov 
412*59d8a77dSDmitry Borisov             if (InformationBufferLength < InfoLength)
413*59d8a77dSDmitry Borisov             {
414*59d8a77dSDmitry Borisov                 *BytesWritten = 0;
415*59d8a77dSDmitry Borisov                 *BytesNeeded = InfoLength;
416*59d8a77dSDmitry Borisov                 return NDIS_STATUS_BUFFER_TOO_SHORT;
417*59d8a77dSDmitry Borisov             }
418*59d8a77dSDmitry Borisov 
419*59d8a77dSDmitry Borisov             if (!(Adapter->Features & DC_HAS_POWER_MANAGEMENT))
420*59d8a77dSDmitry Borisov                 return NDIS_STATUS_NOT_SUPPORTED;
421*59d8a77dSDmitry Borisov 
422*59d8a77dSDmitry Borisov             *BytesWritten = InfoLength;
423*59d8a77dSDmitry Borisov             *BytesNeeded = 0;
424*59d8a77dSDmitry Borisov 
425*59d8a77dSDmitry Borisov             Capabilities = InformationBuffer;
426*59d8a77dSDmitry Borisov             Capabilities->WakeUpCapabilities.MinMagicPacketWakeUp = NdisDeviceStateD3;
427*59d8a77dSDmitry Borisov             Capabilities->WakeUpCapabilities.MinPatternWakeUp = NdisDeviceStateD3;
428*59d8a77dSDmitry Borisov             Capabilities->WakeUpCapabilities.MinLinkChangeWakeUp = NdisDeviceStateD3;
429*59d8a77dSDmitry Borisov 
430*59d8a77dSDmitry Borisov             return NDIS_STATUS_SUCCESS;
431*59d8a77dSDmitry Borisov         }
432*59d8a77dSDmitry Borisov 
433*59d8a77dSDmitry Borisov         case OID_PNP_QUERY_POWER:
434*59d8a77dSDmitry Borisov         {
435*59d8a77dSDmitry Borisov             if (!(Adapter->Features & DC_HAS_POWER_MANAGEMENT))
436*59d8a77dSDmitry Borisov                 return NDIS_STATUS_NOT_SUPPORTED;
437*59d8a77dSDmitry Borisov 
438*59d8a77dSDmitry Borisov             return NDIS_STATUS_SUCCESS;
439*59d8a77dSDmitry Borisov         }
440*59d8a77dSDmitry Borisov 
441*59d8a77dSDmitry Borisov         case OID_PNP_ENABLE_WAKE_UP:
442*59d8a77dSDmitry Borisov         {
443*59d8a77dSDmitry Borisov             if (!(Adapter->Features & DC_HAS_POWER_MANAGEMENT))
444*59d8a77dSDmitry Borisov                 return NDIS_STATUS_NOT_SUPPORTED;
445*59d8a77dSDmitry Borisov 
446*59d8a77dSDmitry Borisov             GenericInfo.Ulong = Adapter->WakeUpFlags & (NDIS_PNP_WAKE_UP_MAGIC_PACKET |
447*59d8a77dSDmitry Borisov                                                         NDIS_PNP_WAKE_UP_PATTERN_MATCH |
448*59d8a77dSDmitry Borisov                                                         NDIS_PNP_WAKE_UP_LINK_CHANGE);
449*59d8a77dSDmitry Borisov             break;
450*59d8a77dSDmitry Borisov         }
451*59d8a77dSDmitry Borisov 
452*59d8a77dSDmitry Borisov         default:
453*59d8a77dSDmitry Borisov             Status = NDIS_STATUS_INVALID_OID;
454*59d8a77dSDmitry Borisov             break;
455*59d8a77dSDmitry Borisov     }
456*59d8a77dSDmitry Borisov 
457*59d8a77dSDmitry Borisov     if (Status == NDIS_STATUS_SUCCESS)
458*59d8a77dSDmitry Borisov     {
459*59d8a77dSDmitry Borisov         if (InfoLength > InformationBufferLength)
460*59d8a77dSDmitry Borisov         {
461*59d8a77dSDmitry Borisov             *BytesWritten = 0;
462*59d8a77dSDmitry Borisov             *BytesNeeded = InfoLength;
463*59d8a77dSDmitry Borisov             Status = NDIS_STATUS_BUFFER_TOO_SHORT;
464*59d8a77dSDmitry Borisov         }
465*59d8a77dSDmitry Borisov         else
466*59d8a77dSDmitry Borisov         {
467*59d8a77dSDmitry Borisov             NdisMoveMemory(InformationBuffer, InfoPtr, InfoLength);
468*59d8a77dSDmitry Borisov             *BytesWritten = InfoLength;
469*59d8a77dSDmitry Borisov             *BytesNeeded = 0;
470*59d8a77dSDmitry Borisov         }
471*59d8a77dSDmitry Borisov     }
472*59d8a77dSDmitry Borisov     else
473*59d8a77dSDmitry Borisov     {
474*59d8a77dSDmitry Borisov         *BytesWritten = 0;
475*59d8a77dSDmitry Borisov         *BytesNeeded = 0;
476*59d8a77dSDmitry Borisov     }
477*59d8a77dSDmitry Borisov 
478*59d8a77dSDmitry Borisov     return Status;
479*59d8a77dSDmitry Borisov }
480*59d8a77dSDmitry Borisov 
481*59d8a77dSDmitry Borisov NDIS_STATUS
482*59d8a77dSDmitry Borisov NTAPI
DcSetInformation(_In_ NDIS_HANDLE MiniportAdapterContext,_In_ NDIS_OID Oid,_In_ PVOID InformationBuffer,_In_ ULONG InformationBufferLength,_Out_ PULONG BytesRead,_Out_ PULONG BytesNeeded)483*59d8a77dSDmitry Borisov DcSetInformation(
484*59d8a77dSDmitry Borisov     _In_ NDIS_HANDLE MiniportAdapterContext,
485*59d8a77dSDmitry Borisov     _In_ NDIS_OID Oid,
486*59d8a77dSDmitry Borisov     _In_ PVOID InformationBuffer,
487*59d8a77dSDmitry Borisov     _In_ ULONG InformationBufferLength,
488*59d8a77dSDmitry Borisov     _Out_ PULONG BytesRead,
489*59d8a77dSDmitry Borisov     _Out_ PULONG BytesNeeded)
490*59d8a77dSDmitry Borisov {
491*59d8a77dSDmitry Borisov     PDC21X4_ADAPTER Adapter = (PDC21X4_ADAPTER)MiniportAdapterContext;
492*59d8a77dSDmitry Borisov     NDIS_STATUS Status = NDIS_STATUS_SUCCESS;
493*59d8a77dSDmitry Borisov     ULONG GenericUlong;
494*59d8a77dSDmitry Borisov 
495*59d8a77dSDmitry Borisov     *BytesRead = 0;
496*59d8a77dSDmitry Borisov     *BytesNeeded = 0;
497*59d8a77dSDmitry Borisov 
498*59d8a77dSDmitry Borisov     switch (Oid)
499*59d8a77dSDmitry Borisov     {
500*59d8a77dSDmitry Borisov         case OID_GEN_CURRENT_PACKET_FILTER:
501*59d8a77dSDmitry Borisov         {
502*59d8a77dSDmitry Borisov             if (InformationBufferLength < sizeof(ULONG))
503*59d8a77dSDmitry Borisov             {
504*59d8a77dSDmitry Borisov                 *BytesNeeded = sizeof(ULONG);
505*59d8a77dSDmitry Borisov                 Status = NDIS_STATUS_INVALID_LENGTH;
506*59d8a77dSDmitry Borisov                 break;
507*59d8a77dSDmitry Borisov             }
508*59d8a77dSDmitry Borisov 
509*59d8a77dSDmitry Borisov             *BytesRead = sizeof(ULONG);
510*59d8a77dSDmitry Borisov             NdisMoveMemory(&GenericUlong, InformationBuffer, sizeof(ULONG));
511*59d8a77dSDmitry Borisov 
512*59d8a77dSDmitry Borisov             if (GenericUlong & ~DC_PACKET_FILTERS)
513*59d8a77dSDmitry Borisov             {
514*59d8a77dSDmitry Borisov                 Status = NDIS_STATUS_NOT_SUPPORTED;
515*59d8a77dSDmitry Borisov                 break;
516*59d8a77dSDmitry Borisov             }
517*59d8a77dSDmitry Borisov 
518*59d8a77dSDmitry Borisov             Status = DcApplyPacketFilter(Adapter, GenericUlong);
519*59d8a77dSDmitry Borisov             break;
520*59d8a77dSDmitry Borisov         }
521*59d8a77dSDmitry Borisov 
522*59d8a77dSDmitry Borisov         case OID_802_3_MULTICAST_LIST:
523*59d8a77dSDmitry Borisov         {
524*59d8a77dSDmitry Borisov             ULONG Size;
525*59d8a77dSDmitry Borisov 
526*59d8a77dSDmitry Borisov             if (InformationBufferLength % ETH_LENGTH_OF_ADDRESS)
527*59d8a77dSDmitry Borisov             {
528*59d8a77dSDmitry Borisov                 *BytesNeeded = (InformationBufferLength / ETH_LENGTH_OF_ADDRESS) *
529*59d8a77dSDmitry Borisov                                ETH_LENGTH_OF_ADDRESS;
530*59d8a77dSDmitry Borisov                 Status = NDIS_STATUS_INVALID_LENGTH;
531*59d8a77dSDmitry Borisov                 break;
532*59d8a77dSDmitry Borisov             }
533*59d8a77dSDmitry Borisov 
534*59d8a77dSDmitry Borisov             Size = Adapter->MulticastMaxEntries * ETH_LENGTH_OF_ADDRESS;
535*59d8a77dSDmitry Borisov             if (InformationBufferLength > Size)
536*59d8a77dSDmitry Borisov             {
537*59d8a77dSDmitry Borisov                 *BytesNeeded = Size;
538*59d8a77dSDmitry Borisov                 Status = NDIS_STATUS_MULTICAST_FULL;
539*59d8a77dSDmitry Borisov                 break;
540*59d8a77dSDmitry Borisov             }
541*59d8a77dSDmitry Borisov 
542*59d8a77dSDmitry Borisov             *BytesRead = InformationBufferLength;
543*59d8a77dSDmitry Borisov             NdisMoveMemory(Adapter->MulticastList, InformationBuffer, InformationBufferLength);
544*59d8a77dSDmitry Borisov 
545*59d8a77dSDmitry Borisov             Adapter->MulticastCount = InformationBufferLength / ETH_LENGTH_OF_ADDRESS;
546*59d8a77dSDmitry Borisov 
547*59d8a77dSDmitry Borisov             Status = DcUpdateMulticastList(Adapter);
548*59d8a77dSDmitry Borisov             break;
549*59d8a77dSDmitry Borisov         }
550*59d8a77dSDmitry Borisov 
551*59d8a77dSDmitry Borisov         case OID_GEN_CURRENT_LOOKAHEAD:
552*59d8a77dSDmitry Borisov         {
553*59d8a77dSDmitry Borisov             if (InformationBufferLength < sizeof(ULONG))
554*59d8a77dSDmitry Borisov             {
555*59d8a77dSDmitry Borisov                 *BytesNeeded = sizeof(ULONG);
556*59d8a77dSDmitry Borisov                 Status = NDIS_STATUS_INVALID_LENGTH;
557*59d8a77dSDmitry Borisov                 break;
558*59d8a77dSDmitry Borisov             }
559*59d8a77dSDmitry Borisov 
560*59d8a77dSDmitry Borisov             /* Nothing to do */
561*59d8a77dSDmitry Borisov             *BytesRead = sizeof(ULONG);
562*59d8a77dSDmitry Borisov             break;
563*59d8a77dSDmitry Borisov         }
564*59d8a77dSDmitry Borisov 
565*59d8a77dSDmitry Borisov         case OID_PNP_ENABLE_WAKE_UP:
566*59d8a77dSDmitry Borisov         {
567*59d8a77dSDmitry Borisov             if (InformationBufferLength < sizeof(ULONG))
568*59d8a77dSDmitry Borisov             {
569*59d8a77dSDmitry Borisov                 *BytesNeeded = sizeof(ULONG);
570*59d8a77dSDmitry Borisov                 Status = NDIS_STATUS_INVALID_LENGTH;
571*59d8a77dSDmitry Borisov                 break;
572*59d8a77dSDmitry Borisov             }
573*59d8a77dSDmitry Borisov 
574*59d8a77dSDmitry Borisov             if (!(Adapter->Features & DC_HAS_POWER_MANAGEMENT))
575*59d8a77dSDmitry Borisov             {
576*59d8a77dSDmitry Borisov                 return NDIS_STATUS_NOT_SUPPORTED;
577*59d8a77dSDmitry Borisov             }
578*59d8a77dSDmitry Borisov 
579*59d8a77dSDmitry Borisov             *BytesRead = sizeof(ULONG);
580*59d8a77dSDmitry Borisov             NdisMoveMemory(&GenericUlong, InformationBuffer, sizeof(ULONG));
581*59d8a77dSDmitry Borisov 
582*59d8a77dSDmitry Borisov             Adapter->WakeUpFlags = GenericUlong;
583*59d8a77dSDmitry Borisov             break;
584*59d8a77dSDmitry Borisov         }
585*59d8a77dSDmitry Borisov 
586*59d8a77dSDmitry Borisov         case OID_PNP_ADD_WAKE_UP_PATTERN:
587*59d8a77dSDmitry Borisov         {
588*59d8a77dSDmitry Borisov             if (InformationBufferLength < sizeof(NDIS_PM_PACKET_PATTERN))
589*59d8a77dSDmitry Borisov             {
590*59d8a77dSDmitry Borisov                 *BytesNeeded = sizeof(NDIS_PM_PACKET_PATTERN);
591*59d8a77dSDmitry Borisov                 Status = NDIS_STATUS_INVALID_LENGTH;
592*59d8a77dSDmitry Borisov                 break;
593*59d8a77dSDmitry Borisov             }
594*59d8a77dSDmitry Borisov 
595*59d8a77dSDmitry Borisov             if (!(Adapter->Features & DC_HAS_POWER_MANAGEMENT))
596*59d8a77dSDmitry Borisov             {
597*59d8a77dSDmitry Borisov                 return NDIS_STATUS_NOT_SUPPORTED;
598*59d8a77dSDmitry Borisov             }
599*59d8a77dSDmitry Borisov 
600*59d8a77dSDmitry Borisov             *BytesRead = sizeof(NDIS_PM_PACKET_PATTERN);
601*59d8a77dSDmitry Borisov 
602*59d8a77dSDmitry Borisov             Status = DcAddWakeUpPattern(Adapter, InformationBuffer);
603*59d8a77dSDmitry Borisov             break;
604*59d8a77dSDmitry Borisov         }
605*59d8a77dSDmitry Borisov 
606*59d8a77dSDmitry Borisov         case OID_PNP_REMOVE_WAKE_UP_PATTERN:
607*59d8a77dSDmitry Borisov         {
608*59d8a77dSDmitry Borisov             if (InformationBufferLength < sizeof(NDIS_PM_PACKET_PATTERN))
609*59d8a77dSDmitry Borisov             {
610*59d8a77dSDmitry Borisov                 *BytesNeeded = sizeof(NDIS_PM_PACKET_PATTERN);
611*59d8a77dSDmitry Borisov                 Status = NDIS_STATUS_INVALID_LENGTH;
612*59d8a77dSDmitry Borisov                 break;
613*59d8a77dSDmitry Borisov             }
614*59d8a77dSDmitry Borisov 
615*59d8a77dSDmitry Borisov             if (!(Adapter->Features & DC_HAS_POWER_MANAGEMENT))
616*59d8a77dSDmitry Borisov             {
617*59d8a77dSDmitry Borisov                 return NDIS_STATUS_NOT_SUPPORTED;
618*59d8a77dSDmitry Borisov             }
619*59d8a77dSDmitry Borisov 
620*59d8a77dSDmitry Borisov             *BytesRead = sizeof(NDIS_PM_PACKET_PATTERN);
621*59d8a77dSDmitry Borisov 
622*59d8a77dSDmitry Borisov             Status = DcRemoveWakeUpPattern(Adapter, InformationBuffer);
623*59d8a77dSDmitry Borisov             break;
624*59d8a77dSDmitry Borisov         }
625*59d8a77dSDmitry Borisov 
626*59d8a77dSDmitry Borisov         case OID_PNP_SET_POWER:
627*59d8a77dSDmitry Borisov         {
628*59d8a77dSDmitry Borisov             if (InformationBufferLength < sizeof(NDIS_DEVICE_POWER_STATE))
629*59d8a77dSDmitry Borisov             {
630*59d8a77dSDmitry Borisov                 *BytesNeeded = sizeof(NDIS_DEVICE_POWER_STATE);
631*59d8a77dSDmitry Borisov                 Status = NDIS_STATUS_INVALID_LENGTH;
632*59d8a77dSDmitry Borisov                 break;
633*59d8a77dSDmitry Borisov             }
634*59d8a77dSDmitry Borisov 
635*59d8a77dSDmitry Borisov             if (!(Adapter->Features & DC_HAS_POWER_MANAGEMENT))
636*59d8a77dSDmitry Borisov             {
637*59d8a77dSDmitry Borisov                 return NDIS_STATUS_NOT_SUPPORTED;
638*59d8a77dSDmitry Borisov             }
639*59d8a77dSDmitry Borisov 
640*59d8a77dSDmitry Borisov             *BytesRead = sizeof(ULONG);
641*59d8a77dSDmitry Borisov             NdisMoveMemory(&GenericUlong, InformationBuffer, sizeof(ULONG));
642*59d8a77dSDmitry Borisov 
643*59d8a77dSDmitry Borisov             if (GenericUlong < NdisDeviceStateD0 || GenericUlong > NdisDeviceStateD3)
644*59d8a77dSDmitry Borisov             {
645*59d8a77dSDmitry Borisov                 ASSERT(FALSE);
646*59d8a77dSDmitry Borisov                 Status = NDIS_STATUS_INVALID_DATA;
647*59d8a77dSDmitry Borisov                 break;
648*59d8a77dSDmitry Borisov             }
649*59d8a77dSDmitry Borisov 
650*59d8a77dSDmitry Borisov             DcSetPower(Adapter, GenericUlong);
651*59d8a77dSDmitry Borisov             break;
652*59d8a77dSDmitry Borisov         }
653*59d8a77dSDmitry Borisov 
654*59d8a77dSDmitry Borisov         default:
655*59d8a77dSDmitry Borisov             Status = NDIS_STATUS_NOT_SUPPORTED;
656*59d8a77dSDmitry Borisov             break;
657*59d8a77dSDmitry Borisov     }
658*59d8a77dSDmitry Borisov 
659*59d8a77dSDmitry Borisov     return Status;
660*59d8a77dSDmitry Borisov }
661