Commit 51428fd6 authored by David S. Miller's avatar David S. Miller
Browse files

Merge branch...


Merge branch 'dsa-microchip-Modify-KSZ9477-DSA-driver-in-preparation-to-add-other-KSZ-switch-drivers'

Tristram Ha says:

====================
net: dsa: microchip: Modify KSZ9477 DSA driver in preparation to add other KSZ switch drivers

This series of patches is to modify the original KSZ9477 DSA driver so
that other KSZ switch drivers can be added and use the common code.

There are several steps to accomplish this achievement.  First is to
rename some function names with a prefix to indicate chip specific
function.  Second is to move common code into header that can be shared.
Last is to modify tag_ksz.c so that it can handle many tail tag formats
used by different KSZ switch drivers.

ksz_common.c will contain the common code used by all KSZ switch drivers.
ksz9477.c will contain KSZ9477 code from the original ksz_common.c.
ksz9477_spi.c is renamed from ksz_spi.c.
ksz9477_reg.h is renamed from ksz_9477_reg.h.
ksz_common.h is added to provide common code access to KSZ switch
drivers.
ksz_spi.h is added to provide common SPI access functions to KSZ SPI
drivers.

v4
- Patches were removed to concentrate on changing driver structure without
adding new code.

v3
- The phy_device structure is used to hold port link information
- A structure is passed in ksz_xmit and ksz_rcv instead of function pointer
- Switch offload forwarding is supported

v2
- Initialize reg_mutex before use
- The alu_mutex is only used inside chip specific functions

v1
- Each patch in the set is self-contained
- Use ksz9477 prefix to indicate KSZ9477 specific code
====================

Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parents b1a20048 84bd1908
Loading
Loading
Loading
Loading
+10 −6
Original line number Diff line number Diff line
menuconfig MICROCHIP_KSZ
	tristate "Microchip KSZ series switch support"
config NET_DSA_MICROCHIP_KSZ_COMMON
	tristate

menuconfig NET_DSA_MICROCHIP_KSZ9477
	tristate "Microchip KSZ9477 series switch support"
	depends on NET_DSA
	select NET_DSA_TAG_KSZ
	select NET_DSA_MICROCHIP_KSZ_COMMON
	help
	  This driver adds support for Microchip KSZ switch chips.
	  This driver adds support for Microchip KSZ9477 switch chips.

config MICROCHIP_KSZ_SPI_DRIVER
	tristate "KSZ series SPI connected switch driver"
	depends on MICROCHIP_KSZ && SPI
config NET_DSA_MICROCHIP_KSZ9477_SPI
	tristate "KSZ9477 series SPI connected switch driver"
	depends on NET_DSA_MICROCHIP_KSZ9477 && SPI
	help
	  Select to enable support for registering switches configured through SPI.
+3 −2
Original line number Diff line number Diff line
obj-$(CONFIG_MICROCHIP_KSZ)	        += ksz_common.o
obj-$(CONFIG_MICROCHIP_KSZ_SPI_DRIVER)	+= ksz_spi.o
obj-$(CONFIG_NET_DSA_MICROCHIP_KSZ_COMMON)	+= ksz_common.o
obj-$(CONFIG_NET_DSA_MICROCHIP_KSZ9477)		+= ksz9477.o
obj-$(CONFIG_NET_DSA_MICROCHIP_KSZ9477_SPI)	+= ksz9477_spi.o
+1316 −0

File added.

Preview size limit exceeded, changes collapsed.

+3 −14
Original line number Diff line number Diff line
/*
 * Microchip KSZ9477 register definitions
 *
 * Copyright (C) 2017
/* SPDX-License-Identifier: GPL-2.0
 *
 * Permission to use, copy, modify, and/or distribute this software for any
 * purpose with or without fee is hereby granted, provided that the above
 * copyright notice and this permission notice appear in all copies.
 * Microchip KSZ9477 register definitions
 *
 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
 * Copyright (C) 2017-2018 Microchip Technology Inc.
 */

#ifndef __KSZ9477_REGS_H
+177 −0
Original line number Diff line number Diff line
// SPDX-License-Identifier: GPL-2.0
/*
 * Microchip KSZ series register access through SPI
 * Microchip KSZ9477 series register access through SPI
 *
 * Copyright (C) 2017
 *
 * Permission to use, copy, modify, and/or distribute this software for any
 * purpose with or without fee is hereby granted, provided that the above
 * copyright notice and this permission notice appear in all copies.
 *
 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
 * Copyright (C) 2017-2018 Microchip Technology Inc.
 */

