Skip to contentSkip to conversation

ieee802154: iface handling and new nl802154 commands

PATCH In review Alexander Aring 2 participants 20 messages Nov 12, 2014

Subsystems (3)
lore
Share & tools
lore

Alexander Aring

author maintainer
#0 lore raw

cover ieee802154: iface handling and new nl802154 commands

This patch series contains iface handling cleanup patches and mostly trivial patches to support several netlink commands. Also removing the constraints checks for 802.15.4 parameters from driver layer. This should be handled by nl802154 layer now. The old netlink interface should be deprecated now and these constraints checks are not supported anymore by the old netlink interface. Some of the current driver never checked on these constraints so we don't fix the old netlink interface anymore to check on "global" 802.15.4 constraints.

All users should use the wpan-tools from [0] now. Some cmd's are not supported already like interface deletion or adding, but will be supported in near future.

[0] https://github.com/linux-wpan/wpan-tools/archive/wpan-tools-0.1.tar.gz

Alexander Aring (18):
mac820154: move interface unregistration into iface
mac820154: rename sdata next to tmp
mac820154: move mutex locks out of loop
mac802154: add wpan_phy priv id
mac802154: change module description
mac802154: add ifname change notifier
ieee802154: cleanup cfg802154 intendation
ieee820154: add channel set support
ieee820154: remove valid page and channel checks
ieee820154: add pan_id setting support
ieee820154: add short_addr setting support
ieee820154: add backoff exponent setting support
at86rf230: remove invalid backoff exponent check
ieee820154: add max csma backoffs setting support
at86rf230: remove invalid max csma backoffs check
ieee820154: add max frame retries setting support
at86rf230: remove invalid max frame retries check
ieee820154: add lbt setting support

 drivers/net/ieee802154/at86rf230.c |  20 +---
 drivers/net/ieee802154/fakelb.c    |   3 -
 include/linux/ieee802154.h         |   4 +
 include/net/cfg802154.h            |  28 ++++-
 net/ieee802154/nl802154.c          | 214 +++++++++++++++++++++++++++++++++++++
 net/ieee802154/rdev-ops.h          |  55 ++++++++++
 net/mac802154/cfg.c                | 136 +++++++++++++++++++++++
 net/mac802154/ieee802154_i.h       |   7 ++
 net/mac802154/iface.c              |  48 +++++++++
 net/mac802154/main.c               |  28 +++--
 net/mac802154/util.c               |   3 +
 11 files changed, 513 insertions(+), 33 deletions(-)
Signature · 1 line
2.1.3
author maintainer
#1 lore raw

PATCH 1/18 mac820154: move interface unregistration into iface

This patch move the iface unregistration into iface.c file to have a behaviour which is similar like mac80211. Also iface handling should be inside iface.c file only.

---
 net/mac802154/ieee802154_i.h |  1 +
 net/mac802154/iface.c        | 13 +++++++++++++
 net/mac802154/main.c         |  9 +--------
 3 files changed, 15 insertions(+), 8 deletions(-)
net/mac802154/ieee802154_i.h +1 -0
index e22f509..abb1970 100644
@@ -172,5 +172,6 @@ void ieee802154_if_remove(struct ieee802154_sub_if_data *sdata);
 struct net_device *
 ieee802154_if_add(struct ieee802154_local *local, const char *name,
 		  struct wpan_dev **new_wpan_dev, int type);
+void ieee802154_remove_interfaces(struct ieee802154_local *local);
 
 #endif /* __IEEE802154_I_H */
net/mac802154/iface.c +13 -0
index 83715b5..8d90fba 100644
@@ -535,3 +535,16 @@ void ieee802154_if_remove(struct ieee802154_sub_if_data *sdata)
 	synchronize_rcu();
 	unregister_netdevice(sdata->dev);
 }
+
+void ieee802154_remove_interfaces(struct ieee802154_local *local)
+{
+	struct ieee802154_sub_if_data *sdata, *next;
+
+	list_for_each_entry_safe(sdata, next, &local->interfaces, list) {
+		mutex_lock(&sdata->local->iflist_mtx);
+		list_del(&sdata->list);
+		mutex_unlock(&sdata->local->iflist_mtx);
+
+		unregister_netdevice(sdata->dev);
+	}
+}
net/mac802154/main.c +1 -8
index 234084d..709dcc5 100644
@@ -165,7 +165,6 @@ EXPORT_SYMBOL(ieee802154_register_hw);
 void ieee802154_unregister_hw(struct ieee802154_hw *hw)
 {
 	struct ieee802154_local *local = hw_to_local(hw);
-	struct ieee802154_sub_if_data *sdata, *next;
 
 	tasklet_kill(&local->tasklet);
 	flush_workqueue(local->workqueue);
@@ -173,13 +172,7 @@ void ieee802154_unregister_hw(struct ieee802154_hw *hw)
 
 	rtnl_lock();
 
-	list_for_each_entry_safe(sdata, next, &local->interfaces, list) {
-		mutex_lock(&sdata->local->iflist_mtx);
-		list_del(&sdata->list);
-		mutex_unlock(&sdata->local->iflist_mtx);
-
-		unregister_netdevice(sdata->dev);
-	}
+	ieee802154_remove_interfaces(local);
 
 	rtnl_unlock();
 
Signature · 1 line
2.1.3
author maintainer
#2 lore raw

PATCH 2/18 mac820154: rename sdata next to tmp

In reply to Alexander Aring

This patch is just a cleanup to name the temporary variable for protected list for each loop as tmp.

---
 net/mac802154/iface.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)
