mediatek: mt76-6e-usb Fix to build error
[platform/kernel/linux-rpi.git] / drivers / net / wireless / broadcom / b43legacy / sysfs.c
1 // SPDX-License-Identifier: GPL-2.0-or-later
2 /*
3
4   Broadcom B43legacy wireless driver
5
6   SYSFS support routines
7
8   Copyright (c) 2006 Michael Buesch <m@bues.ch>
9
10
11 */
12
13 #include "sysfs.h"
14 #include "b43legacy.h"
15 #include "main.h"
16 #include "phy.h"
17 #include "radio.h"
18
19 #include <linux/capability.h>
20
21
22 #define GENERIC_FILESIZE        64
23
24
25 static int get_integer(const char *buf, size_t count)
26 {
27         char tmp[10 + 1] = { 0 };
28         int ret = -EINVAL, res;
29
30         if (count == 0)
31                 goto out;
32         count = min_t(size_t, count, 10);
33         memcpy(tmp, buf, count);
34         ret = kstrtoint(tmp, 10, &res);
35         if (!ret)
36                 return res;
37 out:
38         return ret;
39 }
40
41 static int get_boolean(const char *buf, size_t count)
42 {
43         if (count != 0) {
44                 if (buf[0] == '1')
45                         return 1;
46                 if (buf[0] == '0')
47                         return 0;
48                 if (count >= 4 && memcmp(buf, "true", 4) == 0)
49                         return 1;
50                 if (count >= 5 && memcmp(buf, "false", 5) == 0)
51                         return 0;
52                 if (count >= 3 && memcmp(buf, "yes", 3) == 0)
53                         return 1;
54                 if (count >= 2 && memcmp(buf, "no", 2) == 0)
55                         return 0;
56                 if (count >= 2 && memcmp(buf, "on", 2) == 0)
57                         return 1;
58                 if (count >= 3 && memcmp(buf, "off", 3) == 0)
59                         return 0;
60         }
61         return -EINVAL;
62 }
63
64 static ssize_t b43legacy_attr_interfmode_show(struct device *dev,
65                                               struct device_attribute *attr,
66                                               char *buf)
67 {
68         struct b43legacy_wldev *wldev = dev_to_b43legacy_wldev(dev);
69         ssize_t count = 0;
70
71         if (!capable(CAP_NET_ADMIN))
72                 return -EPERM;
73
74         mutex_lock(&wldev->wl->mutex);
75
76         switch (wldev->phy.interfmode) {
77         case B43legacy_INTERFMODE_NONE:
78                 count = snprintf(buf, PAGE_SIZE, "0 (No Interference"
79                                  " Mitigation)\n");
80                 break;
81         case B43legacy_INTERFMODE_NONWLAN:
82                 count = snprintf(buf, PAGE_SIZE, "1 (Non-WLAN Interference"
83                                  " Mitigation)\n");
84                 break;
85         case B43legacy_INTERFMODE_MANUALWLAN:
86                 count = snprintf(buf, PAGE_SIZE, "2 (WLAN Interference"
87                                  " Mitigation)\n");
88                 break;
89         default:
90                 B43legacy_WARN_ON(1);
91         }
92
93         mutex_unlock(&wldev->wl->mutex);
94
95         return count;
96 }
97
98 static ssize_t b43legacy_attr_interfmode_store(struct device *dev,
99                                                struct device_attribute *attr,
100                                                const char *buf, size_t count)
101 {
102         struct b43legacy_wldev *wldev = dev_to_b43legacy_wldev(dev);
103         unsigned long flags;
104         int err;
105         int mode;
106
107         if (!capable(CAP_NET_ADMIN))
108                 return -EPERM;
109
110         mode = get_integer(buf, count);
111         switch (mode) {
112         case 0:
113                 mode = B43legacy_INTERFMODE_NONE;
114                 break;
115         case 1:
116                 mode = B43legacy_INTERFMODE_NONWLAN;
117                 break;
118         case 2:
119                 mode = B43legacy_INTERFMODE_MANUALWLAN;
120                 break;
121         case 3:
122                 mode = B43legacy_INTERFMODE_AUTOWLAN;
123                 break;
124         default:
125                 return -EINVAL;
126         }
127
128         mutex_lock(&wldev->wl->mutex);
129         spin_lock_irqsave(&wldev->wl->irq_lock, flags);
130
131         err = b43legacy_radio_set_interference_mitigation(wldev, mode);
132         if (err)
133                 b43legacyerr(wldev->wl, "Interference Mitigation not "
134                        "supported by device\n");
135         spin_unlock_irqrestore(&wldev->wl->irq_lock, flags);
136         mutex_unlock(&wldev->wl->mutex);
137
138         return err ? err : count;
139 }
140
141 static DEVICE_ATTR(interference, 0644,
142                    b43legacy_attr_interfmode_show,
143                    b43legacy_attr_interfmode_store);
144
145 static ssize_t b43legacy_attr_preamble_show(struct device *dev,
146                                             struct device_attribute *attr,
147                                             char *buf)
148 {
149         struct b43legacy_wldev *wldev = dev_to_b43legacy_wldev(dev);
150         ssize_t count;
151
152         if (!capable(CAP_NET_ADMIN))
153                 return -EPERM;
154
155         mutex_lock(&wldev->wl->mutex);
156
157         if (wldev->short_preamble)
158                 count = snprintf(buf, PAGE_SIZE, "1 (Short Preamble"
159                                  " enabled)\n");
160         else
161                 count = snprintf(buf, PAGE_SIZE, "0 (Short Preamble"
162                                  " disabled)\n");
163
164         mutex_unlock(&wldev->wl->mutex);
165
166         return count;
167 }
168
169 static ssize_t b43legacy_attr_preamble_store(struct device *dev,
170                                              struct device_attribute *attr,
171                                              const char *buf, size_t count)
172 {
173         struct b43legacy_wldev *wldev = dev_to_b43legacy_wldev(dev);
174         unsigned long flags;
175         int value;
176
177         if (!capable(CAP_NET_ADMIN))
178                 return -EPERM;
179
180         value = get_boolean(buf, count);
181         if (value < 0)
182                 return value;
183         mutex_lock(&wldev->wl->mutex);
184         spin_lock_irqsave(&wldev->wl->irq_lock, flags);
185
186         wldev->short_preamble = !!value;
187
188         spin_unlock_irqrestore(&wldev->wl->irq_lock, flags);
189         mutex_unlock(&wldev->wl->mutex);
190
191         return count;
192 }
193
194 static DEVICE_ATTR(shortpreamble, 0644,
195                    b43legacy_attr_preamble_show,
196                    b43legacy_attr_preamble_store);
197
198 int b43legacy_sysfs_register(struct b43legacy_wldev *wldev)
199 {
200         struct device *dev = wldev->dev->dev;
201         int err;
202
203         B43legacy_WARN_ON(b43legacy_status(wldev) !=
204                           B43legacy_STAT_INITIALIZED);
205
206         err = device_create_file(dev, &dev_attr_interference);
207         if (err)
208                 goto out;
209         err = device_create_file(dev, &dev_attr_shortpreamble);
210         if (err)
211                 goto err_remove_interfmode;
212
213 out:
214         return err;
215 err_remove_interfmode:
216         device_remove_file(dev, &dev_attr_interference);
217         goto out;
218 }
219
220 void b43legacy_sysfs_unregister(struct b43legacy_wldev *wldev)
221 {
222         struct device *dev = wldev->dev->dev;
223
224         device_remove_file(dev, &dev_attr_shortpreamble);
225         device_remove_file(dev, &dev_attr_interference);
226 }