TianoCore EDK2 master
Loading...
Searching...
No Matches
Receive_filters.c
Go to the documentation of this file.
1
10#include "Snp.h"
11
29 SNP_DRIVER *Snp,
30 UINT32 EnableFlags,
31 UINTN MCastAddressCount,
32 EFI_MAC_ADDRESS *MCastAddressList
33 )
34{
35 Snp->Cdb.OpCode = PXE_OPCODE_RECEIVE_FILTERS;
36 Snp->Cdb.OpFlags = PXE_OPFLAGS_RECEIVE_FILTER_ENABLE;
37 Snp->Cdb.CPBsize = PXE_CPBSIZE_NOT_USED;
38 Snp->Cdb.DBsize = PXE_DBSIZE_NOT_USED;
39 Snp->Cdb.CPBaddr = PXE_CPBADDR_NOT_USED;
40 Snp->Cdb.DBaddr = PXE_DBADDR_NOT_USED;
41 Snp->Cdb.StatCode = PXE_STATCODE_INITIALIZE;
42 Snp->Cdb.StatFlags = PXE_STATFLAGS_INITIALIZE;
43 Snp->Cdb.IFnum = Snp->IfNum;
44 Snp->Cdb.Control = PXE_CONTROL_LAST_CDB_IN_LIST;
45
46 if ((EnableFlags & EFI_SIMPLE_NETWORK_RECEIVE_UNICAST) != 0) {
47 Snp->Cdb.OpFlags |= PXE_OPFLAGS_RECEIVE_FILTER_UNICAST;
48 }
49
50 if ((EnableFlags & EFI_SIMPLE_NETWORK_RECEIVE_BROADCAST) != 0) {
51 Snp->Cdb.OpFlags |= PXE_OPFLAGS_RECEIVE_FILTER_BROADCAST;
52 }
53
54 if ((EnableFlags & EFI_SIMPLE_NETWORK_RECEIVE_PROMISCUOUS) != 0) {
56 }
57
58 if ((EnableFlags & EFI_SIMPLE_NETWORK_RECEIVE_PROMISCUOUS_MULTICAST) != 0) {
60 }
61
62 if ((EnableFlags & EFI_SIMPLE_NETWORK_RECEIVE_MULTICAST) != 0) {
64 }
65
66 if (MCastAddressCount != 0) {
67 Snp->Cdb.CPBsize = (UINT16)(MCastAddressCount * sizeof (EFI_MAC_ADDRESS));
68 Snp->Cdb.CPBaddr = (UINT64)(UINTN)Snp->Cpb;
69 CopyMem (Snp->Cpb, MCastAddressList, Snp->Cdb.CPBsize);
70 }
71
72 //
73 // Issue UNDI command and check result.
74 //
75 DEBUG ((DEBUG_NET, "\nsnp->undi.receive_filters() "));
76
77 (*Snp->IssueUndi32Command)((UINT64)(UINTN)&Snp->Cdb);
78
79 if (Snp->Cdb.StatCode != PXE_STATCODE_SUCCESS) {
80 //
81 // UNDI command failed. Return UNDI status to caller.
82 //
83 DEBUG (
84 (DEBUG_ERROR,
85 "\nsnp->undi.receive_filters() %xh:%xh\n",
86 Snp->Cdb.StatFlags,
87 Snp->Cdb.StatCode)
88 );
89
90 switch (Snp->Cdb.StatCode) {
91 case PXE_STATCODE_INVALID_CDB:
92 case PXE_STATCODE_INVALID_CPB:
93 case PXE_STATCODE_INVALID_PARAMETER:
94 return EFI_INVALID_PARAMETER;
95
96 case PXE_STATCODE_UNSUPPORTED:
97 return EFI_UNSUPPORTED;
98 }
99
100 return EFI_DEVICE_ERROR;
101 }
102
103 return EFI_SUCCESS;
104}
105
120 SNP_DRIVER *Snp,
121 UINT32 DisableFlags,
122 BOOLEAN ResetMCastList
123 )
124{
125 Snp->Cdb.OpCode = PXE_OPCODE_RECEIVE_FILTERS;
126 Snp->Cdb.CPBsize = PXE_CPBSIZE_NOT_USED;
127 Snp->Cdb.DBsize = PXE_DBSIZE_NOT_USED;
128 Snp->Cdb.CPBaddr = PXE_CPBADDR_NOT_USED;
129 Snp->Cdb.DBaddr = PXE_DBADDR_NOT_USED;
130 Snp->Cdb.StatCode = PXE_STATCODE_INITIALIZE;
131 Snp->Cdb.StatFlags = PXE_STATFLAGS_INITIALIZE;
132 Snp->Cdb.IFnum = Snp->IfNum;
133 Snp->Cdb.Control = PXE_CONTROL_LAST_CDB_IN_LIST;
134
135 Snp->Cdb.OpFlags = (UINT16)((DisableFlags != 0) ? PXE_OPFLAGS_RECEIVE_FILTER_DISABLE : PXE_OPFLAGS_NOT_USED);
136
137 if (ResetMCastList) {
139 }
140
141 if ((DisableFlags & EFI_SIMPLE_NETWORK_RECEIVE_UNICAST) != 0) {
142 Snp->Cdb.OpFlags |= PXE_OPFLAGS_RECEIVE_FILTER_UNICAST;
143 }
144
145 if ((DisableFlags & EFI_SIMPLE_NETWORK_RECEIVE_BROADCAST) != 0) {
146 Snp->Cdb.OpFlags |= PXE_OPFLAGS_RECEIVE_FILTER_BROADCAST;
147 }
148
149 if ((DisableFlags & EFI_SIMPLE_NETWORK_RECEIVE_PROMISCUOUS) != 0) {
150 Snp->Cdb.OpFlags |= PXE_OPFLAGS_RECEIVE_FILTER_PROMISCUOUS;
151 }
152
153 if ((DisableFlags & EFI_SIMPLE_NETWORK_RECEIVE_PROMISCUOUS_MULTICAST) != 0) {
155 }
156
157 if ((DisableFlags & EFI_SIMPLE_NETWORK_RECEIVE_MULTICAST) != 0) {
159 }
160
161 //
162 // Issue UNDI command and check result.
163 //
164 DEBUG ((DEBUG_NET, "\nsnp->undi.receive_filters() "));
165
166 (*Snp->IssueUndi32Command)((UINT64)(UINTN)&Snp->Cdb);
167
168 if (Snp->Cdb.StatCode != PXE_STATCODE_SUCCESS) {
169 //
170 // UNDI command failed. Return UNDI status to caller.
171 //
172 DEBUG (
173 (DEBUG_ERROR,
174 "\nsnp->undi.receive_filters() %xh:%xh\n",
175 Snp->Cdb.StatFlags,
176 Snp->Cdb.StatCode)
177 );
178
179 return EFI_DEVICE_ERROR;
180 }
181
182 return EFI_SUCCESS;
183}
184
196 SNP_DRIVER *Snp
197 )
198{
199 Snp->Cdb.OpCode = PXE_OPCODE_RECEIVE_FILTERS;
200 Snp->Cdb.OpFlags = PXE_OPFLAGS_RECEIVE_FILTER_READ;
201 Snp->Cdb.CPBsize = PXE_CPBSIZE_NOT_USED;
202 Snp->Cdb.DBsize = (UINT16)(Snp->Mode.MaxMCastFilterCount * sizeof (EFI_MAC_ADDRESS));
203 Snp->Cdb.CPBaddr = PXE_CPBADDR_NOT_USED;
204 if (Snp->Cdb.DBsize == 0) {
205 Snp->Cdb.DBaddr = (UINT64)(UINTN)NULL;
206 } else {
207 Snp->Cdb.DBaddr = (UINT64)(UINTN)Snp->Db;
208 ZeroMem (Snp->Db, Snp->Cdb.DBsize);
209 }
210
211 Snp->Cdb.StatCode = PXE_STATCODE_INITIALIZE;
212 Snp->Cdb.StatFlags = PXE_STATFLAGS_INITIALIZE;
213 Snp->Cdb.IFnum = Snp->IfNum;
214 Snp->Cdb.Control = PXE_CONTROL_LAST_CDB_IN_LIST;
215
216 DEBUG ((DEBUG_NET, "\nsnp->undi.receive_filters() "));
217
218 (*Snp->IssueUndi32Command)((UINT64)(UINTN)&Snp->Cdb);
219
220 if (Snp->Cdb.StatCode != PXE_STATCODE_SUCCESS) {
221 //
222 // UNDI command failed. Return UNDI status to caller.
223 //
224 DEBUG (
225 (DEBUG_ERROR,
226 "\nsnp->undi.receive_filters() %xh:%xh\n",
227 Snp->Cdb.StatFlags,
228 Snp->Cdb.StatCode)
229 );
230
231 return EFI_DEVICE_ERROR;
232 }
233
234 //
235 // Convert UNDI32 StatFlags to EFI SNP filter flags.
236 //
237 Snp->Mode.ReceiveFilterSetting = 0;
238
239 if ((Snp->Cdb.StatFlags & PXE_STATFLAGS_RECEIVE_FILTER_UNICAST) != 0) {
240 Snp->Mode.ReceiveFilterSetting |= EFI_SIMPLE_NETWORK_RECEIVE_UNICAST;
241 }
242
243 if ((Snp->Cdb.StatFlags & PXE_STATFLAGS_RECEIVE_FILTER_BROADCAST) != 0) {
244 Snp->Mode.ReceiveFilterSetting |= EFI_SIMPLE_NETWORK_RECEIVE_BROADCAST;
245 }
246
247 if ((Snp->Cdb.StatFlags & PXE_STATFLAGS_RECEIVE_FILTER_PROMISCUOUS) != 0) {
248 Snp->Mode.ReceiveFilterSetting |= EFI_SIMPLE_NETWORK_RECEIVE_PROMISCUOUS;
249 }
250
251 if ((Snp->Cdb.StatFlags & PXE_STATFLAGS_RECEIVE_FILTER_ALL_MULTICAST) != 0) {
252 Snp->Mode.ReceiveFilterSetting |= EFI_SIMPLE_NETWORK_RECEIVE_PROMISCUOUS_MULTICAST;
253 }
254
255 if ((Snp->Cdb.StatFlags & PXE_STATFLAGS_RECEIVE_FILTER_FILTERED_MULTICAST) != 0) {
256 Snp->Mode.ReceiveFilterSetting |= EFI_SIMPLE_NETWORK_RECEIVE_MULTICAST;
257 }
258
259 CopyMem (Snp->Mode.MCastFilter, Snp->Db, Snp->Cdb.DBsize);
260
261 //
262 // Count number of active entries in multicast filter list.
263 //
264 {
265 EFI_MAC_ADDRESS ZeroMacAddr;
266
267 SetMem (&ZeroMacAddr, sizeof ZeroMacAddr, 0);
268
269 for (Snp->Mode.MCastFilterCount = 0;
270 Snp->Mode.MCastFilterCount < Snp->Mode.MaxMCastFilterCount;
271 Snp->Mode.MCastFilterCount++
272 )
273 {
274 if (CompareMem (
275 &Snp->Mode.MCastFilter[Snp->Mode.MCastFilterCount],
276 &ZeroMacAddr,
277 sizeof ZeroMacAddr
278 ) == 0)
279 {
280 break;
281 }
282 }
283 }
284
285 return EFI_SUCCESS;
286}
287
383EFIAPI
386 IN UINT32 Enable,
387 IN UINT32 Disable,
388 IN BOOLEAN ResetMCastFilter,
389 IN UINTN MCastFilterCnt OPTIONAL,
390 IN EFI_MAC_ADDRESS *MCastFilter OPTIONAL
391 )
392{
393 SNP_DRIVER *Snp;
394 EFI_STATUS Status;
395 EFI_TPL OldTpl;
396
397 if (This == NULL) {
398 return EFI_INVALID_PARAMETER;
399 }
400
401 Snp = EFI_SIMPLE_NETWORK_DEV_FROM_THIS (This);
402
403 OldTpl = gBS->RaiseTPL (TPL_CALLBACK);
404
405 switch (Snp->Mode.State) {
406 case EfiSimpleNetworkInitialized:
407 break;
408
409 case EfiSimpleNetworkStopped:
410 Status = EFI_NOT_STARTED;
411 goto ON_EXIT;
412
413 default:
414 Status = EFI_DEVICE_ERROR;
415 goto ON_EXIT;
416 }
417
418 //
419 // check if we are asked to enable or disable something that the UNDI
420 // does not even support!
421 //
422 if (((Enable &~Snp->Mode.ReceiveFilterMask) != 0) ||
423 ((Disable &~Snp->Mode.ReceiveFilterMask) != 0))
424 {
425 Status = EFI_INVALID_PARAMETER;
426 goto ON_EXIT;
427 }
428
429 if (ResetMCastFilter) {
430 Disable |= EFI_SIMPLE_NETWORK_RECEIVE_MULTICAST & Snp->Mode.ReceiveFilterMask;
431 MCastFilterCnt = 0;
432 MCastFilter = NULL;
433 } else {
434 if (MCastFilterCnt != 0) {
435 if ((MCastFilterCnt > Snp->Mode.MaxMCastFilterCount) ||
436 (MCastFilter == NULL))
437 {
438 Status = EFI_INVALID_PARAMETER;
439 goto ON_EXIT;
440 }
441 }
442 }
443
444 if ((Enable == 0) && (Disable == 0) && !ResetMCastFilter && (MCastFilterCnt == 0)) {
445 Status = EFI_SUCCESS;
446 goto ON_EXIT;
447 }
448
449 if (((Enable & EFI_SIMPLE_NETWORK_RECEIVE_MULTICAST) != 0) && (MCastFilterCnt == 0)) {
450 Status = EFI_INVALID_PARAMETER;
451 goto ON_EXIT;
452 }
453
454 if ((Enable != 0) || (MCastFilterCnt != 0)) {
455 Status = PxeRecvFilterEnable (
456 Snp,
457 Enable,
458 MCastFilterCnt,
459 MCastFilter
460 );
461
462 if (EFI_ERROR (Status)) {
463 goto ON_EXIT;
464 }
465 }
466
467 if ((Disable != 0) || ResetMCastFilter) {
468 Status = PxeRecvFilterDisable (Snp, Disable, ResetMCastFilter);
469
470 if (EFI_ERROR (Status)) {
471 goto ON_EXIT;
472 }
473 }
474
475 Status = PxeRecvFilterRead (Snp);
476
477ON_EXIT:
478 gBS->RestoreTPL (OldTpl);
479
480 return Status;
481}
UINT64 UINTN
INTN EFIAPI CompareMem(IN CONST VOID *DestinationBuffer, IN CONST VOID *SourceBuffer, IN UINTN Length)
VOID *EFIAPI CopyMem(OUT VOID *DestinationBuffer, IN CONST VOID *SourceBuffer, IN UINTN Length)
VOID *EFIAPI SetMem(OUT VOID *Buffer, IN UINTN Length, IN UINT8 Value)
Definition: SetMemWrapper.c:38
VOID *EFIAPI ZeroMem(OUT VOID *Buffer, IN UINTN Length)
#define NULL
Definition: Base.h:319
#define IN
Definition: Base.h:279
#define DEBUG(Expression)
Definition: DebugLib.h:434
EFI_STATUS PxeRecvFilterDisable(SNP_DRIVER *Snp, UINT32 DisableFlags, BOOLEAN ResetMCastList)
EFI_STATUS EFIAPI SnpUndi32ReceiveFilters(IN EFI_SIMPLE_NETWORK_PROTOCOL *This, IN UINT32 Enable, IN UINT32 Disable, IN BOOLEAN ResetMCastFilter, IN UINTN MCastFilterCnt OPTIONAL, IN EFI_MAC_ADDRESS *MCastFilter OPTIONAL)
EFI_STATUS PxeRecvFilterRead(SNP_DRIVER *Snp)
EFI_STATUS PxeRecvFilterEnable(SNP_DRIVER *Snp, UINT32 EnableFlags, UINTN MCastAddressCount, EFI_MAC_ADDRESS *MCastAddressList)
RETURN_STATUS EFI_STATUS
Definition: UefiBaseType.h:29
UINTN EFI_TPL
Definition: UefiBaseType.h:41
#define EFI_SUCCESS
Definition: UefiBaseType.h:112
EFI_BOOT_SERVICES * gBS
#define PXE_CPBSIZE_NOT_USED
zero
Definition: UefiPxe.h:57
#define PXE_OPFLAGS_RECEIVE_FILTER_UNICAST
Definition: UefiPxe.h:284
#define PXE_STATFLAGS_RECEIVE_FILTER_ALL_MULTICAST
Definition: UefiPxe.h:504
#define PXE_STATFLAGS_RECEIVE_FILTER_BROADCAST
Definition: UefiPxe.h:488
#define PXE_STATFLAGS_RECEIVE_FILTER_FILTERED_MULTICAST
Definition: UefiPxe.h:494
#define PXE_STATFLAGS_RECEIVE_FILTER_UNICAST
Definition: UefiPxe.h:483
#define PXE_OPFLAGS_RECEIVE_FILTER_RESET_MCAST_LIST
Definition: UefiPxe.h:278
#define PXE_OPFLAGS_RECEIVE_FILTER_PROMISCUOUS
Definition: UefiPxe.h:302
#define PXE_DBSIZE_NOT_USED
zero
Definition: UefiPxe.h:58
#define PXE_CPBADDR_NOT_USED
zero
Definition: UefiPxe.h:59
#define PXE_DBADDR_NOT_USED
zero
Definition: UefiPxe.h:60
#define PXE_OPFLAGS_RECEIVE_FILTER_FILTERED_MULTICAST
Definition: UefiPxe.h:297
#define PXE_OPCODE_RECEIVE_FILTERS
Definition: UefiPxe.h:130
#define PXE_STATFLAGS_RECEIVE_FILTER_PROMISCUOUS
Definition: UefiPxe.h:499
#define PXE_OPFLAGS_RECEIVE_FILTER_ALL_MULTICAST
Definition: UefiPxe.h:308
#define PXE_STATCODE_SUCCESS
Definition: UefiPxe.h:602
#define PXE_OPFLAGS_RECEIVE_FILTER_BROADCAST
Definition: UefiPxe.h:290
EFI_MAC_ADDRESS MCastFilter[MAX_MCAST_FILTER_CNT]
Definition: Snp.h:55