]> git.proxmox.com Git - mirror_edk2.git/blob - MdeModulePkg/Universal/Network/SnpDxe/Initialize.c
sync comments, fix function header, rename variable name to follow coding style.
[mirror_edk2.git] / MdeModulePkg / Universal / Network / SnpDxe / Initialize.c
1 /** @file
2 Implementation of initializing a network adapter.
3
4 Copyright (c) 2004 - 2008, 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
16 #include "Snp.h"
17
18 /**
19 this routine calls undi to initialize the interface.
20
21 @param Snp pointer to snp driver structure
22 @param CableDetectFlag Do/don't detect the cable (depending on what undi supports)
23
24 @retval EFI_SUCCESS UNDI is initialized successfully
25 @retval EFI_DEVICE_ERROR UNDI could not be initialized
26 @retval Other other errors
27
28 **/
29 EFI_STATUS
30 PxeInit (
31 SNP_DRIVER *Snp,
32 UINT16 CableDetectFlag
33 )
34 {
35 PXE_CPB_INITIALIZE *Cpb;
36 VOID *Addr;
37 EFI_STATUS Status;
38
39 Cpb = Snp->Cpb;
40 if (Snp->TxRxBufferSize != 0) {
41 Status = Snp->PciIo->AllocateBuffer (
42 Snp->PciIo,
43 AllocateAnyPages,
44 EfiBootServicesData,
45 SNP_MEM_PAGES (Snp->TxRxBufferSize),
46 &Addr,
47 0
48 );
49
50 if (Status != EFI_SUCCESS) {
51 DEBUG (
52 (EFI_D_ERROR,
53 "\nSnp->PxeInit() AllocateBuffer %xh (%r)\n",
54 Status,
55 Status)
56 );
57
58 return Status;
59 }
60
61 ASSERT (Addr);
62
63 Snp->TxRxBuffer = Addr;
64 }
65
66 Cpb->MemoryAddr = (UINT64)(UINTN) Snp->TxRxBuffer;
67
68 Cpb->MemoryLength = Snp->TxRxBufferSize;
69
70 //
71 // let UNDI decide/detect these values
72 //
73 Cpb->LinkSpeed = 0;
74 Cpb->TxBufCnt = 0;
75 Cpb->TxBufSize = 0;
76 Cpb->RxBufCnt = 0;
77 Cpb->RxBufSize = 0;
78
79 Cpb->DuplexMode = PXE_DUPLEX_DEFAULT;
80
81 Cpb->LoopBackMode = LOOPBACK_NORMAL;
82
83 Snp->Cdb.OpCode = PXE_OPCODE_INITIALIZE;
84 Snp->Cdb.OpFlags = CableDetectFlag;
85
86 Snp->Cdb.CPBsize = sizeof (PXE_CPB_INITIALIZE);
87 Snp->Cdb.DBsize = sizeof (PXE_DB_INITIALIZE);
88
89 Snp->Cdb.CPBaddr = (UINT64)(UINTN) Snp->Cpb;
90 Snp->Cdb.DBaddr = (UINT64)(UINTN) Snp->Db;
91
92 Snp->Cdb.StatCode = PXE_STATCODE_INITIALIZE;
93 Snp->Cdb.StatFlags = PXE_STATFLAGS_INITIALIZE;
94 Snp->Cdb.IFnum = Snp->IfNum;
95 Snp->Cdb.Control = PXE_CONTROL_LAST_CDB_IN_LIST;
96
97 DEBUG ((EFI_D_NET, "\nSnp->undi.initialize() "));
98
99 (*Snp->IssueUndi32Command) ((UINT64)(UINTN) &Snp->Cdb);
100
101 if (Snp->Cdb.StatCode == PXE_STATCODE_SUCCESS) {
102 Snp->Mode.State = EfiSimpleNetworkInitialized;
103
104 Status = EFI_SUCCESS;
105 } else {
106 DEBUG (
107 (EFI_D_WARN,
108 "\nSnp->undi.initialize() %xh:%xh\n",
109 Snp->Cdb.StatFlags,
110 Snp->Cdb.StatCode)
111 );
112
113 if (Snp->TxRxBuffer != NULL) {
114 Snp->PciIo->FreeBuffer (
115 Snp->PciIo,
116 SNP_MEM_PAGES (Snp->TxRxBufferSize),
117 (VOID *) Snp->TxRxBuffer
118 );
119 }
120
121 Snp->TxRxBuffer = NULL;
122
123 Status = EFI_DEVICE_ERROR;
124 }
125
126 return Status;
127 }
128
129
130 /**
131 Resets a network adapter and allocates the transmit and receive buffers
132 required by the network interface; optionally, also requests allocation of
133 additional transmit and receive buffers.
134
135 This function allocates the transmit and receive buffers required by the network
136 interface. If this allocation fails, then EFI_OUT_OF_RESOURCES is returned.
137 If the allocation succeeds and the network interface is successfully initialized,
138 then EFI_SUCCESS will be returned.
139
140 @param This A pointer to the EFI_SIMPLE_NETWORK_PROTOCOL instance.
141
142 @param ExtraRxBufferSize The size, in bytes, of the extra receive buffer space
143 that the driver should allocate for the network interface.
144 Some network interfaces will not be able to use the
145 extra buffer, and the caller will not know if it is
146 actually being used.
147 @param ExtraTxBufferSize The size, in bytes, of the extra transmit buffer space
148 that the driver should allocate for the network interface.
149 Some network interfaces will not be able to use the
150 extra buffer, and the caller will not know if it is
151 actually being used.
152
153 @retval EFI_SUCCESS The network interface was initialized.
154 @retval EFI_NOT_STARTED The network interface has not been started.
155 @retval EFI_OUT_OF_RESOURCES There was not enough memory for the transmit and
156 receive buffers.
157 @retval EFI_INVALID_PARAMETER This parameter was NULL or did not point to a valid
158 EFI_SIMPLE_NETWORK_PROTOCOL structure.
159 @retval EFI_DEVICE_ERROR The command could not be sent to the network interface.
160 @retval EFI_UNSUPPORTED The increased buffer size feature is not supported.
161
162 **/
163 EFI_STATUS
164 EFIAPI
165 SnpUndi32Initialize (
166 IN EFI_SIMPLE_NETWORK_PROTOCOL *This,
167 IN UINTN ExtraRxBufferSize OPTIONAL,
168 IN UINTN ExtraTxBufferSize OPTIONAL
169 )
170 {
171 EFI_STATUS EfiStatus;
172 SNP_DRIVER *Snp;
173 EFI_TPL OldTpl;
174
175 if (This == NULL) {
176 return EFI_INVALID_PARAMETER;
177 }
178
179 Snp = EFI_SIMPLE_NETWORK_DEV_FROM_THIS (This);
180
181 OldTpl = gBS->RaiseTPL (TPL_CALLBACK);
182
183 if (Snp == NULL) {
184 EfiStatus = EFI_INVALID_PARAMETER;
185 goto ON_EXIT;
186 }
187
188 switch (Snp->Mode.State) {
189 case EfiSimpleNetworkStarted:
190 break;
191
192 case EfiSimpleNetworkStopped:
193 EfiStatus = EFI_NOT_STARTED;
194 goto ON_EXIT;
195
196 default:
197 EfiStatus = EFI_DEVICE_ERROR;
198 goto ON_EXIT;
199 }
200
201 EfiStatus = gBS->CreateEvent (
202 EVT_NOTIFY_WAIT,
203 TPL_NOTIFY,
204 &SnpWaitForPacketNotify,
205 Snp,
206 &Snp->Snp.WaitForPacket
207 );
208
209 if (EFI_ERROR (EfiStatus)) {
210 Snp->Snp.WaitForPacket = NULL;
211 EfiStatus = EFI_DEVICE_ERROR;
212 goto ON_EXIT;
213 }
214 //
215 //
216 //
217 Snp->Mode.MCastFilterCount = 0;
218 Snp->Mode.ReceiveFilterSetting = 0;
219 ZeroMem (Snp->Mode.MCastFilter, sizeof Snp->Mode.MCastFilter);
220 CopyMem (
221 &Snp->Mode.CurrentAddress,
222 &Snp->Mode.PermanentAddress,
223 sizeof (EFI_MAC_ADDRESS)
224 );
225
226 //
227 // Compute tx/rx buffer sizes based on UNDI init info and parameters.
228 //
229 Snp->TxRxBufferSize = (UINT32) (Snp->InitInfo.MemoryRequired + ExtraRxBufferSize + ExtraTxBufferSize);
230
231 if (Snp->Mode.MediaPresentSupported) {
232 if (PxeInit (Snp, PXE_OPFLAGS_INITIALIZE_DETECT_CABLE) == EFI_SUCCESS) {
233 Snp->Mode.MediaPresent = TRUE;
234 goto ON_EXIT;
235 }
236 }
237
238 Snp->Mode.MediaPresent = FALSE;
239
240 EfiStatus = PxeInit (Snp, PXE_OPFLAGS_INITIALIZE_DO_NOT_DETECT_CABLE);
241
242 if (EFI_ERROR (EfiStatus)) {
243 gBS->CloseEvent (Snp->Snp.WaitForPacket);
244 }
245
246 ON_EXIT:
247 gBS->RestoreTPL (OldTpl);
248
249 return EfiStatus;
250 }