sync comments, fix function header, rename variable name to follow coding style.
[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 - 2007, Intel Corporation. <BR> \r
5 All rights reserved. This program and the accompanying materials are licensed \r
6 and made available under the terms and conditions of the BSD License which \r
7 accompanies this distribution. The full text of the license may be found at \r
8 http://opensource.org/licenses/bsd-license.php \r
9 \r
10 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
11 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
12 \r
13 **/\r
14 \r
15 #include "Snp.h"\r
16 \r
17 \r
18 /**\r
19   this routine calls undi to start the interface and changes the snp state.\r
20 \r
21   @param  Snp                    pointer to snp driver structure\r
22 \r
23   @retval EFI_DEVICE_ERROR       UNDI could not be started\r
24   @retval EFI_SUCCESS            UNDI is started successfully\r
25   \r
26 **/\r
27 EFI_STATUS\r
28 PxeStart (\r
29   IN SNP_DRIVER *Snp\r
30   )\r
31 {\r
32   PXE_CPB_START_31  *Cpb31;\r
33 \r
34   Cpb31  = Snp->Cpb;\r
35   //\r
36   // Initialize UNDI Start CDB for H/W UNDI\r
37   //\r
38   Snp->Cdb.OpCode     = PXE_OPCODE_START;\r
39   Snp->Cdb.OpFlags    = PXE_OPFLAGS_NOT_USED;\r
40   Snp->Cdb.CPBsize    = PXE_CPBSIZE_NOT_USED;\r
41   Snp->Cdb.DBsize     = PXE_DBSIZE_NOT_USED;\r
42   Snp->Cdb.CPBaddr    = PXE_CPBADDR_NOT_USED;\r
43   Snp->Cdb.DBaddr     = PXE_DBADDR_NOT_USED;\r
44   Snp->Cdb.StatCode   = PXE_STATCODE_INITIALIZE;\r
45   Snp->Cdb.StatFlags  = PXE_STATFLAGS_INITIALIZE;\r
46   Snp->Cdb.IFnum      = Snp->IfNum;\r
47   Snp->Cdb.Control    = PXE_CONTROL_LAST_CDB_IN_LIST;\r
48 \r
49   //\r
50   // Make changes to H/W UNDI Start CDB if this is\r
51   // a S/W UNDI.\r
52   //\r
53   if (Snp->IsSwUndi) {\r
54     Snp->Cdb.CPBsize  = sizeof (PXE_CPB_START_31);\r
55     Snp->Cdb.CPBaddr  = (UINT64)(UINTN) Cpb31;\r
56 \r
57     Cpb31->Delay     = (UINT64)(UINTN) &SnpUndi32CallbackDelay;\r
58     Cpb31->Block     = (UINT64)(UINTN) &SnpUndi32CallbackBlock;\r
59 \r
60     //\r
61     // Virtual == Physical.  This can be set to zero.\r
62     //\r
63     Cpb31->Virt2Phys = (UINT64)(UINTN) 0;\r
64     Cpb31->Mem_IO    = (UINT64)(UINTN) &SnpUndi32CallbackMemio;\r
65 \r
66     Cpb31->Map_Mem   = (UINT64)(UINTN) &SnpUndi32CallbackMap;\r
67     Cpb31->UnMap_Mem = (UINT64)(UINTN) &SnpUndi32CallbackUnmap;\r
68     Cpb31->Sync_Mem  = (UINT64)(UINTN) &SnpUndi32CallbackSync;\r
69 \r
70     Cpb31->Unique_ID = (UINT64)(UINTN) Snp;\r
71   }\r
72   //\r
73   // Issue UNDI command and check result.\r
74   //\r
75   DEBUG ((EFI_D_NET, "\nsnp->undi.start()  "));\r
76 \r
77   (*Snp->IssueUndi32Command) ((UINT64)(UINTN) &Snp->Cdb);\r
78 \r
79   if (Snp->Cdb.StatCode != PXE_STATCODE_SUCCESS) {\r
80     //\r
81     // UNDI could not be started. Return UNDI error.\r
82     //\r
83     DEBUG (\r
84       (EFI_D_ERROR,\r
85       "\nsnp->undi.start()  %xh:%xh\n",\r
86       Snp->Cdb.StatCode,\r
87       Snp->Cdb.StatFlags)\r
88       );\r
89 \r
90     return EFI_DEVICE_ERROR;\r
91   }\r
92   //\r
93   // Set simple network state to Started and return success.\r
94   //\r
95   Snp->Mode.State = EfiSimpleNetworkStarted;\r
96 \r
97   return EFI_SUCCESS;\r
98 }\r
99 \r
100 \r
101 /**\r
102   Changes the state of a network interface from "stopped" to "started."\r
103   \r
104   This function starts a network interface. If the network interface successfully\r
105   starts, then EFI_SUCCESS will be returned.\r
106 \r
107   @param  This                   A pointer to the EFI_SIMPLE_NETWORK_PROTOCOL instance.\r
108 \r
109   @retval EFI_SUCCESS            The network interface was started.\r
110   @retval EFI_ALREADY_STARTED    The network interface is already in the started state.\r
111   @retval EFI_INVALID_PARAMETER  This parameter was NULL or did not point to a valid \r
112                                  EFI_SIMPLE_NETWORK_PROTOCOL structure.\r
113   @retval EFI_DEVICE_ERROR       The command could not be sent to the network interface.\r
114   @retval EFI_UNSUPPORTED        This function is not supported by the network interface.\r
115 \r
116 **/\r
117 EFI_STATUS\r
118 EFIAPI\r
119 SnpUndi32Start (\r
120   IN EFI_SIMPLE_NETWORK_PROTOCOL *This\r
121   )\r
122 {\r
123   SNP_DRIVER  *Snp;\r
124   EFI_STATUS  Status;\r
125   UINTN       Index;\r
126   EFI_TPL     OldTpl;\r
127 \r
128   if (This == NULL) {\r
129     return EFI_INVALID_PARAMETER;\r
130   }\r
131 \r
132   Snp = EFI_SIMPLE_NETWORK_DEV_FROM_THIS (This);\r
133 \r
134   OldTpl = gBS->RaiseTPL (TPL_CALLBACK);\r
135 \r
136   switch (Snp->Mode.State) {\r
137   case EfiSimpleNetworkStopped:\r
138     break;\r
139 \r
140   case EfiSimpleNetworkStarted:\r
141   case EfiSimpleNetworkInitialized:\r
142     Status = EFI_ALREADY_STARTED;\r
143     goto ON_EXIT;\r
144 \r
145   default:\r
146     Status = EFI_DEVICE_ERROR;\r
147     goto ON_EXIT;\r
148   }\r
149 \r
150   Status = PxeStart (Snp);\r
151   if (EFI_ERROR (Status)) {\r
152     goto ON_EXIT;\r
153   }\r
154   //\r
155   // clear the map_list in SNP structure\r
156   //\r
157   for (Index = 0; Index < MAX_MAP_LENGTH; Index++) {\r
158     Snp->MapList[Index].VirtualAddress = 0;\r
159     Snp->MapList[Index].MapCookie      = 0;\r
160   }\r
161 \r
162   Snp->Mode.MCastFilterCount = 0;\r
163 \r
164 ON_EXIT:\r
165   gBS->RestoreTPL (OldTpl);\r
166 \r
167   return Status;\r
168 }\r