#include <asm/unaligned.h>
@@ -24,6 +13,7 @@
#include <linux/spi/spi.h>

#include "ksz_priv.h"
#include "ksz_spi.h"

/* SPI frame opcodes */
#define KS_SPIOP_RD			3
@@ -33,7 +23,10 @@
#define SPI_ADDR_MASK			(BIT(SPI_ADDR_SHIFT) - 1)
#define SPI_TURNAROUND_SHIFT		5

static int ksz_spi_read_reg(struct spi_device *spi, u32 reg, u8 *val,
/* Enough to read all switch port registers. */
#define SPI_TX_BUF_LEN			0x100

static int ksz9477_spi_read_reg(struct spi_device *spi, u32 reg, u8 *val,
				unsigned int len)
{
	u32 txbuf;
@@ -48,27 +41,36 @@ static int ksz_spi_read_reg(struct spi_device *spi, u32 reg, u8 *val,
	return ret;
}

static int ksz_spi_read(struct ksz_device *dev, u32 reg, u8 *data,
static int ksz9477_spi_write_reg(struct spi_device *spi, u32 reg, u8 *val,
				 unsigned int len)
{
	struct spi_device *spi = dev->priv;
	u32 *txbuf = (u32 *)val;

	*txbuf = reg & SPI_ADDR_MASK;
	*txbuf |= (KS_SPIOP_WR << SPI_ADDR_SHIFT);
	*txbuf <<= SPI_TURNAROUND_SHIFT;
	*txbuf = cpu_to_be32(*txbuf);

	return ksz_spi_read_reg(spi, reg, data, len);
	return spi_write(spi, txbuf, 4 + len);
}

static int ksz_spi_read8(struct ksz_device *dev, u32 reg, u8 *val)
static int ksz_spi_read(struct ksz_device *dev, u32 reg, u8 *data,
			unsigned int len)
{
	return ksz_spi_read(dev, reg, val, 1);
	struct spi_device *spi = dev->priv;

	return ksz9477_spi_read_reg(spi, reg, data, len);
}

static int ksz_spi_read16(struct ksz_device *dev, u32 reg, u16 *val)
static int ksz_spi_write(struct ksz_device *dev, u32 reg, void *data,
			 unsigned int len)
{
	int ret = ksz_spi_read(dev, reg, (u8 *)val, 2);

	if (!ret)
		*val = be16_to_cpu(*val);
	struct spi_device *spi = dev->priv;

	return ret;
	if (len > SPI_TX_BUF_LEN)
		len = SPI_TX_BUF_LEN;
	memcpy(&dev->txbuf[4], data, len);
	return ksz9477_spi_write_reg(spi, reg, dev->txbuf, len);
}

static int ksz_spi_read24(struct ksz_device *dev, u32 reg, u32 *val)
@@ -86,72 +88,15 @@ static int ksz_spi_read24(struct ksz_device *dev, u32 reg, u32 *val)
	return ret;
}

static int ksz_spi_read32(struct ksz_device *dev, u32 reg, u32 *val)
{
	int ret = ksz_spi_read(dev, reg, (u8 *)val, 4);

	if (!ret)
		*val = be32_to_cpu(*val);

	return ret;
}

static int ksz_spi_write_reg(struct spi_device *spi, u32 reg, u8 *val,
			     unsigned int len)
{
	u32 txbuf;
	u8 data[12];
	int i;

	txbuf = reg & SPI_ADDR_MASK;
	txbuf |= (KS_SPIOP_WR << SPI_ADDR_SHIFT);
	txbuf <<= SPI_TURNAROUND_SHIFT;
	txbuf = cpu_to_be32(txbuf);

	data[0] = txbuf & 0xFF;
	data[1] = (txbuf & 0xFF00) >> 8;
	data[2] = (txbuf & 0xFF0000) >> 16;
	data[3] = (txbuf & 0xFF000000) >> 24;
	for (i = 0; i < len; i++)
		data[i + 4] = val[i];

	return spi_write(spi, &data, 4 + len);
}

static int ksz_spi_write8(struct ksz_device *dev, u32 reg, u8 value)
{
	struct spi_device *spi = dev->priv;

	return ksz_spi_write_reg(spi, reg, &value, 1);
}

static int ksz_spi_write16(struct ksz_device *dev, u32 reg, u16 value)
{
	struct spi_device *spi = dev->priv;

	value = cpu_to_be16(value);
	return ksz_spi_write_reg(spi, reg, (u8 *)&value, 2);
}

static int ksz_spi_write24(struct ksz_device *dev, u32 reg, u32 value)
{
	struct spi_device *spi = dev->priv;

	/* make it to big endian 24bit from MSB */
	value <<= 8;
	value = cpu_to_be32(value);
	return ksz_spi_write_reg(spi, reg, (u8 *)&value, 3);
}

static int ksz_spi_write32(struct ksz_device *dev, u32 reg, u32 value)
{
	struct spi_device *spi = dev->priv;

	value = cpu_to_be32(value);
	return ksz_spi_write_reg(spi, reg, (u8 *)&value, 4);
	return ksz_spi_write(dev, reg, &value, 3);
}

static const struct ksz_io_ops ksz_spi_ops = {
static const struct ksz_io_ops ksz9477_spi_ops = {
	.read8 = ksz_spi_read8,
	.read16 = ksz_spi_read16,
	.read24 = ksz_spi_read24,
@@ -160,21 +105,27 @@ static const struct ksz_io_ops ksz_spi_ops = {
	.write16 = ksz_spi_write16,
	.write24 = ksz_spi_write24,
	.write32 = ksz_spi_write32,
	.get = ksz_spi_get,
	.set = ksz_spi_set,
};

static int ksz_spi_probe(struct spi_device *spi)
static int ksz9477_spi_probe(struct spi_device *spi)
{
	struct ksz_device *dev;
	int ret;

	dev = ksz_switch_alloc(&spi->dev, &ksz_spi_ops, spi);
	dev = ksz_switch_alloc(&spi->dev, &ksz9477_spi_ops, spi);
	if (!dev)
		return -ENOMEM;

	if (spi->dev.platform_data)
		dev->pdata = spi->dev.platform_data;

	ret = ksz_switch_register(dev);
	dev->txbuf = devm_kzalloc(dev->dev, 4 + SPI_TX_BUF_LEN, GFP_KERNEL);

	ret = ksz9477_switch_register(dev);

	/* Main DSA driver may not be started yet. */
	if (ret)
		return ret;

@@ -183,7 +134,7 @@ static int ksz_spi_probe(struct spi_device *spi)
	return 0;
}

static int ksz_spi_remove(struct spi_device *spi)
static int ksz9477_spi_remove(struct spi_device *spi)
{
	struct ksz_device *dev = spi_get_drvdata(spi);

@@ -193,25 +144,34 @@ static int ksz_spi_remove(struct spi_device *spi)
	return 0;
}

static const struct of_device_id ksz_dt_ids[] = {
static void ksz9477_spi_shutdown(struct spi_device *spi)
{
	struct ksz_device *dev = spi_get_drvdata(spi);

	if (dev && dev->dev_ops->shutdown)
		dev->dev_ops->shutdown(dev);
}

static const struct of_device_id ksz9477_dt_ids[] = {
	{ .compatible = "microchip,ksz9477" },
	{ .compatible = "microchip,ksz9897" },
	{},
};
MODULE_DEVICE_TABLE(of, ksz_dt_ids);
MODULE_DEVICE_TABLE(of, ksz9477_dt_ids);

static struct spi_driver ksz_spi_driver = {
static struct spi_driver ksz9477_spi_driver = {
	.driver = {
		.name	= "ksz9477-switch",
		.owner	= THIS_MODULE,
		.of_match_table = of_match_ptr(ksz_dt_ids),
		.of_match_table = of_match_ptr(ksz9477_dt_ids),
	},
	.probe	= ksz_spi_probe,
	.remove	= ksz_spi_remove,
	.probe	= ksz9477_spi_probe,
	.remove	= ksz9477_spi_remove,
	.shutdown = ksz9477_spi_shutdown,
};

module_spi_driver(ksz_spi_driver);
module_spi_driver(ksz9477_spi_driver);

MODULE_AUTHOR("Woojung Huh <Woojung.Huh@microchip.com>");
MODULE_DESCRIPTION("Microchip KSZ Series Switch SPI access Driver");
MODULE_DESCRIPTION("Microchip KSZ9477 Series Switch SPI access Driver");
MODULE_LICENSE("GPL");
Loading