sysfs.c 3.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155
  1. /*
  2. Broadcom B43 wireless driver
  3. SYSFS support routines
  4. Copyright (c) 2006 Michael Buesch <m@bues.ch>
  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_t(size_t, count, 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. int err;
  78. int mode;
  79. if (!capable(CAP_NET_ADMIN))
  80. return -EPERM;
  81. mode = get_integer(buf, count);
  82. switch (mode) {
  83. case 0:
  84. mode = B43_INTERFMODE_NONE;
  85. break;
  86. case 1:
  87. mode = B43_INTERFMODE_NONWLAN;
  88. break;
  89. case 2:
  90. mode = B43_INTERFMODE_MANUALWLAN;
  91. break;
  92. case 3:
  93. mode = B43_INTERFMODE_AUTOWLAN;
  94. break;
  95. default:
  96. return -EINVAL;
  97. }
  98. mutex_lock(&wldev->wl->mutex);
  99. if (wldev->phy.ops->interf_mitigation) {
  100. err = wldev->phy.ops->interf_mitigation(wldev, mode);
  101. if (err) {
  102. b43err(wldev->wl, "Interference Mitigation not "
  103. "supported by device\n");
  104. }
  105. } else
  106. err = -ENOSYS;
  107. mmiowb();
  108. mutex_unlock(&wldev->wl->mutex);
  109. return err ? err : count;
  110. }
  111. static DEVICE_ATTR(interference, 0644,
  112. b43_attr_interfmode_show, b43_attr_interfmode_store);
  113. int b43_sysfs_register(struct b43_wldev *wldev)
  114. {
  115. struct device *dev = wldev->dev->dev;
  116. B43_WARN_ON(b43_status(wldev) != B43_STAT_INITIALIZED);
  117. return device_create_file(dev, &dev_attr_interference);
  118. }
  119. void b43_sysfs_unregister(struct b43_wldev *wldev)
  120. {
  121. struct device *dev = wldev->dev->dev;
  122. device_remove_file(dev, &dev_attr_interference);
  123. }