net: dsa: mv88e6xxx: update code operating on hidden registers
authorMarek Behún <marek.behun@nic.cz>
Mon, 26 Aug 2019 21:31:51 +0000 (23:31 +0200)
committerDavid S. Miller <davem@davemloft.net>
Wed, 28 Aug 2019 04:42:16 +0000 (21:42 -0700)
This patch moves the functions operating on the hidden debug registers
into it's own file, port_hidden.c. The functions prefix is renamed from
mv88e6390_hidden_ to mv88e6xxx_port_hidden_, to be consistent with the
rest of this driver. The macros are prefixed with MV88E6XXX_ prefix, and
are changed not to use the BIT() macro nor bit shifts, since the rest of
the port.h file does not use it.

We also add the support for setting the Block Address field when
operating hidden registers. Marvell's mdio examples for SERDES settings
on Topaz use Block Address 0x7 when reading/writing hidden registers,
and although the specification says that block must be set to 0xf, those
settings are reachable only with Block Address 0x7.

Signed-off-by: Marek Behún <marek.behun@nic.cz>
Reviewed-by: Andrew Lunn <andrew@lunn.ch>
Tested-by: Vivien Didelot <vivien.didelot@gmail.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
drivers/net/dsa/mv88e6xxx/Makefile
drivers/net/dsa/mv88e6xxx/chip.c
drivers/net/dsa/mv88e6xxx/port.h
drivers/net/dsa/mv88e6xxx/port_hidden.c [new file with mode: 0644]

index e85755dde90b98d503bb3ad225956d323b7ffb2a..aa645ff86f641fd137f74083425ab2a28712c0d5 100644 (file)
@@ -10,6 +10,7 @@ mv88e6xxx-$(CONFIG_NET_DSA_MV88E6XXX_GLOBAL2) += global2_scratch.o
 mv88e6xxx-$(CONFIG_NET_DSA_MV88E6XXX_PTP) += hwtstamp.o
 mv88e6xxx-objs += phy.o
 mv88e6xxx-objs += port.o
+mv88e6xxx-objs += port_hidden.o
 mv88e6xxx-$(CONFIG_NET_DSA_MV88E6XXX_PTP) += ptp.o
 mv88e6xxx-objs += serdes.o
 mv88e6xxx-objs += smi.o
index d0bf98c10b2ba71b4f864417c672a895579984e9..ec4274d711456f26984ec9ff24a0354f1c7b3068 100644 (file)
@@ -2317,60 +2317,6 @@ static int mv88e6xxx_stats_setup(struct mv88e6xxx_chip *chip)
        return mv88e6xxx_g1_stats_clear(chip);
 }
 
