mbox series

[v4,00/11] microchip: add support for ksz88x3 driver family

Message ID 20200803054442.20089-1-m.grzeschik@pengutronix.de
Headers show
Series microchip: add support for ksz88x3 driver family | expand

Message

Michael Grzeschik Aug. 3, 2020, 5:44 a.m. UTC
This series adds support for the ksz88x3 driver family to the dsa based ksz
drivers. The driver is making use of the already available ksz8795 driver and
moves it to an generic driver for the ksz8 based chips which have similar
functions but an totaly different register layout.

Andrew Lunn (1):
  net: phy: Add support for microchip SMI0 MDIO bus

Michael Grzeschik (10):
  dt-bindings: net: mdio-gpio: add compatible for microchip,mdio-smi0
  net: tag: ksz: Add KSZ8863 tag code
  net: dsa: microchip: ksz8795: use port_cnt where possible
  net: dsa: microchip: ksz8795: dynamic allocate memory for
    flush_dyn_mac_table
  net: dsa: microchip: ksz8795: change drivers prefix to be generic
  net: dsa: microchip: ksz8795: move register offsets and shifts to
    separate struct
  net: dsa: microchip: ksz8795: add support for ksz88xx chips
  net: dsa: microchip: Add Microchip KSZ8863 SMI based driver support
  net: dsa: microchip: Add Microchip KSZ8863 SPI based driver support
  dt-bindings: net: dsa: document additional Microchip KSZ8863/8873
    switch

 .../devicetree/bindings/net/dsa/ksz.txt       |   2 +
 .../devicetree/bindings/net/mdio-gpio.txt     |   1 +
 drivers/net/dsa/microchip/Kconfig             |   9 +
 drivers/net/dsa/microchip/Makefile            |   1 +
 drivers/net/dsa/microchip/ksz8.h              |  68 ++
 drivers/net/dsa/microchip/ksz8795.c           | 926 ++++++++++++------
 drivers/net/dsa/microchip/ksz8795_reg.h       | 214 ++--
 drivers/net/dsa/microchip/ksz8795_spi.c       |  64 +-
 drivers/net/dsa/microchip/ksz8863_reg.h       | 124 +++
 drivers/net/dsa/microchip/ksz8863_smi.c       | 204 ++++
 drivers/net/dsa/microchip/ksz_common.h        |   2 +-
 drivers/net/phy/mdio-bitbang.c                |   8 +-
 drivers/net/phy/mdio-gpio.c                   |   9 +
 include/linux/mdio-bitbang.h                  |   3 +
 include/net/dsa.h                             |   2 +
 net/dsa/tag_ksz.c                             |  57 ++
 16 files changed, 1275 insertions(+), 419 deletions(-)
 create mode 100644 drivers/net/dsa/microchip/ksz8.h
 create mode 100644 drivers/net/dsa/microchip/ksz8863_reg.h
 create mode 100644 drivers/net/dsa/microchip/ksz8863_smi.c

Comments

Matthias Schiffer Sept. 10, 2020, 11:44 a.m. UTC | #1
On Mon, 2020-08-03 at 07:44 +0200, Michael Grzeschik wrote:
> Add KSZ88X3 driver support. We add support for the KXZ88X3 three port
> switches using the Microchip SMI Interface. They are supported using
> the
> MDIO-Bitbang Interface.
> 
> Signed-off-by: Michael Grzeschik <m.grzeschik@pengutronix.de>
> 
> ---
> v1 -> v2:  - this code was part of previuos patch
> v2 -> v3:  - this code was part of previuos patch
> v3 -> v4:  - moved this glue code so separate patch
>            - fixed locking in regmap and mdio_read/mdio_write
> 
>  drivers/net/dsa/microchip/Kconfig       |   9 ++
>  drivers/net/dsa/microchip/Makefile      |   1 +
>  drivers/net/dsa/microchip/ksz8863_smi.c | 204
> ++++++++++++++++++++++++
>  3 files changed, 214 insertions(+)
>  create mode 100644 drivers/net/dsa/microchip/ksz8863_smi.c
> 
> diff --git a/drivers/net/dsa/microchip/Kconfig
> b/drivers/net/dsa/microchip/Kconfig
> index 4ec6a47b7f7284f..c5819bd4121cc7c 100644
> --- a/drivers/net/dsa/microchip/Kconfig
> +++ b/drivers/net/dsa/microchip/Kconfig
> @@ -40,3 +40,12 @@ config NET_DSA_MICROCHIP_KSZ8795_SPI
>  
>  	  It is required to use the KSZ8795 switch driver as the only
> access
>  	  is through SPI.
> +
> +config NET_DSA_MICROCHIP_KSZ8863_SMI
> +	tristate "KSZ series SMI connected switch driver"
> +	depends on NET_DSA_MICROCHIP_KSZ8795

