1
0
Fork 0

Fifth batch of iwlwifi patches intended for v5.1

* Some small fixes and continued work on the new debugging
   infrastructure;
 * Greg's debugfs clean-ups;
 * Some janitorial patches from the community;
 * Fix to one false-positive compiler warning;
 * VHT extended NSS support;
 * New PCI IDs for 9260 and 22000 series;
 * Other general bugfixes and cleanups;
 -----BEGIN PGP SIGNATURE-----
 
 iQIzBAABCgAdFiEEF3LNfgb2BPWm68smoUecoho8xfoFAlxtoe0ACgkQoUecoho8
 xfq7zw/+OD/fjZUjNYVPhsSVKLzrEuSmUMU8FhuPSq/n/Y1Nqn9YsbGfnjGkmrEM
 Nqip7Q2ph6Ml6IqRs2PsBEKxdbZqVek4Pk8zFQm4PlqZO0PdKUCI0wH0MoOoMpYE
 scU0jKMSjNbU8vdv9U4zyytHLLbH4Maw5skSJ7FptjWjTfGqaTE7UT9TCwnPBM/4
 JmqNufVrYMpyAZYiJFDJl0Le0HYxsP41d0t20fYYpReFfFZDTwtbo35UutfwmxrQ
 yazJzCndGFm6g9Af99BR8s0Zvd5jkZWTGnf513VY1eqq1CsFlxK4MP+CjArAaTYF
 ks+Pl1/sm8tuYIUB3sWn99n0siuF1R2RvRAxobYvKmm/EvYnH/wfUSvoW1XVeuaF
 92l3tVHcS15urCP0k3PWRvQhUSGNWOVZplBqQFtDIihnn3f+bFDIO1WCrL8TbtxC
 m+fSsX9xwrZwmI8wVMJ7jeAV43htubgRG9TXaeI1LOxAEpsLIqM/6zUXmVFAxX2x
 nKl3uh3U5IPFeoXPFxR7Ukp5BJqdNni2Bxhe6woAFq9TO7I21+Vu6C6STz/Tqp2w
 UMv5p9YGvv1USwEAuB2S4DfGsp36umUm9//2ijOM3qHxXFF5VFBgORYRPmEFnlcK
 dirE2AoO9KVdb9Zh+FfY9Cvc3gyTsXFIo/qPZ466yE3vqqcc7Q8=
 =fdwA
 -----END PGP SIGNATURE-----

Merge tag 'iwlwifi-next-for-kalle-2019-02-20' of git://git.kernel.org/pub/scm/linux/kernel/git/iwlwifi/iwlwifi-next

Fifth batch of iwlwifi patches intended for v5.1

* Some small fixes and continued work on the new debugging
  infrastructure;
* Greg's debugfs clean-ups;
* Some janitorial patches from the community;
* Fix to one false-positive compiler warning;
* VHT extended NSS support;
* New PCI IDs for 9260 and 22000 series;
* Other general bugfixes and cleanups;
hifive-unleashed-5.1
Kalle Valo 2019-02-20 21:06:13 +02:00
commit 5c0c4c8546
27 changed files with 696 additions and 314 deletions

View File

