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