blob: 05c3a2d4b2c7e8d3fbd7cc309ea05cbf3d3dfa96 [file] [log] [blame]
// Copyright 2025 The Fuchsia Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef SRC_DEVICES_USB_DRIVERS_DWC3_DWC3_METRICS_H_
#define SRC_DEVICES_USB_DRIVERS_DWC3_DWC3_METRICS_H_
#include <lib/inspect/component/cpp/component.h>
#include <zircon/types.h>
#include "src/devices/usb/drivers/dwc3/dwc3-types.h"
namespace dwc3 {
enum class MetricEventType : uint32_t {
kDevtDisconnect = DEVT_DISCONNECT,
kDevtUsbReset = DEVT_USB_RESET,
kDevtConnectionDone = DEVT_CONNECTION_DONE,
kDevtLinkStateChange = DEVT_LINK_STATE_CHANGE,
kDevtRemoteWakeup = DEVT_REMOTE_WAKEUP,
kDevtHibernateRequest = DEVT_HIBERNATE_REQUEST,
kDevtSuspendEntry = DEVT_SUSPEND_ENTRY,
kDevtSof = DEVT_SOF,
kDevtUnknown8 = 8, // Unused event type
kDevtErraticError = DEVT_ERRATIC_ERROR,
kDevtCommandComplete = DEVT_COMMAND_COMPLETE,
kDevtEventBufOverflow = DEVT_EVENT_BUF_OVERFLOW,
kDevtVendorTestLmp = DEVT_VENDOR_TEST_LMP,
kDevtStoppedDisconnect = DEVT_STOPPED_DISCONNECT,
kDevtL1ResumeDetect = DEVT_L1_RESUME_DETECT,
kDevtLdmResponse = DEVT_LDM_RESPONSE,
kDevtUnknown,
kDevtNumEventTypes, // Keeps track of the number of event types
};
class Dwc3Metrics {
public:
void Init();
void IncrementEventCount(uint32_t type) {
type = std::min(type, static_cast<uint32_t>(MetricEventType::kDevtUnknown));
event_counts_[type]++;
}
inspect::Inspector RecordMetrics();
friend struct std::formatter<MetricEventType>;
private:
zx_time_t time_start_;
uint64_t event_counts_[static_cast<uint32_t>(MetricEventType::kDevtNumEventTypes)];
};
} // namespace dwc3
// Needs to be in the root scope.
template <>
struct std::formatter<dwc3::MetricEventType> : std::formatter<std::string> {
auto format(const dwc3::MetricEventType& type, format_context& ctx) const {
std::string fmt;
switch (type) {
case dwc3::MetricEventType::kDevtDisconnect:
fmt = "DEVT_DISCONNECT";
break;
case dwc3::MetricEventType::kDevtUsbReset:
fmt = "DEVT_USB_RESET";
break;
case dwc3::MetricEventType::kDevtConnectionDone:
fmt = "DEVT_CONNECTION_DONE";
break;
case dwc3::MetricEventType::kDevtLinkStateChange:
fmt = "DEVT_LINK_STATE_CHANGE";
break;
case dwc3::MetricEventType::kDevtRemoteWakeup:
fmt = "DEVT_REMOTE_WAKEUP";
break;
case dwc3::MetricEventType::kDevtHibernateRequest:
fmt = "DEVT_HIBERNATE_REQUEST";
break;
case dwc3::MetricEventType::kDevtSuspendEntry:
fmt = "DEVT_SUSPEND_ENTRY";
break;
case dwc3::MetricEventType::kDevtSof:
fmt = "DEVT_SOF";
break;
case dwc3::MetricEventType::kDevtUnknown8:
fmt = "DEVT_UNKNOWN_8";
break;
case dwc3::MetricEventType::kDevtErraticError:
fmt = "DEVT_ERRATIC_ERROR";
break;
case dwc3::MetricEventType::kDevtCommandComplete:
fmt = "DEVT_COMMAND_COMPLETE";
break;
case dwc3::MetricEventType::kDevtEventBufOverflow:
fmt = "DEVT_EVENT_BUF_OVERFLOW";
break;
case dwc3::MetricEventType::kDevtVendorTestLmp:
fmt = "DEVT_VENDOR_TEST_LMP";
break;
case dwc3::MetricEventType::kDevtStoppedDisconnect:
fmt = "DEVT_STOPPED_DISCONNECT";
break;
case dwc3::MetricEventType::kDevtL1ResumeDetect:
fmt = "DEVT_L1_RESUME_DETECT";
break;
case dwc3::MetricEventType::kDevtLdmResponse:
fmt = "DEVT_LDM_RESPONSE";
break;
case dwc3::MetricEventType::kDevtUnknown:
case dwc3::MetricEventType::kDevtNumEventTypes:
fmt = "UNKNOWN";
break;
}
return std::formatter<std::string>::format(fmt, ctx);
}
};
#endif // SRC_DEVICES_USB_DRIVERS_DWC3_DWC3_METRICS_H_