hc
2024-05-10 23fa18eaa71266feff7ba8d83022d9e1cc83c65a
kernel/drivers/net/ethernet/broadcom/genet/bcmmii.c
....@@ -1,14 +1,11 @@
1
+// SPDX-License-Identifier: GPL-2.0-only
12 /*
23 * Broadcom GENET MDIO routines
34 *
45 * Copyright (c) 2014-2017 Broadcom
5
- *
6
- * This program is free software; you can redistribute it and/or modify
7
- * it under the terms of the GNU General Public License version 2 as
8
- * published by the Free Software Foundation.
96 */
107
11
-
8
+#include <linux/acpi.h>
129 #include <linux/types.h>
1310 #include <linux/delay.h>
1411 #include <linux/wait.h>
....@@ -98,6 +95,12 @@
9895 CMD_HD_EN |
9996 CMD_RX_PAUSE_IGNORE | CMD_TX_PAUSE_IGNORE);
10097 reg |= cmd_bits;
98
+ if (reg & CMD_SW_RESET) {
99
+ reg &= ~CMD_SW_RESET;
100
+ bcmgenet_umac_writel(priv, reg, UMAC_CMD);
101
+ udelay(2);
102
+ reg |= CMD_TX_EN | CMD_RX_EN;
103
+ }
101104 bcmgenet_umac_writel(priv, reg, UMAC_CMD);
102105 } else {
103106 /* done if nothing has changed */
....@@ -162,15 +165,6 @@
162165
163166 static void bcmgenet_moca_phy_setup(struct bcmgenet_priv *priv)
164167 {
165
- u32 reg;
166
-
167
- if (!GENET_IS_V5(priv)) {
168
- /* Speed settings are set in bcmgenet_mii_setup() */
169
- reg = bcmgenet_sys_readl(priv, SYS_PORT_CTRL);
170
- reg |= LED_ACT_SOURCE_MAC;
171
- bcmgenet_sys_writel(priv, reg, SYS_PORT_CTRL);
172
- }
173
-
174168 if (priv->hw_params->flags & GENET_HAS_MOCA_LINK_DET)
175169 fixed_phy_set_link_update(priv->dev->phydev,
176170 bcmgenet_fixed_phy_link_update);
....@@ -184,43 +178,12 @@
184178 const char *phy_name = NULL;
185179 u32 id_mode_dis = 0;
186180 u32 port_ctrl;
187
- int bmcr = -1;
188
- int ret;
189181 u32 reg;
190
-
191
- /* MAC clocking workaround during reset of umac state machines */
192
- reg = bcmgenet_umac_readl(priv, UMAC_CMD);
193
- if (reg & CMD_SW_RESET) {
194
- /* An MII PHY must be isolated to prevent TXC contention */
195
- if (priv->phy_interface == PHY_INTERFACE_MODE_MII) {
196
- ret = phy_read(phydev, MII_BMCR);
197
- if (ret >= 0) {
198
- bmcr = ret;
199
- ret = phy_write(phydev, MII_BMCR,
200
- bmcr | BMCR_ISOLATE);
201
- }
202
- if (ret) {
203
- netdev_err(dev, "failed to isolate PHY\n");
204
- return ret;
205
- }
206
- }
207
- /* Switch MAC clocking to RGMII generated clock */
208
- bcmgenet_sys_writel(priv, PORT_MODE_EXT_GPHY, SYS_PORT_CTRL);
209
- /* Ensure 5 clks with Rx disabled
210
- * followed by 5 clks with Reset asserted
211
- */
212
- udelay(4);
213
- reg &= ~(CMD_SW_RESET | CMD_LCL_LOOP_EN);
214
- bcmgenet_umac_writel(priv, reg, UMAC_CMD);
215
- /* Ensure 5 more clocks before Rx is enabled */
216
- udelay(2);
217
- }
218
-
219
- priv->ext_phy = !priv->internal_phy &&
220
- (priv->phy_interface != PHY_INTERFACE_MODE_MOCA);
221182
222183 switch (priv->phy_interface) {
223184 case PHY_INTERFACE_MODE_INTERNAL:
185
+ phy_name = "internal PHY";
186
+ fallthrough;
224187 case PHY_INTERFACE_MODE_MOCA:
225188 /* Irrespective of the actually configured PHY speed (100 or
226189 * 1000) GENETv4 only has an internal GPHY so we will just end
....@@ -232,24 +195,18 @@
232195 else
233196 port_ctrl = PORT_MODE_INT_EPHY;
234197
235
- bcmgenet_sys_writel(priv, port_ctrl, SYS_PORT_CTRL);
236
-
237
- if (priv->internal_phy) {
238
- phy_name = "internal PHY";
239
- } else if (priv->phy_interface == PHY_INTERFACE_MODE_MOCA) {
198
+ if (!phy_name) {
240199 phy_name = "MoCA";
200
+ if (!GENET_IS_V5(priv))
201
+ port_ctrl |= LED_ACT_SOURCE_MAC;
241202 bcmgenet_moca_phy_setup(priv);
242203 }
243204 break;
244205
245206 case PHY_INTERFACE_MODE_MII:
246207 phy_name = "external MII";
247
- phydev->supported &= PHY_BASIC_FEATURES;
248
- bcmgenet_sys_writel(priv,
249
- PORT_MODE_EXT_EPHY, SYS_PORT_CTRL);
250
- /* Restore the MII PHY after isolation */
251
- if (bmcr >= 0)
252
- phy_write(phydev, MII_BMCR, bmcr);
208
+ phy_set_max_speed(phydev, SPEED_100);
209
+ port_ctrl = PORT_MODE_EXT_EPHY;
253210 break;
254211
255212 case PHY_INTERFACE_MODE_REVMII:
....@@ -259,40 +216,50 @@
259216 * capabilities, use that knowledge to also configure the
260217 * Reverse MII interface correctly.
261218 */
262
- if (dev->phydev->supported & PHY_1000BT_FEATURES)
219
+ if (linkmode_test_bit(ETHTOOL_LINK_MODE_1000baseT_Full_BIT,
220
+ dev->phydev->supported))
263221 port_ctrl = PORT_MODE_EXT_RVMII_50;
264222 else
265223 port_ctrl = PORT_MODE_EXT_RVMII_25;
266
- bcmgenet_sys_writel(priv, port_ctrl, SYS_PORT_CTRL);
267224 break;
268225
269226 case PHY_INTERFACE_MODE_RGMII:
270227 /* RGMII_NO_ID: TXC transitions at the same time as TXD
271228 * (requires PCB or receiver-side delay)
272
- * RGMII: Add 2ns delay on TXC (90 degree shift)
273229 *
274230 * ID is implicitly disabled for 100Mbps (RG)MII operation.
275231 */
232
+ phy_name = "external RGMII (no delay)";
276233 id_mode_dis = BIT(16);
277
- /* fall through */
234
+ port_ctrl = PORT_MODE_EXT_GPHY;
235
+ break;
236
+
278237 case PHY_INTERFACE_MODE_RGMII_TXID:
279
- if (id_mode_dis)
280
- phy_name = "external RGMII (no delay)";
281
- else
282
- phy_name = "external RGMII (TX delay)";
283
- bcmgenet_sys_writel(priv,
284
- PORT_MODE_EXT_GPHY, SYS_PORT_CTRL);
238
+ /* RGMII_TXID: Add 2ns delay on TXC (90 degree shift) */
239
+ phy_name = "external RGMII (TX delay)";
240
+ port_ctrl = PORT_MODE_EXT_GPHY;
241
+ break;
242
+
243
+ case PHY_INTERFACE_MODE_RGMII_RXID:
244
+ phy_name = "external RGMII (RX delay)";
245
+ port_ctrl = PORT_MODE_EXT_GPHY;
285246 break;
286247 default:
287248 dev_err(kdev, "unknown phy mode: %d\n", priv->phy_interface);
288249 return -EINVAL;
289250 }
290251
252
+ bcmgenet_sys_writel(priv, port_ctrl, SYS_PORT_CTRL);
253
+
254
+ priv->ext_phy = !priv->internal_phy &&
255
+ (priv->phy_interface != PHY_INTERFACE_MODE_MOCA);
256
+
291257 /* This is an external PHY (xMII), so we need to enable the RGMII
292258 * block for the interface to work
293259 */
294260 if (priv->ext_phy) {
295261 reg = bcmgenet_ext_readl(priv, EXT_RGMII_OOB_CTRL);
262
+ reg &= ~ID_MODE_DIS;
296263 reg |= id_mode_dis;
297264 if (GENET_IS_V1(priv) || GENET_IS_V2(priv) || GENET_IS_V3(priv))
298265 reg |= RGMII_MODE_EN_V123;
....@@ -310,7 +277,8 @@
310277 int bcmgenet_mii_probe(struct net_device *dev)
311278 {
312279 struct bcmgenet_priv *priv = netdev_priv(dev);
313
- struct device_node *dn = priv->pdev->dev.of_node;
280
+ struct device *kdev = &priv->pdev->dev;
281
+ struct device_node *dn = kdev->of_node;
314282 struct phy_device *phydev;
315283 u32 phy_flags = 0;
316284 int ret;
....@@ -333,7 +301,27 @@
333301 return -ENODEV;
334302 }
335303 } else {
336
- phydev = dev->phydev;
304
+ if (has_acpi_companion(kdev)) {
305
+ char mdio_bus_id[MII_BUS_ID_SIZE];
306
+ struct mii_bus *unimacbus;
307
+
308
+ snprintf(mdio_bus_id, MII_BUS_ID_SIZE, "%s-%d",
309
+ UNIMAC_MDIO_DRV_NAME, priv->pdev->id);
310
+
311
+ unimacbus = mdio_find_bus(mdio_bus_id);
312
+ if (!unimacbus) {
313
+ pr_err("Unable to find mii\n");
314
+ return -ENODEV;
315
+ }
316
+ phydev = phy_find_first(unimacbus);
317
+ put_device(&unimacbus->dev);
318
+ if (!phydev) {
319
+ pr_err("Unable to find PHY\n");
320
+ return -ENODEV;
321
+ }
322
+ } else {
323
+ phydev = dev->phydev;
324
+ }
337325 phydev->dev_flags = phy_flags;
338326
339327 ret = phy_connect_direct(dev, phydev, bcmgenet_mii_setup,
....@@ -355,7 +343,7 @@
355343 return ret;
356344 }
357345
358
- phydev->advertising = phydev->supported;
346
+ linkmode_copy(phydev->advertising, phydev->supported);
359347
360348 /* The internal PHY has its link interrupts routed to the
361349 * Ethernet MAC ISRs. On GENETv5 there is a hardware issue
....@@ -458,9 +446,12 @@
458446 /* Retain this platform_device pointer for later cleanup */
459447 priv->mii_pdev = ppdev;
460448 ppdev->dev.parent = &pdev->dev;
461
- ppdev->dev.of_node = bcmgenet_mii_of_find_mdio(priv);
462
- if (pdata)
449
+ if (dn)
450
+ ppdev->dev.of_node = bcmgenet_mii_of_find_mdio(priv);
451
+ else if (pdata)
463452 bcmgenet_mii_pdata_init(priv, &ppd);
453
+ else
454
+ ppd.phy_mask = ~0;
464455
465456 ret = platform_device_add_resources(ppdev, &res, 1);
466457 if (ret)
....@@ -480,12 +471,33 @@
480471 return ret;
481472 }
482473
474
+static int bcmgenet_phy_interface_init(struct bcmgenet_priv *priv)
475
+{
476
+ struct device *kdev = &priv->pdev->dev;
477
+ int phy_mode = device_get_phy_mode(kdev);
478
+
479
+ if (phy_mode < 0) {
480
+ dev_err(kdev, "invalid PHY mode property\n");
481
+ return phy_mode;
482
+ }
483
+
484
+ priv->phy_interface = phy_mode;
485
+
486
+ /* We need to specifically look up whether this PHY interface is
487
+ * internal or not *before* we even try to probe the PHY driver
488
+ * over MDIO as we may have shut down the internal PHY for power
489
+ * saving purposes.
490
+ */
491
+ if (priv->phy_interface == PHY_INTERFACE_MODE_INTERNAL)
492
+ priv->internal_phy = true;
493
+
494
+ return 0;
495
+}
496
+
483497 static int bcmgenet_mii_of_init(struct bcmgenet_priv *priv)
484498 {
485499 struct device_node *dn = priv->pdev->dev.of_node;
486
- struct device *kdev = &priv->pdev->dev;
487500 struct phy_device *phydev;
488
- int phy_mode;
489501 int ret;
490502
491503 /* Fetch the PHY phandle */
....@@ -503,23 +515,12 @@
503515 }
504516
505517 /* Get the link mode */
506
- phy_mode = of_get_phy_mode(dn);
507
- if (phy_mode < 0) {
508
- dev_err(kdev, "invalid PHY mode property\n");
509
- return phy_mode;
510
- }
511
-
512
- priv->phy_interface = phy_mode;
513
-
514
- /* We need to specifically look up whether this PHY interface is internal
515
- * or not *before* we even try to probe the PHY driver over MDIO as we
516
- * may have shut down the internal PHY for power saving purposes.
517
- */
518
- if (priv->phy_interface == PHY_INTERFACE_MODE_INTERNAL)
519
- priv->internal_phy = true;
518
+ ret = bcmgenet_phy_interface_init(priv);
519
+ if (ret)
520
+ return ret;
520521
521522 /* Make sure we initialize MoCA PHYs with a link down */
522
- if (phy_mode == PHY_INTERFACE_MODE_MOCA) {
523
+ if (priv->phy_interface == PHY_INTERFACE_MODE_MOCA) {
523524 phydev = of_phy_find_device(dn);
524525 if (phydev) {
525526 phydev->link = 0;
....@@ -566,8 +567,8 @@
566567 .asym_pause = 0,
567568 };
568569
569
- phydev = fixed_phy_register(PHY_POLL, &fphy_status, -1, NULL);
570
- if (!phydev || IS_ERR(phydev)) {
570
+ phydev = fixed_phy_register(PHY_POLL, &fphy_status, NULL);
571
+ if (IS_ERR(phydev)) {
571572 dev_err(kdev, "failed to register fixed PHY device\n");
572573 return -ENODEV;
573574 }
....@@ -584,10 +585,13 @@
584585
585586 static int bcmgenet_mii_bus_init(struct bcmgenet_priv *priv)
586587 {
587
- struct device_node *dn = priv->pdev->dev.of_node;
588
+ struct device *kdev = &priv->pdev->dev;
589
+ struct device_node *dn = kdev->of_node;
588590
589591 if (dn)
590592 return bcmgenet_mii_of_init(priv);
593
+ else if (has_acpi_companion(kdev))
594
+ return bcmgenet_phy_interface_init(priv);
591595 else
592596 return bcmgenet_mii_pd_init(priv);
593597 }
....@@ -620,5 +624,7 @@
620624 if (of_phy_is_fixed_link(dn))
621625 of_phy_deregister_fixed_link(dn);
622626 of_node_put(priv->phy_dn);
627
+ clk_prepare_enable(priv->clk);
623628 platform_device_unregister(priv->mii_pdev);
629
+ clk_disable_unprepare(priv->clk);
624630 }