X-Git-Url: https://git.proxmox.com/?p=mirror_edk2.git;a=blobdiff_plain;f=OvmfPkg%2FVirtioNetDxe%2FSnpInitialize.c;h=71b67fa52df9978a1dd3e9375bf596ddc42618c8;hp=39282d9a4ac3c09bc4236356d4da625c9450e008;hb=bc8fde6f62fd038e709b4981babda0f7c7ba8418;hpb=12384f9b2657946052fab05cbe86d147124c71bf diff --git a/OvmfPkg/VirtioNetDxe/SnpInitialize.c b/OvmfPkg/VirtioNetDxe/SnpInitialize.c index 39282d9a4a..71b67fa52d 100644 --- a/OvmfPkg/VirtioNetDxe/SnpInitialize.c +++ b/OvmfPkg/VirtioNetDxe/SnpInitialize.c @@ -57,14 +57,15 @@ VirtioNetInitRing ( // // step 4b -- allocate selected queue // - Status = VIRTIO_CFG_WRITE (Dev, Generic.VhdrQueueSelect, Selector); + Status = Dev->VirtIo->SetQueueSel (Dev->VirtIo, Selector); if (EFI_ERROR (Status)) { return Status; } - Status = VIRTIO_CFG_READ (Dev, Generic.VhdrQueueSize, &QueueSize); + Status = Dev->VirtIo->GetQueueNumMax (Dev->VirtIo, &QueueSize); if (EFI_ERROR (Status)) { return Status; } + // // For each packet (RX and TX alike), we need two descriptors: // one for the virtio-net request header, and another one for the data @@ -77,14 +78,34 @@ VirtioNetInitRing ( return Status; } + // + // Additional steps for MMIO: align the queue appropriately, and set the + // size. If anything fails from here on, we must release the ring resources. + // + Status = Dev->VirtIo->SetQueueNum (Dev->VirtIo, QueueSize); + if (EFI_ERROR (Status)) { + goto ReleaseQueue; + } + + Status = Dev->VirtIo->SetQueueAlign (Dev->VirtIo, EFI_PAGE_SIZE); + if (EFI_ERROR (Status)) { + goto ReleaseQueue; + } + // // step 4c -- report GPFN (guest-physical frame number) of queue // - Status = VIRTIO_CFG_WRITE (Dev, Generic.VhdrQueueAddress, - (UINTN) Ring->Base >> EFI_PAGE_SHIFT); + Status = Dev->VirtIo->SetQueueAddress (Dev->VirtIo, + (UINT32) ((UINTN) Ring->Base >> EFI_PAGE_SHIFT)); if (EFI_ERROR (Status)) { - VirtioRingUninit (Ring); + goto ReleaseQueue; } + + return EFI_SUCCESS; + +ReleaseQueue: + VirtioRingUninit (Ring); + return Status; } @@ -120,7 +141,8 @@ VirtioNetInitTx ( { UINTN PktIdx; - Dev->TxMaxPending = MIN (Dev->TxRing.QueueSize / 2, VNET_MAX_PENDING); + Dev->TxMaxPending = (UINT16) MIN (Dev->TxRing.QueueSize / 2, + VNET_MAX_PENDING); Dev->TxCurPending = 0; Dev->TxFreeStack = AllocatePool (Dev->TxMaxPending * sizeof *Dev->TxFreeStack); @@ -141,7 +163,7 @@ VirtioNetInitTx ( Dev->TxRing.Desc[DescIdx].Addr = (UINTN) &Dev->TxSharedReq; Dev->TxRing.Desc[DescIdx].Len = sizeof Dev->TxSharedReq; Dev->TxRing.Desc[DescIdx].Flags = VRING_DESC_F_NEXT; - Dev->TxRing.Desc[DescIdx].Next = DescIdx + 1; + Dev->TxRing.Desc[DescIdx].Next = (UINT16) (DescIdx + 1); // // The second descriptor of each pending TX packet is updated on the fly, @@ -221,7 +243,7 @@ VirtioNetInitRx ( // Limit the number of pending RX packets if the queue is big. The division // by two is due to the above "two descriptors per packet" trait. // - RxAlwaysPending = MIN (Dev->RxRing.QueueSize / 2, VNET_MAX_PENDING); + RxAlwaysPending = (UINT16) MIN (Dev->RxRing.QueueSize / 2, VNET_MAX_PENDING); Dev->RxBuf = AllocatePool (RxAlwaysPending * RxBufSize); if (Dev->RxBuf == NULL) { @@ -261,11 +283,12 @@ VirtioNetInitRx ( Dev->RxRing.Desc[DescIdx].Addr = (UINTN) RxPtr; Dev->RxRing.Desc[DescIdx].Len = sizeof (VIRTIO_NET_REQ); Dev->RxRing.Desc[DescIdx].Flags = VRING_DESC_F_WRITE | VRING_DESC_F_NEXT; - Dev->RxRing.Desc[DescIdx].Next = DescIdx + 1; + 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 = RxBufSize - sizeof (VIRTIO_NET_REQ); + Dev->RxRing.Desc[DescIdx].Len = (UINT32) (RxBufSize - + sizeof (VIRTIO_NET_REQ)); Dev->RxRing.Desc[DescIdx].Flags = VRING_DESC_F_WRITE; RxPtr += Dev->RxRing.Desc[DescIdx++].Len; } @@ -285,10 +308,9 @@ VirtioNetInitRx ( // virtio-0.9.5, 2.4.1.4 Notifying the Device // MemoryFence (); - Status = VIRTIO_CFG_WRITE (Dev, Generic.VhdrQueueNotify, VIRTIO_NET_Q_RX); - + Status = Dev->VirtIo->SetQueueNotify (Dev->VirtIo, VIRTIO_NET_Q_RX); if (EFI_ERROR (Status)) { - VIRTIO_CFG_WRITE (Dev, Generic.VhdrDeviceStatus, 0); + Dev->VirtIo->SetDeviceStatus (Dev->VirtIo, 0); FreePool (Dev->RxBuf); } @@ -338,7 +360,7 @@ VirtioNetInitialize ( EFI_TPL OldTpl; EFI_STATUS Status; UINT8 NextDevStat; - UINT32 Features; + UINT64 Features; if (This == NULL) { return EFI_INVALID_PARAMETER; @@ -364,13 +386,21 @@ VirtioNetInitialize ( // virtio-0.9.5 spec, 2.2.1 Device Initialization Sequence. // NextDevStat = VSTAT_ACK; // step 2 -- acknowledge device presence - Status = VIRTIO_CFG_WRITE (Dev, Generic.VhdrDeviceStatus, NextDevStat); + Status = Dev->VirtIo->SetDeviceStatus (Dev->VirtIo, NextDevStat); if (EFI_ERROR (Status)) { goto InitFailed; } NextDevStat |= VSTAT_DRIVER; // step 3 -- we know how to drive it - Status = VIRTIO_CFG_WRITE (Dev, Generic.VhdrDeviceStatus, NextDevStat); + Status = Dev->VirtIo->SetDeviceStatus (Dev->VirtIo, NextDevStat); + if (EFI_ERROR (Status)) { + goto DeviceFailed; + } + + // + // Set Page Size - MMIO VirtIo Specific + // + Status = Dev->VirtIo->SetPageSize (Dev->VirtIo, EFI_PAGE_SIZE); if (EFI_ERROR (Status)) { goto DeviceFailed; } @@ -379,10 +409,11 @@ VirtioNetInitialize ( // step 4a -- retrieve features. Note that we're past validating required // features in VirtioNetGetFeatures(). // - Status = VIRTIO_CFG_READ (Dev, Generic.VhdrDeviceFeatureBits, &Features); + Status = Dev->VirtIo->GetDeviceFeatures (Dev->VirtIo, &Features); if (EFI_ERROR (Status)) { goto DeviceFailed; } + ASSERT (Features & VIRTIO_NET_F_MAC); ASSERT (Dev->Snm.MediaPresentSupported == !!(Features & VIRTIO_NET_F_STATUS)); @@ -404,7 +435,7 @@ VirtioNetInitialize ( // step 5 -- keep only the features we want // Features &= VIRTIO_NET_F_MAC | VIRTIO_NET_F_STATUS; - Status = VIRTIO_CFG_WRITE (Dev, Generic.VhdrGuestFeatureBits, Features); + Status = Dev->VirtIo->SetGuestFeatures (Dev->VirtIo, Features); if (EFI_ERROR (Status)) { goto ReleaseTxRing; } @@ -413,7 +444,7 @@ VirtioNetInitialize ( // step 6 -- virtio-net initialization complete // NextDevStat |= VSTAT_DRIVER_OK; - Status = VIRTIO_CFG_WRITE (Dev, Generic.VhdrDeviceStatus, NextDevStat); + Status = Dev->VirtIo->SetDeviceStatus (Dev->VirtIo, NextDevStat); if (EFI_ERROR (Status)) { goto ReleaseTxRing; } @@ -439,7 +470,7 @@ ReleaseTxAux: VirtioNetShutdownTx (Dev); AbortDevice: - VIRTIO_CFG_WRITE (Dev, Generic.VhdrDeviceStatus, 0); + Dev->VirtIo->SetDeviceStatus (Dev->VirtIo, 0); ReleaseTxRing: VirtioRingUninit (&Dev->TxRing); @@ -451,7 +482,7 @@ DeviceFailed: // // restore device status invariant for the EfiSimpleNetworkStarted state // - VIRTIO_CFG_WRITE (Dev, Generic.VhdrDeviceStatus, 0); + Dev->VirtIo->SetDeviceStatus (Dev->VirtIo, 0); InitFailed: gBS->RestoreTPL (OldTpl);