]> git.proxmox.com Git - mirror_edk2.git/blame - NetworkPkg/MnpDxe/MnpIo.c
NetworkPkg: Apply uncrustify changes
[mirror_edk2.git] / NetworkPkg / MnpDxe / MnpIo.c
CommitLineData
8a67d61d 1/** @file\r
3e8c18da 2 Implementation of Managed Network Protocol I/O functions.\r
779ae357 3\r
d1102dba 4Copyright (c) 2005 - 2018, Intel Corporation. All rights reserved.<BR>\r
9d510e61 5SPDX-License-Identifier: BSD-2-Clause-Patent\r
8a67d61d 6\r
8a67d61d 7**/\r
8\r
19034421 9#include "MnpImpl.h"\r
779ae357 10#include "MnpVlan.h"\r
8a67d61d 11\r
12/**\r
13 Validates the Mnp transmit token.\r
14\r
6e4bac4d 15 @param[in] Instance Pointer to the Mnp instance context data.\r
16 @param[in] Token Pointer to the transmit token to check.\r
8a67d61d 17\r
18 @return The Token is valid or not.\r
19\r
20**/\r
21BOOLEAN\r
22MnpIsValidTxToken (\r
d1050b9d
MK
23 IN MNP_INSTANCE_DATA *Instance,\r
24 IN EFI_MANAGED_NETWORK_COMPLETION_TOKEN *Token\r
8a67d61d 25 )\r
26{\r
d1050b9d
MK
27 MNP_SERVICE_DATA *MnpServiceData;\r
28 EFI_MANAGED_NETWORK_TRANSMIT_DATA *TxData;\r
29 UINT32 Index;\r
30 UINT32 TotalLength;\r
31 EFI_MANAGED_NETWORK_FRAGMENT_DATA *FragmentTable;\r
8a67d61d 32\r
33 MnpServiceData = Instance->MnpServiceData;\r
34 NET_CHECK_SIGNATURE (MnpServiceData, MNP_SERVICE_DATA_SIGNATURE);\r
35\r
779ae357 36 TxData = Token->Packet.TxData;\r
8a67d61d 37\r
38 if ((Token->Event == NULL) || (TxData == NULL) || (TxData->FragmentCount == 0)) {\r
39 //\r
40 // The token is invalid if the Event is NULL, or the TxData is NULL, or\r
41 // the fragment count is zero.\r
42 //\r
c49ca4a2 43 DEBUG ((DEBUG_WARN, "MnpIsValidTxToken: Invalid Token.\n"));\r
8a67d61d 44 return FALSE;\r
45 }\r
46\r
47 if ((TxData->DestinationAddress != NULL) && (TxData->HeaderLength != 0)) {\r
48 //\r
49 // The token is invalid if the HeaderLength isn't zero while the DestinationAddress\r
50 // is NULL (The destination address is already put into the packet).\r
51 //\r
c49ca4a2 52 DEBUG ((DEBUG_WARN, "MnpIsValidTxToken: DestinationAddress isn't NULL, HeaderLength must be 0.\n"));\r
8a67d61d 53 return FALSE;\r
54 }\r
55\r
56 TotalLength = 0;\r
57 FragmentTable = TxData->FragmentTable;\r
58 for (Index = 0; Index < TxData->FragmentCount; Index++) {\r
8a67d61d 59 if ((FragmentTable[Index].FragmentLength == 0) || (FragmentTable[Index].FragmentBuffer == NULL)) {\r
60 //\r
61 // The token is invalid if any FragmentLength is zero or any FragmentBuffer is NULL.\r
62 //\r
c49ca4a2 63 DEBUG ((DEBUG_WARN, "MnpIsValidTxToken: Invalid FragmentLength or FragmentBuffer.\n"));\r
8a67d61d 64 return FALSE;\r
65 }\r
66\r
67 TotalLength += FragmentTable[Index].FragmentLength;\r
68 }\r
69\r
70 if ((TxData->DestinationAddress == NULL) && (FragmentTable[0].FragmentLength < TxData->HeaderLength)) {\r
71 //\r
72 // Media header is split between fragments.\r
73 //\r
74 return FALSE;\r
75 }\r
76\r
77 if (TotalLength != (TxData->DataLength + TxData->HeaderLength)) {\r
78 //\r
79 // The length calculated from the fragment information doesn't equal to the\r
80 // sum of the DataLength and the HeaderLength.\r
81 //\r
c49ca4a2 82 DEBUG ((DEBUG_WARN, "MnpIsValidTxData: Invalid Datalength compared with the sum of fragment length.\n"));\r
8a67d61d 83 return FALSE;\r
84 }\r
85\r
86 if (TxData->DataLength > MnpServiceData->Mtu) {\r
87 //\r
88 // The total length is larger than the MTU.\r
89 //\r
c49ca4a2 90 DEBUG ((DEBUG_WARN, "MnpIsValidTxData: TxData->DataLength exceeds Mtu.\n"));\r
8a67d61d 91 return FALSE;\r
92 }\r
93\r
94 return TRUE;\r
95}\r
96\r
8a67d61d 97/**\r
98 Build the packet to transmit from the TxData passed in.\r
99\r
6e4bac4d 100 @param[in] MnpServiceData Pointer to the mnp service context data.\r
779ae357 101 @param[in] TxData Pointer to the transmit data containing the information\r
6e4bac4d 102 to build the packet.\r
103 @param[out] PktBuf Pointer to record the address of the packet.\r
779ae357 104 @param[out] PktLen Pointer to a UINT32 variable used to record the packet's\r
6e4bac4d 105 length.\r
106\r
05074499
FS
107 @retval EFI_SUCCESS TxPackage is built.\r
108 @retval EFI_OUT_OF_RESOURCES The deliver fails due to lack of memory resource.\r
109\r
8a67d61d 110**/\r
05074499 111EFI_STATUS\r
8a67d61d 112MnpBuildTxPacket (\r
d1050b9d
MK
113 IN MNP_SERVICE_DATA *MnpServiceData,\r
114 IN EFI_MANAGED_NETWORK_TRANSMIT_DATA *TxData,\r
115 OUT UINT8 **PktBuf,\r
116 OUT UINT32 *PktLen\r
8a67d61d 117 )\r
118{\r
d1050b9d
MK
119 EFI_SIMPLE_NETWORK_MODE *SnpMode;\r
120 UINT8 *DstPos;\r
121 UINT16 Index;\r
122 MNP_DEVICE_DATA *MnpDeviceData;\r
123 UINT8 *TxBuf;\r
d1102dba 124\r
05074499 125 MnpDeviceData = MnpServiceData->MnpDeviceData;\r
d1102dba 126\r
05074499
FS
127 TxBuf = MnpAllocTxBuf (MnpDeviceData);\r
128 if (TxBuf == NULL) {\r
129 return EFI_OUT_OF_RESOURCES;\r
130 }\r
d1102dba 131\r
8ff272ee 132 //\r
05074499 133 // Reserve space for vlan tag if needed.\r
8ff272ee 134 //\r
05074499
FS
135 if (MnpServiceData->VlanId != 0) {\r
136 *PktBuf = TxBuf + NET_VLAN_TAG_LEN;\r
137 } else {\r
138 *PktBuf = TxBuf;\r
139 }\r
d1102dba 140\r
8a67d61d 141 if ((TxData->DestinationAddress == NULL) && (TxData->FragmentCount == 1)) {\r
bdebd2ce 142 CopyMem (\r
d1050b9d
MK
143 *PktBuf,\r
144 TxData->FragmentTable[0].FragmentBuffer,\r
145 TxData->FragmentTable[0].FragmentLength\r
146 );\r
d1102dba 147\r
8a67d61d 148 *PktLen = TxData->FragmentTable[0].FragmentLength;\r
149 } else {\r
150 //\r
151 // Either media header isn't in FragmentTable or there is more than\r
152 // one fragment, copy the data into the packet buffer. Reserve the\r
153 // media header space if necessary.\r
154 //\r
d1102dba 155 SnpMode = MnpDeviceData->Snp->Mode;\r
8ff272ee 156 DstPos = *PktBuf;\r
8a67d61d 157 *PktLen = 0;\r
158 if (TxData->DestinationAddress != NULL) {\r
159 //\r
160 // If dest address is not NULL, move DstPos to reserve space for the\r
161 // media header. Add the media header length to buflen.\r
162 //\r
d1050b9d 163 DstPos += SnpMode->MediaHeaderSize;\r
8a67d61d 164 *PktLen += SnpMode->MediaHeaderSize;\r
165 }\r
166\r
167 for (Index = 0; Index < TxData->FragmentCount; Index++) {\r
168 //\r
169 // Copy the data.\r
170 //\r
e48e37fc 171 CopyMem (\r
8a67d61d 172 DstPos,\r
173 TxData->FragmentTable[Index].FragmentBuffer,\r
174 TxData->FragmentTable[Index].FragmentLength\r
175 );\r
176 DstPos += TxData->FragmentTable[Index].FragmentLength;\r
177 }\r
178\r
179 //\r
8ff272ee 180 // Set the buffer length.\r
8a67d61d 181 //\r
8a67d61d 182 *PktLen += TxData->DataLength + TxData->HeaderLength;\r
183 }\r
05074499
FS
184\r
185 return EFI_SUCCESS;\r
8a67d61d 186}\r
187\r
8a67d61d 188/**\r
d1102dba 189 Synchronously send out the packet.\r
05074499 190\r
5feb1fbd
AC
191 This function places the packet buffer to SNP driver's tansmit queue. The packet\r
192 can be considered successfully sent out once SNP accept the packet, while the\r
05074499 193 packet buffer recycle is deferred for better performance.\r
8a67d61d 194\r
6e4bac4d 195 @param[in] MnpServiceData Pointer to the mnp service context data.\r
5feb1fbd 196 @param[in] Packet Pointer to the packet buffer.\r
6e4bac4d 197 @param[in] Length The length of the packet.\r
198 @param[in, out] Token Pointer to the token the packet generated from.\r
8a67d61d 199\r
6e4bac4d 200 @retval EFI_SUCCESS The packet is sent out.\r
201 @retval EFI_TIMEOUT Time out occurs, the packet isn't sent.\r
202 @retval EFI_DEVICE_ERROR An unexpected network error occurs.\r
8a67d61d 203\r
204**/\r
205EFI_STATUS\r
206MnpSyncSendPacket (\r
d1050b9d
MK
207 IN MNP_SERVICE_DATA *MnpServiceData,\r
208 IN UINT8 *Packet,\r
209 IN UINT32 Length,\r
210 IN OUT EFI_MANAGED_NETWORK_COMPLETION_TOKEN *Token\r
8a67d61d 211 )\r
212{\r
d1050b9d
MK
213 EFI_STATUS Status;\r
214 EFI_SIMPLE_NETWORK_PROTOCOL *Snp;\r
215 EFI_MANAGED_NETWORK_TRANSMIT_DATA *TxData;\r
216 UINT32 HeaderSize;\r
217 MNP_DEVICE_DATA *MnpDeviceData;\r
218 UINT16 ProtocolType;\r
8a67d61d 219\r
779ae357 220 MnpDeviceData = MnpServiceData->MnpDeviceData;\r
221 Snp = MnpDeviceData->Snp;\r
222 TxData = Token->Packet.TxData;\r
05074499 223 Token->Status = EFI_SUCCESS;\r
779ae357 224 HeaderSize = Snp->Mode->MediaHeaderSize - TxData->HeaderLength;\r
8a67d61d 225\r
dd29f3ed 226 //\r
227 // Check media status before transmit packet.\r
228 // Note: media status will be updated by periodic timer MediaDetectTimer.\r
229 //\r
412d1ed9 230 if (Snp->Mode->MediaPresentSupported && !Snp->Mode->MediaPresent) {\r
dd29f3ed 231 //\r
232 // Media not present, skip packet transmit and report EFI_NO_MEDIA\r
233 //\r
c49ca4a2 234 DEBUG ((DEBUG_WARN, "MnpSyncSendPacket: No network cable detected.\n"));\r
05074499 235 Token->Status = EFI_NO_MEDIA;\r
8a67d61d 236 goto SIGNAL_TOKEN;\r
237 }\r
238\r
bdebd2ce
WJ
239 if (MnpServiceData->VlanId != 0) {\r
240 //\r
241 // Insert VLAN tag\r
242 //\r
243 MnpInsertVlanTag (MnpServiceData, TxData, &ProtocolType, &Packet, &Length);\r
244 } else {\r
245 ProtocolType = TxData->ProtocolType;\r
246 }\r
779ae357 247\r
05074499
FS
248 //\r
249 // Transmit the packet through SNP.\r
250 //\r
251 Status = Snp->Transmit (\r
252 Snp,\r
253 HeaderSize,\r
254 Length,\r
255 Packet,\r
256 TxData->SourceAddress,\r
257 TxData->DestinationAddress,\r
258 &ProtocolType\r
259 );\r
260 if (Status == EFI_NOT_READY) {\r
261 Status = MnpRecycleTxBuf (MnpDeviceData);\r
262 if (EFI_ERROR (Status)) {\r
263 Token->Status = EFI_DEVICE_ERROR;\r
264 goto SIGNAL_TOKEN;\r
265 }\r
266\r
8a67d61d 267 Status = Snp->Transmit (\r
268 Snp,\r
269 HeaderSize,\r
270 Length,\r
271 Packet,\r
272 TxData->SourceAddress,\r
273 TxData->DestinationAddress,\r
779ae357 274 &ProtocolType\r
d1102dba 275 );\r
05074499 276 }\r
d1102dba 277\r
05074499
FS
278 if (EFI_ERROR (Status)) {\r
279 Token->Status = EFI_DEVICE_ERROR;\r
8a67d61d 280 }\r
8a67d61d 281\r
282SIGNAL_TOKEN:\r
283\r
8a67d61d 284 gBS->SignalEvent (Token->Event);\r
285\r
36ee91ca 286 //\r
287 // Dispatch the DPC queued by the NotifyFunction of Token->Event.\r
288 //\r
d8d26fb2 289 DispatchDpc ();\r
36ee91ca 290\r
8a67d61d 291 return EFI_SUCCESS;\r
292}\r
293\r
8a67d61d 294/**\r
295 Try to deliver the received packet to the instance.\r
296\r
6e4bac4d 297 @param[in, out] Instance Pointer to the mnp instance context data.\r
8a67d61d 298\r
299 @retval EFI_SUCCESS The received packet is delivered, or there is no\r
300 packet to deliver, or there is no available receive\r
301 token.\r
302 @retval EFI_OUT_OF_RESOURCES The deliver fails due to lack of memory resource.\r
303\r
304**/\r
305EFI_STATUS\r
306MnpInstanceDeliverPacket (\r
d1050b9d 307 IN OUT MNP_INSTANCE_DATA *Instance\r
8a67d61d 308 )\r
309{\r
779ae357 310 MNP_DEVICE_DATA *MnpDeviceData;\r
8a67d61d 311 MNP_RXDATA_WRAP *RxDataWrap;\r
312 NET_BUF *DupNbuf;\r
313 EFI_MANAGED_NETWORK_RECEIVE_DATA *RxData;\r
314 EFI_SIMPLE_NETWORK_MODE *SnpMode;\r
315 EFI_MANAGED_NETWORK_COMPLETION_TOKEN *RxToken;\r
316\r
779ae357 317 MnpDeviceData = Instance->MnpServiceData->MnpDeviceData;\r
318 NET_CHECK_SIGNATURE (MnpDeviceData, MNP_DEVICE_DATA_SIGNATURE);\r
8a67d61d 319\r
e48e37fc 320 if (NetMapIsEmpty (&Instance->RxTokenMap) || IsListEmpty (&Instance->RcvdPacketQueue)) {\r
8a67d61d 321 //\r
322 // No pending received data or no available receive token, return.\r
323 //\r
324 return EFI_SUCCESS;\r
325 }\r
326\r
327 ASSERT (Instance->RcvdPacketQueueSize != 0);\r
328\r
329 RxDataWrap = NET_LIST_HEAD (&Instance->RcvdPacketQueue, MNP_RXDATA_WRAP, WrapEntry);\r
330 if (RxDataWrap->Nbuf->RefCnt > 2) {\r
331 //\r
332 // There are other instances share this Nbuf, duplicate to get a\r
333 // copy to allow the instance to do R/W operations.\r
334 //\r
779ae357 335 DupNbuf = MnpAllocNbuf (MnpDeviceData);\r
8a67d61d 336 if (DupNbuf == NULL) {\r
c49ca4a2 337 DEBUG ((DEBUG_WARN, "MnpDeliverPacket: Failed to allocate a free Nbuf.\n"));\r
8a67d61d 338\r
339 return EFI_OUT_OF_RESOURCES;\r
340 }\r
341\r
342 //\r
343 // Duplicate the net buffer.\r
344 //\r
345 NetbufDuplicate (RxDataWrap->Nbuf, DupNbuf, 0);\r
779ae357 346 MnpFreeNbuf (MnpDeviceData, RxDataWrap->Nbuf);\r
8a67d61d 347 RxDataWrap->Nbuf = DupNbuf;\r
348 }\r
349\r
350 //\r
351 // All resources are OK, remove the packet from the queue.\r
352 //\r
353 NetListRemoveHead (&Instance->RcvdPacketQueue);\r
354 Instance->RcvdPacketQueueSize--;\r
355\r
356 RxData = &RxDataWrap->RxData;\r
779ae357 357 SnpMode = MnpDeviceData->Snp->Mode;\r
8a67d61d 358\r
359 //\r
360 // Set all the buffer pointers.\r
361 //\r
d1050b9d
MK
362 RxData->MediaHeader = NetbufGetByte (RxDataWrap->Nbuf, 0, NULL);\r
363 RxData->DestinationAddress = RxData->MediaHeader;\r
364 RxData->SourceAddress = (UINT8 *)RxData->MediaHeader + SnpMode->HwAddressSize;\r
365 RxData->PacketData = (UINT8 *)RxData->MediaHeader + SnpMode->MediaHeaderSize;\r
8a67d61d 366\r
367 //\r
368 // Insert this RxDataWrap into the delivered queue.\r
369 //\r
e48e37fc 370 InsertTailList (&Instance->RxDeliveredPacketQueue, &RxDataWrap->WrapEntry);\r
8a67d61d 371\r
372 //\r
373 // Get the receive token from the RxTokenMap.\r
374 //\r
375 RxToken = NetMapRemoveHead (&Instance->RxTokenMap, NULL);\r
376\r
377 //\r
378 // Signal this token's event.\r
379 //\r
d1050b9d
MK
380 RxToken->Packet.RxData = &RxDataWrap->RxData;\r
381 RxToken->Status = EFI_SUCCESS;\r
8a67d61d 382 gBS->SignalEvent (RxToken->Event);\r
383\r
384 return EFI_SUCCESS;\r
385}\r
386\r
8a67d61d 387/**\r
388 Deliver the received packet for the instances belonging to the MnpServiceData.\r
389\r
6e4bac4d 390 @param[in] MnpServiceData Pointer to the mnp service context data.\r
8a67d61d 391\r
8a67d61d 392**/\r
8a67d61d 393VOID\r
394MnpDeliverPacket (\r
d1050b9d 395 IN MNP_SERVICE_DATA *MnpServiceData\r
8a67d61d 396 )\r
397{\r
d1050b9d
MK
398 LIST_ENTRY *Entry;\r
399 MNP_INSTANCE_DATA *Instance;\r
8a67d61d 400\r
401 NET_CHECK_SIGNATURE (MnpServiceData, MNP_SERVICE_DATA_SIGNATURE);\r
402\r
403 NET_LIST_FOR_EACH (Entry, &MnpServiceData->ChildrenList) {\r
404 Instance = NET_LIST_USER_STRUCT (Entry, MNP_INSTANCE_DATA, InstEntry);\r
405 NET_CHECK_SIGNATURE (Instance, MNP_INSTANCE_DATA_SIGNATURE);\r
406\r
407 //\r
408 // Try to deliver packet for this instance.\r
409 //\r
410 MnpInstanceDeliverPacket (Instance);\r
411 }\r
412}\r
413\r
8a67d61d 414/**\r
415 Recycle the RxData and other resources used to hold and deliver the received\r
416 packet.\r
417\r
6e4bac4d 418 @param[in] Event The event this notify function registered to.\r
5feb1fbd 419 @param[in] Context Pointer to the context data registered to the Event.\r
6e4bac4d 420\r
8a67d61d 421**/\r
422VOID\r
423EFIAPI\r
424MnpRecycleRxData (\r
d1050b9d
MK
425 IN EFI_EVENT Event,\r
426 IN VOID *Context\r
8a67d61d 427 )\r
428{\r
d1050b9d
MK
429 MNP_RXDATA_WRAP *RxDataWrap;\r
430 MNP_DEVICE_DATA *MnpDeviceData;\r
8a67d61d 431\r
432 ASSERT (Context != NULL);\r
433\r
d1050b9d 434 RxDataWrap = (MNP_RXDATA_WRAP *)Context;\r
8a67d61d 435 NET_CHECK_SIGNATURE (RxDataWrap->Instance, MNP_INSTANCE_DATA_SIGNATURE);\r
436\r
437 ASSERT (RxDataWrap->Nbuf != NULL);\r
438\r
779ae357 439 MnpDeviceData = RxDataWrap->Instance->MnpServiceData->MnpDeviceData;\r
440 NET_CHECK_SIGNATURE (MnpDeviceData, MNP_DEVICE_DATA_SIGNATURE);\r
8a67d61d 441\r
442 //\r
443 // Free this Nbuf.\r
444 //\r
779ae357 445 MnpFreeNbuf (MnpDeviceData, RxDataWrap->Nbuf);\r
8a67d61d 446 RxDataWrap->Nbuf = NULL;\r
447\r
448 //\r
449 // Close the recycle event.\r
450 //\r
451 gBS->CloseEvent (RxDataWrap->RxData.RecycleEvent);\r
452\r
453 //\r
454 // Remove this Wrap entry from the list.\r
455 //\r
e48e37fc 456 RemoveEntryList (&RxDataWrap->WrapEntry);\r
8a67d61d 457\r
766c7483 458 FreePool (RxDataWrap);\r
8a67d61d 459}\r
460\r
8a67d61d 461/**\r
462 Queue the received packet into instance's receive queue.\r
463\r
6e4bac4d 464 @param[in, out] Instance Pointer to the mnp instance context data.\r
465 @param[in, out] RxDataWrap Pointer to the Wrap structure containing the\r
466 received data and other information.\r
8a67d61d 467**/\r
8a67d61d 468VOID\r
469MnpQueueRcvdPacket (\r
d1050b9d
MK
470 IN OUT MNP_INSTANCE_DATA *Instance,\r
471 IN OUT MNP_RXDATA_WRAP *RxDataWrap\r
8a67d61d 472 )\r
473{\r
d1050b9d 474 MNP_RXDATA_WRAP *OldRxDataWrap;\r
8a67d61d 475\r
476 NET_CHECK_SIGNATURE (Instance, MNP_INSTANCE_DATA_SIGNATURE);\r
477\r
478 //\r
479 // Check the queue size. If it exceeds the limit, drop one packet\r
480 // from the head.\r
481 //\r
482 if (Instance->RcvdPacketQueueSize == MNP_MAX_RCVD_PACKET_QUE_SIZE) {\r
c49ca4a2 483 DEBUG ((DEBUG_WARN, "MnpQueueRcvdPacket: Drop one packet bcz queue size limit reached.\n"));\r
8a67d61d 484\r
485 //\r
486 // Get the oldest packet.\r
487 //\r
488 OldRxDataWrap = NET_LIST_HEAD (\r
489 &Instance->RcvdPacketQueue,\r
490 MNP_RXDATA_WRAP,\r
491 WrapEntry\r
492 );\r
493\r
494 //\r
495 // Recycle this OldRxDataWrap, this entry will be removed by the callee.\r
496 //\r
d1050b9d 497 MnpRecycleRxData (NULL, (VOID *)OldRxDataWrap);\r
8a67d61d 498 Instance->RcvdPacketQueueSize--;\r
499 }\r
500\r
501 //\r
502 // Update the timeout tick using the configured parameter.\r
503 //\r
504 RxDataWrap->TimeoutTick = Instance->ConfigData.ReceivedQueueTimeoutValue;\r
505\r
506 //\r
507 // Insert this Wrap into the instance queue.\r
508 //\r
e48e37fc 509 InsertTailList (&Instance->RcvdPacketQueue, &RxDataWrap->WrapEntry);\r
8a67d61d 510 Instance->RcvdPacketQueueSize++;\r
511}\r
512\r
8a67d61d 513/**\r
514 Match the received packet with the instance receive filters.\r
515\r
3e8c18da 516 @param[in] Instance Pointer to the mnp instance context data.\r
517 @param[in] RxData Pointer to the EFI_MANAGED_NETWORK_RECEIVE_DATA.\r
518 @param[in] GroupAddress Pointer to the GroupAddress, the GroupAddress is\r
8a67d61d 519 non-NULL and it contains the destination multicast\r
520 mac address of the received packet if the packet\r
521 destinated to a multicast mac address.\r
3e8c18da 522 @param[in] PktAttr The received packets attribute.\r
8a67d61d 523\r
524 @return The received packet matches the instance's receive filters or not.\r
525\r
526**/\r
8a67d61d 527BOOLEAN\r
528MnpMatchPacket (\r
d1050b9d
MK
529 IN MNP_INSTANCE_DATA *Instance,\r
530 IN EFI_MANAGED_NETWORK_RECEIVE_DATA *RxData,\r
531 IN MNP_GROUP_ADDRESS *GroupAddress OPTIONAL,\r
532 IN UINT8 PktAttr\r
8a67d61d 533 )\r
534{\r
d1050b9d
MK
535 EFI_MANAGED_NETWORK_CONFIG_DATA *ConfigData;\r
536 LIST_ENTRY *Entry;\r
537 MNP_GROUP_CONTROL_BLOCK *GroupCtrlBlk;\r
8a67d61d 538\r
539 NET_CHECK_SIGNATURE (Instance, MNP_INSTANCE_DATA_SIGNATURE);\r
540\r
541 ConfigData = &Instance->ConfigData;\r
542\r
8a67d61d 543 //\r
544 // Check the protocol type.\r
545 //\r
546 if ((ConfigData->ProtocolTypeFilter != 0) && (ConfigData->ProtocolTypeFilter != RxData->ProtocolType)) {\r
547 return FALSE;\r
548 }\r
549\r
36ee91ca 550 if (ConfigData->EnablePromiscuousReceive) {\r
551 //\r
552 // Always match if this instance is configured to be promiscuous.\r
553 //\r
554 return TRUE;\r
555 }\r
556\r
8a67d61d 557 //\r
558 // The protocol type is matched, check receive filter, include unicast and broadcast.\r
559 //\r
560 if ((Instance->ReceiveFilter & PktAttr) != 0) {\r
561 return TRUE;\r
562 }\r
563\r
564 //\r
565 // Check multicast addresses.\r
566 //\r
567 if (ConfigData->EnableMulticastReceive && RxData->MulticastFlag) {\r
8a67d61d 568 ASSERT (GroupAddress != NULL);\r
569\r
570 NET_LIST_FOR_EACH (Entry, &Instance->GroupCtrlBlkList) {\r
8a67d61d 571 GroupCtrlBlk = NET_LIST_USER_STRUCT (Entry, MNP_GROUP_CONTROL_BLOCK, CtrlBlkEntry);\r
572 if (GroupCtrlBlk->GroupAddress == GroupAddress) {\r
573 //\r
574 // The instance is configured to receiveing packets destinated to this\r
575 // multicast address.\r
576 //\r
577 return TRUE;\r
578 }\r
579 }\r
580 }\r
581\r
582 //\r
583 // No match.\r
584 //\r
585 return FALSE;\r
586}\r
587\r
8a67d61d 588/**\r
589 Analyse the received packets.\r
590\r
6e4bac4d 591 @param[in] MnpServiceData Pointer to the mnp service context data.\r
592 @param[in] Nbuf Pointer to the net buffer holding the received\r
593 packet.\r
594 @param[in, out] RxData Pointer to the buffer used to save the analysed\r
595 result in EFI_MANAGED_NETWORK_RECEIVE_DATA.\r
596 @param[out] GroupAddress Pointer to pointer to a MNP_GROUP_ADDRESS used to\r
597 pass out the address of the multicast address the\r
598 received packet destinated to.\r
599 @param[out] PktAttr Pointer to the buffer used to save the analysed\r
600 packet attribute.\r
8a67d61d 601\r
602**/\r
8a67d61d 603VOID\r
604MnpAnalysePacket (\r
d1050b9d
MK
605 IN MNP_SERVICE_DATA *MnpServiceData,\r
606 IN NET_BUF *Nbuf,\r
607 IN OUT EFI_MANAGED_NETWORK_RECEIVE_DATA *RxData,\r
608 OUT MNP_GROUP_ADDRESS **GroupAddress,\r
609 OUT UINT8 *PktAttr\r
8a67d61d 610 )\r
611{\r
d1050b9d
MK
612 EFI_SIMPLE_NETWORK_MODE *SnpMode;\r
613 MNP_DEVICE_DATA *MnpDeviceData;\r
614 UINT8 *BufPtr;\r
615 LIST_ENTRY *Entry;\r
8a67d61d 616\r
779ae357 617 MnpDeviceData = MnpServiceData->MnpDeviceData;\r
618 SnpMode = MnpDeviceData->Snp->Mode;\r
8a67d61d 619\r
620 //\r
621 // Get the packet buffer.\r
622 //\r
623 BufPtr = NetbufGetByte (Nbuf, 0, NULL);\r
624 ASSERT (BufPtr != NULL);\r
625\r
626 //\r
627 // Set the initial values.\r
628 //\r
629 RxData->BroadcastFlag = FALSE;\r
630 RxData->MulticastFlag = FALSE;\r
631 RxData->PromiscuousFlag = FALSE;\r
632 *PktAttr = UNICAST_PACKET;\r
633\r
634 if (!NET_MAC_EQUAL (&SnpMode->CurrentAddress, BufPtr, SnpMode->HwAddressSize)) {\r
635 //\r
636 // This packet isn't destinated to our current mac address, it't not unicast.\r
637 //\r
638 *PktAttr = 0;\r
639\r
640 if (NET_MAC_EQUAL (&SnpMode->BroadcastAddress, BufPtr, SnpMode->HwAddressSize)) {\r
641 //\r
642 // It's broadcast.\r
643 //\r
644 RxData->BroadcastFlag = TRUE;\r
645 *PktAttr = BROADCAST_PACKET;\r
646 } else if ((*BufPtr & 0x01) == 0x1) {\r
647 //\r
648 // It's multicast, try to match the multicast filters.\r
649 //\r
779ae357 650 NET_LIST_FOR_EACH (Entry, &MnpDeviceData->GroupAddressList) {\r
8a67d61d 651 *GroupAddress = NET_LIST_USER_STRUCT (Entry, MNP_GROUP_ADDRESS, AddrEntry);\r
652 if (NET_MAC_EQUAL (BufPtr, &((*GroupAddress)->Address), SnpMode->HwAddressSize)) {\r
653 RxData->MulticastFlag = TRUE;\r
654 break;\r
655 }\r
656 }\r
657\r
658 if (!RxData->MulticastFlag) {\r
659 //\r
660 // No match, set GroupAddress to NULL. This multicast packet must\r
661 // be the result of PROMISUCOUS or PROMISUCOUS_MULTICAST flag is on.\r
662 //\r
663 *GroupAddress = NULL;\r
664 RxData->PromiscuousFlag = TRUE;\r
665\r
779ae357 666 if (MnpDeviceData->PromiscuousCount == 0) {\r
8a67d61d 667 //\r
668 // Skip the below code, there is no receiver of this packet.\r
669 //\r
d1050b9d 670 return;\r
8a67d61d 671 }\r
672 }\r
673 } else {\r
674 RxData->PromiscuousFlag = TRUE;\r
675 }\r
676 }\r
677\r
e48e37fc 678 ZeroMem (&RxData->Timestamp, sizeof (EFI_TIME));\r
8a67d61d 679\r
680 //\r
681 // Fill the common parts of RxData.\r
682 //\r
683 RxData->PacketLength = Nbuf->TotalSize;\r
684 RxData->HeaderLength = SnpMode->MediaHeaderSize;\r
685 RxData->AddressLength = SnpMode->HwAddressSize;\r
686 RxData->DataLength = RxData->PacketLength - RxData->HeaderLength;\r
d1050b9d 687 RxData->ProtocolType = NTOHS (*(UINT16 *)(BufPtr + 2 * SnpMode->HwAddressSize));\r
8a67d61d 688}\r
689\r
8a67d61d 690/**\r
691 Wrap the RxData.\r
692\r
6e4bac4d 693 @param[in] Instance Pointer to the mnp instance context data.\r
694 @param[in] RxData Pointer to the receive data to wrap.\r
8a67d61d 695\r
696 @return Pointer to a MNP_RXDATA_WRAP which wraps the RxData.\r
697\r
698**/\r
8a67d61d 699MNP_RXDATA_WRAP *\r
700MnpWrapRxData (\r
d1050b9d
MK
701 IN MNP_INSTANCE_DATA *Instance,\r
702 IN EFI_MANAGED_NETWORK_RECEIVE_DATA *RxData\r
8a67d61d 703 )\r
704{\r
d1050b9d
MK
705 EFI_STATUS Status;\r
706 MNP_RXDATA_WRAP *RxDataWrap;\r
8a67d61d 707\r
708 //\r
709 // Allocate memory.\r
710 //\r
e48e37fc 711 RxDataWrap = AllocatePool (sizeof (MNP_RXDATA_WRAP));\r
8a67d61d 712 if (RxDataWrap == NULL) {\r
c49ca4a2 713 DEBUG ((DEBUG_ERROR, "MnpDispatchPacket: Failed to allocate a MNP_RXDATA_WRAP.\n"));\r
8a67d61d 714 return NULL;\r
715 }\r
716\r
717 RxDataWrap->Instance = Instance;\r
718\r
719 //\r
720 // Fill the RxData in RxDataWrap,\r
721 //\r
687a2e5f 722 CopyMem (&RxDataWrap->RxData, RxData, sizeof (RxDataWrap->RxData));\r
8a67d61d 723\r
724 //\r
725 // Create the recycle event.\r
726 //\r
727 Status = gBS->CreateEvent (\r
728 EVT_NOTIFY_SIGNAL,\r
e48e37fc 729 TPL_NOTIFY,\r
8a67d61d 730 MnpRecycleRxData,\r
731 RxDataWrap,\r
732 &RxDataWrap->RxData.RecycleEvent\r
733 );\r
734 if (EFI_ERROR (Status)) {\r
c49ca4a2 735 DEBUG ((DEBUG_ERROR, "MnpDispatchPacket: gBS->CreateEvent failed, %r.\n", Status));\r
779ae357 736\r
766c7483 737 FreePool (RxDataWrap);\r
8a67d61d 738 return NULL;\r
739 }\r
740\r
741 return RxDataWrap;\r
742}\r
743\r
8a67d61d 744/**\r
745 Enqueue the received the packets to the instances belonging to the\r
746 MnpServiceData.\r
747\r
6e4bac4d 748 @param[in] MnpServiceData Pointer to the mnp service context data.\r
749 @param[in] Nbuf Pointer to the net buffer representing the received\r
750 packet.\r
8a67d61d 751\r
752**/\r
8a67d61d 753VOID\r
754MnpEnqueuePacket (\r
d1050b9d
MK
755 IN MNP_SERVICE_DATA *MnpServiceData,\r
756 IN NET_BUF *Nbuf\r
8a67d61d 757 )\r
758{\r
e48e37fc 759 LIST_ENTRY *Entry;\r
8a67d61d 760 MNP_INSTANCE_DATA *Instance;\r
761 EFI_MANAGED_NETWORK_RECEIVE_DATA RxData;\r
762 UINT8 PktAttr;\r
763 MNP_GROUP_ADDRESS *GroupAddress;\r
764 MNP_RXDATA_WRAP *RxDataWrap;\r
765\r
67a58d0f 766 GroupAddress = NULL;\r
8a67d61d 767 //\r
768 // First, analyse the packet header.\r
769 //\r
770 MnpAnalysePacket (MnpServiceData, Nbuf, &RxData, &GroupAddress, &PktAttr);\r
771\r
779ae357 772 if (RxData.PromiscuousFlag && (MnpServiceData->MnpDeviceData->PromiscuousCount == 0)) {\r
8a67d61d 773 //\r
774 // No receivers, no more action need.\r
775 //\r
d1050b9d 776 return;\r
8a67d61d 777 }\r
778\r
779 //\r
780 // Iterate the children to find match.\r
781 //\r
782 NET_LIST_FOR_EACH (Entry, &MnpServiceData->ChildrenList) {\r
8a67d61d 783 Instance = NET_LIST_USER_STRUCT (Entry, MNP_INSTANCE_DATA, InstEntry);\r
784 NET_CHECK_SIGNATURE (Instance, MNP_INSTANCE_DATA_SIGNATURE);\r
785\r
786 if (!Instance->Configured) {\r
787 continue;\r
788 }\r
789\r
790 //\r
791 // Check the packet against the instance receive filters.\r
792 //\r
793 if (MnpMatchPacket (Instance, &RxData, GroupAddress, PktAttr)) {\r
8a67d61d 794 //\r
795 // Wrap the RxData.\r
796 //\r
687a2e5f 797 RxDataWrap = MnpWrapRxData (Instance, &RxData);\r
8a67d61d 798 if (RxDataWrap == NULL) {\r
799 continue;\r
800 }\r
801\r
802 //\r
803 // Associate RxDataWrap with Nbuf and increase the RefCnt.\r
804 //\r
805 RxDataWrap->Nbuf = Nbuf;\r
806 NET_GET_REF (RxDataWrap->Nbuf);\r
807\r
808 //\r
809 // Queue the packet into the instance queue.\r
810 //\r
811 MnpQueueRcvdPacket (Instance, RxDataWrap);\r
812 }\r
813 }\r
814}\r
815\r
8a67d61d 816/**\r
817 Try to receive a packet and deliver it.\r
818\r
779ae357 819 @param[in, out] MnpDeviceData Pointer to the mnp device context data.\r
8a67d61d 820\r
821 @retval EFI_SUCCESS add return value to function comment\r
822 @retval EFI_NOT_STARTED The simple network protocol is not started.\r
823 @retval EFI_NOT_READY No packet received.\r
824 @retval EFI_DEVICE_ERROR An unexpected error occurs.\r
825\r
826**/\r
827EFI_STATUS\r
828MnpReceivePacket (\r
d1050b9d 829 IN OUT MNP_DEVICE_DATA *MnpDeviceData\r
8a67d61d 830 )\r
831{\r
d1050b9d
MK
832 EFI_STATUS Status;\r
833 EFI_SIMPLE_NETWORK_PROTOCOL *Snp;\r
834 NET_BUF *Nbuf;\r
835 UINT8 *BufPtr;\r
836 UINTN BufLen;\r
837 UINTN HeaderSize;\r
838 UINT32 Trimmed;\r
839 MNP_SERVICE_DATA *MnpServiceData;\r
840 UINT16 VlanId;\r
841 BOOLEAN IsVlanPacket;\r
8a67d61d 842\r
779ae357 843 NET_CHECK_SIGNATURE (MnpDeviceData, MNP_DEVICE_DATA_SIGNATURE);\r
8a67d61d 844\r
779ae357 845 Snp = MnpDeviceData->Snp;\r
8a67d61d 846 if (Snp->Mode->State != EfiSimpleNetworkInitialized) {\r
847 //\r
848 // The simple network protocol is not started.\r
849 //\r
850 return EFI_NOT_STARTED;\r
851 }\r
852\r
779ae357 853 if (MnpDeviceData->RxNbufCache == NULL) {\r
8a67d61d 854 //\r
855 // Try to get a new buffer as there may be buffers recycled.\r
856 //\r
779ae357 857 MnpDeviceData->RxNbufCache = MnpAllocNbuf (MnpDeviceData);\r
8a67d61d 858\r
779ae357 859 if (MnpDeviceData->RxNbufCache == NULL) {\r
8a67d61d 860 //\r
2048c585 861 // No available buffer in the buffer pool.\r
8a67d61d 862 //\r
863 return EFI_DEVICE_ERROR;\r
864 }\r
865\r
866 NetbufAllocSpace (\r
779ae357 867 MnpDeviceData->RxNbufCache,\r
868 MnpDeviceData->BufferLength,\r
8a67d61d 869 NET_BUF_TAIL\r
870 );\r
871 }\r
872\r
d1050b9d
MK
873 Nbuf = MnpDeviceData->RxNbufCache;\r
874 BufLen = Nbuf->TotalSize;\r
875 BufPtr = NetbufGetByte (Nbuf, 0, NULL);\r
8a67d61d 876 ASSERT (BufPtr != NULL);\r
877\r
878 //\r
879 // Receive packet through Snp.\r
880 //\r
881 Status = Snp->Receive (Snp, &HeaderSize, &BufLen, BufPtr, NULL, NULL, NULL);\r
882 if (EFI_ERROR (Status)) {\r
ed7f7c91 883 DEBUG_CODE_BEGIN ();\r
d1050b9d
MK
884 if (Status != EFI_NOT_READY) {\r
885 DEBUG ((DEBUG_WARN, "MnpReceivePacket: Snp->Receive() = %r.\n", Status));\r
886 }\r
887\r
ed7f7c91 888 DEBUG_CODE_END ();\r
8a67d61d 889\r
890 return Status;\r
891 }\r
892\r
893 //\r
894 // Sanity check.\r
895 //\r
896 if ((HeaderSize != Snp->Mode->MediaHeaderSize) || (BufLen < HeaderSize)) {\r
e48e37fc 897 DEBUG (\r
c49ca4a2 898 (DEBUG_WARN,\r
d1050b9d
MK
899 "MnpReceivePacket: Size error, HL:TL = %d:%d.\n",\r
900 HeaderSize,\r
901 BufLen)\r
8a67d61d 902 );\r
903 return EFI_DEVICE_ERROR;\r
904 }\r
905\r
906 Trimmed = 0;\r
907 if (Nbuf->TotalSize != BufLen) {\r
908 //\r
909 // Trim the packet from tail.\r
910 //\r
d1050b9d 911 Trimmed = NetbufTrim (Nbuf, Nbuf->TotalSize - (UINT32)BufLen, NET_BUF_TAIL);\r
8a67d61d 912 ASSERT (Nbuf->TotalSize == BufLen);\r
913 }\r
914\r
779ae357 915 VlanId = 0;\r
ef89996c 916 if (MnpDeviceData->NumberOfVlan != 0) {\r
917 //\r
918 // VLAN is configured, remove the VLAN tag if any\r
919 //\r
920 IsVlanPacket = MnpRemoveVlanTag (MnpDeviceData, Nbuf, &VlanId);\r
921 } else {\r
922 IsVlanPacket = FALSE;\r
923 }\r
779ae357 924\r
925 MnpServiceData = MnpFindServiceData (MnpDeviceData, VlanId);\r
926 if (MnpServiceData == NULL) {\r
927 //\r
928 // VLAN is not set for this tagged frame, ignore this packet\r
929 //\r
930 if (Trimmed > 0) {\r
931 NetbufAllocSpace (Nbuf, Trimmed, NET_BUF_TAIL);\r
932 }\r
933\r
934 if (IsVlanPacket) {\r
935 NetbufAllocSpace (Nbuf, NET_VLAN_TAG_LEN, NET_BUF_HEAD);\r
936 }\r
937\r
938 goto EXIT;\r
939 }\r
940\r
8a67d61d 941 //\r
942 // Enqueue the packet to the matched instances.\r
943 //\r
944 MnpEnqueuePacket (MnpServiceData, Nbuf);\r
945\r
946 if (Nbuf->RefCnt > 2) {\r
947 //\r
948 // RefCnt > 2 indicates there is at least one receiver of this packet.\r
949 // Free the current RxNbufCache and allocate a new one.\r
950 //\r
779ae357 951 MnpFreeNbuf (MnpDeviceData, Nbuf);\r
8a67d61d 952\r
779ae357 953 Nbuf = MnpAllocNbuf (MnpDeviceData);\r
954 MnpDeviceData->RxNbufCache = Nbuf;\r
8a67d61d 955 if (Nbuf == NULL) {\r
c49ca4a2 956 DEBUG ((DEBUG_ERROR, "MnpReceivePacket: Alloc packet for receiving cache failed.\n"));\r
8a67d61d 957 return EFI_DEVICE_ERROR;\r
958 }\r
959\r
779ae357 960 NetbufAllocSpace (Nbuf, MnpDeviceData->BufferLength, NET_BUF_TAIL);\r
8a67d61d 961 } else {\r
962 //\r
963 // No receiver for this packet.\r
964 //\r
772db4bb 965 if (Trimmed > 0) {\r
966 NetbufAllocSpace (Nbuf, Trimmed, NET_BUF_TAIL);\r
967 }\r
d1050b9d 968\r
779ae357 969 if (IsVlanPacket) {\r
970 NetbufAllocSpace (Nbuf, NET_VLAN_TAG_LEN, NET_BUF_HEAD);\r
971 }\r
772db4bb 972\r
8a67d61d 973 goto EXIT;\r
974 }\r
d1050b9d 975\r
8a67d61d 976 //\r
977 // Deliver the queued packets.\r
978 //\r
979 MnpDeliverPacket (MnpServiceData);\r
980\r
981EXIT:\r
982\r
779ae357 983 ASSERT (Nbuf->TotalSize == MnpDeviceData->BufferLength);\r
8a67d61d 984\r
985 return Status;\r
986}\r
987\r
8a67d61d 988/**\r
989 Remove the received packets if timeout occurs.\r
990\r
dd29f3ed 991 @param[in] Event The event this notify function registered to.\r
992 @param[in] Context Pointer to the context data registered to the event.\r
779ae357 993\r
8a67d61d 994**/\r
995VOID\r
996EFIAPI\r
997MnpCheckPacketTimeout (\r
d1050b9d
MK
998 IN EFI_EVENT Event,\r
999 IN VOID *Context\r
8a67d61d 1000 )\r
1001{\r
d1050b9d
MK
1002 MNP_DEVICE_DATA *MnpDeviceData;\r
1003 MNP_SERVICE_DATA *MnpServiceData;\r
1004 LIST_ENTRY *Entry;\r
1005 LIST_ENTRY *ServiceEntry;\r
1006 LIST_ENTRY *RxEntry;\r
1007 LIST_ENTRY *NextEntry;\r
1008 MNP_INSTANCE_DATA *Instance;\r
1009 MNP_RXDATA_WRAP *RxDataWrap;\r
1010 EFI_TPL OldTpl;\r
1011\r
1012 MnpDeviceData = (MNP_DEVICE_DATA *)Context;\r
779ae357 1013 NET_CHECK_SIGNATURE (MnpDeviceData, MNP_DEVICE_DATA_SIGNATURE);\r
8a67d61d 1014\r
779ae357 1015 NET_LIST_FOR_EACH (ServiceEntry, &MnpDeviceData->ServiceList) {\r
1016 MnpServiceData = MNP_SERVICE_DATA_FROM_LINK (ServiceEntry);\r
8a67d61d 1017\r
779ae357 1018 NET_LIST_FOR_EACH (Entry, &MnpServiceData->ChildrenList) {\r
779ae357 1019 Instance = NET_LIST_USER_STRUCT (Entry, MNP_INSTANCE_DATA, InstEntry);\r
1020 NET_CHECK_SIGNATURE (Instance, MNP_INSTANCE_DATA_SIGNATURE);\r
8a67d61d 1021\r
779ae357 1022 if (!Instance->Configured || (Instance->ConfigData.ReceivedQueueTimeoutValue == 0)) {\r
1023 //\r
1024 // This instance is not configured or there is no receive time out,\r
1025 // just skip to the next instance.\r
1026 //\r
1027 continue;\r
1028 }\r
8a67d61d 1029\r
779ae357 1030 OldTpl = gBS->RaiseTPL (TPL_NOTIFY);\r
8a67d61d 1031\r
779ae357 1032 NET_LIST_FOR_EACH_SAFE (RxEntry, NextEntry, &Instance->RcvdPacketQueue) {\r
779ae357 1033 RxDataWrap = NET_LIST_USER_STRUCT (RxEntry, MNP_RXDATA_WRAP, WrapEntry);\r
8a67d61d 1034\r
8a67d61d 1035 //\r
779ae357 1036 // TimeoutTick unit is microsecond, MNP_TIMEOUT_CHECK_INTERVAL unit is 100ns.\r
8a67d61d 1037 //\r
779ae357 1038 if (RxDataWrap->TimeoutTick >= (MNP_TIMEOUT_CHECK_INTERVAL / 10)) {\r
1039 RxDataWrap->TimeoutTick -= (MNP_TIMEOUT_CHECK_INTERVAL / 10);\r
1040 } else {\r
1041 //\r
1042 // Drop the timeout packet.\r
1043 //\r
c49ca4a2 1044 DEBUG ((DEBUG_WARN, "MnpCheckPacketTimeout: Received packet timeout.\n"));\r
779ae357 1045 MnpRecycleRxData (NULL, RxDataWrap);\r
1046 Instance->RcvdPacketQueueSize--;\r
1047 }\r
8a67d61d 1048 }\r
8a67d61d 1049\r
779ae357 1050 gBS->RestoreTPL (OldTpl);\r
1051 }\r
8a67d61d 1052 }\r
1053}\r
1054\r
dd29f3ed 1055/**\r
1056 Poll to update MediaPresent field in SNP ModeData by Snp->GetStatus().\r
1057\r
1058 @param[in] Event The event this notify function registered to.\r
1059 @param[in] Context Pointer to the context data registered to the event.\r
1060\r
1061**/\r
1062VOID\r
1063EFIAPI\r
1064MnpCheckMediaStatus (\r
d1050b9d
MK
1065 IN EFI_EVENT Event,\r
1066 IN VOID *Context\r
dd29f3ed 1067 )\r
1068{\r
d1050b9d
MK
1069 MNP_DEVICE_DATA *MnpDeviceData;\r
1070 EFI_SIMPLE_NETWORK_PROTOCOL *Snp;\r
1071 UINT32 InterruptStatus;\r
dd29f3ed 1072\r
d1050b9d 1073 MnpDeviceData = (MNP_DEVICE_DATA *)Context;\r
dd29f3ed 1074 NET_CHECK_SIGNATURE (MnpDeviceData, MNP_DEVICE_DATA_SIGNATURE);\r
1075\r
1076 Snp = MnpDeviceData->Snp;\r
1077 if (Snp->Mode->MediaPresentSupported) {\r
1078 //\r
1079 // Upon successful return of GetStatus(), the MediaPresent field of\r
1080 // EFI_SIMPLE_NETWORK_MODE will be updated to reflect any change of media status\r
1081 //\r
1082 Snp->GetStatus (Snp, &InterruptStatus, NULL);\r
1083 }\r
1084}\r
1085\r
8a67d61d 1086/**\r
1087 Poll to receive the packets from Snp. This function is either called by upperlayer\r
1088 protocols/applications or the system poll timer notify mechanism.\r
1089\r
dd29f3ed 1090 @param[in] Event The event this notify function registered to.\r
1091 @param[in] Context Pointer to the context data registered to the event.\r
8a67d61d 1092\r
8a67d61d 1093**/\r
1094VOID\r
1095EFIAPI\r
1096MnpSystemPoll (\r
d1050b9d
MK
1097 IN EFI_EVENT Event,\r
1098 IN VOID *Context\r
8a67d61d 1099 )\r
1100{\r
779ae357 1101 MNP_DEVICE_DATA *MnpDeviceData;\r
8a67d61d 1102\r
d1050b9d 1103 MnpDeviceData = (MNP_DEVICE_DATA *)Context;\r
779ae357 1104 NET_CHECK_SIGNATURE (MnpDeviceData, MNP_DEVICE_DATA_SIGNATURE);\r
8a67d61d 1105\r
1106 //\r
1107 // Try to receive packets from Snp.\r
1108 //\r
779ae357 1109 MnpReceivePacket (MnpDeviceData);\r
36ee91ca 1110\r
a4df47f1 1111 //\r
1112 // Dispatch the DPC queued by the NotifyFunction of rx token's events.\r
1113 //\r
d8d26fb2 1114 DispatchDpc ();\r
8a67d61d 1115}\r