0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013 #include <linux/capability.h>
0014 #include <linux/io.h>
0015
0016 #include "b43.h"
0017 #include "sysfs.h"
0018 #include "main.h"
0019 #include "phy_common.h"
0020
0021 #define GENERIC_FILESIZE 64
0022
0023 static int get_integer(const char *buf, size_t count)
0024 {
0025 char tmp[10 + 1] = { 0 };
0026 int ret = -EINVAL;
0027
0028 if (count == 0)
0029 goto out;
0030 count = min_t(size_t, count, 10);
0031 memcpy(tmp, buf, count);
0032 ret = simple_strtol(tmp, NULL, 10);
0033 out:
0034 return ret;
0035 }
0036
0037 static ssize_t b43_attr_interfmode_show(struct device *dev,
0038 struct device_attribute *attr,
0039 char *buf)
0040 {
0041 struct b43_wldev *wldev = dev_to_b43_wldev(dev);
0042 ssize_t count = 0;
0043
0044 if (!capable(CAP_NET_ADMIN))
0045 return -EPERM;
0046
0047 mutex_lock(&wldev->wl->mutex);
0048
0049 if (wldev->phy.type != B43_PHYTYPE_G) {
0050 mutex_unlock(&wldev->wl->mutex);
0051 return -ENOSYS;
0052 }
0053
0054 switch (wldev->phy.g->interfmode) {
0055 case B43_INTERFMODE_NONE:
0056 count =
0057 snprintf(buf, PAGE_SIZE,
0058 "0 (No Interference Mitigation)\n");
0059 break;
0060 case B43_INTERFMODE_NONWLAN:
0061 count =
0062 snprintf(buf, PAGE_SIZE,
0063 "1 (Non-WLAN Interference Mitigation)\n");
0064 break;
0065 case B43_INTERFMODE_MANUALWLAN:
0066 count =
0067 snprintf(buf, PAGE_SIZE,
0068 "2 (WLAN Interference Mitigation)\n");
0069 break;
0070 default:
0071 B43_WARN_ON(1);
0072 }
0073
0074 mutex_unlock(&wldev->wl->mutex);
0075
0076 return count;
0077 }
0078
0079 static ssize_t b43_attr_interfmode_store(struct device *dev,
0080 struct device_attribute *attr,
0081 const char *buf, size_t count)
0082 {
0083 struct b43_wldev *wldev = dev_to_b43_wldev(dev);
0084 int err;
0085 int mode;
0086
0087 if (!capable(CAP_NET_ADMIN))
0088 return -EPERM;
0089
0090 mode = get_integer(buf, count);
0091 switch (mode) {
0092 case 0:
0093 mode = B43_INTERFMODE_NONE;
0094 break;
0095 case 1:
0096 mode = B43_INTERFMODE_NONWLAN;
0097 break;
0098 case 2:
0099 mode = B43_INTERFMODE_MANUALWLAN;
0100 break;
0101 case 3:
0102 mode = B43_INTERFMODE_AUTOWLAN;
0103 break;
0104 default:
0105 return -EINVAL;
0106 }
0107
0108 mutex_lock(&wldev->wl->mutex);
0109
0110 if (wldev->phy.ops->interf_mitigation) {
0111 err = wldev->phy.ops->interf_mitigation(wldev, mode);
0112 if (err) {
0113 b43err(wldev->wl, "Interference Mitigation not "
0114 "supported by device\n");
0115 }
0116 } else
0117 err = -ENOSYS;
0118
0119 mutex_unlock(&wldev->wl->mutex);
0120
0121 return err ? err : count;
0122 }
0123
0124 static DEVICE_ATTR(interference, 0644,
0125 b43_attr_interfmode_show, b43_attr_interfmode_store);
0126
0127 int b43_sysfs_register(struct b43_wldev *wldev)
0128 {
0129 struct device *dev = wldev->dev->dev;
0130
0131 B43_WARN_ON(b43_status(wldev) != B43_STAT_INITIALIZED);
0132
0133 return device_create_file(dev, &dev_attr_interference);
0134 }
0135
0136 void b43_sysfs_unregister(struct b43_wldev *wldev)
0137 {
0138 struct device *dev = wldev->dev->dev;
0139
0140 device_remove_file(dev, &dev_attr_interference);
0141 }