Skip to content

Commit 71e6b15

Browse files
author
Paolo Abeni
committed
Merge branch 'net-dsa-lantiq-a-bunch-of-fixes'
Daniel Golle says: ==================== net: dsa: lantiq: a bunch of fixes This series is the continuation and result of comments received for a fix for the SGMII restart-an bit not actually being self-clearing, which was reported by by Rasmus Villemoes. A closer investigation and testing the .remove and the .shutdown paths of the mxl-gsw1xx.c and lantiq_gswip.c drivers has revealed a couple of existing problems, which are also addressed in this series. ==================== Link: https://patch.msgid.link/cover.1765241054.git.daniel@makrotopia.org Signed-off-by: Paolo Abeni <pabeni@redhat.com>
2 parents 7b07be1 + 7b103aa commit 71e6b15

File tree

4 files changed

+44
-18
lines changed

4 files changed

+44
-18
lines changed

drivers/net/dsa/lantiq/lantiq_gswip.c

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -444,9 +444,6 @@ static void gswip_remove(struct platform_device *pdev)
444444
if (!priv)
445445
return;
446446

447-
/* disable the switch */
448-
gswip_disable_switch(priv);
449-
450447
dsa_unregister_switch(priv->ds);
451448

452449
for (i = 0; i < priv->num_gphy_fw; i++)

drivers/net/dsa/lantiq/lantiq_gswip.h

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -294,8 +294,6 @@ struct gswip_priv {
294294
u16 version;
295295
};
296296

297-
void gswip_disable_switch(struct gswip_priv *priv);
298-
299297
int gswip_probe_common(struct gswip_priv *priv, u32 version);
300298

301299
#endif /* __LANTIQ_GSWIP_H */

drivers/net/dsa/lantiq/lantiq_gswip_common.c

Lines changed: 10 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -752,6 +752,13 @@ static int gswip_setup(struct dsa_switch *ds)
752752
return 0;
753753
}
754754

