2 Copyright (c) 2004 - 2007, Intel Corporation
3 All rights reserved. This program and the accompanying materials
4 are licensed and made available under the terms and conditions of the BSD License
5 which accompanies this distribution. The full text of the license may be found at
6 http://opensource.org/licenses/bsd-license.php
8 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
9 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
18 2000-Feb-03 M(f)J Genesis.
26 This routine calls undi to create the meadia header for the given data buffer.
28 @param snp pointer to SNP driver structure
29 @param MacHeaderPtr address where the media header will be filled in.
30 @param MacHeaderSize size of the memory at MacHeaderPtr
31 @param BufferPtr data buffer pointer
32 @param BufferLength Size of data in the BufferPtr
33 @param DestinationAddrPtr address of the destination mac address buffer
34 @param SourceAddrPtr address of the source mac address buffer
35 @param ProtocolPtr address of the protocol type
37 @retval EFI_SUCCESS if successfully completed the undi call
38 @retval Other error return from undi call.
49 EFI_MAC_ADDRESS
*DestinationAddrPtr
,
50 EFI_MAC_ADDRESS
*SourceAddrPtr
,
54 PXE_CPB_FILL_HEADER_FRAGMENTED
*cpb
;
59 (VOID
*) cpb
->SrcAddr
,
60 (VOID
*) SourceAddrPtr
,
61 snp
->mode
.HwAddressSize
65 (VOID
*) cpb
->SrcAddr
,
66 (VOID
*) &(snp
->mode
.CurrentAddress
),
67 snp
->mode
.HwAddressSize
72 (VOID
*) cpb
->DestAddr
,
73 (VOID
*) DestinationAddrPtr
,
74 snp
->mode
.HwAddressSize
78 // we need to do the byte swapping
80 cpb
->Protocol
= (UINT16
) PXE_SWAP_UINT16 (*ProtocolPtr
);
82 cpb
->PacketLen
= (UINT32
) (BufferLength
);
83 cpb
->MediaHeaderLen
= (UINT16
) MacHeaderSize
;
88 cpb
->FragDesc
[0].FragAddr
= (UINT64
)(UINTN
) MacHeaderPtr
;
89 cpb
->FragDesc
[0].FragLen
= (UINT32
) MacHeaderSize
;
90 cpb
->FragDesc
[1].FragAddr
= (UINT64
)(UINTN
) BufferPtr
;
91 cpb
->FragDesc
[1].FragLen
= (UINT32
) BufferLength
;
93 cpb
->FragDesc
[0].reserved
= cpb
->FragDesc
[1].reserved
= 0;
95 snp
->cdb
.OpCode
= PXE_OPCODE_FILL_HEADER
;
96 snp
->cdb
.OpFlags
= PXE_OPFLAGS_FILL_HEADER_FRAGMENTED
;
98 snp
->cdb
.DBsize
= PXE_DBSIZE_NOT_USED
;
99 snp
->cdb
.DBaddr
= PXE_DBADDR_NOT_USED
;
101 snp
->cdb
.CPBsize
= sizeof (PXE_CPB_FILL_HEADER_FRAGMENTED
);
102 snp
->cdb
.CPBaddr
= (UINT64
)(UINTN
) cpb
;
104 snp
->cdb
.StatCode
= PXE_STATCODE_INITIALIZE
;
105 snp
->cdb
.StatFlags
= PXE_STATFLAGS_INITIALIZE
;
106 snp
->cdb
.IFnum
= snp
->if_num
;
107 snp
->cdb
.Control
= PXE_CONTROL_LAST_CDB_IN_LIST
;
110 // Issue UNDI command and check result.
112 DEBUG ((EFI_D_NET
, "\nsnp->undi.fill_header() "));
114 (*snp
->issue_undi32_command
) ((UINT64
) (UINTN
) &snp
->cdb
);
116 switch (snp
->cdb
.StatCode
) {
117 case PXE_STATCODE_SUCCESS
:
120 case PXE_STATCODE_INVALID_PARAMETER
:
123 "\nsnp->undi.fill_header() %xh:%xh\n",
128 return EFI_INVALID_PARAMETER
;
133 "\nsnp->undi.fill_header() %xh:%xh\n",
138 return EFI_DEVICE_ERROR
;
144 This routine calls undi to transmit the given data buffer
146 @param snp pointer to SNP driver structure
147 @param BufferPtr data buffer pointer
148 @param BufferLength Size of data in the BufferPtr
150 @retval EFI_SUCCESS if successfully completed the undi call
151 @retval Other error return from undi call.
162 PXE_CPB_TRANSMIT
*cpb
;
166 cpb
->FrameAddr
= (UINT64
) (UINTN
) BufferPtr
;
167 cpb
->DataLen
= (UINT32
) BufferLength
;
169 cpb
->MediaheaderLen
= 0;
172 snp
->cdb
.OpFlags
= PXE_OPFLAGS_TRANSMIT_WHOLE
;
174 snp
->cdb
.CPBsize
= sizeof (PXE_CPB_TRANSMIT
);
175 snp
->cdb
.CPBaddr
= (UINT64
)(UINTN
) cpb
;
177 snp
->cdb
.OpCode
= PXE_OPCODE_TRANSMIT
;
178 snp
->cdb
.DBsize
= PXE_DBSIZE_NOT_USED
;
179 snp
->cdb
.DBaddr
= PXE_DBADDR_NOT_USED
;
181 snp
->cdb
.StatCode
= PXE_STATCODE_INITIALIZE
;
182 snp
->cdb
.StatFlags
= PXE_STATFLAGS_INITIALIZE
;
183 snp
->cdb
.IFnum
= snp
->if_num
;
184 snp
->cdb
.Control
= PXE_CONTROL_LAST_CDB_IN_LIST
;
187 // Issue UNDI command and check result.
189 DEBUG ((EFI_D_NET
, "\nsnp->undi.transmit() "));
190 DEBUG ((EFI_D_NET
, "\nsnp->cdb.OpCode == %x", snp
->cdb
.OpCode
));
191 DEBUG ((EFI_D_NET
, "\nsnp->cdb.CPBaddr == %X", snp
->cdb
.CPBaddr
));
192 DEBUG ((EFI_D_NET
, "\nsnp->cdb.DBaddr == %X", snp
->cdb
.DBaddr
));
193 DEBUG ((EFI_D_NET
, "\ncpb->FrameAddr == %X\n", cpb
->FrameAddr
));
195 (*snp
->issue_undi32_command
) ((UINT64
) (UINTN
) &snp
->cdb
);
197 DEBUG ((EFI_D_NET
, "\nexit snp->undi.transmit() "));
198 DEBUG ((EFI_D_NET
, "\nsnp->cdb.StatCode == %r", snp
->cdb
.StatCode
));
201 // we will unmap the buffers in get_status call, not here
203 switch (snp
->cdb
.StatCode
) {
204 case PXE_STATCODE_SUCCESS
:
207 case PXE_STATCODE_QUEUE_FULL
:
208 case PXE_STATCODE_BUSY
:
209 Status
= EFI_NOT_READY
;
213 Status
= EFI_DEVICE_ERROR
;
218 "\nsnp->undi.transmit() %xh:%xh\n",
228 This is the snp interface routine for transmitting a packet. this routine
229 basically retrieves the snp structure, checks the snp state and calls
230 pxe_fill_header and pxe_transmit calls to complete the transmission.
232 @param this pointer to SNP driver context
233 @param MacHeaderSize size of the memory at MacHeaderPtr
234 @param BufferLength Size of data in the BufferPtr
235 @param BufferPtr data buffer pointer
236 @param SourceAddrPtr address of the source mac address buffer
237 @param DestinationAddrPtr address of the destination mac address buffer
238 @param ProtocolPtr address of the protocol type
240 @retval EFI_SUCCESS if successfully completed the undi call
241 @retval Other error return from undi call.
246 snp_undi32_transmit (
247 IN EFI_SIMPLE_NETWORK_PROTOCOL
* this,
248 IN UINTN MacHeaderSize
,
249 IN UINTN BufferLength
,
251 IN EFI_MAC_ADDRESS
* SourceAddrPtr OPTIONAL
,
252 IN EFI_MAC_ADDRESS
* DestinationAddrPtr OPTIONAL
,
253 IN UINT16
*ProtocolPtr OPTIONAL
261 return EFI_INVALID_PARAMETER
;
264 snp
= EFI_SIMPLE_NETWORK_DEV_FROM_THIS (this);
266 OldTpl
= gBS
->RaiseTPL (TPL_CALLBACK
);
269 return EFI_DEVICE_ERROR
;
272 switch (snp
->mode
.State
) {
273 case EfiSimpleNetworkInitialized
:
276 case EfiSimpleNetworkStopped
:
277 Status
= EFI_NOT_STARTED
;
281 Status
= EFI_DEVICE_ERROR
;
285 if (BufferPtr
== NULL
) {
286 Status
= EFI_INVALID_PARAMETER
;
290 if (BufferLength
< snp
->mode
.MediaHeaderSize
) {
291 Status
= EFI_BUFFER_TOO_SMALL
;
296 // if the MacHeaderSize is non-zero, we need to fill up the header and for that
297 // we need the destination address and the protocol
299 if (MacHeaderSize
!= 0) {
300 if (MacHeaderSize
!= snp
->mode
.MediaHeaderSize
|| DestinationAddrPtr
== 0 || ProtocolPtr
== 0) {
301 Status
= EFI_INVALID_PARAMETER
;
305 Status
= pxe_fillheader (
309 (UINT8
*) BufferPtr
+ MacHeaderSize
,
310 BufferLength
- MacHeaderSize
,
316 if (EFI_ERROR (Status
)) {
321 Status
= pxe_transmit (snp
, BufferPtr
, BufferLength
);
324 gBS
->RestoreTPL (OldTpl
);