[COMMIT osv master] ena: add upper "thin" layer in form of OSv driver class

2 views
Skip to first unread message

Commit Bot

unread,
Jan 11, 2024, 12:43:19 PMJan 11
to osv...@googlegroups.com, Waldemar Kozaczuk
From: Waldemar Kozaczuk <jwkoz...@gmail.com>
Committer: WALDEMAR KOZACZUK <jwkoz...@gmail.com>
Branch: master

ena: add upper "thin" layer in form of OSv driver class

This almost final patch implements a very upper "thin" layer in form of
the aws::ena driver class that subclasses from hw_driver.

The contructor, destructor and probe() merely delegate to functions
ena_attach(), ena_detach() and ena_probe() respectively implemented
in bsd/sys/dev/ena/ena.cc.

Please note that some of the statistics functionality (see fill_stats())
and if_getinfo are left unimplemented for now.

Signed-off-by: Waldemar Kozaczuk <jwkoz...@gmail.com>

---
diff --git a/Makefile b/Makefile
--- a/Makefile
+++ b/Makefile
@@ -940,6 +940,9 @@ drivers += drivers/xenclock.o
drivers += drivers/xenfront.o drivers/xenfront-xenbus.o drivers/xenfront-blk.o
drivers += drivers/xenplatform-pci.o
endif
+ifeq ($(conf_drivers_ena),1)
+drivers += drivers/ena.o
+endif
endif # x64

ifeq ($(arch),aarch64)
diff --git a/arch/x64/arch-setup.cc b/arch/x64/arch-setup.cc
--- a/arch/x64/arch-setup.cc
+++ b/arch/x64/arch-setup.cc
@@ -310,6 +310,9 @@ void arch_init_premain()
#if CONF_drivers_ide
#include "drivers/ide.hh"
#endif
+#if CONF_drivers_ena
+#include "drivers/ena.hh"
+#endif

extern bool opt_pci_disabled;
void arch_init_drivers()
@@ -364,6 +367,9 @@ void arch_init_drivers()
#endif
#if CONF_drivers_ide
drvman->register_driver(ide::ide_drive::probe);
+#endif
+#if CONF_drivers_ena
+ drvman->register_driver(aws::ena::probe);
#endif
boot_time.event("drivers probe");
drvman->load_all();
diff --git a/conf/profiles/x64/all.mk b/conf/profiles/x64/all.mk
--- a/conf/profiles/x64/all.mk
+++ b/conf/profiles/x64/all.mk
@@ -4,6 +4,6 @@ include conf/profiles/$(arch)/virtio-mmio.mk
include conf/profiles/$(arch)/virtio-pci.mk
include conf/profiles/$(arch)/vmware.mk
include conf/profiles/$(arch)/xen.mk
+include conf/profiles/$(arch)/aws.mk

conf_drivers_vga?=1
-conf_drivers_ena?=1
diff --git a/conf/profiles/x64/aws.mk b/conf/profiles/x64/aws.mk
--- a/conf/profiles/x64/aws.mk
+++ b/conf/profiles/x64/aws.mk
@@ -0,0 +1,7 @@
+conf_drivers_pci?=1
+conf_drivers_acpi?=1
+
+conf_drivers_ena?=1
+
+conf_drivers_pvpanic?=1
+conf_drivers_hpet?=1
diff --git a/conf/profiles/x64/base.mk b/conf/profiles/x64/base.mk
--- a/conf/profiles/x64/base.mk
+++ b/conf/profiles/x64/base.mk
@@ -43,6 +43,11 @@ ifeq ($(conf_drivers_vmxnet3),1)
export conf_drivers_pci?=1
endif

+export conf_drivers_ena?=0
+ifeq ($(conf_drivers_ena),1)
+export conf_drivers_pci?=1
+endif
+
export conf_drivers_ide?=0
ifeq ($(conf_drivers_ide),1)
export conf_drivers_pci?=1
diff --git a/core/debug.cc b/core/debug.cc
--- a/core/debug.cc
+++ b/core/debug.cc
@@ -47,6 +47,7 @@ bool logger::parse_configuration(void)
add_tag("poll", logger_info);
add_tag("dhcp", logger_info);
add_tag("acpi", logger_error);
+ add_tag("ena", logger_debug);

