]> git.kernelconcepts.de Git - karo-tx-linux.git/commitdiff
Merge tag 'mac80211-next-for-davem-2015-05-29' of git://git.kernel.org/pub/scm/linux...
authorDavid S. Miller <davem@davemloft.net>
Mon, 1 Jun 2015 00:34:26 +0000 (17:34 -0700)
committerDavid S. Miller <davem@davemloft.net>
Mon, 1 Jun 2015 00:34:26 +0000 (17:34 -0700)
Johannes Berg says:

====================
As we get closer to the merge window, here are a few
more things for -next:
 * disconnect TDLS stations on CSA to avoid issues
 * fix a memory leak introduced in a recent commit
 * switch rfkill and cfg80211 to PM ops
 * in an unlikely scenario, prevent a bookkeeping
   value to get corrupted leading to dropped packets
 * fix a crash in VLAN assignment
 * switch rfkill-gpio to more modern gpiod API
 * send disconnected event to userspace with proper
   local/remote indication
====================

Signed-off-by: David S. Miller <davem@davemloft.net>
24 files changed:
drivers/net/wireless/ath/ath6kl/cfg80211.c
drivers/net/wireless/ath/wil6210/main.c
drivers/net/wireless/brcm80211/brcmfmac/cfg80211.c
drivers/net/wireless/libertas/cfg.c
drivers/net/wireless/libertas/cfg.h
drivers/net/wireless/libertas/cmd.h
drivers/net/wireless/libertas/cmdresp.c
drivers/net/wireless/mwifiex/join.c
drivers/net/wireless/mwifiex/sta_event.c
drivers/net/wireless/rndis_wlan.c
drivers/staging/rtl8723au/os_dep/ioctl_cfg80211.c
drivers/staging/wlan-ng/cfg80211.c
include/net/cfg80211.h
include/net/mac80211.h
net/mac80211/cfg.c
net/mac80211/main.c
net/mac80211/mlme.c
net/mac80211/tdls.c
net/rfkill/core.c
net/rfkill/rfkill-gpio.c
net/wireless/core.h
net/wireless/sme.c
net/wireless/sysfs.c
net/wireless/util.c

index cce4625a53ad7eb630bef4b717cc9fe0177d96fc..a511ef3614b9ed098558d1d86a9fec88b2330235 100644 (file)
@@ -889,7 +889,7 @@ void ath6kl_cfg80211_disconnect_event(struct ath6kl_vif *vif, u8 reason,
                                        GFP_KERNEL);
        } else if (vif->sme_state == SME_CONNECTED) {
                cfg80211_disconnected(vif->ndev, proto_reason,
-                                     NULL, 0, GFP_KERNEL);
+                                     NULL, 0, false, GFP_KERNEL);
        }
 
        vif->sme_state = SME_DISCONNECTED;
@@ -3467,7 +3467,7 @@ void ath6kl_cfg80211_stop(struct ath6kl_vif *vif)
                                        GFP_KERNEL);
                break;
        case SME_CONNECTED:
-               cfg80211_disconnected(vif->ndev, 0, NULL, 0, GFP_KERNEL);
+               cfg80211_disconnected(vif->ndev, 0, NULL, 0, true, GFP_KERNEL);
                break;
        }
 
