diff options
author | Johannes Berg <johannes.berg@intel.com> | 2012-10-24 04:17:18 -0400 |
---|---|---|
committer | Johannes Berg <johannes.berg@intel.com> | 2012-10-30 04:11:34 -0400 |
commit | c8442118ad9cd05cfe3b993f058e70ab25b1009a (patch) | |
tree | e9d454ef6461e70cf99de76f9dda52952b665e44 /net | |
parent | 71fe96bf9db8b117d28de6f9ced606cae2ad9661 (diff) |
cfg80211: allow per interface TX power setting
The TX power setting is currently per wiphy (hardware
device) but with multi-channel capabilities that doesn't
make much sense any more.
Allow drivers (and mac80211) to advertise support for
per-interface TX power configuration. When the TX power
is configured for the wiphy, the wdev will be NULL and
the driver can still handle that, but when a wdev is
given the TX power can be set only for that wdev now.
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
Diffstat (limited to 'net')
-rw-r--r-- | net/mac80211/cfg.c | 5 | ||||
-rw-r--r-- | net/wireless/nl80211.c | 6 | ||||
-rw-r--r-- | net/wireless/rdev-ops.h | 11 | ||||
-rw-r--r-- | net/wireless/trace.h | 24 | ||||
-rw-r--r-- | net/wireless/wext-compat.c | 4 |
5 files changed, 30 insertions, 20 deletions
diff --git a/net/mac80211/cfg.c b/net/mac80211/cfg.c index 34fd3eba3090..a352e4d22dd9 100644 --- a/net/mac80211/cfg.c +++ b/net/mac80211/cfg.c | |||
@@ -1992,6 +1992,7 @@ static int ieee80211_set_wiphy_params(struct wiphy *wiphy, u32 changed) | |||
1992 | } | 1992 | } |
1993 | 1993 | ||
1994 | static int ieee80211_set_tx_power(struct wiphy *wiphy, | 1994 | static int ieee80211_set_tx_power(struct wiphy *wiphy, |
1995 | struct wireless_dev *wdev, | ||
1995 | enum nl80211_tx_power_setting type, int mbm) | 1996 | enum nl80211_tx_power_setting type, int mbm) |
1996 | { | 1997 | { |
1997 | struct ieee80211_local *local = wiphy_priv(wiphy); | 1998 | struct ieee80211_local *local = wiphy_priv(wiphy); |
@@ -2026,7 +2027,9 @@ static int ieee80211_set_tx_power(struct wiphy *wiphy, | |||
2026 | return 0; | 2027 | return 0; |
2027 | } | 2028 | } |
2028 | 2029 | ||
2029 | static int ieee80211_get_tx_power(struct wiphy *wiphy, int *dbm) | 2030 | static int ieee80211_get_tx_power(struct wiphy *wiphy, |
2031 | struct wireless_dev *wdev, | ||
2032 | int *dbm) | ||
2030 | { | 2033 | { |
2031 | struct ieee80211_local *local = wiphy_priv(wiphy); | 2034 | struct ieee80211_local *local = wiphy_priv(wiphy); |
2032 | 2035 | ||
diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c index 879ca620fd6f..87d4670ee53a 100644 --- a/net/wireless/nl80211.c +++ b/net/wireless/nl80211.c | |||
@@ -1585,9 +1585,13 @@ static int nl80211_set_wiphy(struct sk_buff *skb, struct genl_info *info) | |||
1585 | } | 1585 | } |
1586 | 1586 | ||
1587 | if (info->attrs[NL80211_ATTR_WIPHY_TX_POWER_SETTING]) { | 1587 | if (info->attrs[NL80211_ATTR_WIPHY_TX_POWER_SETTING]) { |
1588 | struct wireless_dev *txp_wdev = wdev; | ||
1588 | enum nl80211_tx_power_setting type; | 1589 | enum nl80211_tx_power_setting type; |
1589 | int idx, mbm = 0; | 1590 | int idx, mbm = 0; |
1590 | 1591 | ||
1592 | if (!(rdev->wiphy.features & NL80211_FEATURE_VIF_TXPOWER)) | ||
1593 | txp_wdev = NULL; | ||
1594 | |||
1591 | if (!rdev->ops->set_tx_power) { | 1595 | if (!rdev->ops->set_tx_power) { |
1592 | result = -EOPNOTSUPP; | 1596 | result = -EOPNOTSUPP; |
1593 | goto bad_res; | 1597 | goto bad_res; |
@@ -1607,7 +1611,7 @@ static int nl80211_set_wiphy(struct sk_buff *skb, struct genl_info *info) | |||
1607 | mbm = nla_get_u32(info->attrs[idx]); | 1611 | mbm = nla_get_u32(info->attrs[idx]); |
1608 | } | 1612 | } |
1609 | 1613 | ||
1610 | result = rdev_set_tx_power(rdev, type, mbm); | 1614 | result = rdev_set_tx_power(rdev, txp_wdev, type, mbm); |
1611 | if (result) | 1615 | if (result) |
1612 | goto bad_res; | 1616 | goto bad_res; |
1613 | } | 1617 | } |
diff --git a/net/wireless/rdev-ops.h b/net/wireless/rdev-ops.h index eb5f8974e148..6e5fa659068d 100644 --- a/net/wireless/rdev-ops.h +++ b/net/wireless/rdev-ops.h | |||
@@ -476,21 +476,22 @@ rdev_set_wiphy_params(struct cfg80211_registered_device *rdev, u32 changed) | |||
476 | } | 476 | } |
477 | 477 | ||
478 | static inline int rdev_set_tx_power(struct cfg80211_registered_device *rdev, | 478 | static inline int rdev_set_tx_power(struct cfg80211_registered_device *rdev, |
479 | struct wireless_dev *wdev, | ||
479 | enum nl80211_tx_power_setting type, int mbm) | 480 | enum nl80211_tx_power_setting type, int mbm) |
480 | { | 481 | { |
481 | int ret; | 482 | int ret; |
482 | trace_rdev_set_tx_power(&rdev->wiphy, type, mbm); | 483 | trace_rdev_set_tx_power(&rdev->wiphy, wdev, type, mbm); |
483 | ret = rdev->ops->set_tx_power(&rdev->wiphy, type, mbm); | 484 | ret = rdev->ops->set_tx_power(&rdev->wiphy, wdev, type, mbm); |
484 | trace_rdev_return_int(&rdev->wiphy, ret); | 485 | trace_rdev_return_int(&rdev->wiphy, ret); |
485 | return ret; | 486 | return ret; |
486 | } | 487 | } |
487 | 488 | ||
488 | static inline int rdev_get_tx_power(struct cfg80211_registered_device *rdev, | 489 | static inline int rdev_get_tx_power(struct cfg80211_registered_device *rdev, |
489 | int *dbm) | 490 | struct wireless_dev *wdev, int *dbm) |
490 | { | 491 | { |
491 | int ret; | 492 | int ret; |
492 | trace_rdev_get_tx_power(&rdev->wiphy); | 493 | trace_rdev_get_tx_power(&rdev->wiphy, wdev); |
493 | ret = rdev->ops->get_tx_power(&rdev->wiphy, dbm); | 494 | ret = rdev->ops->get_tx_power(&rdev->wiphy, wdev, dbm); |
494 | trace_rdev_return_int_int(&rdev->wiphy, ret, *dbm); | 495 | trace_rdev_return_int_int(&rdev->wiphy, ret, *dbm); |
495 | return ret; | 496 | return ret; |
496 | } | 497 | } |
diff --git a/net/wireless/trace.h b/net/wireless/trace.h index 0ca71caf85fb..8e03c6382a8a 100644 --- a/net/wireless/trace.h +++ b/net/wireless/trace.h | |||
@@ -26,7 +26,7 @@ | |||
26 | #define WIPHY_PR_ARG MAC_PR_ARG(wiphy_mac) | 26 | #define WIPHY_PR_ARG MAC_PR_ARG(wiphy_mac) |
27 | 27 | ||
28 | #define WDEV_ENTRY __field(u32, id) | 28 | #define WDEV_ENTRY __field(u32, id) |
29 | #define WDEV_ASSIGN (__entry->id) = (wdev->identifier) | 29 | #define WDEV_ASSIGN (__entry->id) = (wdev ? wdev->identifier : 0) |
30 | #define WDEV_PR_FMT ", wdev id: %u" | 30 | #define WDEV_PR_FMT ", wdev id: %u" |
31 | #define WDEV_PR_ARG (__entry->id) | 31 | #define WDEV_PR_ARG (__entry->id) |
32 | 32 | ||
@@ -260,11 +260,6 @@ DEFINE_EVENT(wiphy_only_evt, rdev_get_antenna, | |||
260 | TP_ARGS(wiphy) | 260 | TP_ARGS(wiphy) |
261 | ); | 261 | ); |
262 | 262 | ||
263 | DEFINE_EVENT(wiphy_only_evt, rdev_get_tx_power, | ||
264 | TP_PROTO(struct wiphy *wiphy), | ||
265 | TP_ARGS(wiphy) | ||
266 | ); | ||
267 | |||
268 | DEFINE_EVENT(wiphy_only_evt, rdev_rfkill_poll, | 263 | DEFINE_EVENT(wiphy_only_evt, rdev_rfkill_poll, |
269 | TP_PROTO(struct wiphy *wiphy), | 264 | TP_PROTO(struct wiphy *wiphy), |
270 | TP_ARGS(wiphy) | 265 | TP_ARGS(wiphy) |
@@ -1230,22 +1225,29 @@ TRACE_EVENT(rdev_set_wiphy_params, | |||
1230 | WIPHY_PR_ARG, __entry->changed) | 1225 | WIPHY_PR_ARG, __entry->changed) |
1231 | ); | 1226 | ); |
1232 | 1227 | ||
1228 | DEFINE_EVENT(wiphy_wdev_evt, rdev_get_tx_power, | ||
1229 | TP_PROTO(struct wiphy *wiphy, struct wireless_dev *wdev), | ||
1230 | TP_ARGS(wiphy, wdev) | ||
1231 | ); | ||
1232 | |||
1233 | TRACE_EVENT(rdev_set_tx_power, | 1233 | TRACE_EVENT(rdev_set_tx_power, |
1234 | TP_PROTO(struct wiphy *wiphy, enum nl80211_tx_power_setting type, | 1234 | TP_PROTO(struct wiphy *wiphy, struct wireless_dev *wdev, |
1235 | int mbm), | 1235 | enum nl80211_tx_power_setting type, int mbm), |
1236 | TP_ARGS(wiphy, type, mbm), | 1236 | TP_ARGS(wiphy, wdev, type, mbm), |
1237 | TP_STRUCT__entry( | 1237 | TP_STRUCT__entry( |
1238 | WIPHY_ENTRY | 1238 | WIPHY_ENTRY |
1239 | WDEV_ENTRY | ||
1239 | __field(enum nl80211_tx_power_setting, type) | 1240 | __field(enum nl80211_tx_power_setting, type) |
1240 | __field(int, mbm) | 1241 | __field(int, mbm) |
1241 | ), | 1242 | ), |
1242 | TP_fast_assign( | 1243 | TP_fast_assign( |
1243 | WIPHY_ASSIGN; | 1244 | WIPHY_ASSIGN; |
1245 | WDEV_ASSIGN; | ||
1244 | __entry->type = type; | 1246 | __entry->type = type; |
1245 | __entry->mbm = mbm; | 1247 | __entry->mbm = mbm; |
1246 | ), | 1248 | ), |
1247 | TP_printk(WIPHY_PR_FMT ", type: %d, mbm: %d", | 1249 | TP_printk(WIPHY_PR_FMT WDEV_PR_FMT ", type: %d, mbm: %d", |
1248 | WIPHY_PR_ARG, __entry->type, __entry->mbm) | 1250 | WIPHY_PR_ARG, WDEV_PR_ARG,__entry->type, __entry->mbm) |
1249 | ); | 1251 | ); |
1250 | 1252 | ||
1251 | TRACE_EVENT(rdev_return_int_int, | 1253 | TRACE_EVENT(rdev_return_int_int, |
diff --git a/net/wireless/wext-compat.c b/net/wireless/wext-compat.c index 6488d2dbc1d7..742ab6ec4c9d 100644 --- a/net/wireless/wext-compat.c +++ b/net/wireless/wext-compat.c | |||
@@ -895,7 +895,7 @@ static int cfg80211_wext_siwtxpower(struct net_device *dev, | |||
895 | return 0; | 895 | return 0; |
896 | } | 896 | } |
897 | 897 | ||
898 | return rdev_set_tx_power(rdev, type, DBM_TO_MBM(dbm)); | 898 | return rdev_set_tx_power(rdev, wdev, type, DBM_TO_MBM(dbm)); |
899 | } | 899 | } |
900 | 900 | ||
901 | static int cfg80211_wext_giwtxpower(struct net_device *dev, | 901 | static int cfg80211_wext_giwtxpower(struct net_device *dev, |
@@ -914,7 +914,7 @@ static int cfg80211_wext_giwtxpower(struct net_device *dev, | |||
914 | if (!rdev->ops->get_tx_power) | 914 | if (!rdev->ops->get_tx_power) |
915 | return -EOPNOTSUPP; | 915 | return -EOPNOTSUPP; |
916 | 916 | ||
917 | err = rdev_get_tx_power(rdev, &val); | 917 | err = rdev_get_tx_power(rdev, wdev, &val); |
918 | if (err) | 918 | if (err) |
919 | return err; | 919 | return err; |
920 | 920 | ||