From 42c66f057f6f35b4e3463a4ba37c7460cab48964 Mon Sep 17 00:00:00 2001 From: Michael Walle Date: Fri, 20 Dec 2019 14:16:48 +0100 Subject: drivers: net: fsl_enetc: add write_hwaddr() for LS1028A The LS1028A SoC is special in the handling of the MAC addresses. We need to write to the IERB version of the PSIPMAR0/1 register. This value will be sampled into the corresponding port PSIPMAR0/1 register if the PCI memory access is enabled. Signed-off-by: Michael Walle Signed-off-by: Alex Marginean Reviewed-by: Priyanka Jain --- drivers/net/fsl_enetc.c | 38 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 38 insertions(+) (limited to 'drivers/net/fsl_enetc.c') diff --git a/drivers/net/fsl_enetc.c b/drivers/net/fsl_enetc.c index 7c0ed9f606..2ffab1bb14 100644 --- a/drivers/net/fsl_enetc.c +++ b/drivers/net/fsl_enetc.c @@ -330,12 +330,50 @@ static int enetc_remove(struct udevice *dev) return 0; } +/* + * LS1028A is the only part with IERB at this time and there are plans to + * change its structure, keep this LS1028A specific for now. + */ +#define LS1028A_IERB_BASE 0x1f0800000ULL +#define LS1028A_IERB_PSIPMAR0(pf, vf) (LS1028A_IERB_BASE + 0x8000 \ + + (pf) * 0x100 + (vf) * 8) +#define LS1028A_IERB_PSIPMAR1(pf, vf) (LS1028A_IERB_PSIPMAR0(pf, vf) + 4) + +static int enetc_ls1028a_write_hwaddr(struct udevice *dev) +{ + struct pci_child_platdata *ppdata = dev_get_parent_platdata(dev); + const int devfn_to_pf[] = {0, 1, 2, -1, -1, -1, 3}; + struct eth_pdata *plat = dev_get_platdata(dev); + int devfn = PCI_FUNC(ppdata->devfn); + u8 *addr = plat->enetaddr; + u32 lower, upper; + int pf; + + if (devfn >= ARRAY_SIZE(devfn_to_pf)) + return 0; + + pf = devfn_to_pf[devfn]; + if (pf < 0) + return 0; + + lower = *(const u16 *)(addr + 4); + upper = *(const u32 *)addr; + + out_le32(LS1028A_IERB_PSIPMAR0(pf, 0), upper); + out_le32(LS1028A_IERB_PSIPMAR1(pf, 0), lower); + + return 0; +} + static int enetc_write_hwaddr(struct udevice *dev) { struct eth_pdata *plat = dev_get_platdata(dev); struct enetc_priv *priv = dev_get_priv(dev); u8 *addr = plat->enetaddr; + if (IS_ENABLED(CONFIG_ARCH_LS1028A)) + return enetc_ls1028a_write_hwaddr(dev); + u16 lower = *(const u16 *)(addr + 4); u32 upper = *(const u32 *)addr; -- cgit v1.2.3