]> git.proxmox.com Git - mirror_edk2.git/blob - MdeModulePkg/Universal/Network/SnpDxe/Receive_filters.c
Patch to remove STATIC modifier. This is on longer recommended by EFI Framework codin...
[mirror_edk2.git] / MdeModulePkg / Universal / Network / SnpDxe / Receive_filters.c
1 /** @file
2 Copyright (c) 2004 - 2007, Intel Corporation
3 All rights reserved. This program and the accompanying materials
4 are licensed and made available under the terms and conditions of the BSD License
5 which accompanies this distribution. The full text of the license may be found at
6 http://opensource.org/licenses/bsd-license.php
7
8 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
9 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
10
11 Module name:
12 receive_filters.c
13
14 Abstract:
15
16 Revision history:
17 2000-Feb-17 M(f)J Genesis.
18
19 **/
20
21
22
23 #include "Snp.h"
24
25 /**
26 this routine calls undi to enable the receive filters.
27
28 @param snp pointer to snp driver structure
29 @param EnableFlags bit mask for enabling the receive filters
30 @param MCastAddressCount multicast address count for a new multicast address
31 list
32 @param MCastAddressList list of new multicast addresses
33
34
35 **/
36 EFI_STATUS
37 pxe_rcvfilter_enable (
38 SNP_DRIVER *snp,
39 UINT32 EnableFlags,
40 UINTN MCastAddressCount,
41 EFI_MAC_ADDRESS *MCastAddressList
42 )
43 {
44 snp->cdb.OpCode = PXE_OPCODE_RECEIVE_FILTERS;
45 snp->cdb.OpFlags = PXE_OPFLAGS_RECEIVE_FILTER_ENABLE;
46 snp->cdb.CPBsize = PXE_CPBSIZE_NOT_USED;
47 snp->cdb.DBsize = PXE_DBSIZE_NOT_USED;
48 snp->cdb.CPBaddr = PXE_CPBADDR_NOT_USED;
49 snp->cdb.DBaddr = PXE_DBADDR_NOT_USED;
50 snp->cdb.StatCode = PXE_STATCODE_INITIALIZE;
51 snp->cdb.StatFlags = PXE_STATFLAGS_INITIALIZE;
52 snp->cdb.IFnum = snp->if_num;
53 snp->cdb.Control = PXE_CONTROL_LAST_CDB_IN_LIST;
54
55 if ((EnableFlags & EFI_SIMPLE_NETWORK_RECEIVE_UNICAST) != 0) {
56 snp->cdb.OpFlags |= PXE_OPFLAGS_RECEIVE_FILTER_UNICAST;
57 }
58
59 if ((EnableFlags & EFI_SIMPLE_NETWORK_RECEIVE_BROADCAST) != 0) {
60 snp->cdb.OpFlags |= PXE_OPFLAGS_RECEIVE_FILTER_BROADCAST;
61 }
62
63 if ((EnableFlags & EFI_SIMPLE_NETWORK_RECEIVE_PROMISCUOUS) != 0) {
64 snp->cdb.OpFlags |= PXE_OPFLAGS_RECEIVE_FILTER_PROMISCUOUS;
65 }
66
67 if ((EnableFlags & EFI_SIMPLE_NETWORK_RECEIVE_PROMISCUOUS_MULTICAST) != 0) {
68 snp->cdb.OpFlags |= PXE_OPFLAGS_RECEIVE_FILTER_ALL_MULTICAST;
69 }
70
71 if ((EnableFlags & EFI_SIMPLE_NETWORK_RECEIVE_MULTICAST) != 0) {
72 snp->cdb.OpFlags |= PXE_OPFLAGS_RECEIVE_FILTER_FILTERED_MULTICAST;
73 }
74
75 if (MCastAddressCount != 0) {
76 snp->cdb.CPBsize = (UINT16) (MCastAddressCount * sizeof (EFI_MAC_ADDRESS));
77 snp->cdb.CPBaddr = (UINT64)(UINTN) snp->cpb;
78 CopyMem (snp->cpb, MCastAddressList, snp->cdb.CPBsize);
79 }
80 //
81 // Issue UNDI command and check result.
82 //
83 DEBUG ((EFI_D_NET, "\nsnp->undi.receive_filters() "));
84
85 (*snp->issue_undi32_command) ((UINT64)(UINTN) &snp->cdb);
86
87 if (snp->cdb.StatCode != EFI_SUCCESS) {
88 //
89 // UNDI command failed. Return UNDI status to caller.
90 //
91 DEBUG (
92 (EFI_D_ERROR,
93 "\nsnp->undi.receive_filters() %xh:%xh\n",
94 snp->cdb.StatFlags,
95 snp->cdb.StatCode)
96 );
97
98 switch (snp->cdb.StatCode) {
99 case PXE_STATCODE_INVALID_CDB:
100 case PXE_STATCODE_INVALID_CPB:
101 case PXE_STATCODE_INVALID_PARAMETER:
102 return EFI_INVALID_PARAMETER;
103
104 case PXE_STATCODE_UNSUPPORTED:
105 return EFI_UNSUPPORTED;
106 }
107
108 return EFI_DEVICE_ERROR;
109 }
110
111 return EFI_SUCCESS;
112 }
113
114 /**
115 this routine calls undi to disable the receive filters.
116
117 @param snp pointer to snp driver structure
118 @param DisableFlags bit mask for disabling the receive filters
119 @param ResetMCastList boolean flag to reset/delete the multicast filter list
120
121
122 **/
123 EFI_STATUS
124 pxe_rcvfilter_disable (
125 SNP_DRIVER *snp,
126 UINT32 DisableFlags,
127 BOOLEAN ResetMCastList
128 )
129 {
130 snp->cdb.OpCode = PXE_OPCODE_RECEIVE_FILTERS;
131 snp->cdb.CPBsize = PXE_CPBSIZE_NOT_USED;
132 snp->cdb.DBsize = PXE_DBSIZE_NOT_USED;
133 snp->cdb.CPBaddr = PXE_CPBADDR_NOT_USED;
134 snp->cdb.DBaddr = PXE_DBADDR_NOT_USED;
135 snp->cdb.StatCode = PXE_STATCODE_INITIALIZE;
136 snp->cdb.StatFlags = PXE_STATFLAGS_INITIALIZE;
137 snp->cdb.IFnum = snp->if_num;
138 snp->cdb.Control = PXE_CONTROL_LAST_CDB_IN_LIST;
139
140 snp->cdb.OpFlags = (UINT16) (DisableFlags ? PXE_OPFLAGS_RECEIVE_FILTER_DISABLE : PXE_OPFLAGS_NOT_USED);
141
142 if (ResetMCastList) {
143 snp->cdb.OpFlags |= PXE_OPFLAGS_RECEIVE_FILTER_RESET_MCAST_LIST;
144 }
145
146 if ((DisableFlags & EFI_SIMPLE_NETWORK_RECEIVE_UNICAST) != 0) {
147 snp->cdb.OpFlags |= PXE_OPFLAGS_RECEIVE_FILTER_UNICAST;
148 }
149
150 if ((DisableFlags & EFI_SIMPLE_NETWORK_RECEIVE_BROADCAST) != 0) {
151 snp->cdb.OpFlags |= PXE_OPFLAGS_RECEIVE_FILTER_BROADCAST;
152 }
153
154 if ((DisableFlags & EFI_SIMPLE_NETWORK_RECEIVE_PROMISCUOUS) != 0) {
155 snp->cdb.OpFlags |= PXE_OPFLAGS_RECEIVE_FILTER_PROMISCUOUS;
156 }
157
158 if ((DisableFlags & EFI_SIMPLE_NETWORK_RECEIVE_PROMISCUOUS_MULTICAST) != 0) {
159 snp->cdb.OpFlags |= PXE_OPFLAGS_RECEIVE_FILTER_ALL_MULTICAST;
160 }
161
162 if ((DisableFlags & EFI_SIMPLE_NETWORK_RECEIVE_MULTICAST) != 0) {
163 snp->cdb.OpFlags |= PXE_OPFLAGS_RECEIVE_FILTER_FILTERED_MULTICAST;
164 }
165 //
166 // Issue UNDI command and check result.
167 //
168 DEBUG ((EFI_D_NET, "\nsnp->undi.receive_filters() "));
169
170 (*snp->issue_undi32_command) ((UINT64)(UINTN) &snp->cdb);
171
172 if (snp->cdb.StatCode != EFI_SUCCESS) {
173 //
174 // UNDI command failed. Return UNDI status to caller.
175 //
176 DEBUG (
177 (EFI_D_ERROR,
178 "\nsnp->undi.receive_filters() %xh:%xh\n",
179 snp->cdb.StatFlags,
180 snp->cdb.StatCode)
181 );
182
183 return EFI_DEVICE_ERROR;
184 }
185
186 return EFI_SUCCESS;
187 }
188
189 /**
190 this routine calls undi to read the receive filters.
191
192 @param snp pointer to snp driver structure
193
194
195 **/
196 EFI_STATUS
197 pxe_rcvfilter_read (
198 SNP_DRIVER *snp
199 )
200 {
201 snp->cdb.OpCode = PXE_OPCODE_RECEIVE_FILTERS;
202 snp->cdb.OpFlags = PXE_OPFLAGS_RECEIVE_FILTER_READ;
203 snp->cdb.CPBsize = PXE_CPBSIZE_NOT_USED;
204 snp->cdb.DBsize = (UINT16) (snp->mode.MaxMCastFilterCount * sizeof (EFI_MAC_ADDRESS));
205 snp->cdb.CPBaddr = PXE_CPBADDR_NOT_USED;
206 if (snp->cdb.DBsize == 0) {
207 snp->cdb.DBaddr = (UINT64)(UINTN) NULL;
208 } else {
209 snp->cdb.DBaddr = (UINT64)(UINTN) snp->db;
210 ZeroMem (snp->db, snp->cdb.DBsize);
211 }
212
213 snp->cdb.StatCode = PXE_STATCODE_INITIALIZE;
214 snp->cdb.StatFlags = PXE_STATFLAGS_INITIALIZE;
215 snp->cdb.IFnum = snp->if_num;
216 snp->cdb.Control = PXE_CONTROL_LAST_CDB_IN_LIST;
217
218 DEBUG ((EFI_D_NET, "\nsnp->undi.receive_filters() "));
219
220 (*snp->issue_undi32_command) ((UINT64)(UINTN) &snp->cdb);
221
222 if (snp->cdb.StatCode != EFI_SUCCESS) {
223 //
224 // UNDI command failed. Return UNDI status to caller.
225 //
226 DEBUG (
227 (EFI_D_ERROR,
228 "\nsnp->undi.receive_filters() %xh:%xh\n",
229 snp->cdb.StatFlags,
230 snp->cdb.StatCode)
231 );
232
233 return EFI_DEVICE_ERROR;
234 }
235 //
236 // Convert UNDI32 StatFlags to EFI SNP filter flags.
237 //
238 snp->mode.ReceiveFilterSetting = 0;
239
240 if ((snp->cdb.StatFlags & PXE_STATFLAGS_RECEIVE_FILTER_UNICAST) != 0) {
241 snp->mode.ReceiveFilterSetting |= EFI_SIMPLE_NETWORK_RECEIVE_UNICAST;
242 }
243
244 if ((snp->cdb.StatFlags & PXE_STATFLAGS_RECEIVE_FILTER_BROADCAST) != 0) {
245 snp->mode.ReceiveFilterSetting |= EFI_SIMPLE_NETWORK_RECEIVE_BROADCAST;
246 }
247
248 if ((snp->cdb.StatFlags & PXE_STATFLAGS_RECEIVE_FILTER_PROMISCUOUS) != 0) {
249 snp->mode.ReceiveFilterSetting |= EFI_SIMPLE_NETWORK_RECEIVE_PROMISCUOUS;
250 }
251
252 if ((snp->cdb.StatFlags & PXE_STATFLAGS_RECEIVE_FILTER_ALL_MULTICAST) != 0) {
253 snp->mode.ReceiveFilterSetting |= EFI_SIMPLE_NETWORK_RECEIVE_PROMISCUOUS_MULTICAST;
254 }
255
256 if ((snp->cdb.StatFlags & PXE_STATFLAGS_RECEIVE_FILTER_FILTERED_MULTICAST) != 0) {
257 snp->mode.ReceiveFilterSetting |= EFI_SIMPLE_NETWORK_RECEIVE_MULTICAST;
258 }
259
260 CopyMem (snp->mode.MCastFilter, snp->db, snp->cdb.DBsize);
261
262 //
263 // Count number of active entries in multicast filter list.
264 //
265 {
266 EFI_MAC_ADDRESS ZeroMacAddr;
267
268 SetMem (&ZeroMacAddr, sizeof ZeroMacAddr, 0);
269
270 for (snp->mode.MCastFilterCount = 0;
271 snp->mode.MCastFilterCount < snp->mode.MaxMCastFilterCount;
272 snp->mode.MCastFilterCount++
273 ) {
274 if (CompareMem (
275 &snp->mode.MCastFilter[snp->mode.MCastFilterCount],
276 &ZeroMacAddr,
277 sizeof ZeroMacAddr
278 ) == 0) {
279 break;
280 }
281 }
282 }
283
284 return EFI_SUCCESS;
285 }
286
287
288 /**
289 This is the SNP interface routine for reading/enabling/disabling the
290 receive filters.
291 This routine basically retrieves snp structure, checks the SNP state and
292 checks the parameter validity, calls one of the above routines to actually
293 do the work
294
295 @param this context pointer
296 @param EnableFlags bit mask for enabling the receive filters
297 @param DisableFlags bit mask for disabling the receive filters
298 @param ResetMCastList boolean flag to reset/delete the multicast filter list
299 @param MCastAddressCount multicast address count for a new multicast address
300 list
301 @param MCastAddressList list of new multicast addresses
302
303
304 **/
305 EFI_STATUS
306 EFIAPI
307 snp_undi32_receive_filters (
308 IN EFI_SIMPLE_NETWORK_PROTOCOL * this,
309 IN UINT32 EnableFlags,
310 IN UINT32 DisableFlags,
311 IN BOOLEAN ResetMCastList,
312 IN UINTN MCastAddressCount OPTIONAL,
313 IN EFI_MAC_ADDRESS * MCastAddressList OPTIONAL
314 )
315 {
316 SNP_DRIVER *snp;
317 EFI_STATUS Status;
318 EFI_TPL OldTpl;
319
320 if (this == NULL) {
321 return EFI_INVALID_PARAMETER;
322 }
323
324 snp = EFI_SIMPLE_NETWORK_DEV_FROM_THIS (this);
325
326 OldTpl = gBS->RaiseTPL (TPL_CALLBACK);
327
328 switch (snp->mode.State) {
329 case EfiSimpleNetworkInitialized:
330 break;
331
332 case EfiSimpleNetworkStopped:
333 Status = EFI_NOT_STARTED;
334 goto ON_EXIT;
335
336 default:
337 Status = EFI_DEVICE_ERROR;
338 goto ON_EXIT;
339 }
340 //
341 // check if we are asked to enable or disable something that the UNDI
342 // does not even support!
343 //
344 if (((EnableFlags &~snp->mode.ReceiveFilterMask) != 0) ||
345 ((DisableFlags &~snp->mode.ReceiveFilterMask) != 0)) {
346 Status = EFI_INVALID_PARAMETER;
347 goto ON_EXIT;
348 }
349
350 if (ResetMCastList) {
351
352 DisableFlags |= EFI_SIMPLE_NETWORK_RECEIVE_MULTICAST & snp->mode.ReceiveFilterMask;
353 MCastAddressCount = 0;
354 MCastAddressList = NULL;
355 } else {
356 if (MCastAddressCount != 0) {
357 if ((MCastAddressCount > snp->mode.MaxMCastFilterCount) ||
358 (MCastAddressList == NULL)) {
359
360 Status = EFI_INVALID_PARAMETER;
361 goto ON_EXIT;
362 }
363 }
364 }
365
366 if (EnableFlags == 0 && DisableFlags == 0 && !ResetMCastList && MCastAddressCount == 0) {
367 Status = EFI_SUCCESS;
368 goto ON_EXIT;
369 }
370
371 if ((EnableFlags & EFI_SIMPLE_NETWORK_RECEIVE_MULTICAST) != 0 && MCastAddressCount == 0) {
372 Status = EFI_INVALID_PARAMETER;
373 goto ON_EXIT;
374 }
375
376 if ((EnableFlags != 0) || (MCastAddressCount != 0)) {
377 Status = pxe_rcvfilter_enable (
378 snp,
379 EnableFlags,
380 MCastAddressCount,
381 MCastAddressList
382 );
383
384 if (EFI_ERROR (Status)) {
385 goto ON_EXIT;
386 }
387 }
388
389 if ((DisableFlags != 0) || ResetMCastList) {
390 Status = pxe_rcvfilter_disable (snp, DisableFlags, ResetMCastList);
391
392 if (EFI_ERROR (Status)) {
393 goto ON_EXIT;
394 }
395 }
396
397 Status = pxe_rcvfilter_read (snp);
398
399 ON_EXIT:
400 gBS->RestoreTPL (OldTpl);
401
402 return Status;
403 }