@@ -56,6 +56,25 @@ LOG_MODULE_REGISTER(LOG_MODULE_NAME);
5656
5757#define PHY_ADDR CONFIG_ETH_STM32_HAL_PHY_ADDRESS
5858
59+ #if defined(CONFIG_ETH_STM32_HAL_API_V2 )
60+ #define PHY_SCSR ((uint16_t)0x001FU) /*!< PHY Special Control/Status */
61+ #define PHY_SCSR_AUTONEGO_DONE ((uint16_t)0x1000U) /*!< Auto-Negotiation Done Status */
62+ #define PHY_HCDSPEEDMASK ((uint16_t)0x001CU) /*!< High Capability Speed Mask */
63+ #define PHY_10BT_HD ((uint16_t)0x0004U) /*!< 10Base-T half-duplex */
64+ #define PHY_10BT_FD ((uint16_t)0x0014U) /*!< 10Base-T full-duplex */
65+ #define PHY_100BTX_HD ((uint16_t)0x0008U) /*!< 100Base-TX half-duplex */
66+ #define PHY_100BTX_FD ((uint16_t)0x0018U) /*!< 100Base-TX full-duplex */
67+ #define PHY_AUTONEGO_ENABLE ((uint16_t)0x1000U) /*!< Auto-negotiation enable bit */
68+ #define PHY_TIMEOUT (5000U) /*!< PHY operation timeout in msec */
69+
70+ #define PHY_STATUS_LINK_DOWN ((int32_t)1) /*!< Link down status */
71+ #define PHY_STATUS_100MBITS_FULLDUPLEX ((int32_t)2) /*!< 100 Mbps full-duplex status */
72+ #define PHY_STATUS_100MBITS_HALFDUPLEX ((int32_t)3) /*!< 100 Mbps half-duplex status */
73+ #define PHY_STATUS_10MBITS_FULLDUPLEX ((int32_t)4) /*!< 10 Mbps full-duplex status */
74+ #define PHY_STATUS_10MBITS_HALFDUPLEX ((int32_t)5) /*!< 10 Mbps half-duplex status */
75+ #define PHY_STATUS_AUTONEGO_NOTDONE ((int32_t)6) /*!< Auto-negotiation not done */
76+ #endif
77+
5978#if DT_HAS_COMPAT_STATUS_OKAY (st_stm32_mdio )
6079
6180#define DEVICE_PHY_BY_NAME (n ) \
@@ -67,8 +86,9 @@ static const struct device *eth_stm32_phy_dev = DEVICE_PHY_BY_NAME(0);
6786
6887#if DT_HAS_COMPAT_STATUS_OKAY (st_stm32h7_ethernet )
6988
70- #define PHY_BSR ((uint16_t)0x0001U) /*!< Transceiver Basic Status Register */
71- #define PHY_LINKED_STATUS ((uint16_t)0x0004U) /*!< Valid link established */
89+ #define PHY_BCR ((uint16_t)0x0000U) /*!< Transceiver Basic Control Register */
90+ #define PHY_BSR ((uint16_t)0x0001U) /*!< Transceiver Basic Status Register */
91+ #define PHY_LINKED_STATUS ((uint16_t)0x0004U) /*!< Valid link established */
7292
7393#define IS_ETH_DMATXDESC_OWN (dma_tx_desc ) (dma_tx_desc->DESC3 & \
7494 ETH_DMATXNDESCRF_OWN)
@@ -918,7 +938,6 @@ static int eth_initialize(const struct device *dev)
918938 struct eth_stm32_hal_dev_data * dev_data ;
919939 const struct eth_stm32_hal_dev_cfg * cfg ;
920940 ETH_HandleTypeDef * heth ;
921- HAL_StatusTypeDef hal_ret = HAL_OK ;
922941 int ret = 0 ;
923942
924943 __ASSERT_NO_MSG (dev != NULL );
@@ -966,11 +985,8 @@ static int eth_initialize(const struct device *dev)
966985
967986 heth -> Init .MACAddr = dev_data -> mac_addr ;
968987
969- #if defined(CONFIG_ETH_STM32_HAL_API_V2 )
970- heth -> Init .TxDesc = dma_tx_desc_tab ;
971- heth -> Init .RxDesc = dma_rx_desc_tab ;
972- heth -> Init .RxBuffLen = ETH_STM32_RX_BUF_SIZE ;
973- #endif /* CONFIG_ETH_STM32_HAL_API_V2 */
988+ #if !defined(CONFIG_ETH_STM32_HAL_API_V2 )
989+ HAL_StatusTypeDef hal_ret = HAL_OK ;
974990
975991 hal_ret = HAL_ETH_Init (heth );
976992 if (hal_ret == HAL_TIMEOUT ) {
@@ -983,75 +999,22 @@ static int eth_initialize(const struct device *dev)
983999 return - EINVAL ;
9841000 }
9851001
986- #if defined(CONFIG_PTP_CLOCK_STM32_HAL )
987- /* Enable timestamping of RX packets. We enable all packets to be
988- * timestamped to cover both IEEE 1588 and gPTP.
989- */
990- #if DT_HAS_COMPAT_STATUS_OKAY (st_stm32h7_ethernet )
991- heth -> Instance -> MACTSCR |= ETH_MACTSCR_TSENALL ;
992- #else
993- heth -> Instance -> PTPTSCR |= ETH_PTPTSCR_TSSARFE ;
994- #endif /* DT_HAS_COMPAT_STATUS_OKAY(st_stm32h7_ethernet) */
995- #endif /* CONFIG_PTP_CLOCK_STM32_HAL */
996-
997- #if defined(CONFIG_ETH_STM32_HAL_API_V2 )
998- /* Tx config init: */
999- memset (& tx_config , 0 , sizeof (ETH_TxPacketConfig ));
1000- tx_config .Attributes = ETH_TX_PACKETS_FEATURES_CSUM |
1001- ETH_TX_PACKETS_FEATURES_CRCPAD ;
1002- tx_config .ChecksumCtrl = IS_ENABLED (CONFIG_ETH_STM32_HW_CHECKSUM ) ?
1003- ETH_CHECKSUM_IPHDR_PAYLOAD_INSERT_PHDR_CALC : ETH_CHECKSUM_DISABLE ;
1004- tx_config .CRCPadCtrl = ETH_CRC_PAD_INSERT ;
1005- #endif /* CONFIG_ETH_STM32_HAL_API_V2 */
1006-
10071002 dev_data -> link_up = false;
10081003
10091004 /* Initialize semaphores */
10101005 k_mutex_init (& dev_data -> tx_mutex );
10111006 k_sem_init (& dev_data -> rx_int_sem , 0 , K_SEM_MAX_LIMIT );
1012- #if defined(CONFIG_ETH_STM32_HAL_API_V2 )
1013- k_sem_init (& dev_data -> tx_int_sem , 0 , K_SEM_MAX_LIMIT );
1014- #endif /* CONFIG_ETH_STM32_HAL_API_V2 */
1015-
1016- #if defined(CONFIG_ETH_STM32_HAL_API_V2 )
1017- /* Adjust MDC clock range depending on HCLK frequency: */
1018- HAL_ETH_SetMDIOClockRange (heth );
1019-
1020- /* @TODO: read duplex mode and speed from PHY and set it to ETH */
10211007
1022- ETH_MACConfigTypeDef mac_config ;
1023-
1024- HAL_ETH_GetMACConfig (heth , & mac_config );
1025- mac_config .DuplexMode = IS_ENABLED (CONFIG_ETH_STM32_MODE_HALFDUPLEX ) ?
1026- ETH_HALFDUPLEX_MODE : ETH_FULLDUPLEX_MODE ;
1027- mac_config .Speed = IS_ENABLED (CONFIG_ETH_STM32_SPEED_10M ) ?
1028- ETH_SPEED_10M : ETH_SPEED_100M ;
1029- hal_ret = HAL_ETH_SetMACConfig (heth , & mac_config );
1030- if (hal_ret != HAL_OK ) {
1031- LOG_ERR ("HAL_ETH_SetMACConfig: failed: %d" , hal_ret );
1032- }
1033- #endif /* CONFIG_ETH_STM32_HAL_API_V2 */
1034-
1035- #if defined(CONFIG_ETH_STM32_HAL_API_V2 )
1036-
1037- /* prepare tx buffer header */
1038- for (uint16_t i = 0 ; i < ETH_TXBUFNB ; ++ i ) {
1039- dma_tx_buffer_header [i ].tx_buff .buffer = dma_tx_buffer [i ];
1040- }
1041-
1042- hal_ret = HAL_ETH_Start_IT (heth );
1043- #else
10441008 HAL_ETH_DMATxDescListInit (heth , dma_tx_desc_tab ,
10451009 & dma_tx_buffer [0 ][0 ], ETH_TXBUFNB );
10461010 HAL_ETH_DMARxDescListInit (heth , dma_rx_desc_tab ,
10471011 & dma_rx_buffer [0 ][0 ], ETH_RXBUFNB );
10481012
10491013 hal_ret = HAL_ETH_Start (heth );
1050- #endif /* CONFIG_ETH_STM32_HAL_API_V2 */
1051-
10521014 if (hal_ret != HAL_OK ) {
10531015 LOG_ERR ("HAL_ETH_Start{_IT} failed" );
10541016 }
1017+ #endif /* !CONFIG_ETH_STM32_HAL_API_V2 */
10551018
10561019 setup_mac_filter (heth );
10571020
@@ -1114,6 +1077,191 @@ static void eth_stm32_mcast_filter(const struct device *dev, const struct ethern
11141077
11151078#endif /* CONFIG_ETH_STM32_MULTICAST_FILTER */
11161079
1080+ #if defined(CONFIG_ETH_STM32_HAL_API_V2 )
1081+ #if defined(CONFIG_ETH_STM32_AUTO_NEGOTIATION_ENABLE )
1082+ static uint32_t eth_phy_get_link_state (ETH_HandleTypeDef * heth )
1083+ {
1084+ uint32_t readval = 0 ;
1085+ uint32_t tickstart = 0U ;
1086+
1087+ tickstart = HAL_GetTick ();
1088+
1089+ /* Wait for linked status */
1090+ do {
1091+ HAL_ETH_ReadPHYRegister (heth , PHY_ADDR , PHY_BSR , (uint32_t * )& readval );
1092+
1093+ /* Check for the Timeout */
1094+ if ((HAL_GetTick () - tickstart ) > 5000U ) {
1095+ LOG_INF ("Check for the Timeout" );
1096+ return HAL_TIMEOUT ;
1097+ }
1098+ } while (((readval & PHY_LINKED_STATUS ) != PHY_LINKED_STATUS ));
1099+
1100+ if ((readval & PHY_LINKED_STATUS ) == 0 ) {
1101+ LOG_ERR ("Link Down" );
1102+ return PHY_STATUS_LINK_DOWN ;
1103+ }
1104+
1105+ /* Check Auto negotiation */
1106+ if (HAL_ETH_ReadPHYRegister (heth , PHY_ADDR , PHY_BCR , (uint32_t * )& readval ) != HAL_OK ) {
1107+ LOG_INF ("Error reading BCR register\n" );
1108+ return HAL_ERROR ;
1109+ }
1110+
1111+ if ((readval & PHY_AUTONEGO_ENABLE ) != PHY_AUTONEGO_ENABLE ) {
1112+ /* Enable Auto-Negotiation */
1113+ if ((HAL_ETH_WritePHYRegister (heth , PHY_ADDR , PHY_BCR , PHY_AUTONEGO_ENABLE )) !=
1114+ HAL_OK ) {
1115+ return HAL_ERROR ;
1116+ }
1117+ }
1118+
1119+ /* Auto Nego enabled */
1120+ LOG_DBG ("Auto nego enabled" );
1121+ if (HAL_ETH_ReadPHYRegister (heth , PHY_ADDR , PHY_SCSR , & readval ) != HAL_OK ) {
1122+ return HAL_ERROR ;
1123+ }
1124+
1125+ /* Check if auto nego not done */
1126+ if ((readval & PHY_SCSR_AUTONEGO_DONE ) == 0 ) {
1127+ return PHY_STATUS_AUTONEGO_NOTDONE ;
1128+ }
1129+
1130+ if ((readval & PHY_HCDSPEEDMASK ) == PHY_100BTX_FD ) {
1131+ return PHY_STATUS_100MBITS_FULLDUPLEX ;
1132+ } else if ((readval & PHY_HCDSPEEDMASK ) == PHY_100BTX_HD ) {
1133+ return PHY_STATUS_100MBITS_HALFDUPLEX ;
1134+ } else if ((readval & PHY_HCDSPEEDMASK ) == PHY_10BT_FD ) {
1135+ return PHY_STATUS_10MBITS_FULLDUPLEX ;
1136+ } else {
1137+ return PHY_STATUS_10MBITS_HALFDUPLEX ;
1138+ }
1139+ }
1140+
1141+ static void get_auto_nego_speed_duplex (ETH_HandleTypeDef * heth , ETH_MACConfigTypeDef * mac_config )
1142+ {
1143+ uint32_t phyLinkState ;
1144+ uint32_t tickstart = HAL_GetTick ();
1145+
1146+ do {
1147+ phyLinkState = eth_phy_get_link_state (heth );
1148+ } while ((phyLinkState <= PHY_STATUS_LINK_DOWN ) &&
1149+ ((HAL_GetTick () - tickstart ) < PHY_TIMEOUT ));
1150+
1151+ /* Get link state */
1152+ if (phyLinkState <= PHY_STATUS_LINK_DOWN ) {
1153+ return ;
1154+ }
1155+
1156+ switch (phyLinkState ) {
1157+ case PHY_STATUS_100MBITS_FULLDUPLEX :
1158+ mac_config -> DuplexMode = ETH_FULLDUPLEX_MODE ;
1159+ mac_config -> Speed = ETH_SPEED_100M ;
1160+ break ;
1161+ case PHY_STATUS_100MBITS_HALFDUPLEX :
1162+ mac_config -> DuplexMode = ETH_HALFDUPLEX_MODE ;
1163+ mac_config -> Speed = ETH_SPEED_100M ;
1164+ break ;
1165+ case PHY_STATUS_10MBITS_FULLDUPLEX :
1166+ mac_config -> DuplexMode = ETH_FULLDUPLEX_MODE ;
1167+ mac_config -> Speed = ETH_SPEED_10M ;
1168+ break ;
1169+ case PHY_STATUS_10MBITS_HALFDUPLEX :
1170+ mac_config -> DuplexMode = ETH_HALFDUPLEX_MODE ;
1171+ mac_config -> Speed = ETH_SPEED_10M ;
1172+ break ;
1173+ default :
1174+ mac_config -> DuplexMode = ETH_FULLDUPLEX_MODE ;
1175+ mac_config -> Speed = ETH_SPEED_100M ;
1176+ break ;
1177+ }
1178+ }
1179+ #endif /* CONFIG_ETH_STM32_AUTO_NEGOTIATION_ENABLE */
1180+
1181+ static int eth_enable_api_v2 (const struct device * dev )
1182+ {
1183+ HAL_StatusTypeDef hal_ret = HAL_OK ;
1184+ struct eth_stm32_hal_dev_data * dev_data ;
1185+ ETH_HandleTypeDef * heth ;
1186+ ETH_MACConfigTypeDef mac_config ;
1187+
1188+ dev_data = dev -> data ;
1189+ heth = & dev_data -> heth ;
1190+
1191+ heth -> Init .TxDesc = dma_tx_desc_tab ;
1192+ heth -> Init .RxDesc = dma_rx_desc_tab ;
1193+ heth -> Init .RxBuffLen = ETH_STM32_RX_BUF_SIZE ;
1194+
1195+ hal_ret = HAL_ETH_Init (heth );
1196+ if (hal_ret == HAL_TIMEOUT ) {
1197+ /* HAL Init time out. This could be linked to */
1198+ /* a recoverable error. Log the issue and continue */
1199+ /* driver initialisation */
1200+ LOG_ERR ("HAL_ETH_Init Timed out" );
1201+ } else if (hal_ret != HAL_OK ) {
1202+ LOG_ERR ("HAL_ETH_Init failed: %d" , hal_ret );
1203+ return - EINVAL ;
1204+ }
1205+
1206+ #if defined(CONFIG_PTP_CLOCK_STM32_HAL )
1207+ /* Enable timestamping of RX packets. We enable all packets to be
1208+ * timestamped to cover both IEEE 1588 and gPTP.
1209+ */
1210+ #if DT_HAS_COMPAT_STATUS_OKAY (st_stm32h7_ethernet )
1211+ heth -> Instance -> MACTSCR |= ETH_MACTSCR_TSENALL ;
1212+ #else
1213+ heth -> Instance -> PTPTSCR |= ETH_PTPTSCR_TSSARFE ;
1214+ #endif /* DT_HAS_COMPAT_STATUS_OKAY(st_stm32h7_ethernet) */
1215+ #endif /* CONFIG_PTP_CLOCK_STM32_HAL */
1216+
1217+ dev_data -> link_up = false;
1218+
1219+ /* Initialize semaphores */
1220+ k_mutex_init (& dev_data -> tx_mutex );
1221+ k_sem_init (& dev_data -> rx_int_sem , 0 , K_SEM_MAX_LIMIT );
1222+ k_sem_init (& dev_data -> tx_int_sem , 0 , K_SEM_MAX_LIMIT );
1223+
1224+ /* Tx config init: */
1225+ memset (& tx_config , 0 , sizeof (ETH_TxPacketConfig ));
1226+ tx_config .Attributes = ETH_TX_PACKETS_FEATURES_CSUM |
1227+ ETH_TX_PACKETS_FEATURES_CRCPAD ;
1228+ tx_config .ChecksumCtrl = IS_ENABLED (CONFIG_ETH_STM32_HW_CHECKSUM ) ?
1229+ ETH_CHECKSUM_IPHDR_PAYLOAD_INSERT_PHDR_CALC : ETH_CHECKSUM_DISABLE ;
1230+ tx_config .CRCPadCtrl = ETH_CRC_PAD_INSERT ;
1231+
1232+ HAL_ETH_SetMDIOClockRange (heth );
1233+
1234+ HAL_ETH_GetMACConfig (heth , & mac_config );
1235+
1236+ #if defined(CONFIG_ETH_STM32_AUTO_NEGOTIATION_ENABLE )
1237+ /* Auto Nego enabled */
1238+ get_auto_nego_speed_duplex (heth , & mac_config );
1239+
1240+ #else /* Auto Nego disabled */
1241+ mac_config .DuplexMode = IS_ENABLED (CONFIG_ETH_STM32_MODE_HALFDUPLEX ) ? ETH_HALFDUPLEX_MODE
1242+ : ETH_FULLDUPLEX_MODE ;
1243+ mac_config .Speed = IS_ENABLED (CONFIG_ETH_STM32_SPEED_10M ) ? ETH_SPEED_10M : ETH_SPEED_100M ;
1244+ #endif
1245+
1246+ hal_ret = HAL_ETH_SetMACConfig (heth , & mac_config );
1247+ if (hal_ret != HAL_OK ) {
1248+ LOG_ERR ("HAL_ETH_SetMACConfig: failed: %d" , hal_ret );
1249+ }
1250+
1251+ /* prepare tx buffer header */
1252+ for (uint16_t i = 0 ; i < ETH_TXBUFNB ; ++ i ) {
1253+ dma_tx_buffer_header [i ].tx_buff .buffer = dma_tx_buffer [i ];
1254+ }
1255+
1256+ hal_ret = HAL_ETH_Start_IT (heth );
1257+ if (hal_ret != HAL_OK ) {
1258+ LOG_ERR ("HAL_ETH_Start{_IT} failed" );
1259+ }
1260+
1261+ return 0 ;
1262+ }
1263+ #endif /* CONFIG_ETH_STM32_HAL_API_V2 */
1264+
11171265static void eth_iface_init (struct net_if * iface )
11181266{
11191267 const struct device * dev ;
@@ -1144,6 +1292,14 @@ static void eth_iface_init(struct net_if *iface)
11441292
11451293 ethernet_init (iface );
11461294
1295+ #if defined(CONFIG_ETH_STM32_HAL_API_V2 )
1296+ /* This function requires the Ethernet interface to be
1297+ * properly initialized. In auto-negotiation mode, it reads the speed
1298+ * and duplex settings to configure the driver accordingly.
1299+ */
1300+ eth_enable_api_v2 (dev );
1301+ #endif
1302+
11471303 net_if_carrier_off (iface );
11481304
11491305 net_lldp_set_lldpdu (iface );
0 commit comments