diff options
author | Dmitry Eremin-Solenikov <dbaryshkov@gmail.com> | 2009-08-19 11:32:24 -0400 |
---|---|---|
committer | Dmitry Eremin-Solenikov <dbaryshkov@gmail.com> | 2009-08-19 15:08:22 -0400 |
commit | 16eea493da563b5a3356a77c6d8776dffc29d3b6 (patch) | |
tree | 6a6444442b8d7789d4c2fcb8ba990453969121fc | |
parent | 81f9510381ee43205564063f2e8650672b11d453 (diff) |
ieee802154: add support for channel pages from IEEE 802.15.4-2006
IEEE 802.15.4-2006 adds new concept: channel pages, which can contain several
channels. Add support for channel pages in the API and in the fakehard driver.
Signed-off-by: Dmitry Eremin-Solenikov <dbaryshkov@gmail.com>
-rw-r--r-- | drivers/ieee802154/fakehard.c | 10 | ||||
-rw-r--r-- | include/linux/nl802154.h | 2 | ||||
-rw-r--r-- | include/net/ieee802154_netdev.h | 6 | ||||
-rw-r--r-- | include/net/nl802154.h | 2 | ||||
-rw-r--r-- | net/ieee802154/netlink.c | 28 | ||||
-rw-r--r-- | net/ieee802154/nl_policy.c | 1 |
6 files changed, 38 insertions, 11 deletions
diff --git a/drivers/ieee802154/fakehard.c b/drivers/ieee802154/fakehard.c index 22a93bc764c5..c1c9697f9fde 100644 --- a/drivers/ieee802154/fakehard.c +++ b/drivers/ieee802154/fakehard.c | |||
@@ -119,12 +119,13 @@ static u8 fake_get_bsn(struct net_device *dev) | |||
119 | * 802.15.4-2006 document. | 119 | * 802.15.4-2006 document. |
120 | */ | 120 | */ |
121 | static int fake_assoc_req(struct net_device *dev, | 121 | static int fake_assoc_req(struct net_device *dev, |
122 | struct ieee802154_addr *addr, u8 channel, u8 cap) | 122 | struct ieee802154_addr *addr, u8 channel, u8 page, u8 cap) |
123 | { | 123 | { |
124 | struct wpan_phy *phy = net_to_phy(dev); | 124 | struct wpan_phy *phy = net_to_phy(dev); |
125 | 125 | ||
126 | mutex_lock(&phy->pib_lock); | 126 | mutex_lock(&phy->pib_lock); |
127 | phy->current_channel = channel; | 127 | phy->current_channel = channel; |
128 | phy->current_page = page; | ||
128 | mutex_unlock(&phy->pib_lock); | 129 | mutex_unlock(&phy->pib_lock); |
129 | 130 | ||
130 | /* We simply emulate it here */ | 131 | /* We simply emulate it here */ |
@@ -191,7 +192,7 @@ static int fake_disassoc_req(struct net_device *dev, | |||
191 | * document, with 7.3.8 describing coordinator realignment. | 192 | * document, with 7.3.8 describing coordinator realignment. |
192 | */ | 193 | */ |
193 | static int fake_start_req(struct net_device *dev, struct ieee802154_addr *addr, | 194 | static int fake_start_req(struct net_device *dev, struct ieee802154_addr *addr, |
194 | u8 channel, | 195 | u8 channel, u8 page, |
195 | u8 bcn_ord, u8 sf_ord, u8 pan_coord, u8 blx, | 196 | u8 bcn_ord, u8 sf_ord, u8 pan_coord, u8 blx, |
196 | u8 coord_realign) | 197 | u8 coord_realign) |
197 | { | 198 | { |
@@ -199,6 +200,7 @@ static int fake_start_req(struct net_device *dev, struct ieee802154_addr *addr, | |||
199 | 200 | ||
200 | mutex_lock(&phy->pib_lock); | 201 | mutex_lock(&phy->pib_lock); |
201 | phy->current_channel = channel; | 202 | phy->current_channel = channel; |
203 | phy->current_page = page; | ||
202 | mutex_unlock(&phy->pib_lock); | 204 | mutex_unlock(&phy->pib_lock); |
203 | 205 | ||
204 | /* We don't emulate beacons here at all, so START should fail */ | 206 | /* We don't emulate beacons here at all, so START should fail */ |
@@ -222,11 +224,11 @@ static int fake_start_req(struct net_device *dev, struct ieee802154_addr *addr, | |||
222 | * Note: This is in section 7.5.2.1 of the IEEE 802.15.4-2006 document. | 224 | * Note: This is in section 7.5.2.1 of the IEEE 802.15.4-2006 document. |
223 | */ | 225 | */ |
224 | static int fake_scan_req(struct net_device *dev, u8 type, u32 channels, | 226 | static int fake_scan_req(struct net_device *dev, u8 type, u32 channels, |
225 | u8 duration) | 227 | u8 page, u8 duration) |
226 | { | 228 | { |
227 | u8 edl[27] = {}; | 229 | u8 edl[27] = {}; |
228 | return ieee802154_nl_scan_confirm(dev, IEEE802154_SUCCESS, type, | 230 | return ieee802154_nl_scan_confirm(dev, IEEE802154_SUCCESS, type, |
229 | channels, | 231 | channels, page, |
230 | type == IEEE802154_MAC_SCAN_ED ? edl : NULL); | 232 | type == IEEE802154_MAC_SCAN_ED ? edl : NULL); |
231 | } | 233 | } |
232 | 234 | ||
diff --git a/include/linux/nl802154.h b/include/linux/nl802154.h index 9a1af5f871a3..b7d9435d5a9f 100644 --- a/include/linux/nl802154.h +++ b/include/linux/nl802154.h | |||
@@ -64,6 +64,8 @@ enum { | |||
64 | IEEE802154_ATTR_COORD_REALIGN, | 64 | IEEE802154_ATTR_COORD_REALIGN, |
65 | IEEE802154_ATTR_SEC, | 65 | IEEE802154_ATTR_SEC, |
66 | 66 | ||
67 | IEEE802154_ATTR_PAGE, | ||
68 | |||
67 | __IEEE802154_ATTR_MAX, | 69 | __IEEE802154_ATTR_MAX, |
68 | }; | 70 | }; |
69 | 71 | ||
diff --git a/include/net/ieee802154_netdev.h b/include/net/ieee802154_netdev.h index e2506af3e7c8..5dc6a61952de 100644 --- a/include/net/ieee802154_netdev.h +++ b/include/net/ieee802154_netdev.h | |||
@@ -80,7 +80,7 @@ static inline int mac_cb_type(struct sk_buff *skb) | |||
80 | struct ieee802154_mlme_ops { | 80 | struct ieee802154_mlme_ops { |
81 | int (*assoc_req)(struct net_device *dev, | 81 | int (*assoc_req)(struct net_device *dev, |
82 | struct ieee802154_addr *addr, | 82 | struct ieee802154_addr *addr, |
83 | u8 channel, u8 cap); | 83 | u8 channel, u8 page, u8 cap); |
84 | int (*assoc_resp)(struct net_device *dev, | 84 | int (*assoc_resp)(struct net_device *dev, |
85 | struct ieee802154_addr *addr, | 85 | struct ieee802154_addr *addr, |
86 | u16 short_addr, u8 status); | 86 | u16 short_addr, u8 status); |
@@ -89,10 +89,10 @@ struct ieee802154_mlme_ops { | |||
89 | u8 reason); | 89 | u8 reason); |
90 | int (*start_req)(struct net_device *dev, | 90 | int (*start_req)(struct net_device *dev, |
91 | struct ieee802154_addr *addr, | 91 | struct ieee802154_addr *addr, |
92 | u8 channel, u8 bcn_ord, u8 sf_ord, | 92 | u8 channel, u8 page, u8 bcn_ord, u8 sf_ord, |
93 | u8 pan_coord, u8 blx, u8 coord_realign); | 93 | u8 pan_coord, u8 blx, u8 coord_realign); |
94 | int (*scan_req)(struct net_device *dev, | 94 | int (*scan_req)(struct net_device *dev, |
95 | u8 type, u32 channels, u8 duration); | 95 | u8 type, u32 channels, u8 page, u8 duration); |
96 | 96 | ||
97 | /* | 97 | /* |
98 | * FIXME: these should become the part of PIB/MIB interface. | 98 | * FIXME: these should become the part of PIB/MIB interface. |
diff --git a/include/net/nl802154.h b/include/net/nl802154.h index e554ecd3727a..99d2ba1c7e03 100644 --- a/include/net/nl802154.h +++ b/include/net/nl802154.h | |||
@@ -95,7 +95,7 @@ int ieee802154_nl_disassoc_confirm(struct net_device *dev, | |||
95 | * Note: This API does not permit the return of an active scan result. | 95 | * Note: This API does not permit the return of an active scan result. |
96 | */ | 96 | */ |
97 | int ieee802154_nl_scan_confirm(struct net_device *dev, | 97 | int ieee802154_nl_scan_confirm(struct net_device *dev, |
98 | u8 status, u8 scan_type, u32 unscanned, | 98 | u8 status, u8 scan_type, u32 unscanned, u8 page, |
99 | u8 *edl/*, struct list_head *pan_desc_list */); | 99 | u8 *edl/*, struct list_head *pan_desc_list */); |
100 | 100 | ||
101 | /** | 101 | /** |
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, }, |