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