summaryrefslogtreecommitdiffstats
path: root/net/ieee802154/wpan-class.c
diff options
context:
space:
mode:
Diffstat (limited to 'net/ieee802154/wpan-class.c')
-rw-r--r--net/ieee802154/wpan-class.c77
1 files changed, 69 insertions, 8 deletions
diff --git a/net/ieee802154/wpan-class.c b/net/ieee802154/wpan-class.c
index f306604da67..38bac70cca1 100644
--- a/net/ieee802154/wpan-class.c
+++ b/net/ieee802154/wpan-class.c
@@ -22,6 +22,8 @@
#include <net/wpan-phy.h>
+#include "ieee802154.h"
+
#define MASTER_SHOW_COMPLEX(name, format_string, args...) \
static ssize_t name ## _show(struct device *dev, \
struct device_attribute *attr, char *buf) \
@@ -30,7 +32,7 @@ static ssize_t name ## _show(struct device *dev, \
int ret; \
\
mutex_lock(&phy->pib_lock); \
- ret = sprintf(buf, format_string "\n", args); \
+ ret = snprintf(buf, PAGE_SIZE, format_string "\n", args); \
mutex_unlock(&phy->pib_lock); \
return ret; \
}
@@ -40,12 +42,30 @@ static ssize_t name ## _show(struct device *dev, \
MASTER_SHOW(current_channel, "%d");
MASTER_SHOW(current_page, "%d");
-MASTER_SHOW(channels_supported, "%#x");
MASTER_SHOW_COMPLEX(transmit_power, "%d +- %d dB",
((signed char) (phy->transmit_power << 2)) >> 2,
(phy->transmit_power >> 6) ? (phy->transmit_power >> 6) * 3 : 1 );
MASTER_SHOW(cca_mode, "%d");
+static ssize_t channels_supported_show(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ struct wpan_phy *phy = container_of(dev, struct wpan_phy, dev);
+ int ret;
+ int i, len = 0;
+
+ mutex_lock(&phy->pib_lock);
+ for (i = 0; i < 32; i++) {
+ ret = snprintf(buf + len, PAGE_SIZE - len,
+ "%#09x\n", phy->channels_supported[i]);
+ if (ret < 0)
+ break;
+ len += ret;
+ }
+ mutex_unlock(&phy->pib_lock);
+ return len;
+}
+
static struct device_attribute pmib_attrs[] = {
__ATTR_RO(current_channel),
__ATTR_RO(current_page),
@@ -91,6 +111,31 @@ struct wpan_phy *wpan_phy_find(const char *str)
}
EXPORT_SYMBOL(wpan_phy_find);
+struct wpan_phy_iter_data {
+ int (*fn)(struct wpan_phy *phy, void *data);
+ void *data;
+};
+
+static int wpan_phy_iter(struct device *dev, void *_data)
+{
+ struct wpan_phy_iter_data *wpid = _data;
+ struct wpan_phy *phy = container_of(dev, struct wpan_phy, dev);
+ return wpid->fn(phy, wpid->data);
+}
+
+int wpan_phy_for_each(int (*fn)(struct wpan_phy *phy, void *data),
+ void *data)
+{
+ struct wpan_phy_iter_data wpid = {
+ .fn = fn,
+ .data = data,
+ };
+
+ return class_for_each_device(&wpan_phy_class, NULL,
+ &wpid, wpan_phy_iter);
+}
+EXPORT_SYMBOL(wpan_phy_for_each);
+
static int wpan_phy_idx_valid(int idx)
{
return idx >= 0;
@@ -118,14 +163,15 @@ struct wpan_phy *wpan_phy_alloc(size_t priv_size)
phy->dev.class = &wpan_phy_class;
+ phy->current_channel = -1; /* not initialised */
+ phy->current_page = 0; /* for compatibility */
+
return phy;
}
EXPORT_SYMBOL(wpan_phy_alloc);
-int wpan_phy_register(struct device *parent, struct wpan_phy *phy)
+int wpan_phy_register(struct wpan_phy *phy)
{
- phy->dev.parent = parent;
-
return device_add(&phy->dev);
}
EXPORT_SYMBOL(wpan_phy_register);
@@ -144,16 +190,31 @@ EXPORT_SYMBOL(wpan_phy_free);
static int __init wpan_phy_class_init(void)
{
- return class_register(&wpan_phy_class);
+ int rc;
+ rc = class_register(&wpan_phy_class);
+ if (rc)
+ goto err;
+
+ rc = ieee802154_nl_init();
+ if (rc)
+ goto err_nl;
+
+ return 0;
+err_nl:
+ class_unregister(&wpan_phy_class);
+err:
+ return rc;
}
-subsys_initcall(wpan_phy_class_init);
+module_init(wpan_phy_class_init);
static void __exit wpan_phy_class_exit(void)
{
+ ieee802154_nl_exit();
class_unregister(&wpan_phy_class);
}
module_exit(wpan_phy_class_exit);
-MODULE_DESCRIPTION("IEEE 802.15.4 device class");
MODULE_LICENSE("GPL v2");
+MODULE_DESCRIPTION("IEEE 802.15.4 configuration interface");
+MODULE_AUTHOR("Dmitry Eremin-Solenikov");