net/mac802154/iface.c +2 -2
index 8d90fba..8b21d20 100644
@@ -538,9 +538,9 @@ void ieee802154_if_remove(struct ieee802154_sub_if_data *sdata)
 
 void ieee802154_remove_interfaces(struct ieee802154_local *local)
 {
-	struct ieee802154_sub_if_data *sdata, *next;
+	struct ieee802154_sub_if_data *sdata, *tmp;
 
-	list_for_each_entry_safe(sdata, next, &local->interfaces, list) {
+	list_for_each_entry_safe(sdata, tmp, &local->interfaces, list) {
 		mutex_lock(&sdata->local->iflist_mtx);
 		list_del(&sdata->list);
 		mutex_unlock(&sdata->local->iflist_mtx);
Signature · 1 line
2.1.3
author maintainer
#3 lore raw

PATCH 3/18 mac820154: move mutex locks out of loop

In reply to Alexander Aring

Instead of always re-lock the iflist_mtx at multiple interfaces we lock the complete for each loop at start and at the end.

---
 net/mac802154/iface.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)
net/mac802154/iface.c +2 -2
index 8b21d20..85d2155 100644
@@ -540,11 +540,11 @@ void ieee802154_remove_interfaces(struct ieee802154_local *local)
 {
 	struct ieee802154_sub_if_data *sdata, *tmp;
 
+	mutex_lock(&local->iflist_mtx);
 	list_for_each_entry_safe(sdata, tmp, &local->interfaces, list) {
-		mutex_lock(&sdata->local->iflist_mtx);
 		list_del(&sdata->list);
-		mutex_unlock(&sdata->local->iflist_mtx);
 
 		unregister_netdevice(sdata->dev);
 	}
+	mutex_unlock(&local->iflist_mtx);
 }
Signature · 1 line
2.1.3
author maintainer
#4 lore raw

PATCH 4/18 mac802154: add wpan_phy priv id

In reply to Alexander Aring

This patch adds an unique id for an wpan_phy. This behaviour is mostly grabbed from wireless stack. This is needed for upcomming patches which identify the wpan netdev while NETDEV_CHANGENAME in netdev notify function.

---
 include/net/cfg802154.h      | 8 ++++++++
 net/mac802154/ieee802154_i.h | 3 +++
 net/mac802154/main.c         | 2 ++
 net/mac802154/util.c         | 3 +++
 4 files changed, 16 insertions(+)
include/net/cfg802154.h +8 -0
index e5570e0..3695152 100644
@@ -42,6 +42,14 @@ struct cfg802154_ops {
 struct wpan_phy {
 	struct mutex pib_lock;
 
+	/* If multiple wpan_phys are registered and you're handed e.g.
+	 * a regular netdev with assigned ieee802154_ptr, you won't
+	 * know whether it points to a wpan_phy your driver has registered
+	 * or not. Assign this to something global to your driver to
+	 * help determine whether you own this wpan_phy or not.
+	 */
+	const void *privid;
+
 	/*
 	 * This is a PIB according to 802.15.4-2011.
 	 * We do not provide timing-related variables, as they
net/mac802154/ieee802154_i.h +3 -0
index abb1970..4be5e23 100644
@@ -96,6 +96,9 @@ struct ieee802154_sub_if_data {
 
 #define MAC802154_CHAN_NONE		0xff /* No channel is assigned */
 
+/* utility functions/constants */
+extern const void *const mac802154_wpan_phy_privid; /*  for wpan_phy privid */
+
 static inline struct ieee802154_local *
 hw_to_local(struct ieee802154_hw *hw)
 {
net/mac802154/main.c +2 -0
index 709dcc5..24e8ca6 100644
@@ -92,6 +92,8 @@ ieee802154_alloc_hw(size_t priv_data_len, const struct ieee802154_ops *ops)
 		return NULL;
 	}
 
+	phy->privid = mac802154_wpan_phy_privid;
+
 	local = wpan_phy_priv(phy);
 	local->phy = phy;
 	local->hw.phy = local->phy;
net/mac802154/util.c +3 -0
index 117e4ef..9a04e4a 100644
@@ -15,6 +15,9 @@
 
 #include "ieee802154_i.h"
 
+/* privid for wpan_phys to determine whether they belong to us or not */
+const void *const mac802154_wpan_phy_privid = &mac802154_wpan_phy_privid;
+
 void ieee802154_wake_queue(struct ieee802154_hw *hw)
 {
 	struct ieee802154_local *local = hw_to_local(hw);
Signature · 1 line
2.1.3
author maintainer
#5 lore raw

PATCH 5/18 mac802154: change module description

In reply to Alexander Aring

This patch changes the module description like wireless which is IEEE 802.11 "subsystem" and not "implementation".

---
 net/mac802154/main.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
net/mac802154/main.c +1 -1
index 24e8ca6..40a3264 100644
@@ -182,5 +182,5 @@ void ieee802154_unregister_hw(struct ieee802154_hw *hw)
 }
 EXPORT_SYMBOL(ieee802154_unregister_hw);
 
-MODULE_DESCRIPTION("IEEE 802.15.4 implementation");
+MODULE_DESCRIPTION("IEEE 802.15.4 subsystem");
 MODULE_LICENSE("GPL v2");
Signature · 1 line
2.1.3
author maintainer
#6 lore raw

PATCH 6/18 mac802154: add ifname change notifier

In reply to Alexander Aring

This patch adds a netdev notifier for interface renaming. We have a name attribute inside of subif data struct. This is needed to have always the actual netdev name in sdata name attribute.

---
 net/mac802154/ieee802154_i.h |  3 +++
 net/mac802154/iface.c        | 35 +++++++++++++++++++++++++++++++++++
 net/mac802154/main.c         | 15 +++++++++++++++
 3 files changed, 53 insertions(+)
net/mac802154/ieee802154_i.h +3 -0
index 4be5e23..69cb585 100644
@@ -169,6 +169,9 @@ void mac802154_get_table(struct net_device *dev,
 			 struct ieee802154_llsec_table **t);
 void mac802154_unlock_table(struct net_device *dev);
 
+/* interface handling */
+int ieee802154_iface_init(void);
+void ieee802154_iface_exit(void);
 struct net_device *
 mac802154_add_iface(struct wpan_phy *phy, const char *name, int type);
 void ieee802154_if_remove(struct ieee802154_sub_if_data *sdata);
net/mac802154/iface.c +35 -0
index 85d2155..ec92b48 100644
@@ -548,3 +548,38 @@ void ieee802154_remove_interfaces(struct ieee802154_local *local)
 	}
 	mutex_unlock(&local->iflist_mtx);
 }
+
+static int netdev_notify(struct notifier_block *nb,
+			 unsigned long state, void *ptr)
+{
+	struct net_device *dev = netdev_notifier_info_to_dev(ptr);
+	struct ieee802154_sub_if_data *sdata;
+
+	if (state != NETDEV_CHANGENAME)
+		return NOTIFY_DONE;
+
+	if (!dev->ieee802154_ptr || !dev->ieee802154_ptr->wpan_phy)
+		return NOTIFY_DONE;
+
+	if (dev->ieee802154_ptr->wpan_phy->privid != mac802154_wpan_phy_privid)
+		return NOTIFY_DONE;
+
+	sdata = IEEE802154_DEV_TO_SUB_IF(dev);
+	memcpy(sdata->name, dev->name, IFNAMSIZ);
+
+	return NOTIFY_OK;
+}
+
+static struct notifier_block mac802154_netdev_notifier = {
+	.notifier_call = netdev_notify,
+};
+
+int ieee802154_iface_init(void)
+{
+	return register_netdevice_notifier(&mac802154_netdev_notifier);
+}
+
+void ieee802154_iface_exit(void)
+{
+	unregister_netdevice_notifier(&mac802154_netdev_notifier);
+}
net/mac802154/main.c +15 -0
index 40a3264..46c76e0 100644
@@ -182,5 +182,20 @@ void ieee802154_unregister_hw(struct ieee802154_hw *hw)
 }
 EXPORT_SYMBOL(ieee802154_unregister_hw);
 
+static int __init ieee802154_init(void)
+{
+	return ieee802154_iface_init();
+}
+
+static void __exit ieee802154_exit(void)
+{
+	ieee802154_iface_exit();
+
+	rcu_barrier();
+}
+
+subsys_initcall(ieee802154_init);
+module_exit(ieee802154_exit);
+
 MODULE_DESCRIPTION("IEEE 802.15.4 subsystem");
 MODULE_LICENSE("GPL v2");
Signature · 1 line
2.1.3
author maintainer
#7 lore raw

PATCH 7/18 ieee802154: cleanup cfg802154 intendation

In reply to Alexander Aring

This is patch is cleanup to have a similar indentation like cfg80211 implementation.

---
 include/net/cfg802154.h | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)
