mirror of
https://github.com/kernelkit/infix.git
synced 2026-07-22 01:13:00 +02:00
211 lines
7.7 KiB
Diff
211 lines
7.7 KiB
Diff
From dcaafda96688a910419945920eb73487a3569c97 Mon Sep 17 00:00:00 2001
|
|
From: Tobias Waldekranz <tobias@waldekranz.com>
|
|
Date: Wed, 27 Mar 2024 15:52:43 +0100
|
|
Subject: [PATCH 16/50] net: dsa: mv88e6xxx: Improve indirect register access
|
|
perf on 6393
|
|
|
|
When operating in multi-chip mode, the 6393 family maps a subset of
|
|
commonly used global registers to the outermost address space (in
|
|
which only the SMI command and data registers were available in
|
|
previous families).
|
|
|
|
Therefore, add a new set of SMI operations which remaps accesses to
|
|
such registers to the corresponding directly addressable register. All
|
|
other accesses use the regular indirect interface.
|
|
---
|
|
drivers/net/dsa/mv88e6xxx/chip.c | 7 +++
|
|
drivers/net/dsa/mv88e6xxx/global1.h | 3 ++
|
|
drivers/net/dsa/mv88e6xxx/global2.h | 3 ++
|
|
drivers/net/dsa/mv88e6xxx/smi.c | 76 +++++++++++++++++++++++++++++
|
|
drivers/net/dsa/mv88e6xxx/smi.h | 30 ++++++++++++
|
|
5 files changed, 119 insertions(+)
|
|
|
|
diff --git a/drivers/net/dsa/mv88e6xxx/chip.c b/drivers/net/dsa/mv88e6xxx/chip.c
|
|
index 22f4fe642578..c51588e74aed 100644
|
|
--- a/drivers/net/dsa/mv88e6xxx/chip.c
|
|
+++ b/drivers/net/dsa/mv88e6xxx/chip.c
|
|
@@ -6543,6 +6543,13 @@ static int mv88e6xxx_detect(struct mv88e6xxx_chip *chip)
|
|
/* Update the compatible info with the probed one */
|
|
chip->info = info;
|
|
|
|
+ /* Now that we know the exact chip in use, we might be able to
|
|
+ * make use of more efficient SMI operations
|
|
+ */
|
|
+ err = mv88e6xxx_smi_init(chip, chip->bus, chip->sw_addr);
|
|
+ if (err)
|
|
+ return err;
|
|
+
|
|
dev_info(chip->dev, "switch 0x%x detected: %s, revision %u\n",
|
|
chip->info->prod_num, chip->info->name, rev);
|
|
|
|
diff --git a/drivers/net/dsa/mv88e6xxx/global1.h b/drivers/net/dsa/mv88e6xxx/global1.h
|
|
index 3dbb7a1b8fe1..5ea956aadecc 100644
|
|
--- a/drivers/net/dsa/mv88e6xxx/global1.h
|
|
+++ b/drivers/net/dsa/mv88e6xxx/global1.h
|
|
@@ -218,6 +218,9 @@
|
|
#define MV88E6390_G1_MONITOR_MGMT_CTL_PTR_CPU_DEST_MGMTPRI 0x00e0
|
|
#define MV88E6390_G1_MONITOR_MGMT_CTL_DATA_MASK 0x00ff
|
|
|
|
+/* Offset 0x1B: Free Queue Size Register */
|
|
+#define MV88E6XXX_G1_FREE_Q_SIZE 0x1b
|
|
+
|
|
/* Offset 0x1C: Global Control 2 */
|
|
#define MV88E6XXX_G1_CTL2 0x1c
|
|
#define MV88E6185_G1_CTL2_CASCADE_PORT_MASK 0xf000
|
|
diff --git a/drivers/net/dsa/mv88e6xxx/global2.h b/drivers/net/dsa/mv88e6xxx/global2.h
|
|
index 82f9b410de0b..3663645621c9 100644
|
|
--- a/drivers/net/dsa/mv88e6xxx/global2.h
|
|
+++ b/drivers/net/dsa/mv88e6xxx/global2.h
|
|
@@ -143,6 +143,9 @@
|
|
#define MV88E6XXX_G2_PRIO_OVERRIDE_QFPRIEN 0x0008
|
|
#define MV88E6XXX_G2_PRIO_OVERRIDE_DATA_MASK 0x0007
|
|
|
|
+/* Offset 0x13: IMP Communication/Debug Register */
|
|
+#define MV88E6390_G2_IMP_COMM 0x13
|
|
+
|
|
/* Offset 0x14: EEPROM Command */
|
|
#define MV88E6XXX_G2_EEPROM_CMD 0x14
|
|
#define MV88E6XXX_G2_EEPROM_CMD_BUSY 0x8000
|
|
diff --git a/drivers/net/dsa/mv88e6xxx/smi.c b/drivers/net/dsa/mv88e6xxx/smi.c
|
|
index a990271b7482..f54bb0e79030 100644
|
|
--- a/drivers/net/dsa/mv88e6xxx/smi.c
|
|
+++ b/drivers/net/dsa/mv88e6xxx/smi.c
|
|
@@ -8,6 +8,8 @@
|
|
*/
|
|
|
|
#include "chip.h"
|
|
+#include "global1.h"
|
|
+#include "global2.h"
|
|
#include "smi.h"
|
|
|
|
/* The switch ADDR[4:1] configuration pins define the chip SMI device address
|
|
@@ -168,6 +170,78 @@ static const struct mv88e6xxx_bus_ops mv88e6xxx_smi_indirect_ops = {
|
|
.init = mv88e6xxx_smi_indirect_init,
|
|
};
|
|
|
|
+static u8 mv88e6393_smi_indirect_remap(int dev, int reg)
|
|
+{
|
|
+ static const u8 g1_remap[32] = {
|
|
+ [MV88E6352_G1_VTU_FID] = MV88E6393_SMI_G1_VTU_FID,
|
|
+ [MV88E6352_G1_VTU_SID] = MV88E6393_SMI_G1_VTU_SID,
|
|
+ [MV88E6XXX_G1_STS] = MV88E6393_SMI_G1_STS,
|
|
+ [MV88E6XXX_G1_VTU_OP] = MV88E6393_SMI_G1_VTU_OP,
|
|
+ [MV88E6XXX_G1_VTU_VID] = MV88E6393_SMI_G1_VTU_VID,
|
|
+ [MV88E6XXX_G1_VTU_DATA1] = MV88E6393_SMI_G1_VTU_DATA1,
|
|
+ [MV88E6XXX_G1_VTU_DATA2] = MV88E6393_SMI_G1_VTU_DATA2,
|
|
+ [MV88E6352_G1_ATU_FID] = MV88E6393_SMI_G1_ATU_FID,
|
|
+ [MV88E6XXX_G1_ATU_CTL] = MV88E6393_SMI_G1_ATU_CTL,
|
|
+ [MV88E6XXX_G1_ATU_OP] = MV88E6393_SMI_G1_ATU_OP,
|
|
+ [MV88E6XXX_G1_ATU_DATA] = MV88E6393_SMI_G1_ATU_DATA,
|
|
+ [MV88E6XXX_G1_ATU_MAC01] = MV88E6393_SMI_G1_ATU_MAC01,
|
|
+ [MV88E6XXX_G1_ATU_MAC23] = MV88E6393_SMI_G1_ATU_MAC23,
|
|
+ [MV88E6XXX_G1_ATU_MAC45] = MV88E6393_SMI_G1_ATU_MAC45,
|
|
+ [MV88E6XXX_G1_FREE_Q_SIZE] = MV88E6393_SMI_G1_FREE_Q_SIZE,
|
|
+ [MV88E6XXX_G1_STATS_OP] = MV88E6393_SMI_G1_STATS_OP,
|
|
+ [MV88E6XXX_G1_STATS_COUNTER_32] = MV88E6393_SMI_G1_STATS_COUNTER_32,
|
|
+ [MV88E6XXX_G1_STATS_COUNTER_01] = MV88E6393_SMI_G1_STATS_COUNTER_01,
|
|
+ };
|
|
+
|
|
+ static const u8 g2_remap[32] = {
|
|
+ [MV88E6390_G2_IMP_COMM] = MV88E6393_SMI_G2_IMP_COMM,
|
|
+ [MV88E6352_G2_AVB_CMD] = MV88E6393_SMI_G2_AVB_CMD,
|
|
+ [MV88E6352_G2_AVB_DATA] = MV88E6393_SMI_G2_AVB_DATA,
|
|
+ [MV88E6XXX_G2_SMI_PHY_CMD] = MV88E6393_SMI_G2_SMI_PHY_CMD,
|
|
+ [MV88E6XXX_G2_SMI_PHY_DATA] = MV88E6393_SMI_G2_SMI_PHY_DATA,
|
|
+ [MV88E6393X_G2_MACLINK_INT_SRC] = MV88E6393_SMI_G2_MACLINK_INT_SRC,
|
|
+ };
|
|
+
|
|
+ switch (dev) {
|
|
+ case 0x1b:
|
|
+ return g1_remap[reg];
|
|
+ case 0x1c:
|
|
+ return g2_remap[reg];
|
|
+ }
|
|
+
|
|
+ return 0;
|
|
+}
|
|
+
|
|
+static int mv88e6393_smi_indirect_read(struct mv88e6xxx_chip *chip,
|
|
+ int dev, int reg, u16 *data)
|
|
+{
|
|
+ u8 remap = mv88e6393_smi_indirect_remap(dev, reg);
|
|
+
|
|
+ if (remap)
|
|
+ return mv88e6xxx_smi_direct_read(chip, chip->sw_addr,
|
|
+ remap, data);
|
|
+
|
|
+ return mv88e6xxx_smi_indirect_read(chip, dev, reg, data);
|
|
+}
|
|
+
|
|
+static int mv88e6393_smi_indirect_write(struct mv88e6xxx_chip *chip,
|
|
+ int dev, int reg, u16 data)
|
|
+{
|
|
+ u8 remap = mv88e6393_smi_indirect_remap(dev, reg);
|
|
+
|
|
+ if (remap)
|
|
+ return mv88e6xxx_smi_direct_write(chip, chip->sw_addr,
|
|
+ remap, data);
|
|
+
|
|
+ return mv88e6xxx_smi_indirect_write(chip, dev, reg, data);
|
|
+}
|
|
+
|
|
+static const struct mv88e6xxx_bus_ops mv88e6393_smi_indirect_ops = {
|
|
+ .read = mv88e6393_smi_indirect_read,
|
|
+ .write = mv88e6393_smi_indirect_write,
|
|
+ .init = mv88e6xxx_smi_indirect_init,
|
|
+};
|
|
+
|
|
int mv88e6xxx_smi_init(struct mv88e6xxx_chip *chip,
|
|
struct mii_bus *bus, int sw_addr)
|
|
{
|
|
@@ -175,6 +249,8 @@ int mv88e6xxx_smi_init(struct mv88e6xxx_chip *chip,
|
|
chip->smi_ops = &mv88e6xxx_smi_dual_direct_ops;
|
|
else if (sw_addr == 0)
|
|
chip->smi_ops = &mv88e6xxx_smi_direct_ops;
|
|
+ else if (chip->info->family == MV88E6XXX_FAMILY_6393)
|
|
+ chip->smi_ops = &mv88e6393_smi_indirect_ops;
|
|
else if (chip->info->multi_chip)
|
|
chip->smi_ops = &mv88e6xxx_smi_indirect_ops;
|
|
else
|
|
diff --git a/drivers/net/dsa/mv88e6xxx/smi.h b/drivers/net/dsa/mv88e6xxx/smi.h
|
|
index c6c71d5757f5..788cf68b7b33 100644
|
|
--- a/drivers/net/dsa/mv88e6xxx/smi.h
|
|
+++ b/drivers/net/dsa/mv88e6xxx/smi.h
|
|
@@ -31,6 +31,36 @@
|
|
/* Offset 0x01: SMI Data Register */
|
|
#define MV88E6XXX_SMI_DATA 0x01
|
|
|
|
+/* When using the 6393 in indirect addressing mode, a subset of the
|
|
+ * most commonly used registers are directly mapped out to the chip's
|
|
+ * top address space, allowing them to be directly accessed.
|
|
+ */
|
|
+#define MV88E6393_SMI_G1_VTU_FID 0x02
|
|
+#define MV88E6393_SMI_G1_VTU_SID 0x03
|
|
+#define MV88E6393_SMI_G1_STS 0x04
|
|
+#define MV88E6393_SMI_G1_VTU_OP 0x05
|
|
+#define MV88E6393_SMI_G1_VTU_VID 0x06
|
|
+#define MV88E6393_SMI_G1_VTU_DATA1 0x07
|
|
+#define MV88E6393_SMI_G1_VTU_DATA2 0x08
|
|
+#define MV88E6393_SMI_G1_ATU_FID 0x09
|
|
+#define MV88E6393_SMI_G1_ATU_CTL 0x0a
|
|
+#define MV88E6393_SMI_G1_ATU_OP 0x0b
|
|
+#define MV88E6393_SMI_G1_ATU_DATA 0x0c
|
|
+#define MV88E6393_SMI_G1_ATU_MAC01 0x0d
|
|
+#define MV88E6393_SMI_G1_ATU_MAC23 0x0e
|
|
+#define MV88E6393_SMI_G1_ATU_MAC45 0x0f
|
|
+#define MV88E6393_SMI_G2_IMP_COMM 0x13
|
|
+#define MV88E6393_SMI_G2_AVB_CMD 0x16
|
|
+#define MV88E6393_SMI_G2_AVB_DATA 0x17
|
|
+#define MV88E6393_SMI_G2_SMI_PHY_CMD 0x18
|
|
+#define MV88E6393_SMI_G2_SMI_PHY_DATA 0x19
|
|
+#define MV88E6393_SMI_G2_MACLINK_INT_SRC 0x1a
|
|
+#define MV88E6393_SMI_G1_FREE_Q_SIZE 0x1b
|
|
+#define MV88E6393_SMI_G1_STATS_OP 0x1d
|
|
+#define MV88E6393_SMI_G1_STATS_COUNTER_32 0x1e
|
|
+#define MV88E6393_SMI_G1_STATS_COUNTER_01 0x1f
|
|
+
|
|
+
|
|
int mv88e6xxx_smi_init(struct mv88e6xxx_chip *chip,
|
|
struct mii_bus *bus, int sw_addr);
|
|
|