]> git.proxmox.com Git - mirror_edk2.git/blame - MdeModulePkg/Universal/Network/SnpDxe/Receive_filters.c
MdeModulePkg: Replace BSD License with BSD+Patent License
[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
d1102dba 5Copyright (c) 2004 - 2018, Intel Corporation. All rights reserved.<BR>\r
9d510e61 6SPDX-License-Identifier: BSD-2-Clause-Patent\r
28db6da4 7\r
28db6da4 8**/\r
9\r
10\r
11\r
12#include "Snp.h"\r
13\r
14/**\r
f3816027 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
d1102dba
LG
21 @param MCastAddressList List of new multicast addresses.\r
22\r
f3816027 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
28db6da4 27\r
28**/\r
28db6da4 29EFI_STATUS\r
4cda7726 30PxeRecvFilterEnable (\r
31 SNP_DRIVER *Snp,\r
28db6da4 32 UINT32 EnableFlags,\r
33 UINTN MCastAddressCount,\r
34 EFI_MAC_ADDRESS *MCastAddressList\r
35 )\r
36{\r
4cda7726 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
28db6da4 47\r
48 if ((EnableFlags & EFI_SIMPLE_NETWORK_RECEIVE_UNICAST) != 0) {\r
4cda7726 49 Snp->Cdb.OpFlags |= PXE_OPFLAGS_RECEIVE_FILTER_UNICAST;\r
28db6da4 50 }\r
51\r
52 if ((EnableFlags & EFI_SIMPLE_NETWORK_RECEIVE_BROADCAST) != 0) {\r
4cda7726 53 Snp->Cdb.OpFlags |= PXE_OPFLAGS_RECEIVE_FILTER_BROADCAST;\r
28db6da4 54 }\r
55\r
56 if ((EnableFlags & EFI_SIMPLE_NETWORK_RECEIVE_PROMISCUOUS) != 0) {\r
4cda7726 57 Snp->Cdb.OpFlags |= PXE_OPFLAGS_RECEIVE_FILTER_PROMISCUOUS;\r
28db6da4 58 }\r
59\r
60 if ((EnableFlags & EFI_SIMPLE_NETWORK_RECEIVE_PROMISCUOUS_MULTICAST) != 0) {\r
4cda7726 61 Snp->Cdb.OpFlags |= PXE_OPFLAGS_RECEIVE_FILTER_ALL_MULTICAST;\r
28db6da4 62 }\r
63\r
64 if ((EnableFlags & EFI_SIMPLE_NETWORK_RECEIVE_MULTICAST) != 0) {\r
4cda7726 65 Snp->Cdb.OpFlags |= PXE_OPFLAGS_RECEIVE_FILTER_FILTERED_MULTICAST;\r
28db6da4 66 }\r
67\r
68 if (MCastAddressCount != 0) {\r
4cda7726 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
28db6da4 72 }\r
73 //\r
74 // Issue UNDI command and check result.\r
75 //\r
9cff2f8d 76 DEBUG ((EFI_D_NET, "\nsnp->undi.receive_filters() "));\r
28db6da4 77\r
4cda7726 78 (*Snp->IssueUndi32Command) ((UINT64)(UINTN) &Snp->Cdb);\r
28db6da4 79\r
3af347b3 80 if (Snp->Cdb.StatCode != PXE_STATCODE_SUCCESS) {\r
28db6da4 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
4cda7726 87 Snp->Cdb.StatFlags,\r
88 Snp->Cdb.StatCode)\r
28db6da4 89 );\r
90\r
4cda7726 91 switch (Snp->Cdb.StatCode) {\r
28db6da4 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
f3816027 108 Call undi to disable the receive filters.\r
28db6da4 109\r
f3816027 110 @param Snp Pointer to snp driver structure\r
111 @param DisableFlags Bit mask for disabling the receive filters\r
d1102dba 112 @param ResetMCastList Boolean flag to reset/delete the multicast filter\r
f3816027 113 list.\r
28db6da4 114\r
f3816027 115 @retval EFI_SUCCESS The multicast receive filter list was updated.\r
116 @retval EFI_DEVICE_ERROR Fail to execute UNDI command.\r
d1102dba
LG
117\r
118**/\r
28db6da4 119EFI_STATUS\r
4cda7726 120PxeRecvFilterDisable (\r
121 SNP_DRIVER *Snp,\r
28db6da4 122 UINT32 DisableFlags,\r
123 BOOLEAN ResetMCastList\r
124 )\r
125{\r
4cda7726 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
28db6da4 137\r
138 if (ResetMCastList) {\r
4cda7726 139 Snp->Cdb.OpFlags |= PXE_OPFLAGS_RECEIVE_FILTER_RESET_MCAST_LIST;\r
28db6da4 140 }\r
141\r
142 if ((DisableFlags & EFI_SIMPLE_NETWORK_RECEIVE_UNICAST) != 0) {\r
4cda7726 143 Snp->Cdb.OpFlags |= PXE_OPFLAGS_RECEIVE_FILTER_UNICAST;\r
28db6da4 144 }\r
145\r
146 if ((DisableFlags & EFI_SIMPLE_NETWORK_RECEIVE_BROADCAST) != 0) {\r
4cda7726 147 Snp->Cdb.OpFlags |= PXE_OPFLAGS_RECEIVE_FILTER_BROADCAST;\r
28db6da4 148 }\r
149\r
150 if ((DisableFlags & EFI_SIMPLE_NETWORK_RECEIVE_PROMISCUOUS) != 0) {\r
4cda7726 151 Snp->Cdb.OpFlags |= PXE_OPFLAGS_RECEIVE_FILTER_PROMISCUOUS;\r
28db6da4 152 }\r
153\r
154 if ((DisableFlags & EFI_SIMPLE_NETWORK_RECEIVE_PROMISCUOUS_MULTICAST) != 0) {\r
4cda7726 155 Snp->Cdb.OpFlags |= PXE_OPFLAGS_RECEIVE_FILTER_ALL_MULTICAST;\r
28db6da4 156 }\r
157\r
158 if ((DisableFlags & EFI_SIMPLE_NETWORK_RECEIVE_MULTICAST) != 0) {\r
4cda7726 159 Snp->Cdb.OpFlags |= PXE_OPFLAGS_RECEIVE_FILTER_FILTERED_MULTICAST;\r
28db6da4 160 }\r
161 //\r
162 // Issue UNDI command and check result.\r
163 //\r
9cff2f8d 164 DEBUG ((EFI_D_NET, "\nsnp->undi.receive_filters() "));\r
28db6da4 165\r
4cda7726 166 (*Snp->IssueUndi32Command) ((UINT64)(UINTN) &Snp->Cdb);\r
28db6da4 167\r
3af347b3 168 if (Snp->Cdb.StatCode != PXE_STATCODE_SUCCESS) {\r
28db6da4 169 //\r
170 // UNDI command failed. Return UNDI status to caller.\r
171 //\r
172 DEBUG (\r
9cff2f8d 173 (EFI_D_ERROR,\r
28db6da4 174 "\nsnp->undi.receive_filters() %xh:%xh\n",\r
4cda7726 175 Snp->Cdb.StatFlags,\r
176 Snp->Cdb.StatCode)\r
28db6da4 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
f3816027 186 Call undi to read the receive filters.\r
28db6da4 187\r
f3816027 188 @param Snp Pointer to snp driver structure.\r
28db6da4 189\r
f3816027 190 @retval EFI_SUCCESS The receive filter was read.\r
d1102dba
LG
191 @retval EFI_DEVICE_ERROR Fail to execute UNDI command.\r
192\r
28db6da4 193**/\r
28db6da4 194EFI_STATUS\r
4cda7726 195PxeRecvFilterRead (\r
196 SNP_DRIVER *Snp\r
28db6da4 197 )\r
198{\r
4cda7726 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
28db6da4 206 } else {\r
4cda7726 207 Snp->Cdb.DBaddr = (UINT64)(UINTN) Snp->Db;\r
208 ZeroMem (Snp->Db, Snp->Cdb.DBsize);\r
28db6da4 209 }\r
210\r
4cda7726 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
28db6da4 215\r
9cff2f8d 216 DEBUG ((EFI_D_NET, "\nsnp->undi.receive_filters() "));\r
28db6da4 217\r
4cda7726 218 (*Snp->IssueUndi32Command) ((UINT64)(UINTN) &Snp->Cdb);\r
28db6da4 219\r
3af347b3 220 if (Snp->Cdb.StatCode != PXE_STATCODE_SUCCESS) {\r
28db6da4 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
4cda7726 227 Snp->Cdb.StatFlags,\r
228 Snp->Cdb.StatCode)\r
28db6da4 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
4cda7726 236 Snp->Mode.ReceiveFilterSetting = 0;\r
28db6da4 237\r
4cda7726 238 if ((Snp->Cdb.StatFlags & PXE_STATFLAGS_RECEIVE_FILTER_UNICAST) != 0) {\r
239 Snp->Mode.ReceiveFilterSetting |= EFI_SIMPLE_NETWORK_RECEIVE_UNICAST;\r
28db6da4 240 }\r
241\r
4cda7726 242 if ((Snp->Cdb.StatFlags & PXE_STATFLAGS_RECEIVE_FILTER_BROADCAST) != 0) {\r
243 Snp->Mode.ReceiveFilterSetting |= EFI_SIMPLE_NETWORK_RECEIVE_BROADCAST;\r
28db6da4 244 }\r
245\r
4cda7726 246 if ((Snp->Cdb.StatFlags & PXE_STATFLAGS_RECEIVE_FILTER_PROMISCUOUS) != 0) {\r
247 Snp->Mode.ReceiveFilterSetting |= EFI_SIMPLE_NETWORK_RECEIVE_PROMISCUOUS;\r
28db6da4 248 }\r
249\r
4cda7726 250 if ((Snp->Cdb.StatFlags & PXE_STATFLAGS_RECEIVE_FILTER_ALL_MULTICAST) != 0) {\r
251 Snp->Mode.ReceiveFilterSetting |= EFI_SIMPLE_NETWORK_RECEIVE_PROMISCUOUS_MULTICAST;\r
28db6da4 252 }\r
253\r
4cda7726 254 if ((Snp->Cdb.StatFlags & PXE_STATFLAGS_RECEIVE_FILTER_FILTERED_MULTICAST) != 0) {\r
255 Snp->Mode.ReceiveFilterSetting |= EFI_SIMPLE_NETWORK_RECEIVE_MULTICAST;\r
28db6da4 256 }\r
257\r
4cda7726 258 CopyMem (Snp->Mode.MCastFilter, Snp->Db, Snp->Cdb.DBsize);\r
28db6da4 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
4cda7726 268 for (Snp->Mode.MCastFilterCount = 0;\r
269 Snp->Mode.MCastFilterCount < Snp->Mode.MaxMCastFilterCount;\r
270 Snp->Mode.MCastFilterCount++\r
28db6da4 271 ) {\r
272 if (CompareMem (\r
4cda7726 273 &Snp->Mode.MCastFilter[Snp->Mode.MCastFilterCount],\r
28db6da4 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
4cda7726 287 Manages the multicast receive filters of a network interface.\r
d1102dba
LG
288\r
289 This function is used enable and disable the hardware and software receive\r
4cda7726 290 filters for the underlying network device.\r
d1102dba
LG
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
4cda7726 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
d1102dba 298 If the same bits are set in the Enable and Disable parameters, then the bits\r
4cda7726 299 in the Disable parameter takes precedence.\r
d1102dba
LG
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
4cda7726 303 to zero. The Snp->Mode->MCastFilter contents are undefined.\r
d1102dba
LG
304 After enabling or disabling receive filter settings, software should verify\r
305 the new settings by checking the Snp->Mode->ReceiveFilterSettings,\r
4cda7726 306 Snp->Mode->MCastFilterCount and Snp->Mode->MCastFilter fields.\r
d1102dba 307 Note: Some network drivers and/or devices will automatically promote receive\r
4cda7726 308 filter settings if the requested setting can not be honored. For example, if\r
d1102dba
LG
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
4cda7726 311 or promiscuous multicast receive filters instead. The receiving software is\r
d1102dba 312 responsible for discarding any extra packets that get through the hardware\r
4cda7726 313 receive filters.\r
d1102dba 314 Note: Note: To disable all receive filter hardware, the network driver must\r
4cda7726 315 be Shutdown() and Stopped(). Calling ReceiveFilters() with Disable set to\r
d1102dba
LG
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
4cda7726 318 moving packets into system memory before inspecting and discarding them.\r
d1102dba 319 Unexpected system errors, reboots and hangs can occur if an OS is loaded\r
4cda7726 320 and the network devices are not Shutdown() and Stopped().\r
d1102dba 321 If ResetMCastFilter is TRUE, then the multicast receive filter list on the\r
4cda7726 322 network interface will be reset to the default multicast receive filter list.\r
d1102dba
LG
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
4cda7726 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
d1102dba 330 If the receive filter mask and multicast receive filter list have been\r
4cda7726 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
d1102dba 337 interface. For backward compatibility with EFI 1.1\r
4cda7726 338 platforms, the EFI_SIMPLE_NETWORK_RECEIVE_MULTICAST bit\r
339 must be set when the ResetMCastFilter parameter is TRUE.\r
d1102dba
LG
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
4cda7726 343 @param MCastFilterCnt Number of multicast HW MAC addresses in the new MCastFilter\r
d1102dba
LG
344 list. This value must be less than or equal to the\r
345 MCastFilterCnt field of EFI_SIMPLE_NETWORK_MODE.\r
4cda7726 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
d1102dba
LG
348 MAC addresses. This list will replace any existing\r
349 multicast HW MAC address list. This field is optional\r
4cda7726 350 if ResetMCastFilter is TRUE.\r
d1102dba 351\r
4cda7726 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
d1102dba
LG
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
4cda7726 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
d1102dba 374 * An unexpected error was returned by the\r
4cda7726 375 underlying network driver or device\r
376 @retval EFI_UNSUPPORTED This function is not supported by the network\r
377 interface.\r
28db6da4 378\r
379**/\r
380EFI_STATUS\r
381EFIAPI\r
4cda7726 382SnpUndi32ReceiveFilters (\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
28db6da4 389 )\r
390{\r
4cda7726 391 SNP_DRIVER *Snp;\r
28db6da4 392 EFI_STATUS Status;\r
393 EFI_TPL OldTpl;\r
394\r
4cda7726 395 if (This == NULL) {\r
28db6da4 396 return EFI_INVALID_PARAMETER;\r
397 }\r
398\r
4cda7726 399 Snp = EFI_SIMPLE_NETWORK_DEV_FROM_THIS (This);\r
28db6da4 400\r
401 OldTpl = gBS->RaiseTPL (TPL_CALLBACK);\r
402\r
4cda7726 403 switch (Snp->Mode.State) {\r
28db6da4 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
4cda7726 419 if (((Enable &~Snp->Mode.ReceiveFilterMask) != 0) ||\r
420 ((Disable &~Snp->Mode.ReceiveFilterMask) != 0)) {\r
28db6da4 421 Status = EFI_INVALID_PARAMETER;\r
422 goto ON_EXIT;\r
423 }\r
424\r
4cda7726 425 if (ResetMCastFilter) {\r
28db6da4 426\r
4cda7726 427 Disable |= EFI_SIMPLE_NETWORK_RECEIVE_MULTICAST & Snp->Mode.ReceiveFilterMask;\r
428 MCastFilterCnt = 0;\r
429 MCastFilter = NULL;\r
28db6da4 430 } else {\r
4cda7726 431 if (MCastFilterCnt != 0) {\r
432 if ((MCastFilterCnt > Snp->Mode.MaxMCastFilterCount) ||\r
433 (MCastFilter == NULL)) {\r
28db6da4 434\r
435 Status = EFI_INVALID_PARAMETER;\r
436 goto ON_EXIT;\r
437 }\r
438 }\r
439 }\r
440\r
4cda7726 441 if (Enable == 0 && Disable == 0 && !ResetMCastFilter && MCastFilterCnt == 0) {\r
28db6da4 442 Status = EFI_SUCCESS;\r
443 goto ON_EXIT;\r
444 }\r
445\r
4cda7726 446 if ((Enable & EFI_SIMPLE_NETWORK_RECEIVE_MULTICAST) != 0 && MCastFilterCnt == 0) {\r
28db6da4 447 Status = EFI_INVALID_PARAMETER;\r
448 goto ON_EXIT;\r
449 }\r
450\r
4cda7726 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
28db6da4 458\r
459 if (EFI_ERROR (Status)) {\r
460 goto ON_EXIT;\r
461 }\r
462 }\r
463\r
4cda7726 464 if ((Disable != 0) || ResetMCastFilter) {\r
465 Status = PxeRecvFilterDisable (Snp, Disable, ResetMCastFilter);\r
28db6da4 466\r
467 if (EFI_ERROR (Status)) {\r
468 goto ON_EXIT;\r
469 }\r
470 }\r
471\r
4cda7726 472 Status = PxeRecvFilterRead (Snp);\r
28db6da4 473\r
474ON_EXIT:\r
475 gBS->RestoreTPL (OldTpl);\r
476\r
477 return Status;\r
478}\r