include/net/cfg802154.h +2 -2
index 3695152..8a3edc5 100644
@@ -35,8 +35,8 @@ struct cfg802154_ops {
 	struct net_device * (*add_virtual_intf_deprecated)(struct wpan_phy *wpan_phy,
 							   const char *name,
 							   int type);
-	void (*del_virtual_intf_deprecated)(struct wpan_phy *wpan_phy,
-					    struct net_device *dev);
+	void	(*del_virtual_intf_deprecated)(struct wpan_phy *wpan_phy,
+					       struct net_device *dev);
 };
 
 struct wpan_phy {
Signature · 1 line
2.1.3
author maintainer
#8 lore raw

PATCH 8/18 ieee820154: add channel set support

In reply to Alexander Aring

This patch adds page and channel setting support to nl802154 framework.

---
 include/net/cfg802154.h   |  1 +
 net/ieee802154/nl802154.c | 28 ++++++++++++++++++++++++++++
 net/ieee802154/rdev-ops.h |  7 +++++++
 net/mac802154/cfg.c       | 24 ++++++++++++++++++++++++
 4 files changed, 60 insertions(+)
include/net/cfg802154.h +1 -0
index 8a3edc5..391fdb3 100644
@@ -37,6 +37,7 @@ struct cfg802154_ops {
 							   int type);
 	void	(*del_virtual_intf_deprecated)(struct wpan_phy *wpan_phy,
 					       struct net_device *dev);
+	int	(*set_channel)(struct wpan_phy *wpan_phy, u8 page, u8 channel);
 };
 
 struct wpan_phy {
net/ieee802154/nl802154.c +28 -0
index 46df7dc..d8ef2c8 100644
@@ -23,6 +23,7 @@
 #include <net/sock.h>
 
 #include "nl802154.h"
+#include "rdev-ops.h"
 #include "core.h"
 
 static int nl802154_pre_doit(const struct genl_ops *ops, struct sk_buff *skb,
@@ -550,6 +551,25 @@ static int nl802154_get_interface(struct sk_buff *skb, struct genl_info *info)
 	return genlmsg_reply(msg, info);
 }
 
+static int nl802154_set_channel(struct sk_buff *skb, struct genl_info *info)
+{
+	struct cfg802154_registered_device *rdev = info->user_ptr[0];
+	u8 channel, page;
+
+	if (!info->attrs[NL802154_ATTR_PAGE] ||
+	    !info->attrs[NL802154_ATTR_CHANNEL])
+		return -EINVAL;
+
+	page = nla_get_u8(info->attrs[NL802154_ATTR_PAGE]);
+	channel = nla_get_u8(info->attrs[NL802154_ATTR_CHANNEL]);
+
+	/* check 802.15.4 constraints */
+	if (page >= WPAN_NUM_PAGES || channel >= WPAN_NUM_CHANNELS)
+		return -EINVAL;
+
+	return rdev_set_channel(rdev, page, channel);
+}
+
 #define NL802154_FLAG_NEED_WPAN_PHY	0x01
 #define NL802154_FLAG_NEED_NETDEV	0x02
 #define NL802154_FLAG_NEED_RTNL		0x04
@@ -660,6 +680,14 @@ static const struct genl_ops nl802154_ops[] = {
 		.internal_flags = NL802154_FLAG_NEED_WPAN_DEV |
 				  NL802154_FLAG_NEED_RTNL,
 	},
+	{
+		.cmd = NL802154_CMD_SET_CHANNEL,
+		.doit = nl802154_set_channel,
+		.policy = nl802154_policy,
+		.flags = GENL_ADMIN_PERM,
+		.internal_flags = NL802154_FLAG_NEED_WPAN_PHY |
+				  NL802154_FLAG_NEED_RTNL,
+	},
 };
 
 /* initialisation/exit functions */
net/ieee802154/rdev-ops.h +7 -0
index ac8824e..8a3b0eb 100644
@@ -20,4 +20,11 @@ rdev_del_virtual_intf_deprecated(struct cfg802154_registered_device *rdev,
 	rdev->ops->del_virtual_intf_deprecated(&rdev->wpan_phy, dev);
 }
 
+static inline int
+rdev_set_channel(struct cfg802154_registered_device *rdev, const u8 page,
+		 const u8 channel)
+{
+	return rdev->ops->set_channel(&rdev->wpan_phy, page, channel);
+}
+
 #endif /* __CFG802154_RDEV_OPS */
net/mac802154/cfg.c +24 -0
index d2c4e8f..9d5b189 100644
@@ -17,6 +17,7 @@
 #include <net/cfg802154.h>
 
 #include "ieee802154_i.h"
+#include "driver-ops.h"
 #include "cfg.h"
 
 static struct net_device *
@@ -41,7 +42,30 @@ static void ieee802154_del_iface_deprecated(struct wpan_phy *wpan_phy,
 	ieee802154_if_remove(sdata);
 }
 
+static int
+ieee802154_set_channel(struct wpan_phy *wpan_phy, const u8 page,
+		       const u8 channel)
+{
+	struct ieee802154_local *local = wpan_phy_priv(wpan_phy);
+	int ret;
+
+	ASSERT_RTNL();
+
+	/* check if phy support this setting */
+	if (!(wpan_phy->channels_supported[page] & BIT(channel)))
+		return -EINVAL;
+
+	ret = drv_set_channel(local, page, channel);
+	if (!ret) {
+		wpan_phy->current_page = page;
+		wpan_phy->current_channel = channel;
+	}
+
+	return ret;
+}
+
 const struct cfg802154_ops mac802154_config_ops = {
 	.add_virtual_intf_deprecated = ieee802154_add_iface_deprecated,
 	.del_virtual_intf_deprecated = ieee802154_del_iface_deprecated,
+	.set_channel = ieee802154_set_channel,
 };
Signature · 1 line
2.1.3
author maintainer
#9 lore raw

PATCH 9/18 ieee820154: remove valid page and channel checks

In reply to Alexander Aring

This patch removes validation of page and channel while setting from driver layer. This is already handled by nl802154 and mac802154.

---
 drivers/net/ieee802154/at86rf230.c | 14 +-------------
 drivers/net/ieee802154/fakelb.c    |  3 ---
 2 files changed, 1 insertion(+), 16 deletions(-)
drivers/net/ieee802154/at86rf230.c +1 -13
index ebcbeb3..f9e3bce 100644
@@ -1047,23 +1047,11 @@ at86rf230_channel(struct ieee802154_hw *hw, u8 page, u8 channel)
 	struct at86rf230_local *lp = hw->priv;
 	int rc;
 
-	if (page > 31 ||
-	    !(lp->hw->phy->channels_supported[page] & BIT(channel))) {
-		WARN_ON(1);
-		return -EINVAL;
-	}
-
 	rc = lp->data->set_channel(lp, page, channel);
-	if (rc < 0)
-		return rc;
-
 	/* Wait for PLL */
 	usleep_range(lp->data->t_channel_switch,
 		     lp->data->t_channel_switch + 10);
-	hw->phy->current_channel = channel;
-	hw->phy->current_page = page;
-
-	return 0;
+	return rc;
 }
 
 static int
drivers/net/ieee802154/fakelb.c +0 -3
index 6e62286..96947d7 100644
@@ -58,9 +58,6 @@ fakelb_hw_channel(struct ieee802154_hw *hw, u8 page, u8 channel)
 {
 	pr_debug("set channel to %d\n", channel);
 
-	hw->phy->current_page = page;
-	hw->phy->current_channel = channel;
-
 	return 0;
 }
 
Signature · 1 line
2.1.3
author maintainer
#10 lore raw

PATCH 10/18 ieee820154: add pan_id setting support

In reply to Alexander Aring

This patch adds support for setting pan_id via nl802154 framework. Adding a comment because setting 0xffff as pan_id seems to be valid setting. The pan_id 0xffff as source pan is invalid. I am not sure now about this setting but for the current netlink interface this is an invalid setting, so we do the same now. Maybe we need to change that when we have coordinator support and association support.

---
 include/linux/ieee802154.h |  2 ++
 include/net/cfg802154.h    |  2 ++
 net/ieee802154/nl802154.c  | 31 +++++++++++++++++++++++++++++++
 net/ieee802154/rdev-ops.h  |  7 +++++++
 net/mac802154/cfg.c        | 20 ++++++++++++++++++++
 5 files changed, 62 insertions(+)
