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 } 86