mirror of
https://github.com/acidanthera/audk.git
synced 2025-07-01 10:54:27 +02:00
OvmfPkg/VirtioNetDxe: map VRINGs using VirtioRingMap()
When device is behind the IOMMU then driver need to pass the device address when programing the bus master. The patch uses VirtioRingMap() to map the VRING system physical address[es] to device address[es]. Cc: Ard Biesheuvel <ard.biesheuvel@linaro.org> Cc: Jordan Justen <jordan.l.justen@intel.com> Cc: Tom Lendacky <thomas.lendacky@amd.com> Cc: Laszlo Ersek <lersek@redhat.com> Contributed-under: TianoCore Contribution Agreement 1.1 Signed-off-by: Brijesh Singh <brijesh.singh@amd.com> Reviewed-by: Laszlo Ersek <lersek@redhat.com> Regression-tested-by: Laszlo Ersek <lersek@redhat.com> Tested-by: Laszlo Ersek <lersek@redhat.com>
This commit is contained in:
parent
55dd5a673b
commit
940baec09c
@ -35,11 +35,13 @@
|
|||||||
the network device.
|
the network device.
|
||||||
@param[out] Ring The virtio-ring inside the VNET_DEV structure,
|
@param[out] Ring The virtio-ring inside the VNET_DEV structure,
|
||||||
corresponding to Selector.
|
corresponding to Selector.
|
||||||
|
@param[out] Mapping A resulting token to pass to VirtioNetUninitRing()
|
||||||
|
|
||||||
@retval EFI_UNSUPPORTED The queue size reported by the virtio-net device is
|
@retval EFI_UNSUPPORTED The queue size reported by the virtio-net device is
|
||||||
too small.
|
too small.
|
||||||
@return Status codes from VIRTIO_CFG_WRITE(),
|
@return Status codes from VIRTIO_CFG_WRITE(),
|
||||||
VIRTIO_CFG_READ() and VirtioRingInit().
|
VIRTIO_CFG_READ(), VirtioRingInit() and
|
||||||
|
VirtioRingMap().
|
||||||
@retval EFI_SUCCESS Ring initialized.
|
@retval EFI_SUCCESS Ring initialized.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
@ -49,11 +51,14 @@ EFIAPI
|
|||||||
VirtioNetInitRing (
|
VirtioNetInitRing (
|
||||||
IN OUT VNET_DEV *Dev,
|
IN OUT VNET_DEV *Dev,
|
||||||
IN UINT16 Selector,
|
IN UINT16 Selector,
|
||||||
OUT VRING *Ring
|
OUT VRING *Ring,
|
||||||
|
OUT VOID **Mapping
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
EFI_STATUS Status;
|
EFI_STATUS Status;
|
||||||
UINT16 QueueSize;
|
UINT16 QueueSize;
|
||||||
|
UINT64 RingBaseShift;
|
||||||
|
VOID *MapInfo;
|
||||||
|
|
||||||
//
|
//
|
||||||
// step 4b -- allocate selected queue
|
// step 4b -- allocate selected queue
|
||||||
@ -80,29 +85,42 @@ VirtioNetInitRing (
|
|||||||
}
|
}
|
||||||
|
|
||||||
//
|
//
|
||||||
// Additional steps for MMIO: align the queue appropriately, and set the
|
// If anything fails from here on, we must release the ring resources.
|
||||||
// size. If anything fails from here on, we must release the ring resources.
|
|
||||||
//
|
//
|
||||||
Status = Dev->VirtIo->SetQueueNum (Dev->VirtIo, QueueSize);
|
Status = VirtioRingMap (Dev->VirtIo, Ring, &RingBaseShift, &MapInfo);
|
||||||
if (EFI_ERROR (Status)) {
|
if (EFI_ERROR (Status)) {
|
||||||
goto ReleaseQueue;
|
goto ReleaseQueue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Additional steps for MMIO: align the queue appropriately, and set the
|
||||||
|
// size. If anything fails from here on, we must unmap the ring resources.
|
||||||
|
//
|
||||||
|
Status = Dev->VirtIo->SetQueueNum (Dev->VirtIo, QueueSize);
|
||||||
|
if (EFI_ERROR (Status)) {
|
||||||
|
goto UnmapQueue;
|
||||||
|
}
|
||||||
|
|
||||||
Status = Dev->VirtIo->SetQueueAlign (Dev->VirtIo, EFI_PAGE_SIZE);
|
Status = Dev->VirtIo->SetQueueAlign (Dev->VirtIo, EFI_PAGE_SIZE);
|
||||||
if (EFI_ERROR (Status)) {
|
if (EFI_ERROR (Status)) {
|
||||||
goto ReleaseQueue;
|
goto UnmapQueue;
|
||||||
}
|
}
|
||||||
|
|
||||||
//
|
//
|
||||||
// step 4c -- report GPFN (guest-physical frame number) of queue
|
// step 4c -- report GPFN (guest-physical frame number) of queue
|
||||||
//
|
//
|
||||||
Status = Dev->VirtIo->SetQueueAddress (Dev->VirtIo, Ring, 0);
|
Status = Dev->VirtIo->SetQueueAddress (Dev->VirtIo, Ring, RingBaseShift);
|
||||||
if (EFI_ERROR (Status)) {
|
if (EFI_ERROR (Status)) {
|
||||||
goto ReleaseQueue;
|
goto UnmapQueue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
*Mapping = MapInfo;
|
||||||
|
|
||||||
return EFI_SUCCESS;
|
return EFI_SUCCESS;
|
||||||
|
|
||||||
|
UnmapQueue:
|
||||||
|
Dev->VirtIo->UnmapSharedBuffer (Dev->VirtIo, MapInfo);
|
||||||
|
|
||||||
ReleaseQueue:
|
ReleaseQueue:
|
||||||
VirtioRingUninit (Dev->VirtIo, Ring);
|
VirtioRingUninit (Dev->VirtIo, Ring);
|
||||||
|
|
||||||
@ -456,12 +474,22 @@ VirtioNetInitialize (
|
|||||||
//
|
//
|
||||||
// step 4b, 4c -- allocate and report virtqueues
|
// step 4b, 4c -- allocate and report virtqueues
|
||||||
//
|
//
|
||||||
Status = VirtioNetInitRing (Dev, VIRTIO_NET_Q_RX, &Dev->RxRing);
|
Status = VirtioNetInitRing (
|
||||||
|
Dev,
|
||||||
|
VIRTIO_NET_Q_RX,
|
||||||
|
&Dev->RxRing,
|
||||||
|
&Dev->RxRingMap
|
||||||
|
);
|
||||||
if (EFI_ERROR (Status)) {
|
if (EFI_ERROR (Status)) {
|
||||||
goto DeviceFailed;
|
goto DeviceFailed;
|
||||||
}
|
}
|
||||||
|
|
||||||
Status = VirtioNetInitRing (Dev, VIRTIO_NET_Q_TX, &Dev->TxRing);
|
Status = VirtioNetInitRing (
|
||||||
|
Dev,
|
||||||
|
VIRTIO_NET_Q_TX,
|
||||||
|
&Dev->TxRing,
|
||||||
|
&Dev->TxRingMap
|
||||||
|
);
|
||||||
if (EFI_ERROR (Status)) {
|
if (EFI_ERROR (Status)) {
|
||||||
goto ReleaseRxRing;
|
goto ReleaseRxRing;
|
||||||
}
|
}
|
||||||
@ -510,10 +538,10 @@ AbortDevice:
|
|||||||
Dev->VirtIo->SetDeviceStatus (Dev->VirtIo, 0);
|
Dev->VirtIo->SetDeviceStatus (Dev->VirtIo, 0);
|
||||||
|
|
||||||
ReleaseTxRing:
|
ReleaseTxRing:
|
||||||
VirtioNetUninitRing (Dev, &Dev->TxRing);
|
VirtioNetUninitRing (Dev, &Dev->TxRing, Dev->TxRingMap);
|
||||||
|
|
||||||
ReleaseRxRing:
|
ReleaseRxRing:
|
||||||
VirtioNetUninitRing (Dev, &Dev->RxRing);
|
VirtioNetUninitRing (Dev, &Dev->RxRing, Dev->RxRingMap);
|
||||||
|
|
||||||
DeviceFailed:
|
DeviceFailed:
|
||||||
//
|
//
|
||||||
|
@ -55,15 +55,19 @@ VirtioNetShutdownTx (
|
|||||||
/**
|
/**
|
||||||
Release TX and RX VRING resources.
|
Release TX and RX VRING resources.
|
||||||
|
|
||||||
@param[in,out] Dev The VNET_DEV driver instance which was using the ring.
|
@param[in,out] Dev The VNET_DEV driver instance which was using
|
||||||
@param[in,out] Ring The virtio ring to clean up.
|
the ring.
|
||||||
|
@param[in,out] Ring The virtio ring to clean up.
|
||||||
|
@param[in] RingMap A token return from the VirtioRingMap()
|
||||||
*/
|
*/
|
||||||
VOID
|
VOID
|
||||||
EFIAPI
|
EFIAPI
|
||||||
VirtioNetUninitRing (
|
VirtioNetUninitRing (
|
||||||
IN OUT VNET_DEV *Dev,
|
IN OUT VNET_DEV *Dev,
|
||||||
IN OUT VRING *Ring
|
IN OUT VRING *Ring,
|
||||||
|
IN VOID *RingMap
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
|
Dev->VirtIo->UnmapSharedBuffer (Dev->VirtIo, RingMap);
|
||||||
VirtioRingUninit (Dev->VirtIo, Ring);
|
VirtioRingUninit (Dev->VirtIo, Ring);
|
||||||
}
|
}
|
||||||
|
@ -67,8 +67,8 @@ VirtioNetShutdown (
|
|||||||
Dev->VirtIo->SetDeviceStatus (Dev->VirtIo, 0);
|
Dev->VirtIo->SetDeviceStatus (Dev->VirtIo, 0);
|
||||||
VirtioNetShutdownRx (Dev);
|
VirtioNetShutdownRx (Dev);
|
||||||
VirtioNetShutdownTx (Dev);
|
VirtioNetShutdownTx (Dev);
|
||||||
VirtioNetUninitRing (Dev, &Dev->TxRing);
|
VirtioNetUninitRing (Dev, &Dev->TxRing, Dev->TxRingMap);
|
||||||
VirtioNetUninitRing (Dev, &Dev->RxRing);
|
VirtioNetUninitRing (Dev, &Dev->RxRing, Dev->RxRingMap);
|
||||||
|
|
||||||
Dev->Snm.State = EfiSimpleNetworkStarted;
|
Dev->Snm.State = EfiSimpleNetworkStarted;
|
||||||
Status = EFI_SUCCESS;
|
Status = EFI_SUCCESS;
|
||||||
|
@ -70,8 +70,9 @@ faithfully indented) that implement the transition.
|
|||||||
VirtioNetInitialize | | VirtioNetShutdown
|
VirtioNetInitialize | | VirtioNetShutdown
|
||||||
VirtioNetInitRing {Rx, Tx} | | VirtioNetShutdownRx [SnpSharedHelpers.c]
|
VirtioNetInitRing {Rx, Tx} | | VirtioNetShutdownRx [SnpSharedHelpers.c]
|
||||||
VirtioRingInit | | VirtioNetShutdownTx [SnpSharedHelpers.c]
|
VirtioRingInit | | VirtioNetShutdownTx [SnpSharedHelpers.c]
|
||||||
VirtioNetInitTx | | VirtioNetUninitRing [SnpSharedHelpers.c]
|
VirtioRingMap | | VirtioNetUninitRing [SnpSharedHelpers.c]
|
||||||
VirtioNetInitRx | | {Tx, Rx}
|
VirtioNetInitTx | | {Tx, Rx}
|
||||||
|
VirtioNetInitRx | | VirtIo->UnmapSharedBuffer
|
||||||
| | VirtioRingUninit
|
| | VirtioRingUninit
|
||||||
v |
|
v |
|
||||||
+-----------------------------+
|
+-----------------------------+
|
||||||
|
@ -82,10 +82,14 @@ typedef struct {
|
|||||||
EFI_HANDLE MacHandle; // VirtioNetDriverBindingStart
|
EFI_HANDLE MacHandle; // VirtioNetDriverBindingStart
|
||||||
|
|
||||||
VRING RxRing; // VirtioNetInitRing
|
VRING RxRing; // VirtioNetInitRing
|
||||||
|
VOID *RxRingMap; // VirtioRingMap and
|
||||||
|
// VirtioNetInitRing
|
||||||
UINT8 *RxBuf; // VirtioNetInitRx
|
UINT8 *RxBuf; // VirtioNetInitRx
|
||||||
UINT16 RxLastUsed; // VirtioNetInitRx
|
UINT16 RxLastUsed; // VirtioNetInitRx
|
||||||
|
|
||||||
VRING TxRing; // VirtioNetInitRing
|
VRING TxRing; // VirtioNetInitRing
|
||||||
|
VOID *TxRingMap; // VirtioRingMap and
|
||||||
|
// VirtioNetInitRing
|
||||||
UINT16 TxMaxPending; // VirtioNetInitTx
|
UINT16 TxMaxPending; // VirtioNetInitTx
|
||||||
UINT16 TxCurPending; // VirtioNetInitTx
|
UINT16 TxCurPending; // VirtioNetInitTx
|
||||||
UINT16 *TxFreeStack; // VirtioNetInitTx
|
UINT16 *TxFreeStack; // VirtioNetInitTx
|
||||||
@ -267,7 +271,8 @@ VOID
|
|||||||
EFIAPI
|
EFIAPI
|
||||||
VirtioNetUninitRing (
|
VirtioNetUninitRing (
|
||||||
IN OUT VNET_DEV *Dev,
|
IN OUT VNET_DEV *Dev,
|
||||||
IN OUT VRING *Ring
|
IN OUT VRING *Ring,
|
||||||
|
IN VOID *RingMap
|
||||||
);
|
);
|
||||||
|
|
||||||
//
|
//
|
||||||
|
Loading…
x
Reference in New Issue
Block a user