aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/wireless/intel/iwlwifi/pcie/trans.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/net/wireless/intel/iwlwifi/pcie/trans.c')
-rw-r--r--drivers/net/wireless/intel/iwlwifi/pcie/trans.c385
1 files changed, 153 insertions, 232 deletions
diff --git a/drivers/net/wireless/intel/iwlwifi/pcie/trans.c b/drivers/net/wireless/intel/iwlwifi/pcie/trans.c
index f5df5b370d78..f8a1f985a1d8 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) +
@@ -3288,7 +3305,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 +3333,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 +3356,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 +3409,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 +3421,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 +3432,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);
@@ -3445,7 +3457,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 +3470,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 +3532,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 +3546,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 +3562,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);
@@ -3661,12 +3588,6 @@ struct iwl_trans *iwl_trans_pcie_alloc(struct pci_dev *pdev,
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);