1 // SPDX-License-Identifier: GPL-2.0-only 2 /* r8169_leds.c: Realtek 8169/8168/8101/8125 ethernet driver. 3 * 4 * Copyright (c) 2023 Heiner Kallweit <hkallweit1@gmail.com> 5 * 6 * See MAINTAINERS file for support contact information. 7 */ 8 9 #include <linux/leds.h> 10 #include <linux/netdevice.h> 11 #include <uapi/linux/uleds.h> 12 13 #include "r8169.h" 14 15 #define RTL8168_LED_CTRL_OPTION2 BIT(15) 16 #define RTL8168_LED_CTRL_ACT BIT(3) 17 #define RTL8168_LED_CTRL_LINK_1000 BIT(2) 18 #define RTL8168_LED_CTRL_LINK_100 BIT(1) 19 #define RTL8168_LED_CTRL_LINK_10 BIT(0) 20 21 #define RTL8168_NUM_LEDS 3 22 23 #define RTL8168_SUPPORTED_MODES \ 24 (BIT(TRIGGER_NETDEV_LINK_1000) | BIT(TRIGGER_NETDEV_LINK_100) | \ 25 BIT(TRIGGER_NETDEV_LINK_10) | BIT(TRIGGER_NETDEV_RX) | \ 26 BIT(TRIGGER_NETDEV_TX)) 27 28 struct r8169_led_classdev { 29 struct led_classdev led; 30 struct net_device *ndev; 31 int index; 32 }; 33 34 #define lcdev_to_r8169_ldev(lcdev) container_of(lcdev, struct r8169_led_classdev, led) 35 36 static int rtl8168_led_hw_control_is_supported(struct led_classdev *led_cdev, 37 unsigned long flags) 38 { 39 struct r8169_led_classdev *ldev = lcdev_to_r8169_ldev(led_cdev); 40 struct rtl8169_private *tp = netdev_priv(ldev->ndev); 41 int shift = ldev->index * 4; 42 bool rx, tx; 43 44 if (flags & ~RTL8168_SUPPORTED_MODES) 45 goto nosupp; 46 47 rx = flags & BIT(TRIGGER_NETDEV_RX); 48 tx = flags & BIT(TRIGGER_NETDEV_TX); 49 if (rx != tx) 50 goto nosupp; 51 52 return 0; 53 54 nosupp: 55 /* Switch LED off to indicate that mode isn't supported */ 56 rtl8168_led_mod_ctrl(tp, 0x000f << shift, 0); 57 return -EOPNOTSUPP; 58 } 59 60 static int rtl8168_led_hw_control_set(struct led_classdev *led_cdev, 61 unsigned long flags) 62 { 63 struct r8169_led_classdev *ldev = lcdev_to_r8169_ldev(led_cdev); 64 struct rtl8169_private *tp = netdev_priv(ldev->ndev); 65 int shift = ldev->index * 4; 66 u16 mode = 0; 67 68 if (flags & BIT(TRIGGER_NETDEV_LINK_10)) 69 mode |= RTL8168_LED_CTRL_LINK_10; 70 if (flags & BIT(TRIGGER_NETDEV_LINK_100)) 71 mode |= RTL8168_LED_CTRL_LINK_100; 72 if (flags & BIT(TRIGGER_NETDEV_LINK_1000)) 73 mode |= RTL8168_LED_CTRL_LINK_1000; 74 if (flags & BIT(TRIGGER_NETDEV_TX)) 75 mode |= RTL8168_LED_CTRL_ACT; 76 77 return rtl8168_led_mod_ctrl(tp, 0x000f << shift, mode << shift); 78 } 79 80 static int rtl8168_led_hw_control_get(struct led_classdev *led_cdev, 81 unsigned long *flags) 82 { 83 struct r8169_led_classdev *ldev = lcdev_to_r8169_ldev(led_cdev); 84 struct rtl8169_private *tp = netdev_priv(ldev->ndev); 85 int shift = ldev->index * 4; 86 int mode; 87 88 mode = rtl8168_get_led_mode(tp); 89 if (mode < 0) 90 return mode; 91 92 if (mode & RTL8168_LED_CTRL_OPTION2) { 93 rtl8168_led_mod_ctrl(tp, RTL8168_LED_CTRL_OPTION2, 0); 94 netdev_notice(ldev->ndev, "Deactivating unsupported Option2 LED mode\n"); 95 } 96 97 mode = (mode >> shift) & 0x000f; 98 99 if (mode & RTL8168_LED_CTRL_ACT) 100 *flags |= BIT(TRIGGER_NETDEV_TX) | BIT(TRIGGER_NETDEV_RX); 101 102 if (mode & RTL8168_LED_CTRL_LINK_10) 103 *flags |= BIT(TRIGGER_NETDEV_LINK_10); 104 if (mode & RTL8168_LED_CTRL_LINK_100) 105 *flags |= BIT(TRIGGER_NETDEV_LINK_100); 106 if (mode & RTL8168_LED_CTRL_LINK_1000) 107 *flags |= BIT(TRIGGER_NETDEV_LINK_1000); 108 109 return 0; 110 } 111 112 static struct device * 113 r8169_led_hw_control_get_device(struct led_classdev *led_cdev) 114 { 115 struct r8169_led_classdev *ldev = lcdev_to_r8169_ldev(led_cdev); 116 117 return &ldev->ndev->dev; 118 } 119 120 static void rtl8168_setup_ldev(struct r8169_led_classdev *ldev, 121 struct net_device *ndev, int index) 122 { 123 struct rtl8169_private *tp = netdev_priv(ndev); 124 struct led_classdev *led_cdev = &ldev->led; 125 char led_name[LED_MAX_NAME_SIZE]; 126 127 ldev->ndev = ndev; 128 ldev->index = index; 129 130 r8169_get_led_name(tp, index, led_name, LED_MAX_NAME_SIZE); 131 led_cdev->name = led_name; 132 led_cdev->default_trigger = "netdev"; 133 led_cdev->hw_control_trigger = "netdev"; 134 led_cdev->flags |= LED_RETAIN_AT_SHUTDOWN; 135 led_cdev->hw_control_is_supported = rtl8168_led_hw_control_is_supported; 136 led_cdev->hw_control_set = rtl8168_led_hw_control_set; 137 led_cdev->hw_control_get = rtl8168_led_hw_control_get; 138 led_cdev->hw_control_get_device = r8169_led_hw_control_get_device; 139 140 /* ignore errors */ 141 devm_led_classdev_register(&ndev->dev, led_cdev); 142 } 143 144 void rtl8168_init_leds(struct net_device *ndev) 145 { 146 /* bind resource mgmt to netdev */ 147 struct device *dev = &ndev->dev; 148 struct r8169_led_classdev *leds; 149 int i; 150 151 leds = devm_kcalloc(dev, RTL8168_NUM_LEDS, sizeof(*leds), GFP_KERNEL); 152 if (!leds) 153 return; 154 155 for (i = 0; i < RTL8168_NUM_LEDS; i++) 156 rtl8168_setup_ldev(leds + i, ndev, i); 157 } 158