Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 184452
b: refs/heads/master
c: ffb9eb3
h: refs/heads/master
v: v3
  • Loading branch information
Kalle Valo authored and John W. Linville committed Feb 19, 2010
1 parent e743d6b commit 6258d8f
Show file tree
Hide file tree
Showing 6 changed files with 160 additions and 16 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: 088ea189c4c75cdf211146faa4b341a0f7476be6
refs/heads/master: ffb9eb3d8b450c22bbbc688c6b630141ac476fd9
10 changes: 10 additions & 0 deletions trunk/include/linux/nl80211.h
Original file line number Diff line number Diff line change
Expand Up @@ -416,6 +416,9 @@ enum nl80211_commands {
NL80211_CMD_ACTION,
NL80211_CMD_ACTION_TX_STATUS,

NL80211_CMD_SET_POWER_SAVE,
NL80211_CMD_GET_POWER_SAVE,

/* add new commands above here */

/* used to define NL80211_CMD_MAX below */
Expand Down Expand Up @@ -837,6 +840,8 @@ enum nl80211_attrs {

NL80211_ATTR_ACK,

NL80211_ATTR_PS_STATE,

/* add attributes here, update the policy in nl80211.c */

__NL80211_ATTR_AFTER_LAST,
Expand Down Expand Up @@ -1573,4 +1578,9 @@ enum nl80211_band {
NL80211_BAND_5GHZ,
};

enum nl80211_ps_state {
NL80211_PS_DISABLED,
NL80211_PS_ENABLED,
};

#endif /* __LINUX_NL80211_H */
7 changes: 4 additions & 3 deletions trunk/include/net/cfg80211.h
Original file line number Diff line number Diff line change
Expand Up @@ -1150,7 +1150,6 @@ struct cfg80211_ops {
enum nl80211_channel_type channel_type,
const u8 *buf, size_t len, u64 *cookie);

/* some temporary stuff to finish wext */
int (*set_power_mgmt)(struct wiphy *wiphy, struct net_device *dev,
bool enabled, int timeout);
};
Expand Down Expand Up @@ -1489,6 +1488,9 @@ struct wireless_dev {
struct cfg80211_internal_bss *auth_bsses[MAX_AUTH_BSSES];
struct cfg80211_internal_bss *current_bss; /* associated / joined */

bool ps;
int ps_timeout;

#ifdef CONFIG_CFG80211_WEXT
/* wext data */
struct {
Expand All @@ -1500,8 +1502,7 @@ struct wireless_dev {
u8 bssid[ETH_ALEN], prev_bssid[ETH_ALEN];
u8 ssid[IEEE80211_MAX_SSID_LEN];
s8 default_key, default_mgmt_key;
bool ps, prev_bssid_valid;
int ps_timeout;
bool prev_bssid_valid;
} wext;
#endif
};
Expand Down
16 changes: 9 additions & 7 deletions trunk/net/wireless/core.c
Original file line number Diff line number Diff line change
Expand Up @@ -698,19 +698,21 @@ static int cfg80211_netdev_notifier_call(struct notifier_block * nb,
wdev->wext.default_key = -1;
wdev->wext.default_mgmt_key = -1;
wdev->wext.connect.auth_type = NL80211_AUTHTYPE_AUTOMATIC;
#endif

if (wdev->wiphy->flags & WIPHY_FLAG_PS_ON_BY_DEFAULT)
wdev->wext.ps = true;
wdev->ps = true;
else
wdev->wext.ps = false;
wdev->wext.ps_timeout = 100;
wdev->ps = false;
wdev->ps_timeout = 100;
if (rdev->ops->set_power_mgmt)
if (rdev->ops->set_power_mgmt(wdev->wiphy, dev,
wdev->wext.ps,
wdev->wext.ps_timeout)) {
wdev->ps,
wdev->ps_timeout)) {
/* assume this means it's off */
wdev->wext.ps = false;
wdev->ps = false;
}
#endif

if (!dev->ethtool_ops)
dev->ethtool_ops = &cfg80211_ethtool_ops;

Expand Down
131 changes: 131 additions & 0 deletions trunk/net/wireless/nl80211.c
Original file line number Diff line number Diff line change
Expand Up @@ -148,6 +148,7 @@ static struct nla_policy nl80211_policy[NL80211_ATTR_MAX+1] __read_mostly = {
[NL80211_ATTR_FRAME] = { .type = NLA_BINARY,
.len = IEEE80211_MAX_DATA_LEN },
[NL80211_ATTR_FRAME_MATCH] = { .type = NLA_BINARY, },
[NL80211_ATTR_PS_STATE] = { .type = NLA_U32 },
};

/* policy for the attributes */
Expand Down Expand Up @@ -4663,6 +4664,124 @@ static int nl80211_action(struct sk_buff *skb, struct genl_info *info)
return err;
}

static int nl80211_set_power_save(struct sk_buff *skb, struct genl_info *info)
{
struct cfg80211_registered_device *rdev;
struct wireless_dev *wdev;
struct net_device *dev;
u8 ps_state;
bool state;
int err;

if (!info->attrs[NL80211_ATTR_PS_STATE]) {
err = -EINVAL;
goto out;
}

ps_state = nla_get_u32(info->attrs[NL80211_ATTR_PS_STATE]);

if (ps_state != NL80211_PS_DISABLED && ps_state != NL80211_PS_ENABLED) {
err = -EINVAL;
goto out;
}

rtnl_lock();

err = get_rdev_dev_by_info_ifindex(info, &rdev, &dev);
if (err)
goto unlock_rdev;

wdev = dev->ieee80211_ptr;

if (!rdev->ops->set_power_mgmt) {
err = -EOPNOTSUPP;
goto unlock_rdev;
}

state = (ps_state == NL80211_PS_ENABLED) ? true : false;

if (state == wdev->ps)
goto unlock_rdev;

wdev->ps = state;

if (rdev->ops->set_power_mgmt(wdev->wiphy, dev, wdev->ps,
wdev->ps_timeout))
/* assume this means it's off */
wdev->ps = false;

unlock_rdev:
cfg80211_unlock_rdev(rdev);
dev_put(dev);
rtnl_unlock();

out:
return err;
}

static int nl80211_get_power_save(struct sk_buff *skb, struct genl_info *info)
{
struct cfg80211_registered_device *rdev;
enum nl80211_ps_state ps_state;
struct wireless_dev *wdev;
struct net_device *dev;
struct sk_buff *msg;
void *hdr;
int err;

rtnl_lock();

err = get_rdev_dev_by_info_ifindex(info, &rdev, &dev);
if (err)
goto unlock_rtnl;

wdev = dev->ieee80211_ptr;

if (!rdev->ops->set_power_mgmt) {
err = -EOPNOTSUPP;
goto out;
}

msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
if (!msg) {
err = -ENOMEM;
goto out;
}

hdr = nl80211hdr_put(msg, info->snd_pid, info->snd_seq, 0,
NL80211_CMD_GET_POWER_SAVE);
if (!hdr) {
err = -ENOMEM;
goto free_msg;
}

if (wdev->ps)
ps_state = NL80211_PS_ENABLED;
else
ps_state = NL80211_PS_DISABLED;

NLA_PUT_U32(msg, NL80211_ATTR_PS_STATE, ps_state);

genlmsg_end(msg, hdr);
err = genlmsg_reply(msg, info);
goto out;

nla_put_failure:
err = -ENOBUFS;

free_msg:
nlmsg_free(msg);

out:
cfg80211_unlock_rdev(rdev);
dev_put(dev);

unlock_rtnl:
rtnl_unlock();

return err;
}

static struct genl_ops nl80211_ops[] = {
{
.cmd = NL80211_CMD_GET_WIPHY,
Expand Down Expand Up @@ -4955,6 +5074,18 @@ static struct genl_ops nl80211_ops[] = {
.policy = nl80211_policy,
.flags = GENL_ADMIN_PERM,
},
{
.cmd = NL80211_CMD_SET_POWER_SAVE,
.doit = nl80211_set_power_save,
.policy = nl80211_policy,
.flags = GENL_ADMIN_PERM,
},
{
.cmd = NL80211_CMD_GET_POWER_SAVE,
.doit = nl80211_get_power_save,
.policy = nl80211_policy,
/* can be retrieved by unprivileged users */
},
};

static struct genl_multicast_group nl80211_mlme_mcgrp = {
Expand Down
10 changes: 5 additions & 5 deletions trunk/net/wireless/wext-compat.c
Original file line number Diff line number Diff line change
Expand Up @@ -1099,8 +1099,8 @@ int cfg80211_wext_siwpower(struct net_device *dev,
{
struct wireless_dev *wdev = dev->ieee80211_ptr;
struct cfg80211_registered_device *rdev = wiphy_to_dev(wdev->wiphy);
bool ps = wdev->wext.ps;
int timeout = wdev->wext.ps_timeout;
bool ps = wdev->ps;
int timeout = wdev->ps_timeout;
int err;

if (wdev->iftype != NL80211_IFTYPE_STATION)
Expand Down Expand Up @@ -1133,8 +1133,8 @@ int cfg80211_wext_siwpower(struct net_device *dev,
if (err)
return err;

wdev->wext.ps = ps;
wdev->wext.ps_timeout = timeout;
wdev->ps = ps;
wdev->ps_timeout = timeout;

return 0;

Expand All @@ -1147,7 +1147,7 @@ int cfg80211_wext_giwpower(struct net_device *dev,
{
struct wireless_dev *wdev = dev->ieee80211_ptr;

wrq->disabled = !wdev->wext.ps;
wrq->disabled = !wdev->ps;

return 0;
}
Expand Down

0 comments on commit 6258d8f

Please sign in to comment.