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 RTL8125_LED_CTRL_ACT BIT(9) 22 #define RTL8125_LED_CTRL_LINK_2500 BIT(5) 23 #define RTL8125_LED_CTRL_LINK_1000 BIT(3) 24 #define RTL8125_LED_CTRL_LINK_100 BIT(1) 25 #define RTL8125_LED_CTRL_LINK_10 BIT(0) 26 27 #define RTL8168_NUM_LEDS 3 28 #define RTL8125_NUM_LEDS 4 29 30 struct r8169_led_classdev { 31 struct led_classdev led; 32 struct net_device *ndev; 33 int index; 34 }; 35 36 #define lcdev_to_r8169_ldev(lcdev) container_of(lcdev, struct r8169_led_classdev, led) 37 38 static bool r8169_trigger_mode_is_valid(unsigned long flags) 39 { 40 bool rx, tx; 41 42 if (flags & BIT(TRIGGER_NETDEV_HALF_DUPLEX)) 43 return false; 44 if (flags & BIT(TRIGGER_NETDEV_FULL_DUPLEX)) 45 return false; 46 47 rx = flags & BIT(TRIGGER_NETDEV_RX); 48 tx = flags & BIT(TRIGGER_NETDEV_TX); 49 50 return rx == tx; 51 } 52 53 static int rtl8168_led_hw_control_is_supported(struct led_classdev *led_cdev, 54 unsigned long flags) 55 { 56 struct r8169_led_classdev *ldev = lcdev_to_r8169_ldev(led_cdev); 57 struct rtl8169_private *tp = netdev_priv(ldev->ndev); 58 int shift = ldev->index * 4; 59 60 if (!r8169_trigger_mode_is_valid(flags)) { 61 /* Switch LED off to indicate that mode isn't supported */ 62 rtl8168_led_mod_ctrl(tp, 0x000f << shift, 0); 63 return -EOPNOTSUPP; 64 } 65 66 return 0; 67 } 68 69 static int rtl8168_led_hw_control_set(struct led_classdev *led_cdev, 70 unsigned long flags) 71 { 72 struct r8169_led_classdev *ldev = lcdev_to_r8169_ldev(led_cdev); 73 struct rtl8169_private *tp = netdev_priv(ldev->ndev); 74 int shift = ldev->index * 4; 75 u16 mode = 0; 76 77 if (flags & BIT(TRIGGER_NETDEV_LINK_10)) 78 mode |= RTL8168_LED_CTRL_LINK_10; 79 if (flags & BIT(TRIGGER_NETDEV_LINK_100)) 80 mode |= RTL8168_LED_CTRL_LINK_100; 81 if (flags & BIT(TRIGGER_NETDEV_LINK_1000)) 82 mode |= RTL8168_LED_CTRL_LINK_1000; 83 if (flags & BIT(TRIGGER_NETDEV_TX)) 84 mode |= RTL8168_LED_CTRL_ACT; 85 86 return rtl8168_led_mod_ctrl(tp, 0x000f << shift, mode << shift); 87 } 88 89 static int rtl8168_led_hw_control_get(struct led_classdev *led_cdev, 90 unsigned long *flags) 91 { 92 struct r8169_led_classdev *ldev = lcdev_to_r8169_ldev(led_cdev); 93 struct rtl8169_private *tp = netdev_priv(ldev->ndev); 94 int shift = ldev->index * 4; 95 int mode; 96 97 mode = rtl8168_get_led_mode(tp); 98 if (mode < 0) 99 return mode; 100 101 if (mode & RTL8168_LED_CTRL_OPTION2) { 102 rtl8168_led_mod_ctrl(tp, RTL8168_LED_CTRL_OPTION2, 0); 103 netdev_notice(ldev->ndev, "Deactivating unsupported Option2 LED mode\n"); 104 } 105 106 mode = (mode >> shift) & 0x000f; 107 108 if (mode & RTL8168_LED_CTRL_ACT) 109 *flags |= BIT(TRIGGER_NETDEV_TX) | BIT(TRIGGER_NETDEV_RX); 110 111 if (mode & RTL8168_LED_CTRL_LINK_10) 112 *flags |= BIT(TRIGGER_NETDEV_LINK_10); 113 if (mode & RTL8168_LED_CTRL_LINK_100) 114 *flags |= BIT(TRIGGER_NETDEV_LINK_100); 115 if (mode & RTL8168_LED_CTRL_LINK_1000) 116 *flags |= BIT(TRIGGER_NETDEV_LINK_1000); 117 118 return 0; 119 } 120 121 static struct device * 122 r8169_led_hw_control_get_device(struct led_classdev *led_cdev) 123 { 124 struct r8169_led_classdev *ldev = lcdev_to_r8169_ldev(led_cdev); 125 126 return &ldev->ndev->dev; 127 } 128 129 static void rtl8168_setup_ldev(struct r8169_led_classdev *ldev, 130 struct net_device *ndev, int index) 131 { 132 struct rtl8169_private *tp = netdev_priv(ndev); 133 struct led_classdev *led_cdev = &ldev->led; 134 char led_name[LED_MAX_NAME_SIZE]; 135 136 ldev->ndev = ndev; 137 ldev->index = index; 138 139 r8169_get_led_name(tp, index, led_name, LED_MAX_NAME_SIZE); 140 led_cdev->name = led_name; 141 led_cdev->hw_control_trigger = "netdev"; 142 led_cdev->flags |= LED_RETAIN_AT_SHUTDOWN; 143 led_cdev->hw_control_is_supported = rtl8168_led_hw_control_is_supported; 144 led_cdev->hw_control_set = rtl8168_led_hw_control_set; 145 led_cdev->hw_control_get = rtl8168_led_hw_control_get; 146 led_cdev->hw_control_get_device = r8169_led_hw_control_get_device; 147 148 /* ignore errors */ 149 led_classdev_register(&ndev->dev, led_cdev); 150 } 151 152 struct r8169_led_classdev *rtl8168_init_leds(struct net_device *ndev) 153 { 154 struct r8169_led_classdev *leds; 155 int i; 156 157 leds = kcalloc(RTL8168_NUM_LEDS + 1, sizeof(*leds), GFP_KERNEL); 158 if (!leds) 159 return NULL; 160 161 for (i = 0; i < RTL8168_NUM_LEDS; i++) 162 rtl8168_setup_ldev(leds + i, ndev, i); 163 164 return leds; 165 } 166 167 static int rtl8125_led_hw_control_is_supported(struct led_classdev *led_cdev, 168 unsigned long flags) 169 { 170 struct r8169_led_classdev *ldev = lcdev_to_r8169_ldev(led_cdev); 171 struct rtl8169_private *tp = netdev_priv(ldev->ndev); 172 173 if (!r8169_trigger_mode_is_valid(flags)) { 174 /* Switch LED off to indicate that mode isn't supported */ 175 rtl8125_set_led_mode(tp, ldev->index, 0); 176 return -EOPNOTSUPP; 177 } 178 179 return 0; 180 } 181 182 static int rtl8125_led_hw_control_set(struct led_classdev *led_cdev, 183 unsigned long flags) 184 { 185 struct r8169_led_classdev *ldev = lcdev_to_r8169_ldev(led_cdev); 186 struct rtl8169_private *tp = netdev_priv(ldev->ndev); 187 u16 mode = 0; 188 189 if (flags & BIT(TRIGGER_NETDEV_LINK_10)) 190 mode |= RTL8125_LED_CTRL_LINK_10; 191 if (flags & BIT(TRIGGER_NETDEV_LINK_100)) 192 mode |= RTL8125_LED_CTRL_LINK_100; 193 if (flags & BIT(TRIGGER_NETDEV_LINK_1000)) 194 mode |= RTL8125_LED_CTRL_LINK_1000; 195 if (flags & BIT(TRIGGER_NETDEV_LINK_2500)) 196 mode |= RTL8125_LED_CTRL_LINK_2500; 197 if (flags & (BIT(TRIGGER_NETDEV_TX) | BIT(TRIGGER_NETDEV_RX))) 198 mode |= RTL8125_LED_CTRL_ACT; 199 200 return rtl8125_set_led_mode(tp, ldev->index, mode); 201 } 202 203 static int rtl8125_led_hw_control_get(struct led_classdev *led_cdev, 204 unsigned long *flags) 205 { 206 struct r8169_led_classdev *ldev = lcdev_to_r8169_ldev(led_cdev); 207 struct rtl8169_private *tp = netdev_priv(ldev->ndev); 208 int mode; 209 210 mode = rtl8125_get_led_mode(tp, ldev->index); 211 if (mode < 0) 212 return mode; 213 214 if (mode & RTL8125_LED_CTRL_LINK_10) 215 *flags |= BIT(TRIGGER_NETDEV_LINK_10); 216 if (mode & RTL8125_LED_CTRL_LINK_100) 217 *flags |= BIT(TRIGGER_NETDEV_LINK_100); 218 if (mode & RTL8125_LED_CTRL_LINK_1000) 219 *flags |= BIT(TRIGGER_NETDEV_LINK_1000); 220 if (mode & RTL8125_LED_CTRL_LINK_2500) 221 *flags |= BIT(TRIGGER_NETDEV_LINK_2500); 222 if (mode & RTL8125_LED_CTRL_ACT) 223 *flags |= BIT(TRIGGER_NETDEV_TX) | BIT(TRIGGER_NETDEV_RX); 224 225 return 0; 226 } 227 228 static void rtl8125_setup_led_ldev(struct r8169_led_classdev *ldev, 229 struct net_device *ndev, int index) 230 { 231 struct rtl8169_private *tp = netdev_priv(ndev); 232 struct led_classdev *led_cdev = &ldev->led; 233 char led_name[LED_MAX_NAME_SIZE]; 234 235 ldev->ndev = ndev; 236 ldev->index = index; 237 238 r8169_get_led_name(tp, index, led_name, LED_MAX_NAME_SIZE); 239 led_cdev->name = led_name; 240 led_cdev->hw_control_trigger = "netdev"; 241 led_cdev->flags |= LED_RETAIN_AT_SHUTDOWN; 242 led_cdev->hw_control_is_supported = rtl8125_led_hw_control_is_supported; 243 led_cdev->hw_control_set = rtl8125_led_hw_control_set; 244 led_cdev->hw_control_get = rtl8125_led_hw_control_get; 245 led_cdev->hw_control_get_device = r8169_led_hw_control_get_device; 246 247 /* ignore errors */ 248 led_classdev_register(&ndev->dev, led_cdev); 249 } 250 251 struct r8169_led_classdev *rtl8125_init_leds(struct net_device *ndev) 252 { 253 struct r8169_led_classdev *leds; 254 int i; 255 256 leds = kcalloc(RTL8125_NUM_LEDS + 1, sizeof(*leds), GFP_KERNEL); 257 if (!leds) 258 return NULL; 259 260 for (i = 0; i < RTL8125_NUM_LEDS; i++) 261 rtl8125_setup_led_ldev(leds + i, ndev, i); 262 263 return leds; 264 } 265 266 void r8169_remove_leds(struct r8169_led_classdev *leds) 267 { 268 if (!leds) 269 return; 270 271 for (struct r8169_led_classdev *l = leds; l->ndev; l++) 272 led_classdev_unregister(&l->led); 273 274 kfree(leds); 275 } 276