lists.openwall.net   lists  /  announce  owl-users  owl-dev  john-users  john-dev  passwdqc-users  yescrypt  popa3d-users  /  oss-security  kernel-hardening  musl  sabotage  tlsify  passwords  /  crypt-dev  xvendor  /  Bugtraq  Full-Disclosure  linux-kernel  linux-netdev  linux-ext4  linux-hardening  linux-cve-announce  PHC 
Open Source and information security mailing list archives
 
Hash Suite: Windows password security audit tool. GUI, reports in PDF.
[<prev] [next>] [thread-next>] [day] [month] [year] [list]
Message-Id: <20210504051130.1207550-1-colin.foster@in-advantage.com>
Date:   Mon,  3 May 2021 22:11:26 -0700
From:   Colin Foster <colin.foster@...advantage.com>
To:     colin.foster@...advantage.com
Cc:     Rob Herring <robh+dt@...nel.org>,
        Vladimir Oltean <vladimir.oltean@....com>,
        Claudiu Manoil <claudiu.manoil@....com>,
        Alexandre Belloni <alexandre.belloni@...tlin.com>,
        UNGLinuxDriver@...rochip.com (supporter:OCELOT ETHERNET SWITCH DRIVER),
        Andrew Lunn <andrew@...n.ch>,
        Vivien Didelot <vivien.didelot@...il.com>,
        Florian Fainelli <f.fainelli@...il.com>,
        "David S. Miller" <davem@...emloft.net>,
        Jakub Kicinski <kuba@...nel.org>,
        Russell King <linux@...linux.org.uk>,
        devicetree@...r.kernel.org (open list:OPEN FIRMWARE AND FLATTENED
        DEVICE TREE BINDINGS), linux-kernel@...r.kernel.org (open list),
        netdev@...r.kernel.org (open list:OCELOT ETHERNET SWITCH DRIVER)
Subject: [RFC PATCH vN net-next 1/2] net: mscc: ocelot: add support for non-mmio regmaps

Control for external VSC75XX chips can be performed via non-mmio
interfaces, e.g. SPI. Adding the offets array (one per target) and
the offset element per port allows the ability to track this
location that would otherwise be found in the MMIO regmap resource.

Tracking this offset in the ocelot driver and allowing the
ocelot_regmap_init function to be overloaded with a device-specific
initializer. This driver could update the *offset element to handle the
value that would otherwise be mapped via resource *res->start.

Signed-off-by: Colin Foster <colin.foster@...advantage.com>
---
 drivers/net/dsa/ocelot/felix.c           |  6 ++++--
 drivers/net/dsa/ocelot/felix.h           |  2 ++
 drivers/net/dsa/ocelot/felix_vsc9959.c   |  1 +
 drivers/net/dsa/ocelot/seville_vsc9953.c |  1 +
 drivers/net/ethernet/mscc/ocelot_io.c    | 27 +++++++++++++++++-------
 include/soc/mscc/ocelot.h                |  5 ++++-
 6 files changed, 31 insertions(+), 11 deletions(-)

diff --git a/drivers/net/dsa/ocelot/felix.c b/drivers/net/dsa/ocelot/felix.c
index 628afb47b579..71aa11b209e8 100644
--- a/drivers/net/dsa/ocelot/felix.c
+++ b/drivers/net/dsa/ocelot/felix.c
@@ -1122,7 +1122,8 @@ static int felix_init_structs(struct felix *felix, int num_phys_ports)
 		res.start += felix->switch_base;
 		res.end += felix->switch_base;
 
