2 * Common part for MediaTek MT753x gigabit switch
4 * Copyright (C) 2018 MediaTek Inc. All Rights Reserved.
6 * Author: Weijie Gao <weijie.gao@mediatek.com>
8 * SPDX-License-Identifier: GPL-2.0+
11 #include <linux/kernel.h>
12 #include <linux/delay.h>
15 #include "mt753x_regs.h"
17 void mt753x_irq_enable(struct gsw_mt753x
*gsw
)
22 /* Record initial PHY link status */
23 for (i
= 0; i
< MT753X_NUM_PHYS
; i
++) {
24 val
= gsw
->mii_read(gsw
, i
, MII_BMSR
);
25 if (val
& BMSR_LSTATUS
)
26 gsw
->phy_link_sts
|= BIT(i
);
29 val
= BIT(MT753X_NUM_PHYS
) - 1;
31 mt753x_reg_write(gsw
, SYS_INT_EN
, val
);
34 static void display_port_link_status(struct gsw_mt753x
*gsw
, u32 port
)
39 pmsr
= mt753x_reg_read(gsw
, PMSR(port
));
41 speed_bits
= (pmsr
& MAC_SPD_STS_M
) >> MAC_SPD_STS_S
;
58 if (pmsr
& MAC_LNK_STS
) {
59 dev_info(gsw
->dev
, "Port %d Link is Up - %s/%s\n",
60 port
, speed
, (pmsr
& MAC_DPX_STS
) ? "Full" : "Half");
62 dev_info(gsw
->dev
, "Port %d Link is Down\n", port
);
66 void mt753x_irq_worker(struct work_struct
*work
)
68 struct gsw_mt753x
*gsw
;
69 u32 sts
, physts
, laststs
;
72 gsw
= container_of(work
, struct gsw_mt753x
, irq_worker
);
74 sts
= mt753x_reg_read(gsw
, SYS_INT_STS
);
76 /* Check for changed PHY link status */
77 for (i
= 0; i
< MT753X_NUM_PHYS
; i
++) {
78 if (!(sts
& PHY_LC_INT(i
)))
81 laststs
= gsw
->phy_link_sts
& BIT(i
);
82 physts
= !!(gsw
->mii_read(gsw
, i
, MII_BMSR
) & BMSR_LSTATUS
);
85 if (physts
^ laststs
) {
86 gsw
->phy_link_sts
^= BIT(i
);
87 display_port_link_status(gsw
, i
);
91 mt753x_reg_write(gsw
, SYS_INT_STS
, sts
);