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