Skip to content

Commit

Permalink
dwc_eqos - support 9014-byte jumbo frames
Browse files Browse the repository at this point in the history
Enable support for 9014-byte jumbo frames.

- Update INF to allow JumboPacket up to 9014.
- Tell NetAdapterCx that the receive buffer size needs to be
  RoundUp8(JumboPacket + 8), where JumboPacket is set in the INF
  (default = min = 1514, max = 9014).
- Tell hardware that the receive buffer size is RoundUp8(JumboPacket + 8).

Note that using a full 9022-byte buffer for 1522-byte packets is
sub-optimal. NetAdapterCx does not currently support multi-fragment
packets if using system-managed buffering. With driver-managed buffering
we could fix this, but that probably isn't worthwhile at this point.
  • Loading branch information
idigdoug committed Jan 11, 2024
1 parent 4739f2d commit 41fb3eb
Show file tree
Hide file tree
Showing 6 changed files with 18 additions and 15 deletions.
8 changes: 5 additions & 3 deletions drivers/net/dwc_eqos/device.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ static auto constexpr QueuesSupported = 1u; // TODO: Support multiple queues?
static auto constexpr InterruptLinkStatus = 0x80000000u;
static auto constexpr InterruptChannel0StatusMask = ~InterruptLinkStatus;
static UINT16 constexpr JumboPacketMin = 1514u;
static UINT16 constexpr JumboPacketMax = RxBufferSize - 8u; // 8 == VLAN + CRC. TODO: 9014-byte jumbo frames.
static UINT16 constexpr JumboPacketMax = 9014u;

// D637828D-556C-4829-966A-237072F00FF1
static GUID constexpr DsmGuid = { 0xD637828D, 0x556C, 0x4829, 0x96, 0x6A, 0x23, 0x70, 0x72, 0xF0, 0x0F, 0xF1 };
Expand Down Expand Up @@ -1224,8 +1224,10 @@ DevicePrepareHardware(
NET_ADAPTER_TX_CAPABILITIES_INIT_FOR_DMA(&txCaps, &dmaCaps, QueuesSupported);
txCaps.MaximumNumberOfFragments = QueueDescriptorMinCount - 2; // = 1 hole in the ring + 1 context descriptor.

NET_ADAPTER_RX_CAPABILITIES rxCaps; // TODO: 9014-byte jumbo frames probably require custom buffering.
NET_ADAPTER_RX_CAPABILITIES_INIT_SYSTEM_MANAGED_DMA(&rxCaps, &dmaCaps, RxBufferSize, QueuesSupported);
// TODO: Driver-managed buffering + multi-descriptor receive would
// reduce memory overhead of Jumbo Packets.
NET_ADAPTER_RX_CAPABILITIES rxCaps;
NET_ADAPTER_RX_CAPABILITIES_INIT_SYSTEM_MANAGED_DMA(&rxCaps, &dmaCaps, context->config.RxBufferSize(), QueuesSupported);

NetAdapterSetDataPathCapabilities(context->adapter, &txCaps, &rxCaps);

Expand Down
6 changes: 6 additions & 0 deletions drivers/net/dwc_eqos/device.h
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,12 @@ struct DeviceConfig
bool txFlowControl; // Adapter configuration (Ndi\params\*FlowControl).
bool rxFlowControl; // Adapter configuration (Ndi\params\*FlowControl).
UINT16 jumboFrame; // Adapter configuration (Ndi\params\*JumboFrame). 1514..4088

UINT16 RxBufferSize() const
{
UINT16 const frameSize = jumboFrame + 8u; // 8 = VLAN + CRC.
return (frameSize + 7u) & ~7u; // Round up to multiple of 8.
}
};

// Referenced in driver.cpp DriverEntry.
Expand Down
2 changes: 0 additions & 2 deletions drivers/net/dwc_eqos/driver.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,6 @@

