Network problem with STM32F767VIT + V6, ok with V5

I’m struggling getting the network interface working on a STM32F767VIT custom board, with (among things) a MICREL KSZ8863 network switch, running on MBED OS 6.3.0.
The STM is connected to the switch using RMII wiring, as we have done for some time on other boards using other MCU’s (although not this MCU, and not using V6.).

I did a small test program to try and debug the network interface, and if I compile it with V5.13.2, it works, but with V6.3.0, it does not.

I use Exactly the same custom target files on the 2 builds, but a slightly different custom_target.json (else it will not compile on V6).

When I run the test program on V5, eth.connect returns 0 after a few seconds, and then I can ping the MCU through the switch.

On V6, after a much longer time, it returns code -3004 (not connected to a network), and no response on ping.

I would be very happy if anyone could help me with this particular problem.

Test program (irrelevant bits removed):

int main() {
    EMAC* emac;
    emac = &EMAC::get_default_instance();    
    uint8_t macAddr[6];
    memset(macAddr, 0, 6);
    emac->get_hwaddr(macAddr);
    printf("MAC: %02X:%02X:%02X:%02X:%02X:%02X\r\n", macAddr[0], macAddr[1], macAddr[2], macAddr[3], macAddr[4], macAddr[5]);
    EthernetInterface eth;
    printf("Setting network to: IP:10.13.37.201, Mask:255.255.255.0, GW:10.13.37.1\r\n");
    eth.set_network("10.13.37.201", "255.255.255.0", "10.13.37.1");
    printf("Connecting to network...\r\n");
    printf("eth.connect() returned code: %d\n", eth.connect());
    while(1);
}

target_json on V5:

{    
	"MAXON_MB": {
		"inherits": ["FAMILY_STM32"], 
		"core": "Cortex-M7FD",
		"extra_labels_add": ["STM32F7", "STM32F767", "STM32F767xI", "STM32F767VI", "STM_EMAC"],
		"config": {
			"clock_source": {
				"help": "Mask value : USE_PLL_HSE_EXTC | USE_PLL_HSE_XTAL | USE_PLL_HSI",
				"value": "USE_PLL_HSE_XTAL",
				"macro_name": "CLOCK_SOURCE"
			}
        },
        "overrides": {
            "lse_available": 0,
			"network-default-interface-type": "ETHERNET",
            "clock_source": "USE_PLL_HSE_XTAL"
        },
		"macros_add": ["STM32F767xx"],
		"detect_code": ["1234"],
        "components_add": ["FLASHIAP", "SPIF", "TRNG", "FLASH", "MPU", "EMAC", "ETHERNET"],
        "device_has_add": ["CAN", "CRC", "TRNG", "FLASH", "MPU", "ETHERNET", "EMAC"],
        "device_has_remove": ["SERIAL_FC"],
		"supported_toolchains": ["GCC_ARM"],
        "device_name": "STM32F767VI"
	}
}

target_json on V6:

{    
	"MAXON_MB": {
		"inherits": ["MCU_STM32F7"], 
		"core": "Cortex-M7FD",
		"extra_labels_add": ["STM32F7", "STM32F767", "STM32F767xI", "STM32F767VI", "STM_EMAC"],
        "overrides": {
            "lse_available": 0,
			"network-default-interface-type": "ETHERNET",
            "clock_source": "USE_PLL_HSE_XTAL"
        },
		"macros_add": ["STM32F767xx"],
		"detect_code": ["1234"],
        "components_add": ["FLASHIAP", "SPIF", "TRNG", "FLASH", "MPU", "EMAC", "ETHERNET"],
        "device_has_add": ["ANALOGOUT", "CAN", "CRC", "TRNG", "FLASH", "MPU", "ETHERNET", "EMAC"],
        "device_has_remove": ["SERIAL_FC"],
        "features": ["LWIP"],
		"supported_toolchains": ["GCC_ARM"],
        "device_name": "STM32F767VI"
	}
}

As a general strategy, you could always try narrowing down to find the specific OS version that broke the code. You could binary search it: First try mbed 6.0.0, and if that doesn’t work, try versions between 5.13.2 and 6.0.0, and if it does work try versions between 6.0.0 and 6.3.0, etc. Hopefully you should be able to narrow down the specific release that broke the code. Then, look for all changes that release made to the Ethernet code and the STM32F7 target files, and you may be able to figure out what broke it.

I followed your suggestion, and in this process I discovered that the colleague who assembled the V5 repository I used as a template for the test code, had done som changes in the stm32xx_emac.cpp file, where he basically forced autonegotion to disable, removed some lines concerning link and phy status flags, and hardcoded both flags to true instead.

Although this file is different in V6, I managed to do equivalent changes, so in the end I got it working,
even with V6.6.0.

This is maybe not good practice, are there ways to do this by config parameters instead?