diff mbox series

[SRU,F,PULL,v2,19/23] Revert "UBUNTU: SAUCE: mlxbf-gige: multiple fixes for stability"

Message ID 20210709190830.5405-20-asmaa@nvidia.com
State New
Headers show
Series Cherry-pick the upstreamed mlxbf-gige driver | expand

Commit Message

Asmaa Mnebhi July 9, 2021, 7:08 p.m. UTC
BugLink: https://bugs.launchpad.net/bugs/1934923

This reverts commit 1ebccff108540a2134e27abb7d3c12caf9b9810c.

Signed-off-by: Asmaa Mnebhi <asmaa@nvidia.com>
---
 .../net/ethernet/mellanox/mlxbf_gige/Kconfig  |   2 +-
 .../net/ethernet/mellanox/mlxbf_gige/Makefile |   2 +-
 .../ethernet/mellanox/mlxbf_gige/mlxbf_gige.h |  15 +-
 .../mellanox/mlxbf_gige/mlxbf_gige_main.c     | 236 +++++++++---------
 .../mellanox/mlxbf_gige/mlxbf_gige_mdio.c     |  18 +-
 5 files changed, 133 insertions(+), 140 deletions(-)
diff mbox series

Patch

diff --git a/drivers/net/ethernet/mellanox/mlxbf_gige/Kconfig b/drivers/net/ethernet/mellanox/mlxbf_gige/Kconfig
index 73c5d74081ee..60712e2d0a69 100644
--- a/drivers/net/ethernet/mellanox/mlxbf_gige/Kconfig
+++ b/drivers/net/ethernet/mellanox/mlxbf_gige/Kconfig
@@ -1,4 +1,4 @@ 
-# SPDX-License-Identifier: GPL-2.0-only OR Linux-OpenIB
+# SPDX-License-Identifier: GPL-2.0-only
 #
 # Mellanox GigE driver configuration
 #
diff --git a/drivers/net/ethernet/mellanox/mlxbf_gige/Makefile b/drivers/net/ethernet/mellanox/mlxbf_gige/Makefile
index f6be6c692093..165122b9622a 100644
--- a/drivers/net/ethernet/mellanox/mlxbf_gige/Makefile
+++ b/drivers/net/ethernet/mellanox/mlxbf_gige/Makefile
@@ -1,4 +1,4 @@ 
-# SPDX-License-Identifier: GPL-2.0-only OR Linux-OpenIB
+# SPDX-License-Identifier: GPL-2.0-only
 
 obj-$(CONFIG_MLXBF_GIGE) += mlxbf_gige.o
 
diff --git a/drivers/net/ethernet/mellanox/mlxbf_gige/mlxbf_gige.h b/drivers/net/ethernet/mellanox/mlxbf_gige/mlxbf_gige.h
index adbdc90ddae4..31213c47919c 100644
--- a/drivers/net/ethernet/mellanox/mlxbf_gige/mlxbf_gige.h
+++ b/drivers/net/ethernet/mellanox/mlxbf_gige/mlxbf_gige.h
@@ -13,13 +13,8 @@ 
 #include <linux/irqreturn.h>
 #include <linux/netdevice.h>
 
-/* The silicon design supports a maximum RX ring size of
- * 32K entries. Based on current testing this maximum size
- * is not required to be supported.  Instead the RX ring
- * will be capped at a realistic value of 1024 entries.
- */
 #define MLXBF_GIGE_MIN_RXQ_SZ     32
-#define MLXBF_GIGE_MAX_RXQ_SZ     1024
+#define MLXBF_GIGE_MAX_RXQ_SZ     32768
 #define MLXBF_GIGE_DEFAULT_RXQ_SZ 128
 
 #define MLXBF_GIGE_MIN_TXQ_SZ     4
@@ -28,6 +23,9 @@ 
 
 #define MLXBF_GIGE_DEFAULT_BUF_SZ 2048
 
