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