11/*
2- * Copyright (c) 2015-2023 Arm Limited. All rights reserved.
2+ * Copyright (c) 2015-2025 Arm Limited. All rights reserved.
33 *
44 * SPDX-License-Identifier: Apache-2.0
55 *
@@ -101,14 +101,35 @@ static int32_t ETH_RunTransfer (const uint8_t *out, uint8_t *in, uint32_t len, u
101101 if ((Event & ARM_ETH_MAC_EVENT_RX_FRAME ) || !capab .event_rx_frame ) {
102102 size = eth_mac -> GetRxFrameSize ();
103103 if (size > 0 ) {
104+ if ((size < 14 ) || (size > 14 + ETH_MTU )) {
105+ eth_mac -> ReadFrame (NULL , 0U );
106+ return ARM_DRIVER_ERROR ;
107+ }
104108 eth_mac -> ReadFrame (in , size );
105109 return ARM_DRIVER_OK ;
106110 }
107111 }
108112 }
109113 while ((GET_SYSTICK () - tick ) < SYSTICK_MICROSEC (ETH_TRANSFER_TIMEOUT * 1000 ));
110114
111- return ARM_DRIVER_ERROR ;
115+ return ARM_DRIVER_ERROR_TIMEOUT ;
116+ }
117+
118+ #define ETH_CheckAddressFilter () ETH_CheckFilter(0)
119+ #define ETH_CheckVlanFilter () ETH_CheckFilter(1)
120+
121+ // Check multicast address and VLAN filtering support
122+ static int32_t ETH_CheckFilter (int32_t vlan ) {
123+ int32_t retv ;
124+
125+ eth_mac -> Initialize (cb_event );
126+ eth_mac -> PowerControl (ARM_POWER_FULL );
127+ retv = (!vlan ) ? eth_mac -> SetAddressFilter (NULL , 0 ) :
128+ eth_mac -> Control (ARM_ETH_MAC_VLAN_FILTER , 0 );
129+ eth_mac -> PowerControl (ARM_POWER_OFF );
130+ eth_mac -> Uninitialize ();
131+
132+ return retv ;
112133}
113134
114135// Initialize MAC driver wrapper for RMII interface
@@ -634,6 +655,12 @@ The internal Ethernet MAC loopback is used for the test.
634655void ETH_MAC_SetAddressFilter (void ) {
635656 uint32_t i ,tick ;
636657
658+ if (ETH_CheckAddressFilter () == ARM_DRIVER_ERROR_UNSUPPORTED ) {
659+ /* Multicast address filtering not supported */
660+ TEST_MESSAGE ("[WARNING] Multicast address filtering is not supported" );
661+ return ;
662+ }
663+
637664 /* Allocate buffers */
638665 buffer_out = (uint8_t * )malloc (64 );
639666 TEST_ASSERT (buffer_out != NULL );
@@ -769,6 +796,98 @@ void ETH_MAC_SetAddressFilter (void) {
769796 free (buffer_in );
770797}
771798
799+ /*=======0=========1=========2=========3=========4=========5=========6=========7=========8=========9=========0=========1====*/
800+ /**
801+ \brief Function: ETH_MAC_VLAN_Filter
802+ \details
803+ The function \b ETH_MAC_VLAN_Filter verifies the Ethernet MAC Virtual LAN filtering with the following sequence:
804+ - Buffer allocation
805+ - Initialize
806+ - Power on
807+ - Transfer VLAN packets
808+ - Receive VLAN packets
809+ - Power off
810+ - Uninitialize
811+
812+ \note
813+ The internal Ethernet MAC loopback is used for the test.
814+ */
815+ void ETH_MAC_VLAN_Filter (void ) {
816+ const uint8_t IP_frame [] = {
817+ 0x01 ,0x00 ,0x5e ,0x00 ,0x00 ,0x01 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x81 ,0x00 ,0x00 ,0x00 ,
818+ 0x08 ,0x00 ,0x45 ,0x00 ,0x00 ,0x1c ,0x65 ,0x51 ,0x00 ,0x00 ,0x01 ,0x02 ,0xb2 ,0xe3 ,0xc0 ,0xa8 ,
819+ 0x01 ,0x02 ,0xe0 ,0x00 ,0x00 ,0x01 ,0x11 ,0x64 ,0xee ,0x9b ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,
820+ 0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00
821+ };
822+ const uint16_t test_id [] = { 1 ,2 ,100 ,500 ,1000 ,1005 ,1006 ,1500 ,2000 ,4000 ,4093 };
823+ const uint16_t vlan_id [] = { 1 ,20 ,100 ,1000 ,2000 ,4093 };
824+ uint32_t i ,j ;
825+
826+ if (ETH_CheckVlanFilter () == ARM_DRIVER_ERROR_UNSUPPORTED ) {
827+ /* VLAN tagged frame filtering not supported */
828+ TEST_MESSAGE ("[WARNING] VLAN filtering is not supported" );
829+ return ;
830+ }
831+
832+ /* Allocate buffers */
833+ buffer_out = (uint8_t * )malloc (64 );
834+ TEST_ASSERT (buffer_out != NULL );
835+ if (buffer_out == NULL ) return ;
836+ buffer_in = (uint8_t * )malloc (64 );
837+ TEST_ASSERT (buffer_in != NULL );
838+ if (buffer_in == NULL ) { free (buffer_out ); return ; }
839+
840+ /* Initialize, power on and configure MAC and PHY */
841+ TEST_ASSERT (eth_mac -> Initialize (cb_event ) == ARM_DRIVER_OK );
842+ TEST_ASSERT (eth_mac -> PowerControl (ARM_POWER_FULL ) == ARM_DRIVER_OK );
843+ TEST_ASSERT (eth_mac -> SetMacAddress (& mac_addr ) == ARM_DRIVER_OK );
844+ TEST_ASSERT (eth_mac -> Control (ARM_ETH_MAC_CONFIGURE , ARM_ETH_MAC_SPEED_100M |
845+ ARM_ETH_MAC_DUPLEX_FULL | ARM_ETH_MAC_ADDRESS_BROADCAST ) == ARM_DRIVER_OK );
846+ TEST_ASSERT (eth_phy -> Initialize (eth_mac -> PHY_Read , eth_mac -> PHY_Write ) == ARM_DRIVER_OK );
847+ TEST_ASSERT (eth_phy -> PowerControl (ARM_POWER_FULL ) == ARM_DRIVER_OK );
848+ osDelay (100 );
849+ TEST_ASSERT (eth_phy -> SetInterface (capab .media_interface ) == ARM_DRIVER_OK );
850+ TEST_ASSERT (eth_phy -> SetMode (ARM_ETH_PHY_AUTO_NEGOTIATE ) == ARM_DRIVER_OK );
851+ TEST_ASSERT (eth_mac -> Control (ARM_ETH_MAC_CONTROL_RX , 1 ) == ARM_DRIVER_OK );
852+ TEST_ASSERT (eth_mac -> Control (ARM_ETH_MAC_CONTROL_TX , 1 ) == ARM_DRIVER_OK );
853+
854+ /* Set Ethernet frame */
855+ memcpy (buffer_out , IP_frame , sizeof (IP_frame ));
856+ memcpy (& buffer_out [6 ], & mac_addr , 6 );
857+
858+ TEST_ASSERT (eth_mac -> Control (ARM_ETH_MAC_CONFIGURE , ARM_ETH_MAC_SPEED_100M | ARM_ETH_MAC_DUPLEX_FULL |
859+ ARM_ETH_MAC_ADDRESS_MULTICAST | ARM_ETH_MAC_LOOPBACK ) == ARM_DRIVER_OK );
860+
861+ for (i = 0 ; i < ARRAY_SIZE (vlan_id ); i ++ ) {
862+ TEST_ASSERT (eth_mac -> Control (ARM_ETH_MAC_VLAN_FILTER ,
863+ ARM_ETH_MAC_VLAN_FILTER_ID_ONLY | vlan_id [i ]) == ARM_DRIVER_OK );
864+ for (j = 0 ; j < ARRAY_SIZE (test_id ); j ++ ) {
865+ int32_t retv ;
866+ /* Set VLAN ID tag */
867+ buffer_out [14 ] = (test_id [j ] >> 8 ) & 0xFF ;
868+ buffer_out [15 ] = test_id [j ] & 0xFF ;
869+ retv = ETH_RunTransfer (buffer_out , buffer_in , 64 , 0 );
870+ if (((test_id [j ] == vlan_id [i ]) && (retv != ARM_DRIVER_OK )) ||
871+ ((test_id [j ] != vlan_id [i ]) && (retv == ARM_DRIVER_OK ))) {
872+ snprintf (str ,sizeof (str ),"[FAILED] VLAN tag %d" ,vlan_id [i ]);
873+ TEST_FAIL_MESSAGE (str );
874+ break ;
875+ }
876+ else TEST_PASS ();
877+ }
878+ }
879+
880+ /* Power off and uninitialize */
881+ TEST_ASSERT (eth_phy -> PowerControl (ARM_POWER_OFF ) == ARM_DRIVER_OK );
882+ TEST_ASSERT (eth_phy -> Uninitialize () == ARM_DRIVER_OK );
883+ TEST_ASSERT (eth_mac -> PowerControl (ARM_POWER_OFF ) == ARM_DRIVER_OK );
884+ TEST_ASSERT (eth_mac -> Uninitialize () == ARM_DRIVER_OK );
885+
886+ /* Free buffers */
887+ free (buffer_out );
888+ free (buffer_in );
889+ }
890+
772891/*=======0=========1=========2=========3=========4=========5=========6=========7=========8=========9=========0=========1====*/
773892/**
774893\brief Function: ETH_MAC_SignalEvent
@@ -1222,7 +1341,7 @@ void ETH_Loopback_External (void) {
12221341 while (eth_phy -> GetLinkState () != ARM_ETH_LINK_UP ) {
12231342 if ((GET_SYSTICK () - tick ) >= SYSTICK_MICROSEC (ETH_LINK_TIMEOUT * 1000 )) {
12241343 TEST_FAIL_MESSAGE ("[FAILED] Link down, connect Ethernet cable" );
1225- goto end ;
1344+ goto exit ;
12261345 }
12271346 }
12281347
@@ -1232,7 +1351,7 @@ void ETH_Loopback_External (void) {
12321351 (uint32_t )info .duplex << ARM_ETH_MAC_DUPLEX_Pos |
12331352 ARM_ETH_MAC_ADDRESS_BROADCAST ) == ARM_DRIVER_OK );
12341353
1235- /* Clear input buffer*/
1354+ /* Clear input buffer */
12361355 memset (buffer_in , 0 , 14 + ETH_MTU );
12371356 if (ETH_RunTransfer (buffer_out , buffer_in , 14 + ETH_MTU , 0 ) != ARM_DRIVER_OK ) {
12381357 TEST_FAIL_MESSAGE ("[FAILED] Transfer external cable loopback" );
@@ -1241,11 +1360,12 @@ void ETH_Loopback_External (void) {
12411360 } else TEST_PASS ();
12421361
12431362 /* Power off and uninitialize */
1363+ exit :
12441364 TEST_ASSERT (eth_phy -> PowerControl (ARM_POWER_OFF ) == ARM_DRIVER_OK );
12451365 TEST_ASSERT (eth_phy -> Uninitialize () == ARM_DRIVER_OK );
12461366 TEST_ASSERT (eth_mac -> PowerControl (ARM_POWER_OFF ) == ARM_DRIVER_OK );
12471367 TEST_ASSERT (eth_mac -> Uninitialize () == ARM_DRIVER_OK );
1248- end :
1368+
12491369 /* Free buffers */
12501370 free (buffer_out );
12511371 free (buffer_in );
0 commit comments