/*
Possible areas for improvement:
- 9014-byte jumbo frames (current limit is 4088).
This probably requires custom receive buffer management.
- Tx segmentation offload.
- Run against network test suites and fix any issues.
- Power control, wake-on-LAN, ARP offload.
Expand Down
2 changes: 1 addition & 1 deletion drivers/net/dwc_eqos/dwc_eqos.inf
Original file line number Diff line number Diff line change
Expand Up @@ -88,7 +88,7 @@ HKR, Ndi\params\*JumboPacket, ParamDesc, 0, %JumboPacket
HKR, Ndi\params\*JumboPacket, type, 0, "int"
HKR, Ndi\params\*JumboPacket, default, 0, "1514"
HKR, Ndi\params\*JumboPacket, min, 0, "1514"
HKR, Ndi\params\*JumboPacket, max, 0, "4088" ; TODO: 9014-byte jumbo frames.
HKR, Ndi\params\*JumboPacket, max, 0, "9014"

HKR, Ndi\params\*FlowControl, ParamDesc, 0, %FlowControl%
HKR, Ndi\params\*FlowControl, default, 0, "3"
Expand Down
10 changes: 6 additions & 4 deletions drivers/net/dwc_eqos/rxqueue.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ struct RxQueueContext
NET_EXTENSION packetChecksum;
NET_EXTENSION fragmentLogical;
UINT32 descCount; // A power of 2 between QueueDescriptorMinCount and QueueDescriptorMaxCount.
UINT16 rxBufferSize;
UINT8 rxPbl;
bool running;

Expand Down Expand Up @@ -75,7 +76,7 @@ RxQueueStart(_In_ NETPACKETQUEUE queue)

ChannelRxControl_t rxControl = {};
rxControl.Start = true;
rxControl.ReceiveBufferSize = RxBufferSize;
rxControl.ReceiveBufferSize = context->rxBufferSize;
rxControl.RxPbl = context->rxPbl;
Write32(&context->channelRegs->Rx_Control, rxControl);

Expand Down Expand Up @@ -143,12 +144,12 @@ RxQueueAdvance(_In_ NETPACKETQUEUE queue)

auto const frag = NetRingGetFragmentAtIndex(context->fragmentRing, fragIndex);
frag->Offset = 0;
NT_ASSERT(RxBufferSize <= frag->Capacity);
NT_ASSERT(context->rxBufferSize <= frag->Capacity);

if (descWrite.ErrorSummary ||
descWrite.ContextType ||
!descWrite.FirstDescriptor ||
!descWrite.LastDescriptor) // TODO: Jumbo frames (multi-descriptor packets)
!descWrite.LastDescriptor)
{
if (descWrite.ErrorSummary)
{
Expand Down Expand Up @@ -238,7 +239,7 @@ RxQueueAdvance(_In_ NETPACKETQUEUE queue)
break;
}

NT_ASSERT(RxBufferSize <= NetRingGetFragmentAtIndex(context->fragmentRing, fragIndex)->Capacity);
NT_ASSERT(context->rxBufferSize <= NetRingGetFragmentAtIndex(context->fragmentRing, fragIndex)->Capacity);
auto const fragLogicalAddress = NetExtensionGetFragmentLogicalAddress(&context->fragmentLogical, fragIndex)->LogicalAddress;

RxDescriptorRead descRead = {};
Expand Down Expand Up @@ -393,6 +394,7 @@ RxQueueCreate(
context->packetRing = NetRingCollectionGetPacketRing(rings);
context->fragmentRing = NetRingCollectionGetFragmentRing(rings);
context->descCount = QueueDescriptorCount(context->fragmentRing->NumberOfElements);
context->rxBufferSize = deviceConfig.RxBufferSize();
context->rxPbl = deviceConfig.rxPbl;

TraceWrite("RxQueueCreate-size", LEVEL_VERBOSE,
Expand Down
5 changes: 0 additions & 5 deletions drivers/net/dwc_eqos/rxqueue.h
Original file line number Diff line number Diff line change
Expand Up @@ -7,11 +7,6 @@ struct DeviceContext;
struct DeviceConfig;
struct ChannelRegisters;

// NetAdapterCx appears to allocate fragment buffers in multiples of PAGE_SIZE,
// so there's no reason to use a size smaller than this. 4KB buffers allow us
// to receive jumbo packets up to 4088 bytes.
auto constexpr RxBufferSize = 4096u;

// Called by device.cpp AdapterCreateRxQueue.
_IRQL_requires_same_
_IRQL_requires_(PASSIVE_LEVEL)
Expand Down

0 comments on commit 41fb3eb

Please sign in to comment.