VirtualBox

source: vbox/trunk/src/VBox/Devices/EFI/Firmware/VBoxPkg/E1kNetDxe/SnpTransmit.c@ 99476

最後變更 在這個檔案從99476是 89503,由 vboxsync 提交於 4 年 前

EFI/E1kNetDxe: Updates, the basic receive and transmit operations are functional and PXE booting seems to work with the limited testing done, include the driver in our image

  • 屬性 svn:eol-style 設為 native
  • 屬性 svn:keywords 設為 Author Date Id Revision
檔案大小: 5.7 KB
 
1/** @file
2
3 Implementation of the SNP.Transmit() function and its private helpers if any.
4
5 Copyright (c) 2021, Oracle and/or its affiliates.
6 Copyright (C) 2013, Red Hat, Inc.
7 Copyright (c) 2006 - 2013, Intel Corporation. All rights reserved.<BR>
8
9 SPDX-License-Identifier: BSD-2-Clause-Patent
10
11**/
12
13#include <Library/BaseLib.h>
14#include <Library/BaseMemoryLib.h>
15#include <Library/UefiBootServicesTableLib.h>
16
17#include "E1kNet.h"
18
19/**
20 Places a packet in the transmit queue of a network interface.
21
22 @param This The protocol instance pointer.
23 @param HeaderSize The size, in bytes, of the media header to be filled in by
24 the Transmit() function. If HeaderSize is non-zero, then
25 it must be equal to This->Mode->MediaHeaderSize and the
26 DestAddr and Protocol parameters must not be NULL.
27 @param BufferSize The size, in bytes, of the entire packet (media header and
28 data) to be transmitted through the network interface.
29 @param Buffer A pointer to the packet (media header followed by data) to
30 be transmitted. This parameter cannot be NULL. If
31 HeaderSize is zero, then the media header in Buffer must
32 already be filled in by the caller. If HeaderSize is
33 non-zero, then the media header will be filled in by the
34 Transmit() function.
35 @param SrcAddr The source HW MAC address. If HeaderSize is zero, then
36 this parameter is ignored. If HeaderSize is non-zero and
37 SrcAddr is NULL, then This->Mode->CurrentAddress is used
38 for the source HW MAC address.
39 @param DestAddr The destination HW MAC address. If HeaderSize is zero,
40 then this parameter is ignored.
41 @param Protocol The type of header to build. If HeaderSize is zero, then
42 this parameter is ignored. See RFC 1700, section "Ether
43 Types", for examples.
44
45 @retval EFI_SUCCESS The packet was placed on the transmit queue.
46 @retval EFI_NOT_STARTED The network interface has not been started.
47 @retval EFI_NOT_READY The network interface is too busy to accept
48 this transmit request.
49 @retval EFI_BUFFER_TOO_SMALL The BufferSize parameter is too small.
50 @retval EFI_INVALID_PARAMETER One or more of the parameters has an
51 unsupported value.
52 @retval EFI_DEVICE_ERROR The command could not be sent to the network
53 interface.
54 @retval EFI_UNSUPPORTED This function is not supported by the network
55 interface.
56
57**/
58
59EFI_STATUS
60EFIAPI
61E1kNetTransmit (
62 IN EFI_SIMPLE_NETWORK_PROTOCOL *This,
63 IN UINTN HeaderSize,
64 IN UINTN BufferSize,
65 IN /* +OUT! */ VOID *Buffer,
66 IN EFI_MAC_ADDRESS *SrcAddr OPTIONAL,
67 IN EFI_MAC_ADDRESS *DestAddr OPTIONAL,
68 IN UINT16 *Protocol OPTIONAL
69 )
70{
71 E1K_NET_DEV *Dev;
72 EFI_TPL OldTpl;
73 EFI_STATUS Status;
74 EFI_PHYSICAL_ADDRESS DeviceAddress;
75
76 DEBUG((DEBUG_INFO, "E1kNetTransmit: HeaderSize=%u BufferSize=%u Buffer=%p\n",
77 HeaderSize, BufferSize, Buffer));
78
79 if (This == NULL || BufferSize == 0 || Buffer == NULL) {
80 return EFI_INVALID_PARAMETER;
81 }
82
83 Dev = E1K_NET_FROM_SNP (This);
84 OldTpl = gBS->RaiseTPL (TPL_CALLBACK);
85 switch (Dev->Snm.State) {
86 case EfiSimpleNetworkStopped:
87 Status = EFI_NOT_STARTED;
88 goto Exit;
89 case EfiSimpleNetworkStarted:
90 Status = EFI_DEVICE_ERROR;
91 goto Exit;
92 default:
93 break;
94 }
95
96 if (BufferSize < Dev->Snm.MediaHeaderSize) {
97 Status = EFI_BUFFER_TOO_SMALL;
98 goto Exit;
99 }
100 if (BufferSize > Dev->Snm.MediaHeaderSize + Dev->Snm.MaxPacketSize) {
101 Status = EFI_INVALID_PARAMETER;
102 goto Exit;
103 }
104
105 //
106 // check if we have room for transmission
107 //
108 ASSERT (Dev->TxCurPending <= Dev->TxMaxPending);
109 if (Dev->TxCurPending == Dev->TxMaxPending) {
110 Status = EFI_NOT_READY;
111 goto Exit;
112 }
113
114 //
115 // the caller may want us to fill in the media header:
116 // dst MAC, src MAC, Ethertype
117 //
118 if (HeaderSize != 0) {
119 UINT8 *Ptr;
120
121 if (HeaderSize != Dev->Snm.MediaHeaderSize ||
122 DestAddr == NULL || Protocol == NULL) {
123 Status = EFI_INVALID_PARAMETER;
124 goto Exit;
125 }
126 Ptr = Buffer;
127 ASSERT (sizeof (E1K_NET_MAC) <= sizeof (EFI_MAC_ADDRESS));
128
129 CopyMem (Ptr, DestAddr, sizeof (E1K_NET_MAC));
130 Ptr += sizeof (E1K_NET_MAC);
131
132 CopyMem (Ptr,
133 (SrcAddr == NULL) ? &Dev->Snm.CurrentAddress : SrcAddr,
134 sizeof (E1K_NET_MAC));
135 Ptr += sizeof (E1K_NET_MAC);
136
137 *Ptr++ = (UINT8) (*Protocol >> 8);
138 *Ptr++ = (UINT8) *Protocol;
139
140 ASSERT ((UINTN) (Ptr - (UINT8 *) Buffer) == Dev->Snm.MediaHeaderSize);
141 }
142
143 //
144 // Map the transmit buffer system physical address to device address.
145 //
146 Status = E1kNetMapTxBuf (
147 Dev,
148 Buffer,
149 BufferSize,
150 &DeviceAddress
151 );
152 if (EFI_ERROR (Status)) {
153 Status = EFI_DEVICE_ERROR;
154 goto Exit;
155 }
156
157 Dev->TxCurPending++;
158 Dev->TxRing[Dev->TxLastUsed].AddrBufferLow = (UINT32)DeviceAddress;
159 Dev->TxRing[Dev->TxLastUsed].AddrBufferHigh = (UINT32)RShiftU64(DeviceAddress, 32);
160 Dev->TxRing[Dev->TxLastUsed].BufferLength = (UINT16)BufferSize;
161 Dev->TxRing[Dev->TxLastUsed].Status = 0;
162 Dev->TxRing[Dev->TxLastUsed].Command = E1K_TX_CMD_EOP | E1K_TX_CMD_FCS | E1K_TX_CMD_RS;
163
164 Dev->TxLastUsed = (Dev->TxLastUsed + 1) % E1K_NET_MAX_PENDING;
165 E1kNetRegWrite32(Dev, E1K_REG_TDT, Dev->TxLastUsed);
166
167Exit:
168 gBS->RestoreTPL (OldTpl);
169 return Status;
170}
注意: 瀏覽 TracBrowser 來幫助您使用儲存庫瀏覽器

© 2025 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette