diff --git a/drivers/net/phy/dp83640.c b/drivers/net/phy/dp83640.c
index 5c42c47dc564..c46c81ef0ad0 100644
--- a/drivers/net/phy/dp83640.c
+++ b/drivers/net/phy/dp83640.c
@@ -59,6 +59,22 @@
 				   MII_DP83640_MISR_SPD_INT |\
 				   MII_DP83640_MISR_LINK_INT)
 
+#define DP83640_ACTLED_IDX	0
+#define DP83640_LNKLED_IDX	1
+#define DP83640_SPDLED_IDX	2
+/* LNKLED = ON for Good Link, OFF for No Link */
+/* SPDLED = ON in 100 Mb/s, OFF in 10 Mb/s */
+/* ACTLED = ON for Activity, OFF for No Activity */
+#define DP83640_LED_MODE_1	1
+/* LNKLED = ON for Good Link, Blink for Activity */
+/* SPDLED = ON in 100 Mb/s, OFF in 10 Mb/s */
+/* ACTLED = ON for Collision, OFF for No Collision */
+#define DP83640_LED_MODE_2	2
+/* LNKLED = ON for Good Link, Blink for Activity */
+/* SPDLED = ON in 100 Mb/s, OFF in 10 Mb/s */
+/* ACTLED = ON for Full-Duplex, OFF for Half-Duplex */
+#define DP83640_LED_MODE_3	3
+
 /* phyter seems to miss the mark by 16 ns */
 #define ADJTIME_FIX	16
 
@@ -1515,6 +1531,161 @@ static void dp83640_remove(struct phy_device *phydev)
 	kfree(dp83640);
 }
 
