// SPDX-License-Identifier: GPL-2.0-only
/* r8169_leds.c: Realtek 8169/8168/8101/8125 ethernet driver.
 *
 * Copyright (c) 2023 Heiner Kallweit <hkallweit1@gmail.com>
 *
 * See MAINTAINERS file for support contact information.
 */

#include <linux/leds.h>
#include <linux/netdevice.h>
#include <uapi/linux/uleds.h>

#include "r8169.h"

#define RTL8168_LED_CTRL_OPTION2	BIT(15)
#define RTL8168_LED_CTRL_ACT		BIT(3)
#define RTL8168_LED_CTRL_LINK_1000	BIT(2)
#define RTL8168_LED_CTRL_LINK_100	BIT(1)
#define RTL8168_LED_CTRL_LINK_10	BIT(0)

#define RTL8125_LED_CTRL_ACT		BIT(9)
#define RTL8125_LED_CTRL_LINK_2500	BIT(5)
#define RTL8125_LED_CTRL_LINK_1000	BIT(3)
#define RTL8125_LED_CTRL_LINK_100	BIT(1)
#define RTL8125_LED_CTRL_LINK_10	BIT(0)

#define RTL8168_NUM_LEDS		3
#define RTL8125_NUM_LEDS		4

struct r8169_led_classdev {
	struct led_classdev led;
	struct net_device *ndev;
	int index;
};

#define lcdev_to_r8169_ldev(lcdev) container_of(lcdev, struct r8169_led_classdev, led)

static bool r8169_trigger_mode_is_valid(unsigned long flags)
{
	bool rx, tx;

	if (flags & BIT(TRIGGER_NETDEV_HALF_DUPLEX))
		return false;
	if (flags & BIT(TRIGGER_NETDEV_FULL_DUPLEX))
		return false;

	rx = flags & BIT(TRIGGER_NETDEV_RX);
	tx = flags & BIT(TRIGGER_NETDEV_TX);

	return rx == tx;
}

static int rtl8168_led_hw_control_is_supported(struct led_classdev *led_cdev,
					       unsigned long flags)
{
	struct r8169_led_classdev *ldev = lcdev_to_r8169_ldev(led_cdev);
	struct rtl8169_private *tp = netdev_priv(ldev->ndev);
	int shift = ldev->index * 4;

	if (!r8169_trigger_mode_is_valid(flags)) {
		/* Switch LED off to indicate that mode isn't supported */
		rtl8168_led_mod_ctrl(tp, 0x000f << shift, 0);
		return -EOPNOTSUPP;
	}

	return 0;
}

static int rtl8168_led_hw_control_set(struct led_classdev *led_cdev,
				      unsigned long flags)
{
	struct r8169_led_classdev *ldev = lcdev_to_r8169_ldev(led_cdev);
	struct rtl8169_private *tp = netdev_priv(ldev->ndev);
	int shift = ldev->index * 4;
	u16 mode = 0;

	if (flags & BIT(TRIGGER_NETDEV_LINK_10))
		mode |= RTL8168_LED_CTRL_LINK_10;
	if (flags & BIT(TRIGGER_NETDEV_LINK_100))
		mode |= RTL8168_LED_CTRL_LINK_100;
	if (flags & BIT(TRIGGER_NETDEV_LINK_1000))
		mode |= RTL8168_LED_CTRL_LINK_1000;
	if (flags & BIT(TRIGGER_NETDEV_TX))
		mode |= RTL8168_LED_CTRL_ACT;

	return rtl8168_led_mod_ctrl(tp, 0x000f << shift, mode << shift);
}

static int rtl8168_led_hw_control_get(struct led_classdev *led_cdev,
				      unsigned long *flags)
{
	struct r8169_led_classdev *ldev = lcdev_to_r8169_ldev(led_cdev);
	struct rtl8169_private *tp = netdev_priv(ldev->ndev);
	int shift = ldev->index * 4;
	int mode;

	mode = rtl8168_get_led_mode(tp);
	if (mode < 0)
		return mode;

	if (mode & RTL8168_LED_CTRL_OPTION2) {
		rtl8168_led_mod_ctrl(tp, RTL8168_LED_CTRL_OPTION2, 0);
		netdev_notice(ldev->ndev, "Deactivating unsupported Option2 LED mode\n");
	}

	mode = (mode >> shift) & 0x000f;

	if (mode & RTL8168_LED_CTRL_ACT)
		*flags |= BIT(TRIGGER_NETDEV_TX) | BIT(TRIGGER_NETDEV_RX);

	if (mode & RTL8168_LED_CTRL_LINK_10)
		*flags |= BIT(TRIGGER_NETDEV_LINK_10);
	if (mode & RTL8168_LED_CTRL_LINK_100)
		*flags |= BIT(TRIGGER_NETDEV_LINK_100);
	if (mode & RTL8168_LED_CTRL_LINK_1000)
		*flags |= BIT(TRIGGER_NETDEV_LINK_1000);

	return 0;
}

static struct device *
	r8169_led_hw_control_get_device(struct led_classdev *led_cdev)
{
	struct r8169_led_classdev *ldev = lcdev_to_r8169_ldev(led_cdev);

	return &ldev->ndev->dev;
}

static void rtl8168_setup_ldev(struct r8169_led_classdev *ldev,
			       struct net_device *ndev, int index)
{
	struct rtl8169_private *tp = netdev_priv(ndev);
	struct led_classdev *led_cdev = &ldev->led;
	char led_name[LED_MAX_NAME_SIZE];

	ldev->ndev = ndev;
	ldev->index = index;

