diff options
| author | Ayala Beker <ayala.beker@intel.com> | 2016-09-20 10:31:16 -0400 |
|---|---|---|
| committer | Johannes Berg <johannes.berg@intel.com> | 2016-09-30 07:21:28 -0400 |
| commit | a5a9dcf291e1e541243878eed2d73a74006fa1f1 (patch) | |
| tree | 74662fbcd9476c6fc296d16247c281a310614463 /net/wireless | |
| parent | a442b761b24b6886f9a4e2ff5f8cb4824c96526b (diff) | |
cfg80211: allow the user space to change current NAN configuration
Some NAN configuration paramaters may change during the operation of
the NAN device. For example, a user may want to update master preference
value when the device gets plugged/unplugged to the power.
Add API that allows to do so.
Signed-off-by: Andrei Otcheretianski <andrei.otcheretianski@intel.com>
Signed-off-by: Emmanuel Grumbach <emmanuel.grumbach@intel.com>
Signed-off-by: Luca Coelho <luciano.coelho@intel.com>
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
Diffstat (limited to 'net/wireless')
| -rw-r--r-- | net/wireless/nl80211.c | 42 | ||||
| -rw-r--r-- | net/wireless/rdev-ops.h | 17 | ||||
| -rw-r--r-- | net/wireless/trace.h | 24 |
3 files changed, 83 insertions, 0 deletions
diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c index 0eca59ccd685..c0b5ae4af2d8 100644 --- a/net/wireless/nl80211.c +++ b/net/wireless/nl80211.c | |||
| @@ -10919,6 +10919,40 @@ static int nl80211_nan_del_func(struct sk_buff *skb, | |||
| 10919 | return 0; | 10919 | return 0; |
| 10920 | } | 10920 | } |
| 10921 | 10921 | ||
| 10922 | static int nl80211_nan_change_config(struct sk_buff *skb, | ||
| 10923 | struct genl_info *info) | ||
| 10924 | { | ||
| 10925 | struct cfg80211_registered_device *rdev = info->user_ptr[0]; | ||
| 10926 | struct wireless_dev *wdev = info->user_ptr[1]; | ||
| 10927 | struct cfg80211_nan_conf conf = {}; | ||
| 10928 | u32 changed = 0; | ||
| 10929 | |||
| 10930 | if (wdev->iftype != NL80211_IFTYPE_NAN) | ||
| 10931 | return -EOPNOTSUPP; | ||
| 10932 | |||
| 10933 | if (!wdev->nan_started) | ||
| 10934 | return -ENOTCONN; | ||
| 10935 | |||
| 10936 | if (info->attrs[NL80211_ATTR_NAN_MASTER_PREF]) { | ||
| 10937 | conf.master_pref = | ||
| 10938 | nla_get_u8(info->attrs[NL80211_ATTR_NAN_MASTER_PREF]); | ||
| 10939 | if (conf.master_pref <= 1 || conf.master_pref == 255) | ||
| 10940 | return -EINVAL; | ||
| 10941 | |||
| 10942 | changed |= CFG80211_NAN_CONF_CHANGED_PREF; | ||
| 10943 | } | ||
| 10944 | |||
| 10945 | if (info->attrs[NL80211_ATTR_NAN_DUAL]) { | ||
| 10946 | conf.dual = nla_get_u8(info->attrs[NL80211_ATTR_NAN_DUAL]); | ||
| 10947 | changed |= CFG80211_NAN_CONF_CHANGED_DUAL; | ||
| 10948 | } | ||
| 10949 | |||
| 10950 | if (!changed) | ||
| 10951 | return -EINVAL; | ||
| 10952 | |||
| 10953 | return rdev_nan_change_conf(rdev, wdev, &conf, changed); | ||
| 10954 | } | ||
| 10955 | |||
| 10922 | static int nl80211_get_protocol_features(struct sk_buff *skb, | 10956 | static int nl80211_get_protocol_features(struct sk_buff *skb, |
| 10923 | struct genl_info *info) | 10957 | struct genl_info *info) |
| 10924 | { | 10958 | { |
| @@ -12293,6 +12327,14 @@ static const struct genl_ops nl80211_ops[] = { | |||
| 12293 | NL80211_FLAG_NEED_RTNL, | 12327 | NL80211_FLAG_NEED_RTNL, |
| 12294 | }, | 12328 | }, |
| 12295 | { | 12329 | { |
| 12330 | .cmd = NL80211_CMD_CHANGE_NAN_CONFIG, | ||
| 12331 | .doit = nl80211_nan_change_config, | ||
| 12332 | .policy = nl80211_policy, | ||
| 12333 | .flags = GENL_ADMIN_PERM, | ||
| 12334 | .internal_flags = NL80211_FLAG_NEED_WDEV_UP | | ||
| 12335 | NL80211_FLAG_NEED_RTNL, | ||
| 12336 | }, | ||
| 12337 | { | ||
| 12296 | .cmd = NL80211_CMD_SET_MCAST_RATE, | 12338 | .cmd = NL80211_CMD_SET_MCAST_RATE, |
| 12297 | .doit = nl80211_set_mcast_rate, | 12339 | .doit = nl80211_set_mcast_rate, |
| 12298 | .policy = nl80211_policy, | 12340 | .policy = nl80211_policy, |
diff --git a/net/wireless/rdev-ops.h b/net/wireless/rdev-ops.h index 98c4c3bdcb11..11cf83c8ad4f 100644 --- a/net/wireless/rdev-ops.h +++ b/net/wireless/rdev-ops.h | |||
| @@ -928,6 +928,23 @@ static inline void rdev_del_nan_func(struct cfg80211_registered_device *rdev, | |||
| 928 | trace_rdev_return_void(&rdev->wiphy); | 928 | trace_rdev_return_void(&rdev->wiphy); |
| 929 | } | 929 | } |
| 930 | 930 | ||
| 931 | static inline int | ||
| 932 | rdev_nan_change_conf(struct cfg80211_registered_device *rdev, | ||
| 933 | struct wireless_dev *wdev, | ||
| 934 | struct cfg80211_nan_conf *conf, u32 changes) | ||
| 935 | { | ||
| 936 | int ret; | ||
| 937 | |||
| 938 | trace_rdev_nan_change_conf(&rdev->wiphy, wdev, conf, changes); | ||
| 939 | if (rdev->ops->nan_change_conf) | ||
| 940 | ret = rdev->ops->nan_change_conf(&rdev->wiphy, wdev, conf, | ||
| 941 | changes); | ||
| 942 | else | ||
| 943 | ret = -ENOTSUPP; | ||
| 944 | trace_rdev_return_int(&rdev->wiphy, ret); | ||
| 945 | return ret; | ||
| 946 | } | ||
| 947 | |||
| 931 | static inline int rdev_set_mac_acl(struct cfg80211_registered_device *rdev, | 948 | static inline int rdev_set_mac_acl(struct cfg80211_registered_device *rdev, |
| 932 | struct net_device *dev, | 949 | struct net_device *dev, |
| 933 | struct cfg80211_acl_data *params) | 950 | struct cfg80211_acl_data *params) |
diff --git a/net/wireless/trace.h b/net/wireless/trace.h index 56089843d619..a3d0a91b1e09 100644 --- a/net/wireless/trace.h +++ b/net/wireless/trace.h | |||
| @@ -1911,6 +1911,30 @@ TRACE_EVENT(rdev_start_nan, | |||
| 1911 | __entry->dual) | 1911 | __entry->dual) |
| 1912 | ); | 1912 | ); |
| 1913 | 1913 | ||
| 1914 | TRACE_EVENT(rdev_nan_change_conf, | ||
| 1915 | TP_PROTO(struct wiphy *wiphy, struct wireless_dev *wdev, | ||
| 1916 | struct cfg80211_nan_conf *conf, u32 changes), | ||
| 1917 | TP_ARGS(wiphy, wdev, conf, changes), | ||
| 1918 | TP_STRUCT__entry( | ||
| 1919 | WIPHY_ENTRY | ||
| 1920 | WDEV_ENTRY | ||
| 1921 | __field(u8, master_pref) | ||
| 1922 | __field(u8, dual); | ||
| 1923 | __field(u32, changes); | ||
| 1924 | ), | ||
| 1925 | TP_fast_assign( | ||
| 1926 | WIPHY_ASSIGN; | ||
| 1927 | WDEV_ASSIGN; | ||
| 1928 | __entry->master_pref = conf->master_pref; | ||
| 1929 | __entry->dual = conf->dual; | ||
| 1930 | __entry->changes = changes; | ||
| 1931 | ), | ||
| 1932 | TP_printk(WIPHY_PR_FMT ", " WDEV_PR_FMT | ||
| 1933 | ", master preference: %u, dual: %d, changes: %x", | ||
| 1934 | WIPHY_PR_ARG, WDEV_PR_ARG, __entry->master_pref, | ||
| 1935 | __entry->dual, __entry->changes) | ||
| 1936 | ); | ||
| 1937 | |||
| 1914 | DEFINE_EVENT(wiphy_wdev_evt, rdev_stop_nan, | 1938 | DEFINE_EVENT(wiphy_wdev_evt, rdev_stop_nan, |
| 1915 | TP_PROTO(struct wiphy *wiphy, struct wireless_dev *wdev), | 1939 | TP_PROTO(struct wiphy *wiphy, struct wireless_dev *wdev), |
| 1916 | TP_ARGS(wiphy, wdev) | 1940 | TP_ARGS(wiphy, wdev) |
