diff options
author | Alexander Aring <alex.aring@gmail.com> | 2015-06-24 12:36:36 +0300 |
---|---|---|
committer | Marcel Holtmann <marcel@holtmann.org> | 2015-07-23 18:10:49 +0300 |
commit | 3cf24cf8c3c06f9a6cacc8fc2cad94661b6096b6 (patch) | |
tree | b1192515ba1dcac09a108816386df1145a003a7c /net/mac802154/cfg.c | |
parent | a6cb869b3b7c16fd7c3ee766dd9f9a4fdda7edf9 (diff) | |
download | linux-3cf24cf8c3c06f9a6cacc8fc2cad94661b6096b6.tar.xz |
mac802154: cfg: add suspend and resume callbacks
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.
Signed-off-by: Alexander Aring <alex.aring@gmail.com>
Signed-off-by: Marcel Holtmann <marcel@holtmann.org>
Diffstat (limited to 'net/mac802154/cfg.c')
-rw-r--r-- | net/mac802154/cfg.c | 45 |
1 files changed, 45 insertions, 0 deletions
diff --git a/net/mac802154/cfg.c b/net/mac802154/cfg.c index 44db8613812e..f7ba51e8b4ca 100644 --- a/net/mac802154/cfg.c +++ b/net/mac802154/cfg.c @@ -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, |