ralink: add support for mt7621 switch counters
[15.05/openwrt.git] / target / linux / ramips / files / drivers / net / ethernet / ralink / mdio_rt2880.c
1 /*
2  *   This program is free software; you can redistribute it and/or modify
3  *   it under the terms of the GNU General Public License as published by
4  *   the Free Software Foundation; version 2 of the License
5  *
6  *   This program is distributed in the hope that it will be useful,
7  *   but WITHOUT ANY WARRANTY; without even the implied warranty of
8  *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
9  *   GNU General Public License for more details.
10  *
11  *   You should have received a copy of the GNU General Public License
12  *   along with this program; if not, write to the Free Software
13  *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
14  *
15  *   Copyright (C) 2009-2013 John Crispin <blogic@openwrt.org>
16  */
17
18 #include <linux/module.h>
19 #include <linux/kernel.h>
20 #include <linux/types.h>
21 #include <linux/dma-mapping.h>
22 #include <linux/init.h>
23 #include <linux/skbuff.h>
24 #include <linux/etherdevice.h>
25 #include <linux/ethtool.h>
26 #include <linux/platform_device.h>
27 #include <linux/phy.h>
28 #include <linux/of_device.h>
29 #include <linux/clk.h>
30 #include <linux/of_net.h>
31 #include <linux/of_mdio.h>
32
33 #include "ralink_soc_eth.h"
34 #include "mdio_rt2880.h"
35 #include "mdio.h"
36
37 #define FE_MDIO_RETRY   1000
38
39 static unsigned char *rt2880_speed_str(struct fe_priv *priv)
40 {
41         switch (priv->phy->speed[0]) {
42         case SPEED_1000:
43                 return "1000";
44         case SPEED_100:
45                 return "100";
46         case SPEED_10:
47                 return "10";
48         }
49
50         return "?";
51 }
52
53 void rt2880_mdio_link_adjust(struct fe_priv *priv, int port)
54 {
55         u32 mdio_cfg;
56
57         if (!priv->link[0]) {
58                 netif_carrier_off(priv->netdev);
59                 netdev_info(priv->netdev, "link down\n");
60                 return;
61         }
62
63         mdio_cfg = FE_MDIO_CFG_TX_CLK_SKEW_200 |
64                    FE_MDIO_CFG_RX_CLK_SKEW_200 |
65                    FE_MDIO_CFG_GP1_FRC_EN;
66
67         if (priv->phy->duplex[0] == DUPLEX_FULL)
68                 mdio_cfg |= FE_MDIO_CFG_GP1_DUPLEX;
69
70         if (priv->phy->tx_fc[0])
71                 mdio_cfg |= FE_MDIO_CFG_GP1_FC_TX;
72
73         if (priv->phy->rx_fc[0])
74                 mdio_cfg |= FE_MDIO_CFG_GP1_FC_RX;
75
76         switch (priv->phy->speed[0]) {
77         case SPEED_10:
78                 mdio_cfg |= FE_MDIO_CFG_GP1_SPEED_10;
79                 break;
80         case SPEED_100:
81                 mdio_cfg |= FE_MDIO_CFG_GP1_SPEED_100;
82                 break;
83         case SPEED_1000:
84                 mdio_cfg |= FE_MDIO_CFG_GP1_SPEED_1000;
85                 break;
86         default:
87                 BUG();
88         }
89
90         fe_w32(mdio_cfg, FE_MDIO_CFG);
91
92         netif_carrier_on(priv->netdev);
93         netdev_info(priv->netdev, "link up (%sMbps/%s duplex)\n",
94                     rt2880_speed_str(priv),
95                     (DUPLEX_FULL == priv->phy->duplex[0]) ? "Full" : "Half");
96 }
97
98 static int rt2880_mdio_wait_ready(struct fe_priv *priv)
99 {
100         int retries;
101
102         retries = FE_MDIO_RETRY;
103         while (1) {
104                 u32 t;
105
106                 t = fe_r32(FE_MDIO_ACCESS);
107                 if ((t & (0x1 << 31)) == 0)
108                         return 0;
109
110                 if (retries-- == 0)
111                         break;
112
113                 udelay(1);
114         }
115
116         dev_err(priv->device, "MDIO operation timed out\n");
117         return -ETIMEDOUT;
118 }
119
120 int rt2880_mdio_read(struct mii_bus *bus, int phy_addr, int phy_reg)
121 {
122         struct fe_priv *priv = bus->priv;
123         int err;
124         u32 t;
125
126         err = rt2880_mdio_wait_ready(priv);
127         if (err)
128                 return 0xffff;
129
130         t = (phy_addr << 24) | (phy_reg << 16);
131         fe_w32(t, FE_MDIO_ACCESS);
132         t |= (1 << 31);
133         fe_w32(t, FE_MDIO_ACCESS);
134
135         err = rt2880_mdio_wait_ready(priv);
136         if (err)
137                 return 0xffff;
138
139         pr_debug("%s: addr=%04x, reg=%04x, value=%04x\n", __func__,
140                 phy_addr, phy_reg, fe_r32(FE_MDIO_ACCESS) & 0xffff);
141
142         return fe_r32(FE_MDIO_ACCESS) & 0xffff;
143 }
144
145 int rt2880_mdio_write(struct mii_bus *bus, int phy_addr, int phy_reg, u16 val)
146 {
147         struct fe_priv *priv = bus->priv;
148         int err;
149         u32 t;
150
151         pr_debug("%s: addr=%04x, reg=%04x, value=%04x\n", __func__,
152                 phy_addr, phy_reg, fe_r32(FE_MDIO_ACCESS) & 0xffff);
153
154         err = rt2880_mdio_wait_ready(priv);
155         if (err)
156                 return err;
157
158         t = (1 << 30) | (phy_addr << 24) | (phy_reg << 16) | val;
159         fe_w32(t, FE_MDIO_ACCESS);
160         t |= (1 << 31);
161         fe_w32(t, FE_MDIO_ACCESS);
162
163         return rt2880_mdio_wait_ready(priv);
164 }
165
166 void rt2880_port_init(struct fe_priv *priv, struct device_node *np)
167 {
168         const __be32 *id = of_get_property(np, "reg", NULL);
169         const __be32 *link;
170         int size;
171         int phy_mode;
172
173         if (!id || (be32_to_cpu(*id) != 0)) {
174                 pr_err("%s: invalid port id\n", np->name);
175                 return;
176         }
177
178         priv->phy->phy_fixed[0] = of_get_property(np, "ralink,fixed-link", &size);
179         if (priv->phy->phy_fixed[0] && (size != (4 * sizeof(*priv->phy->phy_fixed[0])))) {
180                 pr_err("%s: invalid fixed link property\n", np->name);
181                 priv->phy->phy_fixed[0] = NULL;
182                 return;
183         }
184
185         phy_mode = of_get_phy_mode(np);
186         switch (phy_mode) {
187         case PHY_INTERFACE_MODE_RGMII:
188                 break;
189         case PHY_INTERFACE_MODE_MII:
190                 break;
191         case PHY_INTERFACE_MODE_RMII:
192                 break;
193         default:
194                 if (!priv->phy->phy_fixed[0])
195                         dev_err(priv->device, "port %d - invalid phy mode\n", priv->phy->speed[0]);
196                 break;
197         }
198
199         priv->phy->phy_node[0] = of_parse_phandle(np, "phy-handle", 0);
200         if (!priv->phy->phy_node[0] && !priv->phy->phy_fixed[0])
201                 return;
202
203         if (priv->phy->phy_fixed[0]) {
204                 link = priv->phy->phy_fixed[0];
205                 priv->phy->speed[0] = be32_to_cpup(link++);
206                 priv->phy->duplex[0] = be32_to_cpup(link++);
207                 priv->phy->tx_fc[0] = be32_to_cpup(link++);
208                 priv->phy->rx_fc[0] = be32_to_cpup(link++);
209
210                 priv->link[0] = 1;
211                 switch (priv->phy->speed[0]) {
212                 case SPEED_10:
213                         break;
214                 case SPEED_100:
215                         break;
216                 case SPEED_1000:
217                         break;
218                 default:
219                         dev_err(priv->device, "invalid link speed: %d\n", priv->phy->speed[0]);
220                         priv->phy->phy_fixed[0] = 0;
221                         return;
222                 }
223                 dev_info(priv->device, "using fixed link parameters\n");
224                 rt2880_mdio_link_adjust(priv, 0);
225                 return;
226         }
227         if (priv->phy->phy_node[0] && priv->mii_bus->phy_map[0]) {
228                 fe_connect_phy_node(priv, priv->phy->phy_node[0]);
229         }
230
231         return;
232 }