123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227 |
- /** @file
- Implementation of collecting the statistics on a network interface.
- Copyright (c) 2004 - 2010, Intel Corporation. All rights reserved.<BR>
- SPDX-License-Identifier: BSD-2-Clause-Patent
- **/
- #include "Snp.h"
- /**
- Resets or collects the statistics on a network interface.
- This function resets or collects the statistics on a network interface. If the
- size of the statistics table specified by StatisticsSize is not big enough for
- all the statistics that are collected by the network interface, then a partial
- buffer of statistics is returned in StatisticsTable, StatisticsSize is set to
- the size required to collect all the available statistics, and
- EFI_BUFFER_TOO_SMALL is returned.
- If StatisticsSize is big enough for all the statistics, then StatisticsTable
- will be filled, StatisticsSize will be set to the size of the returned
- StatisticsTable structure, and EFI_SUCCESS is returned.
- If the driver has not been initialized, EFI_DEVICE_ERROR will be returned.
- If Reset is FALSE, and both StatisticsSize and StatisticsTable are NULL, then
- no operations will be performed, and EFI_SUCCESS will be returned.
- If Reset is TRUE, then all of the supported statistics counters on this network
- interface will be reset to zero.
- @param This A pointer to the EFI_SIMPLE_NETWORK_PROTOCOL instance.
- @param Reset Set to TRUE to reset the statistics for the network interface.
- @param StatisticsSize On input the size, in bytes, of StatisticsTable. On output
- the size, in bytes, of the resulting table of statistics.
- @param StatisticsTable A pointer to the EFI_NETWORK_STATISTICS structure that
- contains the statistics. Type EFI_NETWORK_STATISTICS is
- defined in "Related Definitions" below.
- @retval EFI_SUCCESS The requested operation succeeded.
- @retval EFI_NOT_STARTED The Simple Network Protocol interface has not been
- started by calling Start().
- @retval EFI_BUFFER_TOO_SMALL StatisticsSize is not NULL and StatisticsTable is
- NULL. The current buffer size that is needed to
- hold all the statistics is returned in StatisticsSize.
- @retval EFI_BUFFER_TOO_SMALL StatisticsSize is not NULL and StatisticsTable is
- not NULL. The current buffer size that is needed
- to hold all the statistics is returned in
- StatisticsSize. A partial set of statistics is
- returned in StatisticsTable.
- @retval EFI_INVALID_PARAMETER StatisticsSize is NULL and StatisticsTable is not
- NULL.
- @retval EFI_DEVICE_ERROR The Simple Network Protocol interface has not
- been initialized by calling Initialize().
- @retval EFI_DEVICE_ERROR An error was encountered collecting statistics
- from the NIC.
- @retval EFI_UNSUPPORTED The NIC does not support collecting statistics
- from the network interface.
- **/
- EFI_STATUS
- EFIAPI
- SnpUndi32Statistics (
- IN EFI_SIMPLE_NETWORK_PROTOCOL *This,
- IN BOOLEAN Reset,
- IN OUT UINTN *StatisticsSize OPTIONAL,
- IN OUT EFI_NETWORK_STATISTICS *StatisticsTable OPTIONAL
- )
- {
- SNP_DRIVER *Snp;
- PXE_DB_STATISTICS *Db;
- UINT64 *Stp;
- UINT64 Mask;
- UINTN Size;
- UINTN Index;
- EFI_TPL OldTpl;
- EFI_STATUS Status;
- //
- // Get pointer to SNP driver instance for *This.
- //
- if (This == NULL) {
- return EFI_INVALID_PARAMETER;
- }
- Snp = EFI_SIMPLE_NETWORK_DEV_FROM_THIS (This);
- OldTpl = gBS->RaiseTPL (TPL_CALLBACK);
- //
- // Return error if the SNP is not initialized.
- //
- switch (Snp->Mode.State) {
- case EfiSimpleNetworkInitialized:
- break;
- case EfiSimpleNetworkStopped:
- Status = EFI_NOT_STARTED;
- goto ON_EXIT;
- default:
- Status = EFI_DEVICE_ERROR;
- goto ON_EXIT;
- }
- //
- // if we are not resetting the counters, we have to have a valid stat table
- // with >0 size. if no reset, no table and no size, return success.
- //
- if (!Reset && (StatisticsSize == NULL)) {
- Status = (StatisticsTable != NULL) ? EFI_INVALID_PARAMETER : EFI_SUCCESS;
- goto ON_EXIT;
- }
- //
- // Initialize UNDI Statistics CDB
- //
- Snp->Cdb.OpCode = PXE_OPCODE_STATISTICS;
- Snp->Cdb.CPBsize = PXE_CPBSIZE_NOT_USED;
- Snp->Cdb.CPBaddr = PXE_CPBADDR_NOT_USED;
- Snp->Cdb.StatCode = PXE_STATCODE_INITIALIZE;
- Snp->Cdb.StatFlags = PXE_STATFLAGS_INITIALIZE;
- Snp->Cdb.IFnum = Snp->IfNum;
- Snp->Cdb.Control = PXE_CONTROL_LAST_CDB_IN_LIST;
- if (Reset) {
- Snp->Cdb.OpFlags = PXE_OPFLAGS_STATISTICS_RESET;
- Snp->Cdb.DBsize = PXE_DBSIZE_NOT_USED;
- Snp->Cdb.DBaddr = PXE_DBADDR_NOT_USED;
- Db = Snp->Db;
- } else {
- Snp->Cdb.OpFlags = PXE_OPFLAGS_STATISTICS_READ;
- Snp->Cdb.DBsize = (UINT16)sizeof (PXE_DB_STATISTICS);
- Snp->Cdb.DBaddr = (UINT64)(UINTN)(Db = Snp->Db);
- }
- //
- // Issue UNDI command and check result.
- //
- DEBUG ((DEBUG_NET, "\nsnp->undi.statistics() "));
- (*Snp->IssueUndi32Command)((UINT64)(UINTN)&Snp->Cdb);
- switch (Snp->Cdb.StatCode) {
- case PXE_STATCODE_SUCCESS:
- break;
- case PXE_STATCODE_UNSUPPORTED:
- DEBUG (
- (DEBUG_ERROR,
- "\nsnp->undi.statistics() %xh:%xh\n",
- Snp->Cdb.StatFlags,
- Snp->Cdb.StatCode)
- );
- Status = EFI_UNSUPPORTED;
- goto ON_EXIT;
- default:
- DEBUG (
- (DEBUG_ERROR,
- "\nsnp->undi.statistics() %xh:%xh\n",
- Snp->Cdb.StatFlags,
- Snp->Cdb.StatCode)
- );
- Status = EFI_DEVICE_ERROR;
- goto ON_EXIT;
- }
- if (Reset) {
- Status = EFI_SUCCESS;
- goto ON_EXIT;
- }
- if (StatisticsTable == NULL) {
- *StatisticsSize = sizeof (EFI_NETWORK_STATISTICS);
- Status = EFI_BUFFER_TOO_SMALL;
- goto ON_EXIT;
- }
- //
- // Convert the UNDI statistics information to SNP statistics
- // information.
- //
- ZeroMem (StatisticsTable, *StatisticsSize);
- Stp = (UINT64 *)StatisticsTable;
- Size = 0;
- for (Index = 0, Mask = 1; Index < 64; Index++, Mask = LShiftU64 (Mask, 1), Stp++) {
- //
- // There must be room for a full UINT64. Partial
- // numbers will not be stored.
- //
- if ((Index + 1) * sizeof (UINT64) > *StatisticsSize) {
- break;
- }
- if ((Db->Supported & Mask) != 0) {
- *Stp = Db->Data[Index];
- Size = Index + 1;
- } else {
- SetMem (Stp, sizeof (UINT64), 0xFF);
- }
- }
- //
- // Compute size up to last supported statistic.
- //
- while (++Index < 64) {
- if ((Db->Supported & (Mask = LShiftU64 (Mask, 1))) != 0) {
- Size = Index;
- }
- }
- Size *= sizeof (UINT64);
- if (*StatisticsSize >= Size) {
- *StatisticsSize = Size;
- Status = EFI_SUCCESS;
- } else {
- *StatisticsSize = Size;
- Status = EFI_BUFFER_TOO_SMALL;
- }
- ON_EXIT:
- gBS->RestoreTPL (OldTpl);
- return Status;
- }
|