return 0;
 }
 
+static void mt7915_led_set_config(struct led_classdev *led_cdev,
+                                 u8 delay_on, u8 delay_off)
+{
+       struct mt7915_dev *dev;
+       struct mt76_dev *mt76;
+       u32 val;
+
+       mt76 = container_of(led_cdev, struct mt76_dev, led_cdev);
+       dev = container_of(mt76, struct mt7915_dev, mt76);
+
+       /* select TX blink mode, 2: only data frames */
+       mt76_rmw_field(dev, MT_TMAC_TCR0(0), MT_TMAC_TCR0_TX_BLINK, 2);
+
+       /* enable LED */
+       mt76_wr(dev, MT_LED_EN(0), 1);
+
+       /* set LED Tx blink on/off time */
+       val = FIELD_PREP(MT_LED_TX_BLINK_ON_MASK, delay_on) |
+             FIELD_PREP(MT_LED_TX_BLINK_OFF_MASK, delay_off);
+       mt76_wr(dev, MT_LED_TX_BLINK(0), val);
+
+       /* control LED */
+       val = MT_LED_CTRL_BLINK_MODE | MT_LED_CTRL_KICK;
+       if (dev->mt76.led_al)
+               val |= MT_LED_CTRL_POLARITY;
+
+       mt76_wr(dev, MT_LED_CTRL(0), val);
+       mt76_clear(dev, MT_LED_CTRL(0), MT_LED_CTRL_KICK);
+}
+
+static int mt7915_led_set_blink(struct led_classdev *led_cdev,
+                               unsigned long *delay_on,
+                               unsigned long *delay_off)
+{
+       u16 delta_on = 0, delta_off = 0;
+
+#define HW_TICK                10
+#define TO_HW_TICK(_t) (((_t) > HW_TICK) ? ((_t) / HW_TICK) : HW_TICK)
+
+       if (*delay_on)
+               delta_on = TO_HW_TICK(*delay_on);
+       if (*delay_off)
+               delta_off = TO_HW_TICK(*delay_off);
+
+       mt7915_led_set_config(led_cdev, delta_on, delta_off);
+
+       return 0;
+}
+
+static void mt7915_led_set_brightness(struct led_classdev *led_cdev,
+                                     enum led_brightness brightness)
+{
+       if (!brightness)
+               mt7915_led_set_config(led_cdev, 0, 0xff);
+       else
+               mt7915_led_set_config(led_cdev, 0xff, 0);
+}
+
 static void
 mt7915_init_txpower(struct mt7915_dev *dev,
                    struct ieee80211_supported_band *sband)
                                       MT_WTBL_UPDATE_ADM_COUNT_CLEAR);
        for (i = 0; i < 2; i++)
                mt7915_mac_init_band(dev, i);
+
+       if (IS_ENABLED(CONFIG_MT76_LEDS)) {
+               i = dev->mt76.led_pin ? MT_LED_GPIO_MUX3 : MT_LED_GPIO_MUX2;
+               mt76_rmw_field(dev, i, MT_LED_GPIO_SEL_MASK, 4);
+       }
 }
 
 static int mt7915_txbf_init(struct mt7915_dev *dev)
        dev->mt76.test_ops = &mt7915_testmode_ops;
 #endif
 
+       /* init led callbacks */
+       if (IS_ENABLED(CONFIG_MT76_LEDS)) {
+               dev->mt76.led_cdev.brightness_set = mt7915_led_set_brightness;
+               dev->mt76.led_cdev.blink_set = mt7915_led_set_blink;
+       }
+
        ret = mt76_register_device(&dev->mt76, true, mt76_rates,
                                   ARRAY_SIZE(mt76_rates));
        if (ret)
 
 #define MT_WF_TMAC(_band, ofs)         (MT_WF_TMAC_BASE(_band) + (ofs))
 
 #define MT_TMAC_TCR0(_band)            MT_WF_TMAC(_band, 0)
+#define MT_TMAC_TCR0_TX_BLINK          GENMASK(7, 6)
 #define MT_TMAC_TCR0_TBTT_STOP_CTRL    BIT(25)
 
 #define MT_TMAC_CDTR(_band)            MT_WF_TMAC(_band, 0x090)
 #define MT_SWDEF_ICAP_MODE             1
 #define MT_SWDEF_SPECTRUM_MODE         2
 
+#define MT_LED_TOP_BASE                        0x18013000
+#define MT_LED_PHYS(_n)                        (MT_LED_TOP_BASE + (_n))
+
+#define MT_LED_CTRL(_n)                        MT_LED_PHYS(0x00 + ((_n) * 4))
+#define MT_LED_CTRL_KICK               BIT(7)
+#define MT_LED_CTRL_BLINK_MODE         BIT(2)
+#define MT_LED_CTRL_POLARITY           BIT(1)
+
+#define MT_LED_TX_BLINK(_n)            MT_LED_PHYS(0x10 + ((_n) * 4))
+#define MT_LED_TX_BLINK_ON_MASK                GENMASK(7, 0)
+#define MT_LED_TX_BLINK_OFF_MASK        GENMASK(15, 8)
+
+#define MT_LED_EN(_n)                  MT_LED_PHYS(0x40 + ((_n) * 4))
+
 #define MT_TOP_BASE                    0x18060000
 #define MT_TOP(ofs)                    (MT_TOP_BASE + (ofs))
 
 #define MT_TOP_MISC                    MT_TOP(0xf0)
 #define MT_TOP_MISC_FW_STATE           GENMASK(2, 0)
 
+#define MT_LED_GPIO_MUX2                0x70005058 /* GPIO 18 */
+#define MT_LED_GPIO_MUX3                0x7000505C /* GPIO 26 */
+#define MT_LED_GPIO_SEL_MASK            GENMASK(11, 8)
+
 #define MT_HW_BOUND                    0x70010020
 #define MT_HW_CHIPID                   0x70010200
 #define MT_HW_REV                      0x70010204