@ -223,8 +223,8 @@ const struct iwl_cfg iwl22000_2ac_cfg_jf = {
IWL_DEVICE_22500,
};
const struct iwl_cfg iwl22560_2ax_cfg_hr = {
.name = "Intel(R) Wireless-AX 22560",
const struct iwl_cfg iwl_ax101_cfg_qu_hr = {
.name = "Intel(R) Wi-Fi 6 AX101",
.fw_name_pre = IWL_22000_QU_B_HR_B_FW_PRE,
IWL_DEVICE_22500,
/*
@ -249,7 +249,7 @@ const struct iwl_cfg iwl22260_2ax_cfg = {
};
const struct iwl_cfg killer1650x_2ax_cfg = {
.name = "Killer(R) Wireless-AX 1650x Wireless Network Adapter (22260NGW)",
.name = "Killer(R) Wireless-AX 1650x Wireless Network Adapter (200NGW)",
.fw_name_pre = IWL_CC_A_FW_PRE,
IWL_DEVICE_22500,
/*
@ -262,7 +262,7 @@ const struct iwl_cfg killer1650x_2ax_cfg = {
};
const struct iwl_cfg killer1650w_2ax_cfg = {
.name = "Killer(R) Wireless-AX 1650w Wireless Network Adapter (22260D2W)",
.name = "Killer(R) Wireless-AX 1650w Wireless Network Adapter (200D2W)",
.fw_name_pre = IWL_CC_A_FW_PRE,
IWL_DEVICE_22500,
/*

View File

@ -439,13 +439,10 @@ static inline void iwl_dvm_set_pmi(struct iwl_priv *priv, bool state)
}
#ifdef CONFIG_IWLWIFI_DEBUGFS
int iwl_dbgfs_register(struct iwl_priv *priv, struct dentry *dbgfs_dir);
void iwl_dbgfs_register(struct iwl_priv *priv, struct dentry *dbgfs_dir);
#else
static inline int iwl_dbgfs_register(struct iwl_priv *priv,
struct dentry *dbgfs_dir)
{
return 0;
}
static inline void iwl_dbgfs_register(struct iwl_priv *priv,
struct dentry *dbgfs_dir) { }
#endif /* CONFIG_IWLWIFI_DEBUGFS */
#ifdef CONFIG_IWLWIFI_DEBUG

View File

@ -37,31 +37,8 @@
/* create and remove of files */
#define DEBUGFS_ADD_FILE(name, parent, mode) do { \
if (!debugfs_create_file(#name, mode, parent, priv, \
&iwl_dbgfs_##name##_ops)) \
goto err; \
} while (0)
#define DEBUGFS_ADD_BOOL(name, parent, ptr) do { \
struct dentry *__tmp; \
__tmp = debugfs_create_bool(#name, 0600, parent, ptr); \
if (IS_ERR(__tmp) || !__tmp) \
goto err; \
} while (0)
#define DEBUGFS_ADD_X32(name, parent, ptr) do { \
struct dentry *__tmp; \
__tmp = debugfs_create_x32(#name, 0600, parent, ptr); \
if (IS_ERR(__tmp) || !__tmp) \
goto err; \
} while (0)
#define DEBUGFS_ADD_U32(name, parent, ptr, mode) do { \
struct dentry *__tmp; \
__tmp = debugfs_create_u32(#name, mode, \
parent, ptr); \
if (IS_ERR(__tmp) || !__tmp) \
goto err; \
debugfs_create_file(#name, mode, parent, priv, \
&iwl_dbgfs_##name##_ops); \
} while (0)
/* file operation */
@ -2348,21 +2325,15 @@ DEBUGFS_READ_WRITE_FILE_OPS(calib_disabled);
* Create the debugfs files and directories
*
*/
int iwl_dbgfs_register(struct iwl_priv *priv, struct dentry *dbgfs_dir)
void iwl_dbgfs_register(struct iwl_priv *priv, struct dentry *dbgfs_dir)
{
struct dentry *dir_data, *dir_rf, *dir_debug;
priv->debugfs_dir = dbgfs_dir;
dir_data = debugfs_create_dir("data", dbgfs_dir);
if (!dir_data)
goto err;
dir_rf = debugfs_create_dir("rf", dbgfs_dir);
if (!dir_rf)
goto err;
dir_debug = debugfs_create_dir("debug", dbgfs_dir);
if (!dir_debug)
goto err;
DEBUGFS_ADD_FILE(nvm, dir_data, 0400);
DEBUGFS_ADD_FILE(sram, dir_data, 0600);
@ -2422,13 +2393,6 @@ int iwl_dbgfs_register(struct iwl_priv *priv, struct dentry *dbgfs_dir)
snprintf(buf, 100, "../../%pd2", dev_dir);
if (!debugfs_create_symlink("iwlwifi", mac80211_dir, buf))
goto err;
debugfs_create_symlink("iwlwifi", mac80211_dir, buf);
}
return 0;
err:
IWL_ERR(priv, "failed to create the dvm debugfs entries\n");
return -ENOMEM;
}

View File

@ -1509,13 +1509,10 @@ static struct iwl_op_mode *iwl_op_mode_dvm_start(struct iwl_trans *trans,
if (iwlagn_mac_setup_register(priv, &fw->ucode_capa))
goto out_destroy_workqueue;
if (iwl_dbgfs_register(priv, dbgfs_dir))
goto out_mac80211_unregister;
iwl_dbgfs_register(priv, dbgfs_dir);
return op_mode;
out_mac80211_unregister:
iwlagn_mac_unregister(priv);
out_destroy_workqueue:
iwl_tt_exit(priv);
iwl_cancel_deferred_work(priv);

View File

@ -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
@ -25,7 +25,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
@ -146,16 +146,17 @@ struct iwl_fw_ini_region_cfg_internal {
/**
* struct iwl_fw_ini_region_cfg_fifos - meta data of fifos region
* @lmac1_id: bit map of lmac1 fifos to include in the region.
* @lmac2_id: bit map of lmac2 fifos to include in the region.
* @fid1: fifo id 1 - bitmap of lmac tx/rx fifos to include in the region
* @fid2: fifo id 2 - bitmap of umac rx fifos to include in the region.
* It is unused for tx.
* @num_of_registers: number of prph registers in the region, each register is
* 4 bytes size.
* @header_only: none zero value indicates that this region does not include
* fifo data and includes only the given registers.
*/
struct iwl_fw_ini_region_cfg_fifos {
__le32 lmac1_id;
__le32 lmac2_id;
__le32 fid1;
__le32 fid2;
__le32 num_of_registers;
__le32 header_only;
} __packed; /* FW_DEBUG_TLV_REGION_FIFOS_S */

View File

@ -1044,10 +1044,10 @@ out:
}
static int iwl_dump_ini_prph_iter(struct iwl_fw_runtime *fwrt,
struct iwl_fw_ini_error_dump_range *range,
struct iwl_fw_ini_region_cfg *reg,
int idx)
void *range_ptr, int idx)
{
struct iwl_fw_ini_error_dump_range *range = range_ptr;
__le32 *val = range->data;
u32 addr, prph_val, offset = le32_to_cpu(reg->offset);
int i;
@ -1058,17 +1058,18 @@ static int iwl_dump_ini_prph_iter(struct iwl_fw_runtime *fwrt,
addr = le32_to_cpu(range->start_addr) + i;
prph_val = iwl_read_prph(fwrt->trans, addr + offset);
if (prph_val == 0x5a5a5a5a)
return -1;
return -EBUSY;
*val++ = cpu_to_le32(prph_val);
}
return le32_to_cpu(range->range_data_size);
return sizeof(*range) + le32_to_cpu(range->range_data_size);
}
static int iwl_dump_ini_csr_iter(struct iwl_fw_runtime *fwrt,
struct iwl_fw_ini_error_dump_range *range,
struct iwl_fw_ini_region_cfg *reg,
int idx)
void *range_ptr, int idx)
{
struct iwl_fw_ini_error_dump_range *range = range_ptr;
__le32 *val = range->data;
u32 addr, offset = le32_to_cpu(reg->offset);
int i;
@ -1080,14 +1081,15 @@ static int iwl_dump_ini_csr_iter(struct iwl_fw_runtime *fwrt,
*val++ = cpu_to_le32(iwl_trans_read32(fwrt->trans,
addr + offset));
}
return le32_to_cpu(range->range_data_size);
return sizeof(*range) + le32_to_cpu(range->range_data_size);
}
static int iwl_dump_ini_dev_mem_iter(struct iwl_fw_runtime *fwrt,
struct iwl_fw_ini_error_dump_range *range,
struct iwl_fw_ini_region_cfg *reg,
int idx)
void *range_ptr, int idx)
{
struct iwl_fw_ini_error_dump_range *range = range_ptr;
u32 addr = le32_to_cpu(range->start_addr);
u32 offset = le32_to_cpu(reg->offset);
@ -1095,33 +1097,35 @@ static int iwl_dump_ini_dev_mem_iter(struct iwl_fw_runtime *fwrt,
range->range_data_size = reg->internal.range_data_size;
iwl_trans_read_mem_bytes(fwrt->trans, addr + offset, range->data,
le32_to_cpu(reg->internal.range_data_size));
return le32_to_cpu(range->range_data_size);
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_error_dump_range *range,
struct iwl_fw_ini_region_cfg *reg,
int idx)
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->start_addr = 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 le32_to_cpu(range->range_data_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_error_dump_range *range,
struct iwl_fw_ini_region_cfg *reg,
int idx)
void *range_ptr, int idx)
{
/* increase idx by 1 since the pages are from 1 to
* fwrt->num_of_paging_blk + 1
*/
struct page *page = fwrt->fw_paging_db[++idx].fw_paging_block;
struct iwl_fw_ini_error_dump_range *range = range_ptr;
dma_addr_t addr = fwrt->fw_paging_db[idx].fw_paging_phys;
u32 page_size = fwrt->fw_paging_db[idx].fw_paging_size;
@ -1132,20 +1136,21 @@ static int iwl_dump_ini_paging_iter(struct iwl_fw_runtime *fwrt,
memcpy(range->data, page_address(page), page_size);
dma_sync_single_for_device(fwrt->trans->dev, addr, page_size,
DMA_BIDIRECTIONAL);
return le32_to_cpu(range->range_data_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_error_dump_range *range,
struct iwl_fw_ini_region_cfg *reg,
struct iwl_fw_ini_region_cfg *reg, void *range_ptr,
int idx)
{
struct iwl_fw_ini_error_dump_range *range = range_ptr;
u32 start_addr = iwl_read_umac_prph(fwrt->trans,
MON_BUFF_BASE_ADDR_VER2);
if (start_addr == 0x5a5a5a5a)
return -1;
return -EBUSY;
range->start_addr = cpu_to_le32(start_addr);
range->range_data_size = cpu_to_le32(fwrt->trans->fw_mon[idx].size);
@ -1153,19 +1158,239 @@ iwl_dump_ini_mon_dram_iter(struct iwl_fw_runtime *fwrt,
memcpy(range->data, fwrt->trans->fw_mon[idx].block,
fwrt->trans->fw_mon[idx].size);
return le32_to_cpu(range->range_data_size);
return sizeof(*range) + le32_to_cpu(range->range_data_size);
}
static struct iwl_fw_ini_error_dump_range
*iwl_dump_ini_mem_fill_header(struct iwl_fw_runtime *fwrt, void *data)
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_ini_txf_iter_data *iter = fwrt->dump.fifo_iter;
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 (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->fifo_size = 0;
iter->fifo = -1;
if (le32_to_cpu(reg->offset))
iter->lmac = 1;
else
iter->lmac = 0;
}
if (!iter->internal_txf)
for (iter->fifo++; iter->fifo < txf_num; iter->fifo++) {
iter->fifo_size =
cfg->lmac[iter->lmac].txfifo_size[iter->fifo];
if (iter->fifo_size && (lmac_bitmap & BIT(iter->fifo)))
return true;
}
iter->internal_txf = true;
if (!fw_has_capa(&fwrt->fw->ucode_capa,
IWL_UCODE_TLV_CAPA_EXTEND_SHARED_MEM_CFG))
return false;
for (iter->fifo++; iter->fifo < int_txf_num + txf_num; iter->fifo++) {
iter->fifo_size =
cfg->internal_txfifo_size[iter->fifo - txf_num];
if (iter->fifo_size && (lmac_bitmap & BIT(iter->fifo)))
return true;
}
return false;
}
static int iwl_dump_ini_txf_iter(struct iwl_fw_runtime *fwrt,
struct iwl_fw_ini_region_cfg *reg,
void *range_ptr, int idx)
{
struct iwl_fw_ini_fifo_error_dump_range *range = range_ptr;
struct iwl_ini_txf_iter_data *iter;
u32 offs = le32_to_cpu(reg->offset), addr;
u32 registers_size =
le32_to_cpu(reg->fifos.num_of_registers) * sizeof(__le32);
__le32 *val = range->data;
unsigned long flags;
int i;
if (!iwl_ini_txf_iter(fwrt, reg))
return -EIO;
if (!iwl_trans_grab_nic_access(fwrt->trans, &flags))
return -EBUSY;
iter = fwrt->dump.fifo_iter;
range->fifo_num = cpu_to_le32(iter->fifo);
range->num_of_registers = reg->fifos.num_of_registers;
range->range_data_size = cpu_to_le32(iter->fifo_size + registers_size);
iwl_write_prph_no_grab(fwrt->trans, TXF_LARC_NUM + offs, iter->fifo);
/* read txf registers */
for (i = 0; i < le32_to_cpu(reg->fifos.num_of_registers); i++) {
addr = le32_to_cpu(reg->start_addr[i]) + offs;
*val++ = cpu_to_le32(iwl_read_prph_no_grab(fwrt->trans, addr));
}
if (reg->fifos.header_only) {
range->range_data_size = cpu_to_le32(registers_size);
goto out;
}
/* Set the TXF_READ_MODIFY_ADDR to TXF_WR_PTR */
iwl_write_prph_no_grab(fwrt->trans, TXF_READ_MODIFY_ADDR + offs,
TXF_WR_PTR + offs);
/* Dummy-read to advance the read pointer to the head */
iwl_read_prph_no_grab(fwrt->trans, TXF_READ_MODIFY_DATA + offs);
/* Read FIFO */
addr = TXF_READ_MODIFY_DATA + offs;
for (i = 0; i < iter->fifo_size; i += sizeof(__le32))
*val++ = cpu_to_le32(iwl_read_prph_no_grab(fwrt->trans, addr));
out:
iwl_trans_release_nic_access(fwrt->trans, &flags);
return sizeof(*range) + le32_to_cpu(range->range_data_size);
}
struct iwl_ini_rxf_data {
u32 fifo_num;
u32 size;
u32 offset;
};
static void iwl_ini_get_rxf_data(struct iwl_fw_runtime *fwrt,
struct iwl_fw_ini_region_cfg *reg,
struct iwl_ini_rxf_data *data)
{
u32 fid1 = le32_to_cpu(reg->fifos.fid1);
u32 fid2 = le32_to_cpu(reg->fifos.fid2);
u32 fifo_idx;
if (!data)
return;
memset(data, 0, sizeof(*data));
if (WARN_ON_ONCE((fid1 && fid2) || (!fid1 && !fid2)))
return;
fifo_idx = ffs(fid1) - 1;
if (fid1 && !WARN_ON_ONCE((~BIT(fifo_idx) & fid1) ||
fifo_idx >= MAX_NUM_LMAC)) {
data->size = fwrt->smem_cfg.lmac[fifo_idx].rxfifo1_size;
data->fifo_num = fifo_idx;
return;
}
fifo_idx = ffs(fid2) - 1;
if (fid2 && !WARN_ON_ONCE(fifo_idx != 0)) {
data->size = fwrt->smem_cfg.rxfifo2_size;
data->offset = RXF_DIFF_FROM_PREV;
/* use bit 31 to distinguish between umac and lmac rxf while
* parsing the dump
*/
data->fifo_num = fifo_idx | IWL_RXF_UMAC_BIT;
return;
}
}
static int iwl_dump_ini_rxf_iter(struct iwl_fw_runtime *fwrt,
struct iwl_fw_ini_region_cfg *reg,
void *range_ptr, int idx)
{
struct iwl_fw_ini_fifo_error_dump_range *range = range_ptr;
struct iwl_ini_rxf_data rxf_data;
u32 offs = le32_to_cpu(reg->offset), addr;
u32 registers_size =
le32_to_cpu(reg->fifos.num_of_registers) * sizeof(__le32);
__le32 *val = range->data;
unsigned long flags;
int i;
iwl_ini_get_rxf_data(fwrt, reg, &rxf_data);
if (!rxf_data.size)
return -EIO;
if (!iwl_trans_grab_nic_access(fwrt->trans, &flags))
return -EBUSY;
offs += rxf_data.offset;
range->fifo_num = cpu_to_le32(rxf_data.fifo_num);
range->num_of_registers = reg->fifos.num_of_registers;
range->range_data_size = cpu_to_le32(rxf_data.size + registers_size);
/* read rxf registers */
for (i = 0; i < le32_to_cpu(reg->fifos.num_of_registers); i++) {
addr = le32_to_cpu(reg->start_addr[i]) + offs;
*val++ = cpu_to_le32(iwl_read_prph_no_grab(fwrt->trans, addr));
}
if (reg->fifos.header_only) {
range->range_data_size = cpu_to_le32(registers_size);
goto out;
}
/* Lock fence */
iwl_write_prph_no_grab(fwrt->trans, RXF_SET_FENCE_MODE + offs, 0x1);
/* Set fence pointer to the same place like WR pointer */
iwl_write_prph_no_grab(fwrt->trans, RXF_LD_WR2FENCE + offs, 0x1);
/* Set fence offset */
iwl_write_prph_no_grab(fwrt->trans, RXF_LD_FENCE_OFFSET_ADDR + offs,
0x0);
/* Read FIFO */
addr = RXF_FIFO_RD_FENCE_INC + offs;
for (i = 0; i < rxf_data.size; i += sizeof(__le32))
*val++ = cpu_to_le32(iwl_read_prph_no_grab(fwrt->trans, addr));
out:
iwl_trans_release_nic_access(fwrt->trans, &flags);
return sizeof(*range) + le32_to_cpu(range->range_data_size);
}
static void *iwl_dump_ini_mem_fill_header(struct iwl_fw_runtime *fwrt,
struct iwl_fw_ini_region_cfg *reg,
void *data)
{
struct iwl_fw_ini_error_dump *dump = data;
return dump->ranges;
}
static struct iwl_fw_ini_error_dump_range
*iwl_dump_ini_mon_dram_fill_header(struct iwl_fw_runtime *fwrt, void *data)
static void
*iwl_dump_ini_mon_dram_fill_header(struct iwl_fw_runtime *fwrt,
struct iwl_fw_ini_region_cfg *reg,
void *data)
{
struct iwl_fw_ini_monitor_dram_dump *mon_dump = (void *)data;
u32 write_ptr, cycle_cnt;
@ -1187,39 +1412,13 @@ static struct iwl_fw_ini_error_dump_range
return mon_dump->ranges;
}
static u32 iwl_dump_ini_mem_get_size(struct iwl_fw_runtime *fwrt,
struct iwl_fw_ini_region_cfg *reg)
static void *iwl_dump_ini_fifo_fill_header(struct iwl_fw_runtime *fwrt,
struct iwl_fw_ini_region_cfg *reg,
void *data)
{
return le32_to_cpu(reg->internal.num_of_ranges) *
le32_to_cpu(reg->internal.range_data_size);
}
struct iwl_fw_ini_fifo_error_dump *dump = data;
static u32 iwl_dump_ini_paging_gen2_get_size(struct iwl_fw_runtime *fwrt,
struct iwl_fw_ini_region_cfg *reg)
{
int i;
u32 size = 0;
for (i = 0; i < fwrt->trans->init_dram.paging_cnt; i++)
size += 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)
{
int i;
u32 size = 0;
for (i = 1; i <= fwrt->num_of_paging_blk; i++)
size += fwrt->fw_paging_db[i].fw_paging_size;
return size;
}
static u32 iwl_dump_ini_mon_dram_get_size(struct iwl_fw_runtime *fwrt,
struct iwl_fw_ini_region_cfg *reg)
{
return fwrt->trans->num_blocks ? fwrt->trans->fw_mon[0].size : 0;
return dump->ranges;
}
static u32 iwl_dump_ini_mem_ranges(struct iwl_fw_runtime *fwrt,
@ -1246,25 +1445,138 @@ static u32 iwl_dump_ini_mon_dram_ranges(struct iwl_fw_runtime *fwrt,
return 1;
}
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))
num_of_fifos++;
fwrt->dump.fifo_iter = fifo_iter;
return num_of_fifos;
}
static u32 iwl_dump_ini_rxf_ranges(struct iwl_fw_runtime *fwrt,
struct iwl_fw_ini_region_cfg *reg)
{
/* Each Rx fifo needs a different offset and therefore, it's
* region can contain only one fifo, i.e. 1 memory range.
*/
return 1;
}
static u32 iwl_dump_ini_mem_get_size(struct iwl_fw_runtime *fwrt,
struct iwl_fw_ini_region_cfg *reg)
{
return sizeof(struct iwl_fw_ini_error_dump) +
iwl_dump_ini_mem_ranges(fwrt, reg) *
(sizeof(struct iwl_fw_ini_error_dump_range) +
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)
{
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 = 1; i <= iwl_dump_ini_paging_ranges(fwrt, reg); i++)
size += range_header_len + fwrt->fw_paging_db[i].fw_paging_size;
return size;
}
static u32 iwl_dump_ini_mon_dram_get_size(struct iwl_fw_runtime *fwrt,
struct iwl_fw_ini_region_cfg *reg)
{
u32 size = sizeof(struct iwl_fw_ini_monitor_dram_dump);
if (fwrt->trans->num_blocks)
size += fwrt->trans->fw_mon[0].size;
return size;
}
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;
u32 size = 0;
u32 fifo_hdr = sizeof(struct iwl_fw_ini_fifo_error_dump_range) +
le32_to_cpu(reg->fifos.num_of_registers) * sizeof(__le32);
fwrt->dump.fifo_iter = &iter;
while (iwl_ini_txf_iter(fwrt, reg)) {
size += fifo_hdr;
if (!reg->fifos.header_only)
size += iter.fifo_size;
}
if (size)
size += sizeof(struct iwl_fw_ini_fifo_error_dump);
fwrt->dump.fifo_iter = fifo_iter;
return size;
}
static u32 iwl_dump_ini_rxf_get_size(struct iwl_fw_runtime *fwrt,
struct iwl_fw_ini_region_cfg *reg)
{
struct iwl_ini_rxf_data rx_data;
u32 size = sizeof(struct iwl_fw_ini_fifo_error_dump) +
sizeof(struct iwl_fw_ini_fifo_error_dump_range) +
le32_to_cpu(reg->fifos.num_of_registers) * sizeof(__le32);
if (reg->fifos.header_only)
return size;
iwl_ini_get_rxf_data(fwrt, reg, &rx_data);
size += rx_data.size;
return size;
}
/**
* struct iwl_dump_ini_mem_ops - ini memory dump operations
* @get_num_of_ranges: returns the number of memory ranges in the region.
* @get_size: returns the size of the region data without headers.
* @fill_mem_hdr: fills region type specific headers and returns the first
* range or NULL if failed to fill headers.
* @get_size: returns the total size of the region.
* @fill_mem_hdr: fills region type specific headers and returns pointer to
* the first range or NULL if failed to fill headers.
* @fill_range: copies a given memory range into the dump.
* Returns the size of the range or -1 otherwise.
* Returns the size of the range or negative error value otherwise.
*/
struct iwl_dump_ini_mem_ops {
u32 (*get_num_of_ranges)(struct iwl_fw_runtime *fwrt,
struct iwl_fw_ini_region_cfg *reg);
u32 (*get_size)(struct iwl_fw_runtime *fwrt,
struct iwl_fw_ini_region_cfg *reg);
struct iwl_fw_ini_error_dump_range *
(*fill_mem_hdr)(struct iwl_fw_runtime *fwrt, void *data);
void *(*fill_mem_hdr)(struct iwl_fw_runtime *fwrt,
struct iwl_fw_ini_region_cfg *reg, void *data);
int (*fill_range)(struct iwl_fw_runtime *fwrt,
struct iwl_fw_ini_error_dump_range *range,
struct iwl_fw_ini_region_cfg *reg, int idx);
struct iwl_fw_ini_region_cfg *reg, void *range,
int idx);
};
/**
@ -1281,7 +1593,7 @@ iwl_dump_ini_mem(struct iwl_fw_runtime *fwrt,
struct iwl_dump_ini_mem_ops *ops)
{
struct iwl_fw_ini_error_dump_header *header = (void *)(*data)->data;
struct iwl_fw_ini_error_dump_range *range;
void *range;
u32 num_of_ranges, i;
if (WARN_ON(!ops || !ops->get_num_of_ranges || !ops->get_size ||
@ -1291,26 +1603,29 @@ iwl_dump_ini_mem(struct iwl_fw_runtime *fwrt,
num_of_ranges = ops->get_num_of_ranges(fwrt, reg);
(*data)->type = cpu_to_le32(type | INI_DUMP_BIT);
(*data)->len = cpu_to_le32(sizeof(*header) + num_of_ranges *
sizeof(*range) + ops->get_size(fwrt, reg));
(*data)->len = cpu_to_le32(ops->get_size(fwrt, reg));
header->num_of_ranges = cpu_to_le32(num_of_ranges);
header->name_len = cpu_to_le32(min_t(int, IWL_FW_INI_MAX_NAME,
le32_to_cpu(reg->name_len)));
memcpy(header->name, reg->name, le32_to_cpu(header->name_len));
range = ops->fill_mem_hdr(fwrt, header);
if (!range)
range = ops->fill_mem_hdr(fwrt, reg, header);
if (!range) {
IWL_ERR(fwrt, "Failed to fill region header: id=%d, type=%d\n",
le32_to_cpu(reg->region_id), type);
return;
}
for (i = 0; i < num_of_ranges; i++) {
int range_data_size = ops->fill_range(fwrt, range, reg, i);
int range_size = ops->fill_range(fwrt, reg, range, i);
if (range_data_size < 0) {
IWL_ERR(fwrt, "Failed to dump region type %d\n", type);
if (range_size < 0) {
IWL_ERR(fwrt, "Failed to dump region: id=%d, type=%d\n",
le32_to_cpu(reg->region_id), type);
return;
}
range = ((void *)range) + sizeof(*range) + range_data_size;
range = range + range_size;
}
*data = iwl_fw_error_next_data(*data);
}
@ -1319,8 +1634,6 @@ static int iwl_fw_ini_get_trigger_len(struct iwl_fw_runtime *fwrt,
struct iwl_fw_ini_trigger *trigger)
{
int i, size = 0, hdr_len = sizeof(struct iwl_fw_error_dump_data);
u32 dump_header_len = sizeof(struct iwl_fw_ini_error_dump);
u32 range_header_len = sizeof(struct iwl_fw_ini_error_dump_range);
if (!trigger || !trigger->num_regions)
return 0;
@ -1345,27 +1658,20 @@ static int iwl_fw_ini_get_trigger_len(struct iwl_fw_runtime *fwrt,
case IWL_FW_INI_REGION_PERIPHERY_AUX:
case IWL_FW_INI_REGION_INTERNAL_BUFFER:
case IWL_FW_INI_REGION_CSR:
size += hdr_len + dump_header_len + range_header_len *
iwl_dump_ini_mem_ranges(fwrt, reg) +
iwl_dump_ini_mem_get_size(fwrt, reg);
size += hdr_len + iwl_dump_ini_mem_get_size(fwrt, reg);
break;
case IWL_FW_INI_REGION_TXF:
size += iwl_fw_txf_len(fwrt, &fwrt->smem_cfg);
size += hdr_len + iwl_dump_ini_txf_get_size(fwrt, reg);
break;
case IWL_FW_INI_REGION_RXF:
size += iwl_fw_rxf_len(fwrt, &fwrt->smem_cfg);
size += hdr_len + iwl_dump_ini_rxf_get_size(fwrt, reg);
break;
case IWL_FW_INI_REGION_PAGING: {
size += hdr_len + dump_header_len;
size += hdr_len;
if (iwl_fw_dbg_is_paging_enabled(fwrt)) {
size += range_header_len *
iwl_dump_ini_paging_ranges(fwrt, reg) +
iwl_dump_ini_paging_get_size(fwrt, reg);
size += iwl_dump_ini_paging_get_size(fwrt, reg);
} else {
size += range_header_len *
iwl_dump_ini_paging_gen2_ranges(fwrt,
reg) +
iwl_dump_ini_paging_gen2_get_size(fwrt,
size += iwl_dump_ini_paging_gen2_get_size(fwrt,
reg);
}
break;
@ -1374,8 +1680,6 @@ static int iwl_fw_ini_get_trigger_len(struct iwl_fw_runtime *fwrt,
if (!fwrt->trans->num_blocks)
break;
size += hdr_len +
sizeof(struct iwl_fw_ini_monitor_dram_dump) *
iwl_dump_ini_mon_dram_ranges(fwrt, reg) +
iwl_dump_ini_mon_dram_get_size(fwrt, reg);
break;
case IWL_FW_INI_REGION_DRAM_IMR:
@ -1451,11 +1755,25 @@ static void iwl_fw_ini_dump_trigger(struct iwl_fw_runtime *fwrt,
iwl_dump_ini_mem(fwrt, type, data, reg, &ops);
break;
}
case IWL_FW_INI_REGION_TXF:
iwl_fw_dump_txf(fwrt, data);
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_fifo_fill_header;
ops.fill_range = iwl_dump_ini_txf_iter;
iwl_dump_ini_mem(fwrt, type, data, reg, &ops);
fwrt->dump.fifo_iter = fifo_iter;
break;
}
case IWL_FW_INI_REGION_RXF:
iwl_fw_dump_rxf(fwrt, data);
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_fifo_fill_header;
ops.fill_range = iwl_dump_ini_rxf_iter;
iwl_dump_ini_mem(fwrt, type, data, reg, &ops);
break;
case IWL_FW_INI_REGION_CSR:
ops.get_num_of_ranges = iwl_dump_ini_mem_ranges;
@ -1592,22 +1910,6 @@ int iwl_fw_dbg_collect_desc(struct iwl_fw_runtime *fwrt,
bool monitor_only,
unsigned int delay)
{
/*
* If the loading of the FW completed successfully, the next step is to
* get the SMEM config data. Thus, if fwrt->smem_cfg.num_lmacs is non
* zero, the FW was already loaded successully. If the state is "NO_FW"
* in such a case - exit, since FW may be dead. Otherwise, we
* can try to collect the data, since FW might just not be fully
* loaded (no "ALIVE" yet), and the debug data is accessible.
*
* Corner case: got the FW alive but crashed before getting the SMEM
* config. In such a case, due to HW access problems, we might
* collect garbage.
*/
if (fwrt->trans->state == IWL_TRANS_NO_FW &&
fwrt->smem_cfg.num_lmacs)
return -EIO;
if (test_and_set_bit(IWL_FWRT_STATUS_DUMPING, &fwrt->status))
return -EBUSY;
@ -2109,8 +2411,6 @@ static void iwl_fw_dbg_update_triggers(struct iwl_fw_runtime *fwrt,
/* Since zero means infinity - just set to -1 */
if (!le32_to_cpu(active->trig->occurrences))
active->trig->occurrences = cpu_to_le32(-1);
if (!le32_to_cpu(active->trig->ignore_consec))
active->trig->ignore_consec = cpu_to_le32(-1);
active->active = true;
next:

View File

@ -173,9 +173,8 @@ static const struct file_operations iwl_dbgfs_##name##_ops = { \
_FWRT_DEBUGFS_READ_WRITE_FILE_OPS(name, bufsz, struct iwl_fw_runtime)
#define FWRT_DEBUGFS_ADD_FILE_ALIAS(alias, name, parent, mode) do { \
if (!debugfs_create_file(alias, mode, parent, fwrt, \
&iwl_dbgfs_##name##_ops)) \
goto err; \
debugfs_create_file(alias, mode, parent, fwrt, \
&iwl_dbgfs_##name##_ops); \
} while (0)
#define FWRT_DEBUGFS_ADD_FILE(name, parent, mode) \
FWRT_DEBUGFS_ADD_FILE_ALIAS(#name, name, parent, mode)
@ -321,14 +320,10 @@ out:
FWRT_DEBUGFS_WRITE_FILE_OPS(send_hcmd, 512);
int iwl_fwrt_dbgfs_register(struct iwl_fw_runtime *fwrt,
void iwl_fwrt_dbgfs_register(struct iwl_fw_runtime *fwrt,
struct dentry *dbgfs_dir)
{
INIT_DELAYED_WORK(&fwrt->timestamp.wk, iwl_fw_timestamp_marker_wk);
FWRT_DEBUGFS_ADD_FILE(timestamp_marker, dbgfs_dir, 0200);
FWRT_DEBUGFS_ADD_FILE(send_hcmd, dbgfs_dir, 0200);
return 0;
err:
IWL_ERR(fwrt, "Can't create the fwrt debugfs directory\n");
return -ENOMEM;
}

View File

@ -63,14 +63,11 @@
#include "runtime.h"
#ifdef CONFIG_IWLWIFI_DEBUGFS
int iwl_fwrt_dbgfs_register(struct iwl_fw_runtime *fwrt,
void iwl_fwrt_dbgfs_register(struct iwl_fw_runtime *fwrt,
struct dentry *dbgfs_dir);
#else
static inline int iwl_fwrt_dbgfs_register(struct iwl_fw_runtime *fwrt,
struct dentry *dbgfs_dir)
{
return 0;
}
static inline void iwl_fwrt_dbgfs_register(struct iwl_fw_runtime *fwrt,
struct dentry *dbgfs_dir) { }
#endif /* CONFIG_IWLWIFI_DEBUGFS */

View File

@ -8,7 +8,7 @@
* Copyright(c) 2014 Intel Corporation. All rights reserved.
* Copyright(c) 2014 - 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) 2014 Intel Corporation. All rights reserved.
* Copyright(c) 2014 - 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
@ -308,6 +308,34 @@ struct iwl_fw_ini_error_dump {
struct iwl_fw_ini_error_dump_range ranges[];
} __packed;
/* This bit is used to differentiate between lmac and umac rxf */
#define IWL_RXF_UMAC_BIT BIT(31)
/**
* struct iwl_fw_ini_fifo_error_dump_range - ini fifo range dump
* @fifo_num: the fifo num. In case of rxf and umac rxf, set BIT(31) to
* distinguish between lmac and umac
* @num_of_registers: num of registers to dump, dword size each
* @range_data_size: the size of the registers and fifo data
* @data: fifo data
*/
struct iwl_fw_ini_fifo_error_dump_range {
__le32 fifo_num;
__le32 num_of_registers;
__le32 range_data_size;
__le32 data[];
} __packed;
/**
* struct iwl_fw_ini_fifo_error_dump - ini fifo region dump
* @header: the header of this region
* @ranges: the memory ranges of this region
*/
struct iwl_fw_ini_fifo_error_dump {
struct iwl_fw_ini_error_dump_header header;
struct iwl_fw_ini_fifo_error_dump_range ranges[];
} __packed;
/**
* struct iwl_fw_error_dump_rb - content of an Receive Buffer
* @index: the index of the Receive Buffer in the Rx queue

View File

@ -144,6 +144,7 @@ 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;
} dump;
#ifdef CONFIG_IWLWIFI_DEBUGFS
struct {

View File

@ -548,7 +548,7 @@ extern const struct iwl_cfg iwl9560_killer_s_2ac_cfg_shared_clk;
extern const struct iwl_cfg iwl22000_2ac_cfg_hr;
extern const struct iwl_cfg iwl22000_2ac_cfg_hr_cdb;
extern const struct iwl_cfg iwl22000_2ac_cfg_jf;
extern const struct iwl_cfg iwl22560_2ax_cfg_hr;
extern const struct iwl_cfg iwl_ax101_cfg_qu_hr;
extern const struct iwl_cfg iwl22000_2ax_cfg_hr;
extern const struct iwl_cfg iwl22260_2ax_cfg;
extern const struct iwl_cfg killer1650s_2ax_cfg_qu_b0_hr_b0;

View File

@ -1253,11 +1253,6 @@ _iwl_op_mode_start(struct iwl_drv *drv, struct iwlwifi_opmode_table *op)
#ifdef CONFIG_IWLWIFI_DEBUGFS
drv->dbgfs_op_mode = debugfs_create_dir(op->name,
drv->dbgfs_drv);
if (!drv->dbgfs_op_mode) {
IWL_ERR(drv,
"failed to create opmode debugfs directory\n");
return op_mode;
}
dbgfs_dir = drv->dbgfs_op_mode;
#endif
@ -1620,20 +1615,8 @@ struct iwl_drv *iwl_drv_start(struct iwl_trans *trans)
drv->dbgfs_drv = debugfs_create_dir(dev_name(trans->dev),
iwl_dbgfs_root);
if (!drv->dbgfs_drv) {
IWL_ERR(drv, "failed to create debugfs directory\n");
ret = -ENOMEM;
goto err_free_tlv;
}
/* Create transport layer debugfs dir */
drv->trans->dbgfs_dir = debugfs_create_dir("trans", drv->dbgfs_drv);
if (!drv->trans->dbgfs_dir) {
IWL_ERR(drv, "failed to create transport debugfs directory\n");
ret = -ENOMEM;
goto err_free_dbgfs;
}
#endif
ret = iwl_request_firmware(drv, true);
@ -1646,9 +1629,7 @@ struct iwl_drv *iwl_drv_start(struct iwl_trans *trans)
err_fw:
#ifdef CONFIG_IWLWIFI_DEBUGFS
err_free_dbgfs:
debugfs_remove_recursive(drv->dbgfs_drv);
err_free_tlv:
iwl_fw_dbg_free(drv->trans);
#endif
kfree(drv);
@ -1759,9 +1740,6 @@ static int __init iwl_drv_init(void)
#ifdef CONFIG_IWLWIFI_DEBUGFS
/* Create the root of iwlwifi debugfs subsystem. */
iwl_dbgfs_root = debugfs_create_dir(DRV_NAME, NULL);
if (!iwl_dbgfs_root)
return -EFAULT;
#endif
return iwl_pci_register_driver();

View File

@ -850,8 +850,7 @@ iwl_parse_eeprom_data(struct device *dev, const struct iwl_cfg *cfg,
if (WARN_ON(!cfg || !cfg->eeprom_params))
return NULL;
data = kzalloc(sizeof(*data) +
sizeof(struct ieee80211_channel) * IWL_NUM_CHANNELS,
data = kzalloc(struct_size(data, channels, IWL_NUM_CHANNELS),
GFP_KERNEL);
if (!data)
return NULL;

View File

@ -8,7 +8,7 @@
* Copyright(c) 2008 - 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
@ -463,6 +463,9 @@ static void iwl_init_vht_hw_capab(const struct iwl_cfg *cfg,
}
vht_cap->vht_mcs.tx_mcs_map = vht_cap->vht_mcs.rx_mcs_map;
vht_cap->vht_mcs.tx_highest |=
cpu_to_le16(IEEE80211_VHT_EXT_NSS_BW_CAPABLE);
}
static struct ieee80211_sband_iftype_data iwl_he_capa[] = {
@ -946,15 +949,13 @@ iwl_parse_nvm_data(struct iwl_trans *trans, const struct iwl_cfg *cfg,
const __le16 *ch_section;
if (cfg->nvm_type != IWL_NVM_EXT)
data = kzalloc(sizeof(*data) +
sizeof(struct ieee80211_channel) *
IWL_NVM_NUM_CHANNELS,
GFP_KERNEL);
data = kzalloc(struct_size(data, channels,
IWL_NVM_NUM_CHANNELS),
GFP_KERNEL);
else
data = kzalloc(sizeof(*data) +
sizeof(struct ieee80211_channel) *
IWL_NVM_NUM_CHANNELS_EXT,
GFP_KERNEL);
data = kzalloc(struct_size(data, channels,
IWL_NVM_NUM_CHANNELS_EXT),
GFP_KERNEL);
if (!data)
return NULL;
@ -1441,9 +1442,7 @@ struct iwl_nvm_data *iwl_get_nvm(struct iwl_trans *trans,
if (empty_otp)
IWL_INFO(trans, "OTP is empty\n");
nvm = kzalloc(sizeof(*nvm) +
sizeof(struct ieee80211_channel) * IWL_NUM_CHANNELS,
GFP_KERNEL);
nvm = kzalloc(struct_size(nvm, channels, IWL_NUM_CHANNELS), GFP_KERNEL);
if (!nvm) {
ret = -ENOMEM;
goto out;

View File

@ -117,6 +117,7 @@
#define IWL_MVM_TCM_LOWLAT_ENABLE_THRESH 100 /* packets/10 seconds */
#define IWL_MVM_UAPSD_NONAGG_PERIOD 5000 /* msecs */
#define IWL_MVM_UAPSD_NOAGG_LIST_LEN IWL_MVM_UAPSD_NOAGG_BSSIDS_NUM
#define IWL_MVM_NON_TRANSMITTING_AP 0
#define IWL_MVM_RS_NUM_TRY_BEFORE_ANT_TOGGLE 1
#define IWL_MVM_RS_HT_VHT_RETRIES_PER_RATE 2
#define IWL_MVM_RS_HT_VHT_RETRIES_PER_RATE_TW 1

View File

@ -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
@ -1238,6 +1238,8 @@ static int _iwl_dbgfs_inject_beacon_ie(struct iwl_mvm *mvm, char *bin, int len)
goto out_err;
}
mvm->beacon_inject_active = true;
mvmvif = iwl_mvm_vif_from_mac80211(vif);
info = IEEE80211_SKB_CB(beacon);
rate = iwl_mvm_mac_ctxt_get_lowest_rate(info, vif);
@ -1287,6 +1289,7 @@ static ssize_t iwl_dbgfs_inject_beacon_ie_restore_write(struct iwl_mvm *mvm,
int ret = _iwl_dbgfs_inject_beacon_ie(mvm, NULL, 0);
mvm->hw->extra_beacon_tailroom = 0;
mvm->beacon_inject_active = false;
return ret ?: count;
}
@ -1786,6 +1789,7 @@ iwl_dbgfs_send_echo_cmd_write(struct iwl_mvm *mvm, char *buf,
struct iwl_mvm_sniffer_apply {
struct iwl_mvm *mvm;
u8 *bssid;
u16 aid;
};
@ -1795,6 +1799,8 @@ static bool iwl_mvm_sniffer_apply(struct iwl_notif_wait_data *notif_data,
struct iwl_mvm_sniffer_apply *apply = data;
apply->mvm->cur_aid = cpu_to_le16(apply->aid);
memcpy(apply->mvm->cur_bssid, apply->bssid,
sizeof(apply->mvm->cur_bssid));
return true;
}
@ -1827,6 +1833,7 @@ iwl_dbgfs_he_sniffer_params_write(struct iwl_mvm *mvm, char *buf,
he_mon_cmd.aid = cpu_to_le16(aid);
apply.aid = aid;
apply.bssid = (void *)he_mon_cmd.bssid;
mutex_lock(&mvm->mutex);
@ -1855,6 +1862,23 @@ iwl_dbgfs_he_sniffer_params_write(struct iwl_mvm *mvm, char *buf,
return ret ?: count;
}
static ssize_t
iwl_dbgfs_he_sniffer_params_read(struct file *file, char __user *user_buf,
size_t count, loff_t *ppos)
{
struct iwl_mvm *mvm = file->private_data;
u8 buf[32];
int len;
len = scnprintf(buf, sizeof(buf),
"%d %02hhx:%02hhx:%02hhx:%02hhx:%02hhx:%02hhx\n",
le16_to_cpu(mvm->cur_aid), mvm->cur_bssid[0],
mvm->cur_bssid[1], mvm->cur_bssid[2], mvm->cur_bssid[3],
mvm->cur_bssid[4], mvm->cur_bssid[5]);
return simple_read_from_buffer(user_buf, count, ppos, buf, len);
}
static ssize_t
iwl_dbgfs_uapsd_noagg_bssids_read(struct file *file, char __user *user_buf,
size_t count, loff_t *ppos)
@ -1925,7 +1949,7 @@ MVM_DEBUGFS_READ_WRITE_FILE_OPS(d3_sram, 8);
MVM_DEBUGFS_READ_FILE_OPS(sar_geo_profile);
#endif
MVM_DEBUGFS_WRITE_FILE_OPS(he_sniffer_params, 32);
MVM_DEBUGFS_READ_WRITE_FILE_OPS(he_sniffer_params, 32);
static ssize_t iwl_dbgfs_mem_read(struct file *file, char __user *user_buf,
size_t count, loff_t *ppos)
@ -2116,7 +2140,7 @@ int iwl_mvm_dbgfs_register(struct iwl_mvm *mvm, struct dentry *dbgfs_dir)
#ifdef CONFIG_ACPI
MVM_DEBUGFS_ADD_FILE(sar_geo_profile, dbgfs_dir, 0400);
#endif
MVM_DEBUGFS_ADD_FILE(he_sniffer_params, mvm->debugfs_dir, 0200);
MVM_DEBUGFS_ADD_FILE(he_sniffer_params, mvm->debugfs_dir, 0600);
if (!debugfs_create_bool("enable_scan_iteration_notif",
0600,

View File

@ -646,10 +646,10 @@ static int iwl_mvm_config_ltr(struct iwl_mvm *mvm)
}
#ifdef CONFIG_ACPI
static int iwl_mvm_sar_set_profile(struct iwl_mvm *mvm,
union acpi_object *table,
struct iwl_mvm_sar_profile *profile,
bool enabled)
static inline int iwl_mvm_sar_set_profile(struct iwl_mvm *mvm,
union acpi_object *table,
struct iwl_mvm_sar_profile *profile,
bool enabled)
{
int i;

View File

@ -1016,6 +1016,9 @@ int iwl_mvm_mac_ctxt_send_beacon(struct iwl_mvm *mvm,
if (WARN_ON(!beacon))
return -EINVAL;
if (IWL_MVM_NON_TRANSMITTING_AP)
return 0;
if (!fw_has_capa(&mvm->fw->ucode_capa,
IWL_UCODE_TLV_CAPA_CSA_AND_TBTT_OFFLOAD))
return iwl_mvm_mac_ctxt_send_beacon_v6(mvm, vif, beacon);
@ -1041,6 +1044,11 @@ int iwl_mvm_mac_ctxt_beacon_changed(struct iwl_mvm *mvm,
if (!beacon)
return -ENOMEM;
#ifdef CONFIG_IWLWIFI_DEBUGFS
if (mvm->beacon_inject_active)
return -EBUSY;
#endif
ret = iwl_mvm_mac_ctxt_send_beacon(mvm, vif, beacon);
dev_kfree_skb(beacon);
return ret;

View File

@ -796,15 +796,15 @@ int iwl_mvm_mac_setup_register(struct iwl_mvm *mvm)
hw->netdev_features |= IWL_TX_CSUM_NETIF_FLAGS;
}
ret = ieee80211_register_hw(mvm->hw);
if (ret)
iwl_mvm_leds_exit(mvm);
mvm->init_status |= IWL_MVM_INIT_STATUS_REG_HW_INIT_COMPLETE;
if (mvm->cfg->vht_mu_mimo_supported)
wiphy_ext_feature_set(hw->wiphy,
NL80211_EXT_FEATURE_MU_MIMO_AIR_SNIFFER);
ret = ieee80211_register_hw(mvm->hw);
if (ret) {
iwl_mvm_leds_exit(mvm);
}
return ret;
}
@ -941,8 +941,14 @@ void iwl_mvm_mac_itxq_xmit(struct ieee80211_hw *hw, struct ieee80211_txq *txq)
IWL_PLAT_PM_MODE_DISABLED))) {
skb = ieee80211_tx_dequeue(hw, txq);
if (!skb)
if (!skb) {
if (txq->sta)
IWL_DEBUG_TX(mvm,
"TXQ of sta %pM tid %d is now empty\n",
txq->sta->addr,
txq->tid);
break;
}
if (!txq->sta)
iwl_mvm_tx_skb_non_sta(mvm, skb);

View File

@ -978,6 +978,7 @@ struct iwl_mvm {
u32 dbgfs_prph_reg_addr;
bool disable_power_off;
bool disable_power_off_d3;
bool beacon_inject_active;
bool scan_iter_notif_enabled;
@ -1175,6 +1176,7 @@ struct iwl_mvm {
/* sniffer data to include in radiotap */
__le16 cur_aid;
u8 cur_bssid[ETH_ALEN];
#ifdef CONFIG_ACPI
struct iwl_mvm_sar_profile sar_profiles[ACPI_SAR_PROFILE_NUM];
@ -1219,7 +1221,6 @@ enum iwl_mvm_status {
enum iwl_mvm_init_status {
IWL_MVM_INIT_STATUS_THERMAL_INIT_COMPLETE = BIT(0),
IWL_MVM_INIT_STATUS_LEDS_INIT_COMPLETE = BIT(1),
IWL_MVM_INIT_STATUS_REG_HW_INIT_COMPLETE = BIT(2),
};
static inline bool iwl_mvm_is_radio_killed(struct iwl_mvm *mvm)

View File

@ -919,10 +919,7 @@ static void iwl_op_mode_mvm_stop(struct iwl_op_mode *op_mode)
iwl_mvm_thermal_exit(mvm);
if (mvm->init_status & IWL_MVM_INIT_STATUS_REG_HW_INIT_COMPLETE) {
ieee80211_unregister_hw(mvm->hw);
mvm->init_status &= ~IWL_MVM_INIT_STATUS_REG_HW_INIT_COMPLETE;
}
ieee80211_unregister_hw(mvm->hw);
kfree(mvm->scan_cmd);
kfree(mvm->mcast_filter_cmd);
@ -1320,6 +1317,9 @@ void iwl_mvm_nic_restart(struct iwl_mvm *mvm, bool fw_error)
reprobe->dev = mvm->trans->dev;
INIT_WORK(&reprobe->work, iwl_mvm_reprobe_wk);
schedule_work(&reprobe->work);
} else if (test_bit(IWL_MVM_STATUS_HW_RESTART_REQUESTED,
&mvm->status)) {
IWL_ERR(mvm, "HW restart already requested, but not started\n");
} else if (mvm->fwrt.cur_fw_img == IWL_UCODE_REGULAR &&
mvm->hw_registered &&
!test_bit(STATUS_TRANS_DEAD, &mvm->trans->status)) {

View File

@ -3,7 +3,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
*
* 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
@ -1643,8 +1643,26 @@ static s32 rs_get_best_rate(struct iwl_mvm *mvm,
static u32 rs_bw_from_sta_bw(struct ieee80211_sta *sta)
{
struct ieee80211_sta_vht_cap *sta_vht_cap = &sta->vht_cap;
struct ieee80211_vht_cap vht_cap = {
.vht_cap_info = cpu_to_le32(sta_vht_cap->cap),
.supp_mcs = sta_vht_cap->vht_mcs,
};
switch (sta->bandwidth) {
case IEEE80211_STA_RX_BW_160:
/*
* Don't use 160 MHz if VHT extended NSS support
* says we cannot use 2 streams, we don't want to
* deal with this.
* We only check MCS 0 - they will support that if
* we got here at all and we don't care which MCS,
* we want to determine a more global state.
*/
if (ieee80211_get_vht_max_nss(&vht_cap,
IEEE80211_VHT_CHANWIDTH_160MHZ,
0, true) < sta->rx_nss)
return RATE_MCS_CHAN_WIDTH_80;
return RATE_MCS_CHAN_WIDTH_160;
case IEEE80211_STA_RX_BW_80:
return RATE_MCS_CHAN_WIDTH_80;
@ -1796,7 +1814,7 @@ static bool rs_tweak_rate_tbl(struct iwl_mvm *mvm,
struct iwl_scale_tbl_info *tbl,
enum rs_action scale_action)
{
if (sta->bandwidth != IEEE80211_STA_RX_BW_80)
if (rs_bw_from_sta_bw(sta) != RATE_MCS_CHAN_WIDTH_80)
return false;
if (!is_vht_siso(&tbl->rate))
@ -4127,6 +4145,7 @@ static const struct rate_control_ops rs_mvm_ops_drv = {
.add_sta_debugfs = rs_drv_add_sta_debugfs,
.remove_sta_debugfs = rs_remove_sta_debugfs,
#endif
.capa = RATE_CTRL_CAPA_VHT_EXT_NSS_BW,
};
void iwl_mvm_rs_rate_init(struct iwl_mvm *mvm, struct ieee80211_sta *sta,

View File

@ -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
@ -209,7 +209,9 @@ void iwl_mvm_set_tx_cmd(struct iwl_mvm *mvm, struct sk_buff *skb,
u16 offload_assist = 0;
u8 ac;
if (!(info->flags & IEEE80211_TX_CTL_NO_ACK))
if (!(info->flags & IEEE80211_TX_CTL_NO_ACK) ||
(ieee80211_is_probe_resp(fc) &&
!is_multicast_ether_addr(hdr->addr1)))
tx_flags |= TX_CMD_FLG_ACK;
else
tx_flags &= ~TX_CMD_FLG_ACK;
@ -278,7 +280,7 @@ void iwl_mvm_set_tx_cmd(struct iwl_mvm *mvm, struct sk_buff *skb,
}
if (ieee80211_is_data(fc) && len > mvm->rts_threshold &&
!is_multicast_ether_addr(ieee80211_get_DA(hdr)))
!is_multicast_ether_addr(hdr->addr1))
tx_flags |= TX_CMD_FLG_PROT_REQUIRE;
if (fw_has_capa(&mvm->fw->ucode_capa,
@ -719,6 +721,9 @@ int iwl_mvm_tx_skb_non_sta(struct iwl_mvm *mvm, struct sk_buff *skb)
IEEE80211_TX_CTL_TX_OFFCHAN;
int queue = -1;
if (IWL_MVM_NON_TRANSMITTING_AP && ieee80211_is_probe_resp(fc))
return -1;
memcpy(&info, skb->cb, sizeof(info));
if (WARN_ON_ONCE(info.flags & IEEE80211_TX_CTL_AMPDU))
@ -1078,6 +1083,9 @@ static int iwl_mvm_tx_mpdu(struct iwl_mvm *mvm, struct sk_buff *skb,
fc = hdr->frame_control;
hdrlen = ieee80211_hdrlen(fc);
if (IWL_MVM_NON_TRANSMITTING_AP && ieee80211_is_probe_resp(fc))
return -1;
if (WARN_ON_ONCE(!mvmsta))
return -1;
@ -1107,12 +1115,14 @@ static int iwl_mvm_tx_mpdu(struct iwl_mvm *mvm, struct sk_buff *skb,
*/
if (ieee80211_is_data_qos(fc) && !ieee80211_is_qos_nullfunc(fc)) {
tid = ieee80211_get_tid(hdr);
if (WARN_ON_ONCE(tid >= IWL_MAX_TID_COUNT))
if (WARN_ONCE(tid >= IWL_MAX_TID_COUNT, "Invalid TID %d", tid))
goto drop_unlock_sta;
is_ampdu = info->flags & IEEE80211_TX_CTL_AMPDU;
if (WARN_ON_ONCE(is_ampdu &&
mvmsta->tid_data[tid].state != IWL_AGG_ON))
if (WARN_ONCE(is_ampdu &&
mvmsta->tid_data[tid].state != IWL_AGG_ON,
"Invalid internal agg state %d for TID %d",
mvmsta->tid_data[tid].state, tid))
goto drop_unlock_sta;
seq_number = mvmsta->tid_data[tid].seq_number;
@ -1134,7 +1144,7 @@ static int iwl_mvm_tx_mpdu(struct iwl_mvm *mvm, struct sk_buff *skb,
WARN_ON_ONCE(info->flags & IEEE80211_TX_CTL_SEND_AFTER_DTIM);
if (WARN_ON_ONCE(txq_id == IWL_MVM_INVALID_QUEUE)) {
if (WARN_ONCE(txq_id == IWL_MVM_INVALID_QUEUE, "Invalid TXQ id")) {
iwl_trans_free_tx_cmd(mvm->trans, dev_cmd);
spin_unlock(&mvmsta->lock);
return 0;
@ -1184,6 +1194,7 @@ drop_unlock_sta:
iwl_trans_free_tx_cmd(mvm->trans, dev_cmd);
spin_unlock(&mvmsta->lock);
drop:
IWL_DEBUG_TX(mvm, "TX to [%d|%d] dropped\n", mvmsta->sta_id, tid);
return -1;
}

View File

@ -517,6 +517,8 @@ static const struct pci_device_id iwl_hw_card_ids[] = {
{IWL_PCI_DEVICE(0x02F0, 0x0034, iwl9560_2ac_cfg_soc)},
{IWL_PCI_DEVICE(0x02F0, 0x0038, iwl9560_2ac_160_cfg_soc)},
{IWL_PCI_DEVICE(0x02F0, 0x003C, iwl9560_2ac_160_cfg_soc)},
{IWL_PCI_DEVICE(0x02F0, 0x0040, iwl_ax101_cfg_qu_hr)},
{IWL_PCI_DEVICE(0x02F0, 0x0044, iwl_ax101_cfg_qu_hr)},
{IWL_PCI_DEVICE(0x02F0, 0x0060, iwl9461_2ac_cfg_soc)},
{IWL_PCI_DEVICE(0x02F0, 0x0064, iwl9461_2ac_cfg_soc)},
{IWL_PCI_DEVICE(0x02F0, 0x00A0, iwl9462_2ac_cfg_soc)},
@ -525,6 +527,7 @@ static const struct pci_device_id iwl_hw_card_ids[] = {
{IWL_PCI_DEVICE(0x02F0, 0x0234, iwl9560_2ac_cfg_soc)},
{IWL_PCI_DEVICE(0x02F0, 0x0238, iwl9560_2ac_cfg_soc)},
{IWL_PCI_DEVICE(0x02F0, 0x023C, iwl9560_2ac_cfg_soc)},
{IWL_PCI_DEVICE(0x02F0, 0x0244, iwl_ax101_cfg_qu_hr)},
{IWL_PCI_DEVICE(0x02F0, 0x0260, iwl9461_2ac_cfg_soc)},
{IWL_PCI_DEVICE(0x02F0, 0x0264, iwl9461_2ac_cfg_soc)},
{IWL_PCI_DEVICE(0x02F0, 0x02A0, iwl9462_2ac_cfg_soc)},
@ -542,6 +545,8 @@ static const struct pci_device_id iwl_hw_card_ids[] = {
{IWL_PCI_DEVICE(0x06F0, 0x0034, iwl9560_2ac_cfg_soc)},
{IWL_PCI_DEVICE(0x06F0, 0x0038, iwl9560_2ac_160_cfg_soc)},
{IWL_PCI_DEVICE(0x06F0, 0x003C, iwl9560_2ac_160_cfg_soc)},
{IWL_PCI_DEVICE(0x06F0, 0x0040, iwl_ax101_cfg_qu_hr)},
{IWL_PCI_DEVICE(0x06F0, 0x0044, iwl_ax101_cfg_qu_hr)},
{IWL_PCI_DEVICE(0x06F0, 0x0060, iwl9461_2ac_cfg_soc)},
{IWL_PCI_DEVICE(0x06F0, 0x0064, iwl9461_2ac_cfg_soc)},
{IWL_PCI_DEVICE(0x06F0, 0x00A0, iwl9462_2ac_cfg_soc)},
@ -550,6 +555,7 @@ static const struct pci_device_id iwl_hw_card_ids[] = {
{IWL_PCI_DEVICE(0x06F0, 0x0234, iwl9560_2ac_cfg_soc)},
{IWL_PCI_DEVICE(0x06F0, 0x0238, iwl9560_2ac_cfg_soc)},
{IWL_PCI_DEVICE(0x06F0, 0x023C, iwl9560_2ac_cfg_soc)},
{IWL_PCI_DEVICE(0x06F0, 0x0244, iwl_ax101_cfg_qu_hr)},
{IWL_PCI_DEVICE(0x06F0, 0x0260, iwl9461_2ac_cfg_soc)},
{IWL_PCI_DEVICE(0x06F0, 0x0264, iwl9461_2ac_cfg_soc)},
{IWL_PCI_DEVICE(0x06F0, 0x02A0, iwl9462_2ac_cfg_soc)},
@ -597,6 +603,7 @@ static const struct pci_device_id iwl_hw_card_ids[] = {
{IWL_PCI_DEVICE(0x2526, 0x2030, iwl9560_2ac_160_cfg_soc)},
{IWL_PCI_DEVICE(0x2526, 0x2034, iwl9560_2ac_160_cfg_soc)},
{IWL_PCI_DEVICE(0x2526, 0x4010, iwl9260_2ac_160_cfg)},
{IWL_PCI_DEVICE(0x2526, 0x4018, iwl9260_2ac_160_cfg)},
{IWL_PCI_DEVICE(0x2526, 0x401C, iwl9260_2ac_160_cfg)},
{IWL_PCI_DEVICE(0x2526, 0x4030, iwl9560_2ac_160_cfg)},
{IWL_PCI_DEVICE(0x2526, 0x4034, iwl9560_2ac_160_cfg_soc)},
@ -614,6 +621,7 @@ static const struct pci_device_id iwl_hw_card_ids[] = {
{IWL_PCI_DEVICE(0x2720, 0x0034, iwl9560_2ac_160_cfg)},
{IWL_PCI_DEVICE(0x2720, 0x0038, iwl9560_2ac_160_cfg)},
{IWL_PCI_DEVICE(0x2720, 0x003C, iwl9560_2ac_160_cfg)},
{IWL_PCI_DEVICE(0x2720, 0x0044, iwl_ax101_cfg_qu_hr)},
{IWL_PCI_DEVICE(0x2720, 0x0060, iwl9461_2ac_cfg_soc)},
{IWL_PCI_DEVICE(0x2720, 0x0064, iwl9461_2ac_cfg_soc)},
{IWL_PCI_DEVICE(0x2720, 0x00A0, iwl9462_2ac_cfg_soc)},
@ -622,6 +630,7 @@ static const struct pci_device_id iwl_hw_card_ids[] = {
{IWL_PCI_DEVICE(0x2720, 0x0234, iwl9560_2ac_cfg)},
{IWL_PCI_DEVICE(0x2720, 0x0238, iwl9560_2ac_cfg)},
{IWL_PCI_DEVICE(0x2720, 0x023C, iwl9560_2ac_cfg)},
{IWL_PCI_DEVICE(0x2720, 0x0244, iwl_ax101_cfg_qu_hr)},
{IWL_PCI_DEVICE(0x2720, 0x0260, iwl9461_2ac_cfg_soc)},
{IWL_PCI_DEVICE(0x2720, 0x0264, iwl9461_2ac_cfg_soc)},
{IWL_PCI_DEVICE(0x2720, 0x02A0, iwl9462_2ac_cfg_soc)},
@ -699,6 +708,7 @@ static const struct pci_device_id iwl_hw_card_ids[] = {
{IWL_PCI_DEVICE(0x34F0, 0x0034, iwl9560_2ac_cfg_qu_b0_jf_b0)},
{IWL_PCI_DEVICE(0x34F0, 0x0038, iwl9560_2ac_160_cfg_qu_b0_jf_b0)},
{IWL_PCI_DEVICE(0x34F0, 0x003C, iwl9560_2ac_160_cfg_qu_b0_jf_b0)},
{IWL_PCI_DEVICE(0x34F0, 0x0044, iwl_ax101_cfg_qu_hr)},
{IWL_PCI_DEVICE(0x34F0, 0x0060, iwl9461_2ac_cfg_qu_b0_jf_b0)},
{IWL_PCI_DEVICE(0x34F0, 0x0064, iwl9461_2ac_cfg_qu_b0_jf_b0)},
{IWL_PCI_DEVICE(0x34F0, 0x00A0, iwl9462_2ac_cfg_qu_b0_jf_b0)},
@ -707,6 +717,7 @@ static const struct pci_device_id iwl_hw_card_ids[] = {
{IWL_PCI_DEVICE(0x34F0, 0x0234, iwl9560_2ac_cfg_qu_b0_jf_b0)},
{IWL_PCI_DEVICE(0x34F0, 0x0238, iwl9560_2ac_cfg_qu_b0_jf_b0)},
{IWL_PCI_DEVICE(0x34F0, 0x023C, iwl9560_2ac_cfg_qu_b0_jf_b0)},
{IWL_PCI_DEVICE(0x34F0, 0x0244, iwl_ax101_cfg_qu_hr)},
{IWL_PCI_DEVICE(0x34F0, 0x0260, iwl9461_2ac_cfg_qu_b0_jf_b0)},
{IWL_PCI_DEVICE(0x34F0, 0x0264, iwl9461_2ac_cfg_qu_b0_jf_b0)},
{IWL_PCI_DEVICE(0x34F0, 0x02A0, iwl9462_2ac_cfg_qu_b0_jf_b0)},
@ -753,6 +764,7 @@ static const struct pci_device_id iwl_hw_card_ids[] = {
{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, 0x0044, iwl_ax101_cfg_qu_hr)},
{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)},
@ -761,6 +773,7 @@ static const struct pci_device_id iwl_hw_card_ids[] = {
{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, 0x0244, iwl_ax101_cfg_qu_hr)},
{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)},
@ -820,6 +833,7 @@ static const struct pci_device_id iwl_hw_card_ids[] = {
{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, 0x0044, iwl_ax101_cfg_qu_hr)},
{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)},
@ -828,6 +842,7 @@ static const struct pci_device_id iwl_hw_card_ids[] = {
{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, 0x0244, iwl_ax101_cfg_qu_hr)},
{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)},
@ -875,73 +890,75 @@ static const struct pci_device_id iwl_hw_card_ids[] = {
{IWL_PCI_DEVICE(0x2720, 0x0030, iwl9560_2ac_cfg_qnj_jf_b0)},
/* 22000 Series */
{IWL_PCI_DEVICE(0x02F0, 0x0070, iwl22560_2ax_cfg_hr)},
{IWL_PCI_DEVICE(0x02F0, 0x0074, iwl22560_2ax_cfg_hr)},
{IWL_PCI_DEVICE(0x02F0, 0x0078, iwl22560_2ax_cfg_hr)},
{IWL_PCI_DEVICE(0x02F0, 0x007C, iwl22560_2ax_cfg_hr)},
{IWL_PCI_DEVICE(0x02F0, 0x0310, iwl22560_2ax_cfg_hr)},
{IWL_PCI_DEVICE(0x02F0, 0x0070, iwl_ax101_cfg_qu_hr)},
{IWL_PCI_DEVICE(0x02F0, 0x0074, iwl_ax101_cfg_qu_hr)},
{IWL_PCI_DEVICE(0x02F0, 0x0078, iwl_ax101_cfg_qu_hr)},
{IWL_PCI_DEVICE(0x02F0, 0x007C, iwl_ax101_cfg_qu_hr)},
{IWL_PCI_DEVICE(0x02F0, 0x0310, iwl_ax101_cfg_qu_hr)},
{IWL_PCI_DEVICE(0x02F0, 0x1651, killer1650s_2ax_cfg_qu_b0_hr_b0)},
{IWL_PCI_DEVICE(0x02F0, 0x1652, killer1650i_2ax_cfg_qu_b0_hr_b0)},
{IWL_PCI_DEVICE(0x02F0, 0x4070, iwl22560_2ax_cfg_hr)},
{IWL_PCI_DEVICE(0x06F0, 0x0070, iwl22560_2ax_cfg_hr)},
{IWL_PCI_DEVICE(0x06F0, 0x0074, iwl22560_2ax_cfg_hr)},
{IWL_PCI_DEVICE(0x06F0, 0x0078, iwl22560_2ax_cfg_hr)},
{IWL_PCI_DEVICE(0x06F0, 0x007C, iwl22560_2ax_cfg_hr)},
{IWL_PCI_DEVICE(0x06F0, 0x0310, iwl22560_2ax_cfg_hr)},
{IWL_PCI_DEVICE(0x02F0, 0x4070, iwl_ax101_cfg_qu_hr)},
{IWL_PCI_DEVICE(0x06F0, 0x0070, iwl_ax101_cfg_qu_hr)},
{IWL_PCI_DEVICE(0x06F0, 0x0074, iwl_ax101_cfg_qu_hr)},
{IWL_PCI_DEVICE(0x06F0, 0x0078, iwl_ax101_cfg_qu_hr)},
{IWL_PCI_DEVICE(0x06F0, 0x007C, iwl_ax101_cfg_qu_hr)},
{IWL_PCI_DEVICE(0x06F0, 0x0310, iwl_ax101_cfg_qu_hr)},
{IWL_PCI_DEVICE(0x06F0, 0x1651, killer1650s_2ax_cfg_qu_b0_hr_b0)},
{IWL_PCI_DEVICE(0x06F0, 0x1652, killer1650i_2ax_cfg_qu_b0_hr_b0)},
{IWL_PCI_DEVICE(0x06F0, 0x4070, iwl22560_2ax_cfg_hr)},
{IWL_PCI_DEVICE(0x2720, 0x0000, iwl22560_2ax_cfg_hr)},
{IWL_PCI_DEVICE(0x2720, 0x0040, iwl22560_2ax_cfg_hr)},
{IWL_PCI_DEVICE(0x06F0, 0x4070, iwl_ax101_cfg_qu_hr)},
{IWL_PCI_DEVICE(0x2720, 0x0000, iwl_ax101_cfg_qu_hr)},
{IWL_PCI_DEVICE(0x2720, 0x0040, iwl_ax101_cfg_qu_hr)},
{IWL_PCI_DEVICE(0x2720, 0x0070, iwl22000_2ac_cfg_hr_cdb)},
{IWL_PCI_DEVICE(0x2720, 0x0074, iwl22560_2ax_cfg_hr)},
{IWL_PCI_DEVICE(0x2720, 0x0078, iwl22560_2ax_cfg_hr)},
{IWL_PCI_DEVICE(0x2720, 0x007C, iwl22560_2ax_cfg_hr)},
{IWL_PCI_DEVICE(0x2720, 0x0074, iwl_ax101_cfg_qu_hr)},
{IWL_PCI_DEVICE(0x2720, 0x0078, iwl_ax101_cfg_qu_hr)},
{IWL_PCI_DEVICE(0x2720, 0x007C, iwl_ax101_cfg_qu_hr)},
{IWL_PCI_DEVICE(0x2720, 0x0090, iwl22000_2ac_cfg_hr_cdb)},
{IWL_PCI_DEVICE(0x2720, 0x0310, iwl22000_2ac_cfg_hr_cdb)},
{IWL_PCI_DEVICE(0x2720, 0x0A10, iwl22000_2ac_cfg_hr_cdb)},
{IWL_PCI_DEVICE(0x2720, 0x1080, iwl22560_2ax_cfg_hr)},
{IWL_PCI_DEVICE(0x2720, 0x1080, iwl_ax101_cfg_qu_hr)},
{IWL_PCI_DEVICE(0x2720, 0x1651, killer1650s_2ax_cfg_qu_b0_hr_b0)},
{IWL_PCI_DEVICE(0x2720, 0x1652, killer1650i_2ax_cfg_qu_b0_hr_b0)},
{IWL_PCI_DEVICE(0x2720, 0x4070, iwl22560_2ax_cfg_hr)},
{IWL_PCI_DEVICE(0x34F0, 0x0040, iwl22560_2ax_cfg_hr)},
{IWL_PCI_DEVICE(0x34F0, 0x0070, iwl22560_2ax_cfg_hr)},
{IWL_PCI_DEVICE(0x34F0, 0x0074, iwl22560_2ax_cfg_hr)},
{IWL_PCI_DEVICE(0x34F0, 0x0078, iwl22560_2ax_cfg_hr)},
{IWL_PCI_DEVICE(0x34F0, 0x007C, iwl22560_2ax_cfg_hr)},
{IWL_PCI_DEVICE(0x34F0, 0x0310, iwl22560_2ax_cfg_hr)},
{IWL_PCI_DEVICE(0x2720, 0x4070, iwl_ax101_cfg_qu_hr)},
{IWL_PCI_DEVICE(0x34F0, 0x0040, iwl_ax101_cfg_qu_hr)},
{IWL_PCI_DEVICE(0x34F0, 0x0070, iwl_ax101_cfg_qu_hr)},
{IWL_PCI_DEVICE(0x34F0, 0x0074, iwl_ax101_cfg_qu_hr)},
{IWL_PCI_DEVICE(0x34F0, 0x0078, iwl_ax101_cfg_qu_hr)},
{IWL_PCI_DEVICE(0x34F0, 0x007C, iwl_ax101_cfg_qu_hr)},
{IWL_PCI_DEVICE(0x34F0, 0x0310, iwl_ax101_cfg_qu_hr)},
{IWL_PCI_DEVICE(0x34F0, 0x1651, killer1650s_2ax_cfg_qu_b0_hr_b0)},
{IWL_PCI_DEVICE(0x34F0, 0x1652, killer1650i_2ax_cfg_qu_b0_hr_b0)},
{IWL_PCI_DEVICE(0x34F0, 0x4070, iwl22560_2ax_cfg_hr)},
{IWL_PCI_DEVICE(0x34F0, 0x4070, iwl_ax101_cfg_qu_hr)},
{IWL_PCI_DEVICE(0x40C0, 0x0000, iwl22560_2ax_cfg_su_cdb)},
{IWL_PCI_DEVICE(0x40C0, 0x0010, iwl22560_2ax_cfg_su_cdb)},
{IWL_PCI_DEVICE(0x40c0, 0x0090, iwl22560_2ax_cfg_su_cdb)},
{IWL_PCI_DEVICE(0x40C0, 0x0310, iwl22560_2ax_cfg_su_cdb)},
{IWL_PCI_DEVICE(0x40C0, 0x0A10, iwl22560_2ax_cfg_su_cdb)},
{IWL_PCI_DEVICE(0x43F0, 0x0040, iwl22560_2ax_cfg_hr)},
{IWL_PCI_DEVICE(0x43F0, 0x0070, iwl22560_2ax_cfg_hr)},
{IWL_PCI_DEVICE(0x43F0, 0x0074, iwl22560_2ax_cfg_hr)},
{IWL_PCI_DEVICE(0x43F0, 0x0078, iwl22560_2ax_cfg_hr)},
{IWL_PCI_DEVICE(0x43F0, 0x007C, iwl22560_2ax_cfg_hr)},
{IWL_PCI_DEVICE(0x43F0, 0x0040, iwl_ax101_cfg_qu_hr)},
{IWL_PCI_DEVICE(0x43F0, 0x0070, iwl_ax101_cfg_qu_hr)},
{IWL_PCI_DEVICE(0x43F0, 0x0074, iwl_ax101_cfg_qu_hr)},
{IWL_PCI_DEVICE(0x43F0, 0x0078, iwl_ax101_cfg_qu_hr)},
{IWL_PCI_DEVICE(0x43F0, 0x007C, iwl_ax101_cfg_qu_hr)},
{IWL_PCI_DEVICE(0x43F0, 0x1651, killer1650s_2ax_cfg_qu_b0_hr_b0)},
{IWL_PCI_DEVICE(0x43F0, 0x1652, killer1650i_2ax_cfg_qu_b0_hr_b0)},
{IWL_PCI_DEVICE(0x43F0, 0x4070, iwl22560_2ax_cfg_hr)},
{IWL_PCI_DEVICE(0xA0F0, 0x0000, iwl22560_2ax_cfg_hr)},
{IWL_PCI_DEVICE(0xA0F0, 0x0040, iwl22560_2ax_cfg_hr)},
{IWL_PCI_DEVICE(0xA0F0, 0x0070, iwl22560_2ax_cfg_hr)},
{IWL_PCI_DEVICE(0xA0F0, 0x0074, iwl22560_2ax_cfg_hr)},
{IWL_PCI_DEVICE(0xA0F0, 0x0078, iwl22560_2ax_cfg_hr)},
{IWL_PCI_DEVICE(0xA0F0, 0x007C, iwl22560_2ax_cfg_hr)},
{IWL_PCI_DEVICE(0xA0F0, 0x00B0, iwl22560_2ax_cfg_hr)},
{IWL_PCI_DEVICE(0xA0F0, 0x0A10, iwl22560_2ax_cfg_hr)},
{IWL_PCI_DEVICE(0x43F0, 0x4070, iwl_ax101_cfg_qu_hr)},
{IWL_PCI_DEVICE(0xA0F0, 0x0000, iwl_ax101_cfg_qu_hr)},
{IWL_PCI_DEVICE(0xA0F0, 0x0040, iwl_ax101_cfg_qu_hr)},
{IWL_PCI_DEVICE(0xA0F0, 0x0070, iwl_ax101_cfg_qu_hr)},
{IWL_PCI_DEVICE(0xA0F0, 0x0074, iwl_ax101_cfg_qu_hr)},
{IWL_PCI_DEVICE(0xA0F0, 0x0078, iwl_ax101_cfg_qu_hr)},
{IWL_PCI_DEVICE(0xA0F0, 0x007C, iwl_ax101_cfg_qu_hr)},
{IWL_PCI_DEVICE(0xA0F0, 0x00B0, iwl_ax101_cfg_qu_hr)},
{IWL_PCI_DEVICE(0xA0F0, 0x0A10, iwl_ax101_cfg_qu_hr)},
{IWL_PCI_DEVICE(0xA0F0, 0x1651, killer1650s_2ax_cfg_qu_b0_hr_b0)},
{IWL_PCI_DEVICE(0xA0F0, 0x1652, killer1650i_2ax_cfg_qu_b0_hr_b0)},
{IWL_PCI_DEVICE(0xA0F0, 0x4070, iwl22560_2ax_cfg_hr)},
{IWL_PCI_DEVICE(0xA0F0, 0x4070, iwl_ax101_cfg_qu_hr)},
{IWL_PCI_DEVICE(0x2723, 0x0080, iwl22260_2ax_cfg)},
{IWL_PCI_DEVICE(0x2723, 0x0084, iwl22260_2ax_cfg)},
{IWL_PCI_DEVICE(0x2723, 0x0088, iwl22260_2ax_cfg)},
{IWL_PCI_DEVICE(0x2723, 0x008C, iwl22260_2ax_cfg)},
{IWL_PCI_DEVICE(0x2723, 0x1653, killer1650w_2ax_cfg)},
{IWL_PCI_DEVICE(0x2723, 0x1654, killer1650x_2ax_cfg)},
{IWL_PCI_DEVICE(0x2723, 0x4080, iwl22260_2ax_cfg)},
{IWL_PCI_DEVICE(0x2723, 0x4088, iwl22260_2ax_cfg)},

View File

@ -8,7 +8,7 @@
* Copyright(c) 2003 - 2015 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) 2003 - 2015 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
@ -526,6 +526,8 @@ struct cont_rec {
* @fh_mask: current unmasked fh causes
* @hw_mask: current unmasked hw causes
* @in_rescan: true if we have triggered a device rescan
* @base_rb_stts: base virtual address of receive buffer status for all queues
* @base_rb_stts_dma: base physical address of receive buffer status
*/
struct iwl_trans_pcie {
struct iwl_rxq *rxq;
@ -617,6 +619,9 @@ struct iwl_trans_pcie {
cpumask_t affinity_mask[IWL_MAX_RX_HW_QUEUES];
u16 tx_cmd_queue_size;
bool in_rescan;
void *base_rb_stts;
dma_addr_t base_rb_stts_dma;
};
static inline struct iwl_trans_pcie *

View File

@ -702,11 +702,6 @@ static void iwl_pcie_free_rxq_dma(struct iwl_trans *trans,
rxq->bd_dma = 0;
rxq->bd = NULL;
if (rxq->rb_stts)
dma_free_coherent(trans->dev,
use_rx_td ? sizeof(__le16) :
sizeof(struct iwl_rb_status),
rxq->rb_stts, rxq->rb_stts_dma);
rxq->rb_stts_dma = 0;
rxq->rb_stts = NULL;
@ -743,6 +738,8 @@ static int iwl_pcie_alloc_rxq_dma(struct iwl_trans *trans,
int free_size;
bool use_rx_td = (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)
@ -770,12 +767,9 @@ static int iwl_pcie_alloc_rxq_dma(struct iwl_trans *trans,
goto err;
}
/* Allocate the driver's pointer to receive buffer status */
rxq->rb_stts = dma_alloc_coherent(dev,
use_rx_td ? sizeof(__le16) : sizeof(struct iwl_rb_status),
&rxq->rb_stts_dma, GFP_KERNEL);
if (!rxq->rb_stts)
goto err;
rxq->rb_stts = trans_pcie->base_rb_stts + rxq->id * rb_stts_size;
rxq->rb_stts_dma =
trans_pcie->base_rb_stts_dma + rxq->id * rb_stts_size;
if (!use_rx_td)
return 0;
@ -805,7 +799,6 @@ err:
iwl_pcie_free_rxq_dma(trans, rxq);
}
kfree(trans_pcie->rxq);
return -ENOMEM;
}
@ -815,6 +808,9 @@ 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 >=
IWL_DEVICE_FAMILY_22560 ?
sizeof(__le16) : sizeof(struct iwl_rb_status);
if (WARN_ON(trans_pcie->rxq))
return -EINVAL;
@ -822,18 +818,46 @@ int iwl_pcie_rx_alloc(struct iwl_trans *trans)
trans_pcie->rxq = kcalloc(trans->num_rx_queues, sizeof(struct iwl_rxq),
GFP_KERNEL);
if (!trans_pcie->rxq)
return -EINVAL;
return -ENOMEM;
spin_lock_init(&rba->lock);
/*
* Allocate the driver's pointer to receive buffer status.
* Allocate for all queues continuously (HW requirement).
*/
trans_pcie->base_rb_stts =
dma_alloc_coherent(trans->dev,
rb_stts_size * trans->num_rx_queues,
&trans_pcie->base_rb_stts_dma,
GFP_KERNEL);
if (!trans_pcie->base_rb_stts) {
ret = -ENOMEM;
goto err;
}
for (i = 0; i < trans->num_rx_queues; i++) {
struct iwl_rxq *rxq = &trans_pcie->rxq[i];
rxq->id = i;
ret = iwl_pcie_alloc_rxq_dma(trans, rxq);
if (ret)
return ret;
goto err;
}
return 0;
err:
if (trans_pcie->base_rb_stts) {
dma_free_coherent(trans->dev,
rb_stts_size * trans->num_rx_queues,
trans_pcie->base_rb_stts,
trans_pcie->base_rb_stts_dma);
trans_pcie->base_rb_stts = NULL;
trans_pcie->base_rb_stts_dma = 0;
}
kfree(trans_pcie->rxq);
return ret;
}
static void iwl_pcie_rx_hw_init(struct iwl_trans *trans, struct iwl_rxq *rxq)
@ -1042,8 +1066,6 @@ int _iwl_pcie_rx_init(struct iwl_trans *trans)
for (i = 0; i < trans->num_rx_queues; i++) {
struct iwl_rxq *rxq = &trans_pcie->rxq[i];
rxq->id = i;
spin_lock(&rxq->lock);
/*
* Set read write pointer to reflect that we have processed
@ -1130,6 +1152,9 @@ 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 >=
IWL_DEVICE_FAMILY_22560 ?
sizeof(__le16) : sizeof(struct iwl_rb_status);
/*
* if rxq is NULL, it means that nothing has been allocated,
@ -1144,6 +1169,15 @@ void iwl_pcie_rx_free(struct iwl_trans *trans)
iwl_pcie_free_rbs_pool(trans);
if (trans_pcie->base_rb_stts) {
dma_free_coherent(trans->dev,
rb_stts_size * trans->num_rx_queues,
trans_pcie->base_rb_stts,
trans_pcie->base_rb_stts_dma);
trans_pcie->base_rb_stts = NULL;
trans_pcie->base_rb_stts_dma = 0;
}
for (i = 0; i < trans->num_rx_queues; i++) {
struct iwl_rxq *rxq = &trans_pcie->rxq[i];

View File

@ -3540,10 +3540,10 @@ struct iwl_trans *iwl_trans_pcie_alloc(struct pci_dev *pdev,
CSR_HW_RF_ID_TYPE_CHIP_ID(CSR_HW_RF_ID_TYPE_GF)) {
trans->cfg = &iwlax210_2ax_cfg_so_gf_a0;
}
} else if (cfg == &iwl22560_2ax_cfg_hr) {
} 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->cfg = &iwl22560_2ax_cfg_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;