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