1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23#include <linux/io.h>
24#include <linux/iopoll.h>
25#include <linux/mii.h>
26#include <linux/of.h>
27#include <linux/of_gpio.h>
28#include <linux/of_mdio.h>
29#include <linux/phy.h>
30#include <linux/slab.h>
31
32#include "dwxgmac2.h"
33#include "stmmac.h"
34
35#define MII_BUSY 0x00000001
36#define MII_WRITE 0x00000002
37
38
39#define MII_GMAC4_GOC_SHIFT 2
40#define MII_GMAC4_WRITE (1 << MII_GMAC4_GOC_SHIFT)
41#define MII_GMAC4_READ (3 << MII_GMAC4_GOC_SHIFT)
42
43
44#define MII_XGMAC_SADDR BIT(18)
45#define MII_XGMAC_CMD_SHIFT 16
46#define MII_XGMAC_WRITE (1 << MII_XGMAC_CMD_SHIFT)
47#define MII_XGMAC_READ (3 << MII_XGMAC_CMD_SHIFT)
48#define MII_XGMAC_BUSY BIT(22)
49#define MII_XGMAC_MAX_C22ADDR 3
50#define MII_XGMAC_C22P_MASK GENMASK(MII_XGMAC_MAX_C22ADDR, 0)
51
52static int stmmac_xgmac2_c22_format(struct stmmac_priv *priv, int phyaddr,
53 int phyreg, u32 *hw_addr)
54{
55 unsigned int mii_data = priv->hw->mii.data;
56 u32 tmp;
57
58
59 if (phyaddr > MII_XGMAC_MAX_C22ADDR)
60 return -ENODEV;
61
62 if (readl_poll_timeout(priv->ioaddr + mii_data, tmp,
63 !(tmp & MII_XGMAC_BUSY), 100, 10000))
64 return -EBUSY;
65
66
67 tmp = readl(priv->ioaddr + XGMAC_MDIO_C22P);
68 tmp &= ~MII_XGMAC_C22P_MASK;
69 tmp |= BIT(phyaddr);
70 writel(tmp, priv->ioaddr + XGMAC_MDIO_C22P);
71
72 *hw_addr = (phyaddr << 16) | (phyreg & 0x1f);
73 return 0;
74}
75
76static int stmmac_xgmac2_mdio_read(struct mii_bus *bus, int phyaddr, int phyreg)
77{
78 struct net_device *ndev = bus->priv;
79 struct stmmac_priv *priv = netdev_priv(ndev);
80 unsigned int mii_address = priv->hw->mii.addr;
81 unsigned int mii_data = priv->hw->mii.data;
82 u32 tmp, addr, value = MII_XGMAC_BUSY;
83 int ret;
84
85 if (phyreg & MII_ADDR_C45) {
86 return -EOPNOTSUPP;
87 } else {
88 ret = stmmac_xgmac2_c22_format(priv, phyaddr, phyreg, &addr);
89 if (ret)
90 return ret;
91 }
92
93 value |= (priv->clk_csr << priv->hw->mii.clk_csr_shift)
94 & priv->hw->mii.clk_csr_mask;
95 value |= MII_XGMAC_SADDR | MII_XGMAC_READ;
96
97
98 if (readl_poll_timeout(priv->ioaddr + mii_data, tmp,
99 !(tmp & MII_XGMAC_BUSY), 100, 10000))
100 return -EBUSY;
101
102
103 writel(addr, priv->ioaddr + mii_address);
104 writel(value, priv->ioaddr + mii_data);
105
106
107 if (readl_poll_timeout(priv->ioaddr + mii_data, tmp,
108 !(tmp & MII_XGMAC_BUSY), 100, 10000))
109 return -EBUSY;
110
111
112 return readl(priv->ioaddr + mii_data) & GENMASK(15, 0);
113}
114
115static int stmmac_xgmac2_mdio_write(struct mii_bus *bus, int phyaddr,
116 int phyreg, u16 phydata)
117{
118 struct net_device *ndev = bus->priv;
119 struct stmmac_priv *priv = netdev_priv(ndev);
120 unsigned int mii_address = priv->hw->mii.addr;
121 unsigned int mii_data = priv->hw->mii.data;
122 u32 addr, tmp, value = MII_XGMAC_BUSY;
123 int ret;
124
125 if (phyreg & MII_ADDR_C45) {
126 return -EOPNOTSUPP;
127 } else {
128 ret = stmmac_xgmac2_c22_format(priv, phyaddr, phyreg, &addr);
129 if (ret)
130 return ret;
131 }
132
133 value |= (priv->clk_csr << priv->hw->mii.clk_csr_shift)
134 & priv->hw->mii.clk_csr_mask;
135 value |= phydata | MII_XGMAC_SADDR;
136 value |= MII_XGMAC_WRITE;
137
138
139 if (readl_poll_timeout(priv->ioaddr + mii_data, tmp,
140 !(tmp & MII_XGMAC_BUSY), 100, 10000))
141 return -EBUSY;
142
143
144 writel(addr, priv->ioaddr + mii_address);
145 writel(value, priv->ioaddr + mii_data);
146
147
148 return readl_poll_timeout(priv->ioaddr + mii_data, tmp,
149 !(tmp & MII_XGMAC_BUSY), 100, 10000);
150}
151
152
153
154
155
156
157
158
159
160
161
162static int stmmac_mdio_read(struct mii_bus *bus, int phyaddr, int phyreg)
163{
164 struct net_device *ndev = bus->priv;
165 struct stmmac_priv *priv = netdev_priv(ndev);
166 unsigned int mii_address = priv->hw->mii.addr;
167 unsigned int mii_data = priv->hw->mii.data;
168 u32 v;
169 int data;
170 u32 value = MII_BUSY;
171
172 value |= (phyaddr << priv->hw->mii.addr_shift)
173 & priv->hw->mii.addr_mask;
174 value |= (phyreg << priv->hw->mii.reg_shift) & priv->hw->mii.reg_mask;
175 value |= (priv->clk_csr << priv->hw->mii.clk_csr_shift)
176 & priv->hw->mii.clk_csr_mask;
177 if (priv->plat->has_gmac4)
178 value |= MII_GMAC4_READ;
179
180 if (readl_poll_timeout(priv->ioaddr + mii_address, v, !(v & MII_BUSY),
181 100, 10000))
182 return -EBUSY;
183
184 writel(value, priv->ioaddr + mii_address);
185
186 if (readl_poll_timeout(priv->ioaddr + mii_address, v, !(v & MII_BUSY),
187 100, 10000))
188 return -EBUSY;
189
190
191 data = (int)readl(priv->ioaddr + mii_data);
192
193 return data;
194}
195
196
197
198
199
200
201
202
203
204static int stmmac_mdio_write(struct mii_bus *bus, int phyaddr, int phyreg,
205 u16 phydata)
206{
207 struct net_device *ndev = bus->priv;
208 struct stmmac_priv *priv = netdev_priv(ndev);
209 unsigned int mii_address = priv->hw->mii.addr;
210 unsigned int mii_data = priv->hw->mii.data;
211 u32 v;
212 u32 value = MII_BUSY;
213
214 value |= (phyaddr << priv->hw->mii.addr_shift)
215 & priv->hw->mii.addr_mask;
216 value |= (phyreg << priv->hw->mii.reg_shift) & priv->hw->mii.reg_mask;
217
218 value |= (priv->clk_csr << priv->hw->mii.clk_csr_shift)
219 & priv->hw->mii.clk_csr_mask;
220 if (priv->plat->has_gmac4)
221 value |= MII_GMAC4_WRITE;
222 else
223 value |= MII_WRITE;
224
225
226 if (readl_poll_timeout(priv->ioaddr + mii_address, v, !(v & MII_BUSY),
227 100, 10000))
228 return -EBUSY;
229
230
231 writel(phydata, priv->ioaddr + mii_data);
232 writel(value, priv->ioaddr + mii_address);
233
234
235 return readl_poll_timeout(priv->ioaddr + mii_address, v, !(v & MII_BUSY),
236 100, 10000);
237}
238
239
240
241
242
243
244int stmmac_mdio_reset(struct mii_bus *bus)
245{
246#if IS_ENABLED(CONFIG_STMMAC_PLATFORM)
247 struct net_device *ndev = bus->priv;
248 struct stmmac_priv *priv = netdev_priv(ndev);
249 unsigned int mii_address = priv->hw->mii.addr;
250 struct stmmac_mdio_bus_data *data = priv->plat->mdio_bus_data;
251
252#ifdef CONFIG_OF
253 if (priv->device->of_node) {
254 if (data->reset_gpio < 0) {
255 struct device_node *np = priv->device->of_node;
256
257 if (!np)
258 return 0;
259
260 data->reset_gpio = of_get_named_gpio(np,
261 "snps,reset-gpio", 0);
262 if (data->reset_gpio < 0)
263 return 0;
264
265 data->active_low = of_property_read_bool(np,
266 "snps,reset-active-low");
267 of_property_read_u32_array(np,
268 "snps,reset-delays-us", data->delays, 3);
269
270 if (gpio_request(data->reset_gpio, "mdio-reset"))
271 return 0;
272 }
273
274 gpio_direction_output(data->reset_gpio,
275 data->active_low ? 1 : 0);
276 if (data->delays[0])
277 msleep(DIV_ROUND_UP(data->delays[0], 1000));
278
279 gpio_set_value(data->reset_gpio, data->active_low ? 0 : 1);
280 if (data->delays[1])
281 msleep(DIV_ROUND_UP(data->delays[1], 1000));
282
283 gpio_set_value(data->reset_gpio, data->active_low ? 1 : 0);
284 if (data->delays[2])
285 msleep(DIV_ROUND_UP(data->delays[2], 1000));
286 }
287#endif
288
289 if (data->phy_reset) {
290 netdev_dbg(ndev, "stmmac_mdio_reset: calling phy_reset\n");
291 data->phy_reset(priv->plat->bsp_priv);
292 }
293
294
295
296
297
298
299 if (!priv->plat->has_gmac4)
300 writel(0, priv->ioaddr + mii_address);
301#endif
302 return 0;
303}
304
305
306
307
308
309
310int stmmac_mdio_register(struct net_device *ndev)
311{
312 int err = 0;
313 struct mii_bus *new_bus;
314 struct stmmac_priv *priv = netdev_priv(ndev);
315 struct stmmac_mdio_bus_data *mdio_bus_data = priv->plat->mdio_bus_data;
316 struct device_node *mdio_node = priv->plat->mdio_node;
317 struct device *dev = ndev->dev.parent;
318 int addr, found, max_addr;
319
320 if (!mdio_bus_data)
321 return 0;
322
323 new_bus = mdiobus_alloc();
324 if (!new_bus)
325 return -ENOMEM;
326
327 if (mdio_bus_data->irqs)
328 memcpy(new_bus->irq, mdio_bus_data->irqs, sizeof(new_bus->irq));
329
330#ifdef CONFIG_OF
331 if (priv->device->of_node)
332 mdio_bus_data->reset_gpio = -1;
333#endif
334
335 new_bus->name = "stmmac";
336
337 if (priv->plat->has_xgmac) {
338 new_bus->read = &stmmac_xgmac2_mdio_read;
339 new_bus->write = &stmmac_xgmac2_mdio_write;
340
341
342 max_addr = MII_XGMAC_MAX_C22ADDR + 1;
343
344
345 if (priv->plat->phy_addr > MII_XGMAC_MAX_C22ADDR)
346 dev_err(dev, "Unsupported phy_addr (max=%d)\n",
347 MII_XGMAC_MAX_C22ADDR);
348 } else {
349 new_bus->read = &stmmac_mdio_read;
350 new_bus->write = &stmmac_mdio_write;
351 max_addr = PHY_MAX_ADDR;
352 }
353
354 new_bus->reset = &stmmac_mdio_reset;
355 snprintf(new_bus->id, MII_BUS_ID_SIZE, "%s-%x",
356 new_bus->name, priv->plat->bus_id);
357 new_bus->priv = ndev;
358 new_bus->phy_mask = mdio_bus_data->phy_mask;
359 new_bus->parent = priv->device;
360
361 err = of_mdiobus_register(new_bus, mdio_node);
362 if (err != 0) {
363 dev_err(dev, "Cannot register the MDIO bus\n");
364 goto bus_register_fail;
365 }
366
367 if (priv->plat->phy_node || mdio_node)
368 goto bus_register_done;
369
370 found = 0;
371 for (addr = 0; addr < max_addr; addr++) {
372 struct phy_device *phydev = mdiobus_get_phy(new_bus, addr);
373
374 if (!phydev)
375 continue;
376
377
378
379
380
381 if (!mdio_bus_data->irqs &&
382 (mdio_bus_data->probed_phy_irq > 0)) {
383 new_bus->irq[addr] = mdio_bus_data->probed_phy_irq;
384 phydev->irq = mdio_bus_data->probed_phy_irq;
385 }
386
387
388
389
390
391
392 if (priv->plat->phy_addr == -1)
393 priv->plat->phy_addr = addr;
394
395 phy_attached_info(phydev);
396 found = 1;
397 }
398
399 if (!found && !mdio_node) {
400 dev_warn(dev, "No PHY found\n");
401 mdiobus_unregister(new_bus);
402 mdiobus_free(new_bus);
403 return -ENODEV;
404 }
405
406bus_register_done:
407 priv->mii = new_bus;
408
409 return 0;
410
411bus_register_fail:
412 mdiobus_free(new_bus);
413 return err;
414}
415
416
417
418
419
420
421int stmmac_mdio_unregister(struct net_device *ndev)
422{
423 struct stmmac_priv *priv = netdev_priv(ndev);
424
425 if (!priv->mii)
426 return 0;
427
428 mdiobus_unregister(priv->mii);
429 priv->mii->priv = NULL;
430 mdiobus_free(priv->mii);
431 priv->mii = NULL;
432
433 return 0;
434}
435