Merge tag 'pci-v4.9-changes-2' of git://git.kernel.org/pub/scm/linux/kernel/git/helga...
[cascardo/linux.git] / net / wireless / core.c
index 4911cd9..8201e6d 100644 (file)
@@ -225,6 +225,23 @@ void cfg80211_stop_p2p_device(struct cfg80211_registered_device *rdev,
        }
 }
 
+void cfg80211_stop_nan(struct cfg80211_registered_device *rdev,
+                      struct wireless_dev *wdev)
+{
+       ASSERT_RTNL();
+
+       if (WARN_ON(wdev->iftype != NL80211_IFTYPE_NAN))
+               return;
+
+       if (!wdev->nan_started)
+               return;
+
+       rdev_stop_nan(rdev, wdev);
+       wdev->nan_started = false;
+
+       rdev->opencount--;
+}
+
 void cfg80211_shutdown_all_interfaces(struct wiphy *wiphy)
 {
        struct cfg80211_registered_device *rdev = wiphy_to_rdev(wiphy);
@@ -242,6 +259,9 @@ void cfg80211_shutdown_all_interfaces(struct wiphy *wiphy)
                case NL80211_IFTYPE_P2P_DEVICE:
                        cfg80211_stop_p2p_device(rdev, wdev);
                        break;
+               case NL80211_IFTYPE_NAN:
+                       cfg80211_stop_nan(rdev, wdev);
+                       break;
                default:
                        break;
                }
@@ -537,6 +557,11 @@ static int wiphy_verify_combinations(struct wiphy *wiphy)
                                    c->limits[j].max > 1))
                                return -EINVAL;
 
+                       /* Only a single NAN can be allowed */
+                       if (WARN_ON(types & BIT(NL80211_IFTYPE_NAN) &&
+                                   c->limits[j].max > 1))
+                               return -EINVAL;
+
                        cnt += c->limits[j].max;
                        /*
                         * Don't advertise an unsupported type
@@ -579,6 +604,11 @@ int wiphy_register(struct wiphy *wiphy)
                     !rdev->ops->tdls_cancel_channel_switch)))
                return -EINVAL;
 
+       if (WARN_ON((wiphy->interface_modes & BIT(NL80211_IFTYPE_NAN)) &&
+                   (!rdev->ops->start_nan || !rdev->ops->stop_nan ||
+                    !rdev->ops->add_nan_func || !rdev->ops->del_nan_func)))
+               return -EINVAL;
+
        /*
         * if a wiphy has unsupported modes for regulatory channel enforcement,
         * opt-out of enforcement checking
@@ -589,6 +619,7 @@ int wiphy_register(struct wiphy *wiphy)
                                       BIT(NL80211_IFTYPE_P2P_GO) |
                                       BIT(NL80211_IFTYPE_ADHOC) |
                                       BIT(NL80211_IFTYPE_P2P_DEVICE) |
+                                      BIT(NL80211_IFTYPE_NAN) |
                                       BIT(NL80211_IFTYPE_AP_VLAN) |
                                       BIT(NL80211_IFTYPE_MONITOR)))
                wiphy->regulatory_flags |= REGULATORY_IGNORE_STALE_KICKOFF;
@@ -916,6 +947,9 @@ void cfg80211_unregister_wdev(struct wireless_dev *wdev)
                cfg80211_mlme_purge_registrations(wdev);
                cfg80211_stop_p2p_device(rdev, wdev);
                break;
+       case NL80211_IFTYPE_NAN:
+               cfg80211_stop_nan(rdev, wdev);
+               break;
        default:
                WARN_ON_ONCE(1);
                break;
@@ -979,6 +1013,7 @@ void __cfg80211_leave(struct cfg80211_registered_device *rdev,
                /* must be handled by mac80211/driver, has no APIs */
                break;
        case NL80211_IFTYPE_P2P_DEVICE:
+       case NL80211_IFTYPE_NAN:
                /* cannot happen, has no netdev */
                break;
        case NL80211_IFTYPE_AP_VLAN: