aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/wireless/intel
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/net/wireless/intel')
-rw-r--r--drivers/net/wireless/intel/ipw2x00/Kconfig116
-rw-r--r--drivers/net/wireless/intel/ipw2x00/ipw2100.c2
-rw-r--r--drivers/net/wireless/intel/ipw2x00/ipw2200.c2
-rw-r--r--drivers/net/wireless/intel/iwlegacy/3945-mac.c1
-rw-r--r--drivers/net/wireless/intel/iwlegacy/4965-mac.c1
-rw-r--r--drivers/net/wireless/intel/iwlegacy/Kconfig6
-rw-r--r--drivers/net/wireless/intel/iwlegacy/common.c3
-rw-r--r--drivers/net/wireless/intel/iwlwifi/Kconfig20
-rw-r--r--drivers/net/wireless/intel/iwlwifi/cfg/1000.c14
-rw-r--r--drivers/net/wireless/intel/iwlwifi/cfg/2000.c26
-rw-r--r--drivers/net/wireless/intel/iwlwifi/cfg/22000.c70
-rw-r--r--drivers/net/wireless/intel/iwlwifi/cfg/5000.c18
-rw-r--r--drivers/net/wireless/intel/iwlwifi/cfg/6000.c44
-rw-r--r--drivers/net/wireless/intel/iwlwifi/cfg/7000.c10
-rw-r--r--drivers/net/wireless/intel/iwlwifi/cfg/8000.c10
-rw-r--r--drivers/net/wireless/intel/iwlwifi/cfg/9000.c10
-rw-r--r--drivers/net/wireless/intel/iwlwifi/dvm/devices.c3
-rw-r--r--drivers/net/wireless/intel/iwlwifi/dvm/led.c5
-rw-r--r--drivers/net/wireless/intel/iwlwifi/dvm/mac80211.c4
-rw-r--r--drivers/net/wireless/intel/iwlwifi/dvm/main.c12
-rw-r--r--drivers/net/wireless/intel/iwlwifi/dvm/power.c3
-rw-r--r--drivers/net/wireless/intel/iwlwifi/dvm/rs.c29
-rw-r--r--drivers/net/wireless/intel/iwlwifi/dvm/rs.h4
-rw-r--r--drivers/net/wireless/intel/iwlwifi/dvm/tx.c5
-rw-r--r--drivers/net/wireless/intel/iwlwifi/fw/acpi.c10
-rw-r--r--drivers/net/wireless/intel/iwlwifi/fw/acpi.h12
-rw-r--r--drivers/net/wireless/intel/iwlwifi/fw/api/commands.h7
-rw-r--r--drivers/net/wireless/intel/iwlwifi/fw/api/d3.h6
-rw-r--r--drivers/net/wireless/intel/iwlwifi/fw/api/dbg-tlv.h102
-rw-r--r--drivers/net/wireless/intel/iwlwifi/fw/api/debug.h83
-rw-r--r--drivers/net/wireless/intel/iwlwifi/fw/api/location.h4
-rw-r--r--drivers/net/wireless/intel/iwlwifi/fw/api/mac.h4
-rw-r--r--drivers/net/wireless/intel/iwlwifi/fw/api/phy.h7
-rw-r--r--drivers/net/wireless/intel/iwlwifi/fw/api/power.h12
-rw-r--r--drivers/net/wireless/intel/iwlwifi/fw/api/rs.h18
-rw-r--r--drivers/net/wireless/intel/iwlwifi/fw/api/rx.h32
-rw-r--r--drivers/net/wireless/intel/iwlwifi/fw/api/scan.h55
-rw-r--r--drivers/net/wireless/intel/iwlwifi/fw/dbg.c1156
-rw-r--r--drivers/net/wireless/intel/iwlwifi/fw/dbg.h121
-rw-r--r--drivers/net/wireless/intel/iwlwifi/fw/error-dump.h38
-rw-r--r--drivers/net/wireless/intel/iwlwifi/fw/file.h29
-rw-r--r--drivers/net/wireless/intel/iwlwifi/fw/img.h9
-rw-r--r--drivers/net/wireless/intel/iwlwifi/fw/init.c2
-rw-r--r--drivers/net/wireless/intel/iwlwifi/fw/paging.c6
-rw-r--r--drivers/net/wireless/intel/iwlwifi/fw/runtime.h23
-rw-r--r--drivers/net/wireless/intel/iwlwifi/fw/smem.c2
-rw-r--r--drivers/net/wireless/intel/iwlwifi/iwl-config.h53
-rw-r--r--drivers/net/wireless/intel/iwlwifi/iwl-dbg-tlv.c236
-rw-r--r--drivers/net/wireless/intel/iwlwifi/iwl-dbg-tlv.h36
-rw-r--r--drivers/net/wireless/intel/iwlwifi/iwl-devtrace.h1
-rw-r--r--drivers/net/wireless/intel/iwlwifi/iwl-drv.c30
-rw-r--r--drivers/net/wireless/intel/iwlwifi/iwl-eeprom-parse.c21
-rw-r--r--drivers/net/wireless/intel/iwlwifi/iwl-eeprom-parse.h4
-rw-r--r--drivers/net/wireless/intel/iwlwifi/iwl-eeprom-read.c14
-rw-r--r--drivers/net/wireless/intel/iwlwifi/iwl-fh.h6
-rw-r--r--drivers/net/wireless/intel/iwlwifi/iwl-io.c21
-rw-r--r--drivers/net/wireless/intel/iwlwifi/iwl-io.h18
-rw-r--r--drivers/net/wireless/intel/iwlwifi/iwl-modparams.h9
-rw-r--r--drivers/net/wireless/intel/iwlwifi/iwl-nvm-parse.c60
-rw-r--r--drivers/net/wireless/intel/iwlwifi/iwl-op-mode.h27
-rw-r--r--drivers/net/wireless/intel/iwlwifi/iwl-prph.h5
-rw-r--r--drivers/net/wireless/intel/iwlwifi/iwl-trans.c16
-rw-r--r--drivers/net/wireless/intel/iwlwifi/iwl-trans.h150
-rw-r--r--drivers/net/wireless/intel/iwlwifi/mvm/constants.h1
-rw-r--r--drivers/net/wireless/intel/iwlwifi/mvm/d3.c224
-rw-r--r--drivers/net/wireless/intel/iwlwifi/mvm/debugfs.c154
-rw-r--r--drivers/net/wireless/intel/iwlwifi/mvm/fw.c222
-rw-r--r--drivers/net/wireless/intel/iwlwifi/mvm/led.c6
-rw-r--r--drivers/net/wireless/intel/iwlwifi/mvm/mac-ctxt.c42
-rw-r--r--drivers/net/wireless/intel/iwlwifi/mvm/mac80211.c446
-rw-r--r--drivers/net/wireless/intel/iwlwifi/mvm/mvm.h150
-rw-r--r--drivers/net/wireless/intel/iwlwifi/mvm/nvm.c4
-rw-r--r--drivers/net/wireless/intel/iwlwifi/mvm/ops.c480
-rw-r--r--drivers/net/wireless/intel/iwlwifi/mvm/phy-ctxt.c11
-rw-r--r--drivers/net/wireless/intel/iwlwifi/mvm/power.c82
-rw-r--r--drivers/net/wireless/intel/iwlwifi/mvm/rs-fw.c19
-rw-r--r--drivers/net/wireless/intel/iwlwifi/mvm/rs.c13
-rw-r--r--drivers/net/wireless/intel/iwlwifi/mvm/rx.c18
-rw-r--r--drivers/net/wireless/intel/iwlwifi/mvm/rxmq.c115
-rw-r--r--drivers/net/wireless/intel/iwlwifi/mvm/scan.c98
-rw-r--r--drivers/net/wireless/intel/iwlwifi/mvm/sta.c29
-rw-r--r--drivers/net/wireless/intel/iwlwifi/mvm/tdls.c9
-rw-r--r--drivers/net/wireless/intel/iwlwifi/mvm/time-event.c8
-rw-r--r--drivers/net/wireless/intel/iwlwifi/mvm/tt.c21
-rw-r--r--drivers/net/wireless/intel/iwlwifi/mvm/tx.c9
-rw-r--r--drivers/net/wireless/intel/iwlwifi/mvm/utils.c19
-rw-r--r--drivers/net/wireless/intel/iwlwifi/pcie/ctxt-info-gen3.c40
-rw-r--r--drivers/net/wireless/intel/iwlwifi/pcie/drv.c601
-rw-r--r--drivers/net/wireless/intel/iwlwifi/pcie/internal.h38
-rw-r--r--drivers/net/wireless/intel/iwlwifi/pcie/rx.c77
-rw-r--r--drivers/net/wireless/intel/iwlwifi/pcie/trans-gen2.c19
-rw-r--r--drivers/net/wireless/intel/iwlwifi/pcie/trans.c410
-rw-r--r--drivers/net/wireless/intel/iwlwifi/pcie/tx-gen2.c70
-rw-r--r--drivers/net/wireless/intel/iwlwifi/pcie/tx.c176
94 files changed, 2562 insertions, 3912 deletions
diff --git a/drivers/net/wireless/intel/ipw2x00/Kconfig b/drivers/net/wireless/intel/ipw2x00/Kconfig
index 5d2878a73732..ab17903ba9f8 100644
--- a/drivers/net/wireless/intel/ipw2x00/Kconfig
+++ b/drivers/net/wireless/intel/ipw2x00/Kconfig
@@ -13,37 +13,37 @@ config IPW2100
select LIB80211
select LIBIPW
---help---
- A driver for the Intel PRO/Wireless 2100 Network
+ A driver for the Intel PRO/Wireless 2100 Network
Connection 802.11b wireless network adapter.
- See <file:Documentation/networking/device_drivers/intel/ipw2100.txt>
+ See <file:Documentation/networking/device_drivers/intel/ipw2100.txt>
for information on the capabilities currently enabled in this driver
and for tips for debugging issues and problems.
In order to use this driver, you will need a firmware image for it.
- You can obtain the firmware from
- <http://ipw2100.sf.net/>. Once you have the firmware image, you
+ You can obtain the firmware from
+ <http://ipw2100.sf.net/>. Once you have the firmware image, you
will need to place it in /lib/firmware.
- You will also very likely need the Wireless Tools in order to
- configure your card:
+ You will also very likely need the Wireless Tools in order to
+ configure your card:
- <http://www.hpl.hp.com/personal/Jean_Tourrilhes/Linux/Tools.html>.
+ <http://www.hpl.hp.com/personal/Jean_Tourrilhes/Linux/Tools.html>.
+
+ It is recommended that you compile this driver as a module (M)
+ rather than built-in (Y). This driver requires firmware at device
+ initialization time, and when built-in this typically happens
+ before the filesystem is accessible (hence firmware will be
+ unavailable and initialization will fail). If you do choose to build
+ this driver into your kernel image, you can avoid this problem by
+ including the firmware and a firmware loader in an initramfs.
- It is recommended that you compile this driver as a module (M)
- rather than built-in (Y). This driver requires firmware at device
- initialization time, and when built-in this typically happens
- before the filesystem is accessible (hence firmware will be
- unavailable and initialization will fail). If you do choose to build
- this driver into your kernel image, you can avoid this problem by
- including the firmware and a firmware loader in an initramfs.
-
config IPW2100_MONITOR
- bool "Enable promiscuous mode"
- depends on IPW2100
- ---help---
+ bool "Enable promiscuous mode"
+ depends on IPW2100
+ ---help---
Enables promiscuous/monitor mode support for the ipw2100 driver.
- With this feature compiled into the driver, you can switch to
+ With this feature compiled into the driver, you can switch to
promiscuous mode via the Wireless Tool's Monitor mode. While in this
mode, no packets can be sent.
@@ -51,17 +51,17 @@ config IPW2100_DEBUG
bool "Enable full debugging output in IPW2100 module."
depends on IPW2100
---help---
- This option will enable debug tracing output for the IPW2100.
+ This option will enable debug tracing output for the IPW2100.
- This will result in the kernel module being ~60k larger. You can
- control which debug output is sent to the kernel log by setting the
- value in
+ This will result in the kernel module being ~60k larger. You can
+ control which debug output is sent to the kernel log by setting the
+ value in
/sys/bus/pci/drivers/ipw2100/debug_level
This entry will only exist if this option is enabled.
- If you are not trying to debug or develop the IPW2100 driver, you
+ If you are not trying to debug or develop the IPW2100 driver, you
most likely want to say N here.
config IPW2200
@@ -75,37 +75,37 @@ config IPW2200
select LIB80211
select LIBIPW
---help---
- A driver for the Intel PRO/Wireless 2200BG and 2915ABG Network
- Connection adapters.
+ A driver for the Intel PRO/Wireless 2200BG and 2915ABG Network
+ Connection adapters.
- See <file:Documentation/networking/device_drivers/intel/ipw2200.txt>
+ See <file:Documentation/networking/device_drivers/intel/ipw2200.txt>
for information on the capabilities currently enabled in this
driver and for tips for debugging issues and problems.
In order to use this driver, you will need a firmware image for it.
- You can obtain the firmware from
- <http://ipw2200.sf.net/>. See the above referenced README.ipw2200
+ You can obtain the firmware from
+ <http://ipw2200.sf.net/>. See the above referenced README.ipw2200
for information on where to install the firmware images.
- You will also very likely need the Wireless Tools in order to
- configure your card:
+ You will also very likely need the Wireless Tools in order to
+ configure your card:
- <http://www.hpl.hp.com/personal/Jean_Tourrilhes/Linux/Tools.html>.
+ <http://www.hpl.hp.com/personal/Jean_Tourrilhes/Linux/Tools.html>.
- It is recommended that you compile this driver as a module (M)
- rather than built-in (Y). This driver requires firmware at device
- initialization time, and when built-in this typically happens
- before the filesystem is accessible (hence firmware will be
- unavailable and initialization will fail). If you do choose to build
- this driver into your kernel image, you can avoid this problem by
- including the firmware and a firmware loader in an initramfs.
+ It is recommended that you compile this driver as a module (M)
+ rather than built-in (Y). This driver requires firmware at device
+ initialization time, and when built-in this typically happens
+ before the filesystem is accessible (hence firmware will be
+ unavailable and initialization will fail). If you do choose to build
+ this driver into your kernel image, you can avoid this problem by
+ including the firmware and a firmware loader in an initramfs.
config IPW2200_MONITOR
- bool "Enable promiscuous mode"
- depends on IPW2200
- ---help---
+ bool "Enable promiscuous mode"
+ depends on IPW2200
+ ---help---
Enables promiscuous/monitor mode support for the ipw2200 driver.
- With this feature compiled into the driver, you can switch to
+ With this feature compiled into the driver, you can switch to
promiscuous mode via the Wireless Tool's Monitor mode. While in this
mode, no packets can be sent.
@@ -118,28 +118,28 @@ config IPW2200_PROMISCUOUS
depends on IPW2200_MONITOR
select IPW2200_RADIOTAP
---help---
- Enables the creation of a second interface prefixed 'rtap'.
- This second interface will provide every received in radiotap
+ Enables the creation of a second interface prefixed 'rtap'.
+ This second interface will provide every received in radiotap
format.
- This is useful for performing wireless network analysis while
- maintaining an active association.
+ This is useful for performing wireless network analysis while
+ maintaining an active association.
+
+ Example usage:
- Example usage:
+ % modprobe ipw2200 rtap_iface=1
+ % ifconfig rtap0 up
+ % tethereal -i rtap0
- % modprobe ipw2200 rtap_iface=1
- % ifconfig rtap0 up
- % tethereal -i rtap0
+ If you do not specify 'rtap_iface=1' as a module parameter then
+ the rtap interface will not be created and you will need to turn
+ it on via sysfs:
- If you do not specify 'rtap_iface=1' as a module parameter then
- the rtap interface will not be created and you will need to turn
- it on via sysfs:
-
- % echo 1 > /sys/bus/pci/drivers/ipw2200/*/rtap_iface
+ % echo 1 > /sys/bus/pci/drivers/ipw2200/*/rtap_iface
config IPW2200_QOS
- bool "Enable QoS support"
- depends on IPW2200
+ bool "Enable QoS support"
+ depends on IPW2200
config IPW2200_DEBUG
bool "Enable full debugging output in IPW2200 module."
diff --git a/drivers/net/wireless/intel/ipw2x00/ipw2100.c b/drivers/net/wireless/intel/ipw2x00/ipw2100.c
index 75c0c29d81f0..8dfbaff2d1fe 100644
--- a/drivers/net/wireless/intel/ipw2x00/ipw2100.c
+++ b/drivers/net/wireless/intel/ipw2x00/ipw2100.c
@@ -4413,7 +4413,7 @@ static void ipw2100_kill_works(struct ipw2100_priv *priv)
static int ipw2100_tx_allocate(struct ipw2100_priv *priv)
{
- int i, j, err = -EINVAL;
+ int i, j, err;
void *v;
dma_addr_t p;
diff --git a/drivers/net/wireless/intel/ipw2x00/ipw2200.c b/drivers/net/wireless/intel/ipw2x00/ipw2200.c
index fa55d2ccbfab..ed0f06532d5e 100644
--- a/drivers/net/wireless/intel/ipw2x00/ipw2200.c
+++ b/drivers/net/wireless/intel/ipw2x00/ipw2200.c
@@ -2721,7 +2721,7 @@ static void ipw_eeprom_init_sram(struct ipw_priv *priv)
/* Do not load eeprom data on fatal error or suspend */
ipw_write32(priv, IPW_EEPROM_LOAD_DISABLE, 0);
} else {
- IPW_DEBUG_INFO("Enabling FW initializationg of SRAM\n");
+ IPW_DEBUG_INFO("Enabling FW initialization of SRAM\n");
/* Load eeprom data on fatal error or suspend */
ipw_write32(priv, IPW_EEPROM_LOAD_DISABLE, 1);
diff --git a/drivers/net/wireless/intel/iwlegacy/3945-mac.c b/drivers/net/wireless/intel/iwlegacy/3945-mac.c
index b82da75a9ae3..4fbcc7fba3cc 100644
--- a/drivers/net/wireless/intel/iwlegacy/3945-mac.c
+++ b/drivers/net/wireless/intel/iwlegacy/3945-mac.c
@@ -18,7 +18,6 @@
#include <linux/module.h>
#include <linux/init.h>
#include <linux/pci.h>
-#include <linux/pci-aspm.h>
#include <linux/slab.h>
#include <linux/dma-mapping.h>
#include <linux/delay.h>
diff --git a/drivers/net/wireless/intel/iwlegacy/4965-mac.c b/drivers/net/wireless/intel/iwlegacy/4965-mac.c
index fa2c02881939..ffb705b18fb1 100644
--- a/drivers/net/wireless/intel/iwlegacy/4965-mac.c
+++ b/drivers/net/wireless/intel/iwlegacy/4965-mac.c
@@ -18,7 +18,6 @@
#include <linux/module.h>
#include <linux/init.h>
#include <linux/pci.h>
-#include <linux/pci-aspm.h>
#include <linux/slab.h>
#include <linux/dma-mapping.h>
#include <linux/delay.h>
diff --git a/drivers/net/wireless/intel/iwlegacy/Kconfig b/drivers/net/wireless/intel/iwlegacy/Kconfig
index e329fd7b09c0..100f55858b13 100644
--- a/drivers/net/wireless/intel/iwlegacy/Kconfig
+++ b/drivers/net/wireless/intel/iwlegacy/Kconfig
@@ -91,9 +91,9 @@ config IWLEGACY_DEBUG
any problems you may encounter.
config IWLEGACY_DEBUGFS
- bool "iwlegacy (iwl 3945/4965) debugfs support"
- depends on IWLEGACY && MAC80211_DEBUGFS
- ---help---
+ bool "iwlegacy (iwl 3945/4965) debugfs support"
+ depends on IWLEGACY && MAC80211_DEBUGFS
+ ---help---
Enable creation of debugfs files for the iwlegacy drivers. This
is a low-impact option that allows getting insight into the
driver's state at runtime.
diff --git a/drivers/net/wireless/intel/iwlegacy/common.c b/drivers/net/wireless/intel/iwlegacy/common.c
index 4a88e35d58d7..73f7bbf742bc 100644
--- a/drivers/net/wireless/intel/iwlegacy/common.c
+++ b/drivers/net/wireless/intel/iwlegacy/common.c
@@ -4942,8 +4942,7 @@ EXPORT_SYMBOL(il_add_beacon_time);
static int
il_pci_suspend(struct device *device)
{
- struct pci_dev *pdev = to_pci_dev(device);
- struct il_priv *il = pci_get_drvdata(pdev);
+ struct il_priv *il = dev_get_drvdata(device);
/*
* This function is called when system goes into suspend state
diff --git a/drivers/net/wireless/intel/iwlwifi/Kconfig b/drivers/net/wireless/intel/iwlwifi/Kconfig
index 235349a33a3c..091d621ad25f 100644
--- a/drivers/net/wireless/intel/iwlwifi/Kconfig
+++ b/drivers/net/wireless/intel/iwlwifi/Kconfig
@@ -92,20 +92,6 @@ config IWLWIFI_BCAST_FILTERING
If unsure, don't enable this option, as some programs might
expect incoming broadcasts for their normal operations.
-config IWLWIFI_PCIE_RTPM
- bool "Enable runtime power management mode for PCIe devices"
- depends on IWLMVM && PM && EXPERT
- help
- Say Y here to enable runtime power management for PCIe
- devices. If enabled, the device will go into low power mode
- when idle for a short period of time, allowing for improved
- power saving during runtime. Note that this feature requires
- a tight integration with the platform. It is not recommended
- to enable this feature without proper validation with the
- specific target platform.
-
- If unsure, say N.
-
menu "Debugging Options"
config IWLWIFI_DEBUG
@@ -133,9 +119,9 @@ config IWLWIFI_DEBUG
any problems you may encounter.
config IWLWIFI_DEBUGFS
- bool "iwlwifi debugfs support"
- depends on MAC80211_DEBUGFS
- ---help---
+ bool "iwlwifi debugfs support"
+ depends on MAC80211_DEBUGFS
+ ---help---
Enable creation of debugfs files for the iwlwifi drivers. This
is a low-impact option that allows getting insight into the
driver's state at runtime.
diff --git a/drivers/net/wireless/intel/iwlwifi/cfg/1000.c b/drivers/net/wireless/intel/iwlwifi/cfg/1000.c
index a1aa2956b382..b92255b91b72 100644
--- a/drivers/net/wireless/intel/iwlwifi/cfg/1000.c
+++ b/drivers/net/wireless/intel/iwlwifi/cfg/1000.c
@@ -2,7 +2,7 @@
/******************************************************************************
*
* Copyright(c) 2008 - 2014 Intel Corporation. All rights reserved.
- * Copyright(c) 2018 Intel Corporation
+ * Copyright(c) 2018 - 2019 Intel Corporation
*
* Contact Information:
* Intel Linux Wireless <linuxwifi@intel.com>
@@ -69,16 +69,16 @@ static const struct iwl_eeprom_params iwl1000_eeprom_params = {
.fw_name_pre = IWL1000_FW_PRE, \
.ucode_api_max = IWL1000_UCODE_API_MAX, \
.ucode_api_min = IWL1000_UCODE_API_MIN, \
- .device_family = IWL_DEVICE_FAMILY_1000, \
+ .trans.device_family = IWL_DEVICE_FAMILY_1000, \
.max_inst_size = IWLAGN_RTC_INST_SIZE, \
.max_data_size = IWLAGN_RTC_DATA_SIZE, \
.nvm_ver = EEPROM_1000_EEPROM_VERSION, \
.nvm_calib_ver = EEPROM_1000_TX_POWER_VERSION, \
- .base_params = &iwl1000_base_params, \
+ .trans.base_params = &iwl1000_base_params, \
.eeprom_params = &iwl1000_eeprom_params, \
.led_mode = IWL_LED_BLINK, \
.max_ht_ampdu_exponent = IEEE80211_HT_MAX_AMPDU_64K, \
- .csr = &iwl_csr_v1
+ .trans.csr = &iwl_csr_v1
const struct iwl_cfg iwl1000_bgn_cfg = {
.name = "Intel(R) Centrino(R) Wireless-N 1000 BGN",
@@ -95,17 +95,17 @@ const struct iwl_cfg iwl1000_bg_cfg = {
.fw_name_pre = IWL100_FW_PRE, \
.ucode_api_max = IWL100_UCODE_API_MAX, \
.ucode_api_min = IWL100_UCODE_API_MIN, \
- .device_family = IWL_DEVICE_FAMILY_100, \
+ .trans.device_family = IWL_DEVICE_FAMILY_100, \
.max_inst_size = IWLAGN_RTC_INST_SIZE, \
.max_data_size = IWLAGN_RTC_DATA_SIZE, \
.nvm_ver = EEPROM_1000_EEPROM_VERSION, \
.nvm_calib_ver = EEPROM_1000_TX_POWER_VERSION, \
- .base_params = &iwl1000_base_params, \
+ .trans.base_params = &iwl1000_base_params, \
.eeprom_params = &iwl1000_eeprom_params, \
.led_mode = IWL_LED_RF_STATE, \
.rx_with_siso_diversity = true, \
.max_ht_ampdu_exponent = IEEE80211_HT_MAX_AMPDU_64K, \
- .csr = &iwl_csr_v1
+ .trans.csr = &iwl_csr_v1
const struct iwl_cfg iwl100_bgn_cfg = {
.name = "Intel(R) Centrino(R) Wireless-N 100 BGN",
diff --git a/drivers/net/wireless/intel/iwlwifi/cfg/2000.c b/drivers/net/wireless/intel/iwlwifi/cfg/2000.c
index 4a988b676913..2b1ae0cecc83 100644
--- a/drivers/net/wireless/intel/iwlwifi/cfg/2000.c
+++ b/drivers/net/wireless/intel/iwlwifi/cfg/2000.c
@@ -2,7 +2,7 @@
/******************************************************************************
*
* Copyright(c) 2008 - 2014 Intel Corporation. All rights reserved.
- * Copyright(c) 2018 Intel Corporation
+ * Copyright(c) 2018 - 2019 Intel Corporation
*
* Contact Information:
* Intel Linux Wireless <linuxwifi@intel.com>
@@ -95,16 +95,16 @@ static const struct iwl_eeprom_params iwl20x0_eeprom_params = {
.fw_name_pre = IWL2000_FW_PRE, \
.ucode_api_max = IWL2000_UCODE_API_MAX, \
.ucode_api_min = IWL2000_UCODE_API_MIN, \
- .device_family = IWL_DEVICE_FAMILY_2000, \
+ .trans.device_family = IWL_DEVICE_FAMILY_2000, \
.max_inst_size = IWL60_RTC_INST_SIZE, \
.max_data_size = IWL60_RTC_DATA_SIZE, \
.nvm_ver = EEPROM_2000_EEPROM_VERSION, \
.nvm_calib_ver = EEPROM_2000_TX_POWER_VERSION, \
- .base_params = &iwl2000_base_params, \
+ .trans.base_params = &iwl2000_base_params, \
.eeprom_params = &iwl20x0_eeprom_params, \
.led_mode = IWL_LED_RF_STATE, \
.max_ht_ampdu_exponent = IEEE80211_HT_MAX_AMPDU_64K, \
- .csr = &iwl_csr_v1
+ .trans.csr = &iwl_csr_v1
const struct iwl_cfg iwl2000_2bgn_cfg = {
@@ -123,16 +123,16 @@ const struct iwl_cfg iwl2000_2bgn_d_cfg = {
.fw_name_pre = IWL2030_FW_PRE, \
.ucode_api_max = IWL2030_UCODE_API_MAX, \
.ucode_api_min = IWL2030_UCODE_API_MIN, \
- .device_family = IWL_DEVICE_FAMILY_2030, \
+ .trans.device_family = IWL_DEVICE_FAMILY_2030, \
.max_inst_size = IWL60_RTC_INST_SIZE, \
.max_data_size = IWL60_RTC_DATA_SIZE, \
.nvm_ver = EEPROM_2000_EEPROM_VERSION, \
.nvm_calib_ver = EEPROM_2000_TX_POWER_VERSION, \
- .base_params = &iwl2030_base_params, \
+ .trans.base_params = &iwl2030_base_params, \
.eeprom_params = &iwl20x0_eeprom_params, \
.led_mode = IWL_LED_RF_STATE, \
.max_ht_ampdu_exponent = IEEE80211_HT_MAX_AMPDU_64K, \
- .csr = &iwl_csr_v1
+ .trans.csr = &iwl_csr_v1
const struct iwl_cfg iwl2030_2bgn_cfg = {
.name = "Intel(R) Centrino(R) Wireless-N 2230 BGN",
@@ -144,17 +144,17 @@ const struct iwl_cfg iwl2030_2bgn_cfg = {
.fw_name_pre = IWL105_FW_PRE, \
.ucode_api_max = IWL105_UCODE_API_MAX, \
.ucode_api_min = IWL105_UCODE_API_MIN, \
- .device_family = IWL_DEVICE_FAMILY_105, \
+ .trans.device_family = IWL_DEVICE_FAMILY_105, \
.max_inst_size = IWL60_RTC_INST_SIZE, \
.max_data_size = IWL60_RTC_DATA_SIZE, \
.nvm_ver = EEPROM_2000_EEPROM_VERSION, \
.nvm_calib_ver = EEPROM_2000_TX_POWER_VERSION, \
- .base_params = &iwl2000_base_params, \
+ .trans.base_params = &iwl2000_base_params, \
.eeprom_params = &iwl20x0_eeprom_params, \
.led_mode = IWL_LED_RF_STATE, \
.rx_with_siso_diversity = true, \
.max_ht_ampdu_exponent = IEEE80211_HT_MAX_AMPDU_64K, \
- .csr = &iwl_csr_v1
+ .trans.csr = &iwl_csr_v1
const struct iwl_cfg iwl105_bgn_cfg = {
.name = "Intel(R) Centrino(R) Wireless-N 105 BGN",
@@ -172,17 +172,17 @@ const struct iwl_cfg iwl105_bgn_d_cfg = {
.fw_name_pre = IWL135_FW_PRE, \
.ucode_api_max = IWL135_UCODE_API_MAX, \
.ucode_api_min = IWL135_UCODE_API_MIN, \
- .device_family = IWL_DEVICE_FAMILY_135, \
+ .trans.device_family = IWL_DEVICE_FAMILY_135, \
.max_inst_size = IWL60_RTC_INST_SIZE, \
.max_data_size = IWL60_RTC_DATA_SIZE, \
.nvm_ver = EEPROM_2000_EEPROM_VERSION, \
.nvm_calib_ver = EEPROM_2000_TX_POWER_VERSION, \
- .base_params = &iwl2030_base_params, \
+ .trans.base_params = &iwl2030_base_params, \
.eeprom_params = &iwl20x0_eeprom_params, \
.led_mode = IWL_LED_RF_STATE, \
.rx_with_siso_diversity = true, \
.max_ht_ampdu_exponent = IEEE80211_HT_MAX_AMPDU_64K, \
- .csr = &iwl_csr_v1
+ .trans.csr = &iwl_csr_v1
const struct iwl_cfg iwl135_bgn_cfg = {
.name = "Intel(R) Centrino(R) Wireless-N 135 BGN",
diff --git a/drivers/net/wireless/intel/iwlwifi/cfg/22000.c b/drivers/net/wireless/intel/iwlwifi/cfg/22000.c
index 1f500cddb3a7..5e355c4957df 100644
--- a/drivers/net/wireless/intel/iwlwifi/cfg/22000.c
+++ b/drivers/net/wireless/intel/iwlwifi/cfg/22000.c
@@ -56,7 +56,7 @@
#include "iwl-config.h"
/* Highest firmware API version supported */
-#define IWL_22000_UCODE_API_MAX 48
+#define IWL_22000_UCODE_API_MAX 50
/* Lowest firmware API version supported */
#define IWL_22000_UCODE_API_MIN 39
@@ -76,7 +76,6 @@
#define IWL_22000_HR_FW_PRE "iwlwifi-Qu-a0-hr-a0-"
#define IWL_22000_HR_CDB_FW_PRE "iwlwifi-QuIcp-z0-hrcdb-a0-"
#define IWL_22000_HR_A_F0_FW_PRE "iwlwifi-QuQnj-f0-hr-a0-"
-#define IWL_22000_HR_B_F0_FW_PRE "iwlwifi-Qu-b0-hr-b0-"
#define IWL_22000_QU_B_HR_B_FW_PRE "iwlwifi-Qu-b0-hr-b0-"
#define IWL_22000_HR_B_FW_PRE "iwlwifi-QuQnj-b0-hr-b0-"
#define IWL_22000_HR_A0_FW_PRE "iwlwifi-QuQnj-a0-hr-a0-"
@@ -99,8 +98,6 @@
IWL_22000_JF_FW_PRE __stringify(api) ".ucode"
#define IWL_22000_HR_A_F0_QNJ_MODULE_FIRMWARE(api) \
IWL_22000_HR_A_F0_FW_PRE __stringify(api) ".ucode"
-#define IWL_22000_HR_B_F0_QNJ_MODULE_FIRMWARE(api) \
- IWL_22000_HR_B_F0_FW_PRE __stringify(api) ".ucode"
#define IWL_22000_QU_B_HR_B_MODULE_FIRMWARE(api) \
IWL_22000_QU_B_HR_B_FW_PRE __stringify(api) ".ucode"
#define IWL_22000_HR_B_QNJ_MODULE_FIRMWARE(api) \
@@ -172,15 +169,15 @@ static const struct iwl_ht_params iwl_22000_ht_params = {
.smem_len = IWL_22000_SMEM_LEN, \
.features = IWL_TX_CSUM_NETIF_FLAGS | NETIF_F_RXCSUM, \
.apmg_not_supported = true, \
- .mq_rx_supported = true, \
+ .trans.mq_rx_supported = true, \
.vht_mu_mimo_supported = true, \
.mac_addr_from_csr = true, \
.ht_params = &iwl_22000_ht_params, \
.nvm_ver = IWL_22000_NVM_VERSION, \
.max_ht_ampdu_exponent = IEEE80211_HT_MAX_AMPDU_64K, \
- .use_tfh = true, \
- .rf_id = true, \
- .gen2 = true, \
+ .trans.use_tfh = true, \
+ .trans.rf_id = true, \
+ .trans.gen2 = true, \
.nvm_type = IWL_NVM_EXT, \
.dbgc_supported = true, \
.min_umac_error_event_table = 0x400000, \
@@ -191,28 +188,25 @@ static const struct iwl_ht_params iwl_22000_ht_params = {
.fw_mon_smem_cycle_cnt_ptr_addr = 0xa0c174, \
.fw_mon_smem_cycle_cnt_ptr_msk = 0xfffff
-#define IWL_DEVICE_AX200_COMMON \
- IWL_DEVICE_22000_COMMON, \
- .umac_prph_offset = 0x300000
-
#define IWL_DEVICE_22500 \
IWL_DEVICE_22000_COMMON, \
- .device_family = IWL_DEVICE_FAMILY_22000, \
- .base_params = &iwl_22000_base_params, \
- .csr = &iwl_csr_v1, \
+ .trans.device_family = IWL_DEVICE_FAMILY_22000, \
+ .trans.base_params = &iwl_22000_base_params, \
+ .trans.csr = &iwl_csr_v1, \
.gp2_reg_addr = 0xa02c68
#define IWL_DEVICE_22560 \
IWL_DEVICE_22000_COMMON, \
- .device_family = IWL_DEVICE_FAMILY_22560, \
- .base_params = &iwl_22560_base_params, \
- .csr = &iwl_csr_v2
+ .trans.device_family = IWL_DEVICE_FAMILY_22560, \
+ .trans.base_params = &iwl_22560_base_params, \
+ .trans.csr = &iwl_csr_v2
#define IWL_DEVICE_AX210 \
- IWL_DEVICE_AX200_COMMON, \
- .device_family = IWL_DEVICE_FAMILY_AX210, \
- .base_params = &iwl_22560_base_params, \
- .csr = &iwl_csr_v1, \
+ IWL_DEVICE_22000_COMMON, \
+ .trans.umac_prph_offset = 0x300000, \
+ .trans.device_family = IWL_DEVICE_FAMILY_AX210, \
+ .trans.base_params = &iwl_22560_base_params, \
+ .trans.csr = &iwl_csr_v1, \
.min_txq_size = 128, \
.gp2_reg_addr = 0xd02c68, \
.min_256_ba_txq_size = 512
@@ -246,6 +240,7 @@ const struct iwl_cfg iwl_ax101_cfg_qu_hr = {
* HT size; mac80211 would otherwise pick the HE max (256) by default.
*/
.max_tx_agg_size = IEEE80211_MAX_AMPDU_BUF_HT,
+ .tx_with_siso_diversity = true,
};
const struct iwl_cfg iwl_ax201_cfg_qu_hr = {
@@ -342,7 +337,7 @@ const struct iwl_cfg iwl_ax200_cfg_cc = {
* HT size; mac80211 would otherwise pick the HE max (256) by default.
*/
.max_tx_agg_size = IEEE80211_MAX_AMPDU_BUF_HT,
- .bisr_workaround = 1,
+ .trans.bisr_workaround = 1,
};
const struct iwl_cfg killer1650x_2ax_cfg = {
@@ -355,7 +350,7 @@ const struct iwl_cfg killer1650x_2ax_cfg = {
* HT size; mac80211 would otherwise pick the HE max (256) by default.
*/
.max_tx_agg_size = IEEE80211_MAX_AMPDU_BUF_HT,
- .bisr_workaround = 1,
+ .trans.bisr_workaround = 1,
};
const struct iwl_cfg killer1650w_2ax_cfg = {
@@ -368,7 +363,7 @@ const struct iwl_cfg killer1650w_2ax_cfg = {
* HT size; mac80211 would otherwise pick the HE max (256) by default.
*/
.max_tx_agg_size = IEEE80211_MAX_AMPDU_BUF_HT,
- .bisr_workaround = 1,
+ .trans.bisr_workaround = 1,
};
/*
@@ -556,6 +551,30 @@ const struct iwl_cfg killer1650i_2ax_cfg_qu_b0_hr_b0 = {
.max_tx_agg_size = IEEE80211_MAX_AMPDU_BUF_HT,
};
+const struct iwl_cfg killer1650s_2ax_cfg_qu_c0_hr_b0 = {
+ .name = "Killer(R) Wi-Fi 6 AX1650i 160MHz Wireless Network Adapter (201NGW)",
+ .fw_name_pre = IWL_QU_C_HR_B_FW_PRE,
+ IWL_DEVICE_22500,
+ /*
+ * This device doesn't support receiving BlockAck with a large bitmap
+ * so we need to restrict the size of transmitted aggregation to the
+ * HT size; mac80211 would otherwise pick the HE max (256) by default.
+ */
+ .max_tx_agg_size = IEEE80211_MAX_AMPDU_BUF_HT,
+};
+
+const struct iwl_cfg killer1650i_2ax_cfg_qu_c0_hr_b0 = {
+ .name = "Killer(R) Wi-Fi 6 AX1650s 160MHz Wireless Network Adapter (201D2W)",
+ .fw_name_pre = IWL_QU_C_HR_B_FW_PRE,
+ IWL_DEVICE_22500,
+ /*
+ * This device doesn't support receiving BlockAck with a large bitmap
+ * so we need to restrict the size of transmitted aggregation to the
+ * HT size; mac80211 would otherwise pick the HE max (256) by default.
+ */
+ .max_tx_agg_size = IEEE80211_MAX_AMPDU_BUF_HT,
+};
+
const struct iwl_cfg iwl22000_2ax_cfg_jf = {
.name = "Intel(R) Dual Band Wireless AX 22000",
.fw_name_pre = IWL_QU_B_JF_B_FW_PRE,
@@ -639,7 +658,6 @@ const struct iwl_cfg iwlax411_2ax_cfg_so_gf4_a0 = {
MODULE_FIRMWARE(IWL_22000_HR_MODULE_FIRMWARE(IWL_22000_UCODE_API_MAX));
MODULE_FIRMWARE(IWL_22000_JF_MODULE_FIRMWARE(IWL_22000_UCODE_API_MAX));
MODULE_FIRMWARE(IWL_22000_HR_A_F0_QNJ_MODULE_FIRMWARE(IWL_22000_UCODE_API_MAX));
-MODULE_FIRMWARE(IWL_22000_HR_B_F0_QNJ_MODULE_FIRMWARE(IWL_22000_UCODE_API_MAX));
MODULE_FIRMWARE(IWL_22000_HR_B_QNJ_MODULE_FIRMWARE(IWL_22000_UCODE_API_MAX));
MODULE_FIRMWARE(IWL_22000_HR_A0_QNJ_MODULE_FIRMWARE(IWL_22000_UCODE_API_MAX));
MODULE_FIRMWARE(IWL_QU_C_HR_B_MODULE_FIRMWARE(IWL_22000_UCODE_API_MAX));
diff --git a/drivers/net/wireless/intel/iwlwifi/cfg/5000.c b/drivers/net/wireless/intel/iwlwifi/cfg/5000.c
index ce25c690d69c..aab4495c6085 100644
--- a/drivers/net/wireless/intel/iwlwifi/cfg/5000.c
+++ b/drivers/net/wireless/intel/iwlwifi/cfg/5000.c
@@ -67,16 +67,16 @@ static const struct iwl_eeprom_params iwl5000_eeprom_params = {
.fw_name_pre = IWL5000_FW_PRE, \
.ucode_api_max = IWL5000_UCODE_API_MAX, \
.ucode_api_min = IWL5000_UCODE_API_MIN, \
- .device_family = IWL_DEVICE_FAMILY_5000, \
+ .trans.device_family = IWL_DEVICE_FAMILY_5000, \
.max_inst_size = IWLAGN_RTC_INST_SIZE, \
.max_data_size = IWLAGN_RTC_DATA_SIZE, \
.nvm_ver = EEPROM_5000_EEPROM_VERSION, \
.nvm_calib_ver = EEPROM_5000_TX_POWER_VERSION, \
- .base_params = &iwl5000_base_params, \
+ .trans.base_params = &iwl5000_base_params, \
.eeprom_params = &iwl5000_eeprom_params, \
.led_mode = IWL_LED_BLINK, \
.max_ht_ampdu_exponent = IEEE80211_HT_MAX_AMPDU_64K, \
- .csr = &iwl_csr_v1
+ .trans.csr = &iwl_csr_v1
const struct iwl_cfg iwl5300_agn_cfg = {
.name = "Intel(R) Ultimate N WiFi Link 5300 AGN",
@@ -115,34 +115,34 @@ const struct iwl_cfg iwl5350_agn_cfg = {
.fw_name_pre = IWL5000_FW_PRE,
.ucode_api_max = IWL5000_UCODE_API_MAX,
.ucode_api_min = IWL5000_UCODE_API_MIN,
- .device_family = IWL_DEVICE_FAMILY_5000,
+ .trans.device_family = IWL_DEVICE_FAMILY_5000,
.max_inst_size = IWLAGN_RTC_INST_SIZE,
.max_data_size = IWLAGN_RTC_DATA_SIZE,
.nvm_ver = EEPROM_5050_EEPROM_VERSION,
.nvm_calib_ver = EEPROM_5050_TX_POWER_VERSION,
- .base_params = &iwl5000_base_params,
+ .trans.base_params = &iwl5000_base_params,
.eeprom_params = &iwl5000_eeprom_params,
.ht_params = &iwl5000_ht_params,
.led_mode = IWL_LED_BLINK,
.internal_wimax_coex = true,
- .csr = &iwl_csr_v1,
+ .trans.csr = &iwl_csr_v1,
};
#define IWL_DEVICE_5150 \
.fw_name_pre = IWL5150_FW_PRE, \
.ucode_api_max = IWL5150_UCODE_API_MAX, \
.ucode_api_min = IWL5150_UCODE_API_MIN, \
- .device_family = IWL_DEVICE_FAMILY_5150, \
+ .trans.device_family = IWL_DEVICE_FAMILY_5150, \
.max_inst_size = IWLAGN_RTC_INST_SIZE, \
.max_data_size = IWLAGN_RTC_DATA_SIZE, \
.nvm_ver = EEPROM_5050_EEPROM_VERSION, \
.nvm_calib_ver = EEPROM_5050_TX_POWER_VERSION, \
- .base_params = &iwl5000_base_params, \
+ .trans.base_params = &iwl5000_base_params, \
.eeprom_params = &iwl5000_eeprom_params, \
.led_mode = IWL_LED_BLINK, \
.internal_wimax_coex = true, \
.max_ht_ampdu_exponent = IEEE80211_HT_MAX_AMPDU_64K, \
- .csr = &iwl_csr_v1
+ .trans.csr = &iwl_csr_v1
const struct iwl_cfg iwl5150_agn_cfg = {
.name = "Intel(R) WiMAX/WiFi Link 5150 AGN",
diff --git a/drivers/net/wireless/intel/iwlwifi/cfg/6000.c b/drivers/net/wireless/intel/iwlwifi/cfg/6000.c
index 67d61a1588a9..39ea81903dbe 100644
--- a/drivers/net/wireless/intel/iwlwifi/cfg/6000.c
+++ b/drivers/net/wireless/intel/iwlwifi/cfg/6000.c
@@ -2,7 +2,7 @@
/******************************************************************************
*
* Copyright(c) 2008 - 2014 Intel Corporation. All rights reserved.
- * Copyright(c) 2018 Intel Corporation
+ * Copyright(c) 2018 - 2019 Intel Corporation
*
* Contact Information:
* Intel Linux Wireless <linuxwifi@intel.com>
@@ -116,16 +116,16 @@ static const struct iwl_eeprom_params iwl6000_eeprom_params = {
.fw_name_pre = IWL6005_FW_PRE, \
.ucode_api_max = IWL6000G2_UCODE_API_MAX, \
.ucode_api_min = IWL6000G2_UCODE_API_MIN, \
- .device_family = IWL_DEVICE_FAMILY_6005, \
+ .trans.device_family = IWL_DEVICE_FAMILY_6005, \
.max_inst_size = IWL60_RTC_INST_SIZE, \
.max_data_size = IWL60_RTC_DATA_SIZE, \
.nvm_ver = EEPROM_6005_EEPROM_VERSION, \
.nvm_calib_ver = EEPROM_6005_TX_POWER_VERSION, \
- .base_params = &iwl6000_g2_base_params, \
+ .trans.base_params = &iwl6000_g2_base_params, \
.eeprom_params = &iwl6000_eeprom_params, \
.led_mode = IWL_LED_RF_STATE, \
.max_ht_ampdu_exponent = IEEE80211_HT_MAX_AMPDU_64K, \
- .csr = &iwl_csr_v1
+ .trans.csr = &iwl_csr_v1
const struct iwl_cfg iwl6005_2agn_cfg = {
.name = "Intel(R) Centrino(R) Advanced-N 6205 AGN",
@@ -171,16 +171,16 @@ const struct iwl_cfg iwl6005_2agn_mow2_cfg = {
.fw_name_pre = IWL6030_FW_PRE, \
.ucode_api_max = IWL6000G2_UCODE_API_MAX, \
.ucode_api_min = IWL6000G2_UCODE_API_MIN, \
- .device_family = IWL_DEVICE_FAMILY_6030, \
+ .trans.device_family = IWL_DEVICE_FAMILY_6030, \
.max_inst_size = IWL60_RTC_INST_SIZE, \
.max_data_size = IWL60_RTC_DATA_SIZE, \
.nvm_ver = EEPROM_6030_EEPROM_VERSION, \
.nvm_calib_ver = EEPROM_6030_TX_POWER_VERSION, \
- .base_params = &iwl6000_g2_base_params, \
+ .trans.base_params = &iwl6000_g2_base_params, \
.eeprom_params = &iwl6000_eeprom_params, \
.led_mode = IWL_LED_RF_STATE, \
.max_ht_ampdu_exponent = IEEE80211_HT_MAX_AMPDU_64K, \
- .csr = &iwl_csr_v1
+ .trans.csr = &iwl_csr_v1
const struct iwl_cfg iwl6030_2agn_cfg = {
.name = "Intel(R) Centrino(R) Advanced-N 6230 AGN",
@@ -208,16 +208,16 @@ const struct iwl_cfg iwl6030_2bg_cfg = {
.fw_name_pre = IWL6030_FW_PRE, \
.ucode_api_max = IWL6035_UCODE_API_MAX, \
.ucode_api_min = IWL6035_UCODE_API_MIN, \
- .device_family = IWL_DEVICE_FAMILY_6030, \
+ .trans.device_family = IWL_DEVICE_FAMILY_6030, \
.max_inst_size = IWL60_RTC_INST_SIZE, \
.max_data_size = IWL60_RTC_DATA_SIZE, \
.nvm_ver = EEPROM_6030_EEPROM_VERSION, \
.nvm_calib_ver = EEPROM_6030_TX_POWER_VERSION, \
- .base_params = &iwl6000_g2_base_params, \
+ .trans.base_params = &iwl6000_g2_base_params, \
.eeprom_params = &iwl6000_eeprom_params, \
.led_mode = IWL_LED_RF_STATE, \
.max_ht_ampdu_exponent = IEEE80211_HT_MAX_AMPDU_64K, \
- .csr = &iwl_csr_v1
+ .trans.csr = &iwl_csr_v1
const struct iwl_cfg iwl6035_2agn_cfg = {
.name = "Intel(R) Centrino(R) Advanced-N 6235 AGN",
@@ -262,18 +262,18 @@ const struct iwl_cfg iwl130_bg_cfg = {
.fw_name_pre = IWL6000_FW_PRE, \
.ucode_api_max = IWL6000_UCODE_API_MAX, \
.ucode_api_min = IWL6000_UCODE_API_MIN, \
- .device_family = IWL_DEVICE_FAMILY_6000i, \
+ .trans.device_family = IWL_DEVICE_FAMILY_6000i, \
.max_inst_size = IWL60_RTC_INST_SIZE, \
.max_data_size = IWL60_RTC_DATA_SIZE, \
.valid_tx_ant = ANT_BC, /* .cfg overwrite */ \
.valid_rx_ant = ANT_BC, /* .cfg overwrite */ \
.nvm_ver = EEPROM_6000_EEPROM_VERSION, \
.nvm_calib_ver = EEPROM_6000_TX_POWER_VERSION, \
- .base_params = &iwl6000_base_params, \
+ .trans.base_params = &iwl6000_base_params, \
.eeprom_params = &iwl6000_eeprom_params, \
.led_mode = IWL_LED_BLINK, \
.max_ht_ampdu_exponent = IEEE80211_HT_MAX_AMPDU_64K, \
- .csr = &iwl_csr_v1
+ .trans.csr = &iwl_csr_v1
const struct iwl_cfg iwl6000i_2agn_cfg = {
.name = "Intel(R) Centrino(R) Advanced-N 6200 AGN",
@@ -295,19 +295,19 @@ const struct iwl_cfg iwl6000i_2bg_cfg = {
.fw_name_pre = IWL6050_FW_PRE, \
.ucode_api_max = IWL6050_UCODE_API_MAX, \
.ucode_api_min = IWL6050_UCODE_API_MIN, \
- .device_family = IWL_DEVICE_FAMILY_6050, \
+ .trans.device_family = IWL_DEVICE_FAMILY_6050, \
.max_inst_size = IWL60_RTC_INST_SIZE, \
.max_data_size = IWL60_RTC_DATA_SIZE, \
.valid_tx_ant = ANT_AB, /* .cfg overwrite */ \
.valid_rx_ant = ANT_AB, /* .cfg overwrite */ \
.nvm_ver = EEPROM_6050_EEPROM_VERSION, \
.nvm_calib_ver = EEPROM_6050_TX_POWER_VERSION, \
- .base_params = &iwl6050_base_params, \
+ .trans.base_params = &iwl6050_base_params, \
.eeprom_params = &iwl6000_eeprom_params, \
.led_mode = IWL_LED_BLINK, \
.internal_wimax_coex = true, \
.max_ht_ampdu_exponent = IEEE80211_HT_MAX_AMPDU_64K, \
- .csr = &iwl_csr_v1
+ .trans.csr = &iwl_csr_v1
const struct iwl_cfg iwl6050_2agn_cfg = {
.name = "Intel(R) Centrino(R) Advanced-N + WiMAX 6250 AGN",
@@ -324,17 +324,17 @@ const struct iwl_cfg iwl6050_2abg_cfg = {
.fw_name_pre = IWL6050_FW_PRE, \
.ucode_api_max = IWL6050_UCODE_API_MAX, \
.ucode_api_min = IWL6050_UCODE_API_MIN, \
- .device_family = IWL_DEVICE_FAMILY_6150, \
+ .trans.device_family = IWL_DEVICE_FAMILY_6150, \
.max_inst_size = IWL60_RTC_INST_SIZE, \
.max_data_size = IWL60_RTC_DATA_SIZE, \
.nvm_ver = EEPROM_6150_EEPROM_VERSION, \
.nvm_calib_ver = EEPROM_6150_TX_POWER_VERSION, \
- .base_params = &iwl6050_base_params, \
+ .trans.base_params = &iwl6050_base_params, \
.eeprom_params = &iwl6000_eeprom_params, \
.led_mode = IWL_LED_BLINK, \
.internal_wimax_coex = true, \
.max_ht_ampdu_exponent = IEEE80211_HT_MAX_AMPDU_64K, \
- .csr = &iwl_csr_v1
+ .trans.csr = &iwl_csr_v1
const struct iwl_cfg iwl6150_bgn_cfg = {
.name = "Intel(R) Centrino(R) Wireless-N + WiMAX 6150 BGN",
@@ -352,16 +352,16 @@ const struct iwl_cfg iwl6000_3agn_cfg = {
.fw_name_pre = IWL6000_FW_PRE,
.ucode_api_max = IWL6000_UCODE_API_MAX,
.ucode_api_min = IWL6000_UCODE_API_MIN,
- .device_family = IWL_DEVICE_FAMILY_6000,
+ .trans.device_family = IWL_DEVICE_FAMILY_6000,
.max_inst_size = IWL60_RTC_INST_SIZE,
.max_data_size = IWL60_RTC_DATA_SIZE,
.nvm_ver = EEPROM_6000_EEPROM_VERSION,
.nvm_calib_ver = EEPROM_6000_TX_POWER_VERSION,
- .base_params = &iwl6000_base_params,
+ .trans.base_params = &iwl6000_base_params,
.eeprom_params = &iwl6000_eeprom_params,
.ht_params = &iwl6000_ht_params,
.led_mode = IWL_LED_BLINK,
- .csr = &iwl_csr_v1,
+ .trans.csr = &iwl_csr_v1,
};
MODULE_FIRMWARE(IWL6000_MODULE_FIRMWARE(IWL6000_UCODE_API_MAX));
diff --git a/drivers/net/wireless/intel/iwlwifi/cfg/7000.c b/drivers/net/wireless/intel/iwlwifi/cfg/7000.c
index 289e3c398a12..deb520aeb3f8 100644
--- a/drivers/net/wireless/intel/iwlwifi/cfg/7000.c
+++ b/drivers/net/wireless/intel/iwlwifi/cfg/7000.c
@@ -8,7 +8,7 @@
* Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved.
* Copyright(c) 2013 - 2014 Intel Mobile Communications GmbH
* Copyright(c) 2015 Intel Deutschland GmbH
- * Copyright(c) 2018 Intel Corporation
+ * Copyright(c) 2018 - 2019 Intel Corporation
*
* 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
@@ -31,7 +31,7 @@
* Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved.
* Copyright(c) 2013 - 2014 Intel Mobile Communications GmbH
* Copyright(c) 2015 Intel Deutschland GmbH
- * Copyright(c) 2018 Intel Corporation
+ * Copyright(c) 2018 - 2019 Intel Corporation
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -148,14 +148,14 @@ static const struct iwl_ht_params iwl7000_ht_params = {
};
#define IWL_DEVICE_7000_COMMON \
- .device_family = IWL_DEVICE_FAMILY_7000, \
- .base_params = &iwl7000_base_params, \
+ .trans.device_family = IWL_DEVICE_FAMILY_7000, \
+ .trans.base_params = &iwl7000_base_params, \
.led_mode = IWL_LED_RF_STATE, \
.nvm_hw_section_num = 0, \
.non_shared_ant = ANT_A, \
.max_ht_ampdu_exponent = IEEE80211_HT_MAX_AMPDU_64K, \
.dccm_offset = IWL7000_DCCM_OFFSET, \
- .csr = &iwl_csr_v1
+ .trans.csr = &iwl_csr_v1
#define IWL_DEVICE_7000 \
IWL_DEVICE_7000_COMMON, \
diff --git a/drivers/net/wireless/intel/iwlwifi/cfg/8000.c b/drivers/net/wireless/intel/iwlwifi/cfg/8000.c
index d7d17c1cceea..b3cc477140c0 100644
--- a/drivers/net/wireless/intel/iwlwifi/cfg/8000.c
+++ b/drivers/net/wireless/intel/iwlwifi/cfg/8000.c
@@ -8,7 +8,7 @@
* Copyright(c) 2014 Intel Corporation. All rights reserved.
* Copyright(c) 2014 - 2015 Intel Mobile Communications GmbH
* Copyright(c) 2016 Intel Deutschland GmbH
- * Copyright(c) 2018 Intel Corporation
+ * Copyright(c) 2018 - 2019 Intel Corporation
*
* 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
@@ -30,7 +30,7 @@
*
* Copyright(c) 2014 Intel Corporation. All rights reserved.
* Copyright(c) 2014 - 2015 Intel Mobile Communications GmbH
- * Copyright(c) 2018 Intel Corporation
+ * Copyright(c) 2018 - 2019 Intel Corporation
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -134,8 +134,8 @@ static const struct iwl_tt_params iwl8000_tt_params = {
};
#define IWL_DEVICE_8000_COMMON \
- .device_family = IWL_DEVICE_FAMILY_8000, \
- .base_params = &iwl8000_base_params, \
+ .trans.device_family = IWL_DEVICE_FAMILY_8000, \
+ .trans.base_params = &iwl8000_base_params, \
.led_mode = IWL_LED_RF_STATE, \
.nvm_hw_section_num = 10, \
.features = NETIF_F_RXCSUM, \
@@ -152,7 +152,7 @@ static const struct iwl_tt_params iwl8000_tt_params = {
.nvm_type = IWL_NVM_EXT, \
.dbgc_supported = true, \
.min_umac_error_event_table = 0x800000, \
- .csr = &iwl_csr_v1
+ .trans.csr = &iwl_csr_v1
#define IWL_DEVICE_8000 \
IWL_DEVICE_8000_COMMON, \
diff --git a/drivers/net/wireless/intel/iwlwifi/cfg/9000.c b/drivers/net/wireless/intel/iwlwifi/cfg/9000.c
index 41bdd0eaf62c..e8372b67df03 100644
--- a/drivers/net/wireless/intel/iwlwifi/cfg/9000.c
+++ b/drivers/net/wireless/intel/iwlwifi/cfg/9000.c
@@ -122,8 +122,8 @@ static const struct iwl_tt_params iwl9000_tt_params = {
#define IWL_DEVICE_9000 \
.ucode_api_max = IWL9000_UCODE_API_MAX, \
.ucode_api_min = IWL9000_UCODE_API_MIN, \
- .device_family = IWL_DEVICE_FAMILY_9000, \
- .base_params = &iwl9000_base_params, \
+ .trans.device_family = IWL_DEVICE_FAMILY_9000, \
+ .trans.base_params = &iwl9000_base_params, \
.led_mode = IWL_LED_RF_STATE, \
.nvm_hw_section_num = 10, \
.non_shared_ant = ANT_B, \
@@ -136,14 +136,14 @@ static const struct iwl_tt_params iwl9000_tt_params = {
.features = IWL_TX_CSUM_NETIF_FLAGS | NETIF_F_RXCSUM, \
.thermal_params = &iwl9000_tt_params, \
.apmg_not_supported = true, \
- .mq_rx_supported = true, \
+ .trans.mq_rx_supported = true, \
.vht_mu_mimo_supported = true, \
.mac_addr_from_csr = true, \
- .rf_id = true, \
+ .trans.rf_id = true, \
.nvm_type = IWL_NVM_EXT, \
.dbgc_supported = true, \
.min_umac_error_event_table = 0x800000, \
- .csr = &iwl_csr_v1, \
+ .trans.csr = &iwl_csr_v1, \
.d3_debug_data_base_addr = 0x401000, \
.d3_debug_data_length = 92 * 1024, \
.ht_params = &iwl9000_ht_params, \
diff --git a/drivers/net/wireless/intel/iwlwifi/dvm/devices.c b/drivers/net/wireless/intel/iwlwifi/dvm/devices.c
index b39f8b1475e1..dc3f197f94d9 100644
--- a/drivers/net/wireless/intel/iwlwifi/dvm/devices.c
+++ b/drivers/net/wireless/intel/iwlwifi/dvm/devices.c
@@ -2,6 +2,7 @@
/******************************************************************************
*
* Copyright(c) 2008 - 2014 Intel Corporation. All rights reserved.
+ * Copyright (C) 2019 Intel Corporation
*
* Contact Information:
* Intel Linux Wireless <linuxwifi@intel.com>
@@ -483,7 +484,7 @@ static void iwl6000_set_ct_threshold(struct iwl_priv *priv)
/* NIC configuration for 6000 series */
static void iwl6000_nic_config(struct iwl_priv *priv)
{
- switch (priv->cfg->device_family) {
+ switch (priv->trans->trans_cfg->device_family) {
case IWL_DEVICE_FAMILY_6005:
case IWL_DEVICE_FAMILY_6030:
case IWL_DEVICE_FAMILY_6000:
diff --git a/drivers/net/wireless/intel/iwlwifi/dvm/led.c b/drivers/net/wireless/intel/iwlwifi/dvm/led.c
index 38fd41fba661..dd387aba3317 100644
--- a/drivers/net/wireless/intel/iwlwifi/dvm/led.c
+++ b/drivers/net/wireless/intel/iwlwifi/dvm/led.c
@@ -2,6 +2,7 @@
/******************************************************************************
*
* Copyright(c) 2003 - 2014 Intel Corporation. All rights reserved.
+ * Copyright (C) 2019 Intel Corporation
*
* Contact Information:
* Intel Linux Wireless <linuxwifi@intel.com>
@@ -120,9 +121,9 @@ static int iwl_led_cmd(struct iwl_priv *priv,
}
led_cmd.on = iwl_blink_compensation(priv, on,
- priv->cfg->base_params->led_compensation);
+ priv->trans->trans_cfg->base_params->led_compensation);
led_cmd.off = iwl_blink_compensation(priv, off,
- priv->cfg->base_params->led_compensation);
+ priv->trans->trans_cfg->base_params->led_compensation);
ret = iwl_send_led_cmd(priv, &led_cmd);
if (!ret) {
diff --git a/drivers/net/wireless/intel/iwlwifi/dvm/mac80211.c b/drivers/net/wireless/intel/iwlwifi/dvm/mac80211.c
index 6c170636110a..6512d25e3563 100644
--- a/drivers/net/wireless/intel/iwlwifi/dvm/mac80211.c
+++ b/drivers/net/wireless/intel/iwlwifi/dvm/mac80211.c
@@ -2,7 +2,7 @@
/******************************************************************************
*
* Copyright(c) 2003 - 2014 Intel Corporation. All rights reserved.
- * Copyright (C) 2018 Intel Corporation
+ * Copyright (C) 2018 - 2019 Intel Corporation
*
* Portions of this file are derived from the ipw3945 project, as well
* as portions of the ieee80211 subsystem header files.
@@ -1099,7 +1099,7 @@ static void iwlagn_mac_flush(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
goto done;
}
- scd_queues = BIT(priv->cfg->base_params->num_of_queues) - 1;
+ scd_queues = BIT(priv->trans->trans_cfg->base_params->num_of_queues) - 1;
scd_queues &= ~(BIT(IWL_IPAN_CMD_QUEUE_NUM) |
BIT(IWL_DEFAULT_CMD_QUEUE_NUM));
diff --git a/drivers/net/wireless/intel/iwlwifi/dvm/main.c b/drivers/net/wireless/intel/iwlwifi/dvm/main.c
index ae5e4570f1c1..4f2789bb3b5b 100644
--- a/drivers/net/wireless/intel/iwlwifi/dvm/main.c
+++ b/drivers/net/wireless/intel/iwlwifi/dvm/main.c
@@ -3,7 +3,7 @@
*
* Copyright(c) 2003 - 2014 Intel Corporation. All rights reserved.
* Copyright(c) 2015 Intel Deutschland GmbH
- * Copyright (C) 2018 Intel Corporation
+ * Copyright (C) 2018 - 2019 Intel Corporation
*
* Portions of this file are derived from the ipw3945 project, as well
* as portions of the ieee80211 subsystem header files.
@@ -1267,7 +1267,7 @@ static struct iwl_op_mode *iwl_op_mode_dvm_start(struct iwl_trans *trans,
priv->cfg = cfg;
priv->fw = fw;
- switch (priv->cfg->device_family) {
+ switch (priv->trans->trans_cfg->device_family) {
case IWL_DEVICE_FAMILY_1000:
case IWL_DEVICE_FAMILY_100:
priv->lib = &iwl_dvm_1000_cfg;
@@ -1342,7 +1342,7 @@ static struct iwl_op_mode *iwl_op_mode_dvm_start(struct iwl_trans *trans,
driver_data[2]);
WARN_ON(sizeof(priv->transport_queue_stop) * BITS_PER_BYTE <
- priv->cfg->base_params->num_of_queues);
+ priv->trans->trans_cfg->base_params->num_of_queues);
ucode_flags = fw->ucode_capa.flags;
@@ -1405,9 +1405,9 @@ static struct iwl_op_mode *iwl_op_mode_dvm_start(struct iwl_trans *trans,
/* Reset chip to save power until we load uCode during "up". */
iwl_trans_stop_device(priv->trans);
- priv->nvm_data = iwl_parse_eeprom_data(priv->trans->dev, priv->cfg,
- priv->eeprom_blob,
- priv->eeprom_blob_size);
+ priv->nvm_data = iwl_parse_eeprom_data(priv->trans, priv->cfg,
+ priv->eeprom_blob,
+ priv->eeprom_blob_size);
if (!priv->nvm_data)
goto out_free_eeprom_blob;
diff --git a/drivers/net/wireless/intel/iwlwifi/dvm/power.c b/drivers/net/wireless/intel/iwlwifi/dvm/power.c
index dcb948068c1d..93ef023905c9 100644
--- a/drivers/net/wireless/intel/iwlwifi/dvm/power.c
+++ b/drivers/net/wireless/intel/iwlwifi/dvm/power.c
@@ -2,6 +2,7 @@
/******************************************************************************
*
* Copyright(c) 2007 - 2014 Intel Corporation. All rights reserved.
+ * Copyright (C) 2019 Intel Corporation
*
* Portions of this file are derived from the ipw3945 project, as well
* as portions of the ieee80211 subsystem header files.
@@ -199,7 +200,7 @@ static void iwl_static_sleep_cmd(struct iwl_priv *priv,
else
cmd->flags &= ~IWL_POWER_SLEEP_OVER_DTIM_MSK;
- if (priv->cfg->base_params->shadow_reg_enable)
+ if (priv->trans->trans_cfg->base_params->shadow_reg_enable)
cmd->flags |= IWL_POWER_SHADOW_REG_ENA;
else
cmd->flags &= ~IWL_POWER_SHADOW_REG_ENA;
diff --git a/drivers/net/wireless/intel/iwlwifi/dvm/rs.c b/drivers/net/wireless/intel/iwlwifi/dvm/rs.c
index b1e5d64ca60d..74229fcb63a9 100644
--- a/drivers/net/wireless/intel/iwlwifi/dvm/rs.c
+++ b/drivers/net/wireless/intel/iwlwifi/dvm/rs.c
@@ -3256,28 +3256,16 @@ static void rs_add_debugfs(void *priv, void *priv_sta,
struct dentry *dir)
{
struct iwl_lq_sta *lq_sta = priv_sta;
- lq_sta->rs_sta_dbgfs_scale_table_file =
- debugfs_create_file("rate_scale_table", 0600, dir,
- lq_sta, &rs_sta_dbgfs_scale_table_ops);
- lq_sta->rs_sta_dbgfs_stats_table_file =
- debugfs_create_file("rate_stats_table", 0400, dir,
- lq_sta, &rs_sta_dbgfs_stats_table_ops);
- lq_sta->rs_sta_dbgfs_rate_scale_data_file =
- debugfs_create_file("rate_scale_data", 0400, dir,
- lq_sta, &rs_sta_dbgfs_rate_scale_data_ops);
- lq_sta->rs_sta_dbgfs_tx_agg_tid_en_file =
- debugfs_create_u8("tx_agg_tid_enable", 0600, dir,
- &lq_sta->tx_agg_tid_en);
-}
+ debugfs_create_file("rate_scale_table", 0600, dir, lq_sta,
+ &rs_sta_dbgfs_scale_table_ops);
+ debugfs_create_file("rate_stats_table", 0400, dir, lq_sta,
+ &rs_sta_dbgfs_stats_table_ops);
+ debugfs_create_file("rate_scale_data", 0400, dir, lq_sta,
+ &rs_sta_dbgfs_rate_scale_data_ops);
+ debugfs_create_u8("tx_agg_tid_enable", 0600, dir,
+ &lq_sta->tx_agg_tid_en);
-static void rs_remove_debugfs(void *priv, void *priv_sta)
-{
- struct iwl_lq_sta *lq_sta = priv_sta;
- debugfs_remove(lq_sta->rs_sta_dbgfs_scale_table_file);
- debugfs_remove(lq_sta->rs_sta_dbgfs_stats_table_file);
- debugfs_remove(lq_sta->rs_sta_dbgfs_rate_scale_data_file);
- debugfs_remove(lq_sta->rs_sta_dbgfs_tx_agg_tid_en_file);
}
#endif
@@ -3303,7 +3291,6 @@ static const struct rate_control_ops rs_ops = {
.free_sta = rs_free_sta,
#ifdef CONFIG_MAC80211_DEBUGFS
.add_sta_debugfs = rs_add_debugfs,
- .remove_sta_debugfs = rs_remove_debugfs,
#endif
};
diff --git a/drivers/net/wireless/intel/iwlwifi/dvm/rs.h b/drivers/net/wireless/intel/iwlwifi/dvm/rs.h
index b7a1854cd202..68a840d739e8 100644
--- a/drivers/net/wireless/intel/iwlwifi/dvm/rs.h
+++ b/drivers/net/wireless/intel/iwlwifi/dvm/rs.h
@@ -356,10 +356,6 @@ struct iwl_lq_sta {
struct iwl_traffic_load load[IWL_MAX_TID_COUNT];
u8 tx_agg_tid_en;
#ifdef CONFIG_MAC80211_DEBUGFS
- struct dentry *rs_sta_dbgfs_scale_table_file;
- struct dentry *rs_sta_dbgfs_stats_table_file;
- struct dentry *rs_sta_dbgfs_rate_scale_data_file;
- struct dentry *rs_sta_dbgfs_tx_agg_tid_en_file;
u32 dbg_fixed_rate;
#endif
struct iwl_priv *drv;
diff --git a/drivers/net/wireless/intel/iwlwifi/dvm/tx.c b/drivers/net/wireless/intel/iwlwifi/dvm/tx.c
index 247f41705912..3029e3f6de63 100644
--- a/drivers/net/wireless/intel/iwlwifi/dvm/tx.c
+++ b/drivers/net/wireless/intel/iwlwifi/dvm/tx.c
@@ -2,6 +2,7 @@
/******************************************************************************
*
* Copyright(c) 2008 - 2014 Intel Corporation. All rights reserved.
+ * Copyright (C) 2019 Intel Corporation
*
* Contact Information:
* Intel Linux Wireless <linuxwifi@intel.com>
@@ -467,7 +468,7 @@ static int iwlagn_alloc_agg_txq(struct iwl_priv *priv, int mq)
int q;
for (q = IWLAGN_FIRST_AMPDU_QUEUE;
- q < priv->cfg->base_params->num_of_queues; q++) {
+ q < priv->trans->trans_cfg->base_params->num_of_queues; q++) {
if (!test_and_set_bit(q, priv->agg_q_alloc)) {
priv->queue_to_mac80211[q] = mq;
return q;
@@ -1281,7 +1282,7 @@ void iwlagn_rx_reply_compressed_ba(struct iwl_priv *priv,
* (in Tx queue's circular buffer) of first TFD/frame in window */
u16 ba_resp_scd_ssn = le16_to_cpu(ba_resp->scd_ssn);
- if (scd_flow >= priv->cfg->base_params->num_of_queues) {
+ if (scd_flow >= priv->trans->trans_cfg->base_params->num_of_queues) {
IWL_ERR(priv,
"BUG_ON scd_flow is bigger than number of queues\n");
return;
diff --git a/drivers/net/wireless/intel/iwlwifi/fw/acpi.c b/drivers/net/wireless/intel/iwlwifi/fw/acpi.c
index 7573af2d88ce..c2db758b9d54 100644
--- a/drivers/net/wireless/intel/iwlwifi/fw/acpi.c
+++ b/drivers/net/wireless/intel/iwlwifi/fw/acpi.c
@@ -162,12 +162,13 @@ int iwl_acpi_get_mcc(struct device *dev, char *mcc)
wifi_pkg = iwl_acpi_get_wifi_pkg(dev, data, ACPI_WRDD_WIFI_DATA_SIZE,
&tbl_rev);
- if (IS_ERR(wifi_pkg) || tbl_rev != 0) {
+ if (IS_ERR(wifi_pkg)) {
ret = PTR_ERR(wifi_pkg);
goto out_free;
}
- if (wifi_pkg->package.elements[1].type != ACPI_TYPE_INTEGER) {
+ if (wifi_pkg->package.elements[1].type != ACPI_TYPE_INTEGER ||
+ tbl_rev != 0) {
ret = -EINVAL;
goto out_free;
}
@@ -224,12 +225,13 @@ int iwl_acpi_get_eckv(struct device *dev, u32 *extl_clk)
wifi_pkg = iwl_acpi_get_wifi_pkg(dev, data, ACPI_ECKV_WIFI_DATA_SIZE,
&tbl_rev);
- if (IS_ERR(wifi_pkg) || tbl_rev != 0) {
+ if (IS_ERR(wifi_pkg)) {
ret = PTR_ERR(wifi_pkg);
goto out_free;
}
- if (wifi_pkg->package.elements[1].type != ACPI_TYPE_INTEGER) {
+ if (wifi_pkg->package.elements[1].type != ACPI_TYPE_INTEGER ||
+ tbl_rev != 0) {
ret = -EINVAL;
goto out_free;
}
diff --git a/drivers/net/wireless/intel/iwlwifi/fw/acpi.h b/drivers/net/wireless/intel/iwlwifi/fw/acpi.h
index 991a23450999..6cb2d1f5efea 100644
--- a/drivers/net/wireless/intel/iwlwifi/fw/acpi.h
+++ b/drivers/net/wireless/intel/iwlwifi/fw/acpi.h
@@ -68,6 +68,7 @@
#define ACPI_WRDD_METHOD "WRDD"
#define ACPI_SPLC_METHOD "SPLC"
#define ACPI_ECKV_METHOD "ECKV"
+#define ACPI_PPAG_METHOD "PPAG"
#define ACPI_WIFI_DOMAIN (0x07)
@@ -92,6 +93,17 @@
#define ACPI_WGDS_NUM_BANDS 2
#define ACPI_WGDS_TABLE_SIZE 3
+#define ACPI_PPAG_NUM_CHAINS 2
+#define ACPI_PPAG_NUM_SUB_BANDS 5
+#define ACPI_PPAG_WIFI_DATA_SIZE ((ACPI_PPAG_NUM_CHAINS * \
+ ACPI_PPAG_NUM_SUB_BANDS) + 3)
+
+/* PPAG gain value bounds in 1/8 dBm */
+#define ACPI_PPAG_MIN_LB -16
+#define ACPI_PPAG_MAX_LB 24
+#define ACPI_PPAG_MIN_HB -16
+#define ACPI_PPAG_MAX_HB 40
+
#ifdef CONFIG_ACPI
void *iwl_acpi_get_object(struct device *dev, acpi_string method);
diff --git a/drivers/net/wireless/intel/iwlwifi/fw/api/commands.h b/drivers/net/wireless/intel/iwlwifi/fw/api/commands.h
index 4d2274bcc0b5..22dff2c92d4f 100644
--- a/drivers/net/wireless/intel/iwlwifi/fw/api/commands.h
+++ b/drivers/net/wireless/intel/iwlwifi/fw/api/commands.h
@@ -475,6 +475,13 @@ enum iwl_legacy_cmds {
REPLY_RX_MPDU_CMD = 0xc1,
/**
+ * @BAR_FRAME_RELEASE: Frame release from BAR notification, used for
+ * multi-TID BAR (previously, the BAR frame itself was reported
+ * instead). Uses &struct iwl_bar_frame_release.
+ */
+ BAR_FRAME_RELEASE = 0xc2,
+
+ /**
* @FRAME_RELEASE:
* Frame release (reorder helper) notification, uses
* &struct iwl_frame_release
diff --git a/drivers/net/wireless/intel/iwlwifi/fw/api/d3.h b/drivers/net/wireless/intel/iwlwifi/fw/api/d3.h
index 31231b223aae..4c3219e7beb6 100644
--- a/drivers/net/wireless/intel/iwlwifi/fw/api/d3.h
+++ b/drivers/net/wireless/intel/iwlwifi/fw/api/d3.h
@@ -396,6 +396,7 @@ enum iwl_wowlan_flags {
* @is_11n_connection: indicates HT connection
* @offloading_tid: TID reserved for firmware use
* @flags: extra flags, see &enum iwl_wowlan_flags
+ * @sta_id: station ID for wowlan.
* @reserved: reserved
*/
struct iwl_wowlan_config_cmd {
@@ -406,8 +407,9 @@ struct iwl_wowlan_config_cmd {
u8 is_11n_connection;
u8 offloading_tid;
u8 flags;
- u8 reserved[2];
-} __packed; /* WOWLAN_CONFIG_API_S_VER_4 */
+ u8 sta_id;
+ u8 reserved;
+} __packed; /* WOWLAN_CONFIG_API_S_VER_5 */
/*
* WOWLAN_TSC_RSC_PARAMS
diff --git a/drivers/net/wireless/intel/iwlwifi/fw/api/dbg-tlv.h b/drivers/net/wireless/intel/iwlwifi/fw/api/dbg-tlv.h
index aaf3974a9a20..ba586f148c14 100644
--- a/drivers/net/wireless/intel/iwlwifi/fw/api/dbg-tlv.h
+++ b/drivers/net/wireless/intel/iwlwifi/fw/api/dbg-tlv.h
@@ -140,17 +140,6 @@ struct iwl_fw_ini_hcmd_tlv {
struct iwl_fw_ini_hcmd hcmd;
} __packed; /* FW_DEBUG_TLV_HCMD_API_S_VER_1 */
-/**
- * struct iwl_fw_ini_debug_flow_tlv - (IWL_UCODE_TLV_TYPE_DEBUG_FLOW)
- *
- * @header: header
- * @debug_flow_cfg: &enum iwl_fw_ini_debug_flow
- */
-struct iwl_fw_ini_debug_flow_tlv {
- struct iwl_fw_ini_header header;
- __le32 debug_flow_cfg;
-} __packed; /* FW_DEBUG_TLV_FLOW_TLV_S_VER_1 */
-
#define IWL_FW_INI_MAX_REGION_ID 64
#define IWL_FW_INI_MAX_NAME 32
@@ -409,27 +398,6 @@ enum iwl_fw_ini_trigger_id {
}; /* FW_DEBUG_TLV_TRIGGER_ID_E_VER_1 */
/**
- * enum iwl_fw_ini_apply_point
- *
- * @IWL_FW_INI_APPLY_INVALID: invalid
- * @IWL_FW_INI_APPLY_EARLY: pre loading FW
- * @IWL_FW_INI_APPLY_AFTER_ALIVE: first cmd from host after alive
- * @IWL_FW_INI_APPLY_POST_INIT: last cmd in initialization sequence
- * @IWL_FW_INI_APPLY_MISSED_BEACONS: missed beacons notification
- * @IWL_FW_INI_APPLY_SCAN_COMPLETE: scan completed
- * @IWL_FW_INI_APPLY_NUM: number of apply points
-*/
-enum iwl_fw_ini_apply_point {
- IWL_FW_INI_APPLY_INVALID,
- IWL_FW_INI_APPLY_EARLY,
- IWL_FW_INI_APPLY_AFTER_ALIVE,
- IWL_FW_INI_APPLY_POST_INIT,
- IWL_FW_INI_APPLY_MISSED_BEACONS,
- IWL_FW_INI_APPLY_SCAN_COMPLETE,
- IWL_FW_INI_APPLY_NUM,
-}; /* FW_DEBUG_TLV_APPLY_POINT_E_VER_1 */
-
-/**
* enum iwl_fw_ini_allocation_id
*
* @IWL_FW_INI_ALLOCATION_INVALID: invalid
@@ -439,6 +407,7 @@ enum iwl_fw_ini_apply_point {
* @IWL_FW_INI_ALLOCATION_ID_SDFX: for SDFX module
* @IWL_FW_INI_ALLOCATION_ID_FW_DUMP: used for crash and runtime dumps
* @IWL_FW_INI_ALLOCATION_ID_USER_DEFINED: for future user scenarios
+ * @IWL_FW_INI_ALLOCATION_NUM: number of allocation ids
*/
enum iwl_fw_ini_allocation_id {
IWL_FW_INI_ALLOCATION_INVALID,
@@ -448,6 +417,7 @@ enum iwl_fw_ini_allocation_id {
IWL_FW_INI_ALLOCATION_ID_SDFX,
IWL_FW_INI_ALLOCATION_ID_FW_DUMP,
IWL_FW_INI_ALLOCATION_ID_USER_DEFINED,
+ IWL_FW_INI_ALLOCATION_NUM,
}; /* FW_DEBUG_TLV_ALLOCATION_ID_E_VER_1 */
/**
@@ -519,4 +489,72 @@ enum iwl_fw_ini_region_type {
IWL_FW_INI_REGION_NUM
}; /* FW_DEBUG_TLV_REGION_TYPE_E_VER_1 */
+/**
+ * enum iwl_fw_ini_time_point
+ *
+ * Hard coded time points in which the driver can send hcmd or perform dump
+ * collection
+ *
+ * @IWL_FW_INI_TIME_POINT_EARLY: pre loading the FW
+ * @IWL_FW_INI_TIME_POINT_AFTER_ALIVE: first cmd from host after alive notif
+ * @IWL_FW_INI_TIME_POINT_POST_INIT: last cmd in series of init sequence
+ * @IWL_FW_INI_TIME_POINT_FW_ASSERT: FW assert
+ * @IWL_FW_INI_TIME_POINT_FW_HW_ERROR: FW HW error
+ * @IWL_FW_INI_TIME_POINT_FW_TFD_Q_HANG: TFD queue hang
+ * @IWL_FW_INI_TIME_POINT_FW_DHC_NOTIFOCATION: DHC cmd response and notif
+ * @IWL_FW_INI_TIME_POINT_FW_RSP_OR_NOTIF: FW response or notification.
+ * data field holds id and group
+ * @IWL_FW_INI_TIME_POINT_USER_TRIGGER: user trigger time point
+ * @IWL_FW_INI_TIME_POINT_PERIODIC: periodic timepoint that fires in constant
+ * intervals. data field holds the interval time in msec
+ * @IWL_FW_INI_TIME_POINT_WDG_TIMEOUT: watchdog timeout
+ * @IWL_FW_INI_TIME_POINT_HOST_ASSERT: Unused
+ * @IWL_FW_INI_TIME_POINT_HOST_ALIVE_TIMEOUT: alive timeout
+ * @IWL_FW_INI_TIME_POINT_HOST_DEVICE_ENABLE: device enable
+ * @IWL_FW_INI_TIME_POINT_HOST_DEVICE_DISABLE: device disable
+ * @IWL_FW_INI_TIME_POINT_HOST_D3_START: D3 start
+ * @IWL_FW_INI_TIME_POINT_HOST_D3_END: D3 end
+ * @IWL_FW_INI_TIME_POINT_MISSED_BEACONS: missed beacons
+ * @IWL_FW_INI_TIME_POINT_ASSOC_FAILED: association failure
+ * @IWL_FW_INI_TIME_POINT_TX_FAILED: Tx frame failed
+ * @IWL_FW_INI_TIME_POINT_TX_WFD_ACTION_FRAME_FAILED: wifi direct action
+ * frame failed
+ * @IWL_FW_INI_TIME_POINT_TX_LATENCY_THRESHOLD: Tx latency threshold
+ * @IWL_FW_INI_TIME_POINT_HANG_OCCURRED: hang occurred
+ * @IWL_FW_INI_TIME_POINT_EAPOL_FAILED: EAPOL failed
+ * @IWL_FW_INI_TIME_POINT_FAKE_TX: fake Tx
+ * @IWL_FW_INI_TIME_POINT_DEASSOC: de association
+ * @IWL_FW_INI_TIME_POINT_NUM: number of time points
+ */
+enum iwl_fw_ini_time_point {
+ IWL_FW_INI_TIME_POINT_INVALID,
+ IWL_FW_INI_TIME_POINT_EARLY,
+ IWL_FW_INI_TIME_POINT_AFTER_ALIVE,
+ IWL_FW_INI_TIME_POINT_POST_INIT,
+ IWL_FW_INI_TIME_POINT_FW_ASSERT,
+ IWL_FW_INI_TIME_POINT_FW_HW_ERROR,
+ IWL_FW_INI_TIME_POINT_FW_TFD_Q_HANG,
+ IWL_FW_INI_TIME_POINT_FW_DHC_NOTIFOCATION,
+ IWL_FW_INI_TIME_POINT_FW_RSP_OR_NOTIF,
+ IWL_FW_INI_TIME_POINT_USER_TRIGGER,
+ IWL_FW_INI_TIME_POINT_PERIODIC,
+ IWL_FW_INI_TIME_POINT_WDG_TIMEOUT,
+ IWL_FW_INI_TIME_POINT_HOST_ASSERT,
+ IWL_FW_INI_TIME_POINT_HOST_ALIVE_TIMEOUT,
+ IWL_FW_INI_TIME_POINT_HOST_DEVICE_ENABLE,
+ IWL_FW_INI_TIME_POINT_HOST_DEVICE_DISABLE,
+ IWL_FW_INI_TIME_POINT_HOST_D3_START,
+ IWL_FW_INI_TIME_POINT_HOST_D3_END,
+ IWL_FW_INI_TIME_POINT_MISSED_BEACONS,
+ IWL_FW_INI_TIME_POINT_ASSOC_FAILED,
+ IWL_FW_INI_TIME_POINT_TX_FAILED,
+ IWL_FW_INI_TIME_POINT_TX_WFD_ACTION_FRAME_FAILED,
+ IWL_FW_INI_TIME_POINT_TX_LATENCY_THRESHOLD,
+ IWL_FW_INI_TIME_POINT_HANG_OCCURRED,
+ IWL_FW_INI_TIME_POINT_EAPOL_FAILED,
+ IWL_FW_INI_TIME_POINT_FAKE_TX,
+ IWL_FW_INI_TIME_POINT_DEASSOC,
+ IWL_FW_INI_TIME_POINT_NUM,
+}; /* FW_TLV_DEBUG_TIME_POINT_API_E */
+
#endif
diff --git a/drivers/net/wireless/intel/iwlwifi/fw/api/debug.h b/drivers/net/wireless/intel/iwlwifi/fw/api/debug.h
index 988584973aba..98e957ecbeed 100644
--- a/drivers/net/wireless/intel/iwlwifi/fw/api/debug.h
+++ b/drivers/net/wireless/intel/iwlwifi/fw/api/debug.h
@@ -8,7 +8,7 @@
* Copyright(c) 2007 - 2014 Intel Corporation. All rights reserved.
* Copyright(c) 2013 - 2015 Intel Mobile Communications GmbH
* Copyright(c) 2016 - 2017 Intel Deutschland GmbH
- * Copyright (C) 2018 Intel Corporation
+ * Copyright (C) 2018 - 2019 Intel Corporation
*
* 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
@@ -31,7 +31,7 @@
* Copyright(c) 2005 - 2014 Intel Corporation. All rights reserved.
* Copyright(c) 2013 - 2015 Intel Mobile Communications GmbH
* Copyright(c) 2016 - 2017 Intel Deutschland GmbH
- * Copyright (C) 2018 Intel Corporation
+ * Copyright (C) 2018 - 2019 Intel Corporation
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -81,6 +81,19 @@ enum iwl_debug_cmds {
*/
UMAC_RD_WR = 0x1,
/**
+ * @DBGC_SUSPEND_RESUME:
+ * DBGC suspend/resume commad. Uses a single dword as data:
+ * 0 - resume DBGC recording
+ * 1 - suspend DBGC recording
+ */
+ DBGC_SUSPEND_RESUME = 0x7,
+ /**
+ * @BUFFER_ALLOCATION:
+ * passes DRAM buffers to a DBGC
+ * &struct iwl_buf_alloc_cmd
+ */
+ BUFFER_ALLOCATION = 0x8,
+ /**
* @MFU_ASSERT_DUMP_NTF:
* &struct iwl_mfu_assert_dump_notif
*/
@@ -102,6 +115,16 @@ enum {
FW_ERR_FATAL = 0xFF
};
+/** enum iwl_dbg_suspend_resume_cmds - dbgc suspend resume operations
+ * dbgc suspend resume command operations
+ * @DBGC_RESUME_CMD: resume dbgc recording
+ * @DBGC_SUSPEND_CMD: stop dbgc recording
+ */
+enum iwl_dbg_suspend_resume_cmds {
+ DBGC_RESUME_CMD,
+ DBGC_SUSPEND_CMD,
+};
+
/**
* struct iwl_error_resp - FW error indication
* ( REPLY_ERROR = 0x2 )
@@ -335,49 +358,39 @@ struct iwl_dbg_mem_access_rsp {
__le32 data[];
} __packed; /* DEBUG_(U|L)MAC_RD_WR_RSP_API_S_VER_1 */
-#define LDBG_CFG_COMMAND_SIZE 80
-#define BUFFER_ALLOCATION 0x27
-#define START_DEBUG_RECORDING 0x29
-#define STOP_DEBUG_RECORDING 0x2A
+/**
+ * struct iwl_dbg_suspend_resume_cmd - dbgc suspend resume command
+ * @operation: suspend or resume operation, uses
+ * &enum iwl_dbg_suspend_resume_cmds
+ */
+struct iwl_dbg_suspend_resume_cmd {
+ __le32 operation;
+} __packed;
-/* maximum fragments to be allocated per target of allocationId */
-#define IWL_BUFFER_LOCATION_MAX_FRAGS 2
+#define BUF_ALLOC_MAX_NUM_FRAGS 16
/**
- * struct iwl_fragment_data single fragment structure
- * @address: 64bit start address
- * @size: size in bytes
+ * struct iwl_buf_alloc_frag - a DBGC fragment
+ * @addr: base address of the fragment
+ * @size: size of the fragment
*/
-struct iwl_fragment_data {
- __le64 address;
+struct iwl_buf_alloc_frag {
+ __le64 addr;
__le32 size;
} __packed; /* FRAGMENT_STRUCTURE_API_S_VER_1 */
/**
- * struct iwl_buffer_allocation_cmd - buffer allocation command structure
- * @allocation_id: id of the allocation
- * @buffer_location: location of the buffer
+ * struct iwl_buf_alloc_cmd - buffer allocation command
+ * @alloc_id: &enum iwl_fw_ini_allocation_id
+ * @buf_location: &enum iwl_fw_ini_buffer_location
* @num_frags: number of fragments
- * @fragments: memory fragments
+ * @frags: fragments array
*/
-struct iwl_buffer_allocation_cmd {
- __le32 allocation_id;
- __le32 buffer_location;
+struct iwl_buf_alloc_cmd {
+ __le32 alloc_id;
+ __le32 buf_location;
__le32 num_frags;
- struct iwl_fragment_data fragments[IWL_BUFFER_LOCATION_MAX_FRAGS];
-} __packed; /* BUFFER_ALLOCATION_CMD_API_S_VER_1 */
-
-/**
- * struct iwl_ldbg_config_cmd - LDBG config command
- * @type: configuration type
- * @pad: reserved space for type-dependent data
- */
-struct iwl_ldbg_config_cmd {
- __le32 type;
- union {
- u8 pad[LDBG_CFG_COMMAND_SIZE - sizeof(__le32)];
- struct iwl_buffer_allocation_cmd buffer_allocation;
- }; /* LDBG_CFG_BODY_API_U_VER_2 (partially) */
-} __packed; /* LDBG_CFG_CMD_API_S_VER_2 */
+ struct iwl_buf_alloc_frag frags[BUF_ALLOC_MAX_NUM_FRAGS];
+} __packed; /* BUFFER_ALLOCATION_CMD_API_S_VER_2 */
#endif /* __iwl_fw_api_debug_h__ */
diff --git a/drivers/net/wireless/intel/iwlwifi/fw/api/location.h b/drivers/net/wireless/intel/iwlwifi/fw/api/location.h
index ec864c7b497f..7a0fe5adefa5 100644
--- a/drivers/net/wireless/intel/iwlwifi/fw/api/location.h
+++ b/drivers/net/wireless/intel/iwlwifi/fw/api/location.h
@@ -82,7 +82,7 @@ enum iwl_location_subcmd_ids {
TOF_RANGE_ABORT_CMD = 0x2,
/**
* @TOF_RANGE_REQ_EXT_CMD: TOF extended ranging config,
- * uses &struct iwl_tof_range_request_ext_cmd
+ * uses &struct iwl_tof_range_req_ext_cmd
*/
TOF_RANGE_REQ_EXT_CMD = 0x3,
/**
@@ -292,7 +292,7 @@ struct iwl_tof_responder_dyn_config_cmd {
} __packed; /* TOF_RESPONDER_DYN_CONFIG_CMD_API_S_VER_2 */
/**
- * struct iwl_tof_range_request_ext_cmd - extended range req for WLS
+ * struct iwl_tof_range_req_ext_cmd - extended range req for WLS
* @tsf_timer_offset_msec: the recommended time offset (mSec) from the AP's TSF
* @reserved: reserved
* @min_delta_ftm: Minimal time between two consecutive measurements,
diff --git a/drivers/net/wireless/intel/iwlwifi/fw/api/mac.h b/drivers/net/wireless/intel/iwlwifi/fw/api/mac.h
index 85c5e367cbf1..73fb0030c496 100644
--- a/drivers/net/wireless/intel/iwlwifi/fw/api/mac.h
+++ b/drivers/net/wireless/intel/iwlwifi/fw/api/mac.h
@@ -500,6 +500,9 @@ struct iwl_he_pkt_ext {
* enabled AGG, i.e. both BACK and non-BACK frames in a single AGG
* @STA_CTXT_HE_MU_EDCA_CW: indicates that there is an element of MU EDCA
* parameter set, i.e. the backoff counters for trig-based ACs
+ * @STA_CTXT_HE_RU_2MHZ_BLOCK: indicates that 26-tone RU OFDMA transmission are
+ * not allowed (as there are OBSS that might classify such transmissions as
+ * radar pulses).
*/
enum iwl_he_sta_ctxt_flags {
STA_CTXT_HE_REF_BSSID_VALID = BIT(4),
@@ -511,6 +514,7 @@ enum iwl_he_sta_ctxt_flags {
STA_CTXT_HE_CONST_TRIG_RND_ALLOC = BIT(10),
STA_CTXT_HE_ACK_ENABLED = BIT(11),
STA_CTXT_HE_MU_EDCA_CW = BIT(12),
+ STA_CTXT_HE_RU_2MHZ_BLOCK = BIT(14),
};
/**
diff --git a/drivers/net/wireless/intel/iwlwifi/fw/api/phy.h b/drivers/net/wireless/intel/iwlwifi/fw/api/phy.h
index 9cc59e00bd95..8991ddffbf5e 100644
--- a/drivers/net/wireless/intel/iwlwifi/fw/api/phy.h
+++ b/drivers/net/wireless/intel/iwlwifi/fw/api/phy.h
@@ -8,6 +8,7 @@
* Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved.
* Copyright(c) 2013 - 2015 Intel Mobile Communications GmbH
* Copyright(c) 2016 - 2017 Intel Deutschland GmbH
+ * Copyright(c) 2019 Intel Corporation
*
* 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
@@ -30,6 +31,7 @@
* Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved.
* Copyright(c) 2013 - 2015 Intel Mobile Communications GmbH
* Copyright(c) 2016 - 2017 Intel Deutschland GmbH
+ * Copyright(c) 2019 Intel Corporation
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -90,6 +92,11 @@ enum iwl_phy_ops_subcmd_ids {
GEO_TX_POWER_LIMIT = 0x05,
/**
+ * @PER_PLATFORM_ANT_GAIN_CMD: &struct iwl_ppag_table_cmd
+ */
+ PER_PLATFORM_ANT_GAIN_CMD = 0x07,
+
+ /**
* @CT_KILL_NOTIFICATION: &struct ct_kill_notif
*/
CT_KILL_NOTIFICATION = 0xFE,
diff --git a/drivers/net/wireless/intel/iwlwifi/fw/api/power.h b/drivers/net/wireless/intel/iwlwifi/fw/api/power.h
index f195db398bed..6e1b9b21904e 100644
--- a/drivers/net/wireless/intel/iwlwifi/fw/api/power.h
+++ b/drivers/net/wireless/intel/iwlwifi/fw/api/power.h
@@ -450,6 +450,18 @@ struct iwl_geo_tx_power_profiles_resp {
} __packed; /* GEO_TX_POWER_LIMIT_RESP */
/**
+ * struct iwl_ppag_table_cmd - struct for PER_PLATFORM_ANT_GAIN_CMD cmd.
+ * @enabled: 1 if PPAG is enabled, 0 otherwise
+ * @gain: table of antenna gain values per chain and sub-band
+ * @reserved: reserved
+ */
+struct iwl_ppag_table_cmd {
+ __le32 enabled;
+ s8 gain[IWL_NUM_CHAIN_LIMITS][IWL_NUM_SUB_BANDS];
+ s8 reserved[2];
+} __packed; /* PER_PLATFORM_ANT_GAIN_CMD */
+
+/**
* struct iwl_beacon_filter_cmd
* REPLY_BEACON_FILTERING_CMD = 0xd2 (command)
* @bf_energy_delta: Used for RSSI filtering, if in 'normal' state. Send beacon
diff --git a/drivers/net/wireless/intel/iwlwifi/fw/api/rs.h b/drivers/net/wireless/intel/iwlwifi/fw/api/rs.h
index 9eddc4dc2ae6..4347be6491e9 100644
--- a/drivers/net/wireless/intel/iwlwifi/fw/api/rs.h
+++ b/drivers/net/wireless/intel/iwlwifi/fw/api/rs.h
@@ -7,7 +7,7 @@
*
* Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved.
* Copyright(c) 2017 Intel Deutschland GmbH
- * Copyright(c) 2018 Intel Corporation
+ * Copyright(c) 2018 - 2019 Intel Corporation
*
* 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
@@ -29,7 +29,7 @@
*
* Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved.
* Copyright(c) 2017 Intel Deutschland GmbH
- * Copyright(c) 2018 Intel Corporation
+ * Copyright(c) 2018 - 2019 Intel Corporation
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -166,8 +166,16 @@ enum iwl_tlc_mng_ht_rates {
IWL_TLC_MNG_HT_RATE_MAX = IWL_TLC_MNG_HT_RATE_MCS11,
};
-/* Maximum supported tx antennas number */
-#define MAX_NSS 2
+enum IWL_TLC_MNG_NSS {
+ IWL_TLC_NSS_1,
+ IWL_TLC_NSS_2,
+ IWL_TLC_NSS_MAX
+};
+
+enum IWL_TLC_HT_BW_RATES {
+ IWL_TLC_HT_BW_NONE_160,
+ IWL_TLC_HT_BW_160,
+};
/**
* struct tlc_config_cmd - TLC configuration
@@ -195,7 +203,7 @@ struct iwl_tlc_config_cmd {
u8 amsdu;
__le16 flags;
__le16 non_ht_rates;
- __le16 ht_rates[MAX_NSS][2];
+ __le16 ht_rates[IWL_TLC_NSS_MAX][2];
__le16 max_mpdu_len;
u8 sgi_ch_width_supp;
u8 reserved2[1];
diff --git a/drivers/net/wireless/intel/iwlwifi/fw/api/rx.h b/drivers/net/wireless/intel/iwlwifi/fw/api/rx.h
index 9b0bb89599fc..a93449db7bb2 100644
--- a/drivers/net/wireless/intel/iwlwifi/fw/api/rx.h
+++ b/drivers/net/wireless/intel/iwlwifi/fw/api/rx.h
@@ -746,6 +746,38 @@ struct iwl_frame_release {
__le16 nssn;
};
+/**
+ * enum iwl_bar_frame_release_sta_tid - STA/TID information for BAR release
+ * @IWL_BAR_FRAME_RELEASE_TID_MASK: TID mask
+ * @IWL_BAR_FRAME_RELEASE_STA_MASK: STA mask
+ */
+enum iwl_bar_frame_release_sta_tid {
+ IWL_BAR_FRAME_RELEASE_TID_MASK = 0x0000000f,
+ IWL_BAR_FRAME_RELEASE_STA_MASK = 0x000001f0,
+};
+
+/**
+ * enum iwl_bar_frame_release_ba_info - BA information for BAR release
+ * @IWL_BAR_FRAME_RELEASE_NSSN_MASK: NSSN mask
+ * @IWL_BAR_FRAME_RELEASE_SN_MASK: SN mask (ignored by driver)
+ * @IWL_BAR_FRAME_RELEASE_BAID_MASK: BAID mask
+ */
+enum iwl_bar_frame_release_ba_info {
+ IWL_BAR_FRAME_RELEASE_NSSN_MASK = 0x00000fff,
+ IWL_BAR_FRAME_RELEASE_SN_MASK = 0x00fff000,
+ IWL_BAR_FRAME_RELEASE_BAID_MASK = 0x3f000000,
+};
+
+/**
+ * struct iwl_bar_frame_release - frame release from BAR info
+ * @sta_tid: STA & TID information, see &enum iwl_bar_frame_release_sta_tid.
+ * @ba_info: BA information, see &enum iwl_bar_frame_release_ba_info.
+ */
+struct iwl_bar_frame_release {
+ __le32 sta_tid;
+ __le32 ba_info;
+} __packed; /* RX_BAR_TO_FRAME_RELEASE_API_S_VER_1 */
+
enum iwl_rss_hash_func_en {
IWL_RSS_HASH_TYPE_IPV4_TCP,
IWL_RSS_HASH_TYPE_IPV4_UDP,
diff --git a/drivers/net/wireless/intel/iwlwifi/fw/api/scan.h b/drivers/net/wireless/intel/iwlwifi/fw/api/scan.h
index c4960f045415..39c64850cb6f 100644
--- a/drivers/net/wireless/intel/iwlwifi/fw/api/scan.h
+++ b/drivers/net/wireless/intel/iwlwifi/fw/api/scan.h
@@ -93,6 +93,8 @@ struct iwl_ssid_ie {
#define IWL_SCAN_SHORT_BLACKLIST_LEN 16
#define IWL_SCAN_MAX_PROFILES 11
#define SCAN_OFFLOAD_PROBE_REQ_SIZE 512
+#define SCAN_NUM_BAND_PROBE_DATA_V_1 2
+#define SCAN_NUM_BAND_PROBE_DATA_V_2 3
/* Default watchdog (in MS) for scheduled scan iteration */
#define IWL_SCHED_SCAN_WATCHDOG cpu_to_le16(15000)
@@ -251,9 +253,22 @@ struct iwl_scan_probe_segment {
* @common_data: last (and common) part of the probe
* @buf: raw data block
*/
+struct iwl_scan_probe_req_v1 {
+ struct iwl_scan_probe_segment mac_header;
+ struct iwl_scan_probe_segment band_data[SCAN_NUM_BAND_PROBE_DATA_V_1];
+ struct iwl_scan_probe_segment common_data;
+ u8 buf[SCAN_OFFLOAD_PROBE_REQ_SIZE];
+} __packed;
+
+/* iwl_scan_probe_req - PROBE_REQUEST_FRAME_API_S_VER_v2
+ * @mac_header: first (and common) part of the probe
+ * @band_data: band specific data
+ * @common_data: last (and common) part of the probe
+ * @buf: raw data block
+ */
struct iwl_scan_probe_req {
struct iwl_scan_probe_segment mac_header;
- struct iwl_scan_probe_segment band_data[2];
+ struct iwl_scan_probe_segment band_data[SCAN_NUM_BAND_PROBE_DATA_V_2];
struct iwl_scan_probe_segment common_data;
u8 buf[SCAN_OFFLOAD_PROBE_REQ_SIZE];
} __packed;
@@ -608,15 +623,29 @@ enum iwl_umac_scan_general_flags2 {
* struct iwl_scan_channel_cfg_umac
* @flags: bitmap - 0-19: directed scan to i'th ssid.
* @channel_num: channel number 1-13 etc.
+ * @band: band of channel: 0 for 2GHz, 1 for 5GHz
* @iter_count: repetition count for the channel.
* @iter_interval: interval between two scan iterations on one channel.
*/
-struct iwl_scan_channel_cfg_umac {
+struct iwl_scan_channel_cfg_umac {
__le32 flags;
- u8 channel_num;
- u8 iter_count;
- __le16 iter_interval;
-} __packed; /* SCAN_CHANNEL_CFG_S_VER2 */
+ /* Both versions are of the same size, so use a union without adjusting
+ * the command size later
+ */
+ union {
+ struct {
+ u8 channel_num;
+ u8 iter_count;
+ __le16 iter_interval;
+ } v1; /* SCAN_CHANNEL_CFG_S_VER1 */
+ struct {
+ u8 channel_num;
+ u8 band;
+ u8 iter_count;
+ u8 iter_interval;
+ } v2; /* SCAN_CHANNEL_CFG_S_VER2 */
+ };
+} __packed;
/**
* struct iwl_scan_umac_schedule
@@ -630,6 +659,16 @@ struct iwl_scan_umac_schedule {
u8 reserved;
} __packed; /* SCAN_SCHED_PARAM_API_S_VER_1 */
+struct iwl_scan_req_umac_tail_v1 {
+ /* SCAN_PERIODIC_PARAMS_API_S_VER_1 */
+ struct iwl_scan_umac_schedule schedule[IWL_MAX_SCHED_SCAN_PLANS];
+ __le16 delay;
+ __le16 reserved;
+ /* SCAN_PROBE_PARAMS_API_S_VER_1 */
+ struct iwl_scan_probe_req_v1 preq;
+ struct iwl_ssid_ie direct_scan[PROBE_OPTION_MAX];
+} __packed;
+
/**
* struct iwl_scan_req_umac_tail - the rest of the UMAC scan request command
* parameters following channels configuration array.
@@ -639,12 +678,12 @@ struct iwl_scan_umac_schedule {
* @preq: probe request with IEs blocks
* @direct_scan: list of SSIDs for directed active scan
*/
-struct iwl_scan_req_umac_tail {
+struct iwl_scan_req_umac_tail_v2 {
/* SCAN_PERIODIC_PARAMS_API_S_VER_1 */
struct iwl_scan_umac_schedule schedule[IWL_MAX_SCHED_SCAN_PLANS];
__le16 delay;
__le16 reserved;
- /* SCAN_PROBE_PARAMS_API_S_VER_1 */
+ /* SCAN_PROBE_PARAMS_API_S_VER_2 */
struct iwl_scan_probe_req preq;
struct iwl_ssid_ie direct_scan[PROBE_OPTION_MAX];
} __packed;
diff --git a/drivers/net/wireless/intel/iwlwifi/fw/dbg.c b/drivers/net/wireless/intel/iwlwifi/fw/dbg.c
index 4d81776f576d..87421807e040 100644
--- a/drivers/net/wireless/intel/iwlwifi/fw/dbg.c
+++ b/drivers/net/wireless/intel/iwlwifi/fw/dbg.c
@@ -243,7 +243,7 @@ static void iwl_fw_dump_rxf(struct iwl_fw_runtime *fwrt,
/* Pull RXF2 */
iwl_fwrt_dump_rxf(fwrt, dump_data, cfg->rxfifo2_size,
RXF_DIFF_FROM_PREV +
- fwrt->trans->cfg->umac_prph_offset, 1);
+ fwrt->trans->trans_cfg->umac_prph_offset, 1);
/* Pull LMAC2 RXF1 */
if (fwrt->smem_cfg.num_lmacs > 1)
iwl_fwrt_dump_rxf(fwrt, dump_data,
@@ -468,6 +468,9 @@ static const struct iwl_prph_range iwl_prph_dump_addr_9000[] = {
{ .start = 0x00a05400, .end = 0x00a056e8 },
{ .start = 0x00a08000, .end = 0x00a098bc },
{ .start = 0x00a02400, .end = 0x00a02758 },
+ { .start = 0x00a04764, .end = 0x00a0476c },
+ { .start = 0x00a04770, .end = 0x00a04774 },
+ { .start = 0x00a04620, .end = 0x00a04624 },
};
static const struct iwl_prph_range iwl_prph_dump_addr_22000[] = {
@@ -643,6 +646,7 @@ static struct scatterlist *alloc_sgtable(int size)
if (new_page)
__free_page(new_page);
}
+ kfree(table);
return NULL;
}
alloc_size = min_t(int, size, PAGE_SIZE);
@@ -681,17 +685,18 @@ static void iwl_fw_prph_handler(struct iwl_fw_runtime *fwrt, void *ptr,
{
u32 range_len;
- if (fwrt->trans->cfg->device_family >= IWL_DEVICE_FAMILY_AX210) {
+ if (fwrt->trans->trans_cfg->device_family >= IWL_DEVICE_FAMILY_AX210) {
range_len = ARRAY_SIZE(iwl_prph_dump_addr_ax210);
handler(fwrt, iwl_prph_dump_addr_ax210, range_len, ptr);
- } else if (fwrt->trans->cfg->device_family >= IWL_DEVICE_FAMILY_22000) {
+ } else if (fwrt->trans->trans_cfg->device_family >=
+ IWL_DEVICE_FAMILY_22000) {
range_len = ARRAY_SIZE(iwl_prph_dump_addr_22000);
handler(fwrt, iwl_prph_dump_addr_22000, range_len, ptr);
} else {
range_len = ARRAY_SIZE(iwl_prph_dump_addr_comm);
handler(fwrt, iwl_prph_dump_addr_comm, range_len, ptr);
- if (fwrt->trans->cfg->mq_rx_supported) {
+ if (fwrt->trans->trans_cfg->mq_rx_supported) {
range_len = ARRAY_SIZE(iwl_prph_dump_addr_9000);
handler(fwrt, iwl_prph_dump_addr_9000, range_len, ptr);
}
@@ -853,7 +858,8 @@ iwl_fw_error_dump_file(struct iwl_fw_runtime *fwrt,
iwl_fw_prph_handler(fwrt, &prph_len,
iwl_fw_get_prph_len);
- if (fwrt->trans->cfg->device_family == IWL_DEVICE_FAMILY_7000 &&
+ if (fwrt->trans->trans_cfg->device_family ==
+ IWL_DEVICE_FAMILY_7000 &&
iwl_fw_dbg_type_on(fwrt, IWL_FW_ERROR_DUMP_RADIO_REG))
radio_len = sizeof(*dump_data) + RADIO_REG_MAX_READ;
}
@@ -1103,25 +1109,9 @@ static int iwl_dump_ini_dev_mem_iter(struct iwl_fw_runtime *fwrt,
return sizeof(*range) + le32_to_cpu(range->range_data_size);
}
-static int
-iwl_dump_ini_paging_gen2_iter(struct iwl_fw_runtime *fwrt,
- struct iwl_fw_ini_region_cfg *reg,
- void *range_ptr, int idx)
-{
- struct iwl_fw_ini_error_dump_range *range = range_ptr;
- u32 page_size = fwrt->trans->init_dram.paging[idx].size;
-
- range->page_num = cpu_to_le32(idx);
- range->range_data_size = cpu_to_le32(page_size);
- memcpy(range->data, fwrt->trans->init_dram.paging[idx].block,
- page_size);
-
- return sizeof(*range) + le32_to_cpu(range->range_data_size);
-}
-
-static int iwl_dump_ini_paging_iter(struct iwl_fw_runtime *fwrt,
- struct iwl_fw_ini_region_cfg *reg,
- void *range_ptr, int idx)
+static int _iwl_dump_ini_paging_iter(struct iwl_fw_runtime *fwrt,
+ struct iwl_fw_ini_region_cfg *reg,
+ void *range_ptr, int idx)
{
/* increase idx by 1 since the pages are from 1 to
* fwrt->num_of_paging_blk + 1
@@ -1142,6 +1132,27 @@ static int iwl_dump_ini_paging_iter(struct iwl_fw_runtime *fwrt,
return sizeof(*range) + le32_to_cpu(range->range_data_size);
}
+static int iwl_dump_ini_paging_iter(struct iwl_fw_runtime *fwrt,
+ struct iwl_fw_ini_region_cfg *reg,
+ void *range_ptr, int idx)
+{
+ struct iwl_fw_ini_error_dump_range *range;
+ u32 page_size;
+
+ if (!fwrt->trans->trans_cfg->gen2)
+ return _iwl_dump_ini_paging_iter(fwrt, reg, range_ptr, idx);
+
+ range = range_ptr;
+ page_size = fwrt->trans->init_dram.paging[idx].size;
+
+ range->page_num = cpu_to_le32(idx);
+ range->range_data_size = cpu_to_le32(page_size);
+ memcpy(range->data, fwrt->trans->init_dram.paging[idx].block,
+ page_size);
+
+ return sizeof(*range) + le32_to_cpu(range->range_data_size);
+}
+
static int
iwl_dump_ini_mon_dram_iter(struct iwl_fw_runtime *fwrt,
struct iwl_fw_ini_region_cfg *reg, void *range_ptr,
@@ -1163,35 +1174,23 @@ iwl_dump_ini_mon_dram_iter(struct iwl_fw_runtime *fwrt,
return sizeof(*range) + le32_to_cpu(range->range_data_size);
}
-struct iwl_ini_txf_iter_data {
- int fifo;
- int lmac;
- u32 fifo_size;
- bool internal_txf;
- bool init;
-};
-
static bool iwl_ini_txf_iter(struct iwl_fw_runtime *fwrt,
- struct iwl_fw_ini_region_cfg *reg)
+ struct iwl_fw_ini_region_cfg *reg, int idx)
{
- struct iwl_ini_txf_iter_data *iter = fwrt->dump.fifo_iter;
+ struct iwl_txf_iter_data *iter = &fwrt->dump.txf_iter_data;
struct iwl_fwrt_shared_mem_cfg *cfg = &fwrt->smem_cfg;
int txf_num = cfg->num_txfifo_entries;
int int_txf_num = ARRAY_SIZE(cfg->internal_txfifo_size);
u32 lmac_bitmap = le32_to_cpu(reg->fifos.fid1);
- if (!iter)
- return false;
-
- if (iter->init) {
+ if (!idx) {
if (le32_to_cpu(reg->offset) &&
WARN_ONCE(cfg->num_lmacs == 1,
"Invalid lmac offset: 0x%x\n",
le32_to_cpu(reg->offset)))
return false;
- iter->init = false;
- iter->internal_txf = false;
+ iter->internal_txf = 0;
iter->fifo_size = 0;
iter->fifo = -1;
if (le32_to_cpu(reg->offset))
@@ -1208,7 +1207,7 @@ static bool iwl_ini_txf_iter(struct iwl_fw_runtime *fwrt,
return true;
}
- iter->internal_txf = true;
+ iter->internal_txf = 1;
if (!fw_has_capa(&fwrt->fw->ucode_capa,
IWL_UCODE_TLV_CAPA_EXTEND_SHARED_MEM_CFG))
@@ -1229,7 +1228,7 @@ static int iwl_dump_ini_txf_iter(struct iwl_fw_runtime *fwrt,
void *range_ptr, int idx)
{
struct iwl_fw_ini_error_dump_range *range = range_ptr;
- struct iwl_ini_txf_iter_data *iter;
+ struct iwl_txf_iter_data *iter = &fwrt->dump.txf_iter_data;
struct iwl_fw_ini_error_dump_register *reg_dump = (void *)range->data;
u32 offs = le32_to_cpu(reg->offset), addr;
u32 registers_size =
@@ -1238,14 +1237,12 @@ static int iwl_dump_ini_txf_iter(struct iwl_fw_runtime *fwrt,
unsigned long flags;
int i;
- if (!iwl_ini_txf_iter(fwrt, reg))
+ if (!iwl_ini_txf_iter(fwrt, reg, idx))
return -EIO;
if (!iwl_trans_grab_nic_access(fwrt->trans, &flags))
return -EBUSY;
- iter = fwrt->dump.fifo_iter;
-
range->fifo_hdr.fifo_num = cpu_to_le32(iter->fifo);
range->fifo_hdr.num_of_registers = reg->fifos.num_of_registers;
range->range_data_size = cpu_to_le32(iter->fifo_size + registers_size);
@@ -1448,7 +1445,7 @@ static void
struct iwl_fw_ini_monitor_dump *mon_dump = (void *)data;
u32 write_ptr_addr, write_ptr_msk, cycle_cnt_addr, cycle_cnt_msk;
- switch (fwrt->trans->cfg->device_family) {
+ switch (fwrt->trans->trans_cfg->device_family) {
case IWL_DEVICE_FAMILY_9000:
case IWL_DEVICE_FAMILY_22000:
write_ptr_addr = MON_BUFF_WRPTR_VER2;
@@ -1458,7 +1455,7 @@ static void
break;
default:
IWL_ERR(fwrt, "Unsupported device family %d\n",
- fwrt->trans->cfg->device_family);
+ fwrt->trans->trans_cfg->device_family);
return NULL;
}
@@ -1475,10 +1472,10 @@ static void
struct iwl_fw_ini_monitor_dump *mon_dump = (void *)data;
const struct iwl_cfg *cfg = fwrt->trans->cfg;
- if (fwrt->trans->cfg->device_family != IWL_DEVICE_FAMILY_9000 &&
- fwrt->trans->cfg->device_family != IWL_DEVICE_FAMILY_22000) {
+ if (fwrt->trans->trans_cfg->device_family != IWL_DEVICE_FAMILY_9000 &&
+ fwrt->trans->trans_cfg->device_family != IWL_DEVICE_FAMILY_22000) {
IWL_ERR(fwrt, "Unsupported device family %d\n",
- fwrt->trans->cfg->device_family);
+ fwrt->trans->trans_cfg->device_family);
return NULL;
}
@@ -1496,15 +1493,12 @@ static u32 iwl_dump_ini_mem_ranges(struct iwl_fw_runtime *fwrt,
return le32_to_cpu(reg->internal.num_of_ranges);
}
-static u32 iwl_dump_ini_paging_gen2_ranges(struct iwl_fw_runtime *fwrt,
- struct iwl_fw_ini_region_cfg *reg)
-{
- return fwrt->trans->init_dram.paging_cnt;
-}
-
static u32 iwl_dump_ini_paging_ranges(struct iwl_fw_runtime *fwrt,
struct iwl_fw_ini_region_cfg *reg)
{
+ if (fwrt->trans->trans_cfg->gen2)
+ return fwrt->trans->init_dram.paging_cnt;
+
return fwrt->num_of_paging_blk;
}
@@ -1517,16 +1511,11 @@ static u32 iwl_dump_ini_mon_dram_ranges(struct iwl_fw_runtime *fwrt,
static u32 iwl_dump_ini_txf_ranges(struct iwl_fw_runtime *fwrt,
struct iwl_fw_ini_region_cfg *reg)
{
- struct iwl_ini_txf_iter_data iter = { .init = true };
- void *fifo_iter = fwrt->dump.fifo_iter;
u32 num_of_fifos = 0;
- fwrt->dump.fifo_iter = &iter;
- while (iwl_ini_txf_iter(fwrt, reg))
+ while (iwl_ini_txf_iter(fwrt, reg, num_of_fifos))
num_of_fifos++;
- fwrt->dump.fifo_iter = fifo_iter;
-
return num_of_fifos;
}
@@ -1548,20 +1537,6 @@ static u32 iwl_dump_ini_mem_get_size(struct iwl_fw_runtime *fwrt,
le32_to_cpu(reg->internal.range_data_size));
}
-static u32 iwl_dump_ini_paging_gen2_get_size(struct iwl_fw_runtime *fwrt,
- struct iwl_fw_ini_region_cfg *reg)
-{
- int i;
- u32 range_header_len = sizeof(struct iwl_fw_ini_error_dump_range);
- u32 size = sizeof(struct iwl_fw_ini_error_dump);
-
- for (i = 0; i < iwl_dump_ini_paging_gen2_ranges(fwrt, reg); i++)
- size += range_header_len +
- fwrt->trans->init_dram.paging[i].size;
-
- return size;
-}
-
static u32 iwl_dump_ini_paging_get_size(struct iwl_fw_runtime *fwrt,
struct iwl_fw_ini_region_cfg *reg)
{
@@ -1569,8 +1544,15 @@ static u32 iwl_dump_ini_paging_get_size(struct iwl_fw_runtime *fwrt,
u32 range_header_len = sizeof(struct iwl_fw_ini_error_dump_range);
u32 size = sizeof(struct iwl_fw_ini_error_dump);
- for (i = 1; i <= iwl_dump_ini_paging_ranges(fwrt, reg); i++)
- size += range_header_len + fwrt->fw_paging_db[i].fw_paging_size;
+ if (fwrt->trans->trans_cfg->gen2) {
+ for (i = 0; i < iwl_dump_ini_paging_ranges(fwrt, reg); i++)
+ size += range_header_len +
+ fwrt->trans->init_dram.paging[i].size;
+ } else {
+ for (i = 1; i <= iwl_dump_ini_paging_ranges(fwrt, reg); i++)
+ size += range_header_len +
+ fwrt->fw_paging_db[i].fw_paging_size;
+ }
return size;
}
@@ -1599,25 +1581,21 @@ static u32 iwl_dump_ini_mon_smem_get_size(struct iwl_fw_runtime *fwrt,
static u32 iwl_dump_ini_txf_get_size(struct iwl_fw_runtime *fwrt,
struct iwl_fw_ini_region_cfg *reg)
{
- struct iwl_ini_txf_iter_data iter = { .init = true };
- void *fifo_iter = fwrt->dump.fifo_iter;
+ struct iwl_txf_iter_data *iter = &fwrt->dump.txf_iter_data;
u32 size = 0;
u32 fifo_hdr = sizeof(struct iwl_fw_ini_error_dump_range) +
le32_to_cpu(reg->fifos.num_of_registers) *
sizeof(struct iwl_fw_ini_error_dump_register);
- fwrt->dump.fifo_iter = &iter;
- while (iwl_ini_txf_iter(fwrt, reg)) {
+ while (iwl_ini_txf_iter(fwrt, reg, size)) {
size += fifo_hdr;
if (!reg->fifos.header_only)
- size += iter.fifo_size;
+ size += iter->fifo_size;
}
if (size)
size += sizeof(struct iwl_fw_ini_error_dump);
- fwrt->dump.fifo_iter = fifo_iter;
-
return size;
}
@@ -1661,38 +1639,50 @@ struct iwl_dump_ini_mem_ops {
};
/**
- * iwl_dump_ini_mem - copy a memory region into the dump
- * @fwrt: fw runtime struct.
- * @data: dump memory data.
- * @reg: region to copy to the dump.
- * @ops: memory dump operations.
+ * iwl_dump_ini_mem
+ *
+ * Creates a dump tlv and copy a memory region into it.
+ * Returns the size of the current dump tlv or 0 if failed
+ *
+ * @fwrt: fw runtime struct
+ * @list: list to add the dump tlv to
+ * @reg: memory region
+ * @ops: memory dump operations
*/
-static void
-iwl_dump_ini_mem(struct iwl_fw_runtime *fwrt,
- struct iwl_fw_error_dump_data **data,
- struct iwl_fw_ini_region_cfg *reg,
- struct iwl_dump_ini_mem_ops *ops)
+static u32 iwl_dump_ini_mem(struct iwl_fw_runtime *fwrt, struct list_head *list,
+ struct iwl_fw_ini_region_cfg *reg,
+ const struct iwl_dump_ini_mem_ops *ops)
{
- struct iwl_fw_ini_error_dump_header *header = (void *)(*data)->data;
+ struct iwl_fw_ini_dump_entry *entry;
+ struct iwl_fw_error_dump_data *tlv;
+ struct iwl_fw_ini_error_dump_header *header;
u32 num_of_ranges, i, type = le32_to_cpu(reg->region_type), size;
void *range;
- if (WARN_ON(!ops || !ops->get_num_of_ranges || !ops->get_size ||
- !ops->fill_mem_hdr || !ops->fill_range))
- return;
+ if (!ops->get_num_of_ranges || !ops->get_size || !ops->fill_mem_hdr ||
+ !ops->fill_range)
+ return 0;
size = ops->get_size(fwrt, reg);
if (!size)
- return;
+ return 0;
+
+ entry = kmalloc(sizeof(*entry) + sizeof(*tlv) + size, GFP_KERNEL);
+ if (!entry)
+ return 0;
+
+ entry->size = sizeof(*tlv) + size;
- IWL_DEBUG_FW(fwrt, "WRT: collecting region: id=%d, type=%d\n",
+ tlv = (void *)entry->data;
+ tlv->type = cpu_to_le32(type);
+ tlv->len = cpu_to_le32(size);
+
+ IWL_DEBUG_FW(fwrt, "WRT: Collecting region: id=%d, type=%d\n",
le32_to_cpu(reg->region_id), type);
num_of_ranges = ops->get_num_of_ranges(fwrt, reg);
- (*data)->type = cpu_to_le32(type);
- (*data)->len = cpu_to_le32(size);
-
+ header = (void *)tlv->data;
header->region_id = reg->region_id;
header->num_of_ranges = cpu_to_le32(num_of_ranges);
header->name_len = cpu_to_le32(min_t(int, IWL_FW_INI_MAX_NAME,
@@ -1702,10 +1692,9 @@ iwl_dump_ini_mem(struct iwl_fw_runtime *fwrt,
range = ops->fill_mem_hdr(fwrt, reg, header);
if (!range) {
IWL_ERR(fwrt,
- "WRT: failed to fill region header: id=%d, type=%d\n",
+ "WRT: Failed to fill region header: id=%d, type=%d\n",
le32_to_cpu(reg->region_id), type);
- memset(*data, 0, size);
- return;
+ goto out_err;
}
for (i = 0; i < num_of_ranges; i++) {
@@ -1713,30 +1702,49 @@ iwl_dump_ini_mem(struct iwl_fw_runtime *fwrt,
if (range_size < 0) {
IWL_ERR(fwrt,
- "WRT: failed to dump region: id=%d, type=%d\n",
+ "WRT: Failed to dump region: id=%d, type=%d\n",
le32_to_cpu(reg->region_id), type);
- memset(*data, 0, size);
- return;
+ goto out_err;
}
range = range + range_size;
}
- *data = iwl_fw_error_next_data(*data);
+
+ list_add_tail(&entry->list, list);
+
+ return entry->size;
+
+out_err:
+ kfree(entry);
+
+ return 0;
}
-static void iwl_dump_ini_info(struct iwl_fw_runtime *fwrt,
- struct iwl_fw_ini_trigger *trigger,
- struct iwl_fw_error_dump_data **data)
+static u32 iwl_dump_ini_info(struct iwl_fw_runtime *fwrt,
+ struct iwl_fw_ini_trigger *trigger,
+ struct list_head *list)
{
- struct iwl_fw_ini_dump_info *dump = (void *)(*data)->data;
+ struct iwl_fw_ini_dump_entry *entry;
+ struct iwl_fw_error_dump_data *tlv;
+ struct iwl_fw_ini_dump_info *dump;
u32 reg_ids_size = le32_to_cpu(trigger->num_regions) * sizeof(__le32);
+ u32 size = sizeof(*tlv) + sizeof(*dump) + reg_ids_size;
- (*data)->type = cpu_to_le32(IWL_INI_DUMP_INFO_TYPE);
- (*data)->len = cpu_to_le32(sizeof(*dump) + reg_ids_size);
+ entry = kmalloc(sizeof(*entry) + size, GFP_KERNEL);
+ if (!entry)
+ return 0;
+
+ entry->size = size;
+
+ tlv = (void *)entry->data;
+ tlv->type = cpu_to_le32(IWL_INI_DUMP_INFO_TYPE);
+ tlv->len = cpu_to_le32(sizeof(*dump) + reg_ids_size);
+
+ dump = (void *)tlv->data;
dump->version = cpu_to_le32(IWL_INI_DUMP_VER);
dump->trigger_id = trigger->trigger_id;
dump->is_external_cfg =
- cpu_to_le32(fwrt->trans->dbg.external_ini_loaded);
+ cpu_to_le32(fwrt->trans->dbg.external_ini_cfg);
dump->ver_type = cpu_to_le32(fwrt->dump.fw_ver.type);
dump->ver_subtype = cpu_to_le32(fwrt->dump.fw_ver.subtype);
@@ -1770,30 +1778,98 @@ static void iwl_dump_ini_info(struct iwl_fw_runtime *fwrt,
dump->external_dbg_cfg_name_len =
cpu_to_le32(sizeof(dump->external_dbg_cfg_name));
- /* dump info size is allocated in iwl_fw_ini_get_trigger_len.
- * The driver allocates (sizeof(*dump) + reg_ids_size) so it is safe to
- * use reg_ids_size
- */
memcpy(dump->external_dbg_cfg_name, fwrt->dump.external_dbg_cfg_name,
sizeof(dump->external_dbg_cfg_name));
dump->regions_num = trigger->num_regions;
memcpy(dump->region_ids, trigger->data, reg_ids_size);
- *data = iwl_fw_error_next_data(*data);
+ /* add dump info TLV to the beginning of the list since it needs to be
+ * the first TLV in the dump
+ */
+ list_add(&entry->list, list);
+
+ return entry->size;
}
-static int iwl_fw_ini_get_trigger_len(struct iwl_fw_runtime *fwrt,
- struct iwl_fw_ini_trigger *trigger)
-{
- int i, ret_size = 0, hdr_len = sizeof(struct iwl_fw_error_dump_data);
- u32 size;
+static const struct iwl_dump_ini_mem_ops iwl_dump_ini_region_ops[] = {
+ [IWL_FW_INI_REGION_INVALID] = {},
+ [IWL_FW_INI_REGION_DEVICE_MEMORY] = {
+ .get_num_of_ranges = iwl_dump_ini_mem_ranges,
+ .get_size = iwl_dump_ini_mem_get_size,
+ .fill_mem_hdr = iwl_dump_ini_mem_fill_header,
+ .fill_range = iwl_dump_ini_dev_mem_iter,
+ },
+ [IWL_FW_INI_REGION_PERIPHERY_MAC] = {
+ .get_num_of_ranges = iwl_dump_ini_mem_ranges,
+ .get_size = iwl_dump_ini_mem_get_size,
+ .fill_mem_hdr = iwl_dump_ini_mem_fill_header,
+ .fill_range = iwl_dump_ini_prph_iter,
+ },
+ [IWL_FW_INI_REGION_PERIPHERY_PHY] = {},
+ [IWL_FW_INI_REGION_PERIPHERY_AUX] = {},
+ [IWL_FW_INI_REGION_DRAM_BUFFER] = {
+ .get_num_of_ranges = iwl_dump_ini_mon_dram_ranges,
+ .get_size = iwl_dump_ini_mon_dram_get_size,
+ .fill_mem_hdr = iwl_dump_ini_mon_dram_fill_header,
+ .fill_range = iwl_dump_ini_mon_dram_iter,
+ },
+ [IWL_FW_INI_REGION_DRAM_IMR] = {},
+ [IWL_FW_INI_REGION_INTERNAL_BUFFER] = {
+ .get_num_of_ranges = iwl_dump_ini_mem_ranges,
+ .get_size = iwl_dump_ini_mon_smem_get_size,
+ .fill_mem_hdr = iwl_dump_ini_mon_smem_fill_header,
+ .fill_range = iwl_dump_ini_dev_mem_iter,
+ },
+ [IWL_FW_INI_REGION_TXF] = {
+ .get_num_of_ranges = iwl_dump_ini_txf_ranges,
+ .get_size = iwl_dump_ini_txf_get_size,
+ .fill_mem_hdr = iwl_dump_ini_mem_fill_header,
+ .fill_range = iwl_dump_ini_txf_iter,
+ },
+ [IWL_FW_INI_REGION_RXF] = {
+ .get_num_of_ranges = iwl_dump_ini_rxf_ranges,
+ .get_size = iwl_dump_ini_rxf_get_size,
+ .fill_mem_hdr = iwl_dump_ini_mem_fill_header,
+ .fill_range = iwl_dump_ini_rxf_iter,
+ },
+ [IWL_FW_INI_REGION_PAGING] = {
+ .fill_mem_hdr = iwl_dump_ini_mem_fill_header,
+ .get_num_of_ranges = iwl_dump_ini_paging_ranges,
+ .get_size = iwl_dump_ini_paging_get_size,
+ .fill_range = iwl_dump_ini_paging_iter,
+ },
+ [IWL_FW_INI_REGION_CSR] = {
+ .get_num_of_ranges = iwl_dump_ini_mem_ranges,
+ .get_size = iwl_dump_ini_mem_get_size,
+ .fill_mem_hdr = iwl_dump_ini_mem_fill_header,
+ .fill_range = iwl_dump_ini_csr_iter,
+ },
+ [IWL_FW_INI_REGION_NOTIFICATION] = {},
+ [IWL_FW_INI_REGION_DHC] = {},
+ [IWL_FW_INI_REGION_LMAC_ERROR_TABLE] = {
+ .get_num_of_ranges = iwl_dump_ini_mem_ranges,
+ .get_size = iwl_dump_ini_mem_get_size,
+ .fill_mem_hdr = iwl_dump_ini_mem_fill_header,
+ .fill_range = iwl_dump_ini_dev_mem_iter,
+ },
+ [IWL_FW_INI_REGION_UMAC_ERROR_TABLE] = {
+ .get_num_of_ranges = iwl_dump_ini_mem_ranges,
+ .get_size = iwl_dump_ini_mem_get_size,
+ .fill_mem_hdr = iwl_dump_ini_mem_fill_header,
+ .fill_range = iwl_dump_ini_dev_mem_iter,
+ },
+};
- if (!trigger || !trigger->num_regions)
- return 0;
+static u32 iwl_dump_ini_trigger(struct iwl_fw_runtime *fwrt,
+ struct iwl_fw_ini_trigger *trigger,
+ struct list_head *list)
+{
+ int i;
+ u32 size = 0;
for (i = 0; i < le32_to_cpu(trigger->num_regions); i++) {
- u32 reg_id = le32_to_cpu(trigger->data[i]);
+ u32 reg_id = le32_to_cpu(trigger->data[i]), reg_type;
struct iwl_fw_ini_region_cfg *reg;
if (WARN_ON(reg_id >= ARRAY_SIZE(fwrt->dump.active_regs)))
@@ -1802,7 +1878,7 @@ static int iwl_fw_ini_get_trigger_len(struct iwl_fw_runtime *fwrt,
reg = fwrt->dump.active_regs[reg_id];
if (!reg) {
IWL_WARN(fwrt,
- "WRT: unassigned region id %d, skipping\n",
+ "WRT: Unassigned region id %d, skipping\n",
reg_id);
continue;
}
@@ -1811,205 +1887,55 @@ static int iwl_fw_ini_get_trigger_len(struct iwl_fw_runtime *fwrt,
if (le32_to_cpu(reg->domain) != IWL_FW_INI_DBG_DOMAIN_ALWAYS_ON)
continue;
- switch (le32_to_cpu(reg->region_type)) {
- case IWL_FW_INI_REGION_DEVICE_MEMORY:
- case IWL_FW_INI_REGION_PERIPHERY_MAC:
- case IWL_FW_INI_REGION_PERIPHERY_PHY:
- case IWL_FW_INI_REGION_PERIPHERY_AUX:
- case IWL_FW_INI_REGION_CSR:
- case IWL_FW_INI_REGION_LMAC_ERROR_TABLE:
- case IWL_FW_INI_REGION_UMAC_ERROR_TABLE:
- size = iwl_dump_ini_mem_get_size(fwrt, reg);
- if (size)
- ret_size += hdr_len + size;
- break;
- case IWL_FW_INI_REGION_TXF:
- size = iwl_dump_ini_txf_get_size(fwrt, reg);
- if (size)
- ret_size += hdr_len + size;
- break;
- case IWL_FW_INI_REGION_RXF:
- size = iwl_dump_ini_rxf_get_size(fwrt, reg);
- if (size)
- ret_size += hdr_len + size;
- break;
- case IWL_FW_INI_REGION_PAGING:
- if (iwl_fw_dbg_is_paging_enabled(fwrt))
- size = iwl_dump_ini_paging_get_size(fwrt, reg);
- else
- size = iwl_dump_ini_paging_gen2_get_size(fwrt,
- reg);
- if (size)
- ret_size += hdr_len + size;
- break;
- case IWL_FW_INI_REGION_DRAM_BUFFER:
- if (!fwrt->trans->dbg.num_blocks)
- break;
- size = iwl_dump_ini_mon_dram_get_size(fwrt, reg);
- if (size)
- ret_size += hdr_len + size;
- break;
- case IWL_FW_INI_REGION_INTERNAL_BUFFER:
- size = iwl_dump_ini_mon_smem_get_size(fwrt, reg);
- if (size)
- ret_size += hdr_len + size;
- break;
- case IWL_FW_INI_REGION_DRAM_IMR:
- /* Undefined yet */
- default:
- break;
- }
- }
-
- /* add dump info size */
- if (ret_size)
- ret_size += hdr_len + sizeof(struct iwl_fw_ini_dump_info) +
- (le32_to_cpu(trigger->num_regions) * sizeof(__le32));
-
- return ret_size;
-}
-
-static void iwl_fw_ini_dump_trigger(struct iwl_fw_runtime *fwrt,
- struct iwl_fw_ini_trigger *trigger,
- struct iwl_fw_error_dump_data **data)
-{
- int i, num = le32_to_cpu(trigger->num_regions);
-
- iwl_dump_ini_info(fwrt, trigger, data);
-
- for (i = 0; i < num; i++) {
- u32 reg_id = le32_to_cpu(trigger->data[i]);
- struct iwl_fw_ini_region_cfg *reg;
- struct iwl_dump_ini_mem_ops ops;
-
- if (reg_id >= ARRAY_SIZE(fwrt->dump.active_regs))
+ reg_type = le32_to_cpu(reg->region_type);
+ if (reg_type >= ARRAY_SIZE(iwl_dump_ini_region_ops))
continue;
- reg = fwrt->dump.active_regs[reg_id];
- /* Don't warn, get_trigger_len already warned */
- if (!reg)
- continue;
-
- /* currently the driver supports always on domain only */
- if (le32_to_cpu(reg->domain) != IWL_FW_INI_DBG_DOMAIN_ALWAYS_ON)
- continue;
+ size += iwl_dump_ini_mem(fwrt, list, reg,
+ &iwl_dump_ini_region_ops[reg_type]);
+ }
- switch (le32_to_cpu(reg->region_type)) {
- case IWL_FW_INI_REGION_DEVICE_MEMORY:
- case IWL_FW_INI_REGION_LMAC_ERROR_TABLE:
- case IWL_FW_INI_REGION_UMAC_ERROR_TABLE:
- ops.get_num_of_ranges = iwl_dump_ini_mem_ranges;
- ops.get_size = iwl_dump_ini_mem_get_size;
- ops.fill_mem_hdr = iwl_dump_ini_mem_fill_header;
- ops.fill_range = iwl_dump_ini_dev_mem_iter;
- iwl_dump_ini_mem(fwrt, data, reg, &ops);
- break;
- case IWL_FW_INI_REGION_PERIPHERY_MAC:
- case IWL_FW_INI_REGION_PERIPHERY_PHY:
- case IWL_FW_INI_REGION_PERIPHERY_AUX:
- ops.get_num_of_ranges = iwl_dump_ini_mem_ranges;
- ops.get_size = iwl_dump_ini_mem_get_size;
- ops.fill_mem_hdr = iwl_dump_ini_mem_fill_header;
- ops.fill_range = iwl_dump_ini_prph_iter;
- iwl_dump_ini_mem(fwrt, data, reg, &ops);
- break;
- case IWL_FW_INI_REGION_DRAM_BUFFER:
- ops.get_num_of_ranges = iwl_dump_ini_mon_dram_ranges;
- ops.get_size = iwl_dump_ini_mon_dram_get_size;
- ops.fill_mem_hdr = iwl_dump_ini_mon_dram_fill_header;
- ops.fill_range = iwl_dump_ini_mon_dram_iter;
- iwl_dump_ini_mem(fwrt, data, reg, &ops);
- break;
- case IWL_FW_INI_REGION_INTERNAL_BUFFER:
- ops.get_num_of_ranges = iwl_dump_ini_mem_ranges;
- ops.get_size = iwl_dump_ini_mon_smem_get_size;
- ops.fill_mem_hdr = iwl_dump_ini_mon_smem_fill_header;
- ops.fill_range = iwl_dump_ini_dev_mem_iter;
- iwl_dump_ini_mem(fwrt, data, reg, &ops);
- break;
- case IWL_FW_INI_REGION_PAGING:
- ops.fill_mem_hdr = iwl_dump_ini_mem_fill_header;
- if (iwl_fw_dbg_is_paging_enabled(fwrt)) {
- ops.get_num_of_ranges =
- iwl_dump_ini_paging_ranges;
- ops.get_size = iwl_dump_ini_paging_get_size;
- ops.fill_range = iwl_dump_ini_paging_iter;
- } else {
- ops.get_num_of_ranges =
- iwl_dump_ini_paging_gen2_ranges;
- ops.get_size =
- iwl_dump_ini_paging_gen2_get_size;
- ops.fill_range = iwl_dump_ini_paging_gen2_iter;
- }
+ if (size)
+ size += iwl_dump_ini_info(fwrt, trigger, list);
- iwl_dump_ini_mem(fwrt, data, reg, &ops);
- break;
- case IWL_FW_INI_REGION_TXF: {
- struct iwl_ini_txf_iter_data iter = { .init = true };
- void *fifo_iter = fwrt->dump.fifo_iter;
-
- fwrt->dump.fifo_iter = &iter;
- ops.get_num_of_ranges = iwl_dump_ini_txf_ranges;
- ops.get_size = iwl_dump_ini_txf_get_size;
- ops.fill_mem_hdr = iwl_dump_ini_mem_fill_header;
- ops.fill_range = iwl_dump_ini_txf_iter;
- iwl_dump_ini_mem(fwrt, data, reg, &ops);
- fwrt->dump.fifo_iter = fifo_iter;
- break;
- }
- case IWL_FW_INI_REGION_RXF:
- ops.get_num_of_ranges = iwl_dump_ini_rxf_ranges;
- ops.get_size = iwl_dump_ini_rxf_get_size;
- ops.fill_mem_hdr = iwl_dump_ini_mem_fill_header;
- ops.fill_range = iwl_dump_ini_rxf_iter;
- iwl_dump_ini_mem(fwrt, data, reg, &ops);
- break;
- case IWL_FW_INI_REGION_CSR:
- ops.get_num_of_ranges = iwl_dump_ini_mem_ranges;
- ops.get_size = iwl_dump_ini_mem_get_size;
- ops.fill_mem_hdr = iwl_dump_ini_mem_fill_header;
- ops.fill_range = iwl_dump_ini_csr_iter;
- iwl_dump_ini_mem(fwrt, data, reg, &ops);
- break;
- case IWL_FW_INI_REGION_DRAM_IMR:
- /* This is undefined yet */
- default:
- break;
- }
- }
+ return size;
}
-static struct iwl_fw_error_dump_file *
-iwl_fw_error_ini_dump_file(struct iwl_fw_runtime *fwrt,
- enum iwl_fw_ini_trigger_id trig_id)
+static u32 iwl_dump_ini_file_gen(struct iwl_fw_runtime *fwrt,
+ enum iwl_fw_ini_trigger_id trig_id,
+ struct list_head *list)
{
- int size;
- struct iwl_fw_error_dump_data *dump_data;
- struct iwl_fw_error_dump_file *dump_file;
+ struct iwl_fw_ini_dump_entry *entry;
+ struct iwl_fw_ini_dump_file_hdr *hdr;
struct iwl_fw_ini_trigger *trigger;
+ u32 size;
if (!iwl_fw_ini_trigger_on(fwrt, trig_id))
- return NULL;
+ return 0;
trigger = fwrt->dump.active_trigs[trig_id].trig;
+ if (!trigger || !le32_to_cpu(trigger->num_regions))
+ return 0;
- size = iwl_fw_ini_get_trigger_len(fwrt, trigger);
- if (!size)
- return NULL;
+ entry = kmalloc(sizeof(*entry) + sizeof(*hdr), GFP_KERNEL);
+ if (!entry)
+ return 0;
- size += sizeof(*dump_file);
+ entry->size = sizeof(*hdr);
- dump_file = vzalloc(size);
- if (!dump_file)
- return NULL;
+ size = iwl_dump_ini_trigger(fwrt, trigger, list);
+ if (!size) {
+ kfree(entry);
+ return 0;
+ }
- dump_file->barker = cpu_to_le32(IWL_FW_INI_ERROR_DUMP_BARKER);
- dump_data = (void *)dump_file->data;
- dump_file->file_len = cpu_to_le32(size);
+ hdr = (void *)entry->data;
+ hdr->barker = cpu_to_le32(IWL_FW_INI_ERROR_DUMP_BARKER);
+ hdr->file_len = cpu_to_le32(size + entry->size);
- iwl_fw_ini_dump_trigger(fwrt, trigger, &dump_data);
+ list_add(&entry->list, list);
- return dump_file;
+ return le32_to_cpu(hdr->file_len);
}
static void iwl_fw_error_dump(struct iwl_fw_runtime *fwrt)
@@ -2058,27 +1984,44 @@ out:
iwl_fw_free_dump_desc(fwrt);
}
+static void iwl_dump_ini_list_free(struct list_head *list)
+{
+ while (!list_empty(list)) {
+ struct iwl_fw_ini_dump_entry *entry =
+ list_entry(list->next, typeof(*entry), list);
+
+ list_del(&entry->list);
+ kfree(entry);
+ }
+}
+
static void iwl_fw_error_ini_dump(struct iwl_fw_runtime *fwrt, u8 wk_idx)
{
enum iwl_fw_ini_trigger_id trig_id = fwrt->dump.wks[wk_idx].ini_trig_id;
- struct iwl_fw_error_dump_file *dump_file;
+ struct list_head dump_list = LIST_HEAD_INIT(dump_list);
struct scatterlist *sg_dump_data;
u32 file_len;
- dump_file = iwl_fw_error_ini_dump_file(fwrt, trig_id);
- if (!dump_file)
+ file_len = iwl_dump_ini_file_gen(fwrt, trig_id, &dump_list);
+ if (!file_len)
goto out;
- file_len = le32_to_cpu(dump_file->file_len);
-
sg_dump_data = alloc_sgtable(file_len);
if (sg_dump_data) {
- sg_pcopy_from_buffer(sg_dump_data, sg_nents(sg_dump_data),
- dump_file, file_len, 0);
+ struct iwl_fw_ini_dump_entry *entry;
+ int sg_entries = sg_nents(sg_dump_data);
+ u32 offs = 0;
+
+ list_for_each_entry(entry, &dump_list, list) {
+ sg_pcopy_from_buffer(sg_dump_data, sg_entries,
+ entry->data, entry->size, offs);
+ offs += entry->size;
+ }
dev_coredumpsg(fwrt->trans->dev, sg_dump_data, file_len,
GFP_KERNEL);
}
- vfree(dump_file);
+ iwl_dump_ini_list_free(&dump_list);
+
out:
fwrt->dump.wks[wk_idx].ini_trig_id = IWL_FW_TRIGGER_ID_INVALID;
}
@@ -2098,7 +2041,7 @@ int iwl_fw_dbg_collect_desc(struct iwl_fw_runtime *fwrt,
u32 trig_type = le32_to_cpu(desc->trig_desc.type);
int ret;
- if (fwrt->trans->dbg.ini_valid) {
+ if (iwl_trans_dbg_ini_valid(fwrt->trans)) {
ret = iwl_fw_dbg_ini_collect(fwrt, trig_type);
if (!ret)
iwl_fw_free_dump_desc(fwrt);
@@ -2220,7 +2163,7 @@ int _iwl_fw_dbg_ini_collect(struct iwl_fw_runtime *fwrt,
active->trig->occurrences = cpu_to_le32(--occur);
if (le32_to_cpu(active->trig->force_restart)) {
- IWL_WARN(fwrt, "WRT: force restart: trigger %d fired.\n", id);
+ IWL_WARN(fwrt, "WRT: Force restart: trigger %d fired.\n", id);
iwl_force_nmi(fwrt->trans);
return 0;
}
@@ -2240,7 +2183,7 @@ int _iwl_fw_dbg_ini_collect(struct iwl_fw_runtime *fwrt,
fwrt->dump.wks[idx].ini_trig_id = id;
- IWL_WARN(fwrt, "WRT: collecting data: ini trigger %d fired.\n", id);
+ IWL_WARN(fwrt, "WRT: Collecting data: ini trigger %d fired.\n", id);
schedule_delayed_work(&fwrt->dump.wks[idx].wk, usecs_to_jiffies(delay));
@@ -2372,16 +2315,19 @@ static void iwl_fw_dbg_collect_sync(struct iwl_fw_runtime *fwrt, u8 wk_idx)
goto out;
}
- iwl_fw_dbg_stop_recording(fwrt->trans, &params);
+ if (iwl_fw_dbg_stop_restart_recording(fwrt, &params, true)) {
+ IWL_ERR(fwrt, "Failed to stop DBGC recording, aborting dump\n");
+ goto out;
+ }
- IWL_DEBUG_FW_INFO(fwrt, "WRT: data collection start\n");
- if (fwrt->trans->dbg.ini_valid)
+ IWL_DEBUG_FW_INFO(fwrt, "WRT: Data collection start\n");
+ if (iwl_trans_dbg_ini_valid(fwrt->trans))
iwl_fw_error_ini_dump(fwrt, wk_idx);
else
iwl_fw_error_dump(fwrt);
- IWL_DEBUG_FW_INFO(fwrt, "WRT: data collection done\n");
+ IWL_DEBUG_FW_INFO(fwrt, "WRT: Data collection done\n");
- iwl_fw_dbg_restart_recording(fwrt, &params);
+ iwl_fw_dbg_stop_restart_recording(fwrt, &params, false);
out:
clear_bit(wk_idx, &fwrt->dump.active_wks);
@@ -2432,472 +2378,17 @@ void iwl_fw_dbg_read_d3_debug_data(struct iwl_fw_runtime *fwrt)
}
IWL_EXPORT_SYMBOL(iwl_fw_dbg_read_d3_debug_data);
-static void iwl_fw_dbg_info_apply(struct iwl_fw_runtime *fwrt,
- struct iwl_fw_ini_debug_info_tlv *dbg_info,
- bool ext, enum iwl_fw_ini_apply_point pnt)
-{
- u32 img_name_len = le32_to_cpu(dbg_info->img_name_len);
- u32 dbg_cfg_name_len = le32_to_cpu(dbg_info->dbg_cfg_name_len);
-
- if (img_name_len != IWL_FW_INI_MAX_IMG_NAME_LEN) {
- IWL_WARN(fwrt,
- "WRT: ext=%d. Invalid image name length %d, expected %d\n",
- ext, img_name_len,
- IWL_FW_INI_MAX_IMG_NAME_LEN);
- return;
- }
-
- if (dbg_cfg_name_len != IWL_FW_INI_MAX_DBG_CFG_NAME_LEN) {
- IWL_WARN(fwrt,
- "WRT: ext=%d. Invalid debug cfg name length %d, expected %d\n",
- ext, dbg_cfg_name_len,
- IWL_FW_INI_MAX_DBG_CFG_NAME_LEN);
- return;
- }
-
- if (ext) {
- memcpy(fwrt->dump.external_dbg_cfg_name, dbg_info->dbg_cfg_name,
- sizeof(fwrt->dump.external_dbg_cfg_name));
- } else {
- memcpy(fwrt->dump.img_name, dbg_info->img_name,
- sizeof(fwrt->dump.img_name));
- memcpy(fwrt->dump.internal_dbg_cfg_name, dbg_info->dbg_cfg_name,
- sizeof(fwrt->dump.internal_dbg_cfg_name));
- }
-}
-
-static void
-iwl_fw_dbg_buffer_allocation(struct iwl_fw_runtime *fwrt, u32 size)
-{
- struct iwl_trans *trans = fwrt->trans;
- void *virtual_addr = NULL;
- dma_addr_t phys_addr;
-
- if (WARN_ON_ONCE(trans->dbg.num_blocks ==
- ARRAY_SIZE(trans->dbg.fw_mon)))
- return;
-
- virtual_addr =
- dma_alloc_coherent(fwrt->trans->dev, size, &phys_addr,
- GFP_KERNEL | __GFP_NOWARN | __GFP_ZERO |
- __GFP_COMP);
-
- /* TODO: alloc fragments if needed */
- if (!virtual_addr)
- IWL_ERR(fwrt, "Failed to allocate debug memory\n");
-
- IWL_DEBUG_FW(trans,
- "Allocated DRAM buffer[%d], size=0x%x\n",
- trans->dbg.num_blocks, size);
-
- trans->dbg.fw_mon[trans->dbg.num_blocks].block = virtual_addr;
- trans->dbg.fw_mon[trans->dbg.num_blocks].physical = phys_addr;
- trans->dbg.fw_mon[trans->dbg.num_blocks].size = size;
- trans->dbg.num_blocks++;
-}
-
-static void iwl_fw_dbg_buffer_apply(struct iwl_fw_runtime *fwrt,
- struct iwl_fw_ini_allocation_data *alloc,
- enum iwl_fw_ini_apply_point pnt)
-{
- struct iwl_trans *trans = fwrt->trans;
- struct iwl_ldbg_config_cmd ldbg_cmd = {
- .type = cpu_to_le32(BUFFER_ALLOCATION),
- };
- struct iwl_buffer_allocation_cmd *cmd = &ldbg_cmd.buffer_allocation;
- struct iwl_host_cmd hcmd = {
- .id = LDBG_CONFIG_CMD,
- .flags = CMD_ASYNC,
- .data[0] = &ldbg_cmd,
- .len[0] = sizeof(ldbg_cmd),
- };
- int block_idx = trans->dbg.num_blocks;
- u32 buf_location = le32_to_cpu(alloc->tlv.buffer_location);
-
- if (fwrt->trans->dbg.ini_dest == IWL_FW_INI_LOCATION_INVALID)
- fwrt->trans->dbg.ini_dest = buf_location;
-
- if (buf_location != fwrt->trans->dbg.ini_dest) {
- WARN(fwrt,
- "WRT: attempt to override buffer location on apply point %d\n",
- pnt);
-
- return;
- }
-
- if (buf_location == IWL_FW_INI_LOCATION_SRAM_PATH) {
- IWL_DEBUG_FW(trans, "WRT: applying SMEM buffer destination\n");
- /* set sram monitor by enabling bit 7 */
- iwl_set_bit(fwrt->trans, CSR_HW_IF_CONFIG_REG,
- CSR_HW_IF_CONFIG_REG_BIT_MONITOR_SRAM);
-
- return;
- }
-
- if (buf_location != IWL_FW_INI_LOCATION_DRAM_PATH)
- return;
-
- if (!alloc->is_alloc) {
- iwl_fw_dbg_buffer_allocation(fwrt,
- le32_to_cpu(alloc->tlv.size));
- if (block_idx == trans->dbg.num_blocks)
- return;
- alloc->is_alloc = 1;
- }
-
- /* First block is assigned via registers / context info */
- if (trans->dbg.num_blocks == 1)
- return;
-
- IWL_DEBUG_FW(trans,
- "WRT: applying DRAM buffer[%d] destination\n", block_idx);
-
- cmd->num_frags = cpu_to_le32(1);
- cmd->fragments[0].address =
- cpu_to_le64(trans->dbg.fw_mon[block_idx].physical);
- cmd->fragments[0].size = alloc->tlv.size;
- cmd->allocation_id = alloc->tlv.allocation_id;
- cmd->buffer_location = alloc->tlv.buffer_location;
-
- iwl_trans_send_cmd(trans, &hcmd);
-}
-
-static void iwl_fw_dbg_send_hcmd(struct iwl_fw_runtime *fwrt,
- struct iwl_ucode_tlv *tlv,
- bool ext)
-{
- struct iwl_fw_ini_hcmd_tlv *hcmd_tlv = (void *)&tlv->data[0];
- struct iwl_fw_ini_hcmd *data = &hcmd_tlv->hcmd;
- u16 len = le32_to_cpu(tlv->length) - sizeof(*hcmd_tlv);
-
- struct iwl_host_cmd hcmd = {
- .id = WIDE_ID(data->group, data->id),
- .len = { len, },
- .data = { data->data, },
- };
-
- /* currently the driver supports always on domain only */
- if (le32_to_cpu(hcmd_tlv->domain) != IWL_FW_INI_DBG_DOMAIN_ALWAYS_ON)
- return;
-
- IWL_DEBUG_FW(fwrt,
- "WRT: ext=%d. Sending host command id=0x%x, group=0x%x\n",
- ext, data->id, data->group);
-
- iwl_trans_send_cmd(fwrt->trans, &hcmd);
-}
-
-static void iwl_fw_dbg_update_regions(struct iwl_fw_runtime *fwrt,
- struct iwl_fw_ini_region_tlv *tlv,
- bool ext, enum iwl_fw_ini_apply_point pnt)
-{
- void *iter = (void *)tlv->region_config;
- int i, size = le32_to_cpu(tlv->num_regions);
- const char *err_st =
- "WRT: ext=%d. Invalid region %s %d for apply point %d\n";
-
- for (i = 0; i < size; i++) {
- struct iwl_fw_ini_region_cfg *reg = iter, **active;
- int id = le32_to_cpu(reg->region_id);
- u32 type = le32_to_cpu(reg->region_type);
-
- if (WARN(id >= ARRAY_SIZE(fwrt->dump.active_regs), err_st, ext,
- "id", id, pnt))
- break;
-
- if (WARN(type == 0 || type >= IWL_FW_INI_REGION_NUM, err_st,
- ext, "type", type, pnt))
- break;
-
- active = &fwrt->dump.active_regs[id];
-
- if (*active)
- IWL_WARN(fwrt->trans,
- "WRT: ext=%d. Region id %d override\n",
- ext, id);
-
- IWL_DEBUG_FW(fwrt,
- "WRT: ext=%d. Activating region id %d\n",
- ext, id);
-
- *active = reg;
-
- if (type == IWL_FW_INI_REGION_TXF ||
- type == IWL_FW_INI_REGION_RXF)
- iter += le32_to_cpu(reg->fifos.num_of_registers) *
- sizeof(__le32);
- else if (type == IWL_FW_INI_REGION_DEVICE_MEMORY ||
- type == IWL_FW_INI_REGION_PERIPHERY_MAC ||
- type == IWL_FW_INI_REGION_PERIPHERY_PHY ||
- type == IWL_FW_INI_REGION_PERIPHERY_AUX ||
- type == IWL_FW_INI_REGION_INTERNAL_BUFFER ||
- type == IWL_FW_INI_REGION_PAGING ||
- type == IWL_FW_INI_REGION_CSR ||
- type == IWL_FW_INI_REGION_LMAC_ERROR_TABLE ||
- type == IWL_FW_INI_REGION_UMAC_ERROR_TABLE)
- iter += le32_to_cpu(reg->internal.num_of_ranges) *
- sizeof(__le32);
-
- iter += sizeof(*reg);
- }
-}
-
-static int iwl_fw_dbg_trig_realloc(struct iwl_fw_runtime *fwrt,
- struct iwl_fw_ini_active_triggers *active,
- u32 id, int size)
-{
- void *ptr;
-
- if (size <= active->size)
- return 0;
-
- ptr = krealloc(active->trig, size, GFP_KERNEL);
- if (!ptr) {
- IWL_ERR(fwrt, "WRT: Failed to allocate memory for trigger %d\n",
- id);
- return -ENOMEM;
- }
- active->trig = ptr;
- active->size = size;
-
- return 0;
-}
-
-static void iwl_fw_dbg_update_triggers(struct iwl_fw_runtime *fwrt,
- struct iwl_fw_ini_trigger_tlv *tlv,
- bool ext,
- enum iwl_fw_ini_apply_point apply_point)
-{
- int i, size = le32_to_cpu(tlv->num_triggers);
- void *iter = (void *)tlv->trigger_config;
-
- for (i = 0; i < size; i++) {
- struct iwl_fw_ini_trigger *trig = iter;
- struct iwl_fw_ini_active_triggers *active;
- int id = le32_to_cpu(trig->trigger_id);
- u32 trig_regs_size = le32_to_cpu(trig->num_regions) *
- sizeof(__le32);
-
- if (WARN(id >= ARRAY_SIZE(fwrt->dump.active_trigs),
- "WRT: ext=%d. Invalid trigger id %d for apply point %d\n",
- ext, id, apply_point))
- break;
-
- active = &fwrt->dump.active_trigs[id];
-
- if (!active->active) {
- size_t trig_size = sizeof(*trig) + trig_regs_size;
-
- IWL_DEBUG_FW(fwrt,
- "WRT: ext=%d. Activating trigger %d\n",
- ext, id);
-
- if (iwl_fw_dbg_trig_realloc(fwrt, active, id,
- trig_size))
- goto next;
-
- memcpy(active->trig, trig, trig_size);
-
- } else {
- u32 conf_override =
- !(le32_to_cpu(trig->override_trig) & 0xff);
- u32 region_override =
- !(le32_to_cpu(trig->override_trig) & 0xff00);
- u32 offset = 0;
- u32 active_regs =
- le32_to_cpu(active->trig->num_regions);
- u32 new_regs = le32_to_cpu(trig->num_regions);
- int mem_to_add = trig_regs_size;
-
- if (region_override) {
- IWL_DEBUG_FW(fwrt,
- "WRT: ext=%d. Trigger %d regions override\n",
- ext, id);
-
- mem_to_add -= active_regs * sizeof(__le32);
- } else {
- IWL_DEBUG_FW(fwrt,
- "WRT: ext=%d. Trigger %d regions appending\n",
- ext, id);
-
- offset += active_regs;
- new_regs += active_regs;
- }
-
- if (iwl_fw_dbg_trig_realloc(fwrt, active, id,
- active->size + mem_to_add))
- goto next;
-
- if (conf_override) {
- IWL_DEBUG_FW(fwrt,
- "WRT: ext=%d. Trigger %d configuration override\n",
- ext, id);
-
- memcpy(active->trig, trig, sizeof(*trig));
- }
-
- memcpy(active->trig->data + offset, trig->data,
- trig_regs_size);
- active->trig->num_regions = cpu_to_le32(new_regs);
- }
-
- /* Since zero means infinity - just set to -1 */
- if (!le32_to_cpu(active->trig->occurrences))
- active->trig->occurrences = cpu_to_le32(-1);
-
- active->active = true;
-
- if (id == IWL_FW_TRIGGER_ID_PERIODIC_TRIGGER) {
- u32 collect_interval = le32_to_cpu(trig->trigger_data);
-
- /* the minimum allowed interval is 50ms */
- if (collect_interval < 50) {
- collect_interval = 50;
- trig->trigger_data =
- cpu_to_le32(collect_interval);
- }
-
- mod_timer(&fwrt->dump.periodic_trig,
- jiffies + msecs_to_jiffies(collect_interval));
- }
-next:
- iter += sizeof(*trig) + trig_regs_size;
-
- }
-}
-
-static void _iwl_fw_dbg_apply_point(struct iwl_fw_runtime *fwrt,
- struct iwl_apply_point_data *data,
- enum iwl_fw_ini_apply_point pnt,
- bool ext)
-{
- void *iter = data->data;
-
- while (iter && iter < data->data + data->size) {
- struct iwl_ucode_tlv *tlv = iter;
- void *ini_tlv = (void *)tlv->data;
- u32 type = le32_to_cpu(tlv->type);
-
- switch (type) {
- case IWL_UCODE_TLV_TYPE_DEBUG_INFO:
- iwl_fw_dbg_info_apply(fwrt, ini_tlv, ext, pnt);
- break;
- case IWL_UCODE_TLV_TYPE_BUFFER_ALLOCATION: {
- struct iwl_fw_ini_allocation_data *buf_alloc = ini_tlv;
-
- if (pnt != IWL_FW_INI_APPLY_EARLY) {
- IWL_ERR(fwrt,
- "WRT: ext=%d. Invalid apply point %d for buffer allocation\n",
- ext, pnt);
- goto next;
- }
-
- iwl_fw_dbg_buffer_apply(fwrt, ini_tlv, pnt);
- iter += sizeof(buf_alloc->is_alloc);
- break;
- }
- case IWL_UCODE_TLV_TYPE_HCMD:
- if (pnt < IWL_FW_INI_APPLY_AFTER_ALIVE) {
- IWL_ERR(fwrt,
- "WRT: ext=%d. Invalid apply point %d for host command\n",
- ext, pnt);
- goto next;
- }
- iwl_fw_dbg_send_hcmd(fwrt, tlv, ext);
- break;
- case IWL_UCODE_TLV_TYPE_REGIONS:
- iwl_fw_dbg_update_regions(fwrt, ini_tlv, ext, pnt);
- break;
- case IWL_UCODE_TLV_TYPE_TRIGGERS:
- iwl_fw_dbg_update_triggers(fwrt, ini_tlv, ext, pnt);
- break;
- case IWL_UCODE_TLV_TYPE_DEBUG_FLOW:
- break;
- default:
- WARN_ONCE(1,
- "WRT: ext=%d. Invalid TLV 0x%x for apply point\n",
- ext, type);
- break;
- }
-next:
- iter += sizeof(*tlv) + le32_to_cpu(tlv->length);
- }
-}
-
-static void iwl_fw_dbg_ini_reset_cfg(struct iwl_fw_runtime *fwrt)
+void iwl_fw_dbg_stop_sync(struct iwl_fw_runtime *fwrt)
{
int i;
- for (i = 0; i < IWL_FW_INI_MAX_REGION_ID; i++)
- fwrt->dump.active_regs[i] = NULL;
-
- /* disable the triggers, used in recovery flow */
- for (i = 0; i < IWL_FW_TRIGGER_ID_NUM; i++)
- fwrt->dump.active_trigs[i].active = false;
-
- memset(fwrt->dump.img_name, 0,
- sizeof(fwrt->dump.img_name));
- memset(fwrt->dump.internal_dbg_cfg_name, 0,
- sizeof(fwrt->dump.internal_dbg_cfg_name));
- memset(fwrt->dump.external_dbg_cfg_name, 0,
- sizeof(fwrt->dump.external_dbg_cfg_name));
-
- fwrt->trans->dbg.ini_dest = IWL_FW_INI_LOCATION_INVALID;
-}
-
-void iwl_fw_dbg_apply_point(struct iwl_fw_runtime *fwrt,
- enum iwl_fw_ini_apply_point apply_point)
-{
- void *data = &fwrt->trans->dbg.apply_points[apply_point];
-
- IWL_DEBUG_FW(fwrt, "WRT: enabling apply point %d\n", apply_point);
-
- if (apply_point == IWL_FW_INI_APPLY_EARLY)
- iwl_fw_dbg_ini_reset_cfg(fwrt);
-
- _iwl_fw_dbg_apply_point(fwrt, data, apply_point, false);
-
- data = &fwrt->trans->dbg.apply_points_ext[apply_point];
- _iwl_fw_dbg_apply_point(fwrt, data, apply_point, true);
-}
-IWL_EXPORT_SYMBOL(iwl_fw_dbg_apply_point);
-
-void iwl_fwrt_stop_device(struct iwl_fw_runtime *fwrt)
-{
- int i;
-
- del_timer(&fwrt->dump.periodic_trig);
+ iwl_dbg_tlv_del_timers(fwrt->trans);
for (i = 0; i < IWL_FW_RUNTIME_DUMP_WK_NUM; i++)
iwl_fw_dbg_collect_sync(fwrt, i);
- iwl_trans_stop_device(fwrt->trans);
-}
-IWL_EXPORT_SYMBOL(iwl_fwrt_stop_device);
-
-void iwl_fw_dbg_periodic_trig_handler(struct timer_list *t)
-{
- struct iwl_fw_runtime *fwrt;
- enum iwl_fw_ini_trigger_id id = IWL_FW_TRIGGER_ID_PERIODIC_TRIGGER;
- int ret;
- typeof(fwrt->dump) *dump_ptr = container_of(t, typeof(fwrt->dump),
- periodic_trig);
-
- fwrt = container_of(dump_ptr, typeof(*fwrt), dump);
-
- ret = _iwl_fw_dbg_ini_collect(fwrt, id);
- if (!ret || ret == -EBUSY) {
- struct iwl_fw_ini_trigger *trig =
- fwrt->dump.active_trigs[id].trig;
- u32 occur = le32_to_cpu(trig->occurrences);
- u32 collect_interval = le32_to_cpu(trig->trigger_data);
-
- if (!occur)
- return;
-
- mod_timer(&fwrt->dump.periodic_trig,
- jiffies + msecs_to_jiffies(collect_interval));
- }
+ iwl_fw_dbg_stop_restart_recording(fwrt, NULL, true);
}
+IWL_EXPORT_SYMBOL(iwl_fw_dbg_stop_sync);
#define FSEQ_REG(x) { .addr = (x), .str = #x, }
@@ -2937,3 +2428,92 @@ void iwl_fw_error_print_fseq_regs(struct iwl_fw_runtime *fwrt)
iwl_trans_release_nic_access(trans, &flags);
}
IWL_EXPORT_SYMBOL(iwl_fw_error_print_fseq_regs);
+
+static int iwl_fw_dbg_suspend_resume_hcmd(struct iwl_trans *trans, bool suspend)
+{
+ struct iwl_dbg_suspend_resume_cmd cmd = {
+ .operation = suspend ?
+ cpu_to_le32(DBGC_SUSPEND_CMD) :
+ cpu_to_le32(DBGC_RESUME_CMD),
+ };
+ struct iwl_host_cmd hcmd = {
+ .id = WIDE_ID(DEBUG_GROUP, DBGC_SUSPEND_RESUME),
+ .data[0] = &cmd,
+ .len[0] = sizeof(cmd),
+ };
+
+ return iwl_trans_send_cmd(trans, &hcmd);
+}
+
+static void iwl_fw_dbg_stop_recording(struct iwl_trans *trans,
+ struct iwl_fw_dbg_params *params)
+{
+ if (trans->trans_cfg->device_family == IWL_DEVICE_FAMILY_7000) {
+ iwl_set_bits_prph(trans, MON_BUFF_SAMPLE_CTL, 0x100);
+ return;
+ }
+
+ if (params) {
+ params->in_sample = iwl_read_umac_prph(trans, DBGC_IN_SAMPLE);
+ params->out_ctrl = iwl_read_umac_prph(trans, DBGC_OUT_CTRL);
+ }
+
+ iwl_write_umac_prph(trans, DBGC_IN_SAMPLE, 0);
+ /* wait for the DBGC to finish writing the internal buffer to DRAM to
+ * avoid halting the HW while writing
+ */
+ usleep_range(700, 1000);
+ iwl_write_umac_prph(trans, DBGC_OUT_CTRL, 0);
+}
+
+static int iwl_fw_dbg_restart_recording(struct iwl_trans *trans,
+ struct iwl_fw_dbg_params *params)
+{
+ if (!params)
+ return -EIO;
+
+ if (trans->trans_cfg->device_family == IWL_DEVICE_FAMILY_7000) {
+ iwl_clear_bits_prph(trans, MON_BUFF_SAMPLE_CTL, 0x100);
+ iwl_clear_bits_prph(trans, MON_BUFF_SAMPLE_CTL, 0x1);
+ iwl_set_bits_prph(trans, MON_BUFF_SAMPLE_CTL, 0x1);
+ } else {
+ iwl_write_umac_prph(trans, DBGC_IN_SAMPLE, params->in_sample);
+ iwl_write_umac_prph(trans, DBGC_OUT_CTRL, params->out_ctrl);
+ }
+
+ return 0;
+}
+
+int iwl_fw_dbg_stop_restart_recording(struct iwl_fw_runtime *fwrt,
+ struct iwl_fw_dbg_params *params,
+ bool stop)
+{
+ int ret = 0;
+
+ /* if the FW crashed or not debug monitor cfg was given, there is
+ * no point in changing the recording state
+ */
+ if (test_bit(STATUS_FW_ERROR, &fwrt->trans->status) ||
+ (!fwrt->trans->dbg.dest_tlv &&
+ fwrt->trans->dbg.ini_dest == IWL_FW_INI_LOCATION_INVALID))
+ return 0;
+
+ if (fw_has_capa(&fwrt->fw->ucode_capa,
+ IWL_UCODE_TLV_CAPA_DBG_SUSPEND_RESUME_CMD_SUPP))
+ ret = iwl_fw_dbg_suspend_resume_hcmd(fwrt->trans, stop);
+ else if (stop)
+ iwl_fw_dbg_stop_recording(fwrt->trans, params);
+ else
+ ret = iwl_fw_dbg_restart_recording(fwrt->trans, params);
+#ifdef CONFIG_IWLWIFI_DEBUGFS
+ if (!ret) {
+ if (stop)
+ fwrt->trans->dbg.rec_on = false;
+ else
+ iwl_fw_set_dbg_rec_on(fwrt);
+ }
+#endif
+
+ return ret;
+}
+IWL_EXPORT_SYMBOL(iwl_fw_dbg_stop_restart_recording);
diff --git a/drivers/net/wireless/intel/iwlwifi/fw/dbg.h b/drivers/net/wireless/intel/iwlwifi/fw/dbg.h
index a8459ac71b2c..e3b5dd34643f 100644
--- a/drivers/net/wireless/intel/iwlwifi/fw/dbg.h
+++ b/drivers/net/wireless/intel/iwlwifi/fw/dbg.h
@@ -202,7 +202,7 @@ _iwl_fw_dbg_trigger_on(struct iwl_fw_runtime *fwrt,
{
struct iwl_fw_dbg_trigger_tlv *trig;
- if (fwrt->trans->dbg.ini_valid)
+ if (iwl_trans_dbg_ini_valid(fwrt->trans))
return NULL;
if (!iwl_fw_dbg_trigger_enabled(fwrt->fw, id))
@@ -229,8 +229,9 @@ iwl_fw_ini_trigger_on(struct iwl_fw_runtime *fwrt,
struct iwl_fw_ini_trigger *trig;
u32 usec;
- if (!fwrt->trans->dbg.ini_valid || id == IWL_FW_TRIGGER_ID_INVALID ||
- id >= IWL_FW_TRIGGER_ID_NUM || !fwrt->dump.active_trigs[id].active)
+ if (!iwl_trans_dbg_ini_valid(fwrt->trans) ||
+ id == IWL_FW_TRIGGER_ID_INVALID || id >= IWL_FW_TRIGGER_ID_NUM ||
+ !fwrt->dump.active_trigs[id].active)
return false;
trig = fwrt->dump.active_trigs[id].trig;
@@ -262,69 +263,9 @@ _iwl_fw_dbg_trigger_simple_stop(struct iwl_fw_runtime *fwrt,
_iwl_fw_dbg_trigger_simple_stop((fwrt), (wdev), \
iwl_fw_dbg_get_trigger((fwrt)->fw,\
(trig)))
-
-static inline void
-_iwl_fw_dbg_stop_recording(struct iwl_trans *trans,
- struct iwl_fw_dbg_params *params)
-{
- if (trans->cfg->device_family == IWL_DEVICE_FAMILY_7000) {
- iwl_set_bits_prph(trans, MON_BUFF_SAMPLE_CTL, 0x100);
- return;
- }
-
- if (params) {
- params->in_sample = iwl_read_umac_prph(trans, DBGC_IN_SAMPLE);
- params->out_ctrl = iwl_read_umac_prph(trans, DBGC_OUT_CTRL);
- }
-
- iwl_write_umac_prph(trans, DBGC_IN_SAMPLE, 0);
- /* wait for the DBGC to finish writing the internal buffer to DRAM to
- * avoid halting the HW while writing
- */
- usleep_range(700, 1000);
- iwl_write_umac_prph(trans, DBGC_OUT_CTRL, 0);
-#ifdef CONFIG_IWLWIFI_DEBUGFS
- trans->dbg.rec_on = false;
-#endif
-}
-
-static inline void
-iwl_fw_dbg_stop_recording(struct iwl_trans *trans,
- struct iwl_fw_dbg_params *params)
-{
- /* if the FW crashed or not debug monitor cfg was given, there is
- * no point in stopping
- */
- if (test_bit(STATUS_FW_ERROR, &trans->status) ||
- (!trans->dbg.dest_tlv &&
- trans->dbg.ini_dest == IWL_FW_INI_LOCATION_INVALID))
- return;
-
- if (trans->cfg->device_family >= IWL_DEVICE_FAMILY_22560) {
- IWL_ERR(trans,
- "WRT: unsupported device family %d for debug stop recording\n",
- trans->cfg->device_family);
- return;
- }
- _iwl_fw_dbg_stop_recording(trans, params);
-}
-
-static inline void
-_iwl_fw_dbg_restart_recording(struct iwl_trans *trans,
- struct iwl_fw_dbg_params *params)
-{
- if (WARN_ON(!params))
- return;
-
- if (trans->cfg->device_family == IWL_DEVICE_FAMILY_7000) {
- iwl_clear_bits_prph(trans, MON_BUFF_SAMPLE_CTL, 0x100);
- iwl_clear_bits_prph(trans, MON_BUFF_SAMPLE_CTL, 0x1);
- iwl_set_bits_prph(trans, MON_BUFF_SAMPLE_CTL, 0x1);
- } else {
- iwl_write_umac_prph(trans, DBGC_IN_SAMPLE, params->in_sample);
- iwl_write_umac_prph(trans, DBGC_OUT_CTRL, params->out_ctrl);
- }
-}
+int iwl_fw_dbg_stop_restart_recording(struct iwl_fw_runtime *fwrt,
+ struct iwl_fw_dbg_params *params,
+ bool stop);
#ifdef CONFIG_IWLWIFI_DEBUGFS
static inline void iwl_fw_set_dbg_rec_on(struct iwl_fw_runtime *fwrt)
@@ -336,30 +277,6 @@ static inline void iwl_fw_set_dbg_rec_on(struct iwl_fw_runtime *fwrt)
}
#endif
-static inline void
-iwl_fw_dbg_restart_recording(struct iwl_fw_runtime *fwrt,
- struct iwl_fw_dbg_params *params)
-{
- /* if the FW crashed or not debug monitor cfg was given, there is
- * no point in restarting
- */
- if (test_bit(STATUS_FW_ERROR, &fwrt->trans->status) ||
- (!fwrt->trans->dbg.dest_tlv &&
- fwrt->trans->dbg.ini_dest == IWL_FW_INI_LOCATION_INVALID))
- return;
-
- if (fwrt->trans->cfg->device_family >= IWL_DEVICE_FAMILY_22560) {
- IWL_ERR(fwrt,
- "WRT: unsupported device family %d for debug restart recording\n",
- fwrt->trans->cfg->device_family);
- return;
- }
- _iwl_fw_dbg_restart_recording(fwrt->trans, params);
-#ifdef CONFIG_IWLWIFI_DEBUGFS
- iwl_fw_set_dbg_rec_on(fwrt);
-#endif
-}
-
static inline void iwl_fw_dump_conf_clear(struct iwl_fw_runtime *fwrt)
{
fwrt->dump.conf = FW_DBG_INVALID;
@@ -385,7 +302,7 @@ static inline bool iwl_fw_dbg_is_d3_debug_enabled(struct iwl_fw_runtime *fwrt)
static inline bool iwl_fw_dbg_is_paging_enabled(struct iwl_fw_runtime *fwrt)
{
return iwl_fw_dbg_type_on(fwrt, IWL_FW_ERROR_DUMP_PAGING) &&
- !fwrt->trans->cfg->gen2 &&
+ !fwrt->trans->trans_cfg->gen2 &&
fwrt->cur_fw_img < IWL_UCODE_TYPE_MAX &&
fwrt->fw->img[fwrt->cur_fw_img].paging_mem_size &&
fwrt->fw_paging_db[0].fw_paging_block;
@@ -397,24 +314,13 @@ static inline void iwl_fw_flush_dumps(struct iwl_fw_runtime *fwrt)
{
int i;
- del_timer(&fwrt->dump.periodic_trig);
+ iwl_dbg_tlv_del_timers(fwrt->trans);
for (i = 0; i < IWL_FW_RUNTIME_DUMP_WK_NUM; i++) {
flush_delayed_work(&fwrt->dump.wks[i].wk);
fwrt->dump.wks[i].ini_trig_id = IWL_FW_TRIGGER_ID_INVALID;
}
}
-static inline void iwl_fw_cancel_dumps(struct iwl_fw_runtime *fwrt)
-{
- int i;
-
- del_timer(&fwrt->dump.periodic_trig);
- for (i = 0; i < IWL_FW_RUNTIME_DUMP_WK_NUM; i++) {
- cancel_delayed_work_sync(&fwrt->dump.wks[i].wk);
- fwrt->dump.wks[i].ini_trig_id = IWL_FW_TRIGGER_ID_INVALID;
- }
-}
-
#ifdef CONFIG_IWLWIFI_DEBUGFS
static inline void iwl_fw_cancel_timestamp(struct iwl_fw_runtime *fwrt)
{
@@ -451,10 +357,7 @@ static inline void iwl_fw_resume_timestamp(struct iwl_fw_runtime *fwrt) {}
#endif /* CONFIG_IWLWIFI_DEBUGFS */
-void iwl_fw_dbg_apply_point(struct iwl_fw_runtime *fwrt,
- enum iwl_fw_ini_apply_point apply_point);
-
-void iwl_fwrt_stop_device(struct iwl_fw_runtime *fwrt);
+void iwl_fw_dbg_stop_sync(struct iwl_fw_runtime *fwrt);
static inline void iwl_fw_lmac1_set_alive_err_table(struct iwl_trans *trans,
u32 lmac_error_event_table)
@@ -478,7 +381,7 @@ static inline void iwl_fw_umac_set_alive_err_table(struct iwl_trans *trans,
static inline void iwl_fw_error_collect(struct iwl_fw_runtime *fwrt)
{
- if (fwrt->trans->dbg.ini_valid && fwrt->trans->dbg.hw_error) {
+ if (iwl_trans_dbg_ini_valid(fwrt->trans) && fwrt->trans->dbg.hw_error) {
_iwl_fw_dbg_ini_collect(fwrt, IWL_FW_TRIGGER_ID_FW_HW_ERROR);
fwrt->trans->dbg.hw_error = false;
} else {
@@ -486,8 +389,6 @@ static inline void iwl_fw_error_collect(struct iwl_fw_runtime *fwrt)
}
}
-void iwl_fw_dbg_periodic_trig_handler(struct timer_list *t);
-
void iwl_fw_error_print_fseq_regs(struct iwl_fw_runtime *fwrt);
static inline void iwl_fwrt_update_fw_versions(struct iwl_fw_runtime *fwrt,
diff --git a/drivers/net/wireless/intel/iwlwifi/fw/error-dump.h b/drivers/net/wireless/intel/iwlwifi/fw/error-dump.h
index 00a45ea85b69..2e763678dbdb 100644
--- a/drivers/net/wireless/intel/iwlwifi/fw/error-dump.h
+++ b/drivers/net/wireless/intel/iwlwifi/fw/error-dump.h
@@ -288,6 +288,28 @@ struct iwl_fw_error_dump_mem {
#define IWL_INI_DUMP_INFO_TYPE BIT(31)
/**
+ * struct iwl_fw_ini_dump_entry
+ * @list: list of dump entries
+ * @size: size of the data
+ * @data: entry data
+ */
+struct iwl_fw_ini_dump_entry {
+ struct list_head list;
+ u32 size;
+ u8 data[];
+} __packed;
+
+/**
+ * struct iwl_fw_error_dump_file - header of dump file
+ * @barker: must be %IWL_FW_INI_ERROR_DUMP_BARKER
+ * @file_len: the length of all the file including the header
+ */
+struct iwl_fw_ini_dump_file_hdr {
+ __le32 barker;
+ __le32 file_len;
+} __packed;
+
+/**
* struct iwl_fw_ini_fifo_hdr - fifo range header
* @fifo_num: the fifo number. In case of umac rx fifo, set BIT(31) to
* distinguish between lmac and umac rx fifos
@@ -301,10 +323,10 @@ struct iwl_fw_ini_fifo_hdr {
/**
* struct iwl_fw_ini_error_dump_range - range of memory
* @range_data_size: the size of this range, in bytes
- * @internal_base_addr - base address of internal memory range
- * @dram_base_addr - base address of dram monitor range
- * @page_num - page number of memory range
- * @fifo_hdr - fifo header of memory range
+ * @internal_base_addr: base address of internal memory range
+ * @dram_base_addr: base address of dram monitor range
+ * @page_num: page number of memory range
+ * @fifo_hdr: fifo header of memory range
* @data: the actual memory
*/
struct iwl_fw_ini_error_dump_range {
@@ -432,10 +454,10 @@ struct iwl_fw_error_dump_rb {
/**
* struct iwl_fw_ini_monitor_dump - ini monitor dump
- * @header - header of the region
- * @write_ptr - write pointer position in the buffer
- * @cycle_cnt - cycles count
- * @ranges - the memory ranges of this this region
+ * @header: header of the region
+ * @write_ptr: write pointer position in the buffer
+ * @cycle_cnt: cycles count
+ * @ranges: the memory ranges of this this region
*/
struct iwl_fw_ini_monitor_dump {
struct iwl_fw_ini_error_dump_header header;
diff --git a/drivers/net/wireless/intel/iwlwifi/fw/file.h b/drivers/net/wireless/intel/iwlwifi/fw/file.h
index 0c38e7392b61..423cc0cf8e78 100644
--- a/drivers/net/wireless/intel/iwlwifi/fw/file.h
+++ b/drivers/net/wireless/intel/iwlwifi/fw/file.h
@@ -157,8 +157,7 @@ enum iwl_ucode_tlv_type {
IWL_UCODE_TLV_TYPE_HCMD = IWL_UCODE_TLV_DEBUG_BASE + 2,
IWL_UCODE_TLV_TYPE_REGIONS = IWL_UCODE_TLV_DEBUG_BASE + 3,
IWL_UCODE_TLV_TYPE_TRIGGERS = IWL_UCODE_TLV_DEBUG_BASE + 4,
- IWL_UCODE_TLV_TYPE_DEBUG_FLOW = IWL_UCODE_TLV_DEBUG_BASE + 5,
- IWL_UCODE_TLV_DEBUG_MAX = IWL_UCODE_TLV_TYPE_DEBUG_FLOW,
+ IWL_UCODE_TLV_DEBUG_MAX = IWL_UCODE_TLV_TYPE_TRIGGERS,
/* TLVs 0x1000-0x2000 are for internal driver usage */
IWL_UCODE_TLV_FW_DBG_DUMP_LST = 0x1000,
@@ -323,6 +322,7 @@ enum iwl_ucode_tlv_api {
IWL_UCODE_TLV_API_FTM_RTT_ACCURACY = (__force iwl_ucode_tlv_api_t)54,
IWL_UCODE_TLV_API_SAR_TABLE_VER = (__force iwl_ucode_tlv_api_t)55,
IWL_UCODE_TLV_API_ADWELL_HB_DEF_N_AP = (__force iwl_ucode_tlv_api_t)57,
+ IWL_UCODE_TLV_API_SCAN_EXT_CHAN_VER = (__force iwl_ucode_tlv_api_t)58,
NUM_IWL_UCODE_TLV_API
#ifdef __CHECKER__
@@ -441,9 +441,11 @@ enum iwl_ucode_tlv_capa {
IWL_UCODE_TLV_CAPA_DYNAMIC_QUOTA = (__force iwl_ucode_tlv_capa_t)44,
IWL_UCODE_TLV_CAPA_COEX_SCHEMA_2 = (__force iwl_ucode_tlv_capa_t)45,
IWL_UCODE_TLV_CAPA_CHANNEL_SWITCH_CMD = (__force iwl_ucode_tlv_capa_t)46,
- IWL_UCODE_TLV_CAPA_ULTRA_HB_CHANNELS = (__force iwl_ucode_tlv_capa_t)48,
IWL_UCODE_TLV_CAPA_FTM_CALIBRATED = (__force iwl_ucode_tlv_capa_t)47,
+ IWL_UCODE_TLV_CAPA_ULTRA_HB_CHANNELS = (__force iwl_ucode_tlv_capa_t)48,
IWL_UCODE_TLV_CAPA_CS_MODIFY = (__force iwl_ucode_tlv_capa_t)49,
+ IWL_UCODE_TLV_CAPA_SET_LTR_GEN2 = (__force iwl_ucode_tlv_capa_t)50,
+ IWL_UCODE_TLV_CAPA_SET_PPAG = (__force iwl_ucode_tlv_capa_t)52,
/* set 2 */
IWL_UCODE_TLV_CAPA_EXTENDED_DTS_MEASURE = (__force iwl_ucode_tlv_capa_t)64,
@@ -465,6 +467,8 @@ enum iwl_ucode_tlv_capa {
IWL_UCODE_TLV_CAPA_LED_CMD_SUPPORT = (__force iwl_ucode_tlv_capa_t)88,
IWL_UCODE_TLV_CAPA_MCC_UPDATE_11AX_SUPPORT = (__force iwl_ucode_tlv_capa_t)89,
IWL_UCODE_TLV_CAPA_CSI_REPORTING = (__force iwl_ucode_tlv_capa_t)90,
+ IWL_UCODE_TLV_CAPA_DBG_SUSPEND_RESUME_CMD_SUPP = (__force iwl_ucode_tlv_capa_t)92,
+ IWL_UCODE_TLV_CAPA_DBG_BUF_ALLOC_CMD_SUPP = (__force iwl_ucode_tlv_capa_t)93,
/* set 3 */
IWL_UCODE_TLV_CAPA_MLME_OFFLOAD = (__force iwl_ucode_tlv_capa_t)96,
@@ -521,6 +525,10 @@ enum iwl_fw_phy_cfg {
FW_PHY_CFG_TX_CHAIN = 0xf << FW_PHY_CFG_TX_CHAIN_POS,
FW_PHY_CFG_RX_CHAIN_POS = 20,
FW_PHY_CFG_RX_CHAIN = 0xf << FW_PHY_CFG_RX_CHAIN_POS,
+ FW_PHY_CFG_CHAIN_SAD_POS = 23,
+ FW_PHY_CFG_CHAIN_SAD_ENABLED = 0x1 << FW_PHY_CFG_CHAIN_SAD_POS,
+ FW_PHY_CFG_CHAIN_SAD_ANT_A = 0x2 << FW_PHY_CFG_CHAIN_SAD_POS,
+ FW_PHY_CFG_CHAIN_SAD_ANT_B = 0x4 << FW_PHY_CFG_CHAIN_SAD_POS,
FW_PHY_CFG_SHARED_CLK = BIT(31),
};
@@ -965,4 +973,19 @@ struct iwl_fw_cmd_version {
u8 notif_ver;
} __packed;
+static inline size_t _iwl_tlv_array_len(const struct iwl_ucode_tlv *tlv,
+ size_t fixed_size, size_t var_size)
+{
+ size_t var_len = le32_to_cpu(tlv->length) - fixed_size;
+
+ if (WARN_ON(var_len % var_size))
+ return 0;
+
+ return var_len / var_size;
+}
+
+#define iwl_tlv_array_len(_tlv_ptr, _struct_ptr, _memb) \
+ _iwl_tlv_array_len((_tlv_ptr), sizeof(*(_struct_ptr)), \
+ sizeof(_struct_ptr->_memb[0]))
+
#endif /* __iwl_fw_file_h__ */
diff --git a/drivers/net/wireless/intel/iwlwifi/fw/img.h b/drivers/net/wireless/intel/iwlwifi/fw/img.h
index 18ca5f152be6..039576d71276 100644
--- a/drivers/net/wireless/intel/iwlwifi/fw/img.h
+++ b/drivers/net/wireless/intel/iwlwifi/fw/img.h
@@ -228,15 +228,6 @@ struct iwl_fw_dbg {
};
/**
- * @tlv: the buffer allocation tlv
- * @is_alloc: indicates if the buffer was already allocated
- */
-struct iwl_fw_ini_allocation_data {
- struct iwl_fw_ini_allocation_tlv tlv;
- u32 is_alloc;
-} __packed;
-
-/**
* struct iwl_fw_ini_active_triggers
* @active: is this trigger active
* @size: allocated memory size of the trigger
diff --git a/drivers/net/wireless/intel/iwlwifi/fw/init.c b/drivers/net/wireless/intel/iwlwifi/fw/init.c
index c16d6e126e3c..ba00d162ce72 100644
--- a/drivers/net/wireless/intel/iwlwifi/fw/init.c
+++ b/drivers/net/wireless/intel/iwlwifi/fw/init.c
@@ -81,8 +81,6 @@ void iwl_fw_runtime_init(struct iwl_fw_runtime *fwrt, struct iwl_trans *trans,
INIT_DELAYED_WORK(&fwrt->dump.wks[i].wk, iwl_fw_error_dump_wk);
}
iwl_fwrt_dbgfs_register(fwrt, dbgfs_dir);
- timer_setup(&fwrt->dump.periodic_trig,
- iwl_fw_dbg_periodic_trig_handler, 0);
}
IWL_EXPORT_SYMBOL(iwl_fw_runtime_init);
diff --git a/drivers/net/wireless/intel/iwlwifi/fw/paging.c b/drivers/net/wireless/intel/iwlwifi/fw/paging.c
index 9b8dd7fe7112..2bd76bd9dfa5 100644
--- a/drivers/net/wireless/intel/iwlwifi/fw/paging.c
+++ b/drivers/net/wireless/intel/iwlwifi/fw/paging.c
@@ -8,7 +8,7 @@
* Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved.
* Copyright(c) 2013 - 2015 Intel Mobile Communications GmbH
* Copyright(c) 2016 - 2017 Intel Deutschland GmbH
- * Copyright(c) 2018 Intel Corporation
+ * Copyright(c) 2018 - 2019 Intel Corporation
*
* 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
@@ -31,7 +31,7 @@
* Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved.
* Copyright(c) 2013 - 2015 Intel Mobile Communications GmbH
* Copyright(c) 2016 - 2017 Intel Deutschland GmbH
- * Copyright(c) 2018 Intel Corporation
+ * Copyright(c) 2018 - 2019 Intel Corporation
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -322,7 +322,7 @@ int iwl_init_paging(struct iwl_fw_runtime *fwrt, enum iwl_ucode_type type)
const struct fw_img *fw = &fwrt->fw->img[type];
int ret;
- if (fwrt->trans->cfg->gen2)
+ if (fwrt->trans->trans_cfg->gen2)
return 0;
/*
diff --git a/drivers/net/wireless/intel/iwlwifi/fw/runtime.h b/drivers/net/wireless/intel/iwlwifi/fw/runtime.h
index 406ef73992c1..be436c18a047 100644
--- a/drivers/net/wireless/intel/iwlwifi/fw/runtime.h
+++ b/drivers/net/wireless/intel/iwlwifi/fw/runtime.h
@@ -64,7 +64,6 @@
#include "iwl-trans.h"
#include "img.h"
#include "fw/api/debug.h"
-#include "fw/api/dbg-tlv.h"
#include "fw/api/paging.h"
#include "iwl-eeprom-parse.h"
@@ -92,6 +91,20 @@ struct iwl_fwrt_shared_mem_cfg {
#define IWL_FW_RUNTIME_DUMP_WK_NUM 5
/**
+ * struct iwl_txf_iter_data - Tx fifo iterator data struct
+ * @fifo: fifo number
+ * @lmac: lmac number
+ * @fifo_size: fifo size
+ * @internal_txf: non zero if fifo is internal Tx fifo
+ */
+struct iwl_txf_iter_data {
+ int fifo;
+ int lmac;
+ u32 fifo_size;
+ u8 internal_txf;
+};
+
+/**
* struct iwl_fw_runtime - runtime data for firmware
* @fw: firmware image
* @cfg: NIC configuration
@@ -144,8 +157,8 @@ struct iwl_fw_runtime {
struct iwl_fw_ini_active_triggers active_trigs[IWL_FW_TRIGGER_ID_NUM];
u32 lmac_err_id[MAX_NUM_LMAC];
u32 umac_err_id;
- void *fifo_iter;
- struct timer_list periodic_trig;
+
+ struct iwl_txf_iter_data txf_iter_data;
u8 img_name[IWL_FW_INI_MAX_IMG_NAME_LEN];
u8 internal_dbg_cfg_name[IWL_FW_INI_MAX_DBG_CFG_NAME_LEN];
@@ -190,6 +203,10 @@ static inline void iwl_fw_runtime_free(struct iwl_fw_runtime *fwrt)
kfree(active->trig);
active->trig = NULL;
}
+
+ iwl_dbg_tlv_del_timers(fwrt->trans);
+ for (i = 0; i < IWL_FW_RUNTIME_DUMP_WK_NUM; i++)
+ cancel_delayed_work_sync(&fwrt->dump.wks[i].wk);
}
void iwl_fw_runtime_suspend(struct iwl_fw_runtime *fwrt);
diff --git a/drivers/net/wireless/intel/iwlwifi/fw/smem.c b/drivers/net/wireless/intel/iwlwifi/fw/smem.c
index 557ee47bffd8..409b2dd854ac 100644
--- a/drivers/net/wireless/intel/iwlwifi/fw/smem.c
+++ b/drivers/net/wireless/intel/iwlwifi/fw/smem.c
@@ -151,7 +151,7 @@ void iwl_get_shared_mem_conf(struct iwl_fw_runtime *fwrt)
}
pkt = cmd.resp_pkt;
- if (fwrt->trans->cfg->device_family >= IWL_DEVICE_FAMILY_22000)
+ if (fwrt->trans->trans_cfg->device_family >= IWL_DEVICE_FAMILY_22000)
iwl_parse_shared_mem_22000(fwrt, pkt);
else
iwl_parse_shared_mem(fwrt, pkt);
diff --git a/drivers/net/wireless/intel/iwlwifi/iwl-config.h b/drivers/net/wireless/intel/iwlwifi/iwl-config.h
index 1c1bf1b281cd..214495a7165f 100644
--- a/drivers/net/wireless/intel/iwlwifi/iwl-config.h
+++ b/drivers/net/wireless/intel/iwlwifi/iwl-config.h
@@ -161,7 +161,8 @@ static inline u8 num_of_ant(u8 mask)
!!((mask) & ANT_C);
}
-/*
+/**
+ * struct iwl_base_params - params not likely to change within a device family
* @max_ll_items: max number of OTP blocks
* @shadow_ram_support: shadow support for OTP memory
* @led_compensation: compensate on the led on/off time per HW according
@@ -331,7 +332,36 @@ struct iwl_csr_params {
};
/**
+ * struct iwl_cfg_trans - information needed to start the trans
+ *
+ * These values cannot be changed when multiple configs are used for a
+ * single PCI ID, because they are needed before the HW REV or RFID
+ * can be read.
+ *
+ * @base_params: pointer to basic parameters
+ * @csr: csr flags and addresses that are different across devices
+ * @device_family: the device family
+ * @umac_prph_offset: offset to add to UMAC periphery address
+ * @rf_id: need to read rf_id to determine the firmware image
+ * @use_tfh: use TFH
+ * @gen2: 22000 and on transport operation
+ * @mq_rx_supported: multi-queue rx support
+ */
+struct iwl_cfg_trans_params {
+ const struct iwl_base_params *base_params;
+ const struct iwl_csr_params *csr;
+ enum iwl_device_family device_family;
+ u32 umac_prph_offset;
+ u32 rf_id:1,
+ use_tfh:1,
+ gen2:1,
+ mq_rx_supported:1,
+ bisr_workaround:1;
+};
+
+/**
* struct iwl_cfg
+ * @trans: the trans-specific configuration part
* @name: Official name of the device
* @fw_name_pre: Firmware filename prefix. The api version and extension
* (.ucode) will be added to filename before loading from disk. The
@@ -346,10 +376,10 @@ struct iwl_csr_params {
* @nvm_ver: NVM version
* @nvm_calib_ver: NVM calibration version
* @lib: pointer to the lib ops
- * @base_params: pointer to basic parameters
* @ht_params: point to ht parameters
* @led_mode: 0=blinking, 1=On(RF On)/Off(RF Off)
* @rx_with_siso_diversity: 1x1 device with rx antenna diversity
+ * @tx_with_siso_diversity: 1x1 device with tx antenna diversity
* @internal_wimax_coex: internal wifi/wimax combo device
* @high_temp: Is this NIC is designated to be in high temperature.
* @host_interrupt_operation_mode: device needs host interrupt operation
@@ -358,7 +388,6 @@ struct iwl_csr_params {
* @mac_addr_from_csr: read HW address from CSR registers
* @features: hw features, any combination of feature_whitelist
* @pwr_tx_backoffs: translation table between power limits and backoffs
- * @csr: csr flags and addresses that are different across devices
* @max_rx_agg_size: max RX aggregation size of the ADDBA request/response
* @max_tx_agg_size: max TX aggregation size of the ADDBA request/response
* @max_ht_ampdu_factor: the exponent of the max length of A-MPDU that the
@@ -371,18 +400,14 @@ struct iwl_csr_params {
* @dccm2_len: length of the second DCCM
* @smem_offset: offset from which the SMEM begins
* @smem_len: the length of SMEM
- * @mq_rx_supported: multi-queue rx support
* @vht_mu_mimo_supported: VHT MU-MIMO support
- * @rf_id: need to read rf_id to determine the firmware image
* @integrated: discrete or integrated
- * @gen2: 22000 and on transport operation
* @cdb: CDB support
* @nvm_type: see &enum iwl_nvm_type
* @d3_debug_data_base_addr: base address where D3 debug data is stored
* @d3_debug_data_length: length of the D3 debug data
* @bisr_workaround: BISR hardware workaround (for 22260 series devices)
* @min_txq_size: minimum number of slots required in a TX queue
- * @umac_prph_offset: offset to add to UMAC periphery address
* @uhb_supported: ultra high band channels supported
* @min_256_ba_txq_size: minimum number of slots required in a TX queue which
* supports 256 BA aggregation
@@ -392,19 +417,16 @@ struct iwl_csr_params {
* and/or the uCode API version instead.
*/
struct iwl_cfg {
+ struct iwl_cfg_trans_params trans;
/* params specific to an individual device within a device family */
const char *name;
const char *fw_name_pre;
- /* params not likely to change within a device family */
- const struct iwl_base_params *base_params;
/* params likely to change within a device family */
const struct iwl_ht_params *ht_params;
const struct iwl_eeprom_params *eeprom_params;
const struct iwl_pwr_tx_backoff *pwr_tx_backoffs;
const char *default_nvm_file_C_step;
const struct iwl_tt_params *thermal_params;
- const struct iwl_csr_params *csr;
- enum iwl_device_family device_family;
enum iwl_led_mode led_mode;
enum iwl_nvm_type nvm_type;
u32 max_data_size;
@@ -420,6 +442,7 @@ struct iwl_cfg {
u16 nvm_ver;
u16 nvm_calib_ver;
u32 rx_with_siso_diversity:1,
+ tx_with_siso_diversity:1,
bt_shared_single_ant:1,
internal_wimax_coex:1,
host_interrupt_operation_mode:1,
@@ -428,15 +451,10 @@ struct iwl_cfg {
lp_xtal_workaround:1,
disable_dummy_notification:1,
apmg_not_supported:1,
- mq_rx_supported:1,
vht_mu_mimo_supported:1,
- rf_id:1,
integrated:1,
- use_tfh:1,
- gen2:1,
cdb:1,
dbgc_supported:1,
- bisr_workaround:1,
uhb_supported:1;
u8 valid_tx_ant;
u8 valid_rx_ant;
@@ -453,7 +471,6 @@ struct iwl_cfg {
u32 d3_debug_data_base_addr;
u32 d3_debug_data_length;
u32 min_txq_size;
- u32 umac_prph_offset;
u32 fw_mon_smem_write_ptr_addr;
u32 fw_mon_smem_write_ptr_msk;
u32 fw_mon_smem_cycle_cnt_ptr_addr;
@@ -577,6 +594,8 @@ extern const struct iwl_cfg iwl_ax1650i_cfg_quz_hr;
extern const struct iwl_cfg iwl_ax1650s_cfg_quz_hr;
extern const struct iwl_cfg killer1650s_2ax_cfg_qu_b0_hr_b0;
extern const struct iwl_cfg killer1650i_2ax_cfg_qu_b0_hr_b0;
+extern const struct iwl_cfg killer1650s_2ax_cfg_qu_c0_hr_b0;
+extern const struct iwl_cfg killer1650i_2ax_cfg_qu_c0_hr_b0;
extern const struct iwl_cfg killer1650x_2ax_cfg;
extern const struct iwl_cfg killer1650w_2ax_cfg;
extern const struct iwl_cfg iwl9461_2ac_cfg_qu_b0_jf_b0;
diff --git a/drivers/net/wireless/intel/iwlwifi/iwl-dbg-tlv.c b/drivers/net/wireless/intel/iwlwifi/iwl-dbg-tlv.c
index fcaec410b3be..3d7f8ff8ef58 100644
--- a/drivers/net/wireless/intel/iwlwifi/iwl-dbg-tlv.c
+++ b/drivers/net/wireless/intel/iwlwifi/iwl-dbg-tlv.c
@@ -60,149 +60,112 @@
*****************************************************************************/
#include <linux/firmware.h>
+#include "iwl-drv.h"
#include "iwl-trans.h"
#include "iwl-dbg-tlv.h"
-
-void iwl_fw_dbg_copy_tlv(struct iwl_trans *trans, struct iwl_ucode_tlv *tlv,
- bool ext)
+#include "fw/dbg.h"
+#include "fw/runtime.h"
+
+/**
+ * enum iwl_dbg_tlv_type - debug TLV types
+ * @IWL_DBG_TLV_TYPE_DEBUG_INFO: debug info TLV
+ * @IWL_DBG_TLV_TYPE_BUF_ALLOC: buffer allocation TLV
+ * @IWL_DBG_TLV_TYPE_HCMD: host command TLV
+ * @IWL_DBG_TLV_TYPE_REGION: region TLV
+ * @IWL_DBG_TLV_TYPE_TRIGGER: trigger TLV
+ * @IWL_DBG_TLV_TYPE_NUM: number of debug TLVs
+ */
+enum iwl_dbg_tlv_type {
+ IWL_DBG_TLV_TYPE_DEBUG_INFO =
+ IWL_UCODE_TLV_TYPE_DEBUG_INFO - IWL_UCODE_TLV_DEBUG_BASE,
+ IWL_DBG_TLV_TYPE_BUF_ALLOC,
+ IWL_DBG_TLV_TYPE_HCMD,
+ IWL_DBG_TLV_TYPE_REGION,
+ IWL_DBG_TLV_TYPE_TRIGGER,
+ IWL_DBG_TLV_TYPE_NUM,
+};
+
+/**
+ * struct iwl_dbg_tlv_ver_data - debug TLV version struct
+ * @min_ver: min version supported
+ * @max_ver: max version supported
+ */
+struct iwl_dbg_tlv_ver_data {
+ int min_ver;
+ int max_ver;
+};
+
+static const struct iwl_dbg_tlv_ver_data
+dbg_ver_table[IWL_DBG_TLV_TYPE_NUM] = {
+ [IWL_DBG_TLV_TYPE_DEBUG_INFO] = {.min_ver = 1, .max_ver = 1,},
+ [IWL_DBG_TLV_TYPE_BUF_ALLOC] = {.min_ver = 1, .max_ver = 1,},
+ [IWL_DBG_TLV_TYPE_HCMD] = {.min_ver = 1, .max_ver = 1,},
+ [IWL_DBG_TLV_TYPE_REGION] = {.min_ver = 1, .max_ver = 1,},
+ [IWL_DBG_TLV_TYPE_TRIGGER] = {.min_ver = 1, .max_ver = 1,},
+};
+
+static bool iwl_dbg_tlv_ver_support(struct iwl_ucode_tlv *tlv)
{
- struct iwl_apply_point_data *data;
- struct iwl_fw_ini_header *header = (void *)&tlv->data[0];
- u32 apply_point = le32_to_cpu(header->apply_point);
-
- int copy_size = le32_to_cpu(tlv->length) + sizeof(*tlv);
- int offset_size = copy_size;
-
- if (le32_to_cpu(header->tlv_version) != 1)
- return;
-
- if (WARN_ONCE(apply_point >= IWL_FW_INI_APPLY_NUM,
- "Invalid apply point id %d\n", apply_point))
- return;
+ struct iwl_fw_ini_header *hdr = (void *)&tlv->data[0];
+ u32 type = le32_to_cpu(tlv->type);
+ u32 tlv_idx = type - IWL_UCODE_TLV_DEBUG_BASE;
+ u32 ver = le32_to_cpu(hdr->tlv_version);
- if (ext)
- data = &trans->dbg.apply_points_ext[apply_point];
- else
- data = &trans->dbg.apply_points[apply_point];
+ if (ver < dbg_ver_table[tlv_idx].min_ver ||
+ ver > dbg_ver_table[tlv_idx].max_ver)
+ return false;
- /* add room for is_alloc field in &iwl_fw_ini_allocation_data struct */
- if (le32_to_cpu(tlv->type) == IWL_UCODE_TLV_TYPE_BUFFER_ALLOCATION) {
- struct iwl_fw_ini_allocation_data *buf_alloc =
- (void *)tlv->data;
-
- offset_size += sizeof(buf_alloc->is_alloc);
- }
-
- /*
- * Make sure we still have room to copy this TLV. Offset points to the
- * location the last copy ended.
- */
- if (WARN_ONCE(data->offset + offset_size > data->size,
- "Not enough memory for apply point %d\n",
- apply_point))
- return;
-
- memcpy(data->data + data->offset, (void *)tlv, copy_size);
- data->offset += offset_size;
+ return true;
}
-void iwl_alloc_dbg_tlv(struct iwl_trans *trans, size_t len, const u8 *data,
+void iwl_dbg_tlv_alloc(struct iwl_trans *trans, struct iwl_ucode_tlv *tlv,
bool ext)
{
- struct iwl_ucode_tlv *tlv;
- u32 size[IWL_FW_INI_APPLY_NUM] = {0};
- int i;
-
- while (len >= sizeof(*tlv)) {
- u32 tlv_len, tlv_type, apply;
- struct iwl_fw_ini_header *hdr;
-
- len -= sizeof(*tlv);
- tlv = (void *)data;
-
- tlv_len = le32_to_cpu(tlv->length);
- tlv_type = le32_to_cpu(tlv->type);
-
- if (len < tlv_len)
- return;
-
- len -= ALIGN(tlv_len, 4);
- data += sizeof(*tlv) + ALIGN(tlv_len, 4);
-
- if (tlv_type < IWL_UCODE_TLV_DEBUG_BASE ||
- tlv_type > IWL_UCODE_TLV_DEBUG_MAX)
- continue;
-
- hdr = (void *)&tlv->data[0];
- apply = le32_to_cpu(hdr->apply_point);
-
- if (le32_to_cpu(hdr->tlv_version) != 1)
- continue;
-
- IWL_DEBUG_FW(trans, "WRT: read TLV 0x%x, apply point %d\n",
- le32_to_cpu(tlv->type), apply);
-
- if (WARN_ON(apply >= IWL_FW_INI_APPLY_NUM))
- continue;
-
- /* add room for is_alloc field in &iwl_fw_ini_allocation_data
- * struct
- */
- if (tlv_type == IWL_UCODE_TLV_TYPE_BUFFER_ALLOCATION) {
- struct iwl_fw_ini_allocation_data *buf_alloc =
- (void *)tlv->data;
-
- size[apply] += sizeof(buf_alloc->is_alloc);
- }
-
- size[apply] += sizeof(*tlv) + tlv_len;
+ struct iwl_fw_ini_header *hdr = (void *)&tlv->data[0];
+ u32 type = le32_to_cpu(tlv->type);
+ u32 pnt = le32_to_cpu(hdr->apply_point);
+ u32 tlv_idx = type - IWL_UCODE_TLV_DEBUG_BASE;
+ enum iwl_ini_cfg_state *cfg_state = ext ?
+ &trans->dbg.external_ini_cfg : &trans->dbg.internal_ini_cfg;
+
+ IWL_DEBUG_FW(trans, "WRT: read TLV 0x%x, apply point %d\n",
+ type, pnt);
+
+ if (tlv_idx >= IWL_DBG_TLV_TYPE_NUM) {
+ IWL_ERR(trans, "WRT: Unsupported TLV 0x%x\n", type);
+ goto out_err;
}
- for (i = 0; i < ARRAY_SIZE(size); i++) {
- void *mem;
-
- if (!size[i])
- continue;
+ if (!iwl_dbg_tlv_ver_support(tlv)) {
+ IWL_ERR(trans, "WRT: Unsupported TLV 0x%x version %u\n", type,
+ le32_to_cpu(hdr->tlv_version));
+ goto out_err;
+ }
- mem = kzalloc(size[i], GFP_KERNEL);
+ if (*cfg_state == IWL_INI_CFG_STATE_NOT_LOADED)
+ *cfg_state = IWL_INI_CFG_STATE_LOADED;
- if (!mem) {
- IWL_ERR(trans, "No memory for apply point %d\n", i);
- return;
- }
+ return;
- if (ext) {
- trans->dbg.apply_points_ext[i].data = mem;
- trans->dbg.apply_points_ext[i].size = size[i];
- } else {
- trans->dbg.apply_points[i].data = mem;
- trans->dbg.apply_points[i].size = size[i];
- }
-
- trans->dbg.ini_valid = true;
- }
+out_err:
+ *cfg_state = IWL_INI_CFG_STATE_CORRUPTED;
}
-void iwl_fw_dbg_free(struct iwl_trans *trans)
+void iwl_dbg_tlv_del_timers(struct iwl_trans *trans)
{
- int i;
-
- for (i = 0; i < ARRAY_SIZE(trans->dbg.apply_points); i++) {
- kfree(trans->dbg.apply_points[i].data);
- trans->dbg.apply_points[i].size = 0;
- trans->dbg.apply_points[i].offset = 0;
+ /* will be used later */
+}
+IWL_EXPORT_SYMBOL(iwl_dbg_tlv_del_timers);
- kfree(trans->dbg.apply_points_ext[i].data);
- trans->dbg.apply_points_ext[i].size = 0;
- trans->dbg.apply_points_ext[i].offset = 0;
- }
+void iwl_dbg_tlv_free(struct iwl_trans *trans)
+{
+ /* will be used again later */
}
-static int iwl_parse_fw_dbg_tlv(struct iwl_trans *trans, const u8 *data,
- size_t len)
+static int iwl_dbg_tlv_parse_bin(struct iwl_trans *trans, const u8 *data,
+ size_t len)
{
struct iwl_ucode_tlv *tlv;
- enum iwl_ucode_tlv_type tlv_type;
u32 tlv_len;
while (len >= sizeof(*tlv)) {
@@ -210,7 +173,6 @@ static int iwl_parse_fw_dbg_tlv(struct iwl_trans *trans, const u8 *data,
tlv = (void *)data;
tlv_len = le32_to_cpu(tlv->length);
- tlv_type = le32_to_cpu(tlv->type);
if (len < tlv_len) {
IWL_ERR(trans, "invalid TLV len: %zd/%u\n",
@@ -220,39 +182,33 @@ static int iwl_parse_fw_dbg_tlv(struct iwl_trans *trans, const u8 *data,
len -= ALIGN(tlv_len, 4);
data += sizeof(*tlv) + ALIGN(tlv_len, 4);
- switch (tlv_type) {
- case IWL_UCODE_TLV_TYPE_DEBUG_INFO:
- case IWL_UCODE_TLV_TYPE_BUFFER_ALLOCATION:
- case IWL_UCODE_TLV_TYPE_HCMD:
- case IWL_UCODE_TLV_TYPE_REGIONS:
- case IWL_UCODE_TLV_TYPE_TRIGGERS:
- case IWL_UCODE_TLV_TYPE_DEBUG_FLOW:
- iwl_fw_dbg_copy_tlv(trans, tlv, true);
- break;
- default:
- WARN_ONCE(1, "Invalid TLV %x\n", tlv_type);
- break;
- }
+ iwl_dbg_tlv_alloc(trans, tlv, true);
}
return 0;
}
-void iwl_load_fw_dbg_tlv(struct device *dev, struct iwl_trans *trans)
+void iwl_dbg_tlv_load_bin(struct device *dev, struct iwl_trans *trans)
{
const struct firmware *fw;
int res;
- if (trans->dbg.external_ini_loaded || !iwlwifi_mod_params.enable_ini)
+ if (!iwlwifi_mod_params.enable_ini)
return;
res = request_firmware(&fw, "iwl-dbg-tlv.ini", dev);
if (res)
return;
- iwl_alloc_dbg_tlv(trans, fw->size, fw->data, true);
- iwl_parse_fw_dbg_tlv(trans, fw->data, fw->size);
+ iwl_dbg_tlv_parse_bin(trans, fw->data, fw->size);
- trans->dbg.external_ini_loaded = true;
release_firmware(fw);
}
+
+void iwl_dbg_tlv_time_point(struct iwl_fw_runtime *fwrt,
+ enum iwl_fw_ini_time_point tp_id,
+ union iwl_dbg_tlv_tp_data *tp_data)
+{
+ /* will be used later */
+}
+IWL_EXPORT_SYMBOL(iwl_dbg_tlv_time_point);
diff --git a/drivers/net/wireless/intel/iwlwifi/iwl-dbg-tlv.h b/drivers/net/wireless/intel/iwlwifi/iwl-dbg-tlv.h
index 222cd789e07a..e257ad358c94 100644
--- a/drivers/net/wireless/intel/iwlwifi/iwl-dbg-tlv.h
+++ b/drivers/net/wireless/intel/iwlwifi/iwl-dbg-tlv.h
@@ -5,7 +5,7 @@
*
* GPL LICENSE SUMMARY
*
- * Copyright (C) 2018 Intel Corporation
+ * Copyright (C) 2018 - 2019 Intel Corporation
*
* 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
@@ -28,7 +28,7 @@
*
* BSD LICENSE
*
- * Copyright (C) 2018 Intel Corporation
+ * Copyright (C) 2018 - 2019 Intel Corporation
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -66,22 +66,32 @@
/**
* struct iwl_apply_point_data
- * @data: start address of this apply point data
- * @size total size of the data
- * @offset: current offset of the copied data
+ * @list: list to go through the TLVs of the apply point
+ * @tlv: a debug TLV
*/
struct iwl_apply_point_data {
- void *data;
- int size;
- int offset;
+ struct list_head list;
+ struct iwl_ucode_tlv tlv;
+};
+
+/**
+ * union iwl_dbg_tlv_tp_data - data that is given in a time point
+ * @fw_pkt: a packet received from the FW
+ */
+union iwl_dbg_tlv_tp_data {
+ struct iwl_rx_packet *fw_pkt;
};
struct iwl_trans;
-void iwl_load_fw_dbg_tlv(struct device *dev, struct iwl_trans *trans);
-void iwl_fw_dbg_free(struct iwl_trans *trans);
-void iwl_fw_dbg_copy_tlv(struct iwl_trans *trans, struct iwl_ucode_tlv *tlv,
- bool ext);
-void iwl_alloc_dbg_tlv(struct iwl_trans *trans, size_t len, const u8 *data,
+struct iwl_fw_runtime;
+
+void iwl_dbg_tlv_load_bin(struct device *dev, struct iwl_trans *trans);
+void iwl_dbg_tlv_free(struct iwl_trans *trans);
+void iwl_dbg_tlv_alloc(struct iwl_trans *trans, struct iwl_ucode_tlv *tlv,
bool ext);
+void iwl_dbg_tlv_time_point(struct iwl_fw_runtime *fwrt,
+ enum iwl_fw_ini_time_point tp_id,
+ union iwl_dbg_tlv_tp_data *tp_data);
+void iwl_dbg_tlv_del_timers(struct iwl_trans *trans);
#endif /* __iwl_dbg_tlv_h__*/
diff --git a/drivers/net/wireless/intel/iwlwifi/iwl-devtrace.h b/drivers/net/wireless/intel/iwlwifi/iwl-devtrace.h
index cba958eb5186..fc8bc212ee84 100644
--- a/drivers/net/wireless/intel/iwlwifi/iwl-devtrace.h
+++ b/drivers/net/wireless/intel/iwlwifi/iwl-devtrace.h
@@ -75,7 +75,6 @@ static inline size_t iwl_rx_trace_len(const struct iwl_trans *trans,
#include <linux/tracepoint.h>
#include <linux/device.h>
-#include "iwl-trans.h"
#if !defined(CONFIG_IWLWIFI_DEVICE_TRACING) || defined(__CHECKER__)
diff --git a/drivers/net/wireless/intel/iwlwifi/iwl-drv.c b/drivers/net/wireless/intel/iwlwifi/iwl-drv.c
index 38672dd5aae9..ff0519ea00a5 100644
--- a/drivers/net/wireless/intel/iwlwifi/iwl-drv.c
+++ b/drivers/net/wireless/intel/iwlwifi/iwl-drv.c
@@ -215,7 +215,7 @@ static int iwl_request_firmware(struct iwl_drv *drv, bool first)
const struct iwl_cfg *cfg = drv->trans->cfg;
char tag[8];
- if (drv->trans->cfg->device_family == IWL_DEVICE_FAMILY_9000 &&
+ if (drv->trans->trans_cfg->device_family == IWL_DEVICE_FAMILY_9000 &&
(CSR_HW_REV_STEP(drv->trans->hw_rev) != SILICON_B_STEP &&
CSR_HW_REV_STEP(drv->trans->hw_rev) != SILICON_C_STEP)) {
IWL_ERR(drv,
@@ -647,9 +647,6 @@ static int iwl_parse_tlv_firmware(struct iwl_drv *drv,
len -= sizeof(*ucode);
- if (iwlwifi_mod_params.enable_ini)
- iwl_alloc_dbg_tlv(drv->trans, len, data, false);
-
while (len >= sizeof(*tlv)) {
len -= sizeof(*tlv);
tlv = (void *)data;
@@ -1123,7 +1120,7 @@ static int iwl_parse_tlv_firmware(struct iwl_drv *drv,
if (tlv_len != sizeof(*dbg_ptrs))
goto invalid_tlv_len;
- if (drv->trans->cfg->device_family <
+ if (drv->trans->trans_cfg->device_family <
IWL_DEVICE_FAMILY_22000)
break;
drv->trans->dbg.umac_error_event_table =
@@ -1139,7 +1136,7 @@ static int iwl_parse_tlv_firmware(struct iwl_drv *drv,
if (tlv_len != sizeof(*dbg_ptrs))
goto invalid_tlv_len;
- if (drv->trans->cfg->device_family <
+ if (drv->trans->trans_cfg->device_family <
IWL_DEVICE_FAMILY_22000)
break;
drv->trans->dbg.lmac_error_event_table[0] =
@@ -1154,9 +1151,8 @@ static int iwl_parse_tlv_firmware(struct iwl_drv *drv,
case IWL_UCODE_TLV_TYPE_HCMD:
case IWL_UCODE_TLV_TYPE_REGIONS:
case IWL_UCODE_TLV_TYPE_TRIGGERS:
- case IWL_UCODE_TLV_TYPE_DEBUG_FLOW:
if (iwlwifi_mod_params.enable_ini)
- iwl_fw_dbg_copy_tlv(drv->trans, tlv, false);
+ iwl_dbg_tlv_alloc(drv->trans, tlv, false);
break;
case IWL_UCODE_TLV_CMD_VERSIONS:
if (tlv_len % sizeof(struct iwl_fw_cmd_version)) {
@@ -1526,14 +1522,14 @@ static void iwl_req_fw_callback(const struct firmware *ucode_raw, void *context)
fw->init_evtlog_size = (pieces->init_evtlog_size - 16)/12;
else
fw->init_evtlog_size =
- drv->trans->cfg->base_params->max_event_log_size;
+ drv->trans->trans_cfg->base_params->max_event_log_size;
fw->init_errlog_ptr = pieces->init_errlog_ptr;
fw->inst_evtlog_ptr = pieces->inst_evtlog_ptr;
if (pieces->inst_evtlog_size)
fw->inst_evtlog_size = (pieces->inst_evtlog_size - 16)/12;
else
fw->inst_evtlog_size =
- drv->trans->cfg->base_params->max_event_log_size;
+ drv->trans->trans_cfg->base_params->max_event_log_size;
fw->inst_errlog_ptr = pieces->inst_errlog_ptr;
/*
@@ -1640,7 +1636,7 @@ struct iwl_drv *iwl_drv_start(struct iwl_trans *trans)
init_completion(&drv->request_firmware_complete);
INIT_LIST_HEAD(&drv->list);
- iwl_load_fw_dbg_tlv(drv->trans->dev, drv->trans);
+ iwl_dbg_tlv_load_bin(drv->trans->dev, drv->trans);
#ifdef CONFIG_IWLWIFI_DEBUGFS
/* Create the device debugfs entries. */
@@ -1662,8 +1658,8 @@ struct iwl_drv *iwl_drv_start(struct iwl_trans *trans)
err_fw:
#ifdef CONFIG_IWLWIFI_DEBUGFS
debugfs_remove_recursive(drv->dbgfs_drv);
+ iwl_dbg_tlv_free(drv->trans);
#endif
- iwl_fw_dbg_free(drv->trans);
kfree(drv);
err:
return ERR_PTR(ret);
@@ -1693,7 +1689,7 @@ void iwl_drv_stop(struct iwl_drv *drv)
debugfs_remove_recursive(drv->dbgfs_drv);
#endif
- iwl_fw_dbg_free(drv->trans);
+ iwl_dbg_tlv_free(drv->trans);
kfree(drv);
}
@@ -1704,8 +1700,6 @@ struct iwl_mod_params iwlwifi_mod_params = {
.fw_restart = true,
.bt_coex_active = true,
.power_level = IWL_POWER_INDEX_1,
- .d0i3_disable = true,
- .d0i3_timeout = 1000,
.uapsd_disable = IWL_DISABLE_UAPSD_BSS | IWL_DISABLE_UAPSD_P2P_CLIENT,
/* the rest are 0 by default */
};
@@ -1823,9 +1817,6 @@ MODULE_PARM_DESC(antenna_coupling,
module_param_named(nvm_file, iwlwifi_mod_params.nvm_file, charp, 0444);
MODULE_PARM_DESC(nvm_file, "NVM file name");
-module_param_named(d0i3_disable, iwlwifi_mod_params.d0i3_disable, bool, 0444);
-MODULE_PARM_DESC(d0i3_disable, "disable d0i3 functionality (default: Y)");
-
module_param_named(lar_disable, iwlwifi_mod_params.lar_disable, bool, 0444);
MODULE_PARM_DESC(lar_disable, "disable LAR functionality (default: N)");
@@ -1873,9 +1864,6 @@ module_param_named(fw_monitor, iwlwifi_mod_params.fw_monitor, bool, 0444);
MODULE_PARM_DESC(fw_monitor,
"firmware monitor - to debug FW (default: false - needs lots of memory)");
-module_param_named(d0i3_timeout, iwlwifi_mod_params.d0i3_timeout, uint, 0444);
-MODULE_PARM_DESC(d0i3_timeout, "Timeout to D0i3 entry when idle (ms)");
-
module_param_named(disable_11ac, iwlwifi_mod_params.disable_11ac, bool, 0444);
MODULE_PARM_DESC(disable_11ac, "Disable VHT capabilities (default: false)");
diff --git a/drivers/net/wireless/intel/iwlwifi/iwl-eeprom-parse.c b/drivers/net/wireless/intel/iwlwifi/iwl-eeprom-parse.c
index 04338c3a6205..cf7e2a9232e5 100644
--- a/drivers/net/wireless/intel/iwlwifi/iwl-eeprom-parse.c
+++ b/drivers/net/wireless/intel/iwlwifi/iwl-eeprom-parse.c
@@ -7,7 +7,7 @@
*
* Copyright(c) 2008 - 2014 Intel Corporation. All rights reserved.
* Copyright(c) 2015 Intel Mobile Communications GmbH
- * Copyright(c) 2018 Intel Corporation
+ * Copyright(c) 2018 - 2019 Intel Corporation
*
* 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
@@ -29,7 +29,7 @@
*
* Copyright(c) 2005 - 2014 Intel Corporation. All rights reserved.
* Copyright(c) 2015 Intel Mobile Communications GmbH
- * Copyright(c) 2018 Intel Corporation
+ * Copyright(c) 2018 - 2019 Intel Corporation
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -728,12 +728,13 @@ int iwl_init_sband_channels(struct iwl_nvm_data *data,
#define MAX_BIT_RATE_40_MHZ 150 /* Mbps */
#define MAX_BIT_RATE_20_MHZ 72 /* Mbps */
-void iwl_init_ht_hw_capab(const struct iwl_cfg *cfg,
+void iwl_init_ht_hw_capab(struct iwl_trans *trans,
struct iwl_nvm_data *data,
struct ieee80211_sta_ht_cap *ht_info,
enum nl80211_band band,
u8 tx_chains, u8 rx_chains)
{
+ const struct iwl_cfg *cfg = trans->cfg;
int max_bit_rate = 0;
tx_chains = hweight8(tx_chains);
@@ -765,7 +766,7 @@ void iwl_init_ht_hw_capab(const struct iwl_cfg *cfg,
if (cfg->ht_params->ldpc)
ht_info->cap |= IEEE80211_HT_CAP_LDPC_CODING;
- if ((cfg->mq_rx_supported &&
+ if ((trans->trans_cfg->mq_rx_supported &&
iwlwifi_mod_params.amsdu_size == IWL_AMSDU_DEF) ||
iwlwifi_mod_params.amsdu_size >= IWL_AMSDU_8K)
ht_info->cap |= IEEE80211_HT_CAP_MAX_AMSDU;
@@ -805,10 +806,11 @@ void iwl_init_ht_hw_capab(const struct iwl_cfg *cfg,
}
}
-static void iwl_init_sbands(struct device *dev, const struct iwl_cfg *cfg,
+static void iwl_init_sbands(struct iwl_trans *trans, const struct iwl_cfg *cfg,
struct iwl_nvm_data *data,
const u8 *eeprom, size_t eeprom_size)
{
+ struct device *dev = trans->dev;
int n_channels = iwl_init_channel_map(dev, cfg, data,
eeprom, eeprom_size);
int n_used = 0;
@@ -820,7 +822,7 @@ static void iwl_init_sbands(struct device *dev, const struct iwl_cfg *cfg,
sband->n_bitrates = N_RATES_24;
n_used += iwl_init_sband_channels(data, sband, n_channels,
NL80211_BAND_2GHZ);
- iwl_init_ht_hw_capab(cfg, data, &sband->ht_cap, NL80211_BAND_2GHZ,
+ iwl_init_ht_hw_capab(trans, data, &sband->ht_cap, NL80211_BAND_2GHZ,
data->valid_tx_ant, data->valid_rx_ant);
sband = &data->bands[NL80211_BAND_5GHZ];
@@ -829,7 +831,7 @@ static void iwl_init_sbands(struct device *dev, const struct iwl_cfg *cfg,
sband->n_bitrates = N_RATES_52;
n_used += iwl_init_sband_channels(data, sband, n_channels,
NL80211_BAND_5GHZ);
- iwl_init_ht_hw_capab(cfg, data, &sband->ht_cap, NL80211_BAND_5GHZ,
+ iwl_init_ht_hw_capab(trans, data, &sband->ht_cap, NL80211_BAND_5GHZ,
data->valid_tx_ant, data->valid_rx_ant);
if (n_channels != n_used)
@@ -840,10 +842,11 @@ static void iwl_init_sbands(struct device *dev, const struct iwl_cfg *cfg,
/* EEPROM data functions */
struct iwl_nvm_data *
-iwl_parse_eeprom_data(struct device *dev, const struct iwl_cfg *cfg,
+iwl_parse_eeprom_data(struct iwl_trans *trans, const struct iwl_cfg *cfg,
const u8 *eeprom, size_t eeprom_size)
{
struct iwl_nvm_data *data;
+ struct device *dev = trans->dev;
const void *tmp;
u16 radio_cfg, sku;
@@ -918,7 +921,7 @@ iwl_parse_eeprom_data(struct device *dev, const struct iwl_cfg *cfg,
goto err_free;
}
- iwl_init_sbands(dev, cfg, data, eeprom, eeprom_size);
+ iwl_init_sbands(trans, cfg, data, eeprom, eeprom_size);
return data;
err_free:
diff --git a/drivers/net/wireless/intel/iwlwifi/iwl-eeprom-parse.h b/drivers/net/wireless/intel/iwlwifi/iwl-eeprom-parse.h
index 2375d300a7cd..03a748cc98fa 100644
--- a/drivers/net/wireless/intel/iwlwifi/iwl-eeprom-parse.h
+++ b/drivers/net/wireless/intel/iwlwifi/iwl-eeprom-parse.h
@@ -116,14 +116,14 @@ struct iwl_nvm_data {
* later with iwl_free_nvm_data().
*/
struct iwl_nvm_data *
-iwl_parse_eeprom_data(struct device *dev, const struct iwl_cfg *cfg,
+iwl_parse_eeprom_data(struct iwl_trans *trans, const struct iwl_cfg *cfg,
const u8 *eeprom, size_t eeprom_size);
int iwl_init_sband_channels(struct iwl_nvm_data *data,
struct ieee80211_supported_band *sband,
int n_channels, enum nl80211_band band);
-void iwl_init_ht_hw_capab(const struct iwl_cfg *cfg,
+void iwl_init_ht_hw_capab(struct iwl_trans *trans,
struct iwl_nvm_data *data,
struct ieee80211_sta_ht_cap *ht_info,
enum nl80211_band band,
diff --git a/drivers/net/wireless/intel/iwlwifi/iwl-eeprom-read.c b/drivers/net/wireless/intel/iwlwifi/iwl-eeprom-read.c
index 82e87192119e..ad6dc4497437 100644
--- a/drivers/net/wireless/intel/iwlwifi/iwl-eeprom-read.c
+++ b/drivers/net/wireless/intel/iwlwifi/iwl-eeprom-read.c
@@ -6,7 +6,7 @@
* GPL LICENSE SUMMARY
*
* Copyright(c) 2008 - 2014 Intel Corporation. All rights reserved.
- * Copyright(c) 2018 Intel Corporation
+ * Copyright(c) 2018 - 2019 Intel Corporation
*
* 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
@@ -27,7 +27,7 @@
* BSD LICENSE
*
* Copyright(c) 2005 - 2014 Intel Corporation. All rights reserved.
- * Copyright(c) 2018 Intel Corporation
+ * Copyright(c) 2018 - 2019 Intel Corporation
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -193,7 +193,7 @@ static int iwl_init_otp_access(struct iwl_trans *trans)
{
int ret;
- ret = iwl_finish_nic_init(trans);
+ ret = iwl_finish_nic_init(trans, trans->trans_cfg);
if (ret)
return ret;
@@ -207,7 +207,7 @@ static int iwl_init_otp_access(struct iwl_trans *trans)
* CSR auto clock gate disable bit -
* this is only applicable for HW with OTP shadow RAM
*/
- if (trans->cfg->base_params->shadow_ram_support)
+ if (trans->trans_cfg->base_params->shadow_ram_support)
iwl_set_bit(trans, CSR_DBG_LINK_PWR_MGMT_REG,
CSR_RESET_LINK_PWR_MGMT_DISABLED);
@@ -328,7 +328,7 @@ static int iwl_find_otp_image(struct iwl_trans *trans,
}
/* more in the link list, continue */
usedblocks++;
- } while (usedblocks <= trans->cfg->base_params->max_ll_items);
+ } while (usedblocks <= trans->trans_cfg->base_params->max_ll_items);
/* OTP has no valid blocks */
IWL_DEBUG_EEPROM(trans->dev, "OTP has no valid blocks\n");
@@ -361,7 +361,7 @@ int iwl_read_eeprom(struct iwl_trans *trans, u8 **eeprom, size_t *eeprom_size)
if (nvm_is_otp < 0)
return nvm_is_otp;
- sz = trans->cfg->base_params->eeprom_size;
+ sz = trans->trans_cfg->base_params->eeprom_size;
IWL_DEBUG_EEPROM(trans->dev, "NVM size = %d\n", sz);
e = kmalloc(sz, GFP_KERNEL);
@@ -396,7 +396,7 @@ int iwl_read_eeprom(struct iwl_trans *trans, u8 **eeprom, size_t *eeprom_size)
CSR_OTP_GP_REG_ECC_CORR_STATUS_MSK |
CSR_OTP_GP_REG_ECC_UNCORR_STATUS_MSK);
/* traversing the linked list if no shadow ram supported */
- if (!trans->cfg->base_params->shadow_ram_support) {
+ if (!trans->trans_cfg->base_params->shadow_ram_support) {
ret = iwl_find_otp_image(trans, &validblockaddr);
if (ret)
goto err_unlock;
diff --git a/drivers/net/wireless/intel/iwlwifi/iwl-fh.h b/drivers/net/wireless/intel/iwlwifi/iwl-fh.h
index c6a534303936..0c12df558240 100644
--- a/drivers/net/wireless/intel/iwlwifi/iwl-fh.h
+++ b/drivers/net/wireless/intel/iwlwifi/iwl-fh.h
@@ -7,7 +7,7 @@
*
* Copyright(c) 2005 - 2014 Intel Corporation. All rights reserved.
* Copyright(c) 2015 - 2017 Intel Deutschland GmbH
- * Copyright(c) 2018 Intel Corporation
+ * Copyright(c) 2018 - 2019 Intel Corporation
*
* 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
@@ -29,7 +29,7 @@
*
* Copyright(c) 2005 - 2014 Intel Corporation. All rights reserved.
* Copyright(c) 2015 - 2017 Intel Deutschland GmbH
- * Copyright(c) 2018 Intel Corporation
+ * Copyright(c) 2018 - 2019 Intel Corporation
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -127,7 +127,7 @@
static inline unsigned int FH_MEM_CBBC_QUEUE(struct iwl_trans *trans,
unsigned int chnl)
{
- if (trans->cfg->use_tfh) {
+ if (trans->trans_cfg->use_tfh) {
WARN_ON_ONCE(chnl >= 64);
return TFH_TFDQ_CBB_TABLE + 8 * chnl;
}
diff --git a/drivers/net/wireless/intel/iwlwifi/iwl-io.c b/drivers/net/wireless/intel/iwlwifi/iwl-io.c
index a704e25af810..1b7414bf7bef 100644
--- a/drivers/net/wireless/intel/iwlwifi/iwl-io.c
+++ b/drivers/net/wireless/intel/iwlwifi/iwl-io.c
@@ -304,10 +304,10 @@ IWL_EXPORT_SYMBOL(iwl_clear_bits_prph);
void iwl_force_nmi(struct iwl_trans *trans)
{
- if (trans->cfg->device_family < IWL_DEVICE_FAMILY_9000)
+ if (trans->trans_cfg->device_family < IWL_DEVICE_FAMILY_9000)
iwl_write_prph(trans, DEVICE_SET_NMI_REG,
DEVICE_SET_NMI_VAL_DRV);
- else if (trans->cfg->device_family < IWL_DEVICE_FAMILY_AX210)
+ else if (trans->trans_cfg->device_family < IWL_DEVICE_FAMILY_AX210)
iwl_write_umac_prph(trans, UREG_NIC_SET_NMI_DRIVER,
UREG_NIC_SET_NMI_DRIVER_NMI_FROM_DRIVER_MSK);
else
@@ -458,7 +458,7 @@ int iwl_dump_fh(struct iwl_trans *trans, char **buf)
FH_TSSR_TX_ERROR_REG
};
- if (trans->cfg->mq_rx_supported)
+ if (trans->trans_cfg->mq_rx_supported)
return iwl_dump_rfh(trans, buf);
#ifdef CONFIG_IWLWIFI_DEBUGFS
@@ -492,11 +492,12 @@ int iwl_dump_fh(struct iwl_trans *trans, char **buf)
return 0;
}
-int iwl_finish_nic_init(struct iwl_trans *trans)
+int iwl_finish_nic_init(struct iwl_trans *trans,
+ const struct iwl_cfg_trans_params *cfg_trans)
{
int err;
- if (trans->cfg->bisr_workaround) {
+ if (cfg_trans->bisr_workaround) {
/* ensure the TOP FSM isn't still in previous reset */
mdelay(2);
}
@@ -506,9 +507,9 @@ int iwl_finish_nic_init(struct iwl_trans *trans)
* D0U* --> D0A* (powered-up active) state.
*/
iwl_set_bit(trans, CSR_GP_CNTRL,
- BIT(trans->cfg->csr->flag_init_done));
+ BIT(cfg_trans->csr->flag_init_done));
- if (trans->cfg->device_family == IWL_DEVICE_FAMILY_8000)
+ if (cfg_trans->device_family == IWL_DEVICE_FAMILY_8000)
udelay(2);
/*
@@ -517,13 +518,13 @@ int iwl_finish_nic_init(struct iwl_trans *trans)
* and accesses to uCode SRAM.
*/
err = iwl_poll_bit(trans, CSR_GP_CNTRL,
- BIT(trans->cfg->csr->flag_mac_clock_ready),
- BIT(trans->cfg->csr->flag_mac_clock_ready),
+ BIT(cfg_trans->csr->flag_mac_clock_ready),
+ BIT(cfg_trans->csr->flag_mac_clock_ready),
25000);
if (err < 0)
IWL_DEBUG_INFO(trans, "Failed to wake NIC\n");
- if (trans->cfg->bisr_workaround) {
+ if (cfg_trans->bisr_workaround) {
/* ensure BISR shift has finished */
udelay(200);
}
diff --git a/drivers/net/wireless/intel/iwlwifi/iwl-io.h b/drivers/net/wireless/intel/iwlwifi/iwl-io.h
index 920e2146ea3f..f09e368c7040 100644
--- a/drivers/net/wireless/intel/iwlwifi/iwl-io.h
+++ b/drivers/net/wireless/intel/iwlwifi/iwl-io.h
@@ -99,7 +99,8 @@ void iwl_set_bits_mask_prph(struct iwl_trans *trans, u32 ofs,
void iwl_clear_bits_prph(struct iwl_trans *trans, u32 ofs, u32 mask);
void iwl_force_nmi(struct iwl_trans *trans);
-int iwl_finish_nic_init(struct iwl_trans *trans);
+int iwl_finish_nic_init(struct iwl_trans *trans,
+ const struct iwl_cfg_trans_params *cfg_trans);
/* Error handling */
int iwl_dump_fh(struct iwl_trans *trans, char **buf);
@@ -111,35 +112,38 @@ int iwl_dump_fh(struct iwl_trans *trans, char **buf);
*/
static inline u32 iwl_umac_prph(struct iwl_trans *trans, u32 ofs)
{
- return ofs + trans->cfg->umac_prph_offset;
+ return ofs + trans->trans_cfg->umac_prph_offset;
}
static inline u32 iwl_read_umac_prph_no_grab(struct iwl_trans *trans, u32 ofs)
{
- return iwl_read_prph_no_grab(trans, ofs + trans->cfg->umac_prph_offset);
+ return iwl_read_prph_no_grab(trans, ofs +
+ trans->trans_cfg->umac_prph_offset);
}
static inline u32 iwl_read_umac_prph(struct iwl_trans *trans, u32 ofs)
{
- return iwl_read_prph(trans, ofs + trans->cfg->umac_prph_offset);
+ return iwl_read_prph(trans, ofs + trans->trans_cfg->umac_prph_offset);
}
static inline void iwl_write_umac_prph_no_grab(struct iwl_trans *trans, u32 ofs,
u32 val)
{
- iwl_write_prph_no_grab(trans, ofs + trans->cfg->umac_prph_offset, val);
+ iwl_write_prph_no_grab(trans, ofs + trans->trans_cfg->umac_prph_offset,
+ val);
}
static inline void iwl_write_umac_prph(struct iwl_trans *trans, u32 ofs,
u32 val)
{
- iwl_write_prph(trans, ofs + trans->cfg->umac_prph_offset, val);
+ iwl_write_prph(trans, ofs + trans->trans_cfg->umac_prph_offset, val);
}
static inline int iwl_poll_umac_prph_bit(struct iwl_trans *trans, u32 addr,
u32 bits, u32 mask, int timeout)
{
- return iwl_poll_prph_bit(trans, addr + trans->cfg->umac_prph_offset,
+ return iwl_poll_prph_bit(trans, addr +
+ trans->trans_cfg->umac_prph_offset,
bits, mask, timeout);
}
diff --git a/drivers/net/wireless/intel/iwlwifi/iwl-modparams.h b/drivers/net/wireless/intel/iwlwifi/iwl-modparams.h
index 0cae2ef9b9df..ebea3f308b5d 100644
--- a/drivers/net/wireless/intel/iwlwifi/iwl-modparams.h
+++ b/drivers/net/wireless/intel/iwlwifi/iwl-modparams.h
@@ -6,7 +6,7 @@
* GPL LICENSE SUMMARY
*
* Copyright(c) 2007 - 2014 Intel Corporation. All rights reserved.
- * Copyright(c) 2018 Intel Corporation
+ * Copyright(c) 2018 - 2019 Intel Corporation
*
* 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
@@ -27,7 +27,7 @@
* BSD LICENSE
*
* Copyright(c) 2005 - 2014 Intel Corporation. All rights reserved.
- * Copyright(c) 2018 Intel Corporation
+ * Copyright(c) 2018 - 2019 Intel Corporation
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -115,9 +115,6 @@ enum iwl_uapsd_disable {
* @nvm_file: specifies a external NVM file
* @uapsd_disable: disable U-APSD, see &enum iwl_uapsd_disable, default =
* IWL_DISABLE_UAPSD_BSS | IWL_DISABLE_UAPSD_P2P_CLIENT
- * @d0i3_disable: disable d0i3, default = 1,
- * @d0i3_timeout: time to wait after no refs are taken before
- * entering D0i3 (in msecs)
* @lar_disable: disable LAR (regulatory), default = 0
* @fw_monitor: allow to use firmware monitor
* @disable_11ac: disable VHT capabilities, default = false.
@@ -139,8 +136,6 @@ struct iwl_mod_params {
int antenna_coupling;
char *nvm_file;
u32 uapsd_disable;
- bool d0i3_disable;
- unsigned int d0i3_timeout;
bool lar_disable;
bool fw_monitor;
bool disable_11ac;
diff --git a/drivers/net/wireless/intel/iwlwifi/iwl-nvm-parse.c b/drivers/net/wireless/intel/iwlwifi/iwl-nvm-parse.c
index d87a6bb3e456..c8972f6e38ba 100644
--- a/drivers/net/wireless/intel/iwlwifi/iwl-nvm-parse.c
+++ b/drivers/net/wireless/intel/iwlwifi/iwl-nvm-parse.c
@@ -393,11 +393,12 @@ static int iwl_init_channel_map(struct device *dev, const struct iwl_cfg *cfg,
return n_channels;
}
-static void iwl_init_vht_hw_capab(const struct iwl_cfg *cfg,
+static void iwl_init_vht_hw_capab(struct iwl_trans *trans,
struct iwl_nvm_data *data,
struct ieee80211_sta_vht_cap *vht_cap,
u8 tx_chains, u8 rx_chains)
{
+ const struct iwl_cfg *cfg = trans->cfg;
int num_rx_ants = num_of_ant(rx_chains);
int num_tx_ants = num_of_ant(tx_chains);
unsigned int max_ampdu_exponent = (cfg->max_vht_ampdu_exponent ?:
@@ -434,14 +435,14 @@ static void iwl_init_vht_hw_capab(const struct iwl_cfg *cfg,
switch (iwlwifi_mod_params.amsdu_size) {
case IWL_AMSDU_DEF:
- if (cfg->mq_rx_supported)
+ if (trans->trans_cfg->mq_rx_supported)
vht_cap->cap |=
IEEE80211_VHT_CAP_MAX_MPDU_LENGTH_11454;
else
vht_cap->cap |= IEEE80211_VHT_CAP_MAX_MPDU_LENGTH_3895;
break;
case IWL_AMSDU_2K:
- if (cfg->mq_rx_supported)
+ if (trans->trans_cfg->mq_rx_supported)
vht_cap->cap |=
IEEE80211_VHT_CAP_MAX_MPDU_LENGTH_11454;
else
@@ -669,11 +670,13 @@ static void iwl_init_he_hw_capab(struct ieee80211_supported_band *sband,
}
}
-static void iwl_init_sbands(struct device *dev, const struct iwl_cfg *cfg,
+static void iwl_init_sbands(struct iwl_trans *trans,
struct iwl_nvm_data *data,
const void *nvm_ch_flags, u8 tx_chains,
u8 rx_chains, u32 sbands_flags, bool v4)
{
+ struct device *dev = trans->dev;
+ const struct iwl_cfg *cfg = trans->cfg;
int n_channels;
int n_used = 0;
struct ieee80211_supported_band *sband;
@@ -686,7 +689,7 @@ static void iwl_init_sbands(struct device *dev, const struct iwl_cfg *cfg,
sband->n_bitrates = N_RATES_24;
n_used += iwl_init_sband_channels(data, sband, n_channels,
NL80211_BAND_2GHZ);
- iwl_init_ht_hw_capab(cfg, data, &sband->ht_cap, NL80211_BAND_2GHZ,
+ iwl_init_ht_hw_capab(trans, data, &sband->ht_cap, NL80211_BAND_2GHZ,
tx_chains, rx_chains);
if (data->sku_cap_11ax_enable && !iwlwifi_mod_params.disable_11ax)
@@ -698,10 +701,10 @@ static void iwl_init_sbands(struct device *dev, const struct iwl_cfg *cfg,
sband->n_bitrates = N_RATES_52;
n_used += iwl_init_sband_channels(data, sband, n_channels,
NL80211_BAND_5GHZ);
- iwl_init_ht_hw_capab(cfg, data, &sband->ht_cap, NL80211_BAND_5GHZ,
+ iwl_init_ht_hw_capab(trans, data, &sband->ht_cap, NL80211_BAND_5GHZ,
tx_chains, rx_chains);
if (data->sku_cap_11ac_enable && !iwlwifi_mod_params.disable_11ac)
- iwl_init_vht_hw_capab(cfg, data, &sband->vht_cap,
+ iwl_init_vht_hw_capab(trans, data, &sband->vht_cap,
tx_chains, rx_chains);
if (data->sku_cap_11ax_enable && !iwlwifi_mod_params.disable_11ax)
@@ -793,10 +796,10 @@ static void iwl_set_hw_address_from_csr(struct iwl_trans *trans,
{
__le32 mac_addr0 =
cpu_to_le32(iwl_read32(trans,
- trans->cfg->csr->mac_addr0_strap));
+ trans->trans_cfg->csr->mac_addr0_strap));
__le32 mac_addr1 =
cpu_to_le32(iwl_read32(trans,
- trans->cfg->csr->mac_addr1_strap));
+ trans->trans_cfg->csr->mac_addr1_strap));
iwl_flip_hw_address(mac_addr0, mac_addr1, data->hw_addr);
/*
@@ -807,9 +810,9 @@ static void iwl_set_hw_address_from_csr(struct iwl_trans *trans,
return;
mac_addr0 = cpu_to_le32(iwl_read32(trans,
- trans->cfg->csr->mac_addr0_otp));
+ trans->trans_cfg->csr->mac_addr0_otp));
mac_addr1 = cpu_to_le32(iwl_read32(trans,
- trans->cfg->csr->mac_addr1_otp));
+ trans->trans_cfg->csr->mac_addr1_otp));
iwl_flip_hw_address(mac_addr0, mac_addr1, data->hw_addr);
}
@@ -896,7 +899,7 @@ static int iwl_set_hw_address(struct iwl_trans *trans,
}
static bool
-iwl_nvm_no_wide_in_5ghz(struct device *dev, const struct iwl_cfg *cfg,
+iwl_nvm_no_wide_in_5ghz(struct iwl_trans *trans, const struct iwl_cfg *cfg,
const __be16 *nvm_hw)
{
/*
@@ -908,7 +911,7 @@ iwl_nvm_no_wide_in_5ghz(struct device *dev, const struct iwl_cfg *cfg,
* in 5GHz otherwise the FW will throw a sysassert when we try
* to use them.
*/
- if (cfg->device_family == IWL_DEVICE_FAMILY_7000) {
+ if (trans->trans_cfg->device_family == IWL_DEVICE_FAMILY_7000) {
/*
* Unlike the other sections in the NVM, the hw
* section uses big-endian.
@@ -917,7 +920,7 @@ iwl_nvm_no_wide_in_5ghz(struct device *dev, const struct iwl_cfg *cfg,
u8 sku = (subsystem_id & 0x1e) >> 1;
if (sku == 5 || sku == 9) {
- IWL_DEBUG_EEPROM(dev,
+ IWL_DEBUG_EEPROM(trans->dev,
"disabling wide channels in 5GHz (0x%0x %d)\n",
subsystem_id, sku);
return true;
@@ -934,7 +937,6 @@ iwl_parse_nvm_data(struct iwl_trans *trans, const struct iwl_cfg *cfg,
const __le16 *mac_override, const __le16 *phy_sku,
u8 tx_chains, u8 rx_chains, bool lar_fw_supported)
{
- struct device *dev = trans->dev;
struct iwl_nvm_data *data;
bool lar_enabled;
u32 sku, radio_cfg;
@@ -942,7 +944,11 @@ iwl_parse_nvm_data(struct iwl_trans *trans, const struct iwl_cfg *cfg,
u16 lar_config;
const __le16 *ch_section;
- if (cfg->nvm_type != IWL_NVM_EXT)
+ if (cfg->uhb_supported)
+ data = kzalloc(struct_size(data, channels,
+ IWL_NVM_NUM_CHANNELS_UHB),
+ GFP_KERNEL);
+ else if (cfg->nvm_type != IWL_NVM_EXT)
data = kzalloc(struct_size(data, channels,
IWL_NVM_NUM_CHANNELS),
GFP_KERNEL);
@@ -1012,10 +1018,10 @@ iwl_parse_nvm_data(struct iwl_trans *trans, const struct iwl_cfg *cfg,
if (lar_fw_supported && lar_enabled)
sbands_flags |= IWL_NVM_SBANDS_FLAGS_LAR;
- if (iwl_nvm_no_wide_in_5ghz(dev, cfg, nvm_hw))
+ if (iwl_nvm_no_wide_in_5ghz(trans, cfg, nvm_hw))
sbands_flags |= IWL_NVM_SBANDS_FLAGS_NO_WIDE_IN_5GHZ;
- iwl_init_sbands(dev, cfg, data, ch_section, tx_chains, rx_chains,
+ iwl_init_sbands(trans, data, ch_section, tx_chains, rx_chains,
sbands_flags, false);
data->calib_version = 255;
@@ -1066,11 +1072,6 @@ static u32 iwl_nvm_get_regdom_bw_flags(const u16 *nvm_chan,
return flags;
}
-struct regdb_ptrs {
- struct ieee80211_wmm_rule *rule;
- u32 token;
-};
-
struct ieee80211_regdomain *
iwl_parse_nvm_mcc_info(struct device *dev, const struct iwl_cfg *cfg,
int num_of_ch, __le32 *channels, u16 fw_mcc,
@@ -1082,7 +1083,6 @@ iwl_parse_nvm_mcc_info(struct device *dev, const struct iwl_cfg *cfg,
const u16 *nvm_chan;
struct ieee80211_regdomain *regd, *copy_rd;
struct ieee80211_reg_rule *rule;
- struct regdb_ptrs *regdb_ptrs;
enum nl80211_band band;
int center_freq, prev_center_freq = 0;
int valid_rules = 0;
@@ -1114,12 +1114,6 @@ iwl_parse_nvm_mcc_info(struct device *dev, const struct iwl_cfg *cfg,
if (!regd)
return ERR_PTR(-ENOMEM);
- regdb_ptrs = kcalloc(num_of_ch, sizeof(*regdb_ptrs), GFP_KERNEL);
- if (!regdb_ptrs) {
- copy_rd = ERR_PTR(-ENOMEM);
- goto out;
- }
-
/* set alpha2 from FW. */
regd->alpha2[0] = fw_mcc >> 8;
regd->alpha2[1] = fw_mcc & 0xff;
@@ -1191,8 +1185,6 @@ iwl_parse_nvm_mcc_info(struct device *dev, const struct iwl_cfg *cfg,
if (!copy_rd)
copy_rd = ERR_PTR(-ENOMEM);
-out:
- kfree(regdb_ptrs);
kfree(regd);
return copy_rd;
}
@@ -1311,7 +1303,7 @@ int iwl_read_external_nvm(struct iwl_trans *trans,
le32_to_cpu(dword_buff[3]));
/* nvm file validation, dword_buff[2] holds the file version */
- if (trans->cfg->device_family == IWL_DEVICE_FAMILY_8000 &&
+ if (trans->trans_cfg->device_family == IWL_DEVICE_FAMILY_8000 &&
CSR_HW_REV_STEP(trans->hw_rev) == SILICON_C_STEP &&
le32_to_cpu(dword_buff[2]) < 0xE4A) {
ret = -EFAULT;
@@ -1495,7 +1487,7 @@ struct iwl_nvm_data *iwl_get_nvm(struct iwl_trans *trans,
channel_profile = v4 ? (void *)rsp->regulatory.channel_profile :
(void *)rsp_v3->regulatory.channel_profile;
- iwl_init_sbands(trans->dev, trans->cfg, nvm,
+ iwl_init_sbands(trans, nvm,
channel_profile,
nvm->valid_tx_ant & fw->valid_tx_ant,
nvm->valid_rx_ant & fw->valid_rx_ant,
diff --git a/drivers/net/wireless/intel/iwlwifi/iwl-op-mode.h b/drivers/net/wireless/intel/iwlwifi/iwl-op-mode.h
index cbd1a8eed620..3008a5246be8 100644
--- a/drivers/net/wireless/intel/iwlwifi/iwl-op-mode.h
+++ b/drivers/net/wireless/intel/iwlwifi/iwl-op-mode.h
@@ -8,7 +8,7 @@
* Copyright(c) 2007 - 2014 Intel Corporation. All rights reserved.
* Copyright(c) 2013 - 2014 Intel Mobile Communications GmbH
* Copyright(c) 2015 Intel Deutschland GmbH
- * Copyright(c) 2018 Intel Corporation
+ * Copyright(c) 2018 - 2019 Intel Corporation
*
* 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
@@ -31,7 +31,7 @@
* Copyright(c) 2005 - 2014 Intel Corporation. All rights reserved.
* Copyright(c) 2013 - 2014 Intel Mobile Communications GmbH
* Copyright(c) 2015 Intel Deutschland GmbH
- * Copyright(c) 2018 Intel Corporation
+ * Copyright(c) 2018 - 2019 Intel Corporation
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -140,9 +140,6 @@ struct iwl_cfg;
* @nic_config: configure NIC, called before firmware is started.
* May sleep
* @wimax_active: invoked when WiMax becomes active. May sleep
- * @enter_d0i3: configure the fw to enter d0i3. return 1 to indicate d0i3
- * entrance is aborted (e.g. due to held reference). May sleep.
- * @exit_d0i3: configure the fw to exit d0i3. May sleep.
*/
struct iwl_op_mode_ops {
struct iwl_op_mode *(*start)(struct iwl_trans *trans,
@@ -164,8 +161,6 @@ struct iwl_op_mode_ops {
void (*cmd_queue_full)(struct iwl_op_mode *op_mode);
void (*nic_config)(struct iwl_op_mode *op_mode);
void (*wimax_active)(struct iwl_op_mode *op_mode);
- int (*enter_d0i3)(struct iwl_op_mode *op_mode);
- int (*exit_d0i3)(struct iwl_op_mode *op_mode);
};
int iwl_opmode_register(const char *name, const struct iwl_op_mode_ops *ops);
@@ -258,22 +253,4 @@ static inline void iwl_op_mode_wimax_active(struct iwl_op_mode *op_mode)
op_mode->ops->wimax_active(op_mode);
}
-static inline int iwl_op_mode_enter_d0i3(struct iwl_op_mode *op_mode)
-{
- might_sleep();
-
- if (!op_mode->ops->enter_d0i3)
- return 0;
- return op_mode->ops->enter_d0i3(op_mode);
-}
-
-static inline int iwl_op_mode_exit_d0i3(struct iwl_op_mode *op_mode)
-{
- might_sleep();
-
- if (!op_mode->ops->exit_d0i3)
- return 0;
- return op_mode->ops->exit_d0i3(op_mode);
-}
-
#endif /* __iwl_op_mode_h__ */
diff --git a/drivers/net/wireless/intel/iwlwifi/iwl-prph.h b/drivers/net/wireless/intel/iwlwifi/iwl-prph.h
index 8d930bfe0727..f47e0f97acf8 100644
--- a/drivers/net/wireless/intel/iwlwifi/iwl-prph.h
+++ b/drivers/net/wireless/intel/iwlwifi/iwl-prph.h
@@ -451,6 +451,8 @@ enum {
#define UREG_DOORBELL_TO_ISR6 0xA05C04
#define UREG_DOORBELL_TO_ISR6_NMI_BIT BIT(0)
+#define UREG_DOORBELL_TO_ISR6_SUSPEND BIT(18)
+#define UREG_DOORBELL_TO_ISR6_RESUME BIT(19)
#define FSEQ_ERROR_CODE 0xA340C8
#define FSEQ_TOP_INIT_VERSION 0xA34038
@@ -460,4 +462,7 @@ enum {
#define FSEQ_ALIVE_TOKEN 0xA340F0
#define FSEQ_CNVI_ID 0xA3408C
#define FSEQ_CNVR_ID 0xA34090
+
+#define IWL_D3_SLEEP_STATUS_SUSPEND 0xD3
+#define IWL_D3_SLEEP_STATUS_RESUME 0xD0
#endif /* __iwl_prph_h__ */
diff --git a/drivers/net/wireless/intel/iwlwifi/iwl-trans.c b/drivers/net/wireless/intel/iwlwifi/iwl-trans.c
index 727f73e0b3f1..28bdc9a9617e 100644
--- a/drivers/net/wireless/intel/iwlwifi/iwl-trans.c
+++ b/drivers/net/wireless/intel/iwlwifi/iwl-trans.c
@@ -66,7 +66,6 @@
struct iwl_trans *iwl_trans_alloc(unsigned int priv_size,
struct device *dev,
- const struct iwl_cfg *cfg,
const struct iwl_trans_ops *ops)
{
struct iwl_trans *trans;
@@ -84,7 +83,6 @@ struct iwl_trans *iwl_trans_alloc(unsigned int priv_size,
#endif
trans->dev = dev;
- trans->cfg = cfg;
trans->ops = ops;
trans->num_rx_queues = 1;
@@ -202,17 +200,3 @@ int iwl_cmd_groups_verify_sorted(const struct iwl_trans_config *trans)
return 0;
}
IWL_EXPORT_SYMBOL(iwl_cmd_groups_verify_sorted);
-
-void iwl_trans_ref(struct iwl_trans *trans)
-{
- if (trans->ops->ref)
- trans->ops->ref(trans);
-}
-IWL_EXPORT_SYMBOL(iwl_trans_ref);
-
-void iwl_trans_unref(struct iwl_trans *trans)
-{
- if (trans->ops->unref)
- trans->ops->unref(trans);
-}
-IWL_EXPORT_SYMBOL(iwl_trans_unref);
diff --git a/drivers/net/wireless/intel/iwlwifi/iwl-trans.h b/drivers/net/wireless/intel/iwlwifi/iwl-trans.h
index 0f8aeb111b0e..a31408188ed0 100644
--- a/drivers/net/wireless/intel/iwlwifi/iwl-trans.h
+++ b/drivers/net/wireless/intel/iwlwifi/iwl-trans.h
@@ -159,13 +159,6 @@ static inline u32 iwl_rx_packet_payload_len(const struct iwl_rx_packet *pkt)
* @CMD_ASYNC: Return right away and don't wait for the response
* @CMD_WANT_SKB: Not valid with CMD_ASYNC. The caller needs the buffer of
* the response. The caller needs to call iwl_free_resp when done.
- * @CMD_HIGH_PRIO: The command is high priority - it goes to the front of the
- * command queue, but after other high priority commands. Valid only
- * with CMD_ASYNC.
- * @CMD_SEND_IN_IDLE: The command should be sent even when the trans is idle.
- * @CMD_MAKE_TRANS_IDLE: The command response should mark the trans as idle.
- * @CMD_WAKE_UP_TRANS: The command response should wake up the trans
- * (i.e. mark it as non-idle).
* @CMD_WANT_ASYNC_CALLBACK: the op_mode's async callback function must be
* called after this command completes. Valid only with CMD_ASYNC.
*/
@@ -173,11 +166,7 @@ enum CMD_MODE {
CMD_ASYNC = BIT(0),
CMD_WANT_SKB = BIT(1),
CMD_SEND_IN_RFKILL = BIT(2),
- CMD_HIGH_PRIO = BIT(3),
- CMD_SEND_IN_IDLE = BIT(4),
- CMD_MAKE_TRANS_IDLE = BIT(5),
- CMD_WAKE_UP_TRANS = BIT(6),
- CMD_WANT_ASYNC_CALLBACK = BIT(7),
+ CMD_WANT_ASYNC_CALLBACK = BIT(3),
};
#define DEF_CMD_PAYLOAD_SIZE 320
@@ -463,9 +452,8 @@ struct iwl_trans_rxq_dma_data {
*
* All the handlers MUST be implemented
*
- * @start_hw: starts the HW. If low_power is true, the NIC needs to be taken
- * out of a low power state. From that point on, the HW can send
- * interrupts. May sleep.
+ * @start_hw: starts the HW. From that point on, the HW can send interrupts.
+ * May sleep.
* @op_mode_leave: Turn off the HW RF kill indication if on
* May sleep
* @start_fw: allocates and inits all the resources for the transport
@@ -475,9 +463,8 @@ struct iwl_trans_rxq_dma_data {
* the SCD base address in SRAM, then provide it here, or 0 otherwise.
* May sleep
* @stop_device: stops the whole device (embedded CPU put to reset) and stops
- * the HW. If low_power is true, the NIC will be put in low power state.
- * From that point on, the HW will be stopped but will still issue an
- * interrupt if the HW RF kill switch is triggered.
+ * the HW. From that point on, the HW will be stopped but will still issue
+ * an interrupt if the HW RF kill switch is triggered.
* This callback must do the right thing and not crash even if %start_hw()
* was called but not &start_fw(). May sleep.
* @d3_suspend: put the device into the correct mode for WoWLAN during
@@ -535,11 +522,6 @@ struct iwl_trans_rxq_dma_data {
* @release_nic_access: let the NIC go to sleep. The "flags" parameter
* must be the same one that was sent before to the grab_nic_access.
* @set_bits_mask - set SRAM register according to value and mask.
- * @ref: grab a reference to the transport/FW layers, disallowing
- * certain low power states
- * @unref: release a reference previously taken with @ref. Note that
- * initially the reference count is 1, making an initial @unref
- * necessary to allow low power states.
* @dump_data: return a vmalloc'ed buffer with debug data, maybe containing last
* TX'ed commands and similar. The buffer will be vfree'd by the caller.
* Note that the transport must fill in the proper file headers.
@@ -548,14 +530,14 @@ struct iwl_trans_rxq_dma_data {
*/
struct iwl_trans_ops {
- int (*start_hw)(struct iwl_trans *iwl_trans, bool low_power);
+ int (*start_hw)(struct iwl_trans *iwl_trans);
void (*op_mode_leave)(struct iwl_trans *iwl_trans);
int (*start_fw)(struct iwl_trans *trans, const struct fw_img *fw,
bool run_in_rfkill);
void (*fw_alive)(struct iwl_trans *trans, u32 scd_addr);
- void (*stop_device)(struct iwl_trans *trans, bool low_power);
+ void (*stop_device)(struct iwl_trans *trans);
- void (*d3_suspend)(struct iwl_trans *trans, bool test, bool reset);
+ int (*d3_suspend)(struct iwl_trans *trans, bool test, bool reset);
int (*d3_resume)(struct iwl_trans *trans, enum iwl_d3_status *status,
bool test, bool reset);
@@ -566,6 +548,8 @@ struct iwl_trans_ops {
void (*reclaim)(struct iwl_trans *trans, int queue, int ssn,
struct sk_buff_head *skbs);
+ void (*set_q_ptrs)(struct iwl_trans *trans, int queue, int ptr);
+
bool (*txq_enable)(struct iwl_trans *trans, int queue, u16 ssn,
const struct iwl_trans_txq_scd_cfg *cfg,
unsigned int queue_wdg_timeout);
@@ -607,8 +591,6 @@ struct iwl_trans_ops {
unsigned long *flags);
void (*set_bits_mask)(struct iwl_trans *trans, u32 reg, u32 mask,
u32 value);
- void (*ref)(struct iwl_trans *trans);
- void (*unref)(struct iwl_trans *trans);
int (*suspend)(struct iwl_trans *trans);
void (*resume)(struct iwl_trans *trans);
@@ -632,9 +614,6 @@ enum iwl_trans_state {
/**
* DOC: Platform power management
*
- * There are two types of platform power management: system-wide
- * (WoWLAN) and runtime.
- *
* In system-wide power management the entire platform goes into a low
* power state (e.g. idle or suspend to RAM) at the same time and the
* device is configured as a wakeup source for the entire platform.
@@ -643,54 +622,46 @@ enum iwl_trans_state {
* put the platform in low power mode). The device's behavior in this
* mode is dictated by the wake-on-WLAN configuration.
*
- * In runtime power management, only the devices which are themselves
- * idle enter a low power state. This is done at runtime, which means
- * that the entire system is still running normally. This mode is
- * usually triggered automatically by the device driver and requires
- * the ability to enter and exit the low power modes in a very short
- * time, so there is not much impact in usability.
- *
* The terms used for the device's behavior are as follows:
*
* - D0: the device is fully powered and the host is awake;
* - D3: the device is in low power mode and only reacts to
* specific events (e.g. magic-packet received or scan
* results found);
- * - D0I3: the device is in low power mode and reacts to any
- * activity (e.g. RX);
*
* These terms reflect the power modes in the firmware and are not to
- * be confused with the physical device power state. The NIC can be
- * in D0I3 mode even if, for instance, the PCI device is in D3 state.
+ * be confused with the physical device power state.
*/
/**
* enum iwl_plat_pm_mode - platform power management mode
*
* This enumeration describes the device's platform power management
- * behavior when in idle mode (i.e. runtime power management) or when
- * in system-wide suspend (i.e WoWLAN).
+ * behavior when in system-wide suspend (i.e WoWLAN).
*
* @IWL_PLAT_PM_MODE_DISABLED: power management is disabled for this
- * device. At runtime, this means that nothing happens and the
- * device always remains in active. In system-wide suspend mode,
- * it means that the all connections will be closed automatically
- * by mac80211 before the platform is suspended.
+ * device. In system-wide suspend mode, it means that the all
+ * connections will be closed automatically by mac80211 before
+ * the platform is suspended.
* @IWL_PLAT_PM_MODE_D3: the device goes into D3 mode (i.e. WoWLAN).
- * For runtime power management, this mode is not officially
- * supported.
- * @IWL_PLAT_PM_MODE_D0I3: the device goes into D0I3 mode.
*/
enum iwl_plat_pm_mode {
IWL_PLAT_PM_MODE_DISABLED,
IWL_PLAT_PM_MODE_D3,
- IWL_PLAT_PM_MODE_D0I3,
};
-/* Max time to wait for trans to become idle/non-idle on d0i3
- * enter/exit (in msecs).
+/**
+ * enum iwl_ini_cfg_state
+ * @IWL_INI_CFG_STATE_NOT_LOADED: no debug cfg was given
+ * @IWL_INI_CFG_STATE_LOADED: debug cfg was found and loaded
+ * @IWL_INI_CFG_STATE_CORRUPTED: debug cfg was found and some of the TLVs
+ * are corrupted. The rest of the debug TLVs will still be used
*/
-#define IWL_TRANS_IDLE_TIMEOUT 2000
+enum iwl_ini_cfg_state {
+ IWL_INI_CFG_STATE_NOT_LOADED,
+ IWL_INI_CFG_STATE_LOADED,
+ IWL_INI_CFG_STATE_CORRUPTED,
+};
/* Max time to wait for nmi interrupt */
#define IWL_TRANS_NMI_TIMEOUT (HZ / 4)
@@ -733,8 +704,8 @@ struct iwl_self_init_dram {
* @umac_error_event_table: addr of umac error table
* @error_event_table_tlv_status: bitmap that indicates what error table
* pointers was recevied via TLV. uses enum &iwl_error_event_table_status
- * @external_ini_loaded: indicates if an external ini cfg was given
- * @ini_valid: indicates if debug ini mode is on
+ * @internal_ini_cfg: internal debug cfg state. Uses &enum iwl_ini_cfg_state
+ * @external_ini_cfg: external debug cfg state. Uses &enum iwl_ini_cfg_state
* @num_blocks: number of blocks in fw_mon
* @fw_mon: address of the buffers for firmware monitor
* @hw_error: equals true if hw error interrupt was received from the FW
@@ -752,14 +723,11 @@ struct iwl_trans_debug {
u32 umac_error_event_table;
unsigned int error_event_table_tlv_status;
- bool external_ini_loaded;
- bool ini_valid;
-
- struct iwl_apply_point_data apply_points[IWL_FW_INI_APPLY_NUM];
- struct iwl_apply_point_data apply_points_ext[IWL_FW_INI_APPLY_NUM];
+ enum iwl_ini_cfg_state internal_ini_cfg;
+ enum iwl_ini_cfg_state external_ini_cfg;
int num_blocks;
- struct iwl_dram_data fw_mon[IWL_FW_INI_APPLY_NUM];
+ struct iwl_dram_data fw_mon[IWL_FW_INI_ALLOCATION_NUM];
bool hw_error;
enum iwl_fw_ini_buffer_location ini_dest;
@@ -770,6 +738,7 @@ struct iwl_trans_debug {
*
* @ops - pointer to iwl_trans_ops
* @op_mode - pointer to the op_mode
+ * @trans_cfg: the trans-specific configuration part
* @cfg - pointer to the configuration
* @drv - pointer to iwl_drv
* @status: a bit-mask of transport status flags
@@ -797,13 +766,11 @@ struct iwl_trans_debug {
* @system_pm_mode: the system-wide power management mode in use.
* This mode is set dynamically, depending on the WoWLAN values
* configured from the userspace at runtime.
- * @runtime_pm_mode: the runtime power management mode in use. This
- * mode is set during the initialization phase and is not
- * supposed to change during runtime.
*/
struct iwl_trans {
const struct iwl_trans_ops *ops;
struct iwl_op_mode *op_mode;
+ const struct iwl_cfg_trans_params *trans_cfg;
const struct iwl_cfg *cfg;
struct iwl_drv *drv;
enum iwl_trans_state state;
@@ -844,8 +811,6 @@ struct iwl_trans {
struct iwl_self_init_dram init_dram;
enum iwl_plat_pm_mode system_pm_mode;
- enum iwl_plat_pm_mode runtime_pm_mode;
- bool suspending;
/* pointer to trans specific struct */
/*Ensure that this pointer will always be aligned to sizeof pointer */
@@ -864,16 +829,11 @@ static inline void iwl_trans_configure(struct iwl_trans *trans,
WARN_ON(iwl_cmd_groups_verify_sorted(trans_cfg));
}
-static inline int _iwl_trans_start_hw(struct iwl_trans *trans, bool low_power)
+static inline int iwl_trans_start_hw(struct iwl_trans *trans)
{
might_sleep();
- return trans->ops->start_hw(trans, low_power);
-}
-
-static inline int iwl_trans_start_hw(struct iwl_trans *trans)
-{
- return trans->ops->start_hw(trans, true);
+ return trans->ops->start_hw(trans);
}
static inline void iwl_trans_op_mode_leave(struct iwl_trans *trans)
@@ -909,27 +869,23 @@ static inline int iwl_trans_start_fw(struct iwl_trans *trans,
return trans->ops->start_fw(trans, fw, run_in_rfkill);
}
-static inline void _iwl_trans_stop_device(struct iwl_trans *trans,
- bool low_power)
+static inline void iwl_trans_stop_device(struct iwl_trans *trans)
{
might_sleep();
- trans->ops->stop_device(trans, low_power);
+ trans->ops->stop_device(trans);
trans->state = IWL_TRANS_NO_FW;
}
-static inline void iwl_trans_stop_device(struct iwl_trans *trans)
-{
- _iwl_trans_stop_device(trans, true);
-}
-
-static inline void iwl_trans_d3_suspend(struct iwl_trans *trans, bool test,
- bool reset)
+static inline int iwl_trans_d3_suspend(struct iwl_trans *trans, bool test,
+ bool reset)
{
might_sleep();
- if (trans->ops->d3_suspend)
- trans->ops->d3_suspend(trans, test, reset);
+ if (!trans->ops->d3_suspend)
+ return 0;
+
+ return trans->ops->d3_suspend(trans, test, reset);
}
static inline int iwl_trans_d3_resume(struct iwl_trans *trans,
@@ -1004,6 +960,17 @@ static inline void iwl_trans_reclaim(struct iwl_trans *trans, int queue,
trans->ops->reclaim(trans, queue, ssn, skbs);
}
+static inline void iwl_trans_set_q_ptrs(struct iwl_trans *trans, int queue,
+ int ptr)
+{
+ if (WARN_ON_ONCE(trans->state != IWL_TRANS_FW_ALIVE)) {
+ IWL_ERR(trans, "%s bad state = %d\n", __func__, trans->state);
+ return;
+ }
+
+ trans->ops->set_q_ptrs(trans, queue, ptr);
+}
+
static inline void iwl_trans_txq_disable(struct iwl_trans *trans, int queue,
bool configure_scd)
{
@@ -1261,16 +1228,19 @@ static inline void iwl_trans_sync_nmi(struct iwl_trans *trans)
trans->ops->sync_nmi(trans);
}
+static inline bool iwl_trans_dbg_ini_valid(struct iwl_trans *trans)
+{
+ return trans->dbg.internal_ini_cfg != IWL_INI_CFG_STATE_NOT_LOADED ||
+ trans->dbg.external_ini_cfg != IWL_INI_CFG_STATE_NOT_LOADED;
+}
+
/*****************************************************
* transport helper functions
*****************************************************/
struct iwl_trans *iwl_trans_alloc(unsigned int priv_size,
struct device *dev,
- const struct iwl_cfg *cfg,
const struct iwl_trans_ops *ops);
void iwl_trans_free(struct iwl_trans *trans);
-void iwl_trans_ref(struct iwl_trans *trans);
-void iwl_trans_unref(struct iwl_trans *trans);
/*****************************************************
* driver (transport) register/unregister functions
diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/constants.h b/drivers/net/wireless/intel/iwlwifi/mvm/constants.h
index 915b172da57a..60aff2ecec12 100644
--- a/drivers/net/wireless/intel/iwlwifi/mvm/constants.h
+++ b/drivers/net/wireless/intel/iwlwifi/mvm/constants.h
@@ -153,5 +153,6 @@
#define IWL_MVM_FTM_INITIATOR_DYNACK true
#define IWL_MVM_D3_DEBUG false
#define IWL_MVM_USE_TWT false
+#define IWL_MVM_AMPDU_CONSEC_DROPS_DELBA 10
#endif /* __MVM_CONSTANTS_H */
diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/d3.c b/drivers/net/wireless/intel/iwlwifi/mvm/d3.c
index cec40855a641..86c2c587e755 100644
--- a/drivers/net/wireless/intel/iwlwifi/mvm/d3.c
+++ b/drivers/net/wireless/intel/iwlwifi/mvm/d3.c
@@ -735,40 +735,16 @@ iwl_mvm_get_wowlan_config(struct iwl_mvm *mvm,
return 0;
}
-static void
-iwl_mvm_iter_d0i3_ap_keys(struct iwl_mvm *mvm,
- struct ieee80211_vif *vif,
- void (*iter)(struct ieee80211_hw *hw,
- struct ieee80211_vif *vif,
- struct ieee80211_sta *sta,
- struct ieee80211_key_conf *key,
- void *data),
- void *data)
-{
- struct ieee80211_sta *ap_sta;
-
- rcu_read_lock();
-
- ap_sta = rcu_dereference(mvm->fw_id_to_mac_id[mvm->d0i3_ap_sta_id]);
- if (IS_ERR_OR_NULL(ap_sta))
- goto out;
-
- ieee80211_iter_keys_rcu(mvm->hw, vif, iter, data);
-out:
- rcu_read_unlock();
-}
-
-int iwl_mvm_wowlan_config_key_params(struct iwl_mvm *mvm,
- struct ieee80211_vif *vif,
- bool d0i3,
- u32 cmd_flags)
+static int iwl_mvm_wowlan_config_key_params(struct iwl_mvm *mvm,
+ struct ieee80211_vif *vif,
+ u32 cmd_flags)
{
struct iwl_wowlan_kek_kck_material_cmd kek_kck_cmd = {};
struct iwl_wowlan_tkip_params_cmd tkip_cmd = {};
bool unified = fw_has_capa(&mvm->fw->ucode_capa,
IWL_UCODE_TLV_CAPA_CNSLDTD_D3_D0_IMG);
struct wowlan_key_data key_data = {
- .configure_keys = !d0i3 && !unified,
+ .configure_keys = !unified,
.use_rsc_tsc = false,
.tkip = &tkip_cmd,
.use_tkip = false,
@@ -784,25 +760,16 @@ int iwl_mvm_wowlan_config_key_params(struct iwl_mvm *mvm,
* if we have to configure keys, call ieee80211_iter_keys(),
* as we need non-atomic context in order to take the
* required locks.
- * for the d0i3 we can't use ieee80211_iter_keys(), as
- * taking (almost) any mutex might result in deadlock.
*/
- if (!d0i3) {
- /*
- * Note that currently we don't propagate cmd_flags
- * to the iterator. In case of key_data.configure_keys,
- * all the configured commands are SYNC, and
- * iwl_mvm_wowlan_program_keys() will take care of
- * locking/unlocking mvm->mutex.
- */
- ieee80211_iter_keys(mvm->hw, vif,
- iwl_mvm_wowlan_program_keys,
- &key_data);
- } else {
- iwl_mvm_iter_d0i3_ap_keys(mvm, vif,
- iwl_mvm_wowlan_program_keys,
- &key_data);
- }
+ /*
+ * Note that currently we don't propagate cmd_flags
+ * to the iterator. In case of key_data.configure_keys,
+ * all the configured commands are SYNC, and
+ * iwl_mvm_wowlan_program_keys() will take care of
+ * locking/unlocking mvm->mutex.
+ */
+ ieee80211_iter_keys(mvm->hw, vif, iwl_mvm_wowlan_program_keys,
+ &key_data);
if (key_data.error) {
ret = -EIO;
@@ -830,7 +797,7 @@ int iwl_mvm_wowlan_config_key_params(struct iwl_mvm *mvm,
}
/* configure rekey data only if offloaded rekey is supported (d3) */
- if (mvmvif->rekey_data.valid && !d0i3) {
+ if (mvmvif->rekey_data.valid) {
memset(&kek_kck_cmd, 0, sizeof(kek_kck_cmd));
memcpy(kek_kck_cmd.kck, mvmvif->rekey_data.kck,
NL80211_KCK_LEN);
@@ -864,6 +831,8 @@ iwl_mvm_wowlan_config(struct iwl_mvm *mvm,
bool unified_image = fw_has_capa(&mvm->fw->ucode_capa,
IWL_UCODE_TLV_CAPA_CNSLDTD_D3_D0_IMG);
+ mvm->offload_tid = wowlan_config_cmd->offloading_tid;
+
if (!unified_image) {
ret = iwl_mvm_switch_to_d3(mvm);
if (ret)
@@ -881,8 +850,7 @@ iwl_mvm_wowlan_config(struct iwl_mvm *mvm,
* that isn't really a problem though.
*/
mutex_unlock(&mvm->mutex);
- ret = iwl_mvm_wowlan_config_key_params(mvm, vif, false,
- CMD_ASYNC);
+ ret = iwl_mvm_wowlan_config_key_params(mvm, vif, CMD_ASYNC);
mutex_lock(&mvm->mutex);
if (ret)
return ret;
@@ -936,6 +904,8 @@ iwl_mvm_netdetect_config(struct iwl_mvm *mvm,
wowlan_config_cmd.wakeup_filter |=
cpu_to_le32(IWL_WOWLAN_WAKEUP_RF_KILL_DEASSERT);
+ wowlan_config_cmd.sta_id = mvm->aux_sta.sta_id;
+
ret = iwl_mvm_send_cmd_pdu(mvm, WOWLAN_CONFIGURATION, 0,
sizeof(wowlan_config_cmd),
&wowlan_config_cmd);
@@ -1043,6 +1013,8 @@ static int __iwl_mvm_suspend(struct ieee80211_hw *hw,
} else {
struct iwl_wowlan_config_cmd wowlan_config_cmd = {};
+ wowlan_config_cmd.sta_id = mvmvif->ap_sta_id;
+
ap_sta = rcu_dereference_protected(
mvm->fw_id_to_mac_id[mvmvif->ap_sta_id],
lockdep_is_held(&mvm->mutex));
@@ -1082,8 +1054,8 @@ static int __iwl_mvm_suspend(struct ieee80211_hw *hw,
* recording before entering D3. In later devices the FW stops the
* recording automatically.
*/
- if (mvm->trans->cfg->device_family < IWL_DEVICE_FAMILY_9000)
- iwl_fw_dbg_stop_recording(mvm->trans, NULL);
+ if (mvm->trans->trans_cfg->device_family < IWL_DEVICE_FAMILY_9000)
+ iwl_fw_dbg_stop_restart_recording(&mvm->fwrt, NULL, true);
/* must be last -- this switches firmware state */
ret = iwl_mvm_send_cmd(mvm, &d3_cfg_cmd);
@@ -1100,13 +1072,12 @@ static int __iwl_mvm_suspend(struct ieee80211_hw *hw,
clear_bit(IWL_MVM_STATUS_IN_HW_RESTART, &mvm->status);
- iwl_trans_d3_suspend(mvm->trans, test, !unified_image);
+ ret = iwl_trans_d3_suspend(mvm->trans, test, !unified_image);
out:
if (ret < 0) {
iwl_mvm_free_nd(mvm);
if (!unified_image) {
- iwl_mvm_ref(mvm, IWL_MVM_REF_UCODE_DOWN);
if (mvm->fw_restart > 0) {
mvm->fw_restart--;
ieee80211_restart_hw(mvm->hw);
@@ -1119,37 +1090,12 @@ static int __iwl_mvm_suspend(struct ieee80211_hw *hw,
return ret;
}
-static int iwl_mvm_enter_d0i3_sync(struct iwl_mvm *mvm)
-{
- struct iwl_notification_wait wait_d3;
- static const u16 d3_notif[] = { D3_CONFIG_CMD };
- int ret;
-
- iwl_init_notification_wait(&mvm->notif_wait, &wait_d3,
- d3_notif, ARRAY_SIZE(d3_notif),
- NULL, NULL);
-
- ret = iwl_mvm_enter_d0i3(mvm->hw->priv);
- if (ret)
- goto remove_notif;
-
- ret = iwl_wait_notification(&mvm->notif_wait, &wait_d3, HZ);
- WARN_ON_ONCE(ret);
- return ret;
-
-remove_notif:
- iwl_remove_notification(&mvm->notif_wait, &wait_d3);
- return ret;
-}
-
int iwl_mvm_suspend(struct ieee80211_hw *hw, struct cfg80211_wowlan *wowlan)
{
struct iwl_mvm *mvm = IWL_MAC80211_GET_MVM(hw);
struct iwl_trans *trans = mvm->trans;
int ret;
- /* make sure the d0i3 exit work is not pending */
- flush_work(&mvm->d0i3_exit_work);
iwl_mvm_pause_tcm(mvm, true);
iwl_fw_runtime_suspend(&mvm->fwrt);
@@ -1158,25 +1104,6 @@ int iwl_mvm_suspend(struct ieee80211_hw *hw, struct cfg80211_wowlan *wowlan)
if (ret)
return ret;
- if (wowlan->any) {
- trans->system_pm_mode = IWL_PLAT_PM_MODE_D0I3;
-
- if (iwl_mvm_enter_d0i3_on_suspend(mvm)) {
- ret = iwl_mvm_enter_d0i3_sync(mvm);
-
- if (ret)
- return ret;
- }
-
- mutex_lock(&mvm->d0i3_suspend_mutex);
- __set_bit(D0I3_DEFER_WAKEUP, &mvm->d0i3_suspend_flags);
- mutex_unlock(&mvm->d0i3_suspend_mutex);
-
- iwl_trans_d3_suspend(trans, false, false);
-
- return 0;
- }
-
trans->system_pm_mode = IWL_PLAT_PM_MODE_D3;
return __iwl_mvm_suspend(hw, wowlan, false);
@@ -1735,6 +1662,13 @@ static bool iwl_mvm_query_wakeup_reasons(struct iwl_mvm *mvm,
mvm_ap_sta->tid_data[i].seq_number = seq;
}
+ if (mvm->trans->trans_cfg->device_family >= IWL_DEVICE_FAMILY_22000) {
+ i = mvm->offload_tid;
+ iwl_trans_set_q_ptrs(mvm->trans,
+ mvm_ap_sta->tid_data[i].txq_id,
+ mvm_ap_sta->tid_data[i].seq_number >> 4);
+ }
+
/* now we have all the data we need, unlock to avoid mac80211 issues */
mutex_unlock(&mvm->mutex);
@@ -1752,30 +1686,6 @@ out_unlock:
return false;
}
-void iwl_mvm_d0i3_update_keys(struct iwl_mvm *mvm,
- struct ieee80211_vif *vif,
- struct iwl_wowlan_status *status)
-{
- struct iwl_mvm_d3_gtk_iter_data gtkdata = {
- .mvm = mvm,
- .status = status,
- };
-
- /*
- * rekey handling requires taking locks that can't be taken now.
- * however, d0i3 doesn't offload rekey, so we're fine.
- */
- if (WARN_ON_ONCE(status->num_of_gtk_rekeys))
- return;
-
- /* find last GTK that we used initially, if any */
- gtkdata.find_phase = true;
- iwl_mvm_iter_d0i3_ap_keys(mvm, vif, iwl_mvm_d3_update_keys, &gtkdata);
-
- gtkdata.find_phase = false;
- iwl_mvm_iter_d0i3_ap_keys(mvm, vif, iwl_mvm_d3_update_keys, &gtkdata);
-}
-
#define ND_QUERY_BUF_LEN (sizeof(struct iwl_scan_offload_profile_match) * \
IWL_SCAN_MAX_PROFILES)
@@ -2024,15 +1934,6 @@ static int __iwl_mvm_resume(struct iwl_mvm *mvm, bool test)
if (IS_ERR_OR_NULL(vif))
goto err;
- ret = iwl_trans_d3_resume(mvm->trans, &d3_status, test, !unified_image);
- if (ret)
- goto err;
-
- if (d3_status != IWL_D3_STATUS_ALIVE) {
- IWL_INFO(mvm, "Device was reset during suspend\n");
- goto err;
- }
-
iwl_fw_dbg_read_d3_debug_data(&mvm->fwrt);
if (iwl_mvm_check_rt_status(mvm, vif)) {
@@ -2044,6 +1945,15 @@ static int __iwl_mvm_resume(struct iwl_mvm *mvm, bool test)
goto err;
}
+ ret = iwl_trans_d3_resume(mvm->trans, &d3_status, test, !unified_image);
+ if (ret)
+ goto err;
+
+ if (d3_status != IWL_D3_STATUS_ALIVE) {
+ IWL_INFO(mvm, "Device was reset during suspend\n");
+ goto err;
+ }
+
if (d0i3_first) {
ret = iwl_mvm_send_cmd_pdu(mvm, D0I3_END_CMD, 0, 0, NULL);
if (ret < 0) {
@@ -2059,6 +1969,9 @@ static int __iwl_mvm_resume(struct iwl_mvm *mvm, bool test)
*/
iwl_mvm_update_changed_regdom(mvm);
+ /* Re-configure PPAG settings */
+ iwl_mvm_ppag_send_cmd(mvm);
+
if (!unified_image)
/* Re-configure default SAR profile */
iwl_mvm_sar_select_profile(mvm, 1, 1);
@@ -2115,14 +2028,6 @@ out:
* 2. We are using a unified image but had an error while exiting D3
*/
set_bit(IWL_MVM_STATUS_HW_RESTART_REQUESTED, &mvm->status);
- /*
- * When switching images we return 1, which causes mac80211
- * to do a reconfig with IEEE80211_RECONFIG_TYPE_RESTART.
- * This type of reconfig calls iwl_mvm_restart_complete(),
- * where we unref the IWL_MVM_REF_UCODE_DOWN, so we need
- * to take the reference here.
- */
- iwl_mvm_ref(mvm, IWL_MVM_REF_UCODE_DOWN);
return 1;
}
@@ -2134,53 +2039,12 @@ static int iwl_mvm_resume_d3(struct iwl_mvm *mvm)
return __iwl_mvm_resume(mvm, false);
}
-static int iwl_mvm_resume_d0i3(struct iwl_mvm *mvm)
-{
- bool exit_now;
- enum iwl_d3_status d3_status;
- struct iwl_trans *trans = mvm->trans;
-
- iwl_trans_d3_resume(trans, &d3_status, false, false);
-
- /*
- * make sure to clear D0I3_DEFER_WAKEUP before
- * calling iwl_trans_resume(), which might wait
- * for d0i3 exit completion.
- */
- mutex_lock(&mvm->d0i3_suspend_mutex);
- __clear_bit(D0I3_DEFER_WAKEUP, &mvm->d0i3_suspend_flags);
- exit_now = __test_and_clear_bit(D0I3_PENDING_WAKEUP,
- &mvm->d0i3_suspend_flags);
- mutex_unlock(&mvm->d0i3_suspend_mutex);
- if (exit_now) {
- IWL_DEBUG_RPM(mvm, "Run deferred d0i3 exit\n");
- _iwl_mvm_exit_d0i3(mvm);
- }
-
- iwl_trans_resume(trans);
-
- if (iwl_mvm_enter_d0i3_on_suspend(mvm)) {
- int ret = iwl_mvm_exit_d0i3(mvm->hw->priv);
-
- if (ret)
- return ret;
- /*
- * d0i3 exit will be deferred until reconfig_complete.
- * make sure there we are out of d0i3.
- */
- }
- return 0;
-}
-
int iwl_mvm_resume(struct ieee80211_hw *hw)
{
struct iwl_mvm *mvm = IWL_MAC80211_GET_MVM(hw);
int ret;
- if (mvm->trans->system_pm_mode == IWL_PLAT_PM_MODE_D0I3)
- ret = iwl_mvm_resume_d0i3(mvm);
- else
- ret = iwl_mvm_resume_d3(mvm);
+ ret = iwl_mvm_resume_d3(mvm);
mvm->trans->system_pm_mode = IWL_PLAT_PM_MODE_DISABLED;
diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/debugfs.c b/drivers/net/wireless/intel/iwlwifi/mvm/debugfs.c
index 0c188a82cfc1..ad18c2f1a806 100644
--- a/drivers/net/wireless/intel/iwlwifi/mvm/debugfs.c
+++ b/drivers/net/wireless/intel/iwlwifi/mvm/debugfs.c
@@ -1056,19 +1056,11 @@ static ssize_t iwl_dbgfs_fw_restart_write(struct iwl_mvm *mvm, char *buf,
static ssize_t iwl_dbgfs_fw_nmi_write(struct iwl_mvm *mvm, char *buf,
size_t count, loff_t *ppos)
{
- int ret;
-
if (!iwl_mvm_firmware_running(mvm))
return -EIO;
- ret = iwl_mvm_ref_sync(mvm, IWL_MVM_REF_NMI);
- if (ret)
- return ret;
-
iwl_force_nmi(mvm->trans);
- iwl_mvm_unref(mvm, IWL_MVM_REF_NMI);
-
return count;
}
@@ -1181,8 +1173,8 @@ static ssize_t iwl_dbgfs_inject_packet_write(struct iwl_mvm *mvm,
struct iwl_rx_mpdu_desc *desc;
int bin_len = count / 2;
int ret = -EINVAL;
- size_t mpdu_cmd_hdr_size =
- (mvm->trans->cfg->device_family >= IWL_DEVICE_FAMILY_22560) ?
+ size_t mpdu_cmd_hdr_size = (mvm->trans->trans_cfg->device_family >=
+ IWL_DEVICE_FAMILY_22560) ?
sizeof(struct iwl_rx_mpdu_desc) :
IWL_RX_DESC_SIZE_V1;
@@ -1190,7 +1182,7 @@ static ssize_t iwl_dbgfs_inject_packet_write(struct iwl_mvm *mvm,
return -EIO;
/* supporting only 9000 descriptor */
- if (!mvm->trans->cfg->mq_rx_supported)
+ if (!mvm->trans->trans_cfg->mq_rx_supported)
return -ENOTSUPP;
rxb._page = alloc_pages(GFP_ATOMIC, 0);
@@ -1380,19 +1372,12 @@ static ssize_t iwl_dbgfs_fw_dbg_collect_write(struct iwl_mvm *mvm,
char *buf, size_t count,
loff_t *ppos)
{
- int ret;
-
- ret = iwl_mvm_ref_sync(mvm, IWL_MVM_REF_PRPH_WRITE);
- if (ret)
- return ret;
if (count == 0)
return 0;
iwl_fw_dbg_collect(&mvm->fwrt, FW_DBG_TRIGGER_USER, buf,
(count - 1), NULL);
- iwl_mvm_unref(mvm, IWL_MVM_REF_PRPH_WRITE);
-
return count;
}
@@ -1579,87 +1564,6 @@ static ssize_t iwl_dbgfs_bcast_filters_macs_write(struct iwl_mvm *mvm,
}
#endif
-#define PRINT_MVM_REF(ref) do { \
- if (mvm->refs[ref]) \
- pos += scnprintf(buf + pos, bufsz - pos, \
- "\t(0x%lx): %d %s\n", \
- BIT(ref), mvm->refs[ref], #ref); \
-} while (0)
-
-static ssize_t iwl_dbgfs_d0i3_refs_read(struct file *file,
- char __user *user_buf,
- size_t count, loff_t *ppos)
-{
- struct iwl_mvm *mvm = file->private_data;
- int i, pos = 0;
- char buf[256];
- const size_t bufsz = sizeof(buf);
- u32 refs = 0;
-
- for (i = 0; i < IWL_MVM_REF_COUNT; i++)
- if (mvm->refs[i])
- refs |= BIT(i);
-
- pos += scnprintf(buf + pos, bufsz - pos, "taken mvm refs: 0x%x\n",
- refs);
-
- PRINT_MVM_REF(IWL_MVM_REF_UCODE_DOWN);
- PRINT_MVM_REF(IWL_MVM_REF_SCAN);
- PRINT_MVM_REF(IWL_MVM_REF_ROC);
- PRINT_MVM_REF(IWL_MVM_REF_ROC_AUX);
- PRINT_MVM_REF(IWL_MVM_REF_P2P_CLIENT);
- PRINT_MVM_REF(IWL_MVM_REF_AP_IBSS);
- PRINT_MVM_REF(IWL_MVM_REF_USER);
- PRINT_MVM_REF(IWL_MVM_REF_TX);
- PRINT_MVM_REF(IWL_MVM_REF_TX_AGG);
- PRINT_MVM_REF(IWL_MVM_REF_ADD_IF);
- PRINT_MVM_REF(IWL_MVM_REF_START_AP);
- PRINT_MVM_REF(IWL_MVM_REF_BSS_CHANGED);
- PRINT_MVM_REF(IWL_MVM_REF_PREPARE_TX);
- PRINT_MVM_REF(IWL_MVM_REF_PROTECT_TDLS);
- PRINT_MVM_REF(IWL_MVM_REF_CHECK_CTKILL);
- PRINT_MVM_REF(IWL_MVM_REF_PRPH_READ);
- PRINT_MVM_REF(IWL_MVM_REF_PRPH_WRITE);
- PRINT_MVM_REF(IWL_MVM_REF_NMI);
- 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);
- PRINT_MVM_REF(IWL_MVM_REF_INIT_UCODE);
- PRINT_MVM_REF(IWL_MVM_REF_SENDING_CMD);
- PRINT_MVM_REF(IWL_MVM_REF_RX);
-
- return simple_read_from_buffer(user_buf, count, ppos, buf, pos);
-}
-
-static ssize_t iwl_dbgfs_d0i3_refs_write(struct iwl_mvm *mvm, char *buf,
- size_t count, loff_t *ppos)
-{
- unsigned long value;
- int ret;
- bool taken;
-
- ret = kstrtoul(buf, 10, &value);
- if (ret < 0)
- return ret;
-
- mutex_lock(&mvm->mutex);
-
- taken = mvm->refs[IWL_MVM_REF_USER];
- if (value == 1 && !taken)
- iwl_mvm_ref(mvm, IWL_MVM_REF_USER);
- else if (value == 0 && taken)
- iwl_mvm_unref(mvm, IWL_MVM_REF_USER);
- else
- ret = -EINVAL;
-
- mutex_unlock(&mvm->mutex);
-
- if (ret < 0)
- return ret;
- return count;
-}
-
#define MVM_DEBUGFS_WRITE_FILE_OPS(name, bufsz) \
_MVM_DEBUGFS_WRITE_FILE_OPS(name, bufsz, struct iwl_mvm)
#define MVM_DEBUGFS_READ_WRITE_FILE_OPS(name, bufsz) \
@@ -1692,21 +1596,14 @@ iwl_dbgfs_prph_reg_read(struct file *file,
int pos = 0;
char buf[32];
const size_t bufsz = sizeof(buf);
- int ret;
if (!mvm->dbgfs_prph_reg_addr)
return -EINVAL;
- ret = iwl_mvm_ref_sync(mvm, IWL_MVM_REF_PRPH_READ);
- if (ret)
- return ret;
-
pos += scnprintf(buf + pos, bufsz - pos, "Reg 0x%x: (0x%x)\n",
mvm->dbgfs_prph_reg_addr,
iwl_read_prph(mvm->trans, mvm->dbgfs_prph_reg_addr));
- iwl_mvm_unref(mvm, IWL_MVM_REF_PRPH_READ);
-
return simple_read_from_buffer(user_buf, count, ppos, buf, pos);
}
@@ -1716,7 +1613,6 @@ iwl_dbgfs_prph_reg_write(struct iwl_mvm *mvm, char *buf,
{
u8 args;
u32 value;
- int ret;
args = sscanf(buf, "%i %i", &mvm->dbgfs_prph_reg_addr, &value);
/* if we only want to set the reg address - nothing more to do */
@@ -1727,13 +1623,8 @@ iwl_dbgfs_prph_reg_write(struct iwl_mvm *mvm, char *buf,
if (args != 2)
return -EINVAL;
- ret = iwl_mvm_ref_sync(mvm, IWL_MVM_REF_PRPH_WRITE);
- if (ret)
- return ret;
-
iwl_write_prph(mvm->trans, mvm->dbgfs_prph_reg_addr, value);
- iwl_mvm_unref(mvm, IWL_MVM_REF_PRPH_WRITE);
out:
return count;
}
@@ -1867,6 +1758,38 @@ iwl_dbgfs_uapsd_noagg_bssids_read(struct file *file, char __user *user_buf,
return simple_read_from_buffer(user_buf, count, ppos, buf, pos);
}
+static ssize_t
+iwl_dbgfs_ltr_config_write(struct iwl_mvm *mvm,
+ char *buf, size_t count, loff_t *ppos)
+{
+ int ret;
+ struct iwl_ltr_config_cmd ltr_config = {0};
+
+ if (!iwl_mvm_firmware_running(mvm))
+ return -EIO;
+
+ if (sscanf(buf, "%x,%x,%x,%x,%x,%x,%x",
+ &ltr_config.flags,
+ &ltr_config.static_long,
+ &ltr_config.static_short,
+ &ltr_config.ltr_cfg_values[0],
+ &ltr_config.ltr_cfg_values[1],
+ &ltr_config.ltr_cfg_values[2],
+ &ltr_config.ltr_cfg_values[3]) != 7) {
+ return -EINVAL;
+ }
+
+ mutex_lock(&mvm->mutex);
+ ret = iwl_mvm_send_cmd_pdu(mvm, LTR_CONFIG, 0, sizeof(ltr_config),
+ &ltr_config);
+ mutex_unlock(&mvm->mutex);
+
+ if (ret)
+ IWL_ERR(mvm, "failed to send ltr configuration cmd\n");
+
+ return ret ?: count;
+}
+
MVM_DEBUGFS_READ_WRITE_FILE_OPS(prph_reg, 64);
/* Device wide debugfs entries */
@@ -1892,7 +1815,6 @@ MVM_DEBUGFS_WRITE_FILE_OPS(fw_nmi, 10);
MVM_DEBUGFS_WRITE_FILE_OPS(bt_tx_prio, 10);
MVM_DEBUGFS_WRITE_FILE_OPS(bt_force_ant, 10);
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, 64);
MVM_DEBUGFS_WRITE_FILE_OPS(indirection_tbl,
@@ -1916,6 +1838,8 @@ MVM_DEBUGFS_READ_WRITE_STA_FILE_OPS(amsdu_len, 16);
MVM_DEBUGFS_READ_WRITE_FILE_OPS(he_sniffer_params, 32);
+MVM_DEBUGFS_WRITE_FILE_OPS(ltr_config, 512);
+
static ssize_t iwl_dbgfs_mem_read(struct file *file, char __user *user_buf,
size_t count, loff_t *ppos)
{
@@ -2091,7 +2015,6 @@ void iwl_mvm_dbgfs_register(struct iwl_mvm *mvm, struct dentry *dbgfs_dir)
MVM_DEBUGFS_ADD_FILE(bt_force_ant, mvm->debugfs_dir, 0200);
MVM_DEBUGFS_ADD_FILE(scan_ant_rxchain, mvm->debugfs_dir, 0600);
MVM_DEBUGFS_ADD_FILE(prph_reg, mvm->debugfs_dir, 0600);
- MVM_DEBUGFS_ADD_FILE(d0i3_refs, mvm->debugfs_dir, 0600);
MVM_DEBUGFS_ADD_FILE(fw_dbg_conf, mvm->debugfs_dir, 0600);
MVM_DEBUGFS_ADD_FILE(fw_dbg_collect, mvm->debugfs_dir, 0200);
MVM_DEBUGFS_ADD_FILE(send_echo_cmd, mvm->debugfs_dir, 0200);
@@ -2104,6 +2027,9 @@ void iwl_mvm_dbgfs_register(struct iwl_mvm *mvm, struct dentry *dbgfs_dir)
#endif
MVM_DEBUGFS_ADD_FILE(he_sniffer_params, mvm->debugfs_dir, 0600);
+ if (fw_has_capa(&mvm->fw->ucode_capa, IWL_UCODE_TLV_CAPA_SET_LTR_GEN2))
+ MVM_DEBUGFS_ADD_FILE(ltr_config, mvm->debugfs_dir, 0200);
+
debugfs_create_bool("enable_scan_iteration_notif", 0600,
mvm->debugfs_dir, &mvm->scan_iter_notif_enabled);
debugfs_create_bool("drop_bcn_ap_mode", 0600, mvm->debugfs_dir,
diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/fw.c b/drivers/net/wireless/intel/iwlwifi/mvm/fw.c
index 5de54d1559dd..d9eb2b286438 100644
--- a/drivers/net/wireless/intel/iwlwifi/mvm/fw.c
+++ b/drivers/net/wireless/intel/iwlwifi/mvm/fw.c
@@ -357,13 +357,14 @@ static int iwl_mvm_load_ucode_wait_alive(struct iwl_mvm *mvm,
iwl_fw_dbg_error_collect(&mvm->fwrt,
FW_DBG_TRIGGER_ALIVE_TIMEOUT);
- if (trans->cfg->device_family >= IWL_DEVICE_FAMILY_22000)
+ if (trans->trans_cfg->device_family >= IWL_DEVICE_FAMILY_22000)
IWL_ERR(mvm,
"SecBoot CPU1 Status: 0x%x, CPU2 Status: 0x%x\n",
iwl_read_umac_prph(trans, UMAG_SB_CPU_1_STATUS),
iwl_read_umac_prph(trans,
UMAG_SB_CPU_2_STATUS));
- else if (trans->cfg->device_family >= IWL_DEVICE_FAMILY_8000)
+ else if (trans->trans_cfg->device_family >=
+ IWL_DEVICE_FAMILY_8000)
IWL_ERR(mvm,
"SecBoot CPU1 Status: 0x%x, CPU2 Status: 0x%x\n",
iwl_read_prph(trans, SB_CPU_1_STATUS),
@@ -419,6 +420,9 @@ static int iwl_run_unified_mvm_ucode(struct iwl_mvm *mvm, bool read_nvm)
};
int ret;
+ if (mvm->trans->cfg->tx_with_siso_diversity)
+ init_cfg.init_flags |= cpu_to_le32(BIT(IWL_INIT_PHY));
+
lockdep_assert_held(&mvm->mutex);
mvm->rfkill_safe_init_done = false;
@@ -430,7 +434,7 @@ static int iwl_run_unified_mvm_ucode(struct iwl_mvm *mvm, bool read_nvm)
iwl_wait_init_complete,
NULL);
- iwl_fw_dbg_apply_point(&mvm->fwrt, IWL_FW_INI_APPLY_EARLY);
+ iwl_dbg_tlv_time_point(&mvm->fwrt, IWL_FW_INI_TIME_POINT_EARLY, NULL);
/* Will also start the device */
ret = iwl_mvm_load_ucode_wait_alive(mvm, IWL_UCODE_REGULAR);
@@ -438,7 +442,8 @@ static int iwl_run_unified_mvm_ucode(struct iwl_mvm *mvm, bool read_nvm)
IWL_ERR(mvm, "Failed to start RT ucode: %d\n", ret);
goto error;
}
- iwl_fw_dbg_apply_point(&mvm->fwrt, IWL_FW_INI_APPLY_AFTER_ALIVE);
+ iwl_dbg_tlv_time_point(&mvm->fwrt, IWL_FW_INI_TIME_POINT_AFTER_ALIVE,
+ NULL);
/* Send init config command to mark that we are sending NVM access
* commands
@@ -557,7 +562,7 @@ int iwl_run_init_mvm_ucode(struct iwl_mvm *mvm, bool read_nvm)
goto remove_notif;
}
- if (mvm->cfg->device_family < IWL_DEVICE_FAMILY_8000) {
+ if (mvm->trans->trans_cfg->device_family < IWL_DEVICE_FAMILY_8000) {
ret = iwl_mvm_send_bt_init_conf(mvm);
if (ret)
goto remove_notif;
@@ -692,12 +697,13 @@ static int iwl_mvm_sar_get_wrds_table(struct iwl_mvm *mvm)
wifi_pkg = iwl_acpi_get_wifi_pkg(mvm->dev, data,
ACPI_WRDS_WIFI_DATA_SIZE, &tbl_rev);
- if (IS_ERR(wifi_pkg) || tbl_rev != 0) {
+ if (IS_ERR(wifi_pkg)) {
ret = PTR_ERR(wifi_pkg);
goto out_free;
}
- if (wifi_pkg->package.elements[1].type != ACPI_TYPE_INTEGER) {
+ if (wifi_pkg->package.elements[1].type != ACPI_TYPE_INTEGER ||
+ tbl_rev != 0) {
ret = -EINVAL;
goto out_free;
}
@@ -729,13 +735,14 @@ static int iwl_mvm_sar_get_ewrd_table(struct iwl_mvm *mvm)
wifi_pkg = iwl_acpi_get_wifi_pkg(mvm->dev, data,
ACPI_EWRD_WIFI_DATA_SIZE, &tbl_rev);
- if (IS_ERR(wifi_pkg) || tbl_rev != 0) {
+ if (IS_ERR(wifi_pkg)) {
ret = PTR_ERR(wifi_pkg);
goto out_free;
}
if ((wifi_pkg->package.elements[1].type != ACPI_TYPE_INTEGER) ||
- (wifi_pkg->package.elements[2].type != ACPI_TYPE_INTEGER)) {
+ (wifi_pkg->package.elements[2].type != ACPI_TYPE_INTEGER) ||
+ tbl_rev != 0) {
ret = -EINVAL;
goto out_free;
}
@@ -789,11 +796,16 @@ static int iwl_mvm_sar_get_wgds_table(struct iwl_mvm *mvm)
wifi_pkg = iwl_acpi_get_wifi_pkg(mvm->dev, data,
ACPI_WGDS_WIFI_DATA_SIZE, &tbl_rev);
- if (IS_ERR(wifi_pkg) || tbl_rev > 1) {
+ if (IS_ERR(wifi_pkg)) {
ret = PTR_ERR(wifi_pkg);
goto out_free;
}
+ if (tbl_rev != 0) {
+ ret = -EINVAL;
+ goto out_free;
+ }
+
mvm->geo_rev = tbl_rev;
for (i = 0; i < ACPI_NUM_GEO_PROFILES; i++) {
for (j = 0; j < ACPI_GEO_TABLE_SIZE; j++) {
@@ -887,13 +899,17 @@ static bool iwl_mvm_sar_geo_support(struct iwl_mvm *mvm)
* firmware versions. Unfortunately, we don't have a TLV API
* flag to rely on, so rely on the major version which is in
* the first byte of ucode_ver. This was implemented
- * initially on version 38 and then backported to 36, 29 and
- * 17.
+ * initially on version 38 and then backported to 17. It was
+ * also backported to 29, but only for 7265D devices. The
+ * intention was to have it in 36 as well, but not all 8000
+ * family got this feature enabled. The 8000 family is the
+ * only one using version 36, so skip this version entirely.
*/
return IWL_UCODE_SERIAL(mvm->fw->ucode_ver) >= 38 ||
- IWL_UCODE_SERIAL(mvm->fw->ucode_ver) == 36 ||
- IWL_UCODE_SERIAL(mvm->fw->ucode_ver) == 29 ||
- IWL_UCODE_SERIAL(mvm->fw->ucode_ver) == 17;
+ IWL_UCODE_SERIAL(mvm->fw->ucode_ver) == 17 ||
+ (IWL_UCODE_SERIAL(mvm->fw->ucode_ver) == 29 &&
+ ((mvm->trans->hw_rev & CSR_HW_REV_TYPE_MSK) ==
+ CSR_HW_REV_TYPE_7265D));
}
int iwl_mvm_get_sar_geo_profile(struct iwl_mvm *mvm)
@@ -1002,6 +1018,118 @@ static int iwl_mvm_sar_geo_init(struct iwl_mvm *mvm)
return iwl_mvm_send_cmd_pdu(mvm, cmd_wide_id, 0, sizeof(cmd), &cmd);
}
+static int iwl_mvm_get_ppag_table(struct iwl_mvm *mvm)
+{
+ union acpi_object *wifi_pkg, *data, *enabled;
+ int i, j, ret, tbl_rev;
+ int idx = 2;
+
+ mvm->ppag_table.enabled = cpu_to_le32(0);
+ data = iwl_acpi_get_object(mvm->dev, ACPI_PPAG_METHOD);
+ if (IS_ERR(data))
+ return PTR_ERR(data);
+
+ wifi_pkg = iwl_acpi_get_wifi_pkg(mvm->dev, data,
+ ACPI_PPAG_WIFI_DATA_SIZE, &tbl_rev);
+
+ if (IS_ERR(wifi_pkg)) {
+ ret = PTR_ERR(wifi_pkg);
+ goto out_free;
+ }
+
+ if (tbl_rev != 0) {
+ ret = -EINVAL;
+ goto out_free;
+ }
+
+ enabled = &wifi_pkg->package.elements[1];
+ if (enabled->type != ACPI_TYPE_INTEGER ||
+ (enabled->integer.value != 0 && enabled->integer.value != 1)) {
+ ret = -EINVAL;
+ goto out_free;
+ }
+
+ mvm->ppag_table.enabled = cpu_to_le32(enabled->integer.value);
+ if (!mvm->ppag_table.enabled) {
+ ret = 0;
+ goto out_free;
+ }
+
+ /*
+ * read, verify gain values and save them into the PPAG table.
+ * first sub-band (j=0) corresponds to Low-Band (2.4GHz), and the
+ * following sub-bands to High-Band (5GHz).
+ */
+ for (i = 0; i < ACPI_PPAG_NUM_CHAINS; i++) {
+ for (j = 0; j < ACPI_PPAG_NUM_SUB_BANDS; j++) {
+ union acpi_object *ent;
+
+ ent = &wifi_pkg->package.elements[idx++];
+ if (ent->type != ACPI_TYPE_INTEGER ||
+ (j == 0 && ent->integer.value > ACPI_PPAG_MAX_LB) ||
+ (j == 0 && ent->integer.value < ACPI_PPAG_MIN_LB) ||
+ (j != 0 && ent->integer.value > ACPI_PPAG_MAX_HB) ||
+ (j != 0 && ent->integer.value < ACPI_PPAG_MIN_HB)) {
+ mvm->ppag_table.enabled = cpu_to_le32(0);
+ ret = -EINVAL;
+ goto out_free;
+ }
+ mvm->ppag_table.gain[i][j] = ent->integer.value;
+ }
+ }
+ ret = 0;
+out_free:
+ kfree(data);
+ return ret;
+}
+
+int iwl_mvm_ppag_send_cmd(struct iwl_mvm *mvm)
+{
+ int i, j, ret;
+
+ if (!fw_has_capa(&mvm->fw->ucode_capa, IWL_UCODE_TLV_CAPA_SET_PPAG)) {
+ IWL_DEBUG_RADIO(mvm,
+ "PPAG capability not supported by FW, command not sent.\n");
+ return 0;
+ }
+
+ IWL_DEBUG_RADIO(mvm, "Sending PER_PLATFORM_ANT_GAIN_CMD\n");
+ IWL_DEBUG_RADIO(mvm, "PPAG is %s\n",
+ mvm->ppag_table.enabled ? "enabled" : "disabled");
+
+ for (i = 0; i < ACPI_PPAG_NUM_CHAINS; i++) {
+ for (j = 0; j < ACPI_PPAG_NUM_SUB_BANDS; j++) {
+ IWL_DEBUG_RADIO(mvm,
+ "PPAG table: chain[%d] band[%d]: gain = %d\n",
+ i, j, mvm->ppag_table.gain[i][j]);
+ }
+ }
+
+ ret = iwl_mvm_send_cmd_pdu(mvm, WIDE_ID(PHY_OPS_GROUP,
+ PER_PLATFORM_ANT_GAIN_CMD),
+ 0, sizeof(mvm->ppag_table),
+ &mvm->ppag_table);
+ if (ret < 0)
+ IWL_ERR(mvm, "failed to send PER_PLATFORM_ANT_GAIN_CMD (%d)\n",
+ ret);
+
+ return ret;
+}
+
+static int iwl_mvm_ppag_init(struct iwl_mvm *mvm)
+{
+ int ret;
+
+ ret = iwl_mvm_get_ppag_table(mvm);
+ if (ret < 0) {
+ IWL_DEBUG_RADIO(mvm,
+ "PPAG BIOS table invalid or unavailable. (%d)\n",
+ ret);
+ return 0;
+ }
+ return iwl_mvm_ppag_send_cmd(mvm);
+}
+
#else /* CONFIG_ACPI */
static int iwl_mvm_sar_get_wrds_table(struct iwl_mvm *mvm)
{
@@ -1033,6 +1161,16 @@ int iwl_mvm_get_sar_geo_profile(struct iwl_mvm *mvm)
{
return -ENOENT;
}
+
+int iwl_mvm_ppag_send_cmd(struct iwl_mvm *mvm)
+{
+ return -ENOENT;
+}
+
+static int iwl_mvm_ppag_init(struct iwl_mvm *mvm)
+{
+ return -ENOENT;
+}
#endif /* CONFIG_ACPI */
void iwl_mvm_send_recovery_cmd(struct iwl_mvm *mvm, u32 flags)
@@ -1140,17 +1278,13 @@ static int iwl_mvm_load_rt_fw(struct iwl_mvm *mvm)
return ret;
}
- /*
- * Stop and start the transport without entering low power
- * mode. This will save the state of other components on the
- * device that are triggered by the INIT firwmare (MFUART).
- */
- _iwl_trans_stop_device(mvm->trans, false);
- ret = _iwl_trans_start_hw(mvm->trans, false);
+ iwl_fw_dbg_stop_sync(&mvm->fwrt);
+ iwl_trans_stop_device(mvm->trans);
+ ret = iwl_trans_start_hw(mvm->trans);
if (ret)
return ret;
- iwl_fw_dbg_apply_point(&mvm->fwrt, IWL_FW_INI_APPLY_EARLY);
+ iwl_dbg_tlv_time_point(&mvm->fwrt, IWL_FW_INI_TIME_POINT_EARLY, NULL);
mvm->rfkill_safe_init_done = false;
ret = iwl_mvm_load_ucode_wait_alive(mvm, IWL_UCODE_REGULAR);
@@ -1159,7 +1293,8 @@ static int iwl_mvm_load_rt_fw(struct iwl_mvm *mvm)
mvm->rfkill_safe_init_done = true;
- iwl_fw_dbg_apply_point(&mvm->fwrt, IWL_FW_INI_APPLY_AFTER_ALIVE);
+ iwl_dbg_tlv_time_point(&mvm->fwrt, IWL_FW_INI_TIME_POINT_AFTER_ALIVE,
+ NULL);
return iwl_init_paging(&mvm->fwrt, mvm->fwrt.cur_fw_img);
}
@@ -1169,6 +1304,7 @@ int iwl_mvm_up(struct iwl_mvm *mvm)
int ret, i;
struct ieee80211_channel *chan;
struct cfg80211_chan_def chandef;
+ struct ieee80211_supported_band *sband = NULL;
lockdep_assert_held(&mvm->mutex);
@@ -1191,7 +1327,7 @@ int iwl_mvm_up(struct iwl_mvm *mvm)
if (ret)
IWL_ERR(mvm, "Failed to initialize Smart Fifo\n");
- if (!mvm->trans->dbg.ini_valid) {
+ if (!iwl_trans_dbg_ini_valid(mvm->trans)) {
mvm->fwrt.dump.conf = FW_DBG_INVALID;
/* if we have a destination, assume EARLY START */
if (mvm->fw->dbg.dest_tlv)
@@ -1219,7 +1355,7 @@ int iwl_mvm_up(struct iwl_mvm *mvm)
goto error;
/* Init RSS configuration */
- if (mvm->trans->cfg->device_family >= IWL_DEVICE_FAMILY_22000) {
+ if (mvm->trans->trans_cfg->device_family >= IWL_DEVICE_FAMILY_22000) {
ret = iwl_configure_rxq(mvm);
if (ret) {
IWL_ERR(mvm, "Failed to configure RX queues: %d\n",
@@ -1246,9 +1382,11 @@ int iwl_mvm_up(struct iwl_mvm *mvm)
/* reset quota debouncing buffer - 0xff will yield invalid data */
memset(&mvm->last_quota_cmd, 0xff, sizeof(mvm->last_quota_cmd));
- ret = iwl_mvm_send_dqa_cmd(mvm);
- if (ret)
- goto error;
+ if (fw_has_capa(&mvm->fw->ucode_capa, IWL_UCODE_TLV_CAPA_DQA_SUPPORT)) {
+ ret = iwl_mvm_send_dqa_cmd(mvm);
+ if (ret)
+ goto error;
+ }
/* Add auxiliary station for scanning */
ret = iwl_mvm_add_aux_sta(mvm);
@@ -1256,7 +1394,15 @@ int iwl_mvm_up(struct iwl_mvm *mvm)
goto error;
/* Add all the PHY contexts */
- chan = &mvm->hw->wiphy->bands[NL80211_BAND_2GHZ]->channels[0];
+ i = 0;
+ while (!sband && i < NUM_NL80211_BANDS)
+ sband = mvm->hw->wiphy->bands[i++];
+
+ if (WARN_ON_ONCE(!sband))
+ goto error;
+
+ chan = &sband->channels[0];
+
cfg80211_chandef_create(&chandef, chan, NL80211_CHAN_NO_HT);
for (i = 0; i < NUM_PHY_CTX; i++) {
/*
@@ -1270,7 +1416,6 @@ int iwl_mvm_up(struct iwl_mvm *mvm)
goto error;
}
-#ifdef CONFIG_THERMAL
if (iwl_mvm_is_tt_in_fw(mvm)) {
/* in order to give the responsibility of ct-kill and
* TX backoff to FW we need to send empty temperature reporting
@@ -1282,6 +1427,7 @@ int iwl_mvm_up(struct iwl_mvm *mvm)
iwl_mvm_tt_tx_backoff(mvm, 0);
}
+#ifdef CONFIG_THERMAL
/* TODO: read the budget from BIOS / Platform NVM */
/*
@@ -1294,12 +1440,10 @@ int iwl_mvm_up(struct iwl_mvm *mvm)
if (ret)
goto error;
}
-#else
- /* Initialize tx backoffs to the minimal possible */
- iwl_mvm_tt_tx_backoff(mvm, 0);
#endif
- WARN_ON(iwl_mvm_config_ltr(mvm));
+ if (!fw_has_capa(&mvm->fw->ucode_capa, IWL_UCODE_TLV_CAPA_SET_LTR_GEN2))
+ WARN_ON(iwl_mvm_config_ltr(mvm));
ret = iwl_mvm_power_update_device(mvm);
if (ret)
@@ -1323,16 +1467,16 @@ int iwl_mvm_up(struct iwl_mvm *mvm)
goto error;
}
- /* allow FW/transport low power modes if not during restart */
- if (!test_bit(IWL_MVM_STATUS_IN_HW_RESTART, &mvm->status))
- iwl_mvm_unref(mvm, IWL_MVM_REF_UCODE_DOWN);
-
if (test_bit(IWL_MVM_STATUS_IN_HW_RESTART, &mvm->status))
iwl_mvm_send_recovery_cmd(mvm, ERROR_RECOVERY_UPDATE_DB);
if (iwl_acpi_get_eckv(mvm->dev, &mvm->ext_clock_valid))
IWL_DEBUG_INFO(mvm, "ECKV table doesn't exist in BIOS\n");
+ ret = iwl_mvm_ppag_init(mvm);
+ if (ret)
+ goto error;
+
ret = iwl_mvm_sar_init(mvm);
if (ret == 0) {
ret = iwl_mvm_sar_geo_init(mvm);
diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/led.c b/drivers/net/wireless/intel/iwlwifi/mvm/led.c
index 4348bb00e761..d104da9170ca 100644
--- a/drivers/net/wireless/intel/iwlwifi/mvm/led.c
+++ b/drivers/net/wireless/intel/iwlwifi/mvm/led.c
@@ -7,7 +7,7 @@
*
* Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved.
* Copyright(c) 2017 Intel Deutschland GmbH
- * Copyright(c) 2018 Intel Corporation
+ * Copyright(c) 2018 - 2019 Intel Corporation
*
* 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
@@ -29,7 +29,7 @@
*
* Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved.
* Copyright(c) 2017 Intel Deutschland GmbH
- * Copyright(c) 2018 Intel Corporation
+ * Copyright(c) 2018 - 2019 Intel Corporation
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -156,7 +156,7 @@ void iwl_mvm_leds_sync(struct iwl_mvm *mvm)
* if we control through the register, we're doing it
* even when the firmware isn't up, so no need to sync
*/
- if (mvm->cfg->device_family < IWL_DEVICE_FAMILY_8000)
+ if (mvm->trans->trans_cfg->device_family < IWL_DEVICE_FAMILY_8000)
return;
iwl_mvm_led_set(mvm, mvm->led.brightness > 0);
diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/mac-ctxt.c b/drivers/net/wireless/intel/iwlwifi/mvm/mac-ctxt.c
index cb22d447fcb8..9c417dd06291 100644
--- a/drivers/net/wireless/intel/iwlwifi/mvm/mac-ctxt.c
+++ b/drivers/net/wireless/intel/iwlwifi/mvm/mac-ctxt.c
@@ -554,7 +554,7 @@ static void iwl_mvm_mac_ctxt_cmd_common(struct iwl_mvm *mvm,
cpu_to_le32(vif->bss_conf.use_short_slot ?
MAC_FLG_SHORT_SLOT : 0);
- cmd->filter_flags = cpu_to_le32(MAC_FILTER_ACCEPT_GRP);
+ cmd->filter_flags = 0;
for (i = 0; i < IEEE80211_NUM_ACS; i++) {
u8 txf = iwl_mvm_mac_ac_to_tx_fifo(mvm, i);
@@ -623,6 +623,8 @@ static int iwl_mvm_mac_ctxt_cmd_sta(struct iwl_mvm *mvm,
/* We need the dtim_period to set the MAC as associated */
if (vif->bss_conf.assoc && vif->bss_conf.dtim_period &&
!force_assoc_off) {
+ struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif);
+ u8 ap_sta_id = mvmvif->ap_sta_id;
u32 dtim_offs;
/*
@@ -658,6 +660,29 @@ static int iwl_mvm_mac_ctxt_cmd_sta(struct iwl_mvm *mvm,
dtim_offs);
ctxt_sta->is_assoc = cpu_to_le32(1);
+
+ /*
+ * allow multicast data frames only as long as the station is
+ * authorized, i.e., GTK keys are already installed (if needed)
+ */
+ if (ap_sta_id < IWL_MVM_STATION_COUNT) {
+ struct ieee80211_sta *sta;
+
+ rcu_read_lock();
+
+ sta = rcu_dereference(mvm->fw_id_to_mac_id[ap_sta_id]);
+ if (!IS_ERR_OR_NULL(sta)) {
+ struct iwl_mvm_sta *mvmsta =
+ iwl_mvm_sta_from_mac80211(sta);
+
+ if (mvmsta->sta_state ==
+ IEEE80211_STA_AUTHORIZED)
+ cmd.filter_flags |=
+ cpu_to_le32(MAC_FILTER_ACCEPT_GRP);
+ }
+
+ rcu_read_unlock();
+ }
} else {
ctxt_sta->is_assoc = cpu_to_le32(0);
@@ -703,7 +728,8 @@ static int iwl_mvm_mac_ctxt_cmd_listener(struct iwl_mvm *mvm,
MAC_FILTER_IN_CONTROL_AND_MGMT |
MAC_FILTER_IN_BEACON |
MAC_FILTER_IN_PROBE_REQUEST |
- MAC_FILTER_IN_CRC32);
+ MAC_FILTER_IN_CRC32 |
+ MAC_FILTER_ACCEPT_GRP);
ieee80211_hw_set(mvm->hw, RX_INCLUDES_FCS);
/* Allocate sniffer station */
@@ -727,7 +753,8 @@ static int iwl_mvm_mac_ctxt_cmd_ibss(struct iwl_mvm *mvm,
iwl_mvm_mac_ctxt_cmd_common(mvm, vif, &cmd, NULL, action);
cmd.filter_flags = cpu_to_le32(MAC_FILTER_IN_BEACON |
- MAC_FILTER_IN_PROBE_REQUEST);
+ MAC_FILTER_IN_PROBE_REQUEST |
+ MAC_FILTER_ACCEPT_GRP);
/* cmd.ibss.beacon_time/cmd.ibss.beacon_tsf are curently ignored */
cmd.ibss.bi = cpu_to_le32(vif->bss_conf.beacon_int);
@@ -1404,6 +1431,9 @@ void iwl_mvm_rx_missed_beacons_notif(struct iwl_mvm *mvm,
else if (rx_missed_bcon_since_rx > IWL_MVM_MISSED_BEACONS_THRESHOLD)
ieee80211_beacon_loss(vif);
+ iwl_dbg_tlv_time_point(&mvm->fwrt,
+ IWL_FW_INI_TIME_POINT_MISSED_BEACONS, NULL);
+
trigger = iwl_fw_dbg_trigger_on(&mvm->fwrt, ieee80211_vif_to_wdev(vif),
FW_DBG_TRIGGER_MISSED_BEACONS);
if (!trigger)
@@ -1420,8 +1450,6 @@ void iwl_mvm_rx_missed_beacons_notif(struct iwl_mvm *mvm,
rx_missed_bcon >= stop_trig_missed_bcon)
iwl_fw_dbg_collect_trig(&mvm->fwrt, trigger, NULL);
- iwl_fw_dbg_apply_point(&mvm->fwrt, IWL_FW_INI_APPLY_MISSED_BEACONS);
-
out:
rcu_read_unlock();
}
@@ -1567,7 +1595,9 @@ void iwl_mvm_channel_switch_noa_notif(struct iwl_mvm *mvm,
RCU_INIT_POINTER(mvm->csa_vif, NULL);
return;
case NL80211_IFTYPE_STATION:
- iwl_mvm_csa_client_absent(mvm, vif);
+ if (!fw_has_capa(&mvm->fw->ucode_capa,
+ IWL_UCODE_TLV_CAPA_CHANNEL_SWITCH_CMD))
+ iwl_mvm_csa_client_absent(mvm, vif);
cancel_delayed_work(&mvmvif->csa_work);
ieee80211_chswitch_done(vif, true);
break;
diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/mac80211.c b/drivers/net/wireless/intel/iwlwifi/mvm/mac80211.c
index 1c904b5226aa..d31f96c3f925 100644
--- a/drivers/net/wireless/intel/iwlwifi/mvm/mac80211.c
+++ b/drivers/net/wireless/intel/iwlwifi/mvm/mac80211.c
@@ -213,91 +213,6 @@ static int __iwl_mvm_mac_set_key(struct ieee80211_hw *hw,
struct ieee80211_sta *sta,
struct ieee80211_key_conf *key);
-void iwl_mvm_ref(struct iwl_mvm *mvm, enum iwl_mvm_ref_type ref_type)
-{
- if (!iwl_mvm_is_d0i3_supported(mvm))
- return;
-
- IWL_DEBUG_RPM(mvm, "Take mvm reference - type %d\n", ref_type);
- spin_lock_bh(&mvm->refs_lock);
- mvm->refs[ref_type]++;
- spin_unlock_bh(&mvm->refs_lock);
- iwl_trans_ref(mvm->trans);
-}
-
-void iwl_mvm_unref(struct iwl_mvm *mvm, enum iwl_mvm_ref_type ref_type)
-{
- if (!iwl_mvm_is_d0i3_supported(mvm))
- return;
-
- IWL_DEBUG_RPM(mvm, "Leave mvm reference - type %d\n", ref_type);
- spin_lock_bh(&mvm->refs_lock);
- if (WARN_ON(!mvm->refs[ref_type])) {
- spin_unlock_bh(&mvm->refs_lock);
- return;
- }
- mvm->refs[ref_type]--;
- spin_unlock_bh(&mvm->refs_lock);
- iwl_trans_unref(mvm->trans);
-}
-
-static void iwl_mvm_unref_all_except(struct iwl_mvm *mvm,
- enum iwl_mvm_ref_type except_ref)
-{
- int i, j;
-
- if (!iwl_mvm_is_d0i3_supported(mvm))
- return;
-
- spin_lock_bh(&mvm->refs_lock);
- for (i = 0; i < IWL_MVM_REF_COUNT; i++) {
- if (except_ref == i || !mvm->refs[i])
- continue;
-
- IWL_DEBUG_RPM(mvm, "Cleanup: remove mvm ref type %d (%d)\n",
- i, mvm->refs[i]);
- for (j = 0; j < mvm->refs[i]; j++)
- iwl_trans_unref(mvm->trans);
- mvm->refs[i] = 0;
- }
- spin_unlock_bh(&mvm->refs_lock);
-}
-
-bool iwl_mvm_ref_taken(struct iwl_mvm *mvm)
-{
- int i;
- bool taken = false;
-
- if (!iwl_mvm_is_d0i3_supported(mvm))
- return true;
-
- spin_lock_bh(&mvm->refs_lock);
- for (i = 0; i < IWL_MVM_REF_COUNT; i++) {
- if (mvm->refs[i]) {
- taken = true;
- break;
- }
- }
- spin_unlock_bh(&mvm->refs_lock);
-
- return taken;
-}
-
-int iwl_mvm_ref_sync(struct iwl_mvm *mvm, enum iwl_mvm_ref_type ref_type)
-{
- iwl_mvm_ref(mvm, ref_type);
-
- if (!wait_event_timeout(mvm->d0i3_exit_waitq,
- !test_bit(IWL_MVM_STATUS_IN_D0I3, &mvm->status),
- HZ)) {
- WARN_ON_ONCE(1);
- iwl_mvm_unref(mvm, ref_type);
- return -EIO;
- }
-
- return 0;
-}
-
static void iwl_mvm_reset_phy_ctxts(struct iwl_mvm *mvm)
{
int i;
@@ -485,7 +400,7 @@ int iwl_mvm_mac_setup_register(struct iwl_mvm *mvm)
* for older devices. We also don't see this issue on any newer
* devices.
*/
- if (mvm->cfg->device_family >= IWL_DEVICE_FAMILY_9000)
+ if (mvm->trans->trans_cfg->device_family >= IWL_DEVICE_FAMILY_9000)
ieee80211_hw_set(hw, TX_AMSDU);
ieee80211_hw_set(hw, TX_FRAG_LIST);
@@ -762,12 +677,6 @@ int iwl_mvm_mac_setup_register(struct iwl_mvm *mvm)
mvm->rts_threshold = IEEE80211_MAX_RTS_THRESHOLD;
#ifdef CONFIG_PM_SLEEP
- if (iwl_mvm_is_d0i3_supported(mvm) &&
- device_can_wakeup(mvm->trans->dev)) {
- mvm->wowlan.flags = WIPHY_WOWLAN_ANY;
- hw->wiphy->wowlan = &mvm->wowlan;
- }
-
if ((unified || mvm->fw->img[IWL_UCODE_WOWLAN].num_sec) &&
mvm->trans->ops->d3_suspend &&
mvm->trans->ops->d3_resume &&
@@ -833,46 +742,6 @@ int iwl_mvm_mac_setup_register(struct iwl_mvm *mvm)
return ret;
}
-static bool iwl_mvm_defer_tx(struct iwl_mvm *mvm,
- struct ieee80211_sta *sta,
- struct sk_buff *skb)
-{
- struct iwl_mvm_sta *mvmsta;
- bool defer = false;
-
- /*
- * double check the IN_D0I3 flag both before and after
- * taking the spinlock, in order to prevent taking
- * the spinlock when not needed.
- */
- if (likely(!test_bit(IWL_MVM_STATUS_IN_D0I3, &mvm->status)))
- return false;
-
- spin_lock(&mvm->d0i3_tx_lock);
- /*
- * testing the flag again ensures the skb dequeue
- * loop (on d0i3 exit) hasn't run yet.
- */
- if (!test_bit(IWL_MVM_STATUS_IN_D0I3, &mvm->status))
- goto out;
-
- mvmsta = iwl_mvm_sta_from_mac80211(sta);
- if (mvmsta->sta_id == IWL_MVM_INVALID_STA ||
- mvmsta->sta_id != mvm->d0i3_ap_sta_id)
- goto out;
-
- __skb_queue_tail(&mvm->d0i3_tx, skb);
-
- /* trigger wakeup */
- iwl_mvm_ref(mvm, IWL_MVM_REF_TX);
- iwl_mvm_unref(mvm, IWL_MVM_REF_TX);
-
- defer = true;
-out:
- spin_unlock(&mvm->d0i3_tx_lock);
- return defer;
-}
-
static void iwl_mvm_mac_tx(struct ieee80211_hw *hw,
struct ieee80211_tx_control *control,
struct sk_buff *skb)
@@ -917,8 +786,6 @@ static void iwl_mvm_mac_tx(struct ieee80211_hw *hw,
}
if (sta) {
- if (iwl_mvm_defer_tx(mvm, sta, skb))
- return;
if (iwl_mvm_tx_skb(mvm, skb, sta))
goto drop;
return;
@@ -1086,7 +953,6 @@ static int iwl_mvm_mac_ampdu_action(struct ieee80211_hw *hw,
{
struct iwl_mvm *mvm = IWL_MAC80211_GET_MVM(hw);
int ret;
- bool tx_agg_ref = false;
struct ieee80211_sta *sta = params->sta;
enum ieee80211_ampdu_mlme_action action = params->action;
u16 tid = params->tid;
@@ -1101,31 +967,6 @@ static int iwl_mvm_mac_ampdu_action(struct ieee80211_hw *hw,
if (!(mvm->nvm_data->sku_cap_11n_enable))
return -EACCES;
- /* return from D0i3 before starting a new Tx aggregation */
- switch (action) {
- case IEEE80211_AMPDU_TX_START:
- case IEEE80211_AMPDU_TX_STOP_CONT:
- case IEEE80211_AMPDU_TX_STOP_FLUSH:
- case IEEE80211_AMPDU_TX_STOP_FLUSH_CONT:
- case IEEE80211_AMPDU_TX_OPERATIONAL:
- /*
- * for tx start, wait synchronously until D0i3 exit to
- * get the correct sequence number for the tid.
- * additionally, some other ampdu actions use direct
- * target access, which is not handled automatically
- * by the trans layer (unlike commands), so wait for
- * d0i3 exit in these cases as well.
- */
- ret = iwl_mvm_ref_sync(mvm, IWL_MVM_REF_TX_AGG);
- if (ret)
- return ret;
-
- tx_agg_ref = true;
- break;
- default:
- break;
- }
-
mutex_lock(&mvm->mutex);
switch (action) {
@@ -1186,13 +1027,6 @@ static int iwl_mvm_mac_ampdu_action(struct ieee80211_hw *hw,
}
mutex_unlock(&mvm->mutex);
- /*
- * If the tid is marked as started, we won't use it for offloaded
- * traffic on the next D0i3 entry. It's safe to unref.
- */
- if (tx_agg_ref)
- iwl_mvm_unref(mvm, IWL_MVM_REF_TX_AGG);
-
return ret;
}
@@ -1216,11 +1050,6 @@ static void iwl_mvm_cleanup_iterator(void *data, u8 *mac,
static void iwl_mvm_restart_cleanup(struct iwl_mvm *mvm)
{
- /* cleanup all stale references (scan, roc), but keep the
- * ucode_down ref until reconfig is complete
- */
- iwl_mvm_unref_all_except(mvm, IWL_MVM_REF_UCODE_DOWN);
-
iwl_mvm_stop_device(mvm);
mvm->cur_aid = 0;
@@ -1242,7 +1071,6 @@ static void iwl_mvm_restart_cleanup(struct iwl_mvm *mvm)
ieee80211_iterate_interfaces(mvm->hw, 0, iwl_mvm_cleanup_iterator, mvm);
mvm->p2p_device_vif = NULL;
- mvm->d0i3_ap_sta_id = IWL_MVM_INVALID_STA;
iwl_mvm_reset_phy_ctxts(mvm);
memset(mvm->fw_key_table, 0, sizeof(mvm->fw_key_table));
@@ -1251,9 +1079,6 @@ static void iwl_mvm_restart_cleanup(struct iwl_mvm *mvm)
ieee80211_wake_queues(mvm->hw);
- /* clear any stale d0i3 state */
- clear_bit(IWL_MVM_STATUS_IN_D0I3, &mvm->status);
-
mvm->vif_count = 0;
mvm->rx_ba_sessions = 0;
mvm->fwrt.dump.conf = FW_DBG_INVALID;
@@ -1278,18 +1103,13 @@ int __iwl_mvm_mac_start(struct iwl_mvm *mvm)
clear_bit(IWL_MVM_STATUS_HW_RESTART_REQUESTED, &mvm->status);
/* Clean up some internal and mac80211 state on restart */
iwl_mvm_restart_cleanup(mvm);
- } else {
- /* Hold the reference to prevent runtime suspend while
- * the start procedure runs. It's a bit confusing
- * that the UCODE_DOWN reference is taken, but it just
- * means "UCODE is not UP yet". ( TODO: rename this
- * reference).
- */
- iwl_mvm_ref(mvm, IWL_MVM_REF_UCODE_DOWN);
}
ret = iwl_mvm_up(mvm);
- iwl_fw_dbg_apply_point(&mvm->fwrt, IWL_FW_INI_APPLY_POST_INIT);
+ iwl_dbg_tlv_time_point(&mvm->fwrt, IWL_FW_INI_TIME_POINT_POST_INIT,
+ NULL);
+ iwl_dbg_tlv_time_point(&mvm->fwrt, IWL_FW_INI_TIME_POINT_PERIODIC,
+ NULL);
if (ret && test_bit(IWL_MVM_STATUS_IN_HW_RESTART, &mvm->status)) {
/* Something went wrong - we need to finish some cleanup
@@ -1297,9 +1117,6 @@ int __iwl_mvm_mac_start(struct iwl_mvm *mvm)
* would do.
*/
clear_bit(IWL_MVM_STATUS_IN_HW_RESTART, &mvm->status);
-#ifdef CONFIG_PM
- iwl_mvm_d0i3_enable_tx(mvm, NULL);
-#endif
}
return ret;
@@ -1310,19 +1127,6 @@ static int iwl_mvm_mac_start(struct ieee80211_hw *hw)
struct iwl_mvm *mvm = IWL_MAC80211_GET_MVM(hw);
int ret;
- /* Some hw restart cleanups must not hold the mutex */
- if (test_bit(IWL_MVM_STATUS_IN_HW_RESTART, &mvm->status)) {
- /*
- * Make sure we are out of d0i3. This is needed
- * to make sure the reference accounting is correct
- * (and there is no stale d0i3_exit_work).
- */
- wait_event_timeout(mvm->d0i3_exit_waitq,
- !test_bit(IWL_MVM_STATUS_IN_D0I3,
- &mvm->status),
- HZ);
- }
-
mutex_lock(&mvm->mutex);
ret = __iwl_mvm_mac_start(mvm);
mutex_unlock(&mvm->mutex);
@@ -1337,17 +1141,12 @@ static void iwl_mvm_restart_complete(struct iwl_mvm *mvm)
mutex_lock(&mvm->mutex);
clear_bit(IWL_MVM_STATUS_IN_HW_RESTART, &mvm->status);
-#ifdef CONFIG_PM
- iwl_mvm_d0i3_enable_tx(mvm, NULL);
-#endif
+
ret = iwl_mvm_update_quotas(mvm, true, NULL);
if (ret)
IWL_ERR(mvm, "Failed to update quotas after restart (%d)\n",
ret);
- /* allow transport/FW low power modes */
- iwl_mvm_unref(mvm, IWL_MVM_REF_UCODE_DOWN);
-
iwl_mvm_send_recovery_cmd(mvm, ERROR_RECOVERY_END_OF_RECOVERY);
/*
@@ -1359,17 +1158,6 @@ static void iwl_mvm_restart_complete(struct iwl_mvm *mvm)
mutex_unlock(&mvm->mutex);
}
-static void iwl_mvm_resume_complete(struct iwl_mvm *mvm)
-{
- if (iwl_mvm_is_d0i3_supported(mvm) &&
- iwl_mvm_enter_d0i3_on_suspend(mvm))
- WARN_ONCE(!wait_event_timeout(mvm->d0i3_exit_waitq,
- !test_bit(IWL_MVM_STATUS_IN_D0I3,
- &mvm->status),
- HZ),
- "D0i3 exit on resume timed out\n");
-}
-
static void
iwl_mvm_mac_reconfig_complete(struct ieee80211_hw *hw,
enum ieee80211_reconfig_type reconfig_type)
@@ -1381,7 +1169,6 @@ iwl_mvm_mac_reconfig_complete(struct ieee80211_hw *hw,
iwl_mvm_restart_complete(mvm);
break;
case IEEE80211_RECONFIG_TYPE_SUSPEND:
- iwl_mvm_resume_complete(mvm);
break;
}
}
@@ -1443,7 +1230,6 @@ static void iwl_mvm_mac_stop(struct ieee80211_hw *hw)
{
struct iwl_mvm *mvm = IWL_MAC80211_GET_MVM(hw);
- flush_work(&mvm->d0i3_exit_work);
flush_work(&mvm->async_handlers_wk);
flush_work(&mvm->add_stream_wk);
@@ -1457,7 +1243,6 @@ static void iwl_mvm_mac_stop(struct ieee80211_hw *hw)
*/
clear_bit(IWL_MVM_STATUS_FIRMWARE_RUNNING, &mvm->status);
- iwl_fw_cancel_dumps(&mvm->fwrt);
cancel_delayed_work_sync(&mvm->cs_tx_unblock_dwork);
cancel_delayed_work_sync(&mvm->scan_timeout_dwork);
iwl_fw_free_dump_desc(&mvm->fwrt);
@@ -1543,15 +1328,20 @@ static int iwl_mvm_post_channel_switch(struct ieee80211_hw *hw,
goto out_unlock;
}
- iwl_mvm_sta_modify_disable_tx(mvm, mvmsta, false);
+ if (!fw_has_capa(&mvm->fw->ucode_capa,
+ IWL_UCODE_TLV_CAPA_CHANNEL_SWITCH_CMD))
+ iwl_mvm_sta_modify_disable_tx(mvm, mvmsta, false);
iwl_mvm_mac_ctxt_changed(mvm, vif, false, NULL);
- ret = iwl_mvm_enable_beacon_filter(mvm, vif, 0);
- if (ret)
- goto out_unlock;
+ if (!fw_has_capa(&mvm->fw->ucode_capa,
+ IWL_UCODE_TLV_CAPA_CHANNEL_SWITCH_CMD)) {
+ ret = iwl_mvm_enable_beacon_filter(mvm, vif, 0);
+ if (ret)
+ goto out_unlock;
- iwl_mvm_stop_session_protection(mvm, vif);
+ iwl_mvm_stop_session_protection(mvm, vif);
+ }
}
mvmvif->ps_disabled = false;
@@ -1612,15 +1402,6 @@ static int iwl_mvm_mac_add_interface(struct ieee80211_hw *hw,
RCU_INIT_POINTER(mvmvif->probe_resp_data, NULL);
/*
- * make sure D0i3 exit is completed, otherwise a target access
- * during tx queue configuration could be done when still in
- * D0i3 state.
- */
- ret = iwl_mvm_ref_sync(mvm, IWL_MVM_REF_ADD_IF);
- if (ret)
- return ret;
-
- /*
* Not much to do here. The stack will not allow interface
* types or combinations that we didn't advertise, so we
* don't really have to check the types.
@@ -1755,8 +1536,6 @@ static int iwl_mvm_mac_add_interface(struct ieee80211_hw *hw,
out_unlock:
mutex_unlock(&mvm->mutex);
- iwl_mvm_unref(mvm, IWL_MVM_REF_ADD_IF);
-
return ret;
}
@@ -2254,6 +2033,10 @@ static void iwl_mvm_cfg_he_sta(struct iwl_mvm *mvm,
flags = 0;
+ /* Block 26-tone RU OFDMA transmissions */
+ if (mvmvif->he_ru_2mhz_block)
+ flags |= STA_CTXT_HE_RU_2MHZ_BLOCK;
+
/* HTC flags */
if (sta->he_cap.he_cap_elem.mac_cap_info[0] &
IEEE80211_HE_MAC_CAP0_HTC_HE)
@@ -2520,7 +2303,6 @@ static void iwl_mvm_bss_info_changed_station(struct iwl_mvm *mvm,
iwl_mvm_sf_update(mvm, vif, false);
iwl_mvm_power_vif_assoc(mvm, vif);
if (vif->p2p) {
- iwl_mvm_ref(mvm, IWL_MVM_REF_P2P_CLIENT);
iwl_mvm_update_smps(mvm, vif,
IWL_MVM_SMPS_REQ_PROT,
IEEE80211_SMPS_DYNAMIC);
@@ -2556,9 +2338,6 @@ static void iwl_mvm_bss_info_changed_station(struct iwl_mvm *mvm,
IWL_ERR(mvm,
"failed to remove AP station\n");
- if (mvm->d0i3_ap_sta_id == mvmvif->ap_sta_id)
- mvm->d0i3_ap_sta_id =
- IWL_MVM_INVALID_STA;
mvmvif->ap_sta_id = IWL_MVM_INVALID_STA;
}
@@ -2567,9 +2346,6 @@ static void iwl_mvm_bss_info_changed_station(struct iwl_mvm *mvm,
if (ret)
IWL_ERR(mvm, "failed to update quotas\n");
- if (vif->p2p)
- iwl_mvm_unref(mvm, IWL_MVM_REF_P2P_CLIENT);
-
/* this will take the cleared BSSID from bss_conf */
ret = iwl_mvm_mac_ctxt_changed(mvm, vif, false, NULL);
if (ret)
@@ -2657,14 +2433,6 @@ static int iwl_mvm_start_ap_ibss(struct ieee80211_hw *hw,
struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif);
int ret, i;
- /*
- * iwl_mvm_mac_ctxt_add() might read directly from the device
- * (the system time), so make sure it is available.
- */
- ret = iwl_mvm_ref_sync(mvm, IWL_MVM_REF_START_AP);
- if (ret)
- return ret;
-
mutex_lock(&mvm->mutex);
/* Send the beacon template */
@@ -2760,8 +2528,6 @@ static int iwl_mvm_start_ap_ibss(struct ieee80211_hw *hw,
if (vif->p2p && mvm->p2p_device_vif)
iwl_mvm_mac_ctxt_changed(mvm, mvm->p2p_device_vif, false, NULL);
- iwl_mvm_ref(mvm, IWL_MVM_REF_AP_IBSS);
-
iwl_mvm_bt_coex_vif_change(mvm);
/* we don't support TDLS during DCM */
@@ -2783,7 +2549,6 @@ out_remove:
iwl_mvm_mac_ctxt_remove(mvm, vif);
out_unlock:
mutex_unlock(&mvm->mutex);
- iwl_mvm_unref(mvm, IWL_MVM_REF_START_AP);
return ret;
}
@@ -2821,8 +2586,6 @@ static void iwl_mvm_stop_ap_ibss(struct ieee80211_hw *hw,
iwl_mvm_bt_coex_vif_change(mvm);
- iwl_mvm_unref(mvm, IWL_MVM_REF_AP_IBSS);
-
/* Need to update the P2P Device MAC (only GO, IBSS is single vif) */
if (vif->p2p && mvm->p2p_device_vif)
iwl_mvm_mac_ctxt_changed(mvm, mvm->p2p_device_vif, false, NULL);
@@ -2896,14 +2659,6 @@ static void iwl_mvm_bss_info_changed(struct ieee80211_hw *hw,
{
struct iwl_mvm *mvm = IWL_MAC80211_GET_MVM(hw);
- /*
- * iwl_mvm_bss_info_changed_station() might call
- * iwl_mvm_protect_session(), which reads directly from
- * the device (the system time), so make sure it is available.
- */
- if (iwl_mvm_ref_sync(mvm, IWL_MVM_REF_BSS_CHANGED))
- return;
-
mutex_lock(&mvm->mutex);
if (changes & BSS_CHANGED_IDLE && !bss_conf->idle)
@@ -2927,7 +2682,6 @@ static void iwl_mvm_bss_info_changed(struct ieee80211_hw *hw,
}
mutex_unlock(&mvm->mutex);
- iwl_mvm_unref(mvm, IWL_MVM_REF_BSS_CHANGED);
}
static int iwl_mvm_mac_hw_scan(struct ieee80211_hw *hw,
@@ -3205,6 +2959,51 @@ iwl_mvm_tdls_check_trigger(struct iwl_mvm *mvm,
peer_addr, action);
}
+struct iwl_mvm_he_obss_narrow_bw_ru_data {
+ bool tolerated;
+};
+
+static void iwl_mvm_check_he_obss_narrow_bw_ru_iter(struct wiphy *wiphy,
+ struct cfg80211_bss *bss,
+ void *_data)
+{
+ struct iwl_mvm_he_obss_narrow_bw_ru_data *data = _data;
+ const struct element *elem;
+
+ elem = cfg80211_find_elem(WLAN_EID_EXT_CAPABILITY, bss->ies->data,
+ bss->ies->len);
+
+ if (!elem || elem->datalen < 10 ||
+ !(elem->data[10] &
+ WLAN_EXT_CAPA10_OBSS_NARROW_BW_RU_TOLERANCE_SUPPORT)) {
+ data->tolerated = false;
+ }
+}
+
+static void iwl_mvm_check_he_obss_narrow_bw_ru(struct ieee80211_hw *hw,
+ struct ieee80211_vif *vif)
+{
+ struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif);
+ struct iwl_mvm_he_obss_narrow_bw_ru_data iter_data = {
+ .tolerated = true,
+ };
+
+ if (!(vif->bss_conf.chandef.chan->flags & IEEE80211_CHAN_RADAR)) {
+ mvmvif->he_ru_2mhz_block = false;
+ return;
+ }
+
+ cfg80211_bss_iter(hw->wiphy, &vif->bss_conf.chandef,
+ iwl_mvm_check_he_obss_narrow_bw_ru_iter,
+ &iter_data);
+
+ /*
+ * If there is at least one AP on radar channel that cannot
+ * tolerate 26-tone RU UL OFDMA transmissions using HE TB PPDU.
+ */
+ mvmvif->he_ru_2mhz_block = !iter_data.tolerated;
+}
+
static int iwl_mvm_mac_sta_state(struct ieee80211_hw *hw,
struct ieee80211_vif *vif,
struct ieee80211_sta *sta,
@@ -3306,6 +3105,11 @@ static int iwl_mvm_mac_sta_state(struct ieee80211_hw *hw,
iwl_mvm_cfg_he_sta(mvm, vif, mvm_sta->sta_id);
} else if (vif->type == NL80211_IFTYPE_STATION) {
vif->bss_conf.he_support = sta->he_cap.has_he;
+
+ mvmvif->he_ru_2mhz_block = false;
+ if (sta->he_cap.has_he)
+ iwl_mvm_check_he_obss_narrow_bw_ru(hw, vif);
+
iwl_mvm_mac_ctxt_changed(mvm, vif, false, NULL);
}
@@ -3327,10 +3131,20 @@ static int iwl_mvm_mac_sta_state(struct ieee80211_hw *hw,
/* enable beacon filtering */
WARN_ON(iwl_mvm_enable_beacon_filter(mvm, vif, 0));
+ /*
+ * Now that the station is authorized, i.e., keys were already
+ * installed, need to indicate to the FW that
+ * multicast data frames can be forwarded to the driver
+ */
+ iwl_mvm_mac_ctxt_changed(mvm, vif, false, NULL);
+
iwl_mvm_rs_rate_init(mvm, sta, mvmvif->phy_ctxt->channel->band,
true);
} else if (old_state == IEEE80211_STA_AUTHORIZED &&
new_state == IEEE80211_STA_ASSOC) {
+ /* Multicast data frames are no longer allowed */
+ iwl_mvm_mac_ctxt_changed(mvm, vif, false, NULL);
+
/* disable beacon filtering */
ret = iwl_mvm_disable_beacon_filter(mvm, vif, 0);
WARN_ON(ret &&
@@ -3437,13 +3251,6 @@ static void iwl_mvm_mac_mgd_prepare_tx(struct ieee80211_hw *hw,
u32 duration = IWL_MVM_TE_SESSION_PROTECTION_MAX_TIME_MS;
u32 min_duration = IWL_MVM_TE_SESSION_PROTECTION_MIN_TIME_MS;
- /*
- * iwl_mvm_protect_session() reads directly from the device
- * (the system time), so make sure it is available.
- */
- if (iwl_mvm_ref_sync(mvm, IWL_MVM_REF_PREPARE_TX))
- return;
-
if (req_duration > duration)
duration = req_duration;
@@ -3451,8 +3258,6 @@ static void iwl_mvm_mac_mgd_prepare_tx(struct ieee80211_hw *hw,
/* Try really hard to protect the session and hear a beacon */
iwl_mvm_protect_session(mvm, vif, duration, min_duration, 500, false);
mutex_unlock(&mvm->mutex);
-
- iwl_mvm_unref(mvm, IWL_MVM_REF_PREPARE_TX);
}
static int iwl_mvm_mac_sched_scan_start(struct ieee80211_hw *hw,
@@ -3527,7 +3332,7 @@ static int __iwl_mvm_mac_set_key(struct ieee80211_hw *hw,
switch (key->cipher) {
case WLAN_CIPHER_SUITE_TKIP:
- if (!mvm->trans->cfg->gen2) {
+ if (!mvm->trans->trans_cfg->gen2) {
key->flags |= IEEE80211_KEY_FLAG_GENERATE_MMIC;
key->flags |= IEEE80211_KEY_FLAG_PUT_IV_SPACE;
} else if (vif->type == NL80211_IFTYPE_STATION) {
@@ -4035,7 +3840,8 @@ out_unlock:
return ret;
}
-static int iwl_mvm_cancel_roc(struct ieee80211_hw *hw)
+static int iwl_mvm_cancel_roc(struct ieee80211_hw *hw,
+ struct ieee80211_vif *vif)
{
struct iwl_mvm *mvm = IWL_MAC80211_GET_MVM(hw);
@@ -4267,23 +4073,12 @@ static int __iwl_mvm_assign_vif_chanctx(struct iwl_mvm *mvm,
IWL_UCODE_TLV_CAPA_CHANNEL_SWITCH_CMD)) {
u32 duration = 3 * vif->bss_conf.beacon_int;
-
- /* iwl_mvm_protect_session() reads directly from the
- * device (the system time), so make sure it is
- * available.
- */
- ret = iwl_mvm_ref_sync(mvm, IWL_MVM_REF_PROTECT_CSA);
- if (ret)
- goto out_remove_binding;
-
/* Protect the session to make sure we hear the first
* beacon on the new channel.
*/
iwl_mvm_protect_session(mvm, vif, duration, duration,
vif->bss_conf.beacon_int / 2,
true);
-
- iwl_mvm_unref(mvm, IWL_MVM_REF_PROTECT_CSA);
}
iwl_mvm_update_quotas(mvm, false, NULL);
@@ -4633,6 +4428,42 @@ static int iwl_mvm_schedule_client_csa(struct iwl_mvm *mvm,
0, sizeof(cmd), &cmd);
}
+static int iwl_mvm_old_pre_chan_sw_sta(struct iwl_mvm *mvm,
+ struct ieee80211_vif *vif,
+ struct ieee80211_channel_switch *chsw)
+{
+ struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif);
+ u32 apply_time;
+
+ /* Schedule the time event to a bit before beacon 1,
+ * to make sure we're in the new channel when the
+ * GO/AP arrives. In case count <= 1 immediately schedule the
+ * TE (this might result with some packet loss or connection
+ * loss).
+ */
+ if (chsw->count <= 1)
+ apply_time = 0;
+ else
+ apply_time = chsw->device_timestamp +
+ ((vif->bss_conf.beacon_int * (chsw->count - 1) -
+ IWL_MVM_CHANNEL_SWITCH_TIME_CLIENT) * 1024);
+
+ if (chsw->block_tx)
+ iwl_mvm_csa_client_absent(mvm, vif);
+
+ if (mvmvif->bf_data.bf_enabled) {
+ int ret = iwl_mvm_disable_beacon_filter(mvm, vif, 0);
+
+ if (ret)
+ return ret;
+ }
+
+ iwl_mvm_schedule_csa_period(mvm, vif, vif->bss_conf.beacon_int,
+ apply_time);
+
+ return 0;
+}
+
#define IWL_MAX_CSA_BLOCK_TX 1500
static int iwl_mvm_pre_channel_switch(struct ieee80211_hw *hw,
struct ieee80211_vif *vif,
@@ -4641,7 +4472,6 @@ static int iwl_mvm_pre_channel_switch(struct ieee80211_hw *hw,
struct iwl_mvm *mvm = IWL_MAC80211_GET_MVM(hw);
struct ieee80211_vif *csa_vif;
struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif);
- u32 apply_time;
int ret;
mutex_lock(&mvm->mutex);
@@ -4685,21 +4515,7 @@ static int iwl_mvm_pre_channel_switch(struct ieee80211_hw *hw,
break;
case NL80211_IFTYPE_STATION:
- /* Schedule the time event to a bit before beacon 1,
- * to make sure we're in the new channel when the
- * GO/AP arrives. In case count <= 1 immediately schedule the
- * TE (this might result with some packet loss or connection
- * loss).
- */
- if (chsw->count <= 1)
- apply_time = 0;
- else
- apply_time = chsw->device_timestamp +
- ((vif->bss_conf.beacon_int * (chsw->count - 1) -
- IWL_MVM_CHANNEL_SWITCH_TIME_CLIENT) * 1024);
-
if (chsw->block_tx) {
- iwl_mvm_csa_client_absent(mvm, vif);
/*
* In case of undetermined / long time with immediate
* quiet monitor status to gracefully disconnect
@@ -4711,19 +4527,14 @@ static int iwl_mvm_pre_channel_switch(struct ieee80211_hw *hw,
msecs_to_jiffies(IWL_MAX_CSA_BLOCK_TX));
}
- if (mvmvif->bf_data.bf_enabled) {
- ret = iwl_mvm_disable_beacon_filter(mvm, vif, 0);
+ if (!fw_has_capa(&mvm->fw->ucode_capa,
+ IWL_UCODE_TLV_CAPA_CHANNEL_SWITCH_CMD)) {
+ ret = iwl_mvm_old_pre_chan_sw_sta(mvm, vif, chsw);
if (ret)
goto out_unlock;
- }
-
- if (fw_has_capa(&mvm->fw->ucode_capa,
- IWL_UCODE_TLV_CAPA_CHANNEL_SWITCH_CMD))
+ } else {
iwl_mvm_schedule_client_csa(mvm, vif, chsw);
- else
- iwl_mvm_schedule_csa_period(mvm, vif,
- vif->bss_conf.beacon_int,
- apply_time);
+ }
mvmvif->csa_count = chsw->count;
mvmvif->csa_misbehave = false;
@@ -5070,11 +4881,11 @@ void iwl_mvm_sync_rx_queues_internal(struct iwl_mvm *mvm,
if (!iwl_mvm_has_new_rx_api(mvm))
return;
- notif->cookie = mvm->queue_sync_cookie;
-
- if (notif->sync)
+ if (notif->sync) {
+ notif->cookie = mvm->queue_sync_cookie;
atomic_set(&mvm->queue_sync_counter,
mvm->trans->num_rx_queues);
+ }
ret = iwl_mvm_notify_rx_queue(mvm, qmask, (u8 *)notif,
size, !notif->sync);
@@ -5094,7 +4905,8 @@ void iwl_mvm_sync_rx_queues_internal(struct iwl_mvm *mvm,
out:
atomic_set(&mvm->queue_sync_counter, 0);
- mvm->queue_sync_cookie++;
+ if (notif->sync)
+ mvm->queue_sync_cookie++;
}
static void iwl_mvm_sync_rx_queues(struct ieee80211_hw *hw)
diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/mvm.h b/drivers/net/wireless/intel/iwlwifi/mvm/mvm.h
index a263cc629d75..843d00bf2bd5 100644
--- a/drivers/net/wireless/intel/iwlwifi/mvm/mvm.h
+++ b/drivers/net/wireless/intel/iwlwifi/mvm/mvm.h
@@ -258,38 +258,6 @@ enum iwl_mvm_smps_type_request {
NUM_IWL_MVM_SMPS_REQ,
};
-enum iwl_mvm_ref_type {
- IWL_MVM_REF_UCODE_DOWN,
- IWL_MVM_REF_SCAN,
- IWL_MVM_REF_ROC,
- IWL_MVM_REF_ROC_AUX,
- IWL_MVM_REF_P2P_CLIENT,
- IWL_MVM_REF_AP_IBSS,
- IWL_MVM_REF_USER,
- IWL_MVM_REF_TX,
- IWL_MVM_REF_TX_AGG,
- IWL_MVM_REF_ADD_IF,
- IWL_MVM_REF_START_AP,
- IWL_MVM_REF_BSS_CHANGED,
- IWL_MVM_REF_PREPARE_TX,
- IWL_MVM_REF_PROTECT_TDLS,
- IWL_MVM_REF_CHECK_CTKILL,
- IWL_MVM_REF_PRPH_READ,
- IWL_MVM_REF_PRPH_WRITE,
- IWL_MVM_REF_NMI,
- IWL_MVM_REF_TM_CMD,
- IWL_MVM_REF_EXIT_WORK,
- IWL_MVM_REF_PROTECT_CSA,
- IWL_MVM_REF_FW_DBG_COLLECT,
- IWL_MVM_REF_INIT_UCODE,
- IWL_MVM_REF_SENDING_CMD,
- IWL_MVM_REF_RX,
-
- /* update debugfs.c when changing this */
-
- IWL_MVM_REF_COUNT,
-};
-
enum iwl_bt_force_ant_mode {
BT_FORCE_ANT_DIS = 0,
BT_FORCE_ANT_AUTO,
@@ -504,6 +472,9 @@ struct iwl_mvm_vif {
/* we can only have 2 GTK + 2 IGTK active at a time */
struct ieee80211_key_conf *ap_early_keys[4];
+
+ /* 26-tone RU OFDMA transmissions should be blocked */
+ bool he_ru_2mhz_block;
};
static inline struct iwl_mvm_vif *
@@ -617,11 +588,6 @@ struct iwl_mvm_frame_stats {
int last_frame_idx;
};
-enum {
- D0I3_DEFER_WAKEUP,
- D0I3_PENDING_WAKEUP,
-};
-
#define IWL_MVM_DEBUG_SET_TEMPERATURE_DISABLE 0xff
#define IWL_MVM_DEBUG_SET_TEMPERATURE_MIN -100
#define IWL_MVM_DEBUG_SET_TEMPERATURE_MAX 200
@@ -695,6 +661,12 @@ struct iwl_mvm_tcm {
* @valid: reordering is valid for this queue
* @lock: protect reorder buffer internal state
* @mvm: mvm pointer, needed for frame timer context
+ * @consec_oldsn_drops: consecutive drops due to old SN
+ * @consec_oldsn_ampdu_gp2: A-MPDU GP2 timestamp to track
+ * when to apply old SN consecutive drop workaround
+ * @consec_oldsn_prev_drop: track whether or not an MPDU
+ * that was single/part of the previous A-MPDU was
+ * dropped due to old SN
*/
struct iwl_mvm_reorder_buffer {
u16 head_sn;
@@ -708,6 +680,9 @@ struct iwl_mvm_reorder_buffer {
bool valid;
spinlock_t lock;
struct iwl_mvm *mvm;
+ unsigned int consec_oldsn_drops;
+ u32 consec_oldsn_ampdu_gp2;
+ unsigned int consec_oldsn_prev_drop:1;
} ____cacheline_aligned_in_smp;
/**
@@ -1011,10 +986,6 @@ struct iwl_mvm {
unsigned long fw_key_table[BITS_TO_LONGS(STA_KEY_MAX_NUM)];
u8 fw_key_deleted[STA_KEY_MAX_NUM];
- /* references taken by the driver and spinlock protecting them */
- spinlock_t refs_lock;
- u8 refs[IWL_MVM_REF_COUNT];
-
u8 vif_count;
struct ieee80211_vif __rcu *vif_id_to_mac[NUM_MAC_INDEX_DRIVER];
@@ -1039,6 +1010,7 @@ struct iwl_mvm {
struct ieee80211_channel **nd_channels;
int n_nd_channels;
bool net_detect;
+ u8 offload_tid;
#ifdef CONFIG_IWLWIFI_DEBUGFS
bool d3_wake_sysassert;
bool d3_test_active;
@@ -1048,17 +1020,6 @@ struct iwl_mvm {
#endif
#endif
- /* d0i3 */
- u8 d0i3_ap_sta_id;
- bool d0i3_offloading;
- struct work_struct d0i3_exit_work;
- struct sk_buff_head d0i3_tx;
- /* protect d0i3_suspend_flags */
- struct mutex d0i3_suspend_mutex;
- unsigned long d0i3_suspend_flags;
- /* sync d0i3_tx queue and IWL_MVM_STATUS_IN_D0I3 status flag */
- spinlock_t d0i3_tx_lock;
- wait_queue_head_t d0i3_exit_waitq;
wait_queue_head_t rx_sync_waitq;
/* BT-Coex */
@@ -1184,6 +1145,8 @@ struct iwl_mvm {
struct iwl_mvm_sar_profile sar_profiles[ACPI_SAR_PROFILE_NUM];
struct iwl_mvm_geo_profile geo_profiles[ACPI_NUM_GEO_PROFILES];
u32 geo_rev;
+ struct iwl_ppag_table_cmd ppag_table;
+ u32 ppag_rev;
#endif
};
@@ -1201,7 +1164,6 @@ struct iwl_mvm {
* @IWL_MVM_STATUS_ROC_RUNNING: remain-on-channel is running
* @IWL_MVM_STATUS_HW_RESTART_REQUESTED: HW restart was requested
* @IWL_MVM_STATUS_IN_HW_RESTART: HW restart is active
- * @IWL_MVM_STATUS_IN_D0I3: NIC is in D0i3
* @IWL_MVM_STATUS_ROC_AUX_RUNNING: AUX remain-on-channel is running
* @IWL_MVM_STATUS_FIRMWARE_RUNNING: firmware is running
* @IWL_MVM_STATUS_NEED_FLUSH_P2P: need to flush P2P bcast STA
@@ -1212,7 +1174,6 @@ enum iwl_mvm_status {
IWL_MVM_STATUS_ROC_RUNNING,
IWL_MVM_STATUS_HW_RESTART_REQUESTED,
IWL_MVM_STATUS_IN_HW_RESTART,
- IWL_MVM_STATUS_IN_D0I3,
IWL_MVM_STATUS_ROC_AUX_RUNNING,
IWL_MVM_STATUS_FIRMWARE_RUNNING,
IWL_MVM_STATUS_NEED_FLUSH_P2P,
@@ -1291,13 +1252,6 @@ iwl_mvm_rcu_dereference_vif_id(struct iwl_mvm *mvm, u8 vif_id, bool rcu)
lockdep_is_held(&mvm->mutex));
}
-static inline bool iwl_mvm_is_d0i3_supported(struct iwl_mvm *mvm)
-{
- return !iwlwifi_mod_params.d0i3_disable &&
- fw_has_capa(&mvm->fw->ucode_capa,
- IWL_UCODE_TLV_CAPA_D0I3_SUPPORT);
-}
-
static inline bool iwl_mvm_is_adaptive_dwell_supported(struct iwl_mvm *mvm)
{
return fw_has_api(&mvm->fw->ucode_capa,
@@ -1333,19 +1287,6 @@ static inline bool iwl_mvm_is_short_beacon_notif_supported(struct iwl_mvm *mvm)
IWL_UCODE_TLV_API_SHORT_BEACON_NOTIF);
}
-static inline bool iwl_mvm_enter_d0i3_on_suspend(struct iwl_mvm *mvm)
-{
- /* For now we only use this mode to differentiate between
- * slave transports, which handle D0i3 entry in suspend by
- * themselves in conjunction with runtime PM D0i3. So, this
- * function is used to check whether we need to do anything
- * when entering suspend or if the transport layer has already
- * done it.
- */
- return (mvm->trans->system_pm_mode == IWL_PLAT_PM_MODE_D0I3) &&
- (mvm->trans->runtime_pm_mode != IWL_PLAT_PM_MODE_D0I3);
-}
-
static inline bool iwl_mvm_is_dqa_data_queue(struct iwl_mvm *mvm, u8 queue)
{
return (queue >= IWL_MVM_DQA_MIN_DATA_QUEUE) &&
@@ -1424,13 +1365,13 @@ static inline bool iwl_mvm_has_new_rx_api(struct iwl_mvm *mvm)
static inline bool iwl_mvm_has_new_tx_api(struct iwl_mvm *mvm)
{
/* TODO - replace with TLV once defined */
- return mvm->trans->cfg->use_tfh;
+ return mvm->trans->trans_cfg->use_tfh;
}
static inline bool iwl_mvm_has_unified_ucode(struct iwl_mvm *mvm)
{
/* TODO - better define this */
- return mvm->trans->cfg->device_family >= IWL_DEVICE_FAMILY_22000;
+ return mvm->trans->trans_cfg->device_family >= IWL_DEVICE_FAMILY_22000;
}
static inline bool iwl_mvm_is_cdb_supported(struct iwl_mvm *mvm)
@@ -1455,7 +1396,13 @@ static inline bool iwl_mvm_cdb_scan_api(struct iwl_mvm *mvm)
* but then there's a little bit of code in scan that won't make
* any sense...
*/
- return mvm->trans->cfg->device_family >= IWL_DEVICE_FAMILY_22000;
+ return mvm->trans->trans_cfg->device_family >= IWL_DEVICE_FAMILY_22000;
+}
+
+static inline bool iwl_mvm_is_scan_ext_chan_supported(struct iwl_mvm *mvm)
+{
+ return fw_has_api(&mvm->fw->ucode_capa,
+ IWL_UCODE_TLV_API_SCAN_EXT_CHAN_VER);
}
static inline bool iwl_mvm_has_new_rx_stats_api(struct iwl_mvm *mvm)
@@ -1487,7 +1434,6 @@ iwl_mvm_get_agg_status(struct iwl_mvm *mvm, void *tx_resp)
static inline bool iwl_mvm_is_tt_in_fw(struct iwl_mvm *mvm)
{
-#ifdef CONFIG_THERMAL
/* these two TLV are redundant since the responsibility to CT-kill by
* FW happens only after we send at least one command of
* temperature THs report.
@@ -1496,9 +1442,6 @@ static inline bool iwl_mvm_is_tt_in_fw(struct iwl_mvm *mvm)
IWL_UCODE_TLV_CAPA_CT_KILL_BY_FW) &&
fw_has_capa(&mvm->fw->ucode_capa,
IWL_UCODE_TLV_CAPA_TEMP_THS_REPORT_SUPPORT);
-#else /* CONFIG_THERMAL */
- return false;
-#endif /* CONFIG_THERMAL */
}
static inline bool iwl_mvm_is_ctdp_supported(struct iwl_mvm *mvm)
@@ -1663,6 +1606,8 @@ void iwl_mvm_rx_monitor_no_data(struct iwl_mvm *mvm, struct napi_struct *napi,
struct iwl_rx_cmd_buffer *rxb, int queue);
void iwl_mvm_rx_frame_release(struct iwl_mvm *mvm, struct napi_struct *napi,
struct iwl_rx_cmd_buffer *rxb, int queue);
+void iwl_mvm_rx_bar_frame_release(struct iwl_mvm *mvm, struct napi_struct *napi,
+ struct iwl_rx_cmd_buffer *rxb, int queue);
int iwl_mvm_notify_rx_queue(struct iwl_mvm *mvm, u32 rxq_mask,
const u8 *data, u32 count, bool async);
void iwl_mvm_rx_queue_notif(struct iwl_mvm *mvm, struct napi_struct *napi,
@@ -1863,30 +1808,9 @@ void iwl_mvm_set_default_unicast_key(struct ieee80211_hw *hw,
extern const struct file_operations iwl_dbgfs_d3_test_ops;
struct iwl_wowlan_status *iwl_mvm_send_wowlan_get_status(struct iwl_mvm *mvm);
#ifdef CONFIG_PM
-int iwl_mvm_wowlan_config_key_params(struct iwl_mvm *mvm,
- struct ieee80211_vif *vif,
- bool host_awake,
- u32 cmd_flags);
-void iwl_mvm_d0i3_update_keys(struct iwl_mvm *mvm,
- struct ieee80211_vif *vif,
- struct iwl_wowlan_status *status);
void iwl_mvm_set_last_nonqos_seq(struct iwl_mvm *mvm,
struct ieee80211_vif *vif);
#else
-static inline int iwl_mvm_wowlan_config_key_params(struct iwl_mvm *mvm,
- struct ieee80211_vif *vif,
- bool host_awake,
- u32 cmd_flags)
-{
- return 0;
-}
-
-static inline void iwl_mvm_d0i3_update_keys(struct iwl_mvm *mvm,
- struct ieee80211_vif *vif,
- struct iwl_wowlan_status *status)
-{
-}
-
static inline void
iwl_mvm_set_last_nonqos_seq(struct iwl_mvm *mvm, struct ieee80211_vif *vif)
{
@@ -1900,19 +1824,6 @@ int iwl_mvm_send_proto_offload(struct iwl_mvm *mvm,
bool offload_ns,
u32 cmd_flags);
-/* D0i3 */
-void iwl_mvm_ref(struct iwl_mvm *mvm, enum iwl_mvm_ref_type ref_type);
-void iwl_mvm_unref(struct iwl_mvm *mvm, enum iwl_mvm_ref_type ref_type);
-int iwl_mvm_ref_sync(struct iwl_mvm *mvm, enum iwl_mvm_ref_type ref_type);
-bool iwl_mvm_ref_taken(struct iwl_mvm *mvm);
-
-#ifdef CONFIG_PM
-void iwl_mvm_d0i3_enable_tx(struct iwl_mvm *mvm, __le16 *qos_seq);
-int iwl_mvm_enter_d0i3(struct iwl_op_mode *op_mode);
-int iwl_mvm_exit_d0i3(struct iwl_op_mode *op_mode);
-int _iwl_mvm_exit_d0i3(struct iwl_mvm *mvm);
-#endif
-
/* BT Coex */
int iwl_mvm_send_bt_init_conf(struct iwl_mvm *mvm);
void iwl_mvm_rx_bt_coex_notif(struct iwl_mvm *mvm,
@@ -1943,9 +1854,6 @@ iwl_mvm_beacon_filter_debugfs_parameters(struct ieee80211_vif *vif,
struct iwl_beacon_filter_cmd *cmd)
{}
#endif
-int iwl_mvm_update_d0i3_power_mode(struct iwl_mvm *mvm,
- struct ieee80211_vif *vif,
- bool enable, u32 flags);
int iwl_mvm_enable_beacon_filter(struct iwl_mvm *mvm,
struct ieee80211_vif *vif,
u32 flags);
@@ -2025,7 +1933,7 @@ void iwl_mvm_vif_set_low_latency(struct iwl_mvm_vif *mvmvif, bool set,
*/
static inline u32 iwl_mvm_flushable_queues(struct iwl_mvm *mvm)
{
- return ((BIT(mvm->cfg->base_params->num_of_queues) - 1) &
+ return ((BIT(mvm->trans->trans_cfg->base_params->num_of_queues) - 1) &
~BIT(IWL_MVM_DQA_CMD_QUEUE));
}
@@ -2034,7 +1942,8 @@ static inline void iwl_mvm_stop_device(struct iwl_mvm *mvm)
lockdep_assert_held(&mvm->mutex);
iwl_fw_cancel_timestamp(&mvm->fwrt);
clear_bit(IWL_MVM_STATUS_FIRMWARE_RUNNING, &mvm->status);
- iwl_fwrt_stop_device(&mvm->fwrt);
+ iwl_fw_dbg_stop_sync(&mvm->fwrt);
+ iwl_trans_stop_device(mvm->trans);
iwl_free_fw_paging(&mvm->fwrt);
iwl_fw_dump_conf_clear(&mvm->fwrt);
}
@@ -2154,6 +2063,7 @@ void iwl_mvm_event_frame_timeout_callback(struct iwl_mvm *mvm,
int iwl_mvm_sar_select_profile(struct iwl_mvm *mvm, int prof_a, int prof_b);
int iwl_mvm_get_sar_geo_profile(struct iwl_mvm *mvm);
+int iwl_mvm_ppag_send_cmd(struct iwl_mvm *mvm);
#ifdef CONFIG_IWLWIFI_DEBUGFS
void iwl_mvm_sta_add_debugfs(struct ieee80211_hw *hw,
struct ieee80211_vif *vif,
diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/nvm.c b/drivers/net/wireless/intel/iwlwifi/mvm/nvm.c
index a9bb43a2f27b..945c1ea5cda8 100644
--- a/drivers/net/wireless/intel/iwlwifi/mvm/nvm.c
+++ b/drivers/net/wireless/intel/iwlwifi/mvm/nvm.c
@@ -249,7 +249,7 @@ static int iwl_nvm_read_section(struct iwl_mvm *mvm, u16 section,
while (ret == length) {
/* Check no memory assumptions fail and cause an overflow */
if ((size_read + offset + length) >
- mvm->cfg->base_params->eeprom_size) {
+ mvm->trans->trans_cfg->base_params->eeprom_size) {
IWL_ERR(mvm, "EEPROM size is too small for NVM\n");
return -ENOBUFS;
}
@@ -372,7 +372,7 @@ int iwl_nvm_init(struct iwl_mvm *mvm)
/* Read From FW NVM */
IWL_DEBUG_EEPROM(mvm->trans->dev, "Read from NVM\n");
- nvm_buffer = kmalloc(mvm->cfg->base_params->eeprom_size,
+ nvm_buffer = kmalloc(mvm->trans->trans_cfg->base_params->eeprom_size,
GFP_KERNEL);
if (!nvm_buffer)
return -ENOMEM;
diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/ops.c b/drivers/net/wireless/intel/iwlwifi/mvm/ops.c
index 4888054dc3d8..3acbd5b7ab4b 100644
--- a/drivers/net/wireless/intel/iwlwifi/mvm/ops.c
+++ b/drivers/net/wireless/intel/iwlwifi/mvm/ops.c
@@ -173,7 +173,7 @@ static void iwl_mvm_nic_config(struct iwl_op_mode *op_mode)
* unrelated errors. Need to further investigate this, but for now
* we'll separate cases.
*/
- if (mvm->trans->cfg->device_family < IWL_DEVICE_FAMILY_8000)
+ if (mvm->trans->trans_cfg->device_family < IWL_DEVICE_FAMILY_8000)
reg_val |= CSR_HW_IF_CONFIG_REG_BIT_RADIO_SI;
if (iwl_fw_dbg_is_d3_debug_enabled(&mvm->fwrt))
@@ -389,6 +389,7 @@ static const struct iwl_hcmd_names iwl_mvm_legacy_names[] = {
HCMD_NAME(SCAN_ITERATION_COMPLETE_UMAC),
HCMD_NAME(REPLY_RX_PHY_CMD),
HCMD_NAME(REPLY_RX_MPDU_CMD),
+ HCMD_NAME(BAR_FRAME_RELEASE),
HCMD_NAME(FRAME_RELEASE),
HCMD_NAME(BA_NOTIF),
HCMD_NAME(MCC_UPDATE_CMD),
@@ -414,6 +415,7 @@ static const struct iwl_hcmd_names iwl_mvm_legacy_names[] = {
HCMD_NAME(SCAN_ITERATION_COMPLETE),
HCMD_NAME(D0I3_END_CMD),
HCMD_NAME(LTR_CONFIG),
+ HCMD_NAME(LDBG_CONFIG_CMD),
};
/* Please keep this array *SORTED* by hex value.
@@ -465,6 +467,8 @@ static const struct iwl_hcmd_names iwl_mvm_data_path_names[] = {
* Access is done through binary search
*/
static const struct iwl_hcmd_names iwl_mvm_debug_names[] = {
+ HCMD_NAME(DBGC_SUSPEND_RESUME),
+ HCMD_NAME(BUFFER_ALLOCATION),
HCMD_NAME(MFU_ASSERT_DUMP_NTF),
};
@@ -514,9 +518,6 @@ static const struct iwl_hcmd_arr iwl_mvm_groups[] = {
/* this forward declaration can avoid to export the function */
static void iwl_mvm_async_handlers_wk(struct work_struct *wk);
-#ifdef CONFIG_PM
-static void iwl_mvm_d0i3_exit_work(struct work_struct *wk);
-#endif
static u32 iwl_mvm_min_backoff(struct iwl_mvm *mvm)
{
@@ -564,23 +565,16 @@ unlock:
static int iwl_mvm_fwrt_dump_start(void *ctx)
{
struct iwl_mvm *mvm = ctx;
- int ret = 0;
mutex_lock(&mvm->mutex);
- ret = iwl_mvm_ref_sync(mvm, IWL_MVM_REF_FW_DBG_COLLECT);
- if (ret)
- mutex_unlock(&mvm->mutex);
-
- return ret;
+ return 0;
}
static void iwl_mvm_fwrt_dump_end(void *ctx)
{
struct iwl_mvm *mvm = ctx;
- iwl_mvm_unref(mvm, IWL_MVM_REF_FW_DBG_COLLECT);
-
mutex_unlock(&mvm->mutex);
}
@@ -672,7 +666,7 @@ iwl_op_mode_mvm_start(struct iwl_trans *trans, const struct iwl_cfg *cfg,
if (iwl_mvm_has_new_rx_api(mvm)) {
op_mode->ops = &iwl_mvm_ops_mq;
trans->rx_mpdu_cmd_hdr_size =
- (trans->cfg->device_family >=
+ (trans->trans_cfg->device_family >=
IWL_DEVICE_FAMILY_22560) ?
sizeof(struct iwl_rx_mpdu_desc) :
IWL_RX_DESC_SIZE_V1;
@@ -700,7 +694,6 @@ iwl_op_mode_mvm_start(struct iwl_trans *trans, const struct iwl_cfg *cfg,
mvm->drop_bcn_ap_mode = true;
mutex_init(&mvm->mutex);
- mutex_init(&mvm->d0i3_suspend_mutex);
spin_lock_init(&mvm->async_handlers_lock);
INIT_LIST_HEAD(&mvm->time_event_list);
INIT_LIST_HEAD(&mvm->aux_roc_te_list);
@@ -710,18 +703,11 @@ iwl_op_mode_mvm_start(struct iwl_trans *trans, const struct iwl_cfg *cfg,
INIT_WORK(&mvm->async_handlers_wk, iwl_mvm_async_handlers_wk);
INIT_WORK(&mvm->roc_done_wk, iwl_mvm_roc_done_wk);
-#ifdef CONFIG_PM
- INIT_WORK(&mvm->d0i3_exit_work, iwl_mvm_d0i3_exit_work);
-#endif
INIT_DELAYED_WORK(&mvm->tdls_cs.dwork, iwl_mvm_tdls_ch_switch_work);
INIT_DELAYED_WORK(&mvm->scan_timeout_dwork, iwl_mvm_scan_timeout_wk);
INIT_WORK(&mvm->add_stream_wk, iwl_mvm_add_new_dqa_stream_wk);
INIT_LIST_HEAD(&mvm->add_stream_txqs);
- spin_lock_init(&mvm->d0i3_tx_lock);
- spin_lock_init(&mvm->refs_lock);
- skb_queue_head_init(&mvm->d0i3_tx);
- init_waitqueue_head(&mvm->d0i3_exit_waitq);
init_waitqueue_head(&mvm->rx_sync_waitq);
atomic_set(&mvm->queue_sync_counter, 0);
@@ -744,7 +730,7 @@ iwl_op_mode_mvm_start(struct iwl_trans *trans, const struct iwl_cfg *cfg,
trans_cfg.no_reclaim_cmds = no_reclaim_cmds;
trans_cfg.n_no_reclaim_cmds = ARRAY_SIZE(no_reclaim_cmds);
- if (mvm->trans->cfg->device_family >= IWL_DEVICE_FAMILY_22560)
+ if (mvm->trans->trans_cfg->device_family >= IWL_DEVICE_FAMILY_22560)
rb_size_default = IWL_AMSDU_2K;
else
rb_size_default = IWL_AMSDU_4K;
@@ -768,12 +754,9 @@ iwl_op_mode_mvm_start(struct iwl_trans *trans, const struct iwl_cfg *cfg,
trans_cfg.rx_buf_size = rb_size_default;
}
- BUILD_BUG_ON(sizeof(struct iwl_ldbg_config_cmd) !=
- LDBG_CFG_COMMAND_SIZE);
-
trans->wide_cmd_header = true;
trans_cfg.bc_table_dword =
- mvm->trans->cfg->device_family < IWL_DEVICE_FAMILY_22560;
+ mvm->trans->trans_cfg->device_family < IWL_DEVICE_FAMILY_22560;
trans_cfg.command_groups = iwl_mvm_groups;
trans_cfg.command_groups_size = ARRAY_SIZE(iwl_mvm_groups);
@@ -832,13 +815,11 @@ iwl_op_mode_mvm_start(struct iwl_trans *trans, const struct iwl_cfg *cfg,
goto out_free;
mutex_lock(&mvm->mutex);
- iwl_mvm_ref(mvm, IWL_MVM_REF_INIT_UCODE);
err = iwl_run_init_mvm_ucode(mvm, true);
if (err && err != -ERFKILL)
iwl_fw_dbg_error_collect(&mvm->fwrt, FW_DBG_TRIGGER_DRIVER);
if (!iwlmvm_mod_params.init_dbg || !err)
iwl_mvm_stop_device(mvm);
- iwl_mvm_unref(mvm, IWL_MVM_REF_INIT_UCODE);
mutex_unlock(&mvm->mutex);
if (err < 0) {
IWL_ERR(mvm, "Failed to run INIT ucode: %d\n", err);
@@ -870,11 +851,6 @@ iwl_op_mode_mvm_start(struct iwl_trans *trans, const struct iwl_cfg *cfg,
else
memset(&mvm->rx_stats, 0, sizeof(struct mvm_statistics_rx));
- /* The transport always starts with a taken reference, we can
- * release it now if d0i3 is supported */
- if (iwl_mvm_is_d0i3_supported(mvm))
- iwl_trans_unref(mvm->trans);
-
iwl_mvm_toggle_tx_ant(mvm, &mvm->mgmt_last_antenna_idx);
return op_mode;
@@ -898,13 +874,6 @@ static void iwl_op_mode_mvm_stop(struct iwl_op_mode *op_mode)
struct iwl_mvm *mvm = IWL_OP_MODE_GET_MVM(op_mode);
int i;
- /* If d0i3 is supported, we have released the reference that
- * the transport started with, so we should take it back now
- * that we are leaving.
- */
- if (iwl_mvm_is_d0i3_supported(mvm))
- iwl_trans_ref(mvm->trans);
-
iwl_mvm_leds_exit(mvm);
iwl_mvm_thermal_exit(mvm);
@@ -931,7 +900,6 @@ static void iwl_op_mode_mvm_stop(struct iwl_op_mode *op_mode)
iwl_fw_runtime_free(&mvm->fwrt);
mutex_destroy(&mvm->mutex);
- mutex_destroy(&mvm->d0i3_suspend_mutex);
ieee80211_free_hw(mvm->hw);
}
@@ -1020,7 +988,10 @@ static void iwl_mvm_rx_common(struct iwl_mvm *mvm,
struct iwl_rx_packet *pkt)
{
int i;
+ union iwl_dbg_tlv_tp_data tp_data = { .fw_pkt = pkt };
+ iwl_dbg_tlv_time_point(&mvm->fwrt,
+ IWL_FW_INI_TIME_POINT_FW_RSP_OR_NOTIF, &tp_data);
iwl_mvm_rx_check_trigger(mvm, pkt);
/*
@@ -1091,6 +1062,8 @@ static void iwl_mvm_rx_mq(struct iwl_op_mode *op_mode,
iwl_mvm_rx_queue_notif(mvm, napi, rxb, 0);
else if (cmd == WIDE_ID(LEGACY_GROUP, FRAME_RELEASE))
iwl_mvm_rx_frame_release(mvm, napi, rxb, 0);
+ else if (cmd == WIDE_ID(LEGACY_GROUP, BAR_FRAME_RELEASE))
+ iwl_mvm_rx_bar_frame_release(mvm, napi, rxb, 0);
else if (cmd == WIDE_ID(DATA_PATH_GROUP, RX_NO_DATA_NOTIF))
iwl_mvm_rx_monitor_no_data(mvm, napi, rxb, 0);
else
@@ -1234,8 +1207,7 @@ static bool iwl_mvm_set_hw_rfkill_state(struct iwl_op_mode *op_mode, bool state)
* Stop the device if we run OPERATIONAL firmware or if we are in the
* middle of the calibrations.
*/
- return state && (mvm->fwrt.cur_fw_img != IWL_UCODE_INIT ||
- rfkill_safe_init_done);
+ return state && rfkill_safe_init_done;
}
static void iwl_mvm_free_skb(struct iwl_op_mode *op_mode, struct sk_buff *skb)
@@ -1267,7 +1239,7 @@ static void iwl_mvm_reprobe_wk(struct work_struct *wk)
void iwl_mvm_nic_restart(struct iwl_mvm *mvm, bool fw_error)
{
iwl_abort_notification_waits(&mvm->notif_wait);
- del_timer(&mvm->fwrt.dump.periodic_trig);
+ iwl_dbg_tlv_del_timers(mvm->trans);
/*
* This is a bit racy, but worst case we tell mac80211 about
@@ -1319,9 +1291,6 @@ void iwl_mvm_nic_restart(struct iwl_mvm *mvm, bool fw_error)
} else if (mvm->fwrt.cur_fw_img == IWL_UCODE_REGULAR &&
mvm->hw_registered &&
!test_bit(STATUS_TRANS_DEAD, &mvm->trans->status)) {
- /* don't let the transport/FW power down */
- iwl_mvm_ref(mvm, IWL_MVM_REF_UCODE_DOWN);
-
if (mvm->fw->ucode_capa.error_log_size) {
u32 src_size = mvm->fw->ucode_capa.error_log_size;
u32 src_addr = mvm->fw->ucode_capa.error_log_addr;
@@ -1363,422 +1332,6 @@ static void iwl_mvm_cmd_queue_full(struct iwl_op_mode *op_mode)
iwl_mvm_nic_restart(mvm, true);
}
-#ifdef CONFIG_PM
-struct iwl_d0i3_iter_data {
- struct iwl_mvm *mvm;
- struct ieee80211_vif *connected_vif;
- u8 ap_sta_id;
- u8 vif_count;
- u8 offloading_tid;
- bool disable_offloading;
-};
-
-static bool iwl_mvm_disallow_offloading(struct iwl_mvm *mvm,
- struct ieee80211_vif *vif,
- struct iwl_d0i3_iter_data *iter_data)
-{
- struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif);
- struct iwl_mvm_sta *mvmsta;
- u32 available_tids = 0;
- u8 tid;
-
- if (WARN_ON(vif->type != NL80211_IFTYPE_STATION ||
- mvmvif->ap_sta_id == IWL_MVM_INVALID_STA))
- return false;
-
- mvmsta = iwl_mvm_sta_from_staid_rcu(mvm, mvmvif->ap_sta_id);
- if (!mvmsta)
- return false;
-
- spin_lock_bh(&mvmsta->lock);
- for (tid = 0; tid < IWL_MAX_TID_COUNT; tid++) {
- struct iwl_mvm_tid_data *tid_data = &mvmsta->tid_data[tid];
-
- /*
- * in case of pending tx packets, don't use this tid
- * for offloading in order to prevent reuse of the same
- * qos seq counters.
- */
- if (iwl_mvm_tid_queued(mvm, tid_data))
- continue;
-
- if (tid_data->state != IWL_AGG_OFF)
- continue;
-
- available_tids |= BIT(tid);
- }
- spin_unlock_bh(&mvmsta->lock);
-
- /*
- * disallow protocol offloading if we have no available tid
- * (with no pending frames and no active aggregation,
- * as we don't handle "holes" properly - the scheduler needs the
- * frame's seq number and TFD index to match)
- */
- if (!available_tids)
- return true;
-
- /* for simplicity, just use the first available tid */
- iter_data->offloading_tid = ffs(available_tids) - 1;
- return false;
-}
-
-static void iwl_mvm_enter_d0i3_iterator(void *_data, u8 *mac,
- struct ieee80211_vif *vif)
-{
- struct iwl_d0i3_iter_data *data = _data;
- struct iwl_mvm *mvm = data->mvm;
- struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif);
- u32 flags = CMD_ASYNC | CMD_HIGH_PRIO | CMD_SEND_IN_IDLE;
-
- IWL_DEBUG_RPM(mvm, "entering D0i3 - vif %pM\n", vif->addr);
- if (vif->type != NL80211_IFTYPE_STATION ||
- !vif->bss_conf.assoc)
- return;
-
- /*
- * in case of pending tx packets or active aggregations,
- * avoid offloading features in order to prevent reuse of
- * the same qos seq counters.
- */
- if (iwl_mvm_disallow_offloading(mvm, vif, data))
- data->disable_offloading = true;
-
- iwl_mvm_update_d0i3_power_mode(mvm, vif, true, flags);
- iwl_mvm_send_proto_offload(mvm, vif, data->disable_offloading,
- false, flags);
-
- /*
- * on init/association, mvm already configures POWER_TABLE_CMD
- * and REPLY_MCAST_FILTER_CMD, so currently don't
- * reconfigure them (we might want to use different
- * params later on, though).
- */
- data->ap_sta_id = mvmvif->ap_sta_id;
- data->vif_count++;
-
- /*
- * no new commands can be sent at this stage, so it's safe
- * to save the vif pointer during d0i3 entrance.
- */
- data->connected_vif = vif;
-}
-
-static void iwl_mvm_set_wowlan_data(struct iwl_mvm *mvm,
- struct iwl_wowlan_config_cmd *cmd,
- struct iwl_d0i3_iter_data *iter_data)
-{
- struct ieee80211_sta *ap_sta;
- struct iwl_mvm_sta *mvm_ap_sta;
-
- if (iter_data->ap_sta_id == IWL_MVM_INVALID_STA)
- return;
-
- rcu_read_lock();
-
- ap_sta = rcu_dereference(mvm->fw_id_to_mac_id[iter_data->ap_sta_id]);
- if (IS_ERR_OR_NULL(ap_sta))
- goto out;
-
- mvm_ap_sta = iwl_mvm_sta_from_mac80211(ap_sta);
- cmd->is_11n_connection = ap_sta->ht_cap.ht_supported;
- cmd->offloading_tid = iter_data->offloading_tid;
- cmd->flags = ENABLE_L3_FILTERING | ENABLE_NBNS_FILTERING |
- ENABLE_DHCP_FILTERING | ENABLE_STORE_BEACON;
- /*
- * The d0i3 uCode takes care of the nonqos counters,
- * so configure only the qos seq ones.
- */
- iwl_mvm_set_wowlan_qos_seq(mvm_ap_sta, cmd);
-out:
- rcu_read_unlock();
-}
-
-int iwl_mvm_enter_d0i3(struct iwl_op_mode *op_mode)
-{
- struct iwl_mvm *mvm = IWL_OP_MODE_GET_MVM(op_mode);
- u32 flags = CMD_ASYNC | CMD_HIGH_PRIO | CMD_SEND_IN_IDLE;
- int ret;
- struct iwl_d0i3_iter_data d0i3_iter_data = {
- .mvm = mvm,
- };
- struct iwl_wowlan_config_cmd wowlan_config_cmd = {
- .wakeup_filter = cpu_to_le32(IWL_WOWLAN_WAKEUP_RX_FRAME |
- IWL_WOWLAN_WAKEUP_BEACON_MISS |
- IWL_WOWLAN_WAKEUP_LINK_CHANGE),
- };
- struct iwl_d3_manager_config d3_cfg_cmd = {
- .min_sleep_time = cpu_to_le32(1000),
- .wakeup_flags = cpu_to_le32(IWL_WAKEUP_D3_CONFIG_FW_ERROR),
- };
-
- IWL_DEBUG_RPM(mvm, "MVM entering D0i3\n");
-
- if (WARN_ON_ONCE(mvm->fwrt.cur_fw_img != IWL_UCODE_REGULAR))
- return -EINVAL;
-
- set_bit(IWL_MVM_STATUS_IN_D0I3, &mvm->status);
-
- /*
- * iwl_mvm_ref_sync takes a reference before checking the flag.
- * so by checking there is no held reference we prevent a state
- * in which iwl_mvm_ref_sync continues successfully while we
- * configure the firmware to enter d0i3
- */
- if (iwl_mvm_ref_taken(mvm)) {
- IWL_DEBUG_RPM(mvm->trans, "abort d0i3 due to taken ref\n");
- clear_bit(IWL_MVM_STATUS_IN_D0I3, &mvm->status);
- wake_up(&mvm->d0i3_exit_waitq);
- return 1;
- }
-
- ieee80211_iterate_active_interfaces_atomic(mvm->hw,
- IEEE80211_IFACE_ITER_NORMAL,
- iwl_mvm_enter_d0i3_iterator,
- &d0i3_iter_data);
- if (d0i3_iter_data.vif_count == 1) {
- mvm->d0i3_ap_sta_id = d0i3_iter_data.ap_sta_id;
- mvm->d0i3_offloading = !d0i3_iter_data.disable_offloading;
- } else {
- WARN_ON_ONCE(d0i3_iter_data.vif_count > 1);
- mvm->d0i3_ap_sta_id = IWL_MVM_INVALID_STA;
- mvm->d0i3_offloading = false;
- }
-
- iwl_mvm_pause_tcm(mvm, true);
- /* make sure we have no running tx while configuring the seqno */
- synchronize_net();
-
- /* Flush the hw queues, in case something got queued during entry */
- /* TODO new tx api */
- if (iwl_mvm_has_new_tx_api(mvm)) {
- WARN_ONCE(1, "d0i3: Need to implement flush TX queue\n");
- } else {
- ret = iwl_mvm_flush_tx_path(mvm, iwl_mvm_flushable_queues(mvm),
- flags);
- if (ret)
- return ret;
- }
-
- /* configure wowlan configuration only if needed */
- if (mvm->d0i3_ap_sta_id != IWL_MVM_INVALID_STA) {
- /* wake on beacons only if beacon storing isn't supported */
- if (!fw_has_capa(&mvm->fw->ucode_capa,
- IWL_UCODE_TLV_CAPA_BEACON_STORING))
- wowlan_config_cmd.wakeup_filter |=
- cpu_to_le32(IWL_WOWLAN_WAKEUP_BCN_FILTERING);
-
- iwl_mvm_wowlan_config_key_params(mvm,
- d0i3_iter_data.connected_vif,
- true, flags);
-
- iwl_mvm_set_wowlan_data(mvm, &wowlan_config_cmd,
- &d0i3_iter_data);
-
- ret = iwl_mvm_send_cmd_pdu(mvm, WOWLAN_CONFIGURATION, flags,
- sizeof(wowlan_config_cmd),
- &wowlan_config_cmd);
- if (ret)
- return ret;
- }
-
- return iwl_mvm_send_cmd_pdu(mvm, D3_CONFIG_CMD,
- flags | CMD_MAKE_TRANS_IDLE,
- sizeof(d3_cfg_cmd), &d3_cfg_cmd);
-}
-
-static void iwl_mvm_exit_d0i3_iterator(void *_data, u8 *mac,
- struct ieee80211_vif *vif)
-{
- struct iwl_mvm *mvm = _data;
- u32 flags = CMD_ASYNC | CMD_HIGH_PRIO;
-
- IWL_DEBUG_RPM(mvm, "exiting D0i3 - vif %pM\n", vif->addr);
- if (vif->type != NL80211_IFTYPE_STATION ||
- !vif->bss_conf.assoc)
- return;
-
- iwl_mvm_update_d0i3_power_mode(mvm, vif, false, flags);
-}
-
-struct iwl_mvm_d0i3_exit_work_iter_data {
- struct iwl_mvm *mvm;
- struct iwl_wowlan_status *status;
- u32 wakeup_reasons;
-};
-
-static void iwl_mvm_d0i3_exit_work_iter(void *_data, u8 *mac,
- struct ieee80211_vif *vif)
-{
- struct iwl_mvm_d0i3_exit_work_iter_data *data = _data;
- struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif);
- u32 reasons = data->wakeup_reasons;
-
- /* consider only the relevant station interface */
- if (vif->type != NL80211_IFTYPE_STATION || !vif->bss_conf.assoc ||
- data->mvm->d0i3_ap_sta_id != mvmvif->ap_sta_id)
- return;
-
- if (reasons & IWL_WOWLAN_WAKEUP_BY_DISCONNECTION_ON_DEAUTH)
- iwl_mvm_connection_loss(data->mvm, vif, "D0i3");
- else if (reasons & IWL_WOWLAN_WAKEUP_BY_DISCONNECTION_ON_MISSED_BEACON)
- ieee80211_beacon_loss(vif);
- else
- iwl_mvm_d0i3_update_keys(data->mvm, vif, data->status);
-}
-
-void iwl_mvm_d0i3_enable_tx(struct iwl_mvm *mvm, __le16 *qos_seq)
-{
- struct ieee80211_sta *sta = NULL;
- struct iwl_mvm_sta *mvm_ap_sta;
- int i;
- bool wake_queues = false;
-
- lockdep_assert_held(&mvm->mutex);
-
- spin_lock_bh(&mvm->d0i3_tx_lock);
-
- if (mvm->d0i3_ap_sta_id == IWL_MVM_INVALID_STA)
- goto out;
-
- IWL_DEBUG_RPM(mvm, "re-enqueue packets\n");
-
- /* get the sta in order to update seq numbers and re-enqueue skbs */
- sta = rcu_dereference_protected(
- mvm->fw_id_to_mac_id[mvm->d0i3_ap_sta_id],
- lockdep_is_held(&mvm->mutex));
-
- if (IS_ERR_OR_NULL(sta)) {
- sta = NULL;
- goto out;
- }
-
- if (mvm->d0i3_offloading && qos_seq) {
- /* update qos seq numbers if offloading was enabled */
- mvm_ap_sta = iwl_mvm_sta_from_mac80211(sta);
- for (i = 0; i < IWL_MAX_TID_COUNT; i++) {
- u16 seq = le16_to_cpu(qos_seq[i]);
- /* firmware stores last-used one, we store next one */
- seq += 0x10;
- mvm_ap_sta->tid_data[i].seq_number = seq;
- }
- }
-out:
- /* re-enqueue (or drop) all packets */
- while (!skb_queue_empty(&mvm->d0i3_tx)) {
- struct sk_buff *skb = __skb_dequeue(&mvm->d0i3_tx);
-
- if (!sta || iwl_mvm_tx_skb(mvm, skb, sta))
- ieee80211_free_txskb(mvm->hw, skb);
-
- /* if the skb_queue is not empty, we need to wake queues */
- wake_queues = true;
- }
- clear_bit(IWL_MVM_STATUS_IN_D0I3, &mvm->status);
- wake_up(&mvm->d0i3_exit_waitq);
- mvm->d0i3_ap_sta_id = IWL_MVM_INVALID_STA;
- if (wake_queues)
- ieee80211_wake_queues(mvm->hw);
-
- spin_unlock_bh(&mvm->d0i3_tx_lock);
-}
-
-static void iwl_mvm_d0i3_exit_work(struct work_struct *wk)
-{
- struct iwl_mvm *mvm = container_of(wk, struct iwl_mvm, d0i3_exit_work);
- struct iwl_mvm_d0i3_exit_work_iter_data iter_data = {
- .mvm = mvm,
- };
-
- struct iwl_wowlan_status *status;
- u32 wakeup_reasons = 0;
- __le16 *qos_seq = NULL;
-
- mutex_lock(&mvm->mutex);
-
- status = iwl_mvm_send_wowlan_get_status(mvm);
- if (IS_ERR_OR_NULL(status)) {
- /* set to NULL so we don't need to check before kfree'ing */
- status = NULL;
- goto out;
- }
-
- wakeup_reasons = le32_to_cpu(status->wakeup_reasons);
- qos_seq = status->qos_seq_ctr;
-
- IWL_DEBUG_RPM(mvm, "wakeup reasons: 0x%x\n", wakeup_reasons);
-
- iter_data.wakeup_reasons = wakeup_reasons;
- iter_data.status = status;
- ieee80211_iterate_active_interfaces(mvm->hw,
- IEEE80211_IFACE_ITER_NORMAL,
- iwl_mvm_d0i3_exit_work_iter,
- &iter_data);
-out:
- iwl_mvm_d0i3_enable_tx(mvm, qos_seq);
-
- IWL_DEBUG_INFO(mvm, "d0i3 exit completed (wakeup reasons: 0x%x)\n",
- wakeup_reasons);
-
- /* qos_seq might point inside resp_pkt, so free it only now */
- kfree(status);
-
- /* the FW might have updated the regdomain */
- iwl_mvm_update_changed_regdom(mvm);
-
- iwl_mvm_resume_tcm(mvm);
- iwl_mvm_unref(mvm, IWL_MVM_REF_EXIT_WORK);
- mutex_unlock(&mvm->mutex);
-}
-
-int _iwl_mvm_exit_d0i3(struct iwl_mvm *mvm)
-{
- u32 flags = CMD_ASYNC | CMD_HIGH_PRIO | CMD_SEND_IN_IDLE |
- CMD_WAKE_UP_TRANS;
- int ret;
-
- IWL_DEBUG_RPM(mvm, "MVM exiting D0i3\n");
-
- if (WARN_ON_ONCE(mvm->fwrt.cur_fw_img != IWL_UCODE_REGULAR))
- return -EINVAL;
-
- mutex_lock(&mvm->d0i3_suspend_mutex);
- if (test_bit(D0I3_DEFER_WAKEUP, &mvm->d0i3_suspend_flags)) {
- IWL_DEBUG_RPM(mvm, "Deferring d0i3 exit until resume\n");
- __set_bit(D0I3_PENDING_WAKEUP, &mvm->d0i3_suspend_flags);
- mutex_unlock(&mvm->d0i3_suspend_mutex);
- return 0;
- }
- mutex_unlock(&mvm->d0i3_suspend_mutex);
-
- ret = iwl_mvm_send_cmd_pdu(mvm, D0I3_END_CMD, flags, 0, NULL);
- if (ret)
- goto out;
-
- ieee80211_iterate_active_interfaces_atomic(mvm->hw,
- IEEE80211_IFACE_ITER_NORMAL,
- iwl_mvm_exit_d0i3_iterator,
- mvm);
-out:
- schedule_work(&mvm->d0i3_exit_work);
- return ret;
-}
-
-int iwl_mvm_exit_d0i3(struct iwl_op_mode *op_mode)
-{
- struct iwl_mvm *mvm = IWL_OP_MODE_GET_MVM(op_mode);
-
- iwl_mvm_ref(mvm, IWL_MVM_REF_EXIT_WORK);
- return _iwl_mvm_exit_d0i3(mvm);
-}
-
-#define IWL_MVM_D0I3_OPS \
- .enter_d0i3 = iwl_mvm_enter_d0i3, \
- .exit_d0i3 = iwl_mvm_exit_d0i3,
-#else /* CONFIG_PM */
-#define IWL_MVM_D0I3_OPS
-#endif /* CONFIG_PM */
-
#define IWL_MVM_COMMON_OPS \
/* these could be differentiated */ \
.async_cb = iwl_mvm_async_cb, \
@@ -1789,7 +1342,6 @@ int iwl_mvm_exit_d0i3(struct iwl_op_mode *op_mode)
.nic_error = iwl_mvm_nic_error, \
.cmd_queue_full = iwl_mvm_cmd_queue_full, \
.nic_config = iwl_mvm_nic_config, \
- IWL_MVM_D0I3_OPS \
/* as we only register one, these MUST be common! */ \
.start = iwl_op_mode_mvm_start, \
.stop = iwl_op_mode_mvm_stop
diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/phy-ctxt.c b/drivers/net/wireless/intel/iwlwifi/mvm/phy-ctxt.c
index 86e40bae57e3..0243dbe8ac49 100644
--- a/drivers/net/wireless/intel/iwlwifi/mvm/phy-ctxt.c
+++ b/drivers/net/wireless/intel/iwlwifi/mvm/phy-ctxt.c
@@ -289,8 +289,17 @@ void iwl_mvm_phy_ctxt_unref(struct iwl_mvm *mvm, struct iwl_mvm_phy_ctxt *ctxt)
if (ctxt->ref == 0) {
struct ieee80211_channel *chan;
struct cfg80211_chan_def chandef;
+ struct ieee80211_supported_band *sband = NULL;
+ enum nl80211_band band = NL80211_BAND_2GHZ;
+
+ while (!sband && band < NUM_NL80211_BANDS)
+ sband = mvm->hw->wiphy->bands[band++];
+
+ if (WARN_ON(!sband))
+ return;
+
+ chan = &sband->channels[0];
- chan = &mvm->hw->wiphy->bands[NL80211_BAND_2GHZ]->channels[0];
cfg80211_chandef_create(&chandef, chan, NL80211_CHAN_NO_HT);
iwl_mvm_phy_ctxt_changed(mvm, ctxt, &chandef, 1, 1);
}
diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/power.c b/drivers/net/wireless/intel/iwlwifi/mvm/power.c
index 36f5fa1ee793..22136e4832ea 100644
--- a/drivers/net/wireless/intel/iwlwifi/mvm/power.c
+++ b/drivers/net/wireless/intel/iwlwifi/mvm/power.c
@@ -127,12 +127,11 @@ int iwl_mvm_beacon_filter_send_cmd(struct iwl_mvm *mvm,
static
void iwl_mvm_beacon_filter_set_cqm_params(struct iwl_mvm *mvm,
struct ieee80211_vif *vif,
- struct iwl_beacon_filter_cmd *cmd,
- bool d0i3)
+ struct iwl_beacon_filter_cmd *cmd)
{
struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif);
- if (vif->bss_conf.cqm_rssi_thold && !d0i3) {
+ if (vif->bss_conf.cqm_rssi_thold) {
cmd->bf_energy_delta =
cpu_to_le32(vif->bss_conf.cqm_rssi_hyst);
/* fw uses an absolute value for this */
@@ -849,8 +848,7 @@ iwl_mvm_beacon_filter_debugfs_parameters(struct ieee80211_vif *vif,
static int _iwl_mvm_enable_beacon_filter(struct iwl_mvm *mvm,
struct ieee80211_vif *vif,
struct iwl_beacon_filter_cmd *cmd,
- u32 cmd_flags,
- bool d0i3)
+ u32 cmd_flags)
{
struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif);
int ret;
@@ -859,13 +857,11 @@ static int _iwl_mvm_enable_beacon_filter(struct iwl_mvm *mvm,
vif->type != NL80211_IFTYPE_STATION || vif->p2p)
return 0;
- iwl_mvm_beacon_filter_set_cqm_params(mvm, vif, cmd, d0i3);
- if (!d0i3)
- iwl_mvm_beacon_filter_debugfs_parameters(vif, cmd);
+ iwl_mvm_beacon_filter_set_cqm_params(mvm, vif, cmd);
+ iwl_mvm_beacon_filter_debugfs_parameters(vif, cmd);
ret = iwl_mvm_beacon_filter_send_cmd(mvm, cmd, cmd_flags);
- /* don't change bf_enabled in case of temporary d0i3 configuration */
- if (!ret && !d0i3)
+ if (!ret)
mvmvif->bf_data.bf_enabled = true;
return ret;
@@ -880,12 +876,12 @@ int iwl_mvm_enable_beacon_filter(struct iwl_mvm *mvm,
.bf_enable_beacon_filter = cpu_to_le32(1),
};
- return _iwl_mvm_enable_beacon_filter(mvm, vif, &cmd, flags, false);
+ return _iwl_mvm_enable_beacon_filter(mvm, vif, &cmd, flags);
}
static int _iwl_mvm_disable_beacon_filter(struct iwl_mvm *mvm,
struct ieee80211_vif *vif,
- u32 flags, bool d0i3)
+ u32 flags)
{
struct iwl_beacon_filter_cmd cmd = {};
struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif);
@@ -896,8 +892,7 @@ static int _iwl_mvm_disable_beacon_filter(struct iwl_mvm *mvm,
ret = iwl_mvm_beacon_filter_send_cmd(mvm, &cmd, flags);
- /* don't change bf_enabled in case of temporary d0i3 configuration */
- if (!ret && !d0i3)
+ if (!ret)
mvmvif->bf_data.bf_enabled = false;
return ret;
@@ -907,7 +902,7 @@ int iwl_mvm_disable_beacon_filter(struct iwl_mvm *mvm,
struct ieee80211_vif *vif,
u32 flags)
{
- return _iwl_mvm_disable_beacon_filter(mvm, vif, flags, false);
+ return _iwl_mvm_disable_beacon_filter(mvm, vif, flags);
}
static int iwl_mvm_power_set_ps(struct iwl_mvm *mvm)
@@ -958,7 +953,7 @@ static int iwl_mvm_power_set_ba(struct iwl_mvm *mvm,
!vif->bss_conf.ps ||
iwl_mvm_vif_low_latency(mvmvif));
- return _iwl_mvm_enable_beacon_filter(mvm, vif, &cmd, 0, false);
+ return _iwl_mvm_enable_beacon_filter(mvm, vif, &cmd, 0);
}
int iwl_mvm_power_update_ps(struct iwl_mvm *mvm)
@@ -1022,58 +1017,3 @@ int iwl_mvm_power_update_mac(struct iwl_mvm *mvm)
return 0;
}
-
-int iwl_mvm_update_d0i3_power_mode(struct iwl_mvm *mvm,
- struct ieee80211_vif *vif,
- bool enable, u32 flags)
-{
- int ret;
- struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif);
- struct iwl_mac_power_cmd cmd = {};
-
- if (vif->type != NL80211_IFTYPE_STATION || vif->p2p)
- return 0;
-
- if (!vif->bss_conf.assoc)
- return 0;
-
- iwl_mvm_power_build_cmd(mvm, vif, &cmd, !enable);
-
- iwl_mvm_power_log(mvm, &cmd);
-#ifdef CONFIG_IWLWIFI_DEBUGFS
- memcpy(&mvmvif->mac_pwr_cmd, &cmd, sizeof(cmd));
-#endif
- ret = iwl_mvm_send_cmd_pdu(mvm, MAC_PM_POWER_TABLE, flags,
- sizeof(cmd), &cmd);
- if (ret)
- return ret;
-
- /* configure beacon filtering */
- if (mvmvif != mvm->bf_allowed_vif)
- return 0;
-
- if (enable) {
- struct iwl_beacon_filter_cmd cmd_bf = {
- IWL_BF_CMD_CONFIG_D0I3,
- .bf_enable_beacon_filter = cpu_to_le32(1),
- };
- /*
- * When beacon storing is supported - disable beacon filtering
- * altogether - the latest beacon will be sent when exiting d0i3
- */
- if (fw_has_capa(&mvm->fw->ucode_capa,
- IWL_UCODE_TLV_CAPA_BEACON_STORING))
- ret = _iwl_mvm_disable_beacon_filter(mvm, vif, flags,
- true);
- else
- ret = _iwl_mvm_enable_beacon_filter(mvm, vif, &cmd_bf,
- flags, true);
- } else {
- if (mvmvif->bf_data.bf_enabled)
- ret = iwl_mvm_enable_beacon_filter(mvm, vif, flags);
- else
- ret = iwl_mvm_disable_beacon_filter(mvm, vif, flags);
- }
-
- return ret;
-}
diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/rs-fw.c b/drivers/net/wireless/intel/iwlwifi/mvm/rs-fw.c
index 08b67812e94e..8f50e2b121bd 100644
--- a/drivers/net/wireless/intel/iwlwifi/mvm/rs-fw.c
+++ b/drivers/net/wireless/intel/iwlwifi/mvm/rs-fw.c
@@ -193,7 +193,7 @@ rs_fw_vht_set_enabled_rates(const struct ieee80211_sta *sta,
int i, highest_mcs;
for (i = 0; i < sta->rx_nss; i++) {
- if (i == MAX_NSS)
+ if (i == IWL_TLC_NSS_MAX)
break;
highest_mcs = rs_fw_vht_highest_rx_mcs_index(vht_cap, i + 1);
@@ -204,9 +204,10 @@ rs_fw_vht_set_enabled_rates(const struct ieee80211_sta *sta,
if (sta->bandwidth == IEEE80211_STA_RX_BW_20)
supp &= ~BIT(IWL_TLC_MNG_HT_RATE_MCS9);
- cmd->ht_rates[i][0] = cpu_to_le16(supp);
+ cmd->ht_rates[i][IWL_TLC_HT_BW_NONE_160] = cpu_to_le16(supp);
if (sta->bandwidth == IEEE80211_STA_RX_BW_160)
- cmd->ht_rates[i][1] = cmd->ht_rates[i][0];
+ cmd->ht_rates[i][IWL_TLC_HT_BW_160] =
+ cmd->ht_rates[i][IWL_TLC_HT_BW_NONE_160];
}
}
@@ -241,7 +242,7 @@ rs_fw_he_set_enabled_rates(const struct ieee80211_sta *sta,
le16_to_cpu(sband->iftype_data->he_cap.he_mcs_nss_supp.tx_mcs_160);
int i;
- for (i = 0; i < sta->rx_nss && i < MAX_NSS; i++) {
+ for (i = 0; i < sta->rx_nss && i < IWL_TLC_NSS_MAX; i++) {
u16 _mcs_160 = (mcs_160 >> (2 * i)) & 0x3;
u16 _mcs_80 = (mcs_80 >> (2 * i)) & 0x3;
u16 _tx_mcs_160 = (tx_mcs_160 >> (2 * i)) & 0x3;
@@ -255,7 +256,7 @@ rs_fw_he_set_enabled_rates(const struct ieee80211_sta *sta,
}
if (_mcs_80 > _tx_mcs_80)
_mcs_80 = _tx_mcs_80;
- cmd->ht_rates[i][0] =
+ cmd->ht_rates[i][IWL_TLC_HT_BW_NONE_160] =
cpu_to_le16(rs_fw_he_ieee80211_mcs_to_rs_mcs(_mcs_80));
/* If one side doesn't support - mark both as not supporting */
@@ -266,7 +267,7 @@ rs_fw_he_set_enabled_rates(const struct ieee80211_sta *sta,
}
if (_mcs_160 > _tx_mcs_160)
_mcs_160 = _tx_mcs_160;
- cmd->ht_rates[i][1] =
+ cmd->ht_rates[i][IWL_TLC_HT_BW_160] =
cpu_to_le16(rs_fw_he_ieee80211_mcs_to_rs_mcs(_mcs_160));
}
}
@@ -300,8 +301,10 @@ static void rs_fw_set_supp_rates(struct ieee80211_sta *sta,
rs_fw_vht_set_enabled_rates(sta, vht_cap, cmd);
} else if (ht_cap->ht_supported) {
cmd->mode = IWL_TLC_MNG_MODE_HT;
- cmd->ht_rates[0][0] = cpu_to_le16(ht_cap->mcs.rx_mask[0]);
- cmd->ht_rates[1][0] = cpu_to_le16(ht_cap->mcs.rx_mask[1]);
+ cmd->ht_rates[IWL_TLC_NSS_1][IWL_TLC_HT_BW_NONE_160] =
+ cpu_to_le16(ht_cap->mcs.rx_mask[0]);
+ cmd->ht_rates[IWL_TLC_NSS_2][IWL_TLC_HT_BW_NONE_160] =
+ cpu_to_le16(ht_cap->mcs.rx_mask[1]);
}
}
diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/rs.c b/drivers/net/wireless/intel/iwlwifi/mvm/rs.c
index d3f04acfbacb..42d525e46e80 100644
--- a/drivers/net/wireless/intel/iwlwifi/mvm/rs.c
+++ b/drivers/net/wireless/intel/iwlwifi/mvm/rs.c
@@ -3079,11 +3079,7 @@ static void __iwl_mvm_rs_tx_status(struct iwl_mvm *mvm,
struct iwl_mvm_sta *mvmsta = iwl_mvm_sta_from_mac80211(sta);
struct iwl_lq_sta *lq_sta = &mvmsta->lq_sta.rs_drv;
- /* Treat uninitialized rate scaling data same as non-existing. */
- if (!lq_sta) {
- IWL_DEBUG_RATE(mvm, "Station rate scaling not created yet.\n");
- return;
- } else if (!lq_sta->pers.drv) {
+ if (!lq_sta->pers.drv) {
IWL_DEBUG_RATE(mvm, "Rate scaling not initialized yet.\n");
return;
}
@@ -3342,7 +3338,7 @@ static void rs_build_rates_table_from_fixed(struct iwl_mvm *mvm,
if (num_of_ant(ant) == 1)
lq_cmd->single_stream_ant_msk = ant;
- if (!mvm->trans->cfg->gen2)
+ if (!mvm->trans->trans_cfg->gen2)
lq_cmd->agg_frame_cnt_limit = LINK_QUAL_AGG_FRAME_LIMIT_DEF;
else
lq_cmd->agg_frame_cnt_limit =
@@ -4127,10 +4123,6 @@ static void rs_drv_add_sta_debugfs(void *mvm, void *priv_sta,
MVM_DEBUGFS_ADD_FILE_RS(ss_force, dir, 0600);
}
-
-void rs_remove_sta_debugfs(void *mvm, void *mvm_sta)
-{
-}
#endif
/*
@@ -4158,7 +4150,6 @@ static const struct rate_control_ops rs_mvm_ops_drv = {
.rate_update = rs_drv_rate_update,
#ifdef CONFIG_MAC80211_DEBUGFS
.add_sta_debugfs = rs_drv_add_sta_debugfs,
- .remove_sta_debugfs = rs_remove_sta_debugfs,
#endif
.capa = RATE_CTRL_CAPA_VHT_EXT_NSS_BW,
};
diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/rx.c b/drivers/net/wireless/intel/iwlwifi/mvm/rx.c
index 160b0db27103..0ad8ed23a455 100644
--- a/drivers/net/wireless/intel/iwlwifi/mvm/rx.c
+++ b/drivers/net/wireless/intel/iwlwifi/mvm/rx.c
@@ -8,6 +8,7 @@
* Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved.
* Copyright(c) 2013 - 2015 Intel Mobile Communications GmbH
* Copyright(c) 2016 - 2017 Intel Deutschland GmbH
+ * Copyright(c) 2018 - 2019 Intel Corporation
*
* 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
@@ -29,6 +30,8 @@
*
* Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved.
* Copyright(c) 2013 - 2015 Intel Mobile Communications GmbH
+ * Copyright(c) 2016 - 2017 Intel Deutschland GmbH
+ * Copyright(c) 2018 - 2019 Intel Corporation
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -349,7 +352,6 @@ void iwl_mvm_rx_rx_mpdu(struct iwl_mvm *mvm, struct napi_struct *napi,
u32 rate_n_flags;
u32 rx_pkt_status;
u8 crypt_len = 0;
- bool take_ref;
phy_info = &mvm->last_phy_info;
rx_res = (struct iwl_rx_mpdu_res_start *)pkt->data;
@@ -557,22 +559,8 @@ void iwl_mvm_rx_rx_mpdu(struct iwl_mvm *mvm, struct napi_struct *napi,
ieee80211_is_probe_resp(hdr->frame_control)))
rx_status->boottime_ns = ktime_get_boottime_ns();
- /* Take a reference briefly to kick off a d0i3 entry delay so
- * we can handle bursts of RX packets without toggling the
- * state too often. But don't do this for beacons if we are
- * going to idle because the beacon filtering changes we make
- * cause the firmware to send us collateral beacons. */
- take_ref = !(test_bit(STATUS_TRANS_GOING_IDLE, &mvm->trans->status) &&
- ieee80211_is_beacon(hdr->frame_control));
-
- if (take_ref)
- iwl_mvm_ref(mvm, IWL_MVM_REF_RX);
-
iwl_mvm_pass_packet_to_mac80211(mvm, sta, napi, skb, hdr, len,
crypt_len, rxb);
-
- if (take_ref)
- iwl_mvm_unref(mvm, IWL_MVM_REF_RX);
}
struct iwl_mvm_stat_data {
diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/rxmq.c b/drivers/net/wireless/intel/iwlwifi/mvm/rxmq.c
index 854edd7d7103..77b03b757193 100644
--- a/drivers/net/wireless/intel/iwlwifi/mvm/rxmq.c
+++ b/drivers/net/wireless/intel/iwlwifi/mvm/rxmq.c
@@ -349,7 +349,7 @@ static int iwl_mvm_rx_crypto(struct iwl_mvm *mvm, struct ieee80211_hdr *hdr,
!(status & IWL_RX_MPDU_RES_STATUS_TTAK_OK))
return 0;
- if (mvm->trans->cfg->gen2 &&
+ if (mvm->trans->trans_cfg->gen2 &&
!(status & RX_MPDU_RES_STATUS_MIC_OK))
stats->flag |= RX_FLAG_MMIC_ERROR;
@@ -366,7 +366,7 @@ static int iwl_mvm_rx_crypto(struct iwl_mvm *mvm, struct ieee80211_hdr *hdr,
if (pkt_flags & FH_RSCSR_RADA_EN) {
stats->flag |= RX_FLAG_ICV_STRIPPED;
- if (mvm->trans->cfg->gen2)
+ if (mvm->trans->trans_cfg->gen2)
stats->flag |= RX_FLAG_MMIC_STRIPPED;
}
@@ -377,8 +377,16 @@ static int iwl_mvm_rx_crypto(struct iwl_mvm *mvm, struct ieee80211_hdr *hdr,
stats->flag |= RX_FLAG_DECRYPTED;
return 0;
default:
- /* Expected in monitor (not having the keys) */
- if (!mvm->monitor_on)
+ /*
+ * Sometimes we can get frames that were not decrypted
+ * because the firmware didn't have the keys yet. This can
+ * happen after connection where we can get multicast frames
+ * before the GTK is installed.
+ * Silently drop those frames.
+ * Also drop un-decrypted frames in monitor mode.
+ */
+ if (!is_multicast_ether_addr(hdr->addr1) &&
+ !mvm->monitor_on && net_ratelimit())
IWL_ERR(mvm, "Unhandled alg: 0x%x\n", status);
}
@@ -781,6 +789,55 @@ void iwl_mvm_rx_queue_notif(struct iwl_mvm *mvm, struct napi_struct *napi,
wake_up(&mvm->rx_sync_waitq);
}
+static void iwl_mvm_oldsn_workaround(struct iwl_mvm *mvm,
+ struct ieee80211_sta *sta, int tid,
+ struct iwl_mvm_reorder_buffer *buffer,
+ u32 reorder, u32 gp2, int queue)
+{
+ struct iwl_mvm_sta *mvmsta = iwl_mvm_sta_from_mac80211(sta);
+
+ if (gp2 != buffer->consec_oldsn_ampdu_gp2) {
+ /* we have a new (A-)MPDU ... */
+
+ /*
+ * reset counter to 0 if we didn't have any oldsn in
+ * the last A-MPDU (as detected by GP2 being identical)
+ */
+ if (!buffer->consec_oldsn_prev_drop)
+ buffer->consec_oldsn_drops = 0;
+
+ /* either way, update our tracking state */
+ buffer->consec_oldsn_ampdu_gp2 = gp2;
+ } else if (buffer->consec_oldsn_prev_drop) {
+ /*
+ * tracking state didn't change, and we had an old SN
+ * indication before - do nothing in this case, we
+ * already noted this one down and are waiting for the
+ * next A-MPDU (by GP2)
+ */
+ return;
+ }
+
+ /* return unless this MPDU has old SN */
+ if (!(reorder & IWL_RX_MPDU_REORDER_BA_OLD_SN))
+ return;
+
+ /* update state */
+ buffer->consec_oldsn_prev_drop = 1;
+ buffer->consec_oldsn_drops++;
+
+ /* if limit is reached, send del BA and reset state */
+ if (buffer->consec_oldsn_drops == IWL_MVM_AMPDU_CONSEC_DROPS_DELBA) {
+ IWL_WARN(mvm,
+ "reached %d old SN frames from %pM on queue %d, stopping BA session on TID %d\n",
+ IWL_MVM_AMPDU_CONSEC_DROPS_DELBA,
+ sta->addr, queue, tid);
+ ieee80211_stop_rx_ba_session(mvmsta->vif, BIT(tid), sta->addr);
+ buffer->consec_oldsn_prev_drop = 0;
+ buffer->consec_oldsn_drops = 0;
+ }
+}
+
/*
* Returns true if the MPDU was buffered\dropped, false if it should be passed
* to upper layer.
@@ -792,6 +849,7 @@ static bool iwl_mvm_reorder(struct iwl_mvm *mvm,
struct sk_buff *skb,
struct iwl_rx_mpdu_desc *desc)
{
+ struct ieee80211_rx_status *rx_status = IEEE80211_SKB_RXCB(skb);
struct ieee80211_hdr *hdr = iwl_mvm_skb_get_hdr(skb);
struct iwl_mvm_sta *mvm_sta;
struct iwl_mvm_baid_data *baid_data;
@@ -894,6 +952,9 @@ static bool iwl_mvm_reorder(struct iwl_mvm *mvm,
min_sn, IWL_MVM_RELEASE_SEND_RSS_SYNC);
}
+ iwl_mvm_oldsn_workaround(mvm, sta, tid, buffer, reorder,
+ rx_status->device_timestamp, queue);
+
/* drop any oudated packets */
if (ieee80211_sn_less(sn, buffer->head_sn))
goto drop;
@@ -1504,7 +1565,7 @@ void iwl_mvm_rx_mpdu_mq(struct iwl_mvm *mvm, struct napi_struct *napi,
if (unlikely(test_bit(IWL_MVM_STATUS_IN_HW_RESTART, &mvm->status)))
return;
- if (mvm->trans->cfg->device_family >= IWL_DEVICE_FAMILY_22560) {
+ if (mvm->trans->trans_cfg->device_family >= IWL_DEVICE_FAMILY_22560) {
rate_n_flags = le32_to_cpu(desc->v3.rate_n_flags);
channel = desc->v3.channel;
gp2_on_air_rise = le32_to_cpu(desc->v3.gp2_on_air_rise);
@@ -1605,7 +1666,8 @@ void iwl_mvm_rx_mpdu_mq(struct iwl_mvm *mvm, struct napi_struct *napi,
if (likely(!(phy_info & IWL_RX_MPDU_PHY_TSF_OVERLOAD))) {
u64 tsf_on_air_rise;
- if (mvm->trans->cfg->device_family >= IWL_DEVICE_FAMILY_22560)
+ if (mvm->trans->trans_cfg->device_family >=
+ IWL_DEVICE_FAMILY_22560)
tsf_on_air_rise = le64_to_cpu(desc->v3.tsf_on_air_rise);
else
tsf_on_air_rise = le64_to_cpu(desc->v1.tsf_on_air_rise);
@@ -1731,7 +1793,7 @@ void iwl_mvm_rx_mpdu_mq(struct iwl_mvm *mvm, struct napi_struct *napi,
*qc &= ~IEEE80211_QOS_CTL_A_MSDU_PRESENT;
- if (mvm->trans->cfg->device_family ==
+ if (mvm->trans->trans_cfg->device_family ==
IWL_DEVICE_FAMILY_9000) {
iwl_mvm_flip_address(hdr->addr3);
@@ -1960,3 +2022,42 @@ void iwl_mvm_rx_frame_release(struct iwl_mvm *mvm, struct napi_struct *napi,
le16_to_cpu(release->nssn),
queue, 0);
}
+
+void iwl_mvm_rx_bar_frame_release(struct iwl_mvm *mvm, struct napi_struct *napi,
+ struct iwl_rx_cmd_buffer *rxb, int queue)
+{
+ struct iwl_rx_packet *pkt = rxb_addr(rxb);
+ struct iwl_bar_frame_release *release = (void *)pkt->data;
+ unsigned int baid = le32_get_bits(release->ba_info,
+ IWL_BAR_FRAME_RELEASE_BAID_MASK);
+ unsigned int nssn = le32_get_bits(release->ba_info,
+ IWL_BAR_FRAME_RELEASE_NSSN_MASK);
+ unsigned int sta_id = le32_get_bits(release->sta_tid,
+ IWL_BAR_FRAME_RELEASE_STA_MASK);
+ unsigned int tid = le32_get_bits(release->sta_tid,
+ IWL_BAR_FRAME_RELEASE_TID_MASK);
+ struct iwl_mvm_baid_data *baid_data;
+
+ if (WARN_ON_ONCE(baid == IWL_RX_REORDER_DATA_INVALID_BAID ||
+ baid >= ARRAY_SIZE(mvm->baid_map)))
+ return;
+
+ rcu_read_lock();
+ baid_data = rcu_dereference(mvm->baid_map[baid]);
+ if (!baid_data) {
+ IWL_DEBUG_RX(mvm,
+ "Got valid BAID %d but not allocated, invalid BAR release!\n",
+ baid);
+ goto out;
+ }
+
+ if (WARN(tid != baid_data->tid || sta_id != baid_data->sta_id,
+ "baid 0x%x is mapped to sta:%d tid:%d, but BAR release received for sta:%d tid:%d\n",
+ baid, baid_data->sta_id, baid_data->tid, sta_id,
+ tid))
+ goto out;
+
+ iwl_mvm_release_frames_from_notif(mvm, napi, baid, nssn, queue, 0);
+out:
+ rcu_read_unlock();
+}
diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/scan.c b/drivers/net/wireless/intel/iwlwifi/mvm/scan.c
index c284e6975b1b..f6b3045badbd 100644
--- a/drivers/net/wireless/intel/iwlwifi/mvm/scan.c
+++ b/drivers/net/wireless/intel/iwlwifi/mvm/scan.c
@@ -77,7 +77,10 @@
#define IWL_SCAN_DWELL_FRAGMENTED 44
#define IWL_SCAN_DWELL_EXTENDED 90
#define IWL_SCAN_NUM_OF_FRAGS 3
+#define IWL_SCAN_LAST_2_4_CHN 14
+#define IWL_SCAN_BAND_5_2 0
+#define IWL_SCAN_BAND_2_4 1
/* adaptive dwell max budget time [TU] for full scan */
#define IWL_SCAN_ADWELL_MAX_BUDGET_FULL_SCAN 300
@@ -512,7 +515,6 @@ void iwl_mvm_rx_lmac_scan_complete_notif(struct iwl_mvm *mvm,
mvm->scan_status &= ~IWL_MVM_SCAN_REGULAR;
ieee80211_scan_completed(mvm->hw, &info);
- iwl_mvm_unref(mvm, IWL_MVM_REF_SCAN);
cancel_delayed_work(&mvm->scan_timeout_dwork);
iwl_mvm_resume_tcm(mvm);
} else {
@@ -957,11 +959,24 @@ static int iwl_mvm_scan_lmac_flags(struct iwl_mvm *mvm,
return flags;
}
+static void
+iwl_mvm_scan_set_legacy_probe_req(struct iwl_scan_probe_req_v1 *p_req,
+ struct iwl_scan_probe_req *src_p_req)
+{
+ int i;
+
+ p_req->mac_header = src_p_req->mac_header;
+ for (i = 0; i < SCAN_NUM_BAND_PROBE_DATA_V_1; i++)
+ p_req->band_data[i] = src_p_req->band_data[i];
+ p_req->common_data = src_p_req->common_data;
+ memcpy(p_req->buf, src_p_req->buf, sizeof(p_req->buf));
+}
+
static int iwl_mvm_scan_lmac(struct iwl_mvm *mvm, struct ieee80211_vif *vif,
struct iwl_mvm_scan_params *params)
{
struct iwl_scan_req_lmac *cmd = mvm->scan_cmd;
- struct iwl_scan_probe_req *preq =
+ struct iwl_scan_probe_req_v1 *preq =
(void *)(cmd->data + sizeof(struct iwl_scan_channel_cfg_lmac) *
mvm->fw->ucode_capa.n_scan_channels);
u32 ssid_bitmap = 0;
@@ -1031,7 +1046,7 @@ static int iwl_mvm_scan_lmac(struct iwl_mvm *mvm, struct ieee80211_vif *vif,
iwl_mvm_lmac_scan_cfg_channels(mvm, params->channels,
params->n_channels, ssid_bitmap, cmd);
- *preq = params->preq;
+ iwl_mvm_scan_set_legacy_probe_req(preq, &params->preq);
return 0;
}
@@ -1205,7 +1220,7 @@ int iwl_mvm_config_scan(struct iwl_mvm *mvm)
cmd_size = sizeof(struct iwl_scan_config);
else
cmd_size = sizeof(struct iwl_scan_config_v1);
- cmd_size += mvm->fw->ucode_capa.n_scan_channels;
+ cmd_size += num_channels;
cfg = kzalloc(cmd_size, GFP_KERNEL);
if (!cfg)
@@ -1385,9 +1400,17 @@ iwl_mvm_umac_scan_cfg_channels(struct iwl_mvm *mvm,
for (i = 0; i < n_channels; i++) {
channel_cfg[i].flags = cpu_to_le32(ssid_bitmap);
- channel_cfg[i].channel_num = channels[i]->hw_value;
- channel_cfg[i].iter_count = 1;
- channel_cfg[i].iter_interval = 0;
+ channel_cfg[i].v1.channel_num = channels[i]->hw_value;
+ if (iwl_mvm_is_scan_ext_chan_supported(mvm)) {
+ channel_cfg[i].v2.band =
+ channels[i]->hw_value <= IWL_SCAN_LAST_2_4_CHN ?
+ IWL_SCAN_BAND_2_4 : IWL_SCAN_BAND_5_2;
+ channel_cfg[i].v2.iter_count = 1;
+ channel_cfg[i].v2.iter_interval = 0;
+ } else {
+ channel_cfg[i].v1.iter_count = 1;
+ channel_cfg[i].v1.iter_interval = 0;
+ }
}
}
@@ -1477,9 +1500,12 @@ static int iwl_mvm_scan_umac(struct iwl_mvm *mvm, struct ieee80211_vif *vif,
struct iwl_scan_req_umac *cmd = mvm->scan_cmd;
struct iwl_scan_umac_chan_param *chan_param;
void *cmd_data = iwl_mvm_get_scan_req_umac_data(mvm);
- struct iwl_scan_req_umac_tail *sec_part = cmd_data +
- sizeof(struct iwl_scan_channel_cfg_umac) *
- mvm->fw->ucode_capa.n_scan_channels;
+ void *sec_part = cmd_data + sizeof(struct iwl_scan_channel_cfg_umac) *
+ mvm->fw->ucode_capa.n_scan_channels;
+ struct iwl_scan_req_umac_tail_v2 *tail_v2 =
+ (struct iwl_scan_req_umac_tail_v2 *)sec_part;
+ struct iwl_scan_req_umac_tail_v1 *tail_v1;
+ struct iwl_ssid_ie *direct_scan;
int uid, i;
u32 ssid_bitmap = 0;
u8 channel_flags = 0;
@@ -1541,18 +1567,12 @@ static int iwl_mvm_scan_umac(struct iwl_mvm *mvm, struct ieee80211_vif *vif,
chan_param->flags = channel_flags;
chan_param->count = params->n_channels;
- iwl_scan_build_ssids(params, sec_part->direct_scan, &ssid_bitmap);
-
- iwl_mvm_umac_scan_cfg_channels(mvm, params->channels,
- params->n_channels, ssid_bitmap,
- cmd_data);
-
for (i = 0; i < params->n_scan_plans; i++) {
struct cfg80211_sched_scan_plan *scan_plan =
&params->scan_plans[i];
- sec_part->schedule[i].iter_count = scan_plan->iterations;
- sec_part->schedule[i].interval =
+ tail_v2->schedule[i].iter_count = scan_plan->iterations;
+ tail_v2->schedule[i].interval =
cpu_to_le16(scan_plan->interval);
}
@@ -1562,12 +1582,24 @@ static int iwl_mvm_scan_umac(struct iwl_mvm *mvm, struct ieee80211_vif *vif,
* For example, when regular scan is requested the driver sets one scan
* plan with one iteration.
*/
- if (!sec_part->schedule[i - 1].iter_count)
- sec_part->schedule[i - 1].iter_count = 0xff;
+ if (!tail_v2->schedule[i - 1].iter_count)
+ tail_v2->schedule[i - 1].iter_count = 0xff;
- sec_part->delay = cpu_to_le16(params->delay);
- sec_part->preq = params->preq;
+ tail_v2->delay = cpu_to_le16(params->delay);
+ if (iwl_mvm_is_scan_ext_chan_supported(mvm)) {
+ tail_v2->preq = params->preq;
+ direct_scan = tail_v2->direct_scan;
+ } else {
+ tail_v1 = (struct iwl_scan_req_umac_tail_v1 *)sec_part;
+ iwl_mvm_scan_set_legacy_probe_req(&tail_v1->preq,
+ &params->preq);
+ direct_scan = tail_v1->direct_scan;
+ }
+ iwl_scan_build_ssids(params, direct_scan, &ssid_bitmap);
+ iwl_mvm_umac_scan_cfg_channels(mvm, params->channels,
+ params->n_channels, ssid_bitmap,
+ cmd_data);
return 0;
}
@@ -1758,7 +1790,6 @@ int iwl_mvm_reg_scan_start(struct iwl_mvm *mvm, struct ieee80211_vif *vif,
IWL_DEBUG_SCAN(mvm, "Scan request was sent successfully\n");
mvm->scan_status |= IWL_MVM_SCAN_REGULAR;
mvm->scan_vif = iwl_mvm_vif_from_mac80211(vif);
- iwl_mvm_ref(mvm, IWL_MVM_REF_SCAN);
schedule_delayed_work(&mvm->scan_timeout_dwork,
msecs_to_jiffies(SCAN_TIMEOUT));
@@ -1884,7 +1915,6 @@ void iwl_mvm_rx_umac_scan_complete_notif(struct iwl_mvm *mvm,
memcpy(info.tsf_bssid, mvm->scan_vif->bssid, ETH_ALEN);
ieee80211_scan_completed(mvm->hw, &info);
mvm->scan_vif = NULL;
- iwl_mvm_unref(mvm, IWL_MVM_REF_SCAN);
cancel_delayed_work(&mvm->scan_timeout_dwork);
iwl_mvm_resume_tcm(mvm);
} else if (mvm->scan_uid_status[uid] == IWL_MVM_SCAN_SCHED) {
@@ -1909,8 +1939,6 @@ void iwl_mvm_rx_umac_scan_complete_notif(struct iwl_mvm *mvm,
mvm->last_ebs_successful = false;
mvm->scan_uid_status[uid] = 0;
-
- iwl_fw_dbg_apply_point(&mvm->fwrt, IWL_FW_INI_APPLY_SCAN_COMPLETE);
}
void iwl_mvm_rx_umac_scan_iter_complete_notif(struct iwl_mvm *mvm,
@@ -1999,6 +2027,7 @@ static int iwl_mvm_scan_stop_wait(struct iwl_mvm *mvm, int type)
int iwl_mvm_scan_size(struct iwl_mvm *mvm)
{
int base_size = IWL_SCAN_REQ_UMAC_SIZE_V1;
+ int tail_size;
if (iwl_mvm_is_adaptive_dwell_v2_supported(mvm))
base_size = IWL_SCAN_REQ_UMAC_SIZE_V8;
@@ -2007,16 +2036,21 @@ int iwl_mvm_scan_size(struct iwl_mvm *mvm)
else if (iwl_mvm_cdb_scan_api(mvm))
base_size = IWL_SCAN_REQ_UMAC_SIZE_V6;
- if (fw_has_capa(&mvm->fw->ucode_capa, IWL_UCODE_TLV_CAPA_UMAC_SCAN))
+ if (fw_has_capa(&mvm->fw->ucode_capa, IWL_UCODE_TLV_CAPA_UMAC_SCAN)) {
+ if (iwl_mvm_is_scan_ext_chan_supported(mvm))
+ tail_size = sizeof(struct iwl_scan_req_umac_tail_v2);
+ else
+ tail_size = sizeof(struct iwl_scan_req_umac_tail_v1);
+
return base_size +
sizeof(struct iwl_scan_channel_cfg_umac) *
mvm->fw->ucode_capa.n_scan_channels +
- sizeof(struct iwl_scan_req_umac_tail);
-
+ tail_size;
+ }
return sizeof(struct iwl_scan_req_lmac) +
sizeof(struct iwl_scan_channel_cfg_lmac) *
mvm->fw->ucode_capa.n_scan_channels +
- sizeof(struct iwl_scan_probe_req);
+ sizeof(struct iwl_scan_probe_req_v1);
}
/*
@@ -2099,10 +2133,6 @@ out:
mvm->scan_status &= ~type;
if (type == IWL_MVM_SCAN_REGULAR) {
- /* Since the rx handler won't do anything now, we have
- * to release the scan reference here.
- */
- iwl_mvm_unref(mvm, IWL_MVM_REF_SCAN);
cancel_delayed_work(&mvm->scan_timeout_dwork);
if (notify) {
struct cfg80211_scan_info info = {
diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/sta.c b/drivers/net/wireless/intel/iwlwifi/mvm/sta.c
index 10f18536dd0d..0bedba4c61f2 100644
--- a/drivers/net/wireless/intel/iwlwifi/mvm/sta.c
+++ b/drivers/net/wireless/intel/iwlwifi/mvm/sta.c
@@ -67,14 +67,6 @@
#include "sta.h"
#include "rs.h"
-static int iwl_mvm_set_fw_key_idx(struct iwl_mvm *mvm);
-
-static int iwl_mvm_send_sta_key(struct iwl_mvm *mvm,
- u32 sta_id,
- struct ieee80211_key_conf *key, bool mcast,
- u32 tkip_iv32, u16 *tkip_p1k, u32 cmd_flags,
- u8 key_offset, bool mfp);
-
/*
* New version of ADD_STA_sta command added new fields at the end of the
* structure, so sending the size of the relevant API's structure is enough to
@@ -1612,7 +1604,7 @@ int iwl_mvm_add_sta(struct iwl_mvm *mvm,
mvm_sta->mac_id_n_color = FW_CMD_ID_AND_COLOR(mvmvif->id,
mvmvif->color);
mvm_sta->vif = vif;
- if (!mvm->trans->cfg->gen2)
+ if (!mvm->trans->trans_cfg->gen2)
mvm_sta->max_agg_bufsize = LINK_QUAL_AGG_FRAME_LIMIT_DEF;
else
mvm_sta->max_agg_bufsize = LINK_QUAL_AGG_FRAME_LIMIT_GEN2_DEF;
@@ -1895,10 +1887,6 @@ int iwl_mvm_rm_sta(struct iwl_mvm *mvm,
/* unassoc - go ahead - remove the AP STA now */
mvmvif->ap_sta_id = IWL_MVM_INVALID_STA;
-
- /* clear d0i3_ap_sta_id if no longer relevant */
- if (mvm->d0i3_ap_sta_id == sta_id)
- mvm->d0i3_ap_sta_id = IWL_MVM_INVALID_STA;
}
/*
@@ -1966,8 +1954,8 @@ static void iwl_mvm_enable_aux_snif_queue(struct iwl_mvm *mvm, u16 *queue,
u8 sta_id, u8 fifo)
{
unsigned int wdg_timeout = iwlmvm_mod_params.tfd_q_hang_detect ?
- mvm->cfg->base_params->wd_timeout :
- IWL_WATCHDOG_DISABLED;
+ mvm->trans->trans_cfg->base_params->wd_timeout :
+ IWL_WATCHDOG_DISABLED;
if (iwl_mvm_has_new_tx_api(mvm)) {
int tvqm_queue =
@@ -2771,13 +2759,6 @@ int iwl_mvm_sta_tx_agg_start(struct iwl_mvm *mvm, struct ieee80211_vif *vif,
spin_lock_bh(&mvmsta->lock);
- /* possible race condition - we entered D0i3 while starting agg */
- if (test_bit(IWL_MVM_STATUS_IN_D0I3, &mvm->status)) {
- spin_unlock_bh(&mvmsta->lock);
- IWL_ERR(mvm, "Entered D0i3 while starting Tx agg\n");
- return -EIO;
- }
-
/*
* Note the possible cases:
* 1. An enabled TXQ - TXQ needs to become agg'ed
@@ -2832,7 +2813,7 @@ int iwl_mvm_sta_tx_agg_start(struct iwl_mvm *mvm, struct ieee80211_vif *vif,
* to align the wrap around of ssn so we compare relevant values.
*/
normalized_ssn = tid_data->ssn;
- if (mvm->trans->cfg->gen2)
+ if (mvm->trans->trans_cfg->gen2)
normalized_ssn &= 0xff;
if (normalized_ssn == tid_data->next_reclaimed) {
@@ -3872,7 +3853,7 @@ u16 iwl_mvm_tid_queued(struct iwl_mvm *mvm, struct iwl_mvm_tid_data *tid_data)
* In 22000 HW, the next_reclaimed index is only 8 bit, so we'll need
* to align the wrap around of ssn so we compare relevant values.
*/
- if (mvm->trans->cfg->gen2)
+ if (mvm->trans->trans_cfg->gen2)
sn &= 0xff;
return ieee80211_sn_sub(sn, tid_data->next_reclaimed);
diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/tdls.c b/drivers/net/wireless/intel/iwlwifi/mvm/tdls.c
index 9df21a8d1fc1..1851719e9f4b 100644
--- a/drivers/net/wireless/intel/iwlwifi/mvm/tdls.c
+++ b/drivers/net/wireless/intel/iwlwifi/mvm/tdls.c
@@ -205,19 +205,10 @@ void iwl_mvm_mac_mgd_protect_tdls_discover(struct ieee80211_hw *hw,
struct iwl_mvm *mvm = IWL_MAC80211_GET_MVM(hw);
u32 duration = 2 * vif->bss_conf.dtim_period * vif->bss_conf.beacon_int;
- /*
- * iwl_mvm_protect_session() reads directly from the device
- * (the system time), so make sure it is available.
- */
- if (iwl_mvm_ref_sync(mvm, IWL_MVM_REF_PROTECT_TDLS))
- return;
-
mutex_lock(&mvm->mutex);
/* Protect the session to hear the TDLS setup response on the channel */
iwl_mvm_protect_session(mvm, vif, duration, duration, 100, true);
mutex_unlock(&mvm->mutex);
-
- iwl_mvm_unref(mvm, IWL_MVM_REF_PROTECT_TDLS);
}
static const char *
diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/time-event.c b/drivers/net/wireless/intel/iwlwifi/mvm/time-event.c
index 4d34e5ab1bff..a06bc63fb516 100644
--- a/drivers/net/wireless/intel/iwlwifi/mvm/time-event.c
+++ b/drivers/net/wireless/intel/iwlwifi/mvm/time-event.c
@@ -106,10 +106,8 @@ void iwl_mvm_roc_done_wk(struct work_struct *wk)
* in the case that the time event actually completed in the firmware
* (which is handled in iwl_mvm_te_handle_notif).
*/
- if (test_and_clear_bit(IWL_MVM_STATUS_ROC_RUNNING, &mvm->status))
- iwl_mvm_unref(mvm, IWL_MVM_REF_ROC);
- if (test_and_clear_bit(IWL_MVM_STATUS_ROC_AUX_RUNNING, &mvm->status))
- iwl_mvm_unref(mvm, IWL_MVM_REF_ROC_AUX);
+ clear_bit(IWL_MVM_STATUS_ROC_RUNNING, &mvm->status);
+ clear_bit(IWL_MVM_STATUS_ROC_AUX_RUNNING, &mvm->status);
synchronize_net();
@@ -357,7 +355,6 @@ static void iwl_mvm_te_handle_notif(struct iwl_mvm *mvm,
if (te_data->vif->type == NL80211_IFTYPE_P2P_DEVICE) {
set_bit(IWL_MVM_STATUS_ROC_RUNNING, &mvm->status);
- iwl_mvm_ref(mvm, IWL_MVM_REF_ROC);
ieee80211_ready_on_channel(mvm->hw);
} else if (te_data->id == TE_CHANNEL_SWITCH_PERIOD) {
iwl_mvm_te_handle_notify_csa(mvm, te_data, notif);
@@ -405,7 +402,6 @@ static int iwl_mvm_aux_roc_te_handle_notif(struct iwl_mvm *mvm,
} else if (le32_to_cpu(notif->action) == TE_V2_NOTIF_HOST_EVENT_START) {
set_bit(IWL_MVM_STATUS_ROC_AUX_RUNNING, &mvm->status);
te_data->running = true;
- iwl_mvm_ref(mvm, IWL_MVM_REF_ROC_AUX);
ieee80211_ready_on_channel(mvm->hw); /* Start TE */
} else {
IWL_DEBUG_TE(mvm,
diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/tt.c b/drivers/net/wireless/intel/iwlwifi/mvm/tt.c
index 0b3e5c99d316..f0c539b37ea7 100644
--- a/drivers/net/wireless/intel/iwlwifi/mvm/tt.c
+++ b/drivers/net/wireless/intel/iwlwifi/mvm/tt.c
@@ -5,7 +5,7 @@
*
* GPL LICENSE SUMMARY
*
- * Copyright(c) 2013 - 2014 Intel Corporation. All rights reserved.
+ * Copyright(c) 2013 - 2014, 2019 Intel Corporation. All rights reserved.
* Copyright(c) 2013 - 2014 Intel Mobile Communications GmbH
* Copyright(c) 2015 - 2016 Intel Deutschland GmbH
*
@@ -27,7 +27,7 @@
*
* BSD LICENSE
*
- * Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved.
+ * Copyright(c) 2012 - 2014, 2019 Intel Corporation. All rights reserved.
* Copyright(c) 2013 - 2014 Intel Mobile Communications GmbH
* Copyright(c) 2015 - 2016 Intel Deutschland GmbH
* All rights reserved.
@@ -298,16 +298,8 @@ static void check_exit_ctkill(struct work_struct *work)
if (__iwl_mvm_mac_start(mvm))
goto reschedule;
- /* make sure the device is available for direct read/writes */
- if (iwl_mvm_ref_sync(mvm, IWL_MVM_REF_CHECK_CTKILL)) {
- __iwl_mvm_mac_stop(mvm);
- goto reschedule;
- }
-
ret = iwl_mvm_get_temp(mvm, &temp);
- iwl_mvm_unref(mvm, IWL_MVM_REF_CHECK_CTKILL);
-
__iwl_mvm_mac_stop(mvm);
if (ret)
@@ -563,16 +555,19 @@ static int compare_temps(const void *a, const void *b)
return ((s16)le16_to_cpu(*(__le16 *)a) -
(s16)le16_to_cpu(*(__le16 *)b));
}
+#endif
int iwl_mvm_send_temp_report_ths_cmd(struct iwl_mvm *mvm)
{
struct temp_report_ths_cmd cmd = {0};
- int ret, i, j, idx = 0;
+ int ret;
+#ifdef CONFIG_THERMAL
+ int i, j, idx = 0;
lockdep_assert_held(&mvm->mutex);
if (!mvm->tz_device.tzone)
- return -EINVAL;
+ goto send;
/* The driver holds array of temperature trips that are unsorted
* and uncompressed, the FW should get it compressed and sorted
@@ -605,6 +600,7 @@ int iwl_mvm_send_temp_report_ths_cmd(struct iwl_mvm *mvm)
}
send:
+#endif
ret = iwl_mvm_send_cmd_pdu(mvm, WIDE_ID(PHY_OPS_GROUP,
TEMP_REPORTING_THRESHOLDS_CMD),
0, sizeof(cmd), &cmd);
@@ -615,6 +611,7 @@ send:
return ret;
}
+#ifdef CONFIG_THERMAL
static int iwl_mvm_tzone_get_temp(struct thermal_zone_device *device,
int *temperature)
{
diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/tx.c b/drivers/net/wireless/intel/iwlwifi/mvm/tx.c
index 6ac114a393cc..8a059da7a1fa 100644
--- a/drivers/net/wireless/intel/iwlwifi/mvm/tx.c
+++ b/drivers/net/wireless/intel/iwlwifi/mvm/tx.c
@@ -546,7 +546,7 @@ iwl_mvm_set_tx_params(struct iwl_mvm *mvm, struct sk_buff *skb,
hdr->frame_control);
}
- if (mvm->trans->cfg->device_family >=
+ if (mvm->trans->trans_cfg->device_family >=
IWL_DEVICE_FAMILY_22560) {
struct iwl_tx_cmd_gen3 *cmd = (void *)dev_cmd->payload;
@@ -1169,8 +1169,9 @@ static int iwl_mvm_tx_mpdu(struct iwl_mvm *mvm, struct sk_buff *skb,
schedule_work(&mvm->add_stream_wk);
}
- IWL_DEBUG_TX(mvm, "TX to [%d|%d] Q:%d - seq: 0x%x\n", mvmsta->sta_id,
- tid, txq_id, IEEE80211_SEQ_TO_SN(seq_number));
+ IWL_DEBUG_TX(mvm, "TX to [%d|%d] Q:%d - seq: 0x%x len %d\n",
+ mvmsta->sta_id, tid, txq_id,
+ IEEE80211_SEQ_TO_SN(seq_number), skb->len);
/* From now on, we cannot access info->control */
iwl_mvm_skb_prepare_status(skb, dev_cmd);
@@ -1271,7 +1272,7 @@ static void iwl_mvm_check_ratid_empty(struct iwl_mvm *mvm,
* to align the wrap around of ssn so we compare relevant values.
*/
normalized_ssn = tid_data->ssn;
- if (mvm->trans->cfg->gen2)
+ if (mvm->trans->trans_cfg->gen2)
normalized_ssn &= 0xff;
if (normalized_ssn != tid_data->next_reclaimed)
diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/utils.c b/drivers/net/wireless/intel/iwlwifi/mvm/utils.c
index b8e20a01c192..8686107da116 100644
--- a/drivers/net/wireless/intel/iwlwifi/mvm/utils.c
+++ b/drivers/net/wireless/intel/iwlwifi/mvm/utils.c
@@ -88,17 +88,11 @@ int iwl_mvm_send_cmd(struct iwl_mvm *mvm, struct iwl_host_cmd *cmd)
* the mutex, this ensures we don't try to send two
* (or more) synchronous commands at a time.
*/
- if (!(cmd->flags & CMD_ASYNC)) {
+ if (!(cmd->flags & CMD_ASYNC))
lockdep_assert_held(&mvm->mutex);
- if (!(cmd->flags & CMD_SEND_IN_IDLE))
- iwl_mvm_ref(mvm, IWL_MVM_REF_SENDING_CMD);
- }
ret = iwl_trans_send_cmd(mvm->trans, cmd);
- if (!(cmd->flags & (CMD_ASYNC | CMD_SEND_IN_IDLE)))
- iwl_mvm_unref(mvm, IWL_MVM_REF_SENDING_CMD);
-
/*
* If the caller wants the SKB, then don't hide any problems, the
* caller might access the response buffer which will be NULL if
@@ -537,7 +531,7 @@ static void iwl_mvm_dump_lmac_error_log(struct iwl_mvm *mvm, u8 lmac_num)
/* reset the device */
iwl_trans_sw_reset(trans);
- err = iwl_finish_nic_init(trans);
+ err = iwl_finish_nic_init(trans, trans->trans_cfg);
if (err)
return;
}
@@ -945,8 +939,9 @@ unsigned int iwl_mvm_get_wd_timeout(struct iwl_mvm *mvm,
{
struct iwl_fw_dbg_trigger_tlv *trigger;
struct iwl_fw_dbg_trigger_txq_timer *txq_timer;
- unsigned int default_timeout =
- cmd_q ? IWL_DEF_WD_TIMEOUT : mvm->cfg->base_params->wd_timeout;
+ unsigned int default_timeout = cmd_q ?
+ IWL_DEF_WD_TIMEOUT :
+ mvm->trans->trans_cfg->base_params->wd_timeout;
if (!iwl_fw_dbg_trigger_enabled(mvm->fw, FW_DBG_TRIGGER_TXQ_TIMERS)) {
/*
@@ -990,7 +985,7 @@ unsigned int iwl_mvm_get_wd_timeout(struct iwl_mvm *mvm,
return default_timeout;
default:
WARN_ON(1);
- return mvm->cfg->base_params->wd_timeout;
+ return mvm->trans->trans_cfg->base_params->wd_timeout;
}
}
@@ -1436,7 +1431,7 @@ u32 iwl_mvm_get_systime(struct iwl_mvm *mvm)
{
u32 reg_addr = DEVICE_SYSTEM_TIME_REG;
- if (mvm->trans->cfg->device_family >= IWL_DEVICE_FAMILY_22000 &&
+ if (mvm->trans->trans_cfg->device_family >= IWL_DEVICE_FAMILY_22000 &&
mvm->trans->cfg->gp2_reg_addr)
reg_addr = mvm->trans->cfg->gp2_reg_addr;
diff --git a/drivers/net/wireless/intel/iwlwifi/pcie/ctxt-info-gen3.c b/drivers/net/wireless/intel/iwlwifi/pcie/ctxt-info-gen3.c
index 5e86783d616b..74980382e64c 100644
--- a/drivers/net/wireless/intel/iwlwifi/pcie/ctxt-info-gen3.c
+++ b/drivers/net/wireless/intel/iwlwifi/pcie/ctxt-info-gen3.c
@@ -96,7 +96,7 @@ int iwl_pcie_ctxt_info_gen3_init(struct iwl_trans *trans,
cpu_to_le64(trans_pcie->rxq->bd_dma);
/* Configure debug, for integration */
- if (!trans->dbg.ini_valid)
+ if (!iwl_trans_dbg_ini_valid(trans))
iwl_pcie_alloc_fw_monitor(trans, 0);
if (trans->dbg.num_blocks) {
prph_sc_ctrl->hwm_cfg.hwm_base_addr =
@@ -107,13 +107,9 @@ int iwl_pcie_ctxt_info_gen3_init(struct iwl_trans *trans,
/* allocate ucode sections in dram and set addresses */
ret = iwl_pcie_init_fw_sec(trans, fw, &prph_scratch->dram);
- if (ret) {
- dma_free_coherent(trans->dev,
- sizeof(*prph_scratch),
- prph_scratch,
- trans_pcie->prph_scratch_dma_addr);
- return ret;
- }
+ if (ret)
+ goto err_free_prph_scratch;
+
/* Allocate prph information
* currently we don't assign to the prph info anything, but it would get
@@ -121,16 +117,20 @@ int iwl_pcie_ctxt_info_gen3_init(struct iwl_trans *trans,
prph_info = dma_alloc_coherent(trans->dev, sizeof(*prph_info),
&trans_pcie->prph_info_dma_addr,
GFP_KERNEL);
- if (!prph_info)
- return -ENOMEM;
+ if (!prph_info) {
+ ret = -ENOMEM;
+ goto err_free_prph_scratch;
+ }
/* Allocate context info */
ctxt_info_gen3 = dma_alloc_coherent(trans->dev,
sizeof(*ctxt_info_gen3),
&trans_pcie->ctxt_info_dma_addr,
GFP_KERNEL);
- if (!ctxt_info_gen3)
- return -ENOMEM;
+ if (!ctxt_info_gen3) {
+ ret = -ENOMEM;
+ goto err_free_prph_info;
+ }
ctxt_info_gen3->prph_info_base_addr =
cpu_to_le64(trans_pcie->prph_info_dma_addr);
@@ -180,12 +180,26 @@ int iwl_pcie_ctxt_info_gen3_init(struct iwl_trans *trans,
iwl_set_bit(trans, CSR_CTXT_INFO_BOOT_CTRL,
CSR_AUTO_FUNC_BOOT_ENA);
- if (trans->cfg->device_family >= IWL_DEVICE_FAMILY_AX210)
+ if (trans->trans_cfg->device_family >= IWL_DEVICE_FAMILY_AX210)
iwl_write_umac_prph(trans, UREG_CPU_INIT_RUN, 1);
else
iwl_set_bit(trans, CSR_GP_CNTRL, CSR_AUTO_FUNC_INIT);
return 0;
+
+err_free_prph_info:
+ dma_free_coherent(trans->dev,
+ sizeof(*prph_info),
+ prph_info,
+ trans_pcie->prph_info_dma_addr);
+
+err_free_prph_scratch:
+ dma_free_coherent(trans->dev,
+ sizeof(*prph_scratch),
+ prph_scratch,
+ trans_pcie->prph_scratch_dma_addr);
+ return ret;
+
}
void iwl_pcie_ctxt_info_gen3_free(struct iwl_trans *trans)
diff --git a/drivers/net/wireless/intel/iwlwifi/pcie/drv.c b/drivers/net/wireless/intel/iwlwifi/pcie/drv.c
index de711c1160d3..6f4bb7ce71a5 100644
--- a/drivers/net/wireless/intel/iwlwifi/pcie/drv.c
+++ b/drivers/net/wireless/intel/iwlwifi/pcie/drv.c
@@ -65,7 +65,6 @@
#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
#include <linux/module.h>
-#include <linux/pm_runtime.h>
#include <linux/pci.h>
#include <linux/acpi.h>
@@ -73,6 +72,7 @@
#include "iwl-trans.h"
#include "iwl-drv.h"
+#include "iwl-prph.h"
#include "internal.h"
#define IWL_PCI_DEVICE(dev, subdev, cfg) \
@@ -513,31 +513,33 @@ static const struct pci_device_id iwl_hw_card_ids[] = {
{IWL_PCI_DEVICE(0x24FD, 0x9074, iwl8265_2ac_cfg)},
/* 9000 Series */
- {IWL_PCI_DEVICE(0x02F0, 0x0030, iwl9560_2ac_160_cfg_quz_a0_jf_b0_soc)},
- {IWL_PCI_DEVICE(0x02F0, 0x0034, iwl9560_2ac_cfg_quz_a0_jf_b0_soc)},
- {IWL_PCI_DEVICE(0x02F0, 0x0038, iwl9560_2ac_160_cfg_quz_a0_jf_b0_soc)},
- {IWL_PCI_DEVICE(0x02F0, 0x003C, iwl9560_2ac_160_cfg_quz_a0_jf_b0_soc)},
- {IWL_PCI_DEVICE(0x02F0, 0x0060, iwl9461_2ac_cfg_quz_a0_jf_b0_soc)},
- {IWL_PCI_DEVICE(0x02F0, 0x0064, iwl9461_2ac_cfg_quz_a0_jf_b0_soc)},
- {IWL_PCI_DEVICE(0x02F0, 0x00A0, iwl9462_2ac_cfg_quz_a0_jf_b0_soc)},
- {IWL_PCI_DEVICE(0x02F0, 0x00A4, iwl9462_2ac_cfg_quz_a0_jf_b0_soc)},
- {IWL_PCI_DEVICE(0x02F0, 0x0230, iwl9560_2ac_cfg_quz_a0_jf_b0_soc)},
- {IWL_PCI_DEVICE(0x02F0, 0x0234, iwl9560_2ac_cfg_quz_a0_jf_b0_soc)},
- {IWL_PCI_DEVICE(0x02F0, 0x0238, iwl9560_2ac_cfg_quz_a0_jf_b0_soc)},
- {IWL_PCI_DEVICE(0x02F0, 0x023C, iwl9560_2ac_cfg_quz_a0_jf_b0_soc)},
- {IWL_PCI_DEVICE(0x02F0, 0x0260, iwl9461_2ac_cfg_quz_a0_jf_b0_soc)},
- {IWL_PCI_DEVICE(0x02F0, 0x0264, iwl9461_2ac_cfg_quz_a0_jf_b0_soc)},
- {IWL_PCI_DEVICE(0x02F0, 0x02A0, iwl9462_2ac_cfg_quz_a0_jf_b0_soc)},
- {IWL_PCI_DEVICE(0x02F0, 0x02A4, iwl9462_2ac_cfg_quz_a0_jf_b0_soc)},
- {IWL_PCI_DEVICE(0x02F0, 0x1551, iwl9560_killer_s_2ac_cfg_quz_a0_jf_b0_soc)},
- {IWL_PCI_DEVICE(0x02F0, 0x1552, iwl9560_killer_i_2ac_cfg_quz_a0_jf_b0_soc)},
- {IWL_PCI_DEVICE(0x02F0, 0x2030, iwl9560_2ac_160_cfg_quz_a0_jf_b0_soc)},
- {IWL_PCI_DEVICE(0x02F0, 0x2034, iwl9560_2ac_160_cfg_quz_a0_jf_b0_soc)},
- {IWL_PCI_DEVICE(0x02F0, 0x4030, iwl9560_2ac_160_cfg_quz_a0_jf_b0_soc)},
- {IWL_PCI_DEVICE(0x02F0, 0x4034, iwl9560_2ac_160_cfg_quz_a0_jf_b0_soc)},
- {IWL_PCI_DEVICE(0x02F0, 0x40A4, iwl9462_2ac_cfg_quz_a0_jf_b0_soc)},
- {IWL_PCI_DEVICE(0x02F0, 0x4234, iwl9560_2ac_cfg_quz_a0_jf_b0_soc)},
- {IWL_PCI_DEVICE(0x02F0, 0x42A4, iwl9462_2ac_cfg_quz_a0_jf_b0_soc)},
+ {IWL_PCI_DEVICE(0x02F0, 0x0030, iwl9560_2ac_160_cfg_qu_b0_jf_b0)},
+ {IWL_PCI_DEVICE(0x02F0, 0x0034, iwl9560_2ac_cfg_qu_b0_jf_b0)},
+ {IWL_PCI_DEVICE(0x02F0, 0x0038, iwl9560_2ac_160_cfg_qu_b0_jf_b0)},
+ {IWL_PCI_DEVICE(0x02F0, 0x003C, iwl9560_2ac_160_cfg_qu_b0_jf_b0)},
+ {IWL_PCI_DEVICE(0x02F0, 0x0060, iwl9461_2ac_cfg_qu_b0_jf_b0)},
+ {IWL_PCI_DEVICE(0x02F0, 0x0064, iwl9461_2ac_cfg_qu_b0_jf_b0)},
+ {IWL_PCI_DEVICE(0x02F0, 0x00A0, iwl9462_2ac_cfg_qu_b0_jf_b0)},
+ {IWL_PCI_DEVICE(0x02F0, 0x00A4, iwl9462_2ac_cfg_qu_b0_jf_b0)},
+ {IWL_PCI_DEVICE(0x02F0, 0x0230, iwl9560_2ac_cfg_qu_b0_jf_b0)},
+ {IWL_PCI_DEVICE(0x02F0, 0x0234, iwl9560_2ac_cfg_qu_b0_jf_b0)},
+ {IWL_PCI_DEVICE(0x02F0, 0x0238, iwl9560_2ac_cfg_qu_b0_jf_b0)},
+ {IWL_PCI_DEVICE(0x02F0, 0x023C, iwl9560_2ac_cfg_qu_b0_jf_b0)},
+ {IWL_PCI_DEVICE(0x02F0, 0x0260, iwl9461_2ac_cfg_qu_b0_jf_b0)},
+ {IWL_PCI_DEVICE(0x02F0, 0x0264, iwl9461_2ac_cfg_qu_b0_jf_b0)},
+ {IWL_PCI_DEVICE(0x02F0, 0x02A0, iwl9462_2ac_cfg_qu_b0_jf_b0)},
+ {IWL_PCI_DEVICE(0x02F0, 0x02A4, iwl9462_2ac_cfg_qu_b0_jf_b0)},
+ {IWL_PCI_DEVICE(0x02F0, 0x1030, iwl9560_2ac_cfg_qu_b0_jf_b0)},
+ {IWL_PCI_DEVICE(0x02F0, 0x1551, killer1550s_2ac_cfg_qu_b0_jf_b0)},
+ {IWL_PCI_DEVICE(0x02F0, 0x1552, killer1550i_2ac_cfg_qu_b0_jf_b0)},
+ {IWL_PCI_DEVICE(0x02F0, 0x2030, iwl9560_2ac_160_cfg_qu_b0_jf_b0)},
+ {IWL_PCI_DEVICE(0x02F0, 0x2034, iwl9560_2ac_160_cfg_qu_b0_jf_b0)},
+ {IWL_PCI_DEVICE(0x02F0, 0x4030, iwl9560_2ac_160_cfg_qu_b0_jf_b0)},
+ {IWL_PCI_DEVICE(0x02F0, 0x4034, iwl9560_2ac_160_cfg_qu_b0_jf_b0)},
+ {IWL_PCI_DEVICE(0x02F0, 0x40A4, iwl9462_2ac_cfg_qu_b0_jf_b0)},
+ {IWL_PCI_DEVICE(0x02F0, 0x4234, iwl9560_2ac_cfg_qu_b0_jf_b0)},
+ {IWL_PCI_DEVICE(0x02F0, 0x42A4, iwl9462_2ac_cfg_qu_b0_jf_b0)},
+
{IWL_PCI_DEVICE(0x06F0, 0x0030, iwl9560_2ac_160_cfg_quz_a0_jf_b0_soc)},
{IWL_PCI_DEVICE(0x06F0, 0x0034, iwl9560_2ac_cfg_quz_a0_jf_b0_soc)},
{IWL_PCI_DEVICE(0x06F0, 0x0038, iwl9560_2ac_160_cfg_quz_a0_jf_b0_soc)},
@@ -643,34 +645,34 @@ static const struct pci_device_id iwl_hw_card_ids[] = {
{IWL_PCI_DEVICE(0x2720, 0x40A4, iwl9462_2ac_cfg_soc)},
{IWL_PCI_DEVICE(0x2720, 0x4234, iwl9560_2ac_cfg_soc)},
{IWL_PCI_DEVICE(0x2720, 0x42A4, iwl9462_2ac_cfg_soc)},
- {IWL_PCI_DEVICE(0x30DC, 0x0030, iwl9560_2ac_160_cfg_soc)},
- {IWL_PCI_DEVICE(0x30DC, 0x0034, iwl9560_2ac_cfg_soc)},
- {IWL_PCI_DEVICE(0x30DC, 0x0038, iwl9560_2ac_160_cfg_soc)},
- {IWL_PCI_DEVICE(0x30DC, 0x003C, iwl9560_2ac_160_cfg_soc)},
- {IWL_PCI_DEVICE(0x30DC, 0x0060, iwl9460_2ac_cfg_soc)},
- {IWL_PCI_DEVICE(0x30DC, 0x0064, iwl9461_2ac_cfg_soc)},
- {IWL_PCI_DEVICE(0x30DC, 0x00A0, iwl9462_2ac_cfg_soc)},
- {IWL_PCI_DEVICE(0x30DC, 0x00A4, iwl9462_2ac_cfg_soc)},
- {IWL_PCI_DEVICE(0x30DC, 0x0230, iwl9560_2ac_cfg_soc)},
- {IWL_PCI_DEVICE(0x30DC, 0x0234, iwl9560_2ac_cfg_soc)},
- {IWL_PCI_DEVICE(0x30DC, 0x0238, iwl9560_2ac_cfg_soc)},
- {IWL_PCI_DEVICE(0x30DC, 0x023C, iwl9560_2ac_cfg_soc)},
- {IWL_PCI_DEVICE(0x30DC, 0x0260, iwl9461_2ac_cfg_soc)},
- {IWL_PCI_DEVICE(0x30DC, 0x0264, iwl9461_2ac_cfg_soc)},
- {IWL_PCI_DEVICE(0x30DC, 0x02A0, iwl9462_2ac_cfg_soc)},
- {IWL_PCI_DEVICE(0x30DC, 0x02A4, iwl9462_2ac_cfg_soc)},
- {IWL_PCI_DEVICE(0x30DC, 0x1010, iwl9260_2ac_cfg)},
- {IWL_PCI_DEVICE(0x30DC, 0x1030, iwl9560_2ac_cfg_soc)},
- {IWL_PCI_DEVICE(0x30DC, 0x1210, iwl9260_2ac_cfg)},
- {IWL_PCI_DEVICE(0x30DC, 0x1551, iwl9560_killer_s_2ac_cfg_soc)},
- {IWL_PCI_DEVICE(0x30DC, 0x1552, iwl9560_killer_2ac_cfg_soc)},
- {IWL_PCI_DEVICE(0x30DC, 0x2030, iwl9560_2ac_160_cfg_soc)},
- {IWL_PCI_DEVICE(0x30DC, 0x2034, iwl9560_2ac_160_cfg_soc)},
- {IWL_PCI_DEVICE(0x30DC, 0x4030, iwl9560_2ac_160_cfg_soc)},
- {IWL_PCI_DEVICE(0x30DC, 0x4034, iwl9560_2ac_160_cfg_soc)},
- {IWL_PCI_DEVICE(0x30DC, 0x40A4, iwl9462_2ac_cfg_soc)},
- {IWL_PCI_DEVICE(0x30DC, 0x4234, iwl9560_2ac_cfg_soc)},
- {IWL_PCI_DEVICE(0x30DC, 0x42A4, iwl9462_2ac_cfg_soc)},
+
+ {IWL_PCI_DEVICE(0x30DC, 0x0030, iwl9560_2ac_160_cfg_qu_b0_jf_b0)},
+ {IWL_PCI_DEVICE(0x30DC, 0x0034, iwl9560_2ac_cfg_qu_b0_jf_b0)},
+ {IWL_PCI_DEVICE(0x30DC, 0x0038, iwl9560_2ac_160_cfg_qu_b0_jf_b0)},
+ {IWL_PCI_DEVICE(0x30DC, 0x003C, iwl9560_2ac_160_cfg_qu_b0_jf_b0)},
+ {IWL_PCI_DEVICE(0x30DC, 0x0060, iwl9461_2ac_cfg_qu_b0_jf_b0)},
+ {IWL_PCI_DEVICE(0x30DC, 0x0064, iwl9461_2ac_cfg_qu_b0_jf_b0)},
+ {IWL_PCI_DEVICE(0x30DC, 0x00A0, iwl9462_2ac_cfg_qu_b0_jf_b0)},
+ {IWL_PCI_DEVICE(0x30DC, 0x00A4, iwl9462_2ac_cfg_qu_b0_jf_b0)},
+ {IWL_PCI_DEVICE(0x30DC, 0x0230, iwl9560_2ac_cfg_qu_b0_jf_b0)},
+ {IWL_PCI_DEVICE(0x30DC, 0x0234, iwl9560_2ac_cfg_qu_b0_jf_b0)},
+ {IWL_PCI_DEVICE(0x30DC, 0x0238, iwl9560_2ac_cfg_qu_b0_jf_b0)},
+ {IWL_PCI_DEVICE(0x30DC, 0x023C, iwl9560_2ac_cfg_qu_b0_jf_b0)},
+ {IWL_PCI_DEVICE(0x30DC, 0x0260, iwl9461_2ac_cfg_qu_b0_jf_b0)},
+ {IWL_PCI_DEVICE(0x30DC, 0x0264, iwl9461_2ac_cfg_qu_b0_jf_b0)},
+ {IWL_PCI_DEVICE(0x30DC, 0x02A0, iwl9462_2ac_cfg_qu_b0_jf_b0)},
+ {IWL_PCI_DEVICE(0x30DC, 0x02A4, iwl9462_2ac_cfg_qu_b0_jf_b0)},
+ {IWL_PCI_DEVICE(0x30DC, 0x1030, iwl9560_2ac_cfg_qu_b0_jf_b0)},
+ {IWL_PCI_DEVICE(0x30DC, 0x1551, killer1550s_2ac_cfg_qu_b0_jf_b0)},
+ {IWL_PCI_DEVICE(0x30DC, 0x1552, killer1550i_2ac_cfg_qu_b0_jf_b0)},
+ {IWL_PCI_DEVICE(0x30DC, 0x2030, iwl9560_2ac_160_cfg_qu_b0_jf_b0)},
+ {IWL_PCI_DEVICE(0x30DC, 0x2034, iwl9560_2ac_160_cfg_qu_b0_jf_b0)},
+ {IWL_PCI_DEVICE(0x30DC, 0x4030, iwl9560_2ac_160_cfg_qu_b0_jf_b0)},
+ {IWL_PCI_DEVICE(0x30DC, 0x4034, iwl9560_2ac_160_cfg_qu_b0_jf_b0)},
+ {IWL_PCI_DEVICE(0x30DC, 0x40A4, iwl9462_2ac_cfg_qu_b0_jf_b0)},
+ {IWL_PCI_DEVICE(0x30DC, 0x4234, iwl9560_2ac_cfg_qu_b0_jf_b0)},
+ {IWL_PCI_DEVICE(0x30DC, 0x42A4, iwl9462_2ac_cfg_qu_b0_jf_b0)},
+
{IWL_PCI_DEVICE(0x31DC, 0x0030, iwl9560_2ac_160_cfg_shared_clk)},
{IWL_PCI_DEVICE(0x31DC, 0x0034, iwl9560_2ac_cfg_shared_clk)},
{IWL_PCI_DEVICE(0x31DC, 0x0038, iwl9560_2ac_160_cfg_shared_clk)},
@@ -726,62 +728,60 @@ static const struct pci_device_id iwl_hw_card_ids[] = {
{IWL_PCI_DEVICE(0x34F0, 0x4234, iwl9560_2ac_cfg_qu_b0_jf_b0)},
{IWL_PCI_DEVICE(0x34F0, 0x42A4, iwl9462_2ac_cfg_qu_b0_jf_b0)},
- {IWL_PCI_DEVICE(0x3DF0, 0x0030, iwl9560_2ac_160_cfg_soc)},
- {IWL_PCI_DEVICE(0x3DF0, 0x0034, iwl9560_2ac_cfg_soc)},
- {IWL_PCI_DEVICE(0x3DF0, 0x0038, iwl9560_2ac_160_cfg_soc)},
- {IWL_PCI_DEVICE(0x3DF0, 0x003C, iwl9560_2ac_160_cfg_soc)},
- {IWL_PCI_DEVICE(0x3DF0, 0x0060, iwl9461_2ac_cfg_soc)},
- {IWL_PCI_DEVICE(0x3DF0, 0x0064, iwl9461_2ac_cfg_soc)},
- {IWL_PCI_DEVICE(0x3DF0, 0x00A0, iwl9462_2ac_cfg_soc)},
- {IWL_PCI_DEVICE(0x3DF0, 0x00A4, iwl9462_2ac_cfg_soc)},
- {IWL_PCI_DEVICE(0x3DF0, 0x0230, iwl9560_2ac_cfg_soc)},
- {IWL_PCI_DEVICE(0x3DF0, 0x0234, iwl9560_2ac_cfg_soc)},
- {IWL_PCI_DEVICE(0x3DF0, 0x0238, iwl9560_2ac_cfg_soc)},
- {IWL_PCI_DEVICE(0x3DF0, 0x023C, iwl9560_2ac_cfg_soc)},
- {IWL_PCI_DEVICE(0x3DF0, 0x0260, iwl9461_2ac_cfg_soc)},
- {IWL_PCI_DEVICE(0x3DF0, 0x0264, iwl9461_2ac_cfg_soc)},
- {IWL_PCI_DEVICE(0x3DF0, 0x02A0, iwl9462_2ac_cfg_soc)},
- {IWL_PCI_DEVICE(0x3DF0, 0x02A4, iwl9462_2ac_cfg_soc)},
- {IWL_PCI_DEVICE(0x3DF0, 0x1010, iwl9260_2ac_cfg)},
- {IWL_PCI_DEVICE(0x3DF0, 0x1030, iwl9560_2ac_cfg_soc)},
- {IWL_PCI_DEVICE(0x3DF0, 0x1210, iwl9260_2ac_cfg)},
- {IWL_PCI_DEVICE(0x3DF0, 0x1551, iwl9560_killer_s_2ac_cfg_soc)},
- {IWL_PCI_DEVICE(0x3DF0, 0x1552, iwl9560_killer_2ac_cfg_soc)},
- {IWL_PCI_DEVICE(0x3DF0, 0x2030, iwl9560_2ac_160_cfg_soc)},
- {IWL_PCI_DEVICE(0x3DF0, 0x2034, iwl9560_2ac_160_cfg_soc)},
- {IWL_PCI_DEVICE(0x3DF0, 0x4030, iwl9560_2ac_160_cfg_soc)},
- {IWL_PCI_DEVICE(0x3DF0, 0x4034, iwl9560_2ac_160_cfg_soc)},
- {IWL_PCI_DEVICE(0x3DF0, 0x40A4, iwl9462_2ac_cfg_soc)},
- {IWL_PCI_DEVICE(0x3DF0, 0x4234, iwl9560_2ac_cfg_soc)},
- {IWL_PCI_DEVICE(0x3DF0, 0x42A4, iwl9462_2ac_cfg_soc)},
- {IWL_PCI_DEVICE(0x43F0, 0x0030, iwl9560_2ac_160_cfg_soc)},
- {IWL_PCI_DEVICE(0x43F0, 0x0034, iwl9560_2ac_cfg_soc)},
- {IWL_PCI_DEVICE(0x43F0, 0x0038, iwl9560_2ac_160_cfg_soc)},
- {IWL_PCI_DEVICE(0x43F0, 0x003C, iwl9560_2ac_160_cfg_soc)},
- {IWL_PCI_DEVICE(0x43F0, 0x0060, iwl9461_2ac_cfg_soc)},
- {IWL_PCI_DEVICE(0x43F0, 0x0064, iwl9461_2ac_cfg_soc)},
- {IWL_PCI_DEVICE(0x43F0, 0x00A0, iwl9462_2ac_cfg_soc)},
- {IWL_PCI_DEVICE(0x43F0, 0x00A4, iwl9462_2ac_cfg_soc)},
- {IWL_PCI_DEVICE(0x43F0, 0x0230, iwl9560_2ac_cfg_soc)},
- {IWL_PCI_DEVICE(0x43F0, 0x0234, iwl9560_2ac_cfg_soc)},
- {IWL_PCI_DEVICE(0x43F0, 0x0238, iwl9560_2ac_cfg_soc)},
- {IWL_PCI_DEVICE(0x43F0, 0x023C, iwl9560_2ac_cfg_soc)},
- {IWL_PCI_DEVICE(0x43F0, 0x0260, iwl9461_2ac_cfg_soc)},
- {IWL_PCI_DEVICE(0x43F0, 0x0264, iwl9461_2ac_cfg_soc)},
- {IWL_PCI_DEVICE(0x43F0, 0x02A0, iwl9462_2ac_cfg_soc)},
- {IWL_PCI_DEVICE(0x43F0, 0x02A4, iwl9462_2ac_cfg_soc)},
- {IWL_PCI_DEVICE(0x43F0, 0x1010, iwl9260_2ac_cfg)},
- {IWL_PCI_DEVICE(0x43F0, 0x1030, iwl9560_2ac_cfg_soc)},
- {IWL_PCI_DEVICE(0x43F0, 0x1210, iwl9260_2ac_cfg)},
- {IWL_PCI_DEVICE(0x43F0, 0x1551, iwl9560_killer_s_2ac_cfg_soc)},
- {IWL_PCI_DEVICE(0x43F0, 0x1552, iwl9560_killer_2ac_cfg_soc)},
- {IWL_PCI_DEVICE(0x43F0, 0x2030, iwl9560_2ac_160_cfg_soc)},
- {IWL_PCI_DEVICE(0x43F0, 0x2034, iwl9560_2ac_160_cfg_soc)},
- {IWL_PCI_DEVICE(0x43F0, 0x4030, iwl9560_2ac_160_cfg_soc)},
- {IWL_PCI_DEVICE(0x43F0, 0x4034, iwl9560_2ac_160_cfg_soc)},
- {IWL_PCI_DEVICE(0x43F0, 0x40A4, iwl9462_2ac_cfg_soc)},
- {IWL_PCI_DEVICE(0x43F0, 0x4234, iwl9560_2ac_cfg_soc)},
- {IWL_PCI_DEVICE(0x43F0, 0x42A4, iwl9462_2ac_cfg_soc)},
+ {IWL_PCI_DEVICE(0x3DF0, 0x0030, iwl9560_2ac_160_cfg_qu_b0_jf_b0)},
+ {IWL_PCI_DEVICE(0x3DF0, 0x0034, iwl9560_2ac_cfg_qu_b0_jf_b0)},
+ {IWL_PCI_DEVICE(0x3DF0, 0x0038, iwl9560_2ac_160_cfg_qu_b0_jf_b0)},
+ {IWL_PCI_DEVICE(0x3DF0, 0x003C, iwl9560_2ac_160_cfg_qu_b0_jf_b0)},
+ {IWL_PCI_DEVICE(0x3DF0, 0x0060, iwl9461_2ac_cfg_qu_b0_jf_b0)},
+ {IWL_PCI_DEVICE(0x3DF0, 0x0064, iwl9461_2ac_cfg_qu_b0_jf_b0)},
+ {IWL_PCI_DEVICE(0x3DF0, 0x00A0, iwl9462_2ac_cfg_qu_b0_jf_b0)},
+ {IWL_PCI_DEVICE(0x3DF0, 0x00A4, iwl9462_2ac_cfg_qu_b0_jf_b0)},
+ {IWL_PCI_DEVICE(0x3DF0, 0x0230, iwl9560_2ac_cfg_qu_b0_jf_b0)},
+ {IWL_PCI_DEVICE(0x3DF0, 0x0234, iwl9560_2ac_cfg_qu_b0_jf_b0)},
+ {IWL_PCI_DEVICE(0x3DF0, 0x0238, iwl9560_2ac_cfg_qu_b0_jf_b0)},
+ {IWL_PCI_DEVICE(0x3DF0, 0x023C, iwl9560_2ac_cfg_qu_b0_jf_b0)},
+ {IWL_PCI_DEVICE(0x3DF0, 0x0260, iwl9461_2ac_cfg_qu_b0_jf_b0)},
+ {IWL_PCI_DEVICE(0x3DF0, 0x0264, iwl9461_2ac_cfg_qu_b0_jf_b0)},
+ {IWL_PCI_DEVICE(0x3DF0, 0x02A0, iwl9462_2ac_cfg_qu_b0_jf_b0)},
+ {IWL_PCI_DEVICE(0x3DF0, 0x02A4, iwl9462_2ac_cfg_qu_b0_jf_b0)},
+ {IWL_PCI_DEVICE(0x3DF0, 0x1030, iwl9560_2ac_cfg_qu_b0_jf_b0)},
+ {IWL_PCI_DEVICE(0x3DF0, 0x1551, killer1550s_2ac_cfg_qu_b0_jf_b0)},
+ {IWL_PCI_DEVICE(0x3DF0, 0x1552, killer1550i_2ac_cfg_qu_b0_jf_b0)},
+ {IWL_PCI_DEVICE(0x3DF0, 0x2030, iwl9560_2ac_160_cfg_qu_b0_jf_b0)},
+ {IWL_PCI_DEVICE(0x3DF0, 0x2034, iwl9560_2ac_160_cfg_qu_b0_jf_b0)},
+ {IWL_PCI_DEVICE(0x3DF0, 0x4030, iwl9560_2ac_160_cfg_qu_b0_jf_b0)},
+ {IWL_PCI_DEVICE(0x3DF0, 0x4034, iwl9560_2ac_160_cfg_qu_b0_jf_b0)},
+ {IWL_PCI_DEVICE(0x3DF0, 0x40A4, iwl9462_2ac_cfg_qu_b0_jf_b0)},
+ {IWL_PCI_DEVICE(0x3DF0, 0x4234, iwl9560_2ac_cfg_qu_b0_jf_b0)},
+ {IWL_PCI_DEVICE(0x3DF0, 0x42A4, iwl9462_2ac_cfg_qu_b0_jf_b0)},
+
+ {IWL_PCI_DEVICE(0x43F0, 0x0030, iwl9560_2ac_160_cfg_qu_b0_jf_b0)},
+ {IWL_PCI_DEVICE(0x43F0, 0x0034, iwl9560_2ac_cfg_qu_b0_jf_b0)},
+ {IWL_PCI_DEVICE(0x43F0, 0x0038, iwl9560_2ac_160_cfg_qu_b0_jf_b0)},
+ {IWL_PCI_DEVICE(0x43F0, 0x003C, iwl9560_2ac_160_cfg_qu_b0_jf_b0)},
+ {IWL_PCI_DEVICE(0x43F0, 0x0060, iwl9461_2ac_cfg_qu_b0_jf_b0)},
+ {IWL_PCI_DEVICE(0x43F0, 0x0064, iwl9461_2ac_cfg_qu_b0_jf_b0)},
+ {IWL_PCI_DEVICE(0x43F0, 0x00A0, iwl9462_2ac_cfg_qu_b0_jf_b0)},
+ {IWL_PCI_DEVICE(0x43F0, 0x00A4, iwl9462_2ac_cfg_qu_b0_jf_b0)},
+ {IWL_PCI_DEVICE(0x43F0, 0x0230, iwl9560_2ac_cfg_qu_b0_jf_b0)},
+ {IWL_PCI_DEVICE(0x43F0, 0x0234, iwl9560_2ac_cfg_qu_b0_jf_b0)},
+ {IWL_PCI_DEVICE(0x43F0, 0x0238, iwl9560_2ac_cfg_qu_b0_jf_b0)},
+ {IWL_PCI_DEVICE(0x43F0, 0x023C, iwl9560_2ac_cfg_qu_b0_jf_b0)},
+ {IWL_PCI_DEVICE(0x43F0, 0x0260, iwl9461_2ac_cfg_qu_b0_jf_b0)},
+ {IWL_PCI_DEVICE(0x43F0, 0x0264, iwl9461_2ac_cfg_qu_b0_jf_b0)},
+ {IWL_PCI_DEVICE(0x43F0, 0x02A0, iwl9462_2ac_cfg_qu_b0_jf_b0)},
+ {IWL_PCI_DEVICE(0x43F0, 0x02A4, iwl9462_2ac_cfg_qu_b0_jf_b0)},
+ {IWL_PCI_DEVICE(0x43F0, 0x1030, iwl9560_2ac_cfg_qu_b0_jf_b0)},
+ {IWL_PCI_DEVICE(0x43F0, 0x1551, killer1550s_2ac_cfg_qu_b0_jf_b0)},
+ {IWL_PCI_DEVICE(0x43F0, 0x1552, killer1550i_2ac_cfg_qu_b0_jf_b0)},
+ {IWL_PCI_DEVICE(0x43F0, 0x2030, iwl9560_2ac_160_cfg_qu_b0_jf_b0)},
+ {IWL_PCI_DEVICE(0x43F0, 0x2034, iwl9560_2ac_160_cfg_qu_b0_jf_b0)},
+ {IWL_PCI_DEVICE(0x43F0, 0x4030, iwl9560_2ac_160_cfg_qu_b0_jf_b0)},
+ {IWL_PCI_DEVICE(0x43F0, 0x4034, iwl9560_2ac_160_cfg_qu_b0_jf_b0)},
+ {IWL_PCI_DEVICE(0x43F0, 0x40A4, iwl9462_2ac_cfg_qu_b0_jf_b0)},
+ {IWL_PCI_DEVICE(0x43F0, 0x4234, iwl9560_2ac_cfg_qu_b0_jf_b0)},
+ {IWL_PCI_DEVICE(0x43F0, 0x42A4, iwl9462_2ac_cfg_qu_b0_jf_b0)},
+
{IWL_PCI_DEVICE(0x9DF0, 0x0000, iwl9460_2ac_cfg_soc)},
{IWL_PCI_DEVICE(0x9DF0, 0x0010, iwl9460_2ac_cfg_soc)},
{IWL_PCI_DEVICE(0x9DF0, 0x0030, iwl9560_2ac_160_cfg_soc)},
@@ -821,34 +821,34 @@ static const struct pci_device_id iwl_hw_card_ids[] = {
{IWL_PCI_DEVICE(0x9DF0, 0x40A4, iwl9462_2ac_cfg_soc)},
{IWL_PCI_DEVICE(0x9DF0, 0x4234, iwl9560_2ac_cfg_soc)},
{IWL_PCI_DEVICE(0x9DF0, 0x42A4, iwl9462_2ac_cfg_soc)},
- {IWL_PCI_DEVICE(0xA0F0, 0x0030, iwl9560_2ac_160_cfg_soc)},
- {IWL_PCI_DEVICE(0xA0F0, 0x0034, iwl9560_2ac_cfg_soc)},
- {IWL_PCI_DEVICE(0xA0F0, 0x0038, iwl9560_2ac_160_cfg_soc)},
- {IWL_PCI_DEVICE(0xA0F0, 0x003C, iwl9560_2ac_160_cfg_soc)},
- {IWL_PCI_DEVICE(0xA0F0, 0x0060, iwl9461_2ac_cfg_soc)},
- {IWL_PCI_DEVICE(0xA0F0, 0x0064, iwl9461_2ac_cfg_soc)},
- {IWL_PCI_DEVICE(0xA0F0, 0x00A0, iwl9462_2ac_cfg_soc)},
- {IWL_PCI_DEVICE(0xA0F0, 0x00A4, iwl9462_2ac_cfg_soc)},
- {IWL_PCI_DEVICE(0xA0F0, 0x0230, iwl9560_2ac_cfg_soc)},
- {IWL_PCI_DEVICE(0xA0F0, 0x0234, iwl9560_2ac_cfg_soc)},
- {IWL_PCI_DEVICE(0xA0F0, 0x0238, iwl9560_2ac_cfg_soc)},
- {IWL_PCI_DEVICE(0xA0F0, 0x023C, iwl9560_2ac_cfg_soc)},
- {IWL_PCI_DEVICE(0xA0F0, 0x0260, iwl9461_2ac_cfg_soc)},
- {IWL_PCI_DEVICE(0xA0F0, 0x0264, iwl9461_2ac_cfg_soc)},
- {IWL_PCI_DEVICE(0xA0F0, 0x02A0, iwl9462_2ac_cfg_soc)},
- {IWL_PCI_DEVICE(0xA0F0, 0x02A4, iwl9462_2ac_cfg_soc)},
- {IWL_PCI_DEVICE(0xA0F0, 0x1010, iwl9260_2ac_cfg)},
- {IWL_PCI_DEVICE(0xA0F0, 0x1030, iwl9560_2ac_cfg_soc)},
- {IWL_PCI_DEVICE(0xA0F0, 0x1210, iwl9260_2ac_cfg)},
- {IWL_PCI_DEVICE(0xA0F0, 0x1551, iwl9560_killer_s_2ac_cfg_soc)},
- {IWL_PCI_DEVICE(0xA0F0, 0x1552, iwl9560_killer_2ac_cfg_soc)},
- {IWL_PCI_DEVICE(0xA0F0, 0x2030, iwl9560_2ac_160_cfg_soc)},
- {IWL_PCI_DEVICE(0xA0F0, 0x2034, iwl9560_2ac_160_cfg_soc)},
- {IWL_PCI_DEVICE(0xA0F0, 0x4030, iwl9560_2ac_160_cfg_soc)},
- {IWL_PCI_DEVICE(0xA0F0, 0x4034, iwl9560_2ac_160_cfg_soc)},
- {IWL_PCI_DEVICE(0xA0F0, 0x40A4, iwl9462_2ac_cfg_soc)},
- {IWL_PCI_DEVICE(0xA0F0, 0x4234, iwl9560_2ac_cfg_soc)},
- {IWL_PCI_DEVICE(0xA0F0, 0x42A4, iwl9462_2ac_cfg_soc)},
+
+ {IWL_PCI_DEVICE(0xA0F0, 0x0030, iwl9560_2ac_160_cfg_qu_b0_jf_b0)},
+ {IWL_PCI_DEVICE(0xA0F0, 0x0034, iwl9560_2ac_cfg_qu_b0_jf_b0)},
+ {IWL_PCI_DEVICE(0xA0F0, 0x0038, iwl9560_2ac_160_cfg_qu_b0_jf_b0)},
+ {IWL_PCI_DEVICE(0xA0F0, 0x003C, iwl9560_2ac_160_cfg_qu_b0_jf_b0)},
+ {IWL_PCI_DEVICE(0xA0F0, 0x0060, iwl9461_2ac_cfg_qu_b0_jf_b0)},
+ {IWL_PCI_DEVICE(0xA0F0, 0x0064, iwl9461_2ac_cfg_qu_b0_jf_b0)},
+ {IWL_PCI_DEVICE(0xA0F0, 0x00A0, iwl9462_2ac_cfg_qu_b0_jf_b0)},
+ {IWL_PCI_DEVICE(0xA0F0, 0x00A4, iwl9462_2ac_cfg_qu_b0_jf_b0)},
+ {IWL_PCI_DEVICE(0xA0F0, 0x0230, iwl9560_2ac_cfg_qu_b0_jf_b0)},
+ {IWL_PCI_DEVICE(0xA0F0, 0x0234, iwl9560_2ac_cfg_qu_b0_jf_b0)},
+ {IWL_PCI_DEVICE(0xA0F0, 0x0238, iwl9560_2ac_cfg_qu_b0_jf_b0)},
+ {IWL_PCI_DEVICE(0xA0F0, 0x023C, iwl9560_2ac_cfg_qu_b0_jf_b0)},
+ {IWL_PCI_DEVICE(0xA0F0, 0x0260, iwl9461_2ac_cfg_qu_b0_jf_b0)},
+ {IWL_PCI_DEVICE(0xA0F0, 0x0264, iwl9461_2ac_cfg_qu_b0_jf_b0)},
+ {IWL_PCI_DEVICE(0xA0F0, 0x02A0, iwl9462_2ac_cfg_qu_b0_jf_b0)},
+ {IWL_PCI_DEVICE(0xA0F0, 0x02A4, iwl9462_2ac_cfg_qu_b0_jf_b0)},
+ {IWL_PCI_DEVICE(0xA0F0, 0x1030, iwl9560_2ac_cfg_qu_b0_jf_b0)},
+ {IWL_PCI_DEVICE(0xA0F0, 0x1551, killer1550s_2ac_cfg_qu_b0_jf_b0)},
+ {IWL_PCI_DEVICE(0xA0F0, 0x1552, killer1550i_2ac_cfg_qu_b0_jf_b0)},
+ {IWL_PCI_DEVICE(0xA0F0, 0x2030, iwl9560_2ac_160_cfg_qu_b0_jf_b0)},
+ {IWL_PCI_DEVICE(0xA0F0, 0x2034, iwl9560_2ac_160_cfg_qu_b0_jf_b0)},
+ {IWL_PCI_DEVICE(0xA0F0, 0x4030, iwl9560_2ac_160_cfg_qu_b0_jf_b0)},
+ {IWL_PCI_DEVICE(0xA0F0, 0x4034, iwl9560_2ac_160_cfg_qu_b0_jf_b0)},
+ {IWL_PCI_DEVICE(0xA0F0, 0x40A4, iwl9462_2ac_cfg_qu_b0_jf_b0)},
+ {IWL_PCI_DEVICE(0xA0F0, 0x4234, iwl9560_2ac_cfg_qu_b0_jf_b0)},
+ {IWL_PCI_DEVICE(0xA0F0, 0x42A4, iwl9462_2ac_cfg_qu_b0_jf_b0)},
+
{IWL_PCI_DEVICE(0xA370, 0x0030, iwl9560_2ac_160_cfg_soc)},
{IWL_PCI_DEVICE(0xA370, 0x0034, iwl9560_2ac_cfg_soc)},
{IWL_PCI_DEVICE(0xA370, 0x0038, iwl9560_2ac_160_cfg_soc)},
@@ -994,15 +994,22 @@ static int iwl_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
const struct iwl_cfg *cfg = (struct iwl_cfg *)(ent->driver_data);
const struct iwl_cfg *cfg_7265d __maybe_unused = NULL;
struct iwl_trans *iwl_trans;
+ unsigned long flags;
int ret;
- if (WARN_ONCE(!cfg->csr, "CSR addresses aren't configured\n"))
- return -EINVAL;
-
- iwl_trans = iwl_trans_pcie_alloc(pdev, ent, cfg);
+ iwl_trans = iwl_trans_pcie_alloc(pdev, ent, &cfg->trans);
if (IS_ERR(iwl_trans))
return PTR_ERR(iwl_trans);
+ /* the trans_cfg should never change, so set it now */
+ iwl_trans->trans_cfg = &cfg->trans;
+
+ if (WARN_ONCE(!iwl_trans->trans_cfg->csr,
+ "CSR addresses aren't configured\n")) {
+ ret = -EINVAL;
+ goto out_free_trans;
+ }
+
#if IS_ENABLED(CONFIG_IWLMVM)
/*
* special-case 7265D, it has the same PCI IDs.
@@ -1018,29 +1025,70 @@ 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;
- }
- if (iwl_trans->cfg->rf_id && cfg == &iwl22000_2ac_cfg_hr_cdb &&
- iwl_trans->hw_rev != CSR_HW_REV_TYPE_HR_CDB) {
- u32 rf_id_chp = CSR_HW_RF_ID_TYPE_CHIP_ID(iwl_trans->hw_rf_id);
- u32 jf_chp_id = CSR_HW_RF_ID_TYPE_CHIP_ID(CSR_HW_RF_ID_TYPE_JF);
- u32 hr_chp_id = CSR_HW_RF_ID_TYPE_CHIP_ID(CSR_HW_RF_ID_TYPE_HR);
-
- if (rf_id_chp == jf_chp_id) {
- if (iwl_trans->hw_rev == CSR_HW_REV_TYPE_QNJ)
- cfg = &iwl9560_2ac_cfg_qnj_jf_b0;
- else
- cfg = &iwl22000_2ac_cfg_jf;
- } else if (rf_id_chp == hr_chp_id) {
- if (iwl_trans->hw_rev == CSR_HW_REV_TYPE_QNJ)
- cfg = &iwl22000_2ax_cfg_qnj_hr_a0;
- else
- cfg = &iwl22000_2ac_cfg_hr;
+ iwl_trans->hw_rf_id = iwl_read32(iwl_trans, CSR_HW_RF_ID);
+
+ if (cfg == &iwlax210_2ax_cfg_so_hr_a0) {
+ if (iwl_trans->hw_rev == CSR_HW_REV_TYPE_TY) {
+ cfg = &iwlax210_2ax_cfg_ty_gf_a0;
+ } else if (CSR_HW_RF_ID_TYPE_CHIP_ID(iwl_trans->hw_rf_id) ==
+ CSR_HW_RF_ID_TYPE_CHIP_ID(CSR_HW_RF_ID_TYPE_JF)) {
+ cfg = &iwlax210_2ax_cfg_so_jf_a0;
+ } else if (CSR_HW_RF_ID_TYPE_CHIP_ID(iwl_trans->hw_rf_id) ==
+ CSR_HW_RF_ID_TYPE_CHIP_ID(CSR_HW_RF_ID_TYPE_GF)) {
+ cfg = &iwlax211_2ax_cfg_so_gf_a0;
+ } else if (CSR_HW_RF_ID_TYPE_CHIP_ID(iwl_trans->hw_rf_id) ==
+ CSR_HW_RF_ID_TYPE_CHIP_ID(CSR_HW_RF_ID_TYPE_GF4)) {
+ cfg = &iwlax411_2ax_cfg_so_gf4_a0;
+ }
+ } else if (cfg == &iwl_ax101_cfg_qu_hr) {
+ if ((CSR_HW_RF_ID_TYPE_CHIP_ID(iwl_trans->hw_rf_id) ==
+ CSR_HW_RF_ID_TYPE_CHIP_ID(CSR_HW_RF_ID_TYPE_HR) &&
+ iwl_trans->hw_rev == CSR_HW_REV_TYPE_QNJ_B0) ||
+ (CSR_HW_RF_ID_TYPE_CHIP_ID(iwl_trans->hw_rf_id) ==
+ CSR_HW_RF_ID_TYPE_CHIP_ID(CSR_HW_RF_ID_TYPE_HR1))) {
+ cfg = &iwl22000_2ax_cfg_qnj_hr_b0;
+ } else if (CSR_HW_RF_ID_TYPE_CHIP_ID(iwl_trans->hw_rf_id) ==
+ CSR_HW_RF_ID_TYPE_CHIP_ID(CSR_HW_RF_ID_TYPE_HR)) {
+ cfg = &iwl_ax101_cfg_qu_hr;
+ } else if (CSR_HW_RF_ID_TYPE_CHIP_ID(iwl_trans->hw_rf_id) ==
+ CSR_HW_RF_ID_TYPE_CHIP_ID(CSR_HW_RF_ID_TYPE_JF)) {
+ cfg = &iwl22000_2ax_cfg_jf;
+ } else if (CSR_HW_RF_ID_TYPE_CHIP_ID(iwl_trans->hw_rf_id) ==
+ CSR_HW_RF_ID_TYPE_CHIP_ID(CSR_HW_RF_ID_TYPE_HRCDB)) {
+ IWL_ERR(iwl_trans, "RF ID HRCDB is not supported\n");
+ return -EINVAL;
+ } else {
+ IWL_ERR(iwl_trans, "Unrecognized RF ID 0x%08x\n",
+ CSR_HW_RF_ID_TYPE_CHIP_ID(iwl_trans->hw_rf_id));
+ return -EINVAL;
+ }
+ } else if (CSR_HW_RF_ID_TYPE_CHIP_ID(iwl_trans->hw_rf_id) ==
+ CSR_HW_RF_ID_TYPE_CHIP_ID(CSR_HW_RF_ID_TYPE_HR) &&
+ ((cfg != &iwl_ax200_cfg_cc &&
+ cfg != &killer1650x_2ax_cfg &&
+ cfg != &killer1650w_2ax_cfg &&
+ cfg != &iwl_ax201_cfg_quz_hr) ||
+ iwl_trans->hw_rev == CSR_HW_REV_TYPE_QNJ_B0)) {
+ u32 hw_status;
+
+ hw_status = iwl_read_prph(iwl_trans, UMAG_GEN_HW_STATUS);
+ if (CSR_HW_RF_STEP(iwl_trans->hw_rf_id) == SILICON_B_STEP)
+ /*
+ * b step fw is the same for physical card and fpga
+ */
+ cfg = &iwl22000_2ax_cfg_qnj_hr_b0;
+ else if ((hw_status & UMAG_GEN_HW_IS_FPGA) &&
+ CSR_HW_RF_STEP(iwl_trans->hw_rf_id) == SILICON_A_STEP) {
+ cfg = &iwl22000_2ax_cfg_qnj_hr_a0_f0;
+ } else {
+ /*
+ * a step no FPGA
+ */
+ cfg = &iwl22000_2ac_cfg_hr;
}
- iwl_trans->cfg = cfg;
}
/*
@@ -1050,20 +1098,54 @@ static int iwl_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
* thing to do to support Qu C-step.
*/
if (iwl_trans->hw_rev == CSR_HW_REV_TYPE_QU_C0) {
+ if (cfg == &iwl_ax101_cfg_qu_hr)
+ cfg = &iwl_ax101_cfg_qu_c0_hr_b0;
+ else if (cfg == &iwl_ax201_cfg_qu_hr)
+ cfg = &iwl_ax201_cfg_qu_c0_hr_b0;
+ else if (cfg == &iwl9461_2ac_cfg_qu_b0_jf_b0)
+ cfg = &iwl9461_2ac_cfg_qu_c0_jf_b0;
+ else if (cfg == &iwl9462_2ac_cfg_qu_b0_jf_b0)
+ cfg = &iwl9462_2ac_cfg_qu_c0_jf_b0;
+ else if (cfg == &iwl9560_2ac_cfg_qu_b0_jf_b0)
+ cfg = &iwl9560_2ac_cfg_qu_c0_jf_b0;
+ else if (cfg == &iwl9560_2ac_160_cfg_qu_b0_jf_b0)
+ cfg = &iwl9560_2ac_160_cfg_qu_c0_jf_b0;
+ }
+
+ /* same thing for QuZ... */
+ if (iwl_trans->hw_rev == CSR_HW_REV_TYPE_QUZ) {
if (iwl_trans->cfg == &iwl_ax101_cfg_qu_hr)
- iwl_trans->cfg = &iwl_ax101_cfg_qu_c0_hr_b0;
+ iwl_trans->cfg = &iwl_ax101_cfg_quz_hr;
else if (iwl_trans->cfg == &iwl_ax201_cfg_qu_hr)
- iwl_trans->cfg = &iwl_ax201_cfg_qu_c0_hr_b0;
+ iwl_trans->cfg = &iwl_ax201_cfg_quz_hr;
else if (iwl_trans->cfg == &iwl9461_2ac_cfg_qu_b0_jf_b0)
- iwl_trans->cfg = &iwl9461_2ac_cfg_qu_c0_jf_b0;
+ iwl_trans->cfg = &iwl9461_2ac_cfg_quz_a0_jf_b0_soc;
else if (iwl_trans->cfg == &iwl9462_2ac_cfg_qu_b0_jf_b0)
- iwl_trans->cfg = &iwl9462_2ac_cfg_qu_c0_jf_b0;
+ iwl_trans->cfg = &iwl9462_2ac_cfg_quz_a0_jf_b0_soc;
else if (iwl_trans->cfg == &iwl9560_2ac_cfg_qu_b0_jf_b0)
- iwl_trans->cfg = &iwl9560_2ac_cfg_qu_c0_jf_b0;
+ iwl_trans->cfg = &iwl9560_2ac_cfg_quz_a0_jf_b0_soc;
else if (iwl_trans->cfg == &iwl9560_2ac_160_cfg_qu_b0_jf_b0)
- iwl_trans->cfg = &iwl9560_2ac_160_cfg_qu_c0_jf_b0;
+ iwl_trans->cfg = &iwl9560_2ac_160_cfg_quz_a0_jf_b0_soc;
}
+
#endif
+ /* now set the real cfg we decided to use */
+ iwl_trans->cfg = cfg;
+
+ if (iwl_trans->trans_cfg->device_family >= IWL_DEVICE_FAMILY_8000 &&
+ iwl_trans_grab_nic_access(iwl_trans, &flags)) {
+ u32 hw_step;
+
+ hw_step = iwl_read_umac_prph_no_grab(iwl_trans, WFPM_CTRL_REG);
+ hw_step |= ENABLE_WFPM;
+ iwl_write_umac_prph_no_grab(iwl_trans, WFPM_CTRL_REG, hw_step);
+ hw_step = iwl_read_prph_no_grab(iwl_trans, CNVI_AUX_MISC_CHIP);
+ hw_step = (hw_step >> HW_STEP_LOCATION_BITS) & 0xF;
+ if (hw_step == 0x3)
+ iwl_trans->hw_rev = (iwl_trans->hw_rev & 0xFFFFFFF3) |
+ (SILICON_C_STEP << 2);
+ iwl_trans_release_nic_access(iwl_trans, &flags);
+ }
pci_set_drvdata(pdev, iwl_trans);
iwl_trans->drv = iwl_drv_start(iwl_trans);
@@ -1076,25 +1158,6 @@ static int iwl_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
/* register transport layer debugfs here */
iwl_trans_pcie_dbgfs_register(iwl_trans);
- /* if RTPM is in use, enable it in our device */
- if (iwl_trans->runtime_pm_mode != IWL_PLAT_PM_MODE_DISABLED) {
- /* We explicitly set the device to active here to
- * clear contingent errors.
- */
- pm_runtime_set_active(&pdev->dev);
-
- pm_runtime_set_autosuspend_delay(&pdev->dev,
- iwlwifi_mod_params.d0i3_timeout);
- pm_runtime_use_autosuspend(&pdev->dev);
-
- /* We are not supposed to call pm_runtime_allow() by
- * ourselves, but let userspace enable runtime PM via
- * sysfs. However, since we don't enable this from
- * userspace yet, we need to allow/forbid() ourselves.
- */
- pm_runtime_allow(&pdev->dev);
- }
-
/* The PCI device starts with a reference taken and we are
* supposed to release it here. But to simplify the
* interaction with the opmode, we don't do it now, but let
@@ -1112,15 +1175,6 @@ static void iwl_pci_remove(struct pci_dev *pdev)
{
struct iwl_trans *trans = pci_get_drvdata(pdev);
- /* if RTPM was in use, restore it to the state before probe */
- if (trans->runtime_pm_mode != IWL_PLAT_PM_MODE_DISABLED) {
- /* We should not call forbid here, but we do for now.
- * Check the comment to pm_runtime_allow() in
- * iwl_pci_probe().
- */
- pm_runtime_forbid(trans->dev);
- }
-
iwl_drv_stop(trans->drv);
iwl_trans_pcie_free(trans);
@@ -1178,164 +1232,9 @@ static int iwl_pci_resume(struct device *device)
return 0;
}
-int iwl_pci_fw_enter_d0i3(struct iwl_trans *trans)
-{
- struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans);
- int ret;
-
- if (test_bit(STATUS_FW_ERROR, &trans->status))
- return 0;
-
- set_bit(STATUS_TRANS_GOING_IDLE, &trans->status);
-
- /* config the fw */
- ret = iwl_op_mode_enter_d0i3(trans->op_mode);
- if (ret == 1) {
- IWL_DEBUG_RPM(trans, "aborting d0i3 entrance\n");
- clear_bit(STATUS_TRANS_GOING_IDLE, &trans->status);
- return -EBUSY;
- }
- if (ret)
- goto err;
-
- ret = wait_event_timeout(trans_pcie->d0i3_waitq,
- test_bit(STATUS_TRANS_IDLE, &trans->status),
- msecs_to_jiffies(IWL_TRANS_IDLE_TIMEOUT));
- if (!ret) {
- IWL_ERR(trans, "Timeout entering D0i3\n");
- ret = -ETIMEDOUT;
- goto err;
- }
-
- clear_bit(STATUS_TRANS_GOING_IDLE, &trans->status);
-
- return 0;
-err:
- clear_bit(STATUS_TRANS_GOING_IDLE, &trans->status);
- iwl_trans_fw_error(trans);
- return ret;
-}
-
-int iwl_pci_fw_exit_d0i3(struct iwl_trans *trans)
-{
- struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans);
- int ret;
-
- /* sometimes a D0i3 entry is not followed through */
- if (!test_bit(STATUS_TRANS_IDLE, &trans->status))
- return 0;
-
- /* config the fw */
- ret = iwl_op_mode_exit_d0i3(trans->op_mode);
- if (ret)
- goto err;
-
- /* we clear STATUS_TRANS_IDLE only when D0I3_END command is completed */
-
- ret = wait_event_timeout(trans_pcie->d0i3_waitq,
- !test_bit(STATUS_TRANS_IDLE, &trans->status),
- msecs_to_jiffies(IWL_TRANS_IDLE_TIMEOUT));
- if (!ret) {
- IWL_ERR(trans, "Timeout exiting D0i3\n");
- ret = -ETIMEDOUT;
- goto err;
- }
-
- return 0;
-err:
- clear_bit(STATUS_TRANS_IDLE, &trans->status);
- iwl_trans_fw_error(trans);
- return ret;
-}
-
-#ifdef CONFIG_IWLWIFI_PCIE_RTPM
-static int iwl_pci_runtime_suspend(struct device *device)
-{
- struct pci_dev *pdev = to_pci_dev(device);
- struct iwl_trans *trans = pci_get_drvdata(pdev);
- int ret;
-
- IWL_DEBUG_RPM(trans, "entering runtime suspend\n");
-
- if (test_bit(STATUS_DEVICE_ENABLED, &trans->status)) {
- ret = iwl_pci_fw_enter_d0i3(trans);
- if (ret < 0)
- return ret;
- }
-
- trans->system_pm_mode = IWL_PLAT_PM_MODE_D0I3;
-
- iwl_trans_d3_suspend(trans, false, false);
-
- return 0;
-}
-
-static int iwl_pci_runtime_resume(struct device *device)
-{
- struct pci_dev *pdev = to_pci_dev(device);
- struct iwl_trans *trans = pci_get_drvdata(pdev);
- enum iwl_d3_status d3_status;
-
- IWL_DEBUG_RPM(trans, "exiting runtime suspend (resume)\n");
-
- iwl_trans_d3_resume(trans, &d3_status, false, false);
-
- if (test_bit(STATUS_DEVICE_ENABLED, &trans->status))
- return iwl_pci_fw_exit_d0i3(trans);
-
- return 0;
-}
-
-static int iwl_pci_system_prepare(struct device *device)
-{
- struct pci_dev *pdev = to_pci_dev(device);
- struct iwl_trans *trans = pci_get_drvdata(pdev);
-
- IWL_DEBUG_RPM(trans, "preparing for system suspend\n");
-
- /* This is called before entering system suspend and before
- * the runtime resume is called. Set the suspending flag to
- * prevent the wakelock from being taken.
- */
- trans->suspending = true;
-
- /* Wake the device up from runtime suspend before going to
- * platform suspend. This is needed because we don't know
- * whether wowlan any is set and, if it's not, mac80211 will
- * disconnect (in which case, we can't be in D0i3).
- */
- pm_runtime_resume(device);
-
- return 0;
-}
-
-static void iwl_pci_system_complete(struct device *device)
-{
- struct pci_dev *pdev = to_pci_dev(device);
- struct iwl_trans *trans = pci_get_drvdata(pdev);
-
- IWL_DEBUG_RPM(trans, "completing system suspend\n");
-
- /* This is called as a counterpart to the prepare op. It is
- * called either when suspending fails or when suspend
- * completed successfully. Now there's no risk of grabbing
- * the wakelock anymore, so we can release the suspending
- * flag.
- */
- trans->suspending = false;
-}
-#endif /* CONFIG_IWLWIFI_PCIE_RTPM */
-
static const struct dev_pm_ops iwl_dev_pm_ops = {
SET_SYSTEM_SLEEP_PM_OPS(iwl_pci_suspend,
iwl_pci_resume)
-#ifdef CONFIG_IWLWIFI_PCIE_RTPM
- SET_RUNTIME_PM_OPS(iwl_pci_runtime_suspend,
- iwl_pci_runtime_resume,
- NULL)
- .prepare = iwl_pci_system_prepare,
- .complete = iwl_pci_system_complete,
-#endif /* CONFIG_IWLWIFI_PCIE_RTPM */
};
#define IWL_PM_OPS (&iwl_dev_pm_ops)
diff --git a/drivers/net/wireless/intel/iwlwifi/pcie/internal.h b/drivers/net/wireless/intel/iwlwifi/pcie/internal.h
index 9f5d0fc839fe..1047d48beaa5 100644
--- a/drivers/net/wireless/intel/iwlwifi/pcie/internal.h
+++ b/drivers/net/wireless/intel/iwlwifi/pcie/internal.h
@@ -253,7 +253,8 @@ struct iwl_dma_ptr {
*/
static inline int iwl_queue_inc_wrap(struct iwl_trans *trans, int index)
{
- return ++index & (trans->cfg->base_params->max_tfd_queue_size - 1);
+ return ++index &
+ (trans->trans_cfg->base_params->max_tfd_queue_size - 1);
}
/**
@@ -263,7 +264,7 @@ static inline int iwl_queue_inc_wrap(struct iwl_trans *trans, int index)
static inline __le16 iwl_get_closed_rb_stts(struct iwl_trans *trans,
struct iwl_rxq *rxq)
{
- if (trans->cfg->device_family >= IWL_DEVICE_FAMILY_22560) {
+ if (trans->trans_cfg->device_family >= IWL_DEVICE_FAMILY_22560) {
__le16 *rb_stts = rxq->rb_stts;
return READ_ONCE(*rb_stts);
@@ -280,7 +281,8 @@ static inline __le16 iwl_get_closed_rb_stts(struct iwl_trans *trans,
*/
static inline int iwl_queue_dec_wrap(struct iwl_trans *trans, int index)
{
- return --index & (trans->cfg->base_params->max_tfd_queue_size - 1);
+ return --index &
+ (trans->trans_cfg->base_params->max_tfd_queue_size - 1);
}
struct iwl_cmd_meta {
@@ -556,9 +558,10 @@ struct iwl_trans_pcie {
void __iomem *hw_base;
bool ucode_write_complete;
+ bool sx_complete;
wait_queue_head_t ucode_write_waitq;
wait_queue_head_t wait_command_queue;
- wait_queue_head_t d0i3_waitq;
+ wait_queue_head_t sx_waitq;
u8 page_offs, dev_cmd_offs;
@@ -581,7 +584,6 @@ struct iwl_trans_pcie {
/*protect hw register */
spinlock_t reg_lock;
bool cmd_hold_nic_awake;
- bool ref_cmd_in_flight;
#ifdef CONFIG_IWLWIFI_DEBUGFS
struct cont_rec fw_mon_data;
@@ -635,9 +637,10 @@ iwl_trans_pcie_get_trans(struct iwl_trans_pcie *trans_pcie)
* Convention: trans API functions: iwl_trans_pcie_XXX
* Other functions: iwl_pcie_XXX
*/
-struct iwl_trans *iwl_trans_pcie_alloc(struct pci_dev *pdev,
- const struct pci_device_id *ent,
- const struct iwl_cfg *cfg);
+struct iwl_trans
+*iwl_trans_pcie_alloc(struct pci_dev *pdev,
+ const struct pci_device_id *ent,
+ const struct iwl_cfg_trans_params *cfg_trans);
void iwl_trans_pcie_free(struct iwl_trans *trans);
/*****************************************************
@@ -697,6 +700,7 @@ void iwl_pcie_hcmd_complete(struct iwl_trans *trans,
struct iwl_rx_cmd_buffer *rxb);
void iwl_trans_pcie_reclaim(struct iwl_trans *trans, int txq_id, int ssn,
struct sk_buff_head *skbs);
+void iwl_trans_pcie_set_q_ptrs(struct iwl_trans *trans, int txq_id, int ptr);
void iwl_trans_pcie_tx_reset(struct iwl_trans *trans);
void iwl_pcie_gen2_update_byte_tbl(struct iwl_trans_pcie *trans_pcie,
struct iwl_txq *txq, u16 byte_cnt,
@@ -705,7 +709,7 @@ void iwl_pcie_gen2_update_byte_tbl(struct iwl_trans_pcie *trans_pcie,
static inline u16 iwl_pcie_tfd_tb_get_len(struct iwl_trans *trans, void *_tfd,
u8 idx)
{
- if (trans->cfg->use_tfh) {
+ if (trans->trans_cfg->use_tfh) {
struct iwl_tfh_tfd *tfd = _tfd;
struct iwl_tfh_tb *tb = &tfd->tbs[idx];
@@ -911,7 +915,7 @@ static inline void *iwl_pcie_get_tfd(struct iwl_trans *trans,
{
struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans);
- if (trans->cfg->use_tfh)
+ if (trans->trans_cfg->use_tfh)
idx = iwl_pcie_get_cmd_index(txq, idx);
return txq->tfds + trans_pcie->tfd_size * idx;
@@ -955,7 +959,7 @@ static inline void iwl_enable_rfkill_int(struct iwl_trans *trans)
MSIX_HW_INT_CAUSES_REG_RF_KILL);
}
- if (trans->cfg->device_family >= IWL_DEVICE_FAMILY_9000) {
+ if (trans->trans_cfg->device_family >= IWL_DEVICE_FAMILY_9000) {
/*
* On 9000-series devices this bit isn't enabled by default, so
* when we power down the device we need set the bit to allow it
@@ -1045,7 +1049,7 @@ static inline void __iwl_trans_pcie_set_bit(struct iwl_trans *trans,
static inline bool iwl_pcie_dbg_on(struct iwl_trans *trans)
{
- return (trans->dbg.dest_tlv || trans->dbg.ini_valid);
+ return (trans->dbg.dest_tlv || iwl_trans_dbg_ini_valid(trans));
}
void iwl_trans_pcie_rf_kill(struct iwl_trans *trans, bool state);
@@ -1058,9 +1062,6 @@ void iwl_trans_pcie_dbgfs_register(struct iwl_trans *trans);
static inline void iwl_trans_pcie_dbgfs_register(struct iwl_trans *trans) { }
#endif
-int iwl_pci_fw_exit_d0i3(struct iwl_trans *trans);
-int iwl_pci_fw_enter_d0i3(struct iwl_trans *trans);
-
void iwl_pcie_rx_allocator_work(struct work_struct *data);
/* common functions that are used by gen2 transport */
@@ -1113,10 +1114,11 @@ int iwl_trans_pcie_gen2_tx(struct iwl_trans *trans, struct sk_buff *skb,
struct iwl_device_cmd *dev_cmd, int txq_id);
int iwl_trans_pcie_gen2_send_hcmd(struct iwl_trans *trans,
struct iwl_host_cmd *cmd);
-void iwl_trans_pcie_gen2_stop_device(struct iwl_trans *trans,
- bool low_power);
-void _iwl_trans_pcie_gen2_stop_device(struct iwl_trans *trans, bool low_power);
+void iwl_trans_pcie_gen2_stop_device(struct iwl_trans *trans);
+void _iwl_trans_pcie_gen2_stop_device(struct iwl_trans *trans);
void iwl_pcie_gen2_txq_unmap(struct iwl_trans *trans, int txq_id);
void iwl_pcie_gen2_tx_free(struct iwl_trans *trans);
void iwl_pcie_gen2_tx_stop(struct iwl_trans *trans);
+void iwl_pcie_d3_complete_suspend(struct iwl_trans *trans,
+ bool test, bool reset);
#endif /* __iwl_trans_int_pcie_h__ */
diff --git a/drivers/net/wireless/intel/iwlwifi/pcie/rx.c b/drivers/net/wireless/intel/iwlwifi/pcie/rx.c
index a2d709642b2a..19dd075f2f63 100644
--- a/drivers/net/wireless/intel/iwlwifi/pcie/rx.c
+++ b/drivers/net/wireless/intel/iwlwifi/pcie/rx.c
@@ -200,12 +200,12 @@ static inline __le32 iwl_pcie_dma_addr2rbd_ptr(dma_addr_t dma_addr)
*/
int iwl_pcie_rx_stop(struct iwl_trans *trans)
{
- if (trans->cfg->device_family >= IWL_DEVICE_FAMILY_22560) {
+ if (trans->trans_cfg->device_family >= IWL_DEVICE_FAMILY_22560) {
/* TODO: remove this for 22560 once fw does it */
iwl_write_umac_prph(trans, RFH_RXF_DMA_CFG_GEN3, 0);
return iwl_poll_umac_prph_bit(trans, RFH_GEN_STATUS_GEN3,
RXF_DMA_IDLE, RXF_DMA_IDLE, 1000);
- } else if (trans->cfg->mq_rx_supported) {
+ } else if (trans->trans_cfg->mq_rx_supported) {
iwl_write_prph(trans, RFH_RXF_DMA_CFG, 0);
return iwl_poll_prph_bit(trans, RFH_GEN_STATUS,
RXF_DMA_IDLE, RXF_DMA_IDLE, 1000);
@@ -232,7 +232,7 @@ static void iwl_pcie_rxq_inc_wr_ptr(struct iwl_trans *trans,
* 1. shadow registers aren't enabled
* 2. there is a chance that the NIC is asleep
*/
- if (!trans->cfg->base_params->shadow_reg_enable &&
+ if (!trans->trans_cfg->base_params->shadow_reg_enable &&
test_bit(STATUS_TPOWER_PMI, &trans->status)) {
reg = iwl_read32(trans, CSR_UCODE_DRV_GP1);
@@ -240,18 +240,18 @@ static void iwl_pcie_rxq_inc_wr_ptr(struct iwl_trans *trans,
IWL_DEBUG_INFO(trans, "Rx queue requesting wakeup, GP1 = 0x%x\n",
reg);
iwl_set_bit(trans, CSR_GP_CNTRL,
- BIT(trans->cfg->csr->flag_mac_access_req));
+ BIT(trans->trans_cfg->csr->flag_mac_access_req));
rxq->need_update = true;
return;
}
}
rxq->write_actual = round_down(rxq->write, 8);
- if (trans->cfg->device_family == IWL_DEVICE_FAMILY_22560)
+ if (trans->trans_cfg->device_family == IWL_DEVICE_FAMILY_22560)
iwl_write32(trans, HBUS_TARG_WRPTR,
(rxq->write_actual |
((FIRST_RX_QUEUE + rxq->id) << 16)));
- else if (trans->cfg->mq_rx_supported)
+ else if (trans->trans_cfg->mq_rx_supported)
iwl_write32(trans, RFH_Q_FRBDCB_WIDX_TRG(rxq->id),
rxq->write_actual);
else
@@ -279,7 +279,7 @@ static void iwl_pcie_restock_bd(struct iwl_trans *trans,
struct iwl_rxq *rxq,
struct iwl_rx_mem_buffer *rxb)
{
- if (trans->cfg->device_family >= IWL_DEVICE_FAMILY_22560) {
+ if (trans->trans_cfg->device_family >= IWL_DEVICE_FAMILY_22560) {
struct iwl_rx_transfer_desc *bd = rxq->bd;
BUILD_BUG_ON(sizeof(*bd) != 2 * sizeof(u64));
@@ -405,7 +405,7 @@ static void iwl_pcie_rxsq_restock(struct iwl_trans *trans,
static
void iwl_pcie_rxq_restock(struct iwl_trans *trans, struct iwl_rxq *rxq)
{
- if (trans->cfg->mq_rx_supported)
+ if (trans->trans_cfg->mq_rx_supported)
iwl_pcie_rxmq_restock(trans, rxq);
else
iwl_pcie_rxsq_restock(trans, rxq);
@@ -682,7 +682,7 @@ static int iwl_pcie_free_bd_size(struct iwl_trans *trans, bool use_rx_td)
if (use_rx_td)
return sizeof(*rx_td);
else
- return trans->cfg->mq_rx_supported ? sizeof(__le64) :
+ return trans->trans_cfg->mq_rx_supported ? sizeof(__le64) :
sizeof(__le32);
}
@@ -690,7 +690,7 @@ static void iwl_pcie_free_rxq_dma(struct iwl_trans *trans,
struct iwl_rxq *rxq)
{
struct device *dev = trans->dev;
- bool use_rx_td = (trans->cfg->device_family >=
+ bool use_rx_td = (trans->trans_cfg->device_family >=
IWL_DEVICE_FAMILY_22560);
int free_size = iwl_pcie_free_bd_size(trans, use_rx_td);
@@ -712,7 +712,7 @@ static void iwl_pcie_free_rxq_dma(struct iwl_trans *trans,
rxq->used_bd_dma = 0;
rxq->used_bd = NULL;
- if (trans->cfg->device_family < IWL_DEVICE_FAMILY_22560)
+ if (trans->trans_cfg->device_family < IWL_DEVICE_FAMILY_22560)
return;
if (rxq->tr_tail)
@@ -735,13 +735,13 @@ static int iwl_pcie_alloc_rxq_dma(struct iwl_trans *trans,
struct device *dev = trans->dev;
int i;
int free_size;
- bool use_rx_td = (trans->cfg->device_family >=
+ bool use_rx_td = (trans->trans_cfg->device_family >=
IWL_DEVICE_FAMILY_22560);
size_t rb_stts_size = use_rx_td ? sizeof(__le16) :
sizeof(struct iwl_rb_status);
spin_lock_init(&rxq->lock);
- if (trans->cfg->mq_rx_supported)
+ if (trans->trans_cfg->mq_rx_supported)
rxq->queue_size = MQ_RX_TABLE_SIZE;
else
rxq->queue_size = RX_QUEUE_SIZE;
@@ -757,7 +757,7 @@ static int iwl_pcie_alloc_rxq_dma(struct iwl_trans *trans,
if (!rxq->bd)
goto err;
- if (trans->cfg->mq_rx_supported) {
+ if (trans->trans_cfg->mq_rx_supported) {
rxq->used_bd = dma_alloc_coherent(dev,
(use_rx_td ? sizeof(*rxq->cd) : sizeof(__le32)) * rxq->queue_size,
&rxq->used_bd_dma,
@@ -807,7 +807,7 @@ int iwl_pcie_rx_alloc(struct iwl_trans *trans)
struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans);
struct iwl_rb_allocator *rba = &trans_pcie->rba;
int i, ret;
- size_t rb_stts_size = trans->cfg->device_family >=
+ size_t rb_stts_size = trans->trans_cfg->device_family >=
IWL_DEVICE_FAMILY_22560 ?
sizeof(__le16) : sizeof(struct iwl_rb_status);
@@ -1074,8 +1074,8 @@ int _iwl_pcie_rx_init(struct iwl_trans *trans)
rxq->read = 0;
rxq->write = 0;
rxq->write_actual = 0;
- memset(rxq->rb_stts, 0,
- (trans->cfg->device_family >= IWL_DEVICE_FAMILY_22560) ?
+ memset(rxq->rb_stts, 0, (trans->trans_cfg->device_family >=
+ IWL_DEVICE_FAMILY_22560) ?
sizeof(__le16) : sizeof(struct iwl_rb_status));
iwl_pcie_rx_init_rxb_lists(rxq);
@@ -1088,7 +1088,7 @@ int _iwl_pcie_rx_init(struct iwl_trans *trans)
}
/* move the pool to the default queue and allocator ownerships */
- queue_size = trans->cfg->mq_rx_supported ?
+ queue_size = trans->trans_cfg->mq_rx_supported ?
MQ_RX_NUM_RBDS : RX_QUEUE_SIZE;
allocator_pool_size = trans->num_rx_queues *
(RX_CLAIM_REQ_ALLOC - RX_POST_REQ_ALLOC);
@@ -1120,7 +1120,7 @@ int iwl_pcie_rx_init(struct iwl_trans *trans)
if (ret)
return ret;
- if (trans->cfg->mq_rx_supported)
+ if (trans->trans_cfg->mq_rx_supported)
iwl_pcie_rx_mq_hw_init(trans);
else
iwl_pcie_rx_hw_init(trans, trans_pcie->rxq);
@@ -1151,7 +1151,7 @@ void iwl_pcie_rx_free(struct iwl_trans *trans)
struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans);
struct iwl_rb_allocator *rba = &trans_pcie->rba;
int i;
- size_t rb_stts_size = trans->cfg->device_family >=
+ size_t rb_stts_size = trans->trans_cfg->device_family >=
IWL_DEVICE_FAMILY_22560 ?
sizeof(__le16) : sizeof(struct iwl_rb_status);
@@ -1347,7 +1347,7 @@ static void iwl_pcie_rx_handle_rb(struct iwl_trans *trans,
}
page_stolen |= rxcb._page_stolen;
- if (trans->cfg->device_family >= IWL_DEVICE_FAMILY_22560)
+ if (trans->trans_cfg->device_family >= IWL_DEVICE_FAMILY_22560)
break;
offset += ALIGN(len, FH_RSCSR_FRAME_ALIGN);
}
@@ -1392,14 +1392,14 @@ static struct iwl_rx_mem_buffer *iwl_pcie_get_rxb(struct iwl_trans *trans,
BUILD_BUG_ON(sizeof(struct iwl_rx_completion_desc) != 32);
- if (!trans->cfg->mq_rx_supported) {
+ if (!trans->trans_cfg->mq_rx_supported) {
rxb = rxq->queue[i];
rxq->queue[i] = NULL;
return rxb;
}
/* used_bd is a 32/16 bit but only 12 are used to retrieve the vid */
- if (trans->cfg->device_family >= IWL_DEVICE_FAMILY_22560)
+ if (trans->trans_cfg->device_family >= IWL_DEVICE_FAMILY_22560)
vid = le16_to_cpu(rxq->cd[i].rbid) & 0x0FFF;
else
vid = le32_to_cpu(rxq->bd_32[i]) & 0x0FFF;
@@ -1515,7 +1515,7 @@ out:
/* Backtrack one entry */
rxq->read = i;
/* update cr tail with the rxq read pointer */
- if (trans->cfg->device_family >= IWL_DEVICE_FAMILY_22560)
+ if (trans->trans_cfg->device_family >= IWL_DEVICE_FAMILY_22560)
*rxq->cr_tail = cpu_to_le16(r);
spin_unlock(&rxq->lock);
@@ -1597,7 +1597,7 @@ static void iwl_pcie_irq_handle_error(struct iwl_trans *trans)
return;
}
- for (i = 0; i < trans->cfg->base_params->num_of_queues; i++) {
+ for (i = 0; i < trans->trans_cfg->base_params->num_of_queues; i++) {
if (!trans_pcie->txq[i])
continue;
del_timer(&trans_pcie->txq[i]->stuck_timer);
@@ -1838,7 +1838,7 @@ irqreturn_t iwl_pcie_irq_handler(int irq, void *dev_id)
if (inta & CSR_INT_BIT_ALIVE) {
IWL_DEBUG_ISR(trans, "Alive interrupt\n");
isr_stats->alive++;
- if (trans->cfg->gen2) {
+ if (trans->trans_cfg->gen2) {
/*
* We can restock, since firmware configured
* the RFH
@@ -2179,13 +2179,13 @@ irqreturn_t iwl_pcie_irq_msix_handler(int irq, void *dev_id)
if (inta_hw & MSIX_HW_INT_CAUSES_REG_ALIVE) {
IWL_DEBUG_ISR(trans, "Alive interrupt\n");
isr_stats->alive++;
- if (trans->cfg->gen2) {
+ if (trans->trans_cfg->gen2) {
/* We can restock, since firmware configured the RFH */
iwl_pcie_rxmq_restock(trans, trans_pcie->rxq);
}
}
- if (trans->cfg->device_family == IWL_DEVICE_FAMILY_22560 &&
+ if (trans->trans_cfg->device_family == IWL_DEVICE_FAMILY_22560 &&
inta_hw & MSIX_HW_INT_CAUSES_REG_IPC) {
/* Reflect IML transfer status */
int res = iwl_read32(trans, CSR_IML_RESP_ADDR);
@@ -2196,12 +2196,23 @@ irqreturn_t iwl_pcie_irq_msix_handler(int irq, void *dev_id)
iwl_pcie_irq_handle_error(trans);
}
} else if (inta_hw & MSIX_HW_INT_CAUSES_REG_WAKEUP) {
- /* uCode wakes up after power-down sleep */
- IWL_DEBUG_ISR(trans, "Wakeup interrupt\n");
- iwl_pcie_rxq_check_wrptr(trans);
- iwl_pcie_txq_check_wrptrs(trans);
+ u32 sleep_notif =
+ le32_to_cpu(trans_pcie->prph_info->sleep_notif);
+ if (sleep_notif == IWL_D3_SLEEP_STATUS_SUSPEND ||
+ sleep_notif == IWL_D3_SLEEP_STATUS_RESUME) {
+ IWL_DEBUG_ISR(trans,
+ "Sx interrupt: sleep notification = 0x%x\n",
+ sleep_notif);
+ trans_pcie->sx_complete = true;
+ wake_up(&trans_pcie->sx_waitq);
+ } else {
+ /* uCode wakes up after power-down sleep */
+ IWL_DEBUG_ISR(trans, "Wakeup interrupt\n");
+ iwl_pcie_rxq_check_wrptr(trans);
+ iwl_pcie_txq_check_wrptrs(trans);
- isr_stats->wakeup++;
+ isr_stats->wakeup++;
+ }
}
if (inta_hw & MSIX_HW_INT_CAUSES_REG_IML) {
diff --git a/drivers/net/wireless/intel/iwlwifi/pcie/trans-gen2.c b/drivers/net/wireless/intel/iwlwifi/pcie/trans-gen2.c
index 8d17e68577fd..df8455f14e4d 100644
--- a/drivers/net/wireless/intel/iwlwifi/pcie/trans-gen2.c
+++ b/drivers/net/wireless/intel/iwlwifi/pcie/trans-gen2.c
@@ -92,7 +92,7 @@ int iwl_pcie_gen2_apm_init(struct iwl_trans *trans)
iwl_pcie_apm_config(trans);
- ret = iwl_finish_nic_init(trans);
+ ret = iwl_finish_nic_init(trans, trans->trans_cfg);
if (ret)
return ret;
@@ -133,10 +133,10 @@ static void iwl_pcie_gen2_apm_stop(struct iwl_trans *trans, bool op_mode_leave)
* D0A* (powered-up Active) --> D0U* (Uninitialized) state.
*/
iwl_clear_bit(trans, CSR_GP_CNTRL,
- BIT(trans->cfg->csr->flag_init_done));
+ BIT(trans->trans_cfg->csr->flag_init_done));
}
-void _iwl_trans_pcie_gen2_stop_device(struct iwl_trans *trans, bool low_power)
+void _iwl_trans_pcie_gen2_stop_device(struct iwl_trans *trans)
{
struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans);
@@ -147,9 +147,6 @@ void _iwl_trans_pcie_gen2_stop_device(struct iwl_trans *trans, bool low_power)
trans_pcie->is_down = true;
- /* Stop dbgc before stopping device */
- iwl_fw_dbg_stop_recording(trans, NULL);
-
/* tell the device to stop sending interrupts */
iwl_disable_interrupts(trans);
@@ -171,14 +168,14 @@ void _iwl_trans_pcie_gen2_stop_device(struct iwl_trans *trans, bool low_power)
}
iwl_pcie_ctxt_info_free_paging(trans);
- if (trans->cfg->device_family >= IWL_DEVICE_FAMILY_22560)
+ if (trans->trans_cfg->device_family >= IWL_DEVICE_FAMILY_22560)
iwl_pcie_ctxt_info_gen3_free(trans);
else
iwl_pcie_ctxt_info_free(trans);
/* Make sure (redundant) we've released our request to stay awake */
iwl_clear_bit(trans, CSR_GP_CNTRL,
- BIT(trans->cfg->csr->flag_mac_access_req));
+ BIT(trans->trans_cfg->csr->flag_mac_access_req));
/* Stop the device, and put it in low power state */
iwl_pcie_gen2_apm_stop(trans, false);
@@ -218,7 +215,7 @@ void _iwl_trans_pcie_gen2_stop_device(struct iwl_trans *trans, bool low_power)
iwl_pcie_prepare_card_hw(trans);
}
-void iwl_trans_pcie_gen2_stop_device(struct iwl_trans *trans, bool low_power)
+void iwl_trans_pcie_gen2_stop_device(struct iwl_trans *trans)
{
struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans);
bool was_in_rfkill;
@@ -226,7 +223,7 @@ void iwl_trans_pcie_gen2_stop_device(struct iwl_trans *trans, bool low_power)
mutex_lock(&trans_pcie->mutex);
trans_pcie->opmode_down = true;
was_in_rfkill = test_bit(STATUS_RFKILL_OPMODE, &trans->status);
- _iwl_trans_pcie_gen2_stop_device(trans, low_power);
+ _iwl_trans_pcie_gen2_stop_device(trans);
iwl_trans_pcie_handle_stop_rfkill(trans, was_in_rfkill);
mutex_unlock(&trans_pcie->mutex);
}
@@ -343,7 +340,7 @@ int iwl_trans_pcie_gen2_start_fw(struct iwl_trans *trans,
goto out;
}
- if (trans->cfg->device_family >= IWL_DEVICE_FAMILY_22560)
+ if (trans->trans_cfg->device_family >= IWL_DEVICE_FAMILY_22560)
ret = iwl_pcie_ctxt_info_gen3_init(trans, fw);
else
ret = iwl_pcie_ctxt_info_init(trans, fw);
diff --git a/drivers/net/wireless/intel/iwlwifi/pcie/trans.c b/drivers/net/wireless/intel/iwlwifi/pcie/trans.c
index f5df5b370d78..6961f00ff812 100644
--- a/drivers/net/wireless/intel/iwlwifi/pcie/trans.c
+++ b/drivers/net/wireless/intel/iwlwifi/pcie/trans.c
@@ -62,14 +62,12 @@
*
*****************************************************************************/
#include <linux/pci.h>
-#include <linux/pci-aspm.h>
#include <linux/interrupt.h>
#include <linux/debugfs.h>
#include <linux/sched.h>
#include <linux/bitops.h>
#include <linux/gfp.h>
#include <linux/vmalloc.h>
-#include <linux/pm_runtime.h>
#include <linux/module.h>
#include <linux/wait.h>
@@ -185,8 +183,8 @@ out:
static void iwl_trans_pcie_sw_reset(struct iwl_trans *trans)
{
/* Reset entire device - do controller reset (results in SHRD_HW_RST) */
- iwl_set_bit(trans, trans->cfg->csr->addr_sw_reset,
- BIT(trans->cfg->csr->flag_sw_reset));
+ iwl_set_bit(trans, trans->trans_cfg->csr->addr_sw_reset,
+ BIT(trans->trans_cfg->csr->flag_sw_reset));
usleep_range(5000, 6000);
}
@@ -216,8 +214,7 @@ static void iwl_pcie_alloc_fw_monitor_block(struct iwl_trans *trans,
for (power = max_power; power >= min_power; power--) {
size = BIT(power);
cpu_addr = dma_alloc_coherent(trans->dev, size, &phys,
- GFP_KERNEL | __GFP_NOWARN |
- __GFP_ZERO | __GFP_COMP);
+ GFP_KERNEL | __GFP_NOWARN);
if (!cpu_addr)
continue;
@@ -343,7 +340,7 @@ static int iwl_pcie_apm_init(struct iwl_trans *trans)
*/
/* Disable L0S exit timer (platform NMI Work/Around) */
- if (trans->cfg->device_family < IWL_DEVICE_FAMILY_8000)
+ if (trans->trans_cfg->device_family < IWL_DEVICE_FAMILY_8000)
iwl_set_bit(trans, CSR_GIO_CHICKEN_BITS,
CSR_GIO_CHICKEN_BITS_REG_BIT_DIS_L0S_EXIT_TIMER);
@@ -367,10 +364,10 @@ static int iwl_pcie_apm_init(struct iwl_trans *trans)
iwl_pcie_apm_config(trans);
/* Configure analog phase-lock-loop before activating to D0A */
- if (trans->cfg->base_params->pll_cfg)
+ if (trans->trans_cfg->base_params->pll_cfg)
iwl_set_bit(trans, CSR_ANA_PLL_CFG, CSR50_ANA_PLL_CFG_VAL);
- ret = iwl_finish_nic_init(trans);
+ ret = iwl_finish_nic_init(trans, trans->trans_cfg);
if (ret)
return ret;
@@ -442,7 +439,7 @@ static void iwl_pcie_apm_lp_xtal_enable(struct iwl_trans *trans)
iwl_trans_pcie_sw_reset(trans);
- ret = iwl_finish_nic_init(trans);
+ ret = iwl_finish_nic_init(trans, trans->trans_cfg);
if (WARN_ON(ret)) {
/* Release XTAL ON request */
__iwl_trans_pcie_clear_bit(trans, CSR_GP_CNTRL,
@@ -492,7 +489,7 @@ static void iwl_pcie_apm_lp_xtal_enable(struct iwl_trans *trans)
* D0A* (powered-up Active) --> D0U* (Uninitialized) state.
*/
iwl_clear_bit(trans, CSR_GP_CNTRL,
- BIT(trans->cfg->csr->flag_init_done));
+ BIT(trans->trans_cfg->csr->flag_init_done));
/* Activates XTAL resources monitor */
__iwl_trans_pcie_set_bit(trans, CSR_MONITOR_CFG_REG,
@@ -514,12 +511,12 @@ void iwl_pcie_apm_stop_master(struct iwl_trans *trans)
int ret;
/* stop device's busmaster DMA activity */
- iwl_set_bit(trans, trans->cfg->csr->addr_sw_reset,
- BIT(trans->cfg->csr->flag_stop_master));
+ iwl_set_bit(trans, trans->trans_cfg->csr->addr_sw_reset,
+ BIT(trans->trans_cfg->csr->flag_stop_master));
- ret = iwl_poll_bit(trans, trans->cfg->csr->addr_sw_reset,
- BIT(trans->cfg->csr->flag_master_dis),
- BIT(trans->cfg->csr->flag_master_dis), 100);
+ ret = iwl_poll_bit(trans, trans->trans_cfg->csr->addr_sw_reset,
+ BIT(trans->trans_cfg->csr->flag_master_dis),
+ BIT(trans->trans_cfg->csr->flag_master_dis), 100);
if (ret < 0)
IWL_WARN(trans, "Master Disable Timed Out, 100 usec\n");
@@ -535,10 +532,11 @@ static void iwl_pcie_apm_stop(struct iwl_trans *trans, bool op_mode_leave)
iwl_pcie_apm_init(trans);
/* inform ME that we are leaving */
- if (trans->cfg->device_family == IWL_DEVICE_FAMILY_7000)
+ if (trans->trans_cfg->device_family == IWL_DEVICE_FAMILY_7000)
iwl_set_bits_prph(trans, APMG_PCIDEV_STT_REG,
APMG_PCIDEV_STT_VAL_WAKE_ME);
- else if (trans->cfg->device_family >= IWL_DEVICE_FAMILY_8000) {
+ else if (trans->trans_cfg->device_family >=
+ IWL_DEVICE_FAMILY_8000) {
iwl_set_bit(trans, CSR_DBG_LINK_PWR_MGMT_REG,
CSR_RESET_LINK_PWR_MGMT_DISABLED);
iwl_set_bit(trans, CSR_HW_IF_CONFIG_REG,
@@ -568,7 +566,7 @@ static void iwl_pcie_apm_stop(struct iwl_trans *trans, bool op_mode_leave)
* D0A* (powered-up Active) --> D0U* (Uninitialized) state.
*/
iwl_clear_bit(trans, CSR_GP_CNTRL,
- BIT(trans->cfg->csr->flag_init_done));
+ BIT(trans->trans_cfg->csr->flag_init_done));
}
static int iwl_pcie_nic_init(struct iwl_trans *trans)
@@ -595,7 +593,7 @@ static int iwl_pcie_nic_init(struct iwl_trans *trans)
if (iwl_pcie_tx_init(trans))
return -ENOMEM;
- if (trans->cfg->base_params->shadow_reg_enable) {
+ if (trans->trans_cfg->base_params->shadow_reg_enable) {
/* enable shadow regs in HW */
iwl_set_bit(trans, CSR_MAC_SHADOW_REG_CTRL, 0x800FFFFF);
IWL_DEBUG_INFO(trans, "Enabling shadow registers in device\n");
@@ -833,7 +831,7 @@ static int iwl_pcie_load_cpu_sections_8000(struct iwl_trans *trans,
iwl_enable_interrupts(trans);
- if (trans->cfg->use_tfh) {
+ if (trans->trans_cfg->use_tfh) {
if (cpu == 1)
iwl_write_prph(trans, UREG_UCODE_LOAD_STATUS,
0xFFFF);
@@ -898,12 +896,12 @@ void iwl_pcie_apply_destination(struct iwl_trans *trans)
const struct iwl_fw_dbg_dest_tlv_v1 *dest = trans->dbg.dest_tlv;
int i;
- if (trans->dbg.ini_valid) {
+ if (iwl_trans_dbg_ini_valid(trans)) {
if (!trans->dbg.num_blocks)
return;
IWL_DEBUG_FW(trans,
- "WRT: applying DRAM buffer[0] destination\n");
+ "WRT: Applying DRAM buffer[0] destination\n");
iwl_write_umac_prph(trans, MON_BUFF_BASE_ADDR_VER2,
trans->dbg.fw_mon[0].physical >>
MON_BUFF_SHIFT_VER2);
@@ -965,7 +963,7 @@ monitor:
iwl_write_prph(trans, le32_to_cpu(dest->base_reg),
trans->dbg.fw_mon[0].physical >>
dest->base_shift);
- if (trans->cfg->device_family >= IWL_DEVICE_FAMILY_8000)
+ if (trans->trans_cfg->device_family >= IWL_DEVICE_FAMILY_8000)
iwl_write_prph(trans, le32_to_cpu(dest->end_reg),
(trans->dbg.fw_mon[0].physical +
trans->dbg.fw_mon[0].size - 256) >>
@@ -1007,7 +1005,7 @@ static int iwl_pcie_load_given_ucode(struct iwl_trans *trans,
/* supported for 7000 only for the moment */
if (iwlwifi_mod_params.fw_monitor &&
- trans->cfg->device_family == IWL_DEVICE_FAMILY_7000) {
+ trans->trans_cfg->device_family == IWL_DEVICE_FAMILY_7000) {
iwl_pcie_alloc_fw_monitor(trans, 0);
if (trans->dbg.fw_mon[0].size) {
@@ -1136,7 +1134,7 @@ static void iwl_pcie_map_non_rx_causes(struct iwl_trans *trans)
struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans);
int val = trans_pcie->def_irq | MSIX_NON_AUTO_CLEAR_CAUSE;
int i, arr_size =
- (trans->cfg->device_family != IWL_DEVICE_FAMILY_22560) ?
+ (trans->trans_cfg->device_family != IWL_DEVICE_FAMILY_22560) ?
ARRAY_SIZE(causes_list) : ARRAY_SIZE(causes_list_v2);
/*
@@ -1146,7 +1144,8 @@ static void iwl_pcie_map_non_rx_causes(struct iwl_trans *trans)
*/
for (i = 0; i < arr_size; i++) {
struct iwl_causes_list *causes =
- (trans->cfg->device_family != IWL_DEVICE_FAMILY_22560) ?
+ (trans->trans_cfg->device_family !=
+ IWL_DEVICE_FAMILY_22560) ?
causes_list : causes_list_v2;
iwl_write8(trans, CSR_MSIX_IVAR(causes[i].addr), val);
@@ -1190,7 +1189,7 @@ void iwl_pcie_conf_msix_hw(struct iwl_trans_pcie *trans_pcie)
struct iwl_trans *trans = trans_pcie->trans;
if (!trans_pcie->msix_enabled) {
- if (trans->cfg->mq_rx_supported &&
+ if (trans->trans_cfg->mq_rx_supported &&
test_bit(STATUS_DEVICE_ENABLED, &trans->status))
iwl_write_umac_prph(trans, UREG_CHICK,
UREG_CHICK_MSI_ENABLE);
@@ -1231,7 +1230,7 @@ static void iwl_pcie_init_msix(struct iwl_trans_pcie *trans_pcie)
trans_pcie->hw_mask = trans_pcie->hw_init_mask;
}
-static void _iwl_trans_pcie_stop_device(struct iwl_trans *trans, bool low_power)
+static void _iwl_trans_pcie_stop_device(struct iwl_trans *trans)
{
struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans);
@@ -1242,9 +1241,6 @@ static void _iwl_trans_pcie_stop_device(struct iwl_trans *trans, bool low_power)
trans_pcie->is_down = true;
- /* Stop dbgc before stopping device */
- iwl_fw_dbg_stop_recording(trans, NULL);
-
/* tell the device to stop sending interrupts */
iwl_disable_interrupts(trans);
@@ -1274,7 +1270,7 @@ static void _iwl_trans_pcie_stop_device(struct iwl_trans *trans, bool low_power)
/* Make sure (redundant) we've released our request to stay awake */
iwl_clear_bit(trans, CSR_GP_CNTRL,
- BIT(trans->cfg->csr->flag_mac_access_req));
+ BIT(trans->trans_cfg->csr->flag_mac_access_req));
/* Stop the device, and put it in low power state */
iwl_pcie_apm_stop(trans, false);
@@ -1401,7 +1397,7 @@ static int iwl_trans_pcie_start_fw(struct iwl_trans *trans,
iwl_write32(trans, CSR_UCODE_DRV_GP1_CLR, CSR_UCODE_SW_BIT_RFKILL);
/* Load the given image to the HW */
- if (trans->cfg->device_family >= IWL_DEVICE_FAMILY_8000)
+ if (trans->trans_cfg->device_family >= IWL_DEVICE_FAMILY_8000)
ret = iwl_pcie_load_given_ucode_8000(trans, fw);
else
ret = iwl_pcie_load_given_ucode(trans, fw);
@@ -1451,7 +1447,7 @@ void iwl_trans_pcie_handle_stop_rfkill(struct iwl_trans *trans,
iwl_trans_pcie_rf_kill(trans, hw_rfkill);
}
-static void iwl_trans_pcie_stop_device(struct iwl_trans *trans, bool low_power)
+static void iwl_trans_pcie_stop_device(struct iwl_trans *trans)
{
struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans);
bool was_in_rfkill;
@@ -1459,7 +1455,7 @@ static void iwl_trans_pcie_stop_device(struct iwl_trans *trans, bool low_power)
mutex_lock(&trans_pcie->mutex);
trans_pcie->opmode_down = true;
was_in_rfkill = test_bit(STATUS_RFKILL_OPMODE, &trans->status);
- _iwl_trans_pcie_stop_device(trans, low_power);
+ _iwl_trans_pcie_stop_device(trans);
iwl_trans_pcie_handle_stop_rfkill(trans, was_in_rfkill);
mutex_unlock(&trans_pcie->mutex);
}
@@ -1474,22 +1470,16 @@ void iwl_trans_pcie_rf_kill(struct iwl_trans *trans, bool state)
IWL_WARN(trans, "reporting RF_KILL (radio %s)\n",
state ? "disabled" : "enabled");
if (iwl_op_mode_hw_rf_kill(trans->op_mode, state)) {
- if (trans->cfg->gen2)
- _iwl_trans_pcie_gen2_stop_device(trans, true);
+ if (trans->trans_cfg->gen2)
+ _iwl_trans_pcie_gen2_stop_device(trans);
else
- _iwl_trans_pcie_stop_device(trans, true);
+ _iwl_trans_pcie_stop_device(trans);
}
}
-static void iwl_trans_pcie_d3_suspend(struct iwl_trans *trans, bool test,
- bool reset)
+void iwl_pcie_d3_complete_suspend(struct iwl_trans *trans,
+ bool test, bool reset)
{
- if (!reset) {
- /* Enable persistence mode to avoid reset */
- iwl_set_bit(trans, CSR_HW_IF_CONFIG_REG,
- CSR_HW_IF_CONFIG_REG_PERSIST_MODE);
- }
-
iwl_disable_interrupts(trans);
/*
@@ -1504,9 +1494,9 @@ static void iwl_trans_pcie_d3_suspend(struct iwl_trans *trans, bool test,
iwl_pcie_synchronize_irqs(trans);
iwl_clear_bit(trans, CSR_GP_CNTRL,
- BIT(trans->cfg->csr->flag_mac_access_req));
+ BIT(trans->trans_cfg->csr->flag_mac_access_req));
iwl_clear_bit(trans, CSR_GP_CNTRL,
- BIT(trans->cfg->csr->flag_init_done));
+ BIT(trans->trans_cfg->csr->flag_init_done));
if (reset) {
/*
@@ -1520,6 +1510,42 @@ static void iwl_trans_pcie_d3_suspend(struct iwl_trans *trans, bool test,
iwl_pcie_set_pwr(trans, true);
}
+static int iwl_trans_pcie_d3_suspend(struct iwl_trans *trans, bool test,
+ bool reset)
+{
+ int ret;
+ struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans);
+
+ /*
+ * Family IWL_DEVICE_FAMILY_AX210 and above persist mode is set by FW.
+ */
+ if (!reset && trans->trans_cfg->device_family < IWL_DEVICE_FAMILY_AX210) {
+ /* Enable persistence mode to avoid reset */
+ iwl_set_bit(trans, CSR_HW_IF_CONFIG_REG,
+ CSR_HW_IF_CONFIG_REG_PERSIST_MODE);
+ }
+
+ if (trans->trans_cfg->device_family >= IWL_DEVICE_FAMILY_AX210) {
+ iwl_write_umac_prph(trans, UREG_DOORBELL_TO_ISR6,
+ UREG_DOORBELL_TO_ISR6_SUSPEND);
+
+ ret = wait_event_timeout(trans_pcie->sx_waitq,
+ trans_pcie->sx_complete, 2 * HZ);
+ /*
+ * Invalidate it toward resume.
+ */
+ trans_pcie->sx_complete = false;
+
+ if (!ret) {
+ IWL_ERR(trans, "Timeout entering D3\n");
+ return -ETIMEDOUT;
+ }
+ }
+ iwl_pcie_d3_complete_suspend(trans, test, reset);
+
+ return 0;
+}
+
static int iwl_trans_pcie_d3_resume(struct iwl_trans *trans,
enum iwl_d3_status *status,
bool test, bool reset)
@@ -1531,13 +1557,13 @@ static int iwl_trans_pcie_d3_resume(struct iwl_trans *trans,
if (test) {
iwl_enable_interrupts(trans);
*status = IWL_D3_STATUS_ALIVE;
- return 0;
+ goto out;
}
iwl_set_bit(trans, CSR_GP_CNTRL,
- BIT(trans->cfg->csr->flag_mac_access_req));
+ BIT(trans->trans_cfg->csr->flag_mac_access_req));
- ret = iwl_finish_nic_init(trans);
+ ret = iwl_finish_nic_init(trans, trans->trans_cfg);
if (ret)
return ret;
@@ -1557,7 +1583,7 @@ static int iwl_trans_pcie_d3_resume(struct iwl_trans *trans,
if (!reset) {
iwl_clear_bit(trans, CSR_GP_CNTRL,
- BIT(trans->cfg->csr->flag_mac_access_req));
+ BIT(trans->trans_cfg->csr->flag_mac_access_req));
} else {
iwl_trans_pcie_tx_reset(trans);
@@ -1578,17 +1604,38 @@ static int iwl_trans_pcie_d3_resume(struct iwl_trans *trans,
else
*status = IWL_D3_STATUS_ALIVE;
+out:
+ if (*status == IWL_D3_STATUS_ALIVE &&
+ trans->trans_cfg->device_family >= IWL_DEVICE_FAMILY_AX210) {
+ trans_pcie->sx_complete = false;
+ iwl_write_umac_prph(trans, UREG_DOORBELL_TO_ISR6,
+ UREG_DOORBELL_TO_ISR6_RESUME);
+
+ ret = wait_event_timeout(trans_pcie->sx_waitq,
+ trans_pcie->sx_complete, 2 * HZ);
+ /*
+ * Invalidate it toward next suspend.
+ */
+ trans_pcie->sx_complete = false;
+
+ if (!ret) {
+ IWL_ERR(trans, "Timeout exiting D3\n");
+ return -ETIMEDOUT;
+ }
+ }
return 0;
}
-static void iwl_pcie_set_interrupt_capa(struct pci_dev *pdev,
- struct iwl_trans *trans)
+static void
+iwl_pcie_set_interrupt_capa(struct pci_dev *pdev,
+ struct iwl_trans *trans,
+ const struct iwl_cfg_trans_params *cfg_trans)
{
struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans);
int max_irqs, num_irqs, i, ret;
u16 pci_cmd;
- if (!trans->cfg->mq_rx_supported)
+ if (!cfg_trans->mq_rx_supported)
goto enable_msi;
max_irqs = min_t(u32, num_online_cpus() + 2, IWL_MAX_RX_HW_QUEUES);
@@ -1709,7 +1756,7 @@ static int iwl_trans_pcie_clear_persistence_bit(struct iwl_trans *trans)
{
u32 hpm, wprot;
- switch (trans->cfg->device_family) {
+ switch (trans->trans_cfg->device_family) {
case IWL_DEVICE_FAMILY_9000:
wprot = PREG_PRPH_WPROT_9000;
break;
@@ -1736,7 +1783,7 @@ static int iwl_trans_pcie_clear_persistence_bit(struct iwl_trans *trans)
return 0;
}
-static int _iwl_trans_pcie_start_hw(struct iwl_trans *trans, bool low_power)
+static int _iwl_trans_pcie_start_hw(struct iwl_trans *trans)
{
struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans);
int err;
@@ -1772,20 +1819,16 @@ static int _iwl_trans_pcie_start_hw(struct iwl_trans *trans, bool low_power)
/* ...rfkill can call stop_device and set it false if needed */
iwl_pcie_check_hw_rf_kill(trans);
- /* Make sure we sync here, because we'll need full access later */
- if (low_power)
- pm_runtime_resume(trans->dev);
-
return 0;
}
-static int iwl_trans_pcie_start_hw(struct iwl_trans *trans, bool low_power)
+static int iwl_trans_pcie_start_hw(struct iwl_trans *trans)
{
struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans);
int ret;
mutex_lock(&trans_pcie->mutex);
- ret = _iwl_trans_pcie_start_hw(trans, low_power);
+ ret = _iwl_trans_pcie_start_hw(trans);
mutex_unlock(&trans_pcie->mutex);
return ret;
@@ -1828,7 +1871,7 @@ static u32 iwl_trans_pcie_read32(struct iwl_trans *trans, u32 ofs)
static u32 iwl_trans_pcie_prph_msk(struct iwl_trans *trans)
{
- if (trans->cfg->device_family >= IWL_DEVICE_FAMILY_22560)
+ if (trans->trans_cfg->device_family >= IWL_DEVICE_FAMILY_22560)
return 0x00FFFFFF;
else
return 0x000FFFFF;
@@ -1899,7 +1942,7 @@ void iwl_trans_pcie_free(struct iwl_trans *trans)
iwl_pcie_synchronize_irqs(trans);
- if (trans->cfg->gen2)
+ if (trans->trans_cfg->gen2)
iwl_pcie_gen2_tx_free(trans);
else
iwl_pcie_tx_free(trans);
@@ -1981,8 +2024,8 @@ static bool iwl_trans_pcie_grab_nic_access(struct iwl_trans *trans,
/* this bit wakes up the NIC */
__iwl_trans_pcie_set_bit(trans, CSR_GP_CNTRL,
- BIT(trans->cfg->csr->flag_mac_access_req));
- if (trans->cfg->device_family >= IWL_DEVICE_FAMILY_8000)
+ BIT(trans->trans_cfg->csr->flag_mac_access_req));
+ if (trans->trans_cfg->device_family >= IWL_DEVICE_FAMILY_8000)
udelay(2);
/*
@@ -2006,8 +2049,8 @@ static bool iwl_trans_pcie_grab_nic_access(struct iwl_trans *trans,
* and do not save/restore SRAM when power cycling.
*/
ret = iwl_poll_bit(trans, CSR_GP_CNTRL,
- BIT(trans->cfg->csr->flag_val_mac_access_en),
- (BIT(trans->cfg->csr->flag_mac_clock_ready) |
+ BIT(trans->trans_cfg->csr->flag_val_mac_access_en),
+ (BIT(trans->trans_cfg->csr->flag_mac_clock_ready) |
CSR_GP_CNTRL_REG_FLAG_GOING_TO_SLEEP), 15000);
if (unlikely(ret < 0)) {
u32 cntrl = iwl_read32(trans, CSR_GP_CNTRL);
@@ -2089,7 +2132,7 @@ static void iwl_trans_pcie_release_nic_access(struct iwl_trans *trans,
goto out;
__iwl_trans_pcie_clear_bit(trans, CSR_GP_CNTRL,
- BIT(trans->cfg->csr->flag_mac_access_req));
+ BIT(trans->trans_cfg->csr->flag_mac_access_req));
/*
* Above we read the CSR_GP_CNTRL register, which will flush
* any previous writes, but we need the write that clears the
@@ -2196,7 +2239,7 @@ static void iwl_trans_pcie_block_txq_ptrs(struct iwl_trans *trans, bool block)
struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans);
int i;
- for (i = 0; i < trans->cfg->base_params->num_of_queues; i++) {
+ for (i = 0; i < trans->trans_cfg->base_params->num_of_queues; i++) {
struct iwl_txq *txq = trans_pcie->txq[i];
if (i == trans_pcie->cmd_queue)
@@ -2227,7 +2270,7 @@ void iwl_trans_pcie_log_scd_error(struct iwl_trans *trans, struct iwl_txq *txq)
bool active;
u8 fifo;
- if (trans->cfg->use_tfh) {
+ if (trans->trans_cfg->use_tfh) {
IWL_ERR(trans, "Queue %d is stuck %d %d\n", txq_id,
txq->read_ptr, txq->write_ptr);
/* TODO: access new SCD registers and dump them */
@@ -2244,10 +2287,10 @@ void iwl_trans_pcie_log_scd_error(struct iwl_trans *trans, struct iwl_txq *txq)
jiffies_to_msecs(txq->wd_timeout),
txq->read_ptr, txq->write_ptr,
iwl_read_prph(trans, SCD_QUEUE_RDPTR(txq_id)) &
- (trans->cfg->base_params->max_tfd_queue_size - 1),
- iwl_read_prph(trans, SCD_QUEUE_WRPTR(txq_id)) &
- (trans->cfg->base_params->max_tfd_queue_size - 1),
- iwl_read_direct32(trans, FH_TX_TRB_REG(fifo)));
+ (trans->trans_cfg->base_params->max_tfd_queue_size - 1),
+ iwl_read_prph(trans, SCD_QUEUE_WRPTR(txq_id)) &
+ (trans->trans_cfg->base_params->max_tfd_queue_size - 1),
+ iwl_read_direct32(trans, FH_TX_TRB_REG(fifo)));
}
static int iwl_trans_pcie_rxq_dma_data(struct iwl_trans *trans, int queue,
@@ -2335,7 +2378,9 @@ static int iwl_trans_pcie_wait_txqs_empty(struct iwl_trans *trans, u32 txq_bm)
int ret = 0;
/* waiting for all the tx frames complete might take a while */
- for (cnt = 0; cnt < trans->cfg->base_params->num_of_queues; cnt++) {
+ for (cnt = 0;
+ cnt < trans->trans_cfg->base_params->num_of_queues;
+ cnt++) {
if (cnt == trans_pcie->cmd_queue)
continue;
@@ -2363,37 +2408,6 @@ static void iwl_trans_pcie_set_bits_mask(struct iwl_trans *trans, u32 reg,
spin_unlock_irqrestore(&trans_pcie->reg_lock, flags);
}
-static void iwl_trans_pcie_ref(struct iwl_trans *trans)
-{
- struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans);
-
- if (iwlwifi_mod_params.d0i3_disable)
- return;
-
- pm_runtime_get(&trans_pcie->pci_dev->dev);
-
-#ifdef CONFIG_PM
- IWL_DEBUG_RPM(trans, "runtime usage count: %d\n",
- atomic_read(&trans_pcie->pci_dev->dev.power.usage_count));
-#endif /* CONFIG_PM */
-}
-
-static void iwl_trans_pcie_unref(struct iwl_trans *trans)
-{
- struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans);
-
- if (iwlwifi_mod_params.d0i3_disable)
- return;
-
- pm_runtime_mark_last_busy(&trans_pcie->pci_dev->dev);
- pm_runtime_put_autosuspend(&trans_pcie->pci_dev->dev);
-
-#ifdef CONFIG_PM
- IWL_DEBUG_RPM(trans, "runtime usage count: %d\n",
- atomic_read(&trans_pcie->pci_dev->dev.power.usage_count));
-#endif /* CONFIG_PM */
-}
-
static const char *get_csr_string(int cmd)
{
#define IWL_CMD(x) case x: return #x
@@ -2510,7 +2524,8 @@ static ssize_t iwl_dbgfs_tx_queue_read(struct file *file,
int ret;
size_t bufsz;
- bufsz = sizeof(char) * 75 * trans->cfg->base_params->num_of_queues;
+ bufsz = sizeof(char) * 75 *
+ trans->trans_cfg->base_params->num_of_queues;
if (!trans_pcie->txq_memory)
return -EAGAIN;
@@ -2519,7 +2534,9 @@ static ssize_t iwl_dbgfs_tx_queue_read(struct file *file,
if (!buf)
return -ENOMEM;
- for (cnt = 0; cnt < trans->cfg->base_params->num_of_queues; cnt++) {
+ for (cnt = 0;
+ cnt < trans->trans_cfg->base_params->num_of_queues;
+ cnt++) {
txq = trans_pcie->txq[cnt];
pos += scnprintf(buf + pos, bufsz - pos,
"hwq %.2d: read=%u write=%u use=%d stop=%d need_update=%d frozen=%d%s\n",
@@ -2989,7 +3006,7 @@ static u32 iwl_trans_pcie_fh_regs_dump(struct iwl_trans *trans,
(*data)->len = cpu_to_le32(fh_regs_len);
val = (void *)(*data)->data;
- if (!trans->cfg->gen2)
+ if (!trans->trans_cfg->gen2)
for (i = FH_MEM_LOWER_BOUND; i < FH_MEM_UPPER_BOUND;
i += sizeof(u32))
*val++ = cpu_to_le32(iwl_trans_pcie_read32(trans, i));
@@ -3037,7 +3054,7 @@ iwl_trans_pcie_dump_pointers(struct iwl_trans *trans,
{
u32 base, base_high, write_ptr, write_ptr_val, wrap_cnt;
- if (trans->cfg->device_family >= IWL_DEVICE_FAMILY_AX210) {
+ if (trans->trans_cfg->device_family >= IWL_DEVICE_FAMILY_AX210) {
base = DBGC_CUR_DBGBUF_BASE_ADDR_LSB;
base_high = DBGC_CUR_DBGBUF_BASE_ADDR_MSB;
write_ptr = DBGC_CUR_DBGBUF_STATUS;
@@ -3057,7 +3074,7 @@ iwl_trans_pcie_dump_pointers(struct iwl_trans *trans,
cpu_to_le32(iwl_read_prph(trans, wrap_cnt));
fw_mon_data->fw_mon_base_ptr =
cpu_to_le32(iwl_read_prph(trans, base));
- if (trans->cfg->device_family >= IWL_DEVICE_FAMILY_AX210) {
+ if (trans->trans_cfg->device_family >= IWL_DEVICE_FAMILY_AX210) {
fw_mon_data->fw_mon_base_high_ptr =
cpu_to_le32(iwl_read_prph(trans, base_high));
write_ptr_val &= DBGC_CUR_DBGBUF_STATUS_OFFSET_MSK;
@@ -3074,8 +3091,8 @@ iwl_trans_pcie_dump_monitor(struct iwl_trans *trans,
if (trans->dbg.dest_tlv ||
(trans->dbg.num_blocks &&
- (trans->cfg->device_family == IWL_DEVICE_FAMILY_7000 ||
- trans->cfg->device_family >= IWL_DEVICE_FAMILY_AX210))) {
+ (trans->trans_cfg->device_family == IWL_DEVICE_FAMILY_7000 ||
+ trans->trans_cfg->device_family >= IWL_DEVICE_FAMILY_AX210))) {
struct iwl_fw_error_dump_fw_mon *fw_mon_data;
(*data)->type = cpu_to_le32(IWL_FW_ERROR_DUMP_FW_MONITOR);
@@ -3158,7 +3175,7 @@ static int iwl_trans_get_fw_monitor_len(struct iwl_trans *trans, u32 *len)
trans->dbg.dest_tlv->end_shift;
/* Make "end" point to the actual end */
- if (trans->cfg->device_family >=
+ if (trans->trans_cfg->device_family >=
IWL_DEVICE_FAMILY_8000 ||
trans->dbg.dest_tlv->monitor_mode == MARBH_MODE)
end += (1 << trans->dbg.dest_tlv->end_shift);
@@ -3184,7 +3201,7 @@ static struct iwl_trans_dump_data
u32 len, num_rbs = 0, monitor_len = 0;
int i, ptr;
bool dump_rbs = test_bit(STATUS_FW_ERROR, &trans->status) &&
- !trans->cfg->mq_rx_supported &&
+ !trans->trans_cfg->mq_rx_supported &&
dump_mask & BIT(IWL_FW_ERROR_DUMP_RB);
if (!dump_mask)
@@ -3209,7 +3226,7 @@ static struct iwl_trans_dump_data
/* FH registers */
if (dump_mask & BIT(IWL_FW_ERROR_DUMP_FH_REGS)) {
- if (trans->cfg->gen2)
+ if (trans->trans_cfg->gen2)
len += sizeof(*data) +
(iwl_umac_prph(trans, FH_MEM_UPPER_BOUND_GEN2) -
iwl_umac_prph(trans, FH_MEM_LOWER_BOUND_GEN2));
@@ -3233,7 +3250,7 @@ static struct iwl_trans_dump_data
}
/* Paged memory for gen2 HW */
- if (trans->cfg->gen2 && dump_mask & BIT(IWL_FW_ERROR_DUMP_PAGING))
+ if (trans->trans_cfg->gen2 && dump_mask & BIT(IWL_FW_ERROR_DUMP_PAGING))
for (i = 0; i < trans->init_dram.paging_cnt; i++)
len += sizeof(*data) +
sizeof(struct iwl_fw_error_dump_paging) +
@@ -3255,11 +3272,17 @@ static struct iwl_trans_dump_data
ptr = cmdq->write_ptr;
for (i = 0; i < cmdq->n_window; i++) {
u8 idx = iwl_pcie_get_cmd_index(cmdq, ptr);
+ u8 tfdidx;
u32 caplen, cmdlen;
+ if (trans->trans_cfg->use_tfh)
+ tfdidx = idx;
+ else
+ tfdidx = ptr;
+
cmdlen = iwl_trans_pcie_get_cmdlen(trans,
- cmdq->tfds +
- tfd_size * ptr);
+ (u8 *)cmdq->tfds +
+ tfd_size * tfdidx);
caplen = min_t(u32, TFD_MAX_PAYLOAD_SIZE, cmdlen);
if (cmdlen) {
@@ -3288,7 +3311,8 @@ static struct iwl_trans_dump_data
len += iwl_trans_pcie_dump_rbs(trans, &data, num_rbs);
/* Paged memory for gen2 HW */
- if (trans->cfg->gen2 && dump_mask & BIT(IWL_FW_ERROR_DUMP_PAGING)) {
+ if (trans->trans_cfg->gen2 &&
+ dump_mask & BIT(IWL_FW_ERROR_DUMP_PAGING)) {
for (i = 0; i < trans->init_dram.paging_cnt; i++) {
struct iwl_fw_error_dump_paging *paging;
u32 page_len = trans->init_dram.paging[i].size;
@@ -3315,18 +3339,11 @@ static struct iwl_trans_dump_data
#ifdef CONFIG_PM_SLEEP
static int iwl_trans_pcie_suspend(struct iwl_trans *trans)
{
- if (trans->runtime_pm_mode == IWL_PLAT_PM_MODE_D0I3 &&
- (trans->system_pm_mode == IWL_PLAT_PM_MODE_D0I3))
- return iwl_pci_fw_enter_d0i3(trans);
-
return 0;
}
static void iwl_trans_pcie_resume(struct iwl_trans *trans)
{
- if (trans->runtime_pm_mode == IWL_PLAT_PM_MODE_D0I3 &&
- (trans->system_pm_mode == IWL_PLAT_PM_MODE_D0I3))
- iwl_pci_fw_exit_d0i3(trans);
}
#endif /* CONFIG_PM_SLEEP */
@@ -3345,8 +3362,6 @@ static void iwl_trans_pcie_resume(struct iwl_trans *trans)
.grab_nic_access = iwl_trans_pcie_grab_nic_access, \
.release_nic_access = iwl_trans_pcie_release_nic_access, \
.set_bits_mask = iwl_trans_pcie_set_bits_mask, \
- .ref = iwl_trans_pcie_ref, \
- .unref = iwl_trans_pcie_unref, \
.dump_data = iwl_trans_pcie_dump_data, \
.d3_suspend = iwl_trans_pcie_d3_suspend, \
.d3_resume = iwl_trans_pcie_d3_resume, \
@@ -3400,6 +3415,8 @@ static const struct iwl_trans_ops trans_ops_pcie_gen2 = {
.tx = iwl_trans_pcie_gen2_tx,
.reclaim = iwl_trans_pcie_reclaim,
+ .set_q_ptrs = iwl_trans_pcie_set_q_ptrs,
+
.txq_alloc = iwl_trans_pcie_dyn_txq_alloc,
.txq_free = iwl_trans_pcie_dyn_txq_free,
.wait_txq_empty = iwl_trans_pcie_wait_txq_empty,
@@ -3410,8 +3427,8 @@ static const struct iwl_trans_ops trans_ops_pcie_gen2 = {
};
struct iwl_trans *iwl_trans_pcie_alloc(struct pci_dev *pdev,
- const struct pci_device_id *ent,
- const struct iwl_cfg *cfg)
+ const struct pci_device_id *ent,
+ const struct iwl_cfg_trans_params *cfg_trans)
{
struct iwl_trans_pcie *trans_pcie;
struct iwl_trans *trans;
@@ -3421,12 +3438,13 @@ struct iwl_trans *iwl_trans_pcie_alloc(struct pci_dev *pdev,
if (ret)
return ERR_PTR(ret);
- if (cfg->gen2)
+ if (cfg_trans->gen2)
trans = iwl_trans_alloc(sizeof(struct iwl_trans_pcie),
- &pdev->dev, cfg, &trans_ops_pcie_gen2);
+ &pdev->dev, &trans_ops_pcie_gen2);
else
trans = iwl_trans_alloc(sizeof(struct iwl_trans_pcie),
- &pdev->dev, cfg, &trans_ops_pcie);
+ &pdev->dev, &trans_ops_pcie);
+
if (!trans)
return ERR_PTR(-ENOMEM);
@@ -3438,6 +3456,15 @@ struct iwl_trans *iwl_trans_pcie_alloc(struct pci_dev *pdev,
spin_lock_init(&trans_pcie->reg_lock);
mutex_init(&trans_pcie->mutex);
init_waitqueue_head(&trans_pcie->ucode_write_waitq);
+
+ trans_pcie->rba.alloc_wq = alloc_workqueue("rb_allocator",
+ WQ_HIGHPRI | WQ_UNBOUND, 1);
+ if (!trans_pcie->rba.alloc_wq) {
+ ret = -ENOMEM;
+ goto out_free_trans;
+ }
+ INIT_WORK(&trans_pcie->rba.rx_alloc, iwl_pcie_rx_allocator_work);
+
trans_pcie->tso_hdr_page = alloc_percpu(struct iwl_tso_hdr_page);
if (!trans_pcie->tso_hdr_page) {
ret = -ENOMEM;
@@ -3445,7 +3472,7 @@ struct iwl_trans *iwl_trans_pcie_alloc(struct pci_dev *pdev,
}
trans_pcie->debug_rfkill = -1;
- if (!cfg->base_params->pcie_l1_allowed) {
+ if (!cfg_trans->base_params->pcie_l1_allowed) {
/*
* W/A - seems to solve weird behavior. We need to remove this
* if we don't want to stay in L1 all the time. This wastes a
@@ -3458,7 +3485,7 @@ struct iwl_trans *iwl_trans_pcie_alloc(struct pci_dev *pdev,
trans_pcie->def_rx_queue = 0;
- if (cfg->use_tfh) {
+ if (cfg_trans->use_tfh) {
addr_size = 64;
trans_pcie->max_tbs = IWL_TFH_NUM_TBS;
trans_pcie->tfd_size = sizeof(struct iwl_tfh_tfd);
@@ -3520,9 +3547,7 @@ struct iwl_trans *iwl_trans_pcie_alloc(struct pci_dev *pdev,
* "dash" value). To keep hw_rev backwards compatible - we'll store it
* in the old format.
*/
- if (trans->cfg->device_family >= IWL_DEVICE_FAMILY_8000) {
- unsigned long flags;
-
+ if (cfg_trans->device_family >= IWL_DEVICE_FAMILY_8000) {
trans->hw_rev = (trans->hw_rev & 0xfff0) |
(CSR_HW_REV_STEP(trans->hw_rev << 2) << 2);
@@ -3536,98 +3561,15 @@ struct iwl_trans *iwl_trans_pcie_alloc(struct pci_dev *pdev,
* in-order to recognize C step driver should read chip version
* id located at the AUX bus MISC address space.
*/
- ret = iwl_finish_nic_init(trans);
+ ret = iwl_finish_nic_init(trans, cfg_trans);
if (ret)
goto out_no_pci;
- if (iwl_trans_grab_nic_access(trans, &flags)) {
- u32 hw_step;
-
- hw_step = iwl_read_umac_prph_no_grab(trans,
- WFPM_CTRL_REG);
- hw_step |= ENABLE_WFPM;
- iwl_write_umac_prph_no_grab(trans, WFPM_CTRL_REG,
- hw_step);
- hw_step = iwl_read_prph_no_grab(trans,
- CNVI_AUX_MISC_CHIP);
- hw_step = (hw_step >> HW_STEP_LOCATION_BITS) & 0xF;
- if (hw_step == 0x3)
- trans->hw_rev = (trans->hw_rev & 0xFFFFFFF3) |
- (SILICON_C_STEP << 2);
- iwl_trans_release_nic_access(trans, &flags);
- }
}
IWL_DEBUG_INFO(trans, "HW REV: 0x%0x\n", trans->hw_rev);
-#if IS_ENABLED(CONFIG_IWLMVM)
- trans->hw_rf_id = iwl_read32(trans, CSR_HW_RF_ID);
-
- if (cfg == &iwlax210_2ax_cfg_so_hr_a0) {
- if (trans->hw_rev == CSR_HW_REV_TYPE_TY) {
- trans->cfg = &iwlax210_2ax_cfg_ty_gf_a0;
- } else if (CSR_HW_RF_ID_TYPE_CHIP_ID(trans->hw_rf_id) ==
- CSR_HW_RF_ID_TYPE_CHIP_ID(CSR_HW_RF_ID_TYPE_JF)) {
- trans->cfg = &iwlax210_2ax_cfg_so_jf_a0;
- } else if (CSR_HW_RF_ID_TYPE_CHIP_ID(trans->hw_rf_id) ==
- CSR_HW_RF_ID_TYPE_CHIP_ID(CSR_HW_RF_ID_TYPE_GF)) {
- trans->cfg = &iwlax211_2ax_cfg_so_gf_a0;
- } else if (CSR_HW_RF_ID_TYPE_CHIP_ID(trans->hw_rf_id) ==
- CSR_HW_RF_ID_TYPE_CHIP_ID(CSR_HW_RF_ID_TYPE_GF4)) {
- trans->cfg = &iwlax411_2ax_cfg_so_gf4_a0;
- }
- } else if (cfg == &iwl_ax101_cfg_qu_hr) {
- if ((CSR_HW_RF_ID_TYPE_CHIP_ID(trans->hw_rf_id) ==
- CSR_HW_RF_ID_TYPE_CHIP_ID(CSR_HW_RF_ID_TYPE_HR) &&
- trans->hw_rev == CSR_HW_REV_TYPE_QNJ_B0) ||
- (CSR_HW_RF_ID_TYPE_CHIP_ID(trans->hw_rf_id) ==
- CSR_HW_RF_ID_TYPE_CHIP_ID(CSR_HW_RF_ID_TYPE_HR1))) {
- trans->cfg = &iwl22000_2ax_cfg_qnj_hr_b0;
- } else if (CSR_HW_RF_ID_TYPE_CHIP_ID(trans->hw_rf_id) ==
- CSR_HW_RF_ID_TYPE_CHIP_ID(CSR_HW_RF_ID_TYPE_HR)) {
- trans->cfg = &iwl_ax101_cfg_qu_hr;
- } else if (CSR_HW_RF_ID_TYPE_CHIP_ID(trans->hw_rf_id) ==
- CSR_HW_RF_ID_TYPE_CHIP_ID(CSR_HW_RF_ID_TYPE_JF)) {
- trans->cfg = &iwl22000_2ax_cfg_jf;
- } else if (CSR_HW_RF_ID_TYPE_CHIP_ID(trans->hw_rf_id) ==
- CSR_HW_RF_ID_TYPE_CHIP_ID(CSR_HW_RF_ID_TYPE_HRCDB)) {
- IWL_ERR(trans, "RF ID HRCDB is not supported\n");
- ret = -EINVAL;
- goto out_no_pci;
- } else {
- IWL_ERR(trans, "Unrecognized RF ID 0x%08x\n",
- CSR_HW_RF_ID_TYPE_CHIP_ID(trans->hw_rf_id));
- ret = -EINVAL;
- goto out_no_pci;
- }
- } else if (CSR_HW_RF_ID_TYPE_CHIP_ID(trans->hw_rf_id) ==
- CSR_HW_RF_ID_TYPE_CHIP_ID(CSR_HW_RF_ID_TYPE_HR) &&
- ((trans->cfg != &iwl_ax200_cfg_cc &&
- trans->cfg != &killer1650x_2ax_cfg &&
- trans->cfg != &killer1650w_2ax_cfg &&
- trans->cfg != &iwl_ax201_cfg_quz_hr) ||
- trans->hw_rev == CSR_HW_REV_TYPE_QNJ_B0)) {
- u32 hw_status;
-
- hw_status = iwl_read_prph(trans, UMAG_GEN_HW_STATUS);
- if (CSR_HW_RF_STEP(trans->hw_rf_id) == SILICON_B_STEP)
- /*
- * b step fw is the same for physical card and fpga
- */
- trans->cfg = &iwl22000_2ax_cfg_qnj_hr_b0;
- else if ((hw_status & UMAG_GEN_HW_IS_FPGA) &&
- CSR_HW_RF_STEP(trans->hw_rf_id) == SILICON_A_STEP) {
- trans->cfg = &iwl22000_2ax_cfg_qnj_hr_a0_f0;
- } else {
- /*
- * a step no FPGA
- */
- trans->cfg = &iwl22000_2ac_cfg_hr;
- }
- }
-#endif
-
- iwl_pcie_set_interrupt_capa(pdev, trans);
+ iwl_pcie_set_interrupt_capa(pdev, trans, cfg_trans);
trans->hw_id = (pdev->device << 16) + pdev->subsystem_device;
snprintf(trans->hw_id_str, sizeof(trans->hw_id_str),
"PCI ID: 0x%04X:0x%04X", pdev->device, pdev->subsystem_device);
@@ -3635,7 +3577,7 @@ struct iwl_trans *iwl_trans_pcie_alloc(struct pci_dev *pdev,
/* Initialize the wait queue for commands */
init_waitqueue_head(&trans_pcie->wait_command_queue);
- init_waitqueue_head(&trans_pcie->d0i3_waitq);
+ init_waitqueue_head(&trans_pcie->sx_waitq);
if (trans_pcie->msix_enabled) {
ret = iwl_pcie_init_msix_handler(pdev, trans_pcie);
@@ -3657,16 +3599,6 @@ struct iwl_trans *iwl_trans_pcie_alloc(struct pci_dev *pdev,
trans_pcie->inta_mask = CSR_INI_SET_MASK;
}
- trans_pcie->rba.alloc_wq = alloc_workqueue("rb_allocator",
- WQ_HIGHPRI | WQ_UNBOUND, 1);
- INIT_WORK(&trans_pcie->rba.rx_alloc, iwl_pcie_rx_allocator_work);
-
-#ifdef CONFIG_IWLWIFI_PCIE_RTPM
- trans->runtime_pm_mode = IWL_PLAT_PM_MODE_D0I3;
-#else
- trans->runtime_pm_mode = IWL_PLAT_PM_MODE_DISABLED;
-#endif /* CONFIG_IWLWIFI_PCIE_RTPM */
-
#ifdef CONFIG_IWLWIFI_DEBUGFS
trans_pcie->fw_mon_data.state = IWL_FW_MON_DBGFS_STATE_CLOSED;
mutex_init(&trans_pcie->fw_mon_data.mutex);
@@ -3678,6 +3610,8 @@ out_free_ict:
iwl_pcie_free_ict(trans);
out_no_pci:
free_percpu(trans_pcie->tso_hdr_page);
+ destroy_workqueue(trans_pcie->rba.alloc_wq);
+out_free_trans:
iwl_trans_free(trans);
return ERR_PTR(ret);
}
diff --git a/drivers/net/wireless/intel/iwlwifi/pcie/tx-gen2.c b/drivers/net/wireless/intel/iwlwifi/pcie/tx-gen2.c
index 38d110338987..8894027429d6 100644
--- a/drivers/net/wireless/intel/iwlwifi/pcie/tx-gen2.c
+++ b/drivers/net/wireless/intel/iwlwifi/pcie/tx-gen2.c
@@ -50,7 +50,6 @@
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
*****************************************************************************/
-#include <linux/pm_runtime.h>
#include <net/tso.h>
#include <linux/tcp.h>
@@ -99,10 +98,7 @@ void iwl_pcie_gen2_update_byte_tbl(struct iwl_trans_pcie *trans_pcie,
u16 len = byte_cnt;
__le16 bc_ent;
- if (trans_pcie->bc_table_dword)
- len = DIV_ROUND_UP(len, 4);
-
- if (WARN_ON(len > 0xFFF || idx >= txq->n_window))
+ if (WARN(idx >= txq->n_window, "%d >= %d\n", idx, txq->n_window))
return;
filled_tfd_size = offsetof(struct iwl_tfh_tfd, tbs) +
@@ -117,11 +113,20 @@ void iwl_pcie_gen2_update_byte_tbl(struct iwl_trans_pcie *trans_pcie,
*/
num_fetch_chunks = DIV_ROUND_UP(filled_tfd_size, 64) - 1;
- bc_ent = cpu_to_le16(len | (num_fetch_chunks << 12));
- if (trans->cfg->device_family >= IWL_DEVICE_FAMILY_22560)
+ if (trans->trans_cfg->device_family >= IWL_DEVICE_FAMILY_22560) {
+ /* Starting from 22560, the HW expects bytes */
+ WARN_ON(trans_pcie->bc_table_dword);
+ WARN_ON(len > 0x3FFF);
+ bc_ent = cpu_to_le16(len | (num_fetch_chunks << 14));
scd_bc_tbl_gen3->tfd_offset[idx] = bc_ent;
- else
+ } else {
+ /* Until 22560, the HW expects DW */
+ WARN_ON(!trans_pcie->bc_table_dword);
+ len = DIV_ROUND_UP(len, 4);
+ WARN_ON(len > 0xFFF);
+ bc_ent = cpu_to_le16(len | (num_fetch_chunks << 12));
scd_bc_tbl->tfd_offset[idx] = bc_ent;
+ }
}
/*
@@ -542,7 +547,7 @@ struct iwl_tfh_tfd *iwl_pcie_gen2_build_tfd(struct iwl_trans *trans,
memset(tfd, 0, sizeof(*tfd));
- if (trans->cfg->device_family < IWL_DEVICE_FAMILY_22560)
+ if (trans->trans_cfg->device_family < IWL_DEVICE_FAMILY_22560)
len = sizeof(struct iwl_tx_cmd_gen2);
else
len = sizeof(struct iwl_tx_cmd_gen3);
@@ -624,7 +629,7 @@ int iwl_trans_pcie_gen2_tx(struct iwl_trans *trans, struct sk_buff *skb,
return -1;
}
- if (trans->cfg->device_family >= IWL_DEVICE_FAMILY_22560) {
+ if (trans->trans_cfg->device_family >= IWL_DEVICE_FAMILY_22560) {
struct iwl_tx_cmd_gen3 *tx_cmd_gen3 =
(void *)dev_cmd->payload;
@@ -641,12 +646,8 @@ int iwl_trans_pcie_gen2_tx(struct iwl_trans *trans, struct sk_buff *skb,
iwl_pcie_gen2_get_num_tbs(trans, tfd));
/* start timer if queue currently empty */
- if (txq->read_ptr == txq->write_ptr) {
- if (txq->wd_timeout)
- mod_timer(&txq->stuck_timer, jiffies + txq->wd_timeout);
- IWL_DEBUG_RPM(trans, "Q: %d first tx - take ref\n", txq->id);
- iwl_trans_ref(trans);
- }
+ if (txq->read_ptr == txq->write_ptr && txq->wd_timeout)
+ mod_timer(&txq->stuck_timer, jiffies + txq->wd_timeout);
/* Tell device the write index *just past* this latest filled TFD */
txq->write_ptr = iwl_queue_inc_wrap(trans, txq->write_ptr);
@@ -891,12 +892,6 @@ static int iwl_pcie_gen2_enqueue_hcmd(struct iwl_trans *trans,
mod_timer(&txq->stuck_timer, jiffies + txq->wd_timeout);
spin_lock_irqsave(&trans_pcie->reg_lock, flags);
- if (!(cmd->flags & CMD_SEND_IN_IDLE) &&
- !trans_pcie->ref_cmd_in_flight) {
- trans_pcie->ref_cmd_in_flight = true;
- IWL_DEBUG_RPM(trans, "set ref_cmd_in_flight - ref\n");
- iwl_trans_ref(trans);
- }
/* Increment and update queue's write index */
txq->write_ptr = iwl_queue_inc_wrap(trans, txq->write_ptr);
iwl_pcie_gen2_txq_inc_wr_ptr(trans, txq);
@@ -930,16 +925,6 @@ static int iwl_pcie_gen2_send_hcmd_sync(struct iwl_trans *trans,
IWL_DEBUG_INFO(trans, "Setting HCMD_ACTIVE for command %s\n", cmd_str);
- if (pm_runtime_suspended(&trans_pcie->pci_dev->dev)) {
- ret = wait_event_timeout(trans_pcie->d0i3_waitq,
- pm_runtime_active(&trans_pcie->pci_dev->dev),
- msecs_to_jiffies(IWL_TRANS_IDLE_TIMEOUT));
- if (!ret) {
- IWL_ERR(trans, "Timeout exiting D0i3 before hcmd\n");
- return -ETIMEDOUT;
- }
- }
-
cmd_idx = iwl_pcie_gen2_enqueue_hcmd(trans, cmd);
if (cmd_idx < 0) {
ret = cmd_idx;
@@ -1064,23 +1049,6 @@ void iwl_pcie_gen2_txq_unmap(struct iwl_trans *trans, int txq_id)
}
iwl_pcie_gen2_free_tfd(trans, txq);
txq->read_ptr = iwl_queue_inc_wrap(trans, txq->read_ptr);
-
- if (txq->read_ptr == txq->write_ptr) {
- unsigned long flags;
-
- spin_lock_irqsave(&trans_pcie->reg_lock, flags);
- if (txq_id != trans_pcie->cmd_queue) {
- IWL_DEBUG_RPM(trans, "Q %d - last tx freed\n",
- txq->id);
- iwl_trans_unref(trans);
- } else if (trans_pcie->ref_cmd_in_flight) {
- trans_pcie->ref_cmd_in_flight = false;
- IWL_DEBUG_RPM(trans,
- "clear ref_cmd_in_flight\n");
- iwl_trans_unref(trans);
- }
- spin_unlock_irqrestore(&trans_pcie->reg_lock, flags);
- }
}
while (!skb_queue_empty(&txq->overflow_q)) {
@@ -1161,7 +1129,7 @@ int iwl_trans_pcie_dyn_txq_alloc_dma(struct iwl_trans *trans,
if (!txq)
return -ENOMEM;
ret = iwl_pcie_alloc_dma_ptr(trans, &txq->bc_tbl,
- (trans->cfg->device_family >=
+ (trans->trans_cfg->device_family >=
IWL_DEVICE_FAMILY_22560) ?
sizeof(struct iwl_gen3_bc_tbl) :
sizeof(struct iwlagn_scd_bc_tbl));
@@ -1225,7 +1193,7 @@ int iwl_trans_pcie_txq_alloc_response(struct iwl_trans *trans,
txq->id = qid;
trans_pcie->txq[qid] = txq;
- wr_ptr &= (trans->cfg->base_params->max_tfd_queue_size - 1);
+ wr_ptr &= (trans->trans_cfg->base_params->max_tfd_queue_size - 1);
/* Place first TFD at index corresponding to start sequence number */
txq->read_ptr = wr_ptr;
diff --git a/drivers/net/wireless/intel/iwlwifi/pcie/tx.c b/drivers/net/wireless/intel/iwlwifi/pcie/tx.c
index 2f0ba7ef53b8..4806a04cec8c 100644
--- a/drivers/net/wireless/intel/iwlwifi/pcie/tx.c
+++ b/drivers/net/wireless/intel/iwlwifi/pcie/tx.c
@@ -65,7 +65,6 @@
#include <linux/ieee80211.h>
#include <linux/slab.h>
#include <linux/sched.h>
-#include <linux/pm_runtime.h>
#include <net/ip6_checksum.h>
#include <net/tso.h>
@@ -114,17 +113,17 @@ int iwl_queue_space(struct iwl_trans *trans, const struct iwl_txq *q)
* If q->n_window is smaller than max_tfd_queue_size, there is no need
* to reserve any queue entries for this purpose.
*/
- if (q->n_window < trans->cfg->base_params->max_tfd_queue_size)
+ if (q->n_window < trans->trans_cfg->base_params->max_tfd_queue_size)
max = q->n_window;
else
- max = trans->cfg->base_params->max_tfd_queue_size - 1;
+ max = trans->trans_cfg->base_params->max_tfd_queue_size - 1;
/*
* max_tfd_queue_size is a power of 2, so the following is equivalent to
* modulo by max_tfd_queue_size and is well defined.
*/
used = (q->write_ptr - q->read_ptr) &
- (trans->cfg->base_params->max_tfd_queue_size - 1);
+ (trans->trans_cfg->base_params->max_tfd_queue_size - 1);
if (WARN_ON(used > max))
return 0;
@@ -293,7 +292,7 @@ static void iwl_pcie_txq_inc_wr_ptr(struct iwl_trans *trans,
* 2. NIC is woken up for CMD regardless of shadow outside this function
* 3. there is a chance that the NIC is asleep
*/
- if (!trans->cfg->base_params->shadow_reg_enable &&
+ if (!trans->trans_cfg->base_params->shadow_reg_enable &&
txq_id != trans_pcie->cmd_queue &&
test_bit(STATUS_TPOWER_PMI, &trans->status)) {
/*
@@ -307,7 +306,7 @@ static void iwl_pcie_txq_inc_wr_ptr(struct iwl_trans *trans,
IWL_DEBUG_INFO(trans, "Tx queue %d requesting wakeup, GP1 = 0x%x\n",
txq_id, reg);
iwl_set_bit(trans, CSR_GP_CNTRL,
- BIT(trans->cfg->csr->flag_mac_access_req));
+ BIT(trans->trans_cfg->csr->flag_mac_access_req));
txq->need_update = true;
return;
}
@@ -328,7 +327,7 @@ void iwl_pcie_txq_check_wrptrs(struct iwl_trans *trans)
struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans);
int i;
- for (i = 0; i < trans->cfg->base_params->num_of_queues; i++) {
+ for (i = 0; i < trans->trans_cfg->base_params->num_of_queues; i++) {
struct iwl_txq *txq = trans_pcie->txq[i];
if (!test_bit(i, trans_pcie->queue_used))
@@ -347,7 +346,7 @@ static inline dma_addr_t iwl_pcie_tfd_tb_get_addr(struct iwl_trans *trans,
void *_tfd, u8 idx)
{
- if (trans->cfg->use_tfh) {
+ if (trans->trans_cfg->use_tfh) {
struct iwl_tfh_tfd *tfd = _tfd;
struct iwl_tfh_tb *tb = &tfd->tbs[idx];
@@ -390,7 +389,7 @@ static inline void iwl_pcie_tfd_set_tb(struct iwl_trans *trans, void *tfd,
static inline u8 iwl_pcie_tfd_get_num_tbs(struct iwl_trans *trans, void *_tfd)
{
- if (trans->cfg->use_tfh) {
+ if (trans->trans_cfg->use_tfh) {
struct iwl_tfh_tfd *tfd = _tfd;
return le16_to_cpu(tfd->num_tbs) & 0x1f;
@@ -437,7 +436,7 @@ static void iwl_pcie_tfd_unmap(struct iwl_trans *trans,
meta->tbs = 0;
- if (trans->cfg->use_tfh) {
+ if (trans->trans_cfg->use_tfh) {
struct iwl_tfh_tfd *tfd_fh = (void *)tfd;
tfd_fh->num_tbs = 0;
@@ -525,14 +524,14 @@ int iwl_pcie_txq_alloc(struct iwl_trans *trans, struct iwl_txq *txq,
{
struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans);
size_t tfd_sz = trans_pcie->tfd_size *
- trans->cfg->base_params->max_tfd_queue_size;
+ trans->trans_cfg->base_params->max_tfd_queue_size;
size_t tb0_buf_sz;
int i;
if (WARN_ON(txq->entries || txq->tfds))
return -EINVAL;
- if (trans->cfg->use_tfh)
+ if (trans->trans_cfg->use_tfh)
tfd_sz = trans_pcie->tfd_size * slots_num;
timer_setup(&txq->stuck_timer, iwl_pcie_txq_stuck_timer, 0);
@@ -591,7 +590,8 @@ int iwl_pcie_txq_init(struct iwl_trans *trans, struct iwl_txq *txq,
int slots_num, bool cmd_queue)
{
int ret;
- u32 tfd_queue_max_size = trans->cfg->base_params->max_tfd_queue_size;
+ u32 tfd_queue_max_size =
+ trans->trans_cfg->base_params->max_tfd_queue_size;
txq->need_update = false;
@@ -639,20 +639,14 @@ static void iwl_pcie_clear_cmd_in_flight(struct iwl_trans *trans)
lockdep_assert_held(&trans_pcie->reg_lock);
- if (trans_pcie->ref_cmd_in_flight) {
- trans_pcie->ref_cmd_in_flight = false;
- IWL_DEBUG_RPM(trans, "clear ref_cmd_in_flight - unref\n");
- iwl_trans_unref(trans);
- }
-
- if (!trans->cfg->base_params->apmg_wake_up_wa)
+ if (!trans->trans_cfg->base_params->apmg_wake_up_wa)
return;
if (WARN_ON(!trans_pcie->cmd_hold_nic_awake))
return;
trans_pcie->cmd_hold_nic_awake = false;
__iwl_trans_pcie_clear_bit(trans, CSR_GP_CNTRL,
- BIT(trans->cfg->csr->flag_mac_access_req));
+ BIT(trans->trans_cfg->csr->flag_mac_access_req));
}
/*
@@ -683,13 +677,8 @@ static void iwl_pcie_txq_unmap(struct iwl_trans *trans, int txq_id)
unsigned long flags;
spin_lock_irqsave(&trans_pcie->reg_lock, flags);
- if (txq_id != trans_pcie->cmd_queue) {
- IWL_DEBUG_RPM(trans, "Q %d - last tx freed\n",
- txq->id);
- iwl_trans_unref(trans);
- } else {
+ if (txq_id == trans_pcie->cmd_queue)
iwl_pcie_clear_cmd_in_flight(trans);
- }
spin_unlock_irqrestore(&trans_pcie->reg_lock, flags);
}
}
@@ -737,7 +726,7 @@ static void iwl_pcie_txq_free(struct iwl_trans *trans, int txq_id)
if (txq->tfds) {
dma_free_coherent(dev,
trans_pcie->tfd_size *
- trans->cfg->base_params->max_tfd_queue_size,
+ trans->trans_cfg->base_params->max_tfd_queue_size,
txq->tfds, txq->dma_addr);
txq->dma_addr = 0;
txq->tfds = NULL;
@@ -759,7 +748,7 @@ static void iwl_pcie_txq_free(struct iwl_trans *trans, int txq_id)
void iwl_pcie_tx_start(struct iwl_trans *trans, u32 scd_base_addr)
{
struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans);
- int nq = trans->cfg->base_params->num_of_queues;
+ int nq = trans->trans_cfg->base_params->num_of_queues;
int chan;
u32 reg_val;
int clear_dwords = (SCD_TRANS_TBL_OFFSET_QUEUE(nq) -
@@ -786,7 +775,7 @@ void iwl_pcie_tx_start(struct iwl_trans *trans, u32 scd_base_addr)
/* The chain extension of the SCD doesn't work well. This feature is
* enabled by default by the HW, so we need to disable it manually.
*/
- if (trans->cfg->base_params->scd_chain_ext_wa)
+ if (trans->trans_cfg->base_params->scd_chain_ext_wa)
iwl_write_prph(trans, SCD_CHAINEXT_EN, 0);
iwl_trans_ac_txq_enable(trans, trans_pcie->cmd_queue,
@@ -808,7 +797,7 @@ void iwl_pcie_tx_start(struct iwl_trans *trans, u32 scd_base_addr)
reg_val | FH_TX_CHICKEN_BITS_SCD_AUTO_RETRY_EN);
/* Enable L1-Active */
- if (trans->cfg->device_family < IWL_DEVICE_FAMILY_8000)
+ if (trans->trans_cfg->device_family < IWL_DEVICE_FAMILY_8000)
iwl_clear_bits_prph(trans, APMG_PCIDEV_STT_REG,
APMG_PCIDEV_STT_VAL_L1_ACT_DIS);
}
@@ -822,13 +811,13 @@ void iwl_trans_pcie_tx_reset(struct iwl_trans *trans)
* we should never get here in gen2 trans mode return early to avoid
* having invalid accesses
*/
- if (WARN_ON_ONCE(trans->cfg->gen2))
+ if (WARN_ON_ONCE(trans->trans_cfg->gen2))
return;
- for (txq_id = 0; txq_id < trans->cfg->base_params->num_of_queues;
+ for (txq_id = 0; txq_id < trans->trans_cfg->base_params->num_of_queues;
txq_id++) {
struct iwl_txq *txq = trans_pcie->txq[txq_id];
- if (trans->cfg->use_tfh)
+ if (trans->trans_cfg->use_tfh)
iwl_write_direct64(trans,
FH_MEM_CBBC_QUEUE(trans, txq_id),
txq->dma_addr);
@@ -911,7 +900,7 @@ int iwl_pcie_tx_stop(struct iwl_trans *trans)
return 0;
/* Unmap DMA from host system and free skb's */
- for (txq_id = 0; txq_id < trans->cfg->base_params->num_of_queues;
+ for (txq_id = 0; txq_id < trans->trans_cfg->base_params->num_of_queues;
txq_id++)
iwl_pcie_txq_unmap(trans, txq_id);
@@ -933,7 +922,7 @@ void iwl_pcie_tx_free(struct iwl_trans *trans)
/* Tx queues */
if (trans_pcie->txq_memory) {
for (txq_id = 0;
- txq_id < trans->cfg->base_params->num_of_queues;
+ txq_id < trans->trans_cfg->base_params->num_of_queues;
txq_id++) {
iwl_pcie_txq_free(trans, txq_id);
trans_pcie->txq[txq_id] = NULL;
@@ -957,9 +946,10 @@ static int iwl_pcie_tx_alloc(struct iwl_trans *trans)
int ret;
int txq_id, slots_num;
struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans);
- u16 bc_tbls_size = trans->cfg->base_params->num_of_queues;
+ u16 bc_tbls_size = trans->trans_cfg->base_params->num_of_queues;
- bc_tbls_size *= (trans->cfg->device_family >= IWL_DEVICE_FAMILY_22560) ?
+ bc_tbls_size *= (trans->trans_cfg->device_family >=
+ IWL_DEVICE_FAMILY_22560) ?
sizeof(struct iwl_gen3_bc_tbl) :
sizeof(struct iwlagn_scd_bc_tbl);
@@ -984,8 +974,9 @@ static int iwl_pcie_tx_alloc(struct iwl_trans *trans)
goto error;
}
- trans_pcie->txq_memory = kcalloc(trans->cfg->base_params->num_of_queues,
- sizeof(struct iwl_txq), GFP_KERNEL);
+ trans_pcie->txq_memory =
+ kcalloc(trans->trans_cfg->base_params->num_of_queues,
+ sizeof(struct iwl_txq), GFP_KERNEL);
if (!trans_pcie->txq_memory) {
IWL_ERR(trans, "Not enough memory for txq\n");
ret = -ENOMEM;
@@ -993,7 +984,7 @@ static int iwl_pcie_tx_alloc(struct iwl_trans *trans)
}
/* Alloc and init all Tx queues, including the command queue (#4/#9) */
- for (txq_id = 0; txq_id < trans->cfg->base_params->num_of_queues;
+ for (txq_id = 0; txq_id < trans->trans_cfg->base_params->num_of_queues;
txq_id++) {
bool cmd_queue = (txq_id == trans_pcie->cmd_queue);
@@ -1047,7 +1038,7 @@ int iwl_pcie_tx_init(struct iwl_trans *trans)
spin_unlock(&trans_pcie->irq_lock);
/* Alloc and init all Tx queues, including the command queue (#4/#9) */
- for (txq_id = 0; txq_id < trans->cfg->base_params->num_of_queues;
+ for (txq_id = 0; txq_id < trans->trans_cfg->base_params->num_of_queues;
txq_id++) {
bool cmd_queue = (txq_id == trans_pcie->cmd_queue);
@@ -1075,7 +1066,7 @@ int iwl_pcie_tx_init(struct iwl_trans *trans)
}
iwl_set_bits_prph(trans, SCD_GP_CTRL, SCD_GP_CTRL_AUTO_ACTIVE_MODE);
- if (trans->cfg->base_params->num_of_queues > 20)
+ if (trans->trans_cfg->base_params->num_of_queues > 20)
iwl_set_bits_prph(trans, SCD_GP_CTRL,
SCD_GP_CTRL_ENABLE_31_QUEUES);
@@ -1147,7 +1138,7 @@ void iwl_trans_pcie_reclaim(struct iwl_trans *trans, int txq_id, int ssn,
IWL_ERR(trans,
"%s: Read index for txq id (%d), last_to_free %d is out of range [0-%d] %d %d.\n",
__func__, txq_id, last_to_free,
- trans->cfg->base_params->max_tfd_queue_size,
+ trans->trans_cfg->base_params->max_tfd_queue_size,
txq->write_ptr, txq->read_ptr);
goto out;
}
@@ -1170,7 +1161,7 @@ void iwl_trans_pcie_reclaim(struct iwl_trans *trans, int txq_id, int ssn,
txq->entries[read_ptr].skb = NULL;
- if (!trans->cfg->use_tfh)
+ if (!trans->trans_cfg->use_tfh)
iwl_pcie_txq_inval_byte_cnt_tbl(trans, txq);
iwl_pcie_txq_free_tfd(trans, txq);
@@ -1225,20 +1216,28 @@ void iwl_trans_pcie_reclaim(struct iwl_trans *trans, int txq_id, int ssn,
txq->overflow_tx = false;
}
- if (txq->read_ptr == txq->write_ptr) {
- IWL_DEBUG_RPM(trans, "Q %d - last tx reclaimed\n", txq->id);
- iwl_trans_unref(trans);
- }
-
out:
spin_unlock_bh(&txq->lock);
}
+/* Set wr_ptr of specific device and txq */
+void iwl_trans_pcie_set_q_ptrs(struct iwl_trans *trans, int txq_id, int ptr)
+{
+ struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans);
+ struct iwl_txq *txq = trans_pcie->txq[txq_id];
+
+ spin_lock_bh(&txq->lock);
+
+ txq->write_ptr = ptr;
+ txq->read_ptr = txq->write_ptr;
+
+ spin_unlock_bh(&txq->lock);
+}
+
static int iwl_pcie_set_cmd_in_flight(struct iwl_trans *trans,
const struct iwl_host_cmd *cmd)
{
struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans);
- const struct iwl_cfg *cfg = trans->cfg;
int ret;
lockdep_assert_held(&trans_pcie->reg_lock);
@@ -1247,32 +1246,25 @@ static int iwl_pcie_set_cmd_in_flight(struct iwl_trans *trans,
if (test_bit(STATUS_TRANS_DEAD, &trans->status))
return -ENODEV;
- if (!(cmd->flags & CMD_SEND_IN_IDLE) &&
- !trans_pcie->ref_cmd_in_flight) {
- trans_pcie->ref_cmd_in_flight = true;
- IWL_DEBUG_RPM(trans, "set ref_cmd_in_flight - ref\n");
- iwl_trans_ref(trans);
- }
-
/*
* wake up the NIC to make sure that the firmware will see the host
* command - we will let the NIC sleep once all the host commands
* returned. This needs to be done only on NICs that have
* apmg_wake_up_wa set.
*/
- if (cfg->base_params->apmg_wake_up_wa &&
+ if (trans->trans_cfg->base_params->apmg_wake_up_wa &&
!trans_pcie->cmd_hold_nic_awake) {
__iwl_trans_pcie_set_bit(trans, CSR_GP_CNTRL,
- BIT(cfg->csr->flag_mac_access_req));
+ BIT(trans->trans_cfg->csr->flag_mac_access_req));
ret = iwl_poll_bit(trans, CSR_GP_CNTRL,
- BIT(cfg->csr->flag_val_mac_access_en),
- (BIT(cfg->csr->flag_mac_clock_ready) |
+ BIT(trans->trans_cfg->csr->flag_val_mac_access_en),
+ (BIT(trans->trans_cfg->csr->flag_mac_clock_ready) |
CSR_GP_CNTRL_REG_FLAG_GOING_TO_SLEEP),
15000);
if (ret < 0) {
__iwl_trans_pcie_clear_bit(trans, CSR_GP_CNTRL,
- BIT(cfg->csr->flag_mac_access_req));
+ BIT(trans->trans_cfg->csr->flag_mac_access_req));
IWL_ERR(trans, "Failed to wake NIC for hcmd\n");
return -EIO;
}
@@ -1302,12 +1294,12 @@ void iwl_pcie_cmdq_reclaim(struct iwl_trans *trans, int txq_id, int idx)
idx = iwl_pcie_get_cmd_index(txq, idx);
r = iwl_pcie_get_cmd_index(txq, txq->read_ptr);
- if (idx >= trans->cfg->base_params->max_tfd_queue_size ||
+ if (idx >= trans->trans_cfg->base_params->max_tfd_queue_size ||
(!iwl_queue_used(txq, idx))) {
WARN_ONCE(test_bit(txq_id, trans_pcie->queue_used),
"%s: Read index for DMA queue txq id (%d), index %d is out of range [0-%d] %d %d.\n",
__func__, txq_id, idx,
- trans->cfg->base_params->max_tfd_queue_size,
+ trans->trans_cfg->base_params->max_tfd_queue_size,
txq->write_ptr, txq->read_ptr);
return;
}
@@ -1421,7 +1413,7 @@ bool iwl_trans_pcie_txq_enable(struct iwl_trans *trans, int txq_id, u16 ssn,
* this sad hardware issue.
* This bug has been fixed on devices 9000 and up.
*/
- scd_bug = !trans->cfg->mq_rx_supported &&
+ scd_bug = !trans->trans_cfg->mq_rx_supported &&
!((ssn - txq->write_ptr) & 0x3f) &&
(ssn != txq->write_ptr);
if (scd_bug)
@@ -1867,20 +1859,6 @@ void iwl_pcie_hcmd_complete(struct iwl_trans *trans,
wake_up(&trans_pcie->wait_command_queue);
}
- if (meta->flags & CMD_MAKE_TRANS_IDLE) {
- IWL_DEBUG_INFO(trans, "complete %s - mark trans as idle\n",
- iwl_get_cmd_string(trans, cmd->hdr.cmd));
- set_bit(STATUS_TRANS_IDLE, &trans->status);
- wake_up(&trans_pcie->d0i3_waitq);
- }
-
- if (meta->flags & CMD_WAKE_UP_TRANS) {
- IWL_DEBUG_INFO(trans, "complete %s - clear trans idle flag\n",
- iwl_get_cmd_string(trans, cmd->hdr.cmd));
- clear_bit(STATUS_TRANS_IDLE, &trans->status);
- wake_up(&trans_pcie->d0i3_waitq);
- }
-
meta->flags = 0;
spin_unlock_bh(&txq->lock);
@@ -1927,16 +1905,6 @@ static int iwl_pcie_send_hcmd_sync(struct iwl_trans *trans,
IWL_DEBUG_INFO(trans, "Setting HCMD_ACTIVE for command %s\n",
iwl_get_cmd_string(trans, cmd->id));
- if (pm_runtime_suspended(&trans_pcie->pci_dev->dev)) {
- ret = wait_event_timeout(trans_pcie->d0i3_waitq,
- pm_runtime_active(&trans_pcie->pci_dev->dev),
- msecs_to_jiffies(IWL_TRANS_IDLE_TIMEOUT));
- if (!ret) {
- IWL_ERR(trans, "Timeout exiting D0i3 before hcmd\n");
- return -ETIMEDOUT;
- }
- }
-
cmd_idx = iwl_pcie_enqueue_hcmd(trans, cmd);
if (cmd_idx < 0) {
ret = cmd_idx;
@@ -2504,22 +2472,18 @@ int iwl_trans_pcie_tx(struct iwl_trans *trans, struct sk_buff *skb,
wait_write_ptr = ieee80211_has_morefrags(fc);
/* start timer if queue currently empty */
- if (txq->read_ptr == txq->write_ptr) {
- if (txq->wd_timeout) {
- /*
- * If the TXQ is active, then set the timer, if not,
- * set the timer in remainder so that the timer will
- * be armed with the right value when the station will
- * wake up.
- */
- if (!txq->frozen)
- mod_timer(&txq->stuck_timer,
- jiffies + txq->wd_timeout);
- else
- txq->frozen_expiry_remainder = txq->wd_timeout;
- }
- IWL_DEBUG_RPM(trans, "Q: %d first tx - take ref\n", txq->id);
- iwl_trans_ref(trans);
+ if (txq->read_ptr == txq->write_ptr && txq->wd_timeout) {
+ /*
+ * If the TXQ is active, then set the timer, if not,
+ * set the timer in remainder so that the timer will
+ * be armed with the right value when the station will
+ * wake up.
+ */
+ if (!txq->frozen)
+ mod_timer(&txq->stuck_timer,
+ jiffies + txq->wd_timeout);
+ else
+ txq->frozen_expiry_remainder = txq->wd_timeout;
}
/* Tell device the write index *just past* this latest filled TFD */