Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0-or-later
0002 /*
0003 
0004   Broadcom B43 wireless driver
0005 
0006   SYSFS support routines
0007 
0008   Copyright (c) 2006 Michael Buesch <m@bues.ch>
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 }