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