BaseTools:Change the path of the file that Binary Cache
[mirror_edk2.git] / MdeModulePkg / Universal / Network / SnpDxe / Receive_filters.c
1 /** @file\r
2     Implementation of managing the multicast receive filters of a network\r
3     interface.\r
4 \r
5 Copyright (c) 2004 - 2018, Intel Corporation. All rights reserved.<BR>\r
6 SPDX-License-Identifier: BSD-2-Clause-Patent\r
7 \r
8 **/\r
9 \r
10 \r
11 \r
12 #include "Snp.h"\r
13 \r
14 /**\r
15   Call undi to enable the receive filters.\r
16 \r
17   @param  Snp                Pointer to snp driver structure.\r
18   @param  EnableFlags        Bit mask for enabling the receive filters.\r
19   @param  MCastAddressCount  Multicast address count for a new multicast address\r
20                              list.\r
21   @param  MCastAddressList   List of new multicast addresses.\r
22 \r
23   @retval EFI_SUCCESS           The multicast receive filter list was updated.\r
24   @retval EFI_INVALID_PARAMETER Invalid UNDI command.\r
25   @retval EFI_UNSUPPORTED       Command is not supported by UNDI.\r
26   @retval EFI_DEVICE_ERROR      Fail to execute UNDI command.\r
27 \r
28 **/\r
29 EFI_STATUS\r
30 PxeRecvFilterEnable (\r
31   SNP_DRIVER      *Snp,\r
32   UINT32          EnableFlags,\r
33   UINTN           MCastAddressCount,\r
34   EFI_MAC_ADDRESS *MCastAddressList\r
35   )\r
36 {\r
37   Snp->Cdb.OpCode     = PXE_OPCODE_RECEIVE_FILTERS;\r
38   Snp->Cdb.OpFlags    = PXE_OPFLAGS_RECEIVE_FILTER_ENABLE;\r
39   Snp->Cdb.CPBsize    = PXE_CPBSIZE_NOT_USED;\r
40   Snp->Cdb.DBsize     = PXE_DBSIZE_NOT_USED;\r
41   Snp->Cdb.CPBaddr    = PXE_CPBADDR_NOT_USED;\r
42   Snp->Cdb.DBaddr     = PXE_DBADDR_NOT_USED;\r
43   Snp->Cdb.StatCode   = PXE_STATCODE_INITIALIZE;\r
44   Snp->Cdb.StatFlags  = PXE_STATFLAGS_INITIALIZE;\r
45   Snp->Cdb.IFnum      = Snp->IfNum;\r
46   Snp->Cdb.Control    = PXE_CONTROL_LAST_CDB_IN_LIST;\r
47 \r
48   if ((EnableFlags & EFI_SIMPLE_NETWORK_RECEIVE_UNICAST) != 0) {\r
49     Snp->Cdb.OpFlags |= PXE_OPFLAGS_RECEIVE_FILTER_UNICAST;\r
50   }\r
51 \r
52   if ((EnableFlags & EFI_SIMPLE_NETWORK_RECEIVE_BROADCAST) != 0) {\r
53     Snp->Cdb.OpFlags |= PXE_OPFLAGS_RECEIVE_FILTER_BROADCAST;\r
54   }\r
55 \r
56   if ((EnableFlags & EFI_SIMPLE_NETWORK_RECEIVE_PROMISCUOUS) != 0) {\r
57     Snp->Cdb.OpFlags |= PXE_OPFLAGS_RECEIVE_FILTER_PROMISCUOUS;\r
58   }\r
59 \r
60   if ((EnableFlags & EFI_SIMPLE_NETWORK_RECEIVE_PROMISCUOUS_MULTICAST) != 0) {\r
61     Snp->Cdb.OpFlags |= PXE_OPFLAGS_RECEIVE_FILTER_ALL_MULTICAST;\r
62   }\r
63 \r
64   if ((EnableFlags & EFI_SIMPLE_NETWORK_RECEIVE_MULTICAST) != 0) {\r
65     Snp->Cdb.OpFlags |= PXE_OPFLAGS_RECEIVE_FILTER_FILTERED_MULTICAST;\r
66   }\r
67 \r
68   if (MCastAddressCount != 0) {\r
69     Snp->Cdb.CPBsize  = (UINT16) (MCastAddressCount * sizeof (EFI_MAC_ADDRESS));\r
70     Snp->Cdb.CPBaddr  = (UINT64)(UINTN)Snp->Cpb;\r
71     CopyMem (Snp->Cpb, MCastAddressList, Snp->Cdb.CPBsize);\r
72   }\r
73   //\r
74   // Issue UNDI command and check result.\r
75   //\r
76   DEBUG ((EFI_D_NET, "\nsnp->undi.receive_filters()  "));\r
77 \r
78   (*Snp->IssueUndi32Command) ((UINT64)(UINTN) &Snp->Cdb);\r
79 \r
80   if (Snp->Cdb.StatCode != PXE_STATCODE_SUCCESS) {\r
81     //\r
82     // UNDI command failed.  Return UNDI status to caller.\r
83     //\r
84     DEBUG (\r
85       (EFI_D_ERROR,\r
86       "\nsnp->undi.receive_filters()  %xh:%xh\n",\r
87       Snp->Cdb.StatFlags,\r
88       Snp->Cdb.StatCode)\r
89       );\r
90 \r
91     switch (Snp->Cdb.StatCode) {\r
92     case PXE_STATCODE_INVALID_CDB:\r
93     case PXE_STATCODE_INVALID_CPB:\r
94     case PXE_STATCODE_INVALID_PARAMETER:\r
95       return EFI_INVALID_PARAMETER;\r
96 \r
97     case PXE_STATCODE_UNSUPPORTED:\r
98       return EFI_UNSUPPORTED;\r
99     }\r
100 \r
101     return EFI_DEVICE_ERROR;\r
102   }\r
103 \r
104   return EFI_SUCCESS;\r
105 }\r
106 \r
107 /**\r
108   Call undi to disable the receive filters.\r
109 \r
110   @param  Snp             Pointer to snp driver structure\r
111   @param  DisableFlags    Bit mask for disabling the receive filters\r
112   @param  ResetMCastList  Boolean flag to reset/delete the multicast filter\r
113                           list.\r
114 \r
115   @retval EFI_SUCCESS           The multicast receive filter list was updated.\r
116   @retval EFI_DEVICE_ERROR      Fail to execute UNDI command.\r
117 \r
118 **/\r
119 EFI_STATUS\r
120 PxeRecvFilterDisable (\r
121   SNP_DRIVER *Snp,\r
122   UINT32     DisableFlags,\r
123   BOOLEAN    ResetMCastList\r
124   )\r
125 {\r
126   Snp->Cdb.OpCode     = PXE_OPCODE_RECEIVE_FILTERS;\r
127   Snp->Cdb.CPBsize    = PXE_CPBSIZE_NOT_USED;\r
128   Snp->Cdb.DBsize     = PXE_DBSIZE_NOT_USED;\r
129   Snp->Cdb.CPBaddr    = PXE_CPBADDR_NOT_USED;\r
130   Snp->Cdb.DBaddr     = PXE_DBADDR_NOT_USED;\r
131   Snp->Cdb.StatCode   = PXE_STATCODE_INITIALIZE;\r
132   Snp->Cdb.StatFlags  = PXE_STATFLAGS_INITIALIZE;\r
133   Snp->Cdb.IFnum      = Snp->IfNum;\r
134   Snp->Cdb.Control    = PXE_CONTROL_LAST_CDB_IN_LIST;\r
135 \r
136   Snp->Cdb.OpFlags    = (UINT16) ((DisableFlags != 0) ? PXE_OPFLAGS_RECEIVE_FILTER_DISABLE : PXE_OPFLAGS_NOT_USED);\r
137 \r
138   if (ResetMCastList) {\r
139     Snp->Cdb.OpFlags |= PXE_OPFLAGS_RECEIVE_FILTER_RESET_MCAST_LIST;\r
140   }\r
141 \r
142   if ((DisableFlags & EFI_SIMPLE_NETWORK_RECEIVE_UNICAST) != 0) {\r
143     Snp->Cdb.OpFlags |= PXE_OPFLAGS_RECEIVE_FILTER_UNICAST;\r
144   }\r
145 \r
146   if ((DisableFlags & EFI_SIMPLE_NETWORK_RECEIVE_BROADCAST) != 0) {\r
147     Snp->Cdb.OpFlags |= PXE_OPFLAGS_RECEIVE_FILTER_BROADCAST;\r
148   }\r
149 \r
150   if ((DisableFlags & EFI_SIMPLE_NETWORK_RECEIVE_PROMISCUOUS) != 0) {\r
151     Snp->Cdb.OpFlags |= PXE_OPFLAGS_RECEIVE_FILTER_PROMISCUOUS;\r
152   }\r
153 \r
154   if ((DisableFlags & EFI_SIMPLE_NETWORK_RECEIVE_PROMISCUOUS_MULTICAST) != 0) {\r
155     Snp->Cdb.OpFlags |= PXE_OPFLAGS_RECEIVE_FILTER_ALL_MULTICAST;\r
156   }\r
157 \r
158   if ((DisableFlags & EFI_SIMPLE_NETWORK_RECEIVE_MULTICAST) != 0) {\r
159     Snp->Cdb.OpFlags |= PXE_OPFLAGS_RECEIVE_FILTER_FILTERED_MULTICAST;\r
160   }\r
161   //\r
162   // Issue UNDI command and check result.\r
163   //\r
164   DEBUG ((EFI_D_NET, "\nsnp->undi.receive_filters()  "));\r
165 \r
166   (*Snp->IssueUndi32Command) ((UINT64)(UINTN) &Snp->Cdb);\r
167 \r
168   if (Snp->Cdb.StatCode != PXE_STATCODE_SUCCESS) {\r
169     //\r
170     // UNDI command failed.  Return UNDI status to caller.\r
171     //\r
172     DEBUG (\r
173       (EFI_D_ERROR,\r
174       "\nsnp->undi.receive_filters()  %xh:%xh\n",\r
175       Snp->Cdb.StatFlags,\r
176       Snp->Cdb.StatCode)\r
177       );\r
178 \r
179     return EFI_DEVICE_ERROR;\r
180   }\r
181 \r
182   return EFI_SUCCESS;\r
183 }\r
184 \r
185 /**\r
186   Call undi to read the receive filters.\r
187 \r
188   @param  Snp                Pointer to snp driver structure.\r
189 \r
190   @retval EFI_SUCCESS           The receive filter was read.\r
191   @retval EFI_DEVICE_ERROR      Fail to execute UNDI command.\r
192 \r
193 **/\r
194 EFI_STATUS\r
195 PxeRecvFilterRead (\r
196   SNP_DRIVER *Snp\r
197   )\r
198 {\r
199   Snp->Cdb.OpCode   = PXE_OPCODE_RECEIVE_FILTERS;\r
200   Snp->Cdb.OpFlags  = PXE_OPFLAGS_RECEIVE_FILTER_READ;\r
201   Snp->Cdb.CPBsize  = PXE_CPBSIZE_NOT_USED;\r
202   Snp->Cdb.DBsize   = (UINT16) (Snp->Mode.MaxMCastFilterCount * sizeof (EFI_MAC_ADDRESS));\r
203   Snp->Cdb.CPBaddr  = PXE_CPBADDR_NOT_USED;\r
204   if (Snp->Cdb.DBsize == 0) {\r
205     Snp->Cdb.DBaddr = (UINT64)(UINTN) NULL;\r
206   } else {\r
207     Snp->Cdb.DBaddr = (UINT64)(UINTN) Snp->Db;\r
208     ZeroMem (Snp->Db, Snp->Cdb.DBsize);\r
209   }\r
210 \r
211   Snp->Cdb.StatCode   = PXE_STATCODE_INITIALIZE;\r
212   Snp->Cdb.StatFlags  = PXE_STATFLAGS_INITIALIZE;\r
213   Snp->Cdb.IFnum      = Snp->IfNum;\r
214   Snp->Cdb.Control    = PXE_CONTROL_LAST_CDB_IN_LIST;\r
215 \r
216   DEBUG ((EFI_D_NET, "\nsnp->undi.receive_filters()  "));\r
217 \r
218   (*Snp->IssueUndi32Command) ((UINT64)(UINTN) &Snp->Cdb);\r
219 \r
220   if (Snp->Cdb.StatCode != PXE_STATCODE_SUCCESS) {\r
221     //\r
222     // UNDI command failed.  Return UNDI status to caller.\r
223     //\r
224     DEBUG (\r
225       (EFI_D_ERROR,\r
226       "\nsnp->undi.receive_filters()  %xh:%xh\n",\r
227       Snp->Cdb.StatFlags,\r
228       Snp->Cdb.StatCode)\r
229       );\r
230 \r
231     return EFI_DEVICE_ERROR;\r
232   }\r
233   //\r
234   // Convert UNDI32 StatFlags to EFI SNP filter flags.\r
235   //\r
236   Snp->Mode.ReceiveFilterSetting = 0;\r
237 \r
238   if ((Snp->Cdb.StatFlags & PXE_STATFLAGS_RECEIVE_FILTER_UNICAST) != 0) {\r
239     Snp->Mode.ReceiveFilterSetting |= EFI_SIMPLE_NETWORK_RECEIVE_UNICAST;\r
240   }\r
241 \r
242   if ((Snp->Cdb.StatFlags & PXE_STATFLAGS_RECEIVE_FILTER_BROADCAST) != 0) {\r
243     Snp->Mode.ReceiveFilterSetting |= EFI_SIMPLE_NETWORK_RECEIVE_BROADCAST;\r
244   }\r
245 \r
246   if ((Snp->Cdb.StatFlags & PXE_STATFLAGS_RECEIVE_FILTER_PROMISCUOUS) != 0) {\r
247     Snp->Mode.ReceiveFilterSetting |= EFI_SIMPLE_NETWORK_RECEIVE_PROMISCUOUS;\r
248   }\r
249 \r
250   if ((Snp->Cdb.StatFlags & PXE_STATFLAGS_RECEIVE_FILTER_ALL_MULTICAST) != 0) {\r
251     Snp->Mode.ReceiveFilterSetting |= EFI_SIMPLE_NETWORK_RECEIVE_PROMISCUOUS_MULTICAST;\r
252   }\r
253 \r
254   if ((Snp->Cdb.StatFlags & PXE_STATFLAGS_RECEIVE_FILTER_FILTERED_MULTICAST) != 0) {\r
255     Snp->Mode.ReceiveFilterSetting |= EFI_SIMPLE_NETWORK_RECEIVE_MULTICAST;\r
256   }\r
257 \r
258   CopyMem (Snp->Mode.MCastFilter, Snp->Db, Snp->Cdb.DBsize);\r
259 \r
260   //\r
261   // Count number of active entries in multicast filter list.\r
262   //\r
263   {\r
264     EFI_MAC_ADDRESS ZeroMacAddr;\r
265 \r
266     SetMem (&ZeroMacAddr, sizeof ZeroMacAddr, 0);\r
267 \r
268     for (Snp->Mode.MCastFilterCount = 0;\r
269          Snp->Mode.MCastFilterCount < Snp->Mode.MaxMCastFilterCount;\r
270          Snp->Mode.MCastFilterCount++\r
271         ) {\r
272       if (CompareMem (\r
273             &Snp->Mode.MCastFilter[Snp->Mode.MCastFilterCount],\r
274             &ZeroMacAddr,\r
275             sizeof ZeroMacAddr\r
276             ) == 0) {\r
277         break;\r
278       }\r
279     }\r
280   }\r
281 \r
282   return EFI_SUCCESS;\r
283 }\r
284 \r
285 \r
286 /**\r
287   Manages the multicast receive filters of a network interface.\r
288 \r
289   This function is used enable and disable the hardware and software receive\r
290   filters for the underlying network device.\r
291   The receive filter change is broken down into three steps:\r
292   * The filter mask bits that are set (ON) in the Enable parameter are added to\r
293     the current receive filter settings.\r
294   * The filter mask bits that are set (ON) in the Disable parameter are subtracted\r
295     from the updated receive filter settings.\r
296   * If the resulting receive filter setting is not supported by the hardware a\r
297     more liberal setting is selected.\r
298   If the same bits are set in the Enable and Disable parameters, then the bits\r
299   in the Disable parameter takes precedence.\r
300   If the ResetMCastFilter parameter is TRUE, then the multicast address list\r
301   filter is disabled (irregardless of what other multicast bits are set in the\r
302   Enable and Disable parameters). The SNP->Mode->MCastFilterCount field is set\r
303   to zero. The Snp->Mode->MCastFilter contents are undefined.\r
304   After enabling or disabling receive filter settings, software should verify\r
305   the new settings by checking the Snp->Mode->ReceiveFilterSettings,\r
306   Snp->Mode->MCastFilterCount and Snp->Mode->MCastFilter fields.\r
307   Note: Some network drivers and/or devices will automatically promote receive\r
308     filter settings if the requested setting can not be honored. For example, if\r
309     a request for four multicast addresses is made and the underlying hardware\r
310     only supports two multicast addresses the driver might set the promiscuous\r
311     or promiscuous multicast receive filters instead. The receiving software is\r
312     responsible for discarding any extra packets that get through the hardware\r
313     receive filters.\r
314     Note: Note: To disable all receive filter hardware, the network driver must\r
315       be Shutdown() and Stopped(). Calling ReceiveFilters() with Disable set to\r
316       Snp->Mode->ReceiveFilterSettings will make it so no more packets are\r
317       returned by the Receive() function, but the receive hardware may still be\r
318       moving packets into system memory before inspecting and discarding them.\r
319       Unexpected system errors, reboots and hangs can occur if an OS is loaded\r
320       and the network devices are not Shutdown() and Stopped().\r
321   If ResetMCastFilter is TRUE, then the multicast receive filter list on the\r
322   network interface will be reset to the default multicast receive filter list.\r
323   If ResetMCastFilter is FALSE, and this network interface allows the multicast\r
324   receive filter list to be modified, then the MCastFilterCnt and MCastFilter\r
325   are used to update the current multicast receive filter list. The modified\r
326   receive filter list settings can be found in the MCastFilter field of\r
327   EFI_SIMPLE_NETWORK_MODE. If the network interface does not allow the multicast\r
328   receive filter list to be modified, then EFI_INVALID_PARAMETER will be returned.\r
329   If the driver has not been initialized, EFI_DEVICE_ERROR will be returned.\r
330   If the receive filter mask and multicast receive filter list have been\r
331   successfully updated on the network interface, EFI_SUCCESS will be returned.\r
332 \r
333   @param This             A pointer to the EFI_SIMPLE_NETWORK_PROTOCOL instance.\r
334   @param Enable           A bit mask of receive filters to enable on the network\r
335                           interface.\r
336   @param Disable          A bit mask of receive filters to disable on the network\r
337                           interface. For backward compatibility with EFI 1.1\r
338                           platforms, the EFI_SIMPLE_NETWORK_RECEIVE_MULTICAST bit\r
339                           must be set when the ResetMCastFilter parameter is TRUE.\r
340   @param ResetMCastFilter Set to TRUE to reset the contents of the multicast\r
341                           receive filters on the network interface to their\r
342                           default values.\r
343   @param MCastFilterCnt   Number of multicast HW MAC addresses in the new MCastFilter\r
344                           list. This value must be less than or equal to the\r
345                           MCastFilterCnt field of EFI_SIMPLE_NETWORK_MODE.\r
346                           This field is optional if ResetMCastFilter is TRUE.\r
347   @param MCastFilter      A pointer to a list of new multicast receive filter HW\r
348                           MAC addresses. This list will replace any existing\r
349                           multicast HW MAC address list. This field is optional\r
350                           if ResetMCastFilter is TRUE.\r
351 \r
352   @retval EFI_SUCCESS            The multicast receive filter list was updated.\r
353   @retval EFI_NOT_STARTED        The network interface has not been started.\r
354   @retval EFI_INVALID_PARAMETER  One or more of the following conditions is TRUE:\r
355                                  * This is NULL\r
356                                  * There are bits set in Enable that are not set\r
357                                    in Snp->Mode->ReceiveFilterMask\r
358                                  * There are bits set in Disable that are not set\r
359                                    in Snp->Mode->ReceiveFilterMask\r
360                                  * Multicast is being enabled (the\r
361                                    EFI_SIMPLE_NETWORK_RECEIVE_MULTICAST bit is\r
362                                    set in Enable, it is not set in Disable, and\r
363                                    ResetMCastFilter is FALSE) and MCastFilterCount\r
364                                    is zero\r
365                                  * Multicast is being enabled and MCastFilterCount\r
366                                    is greater than Snp->Mode->MaxMCastFilterCount\r
367                                  * Multicast is being enabled and MCastFilter is NULL\r
368                                  * Multicast is being enabled and one or more of\r
369                                    the addresses in the MCastFilter list are not\r
370                                    valid multicast MAC addresses\r
371   @retval EFI_DEVICE_ERROR       One or more of the following conditions is TRUE:\r
372                                  * The network interface has been started but has\r
373                                    not been initialized\r
374                                  * An unexpected error was returned by the\r
375                                    underlying network driver or device\r
376   @retval EFI_UNSUPPORTED        This function is not supported by the network\r
377                                  interface.\r
378 \r
379 **/\r
380 EFI_STATUS\r
381 EFIAPI\r
382 SnpUndi32ReceiveFilters (\r
383   IN EFI_SIMPLE_NETWORK_PROTOCOL *This,\r
384   IN UINT32                      Enable,\r
385   IN UINT32                      Disable,\r
386   IN BOOLEAN                     ResetMCastFilter,\r
387   IN UINTN                       MCastFilterCnt,  OPTIONAL\r
388   IN EFI_MAC_ADDRESS             *MCastFilter     OPTIONAL\r
389   )\r
390 {\r
391   SNP_DRIVER  *Snp;\r
392   EFI_STATUS  Status;\r
393   EFI_TPL     OldTpl;\r
394 \r
395   if (This == NULL) {\r
396     return EFI_INVALID_PARAMETER;\r
397   }\r
398 \r
399   Snp = EFI_SIMPLE_NETWORK_DEV_FROM_THIS (This);\r
400 \r
401   OldTpl = gBS->RaiseTPL (TPL_CALLBACK);\r
402 \r
403   switch (Snp->Mode.State) {\r
404   case EfiSimpleNetworkInitialized:\r
405     break;\r
406 \r
407   case EfiSimpleNetworkStopped:\r
408     Status = EFI_NOT_STARTED;\r
409     goto ON_EXIT;\r
410 \r
411   default:\r
412     Status = EFI_DEVICE_ERROR;\r
413     goto ON_EXIT;\r
414   }\r
415   //\r
416   // check if we are asked to enable or disable something that the UNDI\r
417   // does not even support!\r
418   //\r
419   if (((Enable &~Snp->Mode.ReceiveFilterMask) != 0) ||\r
420     ((Disable &~Snp->Mode.ReceiveFilterMask) != 0)) {\r
421     Status = EFI_INVALID_PARAMETER;\r
422     goto ON_EXIT;\r
423   }\r
424 \r
425   if (ResetMCastFilter) {\r
426 \r
427     Disable |= EFI_SIMPLE_NETWORK_RECEIVE_MULTICAST & Snp->Mode.ReceiveFilterMask;\r
428     MCastFilterCnt = 0;\r
429     MCastFilter    = NULL;\r
430   } else {\r
431     if (MCastFilterCnt != 0) {\r
432       if ((MCastFilterCnt > Snp->Mode.MaxMCastFilterCount) ||\r
433           (MCastFilter == NULL)) {\r
434 \r
435         Status = EFI_INVALID_PARAMETER;\r
436         goto ON_EXIT;\r
437       }\r
438     }\r
439   }\r
440 \r
441   if (Enable == 0 && Disable == 0 && !ResetMCastFilter && MCastFilterCnt == 0) {\r
442     Status = EFI_SUCCESS;\r
443     goto ON_EXIT;\r
444   }\r
445 \r
446   if ((Enable & EFI_SIMPLE_NETWORK_RECEIVE_MULTICAST) != 0 && MCastFilterCnt == 0) {\r
447     Status = EFI_INVALID_PARAMETER;\r
448     goto ON_EXIT;\r
449   }\r
450 \r
451   if ((Enable != 0) || (MCastFilterCnt != 0)) {\r
452     Status = PxeRecvFilterEnable (\r
453                Snp,\r
454                Enable,\r
455                MCastFilterCnt,\r
456                MCastFilter\r
457                );\r
458 \r
459     if (EFI_ERROR (Status)) {\r
460       goto ON_EXIT;\r
461     }\r
462   }\r
463 \r
464   if ((Disable != 0) || ResetMCastFilter) {\r
465     Status = PxeRecvFilterDisable (Snp, Disable, ResetMCastFilter);\r
466 \r
467     if (EFI_ERROR (Status)) {\r
468       goto ON_EXIT;\r
469     }\r
470   }\r
471 \r
472   Status = PxeRecvFilterRead (Snp);\r
473 \r
474 ON_EXIT:\r
475   gBS->RestoreTPL (OldTpl);\r
476 \r
477   return Status;\r
478 }\r