Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

dwc_eqos - support 9014-byte jumbo frames #36

Merged
merged 1 commit into from
Jan 11, 2024
Merged
Show file tree
Hide file tree
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
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