Skip to content

Commit 5d0b0cc

Browse files
committed
SAI proposal for SyncE
Signed-off-by: rpmarvell <rperumal@marvell.com>
1 parent ee6f49b commit 5d0b0cc

8 files changed

Lines changed: 537 additions & 0 deletions

File tree

doc/SyncE/SAI-Proposal-SyncE.md

Lines changed: 320 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,320 @@
1+
# [SAI] Synchronous Ethernet
2+
-------------------------------------------------------------------------------
3+
Title | Synchronous Ethernet
4+
-------------|-----------------------------------------------------------------
5+
Authors | Rajesh Perumal, Dhruvkumar Patel, Ravindranath C K (Marvell)
6+
Status | In review
7+
Type | Standards track
8+
Created | 2025-02-20
9+
SAI-Version | 1.16
10+
-------------------------------------------------------------------------------
11+
12+
## 1.0 Introduction
13+
14+
The aim of the Synchronous Ethernet(SyncE) is to transfer timing(frequency) over the Ethernet physical layer across a network.
15+
SyncE synchronizes the system clock(which drives the tx frequency) at the Switch device. The switch NPU can have one or more
16+
SyncE clocks. The SyncE clocks recover the frequency from any port of the switch and inputs it to the system clock.
17+
SyncE relies on Ethernet port, System clock, the recovered clock signal from SyncE clock and
18+
the quality of recovered clock signal. SyncE clock programming (recovery of the clock signal to the System clock) and
19+
the SSM for SyncE(quality signalling) are focused in this proposal.
20+
21+
## 2.0 Behavior
22+
23+
### SyncE clock object
24+
25+
![SyncE Clocks](SyncE_hardware_diagram.jpg)
26+
27+
SyncE clock and an Ethernet port needs to be associated to setup the the clock source for the associated SyncE clock object.
28+
The recovered clock signal will be fed to the System clock. System clock drives the Ethernet Tx(frequency) with the help of
29+
these SyncE clock sources. SyncE clock has the following attributes : clock-status, clock-hardware-id and clock-src-port.
30+
31+
32+
```mermaid
33+
classDiagram
34+
class SYNCE_CLOCK {
35+
- src_port
36+
- clock_hardware_id
37+
- clock_valid
38+
- clock_force_valid
39+
}
40+
41+
class PORT {
42+
- ...
43+
}
44+
45+
class SWITCH {
46+
- port_list
47+
- synce_clock_list [proposed]
48+
}
49+
50+
51+
%% Relationships
52+
SWITCH --> SYNCE_CLOCK : synce_clock_list
53+
SWITCH --> PORT : port_list
54+
PORT <-- SYNCE_CLOCK : src_port
55+
56+
style PORT fill:#bbf,stroke:#f66,stroke-width:2px,color:green;
57+
style SWITCH fill:#bbf,stroke:#f66,stroke-width:2px,color:green;
58+
59+
```
60+
61+
### SSM over ESMC for SyncE
62+
SyncE relies on quality of recovered clock which needs to be communicated through synchronization status message(SSM) over the
63+
Ethernet synchronization messaging channel(ESMC). To trap the SSM PDUs, new Hostif trap is added.
64+
65+
## 3.0 SAI Enhancement
66+
67+
### 1. New object type for SyncE clock
68+
69+
```c
70+
SAI_OBJECT_TYPE_SYNCE_CLOCK = 114,
71+
```
72+
73+
74+
```c
75+
/**
76+
* @brief Enum defining SyncE attributes.
77+
*/
78+
typedef enum _sai_synce_clock_attr_t
79+
{
80+
/**
81+
* @brief Start of attributes
82+
*/
83+
SAI_SYNCE_CLOCK_ATTR_START = 0x00000000,
84+
/**
85+
* @brief Synchronous ethernet(SyncE) clock source port
86+
*
87+
* Sets the Port to be the source for SyncE
88+
*
89+
* @type sai_object_id_t
90+
* @objects SAI_OBJECT_TYPE_PORT
91+
* @allownull true
92+
* @flags CREATE_AND_SET
93+
* @default SAI_NULL_OBJECT_ID
94+
*/
95+
SAI_SYNCE_CLOCK_ATTR_SRC_PORT = SAI_SYNCE_CLOCK_ATTR_START,
96+
97+
/**
98+
* @brief Synchronous ethernet (SyncE) clock status
99+
*
100+
* Gets recovered clock signal with respect to hardware
101+
* (valid only after attaching the clock to a clock source port)
102+
*
103+
* @type bool
104+
* @flags READ_ONLY
105+
*/
106+
SAI_SYNCE_CLOCK_ATTR_CLOCK_VALID,
107+
108+
/**
109+
* @brief Hardware clock-id
110+
*
111+
* Returns the hardware clock-id associated
112+
*
113+
* @type sai_uint32_t
114+
* @flags READ_ONLY
115+
*/
116+
SAI_SYNCE_CLOCK_ATTR_CLOCK_HARDWARE_ID,
117+
118+
/**
119+
* @brief Synchronous ethernet (SYNCE) clock status
120+
*
121+
* Force set the recovered clock signal state (for debugging)
122+
*
123+
* @type sai_synce_recovered_clock_state_t
124+
* @flags CREATE_AND_SET
125+
* @default SAI_SYNCE_RECOVERED_CLOCK_STATE_FORCE_VALID_DISABLE
126+
*/
127+
SAI_SYNCE_CLOCK_ATTR_DEBUG_FORCE_SYNCE_RECOVERED_CLOCK_STATE,
128+
129+
/**
130+
* @brief End of attributes
131+
*/
132+
SAI_SYNCE_CLOCK_ATTR_END,
133+
/** Custom range base value */
134+
SAI_SYNCE_CLOCK_ATTR_CUSTOM_RANGE_START = 0x10000000,
135+
136+
/** End of custom range base */
137+
SAI_SYNCE_CLOCK_ATTR_CUSTOM_RANGE_END
138+
139+
} sai_synce_clock_attr_t;
140+
141+
/**
142+
* @brief Attribute data for #SAI_SYNCE_CLOCK_ATTR_DEBUG_FORCE_SYNCE_RECOVERED_CLOCK_STATE
143+
*/
144+
typedef enum _sai_synce_recovered_clock_state_t
145+
{
146+
/** Valid signal set as per device fault status */
147+
SAI_SYNCE_RECOVERED_CLOCK_STATE_FORCE_VALID_DISABLE,
148+
149+
/** Valid signal forced to valid */
150+
SAI_SYNCE_RECOVERED_CLOCK_STATE_FORCE_ENABLE_VALID,
151+
152+
/** Valid signal forced to invalid */
153+
SAI_SYNCE_RECOVERED_CLOCK_STATE_FORCE_ENABLE_INVALID,
154+
155+
} sai_synce_recovered_clock_state_t;
156+
157+
158+
/**
159+
* @brief Create SyncE clock
160+
*
161+
* @param[out] synce_id SyncE clock id
162+
* @param[in] switch_id The Switch id
163+
* @param[in] attr_count Number of attributes
164+
* @param[in] attr_list Array of attributes
165+
*
166+
* @return #SAI_STATUS_SUCCESS on success, failure status code on error
167+
*/
168+
typedef sai_status_t (*sai_create_synce_clock_fn)(
169+
_Out_ sai_object_id_t *synce_clock_id,
170+
_In_ sai_object_id_t switch_id,
171+
_In_ uint32_t attr_count,
172+
_In_ const sai_attribute_t *attr_list);
173+
174+
/**
175+
* @brief Remove SyncE clock
176+
*
177+
* @param[in] synce_id SyncE clock id
178+
*
179+
* @return #SAI_STATUS_SUCCESS on success, failure status code on error
180+
*/
181+
typedef sai_status_t (*sai_remove_synce_clock_fn)(
182+
_In_ sai_object_id_t synce_clock_id);
183+
184+
/**
185+
* @brief Set SyncE clock Attribute
186+
*
187+
* @param[in] synce_id SyncE clock id
188+
* @param[in] attr Attribute to set
189+
*
190+
* @return #SAI_STATUS_SUCCESS on success, failure status code on error
191+
*/
192+
typedef sai_status_t (*sai_set_synce_clock_attribute_fn)(
193+
_In_ sai_object_id_t synce_clock_id,
194+
_In_ const sai_attribute_t *attr);
195+
196+
/**
197+
* @brief Get SyncE clock attribute
198+
*
199+
* @param[in] synce_id SyncE clock id
200+
* @param[in] attr_count Number of attributes
201+
* @param[inout] attr_list Array of attributes
202+
*
203+
* @return #SAI_STATUS_SUCCESS on success, failure status code on error
204+
*/
205+
typedef sai_status_t (*sai_get_synce_clock_attribute_fn)(
206+
_In_ sai_object_id_t synce_clock_id,
207+
_In_ uint32_t attr_count,
208+
_Inout_ sai_attribute_t *attr_list);
209+
```
210+
211+
### 2. New hostif trap for SSM over ESMC PDUs
212+
213+
```c
214+
/**
215+
* @brief ITU-T G.8264/Y.1364 Ethernet synchronization messaging channel (ESMC) protocol
216+
* (Dst Mac = 01-80-C2-00-00-02 EtherType = 0x8809 Slow Protocol Subtype = 0xA)
217+
* (default packet action is drop)
218+
*/
219+
SAI_HOSTIF_TRAP_TYPE_ESMC = 0x00000014,
220+
```
221+
222+
### 3. Switch attributes for SyncE clock
223+
```c
224+
/**
225+
* @brief Maximum number of SyncE clocks supported
226+
*
227+
* @type sai_uint32_t
228+
* @flags READ_ONLY
229+
*/
230+
SAI_SWITCH_ATTR_MAX_SYNCE_CLOCK_COUNT,
231+
232+
/**
233+
*
234+
*@brief List of SyncE clock objects on the Switch
235+
*
236+
*@type sai_object_list_t
237+
*@flags READ_ONLY
238+
*@objects SAI_OBJECT_TYPE_SYNCE_CLOCK
239+
*@default internal
240+
*/
241+
SAI_SWITCH_ATTR_SYNCE_CLOCK_LIST,
242+
```
243+
244+
## 4.0 API Example
245+
246+
The API workflow is as given below,
247+
1. Get the maximum number of available SyncE clocks from the switch
248+
2. Get the list of available SyncE clocks from the switch
249+
3. Update the clock source by associating an Ethernet port to the SyncE clock object
250+
4. Update the clock source by updating the port at SyncE clock object​
251+
5. Remove the clock source by setting NULL oid to SyncE clock object
252+
6. Get and set SyncE clock object
253+
7. Remove the SyncE clock object
254+
255+
### 1. Get the maximum SyncE-clock objects present at the switch​
256+
257+
```c
258+
attr_count = 0;​
259+
attr_list[attr_count++].id = SAI_SWITCH_ATTR_MAX_SYNCE_CLOCK_COUNT;​
260+
sai_get_switch_attribute_fn(switch_id, attr_count, attr_list) ;​
261+
synce_clocks_count = attr_list[0].value.u32;
262+
```
263+
### 2. Get the list of SyncE-clock objects present at the switch​
264+
```c
265+
attr_count = 0;​
266+
attr_clock_list[attr_count].id = SAI_SWITCH_ATTR_SYNCE_CLOCK_LIST;​
267+
attr_clock_list[attr_count].value.objlist.count = synce_clocks_count;
268+
attr_clock_list[attr_count++].value.objlist.list = malloc(synce_clocks_count * sizeof(sai_object_id_t))
269+
sai_get_switch_attribute_fn(switch_id, attr_count, attr_clock_list) ;​
270+
```
271+
### 3. Associate a port to the SyncE-clock object to make it a clock source​
272+
```c
273+
attr_count = 0;​
274+
attr_list[attr_count].id = SAI_SYNCE_CLOCK_ATTR_SRC_PORT ;​
275+
attr_list[attr_count++].value.oid = port_oid;​
276+
277+
sai_object_t synce_clock0_oid = attr_clock_list[0].value.oid;​
278+
279+
sai_set_synce_clock_attribute_fn(synce_clock0_oid, switch_oid, attr_count, attr_list) ;
280+
```
281+
282+
### 4. Update the clock source by updating the port at SyncE clock object​
283+
284+
```c
285+
synce_attr.id = SAI_SYNCE_CLOCK_ATTR_SRC_PORT;​
286+
synce_attr.value.oid = new_port_oid;​
287+
sai_set_synce_clock_attribute_fn (synce_clock0_oid, synce_attr);
288+
```
289+
290+
### 5. Remove a port from clock source by setting NULL oid to SyncE object​
291+
292+
```c
293+
synce_attr.id = SAI_SYNCE_CLOCK_ATTR_SRC_PORT;​
294+
synce_attr.value.oid = SAI_NULL_OBJECT_ID;​
295+
sai_set_synce_clock_attribute_fn (synce_clock0_oid, synce_attr) ;​
296+
```
297+
298+
### 6. Getting/Setting SyncE-clock attributes
299+
```c
300+
/** Get Synce-clock */​
301+
302+
attr_count = 0;​
303+
304+
attr_list[attr_count++].id = SAI_SYNCE_CLOCK_ATTR_CLOCK_VALID;​
305+
attr_list[attr_count++].id = SAI_SYNCE_CLOCK_ATTR_CLOCK_HARDWARE_ID;​
306+
sai_get_synce_clock_attribute_fn (synce_clock0_oid, attr_count, attr_list);​
307+
308+
309+
/** Set Synce-clock state by force */​
310+
synce_clock_attr.id = SAI_SYNCE_CLOCK_ATTR_DEBUG_FORCE_CLOCK_STATE;​
311+
synce_clock_attr.value.u32 = SAI_SYNCE_CLOCK_FORCE_ENABLE_VALID;​
312+
313+
sai_set_synce_clock_attribute_fn (synce_clock0_oid, synce_clock_attr);​
314+
```
315+
### 7. Removing a SyncE clock object
316+
317+
```c
318+
/** Remove SyncE-clock*/
319+
sai_remove_synce_clock_fn (synce_clock0_oid) ;​
320+
```
75.9 KB
Loading

