]> Git Repo - J-linux.git/blob - drivers/net/wireless/broadcom/b43legacy/sysfs.c
Merge tag 'vfs-6.13-rc7.fixes' of git://git.kernel.org/pub/scm/linux/kernel/git/vfs/vfs
[J-linux.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 <[email protected]>
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 = sysfs_emit(buf, "0 (No Interference Mitigation)\n");
79                 break;
80         case B43legacy_INTERFMODE_NONWLAN:
81                 count = sysfs_emit(buf,
82                                    "1 (Non-WLAN Interference Mitigation)\n");
83                 break;
84         case B43legacy_INTERFMODE_MANUALWLAN:
85                 count = sysfs_emit(buf, "2 (WLAN Interference Mitigation)\n");
86                 break;
87         default:
88                 B43legacy_WARN_ON(1);
89         }
90
91         mutex_unlock(&wldev->wl->mutex);
92
93         return count;
94 }
95
96 static ssize_t b43legacy_attr_interfmode_store(struct device *dev,
97                                                struct device_attribute *attr,
98                                                const char *buf, size_t count)
99 {
100         struct b43legacy_wldev *wldev = dev_to_b43legacy_wldev(dev);
101         unsigned long flags;
102         int err;
103         int mode;
104
105         if (!capable(CAP_NET_ADMIN))
106                 return -EPERM;
107
108         mode = get_integer(buf, count);
109         switch (mode) {
110         case 0:
111                 mode = B43legacy_INTERFMODE_NONE;
112                 break;
113         case 1:
114                 mode = B43legacy_INTERFMODE_NONWLAN;
115                 break;
116         case 2:
117                 mode = B43legacy_INTERFMODE_MANUALWLAN;
118                 break;
119         case 3:
120                 mode = B43legacy_INTERFMODE_AUTOWLAN;
121                 break;
122         default:
123                 return -EINVAL;
124         }
125
126         mutex_lock(&wldev->wl->mutex);
127         spin_lock_irqsave(&wldev->wl->irq_lock, flags);
128
129         err = b43legacy_radio_set_interference_mitigation(wldev, mode);
130         if (err)
131                 b43legacyerr(wldev->wl, "Interference Mitigation not "
132                        "supported by device\n");
133         spin_unlock_irqrestore(&wldev->wl->irq_lock, flags);
134         mutex_unlock(&wldev->wl->mutex);
135
136         return err ? err : count;
137 }
138
139 static DEVICE_ATTR(interference, 0644,
140                    b43legacy_attr_interfmode_show,
141                    b43legacy_attr_interfmode_store);
142
143 static ssize_t b43legacy_attr_preamble_show(struct device *dev,
144                                             struct device_attribute *attr,
145                                             char *buf)
146 {
147         struct b43legacy_wldev *wldev = dev_to_b43legacy_wldev(dev);
148         ssize_t count;
149
150         if (!capable(CAP_NET_ADMIN))
151                 return -EPERM;
152
153         mutex_lock(&wldev->wl->mutex);
154
155         if (wldev->short_preamble)
156                 count = sysfs_emit(buf, "1 (Short Preamble enabled)\n");
157         else
158                 count = sysfs_emit(buf, "0 (Short Preamble disabled)\n");
159
160         mutex_unlock(&wldev->wl->mutex);
161
162         return count;
163 }
164
165 static ssize_t b43legacy_attr_preamble_store(struct device *dev,
166                                              struct device_attribute *attr,
167                                              const char *buf, size_t count)
168 {
169         struct b43legacy_wldev *wldev = dev_to_b43legacy_wldev(dev);
170         unsigned long flags;
171         int value;
172
173         if (!capable(CAP_NET_ADMIN))
174                 return -EPERM;
175
176         value = get_boolean(buf, count);
177         if (value < 0)
178                 return value;
179         mutex_lock(&wldev->wl->mutex);
180         spin_lock_irqsave(&wldev->wl->irq_lock, flags);
181
182         wldev->short_preamble = !!value;
183
184         spin_unlock_irqrestore(&wldev->wl->irq_lock, flags);
185         mutex_unlock(&wldev->wl->mutex);
186
187         return count;
188 }
189
190 static DEVICE_ATTR(shortpreamble, 0644,
191                    b43legacy_attr_preamble_show,
192                    b43legacy_attr_preamble_store);
193
194 int b43legacy_sysfs_register(struct b43legacy_wldev *wldev)
195 {
196         struct device *dev = wldev->dev->dev;
197         int err;
198
199         B43legacy_WARN_ON(b43legacy_status(wldev) !=
200                           B43legacy_STAT_INITIALIZED);
201
202         err = device_create_file(dev, &dev_attr_interference);
203         if (err)
204                 goto out;
205         err = device_create_file(dev, &dev_attr_shortpreamble);
206         if (err)
207                 goto err_remove_interfmode;
208
209 out:
210         return err;
211 err_remove_interfmode:
212         device_remove_file(dev, &dev_attr_interference);
213         goto out;
214 }
215
216 void b43legacy_sysfs_unregister(struct b43legacy_wldev *wldev)
217 {
218         struct device *dev = wldev->dev->dev;
219
220         device_remove_file(dev, &dev_attr_shortpreamble);
221         device_remove_file(dev, &dev_attr_interference);
222 }
This page took 0.040331 seconds and 4 git commands to generate.