diff options
author | John W. Linville <linville@tuxdriver.com> | 2012-04-12 14:25:14 -0400 |
---|---|---|
committer | John W. Linville <linville@tuxdriver.com> | 2012-04-12 14:41:59 -0400 |
commit | 7eab0f64a9eba5405222fdef0ede2468bf495efd (patch) | |
tree | ec99640b8d0b12adbfacb85c27683125debd14f2 /net/wireless/nl80211.c | |
parent | cade455596504fae8e134a27189713ddf7c6d04d (diff) | |
parent | 8065248069097dddf9945acfb2081025e9618c16 (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.c | 92 |
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] = { | |||
1142 | static int parse_txq_params(struct nlattr *tb[], | 1142 | static 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 | ||
3403 | static const struct nla_policy | 3418 | static 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 | ||
8044 | void 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 | |||
8015 | void | 8077 | void |
8016 | nl80211_send_cqm_pktloss_notify(struct cfg80211_registered_device *rdev, | 8078 | nl80211_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, |