hc
2023-12-09 b22da3d8526a935aa31e086e63f60ff3246cb61c
kernel/drivers/net/phy/fixed_phy.c
....@@ -1,3 +1,4 @@
1
+// SPDX-License-Identifier: GPL-2.0+
12 /*
23 * Fixed MDIO bus (MDIO bus emulation with fixed PHYs)
34 *
....@@ -5,11 +6,6 @@
56 * Anton Vorontsov <avorontsov@ru.mvista.com>
67 *
78 * Copyright (c) 2006-2007 MontaVista Software, Inc.
8
- *
9
- * This program is free software; you can redistribute it and/or modify it
10
- * under the terms of the GNU General Public License as published by the
11
- * Free Software Foundation; either version 2 of the License, or (at your
12
- * option) any later version.
139 */
1410
1511 #include <linux/kernel.h>
....@@ -22,8 +18,10 @@
2218 #include <linux/err.h>
2319 #include <linux/slab.h>
2420 #include <linux/of.h>
25
-#include <linux/gpio.h>
21
+#include <linux/gpio/consumer.h>
2622 #include <linux/idr.h>
23
+#include <linux/netdevice.h>
24
+#include <linux/linkmode.h>
2725
2826 #include "swphy.h"
2927
....@@ -36,9 +34,10 @@
3634 int addr;
3735 struct phy_device *phydev;
3836 struct fixed_phy_status status;
37
+ bool no_carrier;
3938 int (*link_update)(struct net_device *, struct fixed_phy_status *);
4039 struct list_head node;
41
- int link_gpio;
40
+ struct gpio_desc *link_gpiod;
4241 };
4342
4443 static struct platform_device *pdev;
....@@ -46,10 +45,29 @@
4645 .phys = LIST_HEAD_INIT(platform_fmb.phys),
4746 };
4847
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
+
4967 static void fixed_phy_update(struct fixed_phy *fp)
5068 {
51
- if (gpio_is_valid(fp->link_gpio))
52
- fp->status.link = !!gpio_get_value_cansleep(fp->link_gpio);
69
+ if (!fp->no_carrier && fp->link_gpiod)
70
+ fp->status.link = !!gpiod_get_value_cansleep(fp->link_gpiod);
5371 }
5472
5573 static int fixed_mdio_read(struct mii_bus *bus, int phy_addr, int reg_num)
....@@ -60,6 +78,8 @@
6078 list_for_each_entry(fp, &fmb->phys, node) {
6179 if (fp->addr == phy_addr) {
6280 struct fixed_phy_status state;
81
+
82
+ fp->status.link = !fp->no_carrier;
6383
6484 /* Issue callback if user registered it. */
6585 if (fp->link_update)
....@@ -110,9 +130,9 @@
110130 }
111131 EXPORT_SYMBOL_GPL(fixed_phy_set_link_update);
112132
113
-int fixed_phy_add(unsigned int irq, int phy_addr,
114
- struct fixed_phy_status *status,
115
- int link_gpio)
133
+static int fixed_phy_add_gpiod(unsigned int irq, int phy_addr,
134
+ struct fixed_phy_status *status,
135
+ struct gpio_desc *gpiod)
116136 {
117137 int ret;
118138 struct fixed_mdio_bus *fmb = &platform_fmb;
....@@ -131,24 +151,19 @@
131151
132152 fp->addr = phy_addr;
133153 fp->status = *status;
134
- fp->link_gpio = link_gpio;
135
-
136
- if (gpio_is_valid(fp->link_gpio)) {
137
- ret = gpio_request_one(fp->link_gpio, GPIOF_DIR_IN,
138
- "fixed-link-gpio-link");
139
- if (ret)
140
- goto err_regs;
141
- }
154
+ fp->link_gpiod = gpiod;
142155
143156 fixed_phy_update(fp);
144157
145158 list_add_tail(&fp->node, &fmb->phys);
146159
147160 return 0;
161
+}
148162
149
-err_regs:
150
- kfree(fp);
151
- return ret;
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);
152167 }
153168 EXPORT_SYMBOL_GPL(fixed_phy_add);
154169
....@@ -162,8 +177,8 @@
162177 list_for_each_entry_safe(fp, tmp, &fmb->phys, node) {
163178 if (fp->addr == phy_addr) {
164179 list_del(&fp->node);
165
- if (gpio_is_valid(fp->link_gpio))
166
- gpio_free(fp->link_gpio);
180
+ if (fp->link_gpiod)
181
+ gpiod_put(fp->link_gpiod);
167182 kfree(fp);
168183 ida_simple_remove(&phy_fixed_ida, phy_addr);
169184 return;
....@@ -171,10 +186,47 @@
171186 }
172187 }
173188
174
-struct phy_device *fixed_phy_register(unsigned int irq,
175
- struct fixed_phy_status *status,
176
- int link_gpio,
177
- struct device_node *np)
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)
178230 {
179231 struct fixed_mdio_bus *fmb = &platform_fmb;
180232 struct phy_device *phy;
....@@ -184,12 +236,19 @@
184236 if (!fmb->mii_bus || fmb->mii_bus->state != MDIOBUS_REGISTERED)
185237 return ERR_PTR(-EPROBE_DEFER);
186238
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
+
187246 /* Get the next available PHY address, up to PHY_MAX_ADDR */
188247 phy_addr = ida_simple_get(&phy_fixed_ida, 0, PHY_MAX_ADDR, GFP_KERNEL);
189248 if (phy_addr < 0)
190249 return ERR_PTR(phy_addr);
191250
192
- ret = fixed_phy_add(irq, phy_addr, status, link_gpio);
251
+ ret = fixed_phy_add_gpiod(irq, phy_addr, status, gpiod);
193252 if (ret < 0) {
194253 ida_simple_remove(&phy_fixed_ida, phy_addr);
195254 return ERR_PTR(ret);
....@@ -216,15 +275,26 @@
216275
217276 switch (status->speed) {
218277 case SPEED_1000:
219
- phy->supported = PHY_1000BT_FEATURES;
220
- break;
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;
221283 case SPEED_100:
222
- phy->supported = PHY_100BT_FEATURES;
223
- break;
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;
224289 case SPEED_10:
225290 default:
226
- phy->supported = PHY_10BT_FEATURES;
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);
227295 }
296
+
297
+ phy_advertise_supported(phy);
228298
229299 ret = phy_device_register(phy);
230300 if (ret) {
....@@ -236,8 +306,24 @@
236306
237307 return phy;
238308 }
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
+}
239316 EXPORT_SYMBOL_GPL(fixed_phy_register);
240317
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
+
241327 void fixed_phy_unregister(struct phy_device *phy)
242328 {
243329 phy_device_remove(phy);