Branch data Line data Source code
1 : : // SPDX-License-Identifier: GPL-2.0-only
2 : : /*******************************************************************************
3 : : STMMAC Ethernet Driver -- MDIO bus implementation
4 : : Provides Bus interface for MII registers
5 : :
6 : : Copyright (C) 2007-2009 STMicroelectronics Ltd
7 : :
8 : :
9 : : Author: Carl Shaw <carl.shaw@st.com>
10 : : Maintainer: Giuseppe Cavallaro <peppe.cavallaro@st.com>
11 : : *******************************************************************************/
12 : :
13 : : #include <linux/gpio/consumer.h>
14 : : #include <linux/io.h>
15 : : #include <linux/iopoll.h>
16 : : #include <linux/mii.h>
17 : : #include <linux/of_mdio.h>
18 : : #include <linux/phy.h>
19 : : #include <linux/property.h>
20 : : #include <linux/slab.h>
21 : :
22 : : #include "dwxgmac2.h"
23 : : #include "stmmac.h"
24 : :
25 : : #define MII_BUSY 0x00000001
26 : : #define MII_WRITE 0x00000002
27 : : #define MII_DATA_MASK GENMASK(15, 0)
28 : :
29 : : /* GMAC4 defines */
30 : : #define MII_GMAC4_GOC_SHIFT 2
31 : : #define MII_GMAC4_REG_ADDR_SHIFT 16
32 : : #define MII_GMAC4_WRITE (1 << MII_GMAC4_GOC_SHIFT)
33 : : #define MII_GMAC4_READ (3 << MII_GMAC4_GOC_SHIFT)
34 : : #define MII_GMAC4_C45E BIT(1)
35 : :
36 : : /* XGMAC defines */
37 : : #define MII_XGMAC_SADDR BIT(18)
38 : : #define MII_XGMAC_CMD_SHIFT 16
39 : : #define MII_XGMAC_WRITE (1 << MII_XGMAC_CMD_SHIFT)
40 : : #define MII_XGMAC_READ (3 << MII_XGMAC_CMD_SHIFT)
41 : : #define MII_XGMAC_BUSY BIT(22)
42 : : #define MII_XGMAC_MAX_C22ADDR 3
43 : : #define MII_XGMAC_C22P_MASK GENMASK(MII_XGMAC_MAX_C22ADDR, 0)
44 : : #define MII_XGMAC_PA_SHIFT 16
45 : : #define MII_XGMAC_DA_SHIFT 21
46 : :
47 : 0 : static int stmmac_xgmac2_c45_format(struct stmmac_priv *priv, int phyaddr,
48 : : int phyreg, u32 *hw_addr)
49 : : {
50 : 0 : u32 tmp;
51 : :
52 : : /* Set port as Clause 45 */
53 : 0 : tmp = readl(priv->ioaddr + XGMAC_MDIO_C22P);
54 : 0 : tmp &= ~BIT(phyaddr);
55 : 0 : writel(tmp, priv->ioaddr + XGMAC_MDIO_C22P);
56 : :
57 : 0 : *hw_addr = (phyaddr << MII_XGMAC_PA_SHIFT) | (phyreg & 0xffff);
58 : 0 : *hw_addr |= (phyreg >> MII_DEVADDR_C45_SHIFT) << MII_XGMAC_DA_SHIFT;
59 : 0 : return 0;
60 : : }
61 : :
62 : 0 : static int stmmac_xgmac2_c22_format(struct stmmac_priv *priv, int phyaddr,
63 : : int phyreg, u32 *hw_addr)
64 : : {
65 : 0 : u32 tmp;
66 : :
67 : : /* HW does not support C22 addr >= 4 */
68 : 0 : if (phyaddr > MII_XGMAC_MAX_C22ADDR)
69 : : return -ENODEV;
70 : :
71 : : /* Set port as Clause 22 */
72 : 0 : tmp = readl(priv->ioaddr + XGMAC_MDIO_C22P);
73 : 0 : tmp &= ~MII_XGMAC_C22P_MASK;
74 : 0 : tmp |= BIT(phyaddr);
75 : 0 : writel(tmp, priv->ioaddr + XGMAC_MDIO_C22P);
76 : :
77 : 0 : *hw_addr = (phyaddr << MII_XGMAC_PA_SHIFT) | (phyreg & 0x1f);
78 : 0 : return 0;
79 : : }
80 : :
81 : 0 : static int stmmac_xgmac2_mdio_read(struct mii_bus *bus, int phyaddr, int phyreg)
82 : : {
83 : 0 : struct net_device *ndev = bus->priv;
84 : 0 : struct stmmac_priv *priv = netdev_priv(ndev);
85 : 0 : unsigned int mii_address = priv->hw->mii.addr;
86 : 0 : unsigned int mii_data = priv->hw->mii.data;
87 : 0 : u32 tmp, addr, value = MII_XGMAC_BUSY;
88 : 0 : int ret;
89 : :
90 : : /* Wait until any existing MII operation is complete */
91 [ # # # # ]: 0 : if (readl_poll_timeout(priv->ioaddr + mii_data, tmp,
92 : : !(tmp & MII_XGMAC_BUSY), 100, 10000))
93 : : return -EBUSY;
94 : :
95 [ # # ]: 0 : if (phyreg & MII_ADDR_C45) {
96 : 0 : phyreg &= ~MII_ADDR_C45;
97 : :
98 : 0 : ret = stmmac_xgmac2_c45_format(priv, phyaddr, phyreg, &addr);
99 : 0 : if (ret)
100 : : return ret;
101 : : } else {
102 [ # # ]: 0 : ret = stmmac_xgmac2_c22_format(priv, phyaddr, phyreg, &addr);
103 : 0 : if (ret)
104 : : return ret;
105 : :
106 : : value |= MII_XGMAC_SADDR;
107 : : }
108 : :
109 : 0 : value |= (priv->clk_csr << priv->hw->mii.clk_csr_shift)
110 : 0 : & priv->hw->mii.clk_csr_mask;
111 : 0 : value |= MII_XGMAC_READ;
112 : :
113 : : /* Wait until any existing MII operation is complete */
114 [ # # # # ]: 0 : if (readl_poll_timeout(priv->ioaddr + mii_data, tmp,
115 : : !(tmp & MII_XGMAC_BUSY), 100, 10000))
116 : : return -EBUSY;
117 : :
118 : : /* Set the MII address register to read */
119 : 0 : writel(addr, priv->ioaddr + mii_address);
120 : 0 : writel(value, priv->ioaddr + mii_data);
121 : :
122 : : /* Wait until any existing MII operation is complete */
123 [ # # # # ]: 0 : if (readl_poll_timeout(priv->ioaddr + mii_data, tmp,
124 : : !(tmp & MII_XGMAC_BUSY), 100, 10000))
125 : : return -EBUSY;
126 : :
127 : : /* Read the data from the MII data register */
128 : 0 : return readl(priv->ioaddr + mii_data) & GENMASK(15, 0);
129 : : }
130 : :
131 : 0 : static int stmmac_xgmac2_mdio_write(struct mii_bus *bus, int phyaddr,
132 : : int phyreg, u16 phydata)
133 : : {
134 : 0 : struct net_device *ndev = bus->priv;
135 : 0 : struct stmmac_priv *priv = netdev_priv(ndev);
136 : 0 : unsigned int mii_address = priv->hw->mii.addr;
137 : 0 : unsigned int mii_data = priv->hw->mii.data;
138 : 0 : u32 addr, tmp, value = MII_XGMAC_BUSY;
139 : 0 : int ret;
140 : :
141 : : /* Wait until any existing MII operation is complete */
142 [ # # # # ]: 0 : if (readl_poll_timeout(priv->ioaddr + mii_data, tmp,
143 : : !(tmp & MII_XGMAC_BUSY), 100, 10000))
144 : : return -EBUSY;
145 : :
146 [ # # ]: 0 : if (phyreg & MII_ADDR_C45) {
147 : 0 : phyreg &= ~MII_ADDR_C45;
148 : :
149 : 0 : ret = stmmac_xgmac2_c45_format(priv, phyaddr, phyreg, &addr);
150 : 0 : if (ret)
151 : : return ret;
152 : : } else {
153 [ # # ]: 0 : ret = stmmac_xgmac2_c22_format(priv, phyaddr, phyreg, &addr);
154 : 0 : if (ret)
155 : : return ret;
156 : :
157 : : value |= MII_XGMAC_SADDR;
158 : : }
159 : :
160 : 0 : value |= (priv->clk_csr << priv->hw->mii.clk_csr_shift)
161 : 0 : & priv->hw->mii.clk_csr_mask;
162 : 0 : value |= phydata;
163 : 0 : value |= MII_XGMAC_WRITE;
164 : :
165 : : /* Wait until any existing MII operation is complete */
166 [ # # # # ]: 0 : if (readl_poll_timeout(priv->ioaddr + mii_data, tmp,
167 : : !(tmp & MII_XGMAC_BUSY), 100, 10000))
168 : : return -EBUSY;
169 : :
170 : : /* Set the MII address register to write */
171 : 0 : writel(addr, priv->ioaddr + mii_address);
172 : 0 : writel(value, priv->ioaddr + mii_data);
173 : :
174 : : /* Wait until any existing MII operation is complete */
175 [ # # # # ]: 0 : return readl_poll_timeout(priv->ioaddr + mii_data, tmp,
176 : : !(tmp & MII_XGMAC_BUSY), 100, 10000);
177 : : }
178 : :
179 : : /**
180 : : * stmmac_mdio_read
181 : : * @bus: points to the mii_bus structure
182 : : * @phyaddr: MII addr
183 : : * @phyreg: MII reg
184 : : * Description: it reads data from the MII register from within the phy device.
185 : : * For the 7111 GMAC, we must set the bit 0 in the MII address register while
186 : : * accessing the PHY registers.
187 : : * Fortunately, it seems this has no drawback for the 7109 MAC.
188 : : */
189 : 1576 : static int stmmac_mdio_read(struct mii_bus *bus, int phyaddr, int phyreg)
190 : : {
191 : 1576 : struct net_device *ndev = bus->priv;
192 [ - + ]: 1576 : struct stmmac_priv *priv = netdev_priv(ndev);
193 : 1576 : unsigned int mii_address = priv->hw->mii.addr;
194 : 1576 : unsigned int mii_data = priv->hw->mii.data;
195 : 1576 : u32 value = MII_BUSY;
196 : 1576 : int data = 0;
197 : 1576 : u32 v;
198 : :
199 : 1576 : value |= (phyaddr << priv->hw->mii.addr_shift)
200 : 1576 : & priv->hw->mii.addr_mask;
201 : 1576 : value |= (phyreg << priv->hw->mii.reg_shift) & priv->hw->mii.reg_mask;
202 : 1576 : value |= (priv->clk_csr << priv->hw->mii.clk_csr_shift)
203 : 1576 : & priv->hw->mii.clk_csr_mask;
204 [ - + ]: 1576 : if (priv->plat->has_gmac4) {
205 : 0 : value |= MII_GMAC4_READ;
206 [ # # ]: 0 : if (phyreg & MII_ADDR_C45) {
207 : 0 : value |= MII_GMAC4_C45E;
208 : 0 : value &= ~priv->hw->mii.reg_mask;
209 : 0 : value |= ((phyreg >> MII_DEVADDR_C45_SHIFT) <<
210 : : priv->hw->mii.reg_shift) &
211 : : priv->hw->mii.reg_mask;
212 : :
213 : 0 : data |= (phyreg & MII_REGADDR_C45_MASK) <<
214 : : MII_GMAC4_REG_ADDR_SHIFT;
215 : : }
216 : : }
217 : :
218 [ + + + - ]: 2989 : if (readl_poll_timeout(priv->ioaddr + mii_address, v, !(v & MII_BUSY),
219 : : 100, 10000))
220 : : return -EBUSY;
221 : :
222 : 1576 : writel(data, priv->ioaddr + mii_data);
223 : 1576 : writel(value, priv->ioaddr + mii_address);
224 : :
225 [ + + + - ]: 3232 : if (readl_poll_timeout(priv->ioaddr + mii_address, v, !(v & MII_BUSY),
226 : : 100, 10000))
227 : : return -EBUSY;
228 : :
229 : : /* Read the data from the MII data register */
230 : 1576 : data = (int)readl(priv->ioaddr + mii_data) & MII_DATA_MASK;
231 : :
232 : 1576 : return data;
233 : : }
234 : :
235 : : /**
236 : : * stmmac_mdio_write
237 : : * @bus: points to the mii_bus structure
238 : : * @phyaddr: MII addr
239 : : * @phyreg: MII reg
240 : : * @phydata: phy data
241 : : * Description: it writes the data into the MII register from within the device.
242 : : */
243 : 105 : static int stmmac_mdio_write(struct mii_bus *bus, int phyaddr, int phyreg,
244 : : u16 phydata)
245 : : {
246 : 105 : struct net_device *ndev = bus->priv;
247 [ - + ]: 105 : struct stmmac_priv *priv = netdev_priv(ndev);
248 : 105 : unsigned int mii_address = priv->hw->mii.addr;
249 : 105 : unsigned int mii_data = priv->hw->mii.data;
250 : 105 : u32 value = MII_BUSY;
251 : 105 : int data = phydata;
252 : 105 : u32 v;
253 : :
254 : 105 : value |= (phyaddr << priv->hw->mii.addr_shift)
255 : 105 : & priv->hw->mii.addr_mask;
256 : 105 : value |= (phyreg << priv->hw->mii.reg_shift) & priv->hw->mii.reg_mask;
257 : :
258 : 105 : value |= (priv->clk_csr << priv->hw->mii.clk_csr_shift)
259 : 105 : & priv->hw->mii.clk_csr_mask;
260 [ - + ]: 105 : if (priv->plat->has_gmac4) {
261 : 0 : value |= MII_GMAC4_WRITE;
262 [ # # ]: 0 : if (phyreg & MII_ADDR_C45) {
263 : 0 : value |= MII_GMAC4_C45E;
264 : 0 : value &= ~priv->hw->mii.reg_mask;
265 : 0 : value |= ((phyreg >> MII_DEVADDR_C45_SHIFT) <<
266 : : priv->hw->mii.reg_shift) &
267 : : priv->hw->mii.reg_mask;
268 : :
269 : 0 : data |= (phyreg & MII_REGADDR_C45_MASK) <<
270 : : MII_GMAC4_REG_ADDR_SHIFT;
271 : : }
272 : : } else {
273 : 105 : value |= MII_WRITE;
274 : : }
275 : :
276 : : /* Wait until any existing MII operation is complete */
277 [ + + + - ]: 278 : if (readl_poll_timeout(priv->ioaddr + mii_address, v, !(v & MII_BUSY),
278 : : 100, 10000))
279 : : return -EBUSY;
280 : :
281 : : /* Set the MII address register to write */
282 : 105 : writel(data, priv->ioaddr + mii_data);
283 : 105 : writel(value, priv->ioaddr + mii_address);
284 : :
285 : : /* Wait until any existing MII operation is complete */
286 [ + + - + ]: 207 : return readl_poll_timeout(priv->ioaddr + mii_address, v, !(v & MII_BUSY),
287 : : 100, 10000);
288 : : }
289 : :
290 : : /**
291 : : * stmmac_mdio_reset
292 : : * @bus: points to the mii_bus structure
293 : : * Description: reset the MII bus
294 : : */
295 : 21 : int stmmac_mdio_reset(struct mii_bus *bus)
296 : : {
297 : : #if IS_ENABLED(CONFIG_STMMAC_PLATFORM)
298 : 21 : struct net_device *ndev = bus->priv;
299 [ + - ]: 21 : struct stmmac_priv *priv = netdev_priv(ndev);
300 : 21 : unsigned int mii_address = priv->hw->mii.addr;
301 : :
302 : : #ifdef CONFIG_OF
303 : : if (priv->device->of_node) {
304 : : struct gpio_desc *reset_gpio;
305 : : u32 delays[3] = { 0, 0, 0 };
306 : :
307 : : reset_gpio = devm_gpiod_get_optional(priv->device,
308 : : "snps,reset",
309 : : GPIOD_OUT_LOW);
310 : : if (IS_ERR(reset_gpio))
311 : : return PTR_ERR(reset_gpio);
312 : :
313 : : device_property_read_u32_array(priv->device,
314 : : "snps,reset-delays-us",
315 : : delays, ARRAY_SIZE(delays));
316 : :
317 : : if (delays[0])
318 : : msleep(DIV_ROUND_UP(delays[0], 1000));
319 : :
320 : : gpiod_set_value_cansleep(reset_gpio, 1);
321 : : if (delays[1])
322 : : msleep(DIV_ROUND_UP(delays[1], 1000));
323 : :
324 : : gpiod_set_value_cansleep(reset_gpio, 0);
325 : : if (delays[2])
326 : : msleep(DIV_ROUND_UP(delays[2], 1000));
327 : : }
328 : : #endif
329 : :
330 : : /* This is a workaround for problems with the STE101P PHY.
331 : : * It doesn't complete its reset until at least one clock cycle
332 : : * on MDC, so perform a dummy mdio read. To be updated for GMAC4
333 : : * if needed.
334 : : */
335 [ + - ]: 21 : if (!priv->plat->has_gmac4)
336 : 21 : writel(0, priv->ioaddr + mii_address);
337 : : #endif
338 : 21 : return 0;
339 : : }
340 : :
341 : : /**
342 : : * stmmac_mdio_register
343 : : * @ndev: net device structure
344 : : * Description: it registers the MII bus
345 : : */
346 : 21 : int stmmac_mdio_register(struct net_device *ndev)
347 : : {
348 : 21 : int err = 0;
349 : 21 : struct mii_bus *new_bus;
350 [ + - ]: 21 : struct stmmac_priv *priv = netdev_priv(ndev);
351 : 21 : struct stmmac_mdio_bus_data *mdio_bus_data = priv->plat->mdio_bus_data;
352 : 21 : struct device_node *mdio_node = priv->plat->mdio_node;
353 : 21 : struct device *dev = ndev->dev.parent;
354 : 21 : int addr, found, max_addr;
355 : :
356 [ + - ]: 21 : if (!mdio_bus_data)
357 : : return 0;
358 : :
359 : 21 : new_bus = mdiobus_alloc();
360 [ + - ]: 21 : if (!new_bus)
361 : : return -ENOMEM;
362 : :
363 [ - + ]: 21 : if (mdio_bus_data->irqs)
364 : 0 : memcpy(new_bus->irq, mdio_bus_data->irqs, sizeof(new_bus->irq));
365 : :
366 : 21 : new_bus->name = "stmmac";
367 : :
368 [ - + ]: 21 : if (priv->plat->has_xgmac) {
369 : 0 : new_bus->read = &stmmac_xgmac2_mdio_read;
370 : 0 : new_bus->write = &stmmac_xgmac2_mdio_write;
371 : :
372 : : /* Right now only C22 phys are supported */
373 : 0 : max_addr = MII_XGMAC_MAX_C22ADDR + 1;
374 : :
375 : : /* Check if DT specified an unsupported phy addr */
376 [ # # ]: 0 : if (priv->plat->phy_addr > MII_XGMAC_MAX_C22ADDR)
377 : 0 : dev_err(dev, "Unsupported phy_addr (max=%d)\n",
378 : : MII_XGMAC_MAX_C22ADDR);
379 : : } else {
380 : 21 : new_bus->read = &stmmac_mdio_read;
381 : 21 : new_bus->write = &stmmac_mdio_write;
382 : 21 : max_addr = PHY_MAX_ADDR;
383 : : }
384 : :
385 [ + - ]: 21 : if (mdio_bus_data->needs_reset)
386 : 21 : new_bus->reset = &stmmac_mdio_reset;
387 : :
388 : 21 : snprintf(new_bus->id, MII_BUS_ID_SIZE, "%s-%x",
389 : 21 : new_bus->name, priv->plat->bus_id);
390 : 21 : new_bus->priv = ndev;
391 : 21 : new_bus->phy_mask = mdio_bus_data->phy_mask;
392 : 21 : new_bus->parent = priv->device;
393 : :
394 : 21 : err = of_mdiobus_register(new_bus, mdio_node);
395 [ - + ]: 21 : if (err != 0) {
396 : 0 : dev_err(dev, "Cannot register the MDIO bus\n");
397 : 0 : goto bus_register_fail;
398 : : }
399 : :
400 : : /* Looks like we need a dummy read for XGMAC only and C45 PHYs */
401 [ - + ]: 21 : if (priv->plat->has_xgmac)
402 : 0 : stmmac_xgmac2_mdio_read(new_bus, 0, MII_ADDR_C45);
403 : :
404 [ + - - + ]: 21 : if (priv->plat->phy_node || mdio_node)
405 : 0 : goto bus_register_done;
406 : :
407 : : found = 0;
408 [ + + ]: 693 : for (addr = 0; addr < max_addr; addr++) {
409 : 672 : struct phy_device *phydev = mdiobus_get_phy(new_bus, addr);
410 : :
411 [ - + ]: 672 : if (!phydev)
412 : 0 : continue;
413 : :
414 : : /*
415 : : * If an IRQ was provided to be assigned after
416 : : * the bus probe, do it here.
417 : : */
418 [ + - ]: 672 : if (!mdio_bus_data->irqs &&
419 [ - + ]: 672 : (mdio_bus_data->probed_phy_irq > 0)) {
420 : 0 : new_bus->irq[addr] = mdio_bus_data->probed_phy_irq;
421 : 0 : phydev->irq = mdio_bus_data->probed_phy_irq;
422 : : }
423 : :
424 : : /*
425 : : * If we're going to bind the MAC to this PHY bus,
426 : : * and no PHY number was provided to the MAC,
427 : : * use the one probed here.
428 : : */
429 [ - + ]: 672 : if (priv->plat->phy_addr == -1)
430 : 0 : priv->plat->phy_addr = addr;
431 : :
432 : 672 : phy_attached_info(phydev);
433 : 672 : found = 1;
434 : : }
435 : :
436 [ - + ]: 21 : if (!found && !mdio_node) {
437 : 0 : dev_warn(dev, "No PHY found\n");
438 : 0 : mdiobus_unregister(new_bus);
439 : 0 : mdiobus_free(new_bus);
440 : 0 : return -ENODEV;
441 : : }
442 : :
443 : 21 : bus_register_done:
444 : 21 : priv->mii = new_bus;
445 : :
446 : 21 : return 0;
447 : :
448 : : bus_register_fail:
449 : 0 : mdiobus_free(new_bus);
450 : 0 : return err;
451 : : }
452 : :
453 : : /**
454 : : * stmmac_mdio_unregister
455 : : * @ndev: net device structure
456 : : * Description: it unregisters the MII bus
457 : : */
458 : 0 : int stmmac_mdio_unregister(struct net_device *ndev)
459 : : {
460 [ # # ]: 0 : struct stmmac_priv *priv = netdev_priv(ndev);
461 : :
462 [ # # ]: 0 : if (!priv->mii)
463 : : return 0;
464 : :
465 : 0 : mdiobus_unregister(priv->mii);
466 : 0 : priv->mii->priv = NULL;
467 : 0 : mdiobus_free(priv->mii);
468 : 0 : priv->mii = NULL;
469 : :
470 : 0 : return 0;
471 : : }
|