xref: /reactos/drivers/network/dd/e1000/info.c (revision bbabe248)
1 /*
2  * PROJECT:     ReactOS Intel PRO/1000 Driver
3  * LICENSE:     GPL-2.0+ (https://spdx.org/licenses/GPL-2.0+)
4  * PURPOSE:     Miniport information callbacks
5  * COPYRIGHT:   2013 Cameron Gutman (cameron.gutman@reactos.org)
6  *              2018 Mark Jansen (mark.jansen@reactos.org)
7  */
8 
9 #include "nic.h"
10 
11 #include <debug.h>
12 
13 static ULONG SupportedOidList[] =
14 {
15     OID_GEN_SUPPORTED_LIST,
16     OID_GEN_CURRENT_PACKET_FILTER,
17     OID_GEN_HARDWARE_STATUS,
18     OID_GEN_MEDIA_SUPPORTED,
19     OID_GEN_MEDIA_IN_USE,
20     OID_GEN_MAXIMUM_LOOKAHEAD,
21     OID_GEN_MAXIMUM_FRAME_SIZE,
22     OID_GEN_MAXIMUM_SEND_PACKETS,
23     OID_GEN_LINK_SPEED,
24     OID_GEN_TRANSMIT_BUFFER_SPACE,
25     OID_GEN_RECEIVE_BUFFER_SPACE,
26     OID_GEN_RECEIVE_BLOCK_SIZE,
27     OID_GEN_TRANSMIT_BLOCK_SIZE,
28     OID_GEN_VENDOR_ID,
29     OID_GEN_VENDOR_DESCRIPTION,
30     OID_GEN_VENDOR_DRIVER_VERSION,
31     OID_GEN_CURRENT_LOOKAHEAD,
32     OID_802_3_MULTICAST_LIST,
33     OID_GEN_DRIVER_VERSION,
34     OID_GEN_MAXIMUM_TOTAL_SIZE,
35     OID_GEN_MAC_OPTIONS,
36     OID_GEN_MEDIA_CONNECT_STATUS,
37     OID_802_3_PERMANENT_ADDRESS,
38     OID_802_3_CURRENT_ADDRESS,
39     OID_802_3_MAXIMUM_LIST_SIZE,
40     /* Statistics */
41     OID_GEN_XMIT_OK,
42     OID_GEN_RCV_OK,
43     OID_GEN_XMIT_ERROR,
44     OID_GEN_RCV_ERROR,
45     OID_GEN_RCV_NO_BUFFER,
46 };
47 
48 
49 NDIS_STATUS
50 NTAPI
51 MiniportQueryInformation(
52     IN NDIS_HANDLE MiniportAdapterContext,
53     IN NDIS_OID Oid,
54     IN PVOID InformationBuffer,
55     IN ULONG InformationBufferLength,
56     OUT PULONG BytesWritten,
57     OUT PULONG BytesNeeded)
58 {
59     PE1000_ADAPTER Adapter = (PE1000_ADAPTER)MiniportAdapterContext;
60     ULONG genericUlong;
61     ULONG copyLength;
62     PVOID copySource;
63     NDIS_STATUS status;
64 
65     status = NDIS_STATUS_SUCCESS;
66     copySource = &genericUlong;
67     copyLength = sizeof(ULONG);
68 
69     switch (Oid)
70     {
71     case OID_GEN_SUPPORTED_LIST:
72         copySource = (PVOID)&SupportedOidList;
73         copyLength = sizeof(SupportedOidList);
74         break;
75 
76     case OID_GEN_CURRENT_PACKET_FILTER:
77         genericUlong = Adapter->PacketFilter;
78         break;
79 
80     case OID_GEN_HARDWARE_STATUS:
81         UNIMPLEMENTED_DBGBREAK();
82         genericUlong = (ULONG)NdisHardwareStatusReady; //FIXME
83         break;
84 
85     case OID_GEN_MEDIA_SUPPORTED:
86     case OID_GEN_MEDIA_IN_USE:
87     {
88         static const NDIS_MEDIUM medium = NdisMedium802_3;
89         copySource = (PVOID)&medium;
90         copyLength = sizeof(medium);
91         break;
92     }
93 
94     case OID_GEN_RECEIVE_BLOCK_SIZE:
95     case OID_GEN_TRANSMIT_BLOCK_SIZE:
96     case OID_GEN_CURRENT_LOOKAHEAD:
97     case OID_GEN_MAXIMUM_LOOKAHEAD:
98     case OID_GEN_MAXIMUM_FRAME_SIZE:
99         genericUlong = MAXIMUM_FRAME_SIZE - sizeof(ETH_HEADER);
100         break;
101 
102     case OID_802_3_MAXIMUM_LIST_SIZE:
103         genericUlong = MAXIMUM_MULTICAST_ADDRESSES;
104         break;
105 
106     case OID_GEN_LINK_SPEED:
107         genericUlong = Adapter->LinkSpeedMbps * 10000;
108         break;
109 
110     case OID_GEN_TRANSMIT_BUFFER_SPACE:
111         genericUlong = MAXIMUM_FRAME_SIZE;
112         break;
113 
114     case OID_GEN_RECEIVE_BUFFER_SPACE:
115         genericUlong = RECEIVE_BUFFER_SIZE;
116         break;
117 
118     case OID_GEN_VENDOR_ID:
119         /* The 3 bytes of the MAC address is the vendor ID */
120         genericUlong = 0;
121         genericUlong |= (Adapter->PermanentMacAddress[0] << 16);
122         genericUlong |= (Adapter->PermanentMacAddress[1] << 8);
123         genericUlong |= (Adapter->PermanentMacAddress[2] & 0xFF);
124         break;
125 
126     case OID_GEN_VENDOR_DESCRIPTION:
127     {
128         static UCHAR vendorDesc[] = "ReactOS Team";
129         copySource = vendorDesc;
130         copyLength = sizeof(vendorDesc);
131         break;
132     }
133 
134     case OID_GEN_VENDOR_DRIVER_VERSION:
135         genericUlong = DRIVER_VERSION;
136         break;
137 
138     case OID_GEN_DRIVER_VERSION:
139     {
140         static const USHORT driverVersion =
141             (NDIS_MINIPORT_MAJOR_VERSION << 8) + NDIS_MINIPORT_MINOR_VERSION;
142         copySource = (PVOID)&driverVersion;
143         copyLength = sizeof(driverVersion);
144         break;
145     }
146 
147     case OID_GEN_MAXIMUM_TOTAL_SIZE:
148         genericUlong = MAXIMUM_FRAME_SIZE;
149         break;
150 
151     case OID_GEN_MAXIMUM_SEND_PACKETS:
152         genericUlong = 1;
153         break;
154 
155     case OID_GEN_MAC_OPTIONS:
156         genericUlong = NDIS_MAC_OPTION_RECEIVE_SERIALIZED |
157             NDIS_MAC_OPTION_COPY_LOOKAHEAD_DATA |
158             NDIS_MAC_OPTION_TRANSFERS_NOT_PEND |
159             NDIS_MAC_OPTION_NO_LOOPBACK;
160         break;
161 
162     case OID_GEN_MEDIA_CONNECT_STATUS:
163         genericUlong = Adapter->MediaState;
164         break;
165 
166 
167     case OID_802_3_CURRENT_ADDRESS:
168         copySource = Adapter->MulticastList[0].MacAddress;
169         copyLength = IEEE_802_ADDR_LENGTH;
170         break;
171 
172     case OID_802_3_PERMANENT_ADDRESS:
173         copySource = Adapter->PermanentMacAddress;
174         copyLength = IEEE_802_ADDR_LENGTH;
175         break;
176 
177     case OID_GEN_XMIT_OK:
178         genericUlong = 0;
179         break;
180     case OID_GEN_RCV_OK:
181         genericUlong = 0;
182         break;
183     case OID_GEN_XMIT_ERROR:
184         genericUlong = 0;
185         break;
186     case OID_GEN_RCV_ERROR:
187         genericUlong = 0;
188         break;
189     case OID_GEN_RCV_NO_BUFFER:
190         genericUlong = 0;
191         break;
192 
193     default:
194         NDIS_DbgPrint(MIN_TRACE, ("Unknown OID 0x%x(%s)\n", Oid, Oid2Str(Oid)));
195         status = NDIS_STATUS_NOT_SUPPORTED;
196         break;
197     }
198 
199     if (status == NDIS_STATUS_SUCCESS)
200     {
201         if (copyLength > InformationBufferLength)
202         {
203             *BytesNeeded = copyLength;
204             *BytesWritten = 0;
205             status = NDIS_STATUS_INVALID_LENGTH;
206         }
207         else
208         {
209             NdisMoveMemory(InformationBuffer, copySource, copyLength);
210             *BytesWritten = copyLength;
211             *BytesNeeded = copyLength;
212         }
213     }
214     else
215     {
216         *BytesWritten = 0;
217         *BytesNeeded = 0;
218     }
219 
220     /* XMIT_ERROR and RCV_ERROR are really noisy, so do not log those. */
221     if (Oid != OID_GEN_XMIT_ERROR && Oid != OID_GEN_RCV_ERROR)
222     {
223         NDIS_DbgPrint(MAX_TRACE, ("Query OID 0x%x(%s): Completed with status 0x%x (%d, %d)\n",
224                                   Oid, Oid2Str(Oid), status, *BytesWritten, *BytesNeeded));
225     }
226 
227     return status;
228 }
229 
230 NDIS_STATUS
231 NTAPI
232 MiniportSetInformation(
233     IN NDIS_HANDLE MiniportAdapterContext,
234     IN NDIS_OID Oid,
235     IN PVOID InformationBuffer,
236     IN ULONG InformationBufferLength,
237     OUT PULONG BytesRead,
238     OUT PULONG BytesNeeded)
239 {
240     PE1000_ADAPTER Adapter = (PE1000_ADAPTER)MiniportAdapterContext;
241     ULONG genericUlong;
242     NDIS_STATUS status;
243 
244     status = NDIS_STATUS_SUCCESS;
245 
246     switch (Oid)
247     {
248     case OID_GEN_CURRENT_PACKET_FILTER:
249         if (InformationBufferLength < sizeof(ULONG))
250         {
251             *BytesRead = 0;
252             *BytesNeeded = sizeof(ULONG);
253             status = NDIS_STATUS_INVALID_LENGTH;
254             break;
255         }
256 
257         NdisMoveMemory(&genericUlong, InformationBuffer, sizeof(ULONG));
258 
259         if (genericUlong &
260             (NDIS_PACKET_TYPE_SOURCE_ROUTING |
261              NDIS_PACKET_TYPE_SMT |
262              NDIS_PACKET_TYPE_ALL_LOCAL |
263              NDIS_PACKET_TYPE_GROUP |
264              NDIS_PACKET_TYPE_ALL_FUNCTIONAL |
265              NDIS_PACKET_TYPE_FUNCTIONAL))
266         {
267             *BytesRead = sizeof(ULONG);
268             *BytesNeeded = sizeof(ULONG);
269             status = NDIS_STATUS_NOT_SUPPORTED;
270             break;
271         }
272 
273         Adapter->PacketFilter = genericUlong;
274 
275         status = NICApplyPacketFilter(Adapter);
276         if (status != NDIS_STATUS_SUCCESS)
277         {
278             NDIS_DbgPrint(MIN_TRACE, ("Failed to apply new packet filter (0x%x)\n", status));
279             break;
280         }
281 
282         break;
283 
284     case OID_GEN_CURRENT_LOOKAHEAD:
285         if (InformationBufferLength < sizeof(ULONG))
286         {
287             *BytesRead = 0;
288             *BytesNeeded = sizeof(ULONG);
289             status = NDIS_STATUS_INVALID_LENGTH;
290             break;
291         }
292 
293         NdisMoveMemory(&genericUlong, InformationBuffer, sizeof(ULONG));
294 
295         if (genericUlong > MAXIMUM_FRAME_SIZE - sizeof(ETH_HEADER))
296         {
297             status = NDIS_STATUS_INVALID_DATA;
298         }
299         else
300         {
301             // Ignore this...
302         }
303 
304         break;
305 
306     case OID_802_3_MULTICAST_LIST:
307         if (InformationBufferLength % IEEE_802_ADDR_LENGTH)
308         {
309             *BytesRead = 0;
310             *BytesNeeded = InformationBufferLength + (InformationBufferLength % IEEE_802_ADDR_LENGTH);
311             status = NDIS_STATUS_INVALID_LENGTH;
312             break;
313         }
314 
315         if (InformationBufferLength / 6 > MAXIMUM_MULTICAST_ADDRESSES)
316         {
317             *BytesNeeded = MAXIMUM_MULTICAST_ADDRESSES * IEEE_802_ADDR_LENGTH;
318             *BytesRead = 0;
319             status = NDIS_STATUS_INVALID_LENGTH;
320             break;
321         }
322 
323         NdisMoveMemory(Adapter->MulticastList, InformationBuffer, InformationBufferLength);
324         NICUpdateMulticastList(Adapter);
325         break;
326 
327     default:
328         NDIS_DbgPrint(MIN_TRACE, ("Unknown OID 0x%x(%s)\n", Oid, Oid2Str(Oid)));
329         status = NDIS_STATUS_NOT_SUPPORTED;
330         *BytesRead = 0;
331         *BytesNeeded = 0;
332         break;
333     }
334 
335     if (status == NDIS_STATUS_SUCCESS)
336     {
337         *BytesRead = InformationBufferLength;
338         *BytesNeeded = 0;
339     }
340 
341     return status;
342 }
343 
344