* [PATCH net-next 0/8] net: mscc: PTP offloading support
@ 2019-01-17 10:02 Antoine Tenart
2019-01-17 10:02 ` [PATCH net-next 1/8] Documentation/bindings: net: ocelot: document the VCAP and PTP banks Antoine Tenart
` (9 more replies)
0 siblings, 10 replies; 16+ messages in thread
From: Antoine Tenart @ 2019-01-17 10:02 UTC (permalink / raw)
To: davem, alexandre.belloni, UNGLinuxDriver, ralf, paul.burton, jhogan
Cc: Antoine Tenart, netdev, linux-mips, thomas.petazzoni,
quentin.schulz, allan.nielsen
Hi all,
This series adds support for the PTP offloading support in the Mscc
Ocelot Ethernet switch driver. Both PTP 1-step and 2-step modes are
supported.
In order to make use of the PTP offloading support, two new register
banks were described in the Ocelot device tree. The use of those
registers by the Mscc Ocelot Ethernet switch driver is made optional for
dt compatibility reasons. For the same reason a new interrupt is
described, and its use is also made optinal for compatibility reasons.
All of this is done ine patches 1-5.
The PTP offloading support itself is added in patch 8.
While doing this support, a few reworks were done in the Ocelot switch
driver, in patches 6-7.
Patches 2 and 4 should probably go through the MIPS tree.
Thanks!
Antoine
Antoine Tenart (8):
Documentation/bindings: net: ocelot: document the VCAP and PTP banks
MIPS: dts: mscc: describe VCAP and PTP register ranges
Documentation/bindings: net: ocelot: document the PTP ready IRQ
MIPS: dts: mscc: describe the PTP ready interrupt
net: mscc: describe the VCAP and PTP register ranges
net: mscc: improve the frame header parsing readability
net: mscc: remove the frame_info cpuq member
net: mscc: PTP offloading support
.../devicetree/bindings/net/mscc-ocelot.txt | 22 +-
arch/mips/boot/dts/mscc/ocelot.dtsi | 14 +-
drivers/net/ethernet/mscc/ocelot.c | 509 +++++++++++++++++-
drivers/net/ethernet/mscc/ocelot.h | 55 +-
drivers/net/ethernet/mscc/ocelot_board.c | 150 +++++-
drivers/net/ethernet/mscc/ocelot_ptp.h | 41 ++
drivers/net/ethernet/mscc/ocelot_regs.c | 22 +
drivers/net/ethernet/mscc/ocelot_vcap.h | 104 ++++
8 files changed, 877 insertions(+), 40 deletions(-)
create mode 100644 drivers/net/ethernet/mscc/ocelot_ptp.h
create mode 100644 drivers/net/ethernet/mscc/ocelot_vcap.h
--
2.20.1
^ permalink raw reply [flat|nested] 16+ messages in thread
* [PATCH net-next 1/8] Documentation/bindings: net: ocelot: document the VCAP and PTP banks
2019-01-17 10:02 [PATCH net-next 0/8] net: mscc: PTP offloading support Antoine Tenart
@ 2019-01-17 10:02 ` Antoine Tenart
2019-01-17 10:02 ` [PATCH net-next 2/8] MIPS: dts: mscc: describe VCAP and PTP register ranges Antoine Tenart
` (8 subsequent siblings)
9 siblings, 0 replies; 16+ messages in thread
From: Antoine Tenart @ 2019-01-17 10:02 UTC (permalink / raw)
To: davem, alexandre.belloni, UNGLinuxDriver, ralf, paul.burton, jhogan
Cc: Antoine Tenart, netdev, linux-mips, thomas.petazzoni,
quentin.schulz, allan.nielsen
Two additional register ranges needs to be described within the Ocelot
device tree node: the VCAP and the PTP ones. This patch documents the
binding needed to do so.
Signed-off-by: Antoine Tenart <antoine.tenart@bootlin.com>
---
Documentation/devicetree/bindings/net/mscc-ocelot.txt | 11 ++++++++---
1 file changed, 8 insertions(+), 3 deletions(-)
diff --git a/Documentation/devicetree/bindings/net/mscc-ocelot.txt b/Documentation/devicetree/bindings/net/mscc-ocelot.txt
index 9e5c17d426ce..08bc8d7f0c99 100644
--- a/Documentation/devicetree/bindings/net/mscc-ocelot.txt
+++ b/Documentation/devicetree/bindings/net/mscc-ocelot.txt
@@ -11,7 +11,9 @@ Required properties:
- reg-names: Must include the following entries:
- "sys"
- "rew"
+ - "vcap"
- "qs"
+ - "ptp"
- "qsys"
- "ana"
- "portX" with X from 0 to the number of last port index available on that
@@ -43,7 +45,9 @@ Example:
compatible = "mscc,vsc7514-switch";
reg = <0x1010000 0x10000>,
<0x1030000 0x10000>,
+ <0x1060000 0x10000>,
<0x1080000 0x100>,
+ <0x10e0000 0x10000>,
<0x11e0000 0x100>,
<0x11f0000 0x100>,
<0x1200000 0x100>,
@@ -57,9 +61,10 @@ Example:
<0x1280000 0x100>,
<0x1800000 0x80000>,
<0x1880000 0x10000>;
- reg-names = "sys", "rew", "qs", "port0", "port1", "port2",
- "port3", "port4", "port5", "port6", "port7",
- "port8", "port9", "port10", "qsys", "ana";
+ reg-names = "sys", "rew", "vcap", "qs", "ptp", "port0",
+ "port1", "port2", "port3", "port4", "port5",
+ "port6", "port7", "port8", "port9", "port10",
+ "qsys", "ana";
interrupts = <21 22>;
interrupt-names = "xtr", "inj";
--
2.20.1
^ permalink raw reply related [flat|nested] 16+ messages in thread
* [PATCH net-next 2/8] MIPS: dts: mscc: describe VCAP and PTP register ranges
2019-01-17 10:02 [PATCH net-next 0/8] net: mscc: PTP offloading support Antoine Tenart
2019-01-17 10:02 ` [PATCH net-next 1/8] Documentation/bindings: net: ocelot: document the VCAP and PTP banks Antoine Tenart
@ 2019-01-17 10:02 ` Antoine Tenart
2019-01-17 10:02 ` [PATCH net-next 3/8] Documentation/bindings: net: ocelot: document the PTP ready IRQ Antoine Tenart
` (7 subsequent siblings)
9 siblings, 0 replies; 16+ messages in thread
From: Antoine Tenart @ 2019-01-17 10:02 UTC (permalink / raw)
To: davem, alexandre.belloni, UNGLinuxDriver, ralf, paul.burton, jhogan
Cc: Antoine Tenart, netdev, linux-mips, thomas.petazzoni,
quentin.schulz, allan.nielsen
This patch adds two register ranges within the mscc,vsc7514-switch node,
to describe the VCAP and PTP registers.
Signed-off-by: Antoine Tenart <antoine.tenart@bootlin.com>
---
arch/mips/boot/dts/mscc/ocelot.dtsi | 10 ++++++----
1 file changed, 6 insertions(+), 4 deletions(-)
diff --git a/arch/mips/boot/dts/mscc/ocelot.dtsi b/arch/mips/boot/dts/mscc/ocelot.dtsi
index 90c60d42f571..bb81652bebe8 100644
--- a/arch/mips/boot/dts/mscc/ocelot.dtsi
+++ b/arch/mips/boot/dts/mscc/ocelot.dtsi
@@ -119,7 +119,9 @@
compatible = "mscc,vsc7514-switch";
reg = <0x1010000 0x10000>,
<0x1030000 0x10000>,
+ <0x1060000 0x10000>,
<0x1080000 0x100>,
+ <0x10e0000 0x10000>,
<0x11e0000 0x100>,
<0x11f0000 0x100>,
<0x1200000 0x100>,
@@ -133,10 +135,10 @@
<0x1280000 0x100>,
<0x1800000 0x80000>,
<0x1880000 0x10000>;
- reg-names = "sys", "rew", "qs", "port0", "port1",
- "port2", "port3", "port4", "port5", "port6",
- "port7", "port8", "port9", "port10", "qsys",
- "ana";
+ reg-names = "sys", "rew", "vcap", "qs", "ptp", "port0",
+ "port1", "port2", "port3", "port4", "port5",
+ "port6", "port7", "port8", "port9",
+ "port10", "qsys", "ana";
interrupts = <21 22>;
interrupt-names = "xtr", "inj";
--
2.20.1
^ permalink raw reply related [flat|nested] 16+ messages in thread
* [PATCH net-next 3/8] Documentation/bindings: net: ocelot: document the PTP ready IRQ
2019-01-17 10:02 [PATCH net-next 0/8] net: mscc: PTP offloading support Antoine Tenart
2019-01-17 10:02 ` [PATCH net-next 1/8] Documentation/bindings: net: ocelot: document the VCAP and PTP banks Antoine Tenart
2019-01-17 10:02 ` [PATCH net-next 2/8] MIPS: dts: mscc: describe VCAP and PTP register ranges Antoine Tenart
@ 2019-01-17 10:02 ` Antoine Tenart
2019-01-17 10:02 ` [PATCH net-next 4/8] MIPS: dts: mscc: describe the PTP ready interrupt Antoine Tenart
` (6 subsequent siblings)
9 siblings, 0 replies; 16+ messages in thread
From: Antoine Tenart @ 2019-01-17 10:02 UTC (permalink / raw)
To: davem, alexandre.belloni, UNGLinuxDriver, ralf, paul.burton, jhogan
Cc: Antoine Tenart, netdev, linux-mips, thomas.petazzoni,
quentin.schulz, allan.nielsen
One additional interrupt needs to be described within the Ocelot device
tree node: the PTP ready one. This patch documents the binding needed to
do so.
Signed-off-by: Antoine Tenart <antoine.tenart@bootlin.com>
---
Documentation/devicetree/bindings/net/mscc-ocelot.txt | 11 ++++++-----
1 file changed, 6 insertions(+), 5 deletions(-)
diff --git a/Documentation/devicetree/bindings/net/mscc-ocelot.txt b/Documentation/devicetree/bindings/net/mscc-ocelot.txt
index 08bc8d7f0c99..aa33066f3403 100644
--- a/Documentation/devicetree/bindings/net/mscc-ocelot.txt
+++ b/Documentation/devicetree/bindings/net/mscc-ocelot.txt
@@ -18,9 +18,10 @@ Required properties:
- "ana"
- "portX" with X from 0 to the number of last port index available on that
switch
-- interrupts: Should contain the switch interrupts for frame extraction and
- frame injection
-- interrupt-names: should contain the interrupt names: "xtr", "inj"
+- interrupts: Should contain the switch interrupts for frame extraction,
+ frame injection and PTP ready.
+- interrupt-names: should contain the interrupt names: "xtr", "inj" and
+ "ptp_rdy".
- ethernet-ports: A container for child nodes representing switch ports.
The ethernet-ports container has the following properties
@@ -65,8 +66,8 @@ Example:
"port1", "port2", "port3", "port4", "port5",
"port6", "port7", "port8", "port9", "port10",
"qsys", "ana";
- interrupts = <21 22>;
- interrupt-names = "xtr", "inj";
+ interrupts = <18 21 22>;
+ interrupt-names = "ptp_rdy", "xtr", "inj";
ethernet-ports {
#address-cells = <1>;
--
2.20.1
^ permalink raw reply related [flat|nested] 16+ messages in thread
* [PATCH net-next 4/8] MIPS: dts: mscc: describe the PTP ready interrupt
2019-01-17 10:02 [PATCH net-next 0/8] net: mscc: PTP offloading support Antoine Tenart
` (2 preceding siblings ...)
2019-01-17 10:02 ` [PATCH net-next 3/8] Documentation/bindings: net: ocelot: document the PTP ready IRQ Antoine Tenart
@ 2019-01-17 10:02 ` Antoine Tenart
2019-01-17 10:02 ` [PATCH net-next 5/8] net: mscc: describe the VCAP and PTP register ranges Antoine Tenart
` (5 subsequent siblings)
9 siblings, 0 replies; 16+ messages in thread
From: Antoine Tenart @ 2019-01-17 10:02 UTC (permalink / raw)
To: davem, alexandre.belloni, UNGLinuxDriver, ralf, paul.burton, jhogan
Cc: Antoine Tenart, netdev, linux-mips, thomas.petazzoni,
quentin.schulz, allan.nielsen
This patch adds a description of the PTP ready interrupt, which can be
triggered when a PTP timestamp is available on an hardware FIFO.
Signed-off-by: Antoine Tenart <antoine.tenart@bootlin.com>
---
arch/mips/boot/dts/mscc/ocelot.dtsi | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/arch/mips/boot/dts/mscc/ocelot.dtsi b/arch/mips/boot/dts/mscc/ocelot.dtsi
index bb81652bebe8..0bf5fa11c4e7 100644
--- a/arch/mips/boot/dts/mscc/ocelot.dtsi
+++ b/arch/mips/boot/dts/mscc/ocelot.dtsi
@@ -139,8 +139,8 @@
"port1", "port2", "port3", "port4", "port5",
"port6", "port7", "port8", "port9",
"port10", "qsys", "ana";
- interrupts = <21 22>;
- interrupt-names = "xtr", "inj";
+ interrupts = <18 21 22>;
+ interrupt-names = "ptp_rdy", "xtr", "inj";
ethernet-ports {
#address-cells = <1>;
--
2.20.1
^ permalink raw reply related [flat|nested] 16+ messages in thread
* [PATCH net-next 5/8] net: mscc: describe the VCAP and PTP register ranges
2019-01-17 10:02 [PATCH net-next 0/8] net: mscc: PTP offloading support Antoine Tenart
` (3 preceding siblings ...)
2019-01-17 10:02 ` [PATCH net-next 4/8] MIPS: dts: mscc: describe the PTP ready interrupt Antoine Tenart
@ 2019-01-17 10:02 ` Antoine Tenart
2019-01-17 10:02 ` [PATCH net-next 6/8] net: mscc: improve the frame header parsing readability Antoine Tenart
` (4 subsequent siblings)
9 siblings, 0 replies; 16+ messages in thread
From: Antoine Tenart @ 2019-01-17 10:02 UTC (permalink / raw)
To: davem, alexandre.belloni, UNGLinuxDriver, ralf, paul.burton, jhogan
Cc: Antoine Tenart, netdev, linux-mips, thomas.petazzoni,
quentin.schulz, allan.nielsen
This patch adds support for using the VCAP and PTP register ranges, and
adds a description of their registers. Those banks are used when
configuring PTP.
Signed-off-by: Antoine Tenart <antoine.tenart@bootlin.com>
---
drivers/net/ethernet/mscc/ocelot.h | 18 ++++
drivers/net/ethernet/mscc/ocelot_board.c | 21 +++--
drivers/net/ethernet/mscc/ocelot_ptp.h | 41 +++++++++
drivers/net/ethernet/mscc/ocelot_regs.c | 22 +++++
drivers/net/ethernet/mscc/ocelot_vcap.h | 104 +++++++++++++++++++++++
5 files changed, 200 insertions(+), 6 deletions(-)
create mode 100644 drivers/net/ethernet/mscc/ocelot_ptp.h
create mode 100644 drivers/net/ethernet/mscc/ocelot_vcap.h
diff --git a/drivers/net/ethernet/mscc/ocelot.h b/drivers/net/ethernet/mscc/ocelot.h
index 086775f7b52f..4b1b180884ad 100644
--- a/drivers/net/ethernet/mscc/ocelot.h
+++ b/drivers/net/ethernet/mscc/ocelot.h
@@ -22,6 +22,8 @@
#include "ocelot_rew.h"
#include "ocelot_sys.h"
#include "ocelot_qs.h"
+#include "ocelot_ptp.h"
+#include "ocelot_vcap.h"
#define PGID_AGGR 64
#define PGID_SRC 80
@@ -69,6 +71,8 @@ enum ocelot_target {
REW,
SYS,
HSIO,
+ PTP,
+ VCAP,
TARGET_MAX,
};
@@ -334,6 +338,20 @@ enum ocelot_reg {
SYS_CM_DATA_RD,
SYS_CM_OP,
SYS_CM_DATA,
+ PTP_PIN_CFG = PTP << TARGET_OFFSET,
+ PTP_PIN_TOD_SEC_MSB,
+ PTP_PIN_TOD_SEC_LSB,
+ PTP_PIN_TOD_NSEC,
+ PTP_CFG_MISC,
+ PTP_CLK_CFG_ADJ_CFG,
+ PTP_CLK_CFG_ADJ_FREQ,
+ VCAP_UPDATE_CTRL = VCAP << TARGET_OFFSET,
+ VCAP_UPDATE_CTRL_MV_CFG,
+ VCAP_UPDATE_CTRL_ENTRY_DATA,
+ VCAP_UPDATE_CTRL_MASK_DATA,
+ VCAP_UPDATE_CTRL_ACTION_DATA,
+ VCAP_UPDATE_CTRL_COUNTER_DATA,
+ VCAP_CACHE_DATA_TYPE,
};
enum ocelot_regfield {
diff --git a/drivers/net/ethernet/mscc/ocelot_board.c b/drivers/net/ethernet/mscc/ocelot_board.c
index ca3ea2fbfcd0..ba7c93c4318a 100644
--- a/drivers/net/ethernet/mscc/ocelot_board.c
+++ b/drivers/net/ethernet/mscc/ocelot_board.c
@@ -182,12 +182,15 @@ static int mscc_ocelot_probe(struct platform_device *pdev)
struct {
enum ocelot_target id;
char *name;
+ u8 optional:1;
} res[] = {
- { SYS, "sys" },
- { REW, "rew" },
- { QSYS, "qsys" },
- { ANA, "ana" },
- { QS, "qs" },
+ { SYS, "sys", 0 },
+ { REW, "rew", 0 },
+ { QSYS, "qsys", 0 },
+ { ANA, "ana", 0 },
+ { QS, "qs", 0 },
+ { PTP, "ptp", 1 },
+ { VCAP, "vcap", 1 },
};
if (!np && !pdev->dev.platform_data)
@@ -204,8 +207,14 @@ static int mscc_ocelot_probe(struct platform_device *pdev)
struct regmap *target;
target = ocelot_io_platform_init(ocelot, pdev, res[i].name);
- if (IS_ERR(target))
+ if (IS_ERR(target)) {
+ if (res[i].optional) {
+ ocelot->targets[res[i].id] = NULL;
+ continue;
+ }
+
return PTR_ERR(target);
+ }
ocelot->targets[res[i].id] = target;
}
diff --git a/drivers/net/ethernet/mscc/ocelot_ptp.h b/drivers/net/ethernet/mscc/ocelot_ptp.h
new file mode 100644
index 000000000000..9ede14a12573
--- /dev/null
+++ b/drivers/net/ethernet/mscc/ocelot_ptp.h
@@ -0,0 +1,41 @@
+/* SPDX-License-Identifier: (GPL-2.0 OR MIT) */
+/*
+ * Microsemi Ocelot Switch driver
+ *
+ * License: Dual MIT/GPL
+ * Copyright (c) 2017 Microsemi Corporation
+ */
+
+#ifndef _MSCC_OCELOT_PTP_H_
+#define _MSCC_OCELOT_PTP_H_
+
+#define PTP_PIN_CFG_RSZ 0x20
+#define PTP_PIN_TOD_SEC_MSB_RSZ PTP_PIN_CFG_RSZ
+#define PTP_PIN_TOD_SEC_LSB_RSZ PTP_PIN_CFG_RSZ
+#define PTP_PIN_TOD_NSEC_RSZ PTP_PIN_CFG_RSZ
+
+#define PTP_PIN_CFG_DOM BIT(0)
+#define PTP_PIN_CFG_SYNC BIT(2)
+#define PTP_PIN_CFG_ACTION(x) ((x) << 3)
+#define PTP_PIN_CFG_ACTION_MASK PTP_PIN_CFG_ACTION(0x7)
+
+enum {
+ PTP_PIN_ACTION_IDLE = 0,
+ PTP_PIN_ACTION_LOAD,
+ PTP_PIN_ACTION_SAVE,
+ PTP_PIN_ACTION_CLOCK,
+ PTP_PIN_ACTION_DELTA,
+ PTP_PIN_ACTION_NOSYNC,
+ PTP_PIN_ACTION_SYNC,
+};
+
+#define PTP_CFG_MISC_PTP_EN BIT(2)
+
+#define PSEC_PER_SEC 1000000000000LL
+
+#define PTP_CFG_CLK_ADJ_CFG_ENA BIT(0)
+#define PTP_CFG_CLK_ADJ_CFG_DIR BIT(1)
+
+#define PTP_CFG_CLK_ADJ_FREQ_NS BIT(30)
+
+#endif
diff --git a/drivers/net/ethernet/mscc/ocelot_regs.c b/drivers/net/ethernet/mscc/ocelot_regs.c
index 9271af18b93b..bbba0f7a6962 100644
--- a/drivers/net/ethernet/mscc/ocelot_regs.c
+++ b/drivers/net/ethernet/mscc/ocelot_regs.c
@@ -224,12 +224,34 @@ static const u32 ocelot_sys_regmap[] = {
REG(SYS_PTP_CFG, 0x0006c4),
};
+static const u32 ocelot_ptp_regmap[] = {
+ REG(PTP_PIN_CFG, 0x000000),
+ REG(PTP_PIN_TOD_SEC_MSB, 0x000004),
+ REG(PTP_PIN_TOD_SEC_LSB, 0x000008),
+ REG(PTP_PIN_TOD_NSEC, 0x00000c),
+ REG(PTP_CFG_MISC, 0x0000a0),
+ REG(PTP_CLK_CFG_ADJ_CFG, 0x0000a4),
+ REG(PTP_CLK_CFG_ADJ_FREQ, 0x0000a8),
+};
+
+static const u32 ocelot_vcap_regmap[] = {
+ REG(VCAP_UPDATE_CTRL, 0x000000),
+ REG(VCAP_UPDATE_CTRL_MV_CFG, 0x000004),
+ REG(VCAP_UPDATE_CTRL_ENTRY_DATA, 0x000008),
+ REG(VCAP_UPDATE_CTRL_MASK_DATA, 0x000108),
+ REG(VCAP_UPDATE_CTRL_ACTION_DATA, 0x000208),
+ REG(VCAP_UPDATE_CTRL_COUNTER_DATA, 0x000308),
+ REG(VCAP_CACHE_DATA_TYPE, 0x000388),
+};
+
static const u32 *ocelot_regmap[] = {
[ANA] = ocelot_ana_regmap,
[QS] = ocelot_qs_regmap,
[QSYS] = ocelot_qsys_regmap,
[REW] = ocelot_rew_regmap,
[SYS] = ocelot_sys_regmap,
+ [PTP] = ocelot_ptp_regmap,
+ [VCAP] = ocelot_vcap_regmap,
};
static const struct reg_field ocelot_regfields[] = {
diff --git a/drivers/net/ethernet/mscc/ocelot_vcap.h b/drivers/net/ethernet/mscc/ocelot_vcap.h
new file mode 100644
index 000000000000..836bf0a96a73
--- /dev/null
+++ b/drivers/net/ethernet/mscc/ocelot_vcap.h
@@ -0,0 +1,104 @@
+/* SPDX-License-Identifier: (GPL-2.0 OR MIT) */
+/*
+ * Microsemi Ocelot Switch driver
+ *
+ * Copyright (c) 2018 Microsemi Corporation
+ */
+
+#ifndef _MSCC_OCELOT_VCAP_H_
+#define _MSCC_OCELOT_VCAP_H_
+
+/* Three PTP entries per port:
+ * - PTP ver Ethernet
+ * - PTP dst port 319
+ * - PTP dst port 320
+ */
+#define VCAP_IS2_N_PTP_ENTRIES 3
+
+/* VCAP */
+
+#define VCAP_UPDATE_CTRL_UPDATE_SHOT BIT(2)
+#define VCAP_UPDATE_CTRL_UPDATE_ADDR(x) (((x) & 0x3) << 16)
+#define VCAP_UPDATE_CTRL_UPDATE_COUNTER_DIS BIT(19)
+#define VCAP_UPDATE_CTRL_UPDATE_ACTION_DIS BIT(20)
+#define VCAP_UPDATE_CTRL_UPDATE_ENTRY_DIS BIT(21)
+#define VCAP_UPDATE_CTRL_UPDATE_CMD(x) (((x) & 0x3) << 22)
+
+enum vcap_cmds {
+ VCAP_CMD_WRITE = 0,
+ VCAP_CMD_READ,
+ VCAP_CMD_MOVE_UP,
+ VCAP_CMD_MOVE_DOWN,
+ VCAP_CMD_INIT,
+};
+
+enum vcap_selector {
+ VCAP_SEL_COUNTER = BIT(0),
+ VCAP_SEL_ACTION = BIT(1),
+ VCAP_SEL_ENTRY = BIT(2),
+};
+
+struct vcap_data {
+ u32 entry[12];
+ u32 mask[12];
+ u32 action[4];
+ u32 counter;
+ u32 type_group;
+};
+
+/* VCAP IS2 lookup */
+
+#define VCAP_IS2_LKP_TYPE 0
+#define VCAP_IS2_LKP_INGRESS_PORT_MASK 13
+#define VCAP_IS2_LKP_MC 27
+#define VCAP_IS2_LKP_BC 28
+#define VCAP_IS2_LKP_VLAN 29
+#define VCAP_IS2_LKP_VID 30
+#define VCAP_IS2_LKP_IP4 46
+#define VCAP_IS2_LKP_DST_IP4 59
+#define VCAP_IS2_LKP_SRC_IP4 91
+#define VCAP_IS2_LKP_TCP 124
+#define VCAP_IS2_LKP_DPORT 125
+#define VCAP_IS2_LKP_SPORT 141
+#define VCAP_IS2_LKP_ETYPE 142
+
+/* Masks */
+#define VCAP_IS2_LKP_TYPE_M 0xf
+#define VCAP_IS2_LKP_INGRESS_PORT_MASK_M 0xfff
+#define VCAP_IS2_LKP_VID_M 0xfff
+#define VCAP_IS2_LKP_DST_IP4_M 0xffffffff
+#define VCAP_IS2_LKP_SRC_IP4_M 0xffffffff
+#define VCAP_IS2_LKP_DPORT_M 0xffff
+#define VCAP_IS2_LKP_SPORT_M 0xffff
+#define VCAP_IS2_LKP_ETYPE_M 0xffff
+
+/* IS2 lookup types */
+#define VCAP_IS2_LKP_TYPE_MAC_ETYPE 0
+#define VCAP_IS2_LKP_TYPE_TCP_UDP 4
+
+/* VCAP IS2 action */
+
+#define VCAP_IS2_ACT_MASK_MODE 5
+#define VCAP_IS2_ACT_PORT_MASK 20
+#define VCAP_IS2_ACT_REW_OP 31
+
+/* Masks */
+#define VCAP_IS2_ACT_PORT_MASK_M 0x7ff
+#define VCAP_IS2_ACT_REW_OP_M 0x1ff
+
+/* IS2 mask modes */
+#define VCAP_IS2_ACT_MASK_MODE_NOOP 0x0
+#define VCAP_IS2_ACT_MASK_MODE_FILTER 0x1
+
+/* IS2 REW OPS */
+#define VCAP_IS2_ACT_REW_OP_NOOP 0x0
+#define VCAP_IS2_ACT_REW_OP_PTP_ONE 0x2
+#define VCAP_IS2_ACT_REW_OP_PTP_TWO 0x3
+
+/* In addition to VCAP_IS2_REW_OP_PTP_ONE */
+#define VCAP_IS2_ACT_REW_OP_SUB_DELAY_1 (0x1 << 3)
+#define VCAP_IS2_ACT_REW_OP_SUB_DELAY_2 (0x2 << 3)
+#define VCAP_IS2_ACT_REW_OP_ADD_DELAY (0x1 << 5)
+#define VCAP_IS2_ACT_REW_OP_ADD_SUB (0x1 << 7)
+
+#endif
--
2.20.1
^ permalink raw reply related [flat|nested] 16+ messages in thread
* [PATCH net-next 6/8] net: mscc: improve the frame header parsing readability
2019-01-17 10:02 [PATCH net-next 0/8] net: mscc: PTP offloading support Antoine Tenart
` (4 preceding siblings ...)
2019-01-17 10:02 ` [PATCH net-next 5/8] net: mscc: describe the VCAP and PTP register ranges Antoine Tenart
@ 2019-01-17 10:02 ` Antoine Tenart
2019-01-17 10:02 ` [PATCH net-next 7/8] net: mscc: remove the frame_info cpuq member Antoine Tenart
` (3 subsequent siblings)
9 siblings, 0 replies; 16+ messages in thread
From: Antoine Tenart @ 2019-01-17 10:02 UTC (permalink / raw)
To: davem, alexandre.belloni, UNGLinuxDriver, ralf, paul.burton, jhogan
Cc: Antoine Tenart, netdev, linux-mips, thomas.petazzoni,
quentin.schulz, allan.nielsen
This cosmetic patch improves the frame header parsing readability by
introducing a new macro to access and mask its fields.
Signed-off-by: Antoine Tenart <antoine.tenart@bootlin.com>
---
drivers/net/ethernet/mscc/ocelot_board.c | 24 +++++++++++++-----------
1 file changed, 13 insertions(+), 11 deletions(-)
diff --git a/drivers/net/ethernet/mscc/ocelot_board.c b/drivers/net/ethernet/mscc/ocelot_board.c
index ba7c93c4318a..b85982e5717a 100644
--- a/drivers/net/ethernet/mscc/ocelot_board.c
+++ b/drivers/net/ethernet/mscc/ocelot_board.c
@@ -16,24 +16,26 @@
#include "ocelot.h"
-static int ocelot_parse_ifh(u32 *ifh, struct frame_info *info)
+#define IFH_EXTRACT_BITFIELD64(x, o, w) (((x) >> (o)) & GENMASK_ULL((w) - 1, 0))
+
+static int ocelot_parse_ifh(u32 *_ifh, struct frame_info *info)
{
- int i;
u8 llen, wlen;
+ u64 ifh[2];
+
+ ifh[0] = be64_to_cpu(((__force __be64 *)_ifh)[0]);
+ ifh[1] = be64_to_cpu(((__force __be64 *)_ifh)[1]);
- /* The IFH is in network order, switch to CPU order */
- for (i = 0; i < IFH_LEN; i++)
- ifh[i] = ntohl((__force __be32)ifh[i]);
+ wlen = IFH_EXTRACT_BITFIELD64(ifh[0], 7, 8);
+ llen = IFH_EXTRACT_BITFIELD64(ifh[0], 15, 6);
- wlen = (ifh[1] >> 7) & 0xff;
- llen = (ifh[1] >> 15) & 0x3f;
info->len = OCELOT_BUFFER_CELL_SZ * wlen + llen - 80;
- info->port = (ifh[2] & GENMASK(14, 11)) >> 11;
+ info->port = IFH_EXTRACT_BITFIELD64(ifh[1], 43, 4);
- info->cpuq = (ifh[3] & GENMASK(27, 20)) >> 20;
- info->tag_type = (ifh[3] & BIT(16)) >> 16;
- info->vid = ifh[3] & GENMASK(11, 0);
+ info->cpuq = IFH_EXTRACT_BITFIELD64(ifh[1], 20, 8);
+ info->tag_type = IFH_EXTRACT_BITFIELD64(ifh[1], 16, 1);
+ info->vid = IFH_EXTRACT_BITFIELD64(ifh[1], 0, 12);
return 0;
}
--
2.20.1
^ permalink raw reply related [flat|nested] 16+ messages in thread
* [PATCH net-next 7/8] net: mscc: remove the frame_info cpuq member
2019-01-17 10:02 [PATCH net-next 0/8] net: mscc: PTP offloading support Antoine Tenart
` (5 preceding siblings ...)
2019-01-17 10:02 ` [PATCH net-next 6/8] net: mscc: improve the frame header parsing readability Antoine Tenart
@ 2019-01-17 10:02 ` Antoine Tenart
2019-01-17 10:02 ` [PATCH net-next 8/8] net: mscc: PTP offloading support Antoine Tenart
` (2 subsequent siblings)
9 siblings, 0 replies; 16+ messages in thread
From: Antoine Tenart @ 2019-01-17 10:02 UTC (permalink / raw)
To: davem, alexandre.belloni, UNGLinuxDriver, ralf, paul.burton, jhogan
Cc: Antoine Tenart, netdev, linux-mips, thomas.petazzoni,
quentin.schulz, allan.nielsen
In struct frame_info, the cpuq member is never used. This cosmetic patch
removes it from the structure, and from the parsing of the frame header
as it's only set but never used.
Signed-off-by: Antoine Tenart <antoine.tenart@bootlin.com>
---
drivers/net/ethernet/mscc/ocelot.h | 1 -
drivers/net/ethernet/mscc/ocelot_board.c | 1 -
2 files changed, 2 deletions(-)
diff --git a/drivers/net/ethernet/mscc/ocelot.h b/drivers/net/ethernet/mscc/ocelot.h
index 4b1b180884ad..994ba953d60e 100644
--- a/drivers/net/ethernet/mscc/ocelot.h
+++ b/drivers/net/ethernet/mscc/ocelot.h
@@ -45,7 +45,6 @@ struct frame_info {
u32 len;
u16 port;
u16 vid;
- u8 cpuq;
u8 tag_type;
};
diff --git a/drivers/net/ethernet/mscc/ocelot_board.c b/drivers/net/ethernet/mscc/ocelot_board.c
index b85982e5717a..e0a3b6f70e8f 100644
--- a/drivers/net/ethernet/mscc/ocelot_board.c
+++ b/drivers/net/ethernet/mscc/ocelot_board.c
@@ -33,7 +33,6 @@ static int ocelot_parse_ifh(u32 *_ifh, struct frame_info *info)
info->port = IFH_EXTRACT_BITFIELD64(ifh[1], 43, 4);
- info->cpuq = IFH_EXTRACT_BITFIELD64(ifh[1], 20, 8);
info->tag_type = IFH_EXTRACT_BITFIELD64(ifh[1], 16, 1);
info->vid = IFH_EXTRACT_BITFIELD64(ifh[1], 0, 12);
--
2.20.1
^ permalink raw reply related [flat|nested] 16+ messages in thread
* [PATCH net-next 8/8] net: mscc: PTP offloading support
2019-01-17 10:02 [PATCH net-next 0/8] net: mscc: PTP offloading support Antoine Tenart
` (6 preceding siblings ...)
2019-01-17 10:02 ` [PATCH net-next 7/8] net: mscc: remove the frame_info cpuq member Antoine Tenart
@ 2019-01-17 10:02 ` Antoine Tenart
2019-01-18 2:23 ` Richard Cochran
2019-01-18 2:13 ` [PATCH net-next 0/8] " Richard Cochran
2019-01-18 5:07 ` Florian Fainelli
9 siblings, 1 reply; 16+ messages in thread
From: Antoine Tenart @ 2019-01-17 10:02 UTC (permalink / raw)
To: davem, alexandre.belloni, UNGLinuxDriver, ralf, paul.burton, jhogan
Cc: Antoine Tenart, netdev, linux-mips, thomas.petazzoni,
quentin.schulz, allan.nielsen
This patch adds support for offloading PTP timestamping to the Ocelot
switch for both 1-step and 2-step modes.
Signed-off-by: Antoine Tenart <antoine.tenart@bootlin.com>
---
drivers/net/ethernet/mscc/ocelot.c | 509 ++++++++++++++++++++++-
drivers/net/ethernet/mscc/ocelot.h | 36 ++
drivers/net/ethernet/mscc/ocelot_board.c | 106 ++++-
3 files changed, 643 insertions(+), 8 deletions(-)
diff --git a/drivers/net/ethernet/mscc/ocelot.c b/drivers/net/ethernet/mscc/ocelot.c
index 215a45374d7b..ed84c18adcfe 100644
--- a/drivers/net/ethernet/mscc/ocelot.c
+++ b/drivers/net/ethernet/mscc/ocelot.c
@@ -14,6 +14,7 @@
#include <linux/module.h>
#include <linux/netdevice.h>
#include <linux/phy.h>
+#include <linux/ptp_clock_kernel.h>
#include <linux/skbuff.h>
#include <linux/iopoll.h>
#include <net/arp.h>
@@ -530,7 +531,7 @@ static int ocelot_port_stop(struct net_device *dev)
*/
static int ocelot_gen_ifh(u32 *ifh, struct frame_info *info)
{
- ifh[0] = IFH_INJ_BYPASS;
+ ifh[0] = IFH_INJ_BYPASS | ((0x1ff & info->rew_op) << 21);
ifh[1] = (0xf00 & info->port) >> 8;
ifh[2] = (0xff & info->port) << 24;
ifh[3] = (info->tag_type << 16) | info->vid;
@@ -542,6 +543,7 @@ static int ocelot_port_xmit(struct sk_buff *skb, struct net_device *dev)
{
struct ocelot_port *port = netdev_priv(dev);
struct ocelot *ocelot = port->ocelot;
+ struct skb_shared_info *shinfo = skb_shinfo(skb);
u32 val, ifh[IFH_LEN];
struct frame_info info = {};
u8 grp = 0; /* Send everything on CPU group 0 */
@@ -558,6 +560,14 @@ static int ocelot_port_xmit(struct sk_buff *skb, struct net_device *dev)
info.port = BIT(port->chip_port);
info.tag_type = IFH_TAG_TYPE_C;
info.vid = skb_vlan_tag_get(skb);
+
+ /* Check if timestamping is needed */
+ if (ocelot->ptp && shinfo->tx_flags & SKBTX_HW_TSTAMP) {
+ info.rew_op = port->ptp_cmd;
+ if (port->ptp_cmd == IFH_REW_OP_TWO_STEP_PTP)
+ info.rew_op |= (port->ts_id % 4) << 3;
+ }
+
ocelot_gen_ifh(ifh, &info);
for (i = 0; i < IFH_LEN; i++)
@@ -588,11 +598,44 @@ static int ocelot_port_xmit(struct sk_buff *skb, struct net_device *dev)
dev->stats.tx_packets++;
dev->stats.tx_bytes += skb->len;
- dev_kfree_skb_any(skb);
+
+ if (ocelot->ptp && shinfo->tx_flags & SKBTX_HW_TSTAMP &&
+ port->ptp_cmd == IFH_REW_OP_TWO_STEP_PTP) {
+ struct ocelot_skb *oskb =
+ devm_kzalloc(ocelot->dev, sizeof(struct ocelot_skb),
+ GFP_KERNEL);
+
+ oskb->skb = skb;
+ oskb->id = port->ts_id % 4;
+ port->ts_id++;
+
+ list_add_tail(&oskb->head, &port->skbs);
+ } else {
+ dev_kfree_skb_any(skb);
+ }
return NETDEV_TX_OK;
}
+void ocelot_get_hwtimestamp(struct ocelot *ocelot, struct timespec64 *ts)
+{
+ /* Read current PTP time to get seconds */
+ u32 val = ocelot_read_rix(ocelot, PTP_PIN_CFG, TOD_ACC_PIN);
+
+ val &= ~(PTP_PIN_CFG_SYNC | PTP_PIN_CFG_ACTION_MASK | PTP_PIN_CFG_DOM);
+ val |= PTP_PIN_CFG_ACTION(PTP_PIN_ACTION_SAVE);
+ ocelot_write_rix(ocelot, val, PTP_PIN_CFG, TOD_ACC_PIN);
+ ts->tv_sec = ocelot_read_rix(ocelot, PTP_PIN_TOD_SEC_LSB, TOD_ACC_PIN);
+
+ /* Read packet HW timestamp from FIFO */
+ val = ocelot_read(ocelot, SYS_PTP_TXSTAMP);
+ ts->tv_nsec = SYS_PTP_TXSTAMP_PTP_TXSTAMP(val);
+
+ /* Sec has incremented since the ts was registered */
+ if ((ts->tv_sec & 0x1) != !!(val & SYS_PTP_TXSTAMP_PTP_TXSTAMP_SEC))
+ ts->tv_sec--;
+}
+
static void ocelot_mact_mc_reset(struct ocelot_port *port)
{
struct ocelot *ocelot = port->ocelot;
@@ -915,6 +958,262 @@ static int ocelot_set_features(struct net_device *dev,
return 0;
}
+static void ocelot_vcap_is2_cmd(struct ocelot *ocelot, u8 addr,
+ enum vcap_cmds cmd, enum vcap_selector sel)
+{
+ u32 val = VCAP_UPDATE_CTRL_UPDATE_CMD(cmd) |
+ VCAP_UPDATE_CTRL_UPDATE_ADDR(addr) |
+ VCAP_UPDATE_CTRL_UPDATE_SHOT;
+
+ /* Select the destination/origin */
+ if (!(sel & VCAP_SEL_COUNTER))
+ val |= VCAP_UPDATE_CTRL_UPDATE_COUNTER_DIS;
+ if (!(sel & VCAP_SEL_ACTION))
+ val |= VCAP_UPDATE_CTRL_UPDATE_ACTION_DIS;
+ if (!(sel & VCAP_SEL_ENTRY))
+ val |= VCAP_UPDATE_CTRL_UPDATE_ENTRY_DIS;
+
+ ocelot_write(ocelot, val, VCAP_UPDATE_CTRL);
+
+ /* wait for the command to complete */
+ do {
+ val = ocelot_read(ocelot, VCAP_UPDATE_CTRL);
+ } while (val & VCAP_UPDATE_CTRL_UPDATE_SHOT);
+}
+
+static void ocelot_vcap_entry_to_cache(struct ocelot *ocelot,
+ struct vcap_data *data)
+{
+ int i;
+
+ for (i = 0; i < 12; i++) {
+ ocelot_write(ocelot, data->entry[i],
+ VCAP_UPDATE_CTRL_ENTRY_DATA + i * sizeof(u32));
+ ocelot_write(ocelot, ~data->mask[i],
+ VCAP_UPDATE_CTRL_MASK_DATA + i * sizeof(u32));
+ }
+
+ ocelot_write(ocelot, data->type_group, VCAP_CACHE_DATA_TYPE);
+}
+
+static void ocelot_vcap_action_to_cache(struct ocelot *ocelot,
+ struct vcap_data *data)
+{
+ int i;
+
+ /* Encode the type */
+ data->action[0] &= ~BIT(0);
+
+ for (i = 0; i < 4; i++)
+ ocelot_write(ocelot, data->action[i],
+ VCAP_UPDATE_CTRL_ACTION_DATA + i * sizeof(u32));
+
+ ocelot_write(ocelot, data->counter, VCAP_UPDATE_CTRL_COUNTER_DATA);
+}
+
+static void ocelot_vcap_is2_init(struct ocelot *ocelot)
+{
+ struct vcap_data data;
+ int port;
+
+ mutex_init(&ocelot->ptp_lock);
+
+ memset(&data, 0, sizeof(data));
+
+ /* Initialize entries */
+ ocelot_vcap_entry_to_cache(ocelot, &data);
+ ocelot_write(ocelot, 64 /* entry count */, VCAP_UPDATE_CTRL_MV_CFG);
+ ocelot_vcap_is2_cmd(ocelot, 0, VCAP_CMD_INIT, VCAP_SEL_ENTRY);
+
+ /* Initialize actions */
+ ocelot_vcap_action_to_cache(ocelot, &data);
+ ocelot_write(ocelot, 64 + ocelot->num_phys_ports + 2 /* action count */,
+ VCAP_UPDATE_CTRL_MV_CFG);
+ ocelot_vcap_is2_cmd(ocelot, 0, VCAP_CMD_INIT,
+ VCAP_SEL_ACTION | VCAP_SEL_COUNTER);
+
+ /* Enable the IS2 engine */
+ for (port = 0; port < ocelot->num_phys_ports; port++) {
+ ocelot_write_gix(ocelot, ANA_PORT_VCAP_S2_CFG_S2_ENA |
+ ANA_PORT_VCAP_S2_CFG_S2_IP6_CFG(0xa),
+ ANA_PORT_VCAP_S2_CFG, port);
+ ocelot_write_gix(ocelot, 0, ANA_PORT_PTP_CFG, port);
+ }
+}
+
+static void ocelot_vcap_is2_set(struct ocelot *ocelot, u8 addr,
+ struct vcap_data *data)
+{
+ ocelot_vcap_entry_to_cache(ocelot, data);
+ ocelot_vcap_action_to_cache(ocelot, data);
+ ocelot_vcap_is2_cmd(ocelot, addr, VCAP_CMD_WRITE,
+ VCAP_SEL_ENTRY | VCAP_SEL_ACTION | VCAP_SEL_COUNTER);
+}
+
+static inline void ocelot_set_bits(u32 *data, u32 offset, u32 mask, u32 val)
+{
+ u32 word_off = offset / 32, bit_off = offset % 32;
+
+ data[word_off] &= ~(mask << bit_off);
+ data[word_off] |= val << bit_off;
+ if (get_bitmask_order(mask) > (32 - bit_off)) {
+ data[word_off + 1] &= ~(mask >> (32 - bit_off));
+ data[word_off + 1] |= val >> (32 - bit_off);
+ }
+}
+
+static void ocelot_vcap_is2_set_lookup(struct vcap_data *data, u32 offset,
+ u32 mask, u32 val)
+{
+ ocelot_set_bits(data->entry, offset, mask, val);
+ ocelot_set_bits(data->mask, offset, mask, mask);
+}
+
+static void ocelot_vcap_is2_set_action(struct vcap_data *data, u32 offset,
+ u32 mask, u32 val)
+{
+ ocelot_set_bits(data->action, offset, mask, val);
+}
+
+static int ocelot_hwstamp_get(struct ocelot_port *port, struct ifreq *ifr)
+{
+ struct ocelot *ocelot = port->ocelot;
+
+ return copy_to_user(ifr->ifr_data, &ocelot->hwtstamp_config,
+ sizeof(ocelot->hwtstamp_config)) ? -EFAULT : 0;
+}
+
+static int ocelot_hwstamp_set(struct ocelot_port *port, struct ifreq *ifr)
+{
+ struct ocelot *ocelot = port->ocelot;
+ struct hwtstamp_config cfg;
+ struct vcap_data data;
+ int base = port->chip_port * VCAP_IS2_N_PTP_ENTRIES;
+ u32 ptp_op = VCAP_IS2_ACT_REW_OP_PTP_ONE;
+
+ if (copy_from_user(&cfg, ifr->ifr_data, sizeof(cfg)))
+ return -EFAULT;
+
+ /* reserved for future extensions */
+ if (cfg.flags)
+ return -EINVAL;
+
+ /* Tx type sanity check */
+ switch (cfg.tx_type) {
+ case HWTSTAMP_TX_ON:
+ port->ptp_cmd = IFH_REW_OP_TWO_STEP_PTP;
+ break;
+ case HWTSTAMP_TX_ONESTEP_SYNC:
+ /* IFH_REW_OP_ONE_STEP_PTP updates the correctional field, we
+ * need to update the origin time.
+ */
+ port->ptp_cmd = IFH_REW_OP_ORIGIN_PTP;
+ break;
+ case HWTSTAMP_TX_OFF:
+ port->ptp_cmd = 0;
+ break;
+ default:
+ return -ERANGE;
+ }
+
+ mutex_lock(&ocelot->ptp_lock);
+
+ /* Prepare the VCAP PTP entry */
+ memset(&data, 0, sizeof(data));
+
+ switch (cfg.rx_filter) {
+ case HWTSTAMP_FILTER_NONE:
+ ptp_op = VCAP_IS2_ACT_REW_OP_NOOP;
+ break;
+ case HWTSTAMP_FILTER_ALL:
+ case HWTSTAMP_FILTER_SOME:
+ case HWTSTAMP_FILTER_PTP_V1_L4_EVENT:
+ case HWTSTAMP_FILTER_PTP_V1_L4_SYNC:
+ case HWTSTAMP_FILTER_PTP_V1_L4_DELAY_REQ:
+ case HWTSTAMP_FILTER_NTP_ALL:
+ case HWTSTAMP_FILTER_PTP_V2_L4_EVENT:
+ case HWTSTAMP_FILTER_PTP_V2_L4_SYNC:
+ case HWTSTAMP_FILTER_PTP_V2_L4_DELAY_REQ:
+ case HWTSTAMP_FILTER_PTP_V2_L2_EVENT:
+ case HWTSTAMP_FILTER_PTP_V2_L2_SYNC:
+ case HWTSTAMP_FILTER_PTP_V2_L2_DELAY_REQ:
+ case HWTSTAMP_FILTER_PTP_V2_EVENT:
+ case HWTSTAMP_FILTER_PTP_V2_SYNC:
+ case HWTSTAMP_FILTER_PTP_V2_DELAY_REQ:
+ cfg.rx_filter = HWTSTAMP_FILTER_PTP_V2_EVENT;
+ break;
+ default:
+ mutex_unlock(&ocelot->ptp_lock);
+ return -ERANGE;
+ }
+
+ /* Set the PTP action */
+ ocelot_vcap_is2_set_action(&data, VCAP_IS2_ACT_REW_OP,
+ VCAP_IS2_ACT_REW_OP_M, ptp_op);
+
+ data.type_group = 2;
+
+ /* Port mask */
+ ocelot_vcap_is2_set_lookup(&data, VCAP_IS2_LKP_INGRESS_PORT_MASK,
+ VCAP_IS2_LKP_INGRESS_PORT_MASK_M, 0x7ff);
+
+ /* Commit the PTP VCAP entries:
+ *
+ * - One entry for PTP over Ethernet (etype 0x88f7).
+ * - One entry for PTP over IPv4/v6 UDP dst port 319.
+ * - One entry for PTP over IPv4/v6 UDP dst port 320.
+ */
+
+ /* PTP over Ethernet */
+ ocelot_vcap_is2_set_lookup(&data, VCAP_IS2_LKP_TYPE,
+ VCAP_IS2_LKP_TYPE_M,
+ VCAP_IS2_LKP_TYPE_MAC_ETYPE);
+ ocelot_vcap_is2_set_lookup(&data, VCAP_IS2_LKP_ETYPE,
+ VCAP_IS2_LKP_ETYPE_M, 0x88f7);
+ ocelot_vcap_is2_set(ocelot, base++, &data);
+
+ /* PTP over IPv4/v6 UDP dst port 319 */
+ ocelot_vcap_is2_set_lookup(&data, VCAP_IS2_LKP_TYPE,
+ VCAP_IS2_LKP_TYPE_M,
+ VCAP_IS2_LKP_TYPE_TCP_UDP);
+ ocelot_vcap_is2_set_lookup(&data, VCAP_IS2_LKP_DPORT,
+ VCAP_IS2_LKP_DPORT_M, 319);
+ ocelot_vcap_is2_set(ocelot, base++, &data);
+
+ /* PTP over IPv4/v6 UDP dst port 320 */
+ ocelot_vcap_is2_set_lookup(&data, VCAP_IS2_LKP_TYPE,
+ VCAP_IS2_LKP_TYPE_M,
+ VCAP_IS2_LKP_TYPE_TCP_UDP);
+ ocelot_vcap_is2_set_lookup(&data, VCAP_IS2_LKP_DPORT,
+ VCAP_IS2_LKP_DPORT_M, 320);
+ ocelot_vcap_is2_set(ocelot, base++, &data);
+
+ /* Commit back the result & save it */
+ memcpy(&ocelot->hwtstamp_config, &cfg, sizeof(cfg));
+ mutex_unlock(&ocelot->ptp_lock);
+
+ return copy_to_user(ifr->ifr_data, &cfg, sizeof(cfg)) ? -EFAULT : 0;
+}
+
+static int ocelot_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
+{
+ struct ocelot_port *port = netdev_priv(dev);
+ struct ocelot *ocelot = port->ocelot;
+
+ /* The function is only used for PTP operations for now */
+ if (!ocelot->ptp)
+ return -EOPNOTSUPP;
+
+ switch (cmd) {
+ case SIOCSHWTSTAMP:
+ return ocelot_hwstamp_set(port, ifr);
+ case SIOCGHWTSTAMP:
+ return ocelot_hwstamp_get(port, ifr);
+ default:
+ return -EOPNOTSUPP;
+ }
+}
+
static const struct net_device_ops ocelot_port_netdev_ops = {
.ndo_open = ocelot_port_open,
.ndo_stop = ocelot_port_stop,
@@ -929,6 +1228,7 @@ static const struct net_device_ops ocelot_port_netdev_ops = {
.ndo_vlan_rx_add_vid = ocelot_vlan_rx_add_vid,
.ndo_vlan_rx_kill_vid = ocelot_vlan_rx_kill_vid,
.ndo_set_features = ocelot_set_features,
+ .ndo_do_ioctl = ocelot_ioctl,
};
static void ocelot_get_strings(struct net_device *netdev, u32 sset, u8 *data)
@@ -1004,12 +1304,42 @@ static int ocelot_get_sset_count(struct net_device *dev, int sset)
return ocelot->num_stats;
}
+static int ocelot_get_ts_info(struct net_device *dev,
+ struct ethtool_ts_info *info)
+{
+ struct ocelot_port *ocelot_port = netdev_priv(dev);
+ struct ocelot *ocelot = ocelot_port->ocelot;
+ int ret;
+
+ if (!ocelot->ptp)
+ return -EOPNOTSUPP;
+
+ ret = ethtool_op_get_ts_info(dev, info);
+ if (ret)
+ return ret;
+
+ info->phc_index = ocelot->ptp_clock ?
+ ptp_clock_index(ocelot->ptp_clock) : -1;
+ info->so_timestamping |= SOF_TIMESTAMPING_TX_SOFTWARE |
+ SOF_TIMESTAMPING_RX_SOFTWARE |
+ SOF_TIMESTAMPING_SOFTWARE |
+ SOF_TIMESTAMPING_TX_HARDWARE |
+ SOF_TIMESTAMPING_RX_HARDWARE |
+ SOF_TIMESTAMPING_RAW_HARDWARE;
+ info->tx_types = BIT(HWTSTAMP_TX_OFF) | BIT(HWTSTAMP_TX_ON) |
+ BIT(HWTSTAMP_TX_ONESTEP_SYNC);
+ info->rx_filters = BIT(HWTSTAMP_FILTER_NONE) | BIT(HWTSTAMP_FILTER_ALL);
+
+ return 0;
+}
+
static const struct ethtool_ops ocelot_ethtool_ops = {
.get_strings = ocelot_get_strings,
.get_ethtool_stats = ocelot_get_ethtool_stats,
.get_sset_count = ocelot_get_sset_count,
.get_link_ksettings = phy_ethtool_get_link_ksettings,
.set_link_ksettings = phy_ethtool_set_link_ksettings,
+ .get_ts_info = ocelot_get_ts_info,
};
static int ocelot_port_attr_get(struct net_device *dev,
@@ -1616,6 +1946,165 @@ struct notifier_block ocelot_switchdev_blocking_nb __read_mostly = {
};
EXPORT_SYMBOL(ocelot_switchdev_blocking_nb);
+int ocelot_ptp_gettime64(struct ptp_clock_info *ptp, struct timespec64 *ts)
+{
+ struct ocelot *ocelot = container_of(ptp, struct ocelot, ptp_info);
+ u32 val;
+ time64_t s;
+ s64 ns;
+
+ val = ocelot_read_rix(ocelot, PTP_PIN_CFG, TOD_ACC_PIN);
+ val &= ~(PTP_PIN_CFG_SYNC | PTP_PIN_CFG_ACTION_MASK | PTP_PIN_CFG_DOM);
+ val |= PTP_PIN_CFG_ACTION(PTP_PIN_ACTION_SAVE);
+ ocelot_write_rix(ocelot, val, PTP_PIN_CFG, TOD_ACC_PIN);
+
+ s = ocelot_read_rix(ocelot, PTP_PIN_TOD_SEC_MSB, TOD_ACC_PIN);
+ s += ocelot_read_rix(ocelot, PTP_PIN_TOD_SEC_LSB, TOD_ACC_PIN);
+ ns = ocelot_read_rix(ocelot, PTP_PIN_TOD_NSEC, TOD_ACC_PIN);
+
+ /* Deal with negative values */
+ if (ns >= 0x3ffffff0 && ns <= 0x3fffffff) {
+ s--;
+ ns &= 0xf;
+ ns += 999999984;
+ }
+
+ set_normalized_timespec64(ts, s, ns);
+ return 0;
+}
+
+static int ocelot_ptp_settime64(struct ptp_clock_info *ptp,
+ const struct timespec64 *ts)
+{
+ struct ocelot *ocelot = container_of(ptp, struct ocelot, ptp_info);
+ u32 val;
+
+ val = ocelot_read_rix(ocelot, PTP_PIN_CFG, TOD_ACC_PIN);
+ val &= ~(PTP_PIN_CFG_SYNC | PTP_PIN_CFG_ACTION_MASK | PTP_PIN_CFG_DOM);
+ val |= PTP_PIN_CFG_ACTION(PTP_PIN_ACTION_IDLE);
+
+ ocelot_write_rix(ocelot, val, PTP_PIN_CFG, TOD_ACC_PIN);
+
+ ocelot_write_rix(ocelot, lower_32_bits(ts->tv_sec), PTP_PIN_TOD_SEC_LSB,
+ TOD_ACC_PIN);
+ ocelot_write_rix(ocelot, upper_32_bits(ts->tv_sec), PTP_PIN_TOD_SEC_MSB,
+ TOD_ACC_PIN);
+ ocelot_write_rix(ocelot, ts->tv_nsec, PTP_PIN_TOD_NSEC, TOD_ACC_PIN);
+
+ val = ocelot_read_rix(ocelot, PTP_PIN_CFG, TOD_ACC_PIN);
+ val &= ~(PTP_PIN_CFG_SYNC | PTP_PIN_CFG_ACTION_MASK | PTP_PIN_CFG_DOM);
+ val |= PTP_PIN_CFG_ACTION(PTP_PIN_ACTION_LOAD);
+
+ ocelot_write_rix(ocelot, val, PTP_PIN_CFG, TOD_ACC_PIN);
+
+ return 0;
+}
+
+static int ocelot_ptp_adjtime(struct ptp_clock_info *ptp, s64 delta)
+{
+ if (delta > -(NSEC_PER_SEC / 2) && delta < (NSEC_PER_SEC / 2)) {
+ struct ocelot *ocelot = container_of(ptp, struct ocelot, ptp_info);
+ u32 val;
+
+ val = ocelot_read_rix(ocelot, PTP_PIN_CFG, TOD_ACC_PIN);
+ val &= ~(PTP_PIN_CFG_SYNC | PTP_PIN_CFG_ACTION_MASK | PTP_PIN_CFG_DOM);
+ val |= PTP_PIN_CFG_ACTION(PTP_PIN_ACTION_IDLE);
+
+ ocelot_write_rix(ocelot, val, PTP_PIN_CFG, TOD_ACC_PIN);
+
+ ocelot_write_rix(ocelot, 0, PTP_PIN_TOD_SEC_LSB, TOD_ACC_PIN);
+ ocelot_write_rix(ocelot, 0, PTP_PIN_TOD_SEC_MSB, TOD_ACC_PIN);
+ ocelot_write_rix(ocelot, delta, PTP_PIN_TOD_NSEC, TOD_ACC_PIN);
+
+ val = ocelot_read_rix(ocelot, PTP_PIN_CFG, TOD_ACC_PIN);
+ val &= ~(PTP_PIN_CFG_SYNC | PTP_PIN_CFG_ACTION_MASK | PTP_PIN_CFG_DOM);
+ val |= PTP_PIN_CFG_ACTION(PTP_PIN_ACTION_DELTA);
+
+ ocelot_write_rix(ocelot, val, PTP_PIN_CFG, TOD_ACC_PIN);
+ } else {
+ /* Fall back using ocelot_ptp_settime64 which is not exact. */
+ struct timespec64 ts;
+ u64 now;
+
+ ocelot_ptp_gettime64(ptp, &ts);
+
+ now = ktime_to_ns(timespec64_to_ktime(ts));
+ ts = ns_to_timespec64(now + delta);
+
+ ocelot_ptp_settime64(ptp, &ts);
+ }
+ return 0;
+}
+
+static int ocelot_ptp_adjfreq(struct ptp_clock_info *ptp, s32 ppb)
+{
+ struct ocelot *ocelot = container_of(ptp, struct ocelot, ptp_info);
+ u64 adj = 0;
+ u32 unit = 0, direction = 0;
+
+ if (!ppb)
+ goto disable_adj;
+
+ if (ppb < 0) {
+ direction = PTP_CFG_CLK_ADJ_CFG_DIR;
+ ppb = -ppb;
+ }
+
+ adj = PSEC_PER_SEC;
+ do_div(adj, ppb);
+
+ /* If the adjustment value is too large, use ns instead */
+ if (adj >= (1L << 30)) {
+ unit = PTP_CFG_CLK_ADJ_FREQ_NS;
+ do_div(adj, 1000);
+ }
+
+ /* Still too big */
+ if (adj >= (1L << 30))
+ goto disable_adj;
+
+ ocelot_write(ocelot, unit | adj, PTP_CLK_CFG_ADJ_FREQ);
+ ocelot_write(ocelot, PTP_CFG_CLK_ADJ_CFG_ENA | direction,
+ PTP_CLK_CFG_ADJ_CFG);
+ return 0;
+
+disable_adj:
+ ocelot_write(ocelot, 0, PTP_CLK_CFG_ADJ_CFG);
+ return 0;
+}
+
+static struct ptp_clock_info ocelot_ptp_clock_info = {
+ .owner = THIS_MODULE,
+ .name = "ocelot ptp",
+ .max_adj = 0x7fffffff,
+ .n_alarm = 0,
+ .n_ext_ts = 0,
+ .n_per_out = 0,
+ .n_pins = 0,
+ .pps = 0,
+ .gettime64 = ocelot_ptp_gettime64,
+ .settime64 = ocelot_ptp_settime64,
+ .adjtime = ocelot_ptp_adjtime,
+ .adjfreq = ocelot_ptp_adjfreq,
+};
+
+static int ocelot_init_timestamp(struct ocelot *ocelot)
+{
+ ocelot->ptp_info = ocelot_ptp_clock_info;
+
+ ocelot->ptp_clock = ptp_clock_register(&ocelot->ptp_info, ocelot->dev);
+ if (IS_ERR(ocelot->ptp_clock))
+ return PTR_ERR(ocelot->ptp_clock);
+
+ ocelot_write(ocelot, SYS_PTP_CFG_PTP_STAMP_WID(30), SYS_PTP_CFG);
+ ocelot_write(ocelot, 0xffffffff, ANA_TABLES_PTP_ID_LOW);
+ ocelot_write(ocelot, 0xffffffff, ANA_TABLES_PTP_ID_HIGH);
+
+ ocelot_write(ocelot, PTP_CFG_MISC_PTP_EN, PTP_CFG_MISC);
+
+ return 0;
+}
+
int ocelot_probe_port(struct ocelot *ocelot, u8 port,
void __iomem *regs,
struct phy_device *phy)
@@ -1649,6 +2138,8 @@ int ocelot_probe_port(struct ocelot *ocelot, u8 port,
ocelot_mact_learn(ocelot, PGID_CPU, dev->dev_addr, ocelot_port->pvid,
ENTRYTYPE_LOCKED);
+ INIT_LIST_HEAD(&ocelot_port->skbs);
+
err = register_netdev(dev);
if (err) {
dev_err(ocelot->dev, "register_netdev failed\n");
@@ -1669,7 +2160,7 @@ EXPORT_SYMBOL(ocelot_probe_port);
int ocelot_init(struct ocelot *ocelot)
{
u32 port;
- int i, cpu = ocelot->num_phys_ports;
+ int i, ret, cpu = ocelot->num_phys_ports;
char queue_name[32];
ocelot->lags = devm_kcalloc(ocelot->dev, ocelot->num_phys_ports,
@@ -1796,6 +2287,18 @@ int ocelot_init(struct ocelot *ocelot)
INIT_DELAYED_WORK(&ocelot->stats_work, ocelot_check_stats);
queue_delayed_work(ocelot->stats_queue, &ocelot->stats_work,
OCELOT_STATS_CHECK_DELAY);
+
+ if (ocelot->ptp) {
+ ret = ocelot_init_timestamp(ocelot);
+ if (ret) {
+ dev_err(ocelot->dev,
+ "Timestamp initialization failed\n");
+ return ret;
+ }
+
+ ocelot_vcap_is2_init(ocelot);
+ }
+
return 0;
}
EXPORT_SYMBOL(ocelot_init);
diff --git a/drivers/net/ethernet/mscc/ocelot.h b/drivers/net/ethernet/mscc/ocelot.h
index 994ba953d60e..ed1583037dc2 100644
--- a/drivers/net/ethernet/mscc/ocelot.h
+++ b/drivers/net/ethernet/mscc/ocelot.h
@@ -11,9 +11,11 @@
#include <linux/bitops.h>
#include <linux/etherdevice.h>
#include <linux/if_vlan.h>
+#include <linux/net_tstamp.h>
#include <linux/phy.h>
#include <linux/phy/phy.h>
#include <linux/platform_device.h>
+#include <linux/ptp_clock_kernel.h>
#include <linux/regmap.h>
#include "ocelot_ana.h"
@@ -46,6 +48,8 @@ struct frame_info {
u16 port;
u16 vid;
u8 tag_type;
+ u16 rew_op;
+ u32 timestamp; /* rew_val */
};
#define IFH_INJ_BYPASS BIT(31)
@@ -54,6 +58,12 @@ struct frame_info {
#define IFH_TAG_TYPE_C 0
#define IFH_TAG_TYPE_S 1
+#define IFH_REW_OP_NOOP 0x0
+#define IFH_REW_OP_DSCP 0x1
+#define IFH_REW_OP_ONE_STEP_PTP 0x2
+#define IFH_REW_OP_TWO_STEP_PTP 0x3
+#define IFH_REW_OP_ORIGIN_PTP 0x5
+
#define OCELOT_SPEED_2500 0
#define OCELOT_SPEED_1000 1
#define OCELOT_SPEED_100 2
@@ -401,6 +411,13 @@ enum ocelot_regfield {
REGFIELD_MAX
};
+enum ocelot_clk_pins {
+ ALT_PPS_PIN = 1,
+ EXT_CLK_PIN,
+ ALT_LDST_PIN,
+ TOD_ACC_PIN
+};
+
struct ocelot_multicast {
struct list_head list;
unsigned char addr[ETH_ALEN];
@@ -450,6 +467,12 @@ struct ocelot {
u64 *stats;
struct delayed_work stats_work;
struct workqueue_struct *stats_queue;
+
+ u8 ptp:1;
+ struct ptp_clock *ptp_clock;
+ struct ptp_clock_info ptp_info;
+ struct hwtstamp_config hwtstamp_config;
+ struct mutex ptp_lock;
};
struct ocelot_port {
@@ -475,6 +498,16 @@ struct ocelot_port {
phy_interface_t phy_mode;
struct phy *serdes;
+
+ u8 ptp_cmd;
+ struct list_head skbs;
+ u8 ts_id;
+};
+
+struct ocelot_skb {
+ struct list_head head;
+ struct sk_buff *skb;
+ u8 id;
};
u32 __ocelot_read_ix(struct ocelot *ocelot, u32 reg, u32 offset);
@@ -518,4 +551,7 @@ int ocelot_probe_port(struct ocelot *ocelot, u8 port,
extern struct notifier_block ocelot_netdevice_nb;
extern struct notifier_block ocelot_switchdev_blocking_nb;
+int ocelot_ptp_gettime64(struct ptp_clock_info *ptp, struct timespec64 *ts);
+void ocelot_get_hwtimestamp(struct ocelot *ocelot, struct timespec64 *ts);
+
#endif
diff --git a/drivers/net/ethernet/mscc/ocelot_board.c b/drivers/net/ethernet/mscc/ocelot_board.c
index e0a3b6f70e8f..d85920c05269 100644
--- a/drivers/net/ethernet/mscc/ocelot_board.c
+++ b/drivers/net/ethernet/mscc/ocelot_board.c
@@ -31,6 +31,8 @@ static int ocelot_parse_ifh(u32 *_ifh, struct frame_info *info)
info->len = OCELOT_BUFFER_CELL_SZ * wlen + llen - 80;
+ info->timestamp = IFH_EXTRACT_BITFIELD64(ifh[0], 21, 32);
+
info->port = IFH_EXTRACT_BITFIELD64(ifh[1], 43, 4);
info->tag_type = IFH_EXTRACT_BITFIELD64(ifh[1], 16, 1);
@@ -98,7 +100,11 @@ static irqreturn_t ocelot_xtr_irq_handler(int irq, void *arg)
int sz, len, buf_len;
u32 ifh[4];
u32 val;
- struct frame_info info;
+ struct frame_info info = {};
+ struct timespec64 ts;
+ struct skb_shared_hwtstamps *shhwtstamps;
+ u64 tod_in_ns;
+ u64 full_ts_in_ns;
for (i = 0; i < IFH_LEN; i++) {
err = ocelot_rx_frame_word(ocelot, grp, true, &ifh[i]);
@@ -145,6 +151,22 @@ static irqreturn_t ocelot_xtr_irq_handler(int irq, void *arg)
break;
}
+ if (ocelot->ptp) {
+ ocelot_ptp_gettime64(&ocelot->ptp_info, &ts);
+
+ tod_in_ns = ktime_set(ts.tv_sec, ts.tv_nsec);
+ if ((tod_in_ns & 0xffffffff) < info.timestamp)
+ full_ts_in_ns = (((tod_in_ns >> 32) - 1) << 32) |
+ info.timestamp;
+ else
+ full_ts_in_ns = (tod_in_ns & GENMASK_ULL(63, 32)) |
+ info.timestamp;
+
+ shhwtstamps = skb_hwtstamps(skb);
+ memset(shhwtstamps, 0, sizeof(struct skb_shared_hwtstamps));
+ shhwtstamps->hwtstamp = full_ts_in_ns;
+ }
+
/* Everything we see on an interface that is in the HW bridge
* has already been forwarded.
*/
@@ -164,6 +186,65 @@ static irqreturn_t ocelot_xtr_irq_handler(int irq, void *arg)
return IRQ_HANDLED;
}
+static irqreturn_t ocelot_ptp_rdy_irq_handler(int irq, void *arg)
+{
+ struct ocelot *ocelot = arg;
+
+ do {
+ struct skb_shared_hwtstamps shhwtstamps;
+ struct list_head *pos, *tmp;
+ struct ocelot_skb *entry;
+ struct ocelot_port *port;
+ struct timespec64 ts;
+ struct sk_buff *skb = NULL;
+ u32 val, id, txport;
+
+ val = ocelot_read(ocelot, SYS_PTP_STATUS);
+
+ /* Check if a timestamp can be retrieved */
+ if (!(val & SYS_PTP_STATUS_PTP_MESS_VLD))
+ break;
+
+ WARN_ON(val & SYS_PTP_STATUS_PTP_OVFL);
+
+ /* Retrieve the ts ID and Tx port */
+ id = SYS_PTP_STATUS_PTP_MESS_ID_X(val);
+ txport = SYS_PTP_STATUS_PTP_MESS_TXPORT_X(val);
+
+ /* Retrieve its associated skb */
+ port = ocelot->ports[txport];
+
+ list_for_each_safe(pos, tmp, &port->skbs) {
+ entry = list_entry(pos, struct ocelot_skb, head);
+ if (entry->id != id)
+ continue;
+
+ skb = entry->skb;
+
+ list_del(pos);
+ devm_kfree(ocelot->dev, entry);
+ }
+
+ /* Next ts */
+ ocelot_write(ocelot, SYS_PTP_NXT_PTP_NXT, SYS_PTP_NXT);
+
+ if (unlikely(!skb))
+ continue;
+
+ /* Get the h/w timestamp */
+ ocelot_get_hwtimestamp(ocelot, &ts);
+
+ /* Set the timestamp into the skb */
+ memset(&shhwtstamps, 0, sizeof(shhwtstamps));
+ shhwtstamps.hwtstamp = ktime_set(ts.tv_sec, ts.tv_nsec);
+ skb_tstamp_tx(skb, &shhwtstamps);
+
+ dev_kfree_skb_any(skb);
+ } while (true);
+
+ return IRQ_HANDLED;
+}
+
static const struct of_device_id mscc_ocelot_match[] = {
{ .compatible = "mscc,vsc7514-switch" },
{ }
@@ -172,8 +253,8 @@ MODULE_DEVICE_TABLE(of, mscc_ocelot_match);
static int mscc_ocelot_probe(struct platform_device *pdev)
{
- int err, irq;
unsigned int i;
+ int err, irq_xtr, irq_ptp_rdy;
struct device_node *np = pdev->dev.of_node;
struct device_node *ports, *portnp;
struct ocelot *ocelot;
@@ -232,16 +313,31 @@ static int mscc_ocelot_probe(struct platform_device *pdev)
if (err)
return err;
- irq = platform_get_irq_byname(pdev, "xtr");
- if (irq < 0)
+ irq_xtr = platform_get_irq_byname(pdev, "xtr");
+ if (irq_xtr < 0)
return -ENODEV;
- err = devm_request_threaded_irq(&pdev->dev, irq, NULL,
+ err = devm_request_threaded_irq(&pdev->dev, irq_xtr, NULL,
ocelot_xtr_irq_handler, IRQF_ONESHOT,
"frame extraction", ocelot);
if (err)
return err;
+
+ irq_ptp_rdy = platform_get_irq_byname(pdev, "ptp_rdy");
+ if (irq_ptp_rdy > 0) {
+ err = devm_request_threaded_irq(&pdev->dev, irq_ptp_rdy, NULL,
+ ocelot_ptp_rdy_irq_handler,
+ IRQF_ONESHOT, "ptp ready",
+ ocelot);
+ if (err)
+ return err;
+ }
+
+ /* Check if we can support PTP */
+ if (irq_ptp_rdy > 0 && ocelot->targets[PTP] && ocelot->targets[VCAP])
+ ocelot->ptp = 1;
+
regmap_field_write(ocelot->regfields[SYS_RESET_CFG_MEM_INIT], 1);
regmap_field_write(ocelot->regfields[SYS_RESET_CFG_MEM_ENA], 1);
--
2.20.1
^ permalink raw reply related [flat|nested] 16+ messages in thread
* Re: [PATCH net-next 0/8] net: mscc: PTP offloading support
2019-01-17 10:02 [PATCH net-next 0/8] net: mscc: PTP offloading support Antoine Tenart
` (7 preceding siblings ...)
2019-01-17 10:02 ` [PATCH net-next 8/8] net: mscc: PTP offloading support Antoine Tenart
@ 2019-01-18 2:13 ` Richard Cochran
2019-01-18 9:09 ` Antoine Tenart
2019-01-18 5:07 ` Florian Fainelli
9 siblings, 1 reply; 16+ messages in thread
From: Richard Cochran @ 2019-01-18 2:13 UTC (permalink / raw)
To: Antoine Tenart
Cc: davem, alexandre.belloni, UNGLinuxDriver, ralf, paul.burton,
jhogan, netdev, linux-mips, thomas.petazzoni, quentin.schulz,
allan.nielsen
On Thu, Jan 17, 2019 at 11:02:04AM +0100, Antoine Tenart wrote:
> This series adds support for the PTP offloading support in the Mscc
> Ocelot Ethernet switch driver. Both PTP 1-step and 2-step modes are
> supported.
>
> In order to make use of the PTP offloading support, two new register
> banks were described in the Ocelot device tree. The use of those
> registers by the Mscc Ocelot Ethernet switch driver is made optional for
> dt compatibility reasons. For the same reason a new interrupt is
> described, and its use is also made optinal for compatibility reasons.
> All of this is done ine patches 1-5.
>
> The PTP offloading support itself is added in patch 8.
The subject lines and this description are misleading. You are not
offloading the Precision Time Protocol. Instead, this series
implements a normal PHC driver.
Please change the text to avoid the phrase, "PTP offloading".
Thanks,
Richard
^ permalink raw reply [flat|nested] 16+ messages in thread
* Re: [PATCH net-next 8/8] net: mscc: PTP offloading support
2019-01-17 10:02 ` [PATCH net-next 8/8] net: mscc: PTP offloading support Antoine Tenart
@ 2019-01-18 2:23 ` Richard Cochran
2019-01-18 9:08 ` Antoine Tenart
0 siblings, 1 reply; 16+ messages in thread
From: Richard Cochran @ 2019-01-18 2:23 UTC (permalink / raw)
To: Antoine Tenart
Cc: davem, alexandre.belloni, UNGLinuxDriver, ralf, paul.burton,
jhogan, netdev, linux-mips, thomas.petazzoni, quentin.schulz,
allan.nielsen
On Thu, Jan 17, 2019 at 11:02:12AM +0100, Antoine Tenart wrote:
> This patch adds support for offloading PTP timestamping to the Ocelot
> switch for both 1-step and 2-step modes.
For PTP Hardware Clock drivers, please add the PTP maintainer onto CC.
> +int ocelot_ptp_gettime64(struct ptp_clock_info *ptp, struct timespec64 *ts)
> +{
> + struct ocelot *ocelot = container_of(ptp, struct ocelot, ptp_info);
> + u32 val;
> + time64_t s;
> + s64 ns;
> +
> + val = ocelot_read_rix(ocelot, PTP_PIN_CFG, TOD_ACC_PIN);
> + val &= ~(PTP_PIN_CFG_SYNC | PTP_PIN_CFG_ACTION_MASK | PTP_PIN_CFG_DOM);
> + val |= PTP_PIN_CFG_ACTION(PTP_PIN_ACTION_SAVE);
> + ocelot_write_rix(ocelot, val, PTP_PIN_CFG, TOD_ACC_PIN);
> +
> + s = ocelot_read_rix(ocelot, PTP_PIN_TOD_SEC_MSB, TOD_ACC_PIN);
> + s += ocelot_read_rix(ocelot, PTP_PIN_TOD_SEC_LSB, TOD_ACC_PIN);
> + ns = ocelot_read_rix(ocelot, PTP_PIN_TOD_NSEC, TOD_ACC_PIN);
> +
> + /* Deal with negative values */
> + if (ns >= 0x3ffffff0 && ns <= 0x3fffffff) {
> + s--;
> + ns &= 0xf;
> + ns += 999999984;
> + }
> +
> + set_normalized_timespec64(ts, s, ns);
> + return 0;
> +}
> +
> +static int ocelot_ptp_settime64(struct ptp_clock_info *ptp,
> + const struct timespec64 *ts)
> +{
> + struct ocelot *ocelot = container_of(ptp, struct ocelot, ptp_info);
> + u32 val;
> +
> + val = ocelot_read_rix(ocelot, PTP_PIN_CFG, TOD_ACC_PIN);
> + val &= ~(PTP_PIN_CFG_SYNC | PTP_PIN_CFG_ACTION_MASK | PTP_PIN_CFG_DOM);
> + val |= PTP_PIN_CFG_ACTION(PTP_PIN_ACTION_IDLE);
> +
> + ocelot_write_rix(ocelot, val, PTP_PIN_CFG, TOD_ACC_PIN);
> +
> + ocelot_write_rix(ocelot, lower_32_bits(ts->tv_sec), PTP_PIN_TOD_SEC_LSB,
> + TOD_ACC_PIN);
> + ocelot_write_rix(ocelot, upper_32_bits(ts->tv_sec), PTP_PIN_TOD_SEC_MSB,
> + TOD_ACC_PIN);
> + ocelot_write_rix(ocelot, ts->tv_nsec, PTP_PIN_TOD_NSEC, TOD_ACC_PIN);
> +
> + val = ocelot_read_rix(ocelot, PTP_PIN_CFG, TOD_ACC_PIN);
> + val &= ~(PTP_PIN_CFG_SYNC | PTP_PIN_CFG_ACTION_MASK | PTP_PIN_CFG_DOM);
> + val |= PTP_PIN_CFG_ACTION(PTP_PIN_ACTION_LOAD);
> +
> + ocelot_write_rix(ocelot, val, PTP_PIN_CFG, TOD_ACC_PIN);
You are writing multiple registers. This code is not safe when called
concurrently.
Ditto for gettime, adjtime, and adjfreq.
> + return 0;
> +}
> +
> +static int ocelot_ptp_adjtime(struct ptp_clock_info *ptp, s64 delta)
> +{
> + if (delta > -(NSEC_PER_SEC / 2) && delta < (NSEC_PER_SEC / 2)) {
> + struct ocelot *ocelot = container_of(ptp, struct ocelot, ptp_info);
> + u32 val;
> +
> + val = ocelot_read_rix(ocelot, PTP_PIN_CFG, TOD_ACC_PIN);
> + val &= ~(PTP_PIN_CFG_SYNC | PTP_PIN_CFG_ACTION_MASK | PTP_PIN_CFG_DOM);
> + val |= PTP_PIN_CFG_ACTION(PTP_PIN_ACTION_IDLE);
> +
> + ocelot_write_rix(ocelot, val, PTP_PIN_CFG, TOD_ACC_PIN);
> +
> + ocelot_write_rix(ocelot, 0, PTP_PIN_TOD_SEC_LSB, TOD_ACC_PIN);
> + ocelot_write_rix(ocelot, 0, PTP_PIN_TOD_SEC_MSB, TOD_ACC_PIN);
> + ocelot_write_rix(ocelot, delta, PTP_PIN_TOD_NSEC, TOD_ACC_PIN);
> +
> + val = ocelot_read_rix(ocelot, PTP_PIN_CFG, TOD_ACC_PIN);
> + val &= ~(PTP_PIN_CFG_SYNC | PTP_PIN_CFG_ACTION_MASK | PTP_PIN_CFG_DOM);
> + val |= PTP_PIN_CFG_ACTION(PTP_PIN_ACTION_DELTA);
> +
> + ocelot_write_rix(ocelot, val, PTP_PIN_CFG, TOD_ACC_PIN);
> + } else {
> + /* Fall back using ocelot_ptp_settime64 which is not exact. */
> + struct timespec64 ts;
> + u64 now;
> +
> + ocelot_ptp_gettime64(ptp, &ts);
> +
> + now = ktime_to_ns(timespec64_to_ktime(ts));
> + ts = ns_to_timespec64(now + delta);
> +
> + ocelot_ptp_settime64(ptp, &ts);
> + }
> + return 0;
> +}
> +
> +static int ocelot_ptp_adjfreq(struct ptp_clock_info *ptp, s32 ppb)
> +{
Please implement adjfine instead.
> + struct ocelot *ocelot = container_of(ptp, struct ocelot, ptp_info);
> + u64 adj = 0;
> + u32 unit = 0, direction = 0;
> +
> + if (!ppb)
> + goto disable_adj;
> +
> + if (ppb < 0) {
> + direction = PTP_CFG_CLK_ADJ_CFG_DIR;
> + ppb = -ppb;
> + }
> +
> + adj = PSEC_PER_SEC;
> + do_div(adj, ppb);
> +
> + /* If the adjustment value is too large, use ns instead */
> + if (adj >= (1L << 30)) {
> + unit = PTP_CFG_CLK_ADJ_FREQ_NS;
> + do_div(adj, 1000);
> + }
> +
> + /* Still too big */
> + if (adj >= (1L << 30))
> + goto disable_adj;
> +
> + ocelot_write(ocelot, unit | adj, PTP_CLK_CFG_ADJ_FREQ);
> + ocelot_write(ocelot, PTP_CFG_CLK_ADJ_CFG_ENA | direction,
> + PTP_CLK_CFG_ADJ_CFG);
> + return 0;
> +
> +disable_adj:
> + ocelot_write(ocelot, 0, PTP_CLK_CFG_ADJ_CFG);
> + return 0;
> +}
> +
> +static struct ptp_clock_info ocelot_ptp_clock_info = {
> + .owner = THIS_MODULE,
> + .name = "ocelot ptp",
> + .max_adj = 0x7fffffff,
> + .n_alarm = 0,
> + .n_ext_ts = 0,
> + .n_per_out = 0,
> + .n_pins = 0,
> + .pps = 0,
> + .gettime64 = ocelot_ptp_gettime64,
> + .settime64 = ocelot_ptp_settime64,
> + .adjtime = ocelot_ptp_adjtime,
> + .adjfreq = ocelot_ptp_adjfreq,
> +};
> +
> +static int ocelot_init_timestamp(struct ocelot *ocelot)
> +{
> + ocelot->ptp_info = ocelot_ptp_clock_info;
> +
> + ocelot->ptp_clock = ptp_clock_register(&ocelot->ptp_info, ocelot->dev);
> + if (IS_ERR(ocelot->ptp_clock))
> + return PTR_ERR(ocelot->ptp_clock);
> +
> + ocelot_write(ocelot, SYS_PTP_CFG_PTP_STAMP_WID(30), SYS_PTP_CFG);
> + ocelot_write(ocelot, 0xffffffff, ANA_TABLES_PTP_ID_LOW);
> + ocelot_write(ocelot, 0xffffffff, ANA_TABLES_PTP_ID_HIGH);
> +
> + ocelot_write(ocelot, PTP_CFG_MISC_PTP_EN, PTP_CFG_MISC);
> +
> + return 0;
> +}
> +
> int ocelot_probe_port(struct ocelot *ocelot, u8 port,
> void __iomem *regs,
> struct phy_device *phy)
> @@ -1649,6 +2138,8 @@ int ocelot_probe_port(struct ocelot *ocelot, u8 port,
> ocelot_mact_learn(ocelot, PGID_CPU, dev->dev_addr, ocelot_port->pvid,
> ENTRYTYPE_LOCKED);
>
> + INIT_LIST_HEAD(&ocelot_port->skbs);
> +
> err = register_netdev(dev);
> if (err) {
> dev_err(ocelot->dev, "register_netdev failed\n");
> @@ -1669,7 +2160,7 @@ EXPORT_SYMBOL(ocelot_probe_port);
> int ocelot_init(struct ocelot *ocelot)
> {
> u32 port;
> - int i, cpu = ocelot->num_phys_ports;
> + int i, ret, cpu = ocelot->num_phys_ports;
> char queue_name[32];
>
> ocelot->lags = devm_kcalloc(ocelot->dev, ocelot->num_phys_ports,
> @@ -1796,6 +2287,18 @@ int ocelot_init(struct ocelot *ocelot)
> INIT_DELAYED_WORK(&ocelot->stats_work, ocelot_check_stats);
> queue_delayed_work(ocelot->stats_queue, &ocelot->stats_work,
> OCELOT_STATS_CHECK_DELAY);
> +
> + if (ocelot->ptp) {
> + ret = ocelot_init_timestamp(ocelot);
> + if (ret) {
> + dev_err(ocelot->dev,
> + "Timestamp initialization failed\n");
> + return ret;
> + }
> +
> + ocelot_vcap_is2_init(ocelot);
> + }
> +
> return 0;
> }
> EXPORT_SYMBOL(ocelot_init);
> diff --git a/drivers/net/ethernet/mscc/ocelot.h b/drivers/net/ethernet/mscc/ocelot.h
> index 994ba953d60e..ed1583037dc2 100644
> --- a/drivers/net/ethernet/mscc/ocelot.h
> +++ b/drivers/net/ethernet/mscc/ocelot.h
> @@ -11,9 +11,11 @@
> #include <linux/bitops.h>
> #include <linux/etherdevice.h>
> #include <linux/if_vlan.h>
> +#include <linux/net_tstamp.h>
> #include <linux/phy.h>
> #include <linux/phy/phy.h>
> #include <linux/platform_device.h>
> +#include <linux/ptp_clock_kernel.h>
> #include <linux/regmap.h>
>
> #include "ocelot_ana.h"
> @@ -46,6 +48,8 @@ struct frame_info {
> u16 port;
> u16 vid;
> u8 tag_type;
> + u16 rew_op;
> + u32 timestamp; /* rew_val */
> };
>
> #define IFH_INJ_BYPASS BIT(31)
> @@ -54,6 +58,12 @@ struct frame_info {
> #define IFH_TAG_TYPE_C 0
> #define IFH_TAG_TYPE_S 1
>
> +#define IFH_REW_OP_NOOP 0x0
> +#define IFH_REW_OP_DSCP 0x1
> +#define IFH_REW_OP_ONE_STEP_PTP 0x2
> +#define IFH_REW_OP_TWO_STEP_PTP 0x3
> +#define IFH_REW_OP_ORIGIN_PTP 0x5
> +
> #define OCELOT_SPEED_2500 0
> #define OCELOT_SPEED_1000 1
> #define OCELOT_SPEED_100 2
> @@ -401,6 +411,13 @@ enum ocelot_regfield {
> REGFIELD_MAX
> };
>
> +enum ocelot_clk_pins {
> + ALT_PPS_PIN = 1,
> + EXT_CLK_PIN,
> + ALT_LDST_PIN,
> + TOD_ACC_PIN
> +};
> +
> struct ocelot_multicast {
> struct list_head list;
> unsigned char addr[ETH_ALEN];
> @@ -450,6 +467,12 @@ struct ocelot {
> u64 *stats;
> struct delayed_work stats_work;
> struct workqueue_struct *stats_queue;
> +
> + u8 ptp:1;
> + struct ptp_clock *ptp_clock;
> + struct ptp_clock_info ptp_info;
> + struct hwtstamp_config hwtstamp_config;
> + struct mutex ptp_lock;
Just what does this mutex protect? Please add a comment.
Thanks,
Richard
^ permalink raw reply [flat|nested] 16+ messages in thread
* Re: [PATCH net-next 0/8] net: mscc: PTP offloading support
2019-01-17 10:02 [PATCH net-next 0/8] net: mscc: PTP offloading support Antoine Tenart
` (8 preceding siblings ...)
2019-01-18 2:13 ` [PATCH net-next 0/8] " Richard Cochran
@ 2019-01-18 5:07 ` Florian Fainelli
2019-01-18 8:58 ` Antoine Tenart
9 siblings, 1 reply; 16+ messages in thread
From: Florian Fainelli @ 2019-01-18 5:07 UTC (permalink / raw)
To: Antoine Tenart, davem, alexandre.belloni, UNGLinuxDriver, ralf,
paul.burton, jhogan
Cc: netdev, linux-mips, thomas.petazzoni, quentin.schulz, allan.nielsen
On 1/17/2019 2:02 AM, Antoine Tenart wrote:
> Hi all,
>
> This series adds support for the PTP offloading support in the Mscc
> Ocelot Ethernet switch driver. Both PTP 1-step and 2-step modes are
> supported.
>
> In order to make use of the PTP offloading support, two new register
> banks were described in the Ocelot device tree. The use of those
> registers by the Mscc Ocelot Ethernet switch driver is made optional for
> dt compatibility reasons. For the same reason a new interrupt is
> described, and its use is also made optinal for compatibility reasons.
> All of this is done ine patches 1-5.
>
> The PTP offloading support itself is added in patch 8.
>
> While doing this support, a few reworks were done in the Ocelot switch
> driver, in patches 6-7.
>
> Patches 2 and 4 should probably go through the MIPS tree.
Looks like you missed copying netdev on this patch series, do you mind
re-sending there as well?
>
> Thanks!
> Antoine
>
> Antoine Tenart (8):
> Documentation/bindings: net: ocelot: document the VCAP and PTP banks
> MIPS: dts: mscc: describe VCAP and PTP register ranges
> Documentation/bindings: net: ocelot: document the PTP ready IRQ
> MIPS: dts: mscc: describe the PTP ready interrupt
> net: mscc: describe the VCAP and PTP register ranges
> net: mscc: improve the frame header parsing readability
> net: mscc: remove the frame_info cpuq member
> net: mscc: PTP offloading support
>
> .../devicetree/bindings/net/mscc-ocelot.txt | 22 +-
> arch/mips/boot/dts/mscc/ocelot.dtsi | 14 +-
> drivers/net/ethernet/mscc/ocelot.c | 509 +++++++++++++++++-
> drivers/net/ethernet/mscc/ocelot.h | 55 +-
> drivers/net/ethernet/mscc/ocelot_board.c | 150 +++++-
> drivers/net/ethernet/mscc/ocelot_ptp.h | 41 ++
> drivers/net/ethernet/mscc/ocelot_regs.c | 22 +
> drivers/net/ethernet/mscc/ocelot_vcap.h | 104 ++++
> 8 files changed, 877 insertions(+), 40 deletions(-)
> create mode 100644 drivers/net/ethernet/mscc/ocelot_ptp.h
> create mode 100644 drivers/net/ethernet/mscc/ocelot_vcap.h
>
--
Florian
^ permalink raw reply [flat|nested] 16+ messages in thread
* Re: [PATCH net-next 0/8] net: mscc: PTP offloading support
2019-01-18 5:07 ` Florian Fainelli
@ 2019-01-18 8:58 ` Antoine Tenart
2019-01-18 18:16 ` Florian Fainelli
0 siblings, 1 reply; 16+ messages in thread
From: Antoine Tenart @ 2019-01-18 8:58 UTC (permalink / raw)
To: Florian Fainelli
Cc: Antoine Tenart, davem, alexandre.belloni, UNGLinuxDriver, ralf,
paul.burton, jhogan, netdev, linux-mips, thomas.petazzoni,
quentin.schulz, allan.nielsen
Hi Florian,
On Thu, Jan 17, 2019 at 09:07:05PM -0800, Florian Fainelli wrote:
> On 1/17/2019 2:02 AM, Antoine Tenart wrote:
> >
> > This series adds support for the PTP offloading support in the Mscc
> > Ocelot Ethernet switch driver. Both PTP 1-step and 2-step modes are
> > supported.
> >
> > In order to make use of the PTP offloading support, two new register
> > banks were described in the Ocelot device tree. The use of those
> > registers by the Mscc Ocelot Ethernet switch driver is made optional for
> > dt compatibility reasons. For the same reason a new interrupt is
> > described, and its use is also made optinal for compatibility reasons.
> > All of this is done ine patches 1-5.
> >
> > The PTP offloading support itself is added in patch 8.
> >
> > While doing this support, a few reworks were done in the Ocelot switch
> > driver, in patches 6-7.
> >
> > Patches 2 and 4 should probably go through the MIPS tree.
>
> Looks like you missed copying netdev on this patch series, do you mind
> re-sending there as well?
I just checked and netdev is Cc'ed. I'll prepare a v2 to take in account
the comments, so I'll sent it again anyway.
Thanks!
Antoine
--
Antoine Ténart, Bootlin
Embedded Linux and Kernel engineering
https://bootlin.com
^ permalink raw reply [flat|nested] 16+ messages in thread
* Re: [PATCH net-next 8/8] net: mscc: PTP offloading support
2019-01-18 2:23 ` Richard Cochran
@ 2019-01-18 9:08 ` Antoine Tenart
0 siblings, 0 replies; 16+ messages in thread
From: Antoine Tenart @ 2019-01-18 9:08 UTC (permalink / raw)
To: Richard Cochran
Cc: Antoine Tenart, davem, alexandre.belloni, UNGLinuxDriver, ralf,
paul.burton, jhogan, netdev, linux-mips, thomas.petazzoni,
quentin.schulz, allan.nielsen
Hi Richard,
On Thu, Jan 17, 2019 at 06:23:43PM -0800, Richard Cochran wrote:
> On Thu, Jan 17, 2019 at 11:02:12AM +0100, Antoine Tenart wrote:
> > This patch adds support for offloading PTP timestamping to the Ocelot
> > switch for both 1-step and 2-step modes.
>
> For PTP Hardware Clock drivers, please add the PTP maintainer onto CC.
Will do for the v2, sorry about that.
> > +static int ocelot_ptp_settime64(struct ptp_clock_info *ptp,
> > + const struct timespec64 *ts)
> > +{
> > + struct ocelot *ocelot = container_of(ptp, struct ocelot, ptp_info);
> > + u32 val;
> > +
> > + val = ocelot_read_rix(ocelot, PTP_PIN_CFG, TOD_ACC_PIN);
> > + val &= ~(PTP_PIN_CFG_SYNC | PTP_PIN_CFG_ACTION_MASK | PTP_PIN_CFG_DOM);
> > + val |= PTP_PIN_CFG_ACTION(PTP_PIN_ACTION_IDLE);
> > +
> > + ocelot_write_rix(ocelot, val, PTP_PIN_CFG, TOD_ACC_PIN);
> > +
> > + ocelot_write_rix(ocelot, lower_32_bits(ts->tv_sec), PTP_PIN_TOD_SEC_LSB,
> > + TOD_ACC_PIN);
> > + ocelot_write_rix(ocelot, upper_32_bits(ts->tv_sec), PTP_PIN_TOD_SEC_MSB,
> > + TOD_ACC_PIN);
> > + ocelot_write_rix(ocelot, ts->tv_nsec, PTP_PIN_TOD_NSEC, TOD_ACC_PIN);
> > +
> > + val = ocelot_read_rix(ocelot, PTP_PIN_CFG, TOD_ACC_PIN);
> > + val &= ~(PTP_PIN_CFG_SYNC | PTP_PIN_CFG_ACTION_MASK | PTP_PIN_CFG_DOM);
> > + val |= PTP_PIN_CFG_ACTION(PTP_PIN_ACTION_LOAD);
> > +
> > + ocelot_write_rix(ocelot, val, PTP_PIN_CFG, TOD_ACC_PIN);
>
> You are writing multiple registers. This code is not safe when called
> concurrently.
>
> Ditto for gettime, adjtime, and adjfreq.
Right, I'll fix that.
> > +static int ocelot_ptp_adjfreq(struct ptp_clock_info *ptp, s32 ppb)
> > +{
>
> Please implement adjfine instead.
OK, I'll look into it.
> > + struct mutex ptp_lock;
>
> Just what does this mutex protect? Please add a comment.
OK.
Thanks!
Antoine
--
Antoine Ténart, Bootlin
Embedded Linux and Kernel engineering
https://bootlin.com
^ permalink raw reply [flat|nested] 16+ messages in thread
* Re: [PATCH net-next 0/8] net: mscc: PTP offloading support
2019-01-18 2:13 ` [PATCH net-next 0/8] " Richard Cochran
@ 2019-01-18 9:09 ` Antoine Tenart
0 siblings, 0 replies; 16+ messages in thread
From: Antoine Tenart @ 2019-01-18 9:09 UTC (permalink / raw)
To: Richard Cochran
Cc: Antoine Tenart, davem, alexandre.belloni, UNGLinuxDriver, ralf,
paul.burton, jhogan, netdev, linux-mips, thomas.petazzoni,
quentin.schulz, allan.nielsen
Hi Richard,
On Thu, Jan 17, 2019 at 06:13:42PM -0800, Richard Cochran wrote:
> On Thu, Jan 17, 2019 at 11:02:04AM +0100, Antoine Tenart wrote:
> > This series adds support for the PTP offloading support in the Mscc
> > Ocelot Ethernet switch driver. Both PTP 1-step and 2-step modes are
> > supported.
> >
> > In order to make use of the PTP offloading support, two new register
> > banks were described in the Ocelot device tree. The use of those
> > registers by the Mscc Ocelot Ethernet switch driver is made optional for
> > dt compatibility reasons. For the same reason a new interrupt is
> > described, and its use is also made optinal for compatibility reasons.
> > All of this is done ine patches 1-5.
> >
> > The PTP offloading support itself is added in patch 8.
>
> The subject lines and this description are misleading. You are not
> offloading the Precision Time Protocol. Instead, this series
> implements a normal PHC driver.
>
> Please change the text to avoid the phrase, "PTP offloading".
Will do.
Thanks!
Antoine
--
Antoine Ténart, Bootlin
Embedded Linux and Kernel engineering
https://bootlin.com
^ permalink raw reply [flat|nested] 16+ messages in thread
* Re: [PATCH net-next 0/8] net: mscc: PTP offloading support
2019-01-18 8:58 ` Antoine Tenart
@ 2019-01-18 18:16 ` Florian Fainelli
0 siblings, 0 replies; 16+ messages in thread
From: Florian Fainelli @ 2019-01-18 18:16 UTC (permalink / raw)
To: Antoine Tenart
Cc: davem, alexandre.belloni, UNGLinuxDriver, ralf, paul.burton,
jhogan, netdev, linux-mips, thomas.petazzoni, quentin.schulz,
allan.nielsen
On 1/18/19 12:58 AM, Antoine Tenart wrote:
> Hi Florian,
>
> On Thu, Jan 17, 2019 at 09:07:05PM -0800, Florian Fainelli wrote:
>> On 1/17/2019 2:02 AM, Antoine Tenart wrote:
>>>
>>> This series adds support for the PTP offloading support in the Mscc
>>> Ocelot Ethernet switch driver. Both PTP 1-step and 2-step modes are
>>> supported.
>>>
>>> In order to make use of the PTP offloading support, two new register
>>> banks were described in the Ocelot device tree. The use of those
>>> registers by the Mscc Ocelot Ethernet switch driver is made optional for
>>> dt compatibility reasons. For the same reason a new interrupt is
>>> described, and its use is also made optinal for compatibility reasons.
>>> All of this is done ine patches 1-5.
>>>
>>> The PTP offloading support itself is added in patch 8.
>>>
>>> While doing this support, a few reworks were done in the Ocelot switch
>>> driver, in patches 6-7.
>>>
>>> Patches 2 and 4 should probably go through the MIPS tree.
>>
>> Looks like you missed copying netdev on this patch series, do you mind
>> re-sending there as well?
>
> I just checked and netdev is Cc'ed. I'll prepare a v2 to take in account
> the comments, so I'll sent it again anyway.
Indeed, my bad.
--
Florian
^ permalink raw reply [flat|nested] 16+ messages in thread
end of thread, other threads:[~2019-01-18 18:16 UTC | newest]
Thread overview: 16+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2019-01-17 10:02 [PATCH net-next 0/8] net: mscc: PTP offloading support Antoine Tenart
2019-01-17 10:02 ` [PATCH net-next 1/8] Documentation/bindings: net: ocelot: document the VCAP and PTP banks Antoine Tenart
2019-01-17 10:02 ` [PATCH net-next 2/8] MIPS: dts: mscc: describe VCAP and PTP register ranges Antoine Tenart
2019-01-17 10:02 ` [PATCH net-next 3/8] Documentation/bindings: net: ocelot: document the PTP ready IRQ Antoine Tenart
2019-01-17 10:02 ` [PATCH net-next 4/8] MIPS: dts: mscc: describe the PTP ready interrupt Antoine Tenart
2019-01-17 10:02 ` [PATCH net-next 5/8] net: mscc: describe the VCAP and PTP register ranges Antoine Tenart
2019-01-17 10:02 ` [PATCH net-next 6/8] net: mscc: improve the frame header parsing readability Antoine Tenart
2019-01-17 10:02 ` [PATCH net-next 7/8] net: mscc: remove the frame_info cpuq member Antoine Tenart
2019-01-17 10:02 ` [PATCH net-next 8/8] net: mscc: PTP offloading support Antoine Tenart
2019-01-18 2:23 ` Richard Cochran
2019-01-18 9:08 ` Antoine Tenart
2019-01-18 2:13 ` [PATCH net-next 0/8] " Richard Cochran
2019-01-18 9:09 ` Antoine Tenart
2019-01-18 5:07 ` Florian Fainelli
2019-01-18 8:58 ` Antoine Tenart
2019-01-18 18:16 ` Florian Fainelli
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).