Merge tag 'iwlwifi-next-for-kalle-2015-01-22' of https://git.kernel.org/pub/scm/linux...
authorKalle Valo <kvalo@codeaurora.org>
Fri, 23 Jan 2015 15:51:54 +0000 (17:51 +0200)
committerKalle Valo <kvalo@codeaurora.org>
Fri, 23 Jan 2015 15:51:54 +0000 (17:51 +0200)
* more work for new devices (4165 / 8260)
* cleanups / improvemnts in rate control
* fixes for TDLS
* major statistics work from Johannes - more to come
* improvements for the fw error dump infrastructure
* usual amount of small fixes here and there (scan, D0i3 etc...)

36 files changed:
drivers/net/wireless/iwlwifi/iwl-7000.c
drivers/net/wireless/iwlwifi/iwl-8000.c
drivers/net/wireless/iwlwifi/iwl-config.h
drivers/net/wireless/iwlwifi/iwl-csr.h
drivers/net/wireless/iwlwifi/iwl-drv.c
drivers/net/wireless/iwlwifi/iwl-fw-error-dump.h
drivers/net/wireless/iwlwifi/iwl-fw-file.h
drivers/net/wireless/iwlwifi/iwl-io.c
drivers/net/wireless/iwlwifi/iwl-prph.h
drivers/net/wireless/iwlwifi/mvm/coex.c
drivers/net/wireless/iwlwifi/mvm/coex_legacy.c
drivers/net/wireless/iwlwifi/mvm/constants.h
drivers/net/wireless/iwlwifi/mvm/debugfs-vif.c
drivers/net/wireless/iwlwifi/mvm/debugfs.c
drivers/net/wireless/iwlwifi/mvm/fw-api-power.h
drivers/net/wireless/iwlwifi/mvm/fw-api-rs.h
drivers/net/wireless/iwlwifi/mvm/fw-api-scan.h
drivers/net/wireless/iwlwifi/mvm/fw-api-stats.h [new file with mode: 0644]
drivers/net/wireless/iwlwifi/mvm/fw-api-tx.h
drivers/net/wireless/iwlwifi/mvm/fw-api.h
drivers/net/wireless/iwlwifi/mvm/fw.c
drivers/net/wireless/iwlwifi/mvm/mac-ctxt.c
drivers/net/wireless/iwlwifi/mvm/mac80211.c
drivers/net/wireless/iwlwifi/mvm/mvm.h
drivers/net/wireless/iwlwifi/mvm/nvm.c
drivers/net/wireless/iwlwifi/mvm/ops.c
drivers/net/wireless/iwlwifi/mvm/phy-ctxt.c
drivers/net/wireless/iwlwifi/mvm/rs.c
drivers/net/wireless/iwlwifi/mvm/rx.c
drivers/net/wireless/iwlwifi/mvm/scan.c
drivers/net/wireless/iwlwifi/mvm/sta.c
drivers/net/wireless/iwlwifi/mvm/tx.c
drivers/net/wireless/iwlwifi/mvm/utils.c
drivers/net/wireless/iwlwifi/pcie/drv.c
drivers/net/wireless/iwlwifi/pcie/trans.c
drivers/net/wireless/iwlwifi/pcie/tx.c

index 9e76799c47506bc9bc87f5d5d382cda5841368c9..97e38d2e2983b757717be0dcac1aa3b5be262336 100644 (file)
@@ -69,8 +69,8 @@
 #include "iwl-agn-hw.h"
 
 /* Highest firmware API version supported */
-#define IWL7260_UCODE_API_MAX  10
-#define IWL3160_UCODE_API_MAX  10
+#define IWL7260_UCODE_API_MAX  12
+#define IWL3160_UCODE_API_MAX  12
 
 /* Oldest version we won't warn about */
 #define IWL7260_UCODE_API_OK   10
 #define IWL7265_MODULE_FIRMWARE(api) IWL7265_FW_PRE __stringify(api) ".ucode"
 
 #define IWL7265D_FW_PRE "iwlwifi-7265D-"
-#define IWL7265D_MODULE_FIRMWARE(api) IWL7265_FW_PRE __stringify(api) ".ucode"
+#define IWL7265D_MODULE_FIRMWARE(api) IWL7265D_FW_PRE __stringify(api) ".ucode"
 
 #define NVM_HW_SECTION_NUM_FAMILY_7000         0
 
index 46e9c9ac6ba205235b150754318eddf067f00ba9..2f7fe8167dc963259dfaea5469de47dc2bbad6f3 100644 (file)
@@ -69,7 +69,7 @@
 #include "iwl-agn-hw.h"
 
 /* Highest firmware API version supported */
-#define IWL8000_UCODE_API_MAX  10
+#define IWL8000_UCODE_API_MAX  12
 
 /* Oldest version we won't warn about */
 #define IWL8000_UCODE_API_OK   10
@@ -84,6 +84,8 @@
 /* Memory offsets and lengths */
 #define IWL8260_DCCM_OFFSET            0x800000
 #define IWL8260_DCCM_LEN               0x18000
+#define IWL8260_DCCM2_OFFSET           0x880000
+#define IWL8260_DCCM2_LEN              0x8000
 #define IWL8260_SMEM_OFFSET            0x400000
 #define IWL8260_SMEM_LEN               0x68000
 
