1 /**
2   ******************************************************************************
3   * @file    stm32h5xx_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 "stm32h5xx_hal.h"
22 
23 /** @addtogroup STM32H5xx_HAL_Driver
24   * @{
25   */
26 
27 #ifdef HAL_ETH_MODULE_ENABLED
28 
29 #if defined(ETH)
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_MACL3L4CR_L4PEN | ETH_MACL3L4CR_L4SPM | \
42                               ETH_MACL3L4CR_L4SPIM | ETH_MACL3L4CR_L4DPM | \
43                               ETH_MACL3L4CR_L4DPIM)
44 
45 #define ETH_MACL3CR_MASK     (ETH_MACL3L4CR_L3PEN | ETH_MACL3L4CR_L3SAM | \
46                               ETH_MACL3L4CR_L3SAIM | ETH_MACL3L4CR_L3DAM | \
47                               ETH_MACL3L4CR_L3DAIM | ETH_MACL3L4CR_L3HSBM | \
48                               ETH_MACL3L4CR_L3HDBM)
49 
50 #define ETH_MACRXVLAN_MASK (ETH_MACVTR_EIVLRXS | ETH_MACVTR_EIVLS | \
51                             ETH_MACVTR_ERIVLT | ETH_MACVTR_EDVLP | \
52                             ETH_MACVTR_VTHM | ETH_MACVTR_EVLRXS | \
53                             ETH_MACVTR_EVLS | ETH_MACVTR_DOVLTC | \
54                             ETH_MACVTR_ERSVLM | ETH_MACVTR_ESVL | \
55                             ETH_MACVTR_VTIM | ETH_MACVTR_ETV)
56 
57 #define ETH_MACTXVLAN_MASK (ETH_MACVIR_VLTI | ETH_MACVIR_CSVL | \
58                             ETH_MACVIR_VLP | ETH_MACVIR_VLC)
59 
60 #define ETH_MAC_L4_SRSP_MASK          0x0000FFFFU
61 #define ETH_MAC_L4_DSTP_MASK          0xFFFF0000U
62 /**
63   * @}
64   */
65 
66 /* Private macros ------------------------------------------------------------*/
67 /* Private function prototypes -----------------------------------------------*/
68 /* Exported functions ---------------------------------------------------------*/
69 /** @defgroup ETHEx_Exported_Functions ETH Extended Exported Functions
70   * @{
71   */
72 
73 /** @defgroup ETHEx_Exported_Functions_Group1 Extended features functions
74   * @brief    Extended features functions
75   *
76 @verbatim
77  ===============================================================================
78                       ##### Extended features functions #####
79  ===============================================================================
80     [..] This section provides functions allowing to:
81       (+) Configure ARP offload module
82       (+) Configure L3 and L4 filters
83       (+) Configure Extended VLAN features
84       (+) Configure Energy Efficient Ethernet module
85 
86 @endverbatim
87   * @{
88   */
89 
90 /**
91   * @brief  Enables ARP Offload.
92   * @param  heth: pointer to a ETH_HandleTypeDef structure that contains
93   *         the configuration information for ETHERNET module
94   * @retval None
95   */
96 
HAL_ETHEx_EnableARPOffload(ETH_HandleTypeDef * heth)97 void HAL_ETHEx_EnableARPOffload(ETH_HandleTypeDef *heth)
98 {
99   SET_BIT(heth->Instance->MACCR, ETH_MACCR_ARP);
100 }
101 
102 /**
103   * @brief  Disables ARP Offload.
104   * @param  heth: pointer to a ETH_HandleTypeDef structure that contains
105   *         the configuration information for ETHERNET module
106   * @retval None
107   */
HAL_ETHEx_DisableARPOffload(ETH_HandleTypeDef * heth)108 void HAL_ETHEx_DisableARPOffload(ETH_HandleTypeDef *heth)
109 {
110   CLEAR_BIT(heth->Instance->MACCR, ETH_MACCR_ARP);
111 }
112 
113 /**
114   * @brief  Set the ARP Match IP address
115   * @param  heth: pointer to a ETH_HandleTypeDef structure that contains
116   *         the configuration information for ETHERNET module
117   * @param  IpAddress: IP Address to be matched for incoming ARP requests
118   * @retval None
119   */
HAL_ETHEx_SetARPAddressMatch(ETH_HandleTypeDef * heth,uint32_t IpAddress)120 void HAL_ETHEx_SetARPAddressMatch(ETH_HandleTypeDef *heth, uint32_t IpAddress)
121 {
122   WRITE_REG(heth->Instance->MACARPAR, IpAddress);
123 }
124 
125 /**
126   * @brief  Configures the L4 Filter, this function allow to:
127   *         set the layer 4 protocol to be matched (TCP or UDP)
128   *         enable/disable L4 source/destination port perfect/inverse match.
129   * @param  heth: pointer to a ETH_HandleTypeDef structure that contains
130   *         the configuration information for ETHERNET module
131   * @param  Filter: L4 filter to configured, this parameter must be one of the following
132   *           ETH_L4_FILTER_0
133   *           ETH_L4_FILTER_1
134   * @param  pL4FilterConfig: pointer to a ETH_L4FilterConfigTypeDef structure
135   *         that contains L4 filter configuration.
136   * @retval HAL status
137   */
HAL_ETHEx_SetL4FilterConfig(ETH_HandleTypeDef * heth,uint32_t Filter,const ETH_L4FilterConfigTypeDef * pL4FilterConfig)138 HAL_StatusTypeDef HAL_ETHEx_SetL4FilterConfig(ETH_HandleTypeDef *heth, uint32_t Filter,
139                                               const ETH_L4FilterConfigTypeDef *pL4FilterConfig)
140 {
141   if (pL4FilterConfig == NULL)
142   {
143     return HAL_ERROR;
144   }
145 
146   if (Filter == ETH_L4_FILTER_0)
147   {
148     /* Write configuration to MACL3L4C0R register */
149     MODIFY_REG(heth->Instance->MACL3L4C0R, ETH_MACL4CR_MASK, (pL4FilterConfig->Protocol |
150                                                               pL4FilterConfig->SrcPortFilterMatch |
151                                                               pL4FilterConfig->DestPortFilterMatch));
152 
153     /* Write configuration to MACL4A0R register */
154     WRITE_REG(heth->Instance->MACL4A0R, (pL4FilterConfig->SourcePort | (pL4FilterConfig->DestinationPort << 16)));
155 
156   }
157   else /* Filter == ETH_L4_FILTER_1 */
158   {
159     /* Write configuration to MACL3L4C1R register */
160     MODIFY_REG(heth->Instance->MACL3L4C1R, ETH_MACL4CR_MASK, (pL4FilterConfig->Protocol |
161                                                               pL4FilterConfig->SrcPortFilterMatch |
162                                                               pL4FilterConfig->DestPortFilterMatch));
163 
164     /* Write configuration to MACL4A1R register */
165     WRITE_REG(heth->Instance->MACL4A1R, (pL4FilterConfig->SourcePort | (pL4FilterConfig->DestinationPort << 16)));
166   }
167 
168   /* Enable L4 filter */
169   SET_BIT(heth->Instance->MACPFR, ETH_MACPFR_IPFE);
170 
171   return HAL_OK;
172 }
173 
174 /**
175   * @brief  Configures the L4 Filter, this function allow to:
176   *         set the layer 4 protocol to be matched (TCP or UDP)
177   *         enable/disable L4 source/destination port perfect/inverse match.
178   * @param  heth: pointer to a ETH_HandleTypeDef structure that contains
179   *         the configuration information for ETHERNET module
180   * @param  Filter: L4 filter to configured, this parameter must be one of the following
181   *           ETH_L4_FILTER_0
182   *           ETH_L4_FILTER_1
183   * @param  pL4FilterConfig: pointer to a ETH_L4FilterConfigTypeDef structure
184   *         that contains L4 filter configuration.
185   * @retval HAL status
186   */
HAL_ETHEx_GetL4FilterConfig(const ETH_HandleTypeDef * heth,uint32_t Filter,ETH_L4FilterConfigTypeDef * pL4FilterConfig)187 HAL_StatusTypeDef HAL_ETHEx_GetL4FilterConfig(const ETH_HandleTypeDef *heth, uint32_t Filter,
188                                               ETH_L4FilterConfigTypeDef *pL4FilterConfig)
189 {
190   if (pL4FilterConfig == NULL)
191   {
192     return HAL_ERROR;
193   }
194 
195   if (Filter == ETH_L4_FILTER_0)
196   {
197     /* Get configuration from MACL3L4C0R register */
198     pL4FilterConfig->Protocol = READ_BIT(heth->Instance->MACL3L4C0R, ETH_MACL3L4CR_L4PEN);
199     pL4FilterConfig->DestPortFilterMatch = READ_BIT(heth->Instance->MACL3L4C0R,
200                                                     (ETH_MACL3L4CR_L4DPM | ETH_MACL3L4CR_L4DPIM));
201     pL4FilterConfig->SrcPortFilterMatch = READ_BIT(heth->Instance->MACL3L4C0R,
202                                                    (ETH_MACL3L4CR_L4SPM | ETH_MACL3L4CR_L4SPIM));
203 
204     /* Get configuration from MACL4A0R register */
205     pL4FilterConfig->DestinationPort = (READ_BIT(heth->Instance->MACL4A0R, ETH_MAC_L4_DSTP_MASK) >> 16);
206     pL4FilterConfig->SourcePort = READ_BIT(heth->Instance->MACL4A0R, ETH_MAC_L4_SRSP_MASK);
207   }
208   else /* Filter == ETH_L4_FILTER_1 */
209   {
210     /* Get configuration from MACL3L4C1R register */
211     pL4FilterConfig->Protocol = READ_BIT(heth->Instance->MACL3L4C1R, ETH_MACL3L4CR_L4PEN);
212     pL4FilterConfig->DestPortFilterMatch = READ_BIT(heth->Instance->MACL3L4C1R,
213                                                     (ETH_MACL3L4CR_L4DPM | ETH_MACL3L4CR_L4DPIM));
214     pL4FilterConfig->SrcPortFilterMatch = READ_BIT(heth->Instance->MACL3L4C1R,
215                                                    (ETH_MACL3L4CR_L4SPM | ETH_MACL3L4CR_L4SPIM));
216 
217     /* Get configuration from MACL4A1R register */
218     pL4FilterConfig->DestinationPort = (READ_BIT(heth->Instance->MACL4A1R, ETH_MAC_L4_DSTP_MASK) >> 16);
219     pL4FilterConfig->SourcePort = READ_BIT(heth->Instance->MACL4A1R, ETH_MAC_L4_SRSP_MASK);
220   }
221 
222   return HAL_OK;
223 }
224 
225 /**
226   * @brief  Configures the L3 Filter, this function allow to:
227   *         set the layer 3 protocol to be matched (IPv4 or IPv6)
228   *         enable/disable L3 source/destination port perfect/inverse match.
229   * @param  heth: pointer to a ETH_HandleTypeDef structure that contains
230   *         the configuration information for ETHERNET module
231   * @param  Filter: L3 filter to configured, this parameter must be one of the following
232   *           ETH_L3_FILTER_0
233   *           ETH_L3_FILTER_1
234   * @param  pL3FilterConfig: pointer to a ETH_L3FilterConfigTypeDef structure
235   *         that contains L3 filter configuration.
236   * @retval HAL status
237   */
HAL_ETHEx_SetL3FilterConfig(ETH_HandleTypeDef * heth,uint32_t Filter,const ETH_L3FilterConfigTypeDef * pL3FilterConfig)238 HAL_StatusTypeDef HAL_ETHEx_SetL3FilterConfig(ETH_HandleTypeDef *heth, uint32_t Filter,
239                                               const ETH_L3FilterConfigTypeDef *pL3FilterConfig)
240 {
241   if (pL3FilterConfig == NULL)
242   {
243     return HAL_ERROR;
244   }
245 
246   if (Filter == ETH_L3_FILTER_0)
247   {
248     /* Write configuration to MACL3L4C0R register */
249     MODIFY_REG(heth->Instance->MACL3L4C0R, ETH_MACL3CR_MASK, (pL3FilterConfig->Protocol |
250                                                               pL3FilterConfig->SrcAddrFilterMatch |
251                                                               pL3FilterConfig->DestAddrFilterMatch |
252                                                               (pL3FilterConfig->SrcAddrHigherBitsMatch << 6) |
253                                                               (pL3FilterConfig->DestAddrHigherBitsMatch << 11)));
254   }
255   else  /* Filter == ETH_L3_FILTER_1 */
256   {
257     /* Write configuration to MACL3L4C1R register */
258     MODIFY_REG(heth->Instance->MACL3L4C1R, ETH_MACL3CR_MASK, (pL3FilterConfig->Protocol |
259                                                               pL3FilterConfig->SrcAddrFilterMatch |
260                                                               pL3FilterConfig->DestAddrFilterMatch |
261                                                               (pL3FilterConfig->SrcAddrHigherBitsMatch << 6) |
262                                                               (pL3FilterConfig->DestAddrHigherBitsMatch << 11)));
263   }
264 
265   if (Filter == ETH_L3_FILTER_0)
266   {
267     /* Check if IPv6 protocol is selected */
268     if (pL3FilterConfig->Protocol != ETH_L3_IPV4_MATCH)
269     {
270       /* Set the IPv6 address match */
271       /* Set Bits[31:0] of 128-bit IP addr */
272       WRITE_REG(heth->Instance->MACL3A0R0R, pL3FilterConfig->Ip6Addr[0]);
273       /* Set Bits[63:32] of 128-bit IP addr */
274       WRITE_REG(heth->Instance->MACL3A1R0R, pL3FilterConfig->Ip6Addr[1]);
275       /* update Bits[95:64] of 128-bit IP addr */
276       WRITE_REG(heth->Instance->MACL3A2R0R, pL3FilterConfig->Ip6Addr[2]);
277       /* update Bits[127:96] of 128-bit IP addr */
278       WRITE_REG(heth->Instance->MACL3A3R0R, pL3FilterConfig->Ip6Addr[3]);
279     }
280     else /* IPv4 protocol is selected */
281     {
282       /* Set the IPv4 source address match */
283       WRITE_REG(heth->Instance->MACL3A0R0R, pL3FilterConfig->Ip4SrcAddr);
284       /* Set the IPv4 destination address match */
285       WRITE_REG(heth->Instance->MACL3A1R0R, pL3FilterConfig->Ip4DestAddr);
286     }
287   }
288   else  /* Filter == ETH_L3_FILTER_1 */
289   {
290     /* Check if IPv6 protocol is selected */
291     if (pL3FilterConfig->Protocol != ETH_L3_IPV4_MATCH)
292     {
293       /* Set the IPv6 address match */
294       /* Set Bits[31:0] of 128-bit IP addr */
295       WRITE_REG(heth->Instance->MACL3A0R1R, pL3FilterConfig->Ip6Addr[0]);
296       /* Set Bits[63:32] of 128-bit IP addr */
297       WRITE_REG(heth->Instance->MACL3A1R1R, pL3FilterConfig->Ip6Addr[1]);
298       /* update Bits[95:64] of 128-bit IP addr */
299       WRITE_REG(heth->Instance->MACL3A1R1R, pL3FilterConfig->Ip6Addr[2]);
300       /* update Bits[127:96] of 128-bit IP addr */
301       WRITE_REG(heth->Instance->MACL3A1R1R, pL3FilterConfig->Ip6Addr[3]);
302     }
303     else /* IPv4 protocol is selected */
304     {
305       /* Set the IPv4 source address match */
306       WRITE_REG(heth->Instance->MACL3A0R1R, pL3FilterConfig->Ip4SrcAddr);
307       /* Set the IPv4 destination address match */
308       WRITE_REG(heth->Instance->MACL3A0R1R, pL3FilterConfig->Ip4DestAddr);
309 
310     }
311   }
312 
313   /* Enable L3 filter */
314   SET_BIT(heth->Instance->MACPFR, ETH_MACPFR_IPFE);
315 
316   return HAL_OK;
317 }
318 
319 /**
320   * @brief  Configures the L3 Filter, this function allow to:
321   *         set the layer 3 protocol to be matched (IPv4 or IPv6)
322   *         enable/disable L3 source/destination port perfect/inverse match.
323   * @param  heth: pointer to a ETH_HandleTypeDef structure that contains
324   *         the configuration information for ETHERNET module
325   * @param  Filter: L3 filter to configured, this parameter must be one of the following
326   *           ETH_L3_FILTER_0
327   *           ETH_L3_FILTER_1
328   * @param  pL3FilterConfig: pointer to a ETH_L3FilterConfigTypeDef structure
329   *         that will contain the L3 filter configuration.
330   * @retval HAL status
331   */
HAL_ETHEx_GetL3FilterConfig(const ETH_HandleTypeDef * heth,uint32_t Filter,ETH_L3FilterConfigTypeDef * pL3FilterConfig)332 HAL_StatusTypeDef HAL_ETHEx_GetL3FilterConfig(const ETH_HandleTypeDef *heth, uint32_t Filter,
333                                               ETH_L3FilterConfigTypeDef *pL3FilterConfig)
334 {
335   if (pL3FilterConfig == NULL)
336   {
337     return HAL_ERROR;
338   }
339   pL3FilterConfig->Protocol = READ_BIT(*((__IO uint32_t *)(&(heth->Instance->MACL3L4C0R) + Filter)),
340                                        ETH_MACL3L4CR_L3PEN);
341   pL3FilterConfig->SrcAddrFilterMatch = READ_BIT(*((__IO uint32_t *)(&(heth->Instance->MACL3L4C0R) + Filter)),
342                                                  (ETH_MACL3L4CR_L3SAM | ETH_MACL3L4CR_L3SAIM));
343   pL3FilterConfig->DestAddrFilterMatch = READ_BIT(*((__IO uint32_t *)(&(heth->Instance->MACL3L4C0R) + Filter)),
344                                                   (ETH_MACL3L4CR_L3DAM | ETH_MACL3L4CR_L3DAIM));
345   pL3FilterConfig->SrcAddrHigherBitsMatch = (READ_BIT(*((__IO uint32_t *)(&(heth->Instance->MACL3L4C0R) + Filter)),
346                                                       ETH_MACL3L4CR_L3HSBM) >> 6);
347   pL3FilterConfig->DestAddrHigherBitsMatch = (READ_BIT(*((__IO uint32_t *)(&(heth->Instance->MACL3L4C0R) + Filter)),
348                                                        ETH_MACL3L4CR_L3HDBM) >> 11);
349 
350   if (Filter == ETH_L3_FILTER_0)
351   {
352     if (pL3FilterConfig->Protocol != ETH_L3_IPV4_MATCH)
353     {
354       WRITE_REG(pL3FilterConfig->Ip6Addr[0], heth->Instance->MACL3A0R0R);
355       WRITE_REG(pL3FilterConfig->Ip6Addr[1], heth->Instance->MACL3A1R0R);
356       WRITE_REG(pL3FilterConfig->Ip6Addr[2], heth->Instance->MACL3A2R0R);
357       WRITE_REG(pL3FilterConfig->Ip6Addr[3], heth->Instance->MACL3A3R0R);
358     }
359     else
360     {
361       WRITE_REG(pL3FilterConfig->Ip4SrcAddr, heth->Instance->MACL3A0R0R);
362       WRITE_REG(pL3FilterConfig->Ip4DestAddr, heth->Instance->MACL3A1R0R);
363     }
364   }
365   else /* ETH_L3_FILTER_1 */
366   {
367     if (pL3FilterConfig->Protocol != ETH_L3_IPV4_MATCH)
368     {
369       WRITE_REG(pL3FilterConfig->Ip6Addr[0], heth->Instance->MACL3A0R1R);
370       WRITE_REG(pL3FilterConfig->Ip6Addr[1], heth->Instance->MACL3A1R1R);
371       WRITE_REG(pL3FilterConfig->Ip6Addr[2], heth->Instance->MACL3A2R1R);
372       WRITE_REG(pL3FilterConfig->Ip6Addr[3], heth->Instance->MACL3A3R1R);
373     }
374     else
375     {
376       WRITE_REG(pL3FilterConfig->Ip4SrcAddr, heth->Instance->MACL3A0R1R);
377       WRITE_REG(pL3FilterConfig->Ip4DestAddr, heth->Instance->MACL3A1R1R);
378     }
379   }
380 
381   return HAL_OK;
382 }
383 
384 /**
385   * @brief  Enables L3 and L4 filtering process.
386   * @param  heth: pointer to a ETH_HandleTypeDef structure that contains
387   *         the configuration information for ETHERNET module
388   * @retval None.
389   */
HAL_ETHEx_EnableL3L4Filtering(ETH_HandleTypeDef * heth)390 void HAL_ETHEx_EnableL3L4Filtering(ETH_HandleTypeDef *heth)
391 {
392   /* Enable L3/L4 filter */
393   SET_BIT(heth->Instance->MACPFR, ETH_MACPFR_IPFE);
394 }
395 
396 /**
397   * @brief  Disables L3 and L4 filtering process.
398   * @param  heth: pointer to a ETH_HandleTypeDef structure that contains
399   *         the configuration information for ETHERNET module
400   * @retval None.
401   */
HAL_ETHEx_DisableL3L4Filtering(ETH_HandleTypeDef * heth)402 void HAL_ETHEx_DisableL3L4Filtering(ETH_HandleTypeDef *heth)
403 {
404   /* Disable L3/L4 filter */
405   CLEAR_BIT(heth->Instance->MACPFR, ETH_MACPFR_IPFE);
406 }
407 
408 /**
409   * @brief  Get the VLAN Configuration for Receive Packets.
410   * @param  heth: pointer to a ETH_HandleTypeDef structure that contains
411   *         the configuration information for ETHERNET module
412   * @param  pVlanConfig: pointer to a ETH_RxVLANConfigTypeDef structure
413   *         that will contain the VLAN filter configuration.
414   * @retval HAL status
415   */
HAL_ETHEx_GetRxVLANConfig(const ETH_HandleTypeDef * heth,ETH_RxVLANConfigTypeDef * pVlanConfig)416 HAL_StatusTypeDef HAL_ETHEx_GetRxVLANConfig(const ETH_HandleTypeDef *heth, ETH_RxVLANConfigTypeDef *pVlanConfig)
417 {
418   if (pVlanConfig == NULL)
419   {
420     return HAL_ERROR;
421   }
422 
423   pVlanConfig->InnerVLANTagInStatus = ((READ_BIT(heth->Instance->MACVTR,
424                                                  ETH_MACVTR_EIVLRXS) >> 31) == 0U) ? DISABLE : ENABLE;
425   pVlanConfig->StripInnerVLANTag  = READ_BIT(heth->Instance->MACVTR, ETH_MACVTR_EIVLS);
426   pVlanConfig->InnerVLANTag = ((READ_BIT(heth->Instance->MACVTR,
427                                          ETH_MACVTR_ERIVLT) >> 27) == 0U) ? DISABLE : ENABLE;
428   pVlanConfig->DoubleVLANProcessing = ((READ_BIT(heth->Instance->MACVTR,
429                                                  ETH_MACVTR_EDVLP) >> 26) == 0U) ? DISABLE : ENABLE;
430   pVlanConfig->VLANTagHashTableMatch = ((READ_BIT(heth->Instance->MACVTR,
431                                                   ETH_MACVTR_VTHM) >> 25) == 0U) ? DISABLE : ENABLE;
432   pVlanConfig->VLANTagInStatus = ((READ_BIT(heth->Instance->MACVTR,
433                                             ETH_MACVTR_EVLRXS) >> 24) == 0U) ? DISABLE : ENABLE;
434   pVlanConfig->StripVLANTag = READ_BIT(heth->Instance->MACVTR, ETH_MACVTR_EVLS);
435   pVlanConfig->VLANTypeCheck = READ_BIT(heth->Instance->MACVTR,
436                                         (ETH_MACVTR_DOVLTC | ETH_MACVTR_ERSVLM | ETH_MACVTR_ESVL));
437   pVlanConfig->VLANTagInverceMatch = ((READ_BIT(heth->Instance->MACVTR, ETH_MACVTR_VTIM) >> 17) == 0U)
438                                      ? DISABLE : ENABLE;
439 
440   return HAL_OK;
441 }
442 
443 /**
444   * @brief  Set the VLAN Configuration for Receive Packets.
445   * @param  heth: pointer to a ETH_HandleTypeDef structure that contains
446   *         the configuration information for ETHERNET module
447   * @param  pVlanConfig: pointer to a ETH_RxVLANConfigTypeDef structure
448   *         that contains VLAN filter configuration.
449   * @retval HAL status
450   */
HAL_ETHEx_SetRxVLANConfig(ETH_HandleTypeDef * heth,ETH_RxVLANConfigTypeDef * pVlanConfig)451 HAL_StatusTypeDef HAL_ETHEx_SetRxVLANConfig(ETH_HandleTypeDef *heth, ETH_RxVLANConfigTypeDef *pVlanConfig)
452 {
453   if (pVlanConfig == NULL)
454   {
455     return HAL_ERROR;
456   }
457 
458   /* Write config to MACVTR */
459   MODIFY_REG(heth->Instance->MACVTR, ETH_MACRXVLAN_MASK, (((uint32_t)pVlanConfig->InnerVLANTagInStatus << 31) |
460                                                           pVlanConfig->StripInnerVLANTag |
461                                                           ((uint32_t)pVlanConfig->InnerVLANTag << 27) |
462                                                           ((uint32_t)pVlanConfig->DoubleVLANProcessing << 26) |
463                                                           ((uint32_t)pVlanConfig->VLANTagHashTableMatch << 25) |
464                                                           ((uint32_t)pVlanConfig->VLANTagInStatus << 24) |
465                                                           pVlanConfig->StripVLANTag |
466                                                           pVlanConfig->VLANTypeCheck |
467                                                           ((uint32_t)pVlanConfig->VLANTagInverceMatch << 17)));
468 
469   return HAL_OK;
470 }
471 
472 /**
473   * @brief  Set the VLAN Hash Table
474   * @param  heth: pointer to a ETH_HandleTypeDef structure that contains
475   *         the configuration information for ETHERNET module
476   * @param  VLANHashTable: VLAN hash table 16 bit value
477   * @retval None
478   */
HAL_ETHEx_SetVLANHashTable(ETH_HandleTypeDef * heth,uint32_t VLANHashTable)479 void HAL_ETHEx_SetVLANHashTable(ETH_HandleTypeDef *heth, uint32_t VLANHashTable)
480 {
481   MODIFY_REG(heth->Instance->MACVHTR, ETH_MACVHTR_VLHT, VLANHashTable);
482 }
483 
484 /**
485   * @brief  Get the VLAN Configuration for Transmit Packets.
486   * @param  heth: pointer to a ETH_HandleTypeDef structure that contains
487   *         the configuration information for ETHERNET module
488   * @param  VLANTag: Selects the vlan tag, this parameter must be one of the following
489   *                 ETH_OUTER_TX_VLANTAG
490   *                 ETH_INNER_TX_VLANTAG
491   * @param  pVlanConfig: pointer to a ETH_TxVLANConfigTypeDef structure
492   *         that will contain the Tx VLAN filter configuration.
493   * @retval HAL Status.
494   */
HAL_ETHEx_GetTxVLANConfig(const ETH_HandleTypeDef * heth,uint32_t VLANTag,ETH_TxVLANConfigTypeDef * pVlanConfig)495 HAL_StatusTypeDef HAL_ETHEx_GetTxVLANConfig(const ETH_HandleTypeDef *heth, uint32_t VLANTag,
496                                             ETH_TxVLANConfigTypeDef *pVlanConfig)
497 {
498   if (pVlanConfig == NULL)
499   {
500     return HAL_ERROR;
501   }
502 
503   if (VLANTag == ETH_INNER_TX_VLANTAG)
504   {
505     pVlanConfig->SourceTxDesc = ((READ_BIT(heth->Instance->MACIVIR, ETH_MACVIR_VLTI) >> 20) == 0U) ? DISABLE : ENABLE;
506     pVlanConfig->SVLANType = ((READ_BIT(heth->Instance->MACIVIR, ETH_MACVIR_CSVL) >> 19) == 0U) ? DISABLE : ENABLE;
507     pVlanConfig->VLANTagControl = READ_BIT(heth->Instance->MACIVIR, (ETH_MACVIR_VLP | ETH_MACVIR_VLC));
508   }
509   else
510   {
511     pVlanConfig->SourceTxDesc = ((READ_BIT(heth->Instance->MACVIR, ETH_MACVIR_VLTI) >> 20) == 0U) ? DISABLE : ENABLE;
512     pVlanConfig->SVLANType = ((READ_BIT(heth->Instance->MACVIR, ETH_MACVIR_CSVL) >> 19) == 0U) ? DISABLE : ENABLE;
513     pVlanConfig->VLANTagControl = READ_BIT(heth->Instance->MACVIR, (ETH_MACVIR_VLP | ETH_MACVIR_VLC));
514   }
515 
516   return HAL_OK;;
517 }
518 
519 /**
520   * @brief  Set the VLAN Configuration for Transmit Packets.
521   * @param  heth: pointer to a ETH_HandleTypeDef structure that contains
522   *         the configuration information for ETHERNET module
523   * @param  VLANTag: Selects the vlan tag, this parameter must be one of the following
524   *                 ETH_OUTER_TX_VLANTAG
525   *                 ETH_INNER_TX_VLANTAG
526   * @param  pVlanConfig: pointer to a ETH_TxVLANConfigTypeDef structure
527   *         that contains Tx VLAN filter configuration.
528   * @retval HAL Status
529   */
HAL_ETHEx_SetTxVLANConfig(ETH_HandleTypeDef * heth,uint32_t VLANTag,const ETH_TxVLANConfigTypeDef * pVlanConfig)530 HAL_StatusTypeDef HAL_ETHEx_SetTxVLANConfig(ETH_HandleTypeDef *heth, uint32_t VLANTag,
531                                             const ETH_TxVLANConfigTypeDef *pVlanConfig)
532 {
533   if (VLANTag == ETH_INNER_TX_VLANTAG)
534   {
535     MODIFY_REG(heth->Instance->MACIVIR, ETH_MACTXVLAN_MASK, (((uint32_t)pVlanConfig->SourceTxDesc << 20) |
536                                                              ((uint32_t)pVlanConfig->SVLANType << 19) |
537                                                              pVlanConfig->VLANTagControl));
538     /* Enable Double VLAN processing */
539     SET_BIT(heth->Instance->MACVTR, ETH_MACVTR_EDVLP);
540   }
541   else
542   {
543     MODIFY_REG(heth->Instance->MACVIR, ETH_MACTXVLAN_MASK, (((uint32_t)pVlanConfig->SourceTxDesc << 20) |
544                                                             ((uint32_t)pVlanConfig->SVLANType << 19) |
545                                                             pVlanConfig->VLANTagControl));
546   }
547 
548   return HAL_OK;
549 }
550 
551 /**
552   * @brief  Set the VLAN Tag Identifier for Transmit Packets.
553   * @param  heth: pointer to a ETH_HandleTypeDef structure that contains
554   *         the configuration information for ETHERNET module
555   * @param  VLANTag: Selects the vlan tag, this parameter must be one of the following
556   *                 ETH_OUTER_TX_VLANTAG
557   *                 ETH_INNER_TX_VLANTAG
558   * @param  VLANIdentifier: VLAN Identifier 16 bit value
559   * @retval None
560   */
HAL_ETHEx_SetTxVLANIdentifier(ETH_HandleTypeDef * heth,uint32_t VLANTag,uint32_t VLANIdentifier)561 void HAL_ETHEx_SetTxVLANIdentifier(ETH_HandleTypeDef *heth, uint32_t VLANTag, uint32_t VLANIdentifier)
562 {
563   if (VLANTag == ETH_INNER_TX_VLANTAG)
564   {
565     MODIFY_REG(heth->Instance->MACIVIR, ETH_MACVIR_VLT, VLANIdentifier);
566   }
567   else
568   {
569     MODIFY_REG(heth->Instance->MACVIR, ETH_MACVIR_VLT, VLANIdentifier);
570   }
571 }
572 
573 /**
574   * @brief  Enables the VLAN Tag Filtering process.
575   * @param  heth: pointer to a ETH_HandleTypeDef structure that contains
576   *         the configuration information for ETHERNET module
577   * @retval None.
578   */
HAL_ETHEx_EnableVLANProcessing(ETH_HandleTypeDef * heth)579 void HAL_ETHEx_EnableVLANProcessing(ETH_HandleTypeDef *heth)
580 {
581   /* Enable VLAN processing */
582   SET_BIT(heth->Instance->MACPFR, ETH_MACPFR_VTFE);
583 }
584 
585 /**
586   * @brief  Disables the VLAN Tag Filtering process.
587   * @param  heth: pointer to a ETH_HandleTypeDef structure that contains
588   *         the configuration information for ETHERNET module
589   * @retval None.
590   */
HAL_ETHEx_DisableVLANProcessing(ETH_HandleTypeDef * heth)591 void HAL_ETHEx_DisableVLANProcessing(ETH_HandleTypeDef *heth)
592 {
593   /* Disable VLAN processing */
594   CLEAR_BIT(heth->Instance->MACPFR, ETH_MACPFR_VTFE);
595 }
596 
597 /**
598   * @brief  Enters the Low Power Idle (LPI) mode
599   * @param  heth: pointer to a ETH_HandleTypeDef structure that contains
600   *         the configuration information for ETHERNET module
601   * @param  TxAutomate: Enable/Disable automate enter/exit LPI mode.
602   * @param  TxClockStop: Enable/Disable Tx clock stop in LPI mode.
603   * @retval None
604   */
HAL_ETHEx_EnterLPIMode(ETH_HandleTypeDef * heth,FunctionalState TxAutomate,FunctionalState TxClockStop)605 void HAL_ETHEx_EnterLPIMode(ETH_HandleTypeDef *heth, FunctionalState TxAutomate, FunctionalState TxClockStop)
606 {
607   /* Enable LPI Interrupts */
608   __HAL_ETH_MAC_ENABLE_IT(heth, ETH_MACIER_LPIIE);
609 
610   /* Write to LPI Control register: Enter low power mode */
611   MODIFY_REG(heth->Instance->MACLCSR, (ETH_MACLCSR_LPIEN | ETH_MACLCSR_LPITXA | ETH_MACLCSR_LPITCSE),
612              (((uint32_t)TxAutomate << 19) |
613               ((uint32_t)TxClockStop << 21) |
614               ETH_MACLCSR_LPIEN));
615 }
616 
617 /**
618   * @brief  Exits the Low Power Idle (LPI) mode.
619   * @param  heth: pointer to a ETH_HandleTypeDef structure that contains
620   *         the configuration information for ETHERNET module
621   * @retval None
622   */
HAL_ETHEx_ExitLPIMode(ETH_HandleTypeDef * heth)623 void HAL_ETHEx_ExitLPIMode(ETH_HandleTypeDef *heth)
624 {
625   /* Clear the LPI Config and exit low power mode */
626   CLEAR_BIT(heth->Instance->MACLCSR, (ETH_MACLCSR_LPIEN | ETH_MACLCSR_LPITXA | ETH_MACLCSR_LPITCSE));
627 
628   /* Enable LPI Interrupts */
629   __HAL_ETH_MAC_DISABLE_IT(heth, ETH_MACIER_LPIIE);
630 }
631 
632 /**
633   * @brief  Returns the ETH MAC LPI event
634   * @param  heth: pointer to a ETH_HandleTypeDef structure that contains
635   *         the configuration information for ETHERNET module
636   * @retval ETH MAC WakeUp event
637   */
HAL_ETHEx_GetMACLPIEvent(const ETH_HandleTypeDef * heth)638 uint32_t HAL_ETHEx_GetMACLPIEvent(const ETH_HandleTypeDef *heth)
639 {
640   return heth->MACLPIEvent;
641 }
642 
643 /**
644   * @}
645   */
646 
647 /**
648   * @}
649   */
650 
651 /**
652   * @}
653   */
654 
655 #endif /* ETH */
656 
657 #endif /* HAL_ETH_MODULE_ENABLED */
658 /**
659   * @}
660   */
661