lists.openwall.net   lists  /  announce  owl-users  owl-dev  john-users  john-dev  passwdqc-users  yescrypt  popa3d-users  /  oss-security  kernel-hardening  musl  sabotage  tlsify  passwords  /  crypt-dev  xvendor  /  Bugtraq  Full-Disclosure  linux-kernel  linux-netdev  linux-ext4  linux-hardening  linux-cve-announce  PHC 
Open Source and information security mailing list archives
 
Hash Suite: Windows password security audit tool. GUI, reports in PDF.
[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Date:	Tue, 26 Aug 2014 11:26:32 +0200
From:	PERIER Romain <romain.perier@...il.com>
To:	davem <davem@...emloft.net>
Cc:	Heiko Stübner <heiko@...ech.de>,
	Tobias Klauser <tklauser@...tanz.ch>,
	Beniamino Galvani <b.galvani@...il.com>,
	"eric.dumazet" <eric.dumazet@...il.com>,
	yongjun_wei@...ndmicro.com.cn,
	Florian Fainelli <f.fainelli@...il.com>,
	netdev <netdev@...r.kernel.org>, Arnd Bergmann <arnd@...db.de>
Subject: Re: [PATCH v3 3/3] ethernet: arc: Add support for specific SoC glue
 layer device tree bindings

PS: I will add callback function for set_mac_speed from platform
driver and a priv data inline function (like netdev_priv for arc_emac)
into another seperated commit, I think.

Romain

2014-08-26 11:23 GMT+02:00 Romain Perier <romain.perier@...il.com>:
> Some platforms have special bank registers which might be used to select
> the correct clock or the right mode for Media Indepent Interface controllers.
> Sometimes, it is also required to activate vcc regulators in the right order to supply
> the ethernet controller at the right time. This patch is an architecture refactoring
> of the arc-emac device driver. it adds a new software design which allows to add specific
> platform glue layer. Each platform has now its own module which performs custom initialization
> and remove for the target and then calls to the core driver.
>
> Signed-off-by: Romain Perier <romain.perier@...il.com>
> ---
>  drivers/net/ethernet/arc/Kconfig     |  8 ++-
>  drivers/net/ethernet/arc/Makefile    |  3 +-
>  drivers/net/ethernet/arc/emac.h      |  4 ++
>  drivers/net/ethernet/arc/emac_arc.c  | 95 ++++++++++++++++++++++++++++++++++++
>  drivers/net/ethernet/arc/emac_main.c | 80 +++++++++---------------------
>  5 files changed, 129 insertions(+), 61 deletions(-)
>  create mode 100644 drivers/net/ethernet/arc/emac_arc.c
>
> diff --git a/drivers/net/ethernet/arc/Kconfig b/drivers/net/ethernet/arc/Kconfig
> index 514c57f..e193826 100644
> --- a/drivers/net/ethernet/arc/Kconfig
> +++ b/drivers/net/ethernet/arc/Kconfig
> @@ -17,12 +17,16 @@ config NET_VENDOR_ARC
>
>  if NET_VENDOR_ARC
>
> -config ARC_EMAC
> -       tristate "ARC EMAC support"
> +config ARC_EMAC_CORE
> +       bool
>         select MII
>         select PHYLIB
>         depends on OF_IRQ
>         depends on OF_NET
> +
> +config ARC_EMAC
> +       tristate "ARC EMAC support"
> +       select ARC_EMAC_CORE
>         ---help---
>           On some legacy ARC (Synopsys) FPGA boards such as ARCAngel4/ML50x
>           non-standard on-chip ethernet device ARC EMAC 10/100 is used.
> diff --git a/drivers/net/ethernet/arc/Makefile b/drivers/net/ethernet/arc/Makefile
> index 00c8657..241bb80 100644
> --- a/drivers/net/ethernet/arc/Makefile
> +++ b/drivers/net/ethernet/arc/Makefile
> @@ -3,4 +3,5 @@
>  #
>
>  arc_emac-objs := emac_main.o emac_mdio.o
> -obj-$(CONFIG_ARC_EMAC) += arc_emac.o
> +obj-$(CONFIG_ARC_EMAC_CORE) += arc_emac.o
> +obj-$(CONFIG_ARC_EMAC) += emac_arc.o
> diff --git a/drivers/net/ethernet/arc/emac.h b/drivers/net/ethernet/arc/emac.h
> index 8011445..eb2ba67 100644
> --- a/drivers/net/ethernet/arc/emac.h
> +++ b/drivers/net/ethernet/arc/emac.h
> @@ -124,6 +124,8 @@ struct buffer_state {
>   */
>  struct arc_emac_priv {
>         /* Devices */
> +       const char *drv_name;
> +       const char *drv_version;
>         struct device *dev;
>         struct phy_device *phy_dev;
>         struct mii_bus *bus;
> @@ -206,5 +208,7 @@ static inline void arc_reg_clr(struct arc_emac_priv *priv, int reg, int mask)
>
>  int arc_mdio_probe(struct arc_emac_priv *priv);
>  int arc_mdio_remove(struct arc_emac_priv *priv);
> +int arc_emac_probe(struct net_device *ndev, int interface);
> +int arc_emac_remove(struct net_device *ndev);
>
>  #endif /* ARC_EMAC_H */
> diff --git a/drivers/net/ethernet/arc/emac_arc.c b/drivers/net/ethernet/arc/emac_arc.c
> new file mode 100644
> index 0000000..f9cb99b
> --- /dev/null
> +++ b/drivers/net/ethernet/arc/emac_arc.c
> @@ -0,0 +1,95 @@
> +/**
> + * emac_arc.c - ARC EMAC specific glue layer
> + *
> + * Copyright (C) 2014 Romain Perier
> + *
> + * Romain Perier  <romain.perier@...il.com>
> + *
> + * This program is free software; you can redistribute it and/or modify
> + * it under the terms of the GNU General Public License as published by
> + * the Free Software Foundation; either version 2 of the License, or
> + * (at your option) any later version.
> + *
> + * This program is distributed in the hope that it will be useful,
> + * but WITHOUT ANY WARRANTY; without even the implied warranty of
> + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
> + * GNU General Public License for more details.
> + */
> +
> +#include <linux/etherdevice.h>
> +#include <linux/module.h>
> +#include <linux/of_net.h>
> +#include <linux/platform_device.h>
> +
> +#include "emac.h"
> +
> +#define DRV_NAME    "emac_arc"
> +#define DRV_VERSION "1.0"
> +
> +static int emac_arc_probe(struct platform_device *pdev)
> +{
> +       struct device *dev = &pdev->dev;
> +       struct net_device *ndev;
> +       struct arc_emac_priv *priv;
> +       int interface, err;
> +
> +       if (!dev->of_node)
> +               return -ENODEV;
> +
> +       ndev = alloc_etherdev(sizeof(struct arc_emac_priv));
> +       if (!ndev)
> +               return -ENOMEM;
> +       platform_set_drvdata(pdev, ndev);
> +       SET_NETDEV_DEV(ndev, dev);
> +
> +       priv = netdev_priv(ndev);
> +       priv->drv_name = DRV_NAME;
> +       priv->drv_version = DRV_VERSION;
> +
> +       interface = of_get_phy_mode(dev->of_node);
> +       if (interface < 0)
> +               interface = PHY_INTERFACE_MODE_MII;
> +
> +       priv->clk = devm_clk_get(dev, "hclk");
> +       if (IS_ERR(priv->clk)) {
> +               dev_err(dev, "failed to retrieve host clock from device tree\n");
> +               err = -EINVAL;
> +               goto out_netdev;
> +       }
> +
> +       err = arc_emac_probe(ndev, interface);
> +out_netdev:
> +       if (err)
> +               free_netdev(ndev);
> +       return err;
> +}
> +
> +static int emac_arc_remove(struct platform_device *pdev)
> +{
> +       struct net_device *ndev = platform_get_drvdata(pdev);
> +       int err;
> +
> +       err = arc_emac_remove(ndev);
> +       free_netdev(ndev);
> +       return err;
> +}
> +
> +static const struct of_device_id emac_arc_dt_ids[] = {
> +       { .compatible = "snps,arc-emac" },
> +       { /* Sentinel */ }
> +};
> +
> +static struct platform_driver emac_arc_driver = {
> +       .probe = emac_arc_probe,
> +       .remove = emac_arc_remove,
> +       .driver = {
> +               .name = DRV_NAME,
> +               .of_match_table  = emac_arc_dt_ids,
> +       },
> +};
> +
> +module_platform_driver(emac_arc_driver);
> +
> +MODULE_AUTHOR("Romain Perier <romain.perier@...il.com>");
> +MODULE_DESCRIPTION("ARC EMAC platform driver");
> +MODULE_LICENSE("GPL");
> diff --git a/drivers/net/ethernet/arc/emac_main.c b/drivers/net/ethernet/arc/emac_main.c
> index bbc3157..b35c69e 100644
> --- a/drivers/net/ethernet/arc/emac_main.c
> +++ b/drivers/net/ethernet/arc/emac_main.c
> @@ -26,8 +26,6 @@
>
>  #include "emac.h"
>
> -#define DRV_NAME       "arc_emac"
> -#define DRV_VERSION    "1.0"
>
>  /**
>   * arc_emac_adjust_link - Adjust the PHY link duplex.
> @@ -120,8 +118,10 @@ static int arc_emac_set_settings(struct net_device *ndev,
>  static void arc_emac_get_drvinfo(struct net_device *ndev,
>                                  struct ethtool_drvinfo *info)
>  {
> -       strlcpy(info->driver, DRV_NAME, sizeof(info->driver));
> -       strlcpy(info->version, DRV_VERSION, sizeof(info->version));
> +       struct arc_emac_priv *priv = netdev_priv(ndev);
> +
> +       strlcpy(info->driver, priv->drv_name, sizeof(info->driver));
> +       strlcpy(info->version, priv->drv_version, sizeof(info->version));
>  }
>
>  static const struct ethtool_ops arc_emac_ethtool_ops = {
> @@ -671,19 +671,16 @@ static const struct net_device_ops arc_emac_netdev_ops = {
>  #endif
>  };
>
> -static int arc_emac_probe(struct platform_device *pdev)
> +int arc_emac_probe(struct net_device *ndev, int interface)
>  {
> -       struct device *dev = &pdev->dev;
> +       struct device *dev = ndev->dev.parent;
>         struct resource res_regs;
>         struct device_node *phy_node;
>         struct arc_emac_priv *priv;
> -       struct net_device *ndev;
>         const char *mac_addr;
>         unsigned int id, clock_frequency, irq;
>         int err;
>
> -       if (!dev->of_node)
> -               return -ENODEV;
>
>         /* Get PHY from device tree */
>         phy_node = of_parse_phandle(dev->of_node, "phy", 0);
> @@ -706,12 +703,6 @@ static int arc_emac_probe(struct platform_device *pdev)
>                 return -ENODEV;
>         }
>
> -       ndev = alloc_etherdev(sizeof(struct arc_emac_priv));
> -       if (!ndev)
> -               return -ENOMEM;
> -
> -       dev_set_drvdata(dev, ndev);
> -       SET_NETDEV_DEV(ndev, dev);
>
>         ndev->netdev_ops = &arc_emac_netdev_ops;
>         ndev->ethtool_ops = &arc_emac_ethtool_ops;
> @@ -724,28 +715,25 @@ static int arc_emac_probe(struct platform_device *pdev)
>
>         priv->regs = devm_ioremap_resource(dev, &res_regs);
>         if (IS_ERR(priv->regs)) {
> -               err = PTR_ERR(priv->regs);
> -               goto out_netdev;
> +               return PTR_ERR(priv->regs);
>         }
>         dev_dbg(dev, "Registers base address is 0x%p\n", priv->regs);
>
> -       priv->clk = of_clk_get(dev->of_node, 0);
> -       if (IS_ERR(priv->clk)) {
> -               /* Get CPU clock frequency from device tree */
> -               if (of_property_read_u32(dev->of_node, "clock-frequency",
> -                                       &clock_frequency)) {
> -                       dev_err(dev, "failed to retrieve <clock-frequency> from device tree\n");
> -                       err = -EINVAL;
> -                       goto out_netdev;
> -               }
> -       } else {
> +       if (priv->clk) {
>                 err = clk_prepare_enable(priv->clk);
>                 if (err) {
>                         dev_err(dev, "failed to enable clock\n");
> -                       goto out_clkget;
> +                       return err;
>                 }
>
>                 clock_frequency = clk_get_rate(priv->clk);
> +       } else {
> +               /* Get CPU clock frequency from device tree */
> +               if (of_property_read_u32(dev->of_node, "clock-frequency",
> +                                        &clock_frequency)) {
> +                       dev_err(dev, "failed to retrieve <clock-frequency> from device tree\n");
> +                       return -EINVAL;
> +               }
>         }
>
>         id = arc_reg_get(priv, R_ID);
> @@ -806,7 +794,7 @@ static int arc_emac_probe(struct platform_device *pdev)
>         }
>
>         priv->phy_dev = of_phy_connect(ndev, phy_node, arc_emac_adjust_link, 0,
> -                                      PHY_INTERFACE_MODE_MII);
> +                                      interface);
>         if (!priv->phy_dev) {
>                 dev_err(dev, "of_phy_connect() failed\n");
>                 err = -ENODEV;
> @@ -833,20 +821,15 @@ out_netif_api:
>  out_mdio:
>         arc_mdio_remove(priv);
>  out_clken:
> -       if (!IS_ERR(priv->clk))
> +       if (priv->clk)
>                 clk_disable_unprepare(priv->clk);
> -out_clkget:
> -       if (!IS_ERR(priv->clk))
> -               clk_put(priv->clk);
> -out_netdev:
> -       free_netdev(ndev);
>         return err;
>  }
> +EXPORT_SYMBOL_GPL(arc_emac_probe);
>
> -static int arc_emac_remove(struct platform_device *pdev)
> +int arc_emac_remove(struct net_device *ndev)
>  {
> -       struct device *dev = &pdev->dev;
> -       struct net_device *ndev = dev_get_drvdata(dev);
> +       struct device *dev = ndev->dev.parent;
>         struct arc_emac_priv *priv = netdev_priv(ndev);
>
>         phy_disconnect(priv->phy_dev);
> @@ -857,31 +840,12 @@ static int arc_emac_remove(struct platform_device *pdev)
>
>         if (!IS_ERR(priv->clk)) {
>                 clk_disable_unprepare(priv->clk);
> -               clk_put(priv->clk);
>         }
>
> -       free_netdev(ndev);
>
>         return 0;
>  }
> -
> -static const struct of_device_id arc_emac_dt_ids[] = {
> -       { .compatible = "snps,arc-emac" },
> -       { /* Sentinel */ }
> -};
> -MODULE_DEVICE_TABLE(of, arc_emac_dt_ids);
> -
> -static struct platform_driver arc_emac_driver = {
> -       .probe = arc_emac_probe,
> -       .remove = arc_emac_remove,
> -       .driver = {
> -               .name = DRV_NAME,
> -               .owner = THIS_MODULE,
> -               .of_match_table  = arc_emac_dt_ids,
> -               },
> -};
> -
> -module_platform_driver(arc_emac_driver);
> +EXPORT_SYMBOL_GPL(arc_emac_remove);
>
>  MODULE_AUTHOR("Alexey Brodkin <abrodkin@...opsys.com>");
>  MODULE_DESCRIPTION("ARC EMAC driver");
> --
> 1.9.1
>
--
To unsubscribe from this list: send the line "unsubscribe netdev" in
the body of a message to majordomo@...r.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

Powered by blists - more mailing lists