13f976713SDmitry Borisov /*
23f976713SDmitry Borisov * PROJECT: ReactOS Intel PRO/1000 Driver
3*e944dfa7SHermès Bélusca-Maïto * LICENSE: GPL-2.0-or-later (https://spdx.org/licenses/GPL-2.0-or-later)
43f976713SDmitry Borisov * PURPOSE: Sending packets
53f976713SDmitry Borisov * COPYRIGHT: Copyright 2018 Mark Jansen <mark.jansen@reactos.org>
63f976713SDmitry Borisov * Copyright 2019 Victor Perevertkin <victor.perevertkin@reactos.org>
73f976713SDmitry Borisov */
83f976713SDmitry Borisov
93f976713SDmitry Borisov #include "nic.h"
103f976713SDmitry Borisov
113f976713SDmitry Borisov #include <debug.h>
123f976713SDmitry Borisov
133f976713SDmitry Borisov static
143f976713SDmitry Borisov NDIS_STATUS
NICTransmitPacket(_In_ PE1000_ADAPTER Adapter,_In_ PHYSICAL_ADDRESS PhysicalAddress,_In_ ULONG Length)153f976713SDmitry Borisov NICTransmitPacket(
163f976713SDmitry Borisov _In_ PE1000_ADAPTER Adapter,
173f976713SDmitry Borisov _In_ PHYSICAL_ADDRESS PhysicalAddress,
183f976713SDmitry Borisov _In_ ULONG Length)
193f976713SDmitry Borisov {
203f976713SDmitry Borisov volatile PE1000_TRANSMIT_DESCRIPTOR TransmitDescriptor;
213f976713SDmitry Borisov
223f976713SDmitry Borisov NDIS_DbgPrint(MAX_TRACE, ("Called.\n"));
233f976713SDmitry Borisov
243f976713SDmitry Borisov TransmitDescriptor = Adapter->TransmitDescriptors + Adapter->CurrentTxDesc;
253f976713SDmitry Borisov TransmitDescriptor->Address = PhysicalAddress.QuadPart;
263f976713SDmitry Borisov TransmitDescriptor->Length = Length;
273f976713SDmitry Borisov TransmitDescriptor->ChecksumOffset = 0;
283f976713SDmitry Borisov TransmitDescriptor->Command = E1000_TDESC_CMD_RS | E1000_TDESC_CMD_IFCS |
293f976713SDmitry Borisov E1000_TDESC_CMD_EOP | E1000_TDESC_CMD_IDE;
303f976713SDmitry Borisov TransmitDescriptor->Status = 0;
313f976713SDmitry Borisov TransmitDescriptor->ChecksumStartField = 0;
323f976713SDmitry Borisov TransmitDescriptor->Special = 0;
333f976713SDmitry Borisov
343f976713SDmitry Borisov Adapter->CurrentTxDesc = (Adapter->CurrentTxDesc + 1) % NUM_TRANSMIT_DESCRIPTORS;
353f976713SDmitry Borisov
363f976713SDmitry Borisov E1000WriteUlong(Adapter, E1000_REG_TDT, Adapter->CurrentTxDesc);
373f976713SDmitry Borisov
383f976713SDmitry Borisov if (Adapter->CurrentTxDesc == Adapter->LastTxDesc)
393f976713SDmitry Borisov {
403f976713SDmitry Borisov NDIS_DbgPrint(MID_TRACE, ("All TX descriptors are full now\n"));
413f976713SDmitry Borisov Adapter->TxFull = TRUE;
423f976713SDmitry Borisov }
433f976713SDmitry Borisov
443f976713SDmitry Borisov return NDIS_STATUS_SUCCESS;
453f976713SDmitry Borisov }
463f976713SDmitry Borisov
473f976713SDmitry Borisov NDIS_STATUS
483f976713SDmitry Borisov NTAPI
MiniportSend(_In_ NDIS_HANDLE MiniportAdapterContext,_In_ PNDIS_PACKET Packet,_In_ UINT Flags)493f976713SDmitry Borisov MiniportSend(
503f976713SDmitry Borisov _In_ NDIS_HANDLE MiniportAdapterContext,
513f976713SDmitry Borisov _In_ PNDIS_PACKET Packet,
523f976713SDmitry Borisov _In_ UINT Flags)
533f976713SDmitry Borisov {
543f976713SDmitry Borisov PE1000_ADAPTER Adapter = (PE1000_ADAPTER)MiniportAdapterContext;
553f976713SDmitry Borisov PSCATTER_GATHER_LIST sgList;
563f976713SDmitry Borisov ULONG TransmitLength;
573f976713SDmitry Borisov PHYSICAL_ADDRESS TransmitBuffer;
583f976713SDmitry Borisov NDIS_STATUS Status;
593f976713SDmitry Borisov
603f976713SDmitry Borisov sgList = NDIS_PER_PACKET_INFO_FROM_PACKET(Packet, ScatterGatherListPacketInfo);
613f976713SDmitry Borisov
623f976713SDmitry Borisov ASSERT(sgList != NULL);
633f976713SDmitry Borisov ASSERT(sgList->NumberOfElements == 1);
643f976713SDmitry Borisov ASSERT((sgList->Elements[0].Address.LowPart & 3) == 0);
653f976713SDmitry Borisov ASSERT(sgList->Elements[0].Length <= MAXIMUM_FRAME_SIZE);
663f976713SDmitry Borisov
673f976713SDmitry Borisov if (Adapter->TxFull)
683f976713SDmitry Borisov {
693f976713SDmitry Borisov NDIS_DbgPrint(MIN_TRACE, ("All TX descriptors are full\n"));
703f976713SDmitry Borisov return NDIS_STATUS_RESOURCES;
713f976713SDmitry Borisov }
723f976713SDmitry Borisov
733f976713SDmitry Borisov TransmitLength = sgList->Elements[0].Length;
743f976713SDmitry Borisov TransmitBuffer = sgList->Elements[0].Address;
753f976713SDmitry Borisov Adapter->TransmitPackets[Adapter->CurrentTxDesc] = Packet;
763f976713SDmitry Borisov
773f976713SDmitry Borisov Status = NICTransmitPacket(Adapter, TransmitBuffer, TransmitLength);
783f976713SDmitry Borisov if (Status != NDIS_STATUS_SUCCESS)
793f976713SDmitry Borisov {
803f976713SDmitry Borisov NDIS_DbgPrint(MIN_TRACE, ("Transmit packet failed\n"));
813f976713SDmitry Borisov return Status;
823f976713SDmitry Borisov }
833f976713SDmitry Borisov
843f976713SDmitry Borisov return NDIS_STATUS_PENDING;
853f976713SDmitry Borisov }
86