]> git.proxmox.com Git - mirror_edk2.git/blob - EdkModulePkg/Universal/Network/Snp32_64/Dxe/station_address.c
b5d2c402209b9c466fbb097b367b49f603e4fcd0
[mirror_edk2.git] / EdkModulePkg / Universal / Network / Snp32_64 / Dxe / station_address.c
1 /*++
2 Copyright (c) 2006, 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
7
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.
10
11 Module name:
12 station_address.c
13
14 Abstract:
15
16 Revision history:
17 2000-Feb-17 M(f)J Genesis.
18 --*/
19
20
21 #include "Snp.h"
22
23 EFI_STATUS
24 pxe_get_stn_addr (
25 SNP_DRIVER *snp
26 )
27 /*++
28
29 Routine Description:
30 this routine calls undi to read the MAC address of the NIC and updates the
31 mode structure with the address.
32
33 Arguments:
34 snp - pointer to snp driver structure
35
36 Returns:
37
38 --*/
39 {
40 PXE_DB_STATION_ADDRESS *db;
41
42 db = snp->db;
43 snp->cdb.OpCode = PXE_OPCODE_STATION_ADDRESS;
44 snp->cdb.OpFlags = PXE_OPFLAGS_STATION_ADDRESS_READ;
45
46 snp->cdb.CPBaddr = PXE_CPBADDR_NOT_USED;
47 snp->cdb.CPBsize = PXE_CPBSIZE_NOT_USED;
48
49 snp->cdb.DBsize = sizeof (PXE_DB_STATION_ADDRESS);
50 snp->cdb.DBaddr = (UINT64) (UINTN) db;
51
52 snp->cdb.StatCode = PXE_STATCODE_INITIALIZE;
53 snp->cdb.StatFlags = PXE_STATFLAGS_INITIALIZE;
54 snp->cdb.IFnum = snp->if_num;
55 snp->cdb.Control = PXE_CONTROL_LAST_CDB_IN_LIST;
56
57 //
58 // Issue UNDI command and check result.
59 //
60 DEBUG ((EFI_D_NET, "\nsnp->undi.station_addr() "));
61
62 (*snp->issue_undi32_command) ((UINT64) (UINTN) &snp->cdb);
63
64 if (snp->cdb.StatCode != PXE_STATCODE_SUCCESS) {
65 DEBUG (
66 (EFI_D_ERROR,
67 "\nsnp->undi.station_addr() %xh:%xh\n",
68 snp->cdb.StatFlags,
69 snp->cdb.StatCode)
70 );
71
72 return EFI_DEVICE_ERROR;
73 }
74 //
75 // Set new station address in SNP->Mode structure and return success.
76 //
77 CopyMem (
78 &(snp->mode.CurrentAddress),
79 &db->StationAddr,
80 snp->mode.HwAddressSize
81 );
82
83 CopyMem (
84 &snp->mode.BroadcastAddress,
85 &db->BroadcastAddr,
86 snp->mode.HwAddressSize
87 );
88
89 CopyMem (
90 &snp->mode.PermanentAddress,
91 &db->PermanentAddr,
92 snp->mode.HwAddressSize
93 );
94
95 return EFI_SUCCESS;
96 }
97
98 EFI_STATUS
99 pxe_set_stn_addr (
100 SNP_DRIVER *snp,
101 EFI_MAC_ADDRESS *NewMacAddr
102 )
103 /*++
104
105 Routine Description:
106 this routine calls undi to set a new MAC address for the NIC,
107
108 Arguments:
109 snp - pointer to snp driver structure
110 NewMacAddr - pointer to a mac address to be set for the nic, if this is NULL
111 then this routine resets the mac address to the NIC's original
112 address.
113
114 Returns:
115
116 --*/
117 {
118 PXE_CPB_STATION_ADDRESS *cpb;
119 PXE_DB_STATION_ADDRESS *db;
120
121 cpb = snp->cpb;
122 db = snp->db;
123 snp->cdb.OpCode = PXE_OPCODE_STATION_ADDRESS;
124
125 if (NewMacAddr == NULL) {
126 snp->cdb.OpFlags = PXE_OPFLAGS_STATION_ADDRESS_RESET;
127 snp->cdb.CPBsize = PXE_CPBSIZE_NOT_USED;
128 snp->cdb.CPBaddr = PXE_CPBADDR_NOT_USED;
129 } else {
130 snp->cdb.OpFlags = PXE_OPFLAGS_STATION_ADDRESS_READ;
131 //
132 // even though the OPFLAGS are set to READ, supplying a new address
133 // in the CPB will make undi change the mac address to the new one.
134 //
135 CopyMem (&cpb->StationAddr, NewMacAddr, snp->mode.HwAddressSize);
136
137 snp->cdb.CPBsize = sizeof (PXE_CPB_STATION_ADDRESS);
138 snp->cdb.CPBaddr = (UINT64) (UINTN) cpb;
139 }
140
141 snp->cdb.DBsize = sizeof (PXE_DB_STATION_ADDRESS);
142 snp->cdb.DBaddr = (UINT64) (UINTN) db;
143
144 snp->cdb.StatCode = PXE_STATCODE_INITIALIZE;
145 snp->cdb.StatFlags = PXE_STATFLAGS_INITIALIZE;
146 snp->cdb.IFnum = snp->if_num;
147 snp->cdb.Control = PXE_CONTROL_LAST_CDB_IN_LIST;
148
149 //
150 // Issue UNDI command and check result.
151 //
152 DEBUG ((EFI_D_NET, "\nsnp->undi.station_addr() "));
153
154 (*snp->issue_undi32_command) ((UINT64) (UINTN) &snp->cdb);
155
156 if (snp->cdb.StatCode != PXE_STATCODE_SUCCESS) {
157 DEBUG (
158 (EFI_D_ERROR,
159 "\nsnp->undi.station_addr() %xh:%xh\n",
160 snp->cdb.StatFlags,
161 snp->cdb.StatCode)
162 );
163
164 //
165 // UNDI command failed. Return UNDI status to caller.
166 //
167 return EFI_DEVICE_ERROR;
168 }
169 //
170 // read the changed address and save it in SNP->Mode structure
171 //
172 pxe_get_stn_addr (snp);
173
174 return EFI_SUCCESS;
175 }
176
177 EFI_STATUS
178 EFIAPI
179 snp_undi32_station_address (
180 IN EFI_SIMPLE_NETWORK_PROTOCOL * this,
181 IN BOOLEAN ResetFlag,
182 IN EFI_MAC_ADDRESS * NewMacAddr OPTIONAL
183 )
184 /*++
185
186 Routine Description:
187 This is the SNP interface routine for changing the NIC's mac address.
188 This routine basically retrieves snp structure, checks the SNP state and
189 calls the above routines to actually do the work
190
191 Arguments:
192 this - context pointer
193 NewMacAddr - pointer to a mac address to be set for the nic, if this is NULL
194 then this routine resets the mac address to the NIC's original
195 address.
196 ResetFlag - If true, the mac address will change to NIC's original address
197
198 Returns:
199
200 --*/
201 {
202 SNP_DRIVER *snp;
203 EFI_STATUS Status;
204
205 //
206 // Get pointer to SNP driver instance for *this.
207 //
208 if (this == NULL) {
209 return EFI_INVALID_PARAMETER;
210 }
211
212 snp = EFI_SIMPLE_NETWORK_DEV_FROM_THIS (this);
213
214 if (snp == NULL) {
215 return EFI_DEVICE_ERROR;
216 }
217 //
218 // Return error if the SNP is not initialized.
219 //
220 switch (snp->mode.State) {
221 case EfiSimpleNetworkInitialized:
222 break;
223
224 case EfiSimpleNetworkStopped:
225 return EFI_NOT_STARTED;
226
227 case EfiSimpleNetworkStarted:
228 return EFI_DEVICE_ERROR;
229
230 default:
231 return EFI_DEVICE_ERROR;
232 }
233 //
234 // Check for invalid parameter combinations.
235 //
236 if (!ResetFlag && NewMacAddr == NULL) {
237 return EFI_INVALID_PARAMETER;
238 }
239
240 if (ResetFlag) {
241 Status = pxe_set_stn_addr (snp, NULL);
242 } else {
243 Status = pxe_set_stn_addr (snp, NewMacAddr);
244
245 }
246
247 return Status;
248 }