TianoCore EDK2 master
Loading...
Searching...
No Matches
Transmit.c
Go to the documentation of this file.
1
9#include "Snp.h"
10
29 SNP_DRIVER *Snp,
30 VOID *MacHeaderPtr,
31 UINTN HeaderSize,
32 VOID *Buffer,
33 UINTN BufferSize,
34 EFI_MAC_ADDRESS *DestAddr,
35 EFI_MAC_ADDRESS *SrcAddr,
36 UINT16 *ProtocolPtr
37 )
38{
40
41 Cpb = Snp->Cpb;
42 if (SrcAddr != NULL) {
43 CopyMem (
44 (VOID *)Cpb->SrcAddr,
45 (VOID *)SrcAddr,
46 Snp->Mode.HwAddressSize
47 );
48 } else {
49 CopyMem (
50 (VOID *)Cpb->SrcAddr,
51 (VOID *)&(Snp->Mode.CurrentAddress),
52 Snp->Mode.HwAddressSize
53 );
54 }
55
56 CopyMem (
57 (VOID *)Cpb->DestAddr,
58 (VOID *)DestAddr,
59 Snp->Mode.HwAddressSize
60 );
61
62 //
63 // we need to do the byte swapping
64 //
65 Cpb->Protocol = (UINT16)PXE_SWAP_UINT16 (*ProtocolPtr);
66
67 Cpb->PacketLen = (UINT32)(BufferSize);
68 Cpb->MediaHeaderLen = (UINT16)HeaderSize;
69
70 Cpb->FragCnt = 2;
71 Cpb->reserved = 0;
72
73 Cpb->FragDesc[0].FragAddr = (UINT64)(UINTN)MacHeaderPtr;
74 Cpb->FragDesc[0].FragLen = (UINT32)HeaderSize;
75 Cpb->FragDesc[1].FragAddr = (UINT64)(UINTN)Buffer;
76 Cpb->FragDesc[1].FragLen = (UINT32)BufferSize;
77
78 Cpb->FragDesc[0].reserved = Cpb->FragDesc[1].reserved = 0;
79
80 Snp->Cdb.OpCode = PXE_OPCODE_FILL_HEADER;
81 Snp->Cdb.OpFlags = PXE_OPFLAGS_FILL_HEADER_FRAGMENTED;
82
83 Snp->Cdb.DBsize = PXE_DBSIZE_NOT_USED;
84 Snp->Cdb.DBaddr = PXE_DBADDR_NOT_USED;
85
86 Snp->Cdb.CPBsize = (UINT16)sizeof (PXE_CPB_FILL_HEADER_FRAGMENTED);
87 Snp->Cdb.CPBaddr = (UINT64)(UINTN)Cpb;
88
89 Snp->Cdb.StatCode = PXE_STATCODE_INITIALIZE;
90 Snp->Cdb.StatFlags = PXE_STATFLAGS_INITIALIZE;
91 Snp->Cdb.IFnum = Snp->IfNum;
92 Snp->Cdb.Control = PXE_CONTROL_LAST_CDB_IN_LIST;
93
94 //
95 // Issue UNDI command and check result.
96 //
97 DEBUG ((DEBUG_NET, "\nSnp->undi.fill_header() "));
98
99 (*Snp->IssueUndi32Command)((UINT64)(UINTN)&Snp->Cdb);
100
101 switch (Snp->Cdb.StatCode) {
103 return EFI_SUCCESS;
104
105 case PXE_STATCODE_INVALID_PARAMETER:
106 DEBUG (
107 (DEBUG_ERROR,
108 "\nSnp->undi.fill_header() %xh:%xh\n",
109 Snp->Cdb.StatFlags,
110 Snp->Cdb.StatCode)
111 );
112
113 return EFI_INVALID_PARAMETER;
114
115 default:
116 DEBUG (
117 (DEBUG_ERROR,
118 "\nSnp->undi.fill_header() %xh:%xh\n",
119 Snp->Cdb.StatFlags,
120 Snp->Cdb.StatCode)
121 );
122
123 return EFI_DEVICE_ERROR;
124 }
125}
126
140 SNP_DRIVER *Snp,
141 VOID *Buffer,
142 UINTN BufferSize
143 )
144{
145 PXE_CPB_TRANSMIT *Cpb;
146 EFI_STATUS Status;
147
148 Cpb = Snp->Cpb;
149 Cpb->FrameAddr = (UINT64)(UINTN)Buffer;
150 Cpb->DataLen = (UINT32)BufferSize;
151
152 Cpb->MediaheaderLen = 0;
153 Cpb->reserved = 0;
154
155 Snp->Cdb.OpFlags = PXE_OPFLAGS_TRANSMIT_WHOLE;
156
157 Snp->Cdb.CPBsize = (UINT16)sizeof (PXE_CPB_TRANSMIT);
158 Snp->Cdb.CPBaddr = (UINT64)(UINTN)Cpb;
159
160 Snp->Cdb.OpCode = PXE_OPCODE_TRANSMIT;
161 Snp->Cdb.DBsize = PXE_DBSIZE_NOT_USED;
162 Snp->Cdb.DBaddr = PXE_DBADDR_NOT_USED;
163
164 Snp->Cdb.StatCode = PXE_STATCODE_INITIALIZE;
165 Snp->Cdb.StatFlags = PXE_STATFLAGS_INITIALIZE;
166 Snp->Cdb.IFnum = Snp->IfNum;
167 Snp->Cdb.Control = PXE_CONTROL_LAST_CDB_IN_LIST;
168
169 //
170 // Issue UNDI command and check result.
171 //
172 DEBUG ((DEBUG_NET, "\nSnp->undi.transmit() "));
173 DEBUG ((DEBUG_NET, "\nSnp->Cdb.OpCode == %x", Snp->Cdb.OpCode));
174 DEBUG ((DEBUG_NET, "\nSnp->Cdb.CPBaddr == %LX", Snp->Cdb.CPBaddr));
175 DEBUG ((DEBUG_NET, "\nSnp->Cdb.DBaddr == %LX", Snp->Cdb.DBaddr));
176 DEBUG ((DEBUG_NET, "\nCpb->FrameAddr == %LX\n", Cpb->FrameAddr));
177
178 (*Snp->IssueUndi32Command)((UINT64)(UINTN)&Snp->Cdb);
179
180 DEBUG ((DEBUG_NET, "\nexit Snp->undi.transmit() "));
181
182 //
183 // we will unmap the buffers in get_status call, not here
184 //
185 switch (Snp->Cdb.StatCode) {
187 return EFI_SUCCESS;
188
189 case PXE_STATCODE_BUFFER_FULL:
190 case PXE_STATCODE_QUEUE_FULL:
191 case PXE_STATCODE_BUSY:
192 Status = EFI_NOT_READY;
193 DEBUG (
194 (DEBUG_NET,
195 "\nSnp->undi.transmit() %xh:%xh\n",
196 Snp->Cdb.StatFlags,
197 Snp->Cdb.StatCode)
198 );
199 break;
200
201 default:
202 DEBUG (
203 (DEBUG_ERROR,
204 "\nSnp->undi.transmit() %xh:%xh\n",
205 Snp->Cdb.StatFlags,
206 Snp->Cdb.StatCode)
207 );
208 Status = EFI_DEVICE_ERROR;
209 }
210
211 return Status;
212}
213
269EFIAPI
272 IN UINTN HeaderSize,
273 IN UINTN BufferSize,
274 IN VOID *Buffer,
275 IN EFI_MAC_ADDRESS *SrcAddr OPTIONAL,
276 IN EFI_MAC_ADDRESS *DestAddr OPTIONAL,
277 IN UINT16 *Protocol OPTIONAL
278 )
279{
280 SNP_DRIVER *Snp;
281 EFI_STATUS Status;
282 EFI_TPL OldTpl;
283
284 if (This == NULL) {
285 return EFI_INVALID_PARAMETER;
286 }
287
288 Snp = EFI_SIMPLE_NETWORK_DEV_FROM_THIS (This);
289
290 OldTpl = gBS->RaiseTPL (TPL_CALLBACK);
291
292 if (Snp == NULL) {
293 return EFI_DEVICE_ERROR;
294 }
295
296 switch (Snp->Mode.State) {
297 case EfiSimpleNetworkInitialized:
298 break;
299
300 case EfiSimpleNetworkStopped:
301 Status = EFI_NOT_STARTED;
302 goto ON_EXIT;
303
304 default:
305 Status = EFI_DEVICE_ERROR;
306 goto ON_EXIT;
307 }
308
309 if (Buffer == NULL) {
310 Status = EFI_INVALID_PARAMETER;
311 goto ON_EXIT;
312 }
313
314 if (BufferSize < Snp->Mode.MediaHeaderSize) {
315 Status = EFI_BUFFER_TOO_SMALL;
316 goto ON_EXIT;
317 }
318
319 //
320 // if the HeaderSize is non-zero, we need to fill up the header and for that
321 // we need the destination address and the protocol
322 //
323 if (HeaderSize != 0) {
324 if ((HeaderSize != Snp->Mode.MediaHeaderSize) || (DestAddr == 0) || (Protocol == 0)) {
325 Status = EFI_INVALID_PARAMETER;
326 goto ON_EXIT;
327 }
328
329 Status = PxeFillHeader (
330 Snp,
331 Buffer,
332 HeaderSize,
333 (UINT8 *)Buffer + HeaderSize,
334 BufferSize - HeaderSize,
335 DestAddr,
336 SrcAddr,
337 Protocol
338 );
339
340 if (EFI_ERROR (Status)) {
341 goto ON_EXIT;
342 }
343 }
344
345 Status = PxeTransmit (Snp, Buffer, BufferSize);
346
347ON_EXIT:
348 gBS->RestoreTPL (OldTpl);
349
350 return Status;
351}
UINT64 UINTN
VOID *EFIAPI CopyMem(OUT VOID *DestinationBuffer, IN CONST VOID *SourceBuffer, IN UINTN Length)
#define NULL
Definition: Base.h:319
#define IN
Definition: Base.h:279
#define DEBUG(Expression)
Definition: DebugLib.h:434
EFI_STATUS PxeTransmit(SNP_DRIVER *Snp, VOID *Buffer, UINTN BufferSize)
Definition: Transmit.c:139
EFI_STATUS PxeFillHeader(SNP_DRIVER *Snp, VOID *MacHeaderPtr, UINTN HeaderSize, VOID *Buffer, UINTN BufferSize, EFI_MAC_ADDRESS *DestAddr, EFI_MAC_ADDRESS *SrcAddr, UINT16 *ProtocolPtr)
Definition: Transmit.c:28
EFI_STATUS EFIAPI SnpUndi32Transmit(IN EFI_SIMPLE_NETWORK_PROTOCOL *This, IN UINTN HeaderSize, IN UINTN BufferSize, IN VOID *Buffer, IN EFI_MAC_ADDRESS *SrcAddr OPTIONAL, IN EFI_MAC_ADDRESS *DestAddr OPTIONAL, IN UINT16 *Protocol OPTIONAL)
Definition: Transmit.c:270
RETURN_STATUS EFI_STATUS
Definition: UefiBaseType.h:29
UINTN EFI_TPL
Definition: UefiBaseType.h:41
#define EFI_SUCCESS
Definition: UefiBaseType.h:112
EFI_BOOT_SERVICES * gBS
#define PXE_OPCODE_TRANSMIT
Definition: UefiPxe.h:165
#define PXE_OPCODE_FILL_HEADER
Definition: UefiPxe.h:160
#define PXE_DBSIZE_NOT_USED
zero
Definition: UefiPxe.h:58
#define PXE_DBADDR_NOT_USED
zero
Definition: UefiPxe.h:60
#define PXE_STATCODE_SUCCESS
Definition: UefiPxe.h:602
EFI_MAC_ADDRESS CurrentAddress
Definition: Snp.h:55
PXE_MEDIA_PROTOCOL Protocol
Definition: UefiPxe.h:1622
struct s_pxe_cpb_fill_header_fragmented::@1060 FragDesc[MAX_XMIT_FRAGMENTS]
PXE_UINT16 MediaheaderLen
Definition: UefiPxe.h:1677
PXE_UINT32 DataLen
Definition: UefiPxe.h:1672
PXE_UINT64 FrameAddr
Definition: UefiPxe.h:1666
PXE_UINT16 reserved
Definition: UefiPxe.h:1682