Keil Logo

MDK MIDDLEWARE: Receiving raw Ethernet data


Information in this knowledgebase article applies to:

  • MDK v5.x
  • Middleware v7.x Network Component

QUESTION

I want to implement additional Ethernet protocols, which are currently not yet supported by Middleware Network library. How to receive raw Ethernet frames so that they can be processed by my own implementation of Ethernet protocols?

ANSWER

So far up to Middleware v7.7, the supported Ethernet types are ARP (0x0806), IPv4 (0x0800) and IPv6 (0x86dd). In order to receive and process raw Ethernet data with the Ethernet types other than these, an user callback function netETH_ReceiveRaw() need to be implemented.

void netETH_ReceiveRaw (uint32_t if_num, const uint8_t *buf, uint32_t len) {
  uint16_t ether_type;

  ether_type = (buf[12] << 8) | buf[13];
  if (ether_type == 0x888E) {                   // EAPoL protocol
    // Process the frame here
  }
}

The user callback function netETH_ReceiveRaw() is called by the Middleware Network stack to provide raw Ethernet frames to user. Such a raw data contains Ethernet header and payload data.

On the other hand, note that if IPv4 protocol is used in your project, by default a MAC layer filter with the option ARM_ETH_MAC_ADDRESS_BROADCAST is applied on the CMSIS MAC driver, so that only Ethernet data frames with a broadcast destination MAC address or with the MAC address of your device as destination MAC address will be received and processed further by your Ethernet interface. The Ethernet data frames with a multicast destination MAC address or with a different unicast destination MAC address will be filtered out.

If you are implementing an Ethernet protocol based on multicast Ethernet data frames, such as PTPv2, the MAC layer filter option needs to be changed to ARM_ETH_MAC_ADDRESS_MULTICAST or ARM_ETH_MAC_ADDRESS_ALL, by calling the CMSIS Driver API ARM_ETH_MAC_Control() inside the user callback function netETH_Notify(), e.g. as follows:

extern ARM_DRIVER_ETH_MAC Driver_ETH_MAC0;
static ARM_DRIVER_ETH_MAC *mac;

void netETH_Notify (uint32_t if_num, netETH_Event event, uint32_t val) {
  NET_ETH_LINK_INFO *info;
  int32_t status;

  switch (event) {
    case netETH_LinkDown:
      printf ("Link is down\n");
      break;
    case netETH_LinkUp:
      printf ("Link is up\n");

      status = mac->Control(ARM_ETH_MAC_CONFIGURE, ARM_ETH_MAC_SPEED_100M | ARM_ETH_MAC_DUPLEX_FULL |
               ARM_ETH_MAC_ADDRESS_ALL);

      if (status != ARM_DRIVER_OK)  // error handling
      {
         printf ("mac->Control error!\n");
      }

      info = (NET_ETH_LINK_INFO *)&val;
      switch (info->speed) {
        case 0:
          printf ("10 MBit\n");
          break;
        case 1:
          printf ("100 MBit\n");
          break;
        case 2:
          printf ("1 GBit\n");
          break;
      }
      switch (info->duplex) {
        case 0:
          printf ("Half duplex\n");
          break;
        case 1:
          printf ("Full duplex\n");
          break;
      }
      break;
    case netETH_Wakeup:
      printf ("Wakeup frame received\n");
      break;
    case netETH_TimerAlarm:
      printf ("Timer alarm\n");
      break;
  }
}

Last Reviewed: Friday, October 12, 2018


Did this article provide the answer you needed?
 
Yes
No
Not Sure
 
  Arm logo
Important information

This site uses cookies to store information on your computer. By continuing to use our site, you consent to our cookies.

Change Settings

Privacy Policy Update

Arm’s Privacy Policy has been updated. By continuing to use our site, you consent to Arm’s Privacy Policy. Please review our Privacy Policy to learn more about our collection, use and transfers
of your data.