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