1 /***************************************************************************
2  * Copyright (c) 2024 Microsoft Corporation
3  *
4  * This program and the accompanying materials are made available under the
5  * terms of the MIT License which is available at
6  * https://opensource.org/licenses/MIT.
7  *
8  * SPDX-License-Identifier: MIT
9  **************************************************************************/
10 
11 
12 /**************************************************************************/
13 /**************************************************************************/
14 /**                                                                       */
15 /** NetX Component                                                        */
16 /**                                                                       */
17 /**   Multiple Registration Protocol (MRP)                                */
18 /**                                                                       */
19 /**************************************************************************/
20 /**************************************************************************/
21 
22 
23 /**************************************************************************/
24 /*                                                                        */
25 /*  COMPONENT DEFINITION                                   RELEASE        */
26 /*                                                                        */
27 /*    nx_mrp.h                                               Generic      */
28 /*                                                           6.4.0        */
29 /*  AUTHOR                                                                */
30 /*                                                                        */
31 /*    Yajun Xia, Microsoft Corporation                                    */
32 /*                                                                        */
33 /*  DESCRIPTION                                                           */
34 /*                                                                        */
35 /*    This file defines the NetX TSN MRP component.                       */
36 /*                                                                        */
37 /*  RELEASE HISTORY                                                       */
38 /*                                                                        */
39 /*    DATE              NAME                      DESCRIPTION             */
40 /*                                                                        */
41 /*  12-31-2023     Yajun Xia               Initial Version 6.4.0          */
42 /*                                                                        */
43 /**************************************************************************/
44 
45 #ifndef _NX_MRP_H_
46 #define _NX_MRP_H_
47 
48 /* Determine if a C++ compiler is being used.  If so, ensure that standard
49    C is used to process the API information.  */
50 #ifdef __cplusplus
51 
52 /* Yes, C++ compiler is present.  Use standard C.  */
53 extern   "C" {
54 
55 #endif
56 
57 #include "nx_api.h"
58 #include "nx_link.h"
59 #include "tx_timer.h"
60 #include "tx_port.h"
61 
62 /* Define shaper constants. */
63 
64 /* Event input for FSM */
65 #define NX_MRP_EVENT_RNEW                       (0) /* Receive New message (10.7.5.14) */
66 #define NX_MRP_EVENT_RJOININ                    (1) /* Receive JoinIn message (10.7.5.15) */
67 #define NX_MRP_EVENT_RIN                        (2) /* Receive In message (10.7.5.18) */
68 #define NX_MRP_EVENT_RJOINMT                    (3) /* Receive JoinEmpty message (10.7.5.16) */
69 #define NX_MRP_EVENT_RMT                        (4) /* Receive Empty message (10.7.5.19) */
70 #define NX_MRP_EVENT_RLV                        (5) /* Receive Leave message (10.7.5.17) */
71 #define NX_MRP_EVENT_RLA                        (6) /* Receive a LeaveAll message (10.7.5.20) */
72 #define NX_MRP_EVENT_BEGIN                      (7) /* Initialize state machine (10.7.5.1) */
73 #define NX_MRP_EVENT_NEW                        (8) /* A new declaration (10.7.5.4) */
74 #define NX_MRP_EVENT_JOIN                       (9) /* Declaration without signaling new registration (10.7.5.5) */
75 #define NX_MRP_EVENT_LV                         (10)/* Withdraw a declaration (10.7.5.6) */
76 #define NX_MRP_EVENT_TX                         (11)/* Transmission opportunity without a LeaveAll (10.7.5.7) */
77 #define NX_MRP_EVENT_TXLA                       (12)/* Transmission opportunity with a LeaveAll (10.7.5.8) */
78 #define NX_MRP_EVENT_TXLAF                      (13)/* Transmission opportunity with a LeaveAll, and with no room (Full) (10.7.5.9) */
79 #define NX_MRP_EVENT_FLUSH                      (14)/* Port role changes from Root Port or Alternate Port to Designated Port (10.7.5.2) */
80 #define NX_MRP_EVENT_REDECLARE                  (15)/* Port role changes from Designated to Root Port or Alternate Port (10.7.5.3) */
81 #define NX_MRP_EVENT_PERIODIC                   (16)/* A periodic transmission event occurs (10.7.5.10) */
82 #define NX_MRP_EVENT_LEAVETIMER                 (17)/* Leavetimer has expired (10.7.5.21) */
83 #define NX_MRP_EVENT_LEAVEALLTIMER              (18)/* Leavealltimer! leavealltimer has expired. (10.7.5.22) */
84 #define NX_MRP_EVENT_PERIODICTIMER              (19)/* Periodictimer has expired. (10.7.5.23) */
85 #define NX_MRP_EVENT_PERIODICENABLED            (20)/* Periodic Transmission state machine has been enabled */
86 #define NX_MRP_EVENT_PERIODICDISABLED           (21)/* Periodic Transmission state machine has been disabled */
87 
88 /* State definition */
89 #define NX_MRP_APPLICANT_STATE_VO               (0) /* Very anxious Observer */
90 #define NX_MRP_APPLICANT_STATE_VP               (1) /* Very anxious Passive */
91 #define NX_MRP_APPLICANT_STATE_VN               (2) /* Very anxious New */
92 #define NX_MRP_APPLICANT_STATE_AN               (3) /* Anxious New */
93 #define NX_MRP_APPLICANT_STATE_AA               (4) /* Anxious Active */
94 #define NX_MRP_APPLICANT_STATE_QA               (5) /* Quiet Active */
95 #define NX_MRP_APPLICANT_STATE_LA               (6) /* Leaving Active */
96 #define NX_MRP_APPLICANT_STATE_AO               (7) /* Anxious Observer */
97 #define NX_MRP_APPLICANT_STATE_QO               (8) /* Quiet Observer */
98 #define NX_MRP_APPLICANT_STATE_AP               (9) /* Anxious Passive */
99 #define NX_MRP_APPLICANT_STATE_QP               (10)/* Quiet Passive */
100 #define NX_MRP_APPLICANT_STATE_LO               (11)/* Leaving Observer */
101 #define NX_MRP_REGISTRAR_STATE_IN               (12)/* In */
102 #define NX_MRP_REGISTRAR_STATE_LV               (13)/* Leaving */
103 #define NX_MRP_REGISTRAR_STATE_MT               (14)/* Empty */
104 #define NX_MRP_LA_STATE_ACTIVE                  (15)/* LeaveAll state Active */
105 #define NX_MRP_LA_STATE_PASSIVE                 (16)/* LeaveAll state Passive */
106 #define NX_MRP_PT_STATE_ACTIVE                  (17)/* PeriodicTransmission state Active */
107 #define NX_MRP_PT_STATE_PASSIVE                 (18)/* PeriodicTransmission state Passive */
108 
109 /* Action definition */
110 #define NX_MRP_ACTION_NULL                      (0)
111 #define NX_MRP_ACTION_SN                        (1)
112 #define NX_MRP_ACTION_SJ                        (2)
113 #define NX_MRP_ACTION_SJ_OPT                    (3)
114 #define NX_MRP_ACTION_SL                        (4)
115 #define NX_MRP_ACTION_S                         (5)
116 #define NX_MRP_ACTION_S_OPT                     (6)
117 #define NX_MRP_ACTION_SLA                       (7)
118 #define NX_MRP_ACTION_PERIODIC                  (8)
119 #define NX_MRP_ACTION_START_LEAVETIMER          (9)
120 #define NX_MRP_ACTION_STOP_LEAVETIMER           (10)
121 #define NX_MRP_ACTION_START_LEAVEALLTIMER       (11)
122 #define NX_MRP_ACTION_START_PERIODICTIMER       (12)
123 
124 /* Timer definition */
125 #define NX_MRP_TIMER_JOIN                       (200)   /* msec */
126 #define NX_MRP_TIMER_LEAVE                      (1000)  /* range 600-1000 msec */
127 #define NX_MRP_TIMER_LEAVEALL                   (10000) /* msec */
128 #define NX_MRP_TIMER_PERIODIC                   (1000)  /* The Periodic Transmission timer is set to one second when it is started */
129 #define NX_MRP_TIMEOUT_INTERVAL                 (200)   /* msec */
130 
131 #define NX_MRP_TIMER_TICKS_PER_SECOND           (20)    /* tick: 200 ms */
132 
133 /* Attribute event in attribute */
134 #define NX_MRP_ATTRIBUTE_EVENT_NEW              (0)
135 #define NX_MRP_ATTRIBUTE_EVENT_JOININ           (1)
136 #define NX_MRP_ATTRIBUTE_EVENT_IN               (2)
137 #define NX_MRP_ATTRIBUTE_EVENT_JOINMT           (3)
138 #define NX_MRP_ATTRIBUTE_EVENT_MT               (4)
139 #define NX_MRP_ATTRIBUTE_EVENT_LV               (5)
140 
141 #define NX_MRP_INDICATION_NULL                  (0)
142 #define NX_MRP_INDICATION_NEW                   (NX_MRP_EVENT_NEW)
143 #define NX_MRP_INDICATION_JOIN                  (NX_MRP_EVENT_JOIN)
144 #define NX_MRP_INDICATION_LV                    (NX_MRP_EVENT_LV)
145 #define NX_MRP_INDICATION_EVICT                 (30)
146 
147 #define NX_MRP_PARTICIPANT_MSRP                 (NX_LINK_ETHERNET_MSRP)
148 #define NX_MRP_PARTICIPANT_MMRP                 (NX_LINK_ETHERNET_MMRP)
149 #define NX_MRP_PARTICIPANT_MVRP                 (NX_LINK_ETHERNET_MVRP)
150 
151 #define NX_MRP_MRP_ETH_MULTICAST_ADDR_MSB       (0x0180)
152 #define NX_MRP_MSRP_ETH_MULTICAST_ADDR_LSB      (0xC200000E)
153 #define NX_MRP_MMRP_ETH_MULTICAST_ADDR_LSB      (0xC2000020)
154 #define NX_MRP_MVRP_ETH_MULTICAST_ADDR_LSB      (0xC2000021)
155 
156 #define NX_MRP_DEFAULT_OPER_P2P_MAC             (0)
157 
158 #define NX_MRP_RX_EVENT                         (0x00000001u)
159 #define NX_MRP_TIMER_EVENT                      (0x00000002u)
160 #define NX_MRP_ALL_EVENTS                       (0xFFFFFFFFu) /* All event flags. */
161 
162 /* MRP structure.  */
163 typedef struct NX_MRP_PERIODIC_TRANSMISSION_STRUCT
164 {
165     UCHAR state;
166     UCHAR reserved[3];
167 } NX_MRP_PERIODIC_TRANSMISSION;
168 
169 typedef struct NX_MRP_LEAVEALL_STRUCT
170 {
171     UCHAR state;
172     UCHAR action;
173     UCHAR reserved[2];
174 } NX_MRP_LEAVEALL;
175 
176 /* Attribute struct */
177 typedef struct NX_MRP_ATTRIBUTE_APPLICANT_STRUCT
178 {
179     UCHAR state;      /* applicant state */
180     UCHAR action;     /* attribute event value would be encapsulated in next msg */
181     UCHAR reserved[2];
182 } NX_MRP_ATTRIBUTE_APPLICANT;
183 
184 typedef struct NX_MRP_ATTRIBUTE_REGISTRAR_STRUCT
185 {
186     UCHAR state;     /* registrar state */
187     UCHAR reserved[3];
188 } NX_MRP_ATTRIBUTE_REGISTRAR;
189 
190 typedef struct NX_MRP_ATTRIBUTE_STRUCT
191 {
192     UCHAR                           attribute_type;
193     UCHAR                           in_use;
194     UCHAR                           reserved[2];
195     UINT                            leave_timer; /* leave timer is per attribute, when created, the timeout function with param (pointer to attribute) need to be registered */
196     NX_MRP_ATTRIBUTE_APPLICANT      applicant;
197     NX_MRP_ATTRIBUTE_REGISTRAR      registrar;
198     struct NX_MRP_ATTRIBUTE_STRUCT *pre;
199     struct NX_MRP_ATTRIBUTE_STRUCT *next;
200 } NX_MRP_ATTRIBUTE;
201 
202 struct NX_MRP_PARTICIPANT_STRUCT;
203 
204 struct NX_MRP_STRUCT;
205 
206 typedef UINT (*NX_MRP_INDICATION)(struct NX_MRP_STRUCT *mrp, struct NX_MRP_PARTICIPANT_STRUCT *participant, NX_MRP_ATTRIBUTE *attribute, UCHAR indication_type);
207 typedef UINT (*NX_MRP_RX_PACKET_PROCESS)(struct NX_MRP_STRUCT *mrp, struct NX_MRP_PARTICIPANT_STRUCT *participant, NX_PACKET *packet);
208 typedef UINT (*NX_MRP_TX_PACKET_PROCESS)(struct NX_MRP_STRUCT *mrp, struct NX_MRP_PARTICIPANT_STRUCT *participant, NX_PACKET *packet);     /* TBD, interface consideration */
209 
210 /* Participant struct */
211 typedef struct NX_MRP_PARTICIPANT_STRUCT
212 {
213     UINT                              participant_type; /* MVRP/MSRP/MMRP */
214     UINT                              join_timer;
215     UINT                              leaveall_timer;
216     NX_MRP_LEAVEALL                   leaveall;
217     NX_MRP_INDICATION                 indication_function;
218     NX_MRP_RX_PACKET_PROCESS          unpack_function; /* inform participant to pack */
219     NX_MRP_TX_PACKET_PROCESS          pack_function;   /* inform participant to pack */
220     struct NX_MRP_PARTICIPANT_STRUCT *next;            /* participant list */
221     NX_MRP_ATTRIBUTE                 *inused_head;     /* attribute list */
222     UCHAR                            *buffer;          /* save the attribute array pointer */
223     USHORT                            buffer_size;     /* save the attribute array size */
224     UCHAR                             protocol_version;
225     UCHAR                             reserved;
226 } NX_MRP_PARTICIPANT;
227 
228 typedef struct NX_MRP_STRUCT
229 {
230     NX_MRP_PARTICIPANT   *list_head;
231     UINT                  periodic_timer;       /* periodic timer is per port */
232     TX_TIMER              mrp_timer;            /* Main timer expires for each 100ms */
233     TX_THREAD             mrp_thread;
234     NX_LINK_RECEIVE_QUEUE receive_queue;        /* need to insert the packet into list and trigger event in related callback function */
235     NX_PACKET            *received_packet_head; /* new added, need to be discussed*/
236     NX_PACKET            *received_packet_tail;
237     NX_PACKET_POOL       *pkt_pool;             /* Pool used for send packet */
238     TX_EVENT_FLAGS_GROUP  mrp_events;           /* packet event and timer event, the timeout function just set the event flag of timeout */
239     TX_MUTEX              mrp_mutex;
240     NX_IP                *ip_ptr;
241     UINT                  interface_index;
242     UCHAR                 oper_p2p_mac; /* operPointToPointMAC */
243     UCHAR                 reserved[3];
244 } NX_MRP;
245 
246 UINT nx_mrp_applicant_event_process(NX_MRP *mrp, NX_MRP_PARTICIPANT *participant, NX_MRP_ATTRIBUTE *attribute, UCHAR mrp_event);
247 UINT nx_mrp_registrar_event_process(NX_MRP *mrp, NX_MRP_PARTICIPANT *participant, NX_MRP_ATTRIBUTE *attribute, UCHAR mrp_event);
248 UINT nx_mrp_leaveall_event_process(NX_MRP_PARTICIPANT *participant, UCHAR mrp_event);
249 NX_MRP_ATTRIBUTE *nx_mrp_attribute_new(NX_MRP *mrp, NX_MRP_PARTICIPANT *participant,
250                                        NX_MRP_ATTRIBUTE *attribute_array, UINT unit_size,
251                                        UINT unit_number);
252 UINT nx_mrp_attribute_evict(NX_MRP *mrp, NX_MRP_PARTICIPANT *participant, NX_MRP_ATTRIBUTE *target);
253 UINT nx_mrp_ethernet_receive_notify(NX_IP *ip_ptr, UINT interface_index, NX_PACKET *packet_ptr,
254                                     ULONG physical_address_msw, ULONG physical_address_lsw,
255                                     UINT packet_type, UINT header_size, VOID *context,
256                                     struct NX_LINK_TIME_STRUCT *time_ptr);
257 UINT nx_mrp_participant_add(NX_MRP *mrp, NX_MRP_PARTICIPANT *participant);
258 UINT nx_mrp_init(NX_MRP *mrp, NX_IP *ip_ptr, UINT interface_index, NX_PACKET_POOL *pkt_pool_ptr,
259                  CHAR *thread_name, VOID *stack_ptr, ULONG stack_size, UINT priority);
260 
261 UINT nx_mrp_event_process(NX_MRP *mrp, NX_MRP_PARTICIPANT *participant, NX_MRP_ATTRIBUTE *attribute, UCHAR mrp_event);
262 UINT nx_mrp_attribute_event_get(NX_MRP_ATTRIBUTE *attribute, UCHAR *event_ptr);
263 void nx_mrp_rcv_pkt_process(NX_MRP *mrp);
264 void nx_mrp_periodic_timeout_process(NX_MRP *mrp);
265 void nx_mrp_join_timeout_process(NX_MRP *mrp);
266 void nx_mrp_leaveall_timeout_process(NX_MRP *mrp);
267 void nx_mrp_leave_timeout_process(NX_MRP *mrp);
268 void nx_mrp_timeout_process(NX_MRP *mrp);
269 void nx_mrp_thread_entry(ULONG mrp_instance);
270 void nx_mrp_timer_handle(ULONG mrp_instance);
271 
272 NX_MRP_PARTICIPANT *nx_mrp_participant_search(NX_MRP *mrp, UINT participant_type);
273 
274 /* Determine if a C++ compiler is being used.  If so, complete the standard
275    C conditional started above.  */
276 #ifdef __cplusplus
277 }
278 #endif
279 
280 #endif /* _NX_MRP_H_ */
281 
282