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 struct r8169_led_classdev { 24 struct led_classdev led; 25 struct net_device *ndev; 26 int index; 27 }; 28 29 #define lcdev_to_r8169_ldev(lcdev) container_of(lcdev, struct r8169_led_classdev, led) 30 31 static bool r8169_trigger_mode_is_valid(unsigned long flags) 32 { 33 bool rx, tx; 34 35 if (flags & BIT(TRIGGER_NETDEV_HALF_DUPLEX)) 36 return false; 37 if (flags & BIT(TRIGGER_NETDEV_FULL_DUPLEX)) 38 return false; 39 40 rx = flags & BIT(TRIGGER_NETDEV_RX); 41 tx = flags & BIT(TRIGGER_NETDEV_TX); 42 43 return rx == tx; 44 } 45 46 static int rtl8168_led_hw_control_is_supported(struct led_classdev *led_cdev, 47 unsigned long flags) 48 { 49 struct r8169_led_classdev *ldev = lcdev_to_r8169_ldev(led_cdev); 50 struct rtl8169_private *tp = netdev_priv(ldev->ndev); 51 int shift = ldev->index * 4; 52 53 if (!r8169_trigger_mode_is_valid(flags)) { 54 /* Switch LED off to indicate that mode isn't supported */ 55 rtl8168_led_mod_ctrl(tp, 0x000f << shift, 0); 56 return -EOPNOTSUPP; 57 } 58 59 return 0; 60 } 61 62 static int rtl8168_led_hw_control_set(struct led_classdev *led_cdev, 63 unsigned long flags) 64 { 65 struct r8169_led_classdev *ldev = lcdev_to_r8169_ldev(led_cdev); 66 struct rtl8169_private *tp = netdev_priv(ldev->ndev); 67 int shift = ldev->index * 4; 68 u16 mode = 0; 69 70 if (flags & BIT(TRIGGER_NETDEV_LINK_10)) 71 mode |= RTL8168_LED_CTRL_LINK_10; 72 if (flags & BIT(TRIGGER_NETDEV_LINK_100)) 73 mode |= RTL8168_LED_CTRL_LINK_100; 74 if (flags & BIT(TRIGGER_NETDEV_LINK_1000)) 75 mode |= RTL8168_LED_CTRL_LINK_1000; 76 if (flags & BIT(TRIGGER_NETDEV_TX)) 77 mode |= RTL8168_LED_CTRL_ACT; 78 79 return rtl8168_led_mod_ctrl(tp, 0x000f << shift, mode << shift); 80 } 81 82 static int rtl8168_led_hw_control_get(struct led_classdev *led_cdev, 83 unsigned long *flags) 84 { 85 struct r8169_led_classdev *ldev = lcdev_to_r8169_ldev(led_cdev); 86 struct rtl8169_private *tp = netdev_priv(ldev->ndev); 87 int shift = ldev->index * 4; 88 int mode; 89 90 mode = rtl8168_get_led_mode(tp); 91 if (mode < 0) 92 return mode; 93 94 if (mode & RTL8168_LED_CTRL_OPTION2) { 95 rtl8168_led_mod_ctrl(tp, RTL8168_LED_CTRL_OPTION2, 0); 96 netdev_notice(ldev->ndev, "Deactivating unsupported Option2 LED mode\n"); 97 } 98 99 mode = (mode >> shift) & 0x000f; 100 101 if (mode & RTL8168_LED_CTRL_ACT) 102 *flags |= BIT(TRIGGER_NETDEV_TX) | BIT(TRIGGER_NETDEV_RX); 103 104 if (mode & RTL8168_LED_CTRL_LINK_10) 105 *flags |= BIT(TRIGGER_NETDEV_LINK_10); 106 if (mode & RTL8168_LED_CTRL_LINK_100) 107 *flags |= BIT(TRIGGER_NETDEV_LINK_100); 108 if (mode & RTL8168_LED_CTRL_LINK_1000) 109 *flags |= BIT(TRIGGER_NETDEV_LINK_1000); 110 111 return 0; 112 } 113 114 static struct device * 115 r8169_led_hw_control_get_device(struct led_classdev *led_cdev) 116 { 117 struct r8169_led_classdev *ldev = lcdev_to_r8169_ldev(led_cdev); 118 119 return &ldev->ndev->dev; 120 } 121 122 static void rtl8168_setup_ldev(struct r8169_led_classdev *ldev, 123 struct net_device *ndev, int index) 124 { 125 struct rtl8169_private *tp = netdev_priv(ndev); 126 struct led_classdev *led_cdev = &ldev->led; 127 char led_name[LED_MAX_NAME_SIZE]; 128 129 ldev->ndev = ndev; 130 ldev->index = index; 131 132 r8169_get_led_name(tp, index, led_name, LED_MAX_NAME_SIZE); 133 led_cdev->name = led_name; 134 led_cdev->hw_control_trigger = "netdev"; 135 led_cdev->flags |= LED_RETAIN_AT_SHUTDOWN; 136 led_cdev->hw_control_is_supported = rtl8168_led_hw_control_is_supported; 137 led_cdev->hw_control_set = rtl8168_led_hw_control_set; 138 led_cdev->hw_control_get = rtl8168_led_hw_control_get; 139 led_cdev->hw_control_get_device = r8169_led_hw_control_get_device; 140 141 /* ignore errors */ 142 devm_led_classdev_register(&ndev->dev, led_cdev); 143 } 144 145 void rtl8168_init_leds(struct net_device *ndev) 146 { 147 /* bind resource mgmt to netdev */ 148 struct device *dev = &ndev->dev; 149 struct r8169_led_classdev *leds; 150 int i; 151 152 leds = devm_kcalloc(dev, RTL8168_NUM_LEDS, sizeof(*leds), GFP_KERNEL); 153 if (!leds) 154 return; 155 156 for (i = 0; i < RTL8168_NUM_LEDS; i++) 157 rtl8168_setup_ldev(leds + i, ndev, i); 158 } 159