sysfs.c 3.3 KB

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