Skip to content

Commit f7ea70a

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

8 files changed

+536
-0
lines changed

doc/SyncE/SAI-Proposal-SyncE.md

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

doc/SyncE/SyncE_hardware_diagram.jpg

75.9 KB
Loading

inc/sai.h

+2
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

+7
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

+18
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)