summaryrefslogtreecommitdiff
path: root/drivers/net/ethernet/marvell/mvneta.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/net/ethernet/marvell/mvneta.c')
-rw-r--r--drivers/net/ethernet/marvell/mvneta.c72
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,