diff options
Diffstat (limited to 'net/wireless/nl80211.c')
-rw-r--r-- | net/wireless/nl80211.c | 80 |
1 files changed, 45 insertions, 35 deletions
diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c index 170c0abd2a01..af8d84a4a5b2 100644 --- a/net/wireless/nl80211.c +++ b/net/wireless/nl80211.c | |||
@@ -6593,19 +6593,30 @@ static struct genl_multicast_group nl80211_testmode_mcgrp = { | |||
6593 | static int nl80211_testmode_do(struct sk_buff *skb, struct genl_info *info) | 6593 | static int nl80211_testmode_do(struct sk_buff *skb, struct genl_info *info) |
6594 | { | 6594 | { |
6595 | struct cfg80211_registered_device *rdev = info->user_ptr[0]; | 6595 | struct cfg80211_registered_device *rdev = info->user_ptr[0]; |
6596 | struct wireless_dev *wdev = | ||
6597 | __cfg80211_wdev_from_attrs(genl_info_net(info), info->attrs); | ||
6596 | int err; | 6598 | int err; |
6597 | 6599 | ||
6600 | if (!rdev->ops->testmode_cmd) | ||
6601 | return -EOPNOTSUPP; | ||
6602 | |||
6603 | if (IS_ERR(wdev)) { | ||
6604 | err = PTR_ERR(wdev); | ||
6605 | if (err != -EINVAL) | ||
6606 | return err; | ||
6607 | wdev = NULL; | ||
6608 | } else if (wdev->wiphy != &rdev->wiphy) { | ||
6609 | return -EINVAL; | ||
6610 | } | ||
6611 | |||
6598 | if (!info->attrs[NL80211_ATTR_TESTDATA]) | 6612 | if (!info->attrs[NL80211_ATTR_TESTDATA]) |
6599 | return -EINVAL; | 6613 | return -EINVAL; |
6600 | 6614 | ||
6601 | err = -EOPNOTSUPP; | 6615 | rdev->testmode_info = info; |
6602 | if (rdev->ops->testmode_cmd) { | 6616 | err = rdev_testmode_cmd(rdev, wdev, |
6603 | rdev->testmode_info = info; | ||
6604 | err = rdev_testmode_cmd(rdev, | ||
6605 | nla_data(info->attrs[NL80211_ATTR_TESTDATA]), | 6617 | nla_data(info->attrs[NL80211_ATTR_TESTDATA]), |
6606 | nla_len(info->attrs[NL80211_ATTR_TESTDATA])); | 6618 | nla_len(info->attrs[NL80211_ATTR_TESTDATA])); |
6607 | rdev->testmode_info = NULL; | 6619 | rdev->testmode_info = NULL; |
6608 | } | ||
6609 | 6620 | ||
6610 | return err; | 6621 | return err; |
6611 | } | 6622 | } |
@@ -7567,14 +7578,12 @@ static int nl80211_set_cqm_txe(struct genl_info *info, | |||
7567 | u32 rate, u32 pkts, u32 intvl) | 7578 | u32 rate, u32 pkts, u32 intvl) |
7568 | { | 7579 | { |
7569 | struct cfg80211_registered_device *rdev = info->user_ptr[0]; | 7580 | struct cfg80211_registered_device *rdev = info->user_ptr[0]; |
7570 | struct wireless_dev *wdev; | ||
7571 | struct net_device *dev = info->user_ptr[1]; | 7581 | struct net_device *dev = info->user_ptr[1]; |
7582 | struct wireless_dev *wdev = dev->ieee80211_ptr; | ||
7572 | 7583 | ||
7573 | if (rate > 100 || intvl > NL80211_CQM_TXE_MAX_INTVL) | 7584 | if (rate > 100 || intvl > NL80211_CQM_TXE_MAX_INTVL) |
7574 | return -EINVAL; | 7585 | return -EINVAL; |
7575 | 7586 | ||
7576 | wdev = dev->ieee80211_ptr; | ||
7577 | |||
7578 | if (!rdev->ops->set_cqm_txe_config) | 7587 | if (!rdev->ops->set_cqm_txe_config) |
7579 | return -EOPNOTSUPP; | 7588 | return -EOPNOTSUPP; |
7580 | 7589 | ||
@@ -7589,13 +7598,15 @@ static int nl80211_set_cqm_rssi(struct genl_info *info, | |||
7589 | s32 threshold, u32 hysteresis) | 7598 | s32 threshold, u32 hysteresis) |
7590 | { | 7599 | { |
7591 | struct cfg80211_registered_device *rdev = info->user_ptr[0]; | 7600 | struct cfg80211_registered_device *rdev = info->user_ptr[0]; |
7592 | struct wireless_dev *wdev; | ||
7593 | struct net_device *dev = info->user_ptr[1]; | 7601 | struct net_device *dev = info->user_ptr[1]; |
7602 | struct wireless_dev *wdev = dev->ieee80211_ptr; | ||
7594 | 7603 | ||
7595 | if (threshold > 0) | 7604 | if (threshold > 0) |
7596 | return -EINVAL; | 7605 | return -EINVAL; |
7597 | 7606 | ||
7598 | wdev = dev->ieee80211_ptr; | 7607 | /* disabling - hysteresis should also be zero then */ |
7608 | if (threshold == 0) | ||
7609 | hysteresis = 0; | ||
7599 | 7610 | ||
7600 | if (!rdev->ops->set_cqm_rssi_config) | 7611 | if (!rdev->ops->set_cqm_rssi_config) |
7601 | return -EOPNOTSUPP; | 7612 | return -EOPNOTSUPP; |
@@ -7614,36 +7625,33 @@ static int nl80211_set_cqm(struct sk_buff *skb, struct genl_info *info) | |||
7614 | int err; | 7625 | int err; |
7615 | 7626 | ||
7616 | cqm = info->attrs[NL80211_ATTR_CQM]; | 7627 | cqm = info->attrs[NL80211_ATTR_CQM]; |
7617 | if (!cqm) { | 7628 | if (!cqm) |
7618 | err = -EINVAL; | 7629 | return -EINVAL; |
7619 | goto out; | ||
7620 | } | ||
7621 | 7630 | ||
7622 | err = nla_parse_nested(attrs, NL80211_ATTR_CQM_MAX, cqm, | 7631 | err = nla_parse_nested(attrs, NL80211_ATTR_CQM_MAX, cqm, |
7623 | nl80211_attr_cqm_policy); | 7632 | nl80211_attr_cqm_policy); |
7624 | if (err) | 7633 | if (err) |
7625 | goto out; | 7634 | return err; |
7626 | 7635 | ||
7627 | if (attrs[NL80211_ATTR_CQM_RSSI_THOLD] && | 7636 | if (attrs[NL80211_ATTR_CQM_RSSI_THOLD] && |
7628 | attrs[NL80211_ATTR_CQM_RSSI_HYST]) { | 7637 | attrs[NL80211_ATTR_CQM_RSSI_HYST]) { |
7629 | s32 threshold; | 7638 | s32 threshold = nla_get_s32(attrs[NL80211_ATTR_CQM_RSSI_THOLD]); |
7630 | u32 hysteresis; | 7639 | u32 hysteresis = nla_get_u32(attrs[NL80211_ATTR_CQM_RSSI_HYST]); |
7631 | threshold = nla_get_u32(attrs[NL80211_ATTR_CQM_RSSI_THOLD]); | ||
7632 | hysteresis = nla_get_u32(attrs[NL80211_ATTR_CQM_RSSI_HYST]); | ||
7633 | err = nl80211_set_cqm_rssi(info, threshold, hysteresis); | ||
7634 | } else if (attrs[NL80211_ATTR_CQM_TXE_RATE] && | ||
7635 | attrs[NL80211_ATTR_CQM_TXE_PKTS] && | ||
7636 | attrs[NL80211_ATTR_CQM_TXE_INTVL]) { | ||
7637 | u32 rate, pkts, intvl; | ||
7638 | rate = nla_get_u32(attrs[NL80211_ATTR_CQM_TXE_RATE]); | ||
7639 | pkts = nla_get_u32(attrs[NL80211_ATTR_CQM_TXE_PKTS]); | ||
7640 | intvl = nla_get_u32(attrs[NL80211_ATTR_CQM_TXE_INTVL]); | ||
7641 | err = nl80211_set_cqm_txe(info, rate, pkts, intvl); | ||
7642 | } else | ||
7643 | err = -EINVAL; | ||
7644 | 7640 | ||
7645 | out: | 7641 | return nl80211_set_cqm_rssi(info, threshold, hysteresis); |
7646 | return err; | 7642 | } |
7643 | |||
7644 | if (attrs[NL80211_ATTR_CQM_TXE_RATE] && | ||
7645 | attrs[NL80211_ATTR_CQM_TXE_PKTS] && | ||
7646 | attrs[NL80211_ATTR_CQM_TXE_INTVL]) { | ||
7647 | u32 rate = nla_get_u32(attrs[NL80211_ATTR_CQM_TXE_RATE]); | ||
7648 | u32 pkts = nla_get_u32(attrs[NL80211_ATTR_CQM_TXE_PKTS]); | ||
7649 | u32 intvl = nla_get_u32(attrs[NL80211_ATTR_CQM_TXE_INTVL]); | ||
7650 | |||
7651 | return nl80211_set_cqm_txe(info, rate, pkts, intvl); | ||
7652 | } | ||
7653 | |||
7654 | return -EINVAL; | ||
7647 | } | 7655 | } |
7648 | 7656 | ||
7649 | static int nl80211_join_mesh(struct sk_buff *skb, struct genl_info *info) | 7657 | static int nl80211_join_mesh(struct sk_buff *skb, struct genl_info *info) |
@@ -10442,7 +10450,7 @@ EXPORT_SYMBOL(cfg80211_rx_unexpected_4addr_frame); | |||
10442 | int nl80211_send_mgmt(struct cfg80211_registered_device *rdev, | 10450 | int nl80211_send_mgmt(struct cfg80211_registered_device *rdev, |
10443 | struct wireless_dev *wdev, u32 nlportid, | 10451 | struct wireless_dev *wdev, u32 nlportid, |
10444 | int freq, int sig_dbm, | 10452 | int freq, int sig_dbm, |
10445 | const u8 *buf, size_t len, gfp_t gfp) | 10453 | const u8 *buf, size_t len, u32 flags, gfp_t gfp) |
10446 | { | 10454 | { |
10447 | struct net_device *netdev = wdev->netdev; | 10455 | struct net_device *netdev = wdev->netdev; |
10448 | struct sk_buff *msg; | 10456 | struct sk_buff *msg; |
@@ -10465,7 +10473,9 @@ int nl80211_send_mgmt(struct cfg80211_registered_device *rdev, | |||
10465 | nla_put_u32(msg, NL80211_ATTR_WIPHY_FREQ, freq) || | 10473 | nla_put_u32(msg, NL80211_ATTR_WIPHY_FREQ, freq) || |
10466 | (sig_dbm && | 10474 | (sig_dbm && |
10467 | nla_put_u32(msg, NL80211_ATTR_RX_SIGNAL_DBM, sig_dbm)) || | 10475 | nla_put_u32(msg, NL80211_ATTR_RX_SIGNAL_DBM, sig_dbm)) || |
10468 | nla_put(msg, NL80211_ATTR_FRAME, len, buf)) | 10476 | nla_put(msg, NL80211_ATTR_FRAME, len, buf) || |
10477 | (flags && | ||
10478 | nla_put_u32(msg, NL80211_ATTR_RXMGMT_FLAGS, flags))) | ||
10469 | goto nla_put_failure; | 10479 | goto nla_put_failure; |
10470 | 10480 | ||
10471 | genlmsg_end(msg, hdr); | 10481 | genlmsg_end(msg, hdr); |