All of lore.kernel.org
 help / color / mirror / Atom feed
* bug: net: dsa: mv88e6xxx: unable to tx or rx with Clearfog GT 8K (with git bisect)
@ 2020-07-11 13:50 Martin Rowe
  2020-07-11 16:23 ` Andrew Lunn
  0 siblings, 1 reply; 17+ messages in thread
From: Martin Rowe @ 2020-07-11 13:50 UTC (permalink / raw)
  To: netdev; +Cc: andrew, davem, vivien.didelot, linux

Hello,

I hope this is the right forum.

I have been troubleshooting an issue with my Clearfog GT 8Ks where I
am unable to tx or rx on the switch interface, which uses the
mv88e6xxx driver. Based on git bisect, I believe it is related to
commit 34b5e6a33c1a8e466c3a73fd437f66fb16cb83ea from around the
5.7-rc2 era.

Symptoms:
The interface used to work, then it stopped and I didn't immediately
notice because of life. Now the network never comes fully up. dmesg
indicates no issues bringing the device up. Links are brought up and
down with cable connects and disconnects. Negotiation seems to be
working. But the interface rx counter never increases. While the tx
counters do increase, tcpdumps on the other end of the cables never
see any traffic. Basically, it doesn't look like any traffic is going
out or in.

What I have done:
Obvious one first: yes, I bring the parent eth2 before expecting any
of the lan[1-4] interfaces to work.
I know that the interface worked at some point around February when I
was doing some testing.
I have the same issue on all three of my Clearfog GT 8Ks.
Tried different cables.
I searched a lot of web pages.
I can change link modes and duplex using ethtool on a directly
connected device, and I see in dmesg that the Clearfogs detect the
change and reconfigure (example in dmesg output at the bottom).
I have directly connected the switched ports to other devices and
tcpdumped, as well as tried with a commercial switch in between; no
packets are ever received on either side.
I have tried static IP assignments and DHCP. While the interface can
be configured, no packets ever appear to leave the device. When static
IP is assigned, pinging the device doesn't result in anything being
received.
I have tried using the lan[1-4] ports in single port and bridged mode.
I have tried manually configuring the interfaces (i.e. ip commands)
and using systemd.
No firewall rules are active, everything is ACCEPT (iptables,
ebtables, nftables, etc.)
I have tried with and without a MAC address being set in u-boot.
I have tried different u-boot versions, although it wasn't otherwise
changed since the known good working state.
Then I git bisected the mainline kernel...

Commit 34b5e6a33c1a8e466c3a73fd437f66fb16cb83ea is the first "bad"
commit where the interface stops working. To double check I tried with
the latest I had from Linus' branch (HEAD at
bfe91da29bfad9941d5d703d45e29f0812a20724, I think it was around
5.8-rc2), reverted the one problem commit, and the interface worked
again.

I'm using the ARM port of Arch Linux, but I tested with the mainline
kernel that I compiled myself. I did borrow the Arch linux-aarch64
config, though.

I'm more than happy to test any patches, but my C is rudimentary at
best and there's nothing that jumps out at me as being obviously
"wrong" in the problem commit, so I am way out of my depth from here.
Please let me know what information you need from me to help work this
out.

Martin



# dmesg |grep mv88
[    8.635839] mv88e6085 f412a200.mdio-mii:04: switch 0x3400 detected:
Marvell 88E6141, revision 0
[    9.372614] mv88e6085 f412a200.mdio-mii:04: nonfatal error -95
setting MTU on port 1
[    9.382190] mv88e6085 f412a200.mdio-mii:04 lan2 (uninitialized):
PHY [!cp1!config-space@f4000000!mdio@12a200!switch0@4!mdio:11] driver
[Marvell 88E6390] (irq=72)
[    9.401218] mv88e6085 f412a200.mdio-mii:04: nonfatal error -95
setting MTU on port 2
[    9.410884] mv88e6085 f412a200.mdio-mii:04 lan1 (uninitialized):
PHY [!cp1!config-space@f4000000!mdio@12a200!switch0@4!mdio:12] driver
[Marvell 88E6390] (irq=73)
[    9.429732] mv88e6085 f412a200.mdio-mii:04: nonfatal error -95
setting MTU on port 3
[    9.438606] mv88e6085 f412a200.mdio-mii:04 lan4 (uninitialized):
PHY [!cp1!config-space@f4000000!mdio@12a200!switch0@4!mdio:13] driver
[Marvell 88E6390] (irq=74)
[    9.460614] mv88e6085 f412a200.mdio-mii:04: nonfatal error -95
setting MTU on port 4
[    9.469695] mv88e6085 f412a200.mdio-mii:04 lan3 (uninitialized):
PHY [!cp1!config-space@f4000000!mdio@12a200!switch0@4!mdio:14] driver
[Marvell 88E6390] (irq=75)
[    9.497221] mv88e6085 f412a200.mdio-mii:04: configuring for
inband/2500base-x link mode
[    9.719879] mv88e6085 f412a200.mdio-mii:04 lan2: configuring for
phy/ link mode
[    9.789470] mv88e6085 f412a200.mdio-mii:04 lan1: configuring for
phy/ link mode
[    9.803635] mv88e6085 f412a200.mdio-mii:04 lan4: configuring for
phy/ link mode
[    9.822532] mv88e6085 f412a200.mdio-mii:04 lan3: configuring for
phy/ link mode
[   12.827209] mv88e6085 f412a200.mdio-mii:04 lan4: Link is Up -
1Gbps/Full - flow control rx/tx
[   12.848385] mv88e6085 f412a200.mdio-mii:04 lan2: Link is Up -
1Gbps/Full - flow control rx/tx
[   12.933265] mv88e6085 f412a200.mdio-mii:04 lan3: Link is Up -
1Gbps/Full - flow control rx/tx
[ 1582.803879] mv88e6085 f412a200.mdio-mii:04 lan4: Link is Down
[ 1585.109257] mv88e6085 f412a200.mdio-mii:04 lan4: Link is Up -
10Mbps/Half - flow control off
[ 1600.842612] mv88e6085 f412a200.mdio-mii:04 lan4: Link is Down
[ 1603.807772] mv88e6085 f412a200.mdio-mii:04 lan4: Link is Up -
1Gbps/Full - flow control rx/tx

# ip a
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN
group default qlen 1000
    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
    inet 127.0.0.1/8 scope host lo
       valid_lft forever preferred_lft forever
    inet6 ::1/128 scope host
       valid_lft forever preferred_lft forever
2: eth0: <BROADCAST,MULTICAST> mtu 1500 qdisc noop state DOWN group
default qlen 2048
    link/ether d0:63:b4:01:00:01 brd ff:ff:ff:ff:ff:ff
3: eth1: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc mq state UP
group default qlen 2048
    link/ether d0:63:b4:01:00:00 brd ff:ff:ff:ff:ff:ff
    inet 10.0.0.20/24 brd 10.0.0.255 scope global dynamic eth1
       valid_lft 1892sec preferred_lft 1892sec
    inet6 fe80::d263:b4ff:fe01:0/64 scope link
       valid_lft forever preferred_lft forever
4: eth2: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1508 qdisc mq state UP
group default qlen 2048
    link/ether d0:63:b4:01:00:02 brd ff:ff:ff:ff:ff:ff
    inet 169.254.181.234/16 brd 169.254.255.255 scope link eth2
       valid_lft forever preferred_lft forever
    inet6 fe80::d263:b4ff:fe01:2/64 scope link
       valid_lft forever preferred_lft forever
5: lan2@eth2: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue
state UP group default qlen 1000
    link/ether d0:63:b4:01:00:02 brd ff:ff:ff:ff:ff:ff
    inet6 fe80::d263:b4ff:fe01:2/64 scope link
       valid_lft forever preferred_lft forever
6: lan1@eth2: <NO-CARRIER,BROADCAST,MULTICAST,UP> mtu 1500 qdisc
noqueue state LOWERLAYERDOWN group default qlen 1000
    link/ether d0:63:b4:01:00:02 brd ff:ff:ff:ff:ff:ff
7: lan4@eth2: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue
state UP group default qlen 1000
    link/ether d0:63:b4:01:00:02 brd ff:ff:ff:ff:ff:ff
    inet6 fe80::d263:b4ff:fe01:2/64 scope link
       valid_lft forever preferred_lft forever
8: lan3@eth2: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue
state UP group default qlen 1000
    link/ether d0:63:b4:01:00:02 brd ff:ff:ff:ff:ff:ff
    inet6 fe80::d263:b4ff:fe01:2/64 scope link
       valid_lft forever preferred_lft forever

^ permalink raw reply	[flat|nested] 17+ messages in thread

* Re: bug: net: dsa: mv88e6xxx: unable to tx or rx with Clearfog GT 8K (with git bisect)
  2020-07-11 13:50 bug: net: dsa: mv88e6xxx: unable to tx or rx with Clearfog GT 8K (with git bisect) Martin Rowe
@ 2020-07-11 16:23 ` Andrew Lunn
  2020-07-11 19:22   ` Russell King - ARM Linux admin
  0 siblings, 1 reply; 17+ messages in thread
From: Andrew Lunn @ 2020-07-11 16:23 UTC (permalink / raw)
  To: Martin Rowe; +Cc: netdev, davem, vivien.didelot, linux

On Sat, Jul 11, 2020 at 01:50:21PM +0000, Martin Rowe wrote:
> Hello,
> 
> I hope this is the right forum.
> 
> I have been troubleshooting an issue with my Clearfog GT 8Ks where I
> am unable to tx or rx on the switch interface, which uses the
> mv88e6xxx driver. Based on git bisect, I believe it is related to
> commit 34b5e6a33c1a8e466c3a73fd437f66fb16cb83ea from around the
> 5.7-rc2 era.

Hi Martin

Thanks for the bug report.

> Symptoms:
> The interface used to work, then it stopped and I didn't immediately
> notice because of life. Now the network never comes fully up. dmesg
> indicates no issues bringing the device up. Links are brought up and
> down with cable connects and disconnects. Negotiation seems to be
> working. But the interface rx counter never increases. While the tx
> counters do increase, tcpdumps on the other end of the cables never
> see any traffic. Basically, it doesn't look like any traffic is going
> out or in.

So i'm guessing it is the connection between the CPU and the switch.
Could you confirm this? Create a bridge, add two ports of the switch
to the bridge, and then see if packets can pass between switch ports.

If it is the connection between the CPU and the switch, i would then
be thinking about the comphy and the firmware. We have seen issues
where the firmware is too old. That is not something i've debugged
myself, so i don't know where the version information is, or what
version is required.

	Andrew

^ permalink raw reply	[flat|nested] 17+ messages in thread

* Re: bug: net: dsa: mv88e6xxx: unable to tx or rx with Clearfog GT 8K (with git bisect)
  2020-07-11 16:23 ` Andrew Lunn
@ 2020-07-11 19:22   ` Russell King - ARM Linux admin
  2020-07-12 13:00     ` Martin Rowe
  0 siblings, 1 reply; 17+ messages in thread
From: Russell King - ARM Linux admin @ 2020-07-11 19:22 UTC (permalink / raw)
  To: Andrew Lunn; +Cc: Martin Rowe, netdev, davem, vivien.didelot

On Sat, Jul 11, 2020 at 06:23:49PM +0200, Andrew Lunn wrote:
> So i'm guessing it is the connection between the CPU and the switch.
> Could you confirm this? Create a bridge, add two ports of the switch
> to the bridge, and then see if packets can pass between switch ports.
> 
> If it is the connection between the CPU and the switch, i would then
> be thinking about the comphy and the firmware. We have seen issues
> where the firmware is too old. That is not something i've debugged
> myself, so i don't know where the version information is, or what
> version is required.

However, in the report, Martin said that reverting the problem commit
from April 14th on a kernel from July 6th caused everything to work
again.  That is quite conclusive that 34b5e6a33c1a is the cause of
the breakage.

The question is how - I don't get it.  None of the GT8k DSA ports are
fixed-links, not even the CPU port (which no longer even uses phylink.)
However, the MVPP2 is using a fixed-link on the port that faces the
DSA switch, which doesn't sound like a good idea to me to have
dis-similar configurations at either end.  So the addition of
"|| mode == MLO_AN_FIXED" shouldn't make any difference.

I think some debug printks would be needed to work out what's going on.

-- 
RMK's Patch system: https://www.armlinux.org.uk/developer/patches/
FTTP is here! 40Mbps down 10Mbps up. Decent connectivity at last!

^ permalink raw reply	[flat|nested] 17+ messages in thread

* Re: bug: net: dsa: mv88e6xxx: unable to tx or rx with Clearfog GT 8K (with git bisect)
  2020-07-11 19:22   ` Russell King - ARM Linux admin
@ 2020-07-12 13:00     ` Martin Rowe
  2020-07-12 13:25       ` Russell King - ARM Linux admin
  0 siblings, 1 reply; 17+ messages in thread
From: Martin Rowe @ 2020-07-12 13:00 UTC (permalink / raw)
  To: Russell King - ARM Linux admin; +Cc: Andrew Lunn, netdev, davem, vivien.didelot

On Sat, 11 Jul 2020 at 19:23, Russell King - ARM Linux admin
<linux@armlinux.org.uk> wrote:
> On Sat, Jul 11, 2020 at 06:23:49PM +0200, Andrew Lunn wrote:
> > So i'm guessing it is the connection between the CPU and the switch.
> > Could you confirm this? Create a bridge, add two ports of the switch
> > to the bridge, and then see if packets can pass between switch ports.
> >
> > If it is the connection between the CPU and the switch, i would then
> > be thinking about the comphy and the firmware. We have seen issues
> > where the firmware is too old. That is not something i've debugged
> > myself, so i don't know where the version information is, or what
> > version is required.
>
> However, in the report, Martin said that reverting the problem commit
> from April 14th on a kernel from July 6th caused everything to work
> again.  That is quite conclusive that 34b5e6a33c1a is the cause of
> the breakage.

I tried it anyway and couldn't get any traffic to flow between the
ports, but I could have configured it wrongly. I gave each port a
static IP, bridged them (with and without br0 having an IP assigned),
and tried pinging from one port to the other. I tried with the
assigned IPs in the same and different subnets, and made sure the
routes were updated between tests. Tx only, no responses, exactly like
pinging a remote host.

I'm now less confident about my git bisect, though, because it appears
my criteria for verifying if a commit was "good" was not sufficient. I
was just checking to see if the port could get assigned a DHCP address
and ping something else, but it appears that (at least on 5.8-rc4 with
the one revert) the interface "dies" after working for about 30-60
seconds. Basically the symptoms I described originally, just preceded
by 30-60 seconds of it working perfectly. I will re-run the bisect to
figure out what makes it go from "working perfectly" to "working
perfectly for less than a minute", which will take a few days.

^ permalink raw reply	[flat|nested] 17+ messages in thread

* Re: bug: net: dsa: mv88e6xxx: unable to tx or rx with Clearfog GT 8K (with git bisect)
  2020-07-12 13:00     ` Martin Rowe
