From 4e90dc4512f79a3ef21f460495ecccfd3fc58f7b Mon Sep 17 00:00:00 2001 From: Stefan Kalkowski Date: Tue, 10 Nov 2020 16:40:32 +0100 Subject: [PATCH] dde_linux: adjust fec_nic_drv to use platform_drv Fix #3947 --- .../pkg/drivers_nic-imx53_qsb/archives | 1 + .../pkg/drivers_nic-imx6q_sabrelite/archives | 1 + .../pkg/drivers_nic-imx7d_sabre/archives | 1 + .../pkg/drivers_nic-imx8q_evk/archives | 1 + .../raw/drivers_nic-imx53_qsb/drivers.config | 27 +- .../drivers.config | 28 +- .../drivers_nic-imx7d_sabre/drivers.config | 45 +++- .../raw/drivers_nic-imx8q_evk/drivers.config | 32 ++- repos/dde_linux/src/drivers/nic/fec/dummy.c | 12 - .../dde_linux/src/drivers/nic/fec/lx_emul.cc | 251 +++++++++++------- 10 files changed, 267 insertions(+), 132 deletions(-) diff --git a/repos/dde_linux/recipes/pkg/drivers_nic-imx53_qsb/archives b/repos/dde_linux/recipes/pkg/drivers_nic-imx53_qsb/archives index ed6ea6fda4..d7b0ebe621 100644 --- a/repos/dde_linux/recipes/pkg/drivers_nic-imx53_qsb/archives +++ b/repos/dde_linux/recipes/pkg/drivers_nic-imx53_qsb/archives @@ -1,2 +1,3 @@ +_/src/platform_drv _/src/fec_nic_drv _/raw/drivers_nic-imx53_qsb diff --git a/repos/dde_linux/recipes/pkg/drivers_nic-imx6q_sabrelite/archives b/repos/dde_linux/recipes/pkg/drivers_nic-imx6q_sabrelite/archives index 1f8c275e8a..c35977c8e4 100644 --- a/repos/dde_linux/recipes/pkg/drivers_nic-imx6q_sabrelite/archives +++ b/repos/dde_linux/recipes/pkg/drivers_nic-imx6q_sabrelite/archives @@ -1,2 +1,3 @@ +_/src/platform_drv _/src/fec_nic_drv _/raw/drivers_nic-imx6q_sabrelite diff --git a/repos/dde_linux/recipes/pkg/drivers_nic-imx7d_sabre/archives b/repos/dde_linux/recipes/pkg/drivers_nic-imx7d_sabre/archives index 97bdb9a0c8..6021f84d7a 100644 --- a/repos/dde_linux/recipes/pkg/drivers_nic-imx7d_sabre/archives +++ b/repos/dde_linux/recipes/pkg/drivers_nic-imx7d_sabre/archives @@ -1,2 +1,3 @@ +_/src/platform_drv _/src/fec_nic_drv _/raw/drivers_nic-imx7d_sabre diff --git a/repos/dde_linux/recipes/pkg/drivers_nic-imx8q_evk/archives b/repos/dde_linux/recipes/pkg/drivers_nic-imx8q_evk/archives index 9a568de221..67be4b1a29 100644 --- a/repos/dde_linux/recipes/pkg/drivers_nic-imx8q_evk/archives +++ b/repos/dde_linux/recipes/pkg/drivers_nic-imx8q_evk/archives @@ -1,2 +1,3 @@ +_/src/platform_drv _/src/fec_nic_drv _/raw/drivers_nic-imx8q_evk diff --git a/repos/dde_linux/recipes/raw/drivers_nic-imx53_qsb/drivers.config b/repos/dde_linux/recipes/raw/drivers_nic-imx53_qsb/drivers.config index 2ffdc0c3d9..bbc4698e15 100644 --- a/repos/dde_linux/recipes/raw/drivers_nic-imx53_qsb/drivers.config +++ b/repos/dde_linux/recipes/raw/drivers_nic-imx53_qsb/drivers.config @@ -8,7 +8,6 @@ - @@ -16,11 +15,33 @@ + + + + + + + + + + + + + + + - - + + + + + + + + + diff --git a/repos/dde_linux/recipes/raw/drivers_nic-imx6q_sabrelite/drivers.config b/repos/dde_linux/recipes/raw/drivers_nic-imx6q_sabrelite/drivers.config index 7a9eedd9e6..215047ca0d 100644 --- a/repos/dde_linux/recipes/raw/drivers_nic-imx6q_sabrelite/drivers.config +++ b/repos/dde_linux/recipes/raw/drivers_nic-imx6q_sabrelite/drivers.config @@ -8,7 +8,6 @@ - @@ -16,11 +15,34 @@ + + + + + + + + + + + + + + + + - - + + + + + + + + + diff --git a/repos/dde_linux/recipes/raw/drivers_nic-imx7d_sabre/drivers.config b/repos/dde_linux/recipes/raw/drivers_nic-imx7d_sabre/drivers.config index 4fbbe7e269..637bba5f1c 100644 --- a/repos/dde_linux/recipes/raw/drivers_nic-imx7d_sabre/drivers.config +++ b/repos/dde_linux/recipes/raw/drivers_nic-imx7d_sabre/drivers.config @@ -8,24 +8,51 @@ - - + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - - - - - + + + + + + + + + diff --git a/repos/dde_linux/recipes/raw/drivers_nic-imx8q_evk/drivers.config b/repos/dde_linux/recipes/raw/drivers_nic-imx8q_evk/drivers.config index 11826f1075..279032b785 100644 --- a/repos/dde_linux/recipes/raw/drivers_nic-imx8q_evk/drivers.config +++ b/repos/dde_linux/recipes/raw/drivers_nic-imx8q_evk/drivers.config @@ -8,7 +8,6 @@ - @@ -16,13 +15,36 @@ + + + + + + + + + + + + + + + + + + - - - - + + + + + + + + + diff --git a/repos/dde_linux/src/drivers/nic/fec/dummy.c b/repos/dde_linux/src/drivers/nic/fec/dummy.c index 6284a723d2..e66456b675 100644 --- a/repos/dde_linux/src/drivers/nic/fec/dummy.c +++ b/repos/dde_linux/src/drivers/nic/fec/dummy.c @@ -241,11 +241,6 @@ int of_phy_register_fixed_link(struct device_node *np) return -1; } -bool of_property_read_bool(const struct device_node *np, const char *propname) -{ - TRACE_AND_STOP; -} - void phy_led_triggers_unregister(struct phy_device *phy) { TRACE_AND_STOP; @@ -305,13 +300,6 @@ int regulator_disable(struct regulator *r) return -1; } -int request_threaded_irq(unsigned int irq, irq_handler_t handler, - irq_handler_t thread_fn, - unsigned long flags, const char *name, void *dev) -{ - TRACE_AND_STOP; -} - void sk_free(struct sock *sk) { TRACE_AND_STOP; diff --git a/repos/dde_linux/src/drivers/nic/fec/lx_emul.cc b/repos/dde_linux/src/drivers/nic/fec/lx_emul.cc index 22a286aa79..e3e285829a 100644 --- a/repos/dde_linux/src/drivers/nic/fec/lx_emul.cc +++ b/repos/dde_linux/src/drivers/nic/fec/lx_emul.cc @@ -15,12 +15,14 @@ * Unconditionally include common Genode headers _before_ lx_emul.h to * prevent shenanigans with macro definitions. */ -#include +#include #include #include #include #include -#include +#include +#include +#include #include #include @@ -225,79 +227,116 @@ struct Gpio_irq : public Genode::List::Element }; -struct Fec +static unsigned irq_counter = 32; + +struct Fec : public Genode::List::Element { using String = Genode::String<128>; struct Mdio { - struct Phy + struct Phy : public Genode::List::Element { String name; - String phy_driver; - const unsigned phy_reg; - const unsigned gpio_irq; + String phy_driver { }; + String mdio_bus { }; + unsigned phy_reg { 0 }; + unsigned gpio_irq { 0 }; struct phy_device * phy_dev { nullptr }; - Phy(String name, String driver, const unsigned reg, const unsigned irq) - : name(name), phy_driver(driver), phy_reg(reg), gpio_irq(irq) {} + Phy(String name, Genode::Xml_node xml, Platform::Device_capability) + : name(name) + { + using namespace Genode; + + xml.for_each_sub_node("property", [&] (Xml_node node) { + if (String("compatible") == node.attribute_value("name", String())) { + phy_driver = node.attribute_value("value", String()); } + if (String("mdio_bus") == node.attribute_value("name", String())) { + mdio_bus = node.attribute_value("value", String()); } + if (String("mdio_reg") == node.attribute_value("name", String())) { + phy_reg = node.attribute_value("value", 0U); } + if (String("gpio_irq") == node.attribute_value("name", String())) { + gpio_irq = node.attribute_value("value", 0U); } + }); + } }; - enum { MAX = 10 }; - Genode::Constructible phys[MAX]; + Genode::List phys; template - void for_each(FUNC && f) - { - for (unsigned i = 0; i < MAX; i++) - if (phys[i].constructed()) f(*phys[i]); - } + void for_each(FUNC && f) { + for (Phy * p = phys.first(); p; p = p->next()) { f(*p); } } }; String name; - String device; - const unsigned irq; - const size_t mmio; - String phy_mode; - const bool magic_packet; - const int tx_queues; - const int rx_queues; + String type; + Platform::Device_client device; + const unsigned irq { irq_counter }; + String phy_mode {}; + String phy_name {}; + bool magic_packet { true }; + int tx_queues { 1 }; + int rx_queues { 1 }; struct net_device * net_dev { nullptr }; Session_component * session { nullptr }; - Genode::Attached_io_mem_dataspace io_ds { Lx_kit::env().env(), mmio, 0x4000 }; + Genode::Attached_dataspace io_ds { Lx_kit::env().env().rm(), + device.io_mem_dataspace() }; Genode::Constructible mdio; Mdio::Phy * phy { nullptr }; - Fec(String name, String device, const unsigned irq, - const size_t mmio, String mode, const bool magic = true, - const int tx_queues = 1, const int rx_queues = 1) - : name(name), device(device), irq(irq), mmio(mmio), phy_mode(mode), magic_packet(magic), - tx_queues(tx_queues), rx_queues(rx_queues) {}; + Fec(String name, + Genode::Xml_node xml, + Platform::Device_capability cap) + : name(name), device(cap) + { + using namespace Genode; + + xml.for_each_sub_node("property", [&] (Xml_node node) { + if (String("compatible") == node.attribute_value("name", String())) { + type = node.attribute_value("value", String()); } + if (String("mii") == node.attribute_value("name", String())) { + phy_mode = node.attribute_value("value", String()); } + if (String("phy") == node.attribute_value("name", String())) { + phy_name = node.attribute_value("value", String()); } + if (String("magic_packet") == node.attribute_value("name", String())) { + magic_packet = node.attribute_value("value", true); } + if (String("tx-queues") == node.attribute_value("name", String())) { + tx_queues = node.attribute_value("value", 1UL); } + if (String("rx-queues") == node.attribute_value("name", String())) { + rx_queues = node.attribute_value("value", 1UL); } + }); + + irq_counter += 10; + } }; -static const unsigned FEC_MAX = 2; -static Genode::Constructible fec_devices[FEC_MAX]; +static Genode::List & fec_devices() +{ + static Genode::List list; + return list; +} + net_device * Session_component::_register_session_component(Session_component & s, Genode::Session_label policy) { - Genode::Session_label name = policy.last_element(); + unsigned number = 0; + for (Fec * f = fec_devices().first(); f; f = f->next()) { number++; } - for (unsigned i = 0; i < FEC_MAX; i++) { + for (Fec * f = fec_devices().first(); f; f = f->next()) { + /* If there is more than one device, check session label against card name */ + if (number > 1) { + Genode::Session_label name = policy.last_element(); + if (f->name != name) continue; + } - /* No more cards available */ - if (!fec_devices[i].constructed()) return nullptr; + /* Session already in use? */ + if (f->session) continue; - /* Session does not match cards policy */ - if (fec_devices[i]->name.length() > 1 && - fec_devices[i]->name != name) continue; - - /* Session already in use */ - if (fec_devices[i]->session) return nullptr; - - fec_devices[i]->session = &s; - return fec_devices[i]->net_dev; + f->session = &s; + return f->net_dev; } return nullptr; } @@ -317,68 +356,66 @@ void lx_backtrace() #endif } + +static Platform::Connection & platform_connection() +{ + static Genode::Constructible plat; + if (!plat.constructed()) plat.construct(Lx_kit::env().env()); + return *plat; +} + + int platform_driver_register(struct platform_driver * drv) { + using namespace Genode; using String = Fec::String; - try { - unsigned i = 0; - Genode::Attached_rom_dataspace config { Lx_kit::env().env(), "config" }; - config.xml().for_each_sub_node("card", [&] (Genode::Xml_node const node) { - if (i == FEC_MAX) { - Genode::error("More cards defined than available!"); + platform_connection().with_xml([&] (Xml_node & xml) { + xml.for_each_sub_node("device", [&] (Xml_node node) { + + String name = node.attribute_value("name", String()); + String compatible; + node.for_each_sub_node("property", [&] (Xml_node node) { + if (String("compatible") == node.attribute_value("name", String())) { + compatible = node.attribute_value("value", String()); }}); + + if (compatible == "fsl,imx6q-fec" || + compatible == "fsl,imx6sx-fec" || + compatible == "fsl,imx25-fec") { + Fec * f = new (Lx_kit::env().heap()) + Fec(name, node, platform_connection().acquire_device(name.string())); + + /* order of devices is important, therefore insert it at the end */ + Fec * last = fec_devices().first(); + for (; last; last = last->next()) { + if (!last->next()) { break; } + } + fec_devices().insert(f, last); return; } - String name = node.attribute_value("name", String()); - String type = node.attribute_value("type", String()); - String mdio = node.attribute_value("mii", String()); - String phy = node.attribute_value("phy", String()); - unsigned irq = node.attribute_value("irq", 0UL); - Genode::addr_t mmio = node.attribute_value("mmio", 0UL); - bool magic = node.attribute_value("magic_packet", true); - unsigned txq = node.attribute_value("tx-queues", 1UL); - unsigned rxq = node.attribute_value("rx-queues", 1UL); - fec_devices[i].construct(name, type, irq, mmio, mdio, magic, txq, rxq); - - node.for_each_sub_node("mdio", [&] (Genode::Xml_node const node) { - fec_devices[i]->mdio.construct(); - unsigned j = 0; - node.for_each_sub_node("phy", [&] (Genode::Xml_node const node) { - String name = node.attribute_value("name", String()); - String type = node.attribute_value("type", String()); - unsigned irq = node.attribute_value("gpio_irq", 0UL); - unsigned reg = node.attribute_value("reg_num", 0UL); - fec_devices[i]->mdio->phys[j].construct(name, type, reg, irq); - j++; - }); - }); - - for (unsigned k = 0; k <= i; k++) - if (fec_devices[k]->mdio.constructed()) { - fec_devices[k]->mdio->for_each([&] (Fec::Mdio::Phy & p) { - if (p.name == phy) fec_devices[i]->phy = &p; }); + if (compatible == "ethernet-phy-ieee802.3-c22") { + Fec::Mdio::Phy * p = new (Lx_kit::env().heap()) + Fec::Mdio::Phy(name, node, platform_connection().acquire_device(name.string())); + for (Fec * f = fec_devices().first(); f; f = f->next()) { + if (f->phy_name == name) { f->phy = p; } + if (f->name == p->mdio_bus) { + if (!f->mdio.constructed()) { f->mdio.construct(); } + f->mdio->phys.insert(p); + } } - - i++; + } }); - } catch(...) { } - - if (!fec_devices[0].constructed()) { - Genode::warning("No valid configuration provided, use default values"); - fec_devices[0].construct(String(), "fsl,imx6q-fec", 150, 0x2188000, "rgmii"); - } - - for (unsigned i = 0; i < FEC_MAX; i++) { - if (!fec_devices[i].constructed()) break; + }); + for (Fec * f = fec_devices().first(); f; f = f->next()) { platform_device * pd = new (Lx::Malloc::dma()) platform_device(); - pd->name = fec_devices[i]->name.string(); - pd->dev.of_node = (device_node*) &fec_devices[i]; + pd->name = f->name.string(); + pd->dev.of_node = (device_node*) f; pd->dev.plat_dev = pd; drv->probe(pd); { - net_device * dev = fec_devices[i]->net_dev; + net_device * dev = f->net_dev; int err = dev ? dev->netdev_ops->ndo_open(dev) : -1; if (err) { Genode::error("ndo_open() failed: ", err); @@ -430,7 +467,7 @@ const struct of_device_id *of_match_device(const struct of_device_id *matches, { Fec * fec = (Fec*) dev->plat_dev->dev.of_node; for (; matches && matches->compatible[0]; matches++) - if (Genode::strcmp(matches->compatible, fec->device.string()) == 0) + if (Genode::strcmp(matches->compatible, fec->type.string()) == 0) return matches; return nullptr; @@ -586,9 +623,8 @@ int platform_get_irq(struct platform_device * d, unsigned int i) int devm_request_irq(struct device *dev, unsigned int irq, irq_handler_t handler, unsigned long irqflags, const char *devname, void *dev_id) { - Genode::Irq_connection * irq_con = new (Lx_kit::env().heap()) - Genode::Irq_connection(Lx_kit::env().env(), irq); - Lx::Irq::irq().request_irq(irq_con->cap(), irq, handler, dev_id); + Fec * fec = (Fec*) dev->plat_dev->dev.of_node; + Lx::Irq::irq().request_irq(fec->device.irq(irq - fec->irq), irq, handler, dev_id); return 0; } @@ -984,9 +1020,9 @@ static int of_mdiobus_register_phy(Fec::Mdio::Phy & ph, struct mii_bus *mdio) { struct phy_device * phy = get_phy_device(mdio, ph.phy_reg, false); - if (!phy || IS_ERR(phy)) return 1; + if (!phy) return 1; - phy->irq = ph.gpio_irq; + phy->irq = ph.gpio_irq; phy->mdio.dev.of_node = (device_node*) &ph; /* All data is now stored in the phy struct; @@ -1031,8 +1067,9 @@ int of_driver_match_device(struct device *dev, const struct device_driver *drv) { Fec::Mdio::Phy * phy = (Fec::Mdio::Phy*) dev->of_node; - return phy ? (Genode::strcmp(drv->name, - phy->phy_driver.string()) == 0) : 0; + if (!phy) return 0; + + return (Genode::strcmp(drv->name, "Atheros 8035 ethernet") == 0) ? 1 : 0; } @@ -1077,6 +1114,14 @@ int request_irq(unsigned int irq, irq_handler_t handler, unsigned long flags, co } +int request_threaded_irq(unsigned int irq, irq_handler_t handler, + irq_handler_t thread_fn, + unsigned long flags, const char *name, void *dev) +{ + return request_irq(irq, thread_fn, flags, name, dev); +} + + int enable_irq(unsigned int irq) { for (Gpio_irq *girq = Gpio_irq::list()->first(); girq; girq = girq->next()) @@ -1265,6 +1310,12 @@ bool of_phy_is_fixed_link(struct device_node *np) return 0; } +bool of_property_read_bool(const struct device_node *np, const char *propname) +{ + TRACE; + return false; +} + void phy_led_trigger_change_speed(struct phy_device *phy) { TRACE;