-		target = ocelot_regmap_init(ocelot, &res);
+		target = felix->info->init_regmap(ocelot, &res,
+						  &ocelot->offsets[i]);
 		if (IS_ERR(target)) {
 			dev_err(ocelot->dev,
 				"Failed to map device memory space\n");
@@ -1159,7 +1160,8 @@ static int felix_init_structs(struct felix *felix, int num_phys_ports)
 		res.start += felix->switch_base;
 		res.end += felix->switch_base;
 
-		target = ocelot_regmap_init(ocelot, &res);
+		target = felix->info->init_regmap(ocelot, &res,
+						  &ocelot_port->offset);
 		if (IS_ERR(target)) {
 			dev_err(ocelot->dev,
 				"Failed to map memory space for port %d\n",
diff --git a/drivers/net/dsa/ocelot/felix.h b/drivers/net/dsa/ocelot/felix.h
index 4d96cad815d5..03ae576e018a 100644
--- a/drivers/net/dsa/ocelot/felix.h
+++ b/drivers/net/dsa/ocelot/felix.h
@@ -47,6 +47,8 @@ struct felix_info {
 				 enum tc_setup_type type, void *type_data);
 	void	(*port_sched_speed_set)(struct ocelot *ocelot, int port,
 					u32 speed);
+	struct regmap *(*init_regmap)(struct ocelot *ocelot,
+				      struct resource *res, u32 *offset);
 };
 
 extern const struct dsa_switch_ops felix_switch_ops;
diff --git a/drivers/net/dsa/ocelot/felix_vsc9959.c b/drivers/net/dsa/ocelot/felix_vsc9959.c
index 5ff623ee76a6..87178345116b 100644
--- a/drivers/net/dsa/ocelot/felix_vsc9959.c
+++ b/drivers/net/dsa/ocelot/felix_vsc9959.c
@@ -1362,6 +1362,7 @@ static const struct felix_info felix_info_vsc9959 = {
 	.prevalidate_phy_mode	= vsc9959_prevalidate_phy_mode,
 	.port_setup_tc		= vsc9959_port_setup_tc,
 	.port_sched_speed_set	= vsc9959_sched_speed_set,
+	.init_regmap		= ocelot_regmap_init,
 };
 
 static irqreturn_t felix_irq_handler(int irq, void *data)
diff --git a/drivers/net/dsa/ocelot/seville_vsc9953.c b/drivers/net/dsa/ocelot/seville_vsc9953.c
index 84f93a874d50..d88a9729222c 100644
--- a/drivers/net/dsa/ocelot/seville_vsc9953.c
+++ b/drivers/net/dsa/ocelot/seville_vsc9953.c
@@ -1181,6 +1181,7 @@ static const struct felix_info seville_info_vsc9953 = {
 	.mdio_bus_free		= vsc9953_mdio_bus_free,
 	.phylink_validate	= vsc9953_phylink_validate,
 	.prevalidate_phy_mode	= vsc9953_prevalidate_phy_mode,
+	.init_regmap		= ocelot_regmap_init,
 };
 
 static int seville_probe(struct platform_device *pdev)
diff --git a/drivers/net/ethernet/mscc/ocelot_io.c b/drivers/net/ethernet/mscc/ocelot_io.c
index ea4e83410fe4..8f314639faff 100644
--- a/drivers/net/ethernet/mscc/ocelot_io.c
+++ b/drivers/net/ethernet/mscc/ocelot_io.c
@@ -18,7 +18,8 @@ u32 __ocelot_read_ix(struct ocelot *ocelot, u32 reg, u32 offset)
 	WARN_ON(!target);
 
 	regmap_read(ocelot->targets[target],
-		    ocelot->map[target][reg & REG_MASK] + offset, &val);
+		    ocelot->offsets[target] +
+			    ocelot->map[target][reg & REG_MASK] + offset, &val);
 	return val;
 }
 EXPORT_SYMBOL(__ocelot_read_ix);
@@ -30,7 +31,8 @@ void __ocelot_write_ix(struct ocelot *ocelot, u32 val, u32 reg, u32 offset)
 	WARN_ON(!target);
 
 	regmap_write(ocelot->targets[target],
-		     ocelot->map[target][reg & REG_MASK] + offset, val);
+		     ocelot->offsets[target] +
+			     ocelot->map[target][reg & REG_MASK] + offset, val);
 }
 EXPORT_SYMBOL(__ocelot_write_ix);
 
@@ -42,7 +44,8 @@ void __ocelot_rmw_ix(struct ocelot *ocelot, u32 val, u32 mask, u32 reg,
 	WARN_ON(!target);
 
 	regmap_update_bits(ocelot->targets[target],
-			   ocelot->map[target][reg & REG_MASK] + offset,
+			   ocelot->offsets[target] +
+				   ocelot->map[target][reg & REG_MASK] + offset,
 			   mask, val);
 }
 EXPORT_SYMBOL(__ocelot_rmw_ix);