@ 2020-07-12 13:25       ` Russell King - ARM Linux admin
  2020-07-17  5:56         ` Martin Rowe
  0 siblings, 1 reply; 17+ messages in thread
From: Russell King - ARM Linux admin @ 2020-07-12 13:25 UTC (permalink / raw)
  To: Martin Rowe; +Cc: Andrew Lunn, netdev, davem, vivien.didelot

On Sun, Jul 12, 2020 at 01:00:48PM +0000, Martin Rowe wrote:
> On Sat, 11 Jul 2020 at 19:23, Russell King - ARM Linux admin
> <linux@armlinux.org.uk> wrote:
> > On Sat, Jul 11, 2020 at 06:23:49PM +0200, Andrew Lunn wrote:
> > > So i'm guessing it is the connection between the CPU and the switch.
> > > Could you confirm this? Create a bridge, add two ports of the switch
> > > to the bridge, and then see if packets can pass between switch ports.
> > >
> > > If it is the connection between the CPU and the switch, i would then
> > > be thinking about the comphy and the firmware. We have seen issues
> > > where the firmware is too old. That is not something i've debugged
> > > myself, so i don't know where the version information is, or what
> > > version is required.
> >
> > However, in the report, Martin said that reverting the problem commit
> > from April 14th on a kernel from July 6th caused everything to work
> > again.  That is quite conclusive that 34b5e6a33c1a is the cause of
> > the breakage.
> 
> I tried it anyway and couldn't get any traffic to flow between the
> ports, but I could have configured it wrongly. I gave each port a
> static IP, bridged them (with and without br0 having an IP assigned),
> and tried pinging from one port to the other. I tried with the
> assigned IPs in the same and different subnets, and made sure the
> routes were updated between tests. Tx only, no responses, exactly like
> pinging a remote host.

Note that you shouldn't need to set an ip on the bridge ports
themselves.

If you do this:

# ip li set dev eth1 up
# brctl addbr br0
# for port in lan1 lan2 lan3 lan4; do ip li set dev $port up; \
	brctl addif br0 $port; done

Then you should be able to pass traffic between the LAN ports - the
packets should stay on the DSA switch and should not involve the CPU.

If you have machine A with address 192.168.2.1/24 on lan1 and machine B
with address 192.168.2.2/24 on lan2, then they should be able to ping
each other - the packet flow will be through the DSA switch without
involving the CPU.

If that doesn't work, then the next step is to directly connect machine
A to machine B and confirm that works.  If it works there, but does not
work when connected to the DSA switch, then it points to the DSA LAN
ports being incorrectly configured.

At that point, what may help is to get a dump of the registers
associated with each of the ports:

# ethtool -d lan<N>

and then we can see how the kernel is configuring them.

If it is a port issue, that should help pinpoint it - if it's a problem
with the CPU port configuration, then ethtool can't read those registers
(and the only way to get them is to apply some debugfs patch that was
refused from being merged into mainline.)

> I'm now less confident about my git bisect, though, because it appears
> my criteria for verifying if a commit was "good" was not sufficient. I
> was just checking to see if the port could get assigned a DHCP address
> and ping something else, but it appears that (at least on 5.8-rc4 with
> the one revert) the interface "dies" after working for about 30-60
> seconds. Basically the symptoms I described originally, just preceded
> by 30-60 seconds of it working perfectly. I will re-run the bisect to
> figure out what makes it go from "working perfectly" to "working
> perfectly for less than a minute", which will take a few days.

That seems really weird!

-- 
RMK's Patch system: https://www.armlinux.org.uk/developer/patches/
FTTP is here! 40Mbps down 10Mbps up. Decent connectivity at last!

^ permalink raw reply	[flat|nested] 17+ messages in thread

* Re: bug: net: dsa: mv88e6xxx: unable to tx or rx with Clearfog GT 8K (with git bisect)
  2020-07-12 13:25       ` Russell King - ARM Linux admin
@ 2020-07-17  5:56         ` Martin Rowe
  2020-07-17  9:21           ` Russell King - ARM Linux admin
  0 siblings, 1 reply; 17+ messages in thread
From: Martin Rowe @ 2020-07-17  5:56 UTC (permalink / raw)
  To: Russell King - ARM Linux admin; +Cc: Andrew Lunn, netdev, davem, vivien.didelot

On Sun, 12 Jul 2020 at 13:26, Russell King - ARM Linux admin
<linux@armlinux.org.uk> wrote:
> If you have machine A with address 192.168.2.1/24 on lan1 and machine B
> with address 192.168.2.2/24 on lan2, then they should be able to ping
> each other - the packet flow will be through the DSA switch without
> involving the CPU.

I can confirm that bridging the lan ports and connecting two physical
machines does allow me to ping between the two machines, with and
without the commit reverted.

> If it is a port issue, that should help pinpoint it - if it's a problem
> with the CPU port configuration, then ethtool can't read those registers
> (and the only way to get them is to apply some debugfs patch that was
> refused from being merged into mainline.)

It looks like this is the next step then. Do you have a link to the
patch? I'll give it a go. What outputs would be useful for me to
provide?

> > I'm now less confident about my git bisect...
> That seems really weird!

And ended up being unrelated to the current issue; I had other things
connected to the switch while I was testing it and I think STP was
getting involved. Either way, I've isolated it now and have confirmed
that 5.8-rc4 with that one commit reverted is working perfectly. Sorry
for the confusion.

Martin

^ permalink raw reply	[flat|nested] 17+ messages in thread

* Re: bug: net: dsa: mv88e6xxx: unable to tx or rx with Clearfog GT 8K (with git bisect)
  2020-07-17  5:56         ` Martin Rowe
@ 2020-07-17  9:21           ` Russell King - ARM Linux admin
  2020-07-17 12:50             ` Martin Rowe
  0 siblings, 1 reply; 17+ messages in thread
From: Russell King - ARM Linux admin @ 2020-07-17  9:21 UTC (permalink / raw)
  To: Martin Rowe; +Cc: Andrew Lunn, netdev, davem, vivien.didelot

On Fri, Jul 17, 2020 at 05:56:22AM +0000, Martin Rowe wrote:
> On Sun, 12 Jul 2020 at 13:26, Russell King - ARM Linux admin
> <linux@armlinux.org.uk> wrote:
> > If it is a port issue, that should help pinpoint it - if it's a problem
> > with the CPU port configuration, then ethtool can't read those registers
> > (and the only way to get them is to apply some debugfs patch that was
> > refused from being merged into mainline.)
> 
> It looks like this is the next step then. Do you have a link to the
> patch? I'll give it a go. What outputs would be useful for me to
> provide?

The patch below is what I'm still using - a forward ported version of
a Vivien's very old debugfs patch (but with bits of it disabled.) I
prefer the combined format of the "regs" file which dumps all the
switch registers in one place.

The key file is /sys/kernel/debug/mv88e6xxx.0/regs - please send the
contents of that file.

Thanks.

8<===
From: Vivien Didelot <vivien.didelot@savoirfairelinux.com>
Subject: [PATCH] net: dsa: mv88e6xxx: add debugfs interface

Add a debugfs directory named mv88e6xxx.X where X is the DSA switch
index. Mount the debugfs file system with:

    # mount -t debugfs none /sys/kernel/debug

Signed-off-by: Vivien Didelot <vivien.didelot@savoirfairelinux.com>
[Modified by rmk for current kernels.]
Signed-off-by: Russell King <rmk+kernel@armlinux.org.uk>
---
 drivers/net/dsa/mv88e6xxx/chip.c              |    7 +
 drivers/net/dsa/mv88e6xxx/chip.h              |    2 +
 drivers/net/dsa/mv88e6xxx/mv88e6xxx_debugfs.c | 1102 +++++++++++++++++
 3 files changed, 1111 insertions(+)
 create mode 100644 drivers/net/dsa/mv88e6xxx/mv88e6xxx_debugfs.c

diff --git a/drivers/net/dsa/mv88e6xxx/chip.c b/drivers/net/dsa/mv88e6xxx/chip.c
index 7627ea61e0ea..0bce26f1df93 100644
--- a/drivers/net/dsa/mv88e6xxx/chip.c
+++ b/drivers/net/dsa/mv88e6xxx/chip.c
@@ -3030,8 +3030,13 @@ static int mv88e6xxx_setup_devlink_resources(struct dsa_switch *ds)
 	return err;
 }
 
+#include "mv88e6xxx_debugfs.c"
+
 static void mv88e6xxx_teardown(struct dsa_switch *ds)
 {
+	struct mv88e6xxx_chip *chip = ds->priv;
+
+	mv88e6xxx_remove_debugfs(chip);
 	mv88e6xxx_teardown_devlink_params(ds);
 	dsa_devlink_resources_unregister(ds);
 }
@@ -3149,6 +3154,8 @@ static int mv88e6xxx_setup(struct dsa_switch *ds)
 	if (err)
 		goto unlock;
 
+	mv88e6xxx_init_debugfs(chip);
+
 unlock:
 	mv88e6xxx_reg_unlock(chip);
 
