2 Implementation of reading the MAC address of a network adapter.
4 Copyright (c) 2004 - 2018, Intel Corporation. All rights reserved.<BR>
5 SPDX-License-Identifier: BSD-2-Clause-Patent
13 Call UNDI to read the MAC address of the NIC and update the mode structure
16 @param Snp Pointer to snp driver structure.
18 @retval EFI_SUCCESS The MAC address of the NIC is read successfully.
19 @retval EFI_DEVICE_ERROR Failed to read the MAC address of the NIC.
27 PXE_DB_STATION_ADDRESS
*Db
;
30 Snp
->Cdb
.OpCode
= PXE_OPCODE_STATION_ADDRESS
;
31 Snp
->Cdb
.OpFlags
= PXE_OPFLAGS_STATION_ADDRESS_READ
;
33 Snp
->Cdb
.CPBaddr
= PXE_CPBADDR_NOT_USED
;
34 Snp
->Cdb
.CPBsize
= PXE_CPBSIZE_NOT_USED
;
36 Snp
->Cdb
.DBsize
= (UINT16
) sizeof (PXE_DB_STATION_ADDRESS
);
37 Snp
->Cdb
.DBaddr
= (UINT64
)(UINTN
) Db
;
39 Snp
->Cdb
.StatCode
= PXE_STATCODE_INITIALIZE
;
40 Snp
->Cdb
.StatFlags
= PXE_STATFLAGS_INITIALIZE
;
41 Snp
->Cdb
.IFnum
= Snp
->IfNum
;
42 Snp
->Cdb
.Control
= PXE_CONTROL_LAST_CDB_IN_LIST
;
45 // Issue UNDI command and check result.
47 DEBUG ((EFI_D_NET
, "\nsnp->undi.station_addr() "));
49 (*Snp
->IssueUndi32Command
) ((UINT64
)(UINTN
) &Snp
->Cdb
);
51 if (Snp
->Cdb
.StatCode
!= PXE_STATCODE_SUCCESS
) {
54 "\nsnp->undi.station_addr() %xh:%xh\n",
59 return EFI_DEVICE_ERROR
;
62 // Set new station address in SNP->Mode structure and return success.
65 &(Snp
->Mode
.CurrentAddress
),
67 Snp
->Mode
.HwAddressSize
71 &Snp
->Mode
.BroadcastAddress
,
73 Snp
->Mode
.HwAddressSize
77 &Snp
->Mode
.PermanentAddress
,
79 Snp
->Mode
.HwAddressSize
87 Call UNDI to set a new MAC address for the NIC.
89 @param Snp Pointer to Snp driver structure.
90 @param NewMacAddr Pointer to a MAC address to be set for the NIC, if this is
91 NULL then this routine resets the mac address to the NIC's
99 EFI_MAC_ADDRESS
*NewMacAddr
102 PXE_CPB_STATION_ADDRESS
*Cpb
;
103 PXE_DB_STATION_ADDRESS
*Db
;
107 Snp
->Cdb
.OpCode
= PXE_OPCODE_STATION_ADDRESS
;
109 if (NewMacAddr
== NULL
) {
110 Snp
->Cdb
.OpFlags
= PXE_OPFLAGS_STATION_ADDRESS_RESET
;
111 Snp
->Cdb
.CPBsize
= PXE_CPBSIZE_NOT_USED
;
112 Snp
->Cdb
.CPBaddr
= PXE_CPBADDR_NOT_USED
;
114 Snp
->Cdb
.OpFlags
= PXE_OPFLAGS_STATION_ADDRESS_WRITE
;
116 // Supplying a new address in the CPB will make undi change the mac address to the new one.
118 CopyMem (&Cpb
->StationAddr
, NewMacAddr
, Snp
->Mode
.HwAddressSize
);
120 Snp
->Cdb
.CPBsize
= (UINT16
) sizeof (PXE_CPB_STATION_ADDRESS
);
121 Snp
->Cdb
.CPBaddr
= (UINT64
)(UINTN
) Cpb
;
124 Snp
->Cdb
.DBsize
= (UINT16
) sizeof (PXE_DB_STATION_ADDRESS
);
125 Snp
->Cdb
.DBaddr
= (UINT64
)(UINTN
) Db
;
127 Snp
->Cdb
.StatCode
= PXE_STATCODE_INITIALIZE
;
128 Snp
->Cdb
.StatFlags
= PXE_STATFLAGS_INITIALIZE
;
129 Snp
->Cdb
.IFnum
= Snp
->IfNum
;
130 Snp
->Cdb
.Control
= PXE_CONTROL_LAST_CDB_IN_LIST
;
133 // Issue UNDI command and check result.
135 DEBUG ((EFI_D_NET
, "\nsnp->undi.station_addr() "));
137 (*Snp
->IssueUndi32Command
) ((UINT64
)(UINTN
) &Snp
->Cdb
);
139 if (Snp
->Cdb
.StatCode
!= PXE_STATCODE_SUCCESS
) {
142 "\nsnp->undi.station_addr() %xh:%xh\n",
148 // UNDI command failed. Return UNDI status to caller.
150 return EFI_DEVICE_ERROR
;
153 // read the changed address and save it in SNP->Mode structure
162 Modifies or resets the current station address, if supported.
164 This function modifies or resets the current station address of a network
165 interface, if supported. If Reset is TRUE, then the current station address is
166 set to the network interface's permanent address. If Reset is FALSE, and the
167 network interface allows its station address to be modified, then the current
168 station address is changed to the address specified by New. If the network
169 interface does not allow its station address to be modified, then
170 EFI_INVALID_PARAMETER will be returned. If the station address is successfully
171 updated on the network interface, EFI_SUCCESS will be returned. If the driver
172 has not been initialized, EFI_DEVICE_ERROR will be returned.
174 @param This A pointer to the EFI_SIMPLE_NETWORK_PROTOCOL instance.
175 @param Reset Flag used to reset the station address to the network interface's
177 @param New New station address to be used for the network interface.
180 @retval EFI_SUCCESS The network interface's station address was updated.
181 @retval EFI_NOT_STARTED The Simple Network Protocol interface has not been
182 started by calling Start().
183 @retval EFI_INVALID_PARAMETER The New station address was not accepted by the NIC.
184 @retval EFI_INVALID_PARAMETER Reset is FALSE and New is NULL.
185 @retval EFI_DEVICE_ERROR The Simple Network Protocol interface has not
186 been initialized by calling Initialize().
187 @retval EFI_DEVICE_ERROR An error occurred attempting to set the new
189 @retval EFI_UNSUPPORTED The NIC does not support changing the network
190 interface's station address.
195 SnpUndi32StationAddress (
196 IN EFI_SIMPLE_NETWORK_PROTOCOL
*This
,
198 IN EFI_MAC_ADDRESS
*New OPTIONAL
206 // Check for invalid parameter combinations.
208 if ((This
== NULL
) ||
209 (!Reset
&& (New
== NULL
))) {
210 return EFI_INVALID_PARAMETER
;
213 Snp
= EFI_SIMPLE_NETWORK_DEV_FROM_THIS (This
);
215 OldTpl
= gBS
->RaiseTPL (TPL_CALLBACK
);
218 // Return error if the SNP is not initialized.
220 switch (Snp
->Mode
.State
) {
221 case EfiSimpleNetworkInitialized
:
224 case EfiSimpleNetworkStopped
:
225 Status
= EFI_NOT_STARTED
;
229 Status
= EFI_DEVICE_ERROR
;
234 Status
= PxeSetStnAddr (Snp
, NULL
);
236 Status
= PxeSetStnAddr (Snp
, New
);
240 gBS
->RestoreTPL (OldTpl
);