[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-ID: <babc13c4-b0ad-03b3-b635-c14cfef19399@gmail.com>
Date: Sat, 9 Dec 2017 10:49:33 -0800
From: Florian Fainelli <f.fainelli@...il.com>
To: Mason <slash.tmp@...e.fr>, Andrew Lunn <andrew@...n.ch>
Cc: netdev <netdev@...r.kernel.org>, David Miller <davem@...emloft.net>
Subject: Re: Waiting for the PHY to complete auto-negotiation
On 12/07/2017 08:17 AM, Mason wrote:
> On 07/12/2017 00:00, Florian Fainelli wrote:
>
>> On 12/06/2017 11:25 AM, Mason wrote:
>>
>>> When we detect link down, we put the ethernet HW block in reset,
>>> and repeat initialization when the link comes back up.
>>>
>>> Hmmm, however, at the moment, I only reset on an administrative
>>> (user-requested) link down, i.e. through ndo_stop. I would probably
>>> have to handle cable unplug/replug events as well.
>>>
>>> Or just consider the quirk to make flow control too complicated
>>> to implement correctly...
>>
>> I suppose your procedure is fine, but don't you have a better way to
>> resolve that by trying to place a special RX DMA ring entry that allows
>> your RX DMA not to be entirely stopped, but intentionally looped through
>> a buffer that you control? As long as you can stop the Ethernet MAC RX,
>> working with such a limitation is probably fine, but this really sounds
>> like a huge pain in the butt and a major HW flaw.
>
> Could you elaborate a bit on your suggestion?
> (Special ring entry, looped through a buffer under my control)
> Is this a typical thing to do to stop DMA?
What I was thinking is something along the lines of what step 5 does
already, without requiring the need to loop back and sending 5 packets,
just placing an EOC descriptor, and forcing a reduction of the RX ring
size such that you hit that descriptor right away, and have DMA be
contained within that single entry in order to safely stop it. Question
is of course, how to take it out of that state considering that usually
the RX DMA produces status bits (unlike TX where the CPU produces those
bits).
>
> Currently the driver tries to stop DMA in nb8800_dma_stop(),
> which does the following:
>
> http://elixir.free-electrons.com/linux/latest/source/drivers/net/ethernet/aurora/nb8800.c#L881
>
> 1) poll until TX finishes (I assume the system no longer accepts new
> frames to send at this point)
> 2) set the EOC (end of chain) bit on all descriptors (could there be
> a problem if we receive a frame at that moment? Don't we need some
> kind of lock?)
If you have disabled the RX interrupt and quiesced NAPI, this should be
safe.
> 3) disable address filtering (need to check what this does)
> 4) enable loop-back mode
> 5) send up to 5 "fake" packets in order to hit an EOC descriptor
That's quite unusual.
>
> The reason I'm trying to move away from this method is that it doesn't
> work on our new SoC; and when pressed, the HW dev said it had never been
> supported. (Also I find it somewhat hackish, but that's a matter of taste.)
Having any HW state machine requiring X number of clock cycles to
guarantee a full transition to a stopped state is not unusual, however,
the fact that you need to send 5 packets to guarantee an EOC descriptor
is hit is completely unusual. Ideally there is a single bit that tells
the DMA engine: you are enabled, do your thing, or you are now disabled,
and you must stop all accesses to DRAM *now*.
So what would be the correct way to quiesce that controller according to
your HW folks?
--
Florian
Powered by blists - more mailing lists