Commit 9a06cce6 authored by David S. Miller's avatar David S. Miller
Browse files

Merge branch 'dsa-microchip-ptp'

Arun Ramadoss says:

====================
net: dsa: microchip: add PTP support for KSZ9563/KSZ8563 and LAN937x

KSZ9563/KSZ8563 and  LAN937x switch are capable for supporting IEEE 1588 PTP
protocol.  LAN937x has the same PTP register set similar to KSZ9563, hence the
implementation has been made common for the KSZ switches.  KSZ9563 does not
support two step timestamping but LAN937x supports both.  Tested the 1step &
2step p2p timestamping in LAN937x and p2p1step timestamping in KSZ9563.

This patch series is based on the Christian Eggers PTP support for KSZ9563.
Applied the Christian patch and updated as per the latest refactoring of KSZ
series code. The features added on top are PTP packet Interrupt
implementation based on nested handler, LAN937x two step timestamping and
programmable per_out pins.

Link: https://www.spinics.net/lists/netdev/msg705531.html



Patch v7 -> v8
- set skb->ip_summed = CHECKSUM_NONE after updating the checksum

Patch v6 -> v7
- Corrected the misplaced spaces and tabs
- Added mutex lock in do_aux_work
- Replaced 0/1 with false/true for ts_en
- SKB_TX_INPROGRESS flag is set before dsa_enqueue_skb
- Removed the fallthrough keyword
- pdelay_resp header correction is performed based on
  KSZ_SKB_CB(skb)->update_correction instead of clone

Patch v5 -> v6
- Rebased to latest net-next and renamed from RFC to patch net-next.

Patch v4 -> v5
- Replaced irq_domain_add_simple with irq_doamin_add_linear
- Used the helper diff_by_scaled_ppm() for adjfine.

Patch v3 -> v4
- removed IRQF_TRIGGER_FALLING from the request_threaded_irq of ptp msg
- addressed review comments on patch 10 periodic output
- added sign off in patch 6 & 9
- reverted to set PTP_1STEP bit for lan937x which is missed during v3 regression

Patch v2-> v3
- used port_rxtstamp for reconstructing the absolute timestamp instead of
tagger function pointer.
- Reverted to setting of 802.1As bit.

Patch v1 -> v2
- GPIO perout enable bit is different for LAN937x and KSZ9x. Added new patch
for configuring LAN937x programmable pins.
- PTP enabled in hardware based on both tx and rx timestamping of all the user
ports.
- Replaced setting of 802.1AS bit with P2P bit in PTP_MSG_CONF1 register.

RFC v2 -> Patch v1
- Changed the patch author based on past patch submission
- Changed the commit message prefix as net: dsa: microchip: ptp
Individual patch changes are listed in correspondig commits.

RFC v1 -> v2
- Added the p2p1step timestamping and conditional execution of 2 step for
  LAN937x only.