+/* Known pattern for initial state of RX buffers */
+#define MLXBF_GIGE_INIT_BYTE_RX_BUF 0x10
+
 /* There are four individual MAC RX filters. Currently
  * two of them are being used: one for the broadcast MAC
  * (index 0) and one for local MAC (index 1)
@@ -75,7 +73,6 @@  struct mlxbf_gige {
 	void __iomem *gpio_io;
 	void __iomem *cause_rsh_coalesce0_io;
 	void __iomem *cause_gpio_arm_coalesce0_io;
-	spinlock_t lock;
 	spinlock_t gpio_lock;
 	u16 rx_q_entries;
 	u16 tx_q_entries;
@@ -93,8 +90,8 @@  struct mlxbf_gige {
 	u64 error_intr_count;
 	u64 rx_intr_count;
 	u64 llu_plu_intr_count;
-	u8 *rx_buf[MLXBF_GIGE_MAX_RXQ_SZ];
-	u8 *tx_buf[MLXBF_GIGE_MAX_TXQ_SZ];
+	u8 *rx_buf[MLXBF_GIGE_DEFAULT_RXQ_SZ];
+	u8 *tx_buf[MLXBF_GIGE_DEFAULT_TXQ_SZ];
 	int error_irq;
 	int rx_irq;
 	int llu_plu_irq;
diff --git a/drivers/net/ethernet/mellanox/mlxbf_gige/mlxbf_gige_main.c b/drivers/net/ethernet/mellanox/mlxbf_gige/mlxbf_gige_main.c
index abd3fc661e6f..88b0406c2d9e 100644
--- a/drivers/net/ethernet/mellanox/mlxbf_gige/mlxbf_gige_main.c
+++ b/drivers/net/ethernet/mellanox/mlxbf_gige/mlxbf_gige_main.c
@@ -18,7 +18,7 @@ 
 #include "mlxbf_gige_regs.h"
 
 #define DRV_NAME    "mlxbf_gige"
-#define DRV_VERSION "1.1"
+#define DRV_VERSION "1.0"
 
 static void mlxbf_gige_set_mac_rx_filter(struct mlxbf_gige *priv,
 					 unsigned int index, u64 dmac)
@@ -431,9 +431,6 @@  static void mlxbf_gige_get_ethtool_stats(struct net_device *netdev,
 					 u64 *data)
 {
 	struct mlxbf_gige *priv = netdev_priv(netdev);
-	unsigned long flags;
-
-	spin_lock_irqsave(&priv->lock, flags);
 
 	/* Fill data array with interface statistics
 	 *
@@ -469,8 +466,6 @@  static void mlxbf_gige_get_ethtool_stats(struct net_device *netdev,
 		   readq(priv->base + MLXBF_GIGE_RX_PASS_COUNTER_ALL));
 	*data++ = (priv->stats.rx_filter_discard_pkts +
 		   readq(priv->base + MLXBF_GIGE_RX_DISC_COUNTER_ALL));
-
-	spin_unlock_irqrestore(&priv->lock, flags);
 }
 
 static const struct ethtool_ops mlxbf_gige_ethtool_ops = {
@@ -511,8 +506,9 @@  static irqreturn_t mlxbf_gige_error_intr(int irq, void *dev_id)
 
 	int_status = readq(priv->base + MLXBF_GIGE_INT_STATUS);
 
-	if (int_status & MLXBF_GIGE_INT_STATUS_HW_ACCESS_ERROR)
+	if (int_status & MLXBF_GIGE_INT_STATUS_HW_ACCESS_ERROR) {
 		priv->stats.hw_access_errors++;
+	}
 
 	if (int_status & MLXBF_GIGE_INT_STATUS_TX_CHECKSUM_INPUTS) {
 		priv->stats.tx_invalid_checksums++;
@@ -537,14 +533,17 @@  static irqreturn_t mlxbf_gige_error_intr(int irq, void *dev_id)
 		 */
 	}
 
-	if (int_status & MLXBF_GIGE_INT_STATUS_TX_PI_CI_EXCEED_WQ_SIZE)
+	if (int_status & MLXBF_GIGE_INT_STATUS_TX_PI_CI_EXCEED_WQ_SIZE) {
 		priv->stats.tx_index_errors++;
+	}
 
