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