1 /**
2   ******************************************************************************
3   * @file    stm32n6xx_hal_eth_ex.c
4   * @author  MCD Application Team
5   * @brief   ETH HAL Extended module driver.
6   *
7   ******************************************************************************
8   * @attention
9   *
10   * Copyright (c) 2023 STMicroelectronics.
11   * All rights reserved.
12   *
13   * This software is licensed under terms that can be found in the LICENSE file
14   * in the root directory of this software component.
15   * If no LICENSE file comes with this software, it is provided AS-IS.
16   *
17   ******************************************************************************
18   */
19 
20 /* Includes ------------------------------------------------------------------*/
21 #include "stm32n6xx_hal.h"
22 
23 /** @addtogroup STM32N6xx_HAL_Driver
24   * @{
25   */
26 
27 #ifdef HAL_ETH_MODULE_ENABLED
28 
29 #if defined(ETH1)
30 
31 /** @defgroup ETHEx ETHEx
32   * @brief ETH HAL Extended module driver
33   * @{
34   */
35 
36 /* Private typedef -----------------------------------------------------------*/
37 /* Private define ------------------------------------------------------------*/
38 /** @defgroup ETHEx_Private_Constants ETHEx Private Constants
39   * @{
40   */
41 #define ETH_MACL4CR_MASK     (ETH_MACL3L4C0R_L4PEN0 | ETH_MACL3L4C0R_L4SPM0 | \
42                               ETH_MACL3L4C0R_L4SPIM0 | ETH_MACL3L4C0R_L4DPM0 | \
43                               ETH_MACL3L4C0R_L4DPIM0)
44 
45 #define ETH_MACL3CR_MASK     (ETH_MACL3L4C0R_L3PEN0 | ETH_MACL3L4C0R_L3SAM0 | \
46                               ETH_MACL3L4C0R_L3SAIM0 | ETH_MACL3L4C0R_L3DAM0 | \
47                               ETH_MACL3L4C0R_L3DAIM0 | ETH_MACL3L4C0R_L3HSBM0 | \
48                               ETH_MACL3L4C0R_L3HDBM0)
49 
50 
51 #define ETH_MACRXVLAN_MASK (ETH_MACVTCR_EIVLRXS | ETH_MACVTCR_EIVLS | \
52                             ETH_MACVTCR_ERIVLT | ETH_MACVTCR_EDVLP | \
53                             ETH_MACVTCR_VTHM | ETH_MACVTCR_EVLRXS | \
54                             ETH_MACVTCR_EVLS | ETH_MACVTCR_DOVLTC | \
55                             ETH_MACVTCR_ERSVLM | ETH_MACVTCR_ESVL | \
56                             ETH_MACVTCR_VTIM | ETH_MACVTCR_ETV)
57 
58 #define ETH_MACTXVLAN_MASK (ETH_MACVIR_VLTI | ETH_MACVIR_CSVL | \
59                             ETH_MACVIR_VLP | ETH_MACVIR_VLC)
60 
61 #define ETH_MACRXQC1R_MASK            0x37F77877U
62 #define ETH_MACRXQCR_MASK             0x00030303U
63 #define ETH_MTLOMR_MASK               0x00000366U
64 #define ETH_MTLTXQxOMR_MASK           0x000F007FU
65 #define ETH_MTLRXQxOMR_MASK           0x00F1C7FBU
66 #define ETH_MACRXQC2R_PSRQ_MASK       0x0000FFFFU
67 #define ETH_MAC_TMRQR_MASK            0x0017FFFFU
68 #define ETH_MAC_IACR_MASK             0x0000FF03U
69 
70 #define ETH_OP_BUSY_TIMEOUT           0x000000FFU
71 
72 #define ETH_MAC_L4_SRSP_MASK          0x0000FFFFU
73 #define ETH_MAC_L4_DSTP_MASK          0xFFFF0000U
74 #ifdef HAL_ETH_USE_TAS
75 #define ETH_MTLESTCR_MASK             0xFFFFF7F2U
76 /* Maximum Width of the time interval in Gate Control List */
77 #define ETH_EST_WID_MAX               (24U)
78 /* Maximum depth of Gate Control List */
79 #define ETH_EST_DEP_MAX               (64U)
80 #endif /* HAL_ETH_USE_TAS */
81 /**
82   * @}
83   */
84 
85 /* Private macros ------------------------------------------------------------*/
86 /* Private function prototypes -----------------------------------------------*/
87 /* Exported functions ---------------------------------------------------------*/
88 /** @defgroup ETHEx_Exported_Functions ETH Extended Exported Functions
89   * @{
90   */
91 
92 /** @defgroup ETHEx_Exported_Functions_Group1 Extended features functions
93   * @brief    Extended features functions
94   *
95 @verbatim
96  ===============================================================================
97                       ##### Extended features functions #####
98  ===============================================================================
99     [..] This section provides functions allowing to:
100       (+) Configure ARP offload module
101       (+) Configure L3 and L4 filters
102       (+) Configure Extended VLAN features
103       (+) Configure Energy Efficient Ethernet module
104       (+) Configure the Ethernet MTL after ETH peripheral initialization
105       (+) HAL_ETHEx_GetMTLConfig(): Get MTL actual configuration into ETH_MTLConfigTypeDef
106       (+) HAL_ETHEx_SetMTLConfig(): Set MTL configuration based on ETH_MTLConfigTypeDef
107       (+) HAL_ETHEx_SetMACMTLMappingConfig(): Set MAC MTL Mapping configuration based on ETH_MACMTLMappingTypeDef
108       (+) HAL_ETHEx_GetMACMTLMappingConfig(): Get MAC MTL Mapping configuration based on ETH_MACMTLMappingTypeDef
109       (+) HAL_ETHEx_SetUserTagPriorityQueue(): Set User Tag Priority Queue
110       (+) HAL_ETHEx_GetUserTagPriorityQueue(): Get User Tag Priority Queue
111       (+) HAL_ETHEx_SetPacketTypeQueue() : Set Packet Type Queueing
112       (+) HAL_ETHEx_GetPacketTypeQueue() : Get Packet Type Queueing
113       (+) HAL_ETHEx_EnableCBS() : Enable Qav "Credit Based Sahper" feature
114       (+) HAL_ETHEx_SetCBSConfig() : Set Credit Based Shaper parameters
115       (+) HAL_ETHEx_GetCBSConfig() : Get Credit Based Shaper parameters
116       (+) HAL_ETHEx_GetGCLDepth() : Get the GCL List depth
117       (+) HAL_ETHEx_GetGCLWidthTimeInterval() : Get the GCL Width Time interval
118       (+) HAL_ETHEx_EnableEST() : Enable Qbv feature
119       (+) HAL_ETHEx_DisableEST() : Disable Qbv "Enhancement Scheduled Traffic" feature
120       (+) HAL_ETHEx_SetESTConfig() : Set Qbv parameters
121       (+) HAL_ETHEx_SetGCLRegisters() : Set Gate Control List registers
122       (+) HAL_ETHEx_SetGCLConfig() : Set Gate Control List configuration
123       (+) HAL_ETHEx_GetGCLRegisters() : Get Gate Control List configuration
124       (+) HAL_ETHEx_EnableFPE() : Enable Qbu "Frame Preemption" feature
125       (+) HAL_ETHEx_DisableFPE() : Disable Qbu "Frame Preemption" feature
126       (+) HAL_ETHEx_GetFPEConfig() : Get Frame Preemption configuration
127       (+) HAL_ETHEx_SetFPEConfig() : Set Frame Preemption configuration
128 
129 @endverbatim
130   * @{
131   */
132 
133 /**
134   * @brief  Enables ARP Offload.
135   * @param  heth: pointer to a ETH_HandleTypeDef structure that contains
136   *         the configuration information for ETHERNET module
137   * @retval None
138   */
139 
HAL_ETHEx_EnableARPOffload(ETH_HandleTypeDef * heth)140 void HAL_ETHEx_EnableARPOffload(ETH_HandleTypeDef *heth)
141 {
142   SET_BIT(heth->Instance->MACCR, ETH_MACCR_ARP);
143 }
144 
145 /**
146   * @brief  Disables ARP Offload.
147   * @param  heth: pointer to a ETH_HandleTypeDef structure that contains
148   *         the configuration information for ETHERNET module
149   * @retval None
150   */
HAL_ETHEx_DisableARPOffload(ETH_HandleTypeDef * heth)151 void HAL_ETHEx_DisableARPOffload(ETH_HandleTypeDef *heth)
152 {
153   CLEAR_BIT(heth->Instance->MACCR, ETH_MACCR_ARP);
154 }
155 
156 /**
157   * @brief  Set the ARP Match IP address
158   * @param  heth: pointer to a ETH_HandleTypeDef structure that contains
159   *         the configuration information for ETHERNET module
160   * @param  IpAddress: IP Address to be matched for incoming ARP requests
161   * @retval None
162   */
HAL_ETHEx_SetARPAddressMatch(ETH_HandleTypeDef * heth,uint32_t IpAddress)163 void HAL_ETHEx_SetARPAddressMatch(ETH_HandleTypeDef *heth, uint32_t IpAddress)
164 {
165   WRITE_REG(heth->Instance->MACARPAR, IpAddress);
166 }
167 
168 /**
169   * @brief  Configures the L4 Filter, this function allow to:
170   *         set the layer 4 protocol to be matched (TCP or UDP)
171   *         enable/disable L4 source/destination port perfect/inverse match.
172   * @param  heth: pointer to a ETH_HandleTypeDef structure that contains
173   *         the configuration information for ETHERNET module
174   * @param  Filter: L4 filter to configured, this parameter must be one of the following
175   *           ETH_L4_FILTER_0
176   *           ETH_L4_FILTER_1
177   * @param  pL4FilterConfig: pointer to a ETH_L4FilterConfigTypeDef structure
178   *         that contains L4 filter configuration.
179   * @retval HAL status
180   */
HAL_ETHEx_SetL4FilterConfig(ETH_HandleTypeDef * heth,uint32_t Filter,const ETH_L4FilterConfigTypeDef * pL4FilterConfig)181 HAL_StatusTypeDef HAL_ETHEx_SetL4FilterConfig(ETH_HandleTypeDef *heth, uint32_t Filter,
182                                               const ETH_L4FilterConfigTypeDef *pL4FilterConfig)
183 {
184   if (pL4FilterConfig == NULL)
185   {
186     return HAL_ERROR;
187   }
188 
189   if (Filter == ETH_L4_FILTER_0)
190   {
191     /* Write configuration to MACL3L4C0R register */
192     MODIFY_REG(heth->Instance->MACL3L4C0R, ETH_MACL4CR_MASK, (pL4FilterConfig->Protocol |
193                                                               pL4FilterConfig->SrcPortFilterMatch |
194                                                               pL4FilterConfig->DestPortFilterMatch));
195 
196     /* Write configuration to MACL4A0R register */
197     WRITE_REG(heth->Instance->MACL4A0R, (pL4FilterConfig->SourcePort | (pL4FilterConfig->DestinationPort << 16)));
198 
199   }
200   else /* Filter == ETH_L4_FILTER_1 */
201   {
202     /* Write configuration to MACL3L4C1R register */
203     MODIFY_REG(heth->Instance->MACL3L4C1R, ETH_MACL4CR_MASK, (pL4FilterConfig->Protocol |
204                                                               pL4FilterConfig->SrcPortFilterMatch |
205                                                               pL4FilterConfig->DestPortFilterMatch));
206 
207     /* Write configuration to MACL4A1R register */
208     WRITE_REG(heth->Instance->MACL4A1R, (pL4FilterConfig->SourcePort | (pL4FilterConfig->DestinationPort << 16)));
209   }
210 
211   /* Enable L4 filter */
212   SET_BIT(heth->Instance->MACPFR, ETH_MACPFR_IPFE);
213 
214   return HAL_OK;
215 }
216 
217 /**
218   * @brief  Configures the L4 Filter, this function allow to:
219   *         set the layer 4 protocol to be matched (TCP or UDP)
220   *         enable/disable L4 source/destination port perfect/inverse match.
221   * @param  heth: pointer to a ETH_HandleTypeDef structure that contains
222   *         the configuration information for ETHERNET module
223   * @param  Filter: L4 filter to configured, this parameter must be one of the following
224   *           ETH_L4_FILTER_0
225   *           ETH_L4_FILTER_1
226   * @param  pL4FilterConfig: pointer to a ETH_L4FilterConfigTypeDef structure
227   *         that contains L4 filter configuration.
228   * @retval HAL status
229   */
HAL_ETHEx_GetL4FilterConfig(const ETH_HandleTypeDef * heth,uint32_t Filter,ETH_L4FilterConfigTypeDef * pL4FilterConfig)230 HAL_StatusTypeDef HAL_ETHEx_GetL4FilterConfig(const ETH_HandleTypeDef *heth, uint32_t Filter,
231                                               ETH_L4FilterConfigTypeDef *pL4FilterConfig)
232 {
233   if (pL4FilterConfig == NULL)
234   {
235     return HAL_ERROR;
236   }
237 
238   if (Filter == ETH_L4_FILTER_0)
239   {
240     /* Get configuration from MACL3L4C0R register */
241     pL4FilterConfig->Protocol = READ_BIT(heth->Instance->MACL3L4C0R, ETH_MACL3L4C0R_L4PEN0);
242     pL4FilterConfig->DestPortFilterMatch = READ_BIT(heth->Instance->MACL3L4C0R,
243                                                     (ETH_MACL3L4C0R_L4DPM0 | ETH_MACL3L4C0R_L4DPIM0));
244     pL4FilterConfig->SrcPortFilterMatch = READ_BIT(heth->Instance->MACL3L4C0R,
245                                                    (ETH_MACL3L4C0R_L4SPM0 | ETH_MACL3L4C0R_L4SPIM0));
246 
247     /* Get configuration from MACL4A0R register */
248     pL4FilterConfig->DestinationPort = (READ_BIT(heth->Instance->MACL4A0R, ETH_MAC_L4_DSTP_MASK) >> 16);
249     pL4FilterConfig->SourcePort = READ_BIT(heth->Instance->MACL4A0R, ETH_MAC_L4_SRSP_MASK);
250   }
251   else /* Filter == ETH_L4_FILTER_1 */
252   {
253     /* Get configuration from MACL3L4C1R register */
254     pL4FilterConfig->Protocol = READ_BIT(heth->Instance->MACL3L4C1R, ETH_MACL3L4C0R_L4PEN0);
255     pL4FilterConfig->DestPortFilterMatch = READ_BIT(heth->Instance->MACL3L4C1R,
256                                                     (ETH_MACL3L4C0R_L4DPM0 | ETH_MACL3L4C0R_L4DPIM0));
257     pL4FilterConfig->SrcPortFilterMatch = READ_BIT(heth->Instance->MACL3L4C1R,
258                                                    (ETH_MACL3L4C0R_L4SPM0 | ETH_MACL3L4C0R_L4SPIM0));
259 
260     /* Get configuration from MACL4A1R register */
261     pL4FilterConfig->DestinationPort = (READ_BIT(heth->Instance->MACL4A1R, ETH_MAC_L4_DSTP_MASK) >> 16);
262     pL4FilterConfig->SourcePort = READ_BIT(heth->Instance->MACL4A1R, ETH_MAC_L4_SRSP_MASK);
263   }
264 
265   return HAL_OK;
266 }
267 
268 /**
269   * @brief  Configures the L3 Filter, this function allow to:
270   *         set the layer 3 protocol to be matched (IPv4 or IPv6)
271   *         enable/disable L3 source/destination port perfect/inverse match.
272   * @param  heth: pointer to a ETH_HandleTypeDef structure that contains
273   *         the configuration information for ETHERNET module
274   * @param  Filter: L3 filter to configured, this parameter must be one of the following
275   *           ETH_L3_FILTER_0
276   *           ETH_L3_FILTER_1
277   * @param  pL3FilterConfig: pointer to a ETH_L3FilterConfigTypeDef structure
278   *         that contains L3 filter configuration.
279   * @retval HAL status
280   */
HAL_ETHEx_SetL3FilterConfig(ETH_HandleTypeDef * heth,uint32_t Filter,const ETH_L3FilterConfigTypeDef * pL3FilterConfig)281 HAL_StatusTypeDef HAL_ETHEx_SetL3FilterConfig(ETH_HandleTypeDef *heth, uint32_t Filter,
282                                               const ETH_L3FilterConfigTypeDef *pL3FilterConfig)
283 {
284   if (pL3FilterConfig == NULL)
285   {
286     return HAL_ERROR;
287   }
288 
289   if (Filter == ETH_L3_FILTER_0)
290   {
291     /* Write configuration to MACL3L4C0R register */
292     MODIFY_REG(heth->Instance->MACL3L4C0R, ETH_MACL3CR_MASK, (pL3FilterConfig->Protocol |
293                                                               pL3FilterConfig->SrcAddrFilterMatch |
294                                                               pL3FilterConfig->DestAddrFilterMatch |
295                                                               (pL3FilterConfig->SrcAddrHigherBitsMatch << 6) |
296                                                               (pL3FilterConfig->DestAddrHigherBitsMatch << 11)));
297   }
298   else  /* Filter == ETH_L3_FILTER_1 */
299   {
300     /* Write configuration to MACL3L4C1R register */
301     MODIFY_REG(heth->Instance->MACL3L4C1R, ETH_MACL3CR_MASK, (pL3FilterConfig->Protocol |
302                                                               pL3FilterConfig->SrcAddrFilterMatch |
303                                                               pL3FilterConfig->DestAddrFilterMatch |
304                                                               (pL3FilterConfig->SrcAddrHigherBitsMatch << 6) |
305                                                               (pL3FilterConfig->DestAddrHigherBitsMatch << 11)));
306   }
307 
308   if (Filter == ETH_L3_FILTER_0)
309   {
310     /* Check if IPv6 protocol is selected */
311     if (pL3FilterConfig->Protocol != ETH_L3_IPV4_MATCH)
312     {
313       /* Set the IPv6 address match */
314       /* Set Bits[31:0] of 128-bit IP addr */
315       WRITE_REG(heth->Instance->MACL3A0R0R, pL3FilterConfig->Ip6Addr[0]);
316       /* Set Bits[63:32] of 128-bit IP addr */
317       WRITE_REG(heth->Instance->MACL3A1R0R, pL3FilterConfig->Ip6Addr[1]);
318       /* update Bits[95:64] of 128-bit IP addr */
319       WRITE_REG(heth->Instance->MACL3A2R0R, pL3FilterConfig->Ip6Addr[2]);
320       /* update Bits[127:96] of 128-bit IP addr */
321       WRITE_REG(heth->Instance->MACL3A3R0R, pL3FilterConfig->Ip6Addr[3]);
322     }
323     else /* IPv4 protocol is selected */
324     {
325       /* Set the IPv4 source address match */
326       WRITE_REG(heth->Instance->MACL3A0R0R, pL3FilterConfig->Ip4SrcAddr);
327       /* Set the IPv4 destination address match */
328       WRITE_REG(heth->Instance->MACL3A1R0R, pL3FilterConfig->Ip4DestAddr);
329     }
330   }
331   else  /* Filter == ETH_L3_FILTER_1 */
332   {
333     /* Check if IPv6 protocol is selected */
334     if (pL3FilterConfig->Protocol != ETH_L3_IPV4_MATCH)
335     {
336       /* Set the IPv6 address match */
337       /* Set Bits[31:0] of 128-bit IP addr */
338       WRITE_REG(heth->Instance->MACL3A01R, pL3FilterConfig->Ip6Addr[0]);
339       /* Set Bits[63:32] of 128-bit IP addr */
340       WRITE_REG(heth->Instance->MACL3A11R, pL3FilterConfig->Ip6Addr[1]);
341       /* update Bits[95:64] of 128-bit IP addr */
342       WRITE_REG(heth->Instance->MACL3A21R, pL3FilterConfig->Ip6Addr[2]);
343       /* update Bits[127:96] of 128-bit IP addr */
344       WRITE_REG(heth->Instance->MACL3A31R, pL3FilterConfig->Ip6Addr[3]);
345     }
346     else /* IPv4 protocol is selected */
347     {
348       /* Set the IPv4 source address match */
349       WRITE_REG(heth->Instance->MACL3A01R, pL3FilterConfig->Ip4SrcAddr);
350       /* Set the IPv4 destination address match */
351       WRITE_REG(heth->Instance->MACL3A11R, pL3FilterConfig->Ip4DestAddr);
352 
353     }
354   }
355 
356   /* Enable L3 filter */
357   SET_BIT(heth->Instance->MACPFR, ETH_MACPFR_IPFE);
358 
359   return HAL_OK;
360 }
361 
362 /**
363   * @brief  Configures the L3 Filter, this function allow to:
364   *         set the layer 3 protocol to be matched (IPv4 or IPv6)
365   *         enable/disable L3 source/destination port perfect/inverse match.
366   * @param  heth: pointer to a ETH_HandleTypeDef structure that contains
367   *         the configuration information for ETHERNET module
368   * @param  Filter: L3 filter to configured, this parameter must be one of the following
369   *           ETH_L3_FILTER_0
370   *           ETH_L3_FILTER_1
371   * @param  pL3FilterConfig: pointer to a ETH_L3FilterConfigTypeDef structure
372   *         that will contain the L3 filter configuration.
373   * @retval HAL status
374   */
HAL_ETHEx_GetL3FilterConfig(const ETH_HandleTypeDef * heth,uint32_t Filter,ETH_L3FilterConfigTypeDef * pL3FilterConfig)375 HAL_StatusTypeDef HAL_ETHEx_GetL3FilterConfig(const ETH_HandleTypeDef *heth, uint32_t Filter,
376                                               ETH_L3FilterConfigTypeDef *pL3FilterConfig)
377 {
378   if (pL3FilterConfig == NULL)
379   {
380     return HAL_ERROR;
381   }
382   pL3FilterConfig->Protocol = READ_BIT(*((__IO uint32_t *)(&(heth->Instance->MACL3L4C0R) + Filter)),
383                                        ETH_MACL3L4C0R_L3PEN0);
384   pL3FilterConfig->SrcAddrFilterMatch = READ_BIT(*((__IO uint32_t *)(&(heth->Instance->MACL3L4C0R) + Filter)),
385                                                  (ETH_MACL3L4C0R_L3SAM0 | ETH_MACL3L4C0R_L3SAIM0));
386   pL3FilterConfig->DestAddrFilterMatch = READ_BIT(*((__IO uint32_t *)(&(heth->Instance->MACL3L4C0R) + Filter)),
387                                                   (ETH_MACL3L4C0R_L3DAM0 | ETH_MACL3L4C0R_L3DAIM0));
388   pL3FilterConfig->SrcAddrHigherBitsMatch = (READ_BIT(*((__IO uint32_t *)(&(heth->Instance->MACL3L4C0R) + Filter)),
389                                                       ETH_MACL3L4C0R_L3HSBM0) >> 6);
390   pL3FilterConfig->DestAddrHigherBitsMatch = (READ_BIT(*((__IO uint32_t *)(&(heth->Instance->MACL3L4C0R) + Filter)),
391                                                        ETH_MACL3L4C0R_L3HDBM0) >> 11);
392 
393   if (Filter == ETH_L3_FILTER_0)
394   {
395     if (pL3FilterConfig->Protocol != ETH_L3_IPV4_MATCH)
396     {
397       WRITE_REG(pL3FilterConfig->Ip6Addr[0], heth->Instance->MACL3A0R0R);
398       WRITE_REG(pL3FilterConfig->Ip6Addr[1], heth->Instance->MACL3A1R0R);
399       WRITE_REG(pL3FilterConfig->Ip6Addr[2], heth->Instance->MACL3A2R0R);
400       WRITE_REG(pL3FilterConfig->Ip6Addr[3], heth->Instance->MACL3A3R0R);
401     }
402     else
403     {
404       WRITE_REG(pL3FilterConfig->Ip4SrcAddr, heth->Instance->MACL3A0R0R);
405       WRITE_REG(pL3FilterConfig->Ip4DestAddr, heth->Instance->MACL3A1R0R);
406     }
407   }
408   else /* ETH_L3_FILTER_1 */
409   {
410     if (pL3FilterConfig->Protocol != ETH_L3_IPV4_MATCH)
411     {
412       WRITE_REG(pL3FilterConfig->Ip6Addr[0], heth->Instance->MACL3A01R);
413       WRITE_REG(pL3FilterConfig->Ip6Addr[1], heth->Instance->MACL3A11R);
414       WRITE_REG(pL3FilterConfig->Ip6Addr[2], heth->Instance->MACL3A21R);
415       WRITE_REG(pL3FilterConfig->Ip6Addr[3], heth->Instance->MACL3A31R);
416     }
417     else
418     {
419       WRITE_REG(pL3FilterConfig->Ip4SrcAddr, heth->Instance->MACL3A01R);
420       WRITE_REG(pL3FilterConfig->Ip4DestAddr, heth->Instance->MACL3A11R);
421     }
422   }
423 
424   return HAL_OK;
425 }
426 
427 /**
428   * @brief  Enables L3 and L4 filtering process.
429   * @param  heth: pointer to a ETH_HandleTypeDef structure that contains
430   *         the configuration information for ETHERNET module
431   * @retval None.
432   */
HAL_ETHEx_EnableL3L4Filtering(ETH_HandleTypeDef * heth)433 void HAL_ETHEx_EnableL3L4Filtering(ETH_HandleTypeDef *heth)
434 {
435   /* Enable L3/L4 filter */
436   SET_BIT(heth->Instance->MACPFR, ETH_MACPFR_IPFE);
437 }
438 
439 /**
440   * @brief  Disables L3 and L4 filtering process.
441   * @param  heth: pointer to a ETH_HandleTypeDef structure that contains
442   *         the configuration information for ETHERNET module
443   * @retval None.
444   */
HAL_ETHEx_DisableL3L4Filtering(ETH_HandleTypeDef * heth)445 void HAL_ETHEx_DisableL3L4Filtering(ETH_HandleTypeDef *heth)
446 {
447   /* Disable L3/L4 filter */
448   CLEAR_BIT(heth->Instance->MACPFR, ETH_MACPFR_IPFE);
449 }
450 
451 /**
452   * @brief  Get the VLAN Configuration for Receive Packets.
453   * @param  heth: pointer to a ETH_HandleTypeDef structure that contains
454   *         the configuration information for ETHERNET module
455   * @param  pVlanConfig: pointer to a ETH_RxVLANConfigTypeDef structure
456   *         that will contain the VLAN filter configuration.
457   * @retval HAL status
458   */
HAL_ETHEx_GetRxVLANConfig(const ETH_HandleTypeDef * heth,ETH_RxVLANConfigTypeDef * pVlanConfig)459 HAL_StatusTypeDef HAL_ETHEx_GetRxVLANConfig(const ETH_HandleTypeDef *heth, ETH_RxVLANConfigTypeDef *pVlanConfig)
460 {
461   if (pVlanConfig == NULL)
462   {
463     return HAL_ERROR;
464   }
465 
466   pVlanConfig->InnerVLANTagInStatus = ((READ_BIT(heth->Instance->MACVTCR,
467                                                  ETH_MACVTCR_EIVLRXS) >> 31) == 0U) ? DISABLE : ENABLE;
468   pVlanConfig->StripInnerVLANTag  = READ_BIT(heth->Instance->MACVTCR, ETH_MACVTCR_EIVLS);
469   pVlanConfig->InnerVLANTag = ((READ_BIT(heth->Instance->MACVTCR, ETH_MACVTCR_ERIVLT) >> 27) == 0U) ? DISABLE : ENABLE;
470   pVlanConfig->DoubleVLANProcessing = ((READ_BIT(heth->Instance->MACVTCR,
471                                                  ETH_MACVTCR_EDVLP) >> 26) == 0U) ? DISABLE : ENABLE;
472   pVlanConfig->VLANTagHashTableMatch = ((READ_BIT(heth->Instance->MACVTCR,
473                                                   ETH_MACVTCR_VTHM) >> 25) == 0U) ? DISABLE : ENABLE;
474   pVlanConfig->VLANTagInStatus = ((READ_BIT(heth->Instance->MACVTCR, ETH_MACVTCR_EVLRXS) >> 24) == 0U)
475                                  ? DISABLE : ENABLE;
476   pVlanConfig->StripVLANTag = READ_BIT(heth->Instance->MACVTCR, ETH_MACVTCR_EVLS);
477   pVlanConfig->VLANTypeCheck = READ_BIT(heth->Instance->MACVTCR,
478                                         (ETH_MACVTCR_DOVLTC | ETH_MACVTCR_ERSVLM | ETH_MACVTCR_ESVL));
479   pVlanConfig->VLANTagInverseMatch = ((READ_BIT(heth->Instance->MACVTCR, ETH_MACVTCR_VTIM) >> 17) == 0U)
480                                      ? DISABLE : ENABLE;
481   pVlanConfig->BitVLANcomparison = ((READ_BIT(heth->Instance->MACVTCR, ETH_MACVTCR_ETV) >> 16) == 0U)
482                                    ? DISABLE : ENABLE;
483   pVlanConfig->VLANTagEnable = ((READ_BIT(heth->Instance->MACVTDR, ETH_MACVTDR_VEN) >> 16) == 0U)
484                                ? DISABLE : ENABLE;
485   pVlanConfig->VLANcomparison = READ_BIT(heth->Instance->MACVTDR, ETH_MACVTDR_ETV);
486 
487   pVlanConfig->DMAChannelNumberEnable = ((READ_BIT(heth->Instance->MACVTDR, ETH_MACVTDR_DMACHEN) >> 24) == 0U)
488                                         ? DISABLE : ENABLE;
489   pVlanConfig->RxDMAChannelNumber = READ_BIT(heth->Instance->MACVTDR, ETH_MACVTDR_DMACHN);
490 
491   pVlanConfig->VLANTagID = READ_BIT(heth->Instance->MACVTDR, ETH_MACVTDR_VID);
492 
493   return HAL_OK;
494 }
495 
496 /**
497   * @brief  Set the VLAN Configuration for Receive Packets.
498   * @param  heth: pointer to a ETH_HandleTypeDef structure that contains
499   *         the configuration information for ETHERNET module
500   * @param  pVlanConfig: pointer to a ETH_RxVLANConfigTypeDef structure
501   *         that contains VLAN filter configuration.
502   * @retval HAL status
503   */
HAL_ETHEx_SetRxVLANConfig(ETH_HandleTypeDef * heth,ETH_RxVLANConfigTypeDef * pVlanConfig)504 HAL_StatusTypeDef HAL_ETHEx_SetRxVLANConfig(ETH_HandleTypeDef *heth, ETH_RxVLANConfigTypeDef *pVlanConfig)
505 {
506   if (pVlanConfig == NULL)
507   {
508     return HAL_ERROR;
509   }
510 
511   /* Write config to MACVTCR */
512   MODIFY_REG(heth->Instance->MACVTCR, ETH_MACRXVLAN_MASK, (((uint32_t)pVlanConfig->InnerVLANTagInStatus << 31) |
513                                                            pVlanConfig->StripInnerVLANTag |
514                                                            ((uint32_t)pVlanConfig->InnerVLANTag << 27) |
515                                                            ((uint32_t)pVlanConfig->DoubleVLANProcessing << 26) |
516                                                            ((uint32_t)pVlanConfig->VLANTagHashTableMatch << 25) |
517                                                            ((uint32_t)pVlanConfig->VLANTagInStatus << 24) |
518                                                            pVlanConfig->StripVLANTag |
519                                                            pVlanConfig->VLANTypeCheck |
520                                                            ((uint32_t)pVlanConfig->VLANTagInverseMatch << 17) |
521                                                            ((uint32_t)pVlanConfig->BitVLANcomparison << 16)));
522   /* Write config to MACVTDR */
523   MODIFY_REG(heth->Instance->MACVTDR, ETH_MACRXVLAN_MASK, (((uint32_t)pVlanConfig->VLANTagEnable << 16) |
524                                                            ((uint32_t)pVlanConfig->VLANcomparison << 17) |
525                                                            ((uint32_t)pVlanConfig->DMAChannelNumberEnable << 24) |
526                                                            (pVlanConfig->RxDMAChannelNumber << 25)));
527 
528   HAL_ETH_SetRxVLANIdentifier(heth, (uint32_t)pVlanConfig->VLANcomparison, pVlanConfig->VLANTagID);
529 
530   return HAL_OK;
531 }
532 
533 /**
534   * @brief  Set the VLAN Hash Table
535   * @param  heth: pointer to a ETH_HandleTypeDef structure that contains
536   *         the configuration information for ETHERNET module
537   * @param  VLANHashTable: VLAN hash table 16 bit value
538   * @retval None
539   */
HAL_ETHEx_SetVLANHashTable(ETH_HandleTypeDef * heth,uint32_t VLANHashTable)540 void HAL_ETHEx_SetVLANHashTable(ETH_HandleTypeDef *heth, uint32_t VLANHashTable)
541 {
542   MODIFY_REG(heth->Instance->MACVHTR, ETH_MACVHTR_VLHT, VLANHashTable);
543 }
544 
545 /**
546   * @brief  Get the VLAN Configuration for Transmit Packets.
547   * @param  heth: pointer to a ETH_HandleTypeDef structure that contains
548   *         the configuration information for ETHERNET module
549   * @param  VLANTag: Selects the vlan tag, this parameter must be one of the following
550   *                 ETH_OUTER_TX_VLANTAG
551   *                 ETH_INNER_TX_VLANTAG
552   * @param  pVlanConfig: pointer to a ETH_TxVLANConfigTypeDef structure
553   *         that will contain the Tx VLAN filter configuration.
554   * @retval HAL Status.
555   */
HAL_ETHEx_GetTxVLANConfig(const ETH_HandleTypeDef * heth,uint32_t VLANTag,ETH_TxVLANConfigTypeDef * pVlanConfig)556 HAL_StatusTypeDef HAL_ETHEx_GetTxVLANConfig(const ETH_HandleTypeDef *heth, uint32_t VLANTag,
557                                             ETH_TxVLANConfigTypeDef *pVlanConfig)
558 {
559   if (pVlanConfig == NULL)
560   {
561     return HAL_ERROR;
562   }
563 
564   if (VLANTag == ETH_INNER_TX_VLANTAG)
565   {
566     pVlanConfig->SourceTxDesc = ((READ_BIT(heth->Instance->MACIVIR, ETH_MACVIR_VLTI) >> 20) == 0U) ? DISABLE : ENABLE;
567     pVlanConfig->SVLANType = ((READ_BIT(heth->Instance->MACIVIR, ETH_MACVIR_CSVL) >> 19) == 0U) ? DISABLE : ENABLE;
568     pVlanConfig->VLANTagControl = READ_BIT(heth->Instance->MACIVIR, (ETH_MACVIR_VLP | ETH_MACVIR_VLC));
569   }
570   else
571   {
572     pVlanConfig->SourceTxDesc = ((READ_BIT(heth->Instance->MACVIR, ETH_MACVIR_VLTI) >> 20) == 0U) ? DISABLE : ENABLE;
573     pVlanConfig->SVLANType = ((READ_BIT(heth->Instance->MACVIR, ETH_MACVIR_CSVL) >> 19) == 0U) ? DISABLE : ENABLE;
574     pVlanConfig->VLANTagControl = READ_BIT(heth->Instance->MACVIR, (ETH_MACVIR_VLP | ETH_MACVIR_VLC));
575   }
576 
577   return HAL_OK;;
578 }
579 
580 /**
581   * @brief  Set the VLAN Configuration for Transmit Packets.
582   * @param  heth: pointer to a ETH_HandleTypeDef structure that contains
583   *         the configuration information for ETHERNET module
584   * @param  VLANTag: Selects the vlan tag, this parameter must be one of the following
585   *                 ETH_OUTER_TX_VLANTAG
586   *                 ETH_INNER_TX_VLANTAG
587   * @param  pVlanConfig: pointer to a ETH_TxVLANConfigTypeDef structure
588   *         that contains Tx VLAN filter configuration.
589   * @retval HAL Status
590   */
HAL_ETHEx_SetTxVLANConfig(ETH_HandleTypeDef * heth,uint32_t VLANTag,const ETH_TxVLANConfigTypeDef * pVlanConfig)591 HAL_StatusTypeDef HAL_ETHEx_SetTxVLANConfig(ETH_HandleTypeDef *heth, uint32_t VLANTag,
592                                             const ETH_TxVLANConfigTypeDef *pVlanConfig)
593 {
594   if (VLANTag == ETH_INNER_TX_VLANTAG)
595   {
596     MODIFY_REG(heth->Instance->MACIVIR, ETH_MACTXVLAN_MASK, (((uint32_t)pVlanConfig->SourceTxDesc << 20) |
597                                                              ((uint32_t)pVlanConfig->SVLANType << 19) |
598                                                              pVlanConfig->VLANTagControl));
599     /* Enable Double VLAN processing */
600     SET_BIT(heth->Instance->MACVTCR, ETH_MACVTCR_EDVLP);
601   }
602   else
603   {
604     MODIFY_REG(heth->Instance->MACVIR, ETH_MACTXVLAN_MASK, (((uint32_t)pVlanConfig->SourceTxDesc << 20) |
605                                                             ((uint32_t)pVlanConfig->SVLANType << 19) |
606                                                             pVlanConfig->VLANTagControl));
607   }
608 
609   return HAL_OK;
610 }
611 
612 /**
613   * @brief  Set the VLAN Tag Identifier for Transmit Packets.
614   * @param  heth: pointer to a ETH_HandleTypeDef structure that contains
615   *         the configuration information for ETHERNET module
616   * @param  VLANTag: Selects the vlan tag, this parameter must be one of the following
617   *                 ETH_OUTER_TX_VLANTAG
618   *                 ETH_INNER_TX_VLANTAG
619   * @param  VLANIdentifier: VLAN Identifier 16 bit value
620   * @retval None
621   */
HAL_ETHEx_SetTxVLANIdentifier(ETH_HandleTypeDef * heth,uint32_t VLANTag,uint32_t VLANIdentifier)622 void HAL_ETHEx_SetTxVLANIdentifier(ETH_HandleTypeDef *heth, uint32_t VLANTag, uint32_t VLANIdentifier)
623 {
624   if (VLANTag == ETH_INNER_TX_VLANTAG)
625   {
626     MODIFY_REG(heth->Instance->MACIVIR, ETH_MACVIR_VLT, VLANIdentifier);
627   }
628   else
629   {
630     MODIFY_REG(heth->Instance->MACVIR, ETH_MACVIR_VLT, VLANIdentifier);
631   }
632 }
633 
634 /**
635   * @brief  Enables the VLAN Tag Filtering process.
636   * @param  heth: pointer to a ETH_HandleTypeDef structure that contains
637   *         the configuration information for ETHERNET module
638   * @retval None.
639   */
HAL_ETHEx_EnableVLANProcessing(ETH_HandleTypeDef * heth)640 void HAL_ETHEx_EnableVLANProcessing(ETH_HandleTypeDef *heth)
641 {
642   /* Enable VLAN processing */
643   SET_BIT(heth->Instance->MACPFR, ETH_MACPFR_VTFE);
644 }
645 
646 /**
647   * @brief  Disables the VLAN Tag Filtering process.
648   * @param  heth: pointer to a ETH_HandleTypeDef structure that contains
649   *         the configuration information for ETHERNET module
650   * @retval None.
651   */
HAL_ETHEx_DisableVLANProcessing(ETH_HandleTypeDef * heth)652 void HAL_ETHEx_DisableVLANProcessing(ETH_HandleTypeDef *heth)
653 {
654   /* Disable VLAN processing */
655   CLEAR_BIT(heth->Instance->MACPFR, ETH_MACPFR_VTFE);
656 }
657 
658 /**
659   * @brief  Enters the Low Power Idle (LPI) mode
660   * @param  heth: pointer to a ETH_HandleTypeDef structure that contains
661   *         the configuration information for ETHERNET module
662   * @param  TxAutomate: Enable/Disable automate enter/exit LPI mode.
663   * @param  TxClockStop: Enable/Disable Tx clock stop in LPI mode.
664   * @retval None
665   */
HAL_ETHEx_EnterLPIMode(ETH_HandleTypeDef * heth,FunctionalState TxAutomate,FunctionalState TxClockStop)666 void HAL_ETHEx_EnterLPIMode(ETH_HandleTypeDef *heth, FunctionalState TxAutomate, FunctionalState TxClockStop)
667 {
668   /* Enable LPI Interrupts */
669   __HAL_ETH_MAC_ENABLE_IT(heth, ETH_MACIER_LPIIE);
670 
671   /* Write to LPI Control register: Enter low power mode */
672   MODIFY_REG(heth->Instance->MACLCSR, (ETH_MACLCSR_LPIEN | ETH_MACLCSR_LPITXA | ETH_MACLCSR_LPITCSE),
673              (((uint32_t)TxAutomate << 19) |
674               ((uint32_t)TxClockStop << 21) |
675               ETH_MACLCSR_LPIEN));
676 }
677 
678 /**
679   * @brief  Exits the Low Power Idle (LPI) mode.
680   * @param  heth: pointer to a ETH_HandleTypeDef structure that contains
681   *         the configuration information for ETHERNET module
682   * @retval None
683   */
HAL_ETHEx_ExitLPIMode(ETH_HandleTypeDef * heth)684 void HAL_ETHEx_ExitLPIMode(ETH_HandleTypeDef *heth)
685 {
686   /* Clear the LPI Config and exit low power mode */
687   CLEAR_BIT(heth->Instance->MACLCSR, (ETH_MACLCSR_LPIEN | ETH_MACLCSR_LPITXA | ETH_MACLCSR_LPITCSE));
688 
689   /* Enable LPI Interrupts */
690   __HAL_ETH_MAC_DISABLE_IT(heth, ETH_MACIER_LPIIE);
691 }
692 
693 /**
694   * @brief  Returns the ETH MAC LPI event
695   * @param  heth: pointer to a ETH_HandleTypeDef structure that contains
696   *         the configuration information for ETHERNET module
697   * @retval ETH MAC WakeUp event
698   */
HAL_ETHEx_GetMACLPIEvent(const ETH_HandleTypeDef * heth)699 uint32_t HAL_ETHEx_GetMACLPIEvent(const ETH_HandleTypeDef *heth)
700 {
701   return heth->MACLPIEvent;
702 }
703 
704 /**
705   * @brief  Returns the ETH DMA Receive Channels Number Available
706   * @param  heth: pointer to a ETH_HandleTypeDef structure that contains
707   *         the configuration information for ETHERNET module
708   * @retval ETH DMA Rx Channels Number
709   */
HAL_ETHEx_GetRxDMAChNumber(const ETH_HandleTypeDef * heth)710 uint32_t HAL_ETHEx_GetRxDMAChNumber(const ETH_HandleTypeDef *heth)
711 {
712   uint32_t nbr;
713   nbr = (READ_BIT(heth->Instance->MACHWF2R, ETH_MACHWF2R_RXCHCNT) >> 12) + 1U;
714   return nbr;
715 }
716 
717 /**
718   * @brief  Returns the ETH DMA Transmit Channels Number
719   * @param  heth: pointer to a ETH_HandleTypeDef structure that contains
720   *         the configuration information for ETHERNET module
721   * @retval ETH DMA Tx Channels Number
722   */
HAL_ETHEx_GetTxDMAChNumber(const ETH_HandleTypeDef * heth)723 uint32_t HAL_ETHEx_GetTxDMAChNumber(const ETH_HandleTypeDef *heth)
724 {
725   uint32_t nbr;
726   nbr = (READ_BIT(heth->Instance->MACHWF2R, ETH_MACHWF2R_TXCHCNT) >> 18) + 1U;
727   return nbr;
728 }
729 
730 /**
731   * @brief  Returns the ETH MTL Receive Queues Number
732   * @param  heth: pointer to a ETH_HandleTypeDef structure that contains
733   *         the configuration information for ETHERNET module
734   * @retval ETH MTL Rx Queues Number
735   */
HAL_ETHEx_GetRxMTLQNumber(const ETH_HandleTypeDef * heth)736 uint32_t HAL_ETHEx_GetRxMTLQNumber(const ETH_HandleTypeDef *heth)
737 {
738   uint32_t nbr;
739   nbr = READ_BIT(heth->Instance->MACHWF2R, ETH_MACHWF2R_RXQCNT) + 1U;
740   return nbr;
741 }
742 
743 /**
744   * @brief  Returns the ETH MTL Transmit Queues Number
745   * @param  heth: pointer to a ETH_HandleTypeDef structure that contains
746   *         the configuration information for ETHERNET module
747   * @retval ETH MTL Tx Queues Number
748   */
HAL_ETHEx_GetTxMTLQNumber(const ETH_HandleTypeDef * heth)749 uint32_t HAL_ETHEx_GetTxMTLQNumber(const ETH_HandleTypeDef *heth)
750 {
751   uint32_t nbr;
752   nbr = (READ_BIT(heth->Instance->MACHWF2R, ETH_MACHWF2R_TXQCNT) >> 6) + 1U;
753   return nbr;
754 }
755 
756 /**
757   * @brief  Get the configuration of the MTL.
758   * @param  heth: pointer to a ETH_HandleTypeDef structure that contains
759   *         the configuration information for ETHERNET module
760   * @param  mtlconf: pointer to a ETH_MACConfigTypeDef structure that will hold
761   *         the configuration of the MTL.
762   * @retval HAL Status
763   */
HAL_ETHEx_GetMTLConfig(const ETH_HandleTypeDef * heth,ETH_MTLConfigTypeDef * mtlconf)764 HAL_StatusTypeDef HAL_ETHEx_GetMTLConfig(const ETH_HandleTypeDef *heth, ETH_MTLConfigTypeDef *mtlconf)
765 {
766   uint32_t queue;
767 
768   if (mtlconf == NULL)
769   {
770     return HAL_ERROR;
771   }
772 
773   mtlconf->ReceiveArbitrationAlgorithm = READ_BIT(heth->Instance->MTLOMR, ETH_MTLOMR_RAA_Msk);
774   mtlconf->TxSchedulingAlgorithm = READ_BIT(heth->Instance->MTLOMR, ETH_MTLOMR_SCHALG_Msk);
775   mtlconf->TransmitStatus = ((READ_BIT(heth->Instance->MTLOMR, ETH_MTLOMR_DTXSTS_Msk) >> 1) > 0U) ? ENABLE : DISABLE;
776 
777   (mtlconf->RxQ[0]).QueueOpMode = READ_BIT(heth->Instance->MACRXQC0R,
778                                            ETH_MACRXQC0R_RXQ0EN_NOT | ETH_MACRXQC0R_RXQ0EN_GT |
779                                            ETH_MACRXQC0R_RXQ0EN_AV);
780   (mtlconf->RxQ[1]).QueueOpMode = READ_BIT(heth->Instance->MACRXQC0R,
781                                            ETH_MACRXQC0R_RXQ1EN_NOT | ETH_MACRXQC0R_RXQ1EN_GT |
782                                            ETH_MACRXQC0R_RXQ1EN_AV);
783 
784   (mtlconf->RxQ[0]).MappedToDMACh = READ_BIT(heth->Instance->MTLRXQDMAMR, ETH_MTLRXQDMAMR_Q0MDMACH_Msk);
785   (mtlconf->RxQ[1]).MappedToDMACh = READ_BIT(heth->Instance->MTLRXQDMAMR, ETH_MTLRXQDMAMR_Q1MDMACH_Msk);
786 
787   /* Get MTL parameters */
788   for (queue = 0; queue < ETH_MTL_RX_Q_CNT; queue++)
789   {
790     (mtlconf->RxQ[queue]).RxQueueSize = READ_BIT(heth->Instance->MTL_QUEUE[queue].MTLRXQOMR,
791                                                  (ETH_MTLRXQxOMR_RQS_0 | ETH_MTLRXQxOMR_RQS_1 | ETH_MTLRXQxOMR_RQS_2 |
792                                                   ETH_MTLRXQxOMR_RQS_3));
793     (mtlconf->RxQ[queue]).ReceiveQueueMode = READ_BIT(heth->Instance->MTL_QUEUE[queue].MTLRXQOMR, (ETH_MTLRXQxOMR_RTC |
794                                                       ETH_MTLRXQxOMR_RSF));
795     (mtlconf->RxQ[queue]).ForwardRxUndersizedGoodPacket = ((READ_BIT(heth->Instance->MTL_QUEUE[queue].MTLRXQOMR,
796                                                                      ETH_MTLRXQxOMR_FUP) >> 3) > 0U) ? ENABLE : DISABLE;
797     (mtlconf->RxQ[queue]).ForwardRxErrorPacket = ((READ_BIT(heth->Instance->MTL_QUEUE[queue].MTLRXQOMR,
798                                                             ETH_MTLRXQxOMR_FEP) >> 4) > 0U) ? ENABLE : DISABLE;
799     (mtlconf->RxQ[queue]).DropTCPIPChecksumErrorPacket = ((READ_BIT(heth->Instance->MTL_QUEUE[queue].MTLRXQOMR,
800                                                                     ETH_MTLRXQxOMR_DISTCPEF) >>
801                                                            6) == 0U) ? ENABLE : DISABLE;
802   }
803 
804   for (queue = 0; queue < ETH_MTL_TX_Q_CNT; queue++)
805   {
806     (mtlconf->TxQ[queue]).TxQueueSize = READ_BIT(heth->Instance->MTL_QUEUE[queue].MTLTXQOMR,
807                                                  (ETH_MTLTXQxOMR_TQS_0 | ETH_MTLTXQxOMR_TQS_1 | ETH_MTLTXQxOMR_TQS_2 |
808                                                   ETH_MTLTXQxOMR_TQS_3));
809     (mtlconf->TxQ[queue]).TransmitQueueMode = READ_BIT(heth->Instance->MTL_QUEUE[queue].MTLTXQOMR, (ETH_MTLTXQxOMR_TTC |
810                                                        ETH_MTLTXQxOMR_TSF));
811     (mtlconf->TxQ[queue]).QueueOpMode = READ_BIT(heth->Instance->MTL_QUEUE[queue].MTLTXQOMR, ETH_MTLTXQxOMR_TXQEN_NOT |
812                                                  ETH_MTLTXQxOMR_TXQEN_EN | ETH_MTLTXQxOMR_TXQEN_AVMODE);
813   }
814 
815   (mtlconf->TxQ[1]).AVAlgorithm = READ_BIT(heth->Instance->MTL_QUEUE[1].MTLTXQ1ECR, ETH_MTLTXQ1ECR_AVALG);
816 
817   return HAL_OK;
818 }
819 
820 /**
821   * @brief  Get the configuration of the MTL.
822   * @param  heth: pointer to a ETH_HandleTypeDef structure that contains
823   *         the configuration information for ETHERNET module
824   * @param  mtlconf: pointer to a ETH_MACConfigTypeDef structure that will hold
825   *         the configuration of the MTL.
826   * @retval HAL Status
827   */
HAL_ETHEx_GetMACMTLMappingConfig(const ETH_HandleTypeDef * heth,ETH_MACMTLMappingTypeDef * macmtlconf)828 HAL_StatusTypeDef HAL_ETHEx_GetMACMTLMappingConfig(const ETH_HandleTypeDef *heth, ETH_MACMTLMappingTypeDef *macmtlconf)
829 {
830   if (macmtlconf == NULL)
831   {
832     return HAL_ERROR;
833   }
834 
835   macmtlconf->VLANTagFilterFailPacketsQueue = READ_BIT(heth->Instance->MACRXQCR, ETH_MACRXQCR_VFFQ);
836   macmtlconf->VLANTagFilterFailPacketsQueuingEnable = ((READ_BIT(heth->Instance->MACRXQCR,
837                                                                  ETH_MACRXQCR_VFFQE_Msk) >> 16) > 0U)
838                                                       ? ENABLE : DISABLE;
839   macmtlconf->MulticastAddFilterFailPacketsQueue = READ_BIT(heth->Instance->MACRXQCR, ETH_MACRXQCR_MFFQ);
840   macmtlconf->MulticastAddrFilterFailPacketsQueuingEnable = ((READ_BIT(heth->Instance->MACRXQCR,
841                                                                        ETH_MACRXQCR_MFFQE_Msk) >> 8) > 0U)
842                                                             ? ENABLE : DISABLE;
843   macmtlconf->UnicastAddrFilterFailPacketsQueue = READ_BIT(heth->Instance->MACRXQCR, ETH_MACRXQCR_UFFQ);
844   macmtlconf->UnicastAddrFilterFailPacketsQueuingEnable = (READ_BIT(heth->Instance->MACRXQCR,
845                                                                     ETH_MACRXQCR_UFFQE_Msk) > 0U) ? ENABLE : DISABLE;
846   macmtlconf->TypeFieldBasedRxQueuingEnable = (READ_BIT(heth->Instance->MACRXQC1R,
847                                                         ETH_MACRXQC1R_TBRQE_Msk) > 0U) ? ENABLE : DISABLE;
848   macmtlconf->OverridingMCBCQueuePrioritySelect = READ_BIT(heth->Instance->MACRXQC1R, ETH_MACRXQC1R_OMCBCQ);
849   macmtlconf->FramePreemptionResidueQueue = READ_BIT(heth->Instance->MACRXQC1R, ETH_MACRXQC1R_FPRQ);
850   macmtlconf->TaggedPTPoEPacketsQueuingControl = READ_BIT(heth->Instance->MACRXQC1R, ETH_MACRXQC1R_TPQC);
851   macmtlconf->TaggedAVControlPacketsQueuingEnable = (READ_BIT(heth->Instance->MACRXQC1R,
852                                                               ETH_MACRXQC1R_TACPQE_Msk) > 0U) ? ENABLE : DISABLE;
853   macmtlconf->MulticastBroadcastQueueEnable = (READ_BIT(heth->Instance->MACRXQC1R,
854                                                         ETH_MACRXQC1R_MCBCQEN_Msk) > 0U) ? ENABLE : DISABLE;
855   macmtlconf->MulticastBroadcastQueue = READ_BIT(heth->Instance->MACRXQC1R, ETH_MACRXQC1R_MCBCQ);
856   macmtlconf->UntaggedPacketQueue = READ_BIT(heth->Instance->MACRXQC1R, ETH_MACRXQC1R_UPQ);
857   macmtlconf->PTPPacketsQueue = READ_BIT(heth->Instance->MACRXQC1R, ETH_MACRXQC1R_PTPQ);
858   macmtlconf->AVUntaggedControlPacketsQueue = READ_BIT(heth->Instance->MACRXQC1R, ETH_MACRXQC1R_AVCPQ);
859 
860   if (HAL_ETHEx_GetUserTagPriorityQueue(heth, &(macmtlconf->PrioritiesSelectedRxQ0), ETH_RX_QUEUE0) != HAL_OK)
861   {
862     return HAL_ERROR;
863   }
864 
865   if (HAL_ETHEx_GetUserTagPriorityQueue(heth, &(macmtlconf->PrioritiesSelectedRxQ1), ETH_RX_QUEUE1) != HAL_OK)
866   {
867     return HAL_ERROR;
868   }
869 
870   return HAL_OK;
871 }
872 
ETHEx_SetMACMTLMappingConfig(ETH_HandleTypeDef * heth,const ETH_MACMTLMappingTypeDef * macmtlconf)873 HAL_StatusTypeDef ETHEx_SetMACMTLMappingConfig(ETH_HandleTypeDef *heth, const ETH_MACMTLMappingTypeDef *macmtlconf)
874 {
875   uint32_t macmtlregval;
876 
877   /*------------------------ MACRXQC1R Configuration --------------------*/
878   macmtlregval = ((uint32_t)(macmtlconf->AVUntaggedControlPacketsQueue) |
879                   ((uint32_t)(macmtlconf->PTPPacketsQueue) << 4)         |
880                   ((uint32_t)(macmtlconf->UntaggedPacketQueue) << 12)    |
881                   ((uint32_t)(macmtlconf->MulticastBroadcastQueue) << 16) |
882                   ((uint32_t)((macmtlconf->MulticastBroadcastQueueEnable == DISABLE) ? 0U : 1U) << 20) |
883                   ((uint32_t)((macmtlconf->TaggedAVControlPacketsQueuingEnable == DISABLE) ? 0U : 1U) << 21) |
884                   (uint32_t)(macmtlconf->TaggedPTPoEPacketsQueuingControl) |
885                   (uint32_t)(macmtlconf->FramePreemptionResidueQueue) |
886                   (uint32_t)(macmtlconf->OverridingMCBCQueuePrioritySelect) |
887                   ((uint32_t)((macmtlconf->TypeFieldBasedRxQueuingEnable == DISABLE) ? 0U : 1U) << 29));
888 
889   /* Write to MACRXQC1R */
890   MODIFY_REG(heth->Instance->MACRXQC1R, ETH_MACRXQC1R_MASK, macmtlregval);
891 
892   /*------------------------ MACRXQC2R Configuration --------------------*/
893   /* Write to MACRXQC2R */
894   if (HAL_ETHEx_SetUserTagPriorityQueue(heth, macmtlconf->PrioritiesSelectedRxQ0, ETH_RX_QUEUE0) != HAL_OK)
895   {
896     return HAL_ERROR;
897   }
898 
899   if (HAL_ETHEx_SetUserTagPriorityQueue(heth, macmtlconf->PrioritiesSelectedRxQ1, ETH_RX_QUEUE1) != HAL_OK)
900   {
901     return HAL_ERROR;
902   }
903 
904   /*------------------------ MACRXQCR Configuration --------------------*/
905   macmtlregval = (((uint32_t)((macmtlconf->UnicastAddrFilterFailPacketsQueuingEnable == DISABLE) ? 0U : 1U)) |
906                   ((uint32_t)(macmtlconf->UnicastAddrFilterFailPacketsQueue) << 1)         |
907                   ((uint32_t)((macmtlconf->MulticastAddrFilterFailPacketsQueuingEnable == DISABLE) ? 0U : 1U) << 8) |
908                   ((uint32_t)(macmtlconf->MulticastAddFilterFailPacketsQueue) << 9)         |
909                   ((uint32_t)((macmtlconf->VLANTagFilterFailPacketsQueuingEnable == DISABLE) ? 0U : 1U) << 16) |
910                   ((uint32_t)(macmtlconf->VLANTagFilterFailPacketsQueue) << 17));
911 
912   /* Write to MACRXQCR */
913   MODIFY_REG(heth->Instance->MACRXQCR, ETH_MACRXQCR_MASK, macmtlregval);
914 
915   return HAL_OK;
916 }
917 
918 /**
919   * @brief  Set the MAC MTL Mapping configuration.
920   * @param  heth: pointer to a ETH_HandleTypeDef structure that contains
921   *         the configuration information for ETHERNET module
922   * @param  macmtlconf: pointer to a ETH_MACMTLMappingTypeDef structure that contains
923   *         the configuration of the MAC MTL mapping.
924   * @retval HAL status
925   */
HAL_ETHEx_SetMACMTLMappingConfig(ETH_HandleTypeDef * heth,const ETH_MACMTLMappingTypeDef * macmtlconf)926 HAL_StatusTypeDef HAL_ETHEx_SetMACMTLMappingConfig(ETH_HandleTypeDef *heth, const ETH_MACMTLMappingTypeDef *macmtlconf)
927 {
928   if (macmtlconf == NULL)
929   {
930     return HAL_ERROR;
931   }
932 
933   if (heth->gState == HAL_ETH_STATE_READY)
934   {
935     if (ETHEx_SetMACMTLMappingConfig(heth, macmtlconf) != HAL_OK)
936     {
937       return HAL_ERROR;
938     }
939 
940     return HAL_OK;
941   }
942   else
943   {
944     return HAL_ERROR;
945   }
946 }
947 
948 
ETHEx_SetMTLConfig(ETH_HandleTypeDef * heth,const ETH_MTLConfigTypeDef * mtlconf)949 void ETHEx_SetMTLConfig(ETH_HandleTypeDef *heth, const ETH_MTLConfigTypeDef *mtlconf)
950 {
951   uint32_t queue;
952   uint32_t mtlregval;
953 
954   /*------------------------ MTLOMR Configuration --------------------*/
955   mtlregval = (mtlconf->TxSchedulingAlgorithm) |
956               (mtlconf->ReceiveArbitrationAlgorithm) |
957               ((uint32_t)((mtlconf->TransmitStatus == DISABLE) ? 1U : 0U) << 1);
958 
959   /* Write to MTLOMR */
960   MODIFY_REG(heth->Instance->MTLOMR, ETH_MTLOMR_MASK, mtlregval);
961 
962   /*------------------------ MTLRXQDMAMR Configuration --------------------*/
963   mtlregval = (mtlconf->RxQ[0]).MappedToDMACh |
964               (mtlconf->RxQ[1]).MappedToDMACh;
965 
966   /* Write to MTLRXQDMAMR */
967   MODIFY_REG(heth->Instance->MTLRXQDMAMR, ETH_MTLRXQDMAMR_Q0MDMACH_Msk | ETH_MTLRXQDMAMR_Q1MDMACH_Msk, mtlregval);
968 
969   /*------------------------ MTLTXQOMR Configuration --------------------*/
970   for (queue = 0; queue < ETH_MTL_TX_Q_CNT; queue++)
971   {
972     mtlregval = ((mtlconf->TxQ[queue]).QueueOpMode)         |
973                 ((mtlconf->TxQ[queue]).TransmitQueueMode) |
974                 ((mtlconf->TxQ[queue]).TxQueueSize);
975 
976     /* Write to MTLTXQ0OMR */
977     MODIFY_REG(heth->Instance->MTL_QUEUE[queue].MTLTXQOMR, ETH_MTLTXQxOMR_MASK, mtlregval);
978   }
979 
980   /*------------------------ MACRXQC0R Configuration --------------------*/
981   mtlregval = (((mtlconf->RxQ[0]).QueueOpMode)  |
982                ((mtlconf->RxQ[1]).QueueOpMode));
983 
984   /* Write to MACRXQC0R */
985   MODIFY_REG(heth->Instance->MACRXQC0R, ETH_MACRXQC0R_RXQ1EN_Msk | ETH_MACRXQC0R_RXQ0EN_Msk, mtlregval);
986 
987   /*------------------------ MTLRXQOMR Configuration --------------------*/
988   for (queue = 0; queue < ETH_MTL_RX_Q_CNT; queue++)
989   {
990 
991     mtlregval = (((mtlconf->RxQ[queue]).ReceiveQueueMode)  |
992                  ((mtlconf->RxQ[queue]).RxQueueSize)       |
993                  ((uint32_t)(((mtlconf->RxQ[queue]).DropTCPIPChecksumErrorPacket == DISABLE) ? 1U : 0U) << 6) |
994                  ((uint32_t)(mtlconf->RxQ[queue]).ForwardRxErrorPacket << 4) |
995                  ((uint32_t)(mtlconf->RxQ[queue]).ForwardRxUndersizedGoodPacket << 3));
996 
997     /* Write to MTLRXQOMR */
998     MODIFY_REG(heth->Instance->MTL_QUEUE[queue].MTLRXQOMR, ETH_MTLRXQxOMR_MASK, mtlregval);
999   }
1000   /*------------------------ MTLTXQ1ECR Configuration --------------------*/
1001   mtlregval = ((mtlconf->TxQ[1]).AVAlgorithm);
1002 
1003   /* Write to MTLTXQ1ECR */
1004   MODIFY_REG(heth->Instance->MTL_QUEUE[1].MTLTXQ1ECR, ETH_MTLTXQ1ECR_AVALG_Msk, mtlregval);
1005 }
1006 
1007 /**
1008   * @brief  Set the MTL configuration.
1009   * @param  heth: pointer to a ETH_HandleTypeDef structure that contains
1010   *         the configuration information for ETHERNET module
1011   * @param  mtlconf: pointer to a ETH_MTLConfigTypeDef structure that contains
1012   *         the configuration of the MAC.
1013   * @retval HAL status
1014   */
HAL_ETHEx_SetMTLConfig(ETH_HandleTypeDef * heth,ETH_MTLConfigTypeDef * mtlconf)1015 HAL_StatusTypeDef HAL_ETHEx_SetMTLConfig(ETH_HandleTypeDef *heth,  ETH_MTLConfigTypeDef *mtlconf)
1016 {
1017   if (mtlconf == NULL)
1018   {
1019     return HAL_ERROR;
1020   }
1021 
1022   if (heth->gState == HAL_ETH_STATE_READY)
1023   {
1024     ETHEx_SetMTLConfig(heth, mtlconf);
1025   }
1026   else
1027   {
1028     return HAL_ERROR;
1029   }
1030 
1031   return HAL_OK;
1032 }
1033 
1034 /**
1035   * @brief  Get the User Tag Priority Queueing.
1036   * @param  heth: pointer to a ETH_HandleTypeDef structure that contains
1037   *         the configuration information for ETHERNET module
1038   * @param  psrq: user priority
1039   * @param  queue: queue index
1040   * @retval None
1041   */
HAL_ETHEx_GetUserTagPriorityQueue(const ETH_HandleTypeDef * heth,uint32_t * psrq,uint32_t queue)1042 HAL_StatusTypeDef HAL_ETHEx_GetUserTagPriorityQueue(const ETH_HandleTypeDef *heth, uint32_t *psrq, uint32_t queue)
1043 {
1044   if (psrq == NULL)
1045   {
1046     return HAL_ERROR;
1047   }
1048 
1049   if (queue == ETH_RX_QUEUE0)
1050   {
1051     *psrq = (uint32_t)(READ_BIT(heth->Instance->MACRXQC2R, ETH_MACRXQC2R_PSRQ0) >> ETH_MACRXQC2R_PSRQ0_Pos);
1052     return HAL_OK;
1053   }
1054 
1055   if (queue == ETH_RX_QUEUE1)
1056   {
1057     *psrq = (uint32_t)(READ_BIT(heth->Instance->MACRXQC2R, ETH_MACRXQC2R_PSRQ1) >> ETH_MACRXQC2R_PSRQ1_Pos);
1058     return HAL_OK;
1059   }
1060 
1061   return HAL_ERROR;
1062 }
1063 
1064 /**
1065   * @brief  Set the User Tag Priority Queueing.
1066   * @param  heth: pointer to a ETH_HandleTypeDef structure that contains
1067   *         the configuration information for ETHERNET module
1068   * @param  psrq: user priority
1069   * @param  queue: queue index
1070   * @retval None
1071   */
HAL_ETHEx_SetUserTagPriorityQueue(ETH_HandleTypeDef * heth,uint32_t psrq,uint32_t queue)1072 HAL_StatusTypeDef HAL_ETHEx_SetUserTagPriorityQueue(ETH_HandleTypeDef *heth, uint32_t psrq, uint32_t queue)
1073 {
1074   uint32_t idx;
1075   uint32_t tmppsrq;
1076   uint32_t pos;
1077 
1078   for (idx = 0; idx < ETH_MTL_RX_Q_CNT; idx++)
1079   {
1080     pos = idx * 8U;
1081 
1082     if (idx != queue)
1083     {
1084       /* Ensure that the same priority PSR is not mapped to multiple Rx queues. */
1085       if (HAL_ETHEx_GetUserTagPriorityQueue(heth, &tmppsrq, idx) != HAL_OK)
1086       {
1087         return HAL_ERROR;
1088       }
1089 
1090       if ((tmppsrq & psrq) != 0U)
1091       {
1092         CLEAR_BIT(heth->Instance->MACRXQC2R, (psrq << (queue * 8U)));
1093         /* PSR is already mapped to another queue */
1094         return HAL_ERROR;
1095       }
1096     }
1097     else
1098     {
1099       MODIFY_REG(heth->Instance->MACRXQC2R, (psrq << pos), (uint32_t)(psrq << pos));
1100     }
1101   }
1102   return HAL_OK;
1103 }
1104 
1105 /**
1106   * @brief  Set the Packet Type Queueing.
1107   * @param  heth: pointer to a ETH_HandleTypeDef structure that contains
1108   *         the configuration information for ETHERNET module
1109   * @param  typequeueconf: pointer to a ETH_PacketTypeQueueConfigTypeDef structure that contains
1110   *         the configuration of the MAC.
1111   * @retval HAL status
1112   */
HAL_ETHEx_SetPacketTypeQueue(ETH_HandleTypeDef * heth,const ETH_PacketTypeQueueConfigTypeDef * typequeueconf)1113 HAL_StatusTypeDef HAL_ETHEx_SetPacketTypeQueue(ETH_HandleTypeDef *heth,
1114                                                const ETH_PacketTypeQueueConfigTypeDef *typequeueconf)
1115 {
1116   uint32_t cmd;
1117   uint32_t config;
1118 
1119   if (typequeueconf == NULL)
1120   {
1121     return HAL_ERROR;
1122   }
1123 
1124   if (heth->gState != HAL_ETH_STATE_STARTED)
1125   {
1126     return HAL_ERROR;
1127   }
1128 
1129   cmd = ETH_WRITE_OPERATION | ETH_MACIACR_OB | ((uint32_t)(typequeueconf->Address) << 8);
1130   config = typequeueconf->Preemption | (typequeueconf->Queue << 16) | typequeueconf->Type;
1131 
1132   /* Enable Type field based Rx queuing */
1133   SET_BIT(heth->Instance->MACRXQC1R, ETH_MACRXQC1R_TBRQE);
1134 
1135   /* Set configuration to MACTMRQR */
1136   WRITE_REG(heth->Instance->MACTMRQR, config);
1137 
1138   /* Set command to MACIACR */
1139   MODIFY_REG(heth->Instance->MACIACR, ETH_MAC_IACR_MASK, cmd);
1140 
1141   /* Get tick */
1142   uint32_t tickstart = HAL_GetTick();
1143 
1144   /* wait until the Operation reset is done */
1145   while (READ_BIT(heth->Instance->MACIACR, ETH_MACIACR_OB) != (uint32_t)RESET)
1146   {
1147     if ((HAL_GetTick() - tickstart) > ETH_OP_BUSY_TIMEOUT)
1148     {
1149       /* Set Error Code */
1150       heth->MACErrorCode = HAL_ETH_ERROR_TIMEOUT;
1151       /* Set State as Error */
1152       heth->gState = HAL_ETH_STATE_ERROR;
1153       /* Return Error */
1154       return HAL_ERROR;
1155     }
1156   }
1157 
1158   /* Return function status */
1159   return HAL_OK;
1160 }
1161 
1162 /**
1163   * @brief  Get the Packet Type Queueing.
1164   * @param  heth: pointer to a ETH_HandleTypeDef structure that contains
1165   *         the configuration information for ETHERNET module
1166   * @param  typequeueconf: pointer to a ETH_PacketTypeQueueConfigTypeDef structure that contains
1167   *         the configuration of the MAC.
1168   * @retval HAL status
1169   */
HAL_ETHEx_GetPacketTypeQueue(ETH_HandleTypeDef * heth,ETH_PacketTypeQueueConfigTypeDef * typequeueconf)1170 HAL_StatusTypeDef HAL_ETHEx_GetPacketTypeQueue(ETH_HandleTypeDef *heth, ETH_PacketTypeQueueConfigTypeDef *typequeueconf)
1171 {
1172   uint32_t cmd;
1173 
1174   if (heth->gState != HAL_ETH_STATE_STARTED)
1175   {
1176     return HAL_ERROR;
1177   }
1178 
1179   if (typequeueconf == NULL)
1180   {
1181     return HAL_ERROR;
1182   }
1183 
1184   cmd = ETH_READ_OPERATION | ETH_MACIACR_OB | ((uint32_t)(typequeueconf->Address) << 8);
1185 
1186   /* Set command to MACIACR */
1187   MODIFY_REG(heth->Instance->MACIACR, ETH_MAC_IACR_MASK, cmd);
1188 
1189   /* Get tick */
1190   uint32_t tickstart = HAL_GetTick();
1191 
1192   /* wait until the Operation reset is done */
1193   while (READ_BIT(heth->Instance->MACIACR, ETH_MACIACR_OB) != (uint32_t)RESET)
1194   {
1195     if ((HAL_GetTick() - tickstart) > ETH_OP_BUSY_TIMEOUT)
1196     {
1197       /* Set Error Code */
1198       heth->MACErrorCode = HAL_ETH_ERROR_TIMEOUT;
1199       /* Set State as Error */
1200       heth->gState = HAL_ETH_STATE_ERROR;
1201       /* Return Error */
1202       return HAL_ERROR;
1203     }
1204   }
1205 
1206   /* Get configuration from MACTMRQR */
1207   typequeueconf->Preemption = READ_BIT(heth->Instance->MACTMRQR, ETH_MACTMRQR_PFEX_Msk);
1208   typequeueconf->Queue = (READ_BIT(heth->Instance->MACTMRQR, ETH_MACTMRQR_TMRQ_Msk) >> 16);
1209   typequeueconf->Type = READ_BIT(heth->Instance->MACTMRQR, ETH_MACTMRQR_TYP_Msk);
1210 
1211   /* Return function status */
1212   return HAL_OK;
1213 }
1214 
1215 #ifdef HAL_ETH_USE_CBS
1216 /**
1217   * @brief  Enable the CBS Algorithm.
1218   * @param  heth: pointer to a ETH_HandleTypeDef structure that contains
1219   *         the configuration information for ETHERNET module
1220   * @param  queueIndex: contains the AV queue index which will support the CBS algorithm
1221   * @retval HAL status
1222   */
HAL_ETHEx_EnableCBS(ETH_HandleTypeDef * heth,uint8_t queueIndex)1223 HAL_StatusTypeDef HAL_ETHEx_EnableCBS(ETH_HandleTypeDef *heth, uint8_t queueIndex)
1224 {
1225   /* Enable AV mode for Queue x */
1226   MODIFY_REG(heth->Instance->MTL_QUEUE[queueIndex].MTLTXQOMR, ETH_MTLTXQxOMR_TXQEN_Msk, ETH_TX_QUEUE_AV_ENABLED);
1227 
1228   /* Enable CBS Algorithm for Queue x */
1229   SET_BIT(heth->Instance->MTL_QUEUE[queueIndex].MTLTXQ1ECR, ETH_TX_QUEUE_AV_ALGO_CBS);
1230 
1231   /* Return function status */
1232   return HAL_OK;
1233 }
1234 
ETHEx_SetCBSConfig(ETH_HandleTypeDef * heth,ETH_CBSConfigTypeDef * cbsconf)1235 static void ETHEx_SetCBSConfig(ETH_HandleTypeDef *heth, ETH_CBSConfigTypeDef *cbsconf)
1236 {
1237   uint32_t cbsregval;
1238   cbsregval = (uint32_t)(cbsconf->SlotCount | cbsconf->CreditControl);
1239   /* Write to MTLTXQ1ECR */
1240   MODIFY_REG(heth->Instance->MTL_QUEUE[cbsconf->QueueIdx].MTLTXQ1ECR, ETH_MTLTXQ1ECR_SLC_Msk | ETH_MTLTXQ1ECR_CC_Msk,
1241              cbsregval);
1242 
1243   cbsregval = (uint32_t)cbsconf->IdleSlope;
1244   /* Write to MTLTXQ1QWR */
1245   MODIFY_REG(heth->Instance->MTL_QUEUE[cbsconf->QueueIdx].MTLTXQQWR, ETH_MTLTXQ1QWR_ISCQW_Msk, cbsregval);
1246 
1247   cbsregval = (uint32_t)cbsconf->SendSlope;
1248   /* Write to MTLTXQ1SSCR */
1249   MODIFY_REG(heth->Instance->MTL_QUEUE[cbsconf->QueueIdx].MTLTXQ1SSCR, ETH_MTLTXQ1SSCR_SSC_Msk, cbsregval);
1250 
1251   cbsregval = (uint32_t)cbsconf->HiCredit;
1252   /* Write to MTLTXQ1HCR */
1253   MODIFY_REG(heth->Instance->MTL_QUEUE[cbsconf->QueueIdx].MTLTXQ1HCR, ETH_MTLTXQ1HCR_HC_Msk, cbsregval);
1254 
1255   cbsregval = (uint32_t)cbsconf->LoCredit;
1256   /* Write to MTLTXQ1LCR */
1257   MODIFY_REG(heth->Instance->MTL_QUEUE[cbsconf->QueueIdx].MTLTXQ1LCR, ETH_MTLTXQ1LCR_LC_Msk, cbsregval);
1258 }
1259 
1260 /**
1261   * @brief  Set the CBS configuration.
1262   * @param  heth: pointer to a ETH_HandleTypeDef structure that contains
1263   *         the configuration information for ETHERNET module
1264   * @param  cbsconf: pointer to a ETH_CBSConfigTypeDef structure that contains
1265   *         the configuration of the CBS algorithm.
1266   * @retval HAL status
1267   */
HAL_ETHEx_SetCBSConfig(ETH_HandleTypeDef * heth,ETH_CBSConfigTypeDef * cbsconf)1268 HAL_StatusTypeDef HAL_ETHEx_SetCBSConfig(ETH_HandleTypeDef *heth,  ETH_CBSConfigTypeDef *cbsconf)
1269 {
1270   if (cbsconf == NULL)
1271   {
1272     return HAL_ERROR;
1273   }
1274 
1275   if ((READ_BIT(heth->Instance->MTL_QUEUE[cbsconf->QueueIdx].MTLTXQOMR, ETH_TX_QUEUE_AV_ENABLED) != (uint32_t)RESET) &&
1276       (READ_BIT(heth->Instance->MTL_QUEUE[cbsconf->QueueIdx].MTLTXQ1ECR, ETH_TX_QUEUE_AV_ALGO_CBS) != (uint32_t)RESET))
1277   {
1278     ETHEx_SetCBSConfig(heth, cbsconf);
1279   }
1280   else
1281   {
1282     return HAL_ERROR;
1283   }
1284 
1285   return HAL_OK;
1286 }
1287 
1288 /**
1289   * @brief  HAL ETH Get CBS Config.
1290   * @param  heth: pointer to a ETH_HandleTypeDef structure that contains
1291   *         the configuration information for ETHERNET module
1292   * @param  pCBSConfig: pointer to a ETH_CBSConfigTypeDef structure that will hold
1293   *         the configuration of the CBS Algorithm.
1294   * @retval HAL status
1295   */
HAL_ETHEx_GetCBSConfig(const ETH_HandleTypeDef * heth,ETH_CBSConfigTypeDef * pCBSConfig,uint8_t queueIndex)1296 HAL_StatusTypeDef HAL_ETHEx_GetCBSConfig(const ETH_HandleTypeDef *heth, ETH_CBSConfigTypeDef *pCBSConfig,
1297                                          uint8_t queueIndex)
1298 {
1299   if (pCBSConfig == NULL)
1300   {
1301     return HAL_ERROR;
1302   }
1303 
1304   pCBSConfig->QueueIdx = queueIndex;
1305   pCBSConfig->SlotCount = READ_BIT(heth->Instance->MTL_QUEUE[queueIndex].MTLTXQ1ECR, ETH_MTLTXQ1ECR_SLC);
1306   pCBSConfig->CreditControl = READ_BIT(heth->Instance->MTL_QUEUE[queueIndex].MTLTXQ1ECR, ETH_MTLTXQ1ECR_CC);
1307   pCBSConfig->IdleSlope = READ_BIT(heth->Instance->MTL_QUEUE[queueIndex].MTLTXQQWR, ETH_MTLTXQ1QWR_ISCQW);
1308   pCBSConfig->SendSlope = READ_BIT(heth->Instance->MTL_QUEUE[queueIndex].MTLTXQ1SSCR, ETH_MTLTXQ1SSCR_SSC);
1309   pCBSConfig->HiCredit = READ_BIT(heth->Instance->MTL_QUEUE[queueIndex].MTLTXQ1HCR, ETH_MTLTXQ1HCR_HC);
1310   pCBSConfig->LoCredit = READ_BIT(heth->Instance->MTL_QUEUE[queueIndex].MTLTXQ1LCR, ETH_MTLTXQ1LCR_LC);
1311 
1312   return HAL_OK;
1313 }
1314 #endif /* HAL_ETH_USE_CBS */
1315 
1316 #ifdef HAL_ETH_USE_TAS
1317 /**
1318   * @brief  HAL ETH Enable EST feature.
1319   * @param  heth: pointer to a ETH_HandleTypeDef structure that contains
1320   *         the configuration information for ETHERNET module
1321   * @retval HAL status
1322   */
HAL_ETHEx_EnableEST(ETH_HandleTypeDef * heth)1323 HAL_StatusTypeDef HAL_ETHEx_EnableEST(ETH_HandleTypeDef *heth)
1324 {
1325   if (heth->gState == HAL_ETH_STATE_STARTED)
1326   {
1327     /* Enable Enhancement Scheduling Transmission */
1328     SET_BIT(heth->Instance->MTLESTCR, ETH_MTLESTCR_EEST);
1329   }
1330   else
1331   {
1332     return HAL_ERROR;
1333   }
1334 
1335   return HAL_OK;
1336 }
1337 
1338 /**
1339   * @brief  HAL ETH Disable EST feature.
1340   * @param  heth: pointer to a ETH_HandleTypeDef structure that contains
1341   *         the configuration information for ETHERNET module
1342   * @retval HAL status
1343   */
HAL_ETHEx_DisableEST(ETH_HandleTypeDef * heth)1344 HAL_StatusTypeDef HAL_ETHEx_DisableEST(ETH_HandleTypeDef *heth)
1345 {
1346   if (heth->gState == HAL_ETH_STATE_STARTED)
1347   {
1348     /* Disable Enhancement Scheduling Transmission */
1349     CLEAR_BIT(heth->Instance->MTLESTCR, ETH_MTLESTCR_EEST);
1350   }
1351   else
1352   {
1353     return HAL_ERROR;
1354   }
1355 
1356   return HAL_OK;
1357 }
1358 
1359 /**
1360   * @brief  HAL ETH Get the HW Depth of the Gate Control List.
1361   * @param  heth: pointer to a ETH_HandleTypeDef structure that contains
1362   *         the configuration information for ETHERNET module
1363   * @retval Depth of the Gate Control List
1364   */
HAL_ETHEx_GetGCLDepth(const ETH_HandleTypeDef * heth)1365 uint32_t HAL_ETHEx_GetGCLDepth(const ETH_HandleTypeDef *heth)
1366 {
1367   uint32_t gcldepth;
1368 
1369   /* get HW GCL depth from HW configuration */
1370   gcldepth = READ_BIT(heth->Instance->MACHWF3R, ETH_MACHWF3R_ESTDEP_Msk);
1371 
1372   switch (gcldepth)
1373   {
1374     case ETH_MACHWF3R_ESTDEP_64 :
1375       return 64;
1376     case ETH_MACHWF3R_ESTDEP_128 :
1377       return 128;
1378     case ETH_MACHWF3R_ESTDEP_256 :
1379       return 256;
1380     case ETH_MACHWF3R_ESTDEP_512 :
1381       return 512;
1382     case ETH_MACHWF3R_ESTDEP_1024 :
1383       return 1024;
1384     default :
1385       return 0;
1386   }
1387 }
1388 
1389 /**
1390   * @brief  HAL ETH Get the HW Width of the Time Interval field in the Gate Control List
1391   * @param  heth: pointer to a ETH_HandleTypeDef structure that contains
1392   *         the configuration information for ETHERNET module
1393   * @retval Width of the Time Interval field in the Gate Control List
1394   */
HAL_ETHEx_GetGCLWidthTimeInterval(const ETH_HandleTypeDef * heth)1395 uint32_t HAL_ETHEx_GetGCLWidthTimeInterval(const ETH_HandleTypeDef *heth)
1396 {
1397   uint32_t gclwidth;
1398 
1399   /* get HW GCL Width from HW configuration */
1400   gclwidth = READ_BIT(heth->Instance->MACHWF3R, ETH_MACHWF3R_ESTWID_Msk);
1401 
1402   switch (gclwidth)
1403   {
1404     case ETH_MACHWF3R_ESTWID_16 :
1405       return 16;
1406     case ETH_MACHWF3R_ESTWID_20 :
1407       return 20;
1408     case ETH_MACHWF3R_ESTWID_24 :
1409       return 24;
1410     default :
1411       return 0;
1412   }
1413 }
1414 
1415 /**
1416   * @brief  HAL ETH Check HW Completion Check
1417   */
ETHEx_ESTHWCompletionCheck(ETH_HandleTypeDef * heth)1418 static HAL_StatusTypeDef ETHEx_ESTHWCompletionCheck(ETH_HandleTypeDef *heth)
1419 {
1420   /* Get tick */
1421   uint32_t tickstart = HAL_GetTick();
1422 
1423   /* wait until the reset is done by Hardware */
1424   while (READ_BIT(heth->Instance->MTLESTGCLCR, ETH_MTLESTGCLCR_SRWO) != (uint32_t)RESET)
1425   {
1426     if ((HAL_GetTick() - tickstart) > ETH_HWRESET_TIMEOUT)
1427     {
1428       /* Set State as Error */
1429       heth->gState = HAL_ETH_STATE_ERROR;
1430       /* Return Error */
1431       return HAL_ERROR;
1432     }
1433   }
1434   return HAL_OK;
1435 }
1436 
1437 /**
1438   * @brief  HAL ETH Get GCL Registers values
1439   */
HAL_ETHEx_GetGCLRegisters(ETH_HandleTypeDef * heth,ETH_GCLConfigTypeDef * gclconf)1440 HAL_StatusTypeDef HAL_ETHEx_GetGCLRegisters(ETH_HandleTypeDef *heth, ETH_GCLConfigTypeDef *gclconf)
1441 {
1442   uint32_t mtlestgclctrl = ETH_MTLESTGCLCR_GCRR | ETH_MTLESTGCLCR_SRWO | ETH_MTLESTGCLCR_R1W0;
1443   uint32_t mtlestgclctrl_mask = ETH_MTLESTGCLCR_ADDR_Msk | ETH_MTLESTGCLCR_GCRR_Msk | ETH_MTLESTGCLCR_SRWO_Msk;
1444 
1445   /* Set BTR Low Address and start read operation */
1446   MODIFY_REG(heth->Instance->MTLESTGCLCR, mtlestgclctrl_mask, mtlestgclctrl | ETH_MTLESTGCLCR_ADDR_BTRLOW);
1447 
1448   /* wait for a HW reset Check */
1449   if (ETHEx_ESTHWCompletionCheck(heth) != HAL_OK)
1450   {
1451     return HAL_ERROR;
1452   }
1453   /* Get BTR Low value */
1454   gclconf->BaseTimeRegister = (uint32_t)READ_REG(heth->Instance->MTLESTGCLDR);
1455 
1456   /* Set BTR High Address and start read operation */
1457   MODIFY_REG(heth->Instance->MTLESTGCLCR, mtlestgclctrl_mask, mtlestgclctrl | ETH_MTLESTGCLCR_ADDR_BTRHIGH);
1458 
1459   /* wait for a HW reset Check */
1460   if (ETHEx_ESTHWCompletionCheck(heth) != HAL_OK)
1461   {
1462     return HAL_ERROR;
1463   }
1464   /* Get BTR High value */
1465   gclconf->BaseTimeRegister |= ((uint64_t)READ_REG(heth->Instance->MTLESTGCLDR) << 32U);
1466 
1467   /* Set CTR Low Address and start read operation */
1468   MODIFY_REG(heth->Instance->MTLESTGCLCR, mtlestgclctrl_mask, mtlestgclctrl | ETH_MTLESTGCLCR_ADDR_CTRLOW);
1469 
1470   /* wait for a HW reset Check */
1471   if (ETHEx_ESTHWCompletionCheck(heth) != HAL_OK)
1472   {
1473     return HAL_ERROR;
1474   }
1475   /* Get CTR Low value */
1476   gclconf->CycleTimeRegister = (uint32_t)READ_REG(heth->Instance->MTLESTGCLDR);
1477 
1478   /* Set CTR High Address and start read operation */
1479   MODIFY_REG(heth->Instance->MTLESTGCLCR, mtlestgclctrl_mask, mtlestgclctrl | ETH_MTLESTGCLCR_ADDR_CTRHIGH);
1480 
1481   /* wait for a HW reset Check */
1482   if (ETHEx_ESTHWCompletionCheck(heth) != HAL_OK)
1483   {
1484     return HAL_ERROR;
1485   }
1486   /* Get CTR High value */
1487   gclconf->CycleTimeRegister |= ((uint64_t)READ_REG(heth->Instance->MTLESTGCLDR) << 32U);
1488 
1489   /* Set TER Address and start read operation */
1490   MODIFY_REG(heth->Instance->MTLESTGCLCR, mtlestgclctrl_mask, mtlestgclctrl | ETH_MTLESTGCLCR_ADDR_TER);
1491 
1492   /* wait for a HW reset Check */
1493   if (ETHEx_ESTHWCompletionCheck(heth) != HAL_OK)
1494   {
1495     return HAL_ERROR;
1496   }
1497   /* Get TER value */
1498   gclconf->TimeExtensionRegister = (uint32_t)READ_REG(heth->Instance->MTLESTGCLDR);
1499 
1500   /* Set LLR Address and start read operation */
1501   MODIFY_REG(heth->Instance->MTLESTGCLCR, mtlestgclctrl_mask, mtlestgclctrl | ETH_MTLESTGCLCR_ADDR_LLR);
1502 
1503   /* wait for a HW reset Check */
1504   if (ETHEx_ESTHWCompletionCheck(heth) != HAL_OK)
1505   {
1506     return HAL_ERROR;
1507   }
1508   /* Get TER value */
1509   gclconf->ListLengthRegister = (uint32_t)READ_REG(heth->Instance->MTLESTGCLDR);
1510 
1511   return HAL_OK;
1512 }
1513 
1514 /**
1515   * @brief  HAL ETH Set GCL Registers values
1516   */
HAL_ETHEx_SetGCLRegisters(ETH_HandleTypeDef * heth,const ETH_GCLConfigTypeDef * gclconf)1517 HAL_StatusTypeDef HAL_ETHEx_SetGCLRegisters(ETH_HandleTypeDef *heth, const ETH_GCLConfigTypeDef *gclconf)
1518 {
1519   uint32_t mtlestgclctrl = ETH_MTLESTGCLCR_GCRR | ETH_MTLESTGCLCR_SRWO;
1520   uint32_t mtlestgclctrl_mask = ETH_MTLESTGCLCR_ADDR_Msk | ETH_MTLESTGCLCR_GCRR_Msk | ETH_MTLESTGCLCR_SRWO_Msk;
1521 
1522   /* Set BTR Low value */
1523   WRITE_REG(heth->Instance->MTLESTGCLDR, (uint32_t)gclconf->BaseTimeRegister);
1524 
1525   /* Set BTR Low Address and start write operation */
1526   MODIFY_REG(heth->Instance->MTLESTGCLCR, mtlestgclctrl_mask, mtlestgclctrl | ETH_MTLESTGCLCR_ADDR_BTRLOW);
1527 
1528   /* wait for a HW reset Check */
1529   if (ETHEx_ESTHWCompletionCheck(heth) != HAL_OK)
1530   {
1531     return HAL_ERROR;
1532   }
1533 
1534   /* Set BTR High value */
1535   WRITE_REG(heth->Instance->MTLESTGCLDR, ((uint32_t)(gclconf->BaseTimeRegister >> 32)));
1536 
1537   /* Set BTR High Address and start write operation */
1538   MODIFY_REG(heth->Instance->MTLESTGCLCR, mtlestgclctrl_mask, mtlestgclctrl | ETH_MTLESTGCLCR_ADDR_BTRHIGH);
1539 
1540   /* wait for a HW reset Check */
1541   if (ETHEx_ESTHWCompletionCheck(heth) != HAL_OK)
1542   {
1543     return HAL_ERROR;
1544   }
1545 
1546   /* Set CTR Low value */
1547   WRITE_REG(heth->Instance->MTLESTGCLDR, (uint32_t)gclconf->CycleTimeRegister);
1548 
1549   /* Set CTR Low Address and start write operation */
1550   MODIFY_REG(heth->Instance->MTLESTGCLCR, mtlestgclctrl_mask, mtlestgclctrl | ETH_MTLESTGCLCR_ADDR_CTRLOW);
1551 
1552   /* wait for a HW reset Check */
1553   if (ETHEx_ESTHWCompletionCheck(heth) != HAL_OK)
1554   {
1555     return HAL_ERROR;
1556   }
1557 
1558   /* Set CTR High value */
1559   WRITE_REG(heth->Instance->MTLESTGCLDR, ((uint32_t)(gclconf->CycleTimeRegister >> 32)));
1560 
1561   /* Set CTR High Address and start write operation */
1562   MODIFY_REG(heth->Instance->MTLESTGCLCR, mtlestgclctrl_mask, mtlestgclctrl | ETH_MTLESTGCLCR_ADDR_CTRHIGH);
1563 
1564   /* wait for a HW reset Check */
1565   if (ETHEx_ESTHWCompletionCheck(heth) != HAL_OK)
1566   {
1567     return HAL_ERROR;
1568   }
1569 
1570   /* Set TER value */
1571   WRITE_REG(heth->Instance->MTLESTGCLDR, (uint32_t)gclconf->TimeExtensionRegister);
1572 
1573   /* Set TER Address and start write operation */
1574   MODIFY_REG(heth->Instance->MTLESTGCLCR, mtlestgclctrl_mask, mtlestgclctrl | ETH_MTLESTGCLCR_ADDR_TER);
1575 
1576   /* Set LLR value */
1577   WRITE_REG(heth->Instance->MTLESTGCLDR, (uint32_t)gclconf->ListLengthRegister);
1578 
1579   /* Set LLR Address and start write operation */
1580   MODIFY_REG(heth->Instance->MTLESTGCLCR, mtlestgclctrl_mask, mtlestgclctrl | ETH_MTLESTGCLCR_ADDR_LLR);
1581 
1582   /* wait for a HW reset Check */
1583   if (ETHEx_ESTHWCompletionCheck(heth) != HAL_OK)
1584   {
1585     return HAL_ERROR;
1586   }
1587 
1588   return HAL_OK;
1589 }
1590 
1591 /**
1592   * @brief  HAL ETH Set GCL configuration
1593   */
HAL_ETHEx_SetGCLConfig(ETH_HandleTypeDef * heth,ETH_GCLConfigTypeDef * gclconf)1594 HAL_StatusTypeDef HAL_ETHEx_SetGCLConfig(ETH_HandleTypeDef *heth, ETH_GCLConfigTypeDef *gclconf)
1595 {
1596   uint32_t glcidx;
1597   uint32_t data;
1598 
1599   for (glcidx = 0; glcidx < gclconf->ListLengthRegister; glcidx++)
1600   {
1601     /* Set data : TC1 + TC0 + TimeInterval */
1602     data = gclconf->opList->Interval | (gclconf->opList->Gate << ETH_EST_WID_MAX);
1603 
1604     /* Set data to MTLESTGCLDR register */
1605     WRITE_REG(heth->Instance->MTLESTGCLDR, data);
1606 
1607     /* Set Address and start write operation */
1608     MODIFY_REG(heth->Instance->MTLESTGCLCR, ETH_MTLESTGCLCR_ADDR_Msk | ETH_MTLESTGCLCR_SRWO_Msk,
1609                (glcidx << ETH_MTLESTGCLCR_ADDR_Pos) | ETH_MTLESTGCLCR_SRWO);
1610 
1611     /* wait for a HW completion Check */
1612     if (ETHEx_ESTHWCompletionCheck(heth) != HAL_OK)
1613     {
1614       return HAL_ERROR;
1615     }
1616 
1617     /* If ok, Move to the next GLC in the list */
1618     (gclconf->opList)++;
1619   }
1620 
1621   if (HAL_ETHEx_SetGCLRegisters(heth, gclconf) != HAL_OK)
1622   {
1623     return HAL_ERROR;
1624   }
1625 
1626   return HAL_OK;
1627 }
1628 
1629 /**
1630   * @brief  HAL ETH Set Enhancement Scheduling Traffic Configuration
1631   */
ETHEx_SetESTConfig(ETH_HandleTypeDef * heth,ETH_ESTConfigTypeDef * estconf)1632 static HAL_StatusTypeDef ETHEx_SetESTConfig(ETH_HandleTypeDef *heth, ETH_ESTConfigTypeDef *estconf)
1633 {
1634   uint32_t estregval;
1635 
1636   /* Check on GCL list Length */
1637   if (estconf->GCLRegisters.ListLengthRegister > ETH_EST_DEP_MAX)
1638   {
1639     return HAL_ERROR;
1640   }
1641   /* Check on opList */
1642   if (estconf->GCLRegisters.opList == NULL)
1643   {
1644     return HAL_ERROR;
1645   }
1646   /* Check on completion of switch to the S/W owned list */
1647   if (READ_BIT(heth->Instance->MTLESTCR, ETH_MTLESTCR_SSWL) != (uint32_t)RESET)
1648   {
1649     return HAL_ERROR;
1650   }
1651 
1652   /* Programming the GCL and GCL-linked registers */
1653   if (HAL_ETHEx_SetGCLConfig(heth, &estconf->GCLRegisters) != HAL_OK)
1654   {
1655     return HAL_ERROR;
1656   }
1657 
1658   /* Set EST Configuration */
1659   estregval = ((estconf->SwitchToSWOL << 1) |
1660                ((uint32_t)estconf->NotDropFramesDuringFrameSizeError << 4) |
1661                ((uint32_t)estconf->DropFramesCausingError << 5) |
1662                (estconf->LoopCountSchedulingError) |
1663                (estconf->TimeIntervalLeftShift << 8) |
1664                (estconf->CurrentTimeOffset << 12) |
1665                (((uint32_t)(1000000000U / estconf->PTPTimeOffset) * 6U) << 24));
1666 
1667   /* Write to MTLESTCR */
1668   MODIFY_REG(heth->Instance->MTLESTCR, ETH_MTLESTCR_MASK, estregval);
1669 
1670   /* Get Overhead bytes value */
1671   estregval = estconf->OverheadBytesValue;
1672 
1673   /* Write to MTLESTECR */
1674   MODIFY_REG(heth->Instance->MTLESTECR, ETH_MTLESTECR_OVHD_Msk, estregval);
1675 
1676   /* Enable Enhancement Scheduling Traffic feature */
1677   if (HAL_ETHEx_EnableEST(heth) != HAL_OK)
1678   {
1679     return HAL_ERROR;
1680   }
1681 
1682   return HAL_OK;
1683 }
1684 
1685 /**
1686   * @brief  Set the EST configuration.
1687   * @param  heth: pointer to a ETH_HandleTypeDef structure that contains
1688   *         the configuration information for ETHERNET module
1689   * @param  estconf: pointer to a ETH_ESTConfigTypeDef structure that contains
1690   *         the configuration of the EST algorithm.
1691   * @retval HAL status
1692   */
HAL_ETHEx_SetESTConfig(ETH_HandleTypeDef * heth,ETH_ESTConfigTypeDef * estconf)1693 HAL_StatusTypeDef HAL_ETHEx_SetESTConfig(ETH_HandleTypeDef *heth,  ETH_ESTConfigTypeDef *estconf)
1694 {
1695   if (estconf == NULL)
1696   {
1697     return HAL_ERROR;
1698   }
1699 
1700   if (heth->gState == HAL_ETH_STATE_STARTED)
1701   {
1702     if (ETHEx_SetESTConfig(heth, estconf) != HAL_OK)
1703     {
1704       return HAL_ERROR;
1705     }
1706   }
1707   else
1708   {
1709     return HAL_ERROR;
1710   }
1711 
1712   return HAL_OK;
1713 }
1714 #endif /* HAL_ETH_USE_TAS */
1715 
1716 #ifdef HAL_ETH_USE_FPE
1717 /**
1718   * @brief  Enable FPE feature.
1719   * @param  heth: pointer to a ETH_HandleTypeDef structure that contains
1720   *         the configuration information for ETHERNET module
1721   * @retval HAL status
1722   */
HAL_ETHEx_EnableFPE(ETH_HandleTypeDef * heth)1723 HAL_StatusTypeDef HAL_ETHEx_EnableFPE(ETH_HandleTypeDef *heth)
1724 {
1725   if (heth->gState == HAL_ETH_STATE_STARTED)
1726   {
1727     /* Enable Tx Frame Preemption feature */
1728     SET_BIT(heth->Instance->MACFPECSR, ETH_MACFPECSR_EFPE);
1729   }
1730   else
1731   {
1732     return HAL_ERROR;
1733   }
1734 
1735   return HAL_OK;
1736 }
1737 
1738 /**
1739   * @brief  Disable FPE feature.
1740   * @param  heth: pointer to a ETH_HandleTypeDef structure that contains
1741   *         the configuration information for ETHERNET module
1742   * @retval HAL status
1743   */
HAL_ETHEx_DisableFPE(ETH_HandleTypeDef * heth)1744 HAL_StatusTypeDef HAL_ETHEx_DisableFPE(ETH_HandleTypeDef *heth)
1745 {
1746   if (heth->gState == HAL_ETH_STATE_STARTED)
1747   {
1748     /* Disable Tx Frame Preemption feature */
1749     CLEAR_BIT(heth->Instance->MACFPECSR, ETH_MACFPECSR_EFPE);
1750   }
1751   else
1752   {
1753     return HAL_ERROR;
1754   }
1755 
1756   return HAL_OK;
1757 }
1758 
1759 /**
1760   * @brief  Get the FPE configuration.
1761   * @param  heth: pointer to a ETH_HandleTypeDef structure that contains
1762   *         the configuration information for ETHERNET module
1763   * @param  fpeconf: pointer to a ETH_FPEConfigTypeDef structure that contains
1764   *         the configuration of the FPE Feature.
1765   * @retval HAL status
1766   */
HAL_ETHEx_GetFPEConfig(ETH_HandleTypeDef * heth,ETH_FPEConfigTypeDef * fpeconf)1767 HAL_StatusTypeDef HAL_ETHEx_GetFPEConfig(ETH_HandleTypeDef *heth,  ETH_FPEConfigTypeDef *fpeconf)
1768 {
1769   if (fpeconf == NULL)
1770   {
1771     return HAL_ERROR;
1772   }
1773 
1774   fpeconf->AdditionalFragmentSize = READ_BIT(heth->Instance->MTLFPECSR, ETH_MTLFPECSR_AFSZ);
1775   fpeconf->PreemptionClassification = READ_BIT(heth->Instance->MTLFPECSR, ETH_MTLFPECSR_PEC);
1776   fpeconf->HoldReleaseStatus = READ_BIT(heth->Instance->MTLFPECSR, ETH_MTLFPECSR_HRS);
1777 
1778   fpeconf->HoldAdvance = READ_BIT(heth->Instance->MTLFPEAR, ETH_MTLFPEAR_HADV);
1779   fpeconf->ReleaseAdvance = READ_BIT(heth->Instance->MTLFPEAR, ETH_MTLFPEAR_RADV);
1780 
1781   fpeconf->SendVerifymPacket = ((READ_BIT(heth->Instance->MACFPECSR,
1782                                           ETH_MACFPECSR_SVER) >> ETH_MACFPECSR_SVER_Pos) > 0U) ? ENABLE : DISABLE;
1783   fpeconf->SendRespondmPacket = ((READ_BIT(heth->Instance->MACFPECSR,
1784                                            ETH_MACFPECSR_SRSP) >> ETH_MACFPECSR_SRSP_Pos) > 0U) ? ENABLE : DISABLE;
1785   return HAL_OK;
1786 }
1787 
ETHEx_SetFPEConfig(ETH_HandleTypeDef * heth,ETH_FPEConfigTypeDef * fpeconf)1788 static void ETHEx_SetFPEConfig(ETH_HandleTypeDef *heth, ETH_FPEConfigTypeDef *fpeconf)
1789 {
1790   uint32_t fperegval;
1791 
1792   fperegval = fpeconf->PreemptionClassification | fpeconf->AdditionalFragmentSize;
1793 
1794   /* Write to MTLFPECSR */
1795   WRITE_REG(heth->Instance->MTLFPECSR, fperegval);
1796 
1797   fperegval = fpeconf->HoldAdvance | fpeconf->ReleaseAdvance;
1798 
1799   /* Write to MTLFPEAR */
1800   WRITE_REG(heth->Instance->MTLFPEAR, fperegval);
1801 
1802   fperegval = ((uint32_t)((fpeconf->SendVerifymPacket == ENABLE) ? 1U : 0U) << 1) |
1803               ((uint32_t)((fpeconf->SendRespondmPacket == ENABLE) ? 1U : 0U) << 2);
1804 
1805   /* Write to MACFPECSR */
1806   MODIFY_REG(heth->Instance->MACFPECSR, ETH_MACFPECSR_SVER_Msk | ETH_MACFPECSR_SRSP_Msk, fperegval);
1807 }
1808 
1809 /**
1810   * @brief  Set the FPE configuration.
1811   * @param  heth: pointer to a ETH_HandleTypeDef structure that contains
1812   *         the configuration information for ETHERNET module
1813   * @param  fpeconf: pointer to a ETH_FPEConfigTypeDef structure that contains
1814   *         the configuration of the FPE Feature.
1815   * @retval HAL status
1816   */
HAL_ETHEx_SetFPEConfig(ETH_HandleTypeDef * heth,ETH_FPEConfigTypeDef * fpeconf)1817 HAL_StatusTypeDef HAL_ETHEx_SetFPEConfig(ETH_HandleTypeDef *heth,  ETH_FPEConfigTypeDef *fpeconf)
1818 {
1819   if (fpeconf == NULL)
1820   {
1821     return HAL_ERROR;
1822   }
1823 
1824   if (heth->gState == HAL_ETH_STATE_STARTED)
1825   {
1826     ETHEx_SetFPEConfig(heth, fpeconf);
1827   }
1828   else
1829   {
1830     return HAL_ERROR;
1831   }
1832 
1833   return HAL_OK;
1834 }
1835 #endif /* HAL_ETH_USE_FPE */
1836 /**
1837   * @}
1838   */
1839 /**
1840   * @}
1841   */
1842 
1843 /**
1844   * @}
1845   */
1846 
1847 /**
1848   * @}
1849   */
1850 
1851 #endif /* ETH1 */
1852 
1853 #endif /* HAL_ETH_MODULE_ENABLED */
1854 /**
1855   * @}
1856   */
1857