-/* The mv88e6390 has some hidden registers used for debug and
- * development. The errata also makes use of them.
- */
-static int mv88e6390_hidden_write(struct mv88e6xxx_chip *chip, int port,
-                                 int reg, u16 val)
-{
-       u16 ctrl;
-       int err;
-
-       err = mv88e6xxx_port_write(chip, PORT_RESERVED_1A_DATA_PORT,
-                                  PORT_RESERVED_1A, val);
-       if (err)
-               return err;
-
-       ctrl = PORT_RESERVED_1A_BUSY | PORT_RESERVED_1A_WRITE |
-              PORT_RESERVED_1A_BLOCK | port << PORT_RESERVED_1A_PORT_SHIFT |
-              reg;
-
-       return mv88e6xxx_port_write(chip, PORT_RESERVED_1A_CTRL_PORT,
-                                   PORT_RESERVED_1A, ctrl);
-}
-
-static int mv88e6390_hidden_wait(struct mv88e6xxx_chip *chip)
-{
-       int bit = __bf_shf(PORT_RESERVED_1A_BUSY);
-
-       return mv88e6xxx_wait_bit(chip, PORT_RESERVED_1A_CTRL_PORT,
-                                 PORT_RESERVED_1A, bit, 0);
-}
-
-
-static int mv88e6390_hidden_read(struct mv88e6xxx_chip *chip, int port,
-                                 int reg, u16 *val)
-{
-       u16 ctrl;
-       int err;
-
-       ctrl = PORT_RESERVED_1A_BUSY | PORT_RESERVED_1A_READ |
-              PORT_RESERVED_1A_BLOCK | port << PORT_RESERVED_1A_PORT_SHIFT |
-              reg;
-
-       err = mv88e6xxx_port_write(chip, PORT_RESERVED_1A_CTRL_PORT,
-                                  PORT_RESERVED_1A, ctrl);
-       if (err)
-               return err;
-
-       err = mv88e6390_hidden_wait(chip);
-       if (err)
-               return err;
-
-       return  mv88e6xxx_port_read(chip, PORT_RESERVED_1A_DATA_PORT,
-                                   PORT_RESERVED_1A, val);
-}
-
 /* Check if the errata has already been applied. */
 static bool mv88e6390_setup_errata_applied(struct mv88e6xxx_chip *chip)
 {
@@ -2379,7 +2325,7 @@ static bool mv88e6390_setup_errata_applied(struct mv88e6xxx_chip *chip)
        u16 val;
 
        for (port = 0; port < mv88e6xxx_num_ports(chip); port++) {
-               err = mv88e6390_hidden_read(chip, port, 0, &val);
+               err = mv88e6xxx_port_hidden_read(chip, 0xf, port, 0, &val);
                if (err) {
                        dev_err(chip->dev,
                                "Error reading hidden register: %d\n", err);
@@ -2412,7 +2358,7 @@ static int mv88e6390_setup_errata(struct mv88e6xxx_chip *chip)
        }
 
        for (port = 0; port < mv88e6xxx_num_ports(chip); port++) {
-               err = mv88e6390_hidden_write(chip, port, 0, 0x01c0);
+               err = mv88e6xxx_port_hidden_write(chip, 0xf, port, 0, 0x01c0);
                if (err)
                        return err;
        }
index 1abf5ea033e2974546c69174a29219d4e336dd8d..21d2d8f7c8f9de8dd922d920e03b56dc229c4854 100644 (file)
 #define MV88E6095_PORT_IEEE_PRIO_REMAP_4567    0x19
 
 /* Offset 0x1a: Magic undocumented errata register */
-#define PORT_RESERVED_1A                       0x1a
-#define PORT_RESERVED_1A_BUSY                  BIT(15)
-#define PORT_RESERVED_1A_WRITE                 BIT(14)
-#define PORT_RESERVED_1A_READ                  0
-#define PORT_RESERVED_1A_PORT_SHIFT            5
-#define PORT_RESERVED_1A_BLOCK                 (0xf << 10)
-#define PORT_RESERVED_1A_CTRL_PORT             4
-#define PORT_RESERVED_1A_DATA_PORT             5
+#define MV88E6XXX_PORT_RESERVED_1A             0x1a
+#define MV88E6XXX_PORT_RESERVED_1A_BUSY                0x8000
+#define MV88E6XXX_PORT_RESERVED_1A_WRITE       0x4000
+#define MV88E6XXX_PORT_RESERVED_1A_READ                0x0000
+#define MV88E6XXX_PORT_RESERVED_1A_PORT_SHIFT  5
+#define MV88E6XXX_PORT_RESERVED_1A_BLOCK_SHIFT 10
+#define MV88E6XXX_PORT_RESERVED_1A_CTRL_PORT   0x04
+#define MV88E6XXX_PORT_RESERVED_1A_DATA_PORT   0x05
 
 int mv88e6xxx_port_read(struct mv88e6xxx_chip *chip, int port, int reg,
                        u16 *val);
@@ -353,4 +353,10 @@ int mv88e6095_port_set_upstream_port(struct mv88e6xxx_chip *chip, int port,
 int mv88e6xxx_port_disable_learn_limit(struct mv88e6xxx_chip *chip, int port);
 int mv88e6xxx_port_disable_pri_override(struct mv88e6xxx_chip *chip, int port);
 
+int mv88e6xxx_port_hidden_write(struct mv88e6xxx_chip *chip, int block,
+                               int port, int reg, u16 val);
+int mv88e6xxx_port_hidden_wait(struct mv88e6xxx_chip *chip);
+int mv88e6xxx_port_hidden_read(struct mv88e6xxx_chip *chip, int block, int port,
+                              int reg, u16 *val);
+
 #endif /* _MV88E6XXX_PORT_H */
diff --git a/drivers/net/dsa/mv88e6xxx/port_hidden.c b/drivers/net/dsa/mv88e6xxx/port_hidden.c
new file mode 100644 (file)
index 0000000..b49d05f
--- /dev/null
@@ -0,0 +1,70 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+/*
+ * Marvell 88E6xxx Switch Hidden Registers support
+ *
+ * Copyright (c) 2008 Marvell Semiconductor
+ *
+ * Copyright (c) 2019 Andrew Lunn <andrew@lunn.ch>
+ */
+
+#include <linux/bitfield.h>
+
+#include "chip.h"
+#include "port.h"
+
+/* The mv88e6390 and mv88e6341 have some hidden registers used for debug and
+ * development. The errata also makes use of them.
+ */
+int mv88e6xxx_port_hidden_write(struct mv88e6xxx_chip *chip, int block,
+                               int port, int reg, u16 val)
+{
+       u16 ctrl;
+       int err;
+
+       err = mv88e6xxx_port_write(chip, MV88E6XXX_PORT_RESERVED_1A_DATA_PORT,
+                                  MV88E6XXX_PORT_RESERVED_1A, val);
+       if (err)
+               return err;
+
+       ctrl = MV88E6XXX_PORT_RESERVED_1A_BUSY |
+              MV88E6XXX_PORT_RESERVED_1A_WRITE |
+              block << MV88E6XXX_PORT_RESERVED_1A_BLOCK_SHIFT |
+              port << MV88E6XXX_PORT_RESERVED_1A_PORT_SHIFT |
+              reg;
+
+       return mv88e6xxx_port_write(chip, MV88E6XXX_PORT_RESERVED_1A_CTRL_PORT,
+                                   MV88E6XXX_PORT_RESERVED_1A, ctrl);
+}
+
+int mv88e6xxx_port_hidden_wait(struct mv88e6xxx_chip *chip)
+{
+       int bit = __bf_shf(MV88E6XXX_PORT_RESERVED_1A_BUSY);
+
+       return mv88e6xxx_wait_bit(chip, MV88E6XXX_PORT_RESERVED_1A_CTRL_PORT,
+                                 MV88E6XXX_PORT_RESERVED_1A, bit, 0);
+}
+
+int mv88e6xxx_port_hidden_read(struct mv88e6xxx_chip *chip, int block, int port,
+                              int reg, u16 *val)
+{
+       u16 ctrl;
+       int err;
+
+       ctrl = MV88E6XXX_PORT_RESERVED_1A_BUSY |
+              MV88E6XXX_PORT_RESERVED_1A_READ |
+              block << MV88E6XXX_PORT_RESERVED_1A_BLOCK_SHIFT |
+              port << MV88E6XXX_PORT_RESERVED_1A_PORT_SHIFT |
+              reg;
+
+       err = mv88e6xxx_port_write(chip, MV88E6XXX_PORT_RESERVED_1A_CTRL_PORT,
+                                  MV88E6XXX_PORT_RESERVED_1A, ctrl);
+       if (err)
+               return err;
+
+       err = mv88e6xxx_port_hidden_wait(chip);
+       if (err)
+               return err;
+
+       return mv88e6xxx_port_read(chip, MV88E6XXX_PORT_RESERVED_1A_DATA_PORT,
+                                  MV88E6XXX_PORT_RESERVED_1A, val);
+}