mac80211&nl80211: support to abort a scan request on tx
Wei Ni [Fri, 2 Nov 2012 05:40:04 +0000 (13:40 +0800)]
mac80211 & nl80211: add support to abort a scan request on tx

The original issue is the chromium issue:
http://code.google.com/p/chromium-os/issues/detail?id=11485

This fix comes from:
https://gerrit.chromium.org/gerrit/#change,5744
https://gerrit.chromium.org/gerrit/#change,5745

Since this change is for ChromeOs and will affect Android P2P function,
so we add config option MAC80211_SCAN_ABORT for it.

Bug 1051830

Change-Id: I77504f4d279f3f3d99b5e5f9d734480888d62193
Signed-off-by: Wei Ni <wni@nvidia.com>
Reviewed-on: http://git-master/r/160777
Reviewed-by: Automatic_Commit_Validation_User
Reviewed-by: Rhyland Klein <rklein@nvidia.com>
Reviewed-by: Bibhay Ranjan <bibhayr@nvidia.com>
Tested-by: Bibhay Ranjan <bibhayr@nvidia.com>
Reviewed-by: Bharat Nihalani <bnihalani@nvidia.com>

include/net/cfg80211.h
include/uapi/linux/nl80211.h
net/mac80211/Kconfig
net/mac80211/ieee80211_i.h
net/mac80211/scan.c
net/wireless/nl80211.c

