Branch data Line data Source code
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 : 0 : static int get_integer(const char *buf, size_t count)
26 : : {
27 : 0 : char tmp[10 + 1] = { 0 };
28 : 0 : int ret = -EINVAL;
29 : :
30 [ # # ]: 0 : if (count == 0)
31 : 0 : goto out;
32 : 0 : count = min_t(size_t, count, 10);
33 : 0 : memcpy(tmp, buf, count);
34 : 0 : ret = simple_strtol(tmp, NULL, 10);
35 : 0 : out:
36 : 0 : return ret;
37 : : }
38 : :
39 : 0 : static int get_boolean(const char *buf, size_t count)
40 : : {
41 [ # # ]: 0 : if (count != 0) {
42 [ # # ]: 0 : if (buf[0] == '1')
43 : : return 1;
44 [ # # ]: 0 : if (buf[0] == '0')
45 : : return 0;
46 [ # # # # ]: 0 : if (count >= 4 && memcmp(buf, "true", 4) == 0)
47 : : return 1;
48 [ # # # # ]: 0 : if (count >= 5 && memcmp(buf, "false", 5) == 0)
49 : : return 0;
50 [ # # # # ]: 0 : if (count >= 3 && memcmp(buf, "yes", 3) == 0)
51 : : return 1;
52 [ # # # # ]: 0 : if (count >= 2 && memcmp(buf, "no", 2) == 0)
53 : : return 0;
54 [ # # # # ]: 0 : if (count >= 2 && memcmp(buf, "on", 2) == 0)
55 : : return 1;
56 [ # # # # ]: 0 : if (count >= 3 && memcmp(buf, "off", 3) == 0)
57 : 0 : return 0;
58 : : }
59 : : return -EINVAL;
60 : : }
61 : :
62 : 0 : static ssize_t b43legacy_attr_interfmode_show(struct device *dev,
63 : : struct device_attribute *attr,
64 : : char *buf)
65 : : {
66 : 0 : struct b43legacy_wldev *wldev = dev_to_b43legacy_wldev(dev);
67 : 0 : ssize_t count = 0;
68 : :
69 [ # # ]: 0 : if (!capable(CAP_NET_ADMIN))
70 : : return -EPERM;
71 : :
72 : 0 : mutex_lock(&wldev->wl->mutex);
73 : :
74 [ # # # # ]: 0 : switch (wldev->phy.interfmode) {
75 : 0 : case B43legacy_INTERFMODE_NONE:
76 : 0 : count = snprintf(buf, PAGE_SIZE, "0 (No Interference"
77 : : " Mitigation)\n");
78 : 0 : break;
79 : 0 : case B43legacy_INTERFMODE_NONWLAN:
80 : 0 : count = snprintf(buf, PAGE_SIZE, "1 (Non-WLAN Interference"
81 : : " Mitigation)\n");
82 : 0 : break;
83 : 0 : case B43legacy_INTERFMODE_MANUALWLAN:
84 : 0 : count = snprintf(buf, PAGE_SIZE, "2 (WLAN Interference"
85 : : " Mitigation)\n");
86 : 0 : break;
87 : : default:
88 : 0 : B43legacy_WARN_ON(1);
89 : : }
90 : :
91 : 0 : mutex_unlock(&wldev->wl->mutex);
92 : :
93 : 0 : return count;
94 : : }
95 : :
96 : 0 : static ssize_t b43legacy_attr_interfmode_store(struct device *dev,
97 : : struct device_attribute *attr,
98 : : const char *buf, size_t count)
99 : : {
100 : 0 : struct b43legacy_wldev *wldev = dev_to_b43legacy_wldev(dev);
101 : 0 : unsigned long flags;
102 : 0 : int err;
103 : 0 : int mode;
104 : :
105 [ # # ]: 0 : if (!capable(CAP_NET_ADMIN))
106 : : return -EPERM;
107 : :
108 : 0 : mode = get_integer(buf, count);
109 [ # # ]: 0 : 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 : 0 : mutex_lock(&wldev->wl->mutex);
127 : 0 : spin_lock_irqsave(&wldev->wl->irq_lock, flags);
128 : :
129 : 0 : err = b43legacy_radio_set_interference_mitigation(wldev, mode);
130 [ # # ]: 0 : if (err)
131 : 0 : b43legacyerr(wldev->wl, "Interference Mitigation not "
132 : : "supported by device\n");
133 : 0 : spin_unlock_irqrestore(&wldev->wl->irq_lock, flags);
134 : 0 : mutex_unlock(&wldev->wl->mutex);
135 : :
136 [ # # ]: 0 : return err ? err : count;
137 : : }
138 : :
139 : : static DEVICE_ATTR(interference, 0644,
140 : : b43legacy_attr_interfmode_show,
141 : : b43legacy_attr_interfmode_store);
142 : :
143 : 0 : static ssize_t b43legacy_attr_preamble_show(struct device *dev,
144 : : struct device_attribute *attr,
145 : : char *buf)
146 : : {
147 : 0 : struct b43legacy_wldev *wldev = dev_to_b43legacy_wldev(dev);
148 : 0 : ssize_t count;
149 : :
150 [ # # ]: 0 : if (!capable(CAP_NET_ADMIN))
151 : : return -EPERM;
152 : :
153 : 0 : mutex_lock(&wldev->wl->mutex);
154 : :
155 [ # # ]: 0 : if (wldev->short_preamble)
156 : 0 : count = snprintf(buf, PAGE_SIZE, "1 (Short Preamble"
157 : : " enabled)\n");
158 : : else
159 : 0 : count = snprintf(buf, PAGE_SIZE, "0 (Short Preamble"
160 : : " disabled)\n");
161 : :
162 : 0 : mutex_unlock(&wldev->wl->mutex);
163 : :
164 : 0 : return count;
165 : : }
166 : :
167 : 0 : static ssize_t b43legacy_attr_preamble_store(struct device *dev,
168 : : struct device_attribute *attr,
169 : : const char *buf, size_t count)
170 : : {
171 : 0 : struct b43legacy_wldev *wldev = dev_to_b43legacy_wldev(dev);
172 : 0 : unsigned long flags;
173 : 0 : int value;
174 : :
175 [ # # ]: 0 : if (!capable(CAP_NET_ADMIN))
176 : : return -EPERM;
177 : :
178 : 0 : value = get_boolean(buf, count);
179 [ # # ]: 0 : if (value < 0)
180 : 0 : return value;
181 : 0 : mutex_lock(&wldev->wl->mutex);
182 : 0 : spin_lock_irqsave(&wldev->wl->irq_lock, flags);
183 : :
184 : 0 : wldev->short_preamble = !!value;
185 : :
186 : 0 : spin_unlock_irqrestore(&wldev->wl->irq_lock, flags);
187 : 0 : mutex_unlock(&wldev->wl->mutex);
188 : :
189 : 0 : return count;
190 : : }
191 : :
192 : : static DEVICE_ATTR(shortpreamble, 0644,
193 : : b43legacy_attr_preamble_show,
194 : : b43legacy_attr_preamble_store);
195 : :
196 : 0 : int b43legacy_sysfs_register(struct b43legacy_wldev *wldev)
197 : : {
198 : 0 : struct device *dev = wldev->dev->dev;
199 : 0 : int err;
200 : :
201 [ # # ]: 0 : B43legacy_WARN_ON(b43legacy_status(wldev) !=
202 : : B43legacy_STAT_INITIALIZED);
203 : :
204 : 0 : err = device_create_file(dev, &dev_attr_interference);
205 [ # # ]: 0 : if (err)
206 : 0 : goto out;
207 : 0 : err = device_create_file(dev, &dev_attr_shortpreamble);
208 [ # # ]: 0 : if (err)
209 : 0 : goto err_remove_interfmode;
210 : :
211 : 0 : out:
212 : 0 : return err;
213 : : err_remove_interfmode:
214 : 0 : device_remove_file(dev, &dev_attr_interference);
215 : 0 : goto out;
216 : : }
217 : :
218 : 0 : void b43legacy_sysfs_unregister(struct b43legacy_wldev *wldev)
219 : : {
220 : 0 : struct device *dev = wldev->dev->dev;
221 : :
222 : 0 : device_remove_file(dev, &dev_attr_shortpreamble);
223 : 0 : device_remove_file(dev, &dev_attr_interference);
224 : 0 : }
|