* [U-Boot] FEC and EFI Simple Network
@ 2018-03-27 12:12 Patrick Wildt
2018-03-28 21:54 ` Fabio Estevam
0 siblings, 1 reply; 6+ messages in thread
From: Patrick Wildt @ 2018-03-27 12:12 UTC (permalink / raw)
To: u-boot
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
^ permalink raw reply related [flat|nested] 6+ messages in thread
* [U-Boot] FEC and EFI Simple Network
2018-03-27 12:12 [U-Boot] FEC and EFI Simple Network Patrick Wildt
@ 2018-03-28 21:54 ` Fabio Estevam
2018-03-29 4:02 ` Joe Hershberger
0 siblings, 1 reply; 6+ messages in thread
From: Fabio Estevam @ 2018-03-28 21:54 UTC (permalink / raw)
To: u-boot
Adding Joe in case he has some ideas.
On Tue, Mar 27, 2018 at 9:12 AM, Patrick Wildt <patrick@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
^ permalink raw reply [flat|nested] 6+ messages in thread
* [U-Boot] FEC and EFI Simple Network
2018-03-28 21:54 ` Fabio Estevam
@ 2018-03-29 4:02 ` Joe Hershberger
2018-12-02 21:42 ` Alexander Graf
0 siblings, 1 reply; 6+ messages in thread
From: Joe Hershberger @ 2018-03-29 4:02 UTC (permalink / raw)
To: u-boot
Hi Patrick,
On Wed, Mar 28, 2018 at 4:54 PM, Fabio Estevam <festevam@gmail.com> wrote:
> Adding Joe in case he has some ideas.
>
> On Tue, Mar 27, 2018 at 9:12 AM, Patrick Wildt <patrick@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.
Would it be reasonable for fec_init to use a state variable to keep
track of if it (and the HW) is already initialized and not call
fec_open in that case? Also, fec_halt would need to update that state
as well.
>>
>> 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
> _______________________________________________
> U-Boot mailing list
> U-Boot at lists.denx.de
> https://lists.denx.de/listinfo/u-boot
^ permalink raw reply [flat|nested] 6+ messages in thread
* [U-Boot] FEC and EFI Simple Network
2018-03-29 4:02 ` Joe Hershberger
@ 2018-12-02 21:42 ` Alexander Graf
2019-02-23 14:23 ` Alexander Graf
0 siblings, 1 reply; 6+ messages in thread
From: Alexander Graf @ 2018-12-02 21:42 UTC (permalink / raw)
To: u-boot
On 29.03.18 06:02, Joe Hershberger wrote:
> Hi Patrick,
>
> On Wed, Mar 28, 2018 at 4:54 PM, Fabio Estevam <festevam@gmail.com> wrote:
>> Adding Joe in case he has some ideas.
>>
>> On Tue, Mar 27, 2018 at 9:12 AM, Patrick Wildt <patrick@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.
>
> Would it be reasonable for fec_init to use a state variable to keep
> track of if it (and the HW) is already initialized and not call
> fec_open in that case? Also, fec_halt would need to update that state
> as well.
Ping? Is this still an issue?
Alex
^ permalink raw reply [flat|nested] 6+ messages in thread
* [U-Boot] FEC and EFI Simple Network
2018-12-02 21:42 ` Alexander Graf
@ 2019-02-23 14:23 ` Alexander Graf
2019-02-24 4:48 ` Heinrich Schuchardt
0 siblings, 1 reply; 6+ messages in thread
From: Alexander Graf @ 2019-02-23 14:23 UTC (permalink / raw)
To: u-boot
On 02.12.18 22:42, Alexander Graf wrote:
>
>
> On 29.03.18 06:02, Joe Hershberger wrote:
>> Hi Patrick,
>>
>> On Wed, Mar 28, 2018 at 4:54 PM, Fabio Estevam <festevam@gmail.com> wrote:
>>> Adding Joe in case he has some ideas.
>>>
>>> On Tue, Mar 27, 2018 at 9:12 AM, Patrick Wildt <patrick@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.
>>
>> Would it be reasonable for fec_init to use a state variable to keep
>> track of if it (and the HW) is already initialized and not call
>> fec_open in that case? Also, fec_halt would need to update that state
>> as well.
>
> Ping? Is this still an issue?
Last Ping.
Alex
^ permalink raw reply [flat|nested] 6+ messages in thread
* [U-Boot] FEC and EFI Simple Network
2019-02-23 14:23 ` Alexander Graf
@ 2019-02-24 4:48 ` Heinrich Schuchardt
0 siblings, 0 replies; 6+ messages in thread
From: Heinrich Schuchardt @ 2019-02-24 4:48 UTC (permalink / raw)
To: u-boot
On 2/23/19 3:23 PM, Alexander Graf wrote:
>
>
> On 02.12.18 22:42, Alexander Graf wrote:
>>
>>
>> On 29.03.18 06:02, Joe Hershberger wrote:
>>> Hi Patrick,
>>>
>>> On Wed, Mar 28, 2018 at 4:54 PM, Fabio Estevam <festevam@gmail.com> wrote:
>>>> Adding Joe in case he has some ideas.
>>>>
>>>> On Tue, Mar 27, 2018 at 9:12 AM, Patrick Wildt <patrick@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.
>>>
>>> Would it be reasonable for fec_init to use a state variable to keep
>>> track of if it (and the HW) is already initialized and not call
>>> fec_open in that case? Also, fec_halt would need to update that state
>>> as well.
>>
>> Ping? Is this still an issue?
>
> Last Ping.
>
>
> Alex
>
With commit 0c5d2a3dac01 ("efi_loader: completely initialize network")
we changed efi_net_initialize() from only calling eth_init() to execute
the following sequence:
/* Setup packet buffers */
net_init();
/* Disable hardware and put it into the reset state */
eth_halt();
/* Set current device according to environment variables */
eth_set_current();
/* Get hardware ready for send and receive operations */
ret = eth_init();
So I am wondering if our additional call to eth_halt() shouldn't have
fixed the problem that Patrick originally reported.
Best regards
Heinrich
^ permalink raw reply [flat|nested] 6+ messages in thread
end of thread, other threads:[~2019-02-24 4:48 UTC | newest]
Thread overview: 6+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2018-03-27 12:12 [U-Boot] FEC and EFI Simple Network Patrick Wildt
2018-03-28 21:54 ` Fabio Estevam
2018-03-29 4:02 ` Joe Hershberger
2018-12-02 21:42 ` Alexander Graf
2019-02-23 14:23 ` Alexander Graf
2019-02-24 4:48 ` Heinrich Schuchardt
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.