return (true);
}
diff --git a/drivers/ena.cc b/drivers/ena.cc
--- a/drivers/ena.cc
+++ b/drivers/ena.cc
@@ -0,0 +1,105 @@
+/*
+ * Copyright (C) 2023 Waldemar Kozaczuk
+ *
+ * This work is open source software, licensed under the terms of the
+ * BSD license as described in the LICENSE file in the top-level directory.
+ */
+
+#include <sys/cdefs.h>
+
+#include "drivers/ena.hh"
+#include "drivers/pci-device.hh"
+
+#include <osv/aligned_new.hh>
+
+#include <bsd/sys/net/ethernet.h>
+
+extern bool opt_maxnic;
+extern int maxnic;
+
+namespace aws {
+
+#define ena_tag "ena"
+#define ena_d(...) tprintf_d(ena_tag, __VA_ARGS__)
+#define ena_i(...) tprintf_i(ena_tag, __VA_ARGS__)
+#define ena_w(...) tprintf_w(ena_tag, __VA_ARGS__)
+#define ena_e(...) tprintf_e(ena_tag, __VA_ARGS__)
+
+/* TODO - figure out how and if needed to integrate it - ENA code has it own logic to track statistics
+static void if_getinfo(struct ifnet* ifp, struct if_data* out_data)
+{
+ ena* _ena = (ena*)ifp->if_softc;
+
+ // First - take the ifnet data
+ memcpy(out_data, &ifp->if_data, sizeof(*out_data));
+
+ // then fill the internal statistics we've gathered
+ _ena->fill_stats(out_data);
+}*/
+
+void ena::fill_stats(struct if_data* out_data) const
+{
+ assert(!out_data->ifi_oerrors && !out_data->ifi_obytes && !out_data->ifi_opackets);
+ /* TODO - figure out how and if needed to integrate it - ENA code has it own logic to track statistics
+ out_data->ifi_ipackets += _rxq[0].stats.rx_packets;
+ out_data->ifi_ibytes += _rxq[0].stats.rx_bytes;
+ out_data->ifi_iqdrops += _rxq[0].stats.rx_drops;
+ out_data->ifi_ierrors += _rxq[0].stats.rx_csum_err;
+ out_data->ifi_opackets += _txq[0].stats.tx_packets;
+ out_data->ifi_obytes += _txq[0].stats.tx_bytes;
+ out_data->ifi_oerrors += _txq[0].stats.tx_err + _txq[0].stats.tx_drops;
+
+ out_data->ifi_iwakeup_stats = _rxq[0].stats.rx_wakeup_stats;
+ out_data->ifi_owakeup_stats = _txq[0].stats.tx_wakeup_stats;*/
+}
+
+ena::ena(pci::device &dev)
+ : _dev(dev)
+{
+ _adapter = nullptr;
+ auto ret = ena_attach(&_dev, &_adapter);
+ if (ret || !_adapter) {
+ throw std::runtime_error("Failed to attach ena device");
+ }
+
+ //TODO _ifn->if_getinfo = if_getinfo;
+}
+
+ena::~ena()
+{
+ ena_detach(_adapter);
+ _adapter = nullptr;
+}
+
+void ena::dump_config(void)
+{
+ u8 B, D, F;
+ _dev.get_bdf(B, D, F);
+
+ _dev.dump_config();
+ ena_d("%s [%x:%x.%x] vid:id= %x:%x", get_name().c_str(),
+ (u16)B, (u16)D, (u16)F,
+ _dev.get_vendor_id(),
+ _dev.get_device_id());
+}
+
+hw_driver* ena::probe(hw_device* dev)
+{
+ try {
+ if (auto pci_dev = dynamic_cast<pci::device*>(dev)) {
+ pci_dev->dump_config();
+ if (ena_probe(pci_dev)) {
+ if (opt_maxnic && maxnic-- <= 0) {
+ return nullptr;
+ } else {
+ return aligned_new<ena>(*pci_dev);
+ }
+ }
+ }
+ } catch (std::exception& e) {
+ ena_e("Exception on device construction: %s", e.what());
+ }
+ return nullptr;
+}
+
+}
diff --git a/drivers/ena.hh b/drivers/ena.hh
--- a/drivers/ena.hh
+++ b/drivers/ena.hh
@@ -0,0 +1,50 @@
+/*
+ * Copyright (C) 2023 Waldemar Kozaczuk
+ *
+ * This work is open source software, licensed under the terms of the
+ * BSD license as described in the LICENSE file in the top-level directory.
+ */
+
+#ifndef ENA_HH
+#define ENA_HH
+
+#include <bsd/sys/net/if_var.h>
+#include <bsd/sys/net/if.h>
+
+#include "drivers/driver.hh"
+#include "drivers/pci-device.hh"
+
+struct ena_adapter;
+
+bool ena_probe(pci::device *dev);
+int ena_attach(pci::device *dev, ena_adapter **_adapter);
+int ena_detach(ena_adapter *adapter);
+
+namespace aws {
+
+class ena: public hw_driver {
+public:
+ explicit ena(pci::device& dev);
+ virtual ~ena();
+
+ virtual std::string get_name() const { return "ena"; }
+
+ virtual void dump_config(void);
+
+ static hw_driver* probe(hw_device* dev);
+
+ /**
+ * Fill the if_data buffer with data from our iface including those that
+ * we have gathered by ourselvs (e.g. FP queue stats).
+ * @param out_data output buffer
+ */
+ void fill_stats(struct if_data* out_data) const;
+
+private:
+ pci::device& _dev;
+ ena_adapter *_adapter;
+};
+
+}
+
+#endif
Reply all
Reply to author
Forward
0 new messages