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
38 pxe_rcvfilter_enable (
41 UINTN MCastAddressCount
,
42 EFI_MAC_ADDRESS
*MCastAddressList
45 snp
->cdb
.OpCode
= PXE_OPCODE_RECEIVE_FILTERS
;
46 snp
->cdb
.OpFlags
= PXE_OPFLAGS_RECEIVE_FILTER_ENABLE
;
47 snp
->cdb
.CPBsize
= PXE_CPBSIZE_NOT_USED
;
48 snp
->cdb
.DBsize
= PXE_DBSIZE_NOT_USED
;
49 snp
->cdb
.CPBaddr
= PXE_CPBADDR_NOT_USED
;
50 snp
->cdb
.DBaddr
= PXE_DBADDR_NOT_USED
;
51 snp
->cdb
.StatCode
= PXE_STATCODE_INITIALIZE
;
52 snp
->cdb
.StatFlags
= PXE_STATFLAGS_INITIALIZE
;
53 snp
->cdb
.IFnum
= snp
->if_num
;
54 snp
->cdb
.Control
= PXE_CONTROL_LAST_CDB_IN_LIST
;
56 if ((EnableFlags
& EFI_SIMPLE_NETWORK_RECEIVE_UNICAST
) != 0) {
57 snp
->cdb
.OpFlags
|= PXE_OPFLAGS_RECEIVE_FILTER_UNICAST
;
60 if ((EnableFlags
& EFI_SIMPLE_NETWORK_RECEIVE_BROADCAST
) != 0) {
61 snp
->cdb
.OpFlags
|= PXE_OPFLAGS_RECEIVE_FILTER_BROADCAST
;
64 if ((EnableFlags
& EFI_SIMPLE_NETWORK_RECEIVE_PROMISCUOUS
) != 0) {
65 snp
->cdb
.OpFlags
|= PXE_OPFLAGS_RECEIVE_FILTER_PROMISCUOUS
;
68 if ((EnableFlags
& EFI_SIMPLE_NETWORK_RECEIVE_PROMISCUOUS_MULTICAST
) != 0) {
69 snp
->cdb
.OpFlags
|= PXE_OPFLAGS_RECEIVE_FILTER_ALL_MULTICAST
;
72 if ((EnableFlags
& EFI_SIMPLE_NETWORK_RECEIVE_MULTICAST
) != 0) {
73 snp
->cdb
.OpFlags
|= PXE_OPFLAGS_RECEIVE_FILTER_FILTERED_MULTICAST
;
76 if (MCastAddressCount
!= 0) {
77 snp
->cdb
.CPBsize
= (UINT16
) (MCastAddressCount
* sizeof (EFI_MAC_ADDRESS
));
78 snp
->cdb
.CPBaddr
= (UINT64
)(UINTN
) snp
->cpb
;
79 CopyMem (snp
->cpb
, MCastAddressList
, snp
->cdb
.CPBsize
);
82 // Issue UNDI command and check result.
84 DEBUG ((EFI_D_NET
, "\nsnp->undi.receive_filters() "));
86 (*snp
->issue_undi32_command
) ((UINT64
)(UINTN
) &snp
->cdb
);
88 if (snp
->cdb
.StatCode
!= EFI_SUCCESS
) {
90 // UNDI command failed. Return UNDI status to caller.
94 "\nsnp->undi.receive_filters() %xh:%xh\n",
99 switch (snp
->cdb
.StatCode
) {
100 case PXE_STATCODE_INVALID_CDB
:
101 case PXE_STATCODE_INVALID_CPB
:
102 case PXE_STATCODE_INVALID_PARAMETER
:
103 return EFI_INVALID_PARAMETER
;
105 case PXE_STATCODE_UNSUPPORTED
:
106 return EFI_UNSUPPORTED
;
109 return EFI_DEVICE_ERROR
;
116 this routine calls undi to disable the receive filters.
118 @param snp pointer to snp driver structure
119 @param DisableFlags bit mask for disabling the receive filters
120 @param ResetMCastList boolean flag to reset/delete the multicast filter list
126 pxe_rcvfilter_disable (
129 BOOLEAN ResetMCastList
132 snp
->cdb
.OpCode
= PXE_OPCODE_RECEIVE_FILTERS
;
133 snp
->cdb
.CPBsize
= PXE_CPBSIZE_NOT_USED
;
134 snp
->cdb
.DBsize
= PXE_DBSIZE_NOT_USED
;
135 snp
->cdb
.CPBaddr
= PXE_CPBADDR_NOT_USED
;
136 snp
->cdb
.DBaddr
= PXE_DBADDR_NOT_USED
;
137 snp
->cdb
.StatCode
= PXE_STATCODE_INITIALIZE
;
138 snp
->cdb
.StatFlags
= PXE_STATFLAGS_INITIALIZE
;
139 snp
->cdb
.IFnum
= snp
->if_num
;
140 snp
->cdb
.Control
= PXE_CONTROL_LAST_CDB_IN_LIST
;
142 snp
->cdb
.OpFlags
= (UINT16
) (DisableFlags
? PXE_OPFLAGS_RECEIVE_FILTER_DISABLE
: PXE_OPFLAGS_NOT_USED
);
144 if (ResetMCastList
) {
145 snp
->cdb
.OpFlags
|= PXE_OPFLAGS_RECEIVE_FILTER_RESET_MCAST_LIST
;
148 if ((DisableFlags
& EFI_SIMPLE_NETWORK_RECEIVE_UNICAST
) != 0) {
149 snp
->cdb
.OpFlags
|= PXE_OPFLAGS_RECEIVE_FILTER_UNICAST
;
152 if ((DisableFlags
& EFI_SIMPLE_NETWORK_RECEIVE_BROADCAST
) != 0) {
153 snp
->cdb
.OpFlags
|= PXE_OPFLAGS_RECEIVE_FILTER_BROADCAST
;
156 if ((DisableFlags
& EFI_SIMPLE_NETWORK_RECEIVE_PROMISCUOUS
) != 0) {
157 snp
->cdb
.OpFlags
|= PXE_OPFLAGS_RECEIVE_FILTER_PROMISCUOUS
;
160 if ((DisableFlags
& EFI_SIMPLE_NETWORK_RECEIVE_PROMISCUOUS_MULTICAST
) != 0) {
161 snp
->cdb
.OpFlags
|= PXE_OPFLAGS_RECEIVE_FILTER_ALL_MULTICAST
;
164 if ((DisableFlags
& EFI_SIMPLE_NETWORK_RECEIVE_MULTICAST
) != 0) {
165 snp
->cdb
.OpFlags
|= PXE_OPFLAGS_RECEIVE_FILTER_FILTERED_MULTICAST
;
168 // Issue UNDI command and check result.
170 DEBUG ((EFI_D_NET
, "\nsnp->undi.receive_filters() "));
172 (*snp
->issue_undi32_command
) ((UINT64
)(UINTN
) &snp
->cdb
);
174 if (snp
->cdb
.StatCode
!= EFI_SUCCESS
) {
176 // UNDI command failed. Return UNDI status to caller.
180 "\nsnp->undi.receive_filters() %xh:%xh\n",
185 return EFI_DEVICE_ERROR
;
192 this routine calls undi to read the receive filters.
194 @param snp pointer to snp driver structure
204 snp
->cdb
.OpCode
= PXE_OPCODE_RECEIVE_FILTERS
;
205 snp
->cdb
.OpFlags
= PXE_OPFLAGS_RECEIVE_FILTER_READ
;
206 snp
->cdb
.CPBsize
= PXE_CPBSIZE_NOT_USED
;
207 snp
->cdb
.DBsize
= (UINT16
) (snp
->mode
.MaxMCastFilterCount
* sizeof (EFI_MAC_ADDRESS
));
208 snp
->cdb
.CPBaddr
= PXE_CPBADDR_NOT_USED
;
209 if (snp
->cdb
.DBsize
== 0) {
210 snp
->cdb
.DBaddr
= (UINT64
)(UINTN
) NULL
;
212 snp
->cdb
.DBaddr
= (UINT64
)(UINTN
) snp
->db
;
213 ZeroMem (snp
->db
, snp
->cdb
.DBsize
);
216 snp
->cdb
.StatCode
= PXE_STATCODE_INITIALIZE
;
217 snp
->cdb
.StatFlags
= PXE_STATFLAGS_INITIALIZE
;
218 snp
->cdb
.IFnum
= snp
->if_num
;
219 snp
->cdb
.Control
= PXE_CONTROL_LAST_CDB_IN_LIST
;
221 DEBUG ((EFI_D_NET
, "\nsnp->undi.receive_filters() "));
223 (*snp
->issue_undi32_command
) ((UINT64
)(UINTN
) &snp
->cdb
);
225 if (snp
->cdb
.StatCode
!= EFI_SUCCESS
) {
227 // UNDI command failed. Return UNDI status to caller.
231 "\nsnp->undi.receive_filters() %xh:%xh\n",
236 return EFI_DEVICE_ERROR
;
239 // Convert UNDI32 StatFlags to EFI SNP filter flags.
241 snp
->mode
.ReceiveFilterSetting
= 0;
243 if ((snp
->cdb
.StatFlags
& PXE_STATFLAGS_RECEIVE_FILTER_UNICAST
) != 0) {
244 snp
->mode
.ReceiveFilterSetting
|= EFI_SIMPLE_NETWORK_RECEIVE_UNICAST
;
247 if ((snp
->cdb
.StatFlags
& PXE_STATFLAGS_RECEIVE_FILTER_BROADCAST
) != 0) {
248 snp
->mode
.ReceiveFilterSetting
|= EFI_SIMPLE_NETWORK_RECEIVE_BROADCAST
;
251 if ((snp
->cdb
.StatFlags
& PXE_STATFLAGS_RECEIVE_FILTER_PROMISCUOUS
) != 0) {
252 snp
->mode
.ReceiveFilterSetting
|= EFI_SIMPLE_NETWORK_RECEIVE_PROMISCUOUS
;
255 if ((snp
->cdb
.StatFlags
& PXE_STATFLAGS_RECEIVE_FILTER_ALL_MULTICAST
) != 0) {
256 snp
->mode
.ReceiveFilterSetting
|= EFI_SIMPLE_NETWORK_RECEIVE_PROMISCUOUS_MULTICAST
;
259 if ((snp
->cdb
.StatFlags
& PXE_STATFLAGS_RECEIVE_FILTER_FILTERED_MULTICAST
) != 0) {
260 snp
->mode
.ReceiveFilterSetting
|= EFI_SIMPLE_NETWORK_RECEIVE_MULTICAST
;
263 CopyMem (snp
->mode
.MCastFilter
, snp
->db
, snp
->cdb
.DBsize
);
266 // Count number of active entries in multicast filter list.
269 EFI_MAC_ADDRESS ZeroMacAddr
;
271 SetMem (&ZeroMacAddr
, sizeof ZeroMacAddr
, 0);
273 for (snp
->mode
.MCastFilterCount
= 0;
274 snp
->mode
.MCastFilterCount
< snp
->mode
.MaxMCastFilterCount
;
275 snp
->mode
.MCastFilterCount
++
278 &snp
->mode
.MCastFilter
[snp
->mode
.MCastFilterCount
],
292 This is the SNP interface routine for reading/enabling/disabling the
294 This routine basically retrieves snp structure, checks the SNP state and
295 checks the parameter validity, calls one of the above routines to actually
298 @param this context pointer
299 @param EnableFlags bit mask for enabling the receive filters
300 @param DisableFlags bit mask for disabling the receive filters
301 @param ResetMCastList boolean flag to reset/delete the multicast filter list
302 @param MCastAddressCount multicast address count for a new multicast address
304 @param MCastAddressList list of new multicast addresses
310 snp_undi32_receive_filters (
311 IN EFI_SIMPLE_NETWORK_PROTOCOL
* this,
312 IN UINT32 EnableFlags
,
313 IN UINT32 DisableFlags
,
314 IN BOOLEAN ResetMCastList
,
315 IN UINTN MCastAddressCount OPTIONAL
,
316 IN EFI_MAC_ADDRESS
* MCastAddressList OPTIONAL
324 return EFI_INVALID_PARAMETER
;
327 snp
= EFI_SIMPLE_NETWORK_DEV_FROM_THIS (this);
329 OldTpl
= gBS
->RaiseTPL (TPL_CALLBACK
);
331 switch (snp
->mode
.State
) {
332 case EfiSimpleNetworkInitialized
:
335 case EfiSimpleNetworkStopped
:
336 Status
= EFI_NOT_STARTED
;
340 Status
= EFI_DEVICE_ERROR
;
344 // check if we are asked to enable or disable something that the UNDI
345 // does not even support!
347 if (((EnableFlags
&~snp
->mode
.ReceiveFilterMask
) != 0) ||
348 ((DisableFlags
&~snp
->mode
.ReceiveFilterMask
) != 0)) {
349 Status
= EFI_INVALID_PARAMETER
;
353 if (ResetMCastList
) {
355 DisableFlags
|= EFI_SIMPLE_NETWORK_RECEIVE_MULTICAST
& snp
->mode
.ReceiveFilterMask
;
356 MCastAddressCount
= 0;
357 MCastAddressList
= NULL
;
359 if (MCastAddressCount
!= 0) {
360 if ((MCastAddressCount
> snp
->mode
.MaxMCastFilterCount
) ||
361 (MCastAddressList
== NULL
)) {
363 Status
= EFI_INVALID_PARAMETER
;
369 if (EnableFlags
== 0 && DisableFlags
== 0 && !ResetMCastList
&& MCastAddressCount
== 0) {
370 Status
= EFI_SUCCESS
;
374 if ((EnableFlags
& EFI_SIMPLE_NETWORK_RECEIVE_MULTICAST
) != 0 && MCastAddressCount
== 0) {
375 Status
= EFI_INVALID_PARAMETER
;
379 if ((EnableFlags
!= 0) || (MCastAddressCount
!= 0)) {
380 Status
= pxe_rcvfilter_enable (
387 if (EFI_ERROR (Status
)) {
392 if ((DisableFlags
!= 0) || ResetMCastList
) {
393 Status
= pxe_rcvfilter_disable (snp
, DisableFlags
, ResetMCastList
);
395 if (EFI_ERROR (Status
)) {
400 Status
= pxe_rcvfilter_read (snp
);
403 gBS
->RestoreTPL (OldTpl
);