treewide: Use fallthrough pseudo-keyword
[linux-block.git] / drivers / net / phy / fixed_phy.c
1 // SPDX-License-Identifier: GPL-2.0+
2 /*
3  * Fixed MDIO bus (MDIO bus emulation with fixed PHYs)
4  *
5  * Author: Vitaly Bordug <vbordug@ru.mvista.com>
6  *         Anton Vorontsov <avorontsov@ru.mvista.com>
7  *
8  * Copyright (c) 2006-2007 MontaVista Software, Inc.
9  */
10
11 #include <linux/kernel.h>
12 #include <linux/module.h>
13 #include <linux/platform_device.h>
14 #include <linux/list.h>
15 #include <linux/mii.h>
16 #include <linux/phy.h>
17 #include <linux/phy_fixed.h>
18 #include <linux/err.h>
19 #include <linux/slab.h>
20 #include <linux/of.h>
21 #include <linux/gpio/consumer.h>
22 #include <linux/idr.h>
23 #include <linux/netdevice.h>
24 #include <linux/linkmode.h>
25
26 #include "swphy.h"
27
28 struct fixed_mdio_bus {
29         struct mii_bus *mii_bus;
30         struct list_head phys;
31 };
32
33 struct fixed_phy {
34         int addr;
35         struct phy_device *phydev;
36         struct fixed_phy_status status;
37         bool no_carrier;
38         int (*link_update)(struct net_device *, struct fixed_phy_status *);
39         struct list_head node;
40         struct gpio_desc *link_gpiod;
41 };
42
43 static struct platform_device *pdev;
44 static struct fixed_mdio_bus platform_fmb = {
45         .phys = LIST_HEAD_INIT(platform_fmb.phys),
46 };
47
48 int fixed_phy_change_carrier(struct net_device *dev, bool new_carrier)
49 {
50         struct fixed_mdio_bus *fmb = &platform_fmb;
51         struct phy_device *phydev = dev->phydev;
52         struct fixed_phy *fp;
53
54         if (!phydev || !phydev->mdio.bus)
55                 return -EINVAL;
56
57         list_for_each_entry(fp, &fmb->phys, node) {
58                 if (fp->addr == phydev->mdio.addr) {
59                         fp->no_carrier = !new_carrier;
60                         return 0;
61                 }
62         }
63         return -EINVAL;
64 }
65 EXPORT_SYMBOL_GPL(fixed_phy_change_carrier);
66
67 static void fixed_phy_update(struct fixed_phy *fp)
68 {
69         if (!fp->no_carrier && fp->link_gpiod)
70                 fp->status.link = !!gpiod_get_value_cansleep(fp->link_gpiod);
71 }
72
73 static int fixed_mdio_read(struct mii_bus *bus, int phy_addr, int reg_num)
74 {
75         struct fixed_mdio_bus *fmb = bus->priv;
76         struct fixed_phy *fp;
77
78         list_for_each_entry(fp, &fmb->phys, node) {
79                 if (fp->addr == phy_addr) {
80                         struct fixed_phy_status state;
81
82                         fp->status.link = !fp->no_carrier;
83
84                         /* Issue callback if user registered it. */
85                         if (fp->link_update)
86                                 fp->link_update(fp->phydev->attached_dev,
87                                                 &fp->status);
88
89                         /* Check the GPIO for change in status */
90                         fixed_phy_update(fp);
91                         state = fp->status;
92
93                         return swphy_read_reg(reg_num, &state);
94                 }
95         }
96
97         return 0xFFFF;
98 }
99
100 static int fixed_mdio_write(struct mii_bus *bus, int phy_addr, int reg_num,
101                             u16 val)
102 {
103         return 0;
104 }
105
106 /*
107  * If something weird is required to be done with link/speed,
108  * network driver is able to assign a function to implement this.
109  * May be useful for PHY's that need to be software-driven.
110  */
111 int fixed_phy_set_link_update(struct phy_device *phydev,
112                               int (*link_update)(struct net_device *,
113                                                  struct fixed_phy_status *))
114 {
115         struct fixed_mdio_bus *fmb = &platform_fmb;
116         struct fixed_phy *fp;
117
118         if (!phydev || !phydev->mdio.bus)
119                 return -EINVAL;
120
121         list_for_each_entry(fp, &fmb->phys, node) {
122                 if (fp->addr == phydev->mdio.addr) {
123                         fp->link_update = link_update;
124                         fp->phydev = phydev;
125                         return 0;
126                 }
127         }
128
129         return -ENOENT;
130 }
131 EXPORT_SYMBOL_GPL(fixed_phy_set_link_update);
132
133 static int fixed_phy_add_gpiod(unsigned int irq, int phy_addr,
134                                struct fixed_phy_status *status,
135                                struct gpio_desc *gpiod)
136 {
137         int ret;
138         struct fixed_mdio_bus *fmb = &platform_fmb;
139         struct fixed_phy *fp;
140
141         ret = swphy_validate_state(status);
142         if (ret < 0)
143                 return ret;
144
145         fp = kzalloc(sizeof(*fp), GFP_KERNEL);
146         if (!fp)
147                 return -ENOMEM;
148
149         if (irq != PHY_POLL)
150                 fmb->mii_bus->irq[phy_addr] = irq;
151
152         fp->addr = phy_addr;
153         fp->status = *status;
154         fp->link_gpiod = gpiod;
155
156         fixed_phy_update(fp);
157
158         list_add_tail(&fp->node, &fmb->phys);
159
160         return 0;
161 }
162
163 int fixed_phy_add(unsigned int irq, int phy_addr,
164                   struct fixed_phy_status *status) {
165
166         return fixed_phy_add_gpiod(irq, phy_addr, status, NULL);
167 }
168 EXPORT_SYMBOL_GPL(fixed_phy_add);
169
170 static DEFINE_IDA(phy_fixed_ida);
171
172 static void fixed_phy_del(int phy_addr)
173 {
174         struct fixed_mdio_bus *fmb = &platform_fmb;
175         struct fixed_phy *fp, *tmp;
176
177         list_for_each_entry_safe(fp, tmp, &fmb->phys, node) {
178                 if (fp->addr == phy_addr) {
179                         list_del(&fp->node);
180                         if (fp->link_gpiod)
181                                 gpiod_put(fp->link_gpiod);
182                         kfree(fp);
183                         ida_simple_remove(&phy_fixed_ida, phy_addr);
184                         return;
185                 }
186         }
187 }
188
189 #ifdef CONFIG_OF_GPIO
190 static struct gpio_desc *fixed_phy_get_gpiod(struct device_node *np)
191 {
192         struct device_node *fixed_link_node;
193         struct gpio_desc *gpiod;
194
195         if (!np)
196                 return NULL;
197
198         fixed_link_node = of_get_child_by_name(np, "fixed-link");
199         if (!fixed_link_node)
200                 return NULL;
201
202         /*
203          * As the fixed link is just a device tree node without any
204          * Linux device associated with it, we simply have obtain
205          * the GPIO descriptor from the device tree like this.
206          */
207         gpiod = fwnode_gpiod_get_index(of_fwnode_handle(fixed_link_node),
208                                        "link", 0, GPIOD_IN, "mdio");
209         if (IS_ERR(gpiod) && PTR_ERR(gpiod) != -EPROBE_DEFER) {
210                 if (PTR_ERR(gpiod) != -ENOENT)
211                         pr_err("error getting GPIO for fixed link %pOF, proceed without\n",
212                                fixed_link_node);
213                 gpiod = NULL;
214         }
215         of_node_put(fixed_link_node);
216
217         return gpiod;
218 }
219 #else
220 static struct gpio_desc *fixed_phy_get_gpiod(struct device_node *np)
221 {
222         return NULL;
223 }
224 #endif
225
226 static struct phy_device *__fixed_phy_register(unsigned int irq,
227                                                struct fixed_phy_status *status,
228                                                struct device_node *np,
229                                                struct gpio_desc *gpiod)
230 {
231         struct fixed_mdio_bus *fmb = &platform_fmb;
232         struct phy_device *phy;
233         int phy_addr;
234         int ret;
235
236         if (!fmb->mii_bus || fmb->mii_bus->state != MDIOBUS_REGISTERED)
237                 return ERR_PTR(-EPROBE_DEFER);
238
239         /* Check if we have a GPIO associated with this fixed phy */
240         if (!gpiod) {
241                 gpiod = fixed_phy_get_gpiod(np);
242                 if (IS_ERR(gpiod))
243                         return ERR_CAST(gpiod);
244         }
245
246         /* Get the next available PHY address, up to PHY_MAX_ADDR */
247         phy_addr = ida_simple_get(&phy_fixed_ida, 0, PHY_MAX_ADDR, GFP_KERNEL);
248         if (phy_addr < 0)
249                 return ERR_PTR(phy_addr);
250
251         ret = fixed_phy_add_gpiod(irq, phy_addr, status, gpiod);
252         if (ret < 0) {
253                 ida_simple_remove(&phy_fixed_ida, phy_addr);
254                 return ERR_PTR(ret);
255         }
256
257         phy = get_phy_device(fmb->mii_bus, phy_addr, false);
258         if (IS_ERR(phy)) {
259                 fixed_phy_del(phy_addr);
260                 return ERR_PTR(-EINVAL);
261         }
262
263         /* propagate the fixed link values to struct phy_device */
264         phy->link = status->link;
265         if (status->link) {
266                 phy->speed = status->speed;
267                 phy->duplex = status->duplex;
268                 phy->pause = status->pause;
269                 phy->asym_pause = status->asym_pause;
270         }
271
272         of_node_get(np);
273         phy->mdio.dev.of_node = np;
274         phy->is_pseudo_fixed_link = true;
275
276         switch (status->speed) {
277         case SPEED_1000:
278                 linkmode_set_bit(ETHTOOL_LINK_MODE_1000baseT_Half_BIT,
279                                  phy->supported);
280                 linkmode_set_bit(ETHTOOL_LINK_MODE_1000baseT_Full_BIT,
281                                  phy->supported);
282                 fallthrough;
283         case SPEED_100:
284                 linkmode_set_bit(ETHTOOL_LINK_MODE_100baseT_Half_BIT,
285                                  phy->supported);
286                 linkmode_set_bit(ETHTOOL_LINK_MODE_100baseT_Full_BIT,
287                                  phy->supported);
288                 fallthrough;
289         case SPEED_10:
290         default:
291                 linkmode_set_bit(ETHTOOL_LINK_MODE_10baseT_Half_BIT,
292                                  phy->supported);
293                 linkmode_set_bit(ETHTOOL_LINK_MODE_10baseT_Full_BIT,
294                                  phy->supported);
295         }
296
297         phy_advertise_supported(phy);
298
299         ret = phy_device_register(phy);
300         if (ret) {
301                 phy_device_free(phy);
302                 of_node_put(np);
303                 fixed_phy_del(phy_addr);
304                 return ERR_PTR(ret);
305         }
306
307         return phy;
308 }
309
310 struct phy_device *fixed_phy_register(unsigned int irq,
311                                       struct fixed_phy_status *status,
312                                       struct device_node *np)
313 {
314         return __fixed_phy_register(irq, status, np, NULL);
315 }
316 EXPORT_SYMBOL_GPL(fixed_phy_register);
317
318 struct phy_device *
319 fixed_phy_register_with_gpiod(unsigned int irq,
320                               struct fixed_phy_status *status,
321                               struct gpio_desc *gpiod)
322 {
323         return __fixed_phy_register(irq, status, NULL, gpiod);
324 }
325 EXPORT_SYMBOL_GPL(fixed_phy_register_with_gpiod);
326
327 void fixed_phy_unregister(struct phy_device *phy)
328 {
329         phy_device_remove(phy);
330         of_node_put(phy->mdio.dev.of_node);
331         fixed_phy_del(phy->mdio.addr);
332 }
333 EXPORT_SYMBOL_GPL(fixed_phy_unregister);
334
335 static int __init fixed_mdio_bus_init(void)
336 {
337         struct fixed_mdio_bus *fmb = &platform_fmb;
338         int ret;
339
340         pdev = platform_device_register_simple("Fixed MDIO bus", 0, NULL, 0);
341         if (IS_ERR(pdev))
342                 return PTR_ERR(pdev);
343
344         fmb->mii_bus = mdiobus_alloc();
345         if (fmb->mii_bus == NULL) {
346                 ret = -ENOMEM;
347                 goto err_mdiobus_reg;
348         }
349
350         snprintf(fmb->mii_bus->id, MII_BUS_ID_SIZE, "fixed-0");
351         fmb->mii_bus->name = "Fixed MDIO Bus";
352         fmb->mii_bus->priv = fmb;
353         fmb->mii_bus->parent = &pdev->dev;
354         fmb->mii_bus->read = &fixed_mdio_read;
355         fmb->mii_bus->write = &fixed_mdio_write;
356
357         ret = mdiobus_register(fmb->mii_bus);
358         if (ret)
359                 goto err_mdiobus_alloc;
360
361         return 0;
362
363 err_mdiobus_alloc:
364         mdiobus_free(fmb->mii_bus);
365 err_mdiobus_reg:
366         platform_device_unregister(pdev);
367         return ret;
368 }
369 module_init(fixed_mdio_bus_init);
370
371 static void __exit fixed_mdio_bus_exit(void)
372 {
373         struct fixed_mdio_bus *fmb = &platform_fmb;
374         struct fixed_phy *fp, *tmp;
375
376         mdiobus_unregister(fmb->mii_bus);
377         mdiobus_free(fmb->mii_bus);
378         platform_device_unregister(pdev);
379
380         list_for_each_entry_safe(fp, tmp, &fmb->phys, node) {
381                 list_del(&fp->node);
382                 kfree(fp);
383         }
384         ida_destroy(&phy_fixed_ida);
385 }
386 module_exit(fixed_mdio_bus_exit);
387
388 MODULE_DESCRIPTION("Fixed MDIO bus (MDIO bus emulation with fixed PHYs)");
389 MODULE_AUTHOR("Vitaly Bordug");
390 MODULE_LICENSE("GPL");