]> git.proxmox.com Git - mirror_edk2.git/blobdiff - OvmfPkg/VirtioNetDxe/SnpInitialize.c
OvmfPkg/VirtioNetDxe: map VRINGs using VirtioRingMap()
[mirror_edk2.git] / OvmfPkg / VirtioNetDxe / SnpInitialize.c
index 430670a980f2fe7dc2033462b8b4928a8cf89fcb..8eabdbff6f5e268102f7edcb9765334a55c5654c 100644 (file)
@@ -5,6 +5,7 @@
 \r
   Copyright (C) 2013, Red Hat, Inc.\r
   Copyright (c) 2006 - 2010, Intel Corporation. All rights reserved.<BR>\r
 \r
   Copyright (C) 2013, Red Hat, Inc.\r
   Copyright (c) 2006 - 2010, Intel Corporation. All rights reserved.<BR>\r
+  Copyright (c) 2017, AMD Inc, All rights reserved.<BR>\r
 \r
   This program and the accompanying materials are licensed and made available\r
   under the terms and conditions of the BSD License which accompanies this\r
 \r
   This program and the accompanying materials are licensed and made available\r
   under the terms and conditions of the BSD License which accompanies this\r
                            the network device.\r
   @param[out]    Ring      The virtio-ring inside the VNET_DEV structure,\r
                            corresponding to Selector.\r
                            the network device.\r
   @param[out]    Ring      The virtio-ring inside the VNET_DEV structure,\r
                            corresponding to Selector.\r
+  @param[out]    Mapping   A resulting token to pass to VirtioNetUninitRing()\r
 \r
   @retval EFI_UNSUPPORTED  The queue size reported by the virtio-net device is\r
                            too small.\r
   @return                  Status codes from VIRTIO_CFG_WRITE(),\r
 \r
   @retval EFI_UNSUPPORTED  The queue size reported by the virtio-net device is\r
                            too small.\r
   @return                  Status codes from VIRTIO_CFG_WRITE(),\r
-                           VIRTIO_CFG_READ() and VirtioRingInit().\r
+                           VIRTIO_CFG_READ(), VirtioRingInit() and\r
+                           VirtioRingMap().\r
   @retval EFI_SUCCESS      Ring initialized.\r
 */\r
 \r
   @retval EFI_SUCCESS      Ring initialized.\r
 */\r
 \r