@@ -55,7 +58,8 @@ u32 ocelot_port_readl(struct ocelot_port *port, u32 reg)
 
 	WARN_ON(!target);
 
-	regmap_read(port->target, ocelot->map[target][reg & REG_MASK], &val);
+	regmap_read(port->target,
+		    port->offset + ocelot->map[target][reg & REG_MASK], &val);
 	return val;
 }
 EXPORT_SYMBOL(ocelot_port_readl);
@@ -67,7 +71,8 @@ void ocelot_port_writel(struct ocelot_port *port, u32 val, u32 reg)
 
 	WARN_ON(!target);
 
-	regmap_write(port->target, ocelot->map[target][reg & REG_MASK], val);
+	regmap_write(port->target,
+		     port->offset + ocelot->map[target][reg & REG_MASK], val);
 }
 EXPORT_SYMBOL(ocelot_port_writel);
 
@@ -85,7 +90,8 @@ u32 __ocelot_target_read_ix(struct ocelot *ocelot, enum ocelot_target target,
 	u32 val;
 
 	regmap_read(ocelot->targets[target],
-		    ocelot->map[target][reg] + offset, &val);
+		    ocelot->offsets[target] + ocelot->map[target][reg] + offset,
+		    &val);
 	return val;
 }
 
@@ -93,7 +99,9 @@ void __ocelot_target_write_ix(struct ocelot *ocelot, enum ocelot_target target,
 			      u32 val, u32 reg, u32 offset)
 {
 	regmap_write(ocelot->targets[target],
-		     ocelot->map[target][reg] + offset, val);
+		     ocelot->offsets[target] + ocelot->map[target][reg] +
+			     offset,
+		     val);
 }
 
 int ocelot_regfields_init(struct ocelot *ocelot,
@@ -136,10 +144,13 @@ static struct regmap_config ocelot_regmap_config = {
 	.reg_stride	= 4,
 };
 
-struct regmap *ocelot_regmap_init(struct ocelot *ocelot, struct resource *res)
+struct regmap *ocelot_regmap_init(struct ocelot *ocelot, struct resource *res,
+				  u32 *offset)
 {
 	void __iomem *regs;
 
+	*offset = 0;
+
 	regs = devm_ioremap_resource(ocelot->dev, res);
 	if (IS_ERR(regs))
 		return ERR_CAST(regs);
diff --git a/include/soc/mscc/ocelot.h b/include/soc/mscc/ocelot.h
index 425ff29d9389..ad45c1af4be9 100644
--- a/include/soc/mscc/ocelot.h
+++ b/include/soc/mscc/ocelot.h
@@ -591,6 +591,7 @@ struct ocelot_port {
 	struct ocelot			*ocelot;
 
 	struct regmap			*target;
+	u32				offset;
 
 	bool				vlan_aware;
 	/* VLAN that untagged frames are classified to, on ingress */
@@ -621,6 +622,7 @@ struct ocelot {
 	const struct ocelot_ops		*ops;
 	struct regmap			*targets[TARGET_MAX];
 	struct regmap_field		*regfields[REGFIELD_MAX];
+	u32				offsets[TARGET_MAX];
 	const u32 *const		*map;
 	const struct ocelot_stat_layout	*stats_layout;
 	unsigned int			num_stats;
@@ -780,7 +782,8 @@ static inline void ocelot_drain_cpu_queue(struct ocelot *ocelot, int grp)
 /* Hardware initialization */
 int ocelot_regfields_init(struct ocelot *ocelot,
 			  const struct reg_field *const regfields);
-struct regmap *ocelot_regmap_init(struct ocelot *ocelot, struct resource *res);
+struct regmap *ocelot_regmap_init(struct ocelot *ocelot, struct resource *res,
+				  u32 *offset);
 int ocelot_init(struct ocelot *ocelot);
 void ocelot_deinit(struct ocelot *ocelot);
 void ocelot_init_port(struct ocelot *ocelot, int port);
-- 
2.25.1

Powered by blists - more mailing lists

Powered by Openwall GNU/*/Linux Powered by OpenVZ