diff --git a/drivers/net/dsa/mv88e6xxx/chip.h b/drivers/net/dsa/mv88e6xxx/chip.h
index e5430cf2ad71..f78536bdfe39 100644
--- a/drivers/net/dsa/mv88e6xxx/chip.h
+++ b/drivers/net/dsa/mv88e6xxx/chip.h
@@ -333,6 +333,8 @@ struct mv88e6xxx_chip {
 
 	/* Array of port structures. */
 	struct mv88e6xxx_port ports[DSA_MAX_PORTS];
+
+	struct dentry *dbgfs;
 };
 
 struct mv88e6xxx_bus_ops {
diff --git a/drivers/net/dsa/mv88e6xxx/mv88e6xxx_debugfs.c b/drivers/net/dsa/mv88e6xxx/mv88e6xxx_debugfs.c
new file mode 100644
index 000000000000..4005a4760884
--- /dev/null
+++ b/drivers/net/dsa/mv88e6xxx/mv88e6xxx_debugfs.c
@@ -0,0 +1,1102 @@
+#include <linux/debugfs.h>
+#include <linux/seq_file.h>
+
+#define GLOBAL2_PVT_ADDR	0x0b
+#define GLOBAL2_PVT_ADDR_BUSY	BIT(15)
+#define GLOBAL2_PVT_ADDR_OP_INIT_ONES	((0x01 << 12) | GLOBAL2_PVT_ADDR_BUSY)
+#define GLOBAL2_PVT_ADDR_OP_WRITE_PVLAN	((0x03 << 12) | GLOBAL2_PVT_ADDR_BUSY)
+#define GLOBAL2_PVT_ADDR_OP_READ	((0x04 << 12) | GLOBAL2_PVT_ADDR_BUSY)
+#define GLOBAL2_PVT_DATA	0x0c
+
+#define ADDR_GLOBAL2	0x1c
+
+static int mv88e6xxx_serdes_read(struct mv88e6xxx_chip *chip, int reg, u16 *val)
+{
+	return mv88e6xxx_phy_page_read(chip, MV88E6352_ADDR_SERDES,
+				       MV88E6352_SERDES_PAGE_FIBER,
+				       reg, val);
+}
+
+static int mv88e6xxx_serdes_write(struct mv88e6xxx_chip *chip, int reg, u16 val)
+{
+	return mv88e6xxx_phy_page_write(chip, MV88E6352_ADDR_SERDES,
+					MV88E6352_SERDES_PAGE_FIBER,
+					reg, val);
+}
+
+static int _mv88e6xxx_pvt_wait(struct mv88e6xxx_chip *chip)
+{
+	return mv88e6xxx_wait_mask(chip, ADDR_GLOBAL2, GLOBAL2_PVT_ADDR,
+				   GLOBAL2_PVT_ADDR_BUSY, 0);
+}
+
+static int _mv88e6xxx_pvt_cmd(struct mv88e6xxx_chip *chip, int src_dev,
+			      int src_port, u16 op)
+{
+	u16 reg = op;
+	int err;
+
+	/* 9-bit Cross-chip PVT pointer: with GLOBAL2_MISC_5_BIT_PORT cleared,
+	 * source device is 5-bit, source port is 4-bit.
+	 */
+	reg |= (src_dev & 0x1f) << 4;
+	reg |= (src_port & 0xf);
+
+	err = mv88e6xxx_g2_write(chip, GLOBAL2_PVT_ADDR, reg);
+	if (err)
+		return err;
+
+	return _mv88e6xxx_pvt_wait(chip);
+}
+
+static int _mv88e6xxx_pvt_read(struct mv88e6xxx_chip *chip, int src_dev,
+			       int src_port, u16 *data)
+{
+	int ret;
+
+	ret = _mv88e6xxx_pvt_wait(chip);
+	if (ret < 0)
+		return ret;
+
+	ret = _mv88e6xxx_pvt_cmd(chip, src_dev, src_port,
+				GLOBAL2_PVT_ADDR_OP_READ);
+	if (ret < 0)
+		return ret;
+
+	return mv88e6xxx_g2_read(chip, GLOBAL2_PVT_DATA, data);
+}
+
+static int _mv88e6xxx_pvt_write(struct mv88e6xxx_chip *chip, int src_dev,
+				int src_port, u16 data)
+{
+	int err;
+
+	err = _mv88e6xxx_pvt_wait(chip);
+	if (err)
+		return err;
+
+	err = mv88e6xxx_g2_write(chip, GLOBAL2_PVT_DATA, data);
+	if (err)
+		return err;
+
+        return _mv88e6xxx_pvt_cmd(chip, src_dev, src_port,
+				  GLOBAL2_PVT_ADDR_OP_WRITE_PVLAN);
+}
+
+static int mv88e6xxx_regs_show(struct seq_file *s, void *p)
+{
+	struct mv88e6xxx_chip *chip = s->private;
+	int port, reg, ret;
+	u16 data;
+
+	seq_puts(s, "    GLOBAL GLOBAL2 SERDES   ");
+	for (port = 0; port < mv88e6xxx_num_ports(chip); port++)
+		seq_printf(s, " %2d  ", port);
+	seq_puts(s, "\n");
+
+	mutex_lock(&chip->reg_lock);
+
+	for (reg = 0; reg < 32; reg++) {
+		seq_printf(s, "%2x:", reg);
+
+		ret = mv88e6xxx_g1_read(chip, reg, &data);
+		if (ret < 0)
+			goto unlock;
+		seq_printf(s, "  %4x  ", data);
+
+		ret = mv88e6xxx_g2_read(chip, reg, &data);
+		if (ret < 0)
+			goto unlock;
+		seq_printf(s, "  %4x  ", data);
+
+		if (reg != MV88E6XXX_PHY_PAGE) {
+			ret = mv88e6xxx_serdes_read(chip, reg, &data);
+			if (ret < 0)
+				goto unlock;
+		} else {
+			data = 0;
+		}
+		seq_printf(s, "  %4x  ", data);
+
+		/* Port regs 0x1a-0x1f are reserved in 6185 family */
+		if (chip->info->family == MV88E6XXX_FAMILY_6185 && reg > 25) {
+			for (port = 0; port < mv88e6xxx_num_ports(chip); ++port)
+				seq_printf(s, "%4c ", '-');
+			seq_puts(s, "\n");
+			continue;
+		}
+
+		for (port = 0; port < mv88e6xxx_num_ports(chip); ++port) {
+			ret = mv88e6xxx_port_read(chip, port, reg, &data);
+			if (ret < 0)
+				goto unlock;
+
+			seq_printf(s, "%4x ", data);
+		}
+
+		seq_puts(s, "\n");
+	}
+
+	ret = 0;
+unlock:
+	mutex_unlock(&chip->reg_lock);
+
+	return ret;
+}
+
+static ssize_t mv88e6xxx_regs_write(struct file *file, const char __user *buf,
+				    size_t count, loff_t *ppos)
+{
+	struct seq_file *s = file->private_data;
+	struct mv88e6xxx_chip *chip = s->private;
+	char cmd[32], name[32] = { 0 };
+	unsigned int port, reg, val;
+	int ret;
+
+	if (count > sizeof(name) - 1)
+		return -EINVAL;
+
+	if (copy_from_user(cmd, buf, sizeof(cmd)))
+		return -EFAULT;
+
+	ret = sscanf(cmd, "%s %x %x", name, &reg, &val);
+	if (ret != 3)
+		return -EINVAL;
+
+	if (reg > 0x1f || val > 0xffff)
+		return -ERANGE;
+
+	mutex_lock(&chip->reg_lock);
+
+	if (strcasecmp(name, "GLOBAL") == 0)
+		ret = mv88e6xxx_g1_write(chip, reg, val);
+	else if (strcasecmp(name, "GLOBAL2") == 0)
+		ret = mv88e6xxx_g2_write(chip, reg, val);
+	else if (strcasecmp(name, "SERDES") == 0)
+		ret = mv88e6xxx_serdes_write(chip, reg, val);
+	else if (kstrtouint(name, 10, &port) == 0 && port < mv88e6xxx_num_ports(chip))
+		ret = mv88e6xxx_port_write(chip, port, reg, val);
+	else
+		ret = -EINVAL;
+
+	mutex_unlock(&chip->reg_lock);
+
+	return ret < 0 ? ret : count;
+}
+
+static int mv88e6xxx_regs_open(struct inode *inode, struct file *file)
+{
+	return single_open(file, mv88e6xxx_regs_show, inode->i_private);
+}
+
+static const struct file_operations mv88e6xxx_regs_fops = {
+	.open   = mv88e6xxx_regs_open,
+	.read   = seq_read,
+	.write  = mv88e6xxx_regs_write,
+	.llseek = no_llseek,
+	.release = single_release,
+	.owner  = THIS_MODULE,
+};
+
+static int mv88e6xxx_name_show(struct seq_file *s, void *p)
+{
+	struct mv88e6xxx_chip *chip = s->private;
+	struct dsa_switch *ds = chip->ds;
+	struct dsa_switch_tree *dst = ds->dst;
+	struct dsa_port *dp;
+	int i;
+
+	if (!ds->cd)
+		return 0;
+
+	seq_puts(s, " Port  Name\n");
+
+	list_for_each_entry(dp, &dst->ports, list) {
+		if (dp->ds != ds)
+			continue;
+
+		i = dp->index;
+		if (!ds->cd->port_names[i])
+			continue;
+
+		seq_printf(s, "%4d   %s", i, ds->cd->port_names[i]);
+
+		if (dp->slave)
+			seq_printf(s, " (%s)", netdev_name(dp->slave));
+
+		seq_puts(s, "\n");
+	}
+
+	return 0;
+}
+
+static int mv88e6xxx_name_open(struct inode *inode, struct file *file)
+{
+	return single_open(file, mv88e6xxx_name_show, inode->i_private);
+}
+
+static const struct file_operations mv88e6xxx_name_fops = {
+	.open		= mv88e6xxx_name_open,
+	.read		= seq_read,
+	.llseek		= no_llseek,
+	.release	= single_release,
+	.owner		= THIS_MODULE,
+};
+
+static int mv88e6xxx_atu_show(struct seq_file *s, void *p)
+{
+	struct mv88e6xxx_chip *chip = s->private;
+	struct mv88e6xxx_atu_entry addr;
+	const char *state;
+	int fid, i, err;
+
+	seq_puts(s, " FID  MAC Addr                  State         Trunk?  DPV/Trunk ID\n");
+
+	for (fid = 0; fid < mv88e6xxx_num_databases(chip); ++fid) {
+		addr.state = 0;
+		eth_broadcast_addr(addr.mac);
+
+		do {
+			mutex_lock(&chip->reg_lock);
+			err = mv88e6xxx_g1_atu_getnext(chip, fid, &addr);
+			mutex_unlock(&chip->reg_lock);
+			if (err)
+				return err;
+
+			if (addr.state == 0)
+				break;
+
+			/* print ATU entry */
+			seq_printf(s, "%4d  %pM", fid, addr.mac);
+
+			if (is_multicast_ether_addr(addr.mac)) {
+				switch (addr.state) {
+				case MV88E6XXX_G1_ATU_DATA_STATE_MC_STATIC_PO:
+					state = "MC_STATIC_PO";
+					break;
+				case MV88E6XXX_G1_ATU_DATA_STATE_MC_STATIC_DA_MGMT_PO:
+					state = "MC_STATIC_MGMT_PO";
+					break;
+				case MV88E6XXX_G1_ATU_DATA_STATE_MC_STATIC_AVB_NRL_PO:
+					state = "MC_STATIC_NRL_PO";
+					break;
+				case MV88E6XXX_G1_ATU_DATA_STATE_MC_STATIC_POLICY_PO:
+					state = "MC_STATIC_POLICY_PO";
+					break;
+				case MV88E6XXX_G1_ATU_DATA_STATE_MC_STATIC:
+					state = "MC_STATIC";
+					break;
+				case MV88E6XXX_G1_ATU_DATA_STATE_MC_STATIC_DA_MGMT:
+					state = "MC_STATIC_MGMT";
+					break;
+				case MV88E6XXX_G1_ATU_DATA_STATE_MC_STATIC_AVB_NRL:
+					state = "MC_STATIC_NRL";
+					break;
+				case MV88E6XXX_G1_ATU_DATA_STATE_MC_STATIC_POLICY:
+					state = "MC_STATIC_POLICY";
+					break;
+				case 0xb: case 0xa: case 0x9: case 0x8:
+					/* Reserved for future use */
+				case 0x3: case 0x2: case 0x1:
+					/* Reserved for future use */
+				case MV88E6XXX_G1_ATU_DATA_STATE_MC_UNUSED:
+				default:
+					state = "???";
+					break;
+				}
+			} else {
+				switch (addr.state) {
+				case MV88E6XXX_G1_ATU_DATA_STATE_UC_STATIC_PO:
+					state = "UC_STATIC_PO";
+					break;
+				case MV88E6XXX_G1_ATU_DATA_STATE_UC_STATIC:
+					state = "UC_STATIC";
+					break;
+				case MV88E6XXX_G1_ATU_DATA_STATE_UC_STATIC_DA_MGMT_PO:
+					state = "UC_STATIC_MGMT_PO";
+					break;
+				case MV88E6XXX_G1_ATU_DATA_STATE_UC_STATIC_DA_MGMT:
+					state = "UC_STATIC_MGMT";
+					break;
+				case MV88E6XXX_G1_ATU_DATA_STATE_UC_STATIC_AVB_NRL_PO:
+					state = "UC_STATIC_NRL_PO";
+					break;
+				case MV88E6XXX_G1_ATU_DATA_STATE_UC_STATIC_AVB_NRL:
+					state = "UC_STATIC_NRL";
+					break;
+				case MV88E6XXX_G1_ATU_DATA_STATE_UC_STATIC_POLICY_PO:
+					state = "UC_STATIC_POLICY_PO";
+					break;
+				case MV88E6XXX_G1_ATU_DATA_STATE_UC_STATIC_POLICY:
+					state = "UC_STATIC_POLICY";
+					break;
+				case MV88E6XXX_G1_ATU_DATA_STATE_UC_AGE_7_NEWEST:
+					state = "Age 7 (newest)";
+					break;
+				case MV88E6XXX_G1_ATU_DATA_STATE_UC_AGE_6:
+					state = "Age 6";
+					break;
+				case MV88E6XXX_G1_ATU_DATA_STATE_UC_AGE_5:
+					state = "Age 5";
+					break;
+				case MV88E6XXX_G1_ATU_DATA_STATE_UC_AGE_4:
+					state = "Age 4";
+					break;
+				case MV88E6XXX_G1_ATU_DATA_STATE_UC_AGE_3:
+					state = "Age 3";
+					break;
+				case MV88E6XXX_G1_ATU_DATA_STATE_UC_AGE_2:
+					state = "Age 2";
+					break;
+				case MV88E6XXX_G1_ATU_DATA_STATE_UC_AGE_1_OLDEST:
+					state = "Age 1 (oldest)";
+					break;
+				case MV88E6XXX_G1_ATU_DATA_STATE_UC_UNUSED:
+				default:
+					state = "???";
+					break;
+				}
+			}
+
+			seq_printf(s, "  %19s", state);
+
+			if (addr.trunk) {
+				seq_printf(s, "       y  %d",
+					   addr.portvec);
+			} else {
+				seq_puts(s, "       n ");
+				for (i = 0; i < mv88e6xxx_num_ports(chip); ++i)
+					seq_printf(s, " %c",
+						   addr.portvec & BIT(i) ?
+						   48 + i : '-');
+			}
+
+			seq_puts(s, "\n");
+		} while (!is_broadcast_ether_addr(addr.mac));
+	}
+
+	return 0;
+}
+
+static ssize_t mv88e6xxx_atu_write(struct file *file, const char __user *buf,
+				   size_t count, loff_t *ppos)
+{
+	struct seq_file *s = file->private_data;
+	struct mv88e6xxx_chip *chip = s->private;
+	char cmd[64];
+	unsigned int fid;
+	int ret;
+
+	if (copy_from_user(cmd, buf, sizeof(cmd)))
+		return -EFAULT;
+
+	ret = sscanf(cmd, "%u", &fid);
+	if (ret != 1)
+		return -EINVAL;
+
+	if (fid >= mv88e6xxx_num_databases(chip))
+		return -ERANGE;
+
+	mutex_lock(&chip->reg_lock);
+	ret = mv88e6xxx_g1_atu_flush(chip, fid, true);
+	mutex_unlock(&chip->reg_lock);
+
+	return ret < 0 ? ret : count;
+}
+
+static int mv88e6xxx_atu_open(struct inode *inode, struct file *file)
+{
+	return single_open(file, mv88e6xxx_atu_show, inode->i_private);
+}
+
+static const struct file_operations mv88e6xxx_atu_fops = {
+	.open   = mv88e6xxx_atu_open,
+	.read   = seq_read,
+	.write   = mv88e6xxx_atu_write,
+	.llseek = no_llseek,
+	.release = single_release,
+	.owner  = THIS_MODULE,
+};
+
+static int mv88e6xxx_default_vid_show(struct seq_file *s, void *p)
+{
+	struct mv88e6xxx_chip *chip = s->private;
+	u16 pvid;
+	int i, err;
+
+	seq_puts(s, " Port  DefaultVID\n");
+
+	mutex_lock(&chip->reg_lock);
+
+	for (i = 0; i < mv88e6xxx_num_ports(chip); ++i) {
+		err = mv88e6xxx_port_get_pvid(chip, i, &pvid);
+		if (err)
+			break;
+
+		seq_printf(s, "%4d  %d\n", i, pvid);
+	}
+
+	mutex_unlock(&chip->reg_lock);
+
+	return err;
+}
+
+static ssize_t mv88e6xxx_default_vid_write(struct file *file,
+					   const char __user *buf, size_t count,
+					   loff_t *ppos)
+{
+	struct seq_file *s = file->private_data;
+	struct mv88e6xxx_chip *chip = s->private;
+	char cmd[32];
+	unsigned int port, pvid;
+	int ret;
+
+	if (copy_from_user(cmd, buf, sizeof(cmd)))
+		return -EFAULT;
+
+	ret = sscanf(cmd, "%u %u", &port, &pvid);
+	if (ret != 2)
+		return -EINVAL;
+
+	if (port >= mv88e6xxx_num_ports(chip) || pvid > 0xfff)
+		return -ERANGE;
+
+	mutex_lock(&chip->reg_lock);
+	ret = mv88e6xxx_port_set_pvid(chip, port, pvid);
+	mutex_unlock(&chip->reg_lock);
+
+	return ret < 0 ? ret : count;
+}
+
+static int mv88e6xxx_default_vid_open(struct inode *inode, struct file *file)
+{
+	return single_open(file, mv88e6xxx_default_vid_show, inode->i_private);
+}
+
+static const struct file_operations mv88e6xxx_default_vid_fops = {
+	.open		= mv88e6xxx_default_vid_open,
+	.read		= seq_read,
+	.write		= mv88e6xxx_default_vid_write,
+	.llseek		= no_llseek,
+	.release	= single_release,
+	.owner		= THIS_MODULE,
+};
+
+static int mv88e6xxx_fid_show(struct seq_file *s, void *p)
+{
+	struct mv88e6xxx_chip *chip = s->private;
+	u16 fid;
+	int i, err;
+
+	seq_puts(s, " Port  FID\n");
+
+	mutex_lock(&chip->reg_lock);
+
+	for (i = 0; i < mv88e6xxx_num_ports(chip); ++i) {
+		err = mv88e6xxx_port_get_fid(chip, i, &fid);
+		if (err)
+			break;
+
+		seq_printf(s, "%4d  %d\n", i, fid);
+	}
+
+	mutex_unlock(&chip->reg_lock);
+
+	return err;
+}
+
+static int mv88e6xxx_fid_open(struct inode *inode, struct file *file)
+{
+	return single_open(file, mv88e6xxx_fid_show, inode->i_private);
+}
+
+static const struct file_operations mv88e6xxx_fid_fops = {
+	.open		= mv88e6xxx_fid_open,
+	.read		= seq_read,
+	.llseek		= no_llseek,
+	.release	= single_release,
+	.owner		= THIS_MODULE,
+};
+
+static const char * const mv88e6xxx_port_state_names[] = {
+	[MV88E6XXX_PORT_CTL0_STATE_DISABLED] = "Disabled",
+	[MV88E6XXX_PORT_CTL0_STATE_BLOCKING] = "Blocking/Listening",
+	[MV88E6XXX_PORT_CTL0_STATE_LEARNING] = "Learning",
+	[MV88E6XXX_PORT_CTL0_STATE_FORWARDING] = "Forwarding",
+};
+
+static int mv88e6xxx_state_show(struct seq_file *s, void *p)
+{
+	struct mv88e6xxx_chip *chip = s->private;
+	int i, ret;
+	u16 data;
+
+	/* header */
+	seq_puts(s, " Port  Mode\n");
+
+	mutex_lock(&chip->reg_lock);
+
+	/* One line per input port */
+	for (i = 0; i < mv88e6xxx_num_ports(chip); ++i) {
+		seq_printf(s, "%4d ", i);
+
+		ret = mv88e6xxx_port_read(chip, i, MV88E6XXX_PORT_CTL0, &data);
+		if (ret < 0)
+			goto unlock;
+
+		data &= MV88E6XXX_PORT_CTL0_STATE_MASK;
+		seq_printf(s, " %s\n", mv88e6xxx_port_state_names[data]);
+		ret = 0;
+	}
+
+unlock:
+	mutex_unlock(&chip->reg_lock);
+
+	return ret;
+}
+
+static int mv88e6xxx_state_open(struct inode *inode, struct file *file)
+{
+	return single_open(file, mv88e6xxx_state_show, inode->i_private);
+}
+
+static const struct file_operations mv88e6xxx_state_fops = {
+	.open		= mv88e6xxx_state_open,
+	.read		= seq_read,
+	.llseek		= no_llseek,
+	.release	= single_release,
+	.owner		= THIS_MODULE,
+};
+
+static const char * const mv88e6xxx_port_8021q_mode_names[] = {
+	[MV88E6XXX_PORT_CTL2_8021Q_MODE_DISABLED] = "Disabled",
+	[MV88E6XXX_PORT_CTL2_8021Q_MODE_FALLBACK] = "Fallback",
+	[MV88E6XXX_PORT_CTL2_8021Q_MODE_CHECK] = "Check",
+	[MV88E6XXX_PORT_CTL2_8021Q_MODE_SECURE] = "Secure",
+};
+
+static int mv88e6xxx_8021q_mode_show(struct seq_file *s, void *p)
+{
+	struct mv88e6xxx_chip *chip = s->private;
+	int i, ret;
+	u16 data;
+
+	/* header */
+	seq_puts(s, " Port  Mode\n");
+
+	mutex_lock(&chip->reg_lock);
+
+	/* One line per input port */
+	for (i = 0; i < mv88e6xxx_num_ports(chip); ++i) {
+		seq_printf(s, "%4d ", i);
+
+		ret = mv88e6xxx_port_read(chip, i, MV88E6XXX_PORT_CTL2, &data);
+		if (ret < 0)
+			goto unlock;
+
+		data &= MV88E6XXX_PORT_CTL2_8021Q_MODE_MASK;
+		seq_printf(s, " %s\n", mv88e6xxx_port_8021q_mode_names[data]);
+		ret = 0;
+	}
+
+unlock:
+	mutex_unlock(&chip->reg_lock);
+
+	return ret;
+}
+
+static int mv88e6xxx_8021q_mode_open(struct inode *inode, struct file *file)
+{
+	return single_open(file, mv88e6xxx_8021q_mode_show, inode->i_private);
+}
+
+static const struct file_operations mv88e6xxx_8021q_mode_fops = {
+	.open		= mv88e6xxx_8021q_mode_open,
+	.read		= seq_read,
+	.llseek		= no_llseek,
+	.release	= single_release,
+	.owner		= THIS_MODULE,
+};
+
+static int mv88e6xxx_vlan_table_show(struct seq_file *s, void *p)
+{
+	struct mv88e6xxx_chip *chip = s->private;
+	int i, j, ret;
+	u16 data;
+
+	/* header */
+	seq_puts(s, " Port");
+	for (i = 0; i < mv88e6xxx_num_ports(chip); ++i)
+		seq_printf(s, " %2d", i);
+	seq_puts(s, "\n");
+
+	mutex_lock(&chip->reg_lock);
+
+	/* One line per input port */
+	for (i = 0; i < mv88e6xxx_num_ports(chip); ++i) {
+		seq_printf(s, "%4d ", i);
+
+		ret = mv88e6xxx_port_read(chip, i, MV88E6XXX_PORT_BASE_VLAN, &data);
+		if (ret < 0)
+			goto unlock;
+
+		/* One column per output port */
+		for (j = 0; j < mv88e6xxx_num_ports(chip); ++j)
+			seq_printf(s, "  %c", data & BIT(j) ? '*' : '-');
+		seq_puts(s, "\n");
+	}
+
+	ret = 0;
+unlock:
+	mutex_unlock(&chip->reg_lock);
+
+	return ret;
+}
+
+static int mv88e6xxx_vlan_table_open(struct inode *inode, struct file *file)
+{
+	return single_open(file, mv88e6xxx_vlan_table_show, inode->i_private);
+}
+
+static const struct file_operations mv88e6xxx_vlan_table_fops = {
+	.open		= mv88e6xxx_vlan_table_open,
+	.read		= seq_read,
+	.llseek		= no_llseek,
+	.release	= single_release,
+	.owner		= THIS_MODULE,
+};
+
+static int mv88e6xxx_pvt_show(struct seq_file *s, void *p)
+{
+#if 0
+	struct mv88e6xxx_chip *chip = s->private;
+	struct dsa_switch_tree *dst = chip->ds->dst;
+	int port, src_dev, src_port;
+	u16 pvlan;
+	int err = 0;
+
+	if (chip->info->family == MV88E6XXX_FAMILY_6185)
+		return -ENODEV;
+
+	/* header */
+	seq_puts(s, " Dev Port PVLAN");
+	for (port = 0; port < mv88e6xxx_num_ports(chip); ++port)
+		seq_printf(s, " %2d", port);
+	seq_puts(s, "\n");
+
+	mutex_lock(&chip->reg_lock);
+
+	/* One line per external port */
+	for (src_dev = 0; src_dev < DSA_MAX_SWITCHES; ++src_dev) {
+		if (!dst->ds[src_dev])
+			break;
+
+		if (src_dev == chip->ds->index)
+			continue;
+
+		seq_puts(s, "\n");
+		for (src_port = 0; src_port < 16; ++src_port) {
+			if (src_port >= DSA_MAX_PORTS)
+				break;
+
+			err = _mv88e6xxx_pvt_read(chip, src_dev, src_port,
+						  &pvlan);
+			if (err)
+				goto unlock;
+
+			seq_printf(s, "  %d   %2d   %03hhx ", src_dev, src_port,
+				   pvlan);
+
+			/* One column per internal output port */
+			for (port = 0; port < mv88e6xxx_num_ports(chip); ++port)
+				seq_printf(s, "  %c",
+					   pvlan & BIT(port) ? '*' : '-');
+			seq_puts(s, "\n");
+		}
+	}
+
+unlock:
+	mutex_unlock(&chip->reg_lock);
+	return err;
+#else
+	return 0;
+#endif
+}
+
+static ssize_t mv88e6xxx_pvt_write(struct file *file, const char __user *buf,
+				    size_t count, loff_t *ppos)
+{
+	struct seq_file *s = file->private_data;
+	struct mv88e6xxx_chip *chip = s->private;
+	const u16 mask = (1 << mv88e6xxx_num_ports(chip)) - 1;
+	char cmd[32];
+	unsigned int src_dev, src_port, pvlan;
+	int ret;
+
+	if (copy_from_user(cmd, buf, sizeof(cmd)))
+		return -EFAULT;
+
+	if (sscanf(cmd, "%d %d %x", &src_dev, &src_port, &pvlan) != 3)
+		return -EINVAL;
+
+	if (src_dev >= 32 || src_port >= 16 || pvlan & ~mask)
+		return -ERANGE;
+
+	mutex_lock(&chip->reg_lock);
+	ret = _mv88e6xxx_pvt_write(chip, src_dev, src_port, pvlan);
+	mutex_unlock(&chip->reg_lock);
+
+	return ret < 0 ? ret : count;
+}
+
+static int mv88e6xxx_pvt_open(struct inode *inode, struct file *file)
+{
+	return single_open(file, mv88e6xxx_pvt_show, inode->i_private);
+}
+
+static const struct file_operations mv88e6xxx_pvt_fops = {
+	.open		= mv88e6xxx_pvt_open,
+	.read		= seq_read,
+	.write		= mv88e6xxx_pvt_write,
+	.llseek		= no_llseek,
+	.release	= single_release,
+	.owner		= THIS_MODULE,
+};
+
+static int mv88e6xxx_vtu_show(struct seq_file *s, void *p)
+{
+	struct mv88e6xxx_chip *chip = s->private;
+	struct mv88e6xxx_vtu_entry next = { 0 };
+	int port, ret = 0;
+
+	seq_puts(s, " VID  FID  SID");
+	for (port = 0; port < mv88e6xxx_num_ports(chip); ++port)
+		seq_printf(s, " %2d", port);
+	seq_puts(s, "\n");
+
+	if (!chip->info->ops->vtu_getnext)
+		return 0;
+
+	next.vid = chip->info->max_vid; /* first or lowest VID */
+
+	do {
+		mutex_lock(&chip->reg_lock);
+		ret = chip->info->ops->vtu_getnext(chip, &next);
+		mutex_unlock(&chip->reg_lock);
+		if (ret < 0)
+			break;
+
+		if (!next.valid)
+			break;
+
+		seq_printf(s, "%4d %4d   %2d", next.vid, next.fid, next.sid);
+		for (port = 0; port < mv88e6xxx_num_ports(chip); ++port) {
+			switch (next.member[port]) {
+			case MV88E6XXX_G1_VTU_DATA_MEMBER_TAG_UNMODIFIED:
+				seq_puts(s, "  =");
+				break;
+			case MV88E6XXX_G1_VTU_DATA_MEMBER_TAG_UNTAGGED:
+				seq_puts(s, "  u");
+				break;
+			case MV88E6XXX_G1_VTU_DATA_MEMBER_TAG_TAGGED:
+				seq_puts(s, "  t");
+				break;
+			case MV88E6XXX_G1_VTU_DATA_MEMBER_TAG_NON_MEMBER:
+				seq_puts(s, "  x");
+				break;
+			default:
+				seq_puts(s, " ??");
+				break;
+			}
+		}
+		seq_puts(s, "\n");
+	} while (next.vid < chip->info->max_vid);
+
+	return ret;
+}
+
+static ssize_t mv88e6xxx_vtu_write(struct file *file, const char __user *buf,
+				   size_t count, loff_t *ppos)
+{
+	struct seq_file *s = file->private_data;
+	struct mv88e6xxx_chip *chip = s->private;
+	struct mv88e6xxx_vtu_entry entry = { 0 };
+	bool valid = true;
+	char cmd[64], tags[12]; /* DSA_MAX_PORTS */
+	int vid, fid, sid, port, ret;
+
+	if (!chip->info->ops->vtu_loadpurge)
+		return -EOPNOTSUPP;
+
+	if (copy_from_user(cmd, buf, sizeof(cmd)))
+		return -EFAULT;
+
+	/* scan 12 chars instead of num_ports to avoid dynamic scanning... */
+	ret = sscanf(cmd, "%d %d %d %c %c %c %c %c %c %c %c %c %c %c %c", &vid,
+		     &fid, &sid, &tags[0], &tags[1], &tags[2], &tags[3],
+		     &tags[4], &tags[5], &tags[6], &tags[7], &tags[8], &tags[9],
+		     &tags[10], &tags[11]);
+	if (ret == 1)
+		valid = false;
+	else if (ret != 3 + mv88e6xxx_num_ports(chip))
+		return -EINVAL;
+
+	entry.vid = vid;
+	entry.valid = valid;
+
+	if (valid) {
+		entry.fid = fid;
+		entry.sid = sid;
+		/* Note: The VTU entry pointed by VID will be loaded but not
+		 * considered valid until the STU entry pointed by SID is valid.
+		 */
+
+		for (port = 0; port < mv88e6xxx_num_ports(chip); ++port) {
+			u8 tag;
+
+			switch (tags[port]) {
+			case 'u':
+				tag = MV88E6XXX_G1_VTU_DATA_MEMBER_TAG_UNTAGGED;
+				break;
+			case 't':
+				tag = MV88E6XXX_G1_VTU_DATA_MEMBER_TAG_TAGGED;
+				break;
+			case 'x':
+				tag = MV88E6XXX_G1_VTU_DATA_MEMBER_TAG_NON_MEMBER;
+				break;
+			case '=':
+				tag = MV88E6XXX_G1_VTU_DATA_MEMBER_TAG_UNMODIFIED;
+				break;
+			default:
+				return -EINVAL;
+			}
+
+			entry.member[port] = tag;
+		}
+	}
+
+	mutex_lock(&chip->reg_lock);
+	ret = chip->info->ops->vtu_loadpurge(chip, &entry);
+	mutex_unlock(&chip->reg_lock);
+
+	return ret < 0 ? ret : count;
+}
+
+static int mv88e6xxx_vtu_open(struct inode *inode, struct file *file)
+{
+	return single_open(file, mv88e6xxx_vtu_show, inode->i_private);
+}
+
+static const struct file_operations mv88e6xxx_vtu_fops = {
+	.open		= mv88e6xxx_vtu_open,
+	.read		= seq_read,
+	.write		= mv88e6xxx_vtu_write,
+	.llseek		= no_llseek,
+	.release	= single_release,
+	.owner		= THIS_MODULE,
+};
+#if 0
+static int mv88e6xxx_stats_show(struct seq_file *s, void *p)
+{
+	struct mv88e6xxx_chip *chip = s->private;
+	char *strs;
+	u64 *stats;
+	int stat, port, num_stats, num_ports;
+	int err = 0;
+
+	num_stats = mv88e6xxx_get_sset_count(chip->ds);
+	if (num_stats == 0)
+		return 0;
+
+	num_ports = mv88e6xxx_num_ports(chip);
+
+	strs = kcalloc(num_stats, ETH_GSTRING_LEN, GFP_KERNEL);
+	stats = kcalloc(num_stats, num_ports * sizeof(*stats), GFP_KERNEL);
+	if (!strs || !strs) {
+		kfree(strs);
+		kfree(stats);
+		return -ENOMEM;
+	}
+
+	mv88e6xxx_get_strings(chip->ds, 0, strs);
+
+	for (port = 0; port < num_ports; port++)
+		mv88e6xxx_get_ethtool_stats(chip->ds, port, stats + (port * num_stats));
+
+	seq_puts(s, "          Statistic  ");
+	for (port = 0; port < mv88e6xxx_num_ports(chip); port++)
+		seq_printf(s, " Port %2d ", port);
+	seq_puts(s, "\n");
+
+	for (stat = 0; stat < num_stats; stat++) {
+		seq_printf(s, "%19s: ", strs + stat * ETH_GSTRING_LEN);
+		for (port = 0 ; port < num_ports; port++) {
+			u64 value = stats[stat + port * num_stats];
+
+			seq_printf(s, "%8llu ", value);
+		}
+		seq_puts(s, "\n");
+	}
+
+	kfree(stats);
+	kfree(strs);
+
+	return err;
+}
+
+static int mv88e6xxx_stats_open(struct inode *inode, struct file *file)
+{
+	return single_open(file, mv88e6xxx_stats_show, inode->i_private);
+}
+
+static const struct file_operations mv88e6xxx_stats_fops = {
+	.open   = mv88e6xxx_stats_open,
+	.read   = seq_read,
+	.llseek = no_llseek,
+	.release = single_release,
+	.owner  = THIS_MODULE,
+};
+#endif
+static int mv88e6xxx_device_map_show(struct seq_file *s, void *p)
+{
+	struct mv88e6xxx_chip *chip = s->private;
+	int target, ret;
+	u16 data, port_mask;
+
+	seq_puts(s, "Target Port\n");
+
+	/* FIXME */
+	port_mask = MV88E6390_G2_DEVICE_MAPPING_PORT_MASK;
+
+	mutex_lock(&chip->reg_lock);
+	for (target = 0; target < 32; target++) {
+		ret = mv88e6xxx_g2_write(chip, MV88E6XXX_G2_DEVICE_MAPPING,
+			target << 8 /* MV88E6XXX_G2_DEVICE_MAPPING_DEV_MASK */);
+		if (ret < 0)
+			goto out;
+		ret = mv88e6xxx_g2_read(chip, MV88E6XXX_G2_DEVICE_MAPPING, &data);
+		if (ret < 0)
+			goto out;
+		seq_printf(s, "  %2d   %2d\n", target, data & port_mask);
+	}
+out:
+	mutex_unlock(&chip->reg_lock);
+
+	return 0;
+}
+
+static int mv88e6xxx_device_map_open(struct inode *inode, struct file *file)
+{
+	return single_open(file, mv88e6xxx_device_map_show, inode->i_private);
+}
+
+static const struct file_operations mv88e6xxx_device_map_fops = {
+	.open   = mv88e6xxx_device_map_open,
+	.read   = seq_read,
+	.llseek = no_llseek,
+	.release = single_release,
+	.owner  = THIS_MODULE,
+};
+
+/* Must be called with SMI lock held */
+static int _mv88e6xxx_scratch_wait(struct mv88e6xxx_chip *chip)
+{
+	return mv88e6xxx_wait_mask(chip, ADDR_GLOBAL2,
+				   MV88E6XXX_G2_SCRATCH_MISC_MISC,
+			           MV88E6XXX_G2_SCRATCH_MISC_UPDATE, 0);
+}
+
+static int mv88e6xxx_scratch_show(struct seq_file *s, void *p)
+{
+	struct mv88e6xxx_chip *chip = s->private;
+	int reg, ret;
+	u16 data;
+
+	seq_puts(s, "Register Value\n");
+
+	mutex_lock(&chip->reg_lock);
+	for (reg = 0; reg < 0x80; reg++) {
+		ret = mv88e6xxx_g2_write(chip, MV88E6XXX_G2_SCRATCH_MISC_MISC,
+			reg << 8 /* MV88E6XXX_G2_SCRATCH_MISC_PTR_MASK */);
+		if (ret < 0)
+			goto out;
+
+		ret = _mv88e6xxx_scratch_wait(chip);
+		if (ret < 0)
+			goto out;
+
+		ret = mv88e6xxx_g2_read(chip, MV88E6XXX_G2_SCRATCH_MISC_MISC, &data);
+		seq_printf(s, "  %2x   %2x\n", reg,
+			   data & MV88E6XXX_G2_SCRATCH_MISC_DATA_MASK);
+	}
+out:
+	mutex_unlock(&chip->reg_lock);
+
+	return 0;
+}
+
+static int mv88e6xxx_scratch_open(struct inode *inode, struct file *file)
+{
+	return single_open(file, mv88e6xxx_scratch_show, inode->i_private);
+}
+
+static const struct file_operations mv88e6xxx_scratch_fops = {
+	.open   = mv88e6xxx_scratch_open,
+	.read   = seq_read,
+	.llseek = no_llseek,
+	.release = single_release,
+	.owner  = THIS_MODULE,
+};
+
+static void mv88e6xxx_init_debugfs(struct mv88e6xxx_chip *chip)
+{
+	char *name;
+
+	name = kasprintf(GFP_KERNEL, "mv88e6xxx.%d", chip->ds->index);
+	chip->dbgfs = debugfs_create_dir(name, NULL);
+
+	kfree(name);
+
+	debugfs_create_file("regs", S_IRUGO | S_IWUSR, chip->dbgfs, chip,
+			    &mv88e6xxx_regs_fops);
+
+	debugfs_create_file("name", S_IRUGO, chip->dbgfs, chip,
+			    &mv88e6xxx_name_fops);
+
+	debugfs_create_file("atu", S_IRUGO | S_IWUSR, chip->dbgfs, chip,
+			    &mv88e6xxx_atu_fops);
+
+	debugfs_create_file("default_vid", S_IRUGO | S_IWUSR, chip->dbgfs, chip,
+			    &mv88e6xxx_default_vid_fops);
+
+	debugfs_create_file("fid", S_IRUGO, chip->dbgfs, chip, &mv88e6xxx_fid_fops);
+
+	debugfs_create_file("state", S_IRUGO, chip->dbgfs, chip,
+			    &mv88e6xxx_state_fops);
+
+	debugfs_create_file("8021q_mode", S_IRUGO, chip->dbgfs, chip,
+			    &mv88e6xxx_8021q_mode_fops);
+
+	debugfs_create_file("vlan_table", S_IRUGO, chip->dbgfs, chip,
+			    &mv88e6xxx_vlan_table_fops);
+
+	debugfs_create_file("pvt", S_IRUGO | S_IWUSR, chip->dbgfs, chip,
+			    &mv88e6xxx_pvt_fops);
+
+	debugfs_create_file("vtu", S_IRUGO | S_IWUSR, chip->dbgfs, chip,
+			    &mv88e6xxx_vtu_fops);
+#if 0
+	debugfs_create_file("stats", S_IRUGO, chip->dbgfs, chip,
+			    &mv88e6xxx_stats_fops);
+#endif
+	debugfs_create_file("device_map", S_IRUGO, chip->dbgfs, chip,
+			    &mv88e6xxx_device_map_fops);
+
+	debugfs_create_file("scratch", S_IRUGO, chip->dbgfs, chip,
+			    &mv88e6xxx_scratch_fops);
+}
+
+static void mv88e6xxx_remove_debugfs(struct mv88e6xxx_chip *chip)
+{
+	debugfs_remove_recursive(chip->dbgfs);
+}
-- 
2.20.1


-- 
RMK's Patch system: https://www.armlinux.org.uk/developer/patches/
FTTP is here! 40Mbps down 10Mbps up. Decent connectivity at last!

^ permalink raw reply related	[flat|nested] 17+ messages in thread

* Re: bug: net: dsa: mv88e6xxx: unable to tx or rx with Clearfog GT 8K (with git bisect)
  2020-07-17  9:21           ` Russell King - ARM Linux admin
@ 2020-07-17 12:50             ` Martin Rowe
  2020-07-17 18:51               ` Russell King - ARM Linux admin
  0 siblings, 1 reply; 17+ messages in thread
From: Martin Rowe @ 2020-07-17 12:50 UTC (permalink / raw)
  To: Russell King - ARM Linux admin; +Cc: Andrew Lunn, netdev, davem, vivien.didelot

On Fri, 17 Jul 2020 at 09:22, Russell King - ARM Linux admin
<linux@armlinux.org.uk> wrote:
> The key file is /sys/kernel/debug/mv88e6xxx.0/regs - please send the
> contents of that file.

$ cat regs.broken
    GLOBAL GLOBAL2 SERDES     0    1    2    3    4    5
 0:  c800       0    ffff  9e07 9e4f 100f 100f 9e4f 170b
 1:     0    803e    ffff     3    3    3    3    3 201f
 2:     0       0    ffff  ff00    0    0    0    0    0
 3:     0       0    ffff  3400 3400 3400 3400 3400 3400
 4:  40a8     258    ffff    7c  43f  43c  43c  43f 373f
 5:  1000     4f0    ffff     0    0    0    0    0    0
 6:     0    1f0f    ffff    7e   7c   7a   76   6e   5f
 7:     0    703f    ffff     1    0    0    0    0    0
 8:     0    7800    ffff  2080 2080 2080 2080 2080 2080
 9:     0    1500    ffff     1    1    1    1    1    1
 a:   509       0    ffff  8000    0    0    0    0    0
 b:  3000    31ff    ffff     1    2    4    8   10    0
 c:   207       0    ffff     0    0    0    0    0    0
 d:  3333     50f    ffff     0    0    0    0    0    0
 e:     1       4    ffff     0    0    0    0    0    0
 f:     3     f00    ffff  9100 9100 9100 9100 9100 dada
10:     0       0    ffff     0    0    0    0    0    0
11:     0       0    ffff     0    0    0    0    0    0
12:  5555       0    ffff     0    0    0    0    0    0
13:  5555     300    ffff     0    0    0    0    0    0
14:  aaaa       0    ffff     0    0    0    0    0    0
15:  aaaa       0    ffff     0    0    0    0    0    0
16:  ffff       0       0     0   33   33   33   33    0
17:  ffff       0    ffff     0    0    0    0    0    0
18:  fa41    15f6    ffff  3210 3210 3210 3210 3210 3210
19:     0       0    ffff  7654 7654 7654 7654 7654 7654
1a:   3ff       0    ffff     0    0    0    0 1ea0 a100
1b:   1fc    110f    ffff  8000 8000 8000 8000 8000 8000
1c:   7c0       0    ffff     0    0    0    0    0    0
1d:  1400       0    ffff     0    0    0    0    0    0
1e:     0       0    ffff  f000 f000 f000 f000 f000 f000
1f:     0       0    ffff     0   2f    0    0   2e    1

$ cat regs.reverted
    GLOBAL GLOBAL2 SERDES     0    1    2    3    4    5
 0:  c800       0    ffff  9e07 9e4f 100f 100f 9e4f 1f0b
 1:     0    803e    ffff     3    3    3    3    3 203f
 2:     0       0    ffff  ff00    0    0    0    0    0
 3:     0       0    ffff  3400 3400 3400 3400 3400 3400
 4:  40a8     258    ffff    7c  43d  43c  43c  43f 373f
 5:  1000     4f0    ffff     0    0    0    0    0    0
 6:     0    1f0f    ffff    7e   7c   7a   76   6e   5f
 7:     0    703f    ffff     1    0    0    0    0    0
 8:     0    7800    ffff  2080 2080 2080 2080 2080 2080
 9:     0    1500    ffff     1    1    1    1    1    1
 a:   509       0    ffff  8000    0    0    0    0    0
 b:  3000    31ff    ffff     1    2    4    8   10    0
 c:   207       0    ffff     0    0    0    0    0    0
 d:  3333     58b    ffff     0    0    0    0    0    0
 e:     1       4    ffff     0    0    0    0    0    0
 f:     3     f00    ffff  9100 9100 9100 9100 9100 dada
10:     0       0    ffff     0    0    0    0    0    0
11:     0       0    ffff     0    0    0    0    0    0
12:  5555       0    ffff     0    0    0    0    0    0
13:  5555     300    ffff     0    0    0    0    0    0
14:  aaaa       0    ffff     0    0    0    0    0    0
15:  aaaa       0    ffff     0    0    0    0    0    0
16:  ffff       0       0     0   33   33   33   33    0
17:  ffff       0    ffff     0    0    0    0    0    0
18:  fa41    15f6    ffff  3210 3210 3210 3210 3210 3210
19:     0       0    ffff  7654 7654 7654 7654 7654 7654
1a:   3ff       0    ffff     0    0    0    0 1ea0 a100
1b:   1fc    110f    ffff  8000 8000 8000 8000 8000 8000
1c:   7c0       0    ffff     0    0    0    0    0    0
1d:  1400       0    ffff     0    0    0    0    0    0
1e:     0       0    ffff  f000 f000 f000 f000 f000 f000
1f:     0       0    ffff     0   91    0    0   7b   34

Both with 5.8.0-rc4, broken is just mainline, reverted has the one
commit reverted.

Martin

^ permalink raw reply	[flat|nested] 17+ messages in thread

* Re: bug: net: dsa: mv88e6xxx: unable to tx or rx with Clearfog GT 8K (with git bisect)
  2020-07-17 12:50             ` Martin Rowe
@ 2020-07-17 18:51               ` Russell King - ARM Linux admin
  2020-07-17 19:42                 ` Andrew Lunn
  0 siblings, 1 reply; 17+ messages in thread
From: Russell King - ARM Linux admin @ 2020-07-17 18:51 UTC (permalink / raw)
  To: Martin Rowe; +Cc: Andrew Lunn, netdev, davem, vivien.didelot

On Fri, Jul 17, 2020 at 12:50:07PM +0000, Martin Rowe wrote:
> On Fri, 17 Jul 2020 at 09:22, Russell King - ARM Linux admin
> <linux@armlinux.org.uk> wrote:
> > The key file is /sys/kernel/debug/mv88e6xxx.0/regs - please send the
> > contents of that file.
> 
> $ cat regs.broken
>     GLOBAL GLOBAL2 SERDES     0    1    2    3    4    5
>  0:  c800       0    ffff  9e07 9e4f 100f 100f 9e4f 170b
>  1:     0    803e    ffff     3    3    3    3    3 201f
                                                      ^^^^
This is where the problem is.

>  1:     0    803e    ffff     3    3    3    3    3 203f
                                                      ^^^^

In the broken case, the link is forced down, in the working case, the
link is forced up.

What seems to be happening is:

dsa_port_link_register_of() gets called, and we do this:

                phy_np = of_parse_phandle(dp->dn, "phy-handle", 0);
                if (of_phy_is_fixed_link(dp->dn) || phy_np) {
                        if (ds->ops->phylink_mac_link_down)
                                ds->ops->phylink_mac_link_down(ds, port,
                                        MLO_AN_FIXED, PHY_INTERFACE_MODE_NA);
                        return dsa_port_phylink_register(dp);

which forces the link down, and for some reason the link never comes
back up.

One of the issues here is of_phy_is_fixed_link() - it is dangerous.
The function name leads you astray - it suggests that if it returns
true, then you have a fixed link, but it also returns true of you
have managed!="auto" in DT, so it's actually fixed-or-inband-link.

Andrew, any thoughts?

I think it's looking more and more like we need my phylink hack to
grab the "defaults" for the port on phylink_start() to allow DSA to
work sanely with phylink, so that phylink can have the complete
information about the CPU port at all times.

-- 
RMK's Patch system: https://www.armlinux.org.uk/developer/patches/
FTTP is here! 40Mbps down 10Mbps up. Decent connectivity at last!

^ permalink raw reply	[flat|nested] 17+ messages in thread

* Re: bug: net: dsa: mv88e6xxx: unable to tx or rx with Clearfog GT 8K (with git bisect)
  2020-07-17 18:51               ` Russell King - ARM Linux admin
@ 2020-07-17 19:42                 ` Andrew Lunn
  2020-07-17 21:26                   ` Russell King - ARM Linux admin
  0 siblings, 1 reply; 17+ messages in thread
From: Andrew Lunn @ 2020-07-17 19:42 UTC (permalink / raw)
  To: Russell King - ARM Linux admin; +Cc: Martin Rowe, netdev, davem, vivien.didelot

On Fri, Jul 17, 2020 at 07:51:19PM +0100, Russell King - ARM Linux admin wrote:
> On Fri, Jul 17, 2020 at 12:50:07PM +0000, Martin Rowe wrote:
> > On Fri, 17 Jul 2020 at 09:22, Russell King - ARM Linux admin
> > <linux@armlinux.org.uk> wrote:
> > > The key file is /sys/kernel/debug/mv88e6xxx.0/regs - please send the
> > > contents of that file.
> > 
> > $ cat regs.broken
> >     GLOBAL GLOBAL2 SERDES     0    1    2    3    4    5
> >  0:  c800       0    ffff  9e07 9e4f 100f 100f 9e4f 170b
> >  1:     0    803e    ffff     3    3    3    3    3 201f
>                                                       ^^^^
> This is where the problem is.
> 
> >  1:     0    803e    ffff     3    3    3    3    3 203f
>                                                       ^^^^
> 
> In the broken case, the link is forced down, in the working case, the
> link is forced up.
> 
> What seems to be happening is:
> 
> dsa_port_link_register_of() gets called, and we do this:
> 
>                 phy_np = of_parse_phandle(dp->dn, "phy-handle", 0);
>                 if (of_phy_is_fixed_link(dp->dn) || phy_np) {
>                         if (ds->ops->phylink_mac_link_down)
>                                 ds->ops->phylink_mac_link_down(ds, port,
>                                         MLO_AN_FIXED, PHY_INTERFACE_MODE_NA);
>                         return dsa_port_phylink_register(dp);
> 
> which forces the link down, and for some reason the link never comes
> back up.
>
> One of the issues here is of_phy_is_fixed_link() - it is dangerous.
> The function name leads you astray - it suggests that if it returns
> true, then you have a fixed link, but it also returns true of you
> have managed!="auto" in DT, so it's actually fixed-or-inband-link.
> 
> Andrew, any thoughts?


Hi Russell

I think that is my change, if i remember correctly. Something to do
with phylink assuming all interfaces are down to begin with. But DSA
and CPU links were defaulting to up. When phylink later finds the
fixed-link it then configures the interface up again, and because the
interface is up, nothing actually happens, or it ends up in the wrong
mode. So i think my intention was, if there is a fixed link in DT,
down the interface before registering it with phylink, so its
assumptions are true, and it will later be correctly configured up.

So in this case, do you think we are falling into the trap of
managed!="auto" ?

	Andrew

^ permalink raw reply	[flat|nested] 17+ messages in thread

* Re: bug: net: dsa: mv88e6xxx: unable to tx or rx with Clearfog GT 8K (with git bisect)
  2020-07-17 19:42                 ` Andrew Lunn
@ 2020-07-17 21:26                   ` Russell King - ARM Linux admin
  2020-07-18  2:37                     ` Martin Rowe
  0 siblings, 1 reply; 17+ messages in thread
From: Russell King - ARM Linux admin @ 2020-07-17 21:26 UTC (permalink / raw)
  To: Andrew Lunn, Martin Rowe; +Cc: netdev, davem, vivien.didelot

On Fri, Jul 17, 2020 at 09:42:37PM +0200, Andrew Lunn wrote:
> On Fri, Jul 17, 2020 at 07:51:19PM +0100, Russell King - ARM Linux admin wrote:
> > On Fri, Jul 17, 2020 at 12:50:07PM +0000, Martin Rowe wrote:
> > > On Fri, 17 Jul 2020 at 09:22, Russell King - ARM Linux admin
> > > <linux@armlinux.org.uk> wrote:
> > > > The key file is /sys/kernel/debug/mv88e6xxx.0/regs - please send the
> > > > contents of that file.
> > > 
> > > $ cat regs.broken
> > >     GLOBAL GLOBAL2 SERDES     0    1    2    3    4    5
> > >  0:  c800       0    ffff  9e07 9e4f 100f 100f 9e4f 170b
> > >  1:     0    803e    ffff     3    3    3    3    3 201f
> >                                                       ^^^^
> > This is where the problem is.
> > 
> > >  1:     0    803e    ffff     3    3    3    3    3 203f
> >                                                       ^^^^
> > 
> > In the broken case, the link is forced down, in the working case, the
> > link is forced up.
> > 
> > What seems to be happening is:
> > 
> > dsa_port_link_register_of() gets called, and we do this:
> > 
> >                 phy_np = of_parse_phandle(dp->dn, "phy-handle", 0);
> >                 if (of_phy_is_fixed_link(dp->dn) || phy_np) {
> >                         if (ds->ops->phylink_mac_link_down)
> >                                 ds->ops->phylink_mac_link_down(ds, port,
> >                                         MLO_AN_FIXED, PHY_INTERFACE_MODE_NA);
> >                         return dsa_port_phylink_register(dp);
> > 
> > which forces the link down, and for some reason the link never comes
> > back up.
> >
> > One of the issues here is of_phy_is_fixed_link() - it is dangerous.
> > The function name leads you astray - it suggests that if it returns
> > true, then you have a fixed link, but it also returns true of you
> > have managed!="auto" in DT, so it's actually fixed-or-inband-link.
> > 
> > Andrew, any thoughts?
> 
> 
> Hi Russell
> 
> I think that is my change, if i remember correctly. Something to do
> with phylink assuming all interfaces are down to begin with. But DSA
> and CPU links were defaulting to up. When phylink later finds the
> fixed-link it then configures the interface up again, and because the
> interface is up, nothing actually happens, or it ends up in the wrong
> mode. So i think my intention was, if there is a fixed link in DT,
> down the interface before registering it with phylink, so its
> assumptions are true, and it will later be correctly configured up.
> 
> So in this case, do you think we are falling into the trap of
> managed!="auto" ?

Yes, it looks that way to me.  The DT description for the port is:

                        port@5 {
                                reg = <5>;
                                label = "cpu";
                                ethernet = <&cp1_eth2>;
                                phy-mode = "2500base-x";
                                managed = "in-band-status";
                        };

So, of_phy_is_fixed_link() will return true, but as far as phylink is
concerned, it's in in-band status mode rather than fixed-link mode.
Hmm.

Digging out the serdes PHY status on my GT8k (C45 address 21, PHYXS):

 2000  1140 0145 0141 0c00 00a0 0000 0004 2001
 2008  0000 0000 0000 0000 0000 0000 0000 8000
...
 a000  2000 0600 0000 a420 5100 2000 0000 0000

Remembering that it's a C22 register layout for this PHY starting at
0x2000, with the Marvell status register at 0xa003.

BMCR = 0x1140 = BMCR_ANENABLE | BMCR_FULLDPLX | BMCR_SPEED1000
BMSR = 0x0145 = BMSR_ESTATEN | reserved_bit(6) | BMSR_LSTATUS | BMSR_ERCAP
Status = 0xa420 = MV88E6390_SGMII_PHY_STATUS_SPEED_1000 |
		  MV88E6390_SGMII_PHY_STATUS_DUPLEX_FULL |
		  MV88E6390_SGMII_PHY_STATUS_LINK |
		  bit(5)

Note that MV88E6390_SGMII_PHY_STATUS_SPD_DPL_VALID is missing, so the
results of the speed, duplex and pause are not valid.  The only reason
the link is up is because we're forcing it up.

The other end of the link is not allowing the BASE-X configuration to
complete, which is not that surprising when you notice it is:

&cp1_eth2 {
        status = "okay";
        phy-mode = "2500base-x";
        phys = <&cp1_comphy5 2>;
        fixed-link {
                speed = <2500>;
                full-duplex;
        };
};

in fixed-link mode rather than in-band mode.

So, each end of the link has been configured differently in DT.  One
end has been told to use in-band AN, whereas the other end has been
told not to, which means when we start interpreting in-band correctly
in DSA, this dis-similar setup breaks.

Both ends really need to agree, and I'd suggest cp1_eth2 needs to drop
the fixed-link stanza and instead use ``managed = "in-band";'' to be
in agreement with the configuration at the switch.

Martin, can you modify
arch/arm64/boot/dts/marvell/armada-8040-clearfog-gt-8k.dts to test
that please?

Thanks.

-- 
RMK's Patch system: https://www.armlinux.org.uk/developer/patches/
FTTP is here! 40Mbps down 10Mbps up. Decent connectivity at last!

^ permalink raw reply	[flat|nested] 17+ messages in thread

* Re: bug: net: dsa: mv88e6xxx: unable to tx or rx with Clearfog GT 8K (with git bisect)
  2020-07-17 21:26                   ` Russell King - ARM Linux admin
@ 2020-07-18  2:37                     ` Martin Rowe
  2020-07-18  8:50                       ` Russell King - ARM Linux admin
  0 siblings, 1 reply; 17+ messages in thread
From: Martin Rowe @ 2020-07-18  2:37 UTC (permalink / raw)
  To: Russell King - ARM Linux admin; +Cc: Andrew Lunn, netdev, davem, vivien.didelot

On Fri, 17 Jul 2020 at 21:26, Russell King - ARM Linux admin
<linux@armlinux.org.uk> wrote:
> Both ends really need to agree, and I'd suggest cp1_eth2 needs to drop
> the fixed-link stanza and instead use ``managed = "in-band";'' to be
> in agreement with the configuration at the switch.
>
> Martin, can you modify
> arch/arm64/boot/dts/marvell/armada-8040-clearfog-gt-8k.dts to test
> that please?

eth2 now doesn't come up
$ ip link set eth2 up
RTNETLINK answers: No such device
$ dmesg
...
mvpp2 f4000000.ethernet eth2: could not attach PHY (-19)
...

A working dmesg looks like:
$ dmesg |grep f4000000
mvpp2 f4000000.ethernet: using 8 per-cpu buffers
mvpp2 f4000000.ethernet eth1: Using firmware node mac address d0:63:b4:01:00:00
mvpp2 f4000000.ethernet eth2: Using firmware node mac address d0:63:b4:01:00:02
mvpp2 f4000000.ethernet eth2: configuring for fixed/2500base-x link mode
mvpp2 f4000000.ethernet eth2: Link is Up - 2.5Gbps/Full - flow control off
mvpp2 f4000000.ethernet eth1: PHY [f412a200.mdio-mii:00] driver
[Marvell 88E1510] (irq=POLL)
mvpp2 f4000000.ethernet eth1: configuring for phy/sgmii link mode
mv88e6085 f412a200.mdio-mii:04 lan2 (uninitialized): PHY
[!cp1!config-space@f4000000!mdio@12a200!switch0@4!mdio:11] driver
[Marvell 88E6390] (irq=72)
mv88e6085 f412a200.mdio-mii:04 lan1 (uninitialized): PHY
[!cp1!config-space@f4000000!mdio@12a200!switch0@4!mdio:12] driver
[Marvell 88E6390] (irq=73)
mv88e6085 f412a200.mdio-mii:04 lan4 (uninitialized): PHY
[!cp1!config-space@f4000000!mdio@12a200!switch0@4!mdio:13] driver
[Marvell 88E6390] (irq=74)
mv88e6085 f412a200.mdio-mii:04 lan3 (uninitialized): PHY
[!cp1!config-space@f4000000!mdio@12a200!switch0@4!mdio:14] driver
[Marvell 88E6390] (irq=75)
mvpp2 f4000000.ethernet: all ports have a low MTU, switching to per-cpu buffers
mvpp2 f4000000.ethernet eth2: Link is Down
mvpp2 f4000000.ethernet: using 8 per-cpu buffers
mvpp2 f4000000.ethernet eth1: PHY [f412a200.mdio-mii:00] driver
[Marvell 88E1510] (irq=POLL)
mvpp2 f4000000.ethernet eth1: configuring for phy/sgmii link mode
mvpp2 f4000000.ethernet eth2: configuring for fixed/2500base-x link mode
mvpp2 f4000000.ethernet eth2: Link is Up - 2.5Gbps/Full - flow control off
mvpp2 f4000000.ethernet eth2: Link is Down
mvpp2 f4000000.ethernet eth2: configuring for fixed/2500base-x link mode
mvpp2 f4000000.ethernet eth2: Link is Up - 2.5Gbps/Full - flow control off
mvpp2 f4000000.ethernet eth1: Link is Up - 1Gbps/Full - flow control rx/tx

With the DTS patch it looks like:
$ dmesg |grep f4000000
mvpp2 f4000000.ethernet: using 8 per-cpu buffers
mvpp2 f4000000.ethernet eth1: Using firmware node mac address d0:63:b4:01:00:00
mvpp2 f4000000.ethernet eth2: Using firmware node mac address d0:63:b4:01:00:02
mvpp2 f4000000.ethernet eth2: could not attach PHY (-19)
mvpp2 f4000000.ethernet eth1: PHY [f412a200.mdio-mii:00] driver
[Marvell 88E1510] (irq=POLL)
mvpp2 f4000000.ethernet eth1: configuring for phy/sgmii link mode
mv88e6085 f412a200.mdio-mii:04 lan2 (uninitialized): PHY
[!cp1!config-space@f4000000!mdio@12a200!switch0@4!mdio:11] driver
[Marvell 88E6390] (irq=72)
mv88e6085 f412a200.mdio-mii:04 lan1 (uninitialized): PHY
[!cp1!config-space@f4000000!mdio@12a200!switch0@4!mdio:12] driver
[Marvell 88E6390] (irq=73)
mv88e6085 f412a200.mdio-mii:04 lan4 (uninitialized): PHY
[!cp1!config-space@f4000000!mdio@12a200!switch0@4!mdio:13] driver
[Marvell 88E6390] (irq=74)
mv88e6085 f412a200.mdio-mii:04 lan3 (uninitialized): PHY
[!cp1!config-space@f4000000!mdio@12a200!switch0@4!mdio:14] driver
[Marvell 88E6390] (irq=75)
mvpp2 f4000000.ethernet: all ports have a low MTU, switching to per-cpu buffers
mvpp2 f4000000.ethernet: using 8 per-cpu buffers
mvpp2 f4000000.ethernet eth1: PHY [f412a200.mdio-mii:00] driver
[Marvell 88E1510] (irq=POLL)
mvpp2 f4000000.ethernet eth1: configuring for phy/sgmii link mode
mvpp2 f4000000.ethernet eth1: Link is Up - 1Gbps/Full - flow control rx/tx

Output from regs just in case it helps:
$ cat /sys/kernel/debug/mv88e6xxx.0/regs
    GLOBAL GLOBAL2 SERDES     0    1    2    3    4    5
 0:  c801       0    ffff  9e07 1e4f 100f 100f 1e4f 170b
 1:     0    803e    ffff     3    3    3    3    3 201f
 2:     0       0    ffff  ff00    0    0    0    0    0
 3:     0       0    ffff  3400 3400 3400 3400 3400 3400
 4:  40a8     258    ffff    7c  43c  43c  43c  43c 373f
 5:  1000     4f0    ffff     0    0    0    0    0    0
 6:     0    1f0f    ffff    7e   7c   7a   76   6e   5f
 7:     0    703f    ffff     1    0    0    0    0    0
 8:     0    7800    ffff  2080 2080 2080 2080 2080 2080
 9:     0    1500    ffff     1    1    1    1    1    1
 a:   509       0    ffff  8000    0    0    0    0    0
 b:  3000    31ff    ffff     1    2    4    8   10    0
 c:   3f7       0    ffff     0    0    0    0    0    0
 d:  ffff     555    ffff     0    0    0    0    0    0
 e:  ffff       1    ffff     0    0    0    0    0    0
 f:  ffff     f00    ffff  9100 9100 9100 9100 9100 dada
10:     0       0    ffff     0    0    0    0    0    0
11:     0       0    ffff     0    0    0    0    0    0
12:  5555       0    ffff     0    0    0    0    0    0
13:  5555     303    ffff     0    0    0    0    0    0
14:  aaaa       0    ffff     0    0    0    0    0    0
15:  aaaa       0    ffff     0    0    0    0    0    0
16:  ffff       0       0     0   33   33   33   33    0
17:  ffff       0    ffff     0    0    0    0    0    0
18:  fa41    15f6    ffff  3210 3210 3210 3210 3210 3210
19:     0       0    ffff  7654 7654 7654 7654 7654 7654
1a:   3ff       0    ffff     0    0    0    0 1ea0 a100
1b:   200    110f    ffff  8000 8000 8000 8000 8000 8000
1c:   7c0       0    ffff     0    0    0    0    0    0
1d:  1400       0    ffff     0    0    0    0    0    0
1e:     0       0    ffff  f000 f000 f000 f000 f000 f000
1f:     0       0    ffff     0    0    0    0    0    0

I also tried "in-band-status", which has a "working" dmesg but doesn't
tx or rx packets; so basically the same as mainline without patching
the DTS.

Just to make sure I applied the right change, here is the diff:
diff --git a/arch/arm64/boot/dts/marvell/armada-8040-clearfog-gt-8k.dts
b/arch/arm64/boot/dts/marvell/armada-8040-clearfog-gt-8k.dts
index c8243da71041..957ca7e69c1a 100644
--- a/arch/arm64/boot/dts/marvell/armada-8040-clearfog-gt-8k.dts
+++ b/arch/arm64/boot/dts/marvell/armada-8040-clearfog-gt-8k.dts
@@ -454,10 +454,7 @@ &cp1_eth2 {
        status = "okay";
        phy-mode = "2500base-x";
        phys = <&cp1_comphy5 2>;
-       fixed-link {
-               speed = <2500>;
-               full-duplex;
-       };
+       managed = "in-band";
 };

 &cp1_spi1 {

^ permalink raw reply related	[flat|nested] 17+ messages in thread

* Re: bug: net: dsa: mv88e6xxx: unable to tx or rx with Clearfog GT 8K (with git bisect)
  2020-07-18  2:37                     ` Martin Rowe
@ 2020-07-18  8:50                       ` Russell King - ARM Linux admin
  2020-07-18  9:43                         ` Martin Rowe
  0 siblings, 1 reply; 17+ messages in thread
From: Russell King - ARM Linux admin @ 2020-07-18  8:50 UTC (permalink / raw)
  To: Martin Rowe; +Cc: Andrew Lunn, netdev, davem, vivien.didelot

On Sat, Jul 18, 2020 at 02:37:41AM +0000, Martin Rowe wrote:
> On Fri, 17 Jul 2020 at 21:26, Russell King - ARM Linux admin
> <linux@armlinux.org.uk> wrote:
> > Both ends really need to agree, and I'd suggest cp1_eth2 needs to drop
> > the fixed-link stanza and instead use ``managed = "in-band";'' to be
> > in agreement with the configuration at the switch.
> >
> > Martin, can you modify
> > arch/arm64/boot/dts/marvell/armada-8040-clearfog-gt-8k.dts to test
> > that please?
> 
> eth2 now doesn't come up

Sorry, it should have been ``managed = "in-band-status";'' rather than
just "in-band".

-- 
RMK's Patch system: https://www.armlinux.org.uk/developer/patches/
FTTP is here! 40Mbps down 10Mbps up. Decent connectivity at last!

^ permalink raw reply	[flat|nested] 17+ messages in thread

* Re: bug: net: dsa: mv88e6xxx: unable to tx or rx with Clearfog GT 8K (with git bisect)
  2020-07-18  8:50                       ` Russell King - ARM Linux admin
@ 2020-07-18  9:43                         ` Martin Rowe
  2020-07-18 10:12                           ` Russell King - ARM Linux admin
  0 siblings, 1 reply; 17+ messages in thread
From: Martin Rowe @ 2020-07-18  9:43 UTC (permalink / raw)
  To: Russell King - ARM Linux admin; +Cc: Andrew Lunn, netdev, davem, vivien.didelot

On Sat, 18 Jul 2020 at 08:50, Russell King - ARM Linux admin
<linux@armlinux.org.uk> wrote:
> Sorry, it should have been ``managed = "in-band-status";'' rather than
> just "in-band".

Below are the outputs with "in-band-status". It functions the same as
not reverting the patch; interface comes up, when bridged the two
physical machines connected can ping each other, but nothing can tx or
rx from the GT 8K.

$ dmesg |grep f4000000
mvpp2 f4000000.ethernet: using 8 per-cpu buffers
mvpp2 f4000000.ethernet eth1: Using firmware node mac address d0:63:b4:01:00:00
mvpp2 f4000000.ethernet eth2: Using firmware node mac address d0:63:b4:01:00:02
mvpp2 f4000000.ethernet eth2: configuring for inband/2500base-x link mode
mvpp2 f4000000.ethernet eth1: PHY [f412a200.mdio-mii:00] driver
[Marvell 88E1510] (irq=POLL)
mvpp2 f4000000.ethernet eth1: configuring for phy/sgmii link mode
mv88e6085 f412a200.mdio-mii:04 lan2 (uninitialized): PHY
[!cp1!config-space@f4000000!mdio@12a200!switch0@4!mdio:11] driver
[Marvell 88E6390] (irq=72)
mv88e6085 f412a200.mdio-mii:04 lan1 (uninitialized): PHY
[!cp1!config-space@f4000000!mdio@12a200!switch0@4!mdio:12] driver
[Marvell 88E6390] (irq=73)
mv88e6085 f412a200.mdio-mii:04 lan4 (uninitialized): PHY
[!cp1!config-space@f4000000!mdio@12a200!switch0@4!mdio:13] driver
[Marvell 88E6390] (irq=74)
mv88e6085 f412a200.mdio-mii:04 lan3 (uninitialized): PHY
[!cp1!config-space@f4000000!mdio@12a200!switch0@4!mdio:14] driver
[Marvell 88E6390] (irq=75)
mvpp2 f4000000.ethernet: all ports have a low MTU, switching to per-cpu buffers
mvpp2 f4000000.ethernet: using 8 per-cpu buffers
mvpp2 f4000000.ethernet eth1: PHY [f412a200.mdio-mii:00] driver
[Marvell 88E1510] (irq=POLL)
mvpp2 f4000000.ethernet eth1: configuring for phy/sgmii link mode
mvpp2 f4000000.ethernet eth2: configuring for inband/2500base-x link mode
mvpp2 f4000000.ethernet eth2: configuring for inband/2500base-x link mode
mvpp2 f4000000.ethernet eth2: Link is Up - 2.5Gbps/Full - flow control rx/tx
mvpp2 f4000000.ethernet eth1: Link is Up - 1Gbps/Full - flow control rx/tx

$ cat /sys/kernel/debug/mv88e6xxx.0/regs
    GLOBAL GLOBAL2 SERDES     0    1    2    3    4    5
 0:  c801       0    ffff  9e07 9e5f 100f 100f 9e6f 170b
 1:     0    803e    ffff     3    3    3    3    3 201f
 2:     0       0    ffff  ff00    0    0    0    0    0
 3:     0       0    ffff  3400 3400 3400 3400 3400 3400
 4:  40a8     258    ffff    7c  43f  43c  43c  43f 373f
 5:  1000     4f0    ffff     0    0    0    0    0    0
 6:     0    1f0f    ffff    7e   7c   7a   76   6e   5f
 7:     0    703f    ffff     1    0    0    0    0    0
 8:     0    7800    ffff  2080 2080 2080 2080 2080 2080
 9:     0    1500    ffff     1    1    1    1    1    1
 a:   509       0    ffff  8000    0    0    0    0    0
 b:  3000    31ff    ffff     1    2    4    8   10    0
 c:   207       0    ffff     0    0    0    0    0    0
 d:  3333     529    ffff     0    0    0    0    0    0
 e:     1       6    ffff     0    0    0    0    0    0
 f:     3     f00    ffff  9100 9100 9100 9100 9100 dada
10:     0       0    ffff     0    0    0    0    0    0
11:     0       0    ffff     0    0    0    0    0    0
12:  5555       0    ffff     0    0    0    0    0    0
13:  5555     303    ffff     0    0    0    0    0    0
14:  aaaa       0    ffff     0    0    0    0    0    0
15:  aaaa       0    ffff     0    0    0    0    0    0
16:  ffff       0       0     0   33   33   33   33    0
17:  ffff       0    ffff     0    0    0    0    0    0
18:  fa41    15f6    ffff  3210 3210 3210 3210 3210 3210
19:     0       0    ffff  7654 7654 7654 7654 7654 7654
1a:   3ff       0    ffff     0    0    0    0 1ea0 a100
1b:   16b    110f    ffff  8000 8000 8000 8000 8092 8000
1c:   7c0       0    ffff     0    0    0    0    0    0
1d:  1400       0    ffff     0    0    0    0    0    0
1e:     0       0    ffff  f000 f000 f000 f000 f000 f000
1f:     0       0    ffff     0   bf    0    0   f2    0

^ permalink raw reply	[flat|nested] 17+ messages in thread

* Re: bug: net: dsa: mv88e6xxx: unable to tx or rx with Clearfog GT 8K (with git bisect)
  2020-07-18  9:43                         ` Martin Rowe
@ 2020-07-18 10:12                           ` Russell King - ARM Linux admin
  2020-07-18 11:21                             ` Martin Rowe
  0 siblings, 1 reply; 17+ messages in thread
From: Russell King - ARM Linux admin @ 2020-07-18 10:12 UTC (permalink / raw)
  To: Martin Rowe; +Cc: Andrew Lunn, netdev, davem, vivien.didelot

On Sat, Jul 18, 2020 at 09:43:47AM +0000, Martin Rowe wrote:
> On Sat, 18 Jul 2020 at 08:50, Russell King - ARM Linux admin
> <linux@armlinux.org.uk> wrote:
> > Sorry, it should have been ``managed = "in-band-status";'' rather than
> > just "in-band".
> 
> Below are the outputs with "in-band-status". It functions the same as
> not reverting the patch; interface comes up, when bridged the two
> physical machines connected can ping each other, but nothing can tx or
> rx from the GT 8K.

Okay, on top of those changes, please also add this:

diff --git a/drivers/net/dsa/mv88e6xxx/chip.c b/drivers/net/dsa/mv88e6xxx/chip.c
index 17883e8712e0..2e361bbf3b4f 100644
--- a/drivers/net/dsa/mv88e6xxx/chip.c
+++ b/drivers/net/dsa/mv88e6xxx/chip.c
@@ -676,6 +676,9 @@ static void mv88e6xxx_mac_config(struct dsa_switch *ds, int port,
 		return;
 
 	mv88e6xxx_reg_lock(chip);
+	if (mode == MLO_AN_INBAND && chip->info->ops->port_set_link)
+		chip->info->ops->port_set_link(chip, port, LINK_FORCED_DOWN);
+
 	/* FIXME: should we force the link down here - but if we do, how
 	 * do we restore the link force/unforce state? The driver layering
 	 * gets in the way.
@@ -692,6 +695,9 @@ static void mv88e6xxx_mac_config(struct dsa_switch *ds, int port,
 	if (err > 0)
 		err = 0;
 
+	if (mode == MLO_AN_INBAND && chip->info->ops->port_set_link)
+		chip->info->ops->port_set_link(chip, port, LINK_UNFORCED);
+
 err_unlock:
 	mv88e6xxx_reg_unlock(chip);
 
-- 
RMK's Patch system: https://www.armlinux.org.uk/developer/patches/
FTTP is here! 40Mbps down 10Mbps up. Decent connectivity at last!

^ permalink raw reply related	[flat|nested] 17+ messages in thread

* Re: bug: net: dsa: mv88e6xxx: unable to tx or rx with Clearfog GT 8K (with git bisect)
  2020-07-18 10:12                           ` Russell King - ARM Linux admin
@ 2020-07-18 11:21                             ` Martin Rowe
  2020-07-18 11:26                               ` Russell King - ARM Linux admin
  0 siblings, 1 reply; 17+ messages in thread
From: Martin Rowe @ 2020-07-18 11:21 UTC (permalink / raw)
  To: Russell King - ARM Linux admin; +Cc: Andrew Lunn, netdev, davem, vivien.didelot

On Sat, 18 Jul 2020 at 10:13, Russell King - ARM Linux admin
<linux@armlinux.org.uk> wrote:
> Okay, on top of those changes, please also add this:

"in-band-status" plus your chip.c patch works; I can now ping from the GT 8K.

$ dmesg |grep f4000000
mvpp2 f4000000.ethernet: using 8 per-cpu buffers
mvpp2 f4000000.ethernet eth1: Using firmware node mac address d0:63:b4:01:00:00
mvpp2 f4000000.ethernet eth2: Using firmware node mac address d0:63:b4:01:00:02
mvpp2 f4000000.ethernet eth2: configuring for inband/2500base-x link mode
mvpp2 f4000000.ethernet eth1: PHY [f412a200.mdio-mii:00] driver
[Marvell 88E1510] (irq=POLL)
mvpp2 f4000000.ethernet eth1: configuring for phy/sgmii link mode
mv88e6085 f412a200.mdio-mii:04 lan2 (uninitialized): PHY
[!cp1!config-space@f4000000!mdio@12a200!switch0@4!mdio:11] driver
[Marvell 88E6390] (irq=72)
mv88e6085 f412a200.mdio-mii:04 lan1 (uninitialized): PHY
[!cp1!config-space@f4000000!mdio@12a200!switch0@4!mdio:12] driver
[Marvell 88E6390] (irq=73)
mv88e6085 f412a200.mdio-mii:04 lan4 (uninitialized): PHY
[!cp1!config-space@f4000000!mdio@12a200!switch0@4!mdio:13] driver
[Marvell 88E6390] (irq=74)
mv88e6085 f412a200.mdio-mii:04 lan3 (uninitialized): PHY
[!cp1!config-space@f4000000!mdio@12a200!switch0@4!mdio:14] driver
[Marvell 88E6390] (irq=75)
mvpp2 f4000000.ethernet: all ports have a low MTU, switching to per-cpu buffers
mvpp2 f4000000.ethernet eth2: Link is Up - 2.5Gbps/Full - flow control rx/tx
mvpp2 f4000000.ethernet eth2: Link is Down
mvpp2 f4000000.ethernet: using 8 per-cpu buffers
mvpp2 f4000000.ethernet eth1: PHY [f412a200.mdio-mii:00] driver
[Marvell 88E1510] (irq=POLL)
mvpp2 f4000000.ethernet eth1: configuring for phy/sgmii link mode
mvpp2 f4000000.ethernet eth2: configuring for inband/2500base-x link mode
mvpp2 f4000000.ethernet eth2: configuring for inband/2500base-x link mode
mvpp2 f4000000.ethernet eth2: Link is Up - 2.5Gbps/Full - flow control rx/tx
mvpp2 f4000000.ethernet eth1: Link is Up - 1Gbps/Full - flow control rx/tx

$ cat /sys/kernel/debug/mv88e6xxx.0/regs
    GLOBAL GLOBAL2 SERDES     0    1    2    3    4    5
 0:  c801       0    ffff  9e07 9e4f 100f 100f 9e4f 9f0b
 1:     0    803e    ffff     3    3    3    3    3 200f
 2:     0       0    ffff  ff00    0    0    0    0    0
 3:     0       0    ffff  3400 3400 3400 3400 3400 3400
 4:  40a8     258    ffff    7c  43d  43c  43c  43f 373f
 5:  1000     4f0    ffff     0    0    0    0    0    0
 6:     0    1f0f    ffff    7e   7c   7a   76   6e   5f
 7:     0    703f    ffff     1    0    0    0    0    0
 8:     0    7800    ffff  2080 2080 2080 2080 2080 2080
 9:     0    1500    ffff     1    1    1    1    1    1
 a:   509       0    ffff  8000    0    0    0    0    0
 b:  3000    31ff    ffff     1    2    4    8   10    0
 c:     0       0    ffff     0    0    0    0    0    0
 d:  3333     59b    ffff     0    0    0    0    0    0
 e:  ff5b       3    ffff     0    0    0    0    0    0
 f:  6cff     f00    ffff  9100 9100 9100 9100 9100 dada
10:     0       0    ffff     0    0    0    0    0    0
11:     0       0    ffff     0    0    0    0    0    0
12:  5555       0    ffff     0    0    0    0    0    0
13:  5555     303    ffff     0    0    0    0    0    0
14:  aaaa       0    ffff     0    0    0    0    0    0
15:  aaaa       0    ffff     0    0    0    0    0    0
16:  ffff       0       0     0   33   33   33   33    0
17:  ffff       0    ffff     0    0    0    0    0    0
18:  fa41    15f6    ffff  3210 3210 3210 3210 3210 3210
19:     0       0    ffff  7654 7654 7654 7654 7654 7654
1a:   3ff       0    ffff     0    0    0    0 1ea0 a100
1b:   1fc    110f    ffff  8000 8000 8000 8000 8000 8000
1c:   7c0       0    ffff     0    0    0    0    0    0
1d:  1400       0    ffff     0    0    0    0    0    0
1e:     0       0    ffff  f000 f000 f000 f000 f000 f000
1f:     0       0    ffff     0   fe    0    0   e7   52

^ permalink raw reply	[flat|nested] 17+ messages in thread

* Re: bug: net: dsa: mv88e6xxx: unable to tx or rx with Clearfog GT 8K (with git bisect)
  2020-07-18 11:21                             ` Martin Rowe
@ 2020-07-18 11:26                               ` Russell King - ARM Linux admin
  0 siblings, 0 replies; 17+ messages in thread
From: Russell King - ARM Linux admin @ 2020-07-18 11:26 UTC (permalink / raw)
  To: Martin Rowe; +Cc: Andrew Lunn, netdev, davem, vivien.didelot

On Sat, Jul 18, 2020 at 11:21:26AM +0000, Martin Rowe wrote:
> On Sat, 18 Jul 2020 at 10:13, Russell King - ARM Linux admin
> <linux@armlinux.org.uk> wrote:
> > Okay, on top of those changes, please also add this:
> 
> "in-band-status" plus your chip.c patch works; I can now ping from the GT 8K.

Great, and your kernel messages and debug all correlates correctly.
It looks like we have two latent bugs to fix here, both of which
were uncovered by Andrew's change.

Thanks.

-- 
RMK's Patch system: https://www.armlinux.org.uk/developer/patches/
FTTP is here! 40Mbps down 10Mbps up. Decent connectivity at last!

^ permalink raw reply	[flat|nested] 17+ messages in thread

end of thread, other threads:[~2020-07-18 11:26 UTC | newest]

Thread overview: 17+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2020-07-11 13:50 bug: net: dsa: mv88e6xxx: unable to tx or rx with Clearfog GT 8K (with git bisect) Martin Rowe
2020-07-11 16:23 ` Andrew Lunn
2020-07-11 19:22   ` Russell King - ARM Linux admin
2020-07-12 13:00     ` Martin Rowe
2020-07-12 13:25       ` Russell King - ARM Linux admin
2020-07-17  5:56         ` Martin Rowe
2020-07-17  9:21           ` Russell King - ARM Linux admin
2020-07-17 12:50             ` Martin Rowe
2020-07-17 18:51               ` Russell King - ARM Linux admin
2020-07-17 19:42                 ` Andrew Lunn
2020-07-17 21:26                   ` Russell King - ARM Linux admin
2020-07-18  2:37                     ` Martin Rowe
2020-07-18  8:50                       ` Russell King - ARM Linux admin
2020-07-18  9:43                         ` Martin Rowe
2020-07-18 10:12                           ` Russell King - ARM Linux admin
2020-07-18 11:21                             ` Martin Rowe
2020-07-18 11:26                               ` Russell King - ARM Linux admin

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.