index c2a238426425462c7ff40f61c8e98fec9dadca6d..38b953e108a714d10b89b9cd61d1c2144376c191 100644 (file)
@@ -224,7 +224,7 @@ static void _wil6210_disconnect(struct wil6210_priv *wil, const u8 *bssid,
                if (test_bit(wil_status_fwconnected, wil->status)) {
                        clear_bit(wil_status_fwconnected, wil->status);
                        cfg80211_disconnected(ndev, reason_code,
-                                             NULL, 0, GFP_KERNEL);
+                                             NULL, 0, false, GFP_KERNEL);
                } else if (test_bit(wil_status_fwconnecting, wil->status)) {
                        cfg80211_connect_result(ndev, bssid, NULL, 0, NULL, 0,
                                                WLAN_STATUS_UNSPECIFIED_FAILURE,
index 6fe2b7564cbfc961829d71069801c9957414b437..e10fa67010c072f4d2377cd2e42ed3c3802157fe 100644 (file)
@@ -1296,7 +1296,7 @@ static void brcmf_link_down(struct brcmf_cfg80211_vif *vif, u16 reason)
                }
                clear_bit(BRCMF_VIF_STATUS_CONNECTED, &vif->sme_state);
                cfg80211_disconnected(vif->wdev.netdev, reason, NULL, 0,
-                                     GFP_KERNEL);
+                                     true, GFP_KERNEL);
 
        }
        clear_bit(BRCMF_VIF_STATUS_CONNECTING, &vif->sme_state);
