mediatek: add v4.19 support
[openwrt/staging/lynxis.git] / target / linux / mediatek / files-4.19 / drivers / net / phy / mtk / mt753x / mt753x_common.c
1 /*
2 * Common part for MediaTek MT753x gigabit switch
3 *
4 * Copyright (C) 2018 MediaTek Inc. All Rights Reserved.
5 *
6 * Author: Weijie Gao <weijie.gao@mediatek.com>
7 *
8 * SPDX-License-Identifier: GPL-2.0+
9 */
10
11 #include <linux/kernel.h>
12 #include <linux/delay.h>
13
14 #include "mt753x.h"
15 #include "mt753x_regs.h"
16
17 void mt753x_irq_enable(struct gsw_mt753x *gsw)
18 {
19 u32 val;
20 int i;
21
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);
27 }
28
29 val = BIT(MT753X_NUM_PHYS) - 1;
30
31 mt753x_reg_write(gsw, SYS_INT_EN, val);
32 }
33
34 static void display_port_link_status(struct gsw_mt753x *gsw, u32 port)
35 {
36 u32 pmsr, speed_bits;
37 const char *speed;
38
39 pmsr = mt753x_reg_read(gsw, PMSR(port));
40
41 speed_bits = (pmsr & MAC_SPD_STS_M) >> MAC_SPD_STS_S;
42
43 switch (speed_bits) {
44 case MAC_SPD_10:
45 speed = "10Mbps";
46 break;
47 case MAC_SPD_100:
48 speed = "100Mbps";
49 break;
50 case MAC_SPD_1000:
51 speed = "1Gbps";
52 break;
53 case MAC_SPD_2500:
54 speed = "2.5Gbps";
55 break;
56 }
57
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");
61 } else {
62 dev_info(gsw->dev, "Port %d Link is Down\n", port);
63 }
64 }
65
66 void mt753x_irq_worker(struct work_struct *work)
67 {
68 struct gsw_mt753x *gsw;
69 u32 sts, physts, laststs;
70 int i;
71
72 gsw = container_of(work, struct gsw_mt753x, irq_worker);
73
74 sts = mt753x_reg_read(gsw, SYS_INT_STS);
75
76 /* Check for changed PHY link status */
77 for (i = 0; i < MT753X_NUM_PHYS; i++) {
78 if (!(sts & PHY_LC_INT(i)))
79 continue;
80
81 laststs = gsw->phy_link_sts & BIT(i);
82 physts = !!(gsw->mii_read(gsw, i, MII_BMSR) & BMSR_LSTATUS);
83 physts <<= i;
84
85 if (physts ^ laststs) {
86 gsw->phy_link_sts ^= BIT(i);
87 display_port_link_status(gsw, i);
88 }
89 }
90
91 mt753x_reg_write(gsw, SYS_INT_STS, sts);
92
93 enable_irq(gsw->irq);
94 }