ath79/mikrotik: use routerbootpart partitions
[oweals/openwrt.git] / target / linux / layerscape / patches-5.4 / 701-net-0382-enetc-Make-MDIO-accessors-more-generic-and-export-to.patch
1 From 126e6f022c749ac1bf3a607269a106ccd87d0594 Mon Sep 17 00:00:00 2001
2 From: Claudiu Manoil <claudiu.manoil@nxp.com>
3 Date: Mon, 12 Aug 2019 20:26:42 +0300
4 Subject: [PATCH] enetc: Make MDIO accessors more generic and export to
5  include/linux/fsl
6
7 Within the LS1028A SoC, the register map for the ENETC MDIO controller
8 is instantiated a few times: for the central (external) MDIO controller,
9 for the internal bus of each standalone ENETC port, and for the internal
10 bus of the Felix switch.
11
12 Refactoring is needed to support multiple MDIO buses from multiple
13 drivers. The enetc_hw structure is made an opaque type and a smaller
14 enetc_mdio_priv is created.
15
16 'mdio_base' - MDIO registers base address - is being parameterized, to
17 be able to work with different MDIO register bases.
18
19 The ENETC MDIO bus operations are exported from the fsl-enetc-mdio
20 kernel object, the same that registers the central MDIO controller (the
21 dedicated PF). The ENETC main driver has been changed to select it, and
22 use its exported helpers to further register its private MDIO bus. The
23 DSA Felix driver will do the same.
24
25 Signed-off-by: Claudiu Manoil <claudiu.manoil@nxp.com>
26 Signed-off-by: Vladimir Oltean <vladimir.oltean@nxp.com>
27
28 Conflicts:
29         drivers/net/ethernet/freescale/enetc/enetc_mdio.c
30         drivers/net/ethernet/freescale/enetc/enetc_mdio.h
31         drivers/net/ethernet/freescale/enetc/enetc_pci_mdio.c
32         drivers/net/ethernet/freescale/enetc/enetc_pf.c
33         drivers/net/ethernet/freescale/enetc/enetc_pf.h
34
35 mostly with the previous (downstream version of this commit) patch
36 572ee5d842da ("enetc: Make mdio accessors more generic"), which couldn't
37 be reverted cleanly due to the existing downstream workaround for the
38 MDIO erratum.
39 ---
40  drivers/net/ethernet/freescale/enetc/Kconfig       |  1 +
41  drivers/net/ethernet/freescale/enetc/Makefile      |  2 +-
42  drivers/net/ethernet/freescale/enetc/enetc_mdio.c  | 76 ++++------------------
43  drivers/net/ethernet/freescale/enetc/enetc_mdio.h  | 12 ----
44  .../net/ethernet/freescale/enetc/enetc_pci_mdio.c  | 41 +++++++-----
45  drivers/net/ethernet/freescale/enetc/enetc_pf.c    | 71 ++++++++++++++++++++
46  drivers/net/ethernet/freescale/enetc/enetc_pf.h    |  5 --
47  include/linux/fsl/enetc_mdio.h                     | 55 ++++++++++++++++
48  8 files changed, 163 insertions(+), 100 deletions(-)
49  delete mode 100644 drivers/net/ethernet/freescale/enetc/enetc_mdio.h
50  create mode 100644 include/linux/fsl/enetc_mdio.h
51
52 --- a/drivers/net/ethernet/freescale/enetc/Kconfig
53 +++ b/drivers/net/ethernet/freescale/enetc/Kconfig
54 @@ -2,6 +2,7 @@
55  config FSL_ENETC
56         tristate "ENETC PF driver"
57         depends on PCI && PCI_MSI && (ARCH_LAYERSCAPE || COMPILE_TEST)
58 +       select FSL_ENETC_MDIO
59         select PHYLIB
60         help
61           This driver supports NXP ENETC gigabit ethernet controller PCIe
62 --- a/drivers/net/ethernet/freescale/enetc/Makefile
63 +++ b/drivers/net/ethernet/freescale/enetc/Makefile
64 @@ -3,7 +3,7 @@
65  common-objs := enetc.o enetc_cbdr.o enetc_ethtool.o
66  
67  obj-$(CONFIG_FSL_ENETC) += fsl-enetc.o
68 -fsl-enetc-y := enetc_pf.o enetc_mdio.o $(common-objs)
69 +fsl-enetc-y := enetc_pf.o $(common-objs)
70  fsl-enetc-$(CONFIG_PCI_IOV) += enetc_msg.o
71  fsl-enetc-$(CONFIG_FSL_ENETC_QOS) += enetc_qos.o
72  fsl-enetc-$(CONFIG_ENETC_TSN) += enetc_tsn.o
73 --- a/drivers/net/ethernet/freescale/enetc/enetc_mdio.c
74 +++ b/drivers/net/ethernet/freescale/enetc/enetc_mdio.c
75 @@ -1,13 +1,13 @@
76  // SPDX-License-Identifier: (GPL-2.0+ OR BSD-3-Clause)
77  /* Copyright 2019 NXP */
78  
79 +#include <linux/fsl/enetc_mdio.h>
80  #include <linux/mdio.h>
81  #include <linux/of_mdio.h>
82  #include <linux/iopoll.h>
83  #include <linux/of.h>
84  
85  #include "enetc_pf.h"
86 -#include "enetc_mdio.h"
87  
88  #define        ENETC_MDIO_CFG  0x0     /* MDIO configuration and status */
89  #define        ENETC_MDIO_CTL  0x4     /* MDIO control */
90 @@ -99,6 +99,7 @@ int enetc_mdio_write(struct mii_bus *bus
91  
92         return 0;
93  }
94 +EXPORT_SYMBOL_GPL(enetc_mdio_write);
95  
96  int enetc_mdio_read(struct mii_bus *bus, int phy_id, int regnum)
97  {
98 @@ -154,73 +155,18 @@ int enetc_mdio_read(struct mii_bus *bus,
99  
100         return value;
101  }
102 +EXPORT_SYMBOL_GPL(enetc_mdio_read);
103  
104 -int enetc_mdio_probe(struct enetc_pf *pf)
105 +struct enetc_hw *enetc_hw_alloc(struct device *dev, void __iomem *port_regs)
106  {
107 -       struct device *dev = &pf->si->pdev->dev;
108 -       struct enetc_mdio_priv *mdio_priv;
109 -       struct device_node *np;
110 -       struct mii_bus *bus;
111 -       int err;
112 -
113 -       bus = devm_mdiobus_alloc_size(dev, sizeof(*mdio_priv));
114 -       if (!bus)
115 -               return -ENOMEM;
116 -
117 -       bus->name = "Freescale ENETC MDIO Bus";
118 -       bus->read = enetc_mdio_read;
119 -       bus->write = enetc_mdio_write;
120 -       bus->parent = dev;
121 -       mdio_priv = bus->priv;
122 -       mdio_priv->hw = &pf->si->hw;
123 -       mdio_priv->mdio_base = ENETC_EMDIO_BASE;
124 -       snprintf(bus->id, MII_BUS_ID_SIZE, "%s", dev_name(dev));
125 -
126 -       np = of_get_child_by_name(dev->of_node, "mdio");
127 -       if (!np) {
128 -               dev_err(dev, "MDIO node missing\n");
129 -               return -EINVAL;
130 -       }
131 -
132 -       err = of_mdiobus_register(bus, np);
133 -       if (err) {
134 -               of_node_put(np);
135 -               dev_err(dev, "cannot register MDIO bus\n");
136 -               return err;
137 -       }
138 -
139 -       of_node_put(np);
140 -       pf->mdio = bus;
141 -
142 -       return 0;
143 -}
144 +       struct enetc_hw *hw;
145  
146 -void enetc_mdio_remove(struct enetc_pf *pf)
147 -{
148 -       if (pf->mdio)
149 -               mdiobus_unregister(pf->mdio);
150 -}
151 -
152 -int enetc_imdio_init(struct enetc_pf *pf)
153 -{
154 -       struct device *dev = &pf->si->pdev->dev;
155 -       struct enetc_mdio_priv *mdio_priv;
156 -       struct mii_bus *bus;
157 +       hw = devm_kzalloc(dev, sizeof(*hw), GFP_KERNEL);
158 +       if (!hw)
159 +               return ERR_PTR(-ENOMEM);
160  
161 -       bus = devm_mdiobus_alloc_size(dev, sizeof(*mdio_priv));
162 -       if (!bus)
163 -               return -ENOMEM;
164 +       hw->port = port_regs;
165  
166 -       bus->name = "FSL ENETC internal MDIO Bus";
167 -       bus->read = enetc_mdio_read;
168 -       bus->write = enetc_mdio_write;
169 -       bus->parent = dev;
170 -       mdio_priv = bus->priv;
171 -       mdio_priv->hw = &pf->si->hw;
172 -       mdio_priv->mdio_base = ENETC_PM_IMDIO_BASE;
173 -       snprintf(bus->id, MII_BUS_ID_SIZE, "%s", dev_name(dev));
174 -
175 -       pf->imdio = bus;
176 -
177 -       return 0;
178 +       return hw;
179  }
180 +EXPORT_SYMBOL_GPL(enetc_hw_alloc);
181 --- a/drivers/net/ethernet/freescale/enetc/enetc_mdio.h
182 +++ /dev/null
183 @@ -1,12 +0,0 @@
184 -/* SPDX-License-Identifier: (GPL-2.0+ OR BSD-3-Clause) */
185 -/* Copyright 2019 NXP */
186 -
187 -#include <linux/phy.h>
188 -
189 -struct enetc_mdio_priv {
190 -       struct enetc_hw *hw;
191 -       int mdio_base;
192 -};
193 -
194 -int enetc_mdio_write(struct mii_bus *bus, int phy_id, int regnum, u16 value);
195 -int enetc_mdio_read(struct mii_bus *bus, int phy_id, int regnum);
196 --- a/drivers/net/ethernet/freescale/enetc/enetc_pci_mdio.c
197 +++ b/drivers/net/ethernet/freescale/enetc/enetc_pci_mdio.c
198 @@ -1,8 +1,8 @@
199  // SPDX-License-Identifier: (GPL-2.0+ OR BSD-3-Clause)
200  /* Copyright 2019 NXP */
201 +#include <linux/fsl/enetc_mdio.h>
202  #include <linux/of_mdio.h>
203  #include "enetc_pf.h"
204 -#include "enetc_mdio.h"
205  
206  #define ENETC_MDIO_DEV_ID      0xee01
207  #define ENETC_MDIO_DEV_NAME    "FSL PCIe IE Central MDIO"
208 @@ -14,17 +14,29 @@ static int enetc_pci_mdio_probe(struct p
209  {
210         struct enetc_mdio_priv *mdio_priv;
211         struct device *dev = &pdev->dev;
212 +       void __iomem *port_regs;
213         struct enetc_hw *hw;
214         struct mii_bus *bus;
215         int err;
216  
217 -       hw = devm_kzalloc(dev, sizeof(*hw), GFP_KERNEL);
218 -       if (!hw)
219 -               return -ENOMEM;
220 +       port_regs = pci_iomap(pdev, 0, 0);
221 +       if (!port_regs) {
222 +               dev_err(dev, "iomap failed\n");
223 +               err = -ENXIO;
224 +               goto err_ioremap;
225 +       }
226 +
227 +       hw = enetc_hw_alloc(dev, port_regs);
228 +       if (IS_ERR(enetc_hw_alloc)) {
229 +               err = PTR_ERR(hw);
230 +               goto err_hw_alloc;
231 +       }
232  
233         bus = devm_mdiobus_alloc_size(dev, sizeof(*mdio_priv));
234 -       if (!bus)
235 -               return -ENOMEM;
236 +       if (!bus) {
237 +               err = -ENOMEM;
238 +               goto err_mdiobus_alloc;
239 +       }
240  
241         bus->name = ENETC_MDIO_BUS_NAME;
242         bus->read = enetc_mdio_read;
243 @@ -39,7 +51,7 @@ static int enetc_pci_mdio_probe(struct p
244         err = pci_enable_device_mem(pdev);
245         if (err) {
246                 dev_err(dev, "device enable failed\n");
247 -               return err;
248 +               goto err_pci_enable;
249         }
250  
251         err = pci_request_region(pdev, 0, KBUILD_MODNAME);
252 @@ -48,13 +60,6 @@ static int enetc_pci_mdio_probe(struct p
253                 goto err_pci_mem_reg;
254         }
255  
256 -       hw->port = pci_iomap(pdev, 0, 0);
257 -       if (!hw->port) {
258 -               err = -ENXIO;
259 -               dev_err(dev, "iomap failed\n");
260 -               goto err_ioremap;
261 -       }
262 -
263         err = of_mdiobus_register(bus, dev->of_node);
264         if (err)
265                 goto err_mdiobus_reg;
266 @@ -64,12 +69,14 @@ static int enetc_pci_mdio_probe(struct p
267         return 0;
268  
269  err_mdiobus_reg:
270 -       iounmap(mdio_priv->hw->port);
271 -err_ioremap:
272         pci_release_mem_regions(pdev);
273  err_pci_mem_reg:
274         pci_disable_device(pdev);
275 -
276 +err_pci_enable:
277 +err_mdiobus_alloc:
278 +       iounmap(port_regs);
279 +err_hw_alloc:
280 +err_ioremap:
281         return err;
282  }
283  
284 --- a/drivers/net/ethernet/freescale/enetc/enetc_pf.c
285 +++ b/drivers/net/ethernet/freescale/enetc/enetc_pf.c
286 @@ -2,6 +2,7 @@
287  /* Copyright 2017-2019 NXP */
288  
289  #include <linux/module.h>
290 +#include <linux/fsl/enetc_mdio.h>
291  #include <linux/of_mdio.h>
292  #include <linux/of_net.h>
293  #include "enetc_pf.h"
294 @@ -760,6 +761,52 @@ static void enetc_pf_netdev_setup(struct
295         enetc_get_primary_mac_addr(&si->hw, ndev->dev_addr);
296  }
297  
298 +static int enetc_mdio_probe(struct enetc_pf *pf)
299 +{
300 +       struct device *dev = &pf->si->pdev->dev;
301 +       struct enetc_mdio_priv *mdio_priv;
302 +       struct device_node *np;
303 +       struct mii_bus *bus;
304 +       int err;
305 +
306 +       bus = devm_mdiobus_alloc_size(dev, sizeof(*mdio_priv));
307 +       if (!bus)
308 +               return -ENOMEM;
309 +
310 +       bus->name = "Freescale ENETC MDIO Bus";
311 +       bus->read = enetc_mdio_read;
312 +       bus->write = enetc_mdio_write;
313 +       bus->parent = dev;
314 +       mdio_priv = bus->priv;
315 +       mdio_priv->hw = &pf->si->hw;
316 +       mdio_priv->mdio_base = ENETC_EMDIO_BASE;
317 +       snprintf(bus->id, MII_BUS_ID_SIZE, "%s", dev_name(dev));
318 +
319 +       np = of_get_child_by_name(dev->of_node, "mdio");
320 +       if (!np) {
321 +               dev_err(dev, "MDIO node missing\n");
322 +               return -EINVAL;
323 +       }
324 +
325 +       err = of_mdiobus_register(bus, np);
326 +       if (err) {
327 +               of_node_put(np);
328 +               dev_err(dev, "cannot register MDIO bus\n");
329 +               return err;
330 +       }
331 +
332 +       of_node_put(np);
333 +       pf->mdio = bus;
334 +
335 +       return 0;
336 +}
337 +
338 +static void enetc_mdio_remove(struct enetc_pf *pf)
339 +{
340 +       if (pf->mdio)
341 +               mdiobus_unregister(pf->mdio);
342 +}
343 +
344  static int enetc_of_get_phy(struct enetc_pf *pf)
345  {
346         struct device *dev = &pf->si->pdev->dev;
347 @@ -846,6 +893,30 @@ static void enetc_configure_sxgmii(struc
348                      ENETC_PCS_CR_LANE_RESET | ENETC_PCS_CR_RESET_AN);
349  }
350  
351 +static int enetc_imdio_init(struct enetc_pf *pf)
352 +{
353 +       struct device *dev = &pf->si->pdev->dev;
354 +       struct enetc_mdio_priv *mdio_priv;
355 +       struct mii_bus *bus;
356 +
357 +       bus = devm_mdiobus_alloc_size(dev, sizeof(*mdio_priv));
358 +       if (!bus)
359 +               return -ENOMEM;
360 +
361 +       bus->name = "FSL ENETC internal MDIO Bus";
362 +       bus->read = enetc_mdio_read;
363 +       bus->write = enetc_mdio_write;
364 +       bus->parent = dev;
365 +       mdio_priv = bus->priv;
366 +       mdio_priv->hw = &pf->si->hw;
367 +       mdio_priv->mdio_base = ENETC_PM_IMDIO_BASE;
368 +       snprintf(bus->id, MII_BUS_ID_SIZE, "%s", dev_name(dev));
369 +
370 +       pf->imdio = bus;
371 +
372 +       return 0;
373 +}
374 +
375  static int enetc_configure_serdes(struct enetc_ndev_priv *priv)
376  {
377         struct enetc_pf *pf = enetc_si_priv(priv->si);
378 --- a/drivers/net/ethernet/freescale/enetc/enetc_pf.h
379 +++ b/drivers/net/ethernet/freescale/enetc/enetc_pf.h
380 @@ -53,8 +53,3 @@ struct enetc_pf {
381  int enetc_msg_psi_init(struct enetc_pf *pf);
382  void enetc_msg_psi_free(struct enetc_pf *pf);
383  void enetc_msg_handle_rxmsg(struct enetc_pf *pf, int mbox_id, u16 *status);
384 -
385 -/* MDIO */
386 -int enetc_mdio_probe(struct enetc_pf *pf);
387 -void enetc_mdio_remove(struct enetc_pf *pf);
388 -int enetc_imdio_init(struct enetc_pf *pf);
389 --- /dev/null
390 +++ b/include/linux/fsl/enetc_mdio.h
391 @@ -0,0 +1,55 @@
392 +/* SPDX-License-Identifier: (GPL-2.0+ OR BSD-3-Clause) */
393 +/* Copyright 2019 NXP */
394 +
395 +#ifndef _FSL_ENETC_MDIO_H_
396 +#define _FSL_ENETC_MDIO_H_
397 +
398 +#include <linux/phy.h>
399 +
400 +/* PCS registers */
401 +#define ENETC_PCS_LINK_TIMER1                  0x12
402 +#define ENETC_PCS_LINK_TIMER1_VAL              0x06a0
403 +#define ENETC_PCS_LINK_TIMER2                  0x13
404 +#define ENETC_PCS_LINK_TIMER2_VAL              0x0003
405 +#define ENETC_PCS_IF_MODE                      0x14
406 +#define ENETC_PCS_IF_MODE_SGMII_EN             BIT(0)
407 +#define ENETC_PCS_IF_MODE_USE_SGMII_AN         BIT(1)
408 +#define ENETC_PCS_IF_MODE_SGMII_SPEED(x)       (((x) << 2) & GENMASK(3, 2))
409 +
410 +/* Not a mistake, the SerDes PLL needs to be set at 3.125 GHz by Reset
411 + * Configuration Word (RCW, outside Linux control) for 2.5G SGMII mode. The PCS
412 + * still thinks it's at gigabit.
413 + */
414 +enum enetc_pcs_speed {
415 +       ENETC_PCS_SPEED_10      = 0,
416 +       ENETC_PCS_SPEED_100     = 1,
417 +       ENETC_PCS_SPEED_1000    = 2,
418 +       ENETC_PCS_SPEED_2500    = 2,
419 +};
420 +
421 +struct enetc_hw;
422 +
423 +struct enetc_mdio_priv {
424 +       struct enetc_hw *hw;
425 +       int mdio_base;
426 +};
427 +
428 +#if IS_REACHABLE(CONFIG_FSL_ENETC_MDIO)
429 +
430 +int enetc_mdio_read(struct mii_bus *bus, int phy_id, int regnum);
431 +int enetc_mdio_write(struct mii_bus *bus, int phy_id, int regnum, u16 value);
432 +struct enetc_hw *enetc_hw_alloc(struct device *dev, void __iomem *port_regs);
433 +
434 +#else
435 +
436 +static inline int enetc_mdio_read(struct mii_bus *bus, int phy_id, int regnum)
437 +{ return -EINVAL; }
438 +static inline int enetc_mdio_write(struct mii_bus *bus, int phy_id, int regnum,
439 +                                  u16 value)
440 +{ return -EINVAL; }
441 +struct enetc_hw *enetc_hw_alloc(struct device *dev, void __iomem *port_regs)
442 +{ return ERR_PTR(-EINVAL); }
443 +
444 +#endif
445 +
446 +#endif