]> git.proxmox.com Git - mirror_edk2.git/blame - MdeModulePkg/Universal/Network/SnpDxe/Station_address.c
MdeModulePkg: Replace BSD License with BSD+Patent License
[mirror_edk2.git] / MdeModulePkg / Universal / Network / SnpDxe / Station_address.c
CommitLineData
2735e5d0 1/** @file\r
4cda7726 2 Implementation of reading the MAC address of a network adapter.\r
d1102dba
LG
3\r
4Copyright (c) 2004 - 2018, Intel Corporation. All rights reserved.<BR>\r
9d510e61 5SPDX-License-Identifier: BSD-2-Clause-Patent\r
2735e5d0 6\r
2735e5d0 7**/\r
8\r
9#include "Snp.h"\r
10\r
11\r
12/**\r
d1102dba
LG
13 Call UNDI to read the MAC address of the NIC and update the mode structure\r
14 with the address.\r
2735e5d0 15\r
f3816027 16 @param Snp Pointer to snp driver structure.\r
d1102dba 17\r
f3816027 18 @retval EFI_SUCCESS The MAC address of the NIC is read successfully.\r
19 @retval EFI_DEVICE_ERROR Failed to read the MAC address of the NIC.\r
2735e5d0 20\r
21**/\r
22EFI_STATUS\r
4cda7726 23PxeGetStnAddr (\r
24 SNP_DRIVER *Snp\r
2735e5d0 25 )\r
26{\r
4cda7726 27 PXE_DB_STATION_ADDRESS *Db;\r
2735e5d0 28\r
4cda7726 29 Db = Snp->Db;\r
30 Snp->Cdb.OpCode = PXE_OPCODE_STATION_ADDRESS;\r
31 Snp->Cdb.OpFlags = PXE_OPFLAGS_STATION_ADDRESS_READ;\r
2735e5d0 32\r
4cda7726 33 Snp->Cdb.CPBaddr = PXE_CPBADDR_NOT_USED;\r
34 Snp->Cdb.CPBsize = PXE_CPBSIZE_NOT_USED;\r
2735e5d0 35\r
c9325700 36 Snp->Cdb.DBsize = (UINT16) sizeof (PXE_DB_STATION_ADDRESS);\r
4cda7726 37 Snp->Cdb.DBaddr = (UINT64)(UINTN) Db;\r
2735e5d0 38\r
4cda7726 39 Snp->Cdb.StatCode = PXE_STATCODE_INITIALIZE;\r
40 Snp->Cdb.StatFlags = PXE_STATFLAGS_INITIALIZE;\r
41 Snp->Cdb.IFnum = Snp->IfNum;\r
42 Snp->Cdb.Control = PXE_CONTROL_LAST_CDB_IN_LIST;\r
2735e5d0 43\r
44 //\r
45 // Issue UNDI command and check result.\r
46 //\r
9cff2f8d 47 DEBUG ((EFI_D_NET, "\nsnp->undi.station_addr() "));\r
2735e5d0 48\r
4cda7726 49 (*Snp->IssueUndi32Command) ((UINT64)(UINTN) &Snp->Cdb);\r
2735e5d0 50\r
4cda7726 51 if (Snp->Cdb.StatCode != PXE_STATCODE_SUCCESS) {\r
2735e5d0 52 DEBUG (\r
53 (EFI_D_ERROR,\r
54 "\nsnp->undi.station_addr() %xh:%xh\n",\r
4cda7726 55 Snp->Cdb.StatFlags,\r
56 Snp->Cdb.StatCode)\r
2735e5d0 57 );\r
58\r
59 return EFI_DEVICE_ERROR;\r
60 }\r
61 //\r
62 // Set new station address in SNP->Mode structure and return success.\r
63 //\r
64 CopyMem (\r
4cda7726 65 &(Snp->Mode.CurrentAddress),\r
66 &Db->StationAddr,\r
67 Snp->Mode.HwAddressSize\r
2735e5d0 68 );\r
69\r
70 CopyMem (\r
4cda7726 71 &Snp->Mode.BroadcastAddress,\r
72 &Db->BroadcastAddr,\r
73 Snp->Mode.HwAddressSize\r
2735e5d0 74 );\r
75\r
76 CopyMem (\r
4cda7726 77 &Snp->Mode.PermanentAddress,\r
78 &Db->PermanentAddr,\r
79 Snp->Mode.HwAddressSize\r
2735e5d0 80 );\r
81\r
82 return EFI_SUCCESS;\r
83}\r
84\r
85\r
86/**\r
f3816027 87 Call UNDI to set a new MAC address for the NIC.\r
2735e5d0 88\r
f3816027 89 @param Snp Pointer to Snp driver structure.\r
90 @param NewMacAddr Pointer to a MAC address to be set for the NIC, if this is\r
2735e5d0 91 NULL then this routine resets the mac address to the NIC's\r
92 original address.\r
93\r
94\r
95**/\r
2735e5d0 96EFI_STATUS\r
4cda7726 97PxeSetStnAddr (\r
98 SNP_DRIVER *Snp,\r
2735e5d0 99 EFI_MAC_ADDRESS *NewMacAddr\r
100 )\r
101{\r
4cda7726 102 PXE_CPB_STATION_ADDRESS *Cpb;\r
103 PXE_DB_STATION_ADDRESS *Db;\r
2735e5d0 104\r
4cda7726 105 Cpb = Snp->Cpb;\r
106 Db = Snp->Db;\r
107 Snp->Cdb.OpCode = PXE_OPCODE_STATION_ADDRESS;\r
2735e5d0 108\r
109 if (NewMacAddr == NULL) {\r
4cda7726 110 Snp->Cdb.OpFlags = PXE_OPFLAGS_STATION_ADDRESS_RESET;\r
111 Snp->Cdb.CPBsize = PXE_CPBSIZE_NOT_USED;\r
112 Snp->Cdb.CPBaddr = PXE_CPBADDR_NOT_USED;\r
2735e5d0 113 } else {\r
80e3a522 114 Snp->Cdb.OpFlags = PXE_OPFLAGS_STATION_ADDRESS_WRITE;\r
2735e5d0 115 //\r
80e3a522 116 // Supplying a new address in the CPB will make undi change the mac address to the new one.\r
2735e5d0 117 //\r
4cda7726 118 CopyMem (&Cpb->StationAddr, NewMacAddr, Snp->Mode.HwAddressSize);\r
2735e5d0 119\r
c9325700 120 Snp->Cdb.CPBsize = (UINT16) sizeof (PXE_CPB_STATION_ADDRESS);\r
4cda7726 121 Snp->Cdb.CPBaddr = (UINT64)(UINTN) Cpb;\r
2735e5d0 122 }\r
123\r
c9325700 124 Snp->Cdb.DBsize = (UINT16) sizeof (PXE_DB_STATION_ADDRESS);\r
4cda7726 125 Snp->Cdb.DBaddr = (UINT64)(UINTN) Db;\r
2735e5d0 126\r
4cda7726 127 Snp->Cdb.StatCode = PXE_STATCODE_INITIALIZE;\r
128 Snp->Cdb.StatFlags = PXE_STATFLAGS_INITIALIZE;\r
129 Snp->Cdb.IFnum = Snp->IfNum;\r
130 Snp->Cdb.Control = PXE_CONTROL_LAST_CDB_IN_LIST;\r
2735e5d0 131\r
132 //\r
133 // Issue UNDI command and check result.\r
134 //\r
9cff2f8d 135 DEBUG ((EFI_D_NET, "\nsnp->undi.station_addr() "));\r
2735e5d0 136\r
4cda7726 137 (*Snp->IssueUndi32Command) ((UINT64)(UINTN) &Snp->Cdb);\r
2735e5d0 138\r
4cda7726 139 if (Snp->Cdb.StatCode != PXE_STATCODE_SUCCESS) {\r
2735e5d0 140 DEBUG (\r
141 (EFI_D_ERROR,\r
142 "\nsnp->undi.station_addr() %xh:%xh\n",\r
4cda7726 143 Snp->Cdb.StatFlags,\r
144 Snp->Cdb.StatCode)\r
2735e5d0 145 );\r
146\r
147 //\r
148 // UNDI command failed. Return UNDI status to caller.\r
149 //\r
150 return EFI_DEVICE_ERROR;\r
151 }\r
152 //\r
153 // read the changed address and save it in SNP->Mode structure\r
154 //\r
4cda7726 155 PxeGetStnAddr (Snp);\r
2735e5d0 156\r
157 return EFI_SUCCESS;\r
158}\r
159\r
160\r
161/**\r
4cda7726 162 Modifies or resets the current station address, if supported.\r
d1102dba
LG
163\r
164 This function modifies or resets the current station address of a network\r
4cda7726 165 interface, if supported. If Reset is TRUE, then the current station address is\r
d1102dba
LG
166 set to the network interface's permanent address. If Reset is FALSE, and the\r
167 network interface allows its station address to be modified, then the current\r
168 station address is changed to the address specified by New. If the network\r
169 interface does not allow its station address to be modified, then\r
4cda7726 170 EFI_INVALID_PARAMETER will be returned. If the station address is successfully\r
171 updated on the network interface, EFI_SUCCESS will be returned. If the driver\r
172 has not been initialized, EFI_DEVICE_ERROR will be returned.\r
173\r
174 @param This A pointer to the EFI_SIMPLE_NETWORK_PROTOCOL instance.\r
d1102dba 175 @param Reset Flag used to reset the station address to the network interface's\r
4cda7726 176 permanent address.\r
177 @param New New station address to be used for the network interface.\r
178\r
179\r
51195fbe 180 @retval EFI_SUCCESS The network interface's station address was updated.\r
d1102dba 181 @retval EFI_NOT_STARTED The Simple Network Protocol interface has not been\r
4cda7726 182 started by calling Start().\r
183 @retval EFI_INVALID_PARAMETER The New station address was not accepted by the NIC.\r
184 @retval EFI_INVALID_PARAMETER Reset is FALSE and New is NULL.\r
d1102dba 185 @retval EFI_DEVICE_ERROR The Simple Network Protocol interface has not\r
4cda7726 186 been initialized by calling Initialize().\r
d1102dba 187 @retval EFI_DEVICE_ERROR An error occurred attempting to set the new\r
4cda7726 188 station address.\r
d1102dba 189 @retval EFI_UNSUPPORTED The NIC does not support changing the network\r
51195fbe 190 interface's station address.\r
2735e5d0 191\r
192**/\r
193EFI_STATUS\r
194EFIAPI\r
4cda7726 195SnpUndi32StationAddress (\r
196 IN EFI_SIMPLE_NETWORK_PROTOCOL *This,\r
197 IN BOOLEAN Reset,\r
198 IN EFI_MAC_ADDRESS *New OPTIONAL\r
2735e5d0 199 )\r
200{\r
4cda7726 201 SNP_DRIVER *Snp;\r
2735e5d0 202 EFI_STATUS Status;\r
203 EFI_TPL OldTpl;\r
204\r
205 //\r
206 // Check for invalid parameter combinations.\r
207 //\r
4cda7726 208 if ((This == NULL) ||\r
209 (!Reset && (New == NULL))) {\r
2735e5d0 210 return EFI_INVALID_PARAMETER;\r
211 }\r
212\r
4cda7726 213 Snp = EFI_SIMPLE_NETWORK_DEV_FROM_THIS (This);\r
2735e5d0 214\r
215 OldTpl = gBS->RaiseTPL (TPL_CALLBACK);\r
216\r
217 //\r
218 // Return error if the SNP is not initialized.\r
219 //\r
4cda7726 220 switch (Snp->Mode.State) {\r
2735e5d0 221 case EfiSimpleNetworkInitialized:\r
222 break;\r
223\r
224 case EfiSimpleNetworkStopped:\r
225 Status = EFI_NOT_STARTED;\r
226 goto ON_EXIT;\r
227\r
228 default:\r
229 Status = EFI_DEVICE_ERROR;\r
230 goto ON_EXIT;\r
231 }\r
232\r
4cda7726 233 if (Reset) {\r
234 Status = PxeSetStnAddr (Snp, NULL);\r
2735e5d0 235 } else {\r
4cda7726 236 Status = PxeSetStnAddr (Snp, New);\r
2735e5d0 237 }\r
238\r
239ON_EXIT:\r
240 gBS->RestoreTPL (OldTpl);\r
241\r
242 return Status;\r
243}\r