brintos

brintos / linux-shallow public Read only

0
0
Text · 4.8 KiB · d988fe5 Raw
223 lines · c
1// SPDX-License-Identifier: GPL-2.0-or-later2/*3 4  Broadcom B43legacy wireless driver5 6  SYSFS support routines7 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	6423 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	else158		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}223