@@ -48,11 +51,14 @@ EFIAPI
 VirtioNetInitRing (\r
   IN OUT VNET_DEV *Dev,\r
   IN     UINT16   Selector,\r
 VirtioNetInitRing (\r
   IN OUT VNET_DEV *Dev,\r
   IN     UINT16   Selector,\r
-  OUT    VRING    *Ring\r
+  OUT    VRING    *Ring,\r
+  OUT    VOID     **Mapping\r
   )\r
 {\r
   EFI_STATUS Status;\r
   UINT16     QueueSize;\r
   )\r
 {\r
   EFI_STATUS Status;\r
   UINT16     QueueSize;\r
+  UINT64     RingBaseShift;\r
+  VOID       *MapInfo;\r
 \r
   //\r
   // step 4b -- allocate selected queue\r
 \r
   //\r
   // step 4b -- allocate selected queue\r
@@ -73,37 +79,50 @@ VirtioNetInitRing (
   if (QueueSize < 2) {\r
     return EFI_UNSUPPORTED;\r
   }\r
   if (QueueSize < 2) {\r
     return EFI_UNSUPPORTED;\r
   }\r
-  Status = VirtioRingInit (QueueSize, Ring);\r
+  Status = VirtioRingInit (Dev->VirtIo, QueueSize, Ring);\r
   if (EFI_ERROR (Status)) {\r
     return Status;\r
   }\r
 \r
   if (EFI_ERROR (Status)) {\r
     return Status;\r
   }\r
 \r
+  //\r
+  // If anything fails from here on, we must release the ring resources.\r
+  //\r
+  Status = VirtioRingMap (Dev->VirtIo, Ring, &RingBaseShift, &MapInfo);\r
+  if (EFI_ERROR (Status)) {\r
+    goto ReleaseQueue;\r
+  }\r
+\r
   //\r
   // Additional steps for MMIO: align the queue appropriately, and set the\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
+  // size. If anything fails from here on, we must unmap the ring resources.\r
   //\r
   Status = Dev->VirtIo->SetQueueNum (Dev->VirtIo, QueueSize);\r
   if (EFI_ERROR (Status)) {\r
   //\r
   Status = Dev->VirtIo->SetQueueNum (Dev->VirtIo, QueueSize);\r
   if (EFI_ERROR (Status)) {\r
-    goto ReleaseQueue;\r
+    goto UnmapQueue;\r
   }\r
 \r
   Status = Dev->VirtIo->SetQueueAlign (Dev->VirtIo, EFI_PAGE_SIZE);\r
   if (EFI_ERROR (Status)) {\r
   }\r
 \r
   Status = Dev->VirtIo->SetQueueAlign (Dev->VirtIo, EFI_PAGE_SIZE);\r
   if (EFI_ERROR (Status)) {\r
-    goto ReleaseQueue;\r
+    goto UnmapQueue;\r
   }\r
 \r
   //\r
   // step 4c -- report GPFN (guest-physical frame number) of queue\r
   //\r
   }\r
 \r
   //\r
   // step 4c -- report GPFN (guest-physical frame number) of queue\r
   //\r
-  Status = Dev->VirtIo->SetQueueAddress (Dev->VirtIo, Ring);\r
+  Status = Dev->VirtIo->SetQueueAddress (Dev->VirtIo, Ring, RingBaseShift);\r
   if (EFI_ERROR (Status)) {\r
   if (EFI_ERROR (Status)) {\r
-    goto ReleaseQueue;\r
+    goto UnmapQueue;\r
   }\r
 \r
   }\r
 \r
+  *Mapping = MapInfo;\r
+\r
   return EFI_SUCCESS;\r
 \r
   return EFI_SUCCESS;\r
 \r
+UnmapQueue:\r
+  Dev->VirtIo->UnmapSharedBuffer (Dev->VirtIo, MapInfo);\r
+\r
 ReleaseQueue:\r
 ReleaseQueue:\r
-  VirtioRingUninit (Ring);\r
+  VirtioRingUninit (Dev->VirtIo, Ring);\r
 \r
   return Status;\r
 }\r
 \r
   return Status;\r
 }\r
@@ -455,12 +474,22 @@ VirtioNetInitialize (
   //\r
   // step 4b, 4c -- allocate and report virtqueues\r
   //\r
   //\r
   // step 4b, 4c -- allocate and report virtqueues\r
   //\r
-  Status = VirtioNetInitRing (Dev, VIRTIO_NET_Q_RX, &Dev->RxRing);\r
+  Status = VirtioNetInitRing (\r
+             Dev,\r
+             VIRTIO_NET_Q_RX,\r
+             &Dev->RxRing,\r
+             &Dev->RxRingMap\r
+             );\r
   if (EFI_ERROR (Status)) {\r
     goto DeviceFailed;\r
   }\r
 \r
   if (EFI_ERROR (Status)) {\r
     goto DeviceFailed;\r
   }\r
 \r
-  Status = VirtioNetInitRing (Dev, VIRTIO_NET_Q_TX, &Dev->TxRing);\r
+  Status = VirtioNetInitRing (\r
+             Dev,\r
+             VIRTIO_NET_Q_TX,\r
+             &Dev->TxRing,\r
+             &Dev->TxRingMap\r
+             );\r
   if (EFI_ERROR (Status)) {\r
     goto ReleaseRxRing;\r
   }\r
   if (EFI_ERROR (Status)) {\r
     goto ReleaseRxRing;\r
   }\r
@@ -509,10 +538,10 @@ AbortDevice:
   Dev->VirtIo->SetDeviceStatus (Dev->VirtIo, 0);\r
 \r
 ReleaseTxRing:\r
   Dev->VirtIo->SetDeviceStatus (Dev->VirtIo, 0);\r
 \r
 ReleaseTxRing:\r
-  VirtioRingUninit (&Dev->TxRing);\r
+  VirtioNetUninitRing (Dev, &Dev->TxRing, Dev->TxRingMap);\r
 \r
 ReleaseRxRing:\r
 \r
 ReleaseRxRing:\r
-  VirtioRingUninit (&Dev->RxRing);\r
+  VirtioNetUninitRing (Dev, &Dev->RxRing, Dev->RxRingMap);\r
 \r
 DeviceFailed:\r
   //\r
 \r
 DeviceFailed:\r
   //\r