Skip to contentSkip to conversation

mac802154: util: add stop_device utility function

PATCH In review Alexander Aring 2 participants 6 messages Jun 24, 2015

Subsystems (2)
lore
Share & tools
lore

Alexander Aring

author maintainer
#0 lore raw

PATCH 1/3 mac802154: util: add stop_device utility function

This patch adds ieee802154_stop_device for preparing a utility function to stop the ieee802154 device.

---
 net/mac802154/ieee802154_i.h | 1 +
 net/mac802154/iface.c        | 7 ++-----
 net/mac802154/util.c         | 8 ++++++++
 3 files changed, 11 insertions(+), 5 deletions(-)
net/mac802154/ieee802154_i.h +1 -0
index ed87463..0407783 100644
@@ -176,5 +176,6 @@ ieee802154_if_add(struct ieee802154_local *local, const char *name,
 		  unsigned char name_assign_type, enum nl802154_iftype type,
 		  __le64 extended_addr);
 void ieee802154_remove_interfaces(struct ieee802154_local *local);
+void ieee802154_stop_device(struct ieee802154_local *local);
 
 #endif /* __IEEE802154_I_H */
net/mac802154/iface.c +2 -5
index 4760368..416de90 100644
@@ -314,11 +314,8 @@ static int mac802154_slave_close(struct net_device *dev)
 
 	clear_bit(SDATA_STATE_RUNNING, &sdata->state);
 
-	if (!local->open_count) {
-		flush_workqueue(local->workqueue);
-		hrtimer_cancel(&local->ifs_timer);
-		drv_stop(local);
-	}
+	if (!local->open_count)
+		ieee802154_stop_device(local);
 
 	return 0;
 }
net/mac802154/util.c +8 -0
index 583435f..f9fd095 100644
@@ -14,6 +14,7 @@
  */
 
 #include "ieee802154_i.h"
+#include "driver-ops.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;
@@ -92,3 +93,10 @@ void ieee802154_xmit_complete(struct ieee802154_hw *hw, struct sk_buff *skb,
 	dev_consume_skb_any(skb);
 }
 EXPORT_SYMBOL(ieee802154_xmit_complete);
+
+void ieee802154_stop_device(struct ieee802154_local *local)
+{
+	flush_workqueue(local->workqueue);
+	hrtimer_cancel(&local->ifs_timer);
+	drv_stop(local);
+}
Signature · 1 line
2.4.4
author maintainer
#1 lore raw

PATCH 2/3 cfg802154: add PM hooks

From: Varka Bhadram <[email protected]>

This patch help to implement suspend/resume in mac802154, these hooks will be run before the device is suspended and after it resumes.

---
 include/net/cfg802154.h   |  2 ++
 net/ieee802154/rdev-ops.h | 20 ++++++++++++++++++++
 net/ieee802154/sysfs.c    | 38 ++++++++++++++++++++++++++++++++++++++
 net/ieee802154/trace.h    | 22 ++++++++++++++++++++++
 4 files changed, 82 insertions(+)
include/net/cfg802154.h +2 -0
index 290a9a6..382f94b 100644
@@ -34,6 +34,8 @@ struct cfg802154_ops {
 							   int type);
 	void	(*del_virtual_intf_deprecated)(struct wpan_phy *wpan_phy,
 					       struct net_device *dev);
