Re: [PATCH v3 3/4] net: nb8800: Move HW init to ndo_open()

2017-11-16 Thread Marc Gonzalez
On 16/11/2017 17:23, Andrew Lunn wrote:

> Maybe take a look at your memory barriers. Most accesses using the
> _relaxed() version, i.e, no barrier. And then there are specific
> barriers when needed. One could be missing.
> 
> As a quick test, drop the _relaxed. Force a barrier with each
> access. If that works, it is a clear indication you have a barrier
> problem.

That was an interesting suggestion, thanks!

Unfortunately, adding wmb() in dozens of strategic places doesn't
prevent the issue where network connectivity is lost :-(

Regards.



Re: [PATCH v3 3/4] net: nb8800: Move HW init to ndo_open()

2017-11-16 Thread Andrew Lunn
> I'm starting to think there is some kind of race condition between
> SW and HW handling of descriptors. This might also explain the
> out-of-order warnings.

Hi Marc

Maybe take a look at your memory barriers. Most accesses using the
_relaxed() version, i.e, no barrier. And then there are specific
barriers when needed. One could be missing.

As a quick test, drop the _relaxed. Force a barrier with each
access. If that works, it is a clear indication you have a barrier
problem.

Andrew


Re: [PATCH v3 3/4] net: nb8800: Move HW init to ndo_open()

2017-11-16 Thread Marc Gonzalez
On 15/11/2017 17:15, Marc Gonzalez wrote:

> Given the out-of-order datagrams, I'm wondering if it's possible
> for the DMA engine to overwrite a not-yet-read descriptor?
> 
> The EOC flag should stop the DMA engine though...
> 
> Maybe some kind of race...
> 
> I don't think I've been able to trigger the wedge when 256 descriptors
> are used.

I'm still taking stabs in the dark.

Adding a 10 ms delay for every 1024 packets, and using 256 descriptors
doesn't cause any hang, even after an hour.

At 85 packets per ms, 10 ms is large enough to consume all available
descriptors... Yet no issue.

Only when I lower the number of available RX descriptors do I see
the issue. And I don't need any delay...

I'm starting to think there is some kind of race condition between
SW and HW handling of descriptors. This might also explain the
out-of-order warnings.

Lowering the number of RX descriptors to 64, and adding no delay
causes many OUT OF ORDER warnings, and the network locks up in
under a minute:


iperf3: OUT OF ORDER - incoming packet = 13031 and received packet = 0 AND SP = 
13094
iperf3: OUT OF ORDER - incoming packet = 21441 and received packet = 0 AND SP = 
21504
iperf3: OUT OF ORDER - incoming packet = 21442 and received packet = 0 AND SP = 
21504
[ ID] Interval   Transfer Bandwidth   JitterLost/Total 
Datagrams
[  5]   0.00-1.00   sec  97.4 MBytes   817 Mbits/sec  0.016 ms  8793/81753 
(11%)  
iperf3: OUT OF ORDER - incoming packet = 92503 and received packet = 0 AND SP = 
92566
iperf3: OUT OF ORDER - incoming packet = 92504 and received packet = 0 AND SP = 
92566
iperf3: OUT OF ORDER - incoming packet = 125503 and received packet = 0 AND SP 
= 125566
[  5]   1.00-2.00   sec   101 MBytes   851 Mbits/sec  0.011 ms  8835/84797 
(10%)  
iperf3: OUT OF ORDER - incoming packet = 198710 and received packet = 0 AND SP 
= 198773
iperf3: OUT OF ORDER - incoming packet = 243272 and received packet = 0 AND SP 
= 243335
iperf3: OUT OF ORDER - incoming packet = 243791 and received packet = 0 AND SP 
= 243854
[  5]   2.00-3.00   sec   101 MBytes   851 Mbits/sec  0.016 ms  8771/84782 
(10%)  
iperf3: OUT OF ORDER - incoming packet = 294545 and received packet = 0 AND SP 
= 294608
iperf3: OUT OF ORDER - incoming packet = 301719 and received packet = 0 AND SP 
= 301782
iperf3: OUT OF ORDER - incoming packet = 301720 and received packet = 0 AND SP 
= 301782
iperf3: OUT OF ORDER - incoming packet = 305218 and received packet = 0 AND SP 
= 305281
iperf3: OUT OF ORDER - incoming packet = 314655 and received packet = 0 AND SP 
= 314718
iperf3: OUT OF ORDER - incoming packet = 325473 and received packet = 0 AND SP 
= 325536
iperf3: OUT OF ORDER - incoming packet = 325474 and received packet = 0 AND SP 
= 325536
[  5]   3.00-4.00   sec   101 MBytes   850 Mbits/sec  0.013 ms  8903/84798 
(10%)  
iperf3: OUT OF ORDER - incoming packet = 340919 and received packet = 0 AND SP 
= 340982
iperf3: OUT OF ORDER - incoming packet = 340920 and received packet = 0 AND SP 
= 340982
iperf3: OUT OF ORDER - incoming packet = 346325 and received packet = 0 AND SP 
= 346388
iperf3: OUT OF ORDER - incoming packet = 346326 and received packet = 0 AND SP 
= 346388
[  5]   4.00-5.00   sec   101 MBytes   851 Mbits/sec  0.012 ms  8868/84829 
(10%)  
iperf3: OUT OF ORDER - incoming packet = 441873 and received packet = 0 AND SP 
= 441936
iperf3: OUT OF ORDER - incoming packet = 459258 and received packet = 0 AND SP 
= 459321
iperf3: OUT OF ORDER - incoming packet = 495604 and received packet = 0 AND SP 
= 495667
[  5]   5.00-6.00   sec   101 MBytes   850 Mbits/sec  0.013 ms  8835/84760 
(10%)  
iperf3: OUT OF ORDER - incoming packet = 558280 and received packet = 0 AND SP 
= 558343
iperf3: OUT OF ORDER - incoming packet = 558281 and received packet = 0 AND SP 
= 558343
iperf3: OUT OF ORDER - incoming packet = 587445 and received packet = 0 AND SP 
= 587508
iperf3: OUT OF ORDER - incoming packet = 587446 and received packet = 0 AND SP 
= 587508
[  5]   6.00-7.00   sec   102 MBytes   854 Mbits/sec  0.016 ms  8580/84843 
(10%)  
iperf3: OUT OF ORDER - incoming packet = 617324 and received packet = 0 AND SP 
= 617387
iperf3: OUT OF ORDER - incoming packet = 620412 and received packet = 0 AND SP 
= 620475
iperf3: OUT OF ORDER - incoming packet = 635845 and received packet = 0 AND SP 
= 635908
iperf3: OUT OF ORDER - incoming packet = 657102 and received packet = 0 AND SP 
= 657165
iperf3: OUT OF ORDER - incoming packet = 670672 and received packet = 0 AND SP 
= 670735
iperf3: OUT OF ORDER - incoming packet = 670673 and received packet = 0 AND SP 
= 670735
[  5]   7.00-8.00   sec   102 MBytes   853 Mbits/sec  0.012 ms  8582/84757 
(10%)  
iperf3: OUT OF ORDER - incoming packet = 676529 and received packet = 0 AND SP 
= 676592
iperf3: OUT OF ORDER - incoming packet = 682693 and received packet = 0 AND SP 
= 682756
iperf3: OUT OF ORDER - incoming packet = 682694 and received packet = 0 AND SP 
= 682756
iperf3: OUT OF ORDER - incoming packet =

Re: [PATCH v3 3/4] net: nb8800: Move HW init to ndo_open()

2017-11-15 Thread Marc Gonzalez
On 15/11/2017 16:11, Måns Rullgård wrote:

> Well, that's not good.  I'll see if I can replicate it later this week.

In my latest test, I started from v4.14 and only applied the
following patch:

diff --git a/drivers/net/ethernet/aurora/nb8800.c 
b/drivers/net/ethernet/aurora/nb8800.c
index e94159507847..5c109cc4bde8 100644
--- a/drivers/net/ethernet/aurora/nb8800.c
+++ b/drivers/net/ethernet/aurora/nb8800.c
@@ -317,6 +317,7 @@ static int nb8800_poll(struct napi_struct *napi, int budget)
 
len = RX_BYTES_TRANSFERRED(rxd->report);
 
+   udelay(200);
if (IS_RX_ERROR(rxd->report))
nb8800_rx_error(dev, rxd->report);
else
@@ -1246,10 +1247,12 @@ static int nb8800_hw_init(struct net_device *dev)
nb8800_writeb(priv, NB8800_PQ1, val >> 8);
nb8800_writeb(priv, NB8800_PQ2, val & 0xff);
 
+#if 0
/* Auto-negotiate by default */
priv->pause_aneg = true;
priv->pause_rx = true;
priv->pause_tx = true;
+#endif
 
nb8800_mc_init(dev, 0);
 
diff --git a/drivers/net/ethernet/aurora/nb8800.h 
b/drivers/net/ethernet/aurora/nb8800.h
index aacc3cce2cc0..a2d4b841306a 100644
--- a/drivers/net/ethernet/aurora/nb8800.h
+++ b/drivers/net/ethernet/aurora/nb8800.h
@@ -8,7 +8,7 @@
 #include 
 #include 
 
-#define RX_DESC_COUNT  256
+#define RX_DESC_COUNT  16
 #define TX_DESC_COUNT  256
 
 #define NB8800_DESC_LOW4



Once I booted the SMP8759 board, I ran

ip addr add 172.27.64.23/18 brd 172.27.127.255 dev eth0
ip link set eth0 up
sleep 5
iperf3 -s


And from the PC, I ran

iperf3 -c 172.27.64.23 -u -b 0 -l 1400 -t 120


[  5] local 172.27.64.23 port 5201 connected to 172.27.64.1 port 53771
[ ID] Interval   Transfer Bandwidth   JitterLost/Total 
Datagrams
[  5]   0.00-1.00   sec  5.89 MBytes  49.4 Mbits/sec  0.044 ms  77062/81472 
(95%)  
[  5]   1.00-2.00   sec  6.25 MBytes  52.5 Mbits/sec  0.052 ms  80112/84796 
(94%)  
[  5]   2.00-3.00   sec  6.26 MBytes  52.5 Mbits/sec  0.054 ms  80112/84797 
(94%)  
[  5]   3.00-4.00   sec  6.26 MBytes  52.5 Mbits/sec  0.053 ms  80128/84814 
(94%)  
[  5]   4.00-5.00   sec  6.26 MBytes  52.5 Mbits/sec  0.049 ms  80112/84798 
(94%)  
[  5]   5.00-6.00   sec  6.26 MBytes  52.5 Mbits/sec  0.052 ms  80096/84783 
(94%)  
[  5]   6.00-7.00   sec  6.26 MBytes  52.5 Mbits/sec  0.047 ms  80096/84784 
(94%)  
[  5]   7.00-8.00   sec  6.26 MBytes  52.5 Mbits/sec  0.060 ms  80128/84815 
(94%)  
iperf3: OUT OF ORDER - incoming packet = 731264 and received packet = 0 AND SP 
= 731279
iperf3: OUT OF ORDER - incoming packet = 731265 and received packet = 0 AND SP 
= 731279
iperf3: OUT OF ORDER - incoming packet = 731266 and received packet = 0 AND SP 
= 731279
iperf3: OUT OF ORDER - incoming packet = 731267 and received packet = 0 AND SP 
= 731279
iperf3: OUT OF ORDER - incoming packet = 731268 and received packet = 0 AND SP 
= 731279
iperf3: OUT OF ORDER - incoming packet = 731269 and received packet = 0 AND SP 
= 731279
iperf3: OUT OF ORDER - incoming packet = 731270 and received packet = 0 AND SP 
= 731279
iperf3: OUT OF ORDER - incoming packet = 731271 and received packet = 0 AND SP 
= 731279
iperf3: OUT OF ORDER - incoming packet = 731272 and received packet = 0 AND SP 
= 731279
[  5]   8.00-9.00   sec  4.17 MBytes  35.0 Mbits/sec  0.149 ms  53104/56220 
(94%)  
[  5]   9.00-10.00  sec  0.00 Bytes  0.00 bits/sec  0.149 ms  0/0 (0%)  
[  5]  10.00-11.00  sec  0.00 Bytes  0.00 bits/sec  0.149 ms  0/0 (0%)  
[  5]  11.00-12.00  sec  0.00 Bytes  0.00 bits/sec  0.149 ms  0/0 (0%)  
[  5]  12.00-13.00  sec  0.00 Bytes  0.00 bits/sec  0.149 ms  0/0 (0%)  
[  5]  13.00-14.00  sec  0.00 Bytes  0.00 bits/sec  0.149 ms  0/0 (0%)  
^C
- - - - - - - - - - - - - - - - - - - - - - - - -
[ ID] Interval   Transfer Bandwidth   JitterLost/Total 
Datagrams
[  5]   0.00-17.04  sec  0.00 Bytes  0.00 bits/sec  0.149 ms  690950/731279 
(94%)  
[SUM]  0.0-17.0 sec  9 datagrams received out-of-order
iperf3: interrupt - the server has terminated
# ping -c 10 172.27.64.1
PING 172.27.64.1 (172.27.64.1): 56 data bytes

--- 172.27.64.1 ping statistics ---
10 packets transmitted, 0 packets received, 100% packet loss


Given the out-of-order datagrams, I'm wondering if it's possible
for the DMA engine to overwrite a not-yet-read descriptor?

The EOC flag should stop the DMA engine though...

Maybe some kind of race...

I don't think I've been able to trigger the wedge when 256 descriptors
are used.



Re: [PATCH v3 3/4] net: nb8800: Move HW init to ndo_open()

2017-11-15 Thread Måns Rullgård
Marc Gonzalez  writes:

> On 14/11/2017 17:55, Måns Rullgård wrote:
>
>> Marc Gonzalez wrote:
>> 
>>> I will run iperf3 tests with RX_DESC_COUNT lowered to 2.
>>> Would that produce conclusive results?
>>> Do you have other suggestions?
>> 
>> Leave RX_DESC_COUNT alone but add a delay in the nb8800_poll() loop.
>> That should ensure that queue is drained slowly enough for the buffers
>> to run out.
>
> Using the following patch:
>
> diff --git a/drivers/net/ethernet/aurora/nb8800.c 
> b/drivers/net/ethernet/aurora/nb8800.c
> index 31c3f0f10fbb..646300bb53b6 100644
> --- a/drivers/net/ethernet/aurora/nb8800.c
> +++ b/drivers/net/ethernet/aurora/nb8800.c
> @@ -317,6 +317,7 @@ static int nb8800_poll(struct napi_struct *napi, int 
> budget)
>
> len = RX_BYTES_TRANSFERRED(rxd->report);
>
> +   udelay(200);
> if (IS_RX_ERROR(rxd->report))
> nb8800_rx_error(dev, rxd->report);
> else
> @@ -1416,9 +1417,9 @@ static int nb8800_probe(struct platform_device *pdev)
> netdev_info(dev, "MAC address %pM\n", dev->dev_addr);
>
> /* Auto-negotiate by default */
> -   priv->pause_aneg = true;
> -   priv->pause_rx = true;
> -   priv->pause_tx = true;
> +   priv->pause_aneg = false;
> +   priv->pause_rx = false;
> +   priv->pause_tx = false;
>
> priv->ops = match->data;
> priv->ops->power_down(dev);
> diff --git a/drivers/net/ethernet/aurora/nb8800.h 
> b/drivers/net/ethernet/aurora/nb8800.h
> index 23fefca54804..9b59ea776e4a 100644
> --- a/drivers/net/ethernet/aurora/nb8800.h
> +++ b/drivers/net/ethernet/aurora/nb8800.h
> @@ -7,7 +7,7 @@
>  #include 
>  #include 
>
> -#define RX_DESC_COUNT  256
> +#define RX_DESC_COUNT  16
>  #define TX_DESC_COUNT  256
>
>  #define NB8800_DESC_LOW4
>
> I saw both tango4 and tango5 wedged... :-(

Well, that's not good.  I'll see if I can replicate it later this week.

-- 
Måns Rullgård


Re: [PATCH v3 3/4] net: nb8800: Move HW init to ndo_open()

2017-11-15 Thread Marc Gonzalez
On 14/11/2017 17:55, Måns Rullgård wrote:

> Marc Gonzalez wrote:
> 
>> I will run iperf3 tests with RX_DESC_COUNT lowered to 2.
>> Would that produce conclusive results?
>> Do you have other suggestions?
> 
> Leave RX_DESC_COUNT alone but add a delay in the nb8800_poll() loop.
> That should ensure that queue is drained slowly enough for the buffers
> to run out.

Using the following patch:

diff --git a/drivers/net/ethernet/aurora/nb8800.c 
b/drivers/net/ethernet/aurora/nb8800.c
index 31c3f0f10fbb..646300bb53b6 100644
--- a/drivers/net/ethernet/aurora/nb8800.c
+++ b/drivers/net/ethernet/aurora/nb8800.c
@@ -317,6 +317,7 @@ static int nb8800_poll(struct napi_struct *napi, int budget)
 
len = RX_BYTES_TRANSFERRED(rxd->report);
 
+   udelay(200);
if (IS_RX_ERROR(rxd->report))
nb8800_rx_error(dev, rxd->report);
else
@@ -1416,9 +1417,9 @@ static int nb8800_probe(struct platform_device *pdev)
netdev_info(dev, "MAC address %pM\n", dev->dev_addr);
 
/* Auto-negotiate by default */
-   priv->pause_aneg = true;
-   priv->pause_rx = true;
-   priv->pause_tx = true;
+   priv->pause_aneg = false;
+   priv->pause_rx = false;
+   priv->pause_tx = false;
 
priv->ops = match->data;
priv->ops->power_down(dev);
diff --git a/drivers/net/ethernet/aurora/nb8800.h 
b/drivers/net/ethernet/aurora/nb8800.h
index 23fefca54804..9b59ea776e4a 100644
--- a/drivers/net/ethernet/aurora/nb8800.h
+++ b/drivers/net/ethernet/aurora/nb8800.h
@@ -7,7 +7,7 @@
 #include 
 #include 
 
-#define RX_DESC_COUNT  256
+#define RX_DESC_COUNT  16
 #define TX_DESC_COUNT  256
 
 #define NB8800_DESC_LOW4


I saw both tango4 and tango5 wedged... :-(

tango5:

[  5] local 172.27.64.23 port 5201 connected to 172.27.64.1 port 57415
[ ID] Interval   Transfer Bandwidth   JitterLost/Total 
Datagrams
[  5]   0.00-1.00   sec  6.33 MBytes  53.1 Mbits/sec  0.030 ms  73897/78442 
(94%)  
[  5]   1.00-2.00   sec  6.59 MBytes  55.3 Mbits/sec  0.040 ms  76944/81675 
(94%)  
[  5]   2.00-3.00   sec  6.59 MBytes  55.3 Mbits/sec  0.036 ms  76944/81675 
(94%)  
[  5]   3.00-4.00   sec  6.59 MBytes  55.3 Mbits/sec  0.038 ms  76976/81708 
(94%)  
[  5]   4.00-5.00   sec  6.59 MBytes  55.3 Mbits/sec  0.038 ms  76976/81708 
(94%)  
[  5]   5.00-6.00   sec  6.59 MBytes  55.3 Mbits/sec  0.039 ms  76944/81675 
(94%)  
[  5]   6.00-7.00   sec  6.59 MBytes  55.3 Mbits/sec  0.042 ms  76941/81674 
(94%)  
[  5]   7.00-8.00   sec  6.59 MBytes  55.3 Mbits/sec  0.048 ms  76976/81707 
(94%)  
[  5]   8.00-9.00   sec  6.59 MBytes  55.3 Mbits/sec  0.041 ms  76928/81660 
(94%)  
[  5]   9.00-10.00  sec  6.59 MBytes  55.3 Mbits/sec  0.039 ms  76960/81692 
(94%)  
[  5]  10.00-10.04  sec   279 KBytes  55.1 Mbits/sec  0.094 ms  3088/3284 (94%) 
 
- - - - - - - - - - - - - - - - - - - - - - - - -
[ ID] Interval   Transfer Bandwidth   JitterLost/Total 
Datagrams
[  5]   0.00-10.04  sec  0.00 Bytes  0.00 bits/sec  0.094 ms  769574/816900 
(94%)  
^Ciperf3: interrupt - the server has terminated
# ping -c 10 172.27.64.1
PING 172.27.64.1 (172.27.64.1): 56 data bytes

--- 172.27.64.1 ping statistics ---
10 packets transmitted, 0 packets received, 100% packet loss


tango4:

[  5] local 172.27.64.23 port 5201 connected to 172.27.64.1 port 52983
[ ID] Interval   Transfer Bandwidth   JitterLost/Total 
Datagrams
[  5]   0.00-1.00   sec  6.24 MBytes  52.3 Mbits/sec  0.035 ms  74019/78498 
(94%)  
[  5]   1.00-2.00   sec  6.51 MBytes  54.6 Mbits/sec  0.046 ms  77024/81702 
(94%)  
[  5]   2.00-3.00   sec  6.51 MBytes  54.7 Mbits/sec  0.050 ms  77024/81703 
(94%)  
[  5]   3.00-4.00   sec  6.51 MBytes  54.7 Mbits/sec  0.050 ms  77024/81703 
(94%)  
[  5]   4.00-5.00   sec  6.52 MBytes  54.7 Mbits/sec  0.052 ms  77024/81705 
(94%)  
[  5]   5.00-6.00   sec  6.52 MBytes  54.7 Mbits/sec  0.037 ms  76960/81640 
(94%)  
[  5]   6.00-7.00   sec  6.52 MBytes  54.7 Mbits/sec  0.043 ms  77008/81689 
(94%)  
[  5]   7.00-8.00   sec  6.52 MBytes  54.7 Mbits/sec  0.050 ms  77024/81704 
(94%)  
[  5]   8.00-9.00   sec  6.52 MBytes  54.7 Mbits/sec  0.045 ms  77024/81705 
(94%)  
[  5]   9.00-10.00  sec  6.52 MBytes  54.7 Mbits/sec  0.043 ms  77008/81688 
(94%)  
[  5]  10.00-10.04  sec   275 KBytes  54.5 Mbits/sec  0.103 ms  3040/3233 (94%) 
 
- - - - - - - - - - - - - - - - - - - - - - - - -
[ ID] Interval   Transfer Bandwidth   JitterLost/Total 
Datagrams
[  5]   0.00-10.04  sec  0.00 Bytes  0.00 bits/sec  0.103 ms  770179/816970 
(94%)  
^Ciperf3: interrupt - the server has terminated
# ping -c 10 172.27.64.1
PING 172.27.64.1 (172.27.64.1): 56 data bytes

--- 172.27.64.1 ping statistics ---
10 packets transmitted, 0 packets received, 100% packet loss


More tests needed...



Re: [PATCH v3 3/4] net: nb8800: Move HW init to ndo_open()

2017-11-14 Thread Marc Gonzalez
On 14/11/2017 17:55, Måns Rullgård wrote:

> Marc Gonzalez wrote:
> 
>> On 14/11/2017 14:54, Måns Rullgård wrote:
>>
>>> The hack originated from your company.
>>
>> So why are you so insistent that we keep using it?
> 
> Because it's the only way to support some chip variants.  Ones you'd
> apparently rather forget, but which nonetheless exist.

Which chip variants do you have in mind?
All tango3 board supports the reset method.

BTW, could you test my patch series on your board?
(I can't since the board is not supported upstream.)

>>> Also, I have repeated asked you what happens if the tango5 runs out of
>>> DMA buffers under normal operation.  Does that also cause it to lock up?
>>> If so, you have a much bigger problem on your hands.
>>
>> I will run iperf3 tests with RX_DESC_COUNT lowered to 2.
>> Would that produce conclusive results?
>> Do you have other suggestions?
> 
> Leave RX_DESC_COUNT alone but add a delay in the nb8800_poll() loop.
> That should ensure that queue is drained slowly enough for the buffers
> to run out.

OK. I will test this ASAP on tango4 and tango5.

I'll try finding a tango3 board, to check the nb8800_mdio_cmd()
quirk and the flow_control quirk. Again, the HW dev said they
are not needed, so if he's wrong, his credibility his shot.



Re: [PATCH v3 3/4] net: nb8800: Move HW init to ndo_open()

2017-11-14 Thread Måns Rullgård
Marc Gonzalez  writes:

> On 14/11/2017 14:54, Måns Rullgård wrote:
>
>> Marc Gonzalez writes:
>> 
>>> On 14/11/2017 13:40, Måns Rullgård wrote:
>>>
 Marc Gonzalez wrote:

> Power entire ethernet block down in ndo_stop().
> Power it back up in ndo_open() and perform HW init.
> Delete nb8800_dma_stop.

 Leave it alone, please.  Not all chips might have a separate power
 domain for this.  Also, it works just fine on the older chips.
>>>
>>> There is no need for separate power domains. The ethernet block is
>>> clock-gated when it is held in reset.
>> 
>> So you're not powering it down then.  Please be accurate.
>
> Smirk. That looks like trolling.
>
>>> The reset register is implemented on all tango3, tango4, tango5 chips.
>> 
>> It's still not a core feature.
>
> Correct. But it covers 100% of all chips using this driver.
> There is no point in trying to implement support for chips that
> have never existed, do not exist, and never will.

You can't know that.

>>> nb8800_dma_stop() is a hack.
>> 
>> The hack originated from your company.
>
> So why are you so insistent that we keep using it?

Because it's the only way to support some chip variants.  Ones you'd
apparently rather forget, but which nonetheless exist.

>> Also, I have repeated asked you what happens if the tango5 runs out of
>> DMA buffers under normal operation.  Does that also cause it to lock up?
>> If so, you have a much bigger problem on your hands.
>
> I will run iperf3 tests with RX_DESC_COUNT lowered to 2.
> Would that produce conclusive results?
> Do you have other suggestions?

Leave RX_DESC_COUNT alone but add a delay in the nb8800_poll() loop.
That should ensure that queue is drained slowly enough for the buffers
to run out.

-- 
Måns Rullgård


Re: [PATCH v3 3/4] net: nb8800: Move HW init to ndo_open()

2017-11-14 Thread Marc Gonzalez
On 14/11/2017 14:54, Måns Rullgård wrote:

> Marc Gonzalez writes:
> 
>> On 14/11/2017 13:40, Måns Rullgård wrote:
>>
>>> Marc Gonzalez wrote:
>>>
 Power entire ethernet block down in ndo_stop().
 Power it back up in ndo_open() and perform HW init.
 Delete nb8800_dma_stop.
>>>
>>> Leave it alone, please.  Not all chips might have a separate power
>>> domain for this.  Also, it works just fine on the older chips.
>>
>> There is no need for separate power domains. The ethernet block is
>> clock-gated when it is held in reset.
> 
> So you're not powering it down then.  Please be accurate.

Smirk. That looks like trolling.


>> The reset register is implemented on all tango3, tango4, tango5 chips.
> 
> It's still not a core feature.

Correct. But it covers 100% of all chips using this driver.
There is no point in trying to implement support for chips that
have never existed, do not exist, and never will.


>> nb8800_dma_stop() is a hack.
> 
> The hack originated from your company.

So why are you so insistent that we keep using it?


>> The HW dev has stated that it is not supported.  One cannot conclude
>> that it "works fine" just because you've never triggered the error
>> condition. (On tango5, the error condition triggers systematically.)
> 
> That sounds like a problem for tango5.

tango5 does have its share of issues.


> Also, I have repeated asked you what happens if the tango5 runs out of
> DMA buffers under normal operation.  Does that also cause it to lock up?
> If so, you have a much bigger problem on your hands.

I will run iperf3 tests with RX_DESC_COUNT lowered to 2.
Would that produce conclusive results?
Do you have other suggestions?


>> We have several customer bug reports on tango3 and tango4 chips complaining
>> about "broken" ethernet after a link down / link up cycle. They are using a
>> different driver, but it implements the same hack in enet_stop_rx().
>> There is a high probability that the DMA hack is responsible, and wedged the
>> RX DMA state machine.
> 
> But you have no idea what's really the problem?

I have an idea that enet_stop_rx() wedged the RX DMA state machine.



Re: [PATCH v3 3/4] net: nb8800: Move HW init to ndo_open()

2017-11-14 Thread Måns Rullgård
Marc Gonzalez  writes:

> On 14/11/2017 13:40, Måns Rullgård wrote:
>
>> Marc Gonzalez wrote:
>> 
>>> Power entire ethernet block down in ndo_stop().
>>> Power it back up in ndo_open() and perform HW init.
>>> Delete nb8800_dma_stop.
>> 
>> Leave it alone, please.  Not all chips might have a separate power
>> domain for this.  Also, it works just fine on the older chips.
>
> There is no need for separate power domains. The ethernet block is
> clock-gated when it is held in reset.

So you're not powering it down then.  Please be accurate.

> The reset register is implemented on all tango3, tango4, tango5 chips.

It's still not a core feature.

> nb8800_dma_stop() is a hack.

The hack originated from your company.

> The HW dev has stated that it is not supported.  One cannot conclude
> that it "works fine" just because you've never triggered the error
> condition. (On tango5, the error condition triggers systematically.)

That sounds like a problem for tango5.

Also, I have repeated asked you what happens if the tango5 runs out of
DMA buffers under normal operation.  Does that also cause it to lock up?
If so, you have a much bigger problem on your hands.

> We have several customer bug reports on tango3 and tango4 chips complaining
> about "broken" ethernet after a link down / link up cycle. They are using a
> different driver, but it implements the same hack in enet_stop_rx().
> There is a high probability that the DMA hack is responsible, and wedged the
> RX DMA state machine.

But you have no idea what's really the problem?

-- 
Måns Rullgård


Re: [PATCH v3 3/4] net: nb8800: Move HW init to ndo_open()

2017-11-14 Thread Marc Gonzalez
On 14/11/2017 13:40, Måns Rullgård wrote:

> Marc Gonzalez wrote:
> 
>> Power entire ethernet block down in ndo_stop().
>> Power it back up in ndo_open() and perform HW init.
>> Delete nb8800_dma_stop.
> 
> Leave it alone, please.  Not all chips might have a separate power
> domain for this.  Also, it works just fine on the older chips.

There is no need for separate power domains. The ethernet block is
clock-gated when it is held in reset. The reset register is implemented
on all tango3, tango4, tango5 chips.

nb8800_dma_stop() is a hack. The HW dev has stated that it is not supported.
One cannot conclude that it "works fine" just because you've never triggered
the error condition. (On tango5, the error condition triggers systematically.)

We have several customer bug reports on tango3 and tango4 chips complaining
about "broken" ethernet after a link down / link up cycle. They are using a
different driver, but it implements the same hack in enet_stop_rx().
There is a high probability that the DMA hack is responsible, and wedged the
RX DMA state machine.

Since older chips do support the reset register, this patch implements
the same method for all tango chips.



Re: [PATCH v3 3/4] net: nb8800: Move HW init to ndo_open()

2017-11-14 Thread Måns Rullgård
Marc Gonzalez  writes:

> Power entire ethernet block down in ndo_stop().
> Power it back up in ndo_open() and perform HW init.
> Delete nb8800_dma_stop.

Leave it alone, please.  Not all chips might have a separate power
domain for this.  Also, it works just fine on the older chips.

> Signed-off-by: Marc Gonzalez 
> ---
>  drivers/net/ethernet/aurora/nb8800.c | 146 
> +--
>  drivers/net/ethernet/aurora/nb8800.h |   4 +-
>  2 files changed, 40 insertions(+), 110 deletions(-)
>
> diff --git a/drivers/net/ethernet/aurora/nb8800.c 
> b/drivers/net/ethernet/aurora/nb8800.c
> index 09b8001e1ecc..b71d8fb80610 100644
> --- a/drivers/net/ethernet/aurora/nb8800.c
> +++ b/drivers/net/ethernet/aurora/nb8800.c
> @@ -40,7 +40,7 @@
>  #include "nb8800.h"
>
>  static void nb8800_tx_done(struct net_device *dev);
> -static int nb8800_dma_stop(struct net_device *dev);
> +static void nb8800_hw_init(struct net_device *dev);
>
>  static inline u8 nb8800_readb(struct nb8800_priv *priv, int reg)
>  {
> @@ -862,61 +862,6 @@ static int nb8800_dma_init(struct net_device *dev)
>   return -ENOMEM;
>  }
>
> -static int nb8800_dma_stop(struct net_device *dev)
> -{
> - struct nb8800_priv *priv = netdev_priv(dev);
> - struct nb8800_tx_buf *txb = &priv->tx_bufs[0];
> - struct nb8800_tx_desc *txd = &priv->tx_descs[0];
> - int retry = 5;
> - u32 txcr;
> - u32 rxcr;
> - int err;
> - unsigned int i;
> -
> - /* wait for tx to finish */
> - err = readl_poll_timeout_atomic(priv->base + NB8800_TXC_CR, txcr,
> - !(txcr & TCR_EN) &&
> - priv->tx_done == priv->tx_next,
> - 1000, 100);
> - if (err)
> - return err;
> -
> - /* The rx DMA only stops if it reaches the end of chain.
> -  * To make this happen, we set the EOC flag on all rx
> -  * descriptors, put the device in loopback mode, and send
> -  * a few dummy frames.  The interrupt handler will ignore
> -  * these since NAPI is disabled and no real frames are in
> -  * the tx queue.
> -  */
> -
> - for (i = 0; i < RX_DESC_COUNT; i++)
> - priv->rx_descs[i].desc.config |= DESC_EOC;
> -
> - txd->desc[0].s_addr =
> - txb->dma_desc + offsetof(struct nb8800_tx_desc, buf);
> - txd->desc[0].config = DESC_BTS(2) | DESC_DS | DESC_EOF | DESC_EOC | 8;
> - memset(txd->buf, 0, sizeof(txd->buf));
> -
> - nb8800_mac_af(dev, false);
> - nb8800_setb(priv, NB8800_MAC_MODE, LOOPBACK_EN);
> -
> - do {
> - nb8800_writel(priv, NB8800_TX_DESC_ADDR, txb->dma_desc);
> - wmb();
> - nb8800_writel(priv, NB8800_TXC_CR, txcr | TCR_EN);
> -
> - err = readl_poll_timeout_atomic(priv->base + NB8800_RXC_CR,
> - rxcr, !(rxcr & RCR_EN),
> - 1000, 10);
> - } while (err && --retry);
> -
> - nb8800_mac_af(dev, true);
> - nb8800_clearb(priv, NB8800_MAC_MODE, LOOPBACK_EN);
> - nb8800_dma_reset(dev);
> -
> - return retry ? 0 : -ETIMEDOUT;
> -}
> -
>  static void nb8800_pause_adv(struct net_device *dev)
>  {
>   struct nb8800_priv *priv = netdev_priv(dev);
> @@ -941,6 +886,11 @@ static int nb8800_open(struct net_device *dev)
>   struct phy_device *phydev;
>   int err;
>
> + priv->ops->power_up(dev);
> + nb8800_hw_init(dev);
> + priv->ops->init(dev);
> + nb8800_update_mac_addr(dev);
> +
>   /* clear any pending interrupts */
>   nb8800_writel(priv, NB8800_RXC_SR, 0xf);
>   nb8800_writel(priv, NB8800_TXC_SR, 0xf);
> @@ -993,12 +943,11 @@ static int nb8800_stop(struct net_device *dev)
>   netif_stop_queue(dev);
>   napi_disable(&priv->napi);
>
> - nb8800_dma_stop(dev);
> - nb8800_mac_rx(dev, false);
> - nb8800_mac_tx(dev, false);
> -
>   phy_disconnect(phydev);
>
> + priv->ops->power_down(dev);
> + priv->speed = 0;
> +
>   free_irq(dev->irq, dev);
>
>   nb8800_dma_free(dev);
> @@ -1150,7 +1099,7 @@ static const struct ethtool_ops nb8800_ethtool_ops = {
>   .set_link_ksettings = phy_ethtool_set_link_ksettings,
>  };
>
> -static int nb8800_hw_init(struct net_device *dev)
> +static void nb8800_hw_init(struct net_device *dev)
>  {
>   struct nb8800_priv *priv = netdev_priv(dev);
>   u32 val;
> @@ -1230,20 +1179,14 @@ static int nb8800_hw_init(struct net_device *dev)
>   nb8800_writeb(priv, NB8800_PQ1, val >> 8);
>   nb8800_writeb(priv, NB8800_PQ2, val & 0xff);
>
> - /* Auto-negotiate by default */
> - priv->pause_aneg = true;
> - priv->pause_rx = true;
> - priv->pause_tx = true;
> -
>   nb8800_mc_init(dev, 0);
> -
> - return 0;
>  }
>
>  static int nb8800_tangox_init(struct net_device *dev)
>  {
>   struct nb8800_priv *priv = netdev_priv(dev);
>   u32 pad_mode = PAD_MODE_MII;

[PATCH v3 3/4] net: nb8800: Move HW init to ndo_open()

2017-11-14 Thread Marc Gonzalez
Power entire ethernet block down in ndo_stop().
Power it back up in ndo_open() and perform HW init.
Delete nb8800_dma_stop.

Signed-off-by: Marc Gonzalez 
---
 drivers/net/ethernet/aurora/nb8800.c | 146 +--
 drivers/net/ethernet/aurora/nb8800.h |   4 +-
 2 files changed, 40 insertions(+), 110 deletions(-)

diff --git a/drivers/net/ethernet/aurora/nb8800.c 
b/drivers/net/ethernet/aurora/nb8800.c
index 09b8001e1ecc..b71d8fb80610 100644
--- a/drivers/net/ethernet/aurora/nb8800.c
+++ b/drivers/net/ethernet/aurora/nb8800.c
@@ -40,7 +40,7 @@
 #include "nb8800.h"
 
 static void nb8800_tx_done(struct net_device *dev);
-static int nb8800_dma_stop(struct net_device *dev);
+static void nb8800_hw_init(struct net_device *dev);
 
 static inline u8 nb8800_readb(struct nb8800_priv *priv, int reg)
 {
@@ -862,61 +862,6 @@ static int nb8800_dma_init(struct net_device *dev)
return -ENOMEM;
 }
 
-static int nb8800_dma_stop(struct net_device *dev)
-{
-   struct nb8800_priv *priv = netdev_priv(dev);
-   struct nb8800_tx_buf *txb = &priv->tx_bufs[0];
-   struct nb8800_tx_desc *txd = &priv->tx_descs[0];
-   int retry = 5;
-   u32 txcr;
-   u32 rxcr;
-   int err;
-   unsigned int i;
-
-   /* wait for tx to finish */
-   err = readl_poll_timeout_atomic(priv->base + NB8800_TXC_CR, txcr,
-   !(txcr & TCR_EN) &&
-   priv->tx_done == priv->tx_next,
-   1000, 100);
-   if (err)
-   return err;
-
-   /* The rx DMA only stops if it reaches the end of chain.
-* To make this happen, we set the EOC flag on all rx
-* descriptors, put the device in loopback mode, and send
-* a few dummy frames.  The interrupt handler will ignore
-* these since NAPI is disabled and no real frames are in
-* the tx queue.
-*/
-
-   for (i = 0; i < RX_DESC_COUNT; i++)
-   priv->rx_descs[i].desc.config |= DESC_EOC;
-
-   txd->desc[0].s_addr =
-   txb->dma_desc + offsetof(struct nb8800_tx_desc, buf);
-   txd->desc[0].config = DESC_BTS(2) | DESC_DS | DESC_EOF | DESC_EOC | 8;
-   memset(txd->buf, 0, sizeof(txd->buf));
-
-   nb8800_mac_af(dev, false);
-   nb8800_setb(priv, NB8800_MAC_MODE, LOOPBACK_EN);
-
-   do {
-   nb8800_writel(priv, NB8800_TX_DESC_ADDR, txb->dma_desc);
-   wmb();
-   nb8800_writel(priv, NB8800_TXC_CR, txcr | TCR_EN);
-
-   err = readl_poll_timeout_atomic(priv->base + NB8800_RXC_CR,
-   rxcr, !(rxcr & RCR_EN),
-   1000, 10);
-   } while (err && --retry);
-
-   nb8800_mac_af(dev, true);
-   nb8800_clearb(priv, NB8800_MAC_MODE, LOOPBACK_EN);
-   nb8800_dma_reset(dev);
-
-   return retry ? 0 : -ETIMEDOUT;
-}
-
 static void nb8800_pause_adv(struct net_device *dev)
 {
struct nb8800_priv *priv = netdev_priv(dev);
@@ -941,6 +886,11 @@ static int nb8800_open(struct net_device *dev)
struct phy_device *phydev;
int err;
 
+   priv->ops->power_up(dev);
+   nb8800_hw_init(dev);
+   priv->ops->init(dev);
+   nb8800_update_mac_addr(dev);
+
/* clear any pending interrupts */
nb8800_writel(priv, NB8800_RXC_SR, 0xf);
nb8800_writel(priv, NB8800_TXC_SR, 0xf);
@@ -993,12 +943,11 @@ static int nb8800_stop(struct net_device *dev)
netif_stop_queue(dev);
napi_disable(&priv->napi);
 
-   nb8800_dma_stop(dev);
-   nb8800_mac_rx(dev, false);
-   nb8800_mac_tx(dev, false);
-
phy_disconnect(phydev);
 
+   priv->ops->power_down(dev);
+   priv->speed = 0;
+
free_irq(dev->irq, dev);
 
nb8800_dma_free(dev);
@@ -1150,7 +1099,7 @@ static const struct ethtool_ops nb8800_ethtool_ops = {
.set_link_ksettings = phy_ethtool_set_link_ksettings,
 };
 
-static int nb8800_hw_init(struct net_device *dev)
+static void nb8800_hw_init(struct net_device *dev)
 {
struct nb8800_priv *priv = netdev_priv(dev);
u32 val;
@@ -1230,20 +1179,14 @@ static int nb8800_hw_init(struct net_device *dev)
nb8800_writeb(priv, NB8800_PQ1, val >> 8);
nb8800_writeb(priv, NB8800_PQ2, val & 0xff);
 
-   /* Auto-negotiate by default */
-   priv->pause_aneg = true;
-   priv->pause_rx = true;
-   priv->pause_tx = true;
-
nb8800_mc_init(dev, 0);
-
-   return 0;
 }
 
 static int nb8800_tangox_init(struct net_device *dev)
 {
struct nb8800_priv *priv = netdev_priv(dev);
u32 pad_mode = PAD_MODE_MII;
+   int clk_div;
 
switch (priv->phy_mode) {
case PHY_INTERFACE_MODE_MII:
@@ -1266,29 +1209,26 @@ static int nb8800_tangox_init(struct net_device *dev)
 
nb8800_writeb(priv, NB8800_TANGOX_PAD_MODE, pad_mode);
 
+   clk_div = DIV_ROUN