cachepc-linux

Fork of AMDESE/linux with modifications for CachePC side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-linux
Log | Files | Refs | README | LICENSE | sfeed.txt

sysfs.c (4951B)


      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 = 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
     98static 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
    141static DEVICE_ATTR(interference, 0644,
    142		   b43legacy_attr_interfmode_show,
    143		   b43legacy_attr_interfmode_store);
    144
    145static 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
    169static 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
    194static DEVICE_ATTR(shortpreamble, 0644,
    195		   b43legacy_attr_preamble_show,
    196		   b43legacy_attr_preamble_store);
    197
    198int 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
    213out:
    214	return err;
    215err_remove_interfmode:
    216	device_remove_file(dev, &dev_attr_interference);
    217	goto out;
    218}
    219
    220void 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}