Please also update the label or help text for the
NET_DSA_MICROCHIP_KSZ8795 symbol to include the KSZ88X3, so it's clear
which of the KSZ DSA drivers is the correct one for these switches.



> +	select MDIO_BITBANG
> +	default y
> +	help
> +	  Select to enable support for registering switches configured
> through
> +	  Microchip SMI. It Supports the KSZ8863 and KSZ8873 Switch.
> diff --git a/drivers/net/dsa/microchip/Makefile
> b/drivers/net/dsa/microchip/Makefile
> index 929caa81e782ed2..2a03b21a3386f5d 100644
> --- a/drivers/net/dsa/microchip/Makefile
> +++ b/drivers/net/dsa/microchip/Makefile
> @@ -5,3 +5,4 @@ obj-$(CONFIG_NET_DSA_MICROCHIP_KSZ9477_I2C)	+=
> ksz9477_i2c.o
>  obj-$(CONFIG_NET_DSA_MICROCHIP_KSZ9477_SPI)	+= ksz9477_spi.o
>  obj-$(CONFIG_NET_DSA_MICROCHIP_KSZ8795)		+= ksz8795.o
>  obj-$(CONFIG_NET_DSA_MICROCHIP_KSZ8795_SPI)	+= ksz8795_spi.o
> +obj-$(CONFIG_NET_DSA_MICROCHIP_KSZ8863_SMI)	+= ksz8863_smi.o
> diff --git a/drivers/net/dsa/microchip/ksz8863_smi.c
> b/drivers/net/dsa/microchip/ksz8863_smi.c
> new file mode 100644
> index 000000000000000..fd493441d725284
> --- /dev/null
> +++ b/drivers/net/dsa/microchip/ksz8863_smi.c
> @@ -0,0 +1,204 @@
> +// SPDX-License-Identifier: GPL-2.0
> +/*
> + * Microchip KSZ8863 series register access through SMI
> + *
> + * Copyright (C) 2019 Pengutronix, Michael Grzeschik <
> kernel@pengutronix.de>
> + */
> +
> +#include "ksz8.h"
> +#include "ksz_common.h"
> +
> +/* Serial Management Interface (SMI) uses the following frame
> format:
> + *
> + *       preamble|start|Read/Write|  PHY   |  REG  |TA|   Data
> bits      | Idle
> + *               |frame| OP code  |address
> |address|  |                  |
> + * read | 32x1´s | 01  |    00    | 1xRRR  | RRRRR |Z0|
> 00000000DDDDDDDD |  Z
> + * write| 32x1´s | 01  |    00    | 0xRRR  | RRRRR |10|
> xxxxxxxxDDDDDDDD |  Z
> + *
> + */
> +
> +static int ksz8863_mdio_read(void *ctx, const void *reg_buf, size_t
> reg_len,
> +			     void *val_buf, size_t val_len)
> +{
> +	struct ksz_device *dev = (struct ksz_device *)ctx;
> +	struct ksz8 *ksz8 = dev->priv;
> +	struct mdio_device *mdev = ksz8->priv;
> +	u8 reg = *(u8 *)reg_buf;
> +	u8 *val = val_buf;
> +	int ret = 0;
> +	int i;
> +
> +	mutex_lock_nested(&mdev->bus->mdio_lock, MDIO_MUTEX_NESTED);
> +	for (i = 0; i < val_len; i++) {
> +		int tmp = reg + i;
> +
> +		ret = __mdiobus_read(mdev->bus, ((tmp & 0xE0) >> 5) |
> +				     BIT(4), tmp);
> +		if (ret < 0)
> +			goto out;
> +
> +		val[i] = ret;
> +	}
> +	ret = 0;
> +
> + out:
> +	mutex_unlock(&mdev->bus->mdio_lock);
> +
> +	return ret;
> +}
> +
> +static int ksz8863_mdio_write(void *ctx, const void *data, size_t
> count)
> +{
> +	struct ksz_device *dev = (struct ksz_device *)ctx;
> +	struct ksz8 *ksz8 = dev->priv;
> +	struct mdio_device *mdev = ksz8->priv;
> +	u8 *val = (u8 *)(data + 4);
> +	u32 reg = *(u32 *)data;
> +	int ret = 0;
> +	int i;
> +
> +	mutex_lock_nested(&mdev->bus->mdio_lock, MDIO_MUTEX_NESTED);
> +	for (i = 0; i < (count - 4); i++) {
> +		int tmp = reg + i;
> +
> +		ret = __mdiobus_write(mdev->bus, ((tmp & 0xE0) >> 5),
> +				      tmp, val[i]);
> +		if (ret < 0)
> +			goto out;
> +	}
> +
> + out:
> +	mutex_unlock(&mdev->bus->mdio_lock);
> +
> +	return ret;
> +}
> +
> +static const struct regmap_bus regmap_smi[] = {
> +	{
> +		.read = ksz8863_mdio_read,
> +		.write = ksz8863_mdio_write,
> +		.max_raw_read = 1,
> +		.max_raw_write = 1,
> +	},
> +	{
> +		.read = ksz8863_mdio_read,
> +		.write = ksz8863_mdio_write,
> +		.val_format_endian_default = REGMAP_ENDIAN_BIG,
> +		.max_raw_read = 2,
> +		.max_raw_write = 2,
> +	},
> +	{
> +		.read = ksz8863_mdio_read,
> +		.write = ksz8863_mdio_write,
> +		.val_format_endian_default = REGMAP_ENDIAN_BIG,
> +		.max_raw_read = 4,
> +		.max_raw_write = 4,
> +	}
> +};
> +
> +static const struct regmap_config ksz8863_regmap_config[] = {
> +	{
> +		.name = "#8",
> +		.reg_bits = 8,
> +		.pad_bits = 24,
> +		.val_bits = 8,
> +		.cache_type = REGCACHE_NONE,
> +		.use_single_read = 1,
> +		.lock = ksz_regmap_lock,
> +		.unlock = ksz_regmap_unlock,
> +	},
> +	{
> +		.name = "#16",
> +		.reg_bits = 8,
> +		.pad_bits = 24,
> +		.val_bits = 16,
> +		.cache_type = REGCACHE_NONE,
> +		.use_single_read = 1,
> +		.lock = ksz_regmap_lock,
> +		.unlock = ksz_regmap_unlock,
> +	},
> +	{
> +		.name = "#32",
> +		.reg_bits = 8,
> +		.pad_bits = 24,
> +		.val_bits = 32,
> +		.cache_type = REGCACHE_NONE,
> +		.use_single_read = 1,
> +		.lock = ksz_regmap_lock,
> +		.unlock = ksz_regmap_unlock,
> +	}
> +};
> +
> +static int ksz8863_smi_probe(struct mdio_device *mdiodev)
> +{
> +	struct regmap_config rc;
> +	struct ksz_device *dev;
> +	struct ksz8 *ksz8;
> +	int ret;
> +	int i;
> +
> +	ksz8 = devm_kzalloc(&mdiodev->dev, sizeof(struct ksz8),
> GFP_KERNEL);
> +	ksz8->priv = mdiodev;
> +
> +	dev = ksz_switch_alloc(&mdiodev->dev, ksz8);
> +	if (!dev)
> +		return -EINVAL;
> +
> +	for (i = 0; i < ARRAY_SIZE(ksz8863_regmap_config); i++) {
> +		rc = ksz8863_regmap_config[i];
> +		rc.lock_arg = &dev->regmap_mutex;
> +		dev->regmap[i] = devm_regmap_init(&mdiodev->dev,
> +						  &regmap_smi[i], dev,
> +						  &rc);
> +		if (IS_ERR(dev->regmap[i])) {
> +			ret = PTR_ERR(dev->regmap[i]);
> +			dev_err(&mdiodev->dev,
> +				"Failed to initialize regmap%i: %d\n",
> +				ksz8863_regmap_config[i].val_bits,
> ret);
> +			return ret;
> +		}
> +	}
> +
> +	if (mdiodev->dev.platform_data)
> +		dev->pdata = mdiodev->dev.platform_data;
> +
> +	ret = ksz8_switch_register(dev);
> +
> +	/* Main DSA driver may not be started yet. */
> +	if (ret)
> +		return ret;
> +
> +	dev_set_drvdata(&mdiodev->dev, dev);
> +
> +	return 0;
> +}
> +
> +static void ksz8863_smi_remove(struct mdio_device *mdiodev)
> +{
> +	struct ksz_device *dev = dev_get_drvdata(&mdiodev->dev);
> +
> +	if (dev)
> +		ksz_switch_remove(dev);
> +}
> +
> +static const struct of_device_id ksz8863_dt_ids[] = {
> +	{ .compatible = "microchip,ksz8863" },
> +	{ .compatible = "microchip,ksz8873" },
> +	{ },
> +};
> +MODULE_DEVICE_TABLE(of, ksz8863_dt_ids);
> +
> +static struct mdio_driver ksz8863_driver = {
> +	.probe	= ksz8863_smi_probe,
> +	.remove	= ksz8863_smi_remove,
> +	.mdiodrv.driver = {
> +		.name	= "ksz8863-switch",
> +		.of_match_table = ksz8863_dt_ids,
> +	},
> +};
> +
> +mdio_module_driver(ksz8863_driver);
> +
> +MODULE_AUTHOR("Michael Grzeschik <m.grzeschik@pengutronix.de>");
> +MODULE_DESCRIPTION("Microchip KSZ8863 SMI Switch driver");
> +MODULE_LICENSE("GPL v2");