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