]> exis.tech > repos - linux.git/blobdiff - net/wireless/pmsr.c
Merge tag 'hwmon-for-v7.2-rc5' of git://git.kernel.org/pub/scm/linux/kernel/git/groec...
[linux.git] / net / wireless / pmsr.c
index c8447448f3a505d202d7109bc10fdf79ce936efb..34c3625f7fd5e51d34bb4c6ad6f9b0651ad231c6 100644 (file)
@@ -125,6 +125,7 @@ static int pmsr_parse_ftm(struct cfg80211_registered_device *rdev,
                NL_SET_ERR_MSG_ATTR(info->extack,
                                    tb[NL80211_PMSR_FTM_REQ_ATTR_REQUEST_LCI],
                                    "FTM: LCI request not supported");
+               return -EOPNOTSUPP;
        }
 
        out->ftm.request_civicloc =
@@ -133,6 +134,7 @@ static int pmsr_parse_ftm(struct cfg80211_registered_device *rdev,
                NL_SET_ERR_MSG_ATTR(info->extack,
                                    tb[NL80211_PMSR_FTM_REQ_ATTR_REQUEST_CIVICLOC],
                            "FTM: civic location request not supported");
+               return -EOPNOTSUPP;
        }
 
        out->ftm.trigger_based =
@@ -310,6 +312,7 @@ static int pmsr_parse_peer(struct cfg80211_registered_device *rdev,
 {
        struct nlattr *tb[NL80211_PMSR_PEER_ATTR_MAX + 1];
        struct nlattr *req[NL80211_PMSR_REQ_ATTR_MAX + 1];
+       bool have_measurement_type = false;
        struct nlattr *treq;
        int err, rem;
 
@@ -376,6 +379,14 @@ static int pmsr_parse_peer(struct cfg80211_registered_device *rdev,
        }
 
        nla_for_each_nested(treq, req[NL80211_PMSR_REQ_ATTR_DATA], rem) {
+               if (have_measurement_type) {
+                       NL_SET_ERR_MSG_ATTR(info->extack, treq,
+                                           "multiple measurement types in request data");
+                       return -EINVAL;
+               }
+
+               have_measurement_type = true;
+
                switch (nla_type(treq)) {
                case NL80211_PMSR_TYPE_FTM:
                        err = pmsr_parse_ftm(rdev, treq, out, info);
@@ -385,10 +396,16 @@ static int pmsr_parse_peer(struct cfg80211_registered_device *rdev,
                                            "unsupported measurement type");
                        err = -EINVAL;
                }
+               if (err)
+                       return err;
        }
 
-       if (err)
-               return err;
+       if (!have_measurement_type) {
+               NL_SET_ERR_MSG_ATTR(info->extack,
+                                   req[NL80211_PMSR_REQ_ATTR_DATA],
+                                   "missing measurement type in request data");
+               return -EINVAL;
+       }
 
        return 0;
 }
@@ -427,6 +444,11 @@ int nl80211_pmsr_start(struct sk_buff *skb, struct genl_info *info)
                }
        }
 
+       if (!count) {
+               NL_SET_ERR_MSG_ATTR(info->extack, peers, "No peers specified");
+               return -EINVAL;
+       }
+
        req = kzalloc_flex(*req, peers, count);
        if (!req)
                return -ENOMEM;
@@ -807,13 +829,11 @@ static void cfg80211_pmsr_process_abort(struct wireless_dev *wdev)
        }
 }
 
-void cfg80211_pmsr_free_wk(struct work_struct *work)
+void cfg80211_pmsr_free_wk(struct wiphy *wiphy, struct wiphy_work *work)
 {
        struct wireless_dev *wdev = container_of(work, struct wireless_dev,
                                                 pmsr_free_wk);
 
-       guard(wiphy)(wdev->wiphy);
-
        cfg80211_pmsr_process_abort(wdev);
 }
 
@@ -829,7 +849,7 @@ void cfg80211_pmsr_wdev_down(struct wireless_dev *wdev)
        }
        spin_unlock_bh(&wdev->pmsr_lock);
 
-       cancel_work_sync(&wdev->pmsr_free_wk);
+       wiphy_work_cancel(wdev->wiphy, &wdev->pmsr_free_wk);
        if (found)
                cfg80211_pmsr_process_abort(wdev);
 
@@ -844,7 +864,7 @@ void cfg80211_release_pmsr(struct wireless_dev *wdev, u32 portid)
        list_for_each_entry(req, &wdev->pmsr_list, list) {
                if (req->nl_portid == portid) {
                        req->nl_portid = 0;
-                       schedule_work(&wdev->pmsr_free_wk);
+                       wiphy_work_queue(wdev->wiphy, &wdev->pmsr_free_wk);
                }
        }
        spin_unlock_bh(&wdev->pmsr_lock);