lkml.org 
[lkml]   [2022]   [Sep]   [25]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    From
    Subject[PATCH v3 net-next 13/14] net: dsa: ocelot: add external ocelot switch control
    Date
    Add control of an external VSC7512 chip.

    Currently the four copper phy ports are fully functional. Communication to
    external phys is also functional, but the SGMII / QSGMII interfaces are
    currently non-functional.

    Signed-off-by: Colin Foster <colin.foster@in-advantage.com>
    ---

    v3
    * Remove additional entry in vsc7512_port_modes array
    * Add MFD_OCELOT namespace import, which is needed for
    vsc7512_*_io_res

    v2
    * Add MAINTAINERS update
    * Remove phrase "by way of the ocelot-mfd interface" from the commit
    message
    * Move MFD resource addition to a separate patch
    * Update Kconfig help
    * Remove "ocelot_ext_reset()" - it is now shared with ocelot_lib
    * Remove unnecessary includes
    * Remove "_EXT" from OCELOT_EXT_PORT_MODE_SERDES
    * Remove _ext from the compatible string
    * Remove no-longer-necessary GCB register definitions

    v1 from previous RFC:
    * Remove unnecessary byteorder and kconfig header includes.
    * Create OCELOT_EXT_PORT_MODE_SERDES macro to match vsc9959.
    * Utilize readx_poll_timeout for SYS_RESET_CFG_MEM_INIT.
    * *_io_res struct arrays have been moved to the MFD files.
    * Changes to utilize phylink_generic_validate() have been squashed.
    * dev_err_probe() is used in the probe function.
    * Make ocelot_ext_switch_of_match static.
    * Relocate ocelot_ext_ops structure to be next to vsc7512_info, to
    match what was done in other felix drivers.
    * Utilize dev_get_regmap() instead of the obsolete
    ocelot_init_regmap_from_resource() routine.

    ---
    MAINTAINERS | 1 +
    drivers/net/dsa/ocelot/Kconfig | 19 +++
    drivers/net/dsa/ocelot/Makefile | 5 +
    drivers/net/dsa/ocelot/ocelot_ext.c | 194 ++++++++++++++++++++++++++++
    4 files changed, 219 insertions(+)
    create mode 100644 drivers/net/dsa/ocelot/ocelot_ext.c

    diff --git a/MAINTAINERS b/MAINTAINERS
    index 1415a1498d68..214b3f836446 100644
    --- a/MAINTAINERS
    +++ b/MAINTAINERS
    @@ -14752,6 +14752,7 @@ M: Colin Foster <colin.foster@in-advantage.com>
    S: Supported
    F: Documentation/devicetree/bindings/mfd/mscc,ocelot.yaml
    F: drivers/mfd/ocelot*
    +F: drivers/net/dsa/ocelot/ocelot_ext.c
    F: include/linux/mfd/ocelot.h

    OCXL (Open Coherent Accelerator Processor Interface OpenCAPI) DRIVER
    diff --git a/drivers/net/dsa/ocelot/Kconfig b/drivers/net/dsa/ocelot/Kconfig
    index 08db9cf76818..74a900e16d76 100644
    --- a/drivers/net/dsa/ocelot/Kconfig
    +++ b/drivers/net/dsa/ocelot/Kconfig
    @@ -1,4 +1,23 @@
    # SPDX-License-Identifier: GPL-2.0-only
    +config NET_DSA_MSCC_OCELOT_EXT
    + tristate "Ocelot External Ethernet switch support"
    + depends on NET_DSA && SPI
    + depends on NET_VENDOR_MICROSEMI
    + select MDIO_MSCC_MIIM
    + select MFD_OCELOT_CORE
    + select MSCC_OCELOT_SWITCH_LIB
    + select NET_DSA_TAG_OCELOT_8021Q
    + select NET_DSA_TAG_OCELOT
    + help
    + This driver supports the VSC7511, VSC7512, VSC7513 and VSC7514 chips
    + when controlled through SPI.
    +
    + The Ocelot switch family is a set of multi-port networking chips. All
    + of these chips have the ability to be controlled externally through
    + SPI or PCIe interfaces.
    +
    + Say "Y" here to enable external control to these chips.
    +
    config NET_DSA_MSCC_FELIX
    tristate "Ocelot / Felix Ethernet switch support"
    depends on NET_DSA && PCI
    diff --git a/drivers/net/dsa/ocelot/Makefile b/drivers/net/dsa/ocelot/Makefile
    index f6dd131e7491..d7f3f5a4461c 100644
    --- a/drivers/net/dsa/ocelot/Makefile
    +++ b/drivers/net/dsa/ocelot/Makefile
    @@ -1,11 +1,16 @@
    # SPDX-License-Identifier: GPL-2.0-only
    obj-$(CONFIG_NET_DSA_MSCC_FELIX) += mscc_felix.o
    +obj-$(CONFIG_NET_DSA_MSCC_OCELOT_EXT) += mscc_ocelot_ext.o
    obj-$(CONFIG_NET_DSA_MSCC_SEVILLE) += mscc_seville.o

    mscc_felix-objs := \
    felix.o \
    felix_vsc9959.o

    +mscc_ocelot_ext-objs := \
    + felix.o \
    + ocelot_ext.o
    +
    mscc_seville-objs := \
    felix.o \
    seville_vsc9953.o
    diff --git a/drivers/net/dsa/ocelot/ocelot_ext.c b/drivers/net/dsa/ocelot/ocelot_ext.c
    new file mode 100644
    index 000000000000..fb9dbb31fea1
    --- /dev/null
    +++ b/drivers/net/dsa/ocelot/ocelot_ext.c
    @@ -0,0 +1,194 @@
    +// SPDX-License-Identifier: (GPL-2.0 OR MIT)
    +/*
    + * Copyright 2021-2022 Innovative Advantage Inc.
    + */
    +
    +#include <linux/mfd/ocelot.h>
    +#include <linux/phylink.h>
    +#include <linux/platform_device.h>
    +#include <linux/regmap.h>
    +#include <soc/mscc/ocelot.h>
    +#include <soc/mscc/vsc7514_regs.h>
    +#include "felix.h"
    +
    +#define VSC7512_NUM_PORTS 11
    +
    +#define OCELOT_PORT_MODE_SERDES (OCELOT_PORT_MODE_SGMII | \
    + OCELOT_PORT_MODE_QSGMII)
    +
    +static const u32 vsc7512_port_modes[VSC7512_NUM_PORTS] = {
    + OCELOT_PORT_MODE_INTERNAL,
    + OCELOT_PORT_MODE_INTERNAL,
    + OCELOT_PORT_MODE_INTERNAL,
    + OCELOT_PORT_MODE_INTERNAL,
    + OCELOT_PORT_MODE_SERDES,
    + OCELOT_PORT_MODE_SERDES,
    + OCELOT_PORT_MODE_SERDES,
    + OCELOT_PORT_MODE_SERDES,
    + OCELOT_PORT_MODE_SERDES,
    + OCELOT_PORT_MODE_SERDES,
    + OCELOT_PORT_MODE_SGMII,
    +};
    +
    +static const u32 *vsc7512_regmap[TARGET_MAX] = {
    + [ANA] = vsc7514_ana_regmap,
    + [QS] = vsc7514_qs_regmap,
    + [QSYS] = vsc7514_qsys_regmap,
    + [REW] = vsc7514_rew_regmap,
    + [SYS] = vsc7514_sys_regmap,
    + [S0] = vsc7514_vcap_regmap,
    + [S1] = vsc7514_vcap_regmap,
    + [S2] = vsc7514_vcap_regmap,
    + [PTP] = vsc7514_ptp_regmap,
    + [DEV_GMII] = vsc7514_dev_gmii_regmap,
    +};
    +
    +static void ocelot_ext_phylink_validate(struct ocelot *ocelot, int port,
    + unsigned long *supported,
    + struct phylink_link_state *state)
    +{
    + struct felix *felix = ocelot_to_felix(ocelot);
    + struct dsa_switch *ds = felix->ds;
    + struct dsa_port *dp;
    +
    + dp = dsa_to_port(ds, port);
    +
    + phylink_generic_validate(&dp->pl_config, supported, state);
    +}
    +
    +static struct regmap *ocelot_ext_regmap_init(struct ocelot *ocelot,
    + const char *name)
    +{
    + /* In the ocelot-mfd configuration, regmaps are attached to the device
    + * by name alone, so dev_get_regmap will return the requested regmap
    + * without the need to fully define the resource
    + */
    + return dev_get_regmap(ocelot->dev->parent, name);
    +}
    +
    +static const struct ocelot_ops ocelot_ext_ops = {
    + .reset = ocelot_reset,
    + .wm_enc = ocelot_wm_enc,
    + .wm_dec = ocelot_wm_dec,
    + .wm_stat = ocelot_wm_stat,
    + .port_to_netdev = felix_port_to_netdev,
    + .netdev_to_port = felix_netdev_to_port,
    +};
    +
    +static const struct felix_info vsc7512_info = {
    + .target_io_res = vsc7512_target_io_res,
    + .port_io_res = vsc7512_port_io_res,
    + .regfields = vsc7514_regfields,
    + .map = vsc7512_regmap,
    + .ops = &ocelot_ext_ops,
    + .stats_layout = vsc7514_stats_layout,
    + .vcap = vsc7514_vcap_props,
    + .num_mact_rows = 1024,
    + .num_ports = VSC7512_NUM_PORTS,
    + .num_tx_queues = OCELOT_NUM_TC,
    + .phylink_validate = ocelot_ext_phylink_validate,
    + .port_modes = vsc7512_port_modes,
    + .init_regmap = ocelot_ext_regmap_init,
    +};
    +
    +static int ocelot_ext_probe(struct platform_device *pdev)
    +{
    + struct device *dev = &pdev->dev;
    + struct dsa_switch *ds;
    + struct ocelot *ocelot;
    + struct felix *felix;
    + int err;
    +
    + felix = kzalloc(sizeof(*felix), GFP_KERNEL);
    + if (!felix)
    + return -ENOMEM;
    +
    + dev_set_drvdata(dev, felix);
    +
    + ocelot = &felix->ocelot;
    + ocelot->dev = dev;
    +
    + ocelot->num_flooding_pgids = 1;
    +
    + felix->info = &vsc7512_info;
    +
    + ds = kzalloc(sizeof(*ds), GFP_KERNEL);
    + if (!ds) {
    + err = -ENOMEM;
    + dev_err_probe(dev, err, "Failed to allocate DSA switch\n");
    + goto err_free_felix;
    + }
    +
    + ds->dev = dev;
    + ds->num_ports = felix->info->num_ports;
    + ds->num_tx_queues = felix->info->num_tx_queues;
    +
    + ds->ops = &felix_switch_ops;
    + ds->priv = ocelot;
    + felix->ds = ds;
    + felix->tag_proto = DSA_TAG_PROTO_OCELOT;
    +
    + err = dsa_register_switch(ds);
    + if (err) {
    + dev_err_probe(dev, err, "Failed to register DSA switch\n");
    + goto err_free_ds;
    + }
    +
    + return 0;
    +
    +err_free_ds:
    + kfree(ds);
    +err_free_felix:
    + kfree(felix);
    + return err;
    +}
    +
    +static int ocelot_ext_remove(struct platform_device *pdev)
    +{
    + struct felix *felix = dev_get_drvdata(&pdev->dev);
    +
    + if (!felix)
    + return 0;
    +
    + dsa_unregister_switch(felix->ds);
    +
    + kfree(felix->ds);
    + kfree(felix);
    +
    + dev_set_drvdata(&pdev->dev, NULL);
    +
    + return 0;
    +}
    +
    +static void ocelot_ext_shutdown(struct platform_device *pdev)
    +{
    + struct felix *felix = dev_get_drvdata(&pdev->dev);
    +
    + if (!felix)
    + return;
    +
    + dsa_switch_shutdown(felix->ds);
    +
    + dev_set_drvdata(&pdev->dev, NULL);
    +}
    +
    +static const struct of_device_id ocelot_ext_switch_of_match[] = {
    + { .compatible = "mscc,vsc7512-switch" },
    + { },
    +};
    +MODULE_DEVICE_TABLE(of, ocelot_ext_switch_of_match);
    +
    +static struct platform_driver ocelot_ext_switch_driver = {
    + .driver = {
    + .name = "ocelot-switch",
    + .of_match_table = of_match_ptr(ocelot_ext_switch_of_match),
    + },
    + .probe = ocelot_ext_probe,
    + .remove = ocelot_ext_remove,
    + .shutdown = ocelot_ext_shutdown,
    +};
    +module_platform_driver(ocelot_ext_switch_driver);
    +
    +MODULE_DESCRIPTION("External Ocelot Switch driver");
    +MODULE_LICENSE("GPL");
    +MODULE_IMPORT_NS(MFD_OCELOT);
    --
    2.25.1
    \
     
     \ /
      Last update: 2022-09-26 02:33    [W:4.276 / U:0.356 seconds]
    ©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site