net: phy: Convert some PHY and MDIO driver files to SPDX headers
[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.h>
22 #include <linux/seqlock.h>
23 #include <linux/idr.h>
24 #include <linux/netdevice.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         seqcount_t seqcount;
37         struct fixed_phy_status status;
38         bool no_carrier;
39         int (*link_update)(struct net_device *, struct fixed_phy_status *);
40         struct list_head node;
41         int link_gpio;
42 };
43
44 static struct platform_device *pdev;
45 static struct fixed_mdio_bus platform_fmb = {
46         .phys = LIST_HEAD_INIT(platform_fmb.phys),
47 };
48
49 int fixed_phy_change_carrier(struct net_device *dev, bool new_carrier)
50 {
51         struct fixed_mdio_bus *fmb = &platform_fmb;
52         struct phy_device *phydev = dev->phydev;
53         struct fixed_phy *fp;
54
55         if (!phydev || !phydev->mdio.bus)
56                 return -EINVAL;
57
58         list_for_each_entry(fp, &fmb->phys, node) {
59                 if (fp->addr == phydev->mdio.addr) {
60                         fp->no_carrier = !new_carrier;
61                         return 0;
62                 }
63         }
64         return -EINVAL;
65 }
66 EXPORT_SYMBOL_GPL(fixed_phy_change_carrier);
67
68 static void fixed_phy_update(struct fixed_phy *fp)
69 {
70         if (!fp->no_carrier && gpio_is_valid(fp->link_gpio))
71                 fp->status.link = !!gpio_get_value_cansleep(fp->link_gpio);
72 }
73
74 static int fixed_mdio_read(struct mii_bus *bus, int phy_addr, int reg_num)
75 {
76         struct fixed_mdio_bus *fmb = bus->priv;
77         struct fixed_phy *fp;
78
79         list_for_each_entry(fp, &fmb->phys, node) {
80                 if (fp->addr == phy_addr) {
81                         struct fixed_phy_status state;
82                         int s;
83
84                         do {
85                                 s = read_seqcount_begin(&fp->seqcount);
86                                 fp->status.link = !fp->no_carrier;
87                                 /* Issue callback if user registered it. */
88                                 if (fp->link_update) {
89                                         fp->link_update(fp->phydev->attached_dev,
90                                                         &fp->status);
91                                         fixed_phy_update(fp);
92                                 }
93                                 state = fp->status;
94                         } while (read_seqcount_retry(&fp->seqcount, s));
95
96                         return swphy_read_reg(reg_num, &state);
97                 }
98         }
99
100         return 0xFFFF;
101 }
102
103 static int fixed_mdio_write(struct mii_bus *bus, int phy_addr, int reg_num,
104                             u16 val)
105 {
106         return 0;
107 }
108
109 /*
110  * If something weird is required to be done with link/speed,
111  * network driver is able to assign a function to implement this.
112  * May be useful for PHY's that need to be software-driven.
113  */
114 int fixed_phy_set_link_update(struct phy_device *phydev,
115                               int (*link_update)(struct net_device *,
116                                                  struct fixed_phy_status *))
117 {
118         struct fixed_mdio_bus *fmb = &platform_fmb;
119         struct fixed_phy *fp;
120
121         if (!phydev || !phydev->mdio.bus)
122                 return -EINVAL;
123
124         list_for_each_entry(fp, &fmb->phys, node) {
125                 if (fp->addr == phydev->mdio.addr) {
126                         fp->link_update = link_update;
127                         fp->phydev = phydev;
128                         return 0;
129                 }
130         }
131
132         return -ENOENT;
133 }
134 EXPORT_SYMBOL_GPL(fixed_phy_set_link_update);
135
136 int fixed_phy_add(unsigned int irq, int phy_addr,
137                   struct fixed_phy_status *status,
138                   int link_gpio)
139 {
140         int ret;
141         struct fixed_mdio_bus *fmb = &platform_fmb;
142         struct fixed_phy *fp;
143
144         ret = swphy_validate_state(status);
145         if (ret < 0)
146                 return ret;
147
148         fp = kzalloc(sizeof(*fp), GFP_KERNEL);
149         if (!fp)
150                 return -ENOMEM;
151
152         seqcount_init(&fp->seqcount);
153
154         if (irq != PHY_POLL)
155                 fmb->mii_bus->irq[phy_addr] = irq;
156
157         fp->addr = phy_addr;
158         fp->status = *status;
159         fp->link_gpio = link_gpio;
160
161         if (gpio_is_valid(fp->link_gpio)) {
162                 ret = gpio_request_one(fp->link_gpio, GPIOF_DIR_IN,
163                                        "fixed-link-gpio-link");
164                 if (ret)
165                         goto err_regs;
166         }
167
168         fixed_phy_update(fp);
169
170         list_add_tail(&fp->node, &fmb->phys);
171
172         return 0;
173
174 err_regs:
175         kfree(fp);
176         return ret;
177 }
178 EXPORT_SYMBOL_GPL(fixed_phy_add);
179
180 static DEFINE_IDA(phy_fixed_ida);
181
182 static void fixed_phy_del(int phy_addr)
183 {
184         struct fixed_mdio_bus *fmb = &platform_fmb;
185         struct fixed_phy *fp, *tmp;
186
187         list_for_each_entry_safe(fp, tmp, &fmb->phys, node) {
188                 if (fp->addr == phy_addr) {
189                         list_del(&fp->node);
190                         if (gpio_is_valid(fp->link_gpio))
191                                 gpio_free(fp->link_gpio);
192                         kfree(fp);
193                         ida_simple_remove(&phy_fixed_ida, phy_addr);
194                         return;
195                 }
196         }
197 }
198
199 struct phy_device *fixed_phy_register(unsigned int irq,
200                                       struct fixed_phy_status *status,
201                                       int link_gpio,
202                                       struct device_node *np)
203 {
204         struct fixed_mdio_bus *fmb = &platform_fmb;
205         struct phy_device *phy;
206         int phy_addr;
207         int ret;
208
209         if (!fmb->mii_bus || fmb->mii_bus->state != MDIOBUS_REGISTERED)
210                 return ERR_PTR(-EPROBE_DEFER);
211
212         /* Get the next available PHY address, up to PHY_MAX_ADDR */
213         phy_addr = ida_simple_get(&phy_fixed_ida, 0, PHY_MAX_ADDR, GFP_KERNEL);
214         if (phy_addr < 0)
215                 return ERR_PTR(phy_addr);
216
217         ret = fixed_phy_add(irq, phy_addr, status, link_gpio);
218         if (ret < 0) {
219                 ida_simple_remove(&phy_fixed_ida, phy_addr);
220                 return ERR_PTR(ret);
221         }
222
223         phy = get_phy_device(fmb->mii_bus, phy_addr, false);
224         if (IS_ERR(phy)) {
225                 fixed_phy_del(phy_addr);
226                 return ERR_PTR(-EINVAL);
227         }
228
229         /* propagate the fixed link values to struct phy_device */
230         phy->link = status->link;
231         if (status->link) {
232                 phy->speed = status->speed;
233                 phy->duplex = status->duplex;
234                 phy->pause = status->pause;
235                 phy->asym_pause = status->asym_pause;
236         }
237
238         of_node_get(np);
239         phy->mdio.dev.of_node = np;
240         phy->is_pseudo_fixed_link = true;
241
242         switch (status->speed) {
243         case SPEED_1000:
244                 linkmode_set_bit(ETHTOOL_LINK_MODE_1000baseT_Half_BIT,
245                                  phy->supported);
246                 linkmode_set_bit(ETHTOOL_LINK_MODE_1000baseT_Full_BIT,
247                                  phy->supported);
248                 /* fall through */
249         case SPEED_100:
250                 linkmode_set_bit(ETHTOOL_LINK_MODE_100baseT_Half_BIT,
251                                  phy->supported);
252                 linkmode_set_bit(ETHTOOL_LINK_MODE_100baseT_Full_BIT,
253                                  phy->supported);
254                 /* fall through */
255         case SPEED_10:
256         default:
257                 linkmode_set_bit(ETHTOOL_LINK_MODE_10baseT_Half_BIT,
258                                  phy->supported);
259                 linkmode_set_bit(ETHTOOL_LINK_MODE_10baseT_Full_BIT,
260                                  phy->supported);
261         }
262
263         ret = phy_device_register(phy);
264         if (ret) {
265                 phy_device_free(phy);
266                 of_node_put(np);
267                 fixed_phy_del(phy_addr);
268                 return ERR_PTR(ret);
269         }
270
271         return phy;
272 }
273 EXPORT_SYMBOL_GPL(fixed_phy_register);
274
275 void fixed_phy_unregister(struct phy_device *phy)
276 {
277         phy_device_remove(phy);
278         of_node_put(phy->mdio.dev.of_node);
279         fixed_phy_del(phy->mdio.addr);
280 }
281 EXPORT_SYMBOL_GPL(fixed_phy_unregister);
282
283 static int __init fixed_mdio_bus_init(void)
284 {
285         struct fixed_mdio_bus *fmb = &platform_fmb;
286         int ret;
287
288         pdev = platform_device_register_simple("Fixed MDIO bus", 0, NULL, 0);
289         if (IS_ERR(pdev))
290                 return PTR_ERR(pdev);
291
292         fmb->mii_bus = mdiobus_alloc();
293         if (fmb->mii_bus == NULL) {
294                 ret = -ENOMEM;
295                 goto err_mdiobus_reg;
296         }
297
298         snprintf(fmb->mii_bus->id, MII_BUS_ID_SIZE, "fixed-0");
299         fmb->mii_bus->name = "Fixed MDIO Bus";
300         fmb->mii_bus->priv = fmb;
301         fmb->mii_bus->parent = &pdev->dev;
302         fmb->mii_bus->read = &fixed_mdio_read;
303         fmb->mii_bus->write = &fixed_mdio_write;
304
305         ret = mdiobus_register(fmb->mii_bus);
306         if (ret)
307                 goto err_mdiobus_alloc;
308
309         return 0;
310
311 err_mdiobus_alloc:
312         mdiobus_free(fmb->mii_bus);
313 err_mdiobus_reg:
314         platform_device_unregister(pdev);
315         return ret;
316 }
317 module_init(fixed_mdio_bus_init);
318
319 static void __exit fixed_mdio_bus_exit(void)
320 {
321         struct fixed_mdio_bus *fmb = &platform_fmb;
322         struct fixed_phy *fp, *tmp;
323
324         mdiobus_unregister(fmb->mii_bus);
325         mdiobus_free(fmb->mii_bus);
326         platform_device_unregister(pdev);
327
328         list_for_each_entry_safe(fp, tmp, &fmb->phys, node) {
329                 list_del(&fp->node);
330                 kfree(fp);
331         }
332         ida_destroy(&phy_fixed_ida);
333 }
334 module_exit(fixed_mdio_bus_exit);
335
336 MODULE_DESCRIPTION("Fixed MDIO bus (MDIO bus emulation with fixed PHYs)");
337 MODULE_AUTHOR("Vitaly Bordug");
338 MODULE_LICENSE("GPL");