wil6210: ensure P2P device is stopped before removing interface
authorLior David <qca_liord@qca.qualcomm.com>
Mon, 28 Aug 2017 19:18:47 +0000 (22:18 +0300)
committerKalle Valo <kvalo@qca.qualcomm.com>
Thu, 31 Aug 2017 12:19:54 +0000 (15:19 +0300)
User space can remove the P2P management interface while it is active
(for example, while listen/search is active) and this can cause
a crash. Ensure the P2P device is fully stopped before removing.

Signed-off-by: Lior David <qca_liord@qca.qualcomm.com>
Signed-off-by: Maya Erez <qca_merez@qca.qualcomm.com>
Signed-off-by: Kalle Valo <kvalo@qca.qualcomm.com>
drivers/net/wireless/ath/wil6210/cfg80211.c

index 0712a898205db79c669c6a6e1fd5ddbc080afd99..85d5c04618ebcafb87f8a089f31dac3b393f0dc5 100644 (file)
@@ -382,6 +382,34 @@ static int wil_cfg80211_dump_station(struct wiphy *wiphy,
        return rc;
 }
 
+static int wil_cfg80211_start_p2p_device(struct wiphy *wiphy,
+                                        struct wireless_dev *wdev)
+{
+       struct wil6210_priv *wil = wiphy_to_wil(wiphy);
+
+       wil_dbg_misc(wil, "start_p2p_device: entered\n");
+       wil->p2p.p2p_dev_started = 1;
+       return 0;
+}
+
+static void wil_cfg80211_stop_p2p_device(struct wiphy *wiphy,
+                                        struct wireless_dev *wdev)
+{
+       struct wil6210_priv *wil = wiphy_to_wil(wiphy);
+       struct wil_p2p_info *p2p = &wil->p2p;
+
+       if (!p2p->p2p_dev_started)
+               return;
+
+       wil_dbg_misc(wil, "stop_p2p_device: entered\n");
+       mutex_lock(&wil->mutex);
+       mutex_lock(&wil->p2p_wdev_mutex);
+       wil_p2p_stop_radio_operations(wil);
+       p2p->p2p_dev_started = 0;
+       mutex_unlock(&wil->p2p_wdev_mutex);
+       mutex_unlock(&wil->mutex);
+}
+
 static struct wireless_dev *
 wil_cfg80211_add_iface(struct wiphy *wiphy, const char *name,
                       unsigned char name_assign_type,
@@ -430,6 +458,7 @@ static int wil_cfg80211_del_iface(struct wiphy *wiphy,
                return -EINVAL;
        }
 
+       wil_cfg80211_stop_p2p_device(wiphy, wdev);
        wil_p2p_wdev_free(wil);
 
        return 0;
@@ -1661,34 +1690,6 @@ static int wil_cfg80211_change_bss(struct wiphy *wiphy,
        return 0;
 }
 
-static int wil_cfg80211_start_p2p_device(struct wiphy *wiphy,
-                                        struct wireless_dev *wdev)
-{
-       struct wil6210_priv *wil = wiphy_to_wil(wiphy);
-
-       wil_dbg_misc(wil, "start_p2p_device: entered\n");
-       wil->p2p.p2p_dev_started = 1;
-       return 0;
-}
-
-static void wil_cfg80211_stop_p2p_device(struct wiphy *wiphy,
-                                        struct wireless_dev *wdev)
-{
-       struct wil6210_priv *wil = wiphy_to_wil(wiphy);
-       struct wil_p2p_info *p2p = &wil->p2p;
-
-       if (!p2p->p2p_dev_started)
-               return;
-
-       wil_dbg_misc(wil, "stop_p2p_device: entered\n");
-       mutex_lock(&wil->mutex);
-       mutex_lock(&wil->p2p_wdev_mutex);
-       wil_p2p_stop_radio_operations(wil);
-       p2p->p2p_dev_started = 0;
-       mutex_unlock(&wil->p2p_wdev_mutex);
-       mutex_unlock(&wil->mutex);
-}
-
 static int wil_cfg80211_set_power_mgmt(struct wiphy *wiphy,
                                       struct net_device *dev,
                                       bool enabled, int timeout)