cfg80211: Add support for aborting an ongoing scan
authorVidyullatha Kanchanapally <vkanchan@qti.qualcomm.com>
Fri, 30 Oct 2015 13:44:49 +0000 (19:14 +0530)
committerJohannes Berg <johannes.berg@intel.com>
Fri, 4 Dec 2015 13:43:32 +0000 (14:43 +0100)
Implement new functionality for aborting an ongoing scan.

Add NL80211_CMD_ABORT_SCAN to the nl80211 interface. After
aborting the scan, driver shall provide the scan status by
calling cfg80211_scan_done().

Reviewed-by: Jouni Malinen <jouni@qca.qualcomm.com>
Signed-off-by: Vidyullatha Kanchanapally <vkanchan@qti.qualcomm.com>
Signed-off-by: Sunil Dutt <usdutt@qti.qualcomm.com>
[change command to take wdev instead of netdev so that it
 can be used on p2p-device scans]
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
include/net/cfg80211.h
include/uapi/linux/nl80211.h
net/wireless/nl80211.c
net/wireless/rdev-ops.h
net/wireless/trace.h

index e568872203a53171dca5990936be8a504bd9c7b0..9bcaaf7cd15ab053a5de9cbf92fd02f0fb0ffaf7 100644 (file)
@@ -2321,6 +2321,8 @@ struct cfg80211_qos_map {
  *     the driver, and will be valid until passed to cfg80211_scan_done().
  *     For scan results, call cfg80211_inform_bss(); you can call this outside
  *     the scan/scan_done bracket too.
+ * @abort_scan: Tell the driver to abort an ongoing scan. The driver shall
+ *     indicate the status of the scan through cfg80211_scan_done().
  *
  * @auth: Request to authenticate with the specified peer
  *     (invoked with the wireless_dev mutex held)
@@ -2593,6 +2595,7 @@ struct cfg80211_ops {
 
        int     (*scan)(struct wiphy *wiphy,
                        struct cfg80211_scan_request *request);
+       void    (*abort_scan)(struct wiphy *wiphy, struct wireless_dev *wdev);
 
        int     (*auth)(struct wiphy *wiphy, struct net_device *dev,
                        struct cfg80211_auth_request *req);
index 07099cb14778ddb0bc29cec3858a0c3d85ca2d09..5b7b5ebe7ca8731868e38bfab6218c166cb0317d 100644 (file)
  *     as an event to indicate changes for devices with wiphy-specific regdom
  *     management.
  *
+ * @NL80211_CMD_ABORT_SCAN: Stop an ongoing scan. Returns -ENOENT if a scan is
+ *     not running. The driver indicates the status of the scan through
+ *     cfg80211_scan_done().
+ *
  * @NL80211_CMD_MAX: highest used command number
  * @__NL80211_CMD_AFTER_LAST: internal use
  */
@@ -1006,6 +1010,8 @@ enum nl80211_commands {
 
        NL80211_CMD_WIPHY_REG_CHANGE,
 
+       NL80211_CMD_ABORT_SCAN,
+
        /* add new commands above here */
 
        /* used to define NL80211_CMD_MAX below */
index 41e57d0c4d43114222fe8a42ef525349d9d80e43..67e7b531db79046f5a6068cc566b14041be74bc7 100644 (file)
@@ -5997,6 +5997,24 @@ static int nl80211_trigger_scan(struct sk_buff *skb, struct genl_info *info)
        return err;
 }
 
+static int nl80211_abort_scan(struct sk_buff *skb, struct genl_info *info)
+{
+       struct cfg80211_registered_device *rdev = info->user_ptr[0];
+       struct wireless_dev *wdev = info->user_ptr[1];
+
+       if (!rdev->ops->abort_scan)
+               return -EOPNOTSUPP;
+
+       if (rdev->scan_msg)
+               return 0;
+
+       if (!rdev->scan_req)
+               return -ENOENT;
+
+       rdev_abort_scan(rdev, wdev);
+       return 0;
+}
+
 static int
 nl80211_parse_sched_scan_plans(struct wiphy *wiphy, int n_plans,
                               struct cfg80211_sched_scan_request *request,
@@ -10944,6 +10962,14 @@ static const struct genl_ops nl80211_ops[] = {
                .internal_flags = NL80211_FLAG_NEED_WDEV_UP |
                                  NL80211_FLAG_NEED_RTNL,
        },
+       {
+               .cmd = NL80211_CMD_ABORT_SCAN,
+               .doit = nl80211_abort_scan,
+               .policy = nl80211_policy,
+               .flags = GENL_ADMIN_PERM,
+               .internal_flags = NL80211_FLAG_NEED_WDEV_UP |
+                                 NL80211_FLAG_NEED_RTNL,
+       },
        {
                .cmd = NL80211_CMD_GET_SCAN,
                .policy = nl80211_policy,
index b8cc594d409d695b14432d1be210890c9a9e14e0..8ae0c04f9fc7d476919be7dc3b4e6c8e9a528496 100644 (file)
@@ -427,6 +427,14 @@ static inline int rdev_scan(struct cfg80211_registered_device *rdev,
        return ret;
 }
 
+static inline void rdev_abort_scan(struct cfg80211_registered_device *rdev,
+                                  struct wireless_dev *wdev)
+{
+       trace_rdev_abort_scan(&rdev->wiphy, wdev);
+       rdev->ops->abort_scan(&rdev->wiphy, wdev);
+       trace_rdev_return_void(&rdev->wiphy);
+}
+
 static inline int rdev_auth(struct cfg80211_registered_device *rdev,
                            struct net_device *dev,
                            struct cfg80211_auth_request *req)
index 5b9139e53199427ad822474aa58c9e040737e6f0..09b242b09bed841650466abcd4604a7af3c1a9e1 100644 (file)
@@ -2917,6 +2917,10 @@ TRACE_EVENT(rdev_set_coalesce,
                  WIPHY_PR_ARG, __entry->n_rules)
 );
 
+DEFINE_EVENT(wiphy_wdev_evt, rdev_abort_scan,
+       TP_PROTO(struct wiphy *wiphy, struct wireless_dev *wdev),
+       TP_ARGS(wiphy, wdev)
+);
 #endif /* !__RDEV_OPS_TRACE || TRACE_HEADER_MULTI_READ */
 
 #undef TRACE_INCLUDE_PATH