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