aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--include/net/cfg80211.h4
-rw-r--r--net/wireless/core.c1
-rw-r--r--net/wireless/core.h3
-rw-r--r--net/wireless/nl80211.c40
-rw-r--r--net/wireless/util.c25
5 files changed, 56 insertions, 17 deletions
diff --git a/include/net/cfg80211.h b/include/net/cfg80211.h
index 1f1e221b6ce3..a46adb7a91b7 100644
--- a/include/net/cfg80211.h
+++ b/include/net/cfg80211.h
@@ -1908,6 +1908,8 @@ struct cfg80211_cached_keys;
1908 * @mgmt_registrations_lock: lock for the list 1908 * @mgmt_registrations_lock: lock for the list
1909 * @mtx: mutex used to lock data in this struct 1909 * @mtx: mutex used to lock data in this struct
1910 * @cleanup_work: work struct used for cleanup that can't be done directly 1910 * @cleanup_work: work struct used for cleanup that can't be done directly
1911 * @beacon_interval: beacon interval used on this device for transmitting
1912 * beacons, 0 when not valid
1911 */ 1913 */
1912struct wireless_dev { 1914struct wireless_dev {
1913 struct wiphy *wiphy; 1915 struct wiphy *wiphy;
@@ -1948,6 +1950,8 @@ struct wireless_dev {
1948 bool ps; 1950 bool ps;
1949 int ps_timeout; 1951 int ps_timeout;
1950 1952
1953 int beacon_interval;
1954
1951#ifdef CONFIG_CFG80211_WEXT 1955#ifdef CONFIG_CFG80211_WEXT
1952 /* wext data */ 1956 /* wext data */
1953 struct { 1957 struct {
diff --git a/net/wireless/core.c b/net/wireless/core.c
index f924a49b2425..e2ab65d7c86d 100644
--- a/net/wireless/core.c
+++ b/net/wireless/core.c
@@ -787,6 +787,7 @@ static int cfg80211_netdev_notifier_call(struct notifier_block * nb,
787 default: 787 default:
788 break; 788 break;
789 } 789 }
790 wdev->beacon_interval = 0;
790 break; 791 break;
791 case NETDEV_DOWN: 792 case NETDEV_DOWN:
792 dev_hold(dev); 793 dev_hold(dev);
diff --git a/net/wireless/core.h b/net/wireless/core.h
index e3f7b1d995cd..fd9135f9b5be 100644
--- a/net/wireless/core.h
+++ b/net/wireless/core.h
@@ -433,6 +433,9 @@ int cfg80211_set_freq(struct cfg80211_registered_device *rdev,
433 433
434u16 cfg80211_calculate_bitrate(struct rate_info *rate); 434u16 cfg80211_calculate_bitrate(struct rate_info *rate);
435 435
436int cfg80211_validate_beacon_int(struct cfg80211_registered_device *rdev,
437 u32 beacon_int);
438
436#ifdef CONFIG_CFG80211_DEVELOPER_WARNINGS 439#ifdef CONFIG_CFG80211_DEVELOPER_WARNINGS
437#define CFG80211_DEV_WARN_ON(cond) WARN_ON(cond) 440#define CFG80211_DEV_WARN_ON(cond) WARN_ON(cond)
438#else 441#else
diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c
index b5b050b62f2a..9ef8e287d61b 100644
--- a/net/wireless/nl80211.c
+++ b/net/wireless/nl80211.c
@@ -1876,8 +1876,9 @@ static int nl80211_addset_beacon(struct sk_buff *skb, struct genl_info *info)
1876 struct beacon_parameters *info); 1876 struct beacon_parameters *info);
1877 struct cfg80211_registered_device *rdev = info->user_ptr[0]; 1877 struct cfg80211_registered_device *rdev = info->user_ptr[0];
1878 struct net_device *dev = info->user_ptr[1]; 1878 struct net_device *dev = info->user_ptr[1];
1879 struct wireless_dev *wdev = dev->ieee80211_ptr;
1879 struct beacon_parameters params; 1880 struct beacon_parameters params;
1880 int haveinfo = 0; 1881 int haveinfo = 0, err;
1881 1882
1882 if (!is_valid_ie_attr(info->attrs[NL80211_ATTR_BEACON_TAIL])) 1883 if (!is_valid_ie_attr(info->attrs[NL80211_ATTR_BEACON_TAIL]))
1883 return -EINVAL; 1884 return -EINVAL;
@@ -1886,6 +1887,8 @@ static int nl80211_addset_beacon(struct sk_buff *skb, struct genl_info *info)
1886 dev->ieee80211_ptr->iftype != NL80211_IFTYPE_P2P_GO) 1887 dev->ieee80211_ptr->iftype != NL80211_IFTYPE_P2P_GO)
1887 return -EOPNOTSUPP; 1888 return -EOPNOTSUPP;
1888 1889
1890 memset(&params, 0, sizeof(params));
1891
1889 switch (info->genlhdr->cmd) { 1892 switch (info->genlhdr->cmd) {
1890 case NL80211_CMD_NEW_BEACON: 1893 case NL80211_CMD_NEW_BEACON:
1891 /* these are required for NEW_BEACON */ 1894 /* these are required for NEW_BEACON */
@@ -1894,6 +1897,15 @@ static int nl80211_addset_beacon(struct sk_buff *skb, struct genl_info *info)
1894 !info->attrs[NL80211_ATTR_BEACON_HEAD]) 1897 !info->attrs[NL80211_ATTR_BEACON_HEAD])
1895 return -EINVAL; 1898 return -EINVAL;
1896 1899
1900 params.interval =
1901 nla_get_u32(info->attrs[NL80211_ATTR_BEACON_INTERVAL]);
1902 params.dtim_period =
1903 nla_get_u32(info->attrs[NL80211_ATTR_DTIM_PERIOD]);
1904
1905 err = cfg80211_validate_beacon_int(rdev, params.interval);
1906 if (err)
1907 return err;
1908
1897 call = rdev->ops->add_beacon; 1909 call = rdev->ops->add_beacon;
1898 break; 1910 break;
1899 case NL80211_CMD_SET_BEACON: 1911 case NL80211_CMD_SET_BEACON:
@@ -1907,20 +1919,6 @@ static int nl80211_addset_beacon(struct sk_buff *skb, struct genl_info *info)
1907 if (!call) 1919 if (!call)
1908 return -EOPNOTSUPP; 1920 return -EOPNOTSUPP;
1909 1921
1910 memset(&params, 0, sizeof(params));
1911
1912 if (info->attrs[NL80211_ATTR_BEACON_INTERVAL]) {
1913 params.interval =
1914 nla_get_u32(info->attrs[NL80211_ATTR_BEACON_INTERVAL]);
1915 haveinfo = 1;
1916 }
1917
1918 if (info->attrs[NL80211_ATTR_DTIM_PERIOD]) {
1919 params.dtim_period =
1920 nla_get_u32(info->attrs[NL80211_ATTR_DTIM_PERIOD]);
1921 haveinfo = 1;
1922 }
1923
1924 if (info->attrs[NL80211_ATTR_BEACON_HEAD]) { 1922 if (info->attrs[NL80211_ATTR_BEACON_HEAD]) {
1925 params.head = nla_data(info->attrs[NL80211_ATTR_BEACON_HEAD]); 1923 params.head = nla_data(info->attrs[NL80211_ATTR_BEACON_HEAD]);
1926 params.head_len = 1924 params.head_len =
@@ -1938,13 +1936,18 @@ static int nl80211_addset_beacon(struct sk_buff *skb, struct genl_info *info)
1938 if (!haveinfo) 1936 if (!haveinfo)
1939 return -EINVAL; 1937 return -EINVAL;
1940 1938
1941 return call(&rdev->wiphy, dev, &params); 1939 err = call(&rdev->wiphy, dev, &params);
1940 if (!err && params.interval)
1941 wdev->beacon_interval = params.interval;
1942 return err;
1942} 1943}
1943 1944
1944static int nl80211_del_beacon(struct sk_buff *skb, struct genl_info *info) 1945static int nl80211_del_beacon(struct sk_buff *skb, struct genl_info *info)
1945{ 1946{
1946 struct cfg80211_registered_device *rdev = info->user_ptr[0]; 1947 struct cfg80211_registered_device *rdev = info->user_ptr[0];
1947 struct net_device *dev = info->user_ptr[1]; 1948 struct net_device *dev = info->user_ptr[1];
1949 struct wireless_dev *wdev = dev->ieee80211_ptr;
1950 int err;
1948 1951
1949 if (!rdev->ops->del_beacon) 1952 if (!rdev->ops->del_beacon)
1950 return -EOPNOTSUPP; 1953 return -EOPNOTSUPP;
@@ -1953,7 +1956,10 @@ static int nl80211_del_beacon(struct sk_buff *skb, struct genl_info *info)
1953 dev->ieee80211_ptr->iftype != NL80211_IFTYPE_P2P_GO) 1956 dev->ieee80211_ptr->iftype != NL80211_IFTYPE_P2P_GO)
1954 return -EOPNOTSUPP; 1957 return -EOPNOTSUPP;
1955 1958
1956 return rdev->ops->del_beacon(&rdev->wiphy, dev); 1959 err = rdev->ops->del_beacon(&rdev->wiphy, dev);
1960 if (!err)
1961 wdev->beacon_interval = 0;
1962 return err;
1957} 1963}
1958 1964
1959static const struct nla_policy sta_flags_policy[NL80211_STA_FLAG_MAX + 1] = { 1965static const struct nla_policy sta_flags_policy[NL80211_STA_FLAG_MAX + 1] = {
diff --git a/net/wireless/util.c b/net/wireless/util.c
index 6a750bc6bcfe..414c9f604df6 100644
--- a/net/wireless/util.c
+++ b/net/wireless/util.c
@@ -896,3 +896,28 @@ u16 cfg80211_calculate_bitrate(struct rate_info *rate)
896 /* do NOT round down here */ 896 /* do NOT round down here */
897 return (bitrate + 50000) / 100000; 897 return (bitrate + 50000) / 100000;
898} 898}
899
900int cfg80211_validate_beacon_int(struct cfg80211_registered_device *rdev,
901 u32 beacon_int)
902{
903 struct wireless_dev *wdev;
904 int res = 0;
905
906 if (!beacon_int)
907 return -EINVAL;
908
909 mutex_lock(&rdev->devlist_mtx);
910
911 list_for_each_entry(wdev, &rdev->netdev_list, list) {
912 if (!wdev->beacon_interval)
913 continue;
914 if (wdev->beacon_interval != beacon_int) {
915 res = -EINVAL;
916 break;
917 }
918 }
919
920 mutex_unlock(&rdev->devlist_mtx);
921
922 return res;
923}