+static int dp83640_led_brightness_set(struct phy_device *phydev, u8 index,
+				      enum led_brightness brightness)
+{
+	int val;
+
+	if (index > DP83640_SPDLED_IDX)
+		return -EINVAL;
+
+	phy_write(phydev, PAGESEL, 0);
+
+	val = phy_read(phydev, LEDCR) & ~DP83640_LED_DIS(index);
+	val |= DP83640_LED_DRV(index);
+	if (brightness)
+		val |= DP83640_LED_VAL(index);
+	else
+		val &= ~DP83640_LED_VAL(index);
+	phy_write(phydev, LEDCR, val);
+
+	return 0;
+}
+
+/**
+ * dp83640_led_mode - Check the trigger netdev rules and compute the associated
+ *                    configuration mode
+ * @index: The targeted LED
+ * @rules: Rules to be checked
+ *
+ * Returns the mode that is to be set in LED_CFNG. If the rules are not
+ * supported by the PHY, returns -ENOTSUPP. If the rules are supported but don't
+ * impact the LED configuration, returns 0
+ */
+static int dp83640_led_mode(u8 index, unsigned long rules)
+{
+	/* Only changes on ACTLED have an impact on LED Mode configuration */
+	switch (index) {
+	case DP83640_ACTLED_IDX:
+		switch (rules) {
+		case BIT(TRIGGER_NETDEV_TX) | BIT(TRIGGER_NETDEV_RX):
+			return DP83640_LED_MODE_1;
+		case BIT(TRIGGER_NETDEV_COLLISION):
+			return DP83640_LED_MODE_2;
+		case BIT(TRIGGER_NETDEV_FULL_DUPLEX) |
+		     BIT(TRIGGER_NETDEV_HALF_DUPLEX):
+			return DP83640_LED_MODE_3;
+		default:
+			return -EOPNOTSUPP;
+		}
+
+	case DP83640_SPDLED_IDX:
+		/* SPDLED has the same function in every mode */
+		switch (rules) {
+		case BIT(TRIGGER_NETDEV_LINK_10) | BIT(TRIGGER_NETDEV_LINK_100):
+			return 0;
+		default:
+			return -EOPNOTSUPP;
+		}
+
+	case DP83640_LNKLED_IDX:
+		/* LNKLED has the same function in every mode */
+		switch (rules) {
+		case BIT(TRIGGER_NETDEV_LINK):
+			return 0;
+		default:
+			return -EOPNOTSUPP;
+		}
+	default:
+		return -EINVAL;
+	}
+}
+
+static int dp83640_led_hw_is_supported(struct phy_device *phydev, u8 index,
+				       unsigned long rules)
+{
+	int ret;
+
+	ret = dp83640_led_mode(index, rules);
+
+	if (ret < 0)
+		return ret;
+
+	return 0;
+}
+
+static int dp83640_led_hw_control_set(struct phy_device *phydev, u8 index,
+				      unsigned long rules)
+{
+	int mode, val;
+
+	mode = dp83640_led_mode(index, rules);
+	if (mode < 0)
+		return mode;
+
+	if (mode) {
+		phy_write(phydev, PAGESEL, 0);
+		val = phy_read(phydev, PHYCR) & ~(LED_CNFG_1 | LED_CNFG_0);
+		switch (mode) {
+		case DP83640_LED_MODE_1:
+			val |= LED_CNFG_0;
+		break;
+		case DP83640_LED_MODE_2:
+			/* Keeping LED_CNFG_1 and LED_CNFG_0 unset */
+			break;
+		case DP83640_LED_MODE_3:
+			val |= LED_CNFG_1;
+			break;
+		default:
+			return -EINVAL;
+		}
+		phy_write(phydev, PHYCR, val);
+	}
+
+	val = phy_read(phydev, LEDCR);
+	val &= ~(DP83640_LED_DIS(index) | DP83640_LED_DRV(index));
+	phy_write(phydev, LEDCR, val);
+
+	return 0;
+}
+
+static int dp83640_led_hw_control_get(struct phy_device *phydev, u8 index,
+				      unsigned long *rules)
+{
+	int val;
+
+	switch (index) {
+	case DP83640_ACTLED_IDX:
+		phy_write(phydev, PAGESEL, 0);
+		val = phy_read(phydev, PHYCR);
+		if (val & LED_CNFG_0) {
+			/* Mode 1 */
+			*rules = BIT(TRIGGER_NETDEV_TX) | BIT(TRIGGER_NETDEV_RX);
+		} else if (val & LED_CNFG_1) {
+			/* Mode 3 */
+			*rules = BIT(TRIGGER_NETDEV_FULL_DUPLEX) |
+				 BIT(TRIGGER_NETDEV_HALF_DUPLEX);
+		} else {
+			/* Mode 2 */
+			*rules = BIT(TRIGGER_NETDEV_COLLISION);
+		}
+		break;
+
+	case DP83640_LNKLED_IDX:
+		*rules = BIT(TRIGGER_NETDEV_LINK);
+		break;
+
+	case DP83640_SPDLED_IDX:
+		*rules = BIT(TRIGGER_NETDEV_LINK_10) |
+			 BIT(TRIGGER_NETDEV_LINK_100);
+		break;
+	default:
+		return -EINVAL;
+	}
+
+	return 0;
+}
+
 static struct phy_driver dp83640_driver = {
 	.phy_id		= DP83640_PHY_ID,
 	.phy_id_mask	= 0xfffffff0,
@@ -1526,6 +1697,11 @@ static struct phy_driver dp83640_driver = {
 	.config_init	= dp83640_config_init,
 	.config_intr    = dp83640_config_intr,
 	.handle_interrupt = dp83640_handle_interrupt,
+
+	.led_brightness_set = dp83640_led_brightness_set,
+	.led_hw_is_supported = dp83640_led_hw_is_supported,
+	.led_hw_control_set = dp83640_led_hw_control_set,
+	.led_hw_control_get = dp83640_led_hw_control_get,
 };
 
 static int __init dp83640_init(void)
diff --git a/drivers/net/phy/dp83640_reg.h b/drivers/net/phy/dp83640_reg.h
index daae7fa58fb8..09dd2d2527c7 100644
--- a/drivers/net/phy/dp83640_reg.h
+++ b/drivers/net/phy/dp83640_reg.h
@@ -6,6 +6,8 @@
 #define HAVE_DP83640_REGISTERS
 
 /* #define PAGE0                  0x0000 */
+#define LEDCR                     0x0018 /* PHY Control Register */
+#define PHYCR                     0x0019 /* PHY Control Register */
 #define PHYCR2                    0x001c /* PHY Control Register 2 */
 
 #define PAGE4                     0x0004
@@ -50,6 +52,15 @@
 #define PTP_GPIOMON               0x001e /* PTP GPIO Monitor Register */
 #define PTP_RXHASH                0x001f /* PTP Receive Hash Register */
 
+/* Bit definitions for the LEDCR register */
+#define DP83640_LED_DIS(x)        BIT((x) + 9) /* Disable LED */
+#define DP83640_LED_DRV(x)        BIT((x) + 3) /* Force LED val to output */
+#define DP83640_LED_VAL(x)        BIT((x))     /* LED val */
+
+/* Bit definitions for the PHYCR register */
+#define LED_CNFG_0	          BIT(5)  /* LED configuration, bit 0 */
+#define LED_CNFG_1	          BIT(6)  /* LED configuration, bit 1 */
+
 /* Bit definitions for the PHYCR2 register */
 #define BC_WRITE                  (1<<11) /* Broadcast Write Enable */
 
