Line data Source code
1 1 : /* 2 : * Copyright (c) 2017 Intel Corporation. 3 : * 4 : * SPDX-License-Identifier: Apache-2.0 5 : */ 6 : 7 : /** 8 : * @file 9 : * @brief Public functions for the Precision Time Protocol Stack. 10 : * 11 : */ 12 : 13 : #ifndef ZEPHYR_INCLUDE_NET_GPTP_H_ 14 : #define ZEPHYR_INCLUDE_NET_GPTP_H_ 15 : 16 : /** 17 : * @brief generic Precision Time Protocol (gPTP) support 18 : * @defgroup gptp gPTP support 19 : * @since 1.13 20 : * @version 0.1.0 21 : * @ingroup networking 22 : * @{ 23 : */ 24 : 25 : #include <zephyr/net/net_core.h> 26 : #include <zephyr/net/ptp_time.h> 27 : #include <stdbool.h> 28 : 29 : #ifdef __cplusplus 30 : extern "C" { 31 : #endif 32 : 33 : /** @cond INTERNAL_HIDDEN */ 34 : 35 : #define GPTP_OFFSET_SCALED_LOG_VAR_UNKNOWN 0x436A 36 : 37 : #define GPTP_PRIORITY1_NON_GM_CAPABLE 255 38 : #define GPTP_PRIORITY1_GM_CAPABLE 248 39 : 40 : #if defined(CONFIG_NET_GPTP_BMCA_PRIORITY2) 41 : #define GPTP_PRIORITY2_DEFAULT CONFIG_NET_GPTP_BMCA_PRIORITY2 42 : #else 43 : #define GPTP_PRIORITY2_DEFAULT 248 44 : #endif 45 : 46 : /** @endcond */ 47 : 48 : /** 49 : * @brief Scaled Nanoseconds. 50 : */ 51 1 : struct gptp_scaled_ns { 52 : /** High half. */ 53 1 : int32_t high; 54 : 55 : /** Low half. */ 56 1 : int64_t low; 57 : } __packed; 58 : 59 : /** 60 : * @brief UScaled Nanoseconds. 61 : */ 62 1 : struct gptp_uscaled_ns { 63 : /** High half. */ 64 1 : uint32_t high; 65 : 66 : /** Low half. */ 67 1 : uint64_t low; 68 : } __packed; 69 : 70 : /** @cond INTERNAL_HIDDEN */ 71 : 72 : #if defined(CONFIG_NEWLIB_LIBC) 73 : #include <math.h> 74 : 75 : #define GPTP_POW2(exp) pow(2, exp) 76 : #else 77 : 78 : static inline double gptp_pow2(int exp) 79 : { 80 : double res; 81 : 82 : if (exp >= 0) { 83 : res = 1 << exp; 84 : } else { 85 : res = 1.0; 86 : 87 : while (exp++) { 88 : res /= 2; 89 : } 90 : } 91 : 92 : return res; 93 : } 94 : 95 : #define GPTP_POW2(exp) gptp_pow2(exp) 96 : #endif 97 : 98 : /* Pre-calculated constants */ 99 : /* 2^16 */ 100 : #define GPTP_POW2_16 65536.0 101 : /* 2^41 */ 102 : #define GPTP_POW2_41 2199023255552.0 103 : 104 : /* Message types. Event messages have BIT(3) set to 0, and general messages 105 : * have that bit set to 1. IEEE 802.1AS chapter 10.5.2.2.2 106 : */ 107 : #define GPTP_SYNC_MESSAGE 0x00 108 : #define GPTP_DELAY_REQ_MESSAGE 0x01 109 : #define GPTP_PATH_DELAY_REQ_MESSAGE 0x02 110 : #define GPTP_PATH_DELAY_RESP_MESSAGE 0x03 111 : #define GPTP_FOLLOWUP_MESSAGE 0x08 112 : #define GPTP_DELAY_RESP_MESSAGE 0x09 113 : #define GPTP_PATH_DELAY_FOLLOWUP_MESSAGE 0x0a 114 : #define GPTP_ANNOUNCE_MESSAGE 0x0b 115 : #define GPTP_SIGNALING_MESSAGE 0x0c 116 : #define GPTP_MANAGEMENT_MESSAGE 0x0d 117 : 118 : #define GPTP_IS_EVENT_MSG(msg_type) (!((msg_type) & BIT(3))) 119 : 120 : #define GPTP_CLOCK_ID_LEN 8 121 : 122 : /** @endcond */ 123 : 124 : /** 125 : * @brief Port Identity. 126 : */ 127 1 : struct gptp_port_identity { 128 : /** Clock identity of the port. */ 129 1 : uint8_t clk_id[GPTP_CLOCK_ID_LEN]; 130 : 131 : /** Number of the port. */ 132 1 : uint16_t port_number; 133 : } __packed; 134 : 135 : /** gPTP message flags */ 136 1 : struct gptp_flags { 137 : union { 138 : /** Byte access. */ 139 1 : uint8_t octets[2]; 140 : 141 : /** Whole field access. */ 142 1 : uint16_t all; 143 0 : }; 144 : } __packed; 145 : 146 : /** gPTP message header */ 147 1 : struct gptp_hdr { 148 : /** Type of the message. */ 149 1 : uint8_t message_type:4; 150 : 151 : /** Transport specific, always 1. */ 152 1 : uint8_t transport_specific:4; 153 : 154 : /** Version of the PTP, always 2. */ 155 1 : uint8_t ptp_version:4; 156 : 157 : /** Reserved field. */ 158 1 : uint8_t reserved0:4; 159 : 160 : /** Total length of the message from the header to the last TLV. */ 161 1 : uint16_t message_length; 162 : 163 : /** Domain number, always 0. */ 164 1 : uint8_t domain_number; 165 : 166 : /** Reserved field. */ 167 1 : uint8_t reserved1; 168 : 169 : /** Message flags. */ 170 1 : struct gptp_flags flags; 171 : 172 : /** Correction Field. The content depends of the message type. */ 173 1 : int64_t correction_field; 174 : 175 : /** Reserved field. */ 176 1 : uint32_t reserved2; 177 : 178 : /** Port Identity of the sender. */ 179 1 : struct gptp_port_identity port_id; 180 : 181 : /** Sequence Id. */ 182 1 : uint16_t sequence_id; 183 : 184 : /** Control value. Sync: 0, Follow-up: 2, Others: 5. */ 185 1 : uint8_t control; 186 : 187 : /** Message Interval in Log2 for Sync and Announce messages. */ 188 1 : int8_t log_msg_interval; 189 : } __packed; 190 : 191 : /** @cond INTERNAL_HIDDEN */ 192 : 193 : #define GPTP_GET_CURRENT_TIME_USCALED_NS(port, uscaled_ns_ptr) \ 194 : do { \ 195 : (uscaled_ns_ptr)->low = \ 196 : gptp_get_current_time_nanosecond(port) << 16; \ 197 : (uscaled_ns_ptr)->high = 0; \ 198 : } while (false) 199 : 200 : /** @endcond */ 201 : 202 : /** 203 : * @typedef gptp_phase_dis_callback_t 204 : * @brief Define callback that is called after a phase discontinuity has been 205 : * sent by the grandmaster. 206 : * @param gm_identity A pointer to first element of a ClockIdentity array. 207 : * The size of the array is GPTP_CLOCK_ID_LEN. 208 : * @param time_base A pointer to the value of timeBaseIndicator of the current 209 : * grandmaster. 210 : * @param last_gm_ph_change A pointer to the value of lastGmPhaseChange received 211 : * from grandmaster. 212 : * @param last_gm_freq_change A pointer to the value of lastGmFreqChange 213 : * received from the grandmaster. 214 : */ 215 1 : typedef void (*gptp_phase_dis_callback_t)( 216 : uint8_t *gm_identity, 217 : uint16_t *time_base, 218 : struct gptp_scaled_ns *last_gm_ph_change, 219 : double *last_gm_freq_change); 220 : 221 : /** 222 : * @brief Phase discontinuity callback structure. 223 : * 224 : * Stores the phase discontinuity callback information. Caller must make sure 225 : * that the variable pointed by this is valid during the lifetime of 226 : * registration. Typically this means that the variable cannot be 227 : * allocated from stack. 228 : */ 229 1 : struct gptp_phase_dis_cb { 230 : /** Node information for the slist. */ 231 1 : sys_snode_t node; 232 : 233 : /** Phase discontinuity callback. */ 234 1 : gptp_phase_dis_callback_t cb; 235 : }; 236 : 237 : /** 238 : * @brief ClockSourceTime.invoke function parameters 239 : * 240 : * Parameters passed by ClockSourceTime.invoke function. 241 : */ 242 1 : struct gptp_clk_src_time_invoke_params { 243 : /** Frequency change on the last Time Base Indicator Change. */ 244 1 : double last_gm_freq_change; 245 : 246 : /** The time this function is invoked. */ 247 1 : struct net_ptp_extended_time src_time; 248 : 249 : /** Phase change on the last Time Base Indicator Change. */ 250 1 : struct gptp_scaled_ns last_gm_phase_change; 251 : 252 : /** Time Base - changed only if Phase or Frequency changes. */ 253 1 : uint16_t time_base_indicator; 254 : }; 255 : 256 : /** 257 : * @brief Register a phase discontinuity callback. 258 : * 259 : * @param phase_dis Caller specified handler for the callback. 260 : * @param cb Callback to register. 261 : */ 262 1 : void gptp_register_phase_dis_cb(struct gptp_phase_dis_cb *phase_dis, 263 : gptp_phase_dis_callback_t cb); 264 : 265 : /** 266 : * @brief Unregister a phase discontinuity callback. 267 : * 268 : * @param phase_dis Caller specified handler for the callback. 269 : */ 270 1 : void gptp_unregister_phase_dis_cb(struct gptp_phase_dis_cb *phase_dis); 271 : 272 : /** 273 : * @brief Call a phase discontinuity callback function. 274 : */ 275 1 : void gptp_call_phase_dis_cb(void); 276 : 277 : /** 278 : * @brief Get gPTP time. 279 : * 280 : * @param slave_time A pointer to structure where timestamp will be saved. 281 : * @param gm_present A pointer to a boolean where status of the 282 : * presence of a grand master will be saved. 283 : * 284 : * @return Error code. 0 if no error. 285 : */ 286 1 : int gptp_event_capture(struct net_ptp_time *slave_time, bool *gm_present); 287 : 288 : /** 289 : * @brief Utility function to print clock id to a user supplied buffer. 290 : * 291 : * @param clk_id Clock id 292 : * @param output Output buffer 293 : * @param output_len Output buffer len 294 : * 295 : * @return Pointer to output buffer 296 : */ 297 1 : char *gptp_sprint_clock_id(const uint8_t *clk_id, char *output, 298 : size_t output_len); 299 : 300 : /** 301 : * @typedef gptp_port_cb_t 302 : * @brief Callback used while iterating over gPTP ports 303 : * 304 : * @param port Port number 305 : * @param iface Pointer to network interface 306 : * @param user_data A valid pointer to user data or NULL 307 : */ 308 1 : typedef void (*gptp_port_cb_t)(int port, struct net_if *iface, 309 : void *user_data); 310 : 311 : /** 312 : * @brief Go through all the gPTP ports and call callback for each of them. 313 : * 314 : * @param cb User-supplied callback function to call 315 : * @param user_data User specified data 316 : */ 317 1 : void gptp_foreach_port(gptp_port_cb_t cb, void *user_data); 318 : 319 : /** 320 : * @brief Get gPTP domain. 321 : * @details This contains all the configuration / status of the gPTP domain. 322 : * 323 : * @return Pointer to domain or NULL if not found. 324 : */ 325 1 : struct gptp_domain *gptp_get_domain(void); 326 : 327 : /** 328 : * @brief This interface is used by the ClockSource entity to provide time to 329 : * the ClockMaster entity of a time-aware system. 330 : * 331 : * @param arg Current state and parameters of the ClockSource entity. 332 : */ 333 1 : void gptp_clk_src_time_invoke(struct gptp_clk_src_time_invoke_params *arg); 334 : 335 : /** 336 : * @brief Return pointer to gPTP packet header in network packet. 337 : * 338 : * @param pkt Network packet (received or sent) 339 : * 340 : * @return Pointer to gPTP header. 341 : */ 342 1 : struct gptp_hdr *gptp_get_hdr(struct net_pkt *pkt); 343 : 344 : #ifdef __cplusplus 345 : } 346 : #endif 347 : 348 : /** 349 : * @} 350 : */ 351 : 352 : #endif /* ZEPHYR_INCLUDE_NET_GPTP_H_ */