diff options
Diffstat (limited to 'OvmfPkg/VirtioNetDxe/SnpInitialize.c')
-rw-r--r-- | OvmfPkg/VirtioNetDxe/SnpInitialize.c | 36 |
1 files changed, 29 insertions, 7 deletions
diff --git a/OvmfPkg/VirtioNetDxe/SnpInitialize.c b/OvmfPkg/VirtioNetDxe/SnpInitialize.c index 38012a0df8..430670a980 100644 --- a/OvmfPkg/VirtioNetDxe/SnpInitialize.c +++ b/OvmfPkg/VirtioNetDxe/SnpInitialize.c @@ -138,6 +138,7 @@ VirtioNetInitTx ( IN OUT VNET_DEV *Dev
)
{
+ UINTN TxSharedReqSize;
UINTN PktIdx;
Dev->TxMaxPending = (UINT16) MIN (Dev->TxRing.QueueSize / 2,
@@ -149,6 +150,14 @@ VirtioNetInitTx ( return EFI_OUT_OF_RESOURCES;
}
+ //
+ // In VirtIo 1.0, the NumBuffers field is mandatory. In 0.9.5, it depends on
+ // VIRTIO_NET_F_MRG_RXBUF, which we never negotiate.
+ //
+ TxSharedReqSize = (Dev->VirtIo->Revision < VIRTIO_SPEC_REVISION (1, 0, 0)) ?
+ sizeof Dev->TxSharedReq.V0_9_5 :
+ sizeof Dev->TxSharedReq;
+
for (PktIdx = 0; PktIdx < Dev->TxMaxPending; ++PktIdx) {
UINT16 DescIdx;
@@ -160,7 +169,7 @@ VirtioNetInitTx ( // (unmodified by the host) virtio-net request header.
//
Dev->TxRing.Desc[DescIdx].Addr = (UINTN) &Dev->TxSharedReq;
- Dev->TxRing.Desc[DescIdx].Len = sizeof Dev->TxSharedReq;
+ Dev->TxRing.Desc[DescIdx].Len = (UINT32) TxSharedReqSize;
Dev->TxRing.Desc[DescIdx].Flags = VRING_DESC_F_NEXT;
Dev->TxRing.Desc[DescIdx].Next = (UINT16) (DescIdx + 1);
@@ -174,8 +183,13 @@ VirtioNetInitTx ( //
// virtio-0.9.5, Appendix C, Packet Transmission
//
- Dev->TxSharedReq.Flags = 0;
- Dev->TxSharedReq.GsoType = VIRTIO_NET_HDR_GSO_NONE;
+ Dev->TxSharedReq.V0_9_5.Flags = 0;
+ Dev->TxSharedReq.V0_9_5.GsoType = VIRTIO_NET_HDR_GSO_NONE;
+
+ //
+ // For VirtIo 1.0 only -- the field exists, but it is unused
+ //
+ Dev->TxSharedReq.NumBuffers = 0;
//
// virtio-0.9.5, 2.4.2 Receiving Used Buffers From the Device
@@ -223,6 +237,7 @@ VirtioNetInitRx ( )
{
EFI_STATUS Status;
+ UINTN VirtioNetReqSize;
UINTN RxBufSize;
UINT16 RxAlwaysPending;
UINTN PktIdx;
@@ -230,12 +245,20 @@ VirtioNetInitRx ( UINT8 *RxPtr;
//
+ // In VirtIo 1.0, the NumBuffers field is mandatory. In 0.9.5, it depends on
+ // VIRTIO_NET_F_MRG_RXBUF, which we never negotiate.
+ //
+ VirtioNetReqSize = (Dev->VirtIo->Revision < VIRTIO_SPEC_REVISION (1, 0, 0)) ?
+ sizeof (VIRTIO_NET_REQ) :
+ sizeof (VIRTIO_1_0_NET_REQ);
+
+ //
// For each incoming packet we must supply two descriptors:
// - the recipient for the virtio-net request header, plus
// - the recipient for the network data (which consists of Ethernet header
// and Ethernet payload).
//
- RxBufSize = sizeof (VIRTIO_NET_REQ) +
+ RxBufSize = VirtioNetReqSize +
(Dev->Snm.MediaHeaderSize + Dev->Snm.MaxPacketSize);
//
@@ -280,14 +303,13 @@ VirtioNetInitRx ( // virtio-0.9.5, 2.4.1.1 Placing Buffers into the Descriptor Table
//
Dev->RxRing.Desc[DescIdx].Addr = (UINTN) RxPtr;
- Dev->RxRing.Desc[DescIdx].Len = sizeof (VIRTIO_NET_REQ);
+ Dev->RxRing.Desc[DescIdx].Len = (UINT32) VirtioNetReqSize;
Dev->RxRing.Desc[DescIdx].Flags = VRING_DESC_F_WRITE | VRING_DESC_F_NEXT;
Dev->RxRing.Desc[DescIdx].Next = (UINT16) (DescIdx + 1);
RxPtr += Dev->RxRing.Desc[DescIdx++].Len;
Dev->RxRing.Desc[DescIdx].Addr = (UINTN) RxPtr;
- Dev->RxRing.Desc[DescIdx].Len = (UINT32) (RxBufSize -
- sizeof (VIRTIO_NET_REQ));
+ Dev->RxRing.Desc[DescIdx].Len = (UINT32) (RxBufSize - VirtioNetReqSize);
Dev->RxRing.Desc[DescIdx].Flags = VRING_DESC_F_WRITE;
RxPtr += Dev->RxRing.Desc[DescIdx++].Len;
}
|