]> git.proxmox.com Git - mirror_ubuntu-artful-kernel.git/commitdiff
Merge branch 'for-john' of git://git.kernel.org/pub/scm/linux/kernel/git/iwlwifi...
authorJohn W. Linville <linville@tuxdriver.com>
Fri, 9 Aug 2013 17:49:10 +0000 (13:49 -0400)
committerJohn W. Linville <linville@tuxdriver.com>
Fri, 9 Aug 2013 17:49:10 +0000 (13:49 -0400)
60 files changed:
MAINTAINERS
drivers/bluetooth/ath3k.c
drivers/bluetooth/btusb.c
drivers/net/wireless/ath/ath10k/Kconfig
drivers/net/wireless/ath/ath5k/mac80211-ops.c
drivers/net/wireless/ath/ath9k/ar5008_phy.c
drivers/net/wireless/ath/ath9k/hif_usb.c
drivers/net/wireless/ath/ath9k/htc_drv_init.c
drivers/net/wireless/ath/ath9k/xmit.c
drivers/net/wireless/ath/wil6210/debugfs.c
drivers/net/wireless/brcm80211/brcmfmac/dhd_linux.c
drivers/net/wireless/brcm80211/brcmfmac/fwsignal.c
drivers/net/wireless/brcm80211/brcmfmac/wl_cfg80211.c
drivers/net/wireless/cw1200/sta.c
drivers/net/wireless/cw1200/txrx.c
drivers/net/wireless/iwlegacy/4965-mac.c
drivers/net/wireless/iwlegacy/common.c
drivers/net/wireless/mwifiex/cfg80211.c
drivers/net/wireless/mwifiex/cfp.c
drivers/net/wireless/mwifiex/init.c
drivers/net/wireless/mwifiex/join.c
drivers/net/wireless/mwifiex/main.c
drivers/net/wireless/mwifiex/main.h
drivers/net/wireless/mwifiex/sdio.c
drivers/net/wireless/mwifiex/sdio.h
drivers/net/wireless/mwifiex/sta_ioctl.c
drivers/net/wireless/rt2x00/Kconfig
drivers/net/wireless/rt2x00/rt2x00queue.c
drivers/net/wireless/rtlwifi/Kconfig
drivers/net/wireless/rtlwifi/Makefile
drivers/net/wireless/rtlwifi/base.c
drivers/net/wireless/rtlwifi/base.h
drivers/net/wireless/rtlwifi/core.c
drivers/net/wireless/rtlwifi/debug.c
drivers/net/wireless/rtlwifi/efuse.c
drivers/net/wireless/rtlwifi/pci.c
drivers/net/wireless/rtlwifi/ps.c
drivers/net/wireless/rtlwifi/ps.h
drivers/net/wireless/rtlwifi/usb.c
include/linux/mod_devicetable.h
include/net/nfc/hci.h
include/net/nfc/nfc.h
include/uapi/linux/nfc.h
net/bluetooth/hci_core.c
net/mac80211/cfg.c
net/mac80211/mesh_ps.c
net/mac80211/mlme.c
net/mac80211/pm.c
net/mac80211/rc80211_minstrel.c
net/mac80211/rc80211_minstrel_ht.c
net/mac80211/rx.c
net/nfc/core.c
net/nfc/hci/core.c
net/nfc/nci/Kconfig
net/nfc/netlink.c
net/nfc/nfc.h
net/wireless/core.c
net/wireless/nl80211.c
net/wireless/reg.c
net/wireless/sme.c

index bf61e04291abb2f2200544517ab144c89cb3ab8e..6447bec7f33fbe6a95b619057c2bc1a5fb9a0fbd 100644 (file)
@@ -1406,7 +1406,7 @@ ATHEROS ATH6KL WIRELESS DRIVER
 M:     Kalle Valo <kvalo@qca.qualcomm.com>
 L:     linux-wireless@vger.kernel.org
 W:     http://wireless.kernel.org/en/users/Drivers/ath6kl
-T:     git git://git.kernel.org/pub/scm/linux/kernel/git/kvalo/ath6kl.git
+T:     git git://github.com/kvalo/ath.git
 S:     Supported
 F:     drivers/net/wireless/ath/ath6kl/
 
@@ -6719,6 +6719,14 @@ T:       git git://linuxtv.org/anttip/media_tree.git
 S:     Maintained
 F:     drivers/media/tuners/qt1010*
 
+QUALCOMM ATHEROS ATH10K WIRELESS DRIVER
+M:     Kalle Valo <kvalo@qca.qualcomm.com>
+L:     ath10k@lists.infradead.org
+W:     http://wireless.kernel.org/en/users/Drivers/ath10k
+T:     git git://github.com/kvalo/ath.git
+S:     Supported
+F:     drivers/net/wireless/ath/ath10k/
+
 QUALCOMM HEXAGON ARCHITECTURE
 M:     Richard Kuo <rkuo@codeaurora.org>
 L:     linux-hexagon@vger.kernel.org
@@ -8264,7 +8272,7 @@ S:        Maintained
 F:     sound/soc/codecs/twl4030*
 
 TI WILINK WIRELESS DRIVERS
-M:     Luciano Coelho <coelho@ti.com>
+M:     Luciano Coelho <luca@coelho.fi>
 L:     linux-wireless@vger.kernel.org
 W:     http://wireless.kernel.org/en/users/Drivers/wl12xx
 W:     http://wireless.kernel.org/en/users/Drivers/wl1251
