[PATCH v3 03/20] i.MX: ocotp: Add provisions for storing multiple MAC addresses

Andrey Smirnov andrew.smirnov at gmail.com
Tue Jan 10 07:08:56 PST 2017


i.MX SoC variants like Vybrid have more than one built-in Ethernet
interface and as a consequence support storing more than one MAC address
in OCOTP module. Add code to create multiple 'mac_addr<n>' parameters as
well as 'mac_addr' as an "alias" to 'mac_addr0' for backwards
compatibility.

Acked-by: Stefan Lengfeld <s.lengfeld at phytec.de>
Signed-off-by: Andrey Smirnov <andrew.smirnov at gmail.com>
---
 arch/arm/mach-imx/ocotp.c | 70 ++++++++++++++++++++++++++++++++++-------------
 1 file changed, 51 insertions(+), 19 deletions(-)

diff --git a/arch/arm/mach-imx/ocotp.c b/arch/arm/mach-imx/ocotp.c
index 7f625d8..bd5448d 100644
--- a/arch/arm/mach-imx/ocotp.c
+++ b/arch/arm/mach-imx/ocotp.c
@@ -69,12 +69,22 @@
 /* Other definitions */
 #define IMX6_OTP_DATA_ERROR_VAL		0xBADABADA
 #define DEF_RELAX			20
-#define MAC_OFFSET			(0x22 * 4)
+#define MAC_OFFSET_0			(0x22 * 4)
+#define MAC_OFFSET_1			(0x24 * 4)
+#define MAX_MAC_OFFSETS			2
 #define MAC_BYTES			8
 
 struct imx_ocotp_data {
 	int num_regs;
 	u32 (*addr_to_offset)(u32 addr);
+	u8  mac_offsets[MAX_MAC_OFFSETS];
+	u8  mac_offsets_num;
+};
+
+struct ocotp_priv_ethaddr {
+	char value[MAC_BYTES];
+	struct regmap *map;
+	u8 offset;
 };
 
 struct ocotp_priv {
@@ -84,9 +94,10 @@ struct ocotp_priv {
 	struct device_d dev;
 	int permanent_write_enable;
 	int sense_enable;
-	char ethaddr[6];
+	struct ocotp_priv_ethaddr ethaddr[MAX_MAC_OFFSETS];
 	struct regmap_config map_config;
 	const struct imx_ocotp_data *data;
+	int  mac_offset_idx;
 };
 
 static struct ocotp_priv *imx_ocotp;
@@ -408,32 +419,28 @@ static void memreverse(void *dest, const void *src, size_t n)
 
 static int imx_ocotp_get_mac(struct param_d *param, void *priv)
 {
-	struct ocotp_priv *ocotp_priv = priv;
-	char buf[8];
+	char buf[MAC_BYTES];
 	int ret;
+	struct ocotp_priv_ethaddr *ethaddr = priv;
 
-	ret = regmap_bulk_read(ocotp_priv->map, MAC_OFFSET, buf, MAC_BYTES);
+	ret = regmap_bulk_read(ethaddr->map, ethaddr->offset,
+			       buf, MAC_BYTES);
 	if (ret < 0)
 		return ret;
 
-	memreverse(ocotp_priv->ethaddr, buf, 6);
+	memreverse(ethaddr->value, buf, 6);
 	return 0;
 }
 
 static int imx_ocotp_set_mac(struct param_d *param, void *priv)
 {
-	struct ocotp_priv *ocotp_priv = priv;
-	char buf[8];
-	int ret;
+	char buf[MAC_BYTES];
+	struct ocotp_priv_ethaddr *ethaddr = priv;
 
-	memreverse(buf, ocotp_priv->ethaddr, 6);
-	buf[6] = 0; buf[7] = 0;
-
-	ret = regmap_bulk_write(ocotp_priv->map, MAC_OFFSET, buf, MAC_BYTES);
-	if (ret < 0)
-		return ret;
+	memreverse(buf, ethaddr->value, 6);
 
-	return 0;
+	return regmap_bulk_write(ethaddr->map, ethaddr->offset,
+				 buf, MAC_BYTES);
 }
 
 static struct regmap_bus imx_ocotp_regmap_bus = {
@@ -492,9 +499,28 @@ static int imx_ocotp_probe(struct device_d *dev)
 				NULL, NULL, &priv->permanent_write_enable, NULL);
 	}
 
-	if (IS_ENABLED(CONFIG_NET))
-		dev_add_param_mac(&(priv->dev), "mac_addr", imx_ocotp_set_mac,
-				imx_ocotp_get_mac, priv->ethaddr, priv);
+	if (IS_ENABLED(CONFIG_NET)) {
+		int i;
+		struct ocotp_priv_ethaddr *ethaddr;
+
+		for (i = 0; i < priv->data->mac_offsets_num; i++) {
+			ethaddr = &priv->ethaddr[i];
+			ethaddr->map = priv->map;
+			ethaddr->offset = priv->data->mac_offsets[i];
+
+			dev_add_param_mac(&priv->dev, xasprintf("mac_addr%d", i),
+					  imx_ocotp_set_mac, imx_ocotp_get_mac,
+					  ethaddr->value, ethaddr);
+		}
+
+		/*
+		 * Alias to mac_addr0 for backwards compatibility
+		 */
+		ethaddr = &priv->ethaddr[0];
+		dev_add_param_mac(&priv->dev, "mac_addr",
+				  imx_ocotp_set_mac, imx_ocotp_get_mac,
+				  ethaddr->value, ethaddr);
+	}
 
 	dev_add_param_bool(&(priv->dev), "sense_enable", NULL, NULL, &priv->sense_enable, priv);
 
@@ -533,16 +559,22 @@ static u32 vf610_addr_to_offset(u32 addr)
 static struct imx_ocotp_data imx6q_ocotp_data = {
 	.num_regs = 512,
 	.addr_to_offset = imx6q_addr_to_offset,
+	.mac_offsets_num = 1,
+	.mac_offsets = { MAC_OFFSET_0 },
 };
 
 static struct imx_ocotp_data imx6sl_ocotp_data = {
 	.num_regs = 256,
 	.addr_to_offset = imx6sl_addr_to_offset,
+	.mac_offsets_num = 1,
+	.mac_offsets = { MAC_OFFSET_0 },
 };
 
 static struct imx_ocotp_data vf610_ocotp_data = {
 	.num_regs = 512,
 	.addr_to_offset = vf610_addr_to_offset,
+	.mac_offsets_num = 2,
+	.mac_offsets = { MAC_OFFSET_0, MAC_OFFSET_1 },
 };
 
 static __maybe_unused struct of_device_id imx_ocotp_dt_ids[] = {
-- 
2.9.3




More information about the barebox mailing list