fsm/src/fsmd.cpp
DataHoarder 704df5b09d
All checks were successful
continuous-integration/drone/pr Build is passing
continuous-integration/drone/push Build is passing
Implement data-driven YAML switch/port/vlan configuration
Implemented extra missing fields, added VPD hash match

Add extra configuration required for external port tagging, maybe do it via config
2021-11-13 00:18:13 +01:00

125 lines
4 KiB
C++

#include <iostream>
#include <memory>
#include <sstream>
#include <iomanip>
#include <csignal>
#include <unistd.h>
#include <thread>
#include <fstream>
#include "device/PCIEDevice.h"
#include "fm10k/FM10K.h"
#include "fm10k/registers/Register.h"
#include "fm10k/IES.h"
#include "argparse/argparse.hpp"
#include "ryml.hpp"
#include "c4/std/string.hpp"
template <typename T> std::string tohex(T v){
std::stringstream o;
o << std::hex << std::setw(sizeof(v) * 2) << std::setfill('0') << v;
return o.str();
}
static bool stopLoop = false;
static void int_handler(int sig){
stopLoop = true;
std::cout << "STOPPING DUE TO SIGNAL " << sig << std::endl;
}
int main(int argc, char *argv[]) {
argparse::ArgumentParser program("fsmd", "0.1.0");
program.add_argument("-c", "--config").help("Path to YAML switch configuration.").default_value<std::string>("config.yml");
program.add_argument("-v", "--verbose").help("Enable verbose mode").default_value<bool>(false).implicit_value(true);
try{
program.parse_args(argc, argv);
}catch(const std::runtime_error& err){
std::cerr << err.what() << std::endl;
std::cerr << program;
std::exit(1);
}
ryml::Tree config;
try{
std::ifstream f;
std::stringstream buffer;
f.open(program.get("--config"));
buffer << f.rdbuf();
config = ryml::parse(ryml::to_csubstr(buffer.str()));
}catch(const std::runtime_error& err){
std::cerr << err.what() << std::endl;
std::cerr << program;
std::exit(1);
}
if(config.empty()){
std::cerr << "Empty config file" << std::endl;
std::cerr << program;
std::exit(1);
}
auto entries = PCIEDevice::DeviceEntry::find();
std::cout << "Found " << entries.size() << " FM10K management device(s)." << std::endl;
for(auto& entry : entries){
auto dev = std::make_unique<PCIEDevice>(entry);
std::cout << "dev.path: " << dev->getDeviceEntry().getPath() << std::endl;
std::cout << "dev.vendor: " << tohex(dev->getDeviceEntry().getVendor()) << std::endl;
std::cout << "dev.class: " << tohex(dev->getDeviceEntry().getClass()) << std::endl;
auto vpdHash = dev->getDeviceEntry().getVPDHash();
std::cout << "dev.vpd_hash: " << vpdHash << std::endl;
FM10K::FM10K fm10k(std::move(dev));
std::cout << "Device Model_Stepping: " << fm10k.getHardwareInformationString() << std::endl;
auto p = config.rootref()["platform"];
if(p.is_map()){ //Match value
if(!p["device"].is_seed() && p["device"].val() != fm10k.getHardwareInformationString()){
continue;
}
if(!p["device_vpd_hash"].is_seed() && p["device_vpd_hash"].val() != vpdHash){
continue;
}
}
auto fuseData_0 = fm10k.mapRegister<FM10K::registers::MGMT::FUSE_DATA_0>();
std::cout << "FUSE_DATA_0: " << tohex(fuseData_0->value) << std::endl;
std::cout << "FUSE_DATA_0.VDDF_VRM: " << FM10K::VR12_VID_to_Millivolts(fuseData_0->fields.VDDS_VRM) << std::endl;
std::cout << "FUSE_DATA_0.VDDF_VRM: " << FM10K::VR12_VID_to_Millivolts(fuseData_0->fields.VDDF_VRM) << std::endl;
auto deviceCfg = fm10k.mapRegister<FM10K::registers::MGMT::DEVICE_CFG>();
std::cout << "DEVICE_CFG: " << tohex(deviceCfg->value) << std::endl;
std::cout << "trying to initialize: " << std::endl;
auto& port = fm10k.addPort(1, 1);
port.m_portType = Port::PortType::EPL;
port.m_interfaceType = Port::InterfaceType::QSFP_LANE0;
if(fm10k.initialize(config)){
std::cout << "success" << std::endl;
signal(SIGINT, int_handler);
signal(SIGTERM, int_handler);
do{
std::this_thread::yield();
//TODO: check work
FM10K::FM10K::wait(1000);
} while (!stopLoop);
break;
}else{
std::cout << "fail" << std::endl;
}
}
FM10K::IES::getInstance().teardown();
return 0;
}