Feedback on Marvell 6176 DSA switch device tree and driver module code

0

On OpenWRT 5.4.42 kernel on an imx6, I'm seeing a kernel crash when loading builtin modules of igb driver and mv88e6xxx driver over PCI bus for this networking DSA Marvell 6176 switch, HW Block Diagram

and the following device tree:

&pcie {
    pinctrl-names = "default";
    pinctrl-0 = <&pinctrl_pcie>;
    reset-gpio =<&reset_ic 0 1>;
    child-reset-gpios = <&reset_ic 3 1
                    &reset_ic 2 1
                    &reset_ic 1 1>;
    #gpio-cells = <3>;
    status = "okay";
    fsl,max-link-speed = <2>;

    /*
     * PCI bridge: PLX Technology, Inc. PEX 8605 PCI Express4-port Gen2 Switch
     * Port 0 to CPU, Port 1 to igb and ports 2 and 3 are accessible through
     * the half and full size mini PCIe slots on the board.
     */
    pcie@1,0 {
            /* Connection to CPU */
            status = "okay";
            fsl,max-link-speed = <2>;
    };

    pcie@2,1 {
            /* Connection to Intel Gigabit Ethernet Controller*/
            status = "okay";
            fsl,max-link-speed = <1>;
            pcie@3,0 {
                    /* The igb */
                    status = "okay";
                    fsl,max-link-speed = <1>;
                    eth0: igb0 {
                            compatible = "intel,igb";
                            /*pinctrl-names = "default";
                            pinctrl-0 = <&pinctrl_enet>;*/
                            phy-mode = "mii";
                            phy-handle = <&eth0>;
                            phy-reset-gpios = <&reset_ic 4 GPIO_ACTIVE_LOW>;
                            phy-reset-duration = <100>;
                            status = "okay";

                            mdio {
                                    #address-cells = <1>;
                                    #size-cells = <0>;
                                    status = "okay";

                                    switch: switch@0 {
                                            compatible ="marvell,mv88e6085";
                                            reg = <0>;
                                            dsa,member = <0 0>;
                                            eeprom-length = <512>;
                                            interrupt-parent = <&gpio2>;
                                            interrupts =<31IRQ_TYPE_LEVEL_LOW>;
                                            interrupt-controller;
                                            #interrupt-cells = <2>;

                                            ports {
                                                    #address-cells = <1>;
                                                    #size-cells = <0>;

                                                    port@0 {
                                                            reg = <0>;
                                                            label = "port0";
                                                            phy-handle = <&switchphy0>;  
                                                    };

                                                    port@1 {
                                                            reg = <1>;
                                                            label = "port1";
                                                            phy-handle = <&switchphy1>;
                                                    };

                                                    port@2 {
                                                            reg = <2>;
                                                            label = "port0";
                                                            phy-handle = <&switchphy2>;
                                                    };

                                                    port@5 {
                                                            reg = <5>;
                                                            label = "cpu";
                                                            ethernet = <&eth0>;
                                                    };
                                            };

                                            mdio {
                                                    #address-cells = <1>;
                                                    #size-cells = <0>;
                                                    switchphy0:switchphy@0 {
                                                       reg = <0>;
                                                       interrupt-parent = <&switch>;
                                                       interrupts =<0 IRQ_TYPE_LEVEL_HIGH>;
                                                    };

                                                    switchphy1:switchphy@1 {
                                                       reg = <1>;
                                                       interrupt-parent = <&switch>;
                                                       interrupts =<1 IRQ_TYPE_LEVEL_HIGH>;
                                                    };

                                                    switchphy2:switchphy@2 {
                                                        reg = <2>;
                                                        interrupt-parent = <&switch>;
                                                        interrupts =<2 IRQ_TYPE_LEVEL_HIGH>;
                                                    };
                                            };
                                    };
                            };

and kernel driver module code:

/* Create and register mdio bus */
static int igb_enet_mii_init(struct pci_dev *pdev)
{
        struct mii_bus *mii_bus;
        struct net_device *netdev = pci_get_drvdata(pdev);
        struct igb_adapter *adapter = netdev_priv(netdev);
        struct e1000_hw *hw = &adapter->hw;
        struct device_node *np;
        int err;

        mii_bus = mdiobus_alloc();
        if (mii_bus == NULL) {
                err = -ENOMEM;
                goto err_out;
        }

        mii_bus->name = "igb_enet_mii_bus";
        mii_bus->read = igb_enet_mdio_read;
        mii_bus->write = igb_enet_mdio_write;
        mii_bus->reset = igb_enet_mdio_reset;
        snprintf(mii_bus->id, MII_BUS_ID_SIZE, "%s-%x",
                pci_name(pdev), hw->device_id + 1);
        mii_bus->priv = hw;
        mii_bus->parent = &pdev->dev;
        mii_bus->phy_mask = 0xFFFFFFFF;//~(1 << hw->phy.addr);

        /*  Invoke of_mdiobus_register passing a device tree node. The bus is walked and devices instantiated. Do what old binding DSA driver did to detect the Marvell 6176 switch */
        np =  of_find_compatible_node(NULL, NULL, "intel,igb");
        pr_emerg("%s  %s %s\n",np->full_name,np->child->full_name, __func__);
        err = of_mdiobus_register(mii_bus,np->child);
        if (err) {
                printk(KERN_ERR "failed to register mii_bus: %d\n", err);
                goto err_out_free_mdiobus;
        }
        hw->mii_bus = mii_bus;

        return 0;

is causing a kernel crash:

[    2.631594][   T28] CPU: 2 PID: 28 Comm: kworker/u8:1 Not tainted
5.4.42 #0
[    2.631599][   T28] Hardware name: Freescale i.MX6 Quad/DualLite
(Device Tree)
 2.670498][   T32] Workqueue: events_unbound async_run_entry_fn
[    2.676560][   T32] [<80016424>] (unwind_backtrace) from
[<80012a84>] (show_stack+0x10/0x14)
[    2.685057][   T32] [<80012a84>] (show_stack) from [<8053cb30>]
(dump_stack+0x90/0xa4)
[    2.693033][   T32] [<8053cb30>] (dump_stack) from [<800241fc>]
(__warn+0xbc/0xd8)
[    2.700636][   T32] [<800241fc>] (__warn) from [<80024268>]
(warn_slowpath_fmt+0x50/0x94)
[    2.708849][   T32] [<80024268>] (warn_slowpath_fmt) from
[<8004331c>] (__request_module+0xac/0x37c)
[    2.718020][   T32] [<8004331c>] (__request_module) from
[<802eaeac>] (phy_request_driver_module+0x118/0x158)
[    2.727967][   T32] [<802eaeac>] (phy_request_driver_module) from
[<802ec4ac>] (phy_device_create+0x1e4/0x204)
[    2.737997][   T32] [<802ec4ac>] (phy_device_create) from
[<802ec628>] (get_phy_device+0x15c/0x1b0)
[    2.747098][   T32] [<802ec628>] (get_phy_device) from [<803d7ab4>]
(of_mdiobus_register_phy+0x74/0x170)
[    2.756615][   T32] [<803d7ab4>] (of_mdiobus_register_phy) from
[<803d8040>] (of_mdiobus_register+0x120/0x32c)
[    2.766665][   T32] [<803d8040>] (of_mdiobus_register) from
[<802ef248>] (mv88e6xxx_mdio_register+0xdc/0x190)
[    2.776617][   T32] [<802ef248>] (mv88e6xxx_mdio_register) from
[<802f10ac>] (mv88e6xxx_probe+0x618/0x714)
[    2.786305][   T32] [<802f10ac>] (mv88e6xxx_probe) from
[<802edaf8>] (mdio_probe+0x30/0x54)
[    2.794699][   T32] [<802edaf8>] (mdio_probe) from [<8027a034>]
(really_probe+0x1f0/0x364)
[    2.802996][   T32] [<8027a034>] (really_probe) from [<8027a328>]
(driver_probe_device+0x60/0x170)
[    2.811986][   T32] [<8027a328>] (driver_probe_device) from
[<802785c0>] (bus_for_each_drv+0x70/0x94)
[    2.821231][   T32] [<802785c0>] (bus_for_each_drv) from
[<80279dd4>] (__device_attach+0xb4/0x11c)
[    2.830218][   T32] [<80279dd4>] (__device_attach) from
[<802791d8>] (bus_probe_device+0x84/0x8c)
[    2.839117][   T32] [<802791d8>] (bus_probe_device) from
[<802768d0>] (device_add+0x36c/0x614)
[    2.847759][   T32] [<802768d0>] (device_add) from [<802edb9c>]
(mdio_device_register+0x24/0x48)
[    2.856582][   T32] [<802edb9c>] (mdio_device_register) from
[<803d81b4>] (of_mdiobus_register+0x294/0x32c)
[    2.866367][   T32] [<803d81b4>] (of_mdiobus_register) from
[<8032ccc8>] (igb_probe+0x1088/0x13cc)
[    2.875385][   T32] [<8032ccc8>] (igb_probe) from [<8021f010>]
(pci_device_probe+0xd4/0x15c)
[    2.883862][   T32] [<8021f010>] (pci_device_probe) from
[<8027a034>] (really_probe+0x1f0/0x364)
[    2.892676][   T32] [<8027a034>] (really_probe) from [<8027a328>]
(driver_probe_device+0x60/0x170)
[    2.901663][   T32] [<8027a328>] (driver_probe_device) from
[<802785c0>] (bus_for_each_drv+0x70/0x94)
[    2.910910][   T32] [<802785c0>] (bus_for_each_drv) from
[<80279dd4>] (__device_attach+0xb4/0x11c)
[    2.919917][   T32] [<80279dd4>] (__device_attach) from
[<80213bbc>] (pci_bus_add_device+0x44/0x90)
[    2.928995][   T32] [<80213bbc>] (pci_bus_add_device) from
[<80213c34>] (pci_bus_add_devices+0x2c/0x70)
[    2.938420][   T32] [<80213c34>] (pci_bus_add_devices) from
[<80213c68>] (pci_bus_add_devices+0x60/0x70)
[    2.948007][   T32] ---[ end trace c8de08d4ca07a3ea ]---

Please provide feedback on the device tree and driver code with pointers to canonical way to resolve this issue.

linux-kernel
linux-device-driver
embedded-linux
device-tree
asked on Stack Overflow Jun 10, 2020 by user2153522 • edited Jun 15, 2020 by 0andriy

0 Answers

Nobody has answered this question yet.


User contributions licensed under CC BY-SA 3.0