index 11f467c00d0ac836a1c6509bffd31e49b891a844..a12b923bbaca91f14b923e0b271b00ebc1be8d28 100644 (file)
@@ -91,6 +91,10 @@ static struct usb_device_id ath3k_table[] = {
        { USB_DEVICE(0x0489, 0xe04e) },
        { USB_DEVICE(0x0489, 0xe056) },
        { USB_DEVICE(0x0489, 0xe04d) },
+       { USB_DEVICE(0x04c5, 0x1330) },
+       { USB_DEVICE(0x13d3, 0x3402) },
+       { USB_DEVICE(0x0cf3, 0x3121) },
+       { USB_DEVICE(0x0cf3, 0xe003) },
 
        /* Atheros AR5BBU12 with sflash firmware */
        { USB_DEVICE(0x0489, 0xE02C) },
@@ -128,6 +132,10 @@ static struct usb_device_id ath3k_blist_tbl[] = {
        { USB_DEVICE(0x0489, 0xe04e), .driver_info = BTUSB_ATH3012 },
        { USB_DEVICE(0x0489, 0xe056), .driver_info = BTUSB_ATH3012 },
        { USB_DEVICE(0x0489, 0xe04d), .driver_info = BTUSB_ATH3012 },
+       { USB_DEVICE(0x04c5, 0x1330), .driver_info = BTUSB_ATH3012 },
+       { USB_DEVICE(0x13d3, 0x3402), .driver_info = BTUSB_ATH3012 },
+       { USB_DEVICE(0x0cf3, 0x3121), .driver_info = BTUSB_ATH3012 },
+       { USB_DEVICE(0x0cf3, 0xe003), .driver_info = BTUSB_ATH3012 },
 
        /* Atheros AR5BBU22 with sflash firmware */
        { USB_DEVICE(0x0489, 0xE03C), .driver_info = BTUSB_ATH3012 },
@@ -193,24 +201,44 @@ error:
 
 static int ath3k_get_state(struct usb_device *udev, unsigned char *state)
 {
-       int pipe = 0;
+       int ret, pipe = 0;
+       char *buf;
+
+       buf = kmalloc(sizeof(*buf), GFP_KERNEL);
+       if (!buf)
+               return -ENOMEM;
 
        pipe = usb_rcvctrlpipe(udev, 0);
-       return usb_control_msg(udev, pipe, ATH3K_GETSTATE,
-                       USB_TYPE_VENDOR | USB_DIR_IN, 0, 0,
-                       state, 0x01, USB_CTRL_SET_TIMEOUT);
+       ret = usb_control_msg(udev, pipe, ATH3K_GETSTATE,
+                             USB_TYPE_VENDOR | USB_DIR_IN, 0, 0,
+                             buf, sizeof(*buf), USB_CTRL_SET_TIMEOUT);
+
+       *state = *buf;
+       kfree(buf);
+
+       return ret;
 }
 
 static int ath3k_get_version(struct usb_device *udev,
                        struct ath3k_version *version)
 {
-       int pipe = 0;
+       int ret, pipe = 0;
+       struct ath3k_version *buf;
+       const int size = sizeof(*buf);
+
+       buf = kmalloc(size, GFP_KERNEL);
+       if (!buf)
+               return -ENOMEM;
 
        pipe = usb_rcvctrlpipe(udev, 0);
-       return usb_control_msg(udev, pipe, ATH3K_GETVERSION,
-                       USB_TYPE_VENDOR | USB_DIR_IN, 0, 0, version,
-                       sizeof(struct ath3k_version),
-                       USB_CTRL_SET_TIMEOUT);
+       ret = usb_control_msg(udev, pipe, ATH3K_GETVERSION,
+                             USB_TYPE_VENDOR | USB_DIR_IN, 0, 0,
+                             buf, size, USB_CTRL_SET_TIMEOUT);
+
+       memcpy(version, buf, size);
+       kfree(buf);
+
+       return ret;
 }
 
 static int ath3k_load_fwfile(struct usb_device *udev,
index de4cf4daa2f4cefa3a270ccaf8e4e8fb22af1015..8e16f0af6358872606fbe102bddc9ade2c6ab470 100644 (file)
@@ -154,6 +154,10 @@ static struct usb_device_id blacklist_table[] = {
        { USB_DEVICE(0x0489, 0xe04e), .driver_info = BTUSB_ATH3012 },
        { USB_DEVICE(0x0489, 0xe056), .driver_info = BTUSB_ATH3012 },
        { USB_DEVICE(0x0489, 0xe04d), .driver_info = BTUSB_ATH3012 },
+       { USB_DEVICE(0x04c5, 0x1330), .driver_info = BTUSB_ATH3012 },
+       { USB_DEVICE(0x13d3, 0x3402), .driver_info = BTUSB_ATH3012 },
+       { USB_DEVICE(0x0cf3, 0x3121), .driver_info = BTUSB_ATH3012 },
+       { USB_DEVICE(0x0cf3, 0xe003), .driver_info = BTUSB_ATH3012 },
 
        /* Atheros AR5BBU12 with sflash firmware */
        { USB_DEVICE(0x0489, 0xe02c), .driver_info = BTUSB_IGNORE },
@@ -1095,7 +1099,7 @@ static int btusb_setup_intel_patching(struct hci_dev *hdev,
        if (IS_ERR(skb)) {
                BT_ERR("%s sending Intel patch command (0x%4.4x) failed (%ld)",
                       hdev->name, cmd->opcode, PTR_ERR(skb));
-               return -PTR_ERR(skb);
+               return PTR_ERR(skb);
        }
 
        /* It ensures that the returned event matches the event data read from
@@ -1147,7 +1151,7 @@ static int btusb_setup_intel(struct hci_dev *hdev)
        if (IS_ERR(skb)) {
                BT_ERR("%s sending initial HCI reset command failed (%ld)",
                       hdev->name, PTR_ERR(skb));
-               return -PTR_ERR(skb);
+               return PTR_ERR(skb);
        }
        kfree_skb(skb);
 
@@ -1161,7 +1165,7 @@ static int btusb_setup_intel(struct hci_dev *hdev)
        if (IS_ERR(skb)) {
                BT_ERR("%s reading Intel fw version command failed (%ld)",
                       hdev->name, PTR_ERR(skb));
-               return -PTR_ERR(skb);
+               return PTR_ERR(skb);
        }
 
        if (skb->len != sizeof(*ver)) {
@@ -1219,7 +1223,7 @@ static int btusb_setup_intel(struct hci_dev *hdev)
                BT_ERR("%s entering Intel manufacturer mode failed (%ld)",
                       hdev->name, PTR_ERR(skb));
                release_firmware(fw);
-               return -PTR_ERR(skb);
+               return PTR_ERR(skb);
        }
 
        if (skb->data[0]) {
@@ -1276,7 +1280,7 @@ static int btusb_setup_intel(struct hci_dev *hdev)
        if (IS_ERR(skb)) {
                BT_ERR("%s exiting Intel manufacturer mode failed (%ld)",
                       hdev->name, PTR_ERR(skb));
-               return -PTR_ERR(skb);
+               return PTR_ERR(skb);
        }
        kfree_skb(skb);
 
@@ -1292,7 +1296,7 @@ exit_mfg_disable:
        if (IS_ERR(skb)) {
                BT_ERR("%s exiting Intel manufacturer mode failed (%ld)",
                       hdev->name, PTR_ERR(skb));
-               return -PTR_ERR(skb);
+               return PTR_ERR(skb);
        }
        kfree_skb(skb);
 
@@ -1310,7 +1314,7 @@ exit_mfg_deactivate:
        if (IS_ERR(skb)) {
                BT_ERR("%s exiting Intel manufacturer mode failed (%ld)",
                       hdev->name, PTR_ERR(skb));
-               return -PTR_ERR(skb);
+               return PTR_ERR(skb);
        }
        kfree_skb(skb);
 
index cde58fe962543dff415d45f2be2ae06d0d7ceb91..82e8088ca9b4944e5cb13c3fb3c2b14c7af27efe 100644 (file)
@@ -1,6 +1,6 @@
 config ATH10K
         tristate "Atheros 802.11ac wireless cards support"
-        depends on MAC80211
+        depends on MAC80211 && HAS_DMA
        select ATH_COMMON
         ---help---
           This module adds support for wireless adapters based on
index 81b686c6a3764111e8c8e969a90d36d6ced054ea..40825d43322edb511862c90bd2587395745852e7 100644 (file)
@@ -325,7 +325,7 @@ ath5k_prepare_multicast(struct ieee80211_hw *hw,
        struct netdev_hw_addr *ha;
 
        mfilt[0] = 0;
-       mfilt[1] = 1;
+       mfilt[1] = 0;
 
        netdev_hw_addr_list_for_each(ha, mc_list) {
                /* calculate XOR of eight 6-bit values */
index d1acfe98918a2a50689c2760ed6455cf2c239b2a..1576d58291d457612ddeadf0933904bf6f552d3a 100644 (file)
@@ -610,7 +610,15 @@ static void ar5008_hw_override_ini(struct ath_hw *ah,
        REG_SET_BIT(ah, AR_DIAG_SW, (AR_DIAG_RX_DIS | AR_DIAG_RX_ABORT));
 
        if (AR_SREV_9280_20_OR_LATER(ah)) {
-               val = REG_READ(ah, AR_PCU_MISC_MODE2);
+               /*
+                * For AR9280 and above, there is a new feature that allows
+                * Multicast search based on both MAC Address and Key ID.
+                * By default, this feature is enabled. But since the driver
+                * is not using this feature, we switch it off; otherwise
+                * multicast search based on MAC addr only will fail.
+                */
+               val = REG_READ(ah, AR_PCU_MISC_MODE2) &
+                       (~AR_ADHOC_MCAST_KEYID_ENABLE);
 
                if (!AR_SREV_9271(ah))
                        val &= ~AR_PCU_MISC_MODE2_HWWAR1;
index 9e582e14da74609361b689e5f5741d425fd14659..5205a3625e849f3f6d3d775bb7b4b8f866aebca4 100644 (file)
@@ -1082,7 +1082,7 @@ static void ath9k_hif_usb_firmware_fail(struct hif_device_usb *hif_dev)
        struct device *dev = &hif_dev->udev->dev;
        struct device *parent = dev->parent;
 
-       complete(&hif_dev->fw_done);
+       complete_all(&hif_dev->fw_done);
 
        if (parent)
                device_lock(parent);
@@ -1131,7 +1131,7 @@ static void ath9k_hif_usb_firmware_cb(const struct firmware *fw, void *context)
 
        release_firmware(fw);
        hif_dev->flags |= HIF_USB_READY;
-       complete(&hif_dev->fw_done);
+       complete_all(&hif_dev->fw_done);
 
        return;
 
@@ -1295,7 +1295,9 @@ static void ath9k_hif_usb_disconnect(struct usb_interface *interface)
 
        usb_set_intfdata(interface, NULL);
 
-       if (!unplugged && (hif_dev->flags & HIF_USB_START))
+       /* If firmware was loaded we should drop it
+        * go back to first stage bootloader. */
+       if (!unplugged && (hif_dev->flags & HIF_USB_READY))
                ath9k_hif_usb_reboot(udev);
 
        kfree(hif_dev);
@@ -1316,7 +1318,10 @@ static int ath9k_hif_usb_suspend(struct usb_interface *interface,
        if (!(hif_dev->flags & HIF_USB_START))
                ath9k_htc_suspend(hif_dev->htc_handle);
 
-       ath9k_hif_usb_dealloc_urbs(hif_dev);
+       wait_for_completion(&hif_dev->fw_done);
+
+       if (hif_dev->flags & HIF_USB_READY)
+               ath9k_hif_usb_dealloc_urbs(hif_dev);
 
        return 0;
 }
index 71a183ffc77faf04f590b3d9454d1fb3c798ccaf..c3676bf1d6c45ab92d8a161d18ad5f3f0c586d18 100644 (file)
@@ -861,6 +861,7 @@ static int ath9k_init_device(struct ath9k_htc_priv *priv,
        if (error != 0)
                goto err_rx;
 
+       ath9k_hw_disable(priv->ah);
 #ifdef CONFIG_MAC80211_LEDS
        /* must be initialized before ieee80211_register_hw */
        priv->led_cdev.default_trigger = ieee80211_create_tpt_led_trigger(priv->hw,
index c59ae43b9b35aeba9356f499a83f73ae02e96a8b..9279927326203d02f421233b9456f074cb92e5ec 100644 (file)
@@ -146,6 +146,28 @@ static void ath_set_rates(struct ieee80211_vif *vif, struct ieee80211_sta *sta,
                               ARRAY_SIZE(bf->rates));
 }
 
+static void ath_txq_skb_done(struct ath_softc *sc, struct ath_txq *txq,
+                            struct sk_buff *skb)
+{
+       int q;
+
+       q = skb_get_queue_mapping(skb);
+       if (txq == sc->tx.uapsdq)
+               txq = sc->tx.txq_map[q];
+
+       if (txq != sc->tx.txq_map[q])
+               return;
+
+       if (WARN_ON(--txq->pending_frames < 0))
+               txq->pending_frames = 0;
+
+       if (txq->stopped &&
+           txq->pending_frames < sc->tx.txq_max_pending[q]) {
+               ieee80211_wake_queue(sc->hw, q);
+               txq->stopped = false;
+       }
+}
+
 static void ath_tx_flush_tid(struct ath_softc *sc, struct ath_atx_tid *tid)
 {
        struct ath_txq *txq = tid->ac->txq;
@@ -167,6 +189,7 @@ static void ath_tx_flush_tid(struct ath_softc *sc, struct ath_atx_tid *tid)
                if (!bf) {
                        bf = ath_tx_setup_buffer(sc, txq, tid, skb);
                        if (!bf) {
+                               ath_txq_skb_done(sc, txq, skb);
                                ieee80211_free_txskb(sc->hw, skb);
                                continue;
                        }
@@ -811,6 +834,7 @@ ath_tx_get_tid_subframe(struct ath_softc *sc, struct ath_txq *txq,
 
                if (!bf) {
                        __skb_unlink(skb, &tid->buf_q);
+                       ath_txq_skb_done(sc, txq, skb);
                        ieee80211_free_txskb(sc->hw, skb);
                        continue;
                }
@@ -1824,6 +1848,7 @@ static void ath_tx_send_ampdu(struct ath_softc *sc, struct ath_txq *txq,
 
        bf = ath_tx_setup_buffer(sc, txq, tid, skb);
        if (!bf) {
+               ath_txq_skb_done(sc, txq, skb);
                ieee80211_free_txskb(sc->hw, skb);
                return;
        }
@@ -2090,6 +2115,7 @@ int ath_tx_start(struct ieee80211_hw *hw, struct sk_buff *skb,
 
        bf = ath_tx_setup_buffer(sc, txq, tid, skb);
        if (!bf) {
+               ath_txq_skb_done(sc, txq, skb);
                if (txctl->paprd)
                        dev_kfree_skb_any(skb);
                else
@@ -2189,7 +2215,7 @@ static void ath_tx_complete(struct ath_softc *sc, struct sk_buff *skb,
        struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(skb);
        struct ath_common *common = ath9k_hw_common(sc->sc_ah);
        struct ieee80211_hdr * hdr = (struct ieee80211_hdr *)skb->data;
-       int q, padpos, padsize;
+       int padpos, padsize;
        unsigned long flags;
 
        ath_dbg(common, XMIT, "TX complete: skb: %p\n", skb);
@@ -2225,21 +2251,7 @@ static void ath_tx_complete(struct ath_softc *sc, struct sk_buff *skb,
        spin_unlock_irqrestore(&sc->sc_pm_lock, flags);
 
        __skb_queue_tail(&txq->complete_q, skb);
-
-       q = skb_get_queue_mapping(skb);
-       if (txq == sc->tx.uapsdq)
-               txq = sc->tx.txq_map[q];
-
-       if (txq == sc->tx.txq_map[q]) {
-               if (WARN_ON(--txq->pending_frames < 0))
-                       txq->pending_frames = 0;
-
-               if (txq->stopped &&
-                   txq->pending_frames < sc->tx.txq_max_pending[q]) {
-                       ieee80211_wake_queue(sc->hw, q);
-                       txq->stopped = false;
-               }
-       }
+       ath_txq_skb_done(sc, txq, skb);
 }
 
 static void ath_tx_complete_buf(struct ath_softc *sc, struct ath_buf *bf,
index e8308ec309704958b1754c06dbeb7b3fef9f452b..ab636767fbde098ce41bd952aa7d950b6932cb28 100644 (file)
@@ -145,7 +145,7 @@ static void wil_print_ring(struct seq_file *s, const char *prefix,
                                   le16_to_cpu(hdr.type), hdr.flags);
                        if (len <= MAX_MBOXITEM_SIZE) {
                                int n = 0;
-                               unsigned char printbuf[16 * 3 + 2];
+                               char printbuf[16 * 3 + 2];
                                unsigned char databuf[MAX_MBOXITEM_SIZE];
                                void __iomem *src = wmi_buffer(wil, d.addr) +
                                        sizeof(struct wil6210_mbox_hdr);
@@ -416,7 +416,7 @@ static int wil_txdesc_debugfs_show(struct seq_file *s, void *data)
                seq_printf(s, "  SKB = %p\n", skb);
 
                if (skb) {
-                       unsigned char printbuf[16 * 3 + 2];
+                       char printbuf[16 * 3 + 2];
                        int i = 0;
                        int len = le16_to_cpu(d->dma.length);
                        void *p = skb->data;
index 8e8975562ec3b819ff20b32de938a3b012b6671b..80099016d21f4a04cb22b5e3b98ccd84608e658a 100644 (file)
@@ -242,7 +242,7 @@ void brcmf_txflowblock_if(struct brcmf_if *ifp,
 {
        unsigned long flags;
 
-       if (!ifp)
+       if (!ifp || !ifp->ndev)
                return;
 
        brcmf_dbg(TRACE, "enter: idx=%d stop=0x%X reason=%d state=%d\n",
index f0d9f7f6c83d70fbd677175b43ebe70f306795eb..29b1f24c2d0f92c86a55dade5e0e61a943004608 100644 (file)
@@ -1744,13 +1744,14 @@ int brcmf_fws_process_skb(struct brcmf_if *ifp, struct sk_buff *skb)
        ulong flags;
        int fifo = BRCMF_FWS_FIFO_BCMC;
        bool multicast = is_multicast_ether_addr(eh->h_dest);
+       bool pae = eh->h_proto == htons(ETH_P_PAE);
 
        /* determine the priority */
        if (!skb->priority)
                skb->priority = cfg80211_classify8021d(skb);
 
        drvr->tx_multicast += !!multicast;
-       if (ntohs(eh->h_proto) == ETH_P_PAE)
+       if (pae)
                atomic_inc(&ifp->pend_8021x_cnt);
 
        if (!brcmf_fws_fc_active(fws)) {
@@ -1781,6 +1782,11 @@ int brcmf_fws_process_skb(struct brcmf_if *ifp, struct sk_buff *skb)
                brcmf_fws_schedule_deq(fws);
        } else {
                brcmf_err("drop skb: no hanger slot\n");
+               if (pae) {
+                       atomic_dec(&ifp->pend_8021x_cnt);
+                       if (waitqueue_active(&ifp->pend_8021x_wait))
+                               wake_up(&ifp->pend_8021x_wait);
+               }
                brcmu_pkt_buf_free_skb(skb);
        }
        brcmf_fws_unlock(drvr, flags);
index 277b37ae71267a194d6ebcc541b93cc786ef9078..7fa71f73cfe89c5bfb5f2fca8e1e83c4d7124045 100644 (file)
@@ -1093,8 +1093,11 @@ static void brcmf_link_down(struct brcmf_cfg80211_vif *vif)
                brcmf_dbg(INFO, "Call WLC_DISASSOC to stop excess roaming\n ");
                err = brcmf_fil_cmd_data_set(vif->ifp,
                                             BRCMF_C_DISASSOC, NULL, 0);
-               if (err)
+               if (err) {
                        brcmf_err("WLC_DISASSOC failed (%d)\n", err);
+                       cfg80211_disconnected(vif->wdev.netdev, 0,
+                                             NULL, 0, GFP_KERNEL);
+               }
                clear_bit(BRCMF_VIF_STATUS_CONNECTED, &vif->sme_state);
        }
        clear_bit(BRCMF_VIF_STATUS_CONNECTING, &vif->sme_state);
index 7365674366f4426fb79b74cadb4be87bbd07b7a1..010b252be584237c7f6b4e71f5d375332176f586 100644 (file)
@@ -1406,11 +1406,8 @@ static void cw1200_do_unjoin(struct cw1200_common *priv)
        if (!priv->join_status)
                goto done;
 
-       if (priv->join_status > CW1200_JOIN_STATUS_IBSS) {
-               wiphy_err(priv->hw->wiphy, "Unexpected: join status: %d\n",
-                         priv->join_status);
-               BUG_ON(1);
-       }
+       if (priv->join_status == CW1200_JOIN_STATUS_AP)
+               goto done;
 
        cancel_work_sync(&priv->update_filtering_work);
        cancel_work_sync(&priv->set_beacon_wakeup_period_work);
index 5862c373d7148851816a5b16bfeb9c1acaebb191..e824d4d4a18d7e1d385d9d95f8fea195766a3ae8 100644 (file)
@@ -1165,7 +1165,7 @@ void cw1200_rx_cb(struct cw1200_common *priv,
                if (cw1200_handle_action_rx(priv, skb))
                        return;
        } else if (ieee80211_is_beacon(frame->frame_control) &&
-                  !arg->status &&
+                  !arg->status && priv->vif &&
                   !memcmp(ieee80211_get_SA(frame), priv->vif->bss_conf.bssid,
                           ETH_ALEN)) {
                const u8 *tim_ie;
index b9b2bb51e60590ab7dfb91d4e284a6a0c6c259a7..f2ed62e373408d3882a3e463af81b88f3a83b7b1 100644 (file)
@@ -4460,12 +4460,12 @@ il4965_irq_tasklet(struct il_priv *il)
                 * is killed. Hence update the killswitch state here. The
                 * rfkill handler will care about restarting if needed.
                 */
-               if (!test_bit(S_ALIVE, &il->status)) {
-                       if (hw_rf_kill)
-                               set_bit(S_RFKILL, &il->status);
-                       else
-                               clear_bit(S_RFKILL, &il->status);
+               if (hw_rf_kill) {
+                       set_bit(S_RFKILL, &il->status);
+               } else {
+                       clear_bit(S_RFKILL, &il->status);
                        wiphy_rfkill_set_hw_state(il->hw->wiphy, hw_rf_kill);
+                       il_force_reset(il, true);
                }
 
                handled |= CSR_INT_BIT_RF_KILL;
@@ -5334,6 +5334,9 @@ il4965_alive_start(struct il_priv *il)
 
        il->active_rate = RATES_MASK;
 
+       il_power_update_mode(il, true);
+       D_INFO("Updated power mode\n");
+
        if (il_is_associated(il)) {
                struct il_rxon_cmd *active_rxon =
                    (struct il_rxon_cmd *)&il->active;
@@ -5364,9 +5367,6 @@ il4965_alive_start(struct il_priv *il)
        D_INFO("ALIVE processing complete.\n");
        wake_up(&il->wait_command_queue);
 
-       il_power_update_mode(il, true);
-       D_INFO("Updated power mode\n");
-
        return;
 
 restart:
index 3195aad440ddf6317b1b9b34d2e2f57e773755c3..b03e22ef5462d929ea20ffad72a4a01ff067c4a4 100644 (file)
@@ -4660,6 +4660,7 @@ il_force_reset(struct il_priv *il, bool external)
 
        return 0;
 }
+EXPORT_SYMBOL(il_force_reset);
 
 int
 il_mac_change_interface(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
index ef5fa890a28628666398f39624f83e1bfe6aa1f5..89459db4c53b9f1468f832f4e3d0be0200b7ec22 100644 (file)
@@ -1716,9 +1716,9 @@ mwifiex_cfg80211_connect(struct wiphy *wiphy, struct net_device *dev,
        struct mwifiex_private *priv = mwifiex_netdev_get_priv(dev);
        int ret;
 
-       if (priv->bss_mode != NL80211_IFTYPE_STATION) {
+       if (GET_BSS_ROLE(priv) != MWIFIEX_BSS_ROLE_STA) {
                wiphy_err(wiphy,
-                         "%s: reject infra assoc request in non-STA mode\n",
+                         "%s: reject infra assoc request in non-STA role\n",
                          dev->name);
                return -EINVAL;
        }
index 988552dece75d49ab3af4628dec68bd6a9627030..5178c4630d89310e17a5db810977fa5aad8ca525 100644 (file)
@@ -415,7 +415,8 @@ u32 mwifiex_get_supported_rates(struct mwifiex_private *priv, u8 *rates)
        u32 k = 0;
        struct mwifiex_adapter *adapter = priv->adapter;
 
-       if (priv->bss_mode == NL80211_IFTYPE_STATION) {
+       if (priv->bss_mode == NL80211_IFTYPE_STATION ||
+           priv->bss_mode == NL80211_IFTYPE_P2P_CLIENT) {
                switch (adapter->config_bands) {
                case BAND_B:
                        dev_dbg(adapter->dev, "info: infra band=%d "
index caaf4bd56b3062ea4c9a11028233c1517f69296c..2cf8b964e966c5dec94b37ca9a826799d73f4dee 100644 (file)
@@ -693,7 +693,7 @@ int mwifiex_dnld_fw(struct mwifiex_adapter *adapter,
                if (!ret) {
                        dev_notice(adapter->dev,
                                   "WLAN FW already running! Skip FW dnld\n");
-                       goto done;
+                       return 0;
                }
 
                poll_num = MAX_FIRMWARE_POLL_TRIES;
@@ -719,14 +719,8 @@ int mwifiex_dnld_fw(struct mwifiex_adapter *adapter,
 poll_fw:
        /* Check if the firmware is downloaded successfully or not */
        ret = adapter->if_ops.check_fw_status(adapter, poll_num);
-       if (ret) {
+       if (ret)
                dev_err(adapter->dev, "FW failed to be active in time\n");
-               return -1;
-       }
-done:
-       /* re-enable host interrupt for mwifiex after fw dnld is successful */
-       if (adapter->if_ops.enable_int)
-               adapter->if_ops.enable_int(adapter);
 
        return ret;
 }
index 1c8a771e8e8127e666265d10447b88f884a4c5fa..12e778159ec58f5be70ab8c3e9d515beab28b48a 100644 (file)
@@ -1291,8 +1291,10 @@ int mwifiex_associate(struct mwifiex_private *priv,
 {
        u8 current_bssid[ETH_ALEN];
 
-       /* Return error if the adapter or table entry is not marked as infra */
-       if ((priv->bss_mode != NL80211_IFTYPE_STATION) ||
+       /* Return error if the adapter is not STA role or table entry
+        * is not marked as infra.
+        */
+       if ((GET_BSS_ROLE(priv) != MWIFIEX_BSS_ROLE_STA) ||
            (bss_desc->bss_mode != NL80211_IFTYPE_STATION))
                return -1;
 
index e15ab72fb03ddc1ad6eab8e54aded37de3143253..1753431de361b807890ec8bcb177760f457faa07 100644 (file)
@@ -427,6 +427,10 @@ static void mwifiex_fw_dpc(const struct firmware *firmware, void *context)
                                "Cal data request_firmware() failed\n");
        }
 
+       /* enable host interrupt after fw dnld is successful */
+       if (adapter->if_ops.enable_int)
+               adapter->if_ops.enable_int(adapter);
+
        adapter->init_wait_q_woken = false;
        ret = mwifiex_init_fw(adapter);
        if (ret == -1) {
@@ -478,6 +482,8 @@ err_add_intf:
        mwifiex_del_virtual_intf(adapter->wiphy, priv->wdev);
        rtnl_unlock();
 err_init_fw:
+       if (adapter->if_ops.disable_int)
+               adapter->if_ops.disable_int(adapter);
        pr_debug("info: %s: unregister device\n", __func__);
        adapter->if_ops.unregister_dev(adapter);
 done:
@@ -855,7 +861,7 @@ mwifiex_add_card(void *card, struct semaphore *sem,
        INIT_WORK(&adapter->main_work, mwifiex_main_work_queue);
 
        /* Register the device. Fill up the private data structure with relevant
-          information from the card and request for the required IRQ. */
+          information from the card. */
        if (adapter->if_ops.register_dev(adapter)) {
                pr_err("%s: failed to register mwifiex device\n", __func__);
                goto err_registerdev;
@@ -919,6 +925,11 @@ int mwifiex_remove_card(struct mwifiex_adapter *adapter, struct semaphore *sem)
        if (!adapter)
                goto exit_remove;
 
+       /* We can no longer handle interrupts once we start doing the teardown
+        * below. */
+       if (adapter->if_ops.disable_int)
+               adapter->if_ops.disable_int(adapter);
+
        adapter->surprise_removed = true;
 
        /* Stop data */
index 3da73d36acdf5e9a5ebe30ce75333704d98a00c0..253e0bd38e25e22ce911e6e49b4d99261afe596d 100644 (file)
@@ -601,6 +601,7 @@ struct mwifiex_if_ops {
        int (*register_dev) (struct mwifiex_adapter *);
        void (*unregister_dev) (struct mwifiex_adapter *);
        int (*enable_int) (struct mwifiex_adapter *);
+       void (*disable_int) (struct mwifiex_adapter *);
        int (*process_int_status) (struct mwifiex_adapter *);
        int (*host_to_card) (struct mwifiex_adapter *, u8, struct sk_buff *,
                             struct mwifiex_tx_param *);
index 5ee5ed02eccd56645c94f8b4972962130f5b305b..09185c9632483b324d63953652ac6acc93a36752 100644 (file)
@@ -51,6 +51,7 @@ static struct mwifiex_if_ops sdio_ops;
 static struct semaphore add_remove_card_sem;
 
 static int mwifiex_sdio_resume(struct device *dev);
+static void mwifiex_sdio_interrupt(struct sdio_func *func);
 
 /*
  * SDIO probe.
@@ -296,6 +297,15 @@ static struct sdio_driver mwifiex_sdio = {
        }
 };
 
+/* Write data into SDIO card register. Caller claims SDIO device. */
+static int
+mwifiex_write_reg_locked(struct sdio_func *func, u32 reg, u8 data)
+{
+       int ret = -1;
+       sdio_writeb(func, data, reg, &ret);
+       return ret;
+}
+
 /*
  * This function writes data into SDIO card register.
  */
@@ -303,10 +313,10 @@ static int
 mwifiex_write_reg(struct mwifiex_adapter *adapter, u32 reg, u8 data)
 {
        struct sdio_mmc_card *card = adapter->card;
-       int ret = -1;
+       int ret;
 
        sdio_claim_host(card->func);
-       sdio_writeb(card->func, data, reg, &ret);
+       ret = mwifiex_write_reg_locked(card->func, reg, data);
        sdio_release_host(card->func);
 
        return ret;
@@ -685,23 +695,15 @@ mwifiex_sdio_read_fw_status(struct mwifiex_adapter *adapter, u16 *dat)
  * The host interrupt mask is read, the disable bit is reset and
  * written back to the card host interrupt mask register.
  */
-static int mwifiex_sdio_disable_host_int(struct mwifiex_adapter *adapter)
+static void mwifiex_sdio_disable_host_int(struct mwifiex_adapter *adapter)
 {
-       u8 host_int_mask, host_int_disable = HOST_INT_DISABLE;
-
-       /* Read back the host_int_mask register */
-       if (mwifiex_read_reg(adapter, HOST_INT_MASK_REG, &host_int_mask))
-               return -1;
-
-       /* Update with the mask and write back to the register */
-       host_int_mask &= ~host_int_disable;
-
-       if (mwifiex_write_reg(adapter, HOST_INT_MASK_REG, host_int_mask)) {
-               dev_err(adapter->dev, "disable host interrupt failed\n");
-               return -1;
-       }
+       struct sdio_mmc_card *card = adapter->card;
+       struct sdio_func *func = card->func;
 
-       return 0;
+       sdio_claim_host(func);
+       mwifiex_write_reg_locked(func, HOST_INT_MASK_REG, 0);
+       sdio_release_irq(func);
+       sdio_release_host(func);
 }
 
 /*
@@ -713,14 +715,29 @@ static int mwifiex_sdio_disable_host_int(struct mwifiex_adapter *adapter)
 static int mwifiex_sdio_enable_host_int(struct mwifiex_adapter *adapter)
 {
        struct sdio_mmc_card *card = adapter->card;
+       struct sdio_func *func = card->func;
+       int ret;
+
+       sdio_claim_host(func);
+
+       /* Request the SDIO IRQ */
+       ret = sdio_claim_irq(func, mwifiex_sdio_interrupt);
+       if (ret) {
+               dev_err(adapter->dev, "claim irq failed: ret=%d\n", ret);
+               goto out;
+       }
 
        /* Simply write the mask to the register */
-       if (mwifiex_write_reg(adapter, HOST_INT_MASK_REG,
-                             card->reg->host_int_enable)) {
+       ret = mwifiex_write_reg_locked(func, HOST_INT_MASK_REG,
+                                      card->reg->host_int_enable);
+       if (ret) {
                dev_err(adapter->dev, "enable host interrupt failed\n");
-               return -1;
+               sdio_release_irq(func);
        }
-       return 0;
+
+out:
+       sdio_release_host(func);
+       return ret;
 }
 
 /*
@@ -997,9 +1014,6 @@ mwifiex_sdio_interrupt(struct sdio_func *func)
        }
        adapter = card->adapter;
 
-       if (adapter->surprise_removed)
-               return;
-
        if (!adapter->pps_uapsd_mode && adapter->ps_state == PS_STATE_SLEEP)
                adapter->ps_state = PS_STATE_AWAKE;
 
@@ -1625,8 +1639,8 @@ static int mwifiex_sdio_host_to_card(struct mwifiex_adapter *adapter,
        /* Allocate buffer and copy payload */
        blk_size = MWIFIEX_SDIO_BLOCK_SIZE;
        buf_block_len = (pkt_len + blk_size - 1) / blk_size;
-       *(u16 *) &payload[0] = (u16) pkt_len;
-       *(u16 *) &payload[2] = type;
+       *(__le16 *)&payload[0] = cpu_to_le16((u16)pkt_len);
+       *(__le16 *)&payload[2] = cpu_to_le16(type);
 
        /*
         * This is SDIO specific header
@@ -1728,9 +1742,7 @@ mwifiex_unregister_dev(struct mwifiex_adapter *adapter)
        struct sdio_mmc_card *card = adapter->card;
 
        if (adapter->card) {
-               /* Release the SDIO IRQ */
                sdio_claim_host(card->func);
-               sdio_release_irq(card->func);
                sdio_disable_func(card->func);
                sdio_release_host(card->func);
                sdio_set_drvdata(card->func, NULL);
@@ -1744,7 +1756,7 @@ mwifiex_unregister_dev(struct mwifiex_adapter *adapter)
  */
 static int mwifiex_register_dev(struct mwifiex_adapter *adapter)
 {
-       int ret = 0;
+       int ret;
        struct sdio_mmc_card *card = adapter->card;
        struct sdio_func *func = card->func;
 
@@ -1753,22 +1765,14 @@ static int mwifiex_register_dev(struct mwifiex_adapter *adapter)
 
        sdio_claim_host(func);
 
-       /* Request the SDIO IRQ */
-       ret = sdio_claim_irq(func, mwifiex_sdio_interrupt);
-       if (ret) {
-               pr_err("claim irq failed: ret=%d\n", ret);
-               goto disable_func;
-       }
-
        /* Set block size */
        ret = sdio_set_block_size(card->func, MWIFIEX_SDIO_BLOCK_SIZE);
+       sdio_release_host(func);
        if (ret) {
                pr_err("cannot set SDIO block size\n");
-               ret = -1;
-               goto release_irq;
+               return ret;
        }
 
-       sdio_release_host(func);
        sdio_set_drvdata(func, card);
 
        adapter->dev = &func->dev;
@@ -1776,15 +1780,6 @@ static int mwifiex_register_dev(struct mwifiex_adapter *adapter)
        strcpy(adapter->fw_name, card->firmware);
 
        return 0;
-
-release_irq:
-       sdio_release_irq(func);
-disable_func:
-       sdio_disable_func(func);
-       sdio_release_host(func);
-       adapter->card = NULL;
-
-       return -1;
 }
 
 /*
@@ -1813,9 +1808,6 @@ static int mwifiex_init_sdio(struct mwifiex_adapter *adapter)
         */
        mwifiex_read_reg(adapter, HOST_INTSTATUS_REG, &sdio_ireg);
 
-       /* Disable host interrupt mask register for SDIO */
-       mwifiex_sdio_disable_host_int(adapter);
-
        /* Get SDIO ioport */
        mwifiex_init_sdio_ioport(adapter);
 
@@ -1957,6 +1949,7 @@ static struct mwifiex_if_ops sdio_ops = {
        .register_dev = mwifiex_register_dev,
        .unregister_dev = mwifiex_unregister_dev,
        .enable_int = mwifiex_sdio_enable_host_int,
+       .disable_int = mwifiex_sdio_disable_host_int,
        .process_int_status = mwifiex_process_int_status,
        .host_to_card = mwifiex_sdio_host_to_card,
        .wakeup = mwifiex_pm_wakeup_card,
index 6d51dfdd8251a515c3f6a17e94029b5c10f6672a..532ae0ac4dfb3e40bb12592db32ec94e702a4c2b 100644 (file)
@@ -92,9 +92,6 @@
 /* Host Control Registers : Download host interrupt mask */
 #define DN_LD_HOST_INT_MASK            (0x2U)
 
-/* Disable Host interrupt mask */
-#define        HOST_INT_DISABLE                0xff
-
 /* Host Control Registers : Host interrupt status */
 #define HOST_INTSTATUS_REG             0x03
 /* Host Control Registers : Upload host interrupt status */
index 206c3e03807235425ee3c0ad12676cc7c187cad7..8af97abf71088589b61cbc847fdc494a616de7c7 100644 (file)
@@ -257,10 +257,10 @@ int mwifiex_bss_start(struct mwifiex_private *priv, struct cfg80211_bss *bss,
                        goto done;
        }
 
-       if (priv->bss_mode == NL80211_IFTYPE_STATION) {
+       if (priv->bss_mode == NL80211_IFTYPE_STATION ||
+           priv->bss_mode == NL80211_IFTYPE_P2P_CLIENT) {
                u8 config_bands;
 
-               /* Infra mode */
                ret = mwifiex_deauthenticate(priv, NULL);
                if (ret)
                        goto done;
index 9b915d3a44bee4c7d585ca79d8209415c40d7c01..3e60a31582f8b3b15f359a5325a8031de96f4427 100644 (file)
@@ -1,6 +1,6 @@
 menuconfig RT2X00
        tristate "Ralink driver support"
-       depends on MAC80211
+       depends on MAC80211 && HAS_DMA
        ---help---
          This will enable the support for the Ralink drivers,
          developed in the rt2x00 project <http://rt2x00.serialmonkey.com>.
index 6c0a91ff963c6833bb7d325cac7954c7c10b41fc..aa95c6cf3545432bf93b0743af97900a91f55ec9 100644 (file)
@@ -936,13 +936,8 @@ void rt2x00queue_index_inc(struct queue_entry *entry, enum queue_index index)
        spin_unlock_irqrestore(&queue->index_lock, irqflags);
 }
 
-void rt2x00queue_pause_queue(struct data_queue *queue)
+void rt2x00queue_pause_queue_nocheck(struct data_queue *queue)
 {
-       if (!test_bit(DEVICE_STATE_PRESENT, &queue->rt2x00dev->flags) ||
-           !test_bit(QUEUE_STARTED, &queue->flags) ||
-           test_and_set_bit(QUEUE_PAUSED, &queue->flags))
-               return;
-
        switch (queue->qid) {
        case QID_AC_VO:
        case QID_AC_VI:
@@ -958,6 +953,15 @@ void rt2x00queue_pause_queue(struct data_queue *queue)
                break;
        }
 }
+void rt2x00queue_pause_queue(struct data_queue *queue)
+{
+       if (!test_bit(DEVICE_STATE_PRESENT, &queue->rt2x00dev->flags) ||
+           !test_bit(QUEUE_STARTED, &queue->flags) ||
+           test_and_set_bit(QUEUE_PAUSED, &queue->flags))
+               return;
+
+       rt2x00queue_pause_queue_nocheck(queue);
+}
 EXPORT_SYMBOL_GPL(rt2x00queue_pause_queue);
 
 void rt2x00queue_unpause_queue(struct data_queue *queue)
@@ -1019,7 +1023,7 @@ void rt2x00queue_stop_queue(struct data_queue *queue)
                return;
        }
 
-       rt2x00queue_pause_queue(queue);
+       rt2x00queue_pause_queue_nocheck(queue);
 
        queue->rt2x00dev->ops->lib->stop_queue(queue);
 
index 7253de3d8c6671c78e732b001e7270731465d039..c2ffce7a907c90cf3fcc01400f50f2850d371533 100644 (file)
@@ -1,27 +1,20 @@
-config RTLWIFI
-       tristate "Realtek wireless card support"
-       depends on MAC80211
-       select FW_LOADER
-       ---help---
-         This is common code for RTL8192CE/RTL8192CU/RTL8192SE/RTL8723AE
-         drivers.  This module does nothing by itself - the various front-end
-         drivers need to be enabled to support any desired devices.
-
-         If you choose to build as a module, it'll be called rtlwifi.
-
-config RTLWIFI_DEBUG
-       bool "Debugging output for rtlwifi driver family"
-       depends on RTLWIFI
+menuconfig RTL_CARDS
+       tristate "Realtek rtlwifi family of devices"
+       depends on MAC80211 && (PCI || USB)
        default y
        ---help---
-       To use the module option that sets the dynamic-debugging level for,
-       the front-end driver, this parameter must be "Y". For memory-limited
-       systems, choose "N". If in doubt, choose "Y".
+         This option will enable support for the Realtek mac80211-based
+         wireless drivers. Drivers rtl8192ce, rtl8192cu, rtl8192se, rtl8192de,
+         rtl8723eu, and rtl8188eu share some common code.
+
+if RTL_CARDS
 
 config RTL8192CE
        tristate "Realtek RTL8192CE/RTL8188CE Wireless Network Adapter"
-       depends on RTLWIFI && PCI
+       depends on PCI
        select RTL8192C_COMMON
+       select RTLWIFI
+       select RTLWIFI_PCI
        ---help---
        This is the driver for Realtek RTL8192CE/RTL8188CE 802.11n PCIe
        wireless network adapters.
@@ -30,7 +23,9 @@ config RTL8192CE
 
 config RTL8192SE
        tristate "Realtek RTL8192SE/RTL8191SE PCIe Wireless Network Adapter"
-       depends on RTLWIFI && PCI
+       depends on PCI
+       select RTLWIFI
+       select RTLWIFI_PCI
        ---help---
        This is the driver for Realtek RTL8192SE/RTL8191SE 802.11n PCIe
        wireless network adapters.
@@ -39,7 +34,9 @@ config RTL8192SE
 
 config RTL8192DE
        tristate "Realtek RTL8192DE/RTL8188DE PCIe Wireless Network Adapter"
-       depends on RTLWIFI && PCI
+       depends on PCI
+       select RTLWIFI
+       select RTLWIFI_PCI
        ---help---
        This is the driver for Realtek RTL8192DE/RTL8188DE 802.11n PCIe
        wireless network adapters.
@@ -48,7 +45,9 @@ config RTL8192DE
 
 config RTL8723AE
        tristate "Realtek RTL8723AE PCIe Wireless Network Adapter"
-       depends on RTLWIFI && PCI
+       depends on PCI
+       select RTLWIFI
+       select RTLWIFI_PCI
        ---help---
        This is the driver for Realtek RTL8723AE 802.11n PCIe
        wireless network adapters.
@@ -57,7 +56,9 @@ config RTL8723AE
 
 config RTL8188EE
        tristate "Realtek RTL8188EE Wireless Network Adapter"
-       depends on RTLWIFI && PCI
+       depends on PCI
+       select RTLWIFI
+       select RTLWIFI_PCI
        ---help---
        This is the driver for Realtek RTL8188EE 802.11n PCIe
        wireless network adapters.
@@ -66,7 +67,9 @@ config RTL8188EE
 
 config RTL8192CU
        tristate "Realtek RTL8192CU/RTL8188CU USB Wireless Network Adapter"
-       depends on RTLWIFI && USB
+       depends on USB
+       select RTLWIFI
+       select RTLWIFI_USB
        select RTL8192C_COMMON
        ---help---
        This is the driver for Realtek RTL8192CU/RTL8188CU 802.11n USB
@@ -74,7 +77,28 @@ config RTL8192CU
 
        If you choose to build it as a module, it will be called rtl8192cu
 
+config RTLWIFI
+       tristate
+       select FW_LOADER
+
+config RTLWIFI_PCI
+       tristate
+
+config RTLWIFI_USB
+       tristate
+
+config RTLWIFI_DEBUG
+       bool "Debugging output for rtlwifi driver family"
+       depends on RTLWIFI
+       default y
+       ---help---
+       To use the module option that sets the dynamic-debugging level for,
+       the front-end driver, this parameter must be "Y". For memory-limited
+       systems, choose "N". If in doubt, choose "Y".
+
 config RTL8192C_COMMON
        tristate
        depends on RTL8192CE || RTL8192CU
-       default m
+       default y
+
+endif
index ff02b874f8d87dfd15ff0205a6036e65c0b9ad5c..d56f023a4b90dfadabf45670b2f5c8d0ca1fa46d 100644 (file)
@@ -12,13 +12,11 @@ rtlwifi-objs        :=              \
 
 rtl8192c_common-objs +=                \
 
-ifneq ($(CONFIG_PCI),)
-rtlwifi-objs   += pci.o
-endif
+obj-$(CONFIG_RTLWIFI_PCI)      += rtl_pci.o
+rtl_pci-objs   :=              pci.o
 
-ifneq ($(CONFIG_USB),)
-rtlwifi-objs   += usb.o
-endif
+obj-$(CONFIG_RTLWIFI_USB)      += rtl_usb.o
+rtl_usb-objs   :=              usb.o
 
 obj-$(CONFIG_RTL8192C_COMMON)  += rtl8192c/
 obj-$(CONFIG_RTL8192CE)                += rtl8192ce/
index 9d558ac77b0c78b36ad6f6a31a49cf5aa4aae765..7651f5acc14bcccdc179fc09450af258f9d30e23 100644 (file)
@@ -172,6 +172,7 @@ u8 rtl_tid_to_ac(u8 tid)
 {
        return tid_to_ac[tid];
 }
+EXPORT_SYMBOL_GPL(rtl_tid_to_ac);
 
 static void _rtl_init_hw_ht_capab(struct ieee80211_hw *hw,
                                  struct ieee80211_sta_ht_cap *ht_cap)
@@ -406,6 +407,7 @@ void rtl_deinit_deferred_work(struct ieee80211_hw *hw)
        cancel_delayed_work(&rtlpriv->works.ps_rfon_wq);
        cancel_delayed_work(&rtlpriv->works.fwevt_wq);
 }
+EXPORT_SYMBOL_GPL(rtl_deinit_deferred_work);
 
 void rtl_init_rfkill(struct ieee80211_hw *hw)
 {
@@ -439,6 +441,7 @@ void rtl_deinit_rfkill(struct ieee80211_hw *hw)
 {
        wiphy_rfkill_stop_polling(hw->wiphy);
 }
+EXPORT_SYMBOL_GPL(rtl_deinit_rfkill);
 
 int rtl_init_core(struct ieee80211_hw *hw)
 {
@@ -489,10 +492,12 @@ int rtl_init_core(struct ieee80211_hw *hw)
 
        return 0;
 }
+EXPORT_SYMBOL_GPL(rtl_init_core);
 
 void rtl_deinit_core(struct ieee80211_hw *hw)
 {
 }
+EXPORT_SYMBOL_GPL(rtl_deinit_core);
 
 void rtl_init_rx_config(struct ieee80211_hw *hw)
 {
@@ -501,6 +506,7 @@ void rtl_init_rx_config(struct ieee80211_hw *hw)
 
        rtlpriv->cfg->ops->get_hw_reg(hw, HW_VAR_RCR, (u8 *) (&mac->rx_conf));
 }
+EXPORT_SYMBOL_GPL(rtl_init_rx_config);
 
 /*********************************************************
  *
@@ -879,6 +885,7 @@ bool rtl_tx_mgmt_proc(struct ieee80211_hw *hw, struct sk_buff *skb)
 
        return true;
 }
+EXPORT_SYMBOL_GPL(rtl_tx_mgmt_proc);
 
 void rtl_get_tcb_desc(struct ieee80211_hw *hw,
                      struct ieee80211_tx_info *info,
@@ -1052,6 +1059,7 @@ bool rtl_action_proc(struct ieee80211_hw *hw, struct sk_buff *skb, u8 is_tx)
 
        return true;
 }
+EXPORT_SYMBOL_GPL(rtl_action_proc);
 
 /*should call before software enc*/
 u8 rtl_is_special_data(struct ieee80211_hw *hw, struct sk_buff *skb, u8 is_tx)
@@ -1125,6 +1133,7 @@ u8 rtl_is_special_data(struct ieee80211_hw *hw, struct sk_buff *skb, u8 is_tx)
 
        return false;
 }
+EXPORT_SYMBOL_GPL(rtl_is_special_data);
 
 /*********************************************************
  *
@@ -1300,6 +1309,7 @@ void rtl_beacon_statistic(struct ieee80211_hw *hw, struct sk_buff *skb)
 
        rtlpriv->link_info.bcn_rx_inperiod++;
 }
+EXPORT_SYMBOL_GPL(rtl_beacon_statistic);
 
 void rtl_watchdog_wq_callback(void *data)
 {
@@ -1793,6 +1803,7 @@ void rtl_recognize_peer(struct ieee80211_hw *hw, u8 *data, unsigned int len)
 
        mac->vendor = vendor;
 }
+EXPORT_SYMBOL_GPL(rtl_recognize_peer);
 
 /*********************************************************
  *
@@ -1849,6 +1860,7 @@ struct attribute_group rtl_attribute_group = {
        .name = "rtlsysfs",
        .attrs = rtl_sysfs_entries,
 };
+EXPORT_SYMBOL_GPL(rtl_attribute_group);
 
 MODULE_AUTHOR("lizhaoming      <chaoming_li@realsil.com.cn>");
 MODULE_AUTHOR("Realtek WlanFAE <wlanfae@realtek.com>");
@@ -1856,7 +1868,8 @@ MODULE_AUTHOR("Larry Finger       <Larry.FInger@lwfinger.net>");
 MODULE_LICENSE("GPL");
 MODULE_DESCRIPTION("Realtek 802.11n PCI wireless core");
 
-struct rtl_global_var global_var = {};
+struct rtl_global_var rtl_global_var = {};
+EXPORT_SYMBOL_GPL(rtl_global_var);
 
 static int __init rtl_core_module_init(void)
 {
@@ -1864,8 +1877,8 @@ static int __init rtl_core_module_init(void)
                pr_err("Unable to register rtl_rc, use default RC !!\n");
 
        /* init some global vars */
-       INIT_LIST_HEAD(&global_var.glb_priv_list);
-       spin_lock_init(&global_var.glb_list_lock);
+       INIT_LIST_HEAD(&rtl_global_var.glb_priv_list);
+       spin_lock_init(&rtl_global_var.glb_list_lock);
 
        return 0;
 }
index 8576bc34b03289ef077db41f5700e3a2eea5bf21..0e5fe0902daf6eb180a1da431ce54477e49486cb 100644 (file)
@@ -147,7 +147,7 @@ void rtl_recognize_peer(struct ieee80211_hw *hw, u8 *data, unsigned int len);
 u8 rtl_tid_to_ac(u8 tid);
 extern struct attribute_group rtl_attribute_group;
 void rtl_easy_concurrent_retrytimer_callback(unsigned long data);
-extern struct rtl_global_var global_var;
+extern struct rtl_global_var rtl_global_var;
 int rtlwifi_rate_mapping(struct ieee80211_hw *hw,
                         bool isht, u8 desc_rate, bool first_ampdu);
 bool rtl_tx_mgmt_proc(struct ieee80211_hw *hw, struct sk_buff *skb);
index ee84844be0080c2e1bcef681f7e53a7f42f93125..733b7ce7f0e2a981f442cd9cdadd8f40a6426558 100644 (file)
@@ -1330,3 +1330,4 @@ const struct ieee80211_ops rtl_ops = {
        .rfkill_poll = rtl_op_rfkill_poll,
        .flush = rtl_op_flush,
 };
+EXPORT_SYMBOL_GPL(rtl_ops);
index 7d52d3d7769f0e357be0900ec0423dac70cb390c..76e2086e137e5f0356325887ecccc5c768d17f6c 100644 (file)
@@ -51,3 +51,4 @@ void rtl_dbgp_flag_init(struct ieee80211_hw *hw)
 
        /*Init Debug flag enable condition */
 }
+EXPORT_SYMBOL_GPL(rtl_dbgp_flag_init);
index 9e3894178e7773b3d6aca8a4cca70fc518fd6a96..838a1ed3f1942b9f3d56a122c2840548b38103c9 100644 (file)
@@ -229,6 +229,7 @@ void read_efuse_byte(struct ieee80211_hw *hw, u16 _offset, u8 *pbuf)
 
        *pbuf = (u8) (value32 & 0xff);
 }
+EXPORT_SYMBOL_GPL(read_efuse_byte);
 
 void read_efuse(struct ieee80211_hw *hw, u16 _offset, u16 _size_byte, u8 *pbuf)
 {
index c97e9d327331c8b25624327ec4d672c7289f4492..703f839af6ca0b4abefcfc754dc21eb3d13b2dac 100644 (file)
 #include "efuse.h"
 #include <linux/export.h>
 #include <linux/kmemleak.h>
+#include <linux/module.h>
+
+MODULE_AUTHOR("lizhaoming      <chaoming_li@realsil.com.cn>");
+MODULE_AUTHOR("Realtek WlanFAE <wlanfae@realtek.com>");
+MODULE_AUTHOR("Larry Finger    <Larry.FInger@lwfinger.net>");
+MODULE_LICENSE("GPL");
+MODULE_DESCRIPTION("PCI basic driver for rtlwifi");
 
 static const u16 pcibridge_vendors[PCI_BRIDGE_VENDOR_MAX] = {
        PCI_VENDOR_ID_INTEL,
@@ -1008,19 +1015,6 @@ static void _rtl_pci_prepare_bcn_tasklet(struct ieee80211_hw *hw)
        return;
 }
 
-static void rtl_lps_change_work_callback(struct work_struct *work)
-{
-       struct rtl_works *rtlworks =
-           container_of(work, struct rtl_works, lps_change_work);
-       struct ieee80211_hw *hw = rtlworks->hw;
-       struct rtl_priv *rtlpriv = rtl_priv(hw);
-
-       if (rtlpriv->enter_ps)
-               rtl_lps_enter(hw);
-       else
-               rtl_lps_leave(hw);
-}
-
 static void _rtl_pci_init_trx_var(struct ieee80211_hw *hw)
 {
        struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw));
@@ -1899,7 +1893,7 @@ int rtl_pci_probe(struct pci_dev *pdev,
        rtlpriv->rtlhal.interface = INTF_PCI;
        rtlpriv->cfg = (struct rtl_hal_cfg *)(id->driver_data);
        rtlpriv->intf_ops = &rtl_pci_ops;
-       rtlpriv->glb_var = &global_var;
+       rtlpriv->glb_var = &rtl_global_var;
 
        /*
         *init dbgp flags before all
index 884bceae38a91d2b9ce4e07cf70c5c040e844df4..298b615964e861acb23c9ccd85e7b154854e9cda 100644 (file)
@@ -269,6 +269,7 @@ void rtl_ips_nic_on(struct ieee80211_hw *hw)
 
        spin_unlock_irqrestore(&rtlpriv->locks.ips_lock, flags);
 }
+EXPORT_SYMBOL_GPL(rtl_ips_nic_on);
 
 /*for FW LPS*/
 
@@ -518,6 +519,7 @@ void rtl_swlps_beacon(struct ieee80211_hw *hw, void *data, unsigned int len)
                         "u_bufferd: %x, m_buffered: %x\n", u_buffed, m_buffed);
        }
 }
+EXPORT_SYMBOL_GPL(rtl_swlps_beacon);
 
 void rtl_swlps_rf_awake(struct ieee80211_hw *hw)
 {
@@ -611,6 +613,19 @@ void rtl_swlps_rf_sleep(struct ieee80211_hw *hw)
                        MSECS(sleep_intv * mac->vif->bss_conf.beacon_int - 40));
 }
 
+void rtl_lps_change_work_callback(struct work_struct *work)
+{
+       struct rtl_works *rtlworks =
+           container_of(work, struct rtl_works, lps_change_work);
+       struct ieee80211_hw *hw = rtlworks->hw;
+       struct rtl_priv *rtlpriv = rtl_priv(hw);
+
+       if (rtlpriv->enter_ps)
+               rtl_lps_enter(hw);
+       else
+               rtl_lps_leave(hw);
+}
+EXPORT_SYMBOL_GPL(rtl_lps_change_work_callback);
 
 void rtl_swlps_wq_callback(void *data)
 {
@@ -922,3 +937,4 @@ void rtl_p2p_info(struct ieee80211_hw *hw, void *data, unsigned int len)
        else
                rtl_p2p_noa_ie(hw, data, len - FCS_LEN);
 }
+EXPORT_SYMBOL_GPL(rtl_p2p_info);
index 4d682b753f503df0f61b5e58b98e871f58c31029..88bd76ea88f7621dd92cb4ff495ee22e9dc53912 100644 (file)
@@ -49,5 +49,6 @@ void rtl_swlps_rf_awake(struct ieee80211_hw *hw);
 void rtl_swlps_rf_sleep(struct ieee80211_hw *hw);
 void rtl_p2p_ps_cmd(struct ieee80211_hw *hw, u8 p2p_ps_state);
 void rtl_p2p_info(struct ieee80211_hw *hw, void *data, unsigned int len);
+void rtl_lps_change_work_callback(struct work_struct *work);
 
 #endif
index a3532e0778710ff5975a3c3fec4e21299e45e301..e56778cac9bfce39e56d5aa239e34f2fb1135ffb 100644 (file)
 #include "ps.h"
 #include "rtl8192c/fw_common.h"
 #include <linux/export.h>
+#include <linux/module.h>
+
+MODULE_AUTHOR("lizhaoming      <chaoming_li@realsil.com.cn>");
+MODULE_AUTHOR("Realtek WlanFAE <wlanfae@realtek.com>");
+MODULE_AUTHOR("Larry Finger    <Larry.FInger@lwfinger.net>");
+MODULE_LICENSE("GPL");
+MODULE_DESCRIPTION("USB basic driver for rtlwifi");
 
 #define        REALTEK_USB_VENQT_READ                  0xC0
 #define        REALTEK_USB_VENQT_WRITE                 0x40
@@ -1070,6 +1077,8 @@ int rtl_usb_probe(struct usb_interface *intf,
        spin_lock_init(&rtlpriv->locks.usb_lock);
        INIT_WORK(&rtlpriv->works.fill_h2c_cmd,
                  rtl_fill_h2c_cmd_work_callback);
+       INIT_WORK(&rtlpriv->works.lps_change_work,
+                 rtl_lps_change_work_callback);
 
        rtlpriv->usb_data_index = 0;
        init_completion(&rtlpriv->firmware_loading_complete);
index b62d4af6c667c27bbbd3620fde9813c9d6b529b8..45e921401b067b68c9912f82af1c19a1a8c6d048 100644 (file)
@@ -361,7 +361,8 @@ struct ssb_device_id {
        __u16   vendor;
        __u16   coreid;
        __u8    revision;
-};
+       __u8    __pad;
+} __attribute__((packed, aligned(2)));
 #define SSB_DEVICE(_vendor, _coreid, _revision)  \
        { .vendor = _vendor, .coreid = _coreid, .revision = _revision, }
 #define SSB_DEVTABLE_END  \
@@ -377,7 +378,7 @@ struct bcma_device_id {
        __u16   id;
        __u8    rev;
        __u8    class;
-};
+} __attribute__((packed,aligned(2)));
 #define BCMA_CORE(_manuf, _id, _rev, _class)  \
        { .manuf = _manuf, .id = _id, .rev = _rev, .class = _class, }
 #define BCMA_CORETABLE_END  \
index 0af851c3b038186357b8576ec4025bb5193ee1fd..b64b7bce4b94302a8edb923bc54bc1e4b2c8b997 100644 (file)
@@ -59,7 +59,7 @@ struct nfc_hci_ops {
                              struct nfc_target *target);
        int (*event_received)(struct nfc_hci_dev *hdev, u8 gate, u8 event,
                              struct sk_buff *skb);
-       int (*fw_upload)(struct nfc_hci_dev *hdev, const char *firmware_name);
+       int (*fw_download)(struct nfc_hci_dev *hdev, const char *firmware_name);
        int (*discover_se)(struct nfc_hci_dev *dev);
        int (*enable_se)(struct nfc_hci_dev *dev, u32 se_idx);
        int (*disable_se)(struct nfc_hci_dev *dev, u32 se_idx);
index 0e353f1658bb46e638b287ee2bbfdbd33b37a584..5f286b726bb691b3f62e3b6800870ea940a3d65f 100644 (file)
@@ -68,7 +68,7 @@ struct nfc_ops {
                             void *cb_context);
        int (*tm_send)(struct nfc_dev *dev, struct sk_buff *skb);
        int (*check_presence)(struct nfc_dev *dev, struct nfc_target *target);
-       int (*fw_upload)(struct nfc_dev *dev, const char *firmware_name);
+       int (*fw_download)(struct nfc_dev *dev, const char *firmware_name);
 
        /* Secure Element API */
        int (*discover_se)(struct nfc_dev *dev);
@@ -127,7 +127,7 @@ struct nfc_dev {
        int targets_generation;
        struct device dev;
        bool dev_up;
-       bool fw_upload_in_progress;
+       bool fw_download_in_progress;
        u8 rf_mode;
        bool polling;
        struct nfc_target *active_target;
index caed0f324d5ffc6fd88a59dda72f51636af0707a..8137dd8d2adffd1c91d4caf76dfa08b47501408a 100644 (file)
@@ -69,8 +69,8 @@
  *     starting a poll from a device which has a secure element enabled means
  *     we want to do SE based card emulation.
  * @NFC_CMD_DISABLE_SE: Disable the physical link to a specific secure element.
- * @NFC_CMD_FW_UPLOAD: Request to Load/flash firmware, or event to inform that
- *     some firmware was loaded
+ * @NFC_CMD_FW_DOWNLOAD: Request to Load/flash firmware, or event to inform
+ *     that some firmware was loaded
  */
 enum nfc_commands {
        NFC_CMD_UNSPEC,
@@ -94,7 +94,7 @@ enum nfc_commands {
        NFC_CMD_DISABLE_SE,
        NFC_CMD_LLC_SDREQ,
        NFC_EVENT_LLC_SDRES,
-       NFC_CMD_FW_UPLOAD,
+       NFC_CMD_FW_DOWNLOAD,
        NFC_EVENT_SE_ADDED,
        NFC_EVENT_SE_REMOVED,
 /* private: internal use only */
index e3a349977595f2aff6bd27f49e2ee9ee00164470..cc27297da5a9f9094e3079ef43e207dbd9848b68 100644 (file)
@@ -513,7 +513,10 @@ static void hci_init2_req(struct hci_request *req, unsigned long opt)
 
        hci_setup_event_mask(req);
 
-       if (hdev->hci_ver > BLUETOOTH_VER_1_1)
+       /* AVM Berlin (31), aka "BlueFRITZ!", doesn't support the read
+        * local supported commands HCI command.
+        */
+       if (hdev->manufacturer != 31 && hdev->hci_ver > BLUETOOTH_VER_1_1)
                hci_req_add(req, HCI_OP_READ_LOCAL_COMMANDS, 0, NULL);
 
        if (lmp_ssp_capable(hdev)) {
@@ -2165,10 +2168,6 @@ int hci_register_dev(struct hci_dev *hdev)
 
        BT_DBG("%p name %s bus %d", hdev, hdev->name, hdev->bus);
 
-       write_lock(&hci_dev_list_lock);
-       list_add(&hdev->list, &hci_dev_list);
-       write_unlock(&hci_dev_list_lock);
-
        hdev->workqueue = alloc_workqueue("%s", WQ_HIGHPRI | WQ_UNBOUND |
                                          WQ_MEM_RECLAIM, 1, hdev->name);
        if (!hdev->workqueue) {
@@ -2203,6 +2202,10 @@ int hci_register_dev(struct hci_dev *hdev)
        if (hdev->dev_type != HCI_AMP)
                set_bit(HCI_AUTO_OFF, &hdev->dev_flags);
 
+       write_lock(&hci_dev_list_lock);
+       list_add(&hdev->list, &hci_dev_list);
+       write_unlock(&hci_dev_list_lock);
+
        hci_notify(hdev, HCI_DEV_REG);
        hci_dev_hold(hdev);
 
@@ -2215,9 +2218,6 @@ err_wqueue:
        destroy_workqueue(hdev->req_workqueue);
 err:
        ida_simple_remove(&hci_index_ida, hdev->id);
-       write_lock(&hci_dev_list_lock);
-       list_del(&hdev->list);
-       write_unlock(&hci_dev_list_lock);
 
        return error;
 }
@@ -3399,8 +3399,16 @@ void hci_req_cmd_complete(struct hci_dev *hdev, u16 opcode, u8 status)
         */
        if (hdev->sent_cmd) {
                req_complete = bt_cb(hdev->sent_cmd)->req.complete;
-               if (req_complete)
+
+               if (req_complete) {
+                       /* We must set the complete callback to NULL to
+                        * avoid calling the callback more than once if
+                        * this function gets called again.
+                        */
+                       bt_cb(hdev->sent_cmd)->req.complete = NULL;
+
                        goto call_complete;
+               }
        }
 
        /* Remove all pending commands belonging to this request */
index 8184d121ff0904a285529ff234f75c3f15f522e5..43dd7525bfcba54c02dbd9dde2bd89cfc2d29c97 100644 (file)
@@ -666,6 +666,8 @@ static void ieee80211_get_et_stats(struct wiphy *wiphy,
                        if (sta->sdata->dev != dev)
                                continue;
 
+                       sinfo.filled = 0;
+                       sta_set_sinfo(sta, &sinfo);
                        i = 0;
                        ADD_STA_STATS(sta);
                }
index 3b7bfc01ee36e922927958be79e1ec7414c8a3d6..22290a929b94595445865baecdb692aff5e0be9c 100644 (file)
@@ -229,6 +229,10 @@ void ieee80211_mps_sta_status_update(struct sta_info *sta)
        enum nl80211_mesh_power_mode pm;
        bool do_buffer;
 
+       /* For non-assoc STA, prevent buffering or frame transmission */
+       if (sta->sta_state < IEEE80211_STA_ASSOC)
+               return;
+
        /*
         * use peer-specific power mode if peering is established and the
         * peer's power mode is known
index ae31968d42d3b855eebe05dcf0e660b4d367ff8f..cc9e02d79b550106ee07b6aca48ffa9e18081a45 100644 (file)
 #include "led.h"
 
 #define IEEE80211_AUTH_TIMEOUT         (HZ / 5)
+#define IEEE80211_AUTH_TIMEOUT_LONG    (HZ / 2)
 #define IEEE80211_AUTH_TIMEOUT_SHORT   (HZ / 10)
 #define IEEE80211_AUTH_MAX_TRIES       3
 #define IEEE80211_AUTH_WAIT_ASSOC      (HZ * 5)
 #define IEEE80211_ASSOC_TIMEOUT                (HZ / 5)
+#define IEEE80211_ASSOC_TIMEOUT_LONG   (HZ / 2)
 #define IEEE80211_ASSOC_TIMEOUT_SHORT  (HZ / 10)
 #define IEEE80211_ASSOC_MAX_TRIES      3
 
@@ -209,8 +211,9 @@ ieee80211_determine_chantype(struct ieee80211_sub_if_data *sdata,
                             struct ieee80211_channel *channel,
                             const struct ieee80211_ht_operation *ht_oper,
                             const struct ieee80211_vht_operation *vht_oper,
-                            struct cfg80211_chan_def *chandef, bool verbose)
+                            struct cfg80211_chan_def *chandef, bool tracking)
 {
+       struct ieee80211_if_managed *ifmgd = &sdata->u.mgd;
        struct cfg80211_chan_def vht_chandef;
        u32 ht_cfreq, ret;
 
@@ -229,7 +232,7 @@ ieee80211_determine_chantype(struct ieee80211_sub_if_data *sdata,
        ht_cfreq = ieee80211_channel_to_frequency(ht_oper->primary_chan,
                                                  channel->band);
        /* check that channel matches the right operating channel */
-       if (channel->center_freq != ht_cfreq) {
+       if (!tracking && channel->center_freq != ht_cfreq) {
                /*
                 * It's possible that some APs are confused here;
                 * Netgear WNDR3700 sometimes reports 4 higher than
@@ -237,11 +240,10 @@ ieee80211_determine_chantype(struct ieee80211_sub_if_data *sdata,
                 * since we look at probe response/beacon data here
                 * it should be OK.
                 */
-               if (verbose)
-                       sdata_info(sdata,
-                                  "Wrong control channel: center-freq: %d ht-cfreq: %d ht->primary_chan: %d band: %d - Disabling HT\n",
-                                  channel->center_freq, ht_cfreq,
-                                  ht_oper->primary_chan, channel->band);
+               sdata_info(sdata,
+                          "Wrong control channel: center-freq: %d ht-cfreq: %d ht->primary_chan: %d band: %d - Disabling HT\n",
+                          channel->center_freq, ht_cfreq,
+                          ht_oper->primary_chan, channel->band);
                ret = IEEE80211_STA_DISABLE_HT | IEEE80211_STA_DISABLE_VHT;
                goto out;
        }
@@ -295,7 +297,7 @@ ieee80211_determine_chantype(struct ieee80211_sub_if_data *sdata,
                                channel->band);
                break;
        default:
-               if (verbose)
+               if (!(ifmgd->flags & IEEE80211_STA_DISABLE_VHT))
                        sdata_info(sdata,
                                   "AP VHT operation IE has invalid channel width (%d), disable VHT\n",
                                   vht_oper->chan_width);
@@ -304,7 +306,7 @@ ieee80211_determine_chantype(struct ieee80211_sub_if_data *sdata,
        }
 
        if (!cfg80211_chandef_valid(&vht_chandef)) {
-               if (verbose)
+               if (!(ifmgd->flags & IEEE80211_STA_DISABLE_VHT))
                        sdata_info(sdata,
                                   "AP VHT information is invalid, disable VHT\n");
                ret = IEEE80211_STA_DISABLE_VHT;
@@ -317,7 +319,7 @@ ieee80211_determine_chantype(struct ieee80211_sub_if_data *sdata,
        }
 
        if (!cfg80211_chandef_compatible(chandef, &vht_chandef)) {
-               if (verbose)
+               if (!(ifmgd->flags & IEEE80211_STA_DISABLE_VHT))
                        sdata_info(sdata,
                                   "AP VHT information doesn't match HT, disable VHT\n");
                ret = IEEE80211_STA_DISABLE_VHT;
@@ -333,18 +335,27 @@ out:
        if (ret & IEEE80211_STA_DISABLE_VHT)
                vht_chandef = *chandef;
 
+       /*
+        * Ignore the DISABLED flag when we're already connected and only
+        * tracking the APs beacon for bandwidth changes - otherwise we
+        * might get disconnected here if we connect to an AP, update our
+        * regulatory information based on the AP's country IE and the
+        * information we have is wrong/outdated and disables the channel
+        * that we're actually using for the connection to the AP.
+        */
        while (!cfg80211_chandef_usable(sdata->local->hw.wiphy, chandef,
-                                       IEEE80211_CHAN_DISABLED)) {
+                                       tracking ? 0 :
+                                                  IEEE80211_CHAN_DISABLED)) {
                if (WARN_ON(chandef->width == NL80211_CHAN_WIDTH_20_NOHT)) {
                        ret = IEEE80211_STA_DISABLE_HT |
                              IEEE80211_STA_DISABLE_VHT;
-                       goto out;
+                       break;
                }
 
                ret |= chandef_downgrade(chandef);
        }
 
-       if (chandef->width != vht_chandef.width && verbose)
+       if (chandef->width != vht_chandef.width && !tracking)
                sdata_info(sdata,
                           "capabilities/regulatory prevented using AP HT/VHT configuration, downgraded\n");
 
@@ -384,7 +395,7 @@ static int ieee80211_config_bw(struct ieee80211_sub_if_data *sdata,
 
        /* calculate new channel (type) based on HT/VHT operation IEs */
        flags = ieee80211_determine_chantype(sdata, sband, chan, ht_oper,
-                                            vht_oper, &chandef, false);
+                                            vht_oper, &chandef, true);
 
        /*
         * Downgrade the new channel if we associated with restricted
@@ -3394,10 +3405,13 @@ static int ieee80211_probe_auth(struct ieee80211_sub_if_data *sdata)
 
        if (tx_flags == 0) {
                auth_data->timeout = jiffies + IEEE80211_AUTH_TIMEOUT;
-               ifmgd->auth_data->timeout_started = true;
+               auth_data->timeout_started = true;
                run_again(sdata, auth_data->timeout);
        } else {
-               auth_data->timeout_started = false;
+               auth_data->timeout =
+                       round_jiffies_up(jiffies + IEEE80211_AUTH_TIMEOUT_LONG);
+               auth_data->timeout_started = true;
+               run_again(sdata, auth_data->timeout);
        }
 
        return 0;
@@ -3434,7 +3448,11 @@ static int ieee80211_do_assoc(struct ieee80211_sub_if_data *sdata)
                assoc_data->timeout_started = true;
                run_again(sdata, assoc_data->timeout);
        } else {
-               assoc_data->timeout_started = false;
+               assoc_data->timeout =
+                       round_jiffies_up(jiffies +
+                                        IEEE80211_ASSOC_TIMEOUT_LONG);
+               assoc_data->timeout_started = true;
+               run_again(sdata, assoc_data->timeout);
        }
 
        return 0;
@@ -3829,7 +3847,7 @@ static int ieee80211_prep_channel(struct ieee80211_sub_if_data *sdata,
        ifmgd->flags |= ieee80211_determine_chantype(sdata, sband,
                                                     cbss->channel,
                                                     ht_oper, vht_oper,
-                                                    &chandef, true);
+                                                    &chandef, false);
 
        sdata->needed_rx_chains = min(ieee80211_ht_vht_rx_chains(sdata, cbss),
                                      local->rx_chains);
index 7fc5d0d8149a53f2a20377499841657dd9a97c7c..340126204343a063902bb205675cc14bea743a4c 100644 (file)
@@ -99,10 +99,13 @@ int __ieee80211_suspend(struct ieee80211_hw *hw, struct cfg80211_wowlan *wowlan)
        }
        mutex_unlock(&local->sta_mtx);
 
-       /* remove all interfaces */
+       /* remove all interfaces that were created in the driver */
        list_for_each_entry(sdata, &local->interfaces, list) {
-               if (!ieee80211_sdata_running(sdata))
+               if (!ieee80211_sdata_running(sdata) ||
+                   sdata->vif.type == NL80211_IFTYPE_AP_VLAN ||
+                   sdata->vif.type == NL80211_IFTYPE_MONITOR)
                        continue;
+
                drv_remove_interface(local, sdata);
        }
 
index ac7ef5414bdede030d289a81946eaabc7b5d7a88..e6512e2ffd200223cd5cb75090802a98f544bb7d 100644 (file)
@@ -290,7 +290,7 @@ minstrel_get_rate(void *priv, struct ieee80211_sta *sta,
        struct minstrel_rate *msr, *mr;
        unsigned int ndx;
        bool mrr_capable;
-       bool prev_sample = mi->prev_sample;
+       bool prev_sample;
        int delta;
        int sampling_ratio;
 
@@ -314,6 +314,7 @@ minstrel_get_rate(void *priv, struct ieee80211_sta *sta,
                        (mi->sample_count + mi->sample_deferred / 2);
 
        /* delta < 0: no sampling required */
+       prev_sample = mi->prev_sample;
        mi->prev_sample = false;
        if (delta < 0 || (!mrr_capable && prev_sample))
                return;
index 5b2d3012b9830aef8d9101c26ba761402993b382..f5aed963b22e62cd997872d1068bfb6c45eeda7a 100644 (file)
@@ -804,10 +804,18 @@ minstrel_ht_get_rate(void *priv, struct ieee80211_sta *sta, void *priv_sta,
 
        sample_group = &minstrel_mcs_groups[sample_idx / MCS_GROUP_RATES];
        info->flags |= IEEE80211_TX_CTL_RATE_CTRL_PROBE;
+       rate->count = 1;
+
+       if (sample_idx / MCS_GROUP_RATES == MINSTREL_CCK_GROUP) {
+               int idx = sample_idx % ARRAY_SIZE(mp->cck_rates);
+               rate->idx = mp->cck_rates[idx];
+               rate->flags = 0;
+               return;
+       }
+
        rate->idx = sample_idx % MCS_GROUP_RATES +
                    (sample_group->streams - 1) * MCS_GROUP_RATES;
        rate->flags = IEEE80211_TX_RC_MCS | sample_group->flags;
-       rate->count = 1;
 }
 
 static void
index 23dbcfc69b3b7f09ffc35c81d03dddc38d36da5a..2c5a79bd3777f5c313d3205a1154ef6b714a8d4d 100644 (file)
@@ -936,8 +936,14 @@ ieee80211_rx_h_check(struct ieee80211_rx_data *rx)
        struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)rx->skb->data;
        struct ieee80211_rx_status *status = IEEE80211_SKB_RXCB(rx->skb);
 
-       /* Drop duplicate 802.11 retransmissions (IEEE 802.11 Chap. 9.2.9) */
-       if (rx->sta && !is_multicast_ether_addr(hdr->addr1)) {
+       /*
+        * Drop duplicate 802.11 retransmissions
+        * (IEEE 802.11-2012: 9.3.2.10 "Duplicate detection and recovery")
+        */
+       if (rx->skb->len >= 24 && rx->sta &&
+           !ieee80211_is_ctl(hdr->frame_control) &&
+           !ieee80211_is_qos_nullfunc(hdr->frame_control) &&
+           !is_multicast_ether_addr(hdr->addr1)) {
                if (unlikely(ieee80211_has_retry(hdr->frame_control) &&
                             rx->sta->last_seq_ctrl[rx->seqno_idx] ==
                             hdr->seq_ctrl)) {
index dc96a83aa6abb6659311e11ef13f97dc81c3b494..1d074dd1650ff2fd326dd141eedb828d812a12e6 100644 (file)
@@ -44,7 +44,7 @@ DEFINE_MUTEX(nfc_devlist_mutex);
 /* NFC device ID bitmap */
 static DEFINE_IDA(nfc_index_ida);
 
-int nfc_fw_upload(struct nfc_dev *dev, const char *firmware_name)
+int nfc_fw_download(struct nfc_dev *dev, const char *firmware_name)
 {
        int rc = 0;
 
@@ -62,28 +62,28 @@ int nfc_fw_upload(struct nfc_dev *dev, const char *firmware_name)
                goto error;
        }
 
-       if (!dev->ops->fw_upload) {
+       if (!dev->ops->fw_download) {
                rc = -EOPNOTSUPP;
                goto error;
        }
 
-       dev->fw_upload_in_progress = true;
-       rc = dev->ops->fw_upload(dev, firmware_name);
+       dev->fw_download_in_progress = true;
+       rc = dev->ops->fw_download(dev, firmware_name);
        if (rc)
-               dev->fw_upload_in_progress = false;
+               dev->fw_download_in_progress = false;
 
 error:
        device_unlock(&dev->dev);
        return rc;
 }
 
-int nfc_fw_upload_done(struct nfc_dev *dev, const char *firmware_name)
+int nfc_fw_download_done(struct nfc_dev *dev, const char *firmware_name)
 {
-       dev->fw_upload_in_progress = false;
+       dev->fw_download_in_progress = false;
 
-       return nfc_genl_fw_upload_done(dev, firmware_name);
+       return nfc_genl_fw_download_done(dev, firmware_name);
 }
-EXPORT_SYMBOL(nfc_fw_upload_done);
+EXPORT_SYMBOL(nfc_fw_download_done);
 
 /**
  * nfc_dev_up - turn on the NFC device
@@ -110,7 +110,7 @@ int nfc_dev_up(struct nfc_dev *dev)
                goto error;
        }
 
-       if (dev->fw_upload_in_progress) {
+       if (dev->fw_download_in_progress) {
                rc = -EBUSY;
                goto error;
        }
index 7b1c186736ebf924977ed8eb9040357ab88f3c3c..fe66908401f55ed5f608a75b559e5fad1ff15548 100644 (file)
@@ -809,14 +809,14 @@ static void nfc_hci_recv_from_llc(struct nfc_hci_dev *hdev, struct sk_buff *skb)
        }
 }
 
-static int hci_fw_upload(struct nfc_dev *nfc_dev, const char *firmware_name)
+static int hci_fw_download(struct nfc_dev *nfc_dev, const char *firmware_name)
 {
        struct nfc_hci_dev *hdev = nfc_get_drvdata(nfc_dev);
 
-       if (!hdev->ops->fw_upload)
+       if (!hdev->ops->fw_download)
                return -ENOTSUPP;
 
-       return hdev->ops->fw_upload(hdev, firmware_name);
+       return hdev->ops->fw_download(hdev, firmware_name);
 }
 
 static struct nfc_ops hci_nfc_ops = {
@@ -831,7 +831,7 @@ static struct nfc_ops hci_nfc_ops = {
        .im_transceive = hci_transceive,
        .tm_send = hci_tm_send,
        .check_presence = hci_check_presence,
-       .fw_upload = hci_fw_upload,
+       .fw_download = hci_fw_download,
        .discover_se = hci_discover_se,
        .enable_se = hci_enable_se,
        .disable_se = hci_disable_se,
index 2a2416080b4fbfcf2127a4cab2abc755b5188c06..a4f1e42e34818c91eeb2b527c7b547a718454459 100644 (file)
@@ -11,6 +11,7 @@ config NFC_NCI
 
 config NFC_NCI_SPI
        depends on NFC_NCI && SPI
+       select CRC_CCITT
        bool "NCI over SPI protocol support"
        default n
        help
index b05ad909778fe5978677f3f81a31360220f98eb7..f16fd59d41607d80aeeae916ae3d43153a0a5b4e 100644 (file)
@@ -1089,7 +1089,7 @@ exit:
        return rc;
 }
 
-static int nfc_genl_fw_upload(struct sk_buff *skb, struct genl_info *info)
+static int nfc_genl_fw_download(struct sk_buff *skb, struct genl_info *info)
 {
        struct nfc_dev *dev;
        int rc;
@@ -1108,13 +1108,13 @@ static int nfc_genl_fw_upload(struct sk_buff *skb, struct genl_info *info)
        nla_strlcpy(firmware_name, info->attrs[NFC_ATTR_FIRMWARE_NAME],
                    sizeof(firmware_name));
 
-       rc = nfc_fw_upload(dev, firmware_name);
+       rc = nfc_fw_download(dev, firmware_name);
 
        nfc_put_device(dev);
        return rc;
 }
 
-int nfc_genl_fw_upload_done(struct nfc_dev *dev, const char *firmware_name)
+int nfc_genl_fw_download_done(struct nfc_dev *dev, const char *firmware_name)
 {
        struct sk_buff *msg;
        void *hdr;
@@ -1124,7 +1124,7 @@ int nfc_genl_fw_upload_done(struct nfc_dev *dev, const char *firmware_name)
                return -ENOMEM;
 
        hdr = genlmsg_put(msg, 0, 0, &nfc_genl_family, 0,
-                         NFC_CMD_FW_UPLOAD);
+                         NFC_CMD_FW_DOWNLOAD);
        if (!hdr)
                goto free_msg;
 
@@ -1251,8 +1251,8 @@ static struct genl_ops nfc_genl_ops[] = {
                .policy = nfc_genl_policy,
        },
        {
-               .cmd = NFC_CMD_FW_UPLOAD,
-               .doit = nfc_genl_fw_upload,
+               .cmd = NFC_CMD_FW_DOWNLOAD,
+               .doit = nfc_genl_fw_download,
                .policy = nfc_genl_policy,
        },
        {
index ee85a1fc1b2443d88982ca6985574936b0359292..820a7850c36ac7e49012869a88472a96358e2220 100644 (file)
@@ -123,10 +123,10 @@ static inline void nfc_device_iter_exit(struct class_dev_iter *iter)
        class_dev_iter_exit(iter);
 }
 
-int nfc_fw_upload(struct nfc_dev *dev, const char *firmware_name);
-int nfc_genl_fw_upload_done(struct nfc_dev *dev, const char *firmware_name);
+int nfc_fw_download(struct nfc_dev *dev, const char *firmware_name);
+int nfc_genl_fw_download_done(struct nfc_dev *dev, const char *firmware_name);
 
-int nfc_fw_upload_done(struct nfc_dev *dev, const char *firmware_name);
+int nfc_fw_download_done(struct nfc_dev *dev, const char *firmware_name);
 
 int nfc_dev_up(struct nfc_dev *dev);
 
index 4f9f216665e9d4d6753172f3c14d7bbdd3f53154..a8c29fa4f1b3b90539f5370b9084056c5774812a 100644 (file)
@@ -765,6 +765,7 @@ void cfg80211_leave(struct cfg80211_registered_device *rdev,
                cfg80211_leave_mesh(rdev, dev);
                break;
        case NL80211_IFTYPE_AP:
+       case NL80211_IFTYPE_P2P_GO:
                cfg80211_stop_ap(rdev, dev);
                break;
        default:
index 1cc47aca7f05baee3e7ffdf18a4e002b2d62279d..3fcba69817e579244e836b2e2d39a1aab14cc210 100644 (file)
@@ -441,10 +441,12 @@ static int nl80211_prepare_wdev_dump(struct sk_buff *skb,
                        goto out_unlock;
                }
                *rdev = wiphy_to_dev((*wdev)->wiphy);
-               cb->args[0] = (*rdev)->wiphy_idx;
+               /* 0 is the first index - add 1 to parse only once */
+               cb->args[0] = (*rdev)->wiphy_idx + 1;
                cb->args[1] = (*wdev)->identifier;
        } else {
-               struct wiphy *wiphy = wiphy_idx_to_wiphy(cb->args[0]);
+               /* subtract the 1 again here */
+               struct wiphy *wiphy = wiphy_idx_to_wiphy(cb->args[0] - 1);
                struct wireless_dev *tmp;
 
                if (!wiphy) {
@@ -4770,9 +4772,9 @@ do {                                                                          \
        FILL_IN_MESH_PARAM_IF_SET(tb, cfg, dot11MeshForwarding, 0, 1,
                                  mask, NL80211_MESHCONF_FORWARDING,
                                  nla_get_u8);
-       FILL_IN_MESH_PARAM_IF_SET(tb, cfg, rssi_threshold, 1, 255,
+       FILL_IN_MESH_PARAM_IF_SET(tb, cfg, rssi_threshold, -255, 0,
                                  mask, NL80211_MESHCONF_RSSI_THRESHOLD,
-                                 nla_get_u32);
+                                 nla_get_s32);
        FILL_IN_MESH_PARAM_IF_SET(tb, cfg, ht_opmode, 0, 16,
                                  mask, NL80211_MESHCONF_HT_OPMODE,
                                  nla_get_u16);
@@ -6613,12 +6615,14 @@ EXPORT_SYMBOL(cfg80211_testmode_alloc_event_skb);
 
 void cfg80211_testmode_event(struct sk_buff *skb, gfp_t gfp)
 {
+       struct cfg80211_registered_device *rdev = ((void **)skb->cb)[0];
        void *hdr = ((void **)skb->cb)[1];
        struct nlattr *data = ((void **)skb->cb)[2];
 
        nla_nest_end(skb, data);
        genlmsg_end(skb, hdr);
-       genlmsg_multicast(skb, 0, nl80211_testmode_mcgrp.id, gfp);
+       genlmsg_multicast_netns(wiphy_net(&rdev->wiphy), skb, 0,
+                               nl80211_testmode_mcgrp.id, gfp);
 }
 EXPORT_SYMBOL(cfg80211_testmode_event);
 #endif
@@ -10064,7 +10068,8 @@ void cfg80211_mgmt_tx_status(struct wireless_dev *wdev, u64 cookie,
 
        genlmsg_end(msg, hdr);
 
-       genlmsg_multicast(msg, 0, nl80211_mlme_mcgrp.id, gfp);
+       genlmsg_multicast_netns(wiphy_net(&rdev->wiphy), msg, 0,
+                               nl80211_mlme_mcgrp.id, gfp);
        return;
 
  nla_put_failure:
index 5a24c986f34be27e61613f0deb421a35efc61533..de06d5d1287f97b6f6c8a1fd6b3e59371d80ae3e 100644 (file)
@@ -2247,10 +2247,13 @@ int reg_device_uevent(struct device *dev, struct kobj_uevent_env *env)
 
 void wiphy_regulatory_register(struct wiphy *wiphy)
 {
+       struct regulatory_request *lr;
+
        if (!reg_dev_ignore_cell_hint(wiphy))
                reg_num_devs_support_basehint++;
 
-       wiphy_update_regulatory(wiphy, NL80211_REGDOM_SET_BY_CORE);
+       lr = get_last_request();
+       wiphy_update_regulatory(wiphy, lr->initiator);
 }
 
 void wiphy_regulatory_deregister(struct wiphy *wiphy)
@@ -2279,7 +2282,9 @@ void wiphy_regulatory_deregister(struct wiphy *wiphy)
 static void reg_timeout_work(struct work_struct *work)
 {
        REG_DBG_PRINT("Timeout while waiting for CRDA to reply, restoring regulatory settings\n");
+       rtnl_lock();
        restore_regulatory_settings(true);
+       rtnl_unlock();
 }
 
 int __init regulatory_init(void)
index 1d3cfb1a3f28b3a74a32c1c629ddbcba7fb30def..81c8a10d743c04fb76981498b42588f9b821f33f 100644 (file)
@@ -34,8 +34,10 @@ struct cfg80211_conn {
                CFG80211_CONN_SCAN_AGAIN,
                CFG80211_CONN_AUTHENTICATE_NEXT,
                CFG80211_CONN_AUTHENTICATING,
+               CFG80211_CONN_AUTH_FAILED,
                CFG80211_CONN_ASSOCIATE_NEXT,
                CFG80211_CONN_ASSOCIATING,
+               CFG80211_CONN_ASSOC_FAILED,
                CFG80211_CONN_DEAUTH,
                CFG80211_CONN_CONNECTED,
        } state;
@@ -164,6 +166,8 @@ static int cfg80211_conn_do_work(struct wireless_dev *wdev)
                                          NULL, 0,
                                          params->key, params->key_len,
                                          params->key_idx, NULL, 0);
+       case CFG80211_CONN_AUTH_FAILED:
+               return -ENOTCONN;
        case CFG80211_CONN_ASSOCIATE_NEXT:
                BUG_ON(!rdev->ops->assoc);
                wdev->conn->state = CFG80211_CONN_ASSOCIATING;
@@ -188,10 +192,17 @@ static int cfg80211_conn_do_work(struct wireless_dev *wdev)
                                             WLAN_REASON_DEAUTH_LEAVING,
                                             false);
                return err;
+       case CFG80211_CONN_ASSOC_FAILED:
+               cfg80211_mlme_deauth(rdev, wdev->netdev, params->bssid,
+                                    NULL, 0,
+                                    WLAN_REASON_DEAUTH_LEAVING, false);
+               return -ENOTCONN;
        case CFG80211_CONN_DEAUTH:
                cfg80211_mlme_deauth(rdev, wdev->netdev, params->bssid,
                                     NULL, 0,
                                     WLAN_REASON_DEAUTH_LEAVING, false);
+               /* free directly, disconnected event already sent */
+               cfg80211_sme_free(wdev);
                return 0;
        default:
                return 0;
@@ -371,7 +382,7 @@ bool cfg80211_sme_rx_assoc_resp(struct wireless_dev *wdev, u16 status)
                return true;
        }
 
-       wdev->conn->state = CFG80211_CONN_DEAUTH;
+       wdev->conn->state = CFG80211_CONN_ASSOC_FAILED;
        schedule_work(&rdev->conn_work);
        return false;
 }
@@ -383,7 +394,13 @@ void cfg80211_sme_deauth(struct wireless_dev *wdev)
 
 void cfg80211_sme_auth_timeout(struct wireless_dev *wdev)
 {
-       cfg80211_sme_free(wdev);
+       struct cfg80211_registered_device *rdev = wiphy_to_dev(wdev->wiphy);
+
+       if (!wdev->conn)
+               return;
+
+       wdev->conn->state = CFG80211_CONN_AUTH_FAILED;
+       schedule_work(&rdev->conn_work);
 }
 
 void cfg80211_sme_disassoc(struct wireless_dev *wdev)
@@ -399,7 +416,13 @@ void cfg80211_sme_disassoc(struct wireless_dev *wdev)
 
 void cfg80211_sme_assoc_timeout(struct wireless_dev *wdev)
 {
-       cfg80211_sme_disassoc(wdev);
+       struct cfg80211_registered_device *rdev = wiphy_to_dev(wdev->wiphy);
+
+       if (!wdev->conn)
+               return;
+
+       wdev->conn->state = CFG80211_CONN_ASSOC_FAILED;
+       schedule_work(&rdev->conn_work);
 }
 
 static int cfg80211_sme_connect(struct wireless_dev *wdev,