1 /* 2 * ReactOS Realtek 8139 Driver 3 * 4 * Copyright (C) 2013 Cameron Gutman 5 * 6 * This program is free software; you can redistribute it and/or modify 7 * it under the terms of the GNU General Public License as published by 8 * the Free Software Foundation; either version 2 of the License, or 9 * (at your option) any later version. 10 * 11 * This program is distributed in the hope that it will be useful, 12 * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 * GNU General Public License for more details. 15 * 16 * You should have received a copy of the GNU General Public License along 17 * with this program; if not, write to the Free Software Foundation, Inc., 18 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. 19 * 20 */ 21 22 #include "nic.h" 23 24 #define NDEBUG 25 #include <debug.h> 26 27 static ULONG SupportedOidList[] = 28 { 29 OID_GEN_SUPPORTED_LIST, 30 OID_GEN_HARDWARE_STATUS, 31 OID_GEN_MEDIA_SUPPORTED, 32 OID_GEN_MEDIA_IN_USE, 33 OID_GEN_MAXIMUM_LOOKAHEAD, 34 OID_GEN_MAXIMUM_FRAME_SIZE, 35 OID_GEN_LINK_SPEED, 36 OID_GEN_TRANSMIT_BUFFER_SPACE, 37 OID_GEN_RECEIVE_BUFFER_SPACE, 38 OID_GEN_RECEIVE_BLOCK_SIZE, 39 OID_GEN_TRANSMIT_BLOCK_SIZE, 40 OID_GEN_VENDOR_ID, 41 OID_GEN_VENDOR_DESCRIPTION, 42 OID_GEN_VENDOR_DRIVER_VERSION, 43 OID_GEN_CURRENT_PACKET_FILTER, 44 OID_GEN_CURRENT_LOOKAHEAD, 45 OID_GEN_DRIVER_VERSION, 46 OID_GEN_MAXIMUM_TOTAL_SIZE, 47 OID_GEN_PROTOCOL_OPTIONS, 48 OID_GEN_MAC_OPTIONS, 49 OID_GEN_MEDIA_CONNECT_STATUS, 50 OID_GEN_MAXIMUM_SEND_PACKETS, 51 OID_GEN_XMIT_OK, 52 OID_GEN_RCV_OK, 53 OID_GEN_XMIT_ERROR, 54 OID_GEN_RCV_ERROR, 55 OID_GEN_RCV_NO_BUFFER, 56 OID_GEN_RCV_CRC_ERROR, 57 OID_802_3_PERMANENT_ADDRESS, 58 OID_802_3_CURRENT_ADDRESS, 59 OID_802_3_MULTICAST_LIST, 60 OID_802_3_MAXIMUM_LIST_SIZE, 61 OID_802_3_MAC_OPTIONS, 62 OID_802_3_RCV_ERROR_ALIGNMENT, 63 OID_802_3_XMIT_ONE_COLLISION, 64 OID_802_3_XMIT_MORE_COLLISIONS 65 }; 66 67 NDIS_STATUS 68 NTAPI 69 MiniportQueryInformation ( 70 IN NDIS_HANDLE MiniportAdapterContext, 71 IN NDIS_OID Oid, 72 IN PVOID InformationBuffer, 73 IN ULONG InformationBufferLength, 74 OUT PULONG BytesWritten, 75 OUT PULONG BytesNeeded 76 ) 77 { 78 PRTL_ADAPTER adapter = (PRTL_ADAPTER)MiniportAdapterContext; 79 ULONG genericUlong; 80 ULONG copyLength; 81 PVOID copySource; 82 NDIS_STATUS status; 83 84 status = NDIS_STATUS_SUCCESS; 85 copySource = &genericUlong; 86 copyLength = sizeof(ULONG); 87 88 NdisAcquireSpinLock(&adapter->Lock); 89 90 switch (Oid) 91 { 92 case OID_GEN_SUPPORTED_LIST: 93 copySource = (PVOID)&SupportedOidList; 94 copyLength = sizeof(SupportedOidList); 95 break; 96 97 case OID_GEN_CURRENT_PACKET_FILTER: 98 genericUlong = adapter->PacketFilter; 99 break; 100 101 case OID_GEN_HARDWARE_STATUS: 102 genericUlong = (ULONG)NdisHardwareStatusReady; //FIXME 103 break; 104 105 case OID_GEN_MEDIA_SUPPORTED: 106 case OID_GEN_MEDIA_IN_USE: 107 { 108 static const NDIS_MEDIUM medium = NdisMedium802_3; 109 copySource = (PVOID)&medium; 110 copyLength = sizeof(medium); 111 break; 112 } 113 114 case OID_GEN_RECEIVE_BLOCK_SIZE: 115 case OID_GEN_TRANSMIT_BLOCK_SIZE: 116 case OID_GEN_CURRENT_LOOKAHEAD: 117 case OID_GEN_MAXIMUM_LOOKAHEAD: 118 case OID_GEN_MAXIMUM_FRAME_SIZE: 119 genericUlong = MAXIMUM_FRAME_SIZE - sizeof(ETH_HEADER); 120 break; 121 122 case OID_GEN_LINK_SPEED: 123 genericUlong = adapter->LinkSpeedMbps * 1000; 124 break; 125 126 case OID_GEN_TRANSMIT_BUFFER_SPACE: 127 genericUlong = MAXIMUM_FRAME_SIZE; 128 break; 129 130 case OID_GEN_RECEIVE_BUFFER_SPACE: 131 genericUlong = RECEIVE_BUFFER_SIZE; 132 break; 133 134 case OID_GEN_VENDOR_ID: 135 // 136 // The 3 bytes of the MAC address is the vendor ID 137 // 138 genericUlong = 0; 139 genericUlong |= (adapter->PermanentMacAddress[0] << 16); 140 genericUlong |= (adapter->PermanentMacAddress[1] << 8); 141 genericUlong |= (adapter->PermanentMacAddress[2] & 0xFF); 142 break; 143 144 case OID_GEN_VENDOR_DESCRIPTION: 145 { 146 static UCHAR vendorDesc[] = "ReactOS Team"; 147 copySource = vendorDesc; 148 copyLength = sizeof(vendorDesc); 149 break; 150 } 151 152 case OID_GEN_VENDOR_DRIVER_VERSION: 153 genericUlong = DRIVER_VERSION; 154 break; 155 156 case OID_GEN_DRIVER_VERSION: 157 { 158 static const USHORT driverVersion = 159 (NDIS_MINIPORT_MAJOR_VERSION << 8) + NDIS_MINIPORT_MINOR_VERSION; 160 copySource = (PVOID)&driverVersion; 161 copyLength = sizeof(driverVersion); 162 break; 163 } 164 165 case OID_GEN_MAXIMUM_TOTAL_SIZE: 166 genericUlong = MAXIMUM_FRAME_SIZE; 167 break; 168 169 case OID_GEN_PROTOCOL_OPTIONS: 170 NDIS_DbgPrint(MIN_TRACE, ("OID_GEN_PROTOCOL_OPTIONS is unimplemented\n")); 171 status = NDIS_STATUS_NOT_SUPPORTED; 172 break; 173 174 case OID_GEN_MAC_OPTIONS: 175 genericUlong = NDIS_MAC_OPTION_RECEIVE_SERIALIZED | 176 NDIS_MAC_OPTION_COPY_LOOKAHEAD_DATA | 177 NDIS_MAC_OPTION_TRANSFERS_NOT_PEND | 178 NDIS_MAC_OPTION_NO_LOOPBACK; 179 break; 180 181 case OID_GEN_MEDIA_CONNECT_STATUS: 182 genericUlong = adapter->MediaState; 183 break; 184 185 case OID_GEN_MAXIMUM_SEND_PACKETS: 186 genericUlong = 1; 187 break; 188 189 case OID_802_3_CURRENT_ADDRESS: 190 copySource = adapter->CurrentMacAddress; 191 copyLength = IEEE_802_ADDR_LENGTH; 192 break; 193 194 case OID_802_3_PERMANENT_ADDRESS: 195 copySource = adapter->PermanentMacAddress; 196 copyLength = IEEE_802_ADDR_LENGTH; 197 break; 198 199 case OID_802_3_MAXIMUM_LIST_SIZE: 200 genericUlong = MAXIMUM_MULTICAST_ADDRESSES; 201 break; 202 203 case OID_GEN_XMIT_OK: 204 genericUlong = adapter->TransmitOk; 205 break; 206 207 case OID_GEN_RCV_OK: 208 genericUlong = adapter->ReceiveOk; 209 break; 210 211 case OID_GEN_XMIT_ERROR: 212 genericUlong = adapter->TransmitError; 213 break; 214 215 case OID_GEN_RCV_ERROR: 216 genericUlong = adapter->ReceiveError; 217 break; 218 219 case OID_GEN_RCV_NO_BUFFER: 220 genericUlong = adapter->ReceiveNoBufferSpace; 221 break; 222 223 case OID_GEN_RCV_CRC_ERROR: 224 genericUlong = adapter->ReceiveCrcError; 225 break; 226 227 case OID_802_3_RCV_ERROR_ALIGNMENT: 228 genericUlong = adapter->ReceiveAlignmentError; 229 break; 230 231 case OID_802_3_XMIT_ONE_COLLISION: 232 genericUlong = adapter->TransmitOneCollision; 233 break; 234 235 case OID_802_3_XMIT_MORE_COLLISIONS: 236 genericUlong = adapter->TransmitMoreCollisions; 237 break; 238 239 default: 240 NDIS_DbgPrint(MIN_TRACE, ("Unknown OID\n")); 241 status = NDIS_STATUS_NOT_SUPPORTED; 242 break; 243 } 244 245 if (status == NDIS_STATUS_SUCCESS) 246 { 247 if (copyLength > InformationBufferLength) 248 { 249 *BytesNeeded = copyLength; 250 *BytesWritten = 0; 251 status = NDIS_STATUS_INVALID_LENGTH; 252 } 253 else 254 { 255 NdisMoveMemory(InformationBuffer, copySource, copyLength); 256 *BytesWritten = copyLength; 257 *BytesNeeded = copyLength; 258 } 259 } 260 else 261 { 262 *BytesWritten = 0; 263 *BytesNeeded = 0; 264 } 265 266 NdisReleaseSpinLock(&adapter->Lock); 267 268 NDIS_DbgPrint(MAX_TRACE, ("Query OID 0x%x: Completed with status 0x%x (%d, %d)\n", 269 Oid, status, *BytesWritten, *BytesNeeded)); 270 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 { 285 PRTL_ADAPTER adapter = (PRTL_ADAPTER)MiniportAdapterContext; 286 ULONG genericUlong; 287 NDIS_STATUS status; 288 289 status = NDIS_STATUS_SUCCESS; 290 291 NdisAcquireSpinLock(&adapter->Lock); 292 293 switch (Oid) 294 { 295 case OID_GEN_CURRENT_PACKET_FILTER: 296 if (InformationBufferLength < sizeof(ULONG)) 297 { 298 *BytesRead = 0; 299 *BytesNeeded = sizeof(ULONG); 300 status = NDIS_STATUS_INVALID_LENGTH; 301 break; 302 } 303 304 NdisMoveMemory(&genericUlong, InformationBuffer, sizeof(ULONG)); 305 306 if (genericUlong & 307 (NDIS_PACKET_TYPE_ALL_FUNCTIONAL | 308 NDIS_PACKET_TYPE_FUNCTIONAL | 309 NDIS_PACKET_TYPE_GROUP | 310 NDIS_PACKET_TYPE_MAC_FRAME | 311 NDIS_PACKET_TYPE_SMT | 312 NDIS_PACKET_TYPE_SOURCE_ROUTING)) 313 { 314 *BytesRead = sizeof(ULONG); 315 *BytesNeeded = sizeof(ULONG); 316 status = NDIS_STATUS_NOT_SUPPORTED; 317 break; 318 } 319 320 adapter->PacketFilter = genericUlong; 321 322 status = NICApplyPacketFilter(adapter); 323 if (status != NDIS_STATUS_SUCCESS) 324 { 325 NDIS_DbgPrint(MIN_TRACE, ("Failed to apply new packet filter\n")); 326 break; 327 } 328 329 break; 330 331 case OID_GEN_CURRENT_LOOKAHEAD: 332 if (InformationBufferLength < sizeof(ULONG)) 333 { 334 *BytesRead = 0; 335 *BytesNeeded = sizeof(ULONG); 336 status = NDIS_STATUS_INVALID_LENGTH; 337 break; 338 } 339 340 NdisMoveMemory(&genericUlong, InformationBuffer, sizeof(ULONG)); 341 342 if (genericUlong > MAXIMUM_FRAME_SIZE - sizeof(ETH_HEADER)) 343 { 344 status = NDIS_STATUS_INVALID_DATA; 345 } 346 else 347 { 348 // Ignore this... 349 } 350 351 break; 352 353 case OID_802_3_MULTICAST_LIST: 354 if (InformationBufferLength % IEEE_802_ADDR_LENGTH) 355 { 356 *BytesRead = 0; 357 *BytesNeeded = InformationBufferLength + (InformationBufferLength % IEEE_802_ADDR_LENGTH); 358 status = NDIS_STATUS_INVALID_LENGTH; 359 break; 360 } 361 362 if (InformationBufferLength / 6 > MAXIMUM_MULTICAST_ADDRESSES) 363 { 364 *BytesNeeded = MAXIMUM_MULTICAST_ADDRESSES * IEEE_802_ADDR_LENGTH; 365 *BytesRead = 0; 366 status = NDIS_STATUS_INVALID_LENGTH; 367 break; 368 } 369 370 NdisMoveMemory(adapter->MulticastList, InformationBuffer, InformationBufferLength); 371 372 // FIXME: Write to device 373 374 break; 375 376 default: 377 NDIS_DbgPrint(MIN_TRACE, ("Unknown OID\n")); 378 status = NDIS_STATUS_NOT_SUPPORTED; 379 *BytesRead = 0; 380 *BytesNeeded = 0; 381 break; 382 } 383 384 if (status == NDIS_STATUS_SUCCESS) 385 { 386 *BytesRead = InformationBufferLength; 387 *BytesNeeded = 0; 388 } 389 390 NdisReleaseSpinLock(&adapter->Lock); 391 392 return status; 393 } 394