]> git.proxmox.com Git - mirror_edk2.git/blame - MdeModulePkg/Universal/Network/SnpDxe/Get_status.c
NetworkPkg:Add a new error status code EFI_HTTP_ERROR
[mirror_edk2.git] / MdeModulePkg / Universal / Network / SnpDxe / Get_status.c
CommitLineData
75d0f44d 1/** @file\r
4140a663 2 Implementation of reading the current interrupt status and recycled transmit\r
3 buffer status from a network interface.\r
4cda7726 4\r
7b4b93a2 5Copyright (c) 2004 - 2016, Intel Corporation. All rights reserved.<BR>\r
e5eed7d3 6This program and the accompanying materials are licensed\r
c777c357 7and made available under the terms and conditions of the BSD License which\r
8accompanies this distribution. The full text of the license may be found at\r
9http://opensource.org/licenses/bsd-license.php\r
75d0f44d 10\r
11THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
12WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
13\r
75d0f44d 14**/\r
15\r
16#include "Snp.h"\r
17\r
75d0f44d 18/**\r
7b4b93a2
FS
19 Call undi to get the status of the interrupts, get the list of recycled transmit\r
20 buffers that completed transmitting. The recycled transmit buffer address will\r
21 be saved into Snp->RecycledTxBuf.\r
f3816027 22\r
23 @param Snp Pointer to snp driver structure.\r
c777c357 24 @param InterruptStatusPtr A non null pointer to contain the interrupt\r
f3816027 25 status.\r
7b4b93a2
FS
26 @param GetTransmittedBuf Set to TRUE to retrieve the recycled transmit\r
27 buffer address.\r
c777c357 28\r
f3816027 29 @retval EFI_SUCCESS The status of the network interface was retrieved.\r
c777c357 30 @retval EFI_DEVICE_ERROR The command could not be sent to the network\r
f3816027 31 interface.\r
75d0f44d 32\r
33**/\r
34EFI_STATUS\r
4cda7726 35PxeGetStatus (\r
36 SNP_DRIVER *Snp,\r
75d0f44d 37 UINT32 *InterruptStatusPtr,\r
7b4b93a2 38 BOOLEAN GetTransmittedBuf\r
75d0f44d 39 )\r
40{\r
4cda7726 41 PXE_DB_GET_STATUS *Db;\r
75d0f44d 42 UINT16 InterruptFlags;\r
7b4b93a2
FS
43 UINT32 Index;\r
44 UINT64 *Tmp;\r
75d0f44d 45\r
7b4b93a2 46 Tmp = NULL;\r
4cda7726 47 Db = Snp->Db;\r
48 Snp->Cdb.OpCode = PXE_OPCODE_GET_STATUS;\r
75d0f44d 49\r
4cda7726 50 Snp->Cdb.OpFlags = 0;\r
75d0f44d 51\r
7b4b93a2 52 if (GetTransmittedBuf) {\r
4cda7726 53 Snp->Cdb.OpFlags |= PXE_OPFLAGS_GET_TRANSMITTED_BUFFERS;\r
7b4b93a2 54 ZeroMem (Db->TxBuffer, sizeof (Db->TxBuffer));\r
75d0f44d 55 }\r
56\r
57 if (InterruptStatusPtr != NULL) {\r
4cda7726 58 Snp->Cdb.OpFlags |= PXE_OPFLAGS_GET_INTERRUPT_STATUS;\r
75d0f44d 59 }\r
60\r
c777c357 61 if (Snp->MediaStatusSupported) {\r
62 Snp->Cdb.OpFlags |= PXE_OPFLAGS_GET_MEDIA_STATUS;\r
63 }\r
64\r
4cda7726 65 Snp->Cdb.CPBsize = PXE_CPBSIZE_NOT_USED;\r
66 Snp->Cdb.CPBaddr = PXE_CPBADDR_NOT_USED;\r
75d0f44d 67\r
68 //\r
69 // size DB for return of one buffer\r
70 //\r
4cda7726 71 Snp->Cdb.DBsize = (UINT16) ((sizeof (PXE_DB_GET_STATUS) - sizeof (Db->TxBuffer)) + sizeof (Db->TxBuffer[0]));\r
75d0f44d 72\r
4cda7726 73 Snp->Cdb.DBaddr = (UINT64)(UINTN) Db;\r
75d0f44d 74\r
4cda7726 75 Snp->Cdb.StatCode = PXE_STATCODE_INITIALIZE;\r
76 Snp->Cdb.StatFlags = PXE_STATFLAGS_INITIALIZE;\r
77 Snp->Cdb.IFnum = Snp->IfNum;\r
78 Snp->Cdb.Control = PXE_CONTROL_LAST_CDB_IN_LIST;\r
75d0f44d 79\r
80 //\r
81 // Issue UNDI command and check result.\r
82 //\r
9cff2f8d 83 DEBUG ((EFI_D_NET, "\nSnp->undi.get_status() "));\r
75d0f44d 84\r
4cda7726 85 (*Snp->IssueUndi32Command) ((UINT64)(UINTN) &Snp->Cdb);\r
75d0f44d 86\r
4cda7726 87 if (Snp->Cdb.StatCode != EFI_SUCCESS) {\r
75d0f44d 88 DEBUG (\r
9cff2f8d 89 (EFI_D_NET,\r
4cda7726 90 "\nSnp->undi.get_status() %xh:%xh\n",\r
91 Snp->Cdb.StatFlags,\r
92 Snp->Cdb.StatFlags)\r
75d0f44d 93 );\r
94\r
95 return EFI_DEVICE_ERROR;\r
96 }\r
97 //\r
98 // report the values back..\r
99 //\r
100 if (InterruptStatusPtr != NULL) {\r
4cda7726 101 InterruptFlags = (UINT16) (Snp->Cdb.StatFlags & PXE_STATFLAGS_GET_STATUS_INTERRUPT_MASK);\r
75d0f44d 102\r
103 *InterruptStatusPtr = 0;\r
104\r
4cda7726 105 if ((InterruptFlags & PXE_STATFLAGS_GET_STATUS_RECEIVE) == PXE_STATFLAGS_GET_STATUS_RECEIVE) {\r
75d0f44d 106 *InterruptStatusPtr |= EFI_SIMPLE_NETWORK_RECEIVE_INTERRUPT;\r
107 }\r
108\r
4cda7726 109 if ((InterruptFlags & PXE_STATFLAGS_GET_STATUS_TRANSMIT) == PXE_STATFLAGS_GET_STATUS_TRANSMIT) {\r
75d0f44d 110 *InterruptStatusPtr |= EFI_SIMPLE_NETWORK_TRANSMIT_INTERRUPT;\r
111 }\r
112\r
4cda7726 113 if ((InterruptFlags & PXE_STATFLAGS_GET_STATUS_COMMAND) == PXE_STATFLAGS_GET_STATUS_COMMAND) {\r
75d0f44d 114 *InterruptStatusPtr |= EFI_SIMPLE_NETWORK_COMMAND_INTERRUPT;\r
115 }\r
116\r
4cda7726 117 if ((InterruptFlags & PXE_STATFLAGS_GET_STATUS_SOFTWARE) == PXE_STATFLAGS_GET_STATUS_SOFTWARE) {\r
75d0f44d 118 *InterruptStatusPtr |= EFI_SIMPLE_NETWORK_COMMAND_INTERRUPT;\r
119 }\r
120\r
121 }\r
122\r
7b4b93a2
FS
123 if (GetTransmittedBuf) {\r
124 if ((Snp->Cdb.StatFlags & PXE_STATFLAGS_GET_STATUS_NO_TXBUFS_WRITTEN) == 0) {\r
125 //\r
126 // UNDI has written some transmitted buffer addresses into the DB. Store them into Snp->RecycledTxBuf.\r
127 //\r
128 for (Index = 0; Index < MAX_XMIT_BUFFERS; Index++) {\r
129 if (Db->TxBuffer[Index] != 0) {\r
130 if (Snp->RecycledTxBufCount == Snp->MaxRecycledTxBuf) {\r
131 //\r
132 // Snp->RecycledTxBuf is full, reallocate a new one.\r
133 //\r
134 if ((Snp->MaxRecycledTxBuf + SNP_TX_BUFFER_INCREASEMENT) >= SNP_MAX_TX_BUFFER_NUM) {\r
135 return EFI_DEVICE_ERROR;\r
136 }\r
137 Tmp = AllocatePool (sizeof (UINT64) * (Snp->MaxRecycledTxBuf + SNP_TX_BUFFER_INCREASEMENT));\r
138 if (Tmp == NULL) {\r
139 return EFI_DEVICE_ERROR;\r
140 }\r
141 CopyMem (Tmp, Snp->RecycledTxBuf, sizeof (UINT64) * Snp->RecycledTxBufCount);\r
142 FreePool (Snp->RecycledTxBuf);\r
143 Snp->RecycledTxBuf = Tmp;\r
144 Snp->MaxRecycledTxBuf += SNP_TX_BUFFER_INCREASEMENT;\r
145 }\r
146 Snp->RecycledTxBuf[Snp->RecycledTxBufCount] = Db->TxBuffer[Index];\r
147 Snp->RecycledTxBufCount++;\r
148 }\r
149 }\r
150 }\r
75d0f44d 151 }\r
152\r
c777c357 153 //\r
154 // Update MediaPresent field of EFI_SIMPLE_NETWORK_MODE if the UNDI support\r
155 // returning media status from GET_STATUS command\r
156 //\r
157 if (Snp->MediaStatusSupported) {\r
158 Snp->Snp.Mode->MediaPresent =\r
159 (BOOLEAN) (((Snp->Cdb.StatFlags & PXE_STATFLAGS_GET_STATUS_NO_MEDIA) != 0) ? FALSE : TRUE);\r
160 }\r
161\r
75d0f44d 162 return EFI_SUCCESS;\r
163}\r
164\r
75d0f44d 165/**\r
4cda7726 166 Reads the current interrupt status and recycled transmit buffer status from a\r
167 network interface.\r
c777c357 168\r
169 This function gets the current interrupt and recycled transmit buffer status\r
4cda7726 170 from the network interface. The interrupt status is returned as a bit mask in\r
171 InterruptStatus. If InterruptStatus is NULL, the interrupt status will not be\r
172 read. If TxBuf is not NULL, a recycled transmit buffer address will be retrieved.\r
173 If a recycled transmit buffer address is returned in TxBuf, then the buffer has\r
174 been successfully transmitted, and the status for that buffer is cleared. If\r
c777c357 175 the status of the network interface is successfully collected, EFI_SUCCESS\r
4cda7726 176 will be returned. If the driver has not been initialized, EFI_DEVICE_ERROR will\r
177 be returned.\r
178\r
179 @param This A pointer to the EFI_SIMPLE_NETWORK_PROTOCOL instance.\r
c777c357 180 @param InterruptStatus A pointer to the bit mask of the currently active\r
4cda7726 181 interrupts (see "Related Definitions"). If this is NULL,\r
182 the interrupt status will not be read from the device.\r
183 If this is not NULL, the interrupt status will be read\r
c777c357 184 from the device. When the interrupt status is read, it\r
185 will also be cleared. Clearing the transmit interrupt does\r
4cda7726 186 not empty the recycled transmit buffer array.\r
187 @param TxBuf Recycled transmit buffer address. The network interface\r
c777c357 188 will not transmit if its internal recycled transmit\r
4cda7726 189 buffer array is full. Reading the transmit buffer does\r
190 not clear the transmit interrupt. If this is NULL, then\r
c777c357 191 the transmit buffer status will not be read. If there\r
192 are no transmit buffers to recycle and TxBuf is not NULL,\r
4cda7726 193 TxBuf will be set to NULL.\r
194\r
195 @retval EFI_SUCCESS The status of the network interface was retrieved.\r
196 @retval EFI_NOT_STARTED The network interface has not been started.\r
c777c357 197 @retval EFI_INVALID_PARAMETER This parameter was NULL or did not point to a valid\r
4cda7726 198 EFI_SIMPLE_NETWORK_PROTOCOL structure.\r
c777c357 199 @retval EFI_DEVICE_ERROR The command could not be sent to the network\r
4cda7726 200 interface.\r
75d0f44d 201\r
202**/\r
203EFI_STATUS\r
204EFIAPI\r
4cda7726 205SnpUndi32GetStatus (\r
206 IN EFI_SIMPLE_NETWORK_PROTOCOL *This,\r
207 OUT UINT32 *InterruptStatus, OPTIONAL\r
208 OUT VOID **TxBuf OPTIONAL\r
75d0f44d 209 )\r
210{\r
4cda7726 211 SNP_DRIVER *Snp;\r
75d0f44d 212 EFI_TPL OldTpl;\r
213 EFI_STATUS Status;\r
214\r
4cda7726 215 if (This == NULL) {\r
75d0f44d 216 return EFI_INVALID_PARAMETER;\r
217 }\r
218\r
4cda7726 219 if (InterruptStatus == NULL && TxBuf == NULL) {\r
75d0f44d 220 return EFI_INVALID_PARAMETER;\r
221 }\r
222\r
4cda7726 223 Snp = EFI_SIMPLE_NETWORK_DEV_FROM_THIS (This);\r
75d0f44d 224\r
225 OldTpl = gBS->RaiseTPL (TPL_CALLBACK);\r
226\r
4cda7726 227 if (Snp == NULL) {\r
75d0f44d 228 return EFI_DEVICE_ERROR;\r
229 }\r
230\r
4cda7726 231 switch (Snp->Mode.State) {\r
75d0f44d 232 case EfiSimpleNetworkInitialized:\r
233 break;\r
234\r
235 case EfiSimpleNetworkStopped:\r
236 Status = EFI_NOT_STARTED;\r
237 goto ON_EXIT;\r
238\r
239 default:\r
240 Status = EFI_DEVICE_ERROR;\r
241 goto ON_EXIT;\r
242 }\r
243\r
7b4b93a2
FS
244 if (Snp->RecycledTxBufCount == 0 && TxBuf != NULL) {\r
245 Status = PxeGetStatus (Snp, InterruptStatus, TRUE);\r
246 } else {\r
247 Status = PxeGetStatus (Snp, InterruptStatus, FALSE);\r
248 }\r
249\r
250 if (TxBuf != NULL) {\r
251 //\r
252 // Get a recycled buf from Snp->RecycledTxBuf\r
253 //\r
254 if (Snp->RecycledTxBufCount == 0) {\r
255 *TxBuf = NULL;\r
256 } else {\r
257 Snp->RecycledTxBufCount--;\r
258 *TxBuf = (VOID *) (UINTN) Snp->RecycledTxBuf[Snp->RecycledTxBufCount];\r
259 }\r
260 }\r
75d0f44d 261\r
262ON_EXIT:\r
263 gBS->RestoreTPL (OldTpl);\r
264\r
265 return Status;\r
266}\r