1010#include <sys/types.h>
1111#include <sys/stat.h>
1212#include <unistd.h>
13+ #include <math.h>
1314
1415#include <rte_tailq.h>
1516#include <rte_os_shim.h>
@@ -176,6 +177,7 @@ static int ice_timesync_read_rx_timestamp(struct rte_eth_dev *dev,
176177static int ice_timesync_read_tx_timestamp (struct rte_eth_dev * dev ,
177178 struct timespec * timestamp );
178179static int ice_timesync_adjust_time (struct rte_eth_dev * dev , int64_t delta );
180+ static int ice_timesync_adjust_freq (struct rte_eth_dev * dev , int64_t ppm );
179181static int ice_timesync_read_time (struct rte_eth_dev * dev ,
180182 struct timespec * timestamp );
181183static int ice_timesync_write_time (struct rte_eth_dev * dev ,
@@ -307,6 +309,7 @@ static const struct eth_dev_ops ice_eth_dev_ops = {
307309 .timesync_read_rx_timestamp = ice_timesync_read_rx_timestamp ,
308310 .timesync_read_tx_timestamp = ice_timesync_read_tx_timestamp ,
309311 .timesync_adjust_time = ice_timesync_adjust_time ,
312+ .timesync_adjust_freq = ice_timesync_adjust_freq ,
310313 .timesync_read_time = ice_timesync_read_time ,
311314 .timesync_write_time = ice_timesync_write_time ,
312315 .timesync_disable = ice_timesync_disable ,
@@ -2332,6 +2335,33 @@ ice_get_supported_rxdid(struct ice_hw *hw)
23322335 return supported_rxdid ;
23332336}
23342337
2338+ static void ice_ptp_init_info (struct rte_eth_dev * dev )
2339+ {
2340+ struct ice_hw * hw = ICE_DEV_PRIVATE_TO_HW (dev -> data -> dev_private );
2341+ struct ice_adapter * ad =
2342+ ICE_DEV_PRIVATE_TO_ADAPTER (dev -> data -> dev_private );
2343+
2344+ switch (hw -> phy_model ) {
2345+ case ICE_PHY_ETH56G :
2346+ ad -> ptp_tx_block = hw -> pf_id ;
2347+ ad -> ptp_tx_index = 0 ;
2348+ break ;
2349+ case ICE_PHY_E810 :
2350+ case ICE_PHY_E830 :
2351+ ad -> ptp_tx_block = hw -> port_info -> lport ;
2352+ ad -> ptp_tx_index = 0 ;
2353+ break ;
2354+ case ICE_PHY_E822 :
2355+ ad -> ptp_tx_block = hw -> pf_id / ICE_PORTS_PER_QUAD ;
2356+ ad -> ptp_tx_index = (hw -> pf_id % ICE_PORTS_PER_QUAD ) *
2357+ ICE_PORTS_PER_PHY_E822 * ICE_QUADS_PER_PHY_E822 ;
2358+ break ;
2359+ default :
2360+ PMD_DRV_LOG (WARNING , "Unsupported PHY model" );
2361+ break ;
2362+ }
2363+ }
2364+
23352365static int
23362366ice_dev_init (struct rte_eth_dev * dev )
23372367{
@@ -2499,6 +2529,9 @@ ice_dev_init(struct rte_eth_dev *dev)
24992529 /* Initialize PHY model */
25002530 ice_ptp_init_phy_model (hw );
25012531
2532+ /* Initialize PTP info */
2533+ ice_ptp_init_info (dev );
2534+
25022535 if (hw -> phy_model == ICE_PHY_E822 ) {
25032536 ret = ice_start_phy_timer_e822 (hw , hw -> pf_id );
25042537 if (ret )
@@ -6466,23 +6499,6 @@ ice_timesync_enable(struct rte_eth_dev *dev)
64666499 }
64676500 }
64686501
6469- /* Initialize cycle counters for system time/RX/TX timestamp */
6470- memset (& ad -> systime_tc , 0 , sizeof (struct rte_timecounter ));
6471- memset (& ad -> rx_tstamp_tc , 0 , sizeof (struct rte_timecounter ));
6472- memset (& ad -> tx_tstamp_tc , 0 , sizeof (struct rte_timecounter ));
6473-
6474- ad -> systime_tc .cc_mask = ICE_CYCLECOUNTER_MASK ;
6475- ad -> systime_tc .cc_shift = 0 ;
6476- ad -> systime_tc .nsec_mask = 0 ;
6477-
6478- ad -> rx_tstamp_tc .cc_mask = ICE_CYCLECOUNTER_MASK ;
6479- ad -> rx_tstamp_tc .cc_shift = 0 ;
6480- ad -> rx_tstamp_tc .nsec_mask = 0 ;
6481-
6482- ad -> tx_tstamp_tc .cc_mask = ICE_CYCLECOUNTER_MASK ;
6483- ad -> tx_tstamp_tc .cc_shift = 0 ;
6484- ad -> tx_tstamp_tc .nsec_mask = 0 ;
6485-
64866502 ad -> ptp_ena = 1 ;
64876503
64886504 return 0 ;
@@ -6497,14 +6513,13 @@ ice_timesync_read_rx_timestamp(struct rte_eth_dev *dev,
64976513 ICE_DEV_PRIVATE_TO_ADAPTER (dev -> data -> dev_private );
64986514 struct ice_rx_queue * rxq ;
64996515 uint32_t ts_high ;
6500- uint64_t ts_ns , ns ;
6516+ uint64_t ts_ns ;
65016517
65026518 rxq = dev -> data -> rx_queues [flags ];
65036519
65046520 ts_high = rxq -> time_high ;
65056521 ts_ns = ice_tstamp_convert_32b_64b (hw , ad , 1 , ts_high );
6506- ns = rte_timecounter_update (& ad -> rx_tstamp_tc , ts_ns );
6507- * timestamp = rte_ns_to_timespec (ns );
6522+ * timestamp = rte_ns_to_timespec (ts_ns );
65086523
65096524 return 0 ;
65106525}
@@ -6516,51 +6531,127 @@ ice_timesync_read_tx_timestamp(struct rte_eth_dev *dev,
65166531 struct ice_hw * hw = ICE_DEV_PRIVATE_TO_HW (dev -> data -> dev_private );
65176532 struct ice_adapter * ad =
65186533 ICE_DEV_PRIVATE_TO_ADAPTER (dev -> data -> dev_private );
6519- uint8_t lport ;
6520- uint64_t ts_ns , ns , tstamp ;
6534+ uint64_t ts_ns , tstamp ;
65216535 const uint64_t mask = 0xFFFFFFFF ;
65226536 int ret ;
65236537
6524- lport = hw -> port_info -> lport ;
6525-
6526- ret = ice_read_phy_tstamp (hw , lport , 0 , & tstamp );
6527- if (ret ) {
6538+ ret = ice_read_phy_tstamp (hw , ad -> ptp_tx_block , ad -> ptp_tx_index , & tstamp );
6539+ if (ret || tstamp == 0 ) {
65286540 PMD_DRV_LOG (ERR , "Failed to read phy timestamp" );
65296541 return -1 ;
65306542 }
65316543
65326544 ts_ns = ice_tstamp_convert_32b_64b (hw , ad , 1 , (tstamp >> 8 ) & mask );
6533- ns = rte_timecounter_update (& ad -> tx_tstamp_tc , ts_ns );
6534- * timestamp = rte_ns_to_timespec (ns );
6545+ * timestamp = rte_ns_to_timespec (ts_ns );
65356546
65366547 return 0 ;
65376548}
65386549
65396550static int
65406551ice_timesync_adjust_time (struct rte_eth_dev * dev , int64_t delta )
65416552{
6542- struct ice_adapter * ad =
6543- ICE_DEV_PRIVATE_TO_ADAPTER (dev -> data -> dev_private );
6553+ struct ice_hw * hw = ICE_DEV_PRIVATE_TO_HW (dev -> data -> dev_private );
6554+ uint8_t tmr_idx = hw -> func_caps .ts_func_info .tmr_index_assoc ;
6555+ uint32_t lo , lo2 , hi ;
6556+ uint64_t time , ns ;
6557+ int ret ;
6558+
6559+ if (delta > INT32_MAX || delta < INT32_MIN ) {
6560+ lo = ICE_READ_REG (hw , GLTSYN_TIME_L (tmr_idx ));
6561+ hi = ICE_READ_REG (hw , GLTSYN_TIME_H (tmr_idx ));
6562+ lo2 = ICE_READ_REG (hw , GLTSYN_TIME_L (tmr_idx ));
6563+
6564+ if (lo2 < lo ) {
6565+ lo = ICE_READ_REG (hw , GLTSYN_TIME_L (tmr_idx ));
6566+ hi = ICE_READ_REG (hw , GLTSYN_TIME_H (tmr_idx ));
6567+ }
6568+
6569+ time = ((uint64_t )hi << 32 ) | lo ;
6570+ ns = time + delta ;
6571+
6572+ wr32 (hw , GLTSYN_SHTIME_L (tmr_idx ), ICE_LO_DWORD (ns ));
6573+ wr32 (hw , GLTSYN_SHTIME_H (tmr_idx ), ICE_HI_DWORD (ns ));
6574+ wr32 (hw , GLTSYN_SHTIME_0 (tmr_idx ), 0 );
6575+
6576+ ret = ice_ptp_init_time (hw , ns , true);
6577+ if (ret ) {
6578+ PMD_DRV_LOG (ERR , "PTP init time failed, err %d" , ret );
6579+ return -1 ;
6580+ }
6581+ return 0 ;
6582+ }
6583+
6584+ ret = ice_ptp_adj_clock (hw , delta , true);
6585+ if (ret ) {
6586+ PMD_DRV_LOG (ERR , "PTP adj clock failed, err %d" , ret );
6587+ return -1 ;
6588+ }
6589+
6590+ return 0 ;
6591+ }
6592+
6593+ static int
6594+ ice_timesync_adjust_freq (struct rte_eth_dev * dev , int64_t ppm )
6595+ {
6596+ struct ice_hw * hw = ICE_DEV_PRIVATE_TO_HW (dev -> data -> dev_private );
6597+ int64_t incval , diff = 0 ;
6598+ bool negative = false;
6599+ uint64_t div , rem ;
6600+ uint64_t divisor = 1000000ULL << 16 ;
6601+ int shift ;
6602+ int ret ;
6603+
6604+ incval = ice_get_base_incval (hw , ICE_SRC_TMR_MODE_NANOSECONDS );
6605+
6606+ if (ppm < 0 ) {
6607+ negative = true;
6608+ ppm = - ppm ;
6609+ }
6610+
6611+ /* can incval * ppm overflow ? */
6612+ if (log2 (incval ) + log2 (ppm ) > 62 ) {
6613+ rem = ppm % divisor ;
6614+ div = ppm / divisor ;
6615+ diff = div * incval ;
6616+ ppm = rem ;
65446617
6545- ad -> systime_tc .nsec += delta ;
6546- ad -> rx_tstamp_tc .nsec += delta ;
6547- ad -> tx_tstamp_tc .nsec += delta ;
6618+ shift = log2 (incval ) + log2 (ppm ) - 62 ;
6619+ if (shift > 0 ) {
6620+ /* drop precision */
6621+ ppm >>= shift ;
6622+ divisor >>= shift ;
6623+ }
6624+ }
6625+
6626+ if (divisor )
6627+ diff = diff + incval * ppm / divisor ;
6628+
6629+ if (negative )
6630+ incval -= diff ;
6631+ else
6632+ incval += diff ;
65486633
6634+ ret = ice_ptp_write_incval_locked (hw , incval , true);
6635+ if (ret ) {
6636+ PMD_DRV_LOG (ERR , "PTP failed to set incval, err %d" , ret );
6637+ return -1 ;
6638+ }
65496639 return 0 ;
65506640}
65516641
65526642static int
65536643ice_timesync_write_time (struct rte_eth_dev * dev , const struct timespec * ts )
65546644{
6555- struct ice_adapter * ad =
6556- ICE_DEV_PRIVATE_TO_ADAPTER (dev -> data -> dev_private );
6645+ struct ice_hw * hw = ICE_DEV_PRIVATE_TO_HW (dev -> data -> dev_private );
65576646 uint64_t ns ;
6647+ int ret ;
65586648
65596649 ns = rte_timespec_to_ns (ts );
6560-
6561- ad -> systime_tc .nsec = ns ;
6562- ad -> rx_tstamp_tc .nsec = ns ;
6563- ad -> tx_tstamp_tc .nsec = ns ;
6650+ ret = ice_ptp_init_time (hw , ns , true);
6651+ if (ret ) {
6652+ PMD_DRV_LOG (ERR , "PTP init time failed, err %d" , ret );
6653+ return -1 ;
6654+ }
65646655
65656656 return 0 ;
65666657}
@@ -6569,11 +6660,9 @@ static int
65696660ice_timesync_read_time (struct rte_eth_dev * dev , struct timespec * ts )
65706661{
65716662 struct ice_hw * hw = ICE_DEV_PRIVATE_TO_HW (dev -> data -> dev_private );
6572- struct ice_adapter * ad =
6573- ICE_DEV_PRIVATE_TO_ADAPTER (dev -> data -> dev_private );
65746663 uint8_t tmr_idx = hw -> func_caps .ts_func_info .tmr_index_assoc ;
65756664 uint32_t hi , lo , lo2 ;
6576- uint64_t time , ns ;
6665+ uint64_t time ;
65776666
65786667 lo = ICE_READ_REG (hw , GLTSYN_TIME_L (tmr_idx ));
65796668 hi = ICE_READ_REG (hw , GLTSYN_TIME_H (tmr_idx ));
@@ -6585,8 +6674,7 @@ ice_timesync_read_time(struct rte_eth_dev *dev, struct timespec *ts)
65856674 }
65866675
65876676 time = ((uint64_t )hi << 32 ) | lo ;
6588- ns = rte_timecounter_update (& ad -> systime_tc , time );
6589- * ts = rte_ns_to_timespec (ns );
6677+ * ts = rte_ns_to_timespec (time );
65906678
65916679 return 0 ;
65926680}
0 commit comments