include/linux/ieee802154.h +2 -0
index d043449..d4037987 100644
@@ -30,6 +30,8 @@
 #define IEEE802154_MTU			127
 #define IEEE802154_MIN_PSDU_LEN		5
 
+#define IEEE802154_PAN_ID_BROADCAST	0xffff
+
 #define IEEE802154_EXTENDED_ADDR_LEN	8
 
 #define IEEE802154_FC_TYPE_BEACON	0x0	/* Frame is beacon */
include/net/cfg802154.h +2 -0
index 391fdb3..d07b072 100644
@@ -38,6 +38,8 @@ struct cfg802154_ops {
 	void	(*del_virtual_intf_deprecated)(struct wpan_phy *wpan_phy,
 					       struct net_device *dev);
 	int	(*set_channel)(struct wpan_phy *wpan_phy, u8 page, u8 channel);
+	int	(*set_pan_id)(struct wpan_phy *wpan_phy,
+			      struct wpan_dev *wpan_dev, u16 pan_id);
 };
 
 struct wpan_phy {
net/ieee802154/nl802154.c +31 -0
index d8ef2c8..88cd1293 100644
@@ -570,6 +570,29 @@ static int nl802154_set_channel(struct sk_buff *skb, struct genl_info *info)
 	return rdev_set_channel(rdev, page, channel);
 }
 
+static int nl802154_set_pan_id(struct sk_buff *skb, struct genl_info *info)
+{
+	struct cfg802154_registered_device *rdev = info->user_ptr[0];
+	struct net_device *dev = info->user_ptr[1];
+	struct wpan_dev *wpan_dev = dev->ieee802154_ptr;
+	u16 pan_id;
+
+	/* conflict here while tx/rx calls */
+	if (netif_running(dev))
+		return -EBUSY;
+
+	/* don't change address fields on monitor */
+	if (wpan_dev->iftype == NL802154_IFTYPE_MONITOR)
+		return -EINVAL;
+
+	if (!info->attrs[NL802154_ATTR_PAN_ID])
+		return -EINVAL;
+
+	pan_id = nla_get_u16(info->attrs[NL802154_ATTR_PAN_ID]);
+
+	return rdev_set_pan_id(rdev, wpan_dev, pan_id);
+}
+
 #define NL802154_FLAG_NEED_WPAN_PHY	0x01
 #define NL802154_FLAG_NEED_NETDEV	0x02
 #define NL802154_FLAG_NEED_RTNL		0x04
@@ -688,6 +711,14 @@ static const struct genl_ops nl802154_ops[] = {
 		.internal_flags = NL802154_FLAG_NEED_WPAN_PHY |
 				  NL802154_FLAG_NEED_RTNL,
 	},
+	{
+		.cmd = NL802154_CMD_SET_PAN_ID,
+		.doit = nl802154_set_pan_id,
+		.policy = nl802154_policy,
+		.flags = GENL_ADMIN_PERM,
+		.internal_flags = NL802154_FLAG_NEED_NETDEV |
+				  NL802154_FLAG_NEED_RTNL,
+	},
 };
 
 /* initialisation/exit functions */
net/ieee802154/rdev-ops.h +7 -0
index 8a3b0eb..4115ea2 100644
@@ -27,4 +27,11 @@ rdev_set_channel(struct cfg802154_registered_device *rdev, const u8 page,
 	return rdev->ops->set_channel(&rdev->wpan_phy, page, channel);
 }
 
+static inline int
+rdev_set_pan_id(struct cfg802154_registered_device *rdev,
+		struct wpan_dev *wpan_dev, u16 pan_id)
+{
+	return rdev->ops->set_pan_id(&rdev->wpan_phy, wpan_dev, pan_id);
+}
+
 #endif /* __CFG802154_RDEV_OPS */
net/mac802154/cfg.c +20 -0
index 9d5b189..db6e5e9 100644
@@ -64,8 +64,28 @@ ieee802154_set_channel(struct wpan_phy *wpan_phy, const u8 page,
 	return ret;
 }
 
+static int ieee802154_set_pan_id(struct wpan_phy *wpan_phy,
+				 struct wpan_dev *wpan_dev, const u16 pan_id)
+{
+	ASSERT_RTNL();
+
+	/* TODO
+	 * I am not sure about to check here on broadcast pan_id.
+	 * Broadcast is a valid setting, comment from 802.15.4:
+	 * If this value is 0xffff, the device is not associated.
+	 *
+	 * This could useful to simple deassociate an device.
+	 */
+	if (pan_id == IEEE802154_PAN_ID_BROADCAST)
+		return -EINVAL;
+
+	wpan_dev->pan_id = cpu_to_le16(pan_id);
+	return 0;
+}
+
 const struct cfg802154_ops mac802154_config_ops = {
 	.add_virtual_intf_deprecated = ieee802154_add_iface_deprecated,
 	.del_virtual_intf_deprecated = ieee802154_del_iface_deprecated,
 	.set_channel = ieee802154_set_channel,
+	.set_pan_id = ieee802154_set_pan_id,
 };
Signature · 1 line
2.1.3
author maintainer
#11 lore raw

PATCH 11/18 ieee820154: add short_addr setting support

In reply to Alexander Aring

This patch adds support for setting short address via nl802154 framework. Also added a comment because a 0xffff seems to be valid address that we don't have a short address. This is a valid setting but we need more checks in upper layers to don't allow this address as source address. Also the current netlink interface doesn't allow to set the short_addr to 0xffff. Same for the 0xfffe short address which describes a not allocated short address.

---
 include/linux/ieee802154.h |  2 ++
 include/net/cfg802154.h    |  2 ++
 net/ieee802154/nl802154.c  | 31 +++++++++++++++++++++++++++++++
 net/ieee802154/rdev-ops.h  |  7 +++++++
 net/mac802154/cfg.c        | 26 ++++++++++++++++++++++++++
 5 files changed, 68 insertions(+)
include/linux/ieee802154.h +2 -0
index d4037987..ce0f96a 100644
@@ -31,6 +31,8 @@
 #define IEEE802154_MIN_PSDU_LEN		5
 
 #define IEEE802154_PAN_ID_BROADCAST	0xffff
+#define IEEE802154_ADDR_SHORT_BROADCAST	0xffff
+#define IEEE802154_ADDR_SHORT_UNSPEC	0xfffe
 
 #define IEEE802154_EXTENDED_ADDR_LEN	8
 
include/net/cfg802154.h +2 -0
index d07b072..e8a4c2b 100644
@@ -40,6 +40,8 @@ struct cfg802154_ops {
 	int	(*set_channel)(struct wpan_phy *wpan_phy, u8 page, u8 channel);
 	int	(*set_pan_id)(struct wpan_phy *wpan_phy,
 			      struct wpan_dev *wpan_dev, u16 pan_id);
+	int	(*set_short_addr)(struct wpan_phy *wpan_phy,
+				  struct wpan_dev *wpan_dev, u16 short_addr);
 };
 
 struct wpan_phy {
net/ieee802154/nl802154.c +31 -0
index 88cd1293..2978c1a 100644
@@ -593,6 +593,29 @@ static int nl802154_set_pan_id(struct sk_buff *skb, struct genl_info *info)
 	return rdev_set_pan_id(rdev, wpan_dev, pan_id);
 }
 