@@ -134,6 +136,8 @@ static const struct iwl_ht_params iwl8000_ht_params = {
        .non_shared_ant = ANT_A,                                \
        .dccm_offset = IWL8260_DCCM_OFFSET,                     \
        .dccm_len = IWL8260_DCCM_LEN,                           \
+       .dccm2_offset = IWL8260_DCCM2_OFFSET,                   \
+       .dccm2_len = IWL8260_DCCM2_LEN,                         \
        .smem_offset = IWL8260_SMEM_OFFSET,                     \
        .smem_len = IWL8260_SMEM_LEN
 
@@ -156,6 +160,16 @@ const struct iwl_cfg iwl8260_2ac_cfg = {
        .max_ht_ampdu_exponent = IEEE80211_HT_MAX_AMPDU_64K,
 };
 
+const struct iwl_cfg iwl4165_2ac_cfg = {
+       .name = "Intel(R) Dual Band Wireless AC 4165",
+       .fw_name_pre = IWL8000_FW_PRE,
+       IWL_DEVICE_8000,
+       .ht_params = &iwl8000_ht_params,
+       .nvm_ver = IWL8000_NVM_VERSION,
+       .nvm_calib_ver = IWL8000_TX_POWER_VERSION,
+       .max_ht_ampdu_exponent = IEEE80211_HT_MAX_AMPDU_64K,
+};
+
 const struct iwl_cfg iwl8260_2ac_sdio_cfg = {
        .name = "Intel(R) Dual Band Wireless-AC 8260",
        .fw_name_pre = IWL8000_FW_PRE,
index fa0bc4845e1ac937ee57bc3a2b1ba8e110fc90d5..445bff690a63f34e1445dc9d9b4f0d0ac1325b5c 100644 (file)
@@ -263,6 +263,8 @@ struct iwl_pwr_tx_backoff {
  *     station can receive in VHT
  * @dccm_offset: offset from which DCCM begins
  * @dccm_len: length of DCCM (including runtime stack CCM)
+ * @dccm2_offset: offset from which the second DCCM begins
+ * @dccm2_len: length of the second DCCM
  * @smem_offset: offset from which the SMEM begins
  * @smem_len: the length of SMEM
  *
@@ -310,6 +312,8 @@ struct iwl_cfg {
        unsigned int max_vht_ampdu_exponent;
        const u32 dccm_offset;
        const u32 dccm_len;
+       const u32 dccm2_offset;
+       const u32 dccm2_len;
        const u32 smem_offset;
        const u32 smem_len;
 };
@@ -378,6 +382,7 @@ extern const struct iwl_cfg iwl7265d_2n_cfg;
 extern const struct iwl_cfg iwl7265d_n_cfg;
 extern const struct iwl_cfg iwl8260_2n_cfg;
 extern const struct iwl_cfg iwl8260_2ac_cfg;
+extern const struct iwl_cfg iwl4165_2ac_cfg;
 extern const struct iwl_cfg iwl8260_2ac_sdio_cfg;
 extern const struct iwl_cfg iwl4165_2ac_sdio_cfg;
 #endif /* CONFIG_IWLMVM */
index 7f40cf36ec0ed200b1906e0dd7ca11a4385f24d0..faa17f2e352adf72b740ffc37dfb03e747b003e1 100644 (file)
 enum {
        SILICON_A_STEP = 0,
        SILICON_B_STEP,
+       SILICON_C_STEP,
 };
 
 
index e766dcdf72ab0a365126466f43f4a682801867af..e7c0df6db6eef91ebace3e873bd02cdfc0d6f5f7 100644 (file)
@@ -1490,7 +1490,7 @@ module_param_named(d0i3_disable, iwlwifi_mod_params.d0i3_disable,
 MODULE_PARM_DESC(d0i3_disable, "disable d0i3 functionality (default: Y)");
 
 module_param_named(uapsd_disable, iwlwifi_mod_params.uapsd_disable,
-                  bool, S_IRUGO);
+                  bool, S_IRUGO | S_IWUSR);
 #ifdef CONFIG_IWLWIFI_UAPSD
 MODULE_PARM_DESC(uapsd_disable, "disable U-APSD functionality (default: N)");
 #else
index ec115bded88a824b7fc4ded21249dd4a9a448aaf..919a2548a92c5dca064258c437cdb8e59ade42db 100644 (file)
@@ -134,6 +134,27 @@ struct iwl_fw_error_dump_txcmd {
        u8 data[];
 } __packed;
 
+/**
+ * struct iwl_fw_error_dump_fifo - RX/TX FIFO data
+ * @fifo_num: number of FIFO (starting from 0)
+ * @available_bytes: num of bytes available in FIFO (may be less than FIFO size)
+ * @wr_ptr: position of write pointer
+ * @rd_ptr: position of read pointer
+ * @fence_ptr: position of fence pointer
+ * @fence_mode: the current mode of the fence (before locking) -
+ *     0=follow RD pointer ; 1 = freeze
+ * @data: all of the FIFO's data
+ */
+struct iwl_fw_error_dump_fifo {
+       __le32 fifo_num;
+       __le32 available_bytes;
+       __le32 wr_ptr;
+       __le32 rd_ptr;
+       __le32 fence_ptr;
+       __le32 fence_mode;
+       u8 data[];
+} __packed;
+
 enum iwl_fw_error_dump_family {
        IWL_FW_ERROR_DUMP_FAMILY_7 = 7,
        IWL_FW_ERROR_DUMP_FAMILY_8 = 8,
index 752c72b77fba29b9d5b3b2e20d718f36cabf3951..e4f589898eda38132a3ac3bd61278fcc319611e1 100644 (file)
@@ -235,25 +235,34 @@ enum iwl_ucode_tlv_flag {
 
 /**
  * enum iwl_ucode_tlv_api - ucode api
- * @IWL_UCODE_TLV_API_WOWLAN_CONFIG_TID: wowlan config includes tid field.
- * @IWL_UCODE_TLV_CAPA_EXTENDED_BEACON: Support Extended beacon notification
  * @IWL_UCODE_TLV_API_BT_COEX_SPLIT: new API for BT Coex
- * @IWL_UCODE_TLV_API_CSA_FLOW: ucode can do unbind-bind flow for CSA.
  * @IWL_UCODE_TLV_API_DISABLE_STA_TX: ucode supports tx_disable bit.
  * @IWL_UCODE_TLV_API_LMAC_SCAN: This ucode uses LMAC unified scan API.
  * @IWL_UCODE_TLV_API_SF_NO_DUMMY_NOTIF: ucode supports disabling dummy notif.
  * @IWL_UCODE_TLV_API_FRAGMENTED_SCAN: This ucode supports active dwell time
  *     longer than the passive one, which is essential for fragmented scan.
+ * IWL_UCODE_TLV_API_HDC_PHASE_0: ucode supports finer configuration of LTR
+ * @IWL_UCODE_TLV_API_BASIC_DWELL: use only basic dwell time in scan command,
+ *     regardless of the band or the number of the probes. FW will calculate
+ *     the actual dwell time.
+ * @IWL_UCODE_TLV_API_SCD_CFG: This firmware can configure the scheduler
+ *     through the dedicated host command.
+ * @IWL_UCODE_TLV_API_SINGLE_SCAN_EBS: EBS is supported for single scans too.
+ * @IWL_UCODE_TLV_API_ASYNC_DTM: Async temperature notifications are supported.
+ * @IWL_UCODE_TLV_API_LQ_SS_PARAMS: Configure STBC/BFER via LQ CMD ss_params
  */
 enum iwl_ucode_tlv_api {
-       IWL_UCODE_TLV_API_WOWLAN_CONFIG_TID     = BIT(0),
-       IWL_UCODE_TLV_CAPA_EXTENDED_BEACON      = BIT(1),
        IWL_UCODE_TLV_API_BT_COEX_SPLIT         = BIT(3),
-       IWL_UCODE_TLV_API_CSA_FLOW              = BIT(4),
        IWL_UCODE_TLV_API_DISABLE_STA_TX        = BIT(5),
        IWL_UCODE_TLV_API_LMAC_SCAN             = BIT(6),
        IWL_UCODE_TLV_API_SF_NO_DUMMY_NOTIF     = BIT(7),
        IWL_UCODE_TLV_API_FRAGMENTED_SCAN       = BIT(8),
+       IWL_UCODE_TLV_API_HDC_PHASE_0           = BIT(10),
+       IWL_UCODE_TLV_API_BASIC_DWELL           = BIT(13),
+       IWL_UCODE_TLV_API_SCD_CFG               = BIT(15),
+       IWL_UCODE_TLV_API_SINGLE_SCAN_EBS       = BIT(16),
+       IWL_UCODE_TLV_API_ASYNC_DTM             = BIT(17),
+       IWL_UCODE_TLV_API_LQ_SS_PARAMS          = BIT(18),
 };
 
 /**
index 7a2cbf6f90dbf39185c4a2e0ff52eddfb1b9d951..03250a45272eba7185851d74bc90d6a6863d664d 100644 (file)
@@ -193,11 +193,15 @@ void iwl_force_nmi(struct iwl_trans *trans)
         * DEVICE_SET_NMI_8000B_REG - is used.
         */
        if ((trans->cfg->device_family != IWL_DEVICE_FAMILY_8000) ||
-           (CSR_HW_REV_STEP(trans->hw_rev) == SILICON_A_STEP))
-               iwl_write_prph(trans, DEVICE_SET_NMI_REG, DEVICE_SET_NMI_VAL);
-       else
+           (CSR_HW_REV_STEP(trans->hw_rev) == SILICON_A_STEP)) {
+               iwl_write_prph(trans, DEVICE_SET_NMI_REG,
+                              DEVICE_SET_NMI_VAL_DRV);
+               iwl_write_prph(trans, DEVICE_SET_NMI_REG,
+                              DEVICE_SET_NMI_VAL_HW);
+       } else {
                iwl_write_prph(trans, DEVICE_SET_NMI_8000B_REG,
                               DEVICE_SET_NMI_8000B_VAL);
+       }
 }
 IWL_EXPORT_SYMBOL(iwl_force_nmi);
 
index 83ab4239082c969dd61b9fc3415c4b745ebcb55c..b21fcf042b7706393dc502289ecb3c9302bd2d06 100644 (file)
 
 /* Device NMI register */
 #define DEVICE_SET_NMI_REG 0x00a01c30
-#define DEVICE_SET_NMI_VAL 0x1
+#define DEVICE_SET_NMI_VAL_HW BIT(0)
+#define DEVICE_SET_NMI_VAL_DRV BIT(7)
 #define DEVICE_SET_NMI_8000B_REG 0x00a01c24
 #define DEVICE_SET_NMI_8000B_VAL 0x1000000
 
@@ -359,12 +360,30 @@ enum secure_load_status_reg {
 
 /* Rx FIFO */
 #define RXF_SIZE_ADDR                  (0xa00c88)
+#define RXF_RD_D_SPACE                 (0xa00c40)
+#define RXF_RD_WR_PTR                  (0xa00c50)
+#define RXF_RD_RD_PTR                  (0xa00c54)
+#define RXF_RD_FENCE_PTR               (0xa00c4c)
+#define RXF_SET_FENCE_MODE             (0xa00c14)
+#define RXF_LD_WR2FENCE                (0xa00c1c)
+#define RXF_FIFO_RD_FENCE_INC          (0xa00c68)
 #define RXF_SIZE_BYTE_CND_POS          (7)
 #define RXF_SIZE_BYTE_CNT_MSK          (0x3ff << RXF_SIZE_BYTE_CND_POS)
+#define RXF_DIFF_FROM_PREV             (0x200)
 
 #define RXF_LD_FENCE_OFFSET_ADDR       (0xa00c10)
 #define RXF_FIFO_RD_FENCE_ADDR         (0xa00c0c)
 
+/* Tx FIFO */
+#define TXF_FIFO_ITEM_CNT              (0xa00438)
+#define TXF_WR_PTR                     (0xa00414)
+#define TXF_RD_PTR                     (0xa00410)
+#define TXF_FENCE_PTR                  (0xa00418)
+#define TXF_LOCK_FENCE                 (0xa00424)
+#define TXF_LARC_NUM                   (0xa0043c)
+#define TXF_READ_MODIFY_DATA           (0xa00448)
+#define TXF_READ_MODIFY_ADDR           (0xa0044c)
+
 /* FW monitor */
 #define MON_BUFF_SAMPLE_CTL            (0xa03c00)
 #define MON_BUFF_BASE_ADDR             (0xa03c3c)
index d2fd48c31d3d77ad0eb4d5f6aebc7bd733dda7f6..1ec4d55155f7d72fecdbe19db62dd36546bb05e0 100644 (file)
@@ -342,7 +342,7 @@ static const struct corunning_block_luts antenna_coupling_ranges[] = {
        {
                .range = 12,
                .lut20 = {
-                       cpu_to_le32(0x00000001),  cpu_to_le32(0x00000000),
+                       cpu_to_le32(0x00000000),  cpu_to_le32(0x00000000),
                        cpu_to_le32(0x00000000),  cpu_to_le32(0x00000000),
                        cpu_to_le32(0x00000000),  cpu_to_le32(0x00000000),
                        cpu_to_le32(0x00000000),  cpu_to_le32(0x00000000),
@@ -363,7 +363,7 @@ static const struct corunning_block_luts antenna_coupling_ranges[] = {
        {
                .range = 20,
                .lut20 = {
-                       cpu_to_le32(0x00000002),  cpu_to_le32(0x00000000),
+                       cpu_to_le32(0x00000000),  cpu_to_le32(0x00000000),
                        cpu_to_le32(0x00000000),  cpu_to_le32(0x00000000),
                        cpu_to_le32(0x00000000),  cpu_to_le32(0x00000000),
                        cpu_to_le32(0x00000000),  cpu_to_le32(0x00000000),
@@ -384,7 +384,7 @@ static const struct corunning_block_luts antenna_coupling_ranges[] = {
        {
                .range = 21,
                .lut20 = {
-                       cpu_to_le32(0x00000003),  cpu_to_le32(0x00000000),
+                       cpu_to_le32(0x00000000),  cpu_to_le32(0x00000000),
                        cpu_to_le32(0x00000000),  cpu_to_le32(0x00000000),
                        cpu_to_le32(0x00000000),  cpu_to_le32(0x00000000),
                        cpu_to_le32(0x00000000),  cpu_to_le32(0x00000000),
@@ -405,7 +405,7 @@ static const struct corunning_block_luts antenna_coupling_ranges[] = {
        {
                .range = 23,
                .lut20 = {
-                       cpu_to_le32(0x00000004),  cpu_to_le32(0x00000000),
+                       cpu_to_le32(0x00000000),  cpu_to_le32(0x00000000),
                        cpu_to_le32(0x00000000),  cpu_to_le32(0x00000000),
                        cpu_to_le32(0x00000000),  cpu_to_le32(0x00000000),
                        cpu_to_le32(0x00000000),  cpu_to_le32(0x00000000),
@@ -426,7 +426,7 @@ static const struct corunning_block_luts antenna_coupling_ranges[] = {
        {
                .range = 27,
                .lut20 = {
-                       cpu_to_le32(0x00000005),  cpu_to_le32(0x00000000),
+                       cpu_to_le32(0x00000000),  cpu_to_le32(0x00000000),
                        cpu_to_le32(0x00000000),  cpu_to_le32(0x00000000),
                        cpu_to_le32(0x00000000),  cpu_to_le32(0x00000000),
                        cpu_to_le32(0x00000000),  cpu_to_le32(0x00000000),
@@ -447,7 +447,7 @@ static const struct corunning_block_luts antenna_coupling_ranges[] = {
        {
                .range = 30,
                .lut20 = {
-                       cpu_to_le32(0x00000006),  cpu_to_le32(0x00000000),
+                       cpu_to_le32(0x00000000),  cpu_to_le32(0x00000000),
                        cpu_to_le32(0x00000000),  cpu_to_le32(0x00000000),
                        cpu_to_le32(0x00000000),  cpu_to_le32(0x00000000),
                        cpu_to_le32(0x00000000),  cpu_to_le32(0x00000000),
@@ -468,7 +468,7 @@ static const struct corunning_block_luts antenna_coupling_ranges[] = {
        {
                .range = 32,
                .lut20 = {
-                       cpu_to_le32(0x00000007),  cpu_to_le32(0x00000000),
+                       cpu_to_le32(0x00000000),  cpu_to_le32(0x00000000),
                        cpu_to_le32(0x00000000),  cpu_to_le32(0x00000000),
                        cpu_to_le32(0x00000000),  cpu_to_le32(0x00000000),
                        cpu_to_le32(0x00000000),  cpu_to_le32(0x00000000),
@@ -489,7 +489,7 @@ static const struct corunning_block_luts antenna_coupling_ranges[] = {
        {
                .range = 33,
                .lut20 = {
-                       cpu_to_le32(0x00000008),  cpu_to_le32(0x00000000),
+                       cpu_to_le32(0x00000000),  cpu_to_le32(0x00000000),
                        cpu_to_le32(0x00000000),  cpu_to_le32(0x00000000),
                        cpu_to_le32(0x00000000),  cpu_to_le32(0x00000000),
                        cpu_to_le32(0x00000000),  cpu_to_le32(0x00000000),
index 973f2881dd1d17747345c1775dff786a9d924531..d530ef3da1071e5a421db3f4c072504b3571d8e3 100644 (file)
@@ -330,7 +330,7 @@ static const struct corunning_block_luts antenna_coupling_ranges[] = {
        {
                .range = 12,
                .lut20 = {
-                       cpu_to_le32(0x00000001),  cpu_to_le32(0x00000000),
+                       cpu_to_le32(0x00000000),  cpu_to_le32(0x00000000),
                        cpu_to_le32(0x00000000),  cpu_to_le32(0x00000000),
                        cpu_to_le32(0x00000000),  cpu_to_le32(0x00000000),
                        cpu_to_le32(0x00000000),  cpu_to_le32(0x00000000),
@@ -351,7 +351,7 @@ static const struct corunning_block_luts antenna_coupling_ranges[] = {
        {
                .range = 20,
                .lut20 = {
-                       cpu_to_le32(0x00000002),  cpu_to_le32(0x00000000),
+                       cpu_to_le32(0x00000000),  cpu_to_le32(0x00000000),
                        cpu_to_le32(0x00000000),  cpu_to_le32(0x00000000),
                        cpu_to_le32(0x00000000),  cpu_to_le32(0x00000000),
                        cpu_to_le32(0x00000000),  cpu_to_le32(0x00000000),
@@ -372,7 +372,7 @@ static const struct corunning_block_luts antenna_coupling_ranges[] = {
        {
                .range = 21,
                .lut20 = {
-                       cpu_to_le32(0x00000003),  cpu_to_le32(0x00000000),
+                       cpu_to_le32(0x00000000),  cpu_to_le32(0x00000000),
                        cpu_to_le32(0x00000000),  cpu_to_le32(0x00000000),
                        cpu_to_le32(0x00000000),  cpu_to_le32(0x00000000),
                        cpu_to_le32(0x00000000),  cpu_to_le32(0x00000000),
@@ -393,7 +393,7 @@ static const struct corunning_block_luts antenna_coupling_ranges[] = {
        {
                .range = 23,
                .lut20 = {
-                       cpu_to_le32(0x00000004),  cpu_to_le32(0x00000000),
+                       cpu_to_le32(0x00000000),  cpu_to_le32(0x00000000),
                        cpu_to_le32(0x00000000),  cpu_to_le32(0x00000000),
                        cpu_to_le32(0x00000000),  cpu_to_le32(0x00000000),
                        cpu_to_le32(0x00000000),  cpu_to_le32(0x00000000),
@@ -414,7 +414,7 @@ static const struct corunning_block_luts antenna_coupling_ranges[] = {
        {
                .range = 27,
                .lut20 = {
-                       cpu_to_le32(0x00000005),  cpu_to_le32(0x00000000),
+                       cpu_to_le32(0x00000000),  cpu_to_le32(0x00000000),
                        cpu_to_le32(0x00000000),  cpu_to_le32(0x00000000),
                        cpu_to_le32(0x00000000),  cpu_to_le32(0x00000000),
                        cpu_to_le32(0x00000000),  cpu_to_le32(0x00000000),
@@ -435,7 +435,7 @@ static const struct corunning_block_luts antenna_coupling_ranges[] = {
        {
                .range = 30,
                .lut20 = {
-                       cpu_to_le32(0x00000006),  cpu_to_le32(0x00000000),
+                       cpu_to_le32(0x00000000),  cpu_to_le32(0x00000000),
                        cpu_to_le32(0x00000000),  cpu_to_le32(0x00000000),
                        cpu_to_le32(0x00000000),  cpu_to_le32(0x00000000),
                        cpu_to_le32(0x00000000),  cpu_to_le32(0x00000000),
@@ -456,7 +456,7 @@ static const struct corunning_block_luts antenna_coupling_ranges[] = {
        {
                .range = 32,
                .lut20 = {
-                       cpu_to_le32(0x00000007),  cpu_to_le32(0x00000000),
+                       cpu_to_le32(0x00000000),  cpu_to_le32(0x00000000),
                        cpu_to_le32(0x00000000),  cpu_to_le32(0x00000000),
                        cpu_to_le32(0x00000000),  cpu_to_le32(0x00000000),
                        cpu_to_le32(0x00000000),  cpu_to_le32(0x00000000),
@@ -477,7 +477,7 @@ static const struct corunning_block_luts antenna_coupling_ranges[] = {
        {
                .range = 33,
                .lut20 = {
-                       cpu_to_le32(0x00000008),  cpu_to_le32(0x00000000),
+                       cpu_to_le32(0x00000000),  cpu_to_le32(0x00000000),
                        cpu_to_le32(0x00000000),  cpu_to_le32(0x00000000),
                        cpu_to_le32(0x00000000),  cpu_to_le32(0x00000000),
                        cpu_to_le32(0x00000000),  cpu_to_le32(0x00000000),
index 7cd1de820ca7950c444ba9243f7a7c3596c10998..d91c46b0f8887551ddfd812506e82a50d822652f 100644 (file)
 #define IWL_MVM_BT_COEX_MPLUT                  1
 #define IWL_MVM_BT_COEX_RRC                    1
 #define IWL_MVM_BT_COEX_TTC                    1
-#define IWL_MVM_BT_COEX_MPLUT_REG0             0x28412201
+#define IWL_MVM_BT_COEX_MPLUT_REG0             0x22002200
 #define IWL_MVM_BT_COEX_MPLUT_REG1             0x11118451
 #define IWL_MVM_BT_COEX_ANTENNA_COUPLING_THRS  30
 #define IWL_MVM_FW_MCAST_FILTER_PASS_ALL       0
 #define IWL_MVM_FW_BCAST_FILTER_PASS_ALL       0
 #define IWL_MVM_QUOTA_THRESHOLD                        8
 #define IWL_MVM_RS_RSSI_BASED_INIT_RATE         0
-#define IWL_MVM_RS_DISABLE_MIMO                        0
+#define IWL_MVM_RS_DISABLE_P2P_MIMO            0
 #define IWL_MVM_RS_NUM_TRY_BEFORE_ANT_TOGGLE    1
-#define IWL_MVM_RS_LEGACY_RETRIES_PER_RATE      1
 #define IWL_MVM_RS_HT_VHT_RETRIES_PER_RATE      2
 #define IWL_MVM_RS_HT_VHT_RETRIES_PER_RATE_TW   1
 #define IWL_MVM_RS_INITIAL_MIMO_NUM_RATES       3
 #define IWL_MVM_RS_INITIAL_SISO_NUM_RATES       3
-#define IWL_MVM_RS_INITIAL_LEGACY_NUM_RATES     16
+#define IWL_MVM_RS_INITIAL_LEGACY_NUM_RATES     2
+#define IWL_MVM_RS_INITIAL_LEGACY_RETRIES       2
+#define IWL_MVM_RS_SECONDARY_LEGACY_RETRIES    1
 #define IWL_MVM_RS_SECONDARY_LEGACY_NUM_RATES   16
 #define IWL_MVM_RS_SECONDARY_SISO_NUM_RATES     3
 #define IWL_MVM_RS_SECONDARY_SISO_RETRIES       1
index 8dc3ca9f49047b565d71b7981794e14349de7ae4..5fe14591e1c41f06d0f9c4893290165b3ea7674e 100644 (file)
@@ -517,6 +517,34 @@ static ssize_t iwl_dbgfs_low_latency_read(struct file *file,
        return simple_read_from_buffer(user_buf, count, ppos, buf, sizeof(buf));
 }
 
+static ssize_t iwl_dbgfs_uapsd_misbehaving_read(struct file *file,
+                                               char __user *user_buf,
+                                               size_t count, loff_t *ppos)
+{
+       struct ieee80211_vif *vif = file->private_data;
+       struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif);
+       char buf[20];
+       int len;
+
+       len = sprintf(buf, "%pM\n", mvmvif->uapsd_misbehaving_bssid);
+       return simple_read_from_buffer(user_buf, count, ppos, buf, len);
+}
+
+static ssize_t iwl_dbgfs_uapsd_misbehaving_write(struct ieee80211_vif *vif,
+                                                char *buf, size_t count,
+                                                loff_t *ppos)
+{
+       struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif);
+       struct iwl_mvm *mvm = mvmvif->mvm;
+       bool ret;
+
+       mutex_lock(&mvm->mutex);
+       ret = mac_pton(buf, mvmvif->uapsd_misbehaving_bssid);
+       mutex_unlock(&mvm->mutex);
+
+       return ret ? count : -EINVAL;
+}
+
 #define MVM_DEBUGFS_WRITE_FILE_OPS(name, bufsz) \
        _MVM_DEBUGFS_WRITE_FILE_OPS(name, bufsz, struct ieee80211_vif)
 #define MVM_DEBUGFS_READ_WRITE_FILE_OPS(name, bufsz) \
@@ -531,6 +559,7 @@ MVM_DEBUGFS_READ_FILE_OPS(mac_params);
 MVM_DEBUGFS_READ_WRITE_FILE_OPS(pm_params, 32);
 MVM_DEBUGFS_READ_WRITE_FILE_OPS(bf_params, 256);
 MVM_DEBUGFS_READ_WRITE_FILE_OPS(low_latency, 10);
+MVM_DEBUGFS_READ_WRITE_FILE_OPS(uapsd_misbehaving, 20);
 
 void iwl_mvm_vif_dbgfs_register(struct iwl_mvm *mvm, struct ieee80211_vif *vif)
 {
@@ -564,6 +593,8 @@ void iwl_mvm_vif_dbgfs_register(struct iwl_mvm *mvm, struct ieee80211_vif *vif)
        MVM_DEBUGFS_ADD_FILE_VIF(mac_params, mvmvif->dbgfs_dir, S_IRUSR);
        MVM_DEBUGFS_ADD_FILE_VIF(low_latency, mvmvif->dbgfs_dir,
                                 S_IRUSR | S_IWUSR);
+       MVM_DEBUGFS_ADD_FILE_VIF(uapsd_misbehaving, mvmvif->dbgfs_dir,
+                                S_IRUSR | S_IWUSR);
 
        if (vif->type == NL80211_IFTYPE_STATION && !vif->p2p &&
            mvmvif == mvm->bf_allowed_vif)
index a1b276c4dee04d93c01d6faa0b17825a24677815..82c09d86af8c055d5fdda608756d094905898a8f 100644 (file)
@@ -654,10 +654,10 @@ out:
        return ret ?: count;
 }
 
-#define PRINT_STATS_LE32(_str, _val)                                   \
+#define PRINT_STATS_LE32(_struct, _memb)                               \
                         pos += scnprintf(buf + pos, bufsz - pos,       \
-                                         fmt_table, _str,              \
-                                         le32_to_cpu(_val))
+                                         fmt_table, #_memb,            \
+                                         le32_to_cpu(_struct->_memb))
 
 static ssize_t iwl_dbgfs_fw_rx_stats_read(struct file *file,
                                          char __user *user_buf, size_t count,
@@ -692,97 +692,89 @@ static ssize_t iwl_dbgfs_fw_rx_stats_read(struct file *file,
 
        pos += scnprintf(buf + pos, bufsz - pos, fmt_header,
                         "Statistics_Rx - OFDM");
-       PRINT_STATS_LE32("ina_cnt", ofdm->ina_cnt);
-       PRINT_STATS_LE32("fina_cnt", ofdm->fina_cnt);
-       PRINT_STATS_LE32("plcp_err", ofdm->plcp_err);
-       PRINT_STATS_LE32("crc32_err", ofdm->crc32_err);
-       PRINT_STATS_LE32("overrun_err", ofdm->overrun_err);
-       PRINT_STATS_LE32("early_overrun_err", ofdm->early_overrun_err);
-       PRINT_STATS_LE32("crc32_good", ofdm->crc32_good);
-       PRINT_STATS_LE32("false_alarm_cnt", ofdm->false_alarm_cnt);
-       PRINT_STATS_LE32("fina_sync_err_cnt", ofdm->fina_sync_err_cnt);
-       PRINT_STATS_LE32("sfd_timeout", ofdm->sfd_timeout);
-       PRINT_STATS_LE32("fina_timeout", ofdm->fina_timeout);
-       PRINT_STATS_LE32("unresponded_rts", ofdm->unresponded_rts);
-       PRINT_STATS_LE32("rxe_frame_lmt_overrun",
-                        ofdm->rxe_frame_limit_overrun);
-       PRINT_STATS_LE32("sent_ack_cnt", ofdm->sent_ack_cnt);
-       PRINT_STATS_LE32("sent_cts_cnt", ofdm->sent_cts_cnt);
-       PRINT_STATS_LE32("sent_ba_rsp_cnt", ofdm->sent_ba_rsp_cnt);
-       PRINT_STATS_LE32("dsp_self_kill", ofdm->dsp_self_kill);
-       PRINT_STATS_LE32("mh_format_err", ofdm->mh_format_err);
-       PRINT_STATS_LE32("re_acq_main_rssi_sum", ofdm->re_acq_main_rssi_sum);
-       PRINT_STATS_LE32("reserved", ofdm->reserved);
+       PRINT_STATS_LE32(ofdm, ina_cnt);
+       PRINT_STATS_LE32(ofdm, fina_cnt);
+       PRINT_STATS_LE32(ofdm, plcp_err);
+       PRINT_STATS_LE32(ofdm, crc32_err);
+       PRINT_STATS_LE32(ofdm, overrun_err);
+       PRINT_STATS_LE32(ofdm, early_overrun_err);
+       PRINT_STATS_LE32(ofdm, crc32_good);
+       PRINT_STATS_LE32(ofdm, false_alarm_cnt);
+       PRINT_STATS_LE32(ofdm, fina_sync_err_cnt);
+       PRINT_STATS_LE32(ofdm, sfd_timeout);
+       PRINT_STATS_LE32(ofdm, fina_timeout);
+       PRINT_STATS_LE32(ofdm, unresponded_rts);
+       PRINT_STATS_LE32(ofdm, rxe_frame_lmt_overrun);
+       PRINT_STATS_LE32(ofdm, sent_ack_cnt);
+       PRINT_STATS_LE32(ofdm, sent_cts_cnt);
+       PRINT_STATS_LE32(ofdm, sent_ba_rsp_cnt);
+       PRINT_STATS_LE32(ofdm, dsp_self_kill);
+       PRINT_STATS_LE32(ofdm, mh_format_err);
+       PRINT_STATS_LE32(ofdm, re_acq_main_rssi_sum);
+       PRINT_STATS_LE32(ofdm, reserved);
 
        pos += scnprintf(buf + pos, bufsz - pos, fmt_header,
                         "Statistics_Rx - CCK");
-       PRINT_STATS_LE32("ina_cnt", cck->ina_cnt);
-       PRINT_STATS_LE32("fina_cnt", cck->fina_cnt);
-       PRINT_STATS_LE32("plcp_err", cck->plcp_err);
-       PRINT_STATS_LE32("crc32_err", cck->crc32_err);
-       PRINT_STATS_LE32("overrun_err", cck->overrun_err);
-       PRINT_STATS_LE32("early_overrun_err", cck->early_overrun_err);
-       PRINT_STATS_LE32("crc32_good", cck->crc32_good);
-       PRINT_STATS_LE32("false_alarm_cnt", cck->false_alarm_cnt);
-       PRINT_STATS_LE32("fina_sync_err_cnt", cck->fina_sync_err_cnt);
-       PRINT_STATS_LE32("sfd_timeout", cck->sfd_timeout);
-       PRINT_STATS_LE32("fina_timeout", cck->fina_timeout);
-       PRINT_STATS_LE32("unresponded_rts", cck->unresponded_rts);
-       PRINT_STATS_LE32("rxe_frame_lmt_overrun",
-                        cck->rxe_frame_limit_overrun);
-       PRINT_STATS_LE32("sent_ack_cnt", cck->sent_ack_cnt);
-       PRINT_STATS_LE32("sent_cts_cnt", cck->sent_cts_cnt);
-       PRINT_STATS_LE32("sent_ba_rsp_cnt", cck->sent_ba_rsp_cnt);
-       PRINT_STATS_LE32("dsp_self_kill", cck->dsp_self_kill);
-       PRINT_STATS_LE32("mh_format_err", cck->mh_format_err);
-       PRINT_STATS_LE32("re_acq_main_rssi_sum", cck->re_acq_main_rssi_sum);
-       PRINT_STATS_LE32("reserved", cck->reserved);
+       PRINT_STATS_LE32(cck, ina_cnt);
+       PRINT_STATS_LE32(cck, fina_cnt);
+       PRINT_STATS_LE32(cck, plcp_err);
+       PRINT_STATS_LE32(cck, crc32_err);
+       PRINT_STATS_LE32(cck, overrun_err);
+       PRINT_STATS_LE32(cck, early_overrun_err);
+       PRINT_STATS_LE32(cck, crc32_good);
+       PRINT_STATS_LE32(cck, false_alarm_cnt);
+       PRINT_STATS_LE32(cck, fina_sync_err_cnt);
+       PRINT_STATS_LE32(cck, sfd_timeout);
+       PRINT_STATS_LE32(cck, fina_timeout);
+       PRINT_STATS_LE32(cck, unresponded_rts);
+       PRINT_STATS_LE32(cck, rxe_frame_lmt_overrun);
+       PRINT_STATS_LE32(cck, sent_ack_cnt);
+       PRINT_STATS_LE32(cck, sent_cts_cnt);
+       PRINT_STATS_LE32(cck, sent_ba_rsp_cnt);
+       PRINT_STATS_LE32(cck, dsp_self_kill);
+       PRINT_STATS_LE32(cck, mh_format_err);
+       PRINT_STATS_LE32(cck, re_acq_main_rssi_sum);
+       PRINT_STATS_LE32(cck, reserved);
 
        pos += scnprintf(buf + pos, bufsz - pos, fmt_header,
                         "Statistics_Rx - GENERAL");
-       PRINT_STATS_LE32("bogus_cts", general->bogus_cts);
-       PRINT_STATS_LE32("bogus_ack", general->bogus_ack);
-       PRINT_STATS_LE32("non_bssid_frames", general->non_bssid_frames);
-       PRINT_STATS_LE32("filtered_frames", general->filtered_frames);
-       PRINT_STATS_LE32("non_channel_beacons", general->non_channel_beacons);
-       PRINT_STATS_LE32("channel_beacons", general->channel_beacons);
-       PRINT_STATS_LE32("num_missed_bcon", general->num_missed_bcon);
-       PRINT_STATS_LE32("adc_rx_saturation_time",
-                        general->adc_rx_saturation_time);
-       PRINT_STATS_LE32("ina_detection_search_time",
-                        general->ina_detection_search_time);
-       PRINT_STATS_LE32("beacon_silence_rssi_a",
-                        general->beacon_silence_rssi_a);
-       PRINT_STATS_LE32("beacon_silence_rssi_b",
-                        general->beacon_silence_rssi_b);
-       PRINT_STATS_LE32("beacon_silence_rssi_c",
-                        general->beacon_silence_rssi_c);
-       PRINT_STATS_LE32("interference_data_flag",
-                        general->interference_data_flag);
-       PRINT_STATS_LE32("channel_load", general->channel_load);
-       PRINT_STATS_LE32("dsp_false_alarms", general->dsp_false_alarms);
-       PRINT_STATS_LE32("beacon_rssi_a", general->beacon_rssi_a);
-       PRINT_STATS_LE32("beacon_rssi_b", general->beacon_rssi_b);
-       PRINT_STATS_LE32("beacon_rssi_c", general->beacon_rssi_c);
-       PRINT_STATS_LE32("beacon_energy_a", general->beacon_energy_a);
-       PRINT_STATS_LE32("beacon_energy_b", general->beacon_energy_b);
-       PRINT_STATS_LE32("beacon_energy_c", general->beacon_energy_c);
-       PRINT_STATS_LE32("num_bt_kills", general->num_bt_kills);
-       PRINT_STATS_LE32("mac_id", general->mac_id);
-       PRINT_STATS_LE32("directed_data_mpdu", general->directed_data_mpdu);
+       PRINT_STATS_LE32(general, bogus_cts);
+       PRINT_STATS_LE32(general, bogus_ack);
+       PRINT_STATS_LE32(general, non_bssid_frames);
+       PRINT_STATS_LE32(general, filtered_frames);
+       PRINT_STATS_LE32(general, non_channel_beacons);
+       PRINT_STATS_LE32(general, channel_beacons);
+       PRINT_STATS_LE32(general, num_missed_bcon);
+       PRINT_STATS_LE32(general, adc_rx_saturation_time);
+       PRINT_STATS_LE32(general, ina_detection_search_time);
+       PRINT_STATS_LE32(general, beacon_silence_rssi_a);
+       PRINT_STATS_LE32(general, beacon_silence_rssi_b);
+       PRINT_STATS_LE32(general, beacon_silence_rssi_c);
+       PRINT_STATS_LE32(general, interference_data_flag);
+       PRINT_STATS_LE32(general, channel_load);
+       PRINT_STATS_LE32(general, dsp_false_alarms);
+       PRINT_STATS_LE32(general, beacon_rssi_a);
+       PRINT_STATS_LE32(general, beacon_rssi_b);
+       PRINT_STATS_LE32(general, beacon_rssi_c);
+       PRINT_STATS_LE32(general, beacon_energy_a);
+       PRINT_STATS_LE32(general, beacon_energy_b);
+       PRINT_STATS_LE32(general, beacon_energy_c);
+       PRINT_STATS_LE32(general, num_bt_kills);
+       PRINT_STATS_LE32(general, mac_id);
+       PRINT_STATS_LE32(general, directed_data_mpdu);
 
        pos += scnprintf(buf + pos, bufsz - pos, fmt_header,
                         "Statistics_Rx - HT");
-       PRINT_STATS_LE32("plcp_err", ht->plcp_err);
-       PRINT_STATS_LE32("overrun_err", ht->overrun_err);
-       PRINT_STATS_LE32("early_overrun_err", ht->early_overrun_err);
-       PRINT_STATS_LE32("crc32_good", ht->crc32_good);
-       PRINT_STATS_LE32("crc32_err", ht->crc32_err);
-       PRINT_STATS_LE32("mh_format_err", ht->mh_format_err);
-       PRINT_STATS_LE32("agg_crc32_good", ht->agg_crc32_good);
-       PRINT_STATS_LE32("agg_mpdu_cnt", ht->agg_mpdu_cnt);
-       PRINT_STATS_LE32("agg_cnt", ht->agg_cnt);
-       PRINT_STATS_LE32("unsupport_mcs", ht->unsupport_mcs);
+       PRINT_STATS_LE32(ht, plcp_err);
+       PRINT_STATS_LE32(ht, overrun_err);
+       PRINT_STATS_LE32(ht, early_overrun_err);
+       PRINT_STATS_LE32(ht, crc32_good);
+       PRINT_STATS_LE32(ht, crc32_err);
+       PRINT_STATS_LE32(ht, mh_format_err);
+       PRINT_STATS_LE32(ht, agg_crc32_good);
+       PRINT_STATS_LE32(ht, agg_mpdu_cnt);
+       PRINT_STATS_LE32(ht, agg_cnt);
+       PRINT_STATS_LE32(ht, unsupport_mcs);
 
        mutex_unlock(&mvm->mutex);
 
@@ -988,9 +980,14 @@ static ssize_t iwl_dbgfs_fw_dbg_collect_write(struct iwl_mvm *mvm,
                                              char *buf, size_t count,
                                              loff_t *ppos)
 {
-       mutex_lock(&mvm->mutex);
+       int ret = iwl_mvm_ref_sync(mvm, IWL_MVM_REF_PRPH_WRITE);
+
+       if (ret)
+               return ret;
+
        iwl_mvm_fw_dbg_collect(mvm);
-       mutex_unlock(&mvm->mutex);
+
+       iwl_mvm_unref(mvm, IWL_MVM_REF_PRPH_WRITE);
 
        return count;
 }
@@ -1390,6 +1387,7 @@ static ssize_t iwl_dbgfs_d0i3_refs_read(struct file *file,
        PRINT_MVM_REF(IWL_MVM_REF_TM_CMD);
        PRINT_MVM_REF(IWL_MVM_REF_EXIT_WORK);
        PRINT_MVM_REF(IWL_MVM_REF_PROTECT_CSA);
+       PRINT_MVM_REF(IWL_MVM_REF_FW_DBG_COLLECT);
 
        return simple_read_from_buffer(user_buf, count, ppos, buf, pos);
 }
@@ -1489,6 +1487,26 @@ out:
        return count;
 }
 
+static ssize_t iwl_dbgfs_enable_scan_iteration_notif_write(struct iwl_mvm *mvm,
+                                                          char *buf,
+                                                          size_t count,
+                                                          loff_t *ppos)
+{
+       int val;
+
+       mutex_lock(&mvm->mutex);
+
+       if (kstrtoint(buf, 10, &val)) {
+               mutex_unlock(&mvm->mutex);
+               return -EINVAL;
+       }
+
+       mvm->scan_iter_notif_enabled = val;
+       mutex_unlock(&mvm->mutex);
+
+       return count;
+}
+
 MVM_DEBUGFS_READ_WRITE_FILE_OPS(prph_reg, 64);
 
 /* Device wide debugfs entries */
@@ -1511,6 +1529,7 @@ MVM_DEBUGFS_READ_WRITE_FILE_OPS(scan_ant_rxchain, 8);
 MVM_DEBUGFS_READ_WRITE_FILE_OPS(d0i3_refs, 8);
 MVM_DEBUGFS_READ_WRITE_FILE_OPS(fw_dbg_conf, 8);
 MVM_DEBUGFS_WRITE_FILE_OPS(fw_dbg_collect, 8);
+MVM_DEBUGFS_WRITE_FILE_OPS(enable_scan_iteration_notif, 8);
 
 #ifdef CONFIG_IWLWIFI_BCAST_FILTERING
 MVM_DEBUGFS_READ_WRITE_FILE_OPS(bcast_filters, 256);
@@ -1554,6 +1573,8 @@ int iwl_mvm_dbgfs_register(struct iwl_mvm *mvm, struct dentry *dbgfs_dir)
        MVM_DEBUGFS_ADD_FILE(d0i3_refs, mvm->debugfs_dir, S_IRUSR | S_IWUSR);
        MVM_DEBUGFS_ADD_FILE(fw_dbg_conf, mvm->debugfs_dir, S_IRUSR | S_IWUSR);
        MVM_DEBUGFS_ADD_FILE(fw_dbg_collect, mvm->debugfs_dir, S_IWUSR);
+       MVM_DEBUGFS_ADD_FILE(enable_scan_iteration_notif, mvm->debugfs_dir,
+                            S_IWUSR);
 
 #ifdef CONFIG_IWLWIFI_BCAST_FILTERING
        if (mvm->fw->ucode_capa.flags & IWL_UCODE_TLV_FLAGS_BCAST_FILTERING) {
index 430020047b777e5ff830d2ca0485cff86b64278e..4fc0938b3fb6d6c92464f63b3f206cbc798f92b7 100644 (file)
@@ -91,15 +91,33 @@ enum iwl_ltr_config_flags {
        LTR_CFG_FLAG_DENIE_C10_ON_PD = BIT(6),
 };
 
+/**
+ * struct iwl_ltr_config_cmd_v1 - configures the LTR
+ * @flags: See %enum iwl_ltr_config_flags
+ */
+struct iwl_ltr_config_cmd_v1 {
+       __le32 flags;
+       __le32 static_long;
+       __le32 static_short;
+} __packed; /* LTR_CAPABLE_API_S_VER_1 */
+
+#define LTR_VALID_STATES_NUM 4
+
 /**
  * struct iwl_ltr_config_cmd - configures the LTR
  * @flags: See %enum iwl_ltr_config_flags
+ * @static_long:
+ * @static_short:
+ * @ltr_cfg_values:
+ * @ltr_short_idle_timeout:
  */
 struct iwl_ltr_config_cmd {
        __le32 flags;
        __le32 static_long;
        __le32 static_short;
-} __packed;
+       __le32 ltr_cfg_values[LTR_VALID_STATES_NUM];
+       __le32 ltr_short_idle_timeout;
+} __packed; /* LTR_CAPABLE_API_S_VER_2 */
 
 /* Radio LP RX Energy Threshold measured in dBm */
 #define POWER_LPRX_RSSI_THRESHOLD      75
index 8bb5b94bf9639689fa6445cd046f97eccbcec834..6a2a6b0ab91b336147d47ae9a45ba70946a245b7 100644 (file)
@@ -308,6 +308,17 @@ enum {
 #define LQ_FLAG_DYNAMIC_BW_POS          6
 #define LQ_FLAG_DYNAMIC_BW_MSK          (1 << LQ_FLAG_DYNAMIC_BW_POS)
 
+/* Single Stream Parameters
+ * SS_STBC/BFER_ALLOWED - Controls whether STBC or Beamformer (BFER) is allowed
+ * ucode will make a smart decision between SISO/STBC/BFER
+ * SS_PARAMS_VALID - if not set ignore the ss_params field.
+ */
+enum {
+       RS_SS_STBC_ALLOWED = BIT(0),
+       RS_SS_BFER_ALLOWED = BIT(1),
+       RS_SS_PARAMS_VALID = BIT(31),
+};
+
 /**
  * struct iwl_lq_cmd - link quality command
  * @sta_id: station to update
@@ -330,7 +341,7 @@ enum {
  *     2 - 0x3f: maximal number of frames (up to 3f == 63)
  * @rs_table: array of rates for each TX try, each is rate_n_flags,
  *     meaning it is a combination of RATE_MCS_* and IWL_RATE_*_PLCP
- * @bf_params: beam forming params, currently not used
+ * @ss_params: single stream features. declare whether STBC or BFER are allowed.
  */
 struct iwl_lq_cmd {
        u8 sta_id;
@@ -348,6 +359,6 @@ struct iwl_lq_cmd {
        u8 agg_frame_cnt_limit;
        __le32 reserved2;
        __le32 rs_table[LQ_MAX_RETRY_NUM];
-       __le32 bf_params;
+       __le32 ss_params;
 }; /* LINK_QUALITY_CMD_API_S_VER_1 */
 #endif /* __fw_api_rs_h__ */
index 2d1a81c493f16bec4c505a88d3a3f8a764632521..cfc0e65b34a5e14494d83af1b560d0a33493aa66 100644 (file)
@@ -675,6 +675,7 @@ struct iwl_scan_channel_opt {
  * @IWL_MVM_LMAC_SCAN_FLAG_FRAGMENTED: all passive scans will be fragmented
  * @IWL_MVM_LMAC_SCAN_FLAGS_RRM_ENABLED: insert WFA vendor-specific TPC report
  *     and DS parameter set IEs into probe requests.
+ * @IWL_MVM_LMAC_SCAN_FLAG_MATCH: Send match found notification on matches
  */
 enum iwl_mvm_lmac_scan_flags {
        IWL_MVM_LMAC_SCAN_FLAG_PASS_ALL         = BIT(0),
@@ -684,6 +685,7 @@ enum iwl_mvm_lmac_scan_flags {
        IWL_MVM_LMAC_SCAN_FLAG_MULTIPLE_SSIDS   = BIT(4),
        IWL_MVM_LMAC_SCAN_FLAG_FRAGMENTED       = BIT(5),
        IWL_MVM_LMAC_SCAN_FLAGS_RRM_ENABLED     = BIT(6),
+       IWL_MVM_LMAC_SCAN_FLAG_MATCH            = BIT(9),
 };
 
 enum iwl_scan_priority {
diff --git a/drivers/net/wireless/iwlwifi/mvm/fw-api-stats.h b/drivers/net/wireless/iwlwifi/mvm/fw-api-stats.h
new file mode 100644 (file)
index 0000000..928168b
--- /dev/null
@@ -0,0 +1,277 @@
+/******************************************************************************
+ *
+ * This file is provided under a dual BSD/GPLv2 license.  When using or
+ * redistributing this file, you may do so under either license.
+ *
+ * GPL LICENSE SUMMARY
+ *
+ * Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved.
+ * Copyright(c) 2013 - 2015 Intel Mobile Communications GmbH
+ *
+ * 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
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110,
+ * USA
+ *
+ * The full GNU General Public License is included in this distribution
+ * in the file called COPYING.
+ *
+ * Contact Information:
+ *  Intel Linux Wireless <ilw@linux.intel.com>
+ * Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
+ *
+ * BSD LICENSE
+ *
+ * Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved.
+ * Copyright(c) 2013 - 2015 Intel Mobile Communications GmbH
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ *  * Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ *  * Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *  * Neither the name Intel Corporation nor the names of its
+ *    contributors may be used to endorse or promote products derived
+ *    from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ *****************************************************************************/
+
+#ifndef __fw_api_stats_h__
+#define __fw_api_stats_h__
+
+struct mvm_statistics_dbg {
+       __le32 burst_check;
+       __le32 burst_count;
+       __le32 wait_for_silence_timeout_cnt;
+       __le32 reserved[3];
+} __packed; /* STATISTICS_DEBUG_API_S_VER_2 */
+
+struct mvm_statistics_div {
+       __le32 tx_on_a;
+       __le32 tx_on_b;
+       __le32 exec_time;
+       __le32 probe_time;
+       __le32 rssi_ant;
+       __le32 reserved2;
+} __packed; /* STATISTICS_SLOW_DIV_API_S_VER_2 */
+
+struct mvm_statistics_rx_non_phy {
+       __le32 bogus_cts;       /* CTS received when not expecting CTS */
+       __le32 bogus_ack;       /* ACK received when not expecting ACK */
+       __le32 non_bssid_frames;        /* number of frames with BSSID that
+                                        * doesn't belong to the STA BSSID */
+       __le32 filtered_frames; /* count frames that were dumped in the
+                                * filtering process */
+       __le32 non_channel_beacons;     /* beacons with our bss id but not on
+                                        * our serving channel */
+       __le32 channel_beacons; /* beacons with our bss id and in our
+                                * serving channel */
+       __le32 num_missed_bcon; /* number of missed beacons */
+       __le32 adc_rx_saturation_time;  /* count in 0.8us units the time the
+                                        * ADC was in saturation */
+       __le32 ina_detection_search_time;/* total time (in 0.8us) searched
+                                         * for INA */
+       __le32 beacon_silence_rssi_a;   /* RSSI silence after beacon frame */
+       __le32 beacon_silence_rssi_b;   /* RSSI silence after beacon frame */
+       __le32 beacon_silence_rssi_c;   /* RSSI silence after beacon frame */
+       __le32 interference_data_flag;  /* flag for interference data
+                                        * availability. 1 when data is
+                                        * available. */
+       __le32 channel_load;            /* counts RX Enable time in uSec */
+       __le32 dsp_false_alarms;        /* DSP false alarm (both OFDM
+                                        * and CCK) counter */
+       __le32 beacon_rssi_a;
+       __le32 beacon_rssi_b;
+       __le32 beacon_rssi_c;
+       __le32 beacon_energy_a;
+       __le32 beacon_energy_b;
+       __le32 beacon_energy_c;
+       __le32 num_bt_kills;
+       __le32 mac_id;
+       __le32 directed_data_mpdu;
+} __packed; /* STATISTICS_RX_NON_PHY_API_S_VER_3 */
+
+struct mvm_statistics_rx_phy {
+       __le32 ina_cnt;
+       __le32 fina_cnt;
+       __le32 plcp_err;
+       __le32 crc32_err;
+       __le32 overrun_err;
+       __le32 early_overrun_err;
+       __le32 crc32_good;
+       __le32 false_alarm_cnt;
+       __le32 fina_sync_err_cnt;
+       __le32 sfd_timeout;
+       __le32 fina_timeout;
+       __le32 unresponded_rts;
+       __le32 rxe_frame_lmt_overrun;
+       __le32 sent_ack_cnt;
+       __le32 sent_cts_cnt;
+       __le32 sent_ba_rsp_cnt;
+       __le32 dsp_self_kill;
+       __le32 mh_format_err;
+       __le32 re_acq_main_rssi_sum;
+       __le32 reserved;
+} __packed; /* STATISTICS_RX_PHY_API_S_VER_2 */
+
+struct mvm_statistics_rx_ht_phy {
+       __le32 plcp_err;
+       __le32 overrun_err;
+       __le32 early_overrun_err;
+       __le32 crc32_good;
+       __le32 crc32_err;
+       __le32 mh_format_err;
+       __le32 agg_crc32_good;
+       __le32 agg_mpdu_cnt;
+       __le32 agg_cnt;
+       __le32 unsupport_mcs;
+} __packed;  /* STATISTICS_HT_RX_PHY_API_S_VER_1 */
+
+struct mvm_statistics_tx_non_phy {
+       __le32 preamble_cnt;
+       __le32 rx_detected_cnt;
+       __le32 bt_prio_defer_cnt;
+       __le32 bt_prio_kill_cnt;
+       __le32 few_bytes_cnt;
+       __le32 cts_timeout;
+       __le32 ack_timeout;
+       __le32 expected_ack_cnt;
+       __le32 actual_ack_cnt;
+       __le32 dump_msdu_cnt;
+       __le32 burst_abort_next_frame_mismatch_cnt;
+       __le32 burst_abort_missing_next_frame_cnt;
+       __le32 cts_timeout_collision;
+       __le32 ack_or_ba_timeout_collision;
+} __packed; /* STATISTICS_TX_NON_PHY_API_S_VER_3 */
+
+#define MAX_CHAINS 3
+
+struct mvm_statistics_tx_non_phy_agg {
+       __le32 ba_timeout;
+       __le32 ba_reschedule_frames;
+       __le32 scd_query_agg_frame_cnt;
+       __le32 scd_query_no_agg;
+       __le32 scd_query_agg;
+       __le32 scd_query_mismatch;
+       __le32 frame_not_ready;
+       __le32 underrun;
+       __le32 bt_prio_kill;
+       __le32 rx_ba_rsp_cnt;
+       __s8 txpower[MAX_CHAINS];
+       __s8 reserved;
+       __le32 reserved2;
+} __packed; /* STATISTICS_TX_NON_PHY_AGG_API_S_VER_1 */
+
+struct mvm_statistics_tx_channel_width {
+       __le32 ext_cca_narrow_ch20[1];
+       __le32 ext_cca_narrow_ch40[2];
+       __le32 ext_cca_narrow_ch80[3];
+       __le32 ext_cca_narrow_ch160[4];
+       __le32 last_tx_ch_width_indx;
+       __le32 rx_detected_per_ch_width[4];
+       __le32 success_per_ch_width[4];
+       __le32 fail_per_ch_width[4];
+}; /* STATISTICS_TX_CHANNEL_WIDTH_API_S_VER_1 */
+
+struct mvm_statistics_tx {
+       struct mvm_statistics_tx_non_phy general;
+       struct mvm_statistics_tx_non_phy_agg agg;
+       struct mvm_statistics_tx_channel_width channel_width;
+} __packed; /* STATISTICS_TX_API_S_VER_4 */
+
+
+struct mvm_statistics_bt_activity {
+       __le32 hi_priority_tx_req_cnt;
+       __le32 hi_priority_tx_denied_cnt;
+       __le32 lo_priority_tx_req_cnt;
+       __le32 lo_priority_tx_denied_cnt;
+       __le32 hi_priority_rx_req_cnt;
+       __le32 hi_priority_rx_denied_cnt;
+       __le32 lo_priority_rx_req_cnt;
+       __le32 lo_priority_rx_denied_cnt;
+} __packed;  /* STATISTICS_BT_ACTIVITY_API_S_VER_1 */
+
+struct mvm_statistics_general {
+       __le32 radio_temperature;
+       __le32 radio_voltage;
+       struct mvm_statistics_dbg dbg;
+       __le32 sleep_time;
+       __le32 slots_out;
+       __le32 slots_idle;
+       __le32 ttl_timestamp;
+       struct mvm_statistics_div slow_div;
+       __le32 rx_enable_counter;
+       /*
+        * num_of_sos_states:
+        *  count the number of times we have to re-tune
+        *  in order to get out of bad PHY status
+        */
+       __le32 num_of_sos_states;
+       __le32 beacon_filtered;
+       __le32 missed_beacons;
+       __s8 beacon_filter_average_energy;
+       __s8 beacon_filter_reason;
+       __s8 beacon_filter_current_energy;
+       __s8 beacon_filter_reserved;
+       __le32 beacon_filter_delta_time;
+       struct mvm_statistics_bt_activity bt_activity;
+} __packed; /* STATISTICS_GENERAL_API_S_VER_5 */
+
+struct mvm_statistics_rx {
+       struct mvm_statistics_rx_phy ofdm;
+       struct mvm_statistics_rx_phy cck;
+       struct mvm_statistics_rx_non_phy general;
+       struct mvm_statistics_rx_ht_phy ofdm_ht;
+} __packed; /* STATISTICS_RX_API_S_VER_3 */
+
+/*
+ * STATISTICS_NOTIFICATION = 0x9d (notification only, not a command)
+ *
+ * By default, uCode issues this notification after receiving a beacon
+ * while associated.  To disable this behavior, set DISABLE_NOTIF flag in the
+ * REPLY_STATISTICS_CMD 0x9c, above.
+ *
+ * Statistics counters continue to increment beacon after beacon, but are
+ * cleared when changing channels or when driver issues REPLY_STATISTICS_CMD
+ * 0x9c with CLEAR_STATS bit set (see above).
+ *
+ * uCode also issues this notification during scans.  uCode clears statistics
+ * appropriately so that each notification contains statistics for only the
+ * one channel that has just been scanned.
+ */
+
+struct iwl_notif_statistics {
+       __le32 flag;
+       struct mvm_statistics_rx rx;
+       struct mvm_statistics_tx tx;
+       struct mvm_statistics_general general;
+} __packed; /* STATISTICS_NTFY_API_S_VER_8 */
+
+#endif /* __fw_api_stats_h__ */
index 5bca1f8bfebf3d87177cacdbcc919f221aaee020..81c4ea3c6958440b105c239f755b85a6a36fe73c 100644 (file)
@@ -592,4 +592,43 @@ static inline u32 iwl_mvm_get_scd_ssn(struct iwl_mvm_tx_resp *tx_resp)
                            tx_resp->frame_count) & 0xfff;
 }
 
+/**
+ * struct iwl_scd_txq_cfg_cmd - New txq hw scheduler config command
+ * @token:
+ * @sta_id: station id
+ * @tid:
+ * @scd_queue: scheduler queue to confiug
+ * @enable: 1 queue enable, 0 queue disable
+ * @aggregate: 1 aggregated queue, 0 otherwise
+ * @tx_fifo: %enum iwl_mvm_tx_fifo
+ * @window: BA window size
+ * @ssn: SSN for the BA agreement
+ */
+struct iwl_scd_txq_cfg_cmd {
+       u8 token;
+       u8 sta_id;
+       u8 tid;
+       u8 scd_queue;
+       u8 enable;
+       u8 aggregate;
+       u8 tx_fifo;
+       u8 window;
+       __le16 ssn;
+       __le16 reserved;
+} __packed; /* SCD_QUEUE_CFG_CMD_API_S_VER_1 */
+
+/**
+ * struct iwl_scd_txq_cfg_rsp
+ * @token: taken from the command
+ * @sta_id: station id from the command
+ * @tid: tid from the command
+ * @scd_queue: scd_queue from the command
+ */
+struct iwl_scd_txq_cfg_rsp {
+       u8 token;
+       u8 sta_id;
+       u8 tid;
+       u8 scd_queue;
+} __packed; /* SCD_QUEUE_CFG_RSP_API_S_VER_1 */
+
 #endif /* __fw_api_tx_h__ */
index 88af6dd2ceaa4034e7dd167fad32fbb22fcc2fed..b56154fe8ec59cbb1db6b65aea1867e16f8504f9 100644 (file)
@@ -74,6 +74,7 @@
 #include "fw-api-d3.h"
 #include "fw-api-coex.h"
 #include "fw-api-scan.h"
+#include "fw-api-stats.h"
 
 /* Tx queue numbers */
 enum {
@@ -128,6 +129,9 @@ enum {
        /* global key */
        WEP_KEY = 0x20,
 
+       /* Memory */
+       SHARED_MEM_CFG = 0x25,
+
        /* TDLS */
        TDLS_CHANNEL_SWITCH_CMD = 0x27,
        TDLS_CHANNEL_SWITCH_NOTIFICATION = 0xaa,
@@ -1381,214 +1385,6 @@ struct iwl_mvm_marker {
        __le32 metadata[0];
 } __packed; /* MARKER_API_S_VER_1 */
 
-struct mvm_statistics_dbg {
-       __le32 burst_check;
-       __le32 burst_count;
-       __le32 wait_for_silence_timeout_cnt;
-       __le32 reserved[3];
-} __packed; /* STATISTICS_DEBUG_API_S_VER_2 */
-
-struct mvm_statistics_div {
-       __le32 tx_on_a;
-       __le32 tx_on_b;
-       __le32 exec_time;
-       __le32 probe_time;
-       __le32 rssi_ant;
-       __le32 reserved2;
-} __packed; /* STATISTICS_SLOW_DIV_API_S_VER_2 */
-
-struct mvm_statistics_general_common {
-       __le32 temperature;   /* radio temperature */
-       __le32 temperature_m; /* radio voltage */
-       struct mvm_statistics_dbg dbg;
-       __le32 sleep_time;
-       __le32 slots_out;
-       __le32 slots_idle;
-       __le32 ttl_timestamp;
-       struct mvm_statistics_div div;
-       __le32 rx_enable_counter;
-       /*
-        * num_of_sos_states:
-        *  count the number of times we have to re-tune
-        *  in order to get out of bad PHY status
-        */
-       __le32 num_of_sos_states;
-} __packed; /* STATISTICS_GENERAL_API_S_VER_5 */
-
-struct mvm_statistics_rx_non_phy {
-       __le32 bogus_cts;       /* CTS received when not expecting CTS */
-       __le32 bogus_ack;       /* ACK received when not expecting ACK */
-       __le32 non_bssid_frames;        /* number of frames with BSSID that
-                                        * doesn't belong to the STA BSSID */
-       __le32 filtered_frames; /* count frames that were dumped in the
-                                * filtering process */
-       __le32 non_channel_beacons;     /* beacons with our bss id but not on
-                                        * our serving channel */
-       __le32 channel_beacons; /* beacons with our bss id and in our
-                                * serving channel */
-       __le32 num_missed_bcon; /* number of missed beacons */
-       __le32 adc_rx_saturation_time;  /* count in 0.8us units the time the
-                                        * ADC was in saturation */
-       __le32 ina_detection_search_time;/* total time (in 0.8us) searched
-                                         * for INA */
-       __le32 beacon_silence_rssi_a;   /* RSSI silence after beacon frame */
-       __le32 beacon_silence_rssi_b;   /* RSSI silence after beacon frame */
-       __le32 beacon_silence_rssi_c;   /* RSSI silence after beacon frame */
-       __le32 interference_data_flag;  /* flag for interference data
-                                        * availability. 1 when data is
-                                        * available. */
-       __le32 channel_load;            /* counts RX Enable time in uSec */
-       __le32 dsp_false_alarms;        /* DSP false alarm (both OFDM
-                                        * and CCK) counter */
-       __le32 beacon_rssi_a;
-       __le32 beacon_rssi_b;
-       __le32 beacon_rssi_c;
-       __le32 beacon_energy_a;
-       __le32 beacon_energy_b;
-       __le32 beacon_energy_c;
-       __le32 num_bt_kills;
-       __le32 mac_id;
-       __le32 directed_data_mpdu;
-} __packed; /* STATISTICS_RX_NON_PHY_API_S_VER_3 */
-
-struct mvm_statistics_rx_phy {
-       __le32 ina_cnt;
-       __le32 fina_cnt;
-       __le32 plcp_err;
-       __le32 crc32_err;
-       __le32 overrun_err;
-       __le32 early_overrun_err;
-       __le32 crc32_good;
-       __le32 false_alarm_cnt;
-       __le32 fina_sync_err_cnt;
-       __le32 sfd_timeout;
-       __le32 fina_timeout;
-       __le32 unresponded_rts;
-       __le32 rxe_frame_limit_overrun;
-       __le32 sent_ack_cnt;
-       __le32 sent_cts_cnt;
-       __le32 sent_ba_rsp_cnt;
-       __le32 dsp_self_kill;
-       __le32 mh_format_err;
-       __le32 re_acq_main_rssi_sum;
-       __le32 reserved;
-} __packed; /* STATISTICS_RX_PHY_API_S_VER_2 */
-
-struct mvm_statistics_rx_ht_phy {
-       __le32 plcp_err;
-       __le32 overrun_err;
-       __le32 early_overrun_err;
-       __le32 crc32_good;
-       __le32 crc32_err;
-       __le32 mh_format_err;
-       __le32 agg_crc32_good;
-       __le32 agg_mpdu_cnt;
-       __le32 agg_cnt;
-       __le32 unsupport_mcs;
-} __packed;  /* STATISTICS_HT_RX_PHY_API_S_VER_1 */
-
-#define MAX_CHAINS 3
-
-struct mvm_statistics_tx_non_phy_agg {
-       __le32 ba_timeout;
-       __le32 ba_reschedule_frames;
-       __le32 scd_query_agg_frame_cnt;
-       __le32 scd_query_no_agg;
-       __le32 scd_query_agg;
-       __le32 scd_query_mismatch;
-       __le32 frame_not_ready;
-       __le32 underrun;
-       __le32 bt_prio_kill;
-       __le32 rx_ba_rsp_cnt;
-       __s8 txpower[MAX_CHAINS];
-       __s8 reserved;
-       __le32 reserved2;
-} __packed; /* STATISTICS_TX_NON_PHY_AGG_API_S_VER_1 */
-
-struct mvm_statistics_tx_channel_width {
-       __le32 ext_cca_narrow_ch20[1];
-       __le32 ext_cca_narrow_ch40[2];
-       __le32 ext_cca_narrow_ch80[3];
-       __le32 ext_cca_narrow_ch160[4];
-       __le32 last_tx_ch_width_indx;
-       __le32 rx_detected_per_ch_width[4];
-       __le32 success_per_ch_width[4];
-       __le32 fail_per_ch_width[4];
-}; /* STATISTICS_TX_CHANNEL_WIDTH_API_S_VER_1 */
-
-struct mvm_statistics_tx {
-       __le32 preamble_cnt;
-       __le32 rx_detected_cnt;
-       __le32 bt_prio_defer_cnt;
-       __le32 bt_prio_kill_cnt;
-       __le32 few_bytes_cnt;
-       __le32 cts_timeout;
-       __le32 ack_timeout;
-       __le32 expected_ack_cnt;
-       __le32 actual_ack_cnt;
-       __le32 dump_msdu_cnt;
-       __le32 burst_abort_next_frame_mismatch_cnt;
-       __le32 burst_abort_missing_next_frame_cnt;
-       __le32 cts_timeout_collision;
-       __le32 ack_or_ba_timeout_collision;
-       struct mvm_statistics_tx_non_phy_agg agg;
-       struct mvm_statistics_tx_channel_width channel_width;
-} __packed; /* STATISTICS_TX_API_S_VER_4 */
-
-
-struct mvm_statistics_bt_activity {
-       __le32 hi_priority_tx_req_cnt;
-       __le32 hi_priority_tx_denied_cnt;
-       __le32 lo_priority_tx_req_cnt;
-       __le32 lo_priority_tx_denied_cnt;
-       __le32 hi_priority_rx_req_cnt;
-       __le32 hi_priority_rx_denied_cnt;
-       __le32 lo_priority_rx_req_cnt;
-       __le32 lo_priority_rx_denied_cnt;
-} __packed;  /* STATISTICS_BT_ACTIVITY_API_S_VER_1 */
-
-struct mvm_statistics_general {
-       struct mvm_statistics_general_common common;
-       __le32 beacon_filtered;
-       __le32 missed_beacons;
-       __s8 beacon_filter_average_energy;
-       __s8 beacon_filter_reason;
-       __s8 beacon_filter_current_energy;
-       __s8 beacon_filter_reserved;
-       __le32 beacon_filter_delta_time;
-       struct mvm_statistics_bt_activity bt_activity;
-} __packed; /* STATISTICS_GENERAL_API_S_VER_5 */
-
-struct mvm_statistics_rx {
-       struct mvm_statistics_rx_phy ofdm;
-       struct mvm_statistics_rx_phy cck;
-       struct mvm_statistics_rx_non_phy general;
-       struct mvm_statistics_rx_ht_phy ofdm_ht;
-} __packed; /* STATISTICS_RX_API_S_VER_3 */
-
-/*
- * STATISTICS_NOTIFICATION = 0x9d (notification only, not a command)
- *
- * By default, uCode issues this notification after receiving a beacon
- * while associated.  To disable this behavior, set DISABLE_NOTIF flag in the
- * REPLY_STATISTICS_CMD 0x9c, above.
- *
- * Statistics counters continue to increment beacon after beacon, but are
- * cleared when changing channels or when driver issues REPLY_STATISTICS_CMD
- * 0x9c with CLEAR_STATS bit set (see above).
- *
- * uCode also issues this notification during scans.  uCode clears statistics
- * appropriately so that each notification contains statistics for only the
- * one channel that has just been scanned.
- */
-
-struct iwl_notif_statistics { /* STATISTICS_NTFY_API_S_VER_8 */
-       __le32 flag;
-       struct mvm_statistics_rx rx;
-       struct mvm_statistics_tx tx;
-       struct mvm_statistics_general general;
-} __packed;
-
 /***********************************
  * Smart Fifo API
  ***********************************/
@@ -1680,63 +1476,6 @@ struct iwl_dts_measurement_notif {
        __le32 voltage;
 } __packed; /* TEMPERATURE_MEASUREMENT_TRIGGER_NTFY_S */
 
-/**
- * enum iwl_scd_control - scheduler config command control flags
- * @IWL_SCD_CONTROL_RM_TID: remove TID from this queue
- * @IWL_SCD_CONTROL_SET_SSN: use the SSN and program it into HW
- */
-enum iwl_scd_control {
-       IWL_SCD_CONTROL_RM_TID  = BIT(4),
-       IWL_SCD_CONTROL_SET_SSN = BIT(5),
-};
-
-/**
- * enum iwl_scd_flags - scheduler config command flags
- * @IWL_SCD_FLAGS_SHARE_TID: multiple TIDs map to this queue
- * @IWL_SCD_FLAGS_SHARE_RA: multiple RAs map to this queue
- * @IWL_SCD_FLAGS_DQA_ENABLED: DQA is enabled
- */
-enum iwl_scd_flags {
-       IWL_SCD_FLAGS_SHARE_TID         = BIT(0),
-       IWL_SCD_FLAGS_SHARE_RA          = BIT(1),
-       IWL_SCD_FLAGS_DQA_ENABLED       = BIT(2),
-};
-
-#define IWL_SCDQ_INVALID_STA   0xff
-
-/**
- * struct iwl_scd_txq_cfg_cmd - New txq hw scheduler config command
- * @token:     dialog token addba - unused legacy
- * @sta_id:    station id 4-bit
- * @tid:       TID 0..7
- * @scd_queue: TFD queue num 0 .. 31
- * @enable:    1 queue enable, 0 queue disable
- * @aggregate: 1 aggregated queue, 0 otherwise
- * @tx_fifo:   tx fifo num 0..7
- * @window:    up to 64
- * @ssn:       starting seq num 12-bit
- * @control:   command control flags
- * @flags:     flags - see &enum iwl_scd_flags
- *
- * Note that every time the command is sent, all parameters must
- * be filled with the exception of
- *  - the SSN, which is only used with @IWL_SCD_CONTROL_SET_SSN
- *  - the window, which is only relevant when starting aggregation
- */
-struct iwl_scd_txq_cfg_cmd {
-       u8 token;
-       u8 sta_id;
-       u8 tid;
-       u8 scd_queue;
-       u8 enable;
-       u8 aggregate;
-       u8 tx_fifo;
-       u8 window;
-       __le16 ssn;
-       u8 control;
-       u8 flags;
-} __packed;
-
 /***********************************
  * TDLS API
  ***********************************/
@@ -1878,4 +1617,36 @@ struct iwl_tdls_config_res {
        struct iwl_tdls_config_sta_info_res sta_info[IWL_MVM_TDLS_STA_COUNT];
 } __packed; /* TDLS_CONFIG_RSP_API_S_VER_1 */
 
+#define TX_FIFO_MAX_NUM                8
+#define RX_FIFO_MAX_NUM                2
+
+/**
+ * Shared memory configuration information from the FW
+ *
+ * @shared_mem_addr: shared memory addr (pre 8000 HW set to 0x0 as MARBH is not
+ *     accessible)
+ * @shared_mem_size: shared memory size
+ * @sample_buff_addr: internal sample (mon/adc) buff addr (pre 8000 HW set to
+ *     0x0 as accessible only via DBGM RDAT)
+ * @sample_buff_size: internal sample buff size
+ * @txfifo_addr: start addr of TXF0 (excluding the context table 0.5KB), (pre
+ *     8000 HW set to 0x0 as not accessible)
+ * @txfifo_size: size of TXF0 ... TXF7
+ * @rxfifo_size: RXF1, RXF2 sizes. If there is no RXF2, it'll have a value of 0
+ * @page_buff_addr: used by UMAC and performance debug (page miss analysis),
+ *     when paging is not supported this should be 0
+ * @page_buff_size: size of %page_buff_addr
+ */
+struct iwl_shared_mem_cfg {
+       __le32 shared_mem_addr;
+       __le32 shared_mem_size;
+       __le32 sample_buff_addr;
+       __le32 sample_buff_size;
+       __le32 txfifo_addr;
+       __le32 txfifo_size[TX_FIFO_MAX_NUM];
+       __le32 rxfifo_size[RX_FIFO_MAX_NUM];
+       __le32 page_buff_addr;
+       __le32 page_buff_size;
+} __packed; /* SHARED_MEM_ALLOC_API_S_VER_1 */
+
 #endif /* __fw_api_h__ */
index 534ee3123a63fef57318aae3c374b308fc73715c..a322a5e3d31b8e5e4323f98fc6c24d16074dfb97 100644 (file)
@@ -400,10 +400,59 @@ out:
        return ret;
 }
 
-void iwl_mvm_fw_dbg_collect(struct iwl_mvm *mvm)
+static void iwl_mvm_get_shared_mem_conf(struct iwl_mvm *mvm)
 {
+       struct iwl_host_cmd cmd = {
+               .id = SHARED_MEM_CFG,
+               .flags = CMD_WANT_SKB,
+               .data = { NULL, },
+               .len = { 0, },
+       };
+       struct iwl_rx_packet *pkt;
+       struct iwl_shared_mem_cfg *mem_cfg;
+       u32 i;
+
        lockdep_assert_held(&mvm->mutex);
 
+       if (WARN_ON(iwl_mvm_send_cmd(mvm, &cmd)))
+               return;
+
+       pkt = cmd.resp_pkt;
+       if (pkt->hdr.flags & IWL_CMD_FAILED_MSK) {
+               IWL_ERR(mvm, "Bad return from SHARED_MEM_CFG (0x%08X)\n",
+                       pkt->hdr.flags);
+               goto exit;
+       }
+
+       mem_cfg = (void *)pkt->data;
+
+       mvm->shared_mem_cfg.shared_mem_addr =
+               le32_to_cpu(mem_cfg->shared_mem_addr);
+       mvm->shared_mem_cfg.shared_mem_size =
+               le32_to_cpu(mem_cfg->shared_mem_size);
+       mvm->shared_mem_cfg.sample_buff_addr =
+               le32_to_cpu(mem_cfg->sample_buff_addr);
+       mvm->shared_mem_cfg.sample_buff_size =
+               le32_to_cpu(mem_cfg->sample_buff_size);
+       mvm->shared_mem_cfg.txfifo_addr = le32_to_cpu(mem_cfg->txfifo_addr);
+       for (i = 0; i < ARRAY_SIZE(mvm->shared_mem_cfg.txfifo_size); i++)
+               mvm->shared_mem_cfg.txfifo_size[i] =
+                       le32_to_cpu(mem_cfg->txfifo_size[i]);
+       for (i = 0; i < ARRAY_SIZE(mvm->shared_mem_cfg.rxfifo_size); i++)
+               mvm->shared_mem_cfg.rxfifo_size[i] =
+                       le32_to_cpu(mem_cfg->rxfifo_size[i]);
+       mvm->shared_mem_cfg.page_buff_addr =
+               le32_to_cpu(mem_cfg->page_buff_addr);
+       mvm->shared_mem_cfg.page_buff_size =
+               le32_to_cpu(mem_cfg->page_buff_size);
+       IWL_DEBUG_INFO(mvm, "SHARED MEM CFG: got memory offsets/sizes\n");
+
+exit:
+       iwl_free_resp(&cmd);
+}
+
+void iwl_mvm_fw_dbg_collect(struct iwl_mvm *mvm)
+{
        /* stop recording */
        if (mvm->cfg->device_family == IWL_DEVICE_FAMILY_7000) {
                iwl_set_bits_prph(mvm->trans, MON_BUFF_SAMPLE_CTL, 0x100);
@@ -412,11 +461,7 @@ void iwl_mvm_fw_dbg_collect(struct iwl_mvm *mvm)
                iwl_write_prph(mvm->trans, DBGC_OUT_CTRL, 0);
        }
 
-       iwl_mvm_fw_error_dump(mvm);
-
-       /* start recording again */
-       WARN_ON_ONCE(mvm->fw->dbg_dest_tlv &&
-                    iwl_mvm_start_fw_dbg_conf(mvm, mvm->fw_dbg_conf));
+       schedule_work(&mvm->fw_error_dump_wk);
 }
 
 int iwl_mvm_start_fw_dbg_conf(struct iwl_mvm *mvm, enum iwl_fw_dbg_conf conf_id)
@@ -454,6 +499,35 @@ int iwl_mvm_start_fw_dbg_conf(struct iwl_mvm *mvm, enum iwl_fw_dbg_conf conf_id)
        return ret;
 }
 
+static int iwl_mvm_config_ltr_v1(struct iwl_mvm *mvm)
+{
+       struct iwl_ltr_config_cmd_v1 cmd_v1 = {
+               .flags = cpu_to_le32(LTR_CFG_FLAG_FEATURE_ENABLE),
+       };
+
+       if (!mvm->trans->ltr_enabled)
+               return 0;
+
+       return iwl_mvm_send_cmd_pdu(mvm, LTR_CONFIG, 0,
+                                   sizeof(cmd_v1), &cmd_v1);
+}
+
+static int iwl_mvm_config_ltr(struct iwl_mvm *mvm)
+{
+       struct iwl_ltr_config_cmd cmd = {
+               .flags = cpu_to_le32(LTR_CFG_FLAG_FEATURE_ENABLE),
+       };
+
+       if (!mvm->trans->ltr_enabled)
+               return 0;
+
+       if (!(mvm->fw->ucode_capa.api[0] & IWL_UCODE_TLV_API_HDC_PHASE_0))
+               return iwl_mvm_config_ltr_v1(mvm);
+
+       return iwl_mvm_send_cmd_pdu(mvm, LTR_CONFIG, 0,
+                                   sizeof(cmd), &cmd);
+}
+
 int iwl_mvm_up(struct iwl_mvm *mvm)
 {
        int ret, i;
@@ -501,6 +575,8 @@ int iwl_mvm_up(struct iwl_mvm *mvm)
                goto error;
        }
 
+       iwl_mvm_get_shared_mem_conf(mvm);
+
        ret = iwl_mvm_sf_update(mvm, NULL, false);
        if (ret)
                IWL_ERR(mvm, "Failed to initialize Smart Fifo\n");
@@ -557,14 +633,7 @@ int iwl_mvm_up(struct iwl_mvm *mvm)
        /* Initialize tx backoffs to the minimal possible */
        iwl_mvm_tt_tx_backoff(mvm, 0);
 
-       if (mvm->trans->ltr_enabled) {
-               struct iwl_ltr_config_cmd cmd = {
-                       .flags = cpu_to_le32(LTR_CFG_FLAG_FEATURE_ENABLE),
-               };
-
-               WARN_ON(iwl_mvm_send_cmd_pdu(mvm, LTR_CONFIG, 0,
-                                            sizeof(cmd), &cmd));
-       }
+       WARN_ON(iwl_mvm_config_ltr(mvm));
 
        ret = iwl_mvm_power_update_device(mvm);
        if (ret)
index 7196b4d6b7ccee1f979558c6047289b552c8710a..8bf78fa8ace00c6d5d4e98aabd193cb977fc1153 100644 (file)
@@ -208,8 +208,10 @@ u32 iwl_mvm_mac_get_queues_mask(struct ieee80211_vif *vif)
        if (vif->type == NL80211_IFTYPE_P2P_DEVICE)
                return BIT(IWL_MVM_OFFCHANNEL_QUEUE);
 
-       for (ac = 0; ac < IEEE80211_NUM_ACS; ac++)
-               qmask |= BIT(vif->hw_queue[ac]);
+       for (ac = 0; ac < IEEE80211_NUM_ACS; ac++) {
+               if (vif->hw_queue[ac] != IEEE80211_INVAL_HW_QUEUE)
+                       qmask |= BIT(vif->hw_queue[ac]);
+       }
 
        if (vif->type == NL80211_IFTYPE_AP)
                qmask |= BIT(vif->cab_queue);
@@ -496,14 +498,14 @@ void iwl_mvm_mac_ctxt_release(struct iwl_mvm *mvm, struct ieee80211_vif *vif)
 
        switch (vif->type) {
        case NL80211_IFTYPE_P2P_DEVICE:
-               iwl_mvm_disable_txq(mvm, IWL_MVM_OFFCHANNEL_QUEUE);
+               iwl_mvm_disable_txq(mvm, IWL_MVM_OFFCHANNEL_QUEUE, 0);
                break;
        case NL80211_IFTYPE_AP:
-               iwl_mvm_disable_txq(mvm, vif->cab_queue);
+               iwl_mvm_disable_txq(mvm, vif->cab_queue, 0);
                /* fall through */
        default:
                for (ac = 0; ac < IEEE80211_NUM_ACS; ac++)
-                       iwl_mvm_disable_txq(mvm, vif->hw_queue[ac]);
+                       iwl_mvm_disable_txq(mvm, vif->hw_queue[ac], 0);
        }
 }
 
index aa1ee04b151405ae4410bcc63ee231c748fd731b..cef6f3373542646e13fa178500c98c7ff5f5e606 100644 (file)
@@ -761,6 +761,132 @@ static void iwl_mvm_free_coredump(const void *data)
        kfree(fw_error_dump);
 }
 
+static void iwl_mvm_dump_fifos(struct iwl_mvm *mvm,
+                              struct iwl_fw_error_dump_data **dump_data)
+{
+       struct iwl_fw_error_dump_fifo *fifo_hdr;
+       u32 *fifo_data;
+       u32 fifo_len;
+       unsigned long flags;
+       int i, j;
+
+       if (!iwl_trans_grab_nic_access(mvm->trans, false, &flags))
+               return;
+
+       /* Pull RXF data from all RXFs */
+       for (i = 0; i < ARRAY_SIZE(mvm->shared_mem_cfg.rxfifo_size); i++) {
+               /*
+                * Keep aside the additional offset that might be needed for
+                * next RXF
+                */
+               u32 offset_diff = RXF_DIFF_FROM_PREV * i;
+
+               fifo_hdr = (void *)(*dump_data)->data;
+               fifo_data = (void *)fifo_hdr->data;
+               fifo_len = mvm->shared_mem_cfg.rxfifo_size[i];
+
+               /* No need to try to read the data if the length is 0 */
+               if (fifo_len == 0)
+                       continue;
+
+               /* Add a TLV for the RXF */
+               (*dump_data)->type = cpu_to_le32(IWL_FW_ERROR_DUMP_RXF);
+               (*dump_data)->len = cpu_to_le32(fifo_len + sizeof(*fifo_hdr));
+
+               fifo_hdr->fifo_num = cpu_to_le32(i);
+               fifo_hdr->available_bytes =
+                       cpu_to_le32(iwl_trans_read_prph(mvm->trans,
+                                                       RXF_RD_D_SPACE +
+                                                       offset_diff));
+               fifo_hdr->wr_ptr =
+                       cpu_to_le32(iwl_trans_read_prph(mvm->trans,
+                                                       RXF_RD_WR_PTR +
+                                                       offset_diff));
+               fifo_hdr->rd_ptr =
+                       cpu_to_le32(iwl_trans_read_prph(mvm->trans,
+                                                       RXF_RD_RD_PTR +
+                                                       offset_diff));
+               fifo_hdr->fence_ptr =
+                       cpu_to_le32(iwl_trans_read_prph(mvm->trans,
+                                                       RXF_RD_FENCE_PTR +
+                                                       offset_diff));
+               fifo_hdr->fence_mode =
+                       cpu_to_le32(iwl_trans_read_prph(mvm->trans,
+                                                       RXF_SET_FENCE_MODE +
+                                                       offset_diff));
+
+               /* Lock fence */
+               iwl_trans_write_prph(mvm->trans,
+                                    RXF_SET_FENCE_MODE + offset_diff, 0x1);
+               /* Set fence pointer to the same place like WR pointer */
+               iwl_trans_write_prph(mvm->trans,
+                                    RXF_LD_WR2FENCE + offset_diff, 0x1);
+               /* Set fence offset */
+               iwl_trans_write_prph(mvm->trans,
+                                    RXF_LD_FENCE_OFFSET_ADDR + offset_diff,
+                                    0x0);
+
+               /* Read FIFO */
+               fifo_len /= sizeof(u32); /* Size in DWORDS */
+               for (j = 0; j < fifo_len; j++)
+                       fifo_data[j] = iwl_trans_read_prph(mvm->trans,
+                                                        RXF_FIFO_RD_FENCE_INC +
+                                                        offset_diff);
+               *dump_data = iwl_fw_error_next_data(*dump_data);
+       }
+
+       /* Pull TXF data from all TXFs */
+       for (i = 0; i < ARRAY_SIZE(mvm->shared_mem_cfg.txfifo_size); i++) {
+               /* Mark the number of TXF we're pulling now */
+               iwl_trans_write_prph(mvm->trans, TXF_LARC_NUM, i);
+
+               fifo_hdr = (void *)(*dump_data)->data;
+               fifo_data = (void *)fifo_hdr->data;
+               fifo_len = mvm->shared_mem_cfg.txfifo_size[i];
+
+               /* No need to try to read the data if the length is 0 */
+               if (fifo_len == 0)
+                       continue;
+
+               /* Add a TLV for the FIFO */
+               (*dump_data)->type = cpu_to_le32(IWL_FW_ERROR_DUMP_TXF);
+               (*dump_data)->len = cpu_to_le32(fifo_len + sizeof(*fifo_hdr));
+
+               fifo_hdr->fifo_num = cpu_to_le32(i);
+               fifo_hdr->available_bytes =
+                       cpu_to_le32(iwl_trans_read_prph(mvm->trans,
+                                                       TXF_FIFO_ITEM_CNT));
+               fifo_hdr->wr_ptr =
+                       cpu_to_le32(iwl_trans_read_prph(mvm->trans,
+                                                       TXF_WR_PTR));
+               fifo_hdr->rd_ptr =
+                       cpu_to_le32(iwl_trans_read_prph(mvm->trans,
+                                                       TXF_RD_PTR));
+               fifo_hdr->fence_ptr =
+                       cpu_to_le32(iwl_trans_read_prph(mvm->trans,
+                                                       TXF_FENCE_PTR));
+               fifo_hdr->fence_mode =
+                       cpu_to_le32(iwl_trans_read_prph(mvm->trans,
+                                                       TXF_LOCK_FENCE));
+
+               /* Set the TXF_READ_MODIFY_ADDR to TXF_WR_PTR */
+               iwl_trans_write_prph(mvm->trans, TXF_READ_MODIFY_ADDR,
+                                    TXF_WR_PTR);
+
+               /* Dummy-read to advance the read pointer to the head */
+               iwl_trans_read_prph(mvm->trans, TXF_READ_MODIFY_DATA);
+
+               /* Read FIFO */
+               fifo_len /= sizeof(u32); /* Size in DWORDS */
+               for (j = 0; j < fifo_len; j++)
+                       fifo_data[j] = iwl_trans_read_prph(mvm->trans,
+                                                         TXF_READ_MODIFY_DATA);
+               *dump_data = iwl_fw_error_next_data(*dump_data);
+       }
+
+       iwl_trans_release_nic_access(mvm->trans, &flags);
+}
+
 void iwl_mvm_fw_error_dump(struct iwl_mvm *mvm)
 {
        struct iwl_fw_error_dump_file *dump_file;
@@ -769,18 +895,21 @@ void iwl_mvm_fw_error_dump(struct iwl_mvm *mvm)
        struct iwl_fw_error_dump_mem *dump_mem;
        struct iwl_mvm_dump_ptrs *fw_error_dump;
        u32 sram_len, sram_ofs;
-       u32 file_len, rxf_len;
-       unsigned long flags;
-       int reg_val;
+       u32 file_len, fifo_data_len = 0;
        u32 smem_len = mvm->cfg->smem_len;
+       u32 sram2_len = mvm->cfg->dccm2_len;
 
        lockdep_assert_held(&mvm->mutex);
 
        /* W/A for 8000 HW family A-step */
-       if (mvm->cfg->smem_len &&
-           mvm->cfg->device_family == IWL_DEVICE_FAMILY_8000 &&
-           CSR_HW_REV_STEP(mvm->trans->hw_rev) == SILICON_A_STEP)
-               smem_len = 0x38000;
+       if (mvm->cfg->device_family == IWL_DEVICE_FAMILY_8000 &&
+           CSR_HW_REV_STEP(mvm->trans->hw_rev) == SILICON_A_STEP) {
+               if (smem_len)
+                       smem_len = 0x38000;
+
+               if (sram2_len)
+                       sram2_len = 0x10000;
+       }
 
        fw_error_dump = kzalloc(sizeof(*fw_error_dump), GFP_KERNEL);
        if (!fw_error_dump)
@@ -798,23 +927,49 @@ void iwl_mvm_fw_error_dump(struct iwl_mvm *mvm)
                sram_len = mvm->cfg->dccm_len;
        }
 
-       /* reading buffer size */
-       reg_val = iwl_trans_read_prph(mvm->trans, RXF_SIZE_ADDR);
-       rxf_len = (reg_val & RXF_SIZE_BYTE_CNT_MSK) >> RXF_SIZE_BYTE_CND_POS;
+       /* reading RXF/TXF sizes */
+       if (test_bit(STATUS_FW_ERROR, &mvm->trans->status)) {
+               struct iwl_mvm_shared_mem_cfg *mem_cfg = &mvm->shared_mem_cfg;
+               int i;
+
+               fifo_data_len = 0;
+
+               /* Count RXF size */
+               for (i = 0; i < ARRAY_SIZE(mem_cfg->rxfifo_size); i++) {
+                       if (!mem_cfg->rxfifo_size[i])
+                               continue;
 
-       /* the register holds the value divided by 128 */
-       rxf_len = rxf_len << 7;
+                       /* Add header info */
+                       fifo_data_len += mem_cfg->rxfifo_size[i] +
+                                        sizeof(*dump_data) +
+                                        sizeof(struct iwl_fw_error_dump_fifo);
+               }
+
+               for (i = 0; i < ARRAY_SIZE(mem_cfg->txfifo_size); i++) {
+                       if (!mem_cfg->txfifo_size[i])
+                               continue;
+
+                       /* Add header info */
+                       fifo_data_len += mem_cfg->txfifo_size[i] +
+                                        sizeof(*dump_data) +
+                                        sizeof(struct iwl_fw_error_dump_fifo);
+               }
+       }
 
        file_len = sizeof(*dump_file) +
-                  sizeof(*dump_data) * 3 +
+                  sizeof(*dump_data) * 2 +
                   sram_len + sizeof(*dump_mem) +
-                  rxf_len +
+                  fifo_data_len +
                   sizeof(*dump_info);
 
        /* Make room for the SMEM, if it exists */
        if (smem_len)
                file_len += sizeof(*dump_data) + sizeof(*dump_mem) + smem_len;
 
+       /* Make room for the secondary SRAM, if it exists */
+       if (sram2_len)
+               file_len += sizeof(*dump_data) + sizeof(*dump_mem) + sram2_len;
+
        dump_file = vzalloc(file_len);
        if (!dump_file) {
                kfree(fw_error_dump);
@@ -842,24 +997,10 @@ void iwl_mvm_fw_error_dump(struct iwl_mvm *mvm)
                sizeof(dump_info->bus_human_readable));
 
        dump_data = iwl_fw_error_next_data(dump_data);
-       dump_data->type = cpu_to_le32(IWL_FW_ERROR_DUMP_RXF);
-       dump_data->len = cpu_to_le32(rxf_len);
-
-       if (iwl_trans_grab_nic_access(mvm->trans, false, &flags)) {
-               u32 *rxf = (void *)dump_data->data;
-               int i;
-
-               for (i = 0; i < (rxf_len / sizeof(u32)); i++) {
-                       iwl_trans_write_prph(mvm->trans,
-                                            RXF_LD_FENCE_OFFSET_ADDR,
-                                            i * sizeof(u32));
-                       rxf[i] = iwl_trans_read_prph(mvm->trans,
-                                                    RXF_FIFO_RD_FENCE_ADDR);
-               }
-               iwl_trans_release_nic_access(mvm->trans, &flags);
-       }
+       /* We only dump the FIFOs if the FW is in error state */
+       if (test_bit(STATUS_FW_ERROR, &mvm->trans->status))
+               iwl_mvm_dump_fifos(mvm, &dump_data);
 
-       dump_data = iwl_fw_error_next_data(dump_data);
        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;
@@ -879,6 +1020,17 @@ void iwl_mvm_fw_error_dump(struct iwl_mvm *mvm)
                                         dump_mem->data, smem_len);
        }
 
+       if (sram2_len) {
+               dump_data = iwl_fw_error_next_data(dump_data);
+               dump_data->type = cpu_to_le32(IWL_FW_ERROR_DUMP_MEM);
+               dump_data->len = cpu_to_le32(sram2_len + sizeof(*dump_mem));
+               dump_mem = (void *)dump_data->data;
+               dump_mem->type = cpu_to_le32(IWL_FW_ERROR_DUMP_MEM_SRAM);
+               dump_mem->offset = cpu_to_le32(mvm->cfg->dccm2_offset);
+               iwl_trans_read_mem_bytes(mvm->trans, mvm->cfg->dccm2_offset,
+                                        dump_mem->data, sram2_len);
+       }
+
        fw_error_dump->trans_ptr = iwl_trans_dump_data(mvm->trans);
        fw_error_dump->op_mode_len = file_len;
        if (fw_error_dump->trans_ptr)
@@ -1213,10 +1365,6 @@ static int iwl_mvm_mac_add_interface(struct ieee80211_hw *hw,
                mvm->bf_allowed_vif = mvmvif;
                vif->driver_flags |= IEEE80211_VIF_BEACON_FILTER |
                                     IEEE80211_VIF_SUPPORTS_CQM_RSSI;
-               if (mvm->fw->ucode_capa.flags &
-                                       IWL_UCODE_TLV_FLAGS_UAPSD_SUPPORT &&
-                   !iwlwifi_mod_params.uapsd_disable)
-                       vif->driver_flags |= IEEE80211_VIF_SUPPORTS_UAPSD;
        }
 
        /*
@@ -2164,6 +2312,20 @@ static void iwl_mvm_sta_pre_rcu_remove(struct ieee80211_hw *hw,
        mutex_unlock(&mvm->mutex);
 }
 
+static void iwl_mvm_check_uapsd(struct iwl_mvm *mvm, struct ieee80211_vif *vif,
+                               const u8 *bssid)
+{
+       if (!(mvm->fw->ucode_capa.flags & IWL_UCODE_TLV_FLAGS_UAPSD_SUPPORT))
+               return;
+
+       if (iwlwifi_mod_params.uapsd_disable) {
+               vif->driver_flags &= ~IEEE80211_VIF_SUPPORTS_UAPSD;
+               return;
+       }
+
+       vif->driver_flags |= IEEE80211_VIF_SUPPORTS_UAPSD;
+}
+
 static int iwl_mvm_mac_sta_state(struct ieee80211_hw *hw,
                                 struct ieee80211_vif *vif,
                                 struct ieee80211_sta *sta,
@@ -2223,6 +2385,7 @@ static int iwl_mvm_mac_sta_state(struct ieee80211_hw *hw,
                 * Reset EBS status here assuming environment has been changed.
                 */
                mvm->last_ebs_successful = true;
+               iwl_mvm_check_uapsd(mvm, vif, sta->addr);
                ret = 0;
        } else if (old_state == IEEE80211_STA_AUTH &&
                   new_state == IEEE80211_STA_ASSOC) {
index b2100b4140553e2625125f70be383a1b28d5bc97..979ac23522f2f44c312b37c6979535a1cb5dd799 100644 (file)
@@ -276,6 +276,7 @@ enum iwl_mvm_ref_type {
        IWL_MVM_REF_TM_CMD,
        IWL_MVM_REF_EXIT_WORK,
        IWL_MVM_REF_PROTECT_CSA,
+       IWL_MVM_REF_FW_DBG_COLLECT,
 
        /* update debugfs.c when changing this */
 
@@ -535,6 +536,18 @@ enum iwl_mvm_tdls_cs_state {
        IWL_MVM_TDLS_SW_ACTIVE,
 };
 
+struct iwl_mvm_shared_mem_cfg {
+       u32 shared_mem_addr;
+       u32 shared_mem_size;
+       u32 sample_buff_addr;
+       u32 sample_buff_size;
+       u32 txfifo_addr;
+       u32 txfifo_size[TX_FIFO_MAX_NUM];
+       u32 rxfifo_size[RX_FIFO_MAX_NUM];
+       u32 page_buff_addr;
+       u32 page_buff_size;
+};
+
 struct iwl_mvm {
        /* for logger access */
        struct device *dev;
@@ -641,6 +654,8 @@ struct iwl_mvm {
        bool disable_power_off;
        bool disable_power_off_d3;
 
+       bool scan_iter_notif_enabled;
+
        struct debugfs_blob_wrapper nvm_hw_blob;
        struct debugfs_blob_wrapper nvm_sw_blob;
        struct debugfs_blob_wrapper nvm_calib_blob;
@@ -784,6 +799,8 @@ struct iwl_mvm {
                        u32 ch_sw_tm_ie;
                } peer;
        } tdls_cs;
+
+       struct iwl_mvm_shared_mem_cfg shared_mem_cfg;
 };
 
 /* Extract MVM priv from op_mode and _hw */
@@ -855,9 +872,9 @@ static inline bool iwl_mvm_is_d0i3_supported(struct iwl_mvm *mvm)
               (mvm->fw->ucode_capa.capa[0] & IWL_UCODE_TLV_CAPA_D0I3_SUPPORT);
 }
 
-static inline bool iwl_mvm_is_dqa_supported(struct iwl_mvm *mvm)
+static inline bool iwl_mvm_is_scd_cfg_supported(struct iwl_mvm *mvm)
 {
-       return mvm->fw->ucode_capa.capa[0] & IWL_UCODE_TLV_CAPA_DQA_SUPPORT;
+       return mvm->fw->ucode_capa.capa[0] & IWL_UCODE_TLV_API_SCD_CFG;
 }
 
 extern const u8 iwl_mvm_ac_to_tx_fifo[];
@@ -999,6 +1016,9 @@ int iwl_mvm_rx_radio_ver(struct iwl_mvm *mvm, struct iwl_rx_cmd_buffer *rxb,
                         struct iwl_device_cmd *cmd);
 int iwl_mvm_rx_mfuart_notif(struct iwl_mvm *mvm, struct iwl_rx_cmd_buffer *rxb,
                            struct iwl_device_cmd *cmd);
+int iwl_mvm_rx_shared_mem_cfg_notif(struct iwl_mvm *mvm,
+                                   struct iwl_rx_cmd_buffer *rxb,
+                                   struct iwl_device_cmd *cmd);
 
 /* MVM PHY */
 int iwl_mvm_phy_ctxt_add(struct iwl_mvm *mvm, struct iwl_mvm_phy_ctxt *ctxt,
@@ -1060,6 +1080,9 @@ int iwl_mvm_max_scan_ie_len(struct iwl_mvm *mvm, bool is_sched_scan);
 int iwl_mvm_rx_scan_offload_complete_notif(struct iwl_mvm *mvm,
                                           struct iwl_rx_cmd_buffer *rxb,
                                           struct iwl_device_cmd *cmd);
+int iwl_mvm_rx_scan_offload_iter_complete_notif(struct iwl_mvm *mvm,
+                                               struct iwl_rx_cmd_buffer *rxb,
+                                               struct iwl_device_cmd *cmd);
 int iwl_mvm_config_sched_scan(struct iwl_mvm *mvm,
                              struct ieee80211_vif *vif,
                              struct cfg80211_sched_scan_request *req,
@@ -1120,9 +1143,7 @@ iwl_mvm_vif_dbgfs_clean(struct iwl_mvm *mvm, struct ieee80211_vif *vif)
 
 /* rate scaling */
 int iwl_mvm_send_lq_cmd(struct iwl_mvm *mvm, struct iwl_lq_cmd *lq, bool init);
-void iwl_mvm_update_frame_stats(struct iwl_mvm *mvm,
-                               struct iwl_mvm_frame_stats *stats,
-                               u32 rate, bool agg);
+void iwl_mvm_update_frame_stats(struct iwl_mvm *mvm, u32 rate, bool agg);
 int rs_pretty_print_rate(char *buf, const u32 rate);
 void rs_update_last_rssi(struct iwl_mvm *mvm,
                         struct iwl_lq_sta *lq_sta,
@@ -1292,7 +1313,7 @@ static inline bool iwl_mvm_vif_low_latency(struct iwl_mvm_vif *mvmvif)
 /* hw scheduler queue config */
 void iwl_mvm_enable_txq(struct iwl_mvm *mvm, int queue, u16 ssn,
                        const struct iwl_trans_txq_scd_cfg *cfg);
-void iwl_mvm_disable_txq(struct iwl_mvm *mvm, int queue);
+void iwl_mvm_disable_txq(struct iwl_mvm *mvm, int queue, u8 flags);
 
 static inline void iwl_mvm_enable_ac_txq(struct iwl_mvm *mvm, int queue,
                                         u8 fifo)
index d55fd8e3654c830d047fbe9712686ef0dbff73b3..5383429d96c1c49f91539c8440b6016cee9dd31c 100644 (file)
@@ -356,7 +356,7 @@ static int iwl_mvm_read_external_nvm(struct iwl_mvm *mvm)
                max_section_size = IWL_MAX_NVM_SECTION_SIZE;
        else if (CSR_HW_REV_STEP(mvm->trans->hw_rev) == SILICON_A_STEP)
                max_section_size = IWL_MAX_NVM_8000A_SECTION_SIZE;
-       else /* Family 8000 B-step */
+       else /* Family 8000 B-step or C-step */
                max_section_size = IWL_MAX_NVM_8000B_SECTION_SIZE;
 
        /*
@@ -565,6 +565,8 @@ int iwl_nvm_init(struct iwl_mvm *mvm, bool read_nvm_from_nic)
        mvm->nvm_data = iwl_parse_nvm_sections(mvm);
        if (!mvm->nvm_data)
                return -ENODATA;
+       IWL_DEBUG_EEPROM(mvm->trans->dev, "nvm version = %x\n",
+                        mvm->nvm_data->nvm_version);
 
        return 0;
 }
index 239f033e3b9319fbbab0f84082a1ab5cb7ad3e07..8bf8c2a29e5eff6121a788333d9f6c12306e39fd 100644 (file)
@@ -234,6 +234,8 @@ static const struct iwl_rx_handlers iwl_mvm_rx_handlers[] = {
 
        RX_HANDLER(SCAN_REQUEST_CMD, iwl_mvm_rx_scan_response, false),
        RX_HANDLER(SCAN_COMPLETE_NOTIFICATION, iwl_mvm_rx_scan_complete, true),
+       RX_HANDLER(SCAN_ITERATION_COMPLETE,
+                  iwl_mvm_rx_scan_offload_iter_complete_notif, false),
        RX_HANDLER(SCAN_OFFLOAD_COMPLETE,
                   iwl_mvm_rx_scan_offload_complete_notif, true),
        RX_HANDLER(MATCH_FOUND_NOTIFICATION, iwl_mvm_rx_scan_offload_results,
@@ -268,6 +270,7 @@ static const char *const iwl_mvm_cmd_strings[REPLY_MAX] = {
        CMD(MGMT_MCAST_KEY),
        CMD(TX_CMD),
        CMD(TXPATH_FLUSH),
+       CMD(SHARED_MEM_CFG),
        CMD(MAC_CONTEXT_CMD),
        CMD(TIME_EVENT_CMD),
        CMD(TIME_EVENT_NOTIFICATION),
@@ -818,9 +821,20 @@ static void iwl_mvm_fw_error_dump_wk(struct work_struct *work)
        struct iwl_mvm *mvm =
                container_of(work, struct iwl_mvm, fw_error_dump_wk);
 
+       if (iwl_mvm_ref_sync(mvm, IWL_MVM_REF_FW_DBG_COLLECT))
+               return;
+
        mutex_lock(&mvm->mutex);
        iwl_mvm_fw_error_dump(mvm);
+
+       /* start recording again if the firmware is not crashed */
+       WARN_ON_ONCE((!test_bit(STATUS_FW_ERROR, &mvm->trans->status)) &&
+                     mvm->fw->dbg_dest_tlv &&
+                     iwl_mvm_start_fw_dbg_conf(mvm, mvm->fw_dbg_conf));
+
        mutex_unlock(&mvm->mutex);
+
+       iwl_mvm_unref(mvm, IWL_MVM_REF_FW_DBG_COLLECT);
 }
 
 void iwl_mvm_nic_restart(struct iwl_mvm *mvm, bool fw_error)
index 540c36bae2687bf0c8ca3c9f057c11e5b9b04bec..5b43616eeb06332dedd68299650583ec292b201f 100644 (file)
@@ -170,7 +170,7 @@ static void iwl_mvm_phy_ctxt_cmd_data(struct iwl_mvm *mvm,
                active_cnt = 2;
        }
 
-       cmd->rxchain_info = cpu_to_le32(mvm->fw->valid_rx_ant <<
+       cmd->rxchain_info = cpu_to_le32(iwl_mvm_get_valid_rx_ant(mvm) <<
                                        PHY_RX_CHAIN_VALID_POS);
        cmd->rxchain_info |= cpu_to_le32(idle_cnt << PHY_RX_CHAIN_CNT_POS);
        cmd->rxchain_info |= cpu_to_le32(active_cnt <<
index 7ba6e5dbbbd0b196d4e90cdf3bccf2dd0b6ed546..9f32f2db95bd497413a7b98b999a02b45536e204 100644 (file)
@@ -917,7 +917,6 @@ static u16 rs_get_adjacent_rate(struct iwl_mvm *mvm, u8 index, u16 rate_mask,
                        break;
                if (rate_mask & (1 << low))
                        break;
-               IWL_DEBUG_RATE(mvm, "Skipping masked lower rate: %d\n", low);
        }
 
        high = index;
@@ -927,7 +926,6 @@ static u16 rs_get_adjacent_rate(struct iwl_mvm *mvm, u8 index, u16 rate_mask,
                        break;
                if (rate_mask & (1 << high))
                        break;
-               IWL_DEBUG_RATE(mvm, "Skipping masked higher rate: %d\n", high);
        }
 
        return (high << 8) | low;
@@ -1804,20 +1802,12 @@ out:
 static bool rs_stbc_allow(struct iwl_mvm *mvm, struct ieee80211_sta *sta,
                          struct iwl_lq_sta *lq_sta)
 {
-       struct iwl_mvm_sta *mvmsta = iwl_mvm_sta_from_mac80211(sta);
-       struct ieee80211_vif *vif = mvmsta->vif;
-       bool sta_ps_disabled = (vif->type == NL80211_IFTYPE_STATION &&
-                               !vif->bss_conf.ps);
-
        /* Our chip supports Tx STBC and the peer is an HT/VHT STA which
         * supports STBC of at least 1*SS
         */
        if (!lq_sta->stbc)
                return false;
 
-       if (!mvm->ps_disabled && !sta_ps_disabled)
-               return false;
-
        if (!iwl_mvm_bt_coex_is_mimo_allowed(mvm, sta))
                return false;
 
@@ -2610,68 +2600,116 @@ static void rs_vht_set_enabled_rates(struct ieee80211_sta *sta,
        }
 }
 
+static void rs_ht_init(struct iwl_mvm *mvm,
+                      struct ieee80211_sta *sta,
+                      struct iwl_lq_sta *lq_sta,
+                      struct ieee80211_sta_ht_cap *ht_cap)
+{
+       /* active_siso_rate mask includes 9 MBits (bit 5),
+        * and CCK (bits 0-3), supp_rates[] does not;
+        * shift to convert format, force 9 MBits off.
+        */
+       lq_sta->active_siso_rate = ht_cap->mcs.rx_mask[0] << 1;
+       lq_sta->active_siso_rate |= ht_cap->mcs.rx_mask[0] & 0x1;
+       lq_sta->active_siso_rate &= ~((u16)0x2);
+       lq_sta->active_siso_rate <<= IWL_FIRST_OFDM_RATE;
+
+       lq_sta->active_mimo2_rate = ht_cap->mcs.rx_mask[1] << 1;
+       lq_sta->active_mimo2_rate |= ht_cap->mcs.rx_mask[1] & 0x1;
+       lq_sta->active_mimo2_rate &= ~((u16)0x2);
+       lq_sta->active_mimo2_rate <<= IWL_FIRST_OFDM_RATE;
+
+       if (mvm->cfg->ht_params->ldpc &&
+           (ht_cap->cap & IEEE80211_HT_CAP_LDPC_CODING))
+               lq_sta->ldpc = true;
+
+       if (mvm->cfg->ht_params->stbc &&
+           (num_of_ant(iwl_mvm_get_valid_tx_ant(mvm)) > 1) &&
+           (ht_cap->cap & IEEE80211_HT_CAP_RX_STBC))
+               lq_sta->stbc = true;
+
+       lq_sta->is_vht = false;
+}
+
+static void rs_vht_init(struct iwl_mvm *mvm,
+                       struct ieee80211_sta *sta,
+                       struct iwl_lq_sta *lq_sta,
+                       struct ieee80211_sta_vht_cap *vht_cap)
+{
+       rs_vht_set_enabled_rates(sta, vht_cap, lq_sta);
+
+       if (mvm->cfg->ht_params->ldpc &&
+           (vht_cap->cap & IEEE80211_VHT_CAP_RXLDPC))
+               lq_sta->ldpc = true;
+
+       if (mvm->cfg->ht_params->stbc &&
+           (num_of_ant(iwl_mvm_get_valid_tx_ant(mvm)) > 1) &&
+           (vht_cap->cap & IEEE80211_VHT_CAP_RXSTBC_MASK))
+               lq_sta->stbc = true;
+
+       lq_sta->is_vht = true;
+}
+
 #ifdef CONFIG_IWLWIFI_DEBUGFS
-static void iwl_mvm_reset_frame_stats(struct iwl_mvm *mvm,
-                                     struct iwl_mvm_frame_stats *stats)
+static void iwl_mvm_reset_frame_stats(struct iwl_mvm *mvm)
 {
        spin_lock_bh(&mvm->drv_stats_lock);
-       memset(stats, 0, sizeof(*stats));
+       memset(&mvm->drv_rx_stats, 0, sizeof(mvm->drv_rx_stats));
        spin_unlock_bh(&mvm->drv_stats_lock);
 }
 
-void iwl_mvm_update_frame_stats(struct iwl_mvm *mvm,
-                               struct iwl_mvm_frame_stats *stats,
-                               u32 rate, bool agg)
+void iwl_mvm_update_frame_stats(struct iwl_mvm *mvm, u32 rate, bool agg)
 {
        u8 nss = 0, mcs = 0;
 
        spin_lock(&mvm->drv_stats_lock);
 
        if (agg)
-               stats->agg_frames++;
+               mvm->drv_rx_stats.agg_frames++;
 
-       stats->success_frames++;
+       mvm->drv_rx_stats.success_frames++;
 
        switch (rate & RATE_MCS_CHAN_WIDTH_MSK) {
        case RATE_MCS_CHAN_WIDTH_20:
-               stats->bw_20_frames++;
+               mvm->drv_rx_stats.bw_20_frames++;
                break;
        case RATE_MCS_CHAN_WIDTH_40:
-               stats->bw_40_frames++;
+               mvm->drv_rx_stats.bw_40_frames++;
                break;
        case RATE_MCS_CHAN_WIDTH_80:
-               stats->bw_80_frames++;
+               mvm->drv_rx_stats.bw_80_frames++;
                break;
        default:
                WARN_ONCE(1, "bad BW. rate 0x%x", rate);
        }
 
        if (rate & RATE_MCS_HT_MSK) {
-               stats->ht_frames++;
+               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) {
-               stats->vht_frames++;
+               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 {
-               stats->legacy_frames++;
+               mvm->drv_rx_stats.legacy_frames++;
        }
 
        if (nss == 1)
-               stats->siso_frames++;
+               mvm->drv_rx_stats.siso_frames++;
        else if (nss == 2)
-               stats->mimo2_frames++;
+               mvm->drv_rx_stats.mimo2_frames++;
 
        if (rate & RATE_MCS_SGI_MSK)
-               stats->sgi_frames++;
+               mvm->drv_rx_stats.sgi_frames++;
        else
-               stats->ngi_frames++;
+               mvm->drv_rx_stats.ngi_frames++;
 
-       stats->last_rates[stats->last_frame_idx] = rate;
-       stats->last_frame_idx = (stats->last_frame_idx + 1) %
-               ARRAY_SIZE(stats->last_rates);
+       mvm->drv_rx_stats.last_rates[mvm->drv_rx_stats.last_frame_idx] = rate;
+       mvm->drv_rx_stats.last_frame_idx =
+               (mvm->drv_rx_stats.last_frame_idx + 1) %
+                       ARRAY_SIZE(mvm->drv_rx_stats.last_rates);
 
        spin_unlock(&mvm->drv_stats_lock);
 }
@@ -2724,46 +2762,12 @@ void iwl_mvm_rs_rate_init(struct iwl_mvm *mvm, struct ieee80211_sta *sta,
                lq_sta->active_legacy_rate |= BIT(sband->bitrates[i].hw_value);
 
        /* TODO: should probably account for rx_highest for both HT/VHT */
-       if (!vht_cap || !vht_cap->vht_supported) {
-               /* active_siso_rate mask includes 9 MBits (bit 5),
-                * and CCK (bits 0-3), supp_rates[] does not;
-                * shift to convert format, force 9 MBits off.
-                */
-               lq_sta->active_siso_rate = ht_cap->mcs.rx_mask[0] << 1;
-               lq_sta->active_siso_rate |= ht_cap->mcs.rx_mask[0] & 0x1;
-               lq_sta->active_siso_rate &= ~((u16)0x2);
-               lq_sta->active_siso_rate <<= IWL_FIRST_OFDM_RATE;
-
-               /* Same here */
-               lq_sta->active_mimo2_rate = ht_cap->mcs.rx_mask[1] << 1;
-               lq_sta->active_mimo2_rate |= ht_cap->mcs.rx_mask[1] & 0x1;
-               lq_sta->active_mimo2_rate &= ~((u16)0x2);
-               lq_sta->active_mimo2_rate <<= IWL_FIRST_OFDM_RATE;
-
-               lq_sta->is_vht = false;
-               if (mvm->cfg->ht_params->ldpc &&
-                   (ht_cap->cap & IEEE80211_HT_CAP_LDPC_CODING))
-                       lq_sta->ldpc = true;
-
-               if (mvm->cfg->ht_params->stbc &&
-                   (num_of_ant(iwl_mvm_get_valid_tx_ant(mvm)) > 1) &&
-                   (ht_cap->cap & IEEE80211_HT_CAP_RX_STBC))
-                       lq_sta->stbc = true;
-       } else {
-               rs_vht_set_enabled_rates(sta, vht_cap, lq_sta);
-               lq_sta->is_vht = true;
-
-               if (mvm->cfg->ht_params->ldpc &&
-                   (vht_cap->cap & IEEE80211_VHT_CAP_RXLDPC))
-                       lq_sta->ldpc = true;
-
-               if (mvm->cfg->ht_params->stbc &&
-                   (num_of_ant(iwl_mvm_get_valid_tx_ant(mvm)) > 1) &&
-                   (vht_cap->cap & IEEE80211_VHT_CAP_RXSTBC_MASK))
-                       lq_sta->stbc = true;
-       }
+       if (!vht_cap || !vht_cap->vht_supported)
+               rs_ht_init(mvm, sta, lq_sta, ht_cap);
+       else
+               rs_vht_init(mvm, sta, lq_sta, vht_cap);
 
-       if (IWL_MVM_RS_DISABLE_MIMO)
+       if (IWL_MVM_RS_DISABLE_P2P_MIMO && sta_priv->vif->p2p)
                lq_sta->active_mimo2_rate = 0;
 
        lq_sta->max_legacy_rate_idx =
@@ -2774,7 +2778,7 @@ void iwl_mvm_rs_rate_init(struct iwl_mvm *mvm, struct ieee80211_sta *sta,
                rs_get_max_rate_from_mask(lq_sta->active_mimo2_rate);
 
        IWL_DEBUG_RATE(mvm,
-                      "RATE MASK: LEGACY=%lX SISO=%lX MIMO2=%lX VHT=%d LDPC=%d STBC%d\n",
+                      "RATE MASK: LEGACY=%lX SISO=%lX MIMO2=%lX VHT=%d LDPC=%d STBC=%d\n",
                       lq_sta->active_legacy_rate,
                       lq_sta->active_siso_rate,
                       lq_sta->active_mimo2_rate,
@@ -2793,7 +2797,7 @@ void iwl_mvm_rs_rate_init(struct iwl_mvm *mvm, struct ieee80211_sta *sta,
        lq_sta->tx_agg_tid_en = IWL_AGG_ALL_TID;
        lq_sta->is_agg = 0;
 #ifdef CONFIG_IWLWIFI_DEBUGFS
-       iwl_mvm_reset_frame_stats(mvm, &mvm->drv_rx_stats);
+       iwl_mvm_reset_frame_stats(mvm);
 #endif
        rs_initialize_lq(mvm, sta, lq_sta, band, init);
 }
@@ -2862,12 +2866,13 @@ static void rs_fill_rates_for_column(struct iwl_mvm *mvm,
        int index = *rs_table_index;
 
        for (i = 0; i < num_rates && index < end; i++) {
-               ucode_rate = cpu_to_le32(ucode_rate_from_rs_rate(mvm, rate));
-               for (j = 0; j < num_retries && index < end; j++, index++)
+               for (j = 0; j < num_retries && index < end; j++, index++) {
+                       ucode_rate = cpu_to_le32(ucode_rate_from_rs_rate(mvm,
+                                                                        rate));
                        rs_table[index] = ucode_rate;
-
-               if (toggle_ant)
-                       rs_toggle_antenna(valid_tx_ant, rate);
+                       if (toggle_ant)
+                               rs_toggle_antenna(valid_tx_ant, rate);
+               }
 
                prev_rate_idx = rate->index;
                bottom_reached = rs_get_lower_rate_in_column(lq_sta, rate);
@@ -2875,7 +2880,7 @@ static void rs_fill_rates_for_column(struct iwl_mvm *mvm,
                        break;
        }
 
-       if (!bottom_reached)
+       if (!bottom_reached && !is_legacy(rate))
                rate->index = prev_rate_idx;
 
        *rs_table_index = index;
@@ -2911,11 +2916,23 @@ static void rs_build_rates_table(struct iwl_mvm *mvm,
        u8 valid_tx_ant = 0;
        struct iwl_lq_cmd *lq_cmd = &lq_sta->lq;
        bool toggle_ant = false;
+       bool stbc_allowed = false;
 
        memcpy(&rate, initial_rate, sizeof(rate));
 
        valid_tx_ant = iwl_mvm_get_valid_tx_ant(mvm);
-       rate.stbc = rs_stbc_allow(mvm, sta, lq_sta);
+
+       stbc_allowed = rs_stbc_allow(mvm, sta, lq_sta);
+       if (mvm->fw->ucode_capa.api[0] & IWL_UCODE_TLV_API_LQ_SS_PARAMS) {
+               u32 ss_params = RS_SS_PARAMS_VALID;
+
+               if (stbc_allowed)
+                       ss_params |= RS_SS_STBC_ALLOWED;
+               lq_cmd->ss_params = cpu_to_le32(ss_params);
+       } else {
+               /* TODO: remove old API when min FW API hits 14 */
+               rate.stbc = stbc_allowed;
+       }
 
        if (is_siso(&rate)) {
                num_rates = IWL_MVM_RS_INITIAL_SISO_NUM_RATES;
@@ -2925,7 +2942,7 @@ static void rs_build_rates_table(struct iwl_mvm *mvm,
                num_retries = IWL_MVM_RS_HT_VHT_RETRIES_PER_RATE;
        } else {
                num_rates = IWL_MVM_RS_INITIAL_LEGACY_NUM_RATES;
-               num_retries = IWL_MVM_RS_LEGACY_RETRIES_PER_RATE;
+               num_retries = IWL_MVM_RS_INITIAL_LEGACY_RETRIES;
                toggle_ant = true;
        }
 
@@ -2941,7 +2958,7 @@ static void rs_build_rates_table(struct iwl_mvm *mvm,
                lq_cmd->mimo_delim = index;
        } else if (is_legacy(&rate)) {
                num_rates = IWL_MVM_RS_SECONDARY_LEGACY_NUM_RATES;
-               num_retries = IWL_MVM_RS_LEGACY_RETRIES_PER_RATE;
+               num_retries = IWL_MVM_RS_SECONDARY_LEGACY_RETRIES;
        } else {
                WARN_ON_ONCE(1);
        }
@@ -2955,7 +2972,7 @@ static void rs_build_rates_table(struct iwl_mvm *mvm,
        rs_get_lower_rate_down_column(lq_sta, &rate);
 
        num_rates = IWL_MVM_RS_SECONDARY_LEGACY_NUM_RATES;
-       num_retries = IWL_MVM_RS_LEGACY_RETRIES_PER_RATE;
+       num_retries = IWL_MVM_RS_SECONDARY_LEGACY_RETRIES;
 
        rs_fill_rates_for_column(mvm, lq_sta, &rate, lq_cmd->rs_table, &index,
                                 num_rates, num_retries, valid_tx_ant,
index 94b6e7297a1eca297488ac8377496756c85a18e2..f922131b4eaba7a66ab8d2e14f749f5d8cb56206 100644 (file)
@@ -407,7 +407,7 @@ int iwl_mvm_rx_rx_mpdu(struct iwl_mvm *mvm, struct iwl_rx_cmd_buffer *rxb,
        }
 
 #ifdef CONFIG_IWLWIFI_DEBUGFS
-       iwl_mvm_update_frame_stats(mvm, &mvm->drv_rx_stats, rate_n_flags,
+       iwl_mvm_update_frame_stats(mvm, rate_n_flags,
                                   rx_status->flag & RX_FLAG_AMPDU_DETAILS);
 #endif
        iwl_mvm_pass_packet_to_mac80211(mvm, skb, hdr, len, ampdu_status,
@@ -511,13 +511,17 @@ int iwl_mvm_rx_statistics(struct iwl_mvm *mvm,
 {
        struct iwl_rx_packet *pkt = rxb_addr(rxb);
        struct iwl_notif_statistics *stats = (void *)&pkt->data;
-       struct mvm_statistics_general_common *common = &stats->general.common;
        struct iwl_mvm_stat_data data = {
                .stats = stats,
                .mvm = mvm,
        };
 
-       iwl_mvm_tt_temp_changed(mvm, le32_to_cpu(common->temperature));
+       /* Only handle rx statistics temperature changes if async temp
+        * notifications are not supported
+        */
+       if (!(mvm->fw->ucode_capa.api[0] & IWL_UCODE_TLV_API_ASYNC_DTM))
+               iwl_mvm_tt_temp_changed(mvm,
+                               le32_to_cpu(stats->general.radio_temperature));
 
        iwl_mvm_update_rx_statistics(mvm, stats);
 
index 348b9c4b694a5c62685c7b16fb68c35ca32b82c3..3bd5f34d32855fa413bdddd9db0cf600ebf8261e 100644 (file)
@@ -173,15 +173,21 @@ static void iwl_mvm_scan_fill_ssids(struct iwl_ssid_ie *cmd_ssid,
  * already included in the probe template, so we need to set only
  * req->n_ssids - 1 bits in addition to the first bit.
  */
-static u16 iwl_mvm_get_active_dwell(enum ieee80211_band band, int n_ssids)
+static u16 iwl_mvm_get_active_dwell(struct iwl_mvm *mvm,
+                                   enum ieee80211_band band, int n_ssids)
 {
+       if (mvm->fw->ucode_capa.api[0] & IWL_UCODE_TLV_API_BASIC_DWELL)
+               return 10;
        if (band == IEEE80211_BAND_2GHZ)
                return 20  + 3 * (n_ssids + 1);
        return 10  + 2 * (n_ssids + 1);
 }
 
-static u16 iwl_mvm_get_passive_dwell(enum ieee80211_band band)
+static u16 iwl_mvm_get_passive_dwell(struct iwl_mvm *mvm,
+                                    enum ieee80211_band band)
 {
+       if (mvm->fw->ucode_capa.api[0] & IWL_UCODE_TLV_API_BASIC_DWELL)
+                       return 110;
        return band == IEEE80211_BAND_2GHZ ? 100 + 20 : 100 + 10;
 }
 
@@ -309,18 +315,18 @@ static void iwl_mvm_scan_calc_params(struct iwl_mvm *mvm,
                goto not_bound;
 
        params->suspend_time = 30;
-       params->max_out_time = 170;
+       params->max_out_time = 120;
 
        if (iwl_mvm_low_latency(mvm)) {
                if (mvm->fw->ucode_capa.api[0] &
                    IWL_UCODE_TLV_API_FRAGMENTED_SCAN) {
                        params->suspend_time = 105;
-                       params->max_out_time = 70;
                        /*
                         * If there is more than one active interface make
                         * passive scan more fragmented.
                         */
                        frag_passive_dwell = (global_cnt < 2) ? 40 : 20;
+                       params->max_out_time = frag_passive_dwell;
                } else {
                        params->suspend_time = 120;
                        params->max_out_time = 120;
@@ -337,7 +343,8 @@ static void iwl_mvm_scan_calc_params(struct iwl_mvm *mvm,
                 */
                if (vif->type == NL80211_IFTYPE_P2P_DEVICE) {
                        u32 passive_dwell =
-                               iwl_mvm_get_passive_dwell(IEEE80211_BAND_2GHZ);
+                               iwl_mvm_get_passive_dwell(mvm,
+                                                         IEEE80211_BAND_2GHZ);
                        params->max_out_time = passive_dwell;
                } else {
                        params->passive_fragmented = true;
@@ -354,8 +361,8 @@ not_bound:
                        params->dwell[band].passive = frag_passive_dwell;
                else
                        params->dwell[band].passive =
-                               iwl_mvm_get_passive_dwell(band);
-               params->dwell[band].active = iwl_mvm_get_active_dwell(band,
+                               iwl_mvm_get_passive_dwell(mvm, band);
+               params->dwell[band].active = iwl_mvm_get_active_dwell(mvm, band,
                                                                      n_ssids);
        }
 }
@@ -536,6 +543,19 @@ int iwl_mvm_rx_scan_response(struct iwl_mvm *mvm, struct iwl_rx_cmd_buffer *rxb,
        return 0;
 }
 
+int iwl_mvm_rx_scan_offload_iter_complete_notif(struct iwl_mvm *mvm,
+                                               struct iwl_rx_cmd_buffer *rxb,
+                                               struct iwl_device_cmd *cmd)
+{
+       struct iwl_rx_packet *pkt = rxb_addr(rxb);
+       struct iwl_scan_complete_notif *notif = (void *)pkt->data;
+
+       IWL_DEBUG_SCAN(mvm,
+                      "Scan offload iteration complete: status=0x%x scanned channels=%d\n",
+                      notif->status, notif->scanned_channels);
+       return 0;
+}
+
 int iwl_mvm_rx_scan_complete(struct iwl_mvm *mvm, struct iwl_rx_cmd_buffer *rxb,
                          struct iwl_device_cmd *cmd)
 {
@@ -1104,6 +1124,12 @@ int iwl_mvm_scan_offload_stop(struct iwl_mvm *mvm, bool notify)
                return iwl_umac_scan_stop(mvm, IWL_UMAC_SCAN_UID_SCHED_SCAN,
                                          notify);
 
+       if (mvm->scan_status == IWL_MVM_SCAN_NONE)
+               return 0;
+
+       if (iwl_mvm_is_radio_killed(mvm))
+               goto out;
+
        if (mvm->scan_status != IWL_MVM_SCAN_SCHED &&
            (!(mvm->fw->ucode_capa.api[0] & IWL_UCODE_TLV_API_LMAC_SCAN) ||
             mvm->scan_status != IWL_MVM_SCAN_OS)) {
@@ -1140,6 +1166,7 @@ int iwl_mvm_scan_offload_stop(struct iwl_mvm *mvm, bool notify)
        if (mvm->scan_status == IWL_MVM_SCAN_OS)
                iwl_mvm_unref(mvm, IWL_MVM_REF_SCAN);
 
+out:
        mvm->scan_status = IWL_MVM_SCAN_NONE;
 
        if (notify) {
@@ -1296,22 +1323,6 @@ iwl_mvm_build_generic_unified_scan_cmd(struct iwl_mvm *mvm,
        cmd->scan_prio = cpu_to_le32(IWL_SCAN_PRIORITY_HIGH);
        cmd->iter_num = cpu_to_le32(1);
 
-       if (mvm->fw->ucode_capa.flags & IWL_UCODE_TLV_FLAGS_EBS_SUPPORT &&
-           mvm->last_ebs_successful) {
-               cmd->channel_opt[0].flags =
-                       cpu_to_le16(IWL_SCAN_CHANNEL_FLAG_EBS |
-                                   IWL_SCAN_CHANNEL_FLAG_EBS_ACCURATE |
-                                   IWL_SCAN_CHANNEL_FLAG_CACHE_ADD);
-               cmd->channel_opt[0].non_ebs_ratio =
-                       cpu_to_le16(IWL_DENSE_EBS_SCAN_RATIO);
-               cmd->channel_opt[1].flags =
-                       cpu_to_le16(IWL_SCAN_CHANNEL_FLAG_EBS |
-                                   IWL_SCAN_CHANNEL_FLAG_EBS_ACCURATE |
-                                   IWL_SCAN_CHANNEL_FLAG_CACHE_ADD);
-               cmd->channel_opt[1].non_ebs_ratio =
-                       cpu_to_le16(IWL_SPARSE_EBS_SCAN_RATIO);
-       }
-
        if (iwl_mvm_rrm_scan_needed(mvm))
                cmd->scan_flags |=
                        cpu_to_le32(IWL_MVM_LMAC_SCAN_FLAGS_RRM_ENABLED);
@@ -1386,6 +1397,22 @@ int iwl_mvm_unified_scan_lmac(struct iwl_mvm *mvm,
        cmd->schedule[1].iterations = 0;
        cmd->schedule[1].full_scan_mul = 0;
 
+       if (mvm->fw->ucode_capa.api[0] & IWL_UCODE_TLV_API_SINGLE_SCAN_EBS &&
+           mvm->last_ebs_successful) {
+               cmd->channel_opt[0].flags =
+                       cpu_to_le16(IWL_SCAN_CHANNEL_FLAG_EBS |
+                                   IWL_SCAN_CHANNEL_FLAG_EBS_ACCURATE |
+                                   IWL_SCAN_CHANNEL_FLAG_CACHE_ADD);
+               cmd->channel_opt[0].non_ebs_ratio =
+                       cpu_to_le16(IWL_DENSE_EBS_SCAN_RATIO);
+               cmd->channel_opt[1].flags =
+                       cpu_to_le16(IWL_SCAN_CHANNEL_FLAG_EBS |
+                                   IWL_SCAN_CHANNEL_FLAG_EBS_ACCURATE |
+                                   IWL_SCAN_CHANNEL_FLAG_CACHE_ADD);
+               cmd->channel_opt[1].non_ebs_ratio =
+                       cpu_to_le16(IWL_SPARSE_EBS_SCAN_RATIO);
+       }
+
        for (i = 1; i <= req->req.n_ssids; i++)
                ssid_bitmap |= BIT(i);
 
@@ -1458,6 +1485,8 @@ int iwl_mvm_unified_sched_scan_lmac(struct iwl_mvm *mvm,
 
        if (iwl_mvm_scan_pass_all(mvm, req))
                flags |= IWL_MVM_LMAC_SCAN_FLAG_PASS_ALL;
+       else
+               flags |= IWL_MVM_LMAC_SCAN_FLAG_MATCH;
 
        if (req->n_ssids == 1 && req->ssids[0].ssid_len != 0)
                flags |= IWL_MVM_LMAC_SCAN_FLAG_PRE_CONNECTION;
@@ -1468,6 +1497,11 @@ int iwl_mvm_unified_sched_scan_lmac(struct iwl_mvm *mvm,
        if (req->n_ssids == 0)
                flags |= IWL_MVM_LMAC_SCAN_FLAG_PASSIVE;
 
+#ifdef CONFIG_IWLWIFI_DEBUGFS
+       if (mvm->scan_iter_notif_enabled)
+               flags |= IWL_MVM_LMAC_SCAN_FLAG_ITER_COMPLETE;
+#endif
+
        cmd->scan_flags |= cpu_to_le32(flags);
 
        cmd->flags = iwl_mvm_scan_rxon_flags(req->channels[0]->band);
@@ -1484,6 +1518,22 @@ int iwl_mvm_unified_sched_scan_lmac(struct iwl_mvm *mvm,
        cmd->schedule[1].iterations = 0xff;
        cmd->schedule[1].full_scan_mul = IWL_FULL_SCAN_MULTIPLIER;
 
+       if (mvm->fw->ucode_capa.flags & IWL_UCODE_TLV_FLAGS_EBS_SUPPORT &&
+           mvm->last_ebs_successful) {
+               cmd->channel_opt[0].flags =
+                       cpu_to_le16(IWL_SCAN_CHANNEL_FLAG_EBS |
+                                   IWL_SCAN_CHANNEL_FLAG_EBS_ACCURATE |
+                                   IWL_SCAN_CHANNEL_FLAG_CACHE_ADD);
+               cmd->channel_opt[0].non_ebs_ratio =
+                       cpu_to_le16(IWL_DENSE_EBS_SCAN_RATIO);
+               cmd->channel_opt[1].flags =
+                       cpu_to_le16(IWL_SCAN_CHANNEL_FLAG_EBS |
+                                   IWL_SCAN_CHANNEL_FLAG_EBS_ACCURATE |
+                                   IWL_SCAN_CHANNEL_FLAG_CACHE_ADD);
+               cmd->channel_opt[1].non_ebs_ratio =
+                       cpu_to_le16(IWL_SPARSE_EBS_SCAN_RATIO);
+       }
+
        iwl_mvm_lmac_scan_cfg_channels(mvm, req->channels, req->n_channels,
                                       ssid_bitmap, cmd);
 
index ad327984b099f756756bc858e86c9d11f596ded8..14a848480d041d9914450f4984c2ab301662af90 100644 (file)
@@ -250,8 +250,8 @@ static void iwl_mvm_tdls_sta_deinit(struct iwl_mvm *mvm,
 
        /* disable the TDLS STA-specific queues */
        sta_msk = mvmsta->tfd_queue_msk;
-       for_each_set_bit(i, &sta_msk, sizeof(sta_msk))
-               iwl_mvm_disable_txq(mvm, i);
+       for_each_set_bit(i, &sta_msk, sizeof(sta_msk) * BITS_PER_BYTE)
+               iwl_mvm_disable_txq(mvm, i, 0);
 }
 
 int iwl_mvm_add_sta(struct iwl_mvm *mvm,
@@ -464,8 +464,8 @@ void iwl_mvm_sta_drained_wk(struct work_struct *wk)
                if (mvm->tfd_drained[sta_id]) {
                        unsigned long i, msk = mvm->tfd_drained[sta_id];
 
-                       for_each_set_bit(i, &msk, sizeof(msk))
-                               iwl_mvm_disable_txq(mvm, i);
+                       for_each_set_bit(i, &msk, sizeof(msk) * BITS_PER_BYTE)
+                               iwl_mvm_disable_txq(mvm, i, 0);
 
                        mvm->tfd_drained[sta_id] = 0;
                        IWL_DEBUG_TDLS(mvm, "Drained sta %d, with queues %ld\n",
@@ -1058,7 +1058,7 @@ int iwl_mvm_sta_tx_agg_stop(struct iwl_mvm *mvm, struct ieee80211_vif *vif,
 
                iwl_mvm_sta_tx_agg(mvm, sta, tid, txq_id, false);
 
-               iwl_mvm_disable_txq(mvm, txq_id);
+               iwl_mvm_disable_txq(mvm, txq_id, 0);
                return 0;
        case IWL_AGG_STARTING:
        case IWL_EMPTYING_HW_QUEUE_ADDBA:
@@ -1116,7 +1116,7 @@ int iwl_mvm_sta_tx_agg_flush(struct iwl_mvm *mvm, struct ieee80211_vif *vif,
 
                iwl_mvm_sta_tx_agg(mvm, sta, tid, txq_id, false);
 
-               iwl_mvm_disable_txq(mvm, tid_data->txq_id);
+               iwl_mvm_disable_txq(mvm, tid_data->txq_id, 0);
        }
 
        mvm->queue_to_mac80211[tid_data->txq_id] =
@@ -1196,6 +1196,7 @@ static int iwl_mvm_send_sta_key(struct iwl_mvm *mvm,
                break;
        case WLAN_CIPHER_SUITE_WEP104:
                key_flags |= cpu_to_le16(STA_KEY_FLG_WEP_13BYTES);
+               /* fall through */
        case WLAN_CIPHER_SUITE_WEP40:
                key_flags |= cpu_to_le16(STA_KEY_FLG_WEP);
                memcpy(cmd.key + 3, keyconf->key, keyconf->keylen);
index d6cdb770881abc5383f31069f9d408b56a9c9d5e..07304e1fd64aa70b41d4c9a18762b48924a6f250 100644 (file)
@@ -90,8 +90,6 @@ void iwl_mvm_set_tx_cmd(struct iwl_mvm *mvm, struct sk_buff *skb,
 
        if (ieee80211_is_probe_resp(fc))
                tx_flags |= TX_CMD_FLG_TSF;
-       else if (ieee80211_is_back_req(fc))
-               tx_flags |= TX_CMD_FLG_ACK | TX_CMD_FLG_BAR;
 
        if (ieee80211_has_morefrags(fc))
                tx_flags |= TX_CMD_FLG_MORE_FRAG;
@@ -100,6 +98,15 @@ void iwl_mvm_set_tx_cmd(struct iwl_mvm *mvm, struct sk_buff *skb,
                u8 *qc = ieee80211_get_qos_ctl(hdr);
                tx_cmd->tid_tspec = qc[0] & 0xf;
                tx_flags &= ~TX_CMD_FLG_SEQ_CTL;
+       } else if (ieee80211_is_back_req(fc)) {
+               struct ieee80211_bar *bar = (void *)skb->data;
+               u16 control = le16_to_cpu(bar->control);
+
+               tx_flags |= TX_CMD_FLG_ACK | TX_CMD_FLG_BAR;
+               tx_cmd->tid_tspec = (control &
+                                    IEEE80211_BAR_CTRL_TID_INFO_MASK) >>
+                       IEEE80211_BAR_CTRL_TID_INFO_SHIFT;
+               WARN_ON_ONCE(tx_cmd->tid_tspec >= IWL_MAX_TID_COUNT);
        } else {
                tx_cmd->tid_tspec = IWL_TID_NON_QOS;
                if (info->flags & IEEE80211_TX_CTL_ASSIGN_SEQ)
@@ -108,8 +115,12 @@ void iwl_mvm_set_tx_cmd(struct iwl_mvm *mvm, struct sk_buff *skb,
                        tx_flags &= ~TX_CMD_FLG_SEQ_CTL;
        }
 
-       /* tid_tspec will default to 0 = BE when QOS isn't enabled */
-       ac = tid_to_mac80211_ac[tx_cmd->tid_tspec];
+       /* Default to 0 (BE) when tid_spec is set to IWL_TID_NON_QOS */
+       if (tx_cmd->tid_tspec < IWL_MAX_TID_COUNT)
+               ac = tid_to_mac80211_ac[tx_cmd->tid_tspec];
+       else
+               ac = tid_to_mac80211_ac[0];
+
        tx_flags |= iwl_mvm_bt_coex_tx_prio(mvm, hdr, info, ac) <<
                        TX_CMD_FLG_BT_PRIO_POS;
 
@@ -496,7 +507,7 @@ static void iwl_mvm_check_ratid_empty(struct iwl_mvm *mvm,
                IWL_DEBUG_TX_QUEUES(mvm,
                                    "Can continue DELBA flow ssn = next_recl = %d\n",
                                    tid_data->next_reclaimed);
-               iwl_mvm_disable_txq(mvm, tid_data->txq_id);
+               iwl_mvm_disable_txq(mvm, tid_data->txq_id, CMD_ASYNC);
                tid_data->state = IWL_AGG_OFF;
                /*
                 * we can't hold the mutex - but since we are after a sequence
@@ -656,7 +667,8 @@ static void iwl_mvm_rx_tx_cmd_single(struct iwl_mvm *mvm,
 
                /* Single frame failure in an AMPDU queue => send BAR */
                if (txq_id >= mvm->first_agg_queue &&
-                   !(info->flags & IEEE80211_TX_STAT_ACK))
+                   !(info->flags & IEEE80211_TX_STAT_ACK) &&
+                   !(info->flags & IEEE80211_TX_STAT_TX_FILTERED))
                        info->flags |= IEEE80211_TX_STAT_AMPDU_NO_BACK;
 
                /* W/A FW bug: seq_ctl is wrong when the status isn't success */
@@ -919,6 +931,11 @@ int iwl_mvm_rx_ba_notif(struct iwl_mvm *mvm, struct iwl_rx_cmd_buffer *rxb,
        sta_id = ba_notif->sta_id;
        tid = ba_notif->tid;
 
+       if (WARN_ONCE(sta_id >= IWL_MVM_STATION_COUNT ||
+                     tid >= IWL_MAX_TID_COUNT,
+                     "sta_id %d tid %d", sta_id, tid))
+               return 0;
+
        rcu_read_lock();
 
        sta = rcu_dereference(mvm->fw_id_to_mac_id[sta_id]);
index f0a114102c3fda09b732c1709ec9d99f1b0d333c..4eb3cad31aa99f5c830e13fb0e29bc494a794c75 100644 (file)
@@ -533,47 +533,46 @@ void iwl_mvm_dump_nic_error_log(struct iwl_mvm *mvm)
 void iwl_mvm_enable_txq(struct iwl_mvm *mvm, int queue, u16 ssn,
                        const struct iwl_trans_txq_scd_cfg *cfg)
 {
-       if (iwl_mvm_is_dqa_supported(mvm)) {
-               struct iwl_scd_txq_cfg_cmd cmd = {
-                       .scd_queue = queue,
-                       .enable = 1,
-                       .window = cfg->frame_limit,
-                       .sta_id = cfg->sta_id,
-                       .ssn = cpu_to_le16(ssn),
-                       .tx_fifo = cfg->fifo,
-                       .aggregate = cfg->aggregate,
-                       .flags = IWL_SCD_FLAGS_DQA_ENABLED,
-                       .tid = cfg->tid,
-                       .control = IWL_SCD_CONTROL_SET_SSN,
-               };
-               int ret = iwl_mvm_send_cmd_pdu(mvm, SCD_QUEUE_CFG, 0,
-                                              sizeof(cmd), &cmd);
-               if (ret)
-                       IWL_ERR(mvm,
-                               "Failed to configure queue %d on FIFO %d\n",
-                               queue, cfg->fifo);
+       struct iwl_scd_txq_cfg_cmd cmd = {
+               .scd_queue = queue,
+               .enable = 1,
+               .window = cfg->frame_limit,
+               .sta_id = cfg->sta_id,
+               .ssn = cpu_to_le16(ssn),
+               .tx_fifo = cfg->fifo,
+               .aggregate = cfg->aggregate,
+               .tid = cfg->tid,
+       };
+
+       if (!iwl_mvm_is_scd_cfg_supported(mvm)) {
+               iwl_trans_txq_enable_cfg(mvm->trans, queue, ssn, cfg);
+               return;
        }
 
-       iwl_trans_txq_enable_cfg(mvm->trans, queue, ssn,
-                                iwl_mvm_is_dqa_supported(mvm) ? NULL : cfg);
+       iwl_trans_txq_enable_cfg(mvm->trans, queue, ssn, NULL);
+       WARN(iwl_mvm_send_cmd_pdu(mvm, SCD_QUEUE_CFG, 0, sizeof(cmd), &cmd),
+            "Failed to configure queue %d on FIFO %d\n", queue, cfg->fifo);
 }
 
-void iwl_mvm_disable_txq(struct iwl_mvm *mvm, int queue)
+void iwl_mvm_disable_txq(struct iwl_mvm *mvm, int queue, u8 flags)
 {
-       iwl_trans_txq_disable(mvm->trans, queue,
-                             !iwl_mvm_is_dqa_supported(mvm));
-
-       if (iwl_mvm_is_dqa_supported(mvm)) {
-               struct iwl_scd_txq_cfg_cmd cmd = {
-                       .scd_queue = queue,
-                       .enable = 0,
-               };
-               int ret = iwl_mvm_send_cmd_pdu(mvm, SCD_QUEUE_CFG, CMD_ASYNC,
-                                              sizeof(cmd), &cmd);
-               if (ret)
-                       IWL_ERR(mvm, "Failed to disable queue %d (ret=%d)\n",
-                               queue, ret);
+       struct iwl_scd_txq_cfg_cmd cmd = {
+               .scd_queue = queue,
+               .enable = 0,
+       };
+       int ret;
+
+       if (!iwl_mvm_is_scd_cfg_supported(mvm)) {
+               iwl_trans_txq_disable(mvm->trans, queue, true);
+               return;
        }
+
+       iwl_trans_txq_disable(mvm->trans, queue, false);
+       ret = iwl_mvm_send_cmd_pdu(mvm, SCD_QUEUE_CFG, flags,
+                                  sizeof(cmd), &cmd);
+       if (ret)
+               IWL_ERR(mvm, "Failed to disable queue %d (ret=%d)\n",
+                       queue, ret);
 }
 
 /**
@@ -665,7 +664,7 @@ bool iwl_mvm_rx_diversity_allowed(struct iwl_mvm *mvm)
        if (num_of_ant(iwl_mvm_get_valid_rx_ant(mvm)) == 1)
                return false;
 
-       if (!mvm->cfg->rx_with_siso_diversity)
+       if (mvm->cfg->rx_with_siso_diversity)
                return false;
 
        ieee80211_iterate_active_interfaces_atomic(
index 2f0c4b1703442b85b3a56bd90c0548995e0bc661..dbd6bcf5220563c03727bccde83083032b977ff8 100644 (file)
@@ -415,6 +415,8 @@ static const struct pci_device_id iwl_hw_card_ids[] = {
        {IWL_PCI_DEVICE(0x24F3, 0x0010, iwl8260_2ac_cfg)},
        {IWL_PCI_DEVICE(0x24F3, 0x0004, iwl8260_2n_cfg)},
        {IWL_PCI_DEVICE(0x24F4, 0x0030, iwl8260_2ac_cfg)},
+       {IWL_PCI_DEVICE(0x24F5, 0x0010, iwl4165_2ac_cfg)},
+       {IWL_PCI_DEVICE(0x24F6, 0x0030, iwl4165_2ac_cfg)},
 #endif /* CONFIG_IWLMVM */
 
        {0}
@@ -527,8 +529,10 @@ static int iwl_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
        else if (cfg == &iwl7265_n_cfg)
                cfg_7265d = &iwl7265d_n_cfg;
        if (cfg_7265d &&
-           (iwl_trans->hw_rev & CSR_HW_REV_TYPE_MSK) == CSR_HW_REV_TYPE_7265D)
+           (iwl_trans->hw_rev & CSR_HW_REV_TYPE_MSK) == CSR_HW_REV_TYPE_7265D) {
                cfg = cfg_7265d;
+               iwl_trans->cfg = cfg_7265d;
+       }
 #endif
 
        pci_set_drvdata(pdev, iwl_trans);
index 9ee4ca0ba8d37042b0cace64a1735c63daf21276..1ff87677c3d35ceaf68762cc4dda8b578a22e514 100644 (file)
@@ -722,6 +722,11 @@ static int iwl_pcie_load_cpu_sections_8000b(struct iwl_trans *trans,
 
        *first_ucode_section = last_read_idx;
 
+       if (cpu == 1)
+               iwl_write_direct32(trans, FH_UCODE_LOAD_STATUS, 0xFFFF);
+       else
+               iwl_write_direct32(trans, FH_UCODE_LOAD_STATUS, 0xFFFFFFFF);
+
        return 0;
 }
 
@@ -911,9 +916,6 @@ static int iwl_pcie_load_given_ucode_8000b(struct iwl_trans *trans,
        if (trans->dbg_dest_tlv)
                iwl_pcie_apply_destination(trans);
 
-       /* Notify FW loading is done */
-       iwl_write_direct32(trans, FH_UCODE_LOAD_STATUS, 0xFFFFFFFF);
-
        /* wait for image verification to complete  */
        ret = iwl_poll_prph_bit(trans, LMPM_SECURE_BOOT_CPU1_STATUS_ADDR_B0,
                                LMPM_SECURE_BOOT_STATUS_SUCCESS,
@@ -982,7 +984,7 @@ static int iwl_trans_pcie_start_fw(struct iwl_trans *trans,
 
        /* Load the given image to the HW */
        if ((trans->cfg->device_family == IWL_DEVICE_FAMILY_8000) &&
-           (CSR_HW_REV_STEP(trans->hw_rev) == SILICON_B_STEP))
+           (CSR_HW_REV_STEP(trans->hw_rev) != SILICON_A_STEP))
                return iwl_pcie_load_given_ucode_8000b(trans, fw);
        else
                return iwl_pcie_load_given_ucode(trans, fw);
@@ -2348,6 +2350,7 @@ struct iwl_trans *iwl_trans_pcie_alloc(struct pci_dev *pdev,
        trans_pcie->trans = trans;
        spin_lock_init(&trans_pcie->irq_lock);
        spin_lock_init(&trans_pcie->reg_lock);
+       spin_lock_init(&trans_pcie->ref_lock);
        init_waitqueue_head(&trans_pcie->ucode_write_waitq);
 
        err = pci_enable_device(pdev);
index c1c4c75026b28981c47e0416edb59d61404e8827..d40cd4a67d6e07c58c78b1e56b98f1ca118f4da9 100644 (file)
@@ -1190,12 +1190,12 @@ void iwl_trans_pcie_txq_enable(struct iwl_trans *trans, int txq_id, u16 ssn,
         * Assumes that ssn_idx is valid (!= 0xFFF) */
        trans_pcie->txq[txq_id].q.read_ptr = (ssn & 0xff);
        trans_pcie->txq[txq_id].q.write_ptr = (ssn & 0xff);
+       iwl_write_direct32(trans, HBUS_TARG_WRPTR,
+                          (ssn & 0xff) | (txq_id << 8));
 
        if (cfg) {
                u8 frame_limit = cfg->frame_limit;
 
-               iwl_write_direct32(trans, HBUS_TARG_WRPTR,
-                                  (ssn & 0xff) | (txq_id << 8));
                iwl_write_prph(trans, SCD_QUEUE_RDPTR(txq_id), ssn);
 
                /* Set up Tx window size and frame limit for this queue */
@@ -1220,11 +1220,17 @@ void iwl_trans_pcie_txq_enable(struct iwl_trans *trans, int txq_id, u16 ssn,
                if (txq_id == trans_pcie->cmd_queue &&
                    trans_pcie->scd_set_active)
                        iwl_scd_enable_set_active(trans, BIT(txq_id));
+
+               IWL_DEBUG_TX_QUEUES(trans,
+                                   "Activate queue %d on FIFO %d WrPtr: %d\n",
+                                   txq_id, fifo, ssn & 0xff);
+       } else {
+               IWL_DEBUG_TX_QUEUES(trans,
+                                   "Activate queue %d WrPtr: %d\n",
+                                   txq_id, ssn & 0xff);
        }
 
        trans_pcie->txq[txq_id].active = true;
-       IWL_DEBUG_TX_QUEUES(trans, "Activate queue %d on FIFO %d WrPtr: %d\n",
-                           txq_id, fifo, ssn & 0xff);
 }
 
 void iwl_trans_pcie_txq_disable(struct iwl_trans *trans, int txq_id,