]> git.proxmox.com Git - mirror_edk2.git/blob - MdeModulePkg/Universal/Network/SnpDxe/initialize.c
Import SnpDxe, Tcp4Dxe, Udp4Dxe and MnpDxe.
[mirror_edk2.git] / MdeModulePkg / Universal / Network / SnpDxe / initialize.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 initialize.c
13
14 Abstract:
15
16 Revision history:
17 2000-Feb-09 M(f)J Genesis.
18
19 **/
20
21
22 #include "Snp.h"
23
24 VOID
25 EFIAPI
26 SnpWaitForPacketNotify (
27 IN EFI_EVENT Event,
28 IN VOID *SnpPtr
29 );
30
31
32 /**
33 this routine calls undi to initialize the interface.
34
35 @param snp pointer to snp driver structure
36 @param CableDetectFlag Do/don't detect the cable (depending on what undi
37 supports)
38
39
40 **/
41 EFI_STATUS
42 pxe_init (
43 SNP_DRIVER *snp,
44 UINT16 CableDetectFlag
45 )
46 {
47 PXE_CPB_INITIALIZE *cpb;
48 VOID *addr;
49 EFI_STATUS Status;
50
51 cpb = snp->cpb;
52 if (snp->tx_rx_bufsize != 0) {
53 Status = snp->IoFncs->AllocateBuffer (
54 snp->IoFncs,
55 AllocateAnyPages,
56 EfiBootServicesData,
57 SNP_MEM_PAGES (snp->tx_rx_bufsize),
58 &addr,
59 0
60 );
61
62 if (Status != EFI_SUCCESS) {
63 DEBUG (
64 (EFI_D_ERROR,
65 "\nsnp->pxe_init() AllocateBuffer %xh (%r)\n",
66 Status,
67 Status)
68 );
69
70 return Status;
71 }
72
73 ASSERT (addr);
74
75 snp->tx_rx_buffer = addr;
76 }
77
78 cpb->MemoryAddr = (UINT64)(UINTN) snp->tx_rx_buffer;
79
80 cpb->MemoryLength = snp->tx_rx_bufsize;
81
82 //
83 // let UNDI decide/detect these values
84 //
85 cpb->LinkSpeed = 0;
86 cpb->TxBufCnt = 0;
87 cpb->TxBufSize = 0;
88 cpb->RxBufCnt = 0;
89 cpb->RxBufSize = 0;
90
91 cpb->DuplexMode = PXE_DUPLEX_DEFAULT;
92
93 cpb->LoopBackMode = LOOPBACK_NORMAL;
94
95 snp->cdb.OpCode = PXE_OPCODE_INITIALIZE;
96 snp->cdb.OpFlags = CableDetectFlag;
97
98 snp->cdb.CPBsize = sizeof (PXE_CPB_INITIALIZE);
99 snp->cdb.DBsize = sizeof (PXE_DB_INITIALIZE);
100
101 snp->cdb.CPBaddr = (UINT64)(UINTN) snp->cpb;
102 snp->cdb.DBaddr = (UINT64)(UINTN) snp->db;
103
104 snp->cdb.StatCode = PXE_STATCODE_INITIALIZE;
105 snp->cdb.StatFlags = PXE_STATFLAGS_INITIALIZE;
106 snp->cdb.IFnum = snp->if_num;
107 snp->cdb.Control = PXE_CONTROL_LAST_CDB_IN_LIST;
108
109 DEBUG ((EFI_D_NET, "\nsnp->undi.initialize() "));
110
111 (*snp->issue_undi32_command) ((UINT64)(UINTN) &snp->cdb);
112
113 if (snp->cdb.StatCode == PXE_STATCODE_SUCCESS) {
114 snp->mode.State = EfiSimpleNetworkInitialized;
115
116 Status = EFI_SUCCESS;
117 } else {
118 DEBUG (
119 (EFI_D_WARN,
120 "\nsnp->undi.initialize() %xh:%xh\n",
121 snp->cdb.StatFlags,
122 snp->cdb.StatCode)
123 );
124
125 if (snp->tx_rx_buffer != NULL) {
126 snp->IoFncs->FreeBuffer (
127 snp->IoFncs,
128 SNP_MEM_PAGES (snp->tx_rx_bufsize),
129 (VOID *) snp->tx_rx_buffer
130 );
131 }
132
133 snp->tx_rx_buffer = NULL;
134
135 Status = EFI_DEVICE_ERROR;
136 }
137
138 return Status;
139 }
140
141
142 /**
143 This is the SNP interface routine for initializing the interface
144 This routine basically retrieves snp structure, checks the SNP state and
145 calls the pxe_initialize routine to actually do the undi initialization
146
147 @param this context pointer
148 @param extra_rx_buffer_size optional parameter, indicates extra space for
149 rx_buffers
150 @param extra_tx_buffer_size optional parameter, indicates extra space for
151 tx_buffers
152
153
154 **/
155 EFI_STATUS
156 EFIAPI
157 snp_undi32_initialize (
158 IN EFI_SIMPLE_NETWORK_PROTOCOL *this,
159 IN UINTN extra_rx_buffer_size OPTIONAL,
160 IN UINTN extra_tx_buffer_size OPTIONAL
161 )
162 {
163 EFI_STATUS EfiStatus;
164 SNP_DRIVER *snp;
165 EFI_TPL OldTpl;
166
167 //
168 //
169 //
170 if (this == NULL) {
171 return EFI_INVALID_PARAMETER;
172 }
173
174 snp = EFI_SIMPLE_NETWORK_DEV_FROM_THIS (this);
175
176 OldTpl = gBS->RaiseTPL (TPL_CALLBACK);
177
178 if (snp == NULL) {
179 EfiStatus = EFI_INVALID_PARAMETER;
180 goto ON_EXIT;
181 }
182
183 switch (snp->mode.State) {
184 case EfiSimpleNetworkStarted:
185 break;
186
187 case EfiSimpleNetworkStopped:
188 EfiStatus = EFI_NOT_STARTED;
189 goto ON_EXIT;
190
191 default:
192 EfiStatus = EFI_DEVICE_ERROR;
193 goto ON_EXIT;
194 }
195
196 EfiStatus = gBS->CreateEvent (
197 EVT_NOTIFY_WAIT,
198 TPL_NOTIFY,
199 &SnpWaitForPacketNotify,
200 snp,
201 &snp->snp.WaitForPacket
202 );
203
204 if (EFI_ERROR (EfiStatus)) {
205 snp->snp.WaitForPacket = NULL;
206 EfiStatus = EFI_DEVICE_ERROR;
207 goto ON_EXIT;
208 }
209 //
210 //
211 //
212 snp->mode.MCastFilterCount = 0;
213 snp->mode.ReceiveFilterSetting = 0;
214 ZeroMem (snp->mode.MCastFilter, sizeof snp->mode.MCastFilter);
215 CopyMem (
216 &snp->mode.CurrentAddress,
217 &snp->mode.PermanentAddress,
218 sizeof (EFI_MAC_ADDRESS)
219 );
220
221 //
222 // Compute tx/rx buffer sizes based on UNDI init info and parameters.
223 //
224 snp->tx_rx_bufsize = (UINT32) (snp->init_info.MemoryRequired + extra_rx_buffer_size + extra_tx_buffer_size);
225
226 if (snp->mode.MediaPresentSupported) {
227 if (pxe_init (snp, PXE_OPFLAGS_INITIALIZE_DETECT_CABLE) == EFI_SUCCESS) {
228 snp->mode.MediaPresent = TRUE;
229 goto ON_EXIT;
230 }
231 }
232
233 snp->mode.MediaPresent = FALSE;
234
235 EfiStatus = pxe_init (snp, PXE_OPFLAGS_INITIALIZE_DO_NOT_DETECT_CABLE);
236
237 if (EFI_ERROR (EfiStatus)) {
238 gBS->CloseEvent (snp->snp.WaitForPacket);
239 }
240
241 ON_EXIT:
242 gBS->RestoreTPL (OldTpl);
243
244 return EfiStatus;
245 }