	r8169_get_led_name(tp, index, led_name, LED_MAX_NAME_SIZE);
	led_cdev->name = led_name;
	led_cdev->hw_control_trigger = "netdev";
	led_cdev->flags |= LED_RETAIN_AT_SHUTDOWN;
	led_cdev->hw_control_is_supported = rtl8168_led_hw_control_is_supported;
	led_cdev->hw_control_set = rtl8168_led_hw_control_set;
	led_cdev->hw_control_get = rtl8168_led_hw_control_get;
	led_cdev->hw_control_get_device = r8169_led_hw_control_get_device;

	/* ignore errors */
	devm_led_classdev_register(&ndev->dev, led_cdev);
}

void rtl8168_init_leds(struct net_device *ndev)
{
	/* bind resource mgmt to netdev */
	struct device *dev = &ndev->dev;
	struct r8169_led_classdev *leds;
	int i;

	leds = devm_kcalloc(dev, RTL8168_NUM_LEDS, sizeof(*leds), GFP_KERNEL);
	if (!leds)
		return;

	for (i = 0; i < RTL8168_NUM_LEDS; i++)
		rtl8168_setup_ldev(leds + i, ndev, i);
}

static int rtl8125_led_hw_control_is_supported(struct led_classdev *led_cdev,
					       unsigned long flags)
{
	struct r8169_led_classdev *ldev = lcdev_to_r8169_ldev(led_cdev);
	struct rtl8169_private *tp = netdev_priv(ldev->ndev);

	if (!r8169_trigger_mode_is_valid(flags)) {
		/* Switch LED off to indicate that mode isn't supported */
		rtl8125_set_led_mode(tp, ldev->index, 0);
		return -EOPNOTSUPP;
	}

	return 0;
}

static int rtl8125_led_hw_control_set(struct led_classdev *led_cdev,
				      unsigned long flags)
{
	struct r8169_led_classdev *ldev = lcdev_to_r8169_ldev(led_cdev);
	struct rtl8169_private *tp = netdev_priv(ldev->ndev);
	u16 mode = 0;

	if (flags & BIT(TRIGGER_NETDEV_LINK_10))
		mode |= RTL8125_LED_CTRL_LINK_10;
	if (flags & BIT(TRIGGER_NETDEV_LINK_100))
		mode |= RTL8125_LED_CTRL_LINK_100;
	if (flags & BIT(TRIGGER_NETDEV_LINK_1000))
		mode |= RTL8125_LED_CTRL_LINK_1000;
	if (flags & BIT(TRIGGER_NETDEV_LINK_2500))
		mode |= RTL8125_LED_CTRL_LINK_2500;
	if (flags & (BIT(TRIGGER_NETDEV_TX) | BIT(TRIGGER_NETDEV_RX)))
		mode |= RTL8125_LED_CTRL_ACT;

	return rtl8125_set_led_mode(tp, ldev->index, mode);
}

static int rtl8125_led_hw_control_get(struct led_classdev *led_cdev,
				      unsigned long *flags)
{
	struct r8169_led_classdev *ldev = lcdev_to_r8169_ldev(led_cdev);
	struct rtl8169_private *tp = netdev_priv(ldev->ndev);
	int mode;

	mode = rtl8125_get_led_mode(tp, ldev->index);
	if (mode < 0)
		return mode;

	if (mode & RTL8125_LED_CTRL_LINK_10)
		*flags |= BIT(TRIGGER_NETDEV_LINK_10);
	if (mode & RTL8125_LED_CTRL_LINK_100)
		*flags |= BIT(TRIGGER_NETDEV_LINK_100);
	if (mode & RTL8125_LED_CTRL_LINK_1000)
		*flags |= BIT(TRIGGER_NETDEV_LINK_1000);
	if (mode & RTL8125_LED_CTRL_LINK_2500)
		*flags |= BIT(TRIGGER_NETDEV_LINK_2500);
	if (mode & RTL8125_LED_CTRL_ACT)
		*flags |= BIT(TRIGGER_NETDEV_TX) | BIT(TRIGGER_NETDEV_RX);

	return 0;
}

static void rtl8125_setup_led_ldev(struct r8169_led_classdev *ldev,
				   struct net_device *ndev, int index)
{
	struct rtl8169_private *tp = netdev_priv(ndev);
	struct led_classdev *led_cdev = &ldev->led;
	char led_name[LED_MAX_NAME_SIZE];

	ldev->ndev = ndev;
	ldev->index = index;

	r8169_get_led_name(tp, index, led_name, LED_MAX_NAME_SIZE);
	led_cdev->name = led_name;
	led_cdev->hw_control_trigger = "netdev";
	led_cdev->flags |= LED_RETAIN_AT_SHUTDOWN;
	led_cdev->hw_control_is_supported = rtl8125_led_hw_control_is_supported;
	led_cdev->hw_control_set = rtl8125_led_hw_control_set;
	led_cdev->hw_control_get = rtl8125_led_hw_control_get;
	led_cdev->hw_control_get_device = r8169_led_hw_control_get_device;

	/* ignore errors */
	devm_led_classdev_register(&ndev->dev, led_cdev);
}

void rtl8125_init_leds(struct net_device *ndev)
{
	/* bind resource mgmt to netdev */
	struct device *dev = &ndev->dev;
	struct r8169_led_classdev *leds;
	int i;

	leds = devm_kcalloc(dev, RTL8125_NUM_LEDS, sizeof(*leds), GFP_KERNEL);
	if (!leds)
		return;

	for (i = 0; i < RTL8125_NUM_LEDS; i++)
		rtl8125_setup_led_ldev(leds + i, ndev, i);
}
