sysfs.c 3.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128
  1. /* This program is free software; you can redistribute it and/or modify
  2. * it under the terms of the GNU General Public License version 2
  3. * as published by the Free Software Foundation.
  4. *
  5. * This program is distributed in the hope that it will be useful,
  6. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  7. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  8. * GNU General Public License for more details.
  9. *
  10. * Authors:
  11. * Alexander Aring <aar@pengutronix.de>
  12. *
  13. * Based on: net/wireless/sysfs.c
  14. */
  15. #include <linux/device.h>
  16. #include <net/cfg802154.h>
  17. #include "core.h"
  18. #include "sysfs.h"
  19. static inline struct cfg802154_registered_device *
  20. dev_to_rdev(struct device *dev)
  21. {
  22. return container_of(dev, struct cfg802154_registered_device,
  23. wpan_phy.dev);
  24. }
  25. #define SHOW_FMT(name, fmt, member) \
  26. static ssize_t name ## _show(struct device *dev, \
  27. struct device_attribute *attr, \
  28. char *buf) \
  29. { \
  30. return sprintf(buf, fmt "\n", dev_to_rdev(dev)->member); \
  31. } \
  32. static DEVICE_ATTR_RO(name)
  33. SHOW_FMT(index, "%d", wpan_phy_idx);
  34. static ssize_t name_show(struct device *dev,
  35. struct device_attribute *attr,
  36. char *buf)
  37. {
  38. struct wpan_phy *wpan_phy = &dev_to_rdev(dev)->wpan_phy;
  39. return sprintf(buf, "%s\n", dev_name(&wpan_phy->dev));
  40. }
  41. static DEVICE_ATTR_RO(name);
  42. #define MASTER_SHOW_COMPLEX(name, format_string, args...) \
  43. static ssize_t name ## _show(struct device *dev, \
  44. struct device_attribute *attr, char *buf) \
  45. { \
  46. struct wpan_phy *phy = container_of(dev, struct wpan_phy, dev); \
  47. int ret; \
  48. \
  49. mutex_lock(&phy->pib_lock); \
  50. ret = snprintf(buf, PAGE_SIZE, format_string "\n", args); \
  51. mutex_unlock(&phy->pib_lock); \
  52. return ret; \
  53. } \
  54. static DEVICE_ATTR_RO(name)
  55. #define MASTER_SHOW(field, format_string) \
  56. MASTER_SHOW_COMPLEX(field, format_string, phy->field)
  57. MASTER_SHOW(current_channel, "%d");
  58. MASTER_SHOW(current_page, "%d");
  59. MASTER_SHOW(transmit_power, "%d +- 1 dB");
  60. MASTER_SHOW_COMPLEX(cca_mode, "%d", phy->cca.mode);
  61. static ssize_t channels_supported_show(struct device *dev,
  62. struct device_attribute *attr,
  63. char *buf)
  64. {
  65. struct wpan_phy *phy = container_of(dev, struct wpan_phy, dev);
  66. int ret;
  67. int i, len = 0;
  68. mutex_lock(&phy->pib_lock);
  69. for (i = 0; i < 32; i++) {
  70. ret = snprintf(buf + len, PAGE_SIZE - len,
  71. "%#09x\n", phy->channels_supported[i]);
  72. if (ret < 0)
  73. break;
  74. len += ret;
  75. }
  76. mutex_unlock(&phy->pib_lock);
  77. return len;
  78. }
  79. static DEVICE_ATTR_RO(channels_supported);
  80. static void wpan_phy_release(struct device *dev)
  81. {
  82. struct cfg802154_registered_device *rdev = dev_to_rdev(dev);
  83. cfg802154_dev_free(rdev);
  84. }
  85. static struct attribute *pmib_attrs[] = {
  86. &dev_attr_index.attr,
  87. &dev_attr_name.attr,
  88. /* below will be removed soon */
  89. &dev_attr_current_channel.attr,
  90. &dev_attr_current_page.attr,
  91. &dev_attr_channels_supported.attr,
  92. &dev_attr_transmit_power.attr,
  93. &dev_attr_cca_mode.attr,
  94. NULL,
  95. };
  96. ATTRIBUTE_GROUPS(pmib);
  97. struct class wpan_phy_class = {
  98. .name = "ieee802154",
  99. .dev_release = wpan_phy_release,
  100. .dev_groups = pmib_groups,
  101. };
  102. int wpan_phy_sysfs_init(void)
  103. {
  104. return class_register(&wpan_phy_class);
  105. }
  106. void wpan_phy_sysfs_exit(void)
  107. {
  108. class_unregister(&wpan_phy_class);
  109. }