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.

Merge branch 'net-stmmac-correct-mac-propagation-delay'

Johannes Zink says:

====================
net: stmmac: correct MAC propagation delay

Changes in v3:
- work in Richard's review feedback. Thank you for reviewing my patch:
- as some of the hardware may have no or invalid correction value
registers: introduce feature switch which can be enabled in the glue
code drivers depending on the actual hardware support
- only enable the feature on the i.MX8MP for the time being, as the patch
improves timing accuracy and is tested for this hardware
- Link to v2: https://lore.kernel.org/r/20230719-stmmac_correct_mac_delay-v2-1-3366f38ee9a6@pengutronix.de

Changes in v2:
- fix builds for 32bit, this was found by the kernel build bot
Reported-by: kernel test robot <lkp@intel.com>
Closes: https://lore.kernel.org/oe-kbuild-all/202307200225.B8rmKQPN-lkp@intel.com/
- while at it also fix an overflow by shifting a u32 constant from macro by 10bits
by casting the constant to u64
- Link to v1: https://lore.kernel.org/r/20230719-stmmac_correct_mac_delay-v1-1-768aa4d09334@pengutronix.de

Tested-by: Kurt Kanzenbach <kurt@linutronix.de> # imx8mp
====================

Link: https://lore.kernel.org/r/20230719-stmmac_correct_mac_delay-v3-0-61e63427735e@pengutronix.de
Signed-off-by: Jakub Kicinski <kuba@kernel.org>

