Skip to content

Commit 56b3374

Browse files
Update STM32Hxx port to use HW MAC hashtable filter (#970)
* fix * MAC filter updated for DAD and IPv6 all nodes multicast * add more comments * fix formatting * fix comments * fix review comments * fix formatting * update review comments * enable multicast packets in MAC * use multi cast MAC filter * fix formatting * update naming and comments * update comments and formatting * rename function * fix formatting * fix spell check * Uncrustify: triggered by comment --------- Co-authored-by: GitHub Action <[email protected]>
1 parent c0f5ba0 commit 56b3374

File tree

1 file changed

+98
-50
lines changed

1 file changed

+98
-50
lines changed

source/portable/NetworkInterface/STM32Hxx/NetworkInterface.c

Lines changed: 98 additions & 50 deletions
Original file line numberDiff line numberDiff line change
@@ -65,10 +65,15 @@
6565
#endif
6666

6767
/* Interrupt events to process: reception, transmission and error handling. */
68-
#define EMAC_IF_RX_EVENT 1UL
69-
#define EMAC_IF_TX_EVENT 2UL
70-
#define EMAC_IF_ERR_EVENT 4UL
68+
#define EMAC_IF_RX_EVENT 1UL
69+
#define EMAC_IF_TX_EVENT 2UL
70+
#define EMAC_IF_ERR_EVENT 4UL
7171

72+
/*
73+
* Enable either Hash or Perfect Filter, Multicast filter - None,
74+
* Enable Hash Multicast (HMC), and Enable Hash Unicast (HUC).
75+
*/
76+
#define ENABLE_HASH_FILTER_SETTINGS ( ( uint32_t ) 0x00000416U )
7277

7378
#ifndef niEMAC_HANDLER_TASK_NAME
7479
#define niEMAC_HANDLER_TASK_NAME "EMAC-task"
@@ -205,33 +210,91 @@ const PhyProperties_t xPHYProperties =
205210
};
206211
/*-----------------------------------------------------------*/
207212

