AnsweredAssumed Answered

NOT SEND ARP Gratuitous. STM32CubeMX semantic error in NET driver ethernetif.c

Question asked by drachev.andrei on Oct 28, 2015
Latest reply on Nov 3, 2015 by drachev.andrei
STM32CubeF4 Firmware Package V1.8.0 / 14-August-2015
using board STM3240G-eval.(stm32f407IGH)
1) enable  LWIP_ARP in project, 
2) setttings call: "ethernetif_update_config()" and "ethernetif_set_link()".

Problem: not work protocol ARP Gratuitous
When the device to be connected(connection is via cable) to the network must send ARP packet for detecting duplicate IP. lwip stack does not send ARP packet.
Additional Information
First error in function ethernetif_update_config() :
1) When the link is activated, lwip stack trying to send ARP packet from netif_set_link_up ().
2) From netif_set_link_up () after the call etharp_gratuitous (), the function is called ethernetif_update_config ().
3) In function ethernetif_update_config () is tuned physics. HAL_ETH_ConfigMAC () and HAL_ETH_Start ()

Mistake is that first there is an attempt to send an ARP packet and then going on reconfiguring the physical layer. ARP packet does not have time to go becauseIt is tuned physical layer.

void netif_set_link_up(struct netif *netif )
  if (!(netif->flags & NETIF_FLAG_LINK_UP)) {
    netif->flags |= NETIF_FLAG_LINK_UP;
    if (netif->dhcp) {
#endif /* LWIP_DHCP */
    if (netif->autoip) {
#endif /* LWIP_AUTOIP */
    if (netif->flags & NETIF_FLAG_UP) {
      /* For Ethernet network interfaces, we would like to send a "gratuitous ARP" */ 
      if (netif->flags & NETIF_FLAG_ETHARP) {
        etharp_gratuitous(netif);        //TODO here it goes ARP packet
#endif /* LWIP_ARP */
      /* resend IGMP memberships */
      if (netif->flags & NETIF_FLAG_IGMP) {
        igmp_report_groups( netif);
#endif /* LWIP_IGMP */
    NETIF_LINK_CALLBACK(netif); // TODO here called ethernetif_update_config () and resets physics.

Second error in ethernetif_set_link() :
When linkup occurs, the semaphore is released. lwip stack trying to send ARP packet from netif_set_link_up (), but the physics is not yet time to tune and ARP packet is not sent to the set.
an example of a positive result:

void ethernetif_set_link(void const *argument)
  uint32_t regvalue = 0;
  struct link_str *link_arg = (struct link_str *)argument;  
    if (osSemaphoreWait( link_arg->semaphore, 100)== osOK)
      HAL_Delay(300);//TODO delay helps, but you need to think. 
      /* Read PHY_MISR*/
      HAL_ETH_ReadPHYRegister(&heth, PHY_MISR, &regvalue);
      /* Check whether the link interrupt has occurred or not */
      if((regvalue & PHY_LINK_INTERRUPT) != (uint16_t)RESET)
        /* Read PHY_SR*/
        HAL_ETH_ReadPHYRegister(&heth, PHY_SR, &regvalue);
        /* Check whether the link is up or down*/
        if((regvalue & PHY_LINK_STATUS)!= (uint16_t)RESET)
          netif_set_link_up(link_arg->netif);  //TODO here can not send ARP packet