xref: /reactos/drivers/network/dd/e1000/send.c (revision 144e984b)
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
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