Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
at v2.6.28-rc9 158 lines 3.6 kB view raw
1/* 2 3 Broadcom B43 wireless driver 4 5 SYSFS support routines 6 7 Copyright (c) 2006 Michael Buesch <mb@bu3sch.de> 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 unsigned long flags; 98 int err; 99 int mode; 100 101 if (!capable(CAP_NET_ADMIN)) 102 return -EPERM; 103 104 mode = get_integer(buf, count); 105 switch (mode) { 106 case 0: 107 mode = B43_INTERFMODE_NONE; 108 break; 109 case 1: 110 mode = B43_INTERFMODE_NONWLAN; 111 break; 112 case 2: 113 mode = B43_INTERFMODE_MANUALWLAN; 114 break; 115 case 3: 116 mode = B43_INTERFMODE_AUTOWLAN; 117 break; 118 default: 119 return -EINVAL; 120 } 121 122 mutex_lock(&wldev->wl->mutex); 123 spin_lock_irqsave(&wldev->wl->irq_lock, flags); 124 125 if (wldev->phy.ops->interf_mitigation) { 126 err = wldev->phy.ops->interf_mitigation(wldev, mode); 127 if (err) { 128 b43err(wldev->wl, "Interference Mitigation not " 129 "supported by device\n"); 130 } 131 } else 132 err = -ENOSYS; 133 134 mmiowb(); 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 b43_attr_interfmode_show, b43_attr_interfmode_store); 143 144int b43_sysfs_register(struct b43_wldev *wldev) 145{ 146 struct device *dev = wldev->dev->dev; 147 148 B43_WARN_ON(b43_status(wldev) != B43_STAT_INITIALIZED); 149 150 return device_create_file(dev, &dev_attr_interference); 151} 152 153void b43_sysfs_unregister(struct b43_wldev *wldev) 154{ 155 struct device *dev = wldev->dev->dev; 156 157 device_remove_file(dev, &dev_attr_interference); 158}