]> git.proxmox.com Git - mirror_edk2.git/blob - MdeModulePkg/Universal/Network/SnpDxe/start.c
1. Sync the latest network stack. Add NetLibCreateIPv4DPathNode () in netlib library.
[mirror_edk2.git] / MdeModulePkg / Universal / Network / SnpDxe / start.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 start.c
13
14 Abstract:
15
16 Revision history:
17 2000-Feb-07 M(f)J Genesis.
18
19 **/
20
21 #include "Snp.h"
22
23
24 /**
25 this routine calls undi to start the interface and changes the snp state!
26
27 @param snp pointer to snp driver structure
28
29
30 **/
31 EFI_STATUS
32 pxe_start (
33 SNP_DRIVER *snp
34 )
35 {
36 PXE_CPB_START_30 *cpb;
37 PXE_CPB_START_31 *cpb_31;
38
39 cpb = snp->cpb;
40 cpb_31 = snp->cpb;
41 //
42 // Initialize UNDI Start CDB for H/W UNDI
43 //
44 snp->cdb.OpCode = PXE_OPCODE_START;
45 snp->cdb.OpFlags = PXE_OPFLAGS_NOT_USED;
46 snp->cdb.CPBsize = PXE_CPBSIZE_NOT_USED;
47 snp->cdb.DBsize = PXE_DBSIZE_NOT_USED;
48 snp->cdb.CPBaddr = PXE_CPBADDR_NOT_USED;
49 snp->cdb.DBaddr = PXE_DBADDR_NOT_USED;
50 snp->cdb.StatCode = PXE_STATCODE_INITIALIZE;
51 snp->cdb.StatFlags = PXE_STATFLAGS_INITIALIZE;
52 snp->cdb.IFnum = snp->if_num;
53 snp->cdb.Control = PXE_CONTROL_LAST_CDB_IN_LIST;
54
55 //
56 // Make changes to H/W UNDI Start CDB if this is
57 // a S/W UNDI.
58 //
59 if (snp->is_swundi) {
60 if (snp->IsOldUndi) {
61 snp->cdb.CPBsize = sizeof (PXE_CPB_START_30);
62 snp->cdb.CPBaddr = (UINT64)(UINTN) cpb;
63
64 cpb->Delay = (UINT64)(UINTN) &snp_undi32_callback_delay_30;
65 cpb->Block = (UINT64)(UINTN) &snp_undi32_callback_block_30;
66
67 //
68 // Virtual == Physical. This can be set to zero.
69 //
70 cpb->Virt2Phys = (UINT64)(UINTN) &snp_undi32_callback_v2p_30;
71 cpb->Mem_IO = (UINT64)(UINTN) &snp_undi32_callback_memio_30;
72 } else {
73 snp->cdb.CPBsize = sizeof (PXE_CPB_START_31);
74 snp->cdb.CPBaddr = (UINT64)(UINTN) cpb_31;
75
76 cpb_31->Delay = (UINT64)(UINTN) &snp_undi32_callback_delay;
77 cpb_31->Block = (UINT64)(UINTN) &snp_undi32_callback_block;
78
79 //
80 // Virtual == Physical. This can be set to zero.
81 //
82 cpb_31->Virt2Phys = (UINT64)(UINTN) 0;
83 cpb_31->Mem_IO = (UINT64)(UINTN) &snp_undi32_callback_memio;
84
85 cpb_31->Map_Mem = (UINT64)(UINTN) &snp_undi32_callback_map;
86 cpb_31->UnMap_Mem = (UINT64)(UINTN) &snp_undi32_callback_unmap;
87 cpb_31->Sync_Mem = (UINT64)(UINTN) &snp_undi32_callback_sync;
88
89 cpb_31->Unique_ID = (UINT64)(UINTN) snp;
90 }
91 }
92 //
93 // Issue UNDI command and check result.
94 //
95 DEBUG ((EFI_D_NET, "\nsnp->undi.start() "));
96
97 (*snp->issue_undi32_command) ((UINT64)(UINTN) &snp->cdb);
98
99 if (snp->cdb.StatCode != PXE_STATCODE_SUCCESS) {
100 //
101 // UNDI could not be started. Return UNDI error.
102 //
103 DEBUG (
104 (EFI_D_ERROR,
105 "\nsnp->undi.start() %xh:%xh\n",
106 snp->cdb.StatCode,
107 snp->cdb.StatFlags)
108 );
109
110 return EFI_DEVICE_ERROR;
111 }
112 //
113 // Set simple network state to Started and return success.
114 //
115 snp->mode.State = EfiSimpleNetworkStarted;
116
117 return EFI_SUCCESS;
118 }
119
120
121 /**
122 This is the SNP interface routine for starting the interface
123 This routine basically retrieves snp structure, checks the SNP state and
124 calls the pxe_start routine to actually do start undi interface
125
126 @param This context pointer
127
128 @retval EFI_INVALID_PARAMETER "This" is Null
129 @retval No SNP driver can be extracted from "This"
130 @retval EFI_ALREADY_STARTED The state of SNP is EfiSimpleNetworkStarted or
131 EfiSimpleNetworkInitialized
132 @retval EFI_DEVICE_ERROR The state of SNP is other than
133 EfiSimpleNetworkStarted,
134 EfiSimpleNetworkInitialized, and
135 EfiSimpleNetworkStopped
136 @retval EFI_SUCCESS UNDI interface is succesfully started
137 @retval Other Error occurs while calling pxe_start function.
138
139 **/
140 EFI_STATUS
141 EFIAPI
142 snp_undi32_start (
143 IN EFI_SIMPLE_NETWORK_PROTOCOL *This
144 )
145 {
146 SNP_DRIVER *Snp;
147 EFI_STATUS Status;
148 UINTN Index;
149 EFI_TPL OldTpl;
150
151 if (This == NULL) {
152 return EFI_INVALID_PARAMETER;
153 }
154
155 Snp = EFI_SIMPLE_NETWORK_DEV_FROM_THIS (This);
156
157 OldTpl = gBS->RaiseTPL (TPL_CALLBACK);
158
159 switch (Snp->mode.State) {
160 case EfiSimpleNetworkStopped:
161 break;
162
163 case EfiSimpleNetworkStarted:
164 case EfiSimpleNetworkInitialized:
165 Status = EFI_ALREADY_STARTED;
166 goto ON_EXIT;
167
168 default:
169 Status = EFI_DEVICE_ERROR;
170 goto ON_EXIT;
171 }
172
173 Status = pxe_start (Snp);
174 if (EFI_ERROR (Status)) {
175 goto ON_EXIT;
176 }
177 //
178 // clear the map_list in SNP structure
179 //
180 for (Index = 0; Index < MAX_MAP_LENGTH; Index++) {
181 Snp->map_list[Index].virt = 0;
182 Snp->map_list[Index].map_cookie = 0;
183 }
184
185 Snp->mode.MCastFilterCount = 0;
186
187 ON_EXIT:
188 gBS->RestoreTPL (OldTpl);
189
190 return Status;
191 }