Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

ieee802154: Internal PAN management

Introduce structures to describe peer devices in a PAN as well as a few
related helpers. We basically care about:
- Our unique parent after associating with a coordinator.
- Peer devices, children, which successfully associated with us.

Signed-off-by: Miquel Raynal <miquel.raynal@bootlin.com>
Acked-by: Stefan Schmidt <stefan@datenfreihafen.org>
Acked-by: Alexander Aring <aahringo@redhat.com>
Link: https://lore.kernel.org/linux-wpan/20230927181214.129346-3-miquel.raynal@bootlin.com

+113 -1
+47
include/net/cfg802154.h
··· 304 304 }; 305 305 306 306 /** 307 + * struct ieee802154_pan_device - PAN device information 308 + * @pan_id: the PAN ID of this device 309 + * @mode: the preferred mode to reach the device 310 + * @short_addr: the short address of this device 311 + * @extended_addr: the extended address of this device 312 + * @node: the list node 313 + */ 314 + struct ieee802154_pan_device { 315 + __le16 pan_id; 316 + u8 mode; 317 + __le16 short_addr; 318 + __le64 extended_addr; 319 + struct list_head node; 320 + }; 321 + 322 + /** 307 323 * struct cfg802154_scan_request - Scan request 308 324 * 309 325 * @type: type of scan to be performed ··· 494 478 495 479 /* fallback for acknowledgment bit setting */ 496 480 bool ackreq; 481 + 482 + /* Associations */ 483 + struct mutex association_lock; 484 + struct ieee802154_pan_device *parent; 485 + struct list_head children; 497 486 }; 498 487 499 488 #define to_phy(_dev) container_of(_dev, struct wpan_phy, dev) ··· 549 528 550 529 void ieee802154_configure_durations(struct wpan_phy *phy, 551 530 unsigned int page, unsigned int channel); 531 + 532 + /** 533 + * cfg802154_device_is_associated - Checks whether we are associated to any device 534 + * @wpan_dev: the wpan device 535 + * @return: true if we are associated 536 + */ 537 + bool cfg802154_device_is_associated(struct wpan_dev *wpan_dev); 538 + 539 + /** 540 + * cfg802154_device_is_parent - Checks if a device is our coordinator 541 + * @wpan_dev: the wpan device 542 + * @target: the expected parent 543 + * @return: true if @target is our coordinator 544 + */ 545 + bool cfg802154_device_is_parent(struct wpan_dev *wpan_dev, 546 + struct ieee802154_addr *target); 547 + 548 + /** 549 + * cfg802154_device_is_child - Checks whether a device is associated to us 550 + * @wpan_dev: the wpan device 551 + * @target: the expected child 552 + * @return: the PAN device 553 + */ 554 + struct ieee802154_pan_device * 555 + cfg802154_device_is_child(struct wpan_dev *wpan_dev, 556 + struct ieee802154_addr *target); 552 557 553 558 #endif /* __NET_CFG802154_H */
+1 -1
net/ieee802154/Makefile
··· 4 4 obj-y += 6lowpan/ 5 5 6 6 ieee802154-y := netlink.o nl-mac.o nl-phy.o nl_policy.o core.o \ 7 - header_ops.o sysfs.o nl802154.o trace.o 7 + header_ops.o sysfs.o nl802154.o trace.o pan.o 8 8 ieee802154_socket-y := socket.o 9 9 10 10 CFLAGS_trace.o := -I$(src)
+2
net/ieee802154/core.c
··· 276 276 wpan_dev->identifier = ++rdev->wpan_dev_id; 277 277 list_add_rcu(&wpan_dev->list, &rdev->wpan_dev_list); 278 278 rdev->devlist_generation++; 279 + mutex_init(&wpan_dev->association_lock); 280 + INIT_LIST_HEAD(&wpan_dev->children); 279 281 280 282 wpan_dev->netdev = dev; 281 283 break;
+63
net/ieee802154/pan.c
··· 1 + // SPDX-License-Identifier: GPL-2.0 2 + /* 3 + * IEEE 802.15.4 PAN management 4 + * 5 + * Copyright (C) 2023 Qorvo US, Inc 6 + * Authors: 7 + * - David Girault <david.girault@qorvo.com> 8 + * - Miquel Raynal <miquel.raynal@bootlin.com> 9 + */ 10 + 11 + #include <linux/kernel.h> 12 + #include <net/cfg802154.h> 13 + #include <net/af_ieee802154.h> 14 + 15 + /* Checks whether a device address matches one from the PAN list. 16 + * This helper is meant to be used only during PAN management, when we expect 17 + * extended addresses to be used. 18 + */ 19 + static bool cfg802154_pan_device_is_matching(struct ieee802154_pan_device *pan_dev, 20 + struct ieee802154_addr *ext_dev) 21 + { 22 + if (!pan_dev || !ext_dev) 23 + return false; 24 + 25 + if (ext_dev->mode == IEEE802154_ADDR_SHORT) 26 + return false; 27 + 28 + return pan_dev->extended_addr == ext_dev->extended_addr; 29 + } 30 + 31 + bool cfg802154_device_is_associated(struct wpan_dev *wpan_dev) 32 + { 33 + bool is_assoc; 34 + 35 + mutex_lock(&wpan_dev->association_lock); 36 + is_assoc = !list_empty(&wpan_dev->children) || wpan_dev->parent; 37 + mutex_unlock(&wpan_dev->association_lock); 38 + 39 + return is_assoc; 40 + } 41 + 42 + bool cfg802154_device_is_parent(struct wpan_dev *wpan_dev, 43 + struct ieee802154_addr *target) 44 + { 45 + lockdep_assert_held(&wpan_dev->association_lock); 46 + 47 + return cfg802154_pan_device_is_matching(wpan_dev->parent, target); 48 + } 49 + 50 + struct ieee802154_pan_device * 51 + cfg802154_device_is_child(struct wpan_dev *wpan_dev, 52 + struct ieee802154_addr *target) 53 + { 54 + struct ieee802154_pan_device *child; 55 + 56 + lockdep_assert_held(&wpan_dev->association_lock); 57 + 58 + list_for_each_entry(child, &wpan_dev->children, node) 59 + if (cfg802154_pan_device_is_matching(child, target)) 60 + return child; 61 + 62 + return NULL; 63 + }