Reactos

[E1000] Minor improvements (#3904)

- Add support for 64-bit counters (Intel gigabit NICs)
- Properly handle OIDs
- Check that the packet filter is not 0
- Performance increase

authored by

Dmitry Borisov and committed by
GitHub
3f976713 55a1c293

+274 -246
+2 -1
drivers/network/dd/e1000/CMakeLists.txt
··· 12 12 nic.h 13 13 e1000hw.h 14 14 debug.c 15 - debug.h) 15 + debug.h 16 + send.c) 16 17 17 18 add_library(e1000 MODULE ${SOURCE} e1000.rc) 18 19 add_pch(e1000 nic.h SOURCE)
+2 -105
drivers/network/dd/e1000/hardware.c
··· 53 53 0x10B5, // Intel 82546GB Quad Copper KSP3 54 54 }; 55 55 56 - 57 - static ULONG E1000WriteFlush(IN PE1000_ADAPTER Adapter) 58 - { 59 - volatile ULONG Value; 60 - 61 - NdisReadRegisterUlong(Adapter->IoBase + E1000_REG_STATUS, &Value); 62 - return Value; 63 - } 64 - 65 - VOID NTAPI E1000WriteUlong(IN PE1000_ADAPTER Adapter, IN ULONG Address, IN ULONG Value) 66 - { 67 - NdisWriteRegisterUlong((PULONG)(Adapter->IoBase + Address), Value); 68 - } 69 - 70 - VOID NTAPI E1000ReadUlong(IN PE1000_ADAPTER Adapter, IN ULONG Address, OUT PULONG Value) 71 - { 72 - NdisReadRegisterUlong((PULONG)(Adapter->IoBase + Address), Value); 73 - } 74 - 75 - static VOID E1000WriteIoUlong(IN PE1000_ADAPTER Adapter, IN ULONG Address, IN ULONG Value) 76 - { 77 - NdisRawWritePortUlong((PULONG)(Adapter->IoPort), Address); 78 - E1000WriteFlush(Adapter); 79 - NdisRawWritePortUlong((PULONG)(Adapter->IoPort + 4), Value); 80 - } 81 - 82 56 static ULONG PacketFilterToMask(ULONG PacketFilter) 83 57 { 84 58 ULONG FilterMask = 0; ··· 145 119 ULONG Mdic; 146 120 UINT n; 147 121 148 - if (Address > MAX_PHY_REG_ADDRESS) 149 - { 150 - NDIS_DbgPrint(MIN_TRACE, ("PHY Address %d is invalid\n", Address)); 151 - return 1; 152 - } 122 + ASSERT(Address <= MAX_PHY_REG_ADDRESS) 153 123 154 124 Mdic = (Address << E1000_MDIC_REGADD_SHIFT); 155 125 Mdic |= (E1000_MDIC_PHYADD_GIGABIT << E1000_MDIC_PHYADD_SHIFT); 156 126 Mdic |= E1000_MDIC_OP_READ; 157 - 158 127 E1000WriteUlong(Adapter, E1000_REG_MDIC, Mdic); 159 128 160 129 for (n = 0; n < MAX_PHY_READ_ATTEMPTS; n++) ··· 725 694 UINT n; 726 695 NDIS_DbgPrint(MAX_TRACE, ("Called.\n")); 727 696 697 + // FIXME: Use 'Adapter->MulticastListSize'? Check the datasheet 728 698 for (n = 0; n < MAXIMUM_MULTICAST_ADDRESSES; ++n) 729 699 { 730 700 ULONG Ral = *(ULONG *)Adapter->MulticastList[n].MacAddress; ··· 763 733 return NDIS_STATUS_SUCCESS; 764 734 } 765 735 766 - NDIS_STATUS 767 - NTAPI 768 - NICApplyInterruptMask( 769 - IN PE1000_ADAPTER Adapter) 770 - { 771 - NDIS_DbgPrint(MAX_TRACE, ("Called.\n")); 772 - 773 - E1000WriteUlong(Adapter, E1000_REG_IMS, Adapter->InterruptMask /*| 0x1F6DC*/); 774 - return NDIS_STATUS_SUCCESS; 775 - } 776 - 777 - NDIS_STATUS 778 - NTAPI 779 - NICDisableInterrupts( 780 - IN PE1000_ADAPTER Adapter) 781 - { 782 - NDIS_DbgPrint(MAX_TRACE, ("Called.\n")); 783 - 784 - E1000WriteUlong(Adapter, E1000_REG_IMC, ~0); 785 - return NDIS_STATUS_SUCCESS; 786 - } 787 - 788 - ULONG 789 - NTAPI 790 - NICInterruptRecognized( 791 - IN PE1000_ADAPTER Adapter, 792 - OUT PBOOLEAN InterruptRecognized) 793 - { 794 - ULONG Value; 795 - 796 - /* Reading the interrupt acknowledges them */ 797 - E1000ReadUlong(Adapter, E1000_REG_ICR, &Value); 798 - 799 - *InterruptRecognized = (Value & Adapter->InterruptMask) != 0; 800 - 801 - NDIS_DbgPrint(MAX_TRACE, ("NICInterruptRecognized(0x%x, 0x%x).\n", Value, *InterruptRecognized)); 802 - 803 - return (Value & Adapter->InterruptMask); 804 - } 805 - 806 736 VOID 807 737 NTAPI 808 738 NICUpdateLinkStatus( ··· 819 749 SpeedIndex = (DeviceStatus & E1000_STATUS_SPEEDMASK) >> E1000_STATUS_SPEEDSHIFT; 820 750 Adapter->LinkSpeedMbps = SpeedValues[SpeedIndex]; 821 751 } 822 - 823 - NDIS_STATUS 824 - NTAPI 825 - NICTransmitPacket( 826 - IN PE1000_ADAPTER Adapter, 827 - IN PHYSICAL_ADDRESS PhysicalAddress, 828 - IN ULONG Length) 829 - { 830 - volatile PE1000_TRANSMIT_DESCRIPTOR TransmitDescriptor; 831 - 832 - NDIS_DbgPrint(MAX_TRACE, ("Called.\n")); 833 - 834 - TransmitDescriptor = Adapter->TransmitDescriptors + Adapter->CurrentTxDesc; 835 - TransmitDescriptor->Address = PhysicalAddress.QuadPart; 836 - TransmitDescriptor->Length = Length; 837 - TransmitDescriptor->ChecksumOffset = 0; 838 - TransmitDescriptor->Command = E1000_TDESC_CMD_RS | E1000_TDESC_CMD_IFCS | E1000_TDESC_CMD_EOP | E1000_TDESC_CMD_IDE; 839 - TransmitDescriptor->Status = 0; 840 - TransmitDescriptor->ChecksumStartField = 0; 841 - TransmitDescriptor->Special = 0; 842 - 843 - Adapter->CurrentTxDesc = (Adapter->CurrentTxDesc + 1) % NUM_TRANSMIT_DESCRIPTORS; 844 - 845 - E1000WriteUlong(Adapter, E1000_REG_TDT, Adapter->CurrentTxDesc); 846 - 847 - if (Adapter->CurrentTxDesc == Adapter->LastTxDesc) 848 - { 849 - NDIS_DbgPrint(MID_TRACE, ("All TX descriptors are full now\n")); 850 - Adapter->TxFull = TRUE; 851 - } 852 - 853 - return NDIS_STATUS_SUCCESS; 854 - }
+105 -53
drivers/network/dd/e1000/info.c
··· 10 10 11 11 #include <debug.h> 12 12 13 - static ULONG SupportedOidList[] = 13 + static NDIS_OID SupportedOidList[] = 14 14 { 15 15 OID_GEN_SUPPORTED_LIST, 16 16 OID_GEN_CURRENT_PACKET_FILTER, ··· 37 37 OID_802_3_PERMANENT_ADDRESS, 38 38 OID_802_3_CURRENT_ADDRESS, 39 39 OID_802_3_MAXIMUM_LIST_SIZE, 40 + 40 41 /* Statistics */ 41 42 OID_GEN_XMIT_OK, 42 43 OID_GEN_RCV_OK, 43 44 OID_GEN_XMIT_ERROR, 44 45 OID_GEN_RCV_ERROR, 45 46 OID_GEN_RCV_NO_BUFFER, 47 + 48 + OID_PNP_CAPABILITIES, 46 49 }; 47 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 + } 48 70 49 71 NDIS_STATUS 50 72 NTAPI ··· 57 79 OUT PULONG BytesNeeded) 58 80 { 59 81 PE1000_ADAPTER Adapter = (PE1000_ADAPTER)MiniportAdapterContext; 60 - ULONG genericUlong; 61 82 ULONG copyLength; 62 83 PVOID copySource; 63 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; 64 93 65 94 status = NDIS_STATUS_SUCCESS; 66 - copySource = &genericUlong; 95 + copySource = &GenericInfo; 67 96 copyLength = sizeof(ULONG); 68 97 69 98 switch (Oid) ··· 74 103 break; 75 104 76 105 case OID_GEN_CURRENT_PACKET_FILTER: 77 - genericUlong = Adapter->PacketFilter; 106 + GenericInfo.Ulong = Adapter->PacketFilter; 78 107 break; 79 108 80 109 case OID_GEN_HARDWARE_STATUS: 81 110 UNIMPLEMENTED_DBGBREAK(); 82 - genericUlong = (ULONG)NdisHardwareStatusReady; //FIXME 111 + GenericInfo.Ulong = (ULONG)NdisHardwareStatusReady; //FIXME 83 112 break; 84 113 85 114 case OID_GEN_MEDIA_SUPPORTED: 86 115 case OID_GEN_MEDIA_IN_USE: 87 116 { 88 - static const NDIS_MEDIUM medium = NdisMedium802_3; 89 - copySource = (PVOID)&medium; 90 - copyLength = sizeof(medium); 117 + GenericInfo.Medium = NdisMedium802_3; 118 + copyLength = sizeof(NDIS_MEDIUM); 91 119 break; 92 120 } 93 121 ··· 96 124 case OID_GEN_CURRENT_LOOKAHEAD: 97 125 case OID_GEN_MAXIMUM_LOOKAHEAD: 98 126 case OID_GEN_MAXIMUM_FRAME_SIZE: 99 - genericUlong = MAXIMUM_FRAME_SIZE - sizeof(ETH_HEADER); 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; 100 133 break; 101 134 102 135 case OID_802_3_MAXIMUM_LIST_SIZE: 103 - genericUlong = MAXIMUM_MULTICAST_ADDRESSES; 136 + GenericInfo.Ulong = MAXIMUM_MULTICAST_ADDRESSES; 104 137 break; 105 138 106 139 case OID_GEN_LINK_SPEED: 107 - genericUlong = Adapter->LinkSpeedMbps * 10000; 140 + GenericInfo.Ulong = Adapter->LinkSpeedMbps * 10000; 108 141 break; 109 142 110 143 case OID_GEN_TRANSMIT_BUFFER_SPACE: 111 - genericUlong = MAXIMUM_FRAME_SIZE; 144 + GenericInfo.Ulong = MAXIMUM_FRAME_SIZE; 112 145 break; 113 146 114 147 case OID_GEN_RECEIVE_BUFFER_SPACE: 115 - genericUlong = RECEIVE_BUFFER_SIZE; 148 + GenericInfo.Ulong = RECEIVE_BUFFER_SIZE; 116 149 break; 117 150 118 151 case OID_GEN_VENDOR_ID: 119 152 /* 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); 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); 124 157 break; 125 158 126 159 case OID_GEN_VENDOR_DESCRIPTION: ··· 132 165 } 133 166 134 167 case OID_GEN_VENDOR_DRIVER_VERSION: 135 - genericUlong = DRIVER_VERSION; 168 + GenericInfo.Ulong = DRIVER_VERSION; 136 169 break; 137 170 138 171 case OID_GEN_DRIVER_VERSION: 139 172 { 140 - static const USHORT driverVersion = 141 - (NDIS_MINIPORT_MAJOR_VERSION << 8) + NDIS_MINIPORT_MINOR_VERSION; 142 - copySource = (PVOID)&driverVersion; 143 - copyLength = sizeof(driverVersion); 173 + copyLength = sizeof(USHORT); 174 + GenericInfo.Ushort = (NDIS_MINIPORT_MAJOR_VERSION << 8) + NDIS_MINIPORT_MINOR_VERSION; 144 175 break; 145 176 } 146 177 147 178 case OID_GEN_MAXIMUM_TOTAL_SIZE: 148 - genericUlong = MAXIMUM_FRAME_SIZE; 179 + GenericInfo.Ulong = MAXIMUM_FRAME_SIZE; 149 180 break; 150 181 151 182 case OID_GEN_MAXIMUM_SEND_PACKETS: 152 - genericUlong = 1; 183 + GenericInfo.Ulong = 1; 153 184 break; 154 185 155 186 case OID_GEN_MAC_OPTIONS: 156 - genericUlong = NDIS_MAC_OPTION_RECEIVE_SERIALIZED | 187 + GenericInfo.Ulong = NDIS_MAC_OPTION_RECEIVE_SERIALIZED | 157 188 NDIS_MAC_OPTION_COPY_LOOKAHEAD_DATA | 158 189 NDIS_MAC_OPTION_TRANSFERS_NOT_PEND | 159 190 NDIS_MAC_OPTION_NO_LOOPBACK; 160 191 break; 161 192 162 193 case OID_GEN_MEDIA_CONNECT_STATUS: 163 - genericUlong = Adapter->MediaState; 194 + GenericInfo.Ulong = Adapter->MediaState; 164 195 break; 165 - 166 196 167 197 case OID_802_3_CURRENT_ADDRESS: 168 198 copySource = Adapter->MulticastList[0].MacAddress; ··· 175 205 break; 176 206 177 207 case OID_GEN_XMIT_OK: 178 - genericUlong = 0; 179 - break; 180 208 case OID_GEN_RCV_OK: 181 - genericUlong = 0; 182 - break; 183 209 case OID_GEN_XMIT_ERROR: 184 - genericUlong = 0; 185 - break; 186 210 case OID_GEN_RCV_ERROR: 187 - genericUlong = 0; 188 - break; 189 211 case OID_GEN_RCV_NO_BUFFER: 190 - genericUlong = 0; 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); 191 239 break; 240 + } 192 241 193 242 default: 194 243 NDIS_DbgPrint(MIN_TRACE, ("Unknown OID 0x%x(%s)\n", Oid, Oid2Str(Oid))); ··· 202 251 { 203 252 *BytesNeeded = copyLength; 204 253 *BytesWritten = 0; 205 - status = NDIS_STATUS_INVALID_LENGTH; 254 + status = NDIS_STATUS_BUFFER_TOO_SHORT; 206 255 } 207 256 else 208 257 { ··· 217 266 *BytesNeeded = 0; 218 267 } 219 268 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 - 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)); 227 271 return status; 228 272 } 229 273 ··· 257 301 NdisMoveMemory(&genericUlong, InformationBuffer, sizeof(ULONG)); 258 302 259 303 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)) 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)) 266 310 { 267 311 *BytesRead = sizeof(ULONG); 268 312 *BytesNeeded = sizeof(ULONG); 269 313 status = NDIS_STATUS_NOT_SUPPORTED; 314 + break; 315 + } 316 + 317 + if (Adapter->PacketFilter == genericUlong) 318 + { 270 319 break; 271 320 } 272 321 ··· 312 361 break; 313 362 } 314 363 315 - if (InformationBufferLength / 6 > MAXIMUM_MULTICAST_ADDRESSES) 364 + if (InformationBufferLength > sizeof(Adapter->MulticastList)) 316 365 { 317 - *BytesNeeded = MAXIMUM_MULTICAST_ADDRESSES * IEEE_802_ADDR_LENGTH; 366 + *BytesNeeded = sizeof(Adapter->MulticastList); 318 367 *BytesRead = 0; 319 - status = NDIS_STATUS_INVALID_LENGTH; 368 + status = NDIS_STATUS_MULTICAST_FULL; 320 369 break; 321 370 } 322 371 323 372 NdisMoveMemory(Adapter->MulticastList, InformationBuffer, InformationBufferLength); 373 + 374 + Adapter->MulticastListSize = InformationBufferLength / IEEE_802_ADDR_LENGTH; 375 + 324 376 NICUpdateMulticastList(Adapter); 325 377 break; 326 378
+21 -8
drivers/network/dd/e1000/interrupt.c
··· 21 21 ULONG Value; 22 22 PE1000_ADAPTER Adapter = (PE1000_ADAPTER)MiniportAdapterContext; 23 23 24 - Value = NICInterruptRecognized(Adapter, InterruptRecognized); 25 - InterlockedOr(&Adapter->InterruptPending, Value); 24 + /* Reading the interrupt acknowledges them */ 25 + E1000ReadUlong(Adapter, E1000_REG_ICR, &Value); 26 26 27 - if (!(*InterruptRecognized)) 27 + Value &= Adapter->InterruptMask; 28 + _InterlockedOr(&Adapter->InterruptPending, Value); 29 + 30 + if (Value) 31 + { 32 + *InterruptRecognized = TRUE; 33 + /* Mark the events pending service */ 34 + *QueueMiniportHandleInterrupt = TRUE; 35 + } 36 + else 28 37 { 29 38 /* This is not ours. */ 39 + *InterruptRecognized = FALSE; 30 40 *QueueMiniportHandleInterrupt = FALSE; 31 - return; 32 41 } 33 - 34 - /* Mark the events pending service */ 35 - *QueueMiniportHandleInterrupt = TRUE; 36 42 } 37 43 38 44 VOID ··· 46 52 47 53 NDIS_DbgPrint(MAX_TRACE, ("Called.\n")); 48 54 49 - InterruptPending = InterlockedExchange(&Adapter->InterruptPending, 0); 55 + InterruptPending = _InterlockedExchange(&Adapter->InterruptPending, 0); 50 56 51 57 52 58 /* Link State Changed */ ··· 101 107 NDIS_DbgPrint(MIN_TRACE, ("Unrecognized ReceiveDescriptor status flag: %u\n", ReceiveDescriptor->Status)); 102 108 } 103 109 110 + /* Make sure the receive indications are enabled */ 111 + if (!Adapter->PacketFilter) 112 + { 113 + goto NextReceiveDescriptor; 114 + } 115 + 104 116 if (ReceiveDescriptor->Length != 0 && ReceiveDescriptor->Address != 0) 105 117 { 106 118 EthHeader = (PETH_HEADER)(Adapter->ReceiveBuffer + BufferOffset); ··· 120 132 NDIS_DbgPrint(MIN_TRACE, ("Got a NULL descriptor")); 121 133 } 122 134 135 + NextReceiveDescriptor: 123 136 /* Give the descriptor back */ 124 137 ReceiveDescriptor->Status = 0; 125 138
+1 -44
drivers/network/dd/e1000/ndis.c
··· 23 23 return NDIS_STATUS_FAILURE; 24 24 } 25 25 26 - NDIS_STATUS 27 - NTAPI 28 - MiniportSend( 29 - IN NDIS_HANDLE MiniportAdapterContext, 30 - IN PNDIS_PACKET Packet, 31 - IN UINT Flags) 32 - { 33 - PE1000_ADAPTER Adapter = (PE1000_ADAPTER)MiniportAdapterContext; 34 - PSCATTER_GATHER_LIST sgList = NDIS_PER_PACKET_INFO_FROM_PACKET(Packet, ScatterGatherListPacketInfo); 35 - ULONG TransmitLength; 36 - PHYSICAL_ADDRESS TransmitBuffer; 37 - NDIS_STATUS Status; 38 - 39 - ASSERT(sgList != NULL); 40 - ASSERT(sgList->NumberOfElements == 1); 41 - ASSERT((sgList->Elements[0].Address.LowPart & 3) == 0); 42 - ASSERT(sgList->Elements[0].Length <= MAXIMUM_FRAME_SIZE); 43 - 44 - if (Adapter->TxFull) 45 - { 46 - NDIS_DbgPrint(MIN_TRACE, ("All TX descriptors are full\n")); 47 - return NDIS_STATUS_RESOURCES; 48 - } 49 - 50 - TransmitLength = sgList->Elements[0].Length; 51 - TransmitBuffer = sgList->Elements[0].Address; 52 - Adapter->TransmitPackets[Adapter->CurrentTxDesc] = Packet; 53 - 54 - Status = NICTransmitPacket(Adapter, TransmitBuffer, TransmitLength); 55 - if (Status != NDIS_STATUS_SUCCESS) 56 - { 57 - NDIS_DbgPrint(MIN_TRACE, ("Transmit packet failed\n")); 58 - return Status; 59 - } 60 - 61 - return NDIS_STATUS_PENDING; 62 - } 63 - 64 26 VOID 65 27 NTAPI 66 28 MiniportHalt( ··· 264 226 265 227 /* Enable interrupts on the NIC */ 266 228 Adapter->InterruptMask = DEFAULT_INTERRUPT_MASK; 267 - Status = NICApplyInterruptMask(Adapter); 268 - if (Status != NDIS_STATUS_SUCCESS) 269 - { 270 - NDIS_DbgPrint(MIN_TRACE, ("Unable to apply interrupt mask (0x%x)\n", Status)); 271 - goto Cleanup; 272 - } 229 + NICApplyInterruptMask(Adapter); 273 230 274 231 /* Turn on TX and RX now */ 275 232 Status = NICEnableTxRx(Adapter);
+58 -35
drivers/network/dd/e1000/nic.h
··· 26 26 27 27 typedef struct _E1000_ADAPTER 28 28 { 29 + /* NIC Memory */ 30 + volatile PUCHAR IoBase; 31 + NDIS_PHYSICAL_ADDRESS IoAddress; 32 + ULONG IoLength; 33 + 29 34 // NDIS_SPIN_LOCK AdapterLock; 30 35 31 36 NDIS_HANDLE AdapterHandle; ··· 35 40 USHORT SubsystemVendorID; 36 41 37 42 UCHAR PermanentMacAddress[IEEE_802_ADDR_LENGTH]; 43 + 38 44 struct { 39 45 UCHAR MacAddress[IEEE_802_ADDR_LENGTH]; 40 46 } MulticastList[MAXIMUM_MULTICAST_ADDRESSES]; 47 + ULONG MulticastListSize; 41 48 42 49 ULONG LinkSpeedMbps; 43 50 ULONG MediaState; ··· 48 55 ULONG IoPortLength; 49 56 volatile PUCHAR IoPort; 50 57 51 - /* NIC Memory */ 52 - NDIS_PHYSICAL_ADDRESS IoAddress; 53 - ULONG IoLength; 54 - volatile PUCHAR IoBase; 55 - 56 58 /* Interrupt */ 57 59 ULONG InterruptVector; 58 60 ULONG InterruptLevel; ··· 63 65 BOOLEAN InterruptRegistered; 64 66 65 67 LONG InterruptMask; 66 - LONG InterruptPending; 68 + 69 + _Interlocked_ 70 + volatile LONG InterruptPending; 67 71 68 72 69 73 /* Transmit */ ··· 156 160 NICApplyPacketFilter( 157 161 IN PE1000_ADAPTER Adapter); 158 162 159 - NDIS_STATUS 160 - NTAPI 161 - NICApplyInterruptMask( 162 - IN PE1000_ADAPTER Adapter); 163 - 164 - NDIS_STATUS 165 - NTAPI 166 - NICDisableInterrupts( 167 - IN PE1000_ADAPTER Adapter); 168 - 169 - ULONG 170 - NTAPI 171 - NICInterruptRecognized( 172 - IN PE1000_ADAPTER Adapter, 173 - OUT PBOOLEAN InterruptRecognized); 174 - 175 163 VOID 176 164 NTAPI 177 165 NICUpdateLinkStatus( ··· 179 167 180 168 NDIS_STATUS 181 169 NTAPI 182 - NICTransmitPacket( 183 - IN PE1000_ADAPTER Adapter, 184 - IN PHYSICAL_ADDRESS PhysicalAddress, 185 - IN ULONG Length); 170 + MiniportSend( 171 + _In_ NDIS_HANDLE MiniportAdapterContext, 172 + _In_ PNDIS_PACKET Packet, 173 + _In_ UINT Flags); 186 174 187 175 NDIS_STATUS 188 176 NTAPI ··· 216 204 MiniportHandleInterrupt( 217 205 IN NDIS_HANDLE MiniportAdapterContext); 218 206 219 - 207 + FORCEINLINE 220 208 VOID 221 - NTAPI 222 209 E1000ReadUlong( 223 - IN PE1000_ADAPTER Adapter, 224 - IN ULONG Address, 225 - OUT PULONG Value); 210 + _In_ PE1000_ADAPTER Adapter, 211 + _In_ ULONG Address, 212 + _Out_ PULONG Value) 213 + { 214 + NdisReadRegisterUlong((PULONG)(Adapter->IoBase + Address), Value); 215 + } 226 216 217 + FORCEINLINE 227 218 VOID 228 - NTAPI 229 219 E1000WriteUlong( 230 - IN PE1000_ADAPTER Adapter, 231 - IN ULONG Address, 232 - IN ULONG Value); 220 + _In_ PE1000_ADAPTER Adapter, 221 + _In_ ULONG Address, 222 + _In_ ULONG Value) 223 + { 224 + NdisWriteRegisterUlong((PULONG)(Adapter->IoBase + Address), Value); 225 + } 226 + 227 + FORCEINLINE 228 + VOID 229 + E1000WriteIoUlong( 230 + _In_ PE1000_ADAPTER Adapter, 231 + _In_ ULONG Address, 232 + _In_ ULONG Value) 233 + { 234 + volatile ULONG Dummy; 235 + 236 + NdisRawWritePortUlong((PULONG)(Adapter->IoPort), Address); 237 + NdisReadRegisterUlong(Adapter->IoBase + E1000_REG_STATUS, &Dummy); 238 + NdisRawWritePortUlong((PULONG)(Adapter->IoPort + 4), Value); 239 + } 240 + 241 + FORCEINLINE 242 + VOID 243 + NICApplyInterruptMask( 244 + _In_ PE1000_ADAPTER Adapter) 245 + { 246 + E1000WriteUlong(Adapter, E1000_REG_IMS, Adapter->InterruptMask /*| 0x1F6DC*/); 247 + } 248 + 249 + FORCEINLINE 250 + VOID 251 + NICDisableInterrupts( 252 + _In_ PE1000_ADAPTER Adapter) 253 + { 254 + E1000WriteUlong(Adapter, E1000_REG_IMC, ~0); 255 + } 233 256 234 257 #endif /* _E1000_PCH_ */
+85
drivers/network/dd/e1000/send.c
··· 1 + /* 2 + * PROJECT: ReactOS Intel PRO/1000 Driver 3 + * LICENSE: GPL-2.0-or-later (https://spdx.org/licenses/GPL-2.0-or-later.html) 4 + * PURPOSE: Sending packets 5 + * COPYRIGHT: Copyright 2018 Mark Jansen <mark.jansen@reactos.org> 6 + * Copyright 2019 Victor Perevertkin <victor.perevertkin@reactos.org> 7 + */ 8 + 9 + #include "nic.h" 10 + 11 + #include <debug.h> 12 + 13 + static 14 + NDIS_STATUS 15 + NICTransmitPacket( 16 + _In_ PE1000_ADAPTER Adapter, 17 + _In_ PHYSICAL_ADDRESS PhysicalAddress, 18 + _In_ ULONG Length) 19 + { 20 + volatile PE1000_TRANSMIT_DESCRIPTOR TransmitDescriptor; 21 + 22 + NDIS_DbgPrint(MAX_TRACE, ("Called.\n")); 23 + 24 + TransmitDescriptor = Adapter->TransmitDescriptors + Adapter->CurrentTxDesc; 25 + TransmitDescriptor->Address = PhysicalAddress.QuadPart; 26 + TransmitDescriptor->Length = Length; 27 + TransmitDescriptor->ChecksumOffset = 0; 28 + TransmitDescriptor->Command = E1000_TDESC_CMD_RS | E1000_TDESC_CMD_IFCS | 29 + E1000_TDESC_CMD_EOP | E1000_TDESC_CMD_IDE; 30 + TransmitDescriptor->Status = 0; 31 + TransmitDescriptor->ChecksumStartField = 0; 32 + TransmitDescriptor->Special = 0; 33 + 34 + Adapter->CurrentTxDesc = (Adapter->CurrentTxDesc + 1) % NUM_TRANSMIT_DESCRIPTORS; 35 + 36 + E1000WriteUlong(Adapter, E1000_REG_TDT, Adapter->CurrentTxDesc); 37 + 38 + if (Adapter->CurrentTxDesc == Adapter->LastTxDesc) 39 + { 40 + NDIS_DbgPrint(MID_TRACE, ("All TX descriptors are full now\n")); 41 + Adapter->TxFull = TRUE; 42 + } 43 + 44 + return NDIS_STATUS_SUCCESS; 45 + } 46 + 47 + NDIS_STATUS 48 + NTAPI 49 + MiniportSend( 50 + _In_ NDIS_HANDLE MiniportAdapterContext, 51 + _In_ PNDIS_PACKET Packet, 52 + _In_ UINT Flags) 53 + { 54 + PE1000_ADAPTER Adapter = (PE1000_ADAPTER)MiniportAdapterContext; 55 + PSCATTER_GATHER_LIST sgList; 56 + ULONG TransmitLength; 57 + PHYSICAL_ADDRESS TransmitBuffer; 58 + NDIS_STATUS Status; 59 + 60 + sgList = NDIS_PER_PACKET_INFO_FROM_PACKET(Packet, ScatterGatherListPacketInfo); 61 + 62 + ASSERT(sgList != NULL); 63 + ASSERT(sgList->NumberOfElements == 1); 64 + ASSERT((sgList->Elements[0].Address.LowPart & 3) == 0); 65 + ASSERT(sgList->Elements[0].Length <= MAXIMUM_FRAME_SIZE); 66 + 67 + if (Adapter->TxFull) 68 + { 69 + NDIS_DbgPrint(MIN_TRACE, ("All TX descriptors are full\n")); 70 + return NDIS_STATUS_RESOURCES; 71 + } 72 + 73 + TransmitLength = sgList->Elements[0].Length; 74 + TransmitBuffer = sgList->Elements[0].Address; 75 + Adapter->TransmitPackets[Adapter->CurrentTxDesc] = Packet; 76 + 77 + Status = NICTransmitPacket(Adapter, TransmitBuffer, TransmitLength); 78 + if (Status != NDIS_STATUS_SUCCESS) 79 + { 80 + NDIS_DbgPrint(MIN_TRACE, ("Transmit packet failed\n")); 81 + return Status; 82 + } 83 + 84 + return NDIS_STATUS_PENDING; 85 + }