Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

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>

authored by

Arun Ramadoss and committed by
David S. Miller
c2977c61 c59e12a1

+145 -9
+1
MAINTAINERS
··· 13710 13710 F: Documentation/devicetree/bindings/net/dsa/microchip,ksz.yaml 13711 13711 F: Documentation/devicetree/bindings/net/dsa/microchip,lan937x.yaml 13712 13712 F: drivers/net/dsa/microchip/* 13713 + F: include/linux/dsa/ksz_common.h 13713 13714 F: include/linux/platform_data/microchip-ksz.h 13714 13715 F: net/dsa/tag_ksz.c 13715 13716
+2
drivers/net/dsa/microchip/ksz_common.h
··· 104 104 u8 num; 105 105 #if IS_ENABLED(CONFIG_NET_DSA_MICROCHIP_KSZ_PTP) 106 106 struct hwtstamp_config tstamp_config; 107 + bool hwts_tx_en; 108 + bool hwts_rx_en; 107 109 #endif 108 110 }; 109 111
+32 -2
drivers/net/dsa/microchip/ksz_ptp.c
··· 5 5 * Copyright (C) 2022 Microchip Technology Inc. 6 6 */ 7 7 8 + #include <linux/dsa/ksz_common.h> 8 9 #include <linux/kernel.h> 9 10 #include <linux/ptp_classify.h> 10 11 #include <linux/ptp_clock_kernel.h> ··· 24 23 25 24 #define KSZ_PTP_INC_NS 40ULL /* HW clock is incremented every 40 ns (by 40) */ 26 25 #define KSZ_PTP_SUBNS_BITS 32 26 + 27 + static int ksz_ptp_enable_mode(struct ksz_device *dev) 28 + { 29 + struct ksz_tagger_data *tagger_data = ksz_tagger_data(dev->ds); 30 + struct ksz_port *prt; 31 + struct dsa_port *dp; 32 + bool tag_en = false; 33 + 34 + dsa_switch_for_each_user_port(dp, dev->ds) { 35 + prt = &dev->ports[dp->index]; 36 + if (prt->hwts_tx_en || prt->hwts_rx_en) { 37 + tag_en = true; 38 + break; 39 + } 40 + } 41 + 42 + tagger_data->hwtstamp_set_state(dev->ds, tag_en); 43 + 44 + return ksz_rmw16(dev, REG_PTP_MSG_CONF1, PTP_ENABLE, 45 + tag_en ? PTP_ENABLE : 0); 46 + } 27 47 28 48 /* The function is return back the capability of timestamping feature when 29 49 * requested through ethtool -T <interface> utility ··· 89 67 } 90 68 91 69 static int ksz_set_hwtstamp_config(struct ksz_device *dev, 70 + struct ksz_port *prt, 92 71 struct hwtstamp_config *config) 93 72 { 94 73 if (config->flags) ··· 97 74 98 75 switch (config->tx_type) { 99 76 case HWTSTAMP_TX_OFF: 77 + prt->hwts_tx_en = false; 78 + break; 100 79 case HWTSTAMP_TX_ONESTEP_P2P: 80 + prt->hwts_tx_en = true; 101 81 break; 102 82 default: 103 83 return -ERANGE; ··· 108 82 109 83 switch (config->rx_filter) { 110 84 case HWTSTAMP_FILTER_NONE: 85 + prt->hwts_rx_en = false; 111 86 break; 112 87 case HWTSTAMP_FILTER_PTP_V2_L4_EVENT: 113 88 case HWTSTAMP_FILTER_PTP_V2_L4_SYNC: 114 89 config->rx_filter = HWTSTAMP_FILTER_PTP_V2_L4_EVENT; 90 + prt->hwts_rx_en = true; 115 91 break; 116 92 case HWTSTAMP_FILTER_PTP_V2_L2_EVENT: 117 93 case HWTSTAMP_FILTER_PTP_V2_L2_SYNC: 118 94 config->rx_filter = HWTSTAMP_FILTER_PTP_V2_L2_EVENT; 95 + prt->hwts_rx_en = true; 119 96 break; 120 97 case HWTSTAMP_FILTER_PTP_V2_EVENT: 121 98 case HWTSTAMP_FILTER_PTP_V2_SYNC: 122 99 config->rx_filter = HWTSTAMP_FILTER_PTP_V2_EVENT; 100 + prt->hwts_rx_en = true; 123 101 break; 124 102 default: 125 103 config->rx_filter = HWTSTAMP_FILTER_NONE; 126 104 return -ERANGE; 127 105 } 128 106 129 - return 0; 107 + return ksz_ptp_enable_mode(dev); 130 108 } 131 109 132 110 int ksz_hwtstamp_set(struct dsa_switch *ds, int port, struct ifreq *ifr) ··· 146 116 if (ret) 147 117 return ret; 148 118 149 - ret = ksz_set_hwtstamp_config(dev, &config); 119 + ret = ksz_set_hwtstamp_config(dev, prt, &config); 150 120 if (ret) 151 121 return ret; 152 122
+22
include/linux/dsa/ksz_common.h
··· 1 + /* SPDX-License-Identifier: GPL-2.0 */ 2 + /* Microchip switch tag common header 3 + * 4 + * Copyright (C) 2022 Microchip Technology Inc. 5 + */ 6 + 7 + #ifndef _NET_DSA_KSZ_COMMON_H_ 8 + #define _NET_DSA_KSZ_COMMON_H_ 9 + 10 + #include <net/dsa.h> 11 + 12 + struct ksz_tagger_data { 13 + void (*hwtstamp_set_state)(struct dsa_switch *ds, bool on); 14 + }; 15 + 16 + static inline struct ksz_tagger_data * 17 + ksz_tagger_data(struct dsa_switch *ds) 18 + { 19 + return ds->tagger_data; 20 + } 21 + 22 + #endif /* _NET_DSA_KSZ_COMMON_H_ */
+88 -7
net/dsa/tag_ksz.c
··· 4 4 * Copyright (c) 2017 Microchip Technology 5 5 */ 6 6 7 + #include <linux/dsa/ksz_common.h> 7 8 #include <linux/etherdevice.h> 8 9 #include <linux/list.h> 9 10 #include <net/dsa.h> ··· 17 16 #define LAN937X_NAME "lan937x" 18 17 19 18 /* Typically only one byte is used for tail tag. */ 19 + #define KSZ_PTP_TAG_LEN 4 20 20 #define KSZ_EGRESS_TAG_LEN 1 21 21 #define KSZ_INGRESS_TAG_LEN 1 22 + 23 + #define KSZ_HWTS_EN 0 24 + 25 + struct ksz_tagger_private { 26 + struct ksz_tagger_data data; /* Must be first */ 27 + unsigned long state; 28 + }; 29 + 30 + static struct ksz_tagger_private * 31 + ksz_tagger_private(struct dsa_switch *ds) 32 + { 33 + return ds->tagger_data; 34 + } 35 + 36 + static void ksz_hwtstamp_set_state(struct dsa_switch *ds, bool on) 37 + { 38 + struct ksz_tagger_private *priv = ksz_tagger_private(ds); 39 + 40 + if (on) 41 + set_bit(KSZ_HWTS_EN, &priv->state); 42 + else 43 + clear_bit(KSZ_HWTS_EN, &priv->state); 44 + } 45 + 46 + static void ksz_disconnect(struct dsa_switch *ds) 47 + { 48 + struct ksz_tagger_private *priv = ds->tagger_data; 49 + 50 + kfree(priv); 51 + ds->tagger_data = NULL; 52 + } 53 + 54 + static int ksz_connect(struct dsa_switch *ds) 55 + { 56 + struct ksz_tagger_data *tagger_data; 57 + struct ksz_tagger_private *priv; 58 + 59 + priv = kzalloc(sizeof(*priv), GFP_KERNEL); 60 + if (!priv) 61 + return -ENOMEM; 62 + 63 + /* Export functions for switch driver use */ 64 + tagger_data = &priv->data; 65 + tagger_data->hwtstamp_set_state = ksz_hwtstamp_set_state; 66 + ds->tagger_data = priv; 67 + 68 + return 0; 69 + } 22 70 23 71 static struct sk_buff *ksz_common_rcv(struct sk_buff *skb, 24 72 struct net_device *dev, ··· 142 92 MODULE_ALIAS_DSA_TAG_DRIVER(DSA_TAG_PROTO_KSZ8795, KSZ8795_NAME); 143 93 144 94 /* 145 - * For Ingress (Host -> KSZ9477), 2 bytes are added before FCS. 95 + * For Ingress (Host -> KSZ9477), 2/6 bytes are added before FCS. 146 96 * --------------------------------------------------------------------------- 147 - * DA(6bytes)|SA(6bytes)|....|Data(nbytes)|tag0(1byte)|tag1(1byte)|FCS(4bytes) 97 + * DA(6bytes)|SA(6bytes)|....|Data(nbytes)|ts(4bytes)|tag0(1byte)|tag1(1byte)| 98 + * FCS(4bytes) 148 99 * --------------------------------------------------------------------------- 100 + * ts : time stamp (Present only if PTP is enabled in the Hardware) 149 101 * tag0 : Prioritization (not used now) 150 102 * tag1 : each bit represents port (eg, 0x01=port1, 0x02=port2, 0x10=port5) 151 103 * ··· 166 114 #define KSZ9477_TAIL_TAG_OVERRIDE BIT(9) 167 115 #define KSZ9477_TAIL_TAG_LOOKUP BIT(10) 168 116 117 + /* Time stamp tag *needs* to be inserted if PTP is enabled in hardware. 118 + * Regardless of Whether it is a PTP frame or not. 119 + */ 120 + static void ksz_xmit_timestamp(struct dsa_port *dp, struct sk_buff *skb) 121 + { 122 + struct ksz_tagger_private *priv; 123 + 124 + priv = ksz_tagger_private(dp->ds); 125 + 126 + if (!test_bit(KSZ_HWTS_EN, &priv->state)) 127 + return; 128 + 129 + put_unaligned_be32(0, skb_put(skb, KSZ_PTP_TAG_LEN)); 130 + } 131 + 169 132 static struct sk_buff *ksz9477_xmit(struct sk_buff *skb, 170 133 struct net_device *dev) 171 134 { ··· 193 126 return NULL; 194 127 195 128 /* Tag encoding */ 129 + ksz_xmit_timestamp(dp, skb); 130 + 196 131 tag = skb_put(skb, KSZ9477_INGRESS_TAG_LEN); 197 132 addr = skb_mac_header(skb); 198 133 ··· 227 158 .proto = DSA_TAG_PROTO_KSZ9477, 228 159 .xmit = ksz9477_xmit, 229 160 .rcv = ksz9477_rcv, 230 - .needed_tailroom = KSZ9477_INGRESS_TAG_LEN, 161 + .connect = ksz_connect, 162 + .disconnect = ksz_disconnect, 163 + .needed_tailroom = KSZ9477_INGRESS_TAG_LEN + KSZ_PTP_TAG_LEN, 231 164 }; 232 165 233 166 DSA_TAG_DRIVER(ksz9477_netdev_ops); ··· 249 178 return NULL; 250 179 251 180 /* Tag encoding */ 181 + ksz_xmit_timestamp(dp, skb); 182 + 252 183 tag = skb_put(skb, KSZ_INGRESS_TAG_LEN); 253 184 addr = skb_mac_header(skb); 254 185 ··· 267 194 .proto = DSA_TAG_PROTO_KSZ9893, 268 195 .xmit = ksz9893_xmit, 269 196 .rcv = ksz9477_rcv, 270 - .needed_tailroom = KSZ_INGRESS_TAG_LEN, 197 + .connect = ksz_connect, 198 + .disconnect = ksz_disconnect, 199 + .needed_tailroom = KSZ_INGRESS_TAG_LEN + KSZ_PTP_TAG_LEN, 271 200 }; 272 201 273 202 DSA_TAG_DRIVER(ksz9893_netdev_ops); 274 203 MODULE_ALIAS_DSA_TAG_DRIVER(DSA_TAG_PROTO_KSZ9893, KSZ9893_NAME); 275 204 276 - /* For xmit, 2 bytes are added before FCS. 205 + /* For xmit, 2/6 bytes are added before FCS. 277 206 * --------------------------------------------------------------------------- 278 - * DA(6bytes)|SA(6bytes)|....|Data(nbytes)|tag0(1byte)|tag1(1byte)|FCS(4bytes) 207 + * DA(6bytes)|SA(6bytes)|....|Data(nbytes)|ts(4bytes)|tag0(1byte)|tag1(1byte)| 208 + * FCS(4bytes) 279 209 * --------------------------------------------------------------------------- 210 + * ts : time stamp (Present only if PTP is enabled in the Hardware) 280 211 * tag0 : represents tag override, lookup and valid 281 212 * tag1 : each bit represents port (eg, 0x01=port1, 0x02=port2, 0x80=port8) 282 213 * ··· 309 232 if (skb->ip_summed == CHECKSUM_PARTIAL && skb_checksum_help(skb)) 310 233 return NULL; 311 234 235 + ksz_xmit_timestamp(dp, skb); 236 + 312 237 tag = skb_put(skb, LAN937X_EGRESS_TAG_LEN); 313 238 314 239 val = BIT(dp->index); ··· 331 252 .proto = DSA_TAG_PROTO_LAN937X, 332 253 .xmit = lan937x_xmit, 333 254 .rcv = ksz9477_rcv, 334 - .needed_tailroom = LAN937X_EGRESS_TAG_LEN, 255 + .connect = ksz_connect, 256 + .disconnect = ksz_disconnect, 257 + .needed_tailroom = LAN937X_EGRESS_TAG_LEN + KSZ_PTP_TAG_LEN, 335 258 }; 336 259 337 260 DSA_TAG_DRIVER(lan937x_netdev_ops);