@@ -1962,7 +1962,7 @@ brcmf_cfg80211_disconnect(struct wiphy *wiphy, struct net_device *ndev,
 
        clear_bit(BRCMF_VIF_STATUS_CONNECTED, &ifp->vif->sme_state);
        clear_bit(BRCMF_VIF_STATUS_CONNECTING, &ifp->vif->sme_state);
-       cfg80211_disconnected(ndev, reason_code, NULL, 0, GFP_KERNEL);
+       cfg80211_disconnected(ndev, reason_code, NULL, 0, true, GFP_KERNEL);
 
        memcpy(&scbval.ea, &profile->bssid, ETH_ALEN);
        scbval.val = cpu_to_le32(reason_code);
index 1a4d558022d8c1dff78b1181c6f9bc79e7573a12..8317afd065b498fd8001a0e83ec82c9b9a5284aa 100644 (file)
@@ -835,14 +835,13 @@ static int lbs_cfg_scan(struct wiphy *wiphy,
  * Events
  */
 
-void lbs_send_disconnect_notification(struct lbs_private *priv)
+void lbs_send_disconnect_notification(struct lbs_private *priv,
+                                     bool locally_generated)
 {
        lbs_deb_enter(LBS_DEB_CFG80211);
 
-       cfg80211_disconnected(priv->dev,
-               0,
-               NULL, 0,
-               GFP_KERNEL);
+       cfg80211_disconnected(priv->dev, 0, NULL, 0, locally_generated,
+                             GFP_KERNEL);
 
        lbs_deb_leave(LBS_DEB_CFG80211);
 }
@@ -1458,7 +1457,7 @@ int lbs_disconnect(struct lbs_private *priv, u16 reason)
 
        cfg80211_disconnected(priv->dev,
                        reason,
-                       NULL, 0,
+                       NULL, 0, true,
                        GFP_KERNEL);
        priv->connect_status = LBS_DISCONNECTED;
 
@@ -2031,7 +2030,7 @@ static int lbs_leave_ibss(struct wiphy *wiphy, struct net_device *dev)
        ret = lbs_cmd_with_response(priv, CMD_802_11_AD_HOC_STOP, &cmd);
 
        /* TODO: consider doing this at MACREG_INT_CODE_ADHOC_BCN_LOST time */
-       lbs_mac_event_disconnected(priv);
+       lbs_mac_event_disconnected(priv, true);
 
        lbs_deb_leave_args(LBS_DEB_CFG80211, "ret %d", ret);
        return ret;
index 10995f59fe34a1796db45e914196fc7a03248c07..acccc29224016456f40e152dbe2cae340b9f73e3 100644 (file)
@@ -10,7 +10,8 @@ struct wireless_dev *lbs_cfg_alloc(struct device *dev);
 int lbs_cfg_register(struct lbs_private *priv);
 void lbs_cfg_free(struct lbs_private *priv);
 
-void lbs_send_disconnect_notification(struct lbs_private *priv);
+void lbs_send_disconnect_notification(struct lbs_private *priv,
+                                     bool locally_generated);
 void lbs_send_mic_failureevent(struct lbs_private *priv, u32 event);
 
 void lbs_scan_done(struct lbs_private *priv);
index 4279e8ab95f2aa4545cef71daa5649b1314fdf3b..0c5444b02c64110d6f814983dd1bc8984ed442da 100644 (file)
@@ -68,7 +68,8 @@ int lbs_process_command_response(struct lbs_private *priv, u8 *data, u32 len);
 
 /* From cmdresp.c */
 
-void lbs_mac_event_disconnected(struct lbs_private *priv);
+void lbs_mac_event_disconnected(struct lbs_private *priv,
+                               bool locally_generated);
 
 
 
index 65f18f1e869c86559b1fb8f608a4819b4c3c965e..e5442e8956f7ac3b1182058864816dc700548fe5 100644 (file)
  * reset link state etc.
  *
  * @priv:      A pointer to struct lbs_private structure
+ * @locally_generated: indicates disconnect was requested locally
+ *             (usually by userspace)
  *
  * returns:    n/a
  */
-void lbs_mac_event_disconnected(struct lbs_private *priv)
+void lbs_mac_event_disconnected(struct lbs_private *priv,
+                               bool locally_generated)
 {
        if (priv->connect_status != LBS_CONNECTED)
                return;
@@ -36,7 +39,7 @@ void lbs_mac_event_disconnected(struct lbs_private *priv)
        msleep_interruptible(1000);
 
        if (priv->wdev->iftype == NL80211_IFTYPE_STATION)
-               lbs_send_disconnect_notification(priv);
+               lbs_send_disconnect_notification(priv, locally_generated);
 
        /* report disconnect to upper layer */
        netif_stop_queue(priv->dev);
@@ -229,17 +232,17 @@ int lbs_process_event(struct lbs_private *priv, u32 event)
 
        case MACREG_INT_CODE_DEAUTHENTICATED:
                lbs_deb_cmd("EVENT: deauthenticated\n");
-               lbs_mac_event_disconnected(priv);
+               lbs_mac_event_disconnected(priv, false);
                break;
 
        case MACREG_INT_CODE_DISASSOCIATED:
                lbs_deb_cmd("EVENT: disassociated\n");
-               lbs_mac_event_disconnected(priv);
+               lbs_mac_event_disconnected(priv, false);
                break;
 
        case MACREG_INT_CODE_LINK_LOST_NO_SCAN:
                lbs_deb_cmd("EVENT: link lost\n");
-               lbs_mac_event_disconnected(priv);
+               lbs_mac_event_disconnected(priv, true);
                break;
 
        case MACREG_INT_CODE_PS_SLEEP:
index f214a7cd13459874582e9170cc7e116afd530cf6..2ee48e7067bfc6b4a7bb596a589811a692d7f9bc 100644 (file)
@@ -1431,7 +1431,7 @@ int mwifiex_deauthenticate(struct mwifiex_private *priv, u8 *mac)
                ret = mwifiex_deauthenticate_infra(priv, mac);
                if (ret)
                        cfg80211_disconnected(priv->netdev, 0, NULL, 0,
-                                             GFP_KERNEL);
+                                             true, GFP_KERNEL);
                break;
        case NL80211_IFTYPE_ADHOC:
                return mwifiex_send_cmd(priv, HostCmd_CMD_802_11_AD_HOC_STOP,
index 0dc7a1d3993d325a15f84fa447afaa884349eabc..c9064b88d6a4d6bbe33da26d09c4e296e14c7ed0 100644 (file)
@@ -133,7 +133,7 @@ mwifiex_reset_connect_state(struct mwifiex_private *priv, u16 reason_code)
        if (priv->bss_mode == NL80211_IFTYPE_STATION ||
            priv->bss_mode == NL80211_IFTYPE_P2P_CLIENT) {
                cfg80211_disconnected(priv->netdev, reason_code, NULL, 0,
-                                     GFP_KERNEL);
+                                     false, GFP_KERNEL);
        }
        eth_zero_addr(priv->cfg_bssid);
 
index d72ff8e7125d4525d1761c60d3828dba22b63296..43db6976102f940c9e670f20996dd803467edb8a 100644 (file)
@@ -2861,7 +2861,7 @@ static void rndis_wlan_do_link_down_work(struct usbnet *usbdev)
 
                deauthenticate(usbdev);
 
-               cfg80211_disconnected(usbdev->net, 0, NULL, 0, GFP_KERNEL);
+               cfg80211_disconnected(usbdev->net, 0, NULL, 0, true, GFP_KERNEL);
        }
 
        netif_carrier_off(usbdev->net);
index bc95ce89af0671f97a7c7f1128dab96cbc442e39..5ab2f6978209d8ac165d717bdeec16f8c1810c4e 100644 (file)
@@ -379,7 +379,7 @@ void rtw_cfg80211_indicate_disconnect(struct rtw_adapter *padapter)
                                                GFP_ATOMIC);
                } else {
                        cfg80211_disconnected(padapter->pnetdev, 0, NULL,
-                                             0, GFP_ATOMIC);
+                                             0, false, GFP_ATOMIC);
                }
        }
 }
