i.MX: ocotp: Add provisions for storing multiple MAC addresses
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@phytec.de> Signed-off-by: Andrey Smirnov <andrew.smirnov@gmail.com> Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
This commit is contained in:
parent
f36c383bcc
commit
75b6972be4
|
@ -69,12 +69,22 @@
|
||||||
/* Other definitions */
|
/* Other definitions */
|
||||||
#define IMX6_OTP_DATA_ERROR_VAL 0xBADABADA
|
#define IMX6_OTP_DATA_ERROR_VAL 0xBADABADA
|
||||||
#define DEF_RELAX 20
|
#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
|
#define MAC_BYTES 8
|
||||||
|
|
||||||
struct imx_ocotp_data {
|
struct imx_ocotp_data {
|
||||||
int num_regs;
|
int num_regs;
|
||||||
u32 (*addr_to_offset)(u32 addr);
|
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 {
|
struct ocotp_priv {
|
||||||
|
@ -84,9 +94,10 @@ struct ocotp_priv {
|
||||||
struct device_d dev;
|
struct device_d dev;
|
||||||
int permanent_write_enable;
|
int permanent_write_enable;
|
||||||
int sense_enable;
|
int sense_enable;
|
||||||
char ethaddr[6];
|
struct ocotp_priv_ethaddr ethaddr[MAX_MAC_OFFSETS];
|
||||||
struct regmap_config map_config;
|
struct regmap_config map_config;
|
||||||
const struct imx_ocotp_data *data;
|
const struct imx_ocotp_data *data;
|
||||||
|
int mac_offset_idx;
|
||||||
};
|
};
|
||||||
|
|
||||||
static struct ocotp_priv *imx_ocotp;
|
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)
|
static int imx_ocotp_get_mac(struct param_d *param, void *priv)
|
||||||
{
|
{
|
||||||
struct ocotp_priv *ocotp_priv = priv;
|
char buf[MAC_BYTES];
|
||||||
char buf[8];
|
|
||||||
int ret;
|
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)
|
if (ret < 0)
|
||||||
return ret;
|
return ret;
|
||||||
|
|
||||||
memreverse(ocotp_priv->ethaddr, buf, 6);
|
memreverse(ethaddr->value, buf, 6);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int imx_ocotp_set_mac(struct param_d *param, void *priv)
|
static int imx_ocotp_set_mac(struct param_d *param, void *priv)
|
||||||
{
|
{
|
||||||
struct ocotp_priv *ocotp_priv = priv;
|
char buf[MAC_BYTES];
|
||||||
char buf[8];
|
struct ocotp_priv_ethaddr *ethaddr = priv;
|
||||||
int ret;
|
|
||||||
|
|
||||||
memreverse(buf, ocotp_priv->ethaddr, 6);
|
memreverse(buf, ethaddr->value, 6);
|
||||||
buf[6] = 0; buf[7] = 0;
|
|
||||||
|
|
||||||
ret = regmap_bulk_write(ocotp_priv->map, MAC_OFFSET, buf, MAC_BYTES);
|
return regmap_bulk_write(ethaddr->map, ethaddr->offset,
|
||||||
if (ret < 0)
|
buf, MAC_BYTES);
|
||||||
return ret;
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static struct regmap_bus imx_ocotp_regmap_bus = {
|
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);
|
NULL, NULL, &priv->permanent_write_enable, NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (IS_ENABLED(CONFIG_NET))
|
if (IS_ENABLED(CONFIG_NET)) {
|
||||||
dev_add_param_mac(&(priv->dev), "mac_addr", imx_ocotp_set_mac,
|
int i;
|
||||||
imx_ocotp_get_mac, priv->ethaddr, priv);
|
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);
|
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 = {
|
static struct imx_ocotp_data imx6q_ocotp_data = {
|
||||||
.num_regs = 512,
|
.num_regs = 512,
|
||||||
.addr_to_offset = imx6q_addr_to_offset,
|
.addr_to_offset = imx6q_addr_to_offset,
|
||||||
|
.mac_offsets_num = 1,
|
||||||
|
.mac_offsets = { MAC_OFFSET_0 },
|
||||||
};
|
};
|
||||||
|
|
||||||
static struct imx_ocotp_data imx6sl_ocotp_data = {
|
static struct imx_ocotp_data imx6sl_ocotp_data = {
|
||||||
.num_regs = 256,
|
.num_regs = 256,
|
||||||
.addr_to_offset = imx6sl_addr_to_offset,
|
.addr_to_offset = imx6sl_addr_to_offset,
|
||||||
|
.mac_offsets_num = 1,
|
||||||
|
.mac_offsets = { MAC_OFFSET_0 },
|
||||||
};
|
};
|
||||||
|
|
||||||
static struct imx_ocotp_data vf610_ocotp_data = {
|
static struct imx_ocotp_data vf610_ocotp_data = {
|
||||||
.num_regs = 512,
|
.num_regs = 512,
|
||||||
.addr_to_offset = vf610_addr_to_offset,
|
.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[] = {
|
static __maybe_unused struct of_device_id imx_ocotp_dt_ids[] = {
|
||||||
|
|
Loading…
Reference in New Issue