]> git.proxmox.com Git - mirror_edk2.git/blob - MdeModulePkg/Universal/Network/SnpDxe/Receive.c
48c47f15e0556ddc0e6768c1b0c5707e3ee259ed
[mirror_edk2.git] / MdeModulePkg / Universal / Network / SnpDxe / Receive.c
1 /** @file
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
7
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.
10
11 Module name:
12 receive.c
13
14 Abstract:
15
16 Revision history:
17 2000-Feb-03 M(f)J Genesis.
18
19 **/
20
21
22 #include "Snp.h"
23
24 /**
25 this routine calls undi to receive a packet and fills in the data in the
26 input pointers!
27
28 @param snp pointer to snp driver structure
29 @param BufferPtr pointer to the memory for the received data
30 @param BuffSizePtr is a pointer to the length of the buffer on entry and
31 contains the length of the received data on return
32 @param HeaderSizePtr pointer to the header portion of the data received.
33 @param SourceAddrPtr optional parameter, is a pointer to contain the
34 source ethernet address on return
35 @param DestinationAddrPtr optional parameter, is a pointer to contain the
36 destination ethernet address on return
37 @param ProtocolPtr optional parameter, is a pointer to contain the
38 protocol type from the ethernet header on return
39
40
41 **/
42 EFI_STATUS
43 pxe_receive (
44 SNP_DRIVER *snp,
45 VOID *BufferPtr,
46 UINTN *BuffSizePtr,
47 UINTN *HeaderSizePtr,
48 EFI_MAC_ADDRESS *SourceAddrPtr,
49 EFI_MAC_ADDRESS *DestinationAddrPtr,
50 UINT16 *ProtocolPtr
51 )
52 {
53 PXE_CPB_RECEIVE *cpb;
54 PXE_DB_RECEIVE *db;
55 UINTN buf_size;
56
57 cpb = snp->cpb;
58 db = snp->db;
59 buf_size = *BuffSizePtr;
60
61 cpb->BufferAddr = (UINT64)(UINTN) BufferPtr;
62 cpb->BufferLen = (UINT32) *BuffSizePtr;
63
64 cpb->reserved = 0;
65
66 snp->cdb.OpCode = PXE_OPCODE_RECEIVE;
67 snp->cdb.OpFlags = PXE_OPFLAGS_NOT_USED;
68
69 snp->cdb.CPBsize = sizeof (PXE_CPB_RECEIVE);
70 snp->cdb.CPBaddr = (UINT64)(UINTN) cpb;
71
72 snp->cdb.DBsize = sizeof (PXE_DB_RECEIVE);
73 snp->cdb.DBaddr = (UINT64)(UINTN) db;
74
75 snp->cdb.StatCode = PXE_STATCODE_INITIALIZE;
76 snp->cdb.StatFlags = PXE_STATFLAGS_INITIALIZE;
77 snp->cdb.IFnum = snp->if_num;
78 snp->cdb.Control = PXE_CONTROL_LAST_CDB_IN_LIST;
79
80 //
81 // Issue UNDI command and check result.
82 //
83 DEBUG ((EFI_D_NET, "\nsnp->undi.receive () "));
84
85 (*snp->issue_undi32_command) ((UINT64)(UINTN) &snp->cdb);
86
87 switch (snp->cdb.StatCode) {
88 case PXE_STATCODE_SUCCESS:
89 break;
90
91 case PXE_STATCODE_NO_DATA:
92 DEBUG (
93 (EFI_D_NET,
94 "\nsnp->undi.receive () %xh:%xh\n",
95 snp->cdb.StatFlags,
96 snp->cdb.StatCode)
97 );
98
99 return EFI_NOT_READY;
100
101 default:
102 DEBUG (
103 (EFI_D_ERROR,
104 "\nsnp->undi.receive() %xh:%xh\n",
105 snp->cdb.StatFlags,
106 snp->cdb.StatCode)
107 );
108
109 return EFI_DEVICE_ERROR;
110 }
111
112 *BuffSizePtr = db->FrameLen;
113
114 if (HeaderSizePtr != NULL) {
115 *HeaderSizePtr = db->MediaHeaderLen;
116 }
117
118 if (SourceAddrPtr != NULL) {
119 CopyMem (SourceAddrPtr, &db->SrcAddr, snp->mode.HwAddressSize);
120 }
121
122 if (DestinationAddrPtr != NULL) {
123 CopyMem (DestinationAddrPtr, &db->DestAddr, snp->mode.HwAddressSize);
124 }
125
126 if (ProtocolPtr != NULL) {
127 *ProtocolPtr = (UINT16) PXE_SWAP_UINT16 (db->Protocol); /* we need to do the byte swapping */
128 }
129
130 return (*BuffSizePtr <= buf_size) ? EFI_SUCCESS : EFI_BUFFER_TOO_SMALL;
131 }
132
133
134 /**
135 This is the SNP interface routine for receiving network data.
136 This routine basically retrieves snp structure, checks the SNP state and
137 calls the pxe_receive routine to actually do the receive!
138
139 @param this context pointer
140 @param HeaderSizePtr optional parameter and is a pointer to the header
141 portion of the data received.
142 @param BuffSizePtr is a pointer to the length of the buffer on entry and
143 contains the length of the received data on return
144 @param BufferPtr pointer to the memory for the received data
145 @param SourceAddrPtr optional parameter, is a pointer to contain the
146 source ethernet address on return
147 @param DestinationAddrPtr optional parameter, is a pointer to contain the
148 destination ethernet address on return
149 @param ProtocolPtr optional parameter, is a pointer to contain the
150 protocol type from the ethernet header on return
151
152
153 **/
154 EFI_STATUS
155 EFIAPI
156 snp_undi32_receive (
157 IN EFI_SIMPLE_NETWORK_PROTOCOL * this,
158 OUT UINTN *HeaderSizePtr OPTIONAL,
159 IN OUT UINTN *BuffSizePtr,
160 OUT VOID *BufferPtr,
161 OUT EFI_MAC_ADDRESS * SourceAddrPtr OPTIONAL,
162 OUT EFI_MAC_ADDRESS * DestinationAddrPtr OPTIONAL,
163 OUT UINT16 *ProtocolPtr OPTIONAL
164 )
165 {
166 SNP_DRIVER *snp;
167 EFI_TPL OldTpl;
168 EFI_STATUS Status;
169
170 if (this == NULL) {
171 return EFI_INVALID_PARAMETER;
172 }
173
174 snp = EFI_SIMPLE_NETWORK_DEV_FROM_THIS (this);
175
176 OldTpl = gBS->RaiseTPL (TPL_CALLBACK);
177
178 switch (snp->mode.State) {
179 case EfiSimpleNetworkInitialized:
180 break;
181
182 case EfiSimpleNetworkStopped:
183 Status = EFI_NOT_STARTED;
184 goto ON_EXIT;
185
186 default:
187 Status = EFI_DEVICE_ERROR;
188 goto ON_EXIT;
189 }
190
191 if ((BuffSizePtr == NULL) || (BufferPtr == NULL)) {
192 Status = EFI_INVALID_PARAMETER;
193 goto ON_EXIT;
194 }
195
196 if (!snp->mode.ReceiveFilterSetting) {
197 Status = EFI_DEVICE_ERROR;
198 goto ON_EXIT;
199 }
200
201 Status = pxe_receive (
202 snp,
203 BufferPtr,
204 BuffSizePtr,
205 HeaderSizePtr,
206 SourceAddrPtr,
207 DestinationAddrPtr,
208 ProtocolPtr
209 );
210
211 ON_EXIT:
212 gBS->RestoreTPL (OldTpl);
213
214 return Status;
215 }