-	if (int_status & MLXBF_GIGE_INT_STATUS_SW_CONFIG_ERROR)
+	if (int_status & MLXBF_GIGE_INT_STATUS_SW_CONFIG_ERROR) {
 		priv->stats.sw_config_errors++;
+	}
 
-	if (int_status & MLXBF_GIGE_INT_STATUS_SW_ACCESS_ERROR)
+	if (int_status & MLXBF_GIGE_INT_STATUS_SW_ACCESS_ERROR) {
 		priv->stats.sw_access_errors++;
+	}
 
 	/* Clear all error interrupts by writing '1' back to
 	 * all the asserted bits in INT_STATUS.  Do not write
@@ -612,19 +611,13 @@  static irqreturn_t mlxbf_gige_llu_plu_intr(int irq, void *dev_id)
  */
 static u16 mlxbf_gige_tx_buffs_avail(struct mlxbf_gige *priv)
 {
-	unsigned long flags;
 	u16 avail;
 
-	spin_lock_irqsave(&priv->lock, flags);
-
 	if (priv->prev_tx_ci == priv->tx_pi)
 		avail = priv->tx_q_entries - 1;
 	else
 		avail = (((priv->tx_q_entries + priv->prev_tx_ci - priv->tx_pi)
 			  % priv->tx_q_entries) - 1);
-
-	spin_unlock_irqrestore(&priv->lock, flags);
-
 	return avail;
 }
 
@@ -700,29 +693,28 @@  static bool mlxbf_gige_rx_packet(struct mlxbf_gige *priv, int *rx_pkts)
 		/* Packet is OK, increment stats */
 		netdev->stats.rx_packets++;
 		netdev->stats.rx_bytes += datalen;
-
-		skb = dev_alloc_skb(datalen);
-		if (!skb) {
-			netdev->stats.rx_dropped++;
-			return false;
-		}
-
-		memcpy(skb_put(skb, datalen), pktp, datalen);
-
-		skb->dev = netdev;
-		skb->protocol = eth_type_trans(skb, netdev);
-		skb->ip_summed = CHECKSUM_NONE; /* device did not checksum packet */
-
-		netif_receive_skb(skb);
 	} else if (rx_cqe & MLXBF_GIGE_RX_CQE_PKT_STATUS_MAC_ERR) {
 		priv->stats.rx_mac_errors++;
 	} else if (rx_cqe & MLXBF_GIGE_RX_CQE_PKT_STATUS_TRUNCATED) {
 		priv->stats.rx_truncate_errors++;
 	}
 
+	skb = dev_alloc_skb(datalen);
+	if (!skb) {
+		netdev->stats.rx_dropped++;
+		return false;
+	}
+
+	memcpy(skb_put(skb, datalen), pktp, datalen);
+
 	/* Let hardware know we've replenished one buffer */
 	writeq(rx_pi + 1, priv->base + MLXBF_GIGE_RX_WQE_PI);
 
+	skb->dev = netdev;
+	skb->protocol = eth_type_trans(skb, netdev);
+	skb->ip_summed = CHECKSUM_NONE; /* device did not checksum packet */
+
+	netif_receive_skb(skb);
 	(*rx_pkts)++;
 	rx_pi = readq(priv->base + MLXBF_GIGE_RX_WQE_PI);
 	rx_pi_rem = rx_pi % priv->rx_q_entries;
@@ -802,54 +794,15 @@  static void mlxbf_gige_free_irqs(struct mlxbf_gige *priv)
 	devm_free_irq(priv->dev, priv->llu_plu_irq, priv);
 }
 
