64 OUT UINT16 *Protocol OPTIONAL
80 if ((This ==
NULL) || (BufferSize ==
NULL) || (Buffer ==
NULL)) {
81 return EFI_INVALID_PARAMETER;
84 Dev = VIRTIO_NET_FROM_SNP (This);
85 OldTpl =
gBS->RaiseTPL (TPL_CALLBACK);
86 switch (Dev->Snm.
State) {
87 case EfiSimpleNetworkStopped:
88 Status = EFI_NOT_STARTED;
90 case EfiSimpleNetworkStarted:
91 Status = EFI_DEVICE_ERROR;
101 RxCurUsed = *Dev->RxRing.Used.Idx;
104 if (Dev->RxLastUsed == RxCurUsed) {
105 Status = EFI_NOT_READY;
109 UsedElemIdx = Dev->RxLastUsed % Dev->RxRing.QueueSize;
110 DescIdx = Dev->RxRing.Used.UsedElem[UsedElemIdx].Id;
111 RxLen = Dev->RxRing.Used.UsedElem[UsedElemIdx].Len;
116 ASSERT (RxLen >= Dev->RxRing.Desc[DescIdx].Len);
117 RxLen -= Dev->RxRing.Desc[DescIdx].Len;
121 ASSERT (RxLen <= Dev->RxRing.Desc[DescIdx + 1].Len);
123 OrigBufferSize = *BufferSize;
126 if (OrigBufferSize < RxLen) {
127 Status = EFI_BUFFER_TOO_SMALL;
131 if (RxLen < Dev->Snm.MediaHeaderSize) {
132 Status = EFI_DEVICE_ERROR;
136 if (HeaderSize !=
NULL) {
140 RxBufOffset = (
UINTN)(Dev->RxRing.Desc[DescIdx + 1].Addr -
141 Dev->RxBufDeviceBase);
142 RxPtr = Dev->RxBuf + RxBufOffset;
143 CopyMem (Buffer, RxPtr, RxLen);
145 if (DestAddr !=
NULL) {
146 CopyMem (DestAddr, RxPtr, SIZE_OF_VNET (Mac));
149 RxPtr += SIZE_OF_VNET (Mac);
151 if (SrcAddr !=
NULL) {
152 CopyMem (SrcAddr, RxPtr, SIZE_OF_VNET (Mac));
155 RxPtr += SIZE_OF_VNET (Mac);
157 if (Protocol !=
NULL) {
158 *Protocol = (UINT16)((RxPtr[0] << 8) | RxPtr[1]);
161 RxPtr +=
sizeof (UINT16);
171 AvailIdx = *Dev->RxRing.Avail.Idx;
172 Dev->RxRing.Avail.Ring[AvailIdx++ % Dev->RxRing.QueueSize] =
176 *Dev->RxRing.Avail.Idx = AvailIdx;
179 NotifyStatus = Dev->VirtIo->SetQueueNotify (Dev->VirtIo, VIRTIO_NET_Q_RX);
180 if (!EFI_ERROR (Status)) {
182 Status = NotifyStatus;
186 gBS->RestoreTPL (OldTpl);
VOID EFIAPI MemoryFence(VOID)
VOID *EFIAPI CopyMem(OUT VOID *DestinationBuffer, IN CONST VOID *SourceBuffer, IN UINTN Length)
EFI_STATUS EFIAPI VirtioNetReceive(IN EFI_SIMPLE_NETWORK_PROTOCOL *This, OUT UINTN *HeaderSize OPTIONAL, IN OUT UINTN *BufferSize, OUT VOID *Buffer, OUT EFI_MAC_ADDRESS *SrcAddr OPTIONAL, OUT EFI_MAC_ADDRESS *DestAddr OPTIONAL, OUT UINT16 *Protocol OPTIONAL)
VOID EFIAPI Exit(IN EFI_STATUS Status)