+static int nl802154_set_short_addr(struct sk_buff *skb, struct genl_info *info)
+{
+	struct cfg802154_registered_device *rdev = info->user_ptr[0];
+	struct net_device *dev = info->user_ptr[1];
+	struct wpan_dev *wpan_dev = dev->ieee802154_ptr;
+	u16 short_addr;
+
+	/* conflict here while tx/rx calls */
+	if (netif_running(dev))
+		return -EBUSY;
+
+	/* don't change address fields on monitor */
+	if (wpan_dev->iftype == NL802154_IFTYPE_MONITOR)
+		return -EINVAL;
+
+	if (!info->attrs[NL802154_ATTR_SHORT_ADDR])
+		return -EINVAL;
+
+	short_addr = nla_get_u16(info->attrs[NL802154_ATTR_SHORT_ADDR]);
+
+	return rdev_set_short_addr(rdev, wpan_dev, short_addr);
+}
+
 #define NL802154_FLAG_NEED_WPAN_PHY	0x01
 #define NL802154_FLAG_NEED_NETDEV	0x02
 #define NL802154_FLAG_NEED_RTNL		0x04
@@ -719,6 +742,14 @@ static const struct genl_ops nl802154_ops[] = {
 		.internal_flags = NL802154_FLAG_NEED_NETDEV |
 				  NL802154_FLAG_NEED_RTNL,
 	},
+	{
+		.cmd = NL802154_CMD_SET_SHORT_ADDR,
+		.doit = nl802154_set_short_addr,
+		.policy = nl802154_policy,
+		.flags = GENL_ADMIN_PERM,
+		.internal_flags = NL802154_FLAG_NEED_NETDEV |
+				  NL802154_FLAG_NEED_RTNL,
+	},
 };
 
 /* initialisation/exit functions */
net/ieee802154/rdev-ops.h +7 -0
index 4115ea2..16b0de0 100644
@@ -34,4 +34,11 @@ rdev_set_pan_id(struct cfg802154_registered_device *rdev,
 	return rdev->ops->set_pan_id(&rdev->wpan_phy, wpan_dev, pan_id);
 }
 
+static inline int
+rdev_set_short_addr(struct cfg802154_registered_device *rdev,
+		    struct wpan_dev *wpan_dev, u16 short_addr)
+{
+	return rdev->ops->set_short_addr(&rdev->wpan_phy, wpan_dev, short_addr);
+}
+
 #endif /* __CFG802154_RDEV_OPS */
net/mac802154/cfg.c +26 -0
index db6e5e9..df29976 100644
@@ -83,9 +83,35 @@ static int ieee802154_set_pan_id(struct wpan_phy *wpan_phy,
 	return 0;
 }
 
+static int
+ieee802154_set_short_addr(struct wpan_phy *wpan_phy, struct wpan_dev *wpan_dev,
+			  const u16 short_addr)
+{
+	ASSERT_RTNL();
+
+	/* TODO
+	 * I am not sure about to check here on broadcast short_addr.
+	 * Broadcast is a valid setting, comment from 802.15.4:
+	 * A value of 0xfffe indicates that the device has
+	 * associated but has not been allocated an address. A
+	 * value of 0xffff indicates that the device does not
+	 * have a short address.
+	 *
+	 * I think we should allow to set these settings but
+	 * don't allow to allow socket communication with it.
+	 */
+	if (short_addr == IEEE802154_ADDR_SHORT_UNSPEC ||
+	    short_addr == IEEE802154_ADDR_SHORT_BROADCAST)
+		return -EINVAL;
+
+	wpan_dev->short_addr = cpu_to_le16(short_addr);
+	return 0;
+}
+
 const struct cfg802154_ops mac802154_config_ops = {
 	.add_virtual_intf_deprecated = ieee802154_add_iface_deprecated,
 	.del_virtual_intf_deprecated = ieee802154_del_iface_deprecated,
 	.set_channel = ieee802154_set_channel,
 	.set_pan_id = ieee802154_set_pan_id,
+	.set_short_addr = ieee802154_set_short_addr,
 };
Signature · 1 line
2.1.3
author maintainer
#12 lore raw

PATCH 12/18 ieee820154: add backoff exponent setting support

In reply to Alexander Aring

This patch adds support for setting backoff exponents via nl802154 framework.

---
 include/net/cfg802154.h   |  3 +++
 net/ieee802154/nl802154.c | 34 ++++++++++++++++++++++++++++++++++
 net/ieee802154/rdev-ops.h |  9 +++++++++
 net/mac802154/cfg.c       | 18 ++++++++++++++++++
 4 files changed, 64 insertions(+)
include/net/cfg802154.h +3 -0
index e8a4c2b..27e98d1 100644
@@ -42,6 +42,9 @@ struct cfg802154_ops {
 			      struct wpan_dev *wpan_dev, u16 pan_id);
 	int	(*set_short_addr)(struct wpan_phy *wpan_phy,
 				  struct wpan_dev *wpan_dev, u16 short_addr);
+	int	(*set_backoff_exponent)(struct wpan_phy *wpan_phy,
+					struct wpan_dev *wpan_dev, u8 min_be,
+					u8 max_be);
 };
 
 struct wpan_phy {
net/ieee802154/nl802154.c +34 -0
index 2978c1a..d1cf302 100644
@@ -616,6 +616,32 @@ static int nl802154_set_short_addr(struct sk_buff *skb, struct genl_info *info)
 	return rdev_set_short_addr(rdev, wpan_dev, short_addr);
 }
 
+static int
+nl802154_set_backoff_exponent(struct sk_buff *skb, struct genl_info *info)
+{
+	struct cfg802154_registered_device *rdev = info->user_ptr[0];
+	struct net_device *dev = info->user_ptr[1];
+	struct wpan_dev *wpan_dev = dev->ieee802154_ptr;
+	u8 min_be, max_be;
+
+	/* should be set on netif open inside phy settings */
+	if (netif_running(dev))
+		return -EBUSY;
+
+	if (!info->attrs[NL802154_ATTR_MIN_BE] ||
+	    !info->attrs[NL802154_ATTR_MAX_BE])
+		return -EINVAL;
+
+	min_be = nla_get_u8(info->attrs[NL802154_ATTR_MIN_BE]);
+	max_be = nla_get_u8(info->attrs[NL802154_ATTR_MAX_BE]);
+
+	/* check 802.15.4 constraints */
+	if (max_be < 3 || max_be > 8 || min_be > max_be)
+		return -EINVAL;
+
+	return rdev_set_backoff_exponent(rdev, wpan_dev, min_be, max_be);
+}
+
 #define NL802154_FLAG_NEED_WPAN_PHY	0x01
 #define NL802154_FLAG_NEED_NETDEV	0x02
 #define NL802154_FLAG_NEED_RTNL		0x04
@@ -750,6 +776,14 @@ static const struct genl_ops nl802154_ops[] = {
 		.internal_flags = NL802154_FLAG_NEED_NETDEV |
 				  NL802154_FLAG_NEED_RTNL,
 	},
+	{
+		.cmd = NL802154_CMD_SET_BACKOFF_EXPONENT,
+		.doit = nl802154_set_backoff_exponent,
+		.policy = nl802154_policy,
+		.flags = GENL_ADMIN_PERM,
+		.internal_flags = NL802154_FLAG_NEED_NETDEV |
+				  NL802154_FLAG_NEED_RTNL,
+	},
 };
 
 /* initialisation/exit functions */
net/ieee802154/rdev-ops.h +9 -0
index 16b0de0..dbccfa9 100644
@@ -41,4 +41,13 @@ rdev_set_short_addr(struct cfg802154_registered_device *rdev,
 	return rdev->ops->set_short_addr(&rdev->wpan_phy, wpan_dev, short_addr);
 }
 
