aboutsummaryrefslogtreecommitdiffstats
path: root/net/wireless/nl80211.c
diff options
context:
space:
mode:
authorJohn W. Linville <linville@tuxdriver.com>2012-04-12 14:25:14 -0400
committerJohn W. Linville <linville@tuxdriver.com>2012-04-12 14:41:59 -0400
commit7eab0f64a9eba5405222fdef0ede2468bf495efd (patch)
treeec99640b8d0b12adbfacb85c27683125debd14f2 /net/wireless/nl80211.c
parentcade455596504fae8e134a27189713ddf7c6d04d (diff)
parent8065248069097dddf9945acfb2081025e9618c16 (diff)
Merge branch 'master' into for-davem
Conflicts: drivers/net/wireless/iwlwifi/iwl-testmode.c net/wireless/nl80211.c
Diffstat (limited to 'net/wireless/nl80211.c')
-rw-r--r--net/wireless/nl80211.c92
1 files changed, 77 insertions, 15 deletions
diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c
index a4aab1d36285..ff1a6c7fbe33 100644
--- a/net/wireless/nl80211.c
+++ b/net/wireless/nl80211.c
@@ -1142,17 +1142,20 @@ static const struct nla_policy txq_params_policy[NL80211_TXQ_ATTR_MAX + 1] = {
1142static int parse_txq_params(struct nlattr *tb[], 1142static int parse_txq_params(struct nlattr *tb[],
1143 struct ieee80211_txq_params *txq_params) 1143 struct ieee80211_txq_params *txq_params)
1144{ 1144{
1145 if (!tb[NL80211_TXQ_ATTR_QUEUE] || !tb[NL80211_TXQ_ATTR_TXOP] || 1145 if (!tb[NL80211_TXQ_ATTR_AC] || !tb[NL80211_TXQ_ATTR_TXOP] ||
1146 !tb[NL80211_TXQ_ATTR_CWMIN] || !tb[NL80211_TXQ_ATTR_CWMAX] || 1146 !tb[NL80211_TXQ_ATTR_CWMIN] || !tb[NL80211_TXQ_ATTR_CWMAX] ||
1147 !tb[NL80211_TXQ_ATTR_AIFS]) 1147 !tb[NL80211_TXQ_ATTR_AIFS])
1148 return -EINVAL; 1148 return -EINVAL;
1149 1149
1150 txq_params->queue = nla_get_u8(tb[NL80211_TXQ_ATTR_QUEUE]); 1150 txq_params->ac = nla_get_u8(tb[NL80211_TXQ_ATTR_AC]);
1151 txq_params->txop = nla_get_u16(tb[NL80211_TXQ_ATTR_TXOP]); 1151 txq_params->txop = nla_get_u16(tb[NL80211_TXQ_ATTR_TXOP]);
1152 txq_params->cwmin = nla_get_u16(tb[NL80211_TXQ_ATTR_CWMIN]); 1152 txq_params->cwmin = nla_get_u16(tb[NL80211_TXQ_ATTR_CWMIN]);
1153 txq_params->cwmax = nla_get_u16(tb[NL80211_TXQ_ATTR_CWMAX]); 1153 txq_params->cwmax = nla_get_u16(tb[NL80211_TXQ_ATTR_CWMAX]);
1154 txq_params->aifs = nla_get_u8(tb[NL80211_TXQ_ATTR_AIFS]); 1154 txq_params->aifs = nla_get_u8(tb[NL80211_TXQ_ATTR_AIFS]);
1155 1155
1156 if (txq_params->ac >= NL80211_NUM_ACS)
1157 return -EINVAL;
1158
1156 return 0; 1159 return 0;
1157} 1160}
1158 1161
@@ -1332,6 +1335,11 @@ static int nl80211_set_wiphy(struct sk_buff *skb, struct genl_info *info)
1332 goto bad_res; 1335 goto bad_res;
1333 } 1336 }
1334 1337
1338 if (!netif_running(netdev)) {
1339 result = -ENETDOWN;
1340 goto bad_res;
1341 }
1342
1335 nla_for_each_nested(nl_txq_params, 1343 nla_for_each_nested(nl_txq_params,
1336 info->attrs[NL80211_ATTR_WIPHY_TXQ_PARAMS], 1344 info->attrs[NL80211_ATTR_WIPHY_TXQ_PARAMS],
1337 rem_txq_params) { 1345 rem_txq_params) {
@@ -2540,6 +2548,10 @@ static int nl80211_send_station(struct sk_buff *msg, u32 pid, u32 seq,
2540 sizeof(struct nl80211_sta_flag_update), 2548 sizeof(struct nl80211_sta_flag_update),
2541 &sinfo->sta_flags)) 2549 &sinfo->sta_flags))
2542 goto nla_put_failure; 2550 goto nla_put_failure;
2551 if ((sinfo->filled & STATION_INFO_T_OFFSET) &&
2552 nla_put_u64(msg, NL80211_STA_INFO_T_OFFSET,
2553 sinfo->t_offset))
2554 goto nla_put_failure;
2543 nla_nest_end(msg, sinfoattr); 2555 nla_nest_end(msg, sinfoattr);
2544 2556
2545 if ((sinfo->filled & STATION_INFO_ASSOC_REQ_IES) && 2557 if ((sinfo->filled & STATION_INFO_ASSOC_REQ_IES) &&
@@ -3340,6 +3352,8 @@ static int nl80211_get_mesh_config(struct sk_buff *skb,
3340 cur_params.element_ttl) || 3352 cur_params.element_ttl) ||
3341 nla_put_u8(msg, NL80211_MESHCONF_AUTO_OPEN_PLINKS, 3353 nla_put_u8(msg, NL80211_MESHCONF_AUTO_OPEN_PLINKS,
3342 cur_params.auto_open_plinks) || 3354 cur_params.auto_open_plinks) ||
3355 nla_put_u32(msg, NL80211_MESHCONF_SYNC_OFFSET_MAX_NEIGHBOR,
3356 cur_params.dot11MeshNbrOffsetMaxNeighbor) ||
3343 nla_put_u8(msg, NL80211_MESHCONF_HWMP_MAX_PREQ_RETRIES, 3357 nla_put_u8(msg, NL80211_MESHCONF_HWMP_MAX_PREQ_RETRIES,
3344 cur_params.dot11MeshHWMPmaxPREQretries) || 3358 cur_params.dot11MeshHWMPmaxPREQretries) ||
3345 nla_put_u32(msg, NL80211_MESHCONF_PATH_REFRESH_TIME, 3359 nla_put_u32(msg, NL80211_MESHCONF_PATH_REFRESH_TIME,
@@ -3385,6 +3399,7 @@ static const struct nla_policy nl80211_meshconf_params_policy[NL80211_MESHCONF_A
3385 [NL80211_MESHCONF_TTL] = { .type = NLA_U8 }, 3399 [NL80211_MESHCONF_TTL] = { .type = NLA_U8 },
3386 [NL80211_MESHCONF_ELEMENT_TTL] = { .type = NLA_U8 }, 3400 [NL80211_MESHCONF_ELEMENT_TTL] = { .type = NLA_U8 },
3387 [NL80211_MESHCONF_AUTO_OPEN_PLINKS] = { .type = NLA_U8 }, 3401 [NL80211_MESHCONF_AUTO_OPEN_PLINKS] = { .type = NLA_U8 },
3402 [NL80211_MESHCONF_SYNC_OFFSET_MAX_NEIGHBOR] = { .type = NLA_U32 },
3388 3403
3389 [NL80211_MESHCONF_HWMP_MAX_PREQ_RETRIES] = { .type = NLA_U8 }, 3404 [NL80211_MESHCONF_HWMP_MAX_PREQ_RETRIES] = { .type = NLA_U8 },
3390 [NL80211_MESHCONF_PATH_REFRESH_TIME] = { .type = NLA_U32 }, 3405 [NL80211_MESHCONF_PATH_REFRESH_TIME] = { .type = NLA_U32 },
@@ -3402,6 +3417,7 @@ static const struct nla_policy nl80211_meshconf_params_policy[NL80211_MESHCONF_A
3402 3417
3403static const struct nla_policy 3418static const struct nla_policy
3404 nl80211_mesh_setup_params_policy[NL80211_MESH_SETUP_ATTR_MAX+1] = { 3419 nl80211_mesh_setup_params_policy[NL80211_MESH_SETUP_ATTR_MAX+1] = {
3420 [NL80211_MESH_SETUP_ENABLE_VENDOR_SYNC] = { .type = NLA_U8 },
3405 [NL80211_MESH_SETUP_ENABLE_VENDOR_PATH_SEL] = { .type = NLA_U8 }, 3421 [NL80211_MESH_SETUP_ENABLE_VENDOR_PATH_SEL] = { .type = NLA_U8 },
3406 [NL80211_MESH_SETUP_ENABLE_VENDOR_METRIC] = { .type = NLA_U8 }, 3422 [NL80211_MESH_SETUP_ENABLE_VENDOR_METRIC] = { .type = NLA_U8 },
3407 [NL80211_MESH_SETUP_USERSPACE_AUTH] = { .type = NLA_FLAG }, 3423 [NL80211_MESH_SETUP_USERSPACE_AUTH] = { .type = NLA_FLAG },
@@ -3454,6 +3470,9 @@ do {\
3454 mask, NL80211_MESHCONF_ELEMENT_TTL, nla_get_u8); 3470 mask, NL80211_MESHCONF_ELEMENT_TTL, nla_get_u8);
3455 FILL_IN_MESH_PARAM_IF_SET(tb, cfg, auto_open_plinks, 3471 FILL_IN_MESH_PARAM_IF_SET(tb, cfg, auto_open_plinks,
3456 mask, NL80211_MESHCONF_AUTO_OPEN_PLINKS, nla_get_u8); 3472 mask, NL80211_MESHCONF_AUTO_OPEN_PLINKS, nla_get_u8);
3473 FILL_IN_MESH_PARAM_IF_SET(tb, cfg, dot11MeshNbrOffsetMaxNeighbor,
3474 mask, NL80211_MESHCONF_SYNC_OFFSET_MAX_NEIGHBOR,
3475 nla_get_u32);
3457 FILL_IN_MESH_PARAM_IF_SET(tb, cfg, dot11MeshHWMPmaxPREQretries, 3476 FILL_IN_MESH_PARAM_IF_SET(tb, cfg, dot11MeshHWMPmaxPREQretries,
3458 mask, NL80211_MESHCONF_HWMP_MAX_PREQ_RETRIES, 3477 mask, NL80211_MESHCONF_HWMP_MAX_PREQ_RETRIES,
3459 nla_get_u8); 3478 nla_get_u8);
@@ -3511,6 +3530,12 @@ static int nl80211_parse_mesh_setup(struct genl_info *info,
3511 nl80211_mesh_setup_params_policy)) 3530 nl80211_mesh_setup_params_policy))
3512 return -EINVAL; 3531 return -EINVAL;
3513 3532
3533 if (tb[NL80211_MESH_SETUP_ENABLE_VENDOR_SYNC])
3534 setup->sync_method =
3535 (nla_get_u8(tb[NL80211_MESH_SETUP_ENABLE_VENDOR_SYNC])) ?
3536 IEEE80211_SYNC_METHOD_VENDOR :
3537 IEEE80211_SYNC_METHOD_NEIGHBOR_OFFSET;
3538
3514 if (tb[NL80211_MESH_SETUP_ENABLE_VENDOR_PATH_SEL]) 3539 if (tb[NL80211_MESH_SETUP_ENABLE_VENDOR_PATH_SEL])
3515 setup->path_sel_proto = 3540 setup->path_sel_proto =
3516 (nla_get_u8(tb[NL80211_MESH_SETUP_ENABLE_VENDOR_PATH_SEL])) ? 3541 (nla_get_u8(tb[NL80211_MESH_SETUP_ENABLE_VENDOR_PATH_SEL])) ?
@@ -6077,6 +6102,7 @@ static int nl80211_set_wowlan(struct sk_buff *skb, struct genl_info *info)
6077 struct cfg80211_wowlan new_triggers = {}; 6102 struct cfg80211_wowlan new_triggers = {};
6078 struct wiphy_wowlan_support *wowlan = &rdev->wiphy.wowlan; 6103 struct wiphy_wowlan_support *wowlan = &rdev->wiphy.wowlan;
6079 int err, i; 6104 int err, i;
6105 bool prev_enabled = rdev->wowlan;
6080 6106
6081 if (!rdev->wiphy.wowlan.flags && !rdev->wiphy.wowlan.n_patterns) 6107 if (!rdev->wiphy.wowlan.flags && !rdev->wiphy.wowlan.n_patterns)
6082 return -EOPNOTSUPP; 6108 return -EOPNOTSUPP;
@@ -6209,6 +6235,9 @@ static int nl80211_set_wowlan(struct sk_buff *skb, struct genl_info *info)
6209 rdev->wowlan = NULL; 6235 rdev->wowlan = NULL;
6210 } 6236 }
6211 6237
6238 if (rdev->ops->set_wakeup && prev_enabled != !!rdev->wowlan)
6239 rdev->ops->set_wakeup(&rdev->wiphy, rdev->wowlan);
6240
6212 return 0; 6241 return 0;
6213 error: 6242 error:
6214 for (i = 0; i < new_triggers.n_patterns; i++) 6243 for (i = 0; i < new_triggers.n_patterns; i++)
@@ -6467,7 +6496,7 @@ static struct genl_ops nl80211_ops[] = {
6467 .doit = nl80211_get_key, 6496 .doit = nl80211_get_key,
6468 .policy = nl80211_policy, 6497 .policy = nl80211_policy,
6469 .flags = GENL_ADMIN_PERM, 6498 .flags = GENL_ADMIN_PERM,
6470 .internal_flags = NL80211_FLAG_NEED_NETDEV | 6499 .internal_flags = NL80211_FLAG_NEED_NETDEV_UP |
6471 NL80211_FLAG_NEED_RTNL, 6500 NL80211_FLAG_NEED_RTNL,
6472 }, 6501 },
6473 { 6502 {
@@ -6499,7 +6528,7 @@ static struct genl_ops nl80211_ops[] = {
6499 .policy = nl80211_policy, 6528 .policy = nl80211_policy,
6500 .flags = GENL_ADMIN_PERM, 6529 .flags = GENL_ADMIN_PERM,
6501 .doit = nl80211_set_beacon, 6530 .doit = nl80211_set_beacon,
6502 .internal_flags = NL80211_FLAG_NEED_NETDEV | 6531 .internal_flags = NL80211_FLAG_NEED_NETDEV_UP |
6503 NL80211_FLAG_NEED_RTNL, 6532 NL80211_FLAG_NEED_RTNL,
6504 }, 6533 },
6505 { 6534 {
@@ -6507,7 +6536,7 @@ static struct genl_ops nl80211_ops[] = {
6507 .policy = nl80211_policy, 6536 .policy = nl80211_policy,
6508 .flags = GENL_ADMIN_PERM, 6537 .flags = GENL_ADMIN_PERM,
6509 .doit = nl80211_start_ap, 6538 .doit = nl80211_start_ap,
6510 .internal_flags = NL80211_FLAG_NEED_NETDEV | 6539 .internal_flags = NL80211_FLAG_NEED_NETDEV_UP |
6511 NL80211_FLAG_NEED_RTNL, 6540 NL80211_FLAG_NEED_RTNL,
6512 }, 6541 },
6513 { 6542 {
@@ -6515,7 +6544,7 @@ static struct genl_ops nl80211_ops[] = {
6515 .policy = nl80211_policy, 6544 .policy = nl80211_policy,
6516 .flags = GENL_ADMIN_PERM, 6545 .flags = GENL_ADMIN_PERM,
6517 .doit = nl80211_stop_ap, 6546 .doit = nl80211_stop_ap,
6518 .internal_flags = NL80211_FLAG_NEED_NETDEV | 6547 .internal_flags = NL80211_FLAG_NEED_NETDEV_UP |
6519 NL80211_FLAG_NEED_RTNL, 6548 NL80211_FLAG_NEED_RTNL,
6520 }, 6549 },
6521 { 6550 {
@@ -6531,7 +6560,7 @@ static struct genl_ops nl80211_ops[] = {
6531 .doit = nl80211_set_station, 6560 .doit = nl80211_set_station,
6532 .policy = nl80211_policy, 6561 .policy = nl80211_policy,
6533 .flags = GENL_ADMIN_PERM, 6562 .flags = GENL_ADMIN_PERM,
6534 .internal_flags = NL80211_FLAG_NEED_NETDEV | 6563 .internal_flags = NL80211_FLAG_NEED_NETDEV_UP |
6535 NL80211_FLAG_NEED_RTNL, 6564 NL80211_FLAG_NEED_RTNL,
6536 }, 6565 },
6537 { 6566 {
@@ -6547,7 +6576,7 @@ static struct genl_ops nl80211_ops[] = {
6547 .doit = nl80211_del_station, 6576 .doit = nl80211_del_station,
6548 .policy = nl80211_policy, 6577 .policy = nl80211_policy,
6549 .flags = GENL_ADMIN_PERM, 6578 .flags = GENL_ADMIN_PERM,
6550 .internal_flags = NL80211_FLAG_NEED_NETDEV | 6579 .internal_flags = NL80211_FLAG_NEED_NETDEV_UP |
6551 NL80211_FLAG_NEED_RTNL, 6580 NL80211_FLAG_NEED_RTNL,
6552 }, 6581 },
6553 { 6582 {
@@ -6580,7 +6609,7 @@ static struct genl_ops nl80211_ops[] = {
6580 .doit = nl80211_del_mpath, 6609 .doit = nl80211_del_mpath,
6581 .policy = nl80211_policy, 6610 .policy = nl80211_policy,
6582 .flags = GENL_ADMIN_PERM, 6611 .flags = GENL_ADMIN_PERM,
6583 .internal_flags = NL80211_FLAG_NEED_NETDEV | 6612 .internal_flags = NL80211_FLAG_NEED_NETDEV_UP |
6584 NL80211_FLAG_NEED_RTNL, 6613 NL80211_FLAG_NEED_RTNL,
6585 }, 6614 },
6586 { 6615 {
@@ -6588,7 +6617,7 @@ static struct genl_ops nl80211_ops[] = {
6588 .doit = nl80211_set_bss, 6617 .doit = nl80211_set_bss,
6589 .policy = nl80211_policy, 6618 .policy = nl80211_policy,
6590 .flags = GENL_ADMIN_PERM, 6619 .flags = GENL_ADMIN_PERM,
6591 .internal_flags = NL80211_FLAG_NEED_NETDEV | 6620 .internal_flags = NL80211_FLAG_NEED_NETDEV_UP |
6592 NL80211_FLAG_NEED_RTNL, 6621 NL80211_FLAG_NEED_RTNL,
6593 }, 6622 },
6594 { 6623 {
@@ -6614,7 +6643,7 @@ static struct genl_ops nl80211_ops[] = {
6614 .doit = nl80211_get_mesh_config, 6643 .doit = nl80211_get_mesh_config,
6615 .policy = nl80211_policy, 6644 .policy = nl80211_policy,
6616 /* can be retrieved by unprivileged users */ 6645 /* can be retrieved by unprivileged users */
6617 .internal_flags = NL80211_FLAG_NEED_NETDEV | 6646 .internal_flags = NL80211_FLAG_NEED_NETDEV_UP |
6618 NL80211_FLAG_NEED_RTNL, 6647 NL80211_FLAG_NEED_RTNL,
6619 }, 6648 },
6620 { 6649 {
@@ -6747,7 +6776,7 @@ static struct genl_ops nl80211_ops[] = {
6747 .doit = nl80211_setdel_pmksa, 6776 .doit = nl80211_setdel_pmksa,
6748 .policy = nl80211_policy, 6777 .policy = nl80211_policy,
6749 .flags = GENL_ADMIN_PERM, 6778 .flags = GENL_ADMIN_PERM,
6750 .internal_flags = NL80211_FLAG_NEED_NETDEV | 6779 .internal_flags = NL80211_FLAG_NEED_NETDEV_UP |
6751 NL80211_FLAG_NEED_RTNL, 6780 NL80211_FLAG_NEED_RTNL,
6752 }, 6781 },
6753 { 6782 {
@@ -6755,7 +6784,7 @@ static struct genl_ops nl80211_ops[] = {
6755 .doit = nl80211_setdel_pmksa, 6784 .doit = nl80211_setdel_pmksa,
6756 .policy = nl80211_policy, 6785 .policy = nl80211_policy,
6757 .flags = GENL_ADMIN_PERM, 6786 .flags = GENL_ADMIN_PERM,
6758 .internal_flags = NL80211_FLAG_NEED_NETDEV | 6787 .internal_flags = NL80211_FLAG_NEED_NETDEV_UP |
6759 NL80211_FLAG_NEED_RTNL, 6788 NL80211_FLAG_NEED_RTNL,
6760 }, 6789 },
6761 { 6790 {
@@ -6763,7 +6792,7 @@ static struct genl_ops nl80211_ops[] = {
6763 .doit = nl80211_flush_pmksa, 6792 .doit = nl80211_flush_pmksa,
6764 .policy = nl80211_policy, 6793 .policy = nl80211_policy,
6765 .flags = GENL_ADMIN_PERM, 6794 .flags = GENL_ADMIN_PERM,
6766 .internal_flags = NL80211_FLAG_NEED_NETDEV | 6795 .internal_flags = NL80211_FLAG_NEED_NETDEV_UP |
6767 NL80211_FLAG_NEED_RTNL, 6796 NL80211_FLAG_NEED_RTNL,
6768 }, 6797 },
6769 { 6798 {
@@ -6923,7 +6952,7 @@ static struct genl_ops nl80211_ops[] = {
6923 .doit = nl80211_probe_client, 6952 .doit = nl80211_probe_client,
6924 .policy = nl80211_policy, 6953 .policy = nl80211_policy,
6925 .flags = GENL_ADMIN_PERM, 6954 .flags = GENL_ADMIN_PERM,
6926 .internal_flags = NL80211_FLAG_NEED_NETDEV | 6955 .internal_flags = NL80211_FLAG_NEED_NETDEV_UP |
6927 NL80211_FLAG_NEED_RTNL, 6956 NL80211_FLAG_NEED_RTNL,
6928 }, 6957 },
6929 { 6958 {
@@ -8012,6 +8041,39 @@ void nl80211_pmksa_candidate_notify(struct cfg80211_registered_device *rdev,
8012 nlmsg_free(msg); 8041 nlmsg_free(msg);
8013} 8042}
8014 8043
8044void nl80211_ch_switch_notify(struct cfg80211_registered_device *rdev,
8045 struct net_device *netdev, int freq,
8046 enum nl80211_channel_type type, gfp_t gfp)
8047{
8048 struct sk_buff *msg;
8049 void *hdr;
8050
8051 msg = nlmsg_new(NLMSG_GOODSIZE, gfp);
8052 if (!msg)
8053 return;
8054
8055 hdr = nl80211hdr_put(msg, 0, 0, 0, NL80211_CMD_CH_SWITCH_NOTIFY);
8056 if (!hdr) {
8057 nlmsg_free(msg);
8058 return;
8059 }
8060
8061 if (nla_put_u32(msg, NL80211_ATTR_IFINDEX, netdev->ifindex) ||
8062 nla_put_u32(msg, NL80211_ATTR_WIPHY_FREQ, freq) ||
8063 nla_put_u32(msg, NL80211_ATTR_WIPHY_CHANNEL_TYPE, type))
8064 goto nla_put_failure;
8065
8066 genlmsg_end(msg, hdr);
8067
8068 genlmsg_multicast_netns(wiphy_net(&rdev->wiphy), msg, 0,
8069 nl80211_mlme_mcgrp.id, gfp);
8070 return;
8071
8072 nla_put_failure:
8073 genlmsg_cancel(msg, hdr);
8074 nlmsg_free(msg);
8075}
8076
8015void 8077void
8016nl80211_send_cqm_pktloss_notify(struct cfg80211_registered_device *rdev, 8078nl80211_send_cqm_pktloss_notify(struct cfg80211_registered_device *rdev,
8017 struct net_device *netdev, const u8 *peer, 8079 struct net_device *netdev, const u8 *peer,