inc/sai.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -81,6 +81,7 @@
8181
#include "saiversion.h"
8282
#include "saipoe.h"
8383
#include "saiicmpecho.h"
84+
#include "saisynce.h"
8485

8586
/**
8687
* @defgroup SAI SAI - Entry point specific API definitions.
@@ -151,6 +152,7 @@ typedef enum _sai_api_t
151152
SAI_API_POE = 51, /**< sai_poe_api_t */
152153
SAI_API_ICMP_ECHO = 52, /**< sai_icmp_echo_api_t */
153154
SAI_API_PREFIX_COMPRESSION = 53, /**< sai_prefix_compression_api_t */
155+
SAI_API_SYNCE = 54, /**< sai_synce_api_t */
154156
SAI_API_MAX, /**< total number of APIs */
155157

156158
/**

inc/saihostif.h

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -251,6 +251,13 @@ typedef enum _sai_hostif_trap_type_t
251251
*/
252252
SAI_HOSTIF_TRAP_TYPE_DHCPV6_L2 = 0x00000013,
253253

254+
/**
255+
* @brief ITU-T G.8264/Y.1364 Ethernet synchronization messaging channel protocol
256+
* (Dst MAC = 01-80-C2-00-00-02 EtherType = 0x8809 Slow Protocol sub-type = 0xA)
257+
* (default packet action is drop)
258+
*/
259+
SAI_HOSTIF_TRAP_TYPE_ESMC = 0x00000014,
260+
254261
/** Switch traps custom range start */
255262
SAI_HOSTIF_TRAP_TYPE_SWITCH_CUSTOM_RANGE_BASE = 0x00001000,
256263

inc/saiswitch.h

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3197,6 +3197,24 @@ typedef enum _sai_switch_attr_t
31973197
*/
31983198
SAI_SWITCH_ATTR_SHARED_BUFFER_CELL_SIZE,
31993199

3200+
/**
3201+
* @brief Maximum number of synchronous ethernet clocks supported.
3202+
*
3203+
* @type sai_uint32_t
3204+
* @flags READ_ONLY
3205+
*/
3206+
SAI_SWITCH_ATTR_MAX_SYNCE_CLOCK_COUNT,
3207+
3208+
/**
3209+
* @brief Gets the synchronous ethernet clock object list
3210+
*
3211+
* @type sai_object_list_t
3212+
* @flags READ_ONLY
3213+
* @objects SAI_OBJECT_TYPE_SYNCE_CLOCK
3214+
* @default internal
3215+
*/
3216+
SAI_SWITCH_ATTR_SYNCE_CLOCK_LIST,
3217+
32003218
/**
32013219
* @brief End of attributes
32023220
*/

0 commit comments

Comments
 (0)