Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 7 additions & 2 deletions fboss/platform/platform_manager/ConfigValidator.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,8 @@ constexpr auto kSymlinkDirs = {
"gpiochips",
"xcvrs",
"flashes",
"watchdogs"};
"watchdogs",
"mdio-busses"};
// Supported modalias - spidev +
// https://github.com/torvalds/linux/blob/master/drivers/spi/spidev.c#L702
constexpr auto kSpiDevModaliases = {
Expand Down Expand Up @@ -287,6 +288,9 @@ bool ConfigValidator::isValidPciDeviceConfig(
for (const auto& config : *pciDeviceConfig.miscCtrlConfigs()) {
fpgaIpBlockConfigs.push_back(config);
}
for (const auto& config : *pciDeviceConfig.mdioBusConfigs()) {
fpgaIpBlockConfigs.push_back(config);
}

std::set<std::string> uniqueNames{};
for (const auto& config : fpgaIpBlockConfigs) {
Expand Down Expand Up @@ -455,7 +459,8 @@ bool ConfigValidator::isValidDeviceName(
*pciDeviceConfig.gpioChipConfigs(),
*pciDeviceConfig.watchdogConfigs(),
*pciDeviceConfig.infoRomConfigs(),
*pciDeviceConfig.miscCtrlConfigs())) {
*pciDeviceConfig.miscCtrlConfigs(),
*pciDeviceConfig.mdioBusConfigs())) {
return true;
}
}
Expand Down
3 changes: 3 additions & 0 deletions fboss/platform/platform_manager/ExplorationSummary.h
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ enum class ExplorationErrorType {
PCI_SUB_DEVICE_CREATE_XCVR_CTRL,
PCI_SUB_DEVICE_CREATE_INFO_ROM,
PCI_SUB_DEVICE_CREATE_MISC_CTRL,
PCI_SUB_DEVICE_CREATE_MDIO_BUS,
IDPROM_READ,
SLOT_PM_UNIT_ABSENCE,
SLOT_PRESENCE_CHECK,
Expand Down Expand Up @@ -73,6 +74,8 @@ constexpr const char* toExplorationErrorTypeStr(
return "pci_sub_device_create_info_rom";
case ExplorationErrorType::PCI_SUB_DEVICE_CREATE_MISC_CTRL:
return "pci_sub_device_create_misc_ctrl";
case ExplorationErrorType::PCI_SUB_DEVICE_CREATE_MDIO_BUS:
return "pci_sub_device_create_mdio_bus";
case ExplorationErrorType::IDPROM_READ:
return "idprom_read";
case ExplorationErrorType::SLOT_PM_UNIT_ABSENCE:
Expand Down
28 changes: 28 additions & 0 deletions fboss/platform/platform_manager/PciExplorer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -289,6 +289,15 @@ std::string PciExplorer::createFanPwmCtrl(
pciDevice, *fanPwmCtrlConfig.fpgaIpBlockConfig(), instanceId);
}

std::string PciExplorer::createMdioBus(
const PciDevice& pciDevice,
const FpgaIpBlockConfig& mdioBusConfig,
uint32_t instanceId) {
auto auxData = getAuxData(mdioBusConfig, instanceId);
create(pciDevice, mdioBusConfig, auxData);
return getMdioBusSysfsPath(pciDevice, mdioBusConfig, instanceId);
}

void PciExplorer::createFpgaIpBlock(
const PciDevice& pciDevice,
const FpgaIpBlockConfig& fpgaIpBlockConfig,
Expand Down Expand Up @@ -690,6 +699,25 @@ std::string PciExplorer::getXcvrCtrlSysfsPath(
*fpgaIpBlockConfig.pmUnitScopedName());
}

std::string PciExplorer::getMdioBusSysfsPath(
const PciDevice& pciDevice,
const FpgaIpBlockConfig& fpgaIpBlockConfig,
uint32_t instanceId) {
std::string expectedEnding =
fmt::format(".{}.{}", *fpgaIpBlockConfig.deviceName(), instanceId);
for (const auto& dirEntry : fs::directory_iterator(pciDevice.sysfsPath())) {
if (dirEntry.path().string().ends_with(expectedEnding)) {
return Utils().resolveMdioBusCharDevPath(*fpgaIpBlockConfig.deviceName(), instanceId);
}
}
throw PciSubDeviceRuntimeError(
fmt::format(
"Couldn't find MdioBus {} under {}",
*fpgaIpBlockConfig.deviceName(),
pciDevice.sysfsPath()),
*fpgaIpBlockConfig.pmUnitScopedName());
}

bool PciExplorer::isPciSubDeviceReady(
const PciDevice& pciDevice,
const FpgaIpBlockConfig& fpgaIpBlockConfig,
Expand Down
11 changes: 11 additions & 0 deletions fboss/platform/platform_manager/PciExplorer.h
Original file line number Diff line number Diff line change
Expand Up @@ -121,6 +121,13 @@ class PciExplorer {
const FanPwmCtrlConfig& fanPwmCtrlConfig,
uint32_t instanceId);

// Create the mdio_bus based on the given FpgaIpBlockConfig residing
// at the given PciDevice path. Throw std::runtime_error on failure.
std::string createMdioBus(
const PciDevice& pciDevice,
const FpgaIpBlockConfig& mdioBusConfig,
uint32_t instanceId);

// Create the generic device block based on the given FpgaIpBlockConfig
// residing at the given PciDevice. Throw std::runtime_error on failure.
void createFpgaIpBlock(
Expand Down Expand Up @@ -169,6 +176,10 @@ class PciExplorer {
const PciDevice& pciDevice,
const FpgaIpBlockConfig& fpgaIpBlockConfig,
uint32_t instanceId);
std::string getMdioBusSysfsPath(
const PciDevice& pciDevice,
const FpgaIpBlockConfig& fpgaIpBlockConfig,
uint32_t instanceId);
bool isPciSubDeviceReady(
const PciDevice& pciDevice,
const FpgaIpBlockConfig& fpgaIpBlockConfig,
Expand Down
15 changes: 14 additions & 1 deletion fboss/platform/platform_manager/PlatformExplorer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -645,6 +645,18 @@ void PlatformExplorer::explorePciDevices(
[&](const auto& miscCtrlConfig) {
pciExplorer_.createFpgaIpBlock(pciDevice, miscCtrlConfig, instId++);
});
createPciSubDevices(
slotPath,
*pciDeviceConfig.mdioBusConfigs(),
ExplorationErrorType::PCI_SUB_DEVICE_CREATE_MDIO_BUS,
[&](const auto& mdioBusConfig) {
auto mdioBusSysfsPath =
pciExplorer_.createMdioBus(pciDevice, mdioBusConfig, instId++);
dataStore_.updateCharDevPath(
Utils().createDevicePath(
slotPath, *mdioBusConfig.pmUnitScopedName()),
mdioBusSysfsPath);
});
}
}

Expand Down Expand Up @@ -691,7 +703,8 @@ void PlatformExplorer::createDeviceSymLink(
} else if (
linkParentPath.string() == "/run/devmap/gpiochips" ||
linkParentPath.string() == "/run/devmap/flashes" ||
linkParentPath.string() == "/run/devmap/watchdogs") {
linkParentPath.string() == "/run/devmap/watchdogs" ||
linkParentPath.string() == "/run/devmap/mdio-busses") {
targetPath = devicePathResolver_.resolvePciSubDevCharDevPath(devicePath);
} else if (linkParentPath.string() == "/run/devmap/xcvrs") {
auto xcvrName = linkPath.substr(linkParentPath.string().length() + 1);
Expand Down
15 changes: 15 additions & 0 deletions fboss/platform/platform_manager/Utils.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -114,6 +114,21 @@ std::string Utils::resolveWatchdogCharDevPath(const std::string& sysfsPath) {
return charDevPath;
}

std::string Utils::resolveMdioBusCharDevPath(
std::string deviceName,
uint32_t instanceId) {
auto failMsg = "Failed to resolve mdio_bus CharDevPath";
auto charDevPath = fmt::format("/dev/ioc_{}.{}", deviceName, instanceId);
if (!fs::exists(charDevPath)) {
throw std::runtime_error(
fmt::format(
"{}. Reason: {} does not exist in the system",
failMsg,
charDevPath));
}
return charDevPath;
}

bool Utils::checkDeviceReadiness(
std::function<bool()>&& isDeviceReadyFunc,
const std::string& onWaitMsg,
Expand Down
6 changes: 6 additions & 0 deletions fboss/platform/platform_manager/Utils.h
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,12 @@ class Utils {
// Throws an exception when it fails to resolve CharDevicePath
std::string resolveWatchdogCharDevPath(const std::string& sysfsPath);

// Explore and resolve MdioBus's CharDevicePath for given SysfsPath.
// Throws an exception when it fails to resolve CharDevicePath
std::string resolveMdioBusCharDevPath(
std::string deviceName,
uint32_t instanceId);

bool checkDeviceReadiness(
std::function<bool()>&& isDeviceReadyFunc,
const std::string& onWaitMsg,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -403,7 +403,8 @@ struct PciDeviceConfig {
12: list<XcvrCtrlConfig> xcvrCtrlConfigs;
13: list<FpgaIpBlockConfig> infoRomConfigs;
14: list<FpgaIpBlockConfig> miscCtrlConfigs;
15: optional string desiredDriver;
15: list<FpgaIpBlockConfig> mdioBusConfigs;
16: optional string desiredDriver;
}

// These are the PmUnit slot types. Examples: "PIM_SLOT", "PSU_SLOT" and
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -328,6 +328,7 @@ TEST(ConfigValidatorTest, Symlink) {
EXPECT_TRUE(ConfigValidator().isValidSymlink("/run/devmap/eeproms/EEPROM"));
EXPECT_TRUE(ConfigValidator().isValidSymlink("/run/devmap/sensors/sensor1"));
EXPECT_TRUE(ConfigValidator().isValidSymlink("/run/devmap/i2c-busses/bus"));
EXPECT_TRUE(ConfigValidator().isValidSymlink("/run/devmap/mdio-busses/bus"));
}

TEST(ConfigValidatorTest, DevicePath) {
Expand Down