index 7c87aecf474444a908dd02f780a7649f9f93a187..342e2b30c48f92a5a1b98541e4af9cf2d2c40432 100644 (file)
@@ -722,7 +722,7 @@ void prism2_connect_result(wlandevice_t *wlandev, u8 failed)
 void prism2_disconnected(wlandevice_t *wlandev)
 {
        cfg80211_disconnected(wlandev->netdev, 0, NULL,
-               0, GFP_KERNEL);
+               0, false, GFP_KERNEL);
 }
 
 void prism2_roamed(wlandevice_t *wlandev)
index d63ecec730907fb15321114d2eec7262cdeeea64..a741678f24a26d712e08775e213b1b1c50c8ca8a 100644 (file)
@@ -4575,13 +4575,15 @@ void cfg80211_roamed_bss(struct net_device *dev, struct cfg80211_bss *bss,
  * @ie: information elements of the deauth/disassoc frame (may be %NULL)
  * @ie_len: length of IEs
  * @reason: reason code for the disconnection, set it to 0 if unknown
+ * @locally_generated: disconnection was requested locally
  * @gfp: allocation flags
  *
  * After it calls this function, the driver should enter an idle state
  * and not try to connect to any AP any more.
  */
 void cfg80211_disconnected(struct net_device *dev, u16 reason,
-                          const u8 *ie, size_t ie_len, gfp_t gfp);
+                          const u8 *ie, size_t ie_len,
+                          bool locally_generated, gfp_t gfp);
 
 /**
  * cfg80211_ready_on_channel - notification of remain_on_channel start
index 2f8b7decace0fb754a80a0a57851e2eaaaa8ddbe..887fe95b980547d81b00b8be2648a8415bdc8429 100644 (file)
@@ -1728,8 +1728,7 @@ struct ieee80211_tx_control {
  * @sta: station table entry, %NULL for per-vif queue
  * @tid: the TID for this queue (unused for per-vif queue)
  * @ac: the AC for this queue
- * @drv_priv: data area for driver use, will always be aligned to
- *     sizeof(void *).
+ * @drv_priv: driver private area, sized by hw->txq_data_size
  *
  * The driver can obtain packets from this queue by calling
  * ieee80211_tx_dequeue().
index 3469bbdc891c35afe10017fe4d9450c29955a1f0..bb9f83640b46526741026ada9191f868ecfce8fa 100644 (file)
@@ -1411,6 +1411,7 @@ static int ieee80211_change_station(struct wiphy *wiphy,
                }
 
                sta->sdata = vlansdata;
+               ieee80211_check_fast_xmit(sta);
 
                if (sta->sta_state == IEEE80211_STA_AUTHORIZED &&
                    prev_4addr != new_4addr) {
index 3c956c5f99b2886bcd0516ee4ba598c02fb839bb..674164fe5cdba12156b15e8e8a493e56b90dbb6e 100644 (file)
@@ -246,6 +246,7 @@ static void ieee80211_restart_work(struct work_struct *work)
 {
        struct ieee80211_local *local =
                container_of(work, struct ieee80211_local, restart_work);
+       struct ieee80211_sub_if_data *sdata;
 
        /* wait for scan work complete */
        flush_workqueue(local->workqueue);
