diff options
Diffstat (limited to 'target/linux/mediatek/files-5.10/drivers/net/phy/mtk/mt753x/mt753x_common.c')
-rw-r--r-- | target/linux/mediatek/files-5.10/drivers/net/phy/mtk/mt753x/mt753x_common.c | 90 |
1 files changed, 90 insertions, 0 deletions
diff --git a/target/linux/mediatek/files-5.10/drivers/net/phy/mtk/mt753x/mt753x_common.c b/target/linux/mediatek/files-5.10/drivers/net/phy/mtk/mt753x/mt753x_common.c new file mode 100644 index 0000000000..4015ddf125 --- /dev/null +++ b/target/linux/mediatek/files-5.10/drivers/net/phy/mtk/mt753x/mt753x_common.c @@ -0,0 +1,90 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * Copyright (c) 2018 MediaTek Inc. + * Author: Weijie Gao <weijie.gao@mediatek.com> + */ + +#include <linux/kernel.h> +#include <linux/delay.h> + +#include "mt753x.h" +#include "mt753x_regs.h" + +void mt753x_irq_enable(struct gsw_mt753x *gsw) +{ + u32 val; + int i; + + /* Record initial PHY link status */ + for (i = 0; i < MT753X_NUM_PHYS; i++) { + val = gsw->mii_read(gsw, i, MII_BMSR); + if (val & BMSR_LSTATUS) + gsw->phy_link_sts |= BIT(i); + } + + val = BIT(MT753X_NUM_PHYS) - 1; + + mt753x_reg_write(gsw, SYS_INT_EN, val); +} + +static void display_port_link_status(struct gsw_mt753x *gsw, u32 port) +{ + u32 pmsr, speed_bits; + const char *speed; + + pmsr = mt753x_reg_read(gsw, PMSR(port)); + + speed_bits = (pmsr & MAC_SPD_STS_M) >> MAC_SPD_STS_S; + + switch (speed_bits) { + case MAC_SPD_10: + speed = "10Mbps"; + break; + case MAC_SPD_100: + speed = "100Mbps"; + break; + case MAC_SPD_1000: + speed = "1Gbps"; + break; + case MAC_SPD_2500: + speed = "2.5Gbps"; + break; + } + + if (pmsr & MAC_LNK_STS) { + dev_info(gsw->dev, "Port %d Link is Up - %s/%s\n", + port, speed, (pmsr & MAC_DPX_STS) ? "Full" : "Half"); + } else { + dev_info(gsw->dev, "Port %d Link is Down\n", port); + } +} + +void mt753x_irq_worker(struct work_struct *work) +{ + struct gsw_mt753x *gsw; + u32 sts, physts, laststs; + int i; + + gsw = container_of(work, struct gsw_mt753x, irq_worker); + + sts = mt753x_reg_read(gsw, SYS_INT_STS); + + /* Check for changed PHY link status */ + for (i = 0; i < MT753X_NUM_PHYS; i++) { + if (!(sts & PHY_LC_INT(i))) + continue; + + laststs = gsw->phy_link_sts & BIT(i); + physts = !!(gsw->mii_read(gsw, i, MII_BMSR) & BMSR_LSTATUS); + physts <<= i; + + if (physts ^ laststs) { + gsw->phy_link_sts ^= BIT(i); + display_port_link_status(gsw, i); + } + } + + mt753x_reg_write(gsw, SYS_INT_STS, sts); + + enable_irq(gsw->irq); +} |