-static void mlxbf_gige_cache_stats(struct mlxbf_gige *priv)
-{
-	struct mlxbf_gige_stats *p;
-
-	/* Cache stats that will be cleared by clean port operation */
-	p = &priv->stats;
-	p->rx_din_dropped_pkts += readq(priv->base +
-					MLXBF_GIGE_RX_DIN_DROP_COUNTER);
-	p->rx_filter_passed_pkts += readq(priv->base +
-					  MLXBF_GIGE_RX_PASS_COUNTER_ALL);
-	p->rx_filter_discard_pkts += readq(priv->base +
-					   MLXBF_GIGE_RX_DISC_COUNTER_ALL);
-}
-
-static void mlxbf_gige_clean_port(struct mlxbf_gige *priv)
-{
-	u64 control, status;
-	int cnt;
-
-	/* Set the CLEAN_PORT_EN bit to trigger SW reset */
-	control = readq(priv->base + MLXBF_GIGE_CONTROL);
-	control |= MLXBF_GIGE_CONTROL_CLEAN_PORT_EN;
-	writeq(control, priv->base + MLXBF_GIGE_CONTROL);
-
-	/* Loop waiting for status ready bit to assert */
-	cnt = 1000;
-	do {
-		status = readq(priv->base + MLXBF_GIGE_STATUS);
-		if (status & MLXBF_GIGE_STATUS_READY)
-			break;
-		usleep_range(50, 100);
-	} while (--cnt > 0);
-
-	/* Clear the CLEAN_PORT_EN bit at end of this loop */
-	control = readq(priv->base + MLXBF_GIGE_CONTROL);
-	control &= ~MLXBF_GIGE_CONTROL_CLEAN_PORT_EN;
-	writeq(control, priv->base + MLXBF_GIGE_CONTROL);
-}
-
 static int mlxbf_gige_open(struct net_device *netdev)
 {
 	struct mlxbf_gige *priv = netdev_priv(netdev);
-	struct phy_device *phydev = netdev->phydev;
+	struct phy_device *phydev;
 	u64 int_en;
 	int err;
 
-	mlxbf_gige_cache_stats(priv);
-	mlxbf_gige_clean_port(priv);
+	memset(&priv->stats, 0, sizeof(priv->stats));
+
 	mlxbf_gige_rx_init(priv);
 	mlxbf_gige_tx_init(priv);
 	netif_napi_add(netdev, &priv->napi, mlxbf_gige_poll, NAPI_POLL_WEIGHT);
@@ -860,7 +813,40 @@  static int mlxbf_gige_open(struct net_device *netdev)
 	if (err)
 		return err;
 
+	phydev = phy_find_first(priv->mdiobus);
+	if (!phydev)
+		return -EIO;
+
+	/* Sets netdev->phydev to phydev; which will eventually
+	 * be used in ioctl calls.
+	 */
+	err = phy_connect_direct(netdev, phydev,
+				 mlxbf_gige_handle_link_change,
+				 PHY_INTERFACE_MODE_GMII);
+	if (err) {
+		netdev_err(netdev, "Could not attach to PHY\n");
+		return err;
+	}
+
+	/* MAC only supports 1000T full duplex mode */
+	phy_remove_link_mode(phydev, ETHTOOL_LINK_MODE_1000baseT_Half_BIT);
+	phy_remove_link_mode(phydev, ETHTOOL_LINK_MODE_100baseT_Full_BIT);
+	phy_remove_link_mode(phydev, ETHTOOL_LINK_MODE_100baseT_Half_BIT);
+	phy_remove_link_mode(phydev, ETHTOOL_LINK_MODE_10baseT_Full_BIT);
+	phy_remove_link_mode(phydev, ETHTOOL_LINK_MODE_10baseT_Half_BIT);
+
+	/* MAC supports symmetric flow control */
+	phy_support_sym_pause(phydev);
 	phy_start(phydev);
+	err = phy_start_aneg(phydev);
+	if (err < 0) {
+		netdev_err(netdev, "phy_start_aneg failure: 0x%x\n", err);
+		return err;
+	}
+
+	/* Display information about attached PHY device */
+	phy_attached_info(phydev);
+
 
 	/* Set bits in INT_EN that we care about */
 	int_en = MLXBF_GIGE_INT_EN_HW_ACCESS_ERROR |
@@ -875,6 +861,41 @@  static int mlxbf_gige_open(struct net_device *netdev)
 	return 0;
 }
 
