1 /*
2 * PROJECT: ReactOS Intel PRO/1000 Driver
3 * LICENSE: GPL-2.0-or-later (https://spdx.org/licenses/GPL-2.0-or-later)
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
NICTransmitPacket(_In_ PE1000_ADAPTER Adapter,_In_ PHYSICAL_ADDRESS PhysicalAddress,_In_ ULONG Length)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
MiniportSend(_In_ NDIS_HANDLE MiniportAdapterContext,_In_ PNDIS_PACKET Packet,_In_ UINT Flags)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