From: Krzysztof Kozlowski <krzysztof.kozlowski@linaro.org>
To: Camel Guo <camel.guo@axis.com>, Andrew Lunn <andrew@lunn.ch>,
"David S. Miller" <davem@davemloft.net>,
Eric Dumazet <edumazet@google.com>,
Florian Fainelli <f.fainelli@gmail.com>,
Jakub Kicinski <kuba@kernel.org>,
Krzysztof Kozlowski <krzysztof.kozlowski+dt@linaro.org>,
Paolo Abeni <pabeni@redhat.com>, Rob Herring <robh+dt@kernel.org>,
Russell King <linux@armlinux.org.uk>,
Vivien Didelot <vivien.didelot@gmail.com>,
Vladimir Oltean <olteanv@gmail.com>
Cc: devicetree@vger.kernel.org, linux-kernel@vger.kernel.org,
netdev@vger.kernel.org, Rob Herring <robh@kernel.org>,
kernel@axis.com
Subject: Re: [RFC net-next 2/2] net: dsa: Add driver for Maxlinear GSW1XX switch
Date: Tue, 25 Oct 2022 10:23:55 -0400 [thread overview]
Message-ID: <d942c724-4520-4a7b-8c36-704032c68a36@linaro.org> (raw)
In-Reply-To: <20221025135243.4038706-3-camel.guo@axis.com>
On 25/10/2022 09:52, Camel Guo wrote:
> Add initial framework for Maxlinear's GSW1xx switch and
> currently only GSW145 in MDIO managed mode is supported.
>
> Signed-off-by: Camel Guo <camel.guo@axis.com>
> ---
(...)
> + priv->ds->dev = dev;
> + priv->ds->num_ports = priv->hw_info->max_ports;
> + priv->ds->priv = priv;
> + priv->ds->ops = &gsw1xx_switch_ops;
> + priv->dev = dev;
> + version = gsw1xx_switch_r(priv, GSW1XX_IP_VERSION);
> +
> + np = dev->of_node;
> + switch (version) {
> + case GSW1XX_IP_VERSION_2_3:
> + if (!of_device_is_compatible(np, "mxl,gsw145-mdio"))
> + return -EINVAL;
> + break;
> + default:
> + dev_err(dev, "unknown GSW1XX_IP version: 0x%x", version);
> + return -ENOENT;
> + }
> +
> + /* bring up the mdio bus */
> + mdio_np = of_get_child_by_name(np, "mdio");
> + if (!mdio_np) {
> + dev_err(dev, "missing child mdio node\n");
> + return -EINVAL;
> + }
> +
> + err = gsw1xx_mdio(priv, mdio_np);
> + if (err) {
> + dev_err(dev, "mdio probe failed\n");
dev_err_probe()
> + goto put_mdio_node;
> + }
> +
> + err = dsa_register_switch(priv->ds);
> + if (err) {
> + dev_err(dev, "dsa switch register failed: %i\n", err);
dev_err_probe()
> + goto mdio_bus;
> + }
> + if (!dsa_is_cpu_port(priv->ds, priv->hw_info->cpu_port)) {
> + dev_err(dev,
> + "wrong CPU port defined, HW only supports port: %i",
> + priv->hw_info->cpu_port);
> + err = -EINVAL;
> + goto disable_switch;
> + }
> +
> + dev_set_drvdata(dev, priv);
> +
> + return 0;
> +
> +disable_switch:
> + gsw1xx_mdio_mask(priv, GSW1XX_MDIO_GLOB_ENABLE, 0, GSW1XX_MDIO_GLOB);
> + dsa_unregister_switch(priv->ds);
> +mdio_bus:
> + if (mdio_np) {
> + mdiobus_unregister(priv->ds->slave_mii_bus);
> + mdiobus_free(priv->ds->slave_mii_bus);
> + }
> +put_mdio_node:
> + of_node_put(mdio_np);
> + return err;
> +}
> +EXPORT_SYMBOL(gsw1xx_probe);
> +
> +void gsw1xx_remove(struct gsw1xx_priv *priv)
> +{
> + if (!priv)
> + return;
> +
> + /* disable the switch */
> + gsw1xx_mdio_mask(priv, GSW1XX_MDIO_GLOB_ENABLE, 0, GSW1XX_MDIO_GLOB);
> +
> + dsa_unregister_switch(priv->ds);
> +
> + if (priv->ds->slave_mii_bus) {
> + mdiobus_unregister(priv->ds->slave_mii_bus);
> + of_node_put(priv->ds->slave_mii_bus->dev.of_node);
> + mdiobus_free(priv->ds->slave_mii_bus);
> + }
> +
> + dev_set_drvdata(priv->dev, NULL);
> +}
> +EXPORT_SYMBOL(gsw1xx_remove);
> +
> +void gsw1xx_shutdown(struct gsw1xx_priv *priv)
> +{
> + if (!priv)
> + return;
> +
> + /* disable the switch */
> + gsw1xx_mdio_mask(priv, GSW1XX_MDIO_GLOB_ENABLE, 0, GSW1XX_MDIO_GLOB);
> +
> + dsa_switch_shutdown(priv->ds);
> +
> + dev_set_drvdata(priv->dev, NULL);
> +}
> +EXPORT_SYMBOL(gsw1xx_shutdown);
1. EXPORT_SYMBOL_GPL
2. Why do you do it in the first place? It's one driver, no need for
building two modules. Same applies to other places.
> +
> +static const struct regmap_range gsw1xx_valid_regs[] = {
> + /* GSWIP Core Registers */
> + regmap_reg_range(GSW1XX_IP_BASE_ADDR,
> + GSW1XX_IP_BASE_ADDR + GSW1XX_IP_REG_LEN),
> + /* Top Level PDI Registers, MDIO Master Reigsters */
> + regmap_reg_range(GSW1XX_MDIO_BASE_ADDR,
> + GSW1XX_MDIO_BASE_ADDR + GSW1XX_MDIO_REG_LEN),
> +};
> +
> +const struct regmap_access_table gsw1xx_register_set = {
> + .yes_ranges = gsw1xx_valid_regs,
> + .n_yes_ranges = ARRAY_SIZE(gsw1xx_valid_regs),
> +};
> +EXPORT_SYMBOL(gsw1xx_register_set);
> +
> +MODULE_AUTHOR("Camel Guo <camel.guo@axis.com>");
> +MODULE_DESCRIPTION("Core Driver for MaxLinear GSM1XX ethernet switch");
> +MODULE_LICENSE("GPL");
> diff --git a/drivers/net/dsa/gsw1xx_mdio.c b/drivers/net/dsa/gsw1xx_mdio.c
> new file mode 100644
> index 000000000000..8328001041ed
> --- /dev/null
> +++ b/drivers/net/dsa/gsw1xx_mdio.c
> @@ -0,0 +1,128 @@
> +// SPDX-License-Identifier: GPL-2.0
> +/*
> + * MaxLinear switch driver for GSW1XX in MDIO managed mode
> + */
> +#include <linux/kernel.h>
> +#include <linux/module.h>
> +#include <linux/mdio.h>
> +#include <linux/phy.h>
> +#include <linux/of.h>
> +
> +#include "gsw1xx.h"
> +
> +#define GSW1XX_SMDIO_TARGET_BASE_ADDR_REG 0x1F
> +
> +static int gsw1xx_mdio_write(void *ctx, uint32_t reg, uint32_t val)
> +{
> + struct mdio_device *mdiodev = (struct mdio_device *)ctx;
> + int ret = 0;
> +
> + mutex_lock_nested(&mdiodev->bus->mdio_lock, MDIO_MUTEX_NESTED);
> +
> + ret = mdiodev->bus->write(mdiodev->bus, mdiodev->addr,
> + GSW1XX_SMDIO_TARGET_BASE_ADDR_REG, reg);
> + if (ret < 0)
> + goto out;
> +
> + ret = mdiodev->bus->write(mdiodev->bus, mdiodev->addr, 0, val);
> +
> +out:
> + mutex_unlock(&mdiodev->bus->mdio_lock);
> +
> + return ret;
> +}
> +
> +static int gsw1xx_mdio_read(void *ctx, uint32_t reg, uint32_t *val)
> +{
> + struct mdio_device *mdiodev = (struct mdio_device *)ctx;
> + int ret = 0;
> +
> + mutex_lock_nested(&mdiodev->bus->mdio_lock, MDIO_MUTEX_NESTED);
> +
> + ret = mdiodev->bus->write(mdiodev->bus, mdiodev->addr,
> + GSW1XX_SMDIO_TARGET_BASE_ADDR_REG, reg);
> + if (ret < 0)
> + goto out;
> +
> + *val = mdiodev->bus->read(mdiodev->bus, mdiodev->addr, 0);
> +
> +out:
> + mutex_unlock(&mdiodev->bus->mdio_lock);
> +
> + return ret;
> +}
> +
> +static const struct regmap_config gsw1xx_mdio_regmap_config = {
> + .reg_bits = 16,
> + .val_bits = 16,
> + .reg_stride = 1,
> +
> + .disable_locking = true,
> +
> + .volatile_table = &gsw1xx_register_set,
> + .wr_table = &gsw1xx_register_set,
> + .rd_table = &gsw1xx_register_set,
> +
> + .reg_read = gsw1xx_mdio_read,
> + .reg_write = gsw1xx_mdio_write,
> +
> + .cache_type = REGCACHE_NONE,
> +};
> +
> +static int gsw1xx_mdio_probe(struct mdio_device *mdiodev)
> +{
> + struct gsw1xx_priv *priv;
> + struct device *dev = &mdiodev->dev;
> + int ret;
> +
> + priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL);
> + if (!priv)
> + return -ENOMEM;
> +
> + priv->regmap = devm_regmap_init(dev, NULL, mdiodev,
> + &gsw1xx_mdio_regmap_config);
> + if (IS_ERR(priv->regmap)) {
> + ret = PTR_ERR(priv->regmap);
> + dev_err(dev, "regmap init failed: %d\n", ret);
> + return ret;
return dev_err_probe().
> + }
> +
> + return gsw1xx_probe(priv, dev);
> +}
> +
> +static void gsw1xx_mdio_remove(struct mdio_device *mdiodev)
> +{
> + gsw1xx_remove(dev_get_drvdata(&mdiodev->dev));
> +}
> +
> +static void gsw1xx_mdio_shutdown(struct mdio_device *mdiodev)
> +{
> + gsw1xx_shutdown(dev_get_drvdata(&mdiodev->dev));
> +}
> +
> +static const struct gsw1xx_hw_info gsw145_hw_info = {
> + .max_ports = 6,
> + .cpu_port = 5,
> +};
> +
> +static const struct of_device_id gsw1xx_mdio_of_match[] = {
> + { .compatible = "mxl,gsw145-mdio", .data = &gsw145_hw_info },
> + { /* sentinel */ },
> +};
> +MODULE_DEVICE_TABLE(of, gsw1xx_mdio_of_match);
> +
> +static struct mdio_driver gsw1xx_mdio_driver = {
> + .probe = gsw1xx_mdio_probe,
> + .remove = gsw1xx_mdio_remove,
> + .shutdown = gsw1xx_mdio_shutdown,
> + .mdiodrv.driver = {
> + .name = "GSW1XX_MDIO",
> + .of_match_table = of_match_ptr(gsw1xx_mdio_of_match),
of_match_ptr requires maybe_unused. Or just drop it.
Best regards,
Krzysztof
next prev parent reply other threads:[~2022-10-25 14:24 UTC|newest]
Thread overview: 21+ messages / expand[flat|nested] mbox.gz Atom feed top
2022-10-25 13:52 [RFC net-next 0/2] DSA driver draft for MaxLinear's gsw1xx series switch Camel Guo
2022-10-25 13:52 ` [RFC net-next 1/2] dt-bindings: net: dsa: add bindings for GSW Series switches Camel Guo
2022-10-25 14:27 ` Krzysztof Kozlowski
2022-10-25 15:01 ` Andrew Lunn
2022-10-25 19:00 ` Krzysztof Kozlowski
[not found] ` <d0179725-0730-5826-caa4-228469d3bad4@axis.com>
2022-10-27 12:46 ` Krzysztof Kozlowski
2022-10-27 13:57 ` Vladimir Oltean
2022-10-27 16:08 ` Krzysztof Kozlowski
2022-10-27 16:12 ` Vladimir Oltean
2022-10-25 20:05 ` Rob Herring
2022-10-27 15:41 ` Vladimir Oltean
2022-10-25 13:52 ` [RFC net-next 2/2] net: dsa: Add driver for Maxlinear GSW1XX switch Camel Guo
2022-10-25 14:23 ` Krzysztof Kozlowski [this message]
2022-10-25 14:56 ` Andrew Lunn
2022-10-27 6:35 ` Camel Guo
2022-10-27 12:09 ` Andrew Lunn
[not found] ` <55da4718-4422-745a-8880-95adc8e0abd9@axis.com>
2022-10-27 12:48 ` Krzysztof Kozlowski
2022-10-25 14:53 ` Andrew Lunn
[not found] ` <a04fc8bd-e18e-c300-8300-7cba8fe33557@axis.com>
2022-10-27 12:20 ` Andrew Lunn
2022-10-27 16:00 ` Vladimir Oltean
2022-10-28 4:41 ` Arun.Ramadoss
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=d942c724-4520-4a7b-8c36-704032c68a36@linaro.org \
--to=krzysztof.kozlowski@linaro.org \
--cc=andrew@lunn.ch \
--cc=camel.guo@axis.com \
--cc=davem@davemloft.net \
--cc=devicetree@vger.kernel.org \
--cc=edumazet@google.com \
--cc=f.fainelli@gmail.com \
--cc=kernel@axis.com \
--cc=krzysztof.kozlowski+dt@linaro.org \
--cc=kuba@kernel.org \
--cc=linux-kernel@vger.kernel.org \
--cc=linux@armlinux.org.uk \
--cc=netdev@vger.kernel.org \
--cc=olteanv@gmail.com \
--cc=pabeni@redhat.com \
--cc=robh+dt@kernel.org \
--cc=robh@kernel.org \
--cc=vivien.didelot@gmail.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).