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

net: ethernet: ti: am65-cpsw/ethtool: Enable RX HW timestamp only for PTP packets

In the current mechanism of timestamping, am65-cpsw-nuss driver
enables hardware timestamping for all received packets by setting
the TSTAMP_EN bit in CPTS_CONTROL register, which directs the CPTS
module to timestamp all received packets, followed by passing
timestamp via DMA descriptors. This mechanism causes CPSW Port to
Lock up.

To prevent port lock up, don't enable rx packet timestamping by
setting TSTAMP_EN bit in CPTS_CONTROL register. The workaround for
timestamping received packets is to utilize the CPTS Event FIFO
that records timestamps corresponding to certain events. The CPTS
module is configured to generate timestamps for Multicast Ethernet,
UDP/IPv4 and UDP/IPv6 PTP packets.

Update supported hwtstamp_rx_filters values for CPSW's timestamping
capability.

Fixes: b1f66a5bee07 ("net: ethernet: ti: am65-cpsw-nuss: enable packet timestamping support")
Signed-off-by: Chintan Vankar <c-vankar@ti.com>
Signed-off-by: Paolo Abeni <pabeni@redhat.com>

authored by

Chintan Vankar and committed by
Paolo Abeni
c03a6fd3 c459f606

+35 -57
+12 -1
drivers/net/ethernet/ti/am65-cpsw-ethtool.c
··· 695 695 struct ethtool_ts_info *info) 696 696 { 697 697 struct am65_cpsw_common *common = am65_ndev_to_common(ndev); 698 + unsigned int ptp_v2_filter; 699 + 700 + ptp_v2_filter = BIT(HWTSTAMP_FILTER_PTP_V2_L4_EVENT) | 701 + BIT(HWTSTAMP_FILTER_PTP_V2_L4_SYNC) | 702 + BIT(HWTSTAMP_FILTER_PTP_V2_L4_DELAY_REQ) | 703 + BIT(HWTSTAMP_FILTER_PTP_V2_L2_EVENT) | 704 + BIT(HWTSTAMP_FILTER_PTP_V2_L2_SYNC) | 705 + BIT(HWTSTAMP_FILTER_PTP_V2_L2_DELAY_REQ) | 706 + BIT(HWTSTAMP_FILTER_PTP_V2_EVENT) | 707 + BIT(HWTSTAMP_FILTER_PTP_V2_SYNC) | 708 + BIT(HWTSTAMP_FILTER_PTP_V2_DELAY_REQ); 698 709 699 710 if (!IS_ENABLED(CONFIG_TI_K3_AM65_CPTS)) 700 711 return ethtool_op_get_ts_info(ndev, info); ··· 719 708 SOF_TIMESTAMPING_RAW_HARDWARE; 720 709 info->phc_index = am65_cpts_phc_index(common->cpts); 721 710 info->tx_types = BIT(HWTSTAMP_TX_OFF) | BIT(HWTSTAMP_TX_ON); 722 - info->rx_filters = BIT(HWTSTAMP_FILTER_NONE) | BIT(HWTSTAMP_FILTER_ALL); 711 + info->rx_filters = BIT(HWTSTAMP_FILTER_NONE) | ptp_v2_filter; 723 712 return 0; 724 713 } 725 714
+23 -28
drivers/net/ethernet/ti/am65-cpsw-nuss.c
··· 103 103 #define AM65_CPSW_PN_TS_CTL_TX_HOST_TS_EN BIT(11) 104 104 #define AM65_CPSW_PN_TS_CTL_MSG_TYPE_EN_SHIFT 16 105 105 106 + #define AM65_CPSW_PN_TS_CTL_RX_ANX_F_EN BIT(0) 107 + #define AM65_CPSW_PN_TS_CTL_RX_VLAN_LT1_EN BIT(1) 108 + #define AM65_CPSW_PN_TS_CTL_RX_VLAN_LT2_EN BIT(2) 109 + #define AM65_CPSW_PN_TS_CTL_RX_ANX_D_EN BIT(3) 110 + #define AM65_CPSW_PN_TS_CTL_RX_ANX_E_EN BIT(9) 111 + 106 112 /* AM65_CPSW_PORTN_REG_TS_SEQ_LTYPE_REG register fields */ 107 113 #define AM65_CPSW_PN_TS_SEQ_ID_OFFSET_SHIFT 16 108 114 ··· 131 125 (AM65_CPSW_PN_TS_CTL_TX_ANX_D_EN | \ 132 126 AM65_CPSW_PN_TS_CTL_TX_ANX_E_EN | \ 133 127 AM65_CPSW_PN_TS_CTL_TX_ANX_F_EN) 128 + 129 + #define AM65_CPSW_TS_RX_ANX_ALL_EN \ 130 + (AM65_CPSW_PN_TS_CTL_RX_ANX_D_EN | \ 131 + AM65_CPSW_PN_TS_CTL_RX_ANX_E_EN | \ 132 + AM65_CPSW_PN_TS_CTL_RX_ANX_F_EN) 134 133 135 134 #define AM65_CPSW_ALE_AGEOUT_DEFAULT 30 136 135 /* Number of TX/RX descriptors */ ··· 1061 1050 return ret; 1062 1051 } 1063 1052 1064 - static void am65_cpsw_nuss_rx_ts(struct sk_buff *skb, u32 *psdata) 1065 - { 1066 - struct skb_shared_hwtstamps *ssh; 1067 - u64 ns; 1068 - 1069 - ns = ((u64)psdata[1] << 32) | psdata[0]; 1070 - 1071 - ssh = skb_hwtstamps(skb); 1072 - memset(ssh, 0, sizeof(*ssh)); 1073 - ssh->hwtstamp = ns_to_ktime(ns); 1074 - } 1075 - 1076 1053 /* RX psdata[2] word format - checksum information */ 1077 1054 #define AM65_CPSW_RX_PSD_CSUM_ADD GENMASK(15, 0) 1078 1055 #define AM65_CPSW_RX_PSD_CSUM_ERR BIT(16) ··· 1176 1177 skb_reserve(skb, headroom); 1177 1178 } 1178 1179 1179 - /* Pass skb to netstack if no XDP prog or returned XDP_PASS */ 1180 - if (port->rx_ts_enabled) 1181 - am65_cpsw_nuss_rx_ts(skb, psdata); 1182 - 1183 1180 ndev_priv = netdev_priv(ndev); 1184 1181 am65_cpsw_nuss_set_offload_fwd_mark(skb, ndev_priv->offload_fwd_mark); 1185 1182 skb_put(skb, pkt_len); 1183 + if (port->rx_ts_enabled) 1184 + am65_cpts_rx_timestamp(common->cpts, skb); 1186 1185 skb_mark_for_recycle(skb); 1187 1186 skb->protocol = eth_type_trans(skb, ndev); 1188 1187 am65_cpsw_nuss_rx_csum(skb, csum_info); ··· 1733 1736 static int am65_cpsw_nuss_hwtstamp_set(struct net_device *ndev, 1734 1737 struct ifreq *ifr) 1735 1738 { 1736 - struct am65_cpsw_common *common = am65_ndev_to_common(ndev); 1737 1739 struct am65_cpsw_port *port = am65_ndev_to_port(ndev); 1738 1740 u32 ts_ctrl, seq_id, ts_ctrl_ltype2, ts_vlan_ltype; 1739 1741 struct hwtstamp_config cfg; ··· 1756 1760 case HWTSTAMP_FILTER_NONE: 1757 1761 port->rx_ts_enabled = false; 1758 1762 break; 1759 - case HWTSTAMP_FILTER_ALL: 1760 - case HWTSTAMP_FILTER_SOME: 1761 - case HWTSTAMP_FILTER_PTP_V1_L4_EVENT: 1762 - case HWTSTAMP_FILTER_PTP_V1_L4_SYNC: 1763 - case HWTSTAMP_FILTER_PTP_V1_L4_DELAY_REQ: 1764 1763 case HWTSTAMP_FILTER_PTP_V2_L4_EVENT: 1765 1764 case HWTSTAMP_FILTER_PTP_V2_L4_SYNC: 1766 1765 case HWTSTAMP_FILTER_PTP_V2_L4_DELAY_REQ: ··· 1765 1774 case HWTSTAMP_FILTER_PTP_V2_EVENT: 1766 1775 case HWTSTAMP_FILTER_PTP_V2_SYNC: 1767 1776 case HWTSTAMP_FILTER_PTP_V2_DELAY_REQ: 1768 - case HWTSTAMP_FILTER_NTP_ALL: 1769 1777 port->rx_ts_enabled = true; 1770 - cfg.rx_filter = HWTSTAMP_FILTER_ALL; 1778 + cfg.rx_filter = HWTSTAMP_FILTER_PTP_V2_EVENT; 1771 1779 break; 1780 + case HWTSTAMP_FILTER_ALL: 1781 + case HWTSTAMP_FILTER_SOME: 1782 + case HWTSTAMP_FILTER_NTP_ALL: 1783 + return -EOPNOTSUPP; 1772 1784 default: 1773 1785 return -ERANGE; 1774 1786 } ··· 1801 1807 ts_ctrl |= AM65_CPSW_TS_TX_ANX_ALL_EN | 1802 1808 AM65_CPSW_PN_TS_CTL_TX_VLAN_LT1_EN; 1803 1809 1810 + if (port->rx_ts_enabled) 1811 + ts_ctrl |= AM65_CPSW_TS_RX_ANX_ALL_EN | 1812 + AM65_CPSW_PN_TS_CTL_RX_VLAN_LT1_EN; 1813 + 1804 1814 writel(seq_id, port->port_base + AM65_CPSW_PORTN_REG_TS_SEQ_LTYPE_REG); 1805 1815 writel(ts_vlan_ltype, port->port_base + 1806 1816 AM65_CPSW_PORTN_REG_TS_VLAN_LTYPE_REG); 1807 1817 writel(ts_ctrl_ltype2, port->port_base + 1808 1818 AM65_CPSW_PORTN_REG_TS_CTL_LTYPE2); 1809 1819 writel(ts_ctrl, port->port_base + AM65_CPSW_PORTN_REG_TS_CTL); 1810 - 1811 - /* en/dis RX timestamp */ 1812 - am65_cpts_rx_enable(common->cpts, port->rx_ts_enabled); 1813 1820 1814 1821 return copy_to_user(ifr->ifr_data, &cfg, sizeof(cfg)) ? -EFAULT : 0; 1815 1822 } ··· 1828 1833 cfg.tx_type = port->tx_ts_enabled ? 1829 1834 HWTSTAMP_TX_ON : HWTSTAMP_TX_OFF; 1830 1835 cfg.rx_filter = port->rx_ts_enabled ? 1831 - HWTSTAMP_FILTER_ALL : HWTSTAMP_FILTER_NONE; 1836 + HWTSTAMP_FILTER_PTP_V2_EVENT : HWTSTAMP_FILTER_NONE; 1832 1837 1833 1838 return copy_to_user(ifr->ifr_data, &cfg, sizeof(cfg)) ? -EFAULT : 0; 1834 1839 }
-23
drivers/net/ethernet/ti/am65-cpts.c
··· 866 866 return delay; 867 867 } 868 868 869 - /** 870 - * am65_cpts_rx_enable - enable rx timestamping 871 - * @cpts: cpts handle 872 - * @en: enable 873 - * 874 - * This functions enables rx packets timestamping. The CPTS can timestamp all 875 - * rx packets. 876 - */ 877 - void am65_cpts_rx_enable(struct am65_cpts *cpts, bool en) 878 - { 879 - u32 val; 880 - 881 - mutex_lock(&cpts->ptp_clk_lock); 882 - val = am65_cpts_read32(cpts, control); 883 - if (en) 884 - val |= AM65_CPTS_CONTROL_TSTAMP_EN; 885 - else 886 - val &= ~AM65_CPTS_CONTROL_TSTAMP_EN; 887 - am65_cpts_write32(cpts, val, control); 888 - mutex_unlock(&cpts->ptp_clk_lock); 889 - } 890 - EXPORT_SYMBOL_GPL(am65_cpts_rx_enable); 891 - 892 869 static int am65_skb_get_mtype_seqid(struct sk_buff *skb, u32 *mtype_seqid) 893 870 { 894 871 unsigned int ptp_class = ptp_classify_raw(skb);
-5
drivers/net/ethernet/ti/am65-cpts.h
··· 25 25 void am65_cpts_rx_timestamp(struct am65_cpts *cpts, struct sk_buff *skb); 26 26 void am65_cpts_tx_timestamp(struct am65_cpts *cpts, struct sk_buff *skb); 27 27 void am65_cpts_prep_tx_timestamp(struct am65_cpts *cpts, struct sk_buff *skb); 28 - void am65_cpts_rx_enable(struct am65_cpts *cpts, bool en); 29 28 u64 am65_cpts_ns_gettime(struct am65_cpts *cpts); 30 29 int am65_cpts_estf_enable(struct am65_cpts *cpts, int idx, 31 30 struct am65_cpts_estf_cfg *cfg); ··· 60 61 61 62 static inline void am65_cpts_prep_tx_timestamp(struct am65_cpts *cpts, 62 63 struct sk_buff *skb) 63 - { 64 - } 65 - 66 - static inline void am65_cpts_rx_enable(struct am65_cpts *cpts, bool en) 67 64 { 68 65 } 69 66