208-
static void prvMACAddressConfig( ETH_HandleTypeDef * heth,
209-
uint32_t ulIndex,
210-
const uint8_t * Addr )
213+
/* Reverse the bits of a 32 bit unsigned integer */
214+
static uint32_t prvRevBits32( uint32_t ulValue )
211215
{
212-
uint32_t ulTempReg;
213-
uint32_t ulETH_MAC_ADDR_HBASE = ( uint32_t ) &( heth->Instance->MACA0HR );
214-
uint32_t ulETH_MAC_ADDR_LBASE = ( uint32_t ) &( heth->Instance->MACA0LR );
216+
uint32_t ulRev32;
217+
int iIndex;
215218

216-
/* ETH_MAC_ADDRESS0 reserved for the primary MAC-address. */
217-
configASSERT( ulIndex >= ETH_MAC_ADDRESS1 );
219+
ulRev32 = 0;
218220

219-
/* STM32Hxx devices support 4 MAC address registers
220-
* (ETH_MAC_ADDRESS0 - ETH_MAC_ADDRESS3), make sure ulIndex is not
221-
* more than that. */
222-
configASSERT( ulIndex <= ETH_MAC_ADDRESS3 );
221+
for( iIndex = 0; iIndex < 32; iIndex++ )
222+
{
223+
if( ulValue & ( 1 << iIndex ) )
224+
{
225+
{
226+
ulRev32 |= 1 << ( 31 - iIndex );
227+
}
228+
}
229+
}
223230

224-
/* Calculate the selected MAC address high register. */
225-
ulTempReg = 0xBF000000ul | ( ( uint32_t ) Addr[ 5 ] << 8 ) | ( uint32_t ) Addr[ 4 ];
231+
return ulRev32;
232+
}
233+
234+
/* Compute the CRC32 of the given MAC address as per IEEE 802.3 CRC32 */
235+
static uint32_t prvComputeCRC32_MAC( const uint8_t * pucMAC )
236+
{
237+
int iiIndex, ijIndex;
238+
uint32_t ulCRC32 = 0xFFFFFFFF;
226239

227-
/* Load the selected MAC address high register. */
228-
( *( __IO uint32_t * ) ( ( uint32_t ) ( ulETH_MAC_ADDR_HBASE + ulIndex ) ) ) = ulTempReg;
240+
for( ijIndex = 0; ijIndex < 6; ijIndex++ )
241+
{
242+
ulCRC32 = ulCRC32 ^ ( uint32_t ) pucMAC[ ijIndex ];
229243

230-
/* Calculate the selected MAC address low register. */
231-
ulTempReg = ( ( uint32_t ) Addr[ 3 ] << 24 ) | ( ( uint32_t ) Addr[ 2 ] << 16 ) | ( ( uint32_t ) Addr[ 1 ] << 8 ) | Addr[ 0 ];
244+
for( iiIndex = 0; iiIndex < 8; iiIndex++ )
245+
{
246+
if( ulCRC32 & 1 )
247+
{
248+
ulCRC32 = ( ulCRC32 >> 1 ) ^ prvRevBits32( 0x04C11DB7 ); /* IEEE 802.3 CRC32 polynomial - 0x04C11DB7 */
249+
}
250+
else
251+
{
252+
ulCRC32 = ( ulCRC32 >> 1 );
253+
}
254+
}
255+
}
232256

233-
/* Load the selected MAC address low register */
234-
( *( __IO uint32_t * ) ( ( uint32_t ) ( ulETH_MAC_ADDR_LBASE + ulIndex ) ) ) = ulTempReg;
257+
ulCRC32 = ~( ulCRC32 );
258+
return ulCRC32;
259+
}
260+
261+
/* Compute the hash value of a given MAC address to index the bits in the Hash Table
262+
* Registers (ETH_MACHT0R and ETH_MACHT1R) */
263+
static uint32_t prvComputeEthernet_MACHash( const uint8_t * pucMAC )
264+
{
265+
uint32_t ulCRC32;
266+
uint32_t ulHash;
267+
268+
/* Calculate the 32-bit CRC for the MAC */
269+
ulCRC32 = prvComputeCRC32_MAC( pucMAC );
270+
271+
/* Perform bitwise reversal on the CRC32 */
272+
ulHash = prvRevBits32( ulCRC32 );
273+
274+
/* Take the upper 6 bits of the above result */
275+
return( ulHash >> 26 );
276+
}
277+
278+
/* Update the Hash Table Registers
279+
* (ETH_MACHT0R and ETH_MACHT1R) with hash value of the given MAC address */
280+
static void prvSetMAC_HashFilter( ETH_HandleTypeDef * pxEthHandle,
281+
const uint8_t * pucMAC )
282+
{
283+
uint32_t ulHash;
284+
285+
/* Compute the hash */
286+
ulHash = prvComputeEthernet_MACHash( pucMAC );
287+
288+
/* Use the upper (MACHT1R) or lower (MACHT0R) Hash Table Registers
289+
* to set the required bit based on the ulHash */
290+
if( ulHash < 32 )
291+
{
292+
pxEthHandle->Instance->MACHT0R |= ( 1 << ulHash );
293+
}
294+
else
295+
{
296+
pxEthHandle->Instance->MACHT1R |= ( 1 << ( ulHash % 32 ) );
297+
}
235298
}
236299

