summaryrefslogtreecommitdiffstats
path: root/drivers/net/wireless/iwlwifi
diff options
context:
space:
mode:
authorDavid S. Miller <davem@davemloft.net>2015-10-12 19:39:18 -0700
committerDavid S. Miller <davem@davemloft.net>2015-10-12 19:39:18 -0700
commit991659674288dba28c2f5a3d1a0133ef4d20824a (patch)
tree55b98aad2e06c4765533662ce03e9c7979b276b2 /drivers/net/wireless/iwlwifi
parente2ca690b657f4ca5c204fcc6470d462b776d73b3 (diff)
parent7e64e5e66af8308725bfd03fcdf185c09b3056a7 (diff)
Merge tag 'wireless-drivers-next-for-davem-2015-10-09' of git://git.kernel.org/pub/scm/linux/kernel/git/kvalo/wireless-drivers-next
Kalle Valo says: ==================== Major changes: iwlwifi * some debugfs improvements * fix signedness in beacon statistics * deinline some functions to reduce size when device tracing is enabled * filter beacons out in AP mode when no stations are associated * deprecate firmwares version -12 * fix a runtime PM vs. legacy suspend race * one-liner fix for a ToF bug * clean-ups in the rx code * small debugging improvement * fix WoWLAN with new firmware versions * more clean-ups towards multiple RX queues; * some rate scaling fixes and improvements; * some time-of-flight fixes; * other generic improvements and clean-ups; brcmfmac * rework code dealing with multiple interfaces * allow logging firmware console using debug level * support for BCM4350, BCM4365, and BCM4366 PCIE devices * fixed for legacy P2P and P2P device handling * correct set and get tx-power ath9k * add support for Outside Context of a BSS (OCB) mode mwifiex * add USB multichannel feature ==================== Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'drivers/net/wireless/iwlwifi')
-rw-r--r--drivers/net/wireless/iwlwifi/Kconfig1
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-7000.c13
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-8000.c6
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-config.h12
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-drv.c4
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-fw-file.h32
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-fw.h4
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-io.c23
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-io.h21
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-nvm-parse.c15
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-nvm-parse.h2
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-op-mode.h19
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-trans.c1
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-trans.h5
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/constants.h1
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/d3.c3
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/debugfs-vif.c75
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/debugfs.c132
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/fw-api-power.h8
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/fw-api-rx.h238
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/fw-api-stats.h41
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/fw-api.h196
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/fw.c24
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/mac-ctxt.c36
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/mac80211.c26
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/mvm.h68
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/nvm.c7
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/ops.c178
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/power.c80
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/rs.c116
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/rx.c67
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/scan.c2
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/sta.c83
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/tof.c4
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/tof.h2
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/tt.c14
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/tx.c11
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/utils.c141
38 files changed, 994 insertions, 717 deletions
diff --git a/drivers/net/wireless/iwlwifi/Kconfig b/drivers/net/wireless/iwlwifi/Kconfig
index aba095761ac6..6e949df399d6 100644
--- a/drivers/net/wireless/iwlwifi/Kconfig
+++ b/drivers/net/wireless/iwlwifi/Kconfig
@@ -142,6 +142,7 @@ config IWLWIFI_DEBUG_EXPERIMENTAL_UCODE
config IWLWIFI_DEVICE_TRACING
bool "iwlwifi device access tracing"
depends on EVENT_TRACING
+ default y
help
Say Y here to trace all commands, including TX frames and IO
accesses, sent to the device. If you say yes, iwlwifi will
diff --git a/drivers/net/wireless/iwlwifi/iwl-7000.c b/drivers/net/wireless/iwlwifi/iwl-7000.c
index 6951aba620eb..d561181f2cff 100644
--- a/drivers/net/wireless/iwlwifi/iwl-7000.c
+++ b/drivers/net/wireless/iwlwifi/iwl-7000.c
@@ -72,12 +72,10 @@
#define IWL7260_UCODE_API_MAX 17
/* Oldest version we won't warn about */
-#define IWL7260_UCODE_API_OK 12
-#define IWL3165_UCODE_API_OK 13
+#define IWL7260_UCODE_API_OK 13
/* Lowest firmware API version supported */
-#define IWL7260_UCODE_API_MIN 12
-#define IWL3165_UCODE_API_MIN 13
+#define IWL7260_UCODE_API_MIN 13
/* NVM versions */
#define IWL7260_NVM_VERSION 0x0a1d
@@ -113,7 +111,7 @@
static const struct iwl_base_params iwl7000_base_params = {
.eeprom_size = OTP_LOW_IMAGE_SIZE_FAMILY_7000,
- .num_of_queues = IWLAGN_NUM_QUEUES,
+ .num_of_queues = 31,
.pll_cfg_val = 0,
.shadow_ram_support = true,
.led_compensation = 57,
@@ -269,11 +267,6 @@ const struct iwl_cfg iwl3165_2ac_cfg = {
.name = "Intel(R) Dual Band Wireless AC 3165",
.fw_name_pre = IWL7265D_FW_PRE,
IWL_DEVICE_7000,
- /* sparse doens't like the re-assignment but it is safe */
-#ifndef __CHECKER__
- .ucode_api_ok = IWL3165_UCODE_API_OK,
- .ucode_api_min = IWL3165_UCODE_API_MIN,
-#endif
.ht_params = &iwl7000_ht_params,
.nvm_ver = IWL3165_NVM_VERSION,
.nvm_calib_ver = IWL3165_TX_POWER_VERSION,
diff --git a/drivers/net/wireless/iwlwifi/iwl-8000.c b/drivers/net/wireless/iwlwifi/iwl-8000.c
index 197abe43ddc5..0116e5a4c393 100644
--- a/drivers/net/wireless/iwlwifi/iwl-8000.c
+++ b/drivers/net/wireless/iwlwifi/iwl-8000.c
@@ -72,10 +72,10 @@
#define IWL8000_UCODE_API_MAX 17
/* Oldest version we won't warn about */
-#define IWL8000_UCODE_API_OK 12
+#define IWL8000_UCODE_API_OK 13
/* Lowest firmware API version supported */
-#define IWL8000_UCODE_API_MIN 12
+#define IWL8000_UCODE_API_MIN 13
/* NVM versions */
#define IWL8000_NVM_VERSION 0x0a1d
@@ -107,7 +107,7 @@
static const struct iwl_base_params iwl8000_base_params = {
.eeprom_size = OTP_LOW_IMAGE_SIZE_FAMILY_8000,
- .num_of_queues = IWLAGN_NUM_QUEUES,
+ .num_of_queues = 31,
.pll_cfg_val = 0,
.shadow_ram_support = true,
.led_compensation = 57,
diff --git a/drivers/net/wireless/iwlwifi/iwl-config.h b/drivers/net/wireless/iwlwifi/iwl-config.h
index 939fa229c038..910970858f98 100644
--- a/drivers/net/wireless/iwlwifi/iwl-config.h
+++ b/drivers/net/wireless/iwlwifi/iwl-config.h
@@ -223,13 +223,13 @@ struct iwl_tt_tx_backoff {
* @support_tx_backoff: Support tx-backoff?
*/
struct iwl_tt_params {
- s32 ct_kill_entry;
- s32 ct_kill_exit;
+ u32 ct_kill_entry;
+ u32 ct_kill_exit;
u32 ct_kill_duration;
- s32 dynamic_smps_entry;
- s32 dynamic_smps_exit;
- s32 tx_protection_entry;
- s32 tx_protection_exit;
+ u32 dynamic_smps_entry;
+ u32 dynamic_smps_exit;
+ u32 tx_protection_entry;
+ u32 tx_protection_exit;
struct iwl_tt_tx_backoff tx_backoff[TT_TX_BACKOFF_SIZE];
bool support_ct_kill;
bool support_dynamic_smps;
diff --git a/drivers/net/wireless/iwlwifi/iwl-drv.c b/drivers/net/wireless/iwlwifi/iwl-drv.c
index a86aa5bcee7d..463cadfbfccb 100644
--- a/drivers/net/wireless/iwlwifi/iwl-drv.c
+++ b/drivers/net/wireless/iwlwifi/iwl-drv.c
@@ -450,7 +450,7 @@ static int iwl_set_ucode_api_flags(struct iwl_drv *drv, const u8 *data,
u32 api_flags = le32_to_cpu(ucode_api->api_flags);
int i;
- if (api_index >= IWL_API_MAX_BITS / 32) {
+ if (api_index >= DIV_ROUND_UP(NUM_IWL_UCODE_TLV_API, 32)) {
IWL_ERR(drv, "api_index larger than supported by driver\n");
/* don't return an error so we can load FW that has more bits */
return 0;
@@ -472,7 +472,7 @@ static int iwl_set_ucode_capabilities(struct iwl_drv *drv, const u8 *data,
u32 api_flags = le32_to_cpu(ucode_capa->api_capa);
int i;
- if (api_index >= IWL_CAPABILITIES_MAX_BITS / 32) {
+ if (api_index >= DIV_ROUND_UP(NUM_IWL_UCODE_TLV_CAPA, 32)) {
IWL_ERR(drv, "api_index larger than supported by driver\n");
/* don't return an error so we can load FW that has more bits */
return 0;
diff --git a/drivers/net/wireless/iwlwifi/iwl-fw-file.h b/drivers/net/wireless/iwlwifi/iwl-fw-file.h
index 84653e3d02ba..72ddd4a163e6 100644
--- a/drivers/net/wireless/iwlwifi/iwl-fw-file.h
+++ b/drivers/net/wireless/iwlwifi/iwl-fw-file.h
@@ -247,36 +247,31 @@ typedef unsigned int __bitwise__ iwl_ucode_tlv_api_t;
* @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_WIFI_MCC_UPDATE: ucode supports MCC updates with source.
- * IWL_UCODE_TLV_API_HDC_PHASE_0: ucode supports finer configuration of LTR
- * @IWL_UCODE_TLV_API_TX_POWER_DEV: new API for tx power.
* @IWL_UCODE_TLV_API_WIDE_CMD_HDR: ucode supports wide command header
- * @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
- * @IWL_UCODE_TLV_API_STATS_V10: uCode supports/uses statistics API version 10
* @IWL_UCODE_TLV_API_NEW_VERSION: new versioning format
* @IWL_UCODE_TLV_API_EXT_SCAN_PRIORITY: scan APIs use 8-level priority
* instead of 3.
* @IWL_UCODE_TLV_API_TX_POWER_CHAIN: TX power API has larger command size
* (command version 3) that supports per-chain limits
+ *
+ * @NUM_IWL_UCODE_TLV_API: number of bits used
*/
enum iwl_ucode_tlv_api {
IWL_UCODE_TLV_API_BT_COEX_SPLIT = (__force iwl_ucode_tlv_api_t)3,
IWL_UCODE_TLV_API_FRAGMENTED_SCAN = (__force iwl_ucode_tlv_api_t)8,
IWL_UCODE_TLV_API_WIFI_MCC_UPDATE = (__force iwl_ucode_tlv_api_t)9,
- IWL_UCODE_TLV_API_HDC_PHASE_0 = (__force iwl_ucode_tlv_api_t)10,
- IWL_UCODE_TLV_API_TX_POWER_DEV = (__force iwl_ucode_tlv_api_t)11,
IWL_UCODE_TLV_API_WIDE_CMD_HDR = (__force iwl_ucode_tlv_api_t)14,
- IWL_UCODE_TLV_API_SCD_CFG = (__force iwl_ucode_tlv_api_t)15,
- IWL_UCODE_TLV_API_SINGLE_SCAN_EBS = (__force iwl_ucode_tlv_api_t)16,
- IWL_UCODE_TLV_API_ASYNC_DTM = (__force iwl_ucode_tlv_api_t)17,
IWL_UCODE_TLV_API_LQ_SS_PARAMS = (__force iwl_ucode_tlv_api_t)18,
- IWL_UCODE_TLV_API_STATS_V10 = (__force iwl_ucode_tlv_api_t)19,
IWL_UCODE_TLV_API_NEW_VERSION = (__force iwl_ucode_tlv_api_t)20,
IWL_UCODE_TLV_API_EXT_SCAN_PRIORITY = (__force iwl_ucode_tlv_api_t)24,
IWL_UCODE_TLV_API_TX_POWER_CHAIN = (__force iwl_ucode_tlv_api_t)27,
+
+ NUM_IWL_UCODE_TLV_API
+#ifdef __CHECKER__
+ /* sparse says it cannot increment the previous enum member */
+ = 128
+#endif
};
typedef unsigned int __bitwise__ iwl_ucode_tlv_capa_t;
@@ -311,6 +306,8 @@ typedef unsigned int __bitwise__ iwl_ucode_tlv_capa_t;
* is supported.
* @IWL_UCODE_TLV_CAPA_BT_COEX_RRC: supports BT Coex RRC
* @IWL_UCODE_TLV_CAPA_GSCAN_SUPPORT: supports gscan
+ *
+ * @NUM_IWL_UCODE_TLV_CAPA: number of bits used
*/
enum iwl_ucode_tlv_capa {
IWL_UCODE_TLV_CAPA_D0I3_SUPPORT = (__force iwl_ucode_tlv_capa_t)0,
@@ -333,6 +330,12 @@ enum iwl_ucode_tlv_capa {
IWL_UCODE_TLV_CAPA_LAR_MULTI_MCC = (__force iwl_ucode_tlv_capa_t)29,
IWL_UCODE_TLV_CAPA_BT_COEX_RRC = (__force iwl_ucode_tlv_capa_t)30,
IWL_UCODE_TLV_CAPA_GSCAN_SUPPORT = (__force iwl_ucode_tlv_capa_t)31,
+
+ NUM_IWL_UCODE_TLV_CAPA
+#ifdef __CHECKER__
+ /* sparse says it cannot increment the previous enum member */
+ = 128
+#endif
};
/* The default calibrate table size if not specified by firmware file */
@@ -343,9 +346,6 @@ enum iwl_ucode_tlv_capa {
/* The default max probe length if not specified by the firmware file */
#define IWL_DEFAULT_MAX_PROBE_LENGTH 200
-#define IWL_API_MAX_BITS 64
-#define IWL_CAPABILITIES_MAX_BITS 64
-
/*
* For 16.0 uCode and above, there is no differentiation between sections,
* just an offset to the HW address.
diff --git a/drivers/net/wireless/iwlwifi/iwl-fw.h b/drivers/net/wireless/iwlwifi/iwl-fw.h
index 45e732150d28..84ec0cefb62a 100644
--- a/drivers/net/wireless/iwlwifi/iwl-fw.h
+++ b/drivers/net/wireless/iwlwifi/iwl-fw.h
@@ -105,8 +105,8 @@ struct iwl_ucode_capabilities {
u32 n_scan_channels;
u32 standard_phy_calibration_size;
u32 flags;
- unsigned long _api[BITS_TO_LONGS(IWL_API_MAX_BITS)];
- unsigned long _capa[BITS_TO_LONGS(IWL_CAPABILITIES_MAX_BITS)];
+ unsigned long _api[BITS_TO_LONGS(NUM_IWL_UCODE_TLV_API)];
+ unsigned long _capa[BITS_TO_LONGS(NUM_IWL_UCODE_TLV_CAPA)];
};
static inline bool
diff --git a/drivers/net/wireless/iwlwifi/iwl-io.c b/drivers/net/wireless/iwlwifi/iwl-io.c
index 27c66e477833..0bd9d4aad0c0 100644
--- a/drivers/net/wireless/iwlwifi/iwl-io.c
+++ b/drivers/net/wireless/iwlwifi/iwl-io.c
@@ -36,6 +36,29 @@
#include "iwl-prph.h"
#include "iwl-fh.h"
+void iwl_write8(struct iwl_trans *trans, u32 ofs, u8 val)
+{
+ trace_iwlwifi_dev_iowrite8(trans->dev, ofs, val);
+ iwl_trans_write8(trans, ofs, val);
+}
+IWL_EXPORT_SYMBOL(iwl_write8);
+
+void iwl_write32(struct iwl_trans *trans, u32 ofs, u32 val)
+{
+ trace_iwlwifi_dev_iowrite32(trans->dev, ofs, val);
+ iwl_trans_write32(trans, ofs, val);
+}
+IWL_EXPORT_SYMBOL(iwl_write32);
+
+u32 iwl_read32(struct iwl_trans *trans, u32 ofs)
+{
+ u32 val = iwl_trans_read32(trans, ofs);
+
+ trace_iwlwifi_dev_ioread32(trans->dev, ofs, val);
+ return val;
+}
+IWL_EXPORT_SYMBOL(iwl_read32);
+
#define IWL_POLL_INTERVAL 10 /* microseconds */
int iwl_poll_bit(struct iwl_trans *trans, u32 addr,
diff --git a/drivers/net/wireless/iwlwifi/iwl-io.h b/drivers/net/wireless/iwlwifi/iwl-io.h
index 705d12c079e8..501d0560c061 100644
--- a/drivers/net/wireless/iwlwifi/iwl-io.h
+++ b/drivers/net/wireless/iwlwifi/iwl-io.h
@@ -32,24 +32,9 @@
#include "iwl-devtrace.h"
#include "iwl-trans.h"
-static inline void iwl_write8(struct iwl_trans *trans, u32 ofs, u8 val)
-{
- trace_iwlwifi_dev_iowrite8(trans->dev, ofs, val);
- iwl_trans_write8(trans, ofs, val);
-}
-
-static inline void iwl_write32(struct iwl_trans *trans, u32 ofs, u32 val)
-{
- trace_iwlwifi_dev_iowrite32(trans->dev, ofs, val);
- iwl_trans_write32(trans, ofs, val);
-}
-
-static inline u32 iwl_read32(struct iwl_trans *trans, u32 ofs)
-{
- u32 val = iwl_trans_read32(trans, ofs);
- trace_iwlwifi_dev_ioread32(trans->dev, ofs, val);
- return val;
-}
+void iwl_write8(struct iwl_trans *trans, u32 ofs, u8 val);
+void iwl_write32(struct iwl_trans *trans, u32 ofs, u32 val);
+u32 iwl_read32(struct iwl_trans *trans, u32 ofs);
static inline void iwl_set_bit(struct iwl_trans *trans, u32 reg, u32 mask)
{
diff --git a/drivers/net/wireless/iwlwifi/iwl-nvm-parse.c b/drivers/net/wireless/iwlwifi/iwl-nvm-parse.c
index 3b8e85e51002..d82984912e04 100644
--- a/drivers/net/wireless/iwlwifi/iwl-nvm-parse.c
+++ b/drivers/net/wireless/iwlwifi/iwl-nvm-parse.c
@@ -580,13 +580,15 @@ static void iwl_set_hw_address_family_8000(struct device *dev,
IWL_ERR_DEV(dev, "mac address is not found\n");
}
+#define IWL_4165_DEVICE_ID 0x5501
+
struct iwl_nvm_data *
iwl_parse_nvm_data(struct device *dev, const struct iwl_cfg *cfg,
const __le16 *nvm_hw, const __le16 *nvm_sw,
const __le16 *nvm_calib, const __le16 *regulatory,
const __le16 *mac_override, const __le16 *phy_sku,
u8 tx_chains, u8 rx_chains, bool lar_fw_supported,
- u32 mac_addr0, u32 mac_addr1)
+ u32 mac_addr0, u32 mac_addr1, u32 hw_id)
{
struct iwl_nvm_data *data;
u32 sku;
@@ -625,6 +627,17 @@ iwl_parse_nvm_data(struct device *dev, const struct iwl_cfg *cfg,
(sku & NVM_SKU_CAP_11AC_ENABLE);
data->sku_cap_mimo_disabled = sku & NVM_SKU_CAP_MIMO_DISABLE;
+ /*
+ * OTP 0x52 bug work around
+ * define antenna 1x1 according to MIMO disabled
+ */
+ if (hw_id == IWL_4165_DEVICE_ID && data->sku_cap_mimo_disabled) {
+ data->valid_tx_ant = ANT_B;
+ data->valid_rx_ant = ANT_B;
+ tx_chains = ANT_B;
+ rx_chains = ANT_B;
+ }
+
data->n_hw_addrs = iwl_get_n_hw_addrs(cfg, nvm_sw);
if (cfg->device_family != IWL_DEVICE_FAMILY_8000) {
diff --git a/drivers/net/wireless/iwlwifi/iwl-nvm-parse.h b/drivers/net/wireless/iwlwifi/iwl-nvm-parse.h
index 822ba52e0e5a..9f44d8188c5c 100644
--- a/drivers/net/wireless/iwlwifi/iwl-nvm-parse.h
+++ b/drivers/net/wireless/iwlwifi/iwl-nvm-parse.h
@@ -79,7 +79,7 @@ iwl_parse_nvm_data(struct device *dev, const struct iwl_cfg *cfg,
const __le16 *nvm_calib, const __le16 *regulatory,
const __le16 *mac_override, const __le16 *phy_sku,
u8 tx_chains, u8 rx_chains, bool lar_fw_supported,
- u32 mac_addr0, u32 mac_addr1);
+ u32 mac_addr0, u32 mac_addr1, u32 hw_id);
/**
* iwl_parse_mcc_info - parse MCC (mobile country code) info coming from FW
diff --git a/drivers/net/wireless/iwlwifi/iwl-op-mode.h b/drivers/net/wireless/iwlwifi/iwl-op-mode.h
index b47fe9d6b97a..2a58d6833224 100644
--- a/drivers/net/wireless/iwlwifi/iwl-op-mode.h
+++ b/drivers/net/wireless/iwlwifi/iwl-op-mode.h
@@ -7,6 +7,7 @@
*
* Copyright(c) 2007 - 2014 Intel Corporation. All rights reserved.
* Copyright(c) 2013 - 2014 Intel Mobile Communications GmbH
+ * Copyright(c) 2015 Intel Deutschland 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
@@ -33,6 +34,7 @@
*
* Copyright(c) 2005 - 2014 Intel Corporation. All rights reserved.
* Copyright(c) 2013 - 2014 Intel Mobile Communications GmbH
+ * Copyright(c) 2015 Intel Deutschland GmbH
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -108,7 +110,8 @@ struct iwl_cfg;
* interact with it. The driver layer typically calls the start and stop
* handlers, the transport layer calls the others.
*
- * All the handlers MUST be implemented
+ * All the handlers MUST be implemented, except @rx_rss which can be left
+ * out *iff* the opmode will never run on hardware with multi-queue capability.
*
* @start: start the op_mode. The transport layer is already allocated.
* May sleep
@@ -116,6 +119,10 @@ struct iwl_cfg;
* May sleep
* @rx: Rx notification to the op_mode. rxb is the Rx buffer itself. Cmd is the
* HCMD this Rx responds to. Can't sleep.
+ * @rx_rss: data queue RX notification to the op_mode, for (data) notifications
+ * received on the RSS queue(s). The queue parameter indicates which of the
+ * RSS queues received this frame; it will always be non-zero.
+ * This method must not sleep.
* @queue_full: notifies that a HW queue is full.
* Must be atomic and called with BH disabled.
* @queue_not_full: notifies that a HW queue is not full any more.
@@ -146,6 +153,8 @@ struct iwl_op_mode_ops {
void (*stop)(struct iwl_op_mode *op_mode);
void (*rx)(struct iwl_op_mode *op_mode, struct napi_struct *napi,
struct iwl_rx_cmd_buffer *rxb);
+ void (*rx_rss)(struct iwl_op_mode *op_mode, struct napi_struct *napi,
+ struct iwl_rx_cmd_buffer *rxb, unsigned int queue);
void (*queue_full)(struct iwl_op_mode *op_mode, int queue);
void (*queue_not_full)(struct iwl_op_mode *op_mode, int queue);
bool (*hw_rf_kill)(struct iwl_op_mode *op_mode, bool state);
@@ -186,6 +195,14 @@ static inline void iwl_op_mode_rx(struct iwl_op_mode *op_mode,
return op_mode->ops->rx(op_mode, napi, rxb);
}
+static inline void iwl_op_mode_rx_rss(struct iwl_op_mode *op_mode,
+ struct napi_struct *napi,
+ struct iwl_rx_cmd_buffer *rxb,
+ unsigned int queue)
+{
+ op_mode->ops->rx_rss(op_mode, napi, rxb, queue);
+}
+
static inline void iwl_op_mode_queue_full(struct iwl_op_mode *op_mode,
int queue)
{
diff --git a/drivers/net/wireless/iwlwifi/iwl-trans.c b/drivers/net/wireless/iwlwifi/iwl-trans.c
index 9f8bcefc04c5..71610968c365 100644
--- a/drivers/net/wireless/iwlwifi/iwl-trans.c
+++ b/drivers/net/wireless/iwlwifi/iwl-trans.c
@@ -87,6 +87,7 @@ struct iwl_trans *iwl_trans_alloc(unsigned int priv_size,
trans->cfg = cfg;
trans->ops = ops;
trans->dev_cmd_headroom = dev_cmd_headroom;
+ trans->num_rx_queues = 1;
snprintf(trans->dev_cmd_pool_name, sizeof(trans->dev_cmd_pool_name),
"iwl_cmd_pool:%s", dev_name(trans->dev));
diff --git a/drivers/net/wireless/iwlwifi/iwl-trans.h b/drivers/net/wireless/iwlwifi/iwl-trans.h
index c829c505e141..bb51b6f8002c 100644
--- a/drivers/net/wireless/iwlwifi/iwl-trans.h
+++ b/drivers/net/wireless/iwlwifi/iwl-trans.h
@@ -386,6 +386,7 @@ static inline void iwl_free_rxb(struct iwl_rx_cmd_buffer *r)
#define IWL_MAX_HW_QUEUES 32
#define IWL_MAX_TID_COUNT 8
#define IWL_FRAME_LIMIT 64
+#define IWL_MAX_RX_HW_QUEUES 16
/**
* enum iwl_wowlan_status - WoWLAN image/device status
@@ -654,6 +655,8 @@ enum iwl_d0i3_mode {
* @hw_id_str: a string with info about HW ID. Set during transport allocation.
* @pm_support: set to true in start_hw if link pm is supported
* @ltr_enabled: set to true if the LTR is enabled
+ * @num_rx_queues: number of RX queues allocated by the transport;
+ * the transport must set this before calling iwl_drv_start()
* @dev_cmd_pool: pool for Tx cmd allocation - for internal use only.
* The user should use iwl_trans_{alloc,free}_tx_cmd.
* @dev_cmd_headroom: room needed for the transport's private use before the
@@ -693,6 +696,8 @@ struct iwl_trans {
bool pm_support;
bool ltr_enabled;
+ u8 num_rx_queues;
+
/* The following fields are internal only */
struct kmem_cache *dev_cmd_pool;
size_t dev_cmd_headroom;
diff --git a/drivers/net/wireless/iwlwifi/mvm/constants.h b/drivers/net/wireless/iwlwifi/mvm/constants.h
index b8ee3121fbd2..a3ca6db0f303 100644
--- a/drivers/net/wireless/iwlwifi/mvm/constants.h
+++ b/drivers/net/wireless/iwlwifi/mvm/constants.h
@@ -102,6 +102,7 @@
#define IWL_MVM_QUOTA_THRESHOLD 4
#define IWL_MVM_RS_RSSI_BASED_INIT_RATE 0
#define IWL_MVM_RS_DISABLE_P2P_MIMO 0
+#define IWL_MVM_RS_80_20_FAR_RANGE_TWEAK 1
#define IWL_MVM_TOF_IS_RESPONDER 0
#define IWL_MVM_RS_NUM_TRY_BEFORE_ANT_TOGGLE 1
#define IWL_MVM_RS_HT_VHT_RETRIES_PER_RATE 2
diff --git a/drivers/net/wireless/iwlwifi/mvm/d3.c b/drivers/net/wireless/iwlwifi/mvm/d3.c
index 04264e417c1c..1d54355ad76a 100644
--- a/drivers/net/wireless/iwlwifi/mvm/d3.c
+++ b/drivers/net/wireless/iwlwifi/mvm/d3.c
@@ -1170,6 +1170,9 @@ int iwl_mvm_suspend(struct ieee80211_hw *hw, struct cfg80211_wowlan *wowlan)
struct iwl_mvm *mvm = IWL_MAC80211_GET_MVM(hw);
int ret;
+ /* make sure the d0i3 exit work is not pending */
+ flush_work(&mvm->d0i3_exit_work);
+
ret = iwl_trans_suspend(mvm->trans);
if (ret)
return ret;
diff --git a/drivers/net/wireless/iwlwifi/mvm/debugfs-vif.c b/drivers/net/wireless/iwlwifi/mvm/debugfs-vif.c
index 383a3162046c..398bef6f4f61 100644
--- a/drivers/net/wireless/iwlwifi/mvm/debugfs-vif.c
+++ b/drivers/net/wireless/iwlwifi/mvm/debugfs-vif.c
@@ -511,7 +511,8 @@ static ssize_t iwl_dbgfs_tof_enable_write(struct ieee80211_vif *vif,
{
struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif);
struct iwl_mvm *mvm = mvmvif->mvm;
- int value, ret = -EINVAL;
+ u32 value;
+ int ret = -EINVAL;
char *data;
mutex_lock(&mvm->mutex);
@@ -599,7 +600,8 @@ static ssize_t iwl_dbgfs_tof_responder_params_write(struct ieee80211_vif *vif,
{
struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif);
struct iwl_mvm *mvm = mvmvif->mvm;
- int value, ret = 0;
+ u32 value;
+ int ret = 0;
char *data;
mutex_lock(&mvm->mutex);
@@ -822,7 +824,8 @@ static ssize_t iwl_dbgfs_tof_range_request_write(struct ieee80211_vif *vif,
{
struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif);
struct iwl_mvm *mvm = mvmvif->mvm;
- int value, ret = 0;
+ u32 value;
+ int ret = 0;
char *data;
mutex_lock(&mvm->mutex);
@@ -892,6 +895,7 @@ static ssize_t iwl_dbgfs_tof_range_request_write(struct ieee80211_vif *vif,
goto out;
}
memcpy(mvm->tof_data.range_req.macaddr_template, mac, ETH_ALEN);
+ goto out;
}
data = iwl_dbgfs_is_match("macaddr_mask=", buf);
@@ -903,21 +907,22 @@ static ssize_t iwl_dbgfs_tof_range_request_write(struct ieee80211_vif *vif,
goto out;
}
memcpy(mvm->tof_data.range_req.macaddr_mask, mac, ETH_ALEN);
+ goto out;
}
data = iwl_dbgfs_is_match("ap=", buf);
if (data) {
- struct iwl_tof_range_req_ap_entry ap;
+ struct iwl_tof_range_req_ap_entry ap = {};
int size = sizeof(struct iwl_tof_range_req_ap_entry);
u16 burst_period;
u8 *mac = ap.bssid;
unsigned int i;
- if (sscanf(data, "%u %hhd %hhx %hhx"
+ if (sscanf(data, "%u %hhd %hhd %hhd"
"%hhx:%hhx:%hhx:%hhx:%hhx:%hhx"
- "%hhx %hhx %hx"
- "%hhx %hhx %x"
- "%hhx %hhx %hhx %hhx",
+ "%hhd %hhd %hd"
+ "%hhd %hhd %d"
+ "%hhx %hhd %hhd %hhd",
&i, &ap.channel_num, &ap.bandwidth,
&ap.ctrl_ch_position,
mac, mac + 1, mac + 2, mac + 3, mac + 4, mac + 5,
@@ -944,12 +949,12 @@ static ssize_t iwl_dbgfs_tof_range_request_write(struct ieee80211_vif *vif,
data = iwl_dbgfs_is_match("send_range_request=", buf);
if (data) {
ret = kstrtou32(data, 10, &value);
- if (ret == 0 && value) {
+ if (ret == 0 && value)
ret = iwl_mvm_tof_range_request_cmd(mvm, vif);
- goto out;
- }
+ goto out;
}
+ ret = -EINVAL;
out:
mutex_unlock(&mvm->mutex);
return ret ?: count;
@@ -994,16 +999,18 @@ static ssize_t iwl_dbgfs_tof_range_request_read(struct file *file,
struct iwl_tof_range_req_ap_entry *ap = &cmd->ap[i];
pos += scnprintf(buf + pos, bufsz - pos,
- "ap %.2d: channel_num=%hhx bw=%hhx"
- " control=%hhx bssid=%pM type=%hhx"
- " num_of_bursts=%hhx burst_period=%hx ftm=%hhx"
- " retries=%hhx tsf_delta=%x location_req=%hhx "
- " asap=%hhx enable=%hhx rssi=%hhx\n",
+ "ap %.2d: channel_num=%hhd bw=%hhd"
+ " control=%hhd bssid=%pM type=%hhd"
+ " num_of_bursts=%hhd burst_period=%hd ftm=%hhd"
+ " retries=%hhd tsf_delta=%d"
+ " tsf_delta_direction=%hhd location_req=0x%hhx "
+ " asap=%hhd enable=%hhd rssi=%hhd\n",
i, ap->channel_num, ap->bandwidth,
ap->ctrl_ch_position, ap->bssid,
ap->measure_type, ap->num_of_bursts,
ap->burst_period, ap->samples_per_burst,
ap->retries_per_sample, ap->tsf_delta,
+ ap->tsf_delta_direction,
ap->location_req, ap->asap_mode,
ap->enable_dyn_ack, ap->rssi);
}
@@ -1019,7 +1026,8 @@ static ssize_t iwl_dbgfs_tof_range_req_ext_write(struct ieee80211_vif *vif,
{
struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif);
struct iwl_mvm *mvm = mvmvif->mvm;
- int value, ret = 0;
+ u32 value;
+ int ret = 0;
char *data;
mutex_lock(&mvm->mutex);
@@ -1071,12 +1079,12 @@ static ssize_t iwl_dbgfs_tof_range_req_ext_write(struct ieee80211_vif *vif,
data = iwl_dbgfs_is_match("send_range_req_ext=", buf);
if (data) {
ret = kstrtou32(data, 10, &value);
- if (ret == 0 && value) {
+ if (ret == 0 && value)
ret = iwl_mvm_tof_range_request_ext_cmd(mvm, vif);
- goto out;
- }
+ goto out;
}
+ ret = -EINVAL;
out:
mutex_unlock(&mvm->mutex);
return ret ?: count;
@@ -1099,18 +1107,18 @@ static ssize_t iwl_dbgfs_tof_range_req_ext_read(struct file *file,
mutex_lock(&mvm->mutex);
pos += scnprintf(buf + pos, bufsz - pos,
- "tsf_timer_offset_msec = %hx\n",
+ "tsf_timer_offset_msec = %hd\n",
cmd->tsf_timer_offset_msec);
- pos += scnprintf(buf + pos, bufsz - pos, "min_delta_ftm = %hhx\n",
+ pos += scnprintf(buf + pos, bufsz - pos, "min_delta_ftm = %hhd\n",
cmd->min_delta_ftm);
pos += scnprintf(buf + pos, bufsz - pos,
- "ftm_format_and_bw20M = %hhx\n",
+ "ftm_format_and_bw20M = %hhd\n",
cmd->ftm_format_and_bw20M);
pos += scnprintf(buf + pos, bufsz - pos,</