+static inline int
+rdev_set_backoff_exponent(struct cfg802154_registered_device *rdev,
+			  struct wpan_dev *wpan_dev, const u8 min_be,
+			  const u8 max_be)
+{
+	return rdev->ops->set_backoff_exponent(&rdev->wpan_phy, wpan_dev,
+					       min_be, max_be);
+}
+
 #endif /* __CFG802154_RDEV_OPS */
net/mac802154/cfg.c +18 -0
index df29976..67c96f9 100644
@@ -84,6 +84,23 @@ static int ieee802154_set_pan_id(struct wpan_phy *wpan_phy,
 }
 
 static int
+ieee802154_set_backoff_exponent(struct wpan_phy *wpan_phy,
+				struct wpan_dev *wpan_dev,
+				const u8 min_be, const u8 max_be)
+{
+	struct ieee802154_local *local = wpan_phy_priv(wpan_phy);
+
+	ASSERT_RTNL();
+
+	if (!(local->hw.flags & IEEE802154_HW_CSMA_PARAMS))
+		return -EOPNOTSUPP;
+
+	wpan_dev->min_be = min_be;
+	wpan_dev->max_be = max_be;
+	return 0;
+}
+
+static int
 ieee802154_set_short_addr(struct wpan_phy *wpan_phy, struct wpan_dev *wpan_dev,
 			  const u16 short_addr)
 {
@@ -114,4 +131,5 @@ const struct cfg802154_ops mac802154_config_ops = {
 	.set_channel = ieee802154_set_channel,
 	.set_pan_id = ieee802154_set_pan_id,
 	.set_short_addr = ieee802154_set_short_addr,
+	.set_backoff_exponent = ieee802154_set_backoff_exponent,
 };
Signature · 1 line
2.1.3
author maintainer
#13 lore raw

PATCH 13/18 at86rf230: remove invalid backoff exponent check

In reply to Alexander Aring

This patch removes the invalid backoff exponent check from driver layer. This is already handled by nl802154.

---
 drivers/net/ieee802154/at86rf230.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/net/ieee802154/at86rf230.c +1 -1
index f9e3bce..05d4f8f 100644
@@ -1167,7 +1167,7 @@ at86rf230_set_csma_params(struct ieee802154_hw *hw, u8 min_be, u8 max_be,
 	struct at86rf230_local *lp = hw->priv;
 	int rc;
 
-	if (min_be > max_be || max_be > 8 || retries > 5)
+	if (retries > 5)
 		return -EINVAL;
 
 	rc = at86rf230_write_subreg(lp, SR_MIN_BE, min_be);
Signature · 1 line
2.1.3
author maintainer
#14 lore raw

PATCH 14/18 ieee820154: add max csma backoffs setting support

In reply to Alexander Aring

This patch add support for max csma backoffs setting via nl802154 framework.

---
 include/net/cfg802154.h   |  3 +++
 net/ieee802154/nl802154.c | 33 +++++++++++++++++++++++++++++++++
 net/ieee802154/rdev-ops.h |  9 +++++++++
 net/mac802154/cfg.c       | 16 ++++++++++++++++
 4 files changed, 61 insertions(+)
include/net/cfg802154.h +3 -0
index 27e98d1..79b9ae0 100644
@@ -45,6 +45,9 @@ struct cfg802154_ops {
 	int	(*set_backoff_exponent)(struct wpan_phy *wpan_phy,
 					struct wpan_dev *wpan_dev, u8 min_be,
 					u8 max_be);
+	int	(*set_max_csma_backoffs)(struct wpan_phy *wpan_phy,
+					 struct wpan_dev *wpan_dev,
+					 u8 max_csma_backoffs);
 };
 
 struct wpan_phy {
net/ieee802154/nl802154.c +33 -0
index d1cf302..af38355 100644
@@ -642,6 +642,31 @@ nl802154_set_backoff_exponent(struct sk_buff *skb, struct genl_info *info)
 	return rdev_set_backoff_exponent(rdev, wpan_dev, min_be, max_be);
 }
 
+static int
+nl802154_set_max_csma_backoffs(struct sk_buff *skb, struct genl_info *info)
+{
+	struct cfg802154_registered_device *rdev = info->user_ptr[0];
+	struct net_device *dev = info->user_ptr[1];
+	struct wpan_dev *wpan_dev = dev->ieee802154_ptr;
+	u8 max_csma_backoffs;
+
+	/* conflict here while other running iface settings */
+	if (netif_running(dev))
+		return -EBUSY;
+
+	if (!info->attrs[NL802154_ATTR_MAX_CSMA_BACKOFFS])
+		return -EINVAL;
+
+	max_csma_backoffs = nla_get_u8(
+			info->attrs[NL802154_ATTR_MAX_CSMA_BACKOFFS]);
+
+	/* check 802.15.4 constraints */
+	if (max_csma_backoffs > 5)
+		return -EINVAL;
+
+	return rdev_set_max_csma_backoffs(rdev, wpan_dev, max_csma_backoffs);
+}
+
 #define NL802154_FLAG_NEED_WPAN_PHY	0x01
 #define NL802154_FLAG_NEED_NETDEV	0x02
 #define NL802154_FLAG_NEED_RTNL		0x04
@@ -784,6 +809,14 @@ static const struct genl_ops nl802154_ops[] = {
 		.internal_flags = NL802154_FLAG_NEED_NETDEV |
 				  NL802154_FLAG_NEED_RTNL,
 	},
+	{
+		.cmd = NL802154_CMD_SET_MAX_CSMA_BACKOFFS,
+		.doit = nl802154_set_max_csma_backoffs,
+		.policy = nl802154_policy,
+		.flags = GENL_ADMIN_PERM,
+		.internal_flags = NL802154_FLAG_NEED_NETDEV |
+				  NL802154_FLAG_NEED_RTNL,
+	},
 };
 
 /* initialisation/exit functions */
net/ieee802154/rdev-ops.h +9 -0
index dbccfa9..263095c 100644
@@ -50,4 +50,13 @@ rdev_set_backoff_exponent(struct cfg802154_registered_device *rdev,
 					       min_be, max_be);
 }
 
+static inline int
+rdev_set_max_csma_backoffs(struct cfg802154_registered_device *rdev,
+			   struct wpan_dev *wpan_dev,
+			   const u8 max_csma_backoffs)
+{
+	return rdev->ops->set_max_csma_backoffs(&rdev->wpan_phy, wpan_dev,
+						max_csma_backoffs);
+}
+
 #endif /* __CFG802154_RDEV_OPS */
net/mac802154/cfg.c +16 -0
index 67c96f9..d72feeb 100644
@@ -125,6 +125,21 @@ ieee802154_set_short_addr(struct wpan_phy *wpan_phy, struct wpan_dev *wpan_dev,
 	return 0;
 }
 
