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