]> git.proxmox.com Git - mirror_edk2.git/blame - NetworkPkg/SnpDxe/Statistics.c
UefiCpuPkg: Move AsmRelocateApLoopStart from Mpfuncs.nasm to AmdSev.nasm
[mirror_edk2.git] / NetworkPkg / SnpDxe / Statistics.c
CommitLineData
1f4db48d 1/** @file\r
4cda7726 2 Implementation of collecting the statistics on a network interface.\r
e2851998 3\r
e5eed7d3 4Copyright (c) 2004 - 2010, Intel Corporation. All rights reserved.<BR>\r
9d510e61 5SPDX-License-Identifier: BSD-2-Clause-Patent\r
1f4db48d 6\r
1f4db48d 7**/\r
8\r
1f4db48d 9#include "Snp.h"\r
10\r
1f4db48d 11/**\r
4cda7726 12 Resets or collects the statistics on a network interface.\r
e2851998 13\r
4cda7726 14 This function resets or collects the statistics on a network interface. If the\r
15 size of the statistics table specified by StatisticsSize is not big enough for\r
16 all the statistics that are collected by the network interface, then a partial\r
e2851998 17 buffer of statistics is returned in StatisticsTable, StatisticsSize is set to\r
18 the size required to collect all the available statistics, and\r
4cda7726 19 EFI_BUFFER_TOO_SMALL is returned.\r
e2851998 20 If StatisticsSize is big enough for all the statistics, then StatisticsTable\r
21 will be filled, StatisticsSize will be set to the size of the returned\r
4cda7726 22 StatisticsTable structure, and EFI_SUCCESS is returned.\r
23 If the driver has not been initialized, EFI_DEVICE_ERROR will be returned.\r
24 If Reset is FALSE, and both StatisticsSize and StatisticsTable are NULL, then\r
25 no operations will be performed, and EFI_SUCCESS will be returned.\r
26 If Reset is TRUE, then all of the supported statistics counters on this network\r
27 interface will be reset to zero.\r
28\r
29 @param This A pointer to the EFI_SIMPLE_NETWORK_PROTOCOL instance.\r
30 @param Reset Set to TRUE to reset the statistics for the network interface.\r
e2851998 31 @param StatisticsSize On input the size, in bytes, of StatisticsTable. On output\r
4cda7726 32 the size, in bytes, of the resulting table of statistics.\r
e2851998 33 @param StatisticsTable A pointer to the EFI_NETWORK_STATISTICS structure that\r
34 contains the statistics. Type EFI_NETWORK_STATISTICS is\r
35 defined in "Related Definitions" below.\r
36\r
4cda7726 37 @retval EFI_SUCCESS The requested operation succeeded.\r
38 @retval EFI_NOT_STARTED The Simple Network Protocol interface has not been\r
39 started by calling Start().\r
e2851998 40 @retval EFI_BUFFER_TOO_SMALL StatisticsSize is not NULL and StatisticsTable is\r
41 NULL. The current buffer size that is needed to\r
4cda7726 42 hold all the statistics is returned in StatisticsSize.\r
e2851998 43 @retval EFI_BUFFER_TOO_SMALL StatisticsSize is not NULL and StatisticsTable is\r
4cda7726 44 not NULL. The current buffer size that is needed\r
e2851998 45 to hold all the statistics is returned in\r
46 StatisticsSize. A partial set of statistics is\r
4cda7726 47 returned in StatisticsTable.\r
e2851998 48 @retval EFI_INVALID_PARAMETER StatisticsSize is NULL and StatisticsTable is not\r
4cda7726 49 NULL.\r
e2851998 50 @retval EFI_DEVICE_ERROR The Simple Network Protocol interface has not\r
4cda7726 51 been initialized by calling Initialize().\r
e2851998 52 @retval EFI_DEVICE_ERROR An error was encountered collecting statistics\r
4cda7726 53 from the NIC.\r
e2851998 54 @retval EFI_UNSUPPORTED The NIC does not support collecting statistics\r
4cda7726 55 from the network interface.\r
1f4db48d 56\r
57**/\r
58EFI_STATUS\r
59EFIAPI\r
4cda7726 60SnpUndi32Statistics (\r
d1050b9d
MK
61 IN EFI_SIMPLE_NETWORK_PROTOCOL *This,\r
62 IN BOOLEAN Reset,\r
63 IN OUT UINTN *StatisticsSize OPTIONAL,\r
64 IN OUT EFI_NETWORK_STATISTICS *StatisticsTable OPTIONAL\r
1f4db48d 65 )\r
66{\r
d1050b9d
MK
67 SNP_DRIVER *Snp;\r
68 PXE_DB_STATISTICS *Db;\r
69 UINT64 *Stp;\r
70 UINT64 Mask;\r
71 UINTN Size;\r
72 UINTN Index;\r
73 EFI_TPL OldTpl;\r
74 EFI_STATUS Status;\r
1f4db48d 75\r
76 //\r
4cda7726 77 // Get pointer to SNP driver instance for *This.\r
1f4db48d 78 //\r
4cda7726 79 if (This == NULL) {\r
1f4db48d 80 return EFI_INVALID_PARAMETER;\r
81 }\r
82\r
4cda7726 83 Snp = EFI_SIMPLE_NETWORK_DEV_FROM_THIS (This);\r
1f4db48d 84\r
85 OldTpl = gBS->RaiseTPL (TPL_CALLBACK);\r
86\r
87 //\r
88 // Return error if the SNP is not initialized.\r
89 //\r
4cda7726 90 switch (Snp->Mode.State) {\r
d1050b9d
MK
91 case EfiSimpleNetworkInitialized:\r
92 break;\r
1f4db48d 93\r
d1050b9d
MK
94 case EfiSimpleNetworkStopped:\r
95 Status = EFI_NOT_STARTED;\r
96 goto ON_EXIT;\r
1f4db48d 97\r
d1050b9d
MK
98 default:\r
99 Status = EFI_DEVICE_ERROR;\r
100 goto ON_EXIT;\r
1f4db48d 101 }\r
d1050b9d 102\r
1f4db48d 103 //\r
104 // if we are not resetting the counters, we have to have a valid stat table\r
105 // with >0 size. if no reset, no table and no size, return success.\r
106 //\r
d1050b9d 107 if (!Reset && (StatisticsSize == NULL)) {\r
4cda7726 108 Status = (StatisticsTable != NULL) ? EFI_INVALID_PARAMETER : EFI_SUCCESS;\r
1f4db48d 109 goto ON_EXIT;\r
110 }\r
d1050b9d 111\r
1f4db48d 112 //\r
113 // Initialize UNDI Statistics CDB\r
114 //\r
d1050b9d
MK
115 Snp->Cdb.OpCode = PXE_OPCODE_STATISTICS;\r
116 Snp->Cdb.CPBsize = PXE_CPBSIZE_NOT_USED;\r
117 Snp->Cdb.CPBaddr = PXE_CPBADDR_NOT_USED;\r
118 Snp->Cdb.StatCode = PXE_STATCODE_INITIALIZE;\r
119 Snp->Cdb.StatFlags = PXE_STATFLAGS_INITIALIZE;\r
120 Snp->Cdb.IFnum = Snp->IfNum;\r
121 Snp->Cdb.Control = PXE_CONTROL_LAST_CDB_IN_LIST;\r
4cda7726 122\r
123 if (Reset) {\r
d1050b9d
MK
124 Snp->Cdb.OpFlags = PXE_OPFLAGS_STATISTICS_RESET;\r
125 Snp->Cdb.DBsize = PXE_DBSIZE_NOT_USED;\r
126 Snp->Cdb.DBaddr = PXE_DBADDR_NOT_USED;\r
127 Db = Snp->Db;\r
1f4db48d 128 } else {\r
d1050b9d
MK
129 Snp->Cdb.OpFlags = PXE_OPFLAGS_STATISTICS_READ;\r
130 Snp->Cdb.DBsize = (UINT16)sizeof (PXE_DB_STATISTICS);\r
131 Snp->Cdb.DBaddr = (UINT64)(UINTN)(Db = Snp->Db);\r
1f4db48d 132 }\r
d1050b9d 133\r
1f4db48d 134 //\r
135 // Issue UNDI command and check result.\r
136 //\r
c49ca4a2 137 DEBUG ((DEBUG_NET, "\nsnp->undi.statistics() "));\r
1f4db48d 138\r
d1050b9d 139 (*Snp->IssueUndi32Command)((UINT64)(UINTN)&Snp->Cdb);\r
1f4db48d 140\r
4cda7726 141 switch (Snp->Cdb.StatCode) {\r
d1050b9d
MK
142 case PXE_STATCODE_SUCCESS:\r
143 break;\r
1f4db48d 144\r
d1050b9d
MK
145 case PXE_STATCODE_UNSUPPORTED:\r
146 DEBUG (\r
147 (DEBUG_ERROR,\r
148 "\nsnp->undi.statistics() %xh:%xh\n",\r
149 Snp->Cdb.StatFlags,\r
150 Snp->Cdb.StatCode)\r
151 );\r
152\r
153 Status = EFI_UNSUPPORTED;\r
154 goto ON_EXIT;\r
155\r
156 default:\r
157 DEBUG (\r
158 (DEBUG_ERROR,\r
159 "\nsnp->undi.statistics() %xh:%xh\n",\r
160 Snp->Cdb.StatFlags,\r
161 Snp->Cdb.StatCode)\r
162 );\r
163\r
164 Status = EFI_DEVICE_ERROR;\r
165 goto ON_EXIT;\r
1f4db48d 166 }\r
167\r
4cda7726 168 if (Reset) {\r
1f4db48d 169 Status = EFI_SUCCESS;\r
170 goto ON_EXIT;\r
171 }\r
172\r
4cda7726 173 if (StatisticsTable == NULL) {\r
174 *StatisticsSize = sizeof (EFI_NETWORK_STATISTICS);\r
d1050b9d 175 Status = EFI_BUFFER_TOO_SMALL;\r
1f4db48d 176 goto ON_EXIT;\r
177 }\r
d1050b9d 178\r
1f4db48d 179 //\r
180 // Convert the UNDI statistics information to SNP statistics\r
181 // information.\r
182 //\r
4cda7726 183 ZeroMem (StatisticsTable, *StatisticsSize);\r
d1050b9d
MK
184 Stp = (UINT64 *)StatisticsTable;\r
185 Size = 0;\r
1f4db48d 186\r
4cda7726 187 for (Index = 0, Mask = 1; Index < 64; Index++, Mask = LShiftU64 (Mask, 1), Stp++) {\r
1f4db48d 188 //\r
189 // There must be room for a full UINT64. Partial\r
190 // numbers will not be stored.\r
191 //\r
4cda7726 192 if ((Index + 1) * sizeof (UINT64) > *StatisticsSize) {\r
1f4db48d 193 break;\r
194 }\r
195\r
e2851998 196 if ((Db->Supported & Mask) != 0) {\r
d1050b9d
MK
197 *Stp = Db->Data[Index];\r
198 Size = Index + 1;\r
1f4db48d 199 } else {\r
4cda7726 200 SetMem (Stp, sizeof (UINT64), 0xFF);\r
1f4db48d 201 }\r
202 }\r
d1050b9d 203\r
1f4db48d 204 //\r
205 // Compute size up to last supported statistic.\r
206 //\r
4cda7726 207 while (++Index < 64) {\r
e2851998 208 if ((Db->Supported & (Mask = LShiftU64 (Mask, 1))) != 0) {\r
4cda7726 209 Size = Index;\r
1f4db48d 210 }\r
211 }\r
212\r
4cda7726 213 Size *= sizeof (UINT64);\r
1f4db48d 214\r
4cda7726 215 if (*StatisticsSize >= Size) {\r
216 *StatisticsSize = Size;\r
d1050b9d 217 Status = EFI_SUCCESS;\r
1f4db48d 218 } else {\r
4cda7726 219 *StatisticsSize = Size;\r
d1050b9d 220 Status = EFI_BUFFER_TOO_SMALL;\r
1f4db48d 221 }\r
222\r
223ON_EXIT:\r
224 gBS->RestoreTPL (OldTpl);\r
225\r
226 return Status;\r
227}\r