summaryrefslogtreecommitdiff
path: root/net/wireless/nl80211.c
diff options
context:
space:
mode:
authorVarun Wadekar <vwadekar@nvidia.com>2012-04-06 19:24:48 +0530
committerVarun Wadekar <vwadekar@nvidia.com>2012-04-07 01:53:40 +0530
commit72e0b69da32430ad7a26fcb9db45b2551e51f732 (patch)
tree9c4f84dfe4e27cb8434646188ae3f160d7ba506b /net/wireless/nl80211.c
parent97caf63d0c837f9b5c9f6f469979e68c0378e83f (diff)
Revert "cfg80211: restructure AP/GO mode API"
This reverts commit 8860020e0be1f03d83dc9e9e93e18a4ddbe01038. Conflicts: drivers/net/wireless/ath/ath6kl/cfg80211.c include/linux/nl80211.h include/net/cfg80211.h net/wireless/nl80211.c Change-Id: I4b495d6af3a9c47256aa6e984830dc413ca6631b Signed-off-by: Varun Wadekar <vwadekar@nvidia.com>
Diffstat (limited to 'net/wireless/nl80211.c')
-rw-r--r--net/wireless/nl80211.c262
1 files changed, 113 insertions, 149 deletions
diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c
index 4c1eb9472ddb..2f34e2c595af 100644
--- a/net/wireless/nl80211.c
+++ b/net/wireless/nl80211.c
@@ -873,7 +873,7 @@ static int nl80211_send_wiphy(struct sk_buff *msg, u32 pid, u32 seq, int flags,
CMD(add_virtual_intf, NEW_INTERFACE);
CMD(change_virtual_intf, SET_INTERFACE);
CMD(add_key, NEW_KEY);
- CMD(start_ap, START_AP);
+ CMD(add_beacon, NEW_BEACON);
CMD(add_station, NEW_STATION);
CMD(add_mpath, NEW_MPATH);
CMD(update_mesh_config, SET_MESH_CONFIG);
@@ -2077,10 +2077,15 @@ static int nl80211_del_key(struct sk_buff *skb, struct genl_info *info)
return err;
}
-static int nl80211_parse_beacon(struct genl_info *info,
- struct cfg80211_beacon_data *bcn)
+static int nl80211_addset_beacon(struct sk_buff *skb, struct genl_info *info)
{
- bool haveinfo = false;
+ int (*call)(struct wiphy *wiphy, struct net_device *dev,
+ 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, err;
if (!is_valid_ie_attr(info->attrs[NL80211_ATTR_BEACON_TAIL]) ||
!is_valid_ie_attr(info->attrs[NL80211_ATTR_IE]) ||
@@ -2088,190 +2093,149 @@ static int nl80211_parse_beacon(struct genl_info *info,
!is_valid_ie_attr(info->attrs[NL80211_ATTR_IE_ASSOC_RESP]))
return -EINVAL;
- memset(bcn, 0, sizeof(*bcn));
+ if (dev->ieee80211_ptr->iftype != NL80211_IFTYPE_AP &&
+ dev->ieee80211_ptr->iftype != NL80211_IFTYPE_P2P_GO)
+ return -EOPNOTSUPP;
- if (info->attrs[NL80211_ATTR_BEACON_HEAD]) {
- bcn->head = nla_data(info->attrs[NL80211_ATTR_BEACON_HEAD]);
- bcn->head_len = nla_len(info->attrs[NL80211_ATTR_BEACON_HEAD]);
- if (!bcn->head_len)
+ memset(&params, 0, sizeof(params));
+
+ switch (info->genlhdr->cmd) {
+ case NL80211_CMD_NEW_BEACON:
+ /* these are required for NEW_BEACON */
+ if (!info->attrs[NL80211_ATTR_BEACON_INTERVAL] ||
+ !info->attrs[NL80211_ATTR_DTIM_PERIOD] ||
+ !info->attrs[NL80211_ATTR_BEACON_HEAD])
return -EINVAL;
- haveinfo = true;
+
+ 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;
+
+ /*
+ * In theory, some of these attributes could be required for
+ * NEW_BEACON, but since they were not used when the command was
+ * originally added, keep them optional for old user space
+ * programs to work with drivers that do not need the additional
+ * information.
+ */
+ if (info->attrs[NL80211_ATTR_SSID]) {
+ params.ssid = nla_data(info->attrs[NL80211_ATTR_SSID]);
+ params.ssid_len =
+ nla_len(info->attrs[NL80211_ATTR_SSID]);
+ if (params.ssid_len == 0 ||
+ params.ssid_len > IEEE80211_MAX_SSID_LEN)
+ return -EINVAL;
+ }
+
+ if (info->attrs[NL80211_ATTR_HIDDEN_SSID]) {
+ params.hidden_ssid = nla_get_u32(
+ info->attrs[NL80211_ATTR_HIDDEN_SSID]);
+ if (params.hidden_ssid !=
+ NL80211_HIDDEN_SSID_NOT_IN_USE &&
+ params.hidden_ssid !=
+ NL80211_HIDDEN_SSID_ZERO_LEN &&
+ params.hidden_ssid !=
+ NL80211_HIDDEN_SSID_ZERO_CONTENTS)
+ return -EINVAL;
+ }
+
+ params.privacy = !!info->attrs[NL80211_ATTR_PRIVACY];
+
+ if (info->attrs[NL80211_ATTR_AUTH_TYPE]) {
+ params.auth_type = nla_get_u32(
+ info->attrs[NL80211_ATTR_AUTH_TYPE]);
+ if (!nl80211_valid_auth_type(params.auth_type))
+ return -EINVAL;
+ } else
+ params.auth_type = NL80211_AUTHTYPE_AUTOMATIC;
+
+ err = nl80211_crypto_settings(rdev, info, &params.crypto,
+ NL80211_MAX_NR_CIPHER_SUITES);
+ if (err)
+ return err;
+
+ call = rdev->ops->add_beacon;
+ break;
+ case NL80211_CMD_SET_BEACON:
+ call = rdev->ops->set_beacon;
+ break;
+ default:
+ WARN_ON(1);
+ return -EOPNOTSUPP;
+ }
+
+ if (!call)
+ return -EOPNOTSUPP;
+
+ if (info->attrs[NL80211_ATTR_BEACON_HEAD]) {
+ params.head = nla_data(info->attrs[NL80211_ATTR_BEACON_HEAD]);
+ params.head_len =
+ nla_len(info->attrs[NL80211_ATTR_BEACON_HEAD]);
+ haveinfo = 1;
}
if (info->attrs[NL80211_ATTR_BEACON_TAIL]) {
- bcn->tail = nla_data(info->attrs[NL80211_ATTR_BEACON_TAIL]);
- bcn->tail_len =
+ params.tail = nla_data(info->attrs[NL80211_ATTR_BEACON_TAIL]);
+ params.tail_len =
nla_len(info->attrs[NL80211_ATTR_BEACON_TAIL]);
- haveinfo = true;
+ haveinfo = 1;
}
if (!haveinfo)
return -EINVAL;
if (info->attrs[NL80211_ATTR_IE]) {
- bcn->beacon_ies = nla_data(info->attrs[NL80211_ATTR_IE]);
- bcn->beacon_ies_len = nla_len(info->attrs[NL80211_ATTR_IE]);
+ params.beacon_ies = nla_data(info->attrs[NL80211_ATTR_IE]);
+ params.beacon_ies_len = nla_len(info->attrs[NL80211_ATTR_IE]);
}
if (info->attrs[NL80211_ATTR_IE_PROBE_RESP]) {
- bcn->proberesp_ies =
+ params.proberesp_ies =
nla_data(info->attrs[NL80211_ATTR_IE_PROBE_RESP]);
- bcn->proberesp_ies_len =
+ params.proberesp_ies_len =
nla_len(info->attrs[NL80211_ATTR_IE_PROBE_RESP]);
}
if (info->attrs[NL80211_ATTR_IE_ASSOC_RESP]) {
- bcn->assocresp_ies =
+ params.assocresp_ies =
nla_data(info->attrs[NL80211_ATTR_IE_ASSOC_RESP]);
- bcn->assocresp_ies_len =
+ params.assocresp_ies_len =
nla_len(info->attrs[NL80211_ATTR_IE_ASSOC_RESP]);
}
if (info->attrs[NL80211_ATTR_PROBE_RESP]) {
- bcn->probe_resp =
+ params.probe_resp =
nla_data(info->attrs[NL80211_ATTR_PROBE_RESP]);
- bcn->probe_resp_len =
+ params.probe_resp_len =
nla_len(info->attrs[NL80211_ATTR_PROBE_RESP]);
}
- return 0;
-}
-
-static int nl80211_start_ap(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;
- struct cfg80211_ap_settings params;
- int err;
-
- if (dev->ieee80211_ptr->iftype != NL80211_IFTYPE_AP &&
- dev->ieee80211_ptr->iftype != NL80211_IFTYPE_P2P_GO)
- return -EOPNOTSUPP;
-
- if (!rdev->ops->start_ap)
- return -EOPNOTSUPP;
-
- if (wdev->beacon_interval)
- return -EALREADY;
-
- memset(&params, 0, sizeof(params));
-
- /* these are required for START_AP */
- if (!info->attrs[NL80211_ATTR_BEACON_INTERVAL] ||
- !info->attrs[NL80211_ATTR_DTIM_PERIOD] ||
- !info->attrs[NL80211_ATTR_BEACON_HEAD])
- return -EINVAL;
-
- err = nl80211_parse_beacon(info, &params.beacon);
- if (err)
- return err;
-
- params.beacon_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.beacon_interval);
- if (err)
- return err;
-
- /*
- * In theory, some of these attributes should be required here
- * but since they were not used when the command was originally
- * added, keep them optional for old user space programs to let
- * them continue to work with drivers that do not need the
- * additional information -- drivers must check!
- */
- if (info->attrs[NL80211_ATTR_SSID]) {
- params.ssid = nla_data(info->attrs[NL80211_ATTR_SSID]);
- params.ssid_len =
- nla_len(info->attrs[NL80211_ATTR_SSID]);
- if (params.ssid_len == 0 ||
- params.ssid_len > IEEE80211_MAX_SSID_LEN)
- return -EINVAL;
- }
-
- if (info->attrs[NL80211_ATTR_HIDDEN_SSID]) {
- params.hidden_ssid = nla_get_u32(
- info->attrs[NL80211_ATTR_HIDDEN_SSID]);
- if (params.hidden_ssid != NL80211_HIDDEN_SSID_NOT_IN_USE &&
- params.hidden_ssid != NL80211_HIDDEN_SSID_ZERO_LEN &&
- params.hidden_ssid != NL80211_HIDDEN_SSID_ZERO_CONTENTS)
- return -EINVAL;
- }
-
- params.privacy = !!info->attrs[NL80211_ATTR_PRIVACY];
-
- if (info->attrs[NL80211_ATTR_AUTH_TYPE]) {
- params.auth_type = nla_get_u32(
- info->attrs[NL80211_ATTR_AUTH_TYPE]);
- if (!nl80211_valid_auth_type(params.auth_type))
- return -EINVAL;
- } else
- params.auth_type = NL80211_AUTHTYPE_AUTOMATIC;
-
- err = nl80211_crypto_settings(rdev, info, &params.crypto,
- NL80211_MAX_NR_CIPHER_SUITES);
- if (err)
- return err;
-
- if (info->attrs[NL80211_ATTR_INACTIVITY_TIMEOUT]) {
- if (!(rdev->wiphy.features & NL80211_FEATURE_INACTIVITY_TIMER))
- return -EOPNOTSUPP;
- params.inactivity_timeout = nla_get_u16(
- info->attrs[NL80211_ATTR_INACTIVITY_TIMEOUT]);
- }
-
- err = rdev->ops->start_ap(&rdev->wiphy, dev, &params);
- if (!err)
- wdev->beacon_interval = params.beacon_interval;
+ err = call(&rdev->wiphy, dev, &params);
+ if (!err && params.interval)
+ wdev->beacon_interval = params.interval;
return err;
}
-static int nl80211_set_beacon(struct sk_buff *skb, struct genl_info *info)
+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;
- struct cfg80211_beacon_data params;
int err;
- if (dev->ieee80211_ptr->iftype != NL80211_IFTYPE_AP &&
- dev->ieee80211_ptr->iftype != NL80211_IFTYPE_P2P_GO)
- return -EOPNOTSUPP;
-
- if (!rdev->ops->change_beacon)
- return -EOPNOTSUPP;
-
- if (!wdev->beacon_interval)
- return -EINVAL;
-
- err = nl80211_parse_beacon(info, &params);
- if (err)
- return err;
-
- return rdev->ops->change_beacon(&rdev->wiphy, dev, &params);
-}
-
-static int nl80211_stop_ap(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->stop_ap)
+ if (!rdev->ops->del_beacon)
return -EOPNOTSUPP;
if (dev->ieee80211_ptr->iftype != NL80211_IFTYPE_AP &&
dev->ieee80211_ptr->iftype != NL80211_IFTYPE_P2P_GO)
return -EOPNOTSUPP;
- if (!wdev->beacon_interval)
- return -ENOENT;
-
- err = rdev->ops->stop_ap(&rdev->wiphy, dev);
+ err = rdev->ops->del_beacon(&rdev->wiphy, dev);
if (!err)
wdev->beacon_interval = 0;
return err;
@@ -6407,23 +6371,23 @@ static struct genl_ops nl80211_ops[] = {
.cmd = NL80211_CMD_SET_BEACON,
.policy = nl80211_policy,
.flags = GENL_ADMIN_PERM,
- .doit = nl80211_set_beacon,
+ .doit = nl80211_addset_beacon,
.internal_flags = NL80211_FLAG_NEED_NETDEV |
NL80211_FLAG_NEED_RTNL,
},
{
- .cmd = NL80211_CMD_START_AP,
+ .cmd = NL80211_CMD_NEW_BEACON,
.policy = nl80211_policy,
.flags = GENL_ADMIN_PERM,
- .doit = nl80211_start_ap,
+ .doit = nl80211_addset_beacon,
.internal_flags = NL80211_FLAG_NEED_NETDEV |
NL80211_FLAG_NEED_RTNL,
},
{
- .cmd = NL80211_CMD_STOP_AP,
+ .cmd = NL80211_CMD_DEL_BEACON,
.policy = nl80211_policy,
.flags = GENL_ADMIN_PERM,
- .doit = nl80211_stop_ap,
+ .doit = nl80211_del_beacon,
.internal_flags = NL80211_FLAG_NEED_NETDEV |
NL80211_FLAG_NEED_RTNL,
},