diff options
author | Varun Wadekar <vwadekar@nvidia.com> | 2012-04-06 19:24:48 +0530 |
---|---|---|
committer | Varun Wadekar <vwadekar@nvidia.com> | 2012-04-07 01:53:40 +0530 |
commit | 72e0b69da32430ad7a26fcb9db45b2551e51f732 (patch) | |
tree | 9c4f84dfe4e27cb8434646188ae3f160d7ba506b /net/wireless/nl80211.c | |
parent | 97caf63d0c837f9b5c9f6f469979e68c0378e83f (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.c | 262 |
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(¶ms, 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, ¶ms.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(¶ms, 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, ¶ms.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, ¶ms.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, ¶ms); - if (!err) - wdev->beacon_interval = params.beacon_interval; + err = call(&rdev->wiphy, dev, ¶ms); + 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, ¶ms); - if (err) - return err; - - return rdev->ops->change_beacon(&rdev->wiphy, dev, ¶ms); -} - -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, }, |