[U-Boot] FEC and EFI Simple Network

Fabio Estevam festevam at gmail.com
Wed Mar 28 21:54:23 UTC 2018


Adding Joe in case he has some ideas.

On Tue, Mar 27, 2018 at 9:12 AM, Patrick Wildt <patrick at blueri.se> wrote:
> Hi,
>
> I have been debugging network issues when running an EFI Application
> that uses the EFI Simple Network protocol on an i.MX6 machine (FEC).
>
> The symptom is that u-boot's (FEC) internal RX ring index is reset to 0,
> while the controller is still at idx 3 (or something else).  This is
> caused by the following circumstances:
>
> The Simple Network protocol offers methods like Start(), Stop(),
> Initialize(), Shutdown(), Reset().  Also the protocol has a state.  The
> states are Stopped, Started, Initialized.  The transition is as follows:
>
> Stopped ---Start()---> Started ---Initialize()--> Initialized
>
> Start() does some initialization, Initialize() allocates the TX/RX
> descriptors and actually kicks off the network engine.
>
> So far, only Initialize() is implemented in our u-boot interface, and it
> calls eth_init() which in the end calls fec_init().  Our network state
> is _always_ Started.  This means that EFI Applications see that that the
> state is Started and then call Initialize() to start the actual network
> traffic.  There is no call to Stop()/Shutdown()/Reset() as it's supposed
> to be in a sane state.
>
> In my case the FEC is already initialized since I booted using network
> and the RX desc index is already non-zero.  Now the EFI Application sees
> that the state is Started, calls Initialize() which makes u-boot call
> eth_init() which then calls fec_init().
>
> fec_init() does not reset the controller so that the controller-internal
> RX desc index is not reset to zero.  fec_init() calls fec_open() which
> then resets the driver-internal RX desc index to zero.  Now they are out
> of sync, boom.
>
> This means that fec_init() without a previous fec_halt() breaks the
> whole network if it was already running.  The Designware driver as used
> by some sunxi platforms does a reset of the controller in the init
> function.  Maybe calling fec_halt() at the start of fec_init() could be
> a possible solution?
>
> Patrick
>
> diff --git a/drivers/net/fec_mxc.c b/drivers/net/fec_mxc.c
> index ff7ad91116..ba8bd9920d 100644
> --- a/drivers/net/fec_mxc.c
> +++ b/drivers/net/fec_mxc.c
> @@ -522,6 +522,12 @@ static int fec_open(struct eth_device *edev)
>         return 0;
>  }
>
> +#ifdef CONFIG_DM_ETH
> +static void fecmxc_halt(struct udevice *dev);
> +#else
> +static void fec_halt(struct eth_device *dev);
> +#endif
> +
>  #ifdef CONFIG_DM_ETH
>  static int fecmxc_init(struct udevice *dev)
>  #else
> @@ -537,6 +543,15 @@ static int fec_init(struct eth_device *dev, bd_t *bd)
>         u8 *i;
>         ulong addr;
>
> +#ifdef CONFIG_DM_ETH
> +       fecmxc_halt(dev);
> +#else
> +       fec_halt(dev);
> +#endif
> +
> +       writel(~FEC_TCNTRL_GTS & readl(&fec->eth->x_cntrl),
> +              &fec->eth->x_cntrl);
> +
>         /* Initialize MAC address */
>  #ifdef CONFIG_DM_ETH
>         fecmxc_set_hwaddr(dev);
> @@ -825,19 +840,12 @@ static int fec_recv(struct eth_device *dev)
>         }
>         if (ievent & FEC_IEVENT_HBERR) {
>                 /* Heartbeat error */
> -               writel(0x00000001 | readl(&fec->eth->x_cntrl),
> +               writel(FEC_TCNTRL_GTS | readl(&fec->eth->x_cntrl),
>                        &fec->eth->x_cntrl);
>         }
>         if (ievent & FEC_IEVENT_GRA) {
>                 /* Graceful stop complete */
> -               if (readl(&fec->eth->x_cntrl) & 0x00000001) {
> -#ifdef CONFIG_DM_ETH
> -                       fecmxc_halt(dev);
> -#else
> -                       fec_halt(dev);
> -#endif
> -                       writel(~0x00000001 & readl(&fec->eth->x_cntrl),
> -                              &fec->eth->x_cntrl);
> +               if (readl(&fec->eth->x_cntrl) & FEC_TCNTRL_GTS) {
>  #ifdef CONFIG_DM_ETH
>                         fecmxc_init(dev);
>  #else
> _______________________________________________
> U-Boot mailing list
> U-Boot at lists.denx.de
> https://lists.denx.de/listinfo/u-boot


More information about the U-Boot mailing list