|
@@ -1876,8 +1876,9 @@ static int nl80211_addset_beacon(struct sk_buff *skb, struct genl_info *info)
|
|
|
struct beacon_parameters *info);
|
|
|
struct cfg80211_registered_device *rdev = info->user_ptr[0];
|
|
|
struct net_device *dev = info->user_ptr[1];
|
|
|
+ struct wireless_dev *wdev = dev->ieee80211_ptr;
|
|
|
struct beacon_parameters params;
|
|
|
- int haveinfo = 0;
|
|
|
+ int haveinfo = 0, err;
|
|
|
|
|
|
if (!is_valid_ie_attr(info->attrs[NL80211_ATTR_BEACON_TAIL]))
|
|
|
return -EINVAL;
|
|
@@ -1886,6 +1887,8 @@ static int nl80211_addset_beacon(struct sk_buff *skb, struct genl_info *info)
|
|
|
dev->ieee80211_ptr->iftype != NL80211_IFTYPE_P2P_GO)
|
|
|
return -EOPNOTSUPP;
|
|
|
|
|
|
+ memset(¶ms, 0, sizeof(params));
|
|
|
+
|
|
|
switch (info->genlhdr->cmd) {
|
|
|
case NL80211_CMD_NEW_BEACON:
|
|
|
/* these are required for NEW_BEACON */
|
|
@@ -1894,6 +1897,15 @@ static int nl80211_addset_beacon(struct sk_buff *skb, struct genl_info *info)
|
|
|
!info->attrs[NL80211_ATTR_BEACON_HEAD])
|
|
|
return -EINVAL;
|
|
|
|
|
|
+ params.interval =
|
|
|
+ nla_get_u32(info->attrs[NL80211_ATTR_BEACON_INTERVAL]);
|
|
|
+ params.dtim_period =
|
|
|
+ nla_get_u32(info->attrs[NL80211_ATTR_DTIM_PERIOD]);
|
|
|
+
|
|
|
+ err = cfg80211_validate_beacon_int(rdev, params.interval);
|
|
|
+ if (err)
|
|
|
+ return err;
|
|
|
+
|
|
|
call = rdev->ops->add_beacon;
|
|
|
break;
|
|
|
case NL80211_CMD_SET_BEACON:
|
|
@@ -1907,20 +1919,6 @@ static int nl80211_addset_beacon(struct sk_buff *skb, struct genl_info *info)
|
|
|
if (!call)
|
|
|
return -EOPNOTSUPP;
|
|
|
|
|
|
- memset(¶ms, 0, sizeof(params));
|
|
|
-
|
|
|
- if (info->attrs[NL80211_ATTR_BEACON_INTERVAL]) {
|
|
|
- params.interval =
|
|
|
- nla_get_u32(info->attrs[NL80211_ATTR_BEACON_INTERVAL]);
|
|
|
- haveinfo = 1;
|
|
|
- }
|
|
|
-
|
|
|
- if (info->attrs[NL80211_ATTR_DTIM_PERIOD]) {
|
|
|
- params.dtim_period =
|
|
|
- nla_get_u32(info->attrs[NL80211_ATTR_DTIM_PERIOD]);
|
|
|
- haveinfo = 1;
|
|
|
- }
|
|
|
-
|
|
|
if (info->attrs[NL80211_ATTR_BEACON_HEAD]) {
|
|
|
params.head = nla_data(info->attrs[NL80211_ATTR_BEACON_HEAD]);
|
|
|
params.head_len =
|
|
@@ -1938,13 +1936,18 @@ static int nl80211_addset_beacon(struct sk_buff *skb, struct genl_info *info)
|
|
|
if (!haveinfo)
|
|
|
return -EINVAL;
|
|
|
|
|
|
- return call(&rdev->wiphy, dev, ¶ms);
|
|
|
+ err = call(&rdev->wiphy, dev, ¶ms);
|
|
|
+ if (!err && params.interval)
|
|
|
+ wdev->beacon_interval = params.interval;
|
|
|
+ return err;
|
|
|
}
|
|
|
|
|
|
static int nl80211_del_beacon(struct sk_buff *skb, struct genl_info *info)
|
|
|
{
|
|
|
struct cfg80211_registered_device *rdev = info->user_ptr[0];
|
|
|
struct net_device *dev = info->user_ptr[1];
|
|
|
+ struct wireless_dev *wdev = dev->ieee80211_ptr;
|
|
|
+ int err;
|
|
|
|
|
|
if (!rdev->ops->del_beacon)
|
|
|
return -EOPNOTSUPP;
|
|
@@ -1953,7 +1956,10 @@ static int nl80211_del_beacon(struct sk_buff *skb, struct genl_info *info)
|
|
|
dev->ieee80211_ptr->iftype != NL80211_IFTYPE_P2P_GO)
|
|
|
return -EOPNOTSUPP;
|
|
|
|
|
|
- return rdev->ops->del_beacon(&rdev->wiphy, dev);
|
|
|
+ err = rdev->ops->del_beacon(&rdev->wiphy, dev);
|
|
|
+ if (!err)
|
|
|
+ wdev->beacon_interval = 0;
|
|
|
+ return err;
|
|
|
}
|
|
|
|
|
|
static const struct nla_policy sta_flags_policy[NL80211_STA_FLAG_MAX + 1] = {
|