- Added the periodic output support
====================

Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parents 72863e08 168a5940
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -13710,6 +13710,7 @@ S: Maintained
F:	Documentation/devicetree/bindings/net/dsa/microchip,ksz.yaml
F:	Documentation/devicetree/bindings/net/dsa/microchip,lan937x.yaml
F:	drivers/net/dsa/microchip/*
F:	include/linux/dsa/ksz_common.h
F:	include/linux/platform_data/microchip-ksz.h
F:	net/dsa/tag_ksz.c
+11 −0
Original line number Diff line number Diff line
@@ -11,6 +11,7 @@ menuconfig NET_DSA_MICROCHIP_KSZ_COMMON
config NET_DSA_MICROCHIP_KSZ9477_I2C
	tristate "KSZ series I2C connected switch driver"
	depends on NET_DSA_MICROCHIP_KSZ_COMMON && I2C
	depends on PTP_1588_CLOCK_OPTIONAL
	select REGMAP_I2C
	help
	  Select to enable support for registering switches configured through I2C.
@@ -18,10 +19,20 @@ config NET_DSA_MICROCHIP_KSZ9477_I2C
config NET_DSA_MICROCHIP_KSZ_SPI
	tristate "KSZ series SPI connected switch driver"
	depends on NET_DSA_MICROCHIP_KSZ_COMMON && SPI
	depends on PTP_1588_CLOCK_OPTIONAL
	select REGMAP_SPI
	help
	  Select to enable support for registering switches configured through SPI.

config NET_DSA_MICROCHIP_KSZ_PTP
	bool "Support for the PTP clock on the KSZ9563/LAN937x Ethernet Switch"
	depends on NET_DSA_MICROCHIP_KSZ_COMMON && PTP_1588_CLOCK
	help
	  Select to enable support for timestamping & PTP clock manipulation in
	  KSZ8563/KSZ9563/LAN937x series of switches. KSZ9563/KSZ8563 supports
	  only one step timestamping. LAN937x switch supports both one step and
	  two step timestamping.

config NET_DSA_MICROCHIP_KSZ8863_SMI
	tristate "KSZ series SMI connected switch driver"
	depends on NET_DSA_MICROCHIP_KSZ_COMMON
+5 −0
Original line number Diff line number Diff line
@@ -4,6 +4,11 @@ ksz_switch-objs := ksz_common.o
ksz_switch-objs += ksz9477.o
ksz_switch-objs += ksz8795.o
ksz_switch-objs += lan937x_main.o

ifdef CONFIG_NET_DSA_MICROCHIP_KSZ_PTP
ksz_switch-objs += ksz_ptp.o
endif

obj-$(CONFIG_NET_DSA_MICROCHIP_KSZ9477_I2C)	+= ksz9477_i2c.o
obj-$(CONFIG_NET_DSA_MICROCHIP_KSZ_SPI)		+= ksz_spi.o
obj-$(CONFIG_NET_DSA_MICROCHIP_KSZ8863_SMI)	+= ksz8863_smi.o
+42 −2
Original line number Diff line number Diff line
@@ -6,6 +6,7 @@
 */

#include <linux/delay.h>
#include <linux/dsa/ksz_common.h>
#include <linux/export.h>
#include <linux/gpio/consumer.h>
#include <linux/kernel.h>
@@ -25,6 +26,7 @@
#include <net/switchdev.h>

#include "ksz_common.h"
#include "ksz_ptp.h"
#include "ksz8.h"
#include "ksz9477.h"
#include "lan937x.h"
@@ -2099,13 +2101,23 @@ static int ksz_setup(struct dsa_switch *ds)
			ret = ksz_pirq_setup(dev, dp->index);
			if (ret)
				goto out_girq;

			ret = ksz_ptp_irq_setup(ds, dp->index);
			if (ret)
				goto out_pirq;
		}
	}

	ret = ksz_ptp_clock_register(ds);
	if (ret) {
		dev_err(dev->dev, "Failed to register PTP clock: %d\n", ret);
		goto out_ptpirq;
	}

	ret = ksz_mdio_register(dev);
	if (ret < 0) {
		dev_err(dev->dev, "failed to register the mdio");
		goto out_pirq;
		goto out_ptp_clock_unregister;
	}

	/* start switch */
@@ -2114,6 +2126,12 @@ static int ksz_setup(struct dsa_switch *ds)

	return 0;

out_ptp_clock_unregister:
	ksz_ptp_clock_unregister(ds);
out_ptpirq:
	if (dev->irq > 0)
		dsa_switch_for_each_user_port(dp, dev->ds)
			ksz_ptp_irq_free(ds, dp->index);
out_pirq:
	if (dev->irq > 0)
		dsa_switch_for_each_user_port(dp, dev->ds)
@@ -2130,9 +2148,14 @@ static void ksz_teardown(struct dsa_switch *ds)
	struct ksz_device *dev = ds->priv;
	struct dsa_port *dp;

	ksz_ptp_clock_unregister(ds);

	if (dev->irq > 0) {
		dsa_switch_for_each_user_port(dp, dev->ds)
		dsa_switch_for_each_user_port(dp, dev->ds) {
			ksz_ptp_irq_free(ds, dp->index);

			ksz_irq_free(&dev->ports[dp->index].pirq);
		}

		ksz_irq_free(&dev->girq);
	}
@@ -2517,6 +2540,17 @@ static enum dsa_tag_protocol ksz_get_tag_protocol(struct dsa_switch *ds,
	return proto;
}

static int ksz_connect_tag_protocol(struct dsa_switch *ds,
				    enum dsa_tag_protocol proto)
{
	struct ksz_tagger_data *tagger_data;

	tagger_data = ksz_tagger_data(ds);
	tagger_data->xmit_work_fn = ksz_port_deferred_xmit;

