Marvell mvpp2 improvements
Subsystems (3)
Russell King - ARM Linux admin
maintainercover Marvell mvpp2 improvements
Hi,
This series primarily cleans up mvpp2, but also fixes a left-over from 91a208f2185a ("net: phylink: propagate resolved link config via mac_link_up()").
Patch 1 introduces some port helpers:
mvpp2_port_supports_xlg() - does the port support the XLG MAC mvpp2_port_supports_rgmii() - does the port support RGMII modes
Patch 2 introduces mvpp2_phylink_to_port(), rather than having repeated
open coding of container_of().
Patch 3 introduces mvpp2_modify(), which reads-modifies-writes a
register - I've converted the phylink specific code to use this helper.
Patch 4 moves the hardware control of the pause modes from
mvpp2_xlg_config() (which is called via the phylink_config method) to mvpp2_mac_link_up() - a change that was missed in the above referenced commit.
drivers/net/ethernet/marvell/mvpp2/mvpp2_main.c | 164 +++++++++++++----------- 1 file changed, 89 insertions(+), 75 deletions(-)
Signature · 2 lines
RMK's Patch system: https://www.armlinux.org.uk/developer/patches/ FTTP is here! 40Mbps down 10Mbps up. Decent connectivity at last!
PATCH 1/4 net: mvpp2: add port support helpers
The mvpp2 code has tests scattered amongst the code to determine whether the port supports the XLG, and whether the port supports RGMII mode.
Rather than having these tests scattered, provide a couple of helper functions, so that future additions can ensure that they get these tests correct.
--- .../net/ethernet/marvell/mvpp2/mvpp2_main.c | 43 ++++++++++++------- 1 file changed, 27 insertions(+), 16 deletions(-)
drivers/net/ethernet/marvell/mvpp2/mvpp2_main.c +27 -16
@@ -1114,6 +1114,17 @@ mvpp2_shared_interrupt_mask_unmask(struct mvpp2_port *port, bool mask) } } +/* Only GOP port 0 has an XLG MAC */ +static bool mvpp2_port_supports_xlg (struct mvpp2_port *port) +{ +return port->gop_id ==0 ; +} + +static bool mvpp2_port_supports_rgmii (struct mvpp2_port *port) +{ +return !(port->priv->hw_version ==MVPP22 && port->gop_id ==0 ); +} +/* Port configuration routines */ static bool mvpp2_is_xlg (phy_interface_t interface) {
@@ -1194,7 +1205,7 @@ static int mvpp22_gop_init(struct mvpp2_port *port)case PHY_INTERFACE_MODE_RGMII_ID :case PHY_INTERFACE_MODE_RGMII_RXID :case PHY_INTERFACE_MODE_RGMII_TXID : -if (port->gop_id ==0 ) +if (!mvpp2_port_supports_rgmii (port)) goto invalid_conf;mvpp22_gop_init_rgmii (port);break ;
@@ -1204,7 +1215,7 @@ static int mvpp22_gop_init(struct mvpp2_port *port)mvpp22_gop_init_sgmii (port);break ;case PHY_INTERFACE_MODE_10GBASER : -if (port->gop_id !=0 ) +if (!mvpp2_port_supports_xlg (port)) goto invalid_conf;mvpp22_gop_init_10gkr (port);break ;
@@ -1246,7 +1257,7 @@ static void mvpp22_gop_unmask_irq(struct mvpp2_port *port)writel (val, port->base +MVPP22_GMAC_INT_SUM_MASK ); } -if (port->gop_id ==0 ) { +if (mvpp2_port_supports_xlg (port)) {/* Enable the XLG/GIG irqs for this port */ val =readl (port->base +MVPP22_XLG_EXT_INT_MASK );if (mvpp2_is_xlg (port->phy_interface))
@@ -1261,7 +1272,7 @@ static void mvpp22_gop_mask_irq(struct mvpp2_port *port) {u32 val; -if (port->gop_id ==0 ) { +if (mvpp2_port_supports_xlg (port)) { val =readl (port->base +MVPP22_XLG_EXT_INT_MASK ); val &= ~(MVPP22_XLG_EXT_INT_MASK_XLG |MVPP22_XLG_EXT_INT_MASK_GIG );
@@ -1290,7 +1301,7 @@ static void mvpp22_gop_setup_irq(struct mvpp2_port *port)writel (val, port->base +MVPP22_GMAC_INT_MASK ); } -if (port->gop_id ==0 ) { +if (mvpp2_port_supports_xlg (port)) { val =readl (port->base +MVPP22_XLG_INT_MASK ); val |=MVPP22_XLG_INT_MASK_LINK ;writel (val, port->base +MVPP22_XLG_INT_MASK );
@@ -1328,8 +1339,8 @@ static void mvpp2_port_enable(struct mvpp2_port *port) {u32 val; -/* Only GOP port 0 has an XLG MAC */ -if (port->gop_id ==0 &&mvpp2_is_xlg (port->phy_interface)) { +if (mvpp2_port_supports_xlg (port) && +mvpp2_is_xlg (port->phy_interface)) { val =readl (port->base +MVPP22_XLG_CTRL0_REG ); val |=MVPP22_XLG_CTRL0_PORT_EN ; val &= ~MVPP22_XLG_CTRL0_MIB_CNT_DIS ;
@@ -1346,8 +1357,8 @@ static void mvpp2_port_disable(struct mvpp2_port *port) {u32 val; -/* Only GOP port 0 has an XLG MAC */ -if (port->gop_id ==0 &&mvpp2_is_xlg (port->phy_interface)) { +if (mvpp2_port_supports_xlg (port) && +mvpp2_is_xlg (port->phy_interface)) { val =readl (port->base +MVPP22_XLG_CTRL0_REG ); val &= ~MVPP22_XLG_CTRL0_PORT_EN ;writel (val, port->base +MVPP22_XLG_CTRL0_REG );
@@ -2740,7 +2751,8 @@ static irqreturn_t mvpp2_link_status_isr(int irq, void *dev_id)mvpp22_gop_mask_irq (port); -if (port->gop_id ==0 &&mvpp2_is_xlg (port->phy_interface)) { +if (mvpp2_port_supports_xlg (port) && +mvpp2_is_xlg (port->phy_interface)) { val =readl (port->base +MVPP22_XLG_INT_STAT );if (val &MVPP22_XLG_INT_STAT_LINK ) { event = true;
@@ -3430,8 +3442,7 @@ static void mvpp22_mode_reconfigure(struct mvpp2_port *port)mvpp22_pcs_reset_deassert (port); -/* Only GOP port 0 has an XLG MAC */ -if (port->gop_id ==0 ) { +if (mvpp2_port_supports_xlg (port)) { ctrl3 =readl (port->base +MVPP22_XLG_CTRL3_REG ); ctrl3 &= ~MVPP22_XLG_CTRL3_MACMODESELECT_MASK ;
@@ -3443,7 +3454,7 @@ static void mvpp22_mode_reconfigure(struct mvpp2_port *port)writel (ctrl3, port->base +MVPP22_XLG_CTRL3_REG ); } -if (port->gop_id ==0 &&mvpp2_is_xlg (port->phy_interface)) +if (mvpp2_port_supports_xlg (port) &&mvpp2_is_xlg (port->phy_interface))mvpp2_xlg_max_rx_size_set (port);else mvpp2_gmac_max_rx_size_set (port);
@@ -4768,14 +4779,14 @@ static void mvpp2_phylink_validate(struct phylink_config *config,switch (state->interface) {case PHY_INTERFACE_MODE_10GBASER :case PHY_INTERFACE_MODE_XAUI : -if (port->gop_id !=0 ) +if (!mvpp2_port_supports_xlg (port)) goto empty_set;break ;case PHY_INTERFACE_MODE_RGMII :case PHY_INTERFACE_MODE_RGMII_ID :case PHY_INTERFACE_MODE_RGMII_RXID :case PHY_INTERFACE_MODE_RGMII_TXID : -if (port->priv->hw_version ==MVPP22 && port->gop_id ==0 ) +if (!mvpp2_port_supports_rgmii (port)) goto empty_set;break ;default :
@@ -4791,7 +4802,7 @@ static void mvpp2_phylink_validate(struct phylink_config *config,case PHY_INTERFACE_MODE_10GBASER :case PHY_INTERFACE_MODE_XAUI :case PHY_INTERFACE_MODE_NA : -if (port->gop_id ==0 ) { +if (mvpp2_port_supports_xlg (port)) { phylink_set(mask, 10000baseT_Full); phylink_set(mask, 10000baseCR_Full); phylink_set(mask, 10000baseSR_Full);
Signature · 1 line
2.20.1
PATCH 2/4 net: mvpp2: add mvpp2_phylink_to_port() helper
In reply to Russell King - ARM Linux adminAdd a helper to convert the struct phylink_config pointer passed in from phylink to the drivers internal struct mvpp2_port.
--- .../net/ethernet/marvell/mvpp2/mvpp2_main.c | 30 +++++++++---------- 1 file changed, 15 insertions(+), 15 deletions(-)
drivers/net/ethernet/marvell/mvpp2/mvpp2_main.c +15 -15
@@ -4767,12 +4767,17 @@ static void mvpp2_port_copy_mac_addr(struct net_device *dev, struct mvpp2 *priv,eth_hw_addr_random (dev); } +static inline struct mvpp2_port * +mvpp2_phylink_to_port (struct phylink_config *config) +{ + return container_of(config, struct mvpp2_port, phylink_config); +} +static void mvpp2_phylink_validate (struct phylink_config *config,unsigned long *supported,struct phylink_link_state *state) { - struct mvpp2_port *port = container_of(config, struct mvpp2_port, - phylink_config); +struct mvpp2_port *port =mvpp2_phylink_to_port (config);__ETHTOOL_DECLARE_LINK_MODE_MASK (mask) = {0 , };/* Invalid combinations */
@@ -4913,8 +4918,7 @@ static void mvpp2_gmac_pcs_get_state(struct mvpp2_port *port,static void mvpp2_phylink_mac_pcs_get_state (struct phylink_config *config,struct phylink_link_state *state) { - struct mvpp2_port *port = container_of(config, struct mvpp2_port, - phylink_config); +struct mvpp2_port *port =mvpp2_phylink_to_port (config);if (port->priv->hw_version ==MVPP22 && port->gop_id ==0 ) {u32 mode =readl (port->base +MVPP22_XLG_CTRL3_REG );
@@ -4931,8 +4935,7 @@ static void mvpp2_phylink_mac_pcs_get_state(struct phylink_config *config,static void mvpp2_mac_an_restart (struct phylink_config *config) { - struct mvpp2_port *port = container_of(config, struct mvpp2_port, - phylink_config); +struct mvpp2_port *port =mvpp2_phylink_to_port (config);u32 val =readl (port->base +MVPP2_GMAC_AUTONEG_CONFIG ); writel(val | MVPP2_GMAC_IN_BAND_RESTART_AN,
@@ -5105,13 +5108,12 @@ static void mvpp2_gmac_config(struct mvpp2_port *port, unsigned int mode,static void mvpp2_mac_config (struct phylink_config *config,unsigned int mode,const struct phylink_link_state *state) { -struct net_device *dev =to_net_dev (config->dev); -struct mvpp2_port *port =netdev_priv (dev); +struct mvpp2_port *port =mvpp2_phylink_to_port (config);bool change_interface = port->phy_interface != state->interface;/* Check for invalid configuration */ if (mvpp2_is_xlg (state->interface) && port->gop_id !=0 ) { -netdev_err (dev,"Invalid mode on %s\n" , dev->name); +netdev_err (port->dev,"Invalid mode on %s\n" , port->dev->name);return ; }
@@ -5151,8 +5153,7 @@ static void mvpp2_mac_link_up(struct phylink_config *config, int speed, int duplex, bool tx_pause, bool rx_pause) { - struct net_device *dev = to_net_dev(config->dev); -struct mvpp2_port *port =netdev_priv (dev); + struct mvpp2_port *port = mvpp2_phylink_to_port(config);u32 val;if (mvpp2_is_xlg (interface)) {
@@ -5199,14 +5200,13 @@ static void mvpp2_mac_link_up(struct phylink_config *config,mvpp2_egress_enable (port);mvpp2_ingress_enable (port); -netif_tx_wake_all_queues (dev); +netif_tx_wake_all_queues (port->dev); }static void mvpp2_mac_link_down (struct phylink_config *config,unsigned int mode,phy_interface_t interface) { -struct net_device *dev =to_net_dev (config->dev); -struct mvpp2_port *port =netdev_priv (dev); +struct mvpp2_port *port =mvpp2_phylink_to_port (config);u32 val;if (!phylink_autoneg_inband (mode)) {
@@ -5223,7 +5223,7 @@ static void mvpp2_mac_link_down(struct phylink_config *config, } } -netif_tx_stop_all_queues (dev); +netif_tx_stop_all_queues (port->dev);mvpp2_egress_disable (port);mvpp2_ingress_disable (port);
Signature · 1 line
2.20.1
David Miller
maintainerRe: [PATCH net-next 2/4] net: mvpp2: add mvpp2_phylink_to_port() helper
From: Russell King <[email protected]>
Date: Thu, 18 Jun 2020 16:38:51 +0100
drivers/net/ethernet/marvell/mvpp2/mvpp2_main.c static void mvpp2_port_copy_mac_addr(struct net_device *dev, struct mvpp2 *priv, · line 4774
Quoted 13 lines
drivers/net/ethernet/marvell/mvpp2/mvpp2_main.c +5
-0@@ -4767,12 +4767,17 @@ static void mvpp2_port_copy_mac_addr(struct net_device *dev, struct mvpp2 *priv,eth_hw_addr_random (dev); } +static inline struct mvpp2_port * +mvpp2_phylink_to_port (struct phylink_config *config) +{ + return container_of(config, struct mvpp2_port, phylink_config); +}
Please don't use inline in foo.c files, thank you.
PATCH 3/4 net: mvpp2: add register modification helper
In reply to Russell King - ARM Linux adminAdd a helper to read-modify-write a register, and use it in the phylink helpers.
--- .../net/ethernet/marvell/mvpp2/mvpp2_main.c | 88 ++++++++++--------- 1 file changed, 46 insertions(+), 42 deletions(-)
drivers/net/ethernet/marvell/mvpp2/mvpp2_main.c +46 -42
@@ -1132,6 +1132,17 @@ static bool mvpp2_is_xlg(phy_interface_t interface) interface ==PHY_INTERFACE_MODE_XAUI ; } +static void mvpp2_modify (void __iomem *ptr,u32 mask,u32 set) +{ +u32 old, val; + + old = val =readl (ptr); + val &= ~mask; + val |= set; +if (old != val) +writel (val, ptr); +} +static void mvpp22_gop_init_rgmii (struct mvpp2_port *port) {struct mvpp2 *priv = port->priv;
@@ -4947,38 +4958,29 @@ static void mvpp2_mac_an_restart(struct phylink_config *config)static void mvpp2_xlg_config (struct mvpp2_port *port,unsigned int mode,const struct phylink_link_state *state) { -u32 old_ctrl0, ctrl0; -u32 old_ctrl4, ctrl4; - - old_ctrl0 = ctrl0 =readl (port->base +MVPP22_XLG_CTRL0_REG ); - old_ctrl4 = ctrl4 =readl (port->base +MVPP22_XLG_CTRL4_REG ); - - ctrl0 |=MVPP22_XLG_CTRL0_MAC_RESET_DIS ; +u32 val; + val =MVPP22_XLG_CTRL0_MAC_RESET_DIS ;if (state->pause &MLO_PAUSE_TX ) - ctrl0 |=MVPP22_XLG_CTRL0_TX_FLOW_CTRL_EN ; -else - ctrl0 &= ~MVPP22_XLG_CTRL0_TX_FLOW_CTRL_EN ; + val |=MVPP22_XLG_CTRL0_TX_FLOW_CTRL_EN ;if (state->pause &MLO_PAUSE_RX ) - ctrl0 |=MVPP22_XLG_CTRL0_RX_FLOW_CTRL_EN ; -else - ctrl0 &= ~MVPP22_XLG_CTRL0_RX_FLOW_CTRL_EN ; - - ctrl4 &= ~(MVPP22_XLG_CTRL4_MACMODSELECT_GMAC | -MVPP22_XLG_CTRL4_EN_IDLE_CHECK ); - ctrl4 |=MVPP22_XLG_CTRL4_FWD_FC |MVPP22_XLG_CTRL4_FWD_PFC ; - -if (old_ctrl0 != ctrl0) -writel (ctrl0, port->base +MVPP22_XLG_CTRL0_REG ); -if (old_ctrl4 != ctrl4) -writel (ctrl4, port->base +MVPP22_XLG_CTRL4_REG ); - -if (!(old_ctrl0 &MVPP22_XLG_CTRL0_MAC_RESET_DIS )) { -while (!(readl (port->base +MVPP22_XLG_CTRL0_REG ) & -MVPP22_XLG_CTRL0_MAC_RESET_DIS )) -continue ; - } + val |=MVPP22_XLG_CTRL0_RX_FLOW_CTRL_EN ; + +mvpp2_modify (port->base +MVPP22_XLG_CTRL0_REG , +MVPP22_XLG_CTRL0_MAC_RESET_DIS | +MVPP22_XLG_CTRL0_TX_FLOW_CTRL_EN | +MVPP22_XLG_CTRL0_RX_FLOW_CTRL_EN , val); +mvpp2_modify (port->base +MVPP22_XLG_CTRL4_REG , +MVPP22_XLG_CTRL4_MACMODSELECT_GMAC | +MVPP22_XLG_CTRL4_EN_IDLE_CHECK | +MVPP22_XLG_CTRL4_FWD_FC |MVPP22_XLG_CTRL4_FWD_PFC , +MVPP22_XLG_CTRL4_FWD_FC |MVPP22_XLG_CTRL4_FWD_PFC ); + +/* Wait for reset to deassert */ +do { + val =readl (port->base +MVPP22_XLG_CTRL0_REG ); + }while (!(val &MVPP22_XLG_CTRL0_MAC_RESET_DIS )); } static void mvpp2_gmac_config(struct mvpp2_port *port, unsigned int mode,
@@ -5158,19 +5160,14 @@ static void mvpp2_mac_link_up(struct phylink_config *config,if (mvpp2_is_xlg (interface)) {if (!phylink_autoneg_inband (mode)) { - val =readl (port->base +MVPP22_XLG_CTRL0_REG ); - val &= ~MVPP22_XLG_CTRL0_FORCE_LINK_DOWN ; - val |=MVPP22_XLG_CTRL0_FORCE_LINK_PASS ; -writel (val, port->base +MVPP22_XLG_CTRL0_REG ); +mvpp2_modify (port->base +MVPP22_XLG_CTRL0_REG , +MVPP22_XLG_CTRL0_FORCE_LINK_DOWN | +MVPP22_XLG_CTRL0_FORCE_LINK_PASS , +MVPP22_XLG_CTRL0_FORCE_LINK_PASS ); } }else {if (!phylink_autoneg_inband (mode)) { - val =readl (port->base +MVPP2_GMAC_AUTONEG_CONFIG ); - val &= ~(MVPP2_GMAC_FORCE_LINK_DOWN | -MVPP2_GMAC_CONFIG_MII_SPEED | -MVPP2_GMAC_CONFIG_GMII_SPEED | -MVPP2_GMAC_CONFIG_FULL_DUPLEX ); - val |=MVPP2_GMAC_FORCE_LINK_PASS ; + val =MVPP2_GMAC_FORCE_LINK_PASS ;if (speed ==SPEED_1000 || speed ==SPEED_2500 ) val |=MVPP2_GMAC_CONFIG_GMII_SPEED ;
@@ -5180,20 +5177,27 @@ static void mvpp2_mac_link_up(struct phylink_config *config,if (duplex ==DUPLEX_FULL ) val |=MVPP2_GMAC_CONFIG_FULL_DUPLEX ; -writel (val, port->base +MVPP2_GMAC_AUTONEG_CONFIG ); +mvpp2_modify (port->base +MVPP2_GMAC_AUTONEG_CONFIG , +MVPP2_GMAC_FORCE_LINK_DOWN | +MVPP2_GMAC_FORCE_LINK_PASS | +MVPP2_GMAC_CONFIG_MII_SPEED | +MVPP2_GMAC_CONFIG_GMII_SPEED | +MVPP2_GMAC_CONFIG_FULL_DUPLEX , val); }/* We can always update the flow control enable bits; * these will only be effective if flow control AN * (MVPP2_GMAC_FLOW_CTRL_AUTONEG) is disabled. */ - val =readl (port->base +MVPP22_GMAC_CTRL_4_REG ); - val &= ~(MVPP22_CTRL4_RX_FC_EN |MVPP22_CTRL4_TX_FC_EN ); + val =0 ;if (tx_pause) val |=MVPP22_CTRL4_TX_FC_EN ;if (rx_pause) val |=MVPP22_CTRL4_RX_FC_EN ; -writel (val, port->base +MVPP22_GMAC_CTRL_4_REG ); + +mvpp2_modify (port->base +MVPP22_GMAC_CTRL_4_REG , +MVPP22_CTRL4_RX_FC_EN |MVPP22_CTRL4_TX_FC_EN , + val); }mvpp2_port_enable (port);
Signature · 1 line
2.20.1
PATCH 4/4 net: mvpp2: set xlg flow control in mvpp2_mac_link_up()
In reply to Russell King - ARM Linux adminSet the flow control settings in mvpp2_mac_link_up() for 10G links just as we do for 1G and slower links. This is now the preferred location.
--- .../net/ethernet/marvell/mvpp2/mvpp2_main.c | 23 +++++++++---------- 1 file changed, 11 insertions(+), 12 deletions(-)
drivers/net/ethernet/marvell/mvpp2/mvpp2_main.c +11 -12
@@ -4960,17 +4960,9 @@ static void mvpp2_xlg_config(struct mvpp2_port *port, unsigned int mode, {u32 val; - val =MVPP22_XLG_CTRL0_MAC_RESET_DIS ; -if (state->pause &MLO_PAUSE_TX ) - val |=MVPP22_XLG_CTRL0_TX_FLOW_CTRL_EN ; - -if (state->pause &MLO_PAUSE_RX ) - val |=MVPP22_XLG_CTRL0_RX_FLOW_CTRL_EN ; -mvpp2_modify (port->base +MVPP22_XLG_CTRL0_REG , -MVPP22_XLG_CTRL0_MAC_RESET_DIS | -MVPP22_XLG_CTRL0_TX_FLOW_CTRL_EN | -MVPP22_XLG_CTRL0_RX_FLOW_CTRL_EN , val); +MVPP22_XLG_CTRL0_MAC_RESET_DIS , +MVPP22_XLG_CTRL0_MAC_RESET_DIS ); mvpp2_modify(port->base + MVPP22_XLG_CTRL4_REG, MVPP22_XLG_CTRL4_MACMODSELECT_GMAC | MVPP22_XLG_CTRL4_EN_IDLE_CHECK |
@@ -5160,10 +5152,17 @@ static void mvpp2_mac_link_up(struct phylink_config *config,if (mvpp2_is_xlg (interface)) {if (!phylink_autoneg_inband (mode)) { + val =MVPP22_XLG_CTRL0_FORCE_LINK_PASS ; +if (tx_pause) + val |=MVPP22_XLG_CTRL0_TX_FLOW_CTRL_EN ; +if (rx_pause) + val |=MVPP22_XLG_CTRL0_RX_FLOW_CTRL_EN ; +mvpp2_modify (port->base +MVPP22_XLG_CTRL0_REG ,MVPP22_XLG_CTRL0_FORCE_LINK_DOWN | -MVPP22_XLG_CTRL0_FORCE_LINK_PASS , -MVPP22_XLG_CTRL0_FORCE_LINK_PASS ); +MVPP22_XLG_CTRL0_FORCE_LINK_PASS | +MVPP22_XLG_CTRL0_TX_FLOW_CTRL_EN | +MVPP22_XLG_CTRL0_RX_FLOW_CTRL_EN , val); } }else {if (!phylink_autoneg_inband (mode)) {
Signature · 1 line
2.20.1