+	int	(*suspend)(struct wpan_phy *wpan_phy);
+	int	(*resume)(struct wpan_phy *wpan_phy);
 	int	(*add_virtual_intf)(struct wpan_phy *wpan_phy,
 				    const char *name,
 				    unsigned char name_assign_type,
net/ieee802154/rdev-ops.h +20 -0
index b2155a1..8d5960a 100644
@@ -24,6 +24,26 @@ rdev_del_virtual_intf_deprecated(struct cfg802154_registered_device *rdev,
 }
 
 static inline int
+rdev_suspend(struct cfg802154_registered_device *rdev)
+{
+	int ret;
+	trace_802154_rdev_suspend(&rdev->wpan_phy);
+	ret = rdev->ops->suspend(&rdev->wpan_phy);
+	trace_802154_rdev_return_int(&rdev->wpan_phy, ret);
+	return ret;
+}
+
+static inline int
+rdev_resume(struct cfg802154_registered_device *rdev)
+{
+	int ret;
+	trace_802154_rdev_resume(&rdev->wpan_phy);
+	ret = rdev->ops->resume(&rdev->wpan_phy);
+	trace_802154_rdev_return_int(&rdev->wpan_phy, ret);
+	return ret;
+}
+
+static inline int
 rdev_add_virtual_intf(struct cfg802154_registered_device *rdev, char *name,
 		      unsigned char name_assign_type,
 		      enum nl802154_iftype type, __le64 extended_addr)
net/ieee802154/sysfs.c +38 -0
index 133b428..bd88525 100644
@@ -14,11 +14,13 @@
  */
 
 #include <linux/device.h>
+#include <linux/rtnetlink.h>
 
 #include <net/cfg802154.h>
 
 #include "core.h"
 #include "sysfs.h"
+#include "rdev-ops.h"
 
 static inline struct cfg802154_registered_device *
 dev_to_rdev(struct device *dev)
@@ -62,10 +64,46 @@ static struct attribute *pmib_attrs[] = {
 };
 ATTRIBUTE_GROUPS(pmib);
 
+#ifdef CONFIG_PM_SLEEP
+static int wpan_phy_suspend(struct device *dev)
+{
+	struct cfg802154_registered_device *rdev = dev_to_rdev(dev);
+	int ret = 0;
+
+	if (rdev->ops->suspend) {
+		rtnl_lock();
+		ret = rdev_suspend(rdev);
+		rtnl_unlock();
+	}
+
+	return ret;
+}
+
+static int wpan_phy_resume(struct device *dev)
+{
+	struct cfg802154_registered_device *rdev = dev_to_rdev(dev);
+	int ret = 0;
+
+	if (rdev->ops->resume) {
+		rtnl_lock();
+		ret = rdev_resume(rdev);
+		rtnl_unlock();
+	}
+
+	return ret;
+}
+
+static SIMPLE_DEV_PM_OPS(wpan_phy_pm_ops, wpan_phy_suspend, wpan_phy_resume);
+#define WPAN_PHY_PM_OPS (&wpan_phy_pm_ops)
+#else
+#define WPAN_PHY_PM_OPS NULL
+#endif
+
 struct class wpan_phy_class = {
 	.name = "ieee802154",
 	.dev_release = wpan_phy_release,
 	.dev_groups = pmib_groups,
+	.pm = WPAN_PHY_PM_OPS,
 };
 
 int wpan_phy_sysfs_init(void)
net/ieee802154/trace.h +22 -0
index 9b5f0eb..4399b7f 100644
@@ -40,6 +40,28 @@
  *			rdev->ops traces		     *
  *************************************************************/
 
+DECLARE_EVENT_CLASS(wpan_phy_only_evt,
+	TP_PROTO(struct wpan_phy *wpan_phy),
+	TP_ARGS(wpan_phy),
+	TP_STRUCT__entry(
+		WPAN_PHY_ENTRY
+	),
+	TP_fast_assign(
+		WPAN_PHY_ASSIGN;
+	),
+	TP_printk(WPAN_PHY_PR_FMT, WPAN_PHY_PR_ARG)
+);
+
+DEFINE_EVENT(wpan_phy_only_evt, 802154_rdev_suspend,
+	TP_PROTO(struct wpan_phy *wpan_phy),
+	TP_ARGS(wpan_phy)
+);
+
+DEFINE_EVENT(wpan_phy_only_evt, 802154_rdev_resume,
+	TP_PROTO(struct wpan_phy *wpan_phy),
+	TP_ARGS(wpan_phy)
+);
+
 TRACE_EVENT(802154_rdev_add_virtual_intf,
 	TP_PROTO(struct wpan_phy *wpan_phy, char *name,
 		 enum nl802154_iftype type, __le64 extended_addr),
Signature · 1 line
2.4.4
#2 lore raw

Re: [PATCH bluetooth-next 2/3] cfg802154: add PM hooks

Hi Alex,

Quoted 4 lines

This patch help to implement suspend/resume in mac802154, these hooks will be run before the device is suspended and after it resumes.

Quoted 8 lines

---

include/net/cfg802154.h   |  2 ++
net/ieee802154/rdev-ops.h | 20 ++++++++++++++++++++
net/ieee802154/sysfs.c    | 38 ++++++++++++++++++++++++++++++++++++++
net/ieee802154/trace.h    | 22 ++++++++++++++++++++++
4 files changed, 82 insertions(+)

patch has been applied to bluetooth-next tree.

Regards

Marcel

author maintainer
#3 lore raw

PATCH 3/3 mac802154: cfg: add suspend and resume callbacks

In reply to Alexander Aring

This patch introduces suspend and resume callbacks to mac802154. When doing suspend we calling the stop driver callback which should stop the receiving of frames. A transceiver should go into low-power mode then. Calling resume will call the start driver callback, which starts receiving again and allow to transmit frames.

This was tested only with the fakelb driver and a qemu vm by doing the following commands:

echo "devices" > /sys/power/pm_test
echo "freeze" > /sys/power/state

while doing some high traffic between two fakelb phys.

---
 net/mac802154/cfg.c          | 45 ++++++++++++++++++++++++++++++++++++++++++++
 net/mac802154/ieee802154_i.h |  1 +
 net/mac802154/rx.c           | 10 ++++++++--
 3 files changed, 54 insertions(+), 2 deletions(-)
net/mac802154/cfg.c +45 -0
index 44db861..f7ba51e 100644
@@ -44,6 +44,49 @@ static void ieee802154_del_iface_deprecated(struct wpan_phy *wpan_phy,
 	ieee802154_if_remove(sdata);
 }
 
+#ifdef CONFIG_PM
+static int ieee802154_suspend(struct wpan_phy *wpan_phy)
+{
+	struct ieee802154_local *local = wpan_phy_priv(wpan_phy);
+
+	if (!local->open_count)
+		goto suspend;
+
+	ieee802154_stop_queue(&local->hw);
+	synchronize_net();
+
+	/* stop hardware - this must stop RX */
+	ieee802154_stop_device(local);
+
+suspend:
+	local->suspended = true;
+	return 0;
+}
+
+static int ieee802154_resume(struct wpan_phy *wpan_phy)
+{
+	struct ieee802154_local *local = wpan_phy_priv(wpan_phy);
+	int ret;
+
+	/* nothing to do if HW shouldn't run */
+	if (!local->open_count)
+		goto wake_up;
+
+	/* restart hardware */
+	ret = drv_start(local);
+	if (ret)
+		return ret;
+
+wake_up:
+	ieee802154_wake_queue(&local->hw);
+	local->suspended = false;
+	return 0;
+}
+#else
+#define ieee802154_suspend NULL
+#define ieee802154_resume NULL
+#endif
+
 static int
 ieee802154_add_iface(struct wpan_phy *phy, const char *name,
 		     unsigned char name_assign_type,
@@ -232,6 +275,8 @@ ieee802154_set_lbt_mode(struct wpan_phy *wpan_phy, struct wpan_dev *wpan_dev,
 const struct cfg802154_ops mac802154_config_ops = {
 	.add_virtual_intf_deprecated = ieee802154_add_iface_deprecated,
 	.del_virtual_intf_deprecated = ieee802154_del_iface_deprecated,
+	.suspend = ieee802154_suspend,
+	.resume = ieee802154_resume,
 	.add_virtual_intf = ieee802154_add_iface,
 	.del_virtual_intf = ieee802154_del_iface,
 	.set_channel = ieee802154_set_channel,
net/mac802154/ieee802154_i.h +1 -0
index 0407783..0054f39 100644
@@ -56,6 +56,7 @@ struct ieee802154_local {
 	struct hrtimer ifs_timer;
 
 	bool started;
+	bool suspended;
 
 	struct tasklet_struct tasklet;
 	struct sk_buff_head skb_queue;
net/mac802154/rx.c +8 -2
index d93ad2d..5a258c1 100644
@@ -253,6 +253,9 @@ void ieee802154_rx(struct ieee802154_hw *hw, struct sk_buff *skb)
 
 	WARN_ON_ONCE(softirq_count() == 0);
 
+	if (local->suspended)
+		goto drop;
+
 	/* TODO: When a transceiver omits the checksum here, we
 	 * add an own calculated one. This is currently an ugly
 	 * solution because the monitor needs a crc here.
@@ -273,8 +276,7 @@ void ieee802154_rx(struct ieee802154_hw *hw, struct sk_buff *skb)
 		crc = crc_ccitt(0, skb->data, skb->len);
 		if (crc) {
 			rcu_read_unlock();
-			kfree_skb(skb);
-			return;
+			goto drop;
 		}
 	}
 	/* remove crc */
@@ -283,6 +285,10 @@ void ieee802154_rx(struct ieee802154_hw *hw, struct sk_buff *skb)
 	__ieee802154_rx_handle_packet(local, skb);
 
 	rcu_read_unlock();
+
+	return;
+drop:
+	kfree_skb(skb);
 }
 EXPORT_SYMBOL(ieee802154_rx);
 
Signature · 1 line
2.4.4
#4 lore raw

Re: [PATCH bluetooth-next 3/3] mac802154: cfg: add suspend and resume callbacks

Hi Alex,

Quoted 12 lines

This patch introduces suspend and resume callbacks to mac802154. When doing suspend we calling the stop driver callback which should stop the receiving of frames. A transceiver should go into low-power mode then. Calling resume will call the start driver callback, which starts receiving again and allow to transmit frames.

This was tested only with the fakelb driver and a qemu vm by doing the following commands:

echo "devices" > /sys/power/pm_test
echo "freeze" > /sys/power/state

Quoted 8 lines

while doing some high traffic between two fakelb phys.

---

net/mac802154/cfg.c          | 45 ++++++++++++++++++++++++++++++++++++++++++++
net/mac802154/ieee802154_i.h |  1 +
net/mac802154/rx.c           | 10 ++++++++--
3 files changed, 54 insertions(+), 2 deletions(-)

patch has been applied to bluetooth-next tree.

Regards

Marcel

#5 lore raw
In reply to Alexander Aring

Hi Alex,

Quoted 9 lines

This patch adds ieee802154_stop_device for preparing a utility function to stop the ieee802154 device.

---

net/mac802154/ieee802154_i.h | 1 +
net/mac802154/iface.c        | 7 ++-----
net/mac802154/util.c         | 8 ++++++++
3 files changed, 11 insertions(+), 5 deletions(-)

patch has been applied to bluetooth-next tree.

Regards

Marcel