EthernetInterface Multicast UDP does not work at all on FRDMK64

18 Jan 2015

Using EthernetInterface revision 45:d1ccbed7687a on the FRDM K64 platform, the following code does not receive any multicast packets whatsoever.

It does however receive unicast packets sent to its IP address, so it has not frozen.

Wireshark indicates that it does sends the IGMP v2 join requests. (IGMP snooping is turned off in my switch so this should work even without any IGMP.)

When I send a multicast packet to 224.1.1.1 the activity LED blinks implying multicast packets do enter the device, however receiveFrom() does not return.

It appears that EthernetInterface is discarding any packets sent to the multicast address that has been joined instead of passing them onwards to the user application.

I don't know whether this works on the LPC1768 as I don't have the hardware to test.

Looking at the K64 reference manual it appears that the K64 has hardware multicast (and IP!) filtering support, which needs to be properly configured. I'm looking into how this should be done but don't know yet. (And the online compiler has been falling over a lot today so it's got frustrating to test.)

Test Multicast

#include "mbed.h"
#include "rtos.h"

#include "EthernetInterface.h"

const int ECHO_SERVER_PORT = 5007;
const int BUFFER_SIZE = 256;
const char* MCAST_GRP = "224.1.1.1";

char buffer[BUFFER_SIZE] = { 0 };

DigitalOut ledRed(LED_RED, 1);
DigitalOut ledGreen(LED_GREEN, 1);
DigitalOut ledBlue(LED_BLUE, 1);

Serial pc(USBTX, USBRX);

int main()
{
    pc.puts("Start\r\n");
    ledRed = 0;

    EthernetInterface eth;
    pc.puts("Init...\r\n");
    eth.init(); //Use DHCP
    //eth.init(ip,mask,gateway); //Use Static IP Configuration

    pc.puts("Connect\r\n");
    while (eth.connect(10000)) {ledRed = !ledRed;}    // Keep trying until it connects

    // Turn LED blue
    ledRed = 1;
    ledBlue = 0;

    pc.printf("Server IP Address is %s:%d\r\n", eth.getIPAddress(), ECHO_SERVER_PORT);

    UDPSocket server;
    server.bind(ECHO_SERVER_PORT);
    if (server.join_multicast_group(MCAST_GRP) != 0) {
        pc.printf("Error %d joining the multicast group\n");
        while (true) {}
    }

    // Turn LED Green
    ledBlue = 1;
    ledGreen = 0;

    Endpoint client;
    char buffer[256];
    while (true) {
        pc.printf("\nWait for packet...\r\n");
        int n = server.receiveFrom(client, buffer, sizeof(buffer));

        pc.printf("Packet from \"%s\": %s\r\n", client.get_address(), buffer);
        ledRed = !ledRed;
    }
}
18 Jan 2015

This does appear to be a fault in the K64 specifically, as enabling promiscuous mode is a (basic) fix:

In file lwip-eth/arch/TARGET_Freescale/k64f_emac.c

Add the following at the end of the function static err_t low_level_init(struct netif *netif)

Line 361

  // Enable promiscuous mode
  ENET_RCR = ENET_RCR | ENET_RCR_PROM_MASK; // set the PROM bit

This tells the hardware filter to accept all packets.

I believe that lwIP has a callback function to reconfigure hardware filters, however I do not know how to set this.

I would appreciate any help!

15 Nov 2015

Thank you Richard. I was trying for more than two days to turn on the promiscuous mode. Worked perfectly. Greetings from Brazil. Eduardo

20 Feb 2017

Has anyone had any luck configuring the K64F multicast filter registers (GAUR/GALR)? Running in promiscuous mode allows the multicast program above to work, but promiscuous mode can allow a lot of unwanted traffic in. I have got multicast to work with out promiscuous enabled by setting GAUR/GALR to all 1's. The reference manual describes the CRC/hash algorithm to set the MAC filter registers (GAUR/GALR), and there is an implementation in ENET_AddMulticastGroup() in https://github.com/ARMmbed/mbed-os/blob/master/targets/TARGET_Freescale/TARGET_MCUXpresso_MCUS/TARGET_MCU_K64F/drivers/fsl_enet.c But calling that function does NOT seem to allow packets in from the multicast group. Part of the problem is with ARM cc with -O3 which produces incorrect values for the bit-bang CRC. see https://developer.mbed.org/forum/bugs-suggestions/topic/27401/ If you compile with #pragma O2 the CRC operates correctly. EDIT: my test code had an error. Seems OK with O2 now.