wireless-drivers-next patches for v5.16

Fourth set of patches for v5.16. Mostly fixes this time, wcn36xx and
 iwlwifi have some new features but nothing really out of ordinary. We
 have one conflict with kspp tree.
 
 Conflicts:
 
 kspp tree has a conflict in drivers/net/wireless/intel/iwlwifi/fw/api/tx.h:
 
 https://lkml.kernel.org/r/20211028192934.01520d7e@canb.auug.org.au
 
 Major changes:
 
 ath11k
 
 * fix QCA6390 A-MSDU handling (CVE-2020-24588)
 
 wcn36xx
 
 * enable hardware scan offload for 5Ghz band
 
 * add missing 5GHz channels 136 and 144
 
 iwlwifi
 
 * support a new ACPI table revision
 
 * improvements in the device selection code
 
 * new hardware support
 
 * support for WiFi 6E enablement via BIOS
 
 * support firmware API version 67
 
 * support for 160MHz in ranging measurements
 -----BEGIN PGP SIGNATURE-----
 
 iQFJBAABCgAzFiEEiBjanGPFTz4PRfLobhckVSbrbZsFAmF7+wUVHGt2YWxvQGNv
 ZGVhdXJvcmEub3JnAAoJEG4XJFUm622bRGoH/0XrfEwzH4iR3j/xRPTBMJjBZO/Z
 ZN0PQ2L8402c7iG9M0psSFOdqFe8vtKzuuV367ifQzwmGFoQIzAckL9nCA1yFUBg
 EXF3nP0/mb8R0w6rzjkLUQ9EejLLeX35Kh6B1oLgglPdLvE+Yv6/Iqs1yOHwHZFF
 RBHqyBc9YcQBuhah4JPqIXr8tUCkRgWwK/VvCwhoGDWimBlH7LhgOHTFQhVJ+Z8b
 /RsLS2iIv4wGkiQX9cwilmX3QSz/jK0od1FXHW347v+nm96Fs3d2F1juAyhE6io2
 xN1qzEU4SQ90byxhCsBOvZC6JTpRJvw49XME76MrzaLP+FuZ8I2zdAe7wd8=
 =Y1xX
 -----END PGP SIGNATURE-----

Merge tag 'wireless-drivers-next-2021-10-29' of git://git.kernel.org/pub/scm/linux/kernel/git/kvalo/wireless-drivers-next

Kalle Valo says:

====================
wireless-drivers-next patches for v5.16

Fourth set of patches for v5.16. Mostly fixes this time, wcn36xx and
iwlwifi have some new features but nothing really out of ordinary.
We have one conflict with kspp tree.

Major changes:

ath11k
 * fix QCA6390 A-MSDU handling (CVE-2020-24588)

wcn36xx
 * enable hardware scan offload for 5Ghz band
 * add missing 5GHz channels 136 and 144

iwlwifi
 * support a new ACPI table revision
 * improvements in the device selection code
 * new hardware support
 * support for WiFi 6E enablement via BIOS
 * support firmware API version 67
 * support for 160MHz in ranging measurements

====================

Link: https://lore.kernel.org/r/20211029134707.DE2B0C4360D@smtp.codeaurora.org
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
This commit is contained in:
Jakub Kicinski 2021-10-29 08:58:39 -07:00
Родитель 7444d706be 2619f904b2
Коммит 28131d896d
146 изменённых файлов: 3621 добавлений и 1410 удалений

Просмотреть файл

@ -2690,9 +2690,16 @@ static int ath10k_core_copy_target_iram(struct ath10k *ar)
int i, ret;
u32 len, remaining_len;
hw_mem = ath10k_coredump_get_mem_layout(ar);
/* copy target iram feature must work also when
* ATH10K_FW_CRASH_DUMP_RAM_DATA is disabled, so
* _ath10k_coredump_get_mem_layout() to accomplist that
*/
hw_mem = _ath10k_coredump_get_mem_layout(ar);
if (!hw_mem)
return -ENOMEM;
/* if CONFIG_DEV_COREDUMP is disabled we get NULL, then
* just silently disable the feature by doing nothing
*/
return 0;
for (i = 0; i < hw_mem->region_table.size; i++) {
tmp = &hw_mem->region_table.regions[i];

Просмотреть файл

@ -1447,11 +1447,17 @@ static u32 ath10k_coredump_get_ramdump_size(struct ath10k *ar)
const struct ath10k_hw_mem_layout *ath10k_coredump_get_mem_layout(struct ath10k *ar)
{
int i;
if (!test_bit(ATH10K_FW_CRASH_DUMP_RAM_DATA, &ath10k_coredump_mask))
return NULL;
return _ath10k_coredump_get_mem_layout(ar);
}
EXPORT_SYMBOL(ath10k_coredump_get_mem_layout);
const struct ath10k_hw_mem_layout *_ath10k_coredump_get_mem_layout(struct ath10k *ar)
{
int i;
if (WARN_ON(ar->target_version == 0))
return NULL;
@ -1464,7 +1470,6 @@ const struct ath10k_hw_mem_layout *ath10k_coredump_get_mem_layout(struct ath10k
return NULL;
}
EXPORT_SYMBOL(ath10k_coredump_get_mem_layout);
struct ath10k_fw_crash_data *ath10k_coredump_new(struct ath10k *ar)
{

Просмотреть файл

@ -176,6 +176,7 @@ int ath10k_coredump_register(struct ath10k *ar);
void ath10k_coredump_unregister(struct ath10k *ar);
void ath10k_coredump_destroy(struct ath10k *ar);
const struct ath10k_hw_mem_layout *_ath10k_coredump_get_mem_layout(struct ath10k *ar);
const struct ath10k_hw_mem_layout *ath10k_coredump_get_mem_layout(struct ath10k *ar);
#else /* CONFIG_DEV_COREDUMP */
@ -214,6 +215,12 @@ ath10k_coredump_get_mem_layout(struct ath10k *ar)
return NULL;
}
static inline const struct ath10k_hw_mem_layout *
_ath10k_coredump_get_mem_layout(struct ath10k *ar)
{
return NULL;
}
#endif /* CONFIG_DEV_COREDUMP */
#endif /* _COREDUMP_H_ */

Просмотреть файл

@ -5583,7 +5583,15 @@ static int ath10k_add_interface(struct ieee80211_hw *hw,
if (ar->bus_param.dev_type == ATH10K_DEV_TYPE_HL) {
arvif->beacon_buf = kmalloc(IEEE80211_MAX_FRAME_LEN,
GFP_KERNEL);
arvif->beacon_paddr = (dma_addr_t)arvif->beacon_buf;
/* Using a kernel pointer in place of a dma_addr_t
* token can lead to undefined behavior if that
* makes it into cache management functions. Use a
* known-invalid address token instead, which
* avoids the warning and makes it easier to catch
* bugs if it does end up getting used.
*/
arvif->beacon_paddr = DMA_MAPPING_ERROR;
} else {
arvif->beacon_buf =
dma_alloc_coherent(ar->dev,

Просмотреть файл

@ -525,7 +525,7 @@ static int ath10k_usb_submit_ctrl_in(struct ath10k *ar,
req,
USB_DIR_IN | USB_TYPE_VENDOR |
USB_RECIP_DEVICE, value, index, buf,
size, 2 * HZ);
size, 2000);
if (ret < 0) {
ath10k_warn(ar, "Failed to read usb control message: %d\n",
@ -853,6 +853,11 @@ static int ath10k_usb_setup_pipe_resources(struct ath10k *ar,
le16_to_cpu(endpoint->wMaxPacketSize),
endpoint->bInterval);
}
/* Ignore broken descriptors. */
if (usb_endpoint_maxp(endpoint) == 0)
continue;
urbcount = 0;
pipe_num =

Просмотреть файл

@ -81,6 +81,7 @@ static const struct ath11k_hw_params ath11k_hw_params[] = {
.hal_desc_sz = sizeof(struct hal_rx_desc_ipq8074),
.fix_l1ss = true,
.max_tx_ring = DP_TCL_NUM_RING_MAX,
.hal_params = &ath11k_hw_hal_params_ipq8074,
},
{
.hw_rev = ATH11K_HW_IPQ6018_HW10,
@ -129,6 +130,7 @@ static const struct ath11k_hw_params ath11k_hw_params[] = {
.hal_desc_sz = sizeof(struct hal_rx_desc_ipq8074),
.fix_l1ss = true,
.max_tx_ring = DP_TCL_NUM_RING_MAX,
.hal_params = &ath11k_hw_hal_params_ipq8074,
},
{
.name = "qca6390 hw2.0",
@ -176,6 +178,7 @@ static const struct ath11k_hw_params ath11k_hw_params[] = {
.hal_desc_sz = sizeof(struct hal_rx_desc_ipq8074),
.fix_l1ss = true,
.max_tx_ring = DP_TCL_NUM_RING_MAX_QCA6390,
.hal_params = &ath11k_hw_hal_params_qca6390,
},
{
.name = "qcn9074 hw1.0",
@ -223,6 +226,7 @@ static const struct ath11k_hw_params ath11k_hw_params[] = {
.hal_desc_sz = sizeof(struct hal_rx_desc_qcn9074),
.fix_l1ss = true,
.max_tx_ring = DP_TCL_NUM_RING_MAX,
.hal_params = &ath11k_hw_hal_params_ipq8074,
},
{
.name = "wcn6855 hw2.0",
@ -270,6 +274,7 @@ static const struct ath11k_hw_params ath11k_hw_params[] = {
.hal_desc_sz = sizeof(struct hal_rx_desc_wcn6855),
.fix_l1ss = false,
.max_tx_ring = DP_TCL_NUM_RING_MAX_QCA6390,
.hal_params = &ath11k_hw_hal_params_qca6390,
},
};

Просмотреть файл

@ -739,6 +739,7 @@ int ath11k_dp_service_srng(struct ath11k_base *ab,
int budget)
{
struct napi_struct *napi = &irq_grp->napi;
const struct ath11k_hw_hal_params *hal_params;
int grp_id = irq_grp->grp_id;
int work_done = 0;
int i = 0, j;
@ -821,8 +822,9 @@ int ath11k_dp_service_srng(struct ath11k_base *ab,
struct ath11k_pdev_dp *dp = &ar->dp;
struct dp_rxdma_ring *rx_ring = &dp->rx_refill_buf_ring;
hal_params = ab->hw_params.hal_params;
ath11k_dp_rxbufs_replenish(ab, id, rx_ring, 0,
HAL_RX_BUF_RBM_SW3_BM);
hal_params->rx_buf_rbm);
}
}
}

Просмотреть файл

@ -499,7 +499,7 @@ static int ath11k_dp_rxdma_ring_buf_setup(struct ath11k *ar,
rx_ring->bufs_max = num_entries;
ath11k_dp_rxbufs_replenish(ar->ab, dp->mac_id, rx_ring, num_entries,
HAL_RX_BUF_RBM_SW3_BM);
ar->ab->hw_params.hal_params->rx_buf_rbm);
return 0;
}
@ -2756,7 +2756,7 @@ try_again:
rx_ring = &ar->dp.rx_refill_buf_ring;
ath11k_dp_rxbufs_replenish(ab, i, rx_ring, num_buffs_reaped[i],
HAL_RX_BUF_RBM_SW3_BM);
ab->hw_params.hal_params->rx_buf_rbm);
}
ath11k_dp_rx_process_received_packets(ab, napi, &msdu_list,
@ -2949,6 +2949,7 @@ static int ath11k_dp_rx_reap_mon_status_ring(struct ath11k_base *ab, int mac_id,
int *budget, struct sk_buff_head *skb_list)
{
struct ath11k *ar;
const struct ath11k_hw_hal_params *hal_params;
struct ath11k_pdev_dp *dp;
struct dp_rxdma_ring *rx_ring;
struct hal_srng *srng;
@ -3019,8 +3020,9 @@ move_next:
&buf_id);
if (!skb) {
hal_params = ab->hw_params.hal_params;
ath11k_hal_rx_buf_addr_info_set(rx_mon_status_desc, 0, 0,
HAL_RX_BUF_RBM_SW3_BM);
hal_params->rx_buf_rbm);
num_buffs_reaped++;
break;
}
@ -3030,7 +3032,8 @@ move_next:
FIELD_PREP(DP_RXDMA_BUF_COOKIE_BUF_ID, buf_id);
ath11k_hal_rx_buf_addr_info_set(rx_mon_status_desc, rxcb->paddr,
cookie, HAL_RX_BUF_RBM_SW3_BM);
cookie,
ab->hw_params.hal_params->rx_buf_rbm);
ath11k_hal_srng_src_get_next_entry(ab, srng);
num_buffs_reaped++;
}
@ -3419,7 +3422,8 @@ static int ath11k_dp_rx_h_defrag_reo_reinject(struct ath11k *ar, struct dp_rx_ti
cookie = FIELD_PREP(DP_RXDMA_BUF_COOKIE_PDEV_ID, dp->mac_id) |
FIELD_PREP(DP_RXDMA_BUF_COOKIE_BUF_ID, buf_id);
ath11k_hal_rx_buf_addr_info_set(msdu0, paddr, cookie, HAL_RX_BUF_RBM_SW3_BM);
ath11k_hal_rx_buf_addr_info_set(msdu0, paddr, cookie,
ab->hw_params.hal_params->rx_buf_rbm);
/* Fill mpdu details into reo entrace ring */
srng = &ab->hal.srng_list[ab->dp.reo_reinject_ring.ring_id];
@ -3796,7 +3800,7 @@ int ath11k_dp_process_rx_err(struct ath11k_base *ab, struct napi_struct *napi,
ath11k_hal_rx_msdu_link_info_get(link_desc_va, &num_msdus, msdu_cookies,
&rbm);
if (rbm != HAL_RX_BUF_RBM_WBM_IDLE_DESC_LIST &&
rbm != HAL_RX_BUF_RBM_SW3_BM) {
rbm != ab->hw_params.hal_params->rx_buf_rbm) {
ab->soc_stats.invalid_rbm++;
ath11k_warn(ab, "invalid return buffer manager %d\n", rbm);
ath11k_dp_rx_link_desc_return(ab, desc,
@ -3852,7 +3856,7 @@ exit:
rx_ring = &ar->dp.rx_refill_buf_ring;
ath11k_dp_rxbufs_replenish(ab, i, rx_ring, n_bufs_reaped[i],
HAL_RX_BUF_RBM_SW3_BM);
ab->hw_params.hal_params->rx_buf_rbm);
}
return tot_n_bufs_reaped;
@ -4148,7 +4152,7 @@ int ath11k_dp_rx_process_wbm_err(struct ath11k_base *ab,
rx_ring = &ar->dp.rx_refill_buf_ring;
ath11k_dp_rxbufs_replenish(ab, i, rx_ring, num_buffs_reaped[i],
HAL_RX_BUF_RBM_SW3_BM);
ab->hw_params.hal_params->rx_buf_rbm);
}
rcu_read_lock();
@ -4257,7 +4261,7 @@ int ath11k_dp_process_rxdma_err(struct ath11k_base *ab, int mac_id, int budget)
if (num_buf_freed)
ath11k_dp_rxbufs_replenish(ab, mac_id, rx_ring, num_buf_freed,
HAL_RX_BUF_RBM_SW3_BM);
ab->hw_params.hal_params->rx_buf_rbm);
return budget - quota;
}
@ -4976,6 +4980,7 @@ static void ath11k_dp_rx_mon_dest_process(struct ath11k *ar, int mac_id,
{
struct ath11k_pdev_dp *dp = &ar->dp;
struct ath11k_mon_data *pmon = (struct ath11k_mon_data *)&dp->mon_data;
const struct ath11k_hw_hal_params *hal_params;
void *ring_entry;
void *mon_dst_srng;
u32 ppdu_id;
@ -5039,16 +5044,18 @@ static void ath11k_dp_rx_mon_dest_process(struct ath11k *ar, int mac_id,
if (rx_bufs_used) {
rx_mon_stats->dest_ppdu_done++;
hal_params = ar->ab->hw_params.hal_params;
if (ar->ab->hw_params.rxdma1_enable)
ath11k_dp_rxbufs_replenish(ar->ab, dp->mac_id,
&dp->rxdma_mon_buf_ring,
rx_bufs_used,
HAL_RX_BUF_RBM_SW3_BM);
hal_params->rx_buf_rbm);
else
ath11k_dp_rxbufs_replenish(ar->ab, dp->mac_id,
&dp->rx_refill_buf_ring,
rx_bufs_used,
HAL_RX_BUF_RBM_SW3_BM);
hal_params->rx_buf_rbm);
}
}

Просмотреть файл

