diff options
author | David S. Miller <davem@davemloft.net> | 2009-08-23 22:19:30 -0400 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2009-08-23 22:19:30 -0400 |
commit | 940917226260d6e029f55742a34a7d7810983c75 (patch) | |
tree | 871af506fa09aa2717c6c27307838f43993dabaf /net | |
parent | 9818f660f433b58e770cfeb2ee9566f7b42ca0ae (diff) | |
parent | 929122cdd5d4c344e59f9b55f870a8fcf7aa0d27 (diff) |
Merge branch 'for-next' of git://git.kernel.org/pub/scm/linux/kernel/git/lowpan/lowpan
Diffstat (limited to 'net')
-rw-r--r-- | net/core/dev.c | 4 | ||||
-rw-r--r-- | net/ieee802154/Makefile | 2 | ||||
-rw-r--r-- | net/ieee802154/af_ieee802154.c | 4 | ||||
-rw-r--r-- | net/ieee802154/netlink.c | 28 | ||||
-rw-r--r-- | net/ieee802154/nl_policy.c | 1 | ||||
-rw-r--r-- | net/ieee802154/raw.c | 3 | ||||
-rw-r--r-- | net/ieee802154/wpan-class.c | 159 |
7 files changed, 190 insertions, 11 deletions
diff --git a/net/core/dev.c b/net/core/dev.c index 09fb03fa1ae6..4b837896ebd2 100644 --- a/net/core/dev.c +++ b/net/core/dev.c | |||
@@ -269,7 +269,7 @@ static const unsigned short netdev_lock_type[] = | |||
269 | ARPHRD_IRDA, ARPHRD_FCPP, ARPHRD_FCAL, ARPHRD_FCPL, | 269 | ARPHRD_IRDA, ARPHRD_FCPP, ARPHRD_FCAL, ARPHRD_FCPL, |
270 | ARPHRD_FCFABRIC, ARPHRD_IEEE802_TR, ARPHRD_IEEE80211, | 270 | ARPHRD_FCFABRIC, ARPHRD_IEEE802_TR, ARPHRD_IEEE80211, |
271 | ARPHRD_IEEE80211_PRISM, ARPHRD_IEEE80211_RADIOTAP, ARPHRD_PHONET, | 271 | ARPHRD_IEEE80211_PRISM, ARPHRD_IEEE80211_RADIOTAP, ARPHRD_PHONET, |
272 | ARPHRD_PHONET_PIPE, ARPHRD_IEEE802154, ARPHRD_IEEE802154_PHY, | 272 | ARPHRD_PHONET_PIPE, ARPHRD_IEEE802154, |
273 | ARPHRD_VOID, ARPHRD_NONE}; | 273 | ARPHRD_VOID, ARPHRD_NONE}; |
274 | 274 | ||
275 | static const char *const netdev_lock_name[] = | 275 | static const char *const netdev_lock_name[] = |
@@ -287,7 +287,7 @@ static const char *const netdev_lock_name[] = | |||
287 | "_xmit_IRDA", "_xmit_FCPP", "_xmit_FCAL", "_xmit_FCPL", | 287 | "_xmit_IRDA", "_xmit_FCPP", "_xmit_FCAL", "_xmit_FCPL", |
288 | "_xmit_FCFABRIC", "_xmit_IEEE802_TR", "_xmit_IEEE80211", | 288 | "_xmit_FCFABRIC", "_xmit_IEEE802_TR", "_xmit_IEEE80211", |
289 | "_xmit_IEEE80211_PRISM", "_xmit_IEEE80211_RADIOTAP", "_xmit_PHONET", | 289 | "_xmit_IEEE80211_PRISM", "_xmit_IEEE80211_RADIOTAP", "_xmit_PHONET", |
290 | "_xmit_PHONET_PIPE", "_xmit_IEEE802154", "_xmit_IEEE802154_PHY", | 290 | "_xmit_PHONET_PIPE", "_xmit_IEEE802154", |
291 | "_xmit_VOID", "_xmit_NONE"}; | 291 | "_xmit_VOID", "_xmit_NONE"}; |
292 | 292 | ||
293 | static struct lock_class_key netdev_xmit_lock_key[ARRAY_SIZE(netdev_lock_type)]; | 293 | static struct lock_class_key netdev_xmit_lock_key[ARRAY_SIZE(netdev_lock_type)]; |
diff --git a/net/ieee802154/Makefile b/net/ieee802154/Makefile index f99338a26100..4068a9f5113e 100644 --- a/net/ieee802154/Makefile +++ b/net/ieee802154/Makefile | |||
@@ -1,4 +1,4 @@ | |||
1 | obj-$(CONFIG_IEEE802154) += nl802154.o af_802154.o | 1 | obj-$(CONFIG_IEEE802154) += nl802154.o af_802154.o wpan-class.o |
2 | nl802154-y := netlink.o nl_policy.o | 2 | nl802154-y := netlink.o nl_policy.o |
3 | af_802154-y := af_ieee802154.o raw.o dgram.o | 3 | af_802154-y := af_ieee802154.o raw.o dgram.o |
4 | 4 | ||
diff --git a/net/ieee802154/af_ieee802154.c b/net/ieee802154/af_ieee802154.c index d504c349cb0c..cd949d5e451b 100644 --- a/net/ieee802154/af_ieee802154.c +++ b/net/ieee802154/af_ieee802154.c | |||
@@ -147,9 +147,7 @@ static int ieee802154_dev_ioctl(struct sock *sk, struct ifreq __user *arg, | |||
147 | dev_load(sock_net(sk), ifr.ifr_name); | 147 | dev_load(sock_net(sk), ifr.ifr_name); |
148 | dev = dev_get_by_name(sock_net(sk), ifr.ifr_name); | 148 | dev = dev_get_by_name(sock_net(sk), ifr.ifr_name); |
149 | 149 | ||
150 | if ((dev->type == ARPHRD_IEEE802154 || | 150 | if (dev->type == ARPHRD_IEEE802154 && dev->netdev_ops->ndo_do_ioctl) |
151 | dev->type == ARPHRD_IEEE802154_PHY) && | ||
152 | dev->netdev_ops->ndo_do_ioctl) | ||
153 | ret = dev->netdev_ops->ndo_do_ioctl(dev, &ifr, cmd); | 151 | ret = dev->netdev_ops->ndo_do_ioctl(dev, &ifr, cmd); |
154 | 152 | ||
155 | if (!ret && copy_to_user(arg, &ifr, sizeof(struct ifreq))) | 153 | if (!ret && copy_to_user(arg, &ifr, sizeof(struct ifreq))) |
diff --git a/net/ieee802154/netlink.c b/net/ieee802154/netlink.c index cd0567f06716..2106ecbf0308 100644 --- a/net/ieee802154/netlink.c +++ b/net/ieee802154/netlink.c | |||
@@ -232,7 +232,7 @@ nla_put_failure: | |||
232 | EXPORT_SYMBOL(ieee802154_nl_beacon_indic); | 232 | EXPORT_SYMBOL(ieee802154_nl_beacon_indic); |
233 | 233 | ||
234 | int ieee802154_nl_scan_confirm(struct net_device *dev, | 234 | int ieee802154_nl_scan_confirm(struct net_device *dev, |
235 | u8 status, u8 scan_type, u32 unscanned, | 235 | u8 status, u8 scan_type, u32 unscanned, u8 page, |
236 | u8 *edl/* , struct list_head *pan_desc_list */) | 236 | u8 *edl/* , struct list_head *pan_desc_list */) |
237 | { | 237 | { |
238 | struct sk_buff *msg; | 238 | struct sk_buff *msg; |
@@ -251,6 +251,7 @@ int ieee802154_nl_scan_confirm(struct net_device *dev, | |||
251 | NLA_PUT_U8(msg, IEEE802154_ATTR_STATUS, status); | 251 | NLA_PUT_U8(msg, IEEE802154_ATTR_STATUS, status); |
252 | NLA_PUT_U8(msg, IEEE802154_ATTR_SCAN_TYPE, scan_type); | 252 | NLA_PUT_U8(msg, IEEE802154_ATTR_SCAN_TYPE, scan_type); |
253 | NLA_PUT_U32(msg, IEEE802154_ATTR_CHANNELS, unscanned); | 253 | NLA_PUT_U32(msg, IEEE802154_ATTR_CHANNELS, unscanned); |
254 | NLA_PUT_U8(msg, IEEE802154_ATTR_PAGE, page); | ||
254 | 255 | ||
255 | if (edl) | 256 | if (edl) |
256 | NLA_PUT(msg, IEEE802154_ATTR_ED_LIST, 27, edl); | 257 | NLA_PUT(msg, IEEE802154_ATTR_ED_LIST, 27, edl); |
@@ -349,6 +350,7 @@ static int ieee802154_associate_req(struct sk_buff *skb, | |||
349 | { | 350 | { |
350 | struct net_device *dev; | 351 | struct net_device *dev; |
351 | struct ieee802154_addr addr; | 352 | struct ieee802154_addr addr; |
353 | u8 page; | ||
352 | int ret = -EINVAL; | 354 | int ret = -EINVAL; |
353 | 355 | ||
354 | if (!info->attrs[IEEE802154_ATTR_CHANNEL] || | 356 | if (!info->attrs[IEEE802154_ATTR_CHANNEL] || |
@@ -374,8 +376,14 @@ static int ieee802154_associate_req(struct sk_buff *skb, | |||
374 | } | 376 | } |
375 | addr.pan_id = nla_get_u16(info->attrs[IEEE802154_ATTR_COORD_PAN_ID]); | 377 | addr.pan_id = nla_get_u16(info->attrs[IEEE802154_ATTR_COORD_PAN_ID]); |
376 | 378 | ||
379 | if (info->attrs[IEEE802154_ATTR_PAGE]) | ||
380 | page = nla_get_u8(info->attrs[IEEE802154_ATTR_PAGE]); | ||
381 | else | ||
382 | page = 0; | ||
383 | |||
377 | ret = ieee802154_mlme_ops(dev)->assoc_req(dev, &addr, | 384 | ret = ieee802154_mlme_ops(dev)->assoc_req(dev, &addr, |
378 | nla_get_u8(info->attrs[IEEE802154_ATTR_CHANNEL]), | 385 | nla_get_u8(info->attrs[IEEE802154_ATTR_CHANNEL]), |
386 | page, | ||
379 | nla_get_u8(info->attrs[IEEE802154_ATTR_CAPABILITY])); | 387 | nla_get_u8(info->attrs[IEEE802154_ATTR_CAPABILITY])); |
380 | 388 | ||
381 | dev_put(dev); | 389 | dev_put(dev); |
@@ -458,6 +466,7 @@ static int ieee802154_start_req(struct sk_buff *skb, struct genl_info *info) | |||
458 | struct ieee802154_addr addr; | 466 | struct ieee802154_addr addr; |
459 | 467 | ||
460 | u8 channel, bcn_ord, sf_ord; | 468 | u8 channel, bcn_ord, sf_ord; |
469 | u8 page; | ||
461 | int pan_coord, blx, coord_realign; | 470 | int pan_coord, blx, coord_realign; |
462 | int ret; | 471 | int ret; |
463 | 472 | ||
@@ -488,13 +497,19 @@ static int ieee802154_start_req(struct sk_buff *skb, struct genl_info *info) | |||
488 | blx = nla_get_u8(info->attrs[IEEE802154_ATTR_BAT_EXT]); | 497 | blx = nla_get_u8(info->attrs[IEEE802154_ATTR_BAT_EXT]); |
489 | coord_realign = nla_get_u8(info->attrs[IEEE802154_ATTR_COORD_REALIGN]); | 498 | coord_realign = nla_get_u8(info->attrs[IEEE802154_ATTR_COORD_REALIGN]); |
490 | 499 | ||
500 | if (info->attrs[IEEE802154_ATTR_PAGE]) | ||
501 | page = nla_get_u8(info->attrs[IEEE802154_ATTR_PAGE]); | ||
502 | else | ||
503 | page = 0; | ||
504 | |||
505 | |||
491 | if (addr.short_addr == IEEE802154_ADDR_BROADCAST) { | 506 | if (addr.short_addr == IEEE802154_ADDR_BROADCAST) { |
492 | ieee802154_nl_start_confirm(dev, IEEE802154_NO_SHORT_ADDRESS); | 507 | ieee802154_nl_start_confirm(dev, IEEE802154_NO_SHORT_ADDRESS); |
493 | dev_put(dev); | 508 | dev_put(dev); |
494 | return -EINVAL; | 509 | return -EINVAL; |
495 | } | 510 | } |
496 | 511 | ||
497 | ret = ieee802154_mlme_ops(dev)->start_req(dev, &addr, channel, | 512 | ret = ieee802154_mlme_ops(dev)->start_req(dev, &addr, channel, page, |
498 | bcn_ord, sf_ord, pan_coord, blx, coord_realign); | 513 | bcn_ord, sf_ord, pan_coord, blx, coord_realign); |
499 | 514 | ||
500 | dev_put(dev); | 515 | dev_put(dev); |
@@ -508,6 +523,7 @@ static int ieee802154_scan_req(struct sk_buff *skb, struct genl_info *info) | |||
508 | u8 type; | 523 | u8 type; |
509 | u32 channels; | 524 | u32 channels; |
510 | u8 duration; | 525 | u8 duration; |
526 | u8 page; | ||
511 | 527 | ||
512 | if (!info->attrs[IEEE802154_ATTR_SCAN_TYPE] || | 528 | if (!info->attrs[IEEE802154_ATTR_SCAN_TYPE] || |
513 | !info->attrs[IEEE802154_ATTR_CHANNELS] || | 529 | !info->attrs[IEEE802154_ATTR_CHANNELS] || |
@@ -522,7 +538,13 @@ static int ieee802154_scan_req(struct sk_buff *skb, struct genl_info *info) | |||
522 | channels = nla_get_u32(info->attrs[IEEE802154_ATTR_CHANNELS]); | 538 | channels = nla_get_u32(info->attrs[IEEE802154_ATTR_CHANNELS]); |
523 | duration = nla_get_u8(info->attrs[IEEE802154_ATTR_DURATION]); | 539 | duration = nla_get_u8(info->attrs[IEEE802154_ATTR_DURATION]); |
524 | 540 | ||
525 | ret = ieee802154_mlme_ops(dev)->scan_req(dev, type, channels, | 541 | if (info->attrs[IEEE802154_ATTR_PAGE]) |
542 | page = nla_get_u8(info->attrs[IEEE802154_ATTR_PAGE]); | ||
543 | else | ||
544 | page = 0; | ||
545 | |||
546 | |||
547 | ret = ieee802154_mlme_ops(dev)->scan_req(dev, type, channels, page, | ||
526 | duration); | 548 | duration); |
527 | 549 | ||
528 | dev_put(dev); | 550 | dev_put(dev); |
diff --git a/net/ieee802154/nl_policy.c b/net/ieee802154/nl_policy.c index 83cb4ccef90d..2363ebee02e7 100644 --- a/net/ieee802154/nl_policy.c +++ b/net/ieee802154/nl_policy.c | |||
@@ -33,6 +33,7 @@ const struct nla_policy ieee802154_policy[IEEE802154_ATTR_MAX + 1] = { | |||
33 | [IEEE802154_ATTR_HW_ADDR] = { .type = NLA_HW_ADDR, }, | 33 | [IEEE802154_ATTR_HW_ADDR] = { .type = NLA_HW_ADDR, }, |
34 | [IEEE802154_ATTR_PAN_ID] = { .type = NLA_U16, }, | 34 | [IEEE802154_ATTR_PAN_ID] = { .type = NLA_U16, }, |
35 | [IEEE802154_ATTR_CHANNEL] = { .type = NLA_U8, }, | 35 | [IEEE802154_ATTR_CHANNEL] = { .type = NLA_U8, }, |
36 | [IEEE802154_ATTR_PAGE] = { .type = NLA_U8, }, | ||
36 | [IEEE802154_ATTR_COORD_SHORT_ADDR] = { .type = NLA_U16, }, | 37 | [IEEE802154_ATTR_COORD_SHORT_ADDR] = { .type = NLA_U16, }, |
37 | [IEEE802154_ATTR_COORD_HW_ADDR] = { .type = NLA_HW_ADDR, }, | 38 | [IEEE802154_ATTR_COORD_HW_ADDR] = { .type = NLA_HW_ADDR, }, |
38 | [IEEE802154_ATTR_COORD_PAN_ID] = { .type = NLA_U16, }, | 39 | [IEEE802154_ATTR_COORD_PAN_ID] = { .type = NLA_U16, }, |
diff --git a/net/ieee802154/raw.c b/net/ieee802154/raw.c index 60dee69a1d04..4681501aae93 100644 --- a/net/ieee802154/raw.c +++ b/net/ieee802154/raw.c | |||
@@ -74,8 +74,7 @@ static int raw_bind(struct sock *sk, struct sockaddr *uaddr, int len) | |||
74 | goto out; | 74 | goto out; |
75 | } | 75 | } |
76 | 76 | ||
77 | if (dev->type != ARPHRD_IEEE802154_PHY && | 77 | if (dev->type != ARPHRD_IEEE802154) { |
78 | dev->type != ARPHRD_IEEE802154) { | ||
79 | err = -ENODEV; | 78 | err = -ENODEV; |
80 | goto out_put; | 79 | goto out_put; |
81 | } | 80 | } |
diff --git a/net/ieee802154/wpan-class.c b/net/ieee802154/wpan-class.c new file mode 100644 index 000000000000..f306604da67a --- /dev/null +++ b/net/ieee802154/wpan-class.c | |||
@@ -0,0 +1,159 @@ | |||
1 | /* | ||
2 | * Copyright (C) 2007, 2008, 2009 Siemens AG | ||
3 | * | ||
4 | * This program is free software; you can redistribute it and/or modify | ||
5 | * it under the terms of the GNU General Public License version 2 | ||
6 | * as published by the Free Software Foundation. | ||
7 | * | ||
8 | * This program is distributed in the hope that it will be useful, | ||
9 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
10 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
11 | * GNU General Public License for more details. | ||
12 | * | ||
13 | * You should have received a copy of the GNU General Public License along | ||
14 | * with this program; if not, write to the Free Software Foundation, Inc., | ||
15 | * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. | ||
16 | * | ||
17 | */ | ||
18 | |||
19 | #include <linux/kernel.h> | ||
20 | #include <linux/module.h> | ||
21 | #include <linux/device.h> | ||
22 | |||
23 | #include <net/wpan-phy.h> | ||
24 | |||
25 | #define MASTER_SHOW_COMPLEX(name, format_string, args...) \ | ||
26 | static ssize_t name ## _show(struct device *dev, \ | ||
27 | struct device_attribute *attr, char *buf) \ | ||
28 | { \ | ||
29 | struct wpan_phy *phy = container_of(dev, struct wpan_phy, dev); \ | ||
30 | int ret; \ | ||
31 | \ | ||
32 | mutex_lock(&phy->pib_lock); \ | ||
33 | ret = sprintf(buf, format_string "\n", args); \ | ||
34 | mutex_unlock(&phy->pib_lock); \ | ||
35 | return ret; \ | ||
36 | } | ||
37 | |||
38 | #define MASTER_SHOW(field, format_string) \ | ||
39 | MASTER_SHOW_COMPLEX(field, format_string, phy->field) | ||
40 | |||
41 | MASTER_SHOW(current_channel, "%d"); | ||
42 | MASTER_SHOW(current_page, "%d"); | ||
43 | MASTER_SHOW(channels_supported, "%#x"); | ||
44 | MASTER_SHOW_COMPLEX(transmit_power, "%d +- %d dB", | ||
45 | ((signed char) (phy->transmit_power << 2)) >> 2, | ||
46 | (phy->transmit_power >> 6) ? (phy->transmit_power >> 6) * 3 : 1 ); | ||
47 | MASTER_SHOW(cca_mode, "%d"); | ||
48 | |||
49 | static struct device_attribute pmib_attrs[] = { | ||
50 | __ATTR_RO(current_channel), | ||
51 | __ATTR_RO(current_page), | ||
52 | __ATTR_RO(channels_supported), | ||
53 | __ATTR_RO(transmit_power), | ||
54 | __ATTR_RO(cca_mode), | ||
55 | {}, | ||
56 | }; | ||
57 | |||
58 | static void wpan_phy_release(struct device *d) | ||
59 | { | ||
60 | struct wpan_phy *phy = container_of(d, struct wpan_phy, dev); | ||
61 | kfree(phy); | ||
62 | } | ||
63 | |||
64 | static struct class wpan_phy_class = { | ||
65 | .name = "ieee802154", | ||
66 | .dev_release = wpan_phy_release, | ||
67 | .dev_attrs = pmib_attrs, | ||
68 | }; | ||
69 | |||
70 | static DEFINE_MUTEX(wpan_phy_mutex); | ||
71 | static int wpan_phy_idx; | ||
72 | |||
73 | static int wpan_phy_match(struct device *dev, void *data) | ||
74 | { | ||
75 | return !strcmp(dev_name(dev), (const char *)data); | ||
76 | } | ||
77 | |||
78 | struct wpan_phy *wpan_phy_find(const char *str) | ||
79 | { | ||
80 | struct device *dev; | ||
81 | |||
82 | if (WARN_ON(!str)) | ||
83 | return NULL; | ||
84 | |||
85 | dev = class_find_device(&wpan_phy_class, NULL, | ||
86 | (void *)str, wpan_phy_match); | ||
87 | if (!dev) | ||
88 | return NULL; | ||
89 | |||
90 | return container_of(dev, struct wpan_phy, dev); | ||
91 | } | ||
92 | EXPORT_SYMBOL(wpan_phy_find); | ||
93 | |||
94 | static int wpan_phy_idx_valid(int idx) | ||
95 | { | ||
96 | return idx >= 0; | ||
97 | } | ||
98 | |||
99 | struct wpan_phy *wpan_phy_alloc(size_t priv_size) | ||
100 | { | ||
101 | struct wpan_phy *phy = kzalloc(sizeof(*phy) + priv_size, | ||
102 | GFP_KERNEL); | ||
103 | |||
104 | mutex_lock(&wpan_phy_mutex); | ||
105 | phy->idx = wpan_phy_idx++; | ||
106 | if (unlikely(!wpan_phy_idx_valid(phy->idx))) { | ||
107 | wpan_phy_idx--; | ||
108 | mutex_unlock(&wpan_phy_mutex); | ||
109 | kfree(phy); | ||
110 | return NULL; | ||
111 | } | ||
112 | mutex_unlock(&wpan_phy_mutex); | ||
113 | |||
114 | mutex_init(&phy->pib_lock); | ||
115 | |||
116 | device_initialize(&phy->dev); | ||
117 | dev_set_name(&phy->dev, "wpan-phy%d", phy->idx); | ||
118 | |||
119 | phy->dev.class = &wpan_phy_class; | ||
120 | |||
121 | return phy; | ||
122 | } | ||
123 | EXPORT_SYMBOL(wpan_phy_alloc); | ||
124 | |||
125 | int wpan_phy_register(struct device *parent, struct wpan_phy *phy) | ||
126 | { | ||
127 | phy->dev.parent = parent; | ||
128 | |||
129 | return device_add(&phy->dev); | ||
130 | } | ||
131 | EXPORT_SYMBOL(wpan_phy_register); | ||
132 | |||
133 | void wpan_phy_unregister(struct wpan_phy *phy) | ||
134 | { | ||
135 | device_del(&phy->dev); | ||
136 | } | ||
137 | EXPORT_SYMBOL(wpan_phy_unregister); | ||
138 | |||
139 | void wpan_phy_free(struct wpan_phy *phy) | ||
140 | { | ||
141 | put_device(&phy->dev); | ||
142 | } | ||
143 | EXPORT_SYMBOL(wpan_phy_free); | ||
144 | |||
145 | static int __init wpan_phy_class_init(void) | ||
146 | { | ||
147 | return class_register(&wpan_phy_class); | ||
148 | } | ||
149 | subsys_initcall(wpan_phy_class_init); | ||
150 | |||
151 | static void __exit wpan_phy_class_exit(void) | ||
152 | { | ||
153 | class_unregister(&wpan_phy_class); | ||
154 | } | ||
155 | module_exit(wpan_phy_class_exit); | ||
156 | |||
157 | MODULE_DESCRIPTION("IEEE 802.15.4 device class"); | ||
158 | MODULE_LICENSE("GPL v2"); | ||
159 | |||