Message ID | 20200803054442.20089-10-m.grzeschik@pengutronix.de |
---|---|
State | Changes Requested |
Delegated to: | David Miller |
Headers | show |
Series | microchip: add support for ksz88x3 driver family | expand |
On 8/2/20 10:44 PM, Michael Grzeschik wrote: > 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 > + select MDIO_BITBANG > + default y huh? why? > + help > + Select to enable support for registering switches configured through > + Microchip SMI. It Supports the KSZ8863 and KSZ8873 Switch. supports switch.
On 8/2/2020 10:44 PM, 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> > [snip > + > +config NET_DSA_MICROCHIP_KSZ8863_SMI > + tristate "KSZ series SMI connected switch driver" > + depends on NET_DSA_MICROCHIP_KSZ8795 > + select MDIO_BITBANG > + default y As Randy already identified please remove this. > + 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; There is no need to cast a void pointer, can you also make it a const void *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; Humm, how does this work for reg_len >1 with reg being a scalar? Why not just use reg[i]? > + > + ret = __mdiobus_read(mdev->bus, ((tmp & 0xE0) >> 5) | > + BIT(4), tmp); Can we provide defines instead of these numbers? > + 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; Likewise, no need to cast here. > + struct ksz8 *ksz8 = dev->priv; > + struct mdio_device *mdev = ksz8->priv; > + u8 *val = (u8 *)(data + 4); > + u32 reg = *(u32 *)data; Humm, are you positive this works for all endian configurations?
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, > + ®map_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");
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 + 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, + ®map_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");
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