+static int ieee802154_set_max_csma_backoffs(struct wpan_phy *wpan_phy,
+					    struct wpan_dev *wpan_dev,
+					    const u8 max_csma_backoffs)
+{
+	struct ieee802154_local *local = wpan_phy_priv(wpan_phy);
+
+	ASSERT_RTNL();
+
+	if (!(local->hw.flags & IEEE802154_HW_CSMA_PARAMS))
+		return -EOPNOTSUPP;
+
+	wpan_dev->csma_retries = max_csma_backoffs;
+	return 0;
+}
+
 const struct cfg802154_ops mac802154_config_ops = {
 	.add_virtual_intf_deprecated = ieee802154_add_iface_deprecated,
 	.del_virtual_intf_deprecated = ieee802154_del_iface_deprecated,
@@ -132,4 +147,5 @@ const struct cfg802154_ops mac802154_config_ops = {
 	.set_pan_id = ieee802154_set_pan_id,
 	.set_short_addr = ieee802154_set_short_addr,
 	.set_backoff_exponent = ieee802154_set_backoff_exponent,
+	.set_max_csma_backoffs = ieee802154_set_max_csma_backoffs,
 };
Signature · 1 line
2.1.3
author maintainer
#15 lore raw

PATCH 15/18 at86rf230: remove invalid max csma backoffs check

In reply to Alexander Aring

This patch removes the invalid check on max csma backoffs in driver layer. This is already handled by nl802154 framework.

---
 drivers/net/ieee802154/at86rf230.c | 3 ---
 1 file changed, 3 deletions(-)
drivers/net/ieee802154/at86rf230.c +0 -3
index 05d4f8f..aea00d3 100644
@@ -1167,9 +1167,6 @@ at86rf230_set_csma_params(struct ieee802154_hw *hw, u8 min_be, u8 max_be,
 	struct at86rf230_local *lp = hw->priv;
 	int rc;
 
-	if (retries > 5)
-		return -EINVAL;
-
 	rc = at86rf230_write_subreg(lp, SR_MIN_BE, min_be);
 	if (rc)
 		return rc;
Signature · 1 line
2.1.3
author maintainer
#16 lore raw

PATCH 16/18 ieee820154: add max frame retries setting support

In reply to Alexander Aring

This patch add support for setting mac frame retries setting via nl802154 framework.

---
 include/net/cfg802154.h   |  3 +++
 net/ieee802154/nl802154.c | 32 ++++++++++++++++++++++++++++++++
 net/ieee802154/rdev-ops.h |  9 +++++++++
 net/mac802154/cfg.c       | 16 ++++++++++++++++
 4 files changed, 60 insertions(+)
include/net/cfg802154.h +3 -0
index 79b9ae0..5c3bc12 100644
@@ -48,6 +48,9 @@ struct cfg802154_ops {
 	int	(*set_max_csma_backoffs)(struct wpan_phy *wpan_phy,
 					 struct wpan_dev *wpan_dev,
 					 u8 max_csma_backoffs);
+	int	(*set_max_frame_retries)(struct wpan_phy *wpan_phy,
+					 struct wpan_dev *wpan_dev,
+					 s8 max_frame_retries);
 };
 
 struct wpan_phy {
net/ieee802154/nl802154.c +32 -0
index af38355..0e272c6 100644
@@ -667,6 +667,30 @@ nl802154_set_max_csma_backoffs(struct sk_buff *skb, struct genl_info *info)
 	return rdev_set_max_csma_backoffs(rdev, wpan_dev, max_csma_backoffs);
 }
 
+static int
+nl802154_set_max_frame_retries(struct sk_buff *skb, struct genl_info *info)
+{
+	struct cfg802154_registered_device *rdev = info->user_ptr[0];
+	struct net_device *dev = info->user_ptr[1];
+	struct wpan_dev *wpan_dev = dev->ieee802154_ptr;
+	s8 max_frame_retries;
+
+	if (netif_running(dev))
+		return -EBUSY;
+
+	if (!info->attrs[NL802154_ATTR_MAX_FRAME_RETRIES])
+		return -EINVAL;
+
+	max_frame_retries = nla_get_s8(
+			info->attrs[NL802154_ATTR_MAX_FRAME_RETRIES]);
+
+	/* check 802.15.4 constraints */
+	if (max_frame_retries < -1 || max_frame_retries > 7)
+		return -EINVAL;
+
+	return rdev_set_max_frame_retries(rdev, wpan_dev, max_frame_retries);
+}
+
 #define NL802154_FLAG_NEED_WPAN_PHY	0x01
 #define NL802154_FLAG_NEED_NETDEV	0x02
 #define NL802154_FLAG_NEED_RTNL		0x04
@@ -817,6 +841,14 @@ static const struct genl_ops nl802154_ops[] = {
 		.internal_flags = NL802154_FLAG_NEED_NETDEV |
 				  NL802154_FLAG_NEED_RTNL,
 	},
+	{
+		.cmd = NL802154_CMD_SET_MAX_FRAME_RETRIES,
+		.doit = nl802154_set_max_frame_retries,
+		.policy = nl802154_policy,
+		.flags = GENL_ADMIN_PERM,
+		.internal_flags = NL802154_FLAG_NEED_NETDEV |
+				  NL802154_FLAG_NEED_RTNL,
+	},
 };
 
 /* initialisation/exit functions */
net/ieee802154/rdev-ops.h +9 -0
index 263095c..f9171aa 100644
@@ -59,4 +59,13 @@ rdev_set_max_csma_backoffs(struct cfg802154_registered_device *rdev,
 						max_csma_backoffs);
 }
 
+static inline int
+rdev_set_max_frame_retries(struct cfg802154_registered_device *rdev,
+			   struct wpan_dev *wpan_dev,
+			   const s8 max_frame_retries)
+{
+	return rdev->ops->set_max_frame_retries(&rdev->wpan_phy, wpan_dev,
+						max_frame_retries);
+}
+
 #endif /* __CFG802154_RDEV_OPS */
net/mac802154/cfg.c +16 -0
index d72feeb..a8f6eaa 100644
@@ -140,6 +140,21 @@ static int ieee802154_set_max_csma_backoffs(struct wpan_phy *wpan_phy,
 	return 0;
 }
 
