30
30
#include "cpsw_sl.h"
31
31
#include "am65-cpsw-nuss.h"
32
32
#include "k3-cppi-desc-pool.h"
33
+ #include "am65-cpts.h"
33
34
34
35
#define AM65_CPSW_SS_BASE 0x0
35
36
#define AM65_CPSW_SGMII_BASE 0x100
@@ -668,6 +669,18 @@ static void am65_cpsw_nuss_rx_cleanup(void *data, dma_addr_t desc_dma)
668
669
dev_kfree_skb_any (skb );
669
670
}
670
671
672
+ static void am65_cpsw_nuss_rx_ts (struct sk_buff * skb , u32 * psdata )
673
+ {
674
+ struct skb_shared_hwtstamps * ssh ;
675
+ u64 ns ;
676
+
677
+ ns = ((u64 )psdata [1 ] << 32 ) | psdata [0 ];
678
+
679
+ ssh = skb_hwtstamps (skb );
680
+ memset (ssh , 0 , sizeof (* ssh ));
681
+ ssh -> hwtstamp = ns_to_ktime (ns );
682
+ }
683
+
671
684
/* RX psdata[2] word format - checksum information */
672
685
#define AM65_CPSW_RX_PSD_CSUM_ADD GENMASK(15, 0)
673
686
#define AM65_CPSW_RX_PSD_CSUM_ERR BIT(16)
@@ -745,6 +758,9 @@ static int am65_cpsw_nuss_rx_packets(struct am65_cpsw_common *common,
745
758
skb -> dev = ndev ;
746
759
747
760
psdata = cppi5_hdesc_get_psdata (desc_rx );
761
+ /* add RX timestamp */
762
+ if (port -> rx_ts_enabled )
763
+ am65_cpsw_nuss_rx_ts (skb , psdata );
748
764
csum_info = psdata [2 ];
749
765
dev_dbg (dev , "%s rx csum_info:%#x\n" , __func__ , csum_info );
750
766
@@ -904,6 +920,8 @@ static int am65_cpsw_nuss_tx_compl_packets(struct am65_cpsw_common *common,
904
920
905
921
ndev = skb -> dev ;
906
922
923
+ am65_cpts_tx_timestamp (common -> cpts , skb );
924
+
907
925
ndev_priv = netdev_priv (ndev );
908
926
stats = this_cpu_ptr (ndev_priv -> stats );
909
927
u64_stats_update_begin (& stats -> syncp );
@@ -995,6 +1013,10 @@ static netdev_tx_t am65_cpsw_nuss_ndo_slave_xmit(struct sk_buff *skb,
995
1013
/* padding enabled in hw */
996
1014
pkt_len = skb_headlen (skb );
997
1015
1016
+ /* SKB TX timestamp */
1017
+ if (port -> tx_ts_enabled )
1018
+ am65_cpts_prep_tx_timestamp (common -> cpts , skb );
1019
+
998
1020
q_idx = skb_get_queue_mapping (skb );
999
1021
dev_dbg (dev , "%s skb_queue:%d\n" , __func__ , q_idx );
1000
1022
@@ -1158,6 +1180,111 @@ static int am65_cpsw_nuss_ndo_slave_set_mac_address(struct net_device *ndev,
1158
1180
return 0 ;
1159
1181
}
1160
1182
1183
+ static int am65_cpsw_nuss_hwtstamp_set (struct net_device * ndev ,
1184
+ struct ifreq * ifr )
1185
+ {
1186
+ struct am65_cpsw_common * common = am65_ndev_to_common (ndev );
1187
+ struct am65_cpsw_port * port = am65_ndev_to_port (ndev );
1188
+ u32 ts_ctrl , seq_id , ts_ctrl_ltype2 , ts_vlan_ltype ;
1189
+ struct hwtstamp_config cfg ;
1190
+
1191
+ if (!IS_ENABLED (CONFIG_TI_K3_AM65_CPTS ))
1192
+ return - EOPNOTSUPP ;
1193
+
1194
+ if (copy_from_user (& cfg , ifr -> ifr_data , sizeof (cfg )))
1195
+ return - EFAULT ;
1196
+
1197
+ /* TX HW timestamp */
1198
+ switch (cfg .tx_type ) {
1199
+ case HWTSTAMP_TX_OFF :
1200
+ case HWTSTAMP_TX_ON :
1201
+ break ;
1202
+ default :
1203
+ return - ERANGE ;
1204
+ }
1205
+
1206
+ switch (cfg .rx_filter ) {
1207
+ case HWTSTAMP_FILTER_NONE :
1208
+ port -> rx_ts_enabled = false;
1209
+ break ;
1210
+ case HWTSTAMP_FILTER_ALL :
1211
+ case HWTSTAMP_FILTER_SOME :
1212
+ case HWTSTAMP_FILTER_PTP_V1_L4_EVENT :
1213
+ case HWTSTAMP_FILTER_PTP_V1_L4_SYNC :
1214
+ case HWTSTAMP_FILTER_PTP_V1_L4_DELAY_REQ :
1215
+ case HWTSTAMP_FILTER_PTP_V2_L4_EVENT :
1216
+ case HWTSTAMP_FILTER_PTP_V2_L4_SYNC :
1217
+ case HWTSTAMP_FILTER_PTP_V2_L4_DELAY_REQ :
1218
+ case HWTSTAMP_FILTER_PTP_V2_L2_EVENT :
1219
+ case HWTSTAMP_FILTER_PTP_V2_L2_SYNC :
1220
+ case HWTSTAMP_FILTER_PTP_V2_L2_DELAY_REQ :
1221
+ case HWTSTAMP_FILTER_PTP_V2_EVENT :
1222
+ case HWTSTAMP_FILTER_PTP_V2_SYNC :
1223
+ case HWTSTAMP_FILTER_PTP_V2_DELAY_REQ :
1224
+ case HWTSTAMP_FILTER_NTP_ALL :
1225
+ port -> rx_ts_enabled = true;
1226
+ cfg .rx_filter = HWTSTAMP_FILTER_ALL ;
1227
+ break ;
1228
+ default :
1229
+ return - ERANGE ;
1230
+ }
1231
+
1232
+ port -> tx_ts_enabled = (cfg .tx_type == HWTSTAMP_TX_ON );
1233
+
1234
+ /* cfg TX timestamp */
1235
+ seq_id = (AM65_CPSW_TS_SEQ_ID_OFFSET <<
1236
+ AM65_CPSW_PN_TS_SEQ_ID_OFFSET_SHIFT ) | ETH_P_1588 ;
1237
+
1238
+ ts_vlan_ltype = ETH_P_8021Q ;
1239
+
1240
+ ts_ctrl_ltype2 = ETH_P_1588 |
1241
+ AM65_CPSW_PN_TS_CTL_LTYPE2_TS_107 |
1242
+ AM65_CPSW_PN_TS_CTL_LTYPE2_TS_129 |
1243
+ AM65_CPSW_PN_TS_CTL_LTYPE2_TS_130 |
1244
+ AM65_CPSW_PN_TS_CTL_LTYPE2_TS_131 |
1245
+ AM65_CPSW_PN_TS_CTL_LTYPE2_TS_132 |
1246
+ AM65_CPSW_PN_TS_CTL_LTYPE2_TS_319 |
1247
+ AM65_CPSW_PN_TS_CTL_LTYPE2_TS_320 |
1248
+ AM65_CPSW_PN_TS_CTL_LTYPE2_TS_TTL_NONZERO ;
1249
+
1250
+ ts_ctrl = AM65_CPSW_TS_EVENT_MSG_TYPE_BITS <<
1251
+ AM65_CPSW_PN_TS_CTL_MSG_TYPE_EN_SHIFT ;
1252
+
1253
+ if (port -> tx_ts_enabled )
1254
+ ts_ctrl |= AM65_CPSW_TS_TX_ANX_ALL_EN |
1255
+ AM65_CPSW_PN_TS_CTL_TX_VLAN_LT1_EN ;
1256
+
1257
+ writel (seq_id , port -> port_base + AM65_CPSW_PORTN_REG_TS_SEQ_LTYPE_REG );
1258
+ writel (ts_vlan_ltype , port -> port_base +
1259
+ AM65_CPSW_PORTN_REG_TS_VLAN_LTYPE_REG );
1260
+ writel (ts_ctrl_ltype2 , port -> port_base +
1261
+ AM65_CPSW_PORTN_REG_TS_CTL_LTYPE2 );
1262
+ writel (ts_ctrl , port -> port_base + AM65_CPSW_PORTN_REG_TS_CTL );
1263
+
1264
+ /* en/dis RX timestamp */
1265
+ am65_cpts_rx_enable (common -> cpts , port -> rx_ts_enabled );
1266
+
1267
+ return copy_to_user (ifr -> ifr_data , & cfg , sizeof (cfg )) ? - EFAULT : 0 ;
1268
+ }
1269
+
1270
+ static int am65_cpsw_nuss_hwtstamp_get (struct net_device * ndev ,
1271
+ struct ifreq * ifr )
1272
+ {
1273
+ struct am65_cpsw_port * port = am65_ndev_to_port (ndev );
1274
+ struct hwtstamp_config cfg ;
1275
+
1276
+ if (!IS_ENABLED (CONFIG_TI_K3_AM65_CPTS ))
1277
+ return - EOPNOTSUPP ;
1278
+
1279
+ cfg .flags = 0 ;
1280
+ cfg .tx_type = port -> tx_ts_enabled ?
1281
+ HWTSTAMP_TX_ON : HWTSTAMP_TX_OFF ;
1282
+ cfg .rx_filter = port -> rx_ts_enabled ?
1283
+ HWTSTAMP_FILTER_ALL : HWTSTAMP_FILTER_NONE ;
1284
+
1285
+ return copy_to_user (ifr -> ifr_data , & cfg , sizeof (cfg )) ? - EFAULT : 0 ;
1286
+ }
1287
+
1161
1288
static int am65_cpsw_nuss_ndo_slave_ioctl (struct net_device * ndev ,
1162
1289
struct ifreq * req , int cmd )
1163
1290
{
@@ -1166,6 +1293,13 @@ static int am65_cpsw_nuss_ndo_slave_ioctl(struct net_device *ndev,
1166
1293
if (!netif_running (ndev ))
1167
1294
return - EINVAL ;
1168
1295
1296
+ switch (cmd ) {
1297
+ case SIOCSHWTSTAMP :
1298
+ return am65_cpsw_nuss_hwtstamp_set (ndev , req );
1299
+ case SIOCGHWTSTAMP :
1300
+ return am65_cpsw_nuss_hwtstamp_get (ndev , req );
1301
+ }
1302
+
1169
1303
if (!port -> slave .phy )
1170
1304
return - EOPNOTSUPP ;
1171
1305
@@ -1531,6 +1665,40 @@ static int am65_cpsw_am654_get_efuse_macid(struct device_node *of_node,
1531
1665
return 0 ;
1532
1666
}
1533
1667
1668
+ static int am65_cpsw_init_cpts (struct am65_cpsw_common * common )
1669
+ {
1670
+ struct device * dev = common -> dev ;
1671
+ struct device_node * node ;
1672
+ struct am65_cpts * cpts ;
1673
+ void __iomem * reg_base ;
1674
+
1675
+ if (!IS_ENABLED (CONFIG_TI_K3_AM65_CPTS ))
1676
+ return 0 ;
1677
+
1678
+ node = of_get_child_by_name (dev -> of_node , "cpts" );
1679
+ if (!node ) {
1680
+ dev_err (dev , "%s cpts not found\n" , __func__ );
1681
+ return - ENOENT ;
1682
+ }
1683
+
1684
+ reg_base = common -> cpsw_base + AM65_CPSW_NU_CPTS_BASE ;
1685
+ cpts = am65_cpts_create (dev , reg_base , node );
1686
+ if (IS_ERR (cpts )) {
1687
+ int ret = PTR_ERR (cpts );
1688
+
1689
+ if (ret == - EOPNOTSUPP ) {
1690
+ dev_info (dev , "cpts disabled\n" );
1691
+ return 0 ;
1692
+ }
1693
+
1694
+ dev_err (dev , "cpts create err %d\n" , ret );
1695
+ return ret ;
1696
+ }
1697
+ common -> cpts = cpts ;
1698
+
1699
+ return 0 ;
1700
+ }
1701
+
1534
1702
static int am65_cpsw_nuss_init_slave_ports (struct am65_cpsw_common * common )
1535
1703
{
1536
1704
struct device_node * node , * port_np ;
@@ -1899,6 +2067,10 @@ static int am65_cpsw_nuss_probe(struct platform_device *pdev)
1899
2067
goto err_of_clear ;
1900
2068
}
1901
2069
2070
+ ret = am65_cpsw_init_cpts (common );
2071
+ if (ret )
2072
+ goto err_of_clear ;
2073
+
1902
2074
/* init ports */
1903
2075
for (i = 0 ; i < common -> port_num ; i ++ )
1904
2076
am65_cpsw_nuss_slave_disable_unused (& common -> ports [i ]);
0 commit comments