@@ -254,6 +255,8 @@ static void ieee80211_restart_work(struct work_struct *work)
             "%s called with hardware scan in progress\n", __func__);
 
        rtnl_lock();
+       list_for_each_entry(sdata, &local->interfaces, list)
+               flush_delayed_work(&sdata->dec_tailroom_needed_wk);
        ieee80211_scan_cancel(local);
        ieee80211_reconfig(local);
        rtnl_unlock();
@@ -770,8 +773,10 @@ static int ieee80211_init_cipher_suites(struct ieee80211_local *local)
 
                for (r = 0; r < local->hw.n_cipher_schemes; r++) {
                        suites[w++] = cs[r].cipher;
-                       if (WARN_ON(cs[r].pn_len > IEEE80211_MAX_PN_LEN))
+                       if (WARN_ON(cs[r].pn_len > IEEE80211_MAX_PN_LEN)) {
+                               kfree(suites);
                                return -EINVAL;
+                       }
                }
        }
 
index 3294666f599c73e9039a26d3ac505b695d51fbd2..387fe70ab12641bcf5c3371ee36aa5320628935a 100644 (file)
@@ -1098,6 +1098,24 @@ static void ieee80211_chswitch_timer(unsigned long data)
        ieee80211_queue_work(&sdata->local->hw, &sdata->u.mgd.chswitch_work);
 }
 
