Source
x
static int armdfec_send(struct eth_device *dev, void *dataptr, int datasize)
// SPDX-License-Identifier: GPL-2.0+
/*
* (C) Copyright 2011
* eInfochips Ltd. <www.einfochips.com>
* Written-by: Ajay Bhargav <contact@8051projects.net>
*
* (C) Copyright 2010
* Marvell Semiconductor <www.marvell.com>
* Contributor: Mahavir Jain <mjain@marvell.com>
*/
/* Magic number to read/write PHY address */
static int eth_dump_regs(struct eth_device *dev)
{
struct armdfec_device *darmdfec = to_darmdfec(dev);
struct armdfec_reg *regs = darmdfec->regs;
unsigned int i = 0;
printf("\noffset: phy_adr, value: 0x%x\n", readl(®s->phyadr));
printf("offset: smi, value: 0x%x\n", readl(®s->smi));
for (i = 0x400; i <= 0x4e4; i += 4)
printf("offset: 0x%x, value: 0x%x\n",
i, readl(ARMD1_FEC_BASE + i));
return 0;
}
static int armdfec_phy_timeout(u32 *reg, u32 flag, int cond)
{
u32 timeout = PHY_WAIT_ITERATIONS;
u32 reg_val;
while (--timeout) {
reg_val = readl(reg);
if (cond && (reg_val & flag))
break;
else if (!cond && !(reg_val & flag))
break;
udelay(PHY_WAIT_MICRO_SECONDS);
}
return !timeout;
}
static int smi_reg_read(struct mii_dev *bus, int phy_addr, int devad,
int phy_reg)
{
u16 value = 0;
struct eth_device *dev = eth_get_dev_by_name(bus->name);
struct armdfec_device *darmdfec = to_darmdfec(dev);
struct armdfec_reg *regs = darmdfec->regs;
u32 val;
if (phy_addr == PHY_ADR_REQ && phy_reg == PHY_ADR_REQ) {
val = readl(®s->phyadr);
value = val & 0x1f;
return value;
}
/* check parameters */
if (phy_addr > PHY_MASK) {
printf("ARMD100 FEC: (%s) Invalid phy address: 0x%X\n",
__func__, phy_addr);
return -EINVAL;
}
if (phy_reg > PHY_MASK) {
printf("ARMD100 FEC: (%s) Invalid register offset: 0x%X\n",
__func__, phy_reg);
return -EINVAL;
}
/* wait for the SMI register to become available */
if (armdfec_phy_timeout(®s->smi, SMI_BUSY, false)) {
printf("ARMD100 FEC: (%s) PHY busy timeout\n", __func__);
return -1;
}
writel((phy_addr << 16) | (phy_reg << 21) | SMI_OP_R, ®s->smi);