237300
/*-----------------------------------------------------------*/
@@ -264,7 +327,6 @@ static BaseType_t xSTM32H_NetworkInterfaceInitialise( NetworkInterface_t * pxInt
264327
NetworkEndPoint_t * pxEndPoint;
265328
HAL_StatusTypeDef xHalEthInitStatus;
266329
size_t uxIndex = 0;
267-
BaseType_t xMACEntry = ETH_MAC_ADDRESS1; /* ETH_MAC_ADDRESS0 reserved for the primary MAC-address. */
268330

269331
if( xMacInitStatus == eMACInit )
270332
{
@@ -294,6 +356,9 @@ static BaseType_t xSTM32H_NetworkInterfaceInitialise( NetworkInterface_t * pxInt
294356
/* Only for inspection by debugger. */
295357
( void ) xHalEthInitStatus;
296358

359+
/* Update MAC filter settings */
360+
xEthHandle.Instance->MACPFR |= ENABLE_HASH_FILTER_SETTINGS;
361+
297362
/* Configuration for HAL_ETH_Transmit(_IT). */
298363
memset( &( xTxConfig ), 0, sizeof( ETH_TxPacketConfig ) );
299364
xTxConfig.Attributes = ETH_TX_PACKETS_FEATURES_CRCPAD;
@@ -340,27 +405,23 @@ static BaseType_t xSTM32H_NetworkInterfaceInitialise( NetworkInterface_t * pxInt
340405
#if ( ipconfigUSE_MDNS == 1 )
341406
{
342407
/* Program the MDNS address. */
343-
prvMACAddressConfig( &xEthHandle, xMACEntry, ( uint8_t * ) xMDNS_MacAddress.ucBytes );
344-
xMACEntry += 8;
408+
prvSetMAC_HashFilter( &xEthHandle, ( uint8_t * ) xMDNS_MacAddress.ucBytes );
345409
}
346410
#endif
347411
#if ( ( ipconfigUSE_MDNS == 1 ) && ( ipconfigUSE_IPv6 != 0 ) )
348412
{
349-
prvMACAddressConfig( &xEthHandle, xMACEntry, ( uint8_t * ) xMDNS_MACAddressIPv6.ucBytes );
350-
xMACEntry += 8;
413+
prvSetMAC_HashFilter( &xEthHandle, ( uint8_t * ) xMDNS_MacAddressIPv6.ucBytes );
351414
}
352415
#endif
353416
#if ( ipconfigUSE_LLMNR == 1 )
354417
{
355418
/* Program the LLMNR address. */
356-
prvMACAddressConfig( &xEthHandle, xMACEntry, ( uint8_t * ) xLLMNR_MacAddress.ucBytes );
357-
xMACEntry += 8;
419+
prvSetMAC_HashFilter( &xEthHandle, ( uint8_t * ) xLLMNR_MacAddress.ucBytes );
358420
}
359421
#endif
360422
#if ( ( ipconfigUSE_LLMNR == 1 ) && ( ipconfigUSE_IPv6 != 0 ) )
361423
{
362-
prvMACAddressConfig( &xEthHandle, xMACEntry, ( uint8_t * ) xLLMNR_MacAddressIPv6.ucBytes );
363-
xMACEntry += 8;
424+
prvSetMAC_HashFilter( &xEthHandle, ( uint8_t * ) xLLMNR_MacAddressIPv6.ucBytes );
364425
}
365426
#endif
366427

@@ -377,8 +438,7 @@ static BaseType_t xSTM32H_NetworkInterfaceInitialise( NetworkInterface_t * pxInt
377438

378439
if( xEthHandle.Init.MACAddr != ( uint8_t * ) pxEndPoint->xMACAddress.ucBytes )
379440
{
380-
prvMACAddressConfig( &xEthHandle, xMACEntry, pxEndPoint->xMACAddress.ucBytes );
381-
xMACEntry += 8;
441+
prvSetMAC_HashFilter( &xEthHandle, pxEndPoint->xMACAddress.ucBytes );
382442
}
383443
break;
384444
#endif /* ( ipconfigUSE_IPv4 != 0 ) */
@@ -394,8 +454,7 @@ static BaseType_t xSTM32H_NetworkInterfaceInitialise( NetworkInterface_t * pxInt
394454

395455
/* Allow traffic destined to Solicited-Node multicast address of this endpoint
396456
* for Duplicate Address Detection (DAD) */
397-
prvMACAddressConfig( &xEthHandle, xMACEntry, ucMACAddress );
398-
xMACEntry += 8;
457+
prvSetMAC_HashFilter( &xEthHandle, ucMACAddress );
399458
}
400459
break;
401460
#endif /* ( ipconfigUSE_IPv6 != 0 ) */
@@ -404,25 +463,14 @@ static BaseType_t xSTM32H_NetworkInterfaceInitialise( NetworkInterface_t * pxInt
404463
/* MISRA 16.4 Compliance */
405464
break;
406465
}
407-
408-
if( xMACEntry > ( BaseType_t ) ETH_MAC_ADDRESS3 )
409-
{
410-
/* No more locations available. */
411-
break;
412-
}
413466
}
414467
}
415468

416469
#if ( ipconfigUSE_IPv6 != 0 )
417470
{
418-
if( xMACEntry <= ( BaseType_t ) ETH_MAC_ADDRESS3 )
419-
{
420-
/* Allow traffic destined to IPv6 all nodes multicast MAC 33:33:00:00:00:01 */
421-
uint8_t ucMACAddress[ 6 ] = { 0x33, 0x33, 0, 0, 0, 0x01 };
422-
423-
prvMACAddressConfig( &xEthHandle, xMACEntry, ucMACAddress );
424-
xMACEntry += 8;
425-
}
471+
/* Allow traffic destined to IPv6 all nodes multicast MAC 33:33:00:00:00:01 */
472+
const uint8_t ucMACAddress[ 6 ] = { 0x33, 0x33, 0, 0, 0, 0x01 };
473+
prvSetMAC_HashFilter( &xEthHandle, ucMACAddress );
426474
}
427475
#endif /* ( ipconfigUSE_IPv6 != 0 ) */
428476

0 commit comments

Comments
 (0)