	return 0;
}

static int ksz_port_vlan_filtering(struct dsa_switch *ds, int port,
				   bool flag, struct netlink_ext_ack *extack)
{
@@ -2932,6 +2966,7 @@ static int ksz_switch_detect(struct ksz_device *dev)

static const struct dsa_switch_ops ksz_switch_ops = {
	.get_tag_protocol	= ksz_get_tag_protocol,
	.connect_tag_protocol   = ksz_connect_tag_protocol,
	.get_phy_flags		= ksz_get_phy_flags,
	.setup			= ksz_setup,
	.teardown		= ksz_teardown,
@@ -2966,6 +3001,11 @@ static const struct dsa_switch_ops ksz_switch_ops = {
	.get_pause_stats	= ksz_get_pause_stats,
	.port_change_mtu	= ksz_change_mtu,
	.port_max_mtu		= ksz_max_mtu,
	.get_ts_info		= ksz_get_ts_info,
	.port_hwtstamp_get	= ksz_hwtstamp_get,
	.port_hwtstamp_set	= ksz_hwtstamp_set,
	.port_txtstamp		= ksz_port_txtstamp,
	.port_rxtstamp		= ksz_port_rxtstamp,
};

struct ksz_device *ksz_switch_alloc(struct device *base, void *priv)
+48 −0
Original line number Diff line number Diff line
@@ -15,9 +15,12 @@
#include <net/dsa.h>
#include <linux/irq.h>

#include "ksz_ptp.h"

#define KSZ_MAX_NUM_PORTS 8

struct ksz_device;
struct ksz_port;

struct vlan_table {
	u32 table[3];
@@ -81,6 +84,14 @@ struct ksz_irq {
	struct ksz_device *dev;
};

struct ksz_ptp_irq {
	struct ksz_port *port;
	u16 ts_reg;
	bool ts_en;
	char name[16];
	int num;
};

struct ksz_port {
	bool remove_tag;		/* Remove Tag flag set, for ksz8795 only */
	bool learning;
@@ -100,6 +111,15 @@ struct ksz_port {
	struct ksz_device *ksz_dev;
	struct ksz_irq pirq;
	u8 num;
#if IS_ENABLED(CONFIG_NET_DSA_MICROCHIP_KSZ_PTP)
	struct hwtstamp_config tstamp_config;
	bool hwts_tx_en;
	bool hwts_rx_en;
	struct ksz_irq ptpirq;
	struct ksz_ptp_irq ptpmsg_irq[3];
	ktime_t tstamp_msg;
	struct completion tstamp_msg_comp;
#endif
};

struct ksz_device {
@@ -140,6 +160,7 @@ struct ksz_device {
	u16 port_mask;
	struct mutex lock_irq;		/* IRQ Access */
	struct ksz_irq girq;
	struct ksz_ptp_data ptp_data;
};

/* List of supported models */
@@ -443,6 +464,32 @@ static inline int ksz_write32(struct ksz_device *dev, u32 reg, u32 value)
	return ret;
}

static inline int ksz_rmw16(struct ksz_device *dev, u32 reg, u16 mask,
			    u16 value)
{
	int ret;

	ret = regmap_update_bits(dev->regmap[1], reg, mask, value);
	if (ret)
		dev_err(dev->dev, "can't rmw 16bit reg 0x%x: %pe\n", reg,
			ERR_PTR(ret));

	return ret;
}

static inline int ksz_rmw32(struct ksz_device *dev, u32 reg, u32 mask,
			    u32 value)
{
	int ret;

	ret = regmap_update_bits(dev->regmap[2], reg, mask, value);
	if (ret)
		dev_err(dev->dev, "can't rmw 32bit reg 0x%x: %pe\n", reg,
			ERR_PTR(ret));

	return ret;
}

static inline int ksz_write64(struct ksz_device *dev, u32 reg, u64 value)
{
	u32 val[2];
@@ -591,6 +638,7 @@ static inline int is_lan937x(struct ksz_device *dev)
#define REG_PORT_INT_MASK		0x001F

#define PORT_SRC_PHY_INT		1
#define PORT_SRC_PTP_INT		2

#define KSZ8795_HUGE_PACKET_SIZE	2000
#define KSZ8863_HUGE_PACKET_SIZE	1916
Loading