162306a36Sopenharmony_ci/* SPDX-License-Identifier: GPL-2.0 */ 262306a36Sopenharmony_ci/* Copyright (C) 2021, Intel Corporation. */ 362306a36Sopenharmony_ci 462306a36Sopenharmony_ci#ifndef _ICE_PTP_H_ 562306a36Sopenharmony_ci#define _ICE_PTP_H_ 662306a36Sopenharmony_ci 762306a36Sopenharmony_ci#include <linux/ptp_clock_kernel.h> 862306a36Sopenharmony_ci#include <linux/kthread.h> 962306a36Sopenharmony_ci 1062306a36Sopenharmony_ci#include "ice_ptp_hw.h" 1162306a36Sopenharmony_ci 1262306a36Sopenharmony_cienum ice_ptp_pin_e810 { 1362306a36Sopenharmony_ci GPIO_20 = 0, 1462306a36Sopenharmony_ci GPIO_21, 1562306a36Sopenharmony_ci GPIO_22, 1662306a36Sopenharmony_ci GPIO_23, 1762306a36Sopenharmony_ci NUM_PTP_PIN_E810 1862306a36Sopenharmony_ci}; 1962306a36Sopenharmony_ci 2062306a36Sopenharmony_cienum ice_ptp_pin_e810t { 2162306a36Sopenharmony_ci GNSS = 0, 2262306a36Sopenharmony_ci SMA1, 2362306a36Sopenharmony_ci UFL1, 2462306a36Sopenharmony_ci SMA2, 2562306a36Sopenharmony_ci UFL2, 2662306a36Sopenharmony_ci NUM_PTP_PINS_E810T 2762306a36Sopenharmony_ci}; 2862306a36Sopenharmony_ci 2962306a36Sopenharmony_cistruct ice_perout_channel { 3062306a36Sopenharmony_ci bool ena; 3162306a36Sopenharmony_ci u32 gpio_pin; 3262306a36Sopenharmony_ci u64 period; 3362306a36Sopenharmony_ci u64 start_time; 3462306a36Sopenharmony_ci}; 3562306a36Sopenharmony_ci 3662306a36Sopenharmony_ci/* The ice hardware captures Tx hardware timestamps in the PHY. The timestamp 3762306a36Sopenharmony_ci * is stored in a buffer of registers. Depending on the specific hardware, 3862306a36Sopenharmony_ci * this buffer might be shared across multiple PHY ports. 3962306a36Sopenharmony_ci * 4062306a36Sopenharmony_ci * On transmit of a packet to be timestamped, software is responsible for 4162306a36Sopenharmony_ci * selecting an open index. Hardware makes no attempt to lock or prevent 4262306a36Sopenharmony_ci * re-use of an index for multiple packets. 4362306a36Sopenharmony_ci * 4462306a36Sopenharmony_ci * To handle this, timestamp indexes must be tracked by software to ensure 4562306a36Sopenharmony_ci * that an index is not re-used for multiple transmitted packets. The 4662306a36Sopenharmony_ci * structures and functions declared in this file track the available Tx 4762306a36Sopenharmony_ci * register indexes, as well as provide storage for the SKB pointers. 4862306a36Sopenharmony_ci * 4962306a36Sopenharmony_ci * To allow multiple ports to access the shared register block independently, 5062306a36Sopenharmony_ci * the blocks are split up so that indexes are assigned to each port based on 5162306a36Sopenharmony_ci * hardware logical port number. 5262306a36Sopenharmony_ci * 5362306a36Sopenharmony_ci * The timestamp blocks are handled differently for E810- and E822-based 5462306a36Sopenharmony_ci * devices. In E810 devices, each port has its own block of timestamps, while in 5562306a36Sopenharmony_ci * E822 there is a need to logically break the block of registers into smaller 5662306a36Sopenharmony_ci * chunks based on the port number to avoid collisions. 5762306a36Sopenharmony_ci * 5862306a36Sopenharmony_ci * Example for port 5 in E810: 5962306a36Sopenharmony_ci * +--------+--------+--------+--------+--------+--------+--------+--------+ 6062306a36Sopenharmony_ci * |register|register|register|register|register|register|register|register| 6162306a36Sopenharmony_ci * | block | block | block | block | block | block | block | block | 6262306a36Sopenharmony_ci * | for | for | for | for | for | for | for | for | 6362306a36Sopenharmony_ci * | port 0 | port 1 | port 2 | port 3 | port 4 | port 5 | port 6 | port 7 | 6462306a36Sopenharmony_ci * +--------+--------+--------+--------+--------+--------+--------+--------+ 6562306a36Sopenharmony_ci * ^^ 6662306a36Sopenharmony_ci * || 6762306a36Sopenharmony_ci * |--- quad offset is always 0 6862306a36Sopenharmony_ci * ---- quad number 6962306a36Sopenharmony_ci * 7062306a36Sopenharmony_ci * Example for port 5 in E822: 7162306a36Sopenharmony_ci * +-----------------------------+-----------------------------+ 7262306a36Sopenharmony_ci * | register block for quad 0 | register block for quad 1 | 7362306a36Sopenharmony_ci * |+------+------+------+------+|+------+------+------+------+| 7462306a36Sopenharmony_ci * ||port 0|port 1|port 2|port 3|||port 0|port 1|port 2|port 3|| 7562306a36Sopenharmony_ci * |+------+------+------+------+|+------+------+------+------+| 7662306a36Sopenharmony_ci * +-----------------------------+-------^---------------------+ 7762306a36Sopenharmony_ci * ^ | 7862306a36Sopenharmony_ci * | --- quad offset* 7962306a36Sopenharmony_ci * ---- quad number 8062306a36Sopenharmony_ci * 8162306a36Sopenharmony_ci * * PHY port 5 is port 1 in quad 1 8262306a36Sopenharmony_ci * 8362306a36Sopenharmony_ci */ 8462306a36Sopenharmony_ci 8562306a36Sopenharmony_ci/** 8662306a36Sopenharmony_ci * struct ice_tx_tstamp - Tracking for a single Tx timestamp 8762306a36Sopenharmony_ci * @skb: pointer to the SKB for this timestamp request 8862306a36Sopenharmony_ci * @start: jiffies when the timestamp was first requested 8962306a36Sopenharmony_ci * @cached_tstamp: last read timestamp 9062306a36Sopenharmony_ci * 9162306a36Sopenharmony_ci * This structure tracks a single timestamp request. The SKB pointer is 9262306a36Sopenharmony_ci * provided when initiating a request. The start time is used to ensure that 9362306a36Sopenharmony_ci * we discard old requests that were not fulfilled within a 2 second time 9462306a36Sopenharmony_ci * window. 9562306a36Sopenharmony_ci * Timestamp values in the PHY are read only and do not get cleared except at 9662306a36Sopenharmony_ci * hardware reset or when a new timestamp value is captured. 9762306a36Sopenharmony_ci * 9862306a36Sopenharmony_ci * Some PHY types do not provide a "ready" bitmap indicating which timestamp 9962306a36Sopenharmony_ci * indexes are valid. In these cases, we use a cached_tstamp to keep track of 10062306a36Sopenharmony_ci * the last timestamp we read for a given index. If the current timestamp 10162306a36Sopenharmony_ci * value is the same as the cached value, we assume a new timestamp hasn't 10262306a36Sopenharmony_ci * been captured. This avoids reporting stale timestamps to the stack. This is 10362306a36Sopenharmony_ci * only done if the verify_cached flag is set in ice_ptp_tx structure. 10462306a36Sopenharmony_ci */ 10562306a36Sopenharmony_cistruct ice_tx_tstamp { 10662306a36Sopenharmony_ci struct sk_buff *skb; 10762306a36Sopenharmony_ci unsigned long start; 10862306a36Sopenharmony_ci u64 cached_tstamp; 10962306a36Sopenharmony_ci}; 11062306a36Sopenharmony_ci 11162306a36Sopenharmony_ci/** 11262306a36Sopenharmony_ci * enum ice_tx_tstamp_work - Status of Tx timestamp work function 11362306a36Sopenharmony_ci * @ICE_TX_TSTAMP_WORK_DONE: Tx timestamp processing is complete 11462306a36Sopenharmony_ci * @ICE_TX_TSTAMP_WORK_PENDING: More Tx timestamps are pending 11562306a36Sopenharmony_ci */ 11662306a36Sopenharmony_cienum ice_tx_tstamp_work { 11762306a36Sopenharmony_ci ICE_TX_TSTAMP_WORK_DONE = 0, 11862306a36Sopenharmony_ci ICE_TX_TSTAMP_WORK_PENDING, 11962306a36Sopenharmony_ci}; 12062306a36Sopenharmony_ci 12162306a36Sopenharmony_ci/** 12262306a36Sopenharmony_ci * struct ice_ptp_tx - Tracking structure for all Tx timestamp requests on a port 12362306a36Sopenharmony_ci * @lock: lock to prevent concurrent access to fields of this struct 12462306a36Sopenharmony_ci * @tstamps: array of len to store outstanding requests 12562306a36Sopenharmony_ci * @in_use: bitmap of len to indicate which slots are in use 12662306a36Sopenharmony_ci * @stale: bitmap of len to indicate slots which have stale timestamps 12762306a36Sopenharmony_ci * @block: which memory block (quad or port) the timestamps are captured in 12862306a36Sopenharmony_ci * @offset: offset into timestamp block to get the real index 12962306a36Sopenharmony_ci * @len: length of the tstamps and in_use fields. 13062306a36Sopenharmony_ci * @init: if true, the tracker is initialized; 13162306a36Sopenharmony_ci * @calibrating: if true, the PHY is calibrating the Tx offset. During this 13262306a36Sopenharmony_ci * window, timestamps are temporarily disabled. 13362306a36Sopenharmony_ci * @verify_cached: if true, verify new timestamp differs from last read value 13462306a36Sopenharmony_ci */ 13562306a36Sopenharmony_cistruct ice_ptp_tx { 13662306a36Sopenharmony_ci spinlock_t lock; /* lock protecting in_use bitmap */ 13762306a36Sopenharmony_ci struct ice_tx_tstamp *tstamps; 13862306a36Sopenharmony_ci unsigned long *in_use; 13962306a36Sopenharmony_ci unsigned long *stale; 14062306a36Sopenharmony_ci u8 block; 14162306a36Sopenharmony_ci u8 offset; 14262306a36Sopenharmony_ci u8 len; 14362306a36Sopenharmony_ci u8 init : 1; 14462306a36Sopenharmony_ci u8 calibrating : 1; 14562306a36Sopenharmony_ci u8 verify_cached : 1; 14662306a36Sopenharmony_ci}; 14762306a36Sopenharmony_ci 14862306a36Sopenharmony_ci/* Quad and port information for initializing timestamp blocks */ 14962306a36Sopenharmony_ci#define INDEX_PER_QUAD 64 15062306a36Sopenharmony_ci#define INDEX_PER_PORT_E822 16 15162306a36Sopenharmony_ci#define INDEX_PER_PORT_E810 64 15262306a36Sopenharmony_ci 15362306a36Sopenharmony_ci/** 15462306a36Sopenharmony_ci * struct ice_ptp_port - data used to initialize an external port for PTP 15562306a36Sopenharmony_ci * 15662306a36Sopenharmony_ci * This structure contains data indicating whether a single external port is 15762306a36Sopenharmony_ci * ready for PTP functionality. It is used to track the port initialization 15862306a36Sopenharmony_ci * and determine when the port's PHY offset is valid. 15962306a36Sopenharmony_ci * 16062306a36Sopenharmony_ci * @tx: Tx timestamp tracking for this port 16162306a36Sopenharmony_ci * @ov_work: delayed work task for tracking when PHY offset is valid 16262306a36Sopenharmony_ci * @ps_lock: mutex used to protect the overall PTP PHY start procedure 16362306a36Sopenharmony_ci * @link_up: indicates whether the link is up 16462306a36Sopenharmony_ci * @tx_fifo_busy_cnt: number of times the Tx FIFO was busy 16562306a36Sopenharmony_ci * @port_num: the port number this structure represents 16662306a36Sopenharmony_ci */ 16762306a36Sopenharmony_cistruct ice_ptp_port { 16862306a36Sopenharmony_ci struct ice_ptp_tx tx; 16962306a36Sopenharmony_ci struct kthread_delayed_work ov_work; 17062306a36Sopenharmony_ci struct mutex ps_lock; /* protects overall PTP PHY start procedure */ 17162306a36Sopenharmony_ci bool link_up; 17262306a36Sopenharmony_ci u8 tx_fifo_busy_cnt; 17362306a36Sopenharmony_ci u8 port_num; 17462306a36Sopenharmony_ci}; 17562306a36Sopenharmony_ci 17662306a36Sopenharmony_ci#define GLTSYN_TGT_H_IDX_MAX 4 17762306a36Sopenharmony_ci 17862306a36Sopenharmony_ci/** 17962306a36Sopenharmony_ci * struct ice_ptp - data used for integrating with CONFIG_PTP_1588_CLOCK 18062306a36Sopenharmony_ci * @port: data for the PHY port initialization procedure 18162306a36Sopenharmony_ci * @work: delayed work function for periodic tasks 18262306a36Sopenharmony_ci * @cached_phc_time: a cached copy of the PHC time for timestamp extension 18362306a36Sopenharmony_ci * @cached_phc_jiffies: jiffies when cached_phc_time was last updated 18462306a36Sopenharmony_ci * @ext_ts_chan: the external timestamp channel in use 18562306a36Sopenharmony_ci * @ext_ts_irq: the external timestamp IRQ in use 18662306a36Sopenharmony_ci * @kworker: kwork thread for handling periodic work 18762306a36Sopenharmony_ci * @perout_channels: periodic output data 18862306a36Sopenharmony_ci * @info: structure defining PTP hardware capabilities 18962306a36Sopenharmony_ci * @clock: pointer to registered PTP clock device 19062306a36Sopenharmony_ci * @tstamp_config: hardware timestamping configuration 19162306a36Sopenharmony_ci * @reset_time: kernel time after clock stop on reset 19262306a36Sopenharmony_ci * @tx_hwtstamp_skipped: number of Tx time stamp requests skipped 19362306a36Sopenharmony_ci * @tx_hwtstamp_timeouts: number of Tx skbs discarded with no time stamp 19462306a36Sopenharmony_ci * @tx_hwtstamp_flushed: number of Tx skbs flushed due to interface closed 19562306a36Sopenharmony_ci * @tx_hwtstamp_discarded: number of Tx skbs discarded due to cached PHC time 19662306a36Sopenharmony_ci * being too old to correctly extend timestamp 19762306a36Sopenharmony_ci * @late_cached_phc_updates: number of times cached PHC update is late 19862306a36Sopenharmony_ci */ 19962306a36Sopenharmony_cistruct ice_ptp { 20062306a36Sopenharmony_ci struct ice_ptp_port port; 20162306a36Sopenharmony_ci struct kthread_delayed_work work; 20262306a36Sopenharmony_ci u64 cached_phc_time; 20362306a36Sopenharmony_ci unsigned long cached_phc_jiffies; 20462306a36Sopenharmony_ci u8 ext_ts_chan; 20562306a36Sopenharmony_ci u8 ext_ts_irq; 20662306a36Sopenharmony_ci struct kthread_worker *kworker; 20762306a36Sopenharmony_ci struct ice_perout_channel perout_channels[GLTSYN_TGT_H_IDX_MAX]; 20862306a36Sopenharmony_ci struct ptp_clock_info info; 20962306a36Sopenharmony_ci struct ptp_clock *clock; 21062306a36Sopenharmony_ci struct hwtstamp_config tstamp_config; 21162306a36Sopenharmony_ci u64 reset_time; 21262306a36Sopenharmony_ci u32 tx_hwtstamp_skipped; 21362306a36Sopenharmony_ci u32 tx_hwtstamp_timeouts; 21462306a36Sopenharmony_ci u32 tx_hwtstamp_flushed; 21562306a36Sopenharmony_ci u32 tx_hwtstamp_discarded; 21662306a36Sopenharmony_ci u32 late_cached_phc_updates; 21762306a36Sopenharmony_ci}; 21862306a36Sopenharmony_ci 21962306a36Sopenharmony_ci#define __ptp_port_to_ptp(p) \ 22062306a36Sopenharmony_ci container_of((p), struct ice_ptp, port) 22162306a36Sopenharmony_ci#define ptp_port_to_pf(p) \ 22262306a36Sopenharmony_ci container_of(__ptp_port_to_ptp((p)), struct ice_pf, ptp) 22362306a36Sopenharmony_ci 22462306a36Sopenharmony_ci#define __ptp_info_to_ptp(i) \ 22562306a36Sopenharmony_ci container_of((i), struct ice_ptp, info) 22662306a36Sopenharmony_ci#define ptp_info_to_pf(i) \ 22762306a36Sopenharmony_ci container_of(__ptp_info_to_ptp((i)), struct ice_pf, ptp) 22862306a36Sopenharmony_ci 22962306a36Sopenharmony_ci#define PFTSYN_SEM_BYTES 4 23062306a36Sopenharmony_ci#define PTP_SHARED_CLK_IDX_VALID BIT(31) 23162306a36Sopenharmony_ci#define TS_CMD_MASK 0xF 23262306a36Sopenharmony_ci#define SYNC_EXEC_CMD 0x3 23362306a36Sopenharmony_ci#define ICE_PTP_TS_VALID BIT(0) 23462306a36Sopenharmony_ci 23562306a36Sopenharmony_ci#define FIFO_EMPTY BIT(2) 23662306a36Sopenharmony_ci#define FIFO_OK 0xFF 23762306a36Sopenharmony_ci#define ICE_PTP_FIFO_NUM_CHECKS 5 23862306a36Sopenharmony_ci/* Per-channel register definitions */ 23962306a36Sopenharmony_ci#define GLTSYN_AUX_OUT(_chan, _idx) (GLTSYN_AUX_OUT_0(_idx) + ((_chan) * 8)) 24062306a36Sopenharmony_ci#define GLTSYN_AUX_IN(_chan, _idx) (GLTSYN_AUX_IN_0(_idx) + ((_chan) * 8)) 24162306a36Sopenharmony_ci#define GLTSYN_CLKO(_chan, _idx) (GLTSYN_CLKO_0(_idx) + ((_chan) * 8)) 24262306a36Sopenharmony_ci#define GLTSYN_TGT_L(_chan, _idx) (GLTSYN_TGT_L_0(_idx) + ((_chan) * 16)) 24362306a36Sopenharmony_ci#define GLTSYN_TGT_H(_chan, _idx) (GLTSYN_TGT_H_0(_idx) + ((_chan) * 16)) 24462306a36Sopenharmony_ci#define GLTSYN_EVNT_L(_chan, _idx) (GLTSYN_EVNT_L_0(_idx) + ((_chan) * 16)) 24562306a36Sopenharmony_ci#define GLTSYN_EVNT_H(_chan, _idx) (GLTSYN_EVNT_H_0(_idx) + ((_chan) * 16)) 24662306a36Sopenharmony_ci#define GLTSYN_EVNT_H_IDX_MAX 3 24762306a36Sopenharmony_ci 24862306a36Sopenharmony_ci/* Pin definitions for PTP PPS out */ 24962306a36Sopenharmony_ci#define PPS_CLK_GEN_CHAN 3 25062306a36Sopenharmony_ci#define PPS_CLK_SRC_CHAN 2 25162306a36Sopenharmony_ci#define PPS_PIN_INDEX 5 25262306a36Sopenharmony_ci#define TIME_SYNC_PIN_INDEX 4 25362306a36Sopenharmony_ci#define N_EXT_TS_E810 3 25462306a36Sopenharmony_ci#define N_PER_OUT_E810 4 25562306a36Sopenharmony_ci#define N_PER_OUT_E810T 3 25662306a36Sopenharmony_ci#define N_PER_OUT_NO_SMA_E810T 2 25762306a36Sopenharmony_ci#define N_EXT_TS_NO_SMA_E810T 2 25862306a36Sopenharmony_ci#define ETH_GLTSYN_ENA(_i) (0x03000348 + ((_i) * 4)) 25962306a36Sopenharmony_ci 26062306a36Sopenharmony_ci#if IS_ENABLED(CONFIG_PTP_1588_CLOCK) 26162306a36Sopenharmony_cistruct ice_pf; 26262306a36Sopenharmony_ciint ice_ptp_set_ts_config(struct ice_pf *pf, struct ifreq *ifr); 26362306a36Sopenharmony_ciint ice_ptp_get_ts_config(struct ice_pf *pf, struct ifreq *ifr); 26462306a36Sopenharmony_civoid ice_ptp_cfg_timestamp(struct ice_pf *pf, bool ena); 26562306a36Sopenharmony_ciint ice_get_ptp_clock_index(struct ice_pf *pf); 26662306a36Sopenharmony_ci 26762306a36Sopenharmony_civoid ice_ptp_extts_event(struct ice_pf *pf); 26862306a36Sopenharmony_cis8 ice_ptp_request_ts(struct ice_ptp_tx *tx, struct sk_buff *skb); 26962306a36Sopenharmony_cienum ice_tx_tstamp_work ice_ptp_process_ts(struct ice_pf *pf); 27062306a36Sopenharmony_ci 27162306a36Sopenharmony_civoid 27262306a36Sopenharmony_ciice_ptp_rx_hwtstamp(struct ice_rx_ring *rx_ring, 27362306a36Sopenharmony_ci union ice_32b_rx_flex_desc *rx_desc, struct sk_buff *skb); 27462306a36Sopenharmony_civoid ice_ptp_reset(struct ice_pf *pf); 27562306a36Sopenharmony_civoid ice_ptp_prepare_for_reset(struct ice_pf *pf); 27662306a36Sopenharmony_civoid ice_ptp_init(struct ice_pf *pf); 27762306a36Sopenharmony_civoid ice_ptp_release(struct ice_pf *pf); 27862306a36Sopenharmony_civoid ice_ptp_link_change(struct ice_pf *pf, u8 port, bool linkup); 27962306a36Sopenharmony_ci#else /* IS_ENABLED(CONFIG_PTP_1588_CLOCK) */ 28062306a36Sopenharmony_cistatic inline int ice_ptp_set_ts_config(struct ice_pf *pf, struct ifreq *ifr) 28162306a36Sopenharmony_ci{ 28262306a36Sopenharmony_ci return -EOPNOTSUPP; 28362306a36Sopenharmony_ci} 28462306a36Sopenharmony_ci 28562306a36Sopenharmony_cistatic inline int ice_ptp_get_ts_config(struct ice_pf *pf, struct ifreq *ifr) 28662306a36Sopenharmony_ci{ 28762306a36Sopenharmony_ci return -EOPNOTSUPP; 28862306a36Sopenharmony_ci} 28962306a36Sopenharmony_ci 29062306a36Sopenharmony_cistatic inline void ice_ptp_cfg_timestamp(struct ice_pf *pf, bool ena) { } 29162306a36Sopenharmony_cistatic inline int ice_get_ptp_clock_index(struct ice_pf *pf) 29262306a36Sopenharmony_ci{ 29362306a36Sopenharmony_ci return -1; 29462306a36Sopenharmony_ci} 29562306a36Sopenharmony_ci 29662306a36Sopenharmony_cistatic inline void ice_ptp_extts_event(struct ice_pf *pf) { } 29762306a36Sopenharmony_cistatic inline s8 29862306a36Sopenharmony_ciice_ptp_request_ts(struct ice_ptp_tx *tx, struct sk_buff *skb) 29962306a36Sopenharmony_ci{ 30062306a36Sopenharmony_ci return -1; 30162306a36Sopenharmony_ci} 30262306a36Sopenharmony_ci 30362306a36Sopenharmony_cistatic inline bool ice_ptp_process_ts(struct ice_pf *pf) 30462306a36Sopenharmony_ci{ 30562306a36Sopenharmony_ci return true; 30662306a36Sopenharmony_ci} 30762306a36Sopenharmony_cistatic inline void 30862306a36Sopenharmony_ciice_ptp_rx_hwtstamp(struct ice_rx_ring *rx_ring, 30962306a36Sopenharmony_ci union ice_32b_rx_flex_desc *rx_desc, struct sk_buff *skb) { } 31062306a36Sopenharmony_cistatic inline void ice_ptp_reset(struct ice_pf *pf) { } 31162306a36Sopenharmony_cistatic inline void ice_ptp_prepare_for_reset(struct ice_pf *pf) { } 31262306a36Sopenharmony_cistatic inline void ice_ptp_init(struct ice_pf *pf) { } 31362306a36Sopenharmony_cistatic inline void ice_ptp_release(struct ice_pf *pf) { } 31462306a36Sopenharmony_cistatic inline void ice_ptp_link_change(struct ice_pf *pf, u8 port, bool linkup) 31562306a36Sopenharmony_ci{ 31662306a36Sopenharmony_ci} 31762306a36Sopenharmony_ci#endif /* IS_ENABLED(CONFIG_PTP_1588_CLOCK) */ 31862306a36Sopenharmony_ci#endif /* _ICE_PTP_H_ */ 319