1 // SPDX-License-Identifier: GPL-2.0-only
3 * Copyright (c) 2018 MediaTek Inc.
4 * Author: Weijie Gao <weijie.gao@mediatek.com>
7 #include <linux/kernel.h>
8 #include <linux/delay.h>
11 #include "mt753x_regs.h"
13 void mt753x_irq_enable(struct gsw_mt753x
*gsw
)
18 /* Record initial PHY link status */
19 for (i
= 0; i
< MT753X_NUM_PHYS
; i
++) {
20 val
= gsw
->mii_read(gsw
, i
, MII_BMSR
);
21 if (val
& BMSR_LSTATUS
)
22 gsw
->phy_link_sts
|= BIT(i
);
25 val
= BIT(MT753X_NUM_PHYS
) - 1;
27 mt753x_reg_write(gsw
, SYS_INT_EN
, val
);
30 static void display_port_link_status(struct gsw_mt753x
*gsw
, u32 port
)
35 pmsr
= mt753x_reg_read(gsw
, PMSR(port
));
37 speed_bits
= (pmsr
& MAC_SPD_STS_M
) >> MAC_SPD_STS_S
;
54 if (pmsr
& MAC_LNK_STS
) {
55 dev_info(gsw
->dev
, "Port %d Link is Up - %s/%s\n",
56 port
, speed
, (pmsr
& MAC_DPX_STS
) ? "Full" : "Half");
58 dev_info(gsw
->dev
, "Port %d Link is Down\n", port
);
62 void mt753x_irq_worker(struct work_struct
*work
)
64 struct gsw_mt753x
*gsw
;
65 u32 sts
, physts
, laststs
;
68 gsw
= container_of(work
, struct gsw_mt753x
, irq_worker
);
70 sts
= mt753x_reg_read(gsw
, SYS_INT_STS
);
72 /* Check for changed PHY link status */
73 for (i
= 0; i
< MT753X_NUM_PHYS
; i
++) {
74 if (!(sts
& PHY_LC_INT(i
)))
77 laststs
= gsw
->phy_link_sts
& BIT(i
);
78 physts
= !!(gsw
->mii_read(gsw
, i
, MII_BMSR
) & BMSR_LSTATUS
);
81 if (physts
^ laststs
) {
82 gsw
->phy_link_sts
^= BIT(i
);
83 display_port_link_status(gsw
, i
);
87 mt753x_reg_write(gsw
, SYS_INT_STS
, sts
);