| |
| #include "tlbmc/hal/nic_veeprom/interface.h" |
| |
| #include <memory> |
| #include <string> |
| #include <utility> |
| |
| #include "gbmc-hal/api/app/telemetry/gnic_telemetry.h" |
| #include "gbmc-hal/api/app/telemetry/gnic_telemetry_types.h" |
| #include "gbmc-hal/api/system/registries.h" |
| #include "gbmc-hal/api/system/registry_configs.h" |
| #include "absl/log/log.h" |
| #include "absl/status/status.h" |
| #include "absl/status/statusor.h" |
| #include "absl/strings/str_cat.h" |
| #include "absl/strings/string_view.h" |
| #include "tlbmc/hal/nic_veeprom/accessor_base.h" |
| #include "veeprom.pb.h" |
| |
| namespace milotic_tlbmc::nic_veeprom { |
| namespace { |
| |
| class FakeGnicTelemetry : public platforms::gbmc::hal::GnicTelemetry { |
| public: |
| explicit FakeGnicTelemetry(absl::Status reason) |
| : reason_(std::move(reason)) {} |
| absl::StatusOr<platforms::gbmc::hal::GnicVeepromData> ReadAndParse() |
| override { |
| return absl::NotFoundError(absl::StrCat( |
| "VEEPROM data not available. Reason: ", reason_.message())); |
| } |
| |
| private: |
| absl::Status reason_; |
| }; |
| |
| } // namespace |
| |
| std::unique_ptr<Accessor> Accessor::Create(NicTelemetryVersion version, int bus, |
| int address) { |
| return CreateWithDrivers(version, bus, address, "I2cBusI2c", "At24Eeprom"); |
| } |
| |
| // Version is currently ignored as UnifiedAccessor handles all versions |
| // dynamically. |
| std::unique_ptr<Accessor> Accessor::CreateWithDrivers( |
| NicTelemetryVersion version, int bus, int address, |
| absl::string_view i2c_impl, absl::string_view eeprom_impl) { |
| auto fallback_to_fake = [](const absl::Status& status) { |
| LOG(WARNING) << "Falling back to FakeGnicTelemetry because: " << status; |
| auto accessor = std::make_unique<internal::UnifiedAccessor>( |
| std::make_unique<FakeGnicTelemetry>(status)); |
| accessor->DoRefresh(); |
| return accessor; |
| }; |
| |
| absl::StatusOr<std::unique_ptr<platforms::gbmc::hal::I2cBus>> i2c_bus = |
| platforms::gbmc::hal::I2cBusRegistry::Create( |
| i2c_impl, platforms::gbmc::hal::I2cConfig{ |
| .dev_path = absl::StrCat("/dev/i2c-", bus)}); |
| if (!i2c_bus.ok()) { |
| return fallback_to_fake(i2c_bus.status()); |
| } |
| |
| platforms::gbmc::hal::EepromConfig eeprom_config; |
| eeprom_config.i2c_bus = std::move(*i2c_bus); |
| eeprom_config.address = address; |
| eeprom_config.model = "24c32"; // Hardcoded for gnic veeprom. |
| eeprom_config.size = 0; // Fix: Ensure size is 0 so it gets inferred |
| absl::StatusOr<std::unique_ptr<platforms::gbmc::hal::Eeprom>> eeprom = |
| platforms::gbmc::hal::EepromRegistry::Create(eeprom_impl, eeprom_config); |
| if (!eeprom.ok()) { |
| return fallback_to_fake(eeprom.status()); |
| } |
| |
| absl::StatusOr<std::unique_ptr<platforms::gbmc::hal::GnicCodec>> codec = |
| platforms::gbmc::hal::GnicCodecRegistry::Create("GnicTelemetryCodec", {}); |
| if (!codec.ok()) { |
| return fallback_to_fake(codec.status()); |
| } |
| |
| platforms::gbmc::hal::GnicTelemetryConfig config; |
| config.eeprom = (*eeprom).get(); |
| config.codec = (*codec).get(); |
| |
| absl::StatusOr<std::unique_ptr<platforms::gbmc::hal::GnicTelemetry>> |
| gnic_telemetry = platforms::gbmc::hal::GnicTelemetryRegistry::Create( |
| "GnicTelemetry", config); |
| if (!gnic_telemetry.ok()) { |
| return fallback_to_fake(gnic_telemetry.status()); |
| } |
| |
| return std::make_unique<internal::UnifiedAccessor>( |
| std::move(*eeprom), std::move(*codec), std::move(*gnic_telemetry)); |
| } |
| |
| } // namespace milotic_tlbmc::nic_veeprom |