diff --git a/drivers/net/dwc_eqos/device.cpp b/drivers/net/dwc_eqos/device.cpp index 5e2e915..97c1fdb 100644 --- a/drivers/net/dwc_eqos/device.cpp +++ b/drivers/net/dwc_eqos/device.cpp @@ -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 }; @@ -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); diff --git a/drivers/net/dwc_eqos/device.h b/drivers/net/dwc_eqos/device.h index 83495cb..94c0733 100644 --- a/drivers/net/dwc_eqos/device.h +++ b/drivers/net/dwc_eqos/device.h @@ -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. diff --git a/drivers/net/dwc_eqos/driver.cpp b/drivers/net/dwc_eqos/driver.cpp index af8e9fa..ebb1588 100644 --- a/drivers/net/dwc_eqos/driver.cpp +++ b/drivers/net/dwc_eqos/driver.cpp @@ -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. diff --git a/drivers/net/dwc_eqos/dwc_eqos.inf b/drivers/net/dwc_eqos/dwc_eqos.inf index 2cc5d00..2e54266 100644 --- a/drivers/net/dwc_eqos/dwc_eqos.inf +++ b/drivers/net/dwc_eqos/dwc_eqos.inf @@ -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" diff --git a/drivers/net/dwc_eqos/rxqueue.cpp b/drivers/net/dwc_eqos/rxqueue.cpp index e84d152..8051836 100644 --- a/drivers/net/dwc_eqos/rxqueue.cpp +++ b/drivers/net/dwc_eqos/rxqueue.cpp @@ -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; @@ -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); @@ -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) { @@ -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 = {}; @@ -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, diff --git a/drivers/net/dwc_eqos/rxqueue.h b/drivers/net/dwc_eqos/rxqueue.h index 0b2caf9..7a0fa7f 100644 --- a/drivers/net/dwc_eqos/rxqueue.h +++ b/drivers/net/dwc_eqos/rxqueue.h @@ -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)