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