BaseTools:Change the path of the file that Binary Cache
[mirror_edk2.git] / MdeModulePkg / Universal / Network / SnpDxe / Station_address.c
1 /** @file\r
2     Implementation of reading the MAC address of a network adapter.\r
3 \r
4 Copyright (c) 2004 - 2018, Intel Corporation. All rights reserved.<BR>\r
5 SPDX-License-Identifier: BSD-2-Clause-Patent\r
6 \r
7 **/\r
8 \r
9 #include "Snp.h"\r
10 \r
11 \r
12 /**\r
13   Call UNDI to read the MAC address of the NIC and update the mode structure\r
14   with the address.\r
15 \r
16   @param  Snp         Pointer to snp driver structure.\r
17 \r
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
20 \r
21 **/\r
22 EFI_STATUS\r
23 PxeGetStnAddr (\r
24   SNP_DRIVER *Snp\r
25   )\r
26 {\r
27   PXE_DB_STATION_ADDRESS  *Db;\r
28 \r
29   Db                  = Snp->Db;\r
30   Snp->Cdb.OpCode     = PXE_OPCODE_STATION_ADDRESS;\r
31   Snp->Cdb.OpFlags    = PXE_OPFLAGS_STATION_ADDRESS_READ;\r
32 \r
33   Snp->Cdb.CPBaddr    = PXE_CPBADDR_NOT_USED;\r
34   Snp->Cdb.CPBsize    = PXE_CPBSIZE_NOT_USED;\r
35 \r
36   Snp->Cdb.DBsize     = (UINT16) sizeof (PXE_DB_STATION_ADDRESS);\r
37   Snp->Cdb.DBaddr     = (UINT64)(UINTN) Db;\r
38 \r
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
43 \r
44   //\r
45   // Issue UNDI command and check result.\r
46   //\r
47   DEBUG ((EFI_D_NET, "\nsnp->undi.station_addr()  "));\r
48 \r
49   (*Snp->IssueUndi32Command) ((UINT64)(UINTN) &Snp->Cdb);\r
50 \r
51   if (Snp->Cdb.StatCode != PXE_STATCODE_SUCCESS) {\r
52     DEBUG (\r
53       (EFI_D_ERROR,\r
54       "\nsnp->undi.station_addr()  %xh:%xh\n",\r
55       Snp->Cdb.StatFlags,\r
56       Snp->Cdb.StatCode)\r
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
65     &(Snp->Mode.CurrentAddress),\r
66     &Db->StationAddr,\r
67     Snp->Mode.HwAddressSize\r
68     );\r
69 \r
70   CopyMem (\r
71     &Snp->Mode.BroadcastAddress,\r
72     &Db->BroadcastAddr,\r
73     Snp->Mode.HwAddressSize\r
74     );\r
75 \r
76   CopyMem (\r
77     &Snp->Mode.PermanentAddress,\r
78     &Db->PermanentAddr,\r
79     Snp->Mode.HwAddressSize\r
80     );\r
81 \r
82   return EFI_SUCCESS;\r
83 }\r
84 \r
85 \r
86 /**\r
87   Call UNDI to set a new MAC address for the NIC.\r
88 \r
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
91                       NULL then this routine resets the mac address to the NIC's\r
92                       original address.\r
93 \r
94 \r
95 **/\r
96 EFI_STATUS\r
97 PxeSetStnAddr (\r
98   SNP_DRIVER      *Snp,\r
99   EFI_MAC_ADDRESS *NewMacAddr\r
100   )\r
101 {\r
102   PXE_CPB_STATION_ADDRESS *Cpb;\r
103   PXE_DB_STATION_ADDRESS  *Db;\r
104 \r
105   Cpb             = Snp->Cpb;\r
106   Db              = Snp->Db;\r
107   Snp->Cdb.OpCode = PXE_OPCODE_STATION_ADDRESS;\r
108 \r
109   if (NewMacAddr == NULL) {\r
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
113   } else {\r
114     Snp->Cdb.OpFlags = PXE_OPFLAGS_STATION_ADDRESS_WRITE;\r
115     //\r
116     // Supplying a new address in the CPB will make undi change the mac address to the new one.\r
117     //\r
118     CopyMem (&Cpb->StationAddr, NewMacAddr, Snp->Mode.HwAddressSize);\r
119 \r
120     Snp->Cdb.CPBsize  = (UINT16) sizeof (PXE_CPB_STATION_ADDRESS);\r
121     Snp->Cdb.CPBaddr  = (UINT64)(UINTN) Cpb;\r
122   }\r
123 \r
124   Snp->Cdb.DBsize     = (UINT16) sizeof (PXE_DB_STATION_ADDRESS);\r
125   Snp->Cdb.DBaddr     = (UINT64)(UINTN) Db;\r
126 \r
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
131 \r
132   //\r
133   // Issue UNDI command and check result.\r
134   //\r
135   DEBUG ((EFI_D_NET, "\nsnp->undi.station_addr()  "));\r
136 \r
137   (*Snp->IssueUndi32Command) ((UINT64)(UINTN) &Snp->Cdb);\r
138 \r
139   if (Snp->Cdb.StatCode != PXE_STATCODE_SUCCESS) {\r
140     DEBUG (\r
141       (EFI_D_ERROR,\r
142       "\nsnp->undi.station_addr()  %xh:%xh\n",\r
143       Snp->Cdb.StatFlags,\r
144       Snp->Cdb.StatCode)\r
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
155   PxeGetStnAddr (Snp);\r
156 \r
157   return EFI_SUCCESS;\r
158 }\r
159 \r
160 \r
161 /**\r
162   Modifies or resets the current station address, if supported.\r
163 \r
164   This function modifies or resets the current station address of a network\r
165   interface, if supported. If Reset is TRUE, then the current station address is\r
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
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
175   @param Reset Flag used to reset the station address to the network interface's\r
176                permanent address.\r
177   @param New   New station address to be used for the network interface.\r
178 \r
179 \r
180   @retval EFI_SUCCESS           The network interface's station address was updated.\r
181   @retval EFI_NOT_STARTED       The Simple Network Protocol interface has not been\r
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
185   @retval EFI_DEVICE_ERROR      The Simple Network Protocol interface has not\r
186                                 been initialized by calling Initialize().\r
187   @retval EFI_DEVICE_ERROR      An error occurred attempting to set the new\r
188                                 station address.\r
189   @retval EFI_UNSUPPORTED       The NIC does not support changing the network\r
190                                 interface's station address.\r
191 \r
192 **/\r
193 EFI_STATUS\r
194 EFIAPI\r
195 SnpUndi32StationAddress (\r
196   IN EFI_SIMPLE_NETWORK_PROTOCOL *This,\r
197   IN BOOLEAN                     Reset,\r
198   IN EFI_MAC_ADDRESS             *New OPTIONAL\r
199   )\r
200 {\r
201   SNP_DRIVER  *Snp;\r
202   EFI_STATUS  Status;\r
203   EFI_TPL     OldTpl;\r
204 \r
205   //\r
206   // Check for invalid parameter combinations.\r
207   //\r
208   if ((This == NULL) ||\r
209     (!Reset && (New == NULL))) {\r
210     return EFI_INVALID_PARAMETER;\r
211   }\r
212 \r
213   Snp = EFI_SIMPLE_NETWORK_DEV_FROM_THIS (This);\r
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
220   switch (Snp->Mode.State) {\r
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
233   if (Reset) {\r
234     Status = PxeSetStnAddr (Snp, NULL);\r
235   } else {\r
236     Status = PxeSetStnAddr (Snp, New);\r
237   }\r
238 \r
239 ON_EXIT:\r
240   gBS->RestoreTPL (OldTpl);\r
241 \r
242   return Status;\r
243 }\r