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