Statistics.c 7.3 KB

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