Hi Jens, hi Sergio,

Yes that's exactly my problem. Here's the patch I've came up with on my
driver :

int packetCount = 0;

static void eth_notify (ARM_ETH_MAC_EVENT event) {
  /* Send notification on RX event */
  if (event == ARM_ETH_MAC_EVENT_RX_FRAME) {
    packetCount++;
  }
}

void ethernetif_poll (struct netif *netif) {
  struct ethernetif *eth = netif->state;

  if (!eth->phy_ok || eth->link == ARM_ETH_LINK_DOWN) {
    return;
  }
  while (packetCount)
  {
    ethernetif_input (netif);
    atomicDecrement(packetCount);
  }
}

It works perfectly !

Thanks a lot for your help !

Julien.



2014-03-20 19:46 GMT+01:00 Jens Nielsen <[email protected]>:

>  Alright, I also use the ST drivers (the ones from STM32Cube 1.0.0) on an
> STM32F4
>
> I haven't verified that my fix is 100% accurate but I think it looks safe
> so I'm sending it to ST anyway so they can figure it out if they want to.
>
> My fix goes something like this:
>
>
> At the bottom of HAL_ETH_GetReceivedFrame_IT() I return an error code if I
> don't find a complete packet:
>
> ---
> a/clients/embedded/source/STM32F4XX/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_eth.c
> +++
> b/clients/embedded/source/STM32F4XX/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_eth.c
> @@ -868,7 +868,7 @@ HAL_StatusTypeDef
> HAL_ETH_GetReceivedFrame_IT(ETH_HandleTypeDef *heth)
>    __HAL_UNLOCK(heth);
>
>    /* Return function status */
> -  return HAL_OK;
> +  return HAL_ERROR;
>  }
>
>  /**
>
>
>
> And then return NULL from low_level_input() in my ethernetif:
>
> ---
> a/clients/embedded/source/lwip-1.4.1/port/STM32F4x7/FreeRTOS/ethernetif.c
> +++
> b/clients/embedded/source/lwip-1.4.1/port/STM32F4x7/FreeRTOS/ethernetif.c
> @@ -225,7 +224,10 @@ static struct pbuf * low_level_input(struct netif
> *netif)
>    uint32_t i=0;
>
>    /* get received frame */
> -  HAL_ETH_GetReceivedFrame_IT(&EthHandle);
> +  if ( HAL_ETH_GetReceivedFrame_IT(&EthHandle) != HAL_OK )
> +  {
> +      return NULL;
> +  }
>
>    /* Obtain the size of the packet and put it into the "len" variable. */
>    len = EthHandle.RxFrameInfos.length;
>
>
>
> And in my receive task I have this loop (ok yeah this could be prettier...)
>
> +            do
> +            {
> +                p = low_level_input(netif);
> +                if (p != NULL)
> +                {
> +                    if (netif->input(p, netif) != ERR_OK)
> +                    {
> +                        pbuf_free(p);
> +                    }
> +                }
> +            } while (p != NULL);
>
>
> Hope it helps!
>
> BR /Jens
>
>
>
> On 2014-03-20 19:13, Sergio R. Caprile wrote:
>
> Yes Jens, looks like you are absolutely right, missed that, there is no
> frame loss here, the receiving process must be getting only the first
> frame in the "chip" cue.
>
> Julien is using some ST microcontroller, I guess it has a built-in eth
> controller, probably with DMA.
>
> I've studied the Linux drivers for the DM9000 to write my driver, and
> I've seen they read all the packets out of the chip every time; then I
> setup a simple test to see if interrupts would trigger on every frame or
> only on empty buffer, and guess what... empty buffer only (there is no
> int ack here)
>
> Looks like we've got a different situation here, the chip seems to be
> issuing an interrupt after the first one is ACKed, as you Jens described
> for your case.
>
> Julien, can you confirm this from the chip docs ?
> Pitty one has to fix the drivers for a manufacturer, maybe someone in ST
> can lend a hand ?
>
>
>
>
> _______________________________________________
> lwip-users mailing list
> [email protected]
> https://lists.nongnu.org/mailman/listinfo/lwip-users
>
_______________________________________________
lwip-users mailing list
[email protected]
https://lists.nongnu.org/mailman/listinfo/lwip-users

Reply via email to