+64
+5
drivers/net/ethernet/stmicro/stmmac/dwmac-imx.c
··· 42 42 43 43 struct imx_dwmac_ops { 44 44 u32 addr_width; 45 + u32 flags; 45 46 bool mac_rgmii_txclk_auto_adj; 46 47 47 48 int (*fix_soc_reset)(void *priv, void __iomem *ioaddr); ··· 312 311 goto err_parse_dt; 313 312 } 314 313 314 + if (data->flags & STMMAC_FLAG_HWTSTAMP_CORRECT_LATENCY) 315 + plat_dat->flags |= STMMAC_FLAG_HWTSTAMP_CORRECT_LATENCY; 316 + 315 317 plat_dat->host_dma_width = dwmac->ops->addr_width; 316 318 plat_dat->init = imx_dwmac_init; 317 319 plat_dat->exit = imx_dwmac_exit; ··· 354 350 .addr_width = 34, 355 351 .mac_rgmii_txclk_auto_adj = false, 356 352 .set_intf_mode = imx8mp_set_intf_mode, 353 + .flags = STMMAC_FLAG_HWTSTAMP_CORRECT_LATENCY, 357 354 }; 358 355 359 356 static struct imx_dwmac_ops imx8dxl_dwmac_data = {
+3
drivers/net/ethernet/stmicro/stmmac/hwif.h
··· 532 532 void (*get_systime) (void __iomem *ioaddr, u64 *systime); 533 533 void (*get_ptptime)(void __iomem *ioaddr, u64 *ptp_time); 534 534 void (*timestamp_interrupt)(struct stmmac_priv *priv); 535 + void (*hwtstamp_correct_latency)(struct stmmac_priv *priv); 535 536 }; 536 537 537 538 #define stmmac_config_hw_tstamping(__priv, __args...) \ ··· 551 550 stmmac_do_void_callback(__priv, ptp, get_ptptime, __args) 552 551 #define stmmac_timestamp_interrupt(__priv, __args...) \ 553 552 stmmac_do_void_callback(__priv, ptp, timestamp_interrupt, __args) 553 + #define stmmac_hwtstamp_correct_latency(__priv, __args...) \ 554 + stmmac_do_void_callback(__priv, ptp, hwtstamp_correct_latency, __args) 554 555 555 556 struct stmmac_tx_queue; 556 557 struct stmmac_rx_queue;
+43
drivers/net/ethernet/stmicro/stmmac/stmmac_hwtstamp.c
··· 60 60 *ssinc = data; 61 61 } 62 62 63 + static void hwtstamp_correct_latency(struct stmmac_priv *priv) 64 + { 65 + void __iomem *ioaddr = priv->ptpaddr; 66 + u32 reg_tsic, reg_tsicsns; 67 + u32 reg_tsec, reg_tsecsns; 68 + u64 scaled_ns; 69 + u32 val; 70 + 71 + /* MAC-internal ingress latency */ 72 + scaled_ns = readl(ioaddr + PTP_TS_INGR_LAT); 73 + 74 + /* See section 11.7.2.5.3.1 "Ingress Correction" on page 4001 of 75 + * i.MX8MP Applications Processor Reference Manual Rev. 1, 06/2021 76 + */ 77 + val = readl(ioaddr + PTP_TCR); 78 + if (val & PTP_TCR_TSCTRLSSR) 79 + /* nanoseconds field is in decimal format with granularity of 1ns/bit */ 80 + scaled_ns = ((u64)NSEC_PER_SEC << 16) - scaled_ns; 81 + else 82 + /* nanoseconds field is in binary format with granularity of ~0.466ns/bit */ 83 + scaled_ns = ((1ULL << 31) << 16) - 84 + DIV_U64_ROUND_CLOSEST(scaled_ns * PSEC_PER_NSEC, 466U); 85 + 86 + reg_tsic = scaled_ns >> 16; 87 + reg_tsicsns = scaled_ns & 0xff00; 88 + 89 + /* set bit 31 for 2's compliment */ 90 + reg_tsic |= BIT(31); 91 + 92 + writel(reg_tsic, ioaddr + PTP_TS_INGR_CORR_NS); 93 + writel(reg_tsicsns, ioaddr + PTP_TS_INGR_CORR_SNS); 94 + 95 + /* MAC-internal egress latency */ 96 + scaled_ns = readl(ioaddr + PTP_TS_EGR_LAT); 97 + 98 + reg_tsec = scaled_ns >> 16; 99 + reg_tsecsns = scaled_ns & 0xff00; 100 + 101 + writel(reg_tsec, ioaddr + PTP_TS_EGR_CORR_NS); 102 + writel(reg_tsecsns, ioaddr + PTP_TS_EGR_CORR_SNS); 103 + } 104 + 63 105 static int init_systime(void __iomem *ioaddr, u32 sec, u32 nsec) 64 106 { 65 107 u32 value; ··· 263 221 .get_systime = get_systime, 264 222 .get_ptptime = get_ptptime, 265 223 .timestamp_interrupt = timestamp_interrupt, 224 + .hwtstamp_correct_latency = hwtstamp_correct_latency, 266 225 };
+6
drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
··· 909 909 priv->hwts_tx_en = 0; 910 910 priv->hwts_rx_en = 0; 911 911 912 + if (priv->plat->flags & STMMAC_FLAG_HWTSTAMP_CORRECT_LATENCY) 913 + stmmac_hwtstamp_correct_latency(priv, priv); 914 + 912 915 return 0; 913 916 } 914 917 ··· 1097 1094 1098 1095 if (priv->dma_cap.fpesel) 1099 1096 stmmac_fpe_link_state_handle(priv, true); 1097 + 1098 + if (priv->plat->flags & STMMAC_FLAG_HWTSTAMP_CORRECT_LATENCY) 1099 + stmmac_hwtstamp_correct_latency(priv, priv); 1100 1100 } 1101 1101 1102 1102 static const struct phylink_mac_ops stmmac_phylink_mac_ops = {
+6
drivers/net/ethernet/stmicro/stmmac/stmmac_ptp.h
··· 26 26 #define PTP_ACR 0x40 /* Auxiliary Control Reg */ 27 27 #define PTP_ATNR 0x48 /* Auxiliary Timestamp - Nanoseconds Reg */ 28 28 #define PTP_ATSR 0x4c /* Auxiliary Timestamp - Seconds Reg */ 29 + #define PTP_TS_INGR_CORR_NS 0x58 /* Ingress timestamp correction nanoseconds */ 30 + #define PTP_TS_EGR_CORR_NS 0x5C /* Egress timestamp correction nanoseconds*/ 31 + #define PTP_TS_INGR_CORR_SNS 0x60 /* Ingress timestamp correction subnanoseconds */ 32 + #define PTP_TS_EGR_CORR_SNS 0x64 /* Egress timestamp correction subnanoseconds */ 33 + #define PTP_TS_INGR_LAT 0x68 /* MAC internal Ingress Latency */ 34 + #define PTP_TS_EGR_LAT 0x6c /* MAC internal Egress Latency */ 29 35 30 36 #define PTP_STNSUR_ADDSUB_SHIFT 31 31 37 #define PTP_DIGITAL_ROLLOVER_MODE 0x3B9ACA00 /* 10e9-1 ns */
+1
include/linux/stmmac.h
··· 218 218 #define STMMAC_FLAG_INT_SNAPSHOT_EN BIT(9) 219 219 #define STMMAC_FLAG_RX_CLK_RUNS_IN_LPI BIT(10) 220 220 #define STMMAC_FLAG_EN_TX_LPI_CLOCKGATING BIT(11) 221 + #define STMMAC_FLAG_HWTSTAMP_CORRECT_LATENCY BIT(12) 221 222 222 223 struct plat_stmmacenet_data { 223 224 int bus_id;