//\r
STATIC EFI_MAC_ADDRESS mZeroMacAddress;\r
\r
+STATIC\r
+VOID\r
+EFIAPI\r
+Ip4OnFrameSentDpc (\r
+ IN VOID *Context\r
+ );\r
+\r
STATIC\r
VOID\r
EFIAPI\r
IN VOID *Context\r
);\r
\r
+STATIC\r
+VOID\r
+EFIAPI\r
+Ip4OnArpResolvedDpc (\r
+ IN VOID *Context\r
+ );\r
+\r
STATIC\r
VOID\r
EFIAPI\r
IN VOID *Context\r
);\r
\r
+STATIC\r
+VOID\r
+EFIAPI\r
+Ip4OnFrameReceivedDpc (\r
+ IN VOID *Context\r
+ );\r
+\r
STATIC\r
VOID\r
EFIAPI\r
\r
Status = gBS->CreateEvent (\r
EVT_NOTIFY_SIGNAL,\r
- TPL_CALLBACK,\r
+ NET_TPL_EVENT,\r
Ip4OnFrameSent,\r
Token,\r
&MnpToken->Event\r
\r
Status = gBS->CreateEvent (\r
EVT_NOTIFY_SIGNAL,\r
- TPL_CALLBACK,\r
+ NET_TPL_EVENT,\r
Ip4OnArpResolved,\r
ArpQue,\r
&ArpQue->OnResolved\r
\r
Status = gBS->CreateEvent (\r
EVT_NOTIFY_SIGNAL,\r
- TPL_CALLBACK,\r
+ NET_TPL_EVENT,\r
Ip4OnFrameReceived,\r
Token,\r
&MnpToken->Event\r
Ip4CancelFrameArp (ArpQue, IoStatus, FrameToCancel, Context);\r
\r
if (NetListIsEmpty (&ArpQue->Frames)) {\r
- NetListRemoveEntry (Entry);\r
-\r
Interface->Arp->Cancel (Interface->Arp, &ArpQue->Ip, ArpQue->OnResolved);\r
- Ip4FreeArpQue (ArpQue, EFI_ABORTED);\r
}\r
}\r
\r
Token = NET_LIST_USER_STRUCT (Entry, IP4_LINK_TX_TOKEN, Link);\r
\r
if ((FrameToCancel == NULL) || FrameToCancel (Token, Context)) {\r
- NetListRemoveEntry (Entry);\r
-\r
Interface->Mnp->Cancel (Interface->Mnp, &Token->MnpToken);\r
- Token->CallBack (Token->IpInstance, Token->Packet, IoStatus, 0, Token->Context);\r
- Ip4FreeLinkTxToken (Token);\r
}\r
}\r
}\r
\r
Type = NetGetIpClass (IpAddr);\r
Len = NetGetMaskLength (SubnetMask);\r
- Netmask = mIp4AllMasks[NET_MIN (Len, Type << 3)];\r
+ Netmask = mIp4AllMasks[MIN (Len, Type << 3)];\r
Interface->NetBrdcast = (IpAddr | ~Netmask);\r
\r
//\r
all the queued frame if the ARP requests failed. Or transmit them\r
if the request succeed.\r
\r
- @param Event The Arp request event\r
@param Context The context of the callback, a point to the ARP\r
queue\r
\r
STATIC\r
VOID\r
EFIAPI\r
-Ip4OnArpResolved (\r
- IN EFI_EVENT Event,\r
+Ip4OnArpResolvedDpc (\r
IN VOID *Context\r
)\r
{\r
Token = NET_LIST_USER_STRUCT (Entry, IP4_LINK_TX_TOKEN, Link);\r
CopyMem (&Token->DstMac, &ArpQue->Mac, sizeof (Token->DstMac));\r
\r
- Status = Interface->Mnp->Transmit (Interface->Mnp, &Token->MnpToken);\r
+ //\r
+ // Insert the tx token before transmitting it via MNP as the FrameSentDpc\r
+ // may be called before Mnp->Transmit returns which will remove this tx\r
+ // token from the SentFrames list. Remove it from the list if the returned\r
+ // Status of Mnp->Transmit is not EFI_SUCCESS as in this case the\r
+ // FrameSentDpc won't be queued.\r
+ //\r
+ NetListInsertTail (&Interface->SentFrames, &Token->Link);\r
\r
+ Status = Interface->Mnp->Transmit (Interface->Mnp, &Token->MnpToken);\r
if (EFI_ERROR (Status)) {\r
+ NetListRemoveEntry (Entry);\r
Token->CallBack (Token->IpInstance, Token->Packet, Status, 0, Token->Context);\r
\r
Ip4FreeLinkTxToken (Token);\r
continue;\r
}\r
-\r
- NetListInsertTail (&Interface->SentFrames, &Token->Link);\r
}\r
\r
Ip4FreeArpQue (ArpQue, EFI_SUCCESS);\r
}\r
\r
+STATIC\r
+VOID\r
+EFIAPI\r
+Ip4OnArpResolved (\r
+ IN EFI_EVENT Event,\r
+ IN VOID *Context\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+ Request Ip4OnArpResolvedDpc as a DPC at TPL_CALLBACK\r
+\r
+Arguments:\r
+\r
+ Event - The Arp request event\r
+ Context - The context of the callback, a point to the ARP queue\r
+\r
+Returns:\r
+\r
+ None\r
+\r
+--*/\r
+{\r
+ //\r
+ // Request Ip4OnArpResolvedDpc as a DPC at TPL_CALLBACK\r
+ //\r
+ NetLibQueueDpc (TPL_CALLBACK, Ip4OnArpResolvedDpc, Context);\r
+}\r
+\r
+\r
\r
/**\r
Callback funtion when frame transmission is finished. It will\r
call the frame owner's callback function to tell it the result.\r
\r
- @param Event The transmit token's event\r
@param Context Context which is point to the token.\r
\r
@return None.\r
STATIC\r
VOID\r
EFIAPI\r
-Ip4OnFrameSent (\r
- IN EFI_EVENT Event,\r
+Ip4OnFrameSentDpc (\r
IN VOID *Context\r
)\r
{\r
Ip4FreeLinkTxToken (Token);\r
}\r
\r
+STATIC\r
+VOID\r
+EFIAPI\r
+Ip4OnFrameSent (\r
+ IN EFI_EVENT Event,\r
+ IN VOID *Context\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+ Request Ip4OnFrameSentDpc as a DPC at TPL_CALLBACK\r
+\r
+Arguments:\r
+\r
+ Event - The transmit token's event\r
+ Context - Context which is point to the token.\r
+\r
+Returns:\r
+\r
+ None.\r
+\r
+--*/\r
+{\r
+ //\r
+ // Request Ip4OnFrameSentDpc as a DPC at TPL_CALLBACK\r
+ //\r
+ NetLibQueueDpc (TPL_CALLBACK, Ip4OnFrameSentDpc, Context);\r
+}\r
+\r
\r
\r
/**\r
return EFI_SUCCESS;\r
\r
SEND_NOW:\r
+ //\r
+ // Insert the tx token into the SentFrames list before calling Mnp->Transmit.\r
+ // Remove it if the returned status is not EFI_SUCCESS.\r
+ //\r
+ NetListInsertTail (&Interface->SentFrames, &Token->Link);\r
Status = Interface->Mnp->Transmit (Interface->Mnp, &Token->MnpToken);\r
-\r
if (EFI_ERROR (Status)) {\r
+ NetListRemoveEntry (&Interface->SentFrames);\r
goto ON_ERROR;\r
}\r
\r
- NetListInsertTail (&Interface->SentFrames, &Token->Link);\r
return EFI_SUCCESS;\r
\r
ON_ERROR:\r
again call the Ip4RecycleFrame to signal MNP's event and free\r
the token used.\r
\r
- @param Event The receive event delivered to MNP for receive.\r
@param Context Context for the callback.\r
\r
@return None.\r
STATIC\r
VOID\r
EFIAPI\r
-Ip4OnFrameReceived (\r
- IN EFI_EVENT Event,\r
+Ip4OnFrameReceivedDpc (\r
IN VOID *Context\r
)\r
{\r
Token->CallBack (Token->IpInstance, Packet, EFI_SUCCESS, Flag, Token->Context);\r
}\r
\r
+STATIC\r
+VOID\r
+EFIAPI\r
+Ip4OnFrameReceived (\r
+ IN EFI_EVENT Event,\r
+ IN VOID *Context\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+ Request Ip4OnFrameReceivedDpc as a DPC at TPL_CALLBACK\r
+\r
+Arguments:\r
+\r
+ Event - The receive event delivered to MNP for receive.\r
+ Context - Context for the callback.\r
+\r
+Returns:\r
+\r
+ None.\r
+\r
+--*/\r
+{\r
+ //\r
+ // Request Ip4OnFrameReceivedDpc as a DPC at TPL_CALLBACK\r
+ //\r
+ NetLibQueueDpc (TPL_CALLBACK, Ip4OnFrameReceivedDpc, Context);\r
+}\r
+\r
\r
/**\r
Request to receive the packet from the interface.\r
return EFI_OUT_OF_RESOURCES;\r
}\r
\r
+ Interface->RecvRequest = Token;\r
Status = Interface->Mnp->Receive (Interface->Mnp, &Token->MnpToken);\r
-\r
if (EFI_ERROR (Status)) {\r
+ Interface->RecvRequest = NULL;\r
Ip4FreeFrameRxToken (Token);\r
return Status;\r
}\r
-\r
- Interface->RecvRequest = Token;\r
return EFI_SUCCESS;\r
}\r