1 /*
2 * Copyright 2021-2022 NXP
3 *
4 * SPDX-License-Identifier: BSD-3-Clause
5 */
6
7 #ifndef FSL_NETC_SI_H_
8 #define FSL_NETC_SI_H_
9
10 #include "fsl_netc.h"
11 #include "netc_hw/fsl_netc_hw.h"
12
13 /*******************************************************************************
14 * Definitions
15 ******************************************************************************/
16
17 #if !(defined(__GNUC__) || defined(__ICCARM__))
18 #pragma region netc_hw_si
19 #endif
20 /*!
21 * @addtogroup netc_hw_si
22 * @{
23 */
24
25 /*! @name Control and status bit masks of the transmit buffer descriptor. */
26 /*! @{ */
27 /*! @brief Defines for read format. */
28 #define NETC_SI_TXDESCRIP_RD_TXSTART(n) ((uint32_t)(n)&0x1fffffUL)
29 #define NETC_SI_TXDESCRIP_RD_DR(n) (((uint32_t)(n)&0x3U) << 10U)
30 #define NETC_SI_TXDESCRIP_RD_IPV(n) (((uint32_t)(n)&0x7U) << 12U)
31 #define NETC_SI_TXDESCRIP_RD_PORT(n) (((uint32_t)(n)&0x1fU) << 16U)
32 #define NETC_SI_TXDESCRIP_RD_TSR_MASK (1UL << 22U)
33 #define NETC_SI_TXDESCRIP_RD_SMSO_MASK (1UL << 23U)
34 #define NETC_SI_TXDESCRIP_RD_FLQ(n) (((uint32_t)(n)&0x03U) << 24U)
35 #define NETC_SI_TXDESCRIP_RD_TSE_MASK (1UL << 25U)
36 #define NETC_SI_TXDESCRIP_RD_FL(n) (((uint32_t)(n)&0x03U) << 27U)
37 /*! @} */
38
39 /*!
40 * @brief ENETC Station Interface BD Ring priority enumeration
41 *
42 */
43 typedef enum _enetc_si_bdr_priority
44 {
45 kNETC_SIBdrPriorityLowest = 0U,
46 kNETC_SIBdrPriority0 = 0U,
47 kNETC_SIBdrPriority1,
48 kNETC_SIBdrPriority2,
49 kNETC_SIBdrPriority3,
50 kNETC_SIBdrPriority4,
51 kNETC_SIBdrPriority5,
52 kNETC_SIBdrPriority6,
53 kNETC_SIBdrPriority7 = 7U,
54 kNETC_SIBdrPriorityHighest = kNETC_SIBdrPriority7,
55 } enetc_si_bdr_priority_t;
56
57 /*! @} */ // end of netc_hw_si
58 #if !(defined(__GNUC__) || defined(__ICCARM__))
59 #pragma endregion netc_hw_si
60 #endif
61
62 #if defined(__cplusplus)
63 extern "C" {
64 #endif
65
66 /*******************************************************************************
67 * API
68 ******************************************************************************/
69
70 #if !(defined(__GNUC__) || defined(__ICCARM__))
71 #pragma region netc_hw_si
72 #endif
73 /*!
74 * @addtogroup netc_hw_si
75 * @{
76 */
77
78 /*!
79 * @brief Enable the Station Interface(SI)
80 *
81 * @param base
82 */
NETC_SIEnable(ENETC_SI_Type * base,bool enable)83 static inline void NETC_SIEnable(ENETC_SI_Type *base, bool enable)
84 {
85 if (enable)
86 {
87 base->SIMR |= ENETC_SI_SIMR_EN_MASK;
88 }
89 else
90 {
91 base->SIMR &= ~ENETC_SI_SIMR_EN_MASK;
92 }
93 }
94
95 /*!
96 * @brief Enable the specified Rx BD ring
97 *
98 * @param base
99 * @param ring The ring index.
100 * @param base Enable/Disable the ring.
101 */
NETC_SIRxRingEnable(ENETC_SI_Type * base,uint8_t ring,bool enable)102 static inline void NETC_SIRxRingEnable(ENETC_SI_Type *base, uint8_t ring, bool enable)
103 {
104 if (enable)
105 {
106 base->BDR[ring].RBMR |= ENETC_SI_RBMR_EN_MASK;
107 }
108 else
109 {
110 base->BDR[ring].RBMR &= ~ENETC_SI_RBMR_EN_MASK;
111 }
112 }
113
114 /*!
115 * @brief Enable/Disable unicast/multicast/boardcast promisc mode for specified SI
116 *
117 * @param base
118 * @param type
119 * @param enable
120 */
NETC_SIEnablePromisc(ENETC_SI_Type * base,netc_packet_type_t type,bool enable)121 static inline void NETC_SIEnablePromisc(ENETC_SI_Type *base, netc_packet_type_t type, bool enable)
122 {
123 if (enable)
124 {
125 base->SIMR |= ((uint32_t)1U << ((uint32_t)type + 1U));
126 }
127 else
128 {
129 base->SIMR &= ~((uint32_t)1U << ((uint32_t)type + 1U));
130 }
131 }
132
133 /*!
134 * @brief Set producer index of specified Tx BD ring
135 *
136 * @param base SI base address.
137 * @param ring BD ring index.
138 * @param producer The producer index of specified ring.
139 */
NETC_SISetTxProducer(ENETC_SI_Type * base,uint8_t ring,uint16_t producer)140 static inline void NETC_SISetTxProducer(ENETC_SI_Type *base, uint8_t ring, uint16_t producer)
141 {
142 base->BDR[ring].TBPIR = producer;
143 }
144
145 /*!
146 * @brief Get consumer index of specified Tx BD ring
147 *
148 * @param base SI base address.
149 * @param ring BD ring index.
150 * @return consumer The consumer index of specified ring.
151 */
NETC_SIGetTxConsumer(ENETC_SI_Type * base,uint8_t ring)152 static inline uint16_t NETC_SIGetTxConsumer(ENETC_SI_Type *base, uint8_t ring)
153 {
154 return (uint16_t)base->BDR[ring].TBCIR;
155 }
156
157 /*!
158 * @brief Set consumer index of specified Rx BD ring
159 *
160 * @param base SI base address.
161 * @param ring BD ring index.
162 * @param consumer The consumer index of specified ring.
163 */
NETC_SISetRxConsumer(ENETC_SI_Type * base,uint8_t ring,uint16_t consumer)164 static inline void NETC_SISetRxConsumer(ENETC_SI_Type *base, uint8_t ring, uint16_t consumer)
165 {
166 base->BDR[ring].RBCIR = consumer;
167 }
168
169 /*!
170 * @brief Get producer index of specified Rx BD ring
171 *
172 * @param base SI base address.
173 * @param ring BD ring index.
174 * @return producer The producer index of specified ring.
175 */
NETC_SIGetRxProducer(ENETC_SI_Type * base,uint8_t ring)176 static inline uint16_t NETC_SIGetRxProducer(ENETC_SI_Type *base, uint8_t ring)
177 {
178 return (uint16_t)base->BDR[ring].RBPIR;
179 }
180
181 /*!
182 * @brief Configure the Transmit Buffer Descriptor Ring for specified SI
183 *
184 * @param base SI base address.
185 * @param ring BD ring index.
186 * @param bdrConfig The BD ring configuration.
187 * @return status_t
188 */
189 status_t NETC_SIConfigTxBDR(ENETC_SI_Type *base, uint8_t ring, const netc_tx_bdr_config_t *bdrConfig);
190
191 /*!
192 * @brief Configure the Rx Buffer Descriptor Ring for specified SI
193 *
194 * @param base SI base address.
195 * @param ring BD ring index.
196 * @param bdrConfig The BD ring configuration.
197 * @return status_t
198 */
199 status_t NETC_SIConfigRxBDR(ENETC_SI_Type *base, uint8_t ring, const netc_rx_bdr_config_t *bdrConfig);
200
201 /*!
202 * @brief Enable the mapping of VLAN to IPV
203 *
204 * @param base SI base address.
205 * @param pcpDei The VLAN tag pcp dei value (use NETC_VLAN_PCP_DEI_VALUE macro).
206 * @param ipv The IPV value for this VLAN mapping.
207 */
NETC_SIMapVlanToIpv(ENETC_SI_Type * base,uint8_t pcpDei,uint8_t ipv)208 static inline void NETC_SIMapVlanToIpv(ENETC_SI_Type *base, uint8_t pcpDei, uint8_t ipv)
209 {
210 if (pcpDei <= 7U)
211 {
212 base->SIVLANIPVMR0 |= ENETC_SI_SIVLANIPVMR0_PCP_DEI_0(ipv) << (pcpDei * 4U);
213 }
214 else
215 {
216 pcpDei -= 8U;
217 base->SIVLANIPVMR1 |= ENETC_SI_SIVLANIPVMR1_PCP_DEI_8(ipv) << (pcpDei * 4U);
218 }
219 }
220 /*!
221 * @brief Enable the mapping of VLAN to IPV
222 *
223 * @param base SI base address.
224 * @param enable Whether enable mapping.
225 * @return status_t
226 */
NETC_SIEnableVlanToIpv(ENETC_SI_Type * base,bool enable)227 static inline void NETC_SIEnableVlanToIpv(ENETC_SI_Type *base, bool enable)
228 {
229 if (enable)
230 {
231 base->SIMR |= ENETC_SI_SIMR_V2IPVE_MASK;
232 }
233 else
234 {
235 base->SIMR &= ~ENETC_SI_SIMR_V2IPVE_MASK;
236 }
237 }
238
239 /*!
240 * @brief Set the IPV to ring mapping
241 *
242 * @param base SI base address.
243 * @param ipv IPV value to be mapped.
244 * @param ring The Rx BD ring index to be mapped.
245 * @return status_t
246 */
NETC_SIMapIpvToRing(ENETC_SI_Type * base,uint8_t ipv,uint8_t ring)247 static inline void NETC_SIMapIpvToRing(ENETC_SI_Type *base, uint8_t ipv, uint8_t ring)
248 {
249 base->SIIPVBDRMR0 |= ENETC_SI_SIIPVBDRMR0_IPV0BDR(ring) << (ipv * 4U);
250 }
251
252 /*!
253 * @brief Set the group of Rx BD ring
254 *
255 * @param base SI base address.
256 * @param groupNum Total group number.
257 * @param ringPerGroup Rings per group.
258 * @return status_t
259 */
NETC_SISetRxBDRGroup(ENETC_SI_Type * base,uint8_t groupNum,uint8_t ringPerGroup)260 static inline void NETC_SISetRxBDRGroup(ENETC_SI_Type *base, uint8_t groupNum, uint8_t ringPerGroup)
261 {
262 /* Rings per group should be > 0. */
263 assert(ringPerGroup != 0U);
264
265 base->SIRBGCR =
266 ENETC_SI_SIRBGCR_NUM_GROUPS(groupNum) | ENETC_SI_SIRBGCR_RINGS_PER_GROUP((uint32_t)ringPerGroup - 1U);
267 }
268
269 /*!
270 * @brief Set the default used receive Rx BD ring group.
271 * @note The IPV mapped ring index is the relative index inside the default used group.
272 *
273 * @param base SI base address.
274 * @param groupNum The default Rx group index.
275 * @return status_t
276 */
NETC_SISetDefaultRxBDRGroup(ENETC_SI_Type * base,netc_hw_enetc_si_rxr_group groupIdx)277 static inline void NETC_SISetDefaultRxBDRGroup(ENETC_SI_Type *base, netc_hw_enetc_si_rxr_group groupIdx)
278 {
279 base->SIMR = (base->SIMR & (~ENETC_SI_SIMR_DEFAULT_RX_GROUP_MASK)) | ENETC_SI_SIMR_DEFAULT_RX_GROUP(groupIdx);
280 }
281
282 /*!
283 * @brief Clean the SI transmit interrupt flags
284 *
285 * @param base SI base address.
286 * @param txFrameIntrMask IPV value to be mapped, bit x represents ring x.
287 * @param txThresIntrMask The Rx BD ring index to be mapped, bit x represents ring x.
288 */
NETC_SICleanTxIntrFlags(ENETC_SI_Type * base,uint16_t txFrameIntrMask,uint16_t txThresIntrMask)289 static inline void NETC_SICleanTxIntrFlags(ENETC_SI_Type *base, uint16_t txFrameIntrMask, uint16_t txThresIntrMask)
290 {
291 base->SITXIDR0 = ((uint32_t)txFrameIntrMask << 16U) + txThresIntrMask;
292 }
293
294 /*!
295 * @brief Clean the SI receive interrupt flags
296 *
297 * @param base SI base address.
298 * @param rxIntrMask Rx interrupt bit mask, bit x represents ring x.
299 */
NETC_SICleanRxIntrFlags(ENETC_SI_Type * base,uint32_t rxIntrMask)300 static inline void NETC_SICleanRxIntrFlags(ENETC_SI_Type *base, uint32_t rxIntrMask)
301 {
302 base->SIRXIDR0 = rxIntrMask;
303 }
304
305 /*!
306 * @brief PSI enables/disables specified interrupt
307 *
308 * @param base SI base address.
309 * @param mask The interrupt mask, refer to #netc_psi_msg_flags_t which should be OR'd together.
310 * @param enable Enable/Disable the interrupt.
311 */
312 void NETC_SIPsiEnableInterrupt(ENETC_SI_Type *base, uint32_t mask, bool enable);
313
314 /*!
315 * @brief PSI gets interrupt event flag status
316 *
317 * @param base SI base address.
318 * @return The interrupt mask, refer to #netc_psi_msg_flags_t which should be OR'd together.
319 */
NETC_SIPsiGetStatus(ENETC_SI_Type * base)320 static inline uint32_t NETC_SIPsiGetStatus(ENETC_SI_Type *base)
321 {
322 return (base->PSI.PSIIDR & 0xFFFEFFFEU);
323 }
324
325 /*!
326 * @brief PSI clears interrupt event flag
327 *
328 * @param base SI base address.
329 * @param mask The interrupt mask, refer to #netc_psi_msg_flags_t which should be OR'd together.
330 */
NETC_SIPsiClearStatus(ENETC_SI_Type * base,uint32_t mask)331 static inline void NETC_SIPsiClearStatus(ENETC_SI_Type *base, uint32_t mask)
332 {
333 base->PSI.PSIIDR = mask;
334 }
335
336 /*!
337 * @brief PSI sends message to specified VSI(s)
338 *
339 * @param base SI base address.
340 * @param msg The message to be sent.
341 * @param vsi The VSI number.
342 * @return status_t
343 */
344 status_t NETC_SIPsiSendMsg(ENETC_SI_Type *base, uint16_t msg, netc_vsi_number_t vsi);
345
346 /*!
347 * @brief PSI checks Tx busy flag which should be cleaned when VSI receive the message data
348 *
349 * @param base SI base address.
350 * @param vsi The VSI number.
351 * @return The busy status of specified VSI.
352 */
NETC_SIPsiCheckTxBusy(ENETC_SI_Type * base,netc_vsi_number_t vsi)353 static inline bool NETC_SIPsiCheckTxBusy(ENETC_SI_Type *base, netc_vsi_number_t vsi)
354 {
355 return ((base->PSI_A.PSIMSGSR & (uint32_t)vsi) != 0U);
356 }
357
358 /*!
359 * @brief PSI sets Rx buffer to receive message from specified VSI
360 * @note The buffer memory size should be big enough for the message data from VSI
361 *
362 * @param base SI base address.
363 * @param vsi The VSI number.
364 * @param buffAddr The buffer address to store message data from VSI, must be 64 bytes aligned.
365 * @return status_t
366 */
367 status_t NETC_SIPsiSetRxBuffer(ENETC_SI_Type *base, netc_vsi_number_t vsi, uint64_t buffAddr);
368
369 /*!
370 * @brief PSI gets Rx message from specified VSI
371 *
372 * @param base SI base address.
373 * @param vsi The VSI number.
374 * @param msgInfo The Rx message information.
375 */
376 status_t NETC_SIPsiGetRxMsg(ENETC_SI_Type *base, netc_vsi_number_t vsi, netc_psi_rx_msg_t *msgInfo);
377
378 /*!
379 * @brief Enable VSI interrupt
380 *
381 * @param base SI base address.
382 * @param mask The interrupt mask, see #netc_vsi_msg_flags_t which should be OR'd together.
383 * @param enable Enable/Disable interrupt.
384 */
385 void NETC_SIVsiEnableInterrupt(ENETC_SI_Type *base, uint32_t mask, bool enable);
386
387 /*!
388 * @brief Get VSI interrupt status
389 *
390 * @param base SI base address.
391 * @return A bitmask composed of #netc_vsi_msg_flags_t enumerators OR'd together.
392 */
NETC_SIVsiGetStatus(ENETC_SI_Type * base)393 static inline uint32_t NETC_SIVsiGetStatus(ENETC_SI_Type *base)
394 {
395 return ((base->VSI.VSIIDR & (ENETC_SI_VSIIDR_MS_MASK | ENETC_SI_VSIIDR_MR_MASK)) >> 8U);
396 }
397
398 /*!
399 * @brief Clear VSI interrupt status
400 *
401 * @param base SI base address.
402 * @param mask The interrupt mask, see #netc_vsi_msg_flags_t which should be OR'd together.
403 */
NETC_SIVsiClearStatus(ENETC_SI_Type * base,uint32_t mask)404 static inline void NETC_SIVsiClearStatus(ENETC_SI_Type *base, uint32_t mask)
405 {
406 base->VSI.VSIIDR = mask << 8U;
407 }
408
409 /*!
410 * @brief VSI sends message to PSI
411 *
412 * @param base SI base address.
413 * @param msgAddr Address to store message ready to be sent, must be 64 bytes aligned.
414 * @param msgLen The message length, must be 32 bytes aligned.
415 * @return status_t
416 */
417 status_t NETC_SIVsiSendMsg(ENETC_SI_Type *base, uint64_t msgAddr, uint32_t msgLen);
418
419 /*!
420 * @brief Check VSI Tx status
421 *
422 * @param base SI base address.
423 * @param status The VSI Tx status structure.
424 */
425 void NETC_SIVsiCheckTxStatus(ENETC_SI_Type *base, netc_vsi_msg_tx_status_t *status);
426
427 /*!
428 * @brief VSI receives message from PSI
429 *
430 * @param base SI base address.
431 * @param msg The message from PSI.
432 * @return status_t
433 */
434 status_t NETC_SIVsiReceiveMsg(ENETC_SI_Type *base, uint16_t *msg);
435
436 /*!
437 * @brief Get the discard statistic from SI layer
438 *
439 * @param base SI base address.
440 * @param statistic The statistic data.
441 */
442 void NETC_SIGetDiscardStatistic(ENETC_SI_Type *base, netc_si_discard_statistic_t *statistic);
443
444 /*!
445 * @brief Get the traffic statistic from SI layer
446 *
447 * @param base SI base address.
448 * @param statistic The statistic data.
449 */
450 void NETC_SIGetTrafficStatistic(ENETC_SI_Type *base, netc_si_traffic_statistic_t *statistic);
451
452 /*! @} */ // end of netc_hw_si
453 #if !(defined(__GNUC__) || defined(__ICCARM__))
454 #pragma endregion netc_hw_si
455 #endif
456
457 #if defined(__cplusplus)
458 }
459 #endif
460 #endif /* FSL_NETC_SI_H_ */
461