[RFC PATCH v2 0/2] nb8800 suspend/resume support
Måns Rullgård
mans at mansr.com
Wed Aug 2 08:36:14 PDT 2017
Mason <slash.tmp at free.fr> writes:
> On 02/08/2017 16:41, Mason wrote:
>
>> On 01/08/2017 18:32, Mason wrote:
>>
>>> I need suspend/resume support in the nb8800 driver.
>>> On tango platforms, suspend loses all context (MMIO registers).
>>> To make the task easy, we just close the device on suspend,
>>> and open it again on resume. This requires properly resetting
>>> the HW on resume.
>>>
>>> Patch 1 moves all the HW init to nb8800_init()
>>> Patch 2 adds suspend/resume support
>>
>> I have now confirmed that the "flow control" issue I reported
>> in another thread has nothing to do with flow control per se.
>>
>> The problem is that nb8800_pause_config() calls nb8800_dma_stop()
>> and when it does, RX is borked.
>>
>> On a GigE switch:
>> [ 21.444268] ENTER nb8800_pause_config
>> [ 21.448604] rxcr=06100a8f pause_rx=1 pause_tx=0 pause=1 asym_pause=1
>> [ 21.455020] nb8800 26000.ethernet eth0: Link is Up - 1Gbps/Full - flow control rx/tx
>>
>> In this case, pause_tx and RCR_FL match, so we skip the
>> silly dance.
>
> The documentation states:
>
> Receive Channel Control Register
> Description:
> The Receive Channel Control Register holds channel enable, mode, endian,
> DMA control, and interrupt control information. This register can only
> be written when the Receive DMA Channel is idle - the Enable bit in it is "0".
> Register Number: 0x200
> Access: read/write
> Reset Value: le = AMBA_LE; all other bits = 0x0
> Fields:
>
> fl: Flow control enable. "1" indicates flow control is enabled.
> When flow control is enabled and a Receive FIFO overrun occurs,
> the Ethernet 10/100/1000 Subsystem will send PAUSE frames if in
> full duplex mode. This continues until the Receive FIFO is emptied.
>
> en: Receive DMA Channel enable. "1" indicates that the Receive
> DMA Channel is being configured from a descriptor, or that the DMA
> operation is in progress. The Receive DMA Channel is idle when
> this enable bit is "0". Software sets this bit to "1" to start the
> configuration from a descriptor and DMA operation. When the DMA
> operation is finished, this bit is automatically reset to "0".
Here's the problem. Once started, there is no way to forcibly stop rx
dma. It keeps going until it hits a descriptor with the end of chain
flag set.
>> Receive DMA Channel Disabling
>>
>> When the entire receive frame has been read from the Receive FIFO and
>> sent over the AMBA bus, the DMA operation ends, and the Receive DMA
>> Channel is automatically disabled. To do this, hardware resets the
>> Enable bit in the Receive Channel Control Register to "0" after the
>> last data has been read from the Receive FIFO and sent over the AMBA
>> bus.
>>
>> When operating in descriptor mode, upon completion of a receive frame
>> DMA operation, if the descriptor chain has not ended when a receive
>> frame DMA operation completes, the next receive frame DMA operation
>> begins. The last descriptor in a descriptor chain is indicated by
>> having its End Of Chain- EOC, flag set to "1". If this EOC flag is
>> "0", to begin the next receive frame DMA operation, the next
>> descriptor is automatically retrieved and used to configure the
>> Receive DMA Channel. The Receive DMA Channel is then automatically
>> re-enabled and the next receive frame DMA operation begins.
>>
>> In descriptor mode, an AMBA bus error can occur when reading receive
>> descriptor data. If this happens, receive descriptor processing ends
>> and the Receive DMA Channel is turned off. The Descriptor Error bit
>> in the Receive Status Register is set to "1".
>
> Hmmm, I guess this is what Maxime/Mans did...
>
> Looking at the tango-specific integration, I note this nugget:
>
> 1.5.4 Stopping & Starting the DMA
>
> This feature has been added to allow the software to stop and start
> the DMA without any issues.
>
> Procedure:
> 1- STOP:
> 2- Stop RX core;
> 3- Set OWN bit of all descriptor of the chain to 1;
> 4- Stop DMA by writing dma_stop bit to 1 in RX_DMA_Stop register
> 5- Wait around 100 clock cycles.
>
> The pending packets are held until the system will re-start.
>
> RE-START:
> 1- Clear dma_stop bit (note that if at the time of stopping the DMA,
> the next packet in the FIFO was an UDP packet, when clearing dma_stop,
> this packet will directly start being written in the DRAM since UDP
> packets are not controlled by the descriptor mechanism);
> 2- Program a new chain of descriptor;
> 3- Re-enable DMA (rx_ctrl register)
>
> rx_dma_stop:
> Software control to stop the Rx DMA.
> A write to this bit with “1” will gracefully stop the Rx DMA by after
> transferring the current packet. If more packets are pending they will
> be held until the software clears this bit.
>
> Hmmm, what do you think? This looks promising...
This is only available in the more recent Sigma versions. Although it
is nicer, I didn't think it was worth the trouble to support both
methods since the older method should work on all chips.
--
Måns Rullgård
More information about the linux-arm-kernel
mailing list