summaryrefslogtreecommitdiffstats
path: root/drivers/net
diff options
context:
space:
mode:
authorArun Ramadoss <arun.ramadoss@microchip.com>2023-01-10 14:19:20 +0530
committerDavid S. Miller <davem@davemloft.net>2023-01-13 08:40:40 +0000
commitc2977c61f32e0d54319d158a04cad5fd82c2afcf (patch)
tree59499f782364e7e432d7036a1fccd679085dd678 /drivers/net
parentc59e12a140fbfbef0fae72be71b47cdb05f25713 (diff)
downloadlinux-stable-c2977c61f32e0d54319d158a04cad5fd82c2afcf.tar.gz
linux-stable-c2977c61f32e0d54319d158a04cad5fd82c2afcf.tar.bz2
linux-stable-c2977c61f32e0d54319d158a04cad5fd82c2afcf.zip
net: dsa: microchip: ptp: add 4 bytes in tail tag when ptp enabled
When the PTP is enabled in hardware bit 6 of PTP_MSG_CONF1 register, the transmit frame needs additional 4 bytes before the tail tag. It is needed for all the transmission packets irrespective of PTP packets or not. The 4-byte timestamp field is 0 for frames other than Pdelay_Resp. For the one-step Pdelay_Resp, the switch needs the receive timestamp of the Pdelay_Req message so that it can put the turnaround time in the correction field. Since PTP has to be enabled for both Transmission and reception timestamping, driver needs to track of the tx and rx setting of the all the user ports in the switch. Two flags hw_tx_en and hw_rx_en are added in ksz_port to track the timestampping setting of each port. When any one of ports has tx or rx timestampping enabled, bit 6 of PTP_MSG_CONF1 is set and it is indicated to tag_ksz.c through tagger bytes. This flag adds 4 additional bytes to the tail tag. When tx and rx timestamping of all the ports are disabled, then 4 bytes are not added. Tested using hwstamp -i <interface> Signed-off-by: Arun Ramadoss <arun.ramadoss@microchip.com> Reviewed-by: Vladimir Oltean <olteanv@gmail.com> # mostly api Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'drivers/net')
-rw-r--r--drivers/net/dsa/microchip/ksz_common.h2
-rw-r--r--drivers/net/dsa/microchip/ksz_ptp.c34
2 files changed, 34 insertions, 2 deletions
diff --git a/drivers/net/dsa/microchip/ksz_common.h b/drivers/net/dsa/microchip/ksz_common.h
index a5ce7ec30ba2..641aca78ef05 100644
--- a/drivers/net/dsa/microchip/ksz_common.h
+++ b/drivers/net/dsa/microchip/ksz_common.h
@@ -104,6 +104,8 @@ struct ksz_port {
u8 num;
#if IS_ENABLED(CONFIG_NET_DSA_MICROCHIP_KSZ_PTP)
struct hwtstamp_config tstamp_config;
+ bool hwts_tx_en;
+ bool hwts_rx_en;
#endif
};
diff --git a/drivers/net/dsa/microchip/ksz_ptp.c b/drivers/net/dsa/microchip/ksz_ptp.c
index 6f6747671610..5281aeb84db6 100644
--- a/drivers/net/dsa/microchip/ksz_ptp.c
+++ b/drivers/net/dsa/microchip/ksz_ptp.c
@@ -5,6 +5,7 @@
* Copyright (C) 2022 Microchip Technology Inc.
*/
+#include <linux/dsa/ksz_common.h>
#include <linux/kernel.h>
#include <linux/ptp_classify.h>
#include <linux/ptp_clock_kernel.h>
@@ -24,6 +25,27 @@
#define KSZ_PTP_INC_NS 40ULL /* HW clock is incremented every 40 ns (by 40) */
#define KSZ_PTP_SUBNS_BITS 32
+static int ksz_ptp_enable_mode(struct ksz_device *dev)
+{
+ struct ksz_tagger_data *tagger_data = ksz_tagger_data(dev->ds);
+ struct ksz_port *prt;
+ struct dsa_port *dp;
+ bool tag_en = false;
+
+ dsa_switch_for_each_user_port(dp, dev->ds) {
+ prt = &dev->ports[dp->index];
+ if (prt->hwts_tx_en || prt->hwts_rx_en) {
+ tag_en = true;
+ break;
+ }
+ }
+
+ tagger_data->hwtstamp_set_state(dev->ds, tag_en);
+
+ return ksz_rmw16(dev, REG_PTP_MSG_CONF1, PTP_ENABLE,
+ tag_en ? PTP_ENABLE : 0);
+}
+
/* The function is return back the capability of timestamping feature when
* requested through ethtool -T <interface> utility
*/
@@ -67,6 +89,7 @@ int ksz_hwtstamp_get(struct dsa_switch *ds, int port, struct ifreq *ifr)
}
static int ksz_set_hwtstamp_config(struct ksz_device *dev,
+ struct ksz_port *prt,
struct hwtstamp_config *config)
{
if (config->flags)
@@ -74,7 +97,10 @@ static int ksz_set_hwtstamp_config(struct ksz_device *dev,
switch (config->tx_type) {
case HWTSTAMP_TX_OFF:
+ prt->hwts_tx_en = false;
+ break;
case HWTSTAMP_TX_ONESTEP_P2P:
+ prt->hwts_tx_en = true;
break;
default:
return -ERANGE;
@@ -82,25 +108,29 @@ static int ksz_set_hwtstamp_config(struct ksz_device *dev,
switch (config->rx_filter) {
case HWTSTAMP_FILTER_NONE:
+ prt->hwts_rx_en = false;
break;
case HWTSTAMP_FILTER_PTP_V2_L4_EVENT:
case HWTSTAMP_FILTER_PTP_V2_L4_SYNC:
config->rx_filter = HWTSTAMP_FILTER_PTP_V2_L4_EVENT;
+ prt->hwts_rx_en = true;
break;
case HWTSTAMP_FILTER_PTP_V2_L2_EVENT:
case HWTSTAMP_FILTER_PTP_V2_L2_SYNC:
config->rx_filter = HWTSTAMP_FILTER_PTP_V2_L2_EVENT;
+ prt->hwts_rx_en = true;
break;
case HWTSTAMP_FILTER_PTP_V2_EVENT:
case HWTSTAMP_FILTER_PTP_V2_SYNC:
config->rx_filter = HWTSTAMP_FILTER_PTP_V2_EVENT;
+ prt->hwts_rx_en = true;
break;
default:
config->rx_filter = HWTSTAMP_FILTER_NONE;
return -ERANGE;
}
- return 0;
+ return ksz_ptp_enable_mode(dev);
}
int ksz_hwtstamp_set(struct dsa_switch *ds, int port, struct ifreq *ifr)
@@ -116,7 +146,7 @@ int ksz_hwtstamp_set(struct dsa_switch *ds, int port, struct ifreq *ifr)
if (ret)
return ret;
- ret = ksz_set_hwtstamp_config(dev, &config);
+ ret = ksz_set_hwtstamp_config(dev, prt, &config);
if (ret)
return ret;