+static int ieee802154_set_max_frame_retries(struct wpan_phy *wpan_phy,
+					    struct wpan_dev *wpan_dev,
+					    const s8 max_frame_retries)
+{
+	struct ieee802154_local *local = wpan_phy_priv(wpan_phy);
+
+	ASSERT_RTNL();
+
+	if (!(local->hw.flags & IEEE802154_HW_FRAME_RETRIES))
+		return -EOPNOTSUPP;
+
+	wpan_dev->frame_retries = max_frame_retries;
+	return 0;
+}
+
 const struct cfg802154_ops mac802154_config_ops = {
 	.add_virtual_intf_deprecated = ieee802154_add_iface_deprecated,
 	.del_virtual_intf_deprecated = ieee802154_del_iface_deprecated,
@@ -148,4 +163,5 @@ const struct cfg802154_ops mac802154_config_ops = {
 	.set_short_addr = ieee802154_set_short_addr,
 	.set_backoff_exponent = ieee802154_set_backoff_exponent,
 	.set_max_csma_backoffs = ieee802154_set_max_csma_backoffs,
+	.set_max_frame_retries = ieee802154_set_max_frame_retries,
 };
Signature · 1 line
2.1.3
author maintainer
#17 lore raw

PATCH 17/18 at86rf230: remove invalid max frame retries check

In reply to Alexander Aring

This patch removes the invalid max frame retries check from driver layer. This is already handled by nl802154 framework. Also the IEEE 802.15.4 standard doesn't allow a frame retries setting above 7. This seems to be valid for the at86rf230 transceiver but the chip running out of spec then. We only allow settings according 802.15.4 right now.

---
 drivers/net/ieee802154/at86rf230.c | 3 ---
 1 file changed, 3 deletions(-)
drivers/net/ieee802154/at86rf230.c +0 -3
index aea00d3..31d62f9 100644
@@ -1184,9 +1184,6 @@ at86rf230_set_frame_retries(struct ieee802154_hw *hw, s8 retries)
 	struct at86rf230_local *lp = hw->priv;
 	int rc = 0;
 
-	if (retries < -1 || retries > 15)
-		return -EINVAL;
-
 	lp->tx_aret = retries >= 0;
 	lp->max_frame_retries = retries;
 
Signature · 1 line
2.1.3
author maintainer
#18 lore raw

PATCH 18/18 ieee820154: add lbt setting support

In reply to Alexander Aring

This patch adds support for setting listen before transmit mode via nl802154 framework.

---
 include/net/cfg802154.h   |  2 ++
 net/ieee802154/nl802154.c | 25 +++++++++++++++++++++++++
 net/ieee802154/rdev-ops.h |  7 +++++++
 net/mac802154/cfg.c       | 16 ++++++++++++++++
 4 files changed, 50 insertions(+)
include/net/cfg802154.h +2 -0
index 5c3bc12..fa0a9e5 100644
@@ -51,6 +51,8 @@ struct cfg802154_ops {
 	int	(*set_max_frame_retries)(struct wpan_phy *wpan_phy,
 					 struct wpan_dev *wpan_dev,
 					 s8 max_frame_retries);
+	int	(*set_lbt_mode)(struct wpan_phy *wpan_phy,
+				struct wpan_dev *wpan_dev, bool mode);
 };
 
 struct wpan_phy {
net/ieee802154/nl802154.c +25 -0
index 0e272c6..ccdf33e 100644
@@ -691,6 +691,23 @@ nl802154_set_max_frame_retries(struct sk_buff *skb, struct genl_info *info)
 	return rdev_set_max_frame_retries(rdev, wpan_dev, max_frame_retries);
 }
 
+static int nl802154_set_lbt_mode(struct sk_buff *skb, struct genl_info *info)
+{
+	struct cfg802154_registered_device *rdev = info->user_ptr[0];
+	struct net_device *dev = info->user_ptr[1];
+	struct wpan_dev *wpan_dev = dev->ieee802154_ptr;
+	bool mode;
+
+	if (netif_running(dev))
+		return -EBUSY;
+
+	if (!info->attrs[NL802154_ATTR_LBT_MODE])
+		return -EINVAL;
+
+	mode = !!nla_get_u8(info->attrs[NL802154_ATTR_LBT_MODE]);
+	return rdev_set_lbt_mode(rdev, wpan_dev, mode);
+}
+
 #define NL802154_FLAG_NEED_WPAN_PHY	0x01
 #define NL802154_FLAG_NEED_NETDEV	0x02
 #define NL802154_FLAG_NEED_RTNL		0x04
@@ -849,6 +866,14 @@ static const struct genl_ops nl802154_ops[] = {
 		.internal_flags = NL802154_FLAG_NEED_NETDEV |
 				  NL802154_FLAG_NEED_RTNL,
 	},
+	{
+		.cmd = NL802154_CMD_SET_LBT_MODE,
+		.doit = nl802154_set_lbt_mode,
+		.policy = nl802154_policy,
+		.flags = GENL_ADMIN_PERM,
+		.internal_flags = NL802154_FLAG_NEED_NETDEV |
+				  NL802154_FLAG_NEED_RTNL,
+	},
 };
 
 /* initialisation/exit functions */
net/ieee802154/rdev-ops.h +7 -0
index f9171aa..a78f700 100644
@@ -68,4 +68,11 @@ rdev_set_max_frame_retries(struct cfg802154_registered_device *rdev,
 						max_frame_retries);
 }
 
+static inline int
+rdev_set_lbt_mode(struct cfg802154_registered_device *rdev,
+		  struct wpan_dev *wpan_dev, const bool mode)
+{
+	return rdev->ops->set_lbt_mode(&rdev->wpan_phy, wpan_dev, mode);
+}
+
 #endif /* __CFG802154_RDEV_OPS */
net/mac802154/cfg.c +16 -0
index a8f6eaa..5d669d8 100644
@@ -155,6 +155,21 @@ static int ieee802154_set_max_frame_retries(struct wpan_phy *wpan_phy,
 	return 0;
 }
 
+static int ieee802154_set_lbt_mode(struct wpan_phy *wpan_phy,
+				   struct wpan_dev *wpan_dev,
+				   const bool mode)
+{
+	struct ieee802154_local *local = wpan_phy_priv(wpan_phy);
+
+	ASSERT_RTNL();
+
+	if (!(local->hw.flags & IEEE802154_HW_LBT))
+		return -EOPNOTSUPP;
+
+	wpan_dev->lbt = mode;
+	return 0;
+}
+
 const struct cfg802154_ops mac802154_config_ops = {
 	.add_virtual_intf_deprecated = ieee802154_add_iface_deprecated,
 	.del_virtual_intf_deprecated = ieee802154_del_iface_deprecated,
@@ -164,4 +179,5 @@ const struct cfg802154_ops mac802154_config_ops = {
 	.set_backoff_exponent = ieee802154_set_backoff_exponent,
 	.set_max_csma_backoffs = ieee802154_set_max_csma_backoffs,
 	.set_max_frame_retries = ieee802154_set_max_frame_retries,
+	.set_lbt_mode = ieee802154_set_lbt_mode,
 };
Signature · 1 line
2.1.3
#19 lore raw
In reply to Alexander Aring

Hi Alex,

Quoted 33 lines

This patch series contains iface handling cleanup patches and mostly trivial patches to support several netlink commands. Also removing the constraints checks for 802.15.4 parameters from driver layer. This should be handled by nl802154 layer now. The old netlink interface should be deprecated now and these constraints checks are not supported anymore by the old netlink interface. Some of the current driver never checked on these constraints so we don't fix the old netlink interface anymore to check on "global" 802.15.4 constraints.

All users should use the wpan-tools from [0] now. Some cmd's are not supported already like interface deletion or adding, but will be supported in near future.

[0] https://github.com/linux-wpan/wpan-tools/archive/wpan-tools-0.1.tar.gz

Alexander Aring (18):
mac820154: move interface unregistration into iface
mac820154: rename sdata next to tmp
mac820154: move mutex locks out of loop
mac802154: add wpan_phy priv id
mac802154: change module description
mac802154: add ifname change notifier
ieee802154: cleanup cfg802154 intendation
ieee820154: add channel set support
ieee820154: remove valid page and channel checks
ieee820154: add pan_id setting support
ieee820154: add short_addr setting support
ieee820154: add backoff exponent setting support
at86rf230: remove invalid backoff exponent check
ieee820154: add max csma backoffs setting support
at86rf230: remove invalid max csma backoffs check
ieee820154: add max frame retries setting support
at86rf230: remove invalid max frame retries check
ieee820154: add lbt setting support

Quoted 12 lines
drivers/net/ieee802154/at86rf230.c |  20 +---
drivers/net/ieee802154/fakelb.c    |   3 -
include/linux/ieee802154.h         |   4 +
include/net/cfg802154.h            |  28 ++++-
net/ieee802154/nl802154.c          | 214 +++++++++++++++++++++++++++++++++++++
net/ieee802154/rdev-ops.h          |  55 ++++++++++
net/mac802154/cfg.c                | 136 +++++++++++++++++++++++
net/mac802154/ieee802154_i.h       |   7 ++
net/mac802154/iface.c              |  48 +++++++++
net/mac802154/main.c               |  28 +++--
net/mac802154/util.c               |   3 +
11 files changed, 513 insertions(+), 33 deletions(-)

all 18 patches have been applied to bluetooth-next tree.

Regards

Marcel