@@ -56,6 +56,25 @@ LOG_MODULE_REGISTER(LOG_MODULE_NAME);
56
56
57
57
#define PHY_ADDR CONFIG_ETH_STM32_HAL_PHY_ADDRESS
58
58
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
+
59
78
#if DT_HAS_COMPAT_STATUS_OKAY (st_stm32_mdio )
60
79
61
80
#define DEVICE_PHY_BY_NAME (n ) \
@@ -67,8 +86,9 @@ static const struct device *eth_stm32_phy_dev = DEVICE_PHY_BY_NAME(0);
67
86
68
87
#if DT_HAS_COMPAT_STATUS_OKAY (st_stm32h7_ethernet )
69
88
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 */
72
92
73
93
#define IS_ETH_DMATXDESC_OWN (dma_tx_desc ) (dma_tx_desc->DESC3 & \
74
94
ETH_DMATXNDESCRF_OWN)
@@ -924,7 +944,6 @@ static int eth_initialize(const struct device *dev)
924
944
struct eth_stm32_hal_dev_data * dev_data ;
925
945
const struct eth_stm32_hal_dev_cfg * cfg ;
926
946
ETH_HandleTypeDef * heth ;
927
- HAL_StatusTypeDef hal_ret = HAL_OK ;
928
947
int ret = 0 ;
929
948
930
949
__ASSERT_NO_MSG (dev != NULL );
@@ -972,11 +991,8 @@ static int eth_initialize(const struct device *dev)
972
991
973
992
heth -> Init .MACAddr = dev_data -> mac_addr ;
974
993
975
- #if defined(CONFIG_ETH_STM32_HAL_API_V2 )
976
- heth -> Init .TxDesc = dma_tx_desc_tab ;
977
- heth -> Init .RxDesc = dma_rx_desc_tab ;
978
- heth -> Init .RxBuffLen = ETH_STM32_RX_BUF_SIZE ;
979
- #endif /* CONFIG_ETH_STM32_HAL_API_V2 */
994
+ #if !defined(CONFIG_ETH_STM32_HAL_API_V2 )
995
+ HAL_StatusTypeDef hal_ret = HAL_OK ;
980
996
981
997
hal_ret = HAL_ETH_Init (heth );
982
998
if (hal_ret == HAL_TIMEOUT ) {
@@ -989,75 +1005,22 @@ static int eth_initialize(const struct device *dev)
989
1005
return - EINVAL ;
990
1006
}
991
1007
992
- #if defined(CONFIG_PTP_CLOCK_STM32_HAL )
993
- /* Enable timestamping of RX packets. We enable all packets to be
994
- * timestamped to cover both IEEE 1588 and gPTP.
995
- */
996
- #if DT_HAS_COMPAT_STATUS_OKAY (st_stm32h7_ethernet )
997
- heth -> Instance -> MACTSCR |= ETH_MACTSCR_TSENALL ;
998
- #else
999
- heth -> Instance -> PTPTSCR |= ETH_PTPTSCR_TSSARFE ;
1000
- #endif /* DT_HAS_COMPAT_STATUS_OKAY(st_stm32h7_ethernet) */
1001
- #endif /* CONFIG_PTP_CLOCK_STM32_HAL */
1002
-
1003
- #if defined(CONFIG_ETH_STM32_HAL_API_V2 )
1004
- /* Tx config init: */
1005
- memset (& tx_config , 0 , sizeof (ETH_TxPacketConfig ));
1006
- tx_config .Attributes = ETH_TX_PACKETS_FEATURES_CSUM |
1007
- ETH_TX_PACKETS_FEATURES_CRCPAD ;
1008
- tx_config .ChecksumCtrl = IS_ENABLED (CONFIG_ETH_STM32_HW_CHECKSUM ) ?
1009
- ETH_CHECKSUM_IPHDR_PAYLOAD_INSERT_PHDR_CALC : ETH_CHECKSUM_DISABLE ;
1010
- tx_config .CRCPadCtrl = ETH_CRC_PAD_INSERT ;
1011
- #endif /* CONFIG_ETH_STM32_HAL_API_V2 */
1012
-
1013
1008
dev_data -> link_up = false;
1014
1009
1015
1010
/* Initialize semaphores */
1016
1011
k_mutex_init (& dev_data -> tx_mutex );
1017
1012
k_sem_init (& dev_data -> rx_int_sem , 0 , K_SEM_MAX_LIMIT );
1018
- #if defined(CONFIG_ETH_STM32_HAL_API_V2 )
1019
- k_sem_init (& dev_data -> tx_int_sem , 0 , K_SEM_MAX_LIMIT );
1020
- #endif /* CONFIG_ETH_STM32_HAL_API_V2 */
1021
-
1022
- #if defined(CONFIG_ETH_STM32_HAL_API_V2 )
1023
- /* Adjust MDC clock range depending on HCLK frequency: */
1024
- HAL_ETH_SetMDIOClockRange (heth );
1025
-
1026
- /* @TODO: read duplex mode and speed from PHY and set it to ETH */
1027
1013
1028
- ETH_MACConfigTypeDef mac_config ;
1029
-
1030
- HAL_ETH_GetMACConfig (heth , & mac_config );
1031
- mac_config .DuplexMode = IS_ENABLED (CONFIG_ETH_STM32_MODE_HALFDUPLEX ) ?
1032
- ETH_HALFDUPLEX_MODE : ETH_FULLDUPLEX_MODE ;
1033
- mac_config .Speed = IS_ENABLED (CONFIG_ETH_STM32_SPEED_10M ) ?
1034
- ETH_SPEED_10M : ETH_SPEED_100M ;
1035
- hal_ret = HAL_ETH_SetMACConfig (heth , & mac_config );
1036
- if (hal_ret != HAL_OK ) {
1037
- LOG_ERR ("HAL_ETH_SetMACConfig: failed: %d" , hal_ret );
1038
- }
1039
- #endif /* CONFIG_ETH_STM32_HAL_API_V2 */
1040
-
1041
- #if defined(CONFIG_ETH_STM32_HAL_API_V2 )
1042
-
1043
- /* prepare tx buffer header */
1044
- for (uint16_t i = 0 ; i < ETH_TXBUFNB ; ++ i ) {
1045
- dma_tx_buffer_header [i ].tx_buff .buffer = dma_tx_buffer [i ];
1046
- }
1047
-
1048
- hal_ret = HAL_ETH_Start_IT (heth );
1049
- #else
1050
1014
HAL_ETH_DMATxDescListInit (heth , dma_tx_desc_tab ,
1051
1015
& dma_tx_buffer [0 ][0 ], ETH_TXBUFNB );
1052
1016
HAL_ETH_DMARxDescListInit (heth , dma_rx_desc_tab ,
1053
1017
& dma_rx_buffer [0 ][0 ], ETH_RXBUFNB );
1054
1018
1055
1019
hal_ret = HAL_ETH_Start (heth );
1056
- #endif /* CONFIG_ETH_STM32_HAL_API_V2 */
1057
-
1058
1020
if (hal_ret != HAL_OK ) {
1059
1021
LOG_ERR ("HAL_ETH_Start{_IT} failed" );
1060
1022
}
1023
+ #endif /* !CONFIG_ETH_STM32_HAL_API_V2 */
1061
1024
1062
1025
setup_mac_filter (heth );
1063
1026
@@ -1120,6 +1083,190 @@ static void eth_stm32_mcast_filter(const struct device *dev, const struct ethern
1120
1083
1121
1084
#endif /* CONFIG_ETH_STM32_MULTICAST_FILTER */
1122
1085
1086
+ #if defined(CONFIG_ETH_STM32_HAL_API_V2 )
1087
+ #if defined(CONFIG_ETH_STM32_AUTO_NEGOTIATION_ENABLE )
1088
+ static uint32_t eth_phy_get_link_state (ETH_HandleTypeDef * heth )
1089
+ {
1090
+ uint32_t readval = 0 ;
1091
+ uint32_t tickstart = 0U ;
1092
+
1093
+ tickstart = k_uptime_get_32 ();
1094
+
1095
+ /* Wait for linked status */
1096
+ do {
1097
+ HAL_ETH_ReadPHYRegister (heth , PHY_ADDR , PHY_BSR , & readval );
1098
+
1099
+ /* Check for the Timeout */
1100
+ if ((k_uptime_get_32 () - tickstart ) > PHY_TIMEOUT ) {
1101
+ return HAL_TIMEOUT ;
1102
+ }
1103
+ } while (((readval & PHY_LINKED_STATUS ) != PHY_LINKED_STATUS ));
1104
+
1105
+ if ((readval & PHY_LINKED_STATUS ) == 0 ) {
1106
+ LOG_ERR ("Link Down" );
1107
+ return PHY_STATUS_LINK_DOWN ;
1108
+ }
1109
+
1110
+ /* Check Auto negotiation */
1111
+ if (HAL_ETH_ReadPHYRegister (heth , PHY_ADDR , PHY_BCR , & readval ) != HAL_OK ) {
1112
+ LOG_INF ("Error reading BCR register\n" );
1113
+ return HAL_ERROR ;
1114
+ }
1115
+
1116
+ if ((readval & PHY_AUTONEGO_ENABLE ) != PHY_AUTONEGO_ENABLE ) {
1117
+ /* Enable Auto-Negotiation */
1118
+ if ((HAL_ETH_WritePHYRegister (heth , PHY_ADDR , PHY_BCR , PHY_AUTONEGO_ENABLE )) !=
1119
+ HAL_OK ) {
1120
+ return HAL_ERROR ;
1121
+ }
1122
+ }
1123
+
1124
+ /* Auto Nego enabled */
1125
+ LOG_DBG ("Auto nego enabled" );
1126
+ if (HAL_ETH_ReadPHYRegister (heth , PHY_ADDR , PHY_SCSR , & readval ) != HAL_OK ) {
1127
+ return HAL_ERROR ;
1128
+ }
1129
+
1130
+ /* Check if auto nego not done */
1131
+ if ((readval & PHY_SCSR_AUTONEGO_DONE ) == 0 ) {
1132
+ return PHY_STATUS_AUTONEGO_NOTDONE ;
1133
+ }
1134
+
1135
+ if ((readval & PHY_HCDSPEEDMASK ) == PHY_100BTX_FD ) {
1136
+ return PHY_STATUS_100MBITS_FULLDUPLEX ;
1137
+ } else if ((readval & PHY_HCDSPEEDMASK ) == PHY_100BTX_HD ) {
1138
+ return PHY_STATUS_100MBITS_HALFDUPLEX ;
1139
+ } else if ((readval & PHY_HCDSPEEDMASK ) == PHY_10BT_FD ) {
1140
+ return PHY_STATUS_10MBITS_FULLDUPLEX ;
1141
+ } else {
1142
+ return PHY_STATUS_10MBITS_HALFDUPLEX ;
1143
+ }
1144
+ }
1145
+
1146
+ static void get_auto_nego_speed_duplex (ETH_HandleTypeDef * heth , ETH_MACConfigTypeDef * mac_config )
1147
+ {
1148
+ uint32_t phyLinkState ;
1149
+ uint32_t tickstart = k_uptime_get_32 ();
1150
+
1151
+ do {
1152
+ phyLinkState = eth_phy_get_link_state (heth );
1153
+ } while ((phyLinkState <= PHY_STATUS_LINK_DOWN ) &&
1154
+ ((k_uptime_get_32 () - tickstart ) < PHY_TIMEOUT ));
1155
+
1156
+ /* Get link state */
1157
+ if (phyLinkState <= PHY_STATUS_LINK_DOWN ) {
1158
+ return ;
1159
+ }
1160
+
1161
+ switch (phyLinkState ) {
1162
+ case PHY_STATUS_100MBITS_FULLDUPLEX :
1163
+ mac_config -> DuplexMode = ETH_FULLDUPLEX_MODE ;
1164
+ mac_config -> Speed = ETH_SPEED_100M ;
1165
+ break ;
1166
+ case PHY_STATUS_100MBITS_HALFDUPLEX :
1167
+ mac_config -> DuplexMode = ETH_HALFDUPLEX_MODE ;
1168
+ mac_config -> Speed = ETH_SPEED_100M ;
1169
+ break ;
1170
+ case PHY_STATUS_10MBITS_FULLDUPLEX :
1171
+ mac_config -> DuplexMode = ETH_FULLDUPLEX_MODE ;
1172
+ mac_config -> Speed = ETH_SPEED_10M ;
1173
+ break ;
1174
+ case PHY_STATUS_10MBITS_HALFDUPLEX :
1175
+ mac_config -> DuplexMode = ETH_HALFDUPLEX_MODE ;
1176
+ mac_config -> Speed = ETH_SPEED_10M ;
1177
+ break ;
1178
+ default :
1179
+ mac_config -> DuplexMode = ETH_FULLDUPLEX_MODE ;
1180
+ mac_config -> Speed = ETH_SPEED_100M ;
1181
+ break ;
1182
+ }
1183
+ }
1184
+ #endif /* CONFIG_ETH_STM32_AUTO_NEGOTIATION_ENABLE */
1185
+
1186
+ static int eth_init_api_v2 (const struct device * dev )
1187
+ {
1188
+ HAL_StatusTypeDef hal_ret = HAL_OK ;
1189
+ struct eth_stm32_hal_dev_data * dev_data ;
1190
+ ETH_HandleTypeDef * heth ;
1191
+ ETH_MACConfigTypeDef mac_config ;
1192
+
1193
+ dev_data = dev -> data ;
1194
+ heth = & dev_data -> heth ;
1195
+
1196
+ heth -> Init .TxDesc = dma_tx_desc_tab ;
1197
+ heth -> Init .RxDesc = dma_rx_desc_tab ;
1198
+ heth -> Init .RxBuffLen = ETH_STM32_RX_BUF_SIZE ;
1199
+
1200
+ hal_ret = HAL_ETH_Init (heth );
1201
+ if (hal_ret == HAL_TIMEOUT ) {
1202
+ /* HAL Init time out. This could be linked to */
1203
+ /* a recoverable error. Log the issue and continue */
1204
+ /* driver initialisation */
1205
+ LOG_ERR ("HAL_ETH_Init Timed out" );
1206
+ } else if (hal_ret != HAL_OK ) {
1207
+ LOG_ERR ("HAL_ETH_Init failed: %d" , hal_ret );
1208
+ return - EINVAL ;
1209
+ }
1210
+
1211
+ #if defined(CONFIG_PTP_CLOCK_STM32_HAL )
1212
+ /* Enable timestamping of RX packets. We enable all packets to be
1213
+ * timestamped to cover both IEEE 1588 and gPTP.
1214
+ */
1215
+ #if DT_HAS_COMPAT_STATUS_OKAY (st_stm32h7_ethernet )
1216
+ heth -> Instance -> MACTSCR |= ETH_MACTSCR_TSENALL ;
1217
+ #else
1218
+ heth -> Instance -> PTPTSCR |= ETH_PTPTSCR_TSSARFE ;
1219
+ #endif /* DT_HAS_COMPAT_STATUS_OKAY(st_stm32h7_ethernet) */
1220
+ #endif /* CONFIG_PTP_CLOCK_STM32_HAL */
1221
+
1222
+ dev_data -> link_up = false;
1223
+
1224
+ /* Initialize semaphores */
1225
+ k_mutex_init (& dev_data -> tx_mutex );
1226
+ k_sem_init (& dev_data -> rx_int_sem , 0 , K_SEM_MAX_LIMIT );
1227
+ k_sem_init (& dev_data -> tx_int_sem , 0 , K_SEM_MAX_LIMIT );
1228
+
1229
+ /* Tx config init: */
1230
+ memset (& tx_config , 0 , sizeof (ETH_TxPacketConfig ));
1231
+ tx_config .Attributes = ETH_TX_PACKETS_FEATURES_CSUM |
1232
+ ETH_TX_PACKETS_FEATURES_CRCPAD ;
1233
+ tx_config .ChecksumCtrl = IS_ENABLED (CONFIG_ETH_STM32_HW_CHECKSUM ) ?
1234
+ ETH_CHECKSUM_IPHDR_PAYLOAD_INSERT_PHDR_CALC : ETH_CHECKSUM_DISABLE ;
1235
+ tx_config .CRCPadCtrl = ETH_CRC_PAD_INSERT ;
1236
+
1237
+ HAL_ETH_SetMDIOClockRange (heth );
1238
+
1239
+ HAL_ETH_GetMACConfig (heth , & mac_config );
1240
+
1241
+ #if defined(CONFIG_ETH_STM32_AUTO_NEGOTIATION_ENABLE )
1242
+ /* Auto Nego enabled */
1243
+ get_auto_nego_speed_duplex (heth , & mac_config );
1244
+
1245
+ #else /* Auto Nego disabled */
1246
+ mac_config .DuplexMode = IS_ENABLED (CONFIG_ETH_STM32_MODE_HALFDUPLEX ) ? ETH_HALFDUPLEX_MODE
1247
+ : ETH_FULLDUPLEX_MODE ;
1248
+ mac_config .Speed = IS_ENABLED (CONFIG_ETH_STM32_SPEED_10M ) ? ETH_SPEED_10M : ETH_SPEED_100M ;
1249
+ #endif
1250
+
1251
+ hal_ret = HAL_ETH_SetMACConfig (heth , & mac_config );
1252
+ if (hal_ret != HAL_OK ) {
1253
+ LOG_ERR ("HAL_ETH_SetMACConfig: failed: %d" , hal_ret );
1254
+ }
1255
+
1256
+ /* prepare tx buffer header */
1257
+ for (uint16_t i = 0 ; i < ETH_TXBUFNB ; ++ i ) {
1258
+ dma_tx_buffer_header [i ].tx_buff .buffer = dma_tx_buffer [i ];
1259
+ }
1260
+
1261
+ hal_ret = HAL_ETH_Start_IT (heth );
1262
+ if (hal_ret != HAL_OK ) {
1263
+ LOG_ERR ("HAL_ETH_Start{_IT} failed" );
1264
+ }
1265
+
1266
+ return 0 ;
1267
+ }
1268
+ #endif /* CONFIG_ETH_STM32_HAL_API_V2 */
1269
+
1123
1270
static void eth_iface_init (struct net_if * iface )
1124
1271
{
1125
1272
const struct device * dev ;
@@ -1150,6 +1297,14 @@ static void eth_iface_init(struct net_if *iface)
1150
1297
1151
1298
ethernet_init (iface );
1152
1299
1300
+ #if defined(CONFIG_ETH_STM32_HAL_API_V2 )
1301
+ /* This function requires the Ethernet interface to be
1302
+ * properly initialized. In auto-negotiation mode, it reads the speed
1303
+ * and duplex settings to configure the driver accordingly.
1304
+ */
1305
+ eth_init_api_v2 (dev );
1306
+ #endif
1307
+
1153
1308
net_if_carrier_off (iface );
1154
1309
1155
1310
net_lldp_set_lldpdu (iface );
0 commit comments