Lots of new things, notably:
* ath12k: monitor mode for WCN7850, better 6 GHz regulatory * brcmfmac: SAE for some Cypress devices * iwlwifi: rework device configuration * mac80211: scan improvements with MLO * mt76: EHT improvements, new device IDs * rtw88: throughput improvements * rtw89: MLO, STA/P2P concurrency improvements, SAR -----BEGIN PGP SIGNATURE----- iQIzBAABCgAdFiEEpeA8sTs3M8SN2hR410qiO8sPaAAFAmgvVpAACgkQ10qiO8sP aADeJg//dShJQPKKUw7s4qY9y0lr1kimFw7cKE1vhHAq0eyQE8VP/05sj7XkeLdO 2MDFCmWmTRZW1Av925xhicEhdiggxdOaT3n3RQ82y+Vjx7+6BsqqRE0YVRmK28vM MhUQocSzbd+Gh75wd4ti8G8dDPRJ9sbLTlZhIqPXMth2Ljl9EklMNzOlhzfo8N8+ TgZ8oJx0EZ2n+sObtI5US27rNiPzLCtAM10Nl03F5yxfSk7gh3UpLHFhmu7384Nx 56qqMwsmHHQSaRudg1ls8p30ztwve8/zHkOM6UeVksbb7CS2GHoPoVFtJUWBYmn9 Ckd/XNItniRmIbsABgOyybawJV7EKZAWHclffeICQc526VMZWxeD9xukxQZSykiu 3YXbHbPUkaCi3MlC3arc8SNQpW2l/BQvrC0SHqds4r/h/j4yUbA0wLs0OwqNXXwh NFoXnPTlkhMjNcX0W0t/A+EzXt/EsGKjBasiWC/tVZG9gHpMWKO3G8kLKmDyN/i9 NsUh7E7zJTBjYjS2Bhm4xGmSy3DdgKSkBV2d4qCG/0LoKAW2eIRw97DGyn0pfVlA BAmio94xDJ3AM565WeySmWi/ZqvuDgQy2rd3J1ji0F/QDhdwqUdIHXy9C3VbN9zB TegAIgDjnqpOLzCn2P2FzWZlXwcXsxG13XMvqr2DfhBZtNUmRsw= =NXiI -----END PGP SIGNATURE----- Merge tag 'wireless-next-2025-05-22' of https://git.kernel.org/pub/scm/linux/kernel/git/wireless/wireless-next Johannes Berg says: ==================== Lots of new things, notably: * ath12k: monitor mode for WCN7850, better 6 GHz regulatory * brcmfmac: SAE for some Cypress devices * iwlwifi: rework device configuration * mac80211: scan improvements with MLO * mt76: EHT improvements, new device IDs * rtw88: throughput improvements * rtw89: MLO, STA/P2P concurrency improvements, SAR * tag 'wireless-next-2025-05-22' of https://git.kernel.org/pub/scm/linux/kernel/git/wireless/wireless-next: (389 commits) wifi: mt76: mt7925: add rfkill_poll for hardware rfkill wifi: mt76: support power delta calculation for 5 TX paths wifi: mt76: fix available_antennas setting wifi: mt76: mt7996: fix RX buffer size of MCU event wifi: mt76: mt7996: change max beacon size wifi: mt76: mt7996: fix invalid NSS setting when TX path differs from NSS wifi: mt76: mt7996: drop fragments with multicast or broadcast RA wifi: mt76: mt7996: set EHT max ampdu length capability wifi: mt76: mt7996: fix beamformee SS field wifi: mt76: remove capability of partial bandwidth UL MU-MIMO wifi: mt76: mt7925: add test mode support wifi: mt76: mt7925: extend MCU support for testmode wifi: mt76: mt7925: ensure all MCU commands wait for response wifi: mt76: mt7925: refine the sniffer commnad wifi: mt76: mt7925: prevent multiple scan commands wifi: mt76: mt7915: Fix null-ptr-deref in mt7915_mmio_wed_init() wifi: mt76: mt7996: Fix null-ptr-deref in mt7996_mmio_wed_init() wifi: mt76: mt7925: add RNR scan support for 6GHz wifi: mt76: add mt76_connac_mcu_build_rnr_scan_param routine wifi: mt76: scan: Fix 'mlink' dereferenced before IS_ERR_OR_NULL check ... ==================== Link: https://patch.msgid.link/20250522165501.189958-50-johannes@sipsolutions.net Signed-off-by: Jakub Kicinski <kuba@kernel.org>
This commit is contained in:
commit
ea15e04626
@ -21,6 +21,12 @@ properties:
|
||||
reg:
|
||||
maxItems: 1
|
||||
|
||||
firmware-name:
|
||||
maxItems: 1
|
||||
description:
|
||||
If present, a board or platform specific string used to lookup
|
||||
usecase-specific firmware files for the device.
|
||||
|
||||
vddaon-supply:
|
||||
description: VDD_AON supply regulator handle
|
||||
|
||||
|
||||
@ -80,7 +80,7 @@ static inline u32 shadow_sr_wr_ind_addr(struct ath10k *ar,
|
||||
|
||||
static inline unsigned int
|
||||
ath10k_set_ring_byte(unsigned int offset,
|
||||
struct ath10k_hw_ce_regs_addr_map *addr_map)
|
||||
const struct ath10k_hw_ce_regs_addr_map *addr_map)
|
||||
{
|
||||
return ((offset << addr_map->lsb) & addr_map->mask);
|
||||
}
|
||||
@ -203,7 +203,7 @@ static inline void ath10k_ce_src_ring_dmax_set(struct ath10k *ar,
|
||||
u32 ce_ctrl_addr,
|
||||
unsigned int n)
|
||||
{
|
||||
struct ath10k_hw_ce_ctrl1 *ctrl_regs = ar->hw_ce_regs->ctrl1_regs;
|
||||
const struct ath10k_hw_ce_ctrl1 *ctrl_regs = ar->hw_ce_regs->ctrl1_regs;
|
||||
|
||||
u32 ctrl1_addr = ath10k_ce_read32(ar, ce_ctrl_addr +
|
||||
ctrl_regs->addr);
|
||||
@ -217,7 +217,7 @@ static inline void ath10k_ce_src_ring_byte_swap_set(struct ath10k *ar,
|
||||
u32 ce_ctrl_addr,
|
||||
unsigned int n)
|
||||
{
|
||||
struct ath10k_hw_ce_ctrl1 *ctrl_regs = ar->hw_ce_regs->ctrl1_regs;
|
||||
const struct ath10k_hw_ce_ctrl1 *ctrl_regs = ar->hw_ce_regs->ctrl1_regs;
|
||||
|
||||
u32 ctrl1_addr = ath10k_ce_read32(ar, ce_ctrl_addr +
|
||||
ctrl_regs->addr);
|
||||
@ -231,7 +231,7 @@ static inline void ath10k_ce_dest_ring_byte_swap_set(struct ath10k *ar,
|
||||
u32 ce_ctrl_addr,
|
||||
unsigned int n)
|
||||
{
|
||||
struct ath10k_hw_ce_ctrl1 *ctrl_regs = ar->hw_ce_regs->ctrl1_regs;
|
||||
const struct ath10k_hw_ce_ctrl1 *ctrl_regs = ar->hw_ce_regs->ctrl1_regs;
|
||||
|
||||
u32 ctrl1_addr = ath10k_ce_read32(ar, ce_ctrl_addr +
|
||||
ctrl_regs->addr);
|
||||
@ -313,7 +313,7 @@ static inline void ath10k_ce_src_ring_highmark_set(struct ath10k *ar,
|
||||
u32 ce_ctrl_addr,
|
||||
unsigned int n)
|
||||
{
|
||||
struct ath10k_hw_ce_dst_src_wm_regs *srcr_wm = ar->hw_ce_regs->wm_srcr;
|
||||
const struct ath10k_hw_ce_dst_src_wm_regs *srcr_wm = ar->hw_ce_regs->wm_srcr;
|
||||
u32 addr = ath10k_ce_read32(ar, ce_ctrl_addr + srcr_wm->addr);
|
||||
|
||||
ath10k_ce_write32(ar, ce_ctrl_addr + srcr_wm->addr,
|
||||
@ -325,7 +325,7 @@ static inline void ath10k_ce_src_ring_lowmark_set(struct ath10k *ar,
|
||||
u32 ce_ctrl_addr,
|
||||
unsigned int n)
|
||||
{
|
||||
struct ath10k_hw_ce_dst_src_wm_regs *srcr_wm = ar->hw_ce_regs->wm_srcr;
|
||||
const struct ath10k_hw_ce_dst_src_wm_regs *srcr_wm = ar->hw_ce_regs->wm_srcr;
|
||||
u32 addr = ath10k_ce_read32(ar, ce_ctrl_addr + srcr_wm->addr);
|
||||
|
||||
ath10k_ce_write32(ar, ce_ctrl_addr + srcr_wm->addr,
|
||||
@ -337,7 +337,7 @@ static inline void ath10k_ce_dest_ring_highmark_set(struct ath10k *ar,
|
||||
u32 ce_ctrl_addr,
|
||||
unsigned int n)
|
||||
{
|
||||
struct ath10k_hw_ce_dst_src_wm_regs *dstr_wm = ar->hw_ce_regs->wm_dstr;
|
||||
const struct ath10k_hw_ce_dst_src_wm_regs *dstr_wm = ar->hw_ce_regs->wm_dstr;
|
||||
u32 addr = ath10k_ce_read32(ar, ce_ctrl_addr + dstr_wm->addr);
|
||||
|
||||
ath10k_ce_write32(ar, ce_ctrl_addr + dstr_wm->addr,
|
||||
@ -349,7 +349,7 @@ static inline void ath10k_ce_dest_ring_lowmark_set(struct ath10k *ar,
|
||||
u32 ce_ctrl_addr,
|
||||
unsigned int n)
|
||||
{
|
||||
struct ath10k_hw_ce_dst_src_wm_regs *dstr_wm = ar->hw_ce_regs->wm_dstr;
|
||||
const struct ath10k_hw_ce_dst_src_wm_regs *dstr_wm = ar->hw_ce_regs->wm_dstr;
|
||||
u32 addr = ath10k_ce_read32(ar, ce_ctrl_addr + dstr_wm->addr);
|
||||
|
||||
ath10k_ce_write32(ar, ce_ctrl_addr + dstr_wm->addr,
|
||||
@ -360,7 +360,7 @@ static inline void ath10k_ce_dest_ring_lowmark_set(struct ath10k *ar,
|
||||
static inline void ath10k_ce_copy_complete_inter_enable(struct ath10k *ar,
|
||||
u32 ce_ctrl_addr)
|
||||
{
|
||||
struct ath10k_hw_ce_host_ie *host_ie = ar->hw_ce_regs->host_ie;
|
||||
const struct ath10k_hw_ce_host_ie *host_ie = ar->hw_ce_regs->host_ie;
|
||||
|
||||
u32 host_ie_addr = ath10k_ce_read32(ar, ce_ctrl_addr +
|
||||
ar->hw_ce_regs->host_ie_addr);
|
||||
@ -372,7 +372,7 @@ static inline void ath10k_ce_copy_complete_inter_enable(struct ath10k *ar,
|
||||
static inline void ath10k_ce_copy_complete_intr_disable(struct ath10k *ar,
|
||||
u32 ce_ctrl_addr)
|
||||
{
|
||||
struct ath10k_hw_ce_host_ie *host_ie = ar->hw_ce_regs->host_ie;
|
||||
const struct ath10k_hw_ce_host_ie *host_ie = ar->hw_ce_regs->host_ie;
|
||||
|
||||
u32 host_ie_addr = ath10k_ce_read32(ar, ce_ctrl_addr +
|
||||
ar->hw_ce_regs->host_ie_addr);
|
||||
@ -384,7 +384,7 @@ static inline void ath10k_ce_copy_complete_intr_disable(struct ath10k *ar,
|
||||
static inline void ath10k_ce_watermark_intr_disable(struct ath10k *ar,
|
||||
u32 ce_ctrl_addr)
|
||||
{
|
||||
struct ath10k_hw_ce_host_wm_regs *wm_regs = ar->hw_ce_regs->wm_regs;
|
||||
const struct ath10k_hw_ce_host_wm_regs *wm_regs = ar->hw_ce_regs->wm_regs;
|
||||
|
||||
u32 host_ie_addr = ath10k_ce_read32(ar, ce_ctrl_addr +
|
||||
ar->hw_ce_regs->host_ie_addr);
|
||||
@ -396,7 +396,7 @@ static inline void ath10k_ce_watermark_intr_disable(struct ath10k *ar,
|
||||
static inline void ath10k_ce_error_intr_disable(struct ath10k *ar,
|
||||
u32 ce_ctrl_addr)
|
||||
{
|
||||
struct ath10k_hw_ce_misc_regs *misc_regs = ar->hw_ce_regs->misc_regs;
|
||||
const struct ath10k_hw_ce_misc_regs *misc_regs = ar->hw_ce_regs->misc_regs;
|
||||
|
||||
u32 misc_ie_addr = ath10k_ce_read32(ar,
|
||||
ce_ctrl_addr + ar->hw_ce_regs->misc_ie_addr);
|
||||
@ -410,7 +410,7 @@ static inline void ath10k_ce_engine_int_status_clear(struct ath10k *ar,
|
||||
u32 ce_ctrl_addr,
|
||||
unsigned int mask)
|
||||
{
|
||||
struct ath10k_hw_ce_host_wm_regs *wm_regs = ar->hw_ce_regs->wm_regs;
|
||||
const struct ath10k_hw_ce_host_wm_regs *wm_regs = ar->hw_ce_regs->wm_regs;
|
||||
|
||||
ath10k_ce_write32(ar, ce_ctrl_addr + wm_regs->addr, mask);
|
||||
}
|
||||
@ -1230,7 +1230,7 @@ void ath10k_ce_per_engine_service(struct ath10k *ar, unsigned int ce_id)
|
||||
{
|
||||
struct ath10k_ce *ce = ath10k_ce_priv(ar);
|
||||
struct ath10k_ce_pipe *ce_state = &ce->ce_states[ce_id];
|
||||
struct ath10k_hw_ce_host_wm_regs *wm_regs = ar->hw_ce_regs->wm_regs;
|
||||
const struct ath10k_hw_ce_host_wm_regs *wm_regs = ar->hw_ce_regs->wm_regs;
|
||||
u32 ctrl_addr = ce_state->ctrl_addr;
|
||||
|
||||
/*
|
||||
|
||||
@ -212,40 +212,40 @@ const struct ath10k_hw_regs wcn3990_regs = {
|
||||
.pcie_intr_fw_mask = 0x00100000,
|
||||
};
|
||||
|
||||
static struct ath10k_hw_ce_regs_addr_map wcn3990_src_ring = {
|
||||
static const struct ath10k_hw_ce_regs_addr_map wcn3990_src_ring = {
|
||||
.msb = 0x00000010,
|
||||
.lsb = 0x00000010,
|
||||
.mask = GENMASK(17, 17),
|
||||
};
|
||||
|
||||
static struct ath10k_hw_ce_regs_addr_map wcn3990_dst_ring = {
|
||||
static const struct ath10k_hw_ce_regs_addr_map wcn3990_dst_ring = {
|
||||
.msb = 0x00000012,
|
||||
.lsb = 0x00000012,
|
||||
.mask = GENMASK(18, 18),
|
||||
};
|
||||
|
||||
static struct ath10k_hw_ce_regs_addr_map wcn3990_dmax = {
|
||||
static const struct ath10k_hw_ce_regs_addr_map wcn3990_dmax = {
|
||||
.msb = 0x00000000,
|
||||
.lsb = 0x00000000,
|
||||
.mask = GENMASK(15, 0),
|
||||
};
|
||||
|
||||
static struct ath10k_hw_ce_ctrl1 wcn3990_ctrl1 = {
|
||||
static const struct ath10k_hw_ce_ctrl1 wcn3990_ctrl1 = {
|
||||
.addr = 0x00000018,
|
||||
.src_ring = &wcn3990_src_ring,
|
||||
.dst_ring = &wcn3990_dst_ring,
|
||||
.dmax = &wcn3990_dmax,
|
||||
};
|
||||
|
||||
static struct ath10k_hw_ce_regs_addr_map wcn3990_host_ie_cc = {
|
||||
static const struct ath10k_hw_ce_regs_addr_map wcn3990_host_ie_cc = {
|
||||
.mask = GENMASK(0, 0),
|
||||
};
|
||||
|
||||
static struct ath10k_hw_ce_host_ie wcn3990_host_ie = {
|
||||
static const struct ath10k_hw_ce_host_ie wcn3990_host_ie = {
|
||||
.copy_complete = &wcn3990_host_ie_cc,
|
||||
};
|
||||
|
||||
static struct ath10k_hw_ce_host_wm_regs wcn3990_wm_reg = {
|
||||
static const struct ath10k_hw_ce_host_wm_regs wcn3990_wm_reg = {
|
||||
.dstr_lmask = 0x00000010,
|
||||
.dstr_hmask = 0x00000008,
|
||||
.srcr_lmask = 0x00000004,
|
||||
@ -255,7 +255,7 @@ static struct ath10k_hw_ce_host_wm_regs wcn3990_wm_reg = {
|
||||
.addr = 0x00000030,
|
||||
};
|
||||
|
||||
static struct ath10k_hw_ce_misc_regs wcn3990_misc_reg = {
|
||||
static const struct ath10k_hw_ce_misc_regs wcn3990_misc_reg = {
|
||||
.axi_err = 0x00000100,
|
||||
.dstr_add_err = 0x00000200,
|
||||
.srcr_len_err = 0x00000100,
|
||||
@ -266,19 +266,19 @@ static struct ath10k_hw_ce_misc_regs wcn3990_misc_reg = {
|
||||
.addr = 0x00000038,
|
||||
};
|
||||
|
||||
static struct ath10k_hw_ce_regs_addr_map wcn3990_src_wm_low = {
|
||||
static const struct ath10k_hw_ce_regs_addr_map wcn3990_src_wm_low = {
|
||||
.msb = 0x00000000,
|
||||
.lsb = 0x00000010,
|
||||
.mask = GENMASK(31, 16),
|
||||
};
|
||||
|
||||
static struct ath10k_hw_ce_regs_addr_map wcn3990_src_wm_high = {
|
||||
static const struct ath10k_hw_ce_regs_addr_map wcn3990_src_wm_high = {
|
||||
.msb = 0x0000000f,
|
||||
.lsb = 0x00000000,
|
||||
.mask = GENMASK(15, 0),
|
||||
};
|
||||
|
||||
static struct ath10k_hw_ce_dst_src_wm_regs wcn3990_wm_src_ring = {
|
||||
static const struct ath10k_hw_ce_dst_src_wm_regs wcn3990_wm_src_ring = {
|
||||
.addr = 0x0000004c,
|
||||
.low_rst = 0x00000000,
|
||||
.high_rst = 0x00000000,
|
||||
@ -286,18 +286,18 @@ static struct ath10k_hw_ce_dst_src_wm_regs wcn3990_wm_src_ring = {
|
||||
.wm_high = &wcn3990_src_wm_high,
|
||||
};
|
||||
|
||||
static struct ath10k_hw_ce_regs_addr_map wcn3990_dst_wm_low = {
|
||||
static const struct ath10k_hw_ce_regs_addr_map wcn3990_dst_wm_low = {
|
||||
.lsb = 0x00000010,
|
||||
.mask = GENMASK(31, 16),
|
||||
};
|
||||
|
||||
static struct ath10k_hw_ce_regs_addr_map wcn3990_dst_wm_high = {
|
||||
static const struct ath10k_hw_ce_regs_addr_map wcn3990_dst_wm_high = {
|
||||
.msb = 0x0000000f,
|
||||
.lsb = 0x00000000,
|
||||
.mask = GENMASK(15, 0),
|
||||
};
|
||||
|
||||
static struct ath10k_hw_ce_dst_src_wm_regs wcn3990_wm_dst_ring = {
|
||||
static const struct ath10k_hw_ce_dst_src_wm_regs wcn3990_wm_dst_ring = {
|
||||
.addr = 0x00000050,
|
||||
.low_rst = 0x00000000,
|
||||
.high_rst = 0x00000000,
|
||||
@ -305,7 +305,7 @@ static struct ath10k_hw_ce_dst_src_wm_regs wcn3990_wm_dst_ring = {
|
||||
.wm_high = &wcn3990_dst_wm_high,
|
||||
};
|
||||
|
||||
static struct ath10k_hw_ce_ctrl1_upd wcn3990_ctrl1_upd = {
|
||||
static const struct ath10k_hw_ce_ctrl1_upd wcn3990_ctrl1_upd = {
|
||||
.shift = 19,
|
||||
.mask = 0x00080000,
|
||||
.enable = 0x00000000,
|
||||
@ -344,25 +344,25 @@ const struct ath10k_hw_values wcn3990_values = {
|
||||
.ce_desc_meta_data_lsb = 4,
|
||||
};
|
||||
|
||||
static struct ath10k_hw_ce_regs_addr_map qcax_src_ring = {
|
||||
static const struct ath10k_hw_ce_regs_addr_map qcax_src_ring = {
|
||||
.msb = 0x00000010,
|
||||
.lsb = 0x00000010,
|
||||
.mask = GENMASK(16, 16),
|
||||
};
|
||||
|
||||
static struct ath10k_hw_ce_regs_addr_map qcax_dst_ring = {
|
||||
static const struct ath10k_hw_ce_regs_addr_map qcax_dst_ring = {
|
||||
.msb = 0x00000011,
|
||||
.lsb = 0x00000011,
|
||||
.mask = GENMASK(17, 17),
|
||||
};
|
||||
|
||||
static struct ath10k_hw_ce_regs_addr_map qcax_dmax = {
|
||||
static const struct ath10k_hw_ce_regs_addr_map qcax_dmax = {
|
||||
.msb = 0x0000000f,
|
||||
.lsb = 0x00000000,
|
||||
.mask = GENMASK(15, 0),
|
||||
};
|
||||
|
||||
static struct ath10k_hw_ce_ctrl1 qcax_ctrl1 = {
|
||||
static const struct ath10k_hw_ce_ctrl1 qcax_ctrl1 = {
|
||||
.addr = 0x00000010,
|
||||
.hw_mask = 0x0007ffff,
|
||||
.sw_mask = 0x0007ffff,
|
||||
@ -375,31 +375,31 @@ static struct ath10k_hw_ce_ctrl1 qcax_ctrl1 = {
|
||||
.dmax = &qcax_dmax,
|
||||
};
|
||||
|
||||
static struct ath10k_hw_ce_regs_addr_map qcax_cmd_halt_status = {
|
||||
static const struct ath10k_hw_ce_regs_addr_map qcax_cmd_halt_status = {
|
||||
.msb = 0x00000003,
|
||||
.lsb = 0x00000003,
|
||||
.mask = GENMASK(3, 3),
|
||||
};
|
||||
|
||||
static struct ath10k_hw_ce_cmd_halt qcax_cmd_halt = {
|
||||
static const struct ath10k_hw_ce_cmd_halt qcax_cmd_halt = {
|
||||
.msb = 0x00000000,
|
||||
.mask = GENMASK(0, 0),
|
||||
.status_reset = 0x00000000,
|
||||
.status = &qcax_cmd_halt_status,
|
||||
};
|
||||
|
||||
static struct ath10k_hw_ce_regs_addr_map qcax_host_ie_cc = {
|
||||
static const struct ath10k_hw_ce_regs_addr_map qcax_host_ie_cc = {
|
||||
.msb = 0x00000000,
|
||||
.lsb = 0x00000000,
|
||||
.mask = GENMASK(0, 0),
|
||||
};
|
||||
|
||||
static struct ath10k_hw_ce_host_ie qcax_host_ie = {
|
||||
static const struct ath10k_hw_ce_host_ie qcax_host_ie = {
|
||||
.copy_complete_reset = 0x00000000,
|
||||
.copy_complete = &qcax_host_ie_cc,
|
||||
};
|
||||
|
||||
static struct ath10k_hw_ce_host_wm_regs qcax_wm_reg = {
|
||||
static const struct ath10k_hw_ce_host_wm_regs qcax_wm_reg = {
|
||||
.dstr_lmask = 0x00000010,
|
||||
.dstr_hmask = 0x00000008,
|
||||
.srcr_lmask = 0x00000004,
|
||||
@ -409,7 +409,7 @@ static struct ath10k_hw_ce_host_wm_regs qcax_wm_reg = {
|
||||
.addr = 0x00000030,
|
||||
};
|
||||
|
||||
static struct ath10k_hw_ce_misc_regs qcax_misc_reg = {
|
||||
static const struct ath10k_hw_ce_misc_regs qcax_misc_reg = {
|
||||
.axi_err = 0x00000400,
|
||||
.dstr_add_err = 0x00000200,
|
||||
.srcr_len_err = 0x00000100,
|
||||
@ -420,19 +420,19 @@ static struct ath10k_hw_ce_misc_regs qcax_misc_reg = {
|
||||
.addr = 0x00000038,
|
||||
};
|
||||
|
||||
static struct ath10k_hw_ce_regs_addr_map qcax_src_wm_low = {
|
||||
static const struct ath10k_hw_ce_regs_addr_map qcax_src_wm_low = {
|
||||
.msb = 0x0000001f,
|
||||
.lsb = 0x00000010,
|
||||
.mask = GENMASK(31, 16),
|
||||
};
|
||||
|
||||
static struct ath10k_hw_ce_regs_addr_map qcax_src_wm_high = {
|
||||
static const struct ath10k_hw_ce_regs_addr_map qcax_src_wm_high = {
|
||||
.msb = 0x0000000f,
|
||||
.lsb = 0x00000000,
|
||||
.mask = GENMASK(15, 0),
|
||||
};
|
||||
|
||||
static struct ath10k_hw_ce_dst_src_wm_regs qcax_wm_src_ring = {
|
||||
static const struct ath10k_hw_ce_dst_src_wm_regs qcax_wm_src_ring = {
|
||||
.addr = 0x0000004c,
|
||||
.low_rst = 0x00000000,
|
||||
.high_rst = 0x00000000,
|
||||
@ -440,18 +440,18 @@ static struct ath10k_hw_ce_dst_src_wm_regs qcax_wm_src_ring = {
|
||||
.wm_high = &qcax_src_wm_high,
|
||||
};
|
||||
|
||||
static struct ath10k_hw_ce_regs_addr_map qcax_dst_wm_low = {
|
||||
static const struct ath10k_hw_ce_regs_addr_map qcax_dst_wm_low = {
|
||||
.lsb = 0x00000010,
|
||||
.mask = GENMASK(31, 16),
|
||||
};
|
||||
|
||||
static struct ath10k_hw_ce_regs_addr_map qcax_dst_wm_high = {
|
||||
static const struct ath10k_hw_ce_regs_addr_map qcax_dst_wm_high = {
|
||||
.msb = 0x0000000f,
|
||||
.lsb = 0x00000000,
|
||||
.mask = GENMASK(15, 0),
|
||||
};
|
||||
|
||||
static struct ath10k_hw_ce_dst_src_wm_regs qcax_wm_dst_ring = {
|
||||
static const struct ath10k_hw_ce_dst_src_wm_regs qcax_wm_dst_ring = {
|
||||
.addr = 0x00000050,
|
||||
.low_rst = 0x00000000,
|
||||
.high_rst = 0x00000000,
|
||||
|
||||
@ -289,19 +289,22 @@ struct ath10k_hw_ce_ctrl1 {
|
||||
u32 sw_wr_mask;
|
||||
u32 reset_mask;
|
||||
u32 reset;
|
||||
struct ath10k_hw_ce_regs_addr_map *src_ring;
|
||||
struct ath10k_hw_ce_regs_addr_map *dst_ring;
|
||||
struct ath10k_hw_ce_regs_addr_map *dmax; };
|
||||
const struct ath10k_hw_ce_regs_addr_map *src_ring;
|
||||
const struct ath10k_hw_ce_regs_addr_map *dst_ring;
|
||||
const struct ath10k_hw_ce_regs_addr_map *dmax;
|
||||
};
|
||||
|
||||
struct ath10k_hw_ce_cmd_halt {
|
||||
u32 status_reset;
|
||||
u32 msb;
|
||||
u32 mask;
|
||||
struct ath10k_hw_ce_regs_addr_map *status; };
|
||||
const struct ath10k_hw_ce_regs_addr_map *status;
|
||||
};
|
||||
|
||||
struct ath10k_hw_ce_host_ie {
|
||||
u32 copy_complete_reset;
|
||||
struct ath10k_hw_ce_regs_addr_map *copy_complete; };
|
||||
const struct ath10k_hw_ce_regs_addr_map *copy_complete;
|
||||
};
|
||||
|
||||
struct ath10k_hw_ce_host_wm_regs {
|
||||
u32 dstr_lmask;
|
||||
@ -328,8 +331,9 @@ struct ath10k_hw_ce_dst_src_wm_regs {
|
||||
u32 addr;
|
||||
u32 low_rst;
|
||||
u32 high_rst;
|
||||
struct ath10k_hw_ce_regs_addr_map *wm_low;
|
||||
struct ath10k_hw_ce_regs_addr_map *wm_high; };
|
||||
const struct ath10k_hw_ce_regs_addr_map *wm_low;
|
||||
const struct ath10k_hw_ce_regs_addr_map *wm_high;
|
||||
};
|
||||
|
||||
struct ath10k_hw_ce_ctrl1_upd {
|
||||
u32 shift;
|
||||
@ -355,14 +359,14 @@ struct ath10k_hw_ce_regs {
|
||||
u32 ce_rri_low;
|
||||
u32 ce_rri_high;
|
||||
u32 host_ie_addr;
|
||||
struct ath10k_hw_ce_host_wm_regs *wm_regs;
|
||||
struct ath10k_hw_ce_misc_regs *misc_regs;
|
||||
struct ath10k_hw_ce_ctrl1 *ctrl1_regs;
|
||||
struct ath10k_hw_ce_cmd_halt *cmd_halt;
|
||||
struct ath10k_hw_ce_host_ie *host_ie;
|
||||
struct ath10k_hw_ce_dst_src_wm_regs *wm_srcr;
|
||||
struct ath10k_hw_ce_dst_src_wm_regs *wm_dstr;
|
||||
struct ath10k_hw_ce_ctrl1_upd *upd;
|
||||
const struct ath10k_hw_ce_host_wm_regs *wm_regs;
|
||||
const struct ath10k_hw_ce_misc_regs *misc_regs;
|
||||
const struct ath10k_hw_ce_ctrl1 *ctrl1_regs;
|
||||
const struct ath10k_hw_ce_cmd_halt *cmd_halt;
|
||||
const struct ath10k_hw_ce_host_ie *host_ie;
|
||||
const struct ath10k_hw_ce_dst_src_wm_regs *wm_srcr;
|
||||
const struct ath10k_hw_ce_dst_src_wm_regs *wm_dstr;
|
||||
const struct ath10k_hw_ce_ctrl1_upd *upd;
|
||||
};
|
||||
|
||||
struct ath10k_hw_values {
|
||||
|
||||
@ -1844,7 +1844,7 @@ static int ath10k_sdio_get_htt_tx_complete(struct ath10k *ar)
|
||||
ret = ath10k_sdio_diag_read32(ar, addr, &val);
|
||||
if (ret) {
|
||||
ath10k_warn(ar,
|
||||
"unable to read hi_acs_flags for htt tx comple : %d\n", ret);
|
||||
"unable to read hi_acs_flags for htt tx complete: %d\n", ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
@ -393,11 +393,10 @@ static int ath11k_ce_completed_recv_next(struct ath11k_ce_pipe *pipe,
|
||||
goto err;
|
||||
}
|
||||
|
||||
/* Make sure descriptor is read after the head pointer. */
|
||||
dma_rmb();
|
||||
|
||||
*nbytes = ath11k_hal_ce_dst_status_get_length(desc);
|
||||
if (*nbytes == 0) {
|
||||
ret = -EIO;
|
||||
goto err;
|
||||
}
|
||||
|
||||
*skb = pipe->dest_ring->skb[sw_index];
|
||||
pipe->dest_ring->skb[sw_index] = NULL;
|
||||
@ -430,8 +429,8 @@ static void ath11k_ce_recv_process_cb(struct ath11k_ce_pipe *pipe)
|
||||
dma_unmap_single(ab->dev, ATH11K_SKB_RXCB(skb)->paddr,
|
||||
max_nbytes, DMA_FROM_DEVICE);
|
||||
|
||||
if (unlikely(max_nbytes < nbytes)) {
|
||||
ath11k_warn(ab, "rxed more than expected (nbytes %d, max %d)",
|
||||
if (unlikely(max_nbytes < nbytes || nbytes == 0)) {
|
||||
ath11k_warn(ab, "unexpected rx length (nbytes %d, max %d)",
|
||||
nbytes, max_nbytes);
|
||||
dev_kfree_skb_any(skb);
|
||||
continue;
|
||||
|
||||
@ -2637,7 +2637,7 @@ int ath11k_dp_process_rx(struct ath11k_base *ab, int ring_id,
|
||||
struct ath11k *ar;
|
||||
struct hal_reo_dest_ring *desc;
|
||||
enum hal_reo_dest_ring_push_reason push_reason;
|
||||
u32 cookie;
|
||||
u32 cookie, info0, rx_msdu_info0, rx_mpdu_info0;
|
||||
int i;
|
||||
|
||||
for (i = 0; i < MAX_RADIOS; i++)
|
||||
@ -2650,11 +2650,14 @@ int ath11k_dp_process_rx(struct ath11k_base *ab, int ring_id,
|
||||
try_again:
|
||||
ath11k_hal_srng_access_begin(ab, srng);
|
||||
|
||||
/* Make sure descriptor is read after the head pointer. */
|
||||
dma_rmb();
|
||||
|
||||
while (likely(desc =
|
||||
(struct hal_reo_dest_ring *)ath11k_hal_srng_dst_get_next_entry(ab,
|
||||
srng))) {
|
||||
cookie = FIELD_GET(BUFFER_ADDR_INFO1_SW_COOKIE,
|
||||
desc->buf_addr_info.info1);
|
||||
READ_ONCE(desc->buf_addr_info.info1));
|
||||
buf_id = FIELD_GET(DP_RXDMA_BUF_COOKIE_BUF_ID,
|
||||
cookie);
|
||||
mac_id = FIELD_GET(DP_RXDMA_BUF_COOKIE_PDEV_ID, cookie);
|
||||
@ -2683,8 +2686,9 @@ int ath11k_dp_process_rx(struct ath11k_base *ab, int ring_id,
|
||||
|
||||
num_buffs_reaped[mac_id]++;
|
||||
|
||||
info0 = READ_ONCE(desc->info0);
|
||||
push_reason = FIELD_GET(HAL_REO_DEST_RING_INFO0_PUSH_REASON,
|
||||
desc->info0);
|
||||
info0);
|
||||
if (unlikely(push_reason !=
|
||||
HAL_REO_DEST_RING_PUSH_REASON_ROUTING_INSTRUCTION)) {
|
||||
dev_kfree_skb_any(msdu);
|
||||
@ -2692,18 +2696,21 @@ int ath11k_dp_process_rx(struct ath11k_base *ab, int ring_id,
|
||||
continue;
|
||||
}
|
||||
|
||||
rxcb->is_first_msdu = !!(desc->rx_msdu_info.info0 &
|
||||
rx_msdu_info0 = READ_ONCE(desc->rx_msdu_info.info0);
|
||||
rx_mpdu_info0 = READ_ONCE(desc->rx_mpdu_info.info0);
|
||||
|
||||
rxcb->is_first_msdu = !!(rx_msdu_info0 &
|
||||
RX_MSDU_DESC_INFO0_FIRST_MSDU_IN_MPDU);
|
||||
rxcb->is_last_msdu = !!(desc->rx_msdu_info.info0 &
|
||||
rxcb->is_last_msdu = !!(rx_msdu_info0 &
|
||||
RX_MSDU_DESC_INFO0_LAST_MSDU_IN_MPDU);
|
||||
rxcb->is_continuation = !!(desc->rx_msdu_info.info0 &
|
||||
rxcb->is_continuation = !!(rx_msdu_info0 &
|
||||
RX_MSDU_DESC_INFO0_MSDU_CONTINUATION);
|
||||
rxcb->peer_id = FIELD_GET(RX_MPDU_DESC_META_DATA_PEER_ID,
|
||||
desc->rx_mpdu_info.meta_data);
|
||||
READ_ONCE(desc->rx_mpdu_info.meta_data));
|
||||
rxcb->seq_no = FIELD_GET(RX_MPDU_DESC_INFO0_SEQ_NUM,
|
||||
desc->rx_mpdu_info.info0);
|
||||
rx_mpdu_info0);
|
||||
rxcb->tid = FIELD_GET(HAL_REO_DEST_RING_INFO0_RX_QUEUE_NUM,
|
||||
desc->info0);
|
||||
info0);
|
||||
|
||||
rxcb->mac_id = mac_id;
|
||||
__skb_queue_tail(&msdu_list[mac_id], msdu);
|
||||
|
||||
@ -599,7 +599,7 @@ u32 ath11k_hal_ce_dst_status_get_length(void *buf)
|
||||
struct hal_ce_srng_dst_status_desc *desc = buf;
|
||||
u32 len;
|
||||
|
||||
len = FIELD_GET(HAL_CE_DST_STATUS_DESC_FLAGS_LEN, desc->flags);
|
||||
len = FIELD_GET(HAL_CE_DST_STATUS_DESC_FLAGS_LEN, READ_ONCE(desc->flags));
|
||||
desc->flags &= ~HAL_CE_DST_STATUS_DESC_FLAGS_LEN;
|
||||
|
||||
return len;
|
||||
@ -829,7 +829,7 @@ void ath11k_hal_srng_access_begin(struct ath11k_base *ab, struct hal_srng *srng)
|
||||
srng->u.src_ring.cached_tp =
|
||||
*(volatile u32 *)srng->u.src_ring.tp_addr;
|
||||
} else {
|
||||
srng->u.dst_ring.cached_hp = *srng->u.dst_ring.hp_addr;
|
||||
srng->u.dst_ring.cached_hp = READ_ONCE(*srng->u.dst_ring.hp_addr);
|
||||
|
||||
/* Try to prefetch the next descriptor in the ring */
|
||||
if (srng->flags & HAL_SRNG_FLAGS_CACHED)
|
||||
|
||||
@ -9972,12 +9972,17 @@ static int ath11k_mac_setup_iface_combinations(struct ath11k *ar)
|
||||
struct ath11k_base *ab = ar->ab;
|
||||
struct ieee80211_iface_combination *combinations;
|
||||
struct ieee80211_iface_limit *limits;
|
||||
int n_limits;
|
||||
int n_limits, n_combos;
|
||||
bool p2p;
|
||||
|
||||
p2p = ab->hw_params.interface_modes & BIT(NL80211_IFTYPE_P2P_DEVICE);
|
||||
|
||||
combinations = kzalloc(sizeof(*combinations), GFP_KERNEL);
|
||||
if (ab->hw_params.support_dual_stations)
|
||||
n_combos = 2;
|
||||
else
|
||||
n_combos = 1;
|
||||
|
||||
combinations = kcalloc(n_combos, sizeof(*combinations), GFP_KERNEL);
|
||||
if (!combinations)
|
||||
return -ENOMEM;
|
||||
|
||||
@ -9992,7 +9997,9 @@ static int ath11k_mac_setup_iface_combinations(struct ath11k *ar)
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
limits[0].max = 1;
|
||||
limits[0].types |= BIT(NL80211_IFTYPE_STATION);
|
||||
limits[1].max = 16;
|
||||
limits[1].types |= BIT(NL80211_IFTYPE_AP);
|
||||
if (IS_ENABLED(CONFIG_MAC80211_MESH) &&
|
||||
ab->hw_params.interface_modes & BIT(NL80211_IFTYPE_MESH_POINT))
|
||||
@ -10002,25 +10009,24 @@ static int ath11k_mac_setup_iface_combinations(struct ath11k *ar)
|
||||
combinations[0].n_limits = n_limits;
|
||||
combinations[0].beacon_int_infra_match = true;
|
||||
combinations[0].beacon_int_min_gcd = 100;
|
||||
combinations[0].max_interfaces = 16;
|
||||
combinations[0].num_different_channels = 1;
|
||||
combinations[0].radar_detect_widths = BIT(NL80211_CHAN_WIDTH_20_NOHT) |
|
||||
BIT(NL80211_CHAN_WIDTH_20) |
|
||||
BIT(NL80211_CHAN_WIDTH_40) |
|
||||
BIT(NL80211_CHAN_WIDTH_80) |
|
||||
BIT(NL80211_CHAN_WIDTH_80P80) |
|
||||
BIT(NL80211_CHAN_WIDTH_160);
|
||||
|
||||
if (ab->hw_params.support_dual_stations) {
|
||||
limits[0].max = 2;
|
||||
limits[1].max = 1;
|
||||
|
||||
combinations[0].max_interfaces = ab->hw_params.num_vdevs;
|
||||
combinations[0].num_different_channels = 2;
|
||||
} else {
|
||||
limits[0].max = 1;
|
||||
limits[1].max = 16;
|
||||
|
||||
combinations[0].max_interfaces = 16;
|
||||
combinations[0].num_different_channels = 1;
|
||||
combinations[0].radar_detect_widths = BIT(NL80211_CHAN_WIDTH_20_NOHT) |
|
||||
BIT(NL80211_CHAN_WIDTH_20) |
|
||||
BIT(NL80211_CHAN_WIDTH_40) |
|
||||
BIT(NL80211_CHAN_WIDTH_80) |
|
||||
BIT(NL80211_CHAN_WIDTH_80P80) |
|
||||
BIT(NL80211_CHAN_WIDTH_160);
|
||||
combinations[1].limits = limits;
|
||||
combinations[1].n_limits = n_limits;
|
||||
combinations[1].beacon_int_infra_match = true;
|
||||
combinations[1].beacon_int_min_gcd = 100;
|
||||
combinations[1].max_interfaces = ab->hw_params.num_vdevs;
|
||||
combinations[1].num_different_channels = 2;
|
||||
}
|
||||
|
||||
if (p2p) {
|
||||
@ -10031,7 +10037,7 @@ static int ath11k_mac_setup_iface_combinations(struct ath11k *ar)
|
||||
}
|
||||
|
||||
ar->hw->wiphy->iface_combinations = combinations;
|
||||
ar->hw->wiphy->n_iface_combinations = 1;
|
||||
ar->hw->wiphy->n_iface_combinations = n_combos;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -1993,6 +1993,15 @@ static int ath11k_qmi_alloc_target_mem_chunk(struct ath11k_base *ab)
|
||||
chunk->prev_size == chunk->size)
|
||||
continue;
|
||||
|
||||
if (ab->qmi.mem_seg_count <= ATH11K_QMI_FW_MEM_REQ_SEGMENT_CNT) {
|
||||
ath11k_dbg(ab, ATH11K_DBG_QMI,
|
||||
"size/type mismatch (current %d %u) (prev %d %u), try later with small size\n",
|
||||
chunk->size, chunk->type,
|
||||
chunk->prev_size, chunk->prev_type);
|
||||
ab->qmi.target_mem_delayed = true;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* cannot reuse the existing chunk */
|
||||
dma_free_coherent(ab->dev, chunk->prev_size,
|
||||
chunk->vaddr, chunk->paddr);
|
||||
|
||||
@ -1125,14 +1125,13 @@ static void ath12k_ahb_remove(struct platform_device *pdev)
|
||||
|
||||
if (test_bit(ATH12K_FLAG_QMI_FAIL, &ab->dev_flags)) {
|
||||
ath12k_ahb_power_down(ab, false);
|
||||
ath12k_qmi_deinit_service(ab);
|
||||
goto qmi_fail;
|
||||
}
|
||||
|
||||
ath12k_ahb_remove_prepare(ab);
|
||||
ath12k_core_deinit(ab);
|
||||
|
||||
ath12k_core_hw_group_cleanup(ab->ag);
|
||||
qmi_fail:
|
||||
ath12k_core_deinit(ab);
|
||||
ath12k_ahb_free_resources(ab);
|
||||
}
|
||||
|
||||
|
||||
@ -433,11 +433,10 @@ static int ath12k_ce_completed_recv_next(struct ath12k_ce_pipe *pipe,
|
||||
goto err;
|
||||
}
|
||||
|
||||
/* Make sure descriptor is read after the head pointer. */
|
||||
dma_rmb();
|
||||
|
||||
*nbytes = ath12k_hal_ce_dst_status_get_length(desc);
|
||||
if (*nbytes == 0) {
|
||||
ret = -EIO;
|
||||
goto err;
|
||||
}
|
||||
|
||||
*skb = pipe->dest_ring->skb[sw_index];
|
||||
pipe->dest_ring->skb[sw_index] = NULL;
|
||||
@ -470,8 +469,8 @@ static void ath12k_ce_recv_process_cb(struct ath12k_ce_pipe *pipe)
|
||||
dma_unmap_single(ab->dev, ATH12K_SKB_RXCB(skb)->paddr,
|
||||
max_nbytes, DMA_FROM_DEVICE);
|
||||
|
||||
if (unlikely(max_nbytes < nbytes)) {
|
||||
ath12k_warn(ab, "rxed more than expected (nbytes %d, max %d)",
|
||||
if (unlikely(max_nbytes < nbytes || nbytes == 0)) {
|
||||
ath12k_warn(ab, "unexpected rx length (nbytes %d, max %d)",
|
||||
nbytes, max_nbytes);
|
||||
dev_kfree_skb_any(skb);
|
||||
continue;
|
||||
|
||||
@ -697,7 +697,7 @@ static void ath12k_core_stop(struct ath12k_base *ab)
|
||||
/* De-Init of components as needed */
|
||||
}
|
||||
|
||||
static void ath12k_core_check_bdfext(const struct dmi_header *hdr, void *data)
|
||||
static void ath12k_core_check_cc_code_bdfext(const struct dmi_header *hdr, void *data)
|
||||
{
|
||||
struct ath12k_base *ab = data;
|
||||
const char *magic = ATH12K_SMBIOS_BDF_EXT_MAGIC;
|
||||
@ -719,6 +719,28 @@ static void ath12k_core_check_bdfext(const struct dmi_header *hdr, void *data)
|
||||
return;
|
||||
}
|
||||
|
||||
spin_lock_bh(&ab->base_lock);
|
||||
|
||||
switch (smbios->country_code_flag) {
|
||||
case ATH12K_SMBIOS_CC_ISO:
|
||||
ab->new_alpha2[0] = u16_get_bits(smbios->cc_code >> 8, 0xff);
|
||||
ab->new_alpha2[1] = u16_get_bits(smbios->cc_code, 0xff);
|
||||
ath12k_dbg(ab, ATH12K_DBG_BOOT, "boot smbios cc_code %c%c\n",
|
||||
ab->new_alpha2[0], ab->new_alpha2[1]);
|
||||
break;
|
||||
case ATH12K_SMBIOS_CC_WW:
|
||||
ab->new_alpha2[0] = '0';
|
||||
ab->new_alpha2[1] = '0';
|
||||
ath12k_dbg(ab, ATH12K_DBG_BOOT, "boot smbios worldwide regdomain\n");
|
||||
break;
|
||||
default:
|
||||
ath12k_dbg(ab, ATH12K_DBG_BOOT, "boot ignore smbios country code setting %d\n",
|
||||
smbios->country_code_flag);
|
||||
break;
|
||||
}
|
||||
|
||||
spin_unlock_bh(&ab->base_lock);
|
||||
|
||||
if (!smbios->bdf_enabled) {
|
||||
ath12k_dbg(ab, ATH12K_DBG_BOOT, "bdf variant name not found.\n");
|
||||
return;
|
||||
@ -758,7 +780,7 @@ static void ath12k_core_check_bdfext(const struct dmi_header *hdr, void *data)
|
||||
int ath12k_core_check_smbios(struct ath12k_base *ab)
|
||||
{
|
||||
ab->qmi.target.bdf_ext[0] = '\0';
|
||||
dmi_walk(ath12k_core_check_bdfext, ab);
|
||||
dmi_walk(ath12k_core_check_cc_code_bdfext, ab);
|
||||
|
||||
if (ab->qmi.target.bdf_ext[0] == '\0')
|
||||
return -ENODATA;
|
||||
@ -789,6 +811,8 @@ static int ath12k_core_soc_create(struct ath12k_base *ab)
|
||||
goto err_qmi_deinit;
|
||||
}
|
||||
|
||||
ath12k_debugfs_pdev_create(ab);
|
||||
|
||||
return 0;
|
||||
|
||||
err_qmi_deinit:
|
||||
@ -1812,9 +1836,9 @@ static int ath12k_core_get_wsi_info(struct ath12k_hw_group *ag,
|
||||
of_node_put(next_rx_endpoint);
|
||||
|
||||
device_count++;
|
||||
if (device_count > ATH12K_MAX_SOCS) {
|
||||
if (device_count > ATH12K_MAX_DEVICES) {
|
||||
ath12k_warn(ab, "device count in DT %d is more than limit %d\n",
|
||||
device_count, ATH12K_MAX_SOCS);
|
||||
device_count, ATH12K_MAX_DEVICES);
|
||||
of_node_put(next_wsi_dev);
|
||||
return -EINVAL;
|
||||
}
|
||||
@ -1990,7 +2014,7 @@ static void ath12k_core_hw_group_destroy(struct ath12k_hw_group *ag)
|
||||
}
|
||||
}
|
||||
|
||||
static void ath12k_core_hw_group_cleanup(struct ath12k_hw_group *ag)
|
||||
void ath12k_core_hw_group_cleanup(struct ath12k_hw_group *ag)
|
||||
{
|
||||
struct ath12k_base *ab;
|
||||
int i;
|
||||
@ -2136,10 +2160,9 @@ int ath12k_core_init(struct ath12k_base *ab)
|
||||
|
||||
void ath12k_core_deinit(struct ath12k_base *ab)
|
||||
{
|
||||
ath12k_core_panic_notifier_unregister(ab);
|
||||
ath12k_core_hw_group_cleanup(ab->ag);
|
||||
ath12k_core_hw_group_destroy(ab->ag);
|
||||
ath12k_core_hw_group_unassign(ab);
|
||||
ath12k_core_panic_notifier_unregister(ab);
|
||||
}
|
||||
|
||||
void ath12k_core_free(struct ath12k_base *ab)
|
||||
|
||||
@ -17,6 +17,7 @@
|
||||
#include <linux/of_reserved_mem.h>
|
||||
#include <linux/panic_notifier.h>
|
||||
#include <linux/average.h>
|
||||
#include <linux/of.h>
|
||||
#include "qmi.h"
|
||||
#include "htc.h"
|
||||
#include "wmi.h"
|
||||
@ -63,8 +64,8 @@
|
||||
#define ATH12K_RECONFIGURE_TIMEOUT_HZ (10 * HZ)
|
||||
#define ATH12K_RECOVER_START_TIMEOUT_HZ (20 * HZ)
|
||||
|
||||
#define ATH12K_MAX_SOCS 3
|
||||
#define ATH12K_GROUP_MAX_RADIO (ATH12K_MAX_SOCS * MAX_RADIOS)
|
||||
#define ATH12K_MAX_DEVICES 3
|
||||
#define ATH12K_GROUP_MAX_RADIO (ATH12K_MAX_DEVICES * MAX_RADIOS)
|
||||
#define ATH12K_INVALID_GROUP_ID 0xFF
|
||||
#define ATH12K_INVALID_DEVICE_ID 0xFF
|
||||
|
||||
@ -175,9 +176,34 @@ struct ath12k_ext_irq_grp {
|
||||
struct net_device *napi_ndev;
|
||||
};
|
||||
|
||||
enum ath12k_smbios_cc_type {
|
||||
/* disable country code setting from SMBIOS */
|
||||
ATH12K_SMBIOS_CC_DISABLE = 0,
|
||||
|
||||
/* set country code by ANSI country name, based on ISO3166-1 alpha2 */
|
||||
ATH12K_SMBIOS_CC_ISO = 1,
|
||||
|
||||
/* worldwide regdomain */
|
||||
ATH12K_SMBIOS_CC_WW = 2,
|
||||
};
|
||||
|
||||
struct ath12k_smbios_bdf {
|
||||
struct dmi_header hdr;
|
||||
u32 padding;
|
||||
u8 features_disabled;
|
||||
|
||||
/* enum ath12k_smbios_cc_type */
|
||||
u8 country_code_flag;
|
||||
|
||||
/* To set specific country, you need to set country code
|
||||
* flag=ATH12K_SMBIOS_CC_ISO first, then if country is United
|
||||
* States, then country code value = 0x5553 ("US",'U' = 0x55, 'S'=
|
||||
* 0x53). To set country to INDONESIA, then country code value =
|
||||
* 0x4944 ("IN", 'I'=0x49, 'D'=0x44). If country code flag =
|
||||
* ATH12K_SMBIOS_CC_WW, then you can use worldwide regulatory
|
||||
* setting.
|
||||
*/
|
||||
u16 cc_code;
|
||||
|
||||
u8 bdf_enabled;
|
||||
u8 bdf_ext[];
|
||||
} __packed;
|
||||
@ -317,6 +343,8 @@ struct ath12k_link_vif {
|
||||
|
||||
/* only used in station mode */
|
||||
bool is_sta_assoc_link;
|
||||
|
||||
struct ath12k_reg_tpc_power_info reg_tpc_info;
|
||||
};
|
||||
|
||||
struct ath12k_vif {
|
||||
@ -784,6 +812,8 @@ struct ath12k {
|
||||
u8 ftm_msgref;
|
||||
struct ath12k_fw_stats fw_stats;
|
||||
unsigned long last_tx_power_update;
|
||||
|
||||
s8 max_allowed_tx_power;
|
||||
};
|
||||
|
||||
struct ath12k_hw {
|
||||
@ -875,7 +905,7 @@ struct ath12k_board_data {
|
||||
size_t len;
|
||||
};
|
||||
|
||||
struct ath12k_soc_dp_tx_err_stats {
|
||||
struct ath12k_device_dp_tx_err_stats {
|
||||
/* TCL Ring Descriptor unavailable */
|
||||
u32 desc_na[DP_TCL_NUM_RING_MAX];
|
||||
/* Other failures during dp_tx due to mem allocation failure
|
||||
@ -884,13 +914,20 @@ struct ath12k_soc_dp_tx_err_stats {
|
||||
atomic_t misc_fail;
|
||||
};
|
||||
|
||||
struct ath12k_soc_dp_stats {
|
||||
struct ath12k_device_dp_stats {
|
||||
u32 err_ring_pkts;
|
||||
u32 invalid_rbm;
|
||||
u32 rxdma_error[HAL_REO_ENTR_RING_RXDMA_ECODE_MAX];
|
||||
u32 reo_error[HAL_REO_DEST_RING_ERROR_CODE_MAX];
|
||||
u32 hal_reo_error[DP_REO_DST_RING_MAX];
|
||||
struct ath12k_soc_dp_tx_err_stats tx_err;
|
||||
struct ath12k_device_dp_tx_err_stats tx_err;
|
||||
u32 reo_rx[DP_REO_DST_RING_MAX][ATH12K_MAX_DEVICES];
|
||||
u32 rx_wbm_rel_source[HAL_WBM_REL_SRC_MODULE_MAX][ATH12K_MAX_DEVICES];
|
||||
u32 tqm_rel_reason[MAX_TQM_RELEASE_REASON];
|
||||
u32 fw_tx_status[MAX_FW_TX_STATUS];
|
||||
u32 tx_wbm_rel_source[HAL_WBM_REL_SRC_MODULE_MAX];
|
||||
u32 tx_enqueued[DP_TCL_NUM_RING_MAX];
|
||||
u32 tx_completed[DP_TCL_NUM_RING_MAX];
|
||||
};
|
||||
|
||||
struct ath12k_reg_freq {
|
||||
@ -919,7 +956,7 @@ struct ath12k_hw_group {
|
||||
u8 num_probed;
|
||||
u8 num_started;
|
||||
unsigned long flags;
|
||||
struct ath12k_base *ab[ATH12K_MAX_SOCS];
|
||||
struct ath12k_base *ab[ATH12K_MAX_DEVICES];
|
||||
|
||||
/* protects access to this struct */
|
||||
struct mutex mutex;
|
||||
@ -933,7 +970,7 @@ struct ath12k_hw_group {
|
||||
struct ath12k_hw *ah[ATH12K_GROUP_MAX_RADIO];
|
||||
u8 num_hw;
|
||||
bool mlo_capable;
|
||||
struct device_node *wsi_node[ATH12K_MAX_SOCS];
|
||||
struct device_node *wsi_node[ATH12K_MAX_DEVICES];
|
||||
struct ath12k_mlo_memory mlo_mem;
|
||||
struct ath12k_hw_link hw_links[ATH12K_GROUP_MAX_RADIO];
|
||||
bool hw_link_id_init_done;
|
||||
@ -1041,9 +1078,11 @@ struct ath12k_base {
|
||||
*/
|
||||
struct ieee80211_regdomain *new_regd[MAX_RADIOS];
|
||||
|
||||
struct ath12k_reg_info *reg_info[MAX_RADIOS];
|
||||
|
||||
/* Current DFS Regulatory */
|
||||
enum ath12k_dfs_region dfs_region;
|
||||
struct ath12k_soc_dp_stats soc_stats;
|
||||
struct ath12k_device_dp_stats device_stats;
|
||||
#ifdef CONFIG_ATH12K_DEBUGFS
|
||||
struct dentry *debugfs_soc;
|
||||
#endif
|
||||
@ -1072,8 +1111,6 @@ struct ath12k_base {
|
||||
struct ath12k_dbring_cap *db_caps;
|
||||
u32 num_db_cap;
|
||||
|
||||
struct timer_list mon_reap_timer;
|
||||
|
||||
struct completion htc_suspend;
|
||||
|
||||
u64 fw_soc_drop_count;
|
||||
@ -1246,6 +1283,7 @@ struct ath12k_fw_stats_pdev {
|
||||
};
|
||||
|
||||
int ath12k_core_qmi_firmware_ready(struct ath12k_base *ab);
|
||||
void ath12k_core_hw_group_cleanup(struct ath12k_hw_group *ag);
|
||||
int ath12k_core_pre_init(struct ath12k_base *ab);
|
||||
int ath12k_core_init(struct ath12k_base *ath12k);
|
||||
void ath12k_core_deinit(struct ath12k_base *ath12k);
|
||||
@ -1342,8 +1380,16 @@ static inline void ath12k_core_create_firmware_path(struct ath12k_base *ab,
|
||||
const char *filename,
|
||||
void *buf, size_t buf_len)
|
||||
{
|
||||
snprintf(buf, buf_len, "%s/%s/%s", ATH12K_FW_DIR,
|
||||
ab->hw_params->fw.dir, filename);
|
||||
const char *fw_name = NULL;
|
||||
|
||||
of_property_read_string(ab->dev->of_node, "firmware-name", &fw_name);
|
||||
|
||||
if (fw_name && strncmp(filename, "board", 5))
|
||||
snprintf(buf, buf_len, "%s/%s/%s/%s", ATH12K_FW_DIR,
|
||||
ab->hw_params->fw.dir, fw_name, filename);
|
||||
else
|
||||
snprintf(buf, buf_len, "%s/%s/%s", ATH12K_FW_DIR,
|
||||
ab->hw_params->fw.dir, filename);
|
||||
}
|
||||
|
||||
static inline const char *ath12k_bus_str(enum ath12k_bus bus)
|
||||
|
||||
@ -33,6 +33,76 @@ static const struct file_operations fops_simulate_radar = {
|
||||
.open = simple_open
|
||||
};
|
||||
|
||||
static ssize_t ath12k_read_simulate_fw_crash(struct file *file,
|
||||
char __user *user_buf,
|
||||
size_t count, loff_t *ppos)
|
||||
{
|
||||
const char buf[] =
|
||||
"To simulate firmware crash write one of the keywords to this file:\n"
|
||||
"`assert` - send WMI_FORCE_FW_HANG_CMDID to firmware to cause assert.\n";
|
||||
|
||||
return simple_read_from_buffer(user_buf, count, ppos, buf, strlen(buf));
|
||||
}
|
||||
|
||||
static ssize_t
|
||||
ath12k_write_simulate_fw_crash(struct file *file,
|
||||
const char __user *user_buf,
|
||||
size_t count, loff_t *ppos)
|
||||
{
|
||||
struct ath12k_base *ab = file->private_data;
|
||||
struct ath12k_pdev *pdev;
|
||||
struct ath12k *ar = NULL;
|
||||
char buf[32] = {0};
|
||||
int i, ret;
|
||||
ssize_t rc;
|
||||
|
||||
/* filter partial writes and invalid commands */
|
||||
if (*ppos != 0 || count >= sizeof(buf) || count == 0)
|
||||
return -EINVAL;
|
||||
|
||||
rc = simple_write_to_buffer(buf, sizeof(buf) - 1, ppos, user_buf, count);
|
||||
if (rc < 0)
|
||||
return rc;
|
||||
|
||||
/* drop the possible '\n' from the end */
|
||||
if (buf[*ppos - 1] == '\n')
|
||||
buf[*ppos - 1] = '\0';
|
||||
|
||||
for (i = 0; i < ab->num_radios; i++) {
|
||||
pdev = &ab->pdevs[i];
|
||||
ar = pdev->ar;
|
||||
if (ar)
|
||||
break;
|
||||
}
|
||||
|
||||
if (!ar)
|
||||
return -ENETDOWN;
|
||||
|
||||
if (!strcmp(buf, "assert")) {
|
||||
ath12k_info(ab, "simulating firmware assert crash\n");
|
||||
ret = ath12k_wmi_force_fw_hang_cmd(ar,
|
||||
ATH12K_WMI_FW_HANG_ASSERT_TYPE,
|
||||
ATH12K_WMI_FW_HANG_DELAY);
|
||||
} else {
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (ret) {
|
||||
ath12k_warn(ab, "failed to simulate firmware crash: %d\n", ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
return count;
|
||||
}
|
||||
|
||||
static const struct file_operations fops_simulate_fw_crash = {
|
||||
.read = ath12k_read_simulate_fw_crash,
|
||||
.write = ath12k_write_simulate_fw_crash,
|
||||
.open = simple_open,
|
||||
.owner = THIS_MODULE,
|
||||
.llseek = default_llseek,
|
||||
};
|
||||
|
||||
static ssize_t ath12k_write_tpc_stats_type(struct file *file,
|
||||
const char __user *user_buf,
|
||||
size_t count, loff_t *ppos)
|
||||
@ -951,6 +1021,199 @@ void ath12k_debugfs_op_vif_add(struct ieee80211_hw *hw,
|
||||
&ath12k_fops_link_stats);
|
||||
}
|
||||
|
||||
static ssize_t ath12k_debugfs_dump_device_dp_stats(struct file *file,
|
||||
char __user *user_buf,
|
||||
size_t count, loff_t *ppos)
|
||||
{
|
||||
struct ath12k_base *ab = file->private_data;
|
||||
struct ath12k_device_dp_stats *device_stats = &ab->device_stats;
|
||||
int len = 0, i, j, ret;
|
||||
struct ath12k *ar;
|
||||
const int size = 4096;
|
||||
static const char *rxdma_err[HAL_REO_ENTR_RING_RXDMA_ECODE_MAX] = {
|
||||
[HAL_REO_ENTR_RING_RXDMA_ECODE_OVERFLOW_ERR] = "Overflow",
|
||||
[HAL_REO_ENTR_RING_RXDMA_ECODE_MPDU_LEN_ERR] = "MPDU len",
|
||||
[HAL_REO_ENTR_RING_RXDMA_ECODE_FCS_ERR] = "FCS",
|
||||
[HAL_REO_ENTR_RING_RXDMA_ECODE_DECRYPT_ERR] = "Decrypt",
|
||||
[HAL_REO_ENTR_RING_RXDMA_ECODE_TKIP_MIC_ERR] = "TKIP MIC",
|
||||
[HAL_REO_ENTR_RING_RXDMA_ECODE_UNECRYPTED_ERR] = "Unencrypt",
|
||||
[HAL_REO_ENTR_RING_RXDMA_ECODE_MSDU_LEN_ERR] = "MSDU len",
|
||||
[HAL_REO_ENTR_RING_RXDMA_ECODE_MSDU_LIMIT_ERR] = "MSDU limit",
|
||||
[HAL_REO_ENTR_RING_RXDMA_ECODE_WIFI_PARSE_ERR] = "WiFi parse",
|
||||
[HAL_REO_ENTR_RING_RXDMA_ECODE_AMSDU_PARSE_ERR] = "AMSDU parse",
|
||||
[HAL_REO_ENTR_RING_RXDMA_ECODE_SA_TIMEOUT_ERR] = "SA timeout",
|
||||
[HAL_REO_ENTR_RING_RXDMA_ECODE_DA_TIMEOUT_ERR] = "DA timeout",
|
||||
[HAL_REO_ENTR_RING_RXDMA_ECODE_FLOW_TIMEOUT_ERR] = "Flow timeout",
|
||||
[HAL_REO_ENTR_RING_RXDMA_ECODE_FLUSH_REQUEST_ERR] = "Flush req",
|
||||
[HAL_REO_ENTR_RING_RXDMA_ECODE_AMSDU_FRAG_ERR] = "AMSDU frag",
|
||||
[HAL_REO_ENTR_RING_RXDMA_ECODE_MULTICAST_ECHO_ERR] = "Multicast echo",
|
||||
[HAL_REO_ENTR_RING_RXDMA_ECODE_AMSDU_MISMATCH_ERR] = "AMSDU mismatch",
|
||||
[HAL_REO_ENTR_RING_RXDMA_ECODE_UNAUTH_WDS_ERR] = "Unauth WDS",
|
||||
[HAL_REO_ENTR_RING_RXDMA_ECODE_GRPCAST_AMSDU_WDS_ERR] = "AMSDU or WDS"};
|
||||
|
||||
static const char *reo_err[HAL_REO_DEST_RING_ERROR_CODE_MAX] = {
|
||||
[HAL_REO_DEST_RING_ERROR_CODE_DESC_ADDR_ZERO] = "Desc addr zero",
|
||||
[HAL_REO_DEST_RING_ERROR_CODE_DESC_INVALID] = "Desc inval",
|
||||
[HAL_REO_DEST_RING_ERROR_CODE_AMPDU_IN_NON_BA] = "AMPDU in non BA",
|
||||
[HAL_REO_DEST_RING_ERROR_CODE_NON_BA_DUPLICATE] = "Non BA dup",
|
||||
[HAL_REO_DEST_RING_ERROR_CODE_BA_DUPLICATE] = "BA dup",
|
||||
[HAL_REO_DEST_RING_ERROR_CODE_FRAME_2K_JUMP] = "Frame 2k jump",
|
||||
[HAL_REO_DEST_RING_ERROR_CODE_BAR_2K_JUMP] = "BAR 2k jump",
|
||||
[HAL_REO_DEST_RING_ERROR_CODE_FRAME_OOR] = "Frame OOR",
|
||||
[HAL_REO_DEST_RING_ERROR_CODE_BAR_OOR] = "BAR OOR",
|
||||
[HAL_REO_DEST_RING_ERROR_CODE_NO_BA_SESSION] = "No BA session",
|
||||
[HAL_REO_DEST_RING_ERROR_CODE_FRAME_SN_EQUALS_SSN] = "Frame SN equal SSN",
|
||||
[HAL_REO_DEST_RING_ERROR_CODE_PN_CHECK_FAILED] = "PN check fail",
|
||||
[HAL_REO_DEST_RING_ERROR_CODE_2K_ERR_FLAG_SET] = "2k err",
|
||||
[HAL_REO_DEST_RING_ERROR_CODE_PN_ERR_FLAG_SET] = "PN err",
|
||||
[HAL_REO_DEST_RING_ERROR_CODE_DESC_BLOCKED] = "Desc blocked"};
|
||||
|
||||
static const char *wbm_rel_src[HAL_WBM_REL_SRC_MODULE_MAX] = {
|
||||
[HAL_WBM_REL_SRC_MODULE_TQM] = "TQM",
|
||||
[HAL_WBM_REL_SRC_MODULE_RXDMA] = "Rxdma",
|
||||
[HAL_WBM_REL_SRC_MODULE_REO] = "Reo",
|
||||
[HAL_WBM_REL_SRC_MODULE_FW] = "FW",
|
||||
[HAL_WBM_REL_SRC_MODULE_SW] = "SW"};
|
||||
|
||||
char *buf __free(kfree) = kzalloc(size, GFP_KERNEL);
|
||||
|
||||
if (!buf)
|
||||
return -ENOMEM;
|
||||
|
||||
len += scnprintf(buf + len, size - len, "DEVICE RX STATS:\n\n");
|
||||
len += scnprintf(buf + len, size - len, "err ring pkts: %u\n",
|
||||
device_stats->err_ring_pkts);
|
||||
len += scnprintf(buf + len, size - len, "Invalid RBM: %u\n\n",
|
||||
device_stats->invalid_rbm);
|
||||
len += scnprintf(buf + len, size - len, "RXDMA errors:\n");
|
||||
|
||||
for (i = 0; i < HAL_REO_ENTR_RING_RXDMA_ECODE_MAX; i++)
|
||||
len += scnprintf(buf + len, size - len, "%s: %u\n",
|
||||
rxdma_err[i], device_stats->rxdma_error[i]);
|
||||
|
||||
len += scnprintf(buf + len, size - len, "\nREO errors:\n");
|
||||
|
||||
for (i = 0; i < HAL_REO_DEST_RING_ERROR_CODE_MAX; i++)
|
||||
len += scnprintf(buf + len, size - len, "%s: %u\n",
|
||||
reo_err[i], device_stats->reo_error[i]);
|
||||
|
||||
len += scnprintf(buf + len, size - len, "\nHAL REO errors:\n");
|
||||
|
||||
for (i = 0; i < DP_REO_DST_RING_MAX; i++)
|
||||
len += scnprintf(buf + len, size - len,
|
||||
"ring%d: %u\n", i,
|
||||
device_stats->hal_reo_error[i]);
|
||||
|
||||
len += scnprintf(buf + len, size - len, "\nDEVICE TX STATS:\n");
|
||||
len += scnprintf(buf + len, size - len, "\nTCL Ring Full Failures:\n");
|
||||
|
||||
for (i = 0; i < DP_TCL_NUM_RING_MAX; i++)
|
||||
len += scnprintf(buf + len, size - len, "ring%d: %u\n",
|
||||
i, device_stats->tx_err.desc_na[i]);
|
||||
|
||||
len += scnprintf(buf + len, size - len,
|
||||
"\nMisc Transmit Failures: %d\n",
|
||||
atomic_read(&device_stats->tx_err.misc_fail));
|
||||
|
||||
len += scnprintf(buf + len, size - len, "\ntx_wbm_rel_source:");
|
||||
|
||||
for (i = 0; i < HAL_WBM_REL_SRC_MODULE_MAX; i++)
|
||||
len += scnprintf(buf + len, size - len, " %d:%u",
|
||||
i, device_stats->tx_wbm_rel_source[i]);
|
||||
|
||||
len += scnprintf(buf + len, size - len, "\n");
|
||||
|
||||
len += scnprintf(buf + len, size - len, "\ntqm_rel_reason:");
|
||||
|
||||
for (i = 0; i < MAX_TQM_RELEASE_REASON; i++)
|
||||
len += scnprintf(buf + len, size - len, " %d:%u",
|
||||
i, device_stats->tqm_rel_reason[i]);
|
||||
|
||||
len += scnprintf(buf + len, size - len, "\n");
|
||||
|
||||
len += scnprintf(buf + len, size - len, "\nfw_tx_status:");
|
||||
|
||||
for (i = 0; i < MAX_FW_TX_STATUS; i++)
|
||||
len += scnprintf(buf + len, size - len, " %d:%u",
|
||||
i, device_stats->fw_tx_status[i]);
|
||||
|
||||
len += scnprintf(buf + len, size - len, "\n");
|
||||
|
||||
len += scnprintf(buf + len, size - len, "\ntx_enqueued:");
|
||||
|
||||
for (i = 0; i < DP_TCL_NUM_RING_MAX; i++)
|
||||
len += scnprintf(buf + len, size - len, " %d:%u", i,
|
||||
device_stats->tx_enqueued[i]);
|
||||
|
||||
len += scnprintf(buf + len, size - len, "\n");
|
||||
|
||||
len += scnprintf(buf + len, size - len, "\ntx_completed:");
|
||||
|
||||
for (i = 0; i < DP_TCL_NUM_RING_MAX; i++)
|
||||
len += scnprintf(buf + len, size - len, " %d:%u",
|
||||
i, device_stats->tx_completed[i]);
|
||||
|
||||
len += scnprintf(buf + len, size - len, "\n");
|
||||
|
||||
for (i = 0; i < ab->num_radios; i++) {
|
||||
ar = ath12k_mac_get_ar_by_pdev_id(ab, DP_SW2HW_MACID(i));
|
||||
if (ar) {
|
||||
len += scnprintf(buf + len, size - len,
|
||||
"\nradio%d tx_pending: %u\n", i,
|
||||
atomic_read(&ar->dp.num_tx_pending));
|
||||
}
|
||||
}
|
||||
|
||||
len += scnprintf(buf + len, size - len, "\nREO Rx Received:\n");
|
||||
|
||||
for (i = 0; i < DP_REO_DST_RING_MAX; i++) {
|
||||
len += scnprintf(buf + len, size - len, "Ring%d:", i + 1);
|
||||
|
||||
for (j = 0; j < ATH12K_MAX_DEVICES; j++) {
|
||||
len += scnprintf(buf + len, size - len,
|
||||
"\t%d:%u", j,
|
||||
device_stats->reo_rx[i][j]);
|
||||
}
|
||||
|
||||
len += scnprintf(buf + len, size - len, "\n");
|
||||
}
|
||||
|
||||
len += scnprintf(buf + len, size - len, "\nRx WBM REL SRC Errors:\n");
|
||||
|
||||
for (i = 0; i < HAL_WBM_REL_SRC_MODULE_MAX; i++) {
|
||||
len += scnprintf(buf + len, size - len, "%s:", wbm_rel_src[i]);
|
||||
|
||||
for (j = 0; j < ATH12K_MAX_DEVICES; j++) {
|
||||
len += scnprintf(buf + len,
|
||||
size - len,
|
||||
"\t%d:%u", j,
|
||||
device_stats->rx_wbm_rel_source[i][j]);
|
||||
}
|
||||
|
||||
len += scnprintf(buf + len, size - len, "\n");
|
||||
}
|
||||
|
||||
ret = simple_read_from_buffer(user_buf, count, ppos, buf, len);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static const struct file_operations fops_device_dp_stats = {
|
||||
.read = ath12k_debugfs_dump_device_dp_stats,
|
||||
.open = simple_open,
|
||||
.owner = THIS_MODULE,
|
||||
.llseek = default_llseek,
|
||||
};
|
||||
|
||||
void ath12k_debugfs_pdev_create(struct ath12k_base *ab)
|
||||
{
|
||||
debugfs_create_file("simulate_fw_crash", 0600, ab->debugfs_soc, ab,
|
||||
&fops_simulate_fw_crash);
|
||||
|
||||
debugfs_create_file("device_dp_stats", 0400, ab->debugfs_soc, ab,
|
||||
&fops_device_dp_stats);
|
||||
}
|
||||
|
||||
void ath12k_debugfs_soc_create(struct ath12k_base *ab)
|
||||
{
|
||||
bool dput_needed;
|
||||
|
||||
@ -16,6 +16,7 @@ void ath12k_debugfs_fw_stats_process(struct ath12k *ar,
|
||||
struct ath12k_fw_stats *stats);
|
||||
void ath12k_debugfs_op_vif_add(struct ieee80211_hw *hw,
|
||||
struct ieee80211_vif *vif);
|
||||
void ath12k_debugfs_pdev_create(struct ath12k_base *ab);
|
||||
|
||||
static inline bool ath12k_debugfs_is_extd_rx_stats_enabled(struct ath12k *ar)
|
||||
{
|
||||
@ -144,6 +145,10 @@ static inline void ath12k_debugfs_op_vif_add(struct ieee80211_hw *hw,
|
||||
struct ieee80211_vif *vif)
|
||||
{
|
||||
}
|
||||
|
||||
static inline void ath12k_debugfs_pdev_create(struct ath12k_base *ab)
|
||||
{
|
||||
}
|
||||
#endif /* CONFIG_ATH12K_DEBUGFS */
|
||||
|
||||
#endif /* _ATH12K_DEBUGFS_H_ */
|
||||
|
||||
@ -168,6 +168,8 @@ static int ath12k_dp_srng_calculate_msi_group(struct ath12k_base *ab,
|
||||
grp_mask = &ab->hw_params->ring_mask->reo_status[0];
|
||||
break;
|
||||
case HAL_RXDMA_MONITOR_STATUS:
|
||||
grp_mask = &ab->hw_params->ring_mask->rx_mon_status[0];
|
||||
break;
|
||||
case HAL_RXDMA_MONITOR_DST:
|
||||
grp_mask = &ab->hw_params->ring_mask->rx_mon_dest[0];
|
||||
break;
|
||||
@ -274,12 +276,17 @@ int ath12k_dp_srng_setup(struct ath12k_base *ab, struct dp_srng *ring,
|
||||
break;
|
||||
case HAL_RXDMA_BUF:
|
||||
case HAL_RXDMA_MONITOR_BUF:
|
||||
case HAL_RXDMA_MONITOR_STATUS:
|
||||
params.low_threshold = num_entries >> 3;
|
||||
params.flags |= HAL_SRNG_FLAGS_LOW_THRESH_INTR_EN;
|
||||
params.intr_batch_cntr_thres_entries = 0;
|
||||
params.intr_timer_thres_us = HAL_SRNG_INT_TIMER_THRESHOLD_RX;
|
||||
break;
|
||||
case HAL_RXDMA_MONITOR_STATUS:
|
||||
params.low_threshold = num_entries >> 3;
|
||||
params.flags |= HAL_SRNG_FLAGS_LOW_THRESH_INTR_EN;
|
||||
params.intr_batch_cntr_thres_entries = 1;
|
||||
params.intr_timer_thres_us = HAL_SRNG_INT_TIMER_THRESHOLD_RX;
|
||||
break;
|
||||
case HAL_TX_MONITOR_DST:
|
||||
params.low_threshold = DP_TX_MONITOR_BUF_SIZE_MAX >> 3;
|
||||
params.flags |= HAL_SRNG_FLAGS_LOW_THRESH_INTR_EN;
|
||||
@ -354,7 +361,10 @@ u32 ath12k_dp_tx_get_vdev_bank_config(struct ath12k_base *ab,
|
||||
u32_encode_bits(0, HAL_TX_BANK_CONFIG_EPD);
|
||||
|
||||
/* only valid if idx_lookup_override is not set in tcl_data_cmd */
|
||||
bank_config |= u32_encode_bits(0, HAL_TX_BANK_CONFIG_INDEX_LOOKUP_EN);
|
||||
if (ahvif->vdev_type == WMI_VDEV_TYPE_STA)
|
||||
bank_config |= u32_encode_bits(1, HAL_TX_BANK_CONFIG_INDEX_LOOKUP_EN);
|
||||
else
|
||||
bank_config |= u32_encode_bits(0, HAL_TX_BANK_CONFIG_INDEX_LOOKUP_EN);
|
||||
|
||||
bank_config |= u32_encode_bits(arvif->hal_addr_search_flags & HAL_TX_ADDRX_EN,
|
||||
HAL_TX_BANK_CONFIG_ADDRX_EN) |
|
||||
@ -919,6 +929,25 @@ int ath12k_dp_service_srng(struct ath12k_base *ab,
|
||||
goto done;
|
||||
}
|
||||
|
||||
if (ab->hw_params->ring_mask->rx_mon_status[grp_id]) {
|
||||
ring_mask = ab->hw_params->ring_mask->rx_mon_status[grp_id];
|
||||
for (i = 0; i < ab->num_radios; i++) {
|
||||
for (j = 0; j < ab->hw_params->num_rxdma_per_pdev; j++) {
|
||||
int id = i * ab->hw_params->num_rxdma_per_pdev + j;
|
||||
|
||||
if (ring_mask & BIT(id)) {
|
||||
work_done =
|
||||
ath12k_dp_mon_process_ring(ab, id, napi, budget,
|
||||
0);
|
||||
budget -= work_done;
|
||||
tot_work_done += work_done;
|
||||
if (budget <= 0)
|
||||
goto done;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (ab->hw_params->ring_mask->rx_mon_dest[grp_id]) {
|
||||
monitor_mode = ATH12K_DP_RX_MONITOR_MODE;
|
||||
ring_mask = ab->hw_params->ring_mask->rx_mon_dest[grp_id];
|
||||
@ -982,11 +1011,6 @@ void ath12k_dp_pdev_free(struct ath12k_base *ab)
|
||||
{
|
||||
int i;
|
||||
|
||||
if (!ab->mon_reap_timer.function)
|
||||
return;
|
||||
|
||||
timer_delete_sync(&ab->mon_reap_timer);
|
||||
|
||||
for (i = 0; i < ab->num_radios; i++)
|
||||
ath12k_dp_rx_pdev_free(ab, i);
|
||||
}
|
||||
@ -1024,27 +1048,6 @@ void ath12k_dp_hal_rx_desc_init(struct ath12k_base *ab)
|
||||
ab->hal_rx_ops->rx_desc_get_desc_size();
|
||||
}
|
||||
|
||||
static void ath12k_dp_service_mon_ring(struct timer_list *t)
|
||||
{
|
||||
struct ath12k_base *ab = from_timer(ab, t, mon_reap_timer);
|
||||
int i;
|
||||
|
||||
for (i = 0; i < ab->hw_params->num_rxdma_per_pdev; i++)
|
||||
ath12k_dp_mon_process_ring(ab, i, NULL, DP_MON_SERVICE_BUDGET,
|
||||
ATH12K_DP_RX_MONITOR_MODE);
|
||||
|
||||
mod_timer(&ab->mon_reap_timer, jiffies +
|
||||
msecs_to_jiffies(ATH12K_MON_TIMER_INTERVAL));
|
||||
}
|
||||
|
||||
static void ath12k_dp_mon_reap_timer_init(struct ath12k_base *ab)
|
||||
{
|
||||
if (ab->hw_params->rxdma1_enable)
|
||||
return;
|
||||
|
||||
timer_setup(&ab->mon_reap_timer, ath12k_dp_service_mon_ring, 0);
|
||||
}
|
||||
|
||||
int ath12k_dp_pdev_alloc(struct ath12k_base *ab)
|
||||
{
|
||||
struct ath12k *ar;
|
||||
@ -1055,8 +1058,6 @@ int ath12k_dp_pdev_alloc(struct ath12k_base *ab)
|
||||
if (ret)
|
||||
goto out;
|
||||
|
||||
ath12k_dp_mon_reap_timer_init(ab);
|
||||
|
||||
/* TODO: Per-pdev rx ring unlike tx ring which is mapped to different AC's */
|
||||
for (i = 0; i < ab->num_radios; i++) {
|
||||
ar = ab->pdevs[i].ar;
|
||||
@ -1107,11 +1108,8 @@ static void ath12k_dp_update_vdev_search(struct ath12k_link_vif *arvif)
|
||||
{
|
||||
switch (arvif->ahvif->vdev_type) {
|
||||
case WMI_VDEV_TYPE_STA:
|
||||
/* TODO: Verify the search type and flags since ast hash
|
||||
* is not part of peer mapv3
|
||||
*/
|
||||
arvif->hal_addr_search_flags = HAL_TX_ADDRY_EN;
|
||||
arvif->search_type = HAL_TX_ADDR_SEARCH_DEFAULT;
|
||||
arvif->search_type = HAL_TX_ADDR_SEARCH_INDEX;
|
||||
break;
|
||||
case WMI_VDEV_TYPE_AP:
|
||||
case WMI_VDEV_TYPE_IBSS:
|
||||
|
||||
@ -70,6 +70,16 @@ struct ath12k_pdev_mon_stats {
|
||||
u32 dest_mpdu_drop;
|
||||
u32 dup_mon_linkdesc_cnt;
|
||||
u32 dup_mon_buf_cnt;
|
||||
u32 dest_mon_stuck;
|
||||
u32 dest_mon_not_reaped;
|
||||
};
|
||||
|
||||
enum dp_mon_status_buf_state {
|
||||
DP_MON_STATUS_MATCH,
|
||||
DP_MON_STATUS_NO_DMA,
|
||||
DP_MON_STATUS_LAG,
|
||||
DP_MON_STATUS_LEAD,
|
||||
DP_MON_STATUS_REPLINISH,
|
||||
};
|
||||
|
||||
struct dp_link_desc_bank {
|
||||
@ -121,8 +131,11 @@ struct ath12k_mon_data {
|
||||
u32 mon_last_buf_cookie;
|
||||
u64 mon_last_linkdesc_paddr;
|
||||
u16 chan_noise_floor;
|
||||
u32 err_bitmap;
|
||||
u8 decap_format;
|
||||
|
||||
struct ath12k_pdev_mon_stats rx_mon_stats;
|
||||
enum dp_mon_status_buf_state buf_state;
|
||||
/* lock for monitor data */
|
||||
spinlock_t mon_lock;
|
||||
struct sk_buff_head rx_status_q;
|
||||
@ -191,6 +204,14 @@ struct ath12k_pdev_dp {
|
||||
#define DP_RX_BUFFER_SIZE_LITE 1024
|
||||
#define DP_RX_BUFFER_ALIGN_SIZE 128
|
||||
|
||||
#define RX_MON_STATUS_BASE_BUF_SIZE 2048
|
||||
#define RX_MON_STATUS_BUF_ALIGN 128
|
||||
#define RX_MON_STATUS_BUF_RESERVATION 128
|
||||
#define RX_MON_STATUS_BUF_SIZE (RX_MON_STATUS_BASE_BUF_SIZE - \
|
||||
(RX_MON_STATUS_BUF_RESERVATION + \
|
||||
RX_MON_STATUS_BUF_ALIGN + \
|
||||
SKB_DATA_ALIGN(sizeof(struct skb_shared_info))))
|
||||
|
||||
#define DP_RXDMA_BUF_COOKIE_BUF_ID GENMASK(17, 0)
|
||||
#define DP_RXDMA_BUF_COOKIE_PDEV_ID GENMASK(19, 18)
|
||||
|
||||
@ -266,6 +287,9 @@ struct ath12k_pdev_dp {
|
||||
/* Invalid TX Bank ID value */
|
||||
#define DP_INVALID_BANK_ID -1
|
||||
|
||||
#define MAX_TQM_RELEASE_REASON 15
|
||||
#define MAX_FW_TX_STATUS 7
|
||||
|
||||
struct ath12k_dp_tx_bank_profile {
|
||||
u8 is_configured;
|
||||
u32 num_users;
|
||||
@ -338,6 +362,7 @@ struct ath12k_link_stats {
|
||||
|
||||
struct ath12k_dp {
|
||||
struct ath12k_base *ab;
|
||||
u32 mon_dest_ring_stuck_cnt;
|
||||
u8 num_bank_profiles;
|
||||
/* protects the access and update of bank_profiles */
|
||||
spinlock_t tx_bank_lock;
|
||||
@ -390,6 +415,7 @@ struct ath12k_dp {
|
||||
struct dp_srng rxdma_err_dst_ring[MAX_RXDMA_PER_PDEV];
|
||||
struct dp_rxdma_mon_ring rxdma_mon_buf_ring;
|
||||
struct dp_rxdma_mon_ring tx_mon_buf_ring;
|
||||
struct dp_rxdma_mon_ring rx_mon_status_refill_ring[MAX_RXDMA_PER_PDEV];
|
||||
struct ath12k_reo_q_addr_lut reoq_lut;
|
||||
struct ath12k_reo_q_addr_lut ml_reoq_lut;
|
||||
};
|
||||
@ -1330,6 +1356,8 @@ struct htt_t2h_version_conf_msg {
|
||||
#define HTT_T2H_PEER_MAP_INFO1_MAC_ADDR_H16 GENMASK(15, 0)
|
||||
#define HTT_T2H_PEER_MAP_INFO1_HW_PEER_ID GENMASK(31, 16)
|
||||
#define HTT_T2H_PEER_MAP_INFO2_AST_HASH_VAL GENMASK(15, 0)
|
||||
#define HTT_T2H_PEER_MAP3_INFO2_HW_PEER_ID GENMASK(15, 0)
|
||||
#define HTT_T2H_PEER_MAP3_INFO2_AST_HASH_VAL GENMASK(31, 16)
|
||||
#define HTT_T2H_PEER_MAP_INFO2_NEXT_HOP_M BIT(16)
|
||||
#define HTT_T2H_PEER_MAP_INFO2_NEXT_HOP_S 16
|
||||
|
||||
|
||||
@ -1416,6 +1416,40 @@ ath12k_dp_mon_hal_rx_parse_user_info(const struct hal_receive_user_info *rx_usr_
|
||||
}
|
||||
}
|
||||
|
||||
static void ath12k_dp_mon_parse_rx_msdu_end_err(u32 info, u32 *errmap)
|
||||
{
|
||||
if (info & RX_MSDU_END_INFO13_FCS_ERR)
|
||||
*errmap |= HAL_RX_MPDU_ERR_FCS;
|
||||
|
||||
if (info & RX_MSDU_END_INFO13_DECRYPT_ERR)
|
||||
*errmap |= HAL_RX_MPDU_ERR_DECRYPT;
|
||||
|
||||
if (info & RX_MSDU_END_INFO13_TKIP_MIC_ERR)
|
||||
*errmap |= HAL_RX_MPDU_ERR_TKIP_MIC;
|
||||
|
||||
if (info & RX_MSDU_END_INFO13_A_MSDU_ERROR)
|
||||
*errmap |= HAL_RX_MPDU_ERR_AMSDU_ERR;
|
||||
|
||||
if (info & RX_MSDU_END_INFO13_OVERFLOW_ERR)
|
||||
*errmap |= HAL_RX_MPDU_ERR_OVERFLOW;
|
||||
|
||||
if (info & RX_MSDU_END_INFO13_MSDU_LEN_ERR)
|
||||
*errmap |= HAL_RX_MPDU_ERR_MSDU_LEN;
|
||||
|
||||
if (info & RX_MSDU_END_INFO13_MPDU_LEN_ERR)
|
||||
*errmap |= HAL_RX_MPDU_ERR_MPDU_LEN;
|
||||
}
|
||||
|
||||
static void
|
||||
ath12k_dp_mon_parse_status_msdu_end(struct ath12k_mon_data *pmon,
|
||||
const struct hal_rx_msdu_end *msdu_end)
|
||||
{
|
||||
ath12k_dp_mon_parse_rx_msdu_end_err(__le32_to_cpu(msdu_end->info2),
|
||||
&pmon->err_bitmap);
|
||||
pmon->decap_format = le32_get_bits(msdu_end->info1,
|
||||
RX_MSDU_END_INFO11_DECAP_FORMAT);
|
||||
}
|
||||
|
||||
static enum hal_rx_mon_status
|
||||
ath12k_dp_mon_rx_parse_status_tlv(struct ath12k *ar,
|
||||
struct ath12k_mon_data *pmon,
|
||||
@ -1655,6 +1689,7 @@ ath12k_dp_mon_rx_parse_status_tlv(struct ath12k *ar,
|
||||
case HAL_MON_BUF_ADDR:
|
||||
return HAL_RX_MON_STATUS_BUF_ADDR;
|
||||
case HAL_RX_MSDU_END:
|
||||
ath12k_dp_mon_parse_status_msdu_end(pmon, tlv_data);
|
||||
return HAL_RX_MON_STATUS_MSDU_END;
|
||||
case HAL_RX_MPDU_END:
|
||||
return HAL_RX_MON_STATUS_MPDU_END;
|
||||
@ -1716,6 +1751,124 @@ ath12k_dp_mon_fill_rx_stats_info(struct ath12k *ar,
|
||||
}
|
||||
}
|
||||
|
||||
static struct sk_buff
|
||||
*ath12k_dp_rx_alloc_mon_status_buf(struct ath12k_base *ab,
|
||||
struct dp_rxdma_mon_ring *rx_ring,
|
||||
int *buf_id)
|
||||
{
|
||||
struct sk_buff *skb;
|
||||
dma_addr_t paddr;
|
||||
|
||||
skb = dev_alloc_skb(RX_MON_STATUS_BUF_SIZE);
|
||||
|
||||
if (!skb)
|
||||
goto fail_alloc_skb;
|
||||
|
||||
if (!IS_ALIGNED((unsigned long)skb->data,
|
||||
RX_MON_STATUS_BUF_ALIGN)) {
|
||||
skb_pull(skb, PTR_ALIGN(skb->data, RX_MON_STATUS_BUF_ALIGN) -
|
||||
skb->data);
|
||||
}
|
||||
|
||||
paddr = dma_map_single(ab->dev, skb->data,
|
||||
skb->len + skb_tailroom(skb),
|
||||
DMA_FROM_DEVICE);
|
||||
if (unlikely(dma_mapping_error(ab->dev, paddr)))
|
||||
goto fail_free_skb;
|
||||
|
||||
spin_lock_bh(&rx_ring->idr_lock);
|
||||
*buf_id = idr_alloc(&rx_ring->bufs_idr, skb, 0,
|
||||
rx_ring->bufs_max, GFP_ATOMIC);
|
||||
spin_unlock_bh(&rx_ring->idr_lock);
|
||||
if (*buf_id < 0)
|
||||
goto fail_dma_unmap;
|
||||
|
||||
ATH12K_SKB_RXCB(skb)->paddr = paddr;
|
||||
return skb;
|
||||
|
||||
fail_dma_unmap:
|
||||
dma_unmap_single(ab->dev, paddr, skb->len + skb_tailroom(skb),
|
||||
DMA_FROM_DEVICE);
|
||||
fail_free_skb:
|
||||
dev_kfree_skb_any(skb);
|
||||
fail_alloc_skb:
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static enum dp_mon_status_buf_state
|
||||
ath12k_dp_rx_mon_buf_done(struct ath12k_base *ab, struct hal_srng *srng,
|
||||
struct dp_rxdma_mon_ring *rx_ring)
|
||||
{
|
||||
struct ath12k_skb_rxcb *rxcb;
|
||||
struct hal_tlv_64_hdr *tlv;
|
||||
struct sk_buff *skb;
|
||||
void *status_desc;
|
||||
dma_addr_t paddr;
|
||||
u32 cookie;
|
||||
int buf_id;
|
||||
u8 rbm;
|
||||
|
||||
status_desc = ath12k_hal_srng_src_next_peek(ab, srng);
|
||||
if (!status_desc)
|
||||
return DP_MON_STATUS_NO_DMA;
|
||||
|
||||
ath12k_hal_rx_buf_addr_info_get(status_desc, &paddr, &cookie, &rbm);
|
||||
|
||||
buf_id = u32_get_bits(cookie, DP_RXDMA_BUF_COOKIE_BUF_ID);
|
||||
|
||||
spin_lock_bh(&rx_ring->idr_lock);
|
||||
skb = idr_find(&rx_ring->bufs_idr, buf_id);
|
||||
spin_unlock_bh(&rx_ring->idr_lock);
|
||||
|
||||
if (!skb)
|
||||
return DP_MON_STATUS_NO_DMA;
|
||||
|
||||
rxcb = ATH12K_SKB_RXCB(skb);
|
||||
dma_sync_single_for_cpu(ab->dev, rxcb->paddr,
|
||||
skb->len + skb_tailroom(skb),
|
||||
DMA_FROM_DEVICE);
|
||||
|
||||
tlv = (struct hal_tlv_64_hdr *)skb->data;
|
||||
if (le64_get_bits(tlv->tl, HAL_TLV_HDR_TAG) != HAL_RX_STATUS_BUFFER_DONE)
|
||||
return DP_MON_STATUS_NO_DMA;
|
||||
|
||||
return DP_MON_STATUS_REPLINISH;
|
||||
}
|
||||
|
||||
static u32 ath12k_dp_mon_comp_ppduid(u32 msdu_ppdu_id, u32 *ppdu_id)
|
||||
{
|
||||
u32 ret = 0;
|
||||
|
||||
if ((*ppdu_id < msdu_ppdu_id) &&
|
||||
((msdu_ppdu_id - *ppdu_id) < DP_NOT_PPDU_ID_WRAP_AROUND)) {
|
||||
/* Hold on mon dest ring, and reap mon status ring. */
|
||||
*ppdu_id = msdu_ppdu_id;
|
||||
ret = msdu_ppdu_id;
|
||||
} else if ((*ppdu_id > msdu_ppdu_id) &&
|
||||
((*ppdu_id - msdu_ppdu_id) > DP_NOT_PPDU_ID_WRAP_AROUND)) {
|
||||
/* PPDU ID has exceeded the maximum value and will
|
||||
* restart from 0.
|
||||
*/
|
||||
*ppdu_id = msdu_ppdu_id;
|
||||
ret = msdu_ppdu_id;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
static
|
||||
void ath12k_dp_mon_next_link_desc_get(struct hal_rx_msdu_link *msdu_link,
|
||||
dma_addr_t *paddr, u32 *sw_cookie, u8 *rbm,
|
||||
struct ath12k_buffer_addr **pp_buf_addr_info)
|
||||
{
|
||||
struct ath12k_buffer_addr *buf_addr_info;
|
||||
|
||||
buf_addr_info = &msdu_link->buf_addr_info;
|
||||
|
||||
ath12k_hal_rx_buf_addr_info_get(buf_addr_info, paddr, sw_cookie, rbm);
|
||||
|
||||
*pp_buf_addr_info = buf_addr_info;
|
||||
}
|
||||
|
||||
static void
|
||||
ath12k_dp_mon_fill_rx_rate(struct ath12k *ar,
|
||||
struct hal_rx_mon_ppdu_info *ppdu_info,
|
||||
@ -1795,6 +1948,24 @@ ath12k_dp_mon_fill_rx_rate(struct ath12k *ar,
|
||||
}
|
||||
}
|
||||
|
||||
static void ath12k_dp_mon_rx_msdus_set_payload(struct ath12k *ar,
|
||||
struct sk_buff *head_msdu,
|
||||
struct sk_buff *tail_msdu)
|
||||
{
|
||||
u32 rx_pkt_offset, l2_hdr_offset, total_offset;
|
||||
|
||||
rx_pkt_offset = ar->ab->hal.hal_desc_sz;
|
||||
l2_hdr_offset =
|
||||
ath12k_dp_rx_h_l3pad(ar->ab, (struct hal_rx_desc *)tail_msdu->data);
|
||||
|
||||
if (ar->ab->hw_params->rxdma1_enable)
|
||||
total_offset = ATH12K_MON_RX_PKT_OFFSET;
|
||||
else
|
||||
total_offset = rx_pkt_offset + l2_hdr_offset;
|
||||
|
||||
skb_pull(head_msdu, total_offset);
|
||||
}
|
||||
|
||||
static struct sk_buff *
|
||||
ath12k_dp_mon_rx_merg_msdus(struct ath12k *ar,
|
||||
struct dp_mon_mpdu *mon_mpdu,
|
||||
@ -1803,7 +1974,7 @@ ath12k_dp_mon_rx_merg_msdus(struct ath12k *ar,
|
||||
{
|
||||
struct ath12k_base *ab = ar->ab;
|
||||
struct sk_buff *msdu, *mpdu_buf, *prev_buf, *head_frag_list;
|
||||
struct sk_buff *head_msdu;
|
||||
struct sk_buff *head_msdu, *tail_msdu;
|
||||
struct hal_rx_desc *rx_desc;
|
||||
u8 *hdr_desc, *dest, decap_format = mon_mpdu->decap_format;
|
||||
struct ieee80211_hdr_3addr *wh;
|
||||
@ -1813,8 +1984,9 @@ ath12k_dp_mon_rx_merg_msdus(struct ath12k *ar,
|
||||
|
||||
mpdu_buf = NULL;
|
||||
head_msdu = mon_mpdu->head;
|
||||
tail_msdu = mon_mpdu->tail;
|
||||
|
||||
if (!head_msdu)
|
||||
if (!head_msdu || !tail_msdu)
|
||||
goto err_merge_fail;
|
||||
|
||||
ath12k_dp_mon_fill_rx_stats_info(ar, ppdu_info, rxs);
|
||||
@ -1842,14 +2014,14 @@ ath12k_dp_mon_rx_merg_msdus(struct ath12k *ar,
|
||||
ath12k_dp_mon_fill_rx_rate(ar, ppdu_info, rxs);
|
||||
|
||||
if (decap_format == DP_RX_DECAP_TYPE_RAW) {
|
||||
skb_pull(head_msdu, ATH12K_MON_RX_PKT_OFFSET);
|
||||
ath12k_dp_mon_rx_msdus_set_payload(ar, head_msdu, tail_msdu);
|
||||
|
||||
prev_buf = head_msdu;
|
||||
msdu = head_msdu->next;
|
||||
head_frag_list = NULL;
|
||||
|
||||
while (msdu) {
|
||||
skb_pull(msdu, ATH12K_MON_RX_PKT_OFFSET);
|
||||
ath12k_dp_mon_rx_msdus_set_payload(ar, head_msdu, tail_msdu);
|
||||
|
||||
if (!head_frag_list)
|
||||
head_frag_list = msdu;
|
||||
@ -1884,7 +2056,7 @@ ath12k_dp_mon_rx_merg_msdus(struct ath12k *ar,
|
||||
msdu = head_msdu;
|
||||
|
||||
while (msdu) {
|
||||
skb_pull(msdu, ATH12K_MON_RX_PKT_OFFSET);
|
||||
ath12k_dp_mon_rx_msdus_set_payload(ar, head_msdu, tail_msdu);
|
||||
if (qos_pkt) {
|
||||
dest = skb_push(msdu, sizeof(__le16));
|
||||
if (!dest)
|
||||
@ -2223,43 +2395,30 @@ static int ath12k_dp_pkt_set_pktlen(struct sk_buff *skb, u32 len)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void ath12k_dp_mon_parse_rx_msdu_end_err(u32 info, u32 *errmap)
|
||||
/* Hardware fill buffer with 128 bytes aligned. So need to reap it
|
||||
* with 128 bytes aligned.
|
||||
*/
|
||||
#define RXDMA_DATA_DMA_BLOCK_SIZE 128
|
||||
|
||||
static void
|
||||
ath12k_dp_mon_get_buf_len(struct hal_rx_msdu_desc_info *info,
|
||||
bool *is_frag, u32 *total_len,
|
||||
u32 *frag_len, u32 *msdu_cnt)
|
||||
{
|
||||
if (info & RX_MSDU_END_INFO13_FCS_ERR)
|
||||
*errmap |= HAL_RX_MPDU_ERR_FCS;
|
||||
if (info->msdu_flags & RX_MSDU_DESC_INFO0_MSDU_CONTINUATION) {
|
||||
*is_frag = true;
|
||||
*frag_len = (RX_MON_STATUS_BASE_BUF_SIZE -
|
||||
sizeof(struct hal_rx_desc)) &
|
||||
~(RXDMA_DATA_DMA_BLOCK_SIZE - 1);
|
||||
*total_len += *frag_len;
|
||||
} else {
|
||||
if (*is_frag)
|
||||
*frag_len = info->msdu_len - *total_len;
|
||||
else
|
||||
*frag_len = info->msdu_len;
|
||||
|
||||
if (info & RX_MSDU_END_INFO13_DECRYPT_ERR)
|
||||
*errmap |= HAL_RX_MPDU_ERR_DECRYPT;
|
||||
|
||||
if (info & RX_MSDU_END_INFO13_TKIP_MIC_ERR)
|
||||
*errmap |= HAL_RX_MPDU_ERR_TKIP_MIC;
|
||||
|
||||
if (info & RX_MSDU_END_INFO13_A_MSDU_ERROR)
|
||||
*errmap |= HAL_RX_MPDU_ERR_AMSDU_ERR;
|
||||
|
||||
if (info & RX_MSDU_END_INFO13_OVERFLOW_ERR)
|
||||
*errmap |= HAL_RX_MPDU_ERR_OVERFLOW;
|
||||
|
||||
if (info & RX_MSDU_END_INFO13_MSDU_LEN_ERR)
|
||||
*errmap |= HAL_RX_MPDU_ERR_MSDU_LEN;
|
||||
|
||||
if (info & RX_MSDU_END_INFO13_MPDU_LEN_ERR)
|
||||
*errmap |= HAL_RX_MPDU_ERR_MPDU_LEN;
|
||||
}
|
||||
|
||||
static int
|
||||
ath12k_dp_mon_parse_status_msdu_end(struct ath12k_mon_data *pmon,
|
||||
const struct hal_rx_msdu_end *msdu_end)
|
||||
{
|
||||
struct dp_mon_mpdu *mon_mpdu = pmon->mon_mpdu;
|
||||
|
||||
ath12k_dp_mon_parse_rx_msdu_end_err(__le32_to_cpu(msdu_end->info2),
|
||||
&mon_mpdu->err_bitmap);
|
||||
|
||||
mon_mpdu->decap_format = le32_get_bits(msdu_end->info1,
|
||||
RX_MSDU_END_INFO11_DECAP_FORMAT);
|
||||
|
||||
return 0;
|
||||
*msdu_cnt -= 1;
|
||||
}
|
||||
}
|
||||
|
||||
static int
|
||||
@ -2335,7 +2494,9 @@ ath12k_dp_mon_parse_rx_dest_tlv(struct ath12k *ar,
|
||||
pmon->mon_mpdu = NULL;
|
||||
break;
|
||||
case HAL_RX_MON_STATUS_MSDU_END:
|
||||
return ath12k_dp_mon_parse_status_msdu_end(pmon, tlv_data);
|
||||
pmon->mon_mpdu->decap_format = pmon->decap_format;
|
||||
pmon->mon_mpdu->err_bitmap = pmon->err_bitmap;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
@ -2370,7 +2531,7 @@ ath12k_dp_mon_parse_rx_dest(struct ath12k *ar, struct ath12k_mon_data *pmon,
|
||||
|
||||
hal_status = ath12k_dp_mon_rx_parse_status_tlv(ar, pmon, tlv);
|
||||
|
||||
if (ar->monitor_started &&
|
||||
if (ar->monitor_started && ar->ab->hw_params->rxdma1_enable &&
|
||||
ath12k_dp_mon_parse_rx_dest_tlv(ar, pmon, hal_status, tlv->value))
|
||||
return HAL_RX_MON_STATUS_PPDU_DONE;
|
||||
|
||||
@ -2495,6 +2656,94 @@ int ath12k_dp_mon_buf_replenish(struct ath12k_base *ab,
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
int ath12k_dp_mon_status_bufs_replenish(struct ath12k_base *ab,
|
||||
struct dp_rxdma_mon_ring *rx_ring,
|
||||
int req_entries)
|
||||
{
|
||||
enum hal_rx_buf_return_buf_manager mgr =
|
||||
ab->hw_params->hal_params->rx_buf_rbm;
|
||||
int num_free, num_remain, buf_id;
|
||||
struct ath12k_buffer_addr *desc;
|
||||
struct hal_srng *srng;
|
||||
struct sk_buff *skb;
|
||||
dma_addr_t paddr;
|
||||
u32 cookie;
|
||||
|
||||
req_entries = min(req_entries, rx_ring->bufs_max);
|
||||
|
||||
srng = &ab->hal.srng_list[rx_ring->refill_buf_ring.ring_id];
|
||||
|
||||
spin_lock_bh(&srng->lock);
|
||||
|
||||
ath12k_hal_srng_access_begin(ab, srng);
|
||||
|
||||
num_free = ath12k_hal_srng_src_num_free(ab, srng, true);
|
||||
if (!req_entries && (num_free > (rx_ring->bufs_max * 3) / 4))
|
||||
req_entries = num_free;
|
||||
|
||||
req_entries = min(num_free, req_entries);
|
||||
num_remain = req_entries;
|
||||
|
||||
while (num_remain > 0) {
|
||||
skb = dev_alloc_skb(RX_MON_STATUS_BUF_SIZE);
|
||||
if (!skb)
|
||||
break;
|
||||
|
||||
if (!IS_ALIGNED((unsigned long)skb->data,
|
||||
RX_MON_STATUS_BUF_ALIGN)) {
|
||||
skb_pull(skb,
|
||||
PTR_ALIGN(skb->data, RX_MON_STATUS_BUF_ALIGN) -
|
||||
skb->data);
|
||||
}
|
||||
|
||||
paddr = dma_map_single(ab->dev, skb->data,
|
||||
skb->len + skb_tailroom(skb),
|
||||
DMA_FROM_DEVICE);
|
||||
if (dma_mapping_error(ab->dev, paddr))
|
||||
goto fail_free_skb;
|
||||
|
||||
spin_lock_bh(&rx_ring->idr_lock);
|
||||
buf_id = idr_alloc(&rx_ring->bufs_idr, skb, 0,
|
||||
rx_ring->bufs_max * 3, GFP_ATOMIC);
|
||||
spin_unlock_bh(&rx_ring->idr_lock);
|
||||
if (buf_id < 0)
|
||||
goto fail_dma_unmap;
|
||||
cookie = u32_encode_bits(buf_id, DP_RXDMA_BUF_COOKIE_BUF_ID);
|
||||
|
||||
desc = ath12k_hal_srng_src_get_next_entry(ab, srng);
|
||||
if (!desc)
|
||||
goto fail_buf_unassign;
|
||||
|
||||
ATH12K_SKB_RXCB(skb)->paddr = paddr;
|
||||
|
||||
num_remain--;
|
||||
|
||||
ath12k_hal_rx_buf_addr_info_set(desc, paddr, cookie, mgr);
|
||||
}
|
||||
|
||||
ath12k_hal_srng_access_end(ab, srng);
|
||||
|
||||
spin_unlock_bh(&srng->lock);
|
||||
|
||||
return req_entries - num_remain;
|
||||
|
||||
fail_buf_unassign:
|
||||
spin_lock_bh(&rx_ring->idr_lock);
|
||||
idr_remove(&rx_ring->bufs_idr, buf_id);
|
||||
spin_unlock_bh(&rx_ring->idr_lock);
|
||||
fail_dma_unmap:
|
||||
dma_unmap_single(ab->dev, paddr, skb->len + skb_tailroom(skb),
|
||||
DMA_FROM_DEVICE);
|
||||
fail_free_skb:
|
||||
dev_kfree_skb_any(skb);
|
||||
|
||||
ath12k_hal_srng_access_end(ab, srng);
|
||||
|
||||
spin_unlock_bh(&srng->lock);
|
||||
|
||||
return req_entries - num_remain;
|
||||
}
|
||||
|
||||
static struct dp_mon_tx_ppdu_info *
|
||||
ath12k_dp_mon_tx_get_ppdu_info(struct ath12k_mon_data *pmon,
|
||||
unsigned int ppdu_id,
|
||||
@ -3641,6 +3890,487 @@ int ath12k_dp_mon_srng_process(struct ath12k *ar, int *budget,
|
||||
return num_buffs_reaped;
|
||||
}
|
||||
|
||||
static int ath12k_dp_rx_reap_mon_status_ring(struct ath12k_base *ab, int mac_id,
|
||||
int *budget, struct sk_buff_head *skb_list)
|
||||
{
|
||||
const struct ath12k_hw_hal_params *hal_params;
|
||||
int buf_id, srng_id, num_buffs_reaped = 0;
|
||||
enum dp_mon_status_buf_state reap_status;
|
||||
struct dp_rxdma_mon_ring *rx_ring;
|
||||
struct ath12k_mon_data *pmon;
|
||||
struct ath12k_skb_rxcb *rxcb;
|
||||
struct hal_tlv_64_hdr *tlv;
|
||||
void *rx_mon_status_desc;
|
||||
struct hal_srng *srng;
|
||||
struct ath12k_dp *dp;
|
||||
struct sk_buff *skb;
|
||||
struct ath12k *ar;
|
||||
dma_addr_t paddr;
|
||||
u32 cookie;
|
||||
u8 rbm;
|
||||
|
||||
ar = ab->pdevs[ath12k_hw_mac_id_to_pdev_id(ab->hw_params, mac_id)].ar;
|
||||
dp = &ab->dp;
|
||||
pmon = &ar->dp.mon_data;
|
||||
srng_id = ath12k_hw_mac_id_to_srng_id(ab->hw_params, mac_id);
|
||||
rx_ring = &dp->rx_mon_status_refill_ring[srng_id];
|
||||
|
||||
srng = &ab->hal.srng_list[rx_ring->refill_buf_ring.ring_id];
|
||||
|
||||
spin_lock_bh(&srng->lock);
|
||||
|
||||
ath12k_hal_srng_access_begin(ab, srng);
|
||||
|
||||
while (*budget) {
|
||||
*budget -= 1;
|
||||
rx_mon_status_desc = ath12k_hal_srng_src_peek(ab, srng);
|
||||
if (!rx_mon_status_desc) {
|
||||
pmon->buf_state = DP_MON_STATUS_REPLINISH;
|
||||
break;
|
||||
}
|
||||
ath12k_hal_rx_buf_addr_info_get(rx_mon_status_desc, &paddr,
|
||||
&cookie, &rbm);
|
||||
if (paddr) {
|
||||
buf_id = u32_get_bits(cookie, DP_RXDMA_BUF_COOKIE_BUF_ID);
|
||||
|
||||
spin_lock_bh(&rx_ring->idr_lock);
|
||||
skb = idr_find(&rx_ring->bufs_idr, buf_id);
|
||||
spin_unlock_bh(&rx_ring->idr_lock);
|
||||
|
||||
if (!skb) {
|
||||
ath12k_warn(ab, "rx monitor status with invalid buf_id %d\n",
|
||||
buf_id);
|
||||
pmon->buf_state = DP_MON_STATUS_REPLINISH;
|
||||
goto move_next;
|
||||
}
|
||||
|
||||
rxcb = ATH12K_SKB_RXCB(skb);
|
||||
|
||||
dma_sync_single_for_cpu(ab->dev, rxcb->paddr,
|
||||
skb->len + skb_tailroom(skb),
|
||||
DMA_FROM_DEVICE);
|
||||
|
||||
tlv = (struct hal_tlv_64_hdr *)skb->data;
|
||||
if (le64_get_bits(tlv->tl, HAL_TLV_HDR_TAG) !=
|
||||
HAL_RX_STATUS_BUFFER_DONE) {
|
||||
pmon->buf_state = DP_MON_STATUS_NO_DMA;
|
||||
ath12k_warn(ab,
|
||||
"mon status DONE not set %llx, buf_id %d\n",
|
||||
le64_get_bits(tlv->tl, HAL_TLV_HDR_TAG),
|
||||
buf_id);
|
||||
/* RxDMA status done bit might not be set even
|
||||
* though tp is moved by HW.
|
||||
*/
|
||||
|
||||
/* If done status is missing:
|
||||
* 1. As per MAC team's suggestion,
|
||||
* when HP + 1 entry is peeked and if DMA
|
||||
* is not done and if HP + 2 entry's DMA done
|
||||
* is set. skip HP + 1 entry and
|
||||
* start processing in next interrupt.
|
||||
* 2. If HP + 2 entry's DMA done is not set,
|
||||
* poll onto HP + 1 entry DMA done to be set.
|
||||
* Check status for same buffer for next time
|
||||
* dp_rx_mon_status_srng_process
|
||||
*/
|
||||
reap_status = ath12k_dp_rx_mon_buf_done(ab, srng,
|
||||
rx_ring);
|
||||
if (reap_status == DP_MON_STATUS_NO_DMA)
|
||||
continue;
|
||||
|
||||
spin_lock_bh(&rx_ring->idr_lock);
|
||||
idr_remove(&rx_ring->bufs_idr, buf_id);
|
||||
spin_unlock_bh(&rx_ring->idr_lock);
|
||||
|
||||
dma_unmap_single(ab->dev, rxcb->paddr,
|
||||
skb->len + skb_tailroom(skb),
|
||||
DMA_FROM_DEVICE);
|
||||
|
||||
dev_kfree_skb_any(skb);
|
||||
pmon->buf_state = DP_MON_STATUS_REPLINISH;
|
||||
goto move_next;
|
||||
}
|
||||
|
||||
spin_lock_bh(&rx_ring->idr_lock);
|
||||
idr_remove(&rx_ring->bufs_idr, buf_id);
|
||||
spin_unlock_bh(&rx_ring->idr_lock);
|
||||
|
||||
dma_unmap_single(ab->dev, rxcb->paddr,
|
||||
skb->len + skb_tailroom(skb),
|
||||
DMA_FROM_DEVICE);
|
||||
|
||||
if (ath12k_dp_pkt_set_pktlen(skb, RX_MON_STATUS_BUF_SIZE)) {
|
||||
dev_kfree_skb_any(skb);
|
||||
goto move_next;
|
||||
}
|
||||
__skb_queue_tail(skb_list, skb);
|
||||
} else {
|
||||
pmon->buf_state = DP_MON_STATUS_REPLINISH;
|
||||
}
|
||||
move_next:
|
||||
skb = ath12k_dp_rx_alloc_mon_status_buf(ab, rx_ring,
|
||||
&buf_id);
|
||||
|
||||
if (!skb) {
|
||||
ath12k_warn(ab, "failed to alloc buffer for status ring\n");
|
||||
hal_params = ab->hw_params->hal_params;
|
||||
ath12k_hal_rx_buf_addr_info_set(rx_mon_status_desc, 0, 0,
|
||||
hal_params->rx_buf_rbm);
|
||||
num_buffs_reaped++;
|
||||
break;
|
||||
}
|
||||
rxcb = ATH12K_SKB_RXCB(skb);
|
||||
|
||||
cookie = u32_encode_bits(mac_id, DP_RXDMA_BUF_COOKIE_PDEV_ID) |
|
||||
u32_encode_bits(buf_id, DP_RXDMA_BUF_COOKIE_BUF_ID);
|
||||
|
||||
ath12k_hal_rx_buf_addr_info_set(rx_mon_status_desc, rxcb->paddr,
|
||||
cookie,
|
||||
ab->hw_params->hal_params->rx_buf_rbm);
|
||||
ath12k_hal_srng_src_get_next_entry(ab, srng);
|
||||
num_buffs_reaped++;
|
||||
}
|
||||
ath12k_hal_srng_access_end(ab, srng);
|
||||
spin_unlock_bh(&srng->lock);
|
||||
|
||||
return num_buffs_reaped;
|
||||
}
|
||||
|
||||
static u32
|
||||
ath12k_dp_rx_mon_mpdu_pop(struct ath12k *ar, int mac_id,
|
||||
void *ring_entry, struct sk_buff **head_msdu,
|
||||
struct sk_buff **tail_msdu,
|
||||
struct list_head *used_list,
|
||||
u32 *npackets, u32 *ppdu_id)
|
||||
{
|
||||
struct ath12k_mon_data *pmon = (struct ath12k_mon_data *)&ar->dp.mon_data;
|
||||
struct ath12k_buffer_addr *p_buf_addr_info, *p_last_buf_addr_info;
|
||||
u32 msdu_ppdu_id = 0, msdu_cnt = 0, total_len = 0, frag_len = 0;
|
||||
u32 rx_buf_size, rx_pkt_offset, sw_cookie;
|
||||
bool is_frag, is_first_msdu, drop_mpdu = false;
|
||||
struct hal_reo_entrance_ring *ent_desc =
|
||||
(struct hal_reo_entrance_ring *)ring_entry;
|
||||
u32 rx_bufs_used = 0, i = 0, desc_bank = 0;
|
||||
struct hal_rx_desc *rx_desc, *tail_rx_desc;
|
||||
struct hal_rx_msdu_link *msdu_link_desc;
|
||||
struct sk_buff *msdu = NULL, *last = NULL;
|
||||
struct ath12k_rx_desc_info *desc_info;
|
||||
struct ath12k_buffer_addr buf_info;
|
||||
struct hal_rx_msdu_list msdu_list;
|
||||
struct ath12k_skb_rxcb *rxcb;
|
||||
u16 num_msdus = 0;
|
||||
dma_addr_t paddr;
|
||||
u8 rbm;
|
||||
|
||||
ath12k_hal_rx_reo_ent_buf_paddr_get(ring_entry, &paddr,
|
||||
&sw_cookie,
|
||||
&p_last_buf_addr_info, &rbm,
|
||||
&msdu_cnt);
|
||||
|
||||
spin_lock_bh(&pmon->mon_lock);
|
||||
|
||||
if (le32_get_bits(ent_desc->info1,
|
||||
HAL_REO_ENTR_RING_INFO1_RXDMA_PUSH_REASON) ==
|
||||
HAL_REO_DEST_RING_PUSH_REASON_ERR_DETECTED) {
|
||||
u8 rxdma_err = le32_get_bits(ent_desc->info1,
|
||||
HAL_REO_ENTR_RING_INFO1_RXDMA_ERROR_CODE);
|
||||
if (rxdma_err == HAL_REO_ENTR_RING_RXDMA_ECODE_FLUSH_REQUEST_ERR ||
|
||||
rxdma_err == HAL_REO_ENTR_RING_RXDMA_ECODE_MPDU_LEN_ERR ||
|
||||
rxdma_err == HAL_REO_ENTR_RING_RXDMA_ECODE_OVERFLOW_ERR) {
|
||||
drop_mpdu = true;
|
||||
pmon->rx_mon_stats.dest_mpdu_drop++;
|
||||
}
|
||||
}
|
||||
|
||||
is_frag = false;
|
||||
is_first_msdu = true;
|
||||
rx_pkt_offset = sizeof(struct hal_rx_desc);
|
||||
|
||||
do {
|
||||
if (pmon->mon_last_linkdesc_paddr == paddr) {
|
||||
pmon->rx_mon_stats.dup_mon_linkdesc_cnt++;
|
||||
spin_unlock_bh(&pmon->mon_lock);
|
||||
return rx_bufs_used;
|
||||
}
|
||||
|
||||
desc_bank = u32_get_bits(sw_cookie, DP_LINK_DESC_BANK_MASK);
|
||||
msdu_link_desc =
|
||||
ar->ab->dp.link_desc_banks[desc_bank].vaddr +
|
||||
(paddr - ar->ab->dp.link_desc_banks[desc_bank].paddr);
|
||||
|
||||
ath12k_hal_rx_msdu_list_get(ar, msdu_link_desc, &msdu_list,
|
||||
&num_msdus);
|
||||
desc_info = ath12k_dp_get_rx_desc(ar->ab,
|
||||
msdu_list.sw_cookie[num_msdus - 1]);
|
||||
tail_rx_desc = (struct hal_rx_desc *)(desc_info->skb)->data;
|
||||
|
||||
for (i = 0; i < num_msdus; i++) {
|
||||
u32 l2_hdr_offset;
|
||||
|
||||
if (pmon->mon_last_buf_cookie == msdu_list.sw_cookie[i]) {
|
||||
ath12k_dbg(ar->ab, ATH12K_DBG_DATA,
|
||||
"i %d last_cookie %d is same\n",
|
||||
i, pmon->mon_last_buf_cookie);
|
||||
drop_mpdu = true;
|
||||
pmon->rx_mon_stats.dup_mon_buf_cnt++;
|
||||
continue;
|
||||
}
|
||||
|
||||
desc_info =
|
||||
ath12k_dp_get_rx_desc(ar->ab, msdu_list.sw_cookie[i]);
|
||||
msdu = desc_info->skb;
|
||||
|
||||
if (!msdu) {
|
||||
ath12k_dbg(ar->ab, ATH12K_DBG_DATA,
|
||||
"msdu_pop: invalid msdu (%d/%d)\n",
|
||||
i + 1, num_msdus);
|
||||
goto next_msdu;
|
||||
}
|
||||
rxcb = ATH12K_SKB_RXCB(msdu);
|
||||
if (rxcb->paddr != msdu_list.paddr[i]) {
|
||||
ath12k_dbg(ar->ab, ATH12K_DBG_DATA,
|
||||
"i %d paddr %lx != %lx\n",
|
||||
i, (unsigned long)rxcb->paddr,
|
||||
(unsigned long)msdu_list.paddr[i]);
|
||||
drop_mpdu = true;
|
||||
continue;
|
||||
}
|
||||
if (!rxcb->unmapped) {
|
||||
dma_unmap_single(ar->ab->dev, rxcb->paddr,
|
||||
msdu->len +
|
||||
skb_tailroom(msdu),
|
||||
DMA_FROM_DEVICE);
|
||||
rxcb->unmapped = 1;
|
||||
}
|
||||
if (drop_mpdu) {
|
||||
ath12k_dbg(ar->ab, ATH12K_DBG_DATA,
|
||||
"i %d drop msdu %p *ppdu_id %x\n",
|
||||
i, msdu, *ppdu_id);
|
||||
dev_kfree_skb_any(msdu);
|
||||
msdu = NULL;
|
||||
goto next_msdu;
|
||||
}
|
||||
|
||||
rx_desc = (struct hal_rx_desc *)msdu->data;
|
||||
l2_hdr_offset = ath12k_dp_rx_h_l3pad(ar->ab, tail_rx_desc);
|
||||
if (is_first_msdu) {
|
||||
if (!ath12k_dp_rxdesc_mpdu_valid(ar->ab, rx_desc)) {
|
||||
drop_mpdu = true;
|
||||
dev_kfree_skb_any(msdu);
|
||||
msdu = NULL;
|
||||
pmon->mon_last_linkdesc_paddr = paddr;
|
||||
goto next_msdu;
|
||||
}
|
||||
msdu_ppdu_id =
|
||||
ath12k_dp_rxdesc_get_ppduid(ar->ab, rx_desc);
|
||||
|
||||
if (ath12k_dp_mon_comp_ppduid(msdu_ppdu_id,
|
||||
ppdu_id)) {
|
||||
spin_unlock_bh(&pmon->mon_lock);
|
||||
return rx_bufs_used;
|
||||
}
|
||||
pmon->mon_last_linkdesc_paddr = paddr;
|
||||
is_first_msdu = false;
|
||||
}
|
||||
ath12k_dp_mon_get_buf_len(&msdu_list.msdu_info[i],
|
||||
&is_frag, &total_len,
|
||||
&frag_len, &msdu_cnt);
|
||||
rx_buf_size = rx_pkt_offset + l2_hdr_offset + frag_len;
|
||||
|
||||
if (ath12k_dp_pkt_set_pktlen(msdu, rx_buf_size)) {
|
||||
dev_kfree_skb_any(msdu);
|
||||
goto next_msdu;
|
||||
}
|
||||
|
||||
if (!(*head_msdu))
|
||||
*head_msdu = msdu;
|
||||
else if (last)
|
||||
last->next = msdu;
|
||||
|
||||
last = msdu;
|
||||
next_msdu:
|
||||
pmon->mon_last_buf_cookie = msdu_list.sw_cookie[i];
|
||||
rx_bufs_used++;
|
||||
desc_info->skb = NULL;
|
||||
list_add_tail(&desc_info->list, used_list);
|
||||
}
|
||||
|
||||
ath12k_hal_rx_buf_addr_info_set(&buf_info, paddr, sw_cookie, rbm);
|
||||
|
||||
ath12k_dp_mon_next_link_desc_get(msdu_link_desc, &paddr,
|
||||
&sw_cookie, &rbm,
|
||||
&p_buf_addr_info);
|
||||
|
||||
ath12k_dp_rx_link_desc_return(ar->ab, &buf_info,
|
||||
HAL_WBM_REL_BM_ACT_PUT_IN_IDLE);
|
||||
|
||||
p_last_buf_addr_info = p_buf_addr_info;
|
||||
|
||||
} while (paddr && msdu_cnt);
|
||||
|
||||
spin_unlock_bh(&pmon->mon_lock);
|
||||
|
||||
if (last)
|
||||
last->next = NULL;
|
||||
|
||||
*tail_msdu = msdu;
|
||||
|
||||
if (msdu_cnt == 0)
|
||||
*npackets = 1;
|
||||
|
||||
return rx_bufs_used;
|
||||
}
|
||||
|
||||
/* The destination ring processing is stuck if the destination is not
|
||||
* moving while status ring moves 16 PPDU. The destination ring processing
|
||||
* skips this destination ring PPDU as a workaround.
|
||||
*/
|
||||
#define MON_DEST_RING_STUCK_MAX_CNT 16
|
||||
|
||||
static void ath12k_dp_rx_mon_dest_process(struct ath12k *ar, int mac_id,
|
||||
u32 quota, struct napi_struct *napi)
|
||||
{
|
||||
struct ath12k_mon_data *pmon = (struct ath12k_mon_data *)&ar->dp.mon_data;
|
||||
struct ath12k_pdev_mon_stats *rx_mon_stats;
|
||||
u32 ppdu_id, rx_bufs_used = 0, ring_id;
|
||||
u32 mpdu_rx_bufs_used, npackets = 0;
|
||||
struct ath12k_dp *dp = &ar->ab->dp;
|
||||
struct ath12k_base *ab = ar->ab;
|
||||
void *ring_entry, *mon_dst_srng;
|
||||
struct dp_mon_mpdu *tmp_mpdu;
|
||||
LIST_HEAD(rx_desc_used_list);
|
||||
struct hal_srng *srng;
|
||||
|
||||
ring_id = dp->rxdma_err_dst_ring[mac_id].ring_id;
|
||||
srng = &ab->hal.srng_list[ring_id];
|
||||
|
||||
mon_dst_srng = &ab->hal.srng_list[ring_id];
|
||||
|
||||
spin_lock_bh(&srng->lock);
|
||||
|
||||
ath12k_hal_srng_access_begin(ab, mon_dst_srng);
|
||||
|
||||
ppdu_id = pmon->mon_ppdu_info.ppdu_id;
|
||||
rx_mon_stats = &pmon->rx_mon_stats;
|
||||
|
||||
while ((ring_entry = ath12k_hal_srng_dst_peek(ar->ab, mon_dst_srng))) {
|
||||
struct sk_buff *head_msdu, *tail_msdu;
|
||||
|
||||
head_msdu = NULL;
|
||||
tail_msdu = NULL;
|
||||
|
||||
mpdu_rx_bufs_used = ath12k_dp_rx_mon_mpdu_pop(ar, mac_id, ring_entry,
|
||||
&head_msdu, &tail_msdu,
|
||||
&rx_desc_used_list,
|
||||
&npackets, &ppdu_id);
|
||||
|
||||
rx_bufs_used += mpdu_rx_bufs_used;
|
||||
|
||||
if (mpdu_rx_bufs_used) {
|
||||
dp->mon_dest_ring_stuck_cnt = 0;
|
||||
} else {
|
||||
dp->mon_dest_ring_stuck_cnt++;
|
||||
rx_mon_stats->dest_mon_not_reaped++;
|
||||
}
|
||||
|
||||
if (dp->mon_dest_ring_stuck_cnt > MON_DEST_RING_STUCK_MAX_CNT) {
|
||||
rx_mon_stats->dest_mon_stuck++;
|
||||
ath12k_dbg(ar->ab, ATH12K_DBG_DATA,
|
||||
"status ring ppdu_id=%d dest ring ppdu_id=%d mon_dest_ring_stuck_cnt=%d dest_mon_not_reaped=%u dest_mon_stuck=%u\n",
|
||||
pmon->mon_ppdu_info.ppdu_id, ppdu_id,
|
||||
dp->mon_dest_ring_stuck_cnt,
|
||||
rx_mon_stats->dest_mon_not_reaped,
|
||||
rx_mon_stats->dest_mon_stuck);
|
||||
spin_lock_bh(&pmon->mon_lock);
|
||||
pmon->mon_ppdu_info.ppdu_id = ppdu_id;
|
||||
spin_unlock_bh(&pmon->mon_lock);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (ppdu_id != pmon->mon_ppdu_info.ppdu_id) {
|
||||
spin_lock_bh(&pmon->mon_lock);
|
||||
pmon->mon_ppdu_status = DP_PPDU_STATUS_START;
|
||||
spin_unlock_bh(&pmon->mon_lock);
|
||||
ath12k_dbg(ar->ab, ATH12K_DBG_DATA,
|
||||
"dest_rx: new ppdu_id %x != status ppdu_id %x dest_mon_not_reaped = %u dest_mon_stuck = %u\n",
|
||||
ppdu_id, pmon->mon_ppdu_info.ppdu_id,
|
||||
rx_mon_stats->dest_mon_not_reaped,
|
||||
rx_mon_stats->dest_mon_stuck);
|
||||
break;
|
||||
}
|
||||
|
||||
if (head_msdu && tail_msdu) {
|
||||
tmp_mpdu = kzalloc(sizeof(*tmp_mpdu), GFP_ATOMIC);
|
||||
if (!tmp_mpdu)
|
||||
break;
|
||||
|
||||
tmp_mpdu->head = head_msdu;
|
||||
tmp_mpdu->tail = tail_msdu;
|
||||
tmp_mpdu->err_bitmap = pmon->err_bitmap;
|
||||
tmp_mpdu->decap_format = pmon->decap_format;
|
||||
ath12k_dp_mon_rx_deliver(ar, tmp_mpdu,
|
||||
&pmon->mon_ppdu_info, napi);
|
||||
rx_mon_stats->dest_mpdu_done++;
|
||||
kfree(tmp_mpdu);
|
||||
}
|
||||
|
||||
ring_entry = ath12k_hal_srng_dst_get_next_entry(ar->ab,
|
||||
mon_dst_srng);
|
||||
}
|
||||
ath12k_hal_srng_access_end(ar->ab, mon_dst_srng);
|
||||
|
||||
spin_unlock_bh(&srng->lock);
|
||||
|
||||
if (rx_bufs_used) {
|
||||
rx_mon_stats->dest_ppdu_done++;
|
||||
ath12k_dp_rx_bufs_replenish(ar->ab,
|
||||
&dp->rx_refill_buf_ring,
|
||||
&rx_desc_used_list,
|
||||
rx_bufs_used);
|
||||
}
|
||||
}
|
||||
|
||||
static int
|
||||
__ath12k_dp_mon_process_ring(struct ath12k *ar, int mac_id,
|
||||
struct napi_struct *napi, int *budget)
|
||||
{
|
||||
struct ath12k_mon_data *pmon = (struct ath12k_mon_data *)&ar->dp.mon_data;
|
||||
struct ath12k_pdev_mon_stats *rx_mon_stats = &pmon->rx_mon_stats;
|
||||
struct hal_rx_mon_ppdu_info *ppdu_info = &pmon->mon_ppdu_info;
|
||||
enum hal_rx_mon_status hal_status;
|
||||
struct sk_buff_head skb_list;
|
||||
int num_buffs_reaped;
|
||||
struct sk_buff *skb;
|
||||
|
||||
__skb_queue_head_init(&skb_list);
|
||||
|
||||
num_buffs_reaped = ath12k_dp_rx_reap_mon_status_ring(ar->ab, mac_id,
|
||||
budget, &skb_list);
|
||||
if (!num_buffs_reaped)
|
||||
goto exit;
|
||||
|
||||
while ((skb = __skb_dequeue(&skb_list))) {
|
||||
memset(ppdu_info, 0, sizeof(*ppdu_info));
|
||||
ppdu_info->peer_id = HAL_INVALID_PEERID;
|
||||
|
||||
hal_status = ath12k_dp_mon_parse_rx_dest(ar, pmon, skb);
|
||||
|
||||
if (ar->monitor_started &&
|
||||
pmon->mon_ppdu_status == DP_PPDU_STATUS_START &&
|
||||
hal_status == HAL_TLV_STATUS_PPDU_DONE) {
|
||||
rx_mon_stats->status_ppdu_done++;
|
||||
pmon->mon_ppdu_status = DP_PPDU_STATUS_DONE;
|
||||
ath12k_dp_rx_mon_dest_process(ar, mac_id, *budget, napi);
|
||||
pmon->mon_ppdu_status = DP_PPDU_STATUS_START;
|
||||
}
|
||||
|
||||
dev_kfree_skb_any(skb);
|
||||
}
|
||||
|
||||
exit:
|
||||
return num_buffs_reaped;
|
||||
}
|
||||
|
||||
int ath12k_dp_mon_process_ring(struct ath12k_base *ab, int mac_id,
|
||||
struct napi_struct *napi, int budget,
|
||||
enum dp_monitor_mode monitor_mode)
|
||||
@ -3651,6 +4381,10 @@ int ath12k_dp_mon_process_ring(struct ath12k_base *ab, int mac_id,
|
||||
if (ab->hw_params->rxdma1_enable) {
|
||||
if (monitor_mode == ATH12K_DP_RX_MONITOR_MODE)
|
||||
num_buffs_reaped = ath12k_dp_mon_srng_process(ar, &budget, napi);
|
||||
} else {
|
||||
if (ar->monitor_started)
|
||||
num_buffs_reaped =
|
||||
__ath12k_dp_mon_process_ring(ar, mac_id, napi, &budget);
|
||||
}
|
||||
|
||||
return num_buffs_reaped;
|
||||
|
||||
@ -85,6 +85,9 @@ ath12k_dp_mon_rx_parse_mon_status(struct ath12k *ar,
|
||||
int ath12k_dp_mon_buf_replenish(struct ath12k_base *ab,
|
||||
struct dp_rxdma_mon_ring *buf_ring,
|
||||
int req_entries);
|
||||
int ath12k_dp_mon_status_bufs_replenish(struct ath12k_base *ab,
|
||||
struct dp_rxdma_mon_ring *rx_ring,
|
||||
int req_entries);
|
||||
int ath12k_dp_mon_process_ring(struct ath12k_base *ab, int mac_id,
|
||||
struct napi_struct *napi, int budget,
|
||||
enum dp_monitor_mode monitor_mode);
|
||||
|
||||
@ -194,6 +194,22 @@ static void ath12k_dp_rxdesc_set_msdu_len(struct ath12k_base *ab,
|
||||
ab->hal_rx_ops->rx_desc_set_msdu_len(desc, len);
|
||||
}
|
||||
|
||||
u32 ath12k_dp_rxdesc_get_ppduid(struct ath12k_base *ab,
|
||||
struct hal_rx_desc *rx_desc)
|
||||
{
|
||||
return ab->hal_rx_ops->rx_desc_get_mpdu_ppdu_id(rx_desc);
|
||||
}
|
||||
|
||||
bool ath12k_dp_rxdesc_mpdu_valid(struct ath12k_base *ab,
|
||||
struct hal_rx_desc *rx_desc)
|
||||
{
|
||||
u32 tlv_tag;
|
||||
|
||||
tlv_tag = ab->hal_rx_ops->rx_desc_get_mpdu_start_tag(rx_desc);
|
||||
|
||||
return tlv_tag == HAL_RX_MPDU_START;
|
||||
}
|
||||
|
||||
static bool ath12k_dp_rx_h_is_da_mcbc(struct ath12k_base *ab,
|
||||
struct hal_rx_desc *desc)
|
||||
{
|
||||
@ -414,9 +430,17 @@ static int ath12k_dp_rxdma_mon_buf_ring_free(struct ath12k_base *ab,
|
||||
static int ath12k_dp_rxdma_buf_free(struct ath12k_base *ab)
|
||||
{
|
||||
struct ath12k_dp *dp = &ab->dp;
|
||||
int i;
|
||||
|
||||
ath12k_dp_rxdma_mon_buf_ring_free(ab, &dp->rxdma_mon_buf_ring);
|
||||
|
||||
if (ab->hw_params->rxdma1_enable)
|
||||
return 0;
|
||||
|
||||
for (i = 0; i < ab->hw_params->num_rxdma_per_pdev; i++)
|
||||
ath12k_dp_rxdma_mon_buf_ring_free(ab,
|
||||
&dp->rx_mon_status_refill_ring[i]);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -430,7 +454,12 @@ static int ath12k_dp_rxdma_mon_ring_buf_setup(struct ath12k_base *ab,
|
||||
ath12k_hal_srng_get_entrysize(ab, ringtype);
|
||||
|
||||
rx_ring->bufs_max = num_entries;
|
||||
ath12k_dp_mon_buf_replenish(ab, rx_ring, num_entries);
|
||||
|
||||
if (ringtype == HAL_RXDMA_MONITOR_STATUS)
|
||||
ath12k_dp_mon_status_bufs_replenish(ab, rx_ring,
|
||||
num_entries);
|
||||
else
|
||||
ath12k_dp_mon_buf_replenish(ab, rx_ring, num_entries);
|
||||
|
||||
return 0;
|
||||
}
|
||||
@ -451,7 +480,8 @@ static int ath12k_dp_rxdma_ring_buf_setup(struct ath12k_base *ab,
|
||||
static int ath12k_dp_rxdma_buf_setup(struct ath12k_base *ab)
|
||||
{
|
||||
struct ath12k_dp *dp = &ab->dp;
|
||||
int ret;
|
||||
struct dp_rxdma_mon_ring *mon_ring;
|
||||
int ret, i;
|
||||
|
||||
ret = ath12k_dp_rxdma_ring_buf_setup(ab, &dp->rx_refill_buf_ring);
|
||||
if (ret) {
|
||||
@ -464,9 +494,19 @@ static int ath12k_dp_rxdma_buf_setup(struct ath12k_base *ab)
|
||||
ret = ath12k_dp_rxdma_mon_ring_buf_setup(ab,
|
||||
&dp->rxdma_mon_buf_ring,
|
||||
HAL_RXDMA_MONITOR_BUF);
|
||||
if (ret) {
|
||||
if (ret)
|
||||
ath12k_warn(ab,
|
||||
"failed to setup HAL_RXDMA_MONITOR_BUF\n");
|
||||
return ret;
|
||||
}
|
||||
|
||||
for (i = 0; i < ab->hw_params->num_rxdma_per_pdev; i++) {
|
||||
mon_ring = &dp->rx_mon_status_refill_ring[i];
|
||||
ret = ath12k_dp_rxdma_mon_ring_buf_setup(ab, mon_ring,
|
||||
HAL_RXDMA_MONITOR_STATUS);
|
||||
if (ret) {
|
||||
ath12k_warn(ab,
|
||||
"failed to setup HAL_RXDMA_MONITOR_STATUS\n");
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
@ -819,15 +859,10 @@ void ath12k_dp_rx_peer_tid_delete(struct ath12k *ar,
|
||||
rx_tid->active = false;
|
||||
}
|
||||
|
||||
/* TODO: it's strange (and ugly) that struct hal_reo_dest_ring is converted
|
||||
* to struct hal_wbm_release_ring, I couldn't figure out the logic behind
|
||||
* that.
|
||||
*/
|
||||
static int ath12k_dp_rx_link_desc_return(struct ath12k_base *ab,
|
||||
struct hal_reo_dest_ring *ring,
|
||||
enum hal_wbm_rel_bm_act action)
|
||||
int ath12k_dp_rx_link_desc_return(struct ath12k_base *ab,
|
||||
struct ath12k_buffer_addr *buf_addr_info,
|
||||
enum hal_wbm_rel_bm_act action)
|
||||
{
|
||||
struct hal_wbm_release_ring *link_desc = (struct hal_wbm_release_ring *)ring;
|
||||
struct hal_wbm_release_ring *desc;
|
||||
struct ath12k_dp *dp = &ab->dp;
|
||||
struct hal_srng *srng;
|
||||
@ -845,7 +880,7 @@ static int ath12k_dp_rx_link_desc_return(struct ath12k_base *ab,
|
||||
goto exit;
|
||||
}
|
||||
|
||||
ath12k_hal_rx_msdu_link_desc_set(ab, desc, link_desc, action);
|
||||
ath12k_hal_rx_msdu_link_desc_set(ab, desc, buf_addr_info, action);
|
||||
|
||||
exit:
|
||||
ath12k_hal_srng_access_end(ab, srng);
|
||||
@ -858,14 +893,17 @@ static int ath12k_dp_rx_link_desc_return(struct ath12k_base *ab,
|
||||
static void ath12k_dp_rx_frags_cleanup(struct ath12k_dp_rx_tid *rx_tid,
|
||||
bool rel_link_desc)
|
||||
{
|
||||
struct ath12k_buffer_addr *buf_addr_info;
|
||||
struct ath12k_base *ab = rx_tid->ab;
|
||||
|
||||
lockdep_assert_held(&ab->base_lock);
|
||||
|
||||
if (rx_tid->dst_ring_desc) {
|
||||
if (rel_link_desc)
|
||||
ath12k_dp_rx_link_desc_return(ab, rx_tid->dst_ring_desc,
|
||||
if (rel_link_desc) {
|
||||
buf_addr_info = &rx_tid->dst_ring_desc->buf_addr_info;
|
||||
ath12k_dp_rx_link_desc_return(ab, buf_addr_info,
|
||||
HAL_WBM_REL_BM_ACT_PUT_IN_IDLE);
|
||||
}
|
||||
kfree(rx_tid->dst_ring_desc);
|
||||
rx_tid->dst_ring_desc = NULL;
|
||||
}
|
||||
@ -1802,8 +1840,12 @@ void ath12k_dp_htt_htc_t2h_msg_handler(struct ath12k_base *ab,
|
||||
HTT_T2H_PEER_MAP_INFO1_MAC_ADDR_H16);
|
||||
ath12k_dp_get_mac_addr(le32_to_cpu(resp->peer_map_ev.mac_addr_l32),
|
||||
peer_mac_h16, mac_addr);
|
||||
ast_hash = le32_get_bits(resp->peer_map_ev.info2,
|
||||
HTT_T2H_PEER_MAP3_INFO2_AST_HASH_VAL);
|
||||
hw_peer_id = le32_get_bits(resp->peer_map_ev.info2,
|
||||
HTT_T2H_PEER_MAP3_INFO2_HW_PEER_ID);
|
||||
ath12k_peer_map_event(ab, vdev_id, peer_id, mac_addr, ast_hash,
|
||||
peer_id);
|
||||
hw_peer_id);
|
||||
break;
|
||||
case HTT_T2H_MSG_TYPE_PEER_UNMAP:
|
||||
case HTT_T2H_MSG_TYPE_PEER_UNMAP2:
|
||||
@ -2592,7 +2634,7 @@ static bool ath12k_dp_rx_check_nwifi_hdr_len_valid(struct ath12k_base *ab,
|
||||
if ((likely(hdr_len <= DP_MAX_NWIFI_HDR_LEN)))
|
||||
return true;
|
||||
|
||||
ab->soc_stats.invalid_rbm++;
|
||||
ab->device_stats.invalid_rbm++;
|
||||
WARN_ON_ONCE(1);
|
||||
return false;
|
||||
}
|
||||
@ -2755,9 +2797,9 @@ int ath12k_dp_rx_process(struct ath12k_base *ab, int ring_id,
|
||||
struct napi_struct *napi, int budget)
|
||||
{
|
||||
struct ath12k_hw_group *ag = ab->ag;
|
||||
struct list_head rx_desc_used_list[ATH12K_MAX_SOCS];
|
||||
struct list_head rx_desc_used_list[ATH12K_MAX_DEVICES];
|
||||
struct ath12k_hw_link *hw_links = ag->hw_links;
|
||||
int num_buffs_reaped[ATH12K_MAX_SOCS] = {};
|
||||
int num_buffs_reaped[ATH12K_MAX_DEVICES] = {};
|
||||
struct ath12k_rx_desc_info *desc_info;
|
||||
struct ath12k_dp *dp = &ab->dp;
|
||||
struct dp_rxdma_ring *rx_ring = &dp->rx_refill_buf_ring;
|
||||
@ -2774,7 +2816,7 @@ int ath12k_dp_rx_process(struct ath12k_base *ab, int ring_id,
|
||||
|
||||
__skb_queue_head_init(&msdu_list);
|
||||
|
||||
for (device_id = 0; device_id < ATH12K_MAX_SOCS; device_id++)
|
||||
for (device_id = 0; device_id < ATH12K_MAX_DEVICES; device_id++)
|
||||
INIT_LIST_HEAD(&rx_desc_used_list[device_id]);
|
||||
|
||||
srng = &ab->hal.srng_list[dp->reo_dst_ring[ring_id].ring_id];
|
||||
@ -2835,13 +2877,14 @@ int ath12k_dp_rx_process(struct ath12k_base *ab, int ring_id,
|
||||
DMA_FROM_DEVICE);
|
||||
|
||||
num_buffs_reaped[device_id]++;
|
||||
ab->device_stats.reo_rx[ring_id][ab->device_id]++;
|
||||
|
||||
push_reason = le32_get_bits(desc->info0,
|
||||
HAL_REO_DEST_RING_INFO0_PUSH_REASON);
|
||||
if (push_reason !=
|
||||
HAL_REO_DEST_RING_PUSH_REASON_ROUTING_INSTRUCTION) {
|
||||
dev_kfree_skb_any(msdu);
|
||||
ab->soc_stats.hal_reo_error[ring_id]++;
|
||||
ab->device_stats.hal_reo_error[ring_id]++;
|
||||
continue;
|
||||
}
|
||||
|
||||
@ -2891,7 +2934,7 @@ int ath12k_dp_rx_process(struct ath12k_base *ab, int ring_id,
|
||||
if (!total_msdu_reaped)
|
||||
goto exit;
|
||||
|
||||
for (device_id = 0; device_id < ATH12K_MAX_SOCS; device_id++) {
|
||||
for (device_id = 0; device_id < ATH12K_MAX_DEVICES; device_id++) {
|
||||
if (!num_buffs_reaped[device_id])
|
||||
continue;
|
||||
|
||||
@ -3483,7 +3526,7 @@ static int ath12k_dp_rx_frag_h_mpdu(struct ath12k *ar,
|
||||
goto out_unlock;
|
||||
}
|
||||
} else {
|
||||
ath12k_dp_rx_link_desc_return(ab, ring_desc,
|
||||
ath12k_dp_rx_link_desc_return(ab, &ring_desc->buf_addr_info,
|
||||
HAL_WBM_REL_BM_ACT_PUT_IN_IDLE);
|
||||
}
|
||||
|
||||
@ -3596,7 +3639,7 @@ ath12k_dp_process_rx_err_buf(struct ath12k *ar, struct hal_reo_dest_ring *desc,
|
||||
|
||||
if (ath12k_dp_rx_frag_h_mpdu(ar, msdu, desc)) {
|
||||
dev_kfree_skb_any(msdu);
|
||||
ath12k_dp_rx_link_desc_return(ar->ab, desc,
|
||||
ath12k_dp_rx_link_desc_return(ar->ab, &desc->buf_addr_info,
|
||||
HAL_WBM_REL_BM_ACT_PUT_IN_IDLE);
|
||||
}
|
||||
exit:
|
||||
@ -3608,9 +3651,9 @@ int ath12k_dp_rx_process_err(struct ath12k_base *ab, struct napi_struct *napi,
|
||||
int budget)
|
||||
{
|
||||
struct ath12k_hw_group *ag = ab->ag;
|
||||
struct list_head rx_desc_used_list[ATH12K_MAX_SOCS];
|
||||
struct list_head rx_desc_used_list[ATH12K_MAX_DEVICES];
|
||||
u32 msdu_cookies[HAL_NUM_RX_MSDUS_PER_LINK_DESC];
|
||||
int num_buffs_reaped[ATH12K_MAX_SOCS] = {};
|
||||
int num_buffs_reaped[ATH12K_MAX_DEVICES] = {};
|
||||
struct dp_link_desc_bank *link_desc_banks;
|
||||
enum hal_rx_buf_return_buf_manager rbm;
|
||||
struct hal_rx_msdu_link *link_desc_va;
|
||||
@ -3632,7 +3675,7 @@ int ath12k_dp_rx_process_err(struct ath12k_base *ab, struct napi_struct *napi,
|
||||
tot_n_bufs_reaped = 0;
|
||||
quota = budget;
|
||||
|
||||
for (device_id = 0; device_id < ATH12K_MAX_SOCS; device_id++)
|
||||
for (device_id = 0; device_id < ATH12K_MAX_DEVICES; device_id++)
|
||||
INIT_LIST_HEAD(&rx_desc_used_list[device_id]);
|
||||
|
||||
reo_except = &ab->dp.reo_except_ring;
|
||||
@ -3646,7 +3689,7 @@ int ath12k_dp_rx_process_err(struct ath12k_base *ab, struct napi_struct *napi,
|
||||
while (budget &&
|
||||
(reo_desc = ath12k_hal_srng_dst_get_next_entry(ab, srng))) {
|
||||
drop = false;
|
||||
ab->soc_stats.err_ring_pkts++;
|
||||
ab->device_stats.err_ring_pkts++;
|
||||
|
||||
ret = ath12k_hal_desc_reo_parse_err(ab, reo_desc, &paddr,
|
||||
&desc_bank);
|
||||
@ -3673,9 +3716,10 @@ int ath12k_dp_rx_process_err(struct ath12k_base *ab, struct napi_struct *napi,
|
||||
if (rbm != partner_ab->dp.idle_link_rbm &&
|
||||
rbm != HAL_RX_BUF_RBM_SW3_BM &&
|
||||
rbm != partner_ab->hw_params->hal_params->rx_buf_rbm) {
|
||||
ab->soc_stats.invalid_rbm++;
|
||||
ab->device_stats.invalid_rbm++;
|
||||
ath12k_warn(ab, "invalid return buffer manager %d\n", rbm);
|
||||
ath12k_dp_rx_link_desc_return(partner_ab, reo_desc,
|
||||
ath12k_dp_rx_link_desc_return(partner_ab,
|
||||
&reo_desc->buf_addr_info,
|
||||
HAL_WBM_REL_BM_ACT_REL_MSDU);
|
||||
continue;
|
||||
}
|
||||
@ -3693,7 +3737,8 @@ int ath12k_dp_rx_process_err(struct ath12k_base *ab, struct napi_struct *napi,
|
||||
drop = true;
|
||||
|
||||
/* Return the link desc back to wbm idle list */
|
||||
ath12k_dp_rx_link_desc_return(partner_ab, reo_desc,
|
||||
ath12k_dp_rx_link_desc_return(partner_ab,
|
||||
&reo_desc->buf_addr_info,
|
||||
HAL_WBM_REL_BM_ACT_PUT_IN_IDLE);
|
||||
}
|
||||
|
||||
@ -3720,7 +3765,7 @@ int ath12k_dp_rx_process_err(struct ath12k_base *ab, struct napi_struct *napi,
|
||||
|
||||
spin_unlock_bh(&srng->lock);
|
||||
|
||||
for (device_id = 0; device_id < ATH12K_MAX_SOCS; device_id++) {
|
||||
for (device_id = 0; device_id < ATH12K_MAX_DEVICES; device_id++) {
|
||||
if (!num_buffs_reaped[device_id])
|
||||
continue;
|
||||
|
||||
@ -3836,7 +3881,7 @@ static bool ath12k_dp_rx_h_reo_err(struct ath12k *ar, struct sk_buff *msdu,
|
||||
struct ath12k_skb_rxcb *rxcb = ATH12K_SKB_RXCB(msdu);
|
||||
bool drop = false;
|
||||
|
||||
ar->ab->soc_stats.reo_error[rxcb->err_code]++;
|
||||
ar->ab->device_stats.reo_error[rxcb->err_code]++;
|
||||
|
||||
switch (rxcb->err_code) {
|
||||
case HAL_REO_DEST_RING_ERROR_CODE_DESC_ADDR_ZERO:
|
||||
@ -3909,7 +3954,7 @@ static bool ath12k_dp_rx_h_rxdma_err(struct ath12k *ar, struct sk_buff *msdu,
|
||||
bool drop = false;
|
||||
u32 err_bitmap;
|
||||
|
||||
ar->ab->soc_stats.rxdma_error[rxcb->err_code]++;
|
||||
ar->ab->device_stats.rxdma_error[rxcb->err_code]++;
|
||||
|
||||
switch (rxcb->err_code) {
|
||||
case HAL_REO_ENTR_RING_RXDMA_ECODE_DECRYPT_ERR:
|
||||
@ -3968,7 +4013,7 @@ static void ath12k_dp_rx_wbm_err(struct ath12k *ar,
|
||||
int ath12k_dp_rx_process_wbm_err(struct ath12k_base *ab,
|
||||
struct napi_struct *napi, int budget)
|
||||
{
|
||||
struct list_head rx_desc_used_list[ATH12K_MAX_SOCS];
|
||||
struct list_head rx_desc_used_list[ATH12K_MAX_DEVICES];
|
||||
struct ath12k_hw_group *ag = ab->ag;
|
||||
struct ath12k *ar;
|
||||
struct ath12k_dp *dp = &ab->dp;
|
||||
@ -3979,9 +4024,10 @@ int ath12k_dp_rx_process_wbm_err(struct ath12k_base *ab,
|
||||
struct sk_buff_head msdu_list, scatter_msdu_list;
|
||||
struct ath12k_skb_rxcb *rxcb;
|
||||
void *rx_desc;
|
||||
int num_buffs_reaped[ATH12K_MAX_SOCS] = {};
|
||||
int num_buffs_reaped[ATH12K_MAX_DEVICES] = {};
|
||||
int total_num_buffs_reaped = 0;
|
||||
struct ath12k_rx_desc_info *desc_info;
|
||||
struct ath12k_device_dp_stats *device_stats = &ab->device_stats;
|
||||
struct ath12k_hw_link *hw_links = ag->hw_links;
|
||||
struct ath12k_base *partner_ab;
|
||||
u8 hw_link_id, device_id;
|
||||
@ -3991,7 +4037,7 @@ int ath12k_dp_rx_process_wbm_err(struct ath12k_base *ab,
|
||||
__skb_queue_head_init(&msdu_list);
|
||||
__skb_queue_head_init(&scatter_msdu_list);
|
||||
|
||||
for (device_id = 0; device_id < ATH12K_MAX_SOCS; device_id++)
|
||||
for (device_id = 0; device_id < ATH12K_MAX_DEVICES; device_id++)
|
||||
INIT_LIST_HEAD(&rx_desc_used_list[device_id]);
|
||||
|
||||
srng = &ab->hal.srng_list[dp->rx_rel_ring.ring_id];
|
||||
@ -4115,7 +4161,7 @@ int ath12k_dp_rx_process_wbm_err(struct ath12k_base *ab,
|
||||
if (!total_num_buffs_reaped)
|
||||
goto done;
|
||||
|
||||
for (device_id = 0; device_id < ATH12K_MAX_SOCS; device_id++) {
|
||||
for (device_id = 0; device_id < ATH12K_MAX_DEVICES; device_id++) {
|
||||
if (!num_buffs_reaped[device_id])
|
||||
continue;
|
||||
|
||||
@ -4155,6 +4201,12 @@ int ath12k_dp_rx_process_wbm_err(struct ath12k_base *ab,
|
||||
dev_kfree_skb_any(msdu);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (rxcb->err_rel_src < HAL_WBM_REL_SRC_MODULE_MAX) {
|
||||
device_id = ar->ab->device_id;
|
||||
device_stats->rx_wbm_rel_source[rxcb->err_rel_src][device_id]++;
|
||||
}
|
||||
|
||||
ath12k_dp_rx_wbm_err(ar, napi, msdu, &msdu_list);
|
||||
}
|
||||
rcu_read_unlock();
|
||||
@ -4244,6 +4296,7 @@ void ath12k_dp_rx_process_reo_status(struct ath12k_base *ab)
|
||||
void ath12k_dp_rx_free(struct ath12k_base *ab)
|
||||
{
|
||||
struct ath12k_dp *dp = &ab->dp;
|
||||
struct dp_srng *srng;
|
||||
int i;
|
||||
|
||||
ath12k_dp_srng_cleanup(ab, &dp->rx_refill_buf_ring.refill_buf_ring);
|
||||
@ -4251,6 +4304,10 @@ void ath12k_dp_rx_free(struct ath12k_base *ab)
|
||||
for (i = 0; i < ab->hw_params->num_rxdma_per_pdev; i++) {
|
||||
if (ab->hw_params->rx_mac_buf_ring)
|
||||
ath12k_dp_srng_cleanup(ab, &dp->rx_mac_buf_ring[i]);
|
||||
if (!ab->hw_params->rxdma1_enable) {
|
||||
srng = &dp->rx_mon_status_refill_ring[i].refill_buf_ring;
|
||||
ath12k_dp_srng_cleanup(ab, srng);
|
||||
}
|
||||
}
|
||||
|
||||
for (i = 0; i < ab->hw_params->num_rxdma_dst_ring; i++)
|
||||
@ -4399,6 +4456,19 @@ int ath12k_dp_rx_htt_setup(struct ath12k_base *ab)
|
||||
ret);
|
||||
return ret;
|
||||
}
|
||||
} else {
|
||||
for (i = 0; i < ab->hw_params->num_rxdma_per_pdev; i++) {
|
||||
ring_id =
|
||||
dp->rx_mon_status_refill_ring[i].refill_buf_ring.ring_id;
|
||||
ret = ath12k_dp_tx_htt_srng_setup(ab, ring_id, i,
|
||||
HAL_RXDMA_MONITOR_STATUS);
|
||||
if (ret) {
|
||||
ath12k_warn(ab,
|
||||
"failed to configure mon_status_refill_ring%d %d\n",
|
||||
i, ret);
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ret = ab->hw_params->hw_ops->rxdma_ring_sel_config(ab);
|
||||
@ -4413,6 +4483,7 @@ int ath12k_dp_rx_htt_setup(struct ath12k_base *ab)
|
||||
int ath12k_dp_rx_alloc(struct ath12k_base *ab)
|
||||
{
|
||||
struct ath12k_dp *dp = &ab->dp;
|
||||
struct dp_srng *srng;
|
||||
int i, ret;
|
||||
|
||||
idr_init(&dp->rxdma_mon_buf_ring.bufs_idr);
|
||||
@ -4460,6 +4531,23 @@ int ath12k_dp_rx_alloc(struct ath12k_base *ab)
|
||||
ath12k_warn(ab, "failed to setup HAL_RXDMA_MONITOR_BUF\n");
|
||||
return ret;
|
||||
}
|
||||
} else {
|
||||
for (i = 0; i < ab->hw_params->num_rxdma_per_pdev; i++) {
|
||||
idr_init(&dp->rx_mon_status_refill_ring[i].bufs_idr);
|
||||
spin_lock_init(&dp->rx_mon_status_refill_ring[i].idr_lock);
|
||||
}
|
||||
|
||||
for (i = 0; i < ab->hw_params->num_rxdma_per_pdev; i++) {
|
||||
srng = &dp->rx_mon_status_refill_ring[i].refill_buf_ring;
|
||||
ret = ath12k_dp_srng_setup(ab, srng,
|
||||
HAL_RXDMA_MONITOR_STATUS, 0, i,
|
||||
DP_RXDMA_MON_STATUS_RING_SIZE);
|
||||
if (ret) {
|
||||
ath12k_warn(ab, "failed to setup mon status ring %d\n",
|
||||
i);
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ret = ath12k_dp_rxdma_buf_setup(ab);
|
||||
@ -4530,17 +4618,15 @@ int ath12k_dp_rx_pdev_mon_attach(struct ath12k *ar)
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* if rxdma1_enable is false, no need to setup
|
||||
* rxdma_mon_desc_ring.
|
||||
*/
|
||||
pmon->mon_last_linkdesc_paddr = 0;
|
||||
pmon->mon_last_buf_cookie = DP_RX_DESC_COOKIE_MAX + 1;
|
||||
spin_lock_init(&pmon->mon_lock);
|
||||
|
||||
if (!ar->ab->hw_params->rxdma1_enable)
|
||||
return 0;
|
||||
|
||||
pmon->mon_last_linkdesc_paddr = 0;
|
||||
pmon->mon_last_buf_cookie = DP_RX_DESC_COOKIE_MAX + 1;
|
||||
INIT_LIST_HEAD(&pmon->dp_rx_mon_mpdu_list);
|
||||
pmon->mon_mpdu = NULL;
|
||||
spin_lock_init(&pmon->mon_lock);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -165,5 +165,13 @@ void ath12k_dp_rx_h_fetch_info(struct ath12k_base *ab, struct hal_rx_desc *rx_d
|
||||
struct ath12k_dp_rx_info *rx_info);
|
||||
|
||||
int ath12k_dp_rx_crypto_mic_len(struct ath12k *ar, enum hal_encrypt_type enctype);
|
||||
|
||||
u32 ath12k_dp_rxdesc_get_ppduid(struct ath12k_base *ab,
|
||||
struct hal_rx_desc *rx_desc);
|
||||
bool ath12k_dp_rxdesc_mpdu_valid(struct ath12k_base *ab,
|
||||
struct hal_rx_desc *rx_desc);
|
||||
int ath12k_dp_rx_link_desc_return(struct ath12k_base *ab,
|
||||
struct ath12k_buffer_addr *buf_addr_info,
|
||||
enum hal_wbm_rel_bm_act action);
|
||||
bool ath12k_dp_rxdesc_mpdu_valid(struct ath12k_base *ab,
|
||||
struct hal_rx_desc *rx_desc);
|
||||
#endif /* ATH12K_DP_RX_H */
|
||||
|
||||
@ -350,7 +350,7 @@ int ath12k_dp_tx(struct ath12k *ar, struct ath12k_link_vif *arvif,
|
||||
default:
|
||||
/* TODO: Take care of other encap modes as well */
|
||||
ret = -EINVAL;
|
||||
atomic_inc(&ab->soc_stats.tx_err.misc_fail);
|
||||
atomic_inc(&ab->device_stats.tx_err.misc_fail);
|
||||
goto fail_remove_tx_buf;
|
||||
}
|
||||
|
||||
@ -373,7 +373,7 @@ int ath12k_dp_tx(struct ath12k *ar, struct ath12k_link_vif *arvif,
|
||||
map:
|
||||
ti.paddr = dma_map_single(ab->dev, skb->data, skb->len, DMA_TO_DEVICE);
|
||||
if (dma_mapping_error(ab->dev, ti.paddr)) {
|
||||
atomic_inc(&ab->soc_stats.tx_err.misc_fail);
|
||||
atomic_inc(&ab->device_stats.tx_err.misc_fail);
|
||||
ath12k_warn(ab, "failed to DMA map data Tx buffer\n");
|
||||
ret = -ENOMEM;
|
||||
goto fail_remove_tx_buf;
|
||||
@ -448,7 +448,7 @@ int ath12k_dp_tx(struct ath12k *ar, struct ath12k_link_vif *arvif,
|
||||
* desc because the desc is directly enqueued onto hw queue.
|
||||
*/
|
||||
ath12k_hal_srng_access_end(ab, tcl_ring);
|
||||
ab->soc_stats.tx_err.desc_na[ti.ring_id]++;
|
||||
ab->device_stats.tx_err.desc_na[ti.ring_id]++;
|
||||
spin_unlock_bh(&tcl_ring->lock);
|
||||
ret = -ENOMEM;
|
||||
|
||||
@ -477,6 +477,8 @@ int ath12k_dp_tx(struct ath12k *ar, struct ath12k_link_vif *arvif,
|
||||
arvif->link_stats.tx_enqueued++;
|
||||
spin_unlock_bh(&arvif->link_stats_lock);
|
||||
|
||||
ab->device_stats.tx_enqueued[ti.ring_id]++;
|
||||
|
||||
ath12k_hal_tx_cmd_desc_setup(ab, hal_tcl_desc, &ti);
|
||||
|
||||
ath12k_hal_srng_access_end(ab, tcl_ring);
|
||||
@ -557,6 +559,7 @@ ath12k_dp_tx_htt_tx_complete_buf(struct ath12k_base *ab,
|
||||
info = IEEE80211_SKB_CB(msdu);
|
||||
|
||||
ar = skb_cb->ar;
|
||||
ab->device_stats.tx_completed[tx_ring->tcl_data_ring_id]++;
|
||||
|
||||
if (atomic_dec_and_test(&ar->dp.num_tx_pending))
|
||||
wake_up(&ar->dp.tx_empty_waitq);
|
||||
@ -614,6 +617,7 @@ ath12k_dp_tx_process_htt_tx_complete(struct ath12k_base *ab, void *desc,
|
||||
|
||||
wbm_status = le32_get_bits(status_desc->info0,
|
||||
HTT_TX_WBM_COMP_INFO0_STATUS);
|
||||
ab->device_stats.fw_tx_status[wbm_status]++;
|
||||
|
||||
switch (wbm_status) {
|
||||
case HAL_WBM_REL_HTT_TX_COMP_STATUS_OK:
|
||||
@ -760,7 +764,8 @@ static void ath12k_dp_tx_update_txcompl(struct ath12k *ar, struct hal_tx_status
|
||||
|
||||
static void ath12k_dp_tx_complete_msdu(struct ath12k *ar,
|
||||
struct ath12k_tx_desc_params *desc_params,
|
||||
struct hal_tx_status *ts)
|
||||
struct hal_tx_status *ts,
|
||||
int ring)
|
||||
{
|
||||
struct ath12k_base *ab = ar->ab;
|
||||
struct ath12k_hw *ah = ar->ah;
|
||||
@ -777,6 +782,7 @@ static void ath12k_dp_tx_complete_msdu(struct ath12k *ar,
|
||||
}
|
||||
|
||||
skb_cb = ATH12K_SKB_CB(msdu);
|
||||
ab->device_stats.tx_completed[ring]++;
|
||||
|
||||
dma_unmap_single(ab->dev, skb_cb->paddr, msdu->len, DMA_TO_DEVICE);
|
||||
if (skb_cb->paddr_ext_desc) {
|
||||
@ -907,6 +913,8 @@ void ath12k_dp_tx_completion_handler(struct ath12k_base *ab, int ring_id)
|
||||
struct hal_wbm_release_ring *desc;
|
||||
u8 pdev_id;
|
||||
u64 desc_va;
|
||||
enum hal_wbm_rel_src_module buf_rel_source;
|
||||
enum hal_wbm_tqm_rel_reason rel_status;
|
||||
|
||||
spin_lock_bh(&status_ring->lock);
|
||||
|
||||
@ -963,6 +971,15 @@ void ath12k_dp_tx_completion_handler(struct ath12k_base *ab, int ring_id)
|
||||
desc_params.skb = tx_desc->skb;
|
||||
desc_params.skb_ext_desc = tx_desc->skb_ext_desc;
|
||||
|
||||
/* Find the HAL_WBM_RELEASE_INFO0_REL_SRC_MODULE value */
|
||||
buf_rel_source = le32_get_bits(tx_status->info0,
|
||||
HAL_WBM_RELEASE_INFO0_REL_SRC_MODULE);
|
||||
ab->device_stats.tx_wbm_rel_source[buf_rel_source]++;
|
||||
|
||||
rel_status = le32_get_bits(tx_status->info0,
|
||||
HAL_WBM_COMPL_TX_INFO0_TQM_RELEASE_REASON);
|
||||
ab->device_stats.tqm_rel_reason[rel_status]++;
|
||||
|
||||
/* Release descriptor as soon as extracting necessary info
|
||||
* to reduce contention
|
||||
*/
|
||||
@ -979,7 +996,8 @@ void ath12k_dp_tx_completion_handler(struct ath12k_base *ab, int ring_id)
|
||||
if (atomic_dec_and_test(&ar->dp.num_tx_pending))
|
||||
wake_up(&ar->dp.tx_empty_waitq);
|
||||
|
||||
ath12k_dp_tx_complete_msdu(ar, &desc_params, &ts);
|
||||
ath12k_dp_tx_complete_msdu(ar, &desc_params, &ts,
|
||||
tx_ring->tcl_data_ring_id);
|
||||
}
|
||||
}
|
||||
|
||||
@ -1511,6 +1529,44 @@ int ath12k_dp_tx_htt_rx_monitor_mode_ring_config(struct ath12k *ar, bool reset)
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (!reset) {
|
||||
for (i = 0; i < ab->hw_params->num_rxdma_per_pdev; i++) {
|
||||
ring_id = ab->dp.rx_mac_buf_ring[i].ring_id;
|
||||
ret = ath12k_dp_tx_htt_rx_filter_setup(ar->ab, ring_id,
|
||||
i,
|
||||
HAL_RXDMA_BUF,
|
||||
DP_RXDMA_REFILL_RING_SIZE,
|
||||
&tlv_filter);
|
||||
if (ret) {
|
||||
ath12k_err(ab,
|
||||
"failed to setup filter for mon rx buf %d\n",
|
||||
ret);
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (i = 0; i < ab->hw_params->num_rxdma_per_pdev; i++) {
|
||||
ring_id = ab->dp.rx_mon_status_refill_ring[i].refill_buf_ring.ring_id;
|
||||
if (!reset) {
|
||||
tlv_filter.rx_filter =
|
||||
HTT_RX_MON_FILTER_TLV_FLAGS_MON_STATUS_RING;
|
||||
}
|
||||
|
||||
ret = ath12k_dp_tx_htt_rx_filter_setup(ab, ring_id,
|
||||
i,
|
||||
HAL_RXDMA_MONITOR_STATUS,
|
||||
RX_MON_STATUS_BUF_SIZE,
|
||||
&tlv_filter);
|
||||
if (ret) {
|
||||
ath12k_err(ab,
|
||||
"failed to setup filter for mon status buf %d\n",
|
||||
ret);
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
||||
@ -154,7 +154,14 @@ static const struct hal_srng_config hw_srng_config_template[] = {
|
||||
.ring_dir = HAL_SRNG_DIR_SRC,
|
||||
.max_size = HAL_RXDMA_RING_MAX_SIZE_BE,
|
||||
},
|
||||
[HAL_RXDMA_MONITOR_STATUS] = { 0, },
|
||||
[HAL_RXDMA_MONITOR_STATUS] = {
|
||||
.start_ring_id = HAL_SRNG_RING_ID_WMAC1_SW2RXDMA1_STATBUF,
|
||||
.max_rings = 1,
|
||||
.entry_size = sizeof(struct hal_wbm_buffer_ring) >> 2,
|
||||
.mac_type = ATH12K_HAL_SRNG_PMAC,
|
||||
.ring_dir = HAL_SRNG_DIR_SRC,
|
||||
.max_size = HAL_RXDMA_RING_MAX_SIZE_BE,
|
||||
},
|
||||
[HAL_RXDMA_MONITOR_DESC] = { 0, },
|
||||
[HAL_RXDMA_DIR_BUF] = {
|
||||
.start_ring_id = HAL_SRNG_RING_ID_RXDMA_DIR_BUF,
|
||||
@ -1943,7 +1950,7 @@ u32 ath12k_hal_ce_dst_status_get_length(struct hal_ce_srng_dst_status_desc *desc
|
||||
{
|
||||
u32 len;
|
||||
|
||||
len = le32_get_bits(desc->flags, HAL_CE_DST_STATUS_DESC_FLAGS_LEN);
|
||||
len = le32_get_bits(READ_ONCE(desc->flags), HAL_CE_DST_STATUS_DESC_FLAGS_LEN);
|
||||
desc->flags &= ~cpu_to_le32(HAL_CE_DST_STATUS_DESC_FLAGS_LEN);
|
||||
|
||||
return len;
|
||||
@ -2035,6 +2042,24 @@ int ath12k_hal_srng_src_num_free(struct ath12k_base *ab, struct hal_srng *srng,
|
||||
return ((srng->ring_size - hp + tp) / srng->entry_size) - 1;
|
||||
}
|
||||
|
||||
void *ath12k_hal_srng_src_next_peek(struct ath12k_base *ab,
|
||||
struct hal_srng *srng)
|
||||
{
|
||||
void *desc;
|
||||
u32 next_hp;
|
||||
|
||||
lockdep_assert_held(&srng->lock);
|
||||
|
||||
next_hp = (srng->u.src_ring.hp + srng->entry_size) % srng->ring_size;
|
||||
|
||||
if (next_hp == srng->u.src_ring.cached_tp)
|
||||
return NULL;
|
||||
|
||||
desc = srng->ring_base_vaddr + next_hp;
|
||||
|
||||
return desc;
|
||||
}
|
||||
|
||||
void *ath12k_hal_srng_src_get_next_entry(struct ath12k_base *ab,
|
||||
struct hal_srng *srng)
|
||||
{
|
||||
@ -2068,6 +2093,17 @@ void *ath12k_hal_srng_src_get_next_entry(struct ath12k_base *ab,
|
||||
return desc;
|
||||
}
|
||||
|
||||
void *ath12k_hal_srng_src_peek(struct ath12k_base *ab, struct hal_srng *srng)
|
||||
{
|
||||
lockdep_assert_held(&srng->lock);
|
||||
|
||||
if (((srng->u.src_ring.hp + srng->entry_size) % srng->ring_size) ==
|
||||
srng->u.src_ring.cached_tp)
|
||||
return NULL;
|
||||
|
||||
return srng->ring_base_vaddr + srng->u.src_ring.hp;
|
||||
}
|
||||
|
||||
void *ath12k_hal_srng_src_reap_next(struct ath12k_base *ab,
|
||||
struct hal_srng *srng)
|
||||
{
|
||||
@ -2113,7 +2149,7 @@ void ath12k_hal_srng_access_begin(struct ath12k_base *ab, struct hal_srng *srng)
|
||||
srng->u.src_ring.cached_tp =
|
||||
*(volatile u32 *)srng->u.src_ring.tp_addr;
|
||||
else
|
||||
srng->u.dst_ring.cached_hp = *srng->u.dst_ring.hp_addr;
|
||||
srng->u.dst_ring.cached_hp = READ_ONCE(*srng->u.dst_ring.hp_addr);
|
||||
}
|
||||
|
||||
/* Update cached ring head/tail pointers to HW. ath12k_hal_srng_access_begin()
|
||||
|
||||
@ -498,6 +498,7 @@ enum hal_srng_ring_id {
|
||||
|
||||
HAL_SRNG_RING_ID_WMAC1_SW2RXMON_BUF0 = HAL_SRNG_RING_ID_PMAC1_ID_START,
|
||||
|
||||
HAL_SRNG_RING_ID_WMAC1_SW2RXDMA1_STATBUF,
|
||||
HAL_SRNG_RING_ID_WMAC1_RXDMA2SW0,
|
||||
HAL_SRNG_RING_ID_WMAC1_RXDMA2SW1,
|
||||
HAL_SRNG_RING_ID_WMAC1_RXMON2SW0 = HAL_SRNG_RING_ID_WMAC1_RXDMA2SW1,
|
||||
@ -1143,6 +1144,7 @@ void ath12k_hal_srng_get_params(struct ath12k_base *ab, struct hal_srng *srng,
|
||||
struct hal_srng_params *params);
|
||||
void *ath12k_hal_srng_dst_get_next_entry(struct ath12k_base *ab,
|
||||
struct hal_srng *srng);
|
||||
void *ath12k_hal_srng_src_peek(struct ath12k_base *ab, struct hal_srng *srng);
|
||||
void *ath12k_hal_srng_dst_peek(struct ath12k_base *ab, struct hal_srng *srng);
|
||||
int ath12k_hal_srng_dst_num_free(struct ath12k_base *ab, struct hal_srng *srng,
|
||||
bool sync_hw_ptr);
|
||||
@ -1150,6 +1152,8 @@ void *ath12k_hal_srng_src_get_next_reaped(struct ath12k_base *ab,
|
||||
struct hal_srng *srng);
|
||||
void *ath12k_hal_srng_src_reap_next(struct ath12k_base *ab,
|
||||
struct hal_srng *srng);
|
||||
void *ath12k_hal_srng_src_next_peek(struct ath12k_base *ab,
|
||||
struct hal_srng *srng);
|
||||
void *ath12k_hal_srng_src_get_next_entry(struct ath12k_base *ab,
|
||||
struct hal_srng *srng);
|
||||
int ath12k_hal_srng_src_num_free(struct ath12k_base *ab, struct hal_srng *srng,
|
||||
|
||||
@ -707,7 +707,7 @@ enum hal_rx_msdu_desc_reo_dest_ind {
|
||||
#define RX_MSDU_DESC_INFO0_DECAP_FORMAT GENMASK(30, 29)
|
||||
|
||||
#define HAL_RX_MSDU_PKT_LENGTH_GET(val) \
|
||||
(u32_get_bits((val), RX_MSDU_DESC_INFO0_MSDU_LENGTH))
|
||||
(le32_get_bits((val), RX_MSDU_DESC_INFO0_MSDU_LENGTH))
|
||||
|
||||
struct rx_msdu_desc {
|
||||
__le32 info0;
|
||||
@ -1008,6 +1008,10 @@ enum hal_reo_entr_rxdma_ecode {
|
||||
HAL_REO_ENTR_RING_RXDMA_ECODE_FLOW_TIMEOUT_ERR,
|
||||
HAL_REO_ENTR_RING_RXDMA_ECODE_FLUSH_REQUEST_ERR,
|
||||
HAL_REO_ENTR_RING_RXDMA_ECODE_AMSDU_FRAG_ERR,
|
||||
HAL_REO_ENTR_RING_RXDMA_ECODE_MULTICAST_ECHO_ERR,
|
||||
HAL_REO_ENTR_RING_RXDMA_ECODE_AMSDU_MISMATCH_ERR,
|
||||
HAL_REO_ENTR_RING_RXDMA_ECODE_UNAUTH_WDS_ERR,
|
||||
HAL_REO_ENTR_RING_RXDMA_ECODE_GRPCAST_AMSDU_WDS_ERR,
|
||||
HAL_REO_ENTR_RING_RXDMA_ECODE_MAX,
|
||||
};
|
||||
|
||||
@ -1809,6 +1813,7 @@ enum hal_wbm_rel_src_module {
|
||||
HAL_WBM_REL_SRC_MODULE_REO,
|
||||
HAL_WBM_REL_SRC_MODULE_FW,
|
||||
HAL_WBM_REL_SRC_MODULE_SW,
|
||||
HAL_WBM_REL_SRC_MODULE_MAX,
|
||||
};
|
||||
|
||||
enum hal_wbm_rel_desc_type {
|
||||
|
||||
@ -326,7 +326,7 @@ int ath12k_hal_desc_reo_parse_err(struct ath12k_base *ab,
|
||||
HAL_REO_DEST_RING_INFO0_PUSH_REASON);
|
||||
err_code = le32_get_bits(desc->info0,
|
||||
HAL_REO_DEST_RING_INFO0_ERROR_CODE);
|
||||
ab->soc_stats.reo_error[err_code]++;
|
||||
ab->device_stats.reo_error[err_code]++;
|
||||
|
||||
if (push_reason != HAL_REO_DEST_RING_PUSH_REASON_ERR_DETECTED &&
|
||||
push_reason != HAL_REO_DEST_RING_PUSH_REASON_ROUTING_INSTRUCTION) {
|
||||
@ -381,7 +381,7 @@ int ath12k_hal_wbm_desc_parse_err(struct ath12k_base *ab, void *desc,
|
||||
val = le32_get_bits(wbm_desc->buf_addr_info.info1,
|
||||
BUFFER_ADDR_INFO1_RET_BUF_MGR);
|
||||
if (val != HAL_RX_BUF_RBM_SW3_BM) {
|
||||
ab->soc_stats.invalid_rbm++;
|
||||
ab->device_stats.invalid_rbm++;
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
@ -393,7 +393,7 @@ int ath12k_hal_wbm_desc_parse_err(struct ath12k_base *ab, void *desc,
|
||||
val = le32_get_bits(wbm_cc_desc->info0,
|
||||
HAL_WBM_RELEASE_RX_CC_INFO0_RBM);
|
||||
if (val != HAL_RX_BUF_RBM_SW3_BM) {
|
||||
ab->soc_stats.invalid_rbm++;
|
||||
ab->device_stats.invalid_rbm++;
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
@ -446,17 +446,97 @@ void ath12k_hal_rx_reo_ent_paddr_get(struct ath12k_base *ab,
|
||||
*cookie = le32_get_bits(buff_addr->info1, BUFFER_ADDR_INFO1_SW_COOKIE);
|
||||
}
|
||||
|
||||
void ath12k_hal_rx_reo_ent_buf_paddr_get(void *rx_desc, dma_addr_t *paddr,
|
||||
u32 *sw_cookie,
|
||||
struct ath12k_buffer_addr **pp_buf_addr,
|
||||
u8 *rbm, u32 *msdu_cnt)
|
||||
{
|
||||
struct hal_reo_entrance_ring *reo_ent_ring =
|
||||
(struct hal_reo_entrance_ring *)rx_desc;
|
||||
struct ath12k_buffer_addr *buf_addr_info;
|
||||
struct rx_mpdu_desc *rx_mpdu_desc_info_details;
|
||||
|
||||
rx_mpdu_desc_info_details =
|
||||
(struct rx_mpdu_desc *)&reo_ent_ring->rx_mpdu_info;
|
||||
|
||||
*msdu_cnt = le32_get_bits(rx_mpdu_desc_info_details->info0,
|
||||
RX_MPDU_DESC_INFO0_MSDU_COUNT);
|
||||
|
||||
buf_addr_info = (struct ath12k_buffer_addr *)&reo_ent_ring->buf_addr_info;
|
||||
|
||||
*paddr = (((u64)le32_get_bits(buf_addr_info->info1,
|
||||
BUFFER_ADDR_INFO1_ADDR)) << 32) |
|
||||
le32_get_bits(buf_addr_info->info0,
|
||||
BUFFER_ADDR_INFO0_ADDR);
|
||||
|
||||
*sw_cookie = le32_get_bits(buf_addr_info->info1,
|
||||
BUFFER_ADDR_INFO1_SW_COOKIE);
|
||||
*rbm = le32_get_bits(buf_addr_info->info1,
|
||||
BUFFER_ADDR_INFO1_RET_BUF_MGR);
|
||||
|
||||
*pp_buf_addr = (void *)buf_addr_info;
|
||||
}
|
||||
|
||||
void ath12k_hal_rx_msdu_list_get(struct ath12k *ar,
|
||||
struct hal_rx_msdu_link *link_desc,
|
||||
struct hal_rx_msdu_list *msdu_list,
|
||||
u16 *num_msdus)
|
||||
{
|
||||
struct hal_rx_msdu_details *msdu_details = NULL;
|
||||
struct rx_msdu_desc *msdu_desc_info = NULL;
|
||||
u32 last = 0, first = 0;
|
||||
u8 tmp = 0;
|
||||
int i;
|
||||
|
||||
last = u32_encode_bits(last, RX_MSDU_DESC_INFO0_LAST_MSDU_IN_MPDU);
|
||||
first = u32_encode_bits(first, RX_MSDU_DESC_INFO0_FIRST_MSDU_IN_MPDU);
|
||||
msdu_details = &link_desc->msdu_link[0];
|
||||
|
||||
for (i = 0; i < HAL_RX_NUM_MSDU_DESC; i++) {
|
||||
if (!i && le32_get_bits(msdu_details[i].buf_addr_info.info0,
|
||||
BUFFER_ADDR_INFO0_ADDR) == 0)
|
||||
break;
|
||||
if (le32_get_bits(msdu_details[i].buf_addr_info.info0,
|
||||
BUFFER_ADDR_INFO0_ADDR) == 0) {
|
||||
msdu_desc_info = &msdu_details[i - 1].rx_msdu_info;
|
||||
msdu_desc_info->info0 |= cpu_to_le32(last);
|
||||
break;
|
||||
}
|
||||
msdu_desc_info = &msdu_details[i].rx_msdu_info;
|
||||
|
||||
if (!i)
|
||||
msdu_desc_info->info0 |= cpu_to_le32(first);
|
||||
else if (i == (HAL_RX_NUM_MSDU_DESC - 1))
|
||||
msdu_desc_info->info0 |= cpu_to_le32(last);
|
||||
msdu_list->msdu_info[i].msdu_flags = le32_to_cpu(msdu_desc_info->info0);
|
||||
msdu_list->msdu_info[i].msdu_len =
|
||||
HAL_RX_MSDU_PKT_LENGTH_GET(msdu_desc_info->info0);
|
||||
msdu_list->sw_cookie[i] =
|
||||
le32_get_bits(msdu_details[i].buf_addr_info.info1,
|
||||
BUFFER_ADDR_INFO1_SW_COOKIE);
|
||||
tmp = le32_get_bits(msdu_details[i].buf_addr_info.info1,
|
||||
BUFFER_ADDR_INFO1_RET_BUF_MGR);
|
||||
msdu_list->paddr[i] =
|
||||
((u64)(le32_get_bits(msdu_details[i].buf_addr_info.info1,
|
||||
BUFFER_ADDR_INFO1_ADDR)) << 32) |
|
||||
le32_get_bits(msdu_details[i].buf_addr_info.info0,
|
||||
BUFFER_ADDR_INFO0_ADDR);
|
||||
msdu_list->rbm[i] = tmp;
|
||||
}
|
||||
*num_msdus = i;
|
||||
}
|
||||
|
||||
void ath12k_hal_rx_msdu_link_desc_set(struct ath12k_base *ab,
|
||||
struct hal_wbm_release_ring *dst_desc,
|
||||
struct hal_wbm_release_ring *src_desc,
|
||||
struct hal_wbm_release_ring *desc,
|
||||
struct ath12k_buffer_addr *buf_addr_info,
|
||||
enum hal_wbm_rel_bm_act action)
|
||||
{
|
||||
dst_desc->buf_addr_info = src_desc->buf_addr_info;
|
||||
dst_desc->info0 |= le32_encode_bits(HAL_WBM_REL_SRC_MODULE_SW,
|
||||
HAL_WBM_RELEASE_INFO0_REL_SRC_MODULE) |
|
||||
le32_encode_bits(action, HAL_WBM_RELEASE_INFO0_BM_ACTION) |
|
||||
le32_encode_bits(HAL_WBM_REL_DESC_TYPE_MSDU_LINK,
|
||||
HAL_WBM_RELEASE_INFO0_DESC_TYPE);
|
||||
desc->buf_addr_info = *buf_addr_info;
|
||||
desc->info0 |= le32_encode_bits(HAL_WBM_REL_SRC_MODULE_SW,
|
||||
HAL_WBM_RELEASE_INFO0_REL_SRC_MODULE) |
|
||||
le32_encode_bits(action, HAL_WBM_RELEASE_INFO0_BM_ACTION) |
|
||||
le32_encode_bits(HAL_WBM_REL_DESC_TYPE_MSDU_LINK,
|
||||
HAL_WBM_RELEASE_INFO0_DESC_TYPE);
|
||||
}
|
||||
|
||||
void ath12k_hal_reo_status_queue_stats(struct ath12k_base *ab, struct hal_tlv_64_hdr *tlv,
|
||||
|
||||
@ -538,6 +538,7 @@ struct hal_rx_msdu_desc_info {
|
||||
#define HAL_RX_NUM_MSDU_DESC 6
|
||||
struct hal_rx_msdu_list {
|
||||
struct hal_rx_msdu_desc_info msdu_info[HAL_RX_NUM_MSDU_DESC];
|
||||
u64 paddr[HAL_RX_NUM_MSDU_DESC];
|
||||
u32 sw_cookie[HAL_RX_NUM_MSDU_DESC];
|
||||
u8 rbm[HAL_RX_NUM_MSDU_DESC];
|
||||
};
|
||||
@ -1141,8 +1142,8 @@ void ath12k_hal_rx_msdu_link_info_get(struct hal_rx_msdu_link *link, u32 *num_ms
|
||||
u32 *msdu_cookies,
|
||||
enum hal_rx_buf_return_buf_manager *rbm);
|
||||
void ath12k_hal_rx_msdu_link_desc_set(struct ath12k_base *ab,
|
||||
struct hal_wbm_release_ring *dst_desc,
|
||||
struct hal_wbm_release_ring *src_desc,
|
||||
struct hal_wbm_release_ring *desc,
|
||||
struct ath12k_buffer_addr *buf_addr_info,
|
||||
enum hal_wbm_rel_bm_act action);
|
||||
void ath12k_hal_rx_buf_addr_info_set(struct ath12k_buffer_addr *binfo,
|
||||
dma_addr_t paddr, u32 cookie, u8 manager);
|
||||
@ -1157,5 +1158,12 @@ int ath12k_hal_wbm_desc_parse_err(struct ath12k_base *ab, void *desc,
|
||||
void ath12k_hal_rx_reo_ent_paddr_get(struct ath12k_base *ab,
|
||||
struct ath12k_buffer_addr *buff_addr,
|
||||
dma_addr_t *paddr, u32 *cookie);
|
||||
void ath12k_hal_rx_reo_ent_buf_paddr_get(void *rx_desc, dma_addr_t *paddr, u32 *sw_cookie,
|
||||
struct ath12k_buffer_addr **pp_buf_addr,
|
||||
u8 *rbm, u32 *msdu_cnt);
|
||||
void ath12k_hal_rx_msdu_list_get(struct ath12k *ar,
|
||||
struct hal_rx_msdu_link *link_desc,
|
||||
struct hal_rx_msdu_list *msdu_list,
|
||||
u16 *num_msdus);
|
||||
|
||||
#endif
|
||||
|
||||
@ -118,6 +118,10 @@ static const struct ath12k_hw_ops wcn7850_ops = {
|
||||
#define ATH12K_TX_MON_RING_MASK_0 0x1
|
||||
#define ATH12K_TX_MON_RING_MASK_1 0x2
|
||||
|
||||
#define ATH12K_RX_MON_STATUS_RING_MASK_0 0x1
|
||||
#define ATH12K_RX_MON_STATUS_RING_MASK_1 0x2
|
||||
#define ATH12K_RX_MON_STATUS_RING_MASK_2 0x4
|
||||
|
||||
/* Target firmware's Copy Engine configuration. */
|
||||
static const struct ce_pipe_config ath12k_target_ce_config_wlan_qcn9274[] = {
|
||||
/* CE0: host->target HTC control and raw streams */
|
||||
@ -836,6 +840,12 @@ static const struct ath12k_hw_ring_mask ath12k_hw_ring_mask_wcn7850 = {
|
||||
},
|
||||
.rx_mon_dest = {
|
||||
},
|
||||
.rx_mon_status = {
|
||||
0, 0, 0, 0,
|
||||
ATH12K_RX_MON_STATUS_RING_MASK_0,
|
||||
ATH12K_RX_MON_STATUS_RING_MASK_1,
|
||||
ATH12K_RX_MON_STATUS_RING_MASK_2,
|
||||
},
|
||||
.rx = {
|
||||
0, 0, 0,
|
||||
ATH12K_RX_RING_MASK_0,
|
||||
@ -1370,7 +1380,7 @@ static const struct ath12k_hw_params ath12k_hw_params[] = {
|
||||
BIT(NL80211_IFTYPE_P2P_DEVICE) |
|
||||
BIT(NL80211_IFTYPE_P2P_CLIENT) |
|
||||
BIT(NL80211_IFTYPE_P2P_GO),
|
||||
.supports_monitor = false,
|
||||
.supports_monitor = true,
|
||||
|
||||
.idle_ps = true,
|
||||
.download_calib = false,
|
||||
|
||||
@ -135,6 +135,7 @@ enum hal_encrypt_type;
|
||||
struct ath12k_hw_ring_mask {
|
||||
u8 tx[ATH12K_EXT_IRQ_GRP_NUM_MAX];
|
||||
u8 rx_mon_dest[ATH12K_EXT_IRQ_GRP_NUM_MAX];
|
||||
u8 rx_mon_status[ATH12K_EXT_IRQ_GRP_NUM_MAX];
|
||||
u8 rx[ATH12K_EXT_IRQ_GRP_NUM_MAX];
|
||||
u8 rx_err[ATH12K_EXT_IRQ_GRP_NUM_MAX];
|
||||
u8 rx_wbm_rel[ATH12K_EXT_IRQ_GRP_NUM_MAX];
|
||||
|
||||
@ -229,7 +229,8 @@ ath12k_phymodes[NUM_NL80211_BANDS][ATH12K_CHAN_WIDTH_NUM] = {
|
||||
const struct htt_rx_ring_tlv_filter ath12k_mac_mon_status_filter_default = {
|
||||
.rx_filter = HTT_RX_FILTER_TLV_FLAGS_MPDU_START |
|
||||
HTT_RX_FILTER_TLV_FLAGS_PPDU_END |
|
||||
HTT_RX_FILTER_TLV_FLAGS_PPDU_END_STATUS_DONE,
|
||||
HTT_RX_FILTER_TLV_FLAGS_PPDU_END_STATUS_DONE |
|
||||
HTT_RX_FILTER_TLV_FLAGS_PPDU_START_USER_INFO,
|
||||
.pkt_filter_flags0 = HTT_RX_FP_MGMT_FILTER_FLAGS0,
|
||||
.pkt_filter_flags1 = HTT_RX_FP_MGMT_FILTER_FLAGS1,
|
||||
.pkt_filter_flags2 = HTT_RX_FP_CTRL_FILTER_FLASG2,
|
||||
@ -580,22 +581,16 @@ static int ath12k_mac_vif_link_chan(struct ieee80211_vif *vif, u8 link_id,
|
||||
return 0;
|
||||
}
|
||||
|
||||
static struct ath12k_link_vif *ath12k_mac_get_tx_arvif(struct ath12k_link_vif *arvif)
|
||||
static struct ath12k_link_vif *
|
||||
ath12k_mac_get_tx_arvif(struct ath12k_link_vif *arvif,
|
||||
struct ieee80211_bss_conf *link_conf)
|
||||
{
|
||||
struct ieee80211_bss_conf *link_conf, *tx_bss_conf;
|
||||
struct ieee80211_bss_conf *tx_bss_conf;
|
||||
struct ath12k *ar = arvif->ar;
|
||||
struct ath12k_vif *tx_ahvif;
|
||||
|
||||
lockdep_assert_wiphy(ath12k_ar_to_hw(ar)->wiphy);
|
||||
|
||||
link_conf = ath12k_mac_get_link_bss_conf(arvif);
|
||||
if (!link_conf) {
|
||||
ath12k_warn(ar->ab,
|
||||
"unable to access bss link conf for link %u required to retrieve transmitting link conf\n",
|
||||
arvif->link_id);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
tx_bss_conf = wiphy_dereference(ath12k_ar_to_hw(ar)->wiphy,
|
||||
link_conf->tx_bss_conf);
|
||||
if (tx_bss_conf) {
|
||||
@ -1623,7 +1618,7 @@ static int ath12k_mac_setup_bcn_tmpl(struct ath12k_link_vif *arvif)
|
||||
return -ENOLINK;
|
||||
}
|
||||
|
||||
tx_arvif = ath12k_mac_get_tx_arvif(arvif);
|
||||
tx_arvif = ath12k_mac_get_tx_arvif(arvif, link_conf);
|
||||
if (tx_arvif) {
|
||||
if (tx_arvif != arvif && arvif->is_up)
|
||||
return 0;
|
||||
@ -1693,6 +1688,7 @@ static void ath12k_control_beaconing(struct ath12k_link_vif *arvif,
|
||||
{
|
||||
struct ath12k_wmi_vdev_up_params params = {};
|
||||
struct ath12k_vif *ahvif = arvif->ahvif;
|
||||
struct ieee80211_bss_conf *link_conf;
|
||||
struct ath12k_link_vif *tx_arvif;
|
||||
struct ath12k *ar = arvif->ar;
|
||||
int ret;
|
||||
@ -1725,7 +1721,15 @@ static void ath12k_control_beaconing(struct ath12k_link_vif *arvif,
|
||||
params.aid = ahvif->aid;
|
||||
params.bssid = arvif->bssid;
|
||||
|
||||
tx_arvif = ath12k_mac_get_tx_arvif(arvif);
|
||||
link_conf = ath12k_mac_get_link_bss_conf(arvif);
|
||||
if (!link_conf) {
|
||||
ath12k_warn(ar->ab,
|
||||
"unable to access bss link conf for link %u required to retrieve transmitting link conf\n",
|
||||
arvif->link_id);
|
||||
return;
|
||||
}
|
||||
|
||||
tx_arvif = ath12k_mac_get_tx_arvif(arvif, link_conf);
|
||||
if (tx_arvif) {
|
||||
params.tx_bssid = tx_arvif->bssid;
|
||||
params.nontx_profile_idx = info->bssid_index;
|
||||
@ -2935,6 +2939,7 @@ static void ath12k_peer_assoc_h_eht(struct ath12k *ar,
|
||||
const struct ieee80211_sta_eht_cap *eht_cap;
|
||||
const struct ieee80211_sta_he_cap *he_cap;
|
||||
struct ieee80211_link_sta *link_sta;
|
||||
struct ieee80211_bss_conf *link_conf;
|
||||
u32 *rx_mcs, *tx_mcs;
|
||||
|
||||
lockdep_assert_wiphy(ath12k_ar_to_hw(ar)->wiphy);
|
||||
@ -2946,6 +2951,12 @@ static void ath12k_peer_assoc_h_eht(struct ath12k *ar,
|
||||
return;
|
||||
}
|
||||
|
||||
link_conf = ath12k_mac_get_link_bss_conf(arvif);
|
||||
if (!link_conf) {
|
||||
ath12k_warn(ar->ab, "unable to access link_conf in peer assoc eht set\n");
|
||||
return;
|
||||
}
|
||||
|
||||
eht_cap = &link_sta->eht_cap;
|
||||
he_cap = &link_sta->he_cap;
|
||||
if (!he_cap->has_he || !eht_cap->has_eht)
|
||||
@ -3017,6 +3028,7 @@ static void ath12k_peer_assoc_h_eht(struct ath12k *ar,
|
||||
}
|
||||
|
||||
arg->punct_bitmap = ~arvif->punct_bitmap;
|
||||
arg->eht_disable_mcs15 = link_conf->eht_disable_mcs15;
|
||||
}
|
||||
|
||||
static void ath12k_peer_assoc_h_mlo(struct ath12k_link_sta *arsta,
|
||||
@ -3047,6 +3059,7 @@ static void ath12k_peer_assoc_h_mlo(struct ath12k_link_sta *arsta,
|
||||
ml->ml_peer_id = ahsta->ml_peer_id;
|
||||
ml->ieee_link_id = arsta->link_id;
|
||||
ml->num_partner_links = 0;
|
||||
ml->eml_cap = sta->eml_cap;
|
||||
links = ahsta->links_map;
|
||||
|
||||
rcu_read_lock();
|
||||
@ -3480,25 +3493,18 @@ static struct ath12k_link_vif *ath12k_mac_assign_link_vif(struct ath12k_hw *ah,
|
||||
if (arvif)
|
||||
return arvif;
|
||||
|
||||
if (!vif->valid_links) {
|
||||
/* Use deflink for Non-ML VIFs and mark the link id as 0
|
||||
*/
|
||||
link_id = 0;
|
||||
/* If this is the first link arvif being created for an ML VIF
|
||||
* use the preallocated deflink memory except for scan arvifs
|
||||
*/
|
||||
if (!ahvif->links_map && link_id != ATH12K_DEFAULT_SCAN_LINK) {
|
||||
arvif = &ahvif->deflink;
|
||||
|
||||
if (vif->type == NL80211_IFTYPE_STATION)
|
||||
arvif->is_sta_assoc_link = true;
|
||||
} else {
|
||||
/* If this is the first link arvif being created for an ML VIF
|
||||
* use the preallocated deflink memory except for scan arvifs
|
||||
*/
|
||||
if (!ahvif->links_map && link_id != ATH12K_DEFAULT_SCAN_LINK) {
|
||||
arvif = &ahvif->deflink;
|
||||
if (vif->type == NL80211_IFTYPE_STATION)
|
||||
arvif->is_sta_assoc_link = true;
|
||||
} else {
|
||||
arvif = (struct ath12k_link_vif *)
|
||||
kzalloc(sizeof(struct ath12k_link_vif), GFP_KERNEL);
|
||||
if (!arvif)
|
||||
return NULL;
|
||||
}
|
||||
arvif = kzalloc(sizeof(*arvif), GFP_KERNEL);
|
||||
if (!arvif)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
ath12k_mac_init_arvif(ahvif, arvif, link_id);
|
||||
@ -3746,6 +3752,18 @@ static void ath12k_mac_vif_setup_ps(struct ath12k_link_vif *arvif)
|
||||
psmode, arvif->vdev_id, ret);
|
||||
}
|
||||
|
||||
static bool ath12k_mac_supports_station_tpc(struct ath12k *ar,
|
||||
struct ath12k_vif *ahvif,
|
||||
const struct cfg80211_chan_def *chandef)
|
||||
{
|
||||
return ath12k_wmi_supports_6ghz_cc_ext(ar) &&
|
||||
test_bit(WMI_TLV_SERVICE_EXT_TPC_REG_SUPPORT, ar->ab->wmi_ab.svc_map) &&
|
||||
ahvif->vdev_type == WMI_VDEV_TYPE_STA &&
|
||||
ahvif->vdev_subtype == WMI_VDEV_SUBTYPE_NONE &&
|
||||
chandef->chan &&
|
||||
chandef->chan->band == NL80211_BAND_6GHZ;
|
||||
}
|
||||
|
||||
static void ath12k_mac_bss_info_changed(struct ath12k *ar,
|
||||
struct ath12k_link_vif *arvif,
|
||||
struct ieee80211_bss_conf *info,
|
||||
@ -4647,6 +4665,7 @@ static int ath12k_mac_op_hw_scan(struct ieee80211_hw *hw,
|
||||
spin_lock_bh(&ar->data_lock);
|
||||
ar->scan.state = ATH12K_SCAN_IDLE;
|
||||
spin_unlock_bh(&ar->data_lock);
|
||||
goto exit;
|
||||
}
|
||||
|
||||
ath12k_dbg(ar->ab, ATH12K_DBG_MAC, "mac scan started");
|
||||
@ -5779,12 +5798,15 @@ static int ath12k_mac_handle_link_sta_state(struct ieee80211_hw *hw,
|
||||
enum ieee80211_sta_state new_state)
|
||||
{
|
||||
struct ieee80211_vif *vif = ath12k_ahvif_to_vif(arvif->ahvif);
|
||||
struct ieee80211_bss_conf *link_conf;
|
||||
struct ath12k *ar = arvif->ar;
|
||||
struct ath12k_reg_info *reg_info;
|
||||
struct ath12k_base *ab = ar->ab;
|
||||
int ret = 0;
|
||||
|
||||
lockdep_assert_wiphy(hw->wiphy);
|
||||
|
||||
ath12k_dbg(ar->ab, ATH12K_DBG_MAC, "mac handle link %u sta %pM state %d -> %d\n",
|
||||
ath12k_dbg(ab, ATH12K_DBG_MAC, "mac handle link %u sta %pM state %d -> %d\n",
|
||||
arsta->link_id, arsta->addr, old_state, new_state);
|
||||
|
||||
/* IEEE80211_STA_NONE -> IEEE80211_STA_NOTEXIST: Remove the station
|
||||
@ -5794,7 +5816,7 @@ static int ath12k_mac_handle_link_sta_state(struct ieee80211_hw *hw,
|
||||
new_state == IEEE80211_STA_NOTEXIST)) {
|
||||
ret = ath12k_mac_station_remove(ar, arvif, arsta);
|
||||
if (ret) {
|
||||
ath12k_warn(ar->ab, "Failed to remove station: %pM for VDEV: %d\n",
|
||||
ath12k_warn(ab, "Failed to remove station: %pM for VDEV: %d\n",
|
||||
arsta->addr, arvif->vdev_id);
|
||||
goto exit;
|
||||
}
|
||||
@ -5805,7 +5827,7 @@ static int ath12k_mac_handle_link_sta_state(struct ieee80211_hw *hw,
|
||||
new_state == IEEE80211_STA_NONE) {
|
||||
ret = ath12k_mac_station_add(ar, arvif, arsta);
|
||||
if (ret)
|
||||
ath12k_warn(ar->ab, "Failed to add station: %pM for VDEV: %d\n",
|
||||
ath12k_warn(ab, "Failed to add station: %pM for VDEV: %d\n",
|
||||
arsta->addr, arvif->vdev_id);
|
||||
|
||||
/* IEEE80211_STA_AUTH -> IEEE80211_STA_ASSOC: Send station assoc command for
|
||||
@ -5818,7 +5840,7 @@ static int ath12k_mac_handle_link_sta_state(struct ieee80211_hw *hw,
|
||||
vif->type == NL80211_IFTYPE_ADHOC)) {
|
||||
ret = ath12k_mac_station_assoc(ar, arvif, arsta, false);
|
||||
if (ret)
|
||||
ath12k_warn(ar->ab, "Failed to associate station: %pM\n",
|
||||
ath12k_warn(ab, "Failed to associate station: %pM\n",
|
||||
arsta->addr);
|
||||
|
||||
/* IEEE80211_STA_ASSOC -> IEEE80211_STA_AUTHORIZED: set peer status as
|
||||
@ -5827,9 +5849,21 @@ static int ath12k_mac_handle_link_sta_state(struct ieee80211_hw *hw,
|
||||
} else if (old_state == IEEE80211_STA_ASSOC &&
|
||||
new_state == IEEE80211_STA_AUTHORIZED) {
|
||||
ret = ath12k_mac_station_authorize(ar, arvif, arsta);
|
||||
if (ret)
|
||||
ath12k_warn(ar->ab, "Failed to authorize station: %pM\n",
|
||||
if (ret) {
|
||||
ath12k_warn(ab, "Failed to authorize station: %pM\n",
|
||||
arsta->addr);
|
||||
goto exit;
|
||||
}
|
||||
|
||||
if (ath12k_wmi_supports_6ghz_cc_ext(ar) &&
|
||||
arvif->ahvif->vdev_type == WMI_VDEV_TYPE_STA) {
|
||||
link_conf = ath12k_mac_get_link_bss_conf(arvif);
|
||||
reg_info = ab->reg_info[ar->pdev_idx];
|
||||
ath12k_dbg(ab, ATH12K_DBG_MAC, "connection done, update reg rules\n");
|
||||
ath12k_hw_to_ah(hw)->regd_updated = false;
|
||||
ath12k_reg_handle_chan_list(ab, reg_info, arvif->ahvif->vdev_type,
|
||||
link_conf->power_type);
|
||||
}
|
||||
|
||||
/* IEEE80211_STA_AUTHORIZED -> IEEE80211_STA_ASSOC: station may be in removal,
|
||||
* deauthorize it.
|
||||
@ -5848,7 +5882,7 @@ static int ath12k_mac_handle_link_sta_state(struct ieee80211_hw *hw,
|
||||
vif->type == NL80211_IFTYPE_ADHOC)) {
|
||||
ret = ath12k_mac_station_disassoc(ar, arvif, arsta);
|
||||
if (ret)
|
||||
ath12k_warn(ar->ab, "Failed to disassociate station: %pM\n",
|
||||
ath12k_warn(ab, "Failed to disassociate station: %pM\n",
|
||||
arsta->addr);
|
||||
}
|
||||
|
||||
@ -7466,6 +7500,7 @@ static void ath12k_mac_op_tx(struct ieee80211_hw *hw,
|
||||
struct ath12k_peer *peer;
|
||||
unsigned long links_map;
|
||||
bool is_mcast = false;
|
||||
bool is_dvlan = false;
|
||||
struct ethhdr *eth;
|
||||
bool is_prb_rsp;
|
||||
u16 mcbc_gsn;
|
||||
@ -7531,7 +7566,14 @@ static void ath12k_mac_op_tx(struct ieee80211_hw *hw,
|
||||
if (vif->type == NL80211_IFTYPE_AP && vif->p2p)
|
||||
ath12k_mac_add_p2p_noa_ie(ar, vif, skb, is_prb_rsp);
|
||||
|
||||
if (!vif->valid_links || !is_mcast ||
|
||||
/* Checking if it is a DVLAN frame */
|
||||
if (!test_bit(ATH12K_FLAG_HW_CRYPTO_DISABLED, &ar->ab->dev_flags) &&
|
||||
!(skb_cb->flags & ATH12K_SKB_HW_80211_ENCAP) &&
|
||||
!(skb_cb->flags & ATH12K_SKB_CIPHER_SET) &&
|
||||
ieee80211_has_protected(hdr->frame_control))
|
||||
is_dvlan = true;
|
||||
|
||||
if (!vif->valid_links || !is_mcast || is_dvlan ||
|
||||
test_bit(ATH12K_FLAG_RAW_MODE, &ar->ab->dev_flags)) {
|
||||
ret = ath12k_dp_tx(ar, arvif, skb, false, 0, is_mcast);
|
||||
if (unlikely(ret)) {
|
||||
@ -7990,7 +8032,7 @@ static int ath12k_mac_setup_vdev_params_mbssid(struct ath12k_link_vif *arvif,
|
||||
return -ENOLINK;
|
||||
}
|
||||
|
||||
tx_arvif = ath12k_mac_get_tx_arvif(arvif);
|
||||
tx_arvif = ath12k_mac_get_tx_arvif(arvif, link_conf);
|
||||
if (!tx_arvif)
|
||||
return 0;
|
||||
|
||||
@ -8319,50 +8361,9 @@ void ath12k_mac_11d_scan_stop_all(struct ath12k_base *ab)
|
||||
}
|
||||
}
|
||||
|
||||
int ath12k_mac_vdev_create(struct ath12k *ar, struct ath12k_link_vif *arvif)
|
||||
static void ath12k_mac_determine_vdev_type(struct ieee80211_vif *vif,
|
||||
struct ath12k_vif *ahvif)
|
||||
{
|
||||
struct ath12k_hw *ah = ar->ah;
|
||||
struct ath12k_base *ab = ar->ab;
|
||||
struct ieee80211_hw *hw = ah->hw;
|
||||
struct ath12k_vif *ahvif = arvif->ahvif;
|
||||
struct ieee80211_vif *vif = ath12k_ahvif_to_vif(ahvif);
|
||||
struct ath12k_wmi_vdev_create_arg vdev_arg = {0};
|
||||
struct ath12k_wmi_peer_create_arg peer_param = {0};
|
||||
struct ieee80211_bss_conf *link_conf;
|
||||
u32 param_id, param_value;
|
||||
u16 nss;
|
||||
int i;
|
||||
int ret, vdev_id;
|
||||
u8 link_id;
|
||||
|
||||
lockdep_assert_wiphy(hw->wiphy);
|
||||
|
||||
/* In NO_VIRTUAL_MONITOR, its necessary to restrict only one monitor
|
||||
* interface in each radio
|
||||
*/
|
||||
if (vif->type == NL80211_IFTYPE_MONITOR && ar->monitor_vdev_created)
|
||||
return -EINVAL;
|
||||
|
||||
/* If no link is active and scan vdev is requested
|
||||
* use a default link conf for scan address purpose.
|
||||
*/
|
||||
if (arvif->link_id == ATH12K_DEFAULT_SCAN_LINK && vif->valid_links)
|
||||
link_id = ffs(vif->valid_links) - 1;
|
||||
else
|
||||
link_id = arvif->link_id;
|
||||
|
||||
link_conf = wiphy_dereference(hw->wiphy, vif->link_conf[link_id]);
|
||||
if (!link_conf) {
|
||||
ath12k_warn(ar->ab, "unable to access bss link conf in vdev create for vif %pM link %u\n",
|
||||
vif->addr, arvif->link_id);
|
||||
return -ENOLINK;
|
||||
}
|
||||
|
||||
memcpy(arvif->bssid, link_conf->addr, ETH_ALEN);
|
||||
|
||||
arvif->ar = ar;
|
||||
vdev_id = __ffs64(ab->free_vdev_map);
|
||||
arvif->vdev_id = vdev_id;
|
||||
ahvif->vdev_subtype = WMI_VDEV_SUBTYPE_NONE;
|
||||
|
||||
switch (vif->type) {
|
||||
@ -8386,7 +8387,6 @@ int ath12k_mac_vdev_create(struct ath12k *ar, struct ath12k_link_vif *arvif)
|
||||
break;
|
||||
case NL80211_IFTYPE_MONITOR:
|
||||
ahvif->vdev_type = WMI_VDEV_TYPE_MONITOR;
|
||||
ar->monitor_vdev_id = vdev_id;
|
||||
break;
|
||||
case NL80211_IFTYPE_P2P_DEVICE:
|
||||
ahvif->vdev_type = WMI_VDEV_TYPE_STA;
|
||||
@ -8396,6 +8396,53 @@ int ath12k_mac_vdev_create(struct ath12k *ar, struct ath12k_link_vif *arvif)
|
||||
WARN_ON(1);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
int ath12k_mac_vdev_create(struct ath12k *ar, struct ath12k_link_vif *arvif)
|
||||
{
|
||||
struct ath12k_hw *ah = ar->ah;
|
||||
struct ath12k_base *ab = ar->ab;
|
||||
struct ieee80211_hw *hw = ah->hw;
|
||||
struct ath12k_vif *ahvif = arvif->ahvif;
|
||||
struct ieee80211_vif *vif = ath12k_ahvif_to_vif(ahvif);
|
||||
struct ath12k_wmi_vdev_create_arg vdev_arg = {0};
|
||||
struct ath12k_wmi_peer_create_arg peer_param = {0};
|
||||
struct ieee80211_bss_conf *link_conf = NULL;
|
||||
u32 param_id, param_value;
|
||||
u16 nss;
|
||||
int i;
|
||||
int ret, vdev_id;
|
||||
u8 link_id;
|
||||
|
||||
lockdep_assert_wiphy(hw->wiphy);
|
||||
|
||||
/* In NO_VIRTUAL_MONITOR, its necessary to restrict only one monitor
|
||||
* interface in each radio
|
||||
*/
|
||||
if (vif->type == NL80211_IFTYPE_MONITOR && ar->monitor_vdev_created)
|
||||
return -EINVAL;
|
||||
|
||||
link_id = arvif->link_id;
|
||||
|
||||
if (link_id < IEEE80211_MLD_MAX_NUM_LINKS) {
|
||||
link_conf = wiphy_dereference(hw->wiphy, vif->link_conf[link_id]);
|
||||
if (!link_conf) {
|
||||
ath12k_warn(ar->ab, "unable to access bss link conf in vdev create for vif %pM link %u\n",
|
||||
vif->addr, arvif->link_id);
|
||||
return -ENOLINK;
|
||||
}
|
||||
}
|
||||
|
||||
if (link_conf)
|
||||
memcpy(arvif->bssid, link_conf->addr, ETH_ALEN);
|
||||
else
|
||||
memcpy(arvif->bssid, vif->addr, ETH_ALEN);
|
||||
|
||||
arvif->ar = ar;
|
||||
vdev_id = __ffs64(ab->free_vdev_map);
|
||||
arvif->vdev_id = vdev_id;
|
||||
if (vif->type == NL80211_IFTYPE_MONITOR)
|
||||
ar->monitor_vdev_id = vdev_id;
|
||||
|
||||
ath12k_dbg(ar->ab, ATH12K_DBG_MAC, "mac vdev create id %d type %d subtype %d map %llx\n",
|
||||
arvif->vdev_id, ahvif->vdev_type, ahvif->vdev_subtype,
|
||||
@ -8513,7 +8560,11 @@ int ath12k_mac_vdev_create(struct ath12k *ar, struct ath12k_link_vif *arvif)
|
||||
break;
|
||||
}
|
||||
|
||||
arvif->txpower = link_conf->txpower;
|
||||
if (link_conf)
|
||||
arvif->txpower = link_conf->txpower;
|
||||
else
|
||||
arvif->txpower = NL80211_TX_POWER_AUTOMATIC;
|
||||
|
||||
ret = ath12k_mac_txpower_recalc(ar);
|
||||
if (ret)
|
||||
goto err_peer_del;
|
||||
@ -8751,7 +8802,10 @@ static int ath12k_mac_op_add_interface(struct ieee80211_hw *hw,
|
||||
{
|
||||
struct ath12k_hw *ah = ath12k_hw_to_ah(hw);
|
||||
struct ath12k_vif *ahvif = ath12k_vif_to_ahvif(vif);
|
||||
struct ath12k_reg_info *reg_info;
|
||||
struct ath12k_link_vif *arvif;
|
||||
struct ath12k_base *ab;
|
||||
struct ath12k *ar;
|
||||
int i;
|
||||
|
||||
lockdep_assert_wiphy(hw->wiphy);
|
||||
@ -8770,6 +8824,22 @@ static int ath12k_mac_op_add_interface(struct ieee80211_hw *hw,
|
||||
vif->hw_queue[i] = ATH12K_HW_DEFAULT_QUEUE;
|
||||
|
||||
vif->driver_flags |= IEEE80211_VIF_SUPPORTS_UAPSD;
|
||||
|
||||
ath12k_mac_determine_vdev_type(vif, ahvif);
|
||||
|
||||
for_each_ar(ah, ar, i) {
|
||||
if (!ath12k_wmi_supports_6ghz_cc_ext(ar))
|
||||
continue;
|
||||
|
||||
ab = ar->ab;
|
||||
reg_info = ab->reg_info[ar->pdev_idx];
|
||||
ath12k_dbg(ab, ATH12K_DBG_MAC, "interface added to change reg rules\n");
|
||||
ah->regd_updated = false;
|
||||
ath12k_reg_handle_chan_list(ab, reg_info, ahvif->vdev_type,
|
||||
IEEE80211_REG_UNSET_AP);
|
||||
break;
|
||||
}
|
||||
|
||||
/* Defer vdev creation until assign_chanctx or hw_scan is initiated as driver
|
||||
* will not know if this interface is an ML vif at this point.
|
||||
*/
|
||||
@ -9326,6 +9396,15 @@ ath12k_mac_vdev_start_restart(struct ath12k_link_vif *arvif,
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* TODO: For now we only set TPC power here. However when
|
||||
* channel changes, say CSA, it should be updated again.
|
||||
*/
|
||||
if (ath12k_mac_supports_station_tpc(ar, ahvif, chandef)) {
|
||||
ath12k_mac_fill_reg_tpc_info(ar, arvif, ctx);
|
||||
ath12k_wmi_send_vdev_set_tpc_power(ar, arvif->vdev_id,
|
||||
&arvif->reg_tpc_info);
|
||||
}
|
||||
|
||||
ar->num_started_vdevs++;
|
||||
ath12k_dbg(ab, ATH12K_DBG_MAC, "vdev %pM started, vdev_id %d\n",
|
||||
ahvif->vif->addr, arvif->vdev_id);
|
||||
@ -9581,7 +9660,7 @@ ath12k_mac_update_vif_chan(struct ath12k *ar,
|
||||
params.aid = ahvif->aid;
|
||||
params.bssid = arvif->bssid;
|
||||
|
||||
tx_arvif = ath12k_mac_get_tx_arvif(arvif);
|
||||
tx_arvif = ath12k_mac_get_tx_arvif(arvif, link_conf);
|
||||
if (tx_arvif) {
|
||||
params.tx_bssid = tx_arvif->bssid;
|
||||
params.nontx_profile_idx = link_conf->bssid_index;
|
||||
@ -9718,6 +9797,391 @@ static int ath12k_start_vdev_delay(struct ath12k *ar,
|
||||
return 0;
|
||||
}
|
||||
|
||||
static u8 ath12k_mac_get_num_pwr_levels(struct cfg80211_chan_def *chan_def)
|
||||
{
|
||||
if (chan_def->chan->flags & IEEE80211_CHAN_PSD) {
|
||||
switch (chan_def->width) {
|
||||
case NL80211_CHAN_WIDTH_20:
|
||||
return 1;
|
||||
case NL80211_CHAN_WIDTH_40:
|
||||
return 2;
|
||||
case NL80211_CHAN_WIDTH_80:
|
||||
return 4;
|
||||
case NL80211_CHAN_WIDTH_160:
|
||||
return 8;
|
||||
case NL80211_CHAN_WIDTH_320:
|
||||
return 16;
|
||||
default:
|
||||
return 1;
|
||||
}
|
||||
} else {
|
||||
switch (chan_def->width) {
|
||||
case NL80211_CHAN_WIDTH_20:
|
||||
return 1;
|
||||
case NL80211_CHAN_WIDTH_40:
|
||||
return 2;
|
||||
case NL80211_CHAN_WIDTH_80:
|
||||
return 3;
|
||||
case NL80211_CHAN_WIDTH_160:
|
||||
return 4;
|
||||
case NL80211_CHAN_WIDTH_320:
|
||||
return 5;
|
||||
default:
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static u16 ath12k_mac_get_6ghz_start_frequency(struct cfg80211_chan_def *chan_def)
|
||||
{
|
||||
u16 diff_seq;
|
||||
|
||||
/* It is to get the lowest channel number's center frequency of the chan.
|
||||
* For example,
|
||||
* bandwidth=40 MHz, center frequency is 5965, lowest channel is 1
|
||||
* with center frequency 5955, its diff is 5965 - 5955 = 10.
|
||||
* bandwidth=80 MHz, center frequency is 5985, lowest channel is 1
|
||||
* with center frequency 5955, its diff is 5985 - 5955 = 30.
|
||||
* bandwidth=160 MHz, center frequency is 6025, lowest channel is 1
|
||||
* with center frequency 5955, its diff is 6025 - 5955 = 70.
|
||||
* bandwidth=320 MHz, center frequency is 6105, lowest channel is 1
|
||||
* with center frequency 5955, its diff is 6105 - 5955 = 70.
|
||||
*/
|
||||
switch (chan_def->width) {
|
||||
case NL80211_CHAN_WIDTH_320:
|
||||
diff_seq = 150;
|
||||
break;
|
||||
case NL80211_CHAN_WIDTH_160:
|
||||
diff_seq = 70;
|
||||
break;
|
||||
case NL80211_CHAN_WIDTH_80:
|
||||
diff_seq = 30;
|
||||
break;
|
||||
case NL80211_CHAN_WIDTH_40:
|
||||
diff_seq = 10;
|
||||
break;
|
||||
default:
|
||||
diff_seq = 0;
|
||||
}
|
||||
|
||||
return chan_def->center_freq1 - diff_seq;
|
||||
}
|
||||
|
||||
static u16 ath12k_mac_get_seg_freq(struct cfg80211_chan_def *chan_def,
|
||||
u16 start_seq, u8 seq)
|
||||
{
|
||||
u16 seg_seq;
|
||||
|
||||
/* It is to get the center frequency of the specific bandwidth.
|
||||
* start_seq means the lowest channel number's center frequency.
|
||||
* seq 0/1/2/3 means 20 MHz/40 MHz/80 MHz/160 MHz.
|
||||
* For example,
|
||||
* lowest channel is 1, its center frequency 5955,
|
||||
* center frequency is 5955 when bandwidth=20 MHz, its diff is 5955 - 5955 = 0.
|
||||
* lowest channel is 1, its center frequency 5955,
|
||||
* center frequency is 5965 when bandwidth=40 MHz, its diff is 5965 - 5955 = 10.
|
||||
* lowest channel is 1, its center frequency 5955,
|
||||
* center frequency is 5985 when bandwidth=80 MHz, its diff is 5985 - 5955 = 30.
|
||||
* lowest channel is 1, its center frequency 5955,
|
||||
* center frequency is 6025 when bandwidth=160 MHz, its diff is 6025 - 5955 = 70.
|
||||
*/
|
||||
seg_seq = 10 * (BIT(seq) - 1);
|
||||
return seg_seq + start_seq;
|
||||
}
|
||||
|
||||
static void ath12k_mac_get_psd_channel(struct ath12k *ar,
|
||||
u16 step_freq,
|
||||
u16 *start_freq,
|
||||
u16 *center_freq,
|
||||
u8 i,
|
||||
struct ieee80211_channel **temp_chan,
|
||||
s8 *tx_power)
|
||||
{
|
||||
/* It is to get the center frequency for each 20 MHz.
|
||||
* For example, if the chan is 160 MHz and center frequency is 6025,
|
||||
* then it include 8 channels, they are 1/5/9/13/17/21/25/29,
|
||||
* channel number 1's center frequency is 5955, it is parameter start_freq.
|
||||
* parameter i is the step of the 8 channels. i is 0~7 for the 8 channels.
|
||||
* the channel 1/5/9/13/17/21/25/29 maps i=0/1/2/3/4/5/6/7,
|
||||
* and maps its center frequency is 5955/5975/5995/6015/6035/6055/6075/6095,
|
||||
* the gap is 20 for each channel, parameter step_freq means the gap.
|
||||
* after get the center frequency of each channel, it is easy to find the
|
||||
* struct ieee80211_channel of it and get the max_reg_power.
|
||||
*/
|
||||
*center_freq = *start_freq + i * step_freq;
|
||||
*temp_chan = ieee80211_get_channel(ar->ah->hw->wiphy, *center_freq);
|
||||
*tx_power = (*temp_chan)->max_reg_power;
|
||||
}
|
||||
|
||||
static void ath12k_mac_get_eirp_power(struct ath12k *ar,
|
||||
u16 *start_freq,
|
||||
u16 *center_freq,
|
||||
u8 i,
|
||||
struct ieee80211_channel **temp_chan,
|
||||
struct cfg80211_chan_def *def,
|
||||
s8 *tx_power)
|
||||
{
|
||||
/* It is to get the center frequency for 20 MHz/40 MHz/80 MHz/
|
||||
* 160 MHz bandwidth, and then plus 10 to the center frequency,
|
||||
* it is the center frequency of a channel number.
|
||||
* For example, when configured channel number is 1.
|
||||
* center frequency is 5965 when bandwidth=40 MHz, after plus 10, it is 5975,
|
||||
* then it is channel number 5.
|
||||
* center frequency is 5985 when bandwidth=80 MHz, after plus 10, it is 5995,
|
||||
* then it is channel number 9.
|
||||
* center frequency is 6025 when bandwidth=160 MHz, after plus 10, it is 6035,
|
||||
* then it is channel number 17.
|
||||
* after get the center frequency of each channel, it is easy to find the
|
||||
* struct ieee80211_channel of it and get the max_reg_power.
|
||||
*/
|
||||
*center_freq = ath12k_mac_get_seg_freq(def, *start_freq, i);
|
||||
|
||||
/* For the 20 MHz, its center frequency is same with same channel */
|
||||
if (i != 0)
|
||||
*center_freq += 10;
|
||||
|
||||
*temp_chan = ieee80211_get_channel(ar->ah->hw->wiphy, *center_freq);
|
||||
*tx_power = (*temp_chan)->max_reg_power;
|
||||
}
|
||||
|
||||
void ath12k_mac_fill_reg_tpc_info(struct ath12k *ar,
|
||||
struct ath12k_link_vif *arvif,
|
||||
struct ieee80211_chanctx_conf *ctx)
|
||||
{
|
||||
struct ath12k_base *ab = ar->ab;
|
||||
struct ath12k_reg_tpc_power_info *reg_tpc_info = &arvif->reg_tpc_info;
|
||||
struct ieee80211_bss_conf *bss_conf = ath12k_mac_get_link_bss_conf(arvif);
|
||||
struct ieee80211_channel *chan, *temp_chan;
|
||||
u8 pwr_lvl_idx, num_pwr_levels, pwr_reduction;
|
||||
bool is_psd_power = false, is_tpe_present = false;
|
||||
s8 max_tx_power[ATH12K_NUM_PWR_LEVELS],
|
||||
psd_power, tx_power, eirp_power;
|
||||
u16 start_freq, center_freq;
|
||||
|
||||
chan = ctx->def.chan;
|
||||
start_freq = ath12k_mac_get_6ghz_start_frequency(&ctx->def);
|
||||
pwr_reduction = bss_conf->pwr_reduction;
|
||||
|
||||
if (arvif->reg_tpc_info.num_pwr_levels) {
|
||||
is_tpe_present = true;
|
||||
num_pwr_levels = arvif->reg_tpc_info.num_pwr_levels;
|
||||
} else {
|
||||
num_pwr_levels = ath12k_mac_get_num_pwr_levels(&ctx->def);
|
||||
}
|
||||
|
||||
for (pwr_lvl_idx = 0; pwr_lvl_idx < num_pwr_levels; pwr_lvl_idx++) {
|
||||
/* STA received TPE IE*/
|
||||
if (is_tpe_present) {
|
||||
/* local power is PSD power*/
|
||||
if (chan->flags & IEEE80211_CHAN_PSD) {
|
||||
/* Connecting AP is psd power */
|
||||
if (reg_tpc_info->is_psd_power) {
|
||||
is_psd_power = true;
|
||||
ath12k_mac_get_psd_channel(ar, 20,
|
||||
&start_freq,
|
||||
¢er_freq,
|
||||
pwr_lvl_idx,
|
||||
&temp_chan,
|
||||
&tx_power);
|
||||
psd_power = temp_chan->psd;
|
||||
eirp_power = tx_power;
|
||||
max_tx_power[pwr_lvl_idx] =
|
||||
min_t(s8,
|
||||
psd_power,
|
||||
reg_tpc_info->tpe[pwr_lvl_idx]);
|
||||
/* Connecting AP is not psd power */
|
||||
} else {
|
||||
ath12k_mac_get_eirp_power(ar,
|
||||
&start_freq,
|
||||
¢er_freq,
|
||||
pwr_lvl_idx,
|
||||
&temp_chan,
|
||||
&ctx->def,
|
||||
&tx_power);
|
||||
psd_power = temp_chan->psd;
|
||||
/* convert psd power to EIRP power based
|
||||
* on channel width
|
||||
*/
|
||||
tx_power =
|
||||
min_t(s8, tx_power,
|
||||
psd_power + 13 + pwr_lvl_idx * 3);
|
||||
max_tx_power[pwr_lvl_idx] =
|
||||
min_t(s8,
|
||||
tx_power,
|
||||
reg_tpc_info->tpe[pwr_lvl_idx]);
|
||||
}
|
||||
/* local power is not PSD power */
|
||||
} else {
|
||||
/* Connecting AP is psd power */
|
||||
if (reg_tpc_info->is_psd_power) {
|
||||
is_psd_power = true;
|
||||
ath12k_mac_get_psd_channel(ar, 20,
|
||||
&start_freq,
|
||||
¢er_freq,
|
||||
pwr_lvl_idx,
|
||||
&temp_chan,
|
||||
&tx_power);
|
||||
eirp_power = tx_power;
|
||||
max_tx_power[pwr_lvl_idx] =
|
||||
reg_tpc_info->tpe[pwr_lvl_idx];
|
||||
/* Connecting AP is not psd power */
|
||||
} else {
|
||||
ath12k_mac_get_eirp_power(ar,
|
||||
&start_freq,
|
||||
¢er_freq,
|
||||
pwr_lvl_idx,
|
||||
&temp_chan,
|
||||
&ctx->def,
|
||||
&tx_power);
|
||||
max_tx_power[pwr_lvl_idx] =
|
||||
min_t(s8,
|
||||
tx_power,
|
||||
reg_tpc_info->tpe[pwr_lvl_idx]);
|
||||
}
|
||||
}
|
||||
/* STA not received TPE IE */
|
||||
} else {
|
||||
/* local power is PSD power*/
|
||||
if (chan->flags & IEEE80211_CHAN_PSD) {
|
||||
is_psd_power = true;
|
||||
ath12k_mac_get_psd_channel(ar, 20,
|
||||
&start_freq,
|
||||
¢er_freq,
|
||||
pwr_lvl_idx,
|
||||
&temp_chan,
|
||||
&tx_power);
|
||||
psd_power = temp_chan->psd;
|
||||
eirp_power = tx_power;
|
||||
max_tx_power[pwr_lvl_idx] = psd_power;
|
||||
} else {
|
||||
ath12k_mac_get_eirp_power(ar,
|
||||
&start_freq,
|
||||
¢er_freq,
|
||||
pwr_lvl_idx,
|
||||
&temp_chan,
|
||||
&ctx->def,
|
||||
&tx_power);
|
||||
max_tx_power[pwr_lvl_idx] = tx_power;
|
||||
}
|
||||
}
|
||||
|
||||
if (is_psd_power) {
|
||||
/* If AP local power constraint is present */
|
||||
if (pwr_reduction)
|
||||
eirp_power = eirp_power - pwr_reduction;
|
||||
|
||||
/* If firmware updated max tx power is non zero, then take
|
||||
* the min of firmware updated ap tx power
|
||||
* and max power derived from above mentioned parameters.
|
||||
*/
|
||||
ath12k_dbg(ab, ATH12K_DBG_MAC,
|
||||
"eirp power : %d firmware report power : %d\n",
|
||||
eirp_power, ar->max_allowed_tx_power);
|
||||
/* Firmware reports lower max_allowed_tx_power during vdev
|
||||
* start response. In case of 6 GHz, firmware is not aware
|
||||
* of EIRP power unless driver sets EIRP power through WMI
|
||||
* TPC command. So radio which does not support idle power
|
||||
* save can set maximum calculated EIRP power directly to
|
||||
* firmware through TPC command without min comparison with
|
||||
* vdev start response's max_allowed_tx_power.
|
||||
*/
|
||||
if (ar->max_allowed_tx_power && ab->hw_params->idle_ps)
|
||||
eirp_power = min_t(s8,
|
||||
eirp_power,
|
||||
ar->max_allowed_tx_power);
|
||||
} else {
|
||||
/* If AP local power constraint is present */
|
||||
if (pwr_reduction)
|
||||
max_tx_power[pwr_lvl_idx] =
|
||||
max_tx_power[pwr_lvl_idx] - pwr_reduction;
|
||||
/* If firmware updated max tx power is non zero, then take
|
||||
* the min of firmware updated ap tx power
|
||||
* and max power derived from above mentioned parameters.
|
||||
*/
|
||||
if (ar->max_allowed_tx_power && ab->hw_params->idle_ps)
|
||||
max_tx_power[pwr_lvl_idx] =
|
||||
min_t(s8,
|
||||
max_tx_power[pwr_lvl_idx],
|
||||
ar->max_allowed_tx_power);
|
||||
}
|
||||
reg_tpc_info->chan_power_info[pwr_lvl_idx].chan_cfreq = center_freq;
|
||||
reg_tpc_info->chan_power_info[pwr_lvl_idx].tx_power =
|
||||
max_tx_power[pwr_lvl_idx];
|
||||
}
|
||||
|
||||
reg_tpc_info->num_pwr_levels = num_pwr_levels;
|
||||
reg_tpc_info->is_psd_power = is_psd_power;
|
||||
reg_tpc_info->eirp_power = eirp_power;
|
||||
reg_tpc_info->ap_power_type =
|
||||
ath12k_reg_ap_pwr_convert(bss_conf->power_type);
|
||||
}
|
||||
|
||||
static void ath12k_mac_parse_tx_pwr_env(struct ath12k *ar,
|
||||
struct ath12k_link_vif *arvif)
|
||||
{
|
||||
struct ieee80211_bss_conf *bss_conf = ath12k_mac_get_link_bss_conf(arvif);
|
||||
struct ath12k_reg_tpc_power_info *tpc_info = &arvif->reg_tpc_info;
|
||||
struct ieee80211_parsed_tpe_eirp *local_non_psd, *reg_non_psd;
|
||||
struct ieee80211_parsed_tpe_psd *local_psd, *reg_psd;
|
||||
struct ieee80211_parsed_tpe *tpe = &bss_conf->tpe;
|
||||
enum wmi_reg_6g_client_type client_type;
|
||||
struct ath12k_reg_info *reg_info;
|
||||
struct ath12k_base *ab = ar->ab;
|
||||
bool psd_valid, non_psd_valid;
|
||||
int i;
|
||||
|
||||
reg_info = ab->reg_info[ar->pdev_idx];
|
||||
client_type = reg_info->client_type;
|
||||
|
||||
local_psd = &tpe->psd_local[client_type];
|
||||
reg_psd = &tpe->psd_reg_client[client_type];
|
||||
local_non_psd = &tpe->max_local[client_type];
|
||||
reg_non_psd = &tpe->max_reg_client[client_type];
|
||||
|
||||
psd_valid = local_psd->valid | reg_psd->valid;
|
||||
non_psd_valid = local_non_psd->valid | reg_non_psd->valid;
|
||||
|
||||
if (!psd_valid && !non_psd_valid) {
|
||||
ath12k_warn(ab,
|
||||
"no transmit power envelope match client power type %d\n",
|
||||
client_type);
|
||||
return;
|
||||
};
|
||||
|
||||
if (psd_valid) {
|
||||
tpc_info->is_psd_power = true;
|
||||
|
||||
tpc_info->num_pwr_levels = max(local_psd->count,
|
||||
reg_psd->count);
|
||||
if (tpc_info->num_pwr_levels > ATH12K_NUM_PWR_LEVELS)
|
||||
tpc_info->num_pwr_levels = ATH12K_NUM_PWR_LEVELS;
|
||||
|
||||
for (i = 0; i < tpc_info->num_pwr_levels; i++) {
|
||||
tpc_info->tpe[i] = min(local_psd->power[i],
|
||||
reg_psd->power[i]) / 2;
|
||||
ath12k_dbg(ab, ATH12K_DBG_MAC,
|
||||
"TPE PSD power[%d] : %d\n",
|
||||
i, tpc_info->tpe[i]);
|
||||
}
|
||||
} else {
|
||||
tpc_info->is_psd_power = false;
|
||||
tpc_info->eirp_power = 0;
|
||||
|
||||
tpc_info->num_pwr_levels = max(local_non_psd->count,
|
||||
reg_non_psd->count);
|
||||
if (tpc_info->num_pwr_levels > ATH12K_NUM_PWR_LEVELS)
|
||||
tpc_info->num_pwr_levels = ATH12K_NUM_PWR_LEVELS;
|
||||
|
||||
for (i = 0; i < tpc_info->num_pwr_levels; i++) {
|
||||
tpc_info->tpe[i] = min(local_non_psd->power[i],
|
||||
reg_non_psd->power[i]) / 2;
|
||||
ath12k_dbg(ab, ATH12K_DBG_MAC,
|
||||
"non PSD power[%d] : %d\n",
|
||||
i, tpc_info->tpe[i]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static int
|
||||
ath12k_mac_op_assign_vif_chanctx(struct ieee80211_hw *hw,
|
||||
struct ieee80211_vif *vif,
|
||||
@ -9756,6 +10220,11 @@ ath12k_mac_op_assign_vif_chanctx(struct ieee80211_hw *hw,
|
||||
"mac chanctx assign ptr %p vdev_id %i\n",
|
||||
ctx, arvif->vdev_id);
|
||||
|
||||
if (ath12k_wmi_supports_6ghz_cc_ext(ar) &&
|
||||
ctx->def.chan->band == NL80211_BAND_6GHZ &&
|
||||
ahvif->vdev_type == WMI_VDEV_TYPE_STA)
|
||||
ath12k_mac_parse_tx_pwr_env(ar, arvif);
|
||||
|
||||
arvif->punct_bitmap = ctx->def.punctured;
|
||||
|
||||
/* for some targets bss peer must be created before vdev_start */
|
||||
@ -9860,6 +10329,11 @@ ath12k_mac_op_unassign_vif_chanctx(struct ieee80211_hw *hw,
|
||||
reinit_completion(&ar->completed_11d_scan);
|
||||
ar->state_11d = ATH12K_11D_PREPARING;
|
||||
}
|
||||
|
||||
if (ar->scan.arvif == arvif && ar->scan.state == ATH12K_SCAN_RUNNING) {
|
||||
ath12k_scan_abort(ar);
|
||||
ar->scan.arvif = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
static int
|
||||
@ -10889,8 +11363,20 @@ void ath12k_mac_update_freq_range(struct ath12k *ar,
|
||||
if (!(freq_low && freq_high))
|
||||
return;
|
||||
|
||||
ar->freq_range.start_freq = MHZ_TO_KHZ(freq_low);
|
||||
ar->freq_range.end_freq = MHZ_TO_KHZ(freq_high);
|
||||
if (ar->freq_range.start_freq || ar->freq_range.end_freq) {
|
||||
ar->freq_range.start_freq = min(ar->freq_range.start_freq,
|
||||
MHZ_TO_KHZ(freq_low));
|
||||
ar->freq_range.end_freq = max(ar->freq_range.end_freq,
|
||||
MHZ_TO_KHZ(freq_high));
|
||||
} else {
|
||||
ar->freq_range.start_freq = MHZ_TO_KHZ(freq_low);
|
||||
ar->freq_range.end_freq = MHZ_TO_KHZ(freq_high);
|
||||
}
|
||||
|
||||
ath12k_dbg(ar->ab, ATH12K_DBG_MAC,
|
||||
"mac pdev %u freq limit updated. New range %u->%u MHz\n",
|
||||
ar->pdev->pdev_id, KHZ_TO_MHZ(ar->freq_range.start_freq),
|
||||
KHZ_TO_MHZ(ar->freq_range.end_freq));
|
||||
}
|
||||
|
||||
static void ath12k_mac_update_ch_list(struct ath12k *ar,
|
||||
@ -11374,6 +11860,7 @@ static void ath12k_mac_hw_unregister(struct ath12k_hw *ah)
|
||||
for_each_ar(ah, ar, i) {
|
||||
cancel_work_sync(&ar->regd_update_work);
|
||||
ath12k_debugfs_unregister(ar);
|
||||
ath12k_fw_stats_reset(ar);
|
||||
}
|
||||
|
||||
ieee80211_unregister_hw(hw);
|
||||
@ -11651,6 +12138,18 @@ static int ath12k_mac_hw_register(struct ath12k_hw *ah)
|
||||
goto err_unregister_hw;
|
||||
}
|
||||
|
||||
if (ar->ab->hw_params->current_cc_support && ab->new_alpha2[0]) {
|
||||
struct wmi_set_current_country_arg current_cc = {};
|
||||
|
||||
memcpy(¤t_cc.alpha2, ab->new_alpha2, 2);
|
||||
memcpy(&ar->alpha2, ab->new_alpha2, 2);
|
||||
ret = ath12k_wmi_send_set_current_country_cmd(ar, ¤t_cc);
|
||||
if (ret)
|
||||
ath12k_warn(ar->ab,
|
||||
"failed set cc code for mac register: %d\n",
|
||||
ret);
|
||||
}
|
||||
|
||||
ath12k_fw_stats_init(ar);
|
||||
ath12k_debugfs_register(ar);
|
||||
}
|
||||
@ -12025,6 +12524,7 @@ int ath12k_mac_allocate(struct ath12k_hw_group *ag)
|
||||
if (!ab)
|
||||
continue;
|
||||
|
||||
ath12k_debugfs_pdev_create(ab);
|
||||
ath12k_mac_set_device_defaults(ab);
|
||||
total_radio += ab->num_radios;
|
||||
}
|
||||
|
||||
@ -67,6 +67,46 @@ struct ath12k_mac_get_any_chanctx_conf_arg {
|
||||
struct ieee80211_chanctx_conf *chanctx_conf;
|
||||
};
|
||||
|
||||
/**
|
||||
* struct ath12k_chan_power_info - TPE containing power info per channel chunk
|
||||
* @chan_cfreq: channel center freq (MHz)
|
||||
* e.g.
|
||||
* channel 37/20 MHz, it is 6135
|
||||
* channel 37/40 MHz, it is 6125
|
||||
* channel 37/80 MHz, it is 6145
|
||||
* channel 37/160 MHz, it is 6185
|
||||
* @tx_power: transmit power (dBm)
|
||||
*/
|
||||
struct ath12k_chan_power_info {
|
||||
u16 chan_cfreq;
|
||||
s8 tx_power;
|
||||
};
|
||||
|
||||
/* ath12k only deals with 320 MHz, so 16 subchannels */
|
||||
#define ATH12K_NUM_PWR_LEVELS 16
|
||||
|
||||
/**
|
||||
* struct ath12k_reg_tpc_power_info - regulatory TPC power info
|
||||
* @is_psd_power: is PSD power or not
|
||||
* @eirp_power: Maximum EIRP power (dBm), valid only if power is PSD
|
||||
* @ap_power_type: type of power (SP/LPI/VLP)
|
||||
* @num_pwr_levels: number of power levels
|
||||
* @reg_max: Array of maximum TX power (dBm) per PSD value
|
||||
* @ap_constraint_power: AP constraint power (dBm)
|
||||
* @tpe: TPE values processed from TPE IE
|
||||
* @chan_power_info: power info to send to firmware
|
||||
*/
|
||||
struct ath12k_reg_tpc_power_info {
|
||||
bool is_psd_power;
|
||||
u8 eirp_power;
|
||||
enum wmi_reg_6g_ap_type ap_power_type;
|
||||
u8 num_pwr_levels;
|
||||
u8 reg_max[ATH12K_NUM_PWR_LEVELS];
|
||||
u8 ap_constraint_power;
|
||||
s8 tpe[ATH12K_NUM_PWR_LEVELS];
|
||||
struct ath12k_chan_power_info chan_power_info[ATH12K_NUM_PWR_LEVELS];
|
||||
};
|
||||
|
||||
extern const struct htt_rx_ring_tlv_filter ath12k_mac_mon_status_filter_default;
|
||||
|
||||
#define ATH12K_SCAN_11D_INTERVAL 600000
|
||||
@ -128,4 +168,7 @@ struct ath12k *ath12k_get_ar_by_vif(struct ieee80211_hw *hw,
|
||||
int ath12k_mac_get_fw_stats(struct ath12k *ar, struct ath12k_fw_stats_req_params *param);
|
||||
void ath12k_mac_update_freq_range(struct ath12k *ar,
|
||||
u32 freq_low, u32 freq_high);
|
||||
void ath12k_mac_fill_reg_tpc_info(struct ath12k *ar,
|
||||
struct ath12k_link_vif *arvif,
|
||||
struct ieee80211_chanctx_conf *ctx);
|
||||
#endif
|
||||
|
||||
@ -600,7 +600,8 @@ static int ath12k_pci_ext_irq_config(struct ath12k_base *ab)
|
||||
ab->hw_params->ring_mask->rx_wbm_rel[i] ||
|
||||
ab->hw_params->ring_mask->reo_status[i] ||
|
||||
ab->hw_params->ring_mask->host2rxdma[i] ||
|
||||
ab->hw_params->ring_mask->rx_mon_dest[i]) {
|
||||
ab->hw_params->ring_mask->rx_mon_dest[i] ||
|
||||
ab->hw_params->ring_mask->rx_mon_status[i]) {
|
||||
num_irq = 1;
|
||||
}
|
||||
|
||||
@ -1733,8 +1734,6 @@ static void ath12k_pci_remove(struct pci_dev *pdev)
|
||||
|
||||
if (test_bit(ATH12K_FLAG_QMI_FAIL, &ab->dev_flags)) {
|
||||
ath12k_pci_power_down(ab, false);
|
||||
ath12k_qmi_deinit_service(ab);
|
||||
ath12k_core_hw_group_unassign(ab);
|
||||
goto qmi_fail;
|
||||
}
|
||||
|
||||
@ -1742,9 +1741,10 @@ static void ath12k_pci_remove(struct pci_dev *pdev)
|
||||
|
||||
cancel_work_sync(&ab->reset_work);
|
||||
cancel_work_sync(&ab->dump_work);
|
||||
ath12k_core_deinit(ab);
|
||||
ath12k_core_hw_group_cleanup(ab->ag);
|
||||
|
||||
qmi_fail:
|
||||
ath12k_core_deinit(ab);
|
||||
ath12k_fw_unmap(ab);
|
||||
ath12k_mhi_unregister(ab_pci);
|
||||
|
||||
|
||||
@ -139,7 +139,7 @@ int ath12k_reg_update_chan_list(struct ath12k *ar, bool wait)
|
||||
int num_channels = 0;
|
||||
int i, ret, left;
|
||||
|
||||
if (wait && ar->state_11d != ATH12K_11D_IDLE) {
|
||||
if (wait && ar->state_11d == ATH12K_11D_RUNNING) {
|
||||
left = wait_for_completion_timeout(&ar->completed_11d_scan,
|
||||
ATH12K_SCAN_TIMEOUT_HZ);
|
||||
if (!left) {
|
||||
@ -265,8 +265,8 @@ static void ath12k_copy_regd(struct ieee80211_regdomain *regd_orig,
|
||||
|
||||
int ath12k_regd_update(struct ath12k *ar, bool init)
|
||||
{
|
||||
u32 phy_id, freq_low = 0, freq_high = 0, supported_bands, band;
|
||||
struct ath12k_wmi_hal_reg_capabilities_ext_arg *reg_cap;
|
||||
u32 phy_id, freq_low, freq_high, supported_bands;
|
||||
struct ath12k_hw *ah = ath12k_ar_to_ah(ar);
|
||||
struct ieee80211_hw *hw = ah->hw;
|
||||
struct ieee80211_regdomain *regd, *regd_copy = NULL;
|
||||
@ -276,45 +276,45 @@ int ath12k_regd_update(struct ath12k *ar, bool init)
|
||||
ab = ar->ab;
|
||||
|
||||
supported_bands = ar->pdev->cap.supported_bands;
|
||||
if (supported_bands & WMI_HOST_WLAN_2GHZ_CAP) {
|
||||
band = NL80211_BAND_2GHZ;
|
||||
} else if (supported_bands & WMI_HOST_WLAN_5GHZ_CAP && !ar->supports_6ghz) {
|
||||
band = NL80211_BAND_5GHZ;
|
||||
} else if (supported_bands & WMI_HOST_WLAN_5GHZ_CAP && ar->supports_6ghz) {
|
||||
band = NL80211_BAND_6GHZ;
|
||||
} else {
|
||||
/* This condition is not expected.
|
||||
*/
|
||||
WARN_ON(1);
|
||||
ret = -EINVAL;
|
||||
goto err;
|
||||
}
|
||||
|
||||
reg_cap = &ab->hal_reg_cap[ar->pdev_idx];
|
||||
|
||||
if (ab->hw_params->single_pdev_only && !ar->supports_6ghz) {
|
||||
phy_id = ar->pdev->cap.band[band].phy_id;
|
||||
reg_cap = &ab->hal_reg_cap[phy_id];
|
||||
}
|
||||
|
||||
/* Possible that due to reg change, current limits for supported
|
||||
* frequency changed. Update that
|
||||
* frequency changed. Update it. As a first step, reset the
|
||||
* previous values and then compute and set the new values.
|
||||
*/
|
||||
ar->freq_range.start_freq = 0;
|
||||
ar->freq_range.end_freq = 0;
|
||||
|
||||
if (supported_bands & WMI_HOST_WLAN_2GHZ_CAP) {
|
||||
if (ab->hw_params->single_pdev_only) {
|
||||
phy_id = ar->pdev->cap.band[WMI_HOST_WLAN_2GHZ_CAP].phy_id;
|
||||
reg_cap = &ab->hal_reg_cap[phy_id];
|
||||
}
|
||||
|
||||
freq_low = max(reg_cap->low_2ghz_chan, ab->reg_freq_2ghz.start_freq);
|
||||
freq_high = min(reg_cap->high_2ghz_chan, ab->reg_freq_2ghz.end_freq);
|
||||
} else if (supported_bands & WMI_HOST_WLAN_5GHZ_CAP && !ar->supports_6ghz) {
|
||||
freq_low = max(reg_cap->low_5ghz_chan, ab->reg_freq_5ghz.start_freq);
|
||||
freq_high = min(reg_cap->high_5ghz_chan, ab->reg_freq_5ghz.end_freq);
|
||||
} else if (supported_bands & WMI_HOST_WLAN_5GHZ_CAP && ar->supports_6ghz) {
|
||||
freq_low = max(reg_cap->low_5ghz_chan, ab->reg_freq_6ghz.start_freq);
|
||||
freq_high = min(reg_cap->high_5ghz_chan, ab->reg_freq_6ghz.end_freq);
|
||||
|
||||
ath12k_mac_update_freq_range(ar, freq_low, freq_high);
|
||||
}
|
||||
|
||||
ath12k_mac_update_freq_range(ar, freq_low, freq_high);
|
||||
if (supported_bands & WMI_HOST_WLAN_5GHZ_CAP && !ar->supports_6ghz) {
|
||||
if (ab->hw_params->single_pdev_only) {
|
||||
phy_id = ar->pdev->cap.band[WMI_HOST_WLAN_5GHZ_CAP].phy_id;
|
||||
reg_cap = &ab->hal_reg_cap[phy_id];
|
||||
}
|
||||
|
||||
ath12k_dbg(ab, ATH12K_DBG_REG, "pdev %u reg updated freq limits %u->%u MHz\n",
|
||||
ar->pdev->pdev_id, freq_low, freq_high);
|
||||
freq_low = max(reg_cap->low_5ghz_chan, ab->reg_freq_5ghz.start_freq);
|
||||
freq_high = min(reg_cap->high_5ghz_chan, ab->reg_freq_5ghz.end_freq);
|
||||
|
||||
ath12k_mac_update_freq_range(ar, freq_low, freq_high);
|
||||
}
|
||||
|
||||
if (supported_bands & WMI_HOST_WLAN_5GHZ_CAP && ar->supports_6ghz) {
|
||||
freq_low = max(reg_cap->low_5ghz_chan, ab->reg_freq_6ghz.start_freq);
|
||||
freq_high = min(reg_cap->high_5ghz_chan, ab->reg_freq_6ghz.end_freq);
|
||||
|
||||
ath12k_mac_update_freq_range(ar, freq_low, freq_high);
|
||||
}
|
||||
|
||||
/* If one of the radios within ah has already updated the regd for
|
||||
* the wiphy, then avoid setting regd again
|
||||
@ -454,129 +454,6 @@ static u32 ath12k_map_fw_phy_flags(u32 phy_flags)
|
||||
return flags;
|
||||
}
|
||||
|
||||
static bool
|
||||
ath12k_reg_can_intersect(struct ieee80211_reg_rule *rule1,
|
||||
struct ieee80211_reg_rule *rule2)
|
||||
{
|
||||
u32 start_freq1, end_freq1;
|
||||
u32 start_freq2, end_freq2;
|
||||
|
||||
start_freq1 = rule1->freq_range.start_freq_khz;
|
||||
start_freq2 = rule2->freq_range.start_freq_khz;
|
||||
|
||||
end_freq1 = rule1->freq_range.end_freq_khz;
|
||||
end_freq2 = rule2->freq_range.end_freq_khz;
|
||||
|
||||
if ((start_freq1 >= start_freq2 &&
|
||||
start_freq1 < end_freq2) ||
|
||||
(start_freq2 > start_freq1 &&
|
||||
start_freq2 < end_freq1))
|
||||
return true;
|
||||
|
||||
/* TODO: Should we restrict intersection feasibility
|
||||
* based on min bandwidth of the intersected region also,
|
||||
* say the intersected rule should have a min bandwidth
|
||||
* of 20MHz?
|
||||
*/
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
static void ath12k_reg_intersect_rules(struct ieee80211_reg_rule *rule1,
|
||||
struct ieee80211_reg_rule *rule2,
|
||||
struct ieee80211_reg_rule *new_rule)
|
||||
{
|
||||
u32 start_freq1, end_freq1;
|
||||
u32 start_freq2, end_freq2;
|
||||
u32 freq_diff, max_bw;
|
||||
|
||||
start_freq1 = rule1->freq_range.start_freq_khz;
|
||||
start_freq2 = rule2->freq_range.start_freq_khz;
|
||||
|
||||
end_freq1 = rule1->freq_range.end_freq_khz;
|
||||
end_freq2 = rule2->freq_range.end_freq_khz;
|
||||
|
||||
new_rule->freq_range.start_freq_khz = max_t(u32, start_freq1,
|
||||
start_freq2);
|
||||
new_rule->freq_range.end_freq_khz = min_t(u32, end_freq1, end_freq2);
|
||||
|
||||
freq_diff = new_rule->freq_range.end_freq_khz -
|
||||
new_rule->freq_range.start_freq_khz;
|
||||
max_bw = min_t(u32, rule1->freq_range.max_bandwidth_khz,
|
||||
rule2->freq_range.max_bandwidth_khz);
|
||||
new_rule->freq_range.max_bandwidth_khz = min_t(u32, max_bw, freq_diff);
|
||||
|
||||
new_rule->power_rule.max_antenna_gain =
|
||||
min_t(u32, rule1->power_rule.max_antenna_gain,
|
||||
rule2->power_rule.max_antenna_gain);
|
||||
|
||||
new_rule->power_rule.max_eirp = min_t(u32, rule1->power_rule.max_eirp,
|
||||
rule2->power_rule.max_eirp);
|
||||
|
||||
/* Use the flags of both the rules */
|
||||
new_rule->flags = rule1->flags | rule2->flags;
|
||||
|
||||
/* To be safe, lts use the max cac timeout of both rules */
|
||||
new_rule->dfs_cac_ms = max_t(u32, rule1->dfs_cac_ms,
|
||||
rule2->dfs_cac_ms);
|
||||
}
|
||||
|
||||
static struct ieee80211_regdomain *
|
||||
ath12k_regd_intersect(struct ieee80211_regdomain *default_regd,
|
||||
struct ieee80211_regdomain *curr_regd)
|
||||
{
|
||||
u8 num_old_regd_rules, num_curr_regd_rules, num_new_regd_rules;
|
||||
struct ieee80211_reg_rule *old_rule, *curr_rule, *new_rule;
|
||||
struct ieee80211_regdomain *new_regd = NULL;
|
||||
u8 i, j, k;
|
||||
|
||||
num_old_regd_rules = default_regd->n_reg_rules;
|
||||
num_curr_regd_rules = curr_regd->n_reg_rules;
|
||||
num_new_regd_rules = 0;
|
||||
|
||||
/* Find the number of intersecting rules to allocate new regd memory */
|
||||
for (i = 0; i < num_old_regd_rules; i++) {
|
||||
old_rule = default_regd->reg_rules + i;
|
||||
for (j = 0; j < num_curr_regd_rules; j++) {
|
||||
curr_rule = curr_regd->reg_rules + j;
|
||||
|
||||
if (ath12k_reg_can_intersect(old_rule, curr_rule))
|
||||
num_new_regd_rules++;
|
||||
}
|
||||
}
|
||||
|
||||
if (!num_new_regd_rules)
|
||||
return NULL;
|
||||
|
||||
new_regd = kzalloc(sizeof(*new_regd) + (num_new_regd_rules *
|
||||
sizeof(struct ieee80211_reg_rule)),
|
||||
GFP_ATOMIC);
|
||||
|
||||
if (!new_regd)
|
||||
return NULL;
|
||||
|
||||
/* We set the new country and dfs region directly and only trim
|
||||
* the freq, power, antenna gain by intersecting with the
|
||||
* default regdomain. Also MAX of the dfs cac timeout is selected.
|
||||
*/
|
||||
new_regd->n_reg_rules = num_new_regd_rules;
|
||||
memcpy(new_regd->alpha2, curr_regd->alpha2, sizeof(new_regd->alpha2));
|
||||
new_regd->dfs_region = curr_regd->dfs_region;
|
||||
new_rule = new_regd->reg_rules;
|
||||
|
||||
for (i = 0, k = 0; i < num_old_regd_rules; i++) {
|
||||
old_rule = default_regd->reg_rules + i;
|
||||
for (j = 0; j < num_curr_regd_rules; j++) {
|
||||
curr_rule = curr_regd->reg_rules + j;
|
||||
|
||||
if (ath12k_reg_can_intersect(old_rule, curr_rule))
|
||||
ath12k_reg_intersect_rules(old_rule, curr_rule,
|
||||
(new_rule + k++));
|
||||
}
|
||||
}
|
||||
return new_regd;
|
||||
}
|
||||
|
||||
static const char *
|
||||
ath12k_reg_get_regdom_str(enum nl80211_dfs_regions dfs_region)
|
||||
{
|
||||
@ -613,13 +490,14 @@ ath12k_reg_adjust_bw(u16 start_freq, u16 end_freq, u16 max_bw)
|
||||
static void
|
||||
ath12k_reg_update_rule(struct ieee80211_reg_rule *reg_rule, u32 start_freq,
|
||||
u32 end_freq, u32 bw, u32 ant_gain, u32 reg_pwr,
|
||||
u32 reg_flags)
|
||||
s8 psd, u32 reg_flags)
|
||||
{
|
||||
reg_rule->freq_range.start_freq_khz = MHZ_TO_KHZ(start_freq);
|
||||
reg_rule->freq_range.end_freq_khz = MHZ_TO_KHZ(end_freq);
|
||||
reg_rule->freq_range.max_bandwidth_khz = MHZ_TO_KHZ(bw);
|
||||
reg_rule->power_rule.max_antenna_gain = DBI_TO_MBI(ant_gain);
|
||||
reg_rule->power_rule.max_eirp = DBM_TO_MBM(reg_pwr);
|
||||
reg_rule->psd = psd;
|
||||
reg_rule->flags = reg_flags;
|
||||
}
|
||||
|
||||
@ -641,7 +519,7 @@ ath12k_reg_update_weather_radar_band(struct ath12k_base *ab,
|
||||
ath12k_reg_update_rule(regd->reg_rules + i, reg_rule->start_freq,
|
||||
ETSI_WEATHER_RADAR_BAND_LOW, bw,
|
||||
reg_rule->ant_gain, reg_rule->reg_power,
|
||||
flags);
|
||||
reg_rule->psd_eirp, flags);
|
||||
|
||||
ath12k_dbg(ab, ATH12K_DBG_REG,
|
||||
"\t%d. (%d - %d @ %d) (%d, %d) (%d ms) (FLAGS %d)\n",
|
||||
@ -663,7 +541,7 @@ ath12k_reg_update_weather_radar_band(struct ath12k_base *ab,
|
||||
ath12k_reg_update_rule(regd->reg_rules + i,
|
||||
ETSI_WEATHER_RADAR_BAND_LOW, end_freq, bw,
|
||||
reg_rule->ant_gain, reg_rule->reg_power,
|
||||
flags);
|
||||
reg_rule->psd_eirp, flags);
|
||||
|
||||
regd->reg_rules[i].dfs_cac_ms = ETSI_WEATHER_RADAR_BAND_CAC_TIMEOUT;
|
||||
|
||||
@ -688,7 +566,7 @@ ath12k_reg_update_weather_radar_band(struct ath12k_base *ab,
|
||||
ath12k_reg_update_rule(regd->reg_rules + i, ETSI_WEATHER_RADAR_BAND_HIGH,
|
||||
reg_rule->end_freq, bw,
|
||||
reg_rule->ant_gain, reg_rule->reg_power,
|
||||
flags);
|
||||
reg_rule->psd_eirp, flags);
|
||||
|
||||
ath12k_dbg(ab, ATH12K_DBG_REG,
|
||||
"\t%d. (%d - %d @ %d) (%d, %d) (%d ms) (FLAGS %d)\n",
|
||||
@ -710,26 +588,67 @@ static void ath12k_reg_update_freq_range(struct ath12k_reg_freq *reg_freq,
|
||||
reg_freq->end_freq = reg_rule->end_freq;
|
||||
}
|
||||
|
||||
enum wmi_reg_6g_ap_type
|
||||
ath12k_reg_ap_pwr_convert(enum ieee80211_ap_reg_power power_type)
|
||||
{
|
||||
switch (power_type) {
|
||||
case IEEE80211_REG_LPI_AP:
|
||||
return WMI_REG_INDOOR_AP;
|
||||
case IEEE80211_REG_SP_AP:
|
||||
return WMI_REG_STD_POWER_AP;
|
||||
case IEEE80211_REG_VLP_AP:
|
||||
return WMI_REG_VLP_AP;
|
||||
default:
|
||||
return WMI_REG_MAX_AP_TYPE;
|
||||
}
|
||||
}
|
||||
|
||||
struct ieee80211_regdomain *
|
||||
ath12k_reg_build_regd(struct ath12k_base *ab,
|
||||
struct ath12k_reg_info *reg_info, bool intersect)
|
||||
struct ath12k_reg_info *reg_info,
|
||||
enum wmi_vdev_type vdev_type,
|
||||
enum ieee80211_ap_reg_power power_type)
|
||||
{
|
||||
struct ieee80211_regdomain *tmp_regd, *default_regd, *new_regd = NULL;
|
||||
struct ath12k_reg_rule *reg_rule;
|
||||
struct ieee80211_regdomain *new_regd = NULL;
|
||||
struct ath12k_reg_rule *reg_rule, *reg_rule_6ghz;
|
||||
u32 flags, reg_6ghz_number, max_bw_6ghz;
|
||||
u8 i = 0, j = 0, k = 0;
|
||||
u8 num_rules;
|
||||
u16 max_bw;
|
||||
u32 flags;
|
||||
char alpha2[3];
|
||||
|
||||
num_rules = reg_info->num_5g_reg_rules + reg_info->num_2g_reg_rules;
|
||||
|
||||
/* FIXME: Currently taking reg rules for 6G only from Indoor AP mode list.
|
||||
* This can be updated to choose the combination dynamically based on AP
|
||||
* type and client type, after complete 6G regulatory support is added.
|
||||
*/
|
||||
if (reg_info->is_ext_reg_event)
|
||||
num_rules += reg_info->num_6g_reg_rules_ap[WMI_REG_INDOOR_AP];
|
||||
if (reg_info->is_ext_reg_event) {
|
||||
if (vdev_type == WMI_VDEV_TYPE_STA) {
|
||||
enum wmi_reg_6g_ap_type ap_type;
|
||||
|
||||
ap_type = ath12k_reg_ap_pwr_convert(power_type);
|
||||
if (ap_type == WMI_REG_MAX_AP_TYPE)
|
||||
ap_type = WMI_REG_INDOOR_AP;
|
||||
|
||||
reg_6ghz_number = reg_info->num_6g_reg_rules_cl
|
||||
[ap_type][WMI_REG_DEFAULT_CLIENT];
|
||||
if (reg_6ghz_number == 0) {
|
||||
ap_type = WMI_REG_INDOOR_AP;
|
||||
reg_6ghz_number = reg_info->num_6g_reg_rules_cl
|
||||
[ap_type][WMI_REG_DEFAULT_CLIENT];
|
||||
}
|
||||
|
||||
reg_rule_6ghz = reg_info->reg_rules_6g_client_ptr
|
||||
[ap_type][WMI_REG_DEFAULT_CLIENT];
|
||||
max_bw_6ghz = reg_info->max_bw_6g_client
|
||||
[ap_type][WMI_REG_DEFAULT_CLIENT];
|
||||
} else {
|
||||
reg_6ghz_number = reg_info->num_6g_reg_rules_ap
|
||||
[WMI_REG_INDOOR_AP];
|
||||
reg_rule_6ghz =
|
||||
reg_info->reg_rules_6g_ap_ptr[WMI_REG_INDOOR_AP];
|
||||
max_bw_6ghz = reg_info->max_bw_6g_ap[WMI_REG_INDOOR_AP];
|
||||
}
|
||||
|
||||
num_rules += reg_6ghz_number;
|
||||
}
|
||||
|
||||
if (!num_rules)
|
||||
goto ret;
|
||||
@ -738,20 +657,20 @@ ath12k_reg_build_regd(struct ath12k_base *ab,
|
||||
if (reg_info->dfs_region == ATH12K_DFS_REG_ETSI)
|
||||
num_rules += 2;
|
||||
|
||||
tmp_regd = kzalloc(sizeof(*tmp_regd) +
|
||||
new_regd = kzalloc(sizeof(*new_regd) +
|
||||
(num_rules * sizeof(struct ieee80211_reg_rule)),
|
||||
GFP_ATOMIC);
|
||||
if (!tmp_regd)
|
||||
if (!new_regd)
|
||||
goto ret;
|
||||
|
||||
memcpy(tmp_regd->alpha2, reg_info->alpha2, REG_ALPHA2_LEN + 1);
|
||||
memcpy(new_regd->alpha2, reg_info->alpha2, REG_ALPHA2_LEN + 1);
|
||||
memcpy(alpha2, reg_info->alpha2, REG_ALPHA2_LEN + 1);
|
||||
alpha2[2] = '\0';
|
||||
tmp_regd->dfs_region = ath12k_map_fw_dfs_region(reg_info->dfs_region);
|
||||
new_regd->dfs_region = ath12k_map_fw_dfs_region(reg_info->dfs_region);
|
||||
|
||||
ath12k_dbg(ab, ATH12K_DBG_REG,
|
||||
"\r\nCountry %s, CFG Regdomain %s FW Regdomain %d, num_reg_rules %d\n",
|
||||
alpha2, ath12k_reg_get_regdom_str(tmp_regd->dfs_region),
|
||||
alpha2, ath12k_reg_get_regdom_str(new_regd->dfs_region),
|
||||
reg_info->dfs_region, num_rules);
|
||||
|
||||
/* Reset start and end frequency for each band
|
||||
@ -788,13 +707,13 @@ ath12k_reg_build_regd(struct ath12k_base *ab,
|
||||
*/
|
||||
flags = NL80211_RRF_AUTO_BW;
|
||||
ath12k_reg_update_freq_range(&ab->reg_freq_5ghz, reg_rule);
|
||||
} else if (reg_info->is_ext_reg_event &&
|
||||
reg_info->num_6g_reg_rules_ap[WMI_REG_INDOOR_AP] &&
|
||||
(k < reg_info->num_6g_reg_rules_ap[WMI_REG_INDOOR_AP])) {
|
||||
reg_rule = reg_info->reg_rules_6g_ap_ptr[WMI_REG_INDOOR_AP] + k++;
|
||||
max_bw = min_t(u16, reg_rule->max_bw,
|
||||
reg_info->max_bw_6g_ap[WMI_REG_INDOOR_AP]);
|
||||
} else if (reg_info->is_ext_reg_event && reg_6ghz_number &&
|
||||
(k < reg_6ghz_number)) {
|
||||
reg_rule = reg_rule_6ghz + k++;
|
||||
max_bw = min_t(u16, reg_rule->max_bw, max_bw_6ghz);
|
||||
flags = NL80211_RRF_AUTO_BW;
|
||||
if (reg_rule->psd_flag)
|
||||
flags |= NL80211_RRF_PSD;
|
||||
ath12k_reg_update_freq_range(&ab->reg_freq_6ghz, reg_rule);
|
||||
} else {
|
||||
break;
|
||||
@ -803,11 +722,11 @@ ath12k_reg_build_regd(struct ath12k_base *ab,
|
||||
flags |= ath12k_map_fw_reg_flags(reg_rule->flags);
|
||||
flags |= ath12k_map_fw_phy_flags(reg_info->phybitmap);
|
||||
|
||||
ath12k_reg_update_rule(tmp_regd->reg_rules + i,
|
||||
ath12k_reg_update_rule(new_regd->reg_rules + i,
|
||||
reg_rule->start_freq,
|
||||
reg_rule->end_freq, max_bw,
|
||||
reg_rule->ant_gain, reg_rule->reg_power,
|
||||
flags);
|
||||
reg_rule->psd_eirp, flags);
|
||||
|
||||
/* Update dfs cac timeout if the dfs domain is ETSI and the
|
||||
* new rule covers weather radar band.
|
||||
@ -818,7 +737,7 @@ ath12k_reg_build_regd(struct ath12k_base *ab,
|
||||
reg_info->dfs_region == ATH12K_DFS_REG_ETSI &&
|
||||
(reg_rule->end_freq > ETSI_WEATHER_RADAR_BAND_LOW &&
|
||||
reg_rule->start_freq < ETSI_WEATHER_RADAR_BAND_HIGH)){
|
||||
ath12k_reg_update_weather_radar_band(ab, tmp_regd,
|
||||
ath12k_reg_update_weather_radar_band(ab, new_regd,
|
||||
reg_rule, &i,
|
||||
flags, max_bw);
|
||||
continue;
|
||||
@ -828,36 +747,19 @@ ath12k_reg_build_regd(struct ath12k_base *ab,
|
||||
ath12k_dbg(ab, ATH12K_DBG_REG, "\t%d. (%d - %d @ %d) (%d, %d) (%d ms) (FLAGS %d) (%d, %d)\n",
|
||||
i + 1, reg_rule->start_freq, reg_rule->end_freq,
|
||||
max_bw, reg_rule->ant_gain, reg_rule->reg_power,
|
||||
tmp_regd->reg_rules[i].dfs_cac_ms,
|
||||
new_regd->reg_rules[i].dfs_cac_ms,
|
||||
flags, reg_rule->psd_flag, reg_rule->psd_eirp);
|
||||
} else {
|
||||
ath12k_dbg(ab, ATH12K_DBG_REG,
|
||||
"\t%d. (%d - %d @ %d) (%d, %d) (%d ms) (FLAGS %d)\n",
|
||||
i + 1, reg_rule->start_freq, reg_rule->end_freq,
|
||||
max_bw, reg_rule->ant_gain, reg_rule->reg_power,
|
||||
tmp_regd->reg_rules[i].dfs_cac_ms,
|
||||
new_regd->reg_rules[i].dfs_cac_ms,
|
||||
flags);
|
||||
}
|
||||
}
|
||||
|
||||
tmp_regd->n_reg_rules = i;
|
||||
|
||||
if (intersect) {
|
||||
default_regd = ab->default_regd[reg_info->phy_id];
|
||||
|
||||
/* Get a new regd by intersecting the received regd with
|
||||
* our default regd.
|
||||
*/
|
||||
new_regd = ath12k_regd_intersect(default_regd, tmp_regd);
|
||||
kfree(tmp_regd);
|
||||
if (!new_regd) {
|
||||
ath12k_warn(ab, "Unable to create intersected regdomain\n");
|
||||
goto ret;
|
||||
}
|
||||
} else {
|
||||
new_regd = tmp_regd;
|
||||
}
|
||||
|
||||
new_regd->n_reg_rules = i;
|
||||
ret:
|
||||
return new_regd;
|
||||
}
|
||||
@ -879,6 +781,105 @@ void ath12k_regd_update_work(struct work_struct *work)
|
||||
}
|
||||
}
|
||||
|
||||
void ath12k_reg_reset_reg_info(struct ath12k_reg_info *reg_info)
|
||||
{
|
||||
u8 i, j;
|
||||
|
||||
if (!reg_info)
|
||||
return;
|
||||
|
||||
kfree(reg_info->reg_rules_2g_ptr);
|
||||
kfree(reg_info->reg_rules_5g_ptr);
|
||||
|
||||
if (reg_info->is_ext_reg_event) {
|
||||
for (i = 0; i < WMI_REG_CURRENT_MAX_AP_TYPE; i++) {
|
||||
kfree(reg_info->reg_rules_6g_ap_ptr[i]);
|
||||
|
||||
for (j = 0; j < WMI_REG_MAX_CLIENT_TYPE; j++)
|
||||
kfree(reg_info->reg_rules_6g_client_ptr[i][j]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
enum ath12k_reg_status ath12k_reg_validate_reg_info(struct ath12k_base *ab,
|
||||
struct ath12k_reg_info *reg_info)
|
||||
{
|
||||
int pdev_idx = reg_info->phy_id;
|
||||
|
||||
if (reg_info->status_code != REG_SET_CC_STATUS_PASS) {
|
||||
/* In case of failure to set the requested country,
|
||||
* firmware retains the current regd. We print a failure info
|
||||
* and return from here.
|
||||
*/
|
||||
ath12k_warn(ab, "Failed to set the requested Country regulatory setting\n");
|
||||
return ATH12K_REG_STATUS_DROP;
|
||||
}
|
||||
|
||||
if (pdev_idx >= ab->num_radios) {
|
||||
/* Process the event for phy0 only if single_pdev_only
|
||||
* is true. If pdev_idx is valid but not 0, discard the
|
||||
* event. Otherwise, it goes to fallback.
|
||||
*/
|
||||
if (ab->hw_params->single_pdev_only &&
|
||||
pdev_idx < ab->hw_params->num_rxdma_per_pdev)
|
||||
return ATH12K_REG_STATUS_DROP;
|
||||
else
|
||||
return ATH12K_REG_STATUS_FALLBACK;
|
||||
}
|
||||
|
||||
/* Avoid multiple overwrites to default regd, during core
|
||||
* stop-start after mac registration.
|
||||
*/
|
||||
if (ab->default_regd[pdev_idx] && !ab->new_regd[pdev_idx] &&
|
||||
!memcmp(ab->default_regd[pdev_idx]->alpha2,
|
||||
reg_info->alpha2, 2))
|
||||
return ATH12K_REG_STATUS_DROP;
|
||||
|
||||
return ATH12K_REG_STATUS_VALID;
|
||||
}
|
||||
|
||||
int ath12k_reg_handle_chan_list(struct ath12k_base *ab,
|
||||
struct ath12k_reg_info *reg_info,
|
||||
enum wmi_vdev_type vdev_type,
|
||||
enum ieee80211_ap_reg_power power_type)
|
||||
{
|
||||
struct ieee80211_regdomain *regd = NULL;
|
||||
int pdev_idx = reg_info->phy_id;
|
||||
struct ath12k *ar;
|
||||
|
||||
regd = ath12k_reg_build_regd(ab, reg_info, vdev_type, power_type);
|
||||
if (!regd)
|
||||
return -EINVAL;
|
||||
|
||||
spin_lock_bh(&ab->base_lock);
|
||||
if (test_bit(ATH12K_FLAG_REGISTERED, &ab->dev_flags)) {
|
||||
/* Once mac is registered, ar is valid and all CC events from
|
||||
* firmware is considered to be received due to user requests
|
||||
* currently.
|
||||
* Free previously built regd before assigning the newly
|
||||
* generated regd to ar. NULL pointer handling will be
|
||||
* taken care by kfree itself.
|
||||
*/
|
||||
ar = ab->pdevs[pdev_idx].ar;
|
||||
kfree(ab->new_regd[pdev_idx]);
|
||||
ab->new_regd[pdev_idx] = regd;
|
||||
queue_work(ab->workqueue, &ar->regd_update_work);
|
||||
} else {
|
||||
/* Multiple events for the same *ar is not expected. But we
|
||||
* can still clear any previously stored default_regd if we
|
||||
* are receiving this event for the same radio by mistake.
|
||||
* NULL pointer handling will be taken care by kfree itself.
|
||||
*/
|
||||
kfree(ab->default_regd[pdev_idx]);
|
||||
/* This regd would be applied during mac registration */
|
||||
ab->default_regd[pdev_idx] = regd;
|
||||
}
|
||||
ab->dfs_region = reg_info->dfs_region;
|
||||
spin_unlock_bh(&ab->base_lock);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void ath12k_reg_init(struct ieee80211_hw *hw)
|
||||
{
|
||||
hw->wiphy->regulatory_flags = REGULATORY_WIPHY_SELF_MANAGED;
|
||||
@ -891,6 +892,12 @@ void ath12k_reg_free(struct ath12k_base *ab)
|
||||
int i;
|
||||
|
||||
mutex_lock(&ab->core_lock);
|
||||
for (i = 0; i < MAX_RADIOS; i++) {
|
||||
ath12k_reg_reset_reg_info(ab->reg_info[i]);
|
||||
kfree(ab->reg_info[i]);
|
||||
ab->reg_info[i] = NULL;
|
||||
}
|
||||
|
||||
for (i = 0; i < ab->hw_params->max_radios; i++) {
|
||||
kfree(ab->default_regd[i]);
|
||||
kfree(ab->new_regd[i]);
|
||||
|
||||
@ -92,13 +92,29 @@ enum ath12k_reg_phy_bitmap {
|
||||
ATH12K_REG_PHY_BITMAP_NO11BE = BIT(6),
|
||||
};
|
||||
|
||||
enum ath12k_reg_status {
|
||||
ATH12K_REG_STATUS_VALID,
|
||||
ATH12K_REG_STATUS_DROP,
|
||||
ATH12K_REG_STATUS_FALLBACK,
|
||||
};
|
||||
|
||||
void ath12k_reg_init(struct ieee80211_hw *hw);
|
||||
void ath12k_reg_free(struct ath12k_base *ab);
|
||||
void ath12k_regd_update_work(struct work_struct *work);
|
||||
struct ieee80211_regdomain *ath12k_reg_build_regd(struct ath12k_base *ab,
|
||||
struct ath12k_reg_info *reg_info,
|
||||
bool intersect);
|
||||
enum wmi_vdev_type vdev_type,
|
||||
enum ieee80211_ap_reg_power power_type);
|
||||
int ath12k_regd_update(struct ath12k *ar, bool init);
|
||||
int ath12k_reg_update_chan_list(struct ath12k *ar, bool wait);
|
||||
|
||||
void ath12k_reg_reset_reg_info(struct ath12k_reg_info *reg_info);
|
||||
int ath12k_reg_handle_chan_list(struct ath12k_base *ab,
|
||||
struct ath12k_reg_info *reg_info,
|
||||
enum wmi_vdev_type vdev_type,
|
||||
enum ieee80211_ap_reg_power power_type);
|
||||
enum wmi_reg_6g_ap_type
|
||||
ath12k_reg_ap_pwr_convert(enum ieee80211_ap_reg_power power_type);
|
||||
enum ath12k_reg_status ath12k_reg_validate_reg_info(struct ath12k_base *ab,
|
||||
struct ath12k_reg_info *reg_info);
|
||||
#endif
|
||||
|
||||
@ -2187,9 +2187,10 @@ int ath12k_wmi_send_peer_assoc_cmd(struct ath12k *ar,
|
||||
struct sk_buff *skb;
|
||||
struct wmi_tlv *tlv;
|
||||
void *ptr;
|
||||
u32 peer_legacy_rates_align;
|
||||
u32 peer_ht_rates_align;
|
||||
u32 peer_legacy_rates_align, eml_pad_delay, eml_trans_delay;
|
||||
u32 peer_ht_rates_align, eml_trans_timeout;
|
||||
int i, ret, len;
|
||||
u16 eml_cap;
|
||||
__le32 v;
|
||||
|
||||
peer_legacy_rates_align = roundup(arg->peer_legacy_rates.num_rates,
|
||||
@ -2361,6 +2362,24 @@ int ath12k_wmi_send_peer_assoc_cmd(struct ath12k *ar,
|
||||
ml_params->logical_link_idx = cpu_to_le32(arg->ml.logical_link_idx);
|
||||
ml_params->ml_peer_id = cpu_to_le32(arg->ml.ml_peer_id);
|
||||
ml_params->ieee_link_id = cpu_to_le32(arg->ml.ieee_link_id);
|
||||
|
||||
eml_cap = arg->ml.eml_cap;
|
||||
if (u16_get_bits(eml_cap, IEEE80211_EML_CAP_EMLSR_SUPP)) {
|
||||
/* Padding delay */
|
||||
eml_pad_delay = ieee80211_emlsr_pad_delay_in_us(eml_cap);
|
||||
ml_params->emlsr_padding_delay_us = cpu_to_le32(eml_pad_delay);
|
||||
/* Transition delay */
|
||||
eml_trans_delay = ieee80211_emlsr_trans_delay_in_us(eml_cap);
|
||||
ml_params->emlsr_trans_delay_us = cpu_to_le32(eml_trans_delay);
|
||||
/* Transition timeout */
|
||||
eml_trans_timeout = ieee80211_eml_trans_timeout_in_us(eml_cap);
|
||||
ml_params->emlsr_trans_timeout_us =
|
||||
cpu_to_le32(eml_trans_timeout);
|
||||
ath12k_dbg(ar->ab, ATH12K_DBG_WMI, "wmi peer %pM emlsr padding delay %u, trans delay %u trans timeout %u",
|
||||
arg->peer_mac, eml_pad_delay, eml_trans_delay,
|
||||
eml_trans_timeout);
|
||||
}
|
||||
|
||||
ptr += sizeof(*ml_params);
|
||||
|
||||
skip_ml_params:
|
||||
@ -2380,6 +2399,10 @@ int ath12k_wmi_send_peer_assoc_cmd(struct ath12k *ar,
|
||||
ptr += sizeof(*eht_mcs);
|
||||
}
|
||||
|
||||
/* Update MCS15 capability */
|
||||
if (arg->eht_disable_mcs15)
|
||||
cmd->peer_eht_ops = cpu_to_le32(IEEE80211_EHT_OPER_MCS15_DISABLE);
|
||||
|
||||
tlv = ptr;
|
||||
len = arg->ml.enabled ? arg->ml.num_partner_links * sizeof(*partner_info) : 0;
|
||||
/* fill ML Partner links */
|
||||
@ -2420,7 +2443,7 @@ int ath12k_wmi_send_peer_assoc_cmd(struct ath12k *ar,
|
||||
|
||||
send:
|
||||
ath12k_dbg(ar->ab, ATH12K_DBG_WMI,
|
||||
"wmi peer assoc vdev id %d assoc id %d peer mac %pM peer_flags %x rate_caps %x peer_caps %x listen_intval %d ht_caps %x max_mpdu %d nss %d phymode %d peer_mpdu_density %d vht_caps %x he cap_info %x he ops %x he cap_info_ext %x he phy %x %x %x peer_bw_rxnss_override %x peer_flags_ext %x eht mac_cap %x %x eht phy_cap %x %x %x\n",
|
||||
"wmi peer assoc vdev id %d assoc id %d peer mac %pM peer_flags %x rate_caps %x peer_caps %x listen_intval %d ht_caps %x max_mpdu %d nss %d phymode %d peer_mpdu_density %d vht_caps %x he cap_info %x he ops %x he cap_info_ext %x he phy %x %x %x peer_bw_rxnss_override %x peer_flags_ext %x eht mac_cap %x %x eht phy_cap %x %x %x peer_eht_ops %x\n",
|
||||
cmd->vdev_id, cmd->peer_associd, arg->peer_mac,
|
||||
cmd->peer_flags, cmd->peer_rate_caps, cmd->peer_caps,
|
||||
cmd->peer_listen_intval, cmd->peer_ht_caps,
|
||||
@ -2433,7 +2456,7 @@ int ath12k_wmi_send_peer_assoc_cmd(struct ath12k *ar,
|
||||
cmd->peer_bw_rxnss_override, cmd->peer_flags_ext,
|
||||
cmd->peer_eht_cap_mac[0], cmd->peer_eht_cap_mac[1],
|
||||
cmd->peer_eht_cap_phy[0], cmd->peer_eht_cap_phy[1],
|
||||
cmd->peer_eht_cap_phy[2]);
|
||||
cmd->peer_eht_cap_phy[2], cmd->peer_eht_ops);
|
||||
|
||||
ret = ath12k_wmi_cmd_send(wmi, skb, WMI_PEER_ASSOC_CMDID);
|
||||
if (ret) {
|
||||
@ -4733,6 +4756,7 @@ static int ath12k_service_ready_ext_event(struct ath12k_base *ab,
|
||||
return 0;
|
||||
|
||||
err:
|
||||
kfree(svc_rdy_ext.mac_phy_caps);
|
||||
ath12k_wmi_free_dbring_caps(ab);
|
||||
return ret;
|
||||
}
|
||||
@ -6101,6 +6125,7 @@ static int ath12k_reg_11d_new_cc_event(struct ath12k_base *ab, struct sk_buff *s
|
||||
pdev = &ab->pdevs[i];
|
||||
ar = pdev->ar;
|
||||
ar->state_11d = ATH12K_11D_IDLE;
|
||||
ar->ah->regd_updated = false;
|
||||
complete(&ar->completed_11d_scan);
|
||||
}
|
||||
|
||||
@ -6115,24 +6140,11 @@ static void ath12k_wmi_htc_tx_complete(struct ath12k_base *ab,
|
||||
dev_kfree_skb(skb);
|
||||
}
|
||||
|
||||
static bool ath12k_reg_is_world_alpha(char *alpha)
|
||||
{
|
||||
if (alpha[0] == '0' && alpha[1] == '0')
|
||||
return true;
|
||||
|
||||
if (alpha[0] == 'n' && alpha[1] == 'a')
|
||||
return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
static int ath12k_reg_chan_list_event(struct ath12k_base *ab, struct sk_buff *skb)
|
||||
{
|
||||
struct ath12k_reg_info *reg_info = NULL;
|
||||
struct ieee80211_regdomain *regd = NULL;
|
||||
bool intersect = false;
|
||||
int ret = 0, pdev_idx, i, j;
|
||||
struct ath12k *ar;
|
||||
struct ath12k_reg_info *reg_info;
|
||||
u8 pdev_idx;
|
||||
int ret;
|
||||
|
||||
reg_info = kzalloc(sizeof(*reg_info), GFP_ATOMIC);
|
||||
if (!reg_info) {
|
||||
@ -6141,86 +6153,52 @@ static int ath12k_reg_chan_list_event(struct ath12k_base *ab, struct sk_buff *sk
|
||||
}
|
||||
|
||||
ret = ath12k_pull_reg_chan_list_ext_update_ev(ab, skb, reg_info);
|
||||
|
||||
if (ret) {
|
||||
ath12k_warn(ab, "failed to extract regulatory info from received event\n");
|
||||
goto fallback;
|
||||
}
|
||||
|
||||
if (reg_info->status_code != REG_SET_CC_STATUS_PASS) {
|
||||
/* In case of failure to set the requested ctry,
|
||||
* fw retains the current regd. We print a failure info
|
||||
* and return from here.
|
||||
*/
|
||||
ath12k_warn(ab, "Failed to set the requested Country regulatory setting\n");
|
||||
goto mem_free;
|
||||
}
|
||||
|
||||
ret = ath12k_reg_validate_reg_info(ab, reg_info);
|
||||
if (ret == ATH12K_REG_STATUS_FALLBACK) {
|
||||
ath12k_warn(ab, "failed to validate reg info %d\n", ret);
|
||||
/* firmware has successfully switches to new regd but host can not
|
||||
* continue, so free reginfo and fallback to old regd
|
||||
*/
|
||||
goto mem_free;
|
||||
} else if (ret == ATH12K_REG_STATUS_DROP) {
|
||||
/* reg info is valid but we will not store it and
|
||||
* not going to create new regd for it
|
||||
*/
|
||||
ret = ATH12K_REG_STATUS_VALID;
|
||||
goto mem_free;
|
||||
}
|
||||
|
||||
/* free old reg_info if it exist */
|
||||
pdev_idx = reg_info->phy_id;
|
||||
|
||||
if (pdev_idx >= ab->num_radios) {
|
||||
/* Process the event for phy0 only if single_pdev_only
|
||||
* is true. If pdev_idx is valid but not 0, discard the
|
||||
* event. Otherwise, it goes to fallback.
|
||||
*/
|
||||
if (ab->hw_params->single_pdev_only &&
|
||||
pdev_idx < ab->hw_params->num_rxdma_per_pdev)
|
||||
goto mem_free;
|
||||
else
|
||||
goto fallback;
|
||||
if (ab->reg_info[pdev_idx]) {
|
||||
ath12k_reg_reset_reg_info(ab->reg_info[pdev_idx]);
|
||||
kfree(ab->reg_info[pdev_idx]);
|
||||
}
|
||||
|
||||
/* Avoid multiple overwrites to default regd, during core
|
||||
* stop-start after mac registration.
|
||||
/* reg_info is valid, we store it for later use
|
||||
* even below regd build failed
|
||||
*/
|
||||
if (ab->default_regd[pdev_idx] && !ab->new_regd[pdev_idx] &&
|
||||
!memcmp(ab->default_regd[pdev_idx]->alpha2,
|
||||
reg_info->alpha2, 2))
|
||||
goto mem_free;
|
||||
ab->reg_info[pdev_idx] = reg_info;
|
||||
|
||||
/* Intersect new rules with default regd if a new country setting was
|
||||
* requested, i.e a default regd was already set during initialization
|
||||
* and the regd coming from this event has a valid country info.
|
||||
*/
|
||||
if (ab->default_regd[pdev_idx] &&
|
||||
!ath12k_reg_is_world_alpha((char *)
|
||||
ab->default_regd[pdev_idx]->alpha2) &&
|
||||
!ath12k_reg_is_world_alpha((char *)reg_info->alpha2))
|
||||
intersect = true;
|
||||
|
||||
regd = ath12k_reg_build_regd(ab, reg_info, intersect);
|
||||
if (!regd) {
|
||||
ath12k_warn(ab, "failed to build regd from reg_info\n");
|
||||
ret = ath12k_reg_handle_chan_list(ab, reg_info, WMI_VDEV_TYPE_UNSPEC,
|
||||
IEEE80211_REG_UNSET_AP);
|
||||
if (ret) {
|
||||
ath12k_warn(ab, "failed to handle chan list %d\n", ret);
|
||||
goto fallback;
|
||||
}
|
||||
|
||||
spin_lock(&ab->base_lock);
|
||||
if (test_bit(ATH12K_FLAG_REGISTERED, &ab->dev_flags)) {
|
||||
/* Once mac is registered, ar is valid and all CC events from
|
||||
* fw is considered to be received due to user requests
|
||||
* currently.
|
||||
* Free previously built regd before assigning the newly
|
||||
* generated regd to ar. NULL pointer handling will be
|
||||
* taken care by kfree itself.
|
||||
*/
|
||||
ar = ab->pdevs[pdev_idx].ar;
|
||||
kfree(ab->new_regd[pdev_idx]);
|
||||
ab->new_regd[pdev_idx] = regd;
|
||||
queue_work(ab->workqueue, &ar->regd_update_work);
|
||||
} else {
|
||||
/* Multiple events for the same *ar is not expected. But we
|
||||
* can still clear any previously stored default_regd if we
|
||||
* are receiving this event for the same radio by mistake.
|
||||
* NULL pointer handling will be taken care by kfree itself.
|
||||
*/
|
||||
kfree(ab->default_regd[pdev_idx]);
|
||||
/* This regd would be applied during mac registration */
|
||||
ab->default_regd[pdev_idx] = regd;
|
||||
}
|
||||
ab->dfs_region = reg_info->dfs_region;
|
||||
spin_unlock(&ab->base_lock);
|
||||
goto out;
|
||||
|
||||
goto mem_free;
|
||||
mem_free:
|
||||
ath12k_reg_reset_reg_info(reg_info);
|
||||
kfree(reg_info);
|
||||
|
||||
if (ret == ATH12K_REG_STATUS_VALID)
|
||||
return ret;
|
||||
|
||||
fallback:
|
||||
/* Fallback to older reg (by sending previous country setting
|
||||
@ -6232,20 +6210,8 @@ static int ath12k_reg_chan_list_event(struct ath12k_base *ab, struct sk_buff *sk
|
||||
*/
|
||||
/* TODO: This is rare, but still should also be handled */
|
||||
WARN_ON(1);
|
||||
mem_free:
|
||||
if (reg_info) {
|
||||
kfree(reg_info->reg_rules_2g_ptr);
|
||||
kfree(reg_info->reg_rules_5g_ptr);
|
||||
if (reg_info->is_ext_reg_event) {
|
||||
for (i = 0; i < WMI_REG_CURRENT_MAX_AP_TYPE; i++)
|
||||
kfree(reg_info->reg_rules_6g_ap_ptr[i]);
|
||||
|
||||
for (j = 0; j < WMI_REG_CURRENT_MAX_AP_TYPE; j++)
|
||||
for (i = 0; i < WMI_REG_MAX_CLIENT_TYPE; i++)
|
||||
kfree(reg_info->reg_rules_6g_client_ptr[j][i]);
|
||||
}
|
||||
kfree(reg_info);
|
||||
}
|
||||
out:
|
||||
return ret;
|
||||
}
|
||||
|
||||
@ -6401,13 +6367,14 @@ static void ath12k_vdev_start_resp_event(struct ath12k_base *ab, struct sk_buff
|
||||
ar->last_wmi_vdev_start_status = 0;
|
||||
|
||||
status = le32_to_cpu(vdev_start_resp.status);
|
||||
|
||||
if (WARN_ON_ONCE(status)) {
|
||||
ath12k_warn(ab, "vdev start resp error status %d (%s)\n",
|
||||
status, ath12k_wmi_vdev_resp_print(status));
|
||||
ar->last_wmi_vdev_start_status = status;
|
||||
}
|
||||
|
||||
ar->max_allowed_tx_power = (s8)le32_to_cpu(vdev_start_resp.max_allowed_tx_power);
|
||||
|
||||
complete(&ar->vdev_setup_done);
|
||||
|
||||
rcu_read_unlock();
|
||||
@ -9878,3 +9845,69 @@ int ath12k_wmi_mlo_teardown(struct ath12k *ar)
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
bool ath12k_wmi_supports_6ghz_cc_ext(struct ath12k *ar)
|
||||
{
|
||||
return test_bit(WMI_TLV_SERVICE_REG_CC_EXT_EVENT_SUPPORT,
|
||||
ar->ab->wmi_ab.svc_map) && ar->supports_6ghz;
|
||||
}
|
||||
|
||||
int ath12k_wmi_send_vdev_set_tpc_power(struct ath12k *ar,
|
||||
u32 vdev_id,
|
||||
struct ath12k_reg_tpc_power_info *param)
|
||||
{
|
||||
struct wmi_vdev_set_tpc_power_cmd *cmd;
|
||||
struct ath12k_wmi_pdev *wmi = ar->wmi;
|
||||
struct wmi_vdev_ch_power_params *ch;
|
||||
int i, ret, len, array_len;
|
||||
struct sk_buff *skb;
|
||||
struct wmi_tlv *tlv;
|
||||
u8 *ptr;
|
||||
|
||||
array_len = sizeof(*ch) * param->num_pwr_levels;
|
||||
len = sizeof(*cmd) + TLV_HDR_SIZE + array_len;
|
||||
|
||||
skb = ath12k_wmi_alloc_skb(wmi->wmi_ab, len);
|
||||
if (!skb)
|
||||
return -ENOMEM;
|
||||
|
||||
ptr = skb->data;
|
||||
|
||||
cmd = (struct wmi_vdev_set_tpc_power_cmd *)ptr;
|
||||
cmd->tlv_header = ath12k_wmi_tlv_cmd_hdr(WMI_TAG_VDEV_SET_TPC_POWER_CMD,
|
||||
sizeof(*cmd));
|
||||
cmd->vdev_id = cpu_to_le32(vdev_id);
|
||||
cmd->psd_power = cpu_to_le32(param->is_psd_power);
|
||||
cmd->eirp_power = cpu_to_le32(param->eirp_power);
|
||||
cmd->power_type_6ghz = cpu_to_le32(param->ap_power_type);
|
||||
|
||||
ath12k_dbg(ar->ab, ATH12K_DBG_WMI,
|
||||
"tpc vdev id %d is psd power %d eirp power %d 6 ghz power type %d\n",
|
||||
vdev_id, param->is_psd_power, param->eirp_power, param->ap_power_type);
|
||||
|
||||
ptr += sizeof(*cmd);
|
||||
tlv = (struct wmi_tlv *)ptr;
|
||||
tlv->header = ath12k_wmi_tlv_hdr(WMI_TAG_ARRAY_STRUCT, array_len);
|
||||
|
||||
ptr += TLV_HDR_SIZE;
|
||||
ch = (struct wmi_vdev_ch_power_params *)ptr;
|
||||
|
||||
for (i = 0; i < param->num_pwr_levels; i++, ch++) {
|
||||
ch->tlv_header = ath12k_wmi_tlv_cmd_hdr(WMI_TAG_VDEV_CH_POWER_INFO,
|
||||
sizeof(*ch));
|
||||
ch->chan_cfreq = cpu_to_le32(param->chan_power_info[i].chan_cfreq);
|
||||
ch->tx_power = cpu_to_le32(param->chan_power_info[i].tx_power);
|
||||
|
||||
ath12k_dbg(ar->ab, ATH12K_DBG_WMI, "tpc chan freq %d TX power %d\n",
|
||||
ch->chan_cfreq, ch->tx_power);
|
||||
}
|
||||
|
||||
ret = ath12k_wmi_cmd_send(wmi, skb, WMI_VDEV_SET_TPC_POWER_CMDID);
|
||||
if (ret) {
|
||||
ath12k_warn(ar->ab, "failed to send WMI_VDEV_SET_TPC_POWER_CMDID\n");
|
||||
dev_kfree_skb(skb);
|
||||
return ret;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -26,6 +26,7 @@ struct ath12k_base;
|
||||
struct ath12k;
|
||||
struct ath12k_link_vif;
|
||||
struct ath12k_fw_stats;
|
||||
struct ath12k_reg_tpc_power_info;
|
||||
|
||||
/* There is no signed version of __le32, so for a temporary solution come
|
||||
* up with our own version. The idea is from fs/ntfs/endian.h.
|
||||
@ -386,6 +387,22 @@ enum wmi_tlv_cmd_id {
|
||||
WMI_VDEV_SET_CUSTOM_AGGR_SIZE_CMDID,
|
||||
WMI_VDEV_ENCRYPT_DECRYPT_DATA_REQ_CMDID,
|
||||
WMI_VDEV_ADD_MAC_ADDR_TO_RX_FILTER_CMDID,
|
||||
WMI_VDEV_SET_ARP_STAT_CMDID,
|
||||
WMI_VDEV_GET_ARP_STAT_CMDID,
|
||||
WMI_VDEV_GET_TX_POWER_CMDID,
|
||||
WMI_VDEV_LIMIT_OFFCHAN_CMDID,
|
||||
WMI_VDEV_SET_CUSTOM_SW_RETRY_TH_CMDID,
|
||||
WMI_VDEV_CHAINMASK_CONFIG_CMDID,
|
||||
WMI_VDEV_GET_BCN_RECEPTION_STATS_CMDID,
|
||||
WMI_VDEV_GET_MWS_COEX_INFO_CMDID,
|
||||
WMI_VDEV_DELETE_ALL_PEER_CMDID,
|
||||
WMI_VDEV_BSS_MAX_IDLE_TIME_CMDID,
|
||||
WMI_VDEV_AUDIO_SYNC_TRIGGER_CMDID,
|
||||
WMI_VDEV_AUDIO_SYNC_QTIMER_CMDID,
|
||||
WMI_VDEV_SET_PCL_CMDID,
|
||||
WMI_VDEV_GET_BIG_DATA_CMDID,
|
||||
WMI_VDEV_GET_BIG_DATA_P2_CMDID,
|
||||
WMI_VDEV_SET_TPC_POWER_CMDID,
|
||||
WMI_PEER_CREATE_CMDID = WMI_TLV_CMD(WMI_GRP_PEER),
|
||||
WMI_PEER_DELETE_CMDID,
|
||||
WMI_PEER_FLUSH_TIDS_CMDID,
|
||||
@ -1955,6 +1972,8 @@ enum wmi_tlv_tag {
|
||||
WMI_TAG_TPC_STATS_REG_PWR_ALLOWED,
|
||||
WMI_TAG_TPC_STATS_RATES_ARRAY,
|
||||
WMI_TAG_TPC_STATS_CTL_PWR_TABLE_EVENT,
|
||||
WMI_TAG_VDEV_SET_TPC_POWER_CMD = 0x3B5,
|
||||
WMI_TAG_VDEV_CH_POWER_INFO,
|
||||
WMI_TAG_EHT_RATE_SET = 0x3C4,
|
||||
WMI_TAG_DCS_AWGN_INT_TYPE = 0x3C5,
|
||||
WMI_TAG_MLO_TX_SEND_PARAMS,
|
||||
@ -2201,6 +2220,8 @@ enum wmi_tlv_service {
|
||||
|
||||
WMI_MAX_EXT_SERVICE = 256,
|
||||
|
||||
WMI_TLV_SERVICE_EXT_TPC_REG_SUPPORT = 280,
|
||||
|
||||
WMI_TLV_SERVICE_REG_CC_EXT_EVENT_SUPPORT = 281,
|
||||
|
||||
WMI_TLV_SERVICE_11BE = 289,
|
||||
@ -3755,6 +3776,7 @@ struct peer_assoc_mlo_params {
|
||||
u32 ieee_link_id;
|
||||
u8 num_partner_links;
|
||||
struct wmi_ml_partner_info partner_info[ATH12K_WMI_MLO_MAX_LINKS];
|
||||
u16 eml_cap;
|
||||
};
|
||||
|
||||
struct wmi_rate_set_arg {
|
||||
@ -3833,6 +3855,7 @@ struct ath12k_wmi_peer_assoc_arg {
|
||||
u32 punct_bitmap;
|
||||
bool is_assoc;
|
||||
struct peer_assoc_mlo_params ml;
|
||||
bool eht_disable_mcs15;
|
||||
};
|
||||
|
||||
#define ATH12K_WMI_FLAG_MLO_ENABLED BIT(0)
|
||||
@ -4162,6 +4185,7 @@ struct wmi_vdev_start_resp_event {
|
||||
};
|
||||
__le32 cfgd_tx_streams;
|
||||
__le32 cfgd_rx_streams;
|
||||
__le32 max_allowed_tx_power;
|
||||
} __packed;
|
||||
|
||||
/* VDEV start response status codes */
|
||||
@ -4507,6 +4531,7 @@ struct ath12k_wmi_target_cap_arg {
|
||||
};
|
||||
|
||||
enum wmi_vdev_type {
|
||||
WMI_VDEV_TYPE_UNSPEC = 0,
|
||||
WMI_VDEV_TYPE_AP = 1,
|
||||
WMI_VDEV_TYPE_STA = 2,
|
||||
WMI_VDEV_TYPE_IBSS = 3,
|
||||
@ -5937,6 +5962,41 @@ struct wmi_tpc_stats_arg {
|
||||
struct wmi_tpc_ctl_pwr_table_arg ctl_array;
|
||||
};
|
||||
|
||||
struct wmi_vdev_ch_power_params {
|
||||
__le32 tlv_header;
|
||||
|
||||
/* Channel center frequency (MHz) */
|
||||
__le32 chan_cfreq;
|
||||
|
||||
/* Unit: dBm, either PSD/EIRP power for this frequency or
|
||||
* incremental for non-PSD BW
|
||||
*/
|
||||
__le32 tx_power;
|
||||
} __packed;
|
||||
|
||||
struct wmi_vdev_set_tpc_power_cmd {
|
||||
__le32 tlv_header;
|
||||
__le32 vdev_id;
|
||||
|
||||
/* Value: 0 or 1, is PSD power or not */
|
||||
__le32 psd_power;
|
||||
|
||||
/* Maximum EIRP power (dBm units), valid only if power is PSD */
|
||||
__le32 eirp_power;
|
||||
|
||||
/* Type: WMI_6GHZ_REG_TYPE, used for halphy CTL lookup */
|
||||
__le32 power_type_6ghz;
|
||||
|
||||
/* This fixed_param TLV is followed by the below TLVs:
|
||||
* num_pwr_levels of wmi_vdev_ch_power_info
|
||||
* For PSD power, it is the PSD/EIRP power of the frequency (20 MHz chunks).
|
||||
* For non-PSD power, the power values are for 20, 40, and till
|
||||
* BSS BW power levels.
|
||||
* The num_pwr_levels will be checked by sw how many elements present
|
||||
* in the variable-length array.
|
||||
*/
|
||||
} __packed;
|
||||
|
||||
void ath12k_wmi_init_qcn9274(struct ath12k_base *ab,
|
||||
struct ath12k_wmi_resource_config_arg *config);
|
||||
void ath12k_wmi_init_wcn7850(struct ath12k_base *ab,
|
||||
@ -6131,5 +6191,9 @@ int ath12k_wmi_mlo_teardown(struct ath12k *ar);
|
||||
void ath12k_wmi_fw_stats_dump(struct ath12k *ar,
|
||||
struct ath12k_fw_stats *fw_stats, u32 stats_id,
|
||||
char *buf);
|
||||
bool ath12k_wmi_supports_6ghz_cc_ext(struct ath12k *ar);
|
||||
int ath12k_wmi_send_vdev_set_tpc_power(struct ath12k *ar,
|
||||
u32 vdev_id,
|
||||
struct ath12k_reg_tpc_power_info *param);
|
||||
|
||||
#endif
|
||||
|
||||
@ -74,7 +74,6 @@ static int ath_ahb_probe(struct platform_device *pdev)
|
||||
void __iomem *mem;
|
||||
struct ath_softc *sc;
|
||||
struct ieee80211_hw *hw;
|
||||
struct resource *res;
|
||||
const struct platform_device_id *id = platform_get_device_id(pdev);
|
||||
int irq;
|
||||
int ret = 0;
|
||||
@ -86,16 +85,10 @@ static int ath_ahb_probe(struct platform_device *pdev)
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
|
||||
if (res == NULL) {
|
||||
dev_err(&pdev->dev, "no memory resource found\n");
|
||||
return -ENXIO;
|
||||
}
|
||||
|
||||
mem = devm_ioremap(&pdev->dev, res->start, resource_size(res));
|
||||
if (mem == NULL) {
|
||||
mem = devm_platform_ioremap_resource(pdev, 0);
|
||||
if (IS_ERR(mem)) {
|
||||
dev_err(&pdev->dev, "ioremap failed\n");
|
||||
return -ENOMEM;
|
||||
return PTR_ERR(mem);
|
||||
}
|
||||
|
||||
irq = platform_get_irq(pdev, 0);
|
||||
|
||||
@ -290,6 +290,9 @@ void ath9k_htc_swba(struct ath9k_htc_priv *priv,
|
||||
struct ath_common *common = ath9k_hw_common(priv->ah);
|
||||
int slot;
|
||||
|
||||
if (!priv->cur_beacon_conf.enable_beacon)
|
||||
return;
|
||||
|
||||
if (swba->beacon_pending != 0) {
|
||||
priv->beacon.bmisscnt++;
|
||||
if (priv->beacon.bmisscnt > BSTUCK_THRESHOLD) {
|
||||
|
||||
@ -366,8 +366,7 @@ static void carl9170_tx_shift_bm(struct ar9170 *ar,
|
||||
if (WARN_ON_ONCE(off >= CARL9170_BAW_BITS))
|
||||
return;
|
||||
|
||||
if (!bitmap_empty(tid_info->bitmap, off))
|
||||
off = find_first_bit(tid_info->bitmap, off);
|
||||
off = min(off, find_first_bit(tid_info->bitmap, off));
|
||||
|
||||
tid_info->bsn += off;
|
||||
tid_info->bsn &= 0x0fff;
|
||||
|
||||
@ -617,8 +617,7 @@ static inline bool wil_need_txstat(struct sk_buff *skb)
|
||||
{
|
||||
const u8 *da = wil_skb_get_da(skb);
|
||||
|
||||
return is_unicast_ether_addr(da) && skb->sk &&
|
||||
sock_flag(skb->sk, SOCK_WIFI_STATUS);
|
||||
return is_unicast_ether_addr(da) && sk_requests_wifi_status(skb->sk);
|
||||
}
|
||||
|
||||
static inline void wil_consume_skb(struct sk_buff *skb, bool acked)
|
||||
|
||||
@ -74,7 +74,6 @@
|
||||
#define VNDR_IE_HDR_SIZE 12
|
||||
#define VNDR_IE_PARSE_LIMIT 5
|
||||
|
||||
#define DOT11_MGMT_HDR_LEN 24 /* d11 management header len */
|
||||
#define DOT11_BCN_PRB_FIXED_LEN 12 /* beacon/probe fixed length */
|
||||
|
||||
#define BRCMF_SCAN_JOIN_ACTIVE_DWELL_TIME_MS 320
|
||||
@ -1945,17 +1944,22 @@ static s32 brcmf_set_wpa_version(struct net_device *ndev,
|
||||
struct brcmf_cfg80211_profile *profile = ndev_to_prof(ndev);
|
||||
struct brcmf_pub *drvr = ifp->drvr;
|
||||
struct brcmf_cfg80211_security *sec;
|
||||
s32 val = 0;
|
||||
s32 err = 0;
|
||||
s32 val;
|
||||
s32 err;
|
||||
|
||||
if (sme->crypto.wpa_versions & NL80211_WPA_VERSION_1)
|
||||
if (sme->crypto.wpa_versions & NL80211_WPA_VERSION_1) {
|
||||
val = WPA_AUTH_PSK | WPA_AUTH_UNSPECIFIED;
|
||||
else if (sme->crypto.wpa_versions & NL80211_WPA_VERSION_2)
|
||||
val = WPA2_AUTH_PSK | WPA2_AUTH_UNSPECIFIED;
|
||||
else if (sme->crypto.wpa_versions & NL80211_WPA_VERSION_3)
|
||||
} else if (sme->crypto.wpa_versions & NL80211_WPA_VERSION_2) {
|
||||
if (drvr->bus_if->fwvid == BRCMF_FWVENDOR_CYW &&
|
||||
sme->crypto.akm_suites[0] == WLAN_AKM_SUITE_SAE)
|
||||
val = WPA3_AUTH_SAE_PSK;
|
||||
else
|
||||
val = WPA2_AUTH_PSK | WPA2_AUTH_UNSPECIFIED;
|
||||
} else if (sme->crypto.wpa_versions & NL80211_WPA_VERSION_3) {
|
||||
val = WPA3_AUTH_SAE_PSK;
|
||||
else
|
||||
} else {
|
||||
val = WPA_AUTH_DISABLED;
|
||||
}
|
||||
brcmf_dbg(CONN, "setting wpa_auth to 0x%0x\n", val);
|
||||
err = brcmf_fil_bsscfg_int_set(ifp, "wpa_auth", val);
|
||||
if (err) {
|
||||
@ -2163,28 +2167,25 @@ brcmf_set_key_mgmt(struct net_device *ndev, struct cfg80211_connect_params *sme)
|
||||
switch (sme->crypto.akm_suites[0]) {
|
||||
case WLAN_AKM_SUITE_SAE:
|
||||
val = WPA3_AUTH_SAE_PSK;
|
||||
if (sme->crypto.sae_pwd) {
|
||||
brcmf_dbg(INFO, "using SAE offload\n");
|
||||
profile->use_fwsup = BRCMF_PROFILE_FWSUP_SAE;
|
||||
}
|
||||
break;
|
||||
case WLAN_AKM_SUITE_FT_OVER_SAE:
|
||||
val = WPA3_AUTH_SAE_PSK | WPA2_AUTH_FT;
|
||||
profile->is_ft = true;
|
||||
if (sme->crypto.sae_pwd) {
|
||||
brcmf_dbg(INFO, "using SAE offload\n");
|
||||
profile->use_fwsup = BRCMF_PROFILE_FWSUP_SAE;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
bphy_err(drvr, "invalid akm suite (%d)\n",
|
||||
sme->crypto.akm_suites[0]);
|
||||
return -EINVAL;
|
||||
}
|
||||
if (sme->crypto.sae_pwd) {
|
||||
profile->use_fwsup = BRCMF_PROFILE_FWSUP_SAE;
|
||||
}
|
||||
}
|
||||
|
||||
if (profile->use_fwsup == BRCMF_PROFILE_FWSUP_1X)
|
||||
brcmf_dbg(INFO, "using 1X offload\n");
|
||||
if (profile->use_fwsup == BRCMF_PROFILE_FWSUP_SAE)
|
||||
brcmf_dbg(INFO, "using SAE offload\n");
|
||||
|
||||
if (!brcmf_feat_is_enabled(ifp, BRCMF_FEAT_MFP))
|
||||
goto skip_mfp_config;
|
||||
@ -2221,7 +2222,7 @@ brcmf_set_key_mgmt(struct net_device *ndev, struct cfg80211_connect_params *sme)
|
||||
brcmf_fil_bsscfg_int_set(netdev_priv(ndev), "mfp", mfp);
|
||||
|
||||
skip_mfp_config:
|
||||
brcmf_dbg(CONN, "setting wpa_auth to %d\n", val);
|
||||
brcmf_dbg(CONN, "setting wpa_auth to 0x%0x\n", val);
|
||||
err = brcmf_fil_bsscfg_int_set(netdev_priv(ndev), "wpa_auth", val);
|
||||
if (err) {
|
||||
bphy_err(drvr, "could not set wpa_auth (%d)\n", err);
|
||||
@ -5509,7 +5510,7 @@ brcmf_cfg80211_update_mgmt_frame_registrations(struct wiphy *wiphy,
|
||||
}
|
||||
|
||||
|
||||
static int
|
||||
int
|
||||
brcmf_cfg80211_mgmt_tx(struct wiphy *wiphy, struct wireless_dev *wdev,
|
||||
struct cfg80211_mgmt_tx_params *params, u64 *cookie)
|
||||
{
|
||||
@ -5616,6 +5617,7 @@ brcmf_cfg80211_mgmt_tx(struct wiphy *wiphy, struct wireless_dev *wdev,
|
||||
exit:
|
||||
return err;
|
||||
}
|
||||
BRCMF_EXPORT_SYMBOL_GPL(brcmf_cfg80211_mgmt_tx);
|
||||
|
||||
static int brcmf_cfg80211_set_cqm_rssi_range_config(struct wiphy *wiphy,
|
||||
struct net_device *ndev,
|
||||
@ -6009,6 +6011,7 @@ struct brcmf_cfg80211_vif *brcmf_alloc_vif(struct brcmf_cfg80211_info *cfg,
|
||||
|
||||
vif->wdev.wiphy = cfg->wiphy;
|
||||
vif->wdev.iftype = type;
|
||||
init_completion(&vif->mgmt_tx);
|
||||
|
||||
brcmf_init_prof(&vif->profile);
|
||||
|
||||
@ -6760,6 +6763,8 @@ static void brcmf_register_event_handlers(struct brcmf_cfg80211_info *cfg)
|
||||
brcmf_fweh_register(cfg->pub, BRCMF_E_PSK_SUP,
|
||||
brcmf_notify_connect_status);
|
||||
brcmf_fweh_register(cfg->pub, BRCMF_E_RSSI, brcmf_notify_rssi);
|
||||
|
||||
brcmf_fwvid_register_event_handlers(cfg->pub);
|
||||
}
|
||||
|
||||
static void brcmf_deinit_priv_mem(struct brcmf_cfg80211_info *cfg)
|
||||
@ -7346,6 +7351,7 @@ brcmf_txrx_stypes[NUM_NL80211_IFTYPES] = {
|
||||
[NL80211_IFTYPE_STATION] = {
|
||||
.tx = 0xffff,
|
||||
.rx = BIT(IEEE80211_STYPE_ACTION >> 4) |
|
||||
BIT(IEEE80211_STYPE_AUTH >> 4) |
|
||||
BIT(IEEE80211_STYPE_PROBE_REQ >> 4)
|
||||
},
|
||||
[NL80211_IFTYPE_P2P_CLIENT] = {
|
||||
@ -7653,6 +7659,8 @@ static int brcmf_setup_wiphy(struct wiphy *wiphy, struct brcmf_if *ifp)
|
||||
wiphy_ext_feature_set(wiphy,
|
||||
NL80211_EXT_FEATURE_SAE_OFFLOAD_AP);
|
||||
}
|
||||
if (brcmf_feat_is_enabled(ifp, BRCMF_FEAT_SAE_EXT))
|
||||
wiphy->features |= NL80211_FEATURE_SAE;
|
||||
wiphy->mgmt_stypes = brcmf_txrx_stypes;
|
||||
wiphy->max_remain_on_channel_duration = 5000;
|
||||
if (brcmf_feat_is_enabled(ifp, BRCMF_FEAT_PNO)) {
|
||||
|
||||
@ -13,6 +13,8 @@
|
||||
#include "fwil_types.h"
|
||||
#include "p2p.h"
|
||||
|
||||
#define DOT11_MGMT_HDR_LEN 24 /* d11 management header len */
|
||||
|
||||
#define BRCMF_SCAN_IE_LEN_MAX 2048
|
||||
|
||||
#define WL_NUM_SCAN_MAX 10
|
||||
@ -141,6 +143,21 @@ enum brcmf_profile_fwauth {
|
||||
BRCMF_PROFILE_FWAUTH_SAE
|
||||
};
|
||||
|
||||
/**
|
||||
* enum brcmf_mgmt_tx_status - mgmt frame tx status
|
||||
*
|
||||
* @BRCMF_MGMT_TX_ACK: mgmt frame acked
|
||||
* @BRCMF_MGMT_TX_NOACK: mgmt frame not acked
|
||||
* @BRCMF_MGMT_TX_OFF_CHAN_COMPLETED: off-channel complete
|
||||
* @BRCMF_MGMT_TX_SEND_FRAME: mgmt frame tx is in progres
|
||||
*/
|
||||
enum brcmf_mgmt_tx_status {
|
||||
BRCMF_MGMT_TX_ACK,
|
||||
BRCMF_MGMT_TX_NOACK,
|
||||
BRCMF_MGMT_TX_OFF_CHAN_COMPLETED,
|
||||
BRCMF_MGMT_TX_SEND_FRAME
|
||||
};
|
||||
|
||||
/**
|
||||
* struct brcmf_cfg80211_profile - profile information.
|
||||
*
|
||||
@ -211,6 +228,9 @@ struct vif_saved_ie {
|
||||
* @profile: profile information.
|
||||
* @sme_state: SME state using enum brcmf_vif_status bits.
|
||||
* @list: linked list.
|
||||
* @mgmt_tx: completion for management frame transmit.
|
||||
* @mgmt_tx_status: status of last management frame sent to firmware.
|
||||
* @mgmt_tx_id:
|
||||
* @mgmt_rx_reg: registered rx mgmt frame types.
|
||||
* @mbss: Multiple BSS type, set if not first AP (not relevant for P2P).
|
||||
* @cqm_rssi_low: Lower RSSI limit for CQM monitoring
|
||||
@ -224,6 +244,9 @@ struct brcmf_cfg80211_vif {
|
||||
unsigned long sme_state;
|
||||
struct vif_saved_ie saved_ie;
|
||||
struct list_head list;
|
||||
struct completion mgmt_tx;
|
||||
unsigned long mgmt_tx_status;
|
||||
u32 mgmt_tx_id;
|
||||
u16 mgmt_rx_reg;
|
||||
bool mbss;
|
||||
int is_11d;
|
||||
@ -468,5 +491,7 @@ void brcmf_abort_scanning(struct brcmf_cfg80211_info *cfg);
|
||||
void brcmf_cfg80211_free_netdev(struct net_device *ndev);
|
||||
|
||||
int brcmf_set_wsec(struct brcmf_if *ifp, const u8 *key, u16 key_len, u16 flags);
|
||||
int brcmf_cfg80211_mgmt_tx(struct wiphy *wiphy, struct wireless_dev *wdev,
|
||||
struct cfg80211_mgmt_tx_params *params, u64 *cookie);
|
||||
|
||||
#endif /* BRCMFMAC_CFG80211_H */
|
||||
|
||||
@ -491,6 +491,7 @@ void __brcmf_dbg(u32 level, const char *func, const char *fmt, ...)
|
||||
trace_brcmf_dbg(level, func, &vaf);
|
||||
va_end(args);
|
||||
}
|
||||
BRCMF_EXPORT_SYMBOL_GPL(__brcmf_dbg);
|
||||
#endif
|
||||
|
||||
static void brcmf_mp_attach(void)
|
||||
|
||||
@ -1363,6 +1363,8 @@ int brcmf_attach(struct device *dev)
|
||||
brcmf_fweh_register(drvr, BRCMF_E_PSM_WATCHDOG,
|
||||
brcmf_psm_watchdog_notify);
|
||||
|
||||
brcmf_fwvid_get_cfg80211_ops(drvr);
|
||||
|
||||
ret = brcmf_bus_started(drvr, drvr->ops);
|
||||
if (ret != 0) {
|
||||
bphy_err(drvr, "dongle is not responding: err=%d\n", ret);
|
||||
|
||||
@ -8,11 +8,21 @@
|
||||
#include <bus.h>
|
||||
#include <fwvid.h>
|
||||
#include <fwil.h>
|
||||
#include <fweh.h>
|
||||
|
||||
#include "vops.h"
|
||||
#include "fwil_types.h"
|
||||
|
||||
/* event definitions */
|
||||
#define BRCMF_CYW_E_EXT_AUTH_REQ 187
|
||||
#define BRCMF_CYW_E_EXT_AUTH_FRAME_RX 188
|
||||
#define BRCMF_CYW_E_MGMT_FRAME_TXS 189
|
||||
#define BRCMF_CYW_E_MGMT_FRAME_TXS_OC 190
|
||||
#define BRCMF_CYW_E_LAST 197
|
||||
|
||||
#define MGMT_AUTH_FRAME_DWELL_TIME 4000
|
||||
#define MGMT_AUTH_FRAME_WAIT_TIME (MGMT_AUTH_FRAME_DWELL_TIME + 100)
|
||||
|
||||
static int brcmf_cyw_set_sae_pwd(struct brcmf_if *ifp,
|
||||
struct cfg80211_crypto_settings *crypto)
|
||||
{
|
||||
@ -39,6 +49,19 @@ static int brcmf_cyw_set_sae_pwd(struct brcmf_if *ifp,
|
||||
return err;
|
||||
}
|
||||
|
||||
static const struct brcmf_fweh_event_map brcmf_cyw_event_map = {
|
||||
.items = {
|
||||
{ BRCMF_E_EXT_AUTH_REQ, BRCMF_CYW_E_EXT_AUTH_REQ },
|
||||
{ BRCMF_E_EXT_AUTH_FRAME_RX, BRCMF_CYW_E_EXT_AUTH_FRAME_RX },
|
||||
{ BRCMF_E_MGMT_FRAME_TXSTATUS, BRCMF_CYW_E_MGMT_FRAME_TXS },
|
||||
{
|
||||
BRCMF_E_MGMT_FRAME_OFFCHAN_DONE,
|
||||
BRCMF_CYW_E_MGMT_FRAME_TXS_OC
|
||||
},
|
||||
},
|
||||
.n_items = 4
|
||||
};
|
||||
|
||||
static int brcmf_cyw_alloc_fweh_info(struct brcmf_pub *drvr)
|
||||
{
|
||||
struct brcmf_fweh_info *fweh;
|
||||
@ -49,11 +72,296 @@ static int brcmf_cyw_alloc_fweh_info(struct brcmf_pub *drvr)
|
||||
return -ENOMEM;
|
||||
|
||||
fweh->num_event_codes = BRCMF_CYW_E_LAST;
|
||||
fweh->event_map = &brcmf_cyw_event_map;
|
||||
drvr->fweh = fweh;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int brcmf_cyw_activate_events(struct brcmf_if *ifp)
|
||||
{
|
||||
struct brcmf_fweh_info *fweh = ifp->drvr->fweh;
|
||||
struct brcmf_eventmsgs_ext *eventmask_msg;
|
||||
u32 msglen;
|
||||
int err;
|
||||
|
||||
msglen = sizeof(*eventmask_msg) + fweh->event_mask_len;
|
||||
eventmask_msg = kzalloc(msglen, GFP_KERNEL);
|
||||
if (!eventmask_msg)
|
||||
return -ENOMEM;
|
||||
eventmask_msg->ver = EVENTMSGS_VER;
|
||||
eventmask_msg->command = CYW_EVENTMSGS_SET_MASK;
|
||||
eventmask_msg->len = fweh->event_mask_len;
|
||||
memcpy(eventmask_msg->mask, fweh->event_mask, fweh->event_mask_len);
|
||||
|
||||
err = brcmf_fil_iovar_data_set(ifp, "event_msgs_ext", eventmask_msg,
|
||||
msglen);
|
||||
kfree(eventmask_msg);
|
||||
return err;
|
||||
}
|
||||
|
||||
static
|
||||
int brcmf_cyw_mgmt_tx(struct wiphy *wiphy, struct wireless_dev *wdev,
|
||||
struct cfg80211_mgmt_tx_params *params, u64 *cookie)
|
||||
{
|
||||
struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
|
||||
struct ieee80211_channel *chan = params->chan;
|
||||
struct brcmf_pub *drvr = cfg->pub;
|
||||
const u8 *buf = params->buf;
|
||||
size_t len = params->len;
|
||||
const struct ieee80211_mgmt *mgmt;
|
||||
struct brcmf_cfg80211_vif *vif;
|
||||
s32 err = 0;
|
||||
bool ack = false;
|
||||
s32 chan_nr;
|
||||
u32 freq;
|
||||
struct brcmf_mf_params_le *mf_params;
|
||||
u32 mf_params_len;
|
||||
s32 ready;
|
||||
|
||||
brcmf_dbg(TRACE, "Enter\n");
|
||||
|
||||
mgmt = (const struct ieee80211_mgmt *)buf;
|
||||
|
||||
if (!ieee80211_is_auth(mgmt->frame_control))
|
||||
return brcmf_cfg80211_mgmt_tx(wiphy, wdev, params, cookie);
|
||||
|
||||
*cookie = 0;
|
||||
vif = container_of(wdev, struct brcmf_cfg80211_vif, wdev);
|
||||
|
||||
reinit_completion(&vif->mgmt_tx);
|
||||
clear_bit(BRCMF_MGMT_TX_ACK, &vif->mgmt_tx_status);
|
||||
clear_bit(BRCMF_MGMT_TX_NOACK, &vif->mgmt_tx_status);
|
||||
clear_bit(BRCMF_MGMT_TX_OFF_CHAN_COMPLETED,
|
||||
&vif->mgmt_tx_status);
|
||||
mf_params_len = offsetof(struct brcmf_mf_params_le, data) +
|
||||
(len - DOT11_MGMT_HDR_LEN);
|
||||
mf_params = kzalloc(mf_params_len, GFP_KERNEL);
|
||||
if (!mf_params)
|
||||
return -ENOMEM;
|
||||
|
||||
mf_params->dwell_time = cpu_to_le32(MGMT_AUTH_FRAME_DWELL_TIME);
|
||||
mf_params->len = cpu_to_le16(len - DOT11_MGMT_HDR_LEN);
|
||||
mf_params->frame_control = mgmt->frame_control;
|
||||
|
||||
if (chan)
|
||||
freq = chan->center_freq;
|
||||
else
|
||||
brcmf_fil_cmd_int_get(vif->ifp, BRCMF_C_GET_CHANNEL,
|
||||
&freq);
|
||||
chan_nr = ieee80211_frequency_to_channel(freq);
|
||||
mf_params->channel = cpu_to_le16(chan_nr);
|
||||
memcpy(&mf_params->da[0], &mgmt->da[0], ETH_ALEN);
|
||||
memcpy(&mf_params->bssid[0], &mgmt->bssid[0], ETH_ALEN);
|
||||
mf_params->packet_id = cpu_to_le32(*cookie);
|
||||
memcpy(mf_params->data, &buf[DOT11_MGMT_HDR_LEN],
|
||||
le16_to_cpu(mf_params->len));
|
||||
|
||||
brcmf_dbg(TRACE, "Auth frame, cookie=%d, fc=%04x, len=%d, channel=%d\n",
|
||||
le32_to_cpu(mf_params->packet_id),
|
||||
le16_to_cpu(mf_params->frame_control),
|
||||
le16_to_cpu(mf_params->len), chan_nr);
|
||||
|
||||
vif->mgmt_tx_id = le32_to_cpu(mf_params->packet_id);
|
||||
set_bit(BRCMF_MGMT_TX_SEND_FRAME, &vif->mgmt_tx_status);
|
||||
|
||||
err = brcmf_fil_bsscfg_data_set(vif->ifp, "mgmt_frame",
|
||||
mf_params, mf_params_len);
|
||||
if (err) {
|
||||
bphy_err(drvr, "Failed to send Auth frame: err=%d\n",
|
||||
err);
|
||||
goto tx_status;
|
||||
}
|
||||
|
||||
ready = wait_for_completion_timeout(&vif->mgmt_tx,
|
||||
MGMT_AUTH_FRAME_WAIT_TIME);
|
||||
if (test_bit(BRCMF_MGMT_TX_ACK, &vif->mgmt_tx_status)) {
|
||||
brcmf_dbg(TRACE, "TX Auth frame operation is success\n");
|
||||
ack = true;
|
||||
} else {
|
||||
bphy_err(drvr, "TX Auth frame operation is %s: status=%ld)\n",
|
||||
ready ? "failed" : "timedout", vif->mgmt_tx_status);
|
||||
}
|
||||
|
||||
tx_status:
|
||||
cfg80211_mgmt_tx_status(wdev, *cookie, buf, len, ack,
|
||||
GFP_KERNEL);
|
||||
kfree(mf_params);
|
||||
return err;
|
||||
}
|
||||
|
||||
static int
|
||||
brcmf_cyw_external_auth(struct wiphy *wiphy, struct net_device *dev,
|
||||
struct cfg80211_external_auth_params *params)
|
||||
{
|
||||
struct brcmf_if *ifp;
|
||||
struct brcmf_pub *drvr;
|
||||
struct brcmf_auth_req_status_le auth_status;
|
||||
int ret = 0;
|
||||
|
||||
brcmf_dbg(TRACE, "Enter\n");
|
||||
|
||||
ifp = netdev_priv(dev);
|
||||
drvr = ifp->drvr;
|
||||
if (params->status == WLAN_STATUS_SUCCESS) {
|
||||
auth_status.flags = cpu_to_le16(BRCMF_EXTAUTH_SUCCESS);
|
||||
} else {
|
||||
bphy_err(drvr, "External authentication failed: status=%d\n",
|
||||
params->status);
|
||||
auth_status.flags = cpu_to_le16(BRCMF_EXTAUTH_FAIL);
|
||||
}
|
||||
|
||||
memcpy(auth_status.peer_mac, params->bssid, ETH_ALEN);
|
||||
params->ssid.ssid_len = min_t(u8, params->ssid.ssid_len,
|
||||
IEEE80211_MAX_SSID_LEN);
|
||||
auth_status.ssid_len = cpu_to_le32(params->ssid.ssid_len);
|
||||
memcpy(auth_status.ssid, params->ssid.ssid, params->ssid.ssid_len);
|
||||
|
||||
ret = brcmf_fil_iovar_data_set(ifp, "auth_status", &auth_status,
|
||||
sizeof(auth_status));
|
||||
if (ret < 0)
|
||||
bphy_err(drvr, "auth_status iovar failed: ret=%d\n", ret);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void brcmf_cyw_get_cfg80211_ops(struct brcmf_pub *drvr)
|
||||
{
|
||||
drvr->ops->mgmt_tx = brcmf_cyw_mgmt_tx;
|
||||
drvr->ops->external_auth = brcmf_cyw_external_auth;
|
||||
}
|
||||
|
||||
static s32
|
||||
brcmf_cyw_notify_ext_auth_req(struct brcmf_if *ifp,
|
||||
const struct brcmf_event_msg *e, void *data)
|
||||
{
|
||||
struct brcmf_pub *drvr = ifp->drvr;
|
||||
struct cfg80211_external_auth_params params;
|
||||
struct brcmf_auth_req_status_le *auth_req =
|
||||
(struct brcmf_auth_req_status_le *)data;
|
||||
s32 err = 0;
|
||||
|
||||
brcmf_dbg(INFO, "Enter: event %s (%d) received\n",
|
||||
brcmf_fweh_event_name(e->event_code), e->event_code);
|
||||
|
||||
if (e->datalen < sizeof(*auth_req)) {
|
||||
bphy_err(drvr, "Event %s (%d) data too small. Ignore\n",
|
||||
brcmf_fweh_event_name(e->event_code), e->event_code);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
memset(¶ms, 0, sizeof(params));
|
||||
params.action = NL80211_EXTERNAL_AUTH_START;
|
||||
params.key_mgmt_suite = WLAN_AKM_SUITE_SAE;
|
||||
params.status = WLAN_STATUS_SUCCESS;
|
||||
params.ssid.ssid_len = min_t(u32, 32, le32_to_cpu(auth_req->ssid_len));
|
||||
memcpy(params.ssid.ssid, auth_req->ssid, params.ssid.ssid_len);
|
||||
memcpy(params.bssid, auth_req->peer_mac, ETH_ALEN);
|
||||
|
||||
err = cfg80211_external_auth_request(ifp->ndev, ¶ms, GFP_KERNEL);
|
||||
if (err)
|
||||
bphy_err(drvr, "Ext Auth request to supplicant failed (%d)\n",
|
||||
err);
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
static s32
|
||||
brcmf_notify_auth_frame_rx(struct brcmf_if *ifp,
|
||||
const struct brcmf_event_msg *e, void *data)
|
||||
{
|
||||
struct brcmf_pub *drvr = ifp->drvr;
|
||||
struct brcmf_cfg80211_info *cfg = drvr->config;
|
||||
struct wireless_dev *wdev;
|
||||
u32 mgmt_frame_len = e->datalen - sizeof(struct brcmf_rx_mgmt_data);
|
||||
struct brcmf_rx_mgmt_data *rxframe = (struct brcmf_rx_mgmt_data *)data;
|
||||
u8 *frame = (u8 *)(rxframe + 1);
|
||||
struct brcmu_chan ch;
|
||||
struct ieee80211_mgmt *mgmt_frame;
|
||||
s32 freq;
|
||||
|
||||
brcmf_dbg(INFO, "Enter: event %s (%d) received\n",
|
||||
brcmf_fweh_event_name(e->event_code), e->event_code);
|
||||
|
||||
if (e->datalen < sizeof(*rxframe)) {
|
||||
bphy_err(drvr, "Event %s (%d) data too small. Ignore\n",
|
||||
brcmf_fweh_event_name(e->event_code), e->event_code);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
wdev = &ifp->vif->wdev;
|
||||
WARN_ON(!wdev);
|
||||
|
||||
ch.chspec = be16_to_cpu(rxframe->chanspec);
|
||||
cfg->d11inf.decchspec(&ch);
|
||||
|
||||
mgmt_frame = kzalloc(mgmt_frame_len, GFP_KERNEL);
|
||||
if (!mgmt_frame)
|
||||
return -ENOMEM;
|
||||
|
||||
mgmt_frame->frame_control = cpu_to_le16(IEEE80211_STYPE_AUTH);
|
||||
memcpy(mgmt_frame->da, ifp->mac_addr, ETH_ALEN);
|
||||
memcpy(mgmt_frame->sa, e->addr, ETH_ALEN);
|
||||
brcmf_fil_cmd_data_get(ifp, BRCMF_C_GET_BSSID, mgmt_frame->bssid,
|
||||
ETH_ALEN);
|
||||
frame += offsetof(struct ieee80211_mgmt, u);
|
||||
memcpy(&mgmt_frame->u, frame,
|
||||
mgmt_frame_len - offsetof(struct ieee80211_mgmt, u));
|
||||
|
||||
freq = ieee80211_channel_to_frequency(ch.control_ch_num,
|
||||
ch.band == BRCMU_CHAN_BAND_2G ?
|
||||
NL80211_BAND_2GHZ :
|
||||
NL80211_BAND_5GHZ);
|
||||
|
||||
cfg80211_rx_mgmt(wdev, freq, 0, (u8 *)mgmt_frame, mgmt_frame_len,
|
||||
NL80211_RXMGMT_FLAG_EXTERNAL_AUTH);
|
||||
kfree(mgmt_frame);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static s32
|
||||
brcmf_notify_mgmt_tx_status(struct brcmf_if *ifp,
|
||||
const struct brcmf_event_msg *e, void *data)
|
||||
{
|
||||
struct brcmf_cfg80211_vif *vif = ifp->vif;
|
||||
u32 *packet_id = (u32 *)data;
|
||||
|
||||
brcmf_dbg(INFO, "Enter: event %s (%d), status=%d\n",
|
||||
brcmf_fweh_event_name(e->event_code), e->event_code,
|
||||
e->status);
|
||||
|
||||
if (!test_bit(BRCMF_MGMT_TX_SEND_FRAME, &vif->mgmt_tx_status) ||
|
||||
(*packet_id != vif->mgmt_tx_id))
|
||||
return 0;
|
||||
|
||||
if (e->event_code == BRCMF_E_MGMT_FRAME_TXSTATUS) {
|
||||
if (e->status == BRCMF_E_STATUS_SUCCESS)
|
||||
set_bit(BRCMF_MGMT_TX_ACK, &vif->mgmt_tx_status);
|
||||
else
|
||||
set_bit(BRCMF_MGMT_TX_NOACK, &vif->mgmt_tx_status);
|
||||
} else {
|
||||
set_bit(BRCMF_MGMT_TX_OFF_CHAN_COMPLETED, &vif->mgmt_tx_status);
|
||||
}
|
||||
|
||||
complete(&vif->mgmt_tx);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void brcmf_cyw_register_event_handlers(struct brcmf_pub *drvr)
|
||||
{
|
||||
brcmf_fweh_register(drvr, BRCMF_E_EXT_AUTH_REQ,
|
||||
brcmf_cyw_notify_ext_auth_req);
|
||||
brcmf_fweh_register(drvr, BRCMF_E_EXT_AUTH_FRAME_RX,
|
||||
brcmf_notify_auth_frame_rx);
|
||||
brcmf_fweh_register(drvr, BRCMF_E_MGMT_FRAME_TXSTATUS,
|
||||
brcmf_notify_mgmt_tx_status);
|
||||
brcmf_fweh_register(drvr, BRCMF_E_MGMT_FRAME_OFFCHAN_DONE,
|
||||
brcmf_notify_mgmt_tx_status);
|
||||
}
|
||||
|
||||
const struct brcmf_fwvid_ops brcmf_cyw_ops = {
|
||||
.set_sae_password = brcmf_cyw_set_sae_pwd,
|
||||
.alloc_fweh_info = brcmf_cyw_alloc_fweh_info,
|
||||
.activate_events = brcmf_cyw_activate_events,
|
||||
.get_cfg80211_ops = brcmf_cyw_get_cfg80211_ops,
|
||||
.register_event_handlers = brcmf_cyw_register_event_handlers,
|
||||
};
|
||||
|
||||
@ -0,0 +1,87 @@
|
||||
// SPDX-License-Identifier: ISC
|
||||
/*
|
||||
* Copyright (c) 2012 Broadcom Corporation
|
||||
*/
|
||||
|
||||
#ifndef CYW_FWIL_TYPES_H_
|
||||
#define CYW_FWIL_TYPES_H_
|
||||
|
||||
#include <fwil_types.h>
|
||||
|
||||
enum brcmf_event_msgs_ext_command {
|
||||
CYW_EVENTMSGS_NONE = 0,
|
||||
CYW_EVENTMSGS_SET_BIT = 1,
|
||||
CYW_EVENTMSGS_RESET_BIT = 2,
|
||||
CYW_EVENTMSGS_SET_MASK = 3,
|
||||
};
|
||||
|
||||
#define EVENTMSGS_VER 1
|
||||
#define EVENTMSGS_EXT_STRUCT_SIZE offsetof(struct eventmsgs_ext, mask[0])
|
||||
|
||||
/**
|
||||
* struct brcmf_eventmsgs_ext - structure used with "eventmsgs_ext" iovar.
|
||||
*
|
||||
* @ver: version.
|
||||
* @command: requested operation (see &enum event_msgs_ext_command).
|
||||
* @len: length of the @mask array.
|
||||
* @maxgetsize: indicates maximum mask size that may be returned by firmware
|
||||
* upon iovar GET.
|
||||
* @mask: array where each bit represents firmware event.
|
||||
*/
|
||||
struct brcmf_eventmsgs_ext {
|
||||
u8 ver;
|
||||
u8 command;
|
||||
u8 len;
|
||||
u8 maxgetsize;
|
||||
u8 mask[] __counted_by(len);
|
||||
};
|
||||
|
||||
#define BRCMF_EXTAUTH_START 1
|
||||
#define BRCMF_EXTAUTH_ABORT 2
|
||||
#define BRCMF_EXTAUTH_FAIL 3
|
||||
#define BRCMF_EXTAUTH_SUCCESS 4
|
||||
|
||||
/**
|
||||
* struct brcmf_auth_req_status_le - external auth request and status update
|
||||
*
|
||||
* @flags: flags for external auth status
|
||||
* @peer_mac: peer MAC address
|
||||
* @ssid_len: length of ssid
|
||||
* @ssid: ssid characters
|
||||
* @pmkid: PMKSA identifier
|
||||
*/
|
||||
struct brcmf_auth_req_status_le {
|
||||
__le16 flags;
|
||||
u8 peer_mac[ETH_ALEN];
|
||||
__le32 ssid_len;
|
||||
u8 ssid[IEEE80211_MAX_SSID_LEN];
|
||||
u8 pmkid[WLAN_PMKID_LEN];
|
||||
};
|
||||
|
||||
/**
|
||||
* struct brcmf_mf_params_le - management frame parameters for mgmt_frame iovar
|
||||
*
|
||||
* @version: version of the iovar
|
||||
* @dwell_time: dwell duration in ms
|
||||
* @len: length of frame data
|
||||
* @frame_control: frame control
|
||||
* @channel: channel
|
||||
* @da: peer MAC address
|
||||
* @bssid: BSS network identifier
|
||||
* @packet_id: packet identifier
|
||||
* @data: frame data
|
||||
*/
|
||||
struct brcmf_mf_params_le {
|
||||
__le32 version;
|
||||
__le32 dwell_time;
|
||||
__le16 len;
|
||||
__le16 frame_control;
|
||||
__le16 channel;
|
||||
u8 da[ETH_ALEN];
|
||||
u8 bssid[ETH_ALEN];
|
||||
__le32 packet_id;
|
||||
u8 data[] __counted_by(len);
|
||||
};
|
||||
|
||||
#endif /* CYW_FWIL_TYPES_H_ */
|
||||
|
||||
@ -42,8 +42,9 @@ static const struct brcmf_feat_fwcap brcmf_fwcap_map[] = {
|
||||
{ BRCMF_FEAT_MONITOR_FLAG, "rtap" },
|
||||
{ BRCMF_FEAT_MONITOR_FMT_RADIOTAP, "rtap" },
|
||||
{ BRCMF_FEAT_DOT11H, "802.11h" },
|
||||
{ BRCMF_FEAT_SAE, "sae" },
|
||||
{ BRCMF_FEAT_SAE, "sae " },
|
||||
{ BRCMF_FEAT_FWAUTH, "idauth" },
|
||||
{ BRCMF_FEAT_SAE_EXT, "sae_ext" },
|
||||
};
|
||||
|
||||
#ifdef DEBUG
|
||||
|
||||
@ -31,6 +31,7 @@
|
||||
* FWAUTH: Firmware authenticator
|
||||
* DUMP_OBSS: Firmware has capable to dump obss info to support ACS
|
||||
* SCAN_V2: Version 2 scan params
|
||||
* SAE_EXT: SAE authentication handled by user-space supplicant
|
||||
*/
|
||||
#define BRCMF_FEAT_LIST \
|
||||
BRCMF_FEAT_DEF(MBSS) \
|
||||
@ -57,7 +58,8 @@
|
||||
BRCMF_FEAT_DEF(DUMP_OBSS) \
|
||||
BRCMF_FEAT_DEF(SCAN_V2) \
|
||||
BRCMF_FEAT_DEF(PMKID_V2) \
|
||||
BRCMF_FEAT_DEF(PMKID_V3)
|
||||
BRCMF_FEAT_DEF(PMKID_V3) \
|
||||
BRCMF_FEAT_DEF(SAE_EXT)
|
||||
|
||||
/*
|
||||
* Quirks:
|
||||
|
||||
@ -75,6 +75,7 @@ const char *brcmf_fweh_event_name(enum brcmf_fweh_event_code code)
|
||||
return "nodebug";
|
||||
}
|
||||
#endif
|
||||
BRCMF_EXPORT_SYMBOL_GPL(brcmf_fweh_event_name);
|
||||
|
||||
/**
|
||||
* brcmf_fweh_queue_event() - create and queue event.
|
||||
@ -405,6 +406,7 @@ int brcmf_fweh_register(struct brcmf_pub *drvr, enum brcmf_fweh_event_code code,
|
||||
brcmf_fweh_event_name(code));
|
||||
return 0;
|
||||
}
|
||||
BRCMF_EXPORT_SYMBOL_GPL(brcmf_fweh_register);
|
||||
|
||||
/**
|
||||
* brcmf_fweh_unregister() - remove handler for given code.
|
||||
@ -448,11 +450,14 @@ int brcmf_fweh_activate_events(struct brcmf_if *ifp)
|
||||
brcmf_dbg(EVENT, "enable event IF\n");
|
||||
setbit(fweh->event_mask, BRCMF_E_IF);
|
||||
|
||||
/* allow per-vendor method to activate firmware events */
|
||||
if (!brcmf_fwvid_activate_events(ifp))
|
||||
return 0;
|
||||
|
||||
err = brcmf_fil_iovar_data_set(ifp, "event_msgs", fweh->event_mask,
|
||||
fweh->event_mask_len);
|
||||
if (err)
|
||||
bphy_err(fweh->drvr, "Set event_msgs error (%d)\n", err);
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
|
||||
@ -94,7 +94,11 @@ struct brcmf_cfg80211_info;
|
||||
BRCMF_ENUM_DEF(FIFO_CREDIT_MAP, 74) \
|
||||
BRCMF_ENUM_DEF(ACTION_FRAME_RX, 75) \
|
||||
BRCMF_ENUM_DEF(TDLS_PEER_EVENT, 92) \
|
||||
BRCMF_ENUM_DEF(BCMC_CREDIT_SUPPORT, 127)
|
||||
BRCMF_ENUM_DEF(BCMC_CREDIT_SUPPORT, 127) \
|
||||
BRCMF_ABSTRACT_ENUM_DEF(EXT_AUTH_REQ, 0) \
|
||||
BRCMF_ABSTRACT_ENUM_DEF(EXT_AUTH_FRAME_RX, 1) \
|
||||
BRCMF_ABSTRACT_ENUM_DEF(MGMT_FRAME_TXSTATUS, 2) \
|
||||
BRCMF_ABSTRACT_ENUM_DEF(MGMT_FRAME_OFFCHAN_DONE, 3)
|
||||
|
||||
#define BRCMF_ENUM_DEF(id, val) \
|
||||
BRCMF_E_##id = (val),
|
||||
@ -337,7 +341,7 @@ struct brcmf_fweh_info {
|
||||
struct list_head event_q;
|
||||
uint event_mask_len;
|
||||
u8 *event_mask;
|
||||
struct brcmf_fweh_event_map *event_map;
|
||||
const struct brcmf_fweh_event_map *event_map;
|
||||
uint num_event_codes;
|
||||
brcmf_fweh_handler_t evt_handler[] __counted_by(num_event_codes);
|
||||
};
|
||||
|
||||
@ -15,6 +15,9 @@ struct brcmf_fwvid_ops {
|
||||
void (*feat_attach)(struct brcmf_if *ifp);
|
||||
int (*set_sae_password)(struct brcmf_if *ifp, struct cfg80211_crypto_settings *crypto);
|
||||
int (*alloc_fweh_info)(struct brcmf_pub *drvr);
|
||||
int (*activate_events)(struct brcmf_if *ifp);
|
||||
void (*get_cfg80211_ops)(struct brcmf_pub *drvr);
|
||||
void (*register_event_handlers)(struct brcmf_pub *drvr);
|
||||
};
|
||||
|
||||
/* exported functions */
|
||||
@ -56,4 +59,30 @@ static inline int brcmf_fwvid_alloc_fweh_info(struct brcmf_pub *drvr)
|
||||
return drvr->vops->alloc_fweh_info(drvr);
|
||||
}
|
||||
|
||||
static inline int brcmf_fwvid_activate_events(struct brcmf_if *ifp)
|
||||
{
|
||||
const struct brcmf_fwvid_ops *vops = ifp->drvr->vops;
|
||||
|
||||
if (!vops || !vops->activate_events)
|
||||
return -EOPNOTSUPP;
|
||||
|
||||
return vops->activate_events(ifp);
|
||||
}
|
||||
|
||||
static inline void brcmf_fwvid_get_cfg80211_ops(struct brcmf_pub *drvr)
|
||||
{
|
||||
if (!drvr->vops || !drvr->vops->get_cfg80211_ops)
|
||||
return;
|
||||
|
||||
drvr->vops->get_cfg80211_ops(drvr);
|
||||
}
|
||||
|
||||
static inline void brcmf_fwvid_register_event_handlers(struct brcmf_pub *drvr)
|
||||
{
|
||||
if (!drvr->vops || !drvr->vops->register_event_handlers)
|
||||
return;
|
||||
|
||||
drvr->vops->register_event_handlers(drvr);
|
||||
}
|
||||
|
||||
#endif /* FWVID_H_ */
|
||||
|
||||
@ -8,12 +8,23 @@ iwlwifi-objs += iwl-nvm-utils.o
|
||||
iwlwifi-objs += iwl-utils.o
|
||||
iwlwifi-objs += iwl-phy-db.o iwl-nvm-parse.o
|
||||
iwlwifi-objs += pcie/drv.o pcie/rx.o pcie/tx.o pcie/trans.o
|
||||
iwlwifi-objs += pcie/ctxt-info.o pcie/ctxt-info-gen3.o
|
||||
iwlwifi-objs += pcie/ctxt-info.o pcie/ctxt-info-v2.o
|
||||
iwlwifi-objs += pcie/trans-gen2.o pcie/tx-gen2.o
|
||||
iwlwifi-$(CONFIG_IWLDVM) += cfg/1000.o cfg/2000.o cfg/5000.o cfg/6000.o
|
||||
iwlwifi-$(CONFIG_IWLMVM) += cfg/7000.o cfg/8000.o cfg/9000.o cfg/22000.o
|
||||
|
||||
CFLAGS_pcie/drv.o += -Wno-override-init
|
||||
|
||||
# combined MAC/RF configurations
|
||||
iwlwifi-$(CONFIG_IWLDVM) += cfg/1000.o cfg/2000.o
|
||||
iwlwifi-$(CONFIG_IWLDVM) += cfg/5000.o cfg/6000.o
|
||||
iwlwifi-$(CONFIG_IWLMVM) += cfg/7000.o cfg/8000.o
|
||||
# MAC configurations
|
||||
iwlwifi-$(CONFIG_IWLMVM) += cfg/9000.o cfg/22000.o
|
||||
iwlwifi-$(CONFIG_IWLMVM) += cfg/ax210.o
|
||||
iwlwifi-$(CONFIG_IWLMLD) += cfg/bz.o cfg/sc.o cfg/dr.o
|
||||
# RF configurations
|
||||
iwlwifi-$(CONFIG_IWLMVM) += cfg/rf-jf.o cfg/rf-hr.o cfg/rf-gf.o
|
||||
iwlwifi-$(CONFIG_IWLMLD) += cfg/rf-fm.o cfg/rf-wh.o cfg/rf-pe.o
|
||||
|
||||
iwlwifi-objs += iwl-dbg-tlv.o
|
||||
iwlwifi-objs += iwl-trans.o
|
||||
|
||||
|
||||
@ -2,7 +2,7 @@
|
||||
/******************************************************************************
|
||||
*
|
||||
* Copyright(c) 2008 - 2014 Intel Corporation. All rights reserved.
|
||||
* Copyright(c) 2018 - 2020, 2023 Intel Corporation
|
||||
* Copyright(c) 2018 - 2020, 2023, 2025 Intel Corporation
|
||||
*****************************************************************************/
|
||||
|
||||
#include <linux/module.h>
|
||||
@ -29,7 +29,7 @@
|
||||
#define IWL100_MODULE_FIRMWARE(api) IWL100_FW_PRE "-" __stringify(api) ".ucode"
|
||||
|
||||
|
||||
static const struct iwl_base_params iwl1000_base_params = {
|
||||
static const struct iwl_family_base_params iwl1000_base = {
|
||||
.num_of_queues = IWLAGN_NUM_QUEUES,
|
||||
.max_tfd_queue_size = 256,
|
||||
.eeprom_size = OTP_LOW_IMAGE_SIZE_2K,
|
||||
@ -42,12 +42,6 @@ static const struct iwl_base_params iwl1000_base_params = {
|
||||
.scd_chain_ext_wa = true,
|
||||
};
|
||||
|
||||
static const struct iwl_ht_params iwl1000_ht_params = {
|
||||
.ht_greenfield_support = true,
|
||||
.use_rts_for_aggregation = true, /* use rts/cts protection */
|
||||
.ht40_bands = BIT(NL80211_BAND_2GHZ),
|
||||
};
|
||||
|
||||
static const struct iwl_eeprom_params iwl1000_eeprom_params = {
|
||||
.regulatory_bands = {
|
||||
EEPROM_REG_BAND_1_CHANNELS,
|
||||
@ -60,54 +54,67 @@ static const struct iwl_eeprom_params iwl1000_eeprom_params = {
|
||||
}
|
||||
};
|
||||
|
||||
const struct iwl_mac_cfg iwl1000_mac_cfg = {
|
||||
.device_family = IWL_DEVICE_FAMILY_1000,
|
||||
.base = &iwl1000_base,
|
||||
};
|
||||
|
||||
#define IWL_DEVICE_1000 \
|
||||
.fw_name_pre = IWL1000_FW_PRE, \
|
||||
.ucode_api_max = IWL1000_UCODE_API_MAX, \
|
||||
.ucode_api_min = IWL1000_UCODE_API_MIN, \
|
||||
.trans.device_family = IWL_DEVICE_FAMILY_1000, \
|
||||
.max_inst_size = IWLAGN_RTC_INST_SIZE, \
|
||||
.max_data_size = IWLAGN_RTC_DATA_SIZE, \
|
||||
.nvm_ver = EEPROM_1000_EEPROM_VERSION, \
|
||||
.nvm_calib_ver = EEPROM_1000_TX_POWER_VERSION, \
|
||||
.trans.base_params = &iwl1000_base_params, \
|
||||
.eeprom_params = &iwl1000_eeprom_params, \
|
||||
.led_mode = IWL_LED_BLINK
|
||||
|
||||
const struct iwl_cfg iwl1000_bgn_cfg = {
|
||||
.name = "Intel(R) Centrino(R) Wireless-N 1000 BGN",
|
||||
const struct iwl_rf_cfg iwl1000_bgn_cfg = {
|
||||
IWL_DEVICE_1000,
|
||||
.ht_params = &iwl1000_ht_params,
|
||||
.ht_params = {
|
||||
.ht_greenfield_support = true,
|
||||
.use_rts_for_aggregation = true, /* use rts/cts protection */
|
||||
.ht40_bands = BIT(NL80211_BAND_2GHZ),
|
||||
},
|
||||
};
|
||||
|
||||
const struct iwl_cfg iwl1000_bg_cfg = {
|
||||
.name = "Intel(R) Centrino(R) Wireless-N 1000 BG",
|
||||
const char iwl1000_bgn_name[] = "Intel(R) Centrino(R) Wireless-N 1000 BGN";
|
||||
|
||||
const struct iwl_rf_cfg iwl1000_bg_cfg = {
|
||||
IWL_DEVICE_1000,
|
||||
};
|
||||
|
||||
const char iwl1000_bg_name[] = "Intel(R) Centrino(R) Wireless-N 1000 BG";
|
||||
|
||||
#define IWL_DEVICE_100 \
|
||||
.fw_name_pre = IWL100_FW_PRE, \
|
||||
.ucode_api_max = IWL100_UCODE_API_MAX, \
|
||||
.ucode_api_min = IWL100_UCODE_API_MIN, \
|
||||
.trans.device_family = IWL_DEVICE_FAMILY_100, \
|
||||
.max_inst_size = IWLAGN_RTC_INST_SIZE, \
|
||||
.max_data_size = IWLAGN_RTC_DATA_SIZE, \
|
||||
.nvm_ver = EEPROM_1000_EEPROM_VERSION, \
|
||||
.nvm_calib_ver = EEPROM_1000_TX_POWER_VERSION, \
|
||||
.trans.base_params = &iwl1000_base_params, \
|
||||
.eeprom_params = &iwl1000_eeprom_params, \
|
||||
.led_mode = IWL_LED_RF_STATE, \
|
||||
.rx_with_siso_diversity = true
|
||||
|
||||
const struct iwl_cfg iwl100_bgn_cfg = {
|
||||
.name = "Intel(R) Centrino(R) Wireless-N 100 BGN",
|
||||
const struct iwl_rf_cfg iwl100_bgn_cfg = {
|
||||
IWL_DEVICE_100,
|
||||
.ht_params = &iwl1000_ht_params,
|
||||
.ht_params = {
|
||||
.ht_greenfield_support = true,
|
||||
.use_rts_for_aggregation = true, /* use rts/cts protection */
|
||||
.ht40_bands = BIT(NL80211_BAND_2GHZ),
|
||||
},
|
||||
};
|
||||
|
||||
const struct iwl_cfg iwl100_bg_cfg = {
|
||||
.name = "Intel(R) Centrino(R) Wireless-N 100 BG",
|
||||
const char iwl100_bgn_name[] = "Intel(R) Centrino(R) Wireless-N 100 BGN";
|
||||
|
||||
const struct iwl_rf_cfg iwl100_bg_cfg = {
|
||||
IWL_DEVICE_100,
|
||||
};
|
||||
|
||||
const char iwl100_bg_name[] = "Intel(R) Centrino(R) Wireless-N 100 BG";
|
||||
|
||||
MODULE_FIRMWARE(IWL1000_MODULE_FIRMWARE(IWL1000_UCODE_API_MAX));
|
||||
MODULE_FIRMWARE(IWL100_MODULE_FIRMWARE(IWL100_UCODE_API_MAX));
|
||||
|
||||
@ -2,7 +2,7 @@
|
||||
/******************************************************************************
|
||||
*
|
||||
* Copyright(c) 2008 - 2014 Intel Corporation. All rights reserved.
|
||||
* Copyright(c) 2018 - 2020, 2023 Intel Corporation
|
||||
* Copyright(c) 2018 - 2020, 2023, 2025 Intel Corporation
|
||||
*****************************************************************************/
|
||||
|
||||
#include <linux/module.h>
|
||||
@ -40,7 +40,7 @@
|
||||
#define IWL135_FW_PRE "iwlwifi-135"
|
||||
#define IWL135_MODULE_FIRMWARE(api) IWL135_FW_PRE "-" __stringify(api) ".ucode"
|
||||
|
||||
static const struct iwl_base_params iwl2000_base_params = {
|
||||
static const struct iwl_family_base_params iwl2000_base = {
|
||||
.eeprom_size = OTP_LOW_IMAGE_SIZE_2K,
|
||||
.num_of_queues = IWLAGN_NUM_QUEUES,
|
||||
.max_tfd_queue_size = 256,
|
||||
@ -54,7 +54,7 @@ static const struct iwl_base_params iwl2000_base_params = {
|
||||
};
|
||||
|
||||
|
||||
static const struct iwl_base_params iwl2030_base_params = {
|
||||
static const struct iwl_family_base_params iwl2030_base = {
|
||||
.eeprom_size = OTP_LOW_IMAGE_SIZE_2K,
|
||||
.num_of_queues = IWLAGN_NUM_QUEUES,
|
||||
.max_tfd_queue_size = 256,
|
||||
@ -67,12 +67,6 @@ static const struct iwl_base_params iwl2030_base_params = {
|
||||
.scd_chain_ext_wa = true,
|
||||
};
|
||||
|
||||
static const struct iwl_ht_params iwl2000_ht_params = {
|
||||
.ht_greenfield_support = true,
|
||||
.use_rts_for_aggregation = true, /* use rts/cts protection */
|
||||
.ht40_bands = BIT(NL80211_BAND_2GHZ),
|
||||
};
|
||||
|
||||
static const struct iwl_eeprom_params iwl20x0_eeprom_params = {
|
||||
.regulatory_bands = {
|
||||
EEPROM_REG_BAND_1_CHANNELS,
|
||||
@ -86,97 +80,119 @@ static const struct iwl_eeprom_params iwl20x0_eeprom_params = {
|
||||
.enhanced_txpower = true,
|
||||
};
|
||||
|
||||
const struct iwl_mac_cfg iwl2000_mac_cfg = {
|
||||
.device_family = IWL_DEVICE_FAMILY_2000,
|
||||
.base = &iwl2000_base,
|
||||
};
|
||||
|
||||
#define IWL_DEVICE_2000 \
|
||||
.fw_name_pre = IWL2000_FW_PRE, \
|
||||
.ucode_api_max = IWL2000_UCODE_API_MAX, \
|
||||
.ucode_api_min = IWL2000_UCODE_API_MIN, \
|
||||
.trans.device_family = IWL_DEVICE_FAMILY_2000, \
|
||||
.max_inst_size = IWL60_RTC_INST_SIZE, \
|
||||
.max_data_size = IWL60_RTC_DATA_SIZE, \
|
||||
.nvm_ver = EEPROM_2000_EEPROM_VERSION, \
|
||||
.nvm_calib_ver = EEPROM_2000_TX_POWER_VERSION, \
|
||||
.trans.base_params = &iwl2000_base_params, \
|
||||
.eeprom_params = &iwl20x0_eeprom_params, \
|
||||
.led_mode = IWL_LED_RF_STATE
|
||||
|
||||
|
||||
const struct iwl_cfg iwl2000_2bgn_cfg = {
|
||||
.name = "Intel(R) Centrino(R) Wireless-N 2200 BGN",
|
||||
const struct iwl_rf_cfg iwl2000_2bgn_cfg = {
|
||||
IWL_DEVICE_2000,
|
||||
.ht_params = &iwl2000_ht_params,
|
||||
.ht_params = {
|
||||
.ht_greenfield_support = true,
|
||||
.use_rts_for_aggregation = true, /* use rts/cts protection */
|
||||
.ht40_bands = BIT(NL80211_BAND_2GHZ),
|
||||
},
|
||||
};
|
||||
|
||||
const struct iwl_cfg iwl2000_2bgn_d_cfg = {
|
||||
.name = "Intel(R) Centrino(R) Wireless-N 2200D BGN",
|
||||
IWL_DEVICE_2000,
|
||||
.ht_params = &iwl2000_ht_params,
|
||||
const char iwl2000_2bgn_name[] = "Intel(R) Centrino(R) Wireless-N 2200 BGN";
|
||||
const char iwl2000_2bgn_d_name[] = "Intel(R) Centrino(R) Wireless-N 2200D BGN";
|
||||
|
||||
const struct iwl_mac_cfg iwl2030_mac_cfg = {
|
||||
.device_family = IWL_DEVICE_FAMILY_2030,
|
||||
.base = &iwl2030_base,
|
||||
};
|
||||
|
||||
#define IWL_DEVICE_2030 \
|
||||
.fw_name_pre = IWL2030_FW_PRE, \
|
||||
.ucode_api_max = IWL2030_UCODE_API_MAX, \
|
||||
.ucode_api_min = IWL2030_UCODE_API_MIN, \
|
||||
.trans.device_family = IWL_DEVICE_FAMILY_2030, \
|
||||
.max_inst_size = IWL60_RTC_INST_SIZE, \
|
||||
.max_data_size = IWL60_RTC_DATA_SIZE, \
|
||||
.nvm_ver = EEPROM_2000_EEPROM_VERSION, \
|
||||
.nvm_calib_ver = EEPROM_2000_TX_POWER_VERSION, \
|
||||
.trans.base_params = &iwl2030_base_params, \
|
||||
.eeprom_params = &iwl20x0_eeprom_params, \
|
||||
.led_mode = IWL_LED_RF_STATE
|
||||
|
||||
const struct iwl_cfg iwl2030_2bgn_cfg = {
|
||||
.name = "Intel(R) Centrino(R) Wireless-N 2230 BGN",
|
||||
const struct iwl_rf_cfg iwl2030_2bgn_cfg = {
|
||||
IWL_DEVICE_2030,
|
||||
.ht_params = &iwl2000_ht_params,
|
||||
.ht_params = {
|
||||
.ht_greenfield_support = true,
|
||||
.use_rts_for_aggregation = true, /* use rts/cts protection */
|
||||
.ht40_bands = BIT(NL80211_BAND_2GHZ),
|
||||
},
|
||||
};
|
||||
|
||||
const char iwl2030_2bgn_name[] = "Intel(R) Centrino(R) Wireless-N 2230 BGN";
|
||||
|
||||
const struct iwl_mac_cfg iwl105_mac_cfg = {
|
||||
.device_family = IWL_DEVICE_FAMILY_105,
|
||||
.base = &iwl2000_base,
|
||||
};
|
||||
|
||||
#define IWL_DEVICE_105 \
|
||||
.fw_name_pre = IWL105_FW_PRE, \
|
||||
.ucode_api_max = IWL105_UCODE_API_MAX, \
|
||||
.ucode_api_min = IWL105_UCODE_API_MIN, \
|
||||
.trans.device_family = IWL_DEVICE_FAMILY_105, \
|
||||
.max_inst_size = IWL60_RTC_INST_SIZE, \
|
||||
.max_data_size = IWL60_RTC_DATA_SIZE, \
|
||||
.nvm_ver = EEPROM_2000_EEPROM_VERSION, \
|
||||
.nvm_calib_ver = EEPROM_2000_TX_POWER_VERSION, \
|
||||
.trans.base_params = &iwl2000_base_params, \
|
||||
.eeprom_params = &iwl20x0_eeprom_params, \
|
||||
.led_mode = IWL_LED_RF_STATE, \
|
||||
.rx_with_siso_diversity = true
|
||||
|
||||
const struct iwl_cfg iwl105_bgn_cfg = {
|
||||
.name = "Intel(R) Centrino(R) Wireless-N 105 BGN",
|
||||
const struct iwl_rf_cfg iwl105_bgn_cfg = {
|
||||
IWL_DEVICE_105,
|
||||
.ht_params = &iwl2000_ht_params,
|
||||
.ht_params = {
|
||||
.ht_greenfield_support = true,
|
||||
.use_rts_for_aggregation = true, /* use rts/cts protection */
|
||||
.ht40_bands = BIT(NL80211_BAND_2GHZ),
|
||||
},
|
||||
};
|
||||
|
||||
const struct iwl_cfg iwl105_bgn_d_cfg = {
|
||||
.name = "Intel(R) Centrino(R) Wireless-N 105D BGN",
|
||||
IWL_DEVICE_105,
|
||||
.ht_params = &iwl2000_ht_params,
|
||||
const char iwl105_bgn_name[] = "Intel(R) Centrino(R) Wireless-N 105 BGN";
|
||||
const char iwl105_bgn_d_name[] = "Intel(R) Centrino(R) Wireless-N 105D BGN";
|
||||
|
||||
const struct iwl_mac_cfg iwl135_mac_cfg = {
|
||||
.device_family = IWL_DEVICE_FAMILY_135,
|
||||
.base = &iwl2030_base,
|
||||
};
|
||||
|
||||
#define IWL_DEVICE_135 \
|
||||
.fw_name_pre = IWL135_FW_PRE, \
|
||||
.ucode_api_max = IWL135_UCODE_API_MAX, \
|
||||
.ucode_api_min = IWL135_UCODE_API_MIN, \
|
||||
.trans.device_family = IWL_DEVICE_FAMILY_135, \
|
||||
.max_inst_size = IWL60_RTC_INST_SIZE, \
|
||||
.max_data_size = IWL60_RTC_DATA_SIZE, \
|
||||
.nvm_ver = EEPROM_2000_EEPROM_VERSION, \
|
||||
.nvm_calib_ver = EEPROM_2000_TX_POWER_VERSION, \
|
||||
.trans.base_params = &iwl2030_base_params, \
|
||||
.eeprom_params = &iwl20x0_eeprom_params, \
|
||||
.led_mode = IWL_LED_RF_STATE, \
|
||||
.rx_with_siso_diversity = true
|
||||
|
||||
const struct iwl_cfg iwl135_bgn_cfg = {
|
||||
.name = "Intel(R) Centrino(R) Wireless-N 135 BGN",
|
||||
const struct iwl_rf_cfg iwl135_bgn_cfg = {
|
||||
IWL_DEVICE_135,
|
||||
.ht_params = &iwl2000_ht_params,
|
||||
.ht_params = {
|
||||
.ht_greenfield_support = true,
|
||||
.use_rts_for_aggregation = true, /* use rts/cts protection */
|
||||
.ht40_bands = BIT(NL80211_BAND_2GHZ),
|
||||
},
|
||||
};
|
||||
|
||||
const char iwl135_bgn_name[] = "Intel(R) Centrino(R) Wireless-N 135 BGN";
|
||||
|
||||
MODULE_FIRMWARE(IWL2000_MODULE_FIRMWARE(IWL2000_UCODE_API_MAX));
|
||||
MODULE_FIRMWARE(IWL2030_MODULE_FIRMWARE(IWL2030_UCODE_API_MAX));
|
||||
MODULE_FIRMWARE(IWL105_MODULE_FIRMWARE(IWL105_UCODE_API_MAX));
|
||||
|
||||
@ -1,7 +1,7 @@
|
||||
// SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause
|
||||
/*
|
||||
* Copyright (C) 2015-2017 Intel Deutschland GmbH
|
||||
* Copyright (C) 2018-2024 Intel Corporation
|
||||
* Copyright (C) 2018-2025 Intel Corporation
|
||||
*/
|
||||
#include <linux/module.h>
|
||||
#include <linux/stringify.h>
|
||||
@ -15,14 +15,7 @@
|
||||
/* Lowest firmware API version supported */
|
||||
#define IWL_22000_UCODE_API_MIN 77
|
||||
|
||||
/* NVM versions */
|
||||
#define IWL_22000_NVM_VERSION 0x0a1d
|
||||
|
||||
/* Memory offsets and lengths */
|
||||
#define IWL_22000_DCCM_OFFSET 0x800000 /* LMAC1 */
|
||||
#define IWL_22000_DCCM_LEN 0x10000 /* LMAC1 */
|
||||
#define IWL_22000_DCCM2_OFFSET 0x880000
|
||||
#define IWL_22000_DCCM2_LEN 0x8000
|
||||
#define IWL_22000_SMEM_OFFSET 0x400000
|
||||
#define IWL_22000_SMEM_LEN 0xD0000
|
||||
|
||||
@ -49,8 +42,7 @@
|
||||
#define IWL_CC_A_MODULE_FIRMWARE(api) \
|
||||
IWL_CC_A_FW_PRE "-" __stringify(api) ".ucode"
|
||||
|
||||
static const struct iwl_base_params iwl_22000_base_params = {
|
||||
.eeprom_size = OTP_LOW_IMAGE_SIZE_32K,
|
||||
static const struct iwl_family_base_params iwl_22000_base = {
|
||||
.num_of_queues = 512,
|
||||
.max_tfd_queue_size = 256,
|
||||
.shadow_ram_support = true,
|
||||
@ -59,155 +51,78 @@ static const struct iwl_base_params iwl_22000_base_params = {
|
||||
.max_event_log_size = 512,
|
||||
.shadow_reg_enable = true,
|
||||
.pcie_l1_allowed = true,
|
||||
.smem_offset = IWL_22000_SMEM_OFFSET,
|
||||
.smem_len = IWL_22000_SMEM_LEN,
|
||||
.features = IWL_TX_CSUM_NETIF_FLAGS | NETIF_F_RXCSUM,
|
||||
.apmg_not_supported = true,
|
||||
.mac_addr_from_csr = 0x380,
|
||||
.min_umac_error_event_table = 0x400000,
|
||||
.d3_debug_data_base_addr = 0x401000,
|
||||
.d3_debug_data_length = 60 * 1024,
|
||||
.mon_smem_regs = {
|
||||
.write_ptr = {
|
||||
.addr = LDBG_M2S_BUF_WPTR,
|
||||
.mask = LDBG_M2S_BUF_WPTR_VAL_MSK,
|
||||
},
|
||||
.cycle_cnt = {
|
||||
.addr = LDBG_M2S_BUF_WRAP_CNT,
|
||||
.mask = LDBG_M2S_BUF_WRAP_CNT_VAL_MSK,
|
||||
},
|
||||
},
|
||||
.gp2_reg_addr = 0xa02c68,
|
||||
.mon_dram_regs = {
|
||||
.write_ptr = {
|
||||
.addr = MON_BUFF_WRPTR_VER2,
|
||||
.mask = 0xffffffff,
|
||||
},
|
||||
.cycle_cnt = {
|
||||
.addr = MON_BUFF_CYCLE_CNT_VER2,
|
||||
.mask = 0xffffffff,
|
||||
},
|
||||
},
|
||||
.ucode_api_min = IWL_22000_UCODE_API_MIN,
|
||||
.ucode_api_max = IWL_22000_UCODE_API_MAX,
|
||||
};
|
||||
|
||||
const struct iwl_ht_params iwl_22000_ht_params = {
|
||||
.stbc = true,
|
||||
.ldpc = true,
|
||||
.ht40_bands = BIT(NL80211_BAND_2GHZ) | BIT(NL80211_BAND_5GHZ) |
|
||||
BIT(NL80211_BAND_6GHZ),
|
||||
};
|
||||
|
||||
#define IWL_DEVICE_22000_COMMON \
|
||||
.ucode_api_min = IWL_22000_UCODE_API_MIN, \
|
||||
.led_mode = IWL_LED_RF_STATE, \
|
||||
.nvm_hw_section_num = 10, \
|
||||
.non_shared_ant = ANT_B, \
|
||||
.dccm_offset = IWL_22000_DCCM_OFFSET, \
|
||||
.dccm_len = IWL_22000_DCCM_LEN, \
|
||||
.dccm2_offset = IWL_22000_DCCM2_OFFSET, \
|
||||
.dccm2_len = IWL_22000_DCCM2_LEN, \
|
||||
.smem_offset = IWL_22000_SMEM_OFFSET, \
|
||||
.smem_len = IWL_22000_SMEM_LEN, \
|
||||
.features = IWL_TX_CSUM_NETIF_FLAGS | NETIF_F_RXCSUM, \
|
||||
.apmg_not_supported = true, \
|
||||
.trans.mq_rx_supported = true, \
|
||||
.vht_mu_mimo_supported = true, \
|
||||
.mac_addr_from_csr = 0x380, \
|
||||
.ht_params = &iwl_22000_ht_params, \
|
||||
.nvm_ver = IWL_22000_NVM_VERSION, \
|
||||
.trans.rf_id = true, \
|
||||
.trans.gen2 = true, \
|
||||
.nvm_type = IWL_NVM_EXT, \
|
||||
.dbgc_supported = true, \
|
||||
.min_umac_error_event_table = 0x400000, \
|
||||
.d3_debug_data_base_addr = 0x401000, \
|
||||
.d3_debug_data_length = 60 * 1024, \
|
||||
.mon_smem_regs = { \
|
||||
.write_ptr = { \
|
||||
.addr = LDBG_M2S_BUF_WPTR, \
|
||||
.mask = LDBG_M2S_BUF_WPTR_VAL_MSK, \
|
||||
}, \
|
||||
.cycle_cnt = { \
|
||||
.addr = LDBG_M2S_BUF_WRAP_CNT, \
|
||||
.mask = LDBG_M2S_BUF_WRAP_CNT_VAL_MSK, \
|
||||
}, \
|
||||
}
|
||||
|
||||
#define IWL_DEVICE_22500 \
|
||||
IWL_DEVICE_22000_COMMON, \
|
||||
.ucode_api_max = IWL_22000_UCODE_API_MAX, \
|
||||
.trans.device_family = IWL_DEVICE_FAMILY_22000, \
|
||||
.trans.base_params = &iwl_22000_base_params, \
|
||||
.gp2_reg_addr = 0xa02c68, \
|
||||
.mon_dram_regs = { \
|
||||
.write_ptr = { \
|
||||
.addr = MON_BUFF_WRPTR_VER2, \
|
||||
.mask = 0xffffffff, \
|
||||
}, \
|
||||
.cycle_cnt = { \
|
||||
.addr = MON_BUFF_CYCLE_CNT_VER2, \
|
||||
.mask = 0xffffffff, \
|
||||
}, \
|
||||
}
|
||||
|
||||
const struct iwl_cfg_trans_params iwl_qu_trans_cfg = {
|
||||
const struct iwl_mac_cfg iwl_qu_mac_cfg = {
|
||||
.mq_rx_supported = true,
|
||||
.rf_id = true,
|
||||
.gen2 = true,
|
||||
.device_family = IWL_DEVICE_FAMILY_22000,
|
||||
.base_params = &iwl_22000_base_params,
|
||||
.base = &iwl_22000_base,
|
||||
.integrated = true,
|
||||
.xtal_latency = 500,
|
||||
.ltr_delay = IWL_CFG_TRANS_LTR_DELAY_200US,
|
||||
};
|
||||
|
||||
const struct iwl_cfg_trans_params iwl_qu_medium_latency_trans_cfg = {
|
||||
const struct iwl_mac_cfg iwl_qu_medium_latency_mac_cfg = {
|
||||
.mq_rx_supported = true,
|
||||
.rf_id = true,
|
||||
.gen2 = true,
|
||||
.device_family = IWL_DEVICE_FAMILY_22000,
|
||||
.base_params = &iwl_22000_base_params,
|
||||
.base = &iwl_22000_base,
|
||||
.integrated = true,
|
||||
.xtal_latency = 1820,
|
||||
.ltr_delay = IWL_CFG_TRANS_LTR_DELAY_1820US,
|
||||
};
|
||||
|
||||
const struct iwl_cfg_trans_params iwl_qu_long_latency_trans_cfg = {
|
||||
const struct iwl_mac_cfg iwl_qu_long_latency_mac_cfg = {
|
||||
.mq_rx_supported = true,
|
||||
.rf_id = true,
|
||||
.gen2 = true,
|
||||
.device_family = IWL_DEVICE_FAMILY_22000,
|
||||
.base_params = &iwl_22000_base_params,
|
||||
.base = &iwl_22000_base,
|
||||
.integrated = true,
|
||||
.xtal_latency = 12000,
|
||||
.low_latency_xtal = true,
|
||||
.ltr_delay = IWL_CFG_TRANS_LTR_DELAY_2500US,
|
||||
};
|
||||
|
||||
/*
|
||||
* If the device doesn't support HE, no need to have that many buffers.
|
||||
* 22000 devices can split multiple frames into a single RB, so fewer are
|
||||
* needed; AX210 cannot (but use smaller RBs by default) - these sizes
|
||||
* were picked according to 8 MSDUs inside 256 A-MSDUs in an A-MPDU, with
|
||||
* additional overhead to account for processing time.
|
||||
*/
|
||||
#define IWL_NUM_RBDS_NON_HE 512
|
||||
#define IWL_NUM_RBDS_22000_HE 2048
|
||||
|
||||
/*
|
||||
* All JF radio modules are part of the 9000 series, but the MAC part
|
||||
* looks more like 22000. That's why this device is here, but called
|
||||
* 9560 nevertheless.
|
||||
*/
|
||||
const struct iwl_cfg iwl9560_qu_b0_jf_b0_cfg = {
|
||||
.fw_name_pre = IWL_QU_B_JF_B_FW_PRE,
|
||||
IWL_DEVICE_22500,
|
||||
.num_rbds = IWL_NUM_RBDS_NON_HE,
|
||||
};
|
||||
|
||||
const struct iwl_cfg iwl9560_qu_c0_jf_b0_cfg = {
|
||||
.fw_name_pre = IWL_QU_C_JF_B_FW_PRE,
|
||||
IWL_DEVICE_22500,
|
||||
.num_rbds = IWL_NUM_RBDS_NON_HE,
|
||||
};
|
||||
|
||||
const struct iwl_cfg iwl9560_quz_a0_jf_b0_cfg = {
|
||||
.fw_name_pre = IWL_QUZ_A_JF_B_FW_PRE,
|
||||
IWL_DEVICE_22500,
|
||||
/*
|
||||
* This device doesn't support receiving BlockAck with a large bitmap
|
||||
* so we need to restrict the size of transmitted aggregation to the
|
||||
* HT size; mac80211 would otherwise pick the HE max (256) by default.
|
||||
*/
|
||||
.max_tx_agg_size = IEEE80211_MAX_AMPDU_BUF_HT,
|
||||
.num_rbds = IWL_NUM_RBDS_NON_HE,
|
||||
};
|
||||
|
||||
const struct iwl_cfg_trans_params iwl_ax200_trans_cfg = {
|
||||
const struct iwl_mac_cfg iwl_ax200_mac_cfg = {
|
||||
.device_family = IWL_DEVICE_FAMILY_22000,
|
||||
.base_params = &iwl_22000_base_params,
|
||||
.base = &iwl_22000_base,
|
||||
.mq_rx_supported = true,
|
||||
.rf_id = true,
|
||||
.gen2 = true,
|
||||
.bisr_workaround = 1,
|
||||
};
|
||||
|
||||
const char iwl_ax101_name[] = "Intel(R) Wi-Fi 6 AX101";
|
||||
const char iwl_ax200_name[] = "Intel(R) Wi-Fi 6 AX200 160MHz";
|
||||
const char iwl_ax201_name[] = "Intel(R) Wi-Fi 6 AX201 160MHz";
|
||||
const char iwl_ax203_name[] = "Intel(R) Wi-Fi 6 AX203";
|
||||
|
||||
const char iwl_ax200_killer_1650w_name[] =
|
||||
"Killer(R) Wi-Fi 6 AX1650w 160MHz Wireless Network Adapter (200D2W)";
|
||||
const char iwl_ax200_killer_1650x_name[] =
|
||||
@ -217,210 +132,6 @@ const char iwl_ax201_killer_1650s_name[] =
|
||||
const char iwl_ax201_killer_1650i_name[] =
|
||||
"Killer(R) Wi-Fi 6 AX1650i 160MHz Wireless Network Adapter (201NGW)";
|
||||
|
||||
const struct iwl_cfg iwl_qu_b0_hr1_b0 = {
|
||||
.fw_name_pre = IWL_QU_B_HR_B_FW_PRE,
|
||||
IWL_DEVICE_22500,
|
||||
/*
|
||||
* This device doesn't support receiving BlockAck with a large bitmap
|
||||
* so we need to restrict the size of transmitted aggregation to the
|
||||
* HT size; mac80211 would otherwise pick the HE max (256) by default.
|
||||
*/
|
||||
.max_tx_agg_size = IEEE80211_MAX_AMPDU_BUF_HT,
|
||||
.tx_with_siso_diversity = true,
|
||||
.num_rbds = IWL_NUM_RBDS_22000_HE,
|
||||
};
|
||||
|
||||
const struct iwl_cfg iwl_qu_b0_hr_b0 = {
|
||||
.fw_name_pre = IWL_QU_B_HR_B_FW_PRE,
|
||||
IWL_DEVICE_22500,
|
||||
/*
|
||||
* This device doesn't support receiving BlockAck with a large bitmap
|
||||
* so we need to restrict the size of transmitted aggregation to the
|
||||
* HT size; mac80211 would otherwise pick the HE max (256) by default.
|
||||
*/
|
||||
.max_tx_agg_size = IEEE80211_MAX_AMPDU_BUF_HT,
|
||||
.num_rbds = IWL_NUM_RBDS_22000_HE,
|
||||
};
|
||||
|
||||
const struct iwl_cfg iwl_ax201_cfg_qu_hr = {
|
||||
.name = "Intel(R) Wi-Fi 6 AX201 160MHz",
|
||||
.fw_name_pre = IWL_QU_B_HR_B_FW_PRE,
|
||||
IWL_DEVICE_22500,
|
||||
/*
|
||||
* This device doesn't support receiving BlockAck with a large bitmap
|
||||
* so we need to restrict the size of transmitted aggregation to the
|
||||
* HT size; mac80211 would otherwise pick the HE max (256) by default.
|
||||
*/
|
||||
.max_tx_agg_size = IEEE80211_MAX_AMPDU_BUF_HT,
|
||||
.num_rbds = IWL_NUM_RBDS_22000_HE,
|
||||
};
|
||||
|
||||
const struct iwl_cfg iwl_qu_c0_hr1_b0 = {
|
||||
.fw_name_pre = IWL_QU_C_HR_B_FW_PRE,
|
||||
IWL_DEVICE_22500,
|
||||
/*
|
||||
* This device doesn't support receiving BlockAck with a large bitmap
|
||||
* so we need to restrict the size of transmitted aggregation to the
|
||||
* HT size; mac80211 would otherwise pick the HE max (256) by default.
|
||||
*/
|
||||
.max_tx_agg_size = IEEE80211_MAX_AMPDU_BUF_HT,
|
||||
.tx_with_siso_diversity = true,
|
||||
.num_rbds = IWL_NUM_RBDS_22000_HE,
|
||||
};
|
||||
|
||||
const struct iwl_cfg iwl_qu_c0_hr_b0 = {
|
||||
.fw_name_pre = IWL_QU_C_HR_B_FW_PRE,
|
||||
IWL_DEVICE_22500,
|
||||
/*
|
||||
* This device doesn't support receiving BlockAck with a large bitmap
|
||||
* so we need to restrict the size of transmitted aggregation to the
|
||||
* HT size; mac80211 would otherwise pick the HE max (256) by default.
|
||||
*/
|
||||
.max_tx_agg_size = IEEE80211_MAX_AMPDU_BUF_HT,
|
||||
.num_rbds = IWL_NUM_RBDS_22000_HE,
|
||||
};
|
||||
|
||||
const struct iwl_cfg iwl_ax201_cfg_qu_c0_hr_b0 = {
|
||||
.name = "Intel(R) Wi-Fi 6 AX201 160MHz",
|
||||
.fw_name_pre = IWL_QU_C_HR_B_FW_PRE,
|
||||
IWL_DEVICE_22500,
|
||||
/*
|
||||
* This device doesn't support receiving BlockAck with a large bitmap
|
||||
* so we need to restrict the size of transmitted aggregation to the
|
||||
* HT size; mac80211 would otherwise pick the HE max (256) by default.
|
||||
*/
|
||||
.max_tx_agg_size = IEEE80211_MAX_AMPDU_BUF_HT,
|
||||
.num_rbds = IWL_NUM_RBDS_22000_HE,
|
||||
};
|
||||
|
||||
const struct iwl_cfg iwl_quz_a0_hr1_b0 = {
|
||||
.fw_name_pre = IWL_QUZ_A_HR_B_FW_PRE,
|
||||
IWL_DEVICE_22500,
|
||||
/*
|
||||
* This device doesn't support receiving BlockAck with a large bitmap
|
||||
* so we need to restrict the size of transmitted aggregation to the
|
||||
* HT size; mac80211 would otherwise pick the HE max (256) by default.
|
||||
*/
|
||||
.max_tx_agg_size = IEEE80211_MAX_AMPDU_BUF_HT,
|
||||
.tx_with_siso_diversity = true,
|
||||
.num_rbds = IWL_NUM_RBDS_22000_HE,
|
||||
};
|
||||
|
||||
const struct iwl_cfg iwl_ax201_cfg_quz_hr = {
|
||||
.name = "Intel(R) Wi-Fi 6 AX201 160MHz",
|
||||
.fw_name_pre = IWL_QUZ_A_HR_B_FW_PRE,
|
||||
IWL_DEVICE_22500,
|
||||
/*
|
||||
* This device doesn't support receiving BlockAck with a large bitmap
|
||||
* so we need to restrict the size of transmitted aggregation to the
|
||||
* HT size; mac80211 would otherwise pick the HE max (256) by default.
|
||||
*/
|
||||
.max_tx_agg_size = IEEE80211_MAX_AMPDU_BUF_HT,
|
||||
.num_rbds = IWL_NUM_RBDS_22000_HE,
|
||||
};
|
||||
|
||||
const struct iwl_cfg iwl_ax1650s_cfg_quz_hr = {
|
||||
.name = "Killer(R) Wi-Fi 6 AX1650s 160MHz Wireless Network Adapter (201D2W)",
|
||||
.fw_name_pre = IWL_QUZ_A_HR_B_FW_PRE,
|
||||
IWL_DEVICE_22500,
|
||||
/*
|
||||
* This device doesn't support receiving BlockAck with a large bitmap
|
||||
* so we need to restrict the size of transmitted aggregation to the
|
||||
* HT size; mac80211 would otherwise pick the HE max (256) by default.
|
||||
*/
|
||||
.max_tx_agg_size = IEEE80211_MAX_AMPDU_BUF_HT,
|
||||
.num_rbds = IWL_NUM_RBDS_22000_HE,
|
||||
};
|
||||
|
||||
const struct iwl_cfg iwl_ax1650i_cfg_quz_hr = {
|
||||
.name = "Killer(R) Wi-Fi 6 AX1650i 160MHz Wireless Network Adapter (201NGW)",
|
||||
.fw_name_pre = IWL_QUZ_A_HR_B_FW_PRE,
|
||||
IWL_DEVICE_22500,
|
||||
/*
|
||||
* This device doesn't support receiving BlockAck with a large bitmap
|
||||
* so we need to restrict the size of transmitted aggregation to the
|
||||
* HT size; mac80211 would otherwise pick the HE max (256) by default.
|
||||
*/
|
||||
.max_tx_agg_size = IEEE80211_MAX_AMPDU_BUF_HT,
|
||||
.num_rbds = IWL_NUM_RBDS_22000_HE,
|
||||
};
|
||||
|
||||
const struct iwl_cfg iwl_ax200_cfg_cc = {
|
||||
.fw_name_pre = IWL_CC_A_FW_PRE,
|
||||
IWL_DEVICE_22500,
|
||||
/*
|
||||
* This device doesn't support receiving BlockAck with a large bitmap
|
||||
* so we need to restrict the size of transmitted aggregation to the
|
||||
* HT size; mac80211 would otherwise pick the HE max (256) by default.
|
||||
*/
|
||||
.max_tx_agg_size = IEEE80211_MAX_AMPDU_BUF_HT,
|
||||
.num_rbds = IWL_NUM_RBDS_22000_HE,
|
||||
};
|
||||
|
||||
const struct iwl_cfg killer1650s_2ax_cfg_qu_b0_hr_b0 = {
|
||||
.name = "Killer(R) Wi-Fi 6 AX1650s 160MHz Wireless Network Adapter (201NGW)",
|
||||
.fw_name_pre = IWL_QU_B_HR_B_FW_PRE,
|
||||
IWL_DEVICE_22500,
|
||||
/*
|
||||
* This device doesn't support receiving BlockAck with a large bitmap
|
||||
* so we need to restrict the size of transmitted aggregation to the
|
||||
* HT size; mac80211 would otherwise pick the HE max (256) by default.
|
||||
*/
|
||||
.max_tx_agg_size = IEEE80211_MAX_AMPDU_BUF_HT,
|
||||
.num_rbds = IWL_NUM_RBDS_22000_HE,
|
||||
};
|
||||
|
||||
const struct iwl_cfg killer1650i_2ax_cfg_qu_b0_hr_b0 = {
|
||||
.name = "Killer(R) Wi-Fi 6 AX1650i 160MHz Wireless Network Adapter (201D2W)",
|
||||
.fw_name_pre = IWL_QU_B_HR_B_FW_PRE,
|
||||
IWL_DEVICE_22500,
|
||||
/*
|
||||
* This device doesn't support receiving BlockAck with a large bitmap
|
||||
* so we need to restrict the size of transmitted aggregation to the
|
||||
* HT size; mac80211 would otherwise pick the HE max (256) by default.
|
||||
*/
|
||||
.max_tx_agg_size = IEEE80211_MAX_AMPDU_BUF_HT,
|
||||
.num_rbds = IWL_NUM_RBDS_22000_HE,
|
||||
};
|
||||
|
||||
const struct iwl_cfg killer1650s_2ax_cfg_qu_c0_hr_b0 = {
|
||||
.name = "Killer(R) Wi-Fi 6 AX1650s 160MHz Wireless Network Adapter (201NGW)",
|
||||
.fw_name_pre = IWL_QU_C_HR_B_FW_PRE,
|
||||
IWL_DEVICE_22500,
|
||||
/*
|
||||
* This device doesn't support receiving BlockAck with a large bitmap
|
||||
* so we need to restrict the size of transmitted aggregation to the
|
||||
* HT size; mac80211 would otherwise pick the HE max (256) by default.
|
||||
*/
|
||||
.max_tx_agg_size = IEEE80211_MAX_AMPDU_BUF_HT,
|
||||
.num_rbds = IWL_NUM_RBDS_22000_HE,
|
||||
};
|
||||
|
||||
const struct iwl_cfg killer1650i_2ax_cfg_qu_c0_hr_b0 = {
|
||||
.name = "Killer(R) Wi-Fi 6 AX1650i 160MHz Wireless Network Adapter (201D2W)",
|
||||
.fw_name_pre = IWL_QU_C_HR_B_FW_PRE,
|
||||
IWL_DEVICE_22500,
|
||||
/*
|
||||
* This device doesn't support receiving BlockAck with a large bitmap
|
||||
* so we need to restrict the size of transmitted aggregation to the
|
||||
* HT size; mac80211 would otherwise pick the HE max (256) by default.
|
||||
*/
|
||||
.max_tx_agg_size = IEEE80211_MAX_AMPDU_BUF_HT,
|
||||
.num_rbds = IWL_NUM_RBDS_22000_HE,
|
||||
};
|
||||
|
||||
const struct iwl_cfg iwl_cfg_quz_a0_hr_b0 = {
|
||||
.fw_name_pre = IWL_QUZ_A_HR_B_FW_PRE,
|
||||
IWL_DEVICE_22500,
|
||||
/*
|
||||
* This device doesn't support receiving BlockAck with a large bitmap
|
||||
* so we need to restrict the size of transmitted aggregation to the
|
||||
* HT size; mac80211 would otherwise pick the HE max (256) by default.
|
||||
*/
|
||||
.max_tx_agg_size = IEEE80211_MAX_AMPDU_BUF_HT,
|
||||
.num_rbds = IWL_NUM_RBDS_22000_HE,
|
||||
};
|
||||
|
||||
MODULE_FIRMWARE(IWL_QU_B_HR_B_MODULE_FIRMWARE(IWL_22000_UCODE_API_MAX));
|
||||
MODULE_FIRMWARE(IWL_QU_C_HR_B_MODULE_FIRMWARE(IWL_22000_UCODE_API_MAX));
|
||||
MODULE_FIRMWARE(IWL_QU_B_JF_B_MODULE_FIRMWARE(IWL_22000_UCODE_API_MAX));
|
||||
|
||||
@ -2,7 +2,7 @@
|
||||
/******************************************************************************
|
||||
*
|
||||
* Copyright(c) 2007 - 2014 Intel Corporation. All rights reserved.
|
||||
* Copyright(c) 2018 - 2020, 2023 Intel Corporation
|
||||
* Copyright(c) 2018 - 2020, 2023, 2025 Intel Corporation
|
||||
*****************************************************************************/
|
||||
|
||||
#include <linux/module.h>
|
||||
@ -30,7 +30,7 @@
|
||||
#define IWL5150_FW_PRE "iwlwifi-5150"
|
||||
#define IWL5150_MODULE_FIRMWARE(api) IWL5150_FW_PRE "-" __stringify(api) ".ucode"
|
||||
|
||||
static const struct iwl_base_params iwl5000_base_params = {
|
||||
static const struct iwl_family_base_params iwl5000_base = {
|
||||
.eeprom_size = IWLAGN_EEPROM_IMG_SIZE,
|
||||
.num_of_queues = IWLAGN_NUM_QUEUES,
|
||||
.max_tfd_queue_size = 256,
|
||||
@ -41,11 +41,6 @@ static const struct iwl_base_params iwl5000_base_params = {
|
||||
.scd_chain_ext_wa = true,
|
||||
};
|
||||
|
||||
static const struct iwl_ht_params iwl5000_ht_params = {
|
||||
.ht_greenfield_support = true,
|
||||
.ht40_bands = BIT(NL80211_BAND_2GHZ) | BIT(NL80211_BAND_5GHZ),
|
||||
};
|
||||
|
||||
static const struct iwl_eeprom_params iwl5000_eeprom_params = {
|
||||
.regulatory_bands = {
|
||||
EEPROM_REG_BAND_1_CHANNELS,
|
||||
@ -58,93 +53,107 @@ static const struct iwl_eeprom_params iwl5000_eeprom_params = {
|
||||
},
|
||||
};
|
||||
|
||||
const struct iwl_mac_cfg iwl5000_mac_cfg = {
|
||||
.device_family = IWL_DEVICE_FAMILY_5000,
|
||||
.base = &iwl5000_base,
|
||||
};
|
||||
|
||||
#define IWL_DEVICE_5000 \
|
||||
.fw_name_pre = IWL5000_FW_PRE, \
|
||||
.ucode_api_max = IWL5000_UCODE_API_MAX, \
|
||||
.ucode_api_min = IWL5000_UCODE_API_MIN, \
|
||||
.trans.device_family = IWL_DEVICE_FAMILY_5000, \
|
||||
.max_inst_size = IWLAGN_RTC_INST_SIZE, \
|
||||
.max_data_size = IWLAGN_RTC_DATA_SIZE, \
|
||||
.nvm_ver = EEPROM_5000_EEPROM_VERSION, \
|
||||
.nvm_calib_ver = EEPROM_5000_TX_POWER_VERSION, \
|
||||
.trans.base_params = &iwl5000_base_params, \
|
||||
.eeprom_params = &iwl5000_eeprom_params, \
|
||||
.led_mode = IWL_LED_BLINK
|
||||
|
||||
const struct iwl_cfg iwl5300_agn_cfg = {
|
||||
.name = "Intel(R) Ultimate N WiFi Link 5300 AGN",
|
||||
const struct iwl_rf_cfg iwl5300_agn_cfg = {
|
||||
IWL_DEVICE_5000,
|
||||
/* at least EEPROM 0x11A has wrong info */
|
||||
.valid_tx_ant = ANT_ABC, /* .cfg overwrite */
|
||||
.valid_rx_ant = ANT_ABC, /* .cfg overwrite */
|
||||
.ht_params = &iwl5000_ht_params,
|
||||
.ht_params = {
|
||||
.ht_greenfield_support = true,
|
||||
.ht40_bands = BIT(NL80211_BAND_2GHZ) | BIT(NL80211_BAND_5GHZ),
|
||||
},
|
||||
};
|
||||
|
||||
const struct iwl_cfg iwl5100_bgn_cfg = {
|
||||
.name = "Intel(R) WiFi Link 5100 BGN",
|
||||
const char iwl5300_agn_name[] = "Intel(R) Ultimate N WiFi Link 5300 AGN";
|
||||
|
||||
const struct iwl_rf_cfg iwl5100_n_cfg = {
|
||||
IWL_DEVICE_5000,
|
||||
.valid_tx_ant = ANT_B, /* .cfg overwrite */
|
||||
.valid_rx_ant = ANT_AB, /* .cfg overwrite */
|
||||
.ht_params = &iwl5000_ht_params,
|
||||
.ht_params = {
|
||||
.ht_greenfield_support = true,
|
||||
.ht40_bands = BIT(NL80211_BAND_2GHZ) | BIT(NL80211_BAND_5GHZ),
|
||||
},
|
||||
};
|
||||
|
||||
const struct iwl_cfg iwl5100_abg_cfg = {
|
||||
.name = "Intel(R) WiFi Link 5100 ABG",
|
||||
const char iwl5100_bgn_name[] = "Intel(R) WiFi Link 5100 BGN";
|
||||
|
||||
const struct iwl_rf_cfg iwl5100_abg_cfg = {
|
||||
IWL_DEVICE_5000,
|
||||
.valid_tx_ant = ANT_B, /* .cfg overwrite */
|
||||
.valid_rx_ant = ANT_AB, /* .cfg overwrite */
|
||||
};
|
||||
|
||||
const struct iwl_cfg iwl5100_agn_cfg = {
|
||||
.name = "Intel(R) WiFi Link 5100 AGN",
|
||||
IWL_DEVICE_5000,
|
||||
.valid_tx_ant = ANT_B, /* .cfg overwrite */
|
||||
.valid_rx_ant = ANT_AB, /* .cfg overwrite */
|
||||
.ht_params = &iwl5000_ht_params,
|
||||
};
|
||||
const char iwl5100_abg_name[] = "Intel(R) WiFi Link 5100 ABG";
|
||||
const char iwl5100_agn_name[] = "Intel(R) WiFi Link 5100 AGN";
|
||||
|
||||
const struct iwl_cfg iwl5350_agn_cfg = {
|
||||
.name = "Intel(R) WiMAX/WiFi Link 5350 AGN",
|
||||
const struct iwl_rf_cfg iwl5350_agn_cfg = {
|
||||
.fw_name_pre = IWL5000_FW_PRE,
|
||||
.ucode_api_max = IWL5000_UCODE_API_MAX,
|
||||
.ucode_api_min = IWL5000_UCODE_API_MIN,
|
||||
.trans.device_family = IWL_DEVICE_FAMILY_5000,
|
||||
.max_inst_size = IWLAGN_RTC_INST_SIZE,
|
||||
.max_data_size = IWLAGN_RTC_DATA_SIZE,
|
||||
.nvm_ver = EEPROM_5050_EEPROM_VERSION,
|
||||
.nvm_calib_ver = EEPROM_5050_TX_POWER_VERSION,
|
||||
.trans.base_params = &iwl5000_base_params,
|
||||
.eeprom_params = &iwl5000_eeprom_params,
|
||||
.ht_params = &iwl5000_ht_params,
|
||||
.ht_params = {
|
||||
.ht_greenfield_support = true,
|
||||
.ht40_bands = BIT(NL80211_BAND_2GHZ) | BIT(NL80211_BAND_5GHZ),
|
||||
},
|
||||
.led_mode = IWL_LED_BLINK,
|
||||
.internal_wimax_coex = true,
|
||||
};
|
||||
|
||||
const char iwl5350_agn_name[] = "Intel(R) WiMAX/WiFi Link 5350 AGN";
|
||||
|
||||
const struct iwl_mac_cfg iwl5150_mac_cfg = {
|
||||
.device_family = IWL_DEVICE_FAMILY_5150,
|
||||
.base = &iwl5000_base,
|
||||
};
|
||||
|
||||
#define IWL_DEVICE_5150 \
|
||||
.fw_name_pre = IWL5150_FW_PRE, \
|
||||
.ucode_api_max = IWL5150_UCODE_API_MAX, \
|
||||
.ucode_api_min = IWL5150_UCODE_API_MIN, \
|
||||
.trans.device_family = IWL_DEVICE_FAMILY_5150, \
|
||||
.max_inst_size = IWLAGN_RTC_INST_SIZE, \
|
||||
.max_data_size = IWLAGN_RTC_DATA_SIZE, \
|
||||
.nvm_ver = EEPROM_5050_EEPROM_VERSION, \
|
||||
.nvm_calib_ver = EEPROM_5050_TX_POWER_VERSION, \
|
||||
.trans.base_params = &iwl5000_base_params, \
|
||||
.eeprom_params = &iwl5000_eeprom_params, \
|
||||
.led_mode = IWL_LED_BLINK, \
|
||||
.internal_wimax_coex = true
|
||||
|
||||
const struct iwl_cfg iwl5150_agn_cfg = {
|
||||
.name = "Intel(R) WiMAX/WiFi Link 5150 AGN",
|
||||
const struct iwl_rf_cfg iwl5150_agn_cfg = {
|
||||
IWL_DEVICE_5150,
|
||||
.ht_params = &iwl5000_ht_params,
|
||||
|
||||
.ht_params = {
|
||||
.ht_greenfield_support = true,
|
||||
.ht40_bands = BIT(NL80211_BAND_2GHZ) | BIT(NL80211_BAND_5GHZ),
|
||||
},
|
||||
};
|
||||
|
||||
const struct iwl_cfg iwl5150_abg_cfg = {
|
||||
.name = "Intel(R) WiMAX/WiFi Link 5150 ABG",
|
||||
const char iwl5150_agn_name[] = "Intel(R) WiMAX/WiFi Link 5150 AGN";
|
||||
|
||||
const struct iwl_rf_cfg iwl5150_abg_cfg = {
|
||||
IWL_DEVICE_5150,
|
||||
};
|
||||
|
||||
const char iwl5150_abg_name[] = "Intel(R) WiMAX/WiFi Link 5150 ABG";
|
||||
|
||||
MODULE_FIRMWARE(IWL5000_MODULE_FIRMWARE(IWL5000_UCODE_API_MAX));
|
||||
MODULE_FIRMWARE(IWL5150_MODULE_FIRMWARE(IWL5150_UCODE_API_MAX));
|
||||
|
||||
@ -2,7 +2,7 @@
|
||||
/******************************************************************************
|
||||
*
|
||||
* Copyright(c) 2008 - 2014 Intel Corporation. All rights reserved.
|
||||
* Copyright(c) 2018 - 2020, 2023 Intel Corporation
|
||||
* Copyright(c) 2018 - 2020, 2023, 2025 Intel Corporation
|
||||
*****************************************************************************/
|
||||
|
||||
#include <linux/module.h>
|
||||
@ -49,7 +49,7 @@
|
||||
#define IWL6030_FW_PRE "iwlwifi-6000g2b"
|
||||
#define IWL6030_MODULE_FIRMWARE(api) IWL6030_FW_PRE "-" __stringify(api) ".ucode"
|
||||
|
||||
static const struct iwl_base_params iwl6000_base_params = {
|
||||
static const struct iwl_family_base_params iwl6000_base = {
|
||||
.eeprom_size = OTP_LOW_IMAGE_SIZE_2K,
|
||||
.num_of_queues = IWLAGN_NUM_QUEUES,
|
||||
.max_tfd_queue_size = 256,
|
||||
@ -62,7 +62,7 @@ static const struct iwl_base_params iwl6000_base_params = {
|
||||
.scd_chain_ext_wa = true,
|
||||
};
|
||||
|
||||
static const struct iwl_base_params iwl6050_base_params = {
|
||||
static const struct iwl_family_base_params iwl6050_base = {
|
||||
.eeprom_size = OTP_LOW_IMAGE_SIZE_2K,
|
||||
.num_of_queues = IWLAGN_NUM_QUEUES,
|
||||
.max_tfd_queue_size = 256,
|
||||
@ -75,7 +75,7 @@ static const struct iwl_base_params iwl6050_base_params = {
|
||||
.scd_chain_ext_wa = true,
|
||||
};
|
||||
|
||||
static const struct iwl_base_params iwl6000_g2_base_params = {
|
||||
static const struct iwl_family_base_params iwl6000_g2_base = {
|
||||
.eeprom_size = OTP_LOW_IMAGE_SIZE_2K,
|
||||
.num_of_queues = IWLAGN_NUM_QUEUES,
|
||||
.max_tfd_queue_size = 256,
|
||||
@ -88,12 +88,6 @@ static const struct iwl_base_params iwl6000_g2_base_params = {
|
||||
.scd_chain_ext_wa = true,
|
||||
};
|
||||
|
||||
static const struct iwl_ht_params iwl6000_ht_params = {
|
||||
.ht_greenfield_support = true,
|
||||
.use_rts_for_aggregation = true, /* use rts/cts protection */
|
||||
.ht40_bands = BIT(NL80211_BAND_2GHZ) | BIT(NL80211_BAND_5GHZ),
|
||||
};
|
||||
|
||||
static const struct iwl_eeprom_params iwl6000_eeprom_params = {
|
||||
.regulatory_bands = {
|
||||
EEPROM_REG_BAND_1_CHANNELS,
|
||||
@ -107,143 +101,128 @@ static const struct iwl_eeprom_params iwl6000_eeprom_params = {
|
||||
.enhanced_txpower = true,
|
||||
};
|
||||
|
||||
const struct iwl_mac_cfg iwl6005_mac_cfg = {
|
||||
.device_family = IWL_DEVICE_FAMILY_6005,
|
||||
.base = &iwl6000_g2_base,
|
||||
};
|
||||
|
||||
#define IWL_DEVICE_6005 \
|
||||
.fw_name_pre = IWL6005_FW_PRE, \
|
||||
.ucode_api_max = IWL6000G2_UCODE_API_MAX, \
|
||||
.ucode_api_min = IWL6000G2_UCODE_API_MIN, \
|
||||
.trans.device_family = IWL_DEVICE_FAMILY_6005, \
|
||||
.max_inst_size = IWL60_RTC_INST_SIZE, \
|
||||
.max_data_size = IWL60_RTC_DATA_SIZE, \
|
||||
.nvm_ver = EEPROM_6005_EEPROM_VERSION, \
|
||||
.nvm_calib_ver = EEPROM_6005_TX_POWER_VERSION, \
|
||||
.trans.base_params = &iwl6000_g2_base_params, \
|
||||
.eeprom_params = &iwl6000_eeprom_params, \
|
||||
.led_mode = IWL_LED_RF_STATE
|
||||
|
||||
const struct iwl_cfg iwl6005_2agn_cfg = {
|
||||
.name = "Intel(R) Centrino(R) Advanced-N 6205 AGN",
|
||||
const struct iwl_rf_cfg iwl6005_n_cfg = {
|
||||
IWL_DEVICE_6005,
|
||||
.ht_params = &iwl6000_ht_params,
|
||||
.ht_params = {
|
||||
.ht_greenfield_support = true,
|
||||
.use_rts_for_aggregation = true, /* use rts/cts protection */
|
||||
.ht40_bands = BIT(NL80211_BAND_2GHZ) | BIT(NL80211_BAND_5GHZ),
|
||||
},
|
||||
};
|
||||
|
||||
const struct iwl_cfg iwl6005_2abg_cfg = {
|
||||
.name = "Intel(R) Centrino(R) Advanced-N 6205 ABG",
|
||||
const char iwl6005_2agn_name[] = "Intel(R) Centrino(R) Advanced-N 6205 AGN";
|
||||
const char iwl6005_2agn_sff_name[] = "Intel(R) Centrino(R) Advanced-N 6205S AGN";
|
||||
const char iwl6005_2agn_d_name[] = "Intel(R) Centrino(R) Advanced-N 6205D AGN";
|
||||
const char iwl6005_2agn_mow1_name[] = "Intel(R) Centrino(R) Advanced-N 6206 AGN";
|
||||
const char iwl6005_2agn_mow2_name[] = "Intel(R) Centrino(R) Advanced-N 6207 AGN";
|
||||
|
||||
const struct iwl_rf_cfg iwl6005_non_n_cfg = {
|
||||
IWL_DEVICE_6005,
|
||||
};
|
||||
|
||||
const struct iwl_cfg iwl6005_2bg_cfg = {
|
||||
.name = "Intel(R) Centrino(R) Advanced-N 6205 BG",
|
||||
IWL_DEVICE_6005,
|
||||
};
|
||||
const char iwl6005_2abg_name[] = "Intel(R) Centrino(R) Advanced-N 6205 ABG";
|
||||
const char iwl6005_2bg_name[] = "Intel(R) Centrino(R) Advanced-N 6205 BG";
|
||||
|
||||
const struct iwl_cfg iwl6005_2agn_sff_cfg = {
|
||||
.name = "Intel(R) Centrino(R) Advanced-N 6205S AGN",
|
||||
IWL_DEVICE_6005,
|
||||
.ht_params = &iwl6000_ht_params,
|
||||
};
|
||||
|
||||
const struct iwl_cfg iwl6005_2agn_d_cfg = {
|
||||
.name = "Intel(R) Centrino(R) Advanced-N 6205D AGN",
|
||||
IWL_DEVICE_6005,
|
||||
.ht_params = &iwl6000_ht_params,
|
||||
};
|
||||
|
||||
const struct iwl_cfg iwl6005_2agn_mow1_cfg = {
|
||||
.name = "Intel(R) Centrino(R) Advanced-N 6206 AGN",
|
||||
IWL_DEVICE_6005,
|
||||
.ht_params = &iwl6000_ht_params,
|
||||
};
|
||||
|
||||
const struct iwl_cfg iwl6005_2agn_mow2_cfg = {
|
||||
.name = "Intel(R) Centrino(R) Advanced-N 6207 AGN",
|
||||
IWL_DEVICE_6005,
|
||||
.ht_params = &iwl6000_ht_params,
|
||||
const struct iwl_mac_cfg iwl6030_mac_cfg = {
|
||||
.device_family = IWL_DEVICE_FAMILY_6030,
|
||||
.base = &iwl6000_g2_base,
|
||||
};
|
||||
|
||||
#define IWL_DEVICE_6030 \
|
||||
.fw_name_pre = IWL6030_FW_PRE, \
|
||||
.ucode_api_max = IWL6000G2_UCODE_API_MAX, \
|
||||
.ucode_api_min = IWL6000G2_UCODE_API_MIN, \
|
||||
.trans.device_family = IWL_DEVICE_FAMILY_6030, \
|
||||
.max_inst_size = IWL60_RTC_INST_SIZE, \
|
||||
.max_data_size = IWL60_RTC_DATA_SIZE, \
|
||||
.nvm_ver = EEPROM_6030_EEPROM_VERSION, \
|
||||
.nvm_calib_ver = EEPROM_6030_TX_POWER_VERSION, \
|
||||
.trans.base_params = &iwl6000_g2_base_params, \
|
||||
.eeprom_params = &iwl6000_eeprom_params, \
|
||||
.led_mode = IWL_LED_RF_STATE
|
||||
|
||||
const struct iwl_cfg iwl6030_2agn_cfg = {
|
||||
.name = "Intel(R) Centrino(R) Advanced-N 6230 AGN",
|
||||
const struct iwl_rf_cfg iwl6030_n_cfg = {
|
||||
IWL_DEVICE_6030,
|
||||
.ht_params = &iwl6000_ht_params,
|
||||
.ht_params = {
|
||||
.ht_greenfield_support = true,
|
||||
.use_rts_for_aggregation = true, /* use rts/cts protection */
|
||||
.ht40_bands = BIT(NL80211_BAND_2GHZ) | BIT(NL80211_BAND_5GHZ),
|
||||
},
|
||||
};
|
||||
|
||||
const struct iwl_cfg iwl6030_2abg_cfg = {
|
||||
.name = "Intel(R) Centrino(R) Advanced-N 6230 ABG",
|
||||
const char iwl6030_2agn_name[] = "Intel(R) Centrino(R) Advanced-N 6230 AGN";
|
||||
const char iwl6030_2bgn_name[] = "Intel(R) Centrino(R) Advanced-N 6230 BGN";
|
||||
const char iwl1030_bgn_name[] = "Intel(R) Centrino(R) Wireless-N 1030 BGN";
|
||||
const char iwl1030_bg_name[] = "Intel(R) Centrino(R) Wireless-N 1030 BG";
|
||||
|
||||
const struct iwl_rf_cfg iwl6030_non_n_cfg = {
|
||||
IWL_DEVICE_6030,
|
||||
};
|
||||
|
||||
const struct iwl_cfg iwl6030_2bgn_cfg = {
|
||||
.name = "Intel(R) Centrino(R) Advanced-N 6230 BGN",
|
||||
IWL_DEVICE_6030,
|
||||
.ht_params = &iwl6000_ht_params,
|
||||
};
|
||||
|
||||
const struct iwl_cfg iwl6030_2bg_cfg = {
|
||||
.name = "Intel(R) Centrino(R) Advanced-N 6230 BG",
|
||||
IWL_DEVICE_6030,
|
||||
};
|
||||
const char iwl6030_2abg_name[] = "Intel(R) Centrino(R) Advanced-N 6230 ABG";
|
||||
const char iwl6030_2bg_name[] = "Intel(R) Centrino(R) Advanced-N 6230 BG";
|
||||
|
||||
#define IWL_DEVICE_6035 \
|
||||
.fw_name_pre = IWL6030_FW_PRE, \
|
||||
.ucode_api_max = IWL6035_UCODE_API_MAX, \
|
||||
.ucode_api_min = IWL6035_UCODE_API_MIN, \
|
||||
.trans.device_family = IWL_DEVICE_FAMILY_6030, \
|
||||
.max_inst_size = IWL60_RTC_INST_SIZE, \
|
||||
.max_data_size = IWL60_RTC_DATA_SIZE, \
|
||||
.nvm_ver = EEPROM_6030_EEPROM_VERSION, \
|
||||
.nvm_calib_ver = EEPROM_6030_TX_POWER_VERSION, \
|
||||
.trans.base_params = &iwl6000_g2_base_params, \
|
||||
.eeprom_params = &iwl6000_eeprom_params, \
|
||||
.led_mode = IWL_LED_RF_STATE
|
||||
|
||||
const struct iwl_cfg iwl6035_2agn_cfg = {
|
||||
.name = "Intel(R) Centrino(R) Advanced-N 6235 AGN",
|
||||
const struct iwl_rf_cfg iwl6035_2agn_cfg = {
|
||||
IWL_DEVICE_6035,
|
||||
.ht_params = &iwl6000_ht_params,
|
||||
.ht_params = {
|
||||
.ht_greenfield_support = true,
|
||||
.use_rts_for_aggregation = true, /* use rts/cts protection */
|
||||
.ht40_bands = BIT(NL80211_BAND_2GHZ) | BIT(NL80211_BAND_5GHZ),
|
||||
},
|
||||
};
|
||||
|
||||
const struct iwl_cfg iwl6035_2agn_sff_cfg = {
|
||||
.name = "Intel(R) Centrino(R) Ultimate-N 6235 AGN",
|
||||
IWL_DEVICE_6035,
|
||||
.ht_params = &iwl6000_ht_params,
|
||||
};
|
||||
const char iwl6035_2agn_name[] = "Intel(R) Centrino(R) Advanced-N 6235 AGN";
|
||||
const char iwl6035_2agn_sff_name[] = "Intel(R) Centrino(R) Ultimate-N 6235 AGN";
|
||||
|
||||
const struct iwl_cfg iwl1030_bgn_cfg = {
|
||||
.name = "Intel(R) Centrino(R) Wireless-N 1030 BGN",
|
||||
const struct iwl_rf_cfg iwl130_bgn_cfg = {
|
||||
IWL_DEVICE_6030,
|
||||
.ht_params = &iwl6000_ht_params,
|
||||
};
|
||||
|
||||
const struct iwl_cfg iwl1030_bg_cfg = {
|
||||
.name = "Intel(R) Centrino(R) Wireless-N 1030 BG",
|
||||
IWL_DEVICE_6030,
|
||||
};
|
||||
|
||||
const struct iwl_cfg iwl130_bgn_cfg = {
|
||||
.name = "Intel(R) Centrino(R) Wireless-N 130 BGN",
|
||||
IWL_DEVICE_6030,
|
||||
.ht_params = &iwl6000_ht_params,
|
||||
.ht_params = {
|
||||
.ht_greenfield_support = true,
|
||||
.use_rts_for_aggregation = true, /* use rts/cts protection */
|
||||
.ht40_bands = BIT(NL80211_BAND_2GHZ) | BIT(NL80211_BAND_5GHZ),
|
||||
},
|
||||
.rx_with_siso_diversity = true,
|
||||
};
|
||||
|
||||
const struct iwl_cfg iwl130_bg_cfg = {
|
||||
.name = "Intel(R) Centrino(R) Wireless-N 130 BG",
|
||||
const char iwl130_bgn_name[] = "Intel(R) Centrino(R) Wireless-N 130 BGN";
|
||||
|
||||
const struct iwl_rf_cfg iwl130_bg_cfg = {
|
||||
IWL_DEVICE_6030,
|
||||
.rx_with_siso_diversity = true,
|
||||
};
|
||||
|
||||
const char iwl130_bg_name[] = "Intel(R) Centrino(R) Wireless-N 130 BG";
|
||||
|
||||
const struct iwl_mac_cfg iwl6000i_mac_cfg = {
|
||||
.device_family = IWL_DEVICE_FAMILY_6000i,
|
||||
.base = &iwl6000_base,
|
||||
};
|
||||
|
||||
/*
|
||||
* "i": Internal configuration, use internal Power Amplifier
|
||||
*/
|
||||
@ -251,101 +230,127 @@ const struct iwl_cfg iwl130_bg_cfg = {
|
||||
.fw_name_pre = IWL6000_FW_PRE, \
|
||||
.ucode_api_max = IWL6000_UCODE_API_MAX, \
|
||||
.ucode_api_min = IWL6000_UCODE_API_MIN, \
|
||||
.trans.device_family = IWL_DEVICE_FAMILY_6000i, \
|
||||
.max_inst_size = IWL60_RTC_INST_SIZE, \
|
||||
.max_data_size = IWL60_RTC_DATA_SIZE, \
|
||||
.valid_tx_ant = ANT_BC, /* .cfg overwrite */ \
|
||||
.valid_rx_ant = ANT_BC, /* .cfg overwrite */ \
|
||||
.nvm_ver = EEPROM_6000_EEPROM_VERSION, \
|
||||
.nvm_calib_ver = EEPROM_6000_TX_POWER_VERSION, \
|
||||
.trans.base_params = &iwl6000_base_params, \
|
||||
.eeprom_params = &iwl6000_eeprom_params, \
|
||||
.led_mode = IWL_LED_BLINK
|
||||
|
||||
const struct iwl_cfg iwl6000i_2agn_cfg = {
|
||||
.name = "Intel(R) Centrino(R) Advanced-N 6200 AGN",
|
||||
const struct iwl_rf_cfg iwl6000i_2agn_cfg = {
|
||||
IWL_DEVICE_6000i,
|
||||
.ht_params = &iwl6000_ht_params,
|
||||
.ht_params = {
|
||||
.ht_greenfield_support = true,
|
||||
.use_rts_for_aggregation = true, /* use rts/cts protection */
|
||||
.ht40_bands = BIT(NL80211_BAND_2GHZ) | BIT(NL80211_BAND_5GHZ),
|
||||
},
|
||||
};
|
||||
|
||||
const struct iwl_cfg iwl6000i_2abg_cfg = {
|
||||
.name = "Intel(R) Centrino(R) Advanced-N 6200 ABG",
|
||||
const char iwl6000i_2agn_name[] = "Intel(R) Centrino(R) Advanced-N 6200 AGN";
|
||||
|
||||
const struct iwl_rf_cfg iwl6000i_non_n_cfg = {
|
||||
IWL_DEVICE_6000i,
|
||||
};
|
||||
|
||||
const struct iwl_cfg iwl6000i_2bg_cfg = {
|
||||
.name = "Intel(R) Centrino(R) Advanced-N 6200 BG",
|
||||
IWL_DEVICE_6000i,
|
||||
const char iwl6000i_2abg_name[] = "Intel(R) Centrino(R) Advanced-N 6200 ABG";
|
||||
const char iwl6000i_2bg_name[] = "Intel(R) Centrino(R) Advanced-N 6200 BG";
|
||||
|
||||
const struct iwl_mac_cfg iwl6050_mac_cfg = {
|
||||
.device_family = IWL_DEVICE_FAMILY_6050,
|
||||
.base = &iwl6050_base,
|
||||
};
|
||||
|
||||
#define IWL_DEVICE_6050 \
|
||||
.fw_name_pre = IWL6050_FW_PRE, \
|
||||
.ucode_api_max = IWL6050_UCODE_API_MAX, \
|
||||
.ucode_api_min = IWL6050_UCODE_API_MIN, \
|
||||
.trans.device_family = IWL_DEVICE_FAMILY_6050, \
|
||||
.max_inst_size = IWL60_RTC_INST_SIZE, \
|
||||
.max_data_size = IWL60_RTC_DATA_SIZE, \
|
||||
.valid_tx_ant = ANT_AB, /* .cfg overwrite */ \
|
||||
.valid_rx_ant = ANT_AB, /* .cfg overwrite */ \
|
||||
.nvm_ver = EEPROM_6050_EEPROM_VERSION, \
|
||||
.nvm_calib_ver = EEPROM_6050_TX_POWER_VERSION, \
|
||||
.trans.base_params = &iwl6050_base_params, \
|
||||
.eeprom_params = &iwl6000_eeprom_params, \
|
||||
.led_mode = IWL_LED_BLINK, \
|
||||
.internal_wimax_coex = true
|
||||
|
||||
const struct iwl_cfg iwl6050_2agn_cfg = {
|
||||
.name = "Intel(R) Centrino(R) Advanced-N + WiMAX 6250 AGN",
|
||||
const struct iwl_rf_cfg iwl6050_2agn_cfg = {
|
||||
IWL_DEVICE_6050,
|
||||
.ht_params = &iwl6000_ht_params,
|
||||
.ht_params = {
|
||||
.ht_greenfield_support = true,
|
||||
.use_rts_for_aggregation = true, /* use rts/cts protection */
|
||||
.ht40_bands = BIT(NL80211_BAND_2GHZ) | BIT(NL80211_BAND_5GHZ),
|
||||
},
|
||||
};
|
||||
|
||||
const struct iwl_cfg iwl6050_2abg_cfg = {
|
||||
.name = "Intel(R) Centrino(R) Advanced-N + WiMAX 6250 ABG",
|
||||
const char iwl6050_2agn_name[] = "Intel(R) Centrino(R) Advanced-N + WiMAX 6250 AGN";
|
||||
|
||||
const struct iwl_rf_cfg iwl6050_2abg_cfg = {
|
||||
IWL_DEVICE_6050,
|
||||
};
|
||||
|
||||
const char iwl6050_2abg_name[] = "Intel(R) Centrino(R) Advanced-N + WiMAX 6250 ABG";
|
||||
|
||||
const struct iwl_mac_cfg iwl6150_mac_cfg = {
|
||||
.device_family = IWL_DEVICE_FAMILY_6150,
|
||||
.base = &iwl6050_base,
|
||||
};
|
||||
|
||||
#define IWL_DEVICE_6150 \
|
||||
.fw_name_pre = IWL6050_FW_PRE, \
|
||||
.ucode_api_max = IWL6050_UCODE_API_MAX, \
|
||||
.ucode_api_min = IWL6050_UCODE_API_MIN, \
|
||||
.trans.device_family = IWL_DEVICE_FAMILY_6150, \
|
||||
.max_inst_size = IWL60_RTC_INST_SIZE, \
|
||||
.max_data_size = IWL60_RTC_DATA_SIZE, \
|
||||
.nvm_ver = EEPROM_6150_EEPROM_VERSION, \
|
||||
.nvm_calib_ver = EEPROM_6150_TX_POWER_VERSION, \
|
||||
.trans.base_params = &iwl6050_base_params, \
|
||||
.eeprom_params = &iwl6000_eeprom_params, \
|
||||
.led_mode = IWL_LED_BLINK, \
|
||||
.internal_wimax_coex = true
|
||||
|
||||
const struct iwl_cfg iwl6150_bgn_cfg = {
|
||||
.name = "Intel(R) Centrino(R) Wireless-N + WiMAX 6150 BGN",
|
||||
const struct iwl_rf_cfg iwl6150_bgn_cfg = {
|
||||
IWL_DEVICE_6150,
|
||||
.ht_params = &iwl6000_ht_params,
|
||||
.ht_params = {
|
||||
.ht_greenfield_support = true,
|
||||
.use_rts_for_aggregation = true, /* use rts/cts protection */
|
||||
.ht40_bands = BIT(NL80211_BAND_2GHZ) | BIT(NL80211_BAND_5GHZ),
|
||||
},
|
||||
};
|
||||
|
||||
const struct iwl_cfg iwl6150_bg_cfg = {
|
||||
.name = "Intel(R) Centrino(R) Wireless-N + WiMAX 6150 BG",
|
||||
const char iwl6150_bgn_name[] = "Intel(R) Centrino(R) Wireless-N + WiMAX 6150 BGN";
|
||||
|
||||
const struct iwl_rf_cfg iwl6150_bg_cfg = {
|
||||
IWL_DEVICE_6150,
|
||||
};
|
||||
|
||||
const struct iwl_cfg iwl6000_3agn_cfg = {
|
||||
.name = "Intel(R) Centrino(R) Ultimate-N 6300 AGN",
|
||||
const char iwl6150_bg_name[] = "Intel(R) Centrino(R) Wireless-N + WiMAX 6150 BG";
|
||||
|
||||
const struct iwl_mac_cfg iwl6000_mac_cfg = {
|
||||
.device_family = IWL_DEVICE_FAMILY_6000,
|
||||
.base = &iwl6000_base,
|
||||
};
|
||||
|
||||
const struct iwl_rf_cfg iwl6000_3agn_cfg = {
|
||||
.fw_name_pre = IWL6000_FW_PRE,
|
||||
.ucode_api_max = IWL6000_UCODE_API_MAX,
|
||||
.ucode_api_min = IWL6000_UCODE_API_MIN,
|
||||
.trans.device_family = IWL_DEVICE_FAMILY_6000,
|
||||
.max_inst_size = IWL60_RTC_INST_SIZE,
|
||||
.max_data_size = IWL60_RTC_DATA_SIZE,
|
||||
.nvm_ver = EEPROM_6000_EEPROM_VERSION,
|
||||
.nvm_calib_ver = EEPROM_6000_TX_POWER_VERSION,
|
||||
.trans.base_params = &iwl6000_base_params,
|
||||
.eeprom_params = &iwl6000_eeprom_params,
|
||||
.ht_params = &iwl6000_ht_params,
|
||||
.ht_params = {
|
||||
.ht_greenfield_support = true,
|
||||
.use_rts_for_aggregation = true, /* use rts/cts protection */
|
||||
.ht40_bands = BIT(NL80211_BAND_2GHZ) | BIT(NL80211_BAND_5GHZ),
|
||||
},
|
||||
.led_mode = IWL_LED_BLINK,
|
||||
};
|
||||
|
||||
const char iwl6000_3agn_name[] = "Intel(R) Centrino(R) Ultimate-N 6300 AGN";
|
||||
|
||||
MODULE_FIRMWARE(IWL6000_MODULE_FIRMWARE(IWL6000_UCODE_API_MAX));
|
||||
MODULE_FIRMWARE(IWL6050_MODULE_FIRMWARE(IWL6050_UCODE_API_MAX));
|
||||
MODULE_FIRMWARE(IWL6005_MODULE_FIRMWARE(IWL6000G2_UCODE_API_MAX));
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
// SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause
|
||||
/*
|
||||
* Copyright (C) 2012-2014, 2018-2020, 2023 Intel Corporation
|
||||
* Copyright (C) 2012-2014, 2018-2020, 2023, 2025 Intel Corporation
|
||||
* Copyright (C) 2013-2014 Intel Mobile Communications GmbH
|
||||
* Copyright (C) 2015 Intel Deutschland GmbH
|
||||
*/
|
||||
@ -49,7 +49,7 @@
|
||||
#define IWL7265D_FW_PRE "iwlwifi-7265D"
|
||||
#define IWL7265D_MODULE_FIRMWARE(api) IWL7265D_FW_PRE "-" __stringify(api) ".ucode"
|
||||
|
||||
static const struct iwl_base_params iwl7000_base_params = {
|
||||
static const struct iwl_family_base_params iwl7000_base = {
|
||||
.eeprom_size = OTP_LOW_IMAGE_SIZE_16K,
|
||||
.num_of_queues = 31,
|
||||
.max_tfd_queue_size = 256,
|
||||
@ -60,6 +60,7 @@ static const struct iwl_base_params iwl7000_base_params = {
|
||||
.shadow_reg_enable = true,
|
||||
.pcie_l1_allowed = true,
|
||||
.apmg_wake_up_wa = true,
|
||||
.nvm_hw_section_num = 0,
|
||||
};
|
||||
|
||||
static const struct iwl_tt_params iwl7000_high_temp_tt_params = {
|
||||
@ -84,16 +85,13 @@ static const struct iwl_tt_params iwl7000_high_temp_tt_params = {
|
||||
.support_tx_backoff = true,
|
||||
};
|
||||
|
||||
static const struct iwl_ht_params iwl7000_ht_params = {
|
||||
.stbc = true,
|
||||
.ht40_bands = BIT(NL80211_BAND_2GHZ) | BIT(NL80211_BAND_5GHZ),
|
||||
const struct iwl_mac_cfg iwl7000_mac_cfg = {
|
||||
.device_family = IWL_DEVICE_FAMILY_7000,
|
||||
.base = &iwl7000_base,
|
||||
};
|
||||
|
||||
#define IWL_DEVICE_7000_COMMON \
|
||||
.trans.device_family = IWL_DEVICE_FAMILY_7000, \
|
||||
.trans.base_params = &iwl7000_base_params, \
|
||||
.led_mode = IWL_LED_RF_STATE, \
|
||||
.nvm_hw_section_num = 0, \
|
||||
.non_shared_ant = ANT_A, \
|
||||
.dccm_offset = IWL7000_DCCM_OFFSET
|
||||
|
||||
@ -117,77 +115,52 @@ static const struct iwl_ht_params iwl7000_ht_params = {
|
||||
.ucode_api_max = IWL7265D_UCODE_API_MAX, \
|
||||
.ucode_api_min = IWL7265D_UCODE_API_MIN
|
||||
|
||||
const struct iwl_cfg iwl7260_2ac_cfg = {
|
||||
.name = "Intel(R) Dual Band Wireless AC 7260",
|
||||
const char iwl7260_2ac_name[] = "Intel(R) Dual Band Wireless AC 7260";
|
||||
const char iwl7260_2n_name[] = "Intel(R) Dual Band Wireless N 7260";
|
||||
const char iwl7260_n_name[] = "Intel(R) Wireless N 7260";
|
||||
const char iwl3160_2ac_name[] = "Intel(R) Dual Band Wireless AC 3160";
|
||||
const char iwl3160_2n_name[] = "Intel(R) Dual Band Wireless N 3160";
|
||||
const char iwl3160_n_name[] = "Intel(R) Wireless N 3160";
|
||||
const char iwl3165_2ac_name[] = "Intel(R) Dual Band Wireless-AC 3165";
|
||||
const char iwl3168_2ac_name[] = "Intel(R) Dual Band Wireless-AC 3168";
|
||||
const char iwl7265_2ac_name[] = "Intel(R) Dual Band Wireless-AC 7265";
|
||||
const char iwl7265_2n_name[] = "Intel(R) Dual Band Wireless-N 7265";
|
||||
const char iwl7265_n_name[] = "Intel(R) Wireless-N 7265";
|
||||
|
||||
const struct iwl_rf_cfg iwl7260_cfg = {
|
||||
.fw_name_pre = IWL7260_FW_PRE,
|
||||
IWL_DEVICE_7000,
|
||||
.ht_params = &iwl7000_ht_params,
|
||||
.ht_params = {
|
||||
.stbc = true,
|
||||
.ht40_bands = BIT(NL80211_BAND_2GHZ) | BIT(NL80211_BAND_5GHZ),
|
||||
},
|
||||
.nvm_ver = IWL7260_NVM_VERSION,
|
||||
.host_interrupt_operation_mode = true,
|
||||
.lp_xtal_workaround = true,
|
||||
.dccm_len = IWL7260_DCCM_LEN,
|
||||
};
|
||||
|
||||
const struct iwl_cfg iwl7260_2ac_cfg_high_temp = {
|
||||
.name = "Intel(R) Dual Band Wireless AC 7260",
|
||||
const struct iwl_rf_cfg iwl7260_high_temp_cfg = {
|
||||
.fw_name_pre = IWL7260_FW_PRE,
|
||||
IWL_DEVICE_7000,
|
||||
.ht_params = &iwl7000_ht_params,
|
||||
.ht_params = {
|
||||
.stbc = true,
|
||||
.ht40_bands = BIT(NL80211_BAND_2GHZ) | BIT(NL80211_BAND_5GHZ),
|
||||
},
|
||||
.nvm_ver = IWL7260_NVM_VERSION,
|
||||
.high_temp = true,
|
||||
.host_interrupt_operation_mode = true,
|
||||
.lp_xtal_workaround = true,
|
||||
.dccm_len = IWL7260_DCCM_LEN,
|
||||
.thermal_params = &iwl7000_high_temp_tt_params,
|
||||
};
|
||||
|
||||
const struct iwl_cfg iwl7260_2n_cfg = {
|
||||
.name = "Intel(R) Dual Band Wireless N 7260",
|
||||
.fw_name_pre = IWL7260_FW_PRE,
|
||||
IWL_DEVICE_7000,
|
||||
.ht_params = &iwl7000_ht_params,
|
||||
.nvm_ver = IWL7260_NVM_VERSION,
|
||||
.host_interrupt_operation_mode = true,
|
||||
.lp_xtal_workaround = true,
|
||||
.dccm_len = IWL7260_DCCM_LEN,
|
||||
};
|
||||
|
||||
const struct iwl_cfg iwl7260_n_cfg = {
|
||||
.name = "Intel(R) Wireless N 7260",
|
||||
.fw_name_pre = IWL7260_FW_PRE,
|
||||
IWL_DEVICE_7000,
|
||||
.ht_params = &iwl7000_ht_params,
|
||||
.nvm_ver = IWL7260_NVM_VERSION,
|
||||
.host_interrupt_operation_mode = true,
|
||||
.lp_xtal_workaround = true,
|
||||
.dccm_len = IWL7260_DCCM_LEN,
|
||||
};
|
||||
|
||||
const struct iwl_cfg iwl3160_2ac_cfg = {
|
||||
.name = "Intel(R) Dual Band Wireless AC 3160",
|
||||
const struct iwl_rf_cfg iwl3160_cfg = {
|
||||
.fw_name_pre = IWL3160_FW_PRE,
|
||||
IWL_DEVICE_7000,
|
||||
.ht_params = &iwl7000_ht_params,
|
||||
.nvm_ver = IWL3160_NVM_VERSION,
|
||||
.host_interrupt_operation_mode = true,
|
||||
.dccm_len = IWL3160_DCCM_LEN,
|
||||
};
|
||||
|
||||
const struct iwl_cfg iwl3160_2n_cfg = {
|
||||
.name = "Intel(R) Dual Band Wireless N 3160",
|
||||
.fw_name_pre = IWL3160_FW_PRE,
|
||||
IWL_DEVICE_7000,
|
||||
.ht_params = &iwl7000_ht_params,
|
||||
.nvm_ver = IWL3160_NVM_VERSION,
|
||||
.host_interrupt_operation_mode = true,
|
||||
.dccm_len = IWL3160_DCCM_LEN,
|
||||
};
|
||||
|
||||
const struct iwl_cfg iwl3160_n_cfg = {
|
||||
.name = "Intel(R) Wireless N 3160",
|
||||
.fw_name_pre = IWL3160_FW_PRE,
|
||||
IWL_DEVICE_7000,
|
||||
.ht_params = &iwl7000_ht_params,
|
||||
.ht_params = {
|
||||
.stbc = true,
|
||||
.ht40_bands = BIT(NL80211_BAND_2GHZ) | BIT(NL80211_BAND_5GHZ),
|
||||
},
|
||||
.nvm_ver = IWL3160_NVM_VERSION,
|
||||
.host_interrupt_operation_mode = true,
|
||||
.dccm_len = IWL3160_DCCM_LEN,
|
||||
@ -204,88 +177,52 @@ static const struct iwl_pwr_tx_backoff iwl7265_pwr_tx_backoffs[] = {
|
||||
{0},
|
||||
};
|
||||
|
||||
static const struct iwl_ht_params iwl7265_ht_params = {
|
||||
.stbc = true,
|
||||
.ldpc = true,
|
||||
.ht40_bands = BIT(NL80211_BAND_2GHZ) | BIT(NL80211_BAND_5GHZ),
|
||||
};
|
||||
|
||||
const struct iwl_cfg iwl3165_2ac_cfg = {
|
||||
.name = "Intel(R) Dual Band Wireless AC 3165",
|
||||
const struct iwl_rf_cfg iwl3165_2ac_cfg = {
|
||||
.fw_name_pre = IWL7265D_FW_PRE,
|
||||
IWL_DEVICE_7005D,
|
||||
.ht_params = &iwl7000_ht_params,
|
||||
.ht_params = {
|
||||
.stbc = true,
|
||||
.ht40_bands = BIT(NL80211_BAND_2GHZ) | BIT(NL80211_BAND_5GHZ),
|
||||
},
|
||||
.nvm_ver = IWL3165_NVM_VERSION,
|
||||
.pwr_tx_backoffs = iwl7265_pwr_tx_backoffs,
|
||||
.dccm_len = IWL7265_DCCM_LEN,
|
||||
};
|
||||
|
||||
const struct iwl_cfg iwl3168_2ac_cfg = {
|
||||
.name = "Intel(R) Dual Band Wireless AC 3168",
|
||||
const struct iwl_rf_cfg iwl3168_2ac_cfg = {
|
||||
.fw_name_pre = IWL3168_FW_PRE,
|
||||
IWL_DEVICE_3008,
|
||||
.ht_params = &iwl7000_ht_params,
|
||||
.ht_params = {
|
||||
.stbc = true,
|
||||
.ht40_bands = BIT(NL80211_BAND_2GHZ) | BIT(NL80211_BAND_5GHZ),
|
||||
},
|
||||
.nvm_ver = IWL3168_NVM_VERSION,
|
||||
.pwr_tx_backoffs = iwl7265_pwr_tx_backoffs,
|
||||
.dccm_len = IWL7265_DCCM_LEN,
|
||||
.nvm_type = IWL_NVM_SDP,
|
||||
};
|
||||
|
||||
const struct iwl_cfg iwl7265_2ac_cfg = {
|
||||
.name = "Intel(R) Dual Band Wireless AC 7265",
|
||||
const struct iwl_rf_cfg iwl7265_cfg = {
|
||||
.fw_name_pre = IWL7265_FW_PRE,
|
||||
IWL_DEVICE_7005,
|
||||
.ht_params = &iwl7265_ht_params,
|
||||
.ht_params = {
|
||||
.stbc = true,
|
||||
.ldpc = true,
|
||||
.ht40_bands = BIT(NL80211_BAND_2GHZ) | BIT(NL80211_BAND_5GHZ),
|
||||
},
|
||||
.nvm_ver = IWL7265_NVM_VERSION,
|
||||
.pwr_tx_backoffs = iwl7265_pwr_tx_backoffs,
|
||||
.dccm_len = IWL7265_DCCM_LEN,
|
||||
};
|
||||
|
||||
const struct iwl_cfg iwl7265_2n_cfg = {
|
||||
.name = "Intel(R) Dual Band Wireless N 7265",
|
||||
.fw_name_pre = IWL7265_FW_PRE,
|
||||
IWL_DEVICE_7005,
|
||||
.ht_params = &iwl7265_ht_params,
|
||||
.nvm_ver = IWL7265_NVM_VERSION,
|
||||
.pwr_tx_backoffs = iwl7265_pwr_tx_backoffs,
|
||||
.dccm_len = IWL7265_DCCM_LEN,
|
||||
};
|
||||
|
||||
const struct iwl_cfg iwl7265_n_cfg = {
|
||||
.name = "Intel(R) Wireless N 7265",
|
||||
.fw_name_pre = IWL7265_FW_PRE,
|
||||
IWL_DEVICE_7005,
|
||||
.ht_params = &iwl7265_ht_params,
|
||||
.nvm_ver = IWL7265_NVM_VERSION,
|
||||
.pwr_tx_backoffs = iwl7265_pwr_tx_backoffs,
|
||||
.dccm_len = IWL7265_DCCM_LEN,
|
||||
};
|
||||
|
||||
const struct iwl_cfg iwl7265d_2ac_cfg = {
|
||||
.name = "Intel(R) Dual Band Wireless AC 7265",
|
||||
const struct iwl_rf_cfg iwl7265d_cfg = {
|
||||
.fw_name_pre = IWL7265D_FW_PRE,
|
||||
IWL_DEVICE_7005D,
|
||||
.ht_params = &iwl7265_ht_params,
|
||||
.nvm_ver = IWL7265D_NVM_VERSION,
|
||||
.pwr_tx_backoffs = iwl7265_pwr_tx_backoffs,
|
||||
.dccm_len = IWL7265_DCCM_LEN,
|
||||
};
|
||||
|
||||
const struct iwl_cfg iwl7265d_2n_cfg = {
|
||||
.name = "Intel(R) Dual Band Wireless N 7265",
|
||||
.fw_name_pre = IWL7265D_FW_PRE,
|
||||
IWL_DEVICE_7005D,
|
||||
.ht_params = &iwl7265_ht_params,
|
||||
.nvm_ver = IWL7265D_NVM_VERSION,
|
||||
.pwr_tx_backoffs = iwl7265_pwr_tx_backoffs,
|
||||
.dccm_len = IWL7265_DCCM_LEN,
|
||||
};
|
||||
|
||||
const struct iwl_cfg iwl7265d_n_cfg = {
|
||||
.name = "Intel(R) Wireless N 7265",
|
||||
.fw_name_pre = IWL7265D_FW_PRE,
|
||||
IWL_DEVICE_7005D,
|
||||
.ht_params = &iwl7265_ht_params,
|
||||
.ht_params = {
|
||||
.stbc = true,
|
||||
.ldpc = true,
|
||||
.ht40_bands = BIT(NL80211_BAND_2GHZ) | BIT(NL80211_BAND_5GHZ),
|
||||
},
|
||||
.nvm_ver = IWL7265D_NVM_VERSION,
|
||||
.pwr_tx_backoffs = iwl7265_pwr_tx_backoffs,
|
||||
.dccm_len = IWL7265_DCCM_LEN,
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
// SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause
|
||||
/*
|
||||
* Copyright (C) 2014, 2018-2020, 2023 Intel Corporation
|
||||
* Copyright (C) 2014, 2018-2020, 2023, 2025 Intel Corporation
|
||||
* Copyright (C) 2014-2015 Intel Mobile Communications GmbH
|
||||
* Copyright (C) 2016 Intel Deutschland GmbH
|
||||
*/
|
||||
@ -35,9 +35,7 @@
|
||||
#define IWL8265_MODULE_FIRMWARE(api) \
|
||||
IWL8265_FW_PRE "-" __stringify(api) ".ucode"
|
||||
|
||||
#define DEFAULT_NVM_FILE_FAMILY_8000C "nvmData-8000C"
|
||||
|
||||
static const struct iwl_base_params iwl8000_base_params = {
|
||||
static const struct iwl_family_base_params iwl8000_base = {
|
||||
.eeprom_size = OTP_LOW_IMAGE_SIZE_32K,
|
||||
.num_of_queues = 31,
|
||||
.max_tfd_queue_size = 256,
|
||||
@ -47,12 +45,12 @@ static const struct iwl_base_params iwl8000_base_params = {
|
||||
.max_event_log_size = 512,
|
||||
.shadow_reg_enable = true,
|
||||
.pcie_l1_allowed = true,
|
||||
};
|
||||
|
||||
static const struct iwl_ht_params iwl8000_ht_params = {
|
||||
.stbc = true,
|
||||
.ldpc = true,
|
||||
.ht40_bands = BIT(NL80211_BAND_2GHZ) | BIT(NL80211_BAND_5GHZ),
|
||||
.nvm_hw_section_num = 10,
|
||||
.features = NETIF_F_RXCSUM,
|
||||
.smem_offset = IWL8260_SMEM_OFFSET,
|
||||
.smem_len = IWL8260_SMEM_LEN,
|
||||
.apmg_not_supported = true,
|
||||
.min_umac_error_event_table = 0x800000,
|
||||
};
|
||||
|
||||
static const struct iwl_tt_params iwl8000_tt_params = {
|
||||
@ -76,30 +74,20 @@ static const struct iwl_tt_params iwl8000_tt_params = {
|
||||
.support_tx_backoff = true,
|
||||
};
|
||||
|
||||
const struct iwl_mac_cfg iwl8000_mac_cfg = {
|
||||
.device_family = IWL_DEVICE_FAMILY_8000,
|
||||
.base = &iwl8000_base,
|
||||
};
|
||||
|
||||
#define IWL_DEVICE_8000_COMMON \
|
||||
.trans.device_family = IWL_DEVICE_FAMILY_8000, \
|
||||
.trans.base_params = &iwl8000_base_params, \
|
||||
.led_mode = IWL_LED_RF_STATE, \
|
||||
.nvm_hw_section_num = 10, \
|
||||
.features = NETIF_F_RXCSUM, \
|
||||
.non_shared_ant = ANT_A, \
|
||||
.dccm_offset = IWL8260_DCCM_OFFSET, \
|
||||
.dccm_len = IWL8260_DCCM_LEN, \
|
||||
.dccm2_offset = IWL8260_DCCM2_OFFSET, \
|
||||
.dccm2_len = IWL8260_DCCM2_LEN, \
|
||||
.smem_offset = IWL8260_SMEM_OFFSET, \
|
||||
.smem_len = IWL8260_SMEM_LEN, \
|
||||
.default_nvm_file_C_step = DEFAULT_NVM_FILE_FAMILY_8000C, \
|
||||
.thermal_params = &iwl8000_tt_params, \
|
||||
.apmg_not_supported = true, \
|
||||
.nvm_type = IWL_NVM_EXT, \
|
||||
.dbgc_supported = true, \
|
||||
.min_umac_error_event_table = 0x800000
|
||||
|
||||
#define IWL_DEVICE_8000 \
|
||||
IWL_DEVICE_8000_COMMON, \
|
||||
.ucode_api_max = IWL8000_UCODE_API_MAX, \
|
||||
.ucode_api_min = IWL8000_UCODE_API_MIN \
|
||||
.nvm_type = IWL_NVM_EXT
|
||||
|
||||
#define IWL_DEVICE_8260 \
|
||||
IWL_DEVICE_8000_COMMON, \
|
||||
@ -111,47 +99,39 @@ static const struct iwl_tt_params iwl8000_tt_params = {
|
||||
.ucode_api_max = IWL8265_UCODE_API_MAX, \
|
||||
.ucode_api_min = IWL8265_UCODE_API_MIN \
|
||||
|
||||
const struct iwl_cfg iwl8260_2n_cfg = {
|
||||
.name = "Intel(R) Dual Band Wireless N 8260",
|
||||
const char iwl8260_2n_name[] = "Intel(R) Dual Band Wireless-N 8260";
|
||||
const char iwl8260_2ac_name[] = "Intel(R) Dual Band Wireless-AC 8260";
|
||||
const char iwl8265_2ac_name[] = "Intel(R) Dual Band Wireless-AC 8265";
|
||||
const char iwl8275_2ac_name[] = "Intel(R) Dual Band Wireless-AC 8275";
|
||||
const char iwl4165_2ac_name[] = "Intel(R) Dual Band Wireless-AC 4165";
|
||||
|
||||
const char iwl_killer_1435i_name[] =
|
||||
"Killer(R) Wireless-AC 1435i Wireless Network Adapter (8265D2W)";
|
||||
const char iwl_killer_1434_kix_name[] =
|
||||
"Killer(R) Wireless-AC 1435-KIX Wireless Network Adapter (8265NGW)";
|
||||
|
||||
const struct iwl_rf_cfg iwl8260_cfg = {
|
||||
.fw_name_pre = IWL8000_FW_PRE,
|
||||
IWL_DEVICE_8260,
|
||||
.ht_params = &iwl8000_ht_params,
|
||||
.ht_params = {
|
||||
.stbc = true,
|
||||
.ldpc = true,
|
||||
.ht40_bands = BIT(NL80211_BAND_2GHZ) | BIT(NL80211_BAND_5GHZ),
|
||||
},
|
||||
.nvm_ver = IWL8000_NVM_VERSION,
|
||||
};
|
||||
|
||||
const struct iwl_cfg iwl8260_2ac_cfg = {
|
||||
.name = "Intel(R) Dual Band Wireless AC 8260",
|
||||
.fw_name_pre = IWL8000_FW_PRE,
|
||||
IWL_DEVICE_8260,
|
||||
.ht_params = &iwl8000_ht_params,
|
||||
.nvm_ver = IWL8000_NVM_VERSION,
|
||||
};
|
||||
|
||||
const struct iwl_cfg iwl8265_2ac_cfg = {
|
||||
.name = "Intel(R) Dual Band Wireless AC 8265",
|
||||
const struct iwl_rf_cfg iwl8265_cfg = {
|
||||
.fw_name_pre = IWL8265_FW_PRE,
|
||||
IWL_DEVICE_8265,
|
||||
.ht_params = &iwl8000_ht_params,
|
||||
.ht_params = {
|
||||
.stbc = true,
|
||||
.ldpc = true,
|
||||
.ht40_bands = BIT(NL80211_BAND_2GHZ) | BIT(NL80211_BAND_5GHZ),
|
||||
},
|
||||
.nvm_ver = IWL8000_NVM_VERSION,
|
||||
.vht_mu_mimo_supported = true,
|
||||
};
|
||||
|
||||
const struct iwl_cfg iwl8275_2ac_cfg = {
|
||||
.name = "Intel(R) Dual Band Wireless AC 8275",
|
||||
.fw_name_pre = IWL8265_FW_PRE,
|
||||
IWL_DEVICE_8265,
|
||||
.ht_params = &iwl8000_ht_params,
|
||||
.nvm_ver = IWL8000_NVM_VERSION,
|
||||
.vht_mu_mimo_supported = true,
|
||||
};
|
||||
|
||||
const struct iwl_cfg iwl4165_2ac_cfg = {
|
||||
.name = "Intel(R) Dual Band Wireless AC 4165",
|
||||
.fw_name_pre = IWL8000_FW_PRE,
|
||||
IWL_DEVICE_8000,
|
||||
.ht_params = &iwl8000_ht_params,
|
||||
.nvm_ver = IWL8000_NVM_VERSION,
|
||||
};
|
||||
|
||||
MODULE_FIRMWARE(IWL8000_MODULE_FIRMWARE(IWL8000_UCODE_API_MAX));
|
||||
MODULE_FIRMWARE(IWL8265_MODULE_FIRMWARE(IWL8265_UCODE_API_MAX));
|
||||
|
||||
@ -1,7 +1,7 @@
|
||||
// SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause
|
||||
/*
|
||||
* Copyright (C) 2015-2017 Intel Deutschland GmbH
|
||||
* Copyright (C) 2018-2021, 2023 Intel Corporation
|
||||
* Copyright (C) 2018-2021, 2023, 2025 Intel Corporation
|
||||
*/
|
||||
#include <linux/module.h>
|
||||
#include <linux/stringify.h>
|
||||
@ -15,14 +15,7 @@
|
||||
/* Lowest firmware API version supported */
|
||||
#define IWL9000_UCODE_API_MIN 30
|
||||
|
||||
/* NVM versions */
|
||||
#define IWL9000_NVM_VERSION 0x0a1d
|
||||
|
||||
/* Memory offsets and lengths */
|
||||
#define IWL9000_DCCM_OFFSET 0x800000
|
||||
#define IWL9000_DCCM_LEN 0x18000
|
||||
#define IWL9000_DCCM2_OFFSET 0x880000
|
||||
#define IWL9000_DCCM2_LEN 0x8000
|
||||
#define IWL9000_SMEM_OFFSET 0x400000
|
||||
#define IWL9000_SMEM_LEN 0x68000
|
||||
|
||||
@ -33,7 +26,7 @@
|
||||
#define IWL9260_MODULE_FIRMWARE(api) \
|
||||
IWL9260_FW_PRE "-" __stringify(api) ".ucode"
|
||||
|
||||
static const struct iwl_base_params iwl9000_base_params = {
|
||||
static const struct iwl_family_base_params iwl9000_base = {
|
||||
.eeprom_size = OTP_LOW_IMAGE_SIZE_32K,
|
||||
.num_of_queues = 31,
|
||||
.max_tfd_queue_size = 256,
|
||||
@ -43,150 +36,69 @@ static const struct iwl_base_params iwl9000_base_params = {
|
||||
.max_event_log_size = 512,
|
||||
.shadow_reg_enable = true,
|
||||
.pcie_l1_allowed = true,
|
||||
};
|
||||
|
||||
static const struct iwl_ht_params iwl9000_ht_params = {
|
||||
.stbc = true,
|
||||
.ldpc = true,
|
||||
.ht40_bands = BIT(NL80211_BAND_2GHZ) | BIT(NL80211_BAND_5GHZ),
|
||||
};
|
||||
|
||||
static const struct iwl_tt_params iwl9000_tt_params = {
|
||||
.ct_kill_entry = 115,
|
||||
.ct_kill_exit = 93,
|
||||
.ct_kill_duration = 5,
|
||||
.dynamic_smps_entry = 111,
|
||||
.dynamic_smps_exit = 107,
|
||||
.tx_protection_entry = 112,
|
||||
.tx_protection_exit = 105,
|
||||
.tx_backoff = {
|
||||
{.temperature = 110, .backoff = 200},
|
||||
{.temperature = 111, .backoff = 600},
|
||||
{.temperature = 112, .backoff = 1200},
|
||||
{.temperature = 113, .backoff = 2000},
|
||||
{.temperature = 114, .backoff = 4000},
|
||||
.smem_offset = IWL9000_SMEM_OFFSET,
|
||||
.smem_len = IWL9000_SMEM_LEN,
|
||||
.features = IWL_TX_CSUM_NETIF_FLAGS | NETIF_F_RXCSUM,
|
||||
.apmg_not_supported = true,
|
||||
.mac_addr_from_csr = 0x380,
|
||||
.min_umac_error_event_table = 0x800000,
|
||||
.d3_debug_data_base_addr = 0x401000,
|
||||
.d3_debug_data_length = 92 * 1024,
|
||||
.nvm_hw_section_num = 10,
|
||||
.mon_smem_regs = {
|
||||
.write_ptr = {
|
||||
.addr = LDBG_M2S_BUF_WPTR,
|
||||
.mask = LDBG_M2S_BUF_WPTR_VAL_MSK,
|
||||
},
|
||||
.cycle_cnt = {
|
||||
.addr = LDBG_M2S_BUF_WRAP_CNT,
|
||||
.mask = LDBG_M2S_BUF_WRAP_CNT_VAL_MSK,
|
||||
},
|
||||
},
|
||||
.support_ct_kill = true,
|
||||
.support_dynamic_smps = true,
|
||||
.support_tx_protection = true,
|
||||
.support_tx_backoff = true,
|
||||
.mon_dram_regs = {
|
||||
.write_ptr = {
|
||||
.addr = MON_BUFF_WRPTR_VER2,
|
||||
.mask = 0xffffffff,
|
||||
},
|
||||
.cycle_cnt = {
|
||||
.addr = MON_BUFF_CYCLE_CNT_VER2,
|
||||
.mask = 0xffffffff,
|
||||
},
|
||||
},
|
||||
.ucode_api_max = IWL9000_UCODE_API_MAX,
|
||||
.ucode_api_min = IWL9000_UCODE_API_MIN,
|
||||
};
|
||||
|
||||
#define IWL_DEVICE_9000 \
|
||||
.ucode_api_max = IWL9000_UCODE_API_MAX, \
|
||||
.ucode_api_min = IWL9000_UCODE_API_MIN, \
|
||||
.led_mode = IWL_LED_RF_STATE, \
|
||||
.nvm_hw_section_num = 10, \
|
||||
.non_shared_ant = ANT_B, \
|
||||
.dccm_offset = IWL9000_DCCM_OFFSET, \
|
||||
.dccm_len = IWL9000_DCCM_LEN, \
|
||||
.dccm2_offset = IWL9000_DCCM2_OFFSET, \
|
||||
.dccm2_len = IWL9000_DCCM2_LEN, \
|
||||
.smem_offset = IWL9000_SMEM_OFFSET, \
|
||||
.smem_len = IWL9000_SMEM_LEN, \
|
||||
.features = IWL_TX_CSUM_NETIF_FLAGS | NETIF_F_RXCSUM, \
|
||||
.thermal_params = &iwl9000_tt_params, \
|
||||
.apmg_not_supported = true, \
|
||||
.num_rbds = 512, \
|
||||
.vht_mu_mimo_supported = true, \
|
||||
.mac_addr_from_csr = 0x380, \
|
||||
.nvm_type = IWL_NVM_EXT, \
|
||||
.dbgc_supported = true, \
|
||||
.min_umac_error_event_table = 0x800000, \
|
||||
.d3_debug_data_base_addr = 0x401000, \
|
||||
.d3_debug_data_length = 92 * 1024, \
|
||||
.ht_params = &iwl9000_ht_params, \
|
||||
.nvm_ver = IWL9000_NVM_VERSION, \
|
||||
.mon_smem_regs = { \
|
||||
.write_ptr = { \
|
||||
.addr = LDBG_M2S_BUF_WPTR, \
|
||||
.mask = LDBG_M2S_BUF_WPTR_VAL_MSK, \
|
||||
}, \
|
||||
.cycle_cnt = { \
|
||||
.addr = LDBG_M2S_BUF_WRAP_CNT, \
|
||||
.mask = LDBG_M2S_BUF_WRAP_CNT_VAL_MSK, \
|
||||
}, \
|
||||
}, \
|
||||
.mon_dram_regs = { \
|
||||
.write_ptr = { \
|
||||
.addr = MON_BUFF_WRPTR_VER2, \
|
||||
.mask = 0xffffffff, \
|
||||
}, \
|
||||
.cycle_cnt = { \
|
||||
.addr = MON_BUFF_CYCLE_CNT_VER2, \
|
||||
.mask = 0xffffffff, \
|
||||
}, \
|
||||
}
|
||||
|
||||
const struct iwl_cfg_trans_params iwl9000_trans_cfg = {
|
||||
const struct iwl_mac_cfg iwl9000_mac_cfg = {
|
||||
.device_family = IWL_DEVICE_FAMILY_9000,
|
||||
.base_params = &iwl9000_base_params,
|
||||
.base = &iwl9000_base,
|
||||
.mq_rx_supported = true,
|
||||
.rf_id = true,
|
||||
};
|
||||
|
||||
const struct iwl_cfg_trans_params iwl9560_trans_cfg = {
|
||||
const struct iwl_mac_cfg iwl9560_mac_cfg = {
|
||||
.device_family = IWL_DEVICE_FAMILY_9000,
|
||||
.base_params = &iwl9000_base_params,
|
||||
.base = &iwl9000_base,
|
||||
.mq_rx_supported = true,
|
||||
.rf_id = true,
|
||||
.integrated = true,
|
||||
.xtal_latency = 650,
|
||||
};
|
||||
|
||||
const struct iwl_cfg_trans_params iwl9560_long_latency_trans_cfg = {
|
||||
const struct iwl_mac_cfg iwl9560_long_latency_mac_cfg = {
|
||||
.device_family = IWL_DEVICE_FAMILY_9000,
|
||||
.base_params = &iwl9000_base_params,
|
||||
.base = &iwl9000_base,
|
||||
.mq_rx_supported = true,
|
||||
.rf_id = true,
|
||||
.integrated = true,
|
||||
.xtal_latency = 2820,
|
||||
};
|
||||
|
||||
const struct iwl_cfg_trans_params iwl9560_shared_clk_trans_cfg = {
|
||||
const struct iwl_mac_cfg iwl9560_shared_clk_mac_cfg = {
|
||||
.device_family = IWL_DEVICE_FAMILY_9000,
|
||||
.base_params = &iwl9000_base_params,
|
||||
.base = &iwl9000_base,
|
||||
.mq_rx_supported = true,
|
||||
.rf_id = true,
|
||||
.integrated = true,
|
||||
.xtal_latency = 670,
|
||||
.extra_phy_cfg_flags = FW_PHY_CFG_SHARED_CLK
|
||||
};
|
||||
|
||||
const char iwl9162_name[] = "Intel(R) Wireless-AC 9162";
|
||||
const char iwl9260_name[] = "Intel(R) Wireless-AC 9260";
|
||||
const char iwl9260_1_name[] = "Intel(R) Wireless-AC 9260-1";
|
||||
const char iwl9270_name[] = "Intel(R) Wireless-AC 9270";
|
||||
const char iwl9461_name[] = "Intel(R) Wireless-AC 9461";
|
||||
const char iwl9462_name[] = "Intel(R) Wireless-AC 9462";
|
||||
const char iwl9560_name[] = "Intel(R) Wireless-AC 9560";
|
||||
const char iwl9162_160_name[] = "Intel(R) Wireless-AC 9162 160MHz";
|
||||
const char iwl9260_160_name[] = "Intel(R) Wireless-AC 9260 160MHz";
|
||||
const char iwl9270_160_name[] = "Intel(R) Wireless-AC 9270 160MHz";
|
||||
const char iwl9461_160_name[] = "Intel(R) Wireless-AC 9461 160MHz";
|
||||
const char iwl9462_160_name[] = "Intel(R) Wireless-AC 9462 160MHz";
|
||||
const char iwl9560_160_name[] = "Intel(R) Wireless-AC 9560 160MHz";
|
||||
|
||||
const char iwl9260_killer_1550_name[] =
|
||||
"Killer (R) Wireless-AC 1550 Wireless Network Adapter (9260NGW) 160MHz";
|
||||
const char iwl9560_killer_1550i_name[] =
|
||||
"Killer (R) Wireless-AC 1550i Wireless Network Adapter (9560NGW)";
|
||||
const char iwl9560_killer_1550i_160_name[] =
|
||||
"Killer(R) Wireless-AC 1550i Wireless Network Adapter (9560NGW) 160MHz";
|
||||
const char iwl9560_killer_1550s_name[] =
|
||||
"Killer (R) Wireless-AC 1550s Wireless Network Adapter (9560NGW)";
|
||||
const char iwl9560_killer_1550s_160_name[] =
|
||||
"Killer(R) Wireless-AC 1550s Wireless Network Adapter (9560D2W) 160MHz";
|
||||
|
||||
const struct iwl_cfg iwl9260_2ac_cfg = {
|
||||
.fw_name_pre = IWL9260_FW_PRE,
|
||||
IWL_DEVICE_9000,
|
||||
};
|
||||
|
||||
const struct iwl_cfg iwl9560_2ac_cfg_soc = {
|
||||
.fw_name_pre = IWL9000_FW_PRE,
|
||||
IWL_DEVICE_9000,
|
||||
};
|
||||
|
||||
MODULE_FIRMWARE(IWL9000_MODULE_FIRMWARE(IWL9000_UCODE_API_MAX));
|
||||
MODULE_FIRMWARE(IWL9260_MODULE_FIRMWARE(IWL9000_UCODE_API_MAX));
|
||||
|
||||
@ -1,7 +1,7 @@
|
||||
// SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause
|
||||
/*
|
||||
* Copyright (C) 2015-2017 Intel Deutschland GmbH
|
||||
* Copyright (C) 2018-2024 Intel Corporation
|
||||
* Copyright (C) 2018-2025 Intel Corporation
|
||||
*/
|
||||
#include <linux/module.h>
|
||||
#include <linux/stringify.h>
|
||||
@ -15,14 +15,7 @@
|
||||
/* Lowest firmware API version supported */
|
||||
#define IWL_AX210_UCODE_API_MIN 77
|
||||
|
||||
/* NVM versions */
|
||||
#define IWL_AX210_NVM_VERSION 0x0a1d
|
||||
|
||||
/* Memory offsets and lengths */
|
||||
#define IWL_AX210_DCCM_OFFSET 0x800000 /* LMAC1 */
|
||||
#define IWL_AX210_DCCM_LEN 0x10000 /* LMAC1 */
|
||||
#define IWL_AX210_DCCM2_OFFSET 0x880000
|
||||
#define IWL_AX210_DCCM2_LEN 0x8000
|
||||
#define IWL_AX210_SMEM_OFFSET 0x400000
|
||||
#define IWL_AX210_SMEM_LEN 0xD0000
|
||||
|
||||
@ -47,8 +40,7 @@
|
||||
#define IWL_MA_B_HR_B_FW_MODULE_FIRMWARE(api) \
|
||||
IWL_MA_B_HR_B_FW_PRE "-" __stringify(api) ".ucode"
|
||||
|
||||
static const struct iwl_base_params iwl_ax210_base_params = {
|
||||
.eeprom_size = OTP_LOW_IMAGE_SIZE_32K,
|
||||
static const struct iwl_family_base_params iwl_ax210_base = {
|
||||
.num_of_queues = 512,
|
||||
.max_tfd_queue_size = 65536,
|
||||
.shadow_ram_support = true,
|
||||
@ -57,74 +49,60 @@ static const struct iwl_base_params iwl_ax210_base_params = {
|
||||
.max_event_log_size = 512,
|
||||
.shadow_reg_enable = true,
|
||||
.pcie_l1_allowed = true,
|
||||
.smem_offset = IWL_AX210_SMEM_OFFSET,
|
||||
.smem_len = IWL_AX210_SMEM_LEN,
|
||||
.features = IWL_TX_CSUM_NETIF_FLAGS | NETIF_F_RXCSUM,
|
||||
.apmg_not_supported = true,
|
||||
.mac_addr_from_csr = 0x380,
|
||||
.min_umac_error_event_table = 0x400000,
|
||||
.d3_debug_data_base_addr = 0x401000,
|
||||
.d3_debug_data_length = 60 * 1024,
|
||||
.mon_smem_regs = {
|
||||
.write_ptr = {
|
||||
.addr = LDBG_M2S_BUF_WPTR,
|
||||
.mask = LDBG_M2S_BUF_WPTR_VAL_MSK,
|
||||
},
|
||||
.cycle_cnt = {
|
||||
.addr = LDBG_M2S_BUF_WRAP_CNT,
|
||||
.mask = LDBG_M2S_BUF_WRAP_CNT_VAL_MSK,
|
||||
},
|
||||
},
|
||||
.min_txq_size = 128,
|
||||
.gp2_reg_addr = 0xd02c68,
|
||||
.min_ba_txq_size = IWL_DEFAULT_QUEUE_SIZE_HE,
|
||||
.mon_dram_regs = {
|
||||
.write_ptr = {
|
||||
.addr = DBGC_CUR_DBGBUF_STATUS,
|
||||
.mask = DBGC_CUR_DBGBUF_STATUS_OFFSET_MSK,
|
||||
},
|
||||
.cycle_cnt = {
|
||||
.addr = DBGC_DBGBUF_WRAP_AROUND,
|
||||
.mask = 0xffffffff,
|
||||
},
|
||||
.cur_frag = {
|
||||
.addr = DBGC_CUR_DBGBUF_STATUS,
|
||||
.mask = DBGC_CUR_DBGBUF_STATUS_IDX_MSK,
|
||||
},
|
||||
},
|
||||
.ucode_api_min = IWL_AX210_UCODE_API_MIN,
|
||||
.ucode_api_max = IWL_AX210_UCODE_API_MAX,
|
||||
};
|
||||
|
||||
#define IWL_DEVICE_AX210_COMMON \
|
||||
.ucode_api_min = IWL_AX210_UCODE_API_MIN, \
|
||||
.led_mode = IWL_LED_RF_STATE, \
|
||||
.nvm_hw_section_num = 10, \
|
||||
.non_shared_ant = ANT_B, \
|
||||
.dccm_offset = IWL_AX210_DCCM_OFFSET, \
|
||||
.dccm_len = IWL_AX210_DCCM_LEN, \
|
||||
.dccm2_offset = IWL_AX210_DCCM2_OFFSET, \
|
||||
.dccm2_len = IWL_AX210_DCCM2_LEN, \
|
||||
.smem_offset = IWL_AX210_SMEM_OFFSET, \
|
||||
.smem_len = IWL_AX210_SMEM_LEN, \
|
||||
.features = IWL_TX_CSUM_NETIF_FLAGS | NETIF_F_RXCSUM, \
|
||||
.apmg_not_supported = true, \
|
||||
.trans.mq_rx_supported = true, \
|
||||
.vht_mu_mimo_supported = true, \
|
||||
.mac_addr_from_csr = 0x380, \
|
||||
.ht_params = &iwl_22000_ht_params, \
|
||||
.nvm_ver = IWL_AX210_NVM_VERSION, \
|
||||
.trans.rf_id = true, \
|
||||
.trans.gen2 = true, \
|
||||
.nvm_type = IWL_NVM_EXT, \
|
||||
.dbgc_supported = true, \
|
||||
.min_umac_error_event_table = 0x400000, \
|
||||
.d3_debug_data_base_addr = 0x401000, \
|
||||
.d3_debug_data_length = 60 * 1024, \
|
||||
.mon_smem_regs = { \
|
||||
.write_ptr = { \
|
||||
.addr = LDBG_M2S_BUF_WPTR, \
|
||||
.mask = LDBG_M2S_BUF_WPTR_VAL_MSK, \
|
||||
}, \
|
||||
.cycle_cnt = { \
|
||||
.addr = LDBG_M2S_BUF_WRAP_CNT, \
|
||||
.mask = LDBG_M2S_BUF_WRAP_CNT_VAL_MSK, \
|
||||
}, \
|
||||
}
|
||||
|
||||
#define IWL_DEVICE_AX210 \
|
||||
IWL_DEVICE_AX210_COMMON, \
|
||||
.ucode_api_max = IWL_AX210_UCODE_API_MAX, \
|
||||
.trans.umac_prph_offset = 0x300000, \
|
||||
.trans.device_family = IWL_DEVICE_FAMILY_AX210, \
|
||||
.trans.base_params = &iwl_ax210_base_params, \
|
||||
.min_txq_size = 128, \
|
||||
.gp2_reg_addr = 0xd02c68, \
|
||||
.min_ba_txq_size = IWL_DEFAULT_QUEUE_SIZE_HE, \
|
||||
.mon_dram_regs = { \
|
||||
.write_ptr = { \
|
||||
.addr = DBGC_CUR_DBGBUF_STATUS, \
|
||||
.mask = DBGC_CUR_DBGBUF_STATUS_OFFSET_MSK, \
|
||||
}, \
|
||||
.cycle_cnt = { \
|
||||
.addr = DBGC_DBGBUF_WRAP_AROUND, \
|
||||
.mask = 0xffffffff, \
|
||||
}, \
|
||||
.cur_frag = { \
|
||||
.addr = DBGC_CUR_DBGBUF_STATUS, \
|
||||
.mask = DBGC_CUR_DBGBUF_STATUS_IDX_MSK, \
|
||||
}, \
|
||||
}
|
||||
|
||||
const struct iwl_cfg_trans_params iwl_so_trans_cfg = {
|
||||
const struct iwl_mac_cfg iwl_ty_mac_cfg = {
|
||||
.mq_rx_supported = true,
|
||||
.rf_id = true,
|
||||
.gen2 = true,
|
||||
.device_family = IWL_DEVICE_FAMILY_AX210,
|
||||
.base_params = &iwl_ax210_base_params,
|
||||
.base = &iwl_ax210_base,
|
||||
.umac_prph_offset = 0x300000,
|
||||
/* TODO: the following values need to be checked */
|
||||
.xtal_latency = 500,
|
||||
};
|
||||
|
||||
const struct iwl_mac_cfg iwl_so_mac_cfg = {
|
||||
.mq_rx_supported = true,
|
||||
.gen2 = true,
|
||||
.device_family = IWL_DEVICE_FAMILY_AX210,
|
||||
.base = &iwl_ax210_base,
|
||||
.umac_prph_offset = 0x300000,
|
||||
.integrated = true,
|
||||
/* TODO: the following values need to be checked */
|
||||
@ -132,12 +110,11 @@ const struct iwl_cfg_trans_params iwl_so_trans_cfg = {
|
||||
.ltr_delay = IWL_CFG_TRANS_LTR_DELAY_200US,
|
||||
};
|
||||
|
||||
const struct iwl_cfg_trans_params iwl_so_long_latency_trans_cfg = {
|
||||
const struct iwl_mac_cfg iwl_so_long_latency_mac_cfg = {
|
||||
.mq_rx_supported = true,
|
||||
.rf_id = true,
|
||||
.gen2 = true,
|
||||
.device_family = IWL_DEVICE_FAMILY_AX210,
|
||||
.base_params = &iwl_ax210_base_params,
|
||||
.base = &iwl_ax210_base,
|
||||
.umac_prph_offset = 0x300000,
|
||||
.integrated = true,
|
||||
.low_latency_xtal = true,
|
||||
@ -145,12 +122,11 @@ const struct iwl_cfg_trans_params iwl_so_long_latency_trans_cfg = {
|
||||
.ltr_delay = IWL_CFG_TRANS_LTR_DELAY_2500US,
|
||||
};
|
||||
|
||||
const struct iwl_cfg_trans_params iwl_so_long_latency_imr_trans_cfg = {
|
||||
const struct iwl_mac_cfg iwl_so_long_latency_imr_mac_cfg = {
|
||||
.mq_rx_supported = true,
|
||||
.rf_id = true,
|
||||
.gen2 = true,
|
||||
.device_family = IWL_DEVICE_FAMILY_AX210,
|
||||
.base_params = &iwl_ax210_base_params,
|
||||
.base = &iwl_ax210_base,
|
||||
.umac_prph_offset = 0x300000,
|
||||
.integrated = true,
|
||||
.low_latency_xtal = true,
|
||||
@ -159,107 +135,15 @@ const struct iwl_cfg_trans_params iwl_so_long_latency_imr_trans_cfg = {
|
||||
.imr_enabled = true,
|
||||
};
|
||||
|
||||
/*
|
||||
* If the device doesn't support HE, no need to have that many buffers.
|
||||
* AX210 devices can split multiple frames into a single RB, so fewer are
|
||||
* needed; AX210 cannot (but use smaller RBs by default) - these sizes
|
||||
* were picked according to 8 MSDUs inside 256 A-MSDUs in an A-MPDU, with
|
||||
* additional overhead to account for processing time.
|
||||
*/
|
||||
#define IWL_NUM_RBDS_NON_HE 512
|
||||
#define IWL_NUM_RBDS_AX210_HE 4096
|
||||
|
||||
const struct iwl_cfg_trans_params iwl_ma_trans_cfg = {
|
||||
const struct iwl_mac_cfg iwl_ma_mac_cfg = {
|
||||
.device_family = IWL_DEVICE_FAMILY_AX210,
|
||||
.base_params = &iwl_ax210_base_params,
|
||||
.base = &iwl_ax210_base,
|
||||
.mq_rx_supported = true,
|
||||
.rf_id = true,
|
||||
.gen2 = true,
|
||||
.integrated = true,
|
||||
.umac_prph_offset = 0x300000
|
||||
};
|
||||
|
||||
const char iwl_ax211_name[] = "Intel(R) Wi-Fi 6E AX211 160MHz";
|
||||
const char iwl_ax231_name[] = "Intel(R) Wi-Fi 6E AX231 160MHz";
|
||||
const char iwl_ax411_name[] = "Intel(R) Wi-Fi 6E AX411 160MHz";
|
||||
|
||||
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 iwlax210_2ax_cfg_so_jf_b0 = {
|
||||
.name = "Intel(R) Wireless-AC 9560 160MHz",
|
||||
.fw_name_pre = IWL_SO_A_JF_B_FW_PRE,
|
||||
IWL_DEVICE_AX210,
|
||||
.num_rbds = IWL_NUM_RBDS_NON_HE,
|
||||
};
|
||||
|
||||
const struct iwl_cfg iwlax211_2ax_cfg_so_gf_a0 = {
|
||||
.name = iwl_ax211_name,
|
||||
.fw_name_pre = IWL_SO_A_GF_A_FW_PRE,
|
||||
.uhb_supported = true,
|
||||
IWL_DEVICE_AX210,
|
||||
.num_rbds = IWL_NUM_RBDS_AX210_HE,
|
||||
};
|
||||
|
||||
const struct iwl_cfg iwlax211_2ax_cfg_so_gf_a0_long = {
|
||||
.name = iwl_ax211_name,
|
||||
.fw_name_pre = IWL_SO_A_GF_A_FW_PRE,
|
||||
.uhb_supported = true,
|
||||
IWL_DEVICE_AX210,
|
||||
.num_rbds = IWL_NUM_RBDS_AX210_HE,
|
||||
.trans.xtal_latency = 12000,
|
||||
.trans.low_latency_xtal = true,
|
||||
};
|
||||
|
||||
const struct iwl_cfg iwlax210_2ax_cfg_ty_gf_a0 = {
|
||||
.name = "Intel(R) Wi-Fi 6 AX210 160MHz",
|
||||
.fw_name_pre = IWL_TY_A_GF_A_FW_PRE,
|
||||
.uhb_supported = true,
|
||||
IWL_DEVICE_AX210,
|
||||
.num_rbds = IWL_NUM_RBDS_AX210_HE,
|
||||
};
|
||||
|
||||
const struct iwl_cfg iwlax411_2ax_cfg_so_gf4_a0 = {
|
||||
.name = iwl_ax411_name,
|
||||
.fw_name_pre = IWL_SO_A_GF4_A_FW_PRE,
|
||||
.uhb_supported = true,
|
||||
IWL_DEVICE_AX210,
|
||||
.num_rbds = IWL_NUM_RBDS_AX210_HE,
|
||||
};
|
||||
|
||||
const struct iwl_cfg iwlax411_2ax_cfg_so_gf4_a0_long = {
|
||||
.name = iwl_ax411_name,
|
||||
.fw_name_pre = IWL_SO_A_GF4_A_FW_PRE,
|
||||
.uhb_supported = true,
|
||||
IWL_DEVICE_AX210,
|
||||
.num_rbds = IWL_NUM_RBDS_AX210_HE,
|
||||
.trans.xtal_latency = 12000,
|
||||
.trans.low_latency_xtal = true,
|
||||
};
|
||||
|
||||
const struct iwl_cfg iwl_cfg_ma = {
|
||||
.fw_name_mac = "ma",
|
||||
.uhb_supported = true,
|
||||
IWL_DEVICE_AX210,
|
||||
.num_rbds = IWL_NUM_RBDS_AX210_HE,
|
||||
};
|
||||
|
||||
const struct iwl_cfg iwl_cfg_so_a0_hr_a0 = {
|
||||
.fw_name_pre = IWL_SO_A_HR_B_FW_PRE,
|
||||
IWL_DEVICE_AX210,
|
||||
.num_rbds = IWL_NUM_RBDS_AX210_HE,
|
||||
};
|
||||
|
||||
MODULE_FIRMWARE(IWL_SO_A_JF_B_MODULE_FIRMWARE(IWL_AX210_UCODE_API_MAX));
|
||||
MODULE_FIRMWARE(IWL_SO_A_HR_B_MODULE_FIRMWARE(IWL_AX210_UCODE_API_MAX));
|
||||
IWL_FW_AND_PNVM(IWL_SO_A_GF_A_FW_PRE, IWL_AX210_UCODE_API_MAX);
|
||||
|
||||
@ -10,19 +10,12 @@
|
||||
#include "fw/api/txq.h"
|
||||
|
||||
/* Highest firmware API version supported */
|
||||
#define IWL_BZ_UCODE_API_MAX 98
|
||||
#define IWL_BZ_UCODE_API_MAX 99
|
||||
|
||||
/* Lowest firmware API version supported */
|
||||
#define IWL_BZ_UCODE_API_MIN 93
|
||||
|
||||
/* NVM versions */
|
||||
#define IWL_BZ_NVM_VERSION 0x0a1d
|
||||
|
||||
/* Memory offsets and lengths */
|
||||
#define IWL_BZ_DCCM_OFFSET 0x800000 /* LMAC1 */
|
||||
#define IWL_BZ_DCCM_LEN 0x10000 /* LMAC1 */
|
||||
#define IWL_BZ_DCCM2_OFFSET 0x880000
|
||||
#define IWL_BZ_DCCM2_LEN 0x8000
|
||||
#define IWL_BZ_SMEM_OFFSET 0x400000
|
||||
#define IWL_BZ_SMEM_LEN 0xD0000
|
||||
|
||||
@ -38,13 +31,7 @@
|
||||
#define IWL_BZ_A_HR_B_MODULE_FIRMWARE(api) \
|
||||
IWL_BZ_A_HR_B_FW_PRE "-" __stringify(api) ".ucode"
|
||||
|
||||
#if !IS_ENABLED(CONFIG_IWLMVM)
|
||||
const char iwl_ax211_name[] = "Intel(R) Wi-Fi 6E AX211 160MHz";
|
||||
const char iwl_ax201_name[] = "Intel(R) Wi-Fi 6 AX201 160MHz";
|
||||
#endif
|
||||
|
||||
static const struct iwl_base_params iwl_bz_base_params = {
|
||||
.eeprom_size = OTP_LOW_IMAGE_SIZE_32K,
|
||||
static const struct iwl_family_base_params iwl_bz_base = {
|
||||
.num_of_queues = 512,
|
||||
.max_tfd_queue_size = 65536,
|
||||
.shadow_ram_support = true,
|
||||
@ -53,91 +40,55 @@ static const struct iwl_base_params iwl_bz_base_params = {
|
||||
.max_event_log_size = 512,
|
||||
.shadow_reg_enable = true,
|
||||
.pcie_l1_allowed = true,
|
||||
.smem_offset = IWL_BZ_SMEM_OFFSET,
|
||||
.smem_len = IWL_BZ_SMEM_LEN,
|
||||
.apmg_not_supported = true,
|
||||
.mac_addr_from_csr = 0x30,
|
||||
.min_umac_error_event_table = 0xD0000,
|
||||
.d3_debug_data_base_addr = 0x401000,
|
||||
.d3_debug_data_length = 60 * 1024,
|
||||
.mon_smem_regs = {
|
||||
.write_ptr = {
|
||||
.addr = LDBG_M2S_BUF_WPTR,
|
||||
.mask = LDBG_M2S_BUF_WPTR_VAL_MSK,
|
||||
},
|
||||
.cycle_cnt = {
|
||||
.addr = LDBG_M2S_BUF_WRAP_CNT,
|
||||
.mask = LDBG_M2S_BUF_WRAP_CNT_VAL_MSK,
|
||||
},
|
||||
},
|
||||
.min_txq_size = 128,
|
||||
.gp2_reg_addr = 0xd02c68,
|
||||
.min_ba_txq_size = IWL_DEFAULT_QUEUE_SIZE_EHT,
|
||||
.mon_dram_regs = {
|
||||
.write_ptr = {
|
||||
.addr = DBGC_CUR_DBGBUF_STATUS,
|
||||
.mask = DBGC_CUR_DBGBUF_STATUS_OFFSET_MSK,
|
||||
},
|
||||
.cycle_cnt = {
|
||||
.addr = DBGC_DBGBUF_WRAP_AROUND,
|
||||
.mask = 0xffffffff,
|
||||
},
|
||||
.cur_frag = {
|
||||
.addr = DBGC_CUR_DBGBUF_STATUS,
|
||||
.mask = DBGC_CUR_DBGBUF_STATUS_IDX_MSK,
|
||||
},
|
||||
},
|
||||
.mon_dbgi_regs = {
|
||||
.write_ptr = {
|
||||
.addr = DBGI_SRAM_FIFO_POINTERS,
|
||||
.mask = DBGI_SRAM_FIFO_POINTERS_WR_PTR_MSK,
|
||||
},
|
||||
},
|
||||
.features = IWL_TX_CSUM_NETIF_FLAGS | NETIF_F_RXCSUM,
|
||||
.ucode_api_max = IWL_BZ_UCODE_API_MAX,
|
||||
.ucode_api_min = IWL_BZ_UCODE_API_MIN,
|
||||
};
|
||||
|
||||
const struct iwl_ht_params iwl_bz_ht_params = {
|
||||
.stbc = true,
|
||||
.ldpc = true,
|
||||
.ht40_bands = BIT(NL80211_BAND_2GHZ) | BIT(NL80211_BAND_5GHZ) |
|
||||
BIT(NL80211_BAND_6GHZ),
|
||||
};
|
||||
|
||||
#define IWL_DEVICE_BZ_COMMON \
|
||||
.ucode_api_max = IWL_BZ_UCODE_API_MAX, \
|
||||
.ucode_api_min = IWL_BZ_UCODE_API_MIN, \
|
||||
.led_mode = IWL_LED_RF_STATE, \
|
||||
.nvm_hw_section_num = 10, \
|
||||
.non_shared_ant = ANT_B, \
|
||||
.dccm_offset = IWL_BZ_DCCM_OFFSET, \
|
||||
.dccm_len = IWL_BZ_DCCM_LEN, \
|
||||
.dccm2_offset = IWL_BZ_DCCM2_OFFSET, \
|
||||
.dccm2_len = IWL_BZ_DCCM2_LEN, \
|
||||
.smem_offset = IWL_BZ_SMEM_OFFSET, \
|
||||
.smem_len = IWL_BZ_SMEM_LEN, \
|
||||
.apmg_not_supported = true, \
|
||||
.trans.mq_rx_supported = true, \
|
||||
.vht_mu_mimo_supported = true, \
|
||||
.mac_addr_from_csr = 0x30, \
|
||||
.nvm_ver = IWL_BZ_NVM_VERSION, \
|
||||
.trans.rf_id = true, \
|
||||
.trans.gen2 = true, \
|
||||
.nvm_type = IWL_NVM_EXT, \
|
||||
.dbgc_supported = true, \
|
||||
.min_umac_error_event_table = 0xD0000, \
|
||||
.d3_debug_data_base_addr = 0x401000, \
|
||||
.d3_debug_data_length = 60 * 1024, \
|
||||
.mon_smem_regs = { \
|
||||
.write_ptr = { \
|
||||
.addr = LDBG_M2S_BUF_WPTR, \
|
||||
.mask = LDBG_M2S_BUF_WPTR_VAL_MSK, \
|
||||
}, \
|
||||
.cycle_cnt = { \
|
||||
.addr = LDBG_M2S_BUF_WRAP_CNT, \
|
||||
.mask = LDBG_M2S_BUF_WRAP_CNT_VAL_MSK, \
|
||||
}, \
|
||||
}, \
|
||||
.trans.umac_prph_offset = 0x300000, \
|
||||
.trans.device_family = IWL_DEVICE_FAMILY_BZ, \
|
||||
.trans.base_params = &iwl_bz_base_params, \
|
||||
.min_txq_size = 128, \
|
||||
.gp2_reg_addr = 0xd02c68, \
|
||||
.min_ba_txq_size = IWL_DEFAULT_QUEUE_SIZE_EHT, \
|
||||
.mon_dram_regs = { \
|
||||
.write_ptr = { \
|
||||
.addr = DBGC_CUR_DBGBUF_STATUS, \
|
||||
.mask = DBGC_CUR_DBGBUF_STATUS_OFFSET_MSK, \
|
||||
}, \
|
||||
.cycle_cnt = { \
|
||||
.addr = DBGC_DBGBUF_WRAP_AROUND, \
|
||||
.mask = 0xffffffff, \
|
||||
}, \
|
||||
.cur_frag = { \
|
||||
.addr = DBGC_CUR_DBGBUF_STATUS, \
|
||||
.mask = DBGC_CUR_DBGBUF_STATUS_IDX_MSK, \
|
||||
}, \
|
||||
}, \
|
||||
.mon_dbgi_regs = { \
|
||||
.write_ptr = { \
|
||||
.addr = DBGI_SRAM_FIFO_POINTERS, \
|
||||
.mask = DBGI_SRAM_FIFO_POINTERS_WR_PTR_MSK, \
|
||||
}, \
|
||||
}
|
||||
|
||||
#define IWL_DEVICE_BZ \
|
||||
IWL_DEVICE_BZ_COMMON, \
|
||||
.ht_params = &iwl_bz_ht_params
|
||||
|
||||
/*
|
||||
* This size was picked according to 8 MSDUs inside 512 A-MSDUs in an
|
||||
* A-MPDU, with additional overhead to account for processing time.
|
||||
*/
|
||||
#define IWL_NUM_RBDS_BZ_EHT (512 * 16)
|
||||
|
||||
const struct iwl_cfg_trans_params iwl_bz_trans_cfg = {
|
||||
const struct iwl_mac_cfg iwl_bz_mac_cfg = {
|
||||
.device_family = IWL_DEVICE_FAMILY_BZ,
|
||||
.base_params = &iwl_bz_base_params,
|
||||
.base = &iwl_bz_base,
|
||||
.mq_rx_supported = true,
|
||||
.rf_id = true,
|
||||
.gen2 = true,
|
||||
.integrated = true,
|
||||
.umac_prph_offset = 0x300000,
|
||||
@ -146,38 +97,16 @@ const struct iwl_cfg_trans_params iwl_bz_trans_cfg = {
|
||||
.ltr_delay = IWL_CFG_TRANS_LTR_DELAY_2500US,
|
||||
};
|
||||
|
||||
const struct iwl_cfg_trans_params iwl_gl_trans_cfg = {
|
||||
const struct iwl_mac_cfg iwl_gl_mac_cfg = {
|
||||
.device_family = IWL_DEVICE_FAMILY_BZ,
|
||||
.base_params = &iwl_bz_base_params,
|
||||
.base = &iwl_bz_base,
|
||||
.mq_rx_supported = true,
|
||||
.rf_id = true,
|
||||
.gen2 = true,
|
||||
.umac_prph_offset = 0x300000,
|
||||
.xtal_latency = 12000,
|
||||
.low_latency_xtal = true,
|
||||
};
|
||||
|
||||
const char iwl_fm_name[] = "Intel(R) Wi-Fi 7 BE201 320MHz";
|
||||
const char iwl_wh_name[] = "Intel(R) Wi-Fi 7 BE211 320MHz";
|
||||
const char iwl_gl_name[] = "Intel(R) Wi-Fi 7 BE200 320MHz";
|
||||
const char iwl_mtp_name[] = "Intel(R) Wi-Fi 7 BE202 160MHz";
|
||||
|
||||
const struct iwl_cfg iwl_cfg_bz = {
|
||||
.fw_name_mac = "bz",
|
||||
.uhb_supported = true,
|
||||
IWL_DEVICE_BZ,
|
||||
.features = IWL_TX_CSUM_NETIF_FLAGS | NETIF_F_RXCSUM,
|
||||
.num_rbds = IWL_NUM_RBDS_BZ_EHT,
|
||||
};
|
||||
|
||||
const struct iwl_cfg iwl_cfg_gl = {
|
||||
.fw_name_mac = "gl",
|
||||
.uhb_supported = true,
|
||||
IWL_DEVICE_BZ,
|
||||
.features = IWL_TX_CSUM_NETIF_FLAGS | NETIF_F_RXCSUM,
|
||||
.num_rbds = IWL_NUM_RBDS_BZ_EHT,
|
||||
};
|
||||
|
||||
MODULE_FIRMWARE(IWL_BZ_A_HR_B_MODULE_FIRMWARE(IWL_BZ_UCODE_API_MAX));
|
||||
IWL_FW_AND_PNVM(IWL_BZ_A_GF_A_FW_PRE, IWL_BZ_UCODE_API_MAX);
|
||||
IWL_FW_AND_PNVM(IWL_BZ_A_GF4_A_FW_PRE, IWL_BZ_UCODE_API_MAX);
|
||||
|
||||
@ -9,35 +9,21 @@
|
||||
#include "fw/api/txq.h"
|
||||
|
||||
/* Highest firmware API version supported */
|
||||
#define IWL_DR_UCODE_API_MAX 98
|
||||
#define IWL_DR_UCODE_API_MAX 99
|
||||
|
||||
/* Lowest firmware API version supported */
|
||||
#define IWL_DR_UCODE_API_MIN 96
|
||||
|
||||
/* NVM versions */
|
||||
#define IWL_DR_NVM_VERSION 0x0a1d
|
||||
#define IWL_DR_UCODE_API_MIN 97
|
||||
|
||||
/* Memory offsets and lengths */
|
||||
#define IWL_DR_DCCM_OFFSET 0x800000 /* LMAC1 */
|
||||
#define IWL_DR_DCCM_LEN 0x10000 /* LMAC1 */
|
||||
#define IWL_DR_DCCM2_OFFSET 0x880000
|
||||
#define IWL_DR_DCCM2_LEN 0x8000
|
||||
#define IWL_DR_SMEM_OFFSET 0x400000
|
||||
#define IWL_DR_SMEM_LEN 0xD0000
|
||||
|
||||
#define IWL_DR_A_PE_A_FW_PRE "iwlwifi-dr-a0-pe-a0"
|
||||
#define IWL_BR_A_PET_A_FW_PRE "iwlwifi-br-a0-petc-a0"
|
||||
#define IWL_BR_A_PE_A_FW_PRE "iwlwifi-br-a0-pe-a0"
|
||||
|
||||
#define IWL_DR_A_PE_A_FW_MODULE_FIRMWARE(api) \
|
||||
IWL_DR_A_PE_A_FW_PRE "-" __stringify(api) ".ucode"
|
||||
#define IWL_BR_A_PET_A_FW_MODULE_FIRMWARE(api) \
|
||||
IWL_BR_A_PET_A_FW_PRE "-" __stringify(api) ".ucode"
|
||||
#define IWL_BR_A_PE_A_FW_MODULE_FIRMWARE(api) \
|
||||
IWL_BR_A_PE_A_FW_PRE "-" __stringify(api) ".ucode"
|
||||
|
||||
static const struct iwl_base_params iwl_dr_base_params = {
|
||||
.eeprom_size = OTP_LOW_IMAGE_SIZE_32K,
|
||||
static const struct iwl_family_base_params iwl_dr_base = {
|
||||
.num_of_queues = 512,
|
||||
.max_tfd_queue_size = 65536,
|
||||
.shadow_ram_support = true,
|
||||
@ -46,87 +32,55 @@ static const struct iwl_base_params iwl_dr_base_params = {
|
||||
.max_event_log_size = 512,
|
||||
.shadow_reg_enable = true,
|
||||
.pcie_l1_allowed = true,
|
||||
.smem_offset = IWL_DR_SMEM_OFFSET,
|
||||
.smem_len = IWL_DR_SMEM_LEN,
|
||||
.apmg_not_supported = true,
|
||||
.mac_addr_from_csr = 0x30,
|
||||
.min_umac_error_event_table = 0xD0000,
|
||||
.d3_debug_data_base_addr = 0x401000,
|
||||
.d3_debug_data_length = 60 * 1024,
|
||||
.mon_smem_regs = {
|
||||
.write_ptr = {
|
||||
.addr = LDBG_M2S_BUF_WPTR,
|
||||
.mask = LDBG_M2S_BUF_WPTR_VAL_MSK,
|
||||
},
|
||||
.cycle_cnt = {
|
||||
.addr = LDBG_M2S_BUF_WRAP_CNT,
|
||||
.mask = LDBG_M2S_BUF_WRAP_CNT_VAL_MSK,
|
||||
},
|
||||
},
|
||||
.min_txq_size = 128,
|
||||
.gp2_reg_addr = 0xd02c68,
|
||||
.min_ba_txq_size = IWL_DEFAULT_QUEUE_SIZE_EHT,
|
||||
.mon_dram_regs = {
|
||||
.write_ptr = {
|
||||
.addr = DBGC_CUR_DBGBUF_STATUS,
|
||||
.mask = DBGC_CUR_DBGBUF_STATUS_OFFSET_MSK,
|
||||
},
|
||||
.cycle_cnt = {
|
||||
.addr = DBGC_DBGBUF_WRAP_AROUND,
|
||||
.mask = 0xffffffff,
|
||||
},
|
||||
.cur_frag = {
|
||||
.addr = DBGC_CUR_DBGBUF_STATUS,
|
||||
.mask = DBGC_CUR_DBGBUF_STATUS_IDX_MSK,
|
||||
},
|
||||
},
|
||||
.mon_dbgi_regs = {
|
||||
.write_ptr = {
|
||||
.addr = DBGI_SRAM_FIFO_POINTERS,
|
||||
.mask = DBGI_SRAM_FIFO_POINTERS_WR_PTR_MSK,
|
||||
},
|
||||
},
|
||||
.features = IWL_TX_CSUM_NETIF_FLAGS | NETIF_F_RXCSUM,
|
||||
.ucode_api_max = IWL_DR_UCODE_API_MAX,
|
||||
.ucode_api_min = IWL_DR_UCODE_API_MIN,
|
||||
};
|
||||
|
||||
#define IWL_DEVICE_DR_COMMON \
|
||||
.ucode_api_max = IWL_DR_UCODE_API_MAX, \
|
||||
.ucode_api_min = IWL_DR_UCODE_API_MIN, \
|
||||
.led_mode = IWL_LED_RF_STATE, \
|
||||
.nvm_hw_section_num = 10, \
|
||||
.non_shared_ant = ANT_B, \
|
||||
.dccm_offset = IWL_DR_DCCM_OFFSET, \
|
||||
.dccm_len = IWL_DR_DCCM_LEN, \
|
||||
.dccm2_offset = IWL_DR_DCCM2_OFFSET, \
|
||||
.dccm2_len = IWL_DR_DCCM2_LEN, \
|
||||
.smem_offset = IWL_DR_SMEM_OFFSET, \
|
||||
.smem_len = IWL_DR_SMEM_LEN, \
|
||||
.apmg_not_supported = true, \
|
||||
.trans.mq_rx_supported = true, \
|
||||
.vht_mu_mimo_supported = true, \
|
||||
.mac_addr_from_csr = 0x30, \
|
||||
.nvm_ver = IWL_DR_NVM_VERSION, \
|
||||
.trans.rf_id = true, \
|
||||
.trans.gen2 = true, \
|
||||
.nvm_type = IWL_NVM_EXT, \
|
||||
.dbgc_supported = true, \
|
||||
.min_umac_error_event_table = 0xD0000, \
|
||||
.d3_debug_data_base_addr = 0x401000, \
|
||||
.d3_debug_data_length = 60 * 1024, \
|
||||
.mon_smem_regs = { \
|
||||
.write_ptr = { \
|
||||
.addr = LDBG_M2S_BUF_WPTR, \
|
||||
.mask = LDBG_M2S_BUF_WPTR_VAL_MSK, \
|
||||
}, \
|
||||
.cycle_cnt = { \
|
||||
.addr = LDBG_M2S_BUF_WRAP_CNT, \
|
||||
.mask = LDBG_M2S_BUF_WRAP_CNT_VAL_MSK, \
|
||||
}, \
|
||||
}, \
|
||||
.trans.umac_prph_offset = 0x300000, \
|
||||
.trans.device_family = IWL_DEVICE_FAMILY_DR, \
|
||||
.trans.base_params = &iwl_dr_base_params, \
|
||||
.min_txq_size = 128, \
|
||||
.gp2_reg_addr = 0xd02c68, \
|
||||
.min_ba_txq_size = IWL_DEFAULT_QUEUE_SIZE_EHT, \
|
||||
.mon_dram_regs = { \
|
||||
.write_ptr = { \
|
||||
.addr = DBGC_CUR_DBGBUF_STATUS, \
|
||||
.mask = DBGC_CUR_DBGBUF_STATUS_OFFSET_MSK, \
|
||||
}, \
|
||||
.cycle_cnt = { \
|
||||
.addr = DBGC_DBGBUF_WRAP_AROUND, \
|
||||
.mask = 0xffffffff, \
|
||||
}, \
|
||||
.cur_frag = { \
|
||||
.addr = DBGC_CUR_DBGBUF_STATUS, \
|
||||
.mask = DBGC_CUR_DBGBUF_STATUS_IDX_MSK, \
|
||||
}, \
|
||||
}, \
|
||||
.mon_dbgi_regs = { \
|
||||
.write_ptr = { \
|
||||
.addr = DBGI_SRAM_FIFO_POINTERS, \
|
||||
.mask = DBGI_SRAM_FIFO_POINTERS_WR_PTR_MSK, \
|
||||
}, \
|
||||
}
|
||||
|
||||
#define IWL_DEVICE_DR \
|
||||
IWL_DEVICE_DR_COMMON, \
|
||||
.uhb_supported = true, \
|
||||
.features = IWL_TX_CSUM_NETIF_FLAGS | NETIF_F_RXCSUM, \
|
||||
.num_rbds = IWL_NUM_RBDS_DR_EHT, \
|
||||
.ht_params = &iwl_bz_ht_params
|
||||
|
||||
/*
|
||||
* This size was picked according to 8 MSDUs inside 512 A-MSDUs in an
|
||||
* A-MPDU, with additional overhead to account for processing time.
|
||||
*/
|
||||
#define IWL_NUM_RBDS_DR_EHT (512 * 16)
|
||||
|
||||
const struct iwl_cfg_trans_params iwl_dr_trans_cfg = {
|
||||
const struct iwl_mac_cfg iwl_dr_mac_cfg = {
|
||||
.device_family = IWL_DEVICE_FAMILY_DR,
|
||||
.base_params = &iwl_dr_base_params,
|
||||
.base = &iwl_dr_base,
|
||||
.mq_rx_supported = true,
|
||||
.rf_id = true,
|
||||
.gen2 = true,
|
||||
.integrated = true,
|
||||
.umac_prph_offset = 0x300000,
|
||||
@ -135,31 +89,5 @@ const struct iwl_cfg_trans_params iwl_dr_trans_cfg = {
|
||||
.ltr_delay = IWL_CFG_TRANS_LTR_DELAY_2500US,
|
||||
};
|
||||
|
||||
const char iwl_dr_name[] = "Intel(R) TBD Dr device";
|
||||
|
||||
const struct iwl_cfg iwl_cfg_dr = {
|
||||
.fw_name_mac = "dr",
|
||||
IWL_DEVICE_DR,
|
||||
};
|
||||
|
||||
const struct iwl_cfg_trans_params iwl_br_trans_cfg = {
|
||||
.device_family = IWL_DEVICE_FAMILY_DR,
|
||||
.base_params = &iwl_dr_base_params,
|
||||
.mq_rx_supported = true,
|
||||
.rf_id = true,
|
||||
.gen2 = true,
|
||||
.umac_prph_offset = 0x300000,
|
||||
.xtal_latency = 12000,
|
||||
.low_latency_xtal = true,
|
||||
};
|
||||
|
||||
const char iwl_br_name[] = "Intel(R) TBD Br device";
|
||||
|
||||
const struct iwl_cfg iwl_cfg_br = {
|
||||
.fw_name_mac = "br",
|
||||
IWL_DEVICE_DR,
|
||||
};
|
||||
|
||||
MODULE_FIRMWARE(IWL_DR_A_PE_A_FW_MODULE_FIRMWARE(IWL_DR_UCODE_API_MAX));
|
||||
MODULE_FIRMWARE(IWL_BR_A_PET_A_FW_MODULE_FIRMWARE(IWL_DR_UCODE_API_MAX));
|
||||
MODULE_FIRMWARE(IWL_BR_A_PE_A_FW_MODULE_FIRMWARE(IWL_DR_UCODE_API_MAX));
|
||||
|
||||
|
||||
51
drivers/net/wireless/intel/iwlwifi/cfg/rf-fm.c
Normal file
51
drivers/net/wireless/intel/iwlwifi/cfg/rf-fm.c
Normal file
@ -0,0 +1,51 @@
|
||||
// SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause
|
||||
/*
|
||||
* Copyright (C) 2015-2017 Intel Deutschland GmbH
|
||||
* Copyright (C) 2018-2025 Intel Corporation
|
||||
*/
|
||||
#include "iwl-config.h"
|
||||
|
||||
/* NVM versions */
|
||||
#define IWL_FM_NVM_VERSION 0x0a1d
|
||||
|
||||
#define IWL_DEVICE_FM \
|
||||
.ht_params = { \
|
||||
.stbc = true, \
|
||||
.ldpc = true, \
|
||||
.ht40_bands = BIT(NL80211_BAND_2GHZ) | \
|
||||
BIT(NL80211_BAND_5GHZ), \
|
||||
}, \
|
||||
.led_mode = IWL_LED_RF_STATE, \
|
||||
.non_shared_ant = ANT_B, \
|
||||
.vht_mu_mimo_supported = true, \
|
||||
.uhb_supported = true, \
|
||||
.num_rbds = IWL_NUM_RBDS_EHT, \
|
||||
.nvm_ver = IWL_FM_NVM_VERSION, \
|
||||
.nvm_type = IWL_NVM_EXT
|
||||
|
||||
const struct iwl_rf_cfg iwl_rf_fm = {
|
||||
IWL_DEVICE_FM,
|
||||
};
|
||||
|
||||
const struct iwl_rf_cfg iwl_rf_fm_160mhz = {
|
||||
IWL_DEVICE_FM,
|
||||
.bw_limit = 160,
|
||||
};
|
||||
|
||||
const char iwl_killer_be1750s_name[] =
|
||||
"Killer(R) Wi-Fi 7 BE1750s 320MHz Wireless Network Adapter (BE201D2W)";
|
||||
const char iwl_killer_be1750i_name[] =
|
||||
"Killer(R) Wi-Fi 7 BE1750i 320MHz Wireless Network Adapter (BE201NGW)";
|
||||
const char iwl_killer_be1750w_name[] =
|
||||
"Killer(TM) Wi-Fi 7 BE1750w 320MHz Wireless Network Adapter (BE200D2W)";
|
||||
const char iwl_killer_be1750x_name[] =
|
||||
"Killer(TM) Wi-Fi 7 BE1750x 320MHz Wireless Network Adapter (BE200NGW)";
|
||||
const char iwl_killer_be1790s_name[] =
|
||||
"Killer(R) Wi-Fi 7 BE1790s 320MHz Wireless Network Adapter (BE401D2W)";
|
||||
const char iwl_killer_be1790i_name[] =
|
||||
"Killer(R) Wi-Fi 7 BE1790i 320MHz Wireless Network Adapter (BE401NGW)";
|
||||
|
||||
const char iwl_be201_name[] = "Intel(R) Wi-Fi 7 BE201 320MHz";
|
||||
const char iwl_be200_name[] = "Intel(R) Wi-Fi 7 BE200 320MHz";
|
||||
const char iwl_be202_name[] = "Intel(R) Wi-Fi 7 BE202 160MHz";
|
||||
const char iwl_be401_name[] = "Intel(R) Wi-Fi 7 BE401 320MHz";
|
||||
42
drivers/net/wireless/intel/iwlwifi/cfg/rf-gf.c
Normal file
42
drivers/net/wireless/intel/iwlwifi/cfg/rf-gf.c
Normal file
@ -0,0 +1,42 @@
|
||||
// SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause
|
||||
/*
|
||||
* Copyright (C) 2015-2017 Intel Deutschland GmbH
|
||||
* Copyright (C) 2018-2025 Intel Corporation
|
||||
*/
|
||||
#include "iwl-config.h"
|
||||
|
||||
/* NVM versions */
|
||||
#define IWL_GF_NVM_VERSION 0x0a1d
|
||||
|
||||
const struct iwl_rf_cfg iwl_rf_gf = {
|
||||
.uhb_supported = true,
|
||||
.led_mode = IWL_LED_RF_STATE,
|
||||
.non_shared_ant = ANT_B,
|
||||
.vht_mu_mimo_supported = true,
|
||||
.ht_params = {
|
||||
.stbc = true,
|
||||
.ldpc = true,
|
||||
.ht40_bands = BIT(NL80211_BAND_2GHZ) |
|
||||
BIT(NL80211_BAND_5GHZ),
|
||||
},
|
||||
.nvm_ver = IWL_GF_NVM_VERSION,
|
||||
.nvm_type = IWL_NVM_EXT,
|
||||
.num_rbds = IWL_NUM_RBDS_HE,
|
||||
};
|
||||
|
||||
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 (211D2W)";
|
||||
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 char iwl_ax210_name[] = "Intel(R) Wi-Fi 6E AX210 160MHz";
|
||||
const char iwl_ax211_name[] = "Intel(R) Wi-Fi 6E AX211 160MHz";
|
||||
const char iwl_ax411_name[] = "Intel(R) Wi-Fi 6E AX411 160MHz";
|
||||
42
drivers/net/wireless/intel/iwlwifi/cfg/rf-hr.c
Normal file
42
drivers/net/wireless/intel/iwlwifi/cfg/rf-hr.c
Normal file
@ -0,0 +1,42 @@
|
||||
// SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause
|
||||
/*
|
||||
* Copyright (C) 2015-2017 Intel Deutschland GmbH
|
||||
* Copyright (C) 2018-2025 Intel Corporation
|
||||
*/
|
||||
#include "iwl-config.h"
|
||||
|
||||
/* NVM versions */
|
||||
#define IWL_HR_NVM_VERSION 0x0a1d
|
||||
|
||||
#define IWL_DEVICE_HR \
|
||||
.led_mode = IWL_LED_RF_STATE, \
|
||||
.non_shared_ant = ANT_B, \
|
||||
.vht_mu_mimo_supported = true, \
|
||||
.ht_params = { \
|
||||
.stbc = true, \
|
||||
.ldpc = true, \
|
||||
.ht40_bands = BIT(NL80211_BAND_2GHZ) | \
|
||||
BIT(NL80211_BAND_5GHZ), \
|
||||
}, \
|
||||
.num_rbds = IWL_NUM_RBDS_HE, \
|
||||
.nvm_ver = IWL_HR_NVM_VERSION, \
|
||||
.nvm_type = IWL_NVM_EXT
|
||||
|
||||
const struct iwl_rf_cfg iwl_rf_hr1 = {
|
||||
IWL_DEVICE_HR,
|
||||
.tx_with_siso_diversity = true,
|
||||
};
|
||||
|
||||
const struct iwl_rf_cfg iwl_rf_hr = {
|
||||
IWL_DEVICE_HR,
|
||||
};
|
||||
|
||||
const struct iwl_rf_cfg iwl_rf_hr_80mhz = {
|
||||
IWL_DEVICE_HR,
|
||||
.bw_limit = 80,
|
||||
};
|
||||
|
||||
const char iwl_ax101_name[] = "Intel(R) Wi-Fi 6 AX101";
|
||||
const char iwl_ax200_name[] = "Intel(R) Wi-Fi 6 AX200 160MHz";
|
||||
const char iwl_ax201_name[] = "Intel(R) Wi-Fi 6 AX201 160MHz";
|
||||
const char iwl_ax203_name[] = "Intel(R) Wi-Fi 6 AX203";
|
||||
84
drivers/net/wireless/intel/iwlwifi/cfg/rf-jf.c
Normal file
84
drivers/net/wireless/intel/iwlwifi/cfg/rf-jf.c
Normal file
@ -0,0 +1,84 @@
|
||||
// SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause
|
||||
/*
|
||||
* Copyright (C) 2015-2017 Intel Deutschland GmbH
|
||||
* Copyright (C) 2018-2021, 2023, 2025 Intel Corporation
|
||||
*/
|
||||
#include "iwl-config.h"
|
||||
|
||||
/* NVM versions */
|
||||
#define IWL_JF_NVM_VERSION 0x0a1d
|
||||
|
||||
/* Memory offsets and lengths */
|
||||
#define IWL9000_DCCM_OFFSET 0x800000
|
||||
#define IWL9000_DCCM_LEN 0x18000
|
||||
#define IWL9000_DCCM2_OFFSET 0x880000
|
||||
#define IWL9000_DCCM2_LEN 0x8000
|
||||
|
||||
static const struct iwl_tt_params iwl_jf_tt_params = {
|
||||
.ct_kill_entry = 115,
|
||||
.ct_kill_exit = 93,
|
||||
.ct_kill_duration = 5,
|
||||
.dynamic_smps_entry = 111,
|
||||
.dynamic_smps_exit = 107,
|
||||
.tx_protection_entry = 112,
|
||||
.tx_protection_exit = 105,
|
||||
.tx_backoff = {
|
||||
{.temperature = 110, .backoff = 200},
|
||||
{.temperature = 111, .backoff = 600},
|
||||
{.temperature = 112, .backoff = 1200},
|
||||
{.temperature = 113, .backoff = 2000},
|
||||
{.temperature = 114, .backoff = 4000},
|
||||
},
|
||||
.support_ct_kill = true,
|
||||
.support_dynamic_smps = true,
|
||||
.support_tx_protection = true,
|
||||
.support_tx_backoff = true,
|
||||
};
|
||||
|
||||
/* these values are ignored if not with Pu/Th MAC firmware, due to offload */
|
||||
#define IWL_DEVICE_JF_PU \
|
||||
.dccm_offset = IWL9000_DCCM_OFFSET, \
|
||||
.dccm_len = IWL9000_DCCM_LEN, \
|
||||
.dccm2_offset = IWL9000_DCCM2_OFFSET, \
|
||||
.dccm2_len = IWL9000_DCCM2_LEN, \
|
||||
.thermal_params = &iwl_jf_tt_params
|
||||
|
||||
#define IWL_DEVICE_JF \
|
||||
IWL_DEVICE_JF_PU, \
|
||||
.led_mode = IWL_LED_RF_STATE, \
|
||||
.non_shared_ant = ANT_B, \
|
||||
.num_rbds = IWL_NUM_RBDS_NON_HE, \
|
||||
.vht_mu_mimo_supported = true, \
|
||||
.ht_params = { \
|
||||
.stbc = true, \
|
||||
.ldpc = true, \
|
||||
.ht40_bands = BIT(NL80211_BAND_2GHZ) | \
|
||||
BIT(NL80211_BAND_5GHZ), \
|
||||
}, \
|
||||
.nvm_ver = IWL_JF_NVM_VERSION, \
|
||||
.nvm_type = IWL_NVM_EXT
|
||||
|
||||
const struct iwl_rf_cfg iwl_rf_jf = {
|
||||
IWL_DEVICE_JF,
|
||||
};
|
||||
|
||||
const struct iwl_rf_cfg iwl_rf_jf_80mhz = {
|
||||
IWL_DEVICE_JF,
|
||||
.bw_limit = 80,
|
||||
};
|
||||
|
||||
const char iwl9260_name[] = "Intel(R) Wireless-AC 9260";
|
||||
const char iwl9461_name[] = "Intel(R) Wireless-AC 9461";
|
||||
const char iwl9462_name[] = "Intel(R) Wireless-AC 9462";
|
||||
const char iwl9560_name[] = "Intel(R) Wireless-AC 9560";
|
||||
const char iwl9260_160_name[] = "Intel(R) Wireless-AC 9260 160MHz";
|
||||
const char iwl9461_160_name[] = "Intel(R) Wireless-AC 9461 160MHz";
|
||||
const char iwl9462_160_name[] = "Intel(R) Wireless-AC 9462 160MHz";
|
||||
const char iwl9560_160_name[] = "Intel(R) Wireless-AC 9560 160MHz";
|
||||
|
||||
const char iwl9260_killer_1550_name[] =
|
||||
"Killer(R) Wireless-AC 1550 Wireless Network Adapter (9260NGW) 160MHz";
|
||||
const char iwl9560_killer_1550i_name[] =
|
||||
"Killer(R) Wireless-AC 1550i Wireless Network Adapter (9560NGW) 160MHz";
|
||||
const char iwl9560_killer_1550s_name[] =
|
||||
"Killer(R) Wireless-AC 1550s Wireless Network Adapter (9560D2W) 160MHz";
|
||||
16
drivers/net/wireless/intel/iwlwifi/cfg/rf-pe.c
Normal file
16
drivers/net/wireless/intel/iwlwifi/cfg/rf-pe.c
Normal file
@ -0,0 +1,16 @@
|
||||
// SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause
|
||||
/*
|
||||
* Copyright (C) 2025 Intel Corporation
|
||||
*/
|
||||
#include "iwl-config.h"
|
||||
|
||||
/* currently iwl_rf_wh/iwl_rf_wh_160mhz are just defines for the FM ones */
|
||||
|
||||
const char iwl_killer_bn1850w2_name[] =
|
||||
"Killer(R) Wi-Fi 8 BN1850w2 320MHz Wireless Network Adapter (BN201.D2W)";
|
||||
const char iwl_killer_bn1850i_name[] =
|
||||
"Killer(R) Wi-Fi 8 BN1850i 320MHz Wireless Network Adapter (BN201.NGW)";
|
||||
|
||||
const char iwl_bn201_name[] = "Intel(R) Wi-Fi 8 BN201";
|
||||
const char iwl_be221_name[] = "Intel(R) Wi-Fi 7 BE221";
|
||||
const char iwl_be223_name[] = "Intel(R) Wi-Fi 7 BE223";
|
||||
15
drivers/net/wireless/intel/iwlwifi/cfg/rf-wh.c
Normal file
15
drivers/net/wireless/intel/iwlwifi/cfg/rf-wh.c
Normal file
@ -0,0 +1,15 @@
|
||||
// SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause
|
||||
/*
|
||||
* Copyright (C) 2025 Intel Corporation
|
||||
*/
|
||||
#include "iwl-config.h"
|
||||
|
||||
/* currently iwl_rf_wh/iwl_rf_wh_160mhz are just defines for the FM ones */
|
||||
|
||||
const char iwl_killer_be1775s_name[] =
|
||||
"Killer(R) Wi-Fi 7 BE1775s 320MHz Wireless Network Adapter (BE211D2W)";
|
||||
const char iwl_killer_be1775i_name[] =
|
||||
"Killer(R) Wi-Fi 7 BE1775i 320MHz Wireless Network Adapter (BE211NGW)";
|
||||
|
||||
const char iwl_be211_name[] = "Intel(R) Wi-Fi 7 BE211 320MHz";
|
||||
const char iwl_be213_name[] = "Intel(R) Wi-Fi 7 BE213 160MHz";
|
||||
@ -10,19 +10,15 @@
|
||||
#include "fw/api/txq.h"
|
||||
|
||||
/* Highest firmware API version supported */
|
||||
#define IWL_SC_UCODE_API_MAX 98
|
||||
#define IWL_SC_UCODE_API_MAX 99
|
||||
|
||||
/* Lowest firmware API version supported */
|
||||
#define IWL_SC_UCODE_API_MIN 93
|
||||
#define IWL_SC_UCODE_API_MIN 97
|
||||
|
||||
/* NVM versions */
|
||||
#define IWL_SC_NVM_VERSION 0x0a1d
|
||||
|
||||
/* Memory offsets and lengths */
|
||||
#define IWL_SC_DCCM_OFFSET 0x800000 /* LMAC1 */
|
||||
#define IWL_SC_DCCM_LEN 0x10000 /* LMAC1 */
|
||||
#define IWL_SC_DCCM2_OFFSET 0x880000
|
||||
#define IWL_SC_DCCM2_LEN 0x8000
|
||||
#define IWL_SC_SMEM_OFFSET 0x400000
|
||||
#define IWL_SC_SMEM_LEN 0xD0000
|
||||
|
||||
@ -43,8 +39,7 @@
|
||||
#define IWL_SC_A_HR_B_FW_MODULE_FIRMWARE(api) \
|
||||
IWL_SC_A_HR_B_FW_PRE "-" __stringify(api) ".ucode"
|
||||
|
||||
static const struct iwl_base_params iwl_sc_base_params = {
|
||||
.eeprom_size = OTP_LOW_IMAGE_SIZE_32K,
|
||||
static const struct iwl_family_base_params iwl_sc_base = {
|
||||
.num_of_queues = 512,
|
||||
.max_tfd_queue_size = 65536,
|
||||
.shadow_ram_support = true,
|
||||
@ -53,87 +48,55 @@ static const struct iwl_base_params iwl_sc_base_params = {
|
||||
.max_event_log_size = 512,
|
||||
.shadow_reg_enable = true,
|
||||
.pcie_l1_allowed = true,
|
||||
.smem_offset = IWL_SC_SMEM_OFFSET,
|
||||
.smem_len = IWL_SC_SMEM_LEN,
|
||||
.apmg_not_supported = true,
|
||||
.mac_addr_from_csr = 0x30,
|
||||
.min_umac_error_event_table = 0xD0000,
|
||||
.d3_debug_data_base_addr = 0x401000,
|
||||
.d3_debug_data_length = 60 * 1024,
|
||||
.mon_smem_regs = {
|
||||
.write_ptr = {
|
||||
.addr = LDBG_M2S_BUF_WPTR,
|
||||
.mask = LDBG_M2S_BUF_WPTR_VAL_MSK,
|
||||
},
|
||||
.cycle_cnt = {
|
||||
.addr = LDBG_M2S_BUF_WRAP_CNT,
|
||||
.mask = LDBG_M2S_BUF_WRAP_CNT_VAL_MSK,
|
||||
},
|
||||
},
|
||||
.min_txq_size = 128,
|
||||
.gp2_reg_addr = 0xd02c68,
|
||||
.min_ba_txq_size = IWL_DEFAULT_QUEUE_SIZE_EHT,
|
||||
.mon_dram_regs = {
|
||||
.write_ptr = {
|
||||
.addr = DBGC_CUR_DBGBUF_STATUS,
|
||||
.mask = DBGC_CUR_DBGBUF_STATUS_OFFSET_MSK,
|
||||
},
|
||||
.cycle_cnt = {
|
||||
.addr = DBGC_DBGBUF_WRAP_AROUND,
|
||||
.mask = 0xffffffff,
|
||||
},
|
||||
.cur_frag = {
|
||||
.addr = DBGC_CUR_DBGBUF_STATUS,
|
||||
.mask = DBGC_CUR_DBGBUF_STATUS_IDX_MSK,
|
||||
},
|
||||
},
|
||||
.mon_dbgi_regs = {
|
||||
.write_ptr = {
|
||||
.addr = DBGI_SRAM_FIFO_POINTERS,
|
||||
.mask = DBGI_SRAM_FIFO_POINTERS_WR_PTR_MSK,
|
||||
},
|
||||
},
|
||||
.features = IWL_TX_CSUM_NETIF_FLAGS | NETIF_F_RXCSUM,
|
||||
.ucode_api_max = IWL_SC_UCODE_API_MAX,
|
||||
.ucode_api_min = IWL_SC_UCODE_API_MIN,
|
||||
};
|
||||
|
||||
#define IWL_DEVICE_BZ_COMMON \
|
||||
.ucode_api_max = IWL_SC_UCODE_API_MAX, \
|
||||
.ucode_api_min = IWL_SC_UCODE_API_MIN, \
|
||||
.led_mode = IWL_LED_RF_STATE, \
|
||||
.nvm_hw_section_num = 10, \
|
||||
.non_shared_ant = ANT_B, \
|
||||
.dccm_offset = IWL_SC_DCCM_OFFSET, \
|
||||
.dccm_len = IWL_SC_DCCM_LEN, \
|
||||
.dccm2_offset = IWL_SC_DCCM2_OFFSET, \
|
||||
.dccm2_len = IWL_SC_DCCM2_LEN, \
|
||||
.smem_offset = IWL_SC_SMEM_OFFSET, \
|
||||
.smem_len = IWL_SC_SMEM_LEN, \
|
||||
.apmg_not_supported = true, \
|
||||
.trans.mq_rx_supported = true, \
|
||||
.vht_mu_mimo_supported = true, \
|
||||
.mac_addr_from_csr = 0x30, \
|
||||
.nvm_ver = IWL_SC_NVM_VERSION, \
|
||||
.trans.rf_id = true, \
|
||||
.trans.gen2 = true, \
|
||||
.nvm_type = IWL_NVM_EXT, \
|
||||
.dbgc_supported = true, \
|
||||
.min_umac_error_event_table = 0xD0000, \
|
||||
.d3_debug_data_base_addr = 0x401000, \
|
||||
.d3_debug_data_length = 60 * 1024, \
|
||||
.mon_smem_regs = { \
|
||||
.write_ptr = { \
|
||||
.addr = LDBG_M2S_BUF_WPTR, \
|
||||
.mask = LDBG_M2S_BUF_WPTR_VAL_MSK, \
|
||||
}, \
|
||||
.cycle_cnt = { \
|
||||
.addr = LDBG_M2S_BUF_WRAP_CNT, \
|
||||
.mask = LDBG_M2S_BUF_WRAP_CNT_VAL_MSK, \
|
||||
}, \
|
||||
}, \
|
||||
.trans.umac_prph_offset = 0x300000, \
|
||||
.trans.device_family = IWL_DEVICE_FAMILY_SC, \
|
||||
.trans.base_params = &iwl_sc_base_params, \
|
||||
.min_txq_size = 128, \
|
||||
.gp2_reg_addr = 0xd02c68, \
|
||||
.min_ba_txq_size = IWL_DEFAULT_QUEUE_SIZE_EHT, \
|
||||
.mon_dram_regs = { \
|
||||
.write_ptr = { \
|
||||
.addr = DBGC_CUR_DBGBUF_STATUS, \
|
||||
.mask = DBGC_CUR_DBGBUF_STATUS_OFFSET_MSK, \
|
||||
}, \
|
||||
.cycle_cnt = { \
|
||||
.addr = DBGC_DBGBUF_WRAP_AROUND, \
|
||||
.mask = 0xffffffff, \
|
||||
}, \
|
||||
.cur_frag = { \
|
||||
.addr = DBGC_CUR_DBGBUF_STATUS, \
|
||||
.mask = DBGC_CUR_DBGBUF_STATUS_IDX_MSK, \
|
||||
}, \
|
||||
}, \
|
||||
.mon_dbgi_regs = { \
|
||||
.write_ptr = { \
|
||||
.addr = DBGI_SRAM_FIFO_POINTERS, \
|
||||
.mask = DBGI_SRAM_FIFO_POINTERS_WR_PTR_MSK, \
|
||||
}, \
|
||||
}
|
||||
|
||||
#define IWL_DEVICE_SC \
|
||||
IWL_DEVICE_BZ_COMMON, \
|
||||
.uhb_supported = true, \
|
||||
.features = IWL_TX_CSUM_NETIF_FLAGS | NETIF_F_RXCSUM, \
|
||||
.num_rbds = IWL_NUM_RBDS_SC_EHT, \
|
||||
.ht_params = &iwl_bz_ht_params
|
||||
|
||||
/*
|
||||
* This size was picked according to 8 MSDUs inside 512 A-MSDUs in an
|
||||
* A-MPDU, with additional overhead to account for processing time.
|
||||
*/
|
||||
#define IWL_NUM_RBDS_SC_EHT (512 * 16)
|
||||
|
||||
const struct iwl_cfg_trans_params iwl_sc_trans_cfg = {
|
||||
const struct iwl_mac_cfg iwl_sc_mac_cfg = {
|
||||
.device_family = IWL_DEVICE_FAMILY_SC,
|
||||
.base_params = &iwl_sc_base_params,
|
||||
.base = &iwl_sc_base,
|
||||
.mq_rx_supported = true,
|
||||
.rf_id = true,
|
||||
.gen2 = true,
|
||||
.integrated = true,
|
||||
.umac_prph_offset = 0x300000,
|
||||
@ -142,21 +105,6 @@ const struct iwl_cfg_trans_params iwl_sc_trans_cfg = {
|
||||
.ltr_delay = IWL_CFG_TRANS_LTR_DELAY_2500US,
|
||||
};
|
||||
|
||||
const struct iwl_cfg iwl_cfg_sc = {
|
||||
.fw_name_mac = "sc",
|
||||
IWL_DEVICE_SC,
|
||||
};
|
||||
|
||||
const struct iwl_cfg iwl_cfg_sc2 = {
|
||||
.fw_name_mac = "sc2",
|
||||
IWL_DEVICE_SC,
|
||||
};
|
||||
|
||||
const struct iwl_cfg iwl_cfg_sc2f = {
|
||||
.fw_name_mac = "sc2f",
|
||||
IWL_DEVICE_SC,
|
||||
};
|
||||
|
||||
IWL_FW_AND_PNVM(IWL_SC_A_FM_B_FW_PRE, IWL_SC_UCODE_API_MAX);
|
||||
IWL_FW_AND_PNVM(IWL_SC_A_FM_C_FW_PRE, IWL_SC_UCODE_API_MAX);
|
||||
MODULE_FIRMWARE(IWL_SC_A_HR_A_FW_MODULE_FIRMWARE(IWL_SC_UCODE_API_MAX));
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause */
|
||||
/*
|
||||
* Copyright (C) 2005-2014, 2021, 2024 Intel Corporation
|
||||
* Copyright (C) 2005-2014, 2021, 2024-2025 Intel Corporation
|
||||
*/
|
||||
#ifndef __iwl_agn_h__
|
||||
#define __iwl_agn_h__
|
||||
@ -399,7 +399,7 @@ static inline void iwl_dvm_set_pmi(struct iwl_priv *priv, bool state)
|
||||
* later with iwl_free_nvm_data().
|
||||
*/
|
||||
struct iwl_nvm_data *
|
||||
iwl_parse_eeprom_data(struct iwl_trans *trans, const struct iwl_cfg *cfg,
|
||||
iwl_parse_eeprom_data(struct iwl_trans *trans, const struct iwl_rf_cfg *cfg,
|
||||
const u8 *eeprom, size_t eeprom_size);
|
||||
|
||||
int iwl_read_eeprom(struct iwl_trans *trans, u8 **eeprom, size_t *eeprom_size);
|
||||
|
||||
@ -2,7 +2,7 @@
|
||||
/******************************************************************************
|
||||
*
|
||||
* Copyright(c) 2008 - 2014 Intel Corporation. All rights reserved.
|
||||
* Copyright (C) 2018 Intel Corporation
|
||||
* Copyright (C) 2018, 2025 Intel Corporation
|
||||
*****************************************************************************/
|
||||
|
||||
#include <linux/slab.h>
|
||||
@ -2097,7 +2097,8 @@ static ssize_t iwl_dbgfs_protection_mode_read(struct file *file,
|
||||
char buf[40];
|
||||
const size_t bufsz = sizeof(buf);
|
||||
|
||||
if (priv->cfg->ht_params)
|
||||
/* HT devices also have at least one HT40 band */
|
||||
if (priv->cfg->ht_params.ht40_bands)
|
||||
pos += scnprintf(buf + pos, bufsz - pos,
|
||||
"use %s for aggregation\n",
|
||||
(priv->hw_params.use_rts_for_aggregation) ?
|
||||
@ -2117,7 +2118,8 @@ static ssize_t iwl_dbgfs_protection_mode_write(struct file *file,
|
||||
int buf_size;
|
||||
int rts;
|
||||
|
||||
if (!priv->cfg->ht_params)
|
||||
/* HT devices also have at least one HT40 band */
|
||||
if (!priv->cfg->ht_params.ht40_bands)
|
||||
return -EINVAL;
|
||||
|
||||
memset(buf, 0, sizeof(buf));
|
||||
|
||||
@ -2,6 +2,7 @@
|
||||
/******************************************************************************
|
||||
*
|
||||
* Copyright(c) 2003 - 2014, 2020, 2023 Intel Corporation. All rights reserved.
|
||||
* Copyright (C) 2025 Intel Corporation
|
||||
*****************************************************************************/
|
||||
/*
|
||||
* Please use this file (dev.h) for driver implementation definitions.
|
||||
@ -627,7 +628,7 @@ struct iwl_priv {
|
||||
|
||||
struct iwl_trans *trans;
|
||||
struct device *dev; /* for debug prints only */
|
||||
const struct iwl_cfg *cfg;
|
||||
const struct iwl_rf_cfg *cfg;
|
||||
const struct iwl_fw *fw;
|
||||
const struct iwl_dvm_cfg *lib;
|
||||
unsigned long status;
|
||||
|
||||
@ -2,7 +2,7 @@
|
||||
/******************************************************************************
|
||||
*
|
||||
* Copyright(c) 2008 - 2014 Intel Corporation. All rights reserved.
|
||||
* Copyright (C) 2019 Intel Corporation
|
||||
* Copyright (C) 2019, 2025 Intel Corporation
|
||||
*****************************************************************************/
|
||||
|
||||
#include <linux/units.h>
|
||||
@ -481,7 +481,7 @@ static void iwl6000_set_ct_threshold(struct iwl_priv *priv)
|
||||
/* NIC configuration for 6000 series */
|
||||
static void iwl6000_nic_config(struct iwl_priv *priv)
|
||||
{
|
||||
switch (priv->trans->trans_cfg->device_family) {
|
||||
switch (priv->trans->mac_cfg->device_family) {
|
||||
case IWL_DEVICE_FAMILY_6005:
|
||||
case IWL_DEVICE_FAMILY_6030:
|
||||
case IWL_DEVICE_FAMILY_6000:
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
// SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause
|
||||
/*
|
||||
* Copyright (C) 2005-2014, 2018-2019, 2021, 2024 Intel Corporation
|
||||
* Copyright (C) 2005-2014, 2018-2019, 2021, 2024-2025 Intel Corporation
|
||||
*/
|
||||
#include <linux/types.h>
|
||||
#include <linux/slab.h>
|
||||
@ -151,7 +151,7 @@ static u16 iwl_eeprom_query16(const u8 *eeprom, size_t eeprom_size, int offset)
|
||||
{
|
||||
if (WARN_ON(offset + sizeof(u16) > eeprom_size))
|
||||
return 0;
|
||||
return le16_to_cpup((__le16 *)(eeprom + offset));
|
||||
return le16_to_cpup((const __le16 *)(eeprom + offset));
|
||||
}
|
||||
|
||||
static u32 eeprom_indirect_address(const u8 *eeprom, size_t eeprom_size,
|
||||
@ -204,8 +204,8 @@ static u32 eeprom_indirect_address(const u8 *eeprom, size_t eeprom_size,
|
||||
return (address & ADDRESS_MSK) + (offset << 1);
|
||||
}
|
||||
|
||||
static const u8 *iwl_eeprom_query_addr(const u8 *eeprom, size_t eeprom_size,
|
||||
u32 offset)
|
||||
static const void *iwl_eeprom_query_addr(const u8 *eeprom, size_t eeprom_size,
|
||||
u32 offset)
|
||||
{
|
||||
u32 address = eeprom_indirect_address(eeprom, eeprom_size, offset);
|
||||
|
||||
@ -218,10 +218,9 @@ static const u8 *iwl_eeprom_query_addr(const u8 *eeprom, size_t eeprom_size,
|
||||
static int iwl_eeprom_read_calib(const u8 *eeprom, size_t eeprom_size,
|
||||
struct iwl_nvm_data *data)
|
||||
{
|
||||
struct iwl_eeprom_calib_hdr *hdr;
|
||||
const struct iwl_eeprom_calib_hdr *hdr;
|
||||
|
||||
hdr = (void *)iwl_eeprom_query_addr(eeprom, eeprom_size,
|
||||
EEPROM_CALIB_ALL);
|
||||
hdr = iwl_eeprom_query_addr(eeprom, eeprom_size, EEPROM_CALIB_ALL);
|
||||
if (!hdr)
|
||||
return -ENODATA;
|
||||
data->calib_version = hdr->version;
|
||||
@ -295,7 +294,7 @@ struct iwl_eeprom_enhanced_txpwr {
|
||||
} __packed;
|
||||
|
||||
static s8 iwl_get_max_txpwr_half_dbm(const struct iwl_nvm_data *data,
|
||||
struct iwl_eeprom_enhanced_txpwr *txp)
|
||||
const struct iwl_eeprom_enhanced_txpwr *txp)
|
||||
{
|
||||
s8 result = 0; /* (.5 dBm) */
|
||||
|
||||
@ -329,7 +328,7 @@ static s8 iwl_get_max_txpwr_half_dbm(const struct iwl_nvm_data *data,
|
||||
|
||||
static void
|
||||
iwl_eeprom_enh_txp_read_element(struct iwl_nvm_data *data,
|
||||
struct iwl_eeprom_enhanced_txpwr *txp,
|
||||
const struct iwl_eeprom_enhanced_txpwr *txp,
|
||||
int n_channels, s8 max_txpower_avg)
|
||||
{
|
||||
int ch_idx;
|
||||
@ -360,20 +359,18 @@ static void iwl_eeprom_enhanced_txpower(struct device *dev,
|
||||
const u8 *eeprom, size_t eeprom_size,
|
||||
int n_channels)
|
||||
{
|
||||
struct iwl_eeprom_enhanced_txpwr *txp_array, *txp;
|
||||
const struct iwl_eeprom_enhanced_txpwr *txp_array, *txp;
|
||||
int idx, entries;
|
||||
__le16 *txp_len;
|
||||
const __le16 *txp_len;
|
||||
s8 max_txp_avg_halfdbm;
|
||||
|
||||
BUILD_BUG_ON(sizeof(struct iwl_eeprom_enhanced_txpwr) != 8);
|
||||
|
||||
/* the length is in 16-bit words, but we want entries */
|
||||
txp_len = (__le16 *)iwl_eeprom_query_addr(eeprom, eeprom_size,
|
||||
EEPROM_TXP_SZ_OFFS);
|
||||
txp_len = iwl_eeprom_query_addr(eeprom, eeprom_size, EEPROM_TXP_SZ_OFFS);
|
||||
entries = le16_to_cpup(txp_len) * 2 / EEPROM_TXP_ENTRY_LEN;
|
||||
|
||||
txp_array = (void *)iwl_eeprom_query_addr(eeprom, eeprom_size,
|
||||
EEPROM_TXP_OFFS);
|
||||
txp_array = iwl_eeprom_query_addr(eeprom, eeprom_size, EEPROM_TXP_OFFS);
|
||||
|
||||
for (idx = 0; idx < entries; idx++) {
|
||||
txp = &txp_array[idx];
|
||||
@ -416,7 +413,7 @@ static void iwl_eeprom_enhanced_txpower(struct device *dev,
|
||||
}
|
||||
}
|
||||
|
||||
static void iwl_init_band_reference(const struct iwl_cfg *cfg,
|
||||
static void iwl_init_band_reference(const struct iwl_rf_cfg *cfg,
|
||||
const u8 *eeprom, size_t eeprom_size,
|
||||
int eeprom_band, int *eeprom_ch_count,
|
||||
const struct iwl_eeprom_channel **ch_info,
|
||||
@ -426,7 +423,7 @@ static void iwl_init_band_reference(const struct iwl_cfg *cfg,
|
||||
|
||||
offset |= INDIRECT_ADDRESS | INDIRECT_REGULATORY;
|
||||
|
||||
*ch_info = (void *)iwl_eeprom_query_addr(eeprom, eeprom_size, offset);
|
||||
*ch_info = iwl_eeprom_query_addr(eeprom, eeprom_size, offset);
|
||||
|
||||
switch (eeprom_band) {
|
||||
case 1: /* 2.4GHz band */
|
||||
@ -510,7 +507,7 @@ static void iwl_mod_ht40_chan_info(struct device *dev,
|
||||
#define CHECK_AND_PRINT_I(x) \
|
||||
((eeprom_ch_info[ch_idx].flags & EEPROM_CHANNEL_##x) ? # x " " : "")
|
||||
|
||||
static int iwl_init_channel_map(struct device *dev, const struct iwl_cfg *cfg,
|
||||
static int iwl_init_channel_map(struct device *dev, const struct iwl_rf_cfg *cfg,
|
||||
struct iwl_nvm_data *data,
|
||||
const u8 *eeprom, size_t eeprom_size)
|
||||
{
|
||||
@ -749,7 +746,7 @@ static int iwl_nvm_is_otp(struct iwl_trans *trans)
|
||||
u32 otpgp;
|
||||
|
||||
/* OTP only valid for CP/PP and after */
|
||||
switch (trans->hw_rev & CSR_HW_REV_TYPE_MSK) {
|
||||
switch (trans->info.hw_rev & CSR_HW_REV_TYPE_MSK) {
|
||||
case CSR_HW_REV_TYPE_NONE:
|
||||
IWL_ERR(trans, "Unknown hardware type\n");
|
||||
return -EIO;
|
||||
@ -784,7 +781,7 @@ static int iwl_init_otp_access(struct iwl_trans *trans)
|
||||
* CSR auto clock gate disable bit -
|
||||
* this is only applicable for HW with OTP shadow RAM
|
||||
*/
|
||||
if (trans->trans_cfg->base_params->shadow_ram_support)
|
||||
if (trans->mac_cfg->base->shadow_ram_support)
|
||||
iwl_set_bit(trans, CSR_DBG_LINK_PWR_MGMT_REG,
|
||||
CSR_RESET_LINK_PWR_MGMT_DISABLED);
|
||||
|
||||
@ -905,7 +902,7 @@ static int iwl_find_otp_image(struct iwl_trans *trans,
|
||||
}
|
||||
/* more in the link list, continue */
|
||||
usedblocks++;
|
||||
} while (usedblocks <= trans->trans_cfg->base_params->max_ll_items);
|
||||
} while (usedblocks <= trans->mac_cfg->base->max_ll_items);
|
||||
|
||||
/* OTP has no valid blocks */
|
||||
IWL_DEBUG_EEPROM(trans->dev, "OTP has no valid blocks\n");
|
||||
@ -938,7 +935,7 @@ int iwl_read_eeprom(struct iwl_trans *trans, u8 **eeprom, size_t *eeprom_size)
|
||||
if (nvm_is_otp < 0)
|
||||
return nvm_is_otp;
|
||||
|
||||
sz = trans->trans_cfg->base_params->eeprom_size;
|
||||
sz = trans->mac_cfg->base->eeprom_size;
|
||||
IWL_DEBUG_EEPROM(trans->dev, "NVM size = %d\n", sz);
|
||||
|
||||
e = kmalloc(sz, GFP_KERNEL);
|
||||
@ -973,7 +970,7 @@ int iwl_read_eeprom(struct iwl_trans *trans, u8 **eeprom, size_t *eeprom_size)
|
||||
CSR_OTP_GP_REG_ECC_CORR_STATUS_MSK |
|
||||
CSR_OTP_GP_REG_ECC_UNCORR_STATUS_MSK);
|
||||
/* traversing the linked list if no shadow ram supported */
|
||||
if (!trans->trans_cfg->base_params->shadow_ram_support) {
|
||||
if (!trans->mac_cfg->base->shadow_ram_support) {
|
||||
ret = iwl_find_otp_image(trans, &validblockaddr);
|
||||
if (ret)
|
||||
goto err_unlock;
|
||||
@ -1027,7 +1024,7 @@ int iwl_read_eeprom(struct iwl_trans *trans, u8 **eeprom, size_t *eeprom_size)
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void iwl_init_sbands(struct iwl_trans *trans, const struct iwl_cfg *cfg,
|
||||
static void iwl_init_sbands(struct iwl_trans *trans, const struct iwl_rf_cfg *cfg,
|
||||
struct iwl_nvm_data *data,
|
||||
const u8 *eeprom, size_t eeprom_size)
|
||||
{
|
||||
@ -1062,7 +1059,7 @@ static void iwl_init_sbands(struct iwl_trans *trans, const struct iwl_cfg *cfg,
|
||||
|
||||
/* EEPROM data functions */
|
||||
struct iwl_nvm_data *
|
||||
iwl_parse_eeprom_data(struct iwl_trans *trans, const struct iwl_cfg *cfg,
|
||||
iwl_parse_eeprom_data(struct iwl_trans *trans, const struct iwl_rf_cfg *cfg,
|
||||
const u8 *eeprom, size_t eeprom_size)
|
||||
{
|
||||
struct iwl_nvm_data *data;
|
||||
@ -1098,14 +1095,14 @@ iwl_parse_eeprom_data(struct iwl_trans *trans, const struct iwl_cfg *cfg,
|
||||
EEPROM_RAW_TEMPERATURE);
|
||||
if (!tmp)
|
||||
goto err_free;
|
||||
data->raw_temperature = *(__le16 *)tmp;
|
||||
data->raw_temperature = *(const __le16 *)tmp;
|
||||
|
||||
tmp = iwl_eeprom_query_addr(eeprom, eeprom_size,
|
||||
EEPROM_KELVIN_TEMPERATURE);
|
||||
if (!tmp)
|
||||
goto err_free;
|
||||
data->kelvin_temperature = *(__le16 *)tmp;
|
||||
data->kelvin_voltage = *((__le16 *)tmp + 1);
|
||||
data->kelvin_temperature = *(const __le16 *)tmp;
|
||||
data->kelvin_voltage = *((const __le16 *)tmp + 1);
|
||||
|
||||
radio_cfg =
|
||||
iwl_eeprom_query16(eeprom, eeprom_size, EEPROM_RADIO_CONFIG);
|
||||
|
||||
@ -2,7 +2,7 @@
|
||||
/******************************************************************************
|
||||
*
|
||||
* Copyright(c) 2003 - 2014 Intel Corporation. All rights reserved.
|
||||
* Copyright (C) 2019 Intel Corporation
|
||||
* Copyright (C) 2019, 2025 Intel Corporation
|
||||
*****************************************************************************/
|
||||
|
||||
|
||||
@ -116,9 +116,9 @@ static int iwl_led_cmd(struct iwl_priv *priv,
|
||||
}
|
||||
|
||||
led_cmd.on = iwl_blink_compensation(priv, on,
|
||||
priv->trans->trans_cfg->base_params->led_compensation);
|
||||
priv->trans->mac_cfg->base->led_compensation);
|
||||
led_cmd.off = iwl_blink_compensation(priv, off,
|
||||
priv->trans->trans_cfg->base_params->led_compensation);
|
||||
priv->trans->mac_cfg->base->led_compensation);
|
||||
|
||||
ret = iwl_send_led_cmd(priv, &led_cmd);
|
||||
if (!ret) {
|
||||
|
||||
@ -2,7 +2,7 @@
|
||||
/******************************************************************************
|
||||
*
|
||||
* Copyright(c) 2003 - 2014 Intel Corporation. All rights reserved.
|
||||
* Copyright(C) 2018 - 2019, 2022 - 2024 Intel Corporation
|
||||
* Copyright(C) 2018 - 2019, 2022 - 2025 Intel Corporation
|
||||
*
|
||||
* Portions of this file are derived from the ipw3945 project, as well
|
||||
* as portions of the ieee80211 subsystem header files.
|
||||
@ -96,7 +96,7 @@ int iwlagn_mac_setup_register(struct iwl_priv *priv,
|
||||
ieee80211_hw_set(hw, SUPPORT_FAST_XMIT);
|
||||
ieee80211_hw_set(hw, WANT_MONITOR_VIF);
|
||||
|
||||
if (priv->trans->max_skb_frags)
|
||||
if (priv->trans->info.max_skb_frags)
|
||||
hw->netdev_features = NETIF_F_HIGHDMA | NETIF_F_SG;
|
||||
|
||||
hw->offchannel_tx_hw_queue = IWL_AUX_QUEUE;
|
||||
@ -188,7 +188,7 @@ int iwlagn_mac_setup_register(struct iwl_priv *priv,
|
||||
priv->hw->wiphy->bands[NL80211_BAND_5GHZ] =
|
||||
&priv->nvm_data->bands[NL80211_BAND_5GHZ];
|
||||
|
||||
hw->wiphy->hw_version = priv->trans->hw_id;
|
||||
hw->wiphy->hw_version = priv->trans->info.hw_id;
|
||||
|
||||
iwl_leds_init(priv);
|
||||
|
||||
@ -549,7 +549,7 @@ static int iwlagn_mac_resume(struct ieee80211_hw *hw)
|
||||
|
||||
iwlagn_prepare_restart(priv);
|
||||
|
||||
memset((void *)&ctx->active, 0, sizeof(ctx->active));
|
||||
memset((void *)(uintptr_t)&ctx->active, 0, sizeof(ctx->active));
|
||||
iwl_connection_init_rx_config(priv, ctx);
|
||||
iwlagn_set_rxon_chain(priv, ctx);
|
||||
|
||||
@ -1091,7 +1091,7 @@ static void iwlagn_mac_flush(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
|
||||
goto done;
|
||||
}
|
||||
|
||||
scd_queues = BIT(priv->trans->trans_cfg->base_params->num_of_queues) - 1;
|
||||
scd_queues = BIT(priv->trans->mac_cfg->base->num_of_queues) - 1;
|
||||
scd_queues &= ~(BIT(IWL_IPAN_CMD_QUEUE_NUM) |
|
||||
BIT(IWL_DEFAULT_CMD_QUEUE_NUM));
|
||||
|
||||
|
||||
@ -2,7 +2,7 @@
|
||||
/******************************************************************************
|
||||
*
|
||||
* Copyright(c) 2003 - 2014, 2018 - 2022 Intel Corporation. All rights reserved.
|
||||
* Copyright(c) 2024 Intel Corporation. All rights reserved.
|
||||
* Copyright(c) 2024-2025 Intel Corporation. All rights reserved.
|
||||
* Copyright(c) 2015 Intel Deutschland GmbH
|
||||
*
|
||||
* Portions of this file are derived from the ipw3945 project, as well
|
||||
@ -824,11 +824,11 @@ int iwl_alive_start(struct iwl_priv *priv)
|
||||
iwlagn_send_tx_ant_config(priv, priv->nvm_data->valid_tx_ant);
|
||||
|
||||
if (iwl_is_associated_ctx(ctx) && !priv->wowlan) {
|
||||
struct iwl_rxon_cmd *active_rxon =
|
||||
(struct iwl_rxon_cmd *)&ctx->active;
|
||||
struct iwl_rxon_cmd *active = (void *)(uintptr_t)&ctx->active;
|
||||
|
||||
/* apply any changes in staging */
|
||||
ctx->staging.filter_flags |= RXON_FILTER_ASSOC_MSK;
|
||||
active_rxon->filter_flags &= ~RXON_FILTER_ASSOC_MSK;
|
||||
active->filter_flags &= ~RXON_FILTER_ASSOC_MSK;
|
||||
} else {
|
||||
struct iwl_rxon_context *tmp;
|
||||
/* Initialize our rx_config data */
|
||||
@ -1137,9 +1137,10 @@ static void iwl_uninit_drv(struct iwl_priv *priv)
|
||||
|
||||
static void iwl_set_hw_params(struct iwl_priv *priv)
|
||||
{
|
||||
if (priv->cfg->ht_params)
|
||||
/* there are no devices with HT but without HT40 on all bands */
|
||||
if (priv->cfg->ht_params.ht40_bands)
|
||||
priv->hw_params.use_rts_for_aggregation =
|
||||
priv->cfg->ht_params->use_rts_for_aggregation;
|
||||
priv->cfg->ht_params.use_rts_for_aggregation;
|
||||
|
||||
/* Device-specific setup */
|
||||
priv->lib->set_hw_params(priv);
|
||||
@ -1173,8 +1174,9 @@ static int iwl_eeprom_init_hw_params(struct iwl_priv *priv)
|
||||
{
|
||||
struct iwl_nvm_data *data = priv->nvm_data;
|
||||
|
||||
/* all HT devices also have HT40 on at least one band */
|
||||
if (data->sku_cap_11n_enable &&
|
||||
!priv->cfg->ht_params) {
|
||||
!priv->cfg->ht_params.ht40_bands) {
|
||||
IWL_ERR(priv, "Invalid 11n configuration\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
@ -1224,7 +1226,7 @@ static int iwl_nvm_check_version(struct iwl_nvm_data *data,
|
||||
}
|
||||
|
||||
static struct iwl_op_mode *iwl_op_mode_dvm_start(struct iwl_trans *trans,
|
||||
const struct iwl_cfg *cfg,
|
||||
const struct iwl_rf_cfg *cfg,
|
||||
const struct iwl_fw *fw,
|
||||
struct dentry *dbgfs_dir)
|
||||
{
|
||||
@ -1233,7 +1235,6 @@ static struct iwl_op_mode *iwl_op_mode_dvm_start(struct iwl_trans *trans,
|
||||
struct iwl_op_mode *op_mode;
|
||||
u16 num_mac;
|
||||
u32 ucode_flags;
|
||||
struct iwl_trans_config trans_cfg = {};
|
||||
static const u8 no_reclaim_cmds[] = {
|
||||
REPLY_RX_PHY_CMD,
|
||||
REPLY_RX_MPDU_CMD,
|
||||
@ -1248,7 +1249,8 @@ static struct iwl_op_mode *iwl_op_mode_dvm_start(struct iwl_trans *trans,
|
||||
************************/
|
||||
hw = iwl_alloc_all();
|
||||
if (!hw) {
|
||||
pr_err("%s: Cannot allocate network device\n", trans->name);
|
||||
pr_err("%s: Cannot allocate network device\n",
|
||||
trans->info.name);
|
||||
err = -ENOMEM;
|
||||
goto out;
|
||||
}
|
||||
@ -1261,7 +1263,7 @@ static struct iwl_op_mode *iwl_op_mode_dvm_start(struct iwl_trans *trans,
|
||||
priv->cfg = cfg;
|
||||
priv->fw = fw;
|
||||
|
||||
switch (priv->trans->trans_cfg->device_family) {
|
||||
switch (priv->trans->mac_cfg->device_family) {
|
||||
case IWL_DEVICE_FAMILY_1000:
|
||||
case IWL_DEVICE_FAMILY_100:
|
||||
priv->lib = &iwl_dvm_1000_cfg;
|
||||
@ -1309,52 +1311,50 @@ static struct iwl_op_mode *iwl_op_mode_dvm_start(struct iwl_trans *trans,
|
||||
* Populate the state variables that the transport layer needs
|
||||
* to know about.
|
||||
*/
|
||||
trans_cfg.op_mode = op_mode;
|
||||
trans_cfg.no_reclaim_cmds = no_reclaim_cmds;
|
||||
trans_cfg.n_no_reclaim_cmds = ARRAY_SIZE(no_reclaim_cmds);
|
||||
BUILD_BUG_ON(sizeof(no_reclaim_cmds) >
|
||||
sizeof(trans->conf.no_reclaim_cmds));
|
||||
memcpy(trans->conf.no_reclaim_cmds, no_reclaim_cmds,
|
||||
sizeof(no_reclaim_cmds));
|
||||
|
||||
switch (iwlwifi_mod_params.amsdu_size) {
|
||||
case IWL_AMSDU_DEF:
|
||||
case IWL_AMSDU_4K:
|
||||
trans_cfg.rx_buf_size = IWL_AMSDU_4K;
|
||||
trans->conf.rx_buf_size = IWL_AMSDU_4K;
|
||||
break;
|
||||
case IWL_AMSDU_8K:
|
||||
trans_cfg.rx_buf_size = IWL_AMSDU_8K;
|
||||
trans->conf.rx_buf_size = IWL_AMSDU_8K;
|
||||
break;
|
||||
case IWL_AMSDU_12K:
|
||||
default:
|
||||
trans_cfg.rx_buf_size = IWL_AMSDU_4K;
|
||||
trans->conf.rx_buf_size = IWL_AMSDU_4K;
|
||||
pr_err("Unsupported amsdu_size: %d\n",
|
||||
iwlwifi_mod_params.amsdu_size);
|
||||
}
|
||||
|
||||
trans_cfg.command_groups = iwl_dvm_groups;
|
||||
trans_cfg.command_groups_size = ARRAY_SIZE(iwl_dvm_groups);
|
||||
trans->conf.command_groups = iwl_dvm_groups;
|
||||
trans->conf.command_groups_size = ARRAY_SIZE(iwl_dvm_groups);
|
||||
|
||||
trans_cfg.cmd_fifo = IWLAGN_CMD_FIFO_NUM;
|
||||
trans_cfg.cb_data_offs = offsetof(struct ieee80211_tx_info,
|
||||
driver_data[2]);
|
||||
trans->conf.cmd_fifo = IWLAGN_CMD_FIFO_NUM;
|
||||
trans->conf.cb_data_offs = offsetof(struct ieee80211_tx_info,
|
||||
driver_data[2]);
|
||||
|
||||
WARN_ON(sizeof(priv->transport_queue_stop) * BITS_PER_BYTE <
|
||||
priv->trans->trans_cfg->base_params->num_of_queues);
|
||||
priv->trans->mac_cfg->base->num_of_queues);
|
||||
|
||||
ucode_flags = fw->ucode_capa.flags;
|
||||
|
||||
if (ucode_flags & IWL_UCODE_TLV_FLAGS_PAN) {
|
||||
priv->sta_key_max_num = STA_KEY_MAX_NUM_PAN;
|
||||
trans_cfg.cmd_queue = IWL_IPAN_CMD_QUEUE_NUM;
|
||||
trans->conf.cmd_queue = IWL_IPAN_CMD_QUEUE_NUM;
|
||||
} else {
|
||||
priv->sta_key_max_num = STA_KEY_MAX_NUM;
|
||||
trans_cfg.cmd_queue = IWL_DEFAULT_CMD_QUEUE_NUM;
|
||||
trans->conf.cmd_queue = IWL_DEFAULT_CMD_QUEUE_NUM;
|
||||
}
|
||||
|
||||
/* Configure transport layer */
|
||||
iwl_trans_configure(priv->trans, &trans_cfg);
|
||||
trans->conf.rx_mpdu_cmd = REPLY_RX_MPDU_CMD;
|
||||
trans->conf.rx_mpdu_cmd_hdr_size = sizeof(struct iwl_rx_mpdu_res_start);
|
||||
|
||||
trans->rx_mpdu_cmd = REPLY_RX_MPDU_CMD;
|
||||
trans->rx_mpdu_cmd_hdr_size = sizeof(struct iwl_rx_mpdu_res_start);
|
||||
trans->command_groups = trans_cfg.command_groups;
|
||||
trans->command_groups_size = trans_cfg.command_groups_size;
|
||||
iwl_trans_op_mode_enter(priv->trans, op_mode);
|
||||
|
||||
/* At this point both hw and priv are allocated. */
|
||||
|
||||
@ -1378,18 +1378,18 @@ static struct iwl_op_mode *iwl_op_mode_dvm_start(struct iwl_trans *trans,
|
||||
* 2. Read REV register
|
||||
***********************/
|
||||
IWL_INFO(priv, "Detected %s, REV=0x%X\n",
|
||||
priv->trans->name, priv->trans->hw_rev);
|
||||
priv->trans->info.name, priv->trans->info.hw_rev);
|
||||
|
||||
err = iwl_trans_start_hw(priv->trans);
|
||||
if (err)
|
||||
goto out_free_hw;
|
||||
goto out_leave_trans;
|
||||
|
||||
/* Read the EEPROM */
|
||||
err = iwl_read_eeprom(priv->trans, &priv->eeprom_blob,
|
||||
&priv->eeprom_blob_size);
|
||||
if (err) {
|
||||
IWL_ERR(priv, "Unable to init EEPROM\n");
|
||||
goto out_free_hw;
|
||||
goto out_leave_trans;
|
||||
}
|
||||
|
||||
/* Reset chip to save power until we load uCode during "up". */
|
||||
@ -1437,10 +1437,7 @@ static struct iwl_op_mode *iwl_op_mode_dvm_start(struct iwl_trans *trans,
|
||||
* packaging bug or due to the eeprom check above
|
||||
*/
|
||||
priv->sta_key_max_num = STA_KEY_MAX_NUM;
|
||||
trans_cfg.cmd_queue = IWL_DEFAULT_CMD_QUEUE_NUM;
|
||||
|
||||
/* Configure transport layer again*/
|
||||
iwl_trans_configure(priv->trans, &trans_cfg);
|
||||
trans->conf.cmd_queue = IWL_DEFAULT_CMD_QUEUE_NUM;
|
||||
}
|
||||
|
||||
/*******************
|
||||
@ -1508,6 +1505,8 @@ static struct iwl_op_mode *iwl_op_mode_dvm_start(struct iwl_trans *trans,
|
||||
kfree(priv->eeprom_blob);
|
||||
out_free_eeprom:
|
||||
kfree(priv->nvm_data);
|
||||
out_leave_trans:
|
||||
iwl_trans_op_mode_leave(priv->trans);
|
||||
out_free_hw:
|
||||
ieee80211_free_hw(priv->hw);
|
||||
out:
|
||||
@ -1992,7 +1991,7 @@ static void iwl_nic_config(struct iwl_op_mode *op_mode)
|
||||
/* SKU Control */
|
||||
iwl_trans_set_bits_mask(priv->trans, CSR_HW_IF_CONFIG_REG,
|
||||
CSR_HW_IF_CONFIG_REG_MSK_MAC_STEP_DASH,
|
||||
CSR_HW_REV_STEP_DASH(priv->trans->hw_rev));
|
||||
CSR_HW_REV_STEP_DASH(priv->trans->info.hw_rev));
|
||||
|
||||
/* write radio config values to register */
|
||||
if (priv->nvm_data->radio_cfg_type <= EEPROM_RF_CONFIG_TYPE_MAX) {
|
||||
|
||||
@ -2,7 +2,7 @@
|
||||
/******************************************************************************
|
||||
*
|
||||
* Copyright(c) 2007 - 2014 Intel Corporation. All rights reserved.
|
||||
* Copyright (C) 2019 Intel Corporation
|
||||
* Copyright (C) 2019, 2025 Intel Corporation
|
||||
*
|
||||
* Portions of this file are derived from the ipw3945 project, as well
|
||||
* as portions of the ieee80211 subsystem header files.
|
||||
@ -64,32 +64,32 @@ struct iwl_power_vec_entry {
|
||||
/* for DTIM period 0 through IWL_DTIM_RANGE_0_MAX */
|
||||
/* DTIM 0 - 2 */
|
||||
static const struct iwl_power_vec_entry range_0[IWL_POWER_NUM] = {
|
||||
{{SLP, SLP_TOUT(200), SLP_TOUT(500), SLP_VEC(1, 1, 2, 2, 0xFF)}, 0},
|
||||
{{SLP, SLP_TOUT(200), SLP_TOUT(300), SLP_VEC(1, 2, 2, 2, 0xFF)}, 0},
|
||||
{{SLP, SLP_TOUT(50), SLP_TOUT(100), SLP_VEC(2, 2, 2, 2, 0xFF)}, 0},
|
||||
{{SLP, SLP_TOUT(50), SLP_TOUT(25), SLP_VEC(2, 2, 4, 4, 0xFF)}, 1},
|
||||
{{SLP, SLP_TOUT(25), SLP_TOUT(25), SLP_VEC(2, 2, 4, 6, 0xFF)}, 2}
|
||||
{{SLP, SLP_TOUT(200), SLP_TOUT(500), SLP_VEC(1, 1, 2, 2, 0xFF), 0}, 0},
|
||||
{{SLP, SLP_TOUT(200), SLP_TOUT(300), SLP_VEC(1, 2, 2, 2, 0xFF), 0}, 0},
|
||||
{{SLP, SLP_TOUT(50), SLP_TOUT(100), SLP_VEC(2, 2, 2, 2, 0xFF), 0}, 0},
|
||||
{{SLP, SLP_TOUT(50), SLP_TOUT(25), SLP_VEC(2, 2, 4, 4, 0xFF), 0}, 1},
|
||||
{{SLP, SLP_TOUT(25), SLP_TOUT(25), SLP_VEC(2, 2, 4, 6, 0xFF), 0}, 2}
|
||||
};
|
||||
|
||||
|
||||
/* for DTIM period IWL_DTIM_RANGE_0_MAX + 1 through IWL_DTIM_RANGE_1_MAX */
|
||||
/* DTIM 3 - 10 */
|
||||
static const struct iwl_power_vec_entry range_1[IWL_POWER_NUM] = {
|
||||
{{SLP, SLP_TOUT(200), SLP_TOUT(500), SLP_VEC(1, 2, 3, 4, 4)}, 0},
|
||||
{{SLP, SLP_TOUT(200), SLP_TOUT(300), SLP_VEC(1, 2, 3, 4, 7)}, 0},
|
||||
{{SLP, SLP_TOUT(50), SLP_TOUT(100), SLP_VEC(2, 4, 6, 7, 9)}, 0},
|
||||
{{SLP, SLP_TOUT(50), SLP_TOUT(25), SLP_VEC(2, 4, 6, 9, 10)}, 1},
|
||||
{{SLP, SLP_TOUT(25), SLP_TOUT(25), SLP_VEC(2, 4, 6, 10, 10)}, 2}
|
||||
{{SLP, SLP_TOUT(200), SLP_TOUT(500), SLP_VEC(1, 2, 3, 4, 4), 0}, 0},
|
||||
{{SLP, SLP_TOUT(200), SLP_TOUT(300), SLP_VEC(1, 2, 3, 4, 7), 0}, 0},
|
||||
{{SLP, SLP_TOUT(50), SLP_TOUT(100), SLP_VEC(2, 4, 6, 7, 9), 0}, 0},
|
||||
{{SLP, SLP_TOUT(50), SLP_TOUT(25), SLP_VEC(2, 4, 6, 9, 10), 0}, 1},
|
||||
{{SLP, SLP_TOUT(25), SLP_TOUT(25), SLP_VEC(2, 4, 6, 10, 10), 0}, 2}
|
||||
};
|
||||
|
||||
/* for DTIM period > IWL_DTIM_RANGE_1_MAX */
|
||||
/* DTIM 11 - */
|
||||
static const struct iwl_power_vec_entry range_2[IWL_POWER_NUM] = {
|
||||
{{SLP, SLP_TOUT(200), SLP_TOUT(500), SLP_VEC(1, 2, 3, 4, 0xFF)}, 0},
|
||||
{{SLP, SLP_TOUT(200), SLP_TOUT(300), SLP_VEC(2, 4, 6, 7, 0xFF)}, 0},
|
||||
{{SLP, SLP_TOUT(50), SLP_TOUT(100), SLP_VEC(2, 7, 9, 9, 0xFF)}, 0},
|
||||
{{SLP, SLP_TOUT(50), SLP_TOUT(25), SLP_VEC(2, 7, 9, 9, 0xFF)}, 0},
|
||||
{{SLP, SLP_TOUT(25), SLP_TOUT(25), SLP_VEC(4, 7, 10, 10, 0xFF)}, 0}
|
||||
{{SLP, SLP_TOUT(200), SLP_TOUT(500), SLP_VEC(1, 2, 3, 4, 0xFF), 0}, 0},
|
||||
{{SLP, SLP_TOUT(200), SLP_TOUT(300), SLP_VEC(2, 4, 6, 7, 0xFF), 0}, 0},
|
||||
{{SLP, SLP_TOUT(50), SLP_TOUT(100), SLP_VEC(2, 7, 9, 9, 0xFF), 0}, 0},
|
||||
{{SLP, SLP_TOUT(50), SLP_TOUT(25), SLP_VEC(2, 7, 9, 9, 0xFF), 0}, 0},
|
||||
{{SLP, SLP_TOUT(25), SLP_TOUT(25), SLP_VEC(4, 7, 10, 10, 0xFF), 0}, 0}
|
||||
};
|
||||
|
||||
/* advance power management */
|
||||
@ -196,7 +196,7 @@ static void iwl_static_sleep_cmd(struct iwl_priv *priv,
|
||||
else
|
||||
cmd->flags &= ~IWL_POWER_SLEEP_OVER_DTIM_MSK;
|
||||
|
||||
if (priv->trans->trans_cfg->base_params->shadow_reg_enable)
|
||||
if (priv->trans->mac_cfg->base->shadow_reg_enable)
|
||||
cmd->flags |= IWL_POWER_SHADOW_REG_ENA;
|
||||
else
|
||||
cmd->flags &= ~IWL_POWER_SHADOW_REG_ENA;
|
||||
|
||||
@ -3,7 +3,7 @@
|
||||
*
|
||||
* Copyright(c) 2003 - 2014 Intel Corporation. All rights reserved.
|
||||
* Copyright(c) 2015 Intel Deutschland GmbH
|
||||
* Copyright(c) 2018, 2020-2021 Intel Corporation
|
||||
* Copyright(c) 2018, 2020-2021, 2025 Intel Corporation
|
||||
*
|
||||
* Portions of this file are derived from the ipw3945 project, as well
|
||||
* as portionhelp of the ieee80211 subsystem header files.
|
||||
@ -50,7 +50,7 @@ static void iwlagn_rx_csa(struct iwl_priv *priv, struct iwl_rx_cmd_buffer *rxb)
|
||||
* See iwlagn_mac_channel_switch.
|
||||
*/
|
||||
struct iwl_rxon_context *ctx = &priv->contexts[IWL_RXON_CTX_BSS];
|
||||
struct iwl_rxon_cmd *rxon = (void *)&ctx->active;
|
||||
struct iwl_rxon_cmd *rxon = (void *)(uintptr_t)&ctx->active;
|
||||
|
||||
if (!test_bit(STATUS_CHANNEL_SWITCH_PENDING, &priv->status))
|
||||
return;
|
||||
@ -643,8 +643,8 @@ static void iwlagn_pass_packet_to_mac80211(struct iwl_priv *priv,
|
||||
fraglen = len - hdrlen;
|
||||
|
||||
if (fraglen) {
|
||||
int offset = (void *)hdr + hdrlen -
|
||||
rxb_addr(rxb) + rxb_offset(rxb);
|
||||
int offset = (u8 *)hdr + hdrlen -
|
||||
(u8 *)rxb_addr(rxb) + rxb_offset(rxb);
|
||||
|
||||
skb_add_rx_frag(skb, 0, rxb_steal_page(rxb), offset,
|
||||
fraglen, rxb->truesize);
|
||||
|
||||
@ -1,7 +1,7 @@
|
||||
// SPDX-License-Identifier: GPL-2.0-only
|
||||
/******************************************************************************
|
||||
*
|
||||
* Copyright(c) 2003 - 2014 Intel Corporation. All rights reserved.
|
||||
* Copyright(c) 2003 - 2014, 2025 Intel Corporation. All rights reserved.
|
||||
* Copyright(c) 2015 Intel Deutschland GmbH
|
||||
*****************************************************************************/
|
||||
|
||||
@ -341,7 +341,7 @@ static int iwlagn_rxon_disconn(struct iwl_priv *priv,
|
||||
struct iwl_rxon_context *ctx)
|
||||
{
|
||||
int ret;
|
||||
struct iwl_rxon_cmd *active = (void *)&ctx->active;
|
||||
struct iwl_rxon_cmd *active = (void *)(uintptr_t)&ctx->active;
|
||||
|
||||
if (ctx->ctxid == IWL_RXON_CTX_BSS) {
|
||||
ret = iwlagn_disable_bss(priv, ctx, &ctx->staging);
|
||||
@ -441,7 +441,7 @@ static int iwlagn_rxon_connect(struct iwl_priv *priv,
|
||||
struct iwl_rxon_context *ctx)
|
||||
{
|
||||
int ret;
|
||||
struct iwl_rxon_cmd *active = (void *)&ctx->active;
|
||||
struct iwl_rxon_cmd *active = (void *)(uintptr_t)&ctx->active;
|
||||
|
||||
/* RXON timing must be before associated RXON */
|
||||
if (ctx->ctxid == IWL_RXON_CTX_BSS) {
|
||||
@ -1023,7 +1023,7 @@ static void iwl_calc_basic_rates(struct iwl_priv *priv,
|
||||
int iwlagn_commit_rxon(struct iwl_priv *priv, struct iwl_rxon_context *ctx)
|
||||
{
|
||||
/* cast away the const for active_rxon in this function */
|
||||
struct iwl_rxon_cmd *active = (void *)&ctx->active;
|
||||
struct iwl_rxon_cmd *active = (void *)(uintptr_t)&ctx->active;
|
||||
bool new_assoc = !!(ctx->staging.filter_flags & RXON_FILTER_ASSOC_MSK);
|
||||
int ret;
|
||||
|
||||
|
||||
@ -3,7 +3,7 @@
|
||||
*
|
||||
* Copyright(c) 2008 - 2014 Intel Corporation. All rights reserved.
|
||||
* Copyright (C) 2019 Intel Corporation
|
||||
* Copyright (C) 2023 Intel Corporation
|
||||
* Copyright (C) 2023, 2025 Intel Corporation
|
||||
*****************************************************************************/
|
||||
|
||||
#include <linux/kernel.h>
|
||||
@ -463,7 +463,7 @@ static int iwlagn_alloc_agg_txq(struct iwl_priv *priv, int mq)
|
||||
int q;
|
||||
|
||||
for (q = IWLAGN_FIRST_AMPDU_QUEUE;
|
||||
q < priv->trans->trans_cfg->base_params->num_of_queues; q++) {
|
||||
q < priv->trans->mac_cfg->base->num_of_queues; q++) {
|
||||
if (!test_and_set_bit(q, priv->agg_q_alloc)) {
|
||||
priv->queue_to_mac80211[q] = mq;
|
||||
return q;
|
||||
@ -1277,7 +1277,7 @@ void iwlagn_rx_reply_compressed_ba(struct iwl_priv *priv,
|
||||
* (in Tx queue's circular buffer) of first TFD/frame in window */
|
||||
u16 ba_resp_scd_ssn = le16_to_cpu(ba_resp->scd_ssn);
|
||||
|
||||
if (scd_flow >= priv->trans->trans_cfg->base_params->num_of_queues) {
|
||||
if (scd_flow >= priv->trans->mac_cfg->base->num_of_queues) {
|
||||
IWL_ERR(priv,
|
||||
"BUG_ON scd_flow is bigger than number of queues\n");
|
||||
return;
|
||||
|
||||
@ -3,6 +3,7 @@
|
||||
*
|
||||
* Copyright(c) 2008 - 2014 Intel Corporation. All rights reserved.
|
||||
* Copyright(c) 2015 Intel Deutschland GmbH
|
||||
* Copyright (C) 2025 Intel Corporation
|
||||
*****************************************************************************/
|
||||
|
||||
#include <linux/kernel.h>
|
||||
@ -222,7 +223,7 @@ static int iwl_alive_notify(struct iwl_priv *priv)
|
||||
int ret;
|
||||
int i;
|
||||
|
||||
iwl_trans_fw_alive(priv->trans, 0);
|
||||
iwl_trans_fw_alive(priv->trans);
|
||||
|
||||
if (priv->fw->ucode_capa.flags & IWL_UCODE_TLV_FLAGS_PAN &&
|
||||
priv->nvm_data->sku_cap_ipan_enable) {
|
||||
@ -293,15 +294,10 @@ int iwl_load_ucode_wait_alive(struct iwl_priv *priv,
|
||||
{
|
||||
struct iwl_notification_wait alive_wait;
|
||||
struct iwl_alive_data alive_data;
|
||||
const struct fw_img *fw;
|
||||
int ret;
|
||||
enum iwl_ucode_type old_type;
|
||||
static const u16 alive_cmd[] = { REPLY_ALIVE };
|
||||
|
||||
fw = iwl_get_ucode_image(priv->fw, ucode_type);
|
||||
if (WARN_ON(!fw))
|
||||
return -EINVAL;
|
||||
|
||||
old_type = priv->cur_ucode;
|
||||
priv->cur_ucode = ucode_type;
|
||||
priv->ucode_loaded = false;
|
||||
@ -310,7 +306,7 @@ int iwl_load_ucode_wait_alive(struct iwl_priv *priv,
|
||||
alive_cmd, ARRAY_SIZE(alive_cmd),
|
||||
iwl_alive_fn, &alive_data);
|
||||
|
||||
ret = iwl_trans_start_fw(priv->trans, fw, false);
|
||||
ret = iwl_trans_start_fw(priv->trans, priv->fw, ucode_type, false);
|
||||
if (ret) {
|
||||
priv->cur_ucode = old_type;
|
||||
iwl_remove_notification(&priv->notif_wait, &alive_wait);
|
||||
|
||||
@ -1,7 +1,7 @@
|
||||
// SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause
|
||||
/*
|
||||
* Copyright (C) 2017 Intel Deutschland GmbH
|
||||
* Copyright (C) 2019-2024 Intel Corporation
|
||||
* Copyright (C) 2019-2025 Intel Corporation
|
||||
*/
|
||||
#include <linux/uuid.h>
|
||||
#include "iwl-drv.h"
|
||||
@ -847,12 +847,12 @@ int iwl_acpi_get_ppag_table(struct iwl_fw_runtime *fwrt)
|
||||
if (IS_ERR(data))
|
||||
return PTR_ERR(data);
|
||||
|
||||
/* try to read ppag table rev 3, 2 or 1 (all have the same data size) */
|
||||
/* try to read ppag table rev 1 to 4 (all have the same data size) */
|
||||
wifi_pkg = iwl_acpi_get_wifi_pkg(fwrt->dev, data,
|
||||
ACPI_PPAG_WIFI_DATA_SIZE_V2, &tbl_rev);
|
||||
|
||||
if (!IS_ERR(wifi_pkg)) {
|
||||
if (tbl_rev >= 1 && tbl_rev <= 3) {
|
||||
if (tbl_rev >= 1 && tbl_rev <= 4) {
|
||||
num_sub_bands = IWL_NUM_SUB_BANDS_V2;
|
||||
IWL_DEBUG_RADIO(fwrt,
|
||||
"Reading PPAG table (tbl_rev=%d)\n",
|
||||
@ -882,7 +882,7 @@ int iwl_acpi_get_ppag_table(struct iwl_fw_runtime *fwrt)
|
||||
goto out_free;
|
||||
|
||||
read_table:
|
||||
fwrt->ppag_ver = tbl_rev;
|
||||
fwrt->ppag_bios_rev = tbl_rev;
|
||||
flags = &wifi_pkg->package.elements[1];
|
||||
|
||||
if (flags->type != ACPI_TYPE_INTEGER) {
|
||||
@ -891,7 +891,7 @@ int iwl_acpi_get_ppag_table(struct iwl_fw_runtime *fwrt)
|
||||
}
|
||||
|
||||
fwrt->ppag_flags = iwl_bios_get_ppag_flags(flags->integer.value,
|
||||
fwrt->ppag_ver);
|
||||
fwrt->ppag_bios_rev);
|
||||
|
||||
/*
|
||||
* read, verify gain values and save them into the PPAG table.
|
||||
@ -912,6 +912,7 @@ int iwl_acpi_get_ppag_table(struct iwl_fw_runtime *fwrt)
|
||||
}
|
||||
}
|
||||
|
||||
fwrt->ppag_bios_source = BIOS_SOURCE_ACPI;
|
||||
ret = 0;
|
||||
|
||||
out_free:
|
||||
@ -919,40 +920,39 @@ int iwl_acpi_get_ppag_table(struct iwl_fw_runtime *fwrt)
|
||||
return ret;
|
||||
}
|
||||
|
||||
void iwl_acpi_get_phy_filters(struct iwl_fw_runtime *fwrt,
|
||||
struct iwl_phy_specific_cfg *filters)
|
||||
int iwl_acpi_get_phy_filters(struct iwl_fw_runtime *fwrt)
|
||||
{
|
||||
struct iwl_phy_specific_cfg *filters = &fwrt->phy_filters;
|
||||
struct iwl_phy_specific_cfg tmp = {};
|
||||
union acpi_object *wifi_pkg, *data;
|
||||
union acpi_object *wifi_pkg, *data __free(kfree);
|
||||
int tbl_rev, i;
|
||||
|
||||
data = iwl_acpi_get_object(fwrt->dev, ACPI_WPFC_METHOD);
|
||||
if (IS_ERR(data))
|
||||
return;
|
||||
return PTR_ERR(data);
|
||||
|
||||
wifi_pkg = iwl_acpi_get_wifi_pkg(fwrt->dev, data,
|
||||
ACPI_WPFC_WIFI_DATA_SIZE,
|
||||
&tbl_rev);
|
||||
if (IS_ERR(wifi_pkg))
|
||||
goto out_free;
|
||||
return PTR_ERR(wifi_pkg);
|
||||
|
||||
if (tbl_rev != 0)
|
||||
goto out_free;
|
||||
return -EINVAL;
|
||||
|
||||
BUILD_BUG_ON(ARRAY_SIZE(filters->filter_cfg_chains) !=
|
||||
ACPI_WPFC_WIFI_DATA_SIZE - 1);
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(filters->filter_cfg_chains); i++) {
|
||||
if (wifi_pkg->package.elements[i + 1].type != ACPI_TYPE_INTEGER)
|
||||
goto out_free;
|
||||
return -EINVAL;
|
||||
tmp.filter_cfg_chains[i] =
|
||||
cpu_to_le32(wifi_pkg->package.elements[i + 1].integer.value);
|
||||
}
|
||||
|
||||
IWL_DEBUG_RADIO(fwrt, "Loaded WPFC filter config from ACPI\n");
|
||||
*filters = tmp;
|
||||
out_free:
|
||||
kfree(data);
|
||||
return 0;
|
||||
}
|
||||
IWL_EXPORT_SYMBOL(iwl_acpi_get_phy_filters);
|
||||
|
||||
|
||||
@ -1,7 +1,7 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause */
|
||||
/*
|
||||
* Copyright (C) 2017 Intel Deutschland GmbH
|
||||
* Copyright (C) 2018-2023 Intel Corporation
|
||||
* Copyright (C) 2018-2023, 2025 Intel Corporation
|
||||
*/
|
||||
#ifndef __iwl_fw_acpi__
|
||||
#define __iwl_fw_acpi__
|
||||
@ -180,8 +180,7 @@ int iwl_acpi_get_tas_table(struct iwl_fw_runtime *fwrt,
|
||||
|
||||
int iwl_acpi_get_ppag_table(struct iwl_fw_runtime *fwrt);
|
||||
|
||||
void iwl_acpi_get_phy_filters(struct iwl_fw_runtime *fwrt,
|
||||
struct iwl_phy_specific_cfg *filters);
|
||||
int iwl_acpi_get_phy_filters(struct iwl_fw_runtime *fwrt);
|
||||
|
||||
void iwl_acpi_get_guid_lock_status(struct iwl_fw_runtime *fwrt);
|
||||
|
||||
@ -244,8 +243,10 @@ static inline int iwl_acpi_get_ppag_table(struct iwl_fw_runtime *fwrt)
|
||||
return -ENOENT;
|
||||
}
|
||||
|
||||
/* macro since the second argument doesn't always exist */
|
||||
#define iwl_acpi_get_phy_filters(fwrt, filters) do { } while (0)
|
||||
static inline int iwl_acpi_get_phy_filters(struct iwl_fw_runtime *fwrt)
|
||||
{
|
||||
return -ENOENT;
|
||||
}
|
||||
|
||||
static inline void iwl_acpi_get_guid_lock_status(struct iwl_fw_runtime *fwrt)
|
||||
{
|
||||
|
||||
@ -112,6 +112,16 @@ struct iwl_alive_ntf_v6 {
|
||||
struct iwl_imr_alive_info imr;
|
||||
} __packed; /* UCODE_ALIVE_NTFY_API_S_VER_6 */
|
||||
|
||||
struct iwl_alive_ntf {
|
||||
__le16 status;
|
||||
__le16 flags;
|
||||
struct iwl_lmac_alive lmac_data[2];
|
||||
struct iwl_umac_alive umac_data;
|
||||
struct iwl_sku_id sku_id;
|
||||
struct iwl_imr_alive_info imr;
|
||||
__le64 platform_id;
|
||||
} __packed; /* UCODE_ALIVE_NTFY_API_S_VER_8 */
|
||||
|
||||
/**
|
||||
* enum iwl_extended_cfg_flags - commands driver may send before
|
||||
* finishing init flow
|
||||
|
||||
@ -2,7 +2,7 @@
|
||||
/*
|
||||
* Copyright (C) 2013-2015 Intel Mobile Communications GmbH
|
||||
* Copyright (C) 2016-2017 Intel Deutschland GmbH
|
||||
* Copyright (C) 2018-2022, 2024 Intel Corporation
|
||||
* Copyright (C) 2018-2022, 2024-2025 Intel Corporation
|
||||
*/
|
||||
#ifndef __iwl_fw_api_commands_h__
|
||||
#define __iwl_fw_api_commands_h__
|
||||
@ -145,8 +145,8 @@ enum iwl_legacy_cmds {
|
||||
REMOVE_STA = 0x19,
|
||||
|
||||
/**
|
||||
* @TX_CMD: uses &struct iwl_tx_cmd or &struct iwl_tx_cmd_gen2 or
|
||||
* &struct iwl_tx_cmd_gen3,
|
||||
* @TX_CMD: uses &struct iwl_tx_cmd_v6 or &struct iwl_tx_cmd_v9 or
|
||||
* &struct iwl_tx_cmd,
|
||||
* response in &struct iwl_tx_resp or
|
||||
* &struct iwl_tx_resp_v3
|
||||
*/
|
||||
|
||||
@ -98,7 +98,7 @@ enum iwl_data_path_subcmd_ids {
|
||||
|
||||
/**
|
||||
* @ESR_MODE_NOTIF: notification to recommend/force a wanted esr mode,
|
||||
* uses &struct iwl_esr_mode_notif
|
||||
* uses &struct iwl_esr_mode_notif or &struct iwl_esr_mode_notif_v1
|
||||
*/
|
||||
ESR_MODE_NOTIF = 0xF3,
|
||||
|
||||
|
||||
@ -6,6 +6,11 @@
|
||||
*/
|
||||
#ifndef __iwl_fw_api_location_h__
|
||||
#define __iwl_fw_api_location_h__
|
||||
#include <linux/ieee80211.h>
|
||||
#include <linux/if_ether.h>
|
||||
#include <linux/types.h>
|
||||
#include <linux/bits.h>
|
||||
#include "rs.h"
|
||||
|
||||
/**
|
||||
* enum iwl_location_subcmd_ids - location group command IDs
|
||||
@ -1609,7 +1614,7 @@ struct iwl_tof_range_rsp_ap_entry_ntfy_v5 {
|
||||
} __packed; /* LOCATION_RANGE_RSP_AP_ETRY_NTFY_API_S_VER_5 */
|
||||
|
||||
/**
|
||||
* struct iwl_tof_range_rsp_ap_entry_ntfy - AP parameters (response)
|
||||
* struct iwl_tof_range_rsp_ap_entry_ntfy_v7 - AP parameters (response)
|
||||
* @bssid: BSSID of the AP
|
||||
* @measure_status: current APs measurement status, one of
|
||||
* &enum iwl_tof_entry_status.
|
||||
@ -1645,7 +1650,7 @@ struct iwl_tof_range_rsp_ap_entry_ntfy_v5 {
|
||||
* @tx_pn: the last PN used for this responder Tx in case PMF is configured in
|
||||
* LE byte order.
|
||||
*/
|
||||
struct iwl_tof_range_rsp_ap_entry_ntfy {
|
||||
struct iwl_tof_range_rsp_ap_entry_ntfy_v7 {
|
||||
u8 bssid[ETH_ALEN];
|
||||
u8 measure_status;
|
||||
u8 measure_bw;
|
||||
@ -1672,6 +1677,65 @@ struct iwl_tof_range_rsp_ap_entry_ntfy {
|
||||
} __packed; /* LOCATION_RANGE_RSP_AP_ETRY_NTFY_API_S_VER_6,
|
||||
LOCATION_RANGE_RSP_AP_ETRY_NTFY_API_S_VER_7 */
|
||||
|
||||
/**
|
||||
* struct iwl_tof_range_rsp_ap_entry_ntfy - AP parameters (response)
|
||||
* @bssid: BSSID of the AP
|
||||
* @measure_status: current APs measurement status, one of
|
||||
* &enum iwl_tof_entry_status.
|
||||
* @measure_bw: Current AP Bandwidth: 0 20MHz, 1 40MHz, 2 80MHz
|
||||
* @rtt: The Round Trip Time that took for the last measurement for
|
||||
* current AP [pSec]
|
||||
* @rtt_variance: The Variance of the RTT values measured for current AP
|
||||
* @rtt_spread: The Difference between the maximum and the minimum RTT
|
||||
* values measured for current AP in the current session [pSec]
|
||||
* @rssi: RSSI as uploaded in the Channel Estimation notification
|
||||
* @rssi_spread: The Difference between the maximum and the minimum RSSI values
|
||||
* measured for current AP in the current session
|
||||
* @last_burst: 1 if no more FTM sessions are scheduled for this responder
|
||||
* @refusal_period: refusal period in case of
|
||||
* @IWL_TOF_ENTRY_RESPONDER_CANNOT_COLABORATE [sec]
|
||||
* @timestamp: The GP2 Clock [usec] where Channel Estimation notification was
|
||||
* uploaded by the LMAC
|
||||
* @start_tsf: measurement start time in TSF of the mac specified in the range
|
||||
* request
|
||||
* @reserved1: reserved, for backwards compatibility
|
||||
* @t2t3_initiator: as calculated from the algo in the initiator
|
||||
* @t1t4_responder: as calculated from the algo in the responder
|
||||
* @common_calib: Calib val that was used in for this AP measurement
|
||||
* @specific_calib: val that was used in for this AP measurement
|
||||
* @papd_calib_output: The result of the tof papd calibration that was injected
|
||||
* into the algorithm.
|
||||
* @rttConfidence: a value between 0 - 31 that represents the rtt accuracy.
|
||||
* @reserved: for alignment
|
||||
* @rx_pn: the last PN used for this responder Rx in case PMF is configured in
|
||||
* LE byte order.
|
||||
* @tx_pn: the last PN used for this responder Tx in case PMF is configured in
|
||||
* LE byte order.
|
||||
*/
|
||||
struct iwl_tof_range_rsp_ap_entry_ntfy {
|
||||
u8 bssid[ETH_ALEN];
|
||||
u8 measure_status;
|
||||
u8 measure_bw;
|
||||
__le32 rtt;
|
||||
__le32 rtt_variance;
|
||||
__le32 rtt_spread;
|
||||
s8 rssi;
|
||||
u8 rssi_spread;
|
||||
u8 last_burst;
|
||||
u8 refusal_period;
|
||||
__le32 timestamp;
|
||||
__le32 start_tsf;
|
||||
__le32 reserved1[2];
|
||||
__le32 t2t3_initiator;
|
||||
__le32 t1t4_responder;
|
||||
__le16 common_calib;
|
||||
__le16 specific_calib;
|
||||
__le32 papd_calib_output;
|
||||
u8 rttConfidence;
|
||||
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_8 */
|
||||
|
||||
/**
|
||||
* enum iwl_tof_response_status - tof response status
|
||||
@ -1738,6 +1802,24 @@ struct iwl_tof_range_rsp_ntfy_v7 {
|
||||
struct iwl_tof_range_rsp_ap_entry_ntfy_v5 ap[IWL_TOF_MAX_APS];
|
||||
} __packed; /* LOCATION_RANGE_RSP_NTFY_API_S_VER_7 */
|
||||
|
||||
/**
|
||||
* struct iwl_tof_range_rsp_ntfy_v9 - ranging response notification
|
||||
* @request_id: A Token ID of the corresponding Range request
|
||||
* @num_of_aps: Number of APs results
|
||||
* @last_report: 1 if no more FTM sessions are scheduled, 0 otherwise.
|
||||
* @reserved: reserved
|
||||
* @ap: per-AP data
|
||||
*/
|
||||
struct iwl_tof_range_rsp_ntfy_v9 {
|
||||
u8 request_id;
|
||||
u8 num_of_aps;
|
||||
u8 last_report;
|
||||
u8 reserved;
|
||||
struct iwl_tof_range_rsp_ap_entry_ntfy_v7 ap[IWL_TOF_MAX_APS];
|
||||
} __packed; /* LOCATION_RANGE_RSP_NTFY_API_S_VER_8,
|
||||
* LOCATION_RANGE_RSP_NTFY_API_S_VER_9
|
||||
*/
|
||||
|
||||
/**
|
||||
* struct iwl_tof_range_rsp_ntfy - ranging response notification
|
||||
* @request_id: A Token ID of the corresponding Range request
|
||||
@ -1752,8 +1834,7 @@ struct iwl_tof_range_rsp_ntfy {
|
||||
u8 last_report;
|
||||
u8 reserved;
|
||||
struct iwl_tof_range_rsp_ap_entry_ntfy ap[IWL_TOF_MAX_APS];
|
||||
} __packed; /* LOCATION_RANGE_RSP_NTFY_API_S_VER_8,
|
||||
LOCATION_RANGE_RSP_NTFY_API_S_VER_9 */
|
||||
} __packed; /* LOCATION_RANGE_RSP_NTFY_API_S_VER_10 */
|
||||
|
||||
#define IWL_MVM_TOF_MCSI_BUF_SIZE (245)
|
||||
/**
|
||||
|
||||
@ -310,9 +310,42 @@ enum iwl_mac_config_filter_flags {
|
||||
MAC_CFG_FILTER_ACCEPT_PROBE_REQ = BIT(5),
|
||||
}; /* MAC_FILTER_FLAGS_MASK_E_VER_1 */
|
||||
|
||||
/**
|
||||
* struct iwl_mac_wifi_gen_support_v2 - parameters of iwl_mac_config_cmd
|
||||
* with support up to eht as in version 2 of the command
|
||||
*
|
||||
* @he_support: does this MAC support HE
|
||||
* @he_ap_support: HE AP enabled, "pseudo HE", no trigger frame handling
|
||||
* @eht_support: does this MAC support EHT. Requires he_support
|
||||
*/
|
||||
struct iwl_mac_wifi_gen_support_v2 {
|
||||
__le16 he_support;
|
||||
__le16 he_ap_support;
|
||||
__le32 eht_support;
|
||||
} __packed;
|
||||
|
||||
/**
|
||||
* struct iwl_mac_wifi_gen_support - parameters of iwl_mac_config_cmd
|
||||
* with support up to uhr as in version 3 of the command
|
||||
* ( MAC_CONTEXT_CONFIG_CMD = 0x8 )
|
||||
*
|
||||
* @he_support: does this MAC support HE
|
||||
* @he_ap_support: HE AP enabled, "pseudo HE", no trigger frame handling
|
||||
* @eht_support: does this MAC support EHT. Requires he_support
|
||||
* @uhr_support: does this MAC support UHR. Requires eht_support
|
||||
* @reserved: reserved for alignment and to match version 2's size
|
||||
*/
|
||||
struct iwl_mac_wifi_gen_support {
|
||||
u8 he_support;
|
||||
u8 he_ap_support;
|
||||
u8 eht_support;
|
||||
u8 uhr_support;
|
||||
__le32 reserved;
|
||||
} __packed;
|
||||
|
||||
/**
|
||||
* struct iwl_mac_config_cmd - command structure to configure MAC contexts in
|
||||
* MLD API
|
||||
* MLD API for versions 2 and 3
|
||||
* ( MAC_CONTEXT_CONFIG_CMD = 0x8 )
|
||||
*
|
||||
* @id_and_color: ID and color of the MAC
|
||||
@ -321,9 +354,8 @@ enum iwl_mac_config_filter_flags {
|
||||
* @local_mld_addr: mld address
|
||||
* @reserved_for_local_mld_addr: reserved
|
||||
* @filter_flags: combination of &enum iwl_mac_config_filter_flags
|
||||
* @he_support: does this MAC support HE
|
||||
* @he_ap_support: HE AP enabled, "pseudo HE", no trigger frame handling
|
||||
* @eht_support: does this MAC support EHT. Requires he_support
|
||||
* @wifi_gen_v2: he/eht parameters as in cmd version 2
|
||||
* @wifi_gen: he/eht/uhr parameters as in cmd version 3
|
||||
* @nic_not_ack_enabled: mark that the NIC doesn't support receiving
|
||||
* ACK-enabled AGG, (i.e. both BACK and non-BACK frames in single AGG).
|
||||
* If the NIC is not ACK_ENABLED it may use the EOF-bit in first non-0
|
||||
@ -332,7 +364,6 @@ enum iwl_mac_config_filter_flags {
|
||||
* @p2p_dev: mac data for p2p device
|
||||
*/
|
||||
struct iwl_mac_config_cmd {
|
||||
/* COMMON_INDEX_HDR_API_S_VER_1 */
|
||||
__le32 id_and_color;
|
||||
__le32 action;
|
||||
/* MAC_CONTEXT_TYPE_API_E */
|
||||
@ -340,16 +371,17 @@ struct iwl_mac_config_cmd {
|
||||
u8 local_mld_addr[6];
|
||||
__le16 reserved_for_local_mld_addr;
|
||||
__le32 filter_flags;
|
||||
__le16 he_support;
|
||||
__le16 he_ap_support;
|
||||
__le32 eht_support;
|
||||
union {
|
||||
struct iwl_mac_wifi_gen_support_v2 wifi_gen_v2;
|
||||
struct iwl_mac_wifi_gen_support wifi_gen;
|
||||
};
|
||||
__le32 nic_not_ack_enabled;
|
||||
/* MAC_CONTEXT_CONFIG_SPECIFIC_DATA_API_U_VER_2 */
|
||||
union {
|
||||
struct iwl_mac_client_data client;
|
||||
struct iwl_mac_p2p_dev_data p2p_dev;
|
||||
};
|
||||
} __packed; /* MAC_CONTEXT_CONFIG_CMD_API_S_VER_2 */
|
||||
} __packed; /* MAC_CONTEXT_CONFIG_CMD_API_S_VER_2_VER_3 */
|
||||
|
||||
/**
|
||||
* enum iwl_link_ctx_modify_flags - indicate to the fw what fields are being
|
||||
@ -456,6 +488,24 @@ enum iwl_link_modify_bandwidth {
|
||||
IWL_LINK_MODIFY_BW_320,
|
||||
};
|
||||
|
||||
/**
|
||||
* struct iwl_npca_params - NPCA parameters (non-primary channel access)
|
||||
*
|
||||
* @switch_delay: after switch, delay TX according to destination AP
|
||||
* @switch_back_delay: switch back to control channel before OBSS frame end
|
||||
* @min_dur_threshold: minimum PPDU time to switch to the non-primary
|
||||
* NPCA channel
|
||||
* @flags: NPCA flags - bit 0: puncturing allowed, bit 1: new TX allowed
|
||||
* @reserved: reserved for alignment purposes
|
||||
*/
|
||||
struct iwl_npca_params {
|
||||
u8 switch_delay;
|
||||
u8 switch_back_delay;
|
||||
__le16 min_dur_threshold;
|
||||
__le16 flags;
|
||||
__le16 reserved;
|
||||
} __packed; /* NPCA_PARAM_API_S_VER_1 */
|
||||
|
||||
/**
|
||||
* struct iwl_link_config_cmd - command structure to configure the LINK context
|
||||
* in MLD API
|
||||
@ -513,6 +563,8 @@ enum iwl_link_modify_bandwidth {
|
||||
* IEEE802.11REVme-D5.0
|
||||
* @ibss_bssid_addr: bssid for ibss
|
||||
* @reserved_for_ibss_bssid_addr: reserved
|
||||
* @npca_params: NPCA parameters
|
||||
* @prio_edca_params: priority EDCA parameters for enhanced QoS
|
||||
* @reserved3: reserved for future use
|
||||
*/
|
||||
struct iwl_link_config_cmd {
|
||||
@ -560,8 +612,10 @@ struct iwl_link_config_cmd {
|
||||
u8 ul_mu_data_disable;
|
||||
u8 ibss_bssid_addr[6];
|
||||
__le16 reserved_for_ibss_bssid_addr;
|
||||
__le32 reserved3[8];
|
||||
} __packed; /* LINK_CONTEXT_CONFIG_CMD_API_S_VER_1, _VER_2, _VER_3, _VER_4, _VER_5, _VER_6 */
|
||||
struct iwl_npca_params npca_params; /* since _VER_7 */
|
||||
struct iwl_ac_qos prio_edca_params; /* since _VER_7 */
|
||||
__le32 reserved3[4];
|
||||
} __packed; /* LINK_CONTEXT_CONFIG_CMD_API_S_VER_1, _VER_2, _VER_3, _VER_4, _VER_5, _VER_6, _VER_7 */
|
||||
|
||||
/* Currently FW supports link ids in the range 0-3 and can have
|
||||
* at most two active links for each vif.
|
||||
@ -588,6 +642,62 @@ enum iwl_fw_sta_type {
|
||||
STATION_TYPE_AUX,
|
||||
}; /* STATION_TYPE_E_VER_1 */
|
||||
|
||||
/**
|
||||
* struct iwl_sta_cfg_cmd_v1 - cmd structure to add a peer sta to the uCode's
|
||||
* station table
|
||||
* ( STA_CONFIG_CMD = 0xA )
|
||||
*
|
||||
* @sta_id: index of station in uCode's station table
|
||||
* @link_id: the id of the link that is used to communicate with this sta
|
||||
* @peer_mld_address: the peers mld address
|
||||
* @reserved_for_peer_mld_address: reserved
|
||||
* @peer_link_address: the address of the link that is used to communicate
|
||||
* with this sta
|
||||
* @reserved_for_peer_link_address: reserved
|
||||
* @station_type: type of this station. See &enum iwl_fw_sta_type
|
||||
* @assoc_id: for GO only
|
||||
* @beamform_flags: beam forming controls
|
||||
* @mfp: indicates whether the STA uses management frame protection or not.
|
||||
* @mimo: indicates whether the sta uses mimo or not
|
||||
* @mimo_protection: indicates whether the sta uses mimo protection or not
|
||||
* @ack_enabled: indicates that the AP supports receiving ACK-
|
||||
* enabled AGG, i.e. both BACK and non-BACK frames in a single AGG
|
||||
* @trig_rnd_alloc: indicates that trigger based random allocation
|
||||
* is enabled according to UORA element existence
|
||||
* @tx_ampdu_spacing: minimum A-MPDU spacing:
|
||||
* 4 - 2us density, 5 - 4us density, 6 - 8us density, 7 - 16us density
|
||||
* @tx_ampdu_max_size: maximum A-MPDU length: 0 - 8K, 1 - 16K, 2 - 32K,
|
||||
* 3 - 64K, 4 - 128K, 5 - 256K, 6 - 512K, 7 - 1024K.
|
||||
* @sp_length: the size of the SP in actual number of frames
|
||||
* @uapsd_acs: 4 LS bits are trigger enabled ACs, 4 MS bits are the deliver
|
||||
* enabled ACs.
|
||||
* @pkt_ext: optional, exists according to PPE-present bit in the HE/EHT-PHY
|
||||
* capa
|
||||
* @htc_flags: which features are supported in HTC
|
||||
*/
|
||||
struct iwl_sta_cfg_cmd_v1 {
|
||||
__le32 sta_id;
|
||||
__le32 link_id;
|
||||
u8 peer_mld_address[ETH_ALEN];
|
||||
__le16 reserved_for_peer_mld_address;
|
||||
u8 peer_link_address[ETH_ALEN];
|
||||
__le16 reserved_for_peer_link_address;
|
||||
__le32 station_type;
|
||||
__le32 assoc_id;
|
||||
__le32 beamform_flags;
|
||||
__le32 mfp;
|
||||
__le32 mimo;
|
||||
__le32 mimo_protection;
|
||||
__le32 ack_enabled;
|
||||
__le32 trig_rnd_alloc;
|
||||
__le32 tx_ampdu_spacing;
|
||||
__le32 tx_ampdu_max_size;
|
||||
__le32 sp_length;
|
||||
__le32 uapsd_acs;
|
||||
struct iwl_he_pkt_ext_v2 pkt_ext;
|
||||
__le32 htc_flags;
|
||||
} __packed; /* STA_CMD_API_S_VER_1 */
|
||||
|
||||
/**
|
||||
* struct iwl_sta_cfg_cmd - cmd structure to add a peer sta to the uCode's
|
||||
* station table
|
||||
@ -620,6 +730,14 @@ enum iwl_fw_sta_type {
|
||||
* @pkt_ext: optional, exists according to PPE-present bit in the HE/EHT-PHY
|
||||
* capa
|
||||
* @htc_flags: which features are supported in HTC
|
||||
* @use_ldpc_x2_cw: Indicates whether to use LDPC with double CW
|
||||
* @use_icf: Indicates whether to use ICF instead of RTS
|
||||
* @dps_pad_time: DPS (Dynamic Power Save) padding delay resolution to ensure
|
||||
* proper timing alignment
|
||||
* @dps_trans_delay: DPS minimal time that takes the peer to return to low power
|
||||
* @mic_prep_pad_delay: MIC prep time padding
|
||||
* @mic_compute_pad_delay: MIC compute time padding
|
||||
* @reserved: Reserved for alignment
|
||||
*/
|
||||
struct iwl_sta_cfg_cmd {
|
||||
__le32 sta_id;
|
||||
@ -642,7 +760,14 @@ struct iwl_sta_cfg_cmd {
|
||||
__le32 uapsd_acs;
|
||||
struct iwl_he_pkt_ext_v2 pkt_ext;
|
||||
__le32 htc_flags;
|
||||
} __packed; /* STA_CMD_API_S_VER_1 */
|
||||
u8 use_ldpc_x2_cw;
|
||||
u8 use_icf;
|
||||
u8 dps_pad_time;
|
||||
u8 dps_trans_delay;
|
||||
u8 mic_prep_pad_delay;
|
||||
u8 mic_compute_pad_delay;
|
||||
u8 reserved[2];
|
||||
} __packed; /* STA_CMD_API_S_VER_2 */
|
||||
|
||||
/**
|
||||
* struct iwl_aux_sta_cmd - command for AUX STA configuration
|
||||
@ -686,9 +811,9 @@ struct iwl_mvm_sta_disable_tx_cmd {
|
||||
|
||||
/**
|
||||
* enum iwl_mvm_fw_esr_recommendation - FW recommendation code
|
||||
* @ESR_RECOMMEND_LEAVE: recommendation to leave esr
|
||||
* @ESR_FORCE_LEAVE: force exiting esr
|
||||
* @ESR_RECOMMEND_ENTER: recommendation to enter esr
|
||||
* @ESR_RECOMMEND_LEAVE: recommendation to leave EMLSR
|
||||
* @ESR_FORCE_LEAVE: force exiting EMLSR
|
||||
* @ESR_RECOMMEND_ENTER: recommendation to enter EMLSR
|
||||
*/
|
||||
enum iwl_mvm_fw_esr_recommendation {
|
||||
ESR_RECOMMEND_LEAVE,
|
||||
@ -697,13 +822,44 @@ enum iwl_mvm_fw_esr_recommendation {
|
||||
}; /* ESR_MODE_RECOMMENDATION_CODE_API_E_VER_1 */
|
||||
|
||||
/**
|
||||
* struct iwl_esr_mode_notif - FWs recommendation/force for esr mode
|
||||
* struct iwl_esr_mode_notif_v1 - FW recommendation/force for EMLSR mode
|
||||
*
|
||||
* @action: the action to apply on esr state. See &iwl_mvm_fw_esr_recommendation
|
||||
* @action: the action to apply on EMLSR state.
|
||||
* See &iwl_mvm_fw_esr_recommendation
|
||||
*/
|
||||
struct iwl_esr_mode_notif_v1 {
|
||||
__le32 action;
|
||||
} __packed; /* ESR_MODE_RECOMMENDATION_NTFY_API_S_VER_1 */
|
||||
|
||||
/**
|
||||
* enum iwl_esr_leave_reason - reasons for leaving EMLSR mode
|
||||
*
|
||||
* @ESR_LEAVE_REASON_OMI_MU_UL_DISALLOWED: OMI MU UL disallowed
|
||||
* @ESR_LEAVE_REASON_NO_TRIG_FOR_ESR_STA: No trigger for EMLSR station
|
||||
* @ESR_LEAVE_REASON_NO_ESR_STA_IN_MU_DL: No EMLSR station in MU DL
|
||||
* @ESR_LEAVE_REASON_BAD_ACTIV_FRAME_TH: Bad activation frame threshold
|
||||
* @ESR_LEAVE_REASON_RTS_IN_DUAL_LISTEN: RTS in dual listen
|
||||
*/
|
||||
enum iwl_esr_leave_reason {
|
||||
ESR_LEAVE_REASON_OMI_MU_UL_DISALLOWED = BIT(0),
|
||||
ESR_LEAVE_REASON_NO_TRIG_FOR_ESR_STA = BIT(1),
|
||||
ESR_LEAVE_REASON_NO_ESR_STA_IN_MU_DL = BIT(2),
|
||||
ESR_LEAVE_REASON_BAD_ACTIV_FRAME_TH = BIT(3),
|
||||
ESR_LEAVE_REASON_RTS_IN_DUAL_LISTEN = BIT(4),
|
||||
};
|
||||
|
||||
/**
|
||||
* struct iwl_esr_mode_notif - FW recommendation/force for EMLSR mode
|
||||
*
|
||||
* @action: the action to apply on EMLSR state.
|
||||
* See &iwl_mvm_fw_esr_recommendation
|
||||
* @leave_reason_mask: mask for various reasons to leave EMLSR mode.
|
||||
* See &iwl_esr_leave_reason
|
||||
*/
|
||||
struct iwl_esr_mode_notif {
|
||||
__le32 action;
|
||||
} __packed; /* ESR_MODE_RECOMMENDATION_NTFY_API_S_VER_1 */
|
||||
__le32 leave_reason_mask;
|
||||
} __packed; /* ESR_MODE_RECOMMENDATION_NTFY_API_S_VER_2 */
|
||||
|
||||
/**
|
||||
* struct iwl_missed_beacons_notif - sent when by the firmware upon beacon loss
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause */
|
||||
/*
|
||||
* Copyright (C) 2012-2014, 2018-2022, 2024 Intel Corporation
|
||||
* Copyright (C) 2012-2014, 2018-2022, 2024-2025 Intel Corporation
|
||||
* Copyright (C) 2017 Intel Deutschland GmbH
|
||||
*/
|
||||
#ifndef __iwl_fw_api_mac_h__
|
||||
@ -287,9 +287,9 @@ struct iwl_ac_qos {
|
||||
__le16 cw_min;
|
||||
__le16 cw_max;
|
||||
u8 aifsn;
|
||||
u8 fifos_mask;
|
||||
u8 fifos_mask; /* not in use since _VER_3 */
|
||||
__le16 edca_txop;
|
||||
} __packed; /* AC_QOS_API_S_VER_2 */
|
||||
} __packed; /* AC_QOS_API_S_VER_2, _VER_3 */
|
||||
|
||||
/**
|
||||
* struct iwl_mac_ctx_cmd - command structure to configure MAC contexts
|
||||
|
||||
@ -7,6 +7,8 @@
|
||||
#ifndef __iwl_fw_api_power_h__
|
||||
#define __iwl_fw_api_power_h__
|
||||
|
||||
#include "nvm-reg.h"
|
||||
|
||||
/* Power Management Commands, Responses, Notifications */
|
||||
|
||||
/**
|
||||
@ -629,28 +631,37 @@ enum iwl_ppag_flags {
|
||||
|
||||
/**
|
||||
* union iwl_ppag_table_cmd - union for all versions of PPAG command
|
||||
* @v1: version 1
|
||||
* @v2: version 2
|
||||
* version 3, 4, 5 and 6 are the same structure as v2,
|
||||
* @v1: command version 1 structure.
|
||||
* @v2: command version from 2 to 6 are same structure as v2.
|
||||
* but has a different format of the flags bitmap
|
||||
* @v3: command version 7 structure.
|
||||
* @v1.flags: values from &enum iwl_ppag_flags
|
||||
* @v1.gain: table of antenna gain values per chain and sub-band
|
||||
* @v1.reserved: reserved
|
||||
* @v2.flags: values from &enum iwl_ppag_flags
|
||||
* @v2.gain: table of antenna gain values per chain and sub-band
|
||||
* @v2.reserved: reserved
|
||||
* @v3.ppag_config_info: see @struct bios_value_u32
|
||||
* @v3.gain: table of antenna gain values per chain and sub-band
|
||||
* @v3.reserved: reserved
|
||||
*/
|
||||
union iwl_ppag_table_cmd {
|
||||
struct {
|
||||
__le32 flags;
|
||||
s8 gain[IWL_NUM_CHAIN_LIMITS][IWL_NUM_SUB_BANDS_V1];
|
||||
s8 reserved[2];
|
||||
} v1;
|
||||
} __packed v1; /* PER_PLAT_ANTENNA_GAIN_CMD_API_S_VER_1 */
|
||||
struct {
|
||||
__le32 flags;
|
||||
s8 gain[IWL_NUM_CHAIN_LIMITS][IWL_NUM_SUB_BANDS_V2];
|
||||
s8 reserved[2];
|
||||
} v2;
|
||||
} __packed v2; /* PER_PLAT_ANTENNA_GAIN_CMD_API_S_VER_2, VER3, VER4,
|
||||
* VER5, VER6
|
||||
*/
|
||||
struct {
|
||||
struct bios_value_u32 ppag_config_info;
|
||||
s8 gain[IWL_NUM_CHAIN_LIMITS][IWL_NUM_SUB_BANDS_V2];
|
||||
s8 reserved[2];
|
||||
} __packed v3; /* PER_PLAT_ANTENNA_GAIN_CMD_API_S_VER_7 */
|
||||
} __packed;
|
||||
|
||||
#define IWL_PPAG_CMD_V4_MASK (IWL_PPAG_ETSI_MASK | IWL_PPAG_CHINA_MASK)
|
||||
@ -658,6 +669,15 @@ union iwl_ppag_table_cmd {
|
||||
IWL_PPAG_ETSI_LPI_UHB_MASK | \
|
||||
IWL_PPAG_USA_LPI_UHB_MASK)
|
||||
|
||||
#define IWL_PPAG_CMD_V6_MASK (IWL_PPAG_CMD_V5_MASK | \
|
||||
IWL_PPAG_ETSI_VLP_UHB_MASK | \
|
||||
IWL_PPAG_ETSI_SP_UHB_MASK | \
|
||||
IWL_PPAG_USA_VLP_UHB_MASK | \
|
||||
IWL_PPAG_USA_SP_UHB_MASK | \
|
||||
IWL_PPAG_CANADA_LPI_UHB_MASK | \
|
||||
IWL_PPAG_CANADA_VLP_UHB_MASK | \
|
||||
IWL_PPAG_CANADA_SP_UHB_MASK)
|
||||
|
||||
#define MCC_TO_SAR_OFFSET_TABLE_ROW_SIZE 26
|
||||
#define MCC_TO_SAR_OFFSET_TABLE_COL_SIZE 13
|
||||
|
||||
|
||||
@ -1,11 +1,13 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause */
|
||||
/*
|
||||
* Copyright (C) 2012-2014, 2018-2022, 2024 Intel Corporation
|
||||
* Copyright (C) 2012-2014, 2018-2022, 2024-2025 Intel Corporation
|
||||
* Copyright (C) 2017 Intel Deutschland GmbH
|
||||
*/
|
||||
#ifndef __iwl_fw_api_rs_h__
|
||||
#define __iwl_fw_api_rs_h__
|
||||
|
||||
#include <linux/bitfield.h>
|
||||
#include <linux/types.h>
|
||||
#include <linux/bits.h>
|
||||
#include "mac.h"
|
||||
|
||||
/**
|
||||
@ -213,7 +215,8 @@ enum iwl_tlc_update_flags {
|
||||
* @sta_id: station id
|
||||
* @reserved: reserved
|
||||
* @flags: bitmap of notifications reported
|
||||
* @rate: current initial rate
|
||||
* @rate: current initial rate, format depends on the notification
|
||||
* version
|
||||
* @amsdu_size: Max AMSDU size, in bytes
|
||||
* @amsdu_enabled: bitmap for per-TID AMSDU enablement
|
||||
*/
|
||||
@ -224,7 +227,7 @@ struct iwl_tlc_update_notif {
|
||||
__le32 rate;
|
||||
__le32 amsdu_size;
|
||||
__le32 amsdu_enabled;
|
||||
} __packed; /* TLC_MNG_UPDATE_NTFY_API_S_VER_2 */
|
||||
} __packed; /* TLC_MNG_UPDATE_NTFY_API_S_VER_2, _VER_3, _VER_4 */
|
||||
|
||||
/**
|
||||
* enum iwl_tlc_debug_types - debug options
|
||||
@ -427,6 +430,7 @@ enum {
|
||||
|
||||
/* Bit 4-5: (0) SISO, (1) MIMO2 (2) MIMO3 */
|
||||
#define RATE_VHT_MCS_RATE_CODE_MSK 0xf
|
||||
#define RATE_VHT_MCS_NSS_MSK 0x30
|
||||
|
||||
/*
|
||||
* Legacy OFDM rate format for bits 7:0
|
||||
@ -541,7 +545,7 @@ 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
|
||||
/* rate_n_flags bit field version 2 and 3
|
||||
*
|
||||
* 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
|
||||
@ -553,23 +557,25 @@ enum {
|
||||
* (0) Legacy CCK (1) Legacy OFDM (2) High-throughput (HT)
|
||||
* (3) Very High-throughput (VHT) (4) High-efficiency (HE)
|
||||
* (5) Extremely High-throughput (EHT)
|
||||
* (6) Ultra High Reliability (UHR) (v3 rate format only)
|
||||
*/
|
||||
#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)
|
||||
#define RATE_MCS_MOD_TYPE_CCK (0 << RATE_MCS_MOD_TYPE_POS)
|
||||
#define RATE_MCS_MOD_TYPE_LEGACY_OFDM (1 << RATE_MCS_MOD_TYPE_POS)
|
||||
#define RATE_MCS_MOD_TYPE_HT (2 << RATE_MCS_MOD_TYPE_POS)
|
||||
#define RATE_MCS_MOD_TYPE_VHT (3 << RATE_MCS_MOD_TYPE_POS)
|
||||
#define RATE_MCS_MOD_TYPE_HE (4 << RATE_MCS_MOD_TYPE_POS)
|
||||
#define RATE_MCS_MOD_TYPE_EHT (5 << RATE_MCS_MOD_TYPE_POS)
|
||||
#define RATE_MCS_MOD_TYPE_UHR (6 << 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
|
||||
* (0) 1 Mbps
|
||||
* (1) 2 Mbps
|
||||
* (2) 5.5 Mbps
|
||||
* (3) 11 Mbps
|
||||
*
|
||||
* Legacy OFDM rate format for bis 3:0:
|
||||
*
|
||||
@ -586,15 +592,19 @@ enum {
|
||||
#define RATE_LEGACY_RATE_MSK 0x7
|
||||
|
||||
/*
|
||||
* HT, VHT, HE, EHT rate format for bits 3:0
|
||||
* 3-0: MCS
|
||||
*
|
||||
* HT, VHT, HE, EHT, UHR rate format
|
||||
* Version 2: (not applicable for UHR)
|
||||
* 3-0: MCS
|
||||
* 4: NSS==2 indicator
|
||||
* Version 3:
|
||||
* 4-0: MCS
|
||||
* 5: NSS==2 indicator
|
||||
*/
|
||||
#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) | \
|
||||
#define RATE_MCS_NSS_MSK_V2 0x10
|
||||
#define RATE_MCS_NSS_MSK 0x20
|
||||
#define RATE_MCS_CODE_MSK 0x1f
|
||||
#define RATE_HT_MCS_INDEX(r) ((((r) & RATE_MCS_NSS_MSK) >> 2) | \
|
||||
((r) & RATE_HT_MCS_CODE_MSK))
|
||||
|
||||
/* Bits 7-5: reserved */
|
||||
@ -810,11 +820,38 @@ struct iwl_lq_cmd {
|
||||
}; /* 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);
|
||||
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);
|
||||
|
||||
static inline u32 iwl_v3_rate_from_v2_v3(__le32 rate, bool fw_v3)
|
||||
{
|
||||
u32 val;
|
||||
|
||||
if (fw_v3)
|
||||
return le32_to_cpu(rate);
|
||||
|
||||
val = le32_to_cpu(rate) & ~RATE_MCS_NSS_MSK_V2;
|
||||
val |= u32_encode_bits(le32_get_bits(rate, RATE_MCS_NSS_MSK_V2),
|
||||
RATE_MCS_NSS_MSK);
|
||||
|
||||
return val;
|
||||
}
|
||||
|
||||
static inline __le32 iwl_v3_rate_to_v2_v3(u32 rate, bool fw_v3)
|
||||
{
|
||||
__le32 val;
|
||||
|
||||
if (fw_v3)
|
||||
return cpu_to_le32(rate);
|
||||
|
||||
val = cpu_to_le32(rate & ~RATE_MCS_NSS_MSK);
|
||||
val |= le32_encode_bits(u32_get_bits(rate, RATE_MCS_NSS_MSK),
|
||||
RATE_MCS_NSS_MSK_V2);
|
||||
|
||||
return val;
|
||||
}
|
||||
|
||||
#endif /* __iwl_fw_api_rs_h__ */
|
||||
|
||||
@ -640,7 +640,9 @@ struct iwl_rx_mpdu_desc_v3 {
|
||||
*/
|
||||
__le32 reserved[1];
|
||||
} __packed; /* RX_MPDU_RES_START_API_S_VER_3,
|
||||
RX_MPDU_RES_START_API_S_VER_5 */
|
||||
* RX_MPDU_RES_START_API_S_VER_5,
|
||||
* RX_MPDU_RES_START_API_S_VER_6
|
||||
*/
|
||||
|
||||
/**
|
||||
* struct iwl_rx_mpdu_desc - RX MPDU descriptor
|
||||
@ -724,8 +726,10 @@ struct iwl_rx_mpdu_desc {
|
||||
struct iwl_rx_mpdu_desc_v3 v3;
|
||||
};
|
||||
} __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 */
|
||||
* RX_MPDU_RES_START_API_S_VER_4,
|
||||
* RX_MPDU_RES_START_API_S_VER_5,
|
||||
* RX_MPDU_RES_START_API_S_VER_6
|
||||
*/
|
||||
|
||||
#define IWL_RX_DESC_SIZE_V1 offsetofend(struct iwl_rx_mpdu_desc, v1)
|
||||
|
||||
@ -821,7 +825,7 @@ struct iwl_rx_no_data {
|
||||
* 15:8 chain-B, measured at FINA time (FINA_ENERGY), 16:23 channel
|
||||
* @on_air_rise_time: GP2 during on air rise
|
||||
* @fr_time: frame time
|
||||
* @rate: rate/mcs of frame
|
||||
* @rate: rate/mcs of frame, format depends on the notification version
|
||||
* @phy_info: &enum iwl_rx_phy_eht_data0 and &enum iwl_rx_phy_info_type
|
||||
* @rx_vec: DW-12:9 raw RX vectors from DSP according to modulation type.
|
||||
* for VHT: OFDM_RX_VECTOR_SIGA1_OUT, OFDM_RX_VECTOR_SIGA2_OUT
|
||||
@ -837,9 +841,7 @@ struct iwl_rx_no_data_ver_3 {
|
||||
__le32 rate;
|
||||
__le32 phy_info[2];
|
||||
__le32 rx_vec[4];
|
||||
} __packed; /* RX_NO_DATA_NTFY_API_S_VER_1,
|
||||
RX_NO_DATA_NTFY_API_S_VER_2
|
||||
RX_NO_DATA_NTFY_API_S_VER_3 */
|
||||
} __packed; /* RX_NO_DATA_NTFY_API_S_VER_3, _VER_4 */
|
||||
|
||||
struct iwl_frame_release {
|
||||
u8 baid;
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause */
|
||||
/*
|
||||
* Copyright (C) 2012-2014, 2018, 2024 Intel Corporation
|
||||
* Copyright (C) 2012-2014, 2018, 2024-2025 Intel Corporation
|
||||
* Copyright (C) 2013-2015 Intel Mobile Communications GmbH
|
||||
* Copyright (C) 2016-2017 Intel Deutschland GmbH
|
||||
*/
|
||||
@ -50,7 +50,7 @@ struct iwl_tdls_channel_switch_timing {
|
||||
*/
|
||||
struct iwl_tdls_channel_switch_frame {
|
||||
__le32 switch_time_offset;
|
||||
struct iwl_tx_cmd tx_cmd;
|
||||
struct iwl_tx_cmd_v6 tx_cmd;
|
||||
u8 data[IWL_TDLS_CH_SW_FRAME_MAX_SIZE];
|
||||
} __packed; /* TDLS_STA_CHANNEL_SWITCH_FRAME_API_S_VER_1 */
|
||||
|
||||
@ -131,7 +131,7 @@ struct iwl_tdls_config_cmd {
|
||||
struct iwl_tdls_sta_info sta_info[IWL_TDLS_STA_COUNT];
|
||||
|
||||
__le32 pti_req_data_offset;
|
||||
struct iwl_tx_cmd pti_req_tx_cmd;
|
||||
struct iwl_tx_cmd_v6 pti_req_tx_cmd;
|
||||
u8 pti_req_template[];
|
||||
} __packed; /* TDLS_CONFIG_CMD_API_S_VER_1 */
|
||||
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause */
|
||||
/*
|
||||
* Copyright (C) 2012-2014, 2018-2024 Intel Corporation
|
||||
* Copyright (C) 2012-2014, 2018-2025 Intel Corporation
|
||||
* Copyright (C) 2016-2017 Intel Deutschland GmbH
|
||||
*/
|
||||
#ifndef __iwl_fw_api_tx_h__
|
||||
@ -151,7 +151,7 @@ enum iwl_tx_cmd_sec_ctrl {
|
||||
#define IWL_LOW_RETRY_LIMIT 7
|
||||
|
||||
/**
|
||||
* enum iwl_tx_offload_assist_flags_pos - set %iwl_tx_cmd offload_assist values
|
||||
* enum iwl_tx_offload_assist_flags_pos - set %iwl_tx_cmd_v6 offload_assist values
|
||||
* @TX_CMD_OFFLD_IP_HDR: offset to start of IP header (in words)
|
||||
* from mac header end. For normal case it is 4 words for SNAP.
|
||||
* note: tx_cmd, mac header and pad are not counted in the offset.
|
||||
@ -181,7 +181,7 @@ enum iwl_tx_offload_assist_flags_pos {
|
||||
|
||||
/* TODO: complete documentation for try_cnt and btkill_cnt */
|
||||
/**
|
||||
* struct iwl_tx_cmd - TX command struct to FW
|
||||
* struct iwl_tx_cmd_v6 - TX command struct to FW
|
||||
* ( TX_CMD = 0x1c )
|
||||
* @len: in bytes of the payload, see below for details
|
||||
* @offload_assist: TX offload configuration
|
||||
@ -221,7 +221,7 @@ enum iwl_tx_offload_assist_flags_pos {
|
||||
* After the struct fields the MAC header is placed, plus any padding,
|
||||
* and then the actial payload.
|
||||
*/
|
||||
struct iwl_tx_cmd {
|
||||
struct iwl_tx_cmd_v6 {
|
||||
__le16 len;
|
||||
__le16 offload_assist;
|
||||
__le32 tx_flags;
|
||||
@ -258,7 +258,7 @@ struct iwl_dram_sec_info {
|
||||
} __packed; /* DRAM_SEC_INFO_API_S_VER_1 */
|
||||
|
||||
/**
|
||||
* struct iwl_tx_cmd_gen2 - TX command struct to FW for 22000 devices
|
||||
* struct iwl_tx_cmd_v9 - TX command struct to FW for 22000 devices
|
||||
* ( TX_CMD = 0x1c )
|
||||
* @len: in bytes of the payload, see below for details
|
||||
* @offload_assist: TX offload configuration
|
||||
@ -268,7 +268,7 @@ struct iwl_dram_sec_info {
|
||||
* cleared. Combination of RATE_MCS_*
|
||||
* @hdr: 802.11 header
|
||||
*/
|
||||
struct iwl_tx_cmd_gen2 {
|
||||
struct iwl_tx_cmd_v9 {
|
||||
__le16 len;
|
||||
__le16 offload_assist;
|
||||
__le32 flags;
|
||||
@ -279,18 +279,18 @@ struct iwl_tx_cmd_gen2 {
|
||||
TX_CMD_API_S_VER_9 */
|
||||
|
||||
/**
|
||||
* struct iwl_tx_cmd_gen3 - TX command struct to FW for AX210+ devices
|
||||
* struct iwl_tx_cmd - TX command struct to FW for AX210+ devices
|
||||
* ( TX_CMD = 0x1c )
|
||||
* @len: in bytes of the payload, see below for details
|
||||
* @flags: combination of &enum iwl_tx_cmd_flags
|
||||
* @offload_assist: TX offload configuration
|
||||
* @dram_info: FW internal DRAM storage
|
||||
* @rate_n_flags: rate for *all* Tx attempts, if TX_CMD_FLG_STA_RATE_MSK is
|
||||
* cleared. Combination of RATE_MCS_*
|
||||
* cleared. Combination of RATE_MCS_*; format depends on version
|
||||
* @reserved: reserved
|
||||
* @hdr: 802.11 header
|
||||
*/
|
||||
struct iwl_tx_cmd_gen3 {
|
||||
struct iwl_tx_cmd {
|
||||
__le16 len;
|
||||
__le16 flags;
|
||||
__le32 offload_assist;
|
||||
@ -298,7 +298,9 @@ struct iwl_tx_cmd_gen3 {
|
||||
__le32 rate_n_flags;
|
||||
u8 reserved[8];
|
||||
struct ieee80211_hdr hdr[];
|
||||
} __packed; /* TX_CMD_API_S_VER_8, TX_CMD_API_S_VER_10 */
|
||||
} __packed; /* TX_CMD_API_S_VER_10,
|
||||
* TX_CMD_API_S_VER_11
|
||||
*/
|
||||
|
||||
/*
|
||||
* TX response related data
|
||||
@ -549,7 +551,7 @@ struct iwl_tx_resp_v3 {
|
||||
* @failure_rts: num of failures due to unsuccessful RTS
|
||||
* @failure_frame: num failures due to no ACK (unused for agg)
|
||||
* @initial_rate: for non-agg: rate of the successful Tx. For agg: rate of the
|
||||
* Tx of all the batch. RATE_MCS_*
|
||||
* Tx of all the batch. RATE_MCS_*; format depends on command version
|
||||
* @wireless_media_time: for non-agg: RTS + CTS + frame tx attempts time + ACK.
|
||||
* for agg: RTS + CTS + aggregation tx time + block-ack time.
|
||||
* in usec.
|
||||
@ -600,8 +602,10 @@ struct iwl_tx_resp {
|
||||
__le16 reserved2;
|
||||
struct agg_tx_status status;
|
||||
} __packed; /* TX_RSP_API_S_VER_6,
|
||||
TX_RSP_API_S_VER_7,
|
||||
TX_RSP_API_S_VER_8 */
|
||||
* TX_RSP_API_S_VER_7,
|
||||
* TX_RSP_API_S_VER_8,
|
||||
* TX_RSP_API_S_VER_9
|
||||
*/
|
||||
|
||||
/**
|
||||
* struct iwl_mvm_ba_notif - notifies about reception of BA
|
||||
@ -701,7 +705,8 @@ enum iwl_mvm_ba_resp_flags {
|
||||
* @rts_retry_cnt: RTS retry count
|
||||
* @reserved: reserved (for alignment)
|
||||
* @wireless_time: Wireless-media time
|
||||
* @tx_rate: the rate the aggregation was sent at
|
||||
* @tx_rate: the rate the aggregation was sent at. Format depends on command
|
||||
* version.
|
||||
* @tfd_cnt: number of TFD-Q elements
|
||||
* @ra_tid_cnt: number of RATID-Q elements
|
||||
* @tfd: array of TFD queue status updates. See &iwl_compressed_ba_tfd
|
||||
@ -730,7 +735,8 @@ struct iwl_compressed_ba_notif {
|
||||
DECLARE_FLEX_ARRAY(struct iwl_compressed_ba_tfd, tfd);
|
||||
};
|
||||
} __packed; /* COMPRESSED_BA_RES_API_S_VER_4,
|
||||
COMPRESSED_BA_RES_API_S_VER_5 */
|
||||
COMPRESSED_BA_RES_API_S_VER_6,
|
||||
COMPRESSED_BA_RES_API_S_VER_7 */
|
||||
|
||||
/**
|
||||
* struct iwl_mac_beacon_cmd_v6 - beacon template command
|
||||
@ -742,7 +748,7 @@ struct iwl_compressed_ba_notif {
|
||||
* @frame: the template of the beacon frame
|
||||
*/
|
||||
struct iwl_mac_beacon_cmd_v6 {
|
||||
struct iwl_tx_cmd tx;
|
||||
struct iwl_tx_cmd_v6 tx;
|
||||
__le32 template_id;
|
||||
__le32 tim_idx;
|
||||
__le32 tim_size;
|
||||
@ -761,7 +767,7 @@ struct iwl_mac_beacon_cmd_v6 {
|
||||
* @frame: the template of the beacon frame
|
||||
*/
|
||||
struct iwl_mac_beacon_cmd_v7 {
|
||||
struct iwl_tx_cmd tx;
|
||||
struct iwl_tx_cmd_v6 tx;
|
||||
__le32 template_id;
|
||||
__le32 tim_idx;
|
||||
__le32 tim_size;
|
||||
|
||||
@ -187,7 +187,7 @@ static void iwl_fw_dump_rxf(struct iwl_fw_runtime *fwrt,
|
||||
/* Pull RXF2 */
|
||||
iwl_fwrt_dump_rxf(fwrt, dump_data, cfg->rxfifo2_size,
|
||||
RXF_DIFF_FROM_PREV +
|
||||
fwrt->trans->trans_cfg->umac_prph_offset, 1);
|
||||
fwrt->trans->mac_cfg->umac_prph_offset, 1);
|
||||
/* Pull LMAC2 RXF1 */
|
||||
if (fwrt->smem_cfg.num_lmacs > 1)
|
||||
iwl_fwrt_dump_rxf(fwrt, dump_data,
|
||||
@ -654,10 +654,10 @@ static void iwl_fw_prph_handler(struct iwl_fw_runtime *fwrt, void *ptr,
|
||||
{
|
||||
u32 range_len;
|
||||
|
||||
if (fwrt->trans->trans_cfg->device_family >= IWL_DEVICE_FAMILY_AX210) {
|
||||
if (fwrt->trans->mac_cfg->device_family >= IWL_DEVICE_FAMILY_AX210) {
|
||||
range_len = ARRAY_SIZE(iwl_prph_dump_addr_ax210);
|
||||
handler(fwrt, iwl_prph_dump_addr_ax210, range_len, ptr);
|
||||
} else if (fwrt->trans->trans_cfg->device_family >=
|
||||
} else if (fwrt->trans->mac_cfg->device_family >=
|
||||
IWL_DEVICE_FAMILY_22000) {
|
||||
range_len = ARRAY_SIZE(iwl_prph_dump_addr_22000);
|
||||
handler(fwrt, iwl_prph_dump_addr_22000, range_len, ptr);
|
||||
@ -665,7 +665,7 @@ static void iwl_fw_prph_handler(struct iwl_fw_runtime *fwrt, void *ptr,
|
||||
range_len = ARRAY_SIZE(iwl_prph_dump_addr_comm);
|
||||
handler(fwrt, iwl_prph_dump_addr_comm, range_len, ptr);
|
||||
|
||||
if (fwrt->trans->trans_cfg->mq_rx_supported) {
|
||||
if (fwrt->trans->mac_cfg->mq_rx_supported) {
|
||||
range_len = ARRAY_SIZE(iwl_prph_dump_addr_9000);
|
||||
handler(fwrt, iwl_prph_dump_addr_9000, range_len, ptr);
|
||||
}
|
||||
@ -809,13 +809,14 @@ iwl_fw_error_dump_file(struct iwl_fw_runtime *fwrt,
|
||||
const struct iwl_fw_dbg_mem_seg_tlv *fw_mem = fwrt->fw->dbg.mem_tlv;
|
||||
struct iwl_fwrt_shared_mem_cfg *mem_cfg = &fwrt->smem_cfg;
|
||||
u32 file_len, fifo_len = 0, prph_len = 0, radio_len = 0;
|
||||
u32 smem_len = fwrt->fw->dbg.n_mem_tlv ? 0 : fwrt->trans->cfg->smem_len;
|
||||
u32 smem_len = fwrt->fw->dbg.n_mem_tlv ? 0 : fwrt->trans->mac_cfg->base->smem_len;
|
||||
u32 sram2_len = fwrt->fw->dbg.n_mem_tlv ?
|
||||
0 : fwrt->trans->cfg->dccm2_len;
|
||||
int i;
|
||||
|
||||
/* SRAM - include stack CCM if driver knows the values for it */
|
||||
if (!fwrt->trans->cfg->dccm_offset || !fwrt->trans->cfg->dccm_len) {
|
||||
if (!fwrt->trans->cfg->dccm_offset ||
|
||||
!fwrt->trans->cfg->dccm_len) {
|
||||
const struct fw_img *img;
|
||||
|
||||
if (fwrt->cur_fw_img >= IWL_UCODE_TYPE_MAX)
|
||||
@ -838,7 +839,7 @@ iwl_fw_error_dump_file(struct iwl_fw_runtime *fwrt,
|
||||
iwl_fw_prph_handler(fwrt, &prph_len,
|
||||
iwl_fw_get_prph_len);
|
||||
|
||||
if (fwrt->trans->trans_cfg->device_family ==
|
||||
if (fwrt->trans->mac_cfg->device_family ==
|
||||
IWL_DEVICE_FAMILY_7000 &&
|
||||
iwl_fw_dbg_type_on(fwrt, IWL_FW_ERROR_DUMP_RADIO_REG))
|
||||
radio_len = sizeof(*dump_data) + RADIO_REG_MAX_READ;
|
||||
@ -876,7 +877,7 @@ iwl_fw_error_dump_file(struct iwl_fw_runtime *fwrt,
|
||||
|
||||
if (iwl_fw_dbg_is_d3_debug_enabled(fwrt) && fwrt->dump.d3_debug_data) {
|
||||
file_len += sizeof(*dump_data) +
|
||||
fwrt->trans->cfg->d3_debug_data_length * 2;
|
||||
fwrt->trans->mac_cfg->base->d3_debug_data_length * 2;
|
||||
}
|
||||
|
||||
/* If we only want a monitor dump, reset the file length */
|
||||
@ -904,13 +905,14 @@ iwl_fw_error_dump_file(struct iwl_fw_runtime *fwrt,
|
||||
dump_data->len = cpu_to_le32(sizeof(*dump_info));
|
||||
dump_info = (void *)dump_data->data;
|
||||
dump_info->hw_type =
|
||||
cpu_to_le32(CSR_HW_REV_TYPE(fwrt->trans->hw_rev));
|
||||
cpu_to_le32(CSR_HW_REV_TYPE(fwrt->trans->info.hw_rev));
|
||||
dump_info->hw_step =
|
||||
cpu_to_le32(fwrt->trans->hw_rev_step);
|
||||
cpu_to_le32(fwrt->trans->info.hw_rev_step);
|
||||
memcpy(dump_info->fw_human_readable, fwrt->fw->human_readable,
|
||||
sizeof(dump_info->fw_human_readable));
|
||||
strscpy_pad(dump_info->dev_human_readable, fwrt->trans->name,
|
||||
sizeof(dump_info->dev_human_readable));
|
||||
strscpy_pad(dump_info->dev_human_readable,
|
||||
fwrt->trans->info.name,
|
||||
sizeof(dump_info->dev_human_readable));
|
||||
strscpy_pad(dump_info->bus_human_readable, fwrt->dev->bus->name,
|
||||
sizeof(dump_info->bus_human_readable));
|
||||
dump_info->num_of_lmacs = fwrt->smem_cfg.num_lmacs;
|
||||
@ -996,7 +998,7 @@ iwl_fw_error_dump_file(struct iwl_fw_runtime *fwrt,
|
||||
}
|
||||
|
||||
iwl_fw_dump_mem(fwrt, &dump_data, smem_len,
|
||||
fwrt->trans->cfg->smem_offset,
|
||||
fwrt->trans->mac_cfg->base->smem_offset,
|
||||
IWL_FW_ERROR_DUMP_MEM_SMEM);
|
||||
|
||||
iwl_fw_dump_mem(fwrt, &dump_data, sram2_len,
|
||||
@ -1005,8 +1007,8 @@ iwl_fw_error_dump_file(struct iwl_fw_runtime *fwrt,
|
||||
}
|
||||
|
||||
if (iwl_fw_dbg_is_d3_debug_enabled(fwrt) && fwrt->dump.d3_debug_data) {
|
||||
u32 addr = fwrt->trans->cfg->d3_debug_data_base_addr;
|
||||
size_t data_size = fwrt->trans->cfg->d3_debug_data_length;
|
||||
u32 addr = fwrt->trans->mac_cfg->base->d3_debug_data_base_addr;
|
||||
size_t data_size = fwrt->trans->mac_cfg->base->d3_debug_data_length;
|
||||
|
||||
dump_data->type = cpu_to_le32(IWL_FW_ERROR_DUMP_D3_DEBUG_DATA);
|
||||
dump_data->len = cpu_to_le32(data_size * 2);
|
||||
@ -1109,7 +1111,7 @@ static int iwl_dump_ini_prph_phy_iter_common(struct iwl_fw_runtime *fwrt,
|
||||
range->internal_base_addr = cpu_to_le32(addr);
|
||||
range->range_data_size = size;
|
||||
|
||||
if (fwrt->trans->trans_cfg->device_family < IWL_DEVICE_FAMILY_AX210)
|
||||
if (fwrt->trans->mac_cfg->device_family < IWL_DEVICE_FAMILY_AX210)
|
||||
indirect_wr_addr = WMAL_INDRCT_CMD1;
|
||||
|
||||
indirect_wr_addr += le32_to_cpu(offset);
|
||||
@ -1266,7 +1268,7 @@ static int iwl_dump_ini_paging_iter(struct iwl_fw_runtime *fwrt,
|
||||
/* all paged index start from 1 to skip CSS section */
|
||||
idx++;
|
||||
|
||||
if (!fwrt->trans->trans_cfg->gen2)
|
||||
if (!fwrt->trans->mac_cfg->gen2)
|
||||
return _iwl_dump_ini_paging_iter(fwrt, range_ptr, range_len, idx);
|
||||
|
||||
range = range_ptr;
|
||||
@ -1790,7 +1792,7 @@ iwl_dump_ini_mon_fill_header(struct iwl_fw_runtime *fwrt, u32 alloc_id,
|
||||
|
||||
data->write_ptr = iwl_get_mon_reg(fwrt, alloc_id,
|
||||
&addrs->write_ptr);
|
||||
if (fwrt->trans->trans_cfg->device_family >= IWL_DEVICE_FAMILY_AX210) {
|
||||
if (fwrt->trans->mac_cfg->device_family >= IWL_DEVICE_FAMILY_AX210) {
|
||||
u32 wrt_ptr = le32_to_cpu(data->write_ptr);
|
||||
|
||||
data->write_ptr = cpu_to_le32(wrt_ptr >> 2);
|
||||
@ -1817,7 +1819,7 @@ iwl_dump_ini_mon_dram_fill_header(struct iwl_fw_runtime *fwrt,
|
||||
u32 alloc_id = le32_to_cpu(reg->dram_alloc_id);
|
||||
|
||||
return iwl_dump_ini_mon_fill_header(fwrt, alloc_id, mon_dump,
|
||||
&fwrt->trans->cfg->mon_dram_regs);
|
||||
&fwrt->trans->mac_cfg->base->mon_dram_regs);
|
||||
}
|
||||
|
||||
static void *
|
||||
@ -1830,7 +1832,7 @@ iwl_dump_ini_mon_smem_fill_header(struct iwl_fw_runtime *fwrt,
|
||||
u32 alloc_id = le32_to_cpu(reg->internal_buffer.alloc_id);
|
||||
|
||||
return iwl_dump_ini_mon_fill_header(fwrt, alloc_id, mon_dump,
|
||||
&fwrt->trans->cfg->mon_smem_regs);
|
||||
&fwrt->trans->mac_cfg->base->mon_smem_regs);
|
||||
}
|
||||
|
||||
static void *
|
||||
@ -1844,7 +1846,7 @@ iwl_dump_ini_mon_dbgi_fill_header(struct iwl_fw_runtime *fwrt,
|
||||
/* no offset calculation later */
|
||||
IWL_FW_INI_ALLOCATION_ID_DBGC1,
|
||||
mon_dump,
|
||||
&fwrt->trans->cfg->mon_dbgi_regs);
|
||||
&fwrt->trans->mac_cfg->base->mon_dbgi_regs);
|
||||
}
|
||||
|
||||
static void *
|
||||
@ -1909,7 +1911,7 @@ iwl_dump_ini_mem_block_ranges(struct iwl_fw_runtime *fwrt,
|
||||
static u32 iwl_dump_ini_paging_ranges(struct iwl_fw_runtime *fwrt,
|
||||
struct iwl_dump_ini_region_data *reg_data)
|
||||
{
|
||||
if (fwrt->trans->trans_cfg->gen2) {
|
||||
if (fwrt->trans->mac_cfg->gen2) {
|
||||
if (fwrt->trans->init_dram.paging_cnt)
|
||||
return fwrt->trans->init_dram.paging_cnt - 1;
|
||||
else
|
||||
@ -2021,7 +2023,7 @@ iwl_dump_ini_paging_get_size(struct iwl_fw_runtime *fwrt,
|
||||
/* start from 1 to skip CSS section */
|
||||
for (i = 1; i <= iwl_dump_ini_paging_ranges(fwrt, reg_data); i++) {
|
||||
size += range_header_len;
|
||||
if (fwrt->trans->trans_cfg->gen2)
|
||||
if (fwrt->trans->mac_cfg->gen2)
|
||||
size += fwrt->trans->init_dram.paging[i].size;
|
||||
else
|
||||
size += fwrt->fw_paging_db[i].fw_paging_size;
|
||||
@ -2375,7 +2377,7 @@ static u32 iwl_dump_ini_info(struct iwl_fw_runtime *fwrt,
|
||||
struct iwl_fw_ini_dump_cfg_name *cfg_name;
|
||||
u32 size = sizeof(*tlv) + sizeof(*dump);
|
||||
u32 num_of_cfg_names = 0;
|
||||
u32 hw_type;
|
||||
u32 hw_type, is_cdb, is_jacket;
|
||||
|
||||
list_for_each_entry(node, &fwrt->trans->dbg.debug_info_tlv_list, list) {
|
||||
size += sizeof(*cfg_name);
|
||||
@ -2403,33 +2405,24 @@ static u32 iwl_dump_ini_info(struct iwl_fw_runtime *fwrt,
|
||||
dump->ver_type = cpu_to_le32(fwrt->dump.fw_ver.type);
|
||||
dump->ver_subtype = cpu_to_le32(fwrt->dump.fw_ver.subtype);
|
||||
|
||||
dump->hw_step = cpu_to_le32(fwrt->trans->hw_rev_step);
|
||||
dump->hw_step = cpu_to_le32(fwrt->trans->info.hw_rev_step);
|
||||
|
||||
/*
|
||||
* Several HWs all have type == 0x42, so we'll override this value
|
||||
* according to the detected HW
|
||||
*/
|
||||
hw_type = CSR_HW_REV_TYPE(fwrt->trans->hw_rev);
|
||||
if (hw_type == IWL_AX210_HW_TYPE) {
|
||||
u32 prph_val = iwl_read_umac_prph(fwrt->trans, WFPM_OTP_CFG1_ADDR);
|
||||
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);
|
||||
hw_type = CSR_HW_REV_TYPE(fwrt->trans->info.hw_rev);
|
||||
|
||||
is_cdb = CSR_HW_RFID_IS_CDB(fwrt->trans->info.hw_rf_id);
|
||||
is_jacket = !!(iwl_read_umac_prph(fwrt->trans, WFPM_OTP_CFG1_ADDR) &
|
||||
WFPM_OTP_CFG1_IS_JACKET_BIT);
|
||||
|
||||
/* Use bits 12 and 13 to indicate jacket/CDB, respectively */
|
||||
hw_type |= (is_jacket | (is_cdb << 1)) << IWL_JACKET_CDB_SHIFT;
|
||||
|
||||
/*
|
||||
* The HW type depends on certain bits in this case, so add
|
||||
* these bits to the HW type. We won't have collisions since we
|
||||
* add these bits after the highest possible bit in the mask.
|
||||
*/
|
||||
hw_type |= masked_bits << IWL_AX210_HW_TYPE_ADDITION_SHIFT;
|
||||
}
|
||||
dump->hw_type = cpu_to_le32(hw_type);
|
||||
|
||||
dump->rf_id_flavor =
|
||||
cpu_to_le32(CSR_HW_RFID_FLAVOR(fwrt->trans->hw_rf_id));
|
||||
dump->rf_id_dash = cpu_to_le32(CSR_HW_RFID_DASH(fwrt->trans->hw_rf_id));
|
||||
dump->rf_id_step = cpu_to_le32(CSR_HW_RFID_STEP(fwrt->trans->hw_rf_id));
|
||||
dump->rf_id_type = cpu_to_le32(CSR_HW_RFID_TYPE(fwrt->trans->hw_rf_id));
|
||||
cpu_to_le32(CSR_HW_RFID_FLAVOR(fwrt->trans->info.hw_rf_id));
|
||||
dump->rf_id_dash = cpu_to_le32(CSR_HW_RFID_DASH(fwrt->trans->info.hw_rf_id));
|
||||
dump->rf_id_step = cpu_to_le32(CSR_HW_RFID_STEP(fwrt->trans->info.hw_rf_id));
|
||||
dump->rf_id_type = cpu_to_le32(CSR_HW_RFID_TYPE(fwrt->trans->info.hw_rf_id));
|
||||
|
||||
dump->lmac_major = cpu_to_le32(fwrt->dump.fw_ver.lmac_major);
|
||||
dump->lmac_minor = cpu_to_le32(fwrt->dump.fw_ver.lmac_minor);
|
||||
@ -2731,7 +2724,7 @@ static u32 iwl_dump_ini_trigger(struct iwl_fw_runtime *fwrt,
|
||||
BUILD_BUG_ON((sizeof(trigger->regions_mask) * BITS_PER_BYTE) <
|
||||
ARRAY_SIZE(fwrt->trans->dbg.active_regions));
|
||||
|
||||
if (trigger->time_point &
|
||||
if (trigger->apply_policy &
|
||||
cpu_to_le32(IWL_FW_INI_APPLY_POLICY_SPLIT_DUMP_RESET)) {
|
||||
size += iwl_dump_ini_dump_regions(fwrt, dump_data, list, tp_id,
|
||||
regions_mask, &imr_reg_data,
|
||||
@ -3291,13 +3284,13 @@ void iwl_fw_error_dump_wk(struct work_struct *work)
|
||||
|
||||
void iwl_fw_dbg_read_d3_debug_data(struct iwl_fw_runtime *fwrt)
|
||||
{
|
||||
const struct iwl_cfg *cfg = fwrt->trans->cfg;
|
||||
const struct iwl_mac_cfg *mac_cfg = fwrt->trans->mac_cfg;
|
||||
|
||||
if (!iwl_fw_dbg_is_d3_debug_enabled(fwrt))
|
||||
return;
|
||||
|
||||
if (!fwrt->dump.d3_debug_data) {
|
||||
fwrt->dump.d3_debug_data = kmalloc(cfg->d3_debug_data_length,
|
||||
fwrt->dump.d3_debug_data = kmalloc(mac_cfg->base->d3_debug_data_length,
|
||||
GFP_KERNEL);
|
||||
if (!fwrt->dump.d3_debug_data) {
|
||||
IWL_ERR(fwrt,
|
||||
@ -3307,15 +3300,15 @@ void iwl_fw_dbg_read_d3_debug_data(struct iwl_fw_runtime *fwrt)
|
||||
}
|
||||
|
||||
/* if the buffer holds previous debug data it is overwritten */
|
||||
iwl_trans_read_mem_bytes(fwrt->trans, cfg->d3_debug_data_base_addr,
|
||||
iwl_trans_read_mem_bytes(fwrt->trans, mac_cfg->base->d3_debug_data_base_addr,
|
||||
fwrt->dump.d3_debug_data,
|
||||
cfg->d3_debug_data_length);
|
||||
mac_cfg->base->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,
|
||||
mac_cfg->base->d3_debug_data_base_addr,
|
||||
fwrt->dump.d3_debug_data,
|
||||
cfg->d3_debug_data_length);
|
||||
mac_cfg->base->d3_debug_data_length);
|
||||
}
|
||||
IWL_EXPORT_SYMBOL(iwl_fw_dbg_read_d3_debug_data);
|
||||
|
||||
@ -3350,7 +3343,7 @@ static int iwl_fw_dbg_suspend_resume_hcmd(struct iwl_trans *trans, bool suspend)
|
||||
static void iwl_fw_dbg_stop_recording(struct iwl_trans *trans,
|
||||
struct iwl_fw_dbg_params *params)
|
||||
{
|
||||
if (trans->trans_cfg->device_family == IWL_DEVICE_FAMILY_7000) {
|
||||
if (trans->mac_cfg->device_family == IWL_DEVICE_FAMILY_7000) {
|
||||
iwl_set_bits_prph(trans, MON_BUFF_SAMPLE_CTL, 0x100);
|
||||
return;
|
||||
}
|
||||
@ -3374,7 +3367,7 @@ static int iwl_fw_dbg_restart_recording(struct iwl_trans *trans,
|
||||
if (!params)
|
||||
return -EIO;
|
||||
|
||||
if (trans->trans_cfg->device_family == IWL_DEVICE_FAMILY_7000) {
|
||||
if (trans->mac_cfg->device_family == IWL_DEVICE_FAMILY_7000) {
|
||||
iwl_clear_bits_prph(trans, MON_BUFF_SAMPLE_CTL, 0x100);
|
||||
iwl_clear_bits_prph(trans, MON_BUFF_SAMPLE_CTL, 0x1);
|
||||
iwl_set_bits_prph(trans, MON_BUFF_SAMPLE_CTL, 0x1);
|
||||
@ -3476,7 +3469,7 @@ void iwl_fw_disable_dbg_asserts(struct iwl_fw_runtime *fwrt)
|
||||
GENMASK(31, IWL_FW_DBG_DOMAIN_POS + 1));
|
||||
|
||||
/* supported starting from 9000 devices */
|
||||
if (fwrt->trans->trans_cfg->device_family < IWL_DEVICE_FAMILY_9000)
|
||||
if (fwrt->trans->mac_cfg->device_family < IWL_DEVICE_FAMILY_9000)
|
||||
return;
|
||||
|
||||
if (fwrt->trans->dbg.yoyo_bin_loaded || (preset && preset != 1))
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause */
|
||||
/*
|
||||
* Copyright (C) 2005-2014, 2018-2019, 2021-2024 Intel Corporation
|
||||
* Copyright (C) 2005-2014, 2018-2019, 2021-2025 Intel Corporation
|
||||
* Copyright (C) 2013-2015 Intel Mobile Communications GmbH
|
||||
* Copyright (C) 2015-2017 Intel Deutschland GmbH
|
||||
*/
|
||||
@ -201,7 +201,7 @@ static inline bool iwl_fw_dbg_is_d3_debug_enabled(struct iwl_fw_runtime *fwrt)
|
||||
{
|
||||
return fw_has_capa(&fwrt->fw->ucode_capa,
|
||||
IWL_UCODE_TLV_CAPA_D3_DEBUG) &&
|
||||
fwrt->trans->cfg->d3_debug_data_length && fwrt->ops &&
|
||||
fwrt->trans->mac_cfg->base->d3_debug_data_length && fwrt->ops &&
|
||||
fwrt->ops->d3_debug_enable &&
|
||||
fwrt->ops->d3_debug_enable(fwrt->ops_ctx) &&
|
||||
iwl_fw_dbg_type_on(fwrt, IWL_FW_ERROR_DUMP_D3_DEBUG_DATA);
|
||||
@ -210,7 +210,7 @@ static inline bool iwl_fw_dbg_is_d3_debug_enabled(struct iwl_fw_runtime *fwrt)
|
||||
static inline bool iwl_fw_dbg_is_paging_enabled(struct iwl_fw_runtime *fwrt)
|
||||
{
|
||||
return iwl_fw_dbg_type_on(fwrt, IWL_FW_ERROR_DUMP_PAGING) &&
|
||||
!fwrt->trans->trans_cfg->gen2 &&
|
||||
!fwrt->trans->mac_cfg->gen2 &&
|
||||
fwrt->cur_fw_img < IWL_UCODE_TYPE_MAX &&
|
||||
fwrt->fw->img[fwrt->cur_fw_img].paging_mem_size &&
|
||||
fwrt->fw_paging_db[0].fw_paging_block;
|
||||
|
||||
@ -311,7 +311,7 @@ static ssize_t iwl_dbgfs_fw_ver_read(struct iwl_fw_runtime *fwrt,
|
||||
pos += scnprintf(pos, endpos - pos, "FW: %s\n",
|
||||
fwrt->fw->human_readable);
|
||||
pos += scnprintf(pos, endpos - pos, "Device: %s\n",
|
||||
fwrt->trans->name);
|
||||
fwrt->trans->info.name);
|
||||
pos += scnprintf(pos, endpos - pos, "Bus: %s\n",
|
||||
fwrt->dev->bus->name);
|
||||
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user