aboutsummaryrefslogtreecommitdiffstats
path: root/net/ieee802154
diff options
context:
space:
mode:
authorPhoebe Buckheister <phoebe.buckheister@itwm.fraunhofer.de>2014-03-31 15:37:46 -0400
committerDavid S. Miller <davem@davemloft.net>2014-04-01 16:25:51 -0400
commite462ded699aa2cca04b68fbf203ea4675d4c44d4 (patch)
tree4c7b2f9d1e456acad01eb052f2dfa7d8533d92d8 /net/ieee802154
parent336908f6d73ca297bd46948eb5d04d2020a88606 (diff)
mac802154: make csma/cca parameters per-wpan
Commit 9b2777d6089bcd (ieee802154: add TX power control to wpan_phy) and following erroneously added CSMA and CCA parameters for 802.15.4 devices as PHY parameters, while they are actually MAC parameters and can differ for any two WPAN instances. Since it is now sensible to have multiple WPAN devices with differing CSMA/CCA parameters, make these parameters MAC parameters instead. Signed-off-by: Phoebe Buckheister <phoebe.buckheister@itwm.fraunhofer.de> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net/ieee802154')
-rw-r--r--net/ieee802154/ieee802154.h2
-rw-r--r--net/ieee802154/netlink.c2
-rw-r--r--net/ieee802154/nl-mac.c122
-rw-r--r--net/ieee802154/nl-phy.c200
-rw-r--r--net/ieee802154/wpan-class.c6
5 files changed, 122 insertions, 210 deletions
diff --git a/net/ieee802154/ieee802154.h b/net/ieee802154/ieee802154.h
index 6cbc8965be91..6693a5cf01ce 100644
--- a/net/ieee802154/ieee802154.h
+++ b/net/ieee802154/ieee802154.h
@@ -53,7 +53,6 @@ int ieee802154_list_phy(struct sk_buff *skb, struct genl_info *info);
53int ieee802154_dump_phy(struct sk_buff *skb, struct netlink_callback *cb); 53int ieee802154_dump_phy(struct sk_buff *skb, struct netlink_callback *cb);
54int ieee802154_add_iface(struct sk_buff *skb, struct genl_info *info); 54int ieee802154_add_iface(struct sk_buff *skb, struct genl_info *info);
55int ieee802154_del_iface(struct sk_buff *skb, struct genl_info *info); 55int ieee802154_del_iface(struct sk_buff *skb, struct genl_info *info);
56int ieee802154_set_phyparams(struct sk_buff *skb, struct genl_info *info);
57 56
58enum ieee802154_mcgrp_ids { 57enum ieee802154_mcgrp_ids {
59 IEEE802154_COORD_MCGRP, 58 IEEE802154_COORD_MCGRP,
@@ -67,5 +66,6 @@ int ieee802154_scan_req(struct sk_buff *skb, struct genl_info *info);
67int ieee802154_start_req(struct sk_buff *skb, struct genl_info *info); 66int ieee802154_start_req(struct sk_buff *skb, struct genl_info *info);
68int ieee802154_list_iface(struct sk_buff *skb, struct genl_info *info); 67int ieee802154_list_iface(struct sk_buff *skb, struct genl_info *info);
69int ieee802154_dump_iface(struct sk_buff *skb, struct netlink_callback *cb); 68int ieee802154_dump_iface(struct sk_buff *skb, struct netlink_callback *cb);
69int ieee802154_set_macparams(struct sk_buff *skb, struct genl_info *info);
70 70
71#endif 71#endif
diff --git a/net/ieee802154/netlink.c b/net/ieee802154/netlink.c
index 67c151bf4b91..04b20589d97a 100644
--- a/net/ieee802154/netlink.c
+++ b/net/ieee802154/netlink.c
@@ -115,7 +115,6 @@ static const struct genl_ops ieee8021154_ops[] = {
115 ieee802154_dump_phy), 115 ieee802154_dump_phy),
116 IEEE802154_OP(IEEE802154_ADD_IFACE, ieee802154_add_iface), 116 IEEE802154_OP(IEEE802154_ADD_IFACE, ieee802154_add_iface),
117 IEEE802154_OP(IEEE802154_DEL_IFACE, ieee802154_del_iface), 117 IEEE802154_OP(IEEE802154_DEL_IFACE, ieee802154_del_iface),
118 IEEE802154_OP(IEEE802154_SET_PHYPARAMS, ieee802154_set_phyparams),
119 /* see nl-mac.c */ 118 /* see nl-mac.c */
120 IEEE802154_OP(IEEE802154_ASSOCIATE_REQ, ieee802154_associate_req), 119 IEEE802154_OP(IEEE802154_ASSOCIATE_REQ, ieee802154_associate_req),
121 IEEE802154_OP(IEEE802154_ASSOCIATE_RESP, ieee802154_associate_resp), 120 IEEE802154_OP(IEEE802154_ASSOCIATE_RESP, ieee802154_associate_resp),
@@ -124,6 +123,7 @@ static const struct genl_ops ieee8021154_ops[] = {
124 IEEE802154_OP(IEEE802154_START_REQ, ieee802154_start_req), 123 IEEE802154_OP(IEEE802154_START_REQ, ieee802154_start_req),
125 IEEE802154_DUMP(IEEE802154_LIST_IFACE, ieee802154_list_iface, 124 IEEE802154_DUMP(IEEE802154_LIST_IFACE, ieee802154_list_iface,
126 ieee802154_dump_iface), 125 ieee802154_dump_iface),
126 IEEE802154_OP(IEEE802154_SET_MACPARAMS, ieee802154_set_macparams),
127}; 127};
128 128
129static const struct genl_multicast_group ieee802154_mcgrps[] = { 129static const struct genl_multicast_group ieee802154_mcgrps[] = {
diff --git a/net/ieee802154/nl-mac.c b/net/ieee802154/nl-mac.c
index bda8dba4f993..5d285498c0f6 100644
--- a/net/ieee802154/nl-mac.c
+++ b/net/ieee802154/nl-mac.c
@@ -264,6 +264,7 @@ static int ieee802154_nl_fill_iface(struct sk_buff *msg, u32 portid,
264{ 264{
265 void *hdr; 265 void *hdr;
266 struct wpan_phy *phy; 266 struct wpan_phy *phy;
267 struct ieee802154_mlme_ops *ops;
267 __le16 short_addr, pan_id; 268 __le16 short_addr, pan_id;
268 269
269 pr_debug("%s\n", __func__); 270 pr_debug("%s\n", __func__);
@@ -273,11 +274,12 @@ static int ieee802154_nl_fill_iface(struct sk_buff *msg, u32 portid,
273 if (!hdr) 274 if (!hdr)
274 goto out; 275 goto out;
275 276
276 phy = ieee802154_mlme_ops(dev)->get_phy(dev); 277 ops = ieee802154_mlme_ops(dev);
278 phy = ops->get_phy(dev);
277 BUG_ON(!phy); 279 BUG_ON(!phy);
278 280
279 short_addr = ieee802154_mlme_ops(dev)->get_short_addr(dev); 281 short_addr = ops->get_short_addr(dev);
280 pan_id = ieee802154_mlme_ops(dev)->get_pan_id(dev); 282 pan_id = ops->get_pan_id(dev);
281 283
282 if (nla_put_string(msg, IEEE802154_ATTR_DEV_NAME, dev->name) || 284 if (nla_put_string(msg, IEEE802154_ATTR_DEV_NAME, dev->name) ||
283 nla_put_string(msg, IEEE802154_ATTR_PHY_NAME, wpan_phy_name(phy)) || 285 nla_put_string(msg, IEEE802154_ATTR_PHY_NAME, wpan_phy_name(phy)) ||
@@ -287,6 +289,30 @@ static int ieee802154_nl_fill_iface(struct sk_buff *msg, u32 portid,
287 nla_put_shortaddr(msg, IEEE802154_ATTR_SHORT_ADDR, short_addr) || 289 nla_put_shortaddr(msg, IEEE802154_ATTR_SHORT_ADDR, short_addr) ||
288 nla_put_shortaddr(msg, IEEE802154_ATTR_PAN_ID, pan_id)) 290 nla_put_shortaddr(msg, IEEE802154_ATTR_PAN_ID, pan_id))
289 goto nla_put_failure; 291 goto nla_put_failure;
292
293 if (ops->get_mac_params) {
294 struct ieee802154_mac_params params;
295
296 ops->get_mac_params(dev, &params);
297
298 if (nla_put_s8(msg, IEEE802154_ATTR_TXPOWER,
299 params.transmit_power) ||
300 nla_put_u8(msg, IEEE802154_ATTR_LBT_ENABLED, params.lbt) ||
301 nla_put_u8(msg, IEEE802154_ATTR_CCA_MODE,
302 params.cca_mode) ||
303 nla_put_s32(msg, IEEE802154_ATTR_CCA_ED_LEVEL,
304 params.cca_ed_level) ||
305 nla_put_u8(msg, IEEE802154_ATTR_CSMA_RETRIES,
306 params.csma_retries) ||
307 nla_put_u8(msg, IEEE802154_ATTR_CSMA_MIN_BE,
308 params.min_be) ||
309 nla_put_u8(msg, IEEE802154_ATTR_CSMA_MAX_BE,
310 params.max_be) ||
311 nla_put_s8(msg, IEEE802154_ATTR_FRAME_RETRIES,
312 params.frame_retries))
313 goto nla_put_failure;
314 }
315
290 wpan_phy_put(phy); 316 wpan_phy_put(phy);
291 return genlmsg_end(msg, hdr); 317 return genlmsg_end(msg, hdr);
292 318
@@ -599,3 +625,93 @@ cont:
599 625
600 return skb->len; 626 return skb->len;
601} 627}
628
629int ieee802154_set_macparams(struct sk_buff *skb, struct genl_info *info)
630{
631 struct net_device *dev = NULL;
632 struct ieee802154_mlme_ops *ops;
633 struct ieee802154_mac_params params;
634 struct wpan_phy *phy;
635 int rc = -EINVAL;
636
637 pr_debug("%s\n", __func__);
638
639 dev = ieee802154_nl_get_dev(info);
640 if (!dev)
641 return -ENODEV;
642
643 ops = ieee802154_mlme_ops(dev);
644
645 if (!ops->get_mac_params || !ops->set_mac_params) {
646 rc = -EOPNOTSUPP;
647 goto out;
648 }
649
650 if (netif_running(dev)) {
651 rc = -EBUSY;
652 goto out;
653 }
654
655 if (!info->attrs[IEEE802154_ATTR_LBT_ENABLED] &&
656 !info->attrs[IEEE802154_ATTR_CCA_MODE] &&
657 !info->attrs[IEEE802154_ATTR_CCA_ED_LEVEL] &&
658 !info->attrs[IEEE802154_ATTR_CSMA_RETRIES] &&
659 !info->attrs[IEEE802154_ATTR_CSMA_MIN_BE] &&
660 !info->attrs[IEEE802154_ATTR_CSMA_MAX_BE] &&
661 !info->attrs[IEEE802154_ATTR_FRAME_RETRIES])
662 goto out;
663
664 phy = ops->get_phy(dev);
665
666 if ((!phy->set_lbt && info->attrs[IEEE802154_ATTR_LBT_ENABLED]) ||
667 (!phy->set_cca_mode && info->attrs[IEEE802154_ATTR_CCA_MODE]) ||
668 (!phy->set_cca_ed_level &&
669 info->attrs[IEEE802154_ATTR_CCA_ED_LEVEL]) ||
670 (!phy->set_csma_params &&
671 (info->attrs[IEEE802154_ATTR_CSMA_RETRIES] ||
672 info->attrs[IEEE802154_ATTR_CSMA_MIN_BE] ||
673 info->attrs[IEEE802154_ATTR_CSMA_MAX_BE])) ||
674 (!phy->set_frame_retries &&
675 info->attrs[IEEE802154_ATTR_FRAME_RETRIES])) {
676 rc = -EOPNOTSUPP;
677 goto out_phy;
678 }
679
680 ops->get_mac_params(dev, &params);
681
682 if (info->attrs[IEEE802154_ATTR_TXPOWER])
683 params.transmit_power = nla_get_s8(info->attrs[IEEE802154_ATTR_TXPOWER]);
684
685 if (info->attrs[IEEE802154_ATTR_LBT_ENABLED])
686 params.lbt = nla_get_u8(info->attrs[IEEE802154_ATTR_LBT_ENABLED]);
687
688 if (info->attrs[IEEE802154_ATTR_CCA_MODE])
689 params.cca_mode = nla_get_u8(info->attrs[IEEE802154_ATTR_CCA_MODE]);
690
691 if (info->attrs[IEEE802154_ATTR_CCA_ED_LEVEL])
692 params.cca_ed_level = nla_get_s32(info->attrs[IEEE802154_ATTR_CCA_ED_LEVEL]);
693
694 if (info->attrs[IEEE802154_ATTR_CSMA_RETRIES])
695 params.csma_retries = nla_get_u8(info->attrs[IEEE802154_ATTR_CSMA_RETRIES]);
696
697 if (info->attrs[IEEE802154_ATTR_CSMA_MIN_BE])
698 params.min_be = nla_get_u8(info->attrs[IEEE802154_ATTR_CSMA_MIN_BE]);
699
700 if (info->attrs[IEEE802154_ATTR_CSMA_MAX_BE])
701 params.max_be = nla_get_u8(info->attrs[IEEE802154_ATTR_CSMA_MAX_BE]);
702
703 if (info->attrs[IEEE802154_ATTR_FRAME_RETRIES])
704 params.frame_retries = nla_get_s8(info->attrs[IEEE802154_ATTR_FRAME_RETRIES]);
705
706 rc = ops->set_mac_params(dev, &params);
707
708 wpan_phy_put(phy);
709 dev_put(dev);
710 return rc;
711
712out_phy:
713 wpan_phy_put(phy);
714out:
715 dev_put(dev);
716 return rc;
717}
diff --git a/net/ieee802154/nl-phy.c b/net/ieee802154/nl-phy.c
index 222310a07762..89b265aea151 100644
--- a/net/ieee802154/nl-phy.c
+++ b/net/ieee802154/nl-phy.c
@@ -55,15 +55,7 @@ static int ieee802154_nl_fill_phy(struct sk_buff *msg, u32 portid,
55 mutex_lock(&phy->pib_lock); 55 mutex_lock(&phy->pib_lock);
56 if (nla_put_string(msg, IEEE802154_ATTR_PHY_NAME, wpan_phy_name(phy)) || 56 if (nla_put_string(msg, IEEE802154_ATTR_PHY_NAME, wpan_phy_name(phy)) ||
57 nla_put_u8(msg, IEEE802154_ATTR_PAGE, phy->current_page) || 57 nla_put_u8(msg, IEEE802154_ATTR_PAGE, phy->current_page) ||
58 nla_put_u8(msg, IEEE802154_ATTR_CHANNEL, phy->current_channel) || 58 nla_put_u8(msg, IEEE802154_ATTR_CHANNEL, phy->current_channel))
59 nla_put_s8(msg, IEEE802154_ATTR_TXPOWER, phy->transmit_power) ||
60 nla_put_u8(msg, IEEE802154_ATTR_LBT_ENABLED, phy->lbt) ||
61 nla_put_u8(msg, IEEE802154_ATTR_CCA_MODE, phy->cca_mode) ||
62 nla_put_s32(msg, IEEE802154_ATTR_CCA_ED_LEVEL, phy->cca_ed_level) ||
63 nla_put_u8(msg, IEEE802154_ATTR_CSMA_RETRIES, phy->csma_retries) ||
64 nla_put_u8(msg, IEEE802154_ATTR_CSMA_MIN_BE, phy->min_be) ||
65 nla_put_u8(msg, IEEE802154_ATTR_CSMA_MAX_BE, phy->max_be) ||
66 nla_put_s8(msg, IEEE802154_ATTR_FRAME_RETRIES, phy->frame_retries))
67 goto nla_put_failure; 59 goto nla_put_failure;
68 for (i = 0; i < 32; i++) { 60 for (i = 0; i < 32; i++) {
69 if (phy->channels_supported[i]) 61 if (phy->channels_supported[i])
@@ -362,193 +354,3 @@ out_dev:
362 354
363 return rc; 355 return rc;
364} 356}
365
366static int phy_set_txpower(struct wpan_phy *phy, struct genl_info *info)
367{
368 int txpower = nla_get_s8(info->attrs[IEEE802154_ATTR_TXPOWER]);
369 int rc;
370
371 rc = phy->set_txpower(phy, txpower);
372 if (rc < 0)
373 return rc;
374
375 phy->transmit_power = txpower;
376
377 return 0;
378}
379
380static int phy_set_lbt(struct wpan_phy *phy, struct genl_info *info)
381{
382 u8 on = !!nla_get_u8(info->attrs[IEEE802154_ATTR_LBT_ENABLED]);
383 int rc;
384
385 rc = phy->set_lbt(phy, on);
386 if (rc < 0)
387 return rc;
388
389 phy->lbt = on;
390
391 return 0;
392}
393
394static int phy_set_cca_mode(struct wpan_phy *phy, struct genl_info *info)
395{
396 u8 mode = nla_get_u8(info->attrs[IEEE802154_ATTR_CCA_MODE]);
397 int rc;
398
399 if (mode > 3)
400 return -EINVAL;
401
402 rc = phy->set_cca_mode(phy, mode);
403 if (rc < 0)
404 return rc;
405
406 phy->cca_mode = mode;
407
408 return 0;
409}
410
411static int phy_set_cca_ed_level(struct wpan_phy *phy, struct genl_info *info)
412{
413 s32 level = nla_get_s32(info->attrs[IEEE802154_ATTR_CCA_ED_LEVEL]);
414 int rc;
415
416 rc = phy->set_cca_ed_level(phy, level);
417 if (rc < 0)
418 return rc;
419
420 phy->cca_ed_level = level;
421
422 return 0;
423}
424
425static int phy_set_csma_params(struct wpan_phy *phy, struct genl_info *info)
426{
427 int rc;
428 u8 min_be = phy->min_be;
429 u8 max_be = phy->max_be;
430 u8 retries = phy->csma_retries;
431
432 if (info->attrs[IEEE802154_ATTR_CSMA_RETRIES])
433 retries = nla_get_u8(info->attrs[IEEE802154_ATTR_CSMA_RETRIES]);
434 if (info->attrs[IEEE802154_ATTR_CSMA_MIN_BE])
435 min_be = nla_get_u8(info->attrs[IEEE802154_ATTR_CSMA_MIN_BE]);
436 if (info->attrs[IEEE802154_ATTR_CSMA_MAX_BE])
437 max_be = nla_get_u8(info->attrs[IEEE802154_ATTR_CSMA_MAX_BE]);
438
439 if (retries > 5 || max_be < 3 || max_be > 8 || min_be > max_be)
440 return -EINVAL;
441
442 rc = phy->set_csma_params(phy, min_be, max_be, retries);
443 if (rc < 0)
444 return rc;
445
446 phy->min_be = min_be;
447 phy->max_be = max_be;
448 phy->csma_retries = retries;
449
450 return 0;
451}
452
453static int phy_set_frame_retries(struct wpan_phy *phy, struct genl_info *info)
454{
455 s8 retries = nla_get_s8(info->attrs[IEEE802154_ATTR_FRAME_RETRIES]);
456 int rc;
457
458 if (retries < -1 || retries > 7)
459 return -EINVAL;
460
461 rc = phy->set_frame_retries(phy, retries);
462 if (rc < 0)
463 return rc;
464
465 phy->frame_retries = retries;
466
467 return 0;
468}
469
470int ieee802154_set_phyparams(struct sk_buff *skb, struct genl_info *info)
471{
472 struct wpan_phy *phy;
473 const char *name;
474 int rc = -ENOTSUPP;
475
476 pr_debug("%s\n", __func__);
477
478 if (!info->attrs[IEEE802154_ATTR_PHY_NAME] &&
479 !info->attrs[IEEE802154_ATTR_LBT_ENABLED] &&
480 !info->attrs[IEEE802154_ATTR_CCA_MODE] &&
481 !info->attrs[IEEE802154_ATTR_CCA_ED_LEVEL] &&
482 !info->attrs[IEEE802154_ATTR_CSMA_RETRIES] &&
483 !info->attrs[IEEE802154_ATTR_CSMA_MIN_BE] &&
484 !info->attrs[IEEE802154_ATTR_CSMA_MAX_BE] &&
485 !info->attrs[IEEE802154_ATTR_FRAME_RETRIES])
486 return -EINVAL;
487
488 name = nla_data(info->attrs[IEEE802154_ATTR_PHY_NAME]);
489 if (name[nla_len(info->attrs[IEEE802154_ATTR_PHY_NAME]) - 1] != '\0')
490 return -EINVAL; /* phy name should be null-terminated */
491
492 phy = wpan_phy_find(name);
493 if (!phy)
494 return -ENODEV;
495
496 if ((!phy->set_txpower && info->attrs[IEEE802154_ATTR_TXPOWER]) ||
497 (!phy->set_lbt && info->attrs[IEEE802154_ATTR_LBT_ENABLED]) ||
498 (!phy->set_cca_mode && info->attrs[IEEE802154_ATTR_CCA_MODE]) ||
499 (!phy->set_cca_ed_level &&
500 info->attrs[IEEE802154_ATTR_CCA_ED_LEVEL]))
501 goto out;
502
503 mutex_lock(&phy->pib_lock);
504
505 if (info->attrs[IEEE802154_ATTR_TXPOWER]) {
506 rc = phy_set_txpower(phy, info);
507 if (rc < 0)
508 goto error;
509 }
510
511 if (info->attrs[IEEE802154_ATTR_LBT_ENABLED]) {
512 rc = phy_set_lbt(phy, info);
513 if (rc < 0)
514 goto error;
515 }
516
517 if (info->attrs[IEEE802154_ATTR_CCA_MODE]) {
518 rc = phy_set_cca_mode(phy, info);
519 if (rc < 0)
520 goto error;
521 }
522
523 if (info->attrs[IEEE802154_ATTR_CCA_ED_LEVEL]) {
524 rc = phy_set_cca_ed_level(phy, info);
525 if (rc < 0)
526 goto error;
527 }
528
529 if (info->attrs[IEEE802154_ATTR_CSMA_RETRIES] ||
530 info->attrs[IEEE802154_ATTR_CSMA_MIN_BE] ||
531 info->attrs[IEEE802154_ATTR_CSMA_MAX_BE]) {
532 rc = phy_set_csma_params(phy, info);
533 if (rc < 0)
534 goto error;
535 }
536
537 if (info->attrs[IEEE802154_ATTR_FRAME_RETRIES]) {
538 rc = phy_set_frame_retries(phy, info);
539 if (rc < 0)
540 goto error;
541 }
542
543 mutex_unlock(&phy->pib_lock);
544
545 wpan_phy_put(phy);
546
547 return 0;
548
549error:
550 mutex_unlock(&phy->pib_lock);
551out:
552 wpan_phy_put(phy);
553 return rc;
554}
diff --git a/net/ieee802154/wpan-class.c b/net/ieee802154/wpan-class.c
index edd0962d55f9..8d6f6704da84 100644
--- a/net/ieee802154/wpan-class.c
+++ b/net/ieee802154/wpan-class.c
@@ -169,12 +169,6 @@ struct wpan_phy *wpan_phy_alloc(size_t priv_size)
169 phy->current_channel = -1; /* not initialised */ 169 phy->current_channel = -1; /* not initialised */
170 phy->current_page = 0; /* for compatibility */ 170 phy->current_page = 0; /* for compatibility */
171 171
172 /* defaults per 802.15.4-2011 */
173 phy->min_be = 3;
174 phy->max_be = 5;
175 phy->csma_retries = 4;
176 phy->frame_retries = -1; /* for compatibility, actual default is 3 */
177
178 return phy; 172 return phy;
179 173
180out: 174out: