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