diff options
Diffstat (limited to 'drivers/net/ethernet/marvell/mvneta.c')
-rw-r--r-- | drivers/net/ethernet/marvell/mvneta.c | 72 |
1 files changed, 45 insertions, 27 deletions
diff --git a/drivers/net/ethernet/marvell/mvneta.c b/drivers/net/ethernet/marvell/mvneta.c index 636effe4bdad..303f0afa9506 100644 --- a/drivers/net/ethernet/marvell/mvneta.c +++ b/drivers/net/ethernet/marvell/mvneta.c @@ -1707,7 +1707,7 @@ static int mvneta_txq_sent_desc_proc(struct mvneta_port *pp, } /* Set TXQ descriptors fields relevant for CSUM calculation */ -static u32 mvneta_txq_desc_csum(int l3_offs, int l3_proto, +static u32 mvneta_txq_desc_csum(int l3_offs, __be16 l3_proto, int ip_hdr_len, int l4_proto) { u32 command; @@ -3779,7 +3779,7 @@ static int mvneta_change_mtu(struct net_device *dev, int mtu) return -EINVAL; } - dev->mtu = mtu; + WRITE_ONCE(dev->mtu, mtu); if (!netif_running(dev)) { if (pp->bm_priv) @@ -3873,8 +3873,8 @@ static int mvneta_set_mac_addr(struct net_device *dev, void *addr) return 0; } -static unsigned int mvneta_pcs_query_inband(struct phylink_pcs *pcs, - phy_interface_t interface) +static unsigned int mvneta_pcs_inband_caps(struct phylink_pcs *pcs, + phy_interface_t interface) { /* When operating in an 802.3z mode, we must have AN enabled: * "Bit 2 Field InBandAnEn In-band Auto-Negotiation enable. ... @@ -3882,7 +3882,7 @@ static unsigned int mvneta_pcs_query_inband(struct phylink_pcs *pcs, * Therefore, inband is "required". */ if (phy_interface_mode_is_8023z(interface)) - return LINK_INBAND_VALID | LINK_INBAND_REQUIRED; + return LINK_INBAND_ENABLE; /* QSGMII, SGMII and RGMII can be configured to use inband * signalling of the AN result. Indicate these as "possible". @@ -3890,10 +3890,10 @@ static unsigned int mvneta_pcs_query_inband(struct phylink_pcs *pcs, if (interface == PHY_INTERFACE_MODE_SGMII || interface == PHY_INTERFACE_MODE_QSGMII || phy_interface_mode_is_rgmii(interface)) - return LINK_INBAND_VALID | LINK_INBAND_POSSIBLE; + return LINK_INBAND_DISABLE | LINK_INBAND_ENABLE; /* For any other modes, indicate that inband is not supported. */ - return LINK_INBAND_VALID; + return LINK_INBAND_DISABLE; } static int mvneta_pcs_config(struct phylink_pcs *pcs, unsigned int neg_mode, @@ -3909,7 +3909,7 @@ static int mvneta_pcs_config(struct phylink_pcs *pcs, unsigned int neg_mode, } static const struct phylink_pcs_ops mvneta_phylink_pcs_ops = { - .pcs_query_inband = mvneta_pcs_query_inband, + .pcs_inband_caps = mvneta_pcs_inband_caps, .pcs_get_state = mvgmac_pcs_get_state, .pcs_config = mvneta_pcs_config, .pcs_an_restart = mvgmac_pcs_an_restart, @@ -4013,20 +4013,27 @@ static void mvneta_mac_link_up(struct phylink_config *config, mvneta_port_up(pp); } -static void mvneta_mac_disable_tx_lpi(struct phylink_config *config) +static void mvneta_mac_disable_tx_lpi(struct phylink_config *config, + phy_interface_t interface) { struct mvneta_port *pp = netdev_priv(to_net_dev(config->dev)); - mvgmac_set_eee(&pp->gmac, false); + mvgmac_disable_lpi(&pp->gmac); } -static void mvneta_mac_enable_tx_lpi(struct phylink_config *config, u32 timer) +static int mvneta_mac_enable_tx_lpi(struct phylink_config *config, + phy_interface_t interface, u32 timer, + bool tx_clk_stop) { struct mvneta_port *pp = netdev_priv(to_net_dev(config->dev)); - mvgmac_set_eee(&pp->gmac, false); - mvgmac_set_lpi_timers(&pp->gmac, timer); - mvgmac_set_eee(&pp->gmac, true); + if (interface != PHY_INTERFACE_MODE_SGMII && + interface != PHY_INTERFACE_MODE_QSGMII) + return -EOPNOTSUPP; + + mvgmac_enable_lpi(&pp->gmac, timer); + + return 0; } static const struct phylink_mac_ops mvneta_phylink_ops = { @@ -4125,6 +4132,7 @@ static int mvneta_cpu_online(unsigned int cpu, struct hlist_node *node) if (pp->neta_armada3700) return 0; + netdev_lock(port->napi.dev); spin_lock(&pp->lock); /* * Configuring the driver for a new CPU while the driver is @@ -4132,6 +4140,7 @@ static int mvneta_cpu_online(unsigned int cpu, struct hlist_node *node) */ if (pp->is_stopped) { spin_unlock(&pp->lock); + netdev_unlock(port->napi.dev); return 0; } netif_tx_stop_all_queues(pp->dev); @@ -4151,7 +4160,7 @@ static int mvneta_cpu_online(unsigned int cpu, struct hlist_node *node) /* Mask all ethernet port interrupts */ on_each_cpu(mvneta_percpu_mask_interrupt, pp, true); - napi_enable(&port->napi); + napi_enable_locked(&port->napi); /* * Enable per-CPU interrupts on the CPU that is @@ -4172,6 +4181,8 @@ static int mvneta_cpu_online(unsigned int cpu, struct hlist_node *node) MVNETA_CAUSE_LINK_CHANGE); netif_tx_start_all_queues(pp->dev); spin_unlock(&pp->lock); + netdev_unlock(port->napi.dev); + return 0; } @@ -4535,11 +4546,9 @@ static void mvneta_ethtool_get_strings(struct net_device *netdev, u32 sset, int i; for (i = 0; i < ARRAY_SIZE(mvneta_statistics); i++) - memcpy(data + i * ETH_GSTRING_LEN, - mvneta_statistics[i].name, ETH_GSTRING_LEN); + ethtool_puts(&data, mvneta_statistics[i].name); if (!pp->bm_priv) { - data += ETH_GSTRING_LEN * ARRAY_SIZE(mvneta_statistics); page_pool_ethtool_stats_get_strings(data); } } @@ -4838,7 +4847,7 @@ static int mvneta_ethtool_set_wol(struct net_device *dev, } static int mvneta_ethtool_get_eee(struct net_device *dev, - struct ethtool_eee *eee) + struct ethtool_keee *eee) { struct mvneta_port *pp = netdev_priv(dev); @@ -4846,10 +4855,16 @@ static int mvneta_ethtool_get_eee(struct net_device *dev, } static int mvneta_ethtool_set_eee(struct net_device *dev, - struct ethtool_eee *eee) + struct ethtool_keee *eee) { struct mvneta_port *pp = netdev_priv(dev); + /* The Armada 37x documents do not give limits for this other than + * it being an 8-bit register. + */ + if (eee->tx_lpi_enabled && eee->tx_lpi_timer > 255) + return -EINVAL; + return phylink_ethtool_set_eee(pp->phylink, eee); } @@ -5163,6 +5178,9 @@ static int mvneta_port_power_up(struct mvneta_port *pp, int phy_mode) !phy_interface_mode_is_rgmii(phy_mode)) return -EINVAL; + /* Ensure LPI is disabled */ + mvneta_mac_disable_tx_lpi(&pp->phylink_config, phy_mode); + return 0; } @@ -5255,8 +5273,13 @@ static int mvneta_probe(struct platform_device *pdev) pp->phylink_config.type = PHYLINK_NETDEV; pp->phylink_config.mac_capabilities = MAC_SYM_PAUSE | MAC_10 | MAC_100 | MAC_1000FD | MAC_2500FD; + + /* Setup EEE. Choose 250us idle. Only supported in SGMII modes. */ + __set_bit(PHY_INTERFACE_MODE_QSGMII, pp->phylink_config.lpi_interfaces); + __set_bit(PHY_INTERFACE_MODE_SGMII, pp->phylink_config.lpi_interfaces); pp->phylink_config.lpi_capabilities = MAC_100FD | MAC_1000FD; - pp->phylink_config.lpi_timer_limit_us = 255; + pp->phylink_config.lpi_timer_default = 250; + pp->phylink_config.eee_enabled_default = true; phy_interface_set_rgmii(pp->phylink_config.supported_interfaces); __set_bit(PHY_INTERFACE_MODE_QSGMII, @@ -5284,11 +5307,6 @@ static int mvneta_probe(struct platform_device *pdev) pp->phylink_config.supported_interfaces); } - /* Setup EEE. Choose 250us idle. */ - pp->phylink_config.eee.eee_enabled = true; - pp->phylink_config.eee.tx_lpi_enabled = true; - pp->phylink_config.eee.tx_lpi_timer = 250; - phylink = phylink_create(&pp->phylink_config, pdev->dev.fwnode, phy_mode, &mvneta_phylink_ops); if (IS_ERR(phylink)) { @@ -5607,7 +5625,7 @@ MODULE_DEVICE_TABLE(of, mvneta_match); static struct platform_driver mvneta_driver = { .probe = mvneta_probe, - .remove_new = mvneta_remove, + .remove = mvneta_remove, .driver = { .name = MVNETA_DRIVER_NAME, .of_match_table = mvneta_match, |