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
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.
17 2000-Feb-17 M(f)J Genesis.
26 this routine calls undi to enable the receive filters.
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
32 @param MCastAddressList list of new multicast addresses
37 pxe_rcvfilter_enable (
40 UINTN MCastAddressCount
,
41 EFI_MAC_ADDRESS
*MCastAddressList
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
;
55 if ((EnableFlags
& EFI_SIMPLE_NETWORK_RECEIVE_UNICAST
) != 0) {
56 snp
->cdb
.OpFlags
|= PXE_OPFLAGS_RECEIVE_FILTER_UNICAST
;
59 if ((EnableFlags
& EFI_SIMPLE_NETWORK_RECEIVE_BROADCAST
) != 0) {
60 snp
->cdb
.OpFlags
|= PXE_OPFLAGS_RECEIVE_FILTER_BROADCAST
;
63 if ((EnableFlags
& EFI_SIMPLE_NETWORK_RECEIVE_PROMISCUOUS
) != 0) {
64 snp
->cdb
.OpFlags
|= PXE_OPFLAGS_RECEIVE_FILTER_PROMISCUOUS
;
67 if ((EnableFlags
& EFI_SIMPLE_NETWORK_RECEIVE_PROMISCUOUS_MULTICAST
) != 0) {
68 snp
->cdb
.OpFlags
|= PXE_OPFLAGS_RECEIVE_FILTER_ALL_MULTICAST
;
71 if ((EnableFlags
& EFI_SIMPLE_NETWORK_RECEIVE_MULTICAST
) != 0) {
72 snp
->cdb
.OpFlags
|= PXE_OPFLAGS_RECEIVE_FILTER_FILTERED_MULTICAST
;
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
);
81 // Issue UNDI command and check result.
83 DEBUG ((EFI_D_NET
, "\nsnp->undi.receive_filters() "));
85 (*snp
->issue_undi32_command
) ((UINT64
)(UINTN
) &snp
->cdb
);
87 if (snp
->cdb
.StatCode
!= EFI_SUCCESS
) {
89 // UNDI command failed. Return UNDI status to caller.
93 "\nsnp->undi.receive_filters() %xh:%xh\n",
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
;
104 case PXE_STATCODE_UNSUPPORTED
:
105 return EFI_UNSUPPORTED
;
108 return EFI_DEVICE_ERROR
;
115 this routine calls undi to disable the receive filters.
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
124 pxe_rcvfilter_disable (
127 BOOLEAN ResetMCastList
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
;
140 snp
->cdb
.OpFlags
= (UINT16
) (DisableFlags
? PXE_OPFLAGS_RECEIVE_FILTER_DISABLE
: PXE_OPFLAGS_NOT_USED
);
142 if (ResetMCastList
) {
143 snp
->cdb
.OpFlags
|= PXE_OPFLAGS_RECEIVE_FILTER_RESET_MCAST_LIST
;
146 if ((DisableFlags
& EFI_SIMPLE_NETWORK_RECEIVE_UNICAST
) != 0) {
147 snp
->cdb
.OpFlags
|= PXE_OPFLAGS_RECEIVE_FILTER_UNICAST
;
150 if ((DisableFlags
& EFI_SIMPLE_NETWORK_RECEIVE_BROADCAST
) != 0) {
151 snp
->cdb
.OpFlags
|= PXE_OPFLAGS_RECEIVE_FILTER_BROADCAST
;
154 if ((DisableFlags
& EFI_SIMPLE_NETWORK_RECEIVE_PROMISCUOUS
) != 0) {
155 snp
->cdb
.OpFlags
|= PXE_OPFLAGS_RECEIVE_FILTER_PROMISCUOUS
;
158 if ((DisableFlags
& EFI_SIMPLE_NETWORK_RECEIVE_PROMISCUOUS_MULTICAST
) != 0) {
159 snp
->cdb
.OpFlags
|= PXE_OPFLAGS_RECEIVE_FILTER_ALL_MULTICAST
;
162 if ((DisableFlags
& EFI_SIMPLE_NETWORK_RECEIVE_MULTICAST
) != 0) {
163 snp
->cdb
.OpFlags
|= PXE_OPFLAGS_RECEIVE_FILTER_FILTERED_MULTICAST
;
166 // Issue UNDI command and check result.
168 DEBUG ((EFI_D_NET
, "\nsnp->undi.receive_filters() "));
170 (*snp
->issue_undi32_command
) ((UINT64
)(UINTN
) &snp
->cdb
);
172 if (snp
->cdb
.StatCode
!= EFI_SUCCESS
) {
174 // UNDI command failed. Return UNDI status to caller.
178 "\nsnp->undi.receive_filters() %xh:%xh\n",
183 return EFI_DEVICE_ERROR
;
190 this routine calls undi to read the receive filters.
192 @param snp pointer to snp driver structure
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
;
209 snp
->cdb
.DBaddr
= (UINT64
)(UINTN
) snp
->db
;
210 ZeroMem (snp
->db
, snp
->cdb
.DBsize
);
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
;
218 DEBUG ((EFI_D_NET
, "\nsnp->undi.receive_filters() "));
220 (*snp
->issue_undi32_command
) ((UINT64
)(UINTN
) &snp
->cdb
);
222 if (snp
->cdb
.StatCode
!= EFI_SUCCESS
) {
224 // UNDI command failed. Return UNDI status to caller.
228 "\nsnp->undi.receive_filters() %xh:%xh\n",
233 return EFI_DEVICE_ERROR
;
236 // Convert UNDI32 StatFlags to EFI SNP filter flags.
238 snp
->mode
.ReceiveFilterSetting
= 0;
240 if ((snp
->cdb
.StatFlags
& PXE_STATFLAGS_RECEIVE_FILTER_UNICAST
) != 0) {
241 snp
->mode
.ReceiveFilterSetting
|= EFI_SIMPLE_NETWORK_RECEIVE_UNICAST
;
244 if ((snp
->cdb
.StatFlags
& PXE_STATFLAGS_RECEIVE_FILTER_BROADCAST
) != 0) {
245 snp
->mode
.ReceiveFilterSetting
|= EFI_SIMPLE_NETWORK_RECEIVE_BROADCAST
;
248 if ((snp
->cdb
.StatFlags
& PXE_STATFLAGS_RECEIVE_FILTER_PROMISCUOUS
) != 0) {
249 snp
->mode
.ReceiveFilterSetting
|= EFI_SIMPLE_NETWORK_RECEIVE_PROMISCUOUS
;
252 if ((snp
->cdb
.StatFlags
& PXE_STATFLAGS_RECEIVE_FILTER_ALL_MULTICAST
) != 0) {
253 snp
->mode
.ReceiveFilterSetting
|= EFI_SIMPLE_NETWORK_RECEIVE_PROMISCUOUS_MULTICAST
;
256 if ((snp
->cdb
.StatFlags
& PXE_STATFLAGS_RECEIVE_FILTER_FILTERED_MULTICAST
) != 0) {
257 snp
->mode
.ReceiveFilterSetting
|= EFI_SIMPLE_NETWORK_RECEIVE_MULTICAST
;
260 CopyMem (snp
->mode
.MCastFilter
, snp
->db
, snp
->cdb
.DBsize
);
263 // Count number of active entries in multicast filter list.
266 EFI_MAC_ADDRESS ZeroMacAddr
;
268 SetMem (&ZeroMacAddr
, sizeof ZeroMacAddr
, 0);
270 for (snp
->mode
.MCastFilterCount
= 0;
271 snp
->mode
.MCastFilterCount
< snp
->mode
.MaxMCastFilterCount
;
272 snp
->mode
.MCastFilterCount
++
275 &snp
->mode
.MCastFilter
[snp
->mode
.MCastFilterCount
],
289 This is the SNP interface routine for reading/enabling/disabling the
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
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
301 @param MCastAddressList list of new multicast addresses
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
321 return EFI_INVALID_PARAMETER
;
324 snp
= EFI_SIMPLE_NETWORK_DEV_FROM_THIS (this);
326 OldTpl
= gBS
->RaiseTPL (TPL_CALLBACK
);
328 switch (snp
->mode
.State
) {
329 case EfiSimpleNetworkInitialized
:
332 case EfiSimpleNetworkStopped
:
333 Status
= EFI_NOT_STARTED
;
337 Status
= EFI_DEVICE_ERROR
;
341 // check if we are asked to enable or disable something that the UNDI
342 // does not even support!
344 if (((EnableFlags
&~snp
->mode
.ReceiveFilterMask
) != 0) ||
345 ((DisableFlags
&~snp
->mode
.ReceiveFilterMask
) != 0)) {
346 Status
= EFI_INVALID_PARAMETER
;
350 if (ResetMCastList
) {
352 DisableFlags
|= EFI_SIMPLE_NETWORK_RECEIVE_MULTICAST
& snp
->mode
.ReceiveFilterMask
;
353 MCastAddressCount
= 0;
354 MCastAddressList
= NULL
;
356 if (MCastAddressCount
!= 0) {
357 if ((MCastAddressCount
> snp
->mode
.MaxMCastFilterCount
) ||
358 (MCastAddressList
== NULL
)) {
360 Status
= EFI_INVALID_PARAMETER
;
366 if (EnableFlags
== 0 && DisableFlags
== 0 && !ResetMCastList
&& MCastAddressCount
== 0) {
367 Status
= EFI_SUCCESS
;
371 if ((EnableFlags
& EFI_SIMPLE_NETWORK_RECEIVE_MULTICAST
) != 0 && MCastAddressCount
== 0) {
372 Status
= EFI_INVALID_PARAMETER
;
376 if ((EnableFlags
!= 0) || (MCastAddressCount
!= 0)) {
377 Status
= pxe_rcvfilter_enable (
384 if (EFI_ERROR (Status
)) {
389 if ((DisableFlags
!= 0) || ResetMCastList
) {
390 Status
= pxe_rcvfilter_disable (snp
, DisableFlags
, ResetMCastList
);
392 if (EFI_ERROR (Status
)) {
397 Status
= pxe_rcvfilter_read (snp
);
400 gBS
->RestoreTPL (OldTpl
);