index 26b5b69..f8f5de7 100644 (file)
@@ -1227,6 +1227,15 @@ struct cfg80211_ssid {
 };
 
 /**
+ * enum cfg80211_scan_flag -  scan request control flags
+ *
+ * @CFG80211_SCAN__FLAG_TX_ABORT: abort scan on pending transmit
+ */
+enum cfg80211_scan_flags {
+       CFG80211_SCAN_FLAG_TX_ABORT     = NL80211_SCAN_FLAG_TX_ABORT,
+};
+
+/**
  * struct cfg80211_scan_request - scan request description
  *
  * @ssids: SSIDs to scan for (active scan only)
index d1e48b5..afba28f 100644 (file)
@@ -1190,6 +1190,8 @@ enum nl80211_commands {
  * @NL80211_ATTR_WIPHY_ANTENNA_AVAIL_RX: Bitmap of antennas which are available
  *     for configuration as RX antennas via the above parameters.
  *
+ * @NL80211_ATTR_SCAN_FLAGS: scan request control flags (u32).
+ *
  * @NL80211_ATTR_MCAST_RATE: Multicast tx rate (in 100 kbps) for IBSS
  *
  * @NL80211_ATTR_OFFCHANNEL_TX_OK: For management frame TX, the frame may be
@@ -1616,6 +1618,10 @@ enum nl80211_attrs {
        NL80211_ATTR_WIPHY_ANTENNA_AVAIL_TX,
        NL80211_ATTR_WIPHY_ANTENNA_AVAIL_RX,
 
+#ifdef CONFIG_MAC80211_SCAN_ABORT
+       NL80211_ATTR_SCAN_FLAGS,
+#endif
+
        NL80211_ATTR_SUPPORT_MESH_AUTH,
        NL80211_ATTR_STA_PLINK_STATE,
 
@@ -3623,11 +3629,13 @@ enum nl80211_connect_failed_reason {
  *     dangerous because will destroy stations performance as a lot of frames
  *     will be lost while scanning off-channel, therefore it must be used only
  *     when really needed
+ * @NL80211_SCAN_FLAG_TX_ABORT: abort scan if tx collides
  */
 enum nl80211_scan_flags {
        NL80211_SCAN_FLAG_LOW_PRIORITY                  = 1<<0,
        NL80211_SCAN_FLAG_FLUSH                         = 1<<1,
        NL80211_SCAN_FLAG_AP                            = 1<<2,
+       NL80211_SCAN_FLAG_TX_ABORT                      = 1<<3,
 };
 
 /**
index 62535fe..3d533f1 100644 (file)
@@ -291,3 +291,12 @@ config MAC80211_DEBUG_COUNTERS
          and show them in debugfs.
 
          If unsure, say N.
+
+config MAC80211_SCAN_ABORT
+       bool "Support to abort a scan request on tx"
+       depends on MAC80211
+       depends on WIRELESS
+       default n
+       ---help---
+         Add support for aborting scan requests.
+         This is only for ChromeOs, because it will affect Android P2P.
index 9ca8e32..9f48d84 100644 (file)
@@ -863,6 +863,8 @@ enum {
  *     send out data
  * @SCAN_RESUME: Resume the scan and scan the next channel
  * @SCAN_ABORT: Abort the scan and go back to operating channel
+ * @SCAN_SUSPEND_ABORT: Return to the operating channel then
+ *     terminate the scan operation.
  */
 enum mac80211_scan_state {
        SCAN_DECISION,
@@ -871,6 +873,7 @@ enum mac80211_scan_state {
        SCAN_SUSPEND,
        SCAN_RESUME,
        SCAN_ABORT,
+       SCAN_SUSPEND_ABORT,
 };
 
 struct ieee80211_local {
index 99b1039..5d8b2e7 100644 (file)
@@ -656,9 +656,20 @@ static void ieee80211_scan_state_suspend(struct ieee80211_local *local,
        /* disable PS */
        ieee80211_offchannel_return(local);
 
+#ifndef CONFIG_MAC80211_SCAN_ABORT
        *next_delay = HZ / 5;
        /* afterwards, resume scan & go to next channel */
        local->next_scan_state = SCAN_RESUME;
+#else
+       if (local->next_scan_state == SCAN_SUSPEND) {
+               *next_delay = HZ / 5;
+               /* afterwards, resume scan & go to next channel */
+               local->next_scan_state = SCAN_RESUME;
+       } else {
+               *next_delay = 0;
+               local->next_scan_state = SCAN_ABORT;
+       }
+#endif
 }
 
 static void ieee80211_scan_state_resume(struct ieee80211_local *local,
@@ -757,6 +768,9 @@ void ieee80211_scan_work(struct work_struct *work)
                        ieee80211_scan_state_send_probe(local, &next_delay);
                        break;
                case SCAN_SUSPEND:
+#ifdef CONFIG_MAC80211_SCAN_ABORT
+               case SCAN_SUSPEND_ABORT:
+#endif
                        ieee80211_scan_state_suspend(local, &next_delay);
                        break;
                case SCAN_RESUME:
index 448c034..b145256 100644 (file)
@@ -289,6 +289,9 @@ static const struct nla_policy nl80211_policy[NL80211_ATTR_MAX+1] = {
        [NL80211_ATTR_MGMT_SUBTYPE] = { .type = NLA_U8 },
        [NL80211_ATTR_IE] = { .type = NLA_BINARY,
                              .len = IEEE80211_MAX_DATA_LEN },
+#ifdef CONFIG_MAC80211_SCAN_ABORT
+       [NL80211_ATTR_SCAN_FLAGS] = { .type = NLA_U32 },
+#endif
        [NL80211_ATTR_SCAN_FREQUENCIES] = { .type = NLA_NESTED },
        [NL80211_ATTR_SCAN_SSIDS] = { .type = NLA_NESTED },
 
@@ -5241,6 +5244,12 @@ static int nl80211_trigger_scan(struct sk_buff *skb, struct genl_info *info)
        request->no_cck =
                nla_get_flag(info->attrs[NL80211_ATTR_TX_NO_CCK_RATE]);
 
+#ifdef CONFIG_MAC80211_SCAN_ABORT
+       if (info->attrs[NL80211_ATTR_SCAN_FLAGS])
+               request->flags = nla_get_u32(
+                   info->attrs[NL80211_ATTR_SCAN_FLAGS]);
+#endif
+
        request->wdev = wdev;
        request->wiphy = &rdev->wiphy;
        request->scan_start = jiffies;