]> git.proxmox.com Git - mirror_edk2.git/blame - EdkModulePkg/Universal/Network/Snp32_64/Dxe/statistics.c
Initial import.
[mirror_edk2.git] / EdkModulePkg / Universal / Network / Snp32_64 / Dxe / statistics.c
CommitLineData
878ddf1f 1/*++\r
2Copyright (c) 2006, Intel Corporation \r
3All rights reserved. This program and the accompanying materials \r
4are licensed and made available under the terms and conditions of the BSD License \r
5which accompanies this distribution. The full text of the license may be found at \r
6http://opensource.org/licenses/bsd-license.php \r
7 \r
8THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, \r
9WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. \r
10\r
11Module name:\r
12 statistics.c\r
13\r
14Abstract:\r
15\r
16Revision history:\r
17 2000-Feb-17 M(f)J Genesis.\r
18--*/\r
19\r
20\r
21#include "Snp.h"\r
22\r
23EFI_STATUS\r
24EFIAPI\r
25snp_undi32_statistics (\r
26 IN EFI_SIMPLE_NETWORK_PROTOCOL * this,\r
27 IN BOOLEAN ResetFlag,\r
28 IN OUT UINTN *StatTableSizePtr OPTIONAL,\r
29 IN OUT EFI_NETWORK_STATISTICS * StatTablePtr OPTIONAL\r
30 )\r
31/*++\r
32\r
33Routine Description:\r
34 This is the SNP interface routine for getting the NIC's statistics.\r
35 This routine basically retrieves snp structure, checks the SNP state and\r
36 calls the pxe_ routine to actually do the \r
37\r
38Arguments:\r
39 this - context pointer\r
40 ResetFlag - true to reset the NIC's statistics counters to zero.\r
41 StatTableSizePtr - pointer to the statistics table size\r
42 StatTablePtr - pointer to the statistics table \r
43 \r
44Returns:\r
45\r
46--*/\r
47{\r
48 SNP_DRIVER *snp;\r
49 PXE_DB_STATISTICS *db;\r
50 UINT64 *stp;\r
51 UINT64 mask;\r
52 UINTN size;\r
53 UINTN n;\r
54\r
55 //\r
56 // Get pointer to SNP driver instance for *this.\r
57 //\r
58 if (this == NULL) {\r
59 return EFI_INVALID_PARAMETER;\r
60 }\r
61\r
62 snp = EFI_SIMPLE_NETWORK_DEV_FROM_THIS (this);\r
63\r
64 if (snp == NULL) {\r
65 return EFI_DEVICE_ERROR;\r
66 }\r
67 //\r
68 // Return error if the SNP is not initialized.\r
69 //\r
70 switch (snp->mode.State) {\r
71 case EfiSimpleNetworkInitialized:\r
72 break;\r
73\r
74 case EfiSimpleNetworkStopped:\r
75 return EFI_NOT_STARTED;\r
76\r
77 case EfiSimpleNetworkStarted:\r
78 return EFI_DEVICE_ERROR;\r
79\r
80 default:\r
81 return EFI_DEVICE_ERROR;\r
82 }\r
83 //\r
84 // if we are not resetting the counters, we have to have a valid stat table\r
85 // with >0 size. if no reset, no table and no size, return success.\r
86 //\r
87 if (!ResetFlag && StatTableSizePtr == NULL) {\r
88 return StatTablePtr ? EFI_INVALID_PARAMETER : EFI_SUCCESS;\r
89 }\r
90 //\r
91 // Initialize UNDI Statistics CDB\r
92 //\r
93 snp->cdb.OpCode = PXE_OPCODE_STATISTICS;\r
94 snp->cdb.CPBsize = PXE_CPBSIZE_NOT_USED;\r
95 snp->cdb.CPBaddr = PXE_CPBADDR_NOT_USED;\r
96 snp->cdb.StatCode = PXE_STATCODE_INITIALIZE;\r
97 snp->cdb.StatFlags = PXE_STATFLAGS_INITIALIZE;\r
98 snp->cdb.IFnum = snp->if_num;\r
99 snp->cdb.Control = PXE_CONTROL_LAST_CDB_IN_LIST;\r
100\r
101 if (ResetFlag) {\r
102 snp->cdb.OpFlags = PXE_OPFLAGS_STATISTICS_RESET;\r
103 snp->cdb.DBsize = PXE_DBSIZE_NOT_USED;\r
104 snp->cdb.DBaddr = PXE_DBADDR_NOT_USED;\r
105 db = snp->db;\r
106 } else {\r
107 snp->cdb.OpFlags = PXE_OPFLAGS_STATISTICS_READ;\r
108 snp->cdb.DBsize = sizeof (PXE_DB_STATISTICS);\r
109 snp->cdb.DBaddr = (UINT64) (UINTN) (db = snp->db);\r
110 }\r
111 //\r
112 // Issue UNDI command and check result.\r
113 //\r
114 DEBUG ((EFI_D_NET, "\nsnp->undi.statistics() "));\r
115\r
116 (*snp->issue_undi32_command) ((UINT64) (UINTN) &snp->cdb);\r
117\r
118 switch (snp->cdb.StatCode) {\r
119 case PXE_STATCODE_SUCCESS:\r
120 break;\r
121\r
122 case PXE_STATCODE_UNSUPPORTED:\r
123 DEBUG (\r
124 (EFI_D_ERROR,\r
125 "\nsnp->undi.statistics() %xh:%xh\n",\r
126 snp->cdb.StatFlags,\r
127 snp->cdb.StatCode)\r
128 );\r
129\r
130 return EFI_UNSUPPORTED;\r
131\r
132 default:\r
133 DEBUG (\r
134 (EFI_D_ERROR,\r
135 "\nsnp->undi.statistics() %xh:%xh\n",\r
136 snp->cdb.StatFlags,\r
137 snp->cdb.StatCode)\r
138 );\r
139\r
140 return EFI_DEVICE_ERROR;\r
141 }\r
142\r
143 if (ResetFlag) {\r
144 return EFI_SUCCESS;\r
145 }\r
146\r
147 if (StatTablePtr == NULL) {\r
148 *StatTableSizePtr = sizeof (EFI_NETWORK_STATISTICS);\r
149 return EFI_BUFFER_TOO_SMALL;\r
150 }\r
151 //\r
152 // Convert the UNDI statistics information to SNP statistics\r
153 // information.\r
154 //\r
155 ZeroMem (StatTablePtr, *StatTableSizePtr);\r
156 stp = (UINT64 *) StatTablePtr;\r
157 size = 0;\r
158\r
159 for (n = 0, mask = 1; n < 64; n++, mask = LShiftU64 (mask, 1), stp++) {\r
160 //\r
161 // There must be room for a full UINT64. Partial\r
162 // numbers will not be stored.\r
163 //\r
164 if ((n + 1) * sizeof (UINT64) > *StatTableSizePtr) {\r
165 break;\r
166 }\r
167\r
168 if (db->Supported & mask) {\r
169 *stp = db->Data[n];\r
170 size = n + 1;\r
171 } else {\r
172 SetMem (stp, sizeof (UINT64), 0xFF);\r
173 }\r
174 }\r
175 //\r
176 // Compute size up to last supported statistic.\r
177 //\r
178 while (++n < 64) {\r
179 if (db->Supported & (mask = LShiftU64 (mask, 1))) {\r
180 size = n;\r
181 }\r
182 }\r
183\r
184 size *= sizeof (UINT64);\r
185\r
186 if (*StatTableSizePtr >= size) {\r
187 *StatTableSizePtr = size;\r
188 return EFI_SUCCESS;\r
189 } else {\r
190 *StatTableSizePtr = size;\r
191 return EFI_BUFFER_TOO_SMALL;\r
192 }\r
193}\r