Skip to content
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -531,9 +531,18 @@ private void StartRx()
writeBackStructure.OuterVlanTag = 0x0;
writeBackStructure.InnerVlanTag = 0x0;
writeBackStructure.OamSubtypeCodeOrMACControlPacketOpcode = (uint)frame.UnderlyingPacket.Type;
writeBackStructure.IpHeaderError = false;
writeBackStructure.Ipv4HeaderPresent = frame.UnderlyingPacket.Type == EthernetPacketType.IpV4;
writeBackStructure.Ipv6HeaderPresent = frame.UnderlyingPacket.Type == EthernetPacketType.IpV6;

// Validate IP header checksum if checksum offload is enabled
writeBackStructure.IpHeaderError = false;
writeBackStructure.IpChecksumBypassed = !parent.checksumOffloadEnable.Value;
if(parent.checksumOffloadEnable.Value && writeBackStructure.Ipv4HeaderPresent)
{
var ipv4Packet = (IPv4Packet)frame.UnderlyingPacket.PayloadPacket;
writeBackStructure.IpHeaderError = !ipv4Packet.ValidChecksum;
}

if(writeBackStructure.Ipv4HeaderPresent || writeBackStructure.Ipv6HeaderPresent)
{
switch(((IpPacket)frame.UnderlyingPacket.PayloadPacket).NextHeader)
Expand Down Expand Up @@ -622,6 +631,27 @@ private void StartRx()
writeBackStructure.ReceiveWatchdogTimeout = false;
writeBackStructure.GiantPacket = false;
writeBackStructure.CrcError = parent.crcCheckDisable.Value ? false : !EthernetFrame.CheckCRC(bytes);

// Validate payload checksum if checksum offload is enabled
writeBackStructure.IpPayloadError = false;
if(parent.checksumOffloadEnable.Value && (writeBackStructure.Ipv4HeaderPresent || writeBackStructure.Ipv6HeaderPresent))
{
var ipPacket = (IpPacket)frame.UnderlyingPacket.PayloadPacket;
if(ipPacket.PayloadPacket is TcpPacket tcpPacket)
{
writeBackStructure.IpPayloadError = !tcpPacket.ValidChecksum;
}
else if(ipPacket.PayloadPacket is UdpPacket udpPacket)
{
// UDP checksum is optional in IPv4, mandatory in IPv6
if(udpPacket.Checksum != 0 || writeBackStructure.Ipv6HeaderPresent)
{
writeBackStructure.IpPayloadError = !udpPacket.ValidChecksum;
}
}
// Note: ICMP checksum validation could be added here if PacketDotNet supports it
}

writeBackStructure.ErrorSummary = new bool[]
{
writeBackStructure.DribbleBitError,
Expand Down Expand Up @@ -777,7 +807,7 @@ private void StartTx()
buffer,
(uint)maximumSegmentSize.Value,
latestTxContext,
parent.checksumOffloadEnable.Value,
true, // TSO always requires checksum offload
parent.SendFrame,
sourceAddress
);
Expand All @@ -789,7 +819,7 @@ private void StartTx()
frameAssembler = new FrameAssembler(
parent,
structure.CrcPadControl,
parent.checksumOffloadEnable.Value ? structure.ChecksumControl : ChecksumOperation.None,
structure.ChecksumControl, // TX checksum insertion is controlled by descriptor CIC field, not MACCR.IPC (RX-only)
parent.SendFrame
);
}
Expand Down Expand Up @@ -847,6 +877,7 @@ private void StartTx()
writeBackStructure.LateCollision = false;
writeBackStructure.NoCarrier = false;
writeBackStructure.LossOfCarrier = false;
// Payload checksum errors are reported on RX path, not TX
writeBackStructure.PayloadChecksumError = false;
writeBackStructure.PacketFlushed = false;
writeBackStructure.JabberTimeout = false;
Expand Down