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 NDIS_OID 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 41 /* Statistics */ 42 OID_GEN_XMIT_OK, 43 OID_GEN_RCV_OK, 44 OID_GEN_XMIT_ERROR, 45 OID_GEN_RCV_ERROR, 46 OID_GEN_RCV_NO_BUFFER, 47 48 OID_PNP_CAPABILITIES, 49 }; 50 51 static 52 ULONG64 53 NICQueryStatisticCounter( 54 _In_ PE1000_ADAPTER Adapter, 55 _In_ NDIS_OID Oid) 56 { 57 /* TODO */ 58 return 0; 59 } 60 61 static 62 NDIS_STATUS 63 NICFillPowerManagementCapabilities( 64 _In_ PE1000_ADAPTER Adapter, 65 _Out_ PNDIS_PNP_CAPABILITIES Capabilities) 66 { 67 /* TODO */ 68 return NDIS_STATUS_NOT_SUPPORTED; 69 } 70 71 NDIS_STATUS 72 NTAPI 73 MiniportQueryInformation( 74 IN NDIS_HANDLE MiniportAdapterContext, 75 IN NDIS_OID Oid, 76 IN PVOID InformationBuffer, 77 IN ULONG InformationBufferLength, 78 OUT PULONG BytesWritten, 79 OUT PULONG BytesNeeded) 80 { 81 PE1000_ADAPTER Adapter = (PE1000_ADAPTER)MiniportAdapterContext; 82 ULONG copyLength; 83 PVOID copySource; 84 NDIS_STATUS status; 85 union _GENERIC_INFORMATION 86 { 87 USHORT Ushort; 88 ULONG Ulong; 89 ULONG64 Ulong64; 90 NDIS_MEDIUM Medium; 91 NDIS_PNP_CAPABILITIES PmCapabilities; 92 } GenericInfo; 93 94 status = NDIS_STATUS_SUCCESS; 95 copySource = &GenericInfo; 96 copyLength = sizeof(ULONG); 97 98 switch (Oid) 99 { 100 case OID_GEN_SUPPORTED_LIST: 101 copySource = (PVOID)&SupportedOidList; 102 copyLength = sizeof(SupportedOidList); 103 break; 104 105 case OID_GEN_CURRENT_PACKET_FILTER: 106 GenericInfo.Ulong = Adapter->PacketFilter; 107 break; 108 109 case OID_GEN_HARDWARE_STATUS: 110 UNIMPLEMENTED_DBGBREAK(); 111 GenericInfo.Ulong = (ULONG)NdisHardwareStatusReady; //FIXME 112 break; 113 114 case OID_GEN_MEDIA_SUPPORTED: 115 case OID_GEN_MEDIA_IN_USE: 116 { 117 GenericInfo.Medium = NdisMedium802_3; 118 copyLength = sizeof(NDIS_MEDIUM); 119 break; 120 } 121 122 case OID_GEN_RECEIVE_BLOCK_SIZE: 123 case OID_GEN_TRANSMIT_BLOCK_SIZE: 124 case OID_GEN_CURRENT_LOOKAHEAD: 125 case OID_GEN_MAXIMUM_LOOKAHEAD: 126 case OID_GEN_MAXIMUM_FRAME_SIZE: 127 GenericInfo.Ulong = MAXIMUM_FRAME_SIZE - sizeof(ETH_HEADER); 128 break; 129 130 case OID_802_3_MULTICAST_LIST: 131 copySource = Adapter->MulticastList; 132 copyLength = Adapter->MulticastListSize * IEEE_802_ADDR_LENGTH; 133 break; 134 135 case OID_802_3_MAXIMUM_LIST_SIZE: 136 GenericInfo.Ulong = MAXIMUM_MULTICAST_ADDRESSES; 137 break; 138 139 case OID_GEN_LINK_SPEED: 140 GenericInfo.Ulong = Adapter->LinkSpeedMbps * 10000; 141 break; 142 143 case OID_GEN_TRANSMIT_BUFFER_SPACE: 144 GenericInfo.Ulong = MAXIMUM_FRAME_SIZE; 145 break; 146 147 case OID_GEN_RECEIVE_BUFFER_SPACE: 148 GenericInfo.Ulong = RECEIVE_BUFFER_SIZE; 149 break; 150 151 case OID_GEN_VENDOR_ID: 152 /* The 3 bytes of the MAC address is the vendor ID */ 153 GenericInfo.Ulong = 0; 154 GenericInfo.Ulong |= (Adapter->PermanentMacAddress[0] << 16); 155 GenericInfo.Ulong |= (Adapter->PermanentMacAddress[1] << 8); 156 GenericInfo.Ulong |= (Adapter->PermanentMacAddress[2] & 0xFF); 157 break; 158 159 case OID_GEN_VENDOR_DESCRIPTION: 160 { 161 static UCHAR vendorDesc[] = "ReactOS Team"; 162 copySource = vendorDesc; 163 copyLength = sizeof(vendorDesc); 164 break; 165 } 166 167 case OID_GEN_VENDOR_DRIVER_VERSION: 168 GenericInfo.Ulong = DRIVER_VERSION; 169 break; 170 171 case OID_GEN_DRIVER_VERSION: 172 { 173 copyLength = sizeof(USHORT); 174 GenericInfo.Ushort = (NDIS_MINIPORT_MAJOR_VERSION << 8) + NDIS_MINIPORT_MINOR_VERSION; 175 break; 176 } 177 178 case OID_GEN_MAXIMUM_TOTAL_SIZE: 179 GenericInfo.Ulong = MAXIMUM_FRAME_SIZE; 180 break; 181 182 case OID_GEN_MAXIMUM_SEND_PACKETS: 183 GenericInfo.Ulong = 1; 184 break; 185 186 case OID_GEN_MAC_OPTIONS: 187 GenericInfo.Ulong = NDIS_MAC_OPTION_RECEIVE_SERIALIZED | 188 NDIS_MAC_OPTION_COPY_LOOKAHEAD_DATA | 189 NDIS_MAC_OPTION_TRANSFERS_NOT_PEND | 190 NDIS_MAC_OPTION_NO_LOOPBACK; 191 break; 192 193 case OID_GEN_MEDIA_CONNECT_STATUS: 194 GenericInfo.Ulong = Adapter->MediaState; 195 break; 196 197 case OID_802_3_CURRENT_ADDRESS: 198 copySource = Adapter->MulticastList[0].MacAddress; 199 copyLength = IEEE_802_ADDR_LENGTH; 200 break; 201 202 case OID_802_3_PERMANENT_ADDRESS: 203 copySource = Adapter->PermanentMacAddress; 204 copyLength = IEEE_802_ADDR_LENGTH; 205 break; 206 207 case OID_GEN_XMIT_OK: 208 case OID_GEN_RCV_OK: 209 case OID_GEN_XMIT_ERROR: 210 case OID_GEN_RCV_ERROR: 211 case OID_GEN_RCV_NO_BUFFER: 212 { 213 GenericInfo.Ulong64 = NICQueryStatisticCounter(Adapter, Oid); 214 215 *BytesNeeded = sizeof(ULONG64); 216 if (InformationBufferLength >= sizeof(ULONG64)) 217 { 218 *BytesWritten = sizeof(ULONG64); 219 NdisMoveMemory(InformationBuffer, copySource, sizeof(ULONG64)); 220 } 221 else if (InformationBufferLength >= sizeof(ULONG)) 222 { 223 *BytesWritten = sizeof(ULONG); 224 NdisMoveMemory(InformationBuffer, copySource, sizeof(ULONG)); 225 } 226 else 227 { 228 *BytesWritten = 0; 229 return NDIS_STATUS_BUFFER_TOO_SHORT; 230 } 231 return NDIS_STATUS_SUCCESS; 232 } 233 234 case OID_PNP_CAPABILITIES: 235 { 236 copyLength = sizeof(NDIS_PNP_CAPABILITIES); 237 238 status = NICFillPowerManagementCapabilities(Adapter, &GenericInfo.PmCapabilities); 239 break; 240 } 241 242 default: 243 NDIS_DbgPrint(MIN_TRACE, ("Unknown OID 0x%x(%s)\n", Oid, Oid2Str(Oid))); 244 status = NDIS_STATUS_NOT_SUPPORTED; 245 break; 246 } 247 248 if (status == NDIS_STATUS_SUCCESS) 249 { 250 if (copyLength > InformationBufferLength) 251 { 252 *BytesNeeded = copyLength; 253 *BytesWritten = 0; 254 status = NDIS_STATUS_BUFFER_TOO_SHORT; 255 } 256 else 257 { 258 NdisMoveMemory(InformationBuffer, copySource, copyLength); 259 *BytesWritten = copyLength; 260 *BytesNeeded = copyLength; 261 } 262 } 263 else 264 { 265 *BytesWritten = 0; 266 *BytesNeeded = 0; 267 } 268 269 NDIS_DbgPrint(MAX_TRACE, ("Query OID 0x%x(%s): Completed with status 0x%x (%d, %d)\n", 270 Oid, Oid2Str(Oid), status, *BytesWritten, *BytesNeeded)); 271 return status; 272 } 273 274 NDIS_STATUS 275 NTAPI 276 MiniportSetInformation( 277 IN NDIS_HANDLE MiniportAdapterContext, 278 IN NDIS_OID Oid, 279 IN PVOID InformationBuffer, 280 IN ULONG InformationBufferLength, 281 OUT PULONG BytesRead, 282 OUT PULONG BytesNeeded) 283 { 284 PE1000_ADAPTER Adapter = (PE1000_ADAPTER)MiniportAdapterContext; 285 ULONG genericUlong; 286 NDIS_STATUS status; 287 288 status = NDIS_STATUS_SUCCESS; 289 290 switch (Oid) 291 { 292 case OID_GEN_CURRENT_PACKET_FILTER: 293 if (InformationBufferLength < sizeof(ULONG)) 294 { 295 *BytesRead = 0; 296 *BytesNeeded = sizeof(ULONG); 297 status = NDIS_STATUS_INVALID_LENGTH; 298 break; 299 } 300 301 NdisMoveMemory(&genericUlong, InformationBuffer, sizeof(ULONG)); 302 303 if (genericUlong & 304 ~(NDIS_PACKET_TYPE_DIRECTED | 305 NDIS_PACKET_TYPE_MULTICAST | 306 NDIS_PACKET_TYPE_ALL_MULTICAST | 307 NDIS_PACKET_TYPE_BROADCAST | 308 NDIS_PACKET_TYPE_PROMISCUOUS | 309 NDIS_PACKET_TYPE_MAC_FRAME)) 310 { 311 *BytesRead = sizeof(ULONG); 312 *BytesNeeded = sizeof(ULONG); 313 status = NDIS_STATUS_NOT_SUPPORTED; 314 break; 315 } 316 317 if (Adapter->PacketFilter == genericUlong) 318 { 319 break; 320 } 321 322 Adapter->PacketFilter = genericUlong; 323 324 status = NICApplyPacketFilter(Adapter); 325 if (status != NDIS_STATUS_SUCCESS) 326 { 327 NDIS_DbgPrint(MIN_TRACE, ("Failed to apply new packet filter (0x%x)\n", status)); 328 break; 329 } 330 331 break; 332 333 case OID_GEN_CURRENT_LOOKAHEAD: 334 if (InformationBufferLength < sizeof(ULONG)) 335 { 336 *BytesRead = 0; 337 *BytesNeeded = sizeof(ULONG); 338 status = NDIS_STATUS_INVALID_LENGTH; 339 break; 340 } 341 342 NdisMoveMemory(&genericUlong, InformationBuffer, sizeof(ULONG)); 343 344 if (genericUlong > MAXIMUM_FRAME_SIZE - sizeof(ETH_HEADER)) 345 { 346 status = NDIS_STATUS_INVALID_DATA; 347 } 348 else 349 { 350 // Ignore this... 351 } 352 353 break; 354 355 case OID_802_3_MULTICAST_LIST: 356 if (InformationBufferLength % IEEE_802_ADDR_LENGTH) 357 { 358 *BytesRead = 0; 359 *BytesNeeded = InformationBufferLength + (InformationBufferLength % IEEE_802_ADDR_LENGTH); 360 status = NDIS_STATUS_INVALID_LENGTH; 361 break; 362 } 363 364 if (InformationBufferLength > sizeof(Adapter->MulticastList)) 365 { 366 *BytesNeeded = sizeof(Adapter->MulticastList); 367 *BytesRead = 0; 368 status = NDIS_STATUS_MULTICAST_FULL; 369 break; 370 } 371 372 NdisMoveMemory(Adapter->MulticastList, InformationBuffer, InformationBufferLength); 373 374 Adapter->MulticastListSize = InformationBufferLength / IEEE_802_ADDR_LENGTH; 375 376 NICUpdateMulticastList(Adapter); 377 break; 378 379 default: 380 NDIS_DbgPrint(MIN_TRACE, ("Unknown OID 0x%x(%s)\n", Oid, Oid2Str(Oid))); 381 status = NDIS_STATUS_NOT_SUPPORTED; 382 *BytesRead = 0; 383 *BytesNeeded = 0; 384 break; 385 } 386 387 if (status == NDIS_STATUS_SUCCESS) 388 { 389 *BytesRead = InformationBufferLength; 390 *BytesNeeded = 0; 391 } 392 393 return status; 394 } 395 396