]> git.proxmox.com Git - mirror_edk2.git/blob - MdeModulePkg/Universal/Network/SnpDxe/Start.c
6be07339d8070097ec36b8c530fe60979b487abf
[mirror_edk2.git] / MdeModulePkg / Universal / Network / SnpDxe / Start.c
1 /** @file
2 Implementation of starting a network adapter.
3
4 Copyright (c) 2004 - 2007, 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 #include "Snp.h"
16
17
18 /**
19 Call UNDI to start the interface and changes the snp state.
20
21 @param Snp pointer to snp driver structure.
22
23 @retval EFI_SUCCESS UNDI is started successfully.
24 @retval EFI_DEVICE_ERROR UNDI could not be started.
25
26 **/
27 EFI_STATUS
28 PxeStart (
29 IN SNP_DRIVER *Snp
30 )
31 {
32 PXE_CPB_START_31 *Cpb31;
33
34 Cpb31 = Snp->Cpb;
35 //
36 // Initialize UNDI Start CDB for H/W UNDI
37 //
38 Snp->Cdb.OpCode = PXE_OPCODE_START;
39 Snp->Cdb.OpFlags = PXE_OPFLAGS_NOT_USED;
40 Snp->Cdb.CPBsize = PXE_CPBSIZE_NOT_USED;
41 Snp->Cdb.DBsize = PXE_DBSIZE_NOT_USED;
42 Snp->Cdb.CPBaddr = PXE_CPBADDR_NOT_USED;
43 Snp->Cdb.DBaddr = PXE_DBADDR_NOT_USED;
44 Snp->Cdb.StatCode = PXE_STATCODE_INITIALIZE;
45 Snp->Cdb.StatFlags = PXE_STATFLAGS_INITIALIZE;
46 Snp->Cdb.IFnum = Snp->IfNum;
47 Snp->Cdb.Control = PXE_CONTROL_LAST_CDB_IN_LIST;
48
49 //
50 // Make changes to H/W UNDI Start CDB if this is
51 // a S/W UNDI.
52 //
53 if (Snp->IsSwUndi) {
54 Snp->Cdb.CPBsize = sizeof (PXE_CPB_START_31);
55 Snp->Cdb.CPBaddr = (UINT64)(UINTN) Cpb31;
56
57 Cpb31->Delay = (UINT64)(UINTN) &SnpUndi32CallbackDelay;
58 Cpb31->Block = (UINT64)(UINTN) &SnpUndi32CallbackBlock;
59
60 //
61 // Virtual == Physical. This can be set to zero.
62 //
63 Cpb31->Virt2Phys = (UINT64)(UINTN) 0;
64 Cpb31->Mem_IO = (UINT64)(UINTN) &SnpUndi32CallbackMemio;
65
66 Cpb31->Map_Mem = (UINT64)(UINTN) &SnpUndi32CallbackMap;
67 Cpb31->UnMap_Mem = (UINT64)(UINTN) &SnpUndi32CallbackUnmap;
68 Cpb31->Sync_Mem = (UINT64)(UINTN) &SnpUndi32CallbackSync;
69
70 Cpb31->Unique_ID = (UINT64)(UINTN) Snp;
71 }
72 //
73 // Issue UNDI command and check result.
74 //
75 DEBUG ((EFI_D_NET, "\nsnp->undi.start() "));
76
77 (*Snp->IssueUndi32Command) ((UINT64)(UINTN) &Snp->Cdb);
78
79 if (Snp->Cdb.StatCode != PXE_STATCODE_SUCCESS) {
80 //
81 // UNDI could not be started. Return UNDI error.
82 //
83 DEBUG (
84 (EFI_D_ERROR,
85 "\nsnp->undi.start() %xh:%xh\n",
86 Snp->Cdb.StatCode,
87 Snp->Cdb.StatFlags)
88 );
89
90 return EFI_DEVICE_ERROR;
91 }
92 //
93 // Set simple network state to Started and return success.
94 //
95 Snp->Mode.State = EfiSimpleNetworkStarted;
96
97 return EFI_SUCCESS;
98 }
99
100
101 /**
102 Change the state of a network interface from "stopped" to "started."
103
104 This function starts a network interface. If the network interface successfully
105 starts, then EFI_SUCCESS will be returned.
106
107 @param This A pointer to the EFI_SIMPLE_NETWORK_PROTOCOL instance.
108
109 @retval EFI_SUCCESS The network interface was started.
110 @retval EFI_ALREADY_STARTED The network interface is already in the started state.
111 @retval EFI_INVALID_PARAMETER This parameter was NULL or did not point to a valid
112 EFI_SIMPLE_NETWORK_PROTOCOL structure.
113 @retval EFI_DEVICE_ERROR The command could not be sent to the network interface.
114 @retval EFI_UNSUPPORTED This function is not supported by the network interface.
115
116 **/
117 EFI_STATUS
118 EFIAPI
119 SnpUndi32Start (
120 IN EFI_SIMPLE_NETWORK_PROTOCOL *This
121 )
122 {
123 SNP_DRIVER *Snp;
124 EFI_STATUS Status;
125 UINTN Index;
126 EFI_TPL OldTpl;
127
128 if (This == NULL) {
129 return EFI_INVALID_PARAMETER;
130 }
131
132 Snp = EFI_SIMPLE_NETWORK_DEV_FROM_THIS (This);
133
134 OldTpl = gBS->RaiseTPL (TPL_CALLBACK);
135
136 switch (Snp->Mode.State) {
137 case EfiSimpleNetworkStopped:
138 break;
139
140 case EfiSimpleNetworkStarted:
141 case EfiSimpleNetworkInitialized:
142 Status = EFI_ALREADY_STARTED;
143 goto ON_EXIT;
144
145 default:
146 Status = EFI_DEVICE_ERROR;
147 goto ON_EXIT;
148 }
149
150 Status = PxeStart (Snp);
151 if (EFI_ERROR (Status)) {
152 goto ON_EXIT;
153 }
154 //
155 // clear the map_list in SNP structure
156 //
157 for (Index = 0; Index < MAX_MAP_LENGTH; Index++) {
158 Snp->MapList[Index].VirtualAddress = 0;
159 Snp->MapList[Index].MapCookie = 0;
160 }
161
162 Snp->Mode.MCastFilterCount = 0;
163
164 ON_EXIT:
165 gBS->RestoreTPL (OldTpl);
166
167 return Status;
168 }