@@ -17,6 +17,7 @@ LOG_MODULE_REGISTER(LOG_MODULE_NAME);
17
17
#include <zephyr/device.h>
18
18
#include <zephyr/sys/__assert.h>
19
19
#include <zephyr/sys/util.h>
20
+ #include <zephyr/crc.h>
20
21
#include <errno.h>
21
22
#include <stdbool.h>
22
23
#include <zephyr/net/net_pkt.h>
@@ -96,6 +97,8 @@ static ETH_DMADescTypeDef dma_tx_desc_tab[ETH_TXBUFNB] __eth_stm32_desc;
96
97
static uint8_t dma_rx_buffer [ETH_RXBUFNB ][ETH_STM32_RX_BUF_SIZE ] __eth_stm32_buf ;
97
98
static uint8_t dma_tx_buffer [ETH_TXBUFNB ][ETH_STM32_TX_BUF_SIZE ] __eth_stm32_buf ;
98
99
100
+ static struct net_if_mcast_monitor mcast_monitor ;
101
+
99
102
#if defined(CONFIG_ETH_STM32_HAL_API_V2 )
100
103
101
104
BUILD_ASSERT (ETH_STM32_RX_BUF_SIZE % 4 == 0 , "Rx buffer size must be a multiple of 4" );
@@ -222,8 +225,8 @@ static inline void disable_mcast_filter(ETH_HandleTypeDef *heth)
222
225
ETH_MACFilterConfigTypeDef MACFilterConf ;
223
226
224
227
HAL_ETH_GetMACFilterConfig (heth , & MACFilterConf );
225
- MACFilterConf .HashMulticast = DISABLE ;
226
- MACFilterConf .PassAllMulticast = ENABLE ;
228
+ MACFilterConf .HashMulticast = ENABLE ;
229
+ MACFilterConf .PassAllMulticast = DISABLE ;
227
230
MACFilterConf .HachOrPerfectFilter = DISABLE ;
228
231
229
232
HAL_ETH_SetMACFilterConfig (heth , & MACFilterConf );
@@ -232,13 +235,12 @@ static inline void disable_mcast_filter(ETH_HandleTypeDef *heth)
232
235
#else
233
236
uint32_t tmp = heth -> Instance -> MACFFR ;
234
237
235
- /* disable multicast filtering */
238
+ /* disable multicast perfect filtering */
236
239
tmp &= ~(ETH_MULTICASTFRAMESFILTER_PERFECTHASHTABLE |
237
- ETH_MULTICASTFRAMESFILTER_HASHTABLE |
238
240
ETH_MULTICASTFRAMESFILTER_PERFECT );
239
241
240
- /* enable receiving all multicast frames */
241
- tmp |= ETH_MULTICASTFRAMESFILTER_NONE ;
242
+ /* enable multicast hash receive filter */
243
+ tmp |= ETH_MULTICASTFRAMESFILTER_HASHTABLE ;
242
244
243
245
heth -> Instance -> MACFFR = tmp ;
244
246
@@ -1163,7 +1165,7 @@ static int eth_initialize(const struct device *dev)
1163
1165
LOG_ERR ("HAL_ETH_Start{_IT} failed" );
1164
1166
}
1165
1167
1166
- disable_mcast_filter (heth );
1168
+ setup_mac_filter (heth );
1167
1169
1168
1170
#if defined(CONFIG_SOC_SERIES_STM32H7X ) || defined(CONFIG_ETH_STM32_HAL_API_V2 )
1169
1171
/* Adjust MDC clock range depending on HCLK frequency: */
@@ -1187,6 +1189,103 @@ static int eth_initialize(const struct device *dev)
1187
1189
return 0 ;
1188
1190
}
1189
1191
1192
+ static uint32_t reverse (uint32_t val )
1193
+ {
1194
+ uint32_t res = 0 ;
1195
+ int i ;
1196
+
1197
+ for (i = 0 ; i < 32 ; i ++ ) {
1198
+ if (val & (1 << i )) {
1199
+ res |= 1 << (31 - i );
1200
+ }
1201
+ }
1202
+
1203
+ return res ;
1204
+ }
1205
+
1206
+ static void net_if_mcast_cb (struct net_if * iface ,
1207
+ const struct net_addr * addr ,
1208
+ bool is_joined )
1209
+ {
1210
+ ARG_UNUSED (addr );
1211
+ ARG_UNUSED (is_joined );
1212
+
1213
+ const struct device * dev ;
1214
+ struct eth_stm32_hal_dev_data * dev_data ;
1215
+ ETH_HandleTypeDef * heth ;
1216
+ #if defined(CONFIG_NET_NATIVE_IPV6 )
1217
+ struct net_if_ipv6 * ipv6 ;
1218
+ #endif
1219
+ #if defined(CONFIG_NET_NATIVE_IPV4 )
1220
+ struct net_if_ipv4 * ipv4 ;
1221
+ #endif
1222
+ struct net_eth_addr mac_addr ;
1223
+ uint32_t crc ;
1224
+ uint32_t hash_table [2 ];
1225
+ uint32_t hash_index ;
1226
+ int i ;
1227
+
1228
+ __ASSERT_NO_MSG (iface != NULL );
1229
+
1230
+ dev = net_if_get_device (iface );
1231
+ __ASSERT_NO_MSG (dev != NULL );
1232
+
1233
+ dev_data = DEV_DATA (dev );
1234
+ __ASSERT_NO_MSG (dev_data != NULL );
1235
+
1236
+ heth = & dev_data -> heth ;
1237
+ __ASSERT_NO_MSG (heth != NULL );
1238
+
1239
+ hash_table [0 ] = 0 ;
1240
+ hash_table [1 ] = 0 ;
1241
+
1242
+ #if defined(CONFIG_NET_NATIVE_IPV6 )
1243
+ if (net_if_config_ipv6_get (iface , & ipv6 ) < 0 ) {
1244
+ return ;
1245
+ }
1246
+
1247
+ for (i = 0 ; i < NET_IF_MAX_IPV6_MADDR ; i ++ ) {
1248
+ if (!ipv6 -> mcast [i ].is_used ) {
1249
+ continue ;
1250
+ }
1251
+
1252
+ net_eth_ipv6_mcast_to_mac_addr (& ipv6 -> mcast [i ].address .in_addr ,
1253
+ & mac_addr );
1254
+ crc = reverse (crc32_ieee (mac_addr .addr ,
1255
+ sizeof (struct net_eth_addr )));
1256
+ hash_index = (crc >> 26 ) & 0x3f ;
1257
+ hash_table [hash_index / 32 ] |= (1 << (hash_index % 32 ));
1258
+ }
1259
+ #endif /* CONFIG_NET_IPV6 */
1260
+
1261
+ #if defined(CONFIG_NET_NATIVE_IPV4 )
1262
+ if (net_if_config_ipv4_get (iface , & ipv4 ) < 0 ) {
1263
+ return ;
1264
+ }
1265
+
1266
+ for (i = 0 ; i < NET_IF_MAX_IPV4_MADDR ; i ++ ) {
1267
+ if (!ipv4 -> mcast [i ].is_used ) {
1268
+ continue ;
1269
+ }
1270
+
1271
+ net_eth_ipv4_mcast_to_mac_addr (& ipv4 -> mcast [i ].address .in_addr ,
1272
+ & mac_addr );
1273
+ crc = reverse (crc32_ieee (mac_addr .addr ,
1274
+ sizeof (struct net_eth_addr )));
1275
+ hash_index = (crc >> 26 ) & 0x3f ;
1276
+ hash_table [hash_index / 32 ] |= (1 << (hash_index % 32 ));
1277
+ }
1278
+ #endif /* CONFIG_NET_IPV4 */
1279
+
1280
+ #if defined(CONFIG_SOC_SERIES_STM32H7X )
1281
+ heth -> Instance -> MACHT0R = hash_table [0 ];
1282
+ heth -> Instance -> MACHT1R = hash_table [1 ];
1283
+ #else
1284
+ heth -> Instance -> MACHTLR = hash_table [0 ];
1285
+ heth -> Instance -> MACHTHR = hash_table [1 ];
1286
+ #endif
1287
+ }
1288
+
1190
1289
static void eth_iface_init (struct net_if * iface )
1191
1290
{
1192
1291
const struct device * dev ;
@@ -1210,6 +1309,8 @@ static void eth_iface_init(struct net_if *iface)
1210
1309
is_first_init = true;
1211
1310
}
1212
1311
1312
+ net_if_mcast_mon_register (& mcast_monitor , iface , net_if_mcast_cb );
1313
+
1213
1314
/* Register Ethernet MAC Address with the upper layer */
1214
1315
net_if_set_link_addr (iface , dev_data -> mac_addr ,
1215
1316
sizeof (dev_data -> mac_addr ),
0 commit comments