+static void ieee80211_teardown_tdls_peers(struct ieee80211_sub_if_data *sdata)
+{
+       struct sta_info *sta;
+       u16 reason = WLAN_REASON_TDLS_TEARDOWN_UNSPECIFIED;
+
+       rcu_read_lock();
+       list_for_each_entry_rcu(sta, &sdata->local->sta_list, list) {
+               if (!sta->sta.tdls || sta->sdata != sdata || !sta->uploaded ||
+                   !test_sta_flag(sta, WLAN_STA_AUTHORIZED))
+                       continue;
+
+               ieee80211_tdls_oper_request(&sdata->vif, sta->sta.addr,
+                                           NL80211_TDLS_TEARDOWN, reason,
+                                           GFP_ATOMIC);
+       }
+       rcu_read_unlock();
+}
+
 static void
 ieee80211_sta_process_chanswitch(struct ieee80211_sub_if_data *sdata,
                                 u64 timestamp, u32 device_timestamp,
@@ -1161,6 +1179,14 @@ ieee80211_sta_process_chanswitch(struct ieee80211_sub_if_data *sdata,
                return;
        }
 
+       /*
+        * Drop all TDLS peers - either we disconnect or move to a different
+        * channel from this point on. There's no telling what our peer will do.
+        * The TDLS WIDER_BW scenario is also problematic, as peers might now
+        * have an incompatible wider chandef.
+        */
+       ieee80211_teardown_tdls_peers(sdata);
+
        mutex_lock(&local->mtx);
        mutex_lock(&local->chanctx_mtx);
        conf = rcu_dereference_protected(sdata->vif.chanctx_conf,
index 8a92a920ff17fa78b76640439f5ed81fd7a0ccb3..75e8e3bba538a3e15b8a1ec392e594df5a9dbe47 100644 (file)
@@ -1183,6 +1183,12 @@ int ieee80211_tdls_oper(struct wiphy *wiphy, struct net_device *dev,
 
        switch (oper) {
        case NL80211_TDLS_ENABLE_LINK:
+               if (sdata->vif.csa_active) {
+                       tdls_dbg(sdata, "TDLS: disallow link during CSA\n");
+                       ret = -EBUSY;
+                       break;
+               }
+
                rcu_read_lock();
                sta = sta_info_get(sdata, peer);
                if (!sta) {
index fa7cd792791cbbd5234de865a53330daedb834db..f12149a29cb19b1b508b30528dc3bfd032799622 100644 (file)
@@ -794,7 +794,8 @@ void rfkill_resume_polling(struct rfkill *rfkill)
 }
 EXPORT_SYMBOL(rfkill_resume_polling);
 
-static int rfkill_suspend(struct device *dev, pm_message_t state)
+#ifdef CONFIG_PM_SLEEP
+static int rfkill_suspend(struct device *dev)
 {
        struct rfkill *rfkill = to_rfkill(dev);
 
@@ -818,13 +819,18 @@ static int rfkill_resume(struct device *dev)
        return 0;
 }
 
+static SIMPLE_DEV_PM_OPS(rfkill_pm_ops, rfkill_suspend, rfkill_resume);
+#define RFKILL_PM_OPS (&rfkill_pm_ops)
+#else
+#define RFKILL_PM_OPS NULL
+#endif
+
 static struct class rfkill_class = {
        .name           = "rfkill",
        .dev_release    = rfkill_release,
        .dev_groups     = rfkill_dev_groups,
        .dev_uevent     = rfkill_dev_uevent,
-       .suspend        = rfkill_suspend,
-       .resume         = rfkill_resume,
+       .pm             = RFKILL_PM_OPS,
 };
 
 bool rfkill_blocked(struct rfkill *rfkill)
index d978f2f46ff35e0181e2a833e3bfab2b6d58221e..d5d58d9195524f36b03bdac0125148cb7110901a 100644 (file)
@@ -112,21 +112,17 @@ static int rfkill_gpio_probe(struct platform_device *pdev)
 
        rfkill->clk = devm_clk_get(&pdev->dev, NULL);
 
-       gpio = devm_gpiod_get(&pdev->dev, "reset");
-       if (!IS_ERR(gpio)) {
-               ret = gpiod_direction_output(gpio, 0);
-               if (ret)
-                       return ret;
-               rfkill->reset_gpio = gpio;
-       }
+       gpio = devm_gpiod_get_optional(&pdev->dev, "reset", GPIOD_OUT_LOW);
+       if (IS_ERR(gpio))
+               return PTR_ERR(gpio);
 
-       gpio = devm_gpiod_get(&pdev->dev, "shutdown");
-       if (!IS_ERR(gpio)) {
-               ret = gpiod_direction_output(gpio, 0);
-               if (ret)
-                       return ret;
-               rfkill->shutdown_gpio = gpio;
-       }
+       rfkill->reset_gpio = gpio;
+
+       gpio = devm_gpiod_get_optional(&pdev->dev, "shutdown", GPIOD_OUT_LOW);
+       if (IS_ERR(gpio))
+               return PTR_ERR(gpio);
+
+       rfkill->shutdown_gpio = gpio;
 
        /* Make sure at-least one of the GPIO is defined and that
         * a name is specified for this instance
index 801cd49c5a0c5f2748ff4aba595d865645208745..311eef26bf88b9a0e8125678498583fa19edf688 100644 (file)
@@ -222,6 +222,7 @@ struct cfg80211_event {
                        const u8 *ie;
                        size_t ie_len;
                        u16 reason;
+                       bool locally_generated;
                } dc;
                struct {
                        u8 bssid[ETH_ALEN];
index d11454f87bacf9396241bd5bbc3ba643ef0b3302..8020b5b094d4c8fba0c0f2431f8af7d8ecc40dca 100644 (file)
@@ -938,7 +938,8 @@ void __cfg80211_disconnected(struct net_device *dev, const u8 *ie,
 }
 
 void cfg80211_disconnected(struct net_device *dev, u16 reason,
-                          const u8 *ie, size_t ie_len, gfp_t gfp)
+                          const u8 *ie, size_t ie_len,
+                          bool locally_generated, gfp_t gfp)
 {
        struct wireless_dev *wdev = dev->ieee80211_ptr;
        struct cfg80211_registered_device *rdev = wiphy_to_rdev(wdev->wiphy);
@@ -954,6 +955,7 @@ void cfg80211_disconnected(struct net_device *dev, u16 reason,
        ev->dc.ie_len = ie_len;
        memcpy((void *)ev->dc.ie, ie, ie_len);
        ev->dc.reason = reason;
+       ev->dc.locally_generated = locally_generated;
 
        spin_lock_irqsave(&wdev->event_lock, flags);
        list_add_tail(&ev->list, &wdev->event_list);
index 9ee6bc1a761022dc551fd42f8e68426214d93cd4..9cee0220665d356b7f2b9734ca888ccfae8c0d1c 100644 (file)
@@ -86,7 +86,7 @@ static int wiphy_uevent(struct device *dev, struct kobj_uevent_env *env)
        return 0;
 }
 
-#ifdef CONFIG_PM
+#ifdef CONFIG_PM_SLEEP
 static void cfg80211_leave_all(struct cfg80211_registered_device *rdev)
 {
        struct wireless_dev *wdev;
@@ -95,7 +95,7 @@ static void cfg80211_leave_all(struct cfg80211_registered_device *rdev)
                cfg80211_leave(rdev, wdev);
 }
 
-static int wiphy_suspend(struct device *dev, pm_message_t state)
+static int wiphy_suspend(struct device *dev)
 {
        struct cfg80211_registered_device *rdev = dev_to_rdev(dev);
        int ret = 0;
@@ -136,6 +136,11 @@ static int wiphy_resume(struct device *dev)
 
        return ret;
 }
+
+static SIMPLE_DEV_PM_OPS(wiphy_pm_ops, wiphy_suspend, wiphy_resume);
+#define WIPHY_PM_OPS (&wiphy_pm_ops)
+#else
+#define WIPHY_PM_OPS NULL
 #endif
 
 static const void *wiphy_namespace(struct device *d)
@@ -151,10 +156,7 @@ struct class ieee80211_class = {
        .dev_release = wiphy_dev_release,
        .dev_groups = ieee80211_groups,
        .dev_uevent = wiphy_uevent,
-#ifdef CONFIG_PM
-       .suspend = wiphy_suspend,
-       .resume = wiphy_resume,
-#endif
+       .pm = WIPHY_PM_OPS,
        .ns_type = &net_ns_type_operations,
        .namespace = wiphy_namespace,
 };
index 70051ab52f4f34d2817e76210aafa70bbda62e60..baf7218cec152bb9f894ba47145cec75b9a86123 100644 (file)
@@ -887,7 +887,8 @@ void cfg80211_process_wdev_events(struct wireless_dev *wdev)
                case EVENT_DISCONNECTED:
                        __cfg80211_disconnected(wdev->netdev,
                                                ev->dc.ie, ev->dc.ie_len,
-                                               ev->dc.reason, true);
+                                               ev->dc.reason,
+                                               !ev->dc.locally_generated);
                        break;
                case EVENT_IBSS_JOINED:
                        __cfg80211_ibss_joined(wdev->netdev, ev->ij.bssid,
@@ -944,7 +945,7 @@ int cfg80211_change_iface(struct cfg80211_registered_device *rdev,
             ntype == NL80211_IFTYPE_P2P_CLIENT))
                return -EBUSY;
 
-       if (ntype != otype && netif_running(dev)) {
+       if (ntype != otype) {
                dev->ieee80211_ptr->use_4addr = false;
                dev->ieee80211_ptr->mesh_id_up_len = 0;
                wdev_lock(dev->ieee80211_ptr);