From 1c2722a975fdb8c90bc6ba8570b7fb62db4e2e9c Mon Sep 17 00:00:00 2001 From: Gregory CLEMENT Date: Sat, 12 Mar 2016 18:44:17 +0100 Subject: [PATCH 1/4] net: mvneta: Fix spinlock usage In the previous patch, the spinlock was not initialized. While it didn't cause any trouble yet it could be a problem to use it uninitialized. The most annoying part was the critical section protected by the spinlock in mvneta_stop(). Some of the functions could sleep as pointed when activated CONFIG_DEBUG_ATOMIC_SLEEP. Actually, in mvneta_stop() we only need to protect the is_stopped flagged, indeed the code of the notifier for CPU online is protected by the same spinlock, so when we get the lock, the notifer work is done. Reported-by: Patrick Uiterwijk Signed-off-by: Gregory CLEMENT Signed-off-by: David S. Miller --- drivers/net/ethernet/marvell/mvneta.c | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/drivers/net/ethernet/marvell/mvneta.c b/drivers/net/ethernet/marvell/mvneta.c index be92668faf3e..665eac2c2469 100644 --- a/drivers/net/ethernet/marvell/mvneta.c +++ b/drivers/net/ethernet/marvell/mvneta.c @@ -3480,17 +3480,17 @@ static int mvneta_stop(struct net_device *dev) struct mvneta_port *pp = netdev_priv(dev); /* Inform that we are stopping so we don't want to setup the - * driver for new CPUs in the notifiers + * driver for new CPUs in the notifiers. The code of the + * notifier for CPU online is protected by the same spinlock, + * so when we get the lock, the notifer work is done. */ spin_lock(&pp->lock); pp->is_stopped = true; + spin_unlock(&pp->lock); + mvneta_stop_dev(pp); mvneta_mdio_remove(pp); unregister_cpu_notifier(&pp->cpu_notifier); - /* Now that the notifier are unregistered, we can release le - * lock - */ - spin_unlock(&pp->lock); on_each_cpu(mvneta_percpu_disable, pp, true); free_percpu_irq(dev->irq, pp->ports); mvneta_cleanup_rxqs(pp); @@ -4023,6 +4023,7 @@ static int mvneta_probe(struct platform_device *pdev) dev->ethtool_ops = &mvneta_eth_tool_ops; pp = netdev_priv(dev); + spin_lock_init(&pp->lock); pp->phy_node = phy_node; pp->phy_interface = phy_mode; From 928b6519afeb2a5e2dc61154380b545ed66c476a Mon Sep 17 00:00:00 2001 From: Dmitri Epshtein Date: Sat, 12 Mar 2016 18:44:18 +0100 Subject: [PATCH 2/4] net: mvneta: enable change MAC address when interface is up Function eth_prepare_mac_addr_change() is called as part of MAC address change. This function check if interface is running. To enable change MAC address when interface is running: IFF_LIVE_ADDR_CHANGE flag must be set to dev->priv_flags field Fixes: c5aff18204da ("net: mvneta: driver for Marvell Armada 370/XP network unit") Cc: stable@vger.kernel.org Signed-off-by: Dmitri Epshtein Signed-off-by: Gregory CLEMENT Signed-off-by: David S. Miller --- drivers/net/ethernet/marvell/mvneta.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/net/ethernet/marvell/mvneta.c b/drivers/net/ethernet/marvell/mvneta.c index 665eac2c2469..09a306628807 100644 --- a/drivers/net/ethernet/marvell/mvneta.c +++ b/drivers/net/ethernet/marvell/mvneta.c @@ -4145,7 +4145,7 @@ static int mvneta_probe(struct platform_device *pdev) dev->features = NETIF_F_SG | NETIF_F_IP_CSUM | NETIF_F_TSO; dev->hw_features |= dev->features; dev->vlan_features |= dev->features; - dev->priv_flags |= IFF_UNICAST_FLT; + dev->priv_flags |= IFF_UNICAST_FLT | IFF_LIVE_ADDR_CHANGE; dev->gso_max_segs = MVNETA_MAX_TSO_SEGS; err = register_netdev(dev); From 0838abb3c08cff83719b461adffefc83721af34b Mon Sep 17 00:00:00 2001 From: Dmitri Epshtein Date: Sat, 12 Mar 2016 18:44:19 +0100 Subject: [PATCH 3/4] net: mvneta: fix error messages in mvneta_port_down function This commit corrects error printing when shutting down the port. [gregory.clement@free-electrons.com: split initial commit in two individual changes] Signed-off-by: Dmitri Epshtein Signed-off-by: Gregory CLEMENT Signed-off-by: David S. Miller --- drivers/net/ethernet/marvell/mvneta.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/net/ethernet/marvell/mvneta.c b/drivers/net/ethernet/marvell/mvneta.c index 09a306628807..1af60bdea051 100644 --- a/drivers/net/ethernet/marvell/mvneta.c +++ b/drivers/net/ethernet/marvell/mvneta.c @@ -1107,7 +1107,7 @@ static void mvneta_port_down(struct mvneta_port *pp) do { if (count++ >= MVNETA_RX_DISABLE_TIMEOUT_MSEC) { netdev_warn(pp->dev, - "TIMEOUT for RX stopped ! rx_queue_cmd: 0x08%x\n", + "TIMEOUT for RX stopped ! rx_queue_cmd: 0x%08x\n", val); break; } @@ -1146,7 +1146,7 @@ static void mvneta_port_down(struct mvneta_port *pp) do { if (count++ >= MVNETA_TX_FIFO_EMPTY_TIMEOUT) { netdev_warn(pp->dev, - "TX FIFO empty timeout status=0x08%x\n", + "TX FIFO empty timeout status=0x%08x\n", val); break; } From a3703fb31a4779e5c515f51f602dda1ffcfbfec9 Mon Sep 17 00:00:00 2001 From: Dmitri Epshtein Date: Sat, 12 Mar 2016 18:44:20 +0100 Subject: [PATCH 4/4] net: mvneta: replace magic numbers by existing macros Some literal values are actually already defined by macros, so let's use them. [gregory.clement@free-electrons.com: split intial commit in two individual changes] Signed-off-by: Dmitri Epshtein Signed-off-by: Gregory CLEMENT Signed-off-by: David S. Miller --- drivers/net/ethernet/marvell/mvneta.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/net/ethernet/marvell/mvneta.c b/drivers/net/ethernet/marvell/mvneta.c index 1af60bdea051..577f7ca7deba 100644 --- a/drivers/net/ethernet/marvell/mvneta.c +++ b/drivers/net/ethernet/marvell/mvneta.c @@ -1114,7 +1114,7 @@ static void mvneta_port_down(struct mvneta_port *pp) mdelay(1); val = mvreg_read(pp, MVNETA_RXQ_CMD); - } while (val & 0xff); + } while (val & MVNETA_RXQ_ENABLE_MASK); /* Stop Tx port activity. Check port Tx activity. Issue stop * command for active channels only @@ -1139,7 +1139,7 @@ static void mvneta_port_down(struct mvneta_port *pp) /* Check TX Command reg that all Txqs are stopped */ val = mvreg_read(pp, MVNETA_TXQ_CMD); - } while (val & 0xff); + } while (val & MVNETA_TXQ_ENABLE_MASK); /* Double check to verify that TX FIFO is empty */ count = 0;