Documentation: embargoed-hardware-issues.rst: Add myself for Power
[sfrench/cifs-2.6.git] / drivers / net / ethernet / realtek / r8169_leds.c
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         devm_led_classdev_register(&ndev->dev, led_cdev);
150 }
151
152 void rtl8168_init_leds(struct net_device *ndev)
153 {
154         /* bind resource mgmt to netdev */
155         struct device *dev = &ndev->dev;
156         struct r8169_led_classdev *leds;
157         int i;
158
159         leds = devm_kcalloc(dev, RTL8168_NUM_LEDS, sizeof(*leds), GFP_KERNEL);
160         if (!leds)
161                 return;
162
163         for (i = 0; i < RTL8168_NUM_LEDS; i++)
164                 rtl8168_setup_ldev(leds + i, ndev, i);
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         devm_led_classdev_register(&ndev->dev, led_cdev);
249 }
250
251 void rtl8125_init_leds(struct net_device *ndev)
252 {
253         /* bind resource mgmt to netdev */
254         struct device *dev = &ndev->dev;
255         struct r8169_led_classdev *leds;
256         int i;
257
258         leds = devm_kcalloc(dev, RTL8125_NUM_LEDS, sizeof(*leds), GFP_KERNEL);
259         if (!leds)
260                 return;
261
262         for (i = 0; i < RTL8125_NUM_LEDS; i++)
263                 rtl8125_setup_led_ldev(leds + i, ndev, i);
264 }