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