linux/drivers/net/wireless/b43/sysfs.c
<<
>>
Prefs
   1/*
   2
   3  Broadcom B43 wireless driver
   4
   5  SYSFS support routines
   6
   7  Copyright (c) 2006 Michael Buesch <m@bues.ch>
   8
   9  This program is free software; you can redistribute it and/or modify
  10  it under the terms of the GNU General Public License as published by
  11  the Free Software Foundation; either version 2 of the License, or
  12  (at your option) any later version.
  13
  14  This program is distributed in the hope that it will be useful,
  15  but WITHOUT ANY WARRANTY; without even the implied warranty of
  16  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  17  GNU General Public License for more details.
  18
  19  You should have received a copy of the GNU General Public License
  20  along with this program; see the file COPYING.  If not, write to
  21  the Free Software Foundation, Inc., 51 Franklin Steet, Fifth Floor,
  22  Boston, MA 02110-1301, USA.
  23
  24*/
  25
  26#include <linux/capability.h>
  27#include <linux/io.h>
  28
  29#include "b43.h"
  30#include "sysfs.h"
  31#include "main.h"
  32#include "phy_common.h"
  33
  34#define GENERIC_FILESIZE        64
  35
  36static int get_integer(const char *buf, size_t count)
  37{
  38        char tmp[10 + 1] = { 0 };
  39        int ret = -EINVAL;
  40
  41        if (count == 0)
  42                goto out;
  43        count = min(count, (size_t) 10);
  44        memcpy(tmp, buf, count);
  45        ret = simple_strtol(tmp, NULL, 10);
  46      out:
  47        return ret;
  48}
  49
  50static ssize_t b43_attr_interfmode_show(struct device *dev,
  51                                        struct device_attribute *attr,
  52                                        char *buf)
  53{
  54        struct b43_wldev *wldev = dev_to_b43_wldev(dev);
  55        ssize_t count = 0;
  56
  57        if (!capable(CAP_NET_ADMIN))
  58                return -EPERM;
  59
  60        mutex_lock(&wldev->wl->mutex);
  61
  62        if (wldev->phy.type != B43_PHYTYPE_G) {
  63                mutex_unlock(&wldev->wl->mutex);
  64                return -ENOSYS;
  65        }
  66
  67        switch (wldev->phy.g->interfmode) {
  68        case B43_INTERFMODE_NONE:
  69                count =
  70                    snprintf(buf, PAGE_SIZE,
  71                             "0 (No Interference Mitigation)\n");
  72                break;
  73        case B43_INTERFMODE_NONWLAN:
  74                count =
  75                    snprintf(buf, PAGE_SIZE,
  76                             "1 (Non-WLAN Interference Mitigation)\n");
  77                break;
  78        case B43_INTERFMODE_MANUALWLAN:
  79                count =
  80                    snprintf(buf, PAGE_SIZE,
  81                             "2 (WLAN Interference Mitigation)\n");
  82                break;
  83        default:
  84                B43_WARN_ON(1);
  85        }
  86
  87        mutex_unlock(&wldev->wl->mutex);
  88
  89        return count;
  90}
  91
  92static ssize_t b43_attr_interfmode_store(struct device *dev,
  93                                         struct device_attribute *attr,
  94                                         const char *buf, size_t count)
  95{
  96        struct b43_wldev *wldev = dev_to_b43_wldev(dev);
  97        int err;
  98        int mode;
  99
 100        if (!capable(CAP_NET_ADMIN))
 101                return -EPERM;
 102
 103        mode = get_integer(buf, count);
 104        switch (mode) {
 105        case 0:
 106                mode = B43_INTERFMODE_NONE;
 107                break;
 108        case 1:
 109                mode = B43_INTERFMODE_NONWLAN;
 110                break;
 111        case 2:
 112                mode = B43_INTERFMODE_MANUALWLAN;
 113                break;
 114        case 3:
 115                mode = B43_INTERFMODE_AUTOWLAN;
 116                break;
 117        default:
 118                return -EINVAL;
 119        }
 120
 121        mutex_lock(&wldev->wl->mutex);
 122
 123        if (wldev->phy.ops->interf_mitigation) {
 124                err = wldev->phy.ops->interf_mitigation(wldev, mode);
 125                if (err) {
 126                        b43err(wldev->wl, "Interference Mitigation not "
 127                               "supported by device\n");
 128                }
 129        } else
 130                err = -ENOSYS;
 131
 132        mmiowb();
 133        mutex_unlock(&wldev->wl->mutex);
 134
 135        return err ? err : count;
 136}
 137
 138static DEVICE_ATTR(interference, 0644,
 139                   b43_attr_interfmode_show, b43_attr_interfmode_store);
 140
 141int b43_sysfs_register(struct b43_wldev *wldev)
 142{
 143        struct device *dev = wldev->dev->dev;
 144
 145        B43_WARN_ON(b43_status(wldev) != B43_STAT_INITIALIZED);
 146
 147        return device_create_file(dev, &dev_attr_interference);
 148}
 149
 150void b43_sysfs_unregister(struct b43_wldev *wldev)
 151{
 152        struct device *dev = wldev->dev->dev;
 153
 154        device_remove_file(dev, &dev_attr_interference);
 155}
 156