+static void mlxbf_gige_clean_port(struct mlxbf_gige *priv)
+{
+	struct mlxbf_gige_stats *p;
+	u64 control, status;
+	int cnt;
+
+	/* Cache stats that will be cleared by clean port operation */
+	p = &priv->stats;
+	p->rx_din_dropped_pkts = readq(priv->base + MLXBF_GIGE_RX_DIN_DROP_COUNTER);
+	p->rx_filter_passed_pkts = readq(priv->base + MLXBF_GIGE_RX_PASS_COUNTER_ALL);
+	p->rx_filter_discard_pkts = readq(priv->base + MLXBF_GIGE_RX_DISC_COUNTER_ALL);
+
+	/* Set the CLEAN_PORT_EN bit to trigger SW reset */
+	control = readq(priv->base + MLXBF_GIGE_CONTROL);
+	control |= MLXBF_GIGE_CONTROL_CLEAN_PORT_EN;
+	writeq(control, priv->base + MLXBF_GIGE_CONTROL);
+
+	/* Create memory barrier before reading status */
+	wmb();
+
+	/* Loop waiting for status ready bit to assert */
+	cnt = 1000;
+	do {
+		status = readq(priv->base + MLXBF_GIGE_STATUS);
+		if (status & MLXBF_GIGE_STATUS_READY)
+			break;
+		usleep_range(50, 100);
+	} while (--cnt > 0);
+
+	/* Clear the CLEAN_PORT_EN bit at end of this loop */
+	control = readq(priv->base + MLXBF_GIGE_CONTROL);
+	control &= ~MLXBF_GIGE_CONTROL_CLEAN_PORT_EN;
+	writeq(control, priv->base + MLXBF_GIGE_CONTROL);
+}
+
 static int mlxbf_gige_stop(struct net_device *netdev)
 {
 	struct mlxbf_gige *priv = netdev_priv(netdev);
@@ -885,12 +906,11 @@  static int mlxbf_gige_stop(struct net_device *netdev)
 	netif_napi_del(&priv->napi);
 	mlxbf_gige_free_irqs(priv);
 
-	if (netdev->phydev)
-		phy_stop(netdev->phydev);
+	phy_stop(netdev->phydev);
+	phy_disconnect(netdev->phydev);
 
 	mlxbf_gige_rx_deinit(priv);
 	mlxbf_gige_tx_deinit(priv);
-	mlxbf_gige_cache_stats(priv);
 	mlxbf_gige_clean_port(priv);
 
 	return 0;
@@ -963,6 +983,9 @@  static netdev_tx_t mlxbf_gige_start_xmit(struct sk_buff *skb,
 
 	priv->tx_pi++;
 
+	/* Create memory barrier before write to TX PI */
+	wmb();
+
 	writeq(priv->tx_pi, priv->base + MLXBF_GIGE_TX_PRODUCER_INDEX);
 
 	/* Free incoming skb, contents already copied to HW */
@@ -993,10 +1016,11 @@  static void mlxbf_gige_set_rx_mode(struct net_device *netdev)
 	if (new_promisc_enabled != priv->promisc_enabled) {
 		priv->promisc_enabled = new_promisc_enabled;
 
-		if (new_promisc_enabled)
+		if (new_promisc_enabled) {
 			mlxbf_gige_enable_promisc(priv);
-		else
+		} else {
 			mlxbf_gige_disable_promisc(priv);
+		}
 	}
 }
 
@@ -1058,7 +1082,6 @@  static void mlxbf_gige_initial_mac(struct mlxbf_gige *priv)
 
 static int mlxbf_gige_probe(struct platform_device *pdev)
 {
-	struct phy_device *phydev;
 	struct net_device *netdev;
 	struct resource *mac_res;
 	struct resource *llu_res;
@@ -1100,8 +1123,9 @@  static int mlxbf_gige_probe(struct platform_device *pdev)
 	writeq(control, base + MLXBF_GIGE_CONTROL);
 
 	netdev = devm_alloc_etherdev(&pdev->dev, sizeof(*priv));
-	if (!netdev)
+	if (!netdev) {
 		return -ENOMEM;
+	}
 
 	SET_NETDEV_DEV(netdev, &pdev->dev);
 	netdev->netdev_ops = &mlxbf_gige_netdev_ops;
@@ -1109,13 +1133,13 @@  static int mlxbf_gige_probe(struct platform_device *pdev)
 	priv = netdev_priv(netdev);
 	priv->netdev = netdev;
 
+	/* Initialize feature set supported by hardware (skbuff.h) */
+	netdev->hw_features = NETIF_F_RXCSUM | NETIF_F_HW_CSUM;
+
 	platform_set_drvdata(pdev, priv);
 	priv->dev = &pdev->dev;
 	priv->pdev = pdev;
 
-	spin_lock_init(&priv->lock);
-	spin_lock_init(&priv->gpio_lock);
-
 	/* Attach MDIO device */
 	err = mlxbf_gige_mdio_probe(pdev, priv);
 	if (err)
@@ -1141,34 +1165,6 @@  static int mlxbf_gige_probe(struct platform_device *pdev)
 	priv->rx_irq = platform_get_irq(pdev, MLXBF_GIGE_RECEIVE_PKT_INTR_IDX);
 	priv->llu_plu_irq = platform_get_irq(pdev, MLXBF_GIGE_LLU_PLU_INTR_IDX);
 
-	phydev = phy_find_first(priv->mdiobus);
-	if (!phydev)
-		return -EIO;
-
-	/* Sets netdev->phydev to phydev; which will eventually
-	 * be used in ioctl calls.
-	 */
-	err = phy_connect_direct(netdev, phydev,
-				 mlxbf_gige_handle_link_change,
-				 PHY_INTERFACE_MODE_GMII);
-	if (err) {
-		dev_err(&pdev->dev, "Could not attach to PHY\n");
-		return err;
-	}
-
-	/* MAC only supports 1000T full duplex mode */
-	phy_remove_link_mode(phydev, ETHTOOL_LINK_MODE_1000baseT_Half_BIT);
-	phy_remove_link_mode(phydev, ETHTOOL_LINK_MODE_100baseT_Full_BIT);
-	phy_remove_link_mode(phydev, ETHTOOL_LINK_MODE_100baseT_Half_BIT);
-	phy_remove_link_mode(phydev, ETHTOOL_LINK_MODE_10baseT_Full_BIT);
-	phy_remove_link_mode(phydev, ETHTOOL_LINK_MODE_10baseT_Half_BIT);
-
-	/* MAC supports symmetric flow control */
-	phy_support_sym_pause(phydev);
-
-	/* Display information about attached PHY device */
-	phy_attached_info(phydev);
-
 	err = register_netdev(netdev);
 	if (err) {
 		dev_err(&pdev->dev, "Failed to register netdev\n");
@@ -1178,26 +1174,23 @@  static int mlxbf_gige_probe(struct platform_device *pdev)
 	return 0;
 }
 
+/* Device remove function. */
 static int mlxbf_gige_remove(struct platform_device *pdev)
 {
-	struct mlxbf_gige *priv = platform_get_drvdata(pdev);
+	struct mlxbf_gige *priv;
+
+	priv = platform_get_drvdata(pdev);
 
-	phy_disconnect(priv->netdev->phydev);
 	unregister_netdev(priv->netdev);
+
+	/* Remove mdio */
 	mlxbf_gige_mdio_remove(priv);
+
 	platform_set_drvdata(pdev, NULL);
 
 	return 0;
 }
 
-static void mlxbf_gige_shutdown(struct platform_device *pdev)
-{
-	struct mlxbf_gige *priv = platform_get_drvdata(pdev);
-
-	writeq(0, priv->base + MLXBF_GIGE_INT_EN);
-	mlxbf_gige_clean_port(priv);
-}
-
 static const struct acpi_device_id mlxbf_gige_acpi_match[] = {
 	{ "MLNXBF17", 0 },
 	{},
@@ -1207,7 +1200,6 @@  MODULE_DEVICE_TABLE(acpi, mlxbf_gige_acpi_match);
 static struct platform_driver mlxbf_gige_driver = {
 	.probe = mlxbf_gige_probe,
 	.remove = mlxbf_gige_remove,
-	.shutdown = mlxbf_gige_shutdown,
 	.driver = {
 		.name = DRV_NAME,
 		.acpi_match_table = ACPI_PTR(mlxbf_gige_acpi_match),
@@ -1219,5 +1211,5 @@  module_platform_driver(mlxbf_gige_driver);
 MODULE_DESCRIPTION("Mellanox BlueField SoC Gigabit Ethernet Driver");
 MODULE_AUTHOR("David Thompson <dthompson@mellanox.com>");
 MODULE_AUTHOR("Asmaa Mnebhi <asmaa@mellanox.com>");
-MODULE_LICENSE("Dual BSD/GPL");
+MODULE_LICENSE("GPL v2");
 MODULE_VERSION(DRV_VERSION);
diff --git a/drivers/net/ethernet/mellanox/mlxbf_gige/mlxbf_gige_mdio.c b/drivers/net/ethernet/mellanox/mlxbf_gige/mlxbf_gige_mdio.c
index e5c535270a25..2a1362698cb6 100644
--- a/drivers/net/ethernet/mellanox/mlxbf_gige/mlxbf_gige_mdio.c
+++ b/drivers/net/ethernet/mellanox/mlxbf_gige/mlxbf_gige_mdio.c
@@ -229,22 +229,20 @@  static int mlxbf_gige_mdio_write(struct mii_bus *bus, int phy_add,
 
 static void mlxbf_gige_mdio_disable_gpio12_irq(struct mlxbf_gige *priv)
 {
-	unsigned long flags;
 	u32 val;
 
-	spin_lock_irqsave(&priv->gpio_lock, flags);
+	spin_lock(&priv->gpio_lock);
 	val = readl(priv->gpio_io + MLXBF_GIGE_GPIO_CAUSE_OR_EVTEN0);
 	val &= ~MLXBF_GIGE_CAUSE_OR_EVTEN0_MASK;
 	writel(val, priv->gpio_io + MLXBF_GIGE_GPIO_CAUSE_OR_EVTEN0);
-	spin_unlock_irqrestore(&priv->gpio_lock, flags);
+	spin_unlock(&priv->gpio_lock);
 }
 
 static void mlxbf_gige_mdio_enable_gpio12_irq(struct mlxbf_gige *priv)
 {
-	unsigned long flags;
 	u32 val;
 
-	spin_lock_irqsave(&priv->gpio_lock, flags);
+	spin_lock(&priv->gpio_lock);
 	/* The INT_N interrupt level is active low.
 	 * So enable cause fall bit to detect when GPIO
 	 * state goes low.
@@ -259,7 +257,7 @@  static void mlxbf_gige_mdio_enable_gpio12_irq(struct mlxbf_gige *priv)
 	val |= MLXBF_GIGE_CAUSE_OR_EVTEN0_MASK;
 	writel(val, priv->gpio_io +
 			MLXBF_GIGE_GPIO_CAUSE_OR_EVTEN0);
-	spin_unlock_irqrestore(&priv->gpio_lock, flags);
+	spin_unlock(&priv->gpio_lock);
 }
 
 /* Interrupt handler is called from mlxbf_gige_main.c
@@ -314,6 +312,7 @@  int mlxbf_gige_mdio_probe(struct platform_device *pdev, struct mlxbf_gige *priv)
 	struct resource *res;
 	u32 phy_addr;
 	int ret;
+	int irq;
 
 	res = platform_get_resource(pdev, IORESOURCE_MEM, MLXBF_GIGE_RES_MDIO9);
 	if (!res)
@@ -375,7 +374,12 @@  int mlxbf_gige_mdio_probe(struct platform_device *pdev, struct mlxbf_gige *priv)
 	if (ret < 0)
 		phy_addr = MLXBF_GIGE_DEFAULT_PHY_ADDR;
 
-	priv->mdiobus->irq[phy_addr] = PHY_POLL;
+	irq = platform_get_irq(pdev, MLXBF_GIGE_PHY_INT_N);
+	if (irq < 0) {
+		dev_err(dev, "Failed to retrieve irq\n");
+		return -ENODEV;
+	}
+	priv->mdiobus->irq[phy_addr] = irq;
 
 	/* Auto probe PHY at the corresponding address */
 	priv->mdiobus->phy_mask = ~(1 << phy_addr);