lists.openwall.net | lists / announce owl-users owl-dev john-users john-dev passwdqc-users yescrypt popa3d-users / oss-security kernel-hardening musl sabotage tlsify passwords / crypt-dev xvendor / Bugtraq Full-Disclosure linux-kernel linux-netdev linux-ext4 linux-hardening PHC | |
Open Source and information security mailing list archives
| ||
|
Date: Mon, 17 Feb 2020 11:43:48 +0100 From: Alexandre Belloni <alexandre.belloni@...tlin.com> To: "David S. Miller" <davem@...emloft.net>, Nicolas Ferre <nicolas.ferre@...rochip.com>, Antoine Ténart <antoine.tenart@...tlin.com> Cc: netdev@...r.kernel.org, linux-arm-kernel@...ts.infradead.org, linux-kernel@...r.kernel.org, Alexandre Belloni <alexandre.belloni@...tlin.com> Subject: [PATCH net] net: macb: Properly handle phylink on at91rm9200 at91ether_init was handling the phy mode and speed but since the switch to phylink, the NCFGR register got overwritten by macb_mac_config(). Add new phylink callbacks to handle emac and at91rm9200 properly. Fixes: 7897b071ac3b ("net: macb: convert to phylink") Signed-off-by: Alexandre Belloni <alexandre.belloni@...tlin.com> --- drivers/net/ethernet/cadence/macb.h | 1 + drivers/net/ethernet/cadence/macb_main.c | 81 +++++++++++++++++++++--- 2 files changed, 73 insertions(+), 9 deletions(-) diff --git a/drivers/net/ethernet/cadence/macb.h b/drivers/net/ethernet/cadence/macb.h index dbf7070fcdba..a3f0f27fc79a 100644 --- a/drivers/net/ethernet/cadence/macb.h +++ b/drivers/net/ethernet/cadence/macb.h @@ -652,6 +652,7 @@ #define MACB_CAPS_GEM_HAS_PTP 0x00000040 #define MACB_CAPS_BD_RD_PREFETCH 0x00000080 #define MACB_CAPS_NEEDS_RSTONUBR 0x00000100 +#define MACB_CAPS_MACB_IS_EMAC 0x08000000 #define MACB_CAPS_FIFO_MODE 0x10000000 #define MACB_CAPS_GIGABIT_MODE_AVAILABLE 0x20000000 #define MACB_CAPS_SG_DISABLED 0x40000000 diff --git a/drivers/net/ethernet/cadence/macb_main.c b/drivers/net/ethernet/cadence/macb_main.c index def94e91883a..529a1d0d7dab 100644 --- a/drivers/net/ethernet/cadence/macb_main.c +++ b/drivers/net/ethernet/cadence/macb_main.c @@ -654,6 +654,72 @@ static const struct phylink_mac_ops macb_phylink_ops = { .mac_link_up = macb_mac_link_up, }; +static void at91ether_mac_config(struct phylink_config *config, + unsigned int mode, + const struct phylink_link_state *state) +{ + struct net_device *ndev = to_net_dev(config->dev); + struct macb *bp = netdev_priv(ndev); + unsigned long flags; + u32 ctrl; + + spin_lock_irqsave(&bp->lock, flags); + + ctrl = MACB_BF(CLK, MACB_CLK_DIV32) | MACB_BIT(BIG); + if (state->speed == SPEED_100) + ctrl |= MACB_BIT(SPD); + + if (state->duplex) + ctrl |= MACB_BIT(FD); + + if (state->interface == PHY_INTERFACE_MODE_RMII) + ctrl |= MACB_BIT(RM9200_RMII); + + macb_writel(bp, NCFGR, ctrl); + + bp->speed = state->speed; + + spin_unlock_irqrestore(&bp->lock, flags); +} + +static void at91ether_mac_link_down(struct phylink_config *config, + unsigned int mode, + phy_interface_t interface) +{ + struct net_device *ndev = to_net_dev(config->dev); + struct macb *bp = netdev_priv(ndev); + u32 ctrl; + + /* Disable Rx and Tx */ + ctrl = macb_readl(bp, NCR) & ~(MACB_BIT(RE) | MACB_BIT(TE)); + macb_writel(bp, NCR, ctrl); + + netif_tx_stop_all_queues(ndev); +} + +static void at91ether_mac_link_up(struct phylink_config *config, + unsigned int mode, + phy_interface_t interface, + struct phy_device *phy) +{ + struct net_device *ndev = to_net_dev(config->dev); + struct macb *bp = netdev_priv(ndev); + + /* Enable Rx and Tx */ + macb_writel(bp, NCR, macb_readl(bp, NCR) | MACB_BIT(RE) | MACB_BIT(TE)); + + netif_tx_wake_all_queues(ndev); +} + +static const struct phylink_mac_ops at91ether_phylink_ops = { + .validate = macb_validate, + .mac_pcs_get_state = macb_mac_pcs_get_state, + .mac_an_restart = macb_mac_an_restart, + .mac_config = at91ether_mac_config, + .mac_link_down = at91ether_mac_link_down, + .mac_link_up = at91ether_mac_link_up, +}; + static bool macb_phy_handle_exists(struct device_node *dn) { dn = of_parse_phandle(dn, "phy-handle", 0); @@ -695,13 +761,17 @@ static int macb_phylink_connect(struct macb *bp) /* based on au1000_eth. c*/ static int macb_mii_probe(struct net_device *dev) { + const struct phylink_mac_ops *phylink_ops = &macb_phylink_ops; struct macb *bp = netdev_priv(dev); + if (bp->caps & MACB_CAPS_MACB_IS_EMAC) + phylink_ops = &at91ether_phylink_ops; + bp->phylink_config.dev = &dev->dev; bp->phylink_config.type = PHYLINK_NETDEV; bp->phylink = phylink_create(&bp->phylink_config, bp->pdev->dev.fwnode, - bp->phy_interface, &macb_phylink_ops); + bp->phy_interface, phylink_ops); if (IS_ERR(bp->phylink)) { netdev_err(dev, "Could not create a phylink instance (%ld)\n", PTR_ERR(bp->phylink)); @@ -4041,7 +4111,6 @@ static int at91ether_init(struct platform_device *pdev) struct net_device *dev = platform_get_drvdata(pdev); struct macb *bp = netdev_priv(dev); int err; - u32 reg; bp->queues[0].bp = bp; @@ -4055,12 +4124,6 @@ static int at91ether_init(struct platform_device *pdev) macb_writel(bp, NCR, 0); - reg = MACB_BF(CLK, MACB_CLK_DIV32) | MACB_BIT(BIG); - if (bp->phy_interface == PHY_INTERFACE_MODE_RMII) - reg |= MACB_BIT(RM9200_RMII); - - macb_writel(bp, NCFGR, reg); - return 0; } @@ -4218,7 +4281,7 @@ static const struct macb_config sama5d4_config = { }; static const struct macb_config emac_config = { - .caps = MACB_CAPS_NEEDS_RSTONUBR, + .caps = MACB_CAPS_NEEDS_RSTONUBR | MACB_CAPS_MACB_IS_EMAC, .clk_init = at91ether_clk_init, .init = at91ether_init, }; -- 2.24.1
Powered by blists - more mailing lists