1 /* 2 * Copyright (c) 2024 BayLibre SAS 3 * 4 * SPDX-License-Identifier: Apache-2.0 5 */ 6 7 /** 8 * @file tlv.h 9 * @brief Type, Length, Value extension for PTP 10 * 11 * References are to version 2019 of IEEE 1588, ("PTP") 12 */ 13 14 #ifndef ZEPHYR_INCLUDE_PTP_TLV_H_ 15 #define ZEPHYR_INCLUDE_PTP_TLV_H_ 16 17 #ifdef __cplusplus 18 extern "C" { 19 #endif 20 21 #include <stdint.h> 22 23 #include "ddt.h" 24 #include "msg.h" 25 26 /** 27 * @brief Type of TLV (type, length, value) 28 * 29 * @note based on IEEE 1588-2019 Section 14.1.1 Table 52 30 */ 31 enum ptp_tlv_type { 32 PTP_TLV_TYPE_MANAGEMENT = 1, 33 PTP_TLV_TYPE_MANAGEMENT_ERROR_STATUS, 34 PTP_TLV_TYPE_ORGANIZATION_EXTENSION, 35 PTP_TLV_TYPE_REQUEST_UNICAST_TRANSMISSION, 36 PTP_TLV_TYPE_GRANT_UNICAST_TRANSMISSION, 37 PTP_TLV_TYPE_CANCEL_UNICAST_TRANSMISSION, 38 PTP_TLV_TYPE_ACKNOWLEDGE_CANCEL_UNICAST_TRANSMISSION, 39 PTP_TLV_TYPE_PATH_TRACE, 40 PTP_TLV_TYPE_ORGANIZATION_EXTENSION_PROPAGATE = 0x4000, 41 PTP_TLV_TYPE_ENHANCED_ACCURACY_METRICS, 42 PTP_TLV_TYPE_ORGANIZATION_EXTENSION_DO_NOT_PROPAGATE = 0x8000, 43 PTP_TLV_TYPE_L1_SYNC, 44 PTP_TLV_TYPE_PORT_COMMUNICATION_AVAILABILITY, 45 PTP_TLV_TYPE_PROTOCOL_ADDRESS, 46 PTP_TLV_TYPE_TIME_RECEIVER_RX_SYNC_TIMING_DATA, 47 PTP_TLV_TYPE_TIME_RECEIVER_RX_SYNC_COMPUTED_DATA, 48 PTP_TLV_TYPE_TIME_RECEIVER_TX_EVENT_TIMESTAMPS, 49 PTP_TLV_TYPE_CUMULATIVE_RATE_RATIO, 50 PTP_TLV_TYPE_PAD, 51 PTP_TLV_TYPE_AUTHENTICATION, 52 }; 53 54 /** 55 * @brief PTP management message action field 56 * 57 * @note based on IEEE 1588-2019 Section 15.4.1.6 Table 57 58 */ 59 enum ptp_mgmt_op { 60 PTP_MGMT_GET, 61 PTP_MGMT_SET, 62 PTP_MGMT_RESP, 63 PTP_MGMT_CMD, 64 PTP_MGMT_ACK, 65 }; 66 67 /** 68 * @brief PTP management message ID 69 * 70 * @note based on IEEE 1588-2019 Section 15.5.2.3 Table 59 71 */ 72 enum ptp_mgmt_id { 73 PTP_MGMT_NULL_PTP_MANAGEMENT = 0x0, 74 PTP_MGMT_CLOCK_DESCRIPTION, 75 PTP_MGMT_USER_DESCRIPTION, 76 PTP_MGMT_SAVE_IN_NON_VOLATILE_STORAGE, 77 PTP_MGMT_RESET_NON_VOLATILE_STORAGE, 78 PTP_MGMT_INITIALIZE, 79 PTP_MGMT_FAULT_LOG, 80 PTP_MGMT_FAULT_LOG_RESET, 81 PTP_MGMT_DEFAULT_DATA_SET = 0x2000, 82 PTP_MGMT_CURRENT_DATA_SET, 83 PTP_MGMT_PARENT_DATA_SET, 84 PTP_MGMT_TIME_PROPERTIES_DATA_SET, 85 PTP_MGMT_PORT_DATA_SET, 86 PTP_MGMT_PRIORITY1, 87 PTP_MGMT_PRIORITY2, 88 PTP_MGMT_DOMAIN, 89 PTP_MGMT_TIME_RECEIVER_ONLY, 90 PTP_MGMT_LOG_ANNOUNCE_INTERVAL, 91 PTP_MGMT_ANNOUNCE_RECEIPT_TIMEOUT, 92 PTP_MGMT_LOG_SYNC_INTERVAL, 93 PTP_MGMT_VERSION_NUMBER, 94 PTP_MGMT_ENABLE_PORT, 95 PTP_MGMT_DISABLE_PORT, 96 PTP_MGMT_TIME, 97 PTP_MGMT_CLOCK_ACCURACY, 98 PTP_MGMT_UTC_PROPERTIES, 99 PTP_MGMT_TRACEBILITY_PROPERTIES, 100 PTP_MGMT_TIMESCALE_PROPERTIES, 101 PTP_MGMT_UNICAST_NEGOTIATION_ENABLE, 102 PTP_MGMT_PATH_TRACE_LIST, 103 PTP_MGMT_PATH_TRACE_ENABLE, 104 PTP_MGMT_GRANDMASTER_CLUSTER_TABLE, 105 PTP_MGMT_UNICAST_TIME_TRANSMITTER_TABLE, 106 PTP_MGMT_UNICAST_TIME_TRANSMITTER_MAX_TABLE_SIZE, 107 PTP_MGMT_ACCEPTABLE_TIME_TRANSMITTER_TABLE, 108 PTP_MGMT_ACCEPTABLE_TIME_TRANSMITTER_TABLE_ENABLED, 109 PTP_MGMT_ACCEPTABLE_TIME_TRANSMITTER_MAX_TABLE_SIZE, 110 PTP_MGMT_ALTERNATE_TIME_TRANSMITTER, 111 PTP_MGMT_ALTERNATE_TIME_OFFSET_ENABLE, 112 PTP_MGMT_ALTERNATE_TIME_OFFSET_NAME, 113 PTP_MGMT_ALTERNATE_TIME_OFFSET_MAX_KEY, 114 PTP_MGMT_ALTERNATE_TIME_OFFSET_PROPERTIES, 115 PTP_MGMT_EXTERNAL_PORT_CONFIGURATION_ENABLED = 0x3000, 116 PTP_MGMT_TIME_TRANSMITTER_ONLY, 117 PTP_MGMT_HOLDOVER_UPGRADE_ENABLE, 118 PTP_MGMT_EXT_PORT_CONFIG_PORT_DATA_SET, 119 PTP_MGMT_TRANSPARENT_CLOCK_DEFAULT_DATA_SET = 0x4000, 120 PTP_MGMT_TRANSPARENT_CLOCK_PORT_DATA_SET, 121 PTP_MGMT_PRIMARY_DOMAIN, 122 PTP_MGMT_DELAY_MECHANISM = 0x6000, 123 PTP_MGMT_LOG_MIN_PDELAY_REQ_INTERVAL, 124 }; 125 126 /** 127 * @brief Management error ID 128 * 129 * @note based on IEEE 1588-2019 Section 15.5.4.4 Table 109 130 */ 131 enum ptp_mgmt_err { 132 PTP_MGMT_ERR_RESPONSE_TOO_BIG = 0x1, 133 PTP_MGMT_ERR_NO_SUCH_ID, 134 PTP_MGMT_ERR_WRONG_LENGTH, 135 PTP_MGMT_ERR_WRONG_VALUE, 136 PTP_MGMT_ERR_NOT_SETABLE, 137 PTP_MGMT_ERR_NOT_SUPPORTED, 138 PTP_MGMT_ERR_UNPOPULATED, 139 PTP_MGMT_ERR_GENERAL = 0xFFFE, 140 }; 141 142 /** 143 * @brief PAD TLV - used to increase length of any PTP message. 144 * 145 * @note 14.4.2 - PAD TLV 146 */ 147 struct ptp_tlv_pad { 148 /** Identify type of TLV. */ 149 uint16_t type; 150 /** Length of pad. */ 151 uint16_t length; 152 /** Pad. */ 153 uint8_t pad[]; 154 } __packed; 155 156 /** 157 * @brief Management TLV. 158 * 159 * @note 15.5.2 - MANAGEMENT TLV field format. 160 */ 161 struct ptp_tlv_mgmt { 162 uint16_t type; 163 uint16_t length; 164 uint16_t id; 165 uint8_t data[]; 166 } __packed; 167 168 /** 169 * @brief Management error status TLV. 170 * 171 * @note 15.5.4 - MANAGEMENT_ERROR_STATUS TLV format. 172 */ 173 struct ptp_tlv_mgmt_err { 174 /** Type of TLV, shall be MANAGEMENT_ERROR_STATUS. */ 175 uint16_t type; 176 /** Length of following part of TLV. */ 177 uint16_t length; 178 /** Management error ID*/ 179 uint16_t err_id; 180 /** Management ID corresponding to the ID of management TLV that caused an error. */ 181 uint16_t id; 182 /** @cond INTERNAL_HIDEN */ 183 /** Padding. */ 184 uint32_t reserved; 185 /** @endcond */ 186 /** Optional text field to provide human-readable explanation of the error. */ 187 struct ptp_text display_data; 188 } __packed; 189 190 /** 191 * @brief Structure holding pointers for Clock description send over TLV 192 */ 193 struct ptp_tlv_mgmt_clock_desc { 194 /** Type of PTP Clock. */ 195 uint16_t *type; 196 /** Physical Layer Protocol. */ 197 struct ptp_text *phy_protocol; 198 /** Number of bytes in phy_addr field. */ 199 uint16_t *phy_addr_len; 200 /** Physical address of the PTP Port. */ 201 uint8_t *phy_addr; 202 /** Protocol address of the PTP Port. */ 203 struct ptp_port_addr *protocol_addr; 204 /** Unique identifier of the manufacturer. */ 205 uint8_t *manufacturer_id; 206 /** Description of the PTP Instance from manufacturer. */ 207 struct ptp_text *product_desc; 208 /** Revision for components of the PTP Instance. */ 209 struct ptp_text *revision_data; 210 /** User defined description. */ 211 struct ptp_text *user_desc; 212 /** PTP Profile implemented by the PTP Port. */ 213 uint8_t *profile_id; 214 }; 215 216 /** 217 * @brief Structure holding TLV. It is used as a helper to retrieve TLVs from PTP messages. 218 */ 219 struct ptp_tlv_container { 220 /** Object list. */ 221 sys_snode_t node; 222 /** Pointer to the TLV. */ 223 struct ptp_tlv *tlv; 224 /** Structure holding pointers for Clock description. */ 225 struct ptp_tlv_mgmt_clock_desc clock_desc; 226 }; 227 228 /** 229 * @brief TLV data fields representing defaultDS dataset. 230 */ 231 struct ptp_tlv_default_ds { 232 /** Value of two-step flag and @ref ptp_default_ds.time_receiver_only of the dataset. */ 233 uint8_t flags; 234 /** @cond INTERNAL_HIDEN */ 235 /** Padding. */ 236 uint8_t reserved1; 237 /** @endcond */ 238 /** Value of @ref ptp_default_ds.n_ports of the dataset. */ 239 uint16_t n_ports; 240 /** Value of @ref ptp_default_ds.priority1 of the dataset. */ 241 uint8_t priority1; 242 /** Value of @ref ptp_default_ds.clk_quality of the dataset. */ 243 struct ptp_clk_quality clk_quality; 244 /** Value of @ref ptp_default_ds.priority2 of the dataset. */ 245 uint8_t priority2; 246 /** Value of @ref ptp_default_ds.clk_id of the dataset. */ 247 ptp_clk_id clk_id; 248 /** Value of @ref ptp_default_ds.domain of the dataset. */ 249 uint8_t domain; 250 /** @cond INTERNAL_HIDEN */ 251 /** Padding. */ 252 uint8_t reserved2; 253 /** @endcond */ 254 } __packed; 255 256 /** 257 * @bref TLV data fields representing currentDS dataset. 258 */ 259 struct ptp_tlv_current_ds { 260 /** Value of @ref ptp_current_ds.steps_rm of the dataset. */ 261 uint16_t steps_rm; 262 /** Value of @ref ptp_current_ds.offset_from_tt of the dataset. */ 263 ptp_timeinterval offset_from_tt; 264 /** Value of @ref ptp_current_ds.mean_delay of the dataset. */ 265 ptp_timeinterval mean_delay; 266 } __packed; 267 268 /** 269 * @brief TLV data fields representing parentDS dataset. 270 */ 271 struct ptp_tlv_parent_ds { 272 /** Value of @ref ptp_parent_ds.port_id of the dataset. */ 273 struct ptp_port_id port_id; 274 /** Value of @ref ptp_parent_ds.stats of the dataset. */ 275 uint8_t flags; 276 /** @cond INTERNAL_HIDEN */ 277 /** Padding. */ 278 uint8_t reserved; 279 /** @endcond */ 280 /** Value of @ref ptp_parent_ds.obsreved_parent_offset_scaled_log_variance 281 * of the dataset. 282 */ 283 uint16_t obsreved_parent_offset_scaled_log_variance; 284 /** Value of @ref ptp_parent_ds.obsreved_parent_clk_phase_change_rate of the dataset. */ 285 int32_t obsreved_parent_clk_phase_change_rate; 286 /** Value of @ref ptp_parent_ds.gm_priority1 of the dataset. */ 287 uint8_t gm_priority1; 288 /** Value of @ref ptp_parent_ds.gm_clk_quality of the dataset. */ 289 struct ptp_clk_quality gm_clk_quality; 290 /** Value of @ref ptp_parent_ds.gm_priority2 of the dataset. */ 291 uint8_t gm_priority2; 292 /** Value of @ref ptp_parent_ds.gm_id of the dataset. */ 293 ptp_clk_id gm_id; 294 } __packed; 295 296 /** 297 * @brief TLV data fields representing time_propertiesDS dataset. 298 */ 299 struct ptp_tlv_time_prop_ds { 300 /** Value of @ref ptp_time_prop_ds.current_utc_offset of the dataset. */ 301 int16_t current_utc_offset; 302 /** Value of @ref ptp_time_prop_ds.flags of the dataset. */ 303 uint8_t flags; 304 /** Value of @ref ptp_time_prop_ds.time_src of the dataset. */ 305 uint8_t time_src; 306 } __packed; 307 308 /** 309 * @brief TLV data fields representing portDS dataset. 310 */ 311 struct ptp_tlv_port_ds { 312 /** Value of @ref ptp_port_ds.id of the dataset. */ 313 struct ptp_port_id id; 314 /** Value of @ref ptp_port_ds.state of the dataset. */ 315 uint8_t state; 316 /** Value of @ref ptp_port_ds.log_min_delay_req_interval of the dataset. */ 317 int8_t log_min_delay_req_interval; 318 /** Value of @ref ptp_port_ds.mean_link_delay of the dataset. */ 319 ptp_timeinterval mean_link_delay; 320 /** Value of @ref ptp_port_ds.log_announce_interval of the dataset. */ 321 int8_t log_announce_interval; 322 /** Value of @ref ptp_port_ds.announce_receipt_timeout of the dataset. */ 323 uint8_t announce_receipt_timeout; 324 /** Value of @ref ptp_port_ds.log_sync_interval of the dataset. */ 325 int8_t log_sync_interval; 326 /** Value of @ref ptp_port_ds.delay_mechanism of the dataset. */ 327 uint8_t delay_mechanism; 328 /** Value of @ref ptp_port_ds.log_min_pdelay_req_interval of the dataset. */ 329 int8_t log_min_pdelay_req_interval; 330 /** Value of @ref ptp_port_ds.version of the dataset. */ 331 uint8_t version; 332 } __packed; 333 334 /** 335 * @brief Function allocating memory for TLV container structure. 336 * 337 * @return Pointer to the TLV container structure. 338 */ 339 struct ptp_tlv_container *ptp_tlv_alloc(void); 340 341 /** 342 * @brief Function freeing memory used by TLV container. 343 * 344 * @param[in] tlv_container Pointer to the TLV container structure. 345 */ 346 void ptp_tlv_free(struct ptp_tlv_container *tlv_container); 347 348 /** 349 * @brief Function for getting type of action to be taken on receipt of the PTP message. 350 * 351 * @param[in] msg Pointer to the PTP message. 352 * 353 * @return Type of action to be taken. 354 */ 355 enum ptp_mgmt_op ptp_mgmt_action(struct ptp_msg *msg); 356 357 /** 358 * @brief Function for getting type of the TLV. 359 * 360 * @param[in] tlv Pointer to the TLV. 361 * 362 * @return Type of TLV message. 363 */ 364 enum ptp_tlv_type ptp_tlv_type(struct ptp_tlv *tlv); 365 366 /** 367 * @brief Function processing TLV after reception, and before processing by PTP stack. 368 * 369 * @param[in] tlv Pointer to the received TLV. 370 * 371 * @return Zero on success, otherwise negative. 372 */ 373 int ptp_tlv_post_recv(struct ptp_tlv *tlv); 374 375 /** 376 * @brief Function preparing TLV to on-wire format before transmitting. 377 * 378 * @param[in] tlv Pointer to the received TLV. 379 */ 380 void ptp_tlv_pre_send(struct ptp_tlv *tlv); 381 382 #ifdef __cplusplus 383 } 384 #endif 385 386 /** 387 * @} 388 */ 389 390 #endif /* ZEPHYR_INCLUDE_PTP_TLV_H_ */ 391