755+
static void gswip_teardown(struct dsa_switch *ds)
756+
{
757+
struct gswip_priv *priv = ds->priv;
758+
759+
regmap_clear_bits(priv->mdio, GSWIP_MDIO_GLOB, GSWIP_MDIO_GLOB_ENABLE);
760+
}
761+
755762
static enum dsa_tag_protocol gswip_get_tag_protocol(struct dsa_switch *ds,
756763
int port,
757764
enum dsa_tag_protocol mp)
@@ -1629,6 +1636,7 @@ static const struct phylink_mac_ops gswip_phylink_mac_ops = {
16291636
static const struct dsa_switch_ops gswip_switch_ops = {
16301637
.get_tag_protocol = gswip_get_tag_protocol,
16311638
.setup = gswip_setup,
1639+
.teardown = gswip_teardown,
16321640
.port_setup = gswip_port_setup,
16331641
.port_enable = gswip_port_enable,
16341642
.port_disable = gswip_port_disable,
@@ -1656,12 +1664,6 @@ static const struct dsa_switch_ops gswip_switch_ops = {
16561664
.port_hsr_leave = dsa_port_simple_hsr_leave,
16571665
};
16581666

1659-
void gswip_disable_switch(struct gswip_priv *priv)
1660-
{
1661-
regmap_clear_bits(priv->mdio, GSWIP_MDIO_GLOB, GSWIP_MDIO_GLOB_ENABLE);
1662-
}
1663-
EXPORT_SYMBOL_GPL(gswip_disable_switch);
1664-
16651667
static int gswip_validate_cpu_port(struct dsa_switch *ds)
16661668
{
16671669
struct gswip_priv *priv = ds->priv;
@@ -1718,15 +1720,14 @@ int gswip_probe_common(struct gswip_priv *priv, u32 version)
17181720

17191721
err = gswip_validate_cpu_port(priv->ds);
17201722
if (err)
1721-
goto disable_switch;
1723+
goto unregister_switch;
17221724

17231725
dev_info(priv->dev, "probed GSWIP version %lx mod %lx\n",
17241726
GSWIP_VERSION_REV(version), GSWIP_VERSION_MOD(version));
17251727

17261728
return 0;
17271729

1728-
disable_switch:
1729-
gswip_disable_switch(priv);
1730+
unregister_switch:
17301731
dsa_unregister_switch(priv->ds);
17311732

17321733
return err;

drivers/net/dsa/lantiq/mxl-gsw1xx.c

Lines changed: 34 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -11,10 +11,12 @@
1111

1212
#include <linux/bits.h>
1313
#include <linux/delay.h>
14+
#include <linux/jiffies.h>
1415
#include <linux/module.h>
1516
#include <linux/of_device.h>
1617
#include <linux/of_mdio.h>
1718
#include <linux/regmap.h>
19+
#include <linux/workqueue.h>
1820
#include <net/dsa.h>
1921

2022
#include "lantiq_gswip.h"
@@ -29,6 +31,7 @@ struct gsw1xx_priv {
2931
struct regmap *clk;
3032
struct regmap *shell;
3133
struct phylink_pcs pcs;
34+
struct delayed_work clear_raneg;
3235
phy_interface_t tbi_interface;
3336
struct gswip_priv gswip;
3437
};
@@ -145,7 +148,9 @@ static void gsw1xx_pcs_disable(struct phylink_pcs *pcs)
145148
{
146149
struct gsw1xx_priv *priv = pcs_to_gsw1xx(pcs);
147150

148-
/* Assert SGMII shell reset */
151+
cancel_delayed_work_sync(&priv->clear_raneg);
152+
153+
/* Assert SGMII shell reset (will also clear RANEG bit) */
149154
regmap_set_bits(priv->shell, GSW1XX_SHELL_RST_REQ,
150155
GSW1XX_RST_REQ_SGMII_SHELL);
151156

@@ -428,12 +433,29 @@ static int gsw1xx_pcs_config(struct phylink_pcs *pcs, unsigned int neg_mode,
428433
return 0;
429434
}
430435

436+
static void gsw1xx_pcs_clear_raneg(struct work_struct *work)
437+
{
438+
struct gsw1xx_priv *priv =
439+
container_of(work, struct gsw1xx_priv, clear_raneg.work);
440+
441+
regmap_clear_bits(priv->sgmii, GSW1XX_SGMII_TBI_ANEGCTL,
442+
GSW1XX_SGMII_TBI_ANEGCTL_RANEG);
443+
}
444+
431445
static void gsw1xx_pcs_an_restart(struct phylink_pcs *pcs)
432446
{
433447
struct gsw1xx_priv *priv = pcs_to_gsw1xx(pcs);
434448

449+
cancel_delayed_work_sync(&priv->clear_raneg);
450+
435451
regmap_set_bits(priv->sgmii, GSW1XX_SGMII_TBI_ANEGCTL,
436452
GSW1XX_SGMII_TBI_ANEGCTL_RANEG);
453+
454+
/* despite being documented as self-clearing, the RANEG bit
455+
* sometimes remains set, preventing auto-negotiation from happening.
456+
* MaxLinear advises to manually clear the bit after 10ms.
457+
*/
458+
schedule_delayed_work(&priv->clear_raneg, msecs_to_jiffies(10));
437459
}
438460

439461
static void gsw1xx_pcs_link_up(struct phylink_pcs *pcs,
@@ -636,6 +658,8 @@ static int gsw1xx_probe(struct mdio_device *mdiodev)
636658
if (ret)
637659
return ret;
638660

661+
INIT_DELAYED_WORK(&priv->clear_raneg, gsw1xx_pcs_clear_raneg);
662+
639663
ret = gswip_probe_common(&priv->gswip, version);
640664
if (ret)
641665
return ret;
@@ -648,25 +672,31 @@ static int gsw1xx_probe(struct mdio_device *mdiodev)
648672
static void gsw1xx_remove(struct mdio_device *mdiodev)
649673
{
650674
struct gswip_priv *priv = dev_get_drvdata(&mdiodev->dev);
675+
struct gsw1xx_priv *gsw1xx_priv;
651676

652677
if (!priv)
653678
return;
654679

655-
gswip_disable_switch(priv);
656-
657680
dsa_unregister_switch(priv->ds);
681+
682+
gsw1xx_priv = container_of(priv, struct gsw1xx_priv, gswip);
683+
cancel_delayed_work_sync(&gsw1xx_priv->clear_raneg);
658684
}
659685

660686
static void gsw1xx_shutdown(struct mdio_device *mdiodev)
661687
{
662688
struct gswip_priv *priv = dev_get_drvdata(&mdiodev->dev);
689+
struct gsw1xx_priv *gsw1xx_priv;
663690

664691
if (!priv)
665692
return;
666693

694+
dsa_switch_shutdown(priv->ds);
695+
667696
dev_set_drvdata(&mdiodev->dev, NULL);
668697

669-
gswip_disable_switch(priv);
698+
gsw1xx_priv = container_of(priv, struct gsw1xx_priv, gswip);
699+
cancel_delayed_work_sync(&gsw1xx_priv->clear_raneg);
670700
}
671701

672702
static const struct gswip_hw_info gsw12x_data = {

0 commit comments

Comments
 (0)