@ -356,6 +356,7 @@ int ath11k_hal_wbm_desc_parse_err(struct ath11k_base *ab, void *desc,
struct hal_wbm_release_ring *wbm_desc = desc;
enum hal_wbm_rel_desc_type type;
enum hal_wbm_rel_src_module rel_src;
enum hal_rx_buf_return_buf_manager ret_buf_mgr;
type = FIELD_GET(HAL_WBM_RELEASE_INFO0_DESC_TYPE,
wbm_desc->info0);
@ -371,8 +372,9 @@ int ath11k_hal_wbm_desc_parse_err(struct ath11k_base *ab, void *desc,
rel_src != HAL_WBM_REL_SRC_MODULE_REO)
return -EINVAL;
if (FIELD_GET(BUFFER_ADDR_INFO1_RET_BUF_MGR,
wbm_desc->buf_addr_info.info1) != HAL_RX_BUF_RBM_SW3_BM) {
ret_buf_mgr = FIELD_GET(BUFFER_ADDR_INFO1_RET_BUF_MGR,
wbm_desc->buf_addr_info.info1);
if (ret_buf_mgr != ab->hw_params.hal_params->rx_buf_rbm) {
ab->soc_stats.invalid_rbm++;
return -EINVAL;
}

Просмотреть файл

@ -7,10 +7,11 @@
#include <linux/bitops.h>
#include <linux/bitfield.h>
#include "hw.h"
#include "core.h"
#include "ce.h"
#include "hif.h"
#include "hal.h"
#include "hw.h"
/* Map from pdev index to hw mac index */
static u8 ath11k_hw_ipq8074_mac_from_pdev_id(int pdev_idx)
@ -2124,3 +2125,11 @@ const struct ath11k_hw_regs wcn6855_regs = {
.pcie_qserdes_sysclk_en_sel = 0x01e0c0ac,
.pcie_pcs_osc_dtct_config_base = 0x01e0c628,
};
const struct ath11k_hw_hal_params ath11k_hw_hal_params_ipq8074 = {
.rx_buf_rbm = HAL_RX_BUF_RBM_SW3_BM,
};
const struct ath11k_hw_hal_params ath11k_hw_hal_params_qca6390 = {
.rx_buf_rbm = HAL_RX_BUF_RBM_SW1_BM,
};

Просмотреть файл

@ -6,6 +6,7 @@
#ifndef ATH11K_HW_H
#define ATH11K_HW_H
#include "hal.h"
#include "wmi.h"
/* Target configuration defines */
@ -119,6 +120,10 @@ struct ath11k_hw_ring_mask {
u8 host2rxdma[ATH11K_EXT_IRQ_GRP_NUM_MAX];
};
struct ath11k_hw_hal_params {
enum hal_rx_buf_return_buf_manager rx_buf_rbm;
};
struct ath11k_hw_params {
const char *name;
u16 hw_rev;
@ -170,6 +175,7 @@ struct ath11k_hw_params {
u32 hal_desc_sz;
bool fix_l1ss;
u8 max_tx_ring;
const struct ath11k_hw_hal_params *hal_params;
};
struct ath11k_hw_ops {
@ -223,6 +229,9 @@ extern const struct ath11k_hw_ring_mask ath11k_hw_ring_mask_ipq8074;
extern const struct ath11k_hw_ring_mask ath11k_hw_ring_mask_qca6390;
extern const struct ath11k_hw_ring_mask ath11k_hw_ring_mask_qcn9074;
extern const struct ath11k_hw_hal_params ath11k_hw_hal_params_ipq8074;
extern const struct ath11k_hw_hal_params ath11k_hw_hal_params_qca6390;
static inline
int ath11k_hw_get_mac_from_pdev_id(struct ath11k_hw_params *hw,
int pdev_idx)

Просмотреть файл

@ -340,6 +340,11 @@ static int ath6kl_usb_setup_pipe_resources(struct ath6kl_usb *ar_usb)
le16_to_cpu(endpoint->wMaxPacketSize),
endpoint->bInterval);
}
/* Ignore broken descriptors. */
if (usb_endpoint_maxp(endpoint) == 0)
continue;
urbcount = 0;
pipe_num =
@ -907,7 +912,7 @@ static int ath6kl_usb_submit_ctrl_in(struct ath6kl_usb *ar_usb,
req,
USB_DIR_IN | USB_TYPE_VENDOR |
USB_RECIP_DEVICE, value, index, buf,
size, 2 * HZ);
size, 2000);
if (ret < 0) {
ath6kl_warn("Failed to read usb control message: %d\n", ret);

Просмотреть файл

@ -403,8 +403,21 @@ static void reap_tx_dxes(struct wcn36xx *wcn, struct wcn36xx_dxe_ch *ch)
dma_unmap_single(wcn->dev, ctl->desc->src_addr_l,
ctl->skb->len, DMA_TO_DEVICE);
info = IEEE80211_SKB_CB(ctl->skb);
if (!(info->flags & IEEE80211_TX_CTL_REQ_TX_STATUS)) {
/* Keep frame until TX status comes */
if (info->flags & IEEE80211_TX_CTL_REQ_TX_STATUS) {
if (info->flags & IEEE80211_TX_CTL_NO_ACK) {
info->flags |= IEEE80211_TX_STAT_NOACK_TRANSMITTED;
ieee80211_tx_status_irqsafe(wcn->hw, ctl->skb);
} else {
/* Wait for the TX ack indication or timeout... */
spin_lock(&wcn->dxe_lock);
if (WARN_ON(wcn->tx_ack_skb))
ieee80211_free_txskb(wcn->hw, wcn->tx_ack_skb);
wcn->tx_ack_skb = ctl->skb; /* Tracking ref */
mod_timer(&wcn->tx_ack_timer, jiffies + HZ / 10);
spin_unlock(&wcn->dxe_lock);
}
/* do not free, ownership transferred to mac80211 status cb */
} else {
ieee80211_free_txskb(wcn->hw, ctl->skb);
}
@ -426,7 +439,6 @@ static irqreturn_t wcn36xx_irq_tx_complete(int irq, void *dev)
{
struct wcn36xx *wcn = (struct wcn36xx *)dev;
int int_src, int_reason;
bool transmitted = false;
wcn36xx_dxe_read_register(wcn, WCN36XX_DXE_INT_SRC_RAW_REG, &int_src);
@ -466,7 +478,6 @@ static irqreturn_t wcn36xx_irq_tx_complete(int irq, void *dev)
if (int_reason & (WCN36XX_CH_STAT_INT_DONE_MASK |
WCN36XX_CH_STAT_INT_ED_MASK)) {
reap_tx_dxes(wcn, &wcn->dxe_tx_h_ch);
transmitted = true;
}
}
@ -479,7 +490,6 @@ static irqreturn_t wcn36xx_irq_tx_complete(int irq, void *dev)
WCN36XX_DXE_0_INT_CLR,
WCN36XX_INT_MASK_CHAN_TX_L);
if (int_reason & WCN36XX_CH_STAT_INT_ERR_MASK ) {
wcn36xx_dxe_write_register(wcn,
WCN36XX_DXE_0_INT_ERR_CLR,
@ -507,26 +517,9 @@ static irqreturn_t wcn36xx_irq_tx_complete(int irq, void *dev)
if (int_reason & (WCN36XX_CH_STAT_INT_DONE_MASK |
WCN36XX_CH_STAT_INT_ED_MASK)) {
reap_tx_dxes(wcn, &wcn->dxe_tx_l_ch);
transmitted = true;
}
}
spin_lock(&wcn->dxe_lock);
if (wcn->tx_ack_skb && transmitted) {
struct ieee80211_tx_info *info = IEEE80211_SKB_CB(wcn->tx_ack_skb);
/* TX complete, no need to wait for 802.11 ack indication */
if (info->flags & IEEE80211_TX_CTL_REQ_TX_STATUS &&
info->flags & IEEE80211_TX_CTL_NO_ACK) {
info->flags |= IEEE80211_TX_STAT_NOACK_TRANSMITTED;
del_timer(&wcn->tx_ack_timer);
ieee80211_tx_status_irqsafe(wcn->hw, wcn->tx_ack_skb);
wcn->tx_ack_skb = NULL;
ieee80211_wake_queues(wcn->hw);
}
}
spin_unlock(&wcn->dxe_lock);
return IRQ_HANDLED;
}
@ -613,6 +606,10 @@ static int wcn36xx_rx_handle_packets(struct wcn36xx *wcn,
dxe = ctl->desc;
while (!(READ_ONCE(dxe->ctrl) & WCN36xx_DXE_CTRL_VLD)) {
/* do not read until we own DMA descriptor */
dma_rmb();
/* read/modify DMA descriptor */
skb = ctl->skb;
dma_addr = dxe->dst_addr_l;
ret = wcn36xx_dxe_fill_skb(wcn->dev, ctl, GFP_ATOMIC);
@ -623,9 +620,15 @@ static int wcn36xx_rx_handle_packets(struct wcn36xx *wcn,
dma_unmap_single(wcn->dev, dma_addr, WCN36XX_PKT_SIZE,
DMA_FROM_DEVICE);
wcn36xx_rx_skb(wcn, skb);
} /* else keep old skb not submitted and use it for rx DMA */
}
/* else keep old skb not submitted and reuse it for rx DMA
* (dropping the packet that it contained)
*/
/* flush descriptor changes before re-marking as valid */
dma_wmb();
dxe->ctrl = ctrl;
ctl = ctl->next;
dxe = ctl->desc;
}

Просмотреть файл

@ -359,6 +359,8 @@ enum wcn36xx_hal_host_msg_type {
WCN36XX_HAL_START_SCAN_OFFLOAD_RSP = 205,
WCN36XX_HAL_STOP_SCAN_OFFLOAD_REQ = 206,
WCN36XX_HAL_STOP_SCAN_OFFLOAD_RSP = 207,
WCN36XX_HAL_UPDATE_CHANNEL_LIST_REQ = 208,
WCN36XX_HAL_UPDATE_CHANNEL_LIST_RSP = 209,
WCN36XX_HAL_SCAN_OFFLOAD_IND = 210,
WCN36XX_HAL_AVOID_FREQ_RANGE_IND = 233,
@ -1353,6 +1355,36 @@ struct wcn36xx_hal_stop_scan_offload_rsp_msg {
u32 status;
} __packed;
#define WCN36XX_HAL_CHAN_REG1_MIN_PWR_MASK 0x000000ff
#define WCN36XX_HAL_CHAN_REG1_MAX_PWR_MASK 0x0000ff00
#define WCN36XX_HAL_CHAN_REG1_REG_PWR_MASK 0x00ff0000
#define WCN36XX_HAL_CHAN_REG1_CLASS_ID_MASK 0xff000000
#define WCN36XX_HAL_CHAN_REG2_ANT_GAIN_MASK 0x000000ff
#define WCN36XX_HAL_CHAN_INFO_FLAG_PASSIVE BIT(7)
#define WCN36XX_HAL_CHAN_INFO_FLAG_DFS BIT(10)
#define WCN36XX_HAL_CHAN_INFO_FLAG_HT BIT(11)
#define WCN36XX_HAL_CHAN_INFO_FLAG_VHT BIT(12)
#define WCN36XX_HAL_CHAN_INFO_PHY_11A 0
#define WCN36XX_HAL_CHAN_INFO_PHY_11BG 1
#define WCN36XX_HAL_DEFAULT_ANT_GAIN 6
#define WCN36XX_HAL_DEFAULT_MIN_POWER 6
struct wcn36xx_hal_channel_param {
u32 mhz;
u32 band_center_freq1;
u32 band_center_freq2;
u32 channel_info;
u32 reg_info_1;
u32 reg_info_2;
} __packed;
struct wcn36xx_hal_update_channel_list_req_msg {
struct wcn36xx_hal_msg_header header;
u8 num_channel;
struct wcn36xx_hal_channel_param channels[80];
} __packed;
enum wcn36xx_hal_rate_index {
HW_RATE_INDEX_1MBPS = 0x82,
HW_RATE_INDEX_2MBPS = 0x84,

Просмотреть файл

@ -85,7 +85,9 @@ static struct ieee80211_channel wcn_5ghz_channels[] = {
CHAN5G(5620, 124, PHY_QUADRUPLE_CHANNEL_20MHZ_LOW_40MHZ_HIGH),
CHAN5G(5640, 128, PHY_QUADRUPLE_CHANNEL_20MHZ_HIGH_40MHZ_HIGH),
CHAN5G(5660, 132, PHY_QUADRUPLE_CHANNEL_20MHZ_LOW_40MHZ_LOW),
CHAN5G(5680, 136, PHY_QUADRUPLE_CHANNEL_20MHZ_HIGH_40MHZ_LOW),
CHAN5G(5700, 140, PHY_QUADRUPLE_CHANNEL_20MHZ_LOW_40MHZ_HIGH),
CHAN5G(5720, 144, PHY_QUADRUPLE_CHANNEL_20MHZ_HIGH_40MHZ_HIGH),
CHAN5G(5745, 149, PHY_QUADRUPLE_CHANNEL_20MHZ_LOW_40MHZ_LOW),
CHAN5G(5765, 153, PHY_QUADRUPLE_CHANNEL_20MHZ_HIGH_40MHZ_LOW),
CHAN5G(5785, 157, PHY_QUADRUPLE_CHANNEL_20MHZ_LOW_40MHZ_HIGH),
@ -135,7 +137,9 @@ static struct ieee80211_supported_band wcn_band_2ghz = {
.cap = IEEE80211_HT_CAP_GRN_FLD |
IEEE80211_HT_CAP_SGI_20 |
IEEE80211_HT_CAP_DSSSCCK40 |
IEEE80211_HT_CAP_LSIG_TXOP_PROT,
IEEE80211_HT_CAP_LSIG_TXOP_PROT |
IEEE80211_HT_CAP_SGI_40 |
IEEE80211_HT_CAP_SUP_WIDTH_20_40,
.ht_supported = true,
.ampdu_factor = IEEE80211_HT_MAX_AMPDU_64K,
.ampdu_density = IEEE80211_HT_MPDU_DENSITY_16,
@ -613,15 +617,6 @@ static int wcn36xx_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd,
}
}
}
/* FIXME: Only enable bmps support when encryption is enabled.
* For any reasons, when connected to open/no-security BSS,
* the wcn36xx controller in bmps mode does not forward
* 'wake-up' beacons despite AP sends DTIM with station AID.
* It could be due to a firmware issue or to the way driver
* configure the station.
*/
if (vif->type == NL80211_IFTYPE_STATION)
vif_priv->allow_bmps = true;
break;
case DISABLE_KEY:
if (!(IEEE80211_KEY_FLAG_PAIRWISE & key_conf->flags)) {
@ -659,19 +654,19 @@ static int wcn36xx_hw_scan(struct ieee80211_hw *hw,
struct ieee80211_scan_request *hw_req)
{
struct wcn36xx *wcn = hw->priv;
int i;
if (!get_feat_caps(wcn->fw_feat_caps, SCAN_OFFLOAD)) {
/* fallback to mac80211 software scan */
return 1;
}
/* For unknown reason, the hardware offloaded scan only works with
* 2.4Ghz channels, fallback to software scan in other cases.
/* Firmware scan offload is limited to 48 channels, fallback to
* software driven scanning otherwise.
*/
for (i = 0; i < hw_req->req.n_channels; i++) {
if (hw_req->req.channels[i]->band != NL80211_BAND_2GHZ)
return 1;
if (hw_req->req.n_channels > 48) {
wcn36xx_warn("Offload scan aborted, n_channels=%u",
hw_req->req.n_channels);
return 1;
}
mutex_lock(&wcn->scan_lock);
@ -685,6 +680,7 @@ static int wcn36xx_hw_scan(struct ieee80211_hw *hw,
mutex_unlock(&wcn->scan_lock);
wcn36xx_smd_update_channel_list(wcn, &hw_req->req);
return wcn36xx_smd_start_hw_scan(wcn, vif, &hw_req->req);
}
@ -922,7 +918,6 @@ static void wcn36xx_bss_info_changed(struct ieee80211_hw *hw,
vif->addr,
bss_conf->aid);
vif_priv->sta_assoc = false;
vif_priv->allow_bmps = false;
wcn36xx_smd_set_link_st(wcn,
bss_conf->bssid,
vif->addr,
@ -1132,6 +1127,13 @@ static int wcn36xx_suspend(struct ieee80211_hw *hw, struct cfg80211_wowlan *wow)
goto out;
ret = wcn36xx_smd_wlan_host_suspend_ind(wcn);
}
/* Disable IRQ, we don't want to handle any packet before mac80211 is
* resumed and ready to receive packets.
*/
disable_irq(wcn->tx_irq);
disable_irq(wcn->rx_irq);
out:
mutex_unlock(&wcn->conf_mutex);
return ret;
@ -1154,6 +1156,10 @@ static int wcn36xx_resume(struct ieee80211_hw *hw)
wcn36xx_smd_ipv6_ns_offload(wcn, vif, false);
wcn36xx_smd_arp_offload(wcn, vif, false);
}
enable_irq(wcn->tx_irq);
enable_irq(wcn->rx_irq);
mutex_unlock(&wcn->conf_mutex);
return 0;
@ -1347,7 +1353,6 @@ static int wcn36xx_init_ieee80211(struct wcn36xx *wcn)
ieee80211_hw_set(wcn->hw, HAS_RATE_CONTROL);
ieee80211_hw_set(wcn->hw, SINGLE_SCAN_ON_ALL_BANDS);
ieee80211_hw_set(wcn->hw, REPORTS_TX_ACK_STATUS);
ieee80211_hw_set(wcn->hw, CONNECTION_MONITOR);
wcn->hw->wiphy->interface_modes = BIT(NL80211_IFTYPE_STATION) |
BIT(NL80211_IFTYPE_AP) |
@ -1499,6 +1504,7 @@ static int wcn36xx_probe(struct platform_device *pdev)
mutex_init(&wcn->conf_mutex);
mutex_init(&wcn->hal_mutex);
mutex_init(&wcn->scan_lock);
__skb_queue_head_init(&wcn->amsdu);
wcn->hal_buf = devm_kmalloc(wcn->dev, WCN36XX_HAL_BUF_SIZE, GFP_KERNEL);
if (!wcn->hal_buf) {
@ -1576,6 +1582,8 @@ static int wcn36xx_remove(struct platform_device *pdev)
iounmap(wcn->dxe_base);
iounmap(wcn->ccu_base);
__skb_queue_purge(&wcn->amsdu);
mutex_destroy(&wcn->hal_mutex);
ieee80211_free_hw(hw);

Просмотреть файл

@ -18,19 +18,19 @@
#include "wcn36xx.h"
#define WCN36XX_BMPS_FAIL_THREHOLD 3
int wcn36xx_pmc_enter_bmps_state(struct wcn36xx *wcn,
struct ieee80211_vif *vif)
{
int ret = 0;
struct wcn36xx_vif *vif_priv = wcn36xx_vif_to_priv(vif);
if (!vif_priv->allow_bmps)
return -ENOTSUPP;
/* TODO: Make sure the TX chain clean */
ret = wcn36xx_smd_enter_bmps(wcn, vif);
if (!ret) {
wcn36xx_dbg(WCN36XX_DBG_PMC, "Entered BMPS\n");
vif_priv->pw_state = WCN36XX_BMPS;
vif_priv->bmps_fail_ct = 0;
vif->driver_flags |= IEEE80211_VIF_BEACON_FILTER;
} else {
/*
@ -39,6 +39,11 @@ int wcn36xx_pmc_enter_bmps_state(struct wcn36xx *wcn,
* received just after auth complete
*/
wcn36xx_err("Can not enter BMPS!\n");
if (vif_priv->bmps_fail_ct++ == WCN36XX_BMPS_FAIL_THREHOLD) {
ieee80211_connection_loss(vif);
vif_priv->bmps_fail_ct = 0;
}
}
return ret;
}

Просмотреть файл

@ -16,6 +16,7 @@
#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
#include <linux/bitfield.h>
#include <linux/etherdevice.h>
#include <linux/firmware.h>
#include <linux/bitops.h>
@ -266,7 +267,8 @@ static void wcn36xx_smd_set_sta_ht_params(struct ieee80211_sta *sta,
sta_params->max_ampdu_size = sta->ht_cap.ampdu_factor;
sta_params->max_ampdu_density = sta->ht_cap.ampdu_density;
sta_params->max_amsdu_size = is_cap_supported(caps,
/* max_amsdu_size: 1 : 3839 bytes, 0 : 7935 bytes (max) */
sta_params->max_amsdu_size = !is_cap_supported(caps,
IEEE80211_HT_CAP_MAX_AMSDU);
sta_params->sgi_20Mhz = is_cap_supported(caps,
IEEE80211_HT_CAP_SGI_20);
@ -927,6 +929,86 @@ out:
return ret;
}
int wcn36xx_smd_update_channel_list(struct wcn36xx *wcn, struct cfg80211_scan_request *req)
{
struct wcn36xx_hal_update_channel_list_req_msg *msg_body;
int ret, i;
msg_body = kzalloc(sizeof(*msg_body), GFP_KERNEL);
if (!msg_body)
return -ENOMEM;
INIT_HAL_MSG((*msg_body), WCN36XX_HAL_UPDATE_CHANNEL_LIST_REQ);
msg_body->num_channel = min_t(u8, req->n_channels, sizeof(msg_body->channels));
for (i = 0; i < msg_body->num_channel; i++) {
struct wcn36xx_hal_channel_param *param = &msg_body->channels[i];
u32 min_power = WCN36XX_HAL_DEFAULT_MIN_POWER;
u32 ant_gain = WCN36XX_HAL_DEFAULT_ANT_GAIN;
param->mhz = req->channels[i]->center_freq;
param->band_center_freq1 = req->channels[i]->center_freq;
param->band_center_freq2 = 0;
if (req->channels[i]->flags & IEEE80211_CHAN_NO_IR)
param->channel_info |= WCN36XX_HAL_CHAN_INFO_FLAG_PASSIVE;
if (req->channels[i]->flags & IEEE80211_CHAN_RADAR)
param->channel_info |= WCN36XX_HAL_CHAN_INFO_FLAG_DFS;
if (req->channels[i]->band == NL80211_BAND_5GHZ) {
param->channel_info |= WCN36XX_HAL_CHAN_INFO_FLAG_HT;
param->channel_info |= WCN36XX_HAL_CHAN_INFO_FLAG_VHT;
param->channel_info |= WCN36XX_HAL_CHAN_INFO_PHY_11A;
} else {
param->channel_info |= WCN36XX_HAL_CHAN_INFO_PHY_11BG;
}
if (min_power > req->channels[i]->max_power)
min_power = req->channels[i]->max_power;
if (req->channels[i]->max_antenna_gain)
ant_gain = req->channels[i]->max_antenna_gain;
u32p_replace_bits(&param->reg_info_1, min_power,
WCN36XX_HAL_CHAN_REG1_MIN_PWR_MASK);
u32p_replace_bits(&param->reg_info_1, req->channels[i]->max_power,
WCN36XX_HAL_CHAN_REG1_MAX_PWR_MASK);
u32p_replace_bits(&param->reg_info_1, req->channels[i]->max_reg_power,
WCN36XX_HAL_CHAN_REG1_REG_PWR_MASK);
u32p_replace_bits(&param->reg_info_1, 0,
WCN36XX_HAL_CHAN_REG1_CLASS_ID_MASK);
u32p_replace_bits(&param->reg_info_2, ant_gain,
WCN36XX_HAL_CHAN_REG2_ANT_GAIN_MASK);
wcn36xx_dbg(WCN36XX_DBG_HAL,
"%s: freq=%u, channel_info=%08x, reg_info1=%08x, reg_info2=%08x\n",
__func__, param->mhz, param->channel_info, param->reg_info_1,
param->reg_info_2);
}
mutex_lock(&wcn->hal_mutex);
PREPARE_HAL_BUF(wcn->hal_buf, (*msg_body));
ret = wcn36xx_smd_send_and_wait(wcn, msg_body->header.len);
if (ret) {
wcn36xx_err("Sending hal_update_channel_list failed\n");
goto out;
}
ret = wcn36xx_smd_rsp_status_check(wcn->hal_buf, wcn->hal_rsp_len);
if (ret) {
wcn36xx_err("hal_update_channel_list response failed err=%d\n", ret);
goto out;
}
out:
kfree(msg_body);
mutex_unlock(&wcn->hal_mutex);
return ret;
}
static int wcn36xx_smd_switch_channel_rsp(void *buf, size_t len)
{
struct wcn36xx_hal_switch_channel_rsp_msg *rsp;
@ -2394,8 +2476,11 @@ int wcn36xx_smd_feature_caps_exchange(struct wcn36xx *wcn)
INIT_HAL_MSG(msg_body, WCN36XX_HAL_FEATURE_CAPS_EXCHANGE_REQ);
set_feat_caps(msg_body.feat_caps, STA_POWERSAVE);
if (wcn->rf_id == RF_IRIS_WCN3680)
if (wcn->rf_id == RF_IRIS_WCN3680) {
set_feat_caps(msg_body.feat_caps, DOT11AC);
set_feat_caps(msg_body.feat_caps, WLAN_CH144);
set_feat_caps(msg_body.feat_caps, ANTENNA_DIVERSITY_SELECTION);
}
PREPARE_HAL_BUF(wcn->hal_buf, msg_body);
@ -3137,6 +3222,7 @@ int wcn36xx_smd_rsp_process(struct rpmsg_device *rpdev,
case WCN36XX_HAL_HOST_RESUME_RSP:
case WCN36XX_HAL_ENTER_IMPS_RSP:
case WCN36XX_HAL_EXIT_IMPS_RSP:
case WCN36XX_HAL_UPDATE_CHANNEL_LIST_RSP:
memcpy(wcn->hal_buf, buf, len);
wcn->hal_rsp_len = len;
complete(&wcn->hal_rsp_compl);

Просмотреть файл

@ -70,6 +70,7 @@ int wcn36xx_smd_update_scan_params(struct wcn36xx *wcn, u8 *channels, size_t cha
int wcn36xx_smd_start_hw_scan(struct wcn36xx *wcn, struct ieee80211_vif *vif,
struct cfg80211_scan_request *req);
int wcn36xx_smd_stop_hw_scan(struct wcn36xx *wcn);
int wcn36xx_smd_update_channel_list(struct wcn36xx *wcn, struct cfg80211_scan_request *req);
int wcn36xx_smd_add_sta_self(struct wcn36xx *wcn, struct ieee80211_vif *vif);
int wcn36xx_smd_delete_sta_self(struct wcn36xx *wcn, u8 *addr);
int wcn36xx_smd_delete_sta(struct wcn36xx *wcn, u8 sta_index);

Просмотреть файл

@ -31,6 +31,13 @@ struct wcn36xx_rate {
enum rate_info_bw bw;
};
/* Buffer descriptor rx_ch field is limited to 5-bit (4+1), a mapping is used
* for 11A Channels.
*/
static const u8 ab_rx_ch_map[] = { 36, 40, 44, 48, 52, 56, 60, 64, 100, 104,
108, 112, 116, 120, 124, 128, 132, 136, 140,
149, 153, 157, 161, 165, 144 };
static const struct wcn36xx_rate wcn36xx_rate_table[] = {
/* 11b rates */
{ 10, 0, RX_ENC_LEGACY, 0, RATE_INFO_BW_20 },
@ -224,6 +231,41 @@ static const struct wcn36xx_rate wcn36xx_rate_table[] = {
{ 4333, 9, RX_ENC_VHT, RX_ENC_FLAG_SHORT_GI, RATE_INFO_BW_80 },
};
static struct sk_buff *wcn36xx_unchain_msdu(struct sk_buff_head *amsdu)
{
struct sk_buff *skb, *first;
int total_len = 0;
int space;
first = __skb_dequeue(amsdu);
skb_queue_walk(amsdu, skb)
total_len += skb->len;
space = total_len - skb_tailroom(first);
if (space > 0 && pskb_expand_head(first, 0, space, GFP_ATOMIC) < 0) {
__skb_queue_head(amsdu, first);
return NULL;
}
/* Walk list again, copying contents into msdu_head */
while ((skb = __skb_dequeue(amsdu))) {
skb_copy_from_linear_data(skb, skb_put(first, skb->len),
skb->len);
dev_kfree_skb_irq(skb);
}
return first;
}
static void __skb_queue_purge_irq(struct sk_buff_head *list)
{
struct sk_buff *skb;
while ((skb = __skb_dequeue(list)) != NULL)
dev_kfree_skb_irq(skb);
}
int wcn36xx_rx_skb(struct wcn36xx *wcn, struct sk_buff *skb)
{
struct ieee80211_rx_status status;
@ -245,6 +287,26 @@ int wcn36xx_rx_skb(struct wcn36xx *wcn, struct sk_buff *skb)
"BD <<< ", (char *)bd,
sizeof(struct wcn36xx_rx_bd));
if (bd->pdu.mpdu_data_off <= bd->pdu.mpdu_header_off ||
bd->pdu.mpdu_len < bd->pdu.mpdu_header_len)
goto drop;
if (bd->asf && !bd->esf) { /* chained A-MSDU chunks */
/* Sanity check */
if (bd->pdu.mpdu_data_off + bd->pdu.mpdu_len > WCN36XX_PKT_SIZE)
goto drop;
skb_put(skb, bd->pdu.mpdu_data_off + bd->pdu.mpdu_len);
skb_pull(skb, bd->pdu.mpdu_data_off);
/* Only set status for first chained BD (with mac header) */
goto done;
}
if (bd->pdu.mpdu_header_off < sizeof(*bd) ||
bd->pdu.mpdu_header_off + bd->pdu.mpdu_len > WCN36XX_PKT_SIZE)
goto drop;
skb_put(skb, bd->pdu.mpdu_header_off + bd->pdu.mpdu_len);
skb_pull(skb, bd->pdu.mpdu_header_off);
@ -291,6 +353,22 @@ int wcn36xx_rx_skb(struct wcn36xx *wcn, struct sk_buff *skb)
ieee80211_is_probe_resp(hdr->frame_control))
status.boottime_ns = ktime_get_boottime_ns();
if (bd->scan_learn) {
/* If packet originates from hardware scanning, extract the
* band/channel from bd descriptor.
*/
u8 hwch = (bd->reserved0 << 4) + bd->rx_ch;
if (bd->rf_band != 1 && hwch <= sizeof(ab_rx_ch_map) && hwch >= 1) {
status.band = NL80211_BAND_5GHZ;
status.freq = ieee80211_channel_to_frequency(ab_rx_ch_map[hwch - 1],
status.band);
} else {
status.band = NL80211_BAND_2GHZ;
status.freq = ieee80211_channel_to_frequency(hwch, status.band);
}
}
memcpy(IEEE80211_SKB_RXCB(skb), &status, sizeof(status));
if (ieee80211_is_beacon(hdr->frame_control)) {
@ -305,9 +383,37 @@ int wcn36xx_rx_skb(struct wcn36xx *wcn, struct sk_buff *skb)
(char *)skb->data, skb->len);
}
done:
/* Chained AMSDU ? slow path */
if (unlikely(bd->asf && !(bd->lsf && bd->esf))) {
if (bd->esf && !skb_queue_empty(&wcn->amsdu)) {
wcn36xx_err("Discarding non complete chain");
__skb_queue_purge_irq(&wcn->amsdu);
}
__skb_queue_tail(&wcn->amsdu, skb);
if (!bd->lsf)
return 0; /* Not the last AMSDU, wait for more */
skb = wcn36xx_unchain_msdu(&wcn->amsdu);
if (!skb)
goto drop;
}
ieee80211_rx_irqsafe(wcn->hw, skb);
return 0;
drop: /* drop everything */
wcn36xx_err("Drop frame! skb:%p len:%u hoff:%u doff:%u asf=%u esf=%u lsf=%u\n",
skb, bd->pdu.mpdu_len, bd->pdu.mpdu_header_off,
bd->pdu.mpdu_data_off, bd->asf, bd->esf, bd->lsf);
dev_kfree_skb_irq(skb);
__skb_queue_purge_irq(&wcn->amsdu);
return -EINVAL;
}
static void wcn36xx_set_tx_pdu(struct wcn36xx_tx_bd *bd,
@ -321,8 +427,6 @@ static void wcn36xx_set_tx_pdu(struct wcn36xx_tx_bd *bd,
bd->pdu.mpdu_header_off;
bd->pdu.mpdu_len = len;
bd->pdu.tid = tid;
/* Use seq number generated by mac80211 */
bd->pdu.bd_ssn = WCN36XX_TXBD_SSN_FILL_HOST;
}
static inline struct wcn36xx_vif *get_vif_by_addr(struct wcn36xx *wcn,
@ -419,6 +523,9 @@ static void wcn36xx_set_tx_data(struct wcn36xx_tx_bd *bd,
tid = ieee80211_get_tid(hdr);
/* TID->QID is one-to-one mapping */
bd->queue_id = tid;
bd->pdu.bd_ssn = WCN36XX_TXBD_SSN_FILL_DPU_QOS;
} else {
bd->pdu.bd_ssn = WCN36XX_TXBD_SSN_FILL_DPU_NON_QOS;
}
if (info->flags & IEEE80211_TX_INTFL_DONT_ENCRYPT ||
@ -429,6 +536,9 @@ static void wcn36xx_set_tx_data(struct wcn36xx_tx_bd *bd,
if (ieee80211_is_any_nullfunc(hdr->frame_control)) {
/* Don't use a regular queue for null packet (no ampdu) */
bd->queue_id = WCN36XX_TX_U_WQ_ID;
bd->bd_rate = WCN36XX_BD_RATE_CTRL;
if (ieee80211_is_qos_nullfunc(hdr->frame_control))
bd->pdu.bd_ssn = WCN36XX_TXBD_SSN_FILL_HOST;
}
if (bcast) {
@ -488,6 +598,8 @@ static void wcn36xx_set_tx_mgmt(struct wcn36xx_tx_bd *bd,
bd->queue_id = WCN36XX_TX_U_WQ_ID;
*vif_priv = __vif_priv;
bd->pdu.bd_ssn = WCN36XX_TXBD_SSN_FILL_DPU_NON_QOS;
wcn36xx_set_tx_pdu(bd,
ieee80211_is_data_qos(hdr->frame_control) ?
sizeof(struct ieee80211_qos_hdr) :
@ -502,10 +614,11 @@ int wcn36xx_start_tx(struct wcn36xx *wcn,
struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data;
struct wcn36xx_vif *vif_priv = NULL;
struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
unsigned long flags;
bool is_low = ieee80211_is_data(hdr->frame_control);
bool bcast = is_broadcast_ether_addr(hdr->addr1) ||
is_multicast_ether_addr(hdr->addr1);
bool ack_ind = (info->flags & IEEE80211_TX_CTL_REQ_TX_STATUS) &&
!(info->flags & IEEE80211_TX_CTL_NO_ACK);
struct wcn36xx_tx_bd bd;
int ret;
@ -521,30 +634,16 @@ int wcn36xx_start_tx(struct wcn36xx *wcn,
bd.dpu_rf = WCN36XX_BMU_WQ_TX;
if (info->flags & IEEE80211_TX_CTL_REQ_TX_STATUS) {
if (unlikely(ack_ind)) {
wcn36xx_dbg(WCN36XX_DBG_DXE, "TX_ACK status requested\n");
spin_lock_irqsave(&wcn->dxe_lock, flags);
if (wcn->tx_ack_skb) {
spin_unlock_irqrestore(&wcn->dxe_lock, flags);
wcn36xx_warn("tx_ack_skb already set\n");
return -EINVAL;
}
wcn->tx_ack_skb = skb;
spin_unlock_irqrestore(&wcn->dxe_lock, flags);
/* Only one at a time is supported by fw. Stop the TX queues
* until the ack status gets back.
*/
ieee80211_stop_queues(wcn->hw);
/* TX watchdog if no TX irq or ack indication received */
mod_timer(&wcn->tx_ack_timer, jiffies + HZ / 10);
/* Request ack indication from the firmware */
if (!(info->flags & IEEE80211_TX_CTL_NO_ACK))
bd.tx_comp = 1;
bd.tx_comp = 1;
}
/* Data frames served first*/
@ -558,14 +657,8 @@ int wcn36xx_start_tx(struct wcn36xx *wcn,
bd.tx_bd_sign = 0xbdbdbdbd;
ret = wcn36xx_dxe_tx_frame(wcn, vif_priv, &bd, skb, is_low);
if (ret && (info->flags & IEEE80211_TX_CTL_REQ_TX_STATUS)) {
/* If the skb has not been transmitted,
* don't keep a reference to it.
*/
spin_lock_irqsave(&wcn->dxe_lock, flags);
wcn->tx_ack_skb = NULL;
spin_unlock_irqrestore(&wcn->dxe_lock, flags);
if (unlikely(ret && ack_ind)) {
/* If the skb has not been transmitted, resume TX queue */
ieee80211_wake_queues(wcn->hw);
}

Просмотреть файл

@ -110,7 +110,8 @@ struct wcn36xx_rx_bd {
/* 0x44 */
u32 exp_seq_num:12;
u32 cur_seq_num:12;
u32 fr_type_subtype:8;
u32 rf_band:2;
u32 fr_type_subtype:6;
/* 0x48 */
u32 msdu_size:16;

Просмотреть файл

@ -128,7 +128,6 @@ struct wcn36xx_vif {
enum wcn36xx_hal_bss_type bss_type;
/* Power management */
bool allow_bmps;
enum wcn36xx_power_state pw_state;
u8 bss_index;
@ -151,6 +150,8 @@ struct wcn36xx_vif {
} rekey_data;
struct list_head sta_list;
int bmps_fail_ct;
};
/**
@ -269,6 +270,9 @@ struct wcn36xx {
struct sk_buff *tx_ack_skb;
struct timer_list tx_ack_timer;
/* For A-MSDU re-aggregation */
struct sk_buff_head amsdu;
/* RF module */
unsigned rf_id;
@ -276,7 +280,6 @@ struct wcn36xx {
/* Debug file system entry */
struct wcn36xx_dfs_entry dfs;
#endif /* CONFIG_WCN36XX_DEBUGFS */
};
static inline bool wcn36xx_is_fw_version(struct wcn36xx *wcn,

Просмотреть файл

@ -15,7 +15,7 @@ iwlwifi-objs += iwl-dbg-tlv.o
iwlwifi-objs += iwl-trans.o
iwlwifi-objs += queue/tx.o
iwlwifi-objs += fw/img.o fw/notif-wait.o
iwlwifi-objs += fw/img.o fw/notif-wait.o fw/rs.o
iwlwifi-objs += fw/dbg.o fw/pnvm.o fw/dump.o
iwlwifi-$(CONFIG_IWLMVM) += fw/paging.o fw/smem.o fw/init.o
iwlwifi-$(CONFIG_ACPI) += fw/acpi.o

Просмотреть файл

@ -3,11 +3,6 @@
*
* Copyright(c) 2008 - 2014 Intel Corporation. All rights reserved.
* Copyright(c) 2018 - 2020 Intel Corporation
*
* Contact Information:
* Intel Linux Wireless <linuxwifi@intel.com>
* Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
*
*****************************************************************************/
#include <linux/module.h>

Просмотреть файл

@ -3,11 +3,6 @@
*
* Copyright(c) 2008 - 2014 Intel Corporation. All rights reserved.
* Copyright(c) 2018 - 2020 Intel Corporation
*
* Contact Information:
* Intel Linux Wireless <linuxwifi@intel.com>
* Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
*
*****************************************************************************/
#include <linux/module.h>

Просмотреть файл

@ -9,7 +9,7 @@
#include "iwl-prph.h"
/* Highest firmware API version supported */
#define IWL_22000_UCODE_API_MAX 66
#define IWL_22000_UCODE_API_MAX 67
/* Lowest firmware API version supported */
#define IWL_22000_UCODE_API_MIN 39
@ -53,6 +53,9 @@
#define IWL_BZ_A_GF_A_FW_PRE "iwlwifi-bz-a0-gf-a0-"
#define IWL_BZ_A_GF4_A_FW_PRE "iwlwifi-bz-a0-gf4-a0-"
#define IWL_BZ_A_MR_A_FW_PRE "iwlwifi-bz-a0-mr-a0-"
#define IWL_BZ_A_FM_A_FW_PRE "iwlwifi-bz-a0-fm-a0-"
#define IWL_GL_A_FM_A_FW_PRE "iwlwifi-gl-a0-fm7-a0-"
#define IWL_QU_B_HR_B_MODULE_FIRMWARE(api) \
IWL_QU_B_HR_B_FW_PRE __stringify(api) ".ucode"
@ -106,6 +109,10 @@
IWL_BZ_A_GF4_A_FW_PRE __stringify(api) ".ucode"
#define IWL_BZ_A_MR_A_MODULE_FIRMWARE(api) \
IWL_BZ_A_MR_A_FW_PRE __stringify(api) ".ucode"
#define IWL_BZ_A_FM_A_MODULE_FIRMWARE(api) \
IWL_BZ_A_FM_A_FW_PRE __stringify(api) ".ucode"
#define IWL_GL_A_FM_A_MODULE_FIRMWARE(api) \
IWL_GL_A_FM_A_FW_PRE __stringify(api) ".ucode"
static const struct iwl_base_params iwl_22000_base_params = {
.eeprom_size = OTP_LOW_IMAGE_SIZE_32K,
@ -469,6 +476,14 @@ const char iwl_ax210_killer_1675w_name[] =
"Killer(R) Wi-Fi 6E AX1675w 160MHz Wireless Network Adapter (210D2W)";
const char iwl_ax210_killer_1675x_name[] =
"Killer(R) Wi-Fi 6E AX1675x 160MHz Wireless Network Adapter (210NGW)";
const char iwl_ax211_killer_1675s_name[] =
"Killer(R) Wi-Fi 6E AX1675s 160MHz Wireless Network Adapter (211NGW)";
const char iwl_ax211_killer_1675i_name[] =
"Killer(R) Wi-Fi 6E AX1675i 160MHz Wireless Network Adapter (211NGW)";
const char iwl_ax411_killer_1690s_name[] =
"Killer(R) Wi-Fi 6E AX1690s 160MHz Wireless Network Adapter (411D2W)";
const char iwl_ax411_killer_1690i_name[] =
"Killer(R) Wi-Fi 6E AX1690i 160MHz Wireless Network Adapter (411NGW)";
const struct iwl_cfg iwl_qu_b0_hr1_b0 = {
.fw_name_pre = IWL_QU_B_HR_B_FW_PRE,
@ -850,6 +865,20 @@ const struct iwl_cfg iwl_cfg_bz_a0_mr_a0 = {
.num_rbds = IWL_NUM_RBDS_AX210_HE,
};
const struct iwl_cfg iwl_cfg_bz_a0_fm_a0 = {
.fw_name_pre = IWL_BZ_A_FM_A_FW_PRE,
.uhb_supported = true,
IWL_DEVICE_BZ,
.num_rbds = IWL_NUM_RBDS_AX210_HE,
};
const struct iwl_cfg iwl_cfg_gl_a0_fm_a0 = {
.fw_name_pre = IWL_GL_A_FM_A_FW_PRE,
.uhb_supported = true,
IWL_DEVICE_BZ,
.num_rbds = IWL_NUM_RBDS_AX210_HE,
};
MODULE_FIRMWARE(IWL_QU_B_HR_B_MODULE_FIRMWARE(IWL_22000_UCODE_API_MAX));
MODULE_FIRMWARE(IWL_QNJ_B_HR_B_MODULE_FIRMWARE(IWL_22000_UCODE_API_MAX));
MODULE_FIRMWARE(IWL_QU_C_HR_B_MODULE_FIRMWARE(IWL_22000_UCODE_API_MAX));
@ -876,3 +905,5 @@ MODULE_FIRMWARE(IWL_BZ_A_HR_B_MODULE_FIRMWARE(IWL_22000_UCODE_API_MAX));
MODULE_FIRMWARE(IWL_BZ_A_GF_A_MODULE_FIRMWARE(IWL_22000_UCODE_API_MAX));
MODULE_FIRMWARE(IWL_BZ_A_GF4_A_MODULE_FIRMWARE(IWL_22000_UCODE_API_MAX));
MODULE_FIRMWARE(IWL_BZ_A_MR_A_MODULE_FIRMWARE(IWL_22000_UCODE_API_MAX));
MODULE_FIRMWARE(IWL_BZ_A_FM_A_MODULE_FIRMWARE(IWL_22000_UCODE_API_MAX));
MODULE_FIRMWARE(IWL_GL_A_FM_A_MODULE_FIRMWARE(IWL_22000_UCODE_API_MAX));

Просмотреть файл

@ -3,11 +3,6 @@
*
* Copyright(c) 2007 - 2014 Intel Corporation. All rights reserved.
* Copyright(c) 2018 - 2020 Intel Corporation
*
* Contact Information:
* Intel Linux Wireless <linuxwifi@intel.com>
* Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
*
*****************************************************************************/
#include <linux/module.h>

Просмотреть файл

@ -3,11 +3,6 @@
*
* Copyright(c) 2008 - 2014 Intel Corporation. All rights reserved.
* Copyright(c) 2018 - 2020 Intel Corporation
*
* Contact Information:
* Intel Linux Wireless <linuxwifi@intel.com>
* Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
*
*****************************************************************************/
#include <linux/module.h>

Просмотреть файл

@ -1,6 +1,6 @@
/* SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause */
/*
* Copyright (C) 2005-2014 Intel Corporation
* Copyright (C) 2005-2014, 2021 Intel Corporation
*/
#ifndef __iwl_agn_h__
#define __iwl_agn_h__
@ -398,8 +398,10 @@ do { \
if (!iwl_is_rfkill((m))) \
IWL_ERR(m, fmt, ##args); \
else \
__iwl_err((m)->dev, true, \
!iwl_have_debug_level(IWL_DL_RADIO), \
__iwl_err((m)->dev, \
iwl_have_debug_level(IWL_DL_RADIO) ? \
IWL_ERR_MODE_RFKILL : \
IWL_ERR_MODE_TRACE_ONLY, \
fmt, ##args); \
} while (0)
#else
@ -408,7 +410,8 @@ do { \
if (!iwl_is_rfkill((m))) \
IWL_ERR(m, fmt, ##args); \
else \
__iwl_err((m)->dev, true, true, fmt, ##args); \
__iwl_err((m)->dev, IWL_ERR_MODE_TRACE_ONLY, \
fmt, ##args); \
} while (0)
#endif /* CONFIG_IWLWIFI_DEBUG */

Просмотреть файл

@ -3,10 +3,6 @@
*
* Copyright(c) 2008 - 2014 Intel Corporation. All rights reserved.
* Copyright (C) 2018 Intel Corporation
*
* Contact Information:
* Intel Linux Wireless <linuxwifi@intel.com>
* Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
*****************************************************************************/
#include <linux/slab.h>

Просмотреть файл

@ -2,11 +2,6 @@
/******************************************************************************
*
* Copyright(c) 2003 - 2014, 2020 Intel Corporation. All rights reserved.
*
* Contact Information:
* Intel Linux Wireless <linuxwifi@intel.com>
* Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
*
*****************************************************************************/
/*
* Please use this file (dev.h) for driver implementation definitions.

Просмотреть файл

@ -3,11 +3,6 @@
*
* Copyright(c) 2008 - 2014 Intel Corporation. All rights reserved.
* Copyright (C) 2019 Intel Corporation
*
* Contact Information:
* Intel Linux Wireless <linuxwifi@intel.com>
* Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
*
*****************************************************************************/
#include <linux/units.h>

Просмотреть файл

@ -3,11 +3,6 @@
*
* Copyright(c) 2003 - 2014 Intel Corporation. All rights reserved.
* Copyright (C) 2019 Intel Corporation
*
* Contact Information:
* Intel Linux Wireless <linuxwifi@intel.com>
* Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
*
*****************************************************************************/

Просмотреть файл

@ -2,11 +2,6 @@
/******************************************************************************
*
* Copyright(c) 2003 - 2014 Intel Corporation. All rights reserved.
*
* Contact Information:
* Intel Linux Wireless <linuxwifi@intel.com>
* Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
*
*****************************************************************************/
#ifndef __iwl_leds_h__

Просмотреть файл

@ -2,11 +2,6 @@
/******************************************************************************
*
* Copyright(c) 2008 - 2014 Intel Corporation. All rights reserved.
*
* Contact Information:
* Intel Linux Wireless <linuxwifi@intel.com>
* Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
*
*****************************************************************************/
#include <linux/etherdevice.h>
#include <linux/kernel.h>

Просмотреть файл

@ -6,11 +6,6 @@
*
* Portions of this file are derived from the ipw3945 project, as well
* as portions of the ieee80211 subsystem header files.
*
* Contact Information:
* Intel Linux Wireless <linuxwifi@intel.com>
* Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
*
*****************************************************************************/
#include <linux/kernel.h>
#include <linux/module.h>

Просмотреть файл

@ -6,11 +6,6 @@
*
* Portions of this file are derived from the ipw3945 project, as well
* as portions of the ieee80211 subsystem header files.
*
* Contact Information:
* Intel Linux Wireless <linuxwifi@intel.com>
* Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
*
*****************************************************************************/
#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
@ -52,7 +47,6 @@
#define DRV_DESCRIPTION "Intel(R) Wireless WiFi Link AGN driver for Linux"
MODULE_DESCRIPTION(DRV_DESCRIPTION);
MODULE_AUTHOR(DRV_AUTHOR);
MODULE_LICENSE("GPL");
/* Please keep this array *SORTED* by hex value.

Просмотреть файл

@ -6,10 +6,6 @@
*
* Portions of this file are derived from the ipw3945 project, as well
* as portions of the ieee80211 subsystem header files.
*
* Contact Information:
* Intel Linux Wireless <linuxwifi@intel.com>
* Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
*****************************************************************************/

Просмотреть файл

@ -5,10 +5,6 @@
*
* Portions of this file are derived from the ipw3945 project, as well
* as portions of the ieee80211 subsystem header files.
*
* Contact Information:
* Intel Linux Wireless <linuxwifi@intel.com>
* Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
*****************************************************************************/
#ifndef __iwl_power_setting_h__
#define __iwl_power_setting_h__

Просмотреть файл

@ -3,11 +3,6 @@
*
* Copyright(c) 2005 - 2014 Intel Corporation. All rights reserved.
* Copyright (C) 2019 - 2020 Intel Corporation
*
* Contact Information:
* Intel Linux Wireless <linuxwifi@intel.com>
* Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
*
*****************************************************************************/
#include <linux/kernel.h>
#include <linux/skbuff.h>

Просмотреть файл

@ -2,11 +2,6 @@
/******************************************************************************
*
* Copyright(c) 2003 - 2014 Intel Corporation. All rights reserved.
*
* Contact Information:
* Intel Linux Wireless <linuxwifi@intel.com>
* Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
*
*****************************************************************************/
#ifndef __iwl_agn_rs_h__

Просмотреть файл

@ -7,11 +7,6 @@
*
* Portions of this file are derived from the ipw3945 project, as well
* as portionhelp of the ieee80211 subsystem header files.
*
* Contact Information:
* Intel Linux Wireless <linuxwifi@intel.com>
* Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
*
*****************************************************************************/
#include <linux/etherdevice.h>

Просмотреть файл

@ -3,11 +3,6 @@
*
* Copyright(c) 2003 - 2014 Intel Corporation. All rights reserved.
* Copyright(c) 2015 Intel Deutschland GmbH
*
* Contact Information:
* Intel Linux Wireless <linuxwifi@intel.com>
* Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
*
*****************************************************************************/
#include <linux/etherdevice.h>

Просмотреть файл

@ -3,10 +3,6 @@
*
* Copyright(c) 2008 - 2014 Intel Corporation. All rights reserved.
* Copyright(c) 2018 Intel Corporation
*
* Contact Information:
* Intel Linux Wireless <linuxwifi@intel.com>
* Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
*****************************************************************************/
#include <linux/slab.h>
#include <linux/types.h>

Просмотреть файл

@ -5,11 +5,6 @@
*
* Portions of this file are derived from the ipw3945 project, as well
* as portions of the ieee80211 subsystem header files.
*
* Contact Information:
* Intel Linux Wireless <linuxwifi@intel.com>
* Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
*
*****************************************************************************/
#include <linux/etherdevice.h>
#include <net/mac80211.h>

Просмотреть файл

@ -6,10 +6,6 @@
*
* Portions of this file are derived from the ipw3945 project, as well
* as portions of the ieee80211 subsystem header files.
*
* Contact Information:
* Intel Linux Wireless <linuxwifi@intel.com>
* Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
*****************************************************************************/

Просмотреть файл

@ -5,10 +5,6 @@
*
* Portions of this file are derived from the ipw3945 project, as well
* as portions of the ieee80211 subsystem header files.
*
* Contact Information:
* Intel Linux Wireless <linuxwifi@intel.com>
* Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
*****************************************************************************/
#ifndef __iwl_tt_setting_h__
#define __iwl_tt_setting_h__

Просмотреть файл

@ -3,11 +3,6 @@
*
* Copyright(c) 2008 - 2014 Intel Corporation. All rights reserved.
* Copyright (C) 2019 Intel Corporation
*
* Contact Information:
* Intel Linux Wireless <linuxwifi@intel.com>
* Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
*
*****************************************************************************/
#include <linux/kernel.h>

Просмотреть файл

@ -3,11 +3,6 @@
*
* Copyright(c) 2008 - 2014 Intel Corporation. All rights reserved.
* Copyright(c) 2015 Intel Deutschland GmbH
*
* Contact Information:
* Intel Linux Wireless <linuxwifi@intel.com>
* Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
*
*****************************************************************************/
#include <linux/kernel.h>

Просмотреть файл

@ -184,9 +184,11 @@ int iwl_acpi_get_dsm_u32(struct device *dev, int rev, int func,
}
IWL_EXPORT_SYMBOL(iwl_acpi_get_dsm_u32);
union acpi_object *iwl_acpi_get_wifi_pkg(struct device *dev,
union acpi_object *data,
int data_size, int *tbl_rev)
union acpi_object *iwl_acpi_get_wifi_pkg_range(struct device *dev,
union acpi_object *data,
int min_data_size,
int max_data_size,
int *tbl_rev)
{
int i;
union acpi_object *wifi_pkg;
@ -196,7 +198,7 @@ union acpi_object *iwl_acpi_get_wifi_pkg(struct device *dev,
* describes the domain, and one more entry, otherwise there's
* no point in reading it.
*/
if (WARN_ON_ONCE(data_size < 2))
if (WARN_ON_ONCE(min_data_size < 2 || min_data_size > max_data_size))
return ERR_PTR(-EINVAL);
/*
@ -222,7 +224,8 @@ union acpi_object *iwl_acpi_get_wifi_pkg(struct device *dev,
/* skip entries that are not a package with the right size */
if (wifi_pkg->type != ACPI_TYPE_PACKAGE ||
wifi_pkg->package.count != data_size)
wifi_pkg->package.count < min_data_size ||
wifi_pkg->package.count > max_data_size)
continue;
domain = &wifi_pkg->package.elements[0];
@ -236,7 +239,7 @@ union acpi_object *iwl_acpi_get_wifi_pkg(struct device *dev,
found:
return wifi_pkg;
}
IWL_EXPORT_SYMBOL(iwl_acpi_get_wifi_pkg);
IWL_EXPORT_SYMBOL(iwl_acpi_get_wifi_pkg_range);
int iwl_acpi_get_tas(struct iwl_fw_runtime *fwrt,
__le32 *block_list_array,
@ -707,49 +710,103 @@ int iwl_sar_get_wgds_table(struct iwl_fw_runtime *fwrt)
{
union acpi_object *wifi_pkg, *data;
int i, j, k, ret, tbl_rev;
int idx = 1; /* start from one to skip the domain */
u8 num_bands;
u8 num_bands, num_profiles;
static const struct {
u8 revisions;
u8 bands;
u8 profiles;
u8 min_profiles;
} rev_data[] = {
{
.revisions = BIT(3),
.bands = ACPI_GEO_NUM_BANDS_REV2,
.profiles = ACPI_NUM_GEO_PROFILES_REV3,
.min_profiles = 3,
},
{
.revisions = BIT(2),
.bands = ACPI_GEO_NUM_BANDS_REV2,
.profiles = ACPI_NUM_GEO_PROFILES,
},
{
.revisions = BIT(0) | BIT(1),
.bands = ACPI_GEO_NUM_BANDS_REV0,
.profiles = ACPI_NUM_GEO_PROFILES,
},
};
int idx;
/* start from one to skip the domain */
int entry_idx = 1;
BUILD_BUG_ON(ACPI_NUM_GEO_PROFILES_REV3 != IWL_NUM_GEO_PROFILES_V3);
BUILD_BUG_ON(ACPI_NUM_GEO_PROFILES != IWL_NUM_GEO_PROFILES);
data = iwl_acpi_get_object(fwrt->dev, ACPI_WGDS_METHOD);
if (IS_ERR(data))
return PTR_ERR(data);
/* start by trying to read revision 2 */
wifi_pkg = iwl_acpi_get_wifi_pkg(fwrt->dev, data,
ACPI_WGDS_WIFI_DATA_SIZE_REV2,
&tbl_rev);
if (!IS_ERR(wifi_pkg)) {
if (tbl_rev != 2) {
ret = PTR_ERR(wifi_pkg);
goto out_free;
/* read the highest revision we understand first */
for (idx = 0; idx < ARRAY_SIZE(rev_data); idx++) {
/* min_profiles != 0 requires num_profiles header */
u32 hdr_size = 1 + !!rev_data[idx].min_profiles;
u32 profile_size = ACPI_GEO_PER_CHAIN_SIZE *
rev_data[idx].bands;
u32 max_size = hdr_size + profile_size * rev_data[idx].profiles;
u32 min_size;
if (!rev_data[idx].min_profiles)
min_size = max_size;
else
min_size = hdr_size +
profile_size * rev_data[idx].min_profiles;
wifi_pkg = iwl_acpi_get_wifi_pkg_range(fwrt->dev, data,
min_size, max_size,
&tbl_rev);
if (!IS_ERR(wifi_pkg)) {
if (!(BIT(tbl_rev) & rev_data[idx].revisions))
continue;
num_bands = rev_data[idx].bands;
num_profiles = rev_data[idx].profiles;
if (rev_data[idx].min_profiles) {
/* read header that says # of profiles */
union acpi_object *entry;
entry = &wifi_pkg->package.elements[entry_idx];
entry_idx++;
if (entry->type != ACPI_TYPE_INTEGER ||
entry->integer.value > num_profiles) {
ret = -EINVAL;
goto out_free;
}
num_profiles = entry->integer.value;
/*
* this also validates >= min_profiles since we
* otherwise wouldn't have gotten the data when
* looking up in ACPI
*/
if (wifi_pkg->package.count !=
min_size + profile_size * num_profiles) {
ret = -EINVAL;
goto out_free;
}
}
goto read_table;
}
num_bands = ACPI_GEO_NUM_BANDS_REV2;
goto read_table;
}
/* then try revision 0 (which is the same as 1) */
wifi_pkg = iwl_acpi_get_wifi_pkg(fwrt->dev, data,
ACPI_WGDS_WIFI_DATA_SIZE_REV0,
&tbl_rev);
if (!IS_ERR(wifi_pkg)) {
if (tbl_rev != 0 && tbl_rev != 1) {
ret = PTR_ERR(wifi_pkg);
goto out_free;
}
num_bands = ACPI_GEO_NUM_BANDS_REV0;
goto read_table;
}
ret = PTR_ERR(wifi_pkg);
if (idx < ARRAY_SIZE(rev_data))
ret = PTR_ERR(wifi_pkg);
else
ret = -ENOENT;
goto out_free;
read_table:
fwrt->geo_rev = tbl_rev;
for (i = 0; i < ACPI_NUM_GEO_PROFILES; i++) {
for (i = 0; i < num_profiles; i++) {
for (j = 0; j < ACPI_GEO_NUM_BANDS_REV2; j++) {
union acpi_object *entry;
@ -762,7 +819,8 @@ read_table:
fwrt->geo_profiles[i].bands[j].max =
fwrt->geo_profiles[i].bands[1].max;
} else {
entry = &wifi_pkg->package.elements[idx++];
entry = &wifi_pkg->package.elements[entry_idx];
entry_idx++;
if (entry->type != ACPI_TYPE_INTEGER ||
entry->integer.value > U8_MAX) {
ret = -EINVAL;
@ -779,7 +837,8 @@ read_table:
fwrt->geo_profiles[i].bands[j].chains[k] =
fwrt->geo_profiles[i].bands[1].chains[k];
} else {
entry = &wifi_pkg->package.elements[idx++];
entry = &wifi_pkg->package.elements[entry_idx];
entry_idx++;
if (entry->type != ACPI_TYPE_INTEGER ||
entry->integer.value > U8_MAX) {
ret = -EINVAL;
@ -803,10 +862,10 @@ IWL_EXPORT_SYMBOL(iwl_sar_get_wgds_table);
bool iwl_sar_geo_support(struct iwl_fw_runtime *fwrt)
{
/*
* The GEO_TX_POWER_LIMIT command is not supported on earlier
* firmware versions. Unfortunately, we don't have a TLV API
* flag to rely on, so rely on the major version which is in
* the first byte of ucode_ver. This was implemented
* The PER_CHAIN_LIMIT_OFFSET_CMD command is not supported on
* earlier firmware versions. Unfortunately, we don't have a
* TLV API flag to rely on, so rely on the major version which
* is in the first byte of ucode_ver. This was implemented
* initially on version 38 and then backported to 17. It was
* also backported to 29, but only for 7265D devices. The
* intention was to have it in 36 as well, but not all 8000
@ -822,14 +881,15 @@ bool iwl_sar_geo_support(struct iwl_fw_runtime *fwrt)
IWL_EXPORT_SYMBOL(iwl_sar_geo_support);
int iwl_sar_geo_init(struct iwl_fw_runtime *fwrt,
struct iwl_per_chain_offset *table, u32 n_bands)
struct iwl_per_chain_offset *table,
u32 n_bands, u32 n_profiles)
{
int i, j;
if (!iwl_sar_geo_support(fwrt))
return -EOPNOTSUPP;
for (i = 0; i < ACPI_NUM_GEO_PROFILES; i++) {
for (i = 0; i < n_profiles; i++) {
for (j = 0; j < n_bands; j++) {
struct iwl_per_chain_offset *chain =
&table[i * n_bands + j];

Просмотреть файл

@ -29,6 +29,7 @@
#define ACPI_SAR_PROFILE_NUM 4
#define ACPI_NUM_GEO_PROFILES 3
#define ACPI_NUM_GEO_PROFILES_REV3 8
#define ACPI_GEO_PER_CHAIN_SIZE 3
#define ACPI_SAR_NUM_CHAINS_REV0 2
@ -59,13 +60,6 @@
#define ACPI_GEO_NUM_BANDS_REV2 3
#define ACPI_GEO_NUM_CHAINS 2
#define ACPI_WGDS_WIFI_DATA_SIZE_REV0 (ACPI_NUM_GEO_PROFILES * \
ACPI_GEO_NUM_BANDS_REV0 * \
ACPI_GEO_PER_CHAIN_SIZE + 1)
#define ACPI_WGDS_WIFI_DATA_SIZE_REV2 (ACPI_NUM_GEO_PROFILES * \
ACPI_GEO_NUM_BANDS_REV2 * \
ACPI_GEO_PER_CHAIN_SIZE + 1)
#define ACPI_WRDD_WIFI_DATA_SIZE 2
#define ACPI_SPLC_WIFI_DATA_SIZE 2
#define ACPI_ECKV_WIFI_DATA_SIZE 2
@ -115,8 +109,10 @@ enum iwl_dsm_funcs_rev_0 {
DSM_FUNC_QUERY = 0,
DSM_FUNC_DISABLE_SRD = 1,
DSM_FUNC_ENABLE_INDONESIA_5G2 = 2,
DSM_FUNC_ENABLE_6E = 3,
DSM_FUNC_11AX_ENABLEMENT = 6,
DSM_FUNC_ENABLE_UNII4_CHAN = 7
DSM_FUNC_ENABLE_UNII4_CHAN = 7,
DSM_FUNC_ACTIVATE_CHANNEL = 8
};
enum iwl_dsm_values_srd {
@ -158,10 +154,11 @@ int iwl_acpi_get_dsm_u8(struct device *dev, int rev, int func,
int iwl_acpi_get_dsm_u32(struct device *dev, int rev, int func,
const guid_t *guid, u32 *value);
union acpi_object *iwl_acpi_get_wifi_pkg(struct device *dev,
union acpi_object *data,
int data_size, int *tbl_rev);
union acpi_object *iwl_acpi_get_wifi_pkg_range(struct device *dev,
union acpi_object *data,
int min_data_size,
int max_data_size,
int *tbl_rev);
/**
* iwl_acpi_get_mcc - read MCC from ACPI, if available
*
@ -198,7 +195,8 @@ int iwl_sar_get_wgds_table(struct iwl_fw_runtime *fwrt);
bool iwl_sar_geo_support(struct iwl_fw_runtime *fwrt);
int iwl_sar_geo_init(struct iwl_fw_runtime *fwrt,
struct iwl_per_chain_offset *table, u32 n_bands);
struct iwl_per_chain_offset *table,
u32 n_bands, u32 n_profiles);
int iwl_acpi_get_tas(struct iwl_fw_runtime *fwrt, __le32 *block_list_array,
int *block_list_size);
@ -230,10 +228,11 @@ static inline int iwl_acpi_get_dsm_u32(struct device *dev, int rev, int func,
return -ENOENT;
}
static inline union acpi_object *iwl_acpi_get_wifi_pkg(struct device *dev,
union acpi_object *data,
int data_size,
int *tbl_rev)
static inline union acpi_object *
iwl_acpi_get_wifi_pkg_range(struct device *dev,
union acpi_object *data,
int min_data_size, int max_data_size,
int *tbl_rev)
{
return ERR_PTR(-ENOENT);
}
@ -293,4 +292,14 @@ static inline __le32 iwl_acpi_get_lari_config_bitmap(struct iwl_fw_runtime *fwrt
}
#endif /* CONFIG_ACPI */
static inline union acpi_object *
iwl_acpi_get_wifi_pkg(struct device *dev,
union acpi_object *data,
int data_size, int *tbl_rev)
{
return iwl_acpi_get_wifi_pkg_range(dev, data, data_size, data_size,
tbl_rev);
}
#endif /* __iwl_fw_acpi__ */

Просмотреть файл

@ -624,7 +624,7 @@ struct iwl_wowlan_status_v6 {
} __packed; /* WOWLAN_STATUSES_API_S_VER_6 */
/**
* struct iwl_wowlan_status - WoWLAN status
* struct iwl_wowlan_status_v7 - WoWLAN status
* @gtk: GTK data
* @igtk: IGTK data
* @replay_ctr: GTK rekey replay counter
@ -693,49 +693,6 @@ struct iwl_wowlan_status_v9 {
u8 wake_packet[]; /* can be truncated from _length to _bufsize */
} __packed; /* WOWLAN_STATUSES_RSP_API_S_VER_9 */
/**
* struct iwl_wowlan_status - WoWLAN status
* @gtk: GTK data
* @igtk: IGTK data
* @bigtk: BIGTK data
* @replay_ctr: GTK rekey replay counter
* @pattern_number: number of the matched pattern
* @non_qos_seq_ctr: non-QoS sequence counter to use next
* @qos_seq_ctr: QoS sequence counters to use next
* @wakeup_reasons: wakeup reasons, see &enum iwl_wowlan_wakeup_reason
* @num_of_gtk_rekeys: number of GTK rekeys
* @tid_tear_down: bitmap of TIDs torn down
* @reserved: reserved
* @received_beacons: number of received beacons
* @wake_packet_length: wakeup packet length
* @wake_packet_bufsize: wakeup packet buffer size
* @tid_tear_down: bit mask of tids whose BA sessions were closed
* in suspend state
* @wake_packet: wakeup packet
*/
struct iwl_wowlan_status {
struct iwl_wowlan_gtk_status gtk[1];
struct iwl_wowlan_igtk_status igtk[1];
struct iwl_wowlan_igtk_status bigtk[WOWLAN_IGTK_KEYS_NUM];
__le64 replay_ctr;
__le16 pattern_number;
__le16 non_qos_seq_ctr;
__le16 qos_seq_ctr[8];
__le32 wakeup_reasons;
__le32 num_of_gtk_rekeys;
u8 tid_tear_down;
u8 reserved[3];
__le32 received_beacons;
__le32 wake_packet_length;
__le32 wake_packet_bufsize;
u8 wake_packet[]; /* can be truncated from _length to _bufsize */
} __packed; /* WOWLAN_STATUSES_API_S_VER_11 */
static inline u8 iwlmvm_wowlan_gtk_idx(struct iwl_wowlan_gtk_status *gtk)
{
return gtk->key_flags & IWL_WOWLAN_GTK_IDX_MASK;
}
/* TODO: NetDetect API */
#endif /* __iwl_fw_api_d3_h__ */

Просмотреть файл

@ -7,6 +7,7 @@
#include <linux/bitops.h>
#define IWL_FW_INI_HW_SMEM_REGION_ID 15
#define IWL_FW_INI_MAX_REGION_ID 64
#define IWL_FW_INI_MAX_NAME 32
#define IWL_FW_INI_MAX_CFG_NAME 64
@ -242,6 +243,62 @@ struct iwl_fw_ini_hcmd_tlv {
struct iwl_fw_ini_hcmd hcmd;
} __packed; /* FW_TLV_DEBUG_HCMD_API_S_VER_1 */
/**
* struct iwl_fw_ini_conf_tlv - preset configuration TLV
*
* @address: the base address
* @value: value to set at address
*/
struct iwl_fw_ini_addr_val {
__le32 address;
__le32 value;
} __packed; /* FW_TLV_DEBUG_ADDR_VALUE_VER_1 */
/**
* struct iwl_fw_ini_conf_tlv - configuration TLV to set register/memory.
*
* @hdr: debug header
* @time_point: time point to apply config. One of &enum iwl_fw_ini_time_point
* @set_type: write access type preset token for time point.
* one of &enum iwl_fw_ini_config_set_type
* @addr_offset: the offset to add to any item in address[0] field
* @addr_val: address value pair
*/
struct iwl_fw_ini_conf_set_tlv {
struct iwl_fw_ini_header hdr;
__le32 time_point;
__le32 set_type;
__le32 addr_offset;
struct iwl_fw_ini_addr_val addr_val[0];
} __packed; /* FW_TLV_DEBUG_CONFIG_SET_API_S_VER_1 */
/**
* enum iwl_fw_ini_config_set_type
*
* @IWL_FW_INI_CONFIG_SET_TYPE_INVALID: invalid config set
* @IWL_FW_INI_CONFIG_SET_TYPE_DEVICE_PERIPHERY_MAC: for PERIPHERY MAC configuration
* @IWL_FW_INI_CONFIG_SET_TYPE_DEVICE_PERIPHERY_PHY: for PERIPHERY PHY configuration
* @IWL_FW_INI_CONFIG_SET_TYPE_DEVICE_PERIPHERY_AUX: for PERIPHERY AUX configuration
* @IWL_FW_INI_CONFIG_SET_TYPE_DEVICE_MEMORY: for DEVICE MEMORY configuration
* @IWL_FW_INI_CONFIG_SET_TYPE_CSR: for CSR configuration
* @IWL_FW_INI_CONFIG_SET_TYPE_DBGC_DRAM_ADDR: for DBGC_DRAM_ADDR configuration
* @IWL_FW_INI_CONFIG_SET_TYPE_PERIPH_SCRATCH_HWM: for PERIPH SCRATCH HWM configuration
* @IWL_FW_INI_ALLOCATION_NUM: max number of configuration supported
*/
enum iwl_fw_ini_config_set_type {
IWL_FW_INI_CONFIG_SET_TYPE_INVALID = 0,
IWL_FW_INI_CONFIG_SET_TYPE_DEVICE_PERIPHERY_MAC,
IWL_FW_INI_CONFIG_SET_TYPE_DEVICE_PERIPHERY_PHY,
IWL_FW_INI_CONFIG_SET_TYPE_DEVICE_PERIPHERY_AUX,
IWL_FW_INI_CONFIG_SET_TYPE_DEVICE_MEMORY,
IWL_FW_INI_CONFIG_SET_TYPE_CSR,
IWL_FW_INI_CONFIG_SET_TYPE_DBGC_DRAM_ADDR,
IWL_FW_INI_CONFIG_SET_TYPE_PERIPH_SCRATCH_HWM,
IWL_FW_INI_CONFIG_SET_TYPE_MAX_NUM,
} __packed;
/**
* enum iwl_fw_ini_allocation_id
*

Просмотреть файл

@ -361,6 +361,41 @@ struct iwl_buf_alloc_cmd {
struct iwl_buf_alloc_frag frags[BUF_ALLOC_MAX_NUM_FRAGS];
} __packed; /* BUFFER_ALLOCATION_CMD_API_S_VER_2 */
#define DRAM_INFO_FIRST_MAGIC_WORD 0x76543210
#define DRAM_INFO_SECOND_MAGIC_WORD 0x89ABCDEF
/**
* struct iwL_dram_info - DRAM fragments allocation struct
*
* Driver will fill in the first 1K(+) of the pointed DRAM fragment
*
* @first_word: magic word value
* @second_word: magic word value
* @framfrags: DRAM fragmentaion detail
*/
struct iwl_dram_info {
__le32 first_word;
__le32 second_word;
struct iwl_buf_alloc_cmd dram_frags[IWL_FW_INI_ALLOCATION_NUM - 1];
} __packed; /* INIT_DRAM_FRAGS_ALLOCATIONS_S_VER_1 */
/**
* struct iwl_dbgc1_info - DBGC1 address and size
*
* Driver will fill the dbcg1 address and size at address based on config TLV.
*
* @first_word: all 0 set as identifier
* @dbgc1_add_lsb: LSB bits of DBGC1 physical address
* @dbgc1_add_msb: MSB bits of DBGC1 physical address
* @dbgc1_size: DBGC1 size
*/
struct iwl_dbgc1_info {
__le32 first_word;
__le32 dbgc1_add_lsb;
__le32 dbgc1_add_msb;
__le32 dbgc1_size;
} __packed; /* INIT_DRAM_FRAGS_ALLOCATIONS_S_VER_1 */
/**
* struct iwl_dbg_host_event_cfg_cmd
* @enabled_severities: enabled severities

Просмотреть файл

@ -206,7 +206,7 @@ enum iwl_tof_responder_cfg_flags {
IWL_TOF_RESPONDER_FLAGS_SPECIFIC_CALIB_MODE = BIT(8),
IWL_TOF_RESPONDER_FLAGS_FAST_ALGO_SUPPORT = BIT(9),
IWL_TOF_RESPONDER_FLAGS_RETRY_ON_ALGO_FAIL = BIT(10),
IWL_TOF_RESPONDER_FLAGS_FTM_TX_ANT = RATE_MCS_ANT_ABC_MSK,
IWL_TOF_RESPONDER_FLAGS_FTM_TX_ANT = RATE_MCS_ANT_AB_MSK,
IWL_TOF_RESPONDER_FLAGS_NDP_SUPPORT = BIT(24),
IWL_TOF_RESPONDER_FLAGS_LMR_FEEDBACK = BIT(25),
IWL_TOF_RESPONDER_FLAGS_SESSION_ID = BIT(27),
@ -629,6 +629,7 @@ enum iwl_location_bw {
IWL_LOCATION_BW_20MHZ,
IWL_LOCATION_BW_40MHZ,
IWL_LOCATION_BW_80MHZ,
IWL_LOCATION_BW_160MHZ,
};
#define TK_11AZ_LEN 32
@ -1500,7 +1501,9 @@ struct iwl_tof_range_rsp_ap_entry_ntfy_v6 {
u8 reserved[3];
u8 rx_pn[IEEE80211_CCMP_PN_LEN];
u8 tx_pn[IEEE80211_CCMP_PN_LEN];
} __packed; /* LOCATION_RANGE_RSP_AP_ETRY_NTFY_API_S_VER_6 */
} __packed; /* LOCATION_RANGE_RSP_AP_ETRY_NTFY_API_S_VER_6,
LOCATION_RANGE_RSP_AP_ETRY_NTFY_API_S_VER_7 */
/**
* enum iwl_tof_response_status - tof response status
@ -1581,7 +1584,8 @@ struct iwl_tof_range_rsp_ntfy_v8 {
u8 last_report;
u8 reserved;
struct iwl_tof_range_rsp_ap_entry_ntfy_v6 ap[IWL_MVM_TOF_MAX_APS];
} __packed; /* LOCATION_RANGE_RSP_NTFY_API_S_VER_8 */
} __packed; /* LOCATION_RANGE_RSP_NTFY_API_S_VER_8,
LOCATION_RANGE_RSP_NTFY_API_S_VER_9 */
#define IWL_MVM_TOF_MCSI_BUF_SIZE (245)
/**

Просмотреть файл

@ -1,6 +1,6 @@
/* SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause */
/*
* Copyright (C) 2012-2014, 2018-2019 Intel Corporation
* Copyright (C) 2012-2014, 2018-2019, 2021 Intel Corporation
* Copyright (C) 2013-2015 Intel Mobile Communications GmbH
* Copyright (C) 2016-2017 Intel Deutschland GmbH
*/
@ -39,9 +39,9 @@ enum iwl_mac_conf_subcmd_ids {
PROBE_RESPONSE_DATA_NOTIF = 0xFC,
/**
* @CHANNEL_SWITCH_NOA_NOTIF: &struct iwl_channel_switch_noa_notif
* @CHANNEL_SWITCH_START_NOTIF: &struct iwl_channel_switch_start_notif
*/
CHANNEL_SWITCH_NOA_NOTIF = 0xFF,
CHANNEL_SWITCH_START_NOTIF = 0xFF,
};
#define IWL_P2P_NOA_DESC_COUNT (2)
@ -102,11 +102,11 @@ struct iwl_missed_vap_notif {
} __packed; /* MISSED_VAP_NTFY_API_S_VER_1 */
/**
* struct iwl_channel_switch_noa_notif - Channel switch NOA notification
* struct iwl_channel_switch_start_notif - Channel switch start notification
*
* @id_and_color: ID and color of the MAC
*/
struct iwl_channel_switch_noa_notif {
struct iwl_channel_switch_start_notif {
__le32 id_and_color;
} __packed; /* CHANNEL_SWITCH_START_NTFY_API_S_VER_1 */

Просмотреть файл

@ -138,6 +138,8 @@ struct iwl_mac_data_ibss {
* @FLEXIBLE_TWT_SUPPORTED: AP supports flexible TWT schedule
* @PROTECTED_TWT_SUPPORTED: AP supports protected TWT frames (with 11w)
* @BROADCAST_TWT_SUPPORTED: AP and STA support broadcast TWT
* @COEX_HIGH_PRIORITY_ENABLE: high priority mode for BT coex, to be used
* during 802.1X negotiation (and allowed during 4-way-HS)
*/
enum iwl_mac_data_policy {
TWT_SUPPORTED = BIT(0),
@ -145,6 +147,7 @@ enum iwl_mac_data_policy {
FLEXIBLE_TWT_SUPPORTED = BIT(2),
PROTECTED_TWT_SUPPORTED = BIT(3),
BROADCAST_TWT_SUPPORTED = BIT(4),
COEX_HIGH_PRIORITY_ENABLE = BIT(5),
};
/**

Просмотреть файл

@ -471,6 +471,29 @@ struct iwl_lari_config_change_cmd_v4 {
__le32 oem_unii4_allow_bitmap;
} __packed; /* LARI_CHANGE_CONF_CMD_S_VER_4 */
/**
* struct iwl_lari_config_change_cmd_v5 - change LARI configuration
* @config_bitmap: Bitmap of the config commands. Each bit will trigger a
* different predefined FW config operation.
* @oem_uhb_allow_bitmap: Bitmap of UHB enabled MCC sets.
* @oem_11ax_allow_bitmap: Bitmap of 11ax allowed MCCs. There are two bits
* per country, one to indicate whether to override and the other to
* indicate the value to use.
* @oem_unii4_allow_bitmap: Bitmap of unii4 allowed MCCs.There are two bits
* per country, one to indicate whether to override and the other to
* indicate allow/disallow unii4 channels.
* @chan_state_active_bitmap: Bitmap for overriding channel state to active.
* Each bit represents a country or region to activate, according to the BIOS
* definitions.
*/
struct iwl_lari_config_change_cmd_v5 {
__le32 config_bitmap;
__le32 oem_uhb_allow_bitmap;
__le32 oem_11ax_allow_bitmap;
__le32 oem_unii4_allow_bitmap;
__le32 chan_state_active_bitmap;
} __packed; /* LARI_CHANGE_CONF_CMD_S_VER_5 */
/**
* struct iwl_pnvm_init_complete_ntfy - PNVM initialization complete
* @status: PNVM image loading status

Просмотреть файл

@ -1,6 +1,6 @@
/* SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause */
/*
* Copyright (C) 2012-2014, 2019-2020 Intel Corporation
* Copyright (C) 2012-2014, 2019-2021 Intel Corporation
* Copyright (C) 2013-2015 Intel Mobile Communications GmbH
* Copyright (C) 2016-2017 Intel Deutschland GmbH
*/
@ -29,9 +29,9 @@ enum iwl_phy_ops_subcmd_ids {
TEMP_REPORTING_THRESHOLDS_CMD = 0x04,
/**
* @GEO_TX_POWER_LIMIT: &struct iwl_geo_tx_power_profiles_cmd
* @PER_CHAIN_LIMIT_OFFSET_CMD: &struct iwl_geo_tx_power_profiles_cmd
*/
GEO_TX_POWER_LIMIT = 0x05,
PER_CHAIN_LIMIT_OFFSET_CMD = 0x05,
/**
* @PER_PLATFORM_ANT_GAIN_CMD: &struct iwl_ppag_table_cmd

Просмотреть файл

@ -1,6 +1,6 @@
/* SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause */
/*
* Copyright (C) 2012-2014, 2018-2020 Intel Corporation
* Copyright (C) 2012-2014, 2018-2021 Intel Corporation
* Copyright (C) 2013-2014 Intel Mobile Communications GmbH
* Copyright (C) 2015-2017 Intel Deutschland GmbH
*/
@ -378,9 +378,10 @@ struct iwl_dev_tx_power_cmd {
};
};
#define IWL_NUM_GEO_PROFILES 3
#define IWL_NUM_BANDS_PER_CHAIN_V1 2
#define IWL_NUM_BANDS_PER_CHAIN_V2 3
#define IWL_NUM_GEO_PROFILES 3
#define IWL_NUM_GEO_PROFILES_V3 8
#define IWL_NUM_BANDS_PER_CHAIN_V1 2
#define IWL_NUM_BANDS_PER_CHAIN_V2 3
/**
* enum iwl_geo_per_chain_offset_operation - type of operation
@ -390,10 +391,10 @@ struct iwl_dev_tx_power_cmd {
enum iwl_geo_per_chain_offset_operation {
IWL_PER_CHAIN_OFFSET_SET_TABLES,
IWL_PER_CHAIN_OFFSET_GET_CURRENT_TABLE,
}; /* GEO_TX_POWER_LIMIT FLAGS TYPE */
}; /* PER_CHAIN_OFFSET_OPERATION_E */
/**
* struct iwl_per_chain_offset - embedded struct for GEO_TX_POWER_LIMIT.
* struct iwl_per_chain_offset - embedded struct for PER_CHAIN_LIMIT_OFFSET_CMD.
* @max_tx_power: maximum allowed tx power.
* @chain_a: tx power offset for chain a.
* @chain_b: tx power offset for chain b.
@ -405,17 +406,17 @@ struct iwl_per_chain_offset {
} __packed; /* PER_CHAIN_LIMIT_OFFSET_PER_CHAIN_S_VER_1 */
/**
* struct iwl_geo_tx_power_profile_cmd_v1 - struct for GEO_TX_POWER_LIMIT cmd.
* struct iwl_geo_tx_power_profile_cmd_v1 - struct for PER_CHAIN_LIMIT_OFFSET_CMD cmd.
* @ops: operations, value from &enum iwl_geo_per_chain_offset_operation
* @table: offset profile per band.
*/
struct iwl_geo_tx_power_profiles_cmd_v1 {
__le32 ops;
struct iwl_per_chain_offset table[IWL_NUM_GEO_PROFILES][IWL_NUM_BANDS_PER_CHAIN_V1];
} __packed; /* GEO_TX_POWER_LIMIT_VER_1 */
} __packed; /* PER_CHAIN_LIMIT_OFFSET_CMD_VER_1 */
/**
* struct iwl_geo_tx_power_profile_cmd_v2 - struct for GEO_TX_POWER_LIMIT cmd.
* struct iwl_geo_tx_power_profile_cmd_v2 - struct for PER_CHAIN_LIMIT_OFFSET_CMD cmd.
* @ops: operations, value from &enum iwl_geo_per_chain_offset_operation
* @table: offset profile per band.
* @table_revision: BIOS table revision.
@ -424,10 +425,10 @@ struct iwl_geo_tx_power_profiles_cmd_v2 {
__le32 ops;
struct iwl_per_chain_offset table[IWL_NUM_GEO_PROFILES][IWL_NUM_BANDS_PER_CHAIN_V1];
__le32 table_revision;
} __packed; /* GEO_TX_POWER_LIMIT_VER_2 */
} __packed; /* PER_CHAIN_LIMIT_OFFSET_CMD_VER_2 */
/**
* struct iwl_geo_tx_power_profile_cmd_v3 - struct for GEO_TX_POWER_LIMIT cmd.
* struct iwl_geo_tx_power_profile_cmd_v3 - struct for PER_CHAIN_LIMIT_OFFSET_CMD cmd.
* @ops: operations, value from &enum iwl_geo_per_chain_offset_operation
* @table: offset profile per band.
* @table_revision: BIOS table revision.
@ -436,21 +437,47 @@ struct iwl_geo_tx_power_profiles_cmd_v3 {
__le32 ops;
struct iwl_per_chain_offset table[IWL_NUM_GEO_PROFILES][IWL_NUM_BANDS_PER_CHAIN_V2];
__le32 table_revision;
} __packed; /* GEO_TX_POWER_LIMIT_VER_3 */
} __packed; /* PER_CHAIN_LIMIT_OFFSET_CMD_VER_3 */
/**
* struct iwl_geo_tx_power_profile_cmd_v4 - struct for PER_CHAIN_LIMIT_OFFSET_CMD cmd.
* @ops: operations, value from &enum iwl_geo_per_chain_offset_operation
* @table: offset profile per band.
* @table_revision: BIOS table revision.
*/
struct iwl_geo_tx_power_profiles_cmd_v4 {
__le32 ops;
struct iwl_per_chain_offset table[IWL_NUM_GEO_PROFILES_V3][IWL_NUM_BANDS_PER_CHAIN_V1];
__le32 table_revision;
} __packed; /* PER_CHAIN_LIMIT_OFFSET_CMD_VER_4 */
/**
* struct iwl_geo_tx_power_profile_cmd_v5 - struct for PER_CHAIN_LIMIT_OFFSET_CMD cmd.
* @ops: operations, value from &enum iwl_geo_per_chain_offset_operation
* @table: offset profile per band.
* @table_revision: BIOS table revision.
*/
struct iwl_geo_tx_power_profiles_cmd_v5 {
__le32 ops;
struct iwl_per_chain_offset table[IWL_NUM_GEO_PROFILES_V3][IWL_NUM_BANDS_PER_CHAIN_V2];
__le32 table_revision;
} __packed; /* PER_CHAIN_LIMIT_OFFSET_CMD_VER_5 */
union iwl_geo_tx_power_profiles_cmd {
struct iwl_geo_tx_power_profiles_cmd_v1 v1;
struct iwl_geo_tx_power_profiles_cmd_v2 v2;
struct iwl_geo_tx_power_profiles_cmd_v3 v3;
struct iwl_geo_tx_power_profiles_cmd_v4 v4;
struct iwl_geo_tx_power_profiles_cmd_v5 v5;
};
/**
* struct iwl_geo_tx_power_profiles_resp - response to GEO_TX_POWER_LIMIT cmd
* struct iwl_geo_tx_power_profiles_resp - response to PER_CHAIN_LIMIT_OFFSET_CMD cmd
* @profile_idx: current geo profile in use
*/
struct iwl_geo_tx_power_profiles_resp {
__le32 profile_idx;
} __packed; /* GEO_TX_POWER_LIMIT_RESP */
} __packed; /* PER_CHAIN_LIMIT_OFFSET_RSP */
/**
* union iwl_ppag_table_cmd - union for all versions of PPAG command

Просмотреть файл

@ -184,6 +184,14 @@ struct iwl_tlc_update_notif {
__le32 amsdu_enabled;
} __packed; /* TLC_MNG_UPDATE_NTFY_API_S_VER_2 */
#define IWL_MAX_MCS_DISPLAY_SIZE 12
struct iwl_rate_mcs_info {
char mbps[IWL_MAX_MCS_DISPLAY_SIZE];
char mcs[IWL_MAX_MCS_DISPLAY_SIZE];
};
/*
* These serve as indexes into
* struct iwl_rate_info fw_rate_idx_to_plcp[IWL_RATE_COUNT];
@ -226,6 +234,8 @@ enum {
IWL_LAST_HE_RATE = IWL_RATE_MCS_11_INDEX,
IWL_RATE_COUNT_LEGACY = IWL_LAST_NON_HT_RATE + 1,
IWL_RATE_COUNT = IWL_LAST_HE_RATE + 1,
IWL_RATE_INVM_INDEX = IWL_RATE_COUNT,
IWL_RATE_INVALID = IWL_RATE_COUNT,
};
#define IWL_RATE_BIT_MSK(r) BIT(IWL_RATE_##r##M_INDEX)
@ -248,7 +258,7 @@ enum {
};
/*
* rate_n_flags bit fields
* rate_n_flags bit fields version 1
*
* The 32-bit value has different layouts in the low 8 bites depending on the
* format. There are three formats, HT, VHT and legacy (11abg, with subformats
@ -266,15 +276,15 @@ enum {
/* Bit 8: (1) HT format, (0) legacy or VHT format */
#define RATE_MCS_HT_POS 8
#define RATE_MCS_HT_MSK (1 << RATE_MCS_HT_POS)
#define RATE_MCS_HT_MSK_V1 BIT(RATE_MCS_HT_POS)
/* Bit 9: (1) CCK, (0) OFDM. HT (bit 8) must be "0" for this bit to be valid */
#define RATE_MCS_CCK_POS 9
#define RATE_MCS_CCK_MSK (1 << RATE_MCS_CCK_POS)
#define RATE_MCS_CCK_POS_V1 9
#define RATE_MCS_CCK_MSK_V1 BIT(RATE_MCS_CCK_POS_V1)
/* Bit 26: (1) VHT format, (0) legacy format in bits 8:0 */
#define RATE_MCS_VHT_POS 26
#define RATE_MCS_VHT_MSK (1 << RATE_MCS_VHT_POS)
#define RATE_MCS_VHT_POS_V1 26
#define RATE_MCS_VHT_MSK_V1 BIT(RATE_MCS_VHT_POS_V1)
/*
@ -300,15 +310,16 @@ enum {
* streams and 16-23 have three streams. We could also support MCS 32
* which is the duplicate 20 MHz MCS (bit 5 set, all others zero.)
*/
#define RATE_HT_MCS_RATE_CODE_MSK 0x7
#define RATE_HT_MCS_NSS_POS 3
#define RATE_HT_MCS_NSS_MSK (3 << RATE_HT_MCS_NSS_POS)
#define RATE_HT_MCS_RATE_CODE_MSK_V1 0x7
#define RATE_HT_MCS_NSS_POS_V1 3
#define RATE_HT_MCS_NSS_MSK_V1 (3 << RATE_HT_MCS_NSS_POS_V1)
#define RATE_HT_MCS_MIMO2_MSK BIT(RATE_HT_MCS_NSS_POS_V1)
/* Bit 10: (1) Use Green Field preamble */
#define RATE_HT_MCS_GF_POS 10
#define RATE_HT_MCS_GF_MSK (1 << RATE_HT_MCS_GF_POS)
#define RATE_HT_MCS_INDEX_MSK 0x3f
#define RATE_HT_MCS_INDEX_MSK_V1 0x3f
/*
* Very High-throughput (VHT) rate format for bits 7:0
@ -324,6 +335,7 @@ enum {
#define RATE_VHT_MCS_RATE_CODE_MSK 0xf
#define RATE_VHT_MCS_NSS_POS 4
#define RATE_VHT_MCS_NSS_MSK (3 << RATE_VHT_MCS_NSS_POS)
#define RATE_VHT_MCS_MIMO2_MSK BIT(RATE_VHT_MCS_NSS_POS)
/*
* Legacy OFDM rate format for bits 7:0
@ -347,37 +359,30 @@ enum {
* 110) 11 Mbps
* (bit 7 is 0)
*/
#define RATE_LEGACY_RATE_MSK 0xff
#define RATE_LEGACY_RATE_MSK_V1 0xff
/* Bit 10 - OFDM HE */
#define RATE_MCS_HE_POS 10
#define RATE_MCS_HE_MSK BIT(RATE_MCS_HE_POS)
#define RATE_MCS_HE_POS_V1 10
#define RATE_MCS_HE_MSK_V1 BIT(RATE_MCS_HE_POS_V1)
/*
* Bit 11-12: (0) 20MHz, (1) 40MHz, (2) 80MHz, (3) 160MHz
* 0 and 1 are valid for HT and VHT, 2 and 3 only for VHT
*/
#define RATE_MCS_CHAN_WIDTH_POS 11
#define RATE_MCS_CHAN_WIDTH_MSK (3 << RATE_MCS_CHAN_WIDTH_POS)
#define RATE_MCS_CHAN_WIDTH_20 (0 << RATE_MCS_CHAN_WIDTH_POS)
#define RATE_MCS_CHAN_WIDTH_40 (1 << RATE_MCS_CHAN_WIDTH_POS)
#define RATE_MCS_CHAN_WIDTH_80 (2 << RATE_MCS_CHAN_WIDTH_POS)
#define RATE_MCS_CHAN_WIDTH_160 (3 << RATE_MCS_CHAN_WIDTH_POS)
#define RATE_MCS_CHAN_WIDTH_MSK_V1 (3 << RATE_MCS_CHAN_WIDTH_POS)
/* Bit 13: (1) Short guard interval (0.4 usec), (0) normal GI (0.8 usec) */
#define RATE_MCS_SGI_POS 13
#define RATE_MCS_SGI_MSK (1 << RATE_MCS_SGI_POS)
#define RATE_MCS_SGI_POS_V1 13
#define RATE_MCS_SGI_MSK_V1 BIT(RATE_MCS_SGI_POS_V1)
/* Bit 14-16: Antenna selection (1) Ant A, (2) Ant B, (4) Ant C */
#define RATE_MCS_ANT_POS 14
#define RATE_MCS_ANT_A_MSK (1 << RATE_MCS_ANT_POS)
#define RATE_MCS_ANT_B_MSK (2 << RATE_MCS_ANT_POS)
#define RATE_MCS_ANT_C_MSK (4 << RATE_MCS_ANT_POS)
#define RATE_MCS_ANT_AB_MSK (RATE_MCS_ANT_A_MSK | \
RATE_MCS_ANT_B_MSK)
#define RATE_MCS_ANT_ABC_MSK (RATE_MCS_ANT_AB_MSK | \
RATE_MCS_ANT_C_MSK)
#define RATE_MCS_ANT_MSK RATE_MCS_ANT_ABC_MSK
#define RATE_MCS_ANT_MSK RATE_MCS_ANT_AB_MSK
/* Bit 17: (0) SS, (1) SS*2 */
#define RATE_MCS_STBC_POS 17
@ -411,27 +416,27 @@ enum {
* 3 (does not occur)
*/
#define RATE_MCS_HE_GI_LTF_POS 20
#define RATE_MCS_HE_GI_LTF_MSK (3 << RATE_MCS_HE_GI_LTF_POS)
#define RATE_MCS_HE_GI_LTF_MSK_V1 (3 << RATE_MCS_HE_GI_LTF_POS)
/* Bit 22-23: HE type. (0) SU, (1) SU_EXT, (2) MU, (3) trigger based */
#define RATE_MCS_HE_TYPE_POS 22
#define RATE_MCS_HE_TYPE_SU (0 << RATE_MCS_HE_TYPE_POS)
#define RATE_MCS_HE_TYPE_EXT_SU (1 << RATE_MCS_HE_TYPE_POS)
#define RATE_MCS_HE_TYPE_MU (2 << RATE_MCS_HE_TYPE_POS)
#define RATE_MCS_HE_TYPE_TRIG (3 << RATE_MCS_HE_TYPE_POS)
#define RATE_MCS_HE_TYPE_MSK (3 << RATE_MCS_HE_TYPE_POS)
#define RATE_MCS_HE_TYPE_POS_V1 22
#define RATE_MCS_HE_TYPE_SU_V1 (0 << RATE_MCS_HE_TYPE_POS_V1)
#define RATE_MCS_HE_TYPE_EXT_SU_V1 BIT(RATE_MCS_HE_TYPE_POS_V1)
#define RATE_MCS_HE_TYPE_MU_V1 (2 << RATE_MCS_HE_TYPE_POS_V1)
#define RATE_MCS_HE_TYPE_TRIG_V1 (3 << RATE_MCS_HE_TYPE_POS_V1)
#define RATE_MCS_HE_TYPE_MSK_V1 (3 << RATE_MCS_HE_TYPE_POS_V1)
/* Bit 24-25: (0) 20MHz (no dup), (1) 2x20MHz, (2) 4x20MHz, 3 8x20MHz */
#define RATE_MCS_DUP_POS 24
#define RATE_MCS_DUP_MSK (3 << RATE_MCS_DUP_POS)
#define RATE_MCS_DUP_POS_V1 24
#define RATE_MCS_DUP_MSK_V1 (3 << RATE_MCS_DUP_POS_V1)
/* Bit 27: (1) LDPC enabled, (0) LDPC disabled */
#define RATE_MCS_LDPC_POS 27
#define RATE_MCS_LDPC_MSK (1 << RATE_MCS_LDPC_POS)
#define RATE_MCS_LDPC_POS_V1 27
#define RATE_MCS_LDPC_MSK_V1 BIT(RATE_MCS_LDPC_POS_V1)
/* Bit 28: (1) 106-tone RX (8 MHz RU), (0) normal bandwidth */
#define RATE_MCS_HE_106T_POS 28
#define RATE_MCS_HE_106T_MSK (1 << RATE_MCS_HE_106T_POS)
#define RATE_MCS_HE_106T_POS_V1 28
#define RATE_MCS_HE_106T_MSK_V1 BIT(RATE_MCS_HE_106T_POS_V1)
/* Bit 30-31: (1) RTS, (2) CTS */
#define RATE_MCS_RTS_REQUIRED_POS (30)
@ -440,6 +445,152 @@ enum {
#define RATE_MCS_CTS_REQUIRED_POS (31)
#define RATE_MCS_CTS_REQUIRED_MSK (0x1 << RATE_MCS_CTS_REQUIRED_POS)
/* rate_n_flags bit field version 2
*
* The 32-bit value has different layouts in the low 8 bits depending on the
* format. There are three formats, HT, VHT and legacy (11abg, with subformats
* for CCK and OFDM).
*
*/
/* Bits 10-8: rate format
* (0) Legacy CCK (1) Legacy OFDM (2) High-throughput (HT)
* (3) Very High-throughput (VHT) (4) High-efficiency (HE)
* (5) Extremely High-throughput (EHT)
*/
#define RATE_MCS_MOD_TYPE_POS 8
#define RATE_MCS_MOD_TYPE_MSK (0x7 << RATE_MCS_MOD_TYPE_POS)
#define RATE_MCS_CCK_MSK (0 << RATE_MCS_MOD_TYPE_POS)
#define RATE_MCS_LEGACY_OFDM_MSK (1 << RATE_MCS_MOD_TYPE_POS)
#define RATE_MCS_HT_MSK (2 << RATE_MCS_MOD_TYPE_POS)
#define RATE_MCS_VHT_MSK (3 << RATE_MCS_MOD_TYPE_POS)
#define RATE_MCS_HE_MSK (4 << RATE_MCS_MOD_TYPE_POS)
#define RATE_MCS_EHT_MSK (5 << RATE_MCS_MOD_TYPE_POS)
/*
* Legacy CCK rate format for bits 0:3:
*
* (0) 0xa - 1 Mbps
* (1) 0x14 - 2 Mbps
* (2) 0x37 - 5.5 Mbps
* (3) 0x6e - 11 nbps
*
* Legacy OFDM rate format for bis 3:0:
*
* (0) 6 Mbps
* (1) 9 Mbps
* (2) 12 Mbps
* (3) 18 Mbps
* (4) 24 Mbps
* (5) 36 Mbps
* (6) 48 Mbps
* (7) 54 Mbps
*
*/
#define RATE_LEGACY_RATE_MSK 0x7
/*
* HT, VHT, HE, EHT rate format for bits 3:0
* 3-0: MCS
*
*/
#define RATE_HT_MCS_CODE_MSK 0x7
#define RATE_MCS_NSS_POS 4
#define RATE_MCS_NSS_MSK (1 << RATE_MCS_NSS_POS)
#define RATE_MCS_CODE_MSK 0xf
#define RATE_HT_MCS_INDEX(r) ((((r) & RATE_MCS_NSS_MSK) >> 1) | \
((r) & RATE_HT_MCS_CODE_MSK))
/* Bits 7-5: reserved */
/*
* Bits 13-11: (0) 20MHz, (1) 40MHz, (2) 80MHz, (3) 160MHz, (4) 320MHz
*/
#define RATE_MCS_CHAN_WIDTH_MSK (0x7 << RATE_MCS_CHAN_WIDTH_POS)
#define RATE_MCS_CHAN_WIDTH_20 (0 << RATE_MCS_CHAN_WIDTH_POS)
#define RATE_MCS_CHAN_WIDTH_40 (1 << RATE_MCS_CHAN_WIDTH_POS)
#define RATE_MCS_CHAN_WIDTH_80 (2 << RATE_MCS_CHAN_WIDTH_POS)
#define RATE_MCS_CHAN_WIDTH_160 (3 << RATE_MCS_CHAN_WIDTH_POS)
#define RATE_MCS_CHAN_WIDTH_320 (4 << RATE_MCS_CHAN_WIDTH_POS)
/* Bit 15-14: Antenna selection:
* Bit 14: Ant A active
* Bit 15: Ant B active
*
* All relevant definitions are same as in v1
*/
/* Bit 16 (1) LDPC enables, (0) LDPC disabled */
#define RATE_MCS_LDPC_POS 16
#define RATE_MCS_LDPC_MSK (1 << RATE_MCS_LDPC_POS)
/* Bit 17: (0) SS, (1) SS*2 (same as v1) */
/* Bit 18: OFDM-HE dual carrier mode (same as v1) */
/* Bit 19: (0) Beamforming is off, (1) Beamforming is on (same as v1) */
/*
* Bit 22-20: HE LTF type and guard interval
* CCK:
* 0 long preamble
* 1 short preamble
* HT/VHT:
* 0 0.8us
* 1 0.4us
* HE (ext) SU:
* 0 1xLTF+0.8us
* 1 2xLTF+0.8us
* 2 2xLTF+1.6us
* 3 4xLTF+3.2us
* 4 4xLTF+0.8us
* HE MU:
* 0 4xLTF+0.8us
* 1 2xLTF+0.8us
* 2 2xLTF+1.6us
* 3 4xLTF+3.2us
* HE TRIG:
* 0 1xLTF+1.6us
* 1 2xLTF+1.6us
* 2 4xLTF+3.2us
* */
#define RATE_MCS_HE_GI_LTF_MSK (0x7 << RATE_MCS_HE_GI_LTF_POS)
#define RATE_MCS_SGI_POS RATE_MCS_HE_GI_LTF_POS
#define RATE_MCS_SGI_MSK (1 << RATE_MCS_SGI_POS)
#define RATE_MCS_HE_SU_4_LTF 3
#define RATE_MCS_HE_SU_4_LTF_08_GI 4
/* Bit 24-23: HE type. (0) SU, (1) SU_EXT, (2) MU, (3) trigger based */
#define RATE_MCS_HE_TYPE_POS 23
#define RATE_MCS_HE_TYPE_SU (0 << RATE_MCS_HE_TYPE_POS)
#define RATE_MCS_HE_TYPE_EXT_SU (1 << RATE_MCS_HE_TYPE_POS)
#define RATE_MCS_HE_TYPE_MU (2 << RATE_MCS_HE_TYPE_POS)
#define RATE_MCS_HE_TYPE_TRIG (3 << RATE_MCS_HE_TYPE_POS)
#define RATE_MCS_HE_TYPE_MSK (3 << RATE_MCS_HE_TYPE_POS)
/* Bit 25: duplicate channel enabled
*
* if this bit is set, duplicate is according to BW (bits 11-13):
*
* CCK: 2x 20MHz
* OFDM Legacy: N x 20Mhz, (N = BW \ 2 , either 2, 4, 8, 16)
* EHT: 2 x BW/2, (80 - 2x40, 160 - 2x80, 320 - 2x160)
* */
#define RATE_MCS_DUP_POS 25
#define RATE_MCS_DUP_MSK (1 << RATE_MCS_DUP_POS)
/* Bit 26: (1) 106-tone RX (8 MHz RU), (0) normal bandwidth */
#define RATE_MCS_HE_106T_POS 26
#define RATE_MCS_HE_106T_MSK (1 << RATE_MCS_HE_106T_POS)
/* Bit 27: EHT extra LTF:
* instead of 1 LTF for SISO use 2 LTFs,
* instead of 2 LTFs for NSTS=2 use 4 LTFs*/
#define RATE_MCS_EHT_EXTRA_LTF_POS 27
#define RATE_MCS_EHT_EXTRA_LTF_MSK (1 << RATE_MCS_EHT_EXTRA_LTF_POS)
/* Bit 31-28: reserved */
/* Link Quality definitions */
/* # entries in rate scale table to support Tx retries */
@ -557,4 +708,13 @@ struct iwl_lq_cmd {
__le32 ss_params;
}; /* LINK_QUALITY_CMD_API_S_VER_1 */
u8 iwl_fw_rate_idx_to_plcp(int idx);
u32 iwl_new_rate_from_v1(u32 rate_v1);
u32 iwl_legacy_rate_to_fw_idx(u32 rate_n_flags);
const struct iwl_rate_mcs_info *iwl_rate_mcs(int idx);
const char *iwl_rs_pretty_ant(u8 ant);
const char *iwl_rs_pretty_bw(int bw);
int rs_pretty_print_rate(char *buf, int bufsz, const u32 rate);
bool iwl_he_is_sgi(u32 rate_n_flags);
#endif /* __iwl_fw_api_rs_h__ */

Просмотреть файл

@ -1,6 +1,6 @@
/* SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause */
/*
* Copyright (C) 2012-2014, 2018-2020 Intel Corporation
* Copyright (C) 2012-2014, 2018-2021 Intel Corporation
* Copyright (C) 2013-2015 Intel Mobile Communications GmbH
* Copyright (C) 2015-2017 Intel Deutschland GmbH
*/
@ -13,7 +13,6 @@
#define IWL_RX_INFO_ENERGY_ANT_ABC_IDX 1
#define IWL_RX_INFO_ENERGY_ANT_A_MSK 0x000000ff
#define IWL_RX_INFO_ENERGY_ANT_B_MSK 0x0000ff00
#define IWL_RX_INFO_ENERGY_ANT_C_MSK 0x00ff0000
#define IWL_RX_INFO_ENERGY_ANT_A_POS 0
#define IWL_RX_INFO_ENERGY_ANT_B_POS 8
#define IWL_RX_INFO_ENERGY_ANT_C_POS 16
@ -126,14 +125,12 @@ enum iwl_rx_phy_flags {
* @RX_MPDU_RES_STATUS_OVERRUN_OK: there was no RXE overflow
* @RX_MPDU_RES_STATUS_SRC_STA_FOUND: station was found
* @RX_MPDU_RES_STATUS_KEY_VALID: key was valid
* @RX_MPDU_RES_STATUS_KEY_PARAM_OK: key parameters were usable
* @RX_MPDU_RES_STATUS_ICV_OK: ICV is fine, if not, the packet is destroyed
* @RX_MPDU_RES_STATUS_MIC_OK: used for CCM alg only. TKIP MIC is checked
* in the driver.
* @RX_MPDU_RES_STATUS_TTAK_OK: TTAK is fine
* @RX_MPDU_RES_STATUS_MNG_FRAME_REPLAY_ERR: valid for alg = CCM_CMAC or
* alg = CCM only. Checks replay attack for 11w frames. Relevant only if
* %RX_MPDU_RES_STATUS_ROBUST_MNG_FRAME is set.
* alg = CCM only. Checks replay attack for 11w frames.
* @RX_MPDU_RES_STATUS_SEC_NO_ENC: this frame is not encrypted
* @RX_MPDU_RES_STATUS_SEC_WEP_ENC: this frame is encrypted using WEP
* @RX_MPDU_RES_STATUS_SEC_CCM_ENC: this frame is encrypted using CCM
@ -145,9 +142,6 @@ enum iwl_rx_phy_flags {
* @RX_MPDU_RES_STATUS_SEC_ENC_ERR: this frame couldn't be decrypted
* @RX_MPDU_RES_STATUS_SEC_ENC_MSK: bitmask of the encryption algorithm
* @RX_MPDU_RES_STATUS_DEC_DONE: this frame has been successfully decrypted
* @RX_MPDU_RES_STATUS_EXT_IV_BIT_CMP: extended IV (set with TKIP)
* @RX_MPDU_RES_STATUS_KEY_ID_CMP_BIT: key ID comparison done
* @RX_MPDU_RES_STATUS_ROBUST_MNG_FRAME: this frame is an 11w management frame
* @RX_MPDU_RES_STATUS_CSUM_DONE: checksum was done by the hw
* @RX_MPDU_RES_STATUS_CSUM_OK: checksum found no errors
* @RX_MPDU_RES_STATUS_STA_ID_MSK: station ID mask
@ -158,7 +152,6 @@ enum iwl_mvm_rx_status {
RX_MPDU_RES_STATUS_OVERRUN_OK = BIT(1),
RX_MPDU_RES_STATUS_SRC_STA_FOUND = BIT(2),
RX_MPDU_RES_STATUS_KEY_VALID = BIT(3),
RX_MPDU_RES_STATUS_KEY_PARAM_OK = BIT(4),
RX_MPDU_RES_STATUS_ICV_OK = BIT(5),
RX_MPDU_RES_STATUS_MIC_OK = BIT(6),
RX_MPDU_RES_STATUS_TTAK_OK = BIT(7),
@ -172,9 +165,6 @@ enum iwl_mvm_rx_status {
RX_MPDU_RES_STATUS_SEC_ENC_ERR = (7 << 8),
RX_MPDU_RES_STATUS_SEC_ENC_MSK = (7 << 8),
RX_MPDU_RES_STATUS_DEC_DONE = BIT(11),
RX_MPDU_RES_STATUS_EXT_IV_BIT_CMP = BIT(13),
RX_MPDU_RES_STATUS_KEY_ID_CMP_BIT = BIT(14),
RX_MPDU_RES_STATUS_ROBUST_MNG_FRAME = BIT(15),
RX_MPDU_RES_STATUS_CSUM_DONE = BIT(16),
RX_MPDU_RES_STATUS_CSUM_OK = BIT(17),
RX_MDPU_RES_STATUS_STA_ID_SHIFT = 24,
@ -236,7 +226,6 @@ enum iwl_rx_mpdu_status {
IWL_RX_MPDU_STATUS_OVERRUN_OK = BIT(1),
IWL_RX_MPDU_STATUS_SRC_STA_FOUND = BIT(2),
IWL_RX_MPDU_STATUS_KEY_VALID = BIT(3),
IWL_RX_MPDU_STATUS_KEY_PARAM_OK = BIT(4),
IWL_RX_MPDU_STATUS_ICV_OK = BIT(5),
IWL_RX_MPDU_STATUS_MIC_OK = BIT(6),
IWL_RX_MPDU_RES_STATUS_TTAK_OK = BIT(7),
@ -251,12 +240,8 @@ enum iwl_rx_mpdu_status {
IWL_RX_MPDU_STATUS_SEC_EXT_ENC = 0x4 << 8,
IWL_RX_MPDU_STATUS_SEC_GCM = 0x5 << 8,
IWL_RX_MPDU_STATUS_DECRYPTED = BIT(11),
IWL_RX_MPDU_STATUS_WEP_MATCH = BIT(12),
IWL_RX_MPDU_STATUS_EXT_IV_MATCH = BIT(13),
IWL_RX_MPDU_STATUS_KEY_ID_MATCH = BIT(14),
IWL_RX_MPDU_STATUS_ROBUST_MNG_FRAME = BIT(15),
IWL_RX_MPDU_STATUS_KEY = 0x3f0000,
IWL_RX_MPDU_STATUS_DUPLICATE = BIT(22),
IWL_RX_MPDU_STATUS_STA_ID = 0x1f000000,
@ -460,7 +445,7 @@ struct iwl_rx_mpdu_desc_v1 {
__le32 phy_data1;
};
};
} __packed;
} __packed; /* RX_MPDU_RES_START_API_S_VER_4 */
/**
* struct iwl_rx_mpdu_desc_v3 - RX MPDU descriptor
@ -560,7 +545,8 @@ struct iwl_rx_mpdu_desc_v3 {
* @reserved: reserved
*/
__le32 reserved[2];
} __packed; /* RX_MPDU_RES_START_API_S_VER_3 */
} __packed; /* RX_MPDU_RES_START_API_S_VER_3,
RX_MPDU_RES_START_API_S_VER_5 */
/**
* struct iwl_rx_mpdu_desc - RX MPDU descriptor
@ -625,7 +611,9 @@ struct iwl_rx_mpdu_desc {
struct iwl_rx_mpdu_desc_v1 v1;
struct iwl_rx_mpdu_desc_v3 v3;
};
} __packed; /* RX_MPDU_RES_START_API_S_VER_3 */
} __packed; /* RX_MPDU_RES_START_API_S_VER_3,
RX_MPDU_RES_START_API_S_VER_4,
RX_MPDU_RES_START_API_S_VER_5 */
#define IWL_RX_DESC_SIZE_V1 offsetofend(struct iwl_rx_mpdu_desc, v1)
@ -679,7 +667,8 @@ struct iwl_rx_no_data {
__le32 rate;
__le32 phy_info[2];
__le32 rx_vec[2];
} __packed; /* RX_NO_DATA_NTFY_API_S_VER_1 */
} __packed; /* RX_NO_DATA_NTFY_API_S_VER_1,
TX_NO_DATA_NTFY_API_S_VER_2 */
struct iwl_frame_release {
u8 baid;

Просмотреть файл

@ -28,6 +28,8 @@
* @STA_FLG_MAX_AGG_SIZE_256K: maximal size for A-MPDU (256k supported)
* @STA_FLG_MAX_AGG_SIZE_512K: maximal size for A-MPDU (512k supported)
* @STA_FLG_MAX_AGG_SIZE_1024K: maximal size for A-MPDU (1024k supported)
* @STA_FLG_MAX_AGG_SIZE_2M: maximal size for A-MPDU (2M supported)
* @STA_FLG_MAX_AGG_SIZE_4M: maximal size for A-MPDU (4M supported)
* @STA_FLG_AGG_MPDU_DENS_MSK: maximal MPDU density for Tx aggregation
* @STA_FLG_FAT_EN_MSK: support for channel width (for Tx). This flag is
* initialised by driver and can be updated by fw upon reception of

Просмотреть файл

@ -1,6 +1,6 @@
/* SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause */
/*
* Copyright (C) 2012-2014, 2018-2020 Intel Corporation
* Copyright (C) 2012-2014, 2018-2021 Intel Corporation
* Copyright (C) 2016-2017 Intel Deutschland GmbH
*/
#ifndef __iwl_fw_api_tx_h__
@ -81,6 +81,10 @@ enum iwl_tx_cmd_flags {
IWL_TX_FLAGS_CMD_RATE = BIT(0),
IWL_TX_FLAGS_ENCRYPT_DIS = BIT(1),
IWL_TX_FLAGS_HIGH_PRI = BIT(2),
/* Use these flags only from
* TX_FLAGS_BITS_API_S_VER_4 and above */
IWL_TX_FLAGS_RTS = BIT(3),
IWL_TX_FLAGS_CTS = BIT(4),
}; /* TX_FLAGS_BITS_API_S_VER_3 */
/**
@ -267,7 +271,8 @@ struct iwl_tx_cmd_gen2 {
struct iwl_dram_sec_info dram_info;
__le32 rate_n_flags;
struct ieee80211_hdr hdr[];
} __packed; /* TX_CMD_API_S_VER_7 */
} __packed; /* TX_CMD_API_S_VER_7,
TX_CMD_API_S_VER_9 */
/**
* struct iwl_tx_cmd_gen3 - TX command struct to FW for AX210+ devices
@ -290,7 +295,8 @@ struct iwl_tx_cmd_gen3 {
__le32 rate_n_flags;
__le64 ttl;
struct ieee80211_hdr hdr[];
} __packed; /* TX_CMD_API_S_VER_8 */
} __packed; /* TX_CMD_API_S_VER_8,
TX_CMD_API_S_VER_10 */
/*
* TX response related data
@ -591,7 +597,8 @@ struct iwl_mvm_tx_resp {
__le16 tx_queue;
__le16 reserved2;
struct agg_tx_status status;
} __packed; /* TX_RSP_API_S_VER_6 */
} __packed; /* TX_RSP_API_S_VER_6,
TX_RSP_API_S_VER_7 */
/**
* struct iwl_mvm_ba_notif - notifies about reception of BA
@ -715,7 +722,8 @@ struct iwl_mvm_compressed_ba_notif {
__le16 ra_tid_cnt;
struct iwl_mvm_compressed_ba_ratid ra_tid[0];
struct iwl_mvm_compressed_ba_tfd tfd[];
} __packed; /* COMPRESSED_BA_RES_API_S_VER_4 */
} __packed; /* COMPRESSED_BA_RES_API_S_VER_4,
COMPRESSED_BA_RES_API_S_VER_5 */
/**
* struct iwl_mac_beacon_cmd_v6 - beacon template command
@ -755,12 +763,20 @@ struct iwl_mac_beacon_cmd_v7 {
struct ieee80211_hdr frame[];
} __packed; /* BEACON_TEMPLATE_CMD_API_S_VER_7 */
/* Bit flags for BEACON_TEMPLATE_CMD_API until version 10 */
enum iwl_mac_beacon_flags_v1 {
IWL_MAC_BEACON_CCK_V1 = BIT(8),
IWL_MAC_BEACON_ANT_A_V1 = BIT(9),
IWL_MAC_BEACON_ANT_B_V1 = BIT(10),
IWL_MAC_BEACON_FILS_V1 = BIT(12),
};
/* Bit flags for BEACON_TEMPLATE_CMD_API version 11 and above */
enum iwl_mac_beacon_flags {
IWL_MAC_BEACON_CCK = BIT(8),
IWL_MAC_BEACON_ANT_A = BIT(9),
IWL_MAC_BEACON_ANT_B = BIT(10),
IWL_MAC_BEACON_ANT_C = BIT(11),
IWL_MAC_BEACON_FILS = BIT(12),
IWL_MAC_BEACON_CCK = BIT(5),
IWL_MAC_BEACON_ANT_A = BIT(6),
IWL_MAC_BEACON_ANT_B = BIT(7),
IWL_MAC_BEACON_FILS = BIT(8),
};
/**
@ -788,7 +804,9 @@ struct iwl_mac_beacon_cmd {
__le32 ecsa_offset;
__le32 csa_offset;
struct ieee80211_hdr frame[];
} __packed; /* BEACON_TEMPLATE_CMD_API_S_VER_10 */
} __packed; /* BEACON_TEMPLATE_CMD_API_S_VER_10,
BEACON_TEMPLATE_CMD_API_S_VER_11,
BEACON_TEMPLATE_CMD_API_S_VER_12 */
struct iwl_beacon_notif {
struct iwl_mvm_tx_resp beacon_notify_hdr;

Просмотреть файл

@ -159,11 +159,15 @@ static void iwl_fwrt_dump_txf(struct iwl_fw_runtime *fwrt,
iwl_trans_read_prph(fwrt->trans, TXF_READ_MODIFY_DATA + offset);
/* Read FIFO */
fifo_len /= sizeof(u32); /* Size in DWORDS */
for (i = 0; i < fifo_len; i++)
for (i = 0; i < fifo_len / sizeof(u32); i++)
fifo_data[i] = iwl_trans_read_prph(fwrt->trans,
TXF_READ_MODIFY_DATA +
offset);
if (fwrt->sanitize_ops && fwrt->sanitize_ops->frob_txf)
fwrt->sanitize_ops->frob_txf(fwrt->sanitize_ctx,
fifo_data, fifo_len);
*dump_data = iwl_fw_error_next_data(*dump_data);
}
@ -659,6 +663,10 @@ static void iwl_fw_dump_mem(struct iwl_fw_runtime *fwrt,
iwl_trans_read_mem_bytes(fwrt->trans, ofs, dump_mem->data, len);
*dump_data = iwl_fw_error_next_data(*dump_data);
if (fwrt->sanitize_ops && fwrt->sanitize_ops->frob_mem)
fwrt->sanitize_ops->frob_mem(fwrt->sanitize_ctx, ofs,
dump_mem->data, len);
IWL_DEBUG_INFO(fwrt, "WRT memory dump. Type=%u\n", dump_mem->type);
}
@ -752,6 +760,12 @@ static void iwl_dump_paging(struct iwl_fw_runtime *fwrt,
PAGING_BLOCK_SIZE,
DMA_BIDIRECTIONAL);
(*data) = iwl_fw_error_next_data(*data);
if (fwrt->sanitize_ops && fwrt->sanitize_ops->frob_mem)
fwrt->sanitize_ops->frob_mem(fwrt->sanitize_ctx,
fwrt->fw_paging_db[i].fw_offs,
paging->data,
PAGING_BLOCK_SIZE);
}
}
@ -980,6 +994,11 @@ iwl_fw_error_dump_file(struct iwl_fw_runtime *fwrt,
dump_data->data + data_size,
data_size);
if (fwrt->sanitize_ops && fwrt->sanitize_ops->frob_mem)
fwrt->sanitize_ops->frob_mem(fwrt->sanitize_ctx, addr,
dump_data->data + data_size,
data_size);
dump_data = iwl_fw_error_next_data(dump_data);
}
@ -1146,6 +1165,13 @@ static int iwl_dump_ini_dev_mem_iter(struct iwl_fw_runtime *fwrt,
iwl_trans_read_mem_bytes(fwrt->trans, addr, range->data,
le32_to_cpu(reg->dev_addr.size));
if ((le32_to_cpu(reg->id) & IWL_FW_INI_REGION_V2_MASK) ==
IWL_FW_INI_HW_SMEM_REGION_ID &&
fwrt->sanitize_ops && fwrt->sanitize_ops->frob_txf)
fwrt->sanitize_ops->frob_txf(fwrt->sanitize_ctx,
range->data,
le32_to_cpu(reg->dev_addr.size));
return sizeof(*range) + le32_to_cpu(range->range_data_size);
}
@ -1338,6 +1364,10 @@ static int iwl_dump_ini_txf_iter(struct iwl_fw_runtime *fwrt,
for (i = 0; i < iter->fifo_size; i += sizeof(*data))
*data++ = cpu_to_le32(iwl_read_prph_no_grab(fwrt->trans, addr));
if (fwrt->sanitize_ops && fwrt->sanitize_ops->frob_txf)
fwrt->sanitize_ops->frob_txf(fwrt->sanitize_ctx,
reg_dump, iter->fifo_size);
out:
iwl_trans_release_nic_access(fwrt->trans);
@ -2077,7 +2107,7 @@ static u32 iwl_dump_ini_info(struct iwl_fw_runtime *fwrt,
*/
hw_type = CSR_HW_REV_TYPE(fwrt->trans->hw_rev);
if (hw_type == IWL_AX210_HW_TYPE) {
u32 prph_val = iwl_read_prph(fwrt->trans, WFPM_OTP_CFG1_ADDR);
u32 prph_val = iwl_read_prph(fwrt->trans, WFPM_OTP_CFG1_ADDR_GEN2);
u32 is_jacket = !!(prph_val & WFPM_OTP_CFG1_IS_JACKET_BIT);
u32 is_cdb = !!(prph_val & WFPM_OTP_CFG1_IS_CDB_BIT);
u32 masked_bits = is_jacket | (is_cdb << 1);
@ -2360,7 +2390,9 @@ static void iwl_fw_error_dump(struct iwl_fw_runtime *fwrt,
if (dump_data->monitor_only)
dump_mask &= BIT(IWL_FW_ERROR_DUMP_FW_MONITOR);
fw_error_dump.trans_ptr = iwl_trans_dump_data(fwrt->trans, dump_mask);
fw_error_dump.trans_ptr = iwl_trans_dump_data(fwrt->trans, dump_mask,
fwrt->sanitize_ops,
fwrt->sanitize_ctx);
file_len = le32_to_cpu(dump_file->file_len);
fw_error_dump.fwrt_len = file_len;
@ -2788,6 +2820,12 @@ void iwl_fw_dbg_read_d3_debug_data(struct iwl_fw_runtime *fwrt)
iwl_trans_read_mem_bytes(fwrt->trans, cfg->d3_debug_data_base_addr,
fwrt->dump.d3_debug_data,
cfg->d3_debug_data_length);
if (fwrt->sanitize_ops && fwrt->sanitize_ops->frob_mem)
fwrt->sanitize_ops->frob_mem(fwrt->sanitize_ctx,
cfg->d3_debug_data_base_addr,
fwrt->dump.d3_debug_data,
cfg->d3_debug_data_length);
}
IWL_EXPORT_SYMBOL(iwl_fw_dbg_read_d3_debug_data);

Просмотреть файл

@ -214,7 +214,7 @@ static void iwl_fwrt_dump_lmac_error_log(struct iwl_fw_runtime *fwrt, u8 lmac_nu
/* reset the device */
iwl_trans_sw_reset(trans);
err = iwl_finish_nic_init(trans, trans->trans_cfg);
err = iwl_finish_nic_init(trans);
if (err)
return;
}
@ -328,6 +328,13 @@ static void iwl_fwrt_dump_tcm_error_log(struct iwl_fw_runtime *fwrt)
for (i = 0; i < ARRAY_SIZE(table.sw_status); i++)
IWL_ERR(fwrt, "0x%08X | tcm SW status[%d]\n",
table.sw_status[i], i);
if (trans->trans_cfg->device_family >= IWL_DEVICE_FAMILY_BZ) {
u32 scratch = iwl_read32(trans, CSR_FUNC_SCRATCH);
IWL_ERR(fwrt, "Function Scratch status:\n");
IWL_ERR(fwrt, "0x%08X | Func Scratch\n", scratch);
}
}
static void iwl_fwrt_dump_iml_error_log(struct iwl_fw_runtime *fwrt)

Просмотреть файл

@ -342,10 +342,6 @@ struct iwl_fw_ini_dump_cfg_name {
#define IWL_AX210_HW_TYPE 0x42
/* How many bits to roll when adding to the HW type of AX210 HW */
#define IWL_AX210_HW_TYPE_ADDITION_SHIFT 12
/* This prph is used to tell apart HW_TYPE == 0x42 NICs */
#define WFPM_OTP_CFG1_ADDR 0xd03098
#define WFPM_OTP_CFG1_IS_JACKET_BIT BIT(4)
#define WFPM_OTP_CFG1_IS_CDB_BIT BIT(5)
/* struct iwl_fw_ini_dump_info - ini dump information
* @version: dump version

Просмотреть файл

@ -100,6 +100,9 @@ enum iwl_ucode_tlv_type {
IWL_UCODE_TLV_PNVM_SKU = 64,
IWL_UCODE_TLV_TCM_DEBUG_ADDRS = 65,
IWL_UCODE_TLV_SEC_TABLE_ADDR = 66,
IWL_UCODE_TLV_D3_KEK_KCK_ADDR = 67,
IWL_UCODE_TLV_FW_NUM_STATIONS = IWL_UCODE_TLV_CONST_BASE + 0,
IWL_UCODE_TLV_TYPE_DEBUG_INFO = IWL_UCODE_TLV_DEBUG_BASE + 0,
@ -107,6 +110,7 @@ enum iwl_ucode_tlv_type {
IWL_UCODE_TLV_TYPE_HCMD = IWL_UCODE_TLV_DEBUG_BASE + 2,
IWL_UCODE_TLV_TYPE_REGIONS = IWL_UCODE_TLV_DEBUG_BASE + 3,
IWL_UCODE_TLV_TYPE_TRIGGERS = IWL_UCODE_TLV_DEBUG_BASE + 4,
IWL_UCODE_TLV_TYPE_CONF_SET = IWL_UCODE_TLV_DEBUG_BASE + 5,
IWL_UCODE_TLV_DEBUG_MAX = IWL_UCODE_TLV_TYPE_TRIGGERS,
/* TLVs 0x1000-0x2000 are for internal driver usage */
@ -416,6 +420,8 @@ enum iwl_ucode_tlv_capa {
IWL_UCODE_TLV_CAPA_PASSIVE_6GHZ_SCAN = (__force iwl_ucode_tlv_capa_t)58,
IWL_UCODE_TLV_CAPA_HIDDEN_6GHZ_SCAN = (__force iwl_ucode_tlv_capa_t)59,
IWL_UCODE_TLV_CAPA_BROADCAST_TWT = (__force iwl_ucode_tlv_capa_t)60,
IWL_UCODE_TLV_CAPA_COEX_HIGH_PRIO = (__force iwl_ucode_tlv_capa_t)61,
IWL_UCODE_TLV_CAPA_RFIM_SUPPORT = (__force iwl_ucode_tlv_capa_t)62,
/* set 2 */
IWL_UCODE_TLV_CAPA_EXTENDED_DTS_MEASURE = (__force iwl_ucode_tlv_capa_t)64,
@ -449,7 +455,7 @@ enum iwl_ucode_tlv_capa {
IWL_UCODE_TLV_CAPA_PSC_CHAN_SUPPORT = (__force iwl_ucode_tlv_capa_t)98,
IWL_UCODE_TLV_CAPA_BIGTK_SUPPORT = (__force iwl_ucode_tlv_capa_t)100,
IWL_UCODE_TLV_CAPA_RFIM_SUPPORT = (__force iwl_ucode_tlv_capa_t)102,
IWL_UCODE_TLV_CAPA_DRAM_FRAG_SUPPORT = (__force iwl_ucode_tlv_capa_t)104,
#ifdef __CHECKER__
/* sparse says it cannot increment the previous enum member */
@ -956,6 +962,10 @@ struct iwl_fw_tcm_error_addr {
__le32 addr;
}; /* FW_TLV_TCM_ERROR_INFO_ADDRS_S */
struct iwl_fw_dump_exclude {
__le32 addr, size;
};
static inline size_t _iwl_tlv_array_len(const struct iwl_ucode_tlv *tlv,
size_t fixed_size, size_t var_size)
{

Просмотреть файл

@ -1,59 +1,7 @@
/******************************************************************************
*
* This file is provided under a dual BSD/GPLv2 license. When using or
* redistributing this file, you may do so under either license.
*
* GPL LICENSE SUMMARY
*
// SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause
/*
* Copyright(c) 2019 - 2020 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
* published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
*
* The full GNU General Public License is included in this distribution
* in the file called COPYING.
*
* Contact Information:
* Intel Linux Wireless <linuxwifi@intel.com>
* Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
*
* BSD LICENSE
*
* Copyright(c) 2019 - 2020 Intel Corporation
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
* * Neither the name Intel Corporation nor the names of its
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*****************************************************************************/
*/
#include "img.h"

Просмотреть файл

@ -124,11 +124,13 @@ struct fw_img {
* @fw_paging_phys: page phy pointer
* @fw_paging_block: pointer to the allocated block
* @fw_paging_size: page size
* @fw_offs: offset in the device
*/
struct iwl_fw_paging {
dma_addr_t fw_paging_phys;
struct page *fw_paging_block;
u32 fw_paging_size;
u32 fw_offs;
};
/**
@ -174,6 +176,10 @@ struct iwl_fw_dbg {
u32 dump_mask;
};
struct iwl_dump_exclude {
u32 addr, size;
};
/**
* struct iwl_fw - variables associated with the firmware
*
@ -194,6 +200,10 @@ struct iwl_fw_dbg {
* @cipher_scheme: optional external cipher scheme.
* @human_readable: human readable version
* we get the ALIVE from the uCode
* @phy_integration_ver: PHY integration version string
* @phy_integration_ver_len: length of @phy_integration_ver
* @dump_excl: image dump exclusion areas for RT image
* @dump_excl_wowlan: image dump exclusion areas for WoWLAN image
*/
struct iwl_fw {
u32 ucode_ver;
@ -225,6 +235,8 @@ struct iwl_fw {
u8 *phy_integration_ver;
u32 phy_integration_ver_len;
struct iwl_dump_exclude dump_excl[2], dump_excl_wowlan[2];
};
static inline const char *get_fw_dbg_mode_string(int mode)

Просмотреть файл

@ -1,7 +1,7 @@
// SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause
/*
* Copyright (C) 2017 Intel Deutschland GmbH
* Copyright (C) 2019-2020 Intel Corporation
* Copyright (C) 2019-2021 Intel Corporation
*/
#include "iwl-drv.h"
#include "runtime.h"
@ -16,6 +16,8 @@
void iwl_fw_runtime_init(struct iwl_fw_runtime *fwrt, struct iwl_trans *trans,
const struct iwl_fw *fw,
const struct iwl_fw_runtime_ops *ops, void *ops_ctx,
const struct iwl_dump_sanitize_ops *sanitize_ops,
void *sanitize_ctx,
struct dentry *dbgfs_dir)
{
int i;
@ -26,6 +28,8 @@ void iwl_fw_runtime_init(struct iwl_fw_runtime *fwrt, struct iwl_trans *trans,
fwrt->dev = trans->dev;
fwrt->dump.conf = FW_DBG_INVALID;
fwrt->ops = ops;
fwrt->sanitize_ops = sanitize_ops;
fwrt->sanitize_ctx = sanitize_ctx;
fwrt->ops_ctx = ops_ctx;
for (i = 0; i < IWL_FW_RUNTIME_DUMP_WK_NUM; i++) {
fwrt->dump.wks[i].idx = i;

Просмотреть файл

@ -1,6 +1,6 @@
// SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause
/*
* Copyright (C) 2012-2014, 2018-2019 Intel Corporation
* Copyright (C) 2012-2014, 2018-2019, 2021 Intel Corporation
* Copyright (C) 2013-2015 Intel Mobile Communications GmbH
* Copyright (C) 2016-2017 Intel Deutschland GmbH
*/
@ -152,6 +152,7 @@ static int iwl_fill_paging_mem(struct iwl_fw_runtime *fwrt,
memcpy(page_address(fwrt->fw_paging_db[0].fw_paging_block),
image->sec[sec_idx].data,
image->sec[sec_idx].len);
fwrt->fw_paging_db[0].fw_offs = image->sec[sec_idx].offset;
dma_sync_single_for_device(fwrt->trans->dev,
fwrt->fw_paging_db[0].fw_paging_phys,
fwrt->fw_paging_db[0].fw_paging_size,
@ -197,6 +198,7 @@ static int iwl_fill_paging_mem(struct iwl_fw_runtime *fwrt,
memcpy(page_address(block->fw_paging_block),
image->sec[sec_idx].data + offset, len);
block->fw_offs = image->sec[sec_idx].offset + offset;
dma_sync_single_for_device(fwrt->trans->dev,
block->fw_paging_phys,
block->fw_paging_size,

Просмотреть файл

@ -162,7 +162,7 @@ done:
goto out;
}
IWL_INFO(trans, "loaded PNVM version 0x%0x\n", sha1);
IWL_INFO(trans, "loaded PNVM version %08x\n", sha1);
ret = iwl_trans_set_pnvm(trans, pnvm_data, size);
out:

Просмотреть файл

@ -0,0 +1,252 @@
// SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause
/*
* Copyright (C) 2021 Intel Corporation
*/
#include <net/mac80211.h>
#include "fw/api/rs.h"
#include "iwl-drv.h"
#include "iwl-config.h"
#define IWL_DECLARE_RATE_INFO(r) \
[IWL_RATE_##r##M_INDEX] = IWL_RATE_##r##M_PLCP
/*
* Translate from fw_rate_index (IWL_RATE_XXM_INDEX) to PLCP
* */
static const u8 fw_rate_idx_to_plcp[IWL_RATE_COUNT] = {
IWL_DECLARE_RATE_INFO(1),
IWL_DECLARE_RATE_INFO(2),
IWL_DECLARE_RATE_INFO(5),
IWL_DECLARE_RATE_INFO(11),
IWL_DECLARE_RATE_INFO(6),
IWL_DECLARE_RATE_INFO(9),
IWL_DECLARE_RATE_INFO(12),
IWL_DECLARE_RATE_INFO(18),
IWL_DECLARE_RATE_INFO(24),
IWL_DECLARE_RATE_INFO(36),
IWL_DECLARE_RATE_INFO(48),
IWL_DECLARE_RATE_INFO(54),
};
/* mbps, mcs */
static const struct iwl_rate_mcs_info rate_mcs[IWL_RATE_COUNT] = {
{ "1", "BPSK DSSS"},
{ "2", "QPSK DSSS"},
{"5.5", "BPSK CCK"},
{ "11", "QPSK CCK"},
{ "6", "BPSK 1/2"},
{ "9", "BPSK 1/2"},
{ "12", "QPSK 1/2"},
{ "18", "QPSK 3/4"},
{ "24", "16QAM 1/2"},
{ "36", "16QAM 3/4"},
{ "48", "64QAM 2/3"},
{ "54", "64QAM 3/4"},
{ "60", "64QAM 5/6"},
};
static const char * const ant_name[] = {
[ANT_NONE] = "None",
[ANT_A] = "A",
[ANT_B] = "B",
[ANT_AB] = "AB",
};
static const char * const pretty_bw[] = {
"20Mhz",
"40Mhz",
"80Mhz",
"160 Mhz",
"320Mhz",
};
u8 iwl_fw_rate_idx_to_plcp(int idx)
{
return fw_rate_idx_to_plcp[idx];
}
IWL_EXPORT_SYMBOL(iwl_fw_rate_idx_to_plcp);
const struct iwl_rate_mcs_info *iwl_rate_mcs(int idx)
{
return &rate_mcs[idx];
}
IWL_EXPORT_SYMBOL(iwl_rate_mcs);
const char *iwl_rs_pretty_ant(u8 ant)
{
if (ant >= ARRAY_SIZE(ant_name))
return "UNKNOWN";
return ant_name[ant];
}
IWL_EXPORT_SYMBOL(iwl_rs_pretty_ant);
const char *iwl_rs_pretty_bw(int bw)
{
if (bw >= ARRAY_SIZE(pretty_bw))
return "unknown bw";
return pretty_bw[bw];
}
IWL_EXPORT_SYMBOL(iwl_rs_pretty_bw);
u32 iwl_new_rate_from_v1(u32 rate_v1)
{
u32 rate_v2 = 0;
u32 dup = 0;
if (rate_v1 == 0)
return rate_v1;
/* convert rate */
if (rate_v1 & RATE_MCS_HT_MSK_V1) {
u32 nss = 0;
rate_v2 |= RATE_MCS_HT_MSK;
rate_v2 |=
rate_v1 & RATE_HT_MCS_RATE_CODE_MSK_V1;
nss = (rate_v1 & RATE_HT_MCS_MIMO2_MSK) >>
RATE_HT_MCS_NSS_POS_V1;
rate_v2 |= nss << RATE_MCS_NSS_POS;
} else if (rate_v1 & RATE_MCS_VHT_MSK_V1 ||
rate_v1 & RATE_MCS_HE_MSK_V1) {
rate_v2 |= rate_v1 & RATE_VHT_MCS_RATE_CODE_MSK;
rate_v2 |= rate_v1 & RATE_VHT_MCS_MIMO2_MSK;
if (rate_v1 & RATE_MCS_HE_MSK_V1) {
u32 he_type_bits = rate_v1 & RATE_MCS_HE_TYPE_MSK_V1;
u32 he_type = he_type_bits >> RATE_MCS_HE_TYPE_POS_V1;
u32 he_106t = (rate_v1 & RATE_MCS_HE_106T_MSK_V1) >>
RATE_MCS_HE_106T_POS_V1;
u32 he_gi_ltf = (rate_v1 & RATE_MCS_HE_GI_LTF_MSK_V1) >>
RATE_MCS_HE_GI_LTF_POS;
if ((he_type_bits == RATE_MCS_HE_TYPE_SU ||
he_type_bits == RATE_MCS_HE_TYPE_EXT_SU) &&
he_gi_ltf == RATE_MCS_HE_SU_4_LTF)
/* the new rate have an additional bit to
* represent the value 4 rather then using SGI
* bit for this purpose - as it was done in the old
* rate */
he_gi_ltf += (rate_v1 & RATE_MCS_SGI_MSK_V1) >>
RATE_MCS_SGI_POS_V1;
rate_v2 |= he_gi_ltf << RATE_MCS_HE_GI_LTF_POS;
rate_v2 |= he_type << RATE_MCS_HE_TYPE_POS;
rate_v2 |= he_106t << RATE_MCS_HE_106T_POS;
rate_v2 |= rate_v1 & RATE_HE_DUAL_CARRIER_MODE_MSK;
rate_v2 |= RATE_MCS_HE_MSK;
} else {
rate_v2 |= RATE_MCS_VHT_MSK;
}
/* if legacy format */
} else {
u32 legacy_rate = iwl_legacy_rate_to_fw_idx(rate_v1);
WARN_ON(legacy_rate < 0);
rate_v2 |= legacy_rate;
if (!(rate_v1 & RATE_MCS_CCK_MSK_V1))
rate_v2 |= RATE_MCS_LEGACY_OFDM_MSK;
}
/* convert flags */
if (rate_v1 & RATE_MCS_LDPC_MSK_V1)
rate_v2 |= RATE_MCS_LDPC_MSK;
rate_v2 |= (rate_v1 & RATE_MCS_CHAN_WIDTH_MSK_V1) |
(rate_v1 & RATE_MCS_ANT_AB_MSK) |
(rate_v1 & RATE_MCS_STBC_MSK) |
(rate_v1 & RATE_MCS_BF_MSK);
dup = (rate_v1 & RATE_MCS_DUP_MSK_V1) >> RATE_MCS_DUP_POS_V1;
if (dup) {
rate_v2 |= RATE_MCS_DUP_MSK;
rate_v2 |= dup << RATE_MCS_CHAN_WIDTH_POS;
}
if ((!(rate_v1 & RATE_MCS_HE_MSK_V1)) &&
(rate_v1 & RATE_MCS_SGI_MSK_V1))
rate_v2 |= RATE_MCS_SGI_MSK;
return rate_v2;
}
IWL_EXPORT_SYMBOL(iwl_new_rate_from_v1);
u32 iwl_legacy_rate_to_fw_idx(u32 rate_n_flags)
{
int rate = rate_n_flags & RATE_LEGACY_RATE_MSK_V1;
int idx;
bool ofdm = !(rate_n_flags & RATE_MCS_CCK_MSK_V1);
int offset = ofdm ? IWL_FIRST_OFDM_RATE : 0;
int last = ofdm ? IWL_RATE_COUNT_LEGACY : IWL_FIRST_OFDM_RATE;
for (idx = offset; idx < last; idx++)
if (iwl_fw_rate_idx_to_plcp(idx) == rate)
return idx - offset;
return -1;
}
int rs_pretty_print_rate(char *buf, int bufsz, const u32 rate)
{
char *type;
u8 mcs = 0, nss = 0;
u8 ant = (rate & RATE_MCS_ANT_AB_MSK) >> RATE_MCS_ANT_POS;
u32 bw = (rate & RATE_MCS_CHAN_WIDTH_MSK) >>
RATE_MCS_CHAN_WIDTH_POS;
u32 format = rate & RATE_MCS_MOD_TYPE_MSK;
bool sgi;
if (format == RATE_MCS_CCK_MSK ||
format == RATE_MCS_LEGACY_OFDM_MSK) {
int legacy_rate = rate & RATE_LEGACY_RATE_MSK;
int index = format == RATE_MCS_CCK_MSK ?
legacy_rate :
legacy_rate + IWL_FIRST_OFDM_RATE;
return scnprintf(buf, bufsz, "Legacy | ANT: %s Rate: %s Mbps",
iwl_rs_pretty_ant(ant),
index == IWL_RATE_INVALID ? "BAD" :
iwl_rate_mcs(index)->mbps);
}
if (format == RATE_MCS_VHT_MSK)
type = "VHT";
else if (format == RATE_MCS_HT_MSK)
type = "HT";
else if (format == RATE_MCS_HE_MSK)
type = "HE";
else
type = "Unknown"; /* shouldn't happen */
mcs = format == RATE_MCS_HT_MSK ?
RATE_HT_MCS_INDEX(rate) :
rate & RATE_MCS_CODE_MSK;
nss = ((rate & RATE_MCS_NSS_MSK)
>> RATE_MCS_NSS_POS) + 1;
sgi = format == RATE_MCS_HE_MSK ?
iwl_he_is_sgi(rate) :
rate & RATE_MCS_SGI_MSK;
return scnprintf(buf, bufsz,
"0x%x: %s | ANT: %s BW: %s MCS: %d NSS: %d %s%s%s%s%s",
rate, type, iwl_rs_pretty_ant(ant), iwl_rs_pretty_bw(bw), mcs, nss,
(sgi) ? "SGI " : "NGI ",
(rate & RATE_MCS_STBC_MSK) ? "STBC " : "",
(rate & RATE_MCS_LDPC_MSK) ? "LDPC " : "",
(rate & RATE_HE_DUAL_CARRIER_MODE_MSK) ? "DCM " : "",
(rate & RATE_MCS_BF_MSK) ? "BF " : "");
}
IWL_EXPORT_SYMBOL(rs_pretty_print_rate);
bool iwl_he_is_sgi(u32 rate_n_flags)
{
u32 type = rate_n_flags & RATE_MCS_HE_TYPE_MSK;
u32 ltf_gi = rate_n_flags & RATE_MCS_HE_GI_LTF_MSK;
if (type == RATE_MCS_HE_TYPE_SU ||
type == RATE_MCS_HE_TYPE_EXT_SU)
return ltf_gi == RATE_MCS_HE_SU_4_LTF_08_GI;
return false;
}
IWL_EXPORT_SYMBOL(iwl_he_is_sgi);

Просмотреть файл

@ -105,6 +105,9 @@ struct iwl_fw_runtime {
const struct iwl_fw_runtime_ops *ops;
void *ops_ctx;
const struct iwl_dump_sanitize_ops *sanitize_ops;
void *sanitize_ctx;
/* Paging */
struct iwl_fw_paging fw_paging_db[NUM_OF_FW_PAGING_BLOCKS];
u16 num_of_paging_blk;
@ -151,7 +154,7 @@ struct iwl_fw_runtime {
struct iwl_sar_profile sar_profiles[ACPI_SAR_PROFILE_NUM];
u8 sar_chain_a_profile;
u8 sar_chain_b_profile;
struct iwl_geo_profile geo_profiles[ACPI_NUM_GEO_PROFILES];
struct iwl_geo_profile geo_profiles[ACPI_NUM_GEO_PROFILES_REV3];
u32 geo_rev;
union iwl_ppag_table_cmd ppag_table;
u32 ppag_ver;
@ -161,6 +164,8 @@ struct iwl_fw_runtime {
void iwl_fw_runtime_init(struct iwl_fw_runtime *fwrt, struct iwl_trans *trans,
const struct iwl_fw *fw,
const struct iwl_fw_runtime_ops *ops, void *ops_ctx,
const struct iwl_dump_sanitize_ops *sanitize_ops,
void *sanitize_ctx,
struct dentry *dbgfs_dir);
static inline void iwl_fw_runtime_free(struct iwl_fw_runtime *fwrt)

Просмотреть файл

@ -2,7 +2,8 @@
/*
* Copyright(c) 2021 Intel Corporation
*/
#ifndef __iwl_fw_uefi__
#define __iwl_fw_uefi__
#define IWL_UEFI_OEM_PNVM_NAME L"UefiCnvWlanOemSignedPnvm"
#define IWL_UEFI_REDUCED_POWER_NAME L"UefiCnvWlanReducedPower"
@ -40,3 +41,5 @@ void *iwl_uefi_get_reduced_power(struct iwl_trans *trans, size_t *len)
return ERR_PTR(-EOPNOTSUPP);
}
#endif /* CONFIG_EFI */
#endif /* __iwl_fw_uefi__ */

Просмотреть файл

@ -95,7 +95,6 @@ enum iwl_nvm_type {
#define ANT_AC (ANT_A | ANT_C)
#define ANT_BC (ANT_B | ANT_C)
#define ANT_ABC (ANT_A | ANT_B | ANT_C)
#define MAX_ANT_NUM 3
static inline u8 num_of_ant(u8 mask)
@ -420,6 +419,7 @@ struct iwl_cfg {
#define IWL_CFG_MAC_TYPE_SOF 0x43
#define IWL_CFG_MAC_TYPE_MA 0x44
#define IWL_CFG_MAC_TYPE_BZ 0x46
#define IWL_CFG_MAC_TYPE_GL 0x47
#define IWL_CFG_RF_TYPE_TH 0x105
#define IWL_CFG_RF_TYPE_TH1 0x108
@ -511,6 +511,10 @@ extern const char iwl_ax210_killer_1675w_name[];
extern const char iwl_ax210_killer_1675x_name[];
extern const char iwl9560_killer_1550i_160_name[];
extern const char iwl9560_killer_1550s_160_name[];
extern const char iwl_ax211_killer_1675s_name[];
extern const char iwl_ax211_killer_1675i_name[];
extern const char iwl_ax411_killer_1690s_name[];
extern const char iwl_ax411_killer_1690i_name[];
extern const char iwl_ax211_name[];
extern const char iwl_ax221_name[];
extern const char iwl_ax231_name[];
@ -628,6 +632,8 @@ extern const struct iwl_cfg iwl_cfg_bz_a0_hr_b0;
extern const struct iwl_cfg iwl_cfg_bz_a0_gf_a0;
extern const struct iwl_cfg iwl_cfg_bz_a0_gf4_a0;
extern const struct iwl_cfg iwl_cfg_bz_a0_mr_a0;
extern const struct iwl_cfg iwl_cfg_bz_a0_fm_a0;
extern const struct iwl_cfg iwl_cfg_gl_a0_fm_a0;
#endif /* CONFIG_IWLMVM */
#endif /* __IWL_CONFIG_H__ */

Просмотреть файл

@ -109,12 +109,12 @@ struct iwl_prph_scratch_pnvm_cfg {
* struct iwl_prph_scratch_hwm_cfg - hwm config
* @hwm_base_addr: hwm start address
* @hwm_size: hwm size in DWs
* @reserved: reserved
* @debug_token_config: debug preset
*/
struct iwl_prph_scratch_hwm_cfg {
__le64 hwm_base_addr;
__le32 hwm_size;
__le32 reserved;
__le32 debug_token_config;
} __packed; /* PERIPH_SCRATCH_HWM_CFG_S */
/*

Просмотреть файл

@ -34,6 +34,7 @@
#define CSR_GPIO_IN (CSR_BASE+0x018) /* read external chip pins */
#define CSR_RESET (CSR_BASE+0x020) /* busmaster enable, NMI, etc*/
#define CSR_GP_CNTRL (CSR_BASE+0x024)
#define CSR_FUNC_SCRATCH (CSR_BASE+0x02c) /* Scratch register - used for FW dbg */
/* 2nd byte of CSR_INT_COALESCING, not accessible via iwl_write32()! */
#define CSR_INT_PERIODIC_REG (CSR_BASE+0x005)
@ -135,6 +136,12 @@
#define CSR_DBG_HPET_MEM_REG (CSR_BASE+0x240)
#define CSR_DBG_LINK_PWR_MGMT_REG (CSR_BASE+0x250)
/*
* Scratch register initial configuration - this is set on init, and read
* during a error FW error.
*/
#define CSR_FUNC_SCRATCH_INIT_VALUE (0x01010101)
/* Bits for CSR_HW_IF_CONFIG_REG */
#define CSR_HW_IF_CONFIG_REG_MSK_MAC_DASH (0x00000003)
#define CSR_HW_IF_CONFIG_REG_MSK_MAC_STEP (0x0000000C)
@ -598,6 +605,7 @@ enum msix_hw_int_causes {
MSIX_HW_INT_CAUSES_REG_WAKEUP = BIT(1),
MSIX_HW_INT_CAUSES_REG_IML = BIT(1),
MSIX_HW_INT_CAUSES_REG_RESET_DONE = BIT(2),
MSIX_HW_INT_CAUSES_REG_SW_ERR_BZ = BIT(5),
MSIX_HW_INT_CAUSES_REG_CT_KILL = BIT(6),
MSIX_HW_INT_CAUSES_REG_RF_KILL = BIT(7),
MSIX_HW_INT_CAUSES_REG_PERIODIC = BIT(8),

Просмотреть файл

@ -16,6 +16,7 @@
* @IWL_DBG_TLV_TYPE_HCMD: host command TLV
* @IWL_DBG_TLV_TYPE_REGION: region TLV
* @IWL_DBG_TLV_TYPE_TRIGGER: trigger TLV
* @IWL_DBG_TLV_TYPE_CONF_SET: conf set TLV
* @IWL_DBG_TLV_TYPE_NUM: number of debug TLVs
*/
enum iwl_dbg_tlv_type {
@ -25,6 +26,7 @@ enum iwl_dbg_tlv_type {
IWL_DBG_TLV_TYPE_HCMD,
IWL_DBG_TLV_TYPE_REGION,
IWL_DBG_TLV_TYPE_TRIGGER,
IWL_DBG_TLV_TYPE_CONF_SET,
IWL_DBG_TLV_TYPE_NUM,
};
@ -59,6 +61,7 @@ dbg_ver_table[IWL_DBG_TLV_TYPE_NUM] = {
[IWL_DBG_TLV_TYPE_HCMD] = {.min_ver = 1, .max_ver = 1,},
[IWL_DBG_TLV_TYPE_REGION] = {.min_ver = 1, .max_ver = 2,},
[IWL_DBG_TLV_TYPE_TRIGGER] = {.min_ver = 1, .max_ver = 1,},
[IWL_DBG_TLV_TYPE_CONF_SET] = {.min_ver = 1, .max_ver = 1,},
};
static int iwl_dbg_tlv_add(const struct iwl_ucode_tlv *tlv,
@ -260,6 +263,30 @@ static int iwl_dbg_tlv_alloc_trigger(struct iwl_trans *trans,
return ret;
}
static int iwl_dbg_tlv_config_set(struct iwl_trans *trans,
const struct iwl_ucode_tlv *tlv)
{
struct iwl_fw_ini_conf_set_tlv *conf_set = (void *)tlv->data;
u32 tp = le32_to_cpu(conf_set->time_point);
u32 type = le32_to_cpu(conf_set->set_type);
if (tp <= IWL_FW_INI_TIME_POINT_INVALID ||
tp >= IWL_FW_INI_TIME_POINT_NUM) {
IWL_DEBUG_FW(trans,
"WRT: Invalid time point %u for config set TLV\n", tp);
return -EINVAL;
}
if (type <= IWL_FW_INI_CONFIG_SET_TYPE_INVALID ||
type >= IWL_FW_INI_CONFIG_SET_TYPE_MAX_NUM) {
IWL_DEBUG_FW(trans,
"WRT: Invalid config set type %u for config set TLV\n", type);
return -EINVAL;
}
return iwl_dbg_tlv_add(tlv, &trans->dbg.time_point[tp].config_list);
}
static int (*dbg_tlv_alloc[])(struct iwl_trans *trans,
const struct iwl_ucode_tlv *tlv) = {
[IWL_DBG_TLV_TYPE_DEBUG_INFO] = iwl_dbg_tlv_alloc_debug_info,
@ -267,6 +294,7 @@ static int (*dbg_tlv_alloc[])(struct iwl_trans *trans,
[IWL_DBG_TLV_TYPE_HCMD] = iwl_dbg_tlv_alloc_hcmd,
[IWL_DBG_TLV_TYPE_REGION] = iwl_dbg_tlv_alloc_region,
[IWL_DBG_TLV_TYPE_TRIGGER] = iwl_dbg_tlv_alloc_trigger,
[IWL_DBG_TLV_TYPE_CONF_SET] = iwl_dbg_tlv_config_set,
};
void iwl_dbg_tlv_alloc(struct iwl_trans *trans, const struct iwl_ucode_tlv *tlv,
@ -399,6 +427,13 @@ void iwl_dbg_tlv_free(struct iwl_trans *trans)
list_del(&tlv_node->list);
kfree(tlv_node);
}
list_for_each_entry_safe(tlv_node, tlv_node_tmp,
&tp->config_list, list) {
list_del(&tlv_node->list);
kfree(tlv_node);
}
}
for (i = 0; i < ARRAY_SIZE(trans->dbg.fw_mon_ini); i++)
@ -466,6 +501,7 @@ void iwl_dbg_tlv_init(struct iwl_trans *trans)
INIT_LIST_HEAD(&tp->trig_list);
INIT_LIST_HEAD(&tp->hcmd_list);
INIT_LIST_HEAD(&tp->active_trig_list);
INIT_LIST_HEAD(&tp->config_list);
}
}
@ -649,6 +685,10 @@ static void iwl_dbg_tlv_apply_buffers(struct iwl_fw_runtime *fwrt)
{
int ret, i;
if (fw_has_capa(&fwrt->fw->ucode_capa,
IWL_UCODE_TLV_CAPA_DRAM_FRAG_SUPPORT))
return;
for (i = 0; i < IWL_FW_INI_ALLOCATION_NUM; i++) {
ret = iwl_dbg_tlv_apply_buffer(fwrt, i);
if (ret)
@ -658,6 +698,87 @@ static void iwl_dbg_tlv_apply_buffers(struct iwl_fw_runtime *fwrt)
}
}
static int iwl_dbg_tlv_update_dram(struct iwl_fw_runtime *fwrt,
enum iwl_fw_ini_allocation_id alloc_id,
struct iwl_dram_info *dram_info)
{
struct iwl_fw_mon *fw_mon;
u32 remain_frags, num_frags;
int j, fw_mon_idx = 0;
struct iwl_buf_alloc_cmd *data;
if (le32_to_cpu(fwrt->trans->dbg.fw_mon_cfg[alloc_id].buf_location) !=
IWL_FW_INI_LOCATION_DRAM_PATH) {
IWL_DEBUG_FW(fwrt, "DRAM_PATH is not supported alloc_id %u\n", alloc_id);
return -1;
}
fw_mon = &fwrt->trans->dbg.fw_mon_ini[alloc_id];
/* the first fragment of DBGC1 is given to the FW via register
* or context info
*/
if (alloc_id == IWL_FW_INI_ALLOCATION_ID_DBGC1)
fw_mon_idx++;
remain_frags = fw_mon->num_frags - fw_mon_idx;
if (!remain_frags)
return -1;
num_frags = min_t(u32, remain_frags, BUF_ALLOC_MAX_NUM_FRAGS);
data = &dram_info->dram_frags[alloc_id - 1];
data->alloc_id = cpu_to_le32(alloc_id);
data->num_frags = cpu_to_le32(num_frags);
data->buf_location = cpu_to_le32(IWL_FW_INI_LOCATION_DRAM_PATH);
IWL_DEBUG_FW(fwrt, "WRT: DRAM buffer details alloc_id=%u, num_frags=%u\n",
cpu_to_le32(alloc_id), cpu_to_le32(num_frags));
for (j = 0; j < num_frags; j++) {
struct iwl_buf_alloc_frag *frag = &data->frags[j];
struct iwl_dram_data *fw_mon_frag = &fw_mon->frags[fw_mon_idx++];
frag->addr = cpu_to_le64(fw_mon_frag->physical);
frag->size = cpu_to_le32(fw_mon_frag->size);
IWL_DEBUG_FW(fwrt, "WRT: DRAM fragment details\n");
IWL_DEBUG_FW(fwrt, "frag=%u, addr=0x%016llx, size=0x%x)\n",
j, cpu_to_le64(fw_mon_frag->physical),
cpu_to_le32(fw_mon_frag->size));
}
return 0;
}
static void iwl_dbg_tlv_update_drams(struct iwl_fw_runtime *fwrt)
{
int ret, i, dram_alloc = 0;
struct iwl_dram_info dram_info;
struct iwl_dram_data *frags =
&fwrt->trans->dbg.fw_mon_ini[IWL_FW_INI_ALLOCATION_ID_DBGC1].frags[0];
if (!fw_has_capa(&fwrt->fw->ucode_capa,
IWL_UCODE_TLV_CAPA_DRAM_FRAG_SUPPORT))
return;
dram_info.first_word = cpu_to_le32(DRAM_INFO_FIRST_MAGIC_WORD);
dram_info.second_word = cpu_to_le32(DRAM_INFO_SECOND_MAGIC_WORD);
for (i = IWL_FW_INI_ALLOCATION_ID_DBGC1;
i <= IWL_FW_INI_ALLOCATION_ID_DBGC3; i++) {
ret = iwl_dbg_tlv_update_dram(fwrt, i, &dram_info);
if (!ret)
dram_alloc++;
else
IWL_WARN(fwrt,
"WRT: Failed to set DRAM buffer for alloc id %d, ret=%d\n",
i, ret);
}
if (dram_alloc) {
memcpy(frags->block, &dram_info, sizeof(dram_info));
IWL_DEBUG_FW(fwrt, "block data after %016x\n",
*((int *)fwrt->trans->dbg.fw_mon_ini[1].frags[0].block));
}
}
static void iwl_dbg_tlv_send_hcmds(struct iwl_fw_runtime *fwrt,
struct list_head *hcmd_list)
{
@ -677,6 +798,97 @@ static void iwl_dbg_tlv_send_hcmds(struct iwl_fw_runtime *fwrt,
}
}
static void iwl_dbg_tlv_apply_config(struct iwl_fw_runtime *fwrt,
struct list_head *config_list)
{
struct iwl_dbg_tlv_node *node;
list_for_each_entry(node, config_list, list) {
struct iwl_fw_ini_conf_set_tlv *config_list = (void *)node->tlv.data;
u32 count, address, value;
u32 len = (le32_to_cpu(node->tlv.length) - sizeof(*config_list)) / 8;
u32 type = le32_to_cpu(config_list->set_type);
u32 offset = le32_to_cpu(config_list->addr_offset);
switch (type) {
case IWL_FW_INI_CONFIG_SET_TYPE_DEVICE_PERIPHERY_MAC: {
if (!iwl_trans_grab_nic_access(fwrt->trans)) {
IWL_DEBUG_FW(fwrt, "WRT: failed to get nic access\n");
IWL_DEBUG_FW(fwrt, "WRT: skipping MAC PERIPHERY config\n");
continue;
}
IWL_DEBUG_FW(fwrt, "WRT: MAC PERIPHERY config len: len %u\n", len);
for (count = 0; count < len; count++) {
address = le32_to_cpu(config_list->addr_val[count].address);
value = le32_to_cpu(config_list->addr_val[count].value);
iwl_trans_write_prph(fwrt->trans, address + offset, value);
}
iwl_trans_release_nic_access(fwrt->trans);
break;
}
case IWL_FW_INI_CONFIG_SET_TYPE_DEVICE_MEMORY: {
for (count = 0; count < len; count++) {
address = le32_to_cpu(config_list->addr_val[count].address);
value = le32_to_cpu(config_list->addr_val[count].value);
iwl_trans_write_mem32(fwrt->trans, address + offset, value);
IWL_DEBUG_FW(fwrt, "WRT: DEV_MEM: count %u, add: %u val: %u\n",
count, address, value);
}
break;
}
case IWL_FW_INI_CONFIG_SET_TYPE_CSR: {
for (count = 0; count < len; count++) {
address = le32_to_cpu(config_list->addr_val[count].address);
value = le32_to_cpu(config_list->addr_val[count].value);
iwl_write32(fwrt->trans, address + offset, value);
IWL_DEBUG_FW(fwrt, "WRT: CSR: count %u, add: %u val: %u\n",
count, address, value);
}
break;
}
case IWL_FW_INI_CONFIG_SET_TYPE_DBGC_DRAM_ADDR: {
struct iwl_dbgc1_info dram_info = {};
struct iwl_dram_data *frags = &fwrt->trans->dbg.fw_mon_ini[1].frags[0];
__le64 dram_base_addr = cpu_to_le64(frags->physical);
__le32 dram_size = cpu_to_le32(frags->size);
u64 dram_addr = le64_to_cpu(dram_base_addr);
u32 ret;
IWL_DEBUG_FW(fwrt, "WRT: dram_base_addr 0x%016llx, dram_size 0x%x\n",
dram_base_addr, dram_size);
IWL_DEBUG_FW(fwrt, "WRT: config_list->addr_offset: %u\n",
le32_to_cpu(config_list->addr_offset));
for (count = 0; count < len; count++) {
address = le32_to_cpu(config_list->addr_val[count].address);
dram_info.dbgc1_add_lsb =
cpu_to_le32((dram_addr & 0x00000000FFFFFFFFULL) + 0x400);
dram_info.dbgc1_add_msb =
cpu_to_le32((dram_addr & 0xFFFFFFFF00000000ULL) >> 32);
dram_info.dbgc1_size = cpu_to_le32(le32_to_cpu(dram_size) - 0x400);
ret = iwl_trans_write_mem(fwrt->trans,
address + offset, &dram_info, 4);
if (ret) {
IWL_ERR(fwrt, "Failed to write dram_info to HW_SMEM\n");
break;
}
}
break;
}
case IWL_FW_INI_CONFIG_SET_TYPE_PERIPH_SCRATCH_HWM: {
u32 debug_token_config =
le32_to_cpu(config_list->addr_val[0].value);
IWL_DEBUG_FW(fwrt, "WRT: Setting HWM debug token config: %u\n",
debug_token_config);
fwrt->trans->dbg.ucode_preset = debug_token_config;
break;
}
default:
break;
}
}
}
static void iwl_dbg_tlv_periodic_trig_handler(struct timer_list *t)
{
struct iwl_dbg_tlv_timer_node *timer_node =
@ -996,8 +1208,10 @@ static void iwl_dbg_tlv_init_cfg(struct iwl_fw_runtime *fwrt)
&fwrt->trans->dbg.fw_mon_cfg[i];
u32 dest = le32_to_cpu(fw_mon_cfg->buf_location);
if (dest == IWL_FW_INI_LOCATION_INVALID)
if (dest == IWL_FW_INI_LOCATION_INVALID) {
failed_alloc |= BIT(i);
continue;
}
if (*ini_dest == IWL_FW_INI_LOCATION_INVALID)
*ini_dest = dest;
@ -1024,8 +1238,10 @@ static void iwl_dbg_tlv_init_cfg(struct iwl_fw_runtime *fwrt)
&fwrt->trans->dbg.active_regions[i];
u32 reg_type;
if (!*active_reg)
if (!*active_reg) {
fwrt->trans->dbg.unsupported_region_msk |= BIT(i);
continue;
}
reg = (void *)(*active_reg)->data;
reg_type = le32_to_cpu(reg->type);
@ -1051,7 +1267,7 @@ void _iwl_dbg_tlv_time_point(struct iwl_fw_runtime *fwrt,
union iwl_dbg_tlv_tp_data *tp_data,
bool sync)
{
struct list_head *hcmd_list, *trig_list;
struct list_head *hcmd_list, *trig_list, *conf_list;
if (!iwl_trans_dbg_ini_valid(fwrt->trans) ||
tp_id == IWL_FW_INI_TIME_POINT_INVALID ||
@ -1060,15 +1276,19 @@ void _iwl_dbg_tlv_time_point(struct iwl_fw_runtime *fwrt,
hcmd_list = &fwrt->trans->dbg.time_point[tp_id].hcmd_list;
trig_list = &fwrt->trans->dbg.time_point[tp_id].active_trig_list;
conf_list = &fwrt->trans->dbg.time_point[tp_id].config_list;
switch (tp_id) {
case IWL_FW_INI_TIME_POINT_EARLY:
iwl_dbg_tlv_init_cfg(fwrt);
iwl_dbg_tlv_apply_config(fwrt, conf_list);
iwl_dbg_tlv_update_drams(fwrt);
iwl_dbg_tlv_tp_trigger(fwrt, sync, trig_list, tp_data, NULL);
break;
case IWL_FW_INI_TIME_POINT_AFTER_ALIVE:
iwl_dbg_tlv_apply_buffers(fwrt);
iwl_dbg_tlv_send_hcmds(fwrt, hcmd_list);
iwl_dbg_tlv_apply_config(fwrt, conf_list);
iwl_dbg_tlv_tp_trigger(fwrt, sync, trig_list, tp_data, NULL);
break;
case IWL_FW_INI_TIME_POINT_PERIODIC:
@ -1079,11 +1299,13 @@ void _iwl_dbg_tlv_time_point(struct iwl_fw_runtime *fwrt,
case IWL_FW_INI_TIME_POINT_MISSED_BEACONS:
case IWL_FW_INI_TIME_POINT_FW_DHC_NOTIFICATION:
iwl_dbg_tlv_send_hcmds(fwrt, hcmd_list);
iwl_dbg_tlv_apply_config(fwrt, conf_list);
iwl_dbg_tlv_tp_trigger(fwrt, sync, trig_list, tp_data,
iwl_dbg_tlv_check_fw_pkt);
break;
default:
iwl_dbg_tlv_send_hcmds(fwrt, hcmd_list);
iwl_dbg_tlv_apply_config(fwrt, conf_list);
iwl_dbg_tlv_tp_trigger(fwrt, sync, trig_list, tp_data, NULL);
break;
}

Просмотреть файл

@ -33,11 +33,13 @@ union iwl_dbg_tlv_tp_data {
* @trig_list: list of triggers
* @active_trig_list: list of active triggers
* @hcmd_list: list of host commands
* @config_list: list of configuration
*/
struct iwl_dbg_tlv_time_point_data {
struct list_head trig_list;
struct list_head active_trig_list;
struct list_head hcmd_list;
struct list_head config_list;
};
struct iwl_trans;

Просмотреть файл

@ -1,6 +1,6 @@
// SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause
/*
* Copyright (C) 2005-2011 Intel Corporation
* Copyright (C) 2005-2011, 2021 Intel Corporation
*/
#include <linux/device.h>
#include <linux/interrupt.h>
@ -31,21 +31,31 @@ IWL_EXPORT_SYMBOL(__iwl_info);
__iwl_fn(crit)
IWL_EXPORT_SYMBOL(__iwl_crit);
void __iwl_err(struct device *dev, bool rfkill_prefix, bool trace_only,
const char *fmt, ...)
void __iwl_err(struct device *dev, enum iwl_err_mode mode, const char *fmt, ...)
{
struct va_format vaf = {
.fmt = fmt,
};
va_list args;
va_list args, args2;
va_start(args, fmt);
vaf.va = &args;
if (!trace_only) {
if (rfkill_prefix)
switch (mode) {
case IWL_ERR_MODE_RATELIMIT:
if (net_ratelimit())
break;
fallthrough;
case IWL_ERR_MODE_REGULAR:
case IWL_ERR_MODE_RFKILL:
va_copy(args2, args);
vaf.va = &args2;
if (mode == IWL_ERR_MODE_RFKILL)
dev_err(dev, "(RFKILL) %pV", &vaf);
else
dev_err(dev, "%pV", &vaf);
va_end(args2);
break;
default:
break;
}
trace_iwlwifi_err(&vaf);
va_end(args);

Просмотреть файл

@ -2,14 +2,9 @@
/******************************************************************************
*
* Copyright(c) 2003 - 2014 Intel Corporation. All rights reserved.
* Copyright(c) 2018 - 2020 Intel Corporation
* Copyright(c) 2018 - 2021 Intel Corporation
*
* Portions of this file are derived from the ipw3945 project.
*
* Contact Information:
* Intel Linux Wireless <linuxwifi@intel.com>
* Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
*
*****************************************************************************/
#ifndef __iwl_debug_h__
@ -27,9 +22,16 @@ static inline bool iwl_have_debug_level(u32 level)
#endif
}
enum iwl_err_mode {
IWL_ERR_MODE_REGULAR,
IWL_ERR_MODE_RFKILL,
IWL_ERR_MODE_TRACE_ONLY,
IWL_ERR_MODE_RATELIMIT,
};
struct device;
void __iwl_err(struct device *dev, bool rfkill_prefix, bool only_trace,
const char *fmt, ...) __printf(4, 5);
void __iwl_err(struct device *dev, enum iwl_err_mode mode, const char *fmt, ...)
__printf(3, 4);
void __iwl_warn(struct device *dev, const char *fmt, ...) __printf(2, 3);
void __iwl_info(struct device *dev, const char *fmt, ...) __printf(2, 3);
void __iwl_crit(struct device *dev, const char *fmt, ...) __printf(2, 3);
@ -38,13 +40,17 @@ void __iwl_crit(struct device *dev, const char *fmt, ...) __printf(2, 3);
#define CHECK_FOR_NEWLINE(f) BUILD_BUG_ON(f[sizeof(f) - 2] != '\n')
/* No matter what is m (priv, bus, trans), this will work */
#define IWL_ERR_DEV(d, f, a...) \
#define __IWL_ERR_DEV(d, mode, f, a...) \
do { \
CHECK_FOR_NEWLINE(f); \
__iwl_err((d), false, false, f, ## a); \
__iwl_err((d), mode, f, ## a); \
} while (0)
#define IWL_ERR_DEV(d, f, a...) \
__IWL_ERR_DEV(d, IWL_ERR_MODE_REGULAR, f, ## a)
#define IWL_ERR(m, f, a...) \
IWL_ERR_DEV((m)->dev, f, ## a)
#define IWL_ERR_LIMIT(m, f, a...) \
__IWL_ERR_DEV((m)->dev, IWL_ERR_MODE_RATELIMIT, f, ## a)
#define IWL_WARN(m, f, a...) \
do { \
CHECK_FOR_NEWLINE(f); \

Просмотреть файл

@ -4,11 +4,6 @@
* Copyright(c) 2009 - 2014 Intel Corporation. All rights reserved.
* Copyright(c) 2015 Intel Deutschland GmbH
* Copyright(c) 2018 - 2019 Intel Corporation
*
* Contact Information:
* Intel Linux Wireless <linuxwifi@intel.com>
* Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
*
*****************************************************************************/
#if !defined(__IWLWIFI_DEVICE_TRACE_DATA) || defined(TRACE_HEADER_MULTI_READ)

Просмотреть файл

@ -3,11 +3,6 @@
*
* Copyright(c) 2009 - 2014 Intel Corporation. All rights reserved.
* Copyright(c) 2016-2017 Intel Deutschland GmbH
*
* Contact Information:
* Intel Linux Wireless <linuxwifi@intel.com>
* Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
*
*****************************************************************************/
#if !defined(__IWLWIFI_DEVICE_TRACE_IO) || defined(TRACE_HEADER_MULTI_READ)

Просмотреть файл

@ -5,11 +5,6 @@
* Copyright(c) 2015 Intel Mobile Communications GmbH
* Copyright(c) 2016 - 2017 Intel Deutschland GmbH
* Copyright(c) 2018 Intel Corporation
*
* Contact Information:
* Intel Linux Wireless <linuxwifi@intel.com>
* Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
*
*****************************************************************************/
#if !defined(__IWLWIFI_DEVICE_TRACE_IWLWIFI) || defined(TRACE_HEADER_MULTI_READ)

Просмотреть файл

@ -2,11 +2,6 @@
/******************************************************************************
*
* Copyright(c) 2009 - 2014 Intel Corporation. All rights reserved.
*
* Contact Information:
* Intel Linux Wireless <linuxwifi@intel.com>
* Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
*
*****************************************************************************/
#if !defined(__IWLWIFI_DEVICE_TRACE_MSG) || defined(TRACE_HEADER_MULTI_READ)

Просмотреть файл

@ -2,11 +2,6 @@
/******************************************************************************
*
* Copyright(c) 2009 - 2014 Intel Corporation. All rights reserved.
*
* Contact Information:
* Intel Linux Wireless <linuxwifi@intel.com>
* Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
*
*****************************************************************************/
#if !defined(__IWLWIFI_DEVICE_TRACE_UCODE) || defined(TRACE_HEADER_MULTI_READ)

Просмотреть файл

@ -3,11 +3,6 @@
*
* Copyright(c) 2009 - 2014 Intel Corporation. All rights reserved.
* Copyright (C) 2018 Intel Corporation
*
* Contact Information:
* Intel Linux Wireless <linuxwifi@intel.com>
* Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
*
*****************************************************************************/
#include <linux/module.h>

Просмотреть файл

@ -4,11 +4,6 @@
* Copyright(c) 2009 - 2014 Intel Corporation. All rights reserved.
* Copyright(C) 2016 Intel Deutschland GmbH
* Copyright(c) 2018 Intel Corporation
*
* Contact Information:
* Intel Linux Wireless <linuxwifi@intel.com>
* Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
*
*****************************************************************************/
#ifndef __IWLWIFI_DEVICE_TRACE

Просмотреть файл

@ -31,7 +31,6 @@
#define DRV_DESCRIPTION "Intel(R) Wireless WiFi driver for Linux"
MODULE_DESCRIPTION(DRV_DESCRIPTION);
MODULE_AUTHOR(DRV_AUTHOR);
MODULE_LICENSE("GPL");
#ifdef CONFIG_IWLWIFI_DEBUGFS
@ -550,6 +549,43 @@ static int iwl_parse_v1_v2_firmware(struct iwl_drv *drv,
return 0;
}
static void iwl_drv_set_dump_exclude(struct iwl_drv *drv,
enum iwl_ucode_tlv_type tlv_type,
const void *tlv_data, u32 tlv_len)
{
const struct iwl_fw_dump_exclude *fw = tlv_data;
struct iwl_dump_exclude *excl;
if (tlv_len < sizeof(*fw))
return;
if (tlv_type == IWL_UCODE_TLV_SEC_TABLE_ADDR) {
excl = &drv->fw.dump_excl[0];
/* second time we find this, it's for WoWLAN */
if (excl->addr)
excl = &drv->fw.dump_excl_wowlan[0];
} else if (fw_has_capa(&drv->fw.ucode_capa,
IWL_UCODE_TLV_CAPA_CNSLDTD_D3_D0_IMG)) {
/* IWL_UCODE_TLV_D3_KEK_KCK_ADDR is regular image */
excl = &drv->fw.dump_excl[0];
} else {
/* IWL_UCODE_TLV_D3_KEK_KCK_ADDR is WoWLAN image */
excl = &drv->fw.dump_excl_wowlan[0];
}
if (excl->addr)
excl++;
if (excl->addr) {
IWL_DEBUG_FW_INFO(drv, "found too many excludes in fw file\n");
return;
}
excl->addr = le32_to_cpu(fw->addr) & ~FW_ADDR_CACHE_CONTROL;
excl->size = le32_to_cpu(fw->size);
}
static int iwl_parse_tlv_firmware(struct iwl_drv *drv,
const struct firmware *ucode_raw,
struct iwl_firmware_pieces *pieces,
@ -1133,6 +1169,7 @@ static int iwl_parse_tlv_firmware(struct iwl_drv *drv,
case IWL_UCODE_TLV_TYPE_HCMD:
case IWL_UCODE_TLV_TYPE_REGIONS:
case IWL_UCODE_TLV_TYPE_TRIGGERS:
case IWL_UCODE_TLV_TYPE_CONF_SET:
if (iwlwifi_mod_params.enable_ini)
iwl_dbg_tlv_alloc(drv->trans, tlv, false);
break;
@ -1166,6 +1203,11 @@ static int iwl_parse_tlv_firmware(struct iwl_drv *drv,
return -ENOMEM;
drv->fw.phy_integration_ver_len = tlv_len;
break;
case IWL_UCODE_TLV_SEC_TABLE_ADDR:
case IWL_UCODE_TLV_D3_KEK_KCK_ADDR:
iwl_drv_set_dump_exclude(drv, tlv_type,
tlv_data, tlv_len);
break;
default:
IWL_DEBUG_INFO(drv, "unknown TLV: %d\n", tlv_type);
break;

Просмотреть файл

@ -1,6 +1,6 @@
/* SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause */
/*
* Copyright (C) 2005-2014, 2020 Intel Corporation
* Copyright (C) 2005-2014, 2020-2021 Intel Corporation
* Copyright (C) 2013-2014 Intel Mobile Communications GmbH
*/
#ifndef __iwl_drv_h__
@ -9,7 +9,6 @@
/* for all modules */
#define DRV_NAME "iwlwifi"
#define DRV_AUTHOR "Intel Corporation <linuxwifi@intel.com>"
/* radio config bits (actual values from NVM definition) */
#define NVM_RF_CFG_DASH_MSK(x) (x & 0x3) /* bits 0-1 */

Просмотреть файл

@ -1,6 +1,6 @@
// SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause
/*
* Copyright (C) 2005-2014, 2018-2019 Intel Corporation
* Copyright (C) 2005-2014, 2018-2019, 2021 Intel Corporation
*/
#include <linux/types.h>
#include <linux/slab.h>
@ -139,7 +139,7 @@ static int iwl_init_otp_access(struct iwl_trans *trans)
{
int ret;
ret = iwl_finish_nic_init(trans, trans->trans_cfg);
ret = iwl_finish_nic_init(trans);
if (ret)
return ret;

Просмотреть файл

@ -398,9 +398,50 @@ int iwl_dump_fh(struct iwl_trans *trans, char **buf)
return 0;
}
int iwl_finish_nic_init(struct iwl_trans *trans,
const struct iwl_cfg_trans_params *cfg_trans)
#define IWL_HOST_MON_BLOCK_PEMON 0x00
#define IWL_HOST_MON_BLOCK_HIPM 0x22
#define IWL_HOST_MON_BLOCK_PEMON_VEC0 0x00
#define IWL_HOST_MON_BLOCK_PEMON_VEC1 0x01
#define IWL_HOST_MON_BLOCK_PEMON_WFPM 0x06
static void iwl_dump_host_monitor_block(struct iwl_trans *trans,
u32 block, u32 vec, u32 iter)
{
int i;
IWL_ERR(trans, "Host monitor block 0x%x vector 0x%x\n", block, vec);
iwl_write32(trans, CSR_MONITOR_CFG_REG, (block << 8) | vec);
for (i = 0; i < iter; i++)
IWL_ERR(trans, " value [iter %d]: 0x%08x\n",
i, iwl_read32(trans, CSR_MONITOR_STATUS_REG));
}
static void iwl_dump_host_monitor(struct iwl_trans *trans)
{
switch (trans->trans_cfg->device_family) {
case IWL_DEVICE_FAMILY_22000:
case IWL_DEVICE_FAMILY_AX210:
IWL_ERR(trans, "CSR_RESET = 0x%x\n",
iwl_read32(trans, CSR_RESET));
iwl_dump_host_monitor_block(trans, IWL_HOST_MON_BLOCK_PEMON,
IWL_HOST_MON_BLOCK_PEMON_VEC0, 15);
iwl_dump_host_monitor_block(trans, IWL_HOST_MON_BLOCK_PEMON,
IWL_HOST_MON_BLOCK_PEMON_VEC1, 15);
iwl_dump_host_monitor_block(trans, IWL_HOST_MON_BLOCK_PEMON,
IWL_HOST_MON_BLOCK_PEMON_WFPM, 15);
iwl_dump_host_monitor_block(trans, IWL_HOST_MON_BLOCK_HIPM,
IWL_HOST_MON_BLOCK_PEMON_VEC0, 1);
break;
default:
/* not supported yet */
return;
}
}
int iwl_finish_nic_init(struct iwl_trans *trans)
{
const struct iwl_cfg_trans_params *cfg_trans = trans->trans_cfg;
u32 poll_ready;
int err;
@ -433,9 +474,12 @@ int iwl_finish_nic_init(struct iwl_trans *trans,
* and accesses to uCode SRAM.
*/
err = iwl_poll_bit(trans, CSR_GP_CNTRL, poll_ready, poll_ready, 25000);
if (err < 0)
if (err < 0) {
IWL_DEBUG_INFO(trans, "Failed to wake NIC\n");
iwl_dump_host_monitor(trans);
}
if (cfg_trans->bisr_workaround) {
/* ensure BISR shift has finished */
udelay(200);

Просмотреть файл

@ -1,6 +1,6 @@
/* SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause */
/*
* Copyright (C) 2018-2020 Intel Corporation
* Copyright (C) 2018-2021 Intel Corporation
*/
#ifndef __iwl_io_h__
#define __iwl_io_h__
@ -52,8 +52,7 @@ void iwl_set_bits_mask_prph(struct iwl_trans *trans, u32 ofs,
void iwl_clear_bits_prph(struct iwl_trans *trans, u32 ofs, u32 mask);
void iwl_force_nmi(struct iwl_trans *trans);
int iwl_finish_nic_init(struct iwl_trans *trans,
const struct iwl_cfg_trans_params *cfg_trans);
int iwl_finish_nic_init(struct iwl_trans *trans);
/* Error handling */
int iwl_dump_fh(struct iwl_trans *trans, char **buf);

Просмотреть файл

@ -534,6 +534,17 @@ static void iwl_init_vht_hw_capab(struct iwl_trans *trans,
cpu_to_le16(IEEE80211_VHT_EXT_NSS_BW_CAPABLE);
}
static const u8 iwl_vendor_caps[] = {
0xdd, /* vendor element */
0x06, /* length */
0x00, 0x17, 0x35, /* Intel OUI */
0x08, /* type (Intel Capabilities) */
/* followed by 16 bits of capabilities */
#define IWL_VENDOR_CAP_IMPROVED_BF_FDBK_HE BIT(0)
IWL_VENDOR_CAP_IMPROVED_BF_FDBK_HE,
0x00
};
static const struct ieee80211_sband_iftype_data iwl_he_capa[] = {
{
.types_mask = BIT(NL80211_IFTYPE_STATION),
@ -781,6 +792,12 @@ iwl_nvm_fixup_sband_iftd(struct iwl_trans *trans,
if (fw_has_capa(&fw->ucode_capa, IWL_UCODE_TLV_CAPA_BROADCAST_TWT))
iftype_data->he_cap.he_cap_elem.mac_cap_info[2] |=
IEEE80211_HE_MAC_CAP2_BCAST_TWT;
if (trans->trans_cfg->device_family == IWL_DEVICE_FAMILY_22000 &&
!is_ap) {
iftype_data->vendor_elems.data = iwl_vendor_caps;
iftype_data->vendor_elems.len = ARRAY_SIZE(iwl_vendor_caps);
}
}
static void iwl_init_he_hw_capab(struct iwl_trans *trans,

Просмотреть файл

@ -347,6 +347,12 @@
#define RADIO_REG_SYS_MANUAL_DFT_0 0xAD4078
#define RFIC_REG_RD 0xAD0470
#define WFPM_CTRL_REG 0xA03030
#define WFPM_CTRL_REG_GEN2 0xd03030
#define WFPM_OTP_CFG1_ADDR 0x00a03098
#define WFPM_OTP_CFG1_ADDR_GEN2 0x00d03098
#define WFPM_OTP_CFG1_IS_JACKET_BIT BIT(4)
#define WFPM_OTP_CFG1_IS_CDB_BIT BIT(5)
#define WFPM_GP2 0xA030B4
/* DBGI SRAM Register details */
@ -399,10 +405,40 @@ enum {
LMPM_PAGE_PASS_NOTIF_POS = BIT(20),
};
/*
* CRF ID register
*
* type: bits 0-11
* reserved: bits 12-18
* slave_exist: bit 19
* dash: bits 20-23
* step: bits 24-26
* flavor: bits 27-31
*/
#define REG_CRF_ID_TYPE(val) (((val) & 0x00000FFF) >> 0)
#define REG_CRF_ID_SLAVE(val) (((val) & 0x00080000) >> 19)
#define REG_CRF_ID_DASH(val) (((val) & 0x00F00000) >> 20)
#define REG_CRF_ID_STEP(val) (((val) & 0x07000000) >> 24)
#define REG_CRF_ID_FLAVOR(val) (((val) & 0xF8000000) >> 27)
#define UREG_CHICK (0xA05C00)
#define UREG_CHICK_MSI_ENABLE BIT(24)
#define UREG_CHICK_MSIX_ENABLE BIT(25)
#define SD_REG_VER 0xa29600
#define SD_REG_VER_GEN2 0x00a2b800
#define REG_CRF_ID_TYPE_JF_1 0x201
#define REG_CRF_ID_TYPE_JF_2 0x202
#define REG_CRF_ID_TYPE_HR_CDB 0x503
#define REG_CRF_ID_TYPE_HR_NONE_CDB 0x504
#define REG_CRF_ID_TYPE_HR_NONE_CDB_1X1 0x501
#define REG_CRF_ID_TYPE_HR_NONE_CDB_CCP 0x532
#define REG_CRF_ID_TYPE_GF 0x410
#define REG_CRF_ID_TYPE_GF_TC 0xF08
#define REG_CRF_ID_TYPE_MR 0x810
#define REG_CRF_ID_TYPE_FM 0x910
#define HPM_DEBUG 0xA03440
#define PERSISTENCE_BIT BIT(12)
#define PREG_WFPM_ACCESS BIT(12)

Просмотреть файл

@ -362,6 +362,20 @@ struct iwl_hcmd_arr {
#define HCMD_ARR(x) \
{ .arr = x, .size = ARRAY_SIZE(x) }
/**
* struct iwl_dump_sanitize_ops - dump sanitization operations
* @frob_txf: Scrub the TX FIFO data
* @frob_hcmd: Scrub a host command, the %hcmd pointer is to the header
* but that might be short or long (&struct iwl_cmd_header or
* &struct iwl_cmd_header_wide)
* @frob_mem: Scrub memory data
*/
struct iwl_dump_sanitize_ops {
void (*frob_txf)(void *ctx, void *buf, size_t buflen);
void (*frob_hcmd)(void *ctx, void *hcmd, size_t buflen);
void (*frob_mem)(void *ctx, u32 mem_addr, void *mem, size_t buflen);
};
/**
* struct iwl_trans_config - transport configuration
*
@ -586,7 +600,9 @@ struct iwl_trans_ops {
u32 value);
struct iwl_trans_dump_data *(*dump_data)(struct iwl_trans *trans,
u32 dump_mask);
u32 dump_mask,
const struct iwl_dump_sanitize_ops *sanitize_ops,
void *sanitize_ctx);
void (*debugfs_cleanup)(struct iwl_trans *trans);
void (*sync_nmi)(struct iwl_trans *trans);
int (*set_pnvm)(struct iwl_trans *trans, const void *data, u32 len);
@ -723,8 +739,8 @@ struct iwl_self_init_dram {
* @debug_info_tlv_list: list of debug info TLVs
* @time_point: array of debug time points
* @periodic_trig_list: periodic triggers list
* @domains_bitmap: bitmap of active domains other than
* &IWL_FW_INI_DOMAIN_ALWAYS_ON
* @domains_bitmap: bitmap of active domains other than &IWL_FW_INI_DOMAIN_ALWAYS_ON
* @ucode_preset: preset based on ucode
*/
struct iwl_trans_debug {
u8 n_dest_reg;
@ -758,6 +774,7 @@ struct iwl_trans_debug {
struct list_head periodic_trig_list;
u32 domains_bitmap;
u32 ucode_preset;
};
struct iwl_dma_ptr {
@ -1086,11 +1103,14 @@ static inline int iwl_trans_d3_resume(struct iwl_trans *trans,
}
static inline struct iwl_trans_dump_data *
iwl_trans_dump_data(struct iwl_trans *trans, u32 dump_mask)
iwl_trans_dump_data(struct iwl_trans *trans, u32 dump_mask,
const struct iwl_dump_sanitize_ops *sanitize_ops,
void *sanitize_ctx)
{
if (!trans->ops->dump_data)
return NULL;
return trans->ops->dump_data(trans, dump_mask);
return trans->ops->dump_data(trans, dump_mask,
sanitize_ops, sanitize_ctx);
}
static inline struct iwl_device_tx_cmd *

Просмотреть файл

@ -1379,12 +1379,49 @@ int iwl_mvm_suspend(struct ieee80211_hw *hw, struct cfg80211_wowlan *wowlan)
/* converted data from the different status responses */
struct iwl_wowlan_status_data {
u16 pattern_number;
u16 qos_seq_ctr[8];
u64 replay_ctr;
u32 num_of_gtk_rekeys;
u32 received_beacons;
u32 wakeup_reasons;
u32 wake_packet_length;
u32 wake_packet_bufsize;
const u8 *wake_packet;
u16 pattern_number;
u16 non_qos_seq_ctr;
u16 qos_seq_ctr[8];
u8 tid_tear_down;
struct {
/*
* We store both the TKIP and AES representations
* coming from the firmware because we decode the
* data from there before we iterate the keys and
* know which one we need.
*/
struct {
struct ieee80211_key_seq seq[IWL_MAX_TID_COUNT];
} tkip, aes;
/* including RX MIC key for TKIP */
u8 key[WOWLAN_KEY_MAX_SIZE];
u8 len;
u8 flags;
} gtk;
struct {
/* Same as above */
struct {
struct ieee80211_key_seq seq[IWL_MAX_TID_COUNT];
u64 tx_pn;
} tkip, aes;
} ptk;
struct {
u64 ipn;
u8 key[WOWLAN_KEY_MAX_SIZE];
u8 len;
u8 flags;
} igtk;
u8 wake_packet[];
};
static void iwl_mvm_report_wakeup_reasons(struct iwl_mvm *mvm,
@ -1540,77 +1577,90 @@ static void iwl_mvm_tkip_sc_to_seq(struct tkip_sc *sc,
seq->tkip.iv16 = le16_to_cpu(sc->iv16);
}
static void iwl_mvm_set_aes_rx_seq(struct iwl_mvm *mvm, struct aes_sc *scs,
struct ieee80211_sta *sta,
struct ieee80211_key_conf *key)
static void iwl_mvm_set_key_rx_seq_tids(struct ieee80211_key_conf *key,
struct ieee80211_key_seq *seq)
{
int tid;
BUILD_BUG_ON(IWL_NUM_RSC != IEEE80211_NUM_TIDS);
if (sta && iwl_mvm_has_new_rx_api(mvm)) {
struct iwl_mvm_sta *mvmsta;
struct iwl_mvm_key_pn *ptk_pn;
mvmsta = iwl_mvm_sta_from_mac80211(sta);
rcu_read_lock();
ptk_pn = rcu_dereference(mvmsta->ptk_pn[key->keyidx]);
if (WARN_ON(!ptk_pn)) {
rcu_read_unlock();
return;
}
for (tid = 0; tid < IWL_MAX_TID_COUNT; tid++) {
struct ieee80211_key_seq seq = {};
int i;
iwl_mvm_aes_sc_to_seq(&scs[tid], &seq);
ieee80211_set_key_rx_seq(key, tid, &seq);
for (i = 1; i < mvm->trans->num_rx_queues; i++)
memcpy(ptk_pn->q[i].pn[tid],
seq.ccmp.pn, IEEE80211_CCMP_PN_LEN);
}
rcu_read_unlock();
} else {
for (tid = 0; tid < IWL_NUM_RSC; tid++) {
struct ieee80211_key_seq seq = {};
iwl_mvm_aes_sc_to_seq(&scs[tid], &seq);
ieee80211_set_key_rx_seq(key, tid, &seq);
}
}
for (tid = 0; tid < IWL_MAX_TID_COUNT; tid++)
ieee80211_set_key_rx_seq(key, tid, &seq[tid]);
}
static void iwl_mvm_set_tkip_rx_seq(struct tkip_sc *scs,
struct ieee80211_key_conf *key)
static void iwl_mvm_set_aes_ptk_rx_seq(struct iwl_mvm *mvm,
struct iwl_wowlan_status_data *status,
struct ieee80211_sta *sta,
struct ieee80211_key_conf *key)
{
struct iwl_mvm_sta *mvmsta = iwl_mvm_sta_from_mac80211(sta);
struct iwl_mvm_key_pn *ptk_pn;
int tid;
BUILD_BUG_ON(IWL_NUM_RSC != IEEE80211_NUM_TIDS);
iwl_mvm_set_key_rx_seq_tids(key, status->ptk.aes.seq);
for (tid = 0; tid < IWL_NUM_RSC; tid++) {
struct ieee80211_key_seq seq = {};
if (!iwl_mvm_has_new_rx_api(mvm))
return;
iwl_mvm_tkip_sc_to_seq(&scs[tid], &seq);
ieee80211_set_key_rx_seq(key, tid, &seq);
rcu_read_lock();
ptk_pn = rcu_dereference(mvmsta->ptk_pn[key->keyidx]);
if (WARN_ON(!ptk_pn)) {
rcu_read_unlock();
return;
}
for (tid = 0; tid < IWL_MAX_TID_COUNT; tid++) {
int i;
for (i = 1; i < mvm->trans->num_rx_queues; i++)
memcpy(ptk_pn->q[i].pn[tid],
status->ptk.aes.seq[tid].ccmp.pn,
IEEE80211_CCMP_PN_LEN);
}
rcu_read_unlock();
}
static void iwl_mvm_convert_key_counters(struct iwl_wowlan_status_data *status,
union iwl_all_tsc_rsc *sc)
{
int i;
BUILD_BUG_ON(IWL_MAX_TID_COUNT > IWL_MAX_TID_COUNT);
BUILD_BUG_ON(IWL_MAX_TID_COUNT > IWL_NUM_RSC);
/* GTK RX counters */
for (i = 0; i < IWL_MAX_TID_COUNT; i++) {
iwl_mvm_tkip_sc_to_seq(&sc->tkip.multicast_rsc[i],
&status->gtk.tkip.seq[i]);
iwl_mvm_aes_sc_to_seq(&sc->aes.multicast_rsc[i],
&status->gtk.aes.seq[i]);
}
/* PTK TX counter */
status->ptk.tkip.tx_pn = (u64)le16_to_cpu(sc->tkip.tsc.iv16) |
((u64)le32_to_cpu(sc->tkip.tsc.iv32) << 16);
status->ptk.aes.tx_pn = le64_to_cpu(sc->aes.tsc.pn);
/* PTK RX counters */
for (i = 0; i < IWL_MAX_TID_COUNT; i++) {
iwl_mvm_tkip_sc_to_seq(&sc->tkip.unicast_rsc[i],
&status->ptk.tkip.seq[i]);
iwl_mvm_aes_sc_to_seq(&sc->aes.unicast_rsc[i],
&status->ptk.aes.seq[i]);
}
}
static void iwl_mvm_set_key_rx_seq(struct iwl_mvm *mvm,
struct ieee80211_key_conf *key,
struct iwl_wowlan_status *status)
struct iwl_wowlan_status_data *status)
{
union iwl_all_tsc_rsc *rsc = &status->gtk[0].rsc.all_tsc_rsc;
switch (key->cipher) {
case WLAN_CIPHER_SUITE_CCMP:
case WLAN_CIPHER_SUITE_GCMP:
case WLAN_CIPHER_SUITE_GCMP_256:
iwl_mvm_set_aes_rx_seq(mvm, rsc->aes.multicast_rsc, NULL, key);
iwl_mvm_set_key_rx_seq_tids(key, status->gtk.aes.seq);
break;
case WLAN_CIPHER_SUITE_TKIP:
iwl_mvm_set_tkip_rx_seq(rsc->tkip.multicast_rsc, key);
iwl_mvm_set_key_rx_seq_tids(key, status->gtk.tkip.seq);
break;
default:
WARN_ON(1);
@ -1619,7 +1669,7 @@ static void iwl_mvm_set_key_rx_seq(struct iwl_mvm *mvm,
struct iwl_mvm_d3_gtk_iter_data {
struct iwl_mvm *mvm;
struct iwl_wowlan_status *status;
struct iwl_wowlan_status_data *status;
void *last_gtk;
u32 cipher;
bool find_phase, unhandled_cipher;
@ -1633,6 +1683,7 @@ static void iwl_mvm_d3_update_keys(struct ieee80211_hw *hw,
void *_data)
{
struct iwl_mvm_d3_gtk_iter_data *data = _data;
struct iwl_wowlan_status_data *status = data->status;
if (data->unhandled_cipher)
return;
@ -1661,10 +1712,6 @@ static void iwl_mvm_d3_update_keys(struct ieee80211_hw *hw,
* note that this assumes no TDLS sessions are active
*/
if (sta) {
struct ieee80211_key_seq seq = {};
union iwl_all_tsc_rsc *sc =
&data->status->gtk[0].rsc.all_tsc_rsc;
if (data->find_phase)
return;
@ -1672,16 +1719,12 @@ static void iwl_mvm_d3_update_keys(struct ieee80211_hw *hw,
case WLAN_CIPHER_SUITE_CCMP:
case WLAN_CIPHER_SUITE_GCMP:
case WLAN_CIPHER_SUITE_GCMP_256:
iwl_mvm_set_aes_rx_seq(data->mvm, sc->aes.unicast_rsc,
sta, key);
atomic64_set(&key->tx_pn, le64_to_cpu(sc->aes.tsc.pn));
atomic64_set(&key->tx_pn, status->ptk.aes.tx_pn);
iwl_mvm_set_aes_ptk_rx_seq(data->mvm, status, sta, key);
break;
case WLAN_CIPHER_SUITE_TKIP:
iwl_mvm_tkip_sc_to_seq(&sc->tkip.tsc, &seq);
iwl_mvm_set_tkip_rx_seq(sc->tkip.unicast_rsc, key);
atomic64_set(&key->tx_pn,
(u64)seq.tkip.iv16 |
((u64)seq.tkip.iv32 << 16));
atomic64_set(&key->tx_pn, status->ptk.tkip.tx_pn);
iwl_mvm_set_key_rx_seq_tids(key, status->ptk.tkip.seq);
break;
}
@ -1703,7 +1746,7 @@ static void iwl_mvm_d3_update_keys(struct ieee80211_hw *hw,
static bool iwl_mvm_setup_connection_keep(struct iwl_mvm *mvm,
struct ieee80211_vif *vif,
struct iwl_wowlan_status *status)
struct iwl_wowlan_status_data *status)
{
struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif);
struct iwl_mvm_d3_gtk_iter_data gtkdata = {
@ -1717,7 +1760,7 @@ static bool iwl_mvm_setup_connection_keep(struct iwl_mvm *mvm,
if (!status || !vif->bss_conf.bssid)
return false;
if (le32_to_cpu(status->wakeup_reasons) & disconnection_reasons)
if (status->wakeup_reasons & disconnection_reasons)
return false;
/* find last GTK that we used initially, if any */
@ -1741,7 +1784,7 @@ static bool iwl_mvm_setup_connection_keep(struct iwl_mvm *mvm,
iwl_mvm_d3_update_keys, &gtkdata);
IWL_DEBUG_WOWLAN(mvm, "num of GTK rekeying %d\n",
le32_to_cpu(status->num_of_gtk_rekeys));
status->num_of_gtk_rekeys);
if (status->num_of_gtk_rekeys) {
struct ieee80211_key_conf *key;
struct {
@ -1750,36 +1793,32 @@ static bool iwl_mvm_setup_connection_keep(struct iwl_mvm *mvm,
} conf = {
.conf.cipher = gtkdata.cipher,
.conf.keyidx =
iwlmvm_wowlan_gtk_idx(&status->gtk[0]),
status->gtk.flags & IWL_WOWLAN_GTK_IDX_MASK,
};
__be64 replay_ctr;
IWL_DEBUG_WOWLAN(mvm,
"Received from FW GTK cipher %d, key index %d\n",
conf.conf.cipher, conf.conf.keyidx);
BUILD_BUG_ON(WLAN_KEY_LEN_CCMP != WLAN_KEY_LEN_GCMP);
BUILD_BUG_ON(sizeof(conf.key) < WLAN_KEY_LEN_CCMP);
BUILD_BUG_ON(sizeof(conf.key) < WLAN_KEY_LEN_GCMP_256);
BUILD_BUG_ON(sizeof(conf.key) < WLAN_KEY_LEN_TKIP);
BUILD_BUG_ON(sizeof(conf.key) < sizeof(status->gtk.key));
memcpy(conf.conf.key, status->gtk.key, sizeof(status->gtk.key));
switch (gtkdata.cipher) {
case WLAN_CIPHER_SUITE_CCMP:
case WLAN_CIPHER_SUITE_GCMP:
BUILD_BUG_ON(WLAN_KEY_LEN_CCMP != WLAN_KEY_LEN_GCMP);
BUILD_BUG_ON(sizeof(conf.key) < WLAN_KEY_LEN_CCMP);
conf.conf.keylen = WLAN_KEY_LEN_CCMP;
memcpy(conf.conf.key, status->gtk[0].key,
WLAN_KEY_LEN_CCMP);
break;
case WLAN_CIPHER_SUITE_GCMP_256:
BUILD_BUG_ON(sizeof(conf.key) < WLAN_KEY_LEN_GCMP_256);
conf.conf.keylen = WLAN_KEY_LEN_GCMP_256;
memcpy(conf.conf.key, status->gtk[0].key,
WLAN_KEY_LEN_GCMP_256);
break;
case WLAN_CIPHER_SUITE_TKIP:
BUILD_BUG_ON(sizeof(conf.key) < WLAN_KEY_LEN_TKIP);
conf.conf.keylen = WLAN_KEY_LEN_TKIP;
memcpy(conf.conf.key, status->gtk[0].key, 16);
/* leave TX MIC key zeroed, we don't use it anyway */
memcpy(conf.conf.key +
NL80211_TKIP_DATA_OFFSET_RX_MIC_KEY,
status->gtk[0].tkip_mic_key, 8);
break;
}
@ -1788,8 +1827,7 @@ static bool iwl_mvm_setup_connection_keep(struct iwl_mvm *mvm,
return false;
iwl_mvm_set_key_rx_seq(mvm, key, status);
replay_ctr =
cpu_to_be64(le64_to_cpu(status->replay_ctr));
replay_ctr = cpu_to_be64(status->replay_ctr);
ieee80211_gtk_rekey_notify(vif, vif->bss_conf.bssid,
(void *)&replay_ctr, GFP_KERNEL);
@ -1800,7 +1838,7 @@ out:
WOWLAN_GET_STATUSES, 0) < 10) {
mvmvif->seqno_valid = true;
/* +0x10 because the set API expects next-to-use, not last-used */
mvmvif->seqno = le16_to_cpu(status->non_qos_seq_ctr) + 0x10;
mvmvif->seqno = status->non_qos_seq_ctr + 0x10;
}
return true;
@ -1808,13 +1846,13 @@ out:
/* Occasionally, templates would be nice. This is one of those times ... */
#define iwl_mvm_parse_wowlan_status_common(_ver) \
static struct iwl_wowlan_status * \
static struct iwl_wowlan_status_data * \
iwl_mvm_parse_wowlan_status_common_ ## _ver(struct iwl_mvm *mvm, \
void *_data, int len) \
struct iwl_wowlan_status_ ##_ver *data,\
int len) \
{ \
struct iwl_wowlan_status *status; \
struct iwl_wowlan_status_ ##_ver *data = _data; \
int data_size; \
struct iwl_wowlan_status_data *status; \
int data_size, i; \
\
if (len < sizeof(*data)) { \
IWL_ERR(mvm, "Invalid WoWLAN status response!\n"); \
@ -1832,18 +1870,22 @@ iwl_mvm_parse_wowlan_status_common_ ## _ver(struct iwl_mvm *mvm, \
return ERR_PTR(-ENOMEM); \
\
/* copy all the common fields */ \
status->replay_ctr = data->replay_ctr; \
status->pattern_number = data->pattern_number; \
status->non_qos_seq_ctr = data->non_qos_seq_ctr; \
memcpy(status->qos_seq_ctr, data->qos_seq_ctr, \
sizeof(status->qos_seq_ctr)); \
status->wakeup_reasons = data->wakeup_reasons; \
status->num_of_gtk_rekeys = data->num_of_gtk_rekeys; \
status->received_beacons = data->received_beacons; \
status->wake_packet_length = data->wake_packet_length; \
status->wake_packet_bufsize = data->wake_packet_bufsize; \
status->replay_ctr = le64_to_cpu(data->replay_ctr); \
status->pattern_number = le16_to_cpu(data->pattern_number); \
status->non_qos_seq_ctr = le16_to_cpu(data->non_qos_seq_ctr); \
for (i = 0; i < 8; i++) \
status->qos_seq_ctr[i] = \
le16_to_cpu(data->qos_seq_ctr[i]); \
status->wakeup_reasons = le32_to_cpu(data->wakeup_reasons); \
status->num_of_gtk_rekeys = \
le32_to_cpu(data->num_of_gtk_rekeys); \
status->received_beacons = le32_to_cpu(data->received_beacons); \
status->wake_packet_length = \
le32_to_cpu(data->wake_packet_length); \
status->wake_packet_bufsize = \
le32_to_cpu(data->wake_packet_bufsize); \
memcpy(status->wake_packet, data->wake_packet, \
le32_to_cpu(status->wake_packet_bufsize)); \
status->wake_packet_bufsize); \
\
return status; \
}
@ -1852,10 +1894,49 @@ iwl_mvm_parse_wowlan_status_common(v6)
iwl_mvm_parse_wowlan_status_common(v7)
iwl_mvm_parse_wowlan_status_common(v9)
static struct iwl_wowlan_status *
static void iwl_mvm_convert_gtk(struct iwl_wowlan_status_data *status,
struct iwl_wowlan_gtk_status *data)
{
BUILD_BUG_ON(sizeof(status->gtk.key) < sizeof(data->key));
BUILD_BUG_ON(NL80211_TKIP_DATA_OFFSET_RX_MIC_KEY +
sizeof(data->tkip_mic_key) >
sizeof(status->gtk.key));
status->gtk.len = data->key_len;
status->gtk.flags = data->key_flags;
memcpy(status->gtk.key, data->key, sizeof(data->key));
/* if it's as long as the TKIP encryption key, copy MIC key */
if (status->gtk.len == NL80211_TKIP_DATA_OFFSET_TX_MIC_KEY)
memcpy(status->gtk.key + NL80211_TKIP_DATA_OFFSET_RX_MIC_KEY,
data->tkip_mic_key, sizeof(data->tkip_mic_key));
}
static void iwl_mvm_convert_igtk(struct iwl_wowlan_status_data *status,
struct iwl_wowlan_igtk_status *data)
{
const u8 *ipn = data->ipn;
BUILD_BUG_ON(sizeof(status->igtk.key) < sizeof(data->key));
status->igtk.len = data->key_len;
status->igtk.flags = data->key_flags;
memcpy(status->igtk.key, data->key, sizeof(data->key));
status->igtk.ipn = ((u64)ipn[5] << 0) |
((u64)ipn[4] << 8) |
((u64)ipn[3] << 16) |
((u64)ipn[2] << 24) |
((u64)ipn[1] << 32) |
((u64)ipn[0] << 40);
}
static struct iwl_wowlan_status_data *
iwl_mvm_send_wowlan_get_status(struct iwl_mvm *mvm, u8 sta_id)
{
struct iwl_wowlan_status *status;
struct iwl_wowlan_status_data *status;
struct iwl_wowlan_get_status_cmd get_status_cmd = {
.sta_id = cpu_to_le32(sta_id),
};
@ -1895,59 +1976,57 @@ iwl_mvm_send_wowlan_get_status(struct iwl_mvm *mvm, u8 sta_id)
IWL_UCODE_TLV_API_WOWLAN_KEY_MATERIAL)) {
struct iwl_wowlan_status_v6 *v6 = (void *)cmd.resp_pkt->data;
status = iwl_mvm_parse_wowlan_status_common_v6(mvm,
cmd.resp_pkt->data,
len);
status = iwl_mvm_parse_wowlan_status_common_v6(mvm, v6, len);
if (IS_ERR(status))
goto out_free_resp;
BUILD_BUG_ON(sizeof(v6->gtk.decrypt_key) >
sizeof(status->gtk[0].key));
BUILD_BUG_ON(sizeof(v6->gtk.tkip_mic_key) >
sizeof(status->gtk[0].tkip_mic_key));
sizeof(status->gtk.key));
BUILD_BUG_ON(NL80211_TKIP_DATA_OFFSET_RX_MIC_KEY +
sizeof(v6->gtk.tkip_mic_key) >
sizeof(status->gtk.key));
/* copy GTK info to the right place */
memcpy(status->gtk[0].key, v6->gtk.decrypt_key,
memcpy(status->gtk.key, v6->gtk.decrypt_key,
sizeof(v6->gtk.decrypt_key));
memcpy(status->gtk[0].tkip_mic_key, v6->gtk.tkip_mic_key,
memcpy(status->gtk.key + NL80211_TKIP_DATA_OFFSET_RX_MIC_KEY,
v6->gtk.tkip_mic_key,
sizeof(v6->gtk.tkip_mic_key));
memcpy(&status->gtk[0].rsc, &v6->gtk.rsc,
sizeof(status->gtk[0].rsc));
iwl_mvm_convert_key_counters(status, &v6->gtk.rsc.all_tsc_rsc);
/* hardcode the key length to 16 since v6 only supports 16 */
status->gtk[0].key_len = 16;
status->gtk.len = 16;
/*
* The key index only uses 2 bits (values 0 to 3) and
* we always set bit 7 which means this is the
* currently used key.
*/
status->gtk[0].key_flags = v6->gtk.key_index | BIT(7);
status->gtk.flags = v6->gtk.key_index | BIT(7);
} else if (notif_ver == 7) {
struct iwl_wowlan_status_v7 *v7 = (void *)cmd.resp_pkt->data;
status = iwl_mvm_parse_wowlan_status_common_v7(mvm,
cmd.resp_pkt->data,
len);
status = iwl_mvm_parse_wowlan_status_common_v7(mvm, v7, len);
if (IS_ERR(status))
goto out_free_resp;
status->gtk[0] = v7->gtk[0];
status->igtk[0] = v7->igtk[0];
iwl_mvm_convert_key_counters(status, &v7->gtk[0].rsc.all_tsc_rsc);
iwl_mvm_convert_gtk(status, &v7->gtk[0]);
iwl_mvm_convert_igtk(status, &v7->igtk[0]);
} else if (notif_ver == 9 || notif_ver == 10 || notif_ver == 11) {
struct iwl_wowlan_status_v9 *v9 = (void *)cmd.resp_pkt->data;
/* these three command versions have same layout and size, the
* difference is only in a few not used (reserved) fields.
*/
status = iwl_mvm_parse_wowlan_status_common_v9(mvm,
cmd.resp_pkt->data,
len);
status = iwl_mvm_parse_wowlan_status_common_v9(mvm, v9, len);
if (IS_ERR(status))
goto out_free_resp;
status->gtk[0] = v9->gtk[0];
status->igtk[0] = v9->igtk[0];
iwl_mvm_convert_key_counters(status, &v9->gtk[0].rsc.all_tsc_rsc);
iwl_mvm_convert_gtk(status, &v9->gtk[0]);
iwl_mvm_convert_igtk(status, &v9->igtk[0]);
status->tid_tear_down = v9->tid_tear_down;
} else {
@ -1962,7 +2041,7 @@ out_free_resp:
return status;
}
static struct iwl_wowlan_status *
static struct iwl_wowlan_status_data *
iwl_mvm_get_wakeup_status(struct iwl_mvm *mvm, u8 sta_id)
{
u8 cmd_ver = iwl_fw_lookup_cmd_ver(mvm->fw, LONG_GROUP,
@ -1987,29 +2066,17 @@ static bool iwl_mvm_query_wakeup_reasons(struct iwl_mvm *mvm,
struct ieee80211_vif *vif)
{
struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif);
struct iwl_wowlan_status_data status;
struct iwl_wowlan_status *fw_status;
struct iwl_wowlan_status_data *status;
int i;
bool keep;
struct iwl_mvm_sta *mvm_ap_sta;
fw_status = iwl_mvm_get_wakeup_status(mvm, mvmvif->ap_sta_id);
if (IS_ERR_OR_NULL(fw_status))
status = iwl_mvm_get_wakeup_status(mvm, mvmvif->ap_sta_id);
if (IS_ERR(status))
goto out_unlock;
IWL_DEBUG_WOWLAN(mvm, "wakeup reason 0x%x\n",
le32_to_cpu(fw_status->wakeup_reasons));
status.pattern_number = le16_to_cpu(fw_status->pattern_number);
for (i = 0; i < 8; i++)
status.qos_seq_ctr[i] =
le16_to_cpu(fw_status->qos_seq_ctr[i]);
status.wakeup_reasons = le32_to_cpu(fw_status->wakeup_reasons);
status.wake_packet_length =
le32_to_cpu(fw_status->wake_packet_length);
status.wake_packet_bufsize =
le32_to_cpu(fw_status->wake_packet_bufsize);
status.wake_packet = fw_status->wake_packet;
status->wakeup_reasons);
/* still at hard-coded place 0 for D3 image */
mvm_ap_sta = iwl_mvm_sta_from_staid_protected(mvm, 0);
@ -2017,7 +2084,7 @@ static bool iwl_mvm_query_wakeup_reasons(struct iwl_mvm *mvm,
goto out_free;
for (i = 0; i < IWL_MAX_TID_COUNT; i++) {
u16 seq = status.qos_seq_ctr[i];
u16 seq = status->qos_seq_ctr[i];
/* firmware stores last-used value, we store next value */
seq += 0x10;
mvm_ap_sta->tid_data[i].seq_number = seq;
@ -2033,15 +2100,15 @@ static bool iwl_mvm_query_wakeup_reasons(struct iwl_mvm *mvm,
/* now we have all the data we need, unlock to avoid mac80211 issues */
mutex_unlock(&mvm->mutex);
iwl_mvm_report_wakeup_reasons(mvm, vif, &status);
iwl_mvm_report_wakeup_reasons(mvm, vif, status);
keep = iwl_mvm_setup_connection_keep(mvm, vif, fw_status);
keep = iwl_mvm_setup_connection_keep(mvm, vif, status);
kfree(fw_status);
kfree(status);
return keep;
out_free:
kfree(fw_status);
kfree(status);
out_unlock:
mutex_unlock(&mvm->mutex);
return false;
@ -2165,16 +2232,16 @@ static void iwl_mvm_query_netdetect_reasons(struct iwl_mvm *mvm,
.pattern_idx = -1,
};
struct cfg80211_wowlan_wakeup *wakeup_report = &wakeup;
struct iwl_wowlan_status_data *status;
struct iwl_mvm_nd_query_results query;
struct iwl_wowlan_status *fw_status;
unsigned long matched_profiles;
u32 reasons = 0;
int i, n_matches, ret;
fw_status = iwl_mvm_get_wakeup_status(mvm, IWL_MVM_INVALID_STA);
if (!IS_ERR_OR_NULL(fw_status)) {
reasons = le32_to_cpu(fw_status->wakeup_reasons);
kfree(fw_status);
status = iwl_mvm_get_wakeup_status(mvm, IWL_MVM_INVALID_STA);
if (!IS_ERR(status)) {
reasons = status->wakeup_reasons;
kfree(status);
}
if (reasons & IWL_WOWLAN_WAKEUP_BY_RFKILL_DEASSERTED)

Просмотреть файл

@ -395,10 +395,9 @@ static ssize_t iwl_dbgfs_rs_data_read(struct file *file, char __user *user_buf,
"A-MPDU size limit %d\n",
lq_sta->pers.dbg_agg_frame_count_lim);
desc += scnprintf(buff + desc, bufsz - desc,
"valid_tx_ant %s%s%s\n",
"valid_tx_ant %s%s\n",
(iwl_mvm_get_valid_tx_ant(mvm) & ANT_A) ? "ANT_A," : "",
(iwl_mvm_get_valid_tx_ant(mvm) & ANT_B) ? "ANT_B," : "",
(iwl_mvm_get_valid_tx_ant(mvm) & ANT_C) ? "ANT_C" : "");
(iwl_mvm_get_valid_tx_ant(mvm) & ANT_B) ? "ANT_B," : "");
desc += scnprintf(buff + desc, bufsz - desc,
"last tx rate=0x%X ",
lq_sta->last_rate_n_flags);
@ -986,8 +985,8 @@ static ssize_t iwl_dbgfs_frame_stats_read(struct iwl_mvm *mvm,
continue;
pos += scnprintf(pos, endpos - pos, "Rate[%d]: ",
(int)(ARRAY_SIZE(stats->last_rates) - i));
pos += rs_pretty_print_rate(pos, endpos - pos,
stats->last_rates[idx]);
pos += rs_pretty_print_rate_v1(pos, endpos - pos,
stats->last_rates[idx]);
if (pos < endpos - 1)
*pos++ = '\n';
}
@ -1060,8 +1059,6 @@ iwl_dbgfs_scan_ant_rxchain_read(struct file *file,
pos += scnprintf(buf + pos, bufsz - pos, "A");
if (mvm->scan_rx_ant & ANT_B)
pos += scnprintf(buf + pos, bufsz - pos, "B");
if (mvm->scan_rx_ant & ANT_C)
pos += scnprintf(buf + pos, bufsz - pos, "C");
pos += scnprintf(buf + pos, bufsz - pos, " (%hhx)\n", mvm->scan_rx_ant);
return simple_read_from_buffer(user_buf, count, ppos, buf, pos);
@ -1196,7 +1193,6 @@ static int _iwl_dbgfs_inject_beacon_ie(struct iwl_mvm *mvm, char *bin, int len)
struct ieee80211_tx_info *info;
struct iwl_mac_beacon_cmd beacon_cmd = {};
u8 rate;
u16 flags;
int i;
len /= 2;
@ -1243,12 +1239,9 @@ static int _iwl_dbgfs_inject_beacon_ie(struct iwl_mvm *mvm, char *bin, int len)
mvmvif = iwl_mvm_vif_from_mac80211(vif);
info = IEEE80211_SKB_CB(beacon);
rate = iwl_mvm_mac_ctxt_get_lowest_rate(info, vif);
flags = iwl_mvm_mac80211_idx_to_hwrate(rate);
if (rate == IWL_FIRST_CCK_RATE)
flags |= IWL_MAC_BEACON_CCK;
beacon_cmd.flags = cpu_to_le16(flags);
beacon_cmd.flags =
cpu_to_le16(iwl_mvm_mac_ctxt_get_beacon_flags(mvm->fw, rate));
beacon_cmd.byte_cnt = cpu_to_le16((u16)beacon->len);
beacon_cmd.template_id = cpu_to_le32((u32)mvmvif->id);

Просмотреть файл

@ -324,6 +324,7 @@ iwl_mvm_ftm_target_chandef_v2(struct iwl_mvm *mvm,
u8 *ctrl_ch_position)
{
u32 freq = peer->chandef.chan->center_freq;
u8 cmd_ver;
*channel = ieee80211_frequency_to_channel(freq);
@ -344,6 +345,17 @@ iwl_mvm_ftm_target_chandef_v2(struct iwl_mvm *mvm,
*format_bw = IWL_LOCATION_FRAME_FORMAT_VHT;
*format_bw |= IWL_LOCATION_BW_80MHZ << LOCATION_BW_POS;
break;
case NL80211_CHAN_WIDTH_160:
cmd_ver = iwl_fw_lookup_cmd_ver(mvm->fw, LOCATION_GROUP,
TOF_RANGE_REQ_CMD,
IWL_FW_CMD_VER_UNKNOWN);
if (cmd_ver >= 13) {
*format_bw = IWL_LOCATION_FRAME_FORMAT_HE;
*format_bw |= IWL_LOCATION_BW_160MHZ << LOCATION_BW_POS;
break;
}
fallthrough;
default:
IWL_ERR(mvm, "Unsupported BW in FTM request (%d)\n",
peer->chandef.width);
@ -1142,6 +1154,7 @@ static u8 iwl_mvm_ftm_get_range_resp_ver(struct iwl_mvm *mvm)
static bool iwl_mvm_ftm_resp_size_validation(u8 ver, unsigned int pkt_len)
{
switch (ver) {
case 9:
case 8:
return pkt_len == sizeof(struct iwl_tof_range_rsp_ntfy_v8);
case 7:
@ -1205,7 +1218,7 @@ void iwl_mvm_ftm_range_resp(struct iwl_mvm *mvm, struct iwl_rx_cmd_buffer *rxb)
int peer_idx;
if (new_api) {
if (notif_ver == 8) {
if (notif_ver >= 8) {
fw_ap = &fw_resp_v8->ap[i];
iwl_mvm_ftm_pasn_update_pn(mvm, fw_ap);
} else if (notif_ver == 7) {

Некоторые файлы не были показаны из-за слишком большого количества измененных файлов Показать больше