aboutsummaryrefslogtreecommitdiffstats
path: root/net/wireless/nl80211.c
diff options
context:
space:
mode:
Diffstat (limited to 'net/wireless/nl80211.c')
-rw-r--r--net/wireless/nl80211.c80
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 = {
6593static int nl80211_testmode_do(struct sk_buff *skb, struct genl_info *info) 6593static 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
7645out: 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
7649static int nl80211_join_mesh(struct sk_buff *skb, struct genl_info *info) 7657static int nl80211_join_mesh(struct sk_buff *skb, struct genl_info *info)
@@ -10442,7 +10450,7 @@ EXPORT_SYMBOL(cfg80211_rx_unexpected_4addr_frame);
10442int nl80211_send_mgmt(struct cfg80211_registered_device *rdev, 10450int 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);