]> git.proxmox.com Git - mirror_ubuntu-artful-kernel.git/commitdiff
Merge tag 'wireless-drivers-next-for-davem-2017-02-01' of git://git.kernel.org/pub...
authorDavid S. Miller <davem@davemloft.net>
Wed, 1 Feb 2017 17:46:17 +0000 (12:46 -0500)
committerDavid S. Miller <davem@davemloft.net>
Wed, 1 Feb 2017 17:46:17 +0000 (12:46 -0500)
Kalle Valo says:

====================
wireless-drivers-next patches for 4.11

It's nice to see rt2x00 development has becoming active, for example
adding support for a new chip version. Also wcn36xx has been converted
to use the recently merged QCOM_SMD subsystem. Otherwise new features
and fixes it lots of drivers.

Major changes:

iwlwifi

* some more work in preparation for A000 family support
* add support for radiotap timestamps
* some work on our firmware debugging capabilities

wcn36xx

* convert to a proper QCOM_SMD driver (from the platform_driver interface)

ath10k

* VHT160 support
* dump Copy Engine registers during firmware crash
* search board file extension from SMBIOS

wil6210

* add disable_ap_sme module parameter

rt2x00

* support RT3352 with external PA
* support for RT3352 with 20MHz crystal
* add support for RT5350 WiSoC

brcmfmac

* add support for BCM43455 sdio device

rtl8xxxu

* add support for D-Link DWA-131 rev E1, TP-Link TL-WN822N v4 and others
====================

Signed-off-by: David S. Miller <davem@davemloft.net>
156 files changed:
MAINTAINERS
drivers/bcma/main.c
drivers/net/wireless/ath/ath10k/ce.c
drivers/net/wireless/ath/ath10k/ce.h
drivers/net/wireless/ath/ath10k/core.c
drivers/net/wireless/ath/ath10k/core.h
drivers/net/wireless/ath/ath10k/debug.c
drivers/net/wireless/ath/ath10k/htc.c
drivers/net/wireless/ath/ath10k/htc.h
drivers/net/wireless/ath/ath10k/htt_rx.c
drivers/net/wireless/ath/ath10k/hw.h
drivers/net/wireless/ath/ath10k/mac.c
drivers/net/wireless/ath/ath10k/pci.c
drivers/net/wireless/ath/ath10k/pci.h
drivers/net/wireless/ath/ath10k/wmi-tlv.c
drivers/net/wireless/ath/ath10k/wmi-tlv.h
drivers/net/wireless/ath/ath10k/wmi.c
drivers/net/wireless/ath/ath10k/wmi.h
drivers/net/wireless/ath/ath5k/mac80211-ops.c
drivers/net/wireless/ath/ath6kl/sdio.c
drivers/net/wireless/ath/ath9k/Kconfig
drivers/net/wireless/ath/ath9k/Makefile
drivers/net/wireless/ath/ath9k/ar9002_mac.c
drivers/net/wireless/ath/ath9k/ar9003_mac.c
drivers/net/wireless/ath/ath9k/common-debug.h
drivers/net/wireless/ath/ath9k/common-spectral.c
drivers/net/wireless/ath/ath9k/common-spectral.h
drivers/net/wireless/ath/ath9k/eeprom_4k.c
drivers/net/wireless/ath/ath9k/eeprom_9287.c
drivers/net/wireless/ath/ath9k/eeprom_def.c
drivers/net/wireless/ath/ath9k/hw.c
drivers/net/wireless/ath/wcn36xx/Kconfig
drivers/net/wireless/ath/wcn36xx/dxe.c
drivers/net/wireless/ath/wcn36xx/hal.h
drivers/net/wireless/ath/wcn36xx/main.c
drivers/net/wireless/ath/wcn36xx/smd.c
drivers/net/wireless/ath/wcn36xx/smd.h
drivers/net/wireless/ath/wcn36xx/txrx.c
drivers/net/wireless/ath/wcn36xx/wcn36xx.h
drivers/net/wireless/ath/wil6210/cfg80211.c
drivers/net/wireless/ath/wil6210/debugfs.c
drivers/net/wireless/ath/wil6210/ethtool.c
drivers/net/wireless/ath/wil6210/fw.c
drivers/net/wireless/ath/wil6210/fw_inc.c
drivers/net/wireless/ath/wil6210/interrupt.c
drivers/net/wireless/ath/wil6210/main.c
drivers/net/wireless/ath/wil6210/netdev.c
drivers/net/wireless/ath/wil6210/p2p.c
drivers/net/wireless/ath/wil6210/pcie_bus.c
drivers/net/wireless/ath/wil6210/pm.c
drivers/net/wireless/ath/wil6210/pmc.c
drivers/net/wireless/ath/wil6210/rx_reorder.c
drivers/net/wireless/ath/wil6210/txrx.c
drivers/net/wireless/ath/wil6210/wil6210.h
drivers/net/wireless/ath/wil6210/wil_crash_dump.c
drivers/net/wireless/ath/wil6210/wmi.c
drivers/net/wireless/ath/wil6210/wmi.h
drivers/net/wireless/broadcom/brcm80211/brcmfmac/bcmsdh.c
drivers/net/wireless/broadcom/brcm80211/brcmfmac/bus.h
drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c
drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.h
drivers/net/wireless/broadcom/brcm80211/brcmfmac/common.c
drivers/net/wireless/broadcom/brcm80211/brcmfmac/common.h
drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.c
drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.h
drivers/net/wireless/broadcom/brcm80211/brcmfmac/of.c
drivers/net/wireless/broadcom/brcm80211/brcmfmac/of.h
drivers/net/wireless/broadcom/brcm80211/brcmfmac/pcie.c
drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c
drivers/net/wireless/broadcom/brcm80211/brcmfmac/usb.c
drivers/net/wireless/intel/iwlwifi/dvm/debugfs.c
drivers/net/wireless/intel/iwlwifi/dvm/mac80211.c
drivers/net/wireless/intel/iwlwifi/dvm/rs.c
drivers/net/wireless/intel/iwlwifi/dvm/ucode.c
drivers/net/wireless/intel/iwlwifi/iwl-6000.c
drivers/net/wireless/intel/iwlwifi/iwl-7000.c
drivers/net/wireless/intel/iwlwifi/iwl-8000.c
drivers/net/wireless/intel/iwlwifi/iwl-9000.c
drivers/net/wireless/intel/iwlwifi/iwl-a000.c
drivers/net/wireless/intel/iwlwifi/iwl-drv.c
drivers/net/wireless/intel/iwlwifi/iwl-fw-file.h
drivers/net/wireless/intel/iwlwifi/iwl-fw.h
drivers/net/wireless/intel/iwlwifi/mvm/d3.c
drivers/net/wireless/intel/iwlwifi/mvm/debugfs.c
drivers/net/wireless/intel/iwlwifi/mvm/fw-api.h
drivers/net/wireless/intel/iwlwifi/mvm/fw-dbg.c
drivers/net/wireless/intel/iwlwifi/mvm/fw.c
drivers/net/wireless/intel/iwlwifi/mvm/mac-ctxt.c
drivers/net/wireless/intel/iwlwifi/mvm/mac80211.c
drivers/net/wireless/intel/iwlwifi/mvm/mvm.h
drivers/net/wireless/intel/iwlwifi/mvm/rs.c
drivers/net/wireless/intel/iwlwifi/mvm/rx.c
drivers/net/wireless/intel/iwlwifi/mvm/sta.c
drivers/net/wireless/intel/iwlwifi/mvm/tx.c
drivers/net/wireless/intel/iwlwifi/mvm/utils.c
drivers/net/wireless/intel/iwlwifi/pcie/trans.c
drivers/net/wireless/marvell/libertas/cmd.c
drivers/net/wireless/marvell/mwifiex/11n_aggr.c
drivers/net/wireless/marvell/mwifiex/debugfs.c
drivers/net/wireless/marvell/mwifiex/fw.h
drivers/net/wireless/marvell/mwifiex/init.c
drivers/net/wireless/marvell/mwifiex/main.c
drivers/net/wireless/marvell/mwifiex/main.h
drivers/net/wireless/marvell/mwifiex/pcie.c
drivers/net/wireless/marvell/mwifiex/pcie.h
drivers/net/wireless/marvell/mwifiex/sdio.c
drivers/net/wireless/marvell/mwifiex/sdio.h
drivers/net/wireless/marvell/mwifiex/sta_event.c
drivers/net/wireless/marvell/mwifiex/usb.c
drivers/net/wireless/marvell/mwifiex/util.c
drivers/net/wireless/ralink/rt2x00/rt2800.h
drivers/net/wireless/ralink/rt2x00/rt2800lib.c
drivers/net/wireless/ralink/rt2x00/rt2800usb.c
drivers/net/wireless/ralink/rt2x00/rt2x00.h
drivers/net/wireless/ralink/rt2x00/rt2x00config.c
drivers/net/wireless/ralink/rt2x00/rt2x00mac.c
drivers/net/wireless/ralink/rt2x00/rt2x00mmio.c
drivers/net/wireless/ralink/rt2x00/rt2x00soc.c
drivers/net/wireless/ralink/rt2x00/rt2x00usb.c
drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu.h
drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu_8192c.c
drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu_8192e.c
drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu_8723a.c
drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu_8723b.c
drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu_core.c
drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu_regs.h
drivers/net/wireless/realtek/rtlwifi/base.c
drivers/net/wireless/realtek/rtlwifi/base.h
drivers/net/wireless/realtek/rtlwifi/debug.c
drivers/net/wireless/realtek/rtlwifi/debug.h
drivers/net/wireless/realtek/rtlwifi/efuse.c
drivers/net/wireless/realtek/rtlwifi/efuse.h
drivers/net/wireless/realtek/rtlwifi/pci.c
drivers/net/wireless/realtek/rtlwifi/rtl8188ee/fw.c
drivers/net/wireless/realtek/rtlwifi/rtl8188ee/sw.c
drivers/net/wireless/realtek/rtlwifi/rtl8192c/fw_common.c
drivers/net/wireless/realtek/rtlwifi/rtl8192ce/sw.c
drivers/net/wireless/realtek/rtlwifi/rtl8192cu/sw.c
drivers/net/wireless/realtek/rtlwifi/rtl8192cu/trx.c
drivers/net/wireless/realtek/rtlwifi/rtl8192cu/trx.h
drivers/net/wireless/realtek/rtlwifi/rtl8192de/fw.c
drivers/net/wireless/realtek/rtlwifi/rtl8192de/sw.c
drivers/net/wireless/realtek/rtlwifi/rtl8192ee/fw.c
drivers/net/wireless/realtek/rtlwifi/rtl8192ee/sw.c
drivers/net/wireless/realtek/rtlwifi/rtl8192se/sw.c
drivers/net/wireless/realtek/rtlwifi/rtl8723ae/sw.c
drivers/net/wireless/realtek/rtlwifi/rtl8723be/sw.c
drivers/net/wireless/realtek/rtlwifi/rtl8723com/fw_common.c
drivers/net/wireless/realtek/rtlwifi/rtl8723com/fw_common.h
drivers/net/wireless/realtek/rtlwifi/rtl8821ae/fw.c
drivers/net/wireless/realtek/rtlwifi/rtl8821ae/sw.c
drivers/net/wireless/realtek/rtlwifi/usb.c
drivers/net/wireless/realtek/rtlwifi/wifi.h
drivers/net/wireless/ti/wlcore/sdio.c
include/linux/mmc/sdio_ids.h
include/linux/soc/qcom/smem_state.h

index cc106f71a9b830c1be00445bfd1ac791058635e7..300d2ec2bb3585f6a90e7275d3f5824c0d2db63c 100644 (file)
@@ -10607,7 +10607,7 @@ F:      drivers/net/wireless/realtek/rtlwifi/
 F:     drivers/net/wireless/realtek/rtlwifi/rtl8192ce/
 
 RTL8XXXU WIRELESS DRIVER (rtl8xxxu)
-M:     Jes Sorensen <Jes.Sorensen@redhat.com>
+M:     Jes Sorensen <Jes.Sorensen@gmail.com>
 L:     linux-wireless@vger.kernel.org
 T:     git git://git.kernel.org/pub/scm/linux/kernel/git/jes/linux.git rtl8xxxu-devel
 S:     Maintained
index 2c1798e38abd166bb62596e81c9921a13c452d94..12da68ec48baa751d78899e89ac7da2e60f197f7 100644 (file)
@@ -136,17 +136,17 @@ static bool bcma_is_core_needed_early(u16 core_id)
        return false;
 }
 
-static struct device_node *bcma_of_find_child_device(struct platform_device *parent,
+static struct device_node *bcma_of_find_child_device(struct device *parent,
                                                     struct bcma_device *core)
 {
        struct device_node *node;
        u64 size;
        const __be32 *reg;
 
-       if (!parent || !parent->dev.of_node)
+       if (!parent->of_node)
                return NULL;
 
-       for_each_child_of_node(parent->dev.of_node, node) {
+       for_each_child_of_node(parent->of_node, node) {
                reg = of_get_address(node, 0, &size, NULL);
                if (!reg)
                        continue;
@@ -156,7 +156,7 @@ static struct device_node *bcma_of_find_child_device(struct platform_device *par
        return NULL;
 }
 
-static int bcma_of_irq_parse(struct platform_device *parent,
+static int bcma_of_irq_parse(struct device *parent,
                             struct bcma_device *core,
                             struct of_phandle_args *out_irq, int num)
 {
@@ -169,7 +169,7 @@ static int bcma_of_irq_parse(struct platform_device *parent,
                        return rc;
        }
 
-       out_irq->np = parent->dev.of_node;
+       out_irq->np = parent->of_node;
        out_irq->args_count = 1;
        out_irq->args[0] = num;
 
@@ -177,13 +177,13 @@ static int bcma_of_irq_parse(struct platform_device *parent,
        return of_irq_parse_raw(laddr, out_irq);
 }
 
-static unsigned int bcma_of_get_irq(struct platform_device *parent,
+static unsigned int bcma_of_get_irq(struct device *parent,
                                    struct bcma_device *core, int num)
 {
        struct of_phandle_args out_irq;
        int ret;
 
-       if (!IS_ENABLED(CONFIG_OF_IRQ) || !parent || !parent->dev.of_node)
+       if (!IS_ENABLED(CONFIG_OF_IRQ) || !parent->of_node)
                return 0;
 
        ret = bcma_of_irq_parse(parent, core, &out_irq, num);
@@ -196,7 +196,7 @@ static unsigned int bcma_of_get_irq(struct platform_device *parent,
        return irq_create_of_mapping(&out_irq);
 }
 
-static void bcma_of_fill_device(struct platform_device *parent,
+static void bcma_of_fill_device(struct device *parent,
                                struct bcma_device *core)
 {
        struct device_node *node;
@@ -227,7 +227,7 @@ unsigned int bcma_core_irq(struct bcma_device *core, int num)
                        return mips_irq <= 4 ? mips_irq + 2 : 0;
                }
                if (bus->host_pdev)
-                       return bcma_of_get_irq(bus->host_pdev, core, num);
+                       return bcma_of_get_irq(&bus->host_pdev->dev, core, num);
                return 0;
        case BCMA_HOSTTYPE_SDIO:
                return 0;
@@ -253,7 +253,8 @@ void bcma_prepare_core(struct bcma_bus *bus, struct bcma_device *core)
                if (IS_ENABLED(CONFIG_OF) && bus->host_pdev) {
                        core->dma_dev = &bus->host_pdev->dev;
                        core->dev.parent = &bus->host_pdev->dev;
-                       bcma_of_fill_device(bus->host_pdev, core);
+                       if (core->dev.parent)
+                               bcma_of_fill_device(core->dev.parent, core);
                } else {
                        core->dev.dma_mask = &core->dev.coherent_dma_mask;
                        core->dma_dev = &core->dev;
@@ -633,8 +634,11 @@ static int bcma_device_probe(struct device *dev)
                                               drv);
        int err = 0;
 
+       get_device(dev);
        if (adrv->probe)
                err = adrv->probe(core);
+       if (err)
+               put_device(dev);
 
        return err;
 }
@@ -647,6 +651,7 @@ static int bcma_device_remove(struct device *dev)
 
        if (adrv->remove)
                adrv->remove(core);
+       put_device(dev);
 
        return 0;
 }
index 0b4d7965988445d0e9660cafeb1a5fd6e3eb64ad..da466ab2d823ea0e1a06812eb58eb2cd69de3cc9 100644 (file)
@@ -958,7 +958,7 @@ ath10k_ce_alloc_dest_ring(struct ath10k *ar, unsigned int ce_id,
         * coherent DMA are unsupported
         */
        dest_ring->base_addr_owner_space_unaligned =
-               dma_alloc_coherent(ar->dev,
+               dma_zalloc_coherent(ar->dev,
                                   (nentries * sizeof(struct ce_desc) +
                                    CE_DESC_RING_ALIGN),
                                   &base_addr, GFP_KERNEL);
@@ -969,13 +969,6 @@ ath10k_ce_alloc_dest_ring(struct ath10k *ar, unsigned int ce_id,
 
        dest_ring->base_addr_ce_space_unaligned = base_addr;
 
-       /*
-        * Correctly initialize memory to 0 to prevent garbage
-        * data crashing system when download firmware
-        */
-       memset(dest_ring->base_addr_owner_space_unaligned, 0,
-              nentries * sizeof(struct ce_desc) + CE_DESC_RING_ALIGN);
-
        dest_ring->base_addr_owner_space = PTR_ALIGN(
                        dest_ring->base_addr_owner_space_unaligned,
                        CE_DESC_RING_ALIGN);
@@ -1130,3 +1123,42 @@ void ath10k_ce_free_pipe(struct ath10k *ar, int ce_id)
        ce_state->src_ring = NULL;
        ce_state->dest_ring = NULL;
 }
+
+void ath10k_ce_dump_registers(struct ath10k *ar,
+                             struct ath10k_fw_crash_data *crash_data)
+{
+       struct ath10k_pci *ar_pci = ath10k_pci_priv(ar);
+       struct ath10k_ce_crash_data ce;
+       u32 addr, id;
+
+       lockdep_assert_held(&ar->data_lock);
+
+       ath10k_err(ar, "Copy Engine register dump:\n");
+
+       spin_lock_bh(&ar_pci->ce_lock);
+       for (id = 0; id < CE_COUNT; id++) {
+               addr = ath10k_ce_base_address(ar, id);
+               ce.base_addr = cpu_to_le32(addr);
+
+               ce.src_wr_idx =
+                       cpu_to_le32(ath10k_ce_src_ring_write_index_get(ar, addr));
+               ce.src_r_idx =
+                       cpu_to_le32(ath10k_ce_src_ring_read_index_get(ar, addr));
+               ce.dst_wr_idx =
+                       cpu_to_le32(ath10k_ce_dest_ring_write_index_get(ar, addr));
+               ce.dst_r_idx =
+                       cpu_to_le32(ath10k_ce_dest_ring_read_index_get(ar, addr));
+
+               if (crash_data)
+                       crash_data->ce_crash_data[id] = ce;
+
+               ath10k_err(ar, "[%02d]: 0x%08x %3u %3u %3u %3u", id,
+                          le32_to_cpu(ce.base_addr),
+                          le32_to_cpu(ce.src_wr_idx),
+                          le32_to_cpu(ce.src_r_idx),
+                          le32_to_cpu(ce.dst_wr_idx),
+                          le32_to_cpu(ce.dst_r_idx));
+       }
+
+       spin_unlock_bh(&ar_pci->ce_lock);
+}
index dfc098606bee16be8e6e724b2aeae9a70ffd7a90..e76a98242b98fbb6bd072f766a81b7b046725201 100644 (file)
@@ -20,8 +20,6 @@
 
 #include "hif.h"
 
-/* Maximum number of Copy Engine's supported */
-#define CE_COUNT_MAX 12
 #define CE_HTT_H2T_MSG_SRC_NENTRIES 8192
 
 /* Descriptor rings must be aligned to this boundary */
@@ -228,6 +226,8 @@ void ath10k_ce_per_engine_service_any(struct ath10k *ar);
 void ath10k_ce_per_engine_service(struct ath10k *ar, unsigned int ce_id);
 int ath10k_ce_disable_interrupts(struct ath10k *ar);
 void ath10k_ce_enable_interrupts(struct ath10k *ar);
+void ath10k_ce_dump_registers(struct ath10k *ar,
+                             struct ath10k_fw_crash_data *crash_data);
 
 /* ce_attr.flags values */
 /* Use NonSnooping PCIe accesses? */
index 874c2a755c66aaaf030a45eebbe8a6044d4274f2..c2afcca6fd606e0b6680b3da3a84e023ffc845cf 100644 (file)
@@ -18,6 +18,8 @@
 #include <linux/module.h>
 #include <linux/firmware.h>
 #include <linux/of.h>
+#include <linux/dmi.h>
+#include <linux/ctype.h>
 #include <asm/byteorder.h>
 
 #include "core.h"
@@ -707,6 +709,72 @@ static int ath10k_core_get_board_id_from_otp(struct ath10k *ar)
        return 0;
 }
 
+static void ath10k_core_check_bdfext(const struct dmi_header *hdr, void *data)
+{
+       struct ath10k *ar = data;
+       const char *bdf_ext;
+       const char *magic = ATH10K_SMBIOS_BDF_EXT_MAGIC;
+       u8 bdf_enabled;
+       int i;
+
+       if (hdr->type != ATH10K_SMBIOS_BDF_EXT_TYPE)
+               return;
+
+       if (hdr->length != ATH10K_SMBIOS_BDF_EXT_LENGTH) {
+               ath10k_dbg(ar, ATH10K_DBG_BOOT,
+                          "wrong smbios bdf ext type length (%d).\n",
+                          hdr->length);
+               return;
+       }
+
+       bdf_enabled = *((u8 *)hdr + ATH10K_SMBIOS_BDF_EXT_OFFSET);
+       if (!bdf_enabled) {
+               ath10k_dbg(ar, ATH10K_DBG_BOOT, "bdf variant name not found.\n");
+               return;
+       }
+
+       /* Only one string exists (per spec) */
+       bdf_ext = (char *)hdr + hdr->length;
+
+       if (memcmp(bdf_ext, magic, strlen(magic)) != 0) {
+               ath10k_dbg(ar, ATH10K_DBG_BOOT,
+                          "bdf variant magic does not match.\n");
+               return;
+       }
+
+       for (i = 0; i < strlen(bdf_ext); i++) {
+               if (!isascii(bdf_ext[i]) || !isprint(bdf_ext[i])) {
+                       ath10k_dbg(ar, ATH10K_DBG_BOOT,
+                                  "bdf variant name contains non ascii chars.\n");
+                       return;
+               }
+       }
+
+       /* Copy extension name without magic suffix */
+       if (strscpy(ar->id.bdf_ext, bdf_ext + strlen(magic),
+                   sizeof(ar->id.bdf_ext)) < 0) {
+               ath10k_dbg(ar, ATH10K_DBG_BOOT,
+                          "bdf variant string is longer than the buffer can accommodate (variant: %s)\n",
+                           bdf_ext);
+               return;
+       }
+
+       ath10k_dbg(ar, ATH10K_DBG_BOOT,
+                  "found and validated bdf variant smbios_type 0x%x bdf %s\n",
+                  ATH10K_SMBIOS_BDF_EXT_TYPE, bdf_ext);
+}
+
+static int ath10k_core_check_smbios(struct ath10k *ar)
+{
+       ar->id.bdf_ext[0] = '\0';
+       dmi_walk(ath10k_core_check_bdfext, ar);
+
+       if (ar->id.bdf_ext[0] == '\0')
+               return -ENODATA;
+
+       return 0;
+}
+
 static int ath10k_download_and_run_otp(struct ath10k *ar)
 {
        u32 result, address = ar->hw_params.patch_load_addr;
@@ -1053,6 +1121,9 @@ err:
 static int ath10k_core_create_board_name(struct ath10k *ar, char *name,
                                         size_t name_len)
 {
+       /* strlen(',variant=') + strlen(ar->id.bdf_ext) */
+       char variant[9 + ATH10K_SMBIOS_BDF_EXT_STR_LENGTH];
+
        if (ar->id.bmi_ids_valid) {
                scnprintf(name, name_len,
                          "bus=%s,bmi-chip-id=%d,bmi-board-id=%d",
@@ -1062,12 +1133,15 @@ static int ath10k_core_create_board_name(struct ath10k *ar, char *name,
                goto out;
        }
 
+       if (ar->id.bdf_ext[0] != '\0')
+               scnprintf(variant, sizeof(variant), ",variant=%s",
+                         ar->id.bdf_ext);
+
        scnprintf(name, name_len,
-                 "bus=%s,vendor=%04x,device=%04x,subsystem-vendor=%04x,subsystem-device=%04x",
+                 "bus=%s,vendor=%04x,device=%04x,subsystem-vendor=%04x,subsystem-device=%04x%s",
                  ath10k_bus_str(ar->hif.bus),
                  ar->id.vendor, ar->id.device,
-                 ar->id.subsystem_vendor, ar->id.subsystem_device);
-
+                 ar->id.subsystem_vendor, ar->id.subsystem_device, variant);
 out:
        ath10k_dbg(ar, ATH10K_DBG_BOOT, "boot using board name '%s'\n", name);
 
@@ -2128,6 +2202,10 @@ static int ath10k_core_probe_fw(struct ath10k *ar)
                goto err_free_firmware_files;
        }
 
+       ret = ath10k_core_check_smbios(ar);
+       if (ret)
+               ath10k_dbg(ar, ATH10K_DBG_BOOT, "bdf variant name not set.\n");
+
        ret = ath10k_core_fetch_board_file(ar);
        if (ret) {
                ath10k_err(ar, "failed to fetch board file: %d\n", ret);
index c7664d6569facdee52cb499566a9287ff8731759..88d14be7fcceb44539f80c7217e4d6b0ea27dd79 100644 (file)
 #define ATH10K_NAPI_BUDGET      64
 #define ATH10K_NAPI_QUOTA_LIMIT 60
 
+/* SMBIOS type containing Board Data File Name Extension */
+#define ATH10K_SMBIOS_BDF_EXT_TYPE 0xF8
+
+/* SMBIOS type structure length (excluding strings-set) */
+#define ATH10K_SMBIOS_BDF_EXT_LENGTH 0x9
+
+/* Offset pointing to Board Data File Name Extension */
+#define ATH10K_SMBIOS_BDF_EXT_OFFSET 0x8
+
+/* Board Data File Name Extension string length.
+ * String format: BDF_<Customer ID>_<Extension>\0
+ */
+#define ATH10K_SMBIOS_BDF_EXT_STR_LENGTH 0x20
+
+/* The magic used by QCA spec */
+#define ATH10K_SMBIOS_BDF_EXT_MAGIC "BDF_"
+
 struct ath10k;
 
 enum ath10k_bus {
@@ -314,6 +331,7 @@ struct ath10k_peer {
        struct ieee80211_vif *vif;
        struct ieee80211_sta *sta;
 
+       bool removed;
        int vdev_id;
        u8 addr[ETH_ALEN];
        DECLARE_BITMAP(peer_ids, ATH10K_MAX_NUM_PEER_IDS);
@@ -419,6 +437,21 @@ struct ath10k_vif_iter {
        struct ath10k_vif *arvif;
 };
 
+/* Copy Engine register dump, protected by ce-lock */
+struct ath10k_ce_crash_data {
+       __le32 base_addr;
+       __le32 src_wr_idx;
+       __le32 src_r_idx;
+       __le32 dst_wr_idx;
+       __le32 dst_r_idx;
+};
+
+struct ath10k_ce_crash_hdr {
+       __le32 ce_count;
+       __le32 reserved[3]; /* for future use */
+       struct ath10k_ce_crash_data entries[];
+};
+
 /* used for crash-dump storage, protected by data-lock */
 struct ath10k_fw_crash_data {
        bool crashed_since_read;
@@ -426,6 +459,7 @@ struct ath10k_fw_crash_data {
        uuid_le uuid;
        struct timespec timestamp;
        __le32 registers[REG_DUMP_COUNT_QCA988X];
+       struct ath10k_ce_crash_data ce_crash_data[CE_COUNT_MAX];
 };
 
 struct ath10k_debug {
@@ -781,6 +815,8 @@ struct ath10k {
                bool bmi_ids_valid;
                u8 bmi_board_id;
                u8 bmi_chip_id;
+
+               char bdf_ext[ATH10K_SMBIOS_BDF_EXT_STR_LENGTH];
        } id;
 
        int fw_api;
index e1a70dffc52a80a351eb45a04c0e576333a3769e..d5ff0f4ef5ce39522441b90e8eda250ad105b723 100644 (file)
@@ -41,6 +41,7 @@
  */
 enum ath10k_fw_crash_dump_type {
        ATH10K_FW_CRASH_DUMP_REGISTERS = 0,
+       ATH10K_FW_CRASH_DUMP_CE_DATA = 1,
 
        ATH10K_FW_CRASH_DUMP_MAX,
 };
@@ -400,6 +401,7 @@ void ath10k_debug_fw_stats_process(struct ath10k *ar, struct sk_buff *skb)
                         * prevent firmware from DoS-ing the host.
                         */
                        ath10k_fw_stats_peers_free(&ar->debug.fw_stats.peers);
+                       ath10k_fw_extd_stats_peers_free(&ar->debug.fw_stats.peers_extd);
                        ath10k_warn(ar, "dropping fw peer stats\n");
                        goto free;
                }
@@ -410,10 +412,12 @@ void ath10k_debug_fw_stats_process(struct ath10k *ar, struct sk_buff *skb)
                        goto free;
                }
 
+               if (!list_empty(&stats.peers))
+                       list_splice_tail_init(&stats.peers_extd,
+                                             &ar->debug.fw_stats.peers_extd);
+
                list_splice_tail_init(&stats.peers, &ar->debug.fw_stats.peers);
                list_splice_tail_init(&stats.vdevs, &ar->debug.fw_stats.vdevs);
-               list_splice_tail_init(&stats.peers_extd,
-                                     &ar->debug.fw_stats.peers_extd);
        }
 
        complete(&ar->debug.fw_stats_complete);
@@ -726,6 +730,7 @@ static struct ath10k_dump_file_data *ath10k_build_dump_file(struct ath10k *ar,
                                                            bool mark_read)
 {
        struct ath10k_fw_crash_data *crash_data = ar->debug.fw_crash_data;
+       struct ath10k_ce_crash_hdr *ce_hdr;
        struct ath10k_dump_file_data *dump_data;
        struct ath10k_tlv_dump_data *dump_tlv;
        int hdr_len = sizeof(*dump_data);
@@ -734,6 +739,8 @@ static struct ath10k_dump_file_data *ath10k_build_dump_file(struct ath10k *ar,
 
        len = hdr_len;
        len += sizeof(*dump_tlv) + sizeof(crash_data->registers);
+       len += sizeof(*dump_tlv) + sizeof(*ce_hdr) +
+               CE_COUNT * sizeof(ce_hdr->entries[0]);
 
        sofar += hdr_len;
 
@@ -792,6 +799,18 @@ static struct ath10k_dump_file_data *ath10k_build_dump_file(struct ath10k *ar,
               sizeof(crash_data->registers));
        sofar += sizeof(*dump_tlv) + sizeof(crash_data->registers);
 
+       dump_tlv = (struct ath10k_tlv_dump_data *)(buf + sofar);
+       dump_tlv->type = cpu_to_le32(ATH10K_FW_CRASH_DUMP_CE_DATA);
+       dump_tlv->tlv_len = cpu_to_le32(sizeof(*ce_hdr) +
+                                       CE_COUNT * sizeof(ce_hdr->entries[0]));
+       ce_hdr = (struct ath10k_ce_crash_hdr *)(dump_tlv->tlv_data);
+       ce_hdr->ce_count = cpu_to_le32(CE_COUNT);
+       memset(ce_hdr->reserved, 0, sizeof(ce_hdr->reserved));
+       memcpy(ce_hdr->entries, crash_data->ce_crash_data,
+              CE_COUNT * sizeof(ce_hdr->entries[0]));
+       sofar += sizeof(*dump_tlv) + sizeof(*ce_hdr) +
+                CE_COUNT * sizeof(ce_hdr->entries[0]);
+
        ar->debug.fw_crash_data->crashed_since_read = !mark_read;
 
        spin_unlock_bh(&ar->data_lock);
index 175aae38c3757a9d0118528e1c277ad1a4c98d7f..9f6a915f91bfe842a1672b81a8b6046c7f9d4f1b 100644 (file)
@@ -474,33 +474,16 @@ static void ath10k_htc_reset_endpoint_states(struct ath10k_htc *htc)
        }
 }
 
-static void ath10k_htc_setup_target_buffer_assignments(struct ath10k_htc *htc)
-{
-       struct ath10k_htc_svc_tx_credits *entry;
-
-       entry = &htc->service_tx_alloc[0];
-
-       /*
-        * for PCIE allocate all credists/HTC buffers to WMI.
-        * no buffers are used/required for data. data always
-        * remains on host.
-        */
-       entry++;
-       entry->service_id = ATH10K_HTC_SVC_ID_WMI_CONTROL;
-       entry->credit_allocation = htc->total_transmit_credits;
-}
-
 static u8 ath10k_htc_get_credit_allocation(struct ath10k_htc *htc,
                                           u16 service_id)
 {
        u8 allocation = 0;
-       int i;
 
-       for (i = 0; i < ATH10K_HTC_EP_COUNT; i++) {
-               if (htc->service_tx_alloc[i].service_id == service_id)
-                       allocation =
-                           htc->service_tx_alloc[i].credit_allocation;
-       }
+       /* The WMI control service is the only service with flow control.
+        * Let it have all transmit credits.
+        */
+       if (service_id == ATH10K_HTC_SVC_ID_WMI_CONTROL)
+               allocation = htc->total_transmit_credits;
 
        return allocation;
 }
@@ -574,8 +557,6 @@ int ath10k_htc_wait_target(struct ath10k_htc *htc)
                return -ECOMM;
        }
 
-       ath10k_htc_setup_target_buffer_assignments(htc);
-
        /* setup our pseudo HTC control endpoint connection */
        memset(&conn_req, 0, sizeof(conn_req));
        memset(&conn_resp, 0, sizeof(conn_resp));
@@ -726,12 +707,6 @@ setup:
        ep->max_tx_queue_depth = conn_req->max_send_queue_depth;
        ep->max_ep_message_len = __le16_to_cpu(resp_msg->max_msg_size);
        ep->tx_credits = tx_alloc;
-       ep->tx_credit_size = htc->target_credit_size;
-       ep->tx_credits_per_max_message = ep->max_ep_message_len /
-                                        htc->target_credit_size;
-
-       if (ep->max_ep_message_len % htc->target_credit_size)
-               ep->tx_credits_per_max_message++;
 
        /* copy all the callbacks */
        ep->ep_ops = conn_req->ep_ops;
index 0c55cd92a951722d72f9cfc79c96da4e62cdc676..6ababa345e2b94c169817f72cde649e235f1efc5 100644 (file)
@@ -314,8 +314,6 @@ struct ath10k_htc_ep {
 
        u8 seq_no; /* for debugging */
        int tx_credits;
-       int tx_credit_size;
-       int tx_credits_per_max_message;
        bool tx_credit_flow_enabled;
 };
 
@@ -339,7 +337,6 @@ struct ath10k_htc {
        struct completion ctl_resp;
 
        int total_transmit_credits;
-       struct ath10k_htc_svc_tx_credits service_tx_alloc[ATH10K_HTC_EP_COUNT];
        int target_credit_size;
 };
 
index 0bc7fe8c4b528008c591b7f8dcf098bdac2d8bec..2743a9bcd5564c94485eed2f57a0d7647c4e8975 100644 (file)
@@ -702,6 +702,10 @@ static void ath10k_htt_rx_h_rates(struct ath10k *ar,
                /* 80MHZ */
                case 2:
                        status->vht_flag |= RX_VHT_FLAG_80MHZ;
+                       break;
+               case 3:
+                       status->vht_flag |= RX_VHT_FLAG_160MHZ;
+                       break;
                }
 
                status->flag |= RX_FLAG_VHT;
@@ -926,7 +930,7 @@ static void ath10k_process_rx(struct ath10k *ar,
        *status = *rx_status;
 
        ath10k_dbg(ar, ATH10K_DBG_DATA,
-                  "rx skb %pK len %u peer %pM %s %s sn %u %s%s%s%s%s %srate_idx %u vht_nss %u freq %u band %u flag 0x%llx fcs-err %i mic-err %i amsdu-more %i\n",
+                  "rx skb %pK len %u peer %pM %s %s sn %u %s%s%s%s%s%s %srate_idx %u vht_nss %u freq %u band %u flag 0x%llx fcs-err %i mic-err %i amsdu-more %i\n",
                   skb,
                   skb->len,
                   ieee80211_get_SA(hdr),
@@ -940,6 +944,7 @@ static void ath10k_process_rx(struct ath10k *ar,
                   status->flag & RX_FLAG_VHT ? "vht" : "",
                   status->flag & RX_FLAG_40MHZ ? "40" : "",
                   status->vht_flag & RX_VHT_FLAG_80MHZ ? "80" : "",
+                  status->vht_flag & RX_VHT_FLAG_160MHZ ? "160" : "",
                   status->flag & RX_FLAG_SHORT_GI ? "sgi " : "",
                   status->rate_idx,
                   status->vht_nss,
@@ -2231,6 +2236,8 @@ ath10k_update_per_peer_tx_stats(struct ath10k *ar,
                return;
        }
 
+       memset(&arsta->txrate, 0, sizeof(arsta->txrate));
+
        if (txrate.flags == WMI_RATE_PREAMBLE_CCK ||
            txrate.flags == WMI_RATE_PREAMBLE_OFDM) {
                rate = ATH10K_HW_LEGACY_RATE(peer_stats->ratecode);
@@ -2245,7 +2252,7 @@ ath10k_update_per_peer_tx_stats(struct ath10k *ar,
                rate *= 10;
                if (rate == 60 && txrate.flags == WMI_RATE_PREAMBLE_CCK)
                        rate = rate - 5;
-               arsta->txrate.legacy = rate * 10;
+               arsta->txrate.legacy = rate;
        } else if (txrate.flags == WMI_RATE_PREAMBLE_HT) {
                arsta->txrate.flags = RATE_INFO_FLAGS_MCS;
                arsta->txrate.mcs = txrate.mcs;
index 7feffec531cc060f306fdc8694eaf787870cc995..38aa7c95732ee96cd3c5c75b00720e3ba6accfda 100644 (file)
@@ -578,6 +578,9 @@ ath10k_rx_desc_get_l3_pad_bytes(struct ath10k_hw_params *hw,
 #define TARGET_10_4_IPHDR_PAD_CONFIG           1
 #define TARGET_10_4_QWRAP_CONFIG               0
 
+/* Maximum number of Copy Engine's supported */
+#define CE_COUNT_MAX 12
+
 /* Number of Copy Engines supported */
 #define CE_COUNT ar->hw_values->ce_count
 
index d1b7edba5e491ed39b2d043d783dbdb0e3f2ed33..9977829a6ec446d733416e8269fa32dd202aa2f5 100644 (file)
@@ -569,10 +569,14 @@ chan_to_phymode(const struct cfg80211_chan_def *chandef)
                case NL80211_CHAN_WIDTH_80:
                        phymode = MODE_11AC_VHT80;
                        break;
+               case NL80211_CHAN_WIDTH_160:
+                       phymode = MODE_11AC_VHT160;
+                       break;
+               case NL80211_CHAN_WIDTH_80P80:
+                       phymode = MODE_11AC_VHT80_80;
+                       break;
                case NL80211_CHAN_WIDTH_5:
                case NL80211_CHAN_WIDTH_10:
-               case NL80211_CHAN_WIDTH_80P80:
-               case NL80211_CHAN_WIDTH_160:
                        phymode = MODE_UNKNOWN;
                        break;
                }
@@ -971,6 +975,7 @@ static int ath10k_monitor_vdev_start(struct ath10k *ar, int vdev_id)
        arg.vdev_id = vdev_id;
        arg.channel.freq = channel->center_freq;
        arg.channel.band_center_freq1 = chandef->center_freq1;
+       arg.channel.band_center_freq2 = chandef->center_freq2;
 
        /* TODO setup this dynamically, what in case we
           don't have any vifs? */
@@ -1417,6 +1422,7 @@ static int ath10k_vdev_start_restart(struct ath10k_vif *arvif,
 
        arg.channel.freq = chandef->chan->center_freq;
        arg.channel.band_center_freq1 = chandef->center_freq1;
+       arg.channel.band_center_freq2 = chandef->center_freq2;
        arg.channel.mode = chan_to_phymode(chandef);
 
        arg.channel.min_power = 0;
@@ -2480,6 +2486,9 @@ static void ath10k_peer_assoc_h_vht(struct ath10k *ar,
        if (sta->bandwidth == IEEE80211_STA_RX_BW_80)
                arg->peer_flags |= ar->wmi.peer_flags->bw80;
 
+       if (sta->bandwidth == IEEE80211_STA_RX_BW_160)
+               arg->peer_flags |= ar->wmi.peer_flags->bw160;
+
        arg->peer_vht_rates.rx_max_rate =
                __le16_to_cpu(vht_cap->vht_mcs.rx_highest);
        arg->peer_vht_rates.rx_mcs_set =
@@ -2533,6 +2542,33 @@ static bool ath10k_mac_sta_has_ofdm_only(struct ieee80211_sta *sta)
               ATH10K_MAC_FIRST_OFDM_RATE_IDX;
 }
 
+static enum wmi_phy_mode ath10k_mac_get_phymode_vht(struct ath10k *ar,
+                                                   struct ieee80211_sta *sta)
+{
+       if (sta->bandwidth == IEEE80211_STA_RX_BW_160) {
+               switch (sta->vht_cap.cap & IEEE80211_VHT_CAP_SUPP_CHAN_WIDTH_MASK) {
+               case IEEE80211_VHT_CAP_SUPP_CHAN_WIDTH_160MHZ:
+                       return MODE_11AC_VHT160;
+               case IEEE80211_VHT_CAP_SUPP_CHAN_WIDTH_160_80PLUS80MHZ:
+                       return MODE_11AC_VHT80_80;
+               default:
+                       /* not sure if this is a valid case? */
+                       return MODE_11AC_VHT160;
+               }
+       }
+
+       if (sta->bandwidth == IEEE80211_STA_RX_BW_80)
+               return MODE_11AC_VHT80;
+
+       if (sta->bandwidth == IEEE80211_STA_RX_BW_40)
+               return MODE_11AC_VHT40;
+
+       if (sta->bandwidth == IEEE80211_STA_RX_BW_20)
+               return MODE_11AC_VHT20;
+
+       return MODE_UNKNOWN;
+}
+
 static void ath10k_peer_assoc_h_phymode(struct ath10k *ar,
                                        struct ieee80211_vif *vif,
                                        struct ieee80211_sta *sta,
@@ -2579,12 +2615,7 @@ static void ath10k_peer_assoc_h_phymode(struct ath10k *ar,
                 */
                if (sta->vht_cap.vht_supported &&
                    !ath10k_peer_assoc_h_vht_masked(vht_mcs_mask)) {
-                       if (sta->bandwidth == IEEE80211_STA_RX_BW_80)
-                               phymode = MODE_11AC_VHT80;
-                       else if (sta->bandwidth == IEEE80211_STA_RX_BW_40)
-                               phymode = MODE_11AC_VHT40;
-                       else if (sta->bandwidth == IEEE80211_STA_RX_BW_20)
-                               phymode = MODE_11AC_VHT20;
+                       phymode = ath10k_mac_get_phymode_vht(ar, sta);
                } else if (sta->ht_cap.ht_supported &&
                           !ath10k_peer_assoc_h_ht_masked(ht_mcs_mask)) {
                        if (sta->bandwidth >= IEEE80211_STA_RX_BW_40)
@@ -3774,6 +3805,9 @@ struct ieee80211_txq *ath10k_mac_txq_lookup(struct ath10k *ar,
        if (!peer)
                return NULL;
 
+       if (peer->removed)
+               return NULL;
+
        if (peer->sta)
                return peer->sta->txq[tid];
        else if (peer->vif)
@@ -4311,6 +4345,13 @@ static struct ieee80211_sta_vht_cap ath10k_create_vht_cap(struct ath10k *ar)
                vht_cap.cap |= val;
        }
 
+       /* Currently the firmware seems to be buggy, don't enable 80+80
+        * mode until that's resolved.
+        */
+       if ((ar->vht_cap_info & IEEE80211_VHT_CAP_SHORT_GI_160) &&
+           !(ar->vht_cap_info & IEEE80211_VHT_CAP_SUPP_CHAN_WIDTH_160_80PLUS80MHZ))
+               vht_cap.cap |= IEEE80211_VHT_CAP_SUPP_CHAN_WIDTH_160MHZ;
+
        mcs_map = 0;
        for (i = 0; i < 8; i++) {
                if ((i < ar->num_rf_chains) && (ar->cfg_tx_chainmask & BIT(i)))
@@ -6969,6 +7010,9 @@ static void ath10k_sta_rc_update(struct ieee80211_hw *hw,
                        bw = WMI_PEER_CHWIDTH_80MHZ;
                        break;
                case IEEE80211_STA_RX_BW_160:
+                       bw = WMI_PEER_CHWIDTH_160MHZ;
+                       break;
+               default:
                        ath10k_warn(ar, "Invalid bandwidth %d in rc update for %pM\n",
                                    sta->bandwidth, sta->addr);
                        bw = WMI_PEER_CHWIDTH_20MHZ;
@@ -7476,6 +7520,20 @@ ath10k_mac_op_switch_vif_chanctx(struct ieee80211_hw *hw,
        return 0;
 }
 
+static void ath10k_mac_op_sta_pre_rcu_remove(struct ieee80211_hw *hw,
+                                            struct ieee80211_vif *vif,
+                                            struct ieee80211_sta *sta)
+{
+       struct ath10k *ar;
+       struct ath10k_peer *peer;
+
+       ar = hw->priv;
+
+       list_for_each_entry(peer, &ar->peers, list)
+               if (peer->sta == sta)
+                       peer->removed = true;
+}
+
 static const struct ieee80211_ops ath10k_ops = {
        .tx                             = ath10k_mac_op_tx,
        .wake_tx_queue                  = ath10k_mac_op_wake_tx_queue,
@@ -7516,6 +7574,7 @@ static const struct ieee80211_ops ath10k_ops = {
        .assign_vif_chanctx             = ath10k_mac_op_assign_vif_chanctx,
        .unassign_vif_chanctx           = ath10k_mac_op_unassign_vif_chanctx,
        .switch_vif_chanctx             = ath10k_mac_op_switch_vif_chanctx,
+       .sta_pre_rcu_remove             = ath10k_mac_op_sta_pre_rcu_remove,
 
        CFG80211_TESTMODE_CMD(ath10k_tm_cmd)
 
index e757c514e2b7f4b129b34a4b10fbe18e64f041d5..79e61459bc6c7ae7b02aad6b9f85f854fd374f87 100644 (file)
@@ -896,7 +896,7 @@ static int ath10k_pci_diag_read_mem(struct ath10k *ar, u32 address, void *data,
         */
        alloc_nbytes = min_t(unsigned int, nbytes, DIAG_TRANSFER_LIMIT);
 
-       data_buf = (unsigned char *)dma_alloc_coherent(ar->dev,
+       data_buf = (unsigned char *)dma_zalloc_coherent(ar->dev,
                                                       alloc_nbytes,
                                                       &ce_data_base,
                                                       GFP_ATOMIC);
@@ -905,7 +905,6 @@ static int ath10k_pci_diag_read_mem(struct ath10k *ar, u32 address, void *data,
                ret = -ENOMEM;
                goto done;
        }
-       memset(data_buf, 0, alloc_nbytes);
 
        remaining_bytes = nbytes;
        ce_data = ce_data_base;
@@ -1474,6 +1473,7 @@ static void ath10k_pci_fw_crashed_dump(struct ath10k *ar)
        ath10k_err(ar, "firmware crashed! (uuid %s)\n", uuid);
        ath10k_print_driver_info(ar);
        ath10k_pci_dump_registers(ar, crash_data);
+       ath10k_ce_dump_registers(ar, crash_data);
 
        spin_unlock_bh(&ar->data_lock);
 
@@ -1937,7 +1937,7 @@ static int ath10k_pci_wake_target_cpu(struct ath10k *ar)
 {
        u32 addr, val;
 
-       addr = SOC_CORE_BASE_ADDRESS | CORE_CTRL_ADDRESS;
+       addr = SOC_CORE_BASE_ADDRESS + CORE_CTRL_ADDRESS;
        val = ath10k_pci_read32(ar, addr);
        val |= CORE_CTRL_CPU_INTR_MASK;
        ath10k_pci_write32(ar, addr, val);
index 9854ad56b2dea362834c093f2ee13a28f33e2170..c76789d5de999b1b3f57f457d9dbd932972c43e1 100644 (file)
 #include "ce.h"
 #include "ahb.h"
 
-/*
- * maximum number of bytes that can be handled atomically by DiagRead/DiagWrite
- */
-#define DIAG_TRANSFER_LIMIT 2048
-
 /*
  * maximum number of bytes that can be
  * handled atomically by DiagRead/DiagWrite
index 1f6bb9e8bb0125f815214bb437d4fe5726f8e7ec..f9188027a6f6fe73f9bd098c9c3c96ea3ee56404 100644 (file)
@@ -3637,6 +3637,7 @@ static const struct wmi_peer_flags_map wmi_tlv_peer_flags_map = {
        .vht = WMI_TLV_PEER_VHT,
        .bw80 = WMI_TLV_PEER_80MHZ,
        .pmf = WMI_TLV_PEER_PMF,
+       .bw160 = WMI_TLV_PEER_160MHZ,
 };
 
 /************/
index b8aa6000573cd1abfa2f2c79fa53310a85b13faf..22cf011e839afc190c55c65a387351787369e37d 100644 (file)
@@ -543,6 +543,7 @@ enum wmi_tlv_peer_flags {
        WMI_TLV_PEER_VHT = 0x02000000,
        WMI_TLV_PEER_80MHZ = 0x04000000,
        WMI_TLV_PEER_PMF = 0x08000000,
+       WMI_TLV_PEER_160MHZ = 0x20000000,
 };
 
 enum wmi_tlv_tag {
index 50d6ee6afe26fc362f843af5314c1644cf033e8f..414ad3e1eed4b617652dba2e3939354d9ae58f36 100644 (file)
@@ -28,6 +28,7 @@
 #include "wmi-ops.h"
 #include "p2p.h"
 #include "hw.h"
+#include "hif.h"
 
 #define ATH10K_WMI_BARRIER_ECHO_ID 0xBA991E9
 #define ATH10K_WMI_BARRIER_TIMEOUT_HZ (3 * HZ)
@@ -1574,6 +1575,7 @@ static const struct wmi_peer_flags_map wmi_peer_flags_map = {
        .bw80 = WMI_PEER_80MHZ,
        .vht_2g = WMI_PEER_VHT_2G,
        .pmf = WMI_PEER_PMF,
+       .bw160 = WMI_PEER_160MHZ,
 };
 
 static const struct wmi_peer_flags_map wmi_10x_peer_flags_map = {
@@ -1591,6 +1593,7 @@ static const struct wmi_peer_flags_map wmi_10x_peer_flags_map = {
        .spatial_mux = WMI_10X_PEER_SPATIAL_MUX,
        .vht = WMI_10X_PEER_VHT,
        .bw80 = WMI_10X_PEER_80MHZ,
+       .bw160 = WMI_10X_PEER_160MHZ,
 };
 
 static const struct wmi_peer_flags_map wmi_10_2_peer_flags_map = {
@@ -1610,6 +1613,7 @@ static const struct wmi_peer_flags_map wmi_10_2_peer_flags_map = {
        .bw80 = WMI_10_2_PEER_80MHZ,
        .vht_2g = WMI_10_2_PEER_VHT_2G,
        .pmf = WMI_10_2_PEER_PMF,
+       .bw160 = WMI_10_2_PEER_160MHZ,
 };
 
 void ath10k_wmi_put_wmi_channel(struct wmi_channel *ch,
@@ -1634,7 +1638,10 @@ void ath10k_wmi_put_wmi_channel(struct wmi_channel *ch,
 
        ch->mhz = __cpu_to_le32(arg->freq);
        ch->band_center_freq1 = __cpu_to_le32(arg->band_center_freq1);
-       ch->band_center_freq2 = 0;
+       if (arg->mode == MODE_11AC_VHT80_80)
+               ch->band_center_freq2 = __cpu_to_le32(arg->band_center_freq2);
+       else
+               ch->band_center_freq2 = 0;
        ch->min_power = arg->min_power;
        ch->max_power = arg->max_power;
        ch->reg_power = arg->max_reg_power;
@@ -2319,7 +2326,7 @@ int ath10k_wmi_event_mgmt_rx(struct ath10k *ar, struct sk_buff *skb)
         */
        if (channel >= 1 && channel <= 14) {
                status->band = NL80211_BAND_2GHZ;
-       } else if (channel >= 36 && channel <= 165) {
+       } else if (channel >= 36 && channel <= 169) {
                status->band = NL80211_BAND_5GHZ;
        } else {
                /* Shouldn't happen unless list of advertised channels to
index 5d3dff95b2e5afac3fc8d79530cbbafc0df60bdf..861c2d8c6e8c85deeab23eb747af7389a383c7e8 100644 (file)
@@ -1728,8 +1728,10 @@ enum wmi_phy_mode {
        MODE_11AC_VHT20_2G = 11,
        MODE_11AC_VHT40_2G = 12,
        MODE_11AC_VHT80_2G = 13,
-       MODE_UNKNOWN    = 14,
-       MODE_MAX        = 14
+       MODE_11AC_VHT80_80 = 14,
+       MODE_11AC_VHT160 = 15,
+       MODE_UNKNOWN    = 16,
+       MODE_MAX        = 16
 };
 
 static inline const char *ath10k_wmi_phymode_str(enum wmi_phy_mode mode)
@@ -1757,6 +1759,10 @@ static inline const char *ath10k_wmi_phymode_str(enum wmi_phy_mode mode)
                return "11ac-vht40";
        case MODE_11AC_VHT80:
                return "11ac-vht80";
+       case MODE_11AC_VHT160:
+               return "11ac-vht160";
+       case MODE_11AC_VHT80_80:
+               return "11ac-vht80+80";
        case MODE_11AC_VHT20_2G:
                return "11ac-vht20-2g";
        case MODE_11AC_VHT40_2G:
@@ -1811,6 +1817,7 @@ struct wmi_channel {
 struct wmi_channel_arg {
        u32 freq;
        u32 band_center_freq1;
+       u32 band_center_freq2;
        bool passive;
        bool allow_ibss;
        bool allow_ht;
@@ -1875,9 +1882,18 @@ enum wmi_channel_change_cause {
 #define WMI_VHT_CAP_MAX_MPDU_LEN_MASK            0x00000003
 #define WMI_VHT_CAP_RX_LDPC                      0x00000010
 #define WMI_VHT_CAP_SGI_80MHZ                    0x00000020
+#define WMI_VHT_CAP_SGI_160MHZ                   0x00000040
 #define WMI_VHT_CAP_TX_STBC                      0x00000080
 #define WMI_VHT_CAP_RX_STBC_MASK                 0x00000300
 #define WMI_VHT_CAP_RX_STBC_MASK_SHIFT           8
+#define WMI_VHT_CAP_SU_BFER                      0x00000800
+#define WMI_VHT_CAP_SU_BFEE                      0x00001000
+#define WMI_VHT_CAP_MAX_CS_ANT_MASK              0x0000E000
+#define WMI_VHT_CAP_MAX_CS_ANT_MASK_SHIFT        13
+#define WMI_VHT_CAP_MAX_SND_DIM_MASK             0x00070000
+#define WMI_VHT_CAP_MAX_SND_DIM_MASK_SHIFT       16
+#define WMI_VHT_CAP_MU_BFER                      0x00080000
+#define WMI_VHT_CAP_MU_BFEE                      0x00100000
 #define WMI_VHT_CAP_MAX_AMPDU_LEN_EXP            0x03800000
 #define WMI_VHT_CAP_MAX_AMPDU_LEN_EXP_SHIFT      23
 #define WMI_VHT_CAP_RX_FIXED_ANT                 0x10000000
@@ -1926,6 +1942,8 @@ enum {
        REGDMN_MODE_11AC_VHT40PLUS   = 0x40000, /* 5Ghz, VHT40 + channels */
        REGDMN_MODE_11AC_VHT40MINUS  = 0x80000, /* 5Ghz  VHT40 - channels */
        REGDMN_MODE_11AC_VHT80       = 0x100000, /* 5Ghz, VHT80 channels */
+       REGDMN_MODE_11AC_VHT160      = 0x200000,     /* 5Ghz, VHT160 channels */
+       REGDMN_MODE_11AC_VHT80_80    = 0x400000,     /* 5Ghz, VHT80+80 channels */
        REGDMN_MODE_ALL              = 0xffffffff
 };
 
@@ -5783,6 +5801,7 @@ enum wmi_peer_chwidth {
        WMI_PEER_CHWIDTH_20MHZ = 0,
        WMI_PEER_CHWIDTH_40MHZ = 1,
        WMI_PEER_CHWIDTH_80MHZ = 2,
+       WMI_PEER_CHWIDTH_160MHZ = 3,
 };
 
 enum wmi_peer_param {
@@ -5873,6 +5892,7 @@ struct wmi_peer_flags_map {
        u32 bw80;
        u32 vht_2g;
        u32 pmf;
+       u32 bw160;
 };
 
 enum wmi_peer_flags {
@@ -5892,6 +5912,7 @@ enum wmi_peer_flags {
        WMI_PEER_80MHZ = 0x04000000,
        WMI_PEER_VHT_2G = 0x08000000,
        WMI_PEER_PMF = 0x10000000,
+       WMI_PEER_160MHZ = 0x20000000
 };
 
 enum wmi_10x_peer_flags {
@@ -5909,6 +5930,7 @@ enum wmi_10x_peer_flags {
        WMI_10X_PEER_SPATIAL_MUX = 0x00200000,
        WMI_10X_PEER_VHT = 0x02000000,
        WMI_10X_PEER_80MHZ = 0x04000000,
+       WMI_10X_PEER_160MHZ = 0x20000000
 };
 
 enum wmi_10_2_peer_flags {
@@ -5928,6 +5950,7 @@ enum wmi_10_2_peer_flags {
        WMI_10_2_PEER_80MHZ = 0x04000000,
        WMI_10_2_PEER_VHT_2G = 0x08000000,
        WMI_10_2_PEER_PMF = 0x10000000,
+       WMI_10_2_PEER_160MHZ = 0x20000000
 };
 
 /*
index dc44cfef75176e1710f6622fee85f1f5e9b97e11..16e052d02c94088006e380dd95bc9bec1ba28f88 100644 (file)
@@ -502,8 +502,7 @@ ath5k_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd,
                        break;
                return -EOPNOTSUPP;
        default:
-               WARN_ON(1);
-               return -EINVAL;
+               return -EOPNOTSUPP;
        }
 
        mutex_lock(&ah->lock);
index 8ec66e74d06de14f4d4dfb8b75463f823f566582..2195b1b7a8a63873989d95c655c2868d00371003 100644 (file)
@@ -713,7 +713,7 @@ static void ath6kl_sdio_cleanup_scatter(struct ath6kl *ar)
                 * that the packet is properly freed?
                 */
                if (s_req->busrequest) {
-                       s_req->busrequest->scat_req = 0;
+                       s_req->busrequest->scat_req = NULL;
                        ath6kl_sdio_free_bus_req(ar_sdio, s_req->busrequest);
                }
                kfree(s_req->virt_dma_buf);
index 8f231c67dd516e3620e8b0b53203b736d8ee6521..783a38f1a626a435f5f2eb6b39f2ef9724292f06 100644 (file)
@@ -3,8 +3,8 @@ config ATH9K_HW
 config ATH9K_COMMON
        tristate
        select ATH_COMMON
-       select DEBUG_FS
-       select RELAY
+config ATH9K_COMMON_DEBUG
+       bool
 config ATH9K_DFS_DEBUGFS
        def_bool y
        depends on ATH9K_DEBUGFS && ATH9K_DFS_CERTIFIED
@@ -60,12 +60,14 @@ config ATH9K_DEBUGFS
        bool "Atheros ath9k debugging"
        depends on ATH9K && DEBUG_FS
        select MAC80211_DEBUGFS
+       select ATH9K_COMMON_DEBUG
        select RELAY
        ---help---
          Say Y, if you need access to ath9k's statistics for
          interrupts, rate control, etc.
 
          Also required for changing debug message flags at run time.
+         As well as access to the FFT/spectral data and TX99.
 
 config ATH9K_STATION_STATISTICS
        bool "Detailed station statistics"
@@ -174,8 +176,11 @@ config ATH9K_HTC
 config ATH9K_HTC_DEBUGFS
        bool "Atheros ath9k_htc debugging"
        depends on ATH9K_HTC && DEBUG_FS
+       select ATH9K_COMMON_DEBUG
+       select RELAY
        ---help---
          Say Y, if you need access to ath9k_htc's statistics.
+         As well as access to the FFT/spectral data.
 
 config ATH9K_HWRNG
        bool "Random number generator support"
index 76f9dc37500b18f70e4de8516b3ecb98ef24b511..36a40ffdce151d107c11b1bd78f964a9ca20062a 100644 (file)
@@ -60,8 +60,9 @@ obj-$(CONFIG_ATH9K_COMMON) += ath9k_common.o
 ath9k_common-y:=       common.o \
                        common-init.o \
                        common-beacon.o \
-                       common-debug.o \
-                       common-spectral.o
+
+ath9k_common-$(CONFIG_ATH9K_COMMON_DEBUG) += common-debug.o \
+                                            common-spectral.o
 
 ath9k_htc-y += htc_hst.o \
                hif_usb.o \
index f816909d9474e204c36abe20e73c16e0c259956b..4b3c9b10819766dc90cf28a4f972ae9e71099c7e 100644 (file)
@@ -220,8 +220,8 @@ ar9002_set_txdesc(struct ath_hw *ah, void *ds, struct ath_tx_info *i)
        ads->ds_txstatus6 = ads->ds_txstatus7 = 0;
        ads->ds_txstatus8 = ads->ds_txstatus9 = 0;
 
-       ACCESS_ONCE(ads->ds_link) = i->link;
-       ACCESS_ONCE(ads->ds_data) = i->buf_addr[0];
+       WRITE_ONCE(ads->ds_link, i->link);
+       WRITE_ONCE(ads->ds_data, i->buf_addr[0]);
 
        ctl1 = i->buf_len[0] | (i->is_last ? 0 : AR_TxMore);
        ctl6 = SM(i->keytype, AR_EncrType);
@@ -235,26 +235,26 @@ ar9002_set_txdesc(struct ath_hw *ah, void *ds, struct ath_tx_info *i)
 
        if ((i->is_first || i->is_last) &&
            i->aggr != AGGR_BUF_MIDDLE && i->aggr != AGGR_BUF_LAST) {
-               ACCESS_ONCE(ads->ds_ctl2) = set11nTries(i->rates, 0)
+               WRITE_ONCE(ads->ds_ctl2, set11nTries(i->rates, 0)
                        | set11nTries(i->rates, 1)
                        | set11nTries(i->rates, 2)
                        | set11nTries(i->rates, 3)
                        | (i->dur_update ? AR_DurUpdateEna : 0)
-                       | SM(0, AR_BurstDur);
+                       | SM(0, AR_BurstDur));
 
-               ACCESS_ONCE(ads->ds_ctl3) = set11nRate(i->rates, 0)
+               WRITE_ONCE(ads->ds_ctl3, set11nRate(i->rates, 0)
                        | set11nRate(i->rates, 1)
                        | set11nRate(i->rates, 2)
-                       | set11nRate(i->rates, 3);
+                       | set11nRate(i->rates, 3));
        } else {
-               ACCESS_ONCE(ads->ds_ctl2) = 0;
-               ACCESS_ONCE(ads->ds_ctl3) = 0;
+               WRITE_ONCE(ads->ds_ctl2, 0);
+               WRITE_ONCE(ads->ds_ctl3, 0);
        }
 
        if (!i->is_first) {
-               ACCESS_ONCE(ads->ds_ctl0) = 0;
-               ACCESS_ONCE(ads->ds_ctl1) = ctl1;
-               ACCESS_ONCE(ads->ds_ctl6) = ctl6;
+               WRITE_ONCE(ads->ds_ctl0, 0);
+               WRITE_ONCE(ads->ds_ctl1, ctl1);
+               WRITE_ONCE(ads->ds_ctl6, ctl6);
                return;
        }
 
@@ -279,7 +279,7 @@ ar9002_set_txdesc(struct ath_hw *ah, void *ds, struct ath_tx_info *i)
                break;
        }
 
-       ACCESS_ONCE(ads->ds_ctl0) = (i->pkt_len & AR_FrameLen)
+       WRITE_ONCE(ads->ds_ctl0, (i->pkt_len & AR_FrameLen)
                | (i->flags & ATH9K_TXDESC_VMF ? AR_VirtMoreFrag : 0)
                | SM(i->txpower[0], AR_XmitPower0)
                | (i->flags & ATH9K_TXDESC_VEOL ? AR_VEOL : 0)
@@ -287,29 +287,29 @@ ar9002_set_txdesc(struct ath_hw *ah, void *ds, struct ath_tx_info *i)
                | (i->keyix != ATH9K_TXKEYIX_INVALID ? AR_DestIdxValid : 0)
                | (i->flags & ATH9K_TXDESC_CLRDMASK ? AR_ClrDestMask : 0)
                | (i->flags & ATH9K_TXDESC_RTSENA ? AR_RTSEnable :
-                  (i->flags & ATH9K_TXDESC_CTSENA ? AR_CTSEnable : 0));
+                  (i->flags & ATH9K_TXDESC_CTSENA ? AR_CTSEnable : 0)));
 
-       ACCESS_ONCE(ads->ds_ctl1) = ctl1;
-       ACCESS_ONCE(ads->ds_ctl6) = ctl6;
+       WRITE_ONCE(ads->ds_ctl1, ctl1);
+       WRITE_ONCE(ads->ds_ctl6, ctl6);
 
        if (i->aggr == AGGR_BUF_MIDDLE || i->aggr == AGGR_BUF_LAST)
                return;
 
-       ACCESS_ONCE(ads->ds_ctl4) = set11nPktDurRTSCTS(i->rates, 0)
-               | set11nPktDurRTSCTS(i->rates, 1);
+       WRITE_ONCE(ads->ds_ctl4, set11nPktDurRTSCTS(i->rates, 0)
+               | set11nPktDurRTSCTS(i->rates, 1));
 
-       ACCESS_ONCE(ads->ds_ctl5) = set11nPktDurRTSCTS(i->rates, 2)
-               | set11nPktDurRTSCTS(i->rates, 3);
+       WRITE_ONCE(ads->ds_ctl5, set11nPktDurRTSCTS(i->rates, 2)
+               | set11nPktDurRTSCTS(i->rates, 3));
 
-       ACCESS_ONCE(ads->ds_ctl7) = set11nRateFlags(i->rates, 0)
+       WRITE_ONCE(ads->ds_ctl7, set11nRateFlags(i->rates, 0)
                | set11nRateFlags(i->rates, 1)
                | set11nRateFlags(i->rates, 2)
                | set11nRateFlags(i->rates, 3)
-               | SM(i->rtscts_rate, AR_RTSCTSRate);
+               | SM(i->rtscts_rate, AR_RTSCTSRate));
 
-       ACCESS_ONCE(ads->ds_ctl9) = SM(i->txpower[1], AR_XmitPower1);
-       ACCESS_ONCE(ads->ds_ctl10) = SM(i->txpower[2], AR_XmitPower2);
-       ACCESS_ONCE(ads->ds_ctl11) = SM(i->txpower[3], AR_XmitPower3);
+       WRITE_ONCE(ads->ds_ctl9, SM(i->txpower[1], AR_XmitPower1));
+       WRITE_ONCE(ads->ds_ctl10, SM(i->txpower[2], AR_XmitPower2));
+       WRITE_ONCE(ads->ds_ctl11, SM(i->txpower[3], AR_XmitPower3));
 }
 
 static int ar9002_hw_proc_txdesc(struct ath_hw *ah, void *ds,
@@ -318,7 +318,7 @@ static int ar9002_hw_proc_txdesc(struct ath_hw *ah, void *ds,
        struct ar5416_desc *ads = AR5416DESC(ds);
        u32 status;
 
-       status = ACCESS_ONCE(ads->ds_txstatus9);
+       status = READ_ONCE(ads->ds_txstatus9);
        if ((status & AR_TxDone) == 0)
                return -EINPROGRESS;
 
@@ -332,7 +332,7 @@ static int ar9002_hw_proc_txdesc(struct ath_hw *ah, void *ds,
        ts->ts_rateindex = MS(status, AR_FinalTxIdx);
        ts->ts_seqnum = MS(status, AR_SeqNum);
 
-       status = ACCESS_ONCE(ads->ds_txstatus0);
+       status = READ_ONCE(ads->ds_txstatus0);
        ts->ts_rssi_ctl0 = MS(status, AR_TxRSSIAnt00);
        ts->ts_rssi_ctl1 = MS(status, AR_TxRSSIAnt01);
        ts->ts_rssi_ctl2 = MS(status, AR_TxRSSIAnt02);
@@ -342,7 +342,7 @@ static int ar9002_hw_proc_txdesc(struct ath_hw *ah, void *ds,
                ts->ba_high = ads->AR_BaBitmapHigh;
        }
 
-       status = ACCESS_ONCE(ads->ds_txstatus1);
+       status = READ_ONCE(ads->ds_txstatus1);
        if (status & AR_FrmXmitOK)
                ts->ts_status |= ATH9K_TX_ACKED;
        else {
@@ -371,7 +371,7 @@ static int ar9002_hw_proc_txdesc(struct ath_hw *ah, void *ds,
        ts->ts_longretry = MS(status, AR_DataFailCnt);
        ts->ts_virtcol = MS(status, AR_VirtRetryCnt);
 
-       status = ACCESS_ONCE(ads->ds_txstatus5);
+       status = READ_ONCE(ads->ds_txstatus5);
        ts->ts_rssi = MS(status, AR_TxRSSICombined);
        ts->ts_rssi_ext0 = MS(status, AR_TxRSSIAnt10);
        ts->ts_rssi_ext1 = MS(status, AR_TxRSSIAnt11);
@@ -390,13 +390,13 @@ static int ar9002_hw_get_duration(struct ath_hw *ah, const void *ds, int index)
 
        switch (index) {
        case 0:
-               return MS(ACCESS_ONCE(ads->ds_ctl4), AR_PacketDur0);
+               return MS(READ_ONCE(ads->ds_ctl4), AR_PacketDur0);
        case 1:
-               return MS(ACCESS_ONCE(ads->ds_ctl4), AR_PacketDur1);
+               return MS(READ_ONCE(ads->ds_ctl4), AR_PacketDur1);
        case 2:
-               return MS(ACCESS_ONCE(ads->ds_ctl5), AR_PacketDur2);
+               return MS(READ_ONCE(ads->ds_ctl5), AR_PacketDur2);
        case 3:
-               return MS(ACCESS_ONCE(ads->ds_ctl5), AR_PacketDur3);
+               return MS(READ_ONCE(ads->ds_ctl5), AR_PacketDur3);
        default:
                return -1;
        }
index da84b705cbcdc476734ac5f2c41dc82443e744d6..cc5bb0a76baf3985c205f17f6db912a9eaad3b6e 100644 (file)
@@ -39,47 +39,47 @@ ar9003_set_txdesc(struct ath_hw *ah, void *ds, struct ath_tx_info *i)
              (i->qcu << AR_TxQcuNum_S) | desc_len;
 
        checksum += val;
-       ACCESS_ONCE(ads->info) = val;
+       WRITE_ONCE(ads->info, val);
 
        checksum += i->link;
-       ACCESS_ONCE(ads->link) = i->link;
+       WRITE_ONCE(ads->link, i->link);
 
        checksum += i->buf_addr[0];
-       ACCESS_ONCE(ads->data0) = i->buf_addr[0];
+       WRITE_ONCE(ads->data0, i->buf_addr[0]);
        checksum += i->buf_addr[1];
-       ACCESS_ONCE(ads->data1) = i->buf_addr[1];
+       WRITE_ONCE(ads->data1, i->buf_addr[1]);
        checksum += i->buf_addr[2];
-       ACCESS_ONCE(ads->data2) = i->buf_addr[2];
+       WRITE_ONCE(ads->data2, i->buf_addr[2]);
        checksum += i->buf_addr[3];
-       ACCESS_ONCE(ads->data3) = i->buf_addr[3];
+       WRITE_ONCE(ads->data3, i->buf_addr[3]);
 
        checksum += (val = (i->buf_len[0] << AR_BufLen_S) & AR_BufLen);
-       ACCESS_ONCE(ads->ctl3) = val;
+       WRITE_ONCE(ads->ctl3, val);
        checksum += (val = (i->buf_len[1] << AR_BufLen_S) & AR_BufLen);
-       ACCESS_ONCE(ads->ctl5) = val;
+       WRITE_ONCE(ads->ctl5, val);
        checksum += (val = (i->buf_len[2] << AR_BufLen_S) & AR_BufLen);
-       ACCESS_ONCE(ads->ctl7) = val;
+       WRITE_ONCE(ads->ctl7, val);
        checksum += (val = (i->buf_len[3] << AR_BufLen_S) & AR_BufLen);
-       ACCESS_ONCE(ads->ctl9) = val;
+       WRITE_ONCE(ads->ctl9, val);
 
        checksum = (u16) (((checksum & 0xffff) + (checksum >> 16)) & 0xffff);
-       ACCESS_ONCE(ads->ctl10) = checksum;
+       WRITE_ONCE(ads->ctl10, checksum);
 
        if (i->is_first || i->is_last) {
-               ACCESS_ONCE(ads->ctl13) = set11nTries(i->rates, 0)
+               WRITE_ONCE(ads->ctl13, set11nTries(i->rates, 0)
                        | set11nTries(i->rates, 1)
                        | set11nTries(i->rates, 2)
                        | set11nTries(i->rates, 3)
                        | (i->dur_update ? AR_DurUpdateEna : 0)
-                       | SM(0, AR_BurstDur);
+                       | SM(0, AR_BurstDur));
 
-               ACCESS_ONCE(ads->ctl14) = set11nRate(i->rates, 0)
+               WRITE_ONCE(ads->ctl14, set11nRate(i->rates, 0)
                        | set11nRate(i->rates, 1)
                        | set11nRate(i->rates, 2)
-                       | set11nRate(i->rates, 3);
+                       | set11nRate(i->rates, 3));
        } else {
-               ACCESS_ONCE(ads->ctl13) = 0;
-               ACCESS_ONCE(ads->ctl14) = 0;
+               WRITE_ONCE(ads->ctl13, 0);
+               WRITE_ONCE(ads->ctl14, 0);
        }
 
        ads->ctl20 = 0;
@@ -89,17 +89,17 @@ ar9003_set_txdesc(struct ath_hw *ah, void *ds, struct ath_tx_info *i)
 
        ctl17 = SM(i->keytype, AR_EncrType);
        if (!i->is_first) {
-               ACCESS_ONCE(ads->ctl11) = 0;
-               ACCESS_ONCE(ads->ctl12) = i->is_last ? 0 : AR_TxMore;
-               ACCESS_ONCE(ads->ctl15) = 0;
-               ACCESS_ONCE(ads->ctl16) = 0;
-               ACCESS_ONCE(ads->ctl17) = ctl17;
-               ACCESS_ONCE(ads->ctl18) = 0;
-               ACCESS_ONCE(ads->ctl19) = 0;
+               WRITE_ONCE(ads->ctl11, 0);
+               WRITE_ONCE(ads->ctl12, i->is_last ? 0 : AR_TxMore);
+               WRITE_ONCE(ads->ctl15, 0);
+               WRITE_ONCE(ads->ctl16, 0);
+               WRITE_ONCE(ads->ctl17, ctl17);
+               WRITE_ONCE(ads->ctl18, 0);
+               WRITE_ONCE(ads->ctl19, 0);
                return;
        }
 
-       ACCESS_ONCE(ads->ctl11) = (i->pkt_len & AR_FrameLen)
+       WRITE_ONCE(ads->ctl11, (i->pkt_len & AR_FrameLen)
                | (i->flags & ATH9K_TXDESC_VMF ? AR_VirtMoreFrag : 0)
                | SM(i->txpower[0], AR_XmitPower0)
                | (i->flags & ATH9K_TXDESC_VEOL ? AR_VEOL : 0)
@@ -107,7 +107,7 @@ ar9003_set_txdesc(struct ath_hw *ah, void *ds, struct ath_tx_info *i)
                | (i->flags & ATH9K_TXDESC_LOWRXCHAIN ? AR_LowRxChain : 0)
                | (i->flags & ATH9K_TXDESC_CLRDMASK ? AR_ClrDestMask : 0)
                | (i->flags & ATH9K_TXDESC_RTSENA ? AR_RTSEnable :
-                  (i->flags & ATH9K_TXDESC_CTSENA ? AR_CTSEnable : 0));
+                  (i->flags & ATH9K_TXDESC_CTSENA ? AR_CTSEnable : 0)));
 
        ctl12 = (i->keyix != ATH9K_TXKEYIX_INVALID ?
                 SM(i->keyix, AR_DestIdx) : 0)
@@ -135,26 +135,26 @@ ar9003_set_txdesc(struct ath_hw *ah, void *ds, struct ath_tx_info *i)
        val = (i->flags & ATH9K_TXDESC_PAPRD) >> ATH9K_TXDESC_PAPRD_S;
        ctl12 |= SM(val, AR_PAPRDChainMask);
 
-       ACCESS_ONCE(ads->ctl12) = ctl12;
-       ACCESS_ONCE(ads->ctl17) = ctl17;
+       WRITE_ONCE(ads->ctl12, ctl12);
+       WRITE_ONCE(ads->ctl17, ctl17);
 
-       ACCESS_ONCE(ads->ctl15) = set11nPktDurRTSCTS(i->rates, 0)
-               | set11nPktDurRTSCTS(i->rates, 1);
+       WRITE_ONCE(ads->ctl15, set11nPktDurRTSCTS(i->rates, 0)
+               | set11nPktDurRTSCTS(i->rates, 1));
 
-       ACCESS_ONCE(ads->ctl16) = set11nPktDurRTSCTS(i->rates, 2)
-               | set11nPktDurRTSCTS(i->rates, 3);
+       WRITE_ONCE(ads->ctl16, set11nPktDurRTSCTS(i->rates, 2)
+               | set11nPktDurRTSCTS(i->rates, 3));
 
-       ACCESS_ONCE(ads->ctl18) = set11nRateFlags(i->rates, 0)
+       WRITE_ONCE(ads->ctl18, set11nRateFlags(i->rates, 0)
                | set11nRateFlags(i->rates, 1)
                | set11nRateFlags(i->rates, 2)
                | set11nRateFlags(i->rates, 3)
-               | SM(i->rtscts_rate, AR_RTSCTSRate);
+               | SM(i->rtscts_rate, AR_RTSCTSRate));
 
-       ACCESS_ONCE(ads->ctl19) = AR_Not_Sounding;
+       WRITE_ONCE(ads->ctl19, AR_Not_Sounding);
 
-       ACCESS_ONCE(ads->ctl20) = SM(i->txpower[1], AR_XmitPower1);
-       ACCESS_ONCE(ads->ctl21) = SM(i->txpower[2], AR_XmitPower2);
-       ACCESS_ONCE(ads->ctl22) = SM(i->txpower[3], AR_XmitPower3);
+       WRITE_ONCE(ads->ctl20, SM(i->txpower[1], AR_XmitPower1));
+       WRITE_ONCE(ads->ctl21, SM(i->txpower[2], AR_XmitPower2));
+       WRITE_ONCE(ads->ctl22, SM(i->txpower[3], AR_XmitPower3));
 }
 
 static u16 ar9003_calc_ptr_chksum(struct ar9003_txc *ads)
@@ -359,7 +359,7 @@ static int ar9003_hw_proc_txdesc(struct ath_hw *ah, void *ds,
 
        ads = &ah->ts_ring[ah->ts_tail];
 
-       status = ACCESS_ONCE(ads->status8);
+       status = READ_ONCE(ads->status8);
        if ((status & AR_TxDone) == 0)
                return -EINPROGRESS;
 
@@ -385,7 +385,7 @@ static int ar9003_hw_proc_txdesc(struct ath_hw *ah, void *ds,
 
        if (status & AR_TxOpExceeded)
                ts->ts_status |= ATH9K_TXERR_XTXOP;
-       status = ACCESS_ONCE(ads->status2);
+       status = READ_ONCE(ads->status2);
        ts->ts_rssi_ctl0 = MS(status, AR_TxRSSIAnt00);
        ts->ts_rssi_ctl1 = MS(status, AR_TxRSSIAnt01);
        ts->ts_rssi_ctl2 = MS(status, AR_TxRSSIAnt02);
@@ -395,7 +395,7 @@ static int ar9003_hw_proc_txdesc(struct ath_hw *ah, void *ds,
                ts->ba_high = ads->status6;
        }
 
-       status = ACCESS_ONCE(ads->status3);
+       status = READ_ONCE(ads->status3);
        if (status & AR_ExcessiveRetries)
                ts->ts_status |= ATH9K_TXERR_XRETRY;
        if (status & AR_Filtered)
@@ -420,7 +420,7 @@ static int ar9003_hw_proc_txdesc(struct ath_hw *ah, void *ds,
        ts->ts_longretry = MS(status, AR_DataFailCnt);
        ts->ts_virtcol = MS(status, AR_VirtRetryCnt);
 
-       status = ACCESS_ONCE(ads->status7);
+       status = READ_ONCE(ads->status7);
        ts->ts_rssi = MS(status, AR_TxRSSICombined);
        ts->ts_rssi_ext0 = MS(status, AR_TxRSSIAnt10);
        ts->ts_rssi_ext1 = MS(status, AR_TxRSSIAnt11);
@@ -437,13 +437,13 @@ static int ar9003_hw_get_duration(struct ath_hw *ah, const void *ds, int index)
 
        switch (index) {
        case 0:
-               return MS(ACCESS_ONCE(adc->ctl15), AR_PacketDur0);
+               return MS(READ_ONCE(adc->ctl15), AR_PacketDur0);
        case 1:
-               return MS(ACCESS_ONCE(adc->ctl15), AR_PacketDur1);
+               return MS(READ_ONCE(adc->ctl15), AR_PacketDur1);
        case 2:
-               return MS(ACCESS_ONCE(adc->ctl16), AR_PacketDur2);
+               return MS(READ_ONCE(adc->ctl16), AR_PacketDur2);
        case 3:
-               return MS(ACCESS_ONCE(adc->ctl16), AR_PacketDur3);
+               return MS(READ_ONCE(adc->ctl16), AR_PacketDur3);
        default:
                return 0;
        }
index 7c9788490f7f3371286a473cc3d85cd5747e9465..3376990d3a24803cf190c736f1e0fefd1660d3d9 100644 (file)
@@ -60,6 +60,7 @@ struct ath_rx_stats {
        u32 rx_spectral;
 };
 
+#ifdef CONFIG_ATH9K_COMMON_DEBUG
 void ath9k_cmn_debug_modal_eeprom(struct dentry *debugfs_phy,
                                  struct ath_hw *ah);
 void ath9k_cmn_debug_base_eeprom(struct dentry *debugfs_phy,
@@ -70,3 +71,29 @@ void ath9k_cmn_debug_recv(struct dentry *debugfs_phy,
                          struct ath_rx_stats *rxstats);
 void ath9k_cmn_debug_phy_err(struct dentry *debugfs_phy,
                             struct ath_rx_stats *rxstats);
+#else
+static inline void ath9k_cmn_debug_modal_eeprom(struct dentry *debugfs_phy,
+                                               struct ath_hw *ah)
+{
+}
+
+static inline void ath9k_cmn_debug_base_eeprom(struct dentry *debugfs_phy,
+                                              struct ath_hw *ah)
+{
+}
+
+static inline void ath9k_cmn_debug_stat_rx(struct ath_rx_stats *rxstats,
+                                          struct ath_rx_status *rs)
+{
+}
+
+static inline void ath9k_cmn_debug_recv(struct dentry *debugfs_phy,
+                                       struct ath_rx_stats *rxstats)
+{
+}
+
+static inline void ath9k_cmn_debug_phy_err(struct dentry *debugfs_phy,
+                                          struct ath_rx_stats *rxstats)
+{
+}
+#endif /* CONFIG_ATH9K_COMMON_DEBUG */
index eedf86b67cf517f4b9a400333cbc000ad28441d7..789a3dbe8341ee657623e05a23ea7672c068b618 100644 (file)
@@ -1075,7 +1075,7 @@ static struct rchan_callbacks rfs_spec_scan_cb = {
 
 void ath9k_cmn_spectral_deinit_debug(struct ath_spec_scan_priv *spec_priv)
 {
-       if (IS_ENABLED(CONFIG_ATH9K_DEBUGFS) && spec_priv->rfs_chan_spec_scan) {
+       if (spec_priv->rfs_chan_spec_scan) {
                relay_close(spec_priv->rfs_chan_spec_scan);
                spec_priv->rfs_chan_spec_scan = NULL;
        }
index 998743be9c6724de510d1dc33d62eb67df32577d..5d1a51d83aa646006f20298e206bb391830b5a78 100644 (file)
@@ -151,6 +151,7 @@ static inline u8 spectral_bitmap_weight(u8 *bins)
        return bins[0] & 0x3f;
 }
 
+#ifdef CONFIG_ATH9K_COMMON_DEBUG
 void ath9k_cmn_spectral_init_debug(struct ath_spec_scan_priv *spec_priv, struct dentry *debugfs_phy);
 void ath9k_cmn_spectral_deinit_debug(struct ath_spec_scan_priv *spec_priv);
 
@@ -161,5 +162,27 @@ int ath9k_cmn_spectral_scan_config(struct ath_common *common,
                               enum spectral_mode spectral_mode);
 int ath_cmn_process_fft(struct ath_spec_scan_priv *spec_priv, struct ieee80211_hdr *hdr,
                    struct ath_rx_status *rs, u64 tsf);
+#else
+static inline void ath9k_cmn_spectral_init_debug(struct ath_spec_scan_priv *spec_priv,
+                                                struct dentry *debugfs_phy)
+{
+}
+
+static inline void ath9k_cmn_spectral_deinit_debug(struct ath_spec_scan_priv *spec_priv)
+{
+}
+
+static inline void ath9k_cmn_spectral_scan_trigger(struct ath_common *common,
+                                                  struct ath_spec_scan_priv *spec_priv)
+{
+}
+
+static inline int ath_cmn_process_fft(struct ath_spec_scan_priv *spec_priv,
+                                     struct ieee80211_hdr *hdr,
+                                     struct ath_rx_status *rs, u64 tsf)
+{
+       return 0;
+}
+#endif /* CONFIG_ATH9K_COMMON_DEBUG */
 
 #endif /* SPECTRAL_H */
index 4a01ebe53053f864a3040c6bdd2233205accb0a6..b8c0a08066a010c22e4031f0254dde0f66749824 100644 (file)
@@ -72,7 +72,7 @@ static bool ath9k_hw_4k_fill_eeprom(struct ath_hw *ah)
                return __ath9k_hw_4k_fill_eeprom(ah);
 }
 
-#if defined(CONFIG_ATH9K_DEBUGFS) || defined(CONFIG_ATH9K_HTC_DEBUGFS)
+#ifdef CONFIG_ATH9K_COMMON_DEBUG
 static u32 ath9k_dump_4k_modal_eeprom(char *buf, u32 len, u32 size,
                                      struct modal_eep_4k_header *modal_hdr)
 {
index 9611f020f7c0ab24e9ce535d94cd2a293dfd8036..3caa149b10131eca4b444306eff31688a525fa83 100644 (file)
@@ -75,7 +75,7 @@ static bool ath9k_hw_ar9287_fill_eeprom(struct ath_hw *ah)
                return __ath9k_hw_ar9287_fill_eeprom(ah);
 }
 
-#if defined(CONFIG_ATH9K_DEBUGFS) || defined(CONFIG_ATH9K_HTC_DEBUGFS)
+#ifdef CONFIG_ATH9K_COMMON_DEBUG
 static u32 ar9287_dump_modal_eeprom(char *buf, u32 len, u32 size,
                                    struct modal_eep_ar9287_header *modal_hdr)
 {
index 7d5223451ce9d85cb5aae42d89d9477cb2abdcda..56b44fc7a8e6a2a5c9cf0808b776b79157214844 100644 (file)
@@ -131,7 +131,7 @@ static bool ath9k_hw_def_fill_eeprom(struct ath_hw *ah)
                return __ath9k_hw_def_fill_eeprom(ah);
 }
 
-#if defined(CONFIG_ATH9K_DEBUGFS) || defined(CONFIG_ATH9K_HTC_DEBUGFS)
+#ifdef CONFIG_ATH9K_COMMON_DEBUG
 static u32 ath9k_def_dump_modal_eeprom(char *buf, u32 len, u32 size,
                                       struct modal_eep_header *modal_hdr)
 {
index a35f78be8dec68d65f3fe7ff77a2f5edc244bd73..ac36873d6da4da9a5ee323ed2bebed45be2a5beb 100644 (file)
@@ -731,7 +731,7 @@ u32 ar9003_get_pll_sqsum_dvc(struct ath_hw *ah)
                udelay(100);
 
                if (WARN_ON_ONCE(i >= 100)) {
-                       ath_err(common, "PLL4 meaurement not done\n");
+                       ath_err(common, "PLL4 measurement not done\n");
                        break;
                }
 
index 591ebaea826564bf339f82b8152394dca022b5e8..4b83e87f0b9450bf431b48a168901371f1cab33c 100644 (file)
@@ -1,6 +1,8 @@
 config WCN36XX
        tristate "Qualcomm Atheros WCN3660/3680 support"
        depends on MAC80211 && HAS_DMA
+       depends on QCOM_WCNSS_CTRL || QCOM_WCNSS_CTRL=n
+       depends on QCOM_SMD || QCOM_SMD=n
        ---help---
          This module adds support for wireless adapters based on
          Qualcomm Atheros WCN3660 and WCN3680 mobile chipsets.
index 231fd022f0f54e96b58c522061d6441cf650c404..87dfdaf9044cdf8b41aba6b8345e9d2f9dd325a6 100644 (file)
@@ -23,6 +23,7 @@
 #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
 
 #include <linux/interrupt.h>
+#include <linux/soc/qcom/smem_state.h>
 #include "wcn36xx.h"
 #include "txrx.h"
 
@@ -151,9 +152,12 @@ int wcn36xx_dxe_alloc_ctl_blks(struct wcn36xx *wcn)
                goto out_err;
 
        /* Initialize SMSM state  Clear TX Enable RING EMPTY STATE */
-       ret = wcn->ctrl_ops->smsm_change_state(
-               WCN36XX_SMSM_WLAN_TX_ENABLE,
-               WCN36XX_SMSM_WLAN_TX_RINGS_EMPTY);
+       ret = qcom_smem_state_update_bits(wcn->tx_enable_state,
+                                         WCN36XX_SMSM_WLAN_TX_ENABLE |
+                                         WCN36XX_SMSM_WLAN_TX_RINGS_EMPTY,
+                                         WCN36XX_SMSM_WLAN_TX_RINGS_EMPTY);
+       if (ret)
+               goto out_err;
 
        return 0;
 
@@ -678,9 +682,9 @@ int wcn36xx_dxe_tx_frame(struct wcn36xx *wcn,
         * notify chip about new frame through SMSM bus.
         */
        if (is_low &&  vif_priv->pw_state == WCN36XX_BMPS) {
-               wcn->ctrl_ops->smsm_change_state(
-                                 0,
-                                 WCN36XX_SMSM_WLAN_TX_ENABLE);
+               qcom_smem_state_update_bits(wcn->tx_rings_empty_state,
+                                           WCN36XX_SMSM_WLAN_TX_ENABLE,
+                                           WCN36XX_SMSM_WLAN_TX_ENABLE);
        } else {
                /* indicate End Of Packet and generate interrupt on descriptor
                 * done.
index 4f87ef1e1eb866808ecc0b071b28d7bd4bbaeff1..b765c647319dd6e3a4f20ed25554272f0f240eab 100644 (file)
@@ -350,6 +350,8 @@ enum wcn36xx_hal_host_msg_type {
 
        WCN36XX_HAL_AVOID_FREQ_RANGE_IND = 233,
 
+       WCN36XX_HAL_PRINT_REG_INFO_IND = 259,
+
        WCN36XX_HAL_MSG_MAX = WCN36XX_HAL_MSG_TYPE_MAX_ENUM_SIZE
 };
 
@@ -4703,4 +4705,18 @@ struct stats_class_b_ind {
        u32 rx_time_total;
 };
 
+/* WCN36XX_HAL_PRINT_REG_INFO_IND */
+struct wcn36xx_hal_print_reg_info_ind {
+       struct wcn36xx_hal_msg_header header;
+
+       u32 count;
+       u32 scenario;
+       u32 reason;
+
+       struct {
+               u32 addr;
+               u32 value;
+       } regs[];
+} __packed;
+
 #endif /* _HAL_H_ */
index e1d59da2ad20fca15deea2fb8c01e6830509d7da..0002190c9041334eb8d1f4f8071e906c8e9e9a34 100644 (file)
 #include <linux/platform_device.h>
 #include <linux/of_address.h>
 #include <linux/of_device.h>
+#include <linux/of_irq.h>
+#include <linux/soc/qcom/smd.h>
+#include <linux/soc/qcom/smem_state.h>
+#include <linux/soc/qcom/wcnss_ctrl.h>
 #include "wcn36xx.h"
 
 unsigned int wcn36xx_dbg_mask;
@@ -564,23 +568,59 @@ out:
        return ret;
 }
 
-static void wcn36xx_sw_scan_start(struct ieee80211_hw *hw,
-                                 struct ieee80211_vif *vif,
-                                 const u8 *mac_addr)
+static void wcn36xx_hw_scan_worker(struct work_struct *work)
 {
-       struct wcn36xx *wcn = hw->priv;
+       struct wcn36xx *wcn = container_of(work, struct wcn36xx, scan_work);
+       struct cfg80211_scan_request *req = wcn->scan_req;
+       u8 channels[WCN36XX_HAL_PNO_MAX_NETW_CHANNELS_EX];
+       struct cfg80211_scan_info scan_info = {};
+       int i;
+
+       wcn36xx_dbg(WCN36XX_DBG_MAC, "mac80211 scan %d channels worker\n", req->n_channels);
+
+       for (i = 0; i < req->n_channels; i++)
+               channels[i] = req->channels[i]->hw_value;
+
+       wcn36xx_smd_update_scan_params(wcn, channels, req->n_channels);
 
        wcn36xx_smd_init_scan(wcn, HAL_SYS_MODE_SCAN);
-       wcn36xx_smd_start_scan(wcn);
+       for (i = 0; i < req->n_channels; i++) {
+               wcn->scan_freq = req->channels[i]->center_freq;
+               wcn->scan_band = req->channels[i]->band;
+
+               wcn36xx_smd_start_scan(wcn, req->channels[i]->hw_value);
+               msleep(30);
+               wcn36xx_smd_end_scan(wcn, req->channels[i]->hw_value);
+
+               wcn->scan_freq = 0;
+       }
+       wcn36xx_smd_finish_scan(wcn, HAL_SYS_MODE_SCAN);
+
+       scan_info.aborted = false;
+       ieee80211_scan_completed(wcn->hw, &scan_info);
+
+       mutex_lock(&wcn->scan_lock);
+       wcn->scan_req = NULL;
+       mutex_unlock(&wcn->scan_lock);
 }
 
-static void wcn36xx_sw_scan_complete(struct ieee80211_hw *hw,
-                                    struct ieee80211_vif *vif)
+static int wcn36xx_hw_scan(struct ieee80211_hw *hw,
+                          struct ieee80211_vif *vif,
+                          struct ieee80211_scan_request *hw_req)
 {
        struct wcn36xx *wcn = hw->priv;
 
-       wcn36xx_smd_end_scan(wcn);
-       wcn36xx_smd_finish_scan(wcn, HAL_SYS_MODE_SCAN);
+       mutex_lock(&wcn->scan_lock);
+       if (wcn->scan_req) {
+               mutex_unlock(&wcn->scan_lock);
+               return -EBUSY;
+       }
+       wcn->scan_req = &hw_req->req;
+       mutex_unlock(&wcn->scan_lock);
+
+       schedule_work(&wcn->scan_work);
+
+       return 0;
 }
 
 static void wcn36xx_update_allowed_rates(struct ieee80211_sta *sta,
@@ -993,8 +1033,7 @@ static const struct ieee80211_ops wcn36xx_ops = {
        .configure_filter       = wcn36xx_configure_filter,
        .tx                     = wcn36xx_tx,
        .set_key                = wcn36xx_set_key,
-       .sw_scan_start          = wcn36xx_sw_scan_start,
-       .sw_scan_complete       = wcn36xx_sw_scan_complete,
+       .hw_scan                = wcn36xx_hw_scan,
        .bss_info_changed       = wcn36xx_bss_info_changed,
        .set_rts_threshold      = wcn36xx_set_rts_threshold,
        .sta_add                = wcn36xx_sta_add,
@@ -1019,6 +1058,7 @@ static int wcn36xx_init_ieee80211(struct wcn36xx *wcn)
        ieee80211_hw_set(wcn->hw, SUPPORTS_PS);
        ieee80211_hw_set(wcn->hw, SIGNAL_DBM);
        ieee80211_hw_set(wcn->hw, HAS_RATE_CONTROL);
+       ieee80211_hw_set(wcn->hw, SINGLE_SCAN_ON_ALL_BANDS);
 
        wcn->hw->wiphy->interface_modes = BIT(NL80211_IFTYPE_STATION) |
                BIT(NL80211_IFTYPE_AP) |
@@ -1028,6 +1068,9 @@ static int wcn36xx_init_ieee80211(struct wcn36xx *wcn)
        wcn->hw->wiphy->bands[NL80211_BAND_2GHZ] = &wcn_band_2ghz;
        wcn->hw->wiphy->bands[NL80211_BAND_5GHZ] = &wcn_band_5ghz;
 
+       wcn->hw->wiphy->max_scan_ssids = WCN36XX_MAX_SCAN_SSIDS;
+       wcn->hw->wiphy->max_scan_ie_len = WCN36XX_MAX_SCAN_IE_LEN;
+
        wcn->hw->wiphy->cipher_suites = cipher_suites;
        wcn->hw->wiphy->n_cipher_suites = ARRAY_SIZE(cipher_suites);
 
@@ -1058,8 +1101,7 @@ static int wcn36xx_platform_get_resources(struct wcn36xx *wcn,
        int ret;
 
        /* Set TX IRQ */
-       res = platform_get_resource_byname(pdev, IORESOURCE_IRQ,
-                                          "wcnss_wlantx_irq");
+       res = platform_get_resource_byname(pdev, IORESOURCE_IRQ, "tx");
        if (!res) {
                wcn36xx_err("failed to get tx_irq\n");
                return -ENOENT;
@@ -1067,14 +1109,29 @@ static int wcn36xx_platform_get_resources(struct wcn36xx *wcn,
        wcn->tx_irq = res->start;
 
        /* Set RX IRQ */
-       res = platform_get_resource_byname(pdev, IORESOURCE_IRQ,
-                                          "wcnss_wlanrx_irq");
+       res = platform_get_resource_byname(pdev, IORESOURCE_IRQ, "rx");
        if (!res) {
                wcn36xx_err("failed to get rx_irq\n");
                return -ENOENT;
        }
        wcn->rx_irq = res->start;
 
+       /* Acquire SMSM tx enable handle */
+       wcn->tx_enable_state = qcom_smem_state_get(&pdev->dev,
+                       "tx-enable", &wcn->tx_enable_state_bit);
+       if (IS_ERR(wcn->tx_enable_state)) {
+               wcn36xx_err("failed to get tx-enable state\n");
+               return PTR_ERR(wcn->tx_enable_state);
+       }
+
+       /* Acquire SMSM tx rings empty handle */
+       wcn->tx_rings_empty_state = qcom_smem_state_get(&pdev->dev,
+                       "tx-rings-empty", &wcn->tx_rings_empty_state_bit);
+       if (IS_ERR(wcn->tx_rings_empty_state)) {
+               wcn36xx_err("failed to get tx-rings-empty state\n");
+               return PTR_ERR(wcn->tx_rings_empty_state);
+       }
+
        mmio_node = of_parse_phandle(pdev->dev.parent->of_node, "qcom,mmio", 0);
        if (!mmio_node) {
                wcn36xx_err("failed to acquire qcom,mmio reference\n");
@@ -1115,11 +1172,14 @@ static int wcn36xx_probe(struct platform_device *pdev)
 {
        struct ieee80211_hw *hw;
        struct wcn36xx *wcn;
+       void *wcnss;
        int ret;
-       u8 addr[ETH_ALEN];
+       const u8 *addr;
 
        wcn36xx_dbg(WCN36XX_DBG_MAC, "platform probe\n");
 
+       wcnss = dev_get_drvdata(pdev->dev.parent);
+
        hw = ieee80211_alloc_hw(sizeof(struct wcn36xx), &wcn36xx_ops);
        if (!hw) {
                wcn36xx_err("failed to alloc hw\n");
@@ -1130,11 +1190,26 @@ static int wcn36xx_probe(struct platform_device *pdev)
        wcn = hw->priv;
        wcn->hw = hw;
        wcn->dev = &pdev->dev;
-       wcn->ctrl_ops = pdev->dev.platform_data;
-
        mutex_init(&wcn->hal_mutex);
+       mutex_init(&wcn->scan_lock);
+
+       INIT_WORK(&wcn->scan_work, wcn36xx_hw_scan_worker);
+
+       wcn->smd_channel = qcom_wcnss_open_channel(wcnss, "WLAN_CTRL", wcn36xx_smd_rsp_process);
+       if (IS_ERR(wcn->smd_channel)) {
+               wcn36xx_err("failed to open WLAN_CTRL channel\n");
+               ret = PTR_ERR(wcn->smd_channel);
+               goto out_wq;
+       }
 
-       if (!wcn->ctrl_ops->get_hw_mac(addr)) {
+       qcom_smd_set_drvdata(wcn->smd_channel, hw);
+
+       addr = of_get_property(pdev->dev.of_node, "local-mac-address", &ret);
+       if (addr && ret != ETH_ALEN) {
+               wcn36xx_err("invalid local-mac-address\n");
+               ret = -EINVAL;
+               goto out_wq;
+       } else if (addr) {
                wcn36xx_info("mac address: %pM\n", addr);
                SET_IEEE80211_PERM_ADDR(wcn->hw, addr);
        }
@@ -1158,6 +1233,7 @@ out_wq:
 out_err:
        return ret;
 }
+
 static int wcn36xx_remove(struct platform_device *pdev)
 {
        struct ieee80211_hw *hw = platform_get_drvdata(pdev);
@@ -1165,45 +1241,37 @@ static int wcn36xx_remove(struct platform_device *pdev)
        wcn36xx_dbg(WCN36XX_DBG_MAC, "platform remove\n");
 
        release_firmware(wcn->nv);
-       mutex_destroy(&wcn->hal_mutex);
 
        ieee80211_unregister_hw(hw);
+
+       qcom_smem_state_put(wcn->tx_enable_state);
+       qcom_smem_state_put(wcn->tx_rings_empty_state);
+
        iounmap(wcn->dxe_base);
        iounmap(wcn->ccu_base);
+
+       mutex_destroy(&wcn->hal_mutex);
        ieee80211_free_hw(hw);
 
        return 0;
 }
-static const struct platform_device_id wcn36xx_platform_id_table[] = {
-       {
-               .name = "wcn36xx",
-               .driver_data = 0
-       },
+
+static const struct of_device_id wcn36xx_of_match[] = {
+       { .compatible = "qcom,wcnss-wlan" },
        {}
 };
-MODULE_DEVICE_TABLE(platform, wcn36xx_platform_id_table);
+MODULE_DEVICE_TABLE(of, wcn36xx_of_match);
 
 static struct platform_driver wcn36xx_driver = {
        .probe      = wcn36xx_probe,
        .remove     = wcn36xx_remove,
        .driver         = {
                .name   = "wcn36xx",
+               .of_match_table = wcn36xx_of_match,
        },
-       .id_table    = wcn36xx_platform_id_table,
 };
 
-static int __init wcn36xx_init(void)
-{
-       platform_driver_register(&wcn36xx_driver);
-       return 0;
-}
-module_init(wcn36xx_init);
-
-static void __exit wcn36xx_exit(void)
-{
-       platform_driver_unregister(&wcn36xx_driver);
-}
-module_exit(wcn36xx_exit);
+module_platform_driver(wcn36xx_driver);
 
 MODULE_LICENSE("Dual BSD/GPL");
 MODULE_AUTHOR("Eugene Krasnikov k.eugene.e@gmail.com");
index a443992320f2ed3aa2152b93d2d8ecb1819ec2fb..1c2966f7db7a3f7c41660027444e17f4a908c54d 100644 (file)
@@ -19,6 +19,7 @@
 #include <linux/etherdevice.h>
 #include <linux/firmware.h>
 #include <linux/bitops.h>
+#include <linux/soc/qcom/smd.h>
 #include "smd.h"
 
 struct wcn36xx_cfg_val {
@@ -253,7 +254,7 @@ static int wcn36xx_smd_send_and_wait(struct wcn36xx *wcn, size_t len)
 
        init_completion(&wcn->hal_rsp_compl);
        start = jiffies;
-       ret = wcn->ctrl_ops->tx(wcn->hal_buf, len);
+       ret = qcom_smd_send(wcn->smd_channel, wcn->hal_buf, len);
        if (ret) {
                wcn36xx_err("HAL TX failed\n");
                goto out;
@@ -521,7 +522,7 @@ out:
        return ret;
 }
 
-int wcn36xx_smd_start_scan(struct wcn36xx *wcn)
+int wcn36xx_smd_start_scan(struct wcn36xx *wcn, u8 scan_channel)
 {
        struct wcn36xx_hal_start_scan_req_msg msg_body;
        int ret = 0;
@@ -529,7 +530,7 @@ int wcn36xx_smd_start_scan(struct wcn36xx *wcn)
        mutex_lock(&wcn->hal_mutex);
        INIT_HAL_MSG(msg_body, WCN36XX_HAL_START_SCAN_REQ);
 
-       msg_body.scan_channel = WCN36XX_HW_CHANNEL(wcn);
+       msg_body.scan_channel = scan_channel;
 
        PREPARE_HAL_BUF(wcn->hal_buf, msg_body);
 
@@ -551,7 +552,7 @@ out:
        return ret;
 }
 
-int wcn36xx_smd_end_scan(struct wcn36xx *wcn)
+int wcn36xx_smd_end_scan(struct wcn36xx *wcn, u8 scan_channel)
 {
        struct wcn36xx_hal_end_scan_req_msg msg_body;
        int ret = 0;
@@ -559,7 +560,7 @@ int wcn36xx_smd_end_scan(struct wcn36xx *wcn)
        mutex_lock(&wcn->hal_mutex);
        INIT_HAL_MSG(msg_body, WCN36XX_HAL_END_SCAN_REQ);
 
-       msg_body.scan_channel = WCN36XX_HW_CHANNEL(wcn);
+       msg_body.scan_channel = scan_channel;
 
        PREPARE_HAL_BUF(wcn->hal_buf, msg_body);
 
@@ -2108,6 +2109,30 @@ static int wcn36xx_smd_delete_sta_context_ind(struct wcn36xx *wcn,
        return -ENOENT;
 }
 
+static int wcn36xx_smd_print_reg_info_ind(struct wcn36xx *wcn,
+                                         void *buf,
+                                         size_t len)
+{
+       struct wcn36xx_hal_print_reg_info_ind *rsp = buf;
+       int i;
+
+       if (len < sizeof(*rsp)) {
+               wcn36xx_warn("Corrupted print reg info indication\n");
+               return -EIO;
+       }
+
+       wcn36xx_dbg(WCN36XX_DBG_HAL,
+                   "reginfo indication, scenario: 0x%x reason: 0x%x\n",
+                   rsp->scenario, rsp->reason);
+
+       for (i = 0; i < rsp->count; i++) {
+               wcn36xx_dbg(WCN36XX_DBG_HAL, "\t0x%x: 0x%x\n",
+                           rsp->regs[i].addr, rsp->regs[i].value);
+       }
+
+       return 0;
+}
+
 int wcn36xx_smd_update_cfg(struct wcn36xx *wcn, u32 cfg_id, u32 value)
 {
        struct wcn36xx_hal_update_cfg_req_msg msg_body, *body;
@@ -2180,9 +2205,12 @@ out:
        return ret;
 }
 
-static void wcn36xx_smd_rsp_process(struct wcn36xx *wcn, void *buf, size_t len)
+int wcn36xx_smd_rsp_process(struct qcom_smd_channel *channel,
+                           const void *buf, size_t len)
 {
-       struct wcn36xx_hal_msg_header *msg_header = buf;
+       const struct wcn36xx_hal_msg_header *msg_header = buf;
+       struct ieee80211_hw *hw = qcom_smd_get_drvdata(channel);
+       struct wcn36xx *wcn = hw->priv;
        struct wcn36xx_hal_ind_msg *msg_ind;
        wcn36xx_dbg_dump(WCN36XX_DBG_SMD_DUMP, "SMD <<< ", buf, len);
 
@@ -2233,15 +2261,12 @@ static void wcn36xx_smd_rsp_process(struct wcn36xx *wcn, void *buf, size_t len)
        case WCN36XX_HAL_OTA_TX_COMPL_IND:
        case WCN36XX_HAL_MISSED_BEACON_IND:
        case WCN36XX_HAL_DELETE_STA_CONTEXT_IND:
-               msg_ind = kmalloc(sizeof(*msg_ind) + len, GFP_KERNEL);
+       case WCN36XX_HAL_PRINT_REG_INFO_IND:
+               msg_ind = kmalloc(sizeof(*msg_ind) + len, GFP_ATOMIC);
                if (!msg_ind) {
-                       /*
-                        * FIXME: Do something smarter then just
-                        * printing an error.
-                        */
                        wcn36xx_err("Run out of memory while handling SMD_EVENT (%d)\n",
                                    msg_header->msg_type);
-                       break;
+                       return -ENOMEM;
                }
 
                msg_ind->msg_len = len;
@@ -2257,6 +2282,8 @@ static void wcn36xx_smd_rsp_process(struct wcn36xx *wcn, void *buf, size_t len)
                wcn36xx_err("SMD_EVENT (%d) not supported\n",
                              msg_header->msg_type);
        }
+
+       return 0;
 }
 static void wcn36xx_ind_smd_work(struct work_struct *work)
 {
@@ -2294,6 +2321,11 @@ static void wcn36xx_ind_smd_work(struct work_struct *work)
                                                   hal_ind_msg->msg,
                                                   hal_ind_msg->msg_len);
                break;
+       case WCN36XX_HAL_PRINT_REG_INFO_IND:
+               wcn36xx_smd_print_reg_info_ind(wcn,
+                                              hal_ind_msg->msg,
+                                              hal_ind_msg->msg_len);
+               break;
        default:
                wcn36xx_err("SMD_EVENT (%d) not supported\n",
                              msg_header->msg_type);
@@ -2315,22 +2347,13 @@ int wcn36xx_smd_open(struct wcn36xx *wcn)
        INIT_LIST_HEAD(&wcn->hal_ind_queue);
        spin_lock_init(&wcn->hal_ind_lock);
 
-       ret = wcn->ctrl_ops->open(wcn, wcn36xx_smd_rsp_process);
-       if (ret) {
-               wcn36xx_err("failed to open control channel\n");
-               goto free_wq;
-       }
-
-       return ret;
+       return 0;
 
-free_wq:
-       destroy_workqueue(wcn->hal_ind_wq);
 out:
        return ret;
 }
 
 void wcn36xx_smd_close(struct wcn36xx *wcn)
 {
-       wcn->ctrl_ops->close();
        destroy_workqueue(wcn->hal_ind_wq);
 }
index df80cbbd9d1bed9fea3daca6f65b87b8f053d7d3..8892ccd67b144903ae25cde3287e79f951e5a8c6 100644 (file)
@@ -51,6 +51,7 @@ struct wcn36xx_hal_ind_msg {
 };
 
 struct wcn36xx;
+struct qcom_smd_channel;
 
 int wcn36xx_smd_open(struct wcn36xx *wcn);
 void wcn36xx_smd_close(struct wcn36xx *wcn);
@@ -59,8 +60,8 @@ int wcn36xx_smd_load_nv(struct wcn36xx *wcn);
 int wcn36xx_smd_start(struct wcn36xx *wcn);
 int wcn36xx_smd_stop(struct wcn36xx *wcn);
 int wcn36xx_smd_init_scan(struct wcn36xx *wcn, enum wcn36xx_hal_sys_mode mode);
-int wcn36xx_smd_start_scan(struct wcn36xx *wcn);
-int wcn36xx_smd_end_scan(struct wcn36xx *wcn);
+int wcn36xx_smd_start_scan(struct wcn36xx *wcn, u8 scan_channel);
+int wcn36xx_smd_end_scan(struct wcn36xx *wcn, u8 scan_channel);
 int wcn36xx_smd_finish_scan(struct wcn36xx *wcn,
                            enum wcn36xx_hal_sys_mode mode);
 int wcn36xx_smd_update_scan_params(struct wcn36xx *wcn, u8 *channels, size_t channel_count);
@@ -127,6 +128,10 @@ int wcn36xx_smd_del_ba(struct wcn36xx *wcn, u16 tid, u8 sta_index);
 int wcn36xx_smd_trigger_ba(struct wcn36xx *wcn, u8 sta_index);
 
 int wcn36xx_smd_update_cfg(struct wcn36xx *wcn, u32 cfg_id, u32 value);
+
+int wcn36xx_smd_rsp_process(struct qcom_smd_channel *channel,
+                           const void *buf, size_t len);
+
 int wcn36xx_smd_set_mc_list(struct wcn36xx *wcn,
                            struct ieee80211_vif *vif,
                            struct wcn36xx_hal_rcv_flt_mc_addr_list_type *fp);
index 1f34c2e912d7d9d7e7e39d4684972d4173a405b0..8c387a0a3c091c474e8f7dd948dc31b9060c0813 100644 (file)
@@ -45,9 +45,20 @@ int wcn36xx_rx_skb(struct wcn36xx *wcn, struct sk_buff *skb)
        skb_put(skb, bd->pdu.mpdu_header_off + bd->pdu.mpdu_len);
        skb_pull(skb, bd->pdu.mpdu_header_off);
 
+       hdr = (struct ieee80211_hdr *) skb->data;
+       fc = __le16_to_cpu(hdr->frame_control);
+       sn = IEEE80211_SEQ_TO_SN(__le16_to_cpu(hdr->seq_ctrl));
+
+       /* When scanning associate beacons to this */
+       if (ieee80211_is_beacon(hdr->frame_control) && wcn->scan_freq) {
+               status.freq = wcn->scan_freq;
+               status.band = wcn->scan_band;
+       } else {
+               status.freq = WCN36XX_CENTER_FREQ(wcn);
+               status.band = WCN36XX_BAND(wcn);
+       }
+
        status.mactime = 10;
-       status.freq = WCN36XX_CENTER_FREQ(wcn);
-       status.band = WCN36XX_BAND(wcn);
        status.signal = -get_rssi0(bd);
        status.antenna = 1;
        status.rate_idx = 1;
@@ -61,10 +72,6 @@ int wcn36xx_rx_skb(struct wcn36xx *wcn, struct sk_buff *skb)
 
        memcpy(IEEE80211_SKB_RXCB(skb), &status, sizeof(status));
 
-       hdr = (struct ieee80211_hdr *) skb->data;
-       fc = __le16_to_cpu(hdr->frame_control);
-       sn = IEEE80211_SEQ_TO_SN(__le16_to_cpu(hdr->seq_ctrl));
-
        if (ieee80211_is_beacon(hdr->frame_control)) {
                wcn36xx_dbg(WCN36XX_DBG_BEACON, "beacon skb %p len %d fc %04x sn %d\n",
                            skb, skb->len, fc, sn);
index 22242d18e1fe3b44f7e66ff5f30ab914838e35e8..35a6590c3ee51db0c5f9f2e3e1aa927e1b0531c8 100644 (file)
@@ -35,6 +35,9 @@
 /* How many frames until we start a-mpdu TX session */
 #define WCN36XX_AMPDU_START_THRESH     20
 
+#define WCN36XX_MAX_SCAN_SSIDS         9
+#define WCN36XX_MAX_SCAN_IE_LEN                500
+
 extern unsigned int wcn36xx_dbg_mask;
 
 enum wcn36xx_debug_mask {
@@ -103,19 +106,6 @@ struct nv_data {
        u8      table;
 };
 
-/* Interface for platform control path
- *
- * @open: hook must be called when wcn36xx wants to open control channel.
- * @tx: sends a buffer.
- */
-struct wcn36xx_platform_ctrl_ops {
-       int (*open)(void *drv_priv, void *rsp_cb);
-       void (*close)(void);
-       int (*tx)(char *buf, size_t len);
-       int (*get_hw_mac)(u8 *addr);
-       int (*smsm_change_state)(u32 clear_mask, u32 set_mask);
-};
-
 /**
  * struct wcn36xx_vif - holds VIF related fields
  *
@@ -205,7 +195,13 @@ struct wcn36xx {
        void __iomem            *ccu_base;
        void __iomem            *dxe_base;
 
-       struct wcn36xx_platform_ctrl_ops *ctrl_ops;
+       struct qcom_smd_channel *smd_channel;
+
+       struct qcom_smem_state  *tx_enable_state;
+       unsigned                tx_enable_state_bit;
+       struct qcom_smem_state  *tx_rings_empty_state;
+       unsigned                tx_rings_empty_state_bit;
+
        /*
         * smd_buf must be protected with smd_mutex to garantee
         * that all messages are sent one after another
@@ -219,6 +215,12 @@ struct wcn36xx {
        spinlock_t              hal_ind_lock;
        struct list_head        hal_ind_queue;
 
+       struct work_struct      scan_work;
+       struct cfg80211_scan_request *scan_req;
+       int                     scan_freq;
+       int                     scan_band;
+       struct mutex            scan_lock;
+
        /* DXE channels */
        struct wcn36xx_dxe_ch   dxe_tx_l_ch;    /* TX low */
        struct wcn36xx_dxe_ch   dxe_tx_h_ch;    /* TX high */
index 6aa3ff4240a9b541c209ac8f926193e7a9bc8632..e25e78e71f5402c26378e3508e238f7749439733 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2012-2016 Qualcomm Atheros, Inc.
+ * Copyright (c) 2012-2017 Qualcomm Atheros, Inc.
  *
  * Permission to use, copy, modify, and/or distribute this software for any
  * purpose with or without fee is hereby granted, provided that the above
 
 #define WIL_MAX_ROC_DURATION_MS 5000
 
+bool disable_ap_sme;
+module_param(disable_ap_sme, bool, 0444);
+MODULE_PARM_DESC(disable_ap_sme, " let user space handle AP mode SME");
+
 #define CHAN60G(_channel, _flags) {                            \
        .band                   = NL80211_BAND_60GHZ,           \
        .center_freq            = 56160 + (2160 * (_channel)),  \
@@ -62,9 +66,16 @@ wil_mgmt_stypes[NUM_NL80211_IFTYPES] = {
        },
        [NL80211_IFTYPE_AP] = {
                .tx = BIT(IEEE80211_STYPE_ACTION >> 4) |
-               BIT(IEEE80211_STYPE_PROBE_RESP >> 4),
+               BIT(IEEE80211_STYPE_PROBE_RESP >> 4) |
+               BIT(IEEE80211_STYPE_ASSOC_RESP >> 4) |
+               BIT(IEEE80211_STYPE_DISASSOC >> 4),
                .rx = BIT(IEEE80211_STYPE_ACTION >> 4) |
-               BIT(IEEE80211_STYPE_PROBE_REQ >> 4)
+               BIT(IEEE80211_STYPE_PROBE_REQ >> 4) |
+               BIT(IEEE80211_STYPE_ASSOC_REQ >> 4) |
+               BIT(IEEE80211_STYPE_DISASSOC >> 4) |
+               BIT(IEEE80211_STYPE_AUTH >> 4) |
+               BIT(IEEE80211_STYPE_DEAUTH >> 4) |
+               BIT(IEEE80211_STYPE_REASSOC_REQ >> 4)
        },
        [NL80211_IFTYPE_P2P_CLIENT] = {
                .tx = BIT(IEEE80211_STYPE_ACTION >> 4) |
@@ -194,7 +205,7 @@ static int wil_cfg80211_get_station(struct wiphy *wiphy,
 
        int cid = wil_find_cid(wil, mac);
 
-       wil_dbg_misc(wil, "%s(%pM) CID %d\n", __func__, mac, cid);
+       wil_dbg_misc(wil, "get_station: %pM CID %d\n", mac, cid);
        if (cid < 0)
                return cid;
 
@@ -233,7 +244,7 @@ static int wil_cfg80211_dump_station(struct wiphy *wiphy,
                return -ENOENT;
 
        ether_addr_copy(mac, wil->sta[cid].addr);
-       wil_dbg_misc(wil, "%s(%pM) CID %d\n", __func__, mac, cid);
+       wil_dbg_misc(wil, "dump_station: %pM CID %d\n", mac, cid);
 
        rc = wil_cid_fill_sinfo(wil, cid, sinfo);
 
@@ -250,16 +261,15 @@ wil_cfg80211_add_iface(struct wiphy *wiphy, const char *name,
        struct net_device *ndev = wil_to_ndev(wil);
        struct wireless_dev *p2p_wdev;
 
-       wil_dbg_misc(wil, "%s()\n", __func__);
+       wil_dbg_misc(wil, "add_iface\n");
 
        if (type != NL80211_IFTYPE_P2P_DEVICE) {
-               wil_err(wil, "%s: unsupported iftype %d\n", __func__, type);
+               wil_err(wil, "unsupported iftype %d\n", type);
                return ERR_PTR(-EINVAL);
        }
 
        if (wil->p2p_wdev) {
-               wil_err(wil, "%s: P2P_DEVICE interface already created\n",
-                       __func__);
+               wil_err(wil, "P2P_DEVICE interface already created\n");
                return ERR_PTR(-EINVAL);
        }
 
@@ -282,11 +292,10 @@ static int wil_cfg80211_del_iface(struct wiphy *wiphy,
 {
        struct wil6210_priv *wil = wiphy_to_wil(wiphy);
 
-       wil_dbg_misc(wil, "%s()\n", __func__);
+       wil_dbg_misc(wil, "del_iface\n");
 
        if (wdev != wil->p2p_wdev) {
-               wil_err(wil, "%s: delete of incorrect interface 0x%p\n",
-                       __func__, wdev);
+               wil_err(wil, "delete of incorrect interface 0x%p\n", wdev);
                return -EINVAL;
        }
 
@@ -304,7 +313,7 @@ static int wil_cfg80211_change_iface(struct wiphy *wiphy,
        struct wireless_dev *wdev = wil_to_wdev(wil);
        int rc;
 
-       wil_dbg_misc(wil, "%s() type=%d\n", __func__, type);
+       wil_dbg_misc(wil, "change_iface: type=%d\n", type);
 
        if (netif_running(wil_to_ndev(wil)) && !wil_is_recovery_blocked(wil)) {
                wil_dbg_misc(wil, "interface is up. resetting...\n");
@@ -351,8 +360,7 @@ static int wil_cfg80211_scan(struct wiphy *wiphy,
        uint i, n;
        int rc;
 
-       wil_dbg_misc(wil, "%s(), wdev=0x%p iftype=%d\n",
-                    __func__, wdev, wdev->iftype);
+       wil_dbg_misc(wil, "scan: wdev=0x%p iftype=%d\n", wdev, wdev->iftype);
 
        /* check we are client side */
        switch (wdev->iftype) {
@@ -557,7 +565,7 @@ static int wil_cfg80211_connect(struct wiphy *wiphy,
        int rc = 0;
        enum ieee80211_bss_type bss_type = IEEE80211_BSS_TYPE_ESS;
 
-       wil_dbg_misc(wil, "%s()\n", __func__);
+       wil_dbg_misc(wil, "connect\n");
        wil_print_connect_params(wil, sme);
 
        if (test_bit(wil_status_fwconnecting, wil->status) ||
@@ -593,6 +601,7 @@ static int wil_cfg80211_connect(struct wiphy *wiphy,
                goto out;
        }
        wil->privacy = sme->privacy;
+       wil->pbss = sme->pbss;
 
        if (wil->privacy) {
                /* For secure assoc, remove old keys */
@@ -689,12 +698,11 @@ static int wil_cfg80211_disconnect(struct wiphy *wiphy,
        int rc;
        struct wil6210_priv *wil = wiphy_to_wil(wiphy);
 
-       wil_dbg_misc(wil, "%s(reason=%d)\n", __func__, reason_code);
+       wil_dbg_misc(wil, "disconnect: reason=%d\n", reason_code);
 
        if (!(test_bit(wil_status_fwconnecting, wil->status) ||
              test_bit(wil_status_fwconnected, wil->status))) {
-               wil_err(wil, "%s: Disconnect was called while disconnected\n",
-                       __func__);
+               wil_err(wil, "Disconnect was called while disconnected\n");
                return 0;
        }
 
@@ -702,7 +710,7 @@ static int wil_cfg80211_disconnect(struct wiphy *wiphy,
                      WMI_DISCONNECT_EVENTID, NULL, 0,
                      WIL6210_DISCONNECT_TO_MS);
        if (rc)
-               wil_err(wil, "%s: disconnect error %d\n", __func__, rc);
+               wil_err(wil, "disconnect error %d\n", rc);
 
        return rc;
 }
@@ -750,7 +758,7 @@ int wil_cfg80211_mgmt_tx(struct wiphy *wiphy, struct wireless_dev *wdev,
         * different from currently "listened" channel and fail if it is.
         */
 
-       wil_dbg_misc(wil, "%s()\n", __func__);
+       wil_dbg_misc(wil, "mgmt_tx\n");
        print_hex_dump_bytes("mgmt tx frame ", DUMP_PREFIX_OFFSET, buf, len);
 
        cmd = kmalloc(sizeof(*cmd) + len, GFP_KERNEL);
@@ -811,7 +819,7 @@ static enum wmi_key_usage wil_detect_key_usage(struct wil6210_priv *wil,
                        break;
                }
        }
-       wil_dbg_misc(wil, "%s() -> %s\n", __func__, key_usage_str[rc]);
+       wil_dbg_misc(wil, "detect_key_usage: -> %s\n", key_usage_str[rc]);
 
        return rc;
 }
@@ -916,13 +924,13 @@ static int wil_cfg80211_add_key(struct wiphy *wiphy,
                return -EINVAL;
        }
 
-       wil_dbg_misc(wil, "%s(%pM %s[%d] PN %*phN)\n", __func__,
+       wil_dbg_misc(wil, "add_key: %pM %s[%d] PN %*phN\n",
                     mac_addr, key_usage_str[key_usage], key_index,
                     params->seq_len, params->seq);
 
        if (IS_ERR(cs)) {
-               wil_err(wil, "Not connected, %s(%pM %s[%d] PN %*phN)\n",
-                       __func__, mac_addr, key_usage_str[key_usage], key_index,
+               wil_err(wil, "Not connected, %pM %s[%d] PN %*phN\n",
+                       mac_addr, key_usage_str[key_usage], key_index,
                        params->seq_len, params->seq);
                return -EINVAL;
        }
@@ -931,8 +939,8 @@ static int wil_cfg80211_add_key(struct wiphy *wiphy,
 
        if (params->seq && params->seq_len != IEEE80211_GCMP_PN_LEN) {
                wil_err(wil,
-                       "Wrong PN len %d, %s(%pM %s[%d] PN %*phN)\n",
-                       params->seq_len, __func__, mac_addr,
+                       "Wrong PN len %d, %pM %s[%d] PN %*phN\n",
+                       params->seq_len, mac_addr,
                        key_usage_str[key_usage], key_index,
                        params->seq_len, params->seq);
                return -EINVAL;
@@ -956,11 +964,11 @@ static int wil_cfg80211_del_key(struct wiphy *wiphy,
        struct wil_sta_info *cs = wil_find_sta_by_key_usage(wil, key_usage,
                                                            mac_addr);
 
-       wil_dbg_misc(wil, "%s(%pM %s[%d])\n", __func__, mac_addr,
+       wil_dbg_misc(wil, "del_key: %pM %s[%d]\n", mac_addr,
                     key_usage_str[key_usage], key_index);
 
        if (IS_ERR(cs))
-               wil_info(wil, "Not connected, %s(%pM %s[%d])\n", __func__,
+               wil_info(wil, "Not connected, %pM %s[%d]\n",
                         mac_addr, key_usage_str[key_usage], key_index);
 
        if (!IS_ERR_OR_NULL(cs))
@@ -977,7 +985,7 @@ static int wil_cfg80211_set_default_key(struct wiphy *wiphy,
 {
        struct wil6210_priv *wil = wiphy_to_wil(wiphy);
 
-       wil_dbg_misc(wil, "%s: entered\n", __func__);
+       wil_dbg_misc(wil, "set_default_key: entered\n");
        return 0;
 }
 
@@ -990,8 +998,9 @@ static int wil_remain_on_channel(struct wiphy *wiphy,
        struct wil6210_priv *wil = wiphy_to_wil(wiphy);
        int rc;
 
-       wil_dbg_misc(wil, "%s() center_freq=%d, duration=%d iftype=%d\n",
-                    __func__, chan->center_freq, duration, wdev->iftype);
+       wil_dbg_misc(wil,
+                    "remain_on_channel: center_freq=%d, duration=%d iftype=%d\n",
+                    chan->center_freq, duration, wdev->iftype);
 
        rc = wil_p2p_listen(wil, wdev, duration, chan, cookie);
        return rc;
@@ -1003,7 +1012,7 @@ static int wil_cancel_remain_on_channel(struct wiphy *wiphy,
 {
        struct wil6210_priv *wil = wiphy_to_wil(wiphy);
 
-       wil_dbg_misc(wil, "%s()\n", __func__);
+       wil_dbg_misc(wil, "cancel_remain_on_channel\n");
 
        return wil_p2p_cancel_listen(wil, cookie);
 }
@@ -1159,9 +1168,9 @@ static int _wil_cfg80211_start_ap(struct wiphy *wiphy,
        if (pbss)
                wmi_nettype = WMI_NETTYPE_P2P;
 
-       wil_dbg_misc(wil, "%s: is_go=%d\n", __func__, is_go);
+       wil_dbg_misc(wil, "start_ap: is_go=%d\n", is_go);
        if (is_go && !pbss) {
-               wil_err(wil, "%s: P2P GO must be in PBSS\n", __func__);
+               wil_err(wil, "P2P GO must be in PBSS\n");
                return -ENOTSUPP;
        }
 
@@ -1216,7 +1225,7 @@ static int wil_cfg80211_change_beacon(struct wiphy *wiphy,
        int rc;
        u32 privacy = 0;
 
-       wil_dbg_misc(wil, "%s()\n", __func__);
+       wil_dbg_misc(wil, "change_beacon\n");
        wil_print_bcon_data(bcon);
 
        if (bcon->tail &&
@@ -1255,7 +1264,7 @@ static int wil_cfg80211_start_ap(struct wiphy *wiphy,
        struct cfg80211_crypto_settings *crypto = &info->crypto;
        u8 hidden_ssid;
 
-       wil_dbg_misc(wil, "%s()\n", __func__);
+       wil_dbg_misc(wil, "start_ap\n");
 
        if (!channel) {
                wil_err(wil, "AP: No channel???\n");
@@ -1306,7 +1315,7 @@ static int wil_cfg80211_stop_ap(struct wiphy *wiphy,
 {
        struct wil6210_priv *wil = wiphy_to_wil(wiphy);
 
-       wil_dbg_misc(wil, "%s()\n", __func__);
+       wil_dbg_misc(wil, "stop_ap\n");
 
        netif_carrier_off(ndev);
        wil_set_recovery_state(wil, fw_recovery_idle);
@@ -1322,13 +1331,35 @@ static int wil_cfg80211_stop_ap(struct wiphy *wiphy,
        return 0;
 }
 
+static int wil_cfg80211_add_station(struct wiphy *wiphy,
+                                   struct net_device *dev,
+                                   const u8 *mac,
+                                   struct station_parameters *params)
+{
+       struct wil6210_priv *wil = wiphy_to_wil(wiphy);
+
+       wil_dbg_misc(wil, "add station %pM aid %d\n", mac, params->aid);
+
+       if (!disable_ap_sme) {
+               wil_err(wil, "not supported with AP SME enabled\n");
+               return -EOPNOTSUPP;
+       }
+
+       if (params->aid > WIL_MAX_DMG_AID) {
+               wil_err(wil, "invalid aid\n");
+               return -EINVAL;
+       }
+
+       return wmi_new_sta(wil, mac, params->aid);
+}
+
 static int wil_cfg80211_del_station(struct wiphy *wiphy,
                                    struct net_device *dev,
                                    struct station_del_parameters *params)
 {
        struct wil6210_priv *wil = wiphy_to_wil(wiphy);
 
-       wil_dbg_misc(wil, "%s(%pM, reason=%d)\n", __func__, params->mac,
+       wil_dbg_misc(wil, "del_station: %pM, reason=%d\n", params->mac,
                     params->reason_code);
 
        mutex_lock(&wil->mutex);
@@ -1338,6 +1369,52 @@ static int wil_cfg80211_del_station(struct wiphy *wiphy,
        return 0;
 }
 
+static int wil_cfg80211_change_station(struct wiphy *wiphy,
+                                      struct net_device *dev,
+                                      const u8 *mac,
+                                      struct station_parameters *params)
+{
+       struct wil6210_priv *wil = wiphy_to_wil(wiphy);
+       int authorize;
+       int cid, i;
+       struct vring_tx_data *txdata = NULL;
+
+       wil_dbg_misc(wil, "change station %pM mask 0x%x set 0x%x\n", mac,
+                    params->sta_flags_mask, params->sta_flags_set);
+
+       if (!disable_ap_sme) {
+               wil_dbg_misc(wil, "not supported with AP SME enabled\n");
+               return -EOPNOTSUPP;
+       }
+
+       if (!(params->sta_flags_mask & BIT(NL80211_STA_FLAG_AUTHORIZED)))
+               return 0;
+
+       cid = wil_find_cid(wil, mac);
+       if (cid < 0) {
+               wil_err(wil, "station not found\n");
+               return -ENOLINK;
+       }
+
+       for (i = 0; i < ARRAY_SIZE(wil->vring2cid_tid); i++)
+               if (wil->vring2cid_tid[i][0] == cid) {
+                       txdata = &wil->vring_tx_data[i];
+                       break;
+               }
+
+       if (!txdata) {
+               wil_err(wil, "vring data not found\n");
+               return -ENOLINK;
+       }
+
+       authorize = params->sta_flags_set & BIT(NL80211_STA_FLAG_AUTHORIZED);
+       txdata->dot1x_open = authorize ? 1 : 0;
+       wil_dbg_misc(wil, "cid %d vring %d authorize %d\n", cid, i,
+                    txdata->dot1x_open);
+
+       return 0;
+}
+
 /* probe_client handling */
 static void wil_probe_client_handle(struct wil6210_priv *wil,
                                    struct wil_probe_client_req *req)
@@ -1387,7 +1464,7 @@ void wil_probe_client_flush(struct wil6210_priv *wil)
 {
        struct wil_probe_client_req *req, *t;
 
-       wil_dbg_misc(wil, "%s()\n", __func__);
+       wil_dbg_misc(wil, "probe_client_flush\n");
 
        mutex_lock(&wil->probe_client_mutex);
 
@@ -1407,7 +1484,7 @@ static int wil_cfg80211_probe_client(struct wiphy *wiphy,
        struct wil_probe_client_req *req;
        int cid = wil_find_cid(wil, peer);
 
-       wil_dbg_misc(wil, "%s(%pM => CID %d)\n", __func__, peer, cid);
+       wil_dbg_misc(wil, "probe_client: %pM => CID %d\n", peer, cid);
 
        if (cid < 0)
                return -ENOLINK;
@@ -1435,7 +1512,7 @@ static int wil_cfg80211_change_bss(struct wiphy *wiphy,
        struct wil6210_priv *wil = wiphy_to_wil(wiphy);
 
        if (params->ap_isolate >= 0) {
-               wil_dbg_misc(wil, "%s(ap_isolate %d => %d)\n", __func__,
+               wil_dbg_misc(wil, "change_bss: ap_isolate %d => %d\n",
                             wil->ap_isolate, params->ap_isolate);
                wil->ap_isolate = params->ap_isolate;
        }
@@ -1448,7 +1525,7 @@ static int wil_cfg80211_start_p2p_device(struct wiphy *wiphy,
 {
        struct wil6210_priv *wil = wiphy_to_wil(wiphy);
 
-       wil_dbg_misc(wil, "%s: entered\n", __func__);
+       wil_dbg_misc(wil, "start_p2p_device: entered\n");
        wil->p2p.p2p_dev_started = 1;
        return 0;
 }
@@ -1462,7 +1539,7 @@ static void wil_cfg80211_stop_p2p_device(struct wiphy *wiphy,
        if (!p2p->p2p_dev_started)
                return;
 
-       wil_dbg_misc(wil, "%s: entered\n", __func__);
+       wil_dbg_misc(wil, "stop_p2p_device: entered\n");
        mutex_lock(&wil->mutex);
        mutex_lock(&wil->p2p_wdev_mutex);
        wil_p2p_stop_radio_operations(wil);
@@ -1499,7 +1576,7 @@ static int wil_cfg80211_set_power_mgmt(struct wiphy *wiphy,
        return rc;
 }
 
-static struct cfg80211_ops wil_cfg80211_ops = {
+static const struct cfg80211_ops wil_cfg80211_ops = {
        .add_virtual_intf = wil_cfg80211_add_iface,
        .del_virtual_intf = wil_cfg80211_del_iface,
        .scan = wil_cfg80211_scan,
@@ -1521,7 +1598,9 @@ static struct cfg80211_ops wil_cfg80211_ops = {
        .change_beacon = wil_cfg80211_change_beacon,
        .start_ap = wil_cfg80211_start_ap,
        .stop_ap = wil_cfg80211_stop_ap,
+       .add_station = wil_cfg80211_add_station,
        .del_station = wil_cfg80211_del_station,
+       .change_station = wil_cfg80211_change_station,
        .probe_client = wil_cfg80211_probe_client,
        .change_bss = wil_cfg80211_change_bss,
        /* P2P device */
@@ -1542,10 +1621,11 @@ static void wil_wiphy_init(struct wiphy *wiphy)
                                 BIT(NL80211_IFTYPE_P2P_GO) |
                                 BIT(NL80211_IFTYPE_P2P_DEVICE) |
                                 BIT(NL80211_IFTYPE_MONITOR);
-       wiphy->flags |= WIPHY_FLAG_HAVE_AP_SME |
-                       WIPHY_FLAG_HAS_REMAIN_ON_CHANNEL |
+       wiphy->flags |= WIPHY_FLAG_HAS_REMAIN_ON_CHANNEL |
                        WIPHY_FLAG_AP_PROBE_RESP_OFFLOAD |
                        WIPHY_FLAG_PS_ON_BY_DEFAULT;
+       if (!disable_ap_sme)
+               wiphy->flags |= WIPHY_FLAG_HAVE_AP_SME;
        dev_dbg(wiphy_dev(wiphy), "%s : flags = 0x%08x\n",
                __func__, wiphy->flags);
        wiphy->probe_resp_offload =
index 5e4058a4037b414d1c5c2dc764f96960e6cd3c14..3e8cdf12fedad5251a36aaedecf7470f80ef4d7e 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2012-2016 Qualcomm Atheros, Inc.
+ * Copyright (c) 2012-2017 Qualcomm Atheros, Inc.
  *
  * Permission to use, copy, modify, and/or distribute this software for any
  * purpose with or without fee is hereby granted, provided that the above
@@ -364,13 +364,13 @@ static void wil6210_debugfs_init_offset(struct wil6210_priv *wil,
 }
 
 static const struct dbg_off isr_off[] = {
-       {"ICC", S_IRUGO | S_IWUSR, offsetof(struct RGF_ICR, ICC), doff_io32},
-       {"ICR", S_IRUGO | S_IWUSR, offsetof(struct RGF_ICR, ICR), doff_io32},
-       {"ICM", S_IRUGO | S_IWUSR, offsetof(struct RGF_ICR, ICM), doff_io32},
-       {"ICS",           S_IWUSR, offsetof(struct RGF_ICR, ICS), doff_io32},
-       {"IMV", S_IRUGO | S_IWUSR, offsetof(struct RGF_ICR, IMV), doff_io32},
-       {"IMS",           S_IWUSR, offsetof(struct RGF_ICR, IMS), doff_io32},
-       {"IMC",           S_IWUSR, offsetof(struct RGF_ICR, IMC), doff_io32},
+       {"ICC", 0644, offsetof(struct RGF_ICR, ICC), doff_io32},
+       {"ICR", 0644, offsetof(struct RGF_ICR, ICR), doff_io32},
+       {"ICM", 0644, offsetof(struct RGF_ICR, ICM), doff_io32},
+       {"ICS", 0244, offsetof(struct RGF_ICR, ICS), doff_io32},
+       {"IMV", 0644, offsetof(struct RGF_ICR, IMV), doff_io32},
+       {"IMS", 0244, offsetof(struct RGF_ICR, IMS), doff_io32},
+       {"IMC", 0244, offsetof(struct RGF_ICR, IMC), doff_io32},
        {},
 };
 
@@ -390,9 +390,9 @@ static int wil6210_debugfs_create_ISR(struct wil6210_priv *wil,
 }
 
 static const struct dbg_off pseudo_isr_off[] = {
-       {"CAUSE",   S_IRUGO, HOSTADDR(RGF_DMA_PSEUDO_CAUSE), doff_io32},
-       {"MASK_SW", S_IRUGO, HOSTADDR(RGF_DMA_PSEUDO_CAUSE_MASK_SW), doff_io32},
-       {"MASK_FW", S_IRUGO, HOSTADDR(RGF_DMA_PSEUDO_CAUSE_MASK_FW), doff_io32},
+       {"CAUSE",   0444, HOSTADDR(RGF_DMA_PSEUDO_CAUSE), doff_io32},
+       {"MASK_SW", 0444, HOSTADDR(RGF_DMA_PSEUDO_CAUSE_MASK_SW), doff_io32},
+       {"MASK_FW", 0444, HOSTADDR(RGF_DMA_PSEUDO_CAUSE_MASK_FW), doff_io32},
        {},
 };
 
@@ -411,40 +411,40 @@ static int wil6210_debugfs_create_pseudo_ISR(struct wil6210_priv *wil,
 }
 
 static const struct dbg_off lgc_itr_cnt_off[] = {
-       {"TRSH", S_IRUGO | S_IWUSR, HOSTADDR(RGF_DMA_ITR_CNT_TRSH), doff_io32},
-       {"DATA", S_IRUGO | S_IWUSR, HOSTADDR(RGF_DMA_ITR_CNT_DATA), doff_io32},
-       {"CTL",  S_IRUGO | S_IWUSR, HOSTADDR(RGF_DMA_ITR_CNT_CRL), doff_io32},
+       {"TRSH", 0644, HOSTADDR(RGF_DMA_ITR_CNT_TRSH), doff_io32},
+       {"DATA", 0644, HOSTADDR(RGF_DMA_ITR_CNT_DATA), doff_io32},
+       {"CTL",  0644, HOSTADDR(RGF_DMA_ITR_CNT_CRL), doff_io32},
        {},
 };
 
 static const struct dbg_off tx_itr_cnt_off[] = {
-       {"TRSH", S_IRUGO | S_IWUSR, HOSTADDR(RGF_DMA_ITR_TX_CNT_TRSH),
+       {"TRSH", 0644, HOSTADDR(RGF_DMA_ITR_TX_CNT_TRSH),
         doff_io32},
-       {"DATA", S_IRUGO | S_IWUSR, HOSTADDR(RGF_DMA_ITR_TX_CNT_DATA),
+       {"DATA", 0644, HOSTADDR(RGF_DMA_ITR_TX_CNT_DATA),
         doff_io32},
-       {"CTL",  S_IRUGO | S_IWUSR, HOSTADDR(RGF_DMA_ITR_TX_CNT_CTL),
+       {"CTL",  0644, HOSTADDR(RGF_DMA_ITR_TX_CNT_CTL),
         doff_io32},
-       {"IDL_TRSH", S_IRUGO | S_IWUSR, HOSTADDR(RGF_DMA_ITR_TX_IDL_CNT_TRSH),
+       {"IDL_TRSH", 0644, HOSTADDR(RGF_DMA_ITR_TX_IDL_CNT_TRSH),
         doff_io32},
-       {"IDL_DATA", S_IRUGO | S_IWUSR, HOSTADDR(RGF_DMA_ITR_TX_IDL_CNT_DATA),
+       {"IDL_DATA", 0644, HOSTADDR(RGF_DMA_ITR_TX_IDL_CNT_DATA),
         doff_io32},
-       {"IDL_CTL",  S_IRUGO | S_IWUSR, HOSTADDR(RGF_DMA_ITR_TX_IDL_CNT_CTL),
+       {"IDL_CTL",  0644, HOSTADDR(RGF_DMA_ITR_TX_IDL_CNT_CTL),
         doff_io32},
        {},
 };
 
 static const struct dbg_off rx_itr_cnt_off[] = {
-       {"TRSH", S_IRUGO | S_IWUSR, HOSTADDR(RGF_DMA_ITR_RX_CNT_TRSH),
+       {"TRSH", 0644, HOSTADDR(RGF_DMA_ITR_RX_CNT_TRSH),
         doff_io32},
-       {"DATA", S_IRUGO | S_IWUSR, HOSTADDR(RGF_DMA_ITR_RX_CNT_DATA),
+       {"DATA", 0644, HOSTADDR(RGF_DMA_ITR_RX_CNT_DATA),
         doff_io32},
-       {"CTL",  S_IRUGO | S_IWUSR, HOSTADDR(RGF_DMA_ITR_RX_CNT_CTL),
+       {"CTL",  0644, HOSTADDR(RGF_DMA_ITR_RX_CNT_CTL),
         doff_io32},
-       {"IDL_TRSH", S_IRUGO | S_IWUSR, HOSTADDR(RGF_DMA_ITR_RX_IDL_CNT_TRSH),
+       {"IDL_TRSH", 0644, HOSTADDR(RGF_DMA_ITR_RX_IDL_CNT_TRSH),
         doff_io32},
-       {"IDL_DATA", S_IRUGO | S_IWUSR, HOSTADDR(RGF_DMA_ITR_RX_IDL_CNT_DATA),
+       {"IDL_DATA", 0644, HOSTADDR(RGF_DMA_ITR_RX_IDL_CNT_DATA),
         doff_io32},
-       {"IDL_CTL",  S_IRUGO | S_IWUSR, HOSTADDR(RGF_DMA_ITR_RX_IDL_CNT_CTL),
+       {"IDL_CTL",  0644, HOSTADDR(RGF_DMA_ITR_RX_IDL_CNT_CTL),
         doff_io32},
        {},
 };
@@ -813,7 +813,7 @@ static ssize_t wil_write_file_txmgmt(struct file *file, const char __user *buf,
        rc = wil_cfg80211_mgmt_tx(wiphy, wdev, &params, NULL);
 
        kfree(frame);
-       wil_info(wil, "%s() -> %d\n", __func__, rc);
+       wil_info(wil, "-> %d\n", rc);
 
        return len;
 }
@@ -855,7 +855,7 @@ static ssize_t wil_write_file_wmi(struct file *file, const char __user *buf,
        rc1 = wmi_send(wil, cmdid, cmd, cmdlen);
        kfree(wmi);
 
-       wil_info(wil, "%s(0x%04x[%d]) -> %d\n", __func__, cmdid, cmdlen, rc1);
+       wil_info(wil, "0x%04x[%d] -> %d\n", cmdid, cmdlen, rc1);
 
        return rc;
 }
@@ -1379,6 +1379,7 @@ __acquires(&p->tid_rx_lock) __releases(&p->tid_rx_lock)
        for (i = 0; i < ARRAY_SIZE(wil->sta); i++) {
                struct wil_sta_info *p = &wil->sta[i];
                char *status = "unknown";
+               u8 aid = 0;
 
                switch (p->status) {
                case wil_sta_unused:
@@ -1389,9 +1390,10 @@ __acquires(&p->tid_rx_lock) __releases(&p->tid_rx_lock)
                        break;
                case wil_sta_connected:
                        status = "connected";
+                       aid = p->aid;
                        break;
                }
-               seq_printf(s, "[%d] %pM %s\n", i, p->addr, status);
+               seq_printf(s, "[%d] %pM %s AID %d\n", i, p->addr, status, aid);
 
                if (p->status == wil_sta_connected) {
                        spin_lock_bh(&p->tid_rx_lock);
@@ -1622,7 +1624,7 @@ static void wil6210_debugfs_init_blobs(struct wil6210_priv *wil,
                blob->data = (void * __force)wil->csr + HOSTADDR(map->host);
                blob->size = map->to - map->from;
                snprintf(name, sizeof(name), "blob_%s", map->name);
-               wil_debugfs_create_ioblob(name, S_IRUGO, dbg, wil_blob);
+               wil_debugfs_create_ioblob(name, 0444, dbg, wil_blob);
        }
 }
 
@@ -1632,29 +1634,29 @@ static const struct {
        umode_t mode;
        const struct file_operations *fops;
 } dbg_files[] = {
-       {"mbox",        S_IRUGO,                &fops_mbox},
-       {"vrings",      S_IRUGO,                &fops_vring},
-       {"stations",    S_IRUGO,                &fops_sta},
-       {"desc",        S_IRUGO,                &fops_txdesc},
-       {"bf",          S_IRUGO,                &fops_bf},
-       {"ssid",        S_IRUGO | S_IWUSR,      &fops_ssid},
-       {"mem_val",     S_IRUGO,                &fops_memread},
-       {"reset",                 S_IWUSR,      &fops_reset},
-       {"rxon",                  S_IWUSR,      &fops_rxon},
-       {"tx_mgmt",               S_IWUSR,      &fops_txmgmt},
-       {"wmi_send",              S_IWUSR,      &fops_wmi},
-       {"back",        S_IRUGO | S_IWUSR,      &fops_back},
-       {"pmccfg",      S_IRUGO | S_IWUSR,      &fops_pmccfg},
-       {"pmcdata",     S_IRUGO,                &fops_pmcdata},
-       {"temp",        S_IRUGO,                &fops_temp},
-       {"freq",        S_IRUGO,                &fops_freq},
-       {"link",        S_IRUGO,                &fops_link},
-       {"info",        S_IRUGO,                &fops_info},
-       {"recovery",    S_IRUGO | S_IWUSR,      &fops_recovery},
-       {"led_cfg",     S_IRUGO | S_IWUSR,      &fops_led_cfg},
-       {"led_blink_time",      S_IRUGO | S_IWUSR,      &fops_led_blink_time},
-       {"fw_capabilities",     S_IRUGO,        &fops_fw_capabilities},
-       {"fw_version",  S_IRUGO,                &fops_fw_version},
+       {"mbox",        0444,           &fops_mbox},
+       {"vrings",      0444,           &fops_vring},
+       {"stations", 0444,              &fops_sta},
+       {"desc",        0444,           &fops_txdesc},
+       {"bf",          0444,           &fops_bf},
+       {"ssid",        0644,           &fops_ssid},
+       {"mem_val",     0644,           &fops_memread},
+       {"reset",       0244,           &fops_reset},
+       {"rxon",        0244,           &fops_rxon},
+       {"tx_mgmt",     0244,           &fops_txmgmt},
+       {"wmi_send", 0244,              &fops_wmi},
+       {"back",        0644,           &fops_back},
+       {"pmccfg",      0644,           &fops_pmccfg},
+       {"pmcdata",     0444,           &fops_pmcdata},
+       {"temp",        0444,           &fops_temp},
+       {"freq",        0444,           &fops_freq},
+       {"link",        0444,           &fops_link},
+       {"info",        0444,           &fops_info},
+       {"recovery", 0644,              &fops_recovery},
+       {"led_cfg",     0644,           &fops_led_cfg},
+       {"led_blink_time",      0644,   &fops_led_blink_time},
+       {"fw_capabilities",     0444,   &fops_fw_capabilities},
+       {"fw_version",  0444,           &fops_fw_version},
 };
 
 static void wil6210_debugfs_init_files(struct wil6210_priv *wil,
@@ -1693,30 +1695,32 @@ static void wil6210_debugfs_init_isr(struct wil6210_priv *wil,
 
 /* fields in struct wil6210_priv */
 static const struct dbg_off dbg_wil_off[] = {
-       WIL_FIELD(privacy,      S_IRUGO,                doff_u32),
-       WIL_FIELD(status[0],    S_IRUGO | S_IWUSR,      doff_ulong),
-       WIL_FIELD(hw_version,   S_IRUGO,                doff_x32),
-       WIL_FIELD(recovery_count, S_IRUGO,              doff_u32),
-       WIL_FIELD(ap_isolate,   S_IRUGO,                doff_u32),
-       WIL_FIELD(discovery_mode, S_IRUGO | S_IWUSR,    doff_u8),
+       WIL_FIELD(privacy,      0444,           doff_u32),
+       WIL_FIELD(status[0],    0644,   doff_ulong),
+       WIL_FIELD(hw_version,   0444,   doff_x32),
+       WIL_FIELD(recovery_count, 0444, doff_u32),
+       WIL_FIELD(ap_isolate,   0444,   doff_u32),
+       WIL_FIELD(discovery_mode, 0644, doff_u8),
+       WIL_FIELD(chip_revision, 0444,  doff_u8),
+       WIL_FIELD(abft_len, 0644,               doff_u8),
        {},
 };
 
 static const struct dbg_off dbg_wil_regs[] = {
-       {"RGF_MAC_MTRL_COUNTER_0", S_IRUGO, HOSTADDR(RGF_MAC_MTRL_COUNTER_0),
+       {"RGF_MAC_MTRL_COUNTER_0", 0444, HOSTADDR(RGF_MAC_MTRL_COUNTER_0),
                doff_io32},
-       {"RGF_USER_USAGE_1", S_IRUGO, HOSTADDR(RGF_USER_USAGE_1), doff_io32},
+       {"RGF_USER_USAGE_1", 0444, HOSTADDR(RGF_USER_USAGE_1), doff_io32},
        {},
 };
 
 /* static parameters */
 static const struct dbg_off dbg_statics[] = {
-       {"desc_index",  S_IRUGO | S_IWUSR, (ulong)&dbg_txdesc_index, doff_u32},
-       {"vring_index", S_IRUGO | S_IWUSR, (ulong)&dbg_vring_index, doff_u32},
-       {"mem_addr",    S_IRUGO | S_IWUSR, (ulong)&mem_addr, doff_u32},
-       {"vring_idle_trsh", S_IRUGO | S_IWUSR, (ulong)&vring_idle_trsh,
+       {"desc_index",  0644, (ulong)&dbg_txdesc_index, doff_u32},
+       {"vring_index", 0644, (ulong)&dbg_vring_index, doff_u32},
+       {"mem_addr",    0644, (ulong)&mem_addr, doff_u32},
+       {"vring_idle_trsh", 0644, (ulong)&vring_idle_trsh,
         doff_u32},
-       {"led_polarity", S_IRUGO | S_IWUSR, (ulong)&led_polarity, doff_u8},
+       {"led_polarity", 0644, (ulong)&led_polarity, doff_u8},
        {},
 };
 
index 7053b62ca8d313ac593143bb4619ed13db252de7..adcfef4dabf756da33acd4d6bab05f09f9afdb7e 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2014 Qualcomm Atheros, Inc.
+ * Copyright (c) 2014,2017 Qualcomm Atheros, Inc.
  *
  * Permission to use, copy, modify, and/or distribute this software for any
  * purpose with or without fee is hereby granted, provided that the above
@@ -27,7 +27,7 @@ static int wil_ethtoolops_begin(struct net_device *ndev)
 
        mutex_lock(&wil->mutex);
 
-       wil_dbg_misc(wil, "%s()\n", __func__);
+       wil_dbg_misc(wil, "ethtoolops_begin\n");
 
        return 0;
 }
@@ -36,7 +36,7 @@ static void wil_ethtoolops_complete(struct net_device *ndev)
 {
        struct wil6210_priv *wil = ndev_to_wil(ndev);
 
-       wil_dbg_misc(wil, "%s()\n", __func__);
+       wil_dbg_misc(wil, "ethtoolops_complete\n");
 
        mutex_unlock(&wil->mutex);
 }
@@ -48,7 +48,7 @@ static int wil_ethtoolops_get_coalesce(struct net_device *ndev,
        u32 tx_itr_en, tx_itr_val = 0;
        u32 rx_itr_en, rx_itr_val = 0;
 
-       wil_dbg_misc(wil, "%s()\n", __func__);
+       wil_dbg_misc(wil, "ethtoolops_get_coalesce\n");
 
        tx_itr_en = wil_r(wil, RGF_DMA_ITR_TX_CNT_CTL);
        if (tx_itr_en & BIT_DMA_ITR_TX_CNT_CTL_EN)
@@ -68,7 +68,7 @@ static int wil_ethtoolops_set_coalesce(struct net_device *ndev,
 {
        struct wil6210_priv *wil = ndev_to_wil(ndev);
 
-       wil_dbg_misc(wil, "%s(rx %d usec, tx %d usec)\n", __func__,
+       wil_dbg_misc(wil, "ethtoolops_set_coalesce: rx %d usec, tx %d usec\n",
                     cp->rx_coalesce_usecs, cp->tx_coalesce_usecs);
 
        if (wil->wdev->iftype == NL80211_IFTYPE_MONITOR) {
index 82aae2d705b41803fee7b44ab174be875b159f96..540fc20984d8fe8c65ef56b074f47030da518084 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2014-2015 Qualcomm Atheros, Inc.
+ * Copyright (c) 2014-2015,2017 Qualcomm Atheros, Inc.
  *
  * Permission to use, copy, modify, and/or distribute this software for any
  * purpose with or without fee is hereby granted, provided that the above
@@ -19,8 +19,9 @@
 #include "wil6210.h"
 #include "fw.h"
 
-MODULE_FIRMWARE(WIL_FW_NAME);
-MODULE_FIRMWARE(WIL_FW2_NAME);
+MODULE_FIRMWARE(WIL_FW_NAME_DEFAULT);
+MODULE_FIRMWARE(WIL_FW_NAME_SPARROW_PLUS);
+MODULE_FIRMWARE(WIL_BOARD_FILE_NAME);
 
 static
 void wil_memset_toio_32(volatile void __iomem *dst, u32 val,
index 8f40eb301924b1b0100af4f09732c556236734dc..f4901587c0057a9fc749e29a4e5bd7f0ccc5b1f3 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2014-2016 Qualcomm Atheros, Inc.
+ * Copyright (c) 2014-2017 Qualcomm Atheros, Inc.
  *
  * Permission to use, copy, modify, and/or distribute this software for any
  * purpose with or without fee is hereby granted, provided that the above
@@ -537,3 +537,22 @@ out:
        release_firmware(fw);
        return rc;
 }
+
+/**
+ * wil_fw_verify_file_exists - checks if firmware file exist
+ *
+ * @wil: driver context
+ * @name: firmware file name
+ *
+ * return value - boolean, true for success, false for failure
+ */
+bool wil_fw_verify_file_exists(struct wil6210_priv *wil, const char *name)
+{
+       const struct firmware *fw;
+       int rc;
+
+       rc = request_firmware(&fw, name, wil_to_dev(wil));
+       if (!rc)
+               release_firmware(fw);
+       return rc != -ENOENT;
+}
index 64046e0bd0a228ae724da21aa4592a6cdd8dea4e..cab1e5c0e3747de4ee4c12fe30852d9631610b89 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2012-2016 Qualcomm Atheros, Inc.
+ * Copyright (c) 2012-2017 Qualcomm Atheros, Inc.
  *
  * Permission to use, copy, modify, and/or distribute this software for any
  * purpose with or without fee is hereby granted, provided that the above
@@ -94,7 +94,7 @@ static void wil6210_mask_irq_rx(struct wil6210_priv *wil)
 
 static void wil6210_mask_irq_misc(struct wil6210_priv *wil, bool mask_halp)
 {
-       wil_dbg_irq(wil, "%s: mask_halp(%s)\n", __func__,
+       wil_dbg_irq(wil, "mask_irq_misc: mask_halp(%s)\n",
                    mask_halp ? "true" : "false");
 
        wil_w(wil, RGF_DMA_EP_MISC_ICR + offsetof(struct RGF_ICR, IMS),
@@ -103,7 +103,7 @@ static void wil6210_mask_irq_misc(struct wil6210_priv *wil, bool mask_halp)
 
 void wil6210_mask_halp(struct wil6210_priv *wil)
 {
-       wil_dbg_irq(wil, "%s()\n", __func__);
+       wil_dbg_irq(wil, "mask_halp\n");
 
        wil_w(wil, RGF_DMA_EP_MISC_ICR + offsetof(struct RGF_ICR, IMS),
              BIT_DMA_EP_MISC_ICR_HALP);
@@ -111,7 +111,7 @@ void wil6210_mask_halp(struct wil6210_priv *wil)
 
 static void wil6210_mask_irq_pseudo(struct wil6210_priv *wil)
 {
-       wil_dbg_irq(wil, "%s()\n", __func__);
+       wil_dbg_irq(wil, "mask_irq_pseudo\n");
 
        wil_w(wil, RGF_DMA_PSEUDO_CAUSE_MASK_SW, WIL6210_IRQ_DISABLE);
 
@@ -134,7 +134,7 @@ void wil6210_unmask_irq_rx(struct wil6210_priv *wil)
 
 static void wil6210_unmask_irq_misc(struct wil6210_priv *wil, bool unmask_halp)
 {
-       wil_dbg_irq(wil, "%s: unmask_halp(%s)\n", __func__,
+       wil_dbg_irq(wil, "unmask_irq_misc: unmask_halp(%s)\n",
                    unmask_halp ? "true" : "false");
 
        wil_w(wil, RGF_DMA_EP_MISC_ICR + offsetof(struct RGF_ICR, IMC),
@@ -143,7 +143,7 @@ static void wil6210_unmask_irq_misc(struct wil6210_priv *wil, bool unmask_halp)
 
 static void wil6210_unmask_halp(struct wil6210_priv *wil)
 {
-       wil_dbg_irq(wil, "%s()\n", __func__);
+       wil_dbg_irq(wil, "unmask_halp\n");
 
        wil_w(wil, RGF_DMA_EP_MISC_ICR + offsetof(struct RGF_ICR, IMC),
              BIT_DMA_EP_MISC_ICR_HALP);
@@ -151,7 +151,7 @@ static void wil6210_unmask_halp(struct wil6210_priv *wil)
 
 static void wil6210_unmask_irq_pseudo(struct wil6210_priv *wil)
 {
-       wil_dbg_irq(wil, "%s()\n", __func__);
+       wil_dbg_irq(wil, "unmask_irq_pseudo\n");
 
        set_bit(wil_status_irqen, wil->status);
 
@@ -160,7 +160,7 @@ static void wil6210_unmask_irq_pseudo(struct wil6210_priv *wil)
 
 void wil_mask_irq(struct wil6210_priv *wil)
 {
-       wil_dbg_irq(wil, "%s()\n", __func__);
+       wil_dbg_irq(wil, "mask_irq\n");
 
        wil6210_mask_irq_tx(wil);
        wil6210_mask_irq_rx(wil);
@@ -170,7 +170,7 @@ void wil_mask_irq(struct wil6210_priv *wil)
 
 void wil_unmask_irq(struct wil6210_priv *wil)
 {
-       wil_dbg_irq(wil, "%s()\n", __func__);
+       wil_dbg_irq(wil, "unmask_irq\n");
 
        wil_w(wil, RGF_DMA_EP_RX_ICR + offsetof(struct RGF_ICR, ICC),
              WIL_ICR_ICC_VALUE);
@@ -187,7 +187,7 @@ void wil_unmask_irq(struct wil6210_priv *wil)
 
 void wil_configure_interrupt_moderation(struct wil6210_priv *wil)
 {
-       wil_dbg_irq(wil, "%s()\n", __func__);
+       wil_dbg_irq(wil, "configure_interrupt_moderation\n");
 
        /* disable interrupt moderation for monitor
         * to get better timestamp precision
@@ -400,7 +400,7 @@ static irqreturn_t wil6210_irq_misc(int irq, void *cookie)
        }
 
        if (isr & BIT_DMA_EP_MISC_ICR_HALP) {
-               wil_dbg_irq(wil, "%s: HALP IRQ invoked\n", __func__);
+               wil_dbg_irq(wil, "irq_misc: HALP IRQ invoked\n");
                wil6210_mask_halp(wil);
                isr &= ~BIT_DMA_EP_MISC_ICR_HALP;
                complete(&wil->halp.comp);
@@ -599,7 +599,7 @@ void wil6210_clear_irq(struct wil6210_priv *wil)
 
 void wil6210_set_halp(struct wil6210_priv *wil)
 {
-       wil_dbg_irq(wil, "%s()\n", __func__);
+       wil_dbg_irq(wil, "set_halp\n");
 
        wil_w(wil, RGF_DMA_EP_MISC_ICR + offsetof(struct RGF_ICR, ICS),
              BIT_DMA_EP_MISC_ICR_HALP);
@@ -607,7 +607,7 @@ void wil6210_set_halp(struct wil6210_priv *wil)
 
 void wil6210_clear_halp(struct wil6210_priv *wil)
 {
-       wil_dbg_irq(wil, "%s()\n", __func__);
+       wil_dbg_irq(wil, "clear_halp\n");
 
        wil_w(wil, RGF_DMA_EP_MISC_ICR + offsetof(struct RGF_ICR, ICR),
              BIT_DMA_EP_MISC_ICR_HALP);
@@ -618,7 +618,7 @@ int wil6210_init_irq(struct wil6210_priv *wil, int irq, bool use_msi)
 {
        int rc;
 
-       wil_dbg_misc(wil, "%s(%s)\n", __func__, use_msi ? "MSI" : "INTx");
+       wil_dbg_misc(wil, "init_irq: %s\n", use_msi ? "MSI" : "INTx");
 
        rc = request_threaded_irq(irq, wil6210_hardirq,
                                  wil6210_thread_irq,
@@ -629,7 +629,7 @@ int wil6210_init_irq(struct wil6210_priv *wil, int irq, bool use_msi)
 
 void wil6210_fini_irq(struct wil6210_priv *wil, int irq)
 {
-       wil_dbg_misc(wil, "%s()\n", __func__);
+       wil_dbg_misc(wil, "fini_irq:\n");
 
        wil_mask_irq(wil);
        free_irq(irq, wil);
index e2e021bcaa03d0020e0c7b966083df24a4989e1d..efb1f59aafd9956e5995eede2d606f202cc639ca 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2012-2016 Qualcomm Atheros, Inc.
+ * Copyright (c) 2012-2017 Qualcomm Atheros, Inc.
  *
  * Permission to use, copy, modify, and/or distribute this software for any
  * purpose with or without fee is hereby granted, provided that the above
 #define WAIT_FOR_SCAN_ABORT_MS 1000
 
 bool debug_fw; /* = false; */
-module_param(debug_fw, bool, S_IRUGO);
+module_param(debug_fw, bool, 0444);
 MODULE_PARM_DESC(debug_fw, " do not perform card reset. For FW debug");
 
 static bool oob_mode;
-module_param(oob_mode, bool, S_IRUGO);
+module_param(oob_mode, bool, 0444);
 MODULE_PARM_DESC(oob_mode,
                 " enable out of the box (OOB) mode in FW, for diagnostics and certification");
 
 bool no_fw_recovery;
-module_param(no_fw_recovery, bool, S_IRUGO | S_IWUSR);
+module_param(no_fw_recovery, bool, 0644);
 MODULE_PARM_DESC(no_fw_recovery, " disable automatic FW error recovery");
 
 /* if not set via modparam, will be set to default value of 1/8 of
  * rx ring size during init flow
  */
 unsigned short rx_ring_overflow_thrsh = WIL6210_RX_HIGH_TRSH_INIT;
-module_param(rx_ring_overflow_thrsh, ushort, S_IRUGO);
+module_param(rx_ring_overflow_thrsh, ushort, 0444);
 MODULE_PARM_DESC(rx_ring_overflow_thrsh,
                 " RX ring overflow threshold in descriptors.");
 
@@ -73,7 +73,7 @@ static const struct kernel_param_ops mtu_max_ops = {
        .get = param_get_uint,
 };
 
-module_param_cb(mtu_max, &mtu_max_ops, &mtu_max, S_IRUGO);
+module_param_cb(mtu_max, &mtu_max_ops, &mtu_max, 0444);
 MODULE_PARM_DESC(mtu_max, " Max MTU value.");
 
 static uint rx_ring_order = WIL_RX_RING_SIZE_ORDER_DEFAULT;
@@ -102,11 +102,11 @@ static const struct kernel_param_ops ring_order_ops = {
        .get = param_get_uint,
 };
 
-module_param_cb(rx_ring_order, &ring_order_ops, &rx_ring_order, S_IRUGO);
+module_param_cb(rx_ring_order, &ring_order_ops, &rx_ring_order, 0444);
 MODULE_PARM_DESC(rx_ring_order, " Rx ring order; size = 1 << order");
-module_param_cb(tx_ring_order, &ring_order_ops, &tx_ring_order, S_IRUGO);
+module_param_cb(tx_ring_order, &ring_order_ops, &tx_ring_order, 0444);
 MODULE_PARM_DESC(tx_ring_order, " Tx ring order; size = 1 << order");
-module_param_cb(bcast_ring_order, &ring_order_ops, &bcast_ring_order, S_IRUGO);
+module_param_cb(bcast_ring_order, &ring_order_ops, &bcast_ring_order, 0444);
 MODULE_PARM_DESC(bcast_ring_order, " Bcast ring order; size = 1 << order");
 
 #define RST_DELAY (20) /* msec, for loop in @wil_target_reset */
@@ -172,12 +172,16 @@ __acquires(&sta->tid_rx_lock) __releases(&sta->tid_rx_lock)
        struct wil_sta_info *sta = &wil->sta[cid];
 
        might_sleep();
-       wil_dbg_misc(wil, "%s(CID %d, status %d)\n", __func__, cid,
-                    sta->status);
+       wil_dbg_misc(wil, "disconnect_cid: CID %d, status %d\n",
+                    cid, sta->status);
        /* inform upper/lower layers */
        if (sta->status != wil_sta_unused) {
-               if (!from_event)
-                       wmi_disconnect_sta(wil, sta->addr, reason_code, true);
+               if (!from_event) {
+                       bool del_sta = (wdev->iftype == NL80211_IFTYPE_AP) ?
+                                               disable_ap_sme : false;
+                       wmi_disconnect_sta(wil, sta->addr, reason_code,
+                                          true, del_sta);
+               }
 
                switch (wdev->iftype) {
                case NL80211_IFTYPE_AP:
@@ -237,7 +241,7 @@ static void _wil6210_disconnect(struct wil6210_priv *wil, const u8 *bssid,
                return;
 
        might_sleep();
-       wil_info(wil, "%s(bssid=%pM, reason=%d, ev%s)\n", __func__, bssid,
+       wil_info(wil, "bssid=%pM, reason=%d, ev%s\n", bssid,
                 reason_code, from_event ? "+" : "-");
 
        /* Cases are:
@@ -347,7 +351,7 @@ static int wil_wait_for_recovery(struct wil6210_priv *wil)
 
 void wil_set_recovery_state(struct wil6210_priv *wil, int state)
 {
-       wil_dbg_misc(wil, "%s(%d -> %d)\n", __func__,
+       wil_dbg_misc(wil, "set_recovery_state: %d -> %d\n",
                     wil->recovery_state, state);
 
        wil->recovery_state = state;
@@ -489,7 +493,7 @@ int wil_priv_init(struct wil6210_priv *wil)
 {
        uint i;
 
-       wil_dbg_misc(wil, "%s()\n", __func__);
+       wil_dbg_misc(wil, "priv_init\n");
 
        memset(wil->sta, 0, sizeof(wil->sta));
        for (i = 0; i < WIL6210_MAX_CID; i++)
@@ -564,7 +568,7 @@ out_wmi_wq:
 void wil6210_disconnect(struct wil6210_priv *wil, const u8 *bssid,
                        u16 reason_code, bool from_event)
 {
-       wil_dbg_misc(wil, "%s()\n", __func__);
+       wil_dbg_misc(wil, "disconnect\n");
 
        del_timer_sync(&wil->connect_timer);
        _wil6210_disconnect(wil, bssid, reason_code, from_event);
@@ -572,7 +576,7 @@ void wil6210_disconnect(struct wil6210_priv *wil, const u8 *bssid,
 
 void wil_priv_deinit(struct wil6210_priv *wil)
 {
-       wil_dbg_misc(wil, "%s()\n", __func__);
+       wil_dbg_misc(wil, "priv_deinit\n");
 
        wil_set_recovery_state(wil, fw_recovery_idle);
        del_timer_sync(&wil->scan_timer);
@@ -605,7 +609,7 @@ static inline void wil_release_cpu(struct wil6210_priv *wil)
 
 static void wil_set_oob_mode(struct wil6210_priv *wil, bool enable)
 {
-       wil_info(wil, "%s: enable=%d\n", __func__, enable);
+       wil_info(wil, "enable=%d\n", enable);
        if (enable)
                wil_s(wil, RGF_USER_USAGE_6, BIT_USER_OOB_MODE);
        else
@@ -861,7 +865,7 @@ int wil_reset(struct wil6210_priv *wil, bool load_fw)
 {
        int rc;
 
-       wil_dbg_misc(wil, "%s()\n", __func__);
+       wil_dbg_misc(wil, "reset\n");
 
        WARN_ON(!mutex_is_locked(&wil->mutex));
        WARN_ON(test_bit(wil_status_napi_en, wil->status));
@@ -884,9 +888,8 @@ int wil_reset(struct wil6210_priv *wil, bool load_fw)
                rc = wil->platform_ops.notify(wil->platform_handle,
                                              WIL_PLATFORM_EVT_PRE_RESET);
                if (rc)
-                       wil_err(wil,
-                               "%s: PRE_RESET platform notify failed, rc %d\n",
-                               __func__, rc);
+                       wil_err(wil, "PRE_RESET platform notify failed, rc %d\n",
+                               rc);
        }
 
        set_bit(wil_status_resetting, wil->status);
@@ -915,7 +918,10 @@ int wil_reset(struct wil6210_priv *wil, bool load_fw)
        flush_workqueue(wil->wmi_wq);
 
        wil_bl_crash_info(wil, false);
+       wil_disable_irq(wil);
        rc = wil_target_reset(wil);
+       wil6210_clear_irq(wil);
+       wil_enable_irq(wil);
        wil_rx_fini(wil);
        if (rc) {
                wil_bl_crash_info(wil, true);
@@ -930,16 +936,16 @@ int wil_reset(struct wil6210_priv *wil, bool load_fw)
 
        wil_set_oob_mode(wil, oob_mode);
        if (load_fw) {
-               wil_info(wil, "Use firmware <%s> + board <%s>\n", WIL_FW_NAME,
-                        WIL_FW2_NAME);
+               wil_info(wil, "Use firmware <%s> + board <%s>\n",
+                        wil->wil_fw_name, WIL_BOARD_FILE_NAME);
 
                wil_halt_cpu(wil);
                memset(wil->fw_version, 0, sizeof(wil->fw_version));
                /* Loading f/w from the file */
-               rc = wil_request_firmware(wil, WIL_FW_NAME, true);
+               rc = wil_request_firmware(wil, wil->wil_fw_name, true);
                if (rc)
                        return rc;
-               rc = wil_request_firmware(wil, WIL_FW2_NAME, true);
+               rc = wil_request_firmware(wil, WIL_BOARD_FILE_NAME, true);
                if (rc)
                        return rc;
 
@@ -976,8 +982,7 @@ int wil_reset(struct wil6210_priv *wil, bool load_fw)
                /* check FW is responsive */
                rc = wmi_echo(wil);
                if (rc) {
-                       wil_err(wil, "%s: wmi_echo failed, rc %d\n",
-                               __func__, rc);
+                       wil_err(wil, "wmi_echo failed, rc %d\n", rc);
                        return rc;
                }
 
@@ -987,9 +992,8 @@ int wil_reset(struct wil6210_priv *wil, bool load_fw)
                        rc = wil->platform_ops.notify(wil->platform_handle,
                                                      WIL_PLATFORM_EVT_FW_RDY);
                        if (rc) {
-                               wil_err(wil,
-                                       "%s: FW_RDY notify failed, rc %d\n",
-                                       __func__, rc);
+                               wil_err(wil, "FW_RDY notify failed, rc %d\n",
+                                       rc);
                                rc = 0;
                        }
                }
@@ -1073,7 +1077,7 @@ int wil_up(struct wil6210_priv *wil)
 {
        int rc;
 
-       wil_dbg_misc(wil, "%s()\n", __func__);
+       wil_dbg_misc(wil, "up\n");
 
        mutex_lock(&wil->mutex);
        rc = __wil_up(wil);
@@ -1113,7 +1117,7 @@ int wil_down(struct wil6210_priv *wil)
 {
        int rc;
 
-       wil_dbg_misc(wil, "%s()\n", __func__);
+       wil_dbg_misc(wil, "down\n");
 
        wil_set_recovery_state(wil, fw_recovery_idle);
        mutex_lock(&wil->mutex);
@@ -1146,25 +1150,24 @@ void wil_halp_vote(struct wil6210_priv *wil)
 
        mutex_lock(&wil->halp.lock);
 
-       wil_dbg_irq(wil, "%s: start, HALP ref_cnt (%d)\n", __func__,
+       wil_dbg_irq(wil, "halp_vote: start, HALP ref_cnt (%d)\n",
                    wil->halp.ref_cnt);
 
        if (++wil->halp.ref_cnt == 1) {
                wil6210_set_halp(wil);
                rc = wait_for_completion_timeout(&wil->halp.comp, to_jiffies);
                if (!rc) {
-                       wil_err(wil, "%s: HALP vote timed out\n", __func__);
+                       wil_err(wil, "HALP vote timed out\n");
                        /* Mask HALP as done in case the interrupt is raised */
                        wil6210_mask_halp(wil);
                } else {
                        wil_dbg_irq(wil,
-                                   "%s: HALP vote completed after %d ms\n",
-                                   __func__,
+                                   "halp_vote: HALP vote completed after %d ms\n",
                                    jiffies_to_msecs(to_jiffies - rc));
                }
        }
 
-       wil_dbg_irq(wil, "%s: end, HALP ref_cnt (%d)\n", __func__,
+       wil_dbg_irq(wil, "halp_vote: end, HALP ref_cnt (%d)\n",
                    wil->halp.ref_cnt);
 
        mutex_unlock(&wil->halp.lock);
@@ -1176,15 +1179,15 @@ void wil_halp_unvote(struct wil6210_priv *wil)
 
        mutex_lock(&wil->halp.lock);
 
-       wil_dbg_irq(wil, "%s: start, HALP ref_cnt (%d)\n", __func__,
+       wil_dbg_irq(wil, "halp_unvote: start, HALP ref_cnt (%d)\n",
                    wil->halp.ref_cnt);
 
        if (--wil->halp.ref_cnt == 0) {
                wil6210_clear_halp(wil);
-               wil_dbg_irq(wil, "%s: HALP unvote\n", __func__);
+               wil_dbg_irq(wil, "HALP unvote\n");
        }
 
-       wil_dbg_irq(wil, "%s: end, HALP ref_cnt (%d)\n", __func__,
+       wil_dbg_irq(wil, "halp_unvote:end, HALP ref_cnt (%d)\n",
                    wil->halp.ref_cnt);
 
        mutex_unlock(&wil->halp.lock);
index cab5334e4f9d46a6394181988a69c25183c6412b..708facd5f667d991127dc189e229b36d387891f5 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2012-2016 Qualcomm Atheros, Inc.
+ * Copyright (c) 2012-2017 Qualcomm Atheros, Inc.
  *
  * Permission to use, copy, modify, and/or distribute this software for any
  * purpose with or without fee is hereby granted, provided that the above
@@ -22,10 +22,11 @@ static int wil_open(struct net_device *ndev)
 {
        struct wil6210_priv *wil = ndev_to_wil(ndev);
 
-       wil_dbg_misc(wil, "%s()\n", __func__);
+       wil_dbg_misc(wil, "open\n");
 
-       if (debug_fw) {
-               wil_err(wil, "%s() while in debug_fw mode\n", __func__);
+       if (debug_fw ||
+           test_bit(WMI_FW_CAPABILITY_WMI_ONLY, wil->fw_capabilities)) {
+               wil_err(wil, "while in debug_fw or wmi_only mode\n");
                return -EINVAL;
        }
 
@@ -36,7 +37,7 @@ static int wil_stop(struct net_device *ndev)
 {
        struct wil6210_priv *wil = ndev_to_wil(ndev);
 
-       wil_dbg_misc(wil, "%s()\n", __func__);
+       wil_dbg_misc(wil, "stop\n");
 
        return wil_down(wil);
 }
@@ -132,7 +133,7 @@ void *wil_if_alloc(struct device *dev)
        wil->wdev = wdev;
        wil->radio_wdev = wdev;
 
-       wil_dbg_misc(wil, "%s()\n", __func__);
+       wil_dbg_misc(wil, "if_alloc\n");
 
        rc = wil_priv_init(wil);
        if (rc) {
@@ -179,7 +180,7 @@ void wil_if_free(struct wil6210_priv *wil)
 {
        struct net_device *ndev = wil_to_ndev(wil);
 
-       wil_dbg_misc(wil, "%s()\n", __func__);
+       wil_dbg_misc(wil, "if_free\n");
 
        if (!ndev)
                return;
@@ -234,7 +235,7 @@ void wil_if_remove(struct wil6210_priv *wil)
        struct net_device *ndev = wil_to_ndev(wil);
        struct wireless_dev *wdev = wil_to_wdev(wil);
 
-       wil_dbg_misc(wil, "%s()\n", __func__);
+       wil_dbg_misc(wil, "if_remove\n");
 
        unregister_netdev(ndev);
        wiphy_unregister(wdev->wiphy);
index fbae99525e0104498e2ed1c89d0fb1b4021093d3..792484756654bcd5e27b831409411f2840c5bd8e 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2014-2016 Qualcomm Atheros, Inc.
+ * Copyright (c) 2014-2017 Qualcomm Atheros, Inc.
  *
  * Permission to use, copy, modify, and/or distribute this software for any
  * purpose with or without fee is hereby granted, provided that the above
@@ -69,7 +69,7 @@ void wil_p2p_discovery_timer_fn(ulong x)
 {
        struct wil6210_priv *wil = (void *)x;
 
-       wil_dbg_misc(wil, "%s\n", __func__);
+       wil_dbg_misc(wil, "p2p_discovery_timer_fn\n");
 
        schedule_work(&wil->p2p.discovery_expired_work);
 }
@@ -80,27 +80,25 @@ int wil_p2p_search(struct wil6210_priv *wil,
        int rc;
        struct wil_p2p_info *p2p = &wil->p2p;
 
-       wil_dbg_misc(wil, "%s: channel %d\n",
-                    __func__, P2P_DMG_SOCIAL_CHANNEL);
+       wil_dbg_misc(wil, "p2p_search: channel %d\n", P2P_DMG_SOCIAL_CHANNEL);
 
        lockdep_assert_held(&wil->mutex);
 
        if (p2p->discovery_started) {
-               wil_err(wil, "%s: search failed. discovery already ongoing\n",
-                       __func__);
+               wil_err(wil, "search failed. discovery already ongoing\n");
                rc = -EBUSY;
                goto out;
        }
 
        rc = wmi_p2p_cfg(wil, P2P_DMG_SOCIAL_CHANNEL, P2P_DEFAULT_BI);
        if (rc) {
-               wil_err(wil, "%s: wmi_p2p_cfg failed\n", __func__);
+               wil_err(wil, "wmi_p2p_cfg failed\n");
                goto out;
        }
 
        rc = wmi_set_ssid(wil, strlen(P2P_WILDCARD_SSID), P2P_WILDCARD_SSID);
        if (rc) {
-               wil_err(wil, "%s: wmi_set_ssid failed\n", __func__);
+               wil_err(wil, "wmi_set_ssid failed\n");
                goto out_stop;
        }
 
@@ -108,8 +106,7 @@ int wil_p2p_search(struct wil6210_priv *wil,
        rc = wmi_set_ie(wil, WMI_FRAME_PROBE_REQ,
                        request->ie_len, request->ie);
        if (rc) {
-               wil_err(wil, "%s: wmi_set_ie(WMI_FRAME_PROBE_REQ) failed\n",
-                       __func__);
+               wil_err(wil, "wmi_set_ie(WMI_FRAME_PROBE_REQ) failed\n");
                goto out_stop;
        }
 
@@ -119,14 +116,13 @@ int wil_p2p_search(struct wil6210_priv *wil,
        rc = wmi_set_ie(wil, WMI_FRAME_PROBE_RESP,
                        request->ie_len, request->ie);
        if (rc) {
-               wil_err(wil, "%s: wmi_set_ie(WMI_FRAME_PROBE_RESP) failed\n",
-                       __func__);
+               wil_err(wil, "wmi_set_ie(WMI_FRAME_PROBE_RESP) failed\n");
                goto out_stop;
        }
 
        rc = wmi_start_search(wil);
        if (rc) {
-               wil_err(wil, "%s: wmi_start_search failed\n", __func__);
+               wil_err(wil, "wmi_start_search failed\n");
                goto out_stop;
        }
 
@@ -153,12 +149,12 @@ int wil_p2p_listen(struct wil6210_priv *wil, struct wireless_dev *wdev,
        if (!chan)
                return -EINVAL;
 
-       wil_dbg_misc(wil, "%s: duration %d\n", __func__, duration);
+       wil_dbg_misc(wil, "p2p_listen: duration %d\n", duration);
 
        mutex_lock(&wil->mutex);
 
        if (p2p->discovery_started) {
-               wil_err(wil, "%s: discovery already ongoing\n", __func__);
+               wil_err(wil, "discovery already ongoing\n");
                rc = -EBUSY;
                goto out;
        }
@@ -220,8 +216,8 @@ int wil_p2p_cancel_listen(struct wil6210_priv *wil, u64 cookie)
        mutex_lock(&wil->mutex);
 
        if (cookie != p2p->cookie) {
-               wil_info(wil, "%s: Cookie mismatch: 0x%016llx vs. 0x%016llx\n",
-                        __func__, p2p->cookie, cookie);
+               wil_info(wil, "Cookie mismatch: 0x%016llx vs. 0x%016llx\n",
+                        p2p->cookie, cookie);
                mutex_unlock(&wil->mutex);
                return -ENOENT;
        }
@@ -231,7 +227,7 @@ int wil_p2p_cancel_listen(struct wil6210_priv *wil, u64 cookie)
        mutex_unlock(&wil->mutex);
 
        if (!started) {
-               wil_err(wil, "%s: listen not started\n", __func__);
+               wil_err(wil, "listen not started\n");
                return -ENOENT;
        }
 
@@ -253,7 +249,7 @@ void wil_p2p_listen_expired(struct work_struct *work)
                        struct wil6210_priv, p2p);
        u8 started;
 
-       wil_dbg_misc(wil, "%s()\n", __func__);
+       wil_dbg_misc(wil, "p2p_listen_expired\n");
 
        mutex_lock(&wil->mutex);
        started = wil_p2p_stop_discovery(wil);
@@ -279,7 +275,7 @@ void wil_p2p_search_expired(struct work_struct *work)
                        struct wil6210_priv, p2p);
        u8 started;
 
-       wil_dbg_misc(wil, "%s()\n", __func__);
+       wil_dbg_misc(wil, "p2p_search_expired\n");
 
        mutex_lock(&wil->mutex);
        started = wil_p2p_stop_discovery(wil);
index 44746ca0d2e6ae86a3581c32d055bfb57586ca9b..874c787727fe5a013acfc558a7804679ee5aa39e 100644 (file)
@@ -23,7 +23,7 @@
 #include <linux/rtnetlink.h>
 
 static bool use_msi = true;
-module_param(use_msi, bool, S_IRUGO);
+module_param(use_msi, bool, 0444);
 MODULE_PARM_DESC(use_msi, " Use MSI interrupt, default - true");
 
 #ifdef CONFIG_PM
@@ -36,18 +36,38 @@ static int wil6210_pm_notify(struct notifier_block *notify_block,
 static
 void wil_set_capabilities(struct wil6210_priv *wil)
 {
-       u32 rev_id = wil_r(wil, RGF_USER_JTAG_DEV_ID);
+       u32 jtag_id = wil_r(wil, RGF_USER_JTAG_DEV_ID);
+       u8 chip_revision = (wil_r(wil, RGF_USER_REVISION_ID) &
+                           RGF_USER_REVISION_ID_MASK);
 
        bitmap_zero(wil->hw_capabilities, hw_capability_last);
        bitmap_zero(wil->fw_capabilities, WMI_FW_CAPABILITY_MAX);
-
-       switch (rev_id) {
-       case JTAG_DEV_ID_SPARROW_B0:
-               wil->hw_name = "Sparrow B0";
-               wil->hw_version = HW_VER_SPARROW_B0;
+       wil->wil_fw_name = WIL_FW_NAME_DEFAULT;
+       wil->chip_revision = chip_revision;
+
+       switch (jtag_id) {
+       case JTAG_DEV_ID_SPARROW:
+               switch (chip_revision) {
+               case REVISION_ID_SPARROW_D0:
+                       wil->hw_name = "Sparrow D0";
+                       wil->hw_version = HW_VER_SPARROW_D0;
+                       if (wil_fw_verify_file_exists(wil,
+                                                     WIL_FW_NAME_SPARROW_PLUS))
+                               wil->wil_fw_name = WIL_FW_NAME_SPARROW_PLUS;
+                       break;
+               case REVISION_ID_SPARROW_B0:
+                       wil->hw_name = "Sparrow B0";
+                       wil->hw_version = HW_VER_SPARROW_B0;
+                       break;
+               default:
+                       wil->hw_name = "Unknown";
+                       wil->hw_version = HW_VER_UNKNOWN;
+                       break;
+               }
                break;
        default:
-               wil_err(wil, "Unknown board hardware 0x%08x\n", rev_id);
+               wil_err(wil, "Unknown board hardware, chip_id 0x%08x, chip_revision 0x%08x\n",
+                       jtag_id, chip_revision);
                wil->hw_name = "Unknown";
                wil->hw_version = HW_VER_UNKNOWN;
        }
@@ -55,7 +75,7 @@ void wil_set_capabilities(struct wil6210_priv *wil)
        wil_info(wil, "Board hardware is %s\n", wil->hw_name);
 
        /* extract FW capabilities from file without loading the FW */
-       wil_request_firmware(wil, WIL_FW_NAME, false);
+       wil_request_firmware(wil, wil->wil_fw_name, false);
 }
 
 void wil_disable_irq(struct wil6210_priv *wil)
@@ -79,8 +99,10 @@ static int wil_if_pcie_enable(struct wil6210_priv *wil)
         */
        int msi_only = pdev->msi_enabled;
        bool _use_msi = use_msi;
+       bool wmi_only = test_bit(WMI_FW_CAPABILITY_WMI_ONLY,
+                                wil->fw_capabilities);
 
-       wil_dbg_misc(wil, "%s()\n", __func__);
+       wil_dbg_misc(wil, "if_pcie_enable, wmi_only %d\n", wmi_only);
 
        pdev->msi_enabled = 0;
 
@@ -103,9 +125,11 @@ static int wil_if_pcie_enable(struct wil6210_priv *wil)
        if (rc)
                goto stop_master;
 
-       /* need reset here to obtain MAC */
+       /* need reset here to obtain MAC or in case of WMI-only FW, full reset
+        * and fw loading takes place
+        */
        mutex_lock(&wil->mutex);
-       rc = wil_reset(wil, false);
+       rc = wil_reset(wil, wmi_only);
        mutex_unlock(&wil->mutex);
        if (rc)
                goto release_irq;
@@ -125,7 +149,7 @@ static int wil_if_pcie_disable(struct wil6210_priv *wil)
 {
        struct pci_dev *pdev = wil->pdev;
 
-       wil_dbg_misc(wil, "%s()\n", __func__);
+       wil_dbg_misc(wil, "if_pcie_disable\n");
 
        pci_clear_master(pdev);
        /* disable and release IRQ */
@@ -289,7 +313,7 @@ static void wil_pcie_remove(struct pci_dev *pdev)
        struct wil6210_priv *wil = pci_get_drvdata(pdev);
        void __iomem *csr = wil->csr;
 
-       wil_dbg_misc(wil, "%s()\n", __func__);
+       wil_dbg_misc(wil, "pcie_remove\n");
 
 #ifdef CONFIG_PM
 #ifdef CONFIG_PM_SLEEP
@@ -327,8 +351,7 @@ static int wil6210_suspend(struct device *dev, bool is_runtime)
        struct pci_dev *pdev = to_pci_dev(dev);
        struct wil6210_priv *wil = pci_get_drvdata(pdev);
 
-       wil_dbg_pm(wil, "%s(%s)\n", __func__,
-                  is_runtime ? "runtime" : "system");
+       wil_dbg_pm(wil, "suspend: %s\n", is_runtime ? "runtime" : "system");
 
        rc = wil_can_suspend(wil, is_runtime);
        if (rc)
@@ -354,8 +377,7 @@ static int wil6210_resume(struct device *dev, bool is_runtime)
        struct pci_dev *pdev = to_pci_dev(dev);
        struct wil6210_priv *wil = pci_get_drvdata(pdev);
 
-       wil_dbg_pm(wil, "%s(%s)\n", __func__,
-                  is_runtime ? "runtime" : "system");
+       wil_dbg_pm(wil, "resume: %s\n", is_runtime ? "runtime" : "system");
 
        /* allow master */
        pci_set_master(pdev);
@@ -375,7 +397,7 @@ static int wil6210_pm_notify(struct notifier_block *notify_block,
        int rc = 0;
        enum wil_platform_event evt;
 
-       wil_dbg_pm(wil, "%s: mode (%ld)\n", __func__, mode);
+       wil_dbg_pm(wil, "pm_notify: mode (%ld)\n", mode);
 
        switch (mode) {
        case PM_HIBERNATION_PREPARE:
index 11ee24d509e53f058cad2f7cbc1ebbf4b7f94db8..a0acb2d0cb7933e21f62c98d6b96a80cb51f9ef7 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2014,2016 Qualcomm Atheros, Inc.
+ * Copyright (c) 2014,2017 Qualcomm Atheros, Inc.
  *
  * Permission to use, copy, modify, and/or distribute this software for any
  * purpose with or without fee is hereby granted, provided that the above
@@ -21,8 +21,7 @@ int wil_can_suspend(struct wil6210_priv *wil, bool is_runtime)
        int rc = 0;
        struct wireless_dev *wdev = wil->wdev;
 
-       wil_dbg_pm(wil, "%s(%s)\n", __func__,
-                  is_runtime ? "runtime" : "system");
+       wil_dbg_pm(wil, "can_suspend: %s\n", is_runtime ? "runtime" : "system");
 
        if (!netif_running(wil_to_ndev(wil))) {
                /* can always sleep when down */
@@ -59,7 +58,7 @@ int wil_can_suspend(struct wil6210_priv *wil, bool is_runtime)
        }
 
 out:
-       wil_dbg_pm(wil, "%s(%s) => %s (%d)\n", __func__,
+       wil_dbg_pm(wil, "can_suspend: %s => %s (%d)\n",
                   is_runtime ? "runtime" : "system", rc ? "No" : "Yes", rc);
 
        return rc;
@@ -70,8 +69,7 @@ int wil_suspend(struct wil6210_priv *wil, bool is_runtime)
        int rc = 0;
        struct net_device *ndev = wil_to_ndev(wil);
 
-       wil_dbg_pm(wil, "%s(%s)\n", __func__,
-                  is_runtime ? "runtime" : "system");
+       wil_dbg_pm(wil, "suspend: %s\n", is_runtime ? "runtime" : "system");
 
        /* if netif up, hardware is alive, shut it down */
        if (ndev->flags & IFF_UP) {
@@ -86,7 +84,7 @@ int wil_suspend(struct wil6210_priv *wil, bool is_runtime)
                rc = wil->platform_ops.suspend(wil->platform_handle);
 
 out:
-       wil_dbg_pm(wil, "%s(%s) => %d\n", __func__,
+       wil_dbg_pm(wil, "suspend: %s => %d\n",
                   is_runtime ? "runtime" : "system", rc);
        return rc;
 }
@@ -96,8 +94,7 @@ int wil_resume(struct wil6210_priv *wil, bool is_runtime)
        int rc = 0;
        struct net_device *ndev = wil_to_ndev(wil);
 
-       wil_dbg_pm(wil, "%s(%s)\n", __func__,
-                  is_runtime ? "runtime" : "system");
+       wil_dbg_pm(wil, "resume: %s\n", is_runtime ? "runtime" : "system");
 
        if (wil->platform_ops.resume) {
                rc = wil->platform_ops.resume(wil->platform_handle);
@@ -115,7 +112,7 @@ int wil_resume(struct wil6210_priv *wil, bool is_runtime)
                rc = wil_up(wil);
 
 out:
-       wil_dbg_pm(wil, "%s(%s) => %d\n", __func__,
+       wil_dbg_pm(wil, "resume: %s => %d\n",
                   is_runtime ? "runtime" : "system", rc);
        return rc;
 }
index b9faae0278c9b33d85a4666bc94e847f3672dd26..3ff4f4ce9feffe24c46754c258c3deb811e69056 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2012-2015 Qualcomm Atheros, Inc.
+ * Copyright (c) 2012-2015,2017 Qualcomm Atheros, Inc.
  *
  * Permission to use, copy, modify, and/or distribute this software for any
  * purpose with or without fee is hereby granted, provided that the above
@@ -60,7 +60,7 @@ void wil_pmc_alloc(struct wil6210_priv *wil,
 
        if (wil_is_pmc_allocated(pmc)) {
                /* sanity check */
-               wil_err(wil, "%s: ERROR pmc is already allocated\n", __func__);
+               wil_err(wil, "ERROR pmc is already allocated\n");
                goto no_release_err;
        }
        if ((num_descriptors <= 0) || (descriptor_size <= 0)) {
@@ -90,21 +90,20 @@ void wil_pmc_alloc(struct wil6210_priv *wil,
        pmc->num_descriptors = num_descriptors;
        pmc->descriptor_size = descriptor_size;
 
-       wil_dbg_misc(wil, "%s: %d descriptors x %d bytes each\n",
-                    __func__, num_descriptors, descriptor_size);
+       wil_dbg_misc(wil, "pmc_alloc: %d descriptors x %d bytes each\n",
+                    num_descriptors, descriptor_size);
 
        /* allocate descriptors info list in pmc context*/
        pmc->descriptors = kcalloc(num_descriptors,
                                  sizeof(struct desc_alloc_info),
                                  GFP_KERNEL);
        if (!pmc->descriptors) {
-               wil_err(wil, "%s: ERROR allocating pmc skb list\n", __func__);
+               wil_err(wil, "ERROR allocating pmc skb list\n");
                goto no_release_err;
        }
 
-       wil_dbg_misc(wil,
-                    "%s: allocated descriptors info list %p\n",
-                    __func__, pmc->descriptors);
+       wil_dbg_misc(wil, "pmc_alloc: allocated descriptors info list %p\n",
+                    pmc->descriptors);
 
        /* Allocate pring buffer and descriptors.
         * vring->va should be aligned on its size rounded up to power of 2
@@ -116,15 +115,14 @@ void wil_pmc_alloc(struct wil6210_priv *wil,
                        GFP_KERNEL);
 
        wil_dbg_misc(wil,
-                    "%s: allocated pring %p => %pad. %zd x %d = total %zd bytes\n",
-                    __func__,
+                    "pmc_alloc: allocated pring %p => %pad. %zd x %d = total %zd bytes\n",
                     pmc->pring_va, &pmc->pring_pa,
                     sizeof(struct vring_tx_desc),
                     num_descriptors,
                     sizeof(struct vring_tx_desc) * num_descriptors);
 
        if (!pmc->pring_va) {
-               wil_err(wil, "%s: ERROR allocating pmc pring\n", __func__);
+               wil_err(wil, "ERROR allocating pmc pring\n");
                goto release_pmc_skb_list;
        }
 
@@ -143,9 +141,7 @@ void wil_pmc_alloc(struct wil6210_priv *wil,
                        GFP_KERNEL);
 
                if (unlikely(!pmc->descriptors[i].va)) {
-                       wil_err(wil,
-                               "%s: ERROR allocating pmc descriptor %d",
-                               __func__, i);
+                       wil_err(wil, "ERROR allocating pmc descriptor %d", i);
                        goto release_pmc_skbs;
                }
 
@@ -165,21 +161,21 @@ void wil_pmc_alloc(struct wil6210_priv *wil,
                *_d = *d;
        }
 
-       wil_dbg_misc(wil, "%s: allocated successfully\n", __func__);
+       wil_dbg_misc(wil, "pmc_alloc: allocated successfully\n");
 
        pmc_cmd.op = WMI_PMC_ALLOCATE;
        pmc_cmd.ring_size = cpu_to_le16(pmc->num_descriptors);
        pmc_cmd.mem_base = cpu_to_le64(pmc->pring_pa);
 
-       wil_dbg_misc(wil, "%s: send WMI_PMC_CMD with ALLOCATE op\n", __func__);
+       wil_dbg_misc(wil, "pmc_alloc: send WMI_PMC_CMD with ALLOCATE op\n");
        pmc->last_cmd_status = wmi_send(wil,
                                        WMI_PMC_CMDID,
                                        &pmc_cmd,
                                        sizeof(pmc_cmd));
        if (pmc->last_cmd_status) {
                wil_err(wil,
-                       "%s: WMI_PMC_CMD with ALLOCATE op failed with status %d",
-                       __func__, pmc->last_cmd_status);
+                       "WMI_PMC_CMD with ALLOCATE op failed with status %d",
+                       pmc->last_cmd_status);
                goto release_pmc_skbs;
        }
 
@@ -188,7 +184,7 @@ void wil_pmc_alloc(struct wil6210_priv *wil,
        return;
 
 release_pmc_skbs:
-       wil_err(wil, "%s: exit on error: Releasing skbs...\n", __func__);
+       wil_err(wil, "exit on error: Releasing skbs...\n");
        for (i = 0; pmc->descriptors[i].va && i < num_descriptors; i++) {
                dma_free_coherent(dev,
                                  descriptor_size,
@@ -197,7 +193,7 @@ release_pmc_skbs:
 
                pmc->descriptors[i].va = NULL;
        }
-       wil_err(wil, "%s: exit on error: Releasing pring...\n", __func__);
+       wil_err(wil, "exit on error: Releasing pring...\n");
 
        dma_free_coherent(dev,
                          sizeof(struct vring_tx_desc) * num_descriptors,
@@ -207,8 +203,7 @@ release_pmc_skbs:
        pmc->pring_va = NULL;
 
 release_pmc_skb_list:
-       wil_err(wil, "%s: exit on error: Releasing descriptors info list...\n",
-               __func__);
+       wil_err(wil, "exit on error: Releasing descriptors info list...\n");
        kfree(pmc->descriptors);
        pmc->descriptors = NULL;
 
@@ -232,24 +227,23 @@ void wil_pmc_free(struct wil6210_priv *wil, int send_pmc_cmd)
        pmc->last_cmd_status = 0;
 
        if (!wil_is_pmc_allocated(pmc)) {
-               wil_dbg_misc(wil, "%s: Error, can't free - not allocated\n",
-                            __func__);
+               wil_dbg_misc(wil,
+                            "pmc_free: Error, can't free - not allocated\n");
                pmc->last_cmd_status = -EPERM;
                mutex_unlock(&pmc->lock);
                return;
        }
 
        if (send_pmc_cmd) {
-               wil_dbg_misc(wil, "%s: send WMI_PMC_CMD with RELEASE op\n",
-                            __func__);
+               wil_dbg_misc(wil, "send WMI_PMC_CMD with RELEASE op\n");
                pmc_cmd.op = WMI_PMC_RELEASE;
                pmc->last_cmd_status =
                                wmi_send(wil, WMI_PMC_CMDID, &pmc_cmd,
                                         sizeof(pmc_cmd));
                if (pmc->last_cmd_status) {
                        wil_err(wil,
-                               "%s WMI_PMC_CMD with RELEASE op failed, status %d",
-                               __func__, pmc->last_cmd_status);
+                               "WMI_PMC_CMD with RELEASE op failed, status %d",
+                               pmc->last_cmd_status);
                        /* There's nothing we can do with this error.
                         * Normally, it should never occur.
                         * Continue to freeing all memory allocated for pmc.
@@ -261,8 +255,8 @@ void wil_pmc_free(struct wil6210_priv *wil, int send_pmc_cmd)
                size_t buf_size = sizeof(struct vring_tx_desc) *
                                  pmc->num_descriptors;
 
-               wil_dbg_misc(wil, "%s: free pring va %p\n",
-                            __func__, pmc->pring_va);
+               wil_dbg_misc(wil, "pmc_free: free pring va %p\n",
+                            pmc->pring_va);
                dma_free_coherent(dev, buf_size, pmc->pring_va, pmc->pring_pa);
 
                pmc->pring_va = NULL;
@@ -281,11 +275,11 @@ void wil_pmc_free(struct wil6210_priv *wil, int send_pmc_cmd)
                                          pmc->descriptors[i].pa);
                        pmc->descriptors[i].va = NULL;
                }
-               wil_dbg_misc(wil, "%s: free descriptor info %d/%d\n",
-                            __func__, i, pmc->num_descriptors);
+               wil_dbg_misc(wil, "pmc_free: free descriptor info %d/%d\n", i,
+                            pmc->num_descriptors);
                wil_dbg_misc(wil,
-                            "%s: free pmc descriptors info list %p\n",
-                            __func__, pmc->descriptors);
+                            "pmc_free: free pmc descriptors info list %p\n",
+                            pmc->descriptors);
                kfree(pmc->descriptors);
                pmc->descriptors = NULL;
        } else {
@@ -301,7 +295,7 @@ void wil_pmc_free(struct wil6210_priv *wil, int send_pmc_cmd)
  */
 int wil_pmc_last_cmd_status(struct wil6210_priv *wil)
 {
-       wil_dbg_misc(wil, "%s: status %d\n", __func__,
+       wil_dbg_misc(wil, "pmc_last_cmd_status: status %d\n",
                     wil->pmc.last_cmd_status);
 
        return wil->pmc.last_cmd_status;
@@ -324,7 +318,7 @@ ssize_t wil_pmc_read(struct file *filp, char __user *buf, size_t count,
        mutex_lock(&pmc->lock);
 
        if (!wil_is_pmc_allocated(pmc)) {
-               wil_err(wil, "%s: error, pmc is not allocated!\n", __func__);
+               wil_err(wil, "error, pmc is not allocated!\n");
                pmc->last_cmd_status = -EPERM;
                mutex_unlock(&pmc->lock);
                return -EPERM;
@@ -333,8 +327,8 @@ ssize_t wil_pmc_read(struct file *filp, char __user *buf, size_t count,
        pmc_size = pmc->descriptor_size * pmc->num_descriptors;
 
        wil_dbg_misc(wil,
-                    "%s: size %u, pos %lld\n",
-                    __func__, (unsigned)count, *f_pos);
+                    "pmc_read: size %u, pos %lld\n",
+                    (u32)count, *f_pos);
 
        pmc->last_cmd_status = 0;
 
@@ -343,15 +337,16 @@ ssize_t wil_pmc_read(struct file *filp, char __user *buf, size_t count,
        offset = *f_pos - (idx * pmc->descriptor_size);
 
        if (*f_pos >= pmc_size) {
-               wil_dbg_misc(wil, "%s: reached end of pmc buf: %lld >= %u\n",
-                            __func__, *f_pos, (unsigned)pmc_size);
+               wil_dbg_misc(wil,
+                            "pmc_read: reached end of pmc buf: %lld >= %u\n",
+                            *f_pos, (u32)pmc_size);
                pmc->last_cmd_status = -ERANGE;
                goto out;
        }
 
        wil_dbg_misc(wil,
-                    "%s: read from pos %lld (descriptor %llu, offset %llu) %zu bytes\n",
-                    __func__, *f_pos, idx, offset, count);
+                    "pmc_read: read from pos %lld (descriptor %llu, offset %llu) %zu bytes\n",
+                    *f_pos, idx, offset, count);
 
        /* if no errors, return the copied byte count */
        retval = simple_read_from_buffer(buf,
index 19ed127d4d055703d14e018a1f278a5b8d9dbd89..7404b6f39c6aff08495dd53c6f463d5c20f0e15c 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2014-2016 Qualcomm Atheros, Inc.
+ * Copyright (c) 2014-2017 Qualcomm Atheros, Inc.
  *
  * Permission to use, copy, modify, and/or distribute this software for any
  * purpose with or without fee is hereby granted, provided that the above
@@ -349,8 +349,8 @@ __acquires(&sta->tid_rx_lock) __releases(&sta->tid_rx_lock)
        rc = wmi_addba_rx_resp(wil, cid, tid, dialog_token, status,
                               agg_amsdu, agg_wsize, agg_timeout);
        if (rc || (status != WLAN_STATUS_SUCCESS)) {
-               wil_err(wil, "%s: do not apply ba, rc(%d), status(%d)\n",
-                       __func__, rc, status);
+               wil_err(wil, "do not apply ba, rc(%d), status(%d)\n", rc,
+                       status);
                goto out;
        }
 
@@ -387,7 +387,7 @@ int wil_addba_tx_request(struct wil6210_priv *wil, u8 ringid, u16 wsize)
        txdata->addba_in_progress = true;
        rc = wmi_addba(wil, ringid, agg_wsize, agg_timeout);
        if (rc) {
-               wil_err(wil, "%s: wmi_addba failed, rc (%d)", __func__, rc);
+               wil_err(wil, "wmi_addba failed, rc (%d)", rc);
                txdata->addba_in_progress = false;
        }
 
index c1b4bb03e997b31fe8798a8b3543dd117d1fbe26..072182e527e69afe888b4ef54789495ba37d4c6a 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2012-2016 Qualcomm Atheros, Inc.
+ * Copyright (c) 2012-2017 Qualcomm Atheros, Inc.
  *
  * Permission to use, copy, modify, and/or distribute this software for any
  * purpose with or without fee is hereby granted, provided that the above
 #include "trace.h"
 
 static bool rtap_include_phy_info;
-module_param(rtap_include_phy_info, bool, S_IRUGO);
+module_param(rtap_include_phy_info, bool, 0444);
 MODULE_PARM_DESC(rtap_include_phy_info,
                 " Include PHY info in the radiotap header, default - no");
 
 bool rx_align_2;
-module_param(rx_align_2, bool, S_IRUGO);
+module_param(rx_align_2, bool, 0444);
 MODULE_PARM_DESC(rx_align_2, " align Rx buffers on 4*n+2, default - no");
 
 static inline uint wil_rx_snaplen(void)
@@ -112,7 +112,7 @@ static int wil_vring_alloc(struct wil6210_priv *wil, struct vring *vring)
        size_t sz = vring->size * sizeof(vring->va[0]);
        uint i;
 
-       wil_dbg_misc(wil, "%s()\n", __func__);
+       wil_dbg_misc(wil, "vring_alloc:\n");
 
        BUILD_BUG_ON(sizeof(vring->va[0]) != 32);
 
@@ -745,7 +745,7 @@ void wil_rx_handle(struct wil6210_priv *wil, int *quota)
                wil_err(wil, "Rx IRQ while Rx not yet initialized\n");
                return;
        }
-       wil_dbg_txrx(wil, "%s()\n", __func__);
+       wil_dbg_txrx(wil, "rx_handle\n");
        while ((*quota > 0) && (NULL != (skb = wil_vring_reap_rx(wil, v)))) {
                (*quota)--;
 
@@ -768,7 +768,7 @@ int wil_rx_init(struct wil6210_priv *wil, u16 size)
        struct vring *vring = &wil->vring_rx;
        int rc;
 
-       wil_dbg_misc(wil, "%s()\n", __func__);
+       wil_dbg_misc(wil, "rx_init\n");
 
        if (vring->va) {
                wil_err(wil, "Rx ring already allocated\n");
@@ -799,7 +799,7 @@ void wil_rx_fini(struct wil6210_priv *wil)
 {
        struct vring *vring = &wil->vring_rx;
 
-       wil_dbg_misc(wil, "%s()\n", __func__);
+       wil_dbg_misc(wil, "rx_fini\n");
 
        if (vring->va)
                wil_vring_free(wil, vring, 0);
@@ -851,7 +851,7 @@ int wil_vring_init_tx(struct wil6210_priv *wil, int id, int size,
        struct vring *vring = &wil->vring_tx[id];
        struct vring_tx_data *txdata = &wil->vring_tx_data[id];
 
-       wil_dbg_misc(wil, "%s() max_mpdu_size %d\n", __func__,
+       wil_dbg_misc(wil, "vring_init_tx: max_mpdu_size %d\n",
                     cmd.vring_cfg.tx_sw_ring.max_mpdu_size);
        lockdep_assert_held(&wil->mutex);
 
@@ -931,7 +931,7 @@ int wil_vring_init_bcast(struct wil6210_priv *wil, int id, int size)
        struct vring *vring = &wil->vring_tx[id];
        struct vring_tx_data *txdata = &wil->vring_tx_data[id];
 
-       wil_dbg_misc(wil, "%s() max_mpdu_size %d\n", __func__,
+       wil_dbg_misc(wil, "vring_init_bcast: max_mpdu_size %d\n",
                     cmd.vring_cfg.tx_sw_ring.max_mpdu_size);
        lockdep_assert_held(&wil->mutex);
 
@@ -993,7 +993,7 @@ void wil_vring_fini_tx(struct wil6210_priv *wil, int id)
        if (!vring->va)
                return;
 
-       wil_dbg_misc(wil, "%s() id=%d\n", __func__, id);
+       wil_dbg_misc(wil, "vring_fini_tx: id=%d\n", id);
 
        spin_lock_bh(&txdata->lock);
        txdata->dot1x_open = false;
@@ -1032,12 +1032,14 @@ static struct vring *wil_find_tx_ucast(struct wil6210_priv *wil,
                        struct vring *v = &wil->vring_tx[i];
                        struct vring_tx_data *txdata = &wil->vring_tx_data[i];
 
-                       wil_dbg_txrx(wil, "%s(%pM) -> [%d]\n",
-                                    __func__, eth->h_dest, i);
+                       wil_dbg_txrx(wil, "find_tx_ucast: (%pM) -> [%d]\n",
+                                    eth->h_dest, i);
                        if (v->va && txdata->enabled) {
                                return v;
                        } else {
-                               wil_dbg_txrx(wil, "vring[%d] not valid\n", i);
+                               wil_dbg_txrx(wil,
+                                            "find_tx_ucast: vring[%d] not valid\n",
+                                            i);
                                return NULL;
                        }
                }
@@ -1193,17 +1195,6 @@ found:
        return v;
 }
 
-static struct vring *wil_find_tx_bcast(struct wil6210_priv *wil,
-                                      struct sk_buff *skb)
-{
-       struct wireless_dev *wdev = wil->wdev;
-
-       if (wdev->iftype != NL80211_IFTYPE_AP)
-               return wil_find_tx_bcast_2(wil, skb);
-
-       return wil_find_tx_bcast_1(wil, skb);
-}
-
 static int wil_tx_desc_map(struct vring_tx_desc *d, dma_addr_t pa, u32 len,
                           int vring_index)
 {
@@ -1373,8 +1364,8 @@ static int __wil_tx_vring_tso(struct wil6210_priv *wil, struct vring *vring,
        int gso_type;
        int rc = -EINVAL;
 
-       wil_dbg_txrx(wil, "%s() %d bytes to vring %d\n",
-                    __func__, skb->len, vring_index);
+       wil_dbg_txrx(wil, "tx_vring_tso: %d bytes to vring %d\n", skb->len,
+                    vring_index);
 
        if (unlikely(!txdata->enabled))
                return -EINVAL;
@@ -1643,8 +1634,8 @@ static int __wil_tx_vring(struct wil6210_priv *wil, struct vring *vring,
        bool mcast = (vring_index == wil->bcast_vring);
        uint len = skb_headlen(skb);
 
-       wil_dbg_txrx(wil, "%s() %d bytes to vring %d\n",
-                    __func__, skb->len, vring_index);
+       wil_dbg_txrx(wil, "tx_vring: %d bytes to vring %d\n", skb->len,
+                    vring_index);
 
        if (unlikely(!txdata->enabled))
                return -EINVAL;
@@ -1884,7 +1875,7 @@ netdev_tx_t wil_start_xmit(struct sk_buff *skb, struct net_device *ndev)
        static bool pr_once_fw;
        int rc;
 
-       wil_dbg_txrx(wil, "%s()\n", __func__);
+       wil_dbg_txrx(wil, "start_xmit\n");
        if (unlikely(!test_bit(wil_status_fwready, wil->status))) {
                if (!pr_once_fw) {
                        wil_err(wil, "FW not ready\n");
@@ -1903,12 +1894,26 @@ netdev_tx_t wil_start_xmit(struct sk_buff *skb, struct net_device *ndev)
        pr_once_fw = false;
 
        /* find vring */
-       if (wil->wdev->iftype == NL80211_IFTYPE_STATION) {
-               /* in STA mode (ESS), all to same VRING */
+       if (wil->wdev->iftype == NL80211_IFTYPE_STATION && !wil->pbss) {
+               /* in STA mode (ESS), all to same VRING (to AP) */
                vring = wil_find_tx_vring_sta(wil, skb);
-       } else { /* direct communication, find matching VRING */
-               vring = bcast ? wil_find_tx_bcast(wil, skb) :
-                               wil_find_tx_ucast(wil, skb);
+       } else if (bcast) {
+               if (wil->pbss)
+                       /* in pbss, no bcast VRING - duplicate skb in
+                        * all stations VRINGs
+                        */
+                       vring = wil_find_tx_bcast_2(wil, skb);
+               else if (wil->wdev->iftype == NL80211_IFTYPE_AP)
+                       /* AP has a dedicated bcast VRING */
+                       vring = wil_find_tx_bcast_1(wil, skb);
+               else
+                       /* unexpected combination, fallback to duplicating
+                        * the skb in all stations VRINGs
+                        */
+                       vring = wil_find_tx_bcast_2(wil, skb);
+       } else {
+               /* unicast, find specific VRING by dest. address */
+               vring = wil_find_tx_ucast(wil, skb);
        }
        if (unlikely(!vring)) {
                wil_dbg_txrx(wil, "No Tx VRING found for %pM\n", eth->h_dest);
@@ -1982,7 +1987,7 @@ int wil_tx_complete(struct wil6210_priv *wil, int ringid)
                return 0;
        }
 
-       wil_dbg_txrx(wil, "%s(%d)\n", __func__, ringid);
+       wil_dbg_txrx(wil, "tx_complete: (%d)\n", ringid);
 
        used_before_complete = wil_vring_used_tx(vring);
 
index 237e1666df2da1efcb2832515e1df8f16adfcade..085a2dbfa21d615887c458e6385ac06cae8dcca3 100644 (file)
@@ -33,10 +33,12 @@ extern int agg_wsize;
 extern u32 vring_idle_trsh;
 extern bool rx_align_2;
 extern bool debug_fw;
+extern bool disable_ap_sme;
 
 #define WIL_NAME "wil6210"
-#define WIL_FW_NAME "wil6210.fw" /* code */
-#define WIL_FW2_NAME "wil6210.brd" /* board & radio parameters */
+#define WIL_FW_NAME_DEFAULT "wil6210.fw" /* code Sparrow B0 */
+#define WIL_FW_NAME_SPARROW_PLUS "wil6210_sparrow_plus.fw" /* code Sparrow D0 */
+#define WIL_BOARD_FILE_NAME "wil6210.brd" /* board & radio parameters */
 
 #define WIL_MAX_BUS_REQUEST_KBPS 800000 /* ~6.1Gbps */
 
@@ -98,6 +100,9 @@ static inline u32 wil_mtu2macbuf(u32 mtu)
 #define WIL6210_RX_HIGH_TRSH_INIT              (0)
 #define WIL6210_RX_HIGH_TRSH_DEFAULT \
                                (1 << (WIL_RX_RING_SIZE_ORDER_DEFAULT - 3))
+#define WIL_MAX_DMG_AID 254 /* for DMG only 1-254 allowed (see
+                            * 802.11REVmc/D5.0, section 9.4.1.8)
+                            */
 /* Hardware definitions begin */
 
 /*
@@ -249,7 +254,12 @@ struct RGF_ICR {
        #define BIT_CAF_OSC_DIG_XTAL_STABLE     BIT(0)
 
 #define RGF_USER_JTAG_DEV_ID   (0x880b34) /* device ID */
-       #define JTAG_DEV_ID_SPARROW_B0  (0x2632072f)
+       #define JTAG_DEV_ID_SPARROW     (0x2632072f)
+
+#define RGF_USER_REVISION_ID           (0x88afe4)
+#define RGF_USER_REVISION_ID_MASK      (3)
+       #define REVISION_ID_SPARROW_B0  (0x0)
+       #define REVISION_ID_SPARROW_D0  (0x3)
 
 /* crash codes for FW/Ucode stored here */
 #define RGF_FW_ASSERT_CODE             (0x91f020)
@@ -257,7 +267,8 @@ struct RGF_ICR {
 
 enum {
        HW_VER_UNKNOWN,
-       HW_VER_SPARROW_B0, /* JTAG_DEV_ID_SPARROW_B0 */
+       HW_VER_SPARROW_B0, /* REVISION_ID_SPARROW_B0 */
+       HW_VER_SPARROW_D0, /* REVISION_ID_SPARROW_D0 */
 };
 
 /* popular locations */
@@ -512,6 +523,7 @@ struct wil_sta_info {
        unsigned long tid_rx_stop_requested[BITS_TO_LONGS(WIL_STA_TID_NUM)];
        struct wil_tid_crypto_rx tid_crypto_rx[WIL_STA_TID_NUM];
        struct wil_tid_crypto_rx group_crypto_rx;
+       u8 aid; /* 1-254; 0 if unknown/not reported */
 };
 
 enum {
@@ -583,7 +595,9 @@ struct wil6210_priv {
        DECLARE_BITMAP(status, wil_status_last);
        u8 fw_version[ETHTOOL_FWVERS_LEN];
        u32 hw_version;
+       u8 chip_revision;
        const char *hw_name;
+       const char *wil_fw_name;
        DECLARE_BITMAP(hw_capabilities, hw_capability_last);
        DECLARE_BITMAP(fw_capabilities, WMI_FW_CAPABILITY_MAX);
        u8 n_mids; /* number of additional MIDs as reported by FW */
@@ -653,6 +667,7 @@ struct wil6210_priv {
        struct dentry *debug;
        struct wil_blob_wrapper blobs[ARRAY_SIZE(fw_mapping)];
        u8 discovery_mode;
+       u8 abft_len;
 
        void *platform_handle;
        struct wil_platform_ops platform_ops;
@@ -816,8 +831,8 @@ int wmi_set_ie(struct wil6210_priv *wil, u8 type, u16 ie_len, const void *ie);
 int wmi_rx_chain_add(struct wil6210_priv *wil, struct vring *vring);
 int wmi_rxon(struct wil6210_priv *wil, bool on);
 int wmi_get_temperature(struct wil6210_priv *wil, u32 *t_m, u32 *t_r);
-int wmi_disconnect_sta(struct wil6210_priv *wil, const u8 *mac, u16 reason,
-                      bool full_disconnect);
+int wmi_disconnect_sta(struct wil6210_priv *wil, const u8 *mac,
+                      u16 reason, bool full_disconnect, bool del_sta);
 int wmi_addba(struct wil6210_priv *wil, u8 ringid, u8 size, u16 timeout);
 int wmi_delba_tx(struct wil6210_priv *wil, u8 ringid, u16 reason);
 int wmi_delba_rx(struct wil6210_priv *wil, u8 cidxtid, u16 reason);
@@ -827,6 +842,7 @@ int wmi_ps_dev_profile_cfg(struct wil6210_priv *wil,
                           enum wmi_ps_profile_type ps_profile);
 int wmi_set_mgmt_retry(struct wil6210_priv *wil, u8 retry_short);
 int wmi_get_mgmt_retry(struct wil6210_priv *wil, u8 *retry_short);
+int wmi_new_sta(struct wil6210_priv *wil, const u8 *mac, u8 aid);
 int wil_addba_rx_request(struct wil6210_priv *wil, u8 cidxtid,
                         u8 dialog_token, __le16 ba_param_set,
                         __le16 ba_timeout, __le16 ba_seq_ctrl);
@@ -918,6 +934,7 @@ int wil_iftype_nl2wmi(enum nl80211_iftype type);
 int wil_ioctl(struct wil6210_priv *wil, void __user *data, int cmd);
 int wil_request_firmware(struct wil6210_priv *wil, const char *name,
                         bool load);
+bool wil_fw_verify_file_exists(struct wil6210_priv *wil, const char *name);
 
 int wil_can_suspend(struct wil6210_priv *wil, bool is_runtime);
 int wil_suspend(struct wil6210_priv *wil, bool is_runtime);
index d051eea47a54ec58af7a154f411d5c0c9e6d3288..e53cf0cf70315ed3b32b3851fc5724c985c00de2 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2015 Qualcomm Atheros, Inc.
+ * Copyright (c) 2015,2017 Qualcomm Atheros, Inc.
  *
  * Permission to use, copy, modify, and/or distribute this software for any
  * purpose with or without fee is hereby granted, provided that the above
@@ -62,13 +62,13 @@ int wil_fw_copy_crash_dump(struct wil6210_priv *wil, void *dest, u32 size)
        u32 host_min, dump_size, offset, len;
 
        if (wil_fw_get_crash_dump_bounds(wil, &dump_size, &host_min)) {
-               wil_err(wil, "%s: fail to obtain crash dump size\n", __func__);
+               wil_err(wil, "fail to obtain crash dump size\n");
                return -EINVAL;
        }
 
        if (dump_size > size) {
-               wil_err(wil, "%s: not enough space for dump. Need %d have %d\n",
-                       __func__, dump_size, size);
+               wil_err(wil, "not enough space for dump. Need %d have %d\n",
+                       dump_size, size);
                return -EINVAL;
        }
 
@@ -83,8 +83,9 @@ int wil_fw_copy_crash_dump(struct wil6210_priv *wil, void *dest, u32 size)
                len = map->to - map->from;
                offset = map->host - host_min;
 
-               wil_dbg_misc(wil, "%s() - dump %s, size %d, offset %d\n",
-                            __func__, fw_mapping[i].name, len, offset);
+               wil_dbg_misc(wil,
+                            "fw_copy_crash_dump: - dump %s, size %d, offset %d\n",
+                            fw_mapping[i].name, len, offset);
 
                wil_memcpy_fromio_32((void * __force)(dest + offset),
                                     (const void __iomem * __force)data, len);
@@ -99,7 +100,7 @@ void wil_fw_core_dump(struct wil6210_priv *wil)
        u32 fw_dump_size;
 
        if (wil_fw_get_crash_dump_bounds(wil, &fw_dump_size, NULL)) {
-               wil_err(wil, "%s: fail to get fw dump size\n", __func__);
+               wil_err(wil, "fail to get fw dump size\n");
                return;
        }
 
@@ -115,6 +116,5 @@ void wil_fw_core_dump(struct wil6210_priv *wil)
         * after 5 min
         */
        dev_coredumpv(wil_to_dev(wil), fw_dump_data, fw_dump_size, GFP_KERNEL);
-       wil_info(wil, "%s: fw core dumped, size %d bytes\n", __func__,
-                fw_dump_size);
+       wil_info(wil, "fw core dumped, size %d bytes\n", fw_dump_size);
 }
index 7585003bef67cb867263ab5460aaef90c6d01d47..1f22c19696b11914e7e79a470882f7de692753c0 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2012-2016 Qualcomm Atheros, Inc.
+ * Copyright (c) 2012-2017 Qualcomm Atheros, Inc.
  *
  * Permission to use, copy, modify, and/or distribute this software for any
  * purpose with or without fee is hereby granted, provided that the above
 #include "trace.h"
 
 static uint max_assoc_sta = WIL6210_MAX_CID;
-module_param(max_assoc_sta, uint, S_IRUGO | S_IWUSR);
+module_param(max_assoc_sta, uint, 0644);
 MODULE_PARM_DESC(max_assoc_sta, " Max number of stations associated to the AP");
 
 int agg_wsize; /* = 0; */
-module_param(agg_wsize, int, S_IRUGO | S_IWUSR);
+module_param(agg_wsize, int, 0644);
 MODULE_PARM_DESC(agg_wsize, " Window size for Tx Block Ack after connect;"
                 " 0 - use default; < 0 - don't auto-establish");
 
 u8 led_id = WIL_LED_INVALID_ID;
-module_param(led_id, byte, S_IRUGO);
+module_param(led_id, byte, 0444);
 MODULE_PARM_DESC(led_id,
                 " 60G device led enablement. Set the led ID (0-2) to enable");
 
@@ -495,8 +495,8 @@ static void wmi_evt_connect(struct wil6210_priv *wil, int id, void *d, int len)
        }
 
        ch = evt->channel + 1;
-       wil_info(wil, "Connect %pM channel [%d] cid %d\n",
-                evt->bssid, ch, evt->cid);
+       wil_info(wil, "Connect %pM channel [%d] cid %d aid %d\n",
+                evt->bssid, ch, evt->cid, evt->aid);
        wil_hex_dump_wmi("connect AI : ", DUMP_PREFIX_OFFSET, 16, 1,
                         evt->assoc_info, len - sizeof(*evt), true);
 
@@ -539,8 +539,8 @@ static void wmi_evt_connect(struct wil6210_priv *wil, int id, void *d, int len)
        } else if ((wdev->iftype == NL80211_IFTYPE_AP) ||
                   (wdev->iftype == NL80211_IFTYPE_P2P_GO)) {
                if (wil->sta[evt->cid].status != wil_sta_unused) {
-                       wil_err(wil, "%s: AP: Invalid status %d for CID %d\n",
-                               __func__, wil->sta[evt->cid].status, evt->cid);
+                       wil_err(wil, "AP: Invalid status %d for CID %d\n",
+                               wil->sta[evt->cid].status, evt->cid);
                        mutex_unlock(&wil->mutex);
                        return;
                }
@@ -553,22 +553,19 @@ static void wmi_evt_connect(struct wil6210_priv *wil, int id, void *d, int len)
 
        rc = wil_tx_init(wil, evt->cid);
        if (rc) {
-               wil_err(wil, "%s: config tx vring failed for CID %d, rc (%d)\n",
-                       __func__, evt->cid, rc);
+               wil_err(wil, "config tx vring failed for CID %d, rc (%d)\n",
+                       evt->cid, rc);
                wmi_disconnect_sta(wil, wil->sta[evt->cid].addr,
-                                  WLAN_REASON_UNSPECIFIED, false);
+                                  WLAN_REASON_UNSPECIFIED, false, false);
        } else {
-               wil_info(wil, "%s: successful connection to CID %d\n",
-                        __func__, evt->cid);
+               wil_info(wil, "successful connection to CID %d\n", evt->cid);
        }
 
        if ((wdev->iftype == NL80211_IFTYPE_STATION) ||
            (wdev->iftype == NL80211_IFTYPE_P2P_CLIENT)) {
                if (rc) {
                        netif_carrier_off(ndev);
-                       wil_err(wil,
-                               "%s: cfg80211_connect_result with failure\n",
-                               __func__);
+                       wil_err(wil, "cfg80211_connect_result with failure\n");
                        cfg80211_connect_result(ndev, evt->bssid, NULL, 0,
                                                NULL, 0,
                                                WLAN_STATUS_UNSPECIFIED_FAILURE,
@@ -583,8 +580,12 @@ static void wmi_evt_connect(struct wil6210_priv *wil, int id, void *d, int len)
                }
        } else if ((wdev->iftype == NL80211_IFTYPE_AP) ||
                   (wdev->iftype == NL80211_IFTYPE_P2P_GO)) {
-               if (rc)
+               if (rc) {
+                       if (disable_ap_sme)
+                               /* notify new_sta has failed */
+                               cfg80211_del_sta(ndev, evt->bssid, GFP_KERNEL);
                        goto out;
+               }
 
                memset(&sinfo, 0, sizeof(sinfo));
 
@@ -597,12 +598,13 @@ static void wmi_evt_connect(struct wil6210_priv *wil, int id, void *d, int len)
 
                cfg80211_new_sta(ndev, evt->bssid, &sinfo, GFP_KERNEL);
        } else {
-               wil_err(wil, "%s: unhandled iftype %d for CID %d\n",
-                       __func__, wdev->iftype, evt->cid);
+               wil_err(wil, "unhandled iftype %d for CID %d\n", wdev->iftype,
+                       evt->cid);
                goto out;
        }
 
        wil->sta[evt->cid].status = wil_sta_connected;
+       wil->sta[evt->cid].aid = evt->aid;
        set_bit(wil_status_fwconnected, wil->status);
        wil_update_net_queues_bh(wil, NULL, false);
 
@@ -687,6 +689,7 @@ static void wmi_evt_vring_en(struct wil6210_priv *wil, int id, void *d, int len)
 {
        struct wmi_vring_en_event *evt = d;
        u8 vri = evt->vring_index;
+       struct wireless_dev *wdev = wil_to_wdev(wil);
 
        wil_dbg_wmi(wil, "Enable vring %d\n", vri);
 
@@ -694,7 +697,12 @@ static void wmi_evt_vring_en(struct wil6210_priv *wil, int id, void *d, int len)
                wil_err(wil, "Enable for invalid vring %d\n", vri);
                return;
        }
-       wil->vring_tx_data[vri].dot1x_open = true;
+
+       if (wdev->iftype != NL80211_IFTYPE_AP || !disable_ap_sme)
+               /* in AP mode with disable_ap_sme, this is done by
+                * wil_cfg80211_change_station()
+                */
+               wil->vring_tx_data[vri].dot1x_open = true;
        if (vri == wil->bcast_vring) /* no BA for bcast */
                return;
        if (agg_wsize >= 0)
@@ -919,8 +927,8 @@ void wmi_recv_cmd(struct wil6210_priv *wil)
                      offsetof(struct wil6210_mbox_ctl, rx.tail), r->tail);
 
                if (immed_reply) {
-                       wil_dbg_wmi(wil, "%s: Complete WMI 0x%04x\n",
-                                   __func__, wil->reply_id);
+                       wil_dbg_wmi(wil, "recv_cmd: Complete WMI 0x%04x\n",
+                                   wil->reply_id);
                        kfree(evt);
                        num_immed_reply++;
                        complete(&wil->wmi_call);
@@ -934,7 +942,7 @@ void wmi_recv_cmd(struct wil6210_priv *wil)
                }
        }
        /* normally, 1 event per IRQ should be processed */
-       wil_dbg_wmi(wil, "%s -> %d events queued, %d completed\n", __func__,
+       wil_dbg_wmi(wil, "recv_cmd: -> %d events queued, %d completed\n",
                    n - num_immed_reply, num_immed_reply);
 }
 
@@ -950,6 +958,7 @@ int wmi_call(struct wil6210_priv *wil, u16 cmdid, void *buf, u16 len,
        wil->reply_id = reply_id;
        wil->reply_buf = reply;
        wil->reply_size = reply_size;
+       reinit_completion(&wil->wmi_call);
        spin_unlock(&wil->wmi_ev_lock);
 
        rc = __wmi_send(wil, cmdid, buf, len);
@@ -1069,6 +1078,8 @@ int wmi_pcp_start(struct wil6210_priv *wil, int bi, u8 wmi_nettype,
                .pcp_max_assoc_sta = max_assoc_sta,
                .hidden_ssid = hidden_ssid,
                .is_go = is_go,
+               .disable_ap_sme = disable_ap_sme,
+               .abft_len = wil->abft_len,
        };
        struct {
                struct wmi_cmd_hdr wmi;
@@ -1086,6 +1097,13 @@ int wmi_pcp_start(struct wil6210_priv *wil, int bi, u8 wmi_nettype,
                cmd.pcp_max_assoc_sta = WIL6210_MAX_CID;
        }
 
+       if (disable_ap_sme &&
+           !test_bit(WMI_FW_CAPABILITY_DISABLE_AP_SME,
+                     wil->fw_capabilities)) {
+               wil_err(wil, "disable_ap_sme not supported by FW\n");
+               return -EOPNOTSUPP;
+       }
+
        /*
         * Processing time may be huge, in case of secure AP it takes about
         * 3500ms for FW to start AP
@@ -1352,7 +1370,7 @@ int wmi_rxon(struct wil6210_priv *wil, bool on)
                struct wmi_listen_started_event evt;
        } __packed reply;
 
-       wil_info(wil, "%s(%s)\n", __func__, on ? "on" : "off");
+       wil_info(wil, "(%s)\n", on ? "on" : "off");
 
        if (on) {
                rc = wmi_call(wil, WMI_START_LISTEN_CMDID, NULL, 0,
@@ -1456,12 +1474,15 @@ int wmi_get_temperature(struct wil6210_priv *wil, u32 *t_bb, u32 *t_rf)
        return 0;
 }
 
-int wmi_disconnect_sta(struct wil6210_priv *wil, const u8 *mac, u16 reason,
-                      bool full_disconnect)
+int wmi_disconnect_sta(struct wil6210_priv *wil, const u8 *mac,
+                      u16 reason, bool full_disconnect, bool del_sta)
 {
        int rc;
        u16 reason_code;
-       struct wmi_disconnect_sta_cmd cmd = {
+       struct wmi_disconnect_sta_cmd disc_sta_cmd = {
+               .disconnect_reason = cpu_to_le16(reason),
+       };
+       struct wmi_del_sta_cmd del_sta_cmd = {
                .disconnect_reason = cpu_to_le16(reason),
        };
        struct {
@@ -1469,12 +1490,19 @@ int wmi_disconnect_sta(struct wil6210_priv *wil, const u8 *mac, u16 reason,
                struct wmi_disconnect_event evt;
        } __packed reply;
 
-       ether_addr_copy(cmd.dst_mac, mac);
-
-       wil_dbg_wmi(wil, "%s(%pM, reason %d)\n", __func__, mac, reason);
+       wil_dbg_wmi(wil, "disconnect_sta: (%pM, reason %d)\n", mac, reason);
 
-       rc = wmi_call(wil, WMI_DISCONNECT_STA_CMDID, &cmd, sizeof(cmd),
-                     WMI_DISCONNECT_EVENTID, &reply, sizeof(reply), 1000);
+       if (del_sta) {
+               ether_addr_copy(del_sta_cmd.dst_mac, mac);
+               rc = wmi_call(wil, WMI_DEL_STA_CMDID, &del_sta_cmd,
+                             sizeof(del_sta_cmd), WMI_DISCONNECT_EVENTID,
+                             &reply, sizeof(reply), 1000);
+       } else {
+               ether_addr_copy(disc_sta_cmd.dst_mac, mac);
+               rc = wmi_call(wil, WMI_DISCONNECT_STA_CMDID, &disc_sta_cmd,
+                             sizeof(disc_sta_cmd), WMI_DISCONNECT_EVENTID,
+                             &reply, sizeof(reply), 1000);
+       }
        /* failure to disconnect in reasonable time treated as FW error */
        if (rc) {
                wil_fw_error_recovery(wil);
@@ -1507,8 +1535,8 @@ int wmi_addba(struct wil6210_priv *wil, u8 ringid, u8 size, u16 timeout)
                .amsdu = 0,
        };
 
-       wil_dbg_wmi(wil, "%s(ring %d size %d timeout %d)\n", __func__,
-                   ringid, size, timeout);
+       wil_dbg_wmi(wil, "addba: (ring %d size %d timeout %d)\n", ringid, size,
+                   timeout);
 
        return wmi_send(wil, WMI_VRING_BA_EN_CMDID, &cmd, sizeof(cmd));
 }
@@ -1520,8 +1548,7 @@ int wmi_delba_tx(struct wil6210_priv *wil, u8 ringid, u16 reason)
                .reason = cpu_to_le16(reason),
        };
 
-       wil_dbg_wmi(wil, "%s(ring %d reason %d)\n", __func__,
-                   ringid, reason);
+       wil_dbg_wmi(wil, "delba_tx: (ring %d reason %d)\n", ringid, reason);
 
        return wmi_send(wil, WMI_VRING_BA_DIS_CMDID, &cmd, sizeof(cmd));
 }
@@ -1533,8 +1560,8 @@ int wmi_delba_rx(struct wil6210_priv *wil, u8 cidxtid, u16 reason)
                .reason = cpu_to_le16(reason),
        };
 
-       wil_dbg_wmi(wil, "%s(CID %d TID %d reason %d)\n", __func__,
-                   cidxtid & 0xf, (cidxtid >> 4) & 0xf, reason);
+       wil_dbg_wmi(wil, "delba_rx: (CID %d TID %d reason %d)\n", cidxtid & 0xf,
+                   (cidxtid >> 4) & 0xf, reason);
 
        return wmi_send(wil, WMI_RCP_DELBA_CMDID, &cmd, sizeof(cmd));
 }
@@ -1686,11 +1713,29 @@ int wmi_abort_scan(struct wil6210_priv *wil)
        return rc;
 }
 
+int wmi_new_sta(struct wil6210_priv *wil, const u8 *mac, u8 aid)
+{
+       int rc;
+       struct wmi_new_sta_cmd cmd = {
+               .aid = aid,
+       };
+
+       wil_dbg_wmi(wil, "new sta %pM, aid %d\n", mac, aid);
+
+       ether_addr_copy(cmd.dst_mac, mac);
+
+       rc = wmi_send(wil, WMI_NEW_STA_CMDID, &cmd, sizeof(cmd));
+       if (rc)
+               wil_err(wil, "Failed to send new sta (%d)\n", rc);
+
+       return rc;
+}
+
 void wmi_event_flush(struct wil6210_priv *wil)
 {
        struct pending_wmi_event *evt, *t;
 
-       wil_dbg_wmi(wil, "%s()\n", __func__);
+       wil_dbg_wmi(wil, "event_flush\n");
 
        list_for_each_entry_safe(evt, t, &wil->pending_wmi_ev, list) {
                list_del(&evt->list);
@@ -1731,8 +1776,8 @@ static void wmi_event_handle(struct wil6210_priv *wil,
                        WARN_ON(wil->reply_buf);
                        wmi_evt_call_handler(wil, id, evt_data,
                                             len - sizeof(*wmi));
-                       wil_dbg_wmi(wil, "%s: Complete WMI 0x%04x\n",
-                                   __func__, id);
+                       wil_dbg_wmi(wil, "event_handle: Complete WMI 0x%04x\n",
+                                   id);
                        complete(&wil->wmi_call);
                        return;
                }
@@ -1779,11 +1824,11 @@ void wmi_event_worker(struct work_struct *work)
        struct pending_wmi_event *evt;
        struct list_head *lh;
 
-       wil_dbg_wmi(wil, "Start %s\n", __func__);
+       wil_dbg_wmi(wil, "event_worker: Start\n");
        while ((lh = next_wmi_ev(wil)) != NULL) {
                evt = list_entry(lh, struct pending_wmi_event, list);
                wmi_event_handle(wil, &evt->event.hdr);
                kfree(evt);
        }
-       wil_dbg_wmi(wil, "Finished %s\n", __func__);
+       wil_dbg_wmi(wil, "event_worker: Finished\n");
 }
index d93a4d490d24e67444e2d27f03ad74e4e77cd70f..7c9fee57aa9110695e10dc96535169a2f988c62a 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2012-2016 Qualcomm Atheros, Inc.
+ * Copyright (c) 2012-2017 Qualcomm Atheros, Inc.
  * Copyright (c) 2006-2012 Wilocity
  *
  * Permission to use, copy, modify, and/or distribute this software for any
@@ -56,6 +56,8 @@ enum wmi_fw_capability {
        WMI_FW_CAPABILITY_PS_CONFIG             = 1,
        WMI_FW_CAPABILITY_RF_SECTORS            = 2,
        WMI_FW_CAPABILITY_MGMT_RETRY_LIMIT      = 3,
+       WMI_FW_CAPABILITY_DISABLE_AP_SME        = 4,
+       WMI_FW_CAPABILITY_WMI_ONLY              = 5,
        WMI_FW_CAPABILITY_MAX,
 };
 
@@ -185,8 +187,11 @@ enum wmi_command_id {
        WMI_RS_CFG_CMDID                                = 0x921,
        WMI_GET_DETAILED_RS_RES_CMDID                   = 0x922,
        WMI_AOA_MEAS_CMDID                              = 0x923,
+       WMI_BRP_SET_ANT_LIMIT_CMDID                     = 0x924,
        WMI_SET_MGMT_RETRY_LIMIT_CMDID                  = 0x930,
        WMI_GET_MGMT_RETRY_LIMIT_CMDID                  = 0x931,
+       WMI_NEW_STA_CMDID                               = 0x935,
+       WMI_DEL_STA_CMDID                               = 0x936,
        WMI_TOF_SESSION_START_CMDID                     = 0x991,
        WMI_TOF_GET_CAPABILITIES_CMDID                  = 0x992,
        WMI_TOF_SET_LCR_CMDID                           = 0x993,
@@ -543,7 +548,10 @@ struct wmi_pcp_start_cmd {
        u8 pcp_max_assoc_sta;
        u8 hidden_ssid;
        u8 is_go;
-       u8 reserved0[7];
+       u8 reserved0[5];
+       /* abft_len override if non-0 */
+       u8 abft_len;
+       u8 disable_ap_sme;
        u8 network_type;
        u8 channel;
        u8 disable_sec_offload;
@@ -902,6 +910,18 @@ struct wmi_set_mgmt_retry_limit_cmd {
        u8 reserved[3];
 } __packed;
 
+/* WMI_NEW_STA_CMDID */
+struct wmi_new_sta_cmd {
+       u8 dst_mac[WMI_MAC_LEN];
+       u8 aid;
+} __packed;
+
+/* WMI_DEL_STA_CMDID */
+struct wmi_del_sta_cmd {
+       u8 dst_mac[WMI_MAC_LEN];
+       __le16 disconnect_reason;
+} __packed;
+
 enum wmi_tof_burst_duration {
        WMI_TOF_BURST_DURATION_250_USEC         = 2,
        WMI_TOF_BURST_DURATION_500_USEC         = 3,
@@ -1067,6 +1087,7 @@ enum wmi_event_id {
        WMI_RS_CFG_DONE_EVENTID                         = 0x1921,
        WMI_GET_DETAILED_RS_RES_EVENTID                 = 0x1922,
        WMI_AOA_MEAS_EVENTID                            = 0x1923,
+       WMI_BRP_SET_ANT_LIMIT_EVENTID                   = 0x1924,
        WMI_SET_MGMT_RETRY_LIMIT_EVENTID                = 0x1930,
        WMI_GET_MGMT_RETRY_LIMIT_EVENTID                = 0x1931,
        WMI_TOF_SESSION_END_EVENTID                     = 0x1991,
@@ -1287,12 +1308,13 @@ struct wmi_connect_event {
        u8 assoc_req_len;
        u8 assoc_resp_len;
        u8 cid;
-       u8 reserved2[3];
+       u8 aid;
+       u8 reserved2[2];
        /* not in use */
        u8 assoc_info[0];
 } __packed;
 
-/* WMI_DISCONNECT_EVENTID */
+/* disconnect_reason */
 enum wmi_disconnect_reason {
        WMI_DIS_REASON_NO_NETWORK_AVAIL         = 0x01,
        /* bmiss */
@@ -1310,6 +1332,7 @@ enum wmi_disconnect_reason {
        WMI_DIS_REASON_IBSS_MERGE               = 0x0E,
 };
 
+/* WMI_DISCONNECT_EVENTID */
 struct wmi_disconnect_event {
        /* reason code, see 802.11 spec. */
        __le16 protocol_reason_status;
@@ -1759,6 +1782,42 @@ struct wmi_get_detailed_rs_res_event {
        u8 reserved[3];
 } __packed;
 
+/* BRP antenna limit mode */
+enum wmi_brp_ant_limit_mode {
+       /* Disable BRP force antenna limit */
+       WMI_BRP_ANT_LIMIT_MODE_DISABLE          = 0x00,
+       /* Define maximal antennas limit. Only effective antennas will be
+        * actually used
+        */
+       WMI_BRP_ANT_LIMIT_MODE_EFFECTIVE        = 0x01,
+       /* Force a specific number of antennas */
+       WMI_BRP_ANT_LIMIT_MODE_FORCE            = 0x02,
+       /* number of BRP antenna limit modes */
+       WMI_BRP_ANT_LIMIT_MODES_NUM             = 0x03,
+};
+
+/* WMI_BRP_SET_ANT_LIMIT_CMDID */
+struct wmi_brp_set_ant_limit_cmd {
+       /* connection id */
+       u8 cid;
+       /* enum wmi_brp_ant_limit_mode */
+       u8 limit_mode;
+       /* antenna limit count, 1-27
+        * disable_mode - ignored
+        * effective_mode - upper limit to number of antennas to be used
+        * force_mode - exact number of antennas to be used
+        */
+       u8 ant_limit;
+       u8 reserved;
+} __packed;
+
+/* WMI_BRP_SET_ANT_LIMIT_EVENTID */
+struct wmi_brp_set_ant_limit_event {
+       /* wmi_fw_status */
+       u8 status;
+       u8 reserved[3];
+} __packed;
+
 /* broadcast connection ID */
 #define WMI_LINK_MAINTAIN_CFG_CID_BROADCAST    (0xFFFFFFFF)
 
index 72139b579b1892d71a4ff4741ee1ad1bd66478be..5bc2ba214735af2a8f44394834e1c40c45820487 100644 (file)
@@ -1104,6 +1104,7 @@ static const struct sdio_device_id brcmf_sdmmc_ids[] = {
        BRCMF_SDIO_DEVICE(SDIO_DEVICE_ID_BROADCOM_4339),
        BRCMF_SDIO_DEVICE(SDIO_DEVICE_ID_BROADCOM_43430),
        BRCMF_SDIO_DEVICE(SDIO_DEVICE_ID_BROADCOM_4345),
+       BRCMF_SDIO_DEVICE(SDIO_DEVICE_ID_BROADCOM_43455),
        BRCMF_SDIO_DEVICE(SDIO_DEVICE_ID_BROADCOM_4354),
        BRCMF_SDIO_DEVICE(SDIO_DEVICE_ID_BROADCOM_4356),
        { /* end: all zeroes */ }
index e21f7600122b7cbd0c98980dab6ccac0e543c0d6..76693df347425951397a211c863f19046dbf07f5 100644 (file)
@@ -218,9 +218,6 @@ int brcmf_bus_get_memdump(struct brcmf_bus *bus, void *data, size_t len)
  * interface functions from common layer
  */
 
-bool brcmf_c_prec_enq(struct device *dev, struct pktq *q, struct sk_buff *pkt,
-                     int prec);
-
 /* Receive frame for delivery to OS.  Callee disposes of rxp. */
 void brcmf_rx_frame(struct device *dev, struct sk_buff *rxp, bool handle_event);
 /* Receive async event packet from firmware. Callee disposes of rxp. */
@@ -241,13 +238,12 @@ void brcmf_txcomplete(struct device *dev, struct sk_buff *txp, bool success);
 /* Configure the "global" bus state used by upper layers */
 void brcmf_bus_change_state(struct brcmf_bus *bus, enum brcmf_bus_state state);
 
-int brcmf_bus_start(struct device *dev);
+int brcmf_bus_started(struct device *dev);
 s32 brcmf_iovar_data_set(struct device *dev, char *name, void *data, u32 len);
 void brcmf_bus_add_txhdrlen(struct device *dev, uint len);
 
 #ifdef CONFIG_BRCMFMAC_SDIO
 void brcmf_sdio_exit(void);
-void brcmf_sdio_init(void);
 void brcmf_sdio_register(void);
 #endif
 #ifdef CONFIG_BRCMFMAC_USB
index 15eaf722b54b79581b893fca09e03e361fa35d10..0e28d0710af5957abb5c911b21778cdd1542ecf1 100644 (file)
@@ -138,7 +138,6 @@ static struct ieee80211_rate __wl_rates[] = {
        .band                   = NL80211_BAND_2GHZ,            \
        .center_freq            = (_freq),                      \
        .hw_value               = (_channel),                   \
-       .flags                  = IEEE80211_CHAN_DISABLED,      \
        .max_antenna_gain       = 0,                            \
        .max_power              = 30,                           \
 }
@@ -147,7 +146,6 @@ static struct ieee80211_rate __wl_rates[] = {
        .band                   = NL80211_BAND_5GHZ,            \
        .center_freq            = 5000 + (5 * (_channel)),      \
        .hw_value               = (_channel),                   \
-       .flags                  = IEEE80211_CHAN_DISABLED,      \
        .max_antenna_gain       = 0,                            \
        .max_power              = 30,                           \
 }
@@ -328,7 +326,7 @@ u16 channel_to_chanspec(struct brcmu_d11inf *d11inf,
  * triples, returning a pointer to the substring whose first element
  * matches tag
  */
-const struct brcmf_tlv *
+static const struct brcmf_tlv *
 brcmf_parse_tlvs(const void *buf, int buflen, uint key)
 {
        const struct brcmf_tlv *elt = buf;
@@ -3332,7 +3330,6 @@ brcmf_notify_sched_scan_results(struct brcmf_if *ifp,
                goto out_err;
        }
 
-       data += sizeof(struct brcmf_pno_scanresults_le);
        netinfo_start = brcmf_get_netinfo_array(pfn_result);
 
        for (i = 0; i < result_count; i++) {
@@ -3480,8 +3477,7 @@ brcmf_wowl_nd_results(struct brcmf_if *ifp, const struct brcmf_event_msg *e,
                return -EINVAL;
        }
 
-       data += sizeof(struct brcmf_pno_scanresults_le);
-       netinfo = (struct brcmf_pno_net_info_le *)data;
+       netinfo = brcmf_get_netinfo_array(pfn_result);
        memcpy(cfg->wowl.nd->ssid.ssid, netinfo->SSID, netinfo->SSID_len);
        cfg->wowl.nd->ssid.ssid_len = netinfo->SSID_len;
        cfg->wowl.nd->n_channels = 1;
@@ -5071,6 +5067,29 @@ static int brcmf_cfg80211_tdls_oper(struct wiphy *wiphy,
        return ret;
 }
 
+static int
+brcmf_cfg80211_update_conn_params(struct wiphy *wiphy,
+                                 struct net_device *ndev,
+                                 struct cfg80211_connect_params *sme,
+                                 u32 changed)
+{
+       struct brcmf_if *ifp;
+       int err;
+
+       if (!(changed & UPDATE_ASSOC_IES))
+               return 0;
+
+       ifp = netdev_priv(ndev);
+       err = brcmf_vif_set_mgmt_ie(ifp->vif, BRCMF_VNDR_IE_ASSOCREQ_FLAG,
+                                   sme->ie, sme->ie_len);
+       if (err)
+               brcmf_err("Set Assoc REQ IE Failed\n");
+       else
+               brcmf_dbg(TRACE, "Applied Vndr IEs for Assoc request\n");
+
+       return err;
+}
+
 #ifdef CONFIG_PM
 static int
 brcmf_cfg80211_set_rekey_data(struct wiphy *wiphy, struct net_device *ndev,
@@ -5138,6 +5157,7 @@ static struct cfg80211_ops brcmf_cfg80211_ops = {
        .crit_proto_start = brcmf_cfg80211_crit_proto_start,
        .crit_proto_stop = brcmf_cfg80211_crit_proto_stop,
        .tdls_oper = brcmf_cfg80211_tdls_oper,
+       .update_connect_params = brcmf_cfg80211_update_conn_params,
 };
 
 struct brcmf_cfg80211_vif *brcmf_alloc_vif(struct brcmf_cfg80211_info *cfg,
@@ -5825,7 +5845,6 @@ static int brcmf_construct_chaninfo(struct brcmf_cfg80211_info *cfg,
        u32 i, j;
        u32 total;
        u32 chaninfo;
-       u32 index;
 
        pbuf = kzalloc(BRCMF_DCMD_MEDLEN, GFP_KERNEL);
 
@@ -5873,33 +5892,36 @@ static int brcmf_construct_chaninfo(struct brcmf_cfg80211_info *cfg,
                    ch.bw == BRCMU_CHAN_BW_80)
                        continue;
 
-               channel = band->channels;
-               index = band->n_channels;
+               channel = NULL;
                for (j = 0; j < band->n_channels; j++) {
-                       if (channel[j].hw_value == ch.control_ch_num) {
-                               index = j;
+                       if (band->channels[j].hw_value == ch.control_ch_num) {
+                               channel = &band->channels[j];
                                break;
                        }
                }
-               channel[index].center_freq =
-                       ieee80211_channel_to_frequency(ch.control_ch_num,
-                                                      band->band);
-               channel[index].hw_value = ch.control_ch_num;
+               if (!channel) {
+                       /* It seems firmware supports some channel we never
+                        * considered. Something new in IEEE standard?
+                        */
+                       brcmf_err("Ignoring unexpected firmware channel %d\n",
+                                 ch.control_ch_num);
+                       continue;
+               }
 
                /* assuming the chanspecs order is HT20,
                 * HT40 upper, HT40 lower, and VHT80.
                 */
                if (ch.bw == BRCMU_CHAN_BW_80) {
-                       channel[index].flags &= ~IEEE80211_CHAN_NO_80MHZ;
+                       channel->flags &= ~IEEE80211_CHAN_NO_80MHZ;
                } else if (ch.bw == BRCMU_CHAN_BW_40) {
-                       brcmf_update_bw40_channel_flag(&channel[index], &ch);
+                       brcmf_update_bw40_channel_flag(channel, &ch);
                } else {
                        /* enable the channel and disable other bandwidths
                         * for now as mentioned order assure they are enabled
                         * for subsequent chanspecs.
                         */
-                       channel[index].flags = IEEE80211_CHAN_NO_HT40 |
-                                              IEEE80211_CHAN_NO_80MHZ;
+                       channel->flags = IEEE80211_CHAN_NO_HT40 |
+                                        IEEE80211_CHAN_NO_80MHZ;
                        ch.bw = BRCMU_CHAN_BW_20;
                        cfg->d11inf.encchspec(&ch);
                        chaninfo = ch.chspec;
@@ -5907,11 +5929,11 @@ static int brcmf_construct_chaninfo(struct brcmf_cfg80211_info *cfg,
                                                       &chaninfo);
                        if (!err) {
                                if (chaninfo & WL_CHAN_RADAR)
-                                       channel[index].flags |=
+                                       channel->flags |=
                                                (IEEE80211_CHAN_RADAR |
                                                 IEEE80211_CHAN_NO_IR);
                                if (chaninfo & WL_CHAN_PASSIVE)
-                                       channel[index].flags |=
+                                       channel->flags |=
                                                IEEE80211_CHAN_NO_IR;
                        }
                }
@@ -6341,7 +6363,7 @@ static void brcmf_wiphy_pno_params(struct wiphy *wiphy)
 }
 
 #ifdef CONFIG_PM
-static struct wiphy_wowlan_support brcmf_wowlan_support = {
+static const struct wiphy_wowlan_support brcmf_wowlan_support = {
        .flags = WIPHY_WOWLAN_MAGIC_PKT | WIPHY_WOWLAN_DISCONNECT,
        .n_patterns = BRCMF_WOWL_MAXPATTERNS,
        .pattern_max_len = BRCMF_WOWL_MAXPATTERNSIZE,
@@ -6354,19 +6376,29 @@ static void brcmf_wiphy_wowl_params(struct wiphy *wiphy, struct brcmf_if *ifp)
 {
 #ifdef CONFIG_PM
        struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
+       struct wiphy_wowlan_support *wowl;
+
+       wowl = kmemdup(&brcmf_wowlan_support, sizeof(brcmf_wowlan_support),
+                      GFP_KERNEL);
+       if (!wowl) {
+               brcmf_err("only support basic wowlan features\n");
+               wiphy->wowlan = &brcmf_wowlan_support;
+               return;
+       }
 
        if (brcmf_feat_is_enabled(ifp, BRCMF_FEAT_PNO)) {
                if (brcmf_feat_is_enabled(ifp, BRCMF_FEAT_WOWL_ND)) {
-                       brcmf_wowlan_support.flags |= WIPHY_WOWLAN_NET_DETECT;
+                       wowl->flags |= WIPHY_WOWLAN_NET_DETECT;
+                       wowl->max_nd_match_sets = BRCMF_PNO_MAX_PFN_COUNT;
                        init_waitqueue_head(&cfg->wowl.nd_data_wait);
                }
        }
        if (brcmf_feat_is_enabled(ifp, BRCMF_FEAT_WOWL_GTK)) {
-               brcmf_wowlan_support.flags |= WIPHY_WOWLAN_SUPPORTS_GTK_REKEY;
-               brcmf_wowlan_support.flags |= WIPHY_WOWLAN_GTK_REKEY_FAILURE;
+               wowl->flags |= WIPHY_WOWLAN_SUPPORTS_GTK_REKEY;
+               wowl->flags |= WIPHY_WOWLAN_GTK_REKEY_FAILURE;
        }
 
-       wiphy->wowlan = &brcmf_wowlan_support;
+       wiphy->wowlan = wowl;
 #endif
 }
 
@@ -6477,8 +6509,7 @@ static int brcmf_setup_wiphy(struct wiphy *wiphy, struct brcmf_if *ifp)
                        wiphy->bands[NL80211_BAND_5GHZ] = band;
                }
        }
-       err = brcmf_setup_wiphybands(wiphy);
-       return err;
+       return 0;
 }
 
 static s32 brcmf_config_dongle(struct brcmf_cfg80211_info *cfg)
@@ -6748,6 +6779,10 @@ static void brcmf_free_wiphy(struct wiphy *wiphy)
                kfree(wiphy->bands[NL80211_BAND_5GHZ]->channels);
                kfree(wiphy->bands[NL80211_BAND_5GHZ]);
        }
+#if IS_ENABLED(CONFIG_PM)
+       if (wiphy->wowlan != &brcmf_wowlan_support)
+               kfree(wiphy->wowlan);
+#endif
        wiphy_free(wiphy);
 }
 
@@ -6843,6 +6878,12 @@ struct brcmf_cfg80211_info *brcmf_cfg80211_attach(struct brcmf_pub *drvr,
                goto priv_out;
        }
 
+       err = brcmf_setup_wiphybands(wiphy);
+       if (err) {
+               brcmf_err("Setting wiphy bands failed (%d)\n", err);
+               goto wiphy_unreg_out;
+       }
+
        /* If cfg80211 didn't disable 40MHz HT CAP in wiphy_register(),
         * setup 40MHz in 2GHz band and enable OBSS scanning.
         */
index 0c9a7081fca912005474be5f5015d3fb2d667067..8f19d95d4175da0742fbecb17c3fd6fc19453dff 100644 (file)
@@ -396,8 +396,6 @@ void brcmf_free_vif(struct brcmf_cfg80211_vif *vif);
 s32 brcmf_vif_set_mgmt_ie(struct brcmf_cfg80211_vif *vif, s32 pktflag,
                          const u8 *vndr_ie_buf, u32 vndr_ie_len);
 s32 brcmf_vif_clear_mgmt_ies(struct brcmf_cfg80211_vif *vif);
-const struct brcmf_tlv *
-brcmf_parse_tlvs(const void *buf, int buflen, uint key);
 u16 channel_to_chanspec(struct brcmu_d11inf *d11inf,
                        struct ieee80211_channel *ch);
 bool brcmf_get_vif_state_any(struct brcmf_cfg80211_info *cfg,
index 3e15d64c64813513bc22202dd9e468588699abb0..f7c8c2e80349d2f50667f312f303270aeb5994bb 100644 (file)
@@ -74,7 +74,7 @@ module_param_named(roamoff, brcmf_roamoff, int, S_IRUSR);
 MODULE_PARM_DESC(roamoff, "Do not use internal roaming engine");
 
 #ifdef DEBUG
-/* always succeed brcmf_bus_start() */
+/* always succeed brcmf_bus_started() */
 static int brcmf_ignore_probe_fail;
 module_param_named(ignore_probe_fail, brcmf_ignore_probe_fail, int, 0);
 MODULE_PARM_DESC(ignore_probe_fail, "always succeed probe for debugging");
@@ -299,11 +299,9 @@ struct brcmf_mp_device *brcmf_get_module_param(struct device *dev,
                        }
                }
        }
-       if ((bus_type == BRCMF_BUSTYPE_SDIO) && (!found)) {
-               /* No platform data for this device. In case of SDIO try OF
-                * (Open Firwmare) Device Tree.
-                */
-               brcmf_of_probe(dev, &settings->bus.sdio);
+       if (!found) {
+               /* No platform data for this device, try OF (Open Firwmare) */
+               brcmf_of_probe(dev, bus_type, settings);
        }
        return settings;
 }
index bd095abca39340cc75490673755a07593dc66d93..a62f8e70b32078ef3d83e38c3eca4b3362c44aba 100644 (file)
@@ -65,6 +65,8 @@ struct brcmf_mp_device {
        } bus;
 };
 
+void brcmf_c_set_joinpref_default(struct brcmf_if *ifp);
+
 struct brcmf_mp_device *brcmf_get_module_param(struct device *dev,
                                               enum brcmf_bus_type bus_type,
                                               u32 chip, u32 chiprev);
index 9e6f60a0ec3eac7adac493b9fb337ffae62b6b9f..b73a55b00fa7402cf02b626fe710deb2e7188fc3 100644 (file)
@@ -966,7 +966,7 @@ static int brcmf_revinfo_read(struct seq_file *s, void *data)
        return 0;
 }
 
-int brcmf_bus_start(struct device *dev)
+int brcmf_bus_started(struct device *dev)
 {
        int ret = -1;
        struct brcmf_bus *bus_if = dev_get_drvdata(dev);
@@ -1075,16 +1075,6 @@ void brcmf_bus_add_txhdrlen(struct device *dev, uint len)
        }
 }
 
-static void brcmf_bus_detach(struct brcmf_pub *drvr)
-{
-       brcmf_dbg(TRACE, "Enter\n");
-
-       if (drvr) {
-               /* Stop the bus module */
-               brcmf_bus_stop(drvr->bus_if);
-       }
-}
-
 void brcmf_dev_reset(struct device *dev)
 {
        struct brcmf_bus *bus_if = dev_get_drvdata(dev);
@@ -1131,7 +1121,7 @@ void brcmf_detach(struct device *dev)
 
        brcmf_fws_deinit(drvr);
 
-       brcmf_bus_detach(drvr);
+       brcmf_bus_stop(drvr->bus_if);
 
        brcmf_proto_detach(drvr);
 
index c94dcab260d0009bc960e1eef119f66c2187e718..de3197be5491da482ff20e276b9bd34077c4359f 100644 (file)
@@ -216,7 +216,6 @@ void brcmf_txflowblock_if(struct brcmf_if *ifp,
 void brcmf_txfinalize(struct brcmf_if *ifp, struct sk_buff *txp, bool success);
 void brcmf_netif_rx(struct brcmf_if *ifp, struct sk_buff *skb);
 void brcmf_net_setcarrier(struct brcmf_if *ifp, bool on);
-void brcmf_c_set_joinpref_default(struct brcmf_if *ifp);
 int __init brcmf_core_init(void);
 void __exit brcmf_core_exit(void);
 
index 425c41dc0a59bd5167eb429f37395273d06d2403..aee6e5937c41cd3afc763893b3a147e7097430e1 100644 (file)
 #include "common.h"
 #include "of.h"
 
-void brcmf_of_probe(struct device *dev, struct brcmfmac_sdio_pd *sdio)
+void brcmf_of_probe(struct device *dev, enum brcmf_bus_type bus_type,
+                   struct brcmf_mp_device *settings)
 {
+       struct brcmfmac_sdio_pd *sdio = &settings->bus.sdio;
        struct device_node *np = dev->of_node;
        int irq;
        u32 irqf;
        u32 val;
 
-       if (!np || !of_device_is_compatible(np, "brcm,bcm4329-fmac"))
+       if (!np || bus_type != BRCMF_BUSTYPE_SDIO ||
+           !of_device_is_compatible(np, "brcm,bcm4329-fmac"))
                return;
 
        if (of_property_read_u32(np, "brcm,drive-strength", &val) == 0)
index a9d94c15d0f5ef422fdbad2656db1fd3064d0e6c..95b7032d54b199f55650d5d9a4c8d23c7f0c83d6 100644 (file)
  * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
  */
 #ifdef CONFIG_OF
-void brcmf_of_probe(struct device *dev, struct brcmfmac_sdio_pd *sdio);
+void brcmf_of_probe(struct device *dev, enum brcmf_bus_type bus_type,
+                   struct brcmf_mp_device *settings);
 #else
-static void brcmf_of_probe(struct device *dev, struct brcmfmac_sdio_pd *sdio)
+static void brcmf_of_probe(struct device *dev, enum brcmf_bus_type bus_type,
+                          struct brcmf_mp_device *settings)
 {
 }
 #endif /* CONFIG_OF */
index 048027f2085bbd293abe878ba2b2821ba6452804..6fae4cf3f6ab2876eb6ae2c3b5b07d02bcb0d3ca 100644 (file)
@@ -601,7 +601,6 @@ static void brcmf_pcie_attach(struct brcmf_pciedev_info *devinfo)
 {
        u32 config;
 
-       brcmf_pcie_select_core(devinfo, BCMA_CORE_PCIE2);
        /* BAR1 window may not be sized properly */
        brcmf_pcie_select_core(devinfo, BCMA_CORE_PCIE2);
        brcmf_pcie_write_reg32(devinfo, BRCMF_PCIE_PCIE2REG_CONFIGADDR, 0x4e0);
@@ -1572,7 +1571,7 @@ static int brcmf_pcie_attach_bus(struct brcmf_pciedev_info *devinfo)
        if (ret) {
                brcmf_err("brcmf_attach failed\n");
        } else {
-               ret = brcmf_bus_start(&devinfo->pdev->dev);
+               ret = brcmf_bus_started(&devinfo->pdev->dev);
                if (ret)
                        brcmf_err("dongle is not responding\n");
        }
index dfb0658713d9b31714566b5003564a9a53eb5e97..c5744b45ec8fbc6bb67539647d6db4a8afa4a465 100644 (file)
@@ -1661,7 +1661,7 @@ static u8 brcmf_sdio_rxglom(struct brcmf_sdio *bus, u8 rxseq)
                                           pfirst->len, pfirst->next,
                                           pfirst->prev);
                        skb_unlink(pfirst, &bus->glom);
-                       if (brcmf_sdio_fromevntchan(pfirst->data))
+                       if (brcmf_sdio_fromevntchan(&dptr[SDPCM_HWHDR_LEN]))
                                brcmf_rx_event(bus->sdiodev->dev, pfirst);
                        else
                                brcmf_rx_frame(bus->sdiodev->dev, pfirst,
@@ -4065,7 +4065,7 @@ static void brcmf_sdio_firmware_callback(struct device *dev,
 
        sdio_release_host(sdiodev->func[1]);
 
-       err = brcmf_bus_start(dev);
+       err = brcmf_bus_started(dev);
        if (err != 0) {
                brcmf_err("dongle is not responding\n");
                goto fail;
index 2f978a39b58a49485209f1da9f4f1a5c22647307..d93ebbdc773757adda218b16b816c30202792973 100644 (file)
@@ -1148,7 +1148,7 @@ static int brcmf_usb_bus_setup(struct brcmf_usbdev_info *devinfo)
        if (ret)
                goto fail;
 
-       ret = brcmf_bus_start(devinfo->dev);
+       ret = brcmf_bus_started(devinfo->dev);
        if (ret)
                goto fail;
 
index affe760c8c224a3a0b009fcf54a4ef0139d229e4..376c79337a0e04f86796494565749b7b333ab1ff 100644 (file)
@@ -2310,7 +2310,7 @@ static ssize_t iwl_dbgfs_fw_restart_write(struct file *file,
 {
        struct iwl_priv *priv = file->private_data;
        bool restart_fw = iwlwifi_mod_params.restart_fw;
-       int ret;
+       int __maybe_unused ret;
 
        iwlwifi_mod_params.restart_fw = true;
 
index 8c0719468d00514572a0cc6e76c4f084f850a335..2a04d0cd71aefc5b09022daee9e6470e924075a7 100644 (file)
@@ -163,7 +163,7 @@ int iwlagn_mac_setup_register(struct iwl_priv *priv,
                                       REGULATORY_DISABLE_BEACON_HINTS;
 
 #ifdef CONFIG_PM_SLEEP
-       if (priv->fw->img[IWL_UCODE_WOWLAN].sec[0].len &&
+       if (priv->fw->img[IWL_UCODE_WOWLAN].num_sec &&
            priv->trans->ops->d3_suspend &&
            priv->trans->ops->d3_resume &&
            device_can_wakeup(priv->trans->dev)) {
index b95c2d76db33c52cf6c5c9e1957ead160917f772..710dbbefd551eb6cc12563d5e18d9e7ef2339bab 100644 (file)
@@ -364,7 +364,7 @@ static void rs_program_fix_rate(struct iwl_priv *priv,
 /*
        get the traffic load value for tid
 */
-static u32 rs_tl_get_load(struct iwl_lq_sta *lq_data, u8 tid)
+static void rs_tl_get_load(struct iwl_lq_sta *lq_data, u8 tid)
 {
        u32 curr_time = jiffies_to_msecs(jiffies);
        u32 time_diff;
@@ -372,14 +372,14 @@ static u32 rs_tl_get_load(struct iwl_lq_sta *lq_data, u8 tid)
        struct iwl_traffic_load *tl = NULL;
 
        if (tid >= IWL_MAX_TID_COUNT)
-               return 0;
+               return;
 
        tl = &(lq_data->load[tid]);
 
        curr_time -= curr_time % TID_ROUND_VALUE;
 
        if (!(tl->queue_count))
-               return 0;
+               return;
 
        time_diff = TIME_WRAP_AROUND(tl->time_stamp, curr_time);
        index = time_diff / TID_QUEUE_CELL_SPACING;
@@ -388,8 +388,6 @@ static u32 rs_tl_get_load(struct iwl_lq_sta *lq_data, u8 tid)
        /* TID_MAX_TIME_DIFF */
        if (index >= TID_QUEUE_MAX_SIZE)
                rs_tl_rm_old_stats(tl, curr_time);
-
-       return tl->total;
 }
 
 static int rs_tl_turn_on_agg_for_tid(struct iwl_priv *priv,
@@ -397,7 +395,6 @@ static int rs_tl_turn_on_agg_for_tid(struct iwl_priv *priv,
                                      struct ieee80211_sta *sta)
 {
        int ret = -EAGAIN;
-       u32 load;
 
        /*
         * Don't create TX aggregation sessions when in high
@@ -410,7 +407,7 @@ static int rs_tl_turn_on_agg_for_tid(struct iwl_priv *priv,
                return ret;
        }
 
-       load = rs_tl_get_load(lq_data, tid);
+       rs_tl_get_load(lq_data, tid);
 
        IWL_DEBUG_HT(priv, "Starting Tx agg: STA: %pM tid: %d\n",
                        sta->addr, tid);
index c7509c51e9d94cfa18c856b468ca1a809a48c299..d6013bfe991cde5f28b694ff72a0bb46812b0081 100644 (file)
@@ -407,7 +407,7 @@ int iwl_run_init_ucode(struct iwl_priv *priv)
        lockdep_assert_held(&priv->mutex);
 
        /* No init ucode required? Curious, but maybe ok */
-       if (!priv->fw->img[IWL_UCODE_INIT].sec[0].len)
+       if (!priv->fw->img[IWL_UCODE_INIT].num_sec)
                return 0;
 
        iwl_init_notification_wait(&priv->notif_wait, &calib_wait,
index 0b9f6a7bc83439eeb8665c2176a0efb2655d79d1..39335b7b0c165c69a4d1aa004069c70184ed9675 100644 (file)
@@ -371,4 +371,4 @@ const struct iwl_cfg iwl6000_3agn_cfg = {
 MODULE_FIRMWARE(IWL6000_MODULE_FIRMWARE(IWL6000_UCODE_API_MAX));
 MODULE_FIRMWARE(IWL6050_MODULE_FIRMWARE(IWL6050_UCODE_API_MAX));
 MODULE_FIRMWARE(IWL6005_MODULE_FIRMWARE(IWL6000G2_UCODE_API_MAX));
-MODULE_FIRMWARE(IWL6030_MODULE_FIRMWARE(IWL6000G2B_UCODE_API_MAX));
+MODULE_FIRMWARE(IWL6030_MODULE_FIRMWARE(IWL6000G2_UCODE_API_MAX));
index d4b73dedf89b1a9bfdbe02cdd418311a5a062939..a72e58623d3ab013137f7fdf4a469de3d2d28a40 100644 (file)
@@ -73,8 +73,8 @@
 /* Highest firmware API version supported */
 #define IWL7260_UCODE_API_MAX  17
 #define IWL7265_UCODE_API_MAX  17
-#define IWL7265D_UCODE_API_MAX 26
-#define IWL3168_UCODE_API_MAX  26
+#define IWL7265D_UCODE_API_MAX 28
+#define IWL3168_UCODE_API_MAX  28
 
 /* Lowest firmware API version supported */
 #define IWL7260_UCODE_API_MIN  17
index d02ca1491d16cede66389540f8cb92dda5749ff3..df0fc24e99e1cfcf21424aac9582ac968f987bf2 100644 (file)
@@ -70,8 +70,8 @@
 #include "iwl-agn-hw.h"
 
 /* Highest firmware API version supported */
-#define IWL8000_UCODE_API_MAX  26
-#define IWL8265_UCODE_API_MAX  26
+#define IWL8000_UCODE_API_MAX  28
+#define IWL8265_UCODE_API_MAX  28
 
 /* Lowest firmware API version supported */
 #define IWL8000_UCODE_API_MIN  17
index ff850410d89719f77c67c8132f6f2b3e554af3a1..a5f0c0bf85ec8dd7f271a8954cd6d0823acbc9b1 100644 (file)
@@ -55,7 +55,7 @@
 #include "iwl-agn-hw.h"
 
 /* Highest firmware API version supported */
-#define IWL9000_UCODE_API_MAX  26
+#define IWL9000_UCODE_API_MAX  28
 
 /* Lowest firmware API version supported */
 #define IWL9000_UCODE_API_MIN  17
index ea16185258788a2235d1c7055d8bdae107b0caa1..82f18d967c4058547c65a47d508521546dcba52d 100644 (file)
@@ -55,7 +55,7 @@
 #include "iwl-agn-hw.h"
 
 /* Highest firmware API version supported */
-#define IWL_A000_UCODE_API_MAX 26
+#define IWL_A000_UCODE_API_MAX 28
 
 /* Lowest firmware API version supported */
 #define IWL_A000_UCODE_API_MIN 24
index 45b2f679e4d8ec624be0090081aad2cbab2bec5a..d228215016765b57bf6f632103b3cddbf7a65fdd 100644 (file)
@@ -166,8 +166,9 @@ static void iwl_free_fw_desc(struct iwl_drv *drv, struct fw_desc *desc)
 static void iwl_free_fw_img(struct iwl_drv *drv, struct fw_img *img)
 {
        int i;
-       for (i = 0; i < IWL_UCODE_SECTION_MAX; i++)
+       for (i = 0; i < img->num_sec; i++)
                iwl_free_fw_desc(drv, &img->sec[i]);
+       kfree(img->sec);
 }
 
 static void iwl_dealloc_ucode(struct iwl_drv *drv)
@@ -179,8 +180,7 @@ static void iwl_dealloc_ucode(struct iwl_drv *drv)
                kfree(drv->fw.dbg_conf_tlv[i]);
        for (i = 0; i < ARRAY_SIZE(drv->fw.dbg_trigger_tlv); i++)
                kfree(drv->fw.dbg_trigger_tlv[i]);
-       for (i = 0; i < ARRAY_SIZE(drv->fw.dbg_mem_tlv); i++)
-               kfree(drv->fw.dbg_mem_tlv[i]);
+       kfree(drv->fw.dbg_mem_tlv);
 
        for (i = 0; i < IWL_UCODE_TYPE_MAX; i++)
                iwl_free_fw_img(drv, drv->fw.img + i);
@@ -241,7 +241,7 @@ static int iwl_request_firmware(struct iwl_drv *drv, bool first)
 }
 
 struct fw_img_parsing {
-       struct fw_sec sec[IWL_UCODE_SECTION_MAX];
+       struct fw_sec *sec;
        int sec_counter;
 };
 
@@ -276,7 +276,8 @@ struct iwl_firmware_pieces {
        size_t dbg_conf_tlv_len[FW_DBG_CONF_MAX];
        struct iwl_fw_dbg_trigger_tlv *dbg_trigger_tlv[FW_DBG_TRIGGER_MAX];
        size_t dbg_trigger_tlv_len[FW_DBG_TRIGGER_MAX];
-       struct iwl_fw_dbg_mem_seg_tlv *dbg_mem_tlv[FW_DBG_MEM_MAX];
+       struct iwl_fw_dbg_mem_seg_tlv *dbg_mem_tlv;
+       size_t n_dbg_mem_tlv;
 };
 
 /*
@@ -290,11 +291,33 @@ static struct fw_sec *get_sec(struct iwl_firmware_pieces *pieces,
        return &pieces->img[type].sec[sec];
 }
 
+static void alloc_sec_data(struct iwl_firmware_pieces *pieces,
+                          enum iwl_ucode_type type,
+                          int sec)
+{
+       struct fw_img_parsing *img = &pieces->img[type];
+       struct fw_sec *sec_memory;
+       int size = sec + 1;
+       size_t alloc_size = sizeof(*img->sec) * size;
+
+       if (img->sec && img->sec_counter >= size)
+               return;
+
+       sec_memory = krealloc(img->sec, alloc_size, GFP_KERNEL);
+       if (!sec_memory)
+               return;
+
+       img->sec = sec_memory;
+       img->sec_counter = size;
+}
+
 static void set_sec_data(struct iwl_firmware_pieces *pieces,
                         enum iwl_ucode_type type,
                         int sec,
                         const void *data)
 {
+       alloc_sec_data(pieces, type, sec);
+
        pieces->img[type].sec[sec].data = data;
 }
 
@@ -303,6 +326,8 @@ static void set_sec_size(struct iwl_firmware_pieces *pieces,
                         int sec,
                         size_t size)
 {
+       alloc_sec_data(pieces, type, sec);
+
        pieces->img[type].sec[sec].size = size;
 }
 
@@ -318,6 +343,8 @@ static void set_sec_offset(struct iwl_firmware_pieces *pieces,
                           int sec,
                           u32 offset)
 {
+       alloc_sec_data(pieces, type, sec);
+
        pieces->img[type].sec[sec].offset = offset;
 }
 
@@ -383,6 +410,7 @@ static int iwl_store_ucode_sec(struct iwl_firmware_pieces *pieces,
        struct fw_img_parsing *img;
        struct fw_sec *sec;
        struct fw_sec_parsing *sec_parse;
+       size_t alloc_size;
 
        if (WARN_ON(!pieces || !data || type >= IWL_UCODE_TYPE_MAX))
                return -1;
@@ -390,6 +418,13 @@ static int iwl_store_ucode_sec(struct iwl_firmware_pieces *pieces,
        sec_parse = (struct fw_sec_parsing *)data;
 
        img = &pieces->img[type];
+
+       alloc_size = sizeof(*img->sec) * (img->sec_counter + 1);
+       sec = krealloc(img->sec, alloc_size, GFP_KERNEL);
+       if (!sec)
+               return -ENOMEM;
+       img->sec = sec;
+
        sec = &img->sec[img->sec_counter];
 
        sec->offset = le32_to_cpu(sec_parse->offset);
@@ -1009,31 +1044,37 @@ static int iwl_parse_tlv_firmware(struct iwl_drv *drv,
                        struct iwl_fw_dbg_mem_seg_tlv *dbg_mem =
                                (void *)tlv_data;
                        u32 type;
+                       size_t size;
+                       struct iwl_fw_dbg_mem_seg_tlv *n;
 
                        if (tlv_len != (sizeof(*dbg_mem)))
                                goto invalid_tlv_len;
 
                        type = le32_to_cpu(dbg_mem->data_type);
-                       drv->fw.dbg_dynamic_mem = true;
 
-                       if (type >= ARRAY_SIZE(drv->fw.dbg_mem_tlv)) {
-                               IWL_ERR(drv,
-                                       "Skip unknown dbg mem segment: %u\n",
-                                       dbg_mem->data_type);
-                               break;
-                       }
+                       IWL_DEBUG_INFO(drv, "Found debug memory segment: %u\n",
+                                      dbg_mem->data_type);
 
-                       if (pieces->dbg_mem_tlv[type]) {
-                               IWL_ERR(drv,
-                                       "Ignore duplicate mem segment: %u\n",
-                                       dbg_mem->data_type);
+                       switch (type & FW_DBG_MEM_TYPE_MASK) {
+                       case FW_DBG_MEM_TYPE_REGULAR:
+                       case FW_DBG_MEM_TYPE_PRPH:
+                               /* we know how to handle these */
                                break;
+                       default:
+                               IWL_ERR(drv,
+                                       "Found debug memory segment with invalid type: 0x%x\n",
+                                       type);
+                               return -EINVAL;
                        }
 
-                       IWL_DEBUG_INFO(drv, "Found debug memory segment: %u\n",
-                                      dbg_mem->data_type);
-
-                       pieces->dbg_mem_tlv[type] = dbg_mem;
+                       size = sizeof(*pieces->dbg_mem_tlv) *
+                              (pieces->n_dbg_mem_tlv + 1);
+                       n = krealloc(pieces->dbg_mem_tlv, size, GFP_KERNEL);
+                       if (!n)
+                               return -ENOMEM;
+                       pieces->dbg_mem_tlv = n;
+                       pieces->dbg_mem_tlv[pieces->n_dbg_mem_tlv] = *dbg_mem;
+                       pieces->n_dbg_mem_tlv++;
                        break;
                        }
                default:
@@ -1083,12 +1124,18 @@ static int iwl_alloc_ucode(struct iwl_drv *drv,
                           enum iwl_ucode_type type)
 {
        int i;
-       for (i = 0;
-            i < IWL_UCODE_SECTION_MAX && get_sec_size(pieces, type, i);
-            i++)
-               if (iwl_alloc_fw_desc(drv, &(drv->fw.img[type].sec[i]),
-                                     get_sec(pieces, type, i)))
+       struct fw_desc *sec;
+
+       sec = kcalloc(pieces->img[type].sec_counter, sizeof(*sec), GFP_KERNEL);
+       if (!sec)
+               return -ENOMEM;
+       drv->fw.img[type].sec = sec;
+       drv->fw.img[type].num_sec = pieces->img[type].sec_counter;
+
+       for (i = 0; i < pieces->img[type].sec_counter; i++)
+               if (iwl_alloc_fw_desc(drv, &sec[i], get_sec(pieces, type, i)))
                        return -ENOMEM;
+
        return 0;
 }
 
@@ -1345,19 +1392,12 @@ static void iwl_req_fw_callback(const struct firmware *ucode_raw, void *context)
                }
        }
 
-       for (i = 0; i < ARRAY_SIZE(drv->fw.dbg_mem_tlv); i++) {
-               if (pieces->dbg_mem_tlv[i]) {
-                       drv->fw.dbg_mem_tlv[i] =
-                               kmemdup(pieces->dbg_mem_tlv[i],
-                                       sizeof(*drv->fw.dbg_mem_tlv[i]),
-                                       GFP_KERNEL);
-                       if (!drv->fw.dbg_mem_tlv[i])
-                               goto out_free_fw;
-               }
-       }
-
        /* Now that we can no longer fail, copy information */
 
+       drv->fw.dbg_mem_tlv = pieces->dbg_mem_tlv;
+       pieces->dbg_mem_tlv = NULL;
+       drv->fw.n_dbg_mem_tlv = pieces->n_dbg_mem_tlv;
+
        /*
         * The (size - 16) / 12 formula is based on the information recorded
         * for each event, which is of mode 1 (including timestamp) for all
@@ -1441,25 +1481,27 @@ static void iwl_req_fw_callback(const struct firmware *ucode_raw, void *context)
                                op->name, err);
 #endif
        }
-       kfree(pieces);
-       return;
+       goto free;
 
  try_again:
        /* try next, if any */
        release_firmware(ucode_raw);
        if (iwl_request_firmware(drv, false))
                goto out_unbind;
-       kfree(pieces);
-       return;
+       goto free;
 
  out_free_fw:
        IWL_ERR(drv, "failed to allocate pci memory\n");
        iwl_dealloc_ucode(drv);
        release_firmware(ucode_raw);
  out_unbind:
-       kfree(pieces);
        complete(&drv->request_firmware_complete);
        device_release_driver(drv->trans->dev);
+ free:
+       for (i = 0; i < ARRAY_SIZE(pieces->img); i++)
+               kfree(pieces->img[i].sec);
+       kfree(pieces->dbg_mem_tlv);
+       kfree(pieces);
 }
 
 struct iwl_drv *iwl_drv_start(struct iwl_trans *trans,
index 84813b550ef196566821c545ded9eca0b0568d09..d01701ee477702272d4597a33d7c5710510f4fda 100644 (file)
@@ -379,7 +379,6 @@ enum iwl_ucode_tlv_capa {
  * For 16.0 uCode and above, there is no differentiation between sections,
  * just an offset to the HW address.
  */
-#define IWL_UCODE_SECTION_MAX 16
 #define CPU1_CPU2_SEPARATOR_SECTION    0xFFFFCCCC
 #define PAGING_SEPARATOR_SECTION       0xAAAABBBB
 
@@ -489,25 +488,22 @@ enum iwl_fw_dbg_monitor_mode {
 };
 
 /**
- * enum iwl_fw_mem_seg_type - data types for dumping on error
- *
- * @FW_DBG_MEM_SMEM: the data type is SMEM
- * @FW_DBG_MEM_DCCM_LMAC: the data type is DCCM_LMAC
- * @FW_DBG_MEM_DCCM_UMAC: the data type is DCCM_UMAC
+ * enum iwl_fw_mem_seg_type - memory segment type
+ * @FW_DBG_MEM_TYPE_MASK: mask for the type indication
+ * @FW_DBG_MEM_TYPE_REGULAR: regular memory
+ * @FW_DBG_MEM_TYPE_PRPH: periphery memory (requires special reading)
  */
-enum iwl_fw_dbg_mem_seg_type {
-       FW_DBG_MEM_DCCM_LMAC = 0,
-       FW_DBG_MEM_DCCM_UMAC,
-       FW_DBG_MEM_SMEM,
-
-       /* Must be last */
-       FW_DBG_MEM_MAX,
+enum iwl_fw_mem_seg_type {
+       FW_DBG_MEM_TYPE_MASK    = 0xff000000,
+       FW_DBG_MEM_TYPE_REGULAR = 0x00000000,
+       FW_DBG_MEM_TYPE_PRPH    = 0x01000000,
 };
 
 /**
  * struct iwl_fw_dbg_mem_seg_tlv - configures the debug data memory segments
  *
- * @data_type: enum %iwl_fw_mem_seg_type
+ * @data_type: the memory segment type to record, see &enum iwl_fw_mem_seg_type
+ *     for what we care about
  * @ofs: the memory segment offset
  * @len: the memory segment length, in bytes
  *
index 5f229556339a45f9d621e195974c8c5e9bb534b1..d323b70b510a1f5d795a56b82be267567b71360f 100644 (file)
@@ -132,7 +132,8 @@ struct fw_desc {
 };
 
 struct fw_img {
-       struct fw_desc sec[IWL_UCODE_SECTION_MAX];
+       struct fw_desc *sec;
+       int num_sec;
        bool is_dual_cpus;
        u32 paging_mem_size;
 };
@@ -295,8 +296,8 @@ struct iwl_fw {
        struct iwl_fw_dbg_conf_tlv *dbg_conf_tlv[FW_DBG_CONF_MAX];
        size_t dbg_conf_tlv_len[FW_DBG_CONF_MAX];
        struct iwl_fw_dbg_trigger_tlv *dbg_trigger_tlv[FW_DBG_TRIGGER_MAX];
-       struct iwl_fw_dbg_mem_seg_tlv *dbg_mem_tlv[FW_DBG_MEM_MAX];
-       bool dbg_dynamic_mem;
+       struct iwl_fw_dbg_mem_seg_tlv *dbg_mem_tlv;
+       size_t n_dbg_mem_tlv;
        size_t dbg_trigger_tlv_len[FW_DBG_TRIGGER_MAX];
        u8 dbg_dest_reg_num;
        struct iwl_gscan_capabilities gscan_capa;
index b88e2048ae0baa207406972c618a28c7db4026e4..207d8ae1e1160d6239a537981d30e659161fc40d 100644 (file)
@@ -1262,12 +1262,15 @@ static int __iwl_mvm_suspend(struct ieee80211_hw *hw,
        iwl_trans_d3_suspend(mvm->trans, test, !unified_image);
  out:
        if (ret < 0) {
-               iwl_mvm_ref(mvm, IWL_MVM_REF_UCODE_DOWN);
-               if (mvm->restart_fw > 0) {
-                       mvm->restart_fw--;
-                       ieee80211_restart_hw(mvm->hw);
-               }
                iwl_mvm_free_nd(mvm);
+
+               if (!unified_image) {
+                       iwl_mvm_ref(mvm, IWL_MVM_REF_UCODE_DOWN);
+                       if (mvm->restart_fw > 0) {
+                               mvm->restart_fw--;
+                               ieee80211_restart_hw(mvm->hw);
+                       }
+               }
        }
  out_noreset:
        mutex_unlock(&mvm->mutex);
index 7b7d2a146e3020a286da8f7acc9a97d005142ce8..a260cd5032005bcbf520e98f8be188750c987439 100644 (file)
@@ -798,7 +798,7 @@ static ssize_t iwl_dbgfs_drv_rx_stats_read(struct file *file,
 static ssize_t iwl_dbgfs_fw_restart_write(struct iwl_mvm *mvm, char *buf,
                                          size_t count, loff_t *ppos)
 {
-       int ret;
+       int __maybe_unused ret;
 
        mutex_lock(&mvm->mutex);
 
index ae12badc0c2ab7dd08451d3432528274936125b8..567597c261152edb91485f5fa68793f1c2742eea 100644 (file)
@@ -2075,7 +2075,7 @@ struct iwl_mu_group_mgmt_notif {
  * @system_time: system time on air rise
  * @tsf: TSF on air rise
  * @beacon_timestamp: beacon on air rise
- * @phy_flags: general phy flags: band, modulation, etc.
+ * @band: band, matches &RX_RES_PHY_FLAGS_BAND_24 definition
  * @channel: channel this beacon was received on
  * @rates: rate in ucode internal format
  * @byte_count: frame's byte count
@@ -2084,12 +2084,12 @@ struct iwl_stored_beacon_notif {
        __le32 system_time;
        __le64 tsf;
        __le32 beacon_timestamp;
-       __le16 phy_flags;
+       __le16 band;
        __le16 channel;
        __le32 rates;
        __le32 byte_count;
        u8 data[MAX_STORED_BEACON_SIZE];
-} __packed; /* WOWLAN_STROED_BEACON_INFO_S_VER_1 */
+} __packed; /* WOWLAN_STROED_BEACON_INFO_S_VER_2 */
 
 #define LQM_NUMBER_OF_STATIONS_IN_REPORT 16
 
index 2e8e3e8e30a329afc9c5b962739990ebea97fb1e..e7b3b712d77833ee7ef079bbac9ec158e1afe90d 100644 (file)
@@ -406,46 +406,63 @@ static const struct iwl_prph_range iwl_prph_dump_addr_9000[] = {
        { .start = 0x00a02400, .end = 0x00a02758 },
 };
 
-static u32 iwl_dump_prph(struct iwl_trans *trans,
-                        struct iwl_fw_error_dump_data **data,
-                        const struct iwl_prph_range *iwl_prph_dump_addr,
-                        u32 range_len)
+static void _iwl_read_prph_block(struct iwl_trans *trans, u32 start,
+                                u32 len_bytes, __le32 *data)
+{
+       u32 i;
+
+       for (i = 0; i < len_bytes; i += 4)
+               *data++ = cpu_to_le32(iwl_read_prph_no_grab(trans, start + i));
+}
+
+static bool iwl_read_prph_block(struct iwl_trans *trans, u32 start,
+                               u32 len_bytes, __le32 *data)
+{
+       unsigned long flags;
+       bool success = false;
+
+       if (iwl_trans_grab_nic_access(trans, &flags)) {
+               success = true;
+               _iwl_read_prph_block(trans, start, len_bytes, data);
+               iwl_trans_release_nic_access(trans, &flags);
+       }
+
+       return success;
+}
+
+static void iwl_dump_prph(struct iwl_trans *trans,
+                         struct iwl_fw_error_dump_data **data,
+                         const struct iwl_prph_range *iwl_prph_dump_addr,
+                         u32 range_len)
 {
        struct iwl_fw_error_dump_prph *prph;
        unsigned long flags;
-       u32 prph_len = 0, i;
+       u32 i;
 
        if (!iwl_trans_grab_nic_access(trans, &flags))
-               return 0;
+               return;
 
        for (i = 0; i < range_len; i++) {
                /* The range includes both boundaries */
                int num_bytes_in_chunk = iwl_prph_dump_addr[i].end -
                         iwl_prph_dump_addr[i].start + 4;
-               int reg;
-               __le32 *val;
-
-               prph_len += sizeof(**data) + sizeof(*prph) + num_bytes_in_chunk;
 
                (*data)->type = cpu_to_le32(IWL_FW_ERROR_DUMP_PRPH);
                (*data)->len = cpu_to_le32(sizeof(*prph) +
                                        num_bytes_in_chunk);
                prph = (void *)(*data)->data;
                prph->prph_start = cpu_to_le32(iwl_prph_dump_addr[i].start);
-               val = (void *)prph->data;
 
-               for (reg = iwl_prph_dump_addr[i].start;
-                    reg <= iwl_prph_dump_addr[i].end;
-                    reg += 4)
-                       *val++ = cpu_to_le32(iwl_read_prph_no_grab(trans,
-                                                                  reg));
+               _iwl_read_prph_block(trans, iwl_prph_dump_addr[i].start,
+                                    /* our range is inclusive, hence + 4 */
+                                    iwl_prph_dump_addr[i].end -
+                                    iwl_prph_dump_addr[i].start + 4,
+                                    (void *)prph->data);
 
                *data = iwl_fw_error_next_data(*data);
        }
 
        iwl_trans_release_nic_access(trans, &flags);
-
-       return prph_len;
 }
 
 /*
@@ -495,11 +512,10 @@ void iwl_mvm_fw_error_dump(struct iwl_mvm *mvm)
        struct iwl_mvm_dump_ptrs *fw_error_dump;
        struct scatterlist *sg_dump_data;
        u32 sram_len, sram_ofs;
-       struct iwl_fw_dbg_mem_seg_tlv * const *fw_dbg_mem =
-               mvm->fw->dbg_mem_tlv;
+       const struct iwl_fw_dbg_mem_seg_tlv *fw_dbg_mem = mvm->fw->dbg_mem_tlv;
        u32 file_len, fifo_data_len = 0, prph_len = 0, radio_len = 0;
-       u32 smem_len = mvm->fw->dbg_dynamic_mem ? 0 : mvm->cfg->smem_len;
-       u32 sram2_len = mvm->fw->dbg_dynamic_mem ? 0 : mvm->cfg->dccm2_len;
+       u32 smem_len = mvm->fw->n_dbg_mem_tlv ? 0 : mvm->cfg->smem_len;
+       u32 sram2_len = mvm->fw->n_dbg_mem_tlv ? 0 : mvm->cfg->dccm2_len;
        bool monitor_dump_only = false;
        int i;
 
@@ -624,10 +640,9 @@ void iwl_mvm_fw_error_dump(struct iwl_mvm *mvm)
                file_len += sizeof(*dump_data) + sizeof(*dump_mem) + sram2_len;
 
        /* Make room for MEM segments */
-       for (i = 0; i < ARRAY_SIZE(mvm->fw->dbg_mem_tlv); i++) {
-               if (fw_dbg_mem[i])
-                       file_len += sizeof(*dump_data) + sizeof(*dump_mem) +
-                               le32_to_cpu(fw_dbg_mem[i]->len);
+       for (i = 0; i < mvm->fw->n_dbg_mem_tlv; i++) {
+               file_len += sizeof(*dump_data) + sizeof(*dump_mem) +
+                           le32_to_cpu(fw_dbg_mem[i].len);
        }
 
        /* Make room for fw's virtual image pages, if it exists */
@@ -656,7 +671,7 @@ void iwl_mvm_fw_error_dump(struct iwl_mvm *mvm)
                file_len += sizeof(*dump_data) + sizeof(*dump_trig) +
                            mvm->fw_dump_desc->len;
 
-       if (!mvm->fw->dbg_dynamic_mem)
+       if (!mvm->fw->n_dbg_mem_tlv)
                file_len += sram_len + sizeof(*dump_mem);
 
        dump_file = vzalloc(file_len);
@@ -708,7 +723,7 @@ void iwl_mvm_fw_error_dump(struct iwl_mvm *mvm)
        if (monitor_dump_only)
                goto dump_trans_data;
 
-       if (!mvm->fw->dbg_dynamic_mem) {
+       if (!mvm->fw->n_dbg_mem_tlv) {
                dump_data->type = cpu_to_le32(IWL_FW_ERROR_DUMP_MEM);
                dump_data->len = cpu_to_le32(sram_len + sizeof(*dump_mem));
                dump_mem = (void *)dump_data->data;
@@ -719,22 +734,39 @@ void iwl_mvm_fw_error_dump(struct iwl_mvm *mvm)
                dump_data = iwl_fw_error_next_data(dump_data);
        }
 
-       for (i = 0; i < ARRAY_SIZE(mvm->fw->dbg_mem_tlv); i++) {
-               if (fw_dbg_mem[i]) {
-                       u32 len = le32_to_cpu(fw_dbg_mem[i]->len);
-                       u32 ofs = le32_to_cpu(fw_dbg_mem[i]->ofs);
-
-                       dump_data->type = cpu_to_le32(IWL_FW_ERROR_DUMP_MEM);
-                       dump_data->len = cpu_to_le32(len +
-                                       sizeof(*dump_mem));
-                       dump_mem = (void *)dump_data->data;
-                       dump_mem->type = fw_dbg_mem[i]->data_type;
-                       dump_mem->offset = cpu_to_le32(ofs);
+       for (i = 0; i < mvm->fw->n_dbg_mem_tlv; i++) {
+               u32 len = le32_to_cpu(fw_dbg_mem[i].len);
+               u32 ofs = le32_to_cpu(fw_dbg_mem[i].ofs);
+               bool success;
+
+               dump_data->type = cpu_to_le32(IWL_FW_ERROR_DUMP_MEM);
+               dump_data->len = cpu_to_le32(len + sizeof(*dump_mem));
+               dump_mem = (void *)dump_data->data;
+               dump_mem->type = fw_dbg_mem[i].data_type;
+               dump_mem->offset = cpu_to_le32(ofs);
+
+               switch (dump_mem->type & cpu_to_le32(FW_DBG_MEM_TYPE_MASK)) {
+               case cpu_to_le32(FW_DBG_MEM_TYPE_REGULAR):
                        iwl_trans_read_mem_bytes(mvm->trans, ofs,
                                                 dump_mem->data,
                                                 len);
-                       dump_data = iwl_fw_error_next_data(dump_data);
+                       success = true;
+                       break;
+               case cpu_to_le32(FW_DBG_MEM_TYPE_PRPH):
+                       success = iwl_read_prph_block(mvm->trans, ofs, len,
+                                                     (void *)dump_mem->data);
+                       break;
+               default:
+                       /*
+                        * shouldn't get here, we ignored this kind
+                        * of TLV earlier during the TLV parsing?!
+                        */
+                       WARN_ON(1);
+                       success = false;
                }
+
+               if (success)
+                       dump_data = iwl_fw_error_next_data(dump_data);
        }
 
        if (smem_len) {
@@ -816,11 +848,12 @@ dump_trans_data:
                                     sg_nents(sg_dump_data),
                                     fw_error_dump->op_mode_ptr,
                                     fw_error_dump->op_mode_len, 0);
-               sg_pcopy_from_buffer(sg_dump_data,
-                                    sg_nents(sg_dump_data),
-                                    fw_error_dump->trans_ptr->data,
-                                    fw_error_dump->trans_ptr->len,
-                                    fw_error_dump->op_mode_len);
+               if (fw_error_dump->trans_ptr)
+                       sg_pcopy_from_buffer(sg_dump_data,
+                                            sg_nents(sg_dump_data),
+                                            fw_error_dump->trans_ptr->data,
+                                            fw_error_dump->trans_ptr->len,
+                                            fw_error_dump->op_mode_len);
                dev_coredumpsg(mvm->trans->dev, sg_dump_data, file_len,
                               GFP_KERNEL);
        }
index 872066317fa5a88c5c21584560aa81c7b67ae239..b278e44e97add715b29fdb951d26228376e4400a 100644 (file)
@@ -190,7 +190,7 @@ static int iwl_fill_paging_mem(struct iwl_mvm *mvm, const struct fw_img *image)
         * CPU2 paging CSS
         * CPU2 paging image (including instruction and data)
         */
-       for (sec_idx = 0; sec_idx < IWL_UCODE_SECTION_MAX; sec_idx++) {
+       for (sec_idx = 0; sec_idx < image->num_sec; sec_idx++) {
                if (image->sec[sec_idx].offset == PAGING_SEPARATOR_SECTION) {
                        sec_idx++;
                        break;
@@ -201,7 +201,7 @@ static int iwl_fill_paging_mem(struct iwl_mvm *mvm, const struct fw_img *image)
         * If paging is enabled there should be at least 2 more sections left
         * (one for CSS and one for Paging data)
         */
-       if (sec_idx >= ARRAY_SIZE(image->sec) - 1) {
+       if (sec_idx >= image->num_sec - 1) {
                IWL_ERR(mvm, "Paging: Missing CSS and/or paging sections\n");
                iwl_free_fw_paging(mvm);
                return -EINVAL;
@@ -259,9 +259,7 @@ static int iwl_alloc_fw_paging_mem(struct iwl_mvm *mvm,
 {
        struct page *block;
        dma_addr_t phys = 0;
-       int blk_idx = 0;
-       int order, num_of_pages;
-       int dma_enabled;
+       int blk_idx, order, num_of_pages, size, dma_enabled;
 
        if (mvm->fw_paging_db[0].fw_paging_block)
                return 0;
@@ -272,9 +270,8 @@ static int iwl_alloc_fw_paging_mem(struct iwl_mvm *mvm,
        BUILD_BUG_ON(BIT(BLOCK_2_EXP_SIZE) != PAGING_BLOCK_SIZE);
 
        num_of_pages = image->paging_mem_size / FW_PAGING_SIZE;
-       mvm->num_of_paging_blk = ((num_of_pages - 1) /
-                                   NUM_OF_PAGE_PER_GROUP) + 1;
-
+       mvm->num_of_paging_blk =
+               DIV_ROUND_UP(num_of_pages, NUM_OF_PAGE_PER_GROUP);
        mvm->num_of_pages_in_last_blk =
                num_of_pages -
                NUM_OF_PAGE_PER_GROUP * (mvm->num_of_paging_blk - 1);
@@ -284,46 +281,13 @@ static int iwl_alloc_fw_paging_mem(struct iwl_mvm *mvm,
                     mvm->num_of_paging_blk,
                     mvm->num_of_pages_in_last_blk);
 
-       /* allocate block of 4Kbytes for paging CSS */
-       order = get_order(FW_PAGING_SIZE);
-       block = alloc_pages(GFP_KERNEL, order);
-       if (!block) {
-               /* free all the previous pages since we failed */
-               iwl_free_fw_paging(mvm);
-               return -ENOMEM;
-       }
-
-       mvm->fw_paging_db[blk_idx].fw_paging_block = block;
-       mvm->fw_paging_db[blk_idx].fw_paging_size = FW_PAGING_SIZE;
-
-       if (dma_enabled) {
-               phys = dma_map_page(mvm->trans->dev, block, 0,
-                                   PAGE_SIZE << order, DMA_BIDIRECTIONAL);
-               if (dma_mapping_error(mvm->trans->dev, phys)) {
-                       /*
-                        * free the previous pages and the current one since
-                        * we failed to map_page.
-                        */
-                       iwl_free_fw_paging(mvm);
-                       return -ENOMEM;
-               }
-               mvm->fw_paging_db[blk_idx].fw_paging_phys = phys;
-       } else {
-               mvm->fw_paging_db[blk_idx].fw_paging_phys = PAGING_ADDR_SIG |
-                       blk_idx << BLOCK_2_EXP_SIZE;
-       }
-
-       IWL_DEBUG_FW(mvm,
-                    "Paging: allocated 4K(CSS) bytes (order %d) for firmware paging.\n",
-                    order);
-
        /*
-        * allocate blocks in dram.
-        * since that CSS allocated in fw_paging_db[0] loop start from index 1
+        * Allocate CSS and paging blocks in dram.
         */
-       for (blk_idx = 1; blk_idx < mvm->num_of_paging_blk + 1; blk_idx++) {
-               /* allocate block of PAGING_BLOCK_SIZE (32K) */
-               order = get_order(PAGING_BLOCK_SIZE);
+       for (blk_idx = 0; blk_idx < mvm->num_of_paging_blk + 1; blk_idx++) {
+               /* For CSS allocate 4KB, for others PAGING_BLOCK_SIZE (32K) */
+               size = blk_idx ? PAGING_BLOCK_SIZE : FW_PAGING_SIZE;
+               order = get_order(size);
                block = alloc_pages(GFP_KERNEL, order);
                if (!block) {
                        /* free all the previous pages since we failed */
@@ -332,7 +296,7 @@ static int iwl_alloc_fw_paging_mem(struct iwl_mvm *mvm,
                }
 
                mvm->fw_paging_db[blk_idx].fw_paging_block = block;
-               mvm->fw_paging_db[blk_idx].fw_paging_size = PAGING_BLOCK_SIZE;
+               mvm->fw_paging_db[blk_idx].fw_paging_size = size;
 
                if (dma_enabled) {
                        phys = dma_map_page(mvm->trans->dev, block, 0,
@@ -353,9 +317,14 @@ static int iwl_alloc_fw_paging_mem(struct iwl_mvm *mvm,
                                blk_idx << BLOCK_2_EXP_SIZE;
                }
 
-               IWL_DEBUG_FW(mvm,
-                            "Paging: allocated 32K bytes (order %d) for firmware paging.\n",
-                            order);
+               if (!blk_idx)
+                       IWL_DEBUG_FW(mvm,
+                                    "Paging: allocated 4K(CSS) bytes (order %d) for firmware paging.\n",
+                                    order);
+               else
+                       IWL_DEBUG_FW(mvm,
+                                    "Paging: allocated 32K bytes (order %d) for firmware paging.\n",
+                                    order);
        }
 
        return 0;
index 4a0874e4073169632e45b8e09e9a3ff98343594e..ebf6c071eb365c450e5ccc41e0924e0470a1726e 100644 (file)
@@ -1565,7 +1565,7 @@ void iwl_mvm_rx_stored_beacon_notif(struct iwl_mvm *mvm,
        rx_status.flag |= RX_FLAG_MACTIME_PLCP_START;
        rx_status.device_timestamp = le32_to_cpu(sb->system_time);
        rx_status.band =
-               (sb->phy_flags & cpu_to_le16(RX_RES_PHY_FLAGS_BAND_24)) ?
+               (sb->band & cpu_to_le16(RX_RES_PHY_FLAGS_BAND_24)) ?
                                NL80211_BAND_2GHZ : NL80211_BAND_5GHZ;
        rx_status.freq =
                ieee80211_channel_to_frequency(le16_to_cpu(sb->channel),
index 45122dafe9226278abed80ebcba6cd5b49b19f4c..71f9aa9f7c7d62542865af5faefa7bbce296275b 100644 (file)
@@ -463,6 +463,13 @@ int iwl_mvm_mac_setup_register(struct iwl_mvm *mvm)
                                    IEEE80211_RADIOTAP_MCS_HAVE_STBC;
        hw->radiotap_vht_details |= IEEE80211_RADIOTAP_VHT_KNOWN_STBC |
                IEEE80211_RADIOTAP_VHT_KNOWN_BEAMFORMED;
+
+       hw->radiotap_timestamp.units_pos =
+               IEEE80211_RADIOTAP_TIMESTAMP_UNIT_US |
+               IEEE80211_RADIOTAP_TIMESTAMP_SPOS_PLCP_SIG_ACQ;
+       /* this is the case for CCK frames, it's better (only 8) for OFDM */
+       hw->radiotap_timestamp.accuracy = 22;
+
        hw->rate_control_algorithm = "iwl-mvm-rs";
        hw->uapsd_queues = IWL_MVM_UAPSD_QUEUES;
        hw->uapsd_max_sp_len = IWL_UAPSD_MAX_SP;
@@ -670,7 +677,7 @@ int iwl_mvm_mac_setup_register(struct iwl_mvm *mvm)
                hw->wiphy->wowlan = &mvm->wowlan;
        }
 
-       if (mvm->fw->img[IWL_UCODE_WOWLAN].sec[0].len &&
+       if (mvm->fw->img[IWL_UCODE_WOWLAN].num_sec &&
            mvm->trans->ops->d3_suspend &&
            mvm->trans->ops->d3_resume &&
            device_can_wakeup(mvm->trans->dev)) {
index 4a9cb76b7611d29fd1dd8dcfd8c00e24a9158c4f..a672aa71c656263a2acc056d0304451b974fc418 100644 (file)
@@ -1657,8 +1657,8 @@ void iwl_mvm_enable_txq(struct iwl_mvm *mvm, int queue, int mac80211_queue,
  * Disable a TXQ.
  * Note that in non-DQA mode the %mac80211_queue and %tid params are ignored.
  */
-void iwl_mvm_disable_txq(struct iwl_mvm *mvm, int queue, int mac80211_queue,
-                        u8 tid, u8 flags);
+int iwl_mvm_disable_txq(struct iwl_mvm *mvm, int queue, int mac80211_queue,
+                       u8 tid, u8 flags);
 int iwl_mvm_find_free_queue(struct iwl_mvm *mvm, u8 sta_id, u8 minq, u8 maxq);
 
 /* Return a bitmask with all the hw supported queues, except for the
index 227c5ed9cbe6366611682c717d81336df83318d3..80f99c365b6ad83a9679f246adaa72b307c8c4b5 100644 (file)
@@ -161,9 +161,6 @@ static bool rs_mimo_allow(struct iwl_mvm *mvm, struct ieee80211_sta *sta,
                          struct rs_rate *rate,
                          const struct rs_tx_column *next_col)
 {
-       struct iwl_mvm_sta *mvmsta;
-       struct iwl_mvm_vif *mvmvif;
-
        if (!sta->ht_cap.ht_supported)
                return false;
 
@@ -176,9 +173,6 @@ static bool rs_mimo_allow(struct iwl_mvm *mvm, struct ieee80211_sta *sta,
        if (!iwl_mvm_bt_coex_is_mimo_allowed(mvm, sta))
                return false;
 
-       mvmsta = iwl_mvm_sta_from_mac80211(sta);
-       mvmvif = iwl_mvm_vif_from_mac80211(mvmsta->vif);
-
        if (mvm->nvm_data->sku_cap_mimo_disabled)
                return false;
 
@@ -3071,7 +3065,7 @@ static void iwl_mvm_reset_frame_stats(struct iwl_mvm *mvm)
 
 void iwl_mvm_update_frame_stats(struct iwl_mvm *mvm, u32 rate, bool agg)
 {
-       u8 nss = 0, mcs = 0;
+       u8 nss = 0;
 
        spin_lock(&mvm->drv_stats_lock);
 
@@ -3099,11 +3093,9 @@ void iwl_mvm_update_frame_stats(struct iwl_mvm *mvm, u32 rate, bool agg)
 
        if (rate & RATE_MCS_HT_MSK) {
                mvm->drv_rx_stats.ht_frames++;
-               mcs = rate & RATE_HT_MCS_RATE_CODE_MSK;
                nss = ((rate & RATE_HT_MCS_NSS_MSK) >> RATE_HT_MCS_NSS_POS) + 1;
        } else if (rate & RATE_MCS_VHT_MSK) {
                mvm->drv_rx_stats.vht_frames++;
-               mcs = rate & RATE_VHT_MCS_RATE_CODE_MSK;
                nss = ((rate & RATE_VHT_MCS_NSS_MSK) >>
                       RATE_VHT_MCS_NSS_POS) + 1;
        } else {
index 0e60e38b2acf058aef19954ae6e9ccacb2ed0f3e..e16687d5afaa9dda6ed64394cd3ce7ed3248c8e3 100644 (file)
@@ -621,12 +621,10 @@ void iwl_mvm_handle_rx_statistics(struct iwl_mvm *mvm,
        };
        int expected_size = iwl_mvm_has_new_rx_api(mvm) ? sizeof(*stats) :
                            sizeof(struct iwl_notif_statistics_v10);
-       u32 temperature;
 
        if (iwl_rx_packet_payload_len(pkt) != expected_size)
                goto invalid;
 
-       temperature = le32_to_cpu(stats->general.radio_temperature);
        data.mac_id = stats->rx.general.mac_id;
        data.beacon_filter_average_energy =
                stats->general.beacon_filter_average_energy;
index 636c8b03e31892bd30e3a3d7a6b1e9b8a8eb02ea..40e7fc5f1f1f522cecdb6d427ba0ef5ee6c9933d 100644 (file)
@@ -454,13 +454,6 @@ static int iwl_mvm_remove_sta_queue_marking(struct iwl_mvm *mvm, int queue)
 
        rcu_read_unlock();
 
-       spin_lock_bh(&mvm->queue_info_lock);
-       /* Unmap MAC queues and TIDs from this queue */
-       mvm->queue_info[queue].hw_queue_to_mac80211 = 0;
-       mvm->queue_info[queue].hw_queue_refcount = 0;
-       mvm->queue_info[queue].tid_bitmap = 0;
-       spin_unlock_bh(&mvm->queue_info_lock);
-
        return disable_agg_tids;
 }
 
@@ -755,28 +748,22 @@ static int iwl_mvm_sta_alloc_queue(struct iwl_mvm *mvm,
         * first
         */
        if (using_inactive_queue) {
-               struct iwl_scd_txq_cfg_cmd cmd = {
-                       .scd_queue = queue,
-                       .action = SCD_CFG_DISABLE_QUEUE,
-               };
-               u8 txq_curr_ac;
-
-               disable_agg_tids = iwl_mvm_remove_sta_queue_marking(mvm, queue);
+               u8 txq_curr_ac, sta_id;
 
                spin_lock_bh(&mvm->queue_info_lock);
                txq_curr_ac = mvm->queue_info[queue].mac80211_ac;
-               cmd.sta_id = mvm->queue_info[queue].ra_sta_id;
-               cmd.tx_fifo = iwl_mvm_ac_to_tx_fifo[txq_curr_ac];
-               cmd.tid = mvm->queue_info[queue].txq_tid;
+               sta_id = mvm->queue_info[queue].ra_sta_id;
                spin_unlock_bh(&mvm->queue_info_lock);
 
+               disable_agg_tids = iwl_mvm_remove_sta_queue_marking(mvm, queue);
                /* Disable the queue */
                if (disable_agg_tids)
                        iwl_mvm_invalidate_sta_queue(mvm, queue,
                                                     disable_agg_tids, false);
-               iwl_trans_txq_disable(mvm->trans, queue, false);
-               ret = iwl_mvm_send_cmd_pdu(mvm, SCD_QUEUE_CFG, 0, sizeof(cmd),
-                                          &cmd);
+
+               ret = iwl_mvm_disable_txq(mvm, queue,
+                                         mvmsta->vif->hw_queue[txq_curr_ac],
+                                         tid, 0);
                if (ret) {
                        IWL_ERR(mvm,
                                "Failed to free inactive queue %d (ret=%d)\n",
@@ -791,7 +778,7 @@ static int iwl_mvm_sta_alloc_queue(struct iwl_mvm *mvm,
                }
 
                /* If TXQ is allocated to another STA, update removal in FW */
-               if (cmd.sta_id != mvmsta->sta_id)
+               if (sta_id != mvmsta->sta_id)
                        iwl_mvm_invalidate_sta_queue(mvm, queue, 0, true);
        }
 
@@ -868,7 +855,6 @@ static void iwl_mvm_change_queue_owner(struct iwl_mvm *mvm, int queue)
                .scd_queue = queue,
                .action = SCD_CFG_UPDATE_QUEUE_TID,
        };
-       s8 sta_id;
        int tid;
        unsigned long tid_bitmap;
        int ret;
@@ -876,7 +862,6 @@ static void iwl_mvm_change_queue_owner(struct iwl_mvm *mvm, int queue)
        lockdep_assert_held(&mvm->mutex);
 
        spin_lock_bh(&mvm->queue_info_lock);
-       sta_id = mvm->queue_info[queue].ra_sta_id;
        tid_bitmap = mvm->queue_info[queue].tid_bitmap;
        spin_unlock_bh(&mvm->queue_info_lock);
 
index 66957ac12ca400d00e9f5b5dcd05b09af02fd4d9..2b2db38eee3e22c9ab5ee2dd05a5e0782e0add09 100644 (file)
@@ -102,14 +102,13 @@ iwl_mvm_bar_check_trigger(struct iwl_mvm *mvm, const u8 *addr,
 #define OPT_HDR(type, skb, off) \
        (type *)(skb_network_header(skb) + (off))
 
-static void iwl_mvm_tx_csum(struct iwl_mvm *mvm, struct sk_buff *skb,
-                           struct ieee80211_hdr *hdr,
-                           struct ieee80211_tx_info *info,
-                           struct iwl_tx_cmd *tx_cmd)
+static u16 iwl_mvm_tx_csum(struct iwl_mvm *mvm, struct sk_buff *skb,
+                          struct ieee80211_hdr *hdr,
+                          struct ieee80211_tx_info *info)
 {
+       u16 offload_assist = 0;
 #if IS_ENABLED(CONFIG_INET)
        u16 mh_len = ieee80211_hdrlen(hdr->frame_control);
-       u16 offload_assist = le16_to_cpu(tx_cmd->offload_assist);
        u8 protocol = 0;
 
        /*
@@ -117,7 +116,7 @@ static void iwl_mvm_tx_csum(struct iwl_mvm *mvm, struct sk_buff *skb,
         * compute it
         */
        if (skb->ip_summed != CHECKSUM_PARTIAL || IWL_MVM_SW_TX_CSUM_OFFLOAD)
-               return;
+               goto out;
 
        /* We do not expect to be requested to csum stuff we do not support */
        if (WARN_ONCE(!(mvm->hw->netdev_features & IWL_TX_CSUM_NETIF_FLAGS) ||
@@ -125,7 +124,7 @@ static void iwl_mvm_tx_csum(struct iwl_mvm *mvm, struct sk_buff *skb,
                       skb->protocol != htons(ETH_P_IPV6)),
                      "No support for requested checksum\n")) {
                skb_checksum_help(skb);
-               return;
+               goto out;
        }
 
        if (skb->protocol == htons(ETH_P_IP)) {
@@ -145,7 +144,7 @@ static void iwl_mvm_tx_csum(struct iwl_mvm *mvm, struct sk_buff *skb,
                            protocol != NEXTHDR_HOP &&
                            protocol != NEXTHDR_DEST) {
                                skb_checksum_help(skb);
-                               return;
+                               goto out;
                        }
 
                        hp = OPT_HDR(struct ipv6_opt_hdr, skb, off);
@@ -159,7 +158,7 @@ static void iwl_mvm_tx_csum(struct iwl_mvm *mvm, struct sk_buff *skb,
        if (protocol != IPPROTO_TCP && protocol != IPPROTO_UDP) {
                WARN_ON_ONCE(1);
                skb_checksum_help(skb);
-               return;
+               goto out;
        }
 
        /* enable L4 csum */
@@ -191,8 +190,9 @@ static void iwl_mvm_tx_csum(struct iwl_mvm *mvm, struct sk_buff *skb,
        mh_len /= 2;
        offload_assist |= mh_len << TX_CMD_OFFLD_MH_SIZE;
 
-       tx_cmd->offload_assist = cpu_to_le16(offload_assist);
+out:
 #endif
+       return offload_assist;
 }
 
 /*
@@ -295,7 +295,52 @@ void iwl_mvm_set_tx_cmd(struct iwl_mvm *mvm, struct sk_buff *skb,
            !(tx_cmd->offload_assist & cpu_to_le16(BIT(TX_CMD_OFFLD_AMSDU))))
                tx_cmd->offload_assist |= cpu_to_le16(BIT(TX_CMD_OFFLD_PAD));
 
-       iwl_mvm_tx_csum(mvm, skb, hdr, info, tx_cmd);
+       tx_cmd->offload_assist |=
+               cpu_to_le16(iwl_mvm_tx_csum(mvm, skb, hdr, info));
+}
+
+static u32 iwl_mvm_get_tx_rate(struct iwl_mvm *mvm,
+                              struct ieee80211_tx_info *info,
+                              struct ieee80211_sta *sta)
+{
+       int rate_idx;
+       u8 rate_plcp;
+       u32 rate_flags;
+
+       /* HT rate doesn't make sense for a non data frame */
+       WARN_ONCE(info->control.rates[0].flags & IEEE80211_TX_RC_MCS,
+                 "Got an HT rate (flags:0x%x/mcs:%d) for a non data frame\n",
+                 info->control.rates[0].flags,
+                 info->control.rates[0].idx);
+
+       rate_idx = info->control.rates[0].idx;
+       /* if the rate isn't a well known legacy rate, take the lowest one */
+       if (rate_idx < 0 || rate_idx >= IWL_RATE_COUNT_LEGACY)
+               rate_idx = rate_lowest_index(
+                               &mvm->nvm_data->bands[info->band], sta);
+
+       /* For 5 GHZ band, remap mac80211 rate indices into driver indices */
+       if (info->band == NL80211_BAND_5GHZ)
+               rate_idx += IWL_FIRST_OFDM_RATE;
+
+       /* For 2.4 GHZ band, check that there is no need to remap */
+       BUILD_BUG_ON(IWL_FIRST_CCK_RATE != 0);
+
+       /* Get PLCP rate for tx_cmd->rate_n_flags */
+       rate_plcp = iwl_mvm_mac80211_idx_to_hwrate(rate_idx);
+
+       if (info->band == NL80211_BAND_2GHZ &&
+           !iwl_mvm_bt_coex_is_shared_ant_avail(mvm))
+               rate_flags = mvm->cfg->non_shared_ant << RATE_MCS_ANT_POS;
+       else
+               rate_flags =
+                       BIT(mvm->mgmt_last_antenna_idx) << RATE_MCS_ANT_POS;
+
+       /* Set CCK flag as needed */
+       if ((rate_idx >= IWL_FIRST_CCK_RATE) && (rate_idx <= IWL_LAST_CCK_RATE))
+               rate_flags |= RATE_MCS_CCK_MSK;
+
+       return (u32)rate_plcp | rate_flags;
 }
 
 /*
@@ -305,10 +350,6 @@ void iwl_mvm_set_tx_cmd_rate(struct iwl_mvm *mvm, struct iwl_tx_cmd *tx_cmd,
                            struct ieee80211_tx_info *info,
                            struct ieee80211_sta *sta, __le16 fc)
 {
-       u32 rate_flags;
-       int rate_idx;
-       u8 rate_plcp;
-
        /* Set retry limit on RTS packets */
        tx_cmd->rts_retry_limit = IWL_RTS_DFAULT_RETRY_LIMIT;
 
@@ -337,46 +378,12 @@ void iwl_mvm_set_tx_cmd_rate(struct iwl_mvm *mvm, struct iwl_tx_cmd *tx_cmd,
                        cpu_to_le32(TX_CMD_FLG_ACK | TX_CMD_FLG_BAR);
        }
 
-       /* HT rate doesn't make sense for a non data frame */
-       WARN_ONCE(info->control.rates[0].flags & IEEE80211_TX_RC_MCS,
-                 "Got an HT rate (flags:0x%x/mcs:%d) for a non data frame (fc:0x%x)\n",
-                 info->control.rates[0].flags,
-                 info->control.rates[0].idx,
-                 le16_to_cpu(fc));
-
-       rate_idx = info->control.rates[0].idx;
-       /* if the rate isn't a well known legacy rate, take the lowest one */
-       if (rate_idx < 0 || rate_idx >= IWL_RATE_COUNT_LEGACY)
-               rate_idx = rate_lowest_index(
-                               &mvm->nvm_data->bands[info->band], sta);
-
-       /* For 5 GHZ band, remap mac80211 rate indices into driver indices */
-       if (info->band == NL80211_BAND_5GHZ)
-               rate_idx += IWL_FIRST_OFDM_RATE;
-
-       /* For 2.4 GHZ band, check that there is no need to remap */
-       BUILD_BUG_ON(IWL_FIRST_CCK_RATE != 0);
-
-       /* Get PLCP rate for tx_cmd->rate_n_flags */
-       rate_plcp = iwl_mvm_mac80211_idx_to_hwrate(rate_idx);
-
        mvm->mgmt_last_antenna_idx =
                iwl_mvm_next_antenna(mvm, iwl_mvm_get_valid_tx_ant(mvm),
                                     mvm->mgmt_last_antenna_idx);
 
-       if (info->band == NL80211_BAND_2GHZ &&
-           !iwl_mvm_bt_coex_is_shared_ant_avail(mvm))
-               rate_flags = mvm->cfg->non_shared_ant << RATE_MCS_ANT_POS;
-       else
-               rate_flags =
-                       BIT(mvm->mgmt_last_antenna_idx) << RATE_MCS_ANT_POS;
-
-       /* Set CCK flag as needed */
-       if ((rate_idx >= IWL_FIRST_CCK_RATE) && (rate_idx <= IWL_LAST_CCK_RATE))
-               rate_flags |= RATE_MCS_CCK_MSK;
-
        /* Set the rate in the TX cmd */
-       tx_cmd->rate_n_flags = cpu_to_le32((u32)rate_plcp | rate_flags);
+       tx_cmd->rate_n_flags = cpu_to_le32(iwl_mvm_get_tx_rate(mvm, info, sta));
 }
 
 static inline void iwl_mvm_set_tx_cmd_pn(struct ieee80211_tx_info *info,
index d04babd99b53803c2a0248d038bcad3fbfab36f0..26b853ef195fd3d012c4e0f3d32a635708477a81 100644 (file)
@@ -693,10 +693,6 @@ void iwl_mvm_enable_txq(struct iwl_mvm *mvm, int queue, int mac80211_queue,
                        .tid = cfg->tid,
                };
 
-               /* Set sta_id in the command, if it exists */
-               if (iwl_mvm_is_dqa_supported(mvm))
-                       cmd.sta_id = cfg->sta_id;
-
                iwl_trans_txq_enable_cfg(mvm->trans, queue, ssn, NULL,
                                         wdg_timeout);
                WARN(iwl_mvm_send_cmd_pdu(mvm, SCD_QUEUE_CFG, 0, sizeof(cmd),
@@ -706,8 +702,8 @@ void iwl_mvm_enable_txq(struct iwl_mvm *mvm, int queue, int mac80211_queue,
        }
 }
 
-void iwl_mvm_disable_txq(struct iwl_mvm *mvm, int queue, int mac80211_queue,
-                        u8 tid, u8 flags)
+int iwl_mvm_disable_txq(struct iwl_mvm *mvm, int queue, int mac80211_queue,
+                       u8 tid, u8 flags)
 {
        struct iwl_scd_txq_cfg_cmd cmd = {
                .scd_queue = queue,
@@ -720,7 +716,7 @@ void iwl_mvm_disable_txq(struct iwl_mvm *mvm, int queue, int mac80211_queue,
 
        if (WARN_ON(mvm->queue_info[queue].hw_queue_refcount == 0)) {
                spin_unlock_bh(&mvm->queue_info_lock);
-               return;
+               return 0;
        }
 
        mvm->queue_info[queue].tid_bitmap &= ~BIT(tid);
@@ -760,7 +756,7 @@ void iwl_mvm_disable_txq(struct iwl_mvm *mvm, int queue, int mac80211_queue,
        /* If the queue is still enabled - nothing left to do in this func */
        if (cmd.action == SCD_CFG_ENABLE_QUEUE) {
                spin_unlock_bh(&mvm->queue_info_lock);
-               return;
+               return 0;
        }
 
        cmd.sta_id = mvm->queue_info[queue].ra_sta_id;
@@ -791,6 +787,8 @@ void iwl_mvm_disable_txq(struct iwl_mvm *mvm, int queue, int mac80211_queue,
        if (ret)
                IWL_ERR(mvm, "Failed to disable queue %d (ret=%d)\n",
                        queue, ret);
+
+       return ret;
 }
 
 /**
index b10e3633df1a91ac67061502a332af0bef3c8014..c1d99d15796d205f0e8abdf4314d678064111723 100644 (file)
@@ -805,7 +805,7 @@ static int iwl_pcie_load_cpu_sections_8000(struct iwl_trans *trans,
                (*first_ucode_section)++;
        }
 
-       for (i = *first_ucode_section; i < IWL_UCODE_SECTION_MAX; i++) {
+       for (i = *first_ucode_section; i < image->num_sec; i++) {
                last_read_idx = i;
 
                /*
@@ -868,19 +868,15 @@ static int iwl_pcie_load_cpu_sections(struct iwl_trans *trans,
                                      int cpu,
                                      int *first_ucode_section)
 {
-       int shift_param;
        int i, ret = 0;
        u32 last_read_idx = 0;
 
-       if (cpu == 1) {
-               shift_param = 0;
+       if (cpu == 1)
                *first_ucode_section = 0;
-       } else {
-               shift_param = 16;
+       else
                (*first_ucode_section)++;
-       }
 
-       for (i = *first_ucode_section; i < IWL_UCODE_SECTION_MAX; i++) {
+       for (i = *first_ucode_section; i < image->num_sec; i++) {
                last_read_idx = i;
 
                /*
@@ -1066,6 +1062,20 @@ static int iwl_pcie_load_given_ucode_8000(struct iwl_trans *trans,
                                               &first_ucode_section);
 }
 
+static bool iwl_trans_check_hw_rf_kill(struct iwl_trans *trans)
+{
+       bool hw_rfkill = iwl_is_rfkill_set(trans);
+
+       if (hw_rfkill)
+               set_bit(STATUS_RFKILL, &trans->status);
+       else
+               clear_bit(STATUS_RFKILL, &trans->status);
+
+       iwl_trans_pcie_rf_kill(trans, hw_rfkill);
+
+       return hw_rfkill;
+}
+
 static void _iwl_trans_pcie_stop_device(struct iwl_trans *trans, bool low_power)
 {
        struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans);
@@ -1208,12 +1218,7 @@ static int iwl_trans_pcie_start_fw(struct iwl_trans *trans,
        mutex_lock(&trans_pcie->mutex);
 
        /* If platform's RF_KILL switch is NOT set to KILL */
-       hw_rfkill = iwl_is_rfkill_set(trans);
-       if (hw_rfkill)
-               set_bit(STATUS_RFKILL, &trans->status);
-       else
-               clear_bit(STATUS_RFKILL, &trans->status);
-       iwl_trans_pcie_rf_kill(trans, hw_rfkill);
+       hw_rfkill = iwl_trans_check_hw_rf_kill(trans);
        if (hw_rfkill && !run_in_rfkill) {
                ret = -ERFKILL;
                goto out;
@@ -1261,13 +1266,7 @@ static int iwl_trans_pcie_start_fw(struct iwl_trans *trans,
                ret = iwl_pcie_load_given_ucode(trans, fw);
 
        /* re-check RF-Kill state since we may have missed the interrupt */
-       hw_rfkill = iwl_is_rfkill_set(trans);
-       if (hw_rfkill)
-               set_bit(STATUS_RFKILL, &trans->status);
-       else
-               clear_bit(STATUS_RFKILL, &trans->status);
-
-       iwl_trans_pcie_rf_kill(trans, hw_rfkill);
+       hw_rfkill = iwl_trans_check_hw_rf_kill(trans);
        if (hw_rfkill && !run_in_rfkill)
                ret = -ERFKILL;
 
@@ -1659,7 +1658,6 @@ static int iwl_pcie_init_msix_handler(struct pci_dev *pdev,
 static int _iwl_trans_pcie_start_hw(struct iwl_trans *trans, bool low_power)
 {
        struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans);
-       bool hw_rfkill;
        int err;
 
        lockdep_assert_held(&trans_pcie->mutex);
@@ -1683,13 +1681,8 @@ static int _iwl_trans_pcie_start_hw(struct iwl_trans *trans, bool low_power)
        /* Set is_down to false here so that...*/
        trans_pcie->is_down = false;
 
-       hw_rfkill = iwl_is_rfkill_set(trans);
-       if (hw_rfkill)
-               set_bit(STATUS_RFKILL, &trans->status);
-       else
-               clear_bit(STATUS_RFKILL, &trans->status);
-       /* ... rfkill can call stop_device and set it false if needed */
-       iwl_trans_pcie_rf_kill(trans, hw_rfkill);
+       /* ...rfkill can call stop_device and set it false if needed */
+       iwl_trans_check_hw_rf_kill(trans);
 
        /* Make sure we sync here, because we'll need full access later */
        if (low_power)
index 301170cccfff7494b95dfa195ac03c3a11fb271e..033ff881c7518109cf0278552af223ea24307f79 100644 (file)
@@ -305,7 +305,7 @@ int lbs_cmd_802_11_sleep_params(struct lbs_private *priv, uint16_t cmd_action,
        }
 
        lbs_deb_leave_args(LBS_DEB_CMD, "ret %d", ret);
-       return 0;
+       return ret;
 }
 
 static int lbs_wait_for_ds_awake(struct lbs_private *priv)
index c47d6366875d06c5c0c3ceb2af29f31bd55e5158..a75013ac84d7ccdd147f68bc9b10cba667cfeb7f 100644 (file)
@@ -101,13 +101,6 @@ mwifiex_11n_form_amsdu_txpd(struct mwifiex_private *priv,
 {
        struct txpd *local_tx_pd;
        struct mwifiex_txinfo *tx_info = MWIFIEX_SKB_TXCB(skb);
-       unsigned int pad;
-       int headroom = (priv->adapter->iface_type ==
-                       MWIFIEX_USB) ? 0 : INTF_HEADER_LEN;
-
-       pad = ((void *)skb->data - sizeof(*local_tx_pd) -
-               headroom - NULL) & (MWIFIEX_DMA_ALIGN_SZ - 1);
-       skb_push(skb, pad);
 
        skb_push(skb, sizeof(*local_tx_pd));
 
@@ -121,12 +114,10 @@ mwifiex_11n_form_amsdu_txpd(struct mwifiex_private *priv,
        local_tx_pd->bss_num = priv->bss_num;
        local_tx_pd->bss_type = priv->bss_type;
        /* Always zero as the data is followed by struct txpd */
-       local_tx_pd->tx_pkt_offset = cpu_to_le16(sizeof(struct txpd) +
-                                                pad);
+       local_tx_pd->tx_pkt_offset = cpu_to_le16(sizeof(struct txpd));
        local_tx_pd->tx_pkt_type = cpu_to_le16(PKT_TYPE_AMSDU);
        local_tx_pd->tx_pkt_length = cpu_to_le16(skb->len -
-                                                sizeof(*local_tx_pd) -
-                                                pad);
+                                                sizeof(*local_tx_pd));
 
        if (tx_info->flags & MWIFIEX_BUF_FLAG_TDLS_PKT)
                local_tx_pd->flags |= MWIFIEX_TXPD_FLAGS_TDLS_PACKET;
@@ -190,7 +181,11 @@ mwifiex_11n_aggregate_pkt(struct mwifiex_private *priv,
                                       ra_list_flags);
                return -1;
        }
-       skb_reserve(skb_aggr, MWIFIEX_MIN_DATA_HEADER_LEN);
+
+       /* skb_aggr->data already 64 byte align, just reserve bus interface
+        * header and txpd.
+        */
+       skb_reserve(skb_aggr, headroom + sizeof(struct txpd));
        tx_info_aggr =  MWIFIEX_SKB_TXCB(skb_aggr);
 
        memset(tx_info_aggr, 0, sizeof(*tx_info_aggr));
index b9284b5332946baa5c23b1a5c71f5b2668851efe..ae2b69db59940b44e3cf7f6dae2075ce28c390ae 100644 (file)
@@ -114,7 +114,8 @@ mwifiex_info_read(struct file *file, char __user *ubuf,
        if (GET_BSS_ROLE(priv) == MWIFIEX_BSS_ROLE_STA) {
                p += sprintf(p, "multicast_count=\"%d\"\n",
                             netdev_mc_count(netdev));
-               p += sprintf(p, "essid=\"%s\"\n", info.ssid.ssid);
+               p += sprintf(p, "essid=\"%.*s\"\n", info.ssid.ssid_len,
+                            info.ssid.ssid);
                p += sprintf(p, "bssid=\"%pM\"\n", info.bssid);
                p += sprintf(p, "channel=\"%d\"\n", (int) info.bss_chan);
                p += sprintf(p, "country_code = \"%s\"\n", info.country_code);
index 55db158fd1565b6001833cc48443beb73a5088fb..cb6a1a81d44e213c7315c4e64a7e2051b4919a62 100644 (file)
@@ -550,6 +550,7 @@ enum mwifiex_channel_flags {
 #define EVENT_TX_DATA_PAUSE             0x00000055
 #define EVENT_EXT_SCAN_REPORT           0x00000058
 #define EVENT_RXBA_SYNC                 0x00000059
+#define EVENT_UNKNOWN_DEBUG             0x00000063
 #define EVENT_BG_SCAN_STOPPED           0x00000065
 #define EVENT_REMAIN_ON_CHAN_EXPIRED    0x0000005f
 #define EVENT_MULTI_CHAN_INFO           0x0000006a
index 0e89ccfa244ef149a73605337213349f190bebb1..756948385b60166cc02f9cd66aeb0584513e67ee 100644 (file)
@@ -409,8 +409,6 @@ static void mwifiex_free_lock_list(struct mwifiex_adapter *adapter)
 static void
 mwifiex_adapter_cleanup(struct mwifiex_adapter *adapter)
 {
-       int idx;
-
        if (!adapter) {
                pr_err("%s: adapter is NULL\n", __func__);
                return;
@@ -428,23 +426,6 @@ mwifiex_adapter_cleanup(struct mwifiex_adapter *adapter)
        mwifiex_dbg(adapter, INFO, "info: free cmd buffer\n");
        mwifiex_free_cmd_buffer(adapter);
 
-       for (idx = 0; idx < adapter->num_mem_types; idx++) {
-               struct memory_type_mapping *entry =
-                               &adapter->mem_type_mapping_tbl[idx];
-
-               if (entry->mem_ptr) {
-                       vfree(entry->mem_ptr);
-                       entry->mem_ptr = NULL;
-               }
-               entry->mem_size = 0;
-       }
-
-       if (adapter->drv_info_dump) {
-               vfree(adapter->drv_info_dump);
-               adapter->drv_info_dump = NULL;
-               adapter->drv_info_size = 0;
-       }
-
        if (adapter->sleep_cfm)
                dev_kfree_skb_any(adapter->sleep_cfm);
 }
@@ -657,10 +638,9 @@ void mwifiex_free_priv(struct mwifiex_private *priv)
  *      - Free the adapter
  *      - Notify completion
  */
-int
+void
 mwifiex_shutdown_drv(struct mwifiex_adapter *adapter)
 {
-       int ret = -EINPROGRESS;
        struct mwifiex_private *priv;
        s32 i;
        unsigned long flags;
@@ -668,15 +648,7 @@ mwifiex_shutdown_drv(struct mwifiex_adapter *adapter)
 
        /* mwifiex already shutdown */
        if (adapter->hw_status == MWIFIEX_HW_STATUS_NOT_READY)
-               return 0;
-
-       adapter->hw_status = MWIFIEX_HW_STATUS_CLOSING;
-       /* wait for mwifiex_process to complete */
-       if (adapter->mwifiex_processing) {
-               mwifiex_dbg(adapter, WARN,
-                           "main process is still running\n");
-               return ret;
-       }
+               return;
 
        /* cancel current command */
        if (adapter->curr_cmd) {
@@ -727,11 +699,7 @@ mwifiex_shutdown_drv(struct mwifiex_adapter *adapter)
        mwifiex_adapter_cleanup(adapter);
 
        spin_unlock(&adapter->mwifiex_lock);
-
-       /* Notify completion */
-       ret = mwifiex_shutdown_fw_complete(adapter);
-
-       return ret;
+       adapter->hw_status = MWIFIEX_HW_STATUS_NOT_READY;
 }
 
 /*
index e5c3a8aa3929ac8e53f228f0e26671e872ac1cff..9d80180a551975f34d5b912289029e4d713eec95 100644 (file)
@@ -248,15 +248,14 @@ int mwifiex_main_process(struct mwifiex_adapter *adapter)
        if (adapter->mwifiex_processing || adapter->main_locked) {
                adapter->more_task_flag = true;
                spin_unlock_irqrestore(&adapter->main_proc_lock, flags);
-               goto exit_main_proc;
+               return 0;
        } else {
                adapter->mwifiex_processing = true;
                spin_unlock_irqrestore(&adapter->main_proc_lock, flags);
        }
 process_start:
        do {
-               if ((adapter->hw_status == MWIFIEX_HW_STATUS_CLOSING) ||
-                   (adapter->hw_status == MWIFIEX_HW_STATUS_NOT_READY))
+               if (adapter->hw_status == MWIFIEX_HW_STATUS_NOT_READY)
                        break;
 
                /* For non-USB interfaces, If we process interrupts first, it
@@ -464,9 +463,6 @@ process_start:
        adapter->mwifiex_processing = false;
        spin_unlock_irqrestore(&adapter->main_proc_lock, flags);
 
-exit_main_proc:
-       if (adapter->hw_status == MWIFIEX_HW_STATUS_CLOSING)
-               mwifiex_shutdown_drv(adapter);
        return ret;
 }
 EXPORT_SYMBOL_GPL(mwifiex_main_process);
@@ -645,16 +641,14 @@ err_dnld_fw:
        if (adapter->if_ops.unregister_dev)
                adapter->if_ops.unregister_dev(adapter);
 
+       adapter->surprise_removed = true;
+       mwifiex_terminate_workqueue(adapter);
+
        if (adapter->hw_status == MWIFIEX_HW_STATUS_READY) {
                pr_debug("info: %s: shutdown mwifiex\n", __func__);
-               adapter->init_wait_q_woken = false;
-
-               if (mwifiex_shutdown_drv(adapter) == -EINPROGRESS)
-                       wait_event_interruptible(adapter->init_wait_q,
-                                                adapter->init_wait_q_woken);
+               mwifiex_shutdown_drv(adapter);
        }
-       adapter->surprise_removed = true;
-       mwifiex_terminate_workqueue(adapter);
+
        init_failed = true;
 done:
        if (adapter->cal_data) {
@@ -1032,7 +1026,7 @@ void mwifiex_multi_chan_resync(struct mwifiex_adapter *adapter)
 }
 EXPORT_SYMBOL_GPL(mwifiex_multi_chan_resync);
 
-void mwifiex_drv_info_dump(struct mwifiex_adapter *adapter)
+int mwifiex_drv_info_dump(struct mwifiex_adapter *adapter, void **drv_info)
 {
        void *p;
        char drv_version[64];
@@ -1042,21 +1036,17 @@ void mwifiex_drv_info_dump(struct mwifiex_adapter *adapter)
        int i, idx;
        struct netdev_queue *txq;
        struct mwifiex_debug_info *debug_info;
-
-       if (adapter->drv_info_dump) {
-               vfree(adapter->drv_info_dump);
-               adapter->drv_info_dump = NULL;
-               adapter->drv_info_size = 0;
-       }
+       void *drv_info_dump;
 
        mwifiex_dbg(adapter, MSG, "===mwifiex driverinfo dump start===\n");
 
-       adapter->drv_info_dump = vzalloc(MWIFIEX_DRV_INFO_SIZE_MAX);
+       /* memory allocate here should be free in mwifiex_upload_device_dump*/
+       drv_info_dump = vzalloc(MWIFIEX_DRV_INFO_SIZE_MAX);
 
-       if (!adapter->drv_info_dump)
-               return;
+       if (!drv_info_dump)
+               return 0;
 
-       p = (char *)(adapter->drv_info_dump);
+       p = (char *)(drv_info_dump);
        p += sprintf(p, "driver_name = " "\"mwifiex\"\n");
 
        mwifiex_drv_get_driver_version(adapter, drv_version,
@@ -1140,18 +1130,20 @@ void mwifiex_drv_info_dump(struct mwifiex_adapter *adapter)
                kfree(debug_info);
        }
 
-       adapter->drv_info_size = p - adapter->drv_info_dump;
        mwifiex_dbg(adapter, MSG, "===mwifiex driverinfo dump end===\n");
+       *drv_info = drv_info_dump;
+       return p - drv_info_dump;
 }
 EXPORT_SYMBOL_GPL(mwifiex_drv_info_dump);
 
-void mwifiex_upload_device_dump(struct mwifiex_adapter *adapter)
+void mwifiex_upload_device_dump(struct mwifiex_adapter *adapter, void *drv_info,
+                               int drv_info_size)
 {
        u8 idx, *dump_data, *fw_dump_ptr;
        u32 dump_len;
 
        dump_len = (strlen("========Start dump driverinfo========\n") +
-                      adapter->drv_info_size +
+                      drv_info_size +
                       strlen("\n========End dump========\n"));
 
        for (idx = 0; idx < adapter->num_mem_types; idx++) {
@@ -1181,8 +1173,8 @@ void mwifiex_upload_device_dump(struct mwifiex_adapter *adapter)
 
        strcpy(fw_dump_ptr, "========Start dump driverinfo========\n");
        fw_dump_ptr += strlen("========Start dump driverinfo========\n");
-       memcpy(fw_dump_ptr, adapter->drv_info_dump, adapter->drv_info_size);
-       fw_dump_ptr += adapter->drv_info_size;
+       memcpy(fw_dump_ptr, drv_info, drv_info_size);
+       fw_dump_ptr += drv_info_size;
        strcpy(fw_dump_ptr, "\n========End dump========\n");
        fw_dump_ptr += strlen("\n========End dump========\n");
 
@@ -1220,18 +1212,12 @@ done:
                struct memory_type_mapping *entry =
                        &adapter->mem_type_mapping_tbl[idx];
 
-               if (entry->mem_ptr) {
-                       vfree(entry->mem_ptr);
-                       entry->mem_ptr = NULL;
-               }
+               vfree(entry->mem_ptr);
+               entry->mem_ptr = NULL;
                entry->mem_size = 0;
        }
 
-       if (adapter->drv_info_dump) {
-               vfree(adapter->drv_info_dump);
-               adapter->drv_info_dump = NULL;
-               adapter->drv_info_size = 0;
-       }
+       vfree(drv_info);
 }
 EXPORT_SYMBOL_GPL(mwifiex_upload_device_dump);
 
@@ -1362,7 +1348,7 @@ static void mwifiex_main_work_queue(struct work_struct *work)
  * This function gets called during PCIe function level reset. Required
  * code is extracted from mwifiex_remove_card()
  */
-static int
+int
 mwifiex_shutdown_sw(struct mwifiex_adapter *adapter)
 {
        struct mwifiex_private *priv;
@@ -1399,11 +1385,8 @@ mwifiex_shutdown_sw(struct mwifiex_adapter *adapter)
        }
 
        mwifiex_dbg(adapter, CMD, "cmd: calling mwifiex_shutdown_drv...\n");
-       adapter->init_wait_q_woken = false;
 
-       if (mwifiex_shutdown_drv(adapter) == -EINPROGRESS)
-               wait_event_interruptible(adapter->init_wait_q,
-                                        adapter->init_wait_q_woken);
+       mwifiex_shutdown_drv(adapter);
        if (adapter->if_ops.down_dev)
                adapter->if_ops.down_dev(adapter);
 
@@ -1434,24 +1417,18 @@ mwifiex_shutdown_sw(struct mwifiex_adapter *adapter)
 exit_return:
        return 0;
 }
+EXPORT_SYMBOL_GPL(mwifiex_shutdown_sw);
 
 /* This function gets called during PCIe function level reset. Required
  * code is extracted from mwifiex_add_card()
  */
-static int
-mwifiex_reinit_sw(struct mwifiex_adapter *adapter, struct completion *fw_done,
-                 struct mwifiex_if_ops *if_ops, u8 iface_type)
+int
+mwifiex_reinit_sw(struct mwifiex_adapter *adapter)
 {
-       char fw_name[32];
-       struct pcie_service_card *card = adapter->card;
-
        mwifiex_init_lock_list(adapter);
        if (adapter->if_ops.up_dev)
                adapter->if_ops.up_dev(adapter);
 
-       adapter->iface_type = iface_type;
-       adapter->fw_done = fw_done;
-
        adapter->hw_status = MWIFIEX_HW_STATUS_INITIALIZING;
        adapter->surprise_removed = false;
        init_waitqueue_head(&adapter->init_wait_q);
@@ -1488,18 +1465,12 @@ mwifiex_reinit_sw(struct mwifiex_adapter *adapter, struct completion *fw_done,
         * mwifiex_register_dev()
         */
        mwifiex_dbg(adapter, INFO, "%s, mwifiex_init_hw_fw()...\n", __func__);
-       strcpy(fw_name, adapter->fw_name);
-       strcpy(adapter->fw_name, PCIE8997_DEFAULT_WIFIFW_NAME);
 
-       adapter->tx_buf_size = card->pcie.tx_buf_size;
-       adapter->ext_scan = card->pcie.can_ext_scan;
        if (mwifiex_init_hw_fw(adapter, false)) {
-               strcpy(adapter->fw_name, fw_name);
                mwifiex_dbg(adapter, ERROR,
                            "%s: firmware init failed\n", __func__);
                goto err_init_fw;
        }
-       strcpy(adapter->fw_name, fw_name);
        mwifiex_dbg(adapter, INFO, "%s, successful\n", __func__);
 
        complete_all(adapter->fw_done);
@@ -1509,43 +1480,22 @@ err_init_fw:
        mwifiex_dbg(adapter, ERROR, "info: %s: unregister device\n", __func__);
        if (adapter->if_ops.unregister_dev)
                adapter->if_ops.unregister_dev(adapter);
+
+err_kmalloc:
+       adapter->surprise_removed = true;
+       mwifiex_terminate_workqueue(adapter);
        if (adapter->hw_status == MWIFIEX_HW_STATUS_READY) {
                mwifiex_dbg(adapter, ERROR,
                            "info: %s: shutdown mwifiex\n", __func__);
-               adapter->init_wait_q_woken = false;
-
-               if (mwifiex_shutdown_drv(adapter) == -EINPROGRESS)
-                       wait_event_interruptible(adapter->init_wait_q,
-                                                adapter->init_wait_q_woken);
+               mwifiex_shutdown_drv(adapter);
        }
 
-err_kmalloc:
-       mwifiex_terminate_workqueue(adapter);
-       adapter->surprise_removed = true;
        complete_all(adapter->fw_done);
        mwifiex_dbg(adapter, INFO, "%s, error\n", __func__);
 
        return -1;
 }
-
-/* This function processes pre and post PCIe function level resets.
- * It performs software cleanup without touching PCIe specific code.
- * Also, during initialization PCIe stuff is skipped.
- */
-void mwifiex_do_flr(struct mwifiex_adapter *adapter, bool prepare)
-{
-       struct mwifiex_if_ops if_ops;
-
-       if (!prepare) {
-               mwifiex_reinit_sw(adapter, adapter->fw_done, &if_ops,
-                                 adapter->iface_type);
-       } else {
-               memcpy(&if_ops, &adapter->if_ops,
-                      sizeof(struct mwifiex_if_ops));
-               mwifiex_shutdown_sw(adapter);
-       }
-}
-EXPORT_SYMBOL_GPL(mwifiex_do_flr);
+EXPORT_SYMBOL_GPL(mwifiex_reinit_sw);
 
 static irqreturn_t mwifiex_irq_wakeup_handler(int irq, void *priv)
 {
@@ -1681,17 +1631,13 @@ err_init_fw:
        pr_debug("info: %s: unregister device\n", __func__);
        if (adapter->if_ops.unregister_dev)
                adapter->if_ops.unregister_dev(adapter);
-       if (adapter->hw_status == MWIFIEX_HW_STATUS_READY) {
-               pr_debug("info: %s: shutdown mwifiex\n", __func__);
-               adapter->init_wait_q_woken = false;
-
-               if (mwifiex_shutdown_drv(adapter) == -EINPROGRESS)
-                       wait_event_interruptible(adapter->init_wait_q,
-                                                adapter->init_wait_q_woken);
-       }
 err_registerdev:
        adapter->surprise_removed = true;
        mwifiex_terminate_workqueue(adapter);
+       if (adapter->hw_status == MWIFIEX_HW_STATUS_READY) {
+               pr_debug("info: %s: shutdown mwifiex\n", __func__);
+               mwifiex_shutdown_drv(adapter);
+       }
 err_kmalloc:
        mwifiex_free_adapter(adapter);
 
@@ -1741,11 +1687,8 @@ int mwifiex_remove_card(struct mwifiex_adapter *adapter)
 
        mwifiex_dbg(adapter, CMD,
                    "cmd: calling mwifiex_shutdown_drv...\n");
-       adapter->init_wait_q_woken = false;
 
-       if (mwifiex_shutdown_drv(adapter) == -EINPROGRESS)
-               wait_event_interruptible(adapter->init_wait_q,
-                                        adapter->init_wait_q_woken);
+       mwifiex_shutdown_drv(adapter);
        mwifiex_dbg(adapter, CMD,
                    "cmd: mwifiex_shutdown_drv done\n");
        if (atomic_read(&adapter->rx_pending) ||
index d552a9d104d08f0adacb01adaf5d72fba2aa9553..5c8297207f339559461f43cee1dc9b0585a23042 100644 (file)
@@ -248,7 +248,6 @@ enum MWIFIEX_HARDWARE_STATUS {
        MWIFIEX_HW_STATUS_INITIALIZING,
        MWIFIEX_HW_STATUS_INIT_DONE,
        MWIFIEX_HW_STATUS_RESET,
-       MWIFIEX_HW_STATUS_CLOSING,
        MWIFIEX_HW_STATUS_NOT_READY
 };
 
@@ -995,8 +994,6 @@ struct mwifiex_adapter {
        u8 key_api_major_ver, key_api_minor_ver;
        struct memory_type_mapping *mem_type_mapping_tbl;
        u8 num_mem_types;
-       void *drv_info_dump;
-       u32 drv_info_size;
        bool scan_chan_gap_enabled;
        struct sk_buff_head rx_data_q;
        bool mfg_mode;
@@ -1041,9 +1038,7 @@ int mwifiex_init_fw(struct mwifiex_adapter *adapter);
 
 int mwifiex_init_fw_complete(struct mwifiex_adapter *adapter);
 
-int mwifiex_shutdown_drv(struct mwifiex_adapter *adapter);
-
-int mwifiex_shutdown_fw_complete(struct mwifiex_adapter *adapter);
+void mwifiex_shutdown_drv(struct mwifiex_adapter *adapter);
 
 int mwifiex_dnld_fw(struct mwifiex_adapter *, struct mwifiex_fw_image *);
 
@@ -1644,8 +1639,9 @@ void mwifiex_hist_data_add(struct mwifiex_private *priv,
 u8 mwifiex_adjust_data_rate(struct mwifiex_private *priv,
                            u8 rx_rate, u8 ht_info);
 
-void mwifiex_drv_info_dump(struct mwifiex_adapter *adapter);
-void mwifiex_upload_device_dump(struct mwifiex_adapter *adapter);
+int mwifiex_drv_info_dump(struct mwifiex_adapter *adapter, void **drv_info);
+void mwifiex_upload_device_dump(struct mwifiex_adapter *adapter, void *drv_info,
+                               int drv_info_size);
 void *mwifiex_alloc_dma_align_buf(int rx_len, gfp_t flags);
 void mwifiex_queue_main_work(struct mwifiex_adapter *adapter);
 int mwifiex_get_wakeup_reason(struct mwifiex_private *priv, u16 action,
@@ -1670,5 +1666,6 @@ void mwifiex_debugfs_remove(void);
 void mwifiex_dev_debugfs_init(struct mwifiex_private *priv);
 void mwifiex_dev_debugfs_remove(struct mwifiex_private *priv);
 #endif
-void mwifiex_do_flr(struct mwifiex_adapter *adapter, bool prepare);
+int mwifiex_reinit_sw(struct mwifiex_adapter *adapter);
+int mwifiex_shutdown_sw(struct mwifiex_adapter *adapter);
 #endif /* !_MWIFIEX_MAIN_H_ */
index 4db07da81d8daaa862a64f660d710cfd323c3fd0..a0d918094889df6cd9de14046b773d6112b2006b 100644 (file)
@@ -31,8 +31,6 @@
 #define PCIE_VERSION   "1.0"
 #define DRV_NAME        "Marvell mwifiex PCIe"
 
-static u8 user_rmmod;
-
 static struct mwifiex_if_ops pcie_ops;
 
 static const struct of_device_id mwifiex_pcie_of_match_table[] = {
@@ -51,6 +49,8 @@ static int mwifiex_pcie_probe_of(struct device *dev)
        return 0;
 }
 
+static void mwifiex_pcie_work(struct work_struct *work);
+
 static int
 mwifiex_map_pci_memory(struct mwifiex_adapter *adapter, struct sk_buff *skb,
                       size_t size, int flags)
@@ -78,6 +78,42 @@ static void mwifiex_unmap_pci_memory(struct mwifiex_adapter *adapter,
        pci_unmap_single(card->dev, mapping.addr, mapping.len, flags);
 }
 
+/*
+ * This function writes data into PCIE card register.
+ */
+static int mwifiex_write_reg(struct mwifiex_adapter *adapter, int reg, u32 data)
+{
+       struct pcie_service_card *card = adapter->card;
+
+       iowrite32(data, card->pci_mmap1 + reg);
+
+       return 0;
+}
+
+/* This function reads data from PCIE card register.
+ */
+static int mwifiex_read_reg(struct mwifiex_adapter *adapter, int reg, u32 *data)
+{
+       struct pcie_service_card *card = adapter->card;
+
+       *data = ioread32(card->pci_mmap1 + reg);
+       if (*data == 0xffffffff)
+               return 0xffffffff;
+
+       return 0;
+}
+
+/* This function reads u8 data from PCIE card register. */
+static int mwifiex_read_reg_byte(struct mwifiex_adapter *adapter,
+                                int reg, u8 *data)
+{
+       struct pcie_service_card *card = adapter->card;
+
+       *data = ioread8(card->pci_mmap1 + reg);
+
+       return 0;
+}
+
 /*
  * This function reads sleep cookie and checks if FW is ready
  */
@@ -219,6 +255,7 @@ static int mwifiex_pcie_probe(struct pci_dev *pdev,
                card->pcie.mem_type_mapping_tbl = data->mem_type_mapping_tbl;
                card->pcie.num_mem_types = data->num_mem_types;
                card->pcie.can_ext_scan = data->can_ext_scan;
+               INIT_WORK(&card->work, mwifiex_pcie_work);
        }
 
        /* device tree node parsing and platform specific configuration*/
@@ -245,6 +282,9 @@ static void mwifiex_pcie_remove(struct pci_dev *pdev)
        struct pcie_service_card *card;
        struct mwifiex_adapter *adapter;
        struct mwifiex_private *priv;
+       const struct mwifiex_pcie_card_reg *reg;
+       u32 fw_status;
+       int ret;
 
        card = pci_get_drvdata(pdev);
 
@@ -254,7 +294,15 @@ static void mwifiex_pcie_remove(struct pci_dev *pdev)
        if (!adapter || !adapter->priv_num)
                return;
 
-       if (user_rmmod && !adapter->mfg_mode) {
+       cancel_work_sync(&card->work);
+
+       reg = card->pcie.reg;
+       if (reg)
+               ret = mwifiex_read_reg(adapter, reg->fw_status, &fw_status);
+       else
+               fw_status = -1;
+
+       if (fw_status == FIRMWARE_READY_PCIE && !adapter->mfg_mode) {
                mwifiex_deauthenticate_all(adapter);
 
                priv = mwifiex_get_priv(adapter, MWIFIEX_BSS_ROLE_ANY);
@@ -269,7 +317,6 @@ static void mwifiex_pcie_remove(struct pci_dev *pdev)
 
 static void mwifiex_pcie_shutdown(struct pci_dev *pdev)
 {
-       user_rmmod = 1;
        mwifiex_pcie_remove(pdev);
 
        return;
@@ -330,7 +377,7 @@ static void mwifiex_pcie_reset_notify(struct pci_dev *pdev, bool prepare)
                 * Cleanup all software without cleaning anything related to
                 * PCIe and HW.
                 */
-               mwifiex_do_flr(adapter, prepare);
+               mwifiex_shutdown_sw(adapter);
                adapter->surprise_removed = true;
        } else {
                /* Kernel stores and restores PCIe function context before and
@@ -338,7 +385,7 @@ static void mwifiex_pcie_reset_notify(struct pci_dev *pdev, bool prepare)
                 * and firmware including firmware redownload
                 */
                adapter->surprise_removed = false;
-               mwifiex_do_flr(adapter, prepare);
+               mwifiex_reinit_sw(adapter);
        }
        mwifiex_dbg(adapter, INFO, "%s, successful\n", __func__);
 }
@@ -368,43 +415,6 @@ static struct pci_driver __refdata mwifiex_pcie = {
        .err_handler = mwifiex_pcie_err_handler,
 };
 
-/*
- * This function writes data into PCIE card register.
- */
-static int mwifiex_write_reg(struct mwifiex_adapter *adapter, int reg, u32 data)
-{
-       struct pcie_service_card *card = adapter->card;
-
-       iowrite32(data, card->pci_mmap1 + reg);
-
-       return 0;
-}
-
-/*
- * This function reads data from PCIE card register.
- */
-static int mwifiex_read_reg(struct mwifiex_adapter *adapter, int reg, u32 *data)
-{
-       struct pcie_service_card *card = adapter->card;
-
-       *data = ioread32(card->pci_mmap1 + reg);
-       if (*data == 0xffffffff)
-               return 0xffffffff;
-
-       return 0;
-}
-
-/* This function reads u8 data from PCIE card register. */
-static int mwifiex_read_reg_byte(struct mwifiex_adapter *adapter,
-                                int reg, u8 *data)
-{
-       struct pcie_service_card *card = adapter->card;
-
-       *data = ioread8(card->pci_mmap1 + reg);
-
-       return 0;
-}
-
 /*
  * This function adds delay loop to ensure FW is awake before proceeding.
  */
@@ -429,16 +439,25 @@ static void mwifiex_delay_for_sleep_cookie(struct mwifiex_adapter *adapter,
        struct pcie_service_card *card = adapter->card;
        u8 *buffer;
        u32 sleep_cookie, count;
+       struct sk_buff *cmdrsp = card->cmdrsp_buf;
 
        for (count = 0; count < max_delay_loop_cnt; count++) {
-               buffer = card->cmdrsp_buf->data - INTF_HEADER_LEN;
-               sleep_cookie = *(u32 *)buffer;
+               pci_dma_sync_single_for_cpu(card->dev,
+                                           MWIFIEX_SKB_DMA_ADDR(cmdrsp),
+                                           sizeof(sleep_cookie),
+                                           PCI_DMA_FROMDEVICE);
+               buffer = cmdrsp->data;
+               sleep_cookie = READ_ONCE(*(u32 *)buffer);
 
                if (sleep_cookie == MWIFIEX_DEF_SLEEP_COOKIE) {
                        mwifiex_dbg(adapter, INFO,
                                    "sleep cookie found at count %d\n", count);
                        break;
                }
+               pci_dma_sync_single_for_device(card->dev,
+                                              MWIFIEX_SKB_DMA_ADDR(cmdrsp),
+                                              sizeof(sleep_cookie),
+                                              PCI_DMA_FROMDEVICE);
                usleep_range(20, 30);
        }
 
@@ -450,7 +469,6 @@ static void mwifiex_delay_for_sleep_cookie(struct mwifiex_adapter *adapter,
 /* This function wakes up the card by reading fw_status register. */
 static int mwifiex_pm_wakeup_card(struct mwifiex_adapter *adapter)
 {
-       u32 fw_status;
        struct pcie_service_card *card = adapter->card;
        const struct mwifiex_pcie_card_reg *reg = card->pcie.reg;
 
@@ -460,10 +478,10 @@ static int mwifiex_pm_wakeup_card(struct mwifiex_adapter *adapter)
        if (reg->sleep_cookie)
                mwifiex_pcie_dev_wakeup_delay(adapter);
 
-       /* Reading fw_status register will wakeup device */
-       if (mwifiex_read_reg(adapter, reg->fw_status, &fw_status)) {
+       /* Accessing fw_status register will wakeup device */
+       if (mwifiex_write_reg(adapter, reg->fw_status, FIRMWARE_READY_PCIE)) {
                mwifiex_dbg(adapter, ERROR,
-                           "Reading fw_status register failed\n");
+                           "Writing fw_status register failed\n");
                return -1;
        }
 
@@ -1681,7 +1699,13 @@ static int mwifiex_pcie_process_cmd_complete(struct mwifiex_adapter *adapter)
        mwifiex_dbg(adapter, CMD,
                    "info: Rx CMD Response\n");
 
-       mwifiex_unmap_pci_memory(adapter, skb, PCI_DMA_FROMDEVICE);
+       if (adapter->curr_cmd)
+               mwifiex_unmap_pci_memory(adapter, skb, PCI_DMA_FROMDEVICE);
+       else
+               pci_dma_sync_single_for_cpu(card->dev,
+                                           MWIFIEX_SKB_DMA_ADDR(skb),
+                                           MWIFIEX_UPLD_SIZE,
+                                           PCI_DMA_FROMDEVICE);
 
        /* Unmap the command as a response has been received. */
        if (card->cmd_buf) {
@@ -1694,10 +1718,13 @@ static int mwifiex_pcie_process_cmd_complete(struct mwifiex_adapter *adapter)
        rx_len = le16_to_cpu(pkt_len);
        skb_put(skb, MWIFIEX_UPLD_SIZE - skb->len);
        skb_trim(skb, rx_len);
-       skb_pull(skb, INTF_HEADER_LEN);
 
        if (!adapter->curr_cmd) {
                if (adapter->ps_state == PS_STATE_SLEEP_CFM) {
+                       pci_dma_sync_single_for_device(card->dev,
+                                               MWIFIEX_SKB_DMA_ADDR(skb),
+                                               MWIFIEX_SLEEP_COOKIE_SIZE,
+                                               PCI_DMA_FROMDEVICE);
                        if (mwifiex_write_reg(adapter,
                                              PCIE_CPU_INT_EVENT,
                                              CPU_INTR_SLEEP_CFM_DONE)) {
@@ -1707,6 +1734,9 @@ static int mwifiex_pcie_process_cmd_complete(struct mwifiex_adapter *adapter)
                        }
                        mwifiex_delay_for_sleep_cookie(adapter,
                                                       MWIFIEX_MAX_DELAY_COUNT);
+                       mwifiex_unmap_pci_memory(adapter, skb,
+                                                PCI_DMA_FROMDEVICE);
+                       skb_pull(skb, INTF_HEADER_LEN);
                        while (reg->sleep_cookie && (count++ < 10) &&
                               mwifiex_pcie_ok_to_access_hw(adapter))
                                usleep_range(50, 60);
@@ -1724,6 +1754,7 @@ static int mwifiex_pcie_process_cmd_complete(struct mwifiex_adapter *adapter)
                                           PCI_DMA_FROMDEVICE))
                        return -1;
        } else if (mwifiex_pcie_ok_to_access_hw(adapter)) {
+               skb_pull(skb, INTF_HEADER_LEN);
                adapter->curr_cmd->resp_skb = skb;
                adapter->cmd_resp_received = true;
                /* Take the pointer and set it to CMD node and will
@@ -2325,79 +2356,41 @@ static int mwifiex_process_pcie_int(struct mwifiex_adapter *adapter)
                        }
                }
        }
-       while (pcie_ireg & HOST_INTR_MASK) {
-               if (pcie_ireg & HOST_INTR_DNLD_DONE) {
-                       pcie_ireg &= ~HOST_INTR_DNLD_DONE;
-                       mwifiex_dbg(adapter, INTR,
-                                   "info: TX DNLD Done\n");
-                       ret = mwifiex_pcie_send_data_complete(adapter);
-                       if (ret)
-                               return ret;
-               }
-               if (pcie_ireg & HOST_INTR_UPLD_RDY) {
-                       pcie_ireg &= ~HOST_INTR_UPLD_RDY;
-                       mwifiex_dbg(adapter, INTR,
-                                   "info: Rx DATA\n");
-                       ret = mwifiex_pcie_process_recv_data(adapter);
-                       if (ret)
-                               return ret;
-               }
-               if (pcie_ireg & HOST_INTR_EVENT_RDY) {
-                       pcie_ireg &= ~HOST_INTR_EVENT_RDY;
-                       mwifiex_dbg(adapter, INTR,
-                                   "info: Rx EVENT\n");
-                       ret = mwifiex_pcie_process_event_ready(adapter);
-                       if (ret)
-                               return ret;
-               }
-
-               if (pcie_ireg & HOST_INTR_CMD_DONE) {
-                       pcie_ireg &= ~HOST_INTR_CMD_DONE;
-                       if (adapter->cmd_sent) {
-                               mwifiex_dbg(adapter, INTR,
-                                           "info: CMD sent Interrupt\n");
-                               adapter->cmd_sent = false;
-                       }
-                       /* Handle command response */
-                       ret = mwifiex_pcie_process_cmd_complete(adapter);
-                       if (ret)
-                               return ret;
-                       if (adapter->hs_activated)
-                               return ret;
-               }
-
-               if (card->msi_enable) {
-                       spin_lock_irqsave(&adapter->int_lock, flags);
-                       adapter->int_status = 0;
-                       spin_unlock_irqrestore(&adapter->int_lock, flags);
-               }
-
-               if (mwifiex_pcie_ok_to_access_hw(adapter)) {
-                       if (mwifiex_read_reg(adapter, PCIE_HOST_INT_STATUS,
-                                            &pcie_ireg)) {
-                               mwifiex_dbg(adapter, ERROR,
-                                           "Read register failed\n");
-                               return -1;
-                       }
-
-                       if ((pcie_ireg != 0xFFFFFFFF) && (pcie_ireg)) {
-                               if (mwifiex_write_reg(adapter,
-                                                     PCIE_HOST_INT_STATUS,
-                                                     ~pcie_ireg)) {
-                                       mwifiex_dbg(adapter, ERROR,
-                                                   "Write register failed\n");
-                                       return -1;
-                               }
-                       }
 
+       if (pcie_ireg & HOST_INTR_DNLD_DONE) {
+               pcie_ireg &= ~HOST_INTR_DNLD_DONE;
+               mwifiex_dbg(adapter, INTR, "info: TX DNLD Done\n");
+               ret = mwifiex_pcie_send_data_complete(adapter);
+               if (ret)
+                       return ret;
+       }
+       if (pcie_ireg & HOST_INTR_UPLD_RDY) {
+               pcie_ireg &= ~HOST_INTR_UPLD_RDY;
+               mwifiex_dbg(adapter, INTR, "info: Rx DATA\n");
+               ret = mwifiex_pcie_process_recv_data(adapter);
+               if (ret)
+                       return ret;
+       }
+       if (pcie_ireg & HOST_INTR_EVENT_RDY) {
+               pcie_ireg &= ~HOST_INTR_EVENT_RDY;
+               mwifiex_dbg(adapter, INTR, "info: Rx EVENT\n");
+               ret = mwifiex_pcie_process_event_ready(adapter);
+               if (ret)
+                       return ret;
+       }
+       if (pcie_ireg & HOST_INTR_CMD_DONE) {
+               pcie_ireg &= ~HOST_INTR_CMD_DONE;
+               if (adapter->cmd_sent) {
+                       mwifiex_dbg(adapter, INTR,
+                                   "info: CMD sent Interrupt\n");
+                       adapter->cmd_sent = false;
                }
-               if (!card->msi_enable) {
-                       spin_lock_irqsave(&adapter->int_lock, flags);
-                       pcie_ireg |= adapter->int_status;
-                       adapter->int_status = 0;
-                       spin_unlock_irqrestore(&adapter->int_lock, flags);
-               }
+               /* Handle command response */
+               ret = mwifiex_pcie_process_cmd_complete(adapter);
+               if (ret)
+                       return ret;
        }
+
        mwifiex_dbg(adapter, INTR,
                    "info: cmd_sent=%d data_sent=%d\n",
                    adapter->cmd_sent, adapter->data_sent);
@@ -2715,31 +2708,35 @@ static void mwifiex_pcie_fw_dump(struct mwifiex_adapter *adapter)
 
 static void mwifiex_pcie_device_dump_work(struct mwifiex_adapter *adapter)
 {
-       mwifiex_drv_info_dump(adapter);
+       int drv_info_size;
+       void *drv_info;
+
+       drv_info_size = mwifiex_drv_info_dump(adapter, &drv_info);
        mwifiex_pcie_fw_dump(adapter);
-       mwifiex_upload_device_dump(adapter);
+       mwifiex_upload_device_dump(adapter, drv_info, drv_info_size);
 }
 
-static unsigned long iface_work_flags;
-static struct mwifiex_adapter *save_adapter;
 static void mwifiex_pcie_work(struct work_struct *work)
 {
+       struct pcie_service_card *card =
+               container_of(work, struct pcie_service_card, work);
+
        if (test_and_clear_bit(MWIFIEX_IFACE_WORK_DEVICE_DUMP,
-                              &iface_work_flags))
-               mwifiex_pcie_device_dump_work(save_adapter);
+                              &card->work_flags))
+               mwifiex_pcie_device_dump_work(card->adapter);
 }
 
-static DECLARE_WORK(pcie_work, mwifiex_pcie_work);
 /* This function dumps FW information */
 static void mwifiex_pcie_device_dump(struct mwifiex_adapter *adapter)
 {
-       save_adapter = adapter;
-       if (test_bit(MWIFIEX_IFACE_WORK_DEVICE_DUMP, &iface_work_flags))
+       struct pcie_service_card *card = adapter->card;
+
+       if (test_bit(MWIFIEX_IFACE_WORK_DEVICE_DUMP, &card->work_flags))
                return;
 
-       set_bit(MWIFIEX_IFACE_WORK_DEVICE_DUMP, &iface_work_flags);
+       set_bit(MWIFIEX_IFACE_WORK_DEVICE_DUMP, &card->work_flags);
 
-       schedule_work(&pcie_work);
+       schedule_work(&card->work);
 }
 
 /*
@@ -2752,7 +2749,7 @@ static void mwifiex_pcie_device_dump(struct mwifiex_adapter *adapter)
  *      - Allocate command response ring buffer
  *      - Allocate sleep cookie buffer
  */
-static int mwifiex_pcie_init(struct mwifiex_adapter *adapter)
+static int mwifiex_init_pcie(struct mwifiex_adapter *adapter)
 {
        struct pcie_service_card *card = adapter->card;
        int ret;
@@ -2861,13 +2858,16 @@ err_enable_dev:
  *      - Command response ring buffer
  *      - Sleep cookie buffer
  */
-static void mwifiex_pcie_cleanup(struct mwifiex_adapter *adapter)
+static void mwifiex_cleanup_pcie(struct mwifiex_adapter *adapter)
 {
        struct pcie_service_card *card = adapter->card;
        struct pci_dev *pdev = card->dev;
        const struct mwifiex_pcie_card_reg *reg = card->pcie.reg;
+       int ret;
+       u32 fw_status;
 
-       if (user_rmmod) {
+       ret = mwifiex_read_reg(adapter, reg->fw_status, &fw_status);
+       if (fw_status == FIRMWARE_READY_PCIE) {
                mwifiex_dbg(adapter, INFO,
                            "Clearing driver ready signature\n");
                if (mwifiex_write_reg(adapter, reg->drv_rdy, 0x00000000))
@@ -3058,7 +3058,7 @@ static void mwifiex_unregister_dev(struct mwifiex_adapter *adapter)
  *      - Allocate event BD ring buffers
  *      - Allocate command response ring buffer
  *      - Allocate sleep cookie buffer
- * Part of mwifiex_pcie_init(), not reset the PCIE registers
+ * Part of mwifiex_init_pcie(), not reset the PCIE registers
  */
 static void mwifiex_pcie_up_dev(struct mwifiex_adapter *adapter)
 {
@@ -3067,6 +3067,17 @@ static void mwifiex_pcie_up_dev(struct mwifiex_adapter *adapter)
        struct pci_dev *pdev = card->dev;
        const struct mwifiex_pcie_card_reg *reg = card->pcie.reg;
 
+       /* Bluetooth is not on pcie interface. Download Wifi only firmware
+        * during pcie FLR, so that bluetooth part of firmware which is
+        * already running doesn't get affected.
+        */
+       strcpy(adapter->fw_name, PCIE8997_DEFAULT_WIFIFW_NAME);
+
+       /* tx_buf_size might be changed to 3584 by firmware during
+        * data transfer, we should reset it to default size.
+        */
+       adapter->tx_buf_size = card->pcie.tx_buf_size;
+
        card->cmdrsp_buf = NULL;
        ret = mwifiex_pcie_create_txbd_ring(adapter);
        if (ret) {
@@ -3128,7 +3139,6 @@ static void mwifiex_pcie_down_dev(struct mwifiex_adapter *adapter)
                mwifiex_dbg(adapter, ERROR, "Failed to write driver not-ready signature\n");
 
        adapter->seq_num = 0;
-       adapter->tx_buf_size = MWIFIEX_TX_DATA_BUF_SIZE_4K;
 
        if (reg->sleep_cookie)
                mwifiex_pcie_delete_sleep_cookie_buf(adapter);
@@ -3141,8 +3151,8 @@ static void mwifiex_pcie_down_dev(struct mwifiex_adapter *adapter)
 }
 
 static struct mwifiex_if_ops pcie_ops = {
-       .init_if =                      mwifiex_pcie_init,
-       .cleanup_if =                   mwifiex_pcie_cleanup,
+       .init_if =                      mwifiex_init_pcie,
+       .cleanup_if =                   mwifiex_cleanup_pcie,
        .check_fw_status =              mwifiex_check_fw_status,
        .check_winner_status =          mwifiex_check_winner_status,
        .prog_fw =                      mwifiex_prog_fw_w_helper,
@@ -3168,49 +3178,7 @@ static struct mwifiex_if_ops pcie_ops = {
        .up_dev =                       mwifiex_pcie_up_dev,
 };
 
-/*
- * This function initializes the PCIE driver module.
- *
- * This registers the device with PCIE bus.
- */
-static int mwifiex_pcie_init_module(void)
-{
-       int ret;
-
-       pr_debug("Marvell PCIe Driver\n");
-
-       /* Clear the flag in case user removes the card. */
-       user_rmmod = 0;
-
-       ret = pci_register_driver(&mwifiex_pcie);
-       if (ret)
-               pr_err("Driver register failed!\n");
-       else
-               pr_debug("info: Driver registered successfully!\n");
-
-       return ret;
-}
-
-/*
- * This function cleans up the PCIE driver.
- *
- * The following major steps are followed for cleanup -
- *      - Resume the device if its suspended
- *      - Disconnect the device if connected
- *      - Shutdown the firmware
- *      - Unregister the device from PCIE bus.
- */
-static void mwifiex_pcie_cleanup_module(void)
-{
-       /* Set the flag as user is removing this module. */
-       user_rmmod = 1;
-
-       cancel_work_sync(&pcie_work);
-       pci_unregister_driver(&mwifiex_pcie);
-}
-
-module_init(mwifiex_pcie_init_module);
-module_exit(mwifiex_pcie_cleanup_module);
+module_pci_driver(mwifiex_pcie);
 
 MODULE_AUTHOR("Marvell International Ltd.");
 MODULE_DESCRIPTION("Marvell WiFi-Ex PCI-Express Driver version " PCIE_VERSION);
index ae3365d1c34e8acc8d882c56b8972c9c17dd5a85..00e8ee5ad4a834ed1905c5b98acee85be3ca1a32 100644 (file)
 /* FW awake cookie after FW ready */
 #define FW_AWAKE_COOKIE                                                (0xAA55AA55)
 #define MWIFIEX_DEF_SLEEP_COOKIE                       0xBEEFBEEF
+#define MWIFIEX_SLEEP_COOKIE_SIZE                      4
 #define MWIFIEX_MAX_DELAY_COUNT                                100
 
 struct mwifiex_pcie_card_reg {
@@ -386,6 +387,8 @@ struct pcie_service_card {
 #endif
        struct mwifiex_msix_context msix_ctx[MWIFIEX_NUM_MSIX_VECTORS];
        struct mwifiex_msix_context share_irq_ctx;
+       struct work_struct work;
+       unsigned long work_flags;
 };
 
 static inline int
index 43facba641bf3ce7b65cc0345af26e976b9838e2..a4b356d267f982b2646dc90f6eb1a2c3deac1425 100644 (file)
 
 #define SDIO_VERSION   "1.0"
 
-/* The mwifiex_sdio_remove() callback function is called when
- * user removes this module from kernel space or ejects
- * the card from the slot. The driver handles these 2 cases
- * differently.
- * If the user is removing the module, the few commands (FUNC_SHUTDOWN,
- * HS_CANCEL etc.) are sent to the firmware.
- * If the card is removed, there is no need to send these command.
- *
- * The variable 'user_rmmod' is used to distinguish these two
- * scenarios. This flag is initialized as FALSE in case the card
- * is removed, and will be set to TRUE for module removal when
- * module_exit function is called.
- */
-static u8 user_rmmod;
+static void mwifiex_sdio_work(struct work_struct *work);
 
 static struct mwifiex_if_ops sdio_ops;
-static unsigned long iface_work_flags;
 
 static struct memory_type_mapping generic_mem_type_map[] = {
        {"DUMP", NULL, 0, 0xDD},
@@ -116,7 +102,6 @@ mwifiex_sdio_probe(struct sdio_func *func, const struct sdio_device_id *id)
        init_completion(&card->fw_done);
 
        card->func = func;
-       card->device_id = id;
 
        func->card->quirks |= MMC_QUIRK_BLKSZ_FOR_BYTE_MODE;
 
@@ -136,6 +121,7 @@ mwifiex_sdio_probe(struct sdio_func *func, const struct sdio_device_id *id)
                card->fw_dump_enh = data->fw_dump_enh;
                card->can_auto_tdls = data->can_auto_tdls;
                card->can_ext_scan = data->can_ext_scan;
+               INIT_WORK(&card->work, mwifiex_sdio_work);
        }
 
        sdio_claim_host(func);
@@ -212,6 +198,171 @@ static int mwifiex_sdio_resume(struct device *dev)
        return 0;
 }
 
+/* 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.
+ */
+static int
+mwifiex_write_reg(struct mwifiex_adapter *adapter, u32 reg, u8 data)
+{
+       struct sdio_mmc_card *card = adapter->card;
+       int ret;
+
+       sdio_claim_host(card->func);
+       ret = mwifiex_write_reg_locked(card->func, reg, data);
+       sdio_release_host(card->func);
+
+       return ret;
+}
+
+/* This function reads data from SDIO card register.
+ */
+static int
+mwifiex_read_reg(struct mwifiex_adapter *adapter, u32 reg, u8 *data)
+{
+       struct sdio_mmc_card *card = adapter->card;
+       int ret = -1;
+       u8 val;
+
+       sdio_claim_host(card->func);
+       val = sdio_readb(card->func, reg, &ret);
+       sdio_release_host(card->func);
+
+       *data = val;
+
+       return ret;
+}
+
+/* This function writes multiple data into SDIO card memory.
+ *
+ * This does not work in suspended mode.
+ */
+static int
+mwifiex_write_data_sync(struct mwifiex_adapter *adapter,
+                       u8 *buffer, u32 pkt_len, u32 port)
+{
+       struct sdio_mmc_card *card = adapter->card;
+       int ret;
+       u8 blk_mode =
+               (port & MWIFIEX_SDIO_BYTE_MODE_MASK) ? BYTE_MODE : BLOCK_MODE;
+       u32 blk_size = (blk_mode == BLOCK_MODE) ? MWIFIEX_SDIO_BLOCK_SIZE : 1;
+       u32 blk_cnt =
+               (blk_mode ==
+                BLOCK_MODE) ? (pkt_len /
+                               MWIFIEX_SDIO_BLOCK_SIZE) : pkt_len;
+       u32 ioport = (port & MWIFIEX_SDIO_IO_PORT_MASK);
+
+       if (adapter->is_suspended) {
+               mwifiex_dbg(adapter, ERROR,
+                           "%s: not allowed while suspended\n", __func__);
+               return -1;
+       }
+
+       sdio_claim_host(card->func);
+
+       ret = sdio_writesb(card->func, ioport, buffer, blk_cnt * blk_size);
+
+       sdio_release_host(card->func);
+
+       return ret;
+}
+
+/* This function reads multiple data from SDIO card memory.
+ */
+static int mwifiex_read_data_sync(struct mwifiex_adapter *adapter, u8 *buffer,
+                                 u32 len, u32 port, u8 claim)
+{
+       struct sdio_mmc_card *card = adapter->card;
+       int ret;
+       u8 blk_mode = (port & MWIFIEX_SDIO_BYTE_MODE_MASK) ? BYTE_MODE
+                      : BLOCK_MODE;
+       u32 blk_size = (blk_mode == BLOCK_MODE) ? MWIFIEX_SDIO_BLOCK_SIZE : 1;
+       u32 blk_cnt = (blk_mode == BLOCK_MODE) ? (len / MWIFIEX_SDIO_BLOCK_SIZE)
+                       : len;
+       u32 ioport = (port & MWIFIEX_SDIO_IO_PORT_MASK);
+
+       if (claim)
+               sdio_claim_host(card->func);
+
+       ret = sdio_readsb(card->func, buffer, ioport, blk_cnt * blk_size);
+
+       if (claim)
+               sdio_release_host(card->func);
+
+       return ret;
+}
+
+/* This function reads the firmware status.
+ */
+static int
+mwifiex_sdio_read_fw_status(struct mwifiex_adapter *adapter, u16 *dat)
+{
+       struct sdio_mmc_card *card = adapter->card;
+       const struct mwifiex_sdio_card_reg *reg = card->reg;
+       u8 fws0, fws1;
+
+       if (mwifiex_read_reg(adapter, reg->status_reg_0, &fws0))
+               return -1;
+
+       if (mwifiex_read_reg(adapter, reg->status_reg_1, &fws1))
+               return -1;
+
+       *dat = (u16)((fws1 << 8) | fws0);
+       return 0;
+}
+
+/* This function checks the firmware status in card.
+ */
+static int mwifiex_check_fw_status(struct mwifiex_adapter *adapter,
+                                  u32 poll_num)
+{
+       int ret = 0;
+       u16 firmware_stat;
+       u32 tries;
+
+       for (tries = 0; tries < poll_num; tries++) {
+               ret = mwifiex_sdio_read_fw_status(adapter, &firmware_stat);
+               if (ret)
+                       continue;
+               if (firmware_stat == FIRMWARE_READY_SDIO) {
+                       ret = 0;
+                       break;
+               }
+
+               msleep(100);
+               ret = -1;
+       }
+
+       return ret;
+}
+
+/* This function checks if WLAN is the winner.
+ */
+static int mwifiex_check_winner_status(struct mwifiex_adapter *adapter)
+{
+       int ret = 0;
+       u8 winner = 0;
+       struct sdio_mmc_card *card = adapter->card;
+
+       if (mwifiex_read_reg(adapter, card->reg->status_reg_0, &winner))
+               return -1;
+
+       if (winner)
+               adapter->winner = 0;
+       else
+               adapter->winner = 1;
+
+       return ret;
+}
+
 /*
  * SDIO remove.
  *
@@ -223,6 +374,8 @@ mwifiex_sdio_remove(struct sdio_func *func)
        struct sdio_mmc_card *card;
        struct mwifiex_adapter *adapter;
        struct mwifiex_private *priv;
+       int ret = 0;
+       u16 firmware_stat;
 
        card = sdio_get_drvdata(func);
        if (!card)
@@ -234,9 +387,12 @@ mwifiex_sdio_remove(struct sdio_func *func)
        if (!adapter || !adapter->priv_num)
                return;
 
+       cancel_work_sync(&card->work);
+
        mwifiex_dbg(adapter, INFO, "info: SDIO func num=%d\n", func->num);
 
-       if (user_rmmod && !adapter->mfg_mode) {
+       ret = mwifiex_sdio_read_fw_status(adapter, &firmware_stat);
+       if (firmware_stat == FIRMWARE_READY_SDIO && !adapter->mfg_mode) {
                mwifiex_deauthenticate_all(adapter);
 
                priv = mwifiex_get_priv(adapter, MWIFIEX_BSS_ROLE_ANY);
@@ -364,111 +520,6 @@ 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.
- */
-static int
-mwifiex_write_reg(struct mwifiex_adapter *adapter, u32 reg, u8 data)
-{
-       struct sdio_mmc_card *card = adapter->card;
-       int ret;
-
-       sdio_claim_host(card->func);
-       ret = mwifiex_write_reg_locked(card->func, reg, data);
-       sdio_release_host(card->func);
-
-       return ret;
-}
-
-/*
- * This function reads data from SDIO card register.
- */
-static int
-mwifiex_read_reg(struct mwifiex_adapter *adapter, u32 reg, u8 *data)
-{
-       struct sdio_mmc_card *card = adapter->card;
-       int ret = -1;
-       u8 val;
-
-       sdio_claim_host(card->func);
-       val = sdio_readb(card->func, reg, &ret);
-       sdio_release_host(card->func);
-
-       *data = val;
-
-       return ret;
-}
-
-/*
- * This function writes multiple data into SDIO card memory.
- *
- * This does not work in suspended mode.
- */
-static int
-mwifiex_write_data_sync(struct mwifiex_adapter *adapter,
-                       u8 *buffer, u32 pkt_len, u32 port)
-{
-       struct sdio_mmc_card *card = adapter->card;
-       int ret;
-       u8 blk_mode =
-               (port & MWIFIEX_SDIO_BYTE_MODE_MASK) ? BYTE_MODE : BLOCK_MODE;
-       u32 blk_size = (blk_mode == BLOCK_MODE) ? MWIFIEX_SDIO_BLOCK_SIZE : 1;
-       u32 blk_cnt =
-               (blk_mode ==
-                BLOCK_MODE) ? (pkt_len /
-                               MWIFIEX_SDIO_BLOCK_SIZE) : pkt_len;
-       u32 ioport = (port & MWIFIEX_SDIO_IO_PORT_MASK);
-
-       if (adapter->is_suspended) {
-               mwifiex_dbg(adapter, ERROR,
-                           "%s: not allowed while suspended\n", __func__);
-               return -1;
-       }
-
-       sdio_claim_host(card->func);
-
-       ret = sdio_writesb(card->func, ioport, buffer, blk_cnt * blk_size);
-
-       sdio_release_host(card->func);
-
-       return ret;
-}
-
-/*
- * This function reads multiple data from SDIO card memory.
- */
-static int mwifiex_read_data_sync(struct mwifiex_adapter *adapter, u8 *buffer,
-                                 u32 len, u32 port, u8 claim)
-{
-       struct sdio_mmc_card *card = adapter->card;
-       int ret;
-       u8 blk_mode = (port & MWIFIEX_SDIO_BYTE_MODE_MASK) ? BYTE_MODE
-                      : BLOCK_MODE;
-       u32 blk_size = (blk_mode == BLOCK_MODE) ? MWIFIEX_SDIO_BLOCK_SIZE : 1;
-       u32 blk_cnt = (blk_mode == BLOCK_MODE) ? (len / MWIFIEX_SDIO_BLOCK_SIZE)
-                       : len;
-       u32 ioport = (port & MWIFIEX_SDIO_IO_PORT_MASK);
-
-       if (claim)
-               sdio_claim_host(card->func);
-
-       ret = sdio_readsb(card->func, buffer, ioport, blk_cnt * blk_size);
-
-       if (claim)
-               sdio_release_host(card->func);
-
-       return ret;
-}
-
 /*
  * This function wakes up the card.
  *
@@ -754,27 +805,6 @@ mwifiex_sdio_poll_card_status(struct mwifiex_adapter *adapter, u8 bits)
        return -1;
 }
 
-/*
- * This function reads the firmware status.
- */
-static int
-mwifiex_sdio_read_fw_status(struct mwifiex_adapter *adapter, u16 *dat)
-{
-       struct sdio_mmc_card *card = adapter->card;
-       const struct mwifiex_sdio_card_reg *reg = card->reg;
-       u8 fws0, fws1;
-
-       if (mwifiex_read_reg(adapter, reg->status_reg_0, &fws0))
-               return -1;
-
-       if (mwifiex_read_reg(adapter, reg->status_reg_1, &fws1))
-               return -1;
-
-       *dat = (u16) ((fws1 << 8) | fws0);
-
-       return 0;
-}
-
 /*
  * This function disables the host interrupt.
  *
@@ -1079,51 +1109,6 @@ done:
        return ret;
 }
 
-/*
- * This function checks the firmware status in card.
- */
-static int mwifiex_check_fw_status(struct mwifiex_adapter *adapter,
-                                  u32 poll_num)
-{
-       int ret = 0;
-       u16 firmware_stat;
-       u32 tries;
-
-       for (tries = 0; tries < poll_num; tries++) {
-               ret = mwifiex_sdio_read_fw_status(adapter, &firmware_stat);
-               if (ret)
-                       continue;
-               if (firmware_stat == FIRMWARE_READY_SDIO) {
-                       ret = 0;
-                       break;
-               } else {
-                       msleep(100);
-                       ret = -1;
-               }
-       }
-
-       return ret;
-}
-
-/* This function checks if WLAN is the winner.
- */
-static int mwifiex_check_winner_status(struct mwifiex_adapter *adapter)
-{
-       int ret = 0;
-       u8 winner = 0;
-       struct sdio_mmc_card *card = adapter->card;
-
-       if (mwifiex_read_reg(adapter, card->reg->status_reg_0, &winner))
-               return -1;
-
-       if (winner)
-               adapter->winner = 0;
-       else
-               adapter->winner = 1;
-
-       return ret;
-}
-
 /*
  * This function decode sdio aggreation pkt.
  *
@@ -2204,33 +2189,12 @@ mwifiex_update_mp_end_port(struct mwifiex_adapter *adapter, u16 port)
                    port, card->mp_data_port_mask);
 }
 
-static void mwifiex_recreate_adapter(struct sdio_mmc_card *card)
+static void mwifiex_sdio_card_reset_work(struct mwifiex_adapter *adapter)
 {
+       struct sdio_mmc_card *card = adapter->card;
        struct sdio_func *func = card->func;
-       const struct sdio_device_id *device_id = card->device_id;
-
-       /* TODO mmc_hw_reset does not require destroying and re-probing the
-        * whole adapter. Hence there was no need to for this rube-goldberg
-        * design to reload the fw from an external workqueue. If we don't
-        * destroy the adapter we could reload the fw from
-        * mwifiex_main_work_queue directly.
-        * The real difficulty with fw reset is to restore all the user
-        * settings applied through ioctl. By destroying and recreating the
-        * adapter, we take the easy way out, since we rely on user space to
-        * restore them. We assume that user space will treat the new
-        * incarnation of the adapter(interfaces) as if they had been just
-        * discovered and initializes them from scratch.
-        */
 
-       mwifiex_sdio_remove(func);
-
-       /*
-        * Normally, we would let the driver core take care of releasing these.
-        * But we're not letting the driver core handle this one. See above
-        * TODO.
-        */
-       sdio_set_drvdata(func, NULL);
-       devm_kfree(&func->dev, card);
+       mwifiex_shutdown_sw(adapter);
 
        /* power cycle the adapter */
        sdio_claim_host(func);
@@ -2240,24 +2204,10 @@ static void mwifiex_recreate_adapter(struct sdio_mmc_card *card)
        /* Previous save_adapter won't be valid after this. We will cancel
         * pending work requests.
         */
-       clear_bit(MWIFIEX_IFACE_WORK_DEVICE_DUMP, &iface_work_flags);
-       clear_bit(MWIFIEX_IFACE_WORK_CARD_RESET, &iface_work_flags);
-
-       mwifiex_sdio_probe(func, device_id);
-}
-
-static struct mwifiex_adapter *save_adapter;
-static void mwifiex_sdio_card_reset_work(struct mwifiex_adapter *adapter)
-{
-       struct sdio_mmc_card *card = adapter->card;
+       clear_bit(MWIFIEX_IFACE_WORK_DEVICE_DUMP, &card->work_flags);
+       clear_bit(MWIFIEX_IFACE_WORK_CARD_RESET, &card->work_flags);
 
-       /* TODO card pointer is unprotected. If the adapter is removed
-        * physically, sdio core might trigger mwifiex_sdio_remove, before this
-        * workqueue is run, which will destroy the adapter struct. When this
-        * workqueue eventually exceutes it will dereference an invalid adapter
-        * pointer
-        */
-       mwifiex_recreate_adapter(card);
+       mwifiex_reinit_sw(adapter);
 }
 
 /* This function read/write firmware */
@@ -2548,47 +2498,53 @@ done:
 static void mwifiex_sdio_device_dump_work(struct mwifiex_adapter *adapter)
 {
        struct sdio_mmc_card *card = adapter->card;
+       int drv_info_size;
+       void *drv_info;
 
-       mwifiex_drv_info_dump(adapter);
+       drv_info_size = mwifiex_drv_info_dump(adapter, &drv_info);
        if (card->fw_dump_enh)
                mwifiex_sdio_generic_fw_dump(adapter);
        else
                mwifiex_sdio_fw_dump(adapter);
-       mwifiex_upload_device_dump(adapter);
+       mwifiex_upload_device_dump(adapter, drv_info, drv_info_size);
 }
 
 static void mwifiex_sdio_work(struct work_struct *work)
 {
+       struct sdio_mmc_card *card =
+               container_of(work, struct sdio_mmc_card, work);
+
        if (test_and_clear_bit(MWIFIEX_IFACE_WORK_DEVICE_DUMP,
-                              &iface_work_flags))
-               mwifiex_sdio_device_dump_work(save_adapter);
+                              &card->work_flags))
+               mwifiex_sdio_device_dump_work(card->adapter);
        if (test_and_clear_bit(MWIFIEX_IFACE_WORK_CARD_RESET,
-                              &iface_work_flags))
-               mwifiex_sdio_card_reset_work(save_adapter);
+                              &card->work_flags))
+               mwifiex_sdio_card_reset_work(card->adapter);
 }
 
-static DECLARE_WORK(sdio_work, mwifiex_sdio_work);
 /* This function resets the card */
 static void mwifiex_sdio_card_reset(struct mwifiex_adapter *adapter)
 {
-       save_adapter = adapter;
-       if (test_bit(MWIFIEX_IFACE_WORK_CARD_RESET, &iface_work_flags))
+       struct sdio_mmc_card *card = adapter->card;
+
+       if (test_bit(MWIFIEX_IFACE_WORK_CARD_RESET, &card->work_flags))
                return;
 
-       set_bit(MWIFIEX_IFACE_WORK_CARD_RESET, &iface_work_flags);
+       set_bit(MWIFIEX_IFACE_WORK_CARD_RESET, &card->work_flags);
 
-       schedule_work(&sdio_work);
+       schedule_work(&card->work);
 }
 
 /* This function dumps FW information */
 static void mwifiex_sdio_device_dump(struct mwifiex_adapter *adapter)
 {
-       save_adapter = adapter;
-       if (test_bit(MWIFIEX_IFACE_WORK_DEVICE_DUMP, &iface_work_flags))
+       struct sdio_mmc_card *card = adapter->card;
+
+       if (test_bit(MWIFIEX_IFACE_WORK_DEVICE_DUMP, &card->work_flags))
                return;
 
-       set_bit(MWIFIEX_IFACE_WORK_DEVICE_DUMP, &iface_work_flags);
-       schedule_work(&sdio_work);
+       set_bit(MWIFIEX_IFACE_WORK_DEVICE_DUMP, &card->work_flags);
+       schedule_work(&card->work);
 }
 
 /* Function to dump SDIO function registers and SDIO scratch registers in case
@@ -2684,6 +2640,33 @@ mwifiex_sdio_reg_dump(struct mwifiex_adapter *adapter, char *drv_buf)
        return p - drv_buf;
 }
 
+/* sdio device/function initialization, code is extracted
+ * from init_if handler and register_dev handler.
+ */
+static void mwifiex_sdio_up_dev(struct mwifiex_adapter *adapter)
+{
+       struct sdio_mmc_card *card = adapter->card;
+       u8 sdio_ireg;
+
+       sdio_claim_host(card->func);
+       sdio_enable_func(card->func);
+       sdio_set_block_size(card->func, MWIFIEX_SDIO_BLOCK_SIZE);
+       sdio_release_host(card->func);
+
+       /* tx_buf_size might be changed to 3584 by firmware during
+        * data transfer, we will reset to default size.
+        */
+       adapter->tx_buf_size = card->tx_buf_size;
+
+       /* Read the host_int_status_reg for ACK the first interrupt got
+        * from the bootloader. If we don't do this we get a interrupt
+        * as soon as we register the irq.
+        */
+       mwifiex_read_reg(adapter, card->reg->host_int_status_reg, &sdio_ireg);
+
+       mwifiex_init_sdio_ioport(adapter);
+}
+
 static struct mwifiex_if_ops sdio_ops = {
        .init_if = mwifiex_init_sdio,
        .cleanup_if = mwifiex_cleanup_sdio,
@@ -2709,43 +2692,10 @@ static struct mwifiex_if_ops sdio_ops = {
        .reg_dump = mwifiex_sdio_reg_dump,
        .device_dump = mwifiex_sdio_device_dump,
        .deaggr_pkt = mwifiex_deaggr_sdio_pkt,
+       .up_dev = mwifiex_sdio_up_dev,
 };
 
-/*
- * This function initializes the SDIO driver.
- *
- * This registers the device with SDIO bus.
- */
-static int
-mwifiex_sdio_init_module(void)
-{
-       /* Clear the flag in case user removes the card. */
-       user_rmmod = 0;
-
-       return sdio_register_driver(&mwifiex_sdio);
-}
-
-/*
- * This function cleans up the SDIO driver.
- *
- * The following major steps are followed for cleanup -
- *      - Resume the device if its suspended
- *      - Disconnect the device if connected
- *      - Shutdown the firmware
- *      - Unregister the device from SDIO bus.
- */
-static void
-mwifiex_sdio_cleanup_module(void)
-{
-       /* Set the flag as user is removing this module. */
-       user_rmmod = 1;
-       cancel_work_sync(&sdio_work);
-
-       sdio_unregister_driver(&mwifiex_sdio);
-}
-
-module_init(mwifiex_sdio_init_module);
-module_exit(mwifiex_sdio_cleanup_module);
+module_driver(mwifiex_sdio, sdio_register_driver, sdio_unregister_driver);
 
 MODULE_AUTHOR("Marvell International Ltd.");
 MODULE_DESCRIPTION("Marvell WiFi-Ex SDIO Driver version " SDIO_VERSION);
index cdbf3a3ac7f994fbb56ced7df60b501199976202..dccf7fd1aef32cb89235723639fbc2fe4816427d 100644 (file)
@@ -268,8 +268,8 @@ struct sdio_mmc_card {
        struct mwifiex_sdio_mpa_tx mpa_tx;
        struct mwifiex_sdio_mpa_rx mpa_rx;
 
-       /* needed for card reset */
-       const struct sdio_device_id *device_id;
+       struct work_struct work;
+       unsigned long work_flags;
 };
 
 struct mwifiex_sdio_device {
index 9df0c4dc06ed9bc95b739f1fc11a79fe0c19a937..96503d3d053ff0ad28045743e68479389a8b2b5e 100644 (file)
@@ -1009,6 +1009,10 @@ int mwifiex_process_sta_event(struct mwifiex_private *priv)
                                            adapter->event_skb->len -
                                            sizeof(eventcause));
                break;
+       /* Debugging event; not used, but let's not print an ERROR for it. */
+       case EVENT_UNKNOWN_DEBUG:
+               mwifiex_dbg(adapter, EVENT, "event: debug\n");
+               break;
        default:
                mwifiex_dbg(adapter, ERROR, "event: unknown event id: %#x\n",
                            eventcause);
index c563160b3b6be93f8dd3c96f317f289fbe1d9d7b..9cf3334adf4d56e2b3dcbc77bf847c028001a443 100644 (file)
@@ -22,7 +22,6 @@
 
 #define USB_VERSION    "1.0"
 
-static u8 user_rmmod;
 static struct mwifiex_if_ops usb_ops;
 
 static struct usb_device_id mwifiex_usb_table[] = {
@@ -618,7 +617,7 @@ static void mwifiex_usb_disconnect(struct usb_interface *intf)
        if (!adapter || !adapter->priv_num)
                return;
 
-       if (user_rmmod && !adapter->mfg_mode) {
+       if (card->udev->state != USB_STATE_NOTATTACHED && !adapter->mfg_mode) {
                mwifiex_deauthenticate_all(adapter);
 
                mwifiex_init_shutdown_fw(mwifiex_get_priv(adapter,
@@ -1201,43 +1200,7 @@ static struct mwifiex_if_ops usb_ops = {
        .is_port_ready =        mwifiex_usb_is_port_ready,
 };
 
-/* This function initializes the USB driver module.
- *
- * This registers the device with USB bus.
- */
-static int mwifiex_usb_init_module(void)
-{
-       int ret;
-
-       pr_debug("Marvell USB8797 Driver\n");
-
-       ret = usb_register(&mwifiex_usb_driver);
-       if (ret)
-               pr_err("Driver register failed!\n");
-       else
-               pr_debug("info: Driver registered successfully!\n");
-
-       return ret;
-}
-
-/* This function cleans up the USB driver.
- *
- * The following major steps are followed in .disconnect for cleanup:
- *      - Resume the device if its suspended
- *      - Disconnect the device if connected
- *      - Shutdown the firmware
- *      - Unregister the device from USB bus.
- */
-static void mwifiex_usb_cleanup_module(void)
-{
-       /* set the flag as user is removing this module */
-       user_rmmod = 1;
-
-       usb_deregister(&mwifiex_usb_driver);
-}
-
-module_init(mwifiex_usb_init_module);
-module_exit(mwifiex_usb_cleanup_module);
+module_usb_driver(mwifiex_usb_driver);
 
 MODULE_AUTHOR("Marvell International Ltd.");
 MODULE_DESCRIPTION("Marvell WiFi-Ex USB Driver version" USB_VERSION);
index 18fbb96a46e94f290dbf173e1e9db1ceaffc5487..b1ab8da121dd8a9e015fb0a82bf7e0c5ab031749 100644 (file)
@@ -145,21 +145,6 @@ int mwifiex_init_fw_complete(struct mwifiex_adapter *adapter)
        return 0;
 }
 
-/*
- * Firmware shutdown complete callback handler.
- *
- * This function sets the hardware status to not ready and wakes up
- * the function waiting on the init wait queue for the firmware
- * shutdown to complete.
- */
-int mwifiex_shutdown_fw_complete(struct mwifiex_adapter *adapter)
-{
-       adapter->hw_status = MWIFIEX_HW_STATUS_NOT_READY;
-       adapter->init_wait_q_woken = true;
-       wake_up_interruptible(&adapter->init_wait_q);
-       return 0;
-}
-
 /*
  * This function sends init/shutdown command
  * to firmware.
index ec622a08a48607076d0f481838106b3b30264963..256496bfbafb2ef29b4560c9d93753f731035656 100644 (file)
@@ -72,6 +72,7 @@
 #define RF5592                         0x000f
 #define RF3070                         0x3070
 #define RF3290                         0x3290
+#define RF5350                         0x5350
 #define RF5360                         0x5360
 #define RF5362                         0x5362
 #define RF5370                         0x5370
@@ -2286,6 +2287,8 @@ struct mac_iveiv_entry {
 #define RFCSR30_RX_H20M                        FIELD8(0x04)
 #define RFCSR30_RX_VCM                 FIELD8(0x18)
 #define RFCSR30_RF_CALIBRATION         FIELD8(0x80)
+#define RF3322_RFCSR30_TX_H20M         FIELD8(0x01)
+#define RF3322_RFCSR30_RX_H20M         FIELD8(0x02)
 
 /*
  * RFCSR 31:
@@ -2300,6 +2303,12 @@ struct mac_iveiv_entry {
 /* RFCSR 36 bits for RF3053 */
 #define RFCSR36_RF_BS                  FIELD8(0x80)
 
+/*
+ * RFCSR 34:
+ */
+#define RFCSR34_TX0_EXT_PA             FIELD8(0x04)
+#define RFCSR34_TX1_EXT_PA             FIELD8(0x08)
+
 /*
  * RFCSR 38:
  */
@@ -2311,6 +2320,18 @@ struct mac_iveiv_entry {
 #define RFCSR39_RX_DIV                 FIELD8(0x40)
 #define RFCSR39_RX_LO2_EN              FIELD8(0x80)
 
+/*
+ * RFCSR 41:
+ */
+#define RFCSR41_BIT1                   FIELD8(0x01)
+#define RFCSR41_BIT4                   FIELD8(0x08)
+
+/*
+ * RFCSR 42:
+ */
+#define RFCSR42_BIT1                   FIELD8(0x01)
+#define RFCSR42_BIT4                   FIELD8(0x08)
+
 /*
  * RFCSR 49:
  */
@@ -2324,6 +2345,8 @@ struct mac_iveiv_entry {
  * RFCSR 50:
  */
 #define RFCSR50_TX                     FIELD8(0x3f)
+#define RFCSR50_TX0_EXT_PA             FIELD8(0x02)
+#define RFCSR50_TX1_EXT_PA             FIELD8(0x10)
 #define RFCSR50_EP                     FIELD8(0xc0)
 /* bits for RT3593 */
 #define RFCSR50_TX_LO1_EN              FIELD8(0x20)
@@ -2471,6 +2494,8 @@ enum rt2800_eeprom_word {
  * INTERNAL_TX_ALC: 0: disable, 1: enable
  * BT_COEXIST: 0: disable, 1: enable
  * DAC_TEST: 0: disable, 1: enable
+ * EXTERNAL_TX0_PA: 0: disable, 1: enable (only on RT3352)
+ * EXTERNAL_TX1_PA: 0: disable, 1: enable (only on RT3352)
  */
 #define EEPROM_NIC_CONF1_HW_RADIO              FIELD16(0x0001)
 #define EEPROM_NIC_CONF1_EXTERNAL_TX_ALC       FIELD16(0x0002)
@@ -2487,6 +2512,8 @@ enum rt2800_eeprom_word {
 #define EEPROM_NIC_CONF1_INTERNAL_TX_ALC       FIELD16(0x2000)
 #define EEPROM_NIC_CONF1_BT_COEXIST            FIELD16(0x4000)
 #define EEPROM_NIC_CONF1_DAC_TEST              FIELD16(0x8000)
+#define EEPROM_NIC_CONF1_EXTERNAL_TX0_PA_3352  FIELD16(0x4000)
+#define EEPROM_NIC_CONF1_EXTERNAL_TX1_PA_3352  FIELD16(0x8000)
 
 /*
  * EEPROM frequency
index 5436cdb079375c2d5cdc84e870db35e7f255ccb5..572cdea4ca25c474203806d68b77e699ef56a05e 100644 (file)
@@ -373,9 +373,6 @@ static int rt2800_enable_wlan_rt3290(struct rt2x00_dev *rt2x00dev)
        int i, count;
 
        rt2800_register_read(rt2x00dev, WLAN_FUN_CTRL, &reg);
-       if (rt2x00_get_field32(reg, WLAN_EN))
-               return 0;
-
        rt2x00_set_field32(&reg, WLAN_GPIO_OUT_OE_BIT_ALL, 0xff);
        rt2x00_set_field32(&reg, FRC_WL_ANT_SET, 1);
        rt2x00_set_field32(&reg, WLAN_CLK_EN, 0);
@@ -967,8 +964,6 @@ static void rt2800_update_beacons_setup(struct rt2x00_dev *rt2x00dev)
                bcn_num++;
        }
 
-       WARN_ON_ONCE(bcn_num != rt2x00dev->intf_beaconing);
-
        rt2800_register_write(rt2x00dev, BCN_OFFSET0, (u32) reg);
        rt2800_register_write(rt2x00dev, BCN_OFFSET1, (u32) (reg >> 32));
 
@@ -1937,6 +1932,11 @@ static void rt2800_config_lna_gain(struct rt2x00_dev *rt2x00dev,
        rt2x00dev->lna_gain = lna_gain;
 }
 
+static inline bool rt2800_clk_is_20mhz(struct rt2x00_dev *rt2x00dev)
+{
+       return clk_get_rate(rt2x00dev->clk) == 20000000;
+}
+
 #define FREQ_OFFSET_BOUND      0x5f
 
 static void rt2800_freq_cal_mode1(struct rt2x00_dev *rt2x00dev)
@@ -2758,6 +2758,13 @@ static void rt2800_config_channel_rf53xx(struct rt2x00_dev *rt2x00dev,
                                        0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8d,
                                        0x8a, 0x88, 0x88, 0x87, 0x87, 0x86};
 
+                               rt2800_rfcsr_write(rt2x00dev, 59,
+                                                  r59_non_bt[idx]);
+                       } else if (rt2x00_rt(rt2x00dev, RT5350)) {
+                               static const char r59_non_bt[] = {0x0b, 0x0b,
+                                       0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0a,
+                                       0x0a, 0x09, 0x08, 0x07, 0x07, 0x06};
+
                                rt2800_rfcsr_write(rt2x00dev, 59,
                                                   r59_non_bt[idx]);
                        }
@@ -3197,6 +3204,7 @@ static void rt2800_config_channel(struct rt2x00_dev *rt2x00dev,
                rt2800_config_channel_rf3322(rt2x00dev, conf, rf, info);
                break;
        case RF3070:
+       case RF5350:
        case RF5360:
        case RF5362:
        case RF5370:
@@ -3215,6 +3223,7 @@ static void rt2800_config_channel(struct rt2x00_dev *rt2x00dev,
        if (rt2x00_rf(rt2x00dev, RF3070) ||
            rt2x00_rf(rt2x00dev, RF3290) ||
            rt2x00_rf(rt2x00dev, RF3322) ||
+           rt2x00_rf(rt2x00dev, RF5350) ||
            rt2x00_rf(rt2x00dev, RF5360) ||
            rt2x00_rf(rt2x00dev, RF5362) ||
            rt2x00_rf(rt2x00dev, RF5370) ||
@@ -3222,8 +3231,17 @@ static void rt2800_config_channel(struct rt2x00_dev *rt2x00dev,
            rt2x00_rf(rt2x00dev, RF5390) ||
            rt2x00_rf(rt2x00dev, RF5392)) {
                rt2800_rfcsr_read(rt2x00dev, 30, &rfcsr);
-               rt2x00_set_field8(&rfcsr, RFCSR30_TX_H20M, 0);
-               rt2x00_set_field8(&rfcsr, RFCSR30_RX_H20M, 0);
+               if (rt2x00_rf(rt2x00dev, RF3322)) {
+                       rt2x00_set_field8(&rfcsr, RF3322_RFCSR30_TX_H20M,
+                                         conf_is_ht40(conf));
+                       rt2x00_set_field8(&rfcsr, RF3322_RFCSR30_RX_H20M,
+                                         conf_is_ht40(conf));
+               } else {
+                       rt2x00_set_field8(&rfcsr, RFCSR30_TX_H20M,
+                                         conf_is_ht40(conf));
+                       rt2x00_set_field8(&rfcsr, RFCSR30_RX_H20M,
+                                         conf_is_ht40(conf));
+               }
                rt2800_rfcsr_write(rt2x00dev, 30, rfcsr);
 
                rt2800_rfcsr_read(rt2x00dev, 3, &rfcsr);
@@ -3234,11 +3252,18 @@ static void rt2800_config_channel(struct rt2x00_dev *rt2x00dev,
        /*
         * Change BBP settings
         */
+
        if (rt2x00_rt(rt2x00dev, RT3352)) {
+               rt2800_bbp_write(rt2x00dev, 62, 0x37 - rt2x00dev->lna_gain);
+               rt2800_bbp_write(rt2x00dev, 63, 0x37 - rt2x00dev->lna_gain);
+               rt2800_bbp_write(rt2x00dev, 64, 0x37 - rt2x00dev->lna_gain);
+
                rt2800_bbp_write(rt2x00dev, 27, 0x0);
                rt2800_bbp_write(rt2x00dev, 66, 0x26 + rt2x00dev->lna_gain);
                rt2800_bbp_write(rt2x00dev, 27, 0x20);
                rt2800_bbp_write(rt2x00dev, 66, 0x26 + rt2x00dev->lna_gain);
+               rt2800_bbp_write(rt2x00dev, 86, 0x38);
+               rt2800_bbp_write(rt2x00dev, 83, 0x6a);
        } else if (rt2x00_rt(rt2x00dev, RT3593)) {
                if (rf->channel > 14) {
                        /* Disable CCK Packet detection on 5GHz */
@@ -3456,7 +3481,8 @@ static void rt2800_config_channel(struct rt2x00_dev *rt2x00dev,
        /*
         * Clear update flag
         */
-       if (rt2x00_rt(rt2x00dev, RT3352)) {
+       if (rt2x00_rt(rt2x00dev, RT3352) ||
+           rt2x00_rt(rt2x00dev, RT5350)) {
                rt2800_bbp_read(rt2x00dev, 49, &bbp);
                rt2x00_set_field8(&bbp, BBP49_UPDATE_FLAG, 0);
                rt2800_bbp_write(rt2x00dev, 49, bbp);
@@ -4337,6 +4363,7 @@ void rt2800_vco_calibration(struct rt2x00_dev *rt2x00dev)
        case RF3053:
        case RF3070:
        case RF3290:
+       case RF5350:
        case RF5360:
        case RF5362:
        case RF5370:
@@ -4719,6 +4746,8 @@ static int rt2800_init_registers(struct rt2x00_dev *rt2x00dev)
                rt2800_register_write(rt2x00dev, TX_SW_CFG0, 0x00000404);
                rt2800_register_write(rt2x00dev, TX_SW_CFG1, 0x00000000);
                rt2800_register_write(rt2x00dev, TX_SW_CFG2, 0x00000000);
+       } else if (rt2x00_rt(rt2x00dev, RT5350)) {
+               rt2800_register_write(rt2x00dev, TX_SW_CFG0, 0x00000404);
        } else {
                rt2800_register_write(rt2x00dev, TX_SW_CFG0, 0x00000000);
                rt2800_register_write(rt2x00dev, TX_SW_CFG1, 0x00080606);
@@ -4743,15 +4772,16 @@ static int rt2800_init_registers(struct rt2x00_dev *rt2x00dev)
 
        rt2800_register_read(rt2x00dev, MAX_LEN_CFG, &reg);
        rt2x00_set_field32(&reg, MAX_LEN_CFG_MAX_MPDU, AGGREGATION_SIZE);
-       if (rt2x00_rt_rev_gte(rt2x00dev, RT2872, REV_RT2872E) ||
-           rt2x00_rt(rt2x00dev, RT2883) ||
-           rt2x00_rt_rev_lt(rt2x00dev, RT3070, REV_RT3070E)) {
+       if (rt2x00_is_usb(rt2x00dev)) {
+               drv_data->max_psdu = 3;
+       } else if (rt2x00_rt_rev_gte(rt2x00dev, RT2872, REV_RT2872E) ||
+                  rt2x00_rt(rt2x00dev, RT2883) ||
+                  rt2x00_rt_rev_lt(rt2x00dev, RT3070, REV_RT3070E)) {
                drv_data->max_psdu = 2;
-               rt2x00_set_field32(&reg, MAX_LEN_CFG_MAX_PSDU, 2);
        } else {
                drv_data->max_psdu = 1;
-               rt2x00_set_field32(&reg, MAX_LEN_CFG_MAX_PSDU, 1);
        }
+       rt2x00_set_field32(&reg, MAX_LEN_CFG_MAX_PSDU, drv_data->max_psdu);
        rt2x00_set_field32(&reg, MAX_LEN_CFG_MIN_PSDU, 10);
        rt2x00_set_field32(&reg, MAX_LEN_CFG_MIN_MPDU, 10);
        rt2800_register_write(rt2x00dev, MAX_LEN_CFG, reg);
@@ -4769,8 +4799,8 @@ static int rt2800_init_registers(struct rt2x00_dev *rt2x00dev)
        rt2800_register_write(rt2x00dev, PBF_MAX_PCNT, 0x1f3fbf9f);
 
        rt2800_register_read(rt2x00dev, TX_RTY_CFG, &reg);
-       rt2x00_set_field32(&reg, TX_RTY_CFG_SHORT_RTY_LIMIT, 15);
-       rt2x00_set_field32(&reg, TX_RTY_CFG_LONG_RTY_LIMIT, 31);
+       rt2x00_set_field32(&reg, TX_RTY_CFG_SHORT_RTY_LIMIT, 2);
+       rt2x00_set_field32(&reg, TX_RTY_CFG_LONG_RTY_LIMIT, 2);
        rt2x00_set_field32(&reg, TX_RTY_CFG_LONG_RTY_THRE, 2000);
        rt2x00_set_field32(&reg, TX_RTY_CFG_NON_AGG_RTY_MODE, 0);
        rt2x00_set_field32(&reg, TX_RTY_CFG_AGG_RTY_MODE, 0);
@@ -4902,10 +4932,10 @@ static int rt2800_init_registers(struct rt2x00_dev *rt2x00dev)
        rt2800_register_write(rt2x00dev, TXOP_HLDR_ET, reg);
 
        rt2800_register_read(rt2x00dev, TX_RTS_CFG, &reg);
-       rt2x00_set_field32(&reg, TX_RTS_CFG_AUTO_RTS_RETRY_LIMIT, 32);
+       rt2x00_set_field32(&reg, TX_RTS_CFG_AUTO_RTS_RETRY_LIMIT, 7);
        rt2x00_set_field32(&reg, TX_RTS_CFG_RTS_THRES,
                           IEEE80211_MAX_RTS_THRESHOLD);
-       rt2x00_set_field32(&reg, TX_RTS_CFG_RTS_FBK_EN, 0);
+       rt2x00_set_field32(&reg, TX_RTS_CFG_RTS_FBK_EN, 1);
        rt2800_register_write(rt2x00dev, TX_RTS_CFG, reg);
 
        rt2800_register_write(rt2x00dev, EXP_ACK_TIME, 0x002400ca);
@@ -5363,9 +5393,13 @@ static void rt2800_init_bbp_3352(struct rt2x00_dev *rt2x00dev)
 
        rt2800_bbp_write(rt2x00dev, 82, 0x62);
 
-       rt2800_bbp_write(rt2x00dev, 83, 0x6a);
-
-       rt2800_bbp_write(rt2x00dev, 84, 0x99);
+       if (rt2x00_rt(rt2x00dev, RT5350)) {
+               rt2800_bbp_write(rt2x00dev, 83, 0x7a);
+               rt2800_bbp_write(rt2x00dev, 84, 0x9a);
+       } else {
+               rt2800_bbp_write(rt2x00dev, 83, 0x6a);
+               rt2800_bbp_write(rt2x00dev, 84, 0x99);
+       }
 
        rt2800_bbp_write(rt2x00dev, 86, 0x38);
 
@@ -5379,9 +5413,13 @@ static void rt2800_init_bbp_3352(struct rt2x00_dev *rt2x00dev)
 
        rt2800_bbp_write(rt2x00dev, 104, 0x92);
 
-       rt2800_bbp_write(rt2x00dev, 105, 0x34);
-
-       rt2800_bbp_write(rt2x00dev, 106, 0x05);
+       if (rt2x00_rt(rt2x00dev, RT5350)) {
+               rt2800_bbp_write(rt2x00dev, 105, 0x3c);
+               rt2800_bbp_write(rt2x00dev, 106, 0x03);
+       } else {
+               rt2800_bbp_write(rt2x00dev, 105, 0x34);
+               rt2800_bbp_write(rt2x00dev, 106, 0x05);
+       }
 
        rt2800_bbp_write(rt2x00dev, 120, 0x50);
 
@@ -5406,6 +5444,16 @@ static void rt2800_init_bbp_3352(struct rt2x00_dev *rt2x00dev)
        rt2800_bbp_write(rt2x00dev, 143, 0xa2);
 
        rt2800_bbp_write(rt2x00dev, 148, 0xc8);
+
+       if (rt2x00_rt(rt2x00dev, RT5350)) {
+               /* Antenna Software OFDM */
+               rt2800_bbp_write(rt2x00dev, 150, 0x40);
+               /* Antenna Software CCK */
+               rt2800_bbp_write(rt2x00dev, 151, 0x30);
+               rt2800_bbp_write(rt2x00dev, 152, 0xa3);
+               /* Clear previously selected antenna */
+               rt2800_bbp_write(rt2x00dev, 154, 0);
+       }
 }
 
 static void rt2800_init_bbp_3390(struct rt2x00_dev *rt2x00dev)
@@ -5706,6 +5754,7 @@ static void rt2800_init_bbp(struct rt2x00_dev *rt2x00dev)
                rt2800_init_bbp_3290(rt2x00dev);
                break;
        case RT3352:
+       case RT5350:
                rt2800_init_bbp_3352(rt2x00dev);
                break;
        case RT3390:
@@ -6179,6 +6228,12 @@ static void rt2800_init_rfcsr_3290(struct rt2x00_dev *rt2x00dev)
 
 static void rt2800_init_rfcsr_3352(struct rt2x00_dev *rt2x00dev)
 {
+       int tx0_int_pa = test_bit(CAPABILITY_INTERNAL_PA_TX0,
+                                 &rt2x00dev->cap_flags);
+       int tx1_int_pa = test_bit(CAPABILITY_INTERNAL_PA_TX1,
+                                 &rt2x00dev->cap_flags);
+       u8 rfcsr;
+
        rt2800_rf_init_calibration(rt2x00dev, 30);
 
        rt2800_rfcsr_write(rt2x00dev, 0, 0xf0);
@@ -6214,15 +6269,30 @@ static void rt2800_init_rfcsr_3352(struct rt2x00_dev *rt2x00dev)
        rt2800_rfcsr_write(rt2x00dev, 31, 0x80);
        rt2800_rfcsr_write(rt2x00dev, 32, 0x80);
        rt2800_rfcsr_write(rt2x00dev, 33, 0x00);
-       rt2800_rfcsr_write(rt2x00dev, 34, 0x01);
+       rfcsr = 0x01;
+       if (!tx0_int_pa)
+               rt2x00_set_field8(&rfcsr, RFCSR34_TX0_EXT_PA, 1);
+       if (!tx1_int_pa)
+               rt2x00_set_field8(&rfcsr, RFCSR34_TX1_EXT_PA, 1);
+       rt2800_rfcsr_write(rt2x00dev, 34, rfcsr);
        rt2800_rfcsr_write(rt2x00dev, 35, 0x03);
        rt2800_rfcsr_write(rt2x00dev, 36, 0xbd);
        rt2800_rfcsr_write(rt2x00dev, 37, 0x3c);
        rt2800_rfcsr_write(rt2x00dev, 38, 0x5f);
        rt2800_rfcsr_write(rt2x00dev, 39, 0xc5);
        rt2800_rfcsr_write(rt2x00dev, 40, 0x33);
-       rt2800_rfcsr_write(rt2x00dev, 41, 0x5b);
-       rt2800_rfcsr_write(rt2x00dev, 42, 0x5b);
+       rfcsr = 0x52;
+       if (tx0_int_pa) {
+               rt2x00_set_field8(&rfcsr, RFCSR41_BIT1, 1);
+               rt2x00_set_field8(&rfcsr, RFCSR41_BIT4, 1);
+       }
+       rt2800_rfcsr_write(rt2x00dev, 41, rfcsr);
+       rfcsr = 0x52;
+       if (tx1_int_pa) {
+               rt2x00_set_field8(&rfcsr, RFCSR42_BIT1, 1);
+               rt2x00_set_field8(&rfcsr, RFCSR42_BIT4, 1);
+       }
+       rt2800_rfcsr_write(rt2x00dev, 42, rfcsr);
        rt2800_rfcsr_write(rt2x00dev, 43, 0xdb);
        rt2800_rfcsr_write(rt2x00dev, 44, 0xdb);
        rt2800_rfcsr_write(rt2x00dev, 45, 0xdb);
@@ -6230,15 +6300,20 @@ static void rt2800_init_rfcsr_3352(struct rt2x00_dev *rt2x00dev)
        rt2800_rfcsr_write(rt2x00dev, 47, 0x0d);
        rt2800_rfcsr_write(rt2x00dev, 48, 0x14);
        rt2800_rfcsr_write(rt2x00dev, 49, 0x00);
-       rt2800_rfcsr_write(rt2x00dev, 50, 0x2d);
-       rt2800_rfcsr_write(rt2x00dev, 51, 0x7f);
-       rt2800_rfcsr_write(rt2x00dev, 52, 0x00);
-       rt2800_rfcsr_write(rt2x00dev, 53, 0x52);
-       rt2800_rfcsr_write(rt2x00dev, 54, 0x1b);
-       rt2800_rfcsr_write(rt2x00dev, 55, 0x7f);
-       rt2800_rfcsr_write(rt2x00dev, 56, 0x00);
-       rt2800_rfcsr_write(rt2x00dev, 57, 0x52);
-       rt2800_rfcsr_write(rt2x00dev, 58, 0x1b);
+       rfcsr = 0x2d;
+       if (!tx0_int_pa)
+               rt2x00_set_field8(&rfcsr, RFCSR50_TX0_EXT_PA, 1);
+       if (!tx1_int_pa)
+               rt2x00_set_field8(&rfcsr, RFCSR50_TX1_EXT_PA, 1);
+       rt2800_rfcsr_write(rt2x00dev, 50, rfcsr);
+       rt2800_rfcsr_write(rt2x00dev, 51, (tx0_int_pa ? 0x7f : 0x52));
+       rt2800_rfcsr_write(rt2x00dev, 52, (tx0_int_pa ? 0x00 : 0xc0));
+       rt2800_rfcsr_write(rt2x00dev, 53, (tx0_int_pa ? 0x52 : 0xd2));
+       rt2800_rfcsr_write(rt2x00dev, 54, (tx0_int_pa ? 0x1b : 0xc0));
+       rt2800_rfcsr_write(rt2x00dev, 55, (tx1_int_pa ? 0x7f : 0x52));
+       rt2800_rfcsr_write(rt2x00dev, 56, (tx1_int_pa ? 0x00 : 0xc0));
+       rt2800_rfcsr_write(rt2x00dev, 57, (tx0_int_pa ? 0x52 : 0x49));
+       rt2800_rfcsr_write(rt2x00dev, 58, (tx1_int_pa ? 0x1b : 0xc0));
        rt2800_rfcsr_write(rt2x00dev, 59, 0x00);
        rt2800_rfcsr_write(rt2x00dev, 60, 0x00);
        rt2800_rfcsr_write(rt2x00dev, 61, 0x00);
@@ -6490,6 +6565,76 @@ static void rt2800_init_rfcsr_3593(struct rt2x00_dev *rt2x00dev)
        /* TODO: enable stream mode support */
 }
 
+static void rt2800_init_rfcsr_5350(struct rt2x00_dev *rt2x00dev)
+{
+       rt2800_rfcsr_write(rt2x00dev, 0, 0xf0);
+       rt2800_rfcsr_write(rt2x00dev, 1, 0x23);
+       rt2800_rfcsr_write(rt2x00dev, 2, 0x50);
+       rt2800_rfcsr_write(rt2x00dev, 3, 0x08);
+       rt2800_rfcsr_write(rt2x00dev, 4, 0x49);
+       rt2800_rfcsr_write(rt2x00dev, 5, 0x10);
+       rt2800_rfcsr_write(rt2x00dev, 6, 0xe0);
+       rt2800_rfcsr_write(rt2x00dev, 7, 0x00);
+       rt2800_rfcsr_write(rt2x00dev, 8, 0xf1);
+       rt2800_rfcsr_write(rt2x00dev, 9, 0x02);
+       rt2800_rfcsr_write(rt2x00dev, 10, 0x53);
+       rt2800_rfcsr_write(rt2x00dev, 11, 0x4a);
+       rt2800_rfcsr_write(rt2x00dev, 12, 0x46);
+       if (rt2800_clk_is_20mhz(rt2x00dev))
+               rt2800_rfcsr_write(rt2x00dev, 13, 0x1f);
+       else
+               rt2800_rfcsr_write(rt2x00dev, 13, 0x9f);
+       rt2800_rfcsr_write(rt2x00dev, 14, 0x00);
+       rt2800_rfcsr_write(rt2x00dev, 15, 0x00);
+       rt2800_rfcsr_write(rt2x00dev, 16, 0xc0);
+       rt2800_rfcsr_write(rt2x00dev, 18, 0x03);
+       rt2800_rfcsr_write(rt2x00dev, 19, 0x00);
+       rt2800_rfcsr_write(rt2x00dev, 20, 0x00);
+       rt2800_rfcsr_write(rt2x00dev, 21, 0x00);
+       rt2800_rfcsr_write(rt2x00dev, 22, 0x20);
+       rt2800_rfcsr_write(rt2x00dev, 23, 0x00);
+       rt2800_rfcsr_write(rt2x00dev, 24, 0x00);
+       rt2800_rfcsr_write(rt2x00dev, 25, 0x80);
+       rt2800_rfcsr_write(rt2x00dev, 26, 0x00);
+       rt2800_rfcsr_write(rt2x00dev, 27, 0x03);
+       rt2800_rfcsr_write(rt2x00dev, 28, 0x00);
+       rt2800_rfcsr_write(rt2x00dev, 29, 0xd0);
+       rt2800_rfcsr_write(rt2x00dev, 30, 0x10);
+       rt2800_rfcsr_write(rt2x00dev, 31, 0x80);
+       rt2800_rfcsr_write(rt2x00dev, 32, 0x80);
+       rt2800_rfcsr_write(rt2x00dev, 33, 0x00);
+       rt2800_rfcsr_write(rt2x00dev, 34, 0x07);
+       rt2800_rfcsr_write(rt2x00dev, 35, 0x12);
+       rt2800_rfcsr_write(rt2x00dev, 36, 0x00);
+       rt2800_rfcsr_write(rt2x00dev, 37, 0x08);
+       rt2800_rfcsr_write(rt2x00dev, 38, 0x85);
+       rt2800_rfcsr_write(rt2x00dev, 39, 0x1b);
+       rt2800_rfcsr_write(rt2x00dev, 40, 0x0b);
+       rt2800_rfcsr_write(rt2x00dev, 41, 0xbb);
+       rt2800_rfcsr_write(rt2x00dev, 42, 0xd5);
+       rt2800_rfcsr_write(rt2x00dev, 43, 0x9b);
+       rt2800_rfcsr_write(rt2x00dev, 44, 0x0c);
+       rt2800_rfcsr_write(rt2x00dev, 45, 0xa6);
+       rt2800_rfcsr_write(rt2x00dev, 46, 0x73);
+       rt2800_rfcsr_write(rt2x00dev, 47, 0x00);
+       rt2800_rfcsr_write(rt2x00dev, 48, 0x10);
+       rt2800_rfcsr_write(rt2x00dev, 49, 0x80);
+       rt2800_rfcsr_write(rt2x00dev, 50, 0x00);
+       rt2800_rfcsr_write(rt2x00dev, 51, 0x00);
+       rt2800_rfcsr_write(rt2x00dev, 52, 0x38);
+       rt2800_rfcsr_write(rt2x00dev, 53, 0x00);
+       rt2800_rfcsr_write(rt2x00dev, 54, 0x38);
+       rt2800_rfcsr_write(rt2x00dev, 55, 0x43);
+       rt2800_rfcsr_write(rt2x00dev, 56, 0x82);
+       rt2800_rfcsr_write(rt2x00dev, 57, 0x00);
+       rt2800_rfcsr_write(rt2x00dev, 58, 0x39);
+       rt2800_rfcsr_write(rt2x00dev, 59, 0x0b);
+       rt2800_rfcsr_write(rt2x00dev, 60, 0x45);
+       rt2800_rfcsr_write(rt2x00dev, 61, 0xd1);
+       rt2800_rfcsr_write(rt2x00dev, 62, 0x00);
+       rt2800_rfcsr_write(rt2x00dev, 63, 0x00);
+}
+
 static void rt2800_init_rfcsr_5390(struct rt2x00_dev *rt2x00dev)
 {
        rt2800_rf_init_calibration(rt2x00dev, 2);
@@ -6727,6 +6872,9 @@ static void rt2800_init_rfcsr(struct rt2x00_dev *rt2x00dev)
        case RT3593:
                rt2800_init_rfcsr_3593(rt2x00dev);
                break;
+       case RT5350:
+               rt2800_init_rfcsr_5350(rt2x00dev);
+               break;
        case RT5390:
                rt2800_init_rfcsr_5390(rt2x00dev);
                break;
@@ -7104,6 +7252,10 @@ static int rt2800_init_eeprom(struct rt2x00_dev *rt2x00dev)
            rt2x00_rt(rt2x00dev, RT5390) ||
            rt2x00_rt(rt2x00dev, RT5392))
                rt2800_eeprom_read(rt2x00dev, EEPROM_CHIP_ID, &rf);
+       else if (rt2x00_rt(rt2x00dev, RT3352))
+               rf = RF3322;
+       else if (rt2x00_rt(rt2x00dev, RT5350))
+               rf = RF5350;
        else
                rf = rt2x00_get_field16(eeprom, EEPROM_NIC_CONF0_RF_TYPE);
 
@@ -7122,6 +7274,7 @@ static int rt2800_init_eeprom(struct rt2x00_dev *rt2x00dev)
        case RF3290:
        case RF3320:
        case RF3322:
+       case RF5350:
        case RF5360:
        case RF5362:
        case RF5370:
@@ -7193,7 +7346,8 @@ static int rt2800_init_eeprom(struct rt2x00_dev *rt2x00dev)
        /*
         * Detect if this device has Bluetooth co-existence.
         */
-       if (rt2x00_get_field16(eeprom, EEPROM_NIC_CONF1_BT_COEXIST))
+       if (!rt2x00_rt(rt2x00dev, RT3352) &&
+           rt2x00_get_field16(eeprom, EEPROM_NIC_CONF1_BT_COEXIST))
                __set_bit(CAPABILITY_BT_COEXIST, &rt2x00dev->cap_flags);
 
        /*
@@ -7222,6 +7376,22 @@ static int rt2800_init_eeprom(struct rt2x00_dev *rt2x00dev)
                                        EIRP_MAX_TX_POWER_LIMIT)
                __set_bit(CAPABILITY_POWER_LIMIT, &rt2x00dev->cap_flags);
 
+       /*
+        * Detect if device uses internal or external PA
+        */
+       rt2800_eeprom_read(rt2x00dev, EEPROM_NIC_CONF1, &eeprom);
+
+       if (rt2x00_rt(rt2x00dev, RT3352)) {
+               if (!rt2x00_get_field16(eeprom,
+                   EEPROM_NIC_CONF1_EXTERNAL_TX0_PA_3352))
+                   __set_bit(CAPABILITY_INTERNAL_PA_TX0,
+                             &rt2x00dev->cap_flags);
+               if (!rt2x00_get_field16(eeprom,
+                   EEPROM_NIC_CONF1_EXTERNAL_TX1_PA_3352))
+                   __set_bit(CAPABILITY_INTERNAL_PA_TX1,
+                             &rt2x00dev->cap_flags);
+       }
+
        return 0;
 }
 
@@ -7366,6 +7536,27 @@ static const struct rf_channel rf_vals_3x[] = {
        {173, 0x61, 0, 9},
 };
 
+/*
+ * RF value list for rt3xxx with Xtal20MHz
+ * Supports: 2.4 GHz (all) (RF3322)
+ */
+static const struct rf_channel rf_vals_3x_xtal20[] = {
+       {1,    0xE2,     2,  0x14},
+       {2,    0xE3,     2,  0x14},
+       {3,    0xE4,     2,  0x14},
+       {4,    0xE5,     2,  0x14},
+       {5,    0xE6,     2,  0x14},
+       {6,    0xE7,     2,  0x14},
+       {7,    0xE8,     2,  0x14},
+       {8,    0xE9,     2,  0x14},
+       {9,    0xEA,     2,  0x14},
+       {10,   0xEB,     2,  0x14},
+       {11,   0xEC,     2,  0x14},
+       {12,   0xED,     2,  0x14},
+       {13,   0xEE,     2,  0x14},
+       {14,   0xF0,     2,  0x18},
+};
+
 static const struct rf_channel rf_vals_5592_xtal20[] = {
        /* Channel, N, K, mod, R */
        {1, 482, 4, 10, 3},
@@ -7513,6 +7704,13 @@ static int rt2800_probe_hw_mode(struct rt2x00_dev *rt2x00dev)
         */
        rt2x00dev->hw->wiphy->flags &= ~WIPHY_FLAG_PS_ON_BY_DEFAULT;
 
+       /*
+        * Change default retry settings to values corresponding more closely
+        * to rate[0].count setting of minstrel rate control algorithm.
+        */
+       rt2x00dev->hw->wiphy->retry_short = 2;
+       rt2x00dev->hw->wiphy->retry_long = 2;
+
        /*
         * Initialize all hw fields.
         */
@@ -7580,6 +7778,7 @@ static int rt2800_probe_hw_mode(struct rt2x00_dev *rt2x00dev)
        case RF3290:
        case RF3320:
        case RF3322:
+       case RF5350:
        case RF5360:
        case RF5362:
        case RF5370:
@@ -7587,7 +7786,10 @@ static int rt2800_probe_hw_mode(struct rt2x00_dev *rt2x00dev)
        case RF5390:
        case RF5392:
                spec->num_channels = 14;
-               spec->channels = rf_vals_3x;
+               if (rt2800_clk_is_20mhz(rt2x00dev))
+                       spec->channels = rf_vals_3x_xtal20;
+               else
+                       spec->channels = rf_vals_3x;
                break;
 
        case RF3052:
@@ -7713,6 +7915,7 @@ static int rt2800_probe_hw_mode(struct rt2x00_dev *rt2x00dev)
        case RF3053:
        case RF3070:
        case RF3290:
+       case RF5350:
        case RF5360:
        case RF5362:
        case RF5370:
@@ -7753,6 +7956,7 @@ static int rt2800_probe_rt(struct rt2x00_dev *rt2x00dev)
        case RT3390:
        case RT3572:
        case RT3593:
+       case RT5350:
        case RT5390:
        case RT5392:
        case RT5592:
index f38c44061b5ba664f832d62b4a899b8a80568b1f..205a7b8ac8a7a252845f8e8c5866f2ed4cd1e14d 100644 (file)
@@ -123,7 +123,7 @@ static inline bool rt2800usb_entry_txstatus_timeout(struct queue_entry *entry)
        if (!test_bit(ENTRY_DATA_STATUS_PENDING, &entry->flags))
                return false;
 
-       tout = time_after(jiffies, entry->last_action + msecs_to_jiffies(100));
+       tout = time_after(jiffies, entry->last_action + msecs_to_jiffies(500));
        if (unlikely(tout))
                rt2x00_dbg(entry->queue->rt2x00dev,
                           "TX status timeout for entry %d in queue %d\n",
@@ -435,47 +435,6 @@ static int rt2800usb_set_device_state(struct rt2x00_dev *rt2x00dev,
        return retval;
 }
 
-/*
- * Watchdog handlers
- */
-static void rt2800usb_watchdog(struct rt2x00_dev *rt2x00dev)
-{
-       unsigned int i;
-       u32 reg;
-
-       rt2x00usb_register_read(rt2x00dev, TXRXQ_PCNT, &reg);
-       if (rt2x00_get_field32(reg, TXRXQ_PCNT_TX0Q)) {
-               rt2x00_warn(rt2x00dev, "TX HW queue 0 timed out, invoke forced kick\n");
-
-               rt2x00usb_register_write(rt2x00dev, PBF_CFG, 0xf40012);
-
-               for (i = 0; i < 10; i++) {
-                       udelay(10);
-                       if (!rt2x00_get_field32(reg, TXRXQ_PCNT_TX0Q))
-                               break;
-               }
-
-               rt2x00usb_register_write(rt2x00dev, PBF_CFG, 0xf40006);
-       }
-
-       rt2x00usb_register_read(rt2x00dev, TXRXQ_PCNT, &reg);
-       if (rt2x00_get_field32(reg, TXRXQ_PCNT_TX1Q)) {
-               rt2x00_warn(rt2x00dev, "TX HW queue 1 timed out, invoke forced kick\n");
-
-               rt2x00usb_register_write(rt2x00dev, PBF_CFG, 0xf4000a);
-
-               for (i = 0; i < 10; i++) {
-                       udelay(10);
-                       if (!rt2x00_get_field32(reg, TXRXQ_PCNT_TX1Q))
-                               break;
-               }
-
-               rt2x00usb_register_write(rt2x00dev, PBF_CFG, 0xf40006);
-       }
-
-       rt2x00usb_watchdog(rt2x00dev);
-}
-
 /*
  * TX descriptor initialization
  */
@@ -643,10 +602,9 @@ static void rt2800usb_txdone_nostatus(struct rt2x00_dev *rt2x00dev)
                            !test_bit(ENTRY_DATA_STATUS_PENDING, &entry->flags))
                                break;
 
-                       if (test_bit(ENTRY_DATA_IO_FAILED, &entry->flags))
+                       if (test_bit(ENTRY_DATA_IO_FAILED, &entry->flags) ||
+                           rt2800usb_entry_txstatus_timeout(entry))
                                rt2x00lib_txdone_noinfo(entry, TXDONE_FAILURE);
-                       else if (rt2800usb_entry_txstatus_timeout(entry))
-                               rt2x00lib_txdone_noinfo(entry, TXDONE_UNKNOWN);
                        else
                                break;
                }
@@ -877,7 +835,6 @@ static const struct rt2x00lib_ops rt2800usb_rt2x00_ops = {
        .link_tuner             = rt2800_link_tuner,
        .gain_calibration       = rt2800_gain_calibration,
        .vco_calibration        = rt2800_vco_calibration,
-       .watchdog               = rt2800usb_watchdog,
        .start_queue            = rt2800usb_start_queue,
        .kick_queue             = rt2x00usb_kick_queue,
        .stop_queue             = rt2800usb_stop_queue,
index 034a0727303822400959623949fb9d47acb21713..ea299c4e7adaf2d3b6ce3f21894b37591cc7d6c7 100644 (file)
@@ -39,6 +39,7 @@
 #include <linux/hrtimer.h>
 #include <linux/average.h>
 #include <linux/usb.h>
+#include <linux/clk.h>
 
 #include <net/mac80211.h>
 
@@ -169,6 +170,7 @@ struct rt2x00_chip {
 #define RT3572         0x3572
 #define RT3593         0x3593
 #define RT3883         0x3883  /* WSOC */
+#define RT5350         0x5350  /* WSOC 2.4GHz */
 #define RT5390         0x5390  /* 2.4GHz */
 #define RT5392         0x5392  /* 2.4GHz */
 #define RT5592         0x5592
@@ -716,6 +718,8 @@ enum rt2x00_capability_flags {
        CAPABILITY_DOUBLE_ANTENNA,
        CAPABILITY_BT_COEXIST,
        CAPABILITY_VCO_RECALIBRATION,
+       CAPABILITY_INTERNAL_PA_TX0,
+       CAPABILITY_INTERNAL_PA_TX1,
 };
 
 /*
@@ -1009,6 +1013,9 @@ struct rt2x00_dev {
        unsigned int extra_tx_headroom;
 
        struct usb_anchor *anchor;
+
+       /* Clock for System On Chip devices. */
+       struct clk *clk;
 };
 
 struct rt2x00_bar_list_entry {
index 6a1f508d472f0e6ac3be534d780d209e90a0278d..350507458ddc4e0bdf77fe0d99e8f9e55c182113 100644 (file)
@@ -249,6 +249,22 @@ void rt2x00lib_config(struct rt2x00_dev *rt2x00dev,
         */
        rt2x00dev->ops->lib->config(rt2x00dev, &libconf, ieee80211_flags);
 
+       if (conf->flags & IEEE80211_CONF_PS)
+               set_bit(CONFIG_POWERSAVING, &rt2x00dev->flags);
+       else
+               clear_bit(CONFIG_POWERSAVING, &rt2x00dev->flags);
+
+       if (conf->flags & IEEE80211_CONF_MONITOR)
+               set_bit(CONFIG_MONITORING, &rt2x00dev->flags);
+       else
+               clear_bit(CONFIG_MONITORING, &rt2x00dev->flags);
+
+       rt2x00dev->curr_band = conf->chandef.chan->band;
+       rt2x00dev->curr_freq = conf->chandef.chan->center_freq;
+       rt2x00dev->tx_power = conf->power_level;
+       rt2x00dev->short_retry = conf->short_frame_max_tx_count;
+       rt2x00dev->long_retry = conf->long_frame_max_tx_count;
+
        /*
         * Some configuration changes affect the link quality
         * which means we need to reset the link tuner.
@@ -271,20 +287,4 @@ void rt2x00lib_config(struct rt2x00_dev *rt2x00dev,
                                   &rt2x00dev->autowakeup_work,
                                   autowake_timeout - 15);
        }
-
-       if (conf->flags & IEEE80211_CONF_PS)
-               set_bit(CONFIG_POWERSAVING, &rt2x00dev->flags);
-       else
-               clear_bit(CONFIG_POWERSAVING, &rt2x00dev->flags);
-
-       if (conf->flags & IEEE80211_CONF_MONITOR)
-               set_bit(CONFIG_MONITORING, &rt2x00dev->flags);
-       else
-               clear_bit(CONFIG_MONITORING, &rt2x00dev->flags);
-
-       rt2x00dev->curr_band = conf->chandef.chan->band;
-       rt2x00dev->curr_freq = conf->chandef.chan->center_freq;
-       rt2x00dev->tx_power = conf->power_level;
-       rt2x00dev->short_retry = conf->short_frame_max_tx_count;
-       rt2x00dev->long_retry = conf->long_frame_max_tx_count;
 }
index 3cc1384ed2fcc24b3c95b052465a4cdb69b2d972..ecc96312a370377b1d29bc6f4dd450062a6538b4 100644 (file)
@@ -743,7 +743,8 @@ void rt2x00mac_flush(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
                return;
 
        tx_queue_for_each(rt2x00dev, queue)
-               rt2x00queue_flush_queue(queue, drop);
+               if (!rt2x00queue_empty(queue))
+                       rt2x00queue_flush_queue(queue, drop);
 }
 EXPORT_SYMBOL_GPL(rt2x00mac_flush);
 
index f0178fd4fe5ff8c078749e6df8b82d1ea7a26a0c..da38d254c26f042be2beadb1a0bed76660a65bc6 100644 (file)
@@ -101,7 +101,7 @@ void rt2x00mmio_flush_queue(struct data_queue *queue, bool drop)
        unsigned int i;
 
        for (i = 0; !rt2x00queue_empty(queue) && i < 10; i++)
-               msleep(10);
+               msleep(50);
 }
 EXPORT_SYMBOL_GPL(rt2x00mmio_flush_queue);
 
index 69a0cdadb07f3d46a23fb8530c62d631233de743..29250f79c4a4bffc0996222eb2c6381877f47c6f 100644 (file)
@@ -93,6 +93,10 @@ int rt2x00soc_probe(struct platform_device *pdev, const struct rt2x00_ops *ops)
        rt2x00dev->irq = platform_get_irq(pdev, 0);
        rt2x00dev->name = pdev->dev.driver->name;
 
+       rt2x00dev->clk = clk_get(&pdev->dev, NULL);
+       if (IS_ERR(rt2x00dev->clk))
+               rt2x00dev->clk = NULL;
+
        rt2x00_set_chip_intf(rt2x00dev, RT2X00_CHIP_INTF_SOC);
 
        retval = rt2x00soc_alloc_reg(rt2x00dev);
index 6005e14213ca982c12cef1b1297c564b974aded0..838ca58d2dd6e319b6c270bbe319f1041f2ae687 100644 (file)
@@ -517,7 +517,7 @@ void rt2x00usb_flush_queue(struct data_queue *queue, bool drop)
                 * Wait for a little while to give the driver
                 * the oppurtunity to recover itself.
                 */
-               msleep(10);
+               msleep(50);
        }
 }
 EXPORT_SYMBOL_GPL(rt2x00usb_flush_queue);
index df551b2b56ebc9ca0cea244e2dcac22153cf7129..95e3993d8a3319f5761cd3670dc7b7d15e25c5ed 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2014 - 2016 Jes Sorensen <Jes.Sorensen@redhat.com>
+ * Copyright (c) 2014 - 2017 Jes Sorensen <Jes.Sorensen@gmail.com>
  *
  * This program is free software; you can redistribute it and/or modify it
  * under the terms of version 2 of the GNU General Public License as
index f9e2050812ab356babc702cd3dac151b395cc889..a41a29612582fdec94e14caa23b1afa0369fc4e1 100644 (file)
@@ -1,7 +1,7 @@
 /*
  * RTL8XXXU mac80211 USB driver - 8188c/8188r/8192c specific subdriver
  *
- * Copyright (c) 2014 - 2016 Jes Sorensen <Jes.Sorensen@redhat.com>
+ * Copyright (c) 2014 - 2017 Jes Sorensen <Jes.Sorensen@gmail.com>
  *
  * Portions, notably calibration code:
  * Copyright(c) 2007 - 2011 Realtek Corporation. All rights reserved.
index a1178c5d6ad8d4a55d0642b73f94396bb2e69a13..80fee699f58a0914440689481ee13e44eb113ed2 100644 (file)
@@ -1,7 +1,7 @@
 /*
  * RTL8XXXU mac80211 USB driver - 8192e specific subdriver
  *
- * Copyright (c) 2014 - 2016 Jes Sorensen <Jes.Sorensen@redhat.com>
+ * Copyright (c) 2014 - 2017 Jes Sorensen <Jes.Sorensen@gmail.com>
  *
  * Portions, notably calibration code:
  * Copyright(c) 2007 - 2011 Realtek Corporation. All rights reserved.
index aef373028155fb8061d8fdd6eb7fd32ccb46b59b..174631132b96e4ca2d25689cec0e8b80d512bfbd 100644 (file)
@@ -1,7 +1,7 @@
 /*
  * RTL8XXXU mac80211 USB driver - 8723a specific subdriver
  *
- * Copyright (c) 2014 - 2016 Jes Sorensen <Jes.Sorensen@redhat.com>
+ * Copyright (c) 2014 - 2017 Jes Sorensen <Jes.Sorensen@gmail.com>
  *
  * Portions, notably calibration code:
  * Copyright(c) 2007 - 2011 Realtek Corporation. All rights reserved.
index 02b8ddd98a95d207323dcac13d514c0b987c5afe..c4b86a84a721d06df7cb93604b5907739ad85a13 100644 (file)
@@ -1,7 +1,7 @@
 /*
  * RTL8XXXU mac80211 USB driver - 8723b specific subdriver
  *
- * Copyright (c) 2014 - 2016 Jes Sorensen <Jes.Sorensen@redhat.com>
+ * Copyright (c) 2014 - 2017 Jes Sorensen <Jes.Sorensen@gmail.com>
  *
  * Portions, notably calibration code:
  * Copyright(c) 2007 - 2011 Realtek Corporation. All rights reserved.
index 3a86675020a210f4bd325b2d8376822e19203d59..e544dd1d618c3cea36d1a5d11068295e008c13c5 100644 (file)
@@ -1,7 +1,7 @@
 /*
  * RTL8XXXU mac80211 USB driver
  *
- * Copyright (c) 2014 - 2016 Jes Sorensen <Jes.Sorensen@redhat.com>
+ * Copyright (c) 2014 - 2017 Jes Sorensen <Jes.Sorensen@gmail.com>
  *
  * Portions, notably calibration code:
  * Copyright(c) 2007 - 2011 Realtek Corporation. All rights reserved.
@@ -48,7 +48,7 @@ static bool rtl8xxxu_dma_aggregation;
 static int rtl8xxxu_dma_agg_timeout = -1;
 static int rtl8xxxu_dma_agg_pages = -1;
 
-MODULE_AUTHOR("Jes Sorensen <Jes.Sorensen@redhat.com>");
+MODULE_AUTHOR("Jes Sorensen <Jes.Sorensen@gmail.com>");
 MODULE_DESCRIPTION("RTL8XXXu USB mac80211 Wireless LAN Driver");
 MODULE_LICENSE("GPL");
 MODULE_FIRMWARE("rtlwifi/rtl8723aufw_A.bin");
@@ -6000,6 +6000,7 @@ static int rtl8xxxu_probe(struct usb_interface *interface,
                case 0x8176:
                case 0x8178:
                case 0x817f:
+               case 0x818b:
                        untested = 0;
                        break;
                }
@@ -6196,6 +6197,12 @@ static struct usb_device_id dev_table[] = {
        .driver_info = (unsigned long)&rtl8723au_fops},
 {USB_DEVICE_AND_INTERFACE_INFO(USB_VENDOR_ID_REALTEK, 0x818b, 0xff, 0xff, 0xff),
        .driver_info = (unsigned long)&rtl8192eu_fops},
+/* TP-Link TL-WN822N v4 */
+{USB_DEVICE_AND_INTERFACE_INFO(0x2357, 0x0108, 0xff, 0xff, 0xff),
+       .driver_info = (unsigned long)&rtl8192eu_fops},
+/* D-Link DWA-131 rev E1, tested by David Patiño */
+{USB_DEVICE_AND_INTERFACE_INFO(0x2001, 0x3319, 0xff, 0xff, 0xff),
+       .driver_info = (unsigned long)&rtl8192eu_fops},
 /* Tested by Myckel Habets */
 {USB_DEVICE_AND_INTERFACE_INFO(0x2357, 0x0109, 0xff, 0xff, 0xff),
        .driver_info = (unsigned long)&rtl8192eu_fops},
@@ -6347,6 +6354,13 @@ static struct usb_device_id dev_table[] = {
        .driver_info = (unsigned long)&rtl8192cu_fops},
 {USB_DEVICE_AND_INTERFACE_INFO(0x7392, 0x7822, 0xff, 0xff, 0xff),
        .driver_info = (unsigned long)&rtl8192cu_fops},
+/* found in rtl8192eu vendor driver */
+{USB_DEVICE_AND_INTERFACE_INFO(0x2357, 0x0107, 0xff, 0xff, 0xff),
+       .driver_info = (unsigned long)&rtl8192eu_fops},
+{USB_DEVICE_AND_INTERFACE_INFO(0x2019, 0xab33, 0xff, 0xff, 0xff),
+       .driver_info = (unsigned long)&rtl8192eu_fops},
+{USB_DEVICE_AND_INTERFACE_INFO(USB_VENDOR_ID_REALTEK, 0x818c, 0xff, 0xff, 0xff),
+       .driver_info = (unsigned long)&rtl8192eu_fops},
 #endif
 { }
 };
index 315ccfb2dff5fa5d52e6304b809323f0cf780e2a..3d3e2e1ada6face1783d9e0e38e3c1f1c6664c6f 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2014 - 2016 Jes Sorensen <Jes.Sorensen@redhat.com>
+ * Copyright (c) 2014 - 2017 Jes Sorensen <Jes.Sorensen@gmail.com>
  *
  * This program is free software; you can redistribute it and/or modify it
  * under the terms of version 2 of the GNU General Public License as
index 13325e15929e7d27499835890be76c6de1517a3e..01cf0a9aa31b6e0211e3566baba84d5f749f8881 100644 (file)
@@ -2083,65 +2083,6 @@ void rtl_recognize_peer(struct ieee80211_hw *hw, u8 *data, unsigned int len)
 }
 EXPORT_SYMBOL_GPL(rtl_recognize_peer);
 
-/*********************************************************
- *
- * sysfs functions
- *
- *********************************************************/
-static ssize_t rtl_show_debug_level(struct device *d,
-                                   struct device_attribute *attr, char *buf)
-{
-       struct ieee80211_hw *hw = dev_get_drvdata(d);
-       struct rtl_priv *rtlpriv = rtl_priv(hw);
-
-       return sprintf(buf, "0x%08X\n", rtlpriv->dbg.global_debuglevel);
-}
-
-static ssize_t rtl_store_debug_level(struct device *d,
-                                    struct device_attribute *attr,
-                                    const char *buf, size_t count)
-{
-       struct ieee80211_hw *hw = dev_get_drvdata(d);
-       struct rtl_priv *rtlpriv = rtl_priv(hw);
-       unsigned long val;
-       int ret;
-
-       ret = kstrtoul(buf, 0, &val);
-       if (ret) {
-               RT_TRACE(rtlpriv, COMP_ERR, DBG_DMESG,
-                        "%s is not in hex or decimal form.\n", buf);
-       } else {
-               rtlpriv->dbg.global_debuglevel = val;
-               RT_TRACE(rtlpriv, COMP_ERR, DBG_DMESG,
-                        "debuglevel:%x\n",
-                        rtlpriv->dbg.global_debuglevel);
-       }
-
-       return strnlen(buf, count);
-}
-
-static DEVICE_ATTR(debug_level, S_IWUSR | S_IRUGO,
-                  rtl_show_debug_level, rtl_store_debug_level);
-
-static struct attribute *rtl_sysfs_entries[] = {
-
-       &dev_attr_debug_level.attr,
-
-       NULL
-};
-
-/*
- * "name" is folder name witch will be
- * put in device directory like :
- * sys/devices/pci0000:00/0000:00:1c.4/
- * 0000:06:00.0/rtl_sysfs
- */
-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>");
 MODULE_AUTHOR("Larry Finger    <Larry.FInger@lwfinger.net>");
index 74233d601a909b12b6eb33dcd1793db28efca3da..6c770aecebe79b1212add4be0eacf2145849448a 100644 (file)
@@ -148,7 +148,6 @@ int rtl_send_smps_action(struct ieee80211_hw *hw,
 u8 *rtl_find_ie(u8 *data, unsigned int len, u8 ie);
 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 rtl_global_var;
 void rtl_phy_scan_operation_backup(struct ieee80211_hw *hw, u8 operation);
index 33905bbacad212443d33dde648f5bf10511eb9bd..7ecac6116d5dfa01a91b36ee7c6def6bdf31ef54 100644 (file)
 
 #include <linux/moduleparam.h>
 
-void rtl_dbgp_flag_init(struct ieee80211_hw *hw)
+#ifdef CONFIG_RTLWIFI_DEBUG
+void _rtl_dbg_trace(struct rtl_priv *rtlpriv, int comp, int level,
+                   const char *fmt, ...)
 {
-       struct rtl_priv *rtlpriv = rtl_priv(hw);
-       u8 i;
+       if (unlikely((comp & rtlpriv->cfg->mod_params->debug_mask) &&
+                    (level <= rtlpriv->cfg->mod_params->debug_level))) {
+               struct va_format vaf;
+               va_list args;
 
-       rtlpriv->dbg.global_debugcomponents =
-           COMP_ERR | COMP_FW | COMP_INIT | COMP_RECV | COMP_SEND |
-           COMP_MLME | COMP_SCAN | COMP_INTR | COMP_LED | COMP_SEC |
-           COMP_BEACON | COMP_RATE | COMP_RXDESC | COMP_DIG | COMP_TXAGC |
-           COMP_POWER | COMP_POWER_TRACKING | COMP_BB_POWERSAVING | COMP_SWAS |
-           COMP_RF | COMP_TURBO | COMP_RATR | COMP_CMD |
-           COMP_EFUSE | COMP_QOS | COMP_MAC80211 | COMP_REGD | COMP_CHAN |
-           COMP_EASY_CONCURRENT | COMP_EFUSE | COMP_QOS | COMP_MAC80211 |
-           COMP_REGD | COMP_CHAN | COMP_BT_COEXIST;
+               va_start(args, fmt);
 
+               vaf.fmt = fmt;
+               vaf.va = &args;
 
-       for (i = 0; i < DBGP_TYPE_MAX; i++)
-               rtlpriv->dbg.dbgp_type[i] = 0;
+               pr_info(":<%lx> %pV", in_interrupt(), &vaf);
 
-       /*Init Debug flag enable condition */
+               va_end(args);
+       }
 }
-EXPORT_SYMBOL_GPL(rtl_dbgp_flag_init);
+EXPORT_SYMBOL_GPL(_rtl_dbg_trace);
 
-#ifdef CONFIG_RTLWIFI_DEBUG
-void _rtl_dbg_trace(struct rtl_priv *rtlpriv, int comp, int level,
-                   const char *modname, const char *fmt, ...)
+void _rtl_dbg_print(struct rtl_priv *rtlpriv, u64 comp, int level,
+                   const char *fmt, ...)
 {
-       if (unlikely((comp & rtlpriv->dbg.global_debugcomponents) &&
-                    (level <= rtlpriv->dbg.global_debuglevel))) {
+       if (unlikely((comp & rtlpriv->cfg->mod_params->debug_mask) &&
+                    (level <= rtlpriv->cfg->mod_params->debug_level))) {
                struct va_format vaf;
                va_list args;
 
@@ -63,13 +60,25 @@ void _rtl_dbg_trace(struct rtl_priv *rtlpriv, int comp, int level,
                vaf.fmt = fmt;
                vaf.va = &args;
 
-               printk(KERN_DEBUG "%s:%ps:<%lx-%x> %pV",
-                      modname, __builtin_return_address(0),
-                      in_interrupt(), in_atomic(),
-                      &vaf);
+               pr_info("%pV", &vaf);
 
                va_end(args);
        }
 }
-EXPORT_SYMBOL_GPL(_rtl_dbg_trace);
+EXPORT_SYMBOL_GPL(_rtl_dbg_print);
+
+void _rtl_dbg_print_data(struct rtl_priv *rtlpriv, u64 comp, int level,
+                        const char *titlestring,
+                        const void *hexdata, int hexdatalen)
+{
+       if (unlikely(((comp) & rtlpriv->cfg->mod_params->debug_mask) &&
+                    ((level) <= rtlpriv->cfg->mod_params->debug_level))) {
+               pr_info("In process \"%s\" (pid %i): %s\n",
+                       current->comm, current->pid, titlestring);
+               print_hex_dump_bytes("", DUMP_PREFIX_NONE,
+                                    hexdata, hexdatalen);
+       }
+}
+EXPORT_SYMBOL_GPL(_rtl_dbg_print_data);
+
 #endif
index a6cc3ca05c5ee44ffca93d1d0b9c34529a579816..bf5339f1c1bcaad8457392b2404ea76faf74adac 100644 (file)
@@ -168,34 +168,29 @@ enum dbgp_flag_e {
 
 struct rtl_priv;
 
-__printf(5, 6)
+__printf(4, 5)
 void _rtl_dbg_trace(struct rtl_priv *rtlpriv, int comp, int level,
-                   const char *modname, const char *fmt, ...);
+                   const char *fmt, ...);
+
+__printf(4, 5)
+void _rtl_dbg_print(struct rtl_priv *rtlpriv, u64 comp, int level,
+                   const char *fmt, ...);
+
+void _rtl_dbg_print_data(struct rtl_priv *rtlpriv, u64 comp, int level,
+                        const char *titlestring,
+                        const void *hexdata, int hexdatalen);
 
 #define RT_TRACE(rtlpriv, comp, level, fmt, ...)                       \
        _rtl_dbg_trace(rtlpriv, comp, level,                            \
-                      KBUILD_MODNAME, fmt, ##__VA_ARGS__)
+                      fmt, ##__VA_ARGS__)
 
 #define RTPRINT(rtlpriv, dbgtype, dbgflag, fmt, ...)                   \
-do {                                                                   \
-       if (unlikely(rtlpriv->dbg.dbgp_type[dbgtype] & dbgflag)) {      \
-               printk(KERN_DEBUG KBUILD_MODNAME ": " fmt,              \
-                      ##__VA_ARGS__);                                  \
-       }                                                               \
-} while (0)
+       _rtl_dbg_print(rtlpriv, dbgtype, dbgflag, fmt, ##__VA_ARGS__)
 
 #define RT_PRINT_DATA(rtlpriv, _comp, _level, _titlestring, _hexdata,  \
                      _hexdatalen)                                      \
-do {                                                                   \
-       if (unlikely(((_comp) & rtlpriv->dbg.global_debugcomponents) && \
-                    (_level <= rtlpriv->dbg.global_debuglevel))) {     \
-               printk(KERN_DEBUG "%s: In process \"%s\" (pid %i): %s\n", \
-                      KBUILD_MODNAME, current->comm, current->pid,     \
-                      _titlestring);                                   \
-               print_hex_dump_bytes("", DUMP_PREFIX_NONE,              \
-                                    _hexdata, _hexdatalen);            \
-       }                                                               \
-} while (0)
+       _rtl_dbg_print_data(rtlpriv, _comp, _level,                     \
+                           _titlestring, _hexdata, _hexdatalen)
 
 #else
 
@@ -223,6 +218,4 @@ static inline void RT_PRINT_DATA(struct rtl_priv *rtlpriv,
 }
 
 #endif
-
-void rtl_dbgp_flag_init(struct ieee80211_hw *hw);
 #endif
index afc7550e8e41dd2e9db0989fd42b1e283954d1c1..eb58633e674af6cad362edcd2a52e075fadf3367 100644 (file)
@@ -31,6 +31,9 @@ static const u8 MAX_PGPKT_SIZE = 9;
 static const u8 PGPKT_DATA_SIZE = 8;
 static const int EFUSE_MAX_SIZE = 512;
 
+#define START_ADDRESS          0x1000
+#define REG_MCUFWDL            0x0080
+
 static const struct efuse_map RTL8712_SDIO_EFUSE_TABLE[] = {
        {0, 0, 0, 2},
        {0, 1, 0, 2},
@@ -1320,3 +1323,45 @@ int rtl_get_hwinfo(struct ieee80211_hw *hw, struct rtl_priv *rtlpriv,
        return 0;
 }
 EXPORT_SYMBOL_GPL(rtl_get_hwinfo);
+
+void rtl_fw_block_write(struct ieee80211_hw *hw, const u8 *buffer, u32 size)
+{
+       struct rtl_priv *rtlpriv = rtl_priv(hw);
+       u8 *pu4byteptr = (u8 *)buffer;
+       u32 i;
+
+       for (i = 0; i < size; i++)
+               rtl_write_byte(rtlpriv, (START_ADDRESS + i), *(pu4byteptr + i));
+}
+EXPORT_SYMBOL_GPL(rtl_fw_block_write);
+
+void rtl_fw_page_write(struct ieee80211_hw *hw, u32 page, const u8 *buffer,
+                      u32 size)
+{
+       struct rtl_priv *rtlpriv = rtl_priv(hw);
+       u8 value8;
+       u8 u8page = (u8)(page & 0x07);
+
+       value8 = (rtl_read_byte(rtlpriv, REG_MCUFWDL + 2) & 0xF8) | u8page;
+
+       rtl_write_byte(rtlpriv, (REG_MCUFWDL + 2), value8);
+       rtl_fw_block_write(hw, buffer, size);
+}
+EXPORT_SYMBOL_GPL(rtl_fw_page_write);
+
+void rtl_fill_dummy(u8 *pfwbuf, u32 *pfwlen)
+{
+       u32 fwlen = *pfwlen;
+       u8 remain = (u8)(fwlen % 4);
+
+       remain = (remain == 0) ? 0 : (4 - remain);
+
+       while (remain > 0) {
+               pfwbuf[fwlen] = 0;
+               fwlen++;
+               remain--;
+       }
+
+       *pfwlen = fwlen;
+}
+EXPORT_SYMBOL_GPL(rtl_fill_dummy);
index 51aa1210def5f2e9e8cea9d634345ea6b3d35c36..1338ae63fe54aa86d478bf064380fe1a2eaad6cb 100644 (file)
@@ -111,5 +111,9 @@ void efuse_force_write_vendor_Id(struct ieee80211_hw *hw);
 void efuse_re_pg_section(struct ieee80211_hw *hw, u8 section_idx);
 int rtl_get_hwinfo(struct ieee80211_hw *hw, struct rtl_priv *rtlpriv,
                   int max_size, u8 *hwinfo, int *params);
+void rtl_fill_dummy(u8 *pfwbuf, u32 *pfwlen);
+void rtl_fw_page_write(struct ieee80211_hw *hw, u32 page, const u8 *buffer,
+                      u32 size);
+void rtl_fw_block_write(struct ieee80211_hw *hw, const u8 *buffer, u32 size);
 
 #endif
index 81ac0b3933045d7e21d391ff76c987ea635da51e..b402f438b1af7c091154f69b6e42cf6f32ae7cd4 100644 (file)
@@ -2212,16 +2212,6 @@ int rtl_pci_probe(struct pci_dev *pdev,
        rtlpriv->intf_ops = &rtl_pci_ops;
        rtlpriv->glb_var = &rtl_global_var;
 
-       /*
-        *init dbgp flags before all
-        *other functions, because we will
-        *use it in other funtions like
-        *RT_TRACE/RT_PRINT/RTL_PRINT_DATA
-        *you can not use these macro
-        *before this
-        */
-       rtl_dbgp_flag_init(hw);
-
        /* MEM map */
        err = pci_request_regions(pdev, KBUILD_MODNAME);
        if (err) {
@@ -2299,12 +2289,6 @@ int rtl_pci_probe(struct pci_dev *pdev,
        }
        rtlpriv->mac80211.mac80211_registered = 1;
 
-       err = sysfs_create_group(&pdev->dev.kobj, &rtl_attribute_group);
-       if (err) {
-               pr_err("failed to create sysfs device attributes\n");
-               goto fail3;
-       }
-
        /*init rfkill */
        rtl_init_rfkill(hw);    /* Init PCI sw */
 
@@ -2354,8 +2338,6 @@ void rtl_pci_disconnect(struct pci_dev *pdev)
        wait_for_completion(&rtlpriv->firmware_loading_complete);
        clear_bit(RTL_STATUS_INTERFACE_START, &rtlpriv->status);
 
-       sysfs_remove_group(&pdev->dev.kobj, &rtl_attribute_group);
-
        /*ieee80211_unregister_hw will call ops_stop */
        if (rtlmac->mac80211_registered == 1) {
                ieee80211_unregister_hw(hw);
index afa784a466348730128183616c9d80570a3631e2..21ed9ad3be7ad0c209a296e2114981742aa23799 100644 (file)
@@ -27,6 +27,7 @@
 #include "../pci.h"
 #include "../base.h"
 #include "../core.h"
+#include "../efuse.h"
 #include "reg.h"
 #include "def.h"
 #include "fw.h"
@@ -53,63 +54,6 @@ static void _rtl88e_enable_fw_download(struct ieee80211_hw *hw, bool enable)
        }
 }
 
-static void _rtl88e_fw_block_write(struct ieee80211_hw *hw,
-                                  const u8 *buffer, u32 size)
-{
-       struct rtl_priv *rtlpriv = rtl_priv(hw);
-       u32 blocksize = sizeof(u32);
-       u8 *bufferptr = (u8 *)buffer;
-       u32 *pu4BytePtr = (u32 *)buffer;
-       u32 i, offset, blockcount, remainsize;
-
-       blockcount = size / blocksize;
-       remainsize = size % blocksize;
-
-       for (i = 0; i < blockcount; i++) {
-               offset = i * blocksize;
-               rtl_write_dword(rtlpriv, (FW_8192C_START_ADDRESS + offset),
-                               *(pu4BytePtr + i));
-       }
-
-       if (remainsize) {
-               offset = blockcount * blocksize;
-               bufferptr += offset;
-               for (i = 0; i < remainsize; i++) {
-                       rtl_write_byte(rtlpriv, (FW_8192C_START_ADDRESS +
-                                                offset + i), *(bufferptr + i));
-               }
-       }
-}
-
-static void _rtl88e_fw_page_write(struct ieee80211_hw *hw,
-                                 u32 page, const u8 *buffer, u32 size)
-{
-       struct rtl_priv *rtlpriv = rtl_priv(hw);
-       u8 value8;
-       u8 u8page = (u8) (page & 0x07);
-
-       value8 = (rtl_read_byte(rtlpriv, REG_MCUFWDL + 2) & 0xF8) | u8page;
-
-       rtl_write_byte(rtlpriv, (REG_MCUFWDL + 2), value8);
-       _rtl88e_fw_block_write(hw, buffer, size);
-}
-
-static void _rtl88e_fill_dummy(u8 *pfwbuf, u32 *pfwlen)
-{
-       u32 fwlen = *pfwlen;
-       u8 remain = (u8) (fwlen % 4);
-
-       remain = (remain == 0) ? 0 : (4 - remain);
-
-       while (remain > 0) {
-               pfwbuf[fwlen] = 0;
-               fwlen++;
-               remain--;
-       }
-
-       *pfwlen = fwlen;
-}
-
 static void _rtl88e_write_fw(struct ieee80211_hw *hw,
                             enum version_8188e version, u8 *buffer, u32 size)
 {
@@ -120,7 +64,7 @@ static void _rtl88e_write_fw(struct ieee80211_hw *hw,
 
        RT_TRACE(rtlpriv, COMP_FW, DBG_LOUD, "FW size is %d bytes,\n", size);
 
-       _rtl88e_fill_dummy(bufferptr, &size);
+       rtl_fill_dummy(bufferptr, &size);
 
        pagenums = size / FW_8192C_PAGE_SIZE;
        remainsize = size % FW_8192C_PAGE_SIZE;
@@ -130,15 +74,14 @@ static void _rtl88e_write_fw(struct ieee80211_hw *hw,
 
        for (page = 0; page < pagenums; page++) {
                offset = page * FW_8192C_PAGE_SIZE;
-               _rtl88e_fw_page_write(hw, page, (bufferptr + offset),
-                                     FW_8192C_PAGE_SIZE);
+               rtl_fw_page_write(hw, page, (bufferptr + offset),
+                                 FW_8192C_PAGE_SIZE);
        }
 
        if (remainsize) {
                offset = pagenums * FW_8192C_PAGE_SIZE;
                page = pagenums;
-               _rtl88e_fw_page_write(hw, page, (bufferptr + offset),
-                                     remainsize);
+               rtl_fw_page_write(hw, page, (bufferptr + offset), remainsize);
        }
 }
 
index 276c74539fb362d82d0cb25b836505096ea3c846..7661cfa5303209dda82d67b29bca3d9d046427cc 100644 (file)
@@ -131,8 +131,6 @@ int rtl88e_init_sw_vars(struct ieee80211_hw *hw)
        rtlpci->irq_mask[1] = (u32) (IMR_RXFOVW | 0);
        rtlpci->sys_irq_mask = (u32) (HSIMR_PDN_INT_EN | HSIMR_RON_INT_EN);
 
-       /* for debug level */
-       rtlpriv->dbg.global_debuglevel = rtlpriv->cfg->mod_params->debug;
        /* for LPS & IPS */
        rtlpriv->psc.inactiveps = rtlpriv->cfg->mod_params->inactiveps;
        rtlpriv->psc.swctrl_lps = rtlpriv->cfg->mod_params->swctrl_lps;
@@ -276,7 +274,8 @@ static struct rtl_mod_params rtl88ee_mod_params = {
        .swctrl_lps = false,
        .fwctrl_lps = false,
        .msi_support = true,
-       .debug = 0,
+       .debug_level = 0,
+       .debug_mask = 0,
 };
 
 static const struct rtl_hal_cfg rtl88ee_hal_cfg = {
@@ -392,7 +391,8 @@ MODULE_DESCRIPTION("Realtek 8188E 802.11n PCI wireless");
 MODULE_FIRMWARE("rtlwifi/rtl8188efw.bin");
 
 module_param_named(swenc, rtl88ee_mod_params.sw_crypto, bool, 0444);
-module_param_named(debug, rtl88ee_mod_params.debug, int, 0444);
+module_param_named(debug_level, rtl88ee_mod_params.debug_level, int, 0644);
+module_param_named(debug_mask, rtl88ee_mod_params.debug_mask, ullong, 0644);
 module_param_named(ips, rtl88ee_mod_params.inactiveps, bool, 0444);
 module_param_named(swlps, rtl88ee_mod_params.swctrl_lps, bool, 0444);
 module_param_named(fwlps, rtl88ee_mod_params.fwctrl_lps, bool, 0444);
@@ -404,7 +404,8 @@ MODULE_PARM_DESC(ips, "Set to 0 to not use link power save (default 1)\n");
 MODULE_PARM_DESC(swlps, "Set to 1 to use SW control power save (default 0)\n");
 MODULE_PARM_DESC(fwlps, "Set to 1 to use FW control power save (default 1)\n");
 MODULE_PARM_DESC(msi, "Set to 1 to use MSI interrupts mode (default 1)\n");
-MODULE_PARM_DESC(debug, "Set debug level (0-5) (default 0)");
+MODULE_PARM_DESC(debug_level, "Set debug level (0-5) (default 0)");
+MODULE_PARM_DESC(debug_mask, "Set debug mask (default 0)");
 MODULE_PARM_DESC(disable_watchdog, "Set to 1 to disable the watchdog (default 0)\n");
 
 static SIMPLE_DEV_PM_OPS(rtlwifi_pm_ops, rtl_pci_suspend, rtl_pci_resume);
index 433ab7f33acfd0555316eba07f3c03e6b3d77285..c7a77467b20e3401023f09c63334043179c932a1 100644 (file)
@@ -27,6 +27,7 @@
 #include "../pci.h"
 #include "../base.h"
 #include "../core.h"
+#include "../efuse.h"
 #include "../rtl8192ce/reg.h"
 #include "../rtl8192ce/def.h"
 #include "fw_common.h"
@@ -68,63 +69,6 @@ static void _rtl92c_enable_fw_download(struct ieee80211_hw *hw, bool enable)
        }
 }
 
-static void _rtl92c_fw_block_write(struct ieee80211_hw *hw,
-                                  const u8 *buffer, u32 size)
-{
-       struct rtl_priv *rtlpriv = rtl_priv(hw);
-       u32 blocksize = sizeof(u32);
-       u8 *bufferptr = (u8 *)buffer;
-       u32 *pu4byteptr = (u32 *)buffer;
-       u32 i, offset, blockcount, remainsize;
-
-       blockcount = size / blocksize;
-       remainsize = size % blocksize;
-
-       for (i = 0; i < blockcount; i++) {
-               offset = i * blocksize;
-               rtl_write_dword(rtlpriv, (FW_8192C_START_ADDRESS + offset),
-                               *(pu4byteptr + i));
-       }
-
-       if (remainsize) {
-               offset = blockcount * blocksize;
-               bufferptr += offset;
-               for (i = 0; i < remainsize; i++) {
-                       rtl_write_byte(rtlpriv, (FW_8192C_START_ADDRESS +
-                                                offset + i), *(bufferptr + i));
-               }
-       }
-}
-
-static void _rtl92c_fw_page_write(struct ieee80211_hw *hw,
-                                 u32 page, const u8 *buffer, u32 size)
-{
-       struct rtl_priv *rtlpriv = rtl_priv(hw);
-       u8 value8;
-       u8 u8page = (u8) (page & 0x07);
-
-       value8 = (rtl_read_byte(rtlpriv, REG_MCUFWDL + 2) & 0xF8) | u8page;
-
-       rtl_write_byte(rtlpriv, (REG_MCUFWDL + 2), value8);
-       _rtl92c_fw_block_write(hw, buffer, size);
-}
-
-static void _rtl92c_fill_dummy(u8 *pfwbuf, u32 *pfwlen)
-{
-       u32 fwlen = *pfwlen;
-       u8 remain = (u8) (fwlen % 4);
-
-       remain = (remain == 0) ? 0 : (4 - remain);
-
-       while (remain > 0) {
-               pfwbuf[fwlen] = 0;
-               fwlen++;
-               remain--;
-       }
-
-       *pfwlen = fwlen;
-}
-
 static void _rtl92c_write_fw(struct ieee80211_hw *hw,
                             enum version_8192c version, u8 *buffer, u32 size)
 {
@@ -140,7 +84,7 @@ static void _rtl92c_write_fw(struct ieee80211_hw *hw,
                u32 page, offset;
 
                if (rtlhal->hw_type == HARDWARE_TYPE_RTL8192CE)
-                       _rtl92c_fill_dummy(bufferptr, &size);
+                       rtl_fill_dummy(bufferptr, &size);
 
                pageNums = size / FW_8192C_PAGE_SIZE;
                remainsize = size % FW_8192C_PAGE_SIZE;
@@ -150,18 +94,18 @@ static void _rtl92c_write_fw(struct ieee80211_hw *hw,
 
                for (page = 0; page < pageNums; page++) {
                        offset = page * FW_8192C_PAGE_SIZE;
-                       _rtl92c_fw_page_write(hw, page, (bufferptr + offset),
-                                             FW_8192C_PAGE_SIZE);
+                       rtl_fw_page_write(hw, page, (bufferptr + offset),
+                                         FW_8192C_PAGE_SIZE);
                }
 
                if (remainsize) {
                        offset = pageNums * FW_8192C_PAGE_SIZE;
                        page = pageNums;
-                       _rtl92c_fw_page_write(hw, page, (bufferptr + offset),
-                                             remainsize);
+                       rtl_fw_page_write(hw, page, (bufferptr + offset),
+                                         remainsize);
                }
        } else {
-               _rtl92c_fw_block_write(hw, buffer, size);
+               rtl_fw_block_write(hw, buffer, size);
        }
 }
 
index 9bd2bff6212a3c0750d32031893fad9c85782a88..efedd918d10ad13fdd08b4b8b70bd418d3275078 100644 (file)
@@ -130,8 +130,6 @@ int rtl92c_init_sw_vars(struct ieee80211_hw *hw)
 
        rtlpci->irq_mask[1] = (u32) (IMR_CPWM | IMR_C2HCMD | 0);
 
-       /* for debug level */
-       rtlpriv->dbg.global_debuglevel = rtlpriv->cfg->mod_params->debug;
        /* for LPS & IPS */
        rtlpriv->psc.inactiveps = rtlpriv->cfg->mod_params->inactiveps;
        rtlpriv->psc.swctrl_lps = rtlpriv->cfg->mod_params->swctrl_lps;
@@ -247,7 +245,8 @@ static struct rtl_mod_params rtl92ce_mod_params = {
        .inactiveps = true,
        .swctrl_lps = false,
        .fwctrl_lps = true,
-       .debug = 0,
+       .debug_level = 0,
+       .debug_mask = 0,
 };
 
 static const struct rtl_hal_cfg rtl92ce_hal_cfg = {
@@ -364,7 +363,8 @@ MODULE_FIRMWARE("rtlwifi/rtl8192cfwU.bin");
 MODULE_FIRMWARE("rtlwifi/rtl8192cfwU_B.bin");
 
 module_param_named(swenc, rtl92ce_mod_params.sw_crypto, bool, 0444);
-module_param_named(debug, rtl92ce_mod_params.debug, int, 0444);
+module_param_named(debug_level, rtl92ce_mod_params.debug_level, int, 0644);
+module_param_named(debug_mask, rtl92ce_mod_params.debug_mask, ullong, 0644);
 module_param_named(ips, rtl92ce_mod_params.inactiveps, bool, 0444);
 module_param_named(swlps, rtl92ce_mod_params.swctrl_lps, bool, 0444);
 module_param_named(fwlps, rtl92ce_mod_params.fwctrl_lps, bool, 0444);
@@ -372,7 +372,8 @@ MODULE_PARM_DESC(swenc, "Set to 1 for software crypto (default 0)\n");
 MODULE_PARM_DESC(ips, "Set to 0 to not use link power save (default 1)\n");
 MODULE_PARM_DESC(swlps, "Set to 1 to use SW control power save (default 0)\n");
 MODULE_PARM_DESC(fwlps, "Set to 1 to use FW control power save (default 1)\n");
-MODULE_PARM_DESC(debug, "Set debug level (0-5) (default 0)");
+MODULE_PARM_DESC(debug_level, "Set debug level (0-5) (default 0)");
+MODULE_PARM_DESC(debug_mask, "Set debug mask (default 0)");
 
 static SIMPLE_DEV_PM_OPS(rtlwifi_pm_ops, rtl_pci_suspend, rtl_pci_resume);
 
index 935e8308e2e6f3b2ffbe518035be89bf5a6eedca..96c923b3feb4cdbf6317cd3e6b3371c5e7f37b17 100644 (file)
@@ -61,7 +61,6 @@ static int rtl92cu_init_sw_vars(struct ieee80211_hw *hw)
        rtlpriv->dm.dm_flag = 0;
        rtlpriv->dm.disable_framebursting = false;
        rtlpriv->dm.thermalvalue = 0;
-       rtlpriv->dbg.global_debuglevel = rtlpriv->cfg->mod_params->debug;
        rtlpriv->cfg->mod_params->sw_crypto =
                rtlpriv->cfg->mod_params->sw_crypto;
 
@@ -157,13 +156,16 @@ static struct rtl_hal_ops rtl8192cu_hal_ops = {
 
 static struct rtl_mod_params rtl92cu_mod_params = {
        .sw_crypto = 0,
-       .debug = 0,
+       .debug_level = 0,
+       .debug_mask = 0,
 };
 
 module_param_named(swenc, rtl92cu_mod_params.sw_crypto, bool, 0444);
-module_param_named(debug, rtl92cu_mod_params.debug, int, 0444);
+module_param_named(debug_level, rtl92cu_mod_params.debug_level, int, 0644);
+module_param_named(debug_mask, rtl92cu_mod_params.debug_mask, ullong, 0644);
 MODULE_PARM_DESC(swenc, "Set to 1 for software crypto (default 0)\n");
-MODULE_PARM_DESC(debug, "Set debug level (0-5) (default 0)");
+MODULE_PARM_DESC(debug_level, "Set debug level (0-5) (default 0)");
+MODULE_PARM_DESC(debug_mask, "Set debug mask (default 0)");
 
 static struct rtl_hal_usbint_cfg rtl92cu_interface_cfg = {
        /* rx */
index 6da6e2acfbecde515d44ab69a398cf70638c1273..1611e42479d97eb9b5f8322f36af119c2747cac5 100644 (file)
@@ -477,14 +477,14 @@ static void _rtl_fill_usb_tx_desc(u8 *txdesc)
  */
 static void _rtl_tx_desc_checksum(u8 *txdesc)
 {
-       u16 *ptr = (u16 *)txdesc;
+       __le16 *ptr = (__le16 *)txdesc;
        u16     checksum = 0;
        u32 index;
 
        /* Clear first */
        SET_TX_DESC_TX_DESC_CHECKSUM(txdesc, 0);
        for (index = 0; index < 16; index++)
-               checksum = checksum ^ (*(ptr + index));
+               checksum = checksum ^ le16_to_cpu(*(ptr + index));
        SET_TX_DESC_TX_DESC_CHECKSUM(txdesc, checksum);
 }
 
index df88e39301c2dabf089a3089b49cf710fb98eff1..487eec89bc29c5ec01b87547cc1648df73a6a0d4 100644 (file)
@@ -92,129 +92,107 @@ struct rx_drv_info_92c {
        u8 reserve:4;
 } __packed;
 
-/* Define a macro that takes a le32 word, converts it to host ordering,
- * right shifts by a specified count, creates a mask of the specified
- * bit count, and extracts that number of bits.
- */
-
-#define SHIFT_AND_MASK_LE(__pdesc, __shift, __bits)            \
-       ((le32_to_cpu(*(((__le32 *)(__pdesc)))) >> (__shift)) & \
-       BIT_LEN_MASK_32(__bits))
-
-/* Define a macro that clears a bit field in an le32 word and
- * sets the specified value into that bit field. The resulting
- * value remains in le32 ordering; however, it is properly converted
- * to host ordering for the clear and set operations before conversion
- * back to le32.
- */
-
-#define SET_BITS_OFFSET_LE(__pdesc, __shift, __len, __val)     \
-       (*(__le32 *)(__pdesc) =                                 \
-       (cpu_to_le32((le32_to_cpu(*((__le32 *)(__pdesc))) &     \
-       (~(BIT_OFFSET_LEN_MASK_32((__shift), __len)))) |                \
-       (((u32)(__val) & BIT_LEN_MASK_32(__len)) << (__shift)))));
-
 /* macros to read various fields in RX descriptor */
 
 /* DWORD 0 */
 #define GET_RX_DESC_PKT_LEN(__rxdesc)          \
-       SHIFT_AND_MASK_LE((__rxdesc), 0, 14)
+       LE_BITS_TO_4BYTE((__rxdesc), 0, 14)
 #define GET_RX_DESC_CRC32(__rxdesc)            \
-       SHIFT_AND_MASK_LE(__rxdesc, 14, 1)
+       LE_BITS_TO_4BYTE(__rxdesc, 14, 1)
 #define GET_RX_DESC_ICV(__rxdesc)              \
-       SHIFT_AND_MASK_LE(__rxdesc, 15, 1)
+       LE_BITS_TO_4BYTE(__rxdesc, 15, 1)
 #define GET_RX_DESC_DRVINFO_SIZE(__rxdesc)     \
-       SHIFT_AND_MASK_LE(__rxdesc, 16, 4)
+       LE_BITS_TO_4BYTE(__rxdesc, 16, 4)
 #define GET_RX_DESC_SECURITY(__rxdesc)         \
-       SHIFT_AND_MASK_LE(__rxdesc, 20, 3)
+       LE_BITS_TO_4BYTE(__rxdesc, 20, 3)
 #define GET_RX_DESC_QOS(__rxdesc)              \
-       SHIFT_AND_MASK_LE(__rxdesc, 23, 1)
+       LE_BITS_TO_4BYTE(__rxdesc, 23, 1)
 #define GET_RX_DESC_SHIFT(__rxdesc)            \
-       SHIFT_AND_MASK_LE(__rxdesc, 24, 2)
+       LE_BITS_TO_4BYTE(__rxdesc, 24, 2)
 #define GET_RX_DESC_PHY_STATUS(__rxdesc)       \
-       SHIFT_AND_MASK_LE(__rxdesc, 26, 1)
+       LE_BITS_TO_4BYTE(__rxdesc, 26, 1)
 #define GET_RX_DESC_SWDEC(__rxdesc)            \
-       SHIFT_AND_MASK_LE(__rxdesc, 27, 1)
+       LE_BITS_TO_4BYTE(__rxdesc, 27, 1)
 #define GET_RX_DESC_LAST_SEG(__rxdesc)         \
-       SHIFT_AND_MASK_LE(__rxdesc, 28, 1)
+       LE_BITS_TO_4BYTE(__rxdesc, 28, 1)
 #define GET_RX_DESC_FIRST_SEG(__rxdesc)                \
-       SHIFT_AND_MASK_LE(__rxdesc, 29, 1)
+       LE_BITS_TO_4BYTE(__rxdesc, 29, 1)
 #define GET_RX_DESC_EOR(__rxdesc)              \
-       SHIFT_AND_MASK_LE(__rxdesc, 30, 1)
+       LE_BITS_TO_4BYTE(__rxdesc, 30, 1)
 #define GET_RX_DESC_OWN(__rxdesc)              \
-       SHIFT_AND_MASK_LE(__rxdesc, 31, 1)
+       LE_BITS_TO_4BYTE(__rxdesc, 31, 1)
 
 /* DWORD 1 */
 #define GET_RX_DESC_MACID(__rxdesc)            \
-       SHIFT_AND_MASK_LE(__rxdesc+4, 0, 5)
+       LE_BITS_TO_4BYTE(__rxdesc + 4, 0, 5)
 #define GET_RX_DESC_TID(__rxdesc)              \
-       SHIFT_AND_MASK_LE(__rxdesc+4, 5, 4)
+       LE_BITS_TO_4BYTE(__rxdesc + 4, 5, 4)
 #define GET_RX_DESC_PAGGR(__rxdesc)            \
-       SHIFT_AND_MASK_LE(__rxdesc+4, 14, 1)
+       LE_BITS_TO_4BYTE(__rxdesc + 4, 14, 1)
 #define GET_RX_DESC_FAGGR(__rxdesc)            \
-       SHIFT_AND_MASK_LE(__rxdesc+4, 15, 1)
+       LE_BITS_TO_4BYTE(__rxdesc + 4, 15, 1)
 #define GET_RX_DESC_A1_FIT(__rxdesc)           \
-       SHIFT_AND_MASK_LE(__rxdesc+4, 16, 4)
+       LE_BITS_TO_4BYTE(__rxdesc + 4, 16, 4)
 #define GET_RX_DESC_A2_FIT(__rxdesc)           \
-       SHIFT_AND_MASK_LE(__rxdesc+4, 20, 4)
+       LE_BITS_TO_4BYTE(__rxdesc + 4, 20, 4)
 #define GET_RX_DESC_PAM(__rxdesc)              \
-       SHIFT_AND_MASK_LE(__rxdesc+4, 24, 1)
+       LE_BITS_TO_4BYTE(__rxdesc + 4, 24, 1)
 #define GET_RX_DESC_PWR(__rxdesc)              \
-       SHIFT_AND_MASK_LE(__rxdesc+4, 25, 1)
+       LE_BITS_TO_4BYTE(__rxdesc + 4, 25, 1)
 #define GET_RX_DESC_MORE_DATA(__rxdesc)                \
-       SHIFT_AND_MASK_LE(__rxdesc+4, 26, 1)
+       LE_BITS_TO_4BYTE(__rxdesc + 4, 26, 1)
 #define GET_RX_DESC_MORE_FRAG(__rxdesc)                \
-       SHIFT_AND_MASK_LE(__rxdesc+4, 27, 1)
+       LE_BITS_TO_4BYTE(__rxdesc + 4, 27, 1)
 #define GET_RX_DESC_TYPE(__rxdesc)             \
-       SHIFT_AND_MASK_LE(__rxdesc+4, 28, 2)
+       LE_BITS_TO_4BYTE(__rxdesc + 4, 28, 2)
 #define GET_RX_DESC_MC(__rxdesc)               \
-       SHIFT_AND_MASK_LE(__rxdesc+4, 30, 1)
+       LE_BITS_TO_4BYTE(__rxdesc + 4, 30, 1)
 #define GET_RX_DESC_BC(__rxdesc)               \
-       SHIFT_AND_MASK_LE(__rxdesc+4, 31, 1)
+       LE_BITS_TO_4BYTE(__rxdesc + 4, 31, 1)
 
 /* DWORD 2 */
 #define GET_RX_DESC_SEQ(__rxdesc)              \
-       SHIFT_AND_MASK_LE(__rxdesc+8, 0, 12)
+       LE_BITS_TO_4BYTE(__rxdesc + 8, 0, 12)
 #define GET_RX_DESC_FRAG(__rxdesc)             \
-       SHIFT_AND_MASK_LE(__rxdesc+8, 12, 4)
+       LE_BITS_TO_4BYTE(__rxdesc + 8, 12, 4)
 #define GET_RX_DESC_USB_AGG_PKTNUM(__rxdesc)   \
-       SHIFT_AND_MASK_LE(__rxdesc+8, 16, 8)
+       LE_BITS_TO_4BYTE(__rxdesc + 8, 16, 8)
 #define GET_RX_DESC_NEXT_IND(__rxdesc)         \
-       SHIFT_AND_MASK_LE(__rxdesc+8, 30, 1)
+       LE_BITS_TO_4BYTE(__rxdesc + 8, 30, 1)
 
 /* DWORD 3 */
 #define GET_RX_DESC_RX_MCS(__rxdesc)           \
-       SHIFT_AND_MASK_LE(__rxdesc+12, 0, 6)
+       LE_BITS_TO_4BYTE(__rxdesc + 12, 0, 6)
 #define GET_RX_DESC_RX_HT(__rxdesc)            \
-       SHIFT_AND_MASK_LE(__rxdesc+12, 6, 1)
+       LE_BITS_TO_4BYTE(__rxdesc + 12, 6, 1)
 #define GET_RX_DESC_AMSDU(__rxdesc)            \
-       SHIFT_AND_MASK_LE(__rxdesc+12, 7, 1)
+       LE_BITS_TO_4BYTE(__rxdesc + 12, 7, 1)
 #define GET_RX_DESC_SPLCP(__rxdesc)            \
-       SHIFT_AND_MASK_LE(__rxdesc+12, 8, 1)
+       LE_BITS_TO_4BYTE(__rxdesc + 12, 8, 1)
 #define GET_RX_DESC_BW(__rxdesc)               \
-       SHIFT_AND_MASK_LE(__rxdesc+12, 9, 1)
+       LE_BITS_TO_4BYTE(__rxdesc + 12, 9, 1)
 #define GET_RX_DESC_HTC(__rxdesc)              \
-       SHIFT_AND_MASK_LE(__rxdesc+12, 10, 1)
+       LE_BITS_TO_4BYTE(__rxdesc + 12, 10, 1)
 #define GET_RX_DESC_TCP_CHK_RPT(__rxdesc)      \
-       SHIFT_AND_MASK_LE(__rxdesc+12, 11, 1)
+       LE_BITS_TO_4BYTE(__rxdesc + 12, 11, 1)
 #define GET_RX_DESC_IP_CHK_RPT(__rxdesc)       \
-       SHIFT_AND_MASK_LE(__rxdesc+12, 12, 1)
+       LE_BITS_TO_4BYTE(__rxdesc + 12, 12, 1)
 #define GET_RX_DESC_TCP_CHK_VALID(__rxdesc)    \
-       SHIFT_AND_MASK_LE(__rxdesc+12, 13, 1)
+       LE_BITS_TO_4BYTE(__rxdesc + 12, 13, 1)
 #define GET_RX_DESC_HWPC_ERR(__rxdesc)         \
-       SHIFT_AND_MASK_LE(__rxdesc+12, 14, 1)
+       LE_BITS_TO_4BYTE(__rxdesc + 12, 14, 1)
 #define GET_RX_DESC_HWPC_IND(__rxdesc)         \
-       SHIFT_AND_MASK_LE(__rxdesc+12, 15, 1)
+       LE_BITS_TO_4BYTE(__rxdesc + 12, 15, 1)
 #define GET_RX_DESC_IV0(__rxdesc)              \
-       SHIFT_AND_MASK_LE(__rxdesc+12, 16, 16)
+       LE_BITS_TO_4BYTE(__rxdesc + 12, 16, 16)
 
 /* DWORD 4 */
 #define GET_RX_DESC_IV1(__rxdesc)              \
-       SHIFT_AND_MASK_LE(__rxdesc+16, 0, 32)
+       LE_BITS_TO_4BYTE(__rxdesc + 16, 0, 32)
 
 /* DWORD 5 */
 #define GET_RX_DESC_TSFL(__rxdesc)             \
-       SHIFT_AND_MASK_LE(__rxdesc+20, 0, 32)
+       LE_BITS_TO_4BYTE(__rxdesc + 20, 0, 32)
 
 /*======================= tx desc ============================================*/
 
@@ -222,182 +200,182 @@ struct rx_drv_info_92c {
 
 /* Dword 0 */
 #define SET_TX_DESC_PKT_SIZE(__txdesc, __value)                \
-       SET_BITS_OFFSET_LE(__txdesc, 0, 16, __value)
+       SET_BITS_TO_LE_4BYTE(__txdesc, 0, 16, __value)
 #define SET_TX_DESC_OFFSET(__txdesc, __value)          \
-       SET_BITS_OFFSET_LE(__txdesc, 16, 8, __value)
+       SET_BITS_TO_LE_4BYTE(__txdesc, 16, 8, __value)
 #define SET_TX_DESC_BMC(__txdesc, __value)             \
-       SET_BITS_OFFSET_LE(__txdesc, 24, 1, __value)
+       SET_BITS_TO_LE_4BYTE(__txdesc, 24, 1, __value)
 #define SET_TX_DESC_HTC(__txdesc, __value)             \
-       SET_BITS_OFFSET_LE(__txdesc, 25, 1, __value)
+       SET_BITS_TO_LE_4BYTE(__txdesc, 25, 1, __value)
 #define SET_TX_DESC_LAST_SEG(__txdesc, __value)                \
-       SET_BITS_OFFSET_LE(__txdesc, 26, 1, __value)
+       SET_BITS_TO_LE_4BYTE(__txdesc, 26, 1, __value)
 #define SET_TX_DESC_FIRST_SEG(__txdesc, __value)       \
-        SET_BITS_OFFSET_LE(__txdesc, 27, 1, __value)
+        SET_BITS_TO_LE_4BYTE(__txdesc, 27, 1, __value)
 #define SET_TX_DESC_LINIP(__txdesc, __value)           \
-       SET_BITS_OFFSET_LE(__txdesc, 28, 1, __value)
+       SET_BITS_TO_LE_4BYTE(__txdesc, 28, 1, __value)
 #define SET_TX_DESC_NO_ACM(__txdesc, __value)          \
-       SET_BITS_OFFSET_LE(__txdesc, 29, 1, __value)
+       SET_BITS_TO_LE_4BYTE(__txdesc, 29, 1, __value)
 #define SET_TX_DESC_GF(__txdesc, __value)              \
-       SET_BITS_OFFSET_LE(__txdesc, 30, 1, __value)
+       SET_BITS_TO_LE_4BYTE(__txdesc, 30, 1, __value)
 #define SET_TX_DESC_OWN(__txdesc, __value)             \
-       SET_BITS_OFFSET_LE(__txdesc, 31, 1, __value)
+       SET_BITS_TO_LE_4BYTE(__txdesc, 31, 1, __value)
 
 
 /* Dword 1 */
 #define SET_TX_DESC_MACID(__txdesc, __value)           \
-       SET_BITS_OFFSET_LE(__txdesc+4, 0, 5, __value)
+       SET_BITS_TO_LE_4BYTE(__txdesc + 4, 0, 5, __value)
 #define SET_TX_DESC_AGG_ENABLE(__txdesc, __value)      \
-       SET_BITS_OFFSET_LE(__txdesc+4, 5, 1, __value)
+       SET_BITS_TO_LE_4BYTE(__txdesc + 4, 5, 1, __value)
 #define SET_TX_DESC_AGG_BREAK(__txdesc, __value)       \
-       SET_BITS_OFFSET_LE(__txdesc+4, 6, 1, __value)
+       SET_BITS_TO_LE_4BYTE(__txdesc + 4, 6, 1, __value)
 #define SET_TX_DESC_RDG_ENABLE(__txdesc, __value)      \
-       SET_BITS_OFFSET_LE(__txdesc+4, 7, 1, __value)
+       SET_BITS_TO_LE_4BYTE(__txdesc + 4, 7, 1, __value)
 #define SET_TX_DESC_QUEUE_SEL(__txdesc, __value)       \
-       SET_BITS_OFFSET_LE(__txdesc+4, 8, 5, __value)
+       SET_BITS_TO_LE_4BYTE(__txdesc + 4, 8, 5, __value)
 #define SET_TX_DESC_RDG_NAV_EXT(__txdesc, __value)     \
-       SET_BITS_OFFSET_LE(__txdesc+4, 13, 1, __value)
+       SET_BITS_TO_LE_4BYTE(__txdesc + 4, 13, 1, __value)
 #define SET_TX_DESC_LSIG_TXOP_EN(__txdesc, __value)    \
-       SET_BITS_OFFSET_LE(__txdesc+4, 14, 1, __value)
+       SET_BITS_TO_LE_4BYTE(__txdesc + 4, 14, 1, __value)
 #define SET_TX_DESC_PIFS(__txdesc, __value)            \
-       SET_BITS_OFFSET_LE(__txdesc+4, 15, 1, __value)
+       SET_BITS_TO_LE_4BYTE(__txdesc + 4, 15, 1, __value)
 #define SET_TX_DESC_RATE_ID(__txdesc, __value)         \
-       SET_BITS_OFFSET_LE(__txdesc+4, 16, 4, __value)
+       SET_BITS_TO_LE_4BYTE(__txdesc + 4, 16, 4, __value)
 #define SET_TX_DESC_RA_BRSR_ID(__txdesc, __value)      \
-       SET_BITS_OFFSET_LE(__txdesc+4, 16, 4, __value)
+       SET_BITS_TO_LE_4BYTE(__txdesc + 4, 16, 4, __value)
 #define SET_TX_DESC_NAV_USE_HDR(__txdesc, __value)     \
-       SET_BITS_OFFSET_LE(__txdesc+4, 20, 1, __value)
+       SET_BITS_TO_LE_4BYTE(__txdesc + 4, 20, 1, __value)
 #define SET_TX_DESC_EN_DESC_ID(__txdesc, __value)      \
-       SET_BITS_OFFSET_LE(__txdesc+4, 21, 1, __value)
+       SET_BITS_TO_LE_4BYTE(__txdesc + 4, 21, 1, __value)
 #define SET_TX_DESC_SEC_TYPE(__txdesc, __value)                \
-       SET_BITS_OFFSET_LE(__txdesc+4, 22, 2, __value)
+       SET_BITS_TO_LE_4BYTE(__txdesc + 4, 22, 2, __value)
 #define SET_TX_DESC_PKT_OFFSET(__txdesc, __value)      \
-       SET_BITS_OFFSET_LE(__txdesc+4, 26, 5, __value)
+       SET_BITS_TO_LE_4BYTE(__txdesc + 4, 26, 5, __value)
 
 /* Dword 2 */
 #define SET_TX_DESC_RTS_RC(__txdesc, __value)          \
-       SET_BITS_OFFSET_LE(__txdesc+8, 0, 6, __value)
+       SET_BITS_TO_LE_4BYTE(__txdesc + 8, 0, 6, __value)
 #define SET_TX_DESC_DATA_RC(__txdesc, __value)         \
-       SET_BITS_OFFSET_LE(__txdesc+8, 6, 6, __value)
+       SET_BITS_TO_LE_4BYTE(__txdesc + 8, 6, 6, __value)
 #define SET_TX_DESC_BAR_RTY_TH(__txdesc, __value)      \
-       SET_BITS_OFFSET_LE(__txdesc+8, 14, 2, __value)
+       SET_BITS_TO_LE_4BYTE(__txdesc + 8, 14, 2, __value)
 #define SET_TX_DESC_MORE_FRAG(__txdesc, __value)       \
-       SET_BITS_OFFSET_LE(__txdesc+8, 17, 1, __value)
+       SET_BITS_TO_LE_4BYTE(__txdesc + 8, 17, 1, __value)
 #define SET_TX_DESC_RAW(__txdesc, __value)             \
-       SET_BITS_OFFSET_LE(__txdesc+8, 18, 1, __value)
+       SET_BITS_TO_LE_4BYTE(__txdesc + 8, 18, 1, __value)
 #define SET_TX_DESC_CCX(__txdesc, __value)             \
-       SET_BITS_OFFSET_LE(__txdesc+8, 19, 1, __value)
+       SET_BITS_TO_LE_4BYTE(__txdesc + 8, 19, 1, __value)
 #define SET_TX_DESC_AMPDU_DENSITY(__txdesc, __value)   \
-       SET_BITS_OFFSET_LE(__txdesc+8, 20, 3, __value)
+       SET_BITS_TO_LE_4BYTE(__txdesc + 8, 20, 3, __value)
 #define SET_TX_DESC_ANTSEL_A(__txdesc, __value)                \
-       SET_BITS_OFFSET_LE(__txdesc+8, 24, 1, __value)
+       SET_BITS_TO_LE_4BYTE(__txdesc + 8, 24, 1, __value)
 #define SET_TX_DESC_ANTSEL_B(__txdesc, __value)                \
-       SET_BITS_OFFSET_LE(__txdesc+8, 25, 1, __value)
+       SET_BITS_TO_LE_4BYTE(__txdesc + 8, 25, 1, __value)
 #define SET_TX_DESC_TX_ANT_CCK(__txdesc, __value)      \
-       SET_BITS_OFFSET_LE(__txdesc+8, 26, 2, __value)
+       SET_BITS_TO_LE_4BYTE(__txdesc + 8, 26, 2, __value)
 #define SET_TX_DESC_TX_ANTL(__txdesc, __value)         \
-       SET_BITS_OFFSET_LE(__txdesc+8, 28, 2, __value)
+       SET_BITS_TO_LE_4BYTE(__txdesc + 8, 28, 2, __value)
 #define SET_TX_DESC_TX_ANT_HT(__txdesc, __value)       \
-       SET_BITS_OFFSET_LE(__txdesc+8, 30, 2, __value)
+       SET_BITS_TO_LE_4BYTE(__txdesc + 8, 30, 2, __value)
 
 /* Dword 3 */
 #define SET_TX_DESC_NEXT_HEAP_PAGE(__txdesc, __value)  \
-       SET_BITS_OFFSET_LE(__txdesc+12, 0, 8, __value)
+       SET_BITS_TO_LE_4BYTE(__txdesc + 12, 0, 8, __value)
 #define SET_TX_DESC_TAIL_PAGE(__txdesc, __value)       \
-       SET_BITS_OFFSET_LE(__txdesc+12, 8, 8, __value)
+       SET_BITS_TO_LE_4BYTE(__txdesc + 12, 8, 8, __value)
 #define SET_TX_DESC_SEQ(__txdesc, __value)             \
-       SET_BITS_OFFSET_LE(__txdesc+12, 16, 12, __value)
+       SET_BITS_TO_LE_4BYTE(__txdesc + 12, 16, 12, __value)
 #define SET_TX_DESC_PKT_ID(__txdesc, __value)          \
-       SET_BITS_OFFSET_LE(__txdesc+12, 28, 4, __value)
+       SET_BITS_TO_LE_4BYTE(__txdesc + 12, 28, 4, __value)
 
 /* Dword 4 */
 #define SET_TX_DESC_RTS_RATE(__txdesc, __value)                \
-       SET_BITS_OFFSET_LE(__txdesc+16, 0, 5, __value)
+       SET_BITS_TO_LE_4BYTE(__txdesc + 16, 0, 5, __value)
 #define SET_TX_DESC_AP_DCFE(__txdesc, __value)         \
-       SET_BITS_OFFSET_LE(__txdesc+16, 5, 1, __value)
+       SET_BITS_TO_LE_4BYTE(__txdesc + 16, 5, 1, __value)
 #define SET_TX_DESC_QOS(__txdesc, __value)             \
-       SET_BITS_OFFSET_LE(__txdesc+16, 6, 1, __value)
+       SET_BITS_TO_LE_4BYTE(__txdesc + 16, 6, 1, __value)
 #define SET_TX_DESC_HWSEQ_EN(__txdesc, __value)                \
-       SET_BITS_OFFSET_LE(__txdesc+16, 7, 1, __value)
+       SET_BITS_TO_LE_4BYTE(__txdesc + 16, 7, 1, __value)
 #define SET_TX_DESC_USE_RATE(__txdesc, __value)                \
-       SET_BITS_OFFSET_LE(__txdesc+16, 8, 1, __value)
+       SET_BITS_TO_LE_4BYTE(__txdesc + 16, 8, 1, __value)
 #define SET_TX_DESC_DISABLE_RTS_FB(__txdesc, __value)  \
-       SET_BITS_OFFSET_LE(__txdesc+16, 9, 1, __value)
+       SET_BITS_TO_LE_4BYTE(__txdesc + 16, 9, 1, __value)
 #define SET_TX_DESC_DISABLE_FB(__txdesc, __value)      \
-       SET_BITS_OFFSET_LE(__txdesc+16, 10, 1, __value)
+       SET_BITS_TO_LE_4BYTE(__txdesc + 16, 10, 1, __value)
 #define SET_TX_DESC_CTS2SELF(__txdesc, __value)                \
-       SET_BITS_OFFSET_LE(__txdesc+16, 11, 1, __value)
+       SET_BITS_TO_LE_4BYTE(__txdesc + 16, 11, 1, __value)
 #define SET_TX_DESC_RTS_ENABLE(__txdesc, __value)      \
-       SET_BITS_OFFSET_LE(__txdesc+16, 12, 1, __value)
+       SET_BITS_TO_LE_4BYTE(__txdesc + 16, 12, 1, __value)
 #define SET_TX_DESC_HW_RTS_ENABLE(__txdesc, __value)   \
-       SET_BITS_OFFSET_LE(__txdesc+16, 13, 1, __value)
+       SET_BITS_TO_LE_4BYTE(__txdesc + 16, 13, 1, __value)
 #define SET_TX_DESC_WAIT_DCTS(__txdesc, __value)       \
-       SET_BITS_OFFSET_LE(__txdesc+16, 18, 1, __value)
+       SET_BITS_TO_LE_4BYTE(__txdesc + 16, 18, 1, __value)
 #define SET_TX_DESC_CTS2AP_EN(__txdesc, __value)       \
-       SET_BITS_OFFSET_LE(__txdesc+16, 19, 1, __value)
+       SET_BITS_TO_LE_4BYTE(__txdesc + 16, 19, 1, __value)
 #define SET_TX_DESC_DATA_SC(__txdesc, __value)         \
-       SET_BITS_OFFSET_LE(__txdesc+16, 20, 2, __value)
+       SET_BITS_TO_LE_4BYTE(__txdesc + 16, 20, 2, __value)
 #define SET_TX_DESC_DATA_STBC(__txdesc, __value)       \
-       SET_BITS_OFFSET_LE(__txdesc+16, 22, 2, __value)
+       SET_BITS_TO_LE_4BYTE(__txdesc + 16, 22, 2, __value)
 #define SET_TX_DESC_DATA_SHORT(__txdesc, __value)      \
-       SET_BITS_OFFSET_LE(__txdesc+16, 24, 1, __value)
+       SET_BITS_TO_LE_4BYTE(__txdesc + 16, 24, 1, __value)
 #define SET_TX_DESC_DATA_BW(__txdesc, __value)         \
-       SET_BITS_OFFSET_LE(__txdesc+16, 25, 1, __value)
+       SET_BITS_TO_LE_4BYTE(__txdesc + 16, 25, 1, __value)
 #define SET_TX_DESC_RTS_SHORT(__txdesc, __value)       \
-       SET_BITS_OFFSET_LE(__txdesc+16, 26, 1, __value)
+       SET_BITS_TO_LE_4BYTE(__txdesc + 16, 26, 1, __value)
 #define SET_TX_DESC_RTS_BW(__txdesc, __value)          \
-       SET_BITS_OFFSET_LE(__txdesc+16, 27, 1, __value)
+       SET_BITS_TO_LE_4BYTE(__txdesc + 16, 27, 1, __value)
 #define SET_TX_DESC_RTS_SC(__txdesc, __value)          \
-       SET_BITS_OFFSET_LE(__txdesc+16, 28, 2, __value)
+       SET_BITS_TO_LE_4BYTE(__txdesc + 16, 28, 2, __value)
 #define SET_TX_DESC_RTS_STBC(__txdesc, __value)                \
-       SET_BITS_OFFSET_LE(__txdesc+16, 30, 2, __value)
+       SET_BITS_TO_LE_4BYTE(__txdesc + 16, 30, 2, __value)
 
 /* Dword 5 */
 #define SET_TX_DESC_TX_RATE(__pdesc, __val)            \
-       SET_BITS_OFFSET_LE(__pdesc+20, 0, 6, __val)
+       SET_BITS_TO_LE_4BYTE(__pdesc + 20, 0, 6, __val)
 #define SET_TX_DESC_DATA_SHORTGI(__pdesc, __val)       \
-       SET_BITS_OFFSET_LE(__pdesc+20, 6, 1, __val)
+       SET_BITS_TO_LE_4BYTE(__pdesc + 20, 6, 1, __val)
 #define SET_TX_DESC_CCX_TAG(__pdesc, __val)            \
-       SET_BITS_OFFSET_LE(__pdesc+20, 7, 1, __val)
+       SET_BITS_TO_LE_4BYTE(__pdesc + 20, 7, 1, __val)
 #define SET_TX_DESC_DATA_RATE_FB_LIMIT(__txdesc, __value) \
-       SET_BITS_OFFSET_LE(__txdesc+20, 8, 5, __value)
+       SET_BITS_TO_LE_4BYTE(__txdesc + 20, 8, 5, __value)
 #define SET_TX_DESC_RTS_RATE_FB_LIMIT(__txdesc, __value) \
-       SET_BITS_OFFSET_LE(__txdesc+20, 13, 4, __value)
+       SET_BITS_TO_LE_4BYTE(__txdesc + 20, 13, 4, __value)
 #define SET_TX_DESC_RETRY_LIMIT_ENABLE(__txdesc, __value) \
-       SET_BITS_OFFSET_LE(__txdesc+20, 17, 1, __value)
+       SET_BITS_TO_LE_4BYTE(__txdesc + 20, 17, 1, __value)
 #define SET_TX_DESC_DATA_RETRY_LIMIT(__txdesc, __value)        \
-       SET_BITS_OFFSET_LE(__txdesc+20, 18, 6, __value)
+       SET_BITS_TO_LE_4BYTE(__txdesc + 20, 18, 6, __value)
 #define SET_TX_DESC_USB_TXAGG_NUM(__txdesc, __value)   \
-       SET_BITS_OFFSET_LE(__txdesc+20, 24, 8, __value)
+       SET_BITS_TO_LE_4BYTE(__txdesc + 20, 24, 8, __value)
 
 /* Dword 6 */
 #define SET_TX_DESC_TXAGC_A(__txdesc, __value)         \
-       SET_BITS_OFFSET_LE(__txdesc+24, 0, 5, __value)
+       SET_BITS_TO_LE_4BYTE(__txdesc + 24, 0, 5, __value)
 #define SET_TX_DESC_TXAGC_B(__txdesc, __value)         \
-       SET_BITS_OFFSET_LE(__txdesc+24, 5, 5, __value)
+       SET_BITS_TO_LE_4BYTE(__txdesc + 24, 5, 5, __value)
 #define SET_TX_DESC_USB_MAX_LEN(__txdesc, __value)     \
-       SET_BITS_OFFSET_LE(__txdesc+24, 10, 1, __value)
+       SET_BITS_TO_LE_4BYTE(__txdesc + 24, 10, 1, __value)
 #define SET_TX_DESC_MAX_AGG_NUM(__txdesc, __value)     \
-       SET_BITS_OFFSET_LE(__txdesc+24, 11, 5, __value)
+       SET_BITS_TO_LE_4BYTE(__txdesc + 24, 11, 5, __value)
 #define SET_TX_DESC_MCSG1_MAX_LEN(__txdesc, __value)   \
-       SET_BITS_OFFSET_LE(__txdesc+24, 16, 4, __value)
+       SET_BITS_TO_LE_4BYTE(__txdesc + 24, 16, 4, __value)
 #define SET_TX_DESC_MCSG2_MAX_LEN(__txdesc, __value)   \
-       SET_BITS_OFFSET_LE(__txdesc+24, 20, 4, __value)
+       SET_BITS_TO_LE_4BYTE(__txdesc + 24, 20, 4, __value)
 #define SET_TX_DESC_MCSG3_MAX_LEN(__txdesc, __value)   \
-       SET_BITS_OFFSET_LE(__txdesc+24, 24, 4, __value)
+       SET_BITS_TO_LE_4BYTE(__txdesc + 24, 24, 4, __value)
 #define SET_TX_DESC_MCSG7_MAX_LEN(__txdesc, __value)   \
-       SET_BITS_OFFSET_LE(__txdesc+24, 28, 4, __value)
+       SET_BITS_TO_LE_4BYTE(__txdesc + 24, 28, 4, __value)
 
 /* Dword 7 */
 #define SET_TX_DESC_TX_DESC_CHECKSUM(__txdesc, __value) \
-       SET_BITS_OFFSET_LE(__txdesc+28, 0, 16, __value)
+       SET_BITS_TO_LE_4BYTE(__txdesc + 28, 0, 16, __value)
 #define SET_TX_DESC_MCSG4_MAX_LEN(__txdesc, __value)   \
-       SET_BITS_OFFSET_LE(__txdesc+28, 16, 4, __value)
+       SET_BITS_TO_LE_4BYTE(__txdesc + 28, 16, 4, __value)
 #define SET_TX_DESC_MCSG5_MAX_LEN(__txdesc, __value)   \
-       SET_BITS_OFFSET_LE(__txdesc+28, 20, 4, __value)
+       SET_BITS_TO_LE_4BYTE(__txdesc + 28, 20, 4, __value)
 #define SET_TX_DESC_MCSG6_MAX_LEN(__txdesc, __value)   \
-       SET_BITS_OFFSET_LE(__txdesc+28, 24, 4, __value)
+       SET_BITS_TO_LE_4BYTE(__txdesc + 28, 24, 4, __value)
 #define SET_TX_DESC_MCSG15_MAX_LEN(__txdesc, __value)  \
-       SET_BITS_OFFSET_LE(__txdesc+28, 28, 4, __value)
+       SET_BITS_TO_LE_4BYTE(__txdesc + 28, 28, 4, __value)
 
 
 int  rtl8192cu_endpoint_mapping(struct ieee80211_hw *hw);
index aa1e51c871dfe41f2feffba62a97267df3ec6a9a..88faeab2574f0b15a4edb43dc96772010eb61ef8 100644 (file)
@@ -26,6 +26,7 @@
 #include "../wifi.h"
 #include "../pci.h"
 #include "../base.h"
+#include "../efuse.h"
 #include "reg.h"
 #include "def.h"
 #include "fw.h"
@@ -59,84 +60,31 @@ static void _rtl92d_enable_fw_download(struct ieee80211_hw *hw, bool enable)
        }
 }
 
-static void _rtl92d_fw_block_write(struct ieee80211_hw *hw,
-                                  const u8 *buffer, u32 size)
-{
-       struct rtl_priv *rtlpriv = rtl_priv(hw);
-       u32 blocksize = sizeof(u32);
-       u8 *bufferptr = (u8 *) buffer;
-       u32 *pu4BytePtr = (u32 *) buffer;
-       u32 i, offset, blockCount, remainSize;
-
-       blockCount = size / blocksize;
-       remainSize = size % blocksize;
-       for (i = 0; i < blockCount; i++) {
-               offset = i * blocksize;
-               rtl_write_dword(rtlpriv, (FW_8192D_START_ADDRESS + offset),
-                               *(pu4BytePtr + i));
-       }
-       if (remainSize) {
-               offset = blockCount * blocksize;
-               bufferptr += offset;
-               for (i = 0; i < remainSize; i++) {
-                       rtl_write_byte(rtlpriv, (FW_8192D_START_ADDRESS +
-                                                offset + i), *(bufferptr + i));
-               }
-       }
-}
-
-static void _rtl92d_fw_page_write(struct ieee80211_hw *hw,
-                                 u32 page, const u8 *buffer, u32 size)
-{
-       struct rtl_priv *rtlpriv = rtl_priv(hw);
-       u8 value8;
-       u8 u8page = (u8) (page & 0x07);
-
-       value8 = (rtl_read_byte(rtlpriv, REG_MCUFWDL + 2) & 0xF8) | u8page;
-       rtl_write_byte(rtlpriv, (REG_MCUFWDL + 2), value8);
-       _rtl92d_fw_block_write(hw, buffer, size);
-}
-
-static void _rtl92d_fill_dummy(u8 *pfwbuf, u32 *pfwlen)
-{
-       u32 fwlen = *pfwlen;
-       u8 remain = (u8) (fwlen % 4);
-
-       remain = (remain == 0) ? 0 : (4 - remain);
-       while (remain > 0) {
-               pfwbuf[fwlen] = 0;
-               fwlen++;
-               remain--;
-       }
-       *pfwlen = fwlen;
-}
-
 static void _rtl92d_write_fw(struct ieee80211_hw *hw,
                             enum version_8192d version, u8 *buffer, u32 size)
 {
        struct rtl_priv *rtlpriv = rtl_priv(hw);
        struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
-       u8 *bufferPtr = buffer;
-       u32 pagenums, remainSize;
+       u8 *bufferptr = buffer;
+       u32 pagenums, remainsize;
        u32 page, offset;
 
        RT_TRACE(rtlpriv, COMP_FW, DBG_TRACE, "FW size is %d bytes,\n", size);
        if (rtlhal->hw_type == HARDWARE_TYPE_RTL8192DE)
-               _rtl92d_fill_dummy(bufferPtr, &size);
+               rtl_fill_dummy(bufferptr, &size);
        pagenums = size / FW_8192D_PAGE_SIZE;
-       remainSize = size % FW_8192D_PAGE_SIZE;
+       remainsize = size % FW_8192D_PAGE_SIZE;
        if (pagenums > 8)
                pr_err("Page numbers should not greater then 8\n");
        for (page = 0; page < pagenums; page++) {
                offset = page * FW_8192D_PAGE_SIZE;
-               _rtl92d_fw_page_write(hw, page, (bufferPtr + offset),
-                                     FW_8192D_PAGE_SIZE);
+               rtl_fw_page_write(hw, page, (bufferptr + offset),
+                                 FW_8192D_PAGE_SIZE);
        }
-       if (remainSize) {
+       if (remainsize) {
                offset = pagenums * FW_8192D_PAGE_SIZE;
                page = pagenums;
-               _rtl92d_fw_page_write(hw, page, (bufferPtr + offset),
-                                     remainSize);
+               rtl_fw_page_write(hw, page, (bufferptr + offset), remainsize);
        }
 }
 
@@ -323,7 +271,6 @@ int rtl92d_download_fw(struct ieee80211_hw *hw)
        spin_unlock_irqrestore(&globalmutex_for_fwdownload, flags);
        if (err)
                pr_err("fw is not ready to run!\n");
-               goto exit;
 exit:
        err = _rtl92d_fw_init(hw);
        return err;
index 51463d7b130aff3a206914a9849f422454219ad3..16132c66e5e1b37db21d0cd81163f8c38152ee3e 100644 (file)
@@ -140,8 +140,6 @@ static int rtl92d_init_sw_vars(struct ieee80211_hw *hw)
 
        rtlpci->irq_mask[1] = (u32) (IMR_CPWM | IMR_C2HCMD);
 
-       /* for debug level */
-       rtlpriv->dbg.global_debuglevel = rtlpriv->cfg->mod_params->debug;
        /* for LPS & IPS */
        rtlpriv->psc.inactiveps = rtlpriv->cfg->mod_params->inactiveps;
        rtlpriv->psc.swctrl_lps = rtlpriv->cfg->mod_params->swctrl_lps;
@@ -254,7 +252,8 @@ static struct rtl_mod_params rtl92de_mod_params = {
        .inactiveps = true,
        .swctrl_lps = true,
        .fwctrl_lps = false,
-       .debug = 0,
+       .debug_level = 0,
+       .debug_mask = 0,
 };
 
 static const struct rtl_hal_cfg rtl92de_hal_cfg = {
@@ -364,15 +363,17 @@ MODULE_DESCRIPTION("Realtek 8192DE 802.11n Dual Mac PCI wireless");
 MODULE_FIRMWARE("rtlwifi/rtl8192defw.bin");
 
 module_param_named(swenc, rtl92de_mod_params.sw_crypto, bool, 0444);
-module_param_named(debug, rtl92de_mod_params.debug, int, 0444);
+module_param_named(debug_level, rtl92de_mod_params.debug_level, int, 0644);
 module_param_named(ips, rtl92de_mod_params.inactiveps, bool, 0444);
 module_param_named(swlps, rtl92de_mod_params.swctrl_lps, bool, 0444);
 module_param_named(fwlps, rtl92de_mod_params.fwctrl_lps, bool, 0444);
+module_param_named(debug_mask, rtl92de_mod_params.debug_mask, ullong, 0644);
 MODULE_PARM_DESC(swenc, "Set to 1 for software crypto (default 0)\n");
 MODULE_PARM_DESC(ips, "Set to 0 to not use link power save (default 1)\n");
 MODULE_PARM_DESC(swlps, "Set to 1 to use SW control power save (default 1)\n");
 MODULE_PARM_DESC(fwlps, "Set to 1 to use FW control power save (default 0)\n");
-MODULE_PARM_DESC(debug, "Set debug level (0-5) (default 0)");
+MODULE_PARM_DESC(debug_level, "Set debug level (0-5) (default 0)");
+MODULE_PARM_DESC(debug_mask, "Set debug mask (default 0)");
 
 static SIMPLE_DEV_PM_OPS(rtlwifi_pm_ops, rtl_pci_suspend, rtl_pci_resume);
 
index 78ee6e1d18505dcfcdee90cd9e5fea78eefb0999..9d7a16c9e74ef9186dada1f2dba9230f36fbc8ad 100644 (file)
@@ -27,6 +27,7 @@
 #include "../pci.h"
 #include "../base.h"
 #include "../core.h"
+#include "../efuse.h"
 #include "reg.h"
 #include "def.h"
 #include "fw.h"
@@ -48,64 +49,6 @@ static void _rtl92ee_enable_fw_download(struct ieee80211_hw *hw, bool enable)
        }
 }
 
-static void _rtl92ee_fw_block_write(struct ieee80211_hw *hw,
-                                   const u8 *buffer, u32 size)
-{
-       struct rtl_priv *rtlpriv = rtl_priv(hw);
-       u32 blocksize = sizeof(u32);
-       u8 *bufferptr = (u8 *)buffer;
-       u32 *pu4byteptr = (u32 *)buffer;
-       u32 i, offset, blockcount, remainsize;
-
-       blockcount = size / blocksize;
-       remainsize = size % blocksize;
-
-       for (i = 0; i < blockcount; i++) {
-               offset = i * blocksize;
-               rtl_write_dword(rtlpriv, (FW_8192C_START_ADDRESS + offset),
-                               *(pu4byteptr + i));
-       }
-
-       if (remainsize) {
-               offset = blockcount * blocksize;
-               bufferptr += offset;
-               for (i = 0; i < remainsize; i++) {
-                       rtl_write_byte(rtlpriv,
-                                      (FW_8192C_START_ADDRESS + offset + i),
-                                      *(bufferptr + i));
-               }
-       }
-}
-
-static void _rtl92ee_fw_page_write(struct ieee80211_hw *hw, u32 page,
-                                  const u8 *buffer, u32 size)
-{
-       struct rtl_priv *rtlpriv = rtl_priv(hw);
-       u8 value8;
-       u8 u8page = (u8)(page & 0x07);
-
-       value8 = (rtl_read_byte(rtlpriv, REG_MCUFWDL + 2) & 0xF8) | u8page;
-       rtl_write_byte(rtlpriv, (REG_MCUFWDL + 2), value8);
-
-       _rtl92ee_fw_block_write(hw, buffer, size);
-}
-
-static void _rtl92ee_fill_dummy(u8 *pfwbuf, u32 *pfwlen)
-{
-       u32 fwlen = *pfwlen;
-       u8 remain = (u8)(fwlen % 4);
-
-       remain = (remain == 0) ? 0 : (4 - remain);
-
-       while (remain > 0) {
-               pfwbuf[fwlen] = 0;
-               fwlen++;
-               remain--;
-       }
-
-       *pfwlen = fwlen;
-}
-
 static void _rtl92ee_write_fw(struct ieee80211_hw *hw,
                              enum version_8192e version,
                              u8 *buffer, u32 size)
@@ -117,7 +60,7 @@ static void _rtl92ee_write_fw(struct ieee80211_hw *hw,
 
        RT_TRACE(rtlpriv, COMP_FW, DBG_LOUD , "FW size is %d bytes,\n", size);
 
-       _rtl92ee_fill_dummy(bufferptr, &size);
+       rtl_fill_dummy(bufferptr, &size);
 
        pagenums = size / FW_8192C_PAGE_SIZE;
        remainsize = size % FW_8192C_PAGE_SIZE;
@@ -127,16 +70,15 @@ static void _rtl92ee_write_fw(struct ieee80211_hw *hw,
 
        for (page = 0; page < pagenums; page++) {
                offset = page * FW_8192C_PAGE_SIZE;
-               _rtl92ee_fw_page_write(hw, page, (bufferptr + offset),
-                                      FW_8192C_PAGE_SIZE);
+               rtl_fw_page_write(hw, page, (bufferptr + offset),
+                                 FW_8192C_PAGE_SIZE);
                udelay(2);
        }
 
        if (remainsize) {
                offset = pagenums * FW_8192C_PAGE_SIZE;
                page = pagenums;
-               _rtl92ee_fw_page_write(hw, page, (bufferptr + offset),
-                                      remainsize);
+               rtl_fw_page_write(hw, page, (bufferptr + offset), remainsize);
        }
 }
 
index eddc704b3ee35ed3c63884f2bc9886340e279ebc..554f2dc86bc5acd3f2877f41e77a03e517cb724d 100644 (file)
@@ -133,8 +133,6 @@ int rtl92ee_init_sw_vars(struct ieee80211_hw *hw)
                                     0);
        rtlpci->irq_mask[1] = (u32)(IMR_RXFOVW | 0);
 
-       /* for debug level */
-       rtlpriv->dbg.global_debuglevel = rtlpriv->cfg->mod_params->debug;
        /* for LPS & IPS */
        rtlpriv->psc.inactiveps = rtlpriv->cfg->mod_params->inactiveps;
        rtlpriv->psc.swctrl_lps = rtlpriv->cfg->mod_params->swctrl_lps;
@@ -258,7 +256,8 @@ static struct rtl_mod_params rtl92ee_mod_params = {
        .swctrl_lps = false,
        .fwctrl_lps = true,
        .msi_support = true,
-       .debug = 0,
+       .debug_level = 0,
+       .debug_mask = 0,
 };
 
 static const struct rtl_hal_cfg rtl92ee_hal_cfg = {
@@ -368,7 +367,8 @@ MODULE_DESCRIPTION("Realtek 8192EE 802.11n PCI wireless");
 MODULE_FIRMWARE("rtlwifi/rtl8192eefw.bin");
 
 module_param_named(swenc, rtl92ee_mod_params.sw_crypto, bool, 0444);
-module_param_named(debug, rtl92ee_mod_params.debug, int, 0444);
+module_param_named(debug_level, rtl92ee_mod_params.debug_level, int, 0644);
+module_param_named(debug_mask, rtl92ee_mod_params.debug_mask, ullong, 0644);
 module_param_named(ips, rtl92ee_mod_params.inactiveps, bool, 0444);
 module_param_named(swlps, rtl92ee_mod_params.swctrl_lps, bool, 0444);
 module_param_named(fwlps, rtl92ee_mod_params.fwctrl_lps, bool, 0444);
@@ -380,7 +380,8 @@ MODULE_PARM_DESC(ips, "Set to 0 to not use link power save (default 1)\n");
 MODULE_PARM_DESC(swlps, "Set to 1 to use SW control power save (default 0)\n");
 MODULE_PARM_DESC(fwlps, "Set to 1 to use FW control power save (default 1)\n");
 MODULE_PARM_DESC(msi, "Set to 1 to use MSI interrupts mode (default 1)\n");
-MODULE_PARM_DESC(debug, "Set debug level (0-5) (default 0)");
+MODULE_PARM_DESC(debug_level, "Set debug level (0-5) (default 0)");
+MODULE_PARM_DESC(debug_mask, "Set debug mask (default 0)");
 MODULE_PARM_DESC(disable_watchdog, "Set to 1 to disable the watchdog (default 0)\n");
 
 static SIMPLE_DEV_PM_OPS(rtlwifi_pm_ops, rtl_pci_suspend, rtl_pci_resume);
index 3c66d00abbac1fa5be5a02307443a53a3e015404..2006b09ea74ffac4888e2700f72329e8630d48a7 100644 (file)
@@ -178,8 +178,6 @@ static int rtl92s_init_sw_vars(struct ieee80211_hw *hw)
 
        rtlpci->first_init = true;
 
-       /* for debug level */
-       rtlpriv->dbg.global_debuglevel = rtlpriv->cfg->mod_params->debug;
        /* for LPS & IPS */
        rtlpriv->psc.inactiveps = rtlpriv->cfg->mod_params->inactiveps;
        rtlpriv->psc.swctrl_lps = rtlpriv->cfg->mod_params->swctrl_lps;
@@ -297,7 +295,8 @@ static struct rtl_mod_params rtl92se_mod_params = {
        .inactiveps = true,
        .swctrl_lps = true,
        .fwctrl_lps = false,
-       .debug = 0,
+       .debug_level = 0,
+       .debug_mask = 0,
 };
 
 /* Because memory R/W bursting will cause system hang/crash
@@ -416,7 +415,8 @@ MODULE_DESCRIPTION("Realtek 8192S/8191S 802.11n PCI wireless");
 MODULE_FIRMWARE("rtlwifi/rtl8192sefw.bin");
 
 module_param_named(swenc, rtl92se_mod_params.sw_crypto, bool, 0444);
-module_param_named(debug, rtl92se_mod_params.debug, int, 0444);
+module_param_named(debug_level, rtl92se_mod_params.debug_level, int, 0644);
+module_param_named(debug_mask, rtl92se_mod_params.debug_mask, ullong, 0644);
 module_param_named(ips, rtl92se_mod_params.inactiveps, bool, 0444);
 module_param_named(swlps, rtl92se_mod_params.swctrl_lps, bool, 0444);
 module_param_named(fwlps, rtl92se_mod_params.fwctrl_lps, bool, 0444);
@@ -424,7 +424,8 @@ MODULE_PARM_DESC(swenc, "Set to 1 for software crypto (default 0)\n");
 MODULE_PARM_DESC(ips, "Set to 0 to not use link power save (default 1)\n");
 MODULE_PARM_DESC(swlps, "Set to 1 to use SW control power save (default 1)\n");
 MODULE_PARM_DESC(fwlps, "Set to 1 to use FW control power save (default 0)\n");
-MODULE_PARM_DESC(debug, "Set debug level (0-5) (default 0)");
+MODULE_PARM_DESC(debug_level, "Set debug level (0-5) (default 0)");
+MODULE_PARM_DESC(debug_mask, "Set debug mask (default 0)");
 
 static SIMPLE_DEV_PM_OPS(rtlwifi_pm_ops, rtl_pci_suspend, rtl_pci_resume);
 
index 401f54266f15d99913dedc31847e59c7cdb90999..7bf9f255792048b9a03a8b6a6117f77c51bd5535 100644 (file)
@@ -145,8 +145,6 @@ int rtl8723e_init_sw_vars(struct ieee80211_hw *hw)
                 (u32)(PHIMR_RXFOVW |
                                0);
 
-       /* for debug level */
-       rtlpriv->dbg.global_debuglevel = rtlpriv->cfg->mod_params->debug;
        /* for LPS & IPS */
        rtlpriv->psc.inactiveps = rtlpriv->cfg->mod_params->inactiveps;
        rtlpriv->psc.swctrl_lps = rtlpriv->cfg->mod_params->swctrl_lps;
@@ -268,7 +266,8 @@ static struct rtl_mod_params rtl8723e_mod_params = {
        .inactiveps = true,
        .swctrl_lps = false,
        .fwctrl_lps = true,
-       .debug = 0,
+       .debug_level = 0,
+       .debug_mask = 0,
        .msi_support = false,
        .disable_watchdog = false,
 };
@@ -382,7 +381,8 @@ MODULE_DESCRIPTION("Realtek 8723E 802.11n PCI wireless");
 MODULE_FIRMWARE("rtlwifi/rtl8723efw.bin");
 
 module_param_named(swenc, rtl8723e_mod_params.sw_crypto, bool, 0444);
-module_param_named(debug, rtl8723e_mod_params.debug, int, 0444);
+module_param_named(debug_level, rtl8723e_mod_params.debug_level, int, 0644);
+module_param_named(debug_mask, rtl8723e_mod_params.debug_mask, ullong, 0644);
 module_param_named(ips, rtl8723e_mod_params.inactiveps, bool, 0444);
 module_param_named(swlps, rtl8723e_mod_params.swctrl_lps, bool, 0444);
 module_param_named(fwlps, rtl8723e_mod_params.fwctrl_lps, bool, 0444);
@@ -394,7 +394,8 @@ MODULE_PARM_DESC(ips, "Set to 0 to not use link power save (default 1)\n");
 MODULE_PARM_DESC(swlps, "Set to 1 to use SW control power save (default 0)\n");
 MODULE_PARM_DESC(fwlps, "Set to 1 to use FW control power save (default 1)\n");
 MODULE_PARM_DESC(msi, "Set to 1 to use MSI interrupts mode (default 0)\n");
-MODULE_PARM_DESC(debug, "Set debug level (0-5) (default 0)");
+MODULE_PARM_DESC(debug_level, "Set debug level (0-5) (default 0)");
+MODULE_PARM_DESC(debug_mask, "Set debug mask (default 0)");
 MODULE_PARM_DESC(disable_watchdog, "Set to 1 to disable the watchdog (default 0)\n");
 
 static SIMPLE_DEV_PM_OPS(rtlwifi_pm_ops, rtl_pci_suspend, rtl_pci_resume);
index dd42c1a6d986eeb7981e855604f5c7e1d9b804e2..e571b876f0af9cbaaefd30a96bbdbfc7db402c63 100644 (file)
@@ -144,8 +144,6 @@ int rtl8723be_init_sw_vars(struct ieee80211_hw *hw)
                                     HSIMR_RON_INT_EN   |
                                     0);
 
-       /* for debug level */
-       rtlpriv->dbg.global_debuglevel = rtlpriv->cfg->mod_params->debug;
        /* for LPS & IPS */
        rtlpriv->psc.inactiveps = rtlpriv->cfg->mod_params->inactiveps;
        rtlpriv->psc.swctrl_lps = rtlpriv->cfg->mod_params->swctrl_lps;
@@ -271,7 +269,8 @@ static struct rtl_mod_params rtl8723be_mod_params = {
        .fwctrl_lps = true,
        .msi_support = false,
        .disable_watchdog = false,
-       .debug = 0,
+       .debug_level = 0,
+       .debug_mask = 0,
        .ant_sel = 0,
 };
 
@@ -386,7 +385,8 @@ MODULE_DESCRIPTION("Realtek 8723BE 802.11n PCI wireless");
 MODULE_FIRMWARE("rtlwifi/rtl8723befw.bin");
 
 module_param_named(swenc, rtl8723be_mod_params.sw_crypto, bool, 0444);
-module_param_named(debug, rtl8723be_mod_params.debug, int, 0444);
+module_param_named(debug_level, rtl8723be_mod_params.debug_level, int, 0644);
+module_param_named(debug_mask, rtl8723be_mod_params.debug_mask, ullong, 0644);
 module_param_named(ips, rtl8723be_mod_params.inactiveps, bool, 0444);
 module_param_named(swlps, rtl8723be_mod_params.swctrl_lps, bool, 0444);
 module_param_named(fwlps, rtl8723be_mod_params.fwctrl_lps, bool, 0444);
@@ -399,7 +399,8 @@ MODULE_PARM_DESC(ips, "Set to 0 to not use link power save (default 1)\n");
 MODULE_PARM_DESC(swlps, "Set to 1 to use SW control power save (default 0)\n");
 MODULE_PARM_DESC(fwlps, "Set to 1 to use FW control power save (default 1)\n");
 MODULE_PARM_DESC(msi, "Set to 1 to use MSI interrupts mode (default 0)\n");
-MODULE_PARM_DESC(debug, "Set debug level (0-5) (default 0)");
+MODULE_PARM_DESC(debug_level, "Set debug level (0-5) (default 0)");
+MODULE_PARM_DESC(debug_mask, "Set debug mask (default 0)");
 MODULE_PARM_DESC(disable_watchdog,
                 "Set to 1 to disable the watchdog (default 0)\n");
 MODULE_PARM_DESC(ant_sel, "Set to 1 or 2 to force antenna number (default 0)\n");
index 8e0d038df7019d36a2137dc9868714f8af37f526..ac573d69f6d67429bdfe9785f929c40ff96c4ae0 100644 (file)
@@ -26,6 +26,7 @@
 #include "../wifi.h"
 #include "../pci.h"
 #include "../base.h"
+#include "../efuse.h"
 #include "fw_common.h"
 #include <linux/module.h>
 
@@ -53,65 +54,6 @@ void rtl8723_enable_fw_download(struct ieee80211_hw *hw, bool enable)
 }
 EXPORT_SYMBOL_GPL(rtl8723_enable_fw_download);
 
-void rtl8723_fw_block_write(struct ieee80211_hw *hw,
-                           const u8 *buffer, u32 size)
-{
-       struct rtl_priv *rtlpriv = rtl_priv(hw);
-       u32 blocksize = sizeof(u32);
-       u8 *bufferptr = (u8 *)buffer;
-       u32 *pu4byteptr = (u32 *)buffer;
-       u32 i, offset, blockcount, remainsize;
-
-       blockcount = size / blocksize;
-       remainsize = size % blocksize;
-
-       for (i = 0; i < blockcount; i++) {
-               offset = i * blocksize;
-               rtl_write_dword(rtlpriv, (FW_8192C_START_ADDRESS + offset),
-                               *(pu4byteptr + i));
-       }
-       if (remainsize) {
-               offset = blockcount * blocksize;
-               bufferptr += offset;
-               for (i = 0; i < remainsize; i++) {
-                       rtl_write_byte(rtlpriv,
-                                      (FW_8192C_START_ADDRESS + offset + i),
-                                      *(bufferptr + i));
-               }
-       }
-}
-EXPORT_SYMBOL_GPL(rtl8723_fw_block_write);
-
-void rtl8723_fw_page_write(struct ieee80211_hw *hw,
-                          u32 page, const u8 *buffer, u32 size)
-{
-       struct rtl_priv *rtlpriv = rtl_priv(hw);
-       u8 value8;
-       u8 u8page = (u8) (page & 0x07);
-
-       value8 = (rtl_read_byte(rtlpriv, REG_MCUFWDL + 2) & 0xF8) | u8page;
-
-       rtl_write_byte(rtlpriv, (REG_MCUFWDL + 2), value8);
-       rtl8723_fw_block_write(hw, buffer, size);
-}
-EXPORT_SYMBOL_GPL(rtl8723_fw_page_write);
-
-void rtl8723_fill_dummy(u8 *pfwbuf, u32 *pfwlen)
-{
-       u32 fwlen = *pfwlen;
-       u8 remain = (u8) (fwlen % 4);
-
-       remain = (remain == 0) ? 0 : (4 - remain);
-
-       while (remain > 0) {
-               pfwbuf[fwlen] = 0;
-               fwlen++;
-               remain--;
-       }
-       *pfwlen = fwlen;
-}
-EXPORT_SYMBOL(rtl8723_fill_dummy);
-
 void rtl8723_write_fw(struct ieee80211_hw *hw,
                      enum version_8723e version,
                      u8 *buffer, u32 size, u8 max_page)
@@ -123,7 +65,7 @@ void rtl8723_write_fw(struct ieee80211_hw *hw,
 
        RT_TRACE(rtlpriv, COMP_FW, DBG_TRACE, "FW size is %d bytes,\n", size);
 
-       rtl8723_fill_dummy(bufferptr, &size);
+       rtl_fill_dummy(bufferptr, &size);
 
        page_nums = size / FW_8192C_PAGE_SIZE;
        remain_size = size % FW_8192C_PAGE_SIZE;
@@ -134,15 +76,14 @@ void rtl8723_write_fw(struct ieee80211_hw *hw,
        }
        for (page = 0; page < page_nums; page++) {
                offset = page * FW_8192C_PAGE_SIZE;
-               rtl8723_fw_page_write(hw, page, (bufferptr + offset),
-                                     FW_8192C_PAGE_SIZE);
+               rtl_fw_page_write(hw, page, (bufferptr + offset),
+                                 FW_8192C_PAGE_SIZE);
        }
 
        if (remain_size) {
                offset = page_nums * FW_8192C_PAGE_SIZE;
                page = page_nums;
-               rtl8723_fw_page_write(hw, page, (bufferptr + offset),
-                                     remain_size);
+               rtl_fw_page_write(hw, page, (bufferptr + offset), remain_size);
        }
        RT_TRACE(rtlpriv, COMP_FW, DBG_TRACE, "FW write done.\n");
 }
index 8ea372d1626e5e75432c363f1b592df04a710817..77c25a9762335a6faf8bb69443d6b271e05a9478 100644 (file)
@@ -28,7 +28,6 @@
 
 #define REG_SYS_FUNC_EN                                0x0002
 #define REG_MCUFWDL                            0x0080
-#define FW_8192C_START_ADDRESS                 0x1000
 #define FW_8192C_PAGE_SIZE                     4096
 #define FW_8723A_POLLING_TIMEOUT_COUNT         1000
 #define FW_8723B_POLLING_TIMEOUT_COUNT         6000
@@ -84,10 +83,6 @@ enum rtl8723be_cmd {
 void rtl8723ae_firmware_selfreset(struct ieee80211_hw *hw);
 void rtl8723be_firmware_selfreset(struct ieee80211_hw *hw);
 void rtl8723_enable_fw_download(struct ieee80211_hw *hw, bool enable);
-void rtl8723_fw_block_write(struct ieee80211_hw *hw,
-                           const u8 *buffer, u32 size);
-void rtl8723_fw_page_write(struct ieee80211_hw *hw,
-                          u32 page, const u8 *buffer, u32 size);
 void rtl8723_write_fw(struct ieee80211_hw *hw,
                      enum version_8723e version,
                      u8 *buffer, u32 size, u8 max_page);
@@ -95,6 +90,5 @@ int rtl8723_fw_free_to_go(struct ieee80211_hw *hw, bool is_8723be, int count);
 int rtl8723_download_fw(struct ieee80211_hw *hw, bool is_8723be, int count);
 bool rtl8723_cmd_send_packet(struct ieee80211_hw *hw,
                             struct sk_buff *skb);
-void rtl8723_fill_dummy(u8 *pfwbuf, u32 *pfwlen);
 
 #endif
index 94e97dce545798d761f3b391d3c8c72fa1f4d776..328c64d465ba40829eb3682c0cd289f58b227302 100644 (file)
@@ -27,6 +27,7 @@
 #include "../pci.h"
 #include "../base.h"
 #include "../core.h"
+#include "../efuse.h"
 #include "reg.h"
 #include "def.h"
 #include "fw.h"
@@ -51,63 +52,6 @@ static void _rtl8821ae_enable_fw_download(struct ieee80211_hw *hw, bool enable)
        }
 }
 
-static void _rtl8821ae_fw_block_write(struct ieee80211_hw *hw,
-                                     const u8 *buffer, u32 size)
-{
-       struct rtl_priv *rtlpriv = rtl_priv(hw);
-       u32 blocksize = sizeof(u32);
-       u8 *bufferptr = (u8 *)buffer;
-       u32 *pu4byteptr = (u32 *)buffer;
-       u32 i, offset, blockcount, remainsize;
-
-       blockcount = size / blocksize;
-       remainsize = size % blocksize;
-
-       for (i = 0; i < blockcount; i++) {
-               offset = i * blocksize;
-               rtl_write_dword(rtlpriv, (FW_8821AE_START_ADDRESS + offset),
-                               *(pu4byteptr + i));
-       }
-
-       if (remainsize) {
-               offset = blockcount * blocksize;
-               bufferptr += offset;
-               for (i = 0; i < remainsize; i++) {
-                       rtl_write_byte(rtlpriv, (FW_8821AE_START_ADDRESS +
-                                       offset + i), *(bufferptr + i));
-               }
-       }
-}
-
-static void _rtl8821ae_fw_page_write(struct ieee80211_hw *hw,
-                                    u32 page, const u8 *buffer, u32 size)
-{
-       struct rtl_priv *rtlpriv = rtl_priv(hw);
-       u8 value8;
-       u8 u8page = (u8)(page & 0x07);
-
-       value8 = (rtl_read_byte(rtlpriv, REG_MCUFWDL + 2) & 0xF8) | u8page;
-
-       rtl_write_byte(rtlpriv, (REG_MCUFWDL + 2), value8);
-       _rtl8821ae_fw_block_write(hw, buffer, size);
-}
-
-static void _rtl8821ae_fill_dummy(u8 *pfwbuf, u32 *pfwlen)
-{
-       u32 fwlen = *pfwlen;
-       u8 remain = (u8)(fwlen % 4);
-
-       remain = (remain == 0) ? 0 : (4 - remain);
-
-       while (remain > 0) {
-               pfwbuf[fwlen] = 0;
-               fwlen++;
-               remain--;
-       }
-
-       *pfwlen = fwlen;
-}
-
 static void _rtl8821ae_write_fw(struct ieee80211_hw *hw,
                                enum version_8821ae version,
                                u8 *buffer, u32 size)
@@ -119,7 +63,7 @@ static void _rtl8821ae_write_fw(struct ieee80211_hw *hw,
 
        RT_TRACE(rtlpriv, COMP_FW, DBG_LOUD, "FW size is %d bytes,\n", size);
 
-       _rtl8821ae_fill_dummy(bufferptr, &size);
+       rtl_fill_dummy(bufferptr, &size);
 
        pagenums = size / FW_8821AE_PAGE_SIZE;
        remainsize = size % FW_8821AE_PAGE_SIZE;
@@ -129,15 +73,14 @@ static void _rtl8821ae_write_fw(struct ieee80211_hw *hw,
 
        for (page = 0; page < pagenums; page++) {
                offset = page * FW_8821AE_PAGE_SIZE;
-               _rtl8821ae_fw_page_write(hw, page, (bufferptr + offset),
-                                        FW_8821AE_PAGE_SIZE);
+               rtl_fw_page_write(hw, page, (bufferptr + offset),
+                                 FW_8821AE_PAGE_SIZE);
        }
 
        if (remainsize) {
                offset = pagenums * FW_8821AE_PAGE_SIZE;
                page = pagenums;
-               _rtl8821ae_fw_page_write(hw, page, (bufferptr + offset),
-                                        remainsize);
+               rtl_fw_page_write(hw, page, (bufferptr + offset), remainsize);
        }
 }
 
index 220de5f89dbce5fd4ed2ac24c59ceecbe2647c0b..cd2a53b7e053cf3fafb1dcd03434bd75f4da2451 100644 (file)
@@ -160,8 +160,6 @@ int rtl8821ae_init_sw_vars(struct ieee80211_hw *hw)
        rtlpriv->psc.wo_wlan_mode = WAKE_ON_MAGIC_PACKET |
                                    WAKE_ON_PATTERN_MATCH;
 
-       /* for debug level */
-       rtlpriv->dbg.global_debuglevel = rtlpriv->cfg->mod_params->debug;
        /* for LPS & IPS */
        rtlpriv->psc.inactiveps = rtlpriv->cfg->mod_params->inactiveps;
        rtlpriv->psc.swctrl_lps = rtlpriv->cfg->mod_params->swctrl_lps;
@@ -309,7 +307,8 @@ static struct rtl_mod_params rtl8821ae_mod_params = {
        .fwctrl_lps = true,
        .msi_support = true,
        .int_clear = true,
-       .debug = 0,
+       .debug_level = 0,
+       .debug_mask = 0,
        .disable_watchdog = 0,
 };
 
@@ -430,7 +429,8 @@ MODULE_DESCRIPTION("Realtek 8821ae 802.11ac PCI wireless");
 MODULE_FIRMWARE("rtlwifi/rtl8821aefw.bin");
 
 module_param_named(swenc, rtl8821ae_mod_params.sw_crypto, bool, 0444);
-module_param_named(debug, rtl8821ae_mod_params.debug, int, 0444);
+module_param_named(debug_level, rtl8821ae_mod_params.debug_level, int, 0644);
+module_param_named(debug_mask, rtl8821ae_mod_params.debug_mask, ullong, 0644);
 module_param_named(ips, rtl8821ae_mod_params.inactiveps, bool, 0444);
 module_param_named(swlps, rtl8821ae_mod_params.swctrl_lps, bool, 0444);
 module_param_named(fwlps, rtl8821ae_mod_params.fwctrl_lps, bool, 0444);
@@ -443,7 +443,8 @@ MODULE_PARM_DESC(ips, "Set to 0 to not use link power save (default 1)\n");
 MODULE_PARM_DESC(swlps, "Set to 1 to use SW control power save (default 0)\n");
 MODULE_PARM_DESC(fwlps, "Set to 1 to use FW control power save (default 1)\n");
 MODULE_PARM_DESC(msi, "Set to 1 to use MSI interrupts mode (default 1)\n");
-MODULE_PARM_DESC(debug, "Set debug level (0-5) (default 0)");
+MODULE_PARM_DESC(debug_level, "Set debug level (0-5) (default 0)");
+MODULE_PARM_DESC(debug_mask, "Set debug mask (default 0)");
 MODULE_PARM_DESC(disable_watchdog, "Set to 1 to disable the watchdog (default 0)\n");
 MODULE_PARM_DESC(int_clear, "Set to 0 to disable interrupt clear before set (default 1)\n");
 
index 916a230aeeaaaf869bfeda189782840806e52eca..4d989b8ab185681aa500b4e7de7fc34260f904a9 100644 (file)
@@ -818,12 +818,30 @@ static void rtl_usb_stop(struct ieee80211_hw *hw)
        struct rtl_priv *rtlpriv = rtl_priv(hw);
        struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
        struct rtl_usb *rtlusb = rtl_usbdev(rtl_usbpriv(hw));
+       struct urb *urb;
 
        /* should after adapter start and interrupt enable. */
        set_hal_stop(rtlhal);
        cancel_work_sync(&rtlpriv->works.fill_h2c_cmd);
        /* Enable software */
        SET_USB_STOP(rtlusb);
+
+       /* free pre-allocated URBs from rtl_usb_start() */
+       usb_kill_anchored_urbs(&rtlusb->rx_submitted);
+
+       tasklet_kill(&rtlusb->rx_work_tasklet);
+       cancel_work_sync(&rtlpriv->works.lps_change_work);
+
+       flush_workqueue(rtlpriv->works.rtl_wq);
+
+       skb_queue_purge(&rtlusb->rx_queue);
+
+       while ((urb = usb_get_from_anchor(&rtlusb->rx_cleanup_urbs))) {
+               usb_free_coherent(urb->dev, urb->transfer_buffer_length,
+                               urb->transfer_buffer, urb->transfer_dma);
+               usb_free_urb(urb);
+       }
+
        rtlpriv->cfg->ops->hw_disable(hw);
 }
 
@@ -1074,7 +1092,6 @@ int rtl_usb_probe(struct usb_interface *intf,
        rtlpriv->rtlhal.interface = INTF_USB;
        rtlpriv->cfg = rtl_hal_cfg;
        rtlpriv->intf_ops = &rtl_usb_ops;
-       rtl_dbgp_flag_init(hw);
        /* Init IO handler */
        _rtl_usb_io_handler_init(&udev->dev, hw);
        rtlpriv->cfg->ops->read_chip_version(hw);
index dafe486f844867a1f96637af5fff774bf3ee3afd..310fa90200b272d8cadea1c1daf59c7ca9bc3daf 100644 (file)
@@ -2221,11 +2221,13 @@ struct rtl_intf_ops {
 };
 
 struct rtl_mod_params {
+       /* default: 0,0 */
+       u64 debug_mask;
        /* default: 0 = using hardware encryption */
        bool sw_crypto;
 
        /* default: 0 = DBG_EMERG (0)*/
-       int debug;
+       int debug_level;
 
        /* default: 1 = using no linked power save */
        bool inactiveps;
@@ -2345,16 +2347,6 @@ struct rtl_works {
        struct work_struct fill_h2c_cmd;
 };
 
-struct rtl_debug {
-       u32 dbgp_type[DBGP_TYPE_MAX];
-       int global_debuglevel;
-       u64 global_debugcomponents;
-
-       /* add for proc debug */
-       struct proc_dir_entry *proc_dir;
-       char proc_name[20];
-};
-
 #define MIMO_PS_STATIC                 0
 #define MIMO_PS_DYNAMIC                        1
 #define MIMO_PS_NOLIMIT                        3
@@ -2583,7 +2575,6 @@ struct rtl_priv {
        /* sta entry list for ap adhoc or mesh */
        struct list_head entry_list;
 
-       struct rtl_debug dbg;
        int max_fw_size;
 
        /*
@@ -2713,23 +2704,14 @@ enum bt_radio_shared {
        (le32_to_cpu(_val))
 
 /* Read data from memory */
-#define READEF1BYTE(_ptr)      \
+#define READEF1BYTE(_ptr)      \
        EF1BYTE(*((u8 *)(_ptr)))
 /* Read le16 data from memory and convert to host ordering */
-#define READEF2BYTE(_ptr)      \
+#define READEF2BYTE(_ptr)      \
        EF2BYTE(*(_ptr))
-#define READEF4BYTE(_ptr)      \
+#define READEF4BYTE(_ptr)      \
        EF4BYTE(*(_ptr))
 
-/* Write data to memory */
-#define WRITEEF1BYTE(_ptr, _val)       \
-       (*((u8 *)(_ptr))) = EF1BYTE(_val)
-/* Write le16 data to memory in host ordering */
-#define WRITEEF2BYTE(_ptr, _val)       \
-       (*((u16 *)(_ptr))) = EF2BYTE(_val)
-#define WRITEEF4BYTE(_ptr, _val)       \
-       (*((u32 *)(_ptr))) = EF2BYTE(_val)
-
 /* Create a bit mask
  * Examples:
  * BIT_LEN_MASK_32(0) => 0x00000000
@@ -2810,14 +2792,14 @@ value to host byte ordering.*/
  * Set subfield of little-endian 4-byte value to specified value.
  */
 #define SET_BITS_TO_LE_4BYTE(__pstart, __bitoffset, __bitlen, __val) \
-       *((u32 *)(__pstart)) = \
-       ( \
+       *((__le32 *)(__pstart)) = \
+       cpu_to_le32( \
                LE_BITS_CLEARED_TO_4BYTE(__pstart, __bitoffset, __bitlen) | \
                ((((u32)__val) & BIT_LEN_MASK_32(__bitlen)) << (__bitoffset)) \
        );
 #define SET_BITS_TO_LE_2BYTE(__pstart, __bitoffset, __bitlen, __val) \
-       *((u16 *)(__pstart)) = \
-       ( \
+       *((__le16 *)(__pstart)) = \
+       cpu_to_le16( \
                LE_BITS_CLEARED_TO_2BYTE(__pstart, __bitoffset, __bitlen) | \
                ((((u16)__val) & BIT_LEN_MASK_16(__bitlen)) << (__bitoffset)) \
        );
index 47fe7f96a242794caf0150f367ae8300bd1d2c48..287023ef4a782f33375d337ae97ba21671b6327d 100644 (file)
@@ -81,13 +81,6 @@ static int __must_check wl12xx_sdio_raw_read(struct device *child, int addr,
 
        sdio_claim_host(func);
 
-       if (unlikely(dump)) {
-               printk(KERN_DEBUG "wlcore_sdio: READ from 0x%04x\n", addr);
-               print_hex_dump(KERN_DEBUG, "wlcore_sdio: READ ",
-                               DUMP_PREFIX_OFFSET, 16, 1,
-                               buf, len, false);
-       }
-
        if (unlikely(addr == HW_ACCESS_ELP_CTRL_REG)) {
                ((u8 *)buf)[0] = sdio_f0_readb(func, addr, &ret);
                dev_dbg(child->parent, "sdio read 52 addr 0x%x, byte 0x%02x\n",
@@ -107,6 +100,13 @@ static int __must_check wl12xx_sdio_raw_read(struct device *child, int addr,
        if (WARN_ON(ret))
                dev_err(child->parent, "sdio read failed (%d)\n", ret);
 
+       if (unlikely(dump)) {
+               printk(KERN_DEBUG "wlcore_sdio: READ from 0x%04x\n", addr);
+               print_hex_dump(KERN_DEBUG, "wlcore_sdio: READ ",
+                              DUMP_PREFIX_OFFSET, 16, 1,
+                              buf, len, false);
+       }
+
        return ret;
 }
 
index d43ef96bf0753ce5d11c615d91b81a8298afc69a..71b113e1223fb1dfb7692e51ec736067c56e97ae 100644 (file)
@@ -36,6 +36,7 @@
 #define SDIO_DEVICE_ID_BROADCOM_43362          0xa962
 #define SDIO_DEVICE_ID_BROADCOM_43430          0xa9a6
 #define SDIO_DEVICE_ID_BROADCOM_4345           0x4345
+#define SDIO_DEVICE_ID_BROADCOM_43455          0xa9bf
 #define SDIO_DEVICE_ID_BROADCOM_4354           0x4354
 #define SDIO_DEVICE_ID_BROADCOM_4356           0x4356
 
index 7b88697929e9ef6f729ce9fd1d9e512d352f8b94..b8478ee7a71f2757195a0aa135b0eeb38c766d9c 100644 (file)
@@ -1,7 +1,7 @@
 #ifndef __QCOM_SMEM_STATE__
 #define __QCOM_SMEM_STATE__
 
-#include <linux/errno.h>
+#include <linux/err.h>
 
 struct device_node;
 struct qcom_smem_state;