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