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