sysfs.c 3.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158
  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_common.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. if (wldev->phy.type != B43_PHYTYPE_G) {
  47. mutex_unlock(&wldev->wl->mutex);
  48. return -ENOSYS;
  49. }
  50. switch (wldev->phy.g->interfmode) {
  51. case B43_INTERFMODE_NONE:
  52. count =
  53. snprintf(buf, PAGE_SIZE,
  54. "0 (No Interference Mitigation)\n");
  55. break;
  56. case B43_INTERFMODE_NONWLAN:
  57. count =
  58. snprintf(buf, PAGE_SIZE,
  59. "1 (Non-WLAN Interference Mitigation)\n");
  60. break;
  61. case B43_INTERFMODE_MANUALWLAN:
  62. count =
  63. snprintf(buf, PAGE_SIZE,
  64. "2 (WLAN Interference Mitigation)\n");
  65. break;
  66. default:
  67. B43_WARN_ON(1);
  68. }
  69. mutex_unlock(&wldev->wl->mutex);
  70. return count;
  71. }
  72. static ssize_t b43_attr_interfmode_store(struct device *dev,
  73. struct device_attribute *attr,
  74. const char *buf, size_t count)
  75. {
  76. struct b43_wldev *wldev = dev_to_b43_wldev(dev);
  77. unsigned long flags;
  78. int err;
  79. int mode;
  80. if (!capable(CAP_NET_ADMIN))
  81. return -EPERM;
  82. mode = get_integer(buf, count);
  83. switch (mode) {
  84. case 0:
  85. mode = B43_INTERFMODE_NONE;
  86. break;
  87. case 1:
  88. mode = B43_INTERFMODE_NONWLAN;
  89. break;
  90. case 2:
  91. mode = B43_INTERFMODE_MANUALWLAN;
  92. break;
  93. case 3:
  94. mode = B43_INTERFMODE_AUTOWLAN;
  95. break;
  96. default:
  97. return -EINVAL;
  98. }
  99. mutex_lock(&wldev->wl->mutex);
  100. spin_lock_irqsave(&wldev->wl->irq_lock, flags);
  101. if (wldev->phy.ops->interf_mitigation) {
  102. err = wldev->phy.ops->interf_mitigation(wldev, mode);
  103. if (err) {
  104. b43err(wldev->wl, "Interference Mitigation not "
  105. "supported by device\n");
  106. }
  107. } else
  108. err = -ENOSYS;
  109. mmiowb();
  110. spin_unlock_irqrestore(&wldev->wl->irq_lock, flags);
  111. mutex_unlock(&wldev->wl->mutex);
  112. return err ? err : count;
  113. }
  114. static DEVICE_ATTR(interference, 0644,
  115. b43_attr_interfmode_show, b43_attr_interfmode_store);
  116. int b43_sysfs_register(struct b43_wldev *wldev)
  117. {
  118. struct device *dev = wldev->dev->dev;
  119. B43_WARN_ON(b43_status(wldev) != B43_STAT_INITIALIZED);
  120. return device_create_file(dev, &dev_attr_interference);
  121. }
  122. void b43_sysfs_unregister(struct b43_wldev *wldev)
  123. {
  124. struct device *dev = wldev->dev->dev;
  125. device_remove_file(dev, &dev_attr_interference);
  126. }