mirror of
https://github.com/AsahiLinux/u-boot
synced 2024-11-11 15:37:23 +00:00
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 <michael@walle.cc> Signed-off-by: Alex Marginean <alexandru.marginean@nxp.com> Reviewed-by: Priyanka Jain <priyanka.jain@nxp.com>
This commit is contained in:
parent
ee5c70b8f7
commit
42c66f057f
1 changed files with 38 additions and 0 deletions
|
@ -330,12 +330,50 @@ static int enetc_remove(struct udevice *dev)
|
||||||
return 0;
|
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)
|
static int enetc_write_hwaddr(struct udevice *dev)
|
||||||
{
|
{
|
||||||
struct eth_pdata *plat = dev_get_platdata(dev);
|
struct eth_pdata *plat = dev_get_platdata(dev);
|
||||||
struct enetc_priv *priv = dev_get_priv(dev);
|
struct enetc_priv *priv = dev_get_priv(dev);
|
||||||
u8 *addr = plat->enetaddr;
|
u8 *addr = plat->enetaddr;
|
||||||
|
|
||||||
|
if (IS_ENABLED(CONFIG_ARCH_LS1028A))
|
||||||
|
return enetc_ls1028a_write_hwaddr(dev);
|
||||||
|
|
||||||
u16 lower = *(const u16 *)(addr + 4);
|
u16 lower = *(const u16 *)(addr + 4);
|
||||||
u32 upper = *(const u32 *)addr;
|
u32 upper = *(const u32 *)addr;
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue