File Index
Files and directories
Sign in
FILE

sysfs.c

File preview with syntax highlighting.

linux-6.19.14/drivers/net/wireless/broadcom/b43legacy/sysfs.c 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
 25static 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;
 37out:
 38	return ret;
 39}
 40
 41static 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
 64static 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
 96static 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
139static DEVICE_ATTR(interference, 0644,
140		   b43legacy_attr_interfmode_show,
141		   b43legacy_attr_interfmode_store);
142
143static 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
165static 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
190static DEVICE_ATTR(shortpreamble, 0644,
191		   b43legacy_attr_preamble_show,
192		   b43legacy_attr_preamble_store);
193
194int 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
209out:
210	return err;
211err_remove_interfmode:
212	device_remove_file(dev, &dev_attr_interference);
213	goto out;
214}
215
216void 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}
~/ Read-only file preview.