wireless-drivers-next patches for 5.1

Most likely the last set of patches for 5.1. WPA3 support to ath10k
 and qtnfmac. FTM support to iwlwifi and ath10k. And of course other
 new features and bugfixes.
 
 wireless-drivers was merged due to dependency in mt76.
 
 Major changes:
 
 iwlwifi
 
 * HE radiotap
 
 * FTM (Fine Timing Measurement) initiator and responder implementation
 
 * bump supported firmware API to 46
 
 * VHT extended NSS support
 
 * new PCI IDs for 9260 and 22000 series
 
 ath10k
 
 * change QMI interface to support the new (and backwards incompatible)
   interface from HL3.1 and used in recent HL2.0 branch firmware
   releases
 
 * support WPA3 with WCN3990
 
 * support for mac80211 airtime fairness based on transmit rate
   estimation, the firmware needs to support WMI_SERVICE_PEER_STATS to
   enable this
 
 * report transmit airtime to mac80211 with firmwares having
   WMI_SERVICE_REPORT_AIRTIME feature, this to have more accurate
   airtime fairness based on real transmit time (instead of just
   estimated from transmit rate)
 
 * support Fine Timing Measurement (FTM) responder role
 
 * add dynamic VLAN support with firmware having WMI_SERVICE_PER_PACKET_SW_ENCRYPT
 
 * switch to use SPDX license identifiers
 
 ath
 
 * add new country codes for US
 
 brcmfmac
 
 * support monitor frames with the hardware/ucode header
 
 qtnfmac
 
 * enable WPA3 SAE and OWE support
 
 mt76
 
 * beacon support for USB devices (mesh+ad-hoc only)
 
 rtlwifi
 
 * convert to use SPDX license identifiers
 
 libertas_tf
 
 * get the MAC address before registering the device
 -----BEGIN PGP SIGNATURE-----
 Version: GnuPG v1
 
 iQEcBAABAgAGBQJccAnlAAoJEG4XJFUm622bxxMH/2cz2GEuDQXOwfYLnCUwFES8
 vqTdMWnlfqGQvsTyvtSp91KqsL3hE2FB1Cu3n6/vzND3C7afT0V2/QlU7Pmgr8sR
 1gnJnu0NJT5SZfzcTsqwt8rFw9lQZ3HcvEcfNo6T5KUyyY7FGCNGR5H27nvoKOP3
 ea1h7U80loPV40sGTI8jj963wa9LNHUrjHTK4wY+KMWECgZuD/fHeE9YPB9MTdff
 lJ5bWCoQmuJddvTtC+X0tOAsCkxgdbbw6ieKqzep8H4gtUjerZD+V8uUdbtpr7IL
 sWPoaqrrADMv9cZtDVj+pEtNIJ3mpfuHYFKSON9jy/uxygeFTfVzLu43RFreDp8=
 =D15/
 -----END PGP SIGNATURE-----

Merge tag 'wireless-drivers-next-for-davem-2019-02-22' of git://git.kernel.org/pub/scm/linux/kernel/git/kvalo/wireless-drivers-next

Kalle Valo says:

====================
wireless-drivers-next patches for 5.1

Most likely the last set of patches for 5.1. WPA3 support to ath10k
and qtnfmac. FTM support to iwlwifi and ath10k. And of course other
new features and bugfixes.

wireless-drivers was merged due to dependency in mt76.

Major changes:

iwlwifi

* HE radiotap

* FTM (Fine Timing Measurement) initiator and responder implementation

* bump supported firmware API to 46

* VHT extended NSS support

* new PCI IDs for 9260 and 22000 series

ath10k

* change QMI interface to support the new (and backwards incompatible)
  interface from HL3.1 and used in recent HL2.0 branch firmware
  releases

* support WPA3 with WCN3990

* support for mac80211 airtime fairness based on transmit rate
  estimation, the firmware needs to support WMI_SERVICE_PEER_STATS to
  enable this

* report transmit airtime to mac80211 with firmwares having
  WMI_SERVICE_REPORT_AIRTIME feature, this to have more accurate
  airtime fairness based on real transmit time (instead of just
  estimated from transmit rate)

* support Fine Timing Measurement (FTM) responder role

* add dynamic VLAN support with firmware having WMI_SERVICE_PER_PACKET_SW_ENCRYPT

* switch to use SPDX license identifiers

ath

* add new country codes for US

brcmfmac

* support monitor frames with the hardware/ucode header

qtnfmac

* enable WPA3 SAE and OWE support

mt76

* beacon support for USB devices (mesh+ad-hoc only)

rtlwifi

* convert to use SPDX license identifiers

libertas_tf

* get the MAC address before registering the device
====================

Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
David S. Miller 2019-02-22 12:56:24 -08:00
commit 1a25660856
478 changed files with 8803 additions and 10536 deletions

View File

@ -1,4 +1,4 @@
# SPDX-License-Identifier: GPL-2.0 # SPDX-License-Identifier: ISC
obj-$(CONFIG_ATH10K) += ath10k_core.o obj-$(CONFIG_ATH10K) += ath10k_core.o
ath10k_core-y += mac.o \ ath10k_core-y += mac.o \
debug.o \ debug.o \

View File

@ -1,18 +1,7 @@
// SPDX-License-Identifier: ISC
/* /*
* Copyright (c) 2016-2017 Qualcomm Atheros, Inc. All rights reserved. * Copyright (c) 2016-2017 Qualcomm Atheros, Inc. All rights reserved.
* Copyright (c) 2015 The Linux Foundation. All rights reserved. * Copyright (c) 2015 The Linux Foundation. All rights reserved.
*
* Permission to use, copy, modify, and/or distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/ */
#include <linux/module.h> #include <linux/module.h>
#include <linux/of.h> #include <linux/of.h>
@ -661,7 +650,8 @@ static void ath10k_ahb_hif_stop(struct ath10k *ar)
ath10k_pci_flush(ar); ath10k_pci_flush(ar);
} }
static int ath10k_ahb_hif_power_up(struct ath10k *ar) static int ath10k_ahb_hif_power_up(struct ath10k *ar,
enum ath10k_firmware_mode fw_mode)
{ {
int ret; int ret;

View File

@ -1,18 +1,7 @@
/* SPDX-License-Identifier: ISC */
/* /*
* Copyright (c) 2016 Qualcomm Atheros, Inc. All rights reserved. * Copyright (c) 2016 Qualcomm Atheros, Inc. All rights reserved.
* Copyright (c) 2015 The Linux Foundation. All rights reserved. * Copyright (c) 2015 The Linux Foundation. All rights reserved.
*
* Permission to use, copy, modify, and/or distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/ */
#ifndef _AHB_H_ #ifndef _AHB_H_

View File

@ -1,18 +1,7 @@
// SPDX-License-Identifier: ISC
/* /*
* Copyright (c) 2005-2011 Atheros Communications Inc. * Copyright (c) 2005-2011 Atheros Communications Inc.
* Copyright (c) 2011-2014,2016-2017 Qualcomm Atheros, Inc. * Copyright (c) 2011-2014,2016-2017 Qualcomm Atheros, Inc.
*
* Permission to use, copy, modify, and/or distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/ */
#include "bmi.h" #include "bmi.h"

View File

@ -1,18 +1,7 @@
/* SPDX-License-Identifier: ISC */
/* /*
* Copyright (c) 2005-2011 Atheros Communications Inc. * Copyright (c) 2005-2011 Atheros Communications Inc.
* Copyright (c) 2011-2015,2017 Qualcomm Atheros, Inc. * Copyright (c) 2011-2015,2017 Qualcomm Atheros, Inc.
*
* Permission to use, copy, modify, and/or distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/ */
#ifndef _BMI_H_ #ifndef _BMI_H_

View File

@ -1,19 +1,8 @@
// SPDX-License-Identifier: ISC
/* /*
* Copyright (c) 2005-2011 Atheros Communications Inc. * Copyright (c) 2005-2011 Atheros Communications Inc.
* Copyright (c) 2011-2017 Qualcomm Atheros, Inc. * Copyright (c) 2011-2017 Qualcomm Atheros, Inc.
* Copyright (c) 2018 The Linux Foundation. All rights reserved. * Copyright (c) 2018 The Linux Foundation. All rights reserved.
*
* Permission to use, copy, modify, and/or distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/ */
#include "hif.h" #include "hif.h"
@ -228,11 +217,31 @@ ath10k_ce_shadow_dest_ring_write_index_set(struct ath10k *ar,
} }
static inline void ath10k_ce_src_ring_base_addr_set(struct ath10k *ar, static inline void ath10k_ce_src_ring_base_addr_set(struct ath10k *ar,
u32 ce_ctrl_addr, u32 ce_id,
unsigned int addr) u64 addr)
{ {
struct ath10k_ce *ce = ath10k_ce_priv(ar);
struct ath10k_ce_pipe *ce_state = &ce->ce_states[ce_id];
u32 ce_ctrl_addr = ath10k_ce_base_address(ar, ce_id);
u32 addr_lo = lower_32_bits(addr);
ath10k_ce_write32(ar, ce_ctrl_addr + ath10k_ce_write32(ar, ce_ctrl_addr +
ar->hw_ce_regs->sr_base_addr, addr); ar->hw_ce_regs->sr_base_addr_lo, addr_lo);
if (ce_state->ops->ce_set_src_ring_base_addr_hi) {
ce_state->ops->ce_set_src_ring_base_addr_hi(ar, ce_ctrl_addr,
addr);
}
}
static void ath10k_ce_set_src_ring_base_addr_hi(struct ath10k *ar,
u32 ce_ctrl_addr,
u64 addr)
{
u32 addr_hi = upper_32_bits(addr) & CE_DESC_ADDR_HI_MASK;
ath10k_ce_write32(ar, ce_ctrl_addr +
ar->hw_ce_regs->sr_base_addr_hi, addr_hi);
} }
static inline void ath10k_ce_src_ring_size_set(struct ath10k *ar, static inline void ath10k_ce_src_ring_size_set(struct ath10k *ar,
@ -313,11 +322,36 @@ static inline u32 ath10k_ce_dest_ring_read_index_get(struct ath10k *ar,
} }
static inline void ath10k_ce_dest_ring_base_addr_set(struct ath10k *ar, static inline void ath10k_ce_dest_ring_base_addr_set(struct ath10k *ar,
u32 ce_ctrl_addr, u32 ce_id,
u32 addr) u64 addr)
{ {
struct ath10k_ce *ce = ath10k_ce_priv(ar);
struct ath10k_ce_pipe *ce_state = &ce->ce_states[ce_id];
u32 ce_ctrl_addr = ath10k_ce_base_address(ar, ce_id);
u32 addr_lo = lower_32_bits(addr);
ath10k_ce_write32(ar, ce_ctrl_addr + ath10k_ce_write32(ar, ce_ctrl_addr +
ar->hw_ce_regs->dr_base_addr, addr); ar->hw_ce_regs->dr_base_addr_lo, addr_lo);
if (ce_state->ops->ce_set_dest_ring_base_addr_hi) {
ce_state->ops->ce_set_dest_ring_base_addr_hi(ar, ce_ctrl_addr,
addr);
}
}
static void ath10k_ce_set_dest_ring_base_addr_hi(struct ath10k *ar,
u32 ce_ctrl_addr,
u64 addr)
{
u32 addr_hi = upper_32_bits(addr) & CE_DESC_ADDR_HI_MASK;
u32 reg_value;
reg_value = ath10k_ce_read32(ar, ce_ctrl_addr +
ar->hw_ce_regs->dr_base_addr_hi);
reg_value &= ~CE_DESC_ADDR_HI_MASK;
reg_value |= addr_hi;
ath10k_ce_write32(ar, ce_ctrl_addr +
ar->hw_ce_regs->dr_base_addr_hi, reg_value);
} }
static inline void ath10k_ce_dest_ring_size_set(struct ath10k *ar, static inline void ath10k_ce_dest_ring_size_set(struct ath10k *ar,
@ -500,14 +534,8 @@ static int _ath10k_ce_send_nolock(struct ath10k_ce_pipe *ce_state,
write_index = CE_RING_IDX_INCR(nentries_mask, write_index); write_index = CE_RING_IDX_INCR(nentries_mask, write_index);
/* WORKAROUND */ /* WORKAROUND */
if (!(flags & CE_SEND_FLAG_GATHER)) { if (!(flags & CE_SEND_FLAG_GATHER))
if (ar->hw_params.shadow_reg_support) ath10k_ce_src_ring_write_index_set(ar, ctrl_addr, write_index);
ath10k_ce_shadow_src_ring_write_index_set(ar, ce_state,
write_index);
else
ath10k_ce_src_ring_write_index_set(ar, ctrl_addr,
write_index);
}
src_ring->write_index = write_index; src_ring->write_index = write_index;
exit: exit:
@ -563,7 +591,7 @@ static int _ath10k_ce_send_nolock_64(struct ath10k_ce_pipe *ce_state,
addr = (__le32 *)&sdesc.addr; addr = (__le32 *)&sdesc.addr;
flags |= upper_32_bits(buffer) & CE_DESC_FLAGS_GET_MASK; flags |= upper_32_bits(buffer) & CE_DESC_ADDR_HI_MASK;
addr[0] = __cpu_to_le32(buffer); addr[0] = __cpu_to_le32(buffer);
addr[1] = __cpu_to_le32(flags); addr[1] = __cpu_to_le32(flags);
if (flags & CE_SEND_FLAG_GATHER) if (flags & CE_SEND_FLAG_GATHER)
@ -581,8 +609,14 @@ static int _ath10k_ce_send_nolock_64(struct ath10k_ce_pipe *ce_state,
/* Update Source Ring Write Index */ /* Update Source Ring Write Index */
write_index = CE_RING_IDX_INCR(nentries_mask, write_index); write_index = CE_RING_IDX_INCR(nentries_mask, write_index);
if (!(flags & CE_SEND_FLAG_GATHER)) if (!(flags & CE_SEND_FLAG_GATHER)) {
ath10k_ce_src_ring_write_index_set(ar, ctrl_addr, write_index); if (ar->hw_params.shadow_reg_support)
ath10k_ce_shadow_src_ring_write_index_set(ar, ce_state,
write_index);
else
ath10k_ce_src_ring_write_index_set(ar, ctrl_addr,
write_index);
}
src_ring->write_index = write_index; src_ring->write_index = write_index;
exit: exit:
@ -731,7 +765,7 @@ static int __ath10k_ce_rx_post_buf_64(struct ath10k_ce_pipe *pipe,
return -ENOSPC; return -ENOSPC;
desc->addr = __cpu_to_le64(paddr); desc->addr = __cpu_to_le64(paddr);
desc->addr &= __cpu_to_le64(CE_DESC_37BIT_ADDR_MASK); desc->addr &= __cpu_to_le64(CE_DESC_ADDR_MASK);
desc->nbytes = 0; desc->nbytes = 0;
@ -1346,7 +1380,7 @@ static int ath10k_ce_init_src_ring(struct ath10k *ar,
ath10k_ce_src_ring_write_index_get(ar, ctrl_addr); ath10k_ce_src_ring_write_index_get(ar, ctrl_addr);
src_ring->write_index &= src_ring->nentries_mask; src_ring->write_index &= src_ring->nentries_mask;
ath10k_ce_src_ring_base_addr_set(ar, ctrl_addr, ath10k_ce_src_ring_base_addr_set(ar, ce_id,
src_ring->base_addr_ce_space); src_ring->base_addr_ce_space);
ath10k_ce_src_ring_size_set(ar, ctrl_addr, nentries); ath10k_ce_src_ring_size_set(ar, ctrl_addr, nentries);
ath10k_ce_src_ring_dmax_set(ar, ctrl_addr, attr->src_sz_max); ath10k_ce_src_ring_dmax_set(ar, ctrl_addr, attr->src_sz_max);
@ -1385,7 +1419,7 @@ static int ath10k_ce_init_dest_ring(struct ath10k *ar,
ath10k_ce_dest_ring_write_index_get(ar, ctrl_addr); ath10k_ce_dest_ring_write_index_get(ar, ctrl_addr);
dest_ring->write_index &= dest_ring->nentries_mask; dest_ring->write_index &= dest_ring->nentries_mask;
ath10k_ce_dest_ring_base_addr_set(ar, ctrl_addr, ath10k_ce_dest_ring_base_addr_set(ar, ce_id,
dest_ring->base_addr_ce_space); dest_ring->base_addr_ce_space);
ath10k_ce_dest_ring_size_set(ar, ctrl_addr, nentries); ath10k_ce_dest_ring_size_set(ar, ctrl_addr, nentries);
ath10k_ce_dest_ring_byte_swap_set(ar, ctrl_addr, 0); ath10k_ce_dest_ring_byte_swap_set(ar, ctrl_addr, 0);
@ -1404,12 +1438,12 @@ static int ath10k_ce_alloc_shadow_base(struct ath10k *ar,
u32 nentries) u32 nentries)
{ {
src_ring->shadow_base_unaligned = kcalloc(nentries, src_ring->shadow_base_unaligned = kcalloc(nentries,
sizeof(struct ce_desc), sizeof(struct ce_desc_64),
GFP_KERNEL); GFP_KERNEL);
if (!src_ring->shadow_base_unaligned) if (!src_ring->shadow_base_unaligned)
return -ENOMEM; return -ENOMEM;
src_ring->shadow_base = (struct ce_desc *) src_ring->shadow_base = (struct ce_desc_64 *)
PTR_ALIGN(src_ring->shadow_base_unaligned, PTR_ALIGN(src_ring->shadow_base_unaligned,
CE_DESC_RING_ALIGN); CE_DESC_RING_ALIGN);
return 0; return 0;
@ -1461,7 +1495,7 @@ ath10k_ce_alloc_src_ring(struct ath10k *ar, unsigned int ce_id,
ret = ath10k_ce_alloc_shadow_base(ar, src_ring, nentries); ret = ath10k_ce_alloc_shadow_base(ar, src_ring, nentries);
if (ret) { if (ret) {
dma_free_coherent(ar->dev, dma_free_coherent(ar->dev,
(nentries * sizeof(struct ce_desc) + (nentries * sizeof(struct ce_desc_64) +
CE_DESC_RING_ALIGN), CE_DESC_RING_ALIGN),
src_ring->base_addr_owner_space_unaligned, src_ring->base_addr_owner_space_unaligned,
base_addr); base_addr);
@ -1554,7 +1588,8 @@ ath10k_ce_alloc_dest_ring(struct ath10k *ar, unsigned int ce_id,
*/ */
dest_ring->base_addr_owner_space_unaligned = dest_ring->base_addr_owner_space_unaligned =
dma_alloc_coherent(ar->dev, dma_alloc_coherent(ar->dev,
(nentries * sizeof(struct ce_desc) + CE_DESC_RING_ALIGN), (nentries * sizeof(struct ce_desc) +
CE_DESC_RING_ALIGN),
&base_addr, GFP_KERNEL); &base_addr, GFP_KERNEL);
if (!dest_ring->base_addr_owner_space_unaligned) { if (!dest_ring->base_addr_owner_space_unaligned) {
kfree(dest_ring); kfree(dest_ring);
@ -1660,7 +1695,7 @@ static void ath10k_ce_deinit_src_ring(struct ath10k *ar, unsigned int ce_id)
{ {
u32 ctrl_addr = ath10k_ce_base_address(ar, ce_id); u32 ctrl_addr = ath10k_ce_base_address(ar, ce_id);
ath10k_ce_src_ring_base_addr_set(ar, ctrl_addr, 0); ath10k_ce_src_ring_base_addr_set(ar, ce_id, 0);
ath10k_ce_src_ring_size_set(ar, ctrl_addr, 0); ath10k_ce_src_ring_size_set(ar, ctrl_addr, 0);
ath10k_ce_src_ring_dmax_set(ar, ctrl_addr, 0); ath10k_ce_src_ring_dmax_set(ar, ctrl_addr, 0);
ath10k_ce_src_ring_highmark_set(ar, ctrl_addr, 0); ath10k_ce_src_ring_highmark_set(ar, ctrl_addr, 0);
@ -1670,7 +1705,7 @@ static void ath10k_ce_deinit_dest_ring(struct ath10k *ar, unsigned int ce_id)
{ {
u32 ctrl_addr = ath10k_ce_base_address(ar, ce_id); u32 ctrl_addr = ath10k_ce_base_address(ar, ce_id);
ath10k_ce_dest_ring_base_addr_set(ar, ctrl_addr, 0); ath10k_ce_dest_ring_base_addr_set(ar, ce_id, 0);
ath10k_ce_dest_ring_size_set(ar, ctrl_addr, 0); ath10k_ce_dest_ring_size_set(ar, ctrl_addr, 0);
ath10k_ce_dest_ring_highmark_set(ar, ctrl_addr, 0); ath10k_ce_dest_ring_highmark_set(ar, ctrl_addr, 0);
} }
@ -1802,6 +1837,8 @@ static const struct ath10k_ce_ops ce_ops = {
.ce_extract_desc_data = ath10k_ce_extract_desc_data, .ce_extract_desc_data = ath10k_ce_extract_desc_data,
.ce_free_pipe = _ath10k_ce_free_pipe, .ce_free_pipe = _ath10k_ce_free_pipe,
.ce_send_nolock = _ath10k_ce_send_nolock, .ce_send_nolock = _ath10k_ce_send_nolock,
.ce_set_src_ring_base_addr_hi = NULL,
.ce_set_dest_ring_base_addr_hi = NULL,
}; };
static const struct ath10k_ce_ops ce_64_ops = { static const struct ath10k_ce_ops ce_64_ops = {
@ -1814,6 +1851,8 @@ static const struct ath10k_ce_ops ce_64_ops = {
.ce_extract_desc_data = ath10k_ce_extract_desc_data_64, .ce_extract_desc_data = ath10k_ce_extract_desc_data_64,
.ce_free_pipe = _ath10k_ce_free_pipe_64, .ce_free_pipe = _ath10k_ce_free_pipe_64,
.ce_send_nolock = _ath10k_ce_send_nolock_64, .ce_send_nolock = _ath10k_ce_send_nolock_64,
.ce_set_src_ring_base_addr_hi = ath10k_ce_set_src_ring_base_addr_hi,
.ce_set_dest_ring_base_addr_hi = ath10k_ce_set_dest_ring_base_addr_hi,
}; };
static void ath10k_ce_set_ops(struct ath10k *ar, static void ath10k_ce_set_ops(struct ath10k *ar,
@ -1909,7 +1948,7 @@ void ath10k_ce_alloc_rri(struct ath10k *ar)
lower_32_bits(ce->paddr_rri)); lower_32_bits(ce->paddr_rri));
ath10k_ce_write32(ar, ar->hw_ce_regs->ce_rri_high, ath10k_ce_write32(ar, ar->hw_ce_regs->ce_rri_high,
(upper_32_bits(ce->paddr_rri) & (upper_32_bits(ce->paddr_rri) &
CE_DESC_FLAGS_GET_MASK)); CE_DESC_ADDR_HI_MASK));
for (i = 0; i < CE_COUNT; i++) { for (i = 0; i < CE_COUNT; i++) {
ctrl1_regs = ar->hw_ce_regs->ctrl1_regs->addr; ctrl1_regs = ar->hw_ce_regs->ctrl1_regs->addr;

View File

@ -1,19 +1,8 @@
/* SPDX-License-Identifier: ISC */
/* /*
* Copyright (c) 2005-2011 Atheros Communications Inc. * Copyright (c) 2005-2011 Atheros Communications Inc.
* Copyright (c) 2011-2017 Qualcomm Atheros, Inc. * Copyright (c) 2011-2017 Qualcomm Atheros, Inc.
* Copyright (c) 2018 The Linux Foundation. All rights reserved. * Copyright (c) 2018 The Linux Foundation. All rights reserved.
*
* Permission to use, copy, modify, and/or distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/ */
#ifndef _CE_H_ #ifndef _CE_H_
@ -39,8 +28,8 @@ struct ath10k_ce_pipe;
#define CE_DESC_FLAGS_BYTE_SWAP (1 << 1) #define CE_DESC_FLAGS_BYTE_SWAP (1 << 1)
#define CE_WCN3990_DESC_FLAGS_GATHER BIT(31) #define CE_WCN3990_DESC_FLAGS_GATHER BIT(31)
#define CE_DESC_FLAGS_GET_MASK GENMASK(4, 0) #define CE_DESC_ADDR_MASK GENMASK_ULL(34, 0)
#define CE_DESC_37BIT_ADDR_MASK GENMASK_ULL(37, 0) #define CE_DESC_ADDR_HI_MASK GENMASK(4, 0)
/* Following desc flags are used in QCA99X0 */ /* Following desc flags are used in QCA99X0 */
#define CE_DESC_FLAGS_HOST_INT_DIS (1 << 2) #define CE_DESC_FLAGS_HOST_INT_DIS (1 << 2)
@ -104,7 +93,7 @@ struct ath10k_ce_ring {
/* Host address space */ /* Host address space */
void *base_addr_owner_space_unaligned; void *base_addr_owner_space_unaligned;
/* CE address space */ /* CE address space */
u32 base_addr_ce_space_unaligned; dma_addr_t base_addr_ce_space_unaligned;
/* /*
* Actual start of descriptors. * Actual start of descriptors.
@ -115,10 +104,10 @@ struct ath10k_ce_ring {
void *base_addr_owner_space; void *base_addr_owner_space;
/* CE address space */ /* CE address space */
u32 base_addr_ce_space; dma_addr_t base_addr_ce_space;
char *shadow_base_unaligned; char *shadow_base_unaligned;
struct ce_desc *shadow_base; struct ce_desc_64 *shadow_base;
/* keep last */ /* keep last */
void *per_transfer_context[0]; void *per_transfer_context[0];
@ -334,6 +323,12 @@ struct ath10k_ce_ops {
void *per_transfer_context, void *per_transfer_context,
dma_addr_t buffer, u32 nbytes, dma_addr_t buffer, u32 nbytes,
u32 transfer_id, u32 flags); u32 transfer_id, u32 flags);
void (*ce_set_src_ring_base_addr_hi)(struct ath10k *ar,
u32 ce_ctrl_addr,
u64 addr);
void (*ce_set_dest_ring_base_addr_hi)(struct ath10k *ar,
u32 ce_ctrl_addr,
u64 addr);
}; };
static inline u32 ath10k_ce_base_address(struct ath10k *ar, unsigned int ce_id) static inline u32 ath10k_ce_base_address(struct ath10k *ar, unsigned int ce_id)

View File

@ -1,19 +1,8 @@
// SPDX-License-Identifier: ISC
/* /*
* Copyright (c) 2005-2011 Atheros Communications Inc. * Copyright (c) 2005-2011 Atheros Communications Inc.
* Copyright (c) 2011-2017 Qualcomm Atheros, Inc. * Copyright (c) 2011-2017 Qualcomm Atheros, Inc.
* Copyright (c) 2018, The Linux Foundation. All rights reserved. * Copyright (c) 2018, The Linux Foundation. All rights reserved.
*
* Permission to use, copy, modify, and/or distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/ */
#include <linux/module.h> #include <linux/module.h>
@ -561,7 +550,7 @@ static const struct ath10k_hw_params ath10k_hw_params_list[] = {
.hw_ops = &wcn3990_ops, .hw_ops = &wcn3990_ops,
.decap_align_bytes = 1, .decap_align_bytes = 1,
.num_peers = TARGET_HL_10_TLV_NUM_PEERS, .num_peers = TARGET_HL_10_TLV_NUM_PEERS,
.n_cipher_suites = 8, .n_cipher_suites = 11,
.ast_skid_limit = TARGET_HL_10_TLV_AST_SKID_LIMIT, .ast_skid_limit = TARGET_HL_10_TLV_AST_SKID_LIMIT,
.num_wds_entries = TARGET_HL_10_TLV_NUM_WDS_ENTRIES, .num_wds_entries = TARGET_HL_10_TLV_NUM_WDS_ENTRIES,
.target_64bit = true, .target_64bit = true,
@ -2309,6 +2298,10 @@ static int ath10k_core_init_firmware_features(struct ath10k *ar)
ar->max_num_stations = TARGET_TLV_NUM_STATIONS; ar->max_num_stations = TARGET_TLV_NUM_STATIONS;
ar->max_num_vdevs = TARGET_TLV_NUM_VDEVS; ar->max_num_vdevs = TARGET_TLV_NUM_VDEVS;
ar->max_num_tdls_vdevs = TARGET_TLV_NUM_TDLS_VDEVS; ar->max_num_tdls_vdevs = TARGET_TLV_NUM_TDLS_VDEVS;
if (ar->hif.bus == ATH10K_BUS_SDIO)
ar->htt.max_num_pending_tx =
TARGET_TLV_NUM_MSDU_DESC_HL;
else
ar->htt.max_num_pending_tx = TARGET_TLV_NUM_MSDU_DESC; ar->htt.max_num_pending_tx = TARGET_TLV_NUM_MSDU_DESC;
ar->wow.max_num_patterns = TARGET_TLV_NUM_WOW_PATTERNS; ar->wow.max_num_patterns = TARGET_TLV_NUM_WOW_PATTERNS;
ar->fw_stats_req_mask = WMI_STAT_PDEV | WMI_STAT_VDEV | ar->fw_stats_req_mask = WMI_STAT_PDEV | WMI_STAT_VDEV |
@ -2556,6 +2549,12 @@ int ath10k_core_start(struct ath10k *ar, enum ath10k_firmware_mode mode,
goto err_hif_stop; goto err_hif_stop;
} }
status = ath10k_hif_swap_mailbox(ar);
if (status) {
ath10k_err(ar, "failed to swap mailbox: %d\n", status);
goto err_hif_stop;
}
if (mode == ATH10K_FIRMWARE_MODE_NORMAL) { if (mode == ATH10K_FIRMWARE_MODE_NORMAL) {
status = ath10k_htt_connect(&ar->htt); status = ath10k_htt_connect(&ar->htt);
if (status) { if (status) {
@ -2621,6 +2620,9 @@ int ath10k_core_start(struct ath10k *ar, enum ath10k_firmware_mode mode,
ar->wmi.svc_map)) ar->wmi.svc_map))
val |= WMI_10_4_TX_DATA_ACK_RSSI; val |= WMI_10_4_TX_DATA_ACK_RSSI;
if (test_bit(WMI_SERVICE_REPORT_AIRTIME, ar->wmi.svc_map))
val |= WMI_10_4_REPORT_AIRTIME;
status = ath10k_mac_ext_resource_config(ar, val); status = ath10k_mac_ext_resource_config(ar, val);
if (status) { if (status) {
ath10k_err(ar, ath10k_err(ar,
@ -2649,6 +2651,13 @@ int ath10k_core_start(struct ath10k *ar, enum ath10k_firmware_mode mode,
goto err_hif_stop; goto err_hif_stop;
} }
status = ath10k_wmi_pdev_set_base_macaddr(ar, ar->mac_addr);
if (status && status != -EOPNOTSUPP) {
ath10k_err(ar,
"failed to set base mac address: %d\n", status);
goto err_hif_stop;
}
/* Some firmware revisions do not properly set up hardware rx filter /* Some firmware revisions do not properly set up hardware rx filter
* registers. * registers.
* *
@ -2763,7 +2772,7 @@ static int ath10k_core_probe_fw(struct ath10k *ar)
struct bmi_target_info target_info; struct bmi_target_info target_info;
int ret = 0; int ret = 0;
ret = ath10k_hif_power_up(ar); ret = ath10k_hif_power_up(ar, ATH10K_FIRMWARE_MODE_NORMAL);
if (ret) { if (ret) {
ath10k_err(ar, "could not power on hif bus (%d)\n", ret); ath10k_err(ar, "could not power on hif bus (%d)\n", ret);
return ret; return ret;
@ -2977,8 +2986,8 @@ static void ath10k_core_register_work(struct work_struct *work)
int ath10k_core_register(struct ath10k *ar, int ath10k_core_register(struct ath10k *ar,
const struct ath10k_bus_params *bus_params) const struct ath10k_bus_params *bus_params)
{ {
ar->chip_id = bus_params->chip_id; ar->bus_param = *bus_params;
ar->dev_type = bus_params->dev_type;
queue_work(ar->workqueue, &ar->register_work); queue_work(ar->workqueue, &ar->register_work);
return 0; return 0;
@ -3098,9 +3107,7 @@ struct ath10k *ath10k_core_create(size_t priv_size, struct device *dev,
mutex_init(&ar->conf_mutex); mutex_init(&ar->conf_mutex);
spin_lock_init(&ar->data_lock); spin_lock_init(&ar->data_lock);
spin_lock_init(&ar->txqs_lock);
INIT_LIST_HEAD(&ar->txqs);
INIT_LIST_HEAD(&ar->peers); INIT_LIST_HEAD(&ar->peers);
init_waitqueue_head(&ar->peer_mapping_wq); init_waitqueue_head(&ar->peer_mapping_wq);
init_waitqueue_head(&ar->htt.empty_tx_wq); init_waitqueue_head(&ar->htt.empty_tx_wq);

View File

@ -1,19 +1,8 @@
/* SPDX-License-Identifier: ISC */
/* /*
* Copyright (c) 2005-2011 Atheros Communications Inc. * Copyright (c) 2005-2011 Atheros Communications Inc.
* Copyright (c) 2011-2017 Qualcomm Atheros, Inc. * Copyright (c) 2011-2017 Qualcomm Atheros, Inc.
* Copyright (c) 2018, The Linux Foundation. All rights reserved. * Copyright (c) 2018, The Linux Foundation. All rights reserved.
*
* Permission to use, copy, modify, and/or distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/ */
#ifndef _CORE_H_ #ifndef _CORE_H_
@ -90,6 +79,9 @@
/* The magic used by QCA spec */ /* The magic used by QCA spec */
#define ATH10K_SMBIOS_BDF_EXT_MAGIC "BDF_" #define ATH10K_SMBIOS_BDF_EXT_MAGIC "BDF_"
/* Default Airtime weight multipler (Tuned for multiclient performance) */
#define ATH10K_AIRTIME_WEIGHT_MULTIPLIER 4
struct ath10k; struct ath10k;
static inline const char *ath10k_bus_str(enum ath10k_bus bus) static inline const char *ath10k_bus_str(enum ath10k_bus bus)
@ -116,6 +108,7 @@ enum ath10k_skb_flags {
ATH10K_SKB_F_DELIVER_CAB = BIT(2), ATH10K_SKB_F_DELIVER_CAB = BIT(2),
ATH10K_SKB_F_MGMT = BIT(3), ATH10K_SKB_F_MGMT = BIT(3),
ATH10K_SKB_F_QOS = BIT(4), ATH10K_SKB_F_QOS = BIT(4),
ATH10K_SKB_F_RAW_TX = BIT(5),
}; };
struct ath10k_skb_cb { struct ath10k_skb_cb {
@ -123,6 +116,7 @@ struct ath10k_skb_cb {
u8 flags; u8 flags;
u8 eid; u8 eid;
u16 msdu_id; u16 msdu_id;
u16 airtime_est;
struct ieee80211_vif *vif; struct ieee80211_vif *vif;
struct ieee80211_txq *txq; struct ieee80211_txq *txq;
} __packed; } __packed;
@ -443,14 +437,14 @@ enum ath10k_amsdu_subfrm_num {
}; };
struct ath10k_sta_tid_stats { struct ath10k_sta_tid_stats {
unsigned long int rx_pkt_from_fw; unsigned long rx_pkt_from_fw;
unsigned long int rx_pkt_unchained; unsigned long rx_pkt_unchained;
unsigned long int rx_pkt_drop_chained; unsigned long rx_pkt_drop_chained;
unsigned long int rx_pkt_drop_filter; unsigned long rx_pkt_drop_filter;
unsigned long int rx_pkt_err[ATH10K_PKT_RX_ERR_MAX]; unsigned long rx_pkt_err[ATH10K_PKT_RX_ERR_MAX];
unsigned long int rx_pkt_queued_for_mac; unsigned long rx_pkt_queued_for_mac;
unsigned long int rx_pkt_ampdu[ATH10K_AMPDU_SUBFRM_NUM_MAX]; unsigned long rx_pkt_ampdu[ATH10K_AMPDU_SUBFRM_NUM_MAX];
unsigned long int rx_pkt_amsdu[ATH10K_AMSDU_SUBFRM_NUM_MAX]; unsigned long rx_pkt_amsdu[ATH10K_AMSDU_SUBFRM_NUM_MAX];
}; };
enum ath10k_counter_type { enum ath10k_counter_type {
@ -495,6 +489,7 @@ struct ath10k_sta {
u16 peer_id; u16 peer_id;
struct rate_info txrate; struct rate_info txrate;
struct ieee80211_tx_info tx_info; struct ieee80211_tx_info tx_info;
u32 last_tx_bitrate;
struct work_struct update_wk; struct work_struct update_wk;
u64 rx_duration; u64 rx_duration;
@ -571,6 +566,7 @@ struct ath10k_vif {
bool nohwcrypt; bool nohwcrypt;
int num_legacy_stations; int num_legacy_stations;
int txpower; int txpower;
bool ftm_responder;
struct wmi_wmm_params_all_arg wmm_params; struct wmi_wmm_params_all_arg wmm_params;
struct work_struct ap_csa_work; struct work_struct ap_csa_work;
struct delayed_work connection_loss_work; struct delayed_work connection_loss_work;
@ -922,6 +918,7 @@ enum ath10k_dev_type {
struct ath10k_bus_params { struct ath10k_bus_params {
u32 chip_id; u32 chip_id;
enum ath10k_dev_type dev_type; enum ath10k_dev_type dev_type;
bool link_can_suspend;
}; };
struct ath10k { struct ath10k {
@ -1068,10 +1065,7 @@ struct ath10k {
/* protects shared structure data */ /* protects shared structure data */
spinlock_t data_lock; spinlock_t data_lock;
/* protects: ar->txqs, artxq->list */
spinlock_t txqs_lock;
struct list_head txqs;
struct list_head arvifs; struct list_head arvifs;
struct list_head peers; struct list_head peers;
struct ath10k_peer *peer_map[ATH10K_MAX_NUM_PEER_IDS]; struct ath10k_peer *peer_map[ATH10K_MAX_NUM_PEER_IDS];
@ -1182,6 +1176,7 @@ struct ath10k {
u32 ampdu_reference; u32 ampdu_reference;
const u8 *wmi_key_cipher;
void *ce_priv; void *ce_priv;
u32 sta_tid_stats_mask; u32 sta_tid_stats_mask;
@ -1190,6 +1185,7 @@ struct ath10k {
enum ath10k_radar_confirmation_state radar_conf_state; enum ath10k_radar_confirmation_state radar_conf_state;
struct ath10k_radar_found_info last_radar_info; struct ath10k_radar_found_info last_radar_info;
struct work_struct radar_confirmation_work; struct work_struct radar_confirmation_work;
struct ath10k_bus_params bus_param;
/* must be last */ /* must be last */
u8 drv_priv[0] __aligned(sizeof(void *)); u8 drv_priv[0] __aligned(sizeof(void *));

View File

@ -1,18 +1,7 @@
// SPDX-License-Identifier: ISC
/* /*
* Copyright (c) 2011-2017 Qualcomm Atheros, Inc. * Copyright (c) 2011-2017 Qualcomm Atheros, Inc.
* Copyright (c) 2018, The Linux Foundation. All rights reserved. * Copyright (c) 2018, The Linux Foundation. All rights reserved.
*
* Permission to use, copy, modify, and/or distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/ */
#include "coredump.h" #include "coredump.h"
@ -1167,7 +1156,7 @@ static struct ath10k_dump_file_data *ath10k_coredump_build(struct ath10k *ar)
dump_data->version = cpu_to_le32(ATH10K_FW_CRASH_DUMP_VERSION); dump_data->version = cpu_to_le32(ATH10K_FW_CRASH_DUMP_VERSION);
guid_copy(&dump_data->guid, &crash_data->guid); guid_copy(&dump_data->guid, &crash_data->guid);
dump_data->chip_id = cpu_to_le32(ar->chip_id); dump_data->chip_id = cpu_to_le32(ar->bus_param.chip_id);
dump_data->bus_type = cpu_to_le32(0); dump_data->bus_type = cpu_to_le32(0);
dump_data->target_version = cpu_to_le32(ar->target_version); dump_data->target_version = cpu_to_le32(ar->target_version);
dump_data->fw_version_major = cpu_to_le32(ar->fw_version_major); dump_data->fw_version_major = cpu_to_le32(ar->fw_version_major);

View File

@ -1,17 +1,6 @@
/* SPDX-License-Identifier: ISC */
/* /*
* Copyright (c) 2011-2017 Qualcomm Atheros, Inc. * Copyright (c) 2011-2017 Qualcomm Atheros, Inc.
*
* Permission to use, copy, modify, and/or distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/ */
#ifndef _COREDUMP_H_ #ifndef _COREDUMP_H_

View File

@ -1,19 +1,8 @@
// SPDX-License-Identifier: ISC
/* /*
* Copyright (c) 2005-2011 Atheros Communications Inc. * Copyright (c) 2005-2011 Atheros Communications Inc.
* Copyright (c) 2011-2017 Qualcomm Atheros, Inc. * Copyright (c) 2011-2017 Qualcomm Atheros, Inc.
* Copyright (c) 2018, The Linux Foundation. All rights reserved. * Copyright (c) 2018, The Linux Foundation. All rights reserved.
*
* Permission to use, copy, modify, and/or distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/ */
#include <linux/module.h> #include <linux/module.h>
@ -58,7 +47,7 @@ void ath10k_debug_print_hwfw_info(struct ath10k *ar)
ath10k_info(ar, "%s target 0x%08x chip_id 0x%08x sub %04x:%04x", ath10k_info(ar, "%s target 0x%08x chip_id 0x%08x sub %04x:%04x",
ar->hw_params.name, ar->hw_params.name,
ar->target_version, ar->target_version,
ar->chip_id, ar->bus_param.chip_id,
ar->id.subsystem_vendor, ar->id.subsystem_device); ar->id.subsystem_vendor, ar->id.subsystem_device);
ath10k_info(ar, "kconfig debug %d debugfs %d tracing %d dfs %d testmode %d\n", ath10k_info(ar, "kconfig debug %d debugfs %d tracing %d dfs %d testmode %d\n",
@ -625,7 +614,7 @@ static ssize_t ath10k_read_chip_id(struct file *file, char __user *user_buf,
size_t len; size_t len;
char buf[50]; char buf[50];
len = scnprintf(buf, sizeof(buf), "0x%08x\n", ar->chip_id); len = scnprintf(buf, sizeof(buf), "0x%08x\n", ar->bus_param.chip_id);
return simple_read_from_buffer(user_buf, count, ppos, buf, len); return simple_read_from_buffer(user_buf, count, ppos, buf, len);
} }

View File

@ -1,19 +1,8 @@
/* SPDX-License-Identifier: ISC */
/* /*
* Copyright (c) 2005-2011 Atheros Communications Inc. * Copyright (c) 2005-2011 Atheros Communications Inc.
* Copyright (c) 2011-2017 Qualcomm Atheros, Inc. * Copyright (c) 2011-2017 Qualcomm Atheros, Inc.
* Copyright (c) 2018, The Linux Foundation. All rights reserved. * Copyright (c) 2018, The Linux Foundation. All rights reserved.
*
* Permission to use, copy, modify, and/or distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/ */
#ifndef _DEBUG_H_ #ifndef _DEBUG_H_
@ -213,12 +202,12 @@ void ath10k_sta_add_debugfs(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
void ath10k_sta_update_rx_duration(struct ath10k *ar, void ath10k_sta_update_rx_duration(struct ath10k *ar,
struct ath10k_fw_stats *stats); struct ath10k_fw_stats *stats);
void ath10k_sta_update_rx_tid_stats(struct ath10k *ar, u8 *first_hdr, void ath10k_sta_update_rx_tid_stats(struct ath10k *ar, u8 *first_hdr,
unsigned long int num_msdus, unsigned long num_msdus,
enum ath10k_pkt_rx_err err, enum ath10k_pkt_rx_err err,
unsigned long int unchain_cnt, unsigned long unchain_cnt,
unsigned long int drop_cnt, unsigned long drop_cnt,
unsigned long int drop_cnt_filter, unsigned long drop_cnt_filter,
unsigned long int queued_msdus); unsigned long queued_msdus);
void ath10k_sta_update_rx_tid_stats_ampdu(struct ath10k *ar, void ath10k_sta_update_rx_tid_stats_ampdu(struct ath10k *ar,
u16 peer_id, u8 tid, u16 peer_id, u8 tid,
struct htt_rx_indication_mpdu_range *ranges, struct htt_rx_indication_mpdu_range *ranges,
@ -232,12 +221,12 @@ void ath10k_sta_update_rx_duration(struct ath10k *ar,
static inline static inline
void ath10k_sta_update_rx_tid_stats(struct ath10k *ar, u8 *first_hdr, void ath10k_sta_update_rx_tid_stats(struct ath10k *ar, u8 *first_hdr,
unsigned long int num_msdus, unsigned long num_msdus,
enum ath10k_pkt_rx_err err, enum ath10k_pkt_rx_err err,
unsigned long int unchain_cnt, unsigned long unchain_cnt,
unsigned long int drop_cnt, unsigned long drop_cnt,
unsigned long int drop_cnt_filter, unsigned long drop_cnt_filter,
unsigned long int queued_msdus) unsigned long queued_msdus)
{ {
} }

View File

@ -1,18 +1,7 @@
// SPDX-License-Identifier: ISC
/* /*
* Copyright (c) 2014-2017 Qualcomm Atheros, Inc. * Copyright (c) 2014-2017 Qualcomm Atheros, Inc.
* Copyright (c) 2018, The Linux Foundation. All rights reserved. * Copyright (c) 2018, The Linux Foundation. All rights reserved.
*
* Permission to use, copy, modify, and/or distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/ */
#include "core.h" #include "core.h"
@ -87,12 +76,12 @@ void ath10k_sta_update_rx_tid_stats_ampdu(struct ath10k *ar, u16 peer_id, u8 tid
} }
void ath10k_sta_update_rx_tid_stats(struct ath10k *ar, u8 *first_hdr, void ath10k_sta_update_rx_tid_stats(struct ath10k *ar, u8 *first_hdr,
unsigned long int num_msdus, unsigned long num_msdus,
enum ath10k_pkt_rx_err err, enum ath10k_pkt_rx_err err,
unsigned long int unchain_cnt, unsigned long unchain_cnt,
unsigned long int drop_cnt, unsigned long drop_cnt,
unsigned long int drop_cnt_filter, unsigned long drop_cnt_filter,
unsigned long int queued_msdus) unsigned long queued_msdus)
{ {
struct ieee80211_sta *sta; struct ieee80211_sta *sta;
struct ath10k_sta *arsta; struct ath10k_sta *arsta;

View File

@ -1,18 +1,7 @@
/* SPDX-License-Identifier: ISC */
/* /*
* Copyright (c) 2005-2011 Atheros Communications Inc. * Copyright (c) 2005-2011 Atheros Communications Inc.
* Copyright (c) 2011-2015,2017 Qualcomm Atheros, Inc. * Copyright (c) 2011-2015,2017 Qualcomm Atheros, Inc.
*
* Permission to use, copy, modify, and/or distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/ */
#ifndef _HIF_H_ #ifndef _HIF_H_
@ -59,6 +48,8 @@ struct ath10k_hif_ops {
*/ */
void (*stop)(struct ath10k *ar); void (*stop)(struct ath10k *ar);
int (*swap_mailbox)(struct ath10k *ar);
int (*map_service_to_pipe)(struct ath10k *ar, u16 service_id, int (*map_service_to_pipe)(struct ath10k *ar, u16 service_id,
u8 *ul_pipe, u8 *dl_pipe); u8 *ul_pipe, u8 *dl_pipe);
@ -81,7 +72,7 @@ struct ath10k_hif_ops {
void (*write32)(struct ath10k *ar, u32 address, u32 value); void (*write32)(struct ath10k *ar, u32 address, u32 value);
/* Power up the device and enter BMI transfer mode for FW download */ /* Power up the device and enter BMI transfer mode for FW download */
int (*power_up)(struct ath10k *ar); int (*power_up)(struct ath10k *ar, enum ath10k_firmware_mode fw_mode);
/* Power down the device and free up resources. stop() must be called /* Power down the device and free up resources. stop() must be called
* before this if start() was called earlier * before this if start() was called earlier
@ -139,6 +130,13 @@ static inline void ath10k_hif_stop(struct ath10k *ar)
return ar->hif.ops->stop(ar); return ar->hif.ops->stop(ar);
} }
static inline int ath10k_hif_swap_mailbox(struct ath10k *ar)
{
if (ar->hif.ops->swap_mailbox)
return ar->hif.ops->swap_mailbox(ar);
return 0;
}
static inline int ath10k_hif_map_service_to_pipe(struct ath10k *ar, static inline int ath10k_hif_map_service_to_pipe(struct ath10k *ar,
u16 service_id, u16 service_id,
u8 *ul_pipe, u8 *dl_pipe) u8 *ul_pipe, u8 *dl_pipe)
@ -165,9 +163,10 @@ static inline u16 ath10k_hif_get_free_queue_number(struct ath10k *ar,
return ar->hif.ops->get_free_queue_number(ar, pipe_id); return ar->hif.ops->get_free_queue_number(ar, pipe_id);
} }
static inline int ath10k_hif_power_up(struct ath10k *ar) static inline int ath10k_hif_power_up(struct ath10k *ar,
enum ath10k_firmware_mode fw_mode)
{ {
return ar->hif.ops->power_up(ar); return ar->hif.ops->power_up(ar, fw_mode);
} }
static inline void ath10k_hif_power_down(struct ath10k *ar) static inline void ath10k_hif_power_down(struct ath10k *ar)

View File

@ -1,18 +1,7 @@
// SPDX-License-Identifier: ISC
/* /*
* Copyright (c) 2005-2011 Atheros Communications Inc. * Copyright (c) 2005-2011 Atheros Communications Inc.
* Copyright (c) 2011-2017 Qualcomm Atheros, Inc. * Copyright (c) 2011-2017 Qualcomm Atheros, Inc.
*
* Permission to use, copy, modify, and/or distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/ */
#include "core.h" #include "core.h"
@ -53,7 +42,7 @@ static inline void ath10k_htc_restore_tx_skb(struct ath10k_htc *htc,
{ {
struct ath10k_skb_cb *skb_cb = ATH10K_SKB_CB(skb); struct ath10k_skb_cb *skb_cb = ATH10K_SKB_CB(skb);
if (htc->ar->dev_type != ATH10K_DEV_TYPE_HL) if (htc->ar->bus_param.dev_type != ATH10K_DEV_TYPE_HL)
dma_unmap_single(htc->ar->dev, skb_cb->paddr, skb->len, DMA_TO_DEVICE); dma_unmap_single(htc->ar->dev, skb_cb->paddr, skb->len, DMA_TO_DEVICE);
skb_pull(skb, sizeof(struct ath10k_htc_hdr)); skb_pull(skb, sizeof(struct ath10k_htc_hdr));
} }
@ -88,6 +77,7 @@ static void ath10k_htc_prepare_tx_skb(struct ath10k_htc_ep *ep,
hdr->eid = ep->eid; hdr->eid = ep->eid;
hdr->len = __cpu_to_le16(skb->len - sizeof(*hdr)); hdr->len = __cpu_to_le16(skb->len - sizeof(*hdr));
hdr->flags = 0; hdr->flags = 0;
if (ep->tx_credit_flow_enabled)
hdr->flags |= ATH10K_HTC_FLAG_NEED_CREDIT_UPDATE; hdr->flags |= ATH10K_HTC_FLAG_NEED_CREDIT_UPDATE;
spin_lock_bh(&ep->htc->tx_lock); spin_lock_bh(&ep->htc->tx_lock);
@ -138,7 +128,7 @@ int ath10k_htc_send(struct ath10k_htc *htc,
ath10k_htc_prepare_tx_skb(ep, skb); ath10k_htc_prepare_tx_skb(ep, skb);
skb_cb->eid = eid; skb_cb->eid = eid;
if (ar->dev_type != ATH10K_DEV_TYPE_HL) { if (ar->bus_param.dev_type != ATH10K_DEV_TYPE_HL) {
skb_cb->paddr = dma_map_single(dev, skb->data, skb->len, skb_cb->paddr = dma_map_single(dev, skb->data, skb->len,
DMA_TO_DEVICE); DMA_TO_DEVICE);
ret = dma_mapping_error(dev, skb_cb->paddr); ret = dma_mapping_error(dev, skb_cb->paddr);
@ -161,7 +151,7 @@ int ath10k_htc_send(struct ath10k_htc *htc,
return 0; return 0;
err_unmap: err_unmap:
if (ar->dev_type != ATH10K_DEV_TYPE_HL) if (ar->bus_param.dev_type != ATH10K_DEV_TYPE_HL)
dma_unmap_single(dev, skb_cb->paddr, skb->len, DMA_TO_DEVICE); dma_unmap_single(dev, skb_cb->paddr, skb->len, DMA_TO_DEVICE);
err_credits: err_credits:
if (ep->tx_credit_flow_enabled) { if (ep->tx_credit_flow_enabled) {

View File

@ -1,18 +1,7 @@
/* SPDX-License-Identifier: ISC */
/* /*
* Copyright (c) 2005-2011 Atheros Communications Inc. * Copyright (c) 2005-2011 Atheros Communications Inc.
* Copyright (c) 2011-2016 Qualcomm Atheros, Inc. * Copyright (c) 2011-2016 Qualcomm Atheros, Inc.
*
* Permission to use, copy, modify, and/or distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/ */
#ifndef _HTC_H_ #ifndef _HTC_H_
@ -51,7 +40,6 @@ struct ath10k;
*/ */
#define HTC_HOST_MAX_MSG_PER_RX_BUNDLE 8 #define HTC_HOST_MAX_MSG_PER_RX_BUNDLE 8
#define HTC_HOST_MAX_MSG_PER_TX_BUNDLE 16
enum ath10k_htc_tx_flags { enum ath10k_htc_tx_flags {
ATH10K_HTC_FLAG_NEED_CREDIT_UPDATE = 0x01, ATH10K_HTC_FLAG_NEED_CREDIT_UPDATE = 0x01,

View File

@ -1,18 +1,7 @@
// SPDX-License-Identifier: ISC
/* /*
* Copyright (c) 2005-2011 Atheros Communications Inc. * Copyright (c) 2005-2011 Atheros Communications Inc.
* Copyright (c) 2011-2017 Qualcomm Atheros, Inc. * Copyright (c) 2011-2017 Qualcomm Atheros, Inc.
*
* Permission to use, copy, modify, and/or distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/ */
#include <linux/slab.h> #include <linux/slab.h>
@ -268,7 +257,7 @@ int ath10k_htt_setup(struct ath10k_htt *htt)
return status; return status;
} }
status = ath10k_htt_h2t_aggr_cfg_msg(htt, status = htt->tx_ops->htt_h2t_aggr_cfg_msg(htt,
htt->max_num_ampdu, htt->max_num_ampdu,
htt->max_num_amsdu); htt->max_num_amsdu);
if (status) { if (status) {

View File

@ -1,19 +1,8 @@
/* SPDX-License-Identifier: ISC */
/* /*
* Copyright (c) 2005-2011 Atheros Communications Inc. * Copyright (c) 2005-2011 Atheros Communications Inc.
* Copyright (c) 2011-2017 Qualcomm Atheros, Inc. * Copyright (c) 2011-2017 Qualcomm Atheros, Inc.
* Copyright (c) 2018, The Linux Foundation. All rights reserved. * Copyright (c) 2018, The Linux Foundation. All rights reserved.
*
* Permission to use, copy, modify, and/or distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/ */
#ifndef _HTT_H_ #ifndef _HTT_H_
@ -357,6 +346,13 @@ struct htt_aggr_conf {
u8 max_num_amsdu_subframes; u8 max_num_amsdu_subframes;
} __packed; } __packed;
struct htt_aggr_conf_v2 {
u8 max_num_ampdu_subframes;
/* amsdu_subframes is limited by 0x1F mask */
u8 max_num_amsdu_subframes;
u8 reserved;
} __packed;
#define HTT_MGMT_FRM_HDR_DOWNLOAD_LEN 32 #define HTT_MGMT_FRM_HDR_DOWNLOAD_LEN 32
struct htt_mgmt_tx_desc_qca99x0 { struct htt_mgmt_tx_desc_qca99x0 {
__le32 rate; __le32 rate;
@ -564,6 +560,7 @@ struct htt_mgmt_tx_completion {
#define HTT_RX_INDICATION_INFO0_EXT_TID_LSB (0) #define HTT_RX_INDICATION_INFO0_EXT_TID_LSB (0)
#define HTT_RX_INDICATION_INFO0_FLUSH_VALID (1 << 5) #define HTT_RX_INDICATION_INFO0_FLUSH_VALID (1 << 5)
#define HTT_RX_INDICATION_INFO0_RELEASE_VALID (1 << 6) #define HTT_RX_INDICATION_INFO0_RELEASE_VALID (1 << 6)
#define HTT_RX_INDICATION_INFO0_PPDU_DURATION BIT(7)
#define HTT_RX_INDICATION_INFO1_FLUSH_START_SEQNO_MASK 0x0000003F #define HTT_RX_INDICATION_INFO1_FLUSH_START_SEQNO_MASK 0x0000003F
#define HTT_RX_INDICATION_INFO1_FLUSH_START_SEQNO_LSB 0 #define HTT_RX_INDICATION_INFO1_FLUSH_START_SEQNO_LSB 0
@ -577,6 +574,9 @@ struct htt_mgmt_tx_completion {
#define HTT_RX_INDICATION_INFO1_NUM_MPDU_RANGES_LSB 24 #define HTT_RX_INDICATION_INFO1_NUM_MPDU_RANGES_LSB 24
#define HTT_TX_CMPL_FLAG_DATA_RSSI BIT(0) #define HTT_TX_CMPL_FLAG_DATA_RSSI BIT(0)
#define HTT_TX_CMPL_FLAG_PPID_PRESENT BIT(1)
#define HTT_TX_CMPL_FLAG_PA_PRESENT BIT(2)
#define HTT_TX_CMPL_FLAG_PPDU_DURATION_PRESENT BIT(3)
struct htt_rx_indication_hdr { struct htt_rx_indication_hdr {
u8 info0; /* %HTT_RX_INDICATION_INFO0_ */ u8 info0; /* %HTT_RX_INDICATION_INFO0_ */
@ -866,6 +866,21 @@ struct htt_data_tx_completion {
__le16 msdus[0]; /* variable length based on %num_msdus */ __le16 msdus[0]; /* variable length based on %num_msdus */
} __packed; } __packed;
#define HTT_TX_PPDU_DUR_INFO0_PEER_ID_MASK GENMASK(15, 0)
#define HTT_TX_PPDU_DUR_INFO0_TID_MASK GENMASK(20, 16)
struct htt_data_tx_ppdu_dur {
__le32 info0; /* HTT_TX_PPDU_DUR_INFO0_ */
__le32 tx_duration; /* in usecs */
} __packed;
#define HTT_TX_COMPL_PPDU_DUR_INFO0_NUM_ENTRIES_MASK GENMASK(7, 0)
struct htt_data_tx_compl_ppdu_dur {
__le32 info0; /* HTT_TX_COMPL_PPDU_DUR_INFO0_ */
struct htt_data_tx_ppdu_dur ppdu_dur[0];
} __packed;
struct htt_tx_compl_ind_base { struct htt_tx_compl_ind_base {
u32 hdr; u32 hdr;
u16 payload[1/*or more*/]; u16 payload[1/*or more*/];
@ -1650,6 +1665,7 @@ struct htt_cmd {
struct htt_stats_req stats_req; struct htt_stats_req stats_req;
struct htt_oob_sync_req oob_sync_req; struct htt_oob_sync_req oob_sync_req;
struct htt_aggr_conf aggr_conf; struct htt_aggr_conf aggr_conf;
struct htt_aggr_conf_v2 aggr_conf_v2;
struct htt_frag_desc_bank_cfg32 frag_desc_bank_cfg32; struct htt_frag_desc_bank_cfg32 frag_desc_bank_cfg32;
struct htt_frag_desc_bank_cfg64 frag_desc_bank_cfg64; struct htt_frag_desc_bank_cfg64 frag_desc_bank_cfg64;
struct htt_tx_fetch_resp tx_fetch_resp; struct htt_tx_fetch_resp tx_fetch_resp;
@ -1716,14 +1732,14 @@ struct ath10k_htt_txbuf_32 {
struct ath10k_htc_hdr htc_hdr; struct ath10k_htc_hdr htc_hdr;
struct htt_cmd_hdr cmd_hdr; struct htt_cmd_hdr cmd_hdr;
struct htt_data_tx_desc cmd_tx; struct htt_data_tx_desc cmd_tx;
} __packed; } __packed __aligned(4);
struct ath10k_htt_txbuf_64 { struct ath10k_htt_txbuf_64 {
struct htt_data_tx_desc_frag frags[2]; struct htt_data_tx_desc_frag frags[2];
struct ath10k_htc_hdr htc_hdr; struct ath10k_htc_hdr htc_hdr;
struct htt_cmd_hdr cmd_hdr; struct htt_cmd_hdr cmd_hdr;
struct htt_data_tx_desc_64 cmd_tx; struct htt_data_tx_desc_64 cmd_tx;
} __packed; } __packed __aligned(4);
struct ath10k_htt { struct ath10k_htt {
struct ath10k *ar; struct ath10k *ar;
@ -1890,6 +1906,9 @@ struct ath10k_htt_tx_ops {
struct sk_buff *msdu); struct sk_buff *msdu);
int (*htt_alloc_txbuff)(struct ath10k_htt *htt); int (*htt_alloc_txbuff)(struct ath10k_htt *htt);
void (*htt_free_txbuff)(struct ath10k_htt *htt); void (*htt_free_txbuff)(struct ath10k_htt *htt);
int (*htt_h2t_aggr_cfg_msg)(struct ath10k_htt *htt,
u8 max_subfrms_ampdu,
u8 max_subfrms_amsdu);
}; };
static inline int ath10k_htt_send_rx_ring_cfg(struct ath10k_htt *htt) static inline int ath10k_htt_send_rx_ring_cfg(struct ath10k_htt *htt)

View File

@ -1,19 +1,8 @@
// SPDX-License-Identifier: ISC
/* /*
* Copyright (c) 2005-2011 Atheros Communications Inc. * Copyright (c) 2005-2011 Atheros Communications Inc.
* Copyright (c) 2011-2017 Qualcomm Atheros, Inc. * Copyright (c) 2011-2017 Qualcomm Atheros, Inc.
* Copyright (c) 2018, The Linux Foundation. All rights reserved. * Copyright (c) 2018, The Linux Foundation. All rights reserved.
*
* Permission to use, copy, modify, and/or distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/ */
#include "core.h" #include "core.h"
@ -265,7 +254,7 @@ int ath10k_htt_rx_ring_refill(struct ath10k *ar)
struct ath10k_htt *htt = &ar->htt; struct ath10k_htt *htt = &ar->htt;
int ret; int ret;
if (ar->dev_type == ATH10K_DEV_TYPE_HL) if (ar->bus_param.dev_type == ATH10K_DEV_TYPE_HL)
return 0; return 0;
spin_lock_bh(&htt->rx_ring.lock); spin_lock_bh(&htt->rx_ring.lock);
@ -282,7 +271,7 @@ int ath10k_htt_rx_ring_refill(struct ath10k *ar)
void ath10k_htt_rx_free(struct ath10k_htt *htt) void ath10k_htt_rx_free(struct ath10k_htt *htt)
{ {
if (htt->ar->dev_type == ATH10K_DEV_TYPE_HL) if (htt->ar->bus_param.dev_type == ATH10K_DEV_TYPE_HL)
return; return;
del_timer_sync(&htt->rx_ring.refill_retry_timer); del_timer_sync(&htt->rx_ring.refill_retry_timer);
@ -760,7 +749,7 @@ int ath10k_htt_rx_alloc(struct ath10k_htt *htt)
size_t size; size_t size;
struct timer_list *timer = &htt->rx_ring.refill_retry_timer; struct timer_list *timer = &htt->rx_ring.refill_retry_timer;
if (ar->dev_type == ATH10K_DEV_TYPE_HL) if (ar->bus_param.dev_type == ATH10K_DEV_TYPE_HL)
return 0; return 0;
htt->rx_confused = false; htt->rx_confused = false;
@ -1905,7 +1894,7 @@ static void ath10k_htt_rx_h_enqueue(struct ath10k *ar,
} }
static int ath10k_unchain_msdu(struct sk_buff_head *amsdu, static int ath10k_unchain_msdu(struct sk_buff_head *amsdu,
unsigned long int *unchain_cnt) unsigned long *unchain_cnt)
{ {
struct sk_buff *skb, *first; struct sk_buff *skb, *first;
int space; int space;
@ -1954,8 +1943,8 @@ static int ath10k_unchain_msdu(struct sk_buff_head *amsdu,
static void ath10k_htt_rx_h_unchain(struct ath10k *ar, static void ath10k_htt_rx_h_unchain(struct ath10k *ar,
struct sk_buff_head *amsdu, struct sk_buff_head *amsdu,
unsigned long int *drop_cnt, unsigned long *drop_cnt,
unsigned long int *unchain_cnt) unsigned long *unchain_cnt)
{ {
struct sk_buff *first; struct sk_buff *first;
struct htt_rx_desc *rxd; struct htt_rx_desc *rxd;
@ -2005,7 +1994,7 @@ static bool ath10k_htt_rx_amsdu_allowed(struct ath10k *ar,
static void ath10k_htt_rx_h_filter(struct ath10k *ar, static void ath10k_htt_rx_h_filter(struct ath10k *ar,
struct sk_buff_head *amsdu, struct sk_buff_head *amsdu,
struct ieee80211_rx_status *rx_status, struct ieee80211_rx_status *rx_status,
unsigned long int *drop_cnt) unsigned long *drop_cnt)
{ {
if (skb_queue_empty(amsdu)) if (skb_queue_empty(amsdu))
return; return;
@ -2025,10 +2014,10 @@ static int ath10k_htt_rx_handle_amsdu(struct ath10k_htt *htt)
struct ieee80211_rx_status *rx_status = &htt->rx_status; struct ieee80211_rx_status *rx_status = &htt->rx_status;
struct sk_buff_head amsdu; struct sk_buff_head amsdu;
int ret; int ret;
unsigned long int drop_cnt = 0; unsigned long drop_cnt = 0;
unsigned long int unchain_cnt = 0; unsigned long unchain_cnt = 0;
unsigned long int drop_cnt_filter = 0; unsigned long drop_cnt_filter = 0;
unsigned long int msdus_to_queue, num_msdus; unsigned long msdus_to_queue, num_msdus;
enum ath10k_pkt_rx_err err = ATH10K_PKT_RX_ERR_MAX; enum ath10k_pkt_rx_err err = ATH10K_PKT_RX_ERR_MAX;
u8 first_hdr[RX_HTT_HDR_STATUS_LEN]; u8 first_hdr[RX_HTT_HDR_STATUS_LEN];
@ -2220,8 +2209,12 @@ static void ath10k_htt_rx_tx_compl_ind(struct ath10k *ar,
int status = MS(resp->data_tx_completion.flags, HTT_DATA_TX_STATUS); int status = MS(resp->data_tx_completion.flags, HTT_DATA_TX_STATUS);
__le16 msdu_id, *msdus; __le16 msdu_id, *msdus;
bool rssi_enabled = false; bool rssi_enabled = false;
u8 msdu_count = 0; u8 msdu_count = 0, num_airtime_records, tid;
int i; int i;
struct htt_data_tx_compl_ppdu_dur *ppdu_info;
struct ath10k_peer *peer;
u16 ppdu_info_offset = 0, peer_id;
u32 tx_duration;
switch (status) { switch (status) {
case HTT_DATA_TX_STATUS_NO_ACK: case HTT_DATA_TX_STATUS_NO_ACK:
@ -2245,12 +2238,12 @@ static void ath10k_htt_rx_tx_compl_ind(struct ath10k *ar,
resp->data_tx_completion.num_msdus); resp->data_tx_completion.num_msdus);
msdu_count = resp->data_tx_completion.num_msdus; msdu_count = resp->data_tx_completion.num_msdus;
msdus = resp->data_tx_completion.msdus;
if (resp->data_tx_completion.flags2 & HTT_TX_CMPL_FLAG_DATA_RSSI) if (resp->data_tx_completion.flags2 & HTT_TX_CMPL_FLAG_DATA_RSSI)
rssi_enabled = true; rssi_enabled = true;
for (i = 0; i < msdu_count; i++) { for (i = 0; i < msdu_count; i++) {
msdus = resp->data_tx_completion.msdus;
msdu_id = msdus[i]; msdu_id = msdus[i];
tx_done.msdu_id = __le16_to_cpu(msdu_id); tx_done.msdu_id = __le16_to_cpu(msdu_id);
@ -2282,6 +2275,50 @@ static void ath10k_htt_rx_tx_compl_ind(struct ath10k *ar,
ath10k_txrx_tx_unref(htt, &tx_done); ath10k_txrx_tx_unref(htt, &tx_done);
} }
} }
if (!(resp->data_tx_completion.flags2 & HTT_TX_CMPL_FLAG_PPDU_DURATION_PRESENT))
return;
ppdu_info_offset = (msdu_count & 0x01) ? msdu_count + 1 : msdu_count;
if (rssi_enabled)
ppdu_info_offset += ppdu_info_offset;
if (resp->data_tx_completion.flags2 &
(HTT_TX_CMPL_FLAG_PPID_PRESENT | HTT_TX_CMPL_FLAG_PA_PRESENT))
ppdu_info_offset += 2;
ppdu_info = (struct htt_data_tx_compl_ppdu_dur *)&msdus[ppdu_info_offset];
num_airtime_records = FIELD_GET(HTT_TX_COMPL_PPDU_DUR_INFO0_NUM_ENTRIES_MASK,
__le32_to_cpu(ppdu_info->info0));
for (i = 0; i < num_airtime_records; i++) {
struct htt_data_tx_ppdu_dur *ppdu_dur;
u32 info0;
ppdu_dur = &ppdu_info->ppdu_dur[i];
info0 = __le32_to_cpu(ppdu_dur->info0);
peer_id = FIELD_GET(HTT_TX_PPDU_DUR_INFO0_PEER_ID_MASK,
info0);
rcu_read_lock();
spin_lock_bh(&ar->data_lock);
peer = ath10k_peer_find_by_id(ar, peer_id);
if (!peer) {
spin_unlock_bh(&ar->data_lock);
rcu_read_unlock();
continue;
}
tid = FIELD_GET(HTT_TX_PPDU_DUR_INFO0_TID_MASK, info0);
tx_duration = __le32_to_cpu(ppdu_dur->tx_duration);
ieee80211_sta_register_airtime(peer->sta, tid, tx_duration, 0);
spin_unlock_bh(&ar->data_lock);
rcu_read_unlock();
}
} }
static void ath10k_htt_rx_addba(struct ath10k *ar, struct htt_resp *resp) static void ath10k_htt_rx_addba(struct ath10k *ar, struct htt_resp *resp)
@ -2596,6 +2633,7 @@ static void ath10k_htt_rx_tx_fetch_ind(struct ath10k *ar, struct sk_buff *skb)
u8 tid; u8 tid;
int ret; int ret;
int i; int i;
bool may_tx;
ath10k_dbg(ar, ATH10K_DBG_HTT, "htt rx tx fetch ind\n"); ath10k_dbg(ar, ATH10K_DBG_HTT, "htt rx tx fetch ind\n");
@ -2668,8 +2706,13 @@ static void ath10k_htt_rx_tx_fetch_ind(struct ath10k *ar, struct sk_buff *skb)
num_msdus = 0; num_msdus = 0;
num_bytes = 0; num_bytes = 0;
ieee80211_txq_schedule_start(hw, txq->ac);
may_tx = ieee80211_txq_may_transmit(hw, txq);
while (num_msdus < max_num_msdus && while (num_msdus < max_num_msdus &&
num_bytes < max_num_bytes) { num_bytes < max_num_bytes) {
if (!may_tx)
break;
ret = ath10k_mac_tx_push_txq(hw, txq); ret = ath10k_mac_tx_push_txq(hw, txq);
if (ret < 0) if (ret < 0)
break; break;
@ -2677,6 +2720,8 @@ static void ath10k_htt_rx_tx_fetch_ind(struct ath10k *ar, struct sk_buff *skb)
num_msdus++; num_msdus++;
num_bytes += ret; num_bytes += ret;
} }
ieee80211_return_txq(hw, txq);
ieee80211_txq_schedule_end(hw, txq->ac);
record->num_msdus = cpu_to_le16(num_msdus); record->num_msdus = cpu_to_le16(num_msdus);
record->num_bytes = cpu_to_le32(num_bytes); record->num_bytes = cpu_to_le32(num_bytes);
@ -2975,6 +3020,8 @@ ath10k_accumulate_per_peer_tx_stats(struct ath10k *ar,
STATS_OP_FMT(RETRY).rate_table[0][idx] += pstats->retry_bytes; STATS_OP_FMT(RETRY).rate_table[0][idx] += pstats->retry_bytes;
STATS_OP_FMT(RETRY).rate_table[1][idx] += pstats->retry_pkts; STATS_OP_FMT(RETRY).rate_table[1][idx] += pstats->retry_pkts;
} }
tx_stats->tx_duration += pstats->duration;
} }
static void static void
@ -3070,6 +3117,7 @@ ath10k_update_per_peer_tx_stats(struct ath10k *ar,
arsta->txrate.nss = txrate.nss; arsta->txrate.nss = txrate.nss;
arsta->txrate.bw = ath10k_bw_to_mac80211_bw(txrate.bw); arsta->txrate.bw = ath10k_bw_to_mac80211_bw(txrate.bw);
arsta->last_tx_bitrate = cfg80211_calculate_bitrate(&arsta->txrate);
if (sgi) if (sgi)
arsta->txrate.flags |= RATE_INFO_FLAGS_SHORT_GI; arsta->txrate.flags |= RATE_INFO_FLAGS_SHORT_GI;
@ -3141,6 +3189,7 @@ static void ath10k_htt_fetch_peer_stats(struct ath10k *ar,
p_tx_stats->succ_pkts = __le16_to_cpu(tx_stats->succ_pkts); p_tx_stats->succ_pkts = __le16_to_cpu(tx_stats->succ_pkts);
p_tx_stats->retry_pkts = __le16_to_cpu(tx_stats->retry_pkts); p_tx_stats->retry_pkts = __le16_to_cpu(tx_stats->retry_pkts);
p_tx_stats->failed_pkts = __le16_to_cpu(tx_stats->failed_pkts); p_tx_stats->failed_pkts = __le16_to_cpu(tx_stats->failed_pkts);
p_tx_stats->duration = __le16_to_cpu(tx_stats->tx_duration);
ath10k_update_per_peer_tx_stats(ar, sta, p_tx_stats); ath10k_update_per_peer_tx_stats(ar, sta, p_tx_stats);
} }
@ -3234,7 +3283,7 @@ bool ath10k_htt_t2h_msg_handler(struct ath10k *ar, struct sk_buff *skb)
break; break;
} }
case HTT_T2H_MSG_TYPE_RX_IND: case HTT_T2H_MSG_TYPE_RX_IND:
if (ar->dev_type == ATH10K_DEV_TYPE_HL) if (ar->bus_param.dev_type == ATH10K_DEV_TYPE_HL)
return ath10k_htt_rx_proc_rx_ind_hl(htt, return ath10k_htt_rx_proc_rx_ind_hl(htt,
&resp->rx_ind_hl, &resp->rx_ind_hl,
skb); skb);
@ -3530,7 +3579,7 @@ void ath10k_htt_set_rx_ops(struct ath10k_htt *htt)
{ {
struct ath10k *ar = htt->ar; struct ath10k *ar = htt->ar;
if (ar->dev_type == ATH10K_DEV_TYPE_HL) if (ar->bus_param.dev_type == ATH10K_DEV_TYPE_HL)
htt->rx_ops = &htt_rx_ops_hl; htt->rx_ops = &htt_rx_ops_hl;
else if (ar->hw_params.target_64bit) else if (ar->hw_params.target_64bit)
htt->rx_ops = &htt_rx_ops_64; htt->rx_ops = &htt_rx_ops_64;

View File

@ -1,18 +1,7 @@
// SPDX-License-Identifier: ISC
/* /*
* Copyright (c) 2005-2011 Atheros Communications Inc. * Copyright (c) 2005-2011 Atheros Communications Inc.
* Copyright (c) 2011-2017 Qualcomm Atheros, Inc. * Copyright (c) 2011-2017 Qualcomm Atheros, Inc.
*
* Permission to use, copy, modify, and/or distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/ */
#include <linux/etherdevice.h> #include <linux/etherdevice.h>
@ -495,7 +484,7 @@ int ath10k_htt_tx_start(struct ath10k_htt *htt)
if (htt->tx_mem_allocated) if (htt->tx_mem_allocated)
return 0; return 0;
if (ar->dev_type == ATH10K_DEV_TYPE_HL) if (ar->bus_param.dev_type == ATH10K_DEV_TYPE_HL)
return 0; return 0;
ret = ath10k_htt_tx_alloc_buf(htt); ret = ath10k_htt_tx_alloc_buf(htt);
@ -1035,6 +1024,53 @@ int ath10k_htt_h2t_aggr_cfg_msg(struct ath10k_htt *htt,
return 0; return 0;
} }
static int ath10k_htt_h2t_aggr_cfg_msg_v2(struct ath10k_htt *htt,
u8 max_subfrms_ampdu,
u8 max_subfrms_amsdu)
{
struct ath10k *ar = htt->ar;
struct htt_aggr_conf_v2 *aggr_conf;
struct sk_buff *skb;
struct htt_cmd *cmd;
int len;
int ret;
/* Firmware defaults are: amsdu = 3 and ampdu = 64 */
if (max_subfrms_ampdu == 0 || max_subfrms_ampdu > 64)
return -EINVAL;
if (max_subfrms_amsdu == 0 || max_subfrms_amsdu > 31)
return -EINVAL;
len = sizeof(cmd->hdr);
len += sizeof(cmd->aggr_conf_v2);
skb = ath10k_htc_alloc_skb(ar, len);
if (!skb)
return -ENOMEM;
skb_put(skb, len);
cmd = (struct htt_cmd *)skb->data;
cmd->hdr.msg_type = HTT_H2T_MSG_TYPE_AGGR_CFG;
aggr_conf = &cmd->aggr_conf_v2;
aggr_conf->max_num_ampdu_subframes = max_subfrms_ampdu;
aggr_conf->max_num_amsdu_subframes = max_subfrms_amsdu;
ath10k_dbg(ar, ATH10K_DBG_HTT, "htt h2t aggr cfg msg amsdu %d ampdu %d",
aggr_conf->max_num_amsdu_subframes,
aggr_conf->max_num_ampdu_subframes);
ret = ath10k_htc_send(&htt->ar->htc, htt->eid, skb);
if (ret) {
dev_kfree_skb_any(skb);
return ret;
}
return 0;
}
int ath10k_htt_tx_fetch_resp(struct ath10k *ar, int ath10k_htt_tx_fetch_resp(struct ath10k *ar,
__le32 token, __le32 token,
__le16 fetch_seq_num, __le16 fetch_seq_num,
@ -1177,7 +1213,7 @@ int ath10k_htt_mgmt_tx(struct ath10k_htt *htt, struct sk_buff *msdu)
return 0; return 0;
err_unmap_msdu: err_unmap_msdu:
if (ar->dev_type != ATH10K_DEV_TYPE_HL) if (ar->bus_param.dev_type != ATH10K_DEV_TYPE_HL)
dma_unmap_single(dev, skb_cb->paddr, msdu->len, DMA_TO_DEVICE); dma_unmap_single(dev, skb_cb->paddr, msdu->len, DMA_TO_DEVICE);
err_free_txdesc: err_free_txdesc:
dev_kfree_skb_any(txdesc); dev_kfree_skb_any(txdesc);
@ -1498,7 +1534,7 @@ static int ath10k_htt_tx_64(struct ath10k_htt *htt,
u16 msdu_id, flags1 = 0; u16 msdu_id, flags1 = 0;
u16 freq = 0; u16 freq = 0;
dma_addr_t frags_paddr = 0; dma_addr_t frags_paddr = 0;
u32 txbuf_paddr; dma_addr_t txbuf_paddr;
struct htt_msdu_ext_desc_64 *ext_desc = NULL; struct htt_msdu_ext_desc_64 *ext_desc = NULL;
struct htt_msdu_ext_desc_64 *ext_desc_t = NULL; struct htt_msdu_ext_desc_64 *ext_desc_t = NULL;
@ -1692,6 +1728,7 @@ static const struct ath10k_htt_tx_ops htt_tx_ops_32 = {
.htt_tx = ath10k_htt_tx_32, .htt_tx = ath10k_htt_tx_32,
.htt_alloc_txbuff = ath10k_htt_tx_alloc_cont_txbuf_32, .htt_alloc_txbuff = ath10k_htt_tx_alloc_cont_txbuf_32,
.htt_free_txbuff = ath10k_htt_tx_free_cont_txbuf_32, .htt_free_txbuff = ath10k_htt_tx_free_cont_txbuf_32,
.htt_h2t_aggr_cfg_msg = ath10k_htt_h2t_aggr_cfg_msg,
}; };
static const struct ath10k_htt_tx_ops htt_tx_ops_64 = { static const struct ath10k_htt_tx_ops htt_tx_ops_64 = {
@ -1702,6 +1739,7 @@ static const struct ath10k_htt_tx_ops htt_tx_ops_64 = {
.htt_tx = ath10k_htt_tx_64, .htt_tx = ath10k_htt_tx_64,
.htt_alloc_txbuff = ath10k_htt_tx_alloc_cont_txbuf_64, .htt_alloc_txbuff = ath10k_htt_tx_alloc_cont_txbuf_64,
.htt_free_txbuff = ath10k_htt_tx_free_cont_txbuf_64, .htt_free_txbuff = ath10k_htt_tx_free_cont_txbuf_64,
.htt_h2t_aggr_cfg_msg = ath10k_htt_h2t_aggr_cfg_msg_v2,
}; };
static const struct ath10k_htt_tx_ops htt_tx_ops_hl = { static const struct ath10k_htt_tx_ops htt_tx_ops_hl = {
@ -1714,7 +1752,7 @@ void ath10k_htt_set_tx_ops(struct ath10k_htt *htt)
{ {
struct ath10k *ar = htt->ar; struct ath10k *ar = htt->ar;
if (ar->dev_type == ATH10K_DEV_TYPE_HL) if (ar->bus_param.dev_type == ATH10K_DEV_TYPE_HL)
htt->tx_ops = &htt_tx_ops_hl; htt->tx_ops = &htt_tx_ops_hl;
else if (ar->hw_params.target_64bit) else if (ar->hw_params.target_64bit)
htt->tx_ops = &htt_tx_ops_64; htt->tx_ops = &htt_tx_ops_64;

View File

@ -1,17 +1,6 @@
// SPDX-License-Identifier: ISC
/* /*
* Copyright (c) 2014-2017 Qualcomm Atheros, Inc. * Copyright (c) 2014-2017 Qualcomm Atheros, Inc.
*
* Permission to use, copy, modify, and/or distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/ */
#include <linux/types.h> #include <linux/types.h>
@ -318,9 +307,11 @@ static struct ath10k_hw_ce_ctrl1_upd wcn3990_ctrl1_upd = {
}; };
const struct ath10k_hw_ce_regs wcn3990_ce_regs = { const struct ath10k_hw_ce_regs wcn3990_ce_regs = {
.sr_base_addr = 0x00000000, .sr_base_addr_lo = 0x00000000,
.sr_base_addr_hi = 0x00000004,
.sr_size_addr = 0x00000008, .sr_size_addr = 0x00000008,
.dr_base_addr = 0x0000000c, .dr_base_addr_lo = 0x0000000c,
.dr_base_addr_hi = 0x00000010,
.dr_size_addr = 0x00000014, .dr_size_addr = 0x00000014,
.misc_ie_addr = 0x00000034, .misc_ie_addr = 0x00000034,
.sr_wr_index_addr = 0x0000003c, .sr_wr_index_addr = 0x0000003c,
@ -464,9 +455,9 @@ static struct ath10k_hw_ce_dst_src_wm_regs qcax_wm_dst_ring = {
}; };
const struct ath10k_hw_ce_regs qcax_ce_regs = { const struct ath10k_hw_ce_regs qcax_ce_regs = {
.sr_base_addr = 0x00000000, .sr_base_addr_lo = 0x00000000,
.sr_size_addr = 0x00000004, .sr_size_addr = 0x00000004,
.dr_base_addr = 0x00000008, .dr_base_addr_lo = 0x00000008,
.dr_size_addr = 0x0000000c, .dr_size_addr = 0x0000000c,
.ce_cmd_addr = 0x00000018, .ce_cmd_addr = 0x00000018,
.misc_ie_addr = 0x00000034, .misc_ie_addr = 0x00000034,

View File

@ -1,19 +1,8 @@
/* SPDX-License-Identifier: ISC */
/* /*
* Copyright (c) 2005-2011 Atheros Communications Inc. * Copyright (c) 2005-2011 Atheros Communications Inc.
* Copyright (c) 2011-2017 Qualcomm Atheros, Inc. * Copyright (c) 2011-2017 Qualcomm Atheros, Inc.
* Copyright (c) 2018 The Linux Foundation. All rights reserved. * Copyright (c) 2018 The Linux Foundation. All rights reserved.
*
* Permission to use, copy, modify, and/or distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/ */
#ifndef _HW_H_ #ifndef _HW_H_
@ -353,9 +342,11 @@ struct ath10k_hw_ce_ctrl1_upd {
}; };
struct ath10k_hw_ce_regs { struct ath10k_hw_ce_regs {
u32 sr_base_addr; u32 sr_base_addr_lo;
u32 sr_base_addr_hi;
u32 sr_size_addr; u32 sr_size_addr;
u32 dr_base_addr; u32 dr_base_addr_lo;
u32 dr_base_addr_hi;
u32 dr_size_addr; u32 dr_size_addr;
u32 ce_cmd_addr; u32 ce_cmd_addr;
u32 misc_ie_addr; u32 misc_ie_addr;
@ -734,6 +725,7 @@ ath10k_rx_desc_msdu_limit_error(struct ath10k_hw_params *hw,
#define TARGET_TLV_NUM_TDLS_VDEVS 1 #define TARGET_TLV_NUM_TDLS_VDEVS 1
#define TARGET_TLV_NUM_TIDS ((TARGET_TLV_NUM_PEERS) * 2) #define TARGET_TLV_NUM_TIDS ((TARGET_TLV_NUM_PEERS) * 2)
#define TARGET_TLV_NUM_MSDU_DESC (1024 + 32) #define TARGET_TLV_NUM_MSDU_DESC (1024 + 32)
#define TARGET_TLV_NUM_MSDU_DESC_HL 64
#define TARGET_TLV_NUM_WOW_PATTERNS 22 #define TARGET_TLV_NUM_WOW_PATTERNS 22
#define TARGET_TLV_MGMT_NUM_MSDU_DESC (50) #define TARGET_TLV_MGMT_NUM_MSDU_DESC (50)

View File

@ -1,19 +1,8 @@
// SPDX-License-Identifier: ISC
/* /*
* Copyright (c) 2005-2011 Atheros Communications Inc. * Copyright (c) 2005-2011 Atheros Communications Inc.
* Copyright (c) 2011-2017 Qualcomm Atheros, Inc. * Copyright (c) 2011-2017 Qualcomm Atheros, Inc.
* Copyright (c) 2018, The Linux Foundation. All rights reserved. * Copyright (c) 2018-2019, The Linux Foundation. All rights reserved.
*
* Permission to use, copy, modify, and/or distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/ */
#include "mac.h" #include "mac.h"
@ -250,24 +239,24 @@ static int ath10k_send_key(struct ath10k_vif *arvif,
switch (key->cipher) { switch (key->cipher) {
case WLAN_CIPHER_SUITE_CCMP: case WLAN_CIPHER_SUITE_CCMP:
arg.key_cipher = WMI_CIPHER_AES_CCM; arg.key_cipher = ar->wmi_key_cipher[WMI_CIPHER_AES_CCM];
key->flags |= IEEE80211_KEY_FLAG_GENERATE_IV_MGMT; key->flags |= IEEE80211_KEY_FLAG_GENERATE_IV_MGMT;
break; break;
case WLAN_CIPHER_SUITE_TKIP: case WLAN_CIPHER_SUITE_TKIP:
arg.key_cipher = WMI_CIPHER_TKIP; arg.key_cipher = ar->wmi_key_cipher[WMI_CIPHER_TKIP];
arg.key_txmic_len = 8; arg.key_txmic_len = 8;
arg.key_rxmic_len = 8; arg.key_rxmic_len = 8;
break; break;
case WLAN_CIPHER_SUITE_WEP40: case WLAN_CIPHER_SUITE_WEP40:
case WLAN_CIPHER_SUITE_WEP104: case WLAN_CIPHER_SUITE_WEP104:
arg.key_cipher = WMI_CIPHER_WEP; arg.key_cipher = ar->wmi_key_cipher[WMI_CIPHER_WEP];
break; break;
case WLAN_CIPHER_SUITE_CCMP_256: case WLAN_CIPHER_SUITE_CCMP_256:
arg.key_cipher = WMI_CIPHER_AES_CCM; arg.key_cipher = ar->wmi_key_cipher[WMI_CIPHER_AES_CCM];
break; break;
case WLAN_CIPHER_SUITE_GCMP: case WLAN_CIPHER_SUITE_GCMP:
case WLAN_CIPHER_SUITE_GCMP_256: case WLAN_CIPHER_SUITE_GCMP_256:
arg.key_cipher = WMI_CIPHER_AES_GCM; arg.key_cipher = ar->wmi_key_cipher[WMI_CIPHER_AES_GCM];
break; break;
case WLAN_CIPHER_SUITE_BIP_GMAC_128: case WLAN_CIPHER_SUITE_BIP_GMAC_128:
case WLAN_CIPHER_SUITE_BIP_GMAC_256: case WLAN_CIPHER_SUITE_BIP_GMAC_256:
@ -284,7 +273,7 @@ static int ath10k_send_key(struct ath10k_vif *arvif,
key->flags |= IEEE80211_KEY_FLAG_GENERATE_IV; key->flags |= IEEE80211_KEY_FLAG_GENERATE_IV;
if (cmd == DISABLE_KEY) { if (cmd == DISABLE_KEY) {
arg.key_cipher = WMI_CIPHER_NONE; arg.key_cipher = ar->wmi_key_cipher[WMI_CIPHER_NONE];
arg.key_data = NULL; arg.key_data = NULL;
} }
@ -3397,6 +3386,7 @@ ath10k_mac_tx_h_get_txmode(struct ath10k *ar,
struct sk_buff *skb) struct sk_buff *skb)
{ {
const struct ieee80211_hdr *hdr = (void *)skb->data; const struct ieee80211_hdr *hdr = (void *)skb->data;
const struct ath10k_skb_cb *skb_cb = ATH10K_SKB_CB(skb);
__le16 fc = hdr->frame_control; __le16 fc = hdr->frame_control;
if (!vif || vif->type == NL80211_IFTYPE_MONITOR) if (!vif || vif->type == NL80211_IFTYPE_MONITOR)
@ -3438,7 +3428,8 @@ ath10k_mac_tx_h_get_txmode(struct ath10k *ar,
if (ieee80211_is_data_present(fc) && sta && sta->tdls) if (ieee80211_is_data_present(fc) && sta && sta->tdls)
return ATH10K_HW_TXRX_ETHERNET; return ATH10K_HW_TXRX_ETHERNET;
if (test_bit(ATH10K_FLAG_RAW_MODE, &ar->dev_flags)) if (test_bit(ATH10K_FLAG_RAW_MODE, &ar->dev_flags) ||
skb_cb->flags & ATH10K_SKB_F_RAW_TX)
return ATH10K_HW_TXRX_RAW; return ATH10K_HW_TXRX_RAW;
return ATH10K_HW_TXRX_NATIVE_WIFI; return ATH10K_HW_TXRX_NATIVE_WIFI;
@ -3544,10 +3535,13 @@ static void ath10k_tx_h_add_p2p_noa_ie(struct ath10k *ar,
static void ath10k_mac_tx_h_fill_cb(struct ath10k *ar, static void ath10k_mac_tx_h_fill_cb(struct ath10k *ar,
struct ieee80211_vif *vif, struct ieee80211_vif *vif,
struct ieee80211_txq *txq, struct ieee80211_txq *txq,
struct sk_buff *skb) struct sk_buff *skb, u16 airtime)
{ {
struct ieee80211_hdr *hdr = (void *)skb->data; struct ieee80211_hdr *hdr = (void *)skb->data;
struct ath10k_skb_cb *cb = ATH10K_SKB_CB(skb); struct ath10k_skb_cb *cb = ATH10K_SKB_CB(skb);
const struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
bool is_data = ieee80211_is_data(hdr->frame_control) ||
ieee80211_is_data_qos(hdr->frame_control);
cb->flags = 0; cb->flags = 0;
if (!ath10k_tx_h_use_hwcrypto(vif, skb)) if (!ath10k_tx_h_use_hwcrypto(vif, skb))
@ -3559,8 +3553,19 @@ static void ath10k_mac_tx_h_fill_cb(struct ath10k *ar,
if (ieee80211_is_data_qos(hdr->frame_control)) if (ieee80211_is_data_qos(hdr->frame_control))
cb->flags |= ATH10K_SKB_F_QOS; cb->flags |= ATH10K_SKB_F_QOS;
/* Data frames encrypted in software will be posted to firmware
* with tx encap mode set to RAW. Ex: Multicast traffic generated
* for a specific VLAN group will always be encrypted in software.
*/
if (is_data && ieee80211_has_protected(hdr->frame_control) &&
!info->control.hw_key) {
cb->flags |= ATH10K_SKB_F_NO_HWCRYPT;
cb->flags |= ATH10K_SKB_F_RAW_TX;
}
cb->vif = vif; cb->vif = vif;
cb->txq = txq; cb->txq = txq;
cb->airtime_est = airtime;
} }
bool ath10k_mac_tx_frm_has_freq(struct ath10k *ar) bool ath10k_mac_tx_frm_has_freq(struct ath10k *ar)
@ -3667,6 +3672,7 @@ static int ath10k_mac_tx(struct ath10k *ar,
{ {
struct ieee80211_hw *hw = ar->hw; struct ieee80211_hw *hw = ar->hw;
struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
const struct ath10k_skb_cb *skb_cb = ATH10K_SKB_CB(skb);
int ret; int ret;
/* We should disable CCK RATE due to P2P */ /* We should disable CCK RATE due to P2P */
@ -3684,7 +3690,8 @@ static int ath10k_mac_tx(struct ath10k *ar,
ath10k_tx_h_8023(skb); ath10k_tx_h_8023(skb);
break; break;
case ATH10K_HW_TXRX_RAW: case ATH10K_HW_TXRX_RAW:
if (!test_bit(ATH10K_FLAG_RAW_MODE, &ar->dev_flags)) { if (!test_bit(ATH10K_FLAG_RAW_MODE, &ar->dev_flags) &&
!(skb_cb->flags & ATH10K_SKB_F_RAW_TX)) {
WARN_ON_ONCE(1); WARN_ON_ONCE(1);
ieee80211_free_txskb(hw, skb); ieee80211_free_txskb(hw, skb);
return -ENOTSUPP; return -ENOTSUPP;
@ -3863,7 +3870,7 @@ void ath10k_mgmt_over_wmi_tx_work(struct work_struct *work)
ath10k_warn(ar, "failed to transmit management frame by ref via WMI: %d\n", ath10k_warn(ar, "failed to transmit management frame by ref via WMI: %d\n",
ret); ret);
dma_unmap_single(ar->dev, paddr, skb->len, dma_unmap_single(ar->dev, paddr, skb->len,
DMA_FROM_DEVICE); DMA_TO_DEVICE);
ieee80211_free_txskb(ar->hw, skb); ieee80211_free_txskb(ar->hw, skb);
} }
} else { } else {
@ -3890,7 +3897,6 @@ static void ath10k_mac_txq_init(struct ieee80211_txq *txq)
static void ath10k_mac_txq_unref(struct ath10k *ar, struct ieee80211_txq *txq) static void ath10k_mac_txq_unref(struct ath10k *ar, struct ieee80211_txq *txq)
{ {
struct ath10k_txq *artxq;
struct ath10k_skb_cb *cb; struct ath10k_skb_cb *cb;
struct sk_buff *msdu; struct sk_buff *msdu;
int msdu_id; int msdu_id;
@ -3898,12 +3904,6 @@ static void ath10k_mac_txq_unref(struct ath10k *ar, struct ieee80211_txq *txq)
if (!txq) if (!txq)
return; return;
artxq = (void *)txq->drv_priv;
spin_lock_bh(&ar->txqs_lock);
if (!list_empty(&artxq->list))
list_del_init(&artxq->list);
spin_unlock_bh(&ar->txqs_lock);
spin_lock_bh(&ar->htt.tx_lock); spin_lock_bh(&ar->htt.tx_lock);
idr_for_each_entry(&ar->htt.pending_tx, msdu, msdu_id) { idr_for_each_entry(&ar->htt.pending_tx, msdu, msdu_id) {
cb = ATH10K_SKB_CB(msdu); cb = ATH10K_SKB_CB(msdu);
@ -3943,7 +3943,6 @@ static bool ath10k_mac_tx_can_push(struct ieee80211_hw *hw,
struct ath10k_txq *artxq = (void *)txq->drv_priv; struct ath10k_txq *artxq = (void *)txq->drv_priv;
/* No need to get locks */ /* No need to get locks */
if (ar->htt.tx_q_state.mode == HTT_TX_MODE_SWITCH_PUSH) if (ar->htt.tx_q_state.mode == HTT_TX_MODE_SWITCH_PUSH)
return true; return true;
@ -3956,6 +3955,52 @@ static bool ath10k_mac_tx_can_push(struct ieee80211_hw *hw,
return false; return false;
} }
/* Return estimated airtime in microsecond, which is calculated using last
* reported TX rate. This is just a rough estimation because host driver has no
* knowledge of the actual transmit rate, retries or aggregation. If actual
* airtime can be reported by firmware, then delta between estimated and actual
* airtime can be adjusted from deficit.
*/
#define IEEE80211_ATF_OVERHEAD 100 /* IFS + some slot time */
#define IEEE80211_ATF_OVERHEAD_IFS 16 /* IFS only */
static u16 ath10k_mac_update_airtime(struct ath10k *ar,
struct ieee80211_txq *txq,
struct sk_buff *skb)
{
struct ath10k_sta *arsta;
u32 pktlen;
u16 airtime = 0;
if (!txq || !txq->sta)
return airtime;
if (test_bit(WMI_SERVICE_REPORT_AIRTIME, ar->wmi.svc_map))
return airtime;
spin_lock_bh(&ar->data_lock);
arsta = (struct ath10k_sta *)txq->sta->drv_priv;
pktlen = skb->len + 38; /* Assume MAC header 30, SNAP 8 for most case */
if (arsta->last_tx_bitrate) {
/* airtime in us, last_tx_bitrate in 100kbps */
airtime = (pktlen * 8 * (1000 / 100))
/ arsta->last_tx_bitrate;
/* overhead for media access time and IFS */
airtime += IEEE80211_ATF_OVERHEAD_IFS;
} else {
/* This is mostly for throttle excessive BC/MC frames, and the
* airtime/rate doesn't need be exact. Airtime of BC/MC frames
* in 2G get some discount, which helps prevent very low rate
* frames from being blocked for too long.
*/
airtime = (pktlen * 8 * (1000 / 100)) / 60; /* 6M */
airtime += IEEE80211_ATF_OVERHEAD;
}
spin_unlock_bh(&ar->data_lock);
return airtime;
}
int ath10k_mac_tx_push_txq(struct ieee80211_hw *hw, int ath10k_mac_tx_push_txq(struct ieee80211_hw *hw,
struct ieee80211_txq *txq) struct ieee80211_txq *txq)
{ {
@ -3971,6 +4016,7 @@ int ath10k_mac_tx_push_txq(struct ieee80211_hw *hw,
size_t skb_len; size_t skb_len;
bool is_mgmt, is_presp; bool is_mgmt, is_presp;
int ret; int ret;
u16 airtime;
spin_lock_bh(&ar->htt.tx_lock); spin_lock_bh(&ar->htt.tx_lock);
ret = ath10k_htt_tx_inc_pending(htt); ret = ath10k_htt_tx_inc_pending(htt);
@ -3988,7 +4034,8 @@ int ath10k_mac_tx_push_txq(struct ieee80211_hw *hw,
return -ENOENT; return -ENOENT;
} }
ath10k_mac_tx_h_fill_cb(ar, vif, txq, skb); airtime = ath10k_mac_update_airtime(ar, txq, skb);
ath10k_mac_tx_h_fill_cb(ar, vif, txq, skb, airtime);
skb_len = skb->len; skb_len = skb->len;
txmode = ath10k_mac_tx_h_get_txmode(ar, vif, sta, skb); txmode = ath10k_mac_tx_h_get_txmode(ar, vif, sta, skb);
@ -4030,48 +4077,45 @@ int ath10k_mac_tx_push_txq(struct ieee80211_hw *hw,
return skb_len; return skb_len;
} }
void ath10k_mac_tx_push_pending(struct ath10k *ar) static int ath10k_mac_schedule_txq(struct ieee80211_hw *hw, u32 ac)
{ {
struct ieee80211_hw *hw = ar->hw;
struct ieee80211_txq *txq; struct ieee80211_txq *txq;
struct ath10k_txq *artxq; int ret = 0;
struct ath10k_txq *last;
int ret;
int max;
if (ar->htt.num_pending_tx >= (ar->htt.max_num_pending_tx / 2)) ieee80211_txq_schedule_start(hw, ac);
return; while ((txq = ieee80211_next_txq(hw, ac))) {
while (ath10k_mac_tx_can_push(hw, txq)) {
spin_lock_bh(&ar->txqs_lock);
rcu_read_lock();
last = list_last_entry(&ar->txqs, struct ath10k_txq, list);
while (!list_empty(&ar->txqs)) {
artxq = list_first_entry(&ar->txqs, struct ath10k_txq, list);
txq = container_of((void *)artxq, struct ieee80211_txq,
drv_priv);
/* Prevent aggressive sta/tid taking over tx queue */
max = HTC_HOST_MAX_MSG_PER_TX_BUNDLE;
ret = 0;
while (ath10k_mac_tx_can_push(hw, txq) && max--) {
ret = ath10k_mac_tx_push_txq(hw, txq); ret = ath10k_mac_tx_push_txq(hw, txq);
if (ret < 0) if (ret < 0)
break; break;
} }
ieee80211_return_txq(hw, txq);
list_del_init(&artxq->list);
if (ret != -ENOENT)
list_add_tail(&artxq->list, &ar->txqs);
ath10k_htt_tx_txq_update(hw, txq); ath10k_htt_tx_txq_update(hw, txq);
if (ret == -EBUSY)
if (artxq == last || (ret < 0 && ret != -ENOENT))
break; break;
} }
ieee80211_txq_schedule_end(hw, ac);
return ret;
}
void ath10k_mac_tx_push_pending(struct ath10k *ar)
{
struct ieee80211_hw *hw = ar->hw;
u32 ac;
if (ar->htt.tx_q_state.mode != HTT_TX_MODE_SWITCH_PUSH)
return;
if (ar->htt.num_pending_tx >= (ar->htt.max_num_pending_tx / 2))
return;
rcu_read_lock();
for (ac = 0; ac < IEEE80211_NUM_ACS; ac++) {
if (ath10k_mac_schedule_txq(hw, ac) == -EBUSY)
break;
}
rcu_read_unlock(); rcu_read_unlock();
spin_unlock_bh(&ar->txqs_lock);
} }
EXPORT_SYMBOL(ath10k_mac_tx_push_pending); EXPORT_SYMBOL(ath10k_mac_tx_push_pending);
@ -4258,8 +4302,10 @@ static void ath10k_mac_op_tx(struct ieee80211_hw *hw,
bool is_mgmt; bool is_mgmt;
bool is_presp; bool is_presp;
int ret; int ret;
u16 airtime;
ath10k_mac_tx_h_fill_cb(ar, vif, txq, skb); airtime = ath10k_mac_update_airtime(ar, txq, skb);
ath10k_mac_tx_h_fill_cb(ar, vif, txq, skb, airtime);
txmode = ath10k_mac_tx_h_get_txmode(ar, vif, sta, skb); txmode = ath10k_mac_tx_h_get_txmode(ar, vif, sta, skb);
txpath = ath10k_mac_tx_h_get_txpath(ar, skb, txmode); txpath = ath10k_mac_tx_h_get_txpath(ar, skb, txmode);
@ -4310,31 +4356,28 @@ static void ath10k_mac_op_wake_tx_queue(struct ieee80211_hw *hw,
struct ieee80211_txq *txq) struct ieee80211_txq *txq)
{ {
struct ath10k *ar = hw->priv; struct ath10k *ar = hw->priv;
struct ath10k_txq *artxq = (void *)txq->drv_priv; int ret;
struct ieee80211_txq *f_txq; u8 ac;
struct ath10k_txq *f_artxq;
int ret = 0;
int max = HTC_HOST_MAX_MSG_PER_TX_BUNDLE;
spin_lock_bh(&ar->txqs_lock); ath10k_htt_tx_txq_update(hw, txq);
if (list_empty(&artxq->list)) if (ar->htt.tx_q_state.mode != HTT_TX_MODE_SWITCH_PUSH)
list_add_tail(&artxq->list, &ar->txqs); return;
f_artxq = list_first_entry(&ar->txqs, struct ath10k_txq, list); ac = txq->ac;
f_txq = container_of((void *)f_artxq, struct ieee80211_txq, drv_priv); ieee80211_txq_schedule_start(hw, ac);
list_del_init(&f_artxq->list); txq = ieee80211_next_txq(hw, ac);
if (!txq)
goto out;
while (ath10k_mac_tx_can_push(hw, f_txq) && max--) { while (ath10k_mac_tx_can_push(hw, txq)) {
ret = ath10k_mac_tx_push_txq(hw, f_txq); ret = ath10k_mac_tx_push_txq(hw, txq);
if (ret < 0) if (ret < 0)
break; break;
} }
if (ret != -ENOENT) ieee80211_return_txq(hw, txq);
list_add_tail(&f_artxq->list, &ar->txqs);
spin_unlock_bh(&ar->txqs_lock);
ath10k_htt_tx_txq_update(hw, f_txq);
ath10k_htt_tx_txq_update(hw, txq); ath10k_htt_tx_txq_update(hw, txq);
out:
ieee80211_txq_schedule_end(hw, ac);
} }
/* Must not be called with conf_mutex held as workers can use that also. */ /* Must not be called with conf_mutex held as workers can use that also. */
@ -4549,7 +4592,8 @@ static struct ieee80211_sta_ht_cap ath10k_get_ht_cap(struct ath10k *ar)
ht_cap.cap |= stbc; ht_cap.cap |= stbc;
} }
if (ar->ht_cap_info & WMI_HT_CAP_LDPC) if (ar->ht_cap_info & WMI_HT_CAP_LDPC || (ar->ht_cap_info &
WMI_HT_CAP_RX_LDPC && (ar->ht_cap_info & WMI_HT_CAP_TX_LDPC)))
ht_cap.cap |= IEEE80211_HT_CAP_LDPC_CODING; ht_cap.cap |= IEEE80211_HT_CAP_LDPC_CODING;
if (ar->ht_cap_info & WMI_HT_CAP_L_SIG_TXOP_PROT) if (ar->ht_cap_info & WMI_HT_CAP_L_SIG_TXOP_PROT)
@ -4704,7 +4748,7 @@ static int ath10k_start(struct ieee80211_hw *hw)
goto err; goto err;
} }
ret = ath10k_hif_power_up(ar); ret = ath10k_hif_power_up(ar, ATH10K_FIRMWARE_MODE_NORMAL);
if (ret) { if (ret) {
ath10k_err(ar, "Could not init hif: %d\n", ret); ath10k_err(ar, "Could not init hif: %d\n", ret);
goto err_off; goto err_off;
@ -5341,6 +5385,17 @@ static int ath10k_add_interface(struct ieee80211_hw *hw,
goto err_peer_delete; goto err_peer_delete;
} }
if (test_bit(WMI_SERVICE_RTT_RESPONDER_ROLE, ar->wmi.svc_map)) {
vdev_param = ar->wmi.vdev_param->rtt_responder_role;
ret = ath10k_wmi_vdev_set_param(ar, arvif->vdev_id, vdev_param,
arvif->ftm_responder);
/* It is harmless to not set FTM role. Do not warn */
if (ret && ret != -EOPNOTSUPP)
ath10k_warn(ar, "failed to set vdev %i FTM Responder: %d\n",
arvif->vdev_id, ret);
}
if (vif->type == NL80211_IFTYPE_MONITOR) { if (vif->type == NL80211_IFTYPE_MONITOR) {
ar->monitor_arvif = arvif; ar->monitor_arvif = arvif;
ret = ath10k_monitor_recalc(ar); ret = ath10k_monitor_recalc(ar);
@ -5615,6 +5670,20 @@ static void ath10k_bss_info_changed(struct ieee80211_hw *hw,
if (changed & BSS_CHANGED_BSSID && !is_zero_ether_addr(info->bssid)) if (changed & BSS_CHANGED_BSSID && !is_zero_ether_addr(info->bssid))
ether_addr_copy(arvif->bssid, info->bssid); ether_addr_copy(arvif->bssid, info->bssid);
if (changed & BSS_CHANGED_FTM_RESPONDER &&
arvif->ftm_responder != info->ftm_responder &&
test_bit(WMI_SERVICE_RTT_RESPONDER_ROLE, ar->wmi.svc_map)) {
arvif->ftm_responder = info->ftm_responder;
vdev_param = ar->wmi.vdev_param->rtt_responder_role;
ret = ath10k_wmi_vdev_set_param(ar, arvif->vdev_id, vdev_param,
arvif->ftm_responder);
ath10k_dbg(ar, ATH10K_DBG_MAC,
"mac vdev %d ftm_responder %d:ret %d\n",
arvif->vdev_id, arvif->ftm_responder, ret);
}
if (changed & BSS_CHANGED_BEACON_ENABLED) if (changed & BSS_CHANGED_BEACON_ENABLED)
ath10k_control_beaconing(arvif, info); ath10k_control_beaconing(arvif, info);
@ -8617,6 +8686,15 @@ int ath10k_mac_register(struct ath10k *ar)
wiphy_ext_feature_set(ar->hw->wiphy, wiphy_ext_feature_set(ar->hw->wiphy,
NL80211_EXT_FEATURE_ACK_SIGNAL_SUPPORT); NL80211_EXT_FEATURE_ACK_SIGNAL_SUPPORT);
if (ath10k_peer_stats_enabled(ar) ||
test_bit(WMI_SERVICE_REPORT_AIRTIME, ar->wmi.svc_map))
wiphy_ext_feature_set(ar->hw->wiphy,
NL80211_EXT_FEATURE_AIRTIME_FAIRNESS);
if (test_bit(WMI_SERVICE_RTT_RESPONDER_ROLE, ar->wmi.svc_map))
wiphy_ext_feature_set(ar->hw->wiphy,
NL80211_EXT_FEATURE_ENABLE_FTM_RESPONDER);
/* /*
* on LL hardware queues are managed entirely by the FW * on LL hardware queues are managed entirely by the FW
* so we only advertise to mac we can do the queues thing * so we only advertise to mac we can do the queues thing
@ -8726,12 +8804,19 @@ int ath10k_mac_register(struct ath10k *ar)
wiphy_ext_feature_set(ar->hw->wiphy, NL80211_EXT_FEATURE_CQM_RSSI_LIST); wiphy_ext_feature_set(ar->hw->wiphy, NL80211_EXT_FEATURE_CQM_RSSI_LIST);
ar->hw->weight_multiplier = ATH10K_AIRTIME_WEIGHT_MULTIPLIER;
ret = ieee80211_register_hw(ar->hw); ret = ieee80211_register_hw(ar->hw);
if (ret) { if (ret) {
ath10k_err(ar, "failed to register ieee80211: %d\n", ret); ath10k_err(ar, "failed to register ieee80211: %d\n", ret);
goto err_dfs_detector_exit; goto err_dfs_detector_exit;
} }
if (test_bit(WMI_SERVICE_PER_PACKET_SW_ENCRYPT, ar->wmi.svc_map)) {
ar->hw->wiphy->interface_modes |= BIT(NL80211_IFTYPE_AP_VLAN);
ar->hw->wiphy->software_iftypes |= BIT(NL80211_IFTYPE_AP_VLAN);
}
if (!ath_is_world_regd(&ar->ath_common.regulatory)) { if (!ath_is_world_regd(&ar->ath_common.regulatory)) {
ret = regulatory_hint(ar->hw->wiphy, ret = regulatory_hint(ar->hw->wiphy,
ar->ath_common.regulatory.alpha2); ar->ath_common.regulatory.alpha2);

View File

@ -1,18 +1,7 @@
/* SPDX-License-Identifier: ISC */
/* /*
* Copyright (c) 2005-2011 Atheros Communications Inc. * Copyright (c) 2005-2011 Atheros Communications Inc.
* Copyright (c) 2011-2017 Qualcomm Atheros, Inc. * Copyright (c) 2011-2017 Qualcomm Atheros, Inc.
*
* Permission to use, copy, modify, and/or distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/ */
#ifndef _MAC_H_ #ifndef _MAC_H_

View File

@ -1,17 +1,6 @@
// SPDX-License-Identifier: ISC
/* /*
* Copyright (c) 2015 Qualcomm Atheros, Inc. * Copyright (c) 2015 Qualcomm Atheros, Inc.
*
* Permission to use, copy, modify, and/or distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/ */
#include "core.h" #include "core.h"

View File

@ -1,17 +1,6 @@
/* SPDX-License-Identifier: ISC */
/* /*
* Copyright (c) 2015 Qualcomm Atheros, Inc. * Copyright (c) 2015 Qualcomm Atheros, Inc.
*
* Permission to use, copy, modify, and/or distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/ */
#ifndef _P2P_H #ifndef _P2P_H

View File

@ -1,18 +1,7 @@
// SPDX-License-Identifier: ISC
/* /*
* Copyright (c) 2005-2011 Atheros Communications Inc. * Copyright (c) 2005-2011 Atheros Communications Inc.
* Copyright (c) 2011-2017 Qualcomm Atheros, Inc. * Copyright (c) 2011-2017 Qualcomm Atheros, Inc.
*
* Permission to use, copy, modify, and/or distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/ */
#include <linux/pci.h> #include <linux/pci.h>
@ -913,7 +902,6 @@ static int ath10k_pci_diag_read_mem(struct ath10k *ar, u32 address, void *data,
int nbytes) int nbytes)
{ {
struct ath10k_pci *ar_pci = ath10k_pci_priv(ar); struct ath10k_pci *ar_pci = ath10k_pci_priv(ar);
struct ath10k_ce *ce = ath10k_ce_priv(ar);
int ret = 0; int ret = 0;
u32 *buf; u32 *buf;
unsigned int completed_nbytes, alloc_nbytes, remaining_bytes; unsigned int completed_nbytes, alloc_nbytes, remaining_bytes;
@ -924,8 +912,7 @@ static int ath10k_pci_diag_read_mem(struct ath10k *ar, u32 address, void *data,
void *data_buf = NULL; void *data_buf = NULL;
int i; int i;
spin_lock_bh(&ce->ce_lock); mutex_lock(&ar_pci->ce_diag_mutex);
ce_diag = ar_pci->ce_diag; ce_diag = ar_pci->ce_diag;
/* /*
@ -960,19 +947,17 @@ static int ath10k_pci_diag_read_mem(struct ath10k *ar, u32 address, void *data,
nbytes = min_t(unsigned int, remaining_bytes, nbytes = min_t(unsigned int, remaining_bytes,
DIAG_TRANSFER_LIMIT); DIAG_TRANSFER_LIMIT);
ret = ce_diag->ops->ce_rx_post_buf(ce_diag, &ce_data, ce_data); ret = ath10k_ce_rx_post_buf(ce_diag, &ce_data, ce_data);
if (ret != 0) if (ret != 0)
goto done; goto done;
/* Request CE to send from Target(!) address to Host buffer */ /* Request CE to send from Target(!) address to Host buffer */
ret = ath10k_ce_send_nolock(ce_diag, NULL, (u32)address, nbytes, 0, ret = ath10k_ce_send(ce_diag, NULL, (u32)address, nbytes, 0, 0);
0);
if (ret) if (ret)
goto done; goto done;
i = 0; i = 0;
while (ath10k_ce_completed_send_next_nolock(ce_diag, while (ath10k_ce_completed_send_next(ce_diag, NULL) != 0) {
NULL) != 0) {
udelay(DIAG_ACCESS_CE_WAIT_US); udelay(DIAG_ACCESS_CE_WAIT_US);
i += DIAG_ACCESS_CE_WAIT_US; i += DIAG_ACCESS_CE_WAIT_US;
@ -983,10 +968,8 @@ static int ath10k_pci_diag_read_mem(struct ath10k *ar, u32 address, void *data,
} }
i = 0; i = 0;
while (ath10k_ce_completed_recv_next_nolock(ce_diag, while (ath10k_ce_completed_recv_next(ce_diag, (void **)&buf,
(void **)&buf, &completed_nbytes) != 0) {
&completed_nbytes)
!= 0) {
udelay(DIAG_ACCESS_CE_WAIT_US); udelay(DIAG_ACCESS_CE_WAIT_US);
i += DIAG_ACCESS_CE_WAIT_US; i += DIAG_ACCESS_CE_WAIT_US;
@ -1019,7 +1002,7 @@ static int ath10k_pci_diag_read_mem(struct ath10k *ar, u32 address, void *data,
dma_free_coherent(ar->dev, alloc_nbytes, data_buf, dma_free_coherent(ar->dev, alloc_nbytes, data_buf,
ce_data_base); ce_data_base);
spin_unlock_bh(&ce->ce_lock); mutex_unlock(&ar_pci->ce_diag_mutex);
return ret; return ret;
} }
@ -1067,7 +1050,6 @@ int ath10k_pci_diag_write_mem(struct ath10k *ar, u32 address,
const void *data, int nbytes) const void *data, int nbytes)
{ {
struct ath10k_pci *ar_pci = ath10k_pci_priv(ar); struct ath10k_pci *ar_pci = ath10k_pci_priv(ar);
struct ath10k_ce *ce = ath10k_ce_priv(ar);
int ret = 0; int ret = 0;
u32 *buf; u32 *buf;
unsigned int completed_nbytes, alloc_nbytes, remaining_bytes; unsigned int completed_nbytes, alloc_nbytes, remaining_bytes;
@ -1076,8 +1058,7 @@ int ath10k_pci_diag_write_mem(struct ath10k *ar, u32 address,
dma_addr_t ce_data_base = 0; dma_addr_t ce_data_base = 0;
int i; int i;
spin_lock_bh(&ce->ce_lock); mutex_lock(&ar_pci->ce_diag_mutex);
ce_diag = ar_pci->ce_diag; ce_diag = ar_pci->ce_diag;
/* /*
@ -1118,7 +1099,7 @@ int ath10k_pci_diag_write_mem(struct ath10k *ar, u32 address,
memcpy(data_buf, data, nbytes); memcpy(data_buf, data, nbytes);
/* Set up to receive directly into Target(!) address */ /* Set up to receive directly into Target(!) address */
ret = ce_diag->ops->ce_rx_post_buf(ce_diag, &address, address); ret = ath10k_ce_rx_post_buf(ce_diag, &address, address);
if (ret != 0) if (ret != 0)
goto done; goto done;
@ -1126,14 +1107,12 @@ int ath10k_pci_diag_write_mem(struct ath10k *ar, u32 address,
* Request CE to send caller-supplied data that * Request CE to send caller-supplied data that
* was copied to bounce buffer to Target(!) address. * was copied to bounce buffer to Target(!) address.
*/ */
ret = ath10k_ce_send_nolock(ce_diag, NULL, ce_data_base, ret = ath10k_ce_send(ce_diag, NULL, ce_data_base, nbytes, 0, 0);
nbytes, 0, 0);
if (ret != 0) if (ret != 0)
goto done; goto done;
i = 0; i = 0;
while (ath10k_ce_completed_send_next_nolock(ce_diag, while (ath10k_ce_completed_send_next(ce_diag, NULL) != 0) {
NULL) != 0) {
udelay(DIAG_ACCESS_CE_WAIT_US); udelay(DIAG_ACCESS_CE_WAIT_US);
i += DIAG_ACCESS_CE_WAIT_US; i += DIAG_ACCESS_CE_WAIT_US;
@ -1144,10 +1123,8 @@ int ath10k_pci_diag_write_mem(struct ath10k *ar, u32 address,
} }
i = 0; i = 0;
while (ath10k_ce_completed_recv_next_nolock(ce_diag, while (ath10k_ce_completed_recv_next(ce_diag, (void **)&buf,
(void **)&buf, &completed_nbytes) != 0) {
&completed_nbytes)
!= 0) {
udelay(DIAG_ACCESS_CE_WAIT_US); udelay(DIAG_ACCESS_CE_WAIT_US);
i += DIAG_ACCESS_CE_WAIT_US; i += DIAG_ACCESS_CE_WAIT_US;
@ -1182,7 +1159,7 @@ int ath10k_pci_diag_write_mem(struct ath10k *ar, u32 address,
ath10k_warn(ar, "failed to write diag value at 0x%x: %d\n", ath10k_warn(ar, "failed to write diag value at 0x%x: %d\n",
address, ret); address, ret);
spin_unlock_bh(&ce->ce_lock); mutex_unlock(&ar_pci->ce_diag_mutex);
return ret; return ret;
} }
@ -2283,7 +2260,7 @@ static int ath10k_pci_get_num_banks(struct ath10k *ar)
return 1; return 1;
case QCA6164_2_1_DEVICE_ID: case QCA6164_2_1_DEVICE_ID:
case QCA6174_2_1_DEVICE_ID: case QCA6174_2_1_DEVICE_ID:
switch (MS(ar->chip_id, SOC_CHIP_ID_REV)) { switch (MS(ar->bus_param.chip_id, SOC_CHIP_ID_REV)) {
case QCA6174_HW_1_0_CHIP_ID_REV: case QCA6174_HW_1_0_CHIP_ID_REV:
case QCA6174_HW_1_1_CHIP_ID_REV: case QCA6174_HW_1_1_CHIP_ID_REV:
case QCA6174_HW_2_1_CHIP_ID_REV: case QCA6174_HW_2_1_CHIP_ID_REV:
@ -2806,7 +2783,8 @@ static int ath10k_pci_chip_reset(struct ath10k *ar)
return ar_pci->pci_hard_reset(ar); return ar_pci->pci_hard_reset(ar);
} }
static int ath10k_pci_hif_power_up(struct ath10k *ar) static int ath10k_pci_hif_power_up(struct ath10k *ar,
enum ath10k_firmware_mode fw_mode)
{ {
struct ath10k_pci *ar_pci = ath10k_pci_priv(ar); struct ath10k_pci *ar_pci = ath10k_pci_priv(ar);
int ret; int ret;
@ -3462,6 +3440,7 @@ int ath10k_pci_setup_resource(struct ath10k *ar)
spin_lock_init(&ce->ce_lock); spin_lock_init(&ce->ce_lock);
spin_lock_init(&ar_pci->ps_lock); spin_lock_init(&ar_pci->ps_lock);
mutex_init(&ar_pci->ce_diag_mutex);
timer_setup(&ar_pci->rx_post_retry, ath10k_pci_rx_replenish_retry, 0); timer_setup(&ar_pci->rx_post_retry, ath10k_pci_rx_replenish_retry, 0);
@ -3553,7 +3532,7 @@ static int ath10k_pci_probe(struct pci_dev *pdev,
case QCA9377_1_0_DEVICE_ID: case QCA9377_1_0_DEVICE_ID:
hw_rev = ATH10K_HW_QCA9377; hw_rev = ATH10K_HW_QCA9377;
pci_ps = true; pci_ps = true;
pci_soft_reset = NULL; pci_soft_reset = ath10k_pci_warm_reset;
pci_hard_reset = ath10k_pci_qca6174_chip_reset; pci_hard_reset = ath10k_pci_qca6174_chip_reset;
targ_cpu_to_ce_addr = ath10k_pci_qca6174_targ_cpu_to_ce_addr; targ_cpu_to_ce_addr = ath10k_pci_qca6174_targ_cpu_to_ce_addr;
break; break;
@ -3636,6 +3615,7 @@ static int ath10k_pci_probe(struct pci_dev *pdev,
} }
bus_params.dev_type = ATH10K_DEV_TYPE_LL; bus_params.dev_type = ATH10K_DEV_TYPE_LL;
bus_params.link_can_suspend = true;
bus_params.chip_id = ath10k_pci_soc_read32(ar, SOC_CHIP_ID_ADDRESS); bus_params.chip_id = ath10k_pci_soc_read32(ar, SOC_CHIP_ID_ADDRESS);
if (bus_params.chip_id == 0xffffffff) { if (bus_params.chip_id == 0xffffffff) {
ath10k_err(ar, "failed to get chip id\n"); ath10k_err(ar, "failed to get chip id\n");

View File

@ -1,24 +1,14 @@
/* SPDX-License-Identifier: ISC */
/* /*
* Copyright (c) 2005-2011 Atheros Communications Inc. * Copyright (c) 2005-2011 Atheros Communications Inc.
* Copyright (c) 2011-2017 Qualcomm Atheros, Inc. * Copyright (c) 2011-2017 Qualcomm Atheros, Inc.
*
* Permission to use, copy, modify, and/or distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/ */
#ifndef _PCI_H_ #ifndef _PCI_H_
#define _PCI_H_ #define _PCI_H_
#include <linux/interrupt.h> #include <linux/interrupt.h>
#include <linux/mutex.h>
#include "hw.h" #include "hw.h"
#include "ce.h" #include "ce.h"
@ -128,6 +118,8 @@ struct ath10k_pci {
/* Copy Engine used for Diagnostic Accesses */ /* Copy Engine used for Diagnostic Accesses */
struct ath10k_ce_pipe *ce_diag; struct ath10k_ce_pipe *ce_diag;
/* For protecting ce_diag */
struct mutex ce_diag_mutex;
struct ath10k_ce ce; struct ath10k_ce ce;
struct timer_list rx_post_retry; struct timer_list rx_post_retry;

View File

@ -1,17 +1,6 @@
// SPDX-License-Identifier: ISC
/* /*
* Copyright (c) 2018 The Linux Foundation. All rights reserved. * Copyright (c) 2018 The Linux Foundation. All rights reserved.
*
* Permission to use, copy, modify, and/or distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/ */
#include <linux/completion.h> #include <linux/completion.h>

View File

@ -1,17 +1,6 @@
/* SPDX-License-Identifier: ISC */
/* /*
* Copyright (c) 2018 The Linux Foundation. All rights reserved. * Copyright (c) 2018 The Linux Foundation. All rights reserved.
*
* Permission to use, copy, modify, and/or distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/ */
#ifndef _ATH10K_QMI_H_ #ifndef _ATH10K_QMI_H_
#define _ATH10K_QMI_H_ #define _ATH10K_QMI_H_

View File

@ -1,17 +1,6 @@
// SPDX-License-Identifier: ISC
/* /*
* Copyright (c) 2018 The Linux Foundation. All rights reserved. * Copyright (c) 2018 The Linux Foundation. All rights reserved.
*
* Permission to use, copy, modify, and/or distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/ */
#include <linux/soc/qcom/qmi.h> #include <linux/soc/qcom/qmi.h>
@ -1763,14 +1752,239 @@ struct qmi_elem_info wlfw_host_cap_req_msg_v01_ei[] = {
daemon_support_valid), daemon_support_valid),
}, },
{ {
.data_type = QMI_UNSIGNED_1_BYTE, .data_type = QMI_UNSIGNED_4_BYTE,
.elem_len = 1, .elem_len = 1,
.elem_size = sizeof(u8), .elem_size = sizeof(u32),
.array_type = NO_ARRAY, .array_type = NO_ARRAY,
.tlv_type = 0x10, .tlv_type = 0x10,
.offset = offsetof(struct wlfw_host_cap_req_msg_v01, .offset = offsetof(struct wlfw_host_cap_req_msg_v01,
daemon_support), daemon_support),
}, },
{
.data_type = QMI_OPT_FLAG,
.elem_len = 1,
.elem_size = sizeof(u8),
.array_type = NO_ARRAY,
.tlv_type = 0x11,
.offset = offsetof(struct wlfw_host_cap_req_msg_v01,
wake_msi_valid),
},
{
.data_type = QMI_UNSIGNED_4_BYTE,
.elem_len = 1,
.elem_size = sizeof(u32),
.array_type = NO_ARRAY,
.tlv_type = 0x11,
.offset = offsetof(struct wlfw_host_cap_req_msg_v01,
wake_msi),
},
{
.data_type = QMI_OPT_FLAG,
.elem_len = 1,
.elem_size = sizeof(u8),
.array_type = NO_ARRAY,
.tlv_type = 0x12,
.offset = offsetof(struct wlfw_host_cap_req_msg_v01,
gpios_valid),
},
{
.data_type = QMI_DATA_LEN,
.elem_len = 1,
.elem_size = sizeof(u32),
.array_type = NO_ARRAY,
.tlv_type = 0x12,
.offset = offsetof(struct wlfw_host_cap_req_msg_v01,
gpios_len),
},
{
.data_type = QMI_UNSIGNED_4_BYTE,
.elem_len = QMI_WLFW_MAX_NUM_GPIO_V01,
.elem_size = sizeof(u32),
.array_type = VAR_LEN_ARRAY,
.tlv_type = 0x12,
.offset = offsetof(struct wlfw_host_cap_req_msg_v01,
gpios),
},
{
.data_type = QMI_OPT_FLAG,
.elem_len = 1,
.elem_size = sizeof(u8),
.array_type = NO_ARRAY,
.tlv_type = 0x13,
.offset = offsetof(struct wlfw_host_cap_req_msg_v01,
nm_modem_valid),
},
{
.data_type = QMI_UNSIGNED_1_BYTE,
.elem_len = 1,
.elem_size = sizeof(u8),
.array_type = NO_ARRAY,
.tlv_type = 0x13,
.offset = offsetof(struct wlfw_host_cap_req_msg_v01,
nm_modem),
},
{
.data_type = QMI_OPT_FLAG,
.elem_len = 1,
.elem_size = sizeof(u8),
.array_type = NO_ARRAY,
.tlv_type = 0x14,
.offset = offsetof(struct wlfw_host_cap_req_msg_v01,
bdf_support_valid),
},
{
.data_type = QMI_UNSIGNED_1_BYTE,
.elem_len = 1,
.elem_size = sizeof(u8),
.array_type = NO_ARRAY,
.tlv_type = 0x14,
.offset = offsetof(struct wlfw_host_cap_req_msg_v01,
bdf_support),
},
{
.data_type = QMI_OPT_FLAG,
.elem_len = 1,
.elem_size = sizeof(u8),
.array_type = NO_ARRAY,
.tlv_type = 0x15,
.offset = offsetof(struct wlfw_host_cap_req_msg_v01,
bdf_cache_support_valid),
},
{
.data_type = QMI_UNSIGNED_1_BYTE,
.elem_len = 1,
.elem_size = sizeof(u8),
.array_type = NO_ARRAY,
.tlv_type = 0x15,
.offset = offsetof(struct wlfw_host_cap_req_msg_v01,
bdf_cache_support),
},
{
.data_type = QMI_OPT_FLAG,
.elem_len = 1,
.elem_size = sizeof(u8),
.array_type = NO_ARRAY,
.tlv_type = 0x16,
.offset = offsetof(struct wlfw_host_cap_req_msg_v01,
m3_support_valid),
},
{
.data_type = QMI_UNSIGNED_1_BYTE,
.elem_len = 1,
.elem_size = sizeof(u8),
.array_type = NO_ARRAY,
.tlv_type = 0x16,
.offset = offsetof(struct wlfw_host_cap_req_msg_v01,
m3_support),
},
{
.data_type = QMI_OPT_FLAG,
.elem_len = 1,
.elem_size = sizeof(u8),
.array_type = NO_ARRAY,
.tlv_type = 0x17,
.offset = offsetof(struct wlfw_host_cap_req_msg_v01,
m3_cache_support_valid),
},
{
.data_type = QMI_UNSIGNED_1_BYTE,
.elem_len = 1,
.elem_size = sizeof(u8),
.array_type = NO_ARRAY,
.tlv_type = 0x17,
.offset = offsetof(struct wlfw_host_cap_req_msg_v01,
m3_cache_support),
},
{
.data_type = QMI_OPT_FLAG,
.elem_len = 1,
.elem_size = sizeof(u8),
.array_type = NO_ARRAY,
.tlv_type = 0x18,
.offset = offsetof(struct wlfw_host_cap_req_msg_v01,
cal_filesys_support_valid),
},
{
.data_type = QMI_UNSIGNED_1_BYTE,
.elem_len = 1,
.elem_size = sizeof(u8),
.array_type = NO_ARRAY,
.tlv_type = 0x18,
.offset = offsetof(struct wlfw_host_cap_req_msg_v01,
cal_filesys_support),
},
{
.data_type = QMI_OPT_FLAG,
.elem_len = 1,
.elem_size = sizeof(u8),
.array_type = NO_ARRAY,
.tlv_type = 0x19,
.offset = offsetof(struct wlfw_host_cap_req_msg_v01,
cal_cache_support_valid),
},
{
.data_type = QMI_UNSIGNED_1_BYTE,
.elem_len = 1,
.elem_size = sizeof(u8),
.array_type = NO_ARRAY,
.tlv_type = 0x19,
.offset = offsetof(struct wlfw_host_cap_req_msg_v01,
cal_cache_support),
},
{
.data_type = QMI_OPT_FLAG,
.elem_len = 1,
.elem_size = sizeof(u8),
.array_type = NO_ARRAY,
.tlv_type = 0x1A,
.offset = offsetof(struct wlfw_host_cap_req_msg_v01,
cal_done_valid),
},
{
.data_type = QMI_UNSIGNED_1_BYTE,
.elem_len = 1,
.elem_size = sizeof(u8),
.array_type = NO_ARRAY,
.tlv_type = 0x1A,
.offset = offsetof(struct wlfw_host_cap_req_msg_v01,
cal_done),
},
{
.data_type = QMI_OPT_FLAG,
.elem_len = 1,
.elem_size = sizeof(u8),
.array_type = NO_ARRAY,
.tlv_type = 0x1B,
.offset = offsetof(struct wlfw_host_cap_req_msg_v01,
mem_bucket_valid),
},
{
.data_type = QMI_UNSIGNED_4_BYTE,
.elem_len = 1,
.elem_size = sizeof(u32),
.array_type = NO_ARRAY,
.tlv_type = 0x1B,
.offset = offsetof(struct wlfw_host_cap_req_msg_v01,
mem_bucket),
},
{
.data_type = QMI_OPT_FLAG,
.elem_len = 1,
.elem_size = sizeof(u8),
.array_type = NO_ARRAY,
.tlv_type = 0x1C,
.offset = offsetof(struct wlfw_host_cap_req_msg_v01,
mem_cfg_mode_valid),
},
{
.data_type = QMI_UNSIGNED_1_BYTE,
.elem_len = 1,
.elem_size = sizeof(u8),
.array_type = NO_ARRAY,
.tlv_type = 0x1C,
.offset = offsetof(struct wlfw_host_cap_req_msg_v01,
mem_cfg_mode),
},
{} {}
}; };

View File

@ -1,17 +1,6 @@
/* SPDX-License-Identifier: ISC */
/* /*
* Copyright (c) 2018 The Linux Foundation. All rights reserved. * Copyright (c) 2018 The Linux Foundation. All rights reserved.
*
* Permission to use, copy, modify, and/or distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/ */
#ifndef WCN3990_QMI_SVC_V01_H #ifndef WCN3990_QMI_SVC_V01_H
@ -553,12 +542,38 @@ struct wlfw_mac_addr_resp_msg_v01 {
#define WLFW_MAC_ADDR_RESP_MSG_V01_MAX_MSG_LEN 7 #define WLFW_MAC_ADDR_RESP_MSG_V01_MAX_MSG_LEN 7
extern struct qmi_elem_info wlfw_mac_addr_resp_msg_v01_ei[]; extern struct qmi_elem_info wlfw_mac_addr_resp_msg_v01_ei[];
#define QMI_WLFW_MAX_NUM_GPIO_V01 32
struct wlfw_host_cap_req_msg_v01 { struct wlfw_host_cap_req_msg_v01 {
u8 daemon_support_valid; u8 daemon_support_valid;
u8 daemon_support; u32 daemon_support;
u8 wake_msi_valid;
u32 wake_msi;
u8 gpios_valid;
u32 gpios_len;
u32 gpios[QMI_WLFW_MAX_NUM_GPIO_V01];
u8 nm_modem_valid;
u8 nm_modem;
u8 bdf_support_valid;
u8 bdf_support;
u8 bdf_cache_support_valid;
u8 bdf_cache_support;
u8 m3_support_valid;
u8 m3_support;
u8 m3_cache_support_valid;
u8 m3_cache_support;
u8 cal_filesys_support_valid;
u8 cal_filesys_support;
u8 cal_cache_support_valid;
u8 cal_cache_support;
u8 cal_done_valid;
u8 cal_done;
u8 mem_bucket_valid;
u32 mem_bucket;
u8 mem_cfg_mode_valid;
u8 mem_cfg_mode;
}; };
#define WLFW_HOST_CAP_REQ_MSG_V01_MAX_MSG_LEN 4 #define WLFW_HOST_CAP_REQ_MSG_V01_MAX_MSG_LEN 189
extern struct qmi_elem_info wlfw_host_cap_req_msg_v01_ei[]; extern struct qmi_elem_info wlfw_host_cap_req_msg_v01_ei[];
struct wlfw_host_cap_resp_msg_v01 { struct wlfw_host_cap_resp_msg_v01 {

View File

@ -1,18 +1,7 @@
/* SPDX-License-Identifier: ISC */
/* /*
* Copyright (c) 2005-2011 Atheros Communications Inc. * Copyright (c) 2005-2011 Atheros Communications Inc.
* Copyright (c) 2011-2017 Qualcomm Atheros, Inc. * Copyright (c) 2011-2017 Qualcomm Atheros, Inc.
*
* Permission to use, copy, modify, and/or distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/ */
#ifndef _RX_DESC_H_ #ifndef _RX_DESC_H_

View File

@ -1,19 +1,8 @@
// SPDX-License-Identifier: ISC
/* /*
* Copyright (c) 2004-2011 Atheros Communications Inc. * Copyright (c) 2004-2011 Atheros Communications Inc.
* Copyright (c) 2011-2012,2017 Qualcomm Atheros, Inc. * Copyright (c) 2011-2012,2017 Qualcomm Atheros, Inc.
* Copyright (c) 2016-2017 Erik Stromdahl <erik.stromdahl@gmail.com> * Copyright (c) 2016-2017 Erik Stromdahl <erik.stromdahl@gmail.com>
*
* Permission to use, copy, modify, and/or distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/ */
#include <linux/module.h> #include <linux/module.h>
@ -1381,7 +1370,8 @@ static int ath10k_sdio_hif_disable_intrs(struct ath10k *ar)
return ret; return ret;
} }
static int ath10k_sdio_hif_power_up(struct ath10k *ar) static int ath10k_sdio_hif_power_up(struct ath10k *ar,
enum ath10k_firmware_mode fw_mode)
{ {
struct ath10k_sdio *ar_sdio = ath10k_sdio_priv(ar); struct ath10k_sdio *ar_sdio = ath10k_sdio_priv(ar);
struct sdio_func *func = ar_sdio->func; struct sdio_func *func = ar_sdio->func;
@ -1615,12 +1605,33 @@ static int ath10k_sdio_hif_diag_write_mem(struct ath10k *ar, u32 address,
return 0; return 0;
} }
static int ath10k_sdio_hif_swap_mailbox(struct ath10k *ar)
{
struct ath10k_sdio *ar_sdio = ath10k_sdio_priv(ar);
u32 addr, val;
int ret = 0;
addr = host_interest_item_address(HI_ITEM(hi_acs_flags));
ret = ath10k_sdio_hif_diag_read32(ar, addr, &val);
if (ret) {
ath10k_warn(ar, "unable to read hi_acs_flags : %d\n", ret);
return ret;
}
if (val & HI_ACS_FLAGS_SDIO_SWAP_MAILBOX_FW_ACK) {
ath10k_dbg(ar, ATH10K_DBG_SDIO,
"sdio mailbox swap service enabled\n");
ar_sdio->swap_mbox = true;
}
return 0;
}
/* HIF start/stop */ /* HIF start/stop */
static int ath10k_sdio_hif_start(struct ath10k *ar) static int ath10k_sdio_hif_start(struct ath10k *ar)
{ {
struct ath10k_sdio *ar_sdio = ath10k_sdio_priv(ar); struct ath10k_sdio *ar_sdio = ath10k_sdio_priv(ar);
u32 addr, val;
int ret; int ret;
/* Sleep 20 ms before HIF interrupts are disabled. /* Sleep 20 ms before HIF interrupts are disabled.
@ -1654,20 +1665,6 @@ static int ath10k_sdio_hif_start(struct ath10k *ar)
if (ret) if (ret)
ath10k_warn(ar, "failed to enable sdio interrupts: %d\n", ret); ath10k_warn(ar, "failed to enable sdio interrupts: %d\n", ret);
addr = host_interest_item_address(HI_ITEM(hi_acs_flags));
ret = ath10k_sdio_hif_diag_read32(ar, addr, &val);
if (ret) {
ath10k_warn(ar, "unable to read hi_acs_flags address: %d\n", ret);
return ret;
}
if (val & HI_ACS_FLAGS_SDIO_SWAP_MAILBOX_FW_ACK) {
ath10k_dbg(ar, ATH10K_DBG_SDIO,
"sdio mailbox swap service enabled\n");
ar_sdio->swap_mbox = true;
}
/* Enable sleep and then disable it again */ /* Enable sleep and then disable it again */
ret = ath10k_sdio_hif_set_mbox_sleep(ar, true); ret = ath10k_sdio_hif_set_mbox_sleep(ar, true);
if (ret) if (ret)
@ -1898,6 +1895,7 @@ static const struct ath10k_hif_ops ath10k_sdio_hif_ops = {
.exchange_bmi_msg = ath10k_sdio_bmi_exchange_msg, .exchange_bmi_msg = ath10k_sdio_bmi_exchange_msg,
.start = ath10k_sdio_hif_start, .start = ath10k_sdio_hif_start,
.stop = ath10k_sdio_hif_stop, .stop = ath10k_sdio_hif_stop,
.swap_mailbox = ath10k_sdio_hif_swap_mailbox,
.map_service_to_pipe = ath10k_sdio_hif_map_service_to_pipe, .map_service_to_pipe = ath10k_sdio_hif_map_service_to_pipe,
.get_default_pipe = ath10k_sdio_hif_get_default_pipe, .get_default_pipe = ath10k_sdio_hif_get_default_pipe,
.send_complete_check = ath10k_sdio_hif_send_complete_check, .send_complete_check = ath10k_sdio_hif_send_complete_check,
@ -2088,7 +2086,10 @@ static struct sdio_driver ath10k_sdio_driver = {
.id_table = ath10k_sdio_devices, .id_table = ath10k_sdio_devices,
.probe = ath10k_sdio_probe, .probe = ath10k_sdio_probe,
.remove = ath10k_sdio_remove, .remove = ath10k_sdio_remove,
.drv.pm = ATH10K_SDIO_PM_OPS, .drv = {
.owner = THIS_MODULE,
.pm = ATH10K_SDIO_PM_OPS,
},
}; };
static int __init ath10k_sdio_init(void) static int __init ath10k_sdio_init(void)

View File

@ -1,19 +1,8 @@
/* SPDX-License-Identifier: ISC */
/* /*
* Copyright (c) 2004-2011 Atheros Communications Inc. * Copyright (c) 2004-2011 Atheros Communications Inc.
* Copyright (c) 2011-2012 Qualcomm Atheros, Inc. * Copyright (c) 2011-2012 Qualcomm Atheros, Inc.
* Copyright (c) 2016-2017 Erik Stromdahl <erik.stromdahl@gmail.com> * Copyright (c) 2016-2017 Erik Stromdahl <erik.stromdahl@gmail.com>
*
* Permission to use, copy, modify, and/or distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/ */
#ifndef _SDIO_H_ #ifndef _SDIO_H_

View File

@ -1,17 +1,6 @@
// SPDX-License-Identifier: ISC
/* /*
* Copyright (c) 2018 The Linux Foundation. All rights reserved. * Copyright (c) 2018 The Linux Foundation. All rights reserved.
*
* Permission to use, copy, modify, and/or distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/ */
#include <linux/clk.h> #include <linux/clk.h>
@ -30,6 +19,7 @@
#define ATH10K_SNOC_RX_POST_RETRY_MS 50 #define ATH10K_SNOC_RX_POST_RETRY_MS 50
#define CE_POLL_PIPE 4 #define CE_POLL_PIPE 4
#define ATH10K_SNOC_WAKE_IRQ 2
static char *const ce_name[] = { static char *const ce_name[] = {
"WLAN_CE_0", "WLAN_CE_0",
@ -66,7 +56,7 @@ static void ath10k_snoc_pktlog_rx_cb(struct ath10k_ce_pipe *ce_state);
static const struct ath10k_snoc_drv_priv drv_priv = { static const struct ath10k_snoc_drv_priv drv_priv = {
.hw_rev = ATH10K_HW_WCN3990, .hw_rev = ATH10K_HW_WCN3990,
.dma_mask = DMA_BIT_MASK(37), .dma_mask = DMA_BIT_MASK(35),
.msa_size = 0x100000, .msa_size = 0x100000,
}; };
@ -875,13 +865,11 @@ static void ath10k_snoc_tx_pipe_cleanup(struct ath10k_snoc_pipe *snoc_pipe)
{ {
struct ath10k_ce_pipe *ce_pipe; struct ath10k_ce_pipe *ce_pipe;
struct ath10k_ce_ring *ce_ring; struct ath10k_ce_ring *ce_ring;
struct ath10k_snoc *ar_snoc;
struct sk_buff *skb; struct sk_buff *skb;
struct ath10k *ar; struct ath10k *ar;
int i; int i;
ar = snoc_pipe->hif_ce_state; ar = snoc_pipe->hif_ce_state;
ar_snoc = ath10k_snoc_priv(ar);
ce_pipe = snoc_pipe->ce_hdl; ce_pipe = snoc_pipe->ce_hdl;
ce_ring = ce_pipe->src_ring; ce_ring = ce_pipe->src_ring;
@ -958,7 +946,8 @@ static int ath10k_snoc_init_pipes(struct ath10k *ar)
return 0; return 0;
} }
static int ath10k_snoc_wlan_enable(struct ath10k *ar) static int ath10k_snoc_wlan_enable(struct ath10k *ar,
enum ath10k_firmware_mode fw_mode)
{ {
struct ath10k_tgt_pipe_cfg tgt_cfg[CE_COUNT_MAX]; struct ath10k_tgt_pipe_cfg tgt_cfg[CE_COUNT_MAX];
struct ath10k_qmi_wlan_enable_cfg cfg; struct ath10k_qmi_wlan_enable_cfg cfg;
@ -992,7 +981,17 @@ static int ath10k_snoc_wlan_enable(struct ath10k *ar)
cfg.shadow_reg_cfg = (struct ath10k_shadow_reg_cfg *) cfg.shadow_reg_cfg = (struct ath10k_shadow_reg_cfg *)
&target_shadow_reg_cfg_map; &target_shadow_reg_cfg_map;
switch (fw_mode) {
case ATH10K_FIRMWARE_MODE_NORMAL:
mode = QMI_WLFW_MISSION_V01; mode = QMI_WLFW_MISSION_V01;
break;
case ATH10K_FIRMWARE_MODE_UTF:
mode = QMI_WLFW_FTM_V01;
break;
default:
ath10k_err(ar, "invalid firmware mode %d\n", fw_mode);
return -EINVAL;
}
return ath10k_qmi_wlan_enable(ar, &cfg, mode, return ath10k_qmi_wlan_enable(ar, &cfg, mode,
NULL); NULL);
@ -1000,7 +999,16 @@ static int ath10k_snoc_wlan_enable(struct ath10k *ar)
static void ath10k_snoc_wlan_disable(struct ath10k *ar) static void ath10k_snoc_wlan_disable(struct ath10k *ar)
{ {
if (!test_bit(ATH10K_FLAG_CRASH_FLUSH, &ar->dev_flags)) struct ath10k_snoc *ar_snoc = ath10k_snoc_priv(ar);
/* If both ATH10K_FLAG_CRASH_FLUSH and ATH10K_SNOC_FLAG_RECOVERY
* flags are not set, it means that the driver has restarted
* due to a crash inject via debugfs. In this case, the driver
* needs to restart the firmware and hence send qmi wlan disable,
* during the driver restart sequence.
*/
if (!test_bit(ATH10K_FLAG_CRASH_FLUSH, &ar->dev_flags) ||
!test_bit(ATH10K_SNOC_FLAG_RECOVERY, &ar_snoc->flags))
ath10k_qmi_wlan_disable(ar); ath10k_qmi_wlan_disable(ar);
} }
@ -1012,14 +1020,15 @@ static void ath10k_snoc_hif_power_down(struct ath10k *ar)
ath10k_ce_free_rri(ar); ath10k_ce_free_rri(ar);
} }
static int ath10k_snoc_hif_power_up(struct ath10k *ar) static int ath10k_snoc_hif_power_up(struct ath10k *ar,
enum ath10k_firmware_mode fw_mode)
{ {
int ret; int ret;
ath10k_dbg(ar, ATH10K_DBG_SNOC, "%s:WCN3990 driver state = %d\n", ath10k_dbg(ar, ATH10K_DBG_SNOC, "%s:WCN3990 driver state = %d\n",
__func__, ar->state); __func__, ar->state);
ret = ath10k_snoc_wlan_enable(ar); ret = ath10k_snoc_wlan_enable(ar, fw_mode);
if (ret) { if (ret) {
ath10k_err(ar, "failed to enable wcn3990: %d\n", ret); ath10k_err(ar, "failed to enable wcn3990: %d\n", ret);
return ret; return ret;
@ -1041,6 +1050,46 @@ static int ath10k_snoc_hif_power_up(struct ath10k *ar)
return ret; return ret;
} }
#ifdef CONFIG_PM
static int ath10k_snoc_hif_suspend(struct ath10k *ar)
{
struct ath10k_snoc *ar_snoc = ath10k_snoc_priv(ar);
int ret;
if (!device_may_wakeup(ar->dev))
return -EPERM;
ret = enable_irq_wake(ar_snoc->ce_irqs[ATH10K_SNOC_WAKE_IRQ].irq_line);
if (ret) {
ath10k_err(ar, "failed to enable wakeup irq :%d\n", ret);
return ret;
}
ath10k_dbg(ar, ATH10K_DBG_SNOC, "snoc device suspended\n");
return ret;
}
static int ath10k_snoc_hif_resume(struct ath10k *ar)
{
struct ath10k_snoc *ar_snoc = ath10k_snoc_priv(ar);
int ret;
if (!device_may_wakeup(ar->dev))
return -EPERM;
ret = disable_irq_wake(ar_snoc->ce_irqs[ATH10K_SNOC_WAKE_IRQ].irq_line);
if (ret) {
ath10k_err(ar, "failed to disable wakeup irq: %d\n", ret);
return ret;
}
ath10k_dbg(ar, ATH10K_DBG_SNOC, "snoc device resumed\n");
return ret;
}
#endif
static const struct ath10k_hif_ops ath10k_snoc_hif_ops = { static const struct ath10k_hif_ops ath10k_snoc_hif_ops = {
.read32 = ath10k_snoc_read32, .read32 = ath10k_snoc_read32,
.write32 = ath10k_snoc_write32, .write32 = ath10k_snoc_write32,
@ -1054,6 +1103,10 @@ static const struct ath10k_hif_ops ath10k_snoc_hif_ops = {
.send_complete_check = ath10k_snoc_hif_send_complete_check, .send_complete_check = ath10k_snoc_hif_send_complete_check,
.get_free_queue_number = ath10k_snoc_hif_get_free_queue_number, .get_free_queue_number = ath10k_snoc_hif_get_free_queue_number,
.get_target_info = ath10k_snoc_hif_get_target_info, .get_target_info = ath10k_snoc_hif_get_target_info,
#ifdef CONFIG_PM
.suspend = ath10k_snoc_hif_suspend,
.resume = ath10k_snoc_hif_resume,
#endif
}; };
static const struct ath10k_bus_ops ath10k_snoc_bus_ops = { static const struct ath10k_bus_ops ath10k_snoc_bus_ops = {

View File

@ -1,17 +1,6 @@
/* SPDX-License-Identifier: ISC */
/* /*
* Copyright (c) 2018 The Linux Foundation. All rights reserved. * Copyright (c) 2018 The Linux Foundation. All rights reserved.
*
* Permission to use, copy, modify, and/or distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/ */
#ifndef _SNOC_H_ #ifndef _SNOC_H_
@ -90,7 +79,7 @@ struct ath10k_snoc {
struct ath10k_vreg_info *vreg; struct ath10k_vreg_info *vreg;
struct ath10k_clk_info *clk; struct ath10k_clk_info *clk;
struct ath10k_qmi *qmi; struct ath10k_qmi *qmi;
unsigned long int flags; unsigned long flags;
}; };
static inline struct ath10k_snoc *ath10k_snoc_priv(struct ath10k *ar) static inline struct ath10k_snoc *ath10k_snoc_priv(struct ath10k *ar)

View File

@ -1,17 +1,6 @@
// SPDX-License-Identifier: ISC
/* /*
* Copyright (c) 2013-2017 Qualcomm Atheros, Inc. * Copyright (c) 2013-2017 Qualcomm Atheros, Inc.
*
* Permission to use, copy, modify, and/or distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/ */
#include <linux/relay.h> #include <linux/relay.h>
@ -494,6 +483,9 @@ static struct dentry *create_buf_file_handler(const char *filename,
buf_file = debugfs_create_file(filename, mode, parent, buf, buf_file = debugfs_create_file(filename, mode, parent, buf,
&relay_file_operations); &relay_file_operations);
if (IS_ERR(buf_file))
return NULL;
*is_global = 1; *is_global = 1;
return buf_file; return buf_file;
} }

View File

@ -1,17 +1,6 @@
/* SPDX-License-Identifier: ISC */
/* /*
* Copyright (c) 2013-2015 Qualcomm Atheros, Inc. * Copyright (c) 2013-2015 Qualcomm Atheros, Inc.
*
* Permission to use, copy, modify, and/or distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/ */
#ifndef SPECTRAL_H #ifndef SPECTRAL_H

View File

@ -1,17 +1,6 @@
// SPDX-License-Identifier: ISC
/* /*
* Copyright (c) 2015-2016 Qualcomm Atheros, Inc. * Copyright (c) 2015-2016 Qualcomm Atheros, Inc.
*
* Permission to use, copy, modify, and/or distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/ */
/* This file has implementation for code swap logic. With code swap feature, /* This file has implementation for code swap logic. With code swap feature,

View File

@ -1,17 +1,6 @@
/* SPDX-License-Identifier: ISC */
/* /*
* Copyright (c) 2015-2016 Qualcomm Atheros, Inc. * Copyright (c) 2015-2016 Qualcomm Atheros, Inc.
*
* Permission to use, copy, modify, and/or distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/ */
#ifndef _SWAP_H_ #ifndef _SWAP_H_

View File

@ -1,18 +1,7 @@
/* SPDX-License-Identifier: ISC */
/* /*
* Copyright (c) 2005-2011 Atheros Communications Inc. * Copyright (c) 2005-2011 Atheros Communications Inc.
* Copyright (c) 2011-2016 Qualcomm Atheros, Inc. * Copyright (c) 2011-2016 Qualcomm Atheros, Inc.
*
* Permission to use, copy, modify, and/or distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/ */
#ifndef __TARGADDRS_H__ #ifndef __TARGADDRS_H__

View File

@ -1,17 +1,6 @@
// SPDX-License-Identifier: ISC
/* /*
* Copyright (c) 2014-2017 Qualcomm Atheros, Inc. * Copyright (c) 2014-2017 Qualcomm Atheros, Inc.
*
* Permission to use, copy, modify, and/or distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/ */
#include "testmode.h" #include "testmode.h"
@ -270,7 +259,7 @@ static int ath10k_tm_cmd_utf_start(struct ath10k *ar, struct nlattr *tb[])
ath10k_dbg(ar, ATH10K_DBG_TESTMODE, "testmode wmi version %d\n", ath10k_dbg(ar, ATH10K_DBG_TESTMODE, "testmode wmi version %d\n",
ar->testmode.utf_mode_fw.fw_file.wmi_op_version); ar->testmode.utf_mode_fw.fw_file.wmi_op_version);
ret = ath10k_hif_power_up(ar); ret = ath10k_hif_power_up(ar, ATH10K_FIRMWARE_MODE_UTF);
if (ret) { if (ret) {
ath10k_err(ar, "failed to power up hif (testmode): %d\n", ret); ath10k_err(ar, "failed to power up hif (testmode): %d\n", ret);
ar->state = ATH10K_STATE_OFF; ar->state = ATH10K_STATE_OFF;

View File

@ -1,17 +1,6 @@
/* SPDX-License-Identifier: ISC */
/* /*
* Copyright (c) 2014 Qualcomm Atheros, Inc. * Copyright (c) 2014 Qualcomm Atheros, Inc.
*
* Permission to use, copy, modify, and/or distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/ */
#include "core.h" #include "core.h"

View File

@ -1,17 +1,6 @@
/* SPDX-License-Identifier: ISC */
/* /*
* Copyright (c) 2014,2017 Qualcomm Atheros, Inc. * Copyright (c) 2014,2017 Qualcomm Atheros, Inc.
*
* Permission to use, copy, modify, and/or distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/ */
/* "API" level of the ath10k testmode interface. Bump it after every /* "API" level of the ath10k testmode interface. Bump it after every

View File

@ -1,17 +1,6 @@
// SPDX-License-Identifier: ISC
/* /*
* Copyright (c) 2014-2015 Qualcomm Atheros, Inc. * Copyright (c) 2014-2015 Qualcomm Atheros, Inc.
*
* Permission to use, copy, modify, and/or distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/ */
#include <linux/device.h> #include <linux/device.h>

View File

@ -1,17 +1,6 @@
/* SPDX-License-Identifier: ISC */
/* /*
* Copyright (c) 2014-2016 Qualcomm Atheros, Inc. * Copyright (c) 2014-2016 Qualcomm Atheros, Inc.
*
* Permission to use, copy, modify, and/or distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/ */
#ifndef _THERMAL_ #ifndef _THERMAL_
#define _THERMAL_ #define _THERMAL_

View File

@ -1,17 +1,6 @@
// SPDX-License-Identifier: ISC
/* /*
* Copyright (c) 2012 Qualcomm Atheros, Inc. * Copyright (c) 2012 Qualcomm Atheros, Inc.
*
* Permission to use, copy, modify, and/or distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/ */
#include <linux/module.h> #include <linux/module.h>

View File

@ -1,18 +1,7 @@
/* SPDX-License-Identifier: ISC */
/* /*
* Copyright (c) 2005-2011 Atheros Communications Inc. * Copyright (c) 2005-2011 Atheros Communications Inc.
* Copyright (c) 2011-2016 Qualcomm Atheros, Inc. * Copyright (c) 2011-2016 Qualcomm Atheros, Inc.
*
* Permission to use, copy, modify, and/or distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/ */
#if !defined(_TRACE_H_) || defined(TRACE_HEADER_MULTI_READ) #if !defined(_TRACE_H_) || defined(TRACE_HEADER_MULTI_READ)

View File

@ -1,19 +1,8 @@
// SPDX-License-Identifier: ISC
/* /*
* Copyright (c) 2005-2011 Atheros Communications Inc. * Copyright (c) 2005-2011 Atheros Communications Inc.
* Copyright (c) 2011-2016 Qualcomm Atheros, Inc. * Copyright (c) 2011-2016 Qualcomm Atheros, Inc.
* Copyright (c) 2018, The Linux Foundation. All rights reserved. * Copyright (c) 2018, The Linux Foundation. All rights reserved.
*
* Permission to use, copy, modify, and/or distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/ */
#include "core.h" #include "core.h"
@ -95,7 +84,11 @@ int ath10k_txrx_tx_unref(struct ath10k_htt *htt,
wake_up(&htt->empty_tx_wq); wake_up(&htt->empty_tx_wq);
spin_unlock_bh(&htt->tx_lock); spin_unlock_bh(&htt->tx_lock);
if (ar->dev_type != ATH10K_DEV_TYPE_HL) if (txq && txq->sta && skb_cb->airtime_est)
ieee80211_sta_register_airtime(txq->sta, txq->tid,
skb_cb->airtime_est, 0);
if (ar->bus_param.dev_type != ATH10K_DEV_TYPE_HL)
dma_unmap_single(dev, skb_cb->paddr, msdu->len, DMA_TO_DEVICE); dma_unmap_single(dev, skb_cb->paddr, msdu->len, DMA_TO_DEVICE);
ath10k_report_offchan_tx(htt->ar, msdu); ath10k_report_offchan_tx(htt->ar, msdu);

View File

@ -1,18 +1,7 @@
/* SPDX-License-Identifier: ISC */
/* /*
* Copyright (c) 2005-2011 Atheros Communications Inc. * Copyright (c) 2005-2011 Atheros Communications Inc.
* Copyright (c) 2011-2014,2016 Qualcomm Atheros, Inc. * Copyright (c) 2011-2014,2016 Qualcomm Atheros, Inc.
*
* Permission to use, copy, modify, and/or distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/ */
#ifndef _TXRX_H_ #ifndef _TXRX_H_
#define _TXRX_H_ #define _TXRX_H_

View File

@ -1,19 +1,8 @@
// SPDX-License-Identifier: ISC
/* /*
* Copyright (c) 2007-2011 Atheros Communications Inc. * Copyright (c) 2007-2011 Atheros Communications Inc.
* Copyright (c) 2011-2012,2017 Qualcomm Atheros, Inc. * Copyright (c) 2011-2012,2017 Qualcomm Atheros, Inc.
* Copyright (c) 2016-2017 Erik Stromdahl <erik.stromdahl@gmail.com> * Copyright (c) 2016-2017 Erik Stromdahl <erik.stromdahl@gmail.com>
*
* Permission to use, copy, modify, and/or distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/ */
#include <linux/module.h> #include <linux/module.h>
@ -706,7 +695,8 @@ static void ath10k_usb_hif_send_complete_check(struct ath10k *ar,
{ {
} }
static int ath10k_usb_hif_power_up(struct ath10k *ar) static int ath10k_usb_hif_power_up(struct ath10k *ar,
enum ath10k_firmware_mode fw_mode)
{ {
return 0; return 0;
} }

View File

@ -1,19 +1,8 @@
/* SPDX-License-Identifier: ISC */
/* /*
* Copyright (c) 2004-2011 Atheros Communications Inc. * Copyright (c) 2004-2011 Atheros Communications Inc.
* Copyright (c) 2011-2012 Qualcomm Atheros, Inc. * Copyright (c) 2011-2012 Qualcomm Atheros, Inc.
* Copyright (c) 2016-2017 Erik Stromdahl <erik.stromdahl@gmail.com> * Copyright (c) 2016-2017 Erik Stromdahl <erik.stromdahl@gmail.com>
*
* Permission to use, copy, modify, and/or distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/ */
#ifndef _USB_H_ #ifndef _USB_H_

View File

@ -1,19 +1,8 @@
/* SPDX-License-Identifier: ISC */
/* /*
* Copyright (c) 2005-2011 Atheros Communications Inc. * Copyright (c) 2005-2011 Atheros Communications Inc.
* Copyright (c) 2011-2017 Qualcomm Atheros, Inc. * Copyright (c) 2011-2017 Qualcomm Atheros, Inc.
* Copyright (c) 2018, The Linux Foundation. All rights reserved. * Copyright (c) 2018, The Linux Foundation. All rights reserved.
*
* Permission to use, copy, modify, and/or distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/ */
#ifndef _WMI_OPS_H_ #ifndef _WMI_OPS_H_
@ -33,6 +22,9 @@ struct wmi_ops {
struct wmi_mgmt_rx_ev_arg *arg); struct wmi_mgmt_rx_ev_arg *arg);
int (*pull_mgmt_tx_compl)(struct ath10k *ar, struct sk_buff *skb, int (*pull_mgmt_tx_compl)(struct ath10k *ar, struct sk_buff *skb,
struct wmi_tlv_mgmt_tx_compl_ev_arg *arg); struct wmi_tlv_mgmt_tx_compl_ev_arg *arg);
int (*pull_mgmt_tx_bundle_compl)(
struct ath10k *ar, struct sk_buff *skb,
struct wmi_tlv_mgmt_tx_bundle_compl_ev_arg *arg);
int (*pull_ch_info)(struct ath10k *ar, struct sk_buff *skb, int (*pull_ch_info)(struct ath10k *ar, struct sk_buff *skb,
struct wmi_ch_info_ev_arg *arg); struct wmi_ch_info_ev_arg *arg);
int (*pull_vdev_start)(struct ath10k *ar, struct sk_buff *skb, int (*pull_vdev_start)(struct ath10k *ar, struct sk_buff *skb,
@ -66,6 +58,8 @@ struct wmi_ops {
struct sk_buff *(*gen_pdev_suspend)(struct ath10k *ar, u32 suspend_opt); struct sk_buff *(*gen_pdev_suspend)(struct ath10k *ar, u32 suspend_opt);
struct sk_buff *(*gen_pdev_resume)(struct ath10k *ar); struct sk_buff *(*gen_pdev_resume)(struct ath10k *ar);
struct sk_buff *(*gen_pdev_set_base_macaddr)(struct ath10k *ar,
const u8 macaddr[ETH_ALEN]);
struct sk_buff *(*gen_pdev_set_rd)(struct ath10k *ar, u16 rd, u16 rd2g, struct sk_buff *(*gen_pdev_set_rd)(struct ath10k *ar, u16 rd, u16 rd2g,
u16 rd5g, u16 ctl2g, u16 ctl5g, u16 rd5g, u16 ctl2g, u16 ctl5g,
enum wmi_dfs_region dfs_reg); enum wmi_dfs_region dfs_reg);
@ -279,6 +273,16 @@ ath10k_wmi_pull_mgmt_tx_compl(struct ath10k *ar, struct sk_buff *skb,
return ar->wmi.ops->pull_mgmt_tx_compl(ar, skb, arg); return ar->wmi.ops->pull_mgmt_tx_compl(ar, skb, arg);
} }
static inline int
ath10k_wmi_pull_mgmt_tx_bundle_compl(struct ath10k *ar, struct sk_buff *skb,
struct wmi_tlv_mgmt_tx_bundle_compl_ev_arg *arg)
{
if (!ar->wmi.ops->pull_mgmt_tx_bundle_compl)
return -EOPNOTSUPP;
return ar->wmi.ops->pull_mgmt_tx_bundle_compl(ar, skb, arg);
}
static inline int static inline int
ath10k_wmi_pull_mgmt_rx(struct ath10k *ar, struct sk_buff *skb, ath10k_wmi_pull_mgmt_rx(struct ath10k *ar, struct sk_buff *skb,
struct wmi_mgmt_rx_ev_arg *arg) struct wmi_mgmt_rx_ev_arg *arg)
@ -506,6 +510,22 @@ ath10k_wmi_pdev_set_regdomain(struct ath10k *ar, u16 rd, u16 rd2g, u16 rd5g,
ar->wmi.cmd->pdev_set_regdomain_cmdid); ar->wmi.cmd->pdev_set_regdomain_cmdid);
} }
static inline int
ath10k_wmi_pdev_set_base_macaddr(struct ath10k *ar, const u8 macaddr[ETH_ALEN])
{
struct sk_buff *skb;
if (!ar->wmi.ops->gen_pdev_set_base_macaddr)
return -EOPNOTSUPP;
skb = ar->wmi.ops->gen_pdev_set_base_macaddr(ar, macaddr);
if (IS_ERR(skb))
return PTR_ERR(skb);
return ath10k_wmi_cmd_send(ar, skb,
ar->wmi.cmd->pdev_set_base_macaddr_cmdid);
}
static inline int static inline int
ath10k_wmi_pdev_suspend_target(struct ath10k *ar, u32 suspend_opt) ath10k_wmi_pdev_suspend_target(struct ath10k *ar, u32 suspend_opt)
{ {

View File

@ -1,19 +1,8 @@
// SPDX-License-Identifier: ISC
/* /*
* Copyright (c) 2005-2011 Atheros Communications Inc. * Copyright (c) 2005-2011 Atheros Communications Inc.
* Copyright (c) 2011-2017 Qualcomm Atheros, Inc. * Copyright (c) 2011-2017 Qualcomm Atheros, Inc.
* Copyright (c) 2018, The Linux Foundation. All rights reserved. * Copyright (c) 2018, The Linux Foundation. All rights reserved.
*
* Permission to use, copy, modify, and/or distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/ */
#include "core.h" #include "core.h"
#include "debug.h" #include "debug.h"
@ -620,6 +609,9 @@ static void ath10k_wmi_tlv_op_rx(struct ath10k *ar, struct sk_buff *skb)
case WMI_TLV_MGMT_TX_COMPLETION_EVENTID: case WMI_TLV_MGMT_TX_COMPLETION_EVENTID:
ath10k_wmi_event_mgmt_tx_compl(ar, skb); ath10k_wmi_event_mgmt_tx_compl(ar, skb);
break; break;
case WMI_TLV_MGMT_TX_BUNDLE_COMPLETION_EVENTID:
ath10k_wmi_event_mgmt_tx_bundle_compl(ar, skb);
break;
default: default:
ath10k_dbg(ar, ATH10K_DBG_WMI, "Unknown eventid: %d\n", id); ath10k_dbg(ar, ATH10K_DBG_WMI, "Unknown eventid: %d\n", id);
break; break;
@ -686,6 +678,65 @@ ath10k_wmi_tlv_op_pull_mgmt_tx_compl_ev(struct ath10k *ar, struct sk_buff *skb,
return 0; return 0;
} }
struct wmi_tlv_tx_bundle_compl_parse {
const __le32 *num_reports;
const __le32 *desc_ids;
const __le32 *status;
bool desc_ids_done;
bool status_done;
};
static int
ath10k_wmi_tlv_mgmt_tx_bundle_compl_parse(struct ath10k *ar, u16 tag, u16 len,
const void *ptr, void *data)
{
struct wmi_tlv_tx_bundle_compl_parse *bundle_tx_compl = data;
switch (tag) {
case WMI_TLV_TAG_STRUCT_MGMT_TX_COMPL_BUNDLE_EVENT:
bundle_tx_compl->num_reports = ptr;
break;
case WMI_TLV_TAG_ARRAY_UINT32:
if (!bundle_tx_compl->desc_ids_done) {
bundle_tx_compl->desc_ids_done = true;
bundle_tx_compl->desc_ids = ptr;
} else if (!bundle_tx_compl->status_done) {
bundle_tx_compl->status_done = true;
bundle_tx_compl->status = ptr;
}
break;
default:
break;
}
return 0;
}
static int ath10k_wmi_tlv_op_pull_mgmt_tx_bundle_compl_ev(
struct ath10k *ar, struct sk_buff *skb,
struct wmi_tlv_mgmt_tx_bundle_compl_ev_arg *arg)
{
struct wmi_tlv_tx_bundle_compl_parse bundle_tx_compl = { };
int ret;
ret = ath10k_wmi_tlv_iter(ar, skb->data, skb->len,
ath10k_wmi_tlv_mgmt_tx_bundle_compl_parse,
&bundle_tx_compl);
if (ret) {
ath10k_warn(ar, "failed to parse tlv: %d\n", ret);
return ret;
}
if (!bundle_tx_compl.num_reports || !bundle_tx_compl.desc_ids ||
!bundle_tx_compl.status)
return -EPROTO;
arg->num_reports = *bundle_tx_compl.num_reports;
arg->desc_ids = bundle_tx_compl.desc_ids;
arg->status = bundle_tx_compl.status;
return 0;
}
static int ath10k_wmi_tlv_op_pull_mgmt_rx_ev(struct ath10k *ar, static int ath10k_wmi_tlv_op_pull_mgmt_rx_ev(struct ath10k *ar,
struct sk_buff *skb, struct sk_buff *skb,
struct wmi_mgmt_rx_ev_arg *arg) struct wmi_mgmt_rx_ev_arg *arg)
@ -1611,7 +1662,7 @@ static struct sk_buff *ath10k_wmi_tlv_op_gen_init(struct ath10k *ar)
cfg->rx_skip_defrag_timeout_dup_detection_check = __cpu_to_le32(0); cfg->rx_skip_defrag_timeout_dup_detection_check = __cpu_to_le32(0);
cfg->vow_config = __cpu_to_le32(0); cfg->vow_config = __cpu_to_le32(0);
cfg->gtk_offload_max_vdev = __cpu_to_le32(2); cfg->gtk_offload_max_vdev = __cpu_to_le32(2);
cfg->num_msdu_desc = __cpu_to_le32(TARGET_TLV_NUM_MSDU_DESC); cfg->num_msdu_desc = __cpu_to_le32(ar->htt.max_num_pending_tx);
cfg->max_frag_entries = __cpu_to_le32(2); cfg->max_frag_entries = __cpu_to_le32(2);
cfg->num_tdls_vdevs = __cpu_to_le32(TARGET_TLV_NUM_TDLS_VDEVS); cfg->num_tdls_vdevs = __cpu_to_le32(TARGET_TLV_NUM_TDLS_VDEVS);
cfg->num_tdls_conn_table_entries = __cpu_to_le32(0x20); cfg->num_tdls_conn_table_entries = __cpu_to_le32(0x20);
@ -1626,7 +1677,7 @@ static struct sk_buff *ath10k_wmi_tlv_op_gen_init(struct ath10k *ar)
cfg->num_ocb_vdevs = __cpu_to_le32(0); cfg->num_ocb_vdevs = __cpu_to_le32(0);
cfg->num_ocb_channels = __cpu_to_le32(0); cfg->num_ocb_channels = __cpu_to_le32(0);
cfg->num_ocb_schedules = __cpu_to_le32(0); cfg->num_ocb_schedules = __cpu_to_le32(0);
cfg->host_capab = __cpu_to_le32(0); cfg->host_capab = __cpu_to_le32(WMI_TLV_FLAG_MGMT_BUNDLE_TX_COMPL);
ath10k_wmi_put_host_mem_chunks(ar, chunks); ath10k_wmi_put_host_mem_chunks(ar, chunks);
@ -1998,9 +2049,11 @@ ath10k_wmi_tlv_op_gen_vdev_install_key(struct ath10k *ar,
size_t len; size_t len;
void *ptr; void *ptr;
if (arg->key_cipher == WMI_CIPHER_NONE && arg->key_data != NULL) if (arg->key_cipher == ar->wmi_key_cipher[WMI_CIPHER_NONE] &&
arg->key_data)
return ERR_PTR(-EINVAL); return ERR_PTR(-EINVAL);
if (arg->key_cipher != WMI_CIPHER_NONE && arg->key_data == NULL) if (arg->key_cipher != ar->wmi_key_cipher[WMI_CIPHER_NONE] &&
!arg->key_data)
return ERR_PTR(-EINVAL); return ERR_PTR(-EINVAL);
len = sizeof(*tlv) + sizeof(*cmd) + len = sizeof(*tlv) + sizeof(*cmd) +
@ -3259,6 +3312,8 @@ ath10k_wmi_tlv_op_gen_wow_enable(struct ath10k *ar)
cmd = (void *)tlv->value; cmd = (void *)tlv->value;
cmd->enable = __cpu_to_le32(1); cmd->enable = __cpu_to_le32(1);
if (!ar->bus_param.link_can_suspend)
cmd->pause_iface_config = __cpu_to_le32(WOW_IFACE_PAUSE_DISABLED);
ath10k_dbg(ar, ATH10K_DBG_WMI, "wmi tlv wow enable\n"); ath10k_dbg(ar, ATH10K_DBG_WMI, "wmi tlv wow enable\n");
return skb; return skb;
@ -4093,6 +4148,7 @@ static const struct wmi_ops wmi_tlv_ops = {
.pull_scan = ath10k_wmi_tlv_op_pull_scan_ev, .pull_scan = ath10k_wmi_tlv_op_pull_scan_ev,
.pull_mgmt_rx = ath10k_wmi_tlv_op_pull_mgmt_rx_ev, .pull_mgmt_rx = ath10k_wmi_tlv_op_pull_mgmt_rx_ev,
.pull_mgmt_tx_compl = ath10k_wmi_tlv_op_pull_mgmt_tx_compl_ev, .pull_mgmt_tx_compl = ath10k_wmi_tlv_op_pull_mgmt_tx_compl_ev,
.pull_mgmt_tx_bundle_compl = ath10k_wmi_tlv_op_pull_mgmt_tx_bundle_compl_ev,
.pull_ch_info = ath10k_wmi_tlv_op_pull_ch_info_ev, .pull_ch_info = ath10k_wmi_tlv_op_pull_ch_info_ev,
.pull_vdev_start = ath10k_wmi_tlv_op_pull_vdev_start_ev, .pull_vdev_start = ath10k_wmi_tlv_op_pull_vdev_start_ev,
.pull_peer_kick = ath10k_wmi_tlv_op_pull_peer_kick_ev, .pull_peer_kick = ath10k_wmi_tlv_op_pull_peer_kick_ev,

View File

@ -1,19 +1,8 @@
/* SPDX-License-Identifier: ISC */
/* /*
* Copyright (c) 2005-2011 Atheros Communications Inc. * Copyright (c) 2005-2011 Atheros Communications Inc.
* Copyright (c) 2011-2017 Qualcomm Atheros, Inc. * Copyright (c) 2011-2017 Qualcomm Atheros, Inc.
* Copyright (c) 2018, The Linux Foundation. All rights reserved. * Copyright (c) 2018, The Linux Foundation. All rights reserved.
*
* Permission to use, copy, modify, and/or distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/ */
#ifndef _WMI_TLV_H #ifndef _WMI_TLV_H
#define _WMI_TLV_H #define _WMI_TLV_H
@ -321,6 +310,7 @@ enum wmi_tlv_event_id {
WMI_TLV_OFFLOAD_BCN_TX_STATUS_EVENTID, WMI_TLV_OFFLOAD_BCN_TX_STATUS_EVENTID,
WMI_TLV_OFFLOAD_PROB_RESP_TX_STATUS_EVENTID, WMI_TLV_OFFLOAD_PROB_RESP_TX_STATUS_EVENTID,
WMI_TLV_MGMT_TX_COMPLETION_EVENTID, WMI_TLV_MGMT_TX_COMPLETION_EVENTID,
WMI_TLV_MGMT_TX_BUNDLE_COMPLETION_EVENTID,
WMI_TLV_TX_DELBA_COMPLETE_EVENTID = WMI_TLV_EV(WMI_TLV_GRP_BA_NEG), WMI_TLV_TX_DELBA_COMPLETE_EVENTID = WMI_TLV_EV(WMI_TLV_GRP_BA_NEG),
WMI_TLV_TX_ADDBA_COMPLETE_EVENTID, WMI_TLV_TX_ADDBA_COMPLETE_EVENTID,
WMI_TLV_BA_RSP_SSN_EVENTID, WMI_TLV_BA_RSP_SSN_EVENTID,
@ -1592,6 +1582,8 @@ struct chan_info_params {
u32 mac_clk_mhz; u32 mac_clk_mhz;
}; };
#define WMI_TLV_FLAG_MGMT_BUNDLE_TX_COMPL BIT(9)
struct wmi_tlv_mgmt_tx_compl_ev { struct wmi_tlv_mgmt_tx_compl_ev {
__le32 desc_id; __le32 desc_id;
__le32 status; __le32 status;
@ -1998,8 +1990,15 @@ struct wmi_tlv_set_quiet_cmd {
__le32 enabled; __le32 enabled;
} __packed; } __packed;
enum wmi_tlv_wow_interface_cfg {
WOW_IFACE_PAUSE_ENABLED,
WOW_IFACE_PAUSE_DISABLED
};
struct wmi_tlv_wow_enable_cmd { struct wmi_tlv_wow_enable_cmd {
__le32 enable; __le32 enable;
__le32 pause_iface_config;
__le32 flags;
} __packed; } __packed;
struct wmi_tlv_wow_host_wakeup_ind { struct wmi_tlv_wow_host_wakeup_ind {

View File

@ -1,19 +1,8 @@
// SPDX-License-Identifier: ISC
/* /*
* Copyright (c) 2005-2011 Atheros Communications Inc. * Copyright (c) 2005-2011 Atheros Communications Inc.
* Copyright (c) 2011-2017 Qualcomm Atheros, Inc. * Copyright (c) 2011-2017 Qualcomm Atheros, Inc.
* Copyright (c) 2018, The Linux Foundation. All rights reserved. * Copyright (c) 2018-2019, The Linux Foundation. All rights reserved.
*
* Permission to use, copy, modify, and/or distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/ */
#include <linux/skbuff.h> #include <linux/skbuff.h>
@ -827,6 +816,7 @@ static struct wmi_vdev_param_map wmi_vdev_param_map = {
.rx_decap_type = WMI_VDEV_PARAM_UNSUPPORTED, .rx_decap_type = WMI_VDEV_PARAM_UNSUPPORTED,
.bw_nss_ratemask = WMI_VDEV_PARAM_UNSUPPORTED, .bw_nss_ratemask = WMI_VDEV_PARAM_UNSUPPORTED,
.disable_4addr_src_lrn = WMI_VDEV_PARAM_UNSUPPORTED, .disable_4addr_src_lrn = WMI_VDEV_PARAM_UNSUPPORTED,
.rtt_responder_role = WMI_VDEV_PARAM_UNSUPPORTED,
}; };
/* 10.X WMI VDEV param map */ /* 10.X WMI VDEV param map */
@ -903,6 +893,7 @@ static struct wmi_vdev_param_map wmi_10x_vdev_param_map = {
.rx_decap_type = WMI_VDEV_PARAM_UNSUPPORTED, .rx_decap_type = WMI_VDEV_PARAM_UNSUPPORTED,
.bw_nss_ratemask = WMI_VDEV_PARAM_UNSUPPORTED, .bw_nss_ratemask = WMI_VDEV_PARAM_UNSUPPORTED,
.disable_4addr_src_lrn = WMI_VDEV_PARAM_UNSUPPORTED, .disable_4addr_src_lrn = WMI_VDEV_PARAM_UNSUPPORTED,
.rtt_responder_role = WMI_VDEV_PARAM_UNSUPPORTED,
}; };
static struct wmi_vdev_param_map wmi_10_2_4_vdev_param_map = { static struct wmi_vdev_param_map wmi_10_2_4_vdev_param_map = {
@ -978,6 +969,7 @@ static struct wmi_vdev_param_map wmi_10_2_4_vdev_param_map = {
.rx_decap_type = WMI_VDEV_PARAM_UNSUPPORTED, .rx_decap_type = WMI_VDEV_PARAM_UNSUPPORTED,
.bw_nss_ratemask = WMI_VDEV_PARAM_UNSUPPORTED, .bw_nss_ratemask = WMI_VDEV_PARAM_UNSUPPORTED,
.disable_4addr_src_lrn = WMI_VDEV_PARAM_UNSUPPORTED, .disable_4addr_src_lrn = WMI_VDEV_PARAM_UNSUPPORTED,
.rtt_responder_role = WMI_VDEV_PARAM_UNSUPPORTED,
}; };
static struct wmi_vdev_param_map wmi_10_4_vdev_param_map = { static struct wmi_vdev_param_map wmi_10_4_vdev_param_map = {
@ -1056,6 +1048,7 @@ static struct wmi_vdev_param_map wmi_10_4_vdev_param_map = {
.inc_tsf = WMI_10_4_VDEV_PARAM_TSF_INCREMENT, .inc_tsf = WMI_10_4_VDEV_PARAM_TSF_INCREMENT,
.dec_tsf = WMI_10_4_VDEV_PARAM_TSF_DECREMENT, .dec_tsf = WMI_10_4_VDEV_PARAM_TSF_DECREMENT,
.disable_4addr_src_lrn = WMI_10_4_VDEV_PARAM_DISABLE_4_ADDR_SRC_LRN, .disable_4addr_src_lrn = WMI_10_4_VDEV_PARAM_DISABLE_4_ADDR_SRC_LRN,
.rtt_responder_role = WMI_10_4_VDEV_PARAM_ENABLE_DISABLE_RTT_RESPONDER_ROLE,
}; };
static struct wmi_pdev_param_map wmi_pdev_param_map = { static struct wmi_pdev_param_map wmi_pdev_param_map = {
@ -1606,6 +1599,30 @@ static struct wmi_pdev_param_map wmi_10_4_pdev_param_map = {
.enable_btcoex = WMI_10_4_PDEV_PARAM_ENABLE_BTCOEX, .enable_btcoex = WMI_10_4_PDEV_PARAM_ENABLE_BTCOEX,
}; };
static const u8 wmi_key_cipher_suites[] = {
[WMI_CIPHER_NONE] = WMI_CIPHER_NONE,
[WMI_CIPHER_WEP] = WMI_CIPHER_WEP,
[WMI_CIPHER_TKIP] = WMI_CIPHER_TKIP,
[WMI_CIPHER_AES_OCB] = WMI_CIPHER_AES_OCB,
[WMI_CIPHER_AES_CCM] = WMI_CIPHER_AES_CCM,
[WMI_CIPHER_WAPI] = WMI_CIPHER_WAPI,
[WMI_CIPHER_CKIP] = WMI_CIPHER_CKIP,
[WMI_CIPHER_AES_CMAC] = WMI_CIPHER_AES_CMAC,
[WMI_CIPHER_AES_GCM] = WMI_CIPHER_AES_GCM,
};
static const u8 wmi_tlv_key_cipher_suites[] = {
[WMI_CIPHER_NONE] = WMI_TLV_CIPHER_NONE,
[WMI_CIPHER_WEP] = WMI_TLV_CIPHER_WEP,
[WMI_CIPHER_TKIP] = WMI_TLV_CIPHER_TKIP,
[WMI_CIPHER_AES_OCB] = WMI_TLV_CIPHER_AES_OCB,
[WMI_CIPHER_AES_CCM] = WMI_TLV_CIPHER_AES_CCM,
[WMI_CIPHER_WAPI] = WMI_TLV_CIPHER_WAPI,
[WMI_CIPHER_CKIP] = WMI_TLV_CIPHER_CKIP,
[WMI_CIPHER_AES_CMAC] = WMI_TLV_CIPHER_AES_CMAC,
[WMI_CIPHER_AES_GCM] = WMI_TLV_CIPHER_AES_GCM,
};
static const struct wmi_peer_flags_map wmi_peer_flags_map = { static const struct wmi_peer_flags_map wmi_peer_flags_map = {
.auth = WMI_PEER_AUTH, .auth = WMI_PEER_AUTH,
.qos = WMI_PEER_QOS, .qos = WMI_PEER_QOS,
@ -2346,7 +2363,7 @@ static int wmi_process_mgmt_tx_comp(struct ath10k *ar, u32 desc_id,
msdu = pkt_addr->vaddr; msdu = pkt_addr->vaddr;
dma_unmap_single(ar->dev, pkt_addr->paddr, dma_unmap_single(ar->dev, pkt_addr->paddr,
msdu->len, DMA_FROM_DEVICE); msdu->len, DMA_TO_DEVICE);
info = IEEE80211_SKB_CB(msdu); info = IEEE80211_SKB_CB(msdu);
if (status) if (status)
@ -2383,6 +2400,29 @@ int ath10k_wmi_event_mgmt_tx_compl(struct ath10k *ar, struct sk_buff *skb)
return 0; return 0;
} }
int ath10k_wmi_event_mgmt_tx_bundle_compl(struct ath10k *ar, struct sk_buff *skb)
{
struct wmi_tlv_mgmt_tx_bundle_compl_ev_arg arg;
u32 num_reports;
int i, ret;
ret = ath10k_wmi_pull_mgmt_tx_bundle_compl(ar, skb, &arg);
if (ret) {
ath10k_warn(ar, "failed to parse bundle mgmt compl event: %d\n", ret);
return ret;
}
num_reports = __le32_to_cpu(arg.num_reports);
for (i = 0; i < num_reports; i++)
wmi_process_mgmt_tx_comp(ar, __le32_to_cpu(arg.desc_ids[i]),
__le32_to_cpu(arg.status[i]));
ath10k_dbg(ar, ATH10K_DBG_WMI, "wmi tlv event bundle mgmt tx completion\n");
return 0;
}
int ath10k_wmi_event_mgmt_rx(struct ath10k *ar, struct sk_buff *skb) int ath10k_wmi_event_mgmt_rx(struct ath10k *ar, struct sk_buff *skb)
{ {
struct wmi_mgmt_rx_ev_arg arg = {}; struct wmi_mgmt_rx_ev_arg arg = {};
@ -6239,6 +6279,25 @@ int ath10k_wmi_connect(struct ath10k *ar)
return 0; return 0;
} }
static struct sk_buff *
ath10k_wmi_op_gen_pdev_set_base_macaddr(struct ath10k *ar,
const u8 macaddr[ETH_ALEN])
{
struct wmi_pdev_set_base_macaddr_cmd *cmd;
struct sk_buff *skb;
skb = ath10k_wmi_alloc_skb(ar, sizeof(*cmd));
if (!skb)
return ERR_PTR(-ENOMEM);
cmd = (struct wmi_pdev_set_base_macaddr_cmd *)skb->data;
ether_addr_copy(cmd->mac_addr.addr, macaddr);
ath10k_dbg(ar, ATH10K_DBG_WMI,
"wmi pdev basemac %pM\n", macaddr);
return skb;
}
static struct sk_buff * static struct sk_buff *
ath10k_wmi_op_gen_pdev_set_rd(struct ath10k *ar, u16 rd, u16 rd2g, u16 rd5g, ath10k_wmi_op_gen_pdev_set_rd(struct ath10k *ar, u16 rd, u16 rd2g, u16 rd5g,
u16 ctl2g, u16 ctl5g, u16 ctl2g, u16 ctl5g,
@ -9048,6 +9107,7 @@ static const struct wmi_ops wmi_10_2_ops = {
.gen_peer_create = ath10k_wmi_op_gen_peer_create, .gen_peer_create = ath10k_wmi_op_gen_peer_create,
.gen_peer_delete = ath10k_wmi_op_gen_peer_delete, .gen_peer_delete = ath10k_wmi_op_gen_peer_delete,
.gen_peer_flush = ath10k_wmi_op_gen_peer_flush, .gen_peer_flush = ath10k_wmi_op_gen_peer_flush,
.gen_pdev_set_base_macaddr = ath10k_wmi_op_gen_pdev_set_base_macaddr,
.gen_peer_set_param = ath10k_wmi_op_gen_peer_set_param, .gen_peer_set_param = ath10k_wmi_op_gen_peer_set_param,
.gen_set_psmode = ath10k_wmi_op_gen_set_psmode, .gen_set_psmode = ath10k_wmi_op_gen_set_psmode,
.gen_set_sta_ps = ath10k_wmi_op_gen_set_sta_ps, .gen_set_sta_ps = ath10k_wmi_op_gen_set_sta_ps,
@ -9166,6 +9226,7 @@ static const struct wmi_ops wmi_10_4_ops = {
.gen_pdev_suspend = ath10k_wmi_op_gen_pdev_suspend, .gen_pdev_suspend = ath10k_wmi_op_gen_pdev_suspend,
.gen_pdev_resume = ath10k_wmi_op_gen_pdev_resume, .gen_pdev_resume = ath10k_wmi_op_gen_pdev_resume,
.gen_pdev_set_base_macaddr = ath10k_wmi_op_gen_pdev_set_base_macaddr,
.gen_pdev_set_rd = ath10k_wmi_10x_op_gen_pdev_set_rd, .gen_pdev_set_rd = ath10k_wmi_10x_op_gen_pdev_set_rd,
.gen_pdev_set_param = ath10k_wmi_op_gen_pdev_set_param, .gen_pdev_set_param = ath10k_wmi_op_gen_pdev_set_param,
.gen_init = ath10k_wmi_10_4_op_gen_init, .gen_init = ath10k_wmi_10_4_op_gen_init,
@ -9229,6 +9290,7 @@ int ath10k_wmi_attach(struct ath10k *ar)
ar->wmi.vdev_param = &wmi_10_4_vdev_param_map; ar->wmi.vdev_param = &wmi_10_4_vdev_param_map;
ar->wmi.pdev_param = &wmi_10_4_pdev_param_map; ar->wmi.pdev_param = &wmi_10_4_pdev_param_map;
ar->wmi.peer_flags = &wmi_10_2_peer_flags_map; ar->wmi.peer_flags = &wmi_10_2_peer_flags_map;
ar->wmi_key_cipher = wmi_key_cipher_suites;
break; break;
case ATH10K_FW_WMI_OP_VERSION_10_2_4: case ATH10K_FW_WMI_OP_VERSION_10_2_4:
ar->wmi.cmd = &wmi_10_2_4_cmd_map; ar->wmi.cmd = &wmi_10_2_4_cmd_map;
@ -9236,6 +9298,7 @@ int ath10k_wmi_attach(struct ath10k *ar)
ar->wmi.vdev_param = &wmi_10_2_4_vdev_param_map; ar->wmi.vdev_param = &wmi_10_2_4_vdev_param_map;
ar->wmi.pdev_param = &wmi_10_2_4_pdev_param_map; ar->wmi.pdev_param = &wmi_10_2_4_pdev_param_map;
ar->wmi.peer_flags = &wmi_10_2_peer_flags_map; ar->wmi.peer_flags = &wmi_10_2_peer_flags_map;
ar->wmi_key_cipher = wmi_key_cipher_suites;
break; break;
case ATH10K_FW_WMI_OP_VERSION_10_2: case ATH10K_FW_WMI_OP_VERSION_10_2:
ar->wmi.cmd = &wmi_10_2_cmd_map; ar->wmi.cmd = &wmi_10_2_cmd_map;
@ -9243,6 +9306,7 @@ int ath10k_wmi_attach(struct ath10k *ar)
ar->wmi.vdev_param = &wmi_10x_vdev_param_map; ar->wmi.vdev_param = &wmi_10x_vdev_param_map;
ar->wmi.pdev_param = &wmi_10x_pdev_param_map; ar->wmi.pdev_param = &wmi_10x_pdev_param_map;
ar->wmi.peer_flags = &wmi_10_2_peer_flags_map; ar->wmi.peer_flags = &wmi_10_2_peer_flags_map;
ar->wmi_key_cipher = wmi_key_cipher_suites;
break; break;
case ATH10K_FW_WMI_OP_VERSION_10_1: case ATH10K_FW_WMI_OP_VERSION_10_1:
ar->wmi.cmd = &wmi_10x_cmd_map; ar->wmi.cmd = &wmi_10x_cmd_map;
@ -9250,6 +9314,7 @@ int ath10k_wmi_attach(struct ath10k *ar)
ar->wmi.vdev_param = &wmi_10x_vdev_param_map; ar->wmi.vdev_param = &wmi_10x_vdev_param_map;
ar->wmi.pdev_param = &wmi_10x_pdev_param_map; ar->wmi.pdev_param = &wmi_10x_pdev_param_map;
ar->wmi.peer_flags = &wmi_10x_peer_flags_map; ar->wmi.peer_flags = &wmi_10x_peer_flags_map;
ar->wmi_key_cipher = wmi_key_cipher_suites;
break; break;
case ATH10K_FW_WMI_OP_VERSION_MAIN: case ATH10K_FW_WMI_OP_VERSION_MAIN:
ar->wmi.cmd = &wmi_cmd_map; ar->wmi.cmd = &wmi_cmd_map;
@ -9257,9 +9322,11 @@ int ath10k_wmi_attach(struct ath10k *ar)
ar->wmi.vdev_param = &wmi_vdev_param_map; ar->wmi.vdev_param = &wmi_vdev_param_map;
ar->wmi.pdev_param = &wmi_pdev_param_map; ar->wmi.pdev_param = &wmi_pdev_param_map;
ar->wmi.peer_flags = &wmi_peer_flags_map; ar->wmi.peer_flags = &wmi_peer_flags_map;
ar->wmi_key_cipher = wmi_key_cipher_suites;
break; break;
case ATH10K_FW_WMI_OP_VERSION_TLV: case ATH10K_FW_WMI_OP_VERSION_TLV:
ath10k_wmi_tlv_attach(ar); ath10k_wmi_tlv_attach(ar);
ar->wmi_key_cipher = wmi_tlv_key_cipher_suites;
break; break;
case ATH10K_FW_WMI_OP_VERSION_UNSET: case ATH10K_FW_WMI_OP_VERSION_UNSET:
case ATH10K_FW_WMI_OP_VERSION_MAX: case ATH10K_FW_WMI_OP_VERSION_MAX:

View File

@ -1,26 +1,15 @@
/* SPDX-License-Identifier: ISC */
/* /*
* Copyright (c) 2005-2011 Atheros Communications Inc. * Copyright (c) 2005-2011 Atheros Communications Inc.
* Copyright (c) 2011-2017 Qualcomm Atheros, Inc. * Copyright (c) 2011-2017 Qualcomm Atheros, Inc.
* Copyright (c) 2018, The Linux Foundation. All rights reserved. * Copyright (c) 2018, The Linux Foundation. All rights reserved.
*
* Permission to use, copy, modify, and/or distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/ */
#ifndef _WMI_H_ #ifndef _WMI_H_
#define _WMI_H_ #define _WMI_H_
#include <linux/types.h> #include <linux/types.h>
#include <net/mac80211.h> #include <linux/ieee80211.h>
/* /*
* This file specifies the WMI interface for the Unified Software * This file specifies the WMI interface for the Unified Software
@ -208,6 +197,11 @@ enum wmi_service {
WMI_SERVICE_VDEV_DISABLE_4_ADDR_SRC_LRN_SUPPORT, WMI_SERVICE_VDEV_DISABLE_4_ADDR_SRC_LRN_SUPPORT,
WMI_SERVICE_BB_TIMING_CONFIG_SUPPORT, WMI_SERVICE_BB_TIMING_CONFIG_SUPPORT,
WMI_SERVICE_THERM_THROT, WMI_SERVICE_THERM_THROT,
WMI_SERVICE_RTT_RESPONDER_ROLE,
WMI_SERVICE_PER_PACKET_SW_ENCRYPT,
WMI_SERVICE_REPORT_AIRTIME,
/* Remember to add the new value to wmi_service_name()! */
/* keep last */ /* keep last */
WMI_SERVICE_MAX, WMI_SERVICE_MAX,
@ -368,9 +362,14 @@ enum wmi_10_4_service {
WMI_10_4_SERVICE_HTT_ASSERT_TRIGGER_SUPPORT, WMI_10_4_SERVICE_HTT_ASSERT_TRIGGER_SUPPORT,
WMI_10_4_SERVICE_VDEV_FILTER_NEIGHBOR_RX_PACKETS, WMI_10_4_SERVICE_VDEV_FILTER_NEIGHBOR_RX_PACKETS,
WMI_10_4_SERVICE_VDEV_DISABLE_4_ADDR_SRC_LRN_SUPPORT, WMI_10_4_SERVICE_VDEV_DISABLE_4_ADDR_SRC_LRN_SUPPORT,
WMI_10_4_SERVICE_PEER_CHWIDTH_CHANGE,
WMI_10_4_SERVICE_RX_FILTER_OUT_COUNT,
WMI_10_4_SERVICE_RTT_RESPONDER_ROLE,
WMI_10_4_SERVICE_EXT_PEER_TID_CONFIGS_SUPPORT,
WMI_10_4_SERVICE_REPORT_AIRTIME,
}; };
static inline char *wmi_service_name(int service_id) static inline char *wmi_service_name(enum wmi_service service_id)
{ {
#define SVCSTR(x) case x: return #x #define SVCSTR(x) case x: return #x
@ -467,6 +466,7 @@ static inline char *wmi_service_name(int service_id)
SVCSTR(WMI_SERVICE_TX_MODE_PUSH_PULL); SVCSTR(WMI_SERVICE_TX_MODE_PUSH_PULL);
SVCSTR(WMI_SERVICE_TX_MODE_DYNAMIC); SVCSTR(WMI_SERVICE_TX_MODE_DYNAMIC);
SVCSTR(WMI_SERVICE_VDEV_RX_FILTER); SVCSTR(WMI_SERVICE_VDEV_RX_FILTER);
SVCSTR(WMI_SERVICE_BTCOEX);
SVCSTR(WMI_SERVICE_CHECK_CAL_VERSION); SVCSTR(WMI_SERVICE_CHECK_CAL_VERSION);
SVCSTR(WMI_SERVICE_DBGLOG_WARN2); SVCSTR(WMI_SERVICE_DBGLOG_WARN2);
SVCSTR(WMI_SERVICE_BTCOEX_DUTY_CYCLE); SVCSTR(WMI_SERVICE_BTCOEX_DUTY_CYCLE);
@ -476,18 +476,29 @@ static inline char *wmi_service_name(int service_id)
SVCSTR(WMI_SERVICE_SMART_LOGGING_SUPPORT); SVCSTR(WMI_SERVICE_SMART_LOGGING_SUPPORT);
SVCSTR(WMI_SERVICE_TDLS_CONN_TRACKER_IN_HOST_MODE); SVCSTR(WMI_SERVICE_TDLS_CONN_TRACKER_IN_HOST_MODE);
SVCSTR(WMI_SERVICE_TDLS_EXPLICIT_MODE_ONLY); SVCSTR(WMI_SERVICE_TDLS_EXPLICIT_MODE_ONLY);
SVCSTR(WMI_SERVICE_MGMT_TX_WMI);
SVCSTR(WMI_SERVICE_TDLS_WIDER_BANDWIDTH); SVCSTR(WMI_SERVICE_TDLS_WIDER_BANDWIDTH);
SVCSTR(WMI_SERVICE_HTT_MGMT_TX_COMP_VALID_FLAGS); SVCSTR(WMI_SERVICE_HTT_MGMT_TX_COMP_VALID_FLAGS);
SVCSTR(WMI_SERVICE_HOST_DFS_CHECK_SUPPORT); SVCSTR(WMI_SERVICE_HOST_DFS_CHECK_SUPPORT);
SVCSTR(WMI_SERVICE_TPC_STATS_FINAL); SVCSTR(WMI_SERVICE_TPC_STATS_FINAL);
SVCSTR(WMI_SERVICE_RESET_CHIP); SVCSTR(WMI_SERVICE_RESET_CHIP);
SVCSTR(WMI_SERVICE_SPOOF_MAC_SUPPORT);
SVCSTR(WMI_SERVICE_TX_DATA_ACK_RSSI); SVCSTR(WMI_SERVICE_TX_DATA_ACK_RSSI);
SVCSTR(WMI_SERVICE_VDEV_DIFFERENT_BEACON_INTERVAL_SUPPORT); SVCSTR(WMI_SERVICE_VDEV_DIFFERENT_BEACON_INTERVAL_SUPPORT);
default: SVCSTR(WMI_SERVICE_VDEV_DISABLE_4_ADDR_SRC_LRN_SUPPORT);
SVCSTR(WMI_SERVICE_BB_TIMING_CONFIG_SUPPORT);
SVCSTR(WMI_SERVICE_THERM_THROT);
SVCSTR(WMI_SERVICE_RTT_RESPONDER_ROLE);
SVCSTR(WMI_SERVICE_PER_PACKET_SW_ENCRYPT);
SVCSTR(WMI_SERVICE_REPORT_AIRTIME);
case WMI_SERVICE_MAX:
return NULL; return NULL;
} }
#undef SVCSTR #undef SVCSTR
return NULL;
} }
#define WMI_SERVICE_IS_ENABLED(wmi_svc_bmap, svc_id, len) \ #define WMI_SERVICE_IS_ENABLED(wmi_svc_bmap, svc_id, len) \
@ -579,6 +590,8 @@ static inline void wmi_10x_svc_map(const __le32 *in, unsigned long *out,
WMI_SERVICE_HTT_MGMT_TX_COMP_VALID_FLAGS, len); WMI_SERVICE_HTT_MGMT_TX_COMP_VALID_FLAGS, len);
SVCMAP(WMI_10X_SERVICE_BB_TIMING_CONFIG_SUPPORT, SVCMAP(WMI_10X_SERVICE_BB_TIMING_CONFIG_SUPPORT,
WMI_SERVICE_BB_TIMING_CONFIG_SUPPORT, len); WMI_SERVICE_BB_TIMING_CONFIG_SUPPORT, len);
SVCMAP(WMI_10X_SERVICE_PER_PACKET_SW_ENCRYPT,
WMI_SERVICE_PER_PACKET_SW_ENCRYPT, len);
} }
static inline void wmi_main_svc_map(const __le32 *in, unsigned long *out, static inline void wmi_main_svc_map(const __le32 *in, unsigned long *out,
@ -799,6 +812,12 @@ static inline void wmi_10_4_svc_map(const __le32 *in, unsigned long *out,
WMI_SERVICE_VDEV_DIFFERENT_BEACON_INTERVAL_SUPPORT, len); WMI_SERVICE_VDEV_DIFFERENT_BEACON_INTERVAL_SUPPORT, len);
SVCMAP(WMI_10_4_SERVICE_VDEV_DISABLE_4_ADDR_SRC_LRN_SUPPORT, SVCMAP(WMI_10_4_SERVICE_VDEV_DISABLE_4_ADDR_SRC_LRN_SUPPORT,
WMI_SERVICE_VDEV_DISABLE_4_ADDR_SRC_LRN_SUPPORT, len); WMI_SERVICE_VDEV_DISABLE_4_ADDR_SRC_LRN_SUPPORT, len);
SVCMAP(WMI_10_4_SERVICE_RTT_RESPONDER_ROLE,
WMI_SERVICE_RTT_RESPONDER_ROLE, len);
SVCMAP(WMI_10_4_SERVICE_PER_PACKET_SW_ENCRYPT,
WMI_SERVICE_PER_PACKET_SW_ENCRYPT, len);
SVCMAP(WMI_10_4_SERVICE_REPORT_AIRTIME,
WMI_SERVICE_REPORT_AIRTIME, len);
} }
#undef SVCMAP #undef SVCMAP
@ -2075,6 +2094,8 @@ enum wmi_channel_change_cause {
#define WMI_HT_CAP_MPDU_DENSITY 0x0700 /* MPDU Density */ #define WMI_HT_CAP_MPDU_DENSITY 0x0700 /* MPDU Density */
#define WMI_HT_CAP_MPDU_DENSITY_MASK_SHIFT 8 #define WMI_HT_CAP_MPDU_DENSITY_MASK_SHIFT 8
#define WMI_HT_CAP_HT40_SGI 0x0800 #define WMI_HT_CAP_HT40_SGI 0x0800
#define WMI_HT_CAP_RX_LDPC 0x1000 /* LDPC RX support */
#define WMI_HT_CAP_TX_LDPC 0x2000 /* LDPC TX support */
#define WMI_HT_CAP_DEFAULT_ALL (WMI_HT_CAP_ENABLED | \ #define WMI_HT_CAP_DEFAULT_ALL (WMI_HT_CAP_ENABLED | \
WMI_HT_CAP_HT20_SGI | \ WMI_HT_CAP_HT20_SGI | \
@ -2972,6 +2993,8 @@ enum wmi_10_4_feature_mask {
WMI_10_4_TDLS_CONN_TRACKER_IN_HOST_MODE = BIT(11), WMI_10_4_TDLS_CONN_TRACKER_IN_HOST_MODE = BIT(11),
WMI_10_4_TDLS_EXPLICIT_MODE_ONLY = BIT(12), WMI_10_4_TDLS_EXPLICIT_MODE_ONLY = BIT(12),
WMI_10_4_TX_DATA_ACK_RSSI = BIT(16), WMI_10_4_TX_DATA_ACK_RSSI = BIT(16),
WMI_10_4_EXT_PEER_TID_CONFIGS_SUPPORT = BIT(17),
WMI_10_4_REPORT_AIRTIME = BIT(18),
}; };
@ -4083,6 +4106,10 @@ struct wmi_pdev_set_param_cmd {
__le32 param_value; __le32 param_value;
} __packed; } __packed;
struct wmi_pdev_set_base_macaddr_cmd {
struct wmi_mac_addr mac_addr;
} __packed;
/* valid period is 1 ~ 60000ms, unit in millisecond */ /* valid period is 1 ~ 60000ms, unit in millisecond */
#define WMI_PDEV_PARAM_CAL_PERIOD_MAX 60000 #define WMI_PDEV_PARAM_CAL_PERIOD_MAX 60000
@ -4929,15 +4956,30 @@ struct wmi_key_seq_counter {
__le32 key_seq_counter_h; __le32 key_seq_counter_h;
} __packed; } __packed;
#define WMI_CIPHER_NONE 0x0 /* clear key */ enum wmi_cipher_suites {
#define WMI_CIPHER_WEP 0x1 WMI_CIPHER_NONE,
#define WMI_CIPHER_TKIP 0x2 WMI_CIPHER_WEP,
#define WMI_CIPHER_AES_OCB 0x3 WMI_CIPHER_TKIP,
#define WMI_CIPHER_AES_CCM 0x4 WMI_CIPHER_AES_OCB,
#define WMI_CIPHER_WAPI 0x5 WMI_CIPHER_AES_CCM,
#define WMI_CIPHER_CKIP 0x6 WMI_CIPHER_WAPI,
#define WMI_CIPHER_AES_CMAC 0x7 WMI_CIPHER_CKIP,
#define WMI_CIPHER_AES_GCM 0x8 WMI_CIPHER_AES_CMAC,
WMI_CIPHER_AES_GCM,
};
enum wmi_tlv_cipher_suites {
WMI_TLV_CIPHER_NONE,
WMI_TLV_CIPHER_WEP,
WMI_TLV_CIPHER_TKIP,
WMI_TLV_CIPHER_AES_OCB,
WMI_TLV_CIPHER_AES_CCM,
WMI_TLV_CIPHER_WAPI,
WMI_TLV_CIPHER_CKIP,
WMI_TLV_CIPHER_AES_CMAC,
WMI_TLV_CIPHER_ANY,
WMI_TLV_CIPHER_AES_GCM,
};
struct wmi_vdev_install_key_cmd { struct wmi_vdev_install_key_cmd {
__le32 vdev_id; __le32 vdev_id;
@ -5083,6 +5125,7 @@ struct wmi_vdev_param_map {
u32 inc_tsf; u32 inc_tsf;
u32 dec_tsf; u32 dec_tsf;
u32 disable_4addr_src_lrn; u32 disable_4addr_src_lrn;
u32 rtt_responder_role;
}; };
#define WMI_VDEV_PARAM_UNSUPPORTED 0 #define WMI_VDEV_PARAM_UNSUPPORTED 0
@ -6688,6 +6731,12 @@ struct wmi_tlv_mgmt_tx_compl_ev_arg {
__le32 pdev_id; __le32 pdev_id;
}; };
struct wmi_tlv_mgmt_tx_bundle_compl_ev_arg {
__le32 num_reports;
const __le32 *desc_ids;
const __le32 *status;
};
struct wmi_mgmt_rx_ev_arg { struct wmi_mgmt_rx_ev_arg {
__le32 channel; __le32 channel;
__le32 snr; __le32 snr;
@ -7244,6 +7293,7 @@ int ath10k_wmi_start_scan_verify(const struct wmi_start_scan_arg *arg);
int ath10k_wmi_event_scan(struct ath10k *ar, struct sk_buff *skb); int ath10k_wmi_event_scan(struct ath10k *ar, struct sk_buff *skb);
int ath10k_wmi_event_mgmt_rx(struct ath10k *ar, struct sk_buff *skb); int ath10k_wmi_event_mgmt_rx(struct ath10k *ar, struct sk_buff *skb);
int ath10k_wmi_event_mgmt_tx_compl(struct ath10k *ar, struct sk_buff *skb); int ath10k_wmi_event_mgmt_tx_compl(struct ath10k *ar, struct sk_buff *skb);
int ath10k_wmi_event_mgmt_tx_bundle_compl(struct ath10k *ar, struct sk_buff *skb);
void ath10k_wmi_event_chan_info(struct ath10k *ar, struct sk_buff *skb); void ath10k_wmi_event_chan_info(struct ath10k *ar, struct sk_buff *skb);
void ath10k_wmi_event_echo(struct ath10k *ar, struct sk_buff *skb); void ath10k_wmi_event_echo(struct ath10k *ar, struct sk_buff *skb);
int ath10k_wmi_event_debug_mesg(struct ath10k *ar, struct sk_buff *skb); int ath10k_wmi_event_debug_mesg(struct ath10k *ar, struct sk_buff *skb);

View File

@ -1,18 +1,7 @@
// SPDX-License-Identifier: ISC
/* /*
* Copyright (c) 2015-2017 Qualcomm Atheros, Inc. * Copyright (c) 2015-2017 Qualcomm Atheros, Inc.
* Copyright (c) 2018, The Linux Foundation. All rights reserved. * Copyright (c) 2018, The Linux Foundation. All rights reserved.
*
* Permission to use, copy, modify, and/or distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/ */
#include "mac.h" #include "mac.h"
@ -77,7 +66,7 @@ static int ath10k_wow_cleanup(struct ath10k *ar)
return 0; return 0;
} }
/** /*
* Convert a 802.3 format to a 802.11 format. * Convert a 802.3 format to a 802.11 format.
* +------------+-----------+--------+----------------+ * +------------+-----------+--------+----------------+
* 802.3: |dest mac(6B)|src mac(6B)|type(2B)| body... | * 802.3: |dest mac(6B)|src mac(6B)|type(2B)| body... |
@ -88,8 +77,7 @@ static int ath10k_wow_cleanup(struct ath10k *ar)
* 802.11: |4B|dest mac(6B)| 6B |src mac(6B)| 8B |type(2B)| body... | * 802.11: |4B|dest mac(6B)| 6B |src mac(6B)| 8B |type(2B)| body... |
* +--+------------+----+-----------+---------------+-----------+ * +--+------------+----+-----------+---------------+-----------+
*/ */
static void ath10k_wow_convert_8023_to_80211 static void ath10k_wow_convert_8023_to_80211(struct cfg80211_pkt_pattern *new,
(struct cfg80211_pkt_pattern *new,
const struct cfg80211_pkt_pattern *old) const struct cfg80211_pkt_pattern *old)
{ {
u8 hdr_8023_pattern[ETH_HLEN] = {}; u8 hdr_8023_pattern[ETH_HLEN] = {};

View File

@ -1,17 +1,6 @@
/* SPDX-License-Identifier: ISC */
/* /*
* Copyright (c) 2015,2017 Qualcomm Atheros, Inc. * Copyright (c) 2015,2017 Qualcomm Atheros, Inc.
*
* Permission to use, copy, modify, and/or distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/ */
#ifndef _WOW_H_ #ifndef _WOW_H_
#define _WOW_H_ #define _WOW_H_

View File

@ -776,10 +776,8 @@ int ath6kl_wmi_set_roam_lrssi_cmd(struct wmi *wmi, u8 lrssi)
cmd->info.params.roam_rssi_floor = DEF_LRSSI_ROAM_FLOOR; cmd->info.params.roam_rssi_floor = DEF_LRSSI_ROAM_FLOOR;
cmd->roam_ctrl = WMI_SET_LRSSI_SCAN_PARAMS; cmd->roam_ctrl = WMI_SET_LRSSI_SCAN_PARAMS;
ath6kl_wmi_cmd_send(wmi, 0, skb, WMI_SET_ROAM_CTRL_CMDID, return ath6kl_wmi_cmd_send(wmi, 0, skb, WMI_SET_ROAM_CTRL_CMDID,
NO_SYNC_WMIFLAG); NO_SYNC_WMIFLAG);
return 0;
} }
int ath6kl_wmi_force_roam_cmd(struct wmi *wmi, const u8 *bssid) int ath6kl_wmi_force_roam_cmd(struct wmi *wmi, const u8 *bssid)

View File

@ -3457,9 +3457,9 @@ static u32 ar9003_dump_cal_data(struct ath_hw *ah, char *buf, u32 len, u32 size,
if (!((pBase->txrxMask >> i) & 1)) if (!((pBase->txrxMask >> i) & 1))
continue; continue;
len += snprintf(buf + len, size - len, "Chain %d\n", i); len += scnprintf(buf + len, size - len, "Chain %d\n", i);
len += snprintf(buf + len, size - len, len += scnprintf(buf + len, size - len,
"Freq\t ref\tvolt\ttemp\tnf_cal\tnf_pow\trx_temp\n"); "Freq\t ref\tvolt\ttemp\tnf_cal\tnf_pow\trx_temp\n");
for (j = 0; j < cal_pier_nr; j++) { for (j = 0; j < cal_pier_nr; j++) {
@ -3471,10 +3471,10 @@ static u32 ar9003_dump_cal_data(struct ath_hw *ah, char *buf, u32 len, u32 size,
freq = 4800 + eep->calFreqPier5G[j] * 5; freq = 4800 + eep->calFreqPier5G[j] * 5;
} }
len += snprintf(buf + len, size - len, len += scnprintf(buf + len, size - len,
"%d\t", freq); "%d\t", freq);
len += snprintf(buf + len, size - len, len += scnprintf(buf + len, size - len,
"%d\t%d\t%d\t%d\t%d\t%d\n", "%d\t%d\t%d\t%d\t%d\t%d\n",
cal_pier->refPower, cal_pier->refPower,
cal_pier->voltMeas, cal_pier->voltMeas,
@ -3505,12 +3505,12 @@ static u32 ath9k_hw_ar9003_dump_eeprom(struct ath_hw *ah, bool dump_base_hdr,
len += scnprintf(buf + len, size - len, "Calibration data\n"); len += scnprintf(buf + len, size - len, "Calibration data\n");
len = ar9003_dump_cal_data(ah, buf, len, size, true); len = ar9003_dump_cal_data(ah, buf, len, size, true);
len += snprintf(buf + len, size - len, len += scnprintf(buf + len, size - len,
"%20s :\n", "5GHz modal Header"); "%20s :\n", "5GHz modal Header");
len = ar9003_dump_modal_eeprom(buf, len, size, len = ar9003_dump_modal_eeprom(buf, len, size,
&eep->modalHeader5G); &eep->modalHeader5G);
len += snprintf(buf + len, size - len, "Calibration data\n"); len += scnprintf(buf + len, size - len, "Calibration data\n");
len = ar9003_dump_cal_data(ah, buf, len, size, false); len = ar9003_dump_cal_data(ah, buf, len, size, false);
goto out; goto out;

View File

@ -112,8 +112,6 @@ int ath_descdma_setup(struct ath_softc *sc, struct ath_descdma *dd,
#define ATH_TXFIFO_DEPTH 8 #define ATH_TXFIFO_DEPTH 8
#define ATH_TX_ERROR 0x01 #define ATH_TX_ERROR 0x01
#define ATH_AIRTIME_QUANTUM 300 /* usec */
/* Stop tx traffic 1ms before the GO goes away */ /* Stop tx traffic 1ms before the GO goes away */
#define ATH_P2P_PS_STOP_TIME 1000 #define ATH_P2P_PS_STOP_TIME 1000
@ -246,10 +244,8 @@ struct ath_atx_tid {
s8 bar_index; s8 bar_index;
bool active; bool active;
bool clear_ps_filter; bool clear_ps_filter;
bool has_queued;
}; };
void __ath_tx_queue_tid(struct ath_softc *sc, struct ath_atx_tid *tid);
void ath_tx_queue_tid(struct ath_softc *sc, struct ath_atx_tid *tid); void ath_tx_queue_tid(struct ath_softc *sc, struct ath_atx_tid *tid);
struct ath_node { struct ath_node {
@ -263,12 +259,9 @@ struct ath_node {
bool sleeping; bool sleeping;
bool no_ps_filter; bool no_ps_filter;
s64 airtime_deficit[IEEE80211_NUM_ACS];
u32 airtime_rx_start;
#ifdef CONFIG_ATH9K_STATION_STATISTICS #ifdef CONFIG_ATH9K_STATION_STATISTICS
struct ath_rx_rate_stats rx_rate_stats; struct ath_rx_rate_stats rx_rate_stats;
struct ath_airtime_stats airtime_stats;
#endif #endif
u8 key_idx[4]; u8 key_idx[4];
@ -986,11 +979,6 @@ void ath_ant_comb_scan(struct ath_softc *sc, struct ath_rx_status *rs);
#define ATH9K_NUM_CHANCTX 2 /* supports 2 operating channels */ #define ATH9K_NUM_CHANCTX 2 /* supports 2 operating channels */
#define AIRTIME_USE_TX BIT(0)
#define AIRTIME_USE_RX BIT(1)
#define AIRTIME_USE_NEW_QUEUES BIT(2)
#define AIRTIME_ACTIVE(flags) (!!(flags & (AIRTIME_USE_TX|AIRTIME_USE_RX)))
struct ath_softc { struct ath_softc {
struct ieee80211_hw *hw; struct ieee80211_hw *hw;
struct device *dev; struct device *dev;
@ -1034,8 +1022,6 @@ struct ath_softc {
short nbcnvifs; short nbcnvifs;
unsigned long ps_usecount; unsigned long ps_usecount;
u16 airtime_flags; /* AIRTIME_* */
struct ath_rx rx; struct ath_rx rx;
struct ath_tx tx; struct ath_tx tx;
struct ath_beacon beacon; struct ath_beacon beacon;

View File

@ -1039,6 +1039,9 @@ static struct dentry *create_buf_file_handler(const char *filename,
buf_file = debugfs_create_file(filename, mode, parent, buf, buf_file = debugfs_create_file(filename, mode, parent, buf,
&relay_file_operations); &relay_file_operations);
if (IS_ERR(buf_file))
return NULL;
*is_global = 1; *is_global = 1;
return buf_file; return buf_file;
} }

View File

@ -1443,9 +1443,6 @@ int ath9k_init_debug(struct ath_hw *ah)
#endif #endif
debugfs_create_file("tpc", 0600, sc->debug.debugfs_phy, sc, &fops_tpc); debugfs_create_file("tpc", 0600, sc->debug.debugfs_phy, sc, &fops_tpc);
debugfs_create_u16("airtime_flags", 0600,
sc->debug.debugfs_phy, &sc->airtime_flags);
debugfs_create_file("nf_override", 0600, debugfs_create_file("nf_override", 0600,
sc->debug.debugfs_phy, sc, &fops_nf_override); sc->debug.debugfs_phy, sc, &fops_nf_override);

View File

@ -319,20 +319,12 @@ ath9k_debug_sync_cause(struct ath_softc *sc, u32 sync_cause)
void ath_debug_rate_stats(struct ath_softc *sc, void ath_debug_rate_stats(struct ath_softc *sc,
struct ath_rx_status *rs, struct ath_rx_status *rs,
struct sk_buff *skb); struct sk_buff *skb);
void ath_debug_airtime(struct ath_softc *sc,
struct ath_node *an,
u32 rx, u32 tx);
#else #else
static inline void ath_debug_rate_stats(struct ath_softc *sc, static inline void ath_debug_rate_stats(struct ath_softc *sc,
struct ath_rx_status *rs, struct ath_rx_status *rs,
struct sk_buff *skb) struct sk_buff *skb)
{ {
} }
static inline void ath_debug_airtime(struct ath_softc *sc,
struct ath_node *an,
u32 rx, u32 tx)
{
}
#endif /* CONFIG_ATH9K_STATION_STATISTICS */ #endif /* CONFIG_ATH9K_STATION_STATISTICS */
#endif /* DEBUG_H */ #endif /* DEBUG_H */

View File

@ -242,75 +242,6 @@ static const struct file_operations fops_node_recv = {
.llseek = default_llseek, .llseek = default_llseek,
}; };
void ath_debug_airtime(struct ath_softc *sc,
struct ath_node *an,
u32 rx,
u32 tx)
{
struct ath_airtime_stats *astats = &an->airtime_stats;
astats->rx_airtime += rx;
astats->tx_airtime += tx;
}
static ssize_t read_airtime(struct file *file, char __user *user_buf,
size_t count, loff_t *ppos)
{
struct ath_node *an = file->private_data;
struct ath_airtime_stats *astats;
static const char *qname[4] = {
"VO", "VI", "BE", "BK"
};
u32 len = 0, size = 256;
char *buf;
size_t retval;
int i;
buf = kzalloc(size, GFP_KERNEL);
if (buf == NULL)
return -ENOMEM;
astats = &an->airtime_stats;
len += scnprintf(buf + len, size - len, "RX: %u us\n", astats->rx_airtime);
len += scnprintf(buf + len, size - len, "TX: %u us\n", astats->tx_airtime);
len += scnprintf(buf + len, size - len, "Deficit: ");
for (i = 0; i < 4; i++)
len += scnprintf(buf+len, size - len, "%s: %lld us ", qname[i], an->airtime_deficit[i]);
if (len < size)
buf[len++] = '\n';
retval = simple_read_from_buffer(user_buf, count, ppos, buf, len);
kfree(buf);
return retval;
}
static ssize_t
write_airtime_reset_stub(struct file *file, const char __user *ubuf,
size_t count, loff_t *ppos)
{
struct ath_node *an = file->private_data;
struct ath_airtime_stats *astats;
int i;
astats = &an->airtime_stats;
astats->rx_airtime = 0;
astats->tx_airtime = 0;
for (i = 0; i < 4; i++)
an->airtime_deficit[i] = ATH_AIRTIME_QUANTUM;
return count;
}
static const struct file_operations fops_airtime = {
.read = read_airtime,
.write = write_airtime_reset_stub,
.open = simple_open,
.owner = THIS_MODULE,
.llseek = default_llseek,
};
void ath9k_sta_add_debugfs(struct ieee80211_hw *hw, void ath9k_sta_add_debugfs(struct ieee80211_hw *hw,
struct ieee80211_vif *vif, struct ieee80211_vif *vif,
struct ieee80211_sta *sta, struct ieee80211_sta *sta,
@ -320,5 +251,4 @@ void ath9k_sta_add_debugfs(struct ieee80211_hw *hw,
debugfs_create_file("node_aggr", 0444, dir, an, &fops_node_aggr); debugfs_create_file("node_aggr", 0444, dir, an, &fops_node_aggr);
debugfs_create_file("node_recv", 0444, dir, an, &fops_node_recv); debugfs_create_file("node_recv", 0444, dir, an, &fops_node_recv);
debugfs_create_file("airtime", 0644, dir, an, &fops_airtime);
} }

View File

@ -574,12 +574,12 @@ void ath9k_tx_failed_tasklet(unsigned long data)
{ {
struct ath9k_htc_priv *priv = (struct ath9k_htc_priv *)data; struct ath9k_htc_priv *priv = (struct ath9k_htc_priv *)data;
spin_lock_bh(&priv->tx.tx_lock); spin_lock(&priv->tx.tx_lock);
if (priv->tx.flags & ATH9K_HTC_OP_TX_DRAIN) { if (priv->tx.flags & ATH9K_HTC_OP_TX_DRAIN) {
spin_unlock_bh(&priv->tx.tx_lock); spin_unlock(&priv->tx.tx_lock);
return; return;
} }
spin_unlock_bh(&priv->tx.tx_lock); spin_unlock(&priv->tx.tx_lock);
ath9k_htc_tx_drainq(priv, &priv->tx.tx_failed); ath9k_htc_tx_drainq(priv, &priv->tx.tx_failed);
} }

View File

@ -636,15 +636,15 @@ static int ath9k_of_init(struct ath_softc *sc)
ret = ath9k_eeprom_request(sc, eeprom_name); ret = ath9k_eeprom_request(sc, eeprom_name);
if (ret) if (ret)
return ret; return ret;
ah->ah_flags &= ~AH_USE_EEPROM;
ah->ah_flags |= AH_NO_EEP_SWAP;
} }
mac = of_get_mac_address(np); mac = of_get_mac_address(np);
if (mac) if (mac)
ether_addr_copy(common->macaddr, mac); ether_addr_copy(common->macaddr, mac);
ah->ah_flags &= ~AH_USE_EEPROM;
ah->ah_flags |= AH_NO_EEP_SWAP;
return 0; return 0;
} }
@ -676,8 +676,6 @@ static int ath9k_init_softc(u16 devid, struct ath_softc *sc,
/* Will be cleared in ath9k_start() */ /* Will be cleared in ath9k_start() */
set_bit(ATH_OP_INVALID, &common->op_flags); set_bit(ATH_OP_INVALID, &common->op_flags);
sc->airtime_flags = (AIRTIME_USE_TX | AIRTIME_USE_RX |
AIRTIME_USE_NEW_QUEUES);
sc->sc_ah = ah; sc->sc_ah = ah;
sc->dfs_detector = dfs_pattern_detector_init(common, NL80211_DFS_UNSET); sc->dfs_detector = dfs_pattern_detector_init(common, NL80211_DFS_UNSET);
@ -1013,6 +1011,7 @@ static void ath9k_set_hw_capab(struct ath_softc *sc, struct ieee80211_hw *hw)
SET_IEEE80211_PERM_ADDR(hw, common->macaddr); SET_IEEE80211_PERM_ADDR(hw, common->macaddr);
wiphy_ext_feature_set(hw->wiphy, NL80211_EXT_FEATURE_CQM_RSSI_LIST); wiphy_ext_feature_set(hw->wiphy, NL80211_EXT_FEATURE_CQM_RSSI_LIST);
wiphy_ext_feature_set(hw->wiphy, NL80211_EXT_FEATURE_AIRTIME_FAIRNESS);
} }
int ath9k_init_device(u16 devid, struct ath_softc *sc, int ath9k_init_device(u16 devid, struct ath_softc *sc,

View File

@ -1054,14 +1054,7 @@ static void ath_rx_count_airtime(struct ath_softc *sc,
len, rxs->rate_idx, is_sp); len, rxs->rate_idx, is_sp);
} }
if (!!(sc->airtime_flags & AIRTIME_USE_RX)) { ieee80211_sta_register_airtime(sta, tidno, 0, airtime);
spin_lock_bh(&acq->lock);
an->airtime_deficit[acno] -= airtime;
if (an->airtime_deficit[acno] <= 0)
__ath_tx_queue_tid(sc, ATH_AN_2_TID(an, tidno));
spin_unlock_bh(&acq->lock);
}
ath_debug_airtime(sc, an, airtime, 0);
exit: exit:
rcu_read_unlock(); rcu_read_unlock();
} }

View File

@ -113,44 +113,14 @@ void ath_txq_unlock_complete(struct ath_softc *sc, struct ath_txq *txq)
ath_tx_status(hw, skb); ath_tx_status(hw, skb);
} }
void __ath_tx_queue_tid(struct ath_softc *sc, struct ath_atx_tid *tid)
{
struct ath_vif *avp = (struct ath_vif *) tid->an->vif->drv_priv;
struct ath_chanctx *ctx = avp->chanctx;
struct ath_acq *acq;
struct list_head *tid_list;
u8 acno = TID_TO_WME_AC(tid->tidno);
if (!ctx || !list_empty(&tid->list))
return;
acq = &ctx->acq[acno];
if ((sc->airtime_flags & AIRTIME_USE_NEW_QUEUES) &&
tid->an->airtime_deficit[acno] > 0)
tid_list = &acq->acq_new;
else
tid_list = &acq->acq_old;
list_add_tail(&tid->list, tid_list);
}
void ath_tx_queue_tid(struct ath_softc *sc, struct ath_atx_tid *tid) void ath_tx_queue_tid(struct ath_softc *sc, struct ath_atx_tid *tid)
{ {
struct ath_vif *avp = (struct ath_vif *) tid->an->vif->drv_priv; struct ieee80211_txq *queue =
struct ath_chanctx *ctx = avp->chanctx; container_of((void *)tid, struct ieee80211_txq, drv_priv);
struct ath_acq *acq;
if (!ctx || !list_empty(&tid->list)) ieee80211_schedule_txq(sc->hw, queue);
return;
acq = &ctx->acq[TID_TO_WME_AC(tid->tidno)];
spin_lock_bh(&acq->lock);
__ath_tx_queue_tid(sc, tid);
spin_unlock_bh(&acq->lock);
} }
void ath9k_wake_tx_queue(struct ieee80211_hw *hw, struct ieee80211_txq *queue) void ath9k_wake_tx_queue(struct ieee80211_hw *hw, struct ieee80211_txq *queue)
{ {
struct ath_softc *sc = hw->priv; struct ath_softc *sc = hw->priv;
@ -163,11 +133,7 @@ void ath9k_wake_tx_queue(struct ieee80211_hw *hw, struct ieee80211_txq *queue)
tid->tidno); tid->tidno);
ath_txq_lock(sc, txq); ath_txq_lock(sc, txq);
tid->has_queued = true;
ath_tx_queue_tid(sc, tid);
ath_txq_schedule(sc, txq); ath_txq_schedule(sc, txq);
ath_txq_unlock(sc, txq); ath_txq_unlock(sc, txq);
} }
@ -217,8 +183,8 @@ ath_get_skb_tid(struct ath_softc *sc, struct ath_node *an, struct sk_buff *skb)
return ATH_AN_2_TID(an, tidno); return ATH_AN_2_TID(an, tidno);
} }
static struct sk_buff * static int
ath_tid_pull(struct ath_atx_tid *tid) ath_tid_pull(struct ath_atx_tid *tid, struct sk_buff **skbuf)
{ {
struct ieee80211_txq *txq = container_of((void*)tid, struct ieee80211_txq, drv_priv); struct ieee80211_txq *txq = container_of((void*)tid, struct ieee80211_txq, drv_priv);
struct ath_softc *sc = tid->an->sc; struct ath_softc *sc = tid->an->sc;
@ -229,20 +195,16 @@ ath_tid_pull(struct ath_atx_tid *tid)
}; };
struct sk_buff *skb; struct sk_buff *skb;
struct ath_frame_info *fi; struct ath_frame_info *fi;
int q; int q, ret;
if (!tid->has_queued)
return NULL;
skb = ieee80211_tx_dequeue(hw, txq); skb = ieee80211_tx_dequeue(hw, txq);
if (!skb) { if (!skb)
tid->has_queued = false; return -ENOENT;
return NULL;
}
if (ath_tx_prepare(hw, skb, &txctl)) { ret = ath_tx_prepare(hw, skb, &txctl);
if (ret) {
ieee80211_free_txskb(hw, skb); ieee80211_free_txskb(hw, skb);
return NULL; return ret;
} }
q = skb_get_queue_mapping(skb); q = skb_get_queue_mapping(skb);
@ -252,24 +214,19 @@ ath_tid_pull(struct ath_atx_tid *tid)
++tid->txq->pending_frames; ++tid->txq->pending_frames;
} }
return skb; *skbuf = skb;
return 0;
} }
static int ath_tid_dequeue(struct ath_atx_tid *tid,
static bool ath_tid_has_buffered(struct ath_atx_tid *tid) struct sk_buff **skb)
{ {
return !skb_queue_empty(&tid->retry_q) || tid->has_queued; int ret = 0;
} *skb = __skb_dequeue(&tid->retry_q);
if (!*skb)
ret = ath_tid_pull(tid, skb);
static struct sk_buff *ath_tid_dequeue(struct ath_atx_tid *tid) return ret;
{
struct sk_buff *skb;
skb = __skb_dequeue(&tid->retry_q);
if (!skb)
skb = ath_tid_pull(tid);
return skb;
} }
static void ath_tx_flush_tid(struct ath_softc *sc, struct ath_atx_tid *tid) static void ath_tx_flush_tid(struct ath_softc *sc, struct ath_atx_tid *tid)
@ -365,11 +322,12 @@ static void ath_tid_drain(struct ath_softc *sc, struct ath_txq *txq,
struct list_head bf_head; struct list_head bf_head;
struct ath_tx_status ts; struct ath_tx_status ts;
struct ath_frame_info *fi; struct ath_frame_info *fi;
int ret;
memset(&ts, 0, sizeof(ts)); memset(&ts, 0, sizeof(ts));
INIT_LIST_HEAD(&bf_head); INIT_LIST_HEAD(&bf_head);
while ((skb = ath_tid_dequeue(tid))) { while ((ret = ath_tid_dequeue(tid, &skb)) == 0) {
fi = get_frame_info(skb); fi = get_frame_info(skb);
bf = fi->bf; bf = fi->bf;
@ -681,7 +639,6 @@ static void ath_tx_complete_aggr(struct ath_softc *sc, struct ath_txq *txq,
skb_queue_splice_tail(&bf_pending, &tid->retry_q); skb_queue_splice_tail(&bf_pending, &tid->retry_q);
if (!an->sleeping) { if (!an->sleeping) {
ath_tx_queue_tid(sc, tid); ath_tx_queue_tid(sc, tid);
if (ts->ts_status & (ATH9K_TXERR_FILT | ATH9K_TXERR_XRETRY)) if (ts->ts_status & (ATH9K_TXERR_FILT | ATH9K_TXERR_XRETRY))
tid->clear_ps_filter = true; tid->clear_ps_filter = true;
} }
@ -708,11 +665,11 @@ static bool bf_is_ampdu_not_probing(struct ath_buf *bf)
return bf_isampdu(bf) && !(info->flags & IEEE80211_TX_CTL_RATE_CTRL_PROBE); return bf_isampdu(bf) && !(info->flags & IEEE80211_TX_CTL_RATE_CTRL_PROBE);
} }
static void ath_tx_count_airtime(struct ath_softc *sc, struct ath_node *an, static void ath_tx_count_airtime(struct ath_softc *sc,
struct ath_atx_tid *tid, struct ath_buf *bf, struct ieee80211_sta *sta,
struct ath_buf *bf,
struct ath_tx_status *ts) struct ath_tx_status *ts)
{ {
struct ath_txq *txq = tid->txq;
u32 airtime = 0; u32 airtime = 0;
int i; int i;
@ -722,17 +679,7 @@ static void ath_tx_count_airtime(struct ath_softc *sc, struct ath_node *an,
airtime += rate_dur * bf->rates[i].count; airtime += rate_dur * bf->rates[i].count;
} }
if (sc->airtime_flags & AIRTIME_USE_TX) { ieee80211_sta_register_airtime(sta, ts->tid, airtime, 0);
int q = txq->mac80211_qnum;
struct ath_acq *acq = &sc->cur_chan->acq[q];
spin_lock_bh(&acq->lock);
an->airtime_deficit[q] -= airtime;
if (an->airtime_deficit[q] <= 0)
__ath_tx_queue_tid(sc, tid);
spin_unlock_bh(&acq->lock);
}
ath_debug_airtime(sc, an, 0, airtime);
} }
static void ath_tx_process_buffer(struct ath_softc *sc, struct ath_txq *txq, static void ath_tx_process_buffer(struct ath_softc *sc, struct ath_txq *txq,
@ -762,7 +709,7 @@ static void ath_tx_process_buffer(struct ath_softc *sc, struct ath_txq *txq,
if (sta) { if (sta) {
struct ath_node *an = (struct ath_node *)sta->drv_priv; struct ath_node *an = (struct ath_node *)sta->drv_priv;
tid = ath_get_skb_tid(sc, an, bf->bf_mpdu); tid = ath_get_skb_tid(sc, an, bf->bf_mpdu);
ath_tx_count_airtime(sc, an, tid, bf, ts); ath_tx_count_airtime(sc, sta, bf, ts);
if (ts->ts_status & (ATH9K_TXERR_FILT | ATH9K_TXERR_XRETRY)) if (ts->ts_status & (ATH9K_TXERR_FILT | ATH9K_TXERR_XRETRY))
tid->clear_ps_filter = true; tid->clear_ps_filter = true;
} }
@ -947,20 +894,21 @@ static int ath_compute_num_delims(struct ath_softc *sc, struct ath_atx_tid *tid,
return ndelim; return ndelim;
} }
static struct ath_buf * static int
ath_tx_get_tid_subframe(struct ath_softc *sc, struct ath_txq *txq, ath_tx_get_tid_subframe(struct ath_softc *sc, struct ath_txq *txq,
struct ath_atx_tid *tid) struct ath_atx_tid *tid, struct ath_buf **buf)
{ {
struct ieee80211_tx_info *tx_info; struct ieee80211_tx_info *tx_info;
struct ath_frame_info *fi; struct ath_frame_info *fi;
struct sk_buff *skb, *first_skb = NULL;
struct ath_buf *bf; struct ath_buf *bf;
struct sk_buff *skb, *first_skb = NULL;
u16 seqno; u16 seqno;
int ret;
while (1) { while (1) {
skb = ath_tid_dequeue(tid); ret = ath_tid_dequeue(tid, &skb);
if (!skb) if (ret < 0)
break; return ret;
fi = get_frame_info(skb); fi = get_frame_info(skb);
bf = fi->bf; bf = fi->bf;
@ -992,7 +940,7 @@ ath_tx_get_tid_subframe(struct ath_softc *sc, struct ath_txq *txq,
if (!(tx_info->flags & IEEE80211_TX_CTL_AMPDU)) { if (!(tx_info->flags & IEEE80211_TX_CTL_AMPDU)) {
bf->bf_state.bf_type = 0; bf->bf_state.bf_type = 0;
return bf; break;
} }
bf->bf_state.bf_type = BUF_AMPDU | BUF_AGGR; bf->bf_state.bf_type = BUF_AMPDU | BUF_AGGR;
@ -1011,7 +959,7 @@ ath_tx_get_tid_subframe(struct ath_softc *sc, struct ath_txq *txq,
first_skb = skb; first_skb = skb;
continue; continue;
} }
break; return -EINPROGRESS;
} }
if (tid->bar_index > ATH_BA_INDEX(tid->seq_start, seqno)) { if (tid->bar_index > ATH_BA_INDEX(tid->seq_start, seqno)) {
@ -1028,10 +976,11 @@ ath_tx_get_tid_subframe(struct ath_softc *sc, struct ath_txq *txq,
if (bf_isampdu(bf)) if (bf_isampdu(bf))
ath_tx_addto_baw(sc, tid, bf); ath_tx_addto_baw(sc, tid, bf);
return bf; break;
} }
return NULL; *buf = bf;
return 0;
} }
static int static int
@ -1041,7 +990,7 @@ ath_tx_form_aggr(struct ath_softc *sc, struct ath_txq *txq,
{ {
#define PADBYTES(_len) ((4 - ((_len) % 4)) % 4) #define PADBYTES(_len) ((4 - ((_len) % 4)) % 4)
struct ath_buf *bf = bf_first, *bf_prev = NULL; struct ath_buf *bf = bf_first, *bf_prev = NULL;
int nframes = 0, ndelim; int nframes = 0, ndelim, ret;
u16 aggr_limit = 0, al = 0, bpad = 0, u16 aggr_limit = 0, al = 0, bpad = 0,
al_delta, h_baw = tid->baw_size / 2; al_delta, h_baw = tid->baw_size / 2;
struct ieee80211_tx_info *tx_info; struct ieee80211_tx_info *tx_info;
@ -1093,7 +1042,9 @@ ath_tx_form_aggr(struct ath_softc *sc, struct ath_txq *txq,
bf_prev = bf; bf_prev = bf;
bf = ath_tx_get_tid_subframe(sc, txq, tid); ret = ath_tx_get_tid_subframe(sc, txq, tid, &bf);
if (ret < 0)
break;
} }
goto finish; goto finish;
stop: stop:
@ -1490,7 +1441,7 @@ ath_tx_form_burst(struct ath_softc *sc, struct ath_txq *txq,
struct ath_buf *bf_first) struct ath_buf *bf_first)
{ {
struct ath_buf *bf = bf_first, *bf_prev = NULL; struct ath_buf *bf = bf_first, *bf_prev = NULL;
int nframes = 0; int nframes = 0, ret;
do { do {
struct ieee80211_tx_info *tx_info; struct ieee80211_tx_info *tx_info;
@ -1504,8 +1455,8 @@ ath_tx_form_burst(struct ath_softc *sc, struct ath_txq *txq,
if (nframes >= 2) if (nframes >= 2)
break; break;
bf = ath_tx_get_tid_subframe(sc, txq, tid); ret = ath_tx_get_tid_subframe(sc, txq, tid, &bf);
if (!bf) if (ret < 0)
break; break;
tx_info = IEEE80211_SKB_CB(bf->bf_mpdu); tx_info = IEEE80211_SKB_CB(bf->bf_mpdu);
@ -1518,30 +1469,27 @@ ath_tx_form_burst(struct ath_softc *sc, struct ath_txq *txq,
} while (1); } while (1);
} }
static bool ath_tx_sched_aggr(struct ath_softc *sc, struct ath_txq *txq, static int ath_tx_sched_aggr(struct ath_softc *sc, struct ath_txq *txq,
struct ath_atx_tid *tid) struct ath_atx_tid *tid)
{ {
struct ath_buf *bf; struct ath_buf *bf = NULL;
struct ieee80211_tx_info *tx_info; struct ieee80211_tx_info *tx_info;
struct list_head bf_q; struct list_head bf_q;
int aggr_len = 0; int aggr_len = 0, ret;
bool aggr; bool aggr;
if (!ath_tid_has_buffered(tid))
return false;
INIT_LIST_HEAD(&bf_q); INIT_LIST_HEAD(&bf_q);
bf = ath_tx_get_tid_subframe(sc, txq, tid); ret = ath_tx_get_tid_subframe(sc, txq, tid, &bf);
if (!bf) if (ret < 0)
return false; return ret;
tx_info = IEEE80211_SKB_CB(bf->bf_mpdu); tx_info = IEEE80211_SKB_CB(bf->bf_mpdu);
aggr = !!(tx_info->flags & IEEE80211_TX_CTL_AMPDU); aggr = !!(tx_info->flags & IEEE80211_TX_CTL_AMPDU);
if ((aggr && txq->axq_ampdu_depth >= ATH_AGGR_MIN_QDEPTH) || if ((aggr && txq->axq_ampdu_depth >= ATH_AGGR_MIN_QDEPTH) ||
(!aggr && txq->axq_depth >= ATH_NON_AGGR_MIN_QDEPTH)) { (!aggr && txq->axq_depth >= ATH_NON_AGGR_MIN_QDEPTH)) {
__skb_queue_tail(&tid->retry_q, bf->bf_mpdu); __skb_queue_tail(&tid->retry_q, bf->bf_mpdu);
return false; return -EBUSY;
} }
ath_set_rates(tid->an->vif, tid->an->sta, bf); ath_set_rates(tid->an->vif, tid->an->sta, bf);
@ -1551,7 +1499,7 @@ static bool ath_tx_sched_aggr(struct ath_softc *sc, struct ath_txq *txq,
ath_tx_form_burst(sc, txq, tid, &bf_q, bf); ath_tx_form_burst(sc, txq, tid, &bf_q, bf);
if (list_empty(&bf_q)) if (list_empty(&bf_q))
return false; return -EAGAIN;
if (tid->clear_ps_filter || tid->an->no_ps_filter) { if (tid->clear_ps_filter || tid->an->no_ps_filter) {
tid->clear_ps_filter = false; tid->clear_ps_filter = false;
@ -1560,7 +1508,7 @@ static bool ath_tx_sched_aggr(struct ath_softc *sc, struct ath_txq *txq,
ath_tx_fill_desc(sc, bf, txq, aggr_len); ath_tx_fill_desc(sc, bf, txq, aggr_len);
ath_tx_txqaddbuf(sc, txq, &bf_q, false); ath_tx_txqaddbuf(sc, txq, &bf_q, false);
return true; return 0;
} }
int ath_tx_aggr_start(struct ath_softc *sc, struct ieee80211_sta *sta, int ath_tx_aggr_start(struct ath_softc *sc, struct ieee80211_sta *sta,
@ -1623,28 +1571,16 @@ void ath_tx_aggr_sleep(struct ieee80211_sta *sta, struct ath_softc *sc,
{ {
struct ath_common *common = ath9k_hw_common(sc->sc_ah); struct ath_common *common = ath9k_hw_common(sc->sc_ah);
struct ath_atx_tid *tid; struct ath_atx_tid *tid;
struct ath_txq *txq;
int tidno; int tidno;
ath_dbg(common, XMIT, "%s called\n", __func__); ath_dbg(common, XMIT, "%s called\n", __func__);
for (tidno = 0; tidno < IEEE80211_NUM_TIDS; tidno++) { for (tidno = 0; tidno < IEEE80211_NUM_TIDS; tidno++) {
tid = ath_node_to_tid(an, tidno); tid = ath_node_to_tid(an, tidno);
txq = tid->txq;
ath_txq_lock(sc, txq);
if (list_empty(&tid->list)) {
ath_txq_unlock(sc, txq);
continue;
}
if (!skb_queue_empty(&tid->retry_q)) if (!skb_queue_empty(&tid->retry_q))
ieee80211_sta_set_buffered(sta, tid->tidno, true); ieee80211_sta_set_buffered(sta, tid->tidno, true);
list_del_init(&tid->list);
ath_txq_unlock(sc, txq);
} }
} }
@ -1663,11 +1599,12 @@ void ath_tx_aggr_wakeup(struct ath_softc *sc, struct ath_node *an)
ath_txq_lock(sc, txq); ath_txq_lock(sc, txq);
tid->clear_ps_filter = true; tid->clear_ps_filter = true;
if (ath_tid_has_buffered(tid)) { if (!skb_queue_empty(&tid->retry_q)) {
ath_tx_queue_tid(sc, tid); ath_tx_queue_tid(sc, tid);
ath_txq_schedule(sc, txq); ath_txq_schedule(sc, txq);
} }
ath_txq_unlock_complete(sc, txq); ath_txq_unlock_complete(sc, txq);
} }
} }
@ -1698,9 +1635,9 @@ void ath9k_release_buffered_frames(struct ieee80211_hw *hw,
struct ath_txq *txq = sc->tx.uapsdq; struct ath_txq *txq = sc->tx.uapsdq;
struct ieee80211_tx_info *info; struct ieee80211_tx_info *info;
struct list_head bf_q; struct list_head bf_q;
struct ath_buf *bf_tail = NULL, *bf; struct ath_buf *bf_tail = NULL, *bf = NULL;
int sent = 0; int sent = 0;
int i; int i, ret;
INIT_LIST_HEAD(&bf_q); INIT_LIST_HEAD(&bf_q);
for (i = 0; tids && nframes; i++, tids >>= 1) { for (i = 0; tids && nframes; i++, tids >>= 1) {
@ -1713,8 +1650,9 @@ void ath9k_release_buffered_frames(struct ieee80211_hw *hw,
ath_txq_lock(sc, tid->txq); ath_txq_lock(sc, tid->txq);
while (nframes > 0) { while (nframes > 0) {
bf = ath_tx_get_tid_subframe(sc, sc->tx.uapsdq, tid); ret = ath_tx_get_tid_subframe(sc, sc->tx.uapsdq,
if (!bf) tid, &bf);
if (ret < 0)
break; break;
ath9k_set_moredata(sc, bf, true); ath9k_set_moredata(sc, bf, true);
@ -1980,11 +1918,11 @@ void ath_tx_cleanupq(struct ath_softc *sc, struct ath_txq *txq)
*/ */
void ath_txq_schedule(struct ath_softc *sc, struct ath_txq *txq) void ath_txq_schedule(struct ath_softc *sc, struct ath_txq *txq)
{ {
struct ieee80211_hw *hw = sc->hw;
struct ath_common *common = ath9k_hw_common(sc->sc_ah); struct ath_common *common = ath9k_hw_common(sc->sc_ah);
struct ieee80211_txq *queue;
struct ath_atx_tid *tid; struct ath_atx_tid *tid;
struct list_head *tid_list; int ret;
struct ath_acq *acq;
bool active = AIRTIME_ACTIVE(sc->airtime_flags);
if (txq->mac80211_qnum < 0) if (txq->mac80211_qnum < 0)
return; return;
@ -1992,58 +1930,26 @@ void ath_txq_schedule(struct ath_softc *sc, struct ath_txq *txq)
if (test_bit(ATH_OP_HW_RESET, &common->op_flags)) if (test_bit(ATH_OP_HW_RESET, &common->op_flags))
return; return;
ieee80211_txq_schedule_start(hw, txq->mac80211_qnum);
spin_lock_bh(&sc->chan_lock); spin_lock_bh(&sc->chan_lock);
rcu_read_lock(); rcu_read_lock();
acq = &sc->cur_chan->acq[txq->mac80211_qnum];
if (sc->cur_chan->stopped) if (sc->cur_chan->stopped)
goto out; goto out;
begin: while ((queue = ieee80211_next_txq(hw, txq->mac80211_qnum))) {
tid_list = &acq->acq_new; tid = (struct ath_atx_tid *)queue->drv_priv;
if (list_empty(tid_list)) {
tid_list = &acq->acq_old;
if (list_empty(tid_list))
goto out;
}
tid = list_first_entry(tid_list, struct ath_atx_tid, list);
if (active && tid->an->airtime_deficit[txq->mac80211_qnum] <= 0) { ret = ath_tx_sched_aggr(sc, txq, tid);
spin_lock_bh(&acq->lock); ath_dbg(common, QUEUE, "ath_tx_sched_aggr returned %d\n", ret);
tid->an->airtime_deficit[txq->mac80211_qnum] += ATH_AIRTIME_QUANTUM;
list_move_tail(&tid->list, &acq->acq_old);
spin_unlock_bh(&acq->lock);
goto begin;
}
if (!ath_tid_has_buffered(tid)) { ieee80211_return_txq(hw, queue);
spin_lock_bh(&acq->lock);
if ((tid_list == &acq->acq_new) && !list_empty(&acq->acq_old))
list_move_tail(&tid->list, &acq->acq_old);
else {
list_del_init(&tid->list);
}
spin_unlock_bh(&acq->lock);
goto begin;
}
/*
* If we succeed in scheduling something, immediately restart to make
* sure we keep the HW busy.
*/
if(ath_tx_sched_aggr(sc, txq, tid)) {
if (!active) {
spin_lock_bh(&acq->lock);
list_move_tail(&tid->list, &acq->acq_old);
spin_unlock_bh(&acq->lock);
}
goto begin;
} }
out: out:
rcu_read_unlock(); rcu_read_unlock();
spin_unlock_bh(&sc->chan_lock); spin_unlock_bh(&sc->chan_lock);
ieee80211_txq_schedule_end(hw, txq->mac80211_qnum);
} }
void ath_txq_schedule_all(struct ath_softc *sc) void ath_txq_schedule_all(struct ath_softc *sc)
@ -2887,9 +2793,6 @@ void ath_tx_node_init(struct ath_softc *sc, struct ath_node *an)
struct ath_atx_tid *tid; struct ath_atx_tid *tid;
int tidno, acno; int tidno, acno;
for (acno = 0; acno < IEEE80211_NUM_ACS; acno++)
an->airtime_deficit[acno] = ATH_AIRTIME_QUANTUM;
for (tidno = 0; tidno < IEEE80211_NUM_TIDS; tidno++) { for (tidno = 0; tidno < IEEE80211_NUM_TIDS; tidno++) {
tid = ath_node_to_tid(an, tidno); tid = ath_node_to_tid(an, tidno);
tid->an = an; tid->an = an;
@ -2899,7 +2802,6 @@ void ath_tx_node_init(struct ath_softc *sc, struct ath_node *an)
tid->baw_head = tid->baw_tail = 0; tid->baw_head = tid->baw_tail = 0;
tid->active = false; tid->active = false;
tid->clear_ps_filter = true; tid->clear_ps_filter = true;
tid->has_queued = false;
__skb_queue_head_init(&tid->retry_q); __skb_queue_head_init(&tid->retry_q);
INIT_LIST_HEAD(&tid->list); INIT_LIST_HEAD(&tid->list);
acno = TID_TO_WME_AC(tidno); acno = TID_TO_WME_AC(tidno);

View File

@ -427,7 +427,7 @@ static int carl9170_rx_mac_status(struct ar9170 *ar,
if (head->plcp[6] & 0x80) if (head->plcp[6] & 0x80)
status->enc_flags |= RX_ENC_FLAG_SHORT_GI; status->enc_flags |= RX_ENC_FLAG_SHORT_GI;
status->rate_idx = clamp(0, 75, head->plcp[3] & 0x7f); status->rate_idx = clamp(head->plcp[3] & 0x7f, 0, 75);
status->encoding = RX_ENC_HT; status->encoding = RX_ENC_HT;
break; break;

View File

@ -185,7 +185,9 @@ enum CountryCode {
CTRY_UKRAINE = 804, CTRY_UKRAINE = 804,
CTRY_UNITED_KINGDOM = 826, CTRY_UNITED_KINGDOM = 826,
CTRY_UNITED_STATES = 840, CTRY_UNITED_STATES = 840,
CTRY_UNITED_STATES2 = 841,
CTRY_UNITED_STATES_FCC49 = 842, CTRY_UNITED_STATES_FCC49 = 842,
CTRY_UNITED_STATES3 = 843,
CTRY_URUGUAY = 858, CTRY_URUGUAY = 858,
CTRY_UZBEKISTAN = 860, CTRY_UZBEKISTAN = 860,
CTRY_VENEZUELA = 862, CTRY_VENEZUELA = 862,

View File

@ -483,6 +483,8 @@ static struct country_code_to_enum_rd allCountries[] = {
{CTRY_UAE, NULL1_WORLD, "AE"}, {CTRY_UAE, NULL1_WORLD, "AE"},
{CTRY_UNITED_KINGDOM, ETSI1_WORLD, "GB"}, {CTRY_UNITED_KINGDOM, ETSI1_WORLD, "GB"},
{CTRY_UNITED_STATES, FCC3_FCCA, "US"}, {CTRY_UNITED_STATES, FCC3_FCCA, "US"},
{CTRY_UNITED_STATES2, FCC3_FCCA, "US"},
{CTRY_UNITED_STATES3, FCC3_FCCA, "US"},
/* This "PS" is for US public safety actually... to support this we /* This "PS" is for US public safety actually... to support this we
* would need to assign new special alpha2 to CRDA db as with the world * would need to assign new special alpha2 to CRDA db as with the world
* regdomain and use another alpha2 */ * regdomain and use another alpha2 */

View File

@ -178,7 +178,7 @@ brcmf_proto_bcdc_query_dcmd(struct brcmf_pub *drvr, int ifidx, uint cmd,
*fwerr = 0; *fwerr = 0;
ret = brcmf_proto_bcdc_msg(drvr, ifidx, cmd, buf, len, false); ret = brcmf_proto_bcdc_msg(drvr, ifidx, cmd, buf, len, false);
if (ret < 0) { if (ret < 0) {
brcmf_err("brcmf_proto_bcdc_msg failed w/status %d\n", bphy_err(drvr, "brcmf_proto_bcdc_msg failed w/status %d\n",
ret); ret);
goto done; goto done;
} }
@ -195,7 +195,7 @@ brcmf_proto_bcdc_query_dcmd(struct brcmf_pub *drvr, int ifidx, uint cmd,
if ((id < bcdc->reqid) && (++retries < RETRIES)) if ((id < bcdc->reqid) && (++retries < RETRIES))
goto retry; goto retry;
if (id != bcdc->reqid) { if (id != bcdc->reqid) {
brcmf_err("%s: unexpected request id %d (expected %d)\n", bphy_err(drvr, "%s: unexpected request id %d (expected %d)\n",
brcmf_ifname(brcmf_get_ifp(drvr, ifidx)), id, brcmf_ifname(brcmf_get_ifp(drvr, ifidx)), id,
bcdc->reqid); bcdc->reqid);
ret = -EINVAL; ret = -EINVAL;
@ -245,7 +245,7 @@ brcmf_proto_bcdc_set_dcmd(struct brcmf_pub *drvr, int ifidx, uint cmd,
id = (flags & BCDC_DCMD_ID_MASK) >> BCDC_DCMD_ID_SHIFT; id = (flags & BCDC_DCMD_ID_MASK) >> BCDC_DCMD_ID_SHIFT;
if (id != bcdc->reqid) { if (id != bcdc->reqid) {
brcmf_err("%s: unexpected request id %d (expected %d)\n", bphy_err(drvr, "%s: unexpected request id %d (expected %d)\n",
brcmf_ifname(brcmf_get_ifp(drvr, ifidx)), id, brcmf_ifname(brcmf_get_ifp(drvr, ifidx)), id,
bcdc->reqid); bcdc->reqid);
ret = -EINVAL; ret = -EINVAL;
@ -312,7 +312,7 @@ brcmf_proto_bcdc_hdrpull(struct brcmf_pub *drvr, bool do_fws,
} }
if (((h->flags & BCDC_FLAG_VER_MASK) >> BCDC_FLAG_VER_SHIFT) != if (((h->flags & BCDC_FLAG_VER_MASK) >> BCDC_FLAG_VER_SHIFT) !=
BCDC_PROTO_VER) { BCDC_PROTO_VER) {
brcmf_err("%s: non-BCDC packet received, flags 0x%x\n", bphy_err(drvr, "%s: non-BCDC packet received, flags 0x%x\n",
brcmf_ifname(tmp_if), h->flags); brcmf_ifname(tmp_if), h->flags);
return -EBADE; return -EBADE;
} }
@ -460,7 +460,7 @@ int brcmf_proto_bcdc_attach(struct brcmf_pub *drvr)
/* ensure that the msg buf directly follows the cdc msg struct */ /* ensure that the msg buf directly follows the cdc msg struct */
if ((unsigned long)(&bcdc->msg + 1) != (unsigned long)bcdc->buf) { if ((unsigned long)(&bcdc->msg + 1) != (unsigned long)bcdc->buf) {
brcmf_err("struct brcmf_proto_bcdc is not correctly defined\n"); bphy_err(drvr, "struct brcmf_proto_bcdc is not correctly defined\n");
goto fail; goto fail;
} }

View File

@ -90,6 +90,7 @@ struct brcmf_bus_ops {
int (*get_memdump)(struct device *dev, void *data, size_t len); int (*get_memdump)(struct device *dev, void *data, size_t len);
int (*get_fwname)(struct device *dev, const char *ext, int (*get_fwname)(struct device *dev, const char *ext,
unsigned char *fw_name); unsigned char *fw_name);
void (*debugfs_create)(struct device *dev);
}; };
@ -235,6 +236,15 @@ int brcmf_bus_get_fwname(struct brcmf_bus *bus, const char *ext,
return bus->ops->get_fwname(bus->dev, ext, fw_name); return bus->ops->get_fwname(bus->dev, ext, fw_name);
} }
static inline
void brcmf_bus_debugfs_create(struct brcmf_bus *bus)
{
if (!bus->ops->debugfs_create)
return;
return bus->ops->debugfs_create(bus->dev);
}
/* /*
* interface functions from common layer * interface functions from common layer
*/ */

File diff suppressed because it is too large Load Diff

View File

@ -90,6 +90,7 @@ struct brcmf_mp_global_t brcmf_mp_global;
void brcmf_c_set_joinpref_default(struct brcmf_if *ifp) void brcmf_c_set_joinpref_default(struct brcmf_if *ifp)
{ {
struct brcmf_pub *drvr = ifp->drvr;
struct brcmf_join_pref_params join_pref_params[2]; struct brcmf_join_pref_params join_pref_params[2];
int err; int err;
@ -106,7 +107,7 @@ void brcmf_c_set_joinpref_default(struct brcmf_if *ifp)
err = brcmf_fil_iovar_data_set(ifp, "join_pref", join_pref_params, err = brcmf_fil_iovar_data_set(ifp, "join_pref", join_pref_params,
sizeof(join_pref_params)); sizeof(join_pref_params));
if (err) if (err)
brcmf_err("Set join_pref error (%d)\n", err); bphy_err(drvr, "Set join_pref error (%d)\n", err);
} }
static int brcmf_c_download(struct brcmf_if *ifp, u16 flag, static int brcmf_c_download(struct brcmf_if *ifp, u16 flag,
@ -129,7 +130,8 @@ static int brcmf_c_download(struct brcmf_if *ifp, u16 flag,
static int brcmf_c_process_clm_blob(struct brcmf_if *ifp) static int brcmf_c_process_clm_blob(struct brcmf_if *ifp)
{ {
struct brcmf_bus *bus = ifp->drvr->bus_if; struct brcmf_pub *drvr = ifp->drvr;
struct brcmf_bus *bus = drvr->bus_if;
struct brcmf_dload_data_le *chunk_buf; struct brcmf_dload_data_le *chunk_buf;
const struct firmware *clm = NULL; const struct firmware *clm = NULL;
u8 clm_name[BRCMF_FW_NAME_LEN]; u8 clm_name[BRCMF_FW_NAME_LEN];
@ -145,7 +147,7 @@ static int brcmf_c_process_clm_blob(struct brcmf_if *ifp)
memset(clm_name, 0, sizeof(clm_name)); memset(clm_name, 0, sizeof(clm_name));
err = brcmf_bus_get_fwname(bus, ".clm_blob", clm_name); err = brcmf_bus_get_fwname(bus, ".clm_blob", clm_name);
if (err) { if (err) {
brcmf_err("get CLM blob file name failed (%d)\n", err); bphy_err(drvr, "get CLM blob file name failed (%d)\n", err);
return err; return err;
} }
@ -182,12 +184,12 @@ static int brcmf_c_process_clm_blob(struct brcmf_if *ifp)
} while ((datalen > 0) && (err == 0)); } while ((datalen > 0) && (err == 0));
if (err) { if (err) {
brcmf_err("clmload (%zu byte file) failed (%d); ", bphy_err(drvr, "clmload (%zu byte file) failed (%d)\n",
clm->size, err); clm->size, err);
/* Retrieve clmload_status and print */ /* Retrieve clmload_status and print */
err = brcmf_fil_iovar_int_get(ifp, "clmload_status", &status); err = brcmf_fil_iovar_int_get(ifp, "clmload_status", &status);
if (err) if (err)
brcmf_err("get clmload_status failed (%d)\n", err); bphy_err(drvr, "get clmload_status failed (%d)\n", err);
else else
brcmf_dbg(INFO, "clmload_status=%d\n", status); brcmf_dbg(INFO, "clmload_status=%d\n", status);
err = -EIO; err = -EIO;
@ -201,6 +203,7 @@ static int brcmf_c_process_clm_blob(struct brcmf_if *ifp)
int brcmf_c_preinit_dcmds(struct brcmf_if *ifp) int brcmf_c_preinit_dcmds(struct brcmf_if *ifp)
{ {
struct brcmf_pub *drvr = ifp->drvr;
s8 eventmask[BRCMF_EVENTING_MASK_LEN]; s8 eventmask[BRCMF_EVENTING_MASK_LEN];
u8 buf[BRCMF_DCMD_SMLEN]; u8 buf[BRCMF_DCMD_SMLEN];
struct brcmf_bus *bus; struct brcmf_bus *bus;
@ -214,7 +217,7 @@ int brcmf_c_preinit_dcmds(struct brcmf_if *ifp)
err = brcmf_fil_iovar_data_get(ifp, "cur_etheraddr", ifp->mac_addr, err = brcmf_fil_iovar_data_get(ifp, "cur_etheraddr", ifp->mac_addr,
sizeof(ifp->mac_addr)); sizeof(ifp->mac_addr));
if (err < 0) { if (err < 0) {
brcmf_err("Retrieving cur_etheraddr failed, %d\n", err); bphy_err(drvr, "Retrieving cur_etheraddr failed, %d\n", err);
goto done; goto done;
} }
memcpy(ifp->drvr->wiphy->perm_addr, ifp->drvr->mac, ETH_ALEN); memcpy(ifp->drvr->wiphy->perm_addr, ifp->drvr->mac, ETH_ALEN);
@ -226,7 +229,7 @@ int brcmf_c_preinit_dcmds(struct brcmf_if *ifp)
err = brcmf_fil_cmd_data_get(ifp, BRCMF_C_GET_REVINFO, err = brcmf_fil_cmd_data_get(ifp, BRCMF_C_GET_REVINFO,
&revinfo, sizeof(revinfo)); &revinfo, sizeof(revinfo));
if (err < 0) { if (err < 0) {
brcmf_err("retrieving revision info failed, %d\n", err); bphy_err(drvr, "retrieving revision info failed, %d\n", err);
strlcpy(ri->chipname, "UNKNOWN", sizeof(ri->chipname)); strlcpy(ri->chipname, "UNKNOWN", sizeof(ri->chipname));
} else { } else {
ri->vendorid = le32_to_cpu(revinfo.vendorid); ri->vendorid = le32_to_cpu(revinfo.vendorid);
@ -260,7 +263,7 @@ int brcmf_c_preinit_dcmds(struct brcmf_if *ifp)
/* Do any CLM downloading */ /* Do any CLM downloading */
err = brcmf_c_process_clm_blob(ifp); err = brcmf_c_process_clm_blob(ifp);
if (err < 0) { if (err < 0) {
brcmf_err("download CLM blob file failed, %d\n", err); bphy_err(drvr, "download CLM blob file failed, %d\n", err);
goto done; goto done;
} }
@ -269,7 +272,7 @@ int brcmf_c_preinit_dcmds(struct brcmf_if *ifp)
strcpy(buf, "ver"); strcpy(buf, "ver");
err = brcmf_fil_iovar_data_get(ifp, "ver", buf, sizeof(buf)); err = brcmf_fil_iovar_data_get(ifp, "ver", buf, sizeof(buf));
if (err < 0) { if (err < 0) {
brcmf_err("Retrieving version information failed, %d\n", bphy_err(drvr, "Retrieving version information failed, %d\n",
err); err);
goto done; goto done;
} }
@ -304,7 +307,7 @@ int brcmf_c_preinit_dcmds(struct brcmf_if *ifp)
/* set mpc */ /* set mpc */
err = brcmf_fil_iovar_int_set(ifp, "mpc", 1); err = brcmf_fil_iovar_int_set(ifp, "mpc", 1);
if (err) { if (err) {
brcmf_err("failed setting mpc\n"); bphy_err(drvr, "failed setting mpc\n");
goto done; goto done;
} }
@ -314,14 +317,14 @@ int brcmf_c_preinit_dcmds(struct brcmf_if *ifp)
err = brcmf_fil_iovar_data_get(ifp, "event_msgs", eventmask, err = brcmf_fil_iovar_data_get(ifp, "event_msgs", eventmask,
BRCMF_EVENTING_MASK_LEN); BRCMF_EVENTING_MASK_LEN);
if (err) { if (err) {
brcmf_err("Get event_msgs error (%d)\n", err); bphy_err(drvr, "Get event_msgs error (%d)\n", err);
goto done; goto done;
} }
setbit(eventmask, BRCMF_E_IF); setbit(eventmask, BRCMF_E_IF);
err = brcmf_fil_iovar_data_set(ifp, "event_msgs", eventmask, err = brcmf_fil_iovar_data_set(ifp, "event_msgs", eventmask,
BRCMF_EVENTING_MASK_LEN); BRCMF_EVENTING_MASK_LEN);
if (err) { if (err) {
brcmf_err("Set event_msgs error (%d)\n", err); bphy_err(drvr, "Set event_msgs error (%d)\n", err);
goto done; goto done;
} }
@ -329,7 +332,7 @@ int brcmf_c_preinit_dcmds(struct brcmf_if *ifp)
err = brcmf_fil_cmd_int_set(ifp, BRCMF_C_SET_SCAN_CHANNEL_TIME, err = brcmf_fil_cmd_int_set(ifp, BRCMF_C_SET_SCAN_CHANNEL_TIME,
BRCMF_DEFAULT_SCAN_CHANNEL_TIME); BRCMF_DEFAULT_SCAN_CHANNEL_TIME);
if (err) { if (err) {
brcmf_err("BRCMF_C_SET_SCAN_CHANNEL_TIME error (%d)\n", bphy_err(drvr, "BRCMF_C_SET_SCAN_CHANNEL_TIME error (%d)\n",
err); err);
goto done; goto done;
} }
@ -338,7 +341,7 @@ int brcmf_c_preinit_dcmds(struct brcmf_if *ifp)
err = brcmf_fil_cmd_int_set(ifp, BRCMF_C_SET_SCAN_UNASSOC_TIME, err = brcmf_fil_cmd_int_set(ifp, BRCMF_C_SET_SCAN_UNASSOC_TIME,
BRCMF_DEFAULT_SCAN_UNASSOC_TIME); BRCMF_DEFAULT_SCAN_UNASSOC_TIME);
if (err) { if (err) {
brcmf_err("BRCMF_C_SET_SCAN_UNASSOC_TIME error (%d)\n", bphy_err(drvr, "BRCMF_C_SET_SCAN_UNASSOC_TIME error (%d)\n",
err); err);
goto done; goto done;
} }
@ -350,7 +353,7 @@ int brcmf_c_preinit_dcmds(struct brcmf_if *ifp)
} }
#ifndef CONFIG_BRCM_TRACING #ifndef CONFIG_BRCM_TRACING
void __brcmf_err(const char *func, const char *fmt, ...) void __brcmf_err(struct brcmf_bus *bus, const char *func, const char *fmt, ...)
{ {
struct va_format vaf; struct va_format vaf;
va_list args; va_list args;
@ -359,6 +362,9 @@ void __brcmf_err(const char *func, const char *fmt, ...)
vaf.fmt = fmt; vaf.fmt = fmt;
vaf.va = &args; vaf.va = &args;
if (bus)
dev_err(bus->dev, "%s: %pV", func, &vaf);
else
pr_err("%s: %pV", func, &vaf); pr_err("%s: %pV", func, &vaf);
va_end(args); va_end(args);

View File

@ -43,6 +43,36 @@
#define BRCMF_BSSIDX_INVALID -1 #define BRCMF_BSSIDX_INVALID -1
#define RXS_PBPRES BIT(2)
#define D11_PHY_HDR_LEN 6
struct d11rxhdr_le {
__le16 RxFrameSize;
u16 PAD;
__le16 PhyRxStatus_0;
__le16 PhyRxStatus_1;
__le16 PhyRxStatus_2;
__le16 PhyRxStatus_3;
__le16 PhyRxStatus_4;
__le16 PhyRxStatus_5;
__le16 RxStatus1;
__le16 RxStatus2;
__le16 RxTSFTime;
__le16 RxChan;
u8 unknown[12];
} __packed;
struct wlc_d11rxhdr {
struct d11rxhdr_le rxhdr;
__le32 tsf_l;
s8 rssi;
s8 rxpwr0;
s8 rxpwr1;
s8 do_rssi_ma;
s8 rxpwr[4];
} __packed;
char *brcmf_ifname(struct brcmf_if *ifp) char *brcmf_ifname(struct brcmf_if *ifp)
{ {
if (!ifp) if (!ifp)
@ -60,7 +90,7 @@ struct brcmf_if *brcmf_get_ifp(struct brcmf_pub *drvr, int ifidx)
s32 bsscfgidx; s32 bsscfgidx;
if (ifidx < 0 || ifidx >= BRCMF_MAX_IFS) { if (ifidx < 0 || ifidx >= BRCMF_MAX_IFS) {
brcmf_err("ifidx %d out of range\n", ifidx); bphy_err(drvr, "ifidx %d out of range\n", ifidx);
return NULL; return NULL;
} }
@ -111,7 +141,9 @@ void brcmf_configure_arp_nd_offload(struct brcmf_if *ifp, bool enable)
static void _brcmf_set_multicast_list(struct work_struct *work) static void _brcmf_set_multicast_list(struct work_struct *work)
{ {
struct brcmf_if *ifp; struct brcmf_if *ifp = container_of(work, struct brcmf_if,
multicast_work);
struct brcmf_pub *drvr = ifp->drvr;
struct net_device *ndev; struct net_device *ndev;
struct netdev_hw_addr *ha; struct netdev_hw_addr *ha;
u32 cmd_value, cnt; u32 cmd_value, cnt;
@ -120,8 +152,6 @@ static void _brcmf_set_multicast_list(struct work_struct *work)
u32 buflen; u32 buflen;
s32 err; s32 err;
ifp = container_of(work, struct brcmf_if, multicast_work);
brcmf_dbg(TRACE, "Enter, bsscfgidx=%d\n", ifp->bsscfgidx); brcmf_dbg(TRACE, "Enter, bsscfgidx=%d\n", ifp->bsscfgidx);
ndev = ifp->ndev; ndev = ifp->ndev;
@ -151,7 +181,7 @@ static void _brcmf_set_multicast_list(struct work_struct *work)
err = brcmf_fil_iovar_data_set(ifp, "mcast_list", buf, buflen); err = brcmf_fil_iovar_data_set(ifp, "mcast_list", buf, buflen);
if (err < 0) { if (err < 0) {
brcmf_err("Setting mcast_list failed, %d\n", err); bphy_err(drvr, "Setting mcast_list failed, %d\n", err);
cmd_value = cnt ? true : cmd_value; cmd_value = cnt ? true : cmd_value;
} }
@ -164,13 +194,13 @@ static void _brcmf_set_multicast_list(struct work_struct *work)
*/ */
err = brcmf_fil_iovar_int_set(ifp, "allmulti", cmd_value); err = brcmf_fil_iovar_int_set(ifp, "allmulti", cmd_value);
if (err < 0) if (err < 0)
brcmf_err("Setting allmulti failed, %d\n", err); bphy_err(drvr, "Setting allmulti failed, %d\n", err);
/*Finally, pick up the PROMISC flag */ /*Finally, pick up the PROMISC flag */
cmd_value = (ndev->flags & IFF_PROMISC) ? true : false; cmd_value = (ndev->flags & IFF_PROMISC) ? true : false;
err = brcmf_fil_cmd_int_set(ifp, BRCMF_C_SET_PROMISC, cmd_value); err = brcmf_fil_cmd_int_set(ifp, BRCMF_C_SET_PROMISC, cmd_value);
if (err < 0) if (err < 0)
brcmf_err("Setting BRCMF_C_SET_PROMISC failed, %d\n", bphy_err(drvr, "Setting BRCMF_C_SET_PROMISC failed, %d\n",
err); err);
brcmf_configure_arp_nd_offload(ifp, !cmd_value); brcmf_configure_arp_nd_offload(ifp, !cmd_value);
} }
@ -178,11 +208,11 @@ static void _brcmf_set_multicast_list(struct work_struct *work)
#if IS_ENABLED(CONFIG_IPV6) #if IS_ENABLED(CONFIG_IPV6)
static void _brcmf_update_ndtable(struct work_struct *work) static void _brcmf_update_ndtable(struct work_struct *work)
{ {
struct brcmf_if *ifp; struct brcmf_if *ifp = container_of(work, struct brcmf_if,
ndoffload_work);
struct brcmf_pub *drvr = ifp->drvr;
int i, ret; int i, ret;
ifp = container_of(work, struct brcmf_if, ndoffload_work);
/* clear the table in firmware */ /* clear the table in firmware */
ret = brcmf_fil_iovar_data_set(ifp, "nd_hostip_clear", NULL, 0); ret = brcmf_fil_iovar_data_set(ifp, "nd_hostip_clear", NULL, 0);
if (ret) { if (ret) {
@ -195,7 +225,7 @@ static void _brcmf_update_ndtable(struct work_struct *work)
&ifp->ipv6_addr_tbl[i], &ifp->ipv6_addr_tbl[i],
sizeof(struct in6_addr)); sizeof(struct in6_addr));
if (ret) if (ret)
brcmf_err("add nd ip err %d\n", ret); bphy_err(drvr, "add nd ip err %d\n", ret);
} }
} }
#else #else
@ -208,6 +238,7 @@ static int brcmf_netdev_set_mac_address(struct net_device *ndev, void *addr)
{ {
struct brcmf_if *ifp = netdev_priv(ndev); struct brcmf_if *ifp = netdev_priv(ndev);
struct sockaddr *sa = (struct sockaddr *)addr; struct sockaddr *sa = (struct sockaddr *)addr;
struct brcmf_pub *drvr = ifp->drvr;
int err; int err;
brcmf_dbg(TRACE, "Enter, bsscfgidx=%d\n", ifp->bsscfgidx); brcmf_dbg(TRACE, "Enter, bsscfgidx=%d\n", ifp->bsscfgidx);
@ -215,7 +246,7 @@ static int brcmf_netdev_set_mac_address(struct net_device *ndev, void *addr)
err = brcmf_fil_iovar_data_set(ifp, "cur_etheraddr", sa->sa_data, err = brcmf_fil_iovar_data_set(ifp, "cur_etheraddr", sa->sa_data,
ETH_ALEN); ETH_ALEN);
if (err < 0) { if (err < 0) {
brcmf_err("Setting cur_etheraddr failed, %d\n", err); bphy_err(drvr, "Setting cur_etheraddr failed, %d\n", err);
} else { } else {
brcmf_dbg(TRACE, "updated to %pM\n", sa->sa_data); brcmf_dbg(TRACE, "updated to %pM\n", sa->sa_data);
memcpy(ifp->mac_addr, sa->sa_data, ETH_ALEN); memcpy(ifp->mac_addr, sa->sa_data, ETH_ALEN);
@ -275,7 +306,7 @@ static netdev_tx_t brcmf_netdev_start_xmit(struct sk_buff *skb,
/* Can the device send data? */ /* Can the device send data? */
if (drvr->bus_if->state != BRCMF_BUS_UP) { if (drvr->bus_if->state != BRCMF_BUS_UP) {
brcmf_err("xmit rejected state=%d\n", drvr->bus_if->state); bphy_err(drvr, "xmit rejected state=%d\n", drvr->bus_if->state);
netif_stop_queue(ndev); netif_stop_queue(ndev);
dev_kfree_skb(skb); dev_kfree_skb(skb);
ret = -ENODEV; ret = -ENODEV;
@ -309,7 +340,7 @@ static netdev_tx_t brcmf_netdev_start_xmit(struct sk_buff *skb,
ret = pskb_expand_head(skb, ALIGN(head_delta, NET_SKB_PAD), 0, ret = pskb_expand_head(skb, ALIGN(head_delta, NET_SKB_PAD), 0,
GFP_ATOMIC); GFP_ATOMIC);
if (ret < 0) { if (ret < 0) {
brcmf_err("%s: failed to expand headroom\n", bphy_err(drvr, "%s: failed to expand headroom\n",
brcmf_ifname(ifp)); brcmf_ifname(ifp));
atomic_inc(&drvr->bus_if->stats.pktcow_failed); atomic_inc(&drvr->bus_if->stats.pktcow_failed);
goto done; goto done;
@ -409,6 +440,31 @@ void brcmf_netif_mon_rx(struct brcmf_if *ifp, struct sk_buff *skb)
{ {
if (brcmf_feat_is_enabled(ifp, BRCMF_FEAT_MONITOR_FMT_RADIOTAP)) { if (brcmf_feat_is_enabled(ifp, BRCMF_FEAT_MONITOR_FMT_RADIOTAP)) {
/* Do nothing */ /* Do nothing */
} else if (brcmf_feat_is_enabled(ifp, BRCMF_FEAT_MONITOR_FMT_HW_RX_HDR)) {
struct wlc_d11rxhdr *wlc_rxhdr = (struct wlc_d11rxhdr *)skb->data;
struct ieee80211_radiotap_header *radiotap;
unsigned int offset;
u16 RxStatus1;
RxStatus1 = le16_to_cpu(wlc_rxhdr->rxhdr.RxStatus1);
offset = sizeof(struct wlc_d11rxhdr);
/* MAC inserts 2 pad bytes for a4 headers or QoS or A-MSDU
* subframes
*/
if (RxStatus1 & RXS_PBPRES)
offset += 2;
offset += D11_PHY_HDR_LEN;
skb_pull(skb, offset);
/* TODO: use RX header to fill some radiotap data */
radiotap = skb_push(skb, sizeof(*radiotap));
memset(radiotap, 0, sizeof(*radiotap));
radiotap->it_len = cpu_to_le16(sizeof(*radiotap));
/* TODO: 4 bytes with receive status? */
skb->len -= 4;
} else { } else {
struct ieee80211_radiotap_header *radiotap; struct ieee80211_radiotap_header *radiotap;
@ -464,7 +520,8 @@ void brcmf_rx_frame(struct device *dev, struct sk_buff *skb, bool handle_event)
} else { } else {
/* Process special event packets */ /* Process special event packets */
if (handle_event) if (handle_event)
brcmf_fweh_process_skb(ifp->drvr, skb); brcmf_fweh_process_skb(ifp->drvr, skb,
BCMILCP_SUBTYPE_VENDOR_LONG);
brcmf_netif_rx(ifp, skb); brcmf_netif_rx(ifp, skb);
} }
@ -481,7 +538,7 @@ void brcmf_rx_event(struct device *dev, struct sk_buff *skb)
if (brcmf_rx_hdrpull(drvr, skb, &ifp)) if (brcmf_rx_hdrpull(drvr, skb, &ifp))
return; return;
brcmf_fweh_process_skb(ifp->drvr, skb); brcmf_fweh_process_skb(ifp->drvr, skb, 0);
brcmu_pkt_buf_free_skb(skb); brcmu_pkt_buf_free_skb(skb);
} }
@ -551,7 +608,7 @@ static int brcmf_netdev_open(struct net_device *ndev)
/* If bus is not ready, can't continue */ /* If bus is not ready, can't continue */
if (bus_if->state != BRCMF_BUS_UP) { if (bus_if->state != BRCMF_BUS_UP) {
brcmf_err("failed bus is not ready\n"); bphy_err(drvr, "failed bus is not ready\n");
return -EAGAIN; return -EAGAIN;
} }
@ -565,7 +622,7 @@ static int brcmf_netdev_open(struct net_device *ndev)
ndev->features &= ~NETIF_F_IP_CSUM; ndev->features &= ~NETIF_F_IP_CSUM;
if (brcmf_cfg80211_up(ndev)) { if (brcmf_cfg80211_up(ndev)) {
brcmf_err("failed to bring up cfg80211\n"); bphy_err(drvr, "failed to bring up cfg80211\n");
return -EIO; return -EIO;
} }
@ -610,7 +667,7 @@ int brcmf_net_attach(struct brcmf_if *ifp, bool rtnl_locked)
else else
err = register_netdev(ndev); err = register_netdev(ndev);
if (err != 0) { if (err != 0) {
brcmf_err("couldn't register the net device\n"); bphy_err(drvr, "couldn't register the net device\n");
goto fail; goto fail;
} }
@ -687,6 +744,7 @@ static const struct net_device_ops brcmf_netdev_ops_p2p = {
static int brcmf_net_p2p_attach(struct brcmf_if *ifp) static int brcmf_net_p2p_attach(struct brcmf_if *ifp)
{ {
struct brcmf_pub *drvr = ifp->drvr;
struct net_device *ndev; struct net_device *ndev;
brcmf_dbg(TRACE, "Enter, bsscfgidx=%d mac=%pM\n", ifp->bsscfgidx, brcmf_dbg(TRACE, "Enter, bsscfgidx=%d mac=%pM\n", ifp->bsscfgidx,
@ -699,7 +757,7 @@ static int brcmf_net_p2p_attach(struct brcmf_if *ifp)
memcpy(ndev->dev_addr, ifp->mac_addr, ETH_ALEN); memcpy(ndev->dev_addr, ifp->mac_addr, ETH_ALEN);
if (register_netdev(ndev) != 0) { if (register_netdev(ndev) != 0) {
brcmf_err("couldn't register the p2p net device\n"); bphy_err(drvr, "couldn't register the p2p net device\n");
goto fail; goto fail;
} }
@ -728,7 +786,7 @@ struct brcmf_if *brcmf_add_if(struct brcmf_pub *drvr, s32 bsscfgidx, s32 ifidx,
*/ */
if (ifp) { if (ifp) {
if (ifidx) { if (ifidx) {
brcmf_err("ERROR: netdev:%s already exists\n", bphy_err(drvr, "ERROR: netdev:%s already exists\n",
ifp->ndev->name); ifp->ndev->name);
netif_stop_queue(ifp->ndev); netif_stop_queue(ifp->ndev);
brcmf_net_detach(ifp->ndev, false); brcmf_net_detach(ifp->ndev, false);
@ -787,7 +845,7 @@ static void brcmf_del_if(struct brcmf_pub *drvr, s32 bsscfgidx,
ifp = drvr->iflist[bsscfgidx]; ifp = drvr->iflist[bsscfgidx];
drvr->iflist[bsscfgidx] = NULL; drvr->iflist[bsscfgidx] = NULL;
if (!ifp) { if (!ifp) {
brcmf_err("Null interface, bsscfgidx=%d\n", bsscfgidx); bphy_err(drvr, "Null interface, bsscfgidx=%d\n", bsscfgidx);
return; return;
} }
brcmf_dbg(TRACE, "Enter, bsscfgidx=%d, ifidx=%d\n", bsscfgidx, brcmf_dbg(TRACE, "Enter, bsscfgidx=%d, ifidx=%d\n", bsscfgidx,
@ -837,16 +895,17 @@ static int brcmf_psm_watchdog_notify(struct brcmf_if *ifp,
const struct brcmf_event_msg *evtmsg, const struct brcmf_event_msg *evtmsg,
void *data) void *data)
{ {
struct brcmf_pub *drvr = ifp->drvr;
int err; int err;
brcmf_dbg(TRACE, "enter: bsscfgidx=%d\n", ifp->bsscfgidx); brcmf_dbg(TRACE, "enter: bsscfgidx=%d\n", ifp->bsscfgidx);
brcmf_err("PSM's watchdog has fired!\n"); bphy_err(drvr, "PSM's watchdog has fired!\n");
err = brcmf_debug_create_memdump(ifp->drvr->bus_if, data, err = brcmf_debug_create_memdump(ifp->drvr->bus_if, data,
evtmsg->datalen); evtmsg->datalen);
if (err) if (err)
brcmf_err("Failed to get memory dump, %d\n", err); bphy_err(drvr, "Failed to get memory dump, %d\n", err);
return err; return err;
} }
@ -890,7 +949,7 @@ static int brcmf_inetaddr_changed(struct notifier_block *nb,
ret = brcmf_fil_iovar_data_get(ifp, "arp_hostip", addr_table, ret = brcmf_fil_iovar_data_get(ifp, "arp_hostip", addr_table,
sizeof(addr_table)); sizeof(addr_table));
if (ret) { if (ret) {
brcmf_err("fail to get arp ip table err:%d\n", ret); bphy_err(drvr, "fail to get arp ip table err:%d\n", ret);
return NOTIFY_OK; return NOTIFY_OK;
} }
@ -907,7 +966,7 @@ static int brcmf_inetaddr_changed(struct notifier_block *nb,
ret = brcmf_fil_iovar_data_set(ifp, "arp_hostip", ret = brcmf_fil_iovar_data_set(ifp, "arp_hostip",
&ifa->ifa_address, sizeof(ifa->ifa_address)); &ifa->ifa_address, sizeof(ifa->ifa_address));
if (ret) if (ret)
brcmf_err("add arp ip err %d\n", ret); bphy_err(drvr, "add arp ip err %d\n", ret);
} }
break; break;
case NETDEV_DOWN: case NETDEV_DOWN:
@ -919,7 +978,7 @@ static int brcmf_inetaddr_changed(struct notifier_block *nb,
ret = brcmf_fil_iovar_data_set(ifp, "arp_hostip_clear", ret = brcmf_fil_iovar_data_set(ifp, "arp_hostip_clear",
NULL, 0); NULL, 0);
if (ret) { if (ret) {
brcmf_err("fail to clear arp ip table err:%d\n", bphy_err(drvr, "fail to clear arp ip table err:%d\n",
ret); ret);
return NOTIFY_OK; return NOTIFY_OK;
} }
@ -930,7 +989,7 @@ static int brcmf_inetaddr_changed(struct notifier_block *nb,
&addr_table[i], &addr_table[i],
sizeof(addr_table[i])); sizeof(addr_table[i]));
if (ret) if (ret)
brcmf_err("add arp ip err %d\n", bphy_err(drvr, "add arp ip err %d\n",
ret); ret);
} }
} }
@ -1100,11 +1159,12 @@ static int brcmf_bus_started(struct brcmf_pub *drvr, struct cfg80211_ops *ops)
brcmf_debugfs_add_entry(drvr, "revinfo", brcmf_revinfo_read); brcmf_debugfs_add_entry(drvr, "revinfo", brcmf_revinfo_read);
brcmf_feat_debugfs_create(drvr); brcmf_feat_debugfs_create(drvr);
brcmf_proto_debugfs_create(drvr); brcmf_proto_debugfs_create(drvr);
brcmf_bus_debugfs_create(bus_if);
return 0; return 0;
fail: fail:
brcmf_err("failed: %d\n", ret); bphy_err(drvr, "failed: %d\n", ret);
if (drvr->config) { if (drvr->config) {
brcmf_cfg80211_detach(drvr->config); brcmf_cfg80211_detach(drvr->config);
drvr->config = NULL; drvr->config = NULL;
@ -1156,7 +1216,7 @@ int brcmf_attach(struct device *dev, struct brcmf_mp_device *settings)
/* Attach and link in the protocol */ /* Attach and link in the protocol */
ret = brcmf_proto_attach(drvr); ret = brcmf_proto_attach(drvr);
if (ret != 0) { if (ret != 0) {
brcmf_err("brcmf_prot_attach failed\n"); bphy_err(drvr, "brcmf_prot_attach failed\n");
goto fail; goto fail;
} }
@ -1169,7 +1229,7 @@ int brcmf_attach(struct device *dev, struct brcmf_mp_device *settings)
ret = brcmf_bus_started(drvr, ops); ret = brcmf_bus_started(drvr, ops);
if (ret != 0) { if (ret != 0) {
brcmf_err("dongle is not responding: err=%d\n", ret); bphy_err(drvr, "dongle is not responding: err=%d\n", ret);
goto fail; goto fail;
} }
@ -1269,6 +1329,7 @@ static int brcmf_get_pend_8021x_cnt(struct brcmf_if *ifp)
int brcmf_netdev_wait_pend8021x(struct brcmf_if *ifp) int brcmf_netdev_wait_pend8021x(struct brcmf_if *ifp)
{ {
struct brcmf_pub *drvr = ifp->drvr;
int err; int err;
err = wait_event_timeout(ifp->pend_8021x_wait, err = wait_event_timeout(ifp->pend_8021x_wait,
@ -1276,7 +1337,7 @@ int brcmf_netdev_wait_pend8021x(struct brcmf_if *ifp)
MAX_WAIT_FOR_8021X_TX); MAX_WAIT_FOR_8021X_TX);
if (!err) if (!err)
brcmf_err("Timed out waiting for no pending 802.1x packets\n"); bphy_err(drvr, "Timed out waiting for no pending 802.1x packets\n");
return !err; return !err;
} }

View File

@ -36,7 +36,7 @@
#define BRCMF_DCMD_MEDLEN 1536 #define BRCMF_DCMD_MEDLEN 1536
#define BRCMF_DCMD_MAXLEN 8192 #define BRCMF_DCMD_MAXLEN 8192
/* IOCTL from host to device are limited in lenght. A device can only handle /* IOCTL from host to device are limited in length. A device can only handle
* ethernet frame size. This limitation is to be applied by protocol layer. * ethernet frame size. This limitation is to be applied by protocol layer.
*/ */
#define BRCMF_TX_IOCTL_MAX_MSG_SIZE (ETH_FRAME_LEN+ETH_FCS_LEN) #define BRCMF_TX_IOCTL_MAX_MSG_SIZE (ETH_FRAME_LEN+ETH_FCS_LEN)

View File

@ -45,17 +45,30 @@
#undef pr_fmt #undef pr_fmt
#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
__printf(2, 3) struct brcmf_bus;
void __brcmf_err(const char *func, const char *fmt, ...);
__printf(3, 4)
void __brcmf_err(struct brcmf_bus *bus, const char *func, const char *fmt, ...);
/* Macro for error messages. When debugging / tracing the driver all error /* Macro for error messages. When debugging / tracing the driver all error
* messages are important to us. * messages are important to us.
*/ */
#ifndef brcmf_err
#define brcmf_err(fmt, ...) \ #define brcmf_err(fmt, ...) \
do { \ do { \
if (IS_ENABLED(CONFIG_BRCMDBG) || \ if (IS_ENABLED(CONFIG_BRCMDBG) || \
IS_ENABLED(CONFIG_BRCM_TRACING) || \ IS_ENABLED(CONFIG_BRCM_TRACING) || \
net_ratelimit()) \ net_ratelimit()) \
__brcmf_err(__func__, fmt, ##__VA_ARGS__); \ __brcmf_err(NULL, __func__, fmt, ##__VA_ARGS__);\
} while (0)
#endif
#define bphy_err(drvr, fmt, ...) \
do { \
if (IS_ENABLED(CONFIG_BRCMDBG) || \
IS_ENABLED(CONFIG_BRCM_TRACING) || \
net_ratelimit()) \
wiphy_err((drvr)->wiphy, "%s: " fmt, __func__, \
##__VA_ARGS__); \
} while (0) } while (0)
#if defined(DEBUG) || defined(CONFIG_BRCM_TRACING) #if defined(DEBUG) || defined(CONFIG_BRCM_TRACING)

View File

@ -103,6 +103,10 @@ static const struct brcmf_feat_fwfeat brcmf_feat_fwfeat_map[] = {
{ "01-6cb8e269", BIT(BRCMF_FEAT_MONITOR) }, { "01-6cb8e269", BIT(BRCMF_FEAT_MONITOR) },
/* brcmfmac4366b-pcie.bin from linux-firmware.git commit 52442afee990 */ /* brcmfmac4366b-pcie.bin from linux-firmware.git commit 52442afee990 */
{ "01-c47a91a4", BIT(BRCMF_FEAT_MONITOR) }, { "01-c47a91a4", BIT(BRCMF_FEAT_MONITOR) },
/* brcmfmac4366b-pcie.bin from linux-firmware.git commit 211de1679a68 */
{ "01-801fb449", BIT(BRCMF_FEAT_MONITOR_FMT_HW_RX_HDR) },
/* brcmfmac4366c-pcie.bin from linux-firmware.git commit 211de1679a68 */
{ "01-d2cbb8fd", BIT(BRCMF_FEAT_MONITOR_FMT_HW_RX_HDR) },
}; };
static void brcmf_feat_firmware_overrides(struct brcmf_pub *drv) static void brcmf_feat_firmware_overrides(struct brcmf_pub *drv)
@ -181,13 +185,14 @@ static void brcmf_feat_iovar_data_set(struct brcmf_if *ifp,
#define MAX_CAPS_BUFFER_SIZE 768 #define MAX_CAPS_BUFFER_SIZE 768
static void brcmf_feat_firmware_capabilities(struct brcmf_if *ifp) static void brcmf_feat_firmware_capabilities(struct brcmf_if *ifp)
{ {
struct brcmf_pub *drvr = ifp->drvr;
char caps[MAX_CAPS_BUFFER_SIZE]; char caps[MAX_CAPS_BUFFER_SIZE];
enum brcmf_feat_id id; enum brcmf_feat_id id;
int i, err; int i, err;
err = brcmf_fil_iovar_data_get(ifp, "cap", caps, sizeof(caps)); err = brcmf_fil_iovar_data_get(ifp, "cap", caps, sizeof(caps));
if (err) { if (err) {
brcmf_err("could not get firmware cap (%d)\n", err); bphy_err(drvr, "could not get firmware cap (%d)\n", err);
return; return;
} }
@ -212,14 +217,15 @@ static void brcmf_feat_firmware_capabilities(struct brcmf_if *ifp)
static int brcmf_feat_fwcap_debugfs_read(struct seq_file *seq, void *data) static int brcmf_feat_fwcap_debugfs_read(struct seq_file *seq, void *data)
{ {
struct brcmf_bus *bus_if = dev_get_drvdata(seq->private); struct brcmf_bus *bus_if = dev_get_drvdata(seq->private);
struct brcmf_if *ifp = brcmf_get_ifp(bus_if->drvr, 0); struct brcmf_pub *drvr = bus_if->drvr;
struct brcmf_if *ifp = brcmf_get_ifp(drvr, 0);
char caps[MAX_CAPS_BUFFER_SIZE + 1] = { }; char caps[MAX_CAPS_BUFFER_SIZE + 1] = { };
char *tmp; char *tmp;
int err; int err;
err = brcmf_fil_iovar_data_get(ifp, "cap", caps, sizeof(caps)); err = brcmf_fil_iovar_data_get(ifp, "cap", caps, sizeof(caps));
if (err) { if (err) {
brcmf_err("could not get firmware cap (%d)\n", err); bphy_err(drvr, "could not get firmware cap (%d)\n", err);
return err; return err;
} }
@ -268,9 +274,15 @@ void brcmf_feat_attach(struct brcmf_pub *drvr)
BIT(BRCMF_FEAT_WOWL_GTK); BIT(BRCMF_FEAT_WOWL_GTK);
} }
} }
/* MBSS does not work for 43362 */ /* MBSS does not work for all chips */
if (drvr->bus_if->chip == BRCM_CC_43362_CHIP_ID) switch (drvr->bus_if->chip) {
case BRCM_CC_4330_CHIP_ID:
case BRCM_CC_43362_CHIP_ID:
ifp->drvr->feat_flags &= ~BIT(BRCMF_FEAT_MBSS); ifp->drvr->feat_flags &= ~BIT(BRCMF_FEAT_MBSS);
break;
default:
break;
}
brcmf_feat_iovar_int_get(ifp, BRCMF_FEAT_RSDB, "rsdb_mode"); brcmf_feat_iovar_int_get(ifp, BRCMF_FEAT_RSDB, "rsdb_mode");
brcmf_feat_iovar_int_get(ifp, BRCMF_FEAT_TDLS, "tdls_enable"); brcmf_feat_iovar_int_get(ifp, BRCMF_FEAT_TDLS, "tdls_enable");
brcmf_feat_iovar_int_get(ifp, BRCMF_FEAT_MFP, "mfp"); brcmf_feat_iovar_int_get(ifp, BRCMF_FEAT_MFP, "mfp");

View File

@ -35,6 +35,7 @@
* FWSUP: Firmware supplicant. * FWSUP: Firmware supplicant.
* MONITOR: firmware can pass monitor packets to host. * MONITOR: firmware can pass monitor packets to host.
* MONITOR_FMT_RADIOTAP: firmware provides monitor packets with radiotap header * MONITOR_FMT_RADIOTAP: firmware provides monitor packets with radiotap header
* MONITOR_FMT_HW_RX_HDR: firmware provides monitor packets with hw/ucode header
*/ */
#define BRCMF_FEAT_LIST \ #define BRCMF_FEAT_LIST \
BRCMF_FEAT_DEF(MBSS) \ BRCMF_FEAT_DEF(MBSS) \
@ -52,7 +53,8 @@
BRCMF_FEAT_DEF(GSCAN) \ BRCMF_FEAT_DEF(GSCAN) \
BRCMF_FEAT_DEF(FWSUP) \ BRCMF_FEAT_DEF(FWSUP) \
BRCMF_FEAT_DEF(MONITOR) \ BRCMF_FEAT_DEF(MONITOR) \
BRCMF_FEAT_DEF(MONITOR_FMT_RADIOTAP) BRCMF_FEAT_DEF(MONITOR_FMT_RADIOTAP) \
BRCMF_FEAT_DEF(MONITOR_FMT_HW_RX_HDR)
/* /*
* Quirks: * Quirks:

View File

@ -47,7 +47,7 @@ enum nvram_parser_state {
* @state: current parser state. * @state: current parser state.
* @data: input buffer being parsed. * @data: input buffer being parsed.
* @nvram: output buffer with parse result. * @nvram: output buffer with parse result.
* @nvram_len: lenght of parse result. * @nvram_len: length of parse result.
* @line: current line. * @line: current line.
* @column: current column in line. * @column: current column in line.
* @pos: byte offset in input buffer. * @pos: byte offset in input buffer.
@ -719,8 +719,10 @@ brcmf_fw_alloc_request(u32 chip, u32 chiprev,
break; break;
} }
brcmf_chip_name(chip, chiprev, chipname, sizeof(chipname));
if (i == table_size) { if (i == table_size) {
brcmf_err("Unknown chipid %d [%d]\n", chip, chiprev); brcmf_err("Unknown chip %s\n", chipname);
return NULL; return NULL;
} }
@ -729,8 +731,6 @@ brcmf_fw_alloc_request(u32 chip, u32 chiprev,
if (!fwreq) if (!fwreq)
return NULL; return NULL;
brcmf_chip_name(chip, chiprev, chipname, sizeof(chipname));
brcmf_info("using %s for chip %s\n", brcmf_info("using %s for chip %s\n",
mapping_table[i].fw_base, chipname); mapping_table[i].fw_base, chipname);

View File

@ -102,7 +102,8 @@ static void brcmf_fweh_queue_event(struct brcmf_fweh_info *fweh,
schedule_work(&fweh->event_work); schedule_work(&fweh->event_work);
} }
static int brcmf_fweh_call_event_handler(struct brcmf_if *ifp, static int brcmf_fweh_call_event_handler(struct brcmf_pub *drvr,
struct brcmf_if *ifp,
enum brcmf_fweh_event_code code, enum brcmf_fweh_event_code code,
struct brcmf_event_msg *emsg, struct brcmf_event_msg *emsg,
void *data) void *data)
@ -117,9 +118,9 @@ static int brcmf_fweh_call_event_handler(struct brcmf_if *ifp,
if (fweh->evt_handler[code]) if (fweh->evt_handler[code])
err = fweh->evt_handler[code](ifp, emsg, data); err = fweh->evt_handler[code](ifp, emsg, data);
else else
brcmf_err("unhandled event %d ignored\n", code); bphy_err(drvr, "unhandled event %d ignored\n", code);
} else { } else {
brcmf_err("no interface object\n"); bphy_err(drvr, "no interface object\n");
} }
return err; return err;
} }
@ -158,7 +159,7 @@ static void brcmf_fweh_handle_if_event(struct brcmf_pub *drvr,
return; return;
} }
if (ifevent->ifidx >= BRCMF_MAX_IFS) { if (ifevent->ifidx >= BRCMF_MAX_IFS) {
brcmf_err("invalid interface index: %u\n", ifevent->ifidx); bphy_err(drvr, "invalid interface index: %u\n", ifevent->ifidx);
return; return;
} }
@ -181,7 +182,8 @@ static void brcmf_fweh_handle_if_event(struct brcmf_pub *drvr,
if (ifp && ifevent->action == BRCMF_E_IF_CHANGE) if (ifp && ifevent->action == BRCMF_E_IF_CHANGE)
brcmf_proto_reset_if(drvr, ifp); brcmf_proto_reset_if(drvr, ifp);
err = brcmf_fweh_call_event_handler(ifp, emsg->event_code, emsg, data); err = brcmf_fweh_call_event_handler(drvr, ifp, emsg->event_code, emsg,
data);
if (ifp && ifevent->action == BRCMF_E_IF_DEL) { if (ifp && ifevent->action == BRCMF_E_IF_DEL) {
bool armed = brcmf_cfg80211_vif_event_armed(drvr->config); bool armed = brcmf_cfg80211_vif_event_armed(drvr->config);
@ -268,10 +270,10 @@ static void brcmf_fweh_event_worker(struct work_struct *work)
ifp = drvr->iflist[0]; ifp = drvr->iflist[0];
else else
ifp = drvr->iflist[emsg.bsscfgidx]; ifp = drvr->iflist[emsg.bsscfgidx];
err = brcmf_fweh_call_event_handler(ifp, event->code, &emsg, err = brcmf_fweh_call_event_handler(drvr, ifp, event->code,
event->data); &emsg, event->data);
if (err) { if (err) {
brcmf_err("event handler failed (%d)\n", bphy_err(drvr, "event handler failed (%d)\n",
event->code); event->code);
err = 0; err = 0;
} }
@ -339,7 +341,7 @@ int brcmf_fweh_register(struct brcmf_pub *drvr, enum brcmf_fweh_event_code code,
brcmf_fweh_handler_t handler) brcmf_fweh_handler_t handler)
{ {
if (drvr->fweh.evt_handler[code]) { if (drvr->fweh.evt_handler[code]) {
brcmf_err("event code %d already registered\n", code); bphy_err(drvr, "event code %d already registered\n", code);
return -ENOSPC; return -ENOSPC;
} }
drvr->fweh.evt_handler[code] = handler; drvr->fweh.evt_handler[code] = handler;
@ -369,6 +371,7 @@ void brcmf_fweh_unregister(struct brcmf_pub *drvr,
*/ */
int brcmf_fweh_activate_events(struct brcmf_if *ifp) int brcmf_fweh_activate_events(struct brcmf_if *ifp)
{ {
struct brcmf_pub *drvr = ifp->drvr;
int i, err; int i, err;
s8 eventmask[BRCMF_EVENTING_MASK_LEN]; s8 eventmask[BRCMF_EVENTING_MASK_LEN];
@ -388,7 +391,7 @@ int brcmf_fweh_activate_events(struct brcmf_if *ifp)
err = brcmf_fil_iovar_data_set(ifp, "event_msgs", err = brcmf_fil_iovar_data_set(ifp, "event_msgs",
eventmask, BRCMF_EVENTING_MASK_LEN); eventmask, BRCMF_EVENTING_MASK_LEN);
if (err) if (err)
brcmf_err("Set event_msgs error (%d)\n", err); bphy_err(drvr, "Set event_msgs error (%d)\n", err);
return err; return err;
} }

View File

@ -211,7 +211,7 @@ enum brcmf_fweh_event_code {
*/ */
#define BRCM_OUI "\x00\x10\x18" #define BRCM_OUI "\x00\x10\x18"
#define BCMILCP_BCM_SUBTYPE_EVENT 1 #define BCMILCP_BCM_SUBTYPE_EVENT 1
#define BCMILCP_SUBTYPE_VENDOR_LONG 32769
/** /**
* struct brcm_ethhdr - broadcom specific ether header. * struct brcm_ethhdr - broadcom specific ether header.
@ -266,7 +266,7 @@ struct brcmf_event {
* @status: status information. * @status: status information.
* @reason: reason code. * @reason: reason code.
* @auth_type: authentication type. * @auth_type: authentication type.
* @datalen: lenght of event data buffer. * @datalen: length of event data buffer.
* @addr: ether address. * @addr: ether address.
* @ifname: interface name. * @ifname: interface name.
* @ifidx: interface index. * @ifidx: interface index.
@ -334,10 +334,10 @@ void brcmf_fweh_process_event(struct brcmf_pub *drvr,
void brcmf_fweh_p2pdev_setup(struct brcmf_if *ifp, bool ongoing); void brcmf_fweh_p2pdev_setup(struct brcmf_if *ifp, bool ongoing);
static inline void brcmf_fweh_process_skb(struct brcmf_pub *drvr, static inline void brcmf_fweh_process_skb(struct brcmf_pub *drvr,
struct sk_buff *skb) struct sk_buff *skb, u16 stype)
{ {
struct brcmf_event *event_packet; struct brcmf_event *event_packet;
u16 usr_stype; u16 subtype, usr_stype;
/* only process events when protocol matches */ /* only process events when protocol matches */
if (skb->protocol != cpu_to_be16(ETH_P_LINK_CTL)) if (skb->protocol != cpu_to_be16(ETH_P_LINK_CTL))
@ -346,8 +346,16 @@ static inline void brcmf_fweh_process_skb(struct brcmf_pub *drvr,
if ((skb->len + ETH_HLEN) < sizeof(*event_packet)) if ((skb->len + ETH_HLEN) < sizeof(*event_packet))
return; return;
/* check for BRCM oui match */
event_packet = (struct brcmf_event *)skb_mac_header(skb); event_packet = (struct brcmf_event *)skb_mac_header(skb);
/* check subtype if needed */
if (unlikely(stype)) {
subtype = get_unaligned_be16(&event_packet->hdr.subtype);
if (subtype != stype)
return;
}
/* check for BRCM oui match */
if (memcmp(BRCM_OUI, &event_packet->hdr.oui[0], if (memcmp(BRCM_OUI, &event_packet->hdr.oui[0],
sizeof(event_packet->hdr.oui))) sizeof(event_packet->hdr.oui)))
return; return;

View File

@ -110,7 +110,7 @@ brcmf_fil_cmd_data(struct brcmf_if *ifp, u32 cmd, void *data, u32 len, bool set)
s32 err, fwerr; s32 err, fwerr;
if (drvr->bus_if->state != BRCMF_BUS_UP) { if (drvr->bus_if->state != BRCMF_BUS_UP) {
brcmf_err("bus is down. we have nothing to do.\n"); bphy_err(drvr, "bus is down. we have nothing to do.\n");
return -EIO; return -EIO;
} }
@ -242,7 +242,7 @@ brcmf_fil_iovar_data_set(struct brcmf_if *ifp, char *name, const void *data,
buflen, true); buflen, true);
} else { } else {
err = -EPERM; err = -EPERM;
brcmf_err("Creating iovar failed\n"); bphy_err(drvr, "Creating iovar failed\n");
} }
mutex_unlock(&drvr->proto_block); mutex_unlock(&drvr->proto_block);
@ -268,7 +268,7 @@ brcmf_fil_iovar_data_get(struct brcmf_if *ifp, char *name, void *data,
memcpy(data, drvr->proto_buf, len); memcpy(data, drvr->proto_buf, len);
} else { } else {
err = -EPERM; err = -EPERM;
brcmf_err("Creating iovar failed\n"); bphy_err(drvr, "Creating iovar failed\n");
} }
brcmf_dbg(FIL, "ifidx=%d, name=%s, len=%d\n", ifp->ifidx, name, len); brcmf_dbg(FIL, "ifidx=%d, name=%s, len=%d\n", ifp->ifidx, name, len);
@ -366,7 +366,7 @@ brcmf_fil_bsscfg_data_set(struct brcmf_if *ifp, char *name,
buflen, true); buflen, true);
} else { } else {
err = -EPERM; err = -EPERM;
brcmf_err("Creating bsscfg failed\n"); bphy_err(drvr, "Creating bsscfg failed\n");
} }
mutex_unlock(&drvr->proto_block); mutex_unlock(&drvr->proto_block);
@ -392,7 +392,7 @@ brcmf_fil_bsscfg_data_get(struct brcmf_if *ifp, char *name,
memcpy(data, drvr->proto_buf, len); memcpy(data, drvr->proto_buf, len);
} else { } else {
err = -EPERM; err = -EPERM;
brcmf_err("Creating bsscfg failed\n"); bphy_err(drvr, "Creating bsscfg failed\n");
} }
brcmf_dbg(FIL, "ifidx=%d, bsscfgidx=%d, name=%s, len=%d\n", ifp->ifidx, brcmf_dbg(FIL, "ifidx=%d, bsscfgidx=%d, name=%s, len=%d\n", ifp->ifidx,
ifp->bsscfgidx, name, len); ifp->bsscfgidx, name, len);

View File

@ -1255,6 +1255,7 @@ static int brcmf_fws_enq(struct brcmf_fws_info *fws,
enum brcmf_fws_skb_state state, int fifo, enum brcmf_fws_skb_state state, int fifo,
struct sk_buff *p) struct sk_buff *p)
{ {
struct brcmf_pub *drvr = fws->drvr;
int prec = 2 * fifo; int prec = 2 * fifo;
u32 *qfull_stat = &fws->stats.delayq_full_error; u32 *qfull_stat = &fws->stats.delayq_full_error;
struct brcmf_fws_mac_descriptor *entry; struct brcmf_fws_mac_descriptor *entry;
@ -1267,7 +1268,7 @@ static int brcmf_fws_enq(struct brcmf_fws_info *fws,
entry = brcmf_skbcb(p)->mac; entry = brcmf_skbcb(p)->mac;
if (entry == NULL) { if (entry == NULL) {
brcmf_err("no mac descriptor found for skb %p\n", p); bphy_err(drvr, "no mac descriptor found for skb %p\n", p);
return -ENOENT; return -ENOENT;
} }
@ -1457,6 +1458,7 @@ static int
brcmf_fws_txs_process(struct brcmf_fws_info *fws, u8 flags, u32 hslot, brcmf_fws_txs_process(struct brcmf_fws_info *fws, u8 flags, u32 hslot,
u32 genbit, u16 seq, u8 compcnt) u32 genbit, u16 seq, u8 compcnt)
{ {
struct brcmf_pub *drvr = fws->drvr;
u32 fifo; u32 fifo;
u8 cnt = 0; u8 cnt = 0;
int ret; int ret;
@ -1481,13 +1483,13 @@ brcmf_fws_txs_process(struct brcmf_fws_info *fws, u8 flags, u32 hslot,
else if (flags == BRCMF_FWS_TXSTATUS_HOST_TOSSED) else if (flags == BRCMF_FWS_TXSTATUS_HOST_TOSSED)
fws->stats.txs_host_tossed += compcnt; fws->stats.txs_host_tossed += compcnt;
else else
brcmf_err("unexpected txstatus\n"); bphy_err(drvr, "unexpected txstatus\n");
while (cnt < compcnt) { while (cnt < compcnt) {
ret = brcmf_fws_hanger_poppkt(&fws->hanger, hslot, &skb, ret = brcmf_fws_hanger_poppkt(&fws->hanger, hslot, &skb,
remove_from_hanger); remove_from_hanger);
if (ret != 0) { if (ret != 0) {
brcmf_err("no packet in hanger slot: hslot=%d\n", bphy_err(drvr, "no packet in hanger slot: hslot=%d\n",
hslot); hslot);
goto cont; goto cont;
} }
@ -1612,12 +1614,13 @@ static int brcmf_fws_notify_credit_map(struct brcmf_if *ifp,
const struct brcmf_event_msg *e, const struct brcmf_event_msg *e,
void *data) void *data)
{ {
struct brcmf_fws_info *fws = drvr_to_fws(ifp->drvr); struct brcmf_pub *drvr = ifp->drvr;
struct brcmf_fws_info *fws = drvr_to_fws(drvr);
int i; int i;
u8 *credits = data; u8 *credits = data;
if (e->datalen < BRCMF_FWS_FIFO_COUNT) { if (e->datalen < BRCMF_FWS_FIFO_COUNT) {
brcmf_err("event payload too small (%d)\n", e->datalen); bphy_err(drvr, "event payload too small (%d)\n", e->datalen);
return -EINVAL; return -EINVAL;
} }
@ -1681,6 +1684,7 @@ static void brcmf_rxreorder_get_skb_list(struct brcmf_ampdu_rx_reorder *rfi,
void brcmf_fws_rxreorder(struct brcmf_if *ifp, struct sk_buff *pkt) void brcmf_fws_rxreorder(struct brcmf_if *ifp, struct sk_buff *pkt)
{ {
struct brcmf_pub *drvr = ifp->drvr;
u8 *reorder_data; u8 *reorder_data;
u8 flow_id, max_idx, cur_idx, exp_idx, end_idx; u8 flow_id, max_idx, cur_idx, exp_idx, end_idx;
struct brcmf_ampdu_rx_reorder *rfi; struct brcmf_ampdu_rx_reorder *rfi;
@ -1695,7 +1699,7 @@ void brcmf_fws_rxreorder(struct brcmf_if *ifp, struct sk_buff *pkt)
/* validate flags and flow id */ /* validate flags and flow id */
if (flags == 0xFF) { if (flags == 0xFF) {
brcmf_err("invalid flags...so ignore this packet\n"); bphy_err(drvr, "invalid flags...so ignore this packet\n");
brcmf_netif_rx(ifp, pkt); brcmf_netif_rx(ifp, pkt);
return; return;
} }
@ -1732,7 +1736,7 @@ void brcmf_fws_rxreorder(struct brcmf_if *ifp, struct sk_buff *pkt)
flow_id, max_idx); flow_id, max_idx);
rfi = kzalloc(buf_size, GFP_ATOMIC); rfi = kzalloc(buf_size, GFP_ATOMIC);
if (rfi == NULL) { if (rfi == NULL) {
brcmf_err("failed to alloc buffer\n"); bphy_err(drvr, "failed to alloc buffer\n");
brcmf_netif_rx(ifp, pkt); brcmf_netif_rx(ifp, pkt);
return; return;
} }
@ -1996,6 +2000,7 @@ static u8 brcmf_fws_precommit_skb(struct brcmf_fws_info *fws, int fifo,
static void brcmf_fws_rollback_toq(struct brcmf_fws_info *fws, static void brcmf_fws_rollback_toq(struct brcmf_fws_info *fws,
struct sk_buff *skb, int fifo) struct sk_buff *skb, int fifo)
{ {
struct brcmf_pub *drvr = fws->drvr;
struct brcmf_fws_mac_descriptor *entry; struct brcmf_fws_mac_descriptor *entry;
struct sk_buff *pktout; struct sk_buff *pktout;
int qidx, hslot; int qidx, hslot;
@ -2009,11 +2014,11 @@ static void brcmf_fws_rollback_toq(struct brcmf_fws_info *fws,
pktout = brcmu_pktq_penq_head(&entry->psq, qidx, skb); pktout = brcmu_pktq_penq_head(&entry->psq, qidx, skb);
if (pktout == NULL) { if (pktout == NULL) {
brcmf_err("%s queue %d full\n", entry->name, qidx); bphy_err(drvr, "%s queue %d full\n", entry->name, qidx);
rc = -ENOSPC; rc = -ENOSPC;
} }
} else { } else {
brcmf_err("%s entry removed\n", entry->name); bphy_err(drvr, "%s entry removed\n", entry->name);
rc = -ENOENT; rc = -ENOENT;
} }
@ -2118,7 +2123,8 @@ static int brcmf_fws_assign_htod(struct brcmf_fws_info *fws, struct sk_buff *p,
int brcmf_fws_process_skb(struct brcmf_if *ifp, struct sk_buff *skb) int brcmf_fws_process_skb(struct brcmf_if *ifp, struct sk_buff *skb)
{ {
struct brcmf_fws_info *fws = drvr_to_fws(ifp->drvr); struct brcmf_pub *drvr = ifp->drvr;
struct brcmf_fws_info *fws = drvr_to_fws(drvr);
struct brcmf_skbuff_cb *skcb = brcmf_skbcb(skb); struct brcmf_skbuff_cb *skcb = brcmf_skbcb(skb);
struct ethhdr *eh = (struct ethhdr *)(skb->data); struct ethhdr *eh = (struct ethhdr *)(skb->data);
int fifo = BRCMF_FWS_FIFO_BCMC; int fifo = BRCMF_FWS_FIFO_BCMC;
@ -2146,7 +2152,7 @@ int brcmf_fws_process_skb(struct brcmf_if *ifp, struct sk_buff *skb)
brcmf_fws_enq(fws, BRCMF_FWS_SKBSTATE_DELAYED, fifo, skb); brcmf_fws_enq(fws, BRCMF_FWS_SKBSTATE_DELAYED, fifo, skb);
brcmf_fws_schedule_deq(fws); brcmf_fws_schedule_deq(fws);
} else { } else {
brcmf_err("drop skb: no hanger slot\n"); bphy_err(drvr, "drop skb: no hanger slot\n");
brcmf_txfinalize(ifp, skb, false); brcmf_txfinalize(ifp, skb, false);
rc = -ENOMEM; rc = -ENOMEM;
} }
@ -2365,7 +2371,7 @@ struct brcmf_fws_info *brcmf_fws_attach(struct brcmf_pub *drvr)
fws->fws_wq = create_singlethread_workqueue("brcmf_fws_wq"); fws->fws_wq = create_singlethread_workqueue("brcmf_fws_wq");
if (fws->fws_wq == NULL) { if (fws->fws_wq == NULL) {
brcmf_err("workqueue creation failed\n"); bphy_err(drvr, "workqueue creation failed\n");
rc = -EBADF; rc = -EBADF;
goto fail; goto fail;
} }
@ -2381,13 +2387,13 @@ struct brcmf_fws_info *brcmf_fws_attach(struct brcmf_pub *drvr)
rc = brcmf_fweh_register(drvr, BRCMF_E_FIFO_CREDIT_MAP, rc = brcmf_fweh_register(drvr, BRCMF_E_FIFO_CREDIT_MAP,
brcmf_fws_notify_credit_map); brcmf_fws_notify_credit_map);
if (rc < 0) { if (rc < 0) {
brcmf_err("register credit map handler failed\n"); bphy_err(drvr, "register credit map handler failed\n");
goto fail; goto fail;
} }
rc = brcmf_fweh_register(drvr, BRCMF_E_BCMC_CREDIT_SUPPORT, rc = brcmf_fweh_register(drvr, BRCMF_E_BCMC_CREDIT_SUPPORT,
brcmf_fws_notify_bcmc_credit_support); brcmf_fws_notify_bcmc_credit_support);
if (rc < 0) { if (rc < 0) {
brcmf_err("register bcmc credit handler failed\n"); bphy_err(drvr, "register bcmc credit handler failed\n");
brcmf_fweh_unregister(drvr, BRCMF_E_FIFO_CREDIT_MAP); brcmf_fweh_unregister(drvr, BRCMF_E_FIFO_CREDIT_MAP);
goto fail; goto fail;
} }
@ -2399,7 +2405,7 @@ struct brcmf_fws_info *brcmf_fws_attach(struct brcmf_pub *drvr)
fws->fw_signals = true; fws->fw_signals = true;
ifp = brcmf_get_ifp(drvr, 0); ifp = brcmf_get_ifp(drvr, 0);
if (brcmf_fil_iovar_int_set(ifp, "tlv", tlv)) { if (brcmf_fil_iovar_int_set(ifp, "tlv", tlv)) {
brcmf_err("failed to set bdcv2 tlv signaling\n"); bphy_err(drvr, "failed to set bdcv2 tlv signaling\n");
fws->fcmode = BRCMF_FWS_FCMODE_NONE; fws->fcmode = BRCMF_FWS_FCMODE_NONE;
fws->fw_signals = false; fws->fw_signals = false;
} }

View File

@ -134,6 +134,14 @@ struct msgbuf_completion_hdr {
__le16 flow_ring_id; __le16 flow_ring_id;
}; };
/* Data struct for the MSGBUF_TYPE_RING_STATUS */
struct msgbuf_ring_status {
struct msgbuf_common_hdr msg;
struct msgbuf_completion_hdr compl_hdr;
__le16 write_idx;
__le32 rsvd0[5];
};
struct msgbuf_rx_event { struct msgbuf_rx_event {
struct msgbuf_common_hdr msg; struct msgbuf_common_hdr msg;
struct msgbuf_completion_hdr compl_hdr; struct msgbuf_completion_hdr compl_hdr;
@ -431,7 +439,7 @@ static int brcmf_msgbuf_tx_ioctl(struct brcmf_pub *drvr, int ifidx,
brcmf_commonring_lock(commonring); brcmf_commonring_lock(commonring);
ret_ptr = brcmf_commonring_reserve_for_write(commonring); ret_ptr = brcmf_commonring_reserve_for_write(commonring);
if (!ret_ptr) { if (!ret_ptr) {
brcmf_err("Failed to reserve space in commonring\n"); bphy_err(drvr, "Failed to reserve space in commonring\n");
brcmf_commonring_unlock(commonring); brcmf_commonring_unlock(commonring);
return -ENOMEM; return -ENOMEM;
} }
@ -495,7 +503,7 @@ static int brcmf_msgbuf_query_dcmd(struct brcmf_pub *drvr, int ifidx,
timeout = brcmf_msgbuf_ioctl_resp_wait(msgbuf); timeout = brcmf_msgbuf_ioctl_resp_wait(msgbuf);
if (!timeout) { if (!timeout) {
brcmf_err("Timeout on response for query command\n"); bphy_err(drvr, "Timeout on response for query command\n");
return -EIO; return -EIO;
} }
@ -572,6 +580,7 @@ static u32
brcmf_msgbuf_flowring_create_worker(struct brcmf_msgbuf *msgbuf, brcmf_msgbuf_flowring_create_worker(struct brcmf_msgbuf *msgbuf,
struct brcmf_msgbuf_work_item *work) struct brcmf_msgbuf_work_item *work)
{ {
struct brcmf_pub *drvr = msgbuf->drvr;
struct msgbuf_tx_flowring_create_req *create; struct msgbuf_tx_flowring_create_req *create;
struct brcmf_commonring *commonring; struct brcmf_commonring *commonring;
void *ret_ptr; void *ret_ptr;
@ -587,7 +596,7 @@ brcmf_msgbuf_flowring_create_worker(struct brcmf_msgbuf *msgbuf,
&msgbuf->flowring_dma_handle[flowid], &msgbuf->flowring_dma_handle[flowid],
GFP_KERNEL); GFP_KERNEL);
if (!dma_buf) { if (!dma_buf) {
brcmf_err("dma_alloc_coherent failed\n"); bphy_err(drvr, "dma_alloc_coherent failed\n");
brcmf_flowring_delete(msgbuf->flow, flowid); brcmf_flowring_delete(msgbuf->flow, flowid);
return BRCMF_FLOWRING_INVALID_ID; return BRCMF_FLOWRING_INVALID_ID;
} }
@ -600,7 +609,7 @@ brcmf_msgbuf_flowring_create_worker(struct brcmf_msgbuf *msgbuf,
brcmf_commonring_lock(commonring); brcmf_commonring_lock(commonring);
ret_ptr = brcmf_commonring_reserve_for_write(commonring); ret_ptr = brcmf_commonring_reserve_for_write(commonring);
if (!ret_ptr) { if (!ret_ptr) {
brcmf_err("Failed to reserve space in commonring\n"); bphy_err(drvr, "Failed to reserve space in commonring\n");
brcmf_commonring_unlock(commonring); brcmf_commonring_unlock(commonring);
brcmf_msgbuf_remove_flowring(msgbuf, flowid); brcmf_msgbuf_remove_flowring(msgbuf, flowid);
return BRCMF_FLOWRING_INVALID_ID; return BRCMF_FLOWRING_INVALID_ID;
@ -627,7 +636,7 @@ brcmf_msgbuf_flowring_create_worker(struct brcmf_msgbuf *msgbuf,
err = brcmf_commonring_write_complete(commonring); err = brcmf_commonring_write_complete(commonring);
brcmf_commonring_unlock(commonring); brcmf_commonring_unlock(commonring);
if (err) { if (err) {
brcmf_err("Failed to write commonring\n"); bphy_err(drvr, "Failed to write commonring\n");
brcmf_msgbuf_remove_flowring(msgbuf, flowid); brcmf_msgbuf_remove_flowring(msgbuf, flowid);
return BRCMF_FLOWRING_INVALID_ID; return BRCMF_FLOWRING_INVALID_ID;
} }
@ -686,6 +695,7 @@ static u32 brcmf_msgbuf_flowring_create(struct brcmf_msgbuf *msgbuf, int ifidx,
static void brcmf_msgbuf_txflow(struct brcmf_msgbuf *msgbuf, u16 flowid) static void brcmf_msgbuf_txflow(struct brcmf_msgbuf *msgbuf, u16 flowid)
{ {
struct brcmf_flowring *flow = msgbuf->flow; struct brcmf_flowring *flow = msgbuf->flow;
struct brcmf_pub *drvr = msgbuf->drvr;
struct brcmf_commonring *commonring; struct brcmf_commonring *commonring;
void *ret_ptr; void *ret_ptr;
u32 count; u32 count;
@ -705,7 +715,7 @@ static void brcmf_msgbuf_txflow(struct brcmf_msgbuf *msgbuf, u16 flowid)
while (brcmf_flowring_qlen(flow, flowid)) { while (brcmf_flowring_qlen(flow, flowid)) {
skb = brcmf_flowring_dequeue(flow, flowid); skb = brcmf_flowring_dequeue(flow, flowid);
if (skb == NULL) { if (skb == NULL) {
brcmf_err("No SKB, but qlen %d\n", bphy_err(drvr, "No SKB, but qlen %d\n",
brcmf_flowring_qlen(flow, flowid)); brcmf_flowring_qlen(flow, flowid));
break; break;
} }
@ -714,7 +724,7 @@ static void brcmf_msgbuf_txflow(struct brcmf_msgbuf *msgbuf, u16 flowid)
msgbuf->tx_pktids, skb, ETH_HLEN, msgbuf->tx_pktids, skb, ETH_HLEN,
&physaddr, &pktid)) { &physaddr, &pktid)) {
brcmf_flowring_reinsert(flow, flowid, skb); brcmf_flowring_reinsert(flow, flowid, skb);
brcmf_err("No PKTID available !!\n"); bphy_err(drvr, "No PKTID available !!\n");
break; break;
} }
ret_ptr = brcmf_commonring_reserve_for_write(commonring); ret_ptr = brcmf_commonring_reserve_for_write(commonring);
@ -885,6 +895,7 @@ brcmf_msgbuf_process_txstatus(struct brcmf_msgbuf *msgbuf, void *buf)
static u32 brcmf_msgbuf_rxbuf_data_post(struct brcmf_msgbuf *msgbuf, u32 count) static u32 brcmf_msgbuf_rxbuf_data_post(struct brcmf_msgbuf *msgbuf, u32 count)
{ {
struct brcmf_pub *drvr = msgbuf->drvr;
struct brcmf_commonring *commonring; struct brcmf_commonring *commonring;
void *ret_ptr; void *ret_ptr;
struct sk_buff *skb; struct sk_buff *skb;
@ -912,7 +923,7 @@ static u32 brcmf_msgbuf_rxbuf_data_post(struct brcmf_msgbuf *msgbuf, u32 count)
skb = brcmu_pkt_buf_get_skb(BRCMF_MSGBUF_MAX_PKT_SIZE); skb = brcmu_pkt_buf_get_skb(BRCMF_MSGBUF_MAX_PKT_SIZE);
if (skb == NULL) { if (skb == NULL) {
brcmf_err("Failed to alloc SKB\n"); bphy_err(drvr, "Failed to alloc SKB\n");
brcmf_commonring_write_cancel(commonring, alloced - i); brcmf_commonring_write_cancel(commonring, alloced - i);
break; break;
} }
@ -922,7 +933,7 @@ static u32 brcmf_msgbuf_rxbuf_data_post(struct brcmf_msgbuf *msgbuf, u32 count)
msgbuf->rx_pktids, skb, 0, msgbuf->rx_pktids, skb, 0,
&physaddr, &pktid)) { &physaddr, &pktid)) {
dev_kfree_skb_any(skb); dev_kfree_skb_any(skb);
brcmf_err("No PKTID available !!\n"); bphy_err(drvr, "No PKTID available !!\n");
brcmf_commonring_write_cancel(commonring, alloced - i); brcmf_commonring_write_cancel(commonring, alloced - i);
break; break;
} }
@ -992,6 +1003,7 @@ static u32
brcmf_msgbuf_rxbuf_ctrl_post(struct brcmf_msgbuf *msgbuf, bool event_buf, brcmf_msgbuf_rxbuf_ctrl_post(struct brcmf_msgbuf *msgbuf, bool event_buf,
u32 count) u32 count)
{ {
struct brcmf_pub *drvr = msgbuf->drvr;
struct brcmf_commonring *commonring; struct brcmf_commonring *commonring;
void *ret_ptr; void *ret_ptr;
struct sk_buff *skb; struct sk_buff *skb;
@ -1009,7 +1021,7 @@ brcmf_msgbuf_rxbuf_ctrl_post(struct brcmf_msgbuf *msgbuf, bool event_buf,
count, count,
&alloced); &alloced);
if (!ret_ptr) { if (!ret_ptr) {
brcmf_err("Failed to reserve space in commonring\n"); bphy_err(drvr, "Failed to reserve space in commonring\n");
brcmf_commonring_unlock(commonring); brcmf_commonring_unlock(commonring);
return 0; return 0;
} }
@ -1021,7 +1033,7 @@ brcmf_msgbuf_rxbuf_ctrl_post(struct brcmf_msgbuf *msgbuf, bool event_buf,
skb = brcmu_pkt_buf_get_skb(BRCMF_MSGBUF_MAX_PKT_SIZE); skb = brcmu_pkt_buf_get_skb(BRCMF_MSGBUF_MAX_PKT_SIZE);
if (skb == NULL) { if (skb == NULL) {
brcmf_err("Failed to alloc SKB\n"); bphy_err(drvr, "Failed to alloc SKB\n");
brcmf_commonring_write_cancel(commonring, alloced - i); brcmf_commonring_write_cancel(commonring, alloced - i);
break; break;
} }
@ -1031,7 +1043,7 @@ brcmf_msgbuf_rxbuf_ctrl_post(struct brcmf_msgbuf *msgbuf, bool event_buf,
msgbuf->rx_pktids, skb, 0, msgbuf->rx_pktids, skb, 0,
&physaddr, &pktid)) { &physaddr, &pktid)) {
dev_kfree_skb_any(skb); dev_kfree_skb_any(skb);
brcmf_err("No PKTID available !!\n"); bphy_err(drvr, "No PKTID available !!\n");
brcmf_commonring_write_cancel(commonring, alloced - i); brcmf_commonring_write_cancel(commonring, alloced - i);
break; break;
} }
@ -1083,6 +1095,7 @@ static void brcmf_msgbuf_rxbuf_event_post(struct brcmf_msgbuf *msgbuf)
static void brcmf_msgbuf_process_event(struct brcmf_msgbuf *msgbuf, void *buf) static void brcmf_msgbuf_process_event(struct brcmf_msgbuf *msgbuf, void *buf)
{ {
struct brcmf_pub *drvr = msgbuf->drvr;
struct msgbuf_rx_event *event; struct msgbuf_rx_event *event;
u32 idx; u32 idx;
u16 buflen; u16 buflen;
@ -1109,14 +1122,14 @@ static void brcmf_msgbuf_process_event(struct brcmf_msgbuf *msgbuf, void *buf)
ifp = brcmf_get_ifp(msgbuf->drvr, event->msg.ifidx); ifp = brcmf_get_ifp(msgbuf->drvr, event->msg.ifidx);
if (!ifp || !ifp->ndev) { if (!ifp || !ifp->ndev) {
brcmf_err("Received pkt for invalid ifidx %d\n", bphy_err(drvr, "Received pkt for invalid ifidx %d\n",
event->msg.ifidx); event->msg.ifidx);
goto exit; goto exit;
} }
skb->protocol = eth_type_trans(skb, ifp->ndev); skb->protocol = eth_type_trans(skb, ifp->ndev);
brcmf_fweh_process_skb(ifp->drvr, skb); brcmf_fweh_process_skb(ifp->drvr, skb, 0);
exit: exit:
brcmu_pkt_buf_free_skb(skb); brcmu_pkt_buf_free_skb(skb);
@ -1126,6 +1139,7 @@ static void brcmf_msgbuf_process_event(struct brcmf_msgbuf *msgbuf, void *buf)
static void static void
brcmf_msgbuf_process_rx_complete(struct brcmf_msgbuf *msgbuf, void *buf) brcmf_msgbuf_process_rx_complete(struct brcmf_msgbuf *msgbuf, void *buf)
{ {
struct brcmf_pub *drvr = msgbuf->drvr;
struct msgbuf_rx_complete *rx_complete; struct msgbuf_rx_complete *rx_complete;
struct sk_buff *skb; struct sk_buff *skb;
u16 data_offset; u16 data_offset;
@ -1159,7 +1173,7 @@ brcmf_msgbuf_process_rx_complete(struct brcmf_msgbuf *msgbuf, void *buf)
ifp = msgbuf->drvr->mon_if; ifp = msgbuf->drvr->mon_if;
if (!ifp) { if (!ifp) {
brcmf_err("Received unexpected monitor pkt\n"); bphy_err(drvr, "Received unexpected monitor pkt\n");
brcmu_pkt_buf_free_skb(skb); brcmu_pkt_buf_free_skb(skb);
return; return;
} }
@ -1170,7 +1184,7 @@ brcmf_msgbuf_process_rx_complete(struct brcmf_msgbuf *msgbuf, void *buf)
ifp = brcmf_get_ifp(msgbuf->drvr, rx_complete->msg.ifidx); ifp = brcmf_get_ifp(msgbuf->drvr, rx_complete->msg.ifidx);
if (!ifp || !ifp->ndev) { if (!ifp || !ifp->ndev) {
brcmf_err("Received pkt for invalid ifidx %d\n", bphy_err(drvr, "Received pkt for invalid ifidx %d\n",
rx_complete->msg.ifidx); rx_complete->msg.ifidx);
brcmu_pkt_buf_free_skb(skb); brcmu_pkt_buf_free_skb(skb);
return; return;
@ -1180,11 +1194,27 @@ brcmf_msgbuf_process_rx_complete(struct brcmf_msgbuf *msgbuf, void *buf)
brcmf_netif_rx(ifp, skb); brcmf_netif_rx(ifp, skb);
} }
static void brcmf_msgbuf_process_ring_status(struct brcmf_msgbuf *msgbuf,
void *buf)
{
struct msgbuf_ring_status *ring_status = buf;
struct brcmf_pub *drvr = msgbuf->drvr;
int err;
err = le16_to_cpu(ring_status->compl_hdr.status);
if (err) {
int ring = le16_to_cpu(ring_status->compl_hdr.flow_ring_id);
bphy_err(drvr, "Firmware reported ring %d error: %d\n", ring,
err);
}
}
static void static void
brcmf_msgbuf_process_flow_ring_create_response(struct brcmf_msgbuf *msgbuf, brcmf_msgbuf_process_flow_ring_create_response(struct brcmf_msgbuf *msgbuf,
void *buf) void *buf)
{ {
struct brcmf_pub *drvr = msgbuf->drvr;
struct msgbuf_flowring_create_resp *flowring_create_resp; struct msgbuf_flowring_create_resp *flowring_create_resp;
u16 status; u16 status;
u16 flowid; u16 flowid;
@ -1196,7 +1226,7 @@ brcmf_msgbuf_process_flow_ring_create_response(struct brcmf_msgbuf *msgbuf,
status = le16_to_cpu(flowring_create_resp->compl_hdr.status); status = le16_to_cpu(flowring_create_resp->compl_hdr.status);
if (status) { if (status) {
brcmf_err("Flowring creation failed, code %d\n", status); bphy_err(drvr, "Flowring creation failed, code %d\n", status);
brcmf_msgbuf_remove_flowring(msgbuf, flowid); brcmf_msgbuf_remove_flowring(msgbuf, flowid);
return; return;
} }
@ -1213,6 +1243,7 @@ static void
brcmf_msgbuf_process_flow_ring_delete_response(struct brcmf_msgbuf *msgbuf, brcmf_msgbuf_process_flow_ring_delete_response(struct brcmf_msgbuf *msgbuf,
void *buf) void *buf)
{ {
struct brcmf_pub *drvr = msgbuf->drvr;
struct msgbuf_flowring_delete_resp *flowring_delete_resp; struct msgbuf_flowring_delete_resp *flowring_delete_resp;
u16 status; u16 status;
u16 flowid; u16 flowid;
@ -1224,7 +1255,7 @@ brcmf_msgbuf_process_flow_ring_delete_response(struct brcmf_msgbuf *msgbuf,
status = le16_to_cpu(flowring_delete_resp->compl_hdr.status); status = le16_to_cpu(flowring_delete_resp->compl_hdr.status);
if (status) { if (status) {
brcmf_err("Flowring deletion failed, code %d\n", status); bphy_err(drvr, "Flowring deletion failed, code %d\n", status);
brcmf_flowring_delete(msgbuf->flow, flowid); brcmf_flowring_delete(msgbuf->flow, flowid);
return; return;
} }
@ -1237,10 +1268,15 @@ brcmf_msgbuf_process_flow_ring_delete_response(struct brcmf_msgbuf *msgbuf,
static void brcmf_msgbuf_process_msgtype(struct brcmf_msgbuf *msgbuf, void *buf) static void brcmf_msgbuf_process_msgtype(struct brcmf_msgbuf *msgbuf, void *buf)
{ {
struct brcmf_pub *drvr = msgbuf->drvr;
struct msgbuf_common_hdr *msg; struct msgbuf_common_hdr *msg;
msg = (struct msgbuf_common_hdr *)buf; msg = (struct msgbuf_common_hdr *)buf;
switch (msg->msgtype) { switch (msg->msgtype) {
case MSGBUF_TYPE_RING_STATUS:
brcmf_dbg(MSGBUF, "MSGBUF_TYPE_RING_STATUS\n");
brcmf_msgbuf_process_ring_status(msgbuf, buf);
break;
case MSGBUF_TYPE_FLOW_RING_CREATE_CMPLT: case MSGBUF_TYPE_FLOW_RING_CREATE_CMPLT:
brcmf_dbg(MSGBUF, "MSGBUF_TYPE_FLOW_RING_CREATE_CMPLT\n"); brcmf_dbg(MSGBUF, "MSGBUF_TYPE_FLOW_RING_CREATE_CMPLT\n");
brcmf_msgbuf_process_flow_ring_create_response(msgbuf, buf); brcmf_msgbuf_process_flow_ring_create_response(msgbuf, buf);
@ -1269,7 +1305,7 @@ static void brcmf_msgbuf_process_msgtype(struct brcmf_msgbuf *msgbuf, void *buf)
brcmf_msgbuf_process_rx_complete(msgbuf, buf); brcmf_msgbuf_process_rx_complete(msgbuf, buf);
break; break;
default: default:
brcmf_err("Unsupported msgtype %d\n", msg->msgtype); bphy_err(drvr, "Unsupported msgtype %d\n", msg->msgtype);
break; break;
} }
} }
@ -1352,7 +1388,7 @@ void brcmf_msgbuf_delete_flowring(struct brcmf_pub *drvr, u16 flowid)
brcmf_commonring_lock(commonring); brcmf_commonring_lock(commonring);
ret_ptr = brcmf_commonring_reserve_for_write(commonring); ret_ptr = brcmf_commonring_reserve_for_write(commonring);
if (!ret_ptr) { if (!ret_ptr) {
brcmf_err("FW unaware, flowring will be removed !!\n"); bphy_err(drvr, "FW unaware, flowring will be removed !!\n");
brcmf_commonring_unlock(commonring); brcmf_commonring_unlock(commonring);
brcmf_msgbuf_remove_flowring(msgbuf, flowid); brcmf_msgbuf_remove_flowring(msgbuf, flowid);
return; return;
@ -1376,7 +1412,7 @@ void brcmf_msgbuf_delete_flowring(struct brcmf_pub *drvr, u16 flowid)
err = brcmf_commonring_write_complete(commonring); err = brcmf_commonring_write_complete(commonring);
brcmf_commonring_unlock(commonring); brcmf_commonring_unlock(commonring);
if (err) { if (err) {
brcmf_err("Failed to submit RING_DELETE, flowring will be removed\n"); bphy_err(drvr, "Failed to submit RING_DELETE, flowring will be removed\n");
brcmf_msgbuf_remove_flowring(msgbuf, flowid); brcmf_msgbuf_remove_flowring(msgbuf, flowid);
} }
} }
@ -1451,7 +1487,7 @@ int brcmf_proto_msgbuf_attach(struct brcmf_pub *drvr)
if_msgbuf = drvr->bus_if->msgbuf; if_msgbuf = drvr->bus_if->msgbuf;
if (if_msgbuf->max_flowrings >= BRCMF_FLOWRING_HASHSIZE) { if (if_msgbuf->max_flowrings >= BRCMF_FLOWRING_HASHSIZE) {
brcmf_err("driver not configured for this many flowrings %d\n", bphy_err(drvr, "driver not configured for this many flowrings %d\n",
if_msgbuf->max_flowrings); if_msgbuf->max_flowrings);
if_msgbuf->max_flowrings = BRCMF_FLOWRING_HASHSIZE - 1; if_msgbuf->max_flowrings = BRCMF_FLOWRING_HASHSIZE - 1;
} }
@ -1462,7 +1498,7 @@ int brcmf_proto_msgbuf_attach(struct brcmf_pub *drvr)
msgbuf->txflow_wq = create_singlethread_workqueue("msgbuf_txflow"); msgbuf->txflow_wq = create_singlethread_workqueue("msgbuf_txflow");
if (msgbuf->txflow_wq == NULL) { if (msgbuf->txflow_wq == NULL) {
brcmf_err("workqueue creation failed\n"); bphy_err(drvr, "workqueue creation failed\n");
goto fail; goto fail;
} }
INIT_WORK(&msgbuf->txflow_work, brcmf_msgbuf_txflow_worker); INIT_WORK(&msgbuf->txflow_work, brcmf_msgbuf_txflow_worker);

View File

@ -434,6 +434,7 @@ static void brcmf_p2p_print_actframe(bool tx, void *frame, u32 frame_len)
*/ */
static int brcmf_p2p_set_firmware(struct brcmf_if *ifp, u8 *p2p_mac) static int brcmf_p2p_set_firmware(struct brcmf_if *ifp, u8 *p2p_mac)
{ {
struct brcmf_pub *drvr = ifp->drvr;
s32 ret = 0; s32 ret = 0;
brcmf_fil_cmd_int_set(ifp, BRCMF_C_DOWN, 1); brcmf_fil_cmd_int_set(ifp, BRCMF_C_DOWN, 1);
@ -450,7 +451,7 @@ static int brcmf_p2p_set_firmware(struct brcmf_if *ifp, u8 *p2p_mac)
ret = brcmf_fil_iovar_data_set(ifp, "p2p_da_override", p2p_mac, ret = brcmf_fil_iovar_data_set(ifp, "p2p_da_override", p2p_mac,
ETH_ALEN); ETH_ALEN);
if (ret) if (ret)
brcmf_err("failed to update device address ret %d\n", ret); bphy_err(drvr, "failed to update device address ret %d\n", ret);
return ret; return ret;
} }
@ -570,13 +571,14 @@ static s32 brcmf_p2p_deinit_discovery(struct brcmf_p2p_info *p2p)
*/ */
static int brcmf_p2p_enable_discovery(struct brcmf_p2p_info *p2p) static int brcmf_p2p_enable_discovery(struct brcmf_p2p_info *p2p)
{ {
struct brcmf_pub *drvr = p2p->cfg->pub;
struct brcmf_cfg80211_vif *vif; struct brcmf_cfg80211_vif *vif;
s32 ret = 0; s32 ret = 0;
brcmf_dbg(TRACE, "enter\n"); brcmf_dbg(TRACE, "enter\n");
vif = p2p->bss_idx[P2PAPI_BSSCFG_DEVICE].vif; vif = p2p->bss_idx[P2PAPI_BSSCFG_DEVICE].vif;
if (!vif) { if (!vif) {
brcmf_err("P2P config device not available\n"); bphy_err(drvr, "P2P config device not available\n");
ret = -EPERM; ret = -EPERM;
goto exit; goto exit;
} }
@ -590,13 +592,13 @@ static int brcmf_p2p_enable_discovery(struct brcmf_p2p_info *p2p)
vif = p2p->bss_idx[P2PAPI_BSSCFG_PRIMARY].vif; vif = p2p->bss_idx[P2PAPI_BSSCFG_PRIMARY].vif;
ret = brcmf_fil_iovar_int_set(vif->ifp, "p2p_disc", 1); ret = brcmf_fil_iovar_int_set(vif->ifp, "p2p_disc", 1);
if (ret < 0) { if (ret < 0) {
brcmf_err("set p2p_disc error\n"); bphy_err(drvr, "set p2p_disc error\n");
goto exit; goto exit;
} }
vif = p2p->bss_idx[P2PAPI_BSSCFG_DEVICE].vif; vif = p2p->bss_idx[P2PAPI_BSSCFG_DEVICE].vif;
ret = brcmf_p2p_set_discover_state(vif->ifp, WL_P2P_DISC_ST_SCAN, 0, 0); ret = brcmf_p2p_set_discover_state(vif->ifp, WL_P2P_DISC_ST_SCAN, 0, 0);
if (ret < 0) { if (ret < 0) {
brcmf_err("unable to set WL_P2P_DISC_ST_SCAN\n"); bphy_err(drvr, "unable to set WL_P2P_DISC_ST_SCAN\n");
goto exit; goto exit;
} }
@ -608,7 +610,7 @@ static int brcmf_p2p_enable_discovery(struct brcmf_p2p_info *p2p)
*/ */
ret = brcmf_fil_bsscfg_int_set(vif->ifp, "wsec", AES_ENABLED); ret = brcmf_fil_bsscfg_int_set(vif->ifp, "wsec", AES_ENABLED);
if (ret < 0) { if (ret < 0) {
brcmf_err("wsec error %d\n", ret); bphy_err(drvr, "wsec error %d\n", ret);
goto exit; goto exit;
} }
@ -630,6 +632,7 @@ static s32 brcmf_p2p_escan(struct brcmf_p2p_info *p2p, u32 num_chans,
u16 chanspecs[], s32 search_state, u16 chanspecs[], s32 search_state,
enum p2p_bss_type bss_type) enum p2p_bss_type bss_type)
{ {
struct brcmf_pub *drvr = p2p->cfg->pub;
s32 ret = 0; s32 ret = 0;
s32 memsize = offsetof(struct brcmf_p2p_scan_le, s32 memsize = offsetof(struct brcmf_p2p_scan_le,
eparams.params_le.channel_list); eparams.params_le.channel_list);
@ -648,7 +651,7 @@ static s32 brcmf_p2p_escan(struct brcmf_p2p_info *p2p, u32 num_chans,
vif = p2p->bss_idx[bss_type].vif; vif = p2p->bss_idx[bss_type].vif;
if (vif == NULL) { if (vif == NULL) {
brcmf_err("no vif for bss type %d\n", bss_type); bphy_err(drvr, "no vif for bss type %d\n", bss_type);
ret = -EINVAL; ret = -EINVAL;
goto exit; goto exit;
} }
@ -676,7 +679,7 @@ static s32 brcmf_p2p_escan(struct brcmf_p2p_info *p2p, u32 num_chans,
BRCMF_P2P_WILDCARD_SSID_LEN); BRCMF_P2P_WILDCARD_SSID_LEN);
break; break;
default: default:
brcmf_err(" invalid search state %d\n", search_state); bphy_err(drvr, " invalid search state %d\n", search_state);
ret = -EINVAL; ret = -EINVAL;
goto exit; goto exit;
} }
@ -760,6 +763,7 @@ static s32 brcmf_p2p_run_escan(struct brcmf_cfg80211_info *cfg,
struct cfg80211_scan_request *request) struct cfg80211_scan_request *request)
{ {
struct brcmf_p2p_info *p2p = &cfg->p2p; struct brcmf_p2p_info *p2p = &cfg->p2p;
struct brcmf_pub *drvr = cfg->pub;
s32 err = 0; s32 err = 0;
s32 search_state = WL_P2P_DISC_ST_SCAN; s32 search_state = WL_P2P_DISC_ST_SCAN;
struct brcmf_cfg80211_vif *vif; struct brcmf_cfg80211_vif *vif;
@ -822,7 +826,7 @@ static s32 brcmf_p2p_run_escan(struct brcmf_cfg80211_info *cfg,
} }
exit: exit:
if (err) if (err)
brcmf_err("error (%d)\n", err); bphy_err(drvr, "error (%d)\n", err);
return err; return err;
} }
@ -917,19 +921,20 @@ int brcmf_p2p_scan_prep(struct wiphy *wiphy,
static s32 static s32
brcmf_p2p_discover_listen(struct brcmf_p2p_info *p2p, u16 channel, u32 duration) brcmf_p2p_discover_listen(struct brcmf_p2p_info *p2p, u16 channel, u32 duration)
{ {
struct brcmf_pub *drvr = p2p->cfg->pub;
struct brcmf_cfg80211_vif *vif; struct brcmf_cfg80211_vif *vif;
struct brcmu_chan ch; struct brcmu_chan ch;
s32 err = 0; s32 err = 0;
vif = p2p->bss_idx[P2PAPI_BSSCFG_DEVICE].vif; vif = p2p->bss_idx[P2PAPI_BSSCFG_DEVICE].vif;
if (!vif) { if (!vif) {
brcmf_err("Discovery is not set, so we have nothing to do\n"); bphy_err(drvr, "Discovery is not set, so we have nothing to do\n");
err = -EPERM; err = -EPERM;
goto exit; goto exit;
} }
if (test_bit(BRCMF_P2P_STATUS_DISCOVER_LISTEN, &p2p->status)) { if (test_bit(BRCMF_P2P_STATUS_DISCOVER_LISTEN, &p2p->status)) {
brcmf_err("Previous LISTEN is not completed yet\n"); bphy_err(drvr, "Previous LISTEN is not completed yet\n");
/* WAR: prevent cookie mismatch in wpa_supplicant return OK */ /* WAR: prevent cookie mismatch in wpa_supplicant return OK */
goto exit; goto exit;
} }
@ -1046,6 +1051,7 @@ void brcmf_p2p_cancel_remain_on_channel(struct brcmf_if *ifp)
*/ */
static s32 brcmf_p2p_act_frm_search(struct brcmf_p2p_info *p2p, u16 channel) static s32 brcmf_p2p_act_frm_search(struct brcmf_p2p_info *p2p, u16 channel)
{ {
struct brcmf_pub *drvr = p2p->cfg->pub;
s32 err; s32 err;
u32 channel_cnt; u32 channel_cnt;
u16 *default_chan_list; u16 *default_chan_list;
@ -1061,7 +1067,7 @@ static s32 brcmf_p2p_act_frm_search(struct brcmf_p2p_info *p2p, u16 channel)
default_chan_list = kcalloc(channel_cnt, sizeof(*default_chan_list), default_chan_list = kcalloc(channel_cnt, sizeof(*default_chan_list),
GFP_KERNEL); GFP_KERNEL);
if (default_chan_list == NULL) { if (default_chan_list == NULL) {
brcmf_err("channel list allocation failed\n"); bphy_err(drvr, "channel list allocation failed\n");
err = -ENOMEM; err = -ENOMEM;
goto exit; goto exit;
} }
@ -1103,6 +1109,7 @@ static void brcmf_p2p_afx_handler(struct work_struct *work)
struct brcmf_p2p_info *p2p = container_of(afx_hdl, struct brcmf_p2p_info *p2p = container_of(afx_hdl,
struct brcmf_p2p_info, struct brcmf_p2p_info,
afx_hdl); afx_hdl);
struct brcmf_pub *drvr = p2p->cfg->pub;
s32 err; s32 err;
if (!afx_hdl->is_active) if (!afx_hdl->is_active)
@ -1116,7 +1123,7 @@ static void brcmf_p2p_afx_handler(struct work_struct *work)
err = brcmf_p2p_act_frm_search(p2p, afx_hdl->peer_listen_chan); err = brcmf_p2p_act_frm_search(p2p, afx_hdl->peer_listen_chan);
if (err) { if (err) {
brcmf_err("ERROR occurred! value is (%d)\n", err); bphy_err(drvr, "ERROR occurred! value is (%d)\n", err);
if (test_bit(BRCMF_P2P_STATUS_FINDING_COMMON_CHANNEL, if (test_bit(BRCMF_P2P_STATUS_FINDING_COMMON_CHANNEL,
&p2p->status)) &p2p->status))
complete(&afx_hdl->act_frm_scan); complete(&afx_hdl->act_frm_scan);
@ -1338,7 +1345,8 @@ int brcmf_p2p_notify_action_frame_rx(struct brcmf_if *ifp,
const struct brcmf_event_msg *e, const struct brcmf_event_msg *e,
void *data) void *data)
{ {
struct brcmf_cfg80211_info *cfg = ifp->drvr->config; struct brcmf_pub *drvr = ifp->drvr;
struct brcmf_cfg80211_info *cfg = drvr->config;
struct brcmf_p2p_info *p2p = &cfg->p2p; struct brcmf_p2p_info *p2p = &cfg->p2p;
struct afx_hdl *afx_hdl = &p2p->afx_hdl; struct afx_hdl *afx_hdl = &p2p->afx_hdl;
struct wireless_dev *wdev; struct wireless_dev *wdev;
@ -1409,7 +1417,7 @@ int brcmf_p2p_notify_action_frame_rx(struct brcmf_if *ifp,
mgmt_frame = kzalloc(offsetof(struct ieee80211_mgmt, u) + mgmt_frame = kzalloc(offsetof(struct ieee80211_mgmt, u) +
mgmt_frame_len, GFP_KERNEL); mgmt_frame_len, GFP_KERNEL);
if (!mgmt_frame) { if (!mgmt_frame) {
brcmf_err("No memory available for action frame\n"); bphy_err(drvr, "No memory available for action frame\n");
return -ENOMEM; return -ENOMEM;
} }
memcpy(mgmt_frame->da, ifp->mac_addr, ETH_ALEN); memcpy(mgmt_frame->da, ifp->mac_addr, ETH_ALEN);
@ -1492,6 +1500,7 @@ int brcmf_p2p_notify_action_tx_complete(struct brcmf_if *ifp,
static s32 brcmf_p2p_tx_action_frame(struct brcmf_p2p_info *p2p, static s32 brcmf_p2p_tx_action_frame(struct brcmf_p2p_info *p2p,
struct brcmf_fil_af_params_le *af_params) struct brcmf_fil_af_params_le *af_params)
{ {
struct brcmf_pub *drvr = p2p->cfg->pub;
struct brcmf_cfg80211_vif *vif; struct brcmf_cfg80211_vif *vif;
s32 err = 0; s32 err = 0;
s32 timeout = 0; s32 timeout = 0;
@ -1506,7 +1515,7 @@ static s32 brcmf_p2p_tx_action_frame(struct brcmf_p2p_info *p2p,
err = brcmf_fil_bsscfg_data_set(vif->ifp, "actframe", af_params, err = brcmf_fil_bsscfg_data_set(vif->ifp, "actframe", af_params,
sizeof(*af_params)); sizeof(*af_params));
if (err) { if (err) {
brcmf_err(" sending action frame has failed\n"); bphy_err(drvr, " sending action frame has failed\n");
goto exit; goto exit;
} }
@ -1556,6 +1565,7 @@ static s32 brcmf_p2p_pub_af_tx(struct brcmf_cfg80211_info *cfg,
struct brcmf_config_af_params *config_af_params) struct brcmf_config_af_params *config_af_params)
{ {
struct brcmf_p2p_info *p2p = &cfg->p2p; struct brcmf_p2p_info *p2p = &cfg->p2p;
struct brcmf_pub *drvr = cfg->pub;
struct brcmf_fil_action_frame_le *action_frame; struct brcmf_fil_action_frame_le *action_frame;
struct brcmf_p2p_pub_act_frame *act_frm; struct brcmf_p2p_pub_act_frame *act_frm;
s32 err = 0; s32 err = 0;
@ -1634,7 +1644,7 @@ static s32 brcmf_p2p_pub_af_tx(struct brcmf_cfg80211_info *cfg,
config_af_params->extra_listen = false; config_af_params->extra_listen = false;
break; break;
default: default:
brcmf_err("Unknown p2p pub act frame subtype: %d\n", bphy_err(drvr, "Unknown p2p pub act frame subtype: %d\n",
act_frm->subtype); act_frm->subtype);
err = -EINVAL; err = -EINVAL;
} }
@ -1657,6 +1667,7 @@ bool brcmf_p2p_send_action_frame(struct brcmf_cfg80211_info *cfg,
struct brcmf_fil_action_frame_le *action_frame; struct brcmf_fil_action_frame_le *action_frame;
struct brcmf_config_af_params config_af_params; struct brcmf_config_af_params config_af_params;
struct afx_hdl *afx_hdl = &p2p->afx_hdl; struct afx_hdl *afx_hdl = &p2p->afx_hdl;
struct brcmf_pub *drvr = cfg->pub;
u16 action_frame_len; u16 action_frame_len;
bool ack = false; bool ack = false;
u8 category; u8 category;
@ -1692,7 +1703,7 @@ bool brcmf_p2p_send_action_frame(struct brcmf_cfg80211_info *cfg,
if (brcmf_p2p_pub_af_tx(cfg, af_params, &config_af_params)) { if (brcmf_p2p_pub_af_tx(cfg, af_params, &config_af_params)) {
/* Just send unknown subtype frame with */ /* Just send unknown subtype frame with */
/* default parameters. */ /* default parameters. */
brcmf_err("P2P Public action frame, unknown subtype.\n"); bphy_err(drvr, "P2P Public action frame, unknown subtype.\n");
} }
} else if (brcmf_p2p_is_gas_action(action_frame->data, } else if (brcmf_p2p_is_gas_action(action_frame->data,
action_frame_len)) { action_frame_len)) {
@ -1714,7 +1725,7 @@ bool brcmf_p2p_send_action_frame(struct brcmf_cfg80211_info *cfg,
af_params->dwell_time = af_params->dwell_time =
cpu_to_le32(P2P_AF_MIN_DWELL_TIME); cpu_to_le32(P2P_AF_MIN_DWELL_TIME);
} else { } else {
brcmf_err("Unknown action type: %d\n", action); bphy_err(drvr, "Unknown action type: %d\n", action);
goto exit; goto exit;
} }
} else if (brcmf_p2p_is_p2p_action(action_frame->data, } else if (brcmf_p2p_is_p2p_action(action_frame->data,
@ -1722,7 +1733,7 @@ bool brcmf_p2p_send_action_frame(struct brcmf_cfg80211_info *cfg,
/* do not configure anything. it will be */ /* do not configure anything. it will be */
/* sent with a default configuration */ /* sent with a default configuration */
} else { } else {
brcmf_err("Unknown Frame: category 0x%x, action 0x%x\n", bphy_err(drvr, "Unknown Frame: category 0x%x, action 0x%x\n",
category, action); category, action);
return false; return false;
} }
@ -1761,7 +1772,7 @@ bool brcmf_p2p_send_action_frame(struct brcmf_cfg80211_info *cfg,
if (brcmf_p2p_af_searching_channel(p2p) == if (brcmf_p2p_af_searching_channel(p2p) ==
P2P_INVALID_CHANNEL) { P2P_INVALID_CHANNEL) {
brcmf_err("Couldn't find peer's channel.\n"); bphy_err(drvr, "Couldn't find peer's channel.\n");
goto exit; goto exit;
} }
@ -1783,7 +1794,8 @@ bool brcmf_p2p_send_action_frame(struct brcmf_cfg80211_info *cfg,
tx_retry++; tx_retry++;
} }
if (ack == false) { if (ack == false) {
brcmf_err("Failed to send Action Frame(retry %d)\n", tx_retry); bphy_err(drvr, "Failed to send Action Frame(retry %d)\n",
tx_retry);
clear_bit(BRCMF_P2P_STATUS_GO_NEG_PHASE, &p2p->status); clear_bit(BRCMF_P2P_STATUS_GO_NEG_PHASE, &p2p->status);
} }
@ -1965,6 +1977,7 @@ int brcmf_p2p_ifchange(struct brcmf_cfg80211_info *cfg,
enum brcmf_fil_p2p_if_types if_type) enum brcmf_fil_p2p_if_types if_type)
{ {
struct brcmf_p2p_info *p2p = &cfg->p2p; struct brcmf_p2p_info *p2p = &cfg->p2p;
struct brcmf_pub *drvr = cfg->pub;
struct brcmf_cfg80211_vif *vif; struct brcmf_cfg80211_vif *vif;
struct brcmf_fil_p2p_if_le if_request; struct brcmf_fil_p2p_if_le if_request;
s32 err; s32 err;
@ -1974,13 +1987,13 @@ int brcmf_p2p_ifchange(struct brcmf_cfg80211_info *cfg,
vif = p2p->bss_idx[P2PAPI_BSSCFG_PRIMARY].vif; vif = p2p->bss_idx[P2PAPI_BSSCFG_PRIMARY].vif;
if (!vif) { if (!vif) {
brcmf_err("vif for P2PAPI_BSSCFG_PRIMARY does not exist\n"); bphy_err(drvr, "vif for P2PAPI_BSSCFG_PRIMARY does not exist\n");
return -EPERM; return -EPERM;
} }
brcmf_notify_escan_complete(cfg, vif->ifp, true, true); brcmf_notify_escan_complete(cfg, vif->ifp, true, true);
vif = p2p->bss_idx[P2PAPI_BSSCFG_CONNECTION].vif; vif = p2p->bss_idx[P2PAPI_BSSCFG_CONNECTION].vif;
if (!vif) { if (!vif) {
brcmf_err("vif for P2PAPI_BSSCFG_CONNECTION does not exist\n"); bphy_err(drvr, "vif for P2PAPI_BSSCFG_CONNECTION does not exist\n");
return -EPERM; return -EPERM;
} }
brcmf_set_mpc(vif->ifp, 0); brcmf_set_mpc(vif->ifp, 0);
@ -1998,7 +2011,7 @@ int brcmf_p2p_ifchange(struct brcmf_cfg80211_info *cfg,
err = brcmf_fil_iovar_data_set(vif->ifp, "p2p_ifupd", &if_request, err = brcmf_fil_iovar_data_set(vif->ifp, "p2p_ifupd", &if_request,
sizeof(if_request)); sizeof(if_request));
if (err) { if (err) {
brcmf_err("p2p_ifupd FAILED, err=%d\n", err); bphy_err(drvr, "p2p_ifupd FAILED, err=%d\n", err);
brcmf_cfg80211_arm_vif_event(cfg, NULL); brcmf_cfg80211_arm_vif_event(cfg, NULL);
return err; return err;
} }
@ -2006,7 +2019,7 @@ int brcmf_p2p_ifchange(struct brcmf_cfg80211_info *cfg,
BRCMF_VIF_EVENT_TIMEOUT); BRCMF_VIF_EVENT_TIMEOUT);
brcmf_cfg80211_arm_vif_event(cfg, NULL); brcmf_cfg80211_arm_vif_event(cfg, NULL);
if (!err) { if (!err) {
brcmf_err("No BRCMF_E_IF_CHANGE event received\n"); bphy_err(drvr, "No BRCMF_E_IF_CHANGE event received\n");
return -EIO; return -EIO;
} }
@ -2069,6 +2082,7 @@ static struct wireless_dev *brcmf_p2p_create_p2pdev(struct brcmf_p2p_info *p2p,
struct wiphy *wiphy, struct wiphy *wiphy,
u8 *addr) u8 *addr)
{ {
struct brcmf_pub *drvr = p2p->cfg->pub;
struct brcmf_cfg80211_vif *p2p_vif; struct brcmf_cfg80211_vif *p2p_vif;
struct brcmf_if *p2p_ifp; struct brcmf_if *p2p_ifp;
struct brcmf_if *pri_ifp; struct brcmf_if *pri_ifp;
@ -2080,7 +2094,7 @@ static struct wireless_dev *brcmf_p2p_create_p2pdev(struct brcmf_p2p_info *p2p,
p2p_vif = brcmf_alloc_vif(p2p->cfg, NL80211_IFTYPE_P2P_DEVICE); p2p_vif = brcmf_alloc_vif(p2p->cfg, NL80211_IFTYPE_P2P_DEVICE);
if (IS_ERR(p2p_vif)) { if (IS_ERR(p2p_vif)) {
brcmf_err("could not create discovery vif\n"); bphy_err(drvr, "could not create discovery vif\n");
return (struct wireless_dev *)p2p_vif; return (struct wireless_dev *)p2p_vif;
} }
@ -2088,7 +2102,7 @@ static struct wireless_dev *brcmf_p2p_create_p2pdev(struct brcmf_p2p_info *p2p,
/* firmware requires unique mac address for p2pdev interface */ /* firmware requires unique mac address for p2pdev interface */
if (addr && ether_addr_equal(addr, pri_ifp->mac_addr)) { if (addr && ether_addr_equal(addr, pri_ifp->mac_addr)) {
brcmf_err("discovery vif must be different from primary interface\n"); bphy_err(drvr, "discovery vif must be different from primary interface\n");
return ERR_PTR(-EINVAL); return ERR_PTR(-EINVAL);
} }
@ -2101,7 +2115,7 @@ static struct wireless_dev *brcmf_p2p_create_p2pdev(struct brcmf_p2p_info *p2p,
/* Initialize P2P Discovery in the firmware */ /* Initialize P2P Discovery in the firmware */
err = brcmf_fil_iovar_int_set(pri_ifp, "p2p_disc", 1); err = brcmf_fil_iovar_int_set(pri_ifp, "p2p_disc", 1);
if (err < 0) { if (err < 0) {
brcmf_err("set p2p_disc error\n"); bphy_err(drvr, "set p2p_disc error\n");
brcmf_fweh_p2pdev_setup(pri_ifp, false); brcmf_fweh_p2pdev_setup(pri_ifp, false);
brcmf_cfg80211_arm_vif_event(p2p->cfg, NULL); brcmf_cfg80211_arm_vif_event(p2p->cfg, NULL);
goto fail; goto fail;
@ -2113,7 +2127,7 @@ static struct wireless_dev *brcmf_p2p_create_p2pdev(struct brcmf_p2p_info *p2p,
brcmf_cfg80211_arm_vif_event(p2p->cfg, NULL); brcmf_cfg80211_arm_vif_event(p2p->cfg, NULL);
brcmf_fweh_p2pdev_setup(pri_ifp, false); brcmf_fweh_p2pdev_setup(pri_ifp, false);
if (!err) { if (!err) {
brcmf_err("timeout occurred\n"); bphy_err(drvr, "timeout occurred\n");
err = -EIO; err = -EIO;
goto fail; goto fail;
} }
@ -2127,7 +2141,7 @@ static struct wireless_dev *brcmf_p2p_create_p2pdev(struct brcmf_p2p_info *p2p,
/* verify bsscfg index for P2P discovery */ /* verify bsscfg index for P2P discovery */
err = brcmf_fil_iovar_int_get(pri_ifp, "p2p_dev", &bsscfgidx); err = brcmf_fil_iovar_int_get(pri_ifp, "p2p_dev", &bsscfgidx);
if (err < 0) { if (err < 0) {
brcmf_err("retrieving discover bsscfg index failed\n"); bphy_err(drvr, "retrieving discover bsscfg index failed\n");
goto fail; goto fail;
} }
@ -2161,6 +2175,7 @@ struct wireless_dev *brcmf_p2p_add_vif(struct wiphy *wiphy, const char *name,
{ {
struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy); struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
struct brcmf_if *ifp = netdev_priv(cfg_to_ndev(cfg)); struct brcmf_if *ifp = netdev_priv(cfg_to_ndev(cfg));
struct brcmf_pub *drvr = cfg->pub;
struct brcmf_cfg80211_vif *vif; struct brcmf_cfg80211_vif *vif;
enum brcmf_fil_p2p_if_types iftype; enum brcmf_fil_p2p_if_types iftype;
int err; int err;
@ -2201,7 +2216,7 @@ struct wireless_dev *brcmf_p2p_add_vif(struct wiphy *wiphy, const char *name,
BRCMF_VIF_EVENT_TIMEOUT); BRCMF_VIF_EVENT_TIMEOUT);
brcmf_cfg80211_arm_vif_event(cfg, NULL); brcmf_cfg80211_arm_vif_event(cfg, NULL);
if (!err) { if (!err) {
brcmf_err("timeout occurred\n"); bphy_err(drvr, "timeout occurred\n");
err = -EIO; err = -EIO;
goto fail; goto fail;
} }
@ -2209,7 +2224,7 @@ struct wireless_dev *brcmf_p2p_add_vif(struct wiphy *wiphy, const char *name,
/* interface created in firmware */ /* interface created in firmware */
ifp = vif->ifp; ifp = vif->ifp;
if (!ifp) { if (!ifp) {
brcmf_err("no if pointer provided\n"); bphy_err(drvr, "no if pointer provided\n");
err = -ENOENT; err = -ENOENT;
goto fail; goto fail;
} }
@ -2218,7 +2233,7 @@ struct wireless_dev *brcmf_p2p_add_vif(struct wiphy *wiphy, const char *name,
ifp->ndev->name_assign_type = name_assign_type; ifp->ndev->name_assign_type = name_assign_type;
err = brcmf_net_attach(ifp, true); err = brcmf_net_attach(ifp, true);
if (err) { if (err) {
brcmf_err("Registering netdevice failed\n"); bphy_err(drvr, "Registering netdevice failed\n");
free_netdev(ifp->ndev); free_netdev(ifp->ndev);
goto fail; goto fail;
} }
@ -2373,6 +2388,7 @@ void brcmf_p2p_stop_device(struct wiphy *wiphy, struct wireless_dev *wdev)
*/ */
s32 brcmf_p2p_attach(struct brcmf_cfg80211_info *cfg, bool p2pdev_forced) s32 brcmf_p2p_attach(struct brcmf_cfg80211_info *cfg, bool p2pdev_forced)
{ {
struct brcmf_pub *drvr = cfg->pub;
struct brcmf_p2p_info *p2p; struct brcmf_p2p_info *p2p;
struct brcmf_if *pri_ifp; struct brcmf_if *pri_ifp;
s32 err = 0; s32 err = 0;
@ -2387,7 +2403,7 @@ s32 brcmf_p2p_attach(struct brcmf_cfg80211_info *cfg, bool p2pdev_forced)
if (p2pdev_forced) { if (p2pdev_forced) {
err_ptr = brcmf_p2p_create_p2pdev(p2p, NULL, NULL); err_ptr = brcmf_p2p_create_p2pdev(p2p, NULL, NULL);
if (IS_ERR(err_ptr)) { if (IS_ERR(err_ptr)) {
brcmf_err("P2P device creation failed.\n"); bphy_err(drvr, "P2P device creation failed.\n");
err = PTR_ERR(err_ptr); err = PTR_ERR(err_ptr);
} }
} else { } else {

View File

@ -30,6 +30,15 @@
#include <brcmu_wifi.h> #include <brcmu_wifi.h>
#include <brcm_hw_ids.h> #include <brcm_hw_ids.h>
/* Custom brcmf_err() that takes bus arg and passes it further */
#define brcmf_err(bus, fmt, ...) \
do { \
if (IS_ENABLED(CONFIG_BRCMDBG) || \
IS_ENABLED(CONFIG_BRCM_TRACING) || \
net_ratelimit()) \
__brcmf_err(bus, __func__, fmt, ##__VA_ARGS__); \
} while (0)
#include "debug.h" #include "debug.h"
#include "bus.h" #include "bus.h"
#include "commonring.h" #include "commonring.h"
@ -531,6 +540,7 @@ static void
brcmf_pcie_select_core(struct brcmf_pciedev_info *devinfo, u16 coreid) brcmf_pcie_select_core(struct brcmf_pciedev_info *devinfo, u16 coreid)
{ {
const struct pci_dev *pdev = devinfo->pdev; const struct pci_dev *pdev = devinfo->pdev;
struct brcmf_bus *bus = dev_get_drvdata(&pdev->dev);
struct brcmf_core *core; struct brcmf_core *core;
u32 bar0_win; u32 bar0_win;
@ -548,7 +558,7 @@ brcmf_pcie_select_core(struct brcmf_pciedev_info *devinfo, u16 coreid)
} }
} }
} else { } else {
brcmf_err("Unsupported core selected %x\n", coreid); brcmf_err(bus, "Unsupported core selected %x\n", coreid);
} }
} }
@ -848,9 +858,8 @@ static irqreturn_t brcmf_pcie_isr_thread(int irq, void *arg)
static int brcmf_pcie_request_irq(struct brcmf_pciedev_info *devinfo) static int brcmf_pcie_request_irq(struct brcmf_pciedev_info *devinfo)
{ {
struct pci_dev *pdev; struct pci_dev *pdev = devinfo->pdev;
struct brcmf_bus *bus = dev_get_drvdata(&pdev->dev);
pdev = devinfo->pdev;
brcmf_pcie_intr_disable(devinfo); brcmf_pcie_intr_disable(devinfo);
@ -861,7 +870,7 @@ static int brcmf_pcie_request_irq(struct brcmf_pciedev_info *devinfo)
brcmf_pcie_isr_thread, IRQF_SHARED, brcmf_pcie_isr_thread, IRQF_SHARED,
"brcmf_pcie_intr", devinfo)) { "brcmf_pcie_intr", devinfo)) {
pci_disable_msi(pdev); pci_disable_msi(pdev);
brcmf_err("Failed to request IRQ %d\n", pdev->irq); brcmf_err(bus, "Failed to request IRQ %d\n", pdev->irq);
return -EIO; return -EIO;
} }
devinfo->irq_allocated = true; devinfo->irq_allocated = true;
@ -871,15 +880,14 @@ static int brcmf_pcie_request_irq(struct brcmf_pciedev_info *devinfo)
static void brcmf_pcie_release_irq(struct brcmf_pciedev_info *devinfo) static void brcmf_pcie_release_irq(struct brcmf_pciedev_info *devinfo)
{ {
struct pci_dev *pdev; struct pci_dev *pdev = devinfo->pdev;
struct brcmf_bus *bus = dev_get_drvdata(&pdev->dev);
u32 status; u32 status;
u32 count; u32 count;
if (!devinfo->irq_allocated) if (!devinfo->irq_allocated)
return; return;
pdev = devinfo->pdev;
brcmf_pcie_intr_disable(devinfo); brcmf_pcie_intr_disable(devinfo);
free_irq(pdev->irq, devinfo); free_irq(pdev->irq, devinfo);
pci_disable_msi(pdev); pci_disable_msi(pdev);
@ -891,7 +899,7 @@ static void brcmf_pcie_release_irq(struct brcmf_pciedev_info *devinfo)
count++; count++;
} }
if (devinfo->in_irq) if (devinfo->in_irq)
brcmf_err("Still in IRQ (processing) !!!\n"); brcmf_err(bus, "Still in IRQ (processing) !!!\n");
status = brcmf_pcie_read_reg32(devinfo, BRCMF_PCIE_PCIE2REG_MAILBOXINT); status = brcmf_pcie_read_reg32(devinfo, BRCMF_PCIE_PCIE2REG_MAILBOXINT);
brcmf_pcie_write_reg32(devinfo, BRCMF_PCIE_PCIE2REG_MAILBOXINT, status); brcmf_pcie_write_reg32(devinfo, BRCMF_PCIE_PCIE2REG_MAILBOXINT, status);
@ -1102,6 +1110,7 @@ static void brcmf_pcie_release_ringbuffers(struct brcmf_pciedev_info *devinfo)
static int brcmf_pcie_init_ringbuffers(struct brcmf_pciedev_info *devinfo) static int brcmf_pcie_init_ringbuffers(struct brcmf_pciedev_info *devinfo)
{ {
struct brcmf_bus *bus = dev_get_drvdata(&devinfo->pdev->dev);
struct brcmf_pcie_ringbuf *ring; struct brcmf_pcie_ringbuf *ring;
struct brcmf_pcie_ringbuf *rings; struct brcmf_pcie_ringbuf *rings;
u32 d2h_w_idx_ptr; u32 d2h_w_idx_ptr;
@ -1254,7 +1263,7 @@ static int brcmf_pcie_init_ringbuffers(struct brcmf_pciedev_info *devinfo)
return 0; return 0;
fail: fail:
brcmf_err("Allocating ring buffers failed\n"); brcmf_err(bus, "Allocating ring buffers failed\n");
brcmf_pcie_release_ringbuffers(devinfo); brcmf_pcie_release_ringbuffers(devinfo);
return -ENOMEM; return -ENOMEM;
} }
@ -1277,6 +1286,7 @@ brcmf_pcie_release_scratchbuffers(struct brcmf_pciedev_info *devinfo)
static int brcmf_pcie_init_scratchbuffers(struct brcmf_pciedev_info *devinfo) static int brcmf_pcie_init_scratchbuffers(struct brcmf_pciedev_info *devinfo)
{ {
struct brcmf_bus *bus = dev_get_drvdata(&devinfo->pdev->dev);
u64 address; u64 address;
u32 addr; u32 addr;
@ -1316,7 +1326,7 @@ static int brcmf_pcie_init_scratchbuffers(struct brcmf_pciedev_info *devinfo)
return 0; return 0;
fail: fail:
brcmf_err("Allocating scratch buffers failed\n"); brcmf_err(bus, "Allocating scratch buffers failed\n");
brcmf_pcie_release_scratchbuffers(devinfo); brcmf_pcie_release_scratchbuffers(devinfo);
return -ENOMEM; return -ENOMEM;
} }
@ -1437,6 +1447,7 @@ static int
brcmf_pcie_init_share_ram_info(struct brcmf_pciedev_info *devinfo, brcmf_pcie_init_share_ram_info(struct brcmf_pciedev_info *devinfo,
u32 sharedram_addr) u32 sharedram_addr)
{ {
struct brcmf_bus *bus = dev_get_drvdata(&devinfo->pdev->dev);
struct brcmf_pcie_shared_info *shared; struct brcmf_pcie_shared_info *shared;
u32 addr; u32 addr;
@ -1448,7 +1459,8 @@ brcmf_pcie_init_share_ram_info(struct brcmf_pciedev_info *devinfo,
brcmf_dbg(PCIE, "PCIe protocol version %d\n", shared->version); brcmf_dbg(PCIE, "PCIe protocol version %d\n", shared->version);
if ((shared->version > BRCMF_PCIE_MAX_SHARED_VERSION) || if ((shared->version > BRCMF_PCIE_MAX_SHARED_VERSION) ||
(shared->version < BRCMF_PCIE_MIN_SHARED_VERSION)) { (shared->version < BRCMF_PCIE_MIN_SHARED_VERSION)) {
brcmf_err("Unsupported PCIE version %d\n", shared->version); brcmf_err(bus, "Unsupported PCIE version %d\n",
shared->version);
return -EINVAL; return -EINVAL;
} }
@ -1490,6 +1502,7 @@ static int brcmf_pcie_download_fw_nvram(struct brcmf_pciedev_info *devinfo,
const struct firmware *fw, void *nvram, const struct firmware *fw, void *nvram,
u32 nvram_len) u32 nvram_len)
{ {
struct brcmf_bus *bus = dev_get_drvdata(&devinfo->pdev->dev);
u32 sharedram_addr; u32 sharedram_addr;
u32 sharedram_addr_written; u32 sharedram_addr_written;
u32 loop_counter; u32 loop_counter;
@ -1544,7 +1557,13 @@ static int brcmf_pcie_download_fw_nvram(struct brcmf_pciedev_info *devinfo,
loop_counter--; loop_counter--;
} }
if (sharedram_addr == sharedram_addr_written) { if (sharedram_addr == sharedram_addr_written) {
brcmf_err("FW failed to initialize\n"); brcmf_err(bus, "FW failed to initialize\n");
return -ENODEV;
}
if (sharedram_addr < devinfo->ci->rambase ||
sharedram_addr >= devinfo->ci->rambase + devinfo->ci->ramsize) {
brcmf_err(bus, "Invalid shared RAM address 0x%08x\n",
sharedram_addr);
return -ENODEV; return -ENODEV;
} }
brcmf_dbg(PCIE, "Shared RAM addr: 0x%08x\n", sharedram_addr); brcmf_dbg(PCIE, "Shared RAM addr: 0x%08x\n", sharedram_addr);
@ -1555,16 +1574,15 @@ static int brcmf_pcie_download_fw_nvram(struct brcmf_pciedev_info *devinfo,
static int brcmf_pcie_get_resource(struct brcmf_pciedev_info *devinfo) static int brcmf_pcie_get_resource(struct brcmf_pciedev_info *devinfo)
{ {
struct pci_dev *pdev; struct pci_dev *pdev = devinfo->pdev;
struct brcmf_bus *bus = dev_get_drvdata(&pdev->dev);
int err; int err;
phys_addr_t bar0_addr, bar1_addr; phys_addr_t bar0_addr, bar1_addr;
ulong bar1_size; ulong bar1_size;
pdev = devinfo->pdev;
err = pci_enable_device(pdev); err = pci_enable_device(pdev);
if (err) { if (err) {
brcmf_err("pci_enable_device failed err=%d\n", err); brcmf_err(bus, "pci_enable_device failed err=%d\n", err);
return err; return err;
} }
@ -1577,7 +1595,7 @@ static int brcmf_pcie_get_resource(struct brcmf_pciedev_info *devinfo)
/* read Bar-1 mapped memory range */ /* read Bar-1 mapped memory range */
bar1_size = pci_resource_len(pdev, 2); bar1_size = pci_resource_len(pdev, 2);
if ((bar1_size == 0) || (bar1_addr == 0)) { if ((bar1_size == 0) || (bar1_addr == 0)) {
brcmf_err("BAR1 Not enabled, device size=%ld, addr=%#016llx\n", brcmf_err(bus, "BAR1 Not enabled, device size=%ld, addr=%#016llx\n",
bar1_size, (unsigned long long)bar1_addr); bar1_size, (unsigned long long)bar1_addr);
return -EINVAL; return -EINVAL;
} }
@ -1586,7 +1604,7 @@ static int brcmf_pcie_get_resource(struct brcmf_pciedev_info *devinfo)
devinfo->tcm = ioremap_nocache(bar1_addr, bar1_size); devinfo->tcm = ioremap_nocache(bar1_addr, bar1_size);
if (!devinfo->regs || !devinfo->tcm) { if (!devinfo->regs || !devinfo->tcm) {
brcmf_err("ioremap() failed (%p,%p)\n", devinfo->regs, brcmf_err(bus, "ioremap() failed (%p,%p)\n", devinfo->regs,
devinfo->tcm); devinfo->tcm);
return -EINVAL; return -EINVAL;
} }
@ -1873,7 +1891,7 @@ brcmf_pcie_probe(struct pci_dev *pdev, const struct pci_device_id *id)
kfree(bus->msgbuf); kfree(bus->msgbuf);
kfree(bus); kfree(bus);
fail: fail:
brcmf_err("failed %x:%x\n", pdev->vendor, pdev->device); brcmf_err(NULL, "failed %x:%x\n", pdev->vendor, pdev->device);
brcmf_pcie_release_resource(devinfo); brcmf_pcie_release_resource(devinfo);
if (devinfo->ci) if (devinfo->ci)
brcmf_chip_detach(devinfo->ci); brcmf_chip_detach(devinfo->ci);
@ -1947,7 +1965,7 @@ static int brcmf_pcie_pm_enter_D3(struct device *dev)
wait_event_timeout(devinfo->mbdata_resp_wait, devinfo->mbdata_completed, wait_event_timeout(devinfo->mbdata_resp_wait, devinfo->mbdata_completed,
BRCMF_PCIE_MBDATA_TIMEOUT); BRCMF_PCIE_MBDATA_TIMEOUT);
if (!devinfo->mbdata_completed) { if (!devinfo->mbdata_completed) {
brcmf_err("Timeout on response for entering D3 substate\n"); brcmf_err(bus, "Timeout on response for entering D3 substate\n");
brcmf_bus_change_state(bus, BRCMF_BUS_UP); brcmf_bus_change_state(bus, BRCMF_BUS_UP);
return -EIO; return -EIO;
} }
@ -1993,7 +2011,7 @@ static int brcmf_pcie_pm_leave_D3(struct device *dev)
err = brcmf_pcie_probe(pdev, NULL); err = brcmf_pcie_probe(pdev, NULL);
if (err) if (err)
brcmf_err("probe after resume failed, err=%d\n", err); brcmf_err(bus, "probe after resume failed, err=%d\n", err);
return err; return err;
} }
@ -2064,7 +2082,8 @@ void brcmf_pcie_register(void)
brcmf_dbg(PCIE, "Enter\n"); brcmf_dbg(PCIE, "Enter\n");
err = pci_register_driver(&brcmf_pciedrvr); err = pci_register_driver(&brcmf_pciedrvr);
if (err) if (err)
brcmf_err("PCIE driver registration failed, err=%d\n", err); brcmf_err(NULL, "PCIE driver registration failed, err=%d\n",
err);
} }

View File

@ -109,6 +109,7 @@ static int brcmf_pno_channel_config(struct brcmf_if *ifp,
static int brcmf_pno_config(struct brcmf_if *ifp, u32 scan_freq, static int brcmf_pno_config(struct brcmf_if *ifp, u32 scan_freq,
u32 mscan, u32 bestn) u32 mscan, u32 bestn)
{ {
struct brcmf_pub *drvr = ifp->drvr;
struct brcmf_pno_param_le pfn_param; struct brcmf_pno_param_le pfn_param;
u16 flags; u16 flags;
u32 pfnmem; u32 pfnmem;
@ -132,13 +133,13 @@ static int brcmf_pno_config(struct brcmf_if *ifp, u32 scan_freq,
/* set bestn in firmware */ /* set bestn in firmware */
err = brcmf_fil_iovar_int_set(ifp, "pfnmem", pfnmem); err = brcmf_fil_iovar_int_set(ifp, "pfnmem", pfnmem);
if (err < 0) { if (err < 0) {
brcmf_err("failed to set pfnmem\n"); bphy_err(drvr, "failed to set pfnmem\n");
goto exit; goto exit;
} }
/* get max mscan which the firmware supports */ /* get max mscan which the firmware supports */
err = brcmf_fil_iovar_int_get(ifp, "pfnmem", &pfnmem); err = brcmf_fil_iovar_int_get(ifp, "pfnmem", &pfnmem);
if (err < 0) { if (err < 0) {
brcmf_err("failed to get pfnmem\n"); bphy_err(drvr, "failed to get pfnmem\n");
goto exit; goto exit;
} }
mscan = min_t(u32, mscan, pfnmem); mscan = min_t(u32, mscan, pfnmem);
@ -152,7 +153,7 @@ static int brcmf_pno_config(struct brcmf_if *ifp, u32 scan_freq,
err = brcmf_fil_iovar_data_set(ifp, "pfn_set", &pfn_param, err = brcmf_fil_iovar_data_set(ifp, "pfn_set", &pfn_param,
sizeof(pfn_param)); sizeof(pfn_param));
if (err) if (err)
brcmf_err("pfn_set failed, err=%d\n", err); bphy_err(drvr, "pfn_set failed, err=%d\n", err);
exit: exit:
return err; return err;
@ -160,6 +161,7 @@ static int brcmf_pno_config(struct brcmf_if *ifp, u32 scan_freq,
static int brcmf_pno_set_random(struct brcmf_if *ifp, struct brcmf_pno_info *pi) static int brcmf_pno_set_random(struct brcmf_if *ifp, struct brcmf_pno_info *pi)
{ {
struct brcmf_pub *drvr = ifp->drvr;
struct brcmf_pno_macaddr_le pfn_mac; struct brcmf_pno_macaddr_le pfn_mac;
u8 *mac_addr = NULL; u8 *mac_addr = NULL;
u8 *mac_mask = NULL; u8 *mac_mask = NULL;
@ -194,7 +196,7 @@ static int brcmf_pno_set_random(struct brcmf_if *ifp, struct brcmf_pno_info *pi)
err = brcmf_fil_iovar_data_set(ifp, "pfn_macaddr", &pfn_mac, err = brcmf_fil_iovar_data_set(ifp, "pfn_macaddr", &pfn_mac,
sizeof(pfn_mac)); sizeof(pfn_mac));
if (err) if (err)
brcmf_err("pfn_macaddr failed, err=%d\n", err); bphy_err(drvr, "pfn_macaddr failed, err=%d\n", err);
return err; return err;
} }
@ -202,6 +204,7 @@ static int brcmf_pno_set_random(struct brcmf_if *ifp, struct brcmf_pno_info *pi)
static int brcmf_pno_add_ssid(struct brcmf_if *ifp, struct cfg80211_ssid *ssid, static int brcmf_pno_add_ssid(struct brcmf_if *ifp, struct cfg80211_ssid *ssid,
bool active) bool active)
{ {
struct brcmf_pub *drvr = ifp->drvr;
struct brcmf_pno_net_param_le pfn; struct brcmf_pno_net_param_le pfn;
int err; int err;
@ -218,12 +221,13 @@ static int brcmf_pno_add_ssid(struct brcmf_if *ifp, struct cfg80211_ssid *ssid,
brcmf_dbg(SCAN, "adding ssid=%.32s (active=%d)\n", ssid->ssid, active); brcmf_dbg(SCAN, "adding ssid=%.32s (active=%d)\n", ssid->ssid, active);
err = brcmf_fil_iovar_data_set(ifp, "pfn_add", &pfn, sizeof(pfn)); err = brcmf_fil_iovar_data_set(ifp, "pfn_add", &pfn, sizeof(pfn));
if (err < 0) if (err < 0)
brcmf_err("adding failed: err=%d\n", err); bphy_err(drvr, "adding failed: err=%d\n", err);
return err; return err;
} }
static int brcmf_pno_add_bssid(struct brcmf_if *ifp, const u8 *bssid) static int brcmf_pno_add_bssid(struct brcmf_if *ifp, const u8 *bssid)
{ {
struct brcmf_pub *drvr = ifp->drvr;
struct brcmf_pno_bssid_le bssid_cfg; struct brcmf_pno_bssid_le bssid_cfg;
int err; int err;
@ -234,7 +238,7 @@ static int brcmf_pno_add_bssid(struct brcmf_if *ifp, const u8 *bssid)
err = brcmf_fil_iovar_data_set(ifp, "pfn_add_bssid", &bssid_cfg, err = brcmf_fil_iovar_data_set(ifp, "pfn_add_bssid", &bssid_cfg,
sizeof(bssid_cfg)); sizeof(bssid_cfg));
if (err < 0) if (err < 0)
brcmf_err("adding failed: err=%d\n", err); bphy_err(drvr, "adding failed: err=%d\n", err);
return err; return err;
} }
@ -258,6 +262,7 @@ static bool brcmf_is_ssid_active(struct cfg80211_ssid *ssid,
static int brcmf_pno_clean(struct brcmf_if *ifp) static int brcmf_pno_clean(struct brcmf_if *ifp)
{ {
struct brcmf_pub *drvr = ifp->drvr;
int ret; int ret;
/* Disable pfn */ /* Disable pfn */
@ -267,7 +272,7 @@ static int brcmf_pno_clean(struct brcmf_if *ifp)
ret = brcmf_fil_iovar_data_set(ifp, "pfnclear", NULL, 0); ret = brcmf_fil_iovar_data_set(ifp, "pfnclear", NULL, 0);
} }
if (ret < 0) if (ret < 0)
brcmf_err("failed code %d\n", ret); bphy_err(drvr, "failed code %d\n", ret);
return ret; return ret;
} }
@ -392,6 +397,7 @@ static int brcmf_pno_config_networks(struct brcmf_if *ifp,
static int brcmf_pno_config_sched_scans(struct brcmf_if *ifp) static int brcmf_pno_config_sched_scans(struct brcmf_if *ifp)
{ {
struct brcmf_pub *drvr = ifp->drvr;
struct brcmf_pno_info *pi; struct brcmf_pno_info *pi;
struct brcmf_gscan_config *gscan_cfg; struct brcmf_gscan_config *gscan_cfg;
struct brcmf_gscan_bucket_config *buckets; struct brcmf_gscan_bucket_config *buckets;
@ -416,7 +422,7 @@ static int brcmf_pno_config_sched_scans(struct brcmf_if *ifp)
/* clean up everything */ /* clean up everything */
err = brcmf_pno_clean(ifp); err = brcmf_pno_clean(ifp);
if (err < 0) { if (err < 0) {
brcmf_err("failed error=%d\n", err); bphy_err(drvr, "failed error=%d\n", err);
goto free_gscan; goto free_gscan;
} }

View File

@ -47,7 +47,7 @@ int brcmf_proto_attach(struct brcmf_pub *drvr)
if (brcmf_proto_msgbuf_attach(drvr)) if (brcmf_proto_msgbuf_attach(drvr))
goto fail; goto fail;
} else { } else {
brcmf_err("Unsupported proto type %d\n", bphy_err(drvr, "Unsupported proto type %d\n",
drvr->bus_if->proto_type); drvr->bus_if->proto_type);
goto fail; goto fail;
} }
@ -56,7 +56,7 @@ int brcmf_proto_attach(struct brcmf_pub *drvr)
(proto->configure_addr_mode == NULL) || (proto->configure_addr_mode == NULL) ||
(proto->delete_peer == NULL) || (proto->add_tdls_peer == NULL) || (proto->delete_peer == NULL) || (proto->add_tdls_peer == NULL) ||
(proto->debugfs_create == NULL)) { (proto->debugfs_create == NULL)) {
brcmf_err("Not all proto handlers have been installed\n"); bphy_err(drvr, "Not all proto handlers have been installed\n");
goto fail; goto fail;
} }
return 0; return 0;

View File

@ -2999,6 +2999,7 @@ static int brcmf_sdio_trap_info(struct seq_file *seq, struct brcmf_sdio *bus,
if (error < 0) if (error < 0)
return error; return error;
if (seq)
seq_printf(seq, seq_printf(seq,
"dongle trap info: type 0x%x @ epc 0x%08x\n" "dongle trap info: type 0x%x @ epc 0x%08x\n"
" cpsr 0x%08x spsr 0x%08x sp 0x%08x\n" " cpsr 0x%08x spsr 0x%08x sp 0x%08x\n"
@ -3013,7 +3014,20 @@ static int brcmf_sdio_trap_info(struct seq_file *seq, struct brcmf_sdio *bus,
le32_to_cpu(tr.r2), le32_to_cpu(tr.r3), le32_to_cpu(tr.r2), le32_to_cpu(tr.r3),
le32_to_cpu(tr.r4), le32_to_cpu(tr.r5), le32_to_cpu(tr.r4), le32_to_cpu(tr.r5),
le32_to_cpu(tr.r6), le32_to_cpu(tr.r7)); le32_to_cpu(tr.r6), le32_to_cpu(tr.r7));
else
pr_debug("dongle trap info: type 0x%x @ epc 0x%08x\n"
" cpsr 0x%08x spsr 0x%08x sp 0x%08x\n"
" lr 0x%08x pc 0x%08x offset 0x%x\n"
" r0 0x%08x r1 0x%08x r2 0x%08x r3 0x%08x\n"
" r4 0x%08x r5 0x%08x r6 0x%08x r7 0x%08x\n",
le32_to_cpu(tr.type), le32_to_cpu(tr.epc),
le32_to_cpu(tr.cpsr), le32_to_cpu(tr.spsr),
le32_to_cpu(tr.r13), le32_to_cpu(tr.r14),
le32_to_cpu(tr.pc), sh->trap_addr,
le32_to_cpu(tr.r0), le32_to_cpu(tr.r1),
le32_to_cpu(tr.r2), le32_to_cpu(tr.r3),
le32_to_cpu(tr.r4), le32_to_cpu(tr.r5),
le32_to_cpu(tr.r6), le32_to_cpu(tr.r7));
return 0; return 0;
} }
@ -3067,8 +3081,10 @@ static int brcmf_sdio_checkdied(struct brcmf_sdio *bus)
else if (sh.flags & SDPCM_SHARED_ASSERT) else if (sh.flags & SDPCM_SHARED_ASSERT)
brcmf_err("assertion in dongle\n"); brcmf_err("assertion in dongle\n");
if (sh.flags & SDPCM_SHARED_TRAP) if (sh.flags & SDPCM_SHARED_TRAP) {
brcmf_err("firmware trap in dongle\n"); brcmf_err("firmware trap in dongle\n");
brcmf_sdio_trap_info(NULL, bus, &sh);
}
return 0; return 0;
} }
@ -3143,9 +3159,12 @@ static int brcmf_debugfs_sdio_count_read(struct seq_file *seq, void *data)
return 0; return 0;
} }
static void brcmf_sdio_debugfs_create(struct brcmf_sdio *bus) static void brcmf_sdio_debugfs_create(struct device *dev)
{ {
struct brcmf_pub *drvr = bus->sdiodev->bus_if->drvr; struct brcmf_bus *bus_if = dev_get_drvdata(dev);
struct brcmf_pub *drvr = bus_if->drvr;
struct brcmf_sdio_dev *sdiodev = bus_if->bus_priv.sdio;
struct brcmf_sdio *bus = sdiodev->bus;
struct dentry *dentry = brcmf_debugfs_get_devdir(drvr); struct dentry *dentry = brcmf_debugfs_get_devdir(drvr);
if (IS_ERR_OR_NULL(dentry)) if (IS_ERR_OR_NULL(dentry))
@ -3165,7 +3184,7 @@ static int brcmf_sdio_checkdied(struct brcmf_sdio *bus)
return 0; return 0;
} }
static void brcmf_sdio_debugfs_create(struct brcmf_sdio *bus) static void brcmf_sdio_debugfs_create(struct device *dev)
{ {
} }
#endif /* DEBUG */ #endif /* DEBUG */
@ -3477,8 +3496,6 @@ static int brcmf_sdio_bus_preinit(struct device *dev)
if (bus->rxbuf) if (bus->rxbuf)
bus->rxblen = value; bus->rxblen = value;
brcmf_sdio_debugfs_create(bus);
/* the commands below use the terms tx and rx from /* the commands below use the terms tx and rx from
* a device perspective, ie. bus:txglom affects the * a device perspective, ie. bus:txglom affects the
* bus transfers from device to host. * bus transfers from device to host.
@ -4088,6 +4105,7 @@ static const struct brcmf_bus_ops brcmf_sdio_bus_ops = {
.get_ramsize = brcmf_sdio_bus_get_ramsize, .get_ramsize = brcmf_sdio_bus_get_ramsize,
.get_memdump = brcmf_sdio_bus_get_memdump, .get_memdump = brcmf_sdio_bus_get_memdump,
.get_fwname = brcmf_sdio_get_fwname, .get_fwname = brcmf_sdio_get_fwname,
.debugfs_create = brcmf_sdio_debugfs_create
}; };
#define BRCMF_SDIO_FW_CODE 0 #define BRCMF_SDIO_FW_CODE 0
@ -4197,7 +4215,7 @@ static void brcmf_sdio_firmware_callback(struct device *dev, int err,
} else { } else {
/* Disable F2 again */ /* Disable F2 again */
sdio_disable_func(sdiod->func2); sdio_disable_func(sdiod->func2);
goto release; goto checkdied;
} }
if (brcmf_chip_sr_capable(bus->ci)) { if (brcmf_chip_sr_capable(bus->ci)) {
@ -4218,8 +4236,10 @@ static void brcmf_sdio_firmware_callback(struct device *dev, int err,
} }
/* If we didn't come up, turn off backplane clock */ /* If we didn't come up, turn off backplane clock */
if (err != 0) if (err != 0) {
brcmf_sdio_clkctl(bus, CLK_NONE, false); brcmf_sdio_clkctl(bus, CLK_NONE, false);
goto checkdied;
}
sdio_release_host(sdiod->func1); sdio_release_host(sdiod->func1);
@ -4233,12 +4253,15 @@ static void brcmf_sdio_firmware_callback(struct device *dev, int err,
err = brcmf_attach(sdiod->dev, sdiod->settings); err = brcmf_attach(sdiod->dev, sdiod->settings);
if (err != 0) { if (err != 0) {
brcmf_err("brcmf_attach failed\n"); brcmf_err("brcmf_attach failed\n");
goto fail; sdio_claim_host(sdiod->func1);
goto checkdied;
} }
/* ready */ /* ready */
return; return;
checkdied:
brcmf_sdio_checkdied(bus);
release: release:
sdio_release_host(sdiod->func1); sdio_release_host(sdiod->func1);
fail: fail:

View File

@ -14,14 +14,16 @@
* CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/ */
#include <linux/device.h>
#include <linux/module.h> /* bug in tracepoint.h, it should include this */ #include <linux/module.h> /* bug in tracepoint.h, it should include this */
#ifndef __CHECKER__ #ifndef __CHECKER__
#define CREATE_TRACE_POINTS #define CREATE_TRACE_POINTS
#include "bus.h"
#include "tracepoint.h" #include "tracepoint.h"
#include "debug.h" #include "debug.h"
void __brcmf_err(const char *func, const char *fmt, ...) void __brcmf_err(struct brcmf_bus *bus, const char *func, const char *fmt, ...)
{ {
struct va_format vaf = { struct va_format vaf = {
.fmt = fmt, .fmt = fmt,
@ -30,6 +32,9 @@ void __brcmf_err(const char *func, const char *fmt, ...)
va_start(args, fmt); va_start(args, fmt);
vaf.va = &args; vaf.va = &args;
if (bus)
dev_err(bus->dev, "%s: %pV", func, &vaf);
else
pr_err("%s: %pV", func, &vaf); pr_err("%s: %pV", func, &vaf);
trace_brcmf_err(func, &vaf); trace_brcmf_err(func, &vaf);
va_end(args); va_end(args);

View File

@ -508,7 +508,7 @@ static void brcmf_usb_rx_complete(struct urb *urb)
skb = req->skb; skb = req->skb;
req->skb = NULL; req->skb = NULL;
/* zero lenght packets indicate usb "failure". Do not refill */ /* zero length packets indicate usb "failure". Do not refill */
if (urb->status != 0 || !urb->actual_length) { if (urb->status != 0 || !urb->actual_length) {
brcmu_pkt_buf_free_skb(skb); brcmu_pkt_buf_free_skb(skb);
brcmf_usb_enq(devinfo, &devinfo->rx_freeq, req, NULL); brcmf_usb_enq(devinfo, &devinfo->rx_freeq, req, NULL);
@ -575,7 +575,6 @@ static void
brcmf_usb_state_change(struct brcmf_usbdev_info *devinfo, int state) brcmf_usb_state_change(struct brcmf_usbdev_info *devinfo, int state)
{ {
struct brcmf_bus *bcmf_bus = devinfo->bus_pub.bus; struct brcmf_bus *bcmf_bus = devinfo->bus_pub.bus;
int old_state;
brcmf_dbg(USB, "Enter, current state=%d, new state=%d\n", brcmf_dbg(USB, "Enter, current state=%d, new state=%d\n",
devinfo->bus_pub.state, state); devinfo->bus_pub.state, state);
@ -583,7 +582,6 @@ brcmf_usb_state_change(struct brcmf_usbdev_info *devinfo, int state)
if (devinfo->bus_pub.state == state) if (devinfo->bus_pub.state == state)
return; return;
old_state = devinfo->bus_pub.state;
devinfo->bus_pub.state = state; devinfo->bus_pub.state = state;
/* update state of upper layer */ /* update state of upper layer */

View File

@ -6,7 +6,7 @@
* GPL LICENSE SUMMARY * GPL LICENSE SUMMARY
* *
* Copyright(c) 2015-2017 Intel Deutschland GmbH * Copyright(c) 2015-2017 Intel Deutschland GmbH
* Copyright (C) 2018 Intel Corporation * Copyright (C) 2018-2019 Intel Corporation
* *
* This program is free software; you can redistribute it and/or modify * This program is free software; you can redistribute it and/or modify
* it under the terms of version 2 of the GNU General Public License as * it under the terms of version 2 of the GNU General Public License as
@ -20,7 +20,7 @@
* BSD LICENSE * BSD LICENSE
* *
* Copyright(c) 2015-2017 Intel Deutschland GmbH * Copyright(c) 2015-2017 Intel Deutschland GmbH
* Copyright (C) 2018 Intel Corporation * Copyright (C) 2018-2019 Intel Corporation
* All rights reserved. * All rights reserved.
* *
* Redistribution and use in source and binary forms, with or without * Redistribution and use in source and binary forms, with or without
@ -56,7 +56,7 @@
#include "iwl-config.h" #include "iwl-config.h"
/* Highest firmware API version supported */ /* Highest firmware API version supported */
#define IWL_22000_UCODE_API_MAX 43 #define IWL_22000_UCODE_API_MAX 46
/* Lowest firmware API version supported */ /* Lowest firmware API version supported */
#define IWL_22000_UCODE_API_MIN 39 #define IWL_22000_UCODE_API_MIN 39
@ -79,11 +79,15 @@
#define IWL_22000_HR_B_F0_FW_PRE "iwlwifi-Qu-b0-hr-b0-" #define IWL_22000_HR_B_F0_FW_PRE "iwlwifi-Qu-b0-hr-b0-"
#define IWL_22000_QU_B_HR_B_FW_PRE "iwlwifi-Qu-b0-hr-b0-" #define IWL_22000_QU_B_HR_B_FW_PRE "iwlwifi-Qu-b0-hr-b0-"
#define IWL_22000_HR_B_FW_PRE "iwlwifi-QuQnj-b0-hr-b0-" #define IWL_22000_HR_B_FW_PRE "iwlwifi-QuQnj-b0-hr-b0-"
#define IWL_22000_JF_B0_FW_PRE "iwlwifi-QuQnj-a0-jf-b0-"
#define IWL_22000_HR_A0_FW_PRE "iwlwifi-QuQnj-a0-hr-a0-" #define IWL_22000_HR_A0_FW_PRE "iwlwifi-QuQnj-a0-hr-a0-"
#define IWL_22000_SU_Z0_FW_PRE "iwlwifi-su-z0-" #define IWL_22000_SU_Z0_FW_PRE "iwlwifi-su-z0-"
#define IWL_QU_B_JF_B_FW_PRE "iwlwifi-Qu-b0-jf-b0-" #define IWL_QU_B_JF_B_FW_PRE "iwlwifi-Qu-b0-jf-b0-"
#define IWL_QNJ_B_JF_B_FW_PRE "iwlwifi-QuQnj-b0-jf-b0-"
#define IWL_CC_A_FW_PRE "iwlwifi-cc-a0-" #define IWL_CC_A_FW_PRE "iwlwifi-cc-a0-"
#define IWL_22000_SO_A_JF_B_FW_PRE "iwlwifi-so-a0-jf-b0-"
#define IWL_22000_SO_A_HR_B_FW_PRE "iwlwifi-so-a0-hr-b0-"
#define IWL_22000_SO_A_GF_A_FW_PRE "iwlwifi-so-a0-gf-a0-"
#define IWL_22000_TY_A_GF_A_FW_PRE "iwlwifi-ty-a0-gf-a0-"
#define IWL_22000_HR_MODULE_FIRMWARE(api) \ #define IWL_22000_HR_MODULE_FIRMWARE(api) \
IWL_22000_HR_FW_PRE __stringify(api) ".ucode" IWL_22000_HR_FW_PRE __stringify(api) ".ucode"
@ -97,16 +101,26 @@
IWL_22000_QU_B_HR_B_FW_PRE __stringify(api) ".ucode" IWL_22000_QU_B_HR_B_FW_PRE __stringify(api) ".ucode"
#define IWL_22000_HR_B_QNJ_MODULE_FIRMWARE(api) \ #define IWL_22000_HR_B_QNJ_MODULE_FIRMWARE(api) \
IWL_22000_HR_B_FW_PRE __stringify(api) ".ucode" IWL_22000_HR_B_FW_PRE __stringify(api) ".ucode"
#define IWL_22000_JF_B0_QNJ_MODULE_FIRMWARE(api) \
IWL_22000_JF_B0_FW_PRE __stringify(api) ".ucode"
#define IWL_22000_HR_A0_QNJ_MODULE_FIRMWARE(api) \ #define IWL_22000_HR_A0_QNJ_MODULE_FIRMWARE(api) \
IWL_22000_HR_A0_FW_PRE __stringify(api) ".ucode" IWL_22000_HR_A0_FW_PRE __stringify(api) ".ucode"
#define IWL_22000_SU_Z0_MODULE_FIRMWARE(api) \ #define IWL_22000_SU_Z0_MODULE_FIRMWARE(api) \
IWL_22000_SU_Z0_FW_PRE __stringify(api) ".ucode" IWL_22000_SU_Z0_FW_PRE __stringify(api) ".ucode"
#define IWL_QU_B_JF_B_MODULE_FIRMWARE(api) \ #define IWL_QU_B_JF_B_MODULE_FIRMWARE(api) \
IWL_QU_B_JF_B_FW_PRE __stringify(api) ".ucode" IWL_QU_B_JF_B_FW_PRE __stringify(api) ".ucode"
#define IWL_QU_B_JF_B_MODULE_FIRMWARE(api) \
IWL_QU_B_JF_B_FW_PRE __stringify(api) ".ucode"
#define IWL_QNJ_B_JF_B_MODULE_FIRMWARE(api) \
IWL_QNJ_B_JF_B_FW_PRE __stringify(api) ".ucode"
#define IWL_CC_A_MODULE_FIRMWARE(api) \ #define IWL_CC_A_MODULE_FIRMWARE(api) \
IWL_CC_A_FW_PRE __stringify(api) ".ucode" IWL_CC_A_FW_PRE __stringify(api) ".ucode"
#define IWL_22000_SO_A_JF_B_MODULE_FIRMWARE(api) \
IWL_22000_SO_A_JF_B_FW_PRE __stringify(api) ".ucode"
#define IWL_22000_SO_A_HR_B_MODULE_FIRMWARE(api) \
IWL_22000_SO_A_HR_B_FW_PRE __stringify(api) ".ucode"
#define IWL_22000_SO_A_GF_A_MODULE_FIRMWARE(api) \
IWL_22000_SO_A_GF_A_FW_PRE __stringify(api) ".ucode"
#define IWL_22000_TY_A_GF_A_MODULE_FIRMWARE(api) \
IWL_22000_TY_A_GF_A_FW_PRE __stringify(api) ".ucode"
static const struct iwl_base_params iwl_22000_base_params = { static const struct iwl_base_params iwl_22000_base_params = {
.eeprom_size = OTP_LOW_IMAGE_SIZE_32K, .eeprom_size = OTP_LOW_IMAGE_SIZE_32K,
@ -167,6 +181,10 @@ static const struct iwl_ht_params iwl_22000_ht_params = {
.d3_debug_data_base_addr = 0x401000, \ .d3_debug_data_base_addr = 0x401000, \
.d3_debug_data_length = 60 * 1024 .d3_debug_data_length = 60 * 1024
#define IWL_DEVICE_AX200_COMMON \
IWL_DEVICE_22000_COMMON, \
.umac_prph_offset = 0x300000
#define IWL_DEVICE_22500 \ #define IWL_DEVICE_22500 \
IWL_DEVICE_22000_COMMON, \ IWL_DEVICE_22000_COMMON, \
.device_family = IWL_DEVICE_FAMILY_22000, \ .device_family = IWL_DEVICE_FAMILY_22000, \
@ -179,6 +197,13 @@ static const struct iwl_ht_params iwl_22000_ht_params = {
.base_params = &iwl_22560_base_params, \ .base_params = &iwl_22560_base_params, \
.csr = &iwl_csr_v2 .csr = &iwl_csr_v2
#define IWL_DEVICE_AX210 \
IWL_DEVICE_AX200_COMMON, \
.device_family = IWL_DEVICE_FAMILY_AX210, \
.base_params = &iwl_22000_base_params, \
.csr = &iwl_csr_v1, \
.min_txq_size = 128
const struct iwl_cfg iwl22000_2ac_cfg_hr = { const struct iwl_cfg iwl22000_2ac_cfg_hr = {
.name = "Intel(R) Dual Band Wireless AC 22000", .name = "Intel(R) Dual Band Wireless AC 22000",
.fw_name_pre = IWL_22000_HR_FW_PRE, .fw_name_pre = IWL_22000_HR_FW_PRE,
@ -198,8 +223,8 @@ const struct iwl_cfg iwl22000_2ac_cfg_jf = {
IWL_DEVICE_22500, IWL_DEVICE_22500,
}; };
const struct iwl_cfg iwl22560_2ax_cfg_hr = { const struct iwl_cfg iwl_ax101_cfg_qu_hr = {
.name = "Intel(R) Wireless-AX 22560", .name = "Intel(R) Wi-Fi 6 AX101",
.fw_name_pre = IWL_22000_QU_B_HR_B_FW_PRE, .fw_name_pre = IWL_22000_QU_B_HR_B_FW_PRE,
IWL_DEVICE_22500, IWL_DEVICE_22500,
/* /*
@ -220,10 +245,11 @@ const struct iwl_cfg iwl22260_2ax_cfg = {
* HT size; mac80211 would otherwise pick the HE max (256) by default. * HT size; mac80211 would otherwise pick the HE max (256) by default.
*/ */
.max_tx_agg_size = IEEE80211_MAX_AMPDU_BUF_HT, .max_tx_agg_size = IEEE80211_MAX_AMPDU_BUF_HT,
.bisr_workaround = 1,
}; };
const struct iwl_cfg killer1650x_2ax_cfg = { const struct iwl_cfg killer1650x_2ax_cfg = {
.name = "Killer(R) Wireless-AX 1650x Wireless Network Adapter (22260NGW)", .name = "Killer(R) Wireless-AX 1650x Wireless Network Adapter (200NGW)",
.fw_name_pre = IWL_CC_A_FW_PRE, .fw_name_pre = IWL_CC_A_FW_PRE,
IWL_DEVICE_22500, IWL_DEVICE_22500,
/* /*
@ -232,10 +258,11 @@ const struct iwl_cfg killer1650x_2ax_cfg = {
* HT size; mac80211 would otherwise pick the HE max (256) by default. * HT size; mac80211 would otherwise pick the HE max (256) by default.
*/ */
.max_tx_agg_size = IEEE80211_MAX_AMPDU_BUF_HT, .max_tx_agg_size = IEEE80211_MAX_AMPDU_BUF_HT,
.bisr_workaround = 1,
}; };
const struct iwl_cfg killer1650w_2ax_cfg = { const struct iwl_cfg killer1650w_2ax_cfg = {
.name = "Killer(R) Wireless-AX 1650w Wireless Network Adapter (22260D2W)", .name = "Killer(R) Wireless-AX 1650w Wireless Network Adapter (200D2W)",
.fw_name_pre = IWL_CC_A_FW_PRE, .fw_name_pre = IWL_CC_A_FW_PRE,
IWL_DEVICE_22500, IWL_DEVICE_22500,
/* /*
@ -244,6 +271,7 @@ const struct iwl_cfg killer1650w_2ax_cfg = {
* HT size; mac80211 would otherwise pick the HE max (256) by default. * HT size; mac80211 would otherwise pick the HE max (256) by default.
*/ */
.max_tx_agg_size = IEEE80211_MAX_AMPDU_BUF_HT, .max_tx_agg_size = IEEE80211_MAX_AMPDU_BUF_HT,
.bisr_workaround = 1,
}; };
/* /*
@ -275,6 +303,18 @@ const struct iwl_cfg iwl9560_2ac_160_cfg_qu_b0_jf_b0 = {
IWL_DEVICE_22500, IWL_DEVICE_22500,
}; };
const struct iwl_cfg iwl9560_2ac_cfg_qnj_jf_b0 = {
.name = "Intel(R) Wireless-AC 9560 160MHz",
.fw_name_pre = IWL_QNJ_B_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,
};
const struct iwl_cfg killer1550i_2ac_cfg_qu_b0_jf_b0 = { const struct iwl_cfg killer1550i_2ac_cfg_qu_b0_jf_b0 = {
.name = "Killer (R) Wireless-AC 1550i Wireless Network Adapter (9560NGW)", .name = "Killer (R) Wireless-AC 1550i Wireless Network Adapter (9560NGW)",
.fw_name_pre = IWL_QU_B_JF_B_FW_PRE, .fw_name_pre = IWL_QU_B_JF_B_FW_PRE,
@ -347,18 +387,6 @@ const struct iwl_cfg iwl22000_2ax_cfg_qnj_hr_b0 = {
.max_tx_agg_size = IEEE80211_MAX_AMPDU_BUF_HT, .max_tx_agg_size = IEEE80211_MAX_AMPDU_BUF_HT,
}; };
const struct iwl_cfg iwl22000_2ax_cfg_qnj_jf_b0 = {
.name = "Intel(R) Dual Band Wireless AX 22000",
.fw_name_pre = IWL_22000_JF_B0_FW_PRE,
IWL_DEVICE_22500,
/*
* This device doesn't support receiving BlockAck with a large bitmap
* so we need to restrict the size of transmitted aggregation to the
* HT size; mac80211 would otherwise pick the HE max (256) by default.
*/
.max_tx_agg_size = IEEE80211_MAX_AMPDU_BUF_HT,
};
const struct iwl_cfg iwl22000_2ax_cfg_qnj_hr_a0 = { const struct iwl_cfg iwl22000_2ax_cfg_qnj_hr_a0 = {
.name = "Intel(R) Dual Band Wireless AX 22000", .name = "Intel(R) Dual Band Wireless AX 22000",
.fw_name_pre = IWL_22000_HR_A0_FW_PRE, .fw_name_pre = IWL_22000_HR_A0_FW_PRE,
@ -384,13 +412,41 @@ const struct iwl_cfg iwl22560_2ax_cfg_su_cdb = {
.max_tx_agg_size = IEEE80211_MAX_AMPDU_BUF_HT, .max_tx_agg_size = IEEE80211_MAX_AMPDU_BUF_HT,
}; };
const struct iwl_cfg iwlax210_2ax_cfg_so_jf_a0 = {
.name = "Intel(R) Wireless-AC 9560 160MHz",
.fw_name_pre = IWL_22000_SO_A_JF_B_FW_PRE,
IWL_DEVICE_AX210,
};
const struct iwl_cfg iwlax210_2ax_cfg_so_hr_a0 = {
.name = "Intel(R) Wi-Fi 6 AX201 160MHz",
.fw_name_pre = IWL_22000_SO_A_HR_B_FW_PRE,
IWL_DEVICE_AX210,
};
const struct iwl_cfg iwlax210_2ax_cfg_so_gf_a0 = {
.name = "Intel(R) Wi-Fi 7 AX211 160MHz",
.fw_name_pre = IWL_22000_SO_A_GF_A_FW_PRE,
IWL_DEVICE_AX210,
};
const struct iwl_cfg iwlax210_2ax_cfg_ty_gf_a0 = {
.name = "Intel(R) Wi-Fi 7 AX210 160MHz",
.fw_name_pre = IWL_22000_TY_A_GF_A_FW_PRE,
IWL_DEVICE_AX210,
};
MODULE_FIRMWARE(IWL_22000_HR_MODULE_FIRMWARE(IWL_22000_UCODE_API_MAX)); MODULE_FIRMWARE(IWL_22000_HR_MODULE_FIRMWARE(IWL_22000_UCODE_API_MAX));
MODULE_FIRMWARE(IWL_22000_JF_MODULE_FIRMWARE(IWL_22000_UCODE_API_MAX)); MODULE_FIRMWARE(IWL_22000_JF_MODULE_FIRMWARE(IWL_22000_UCODE_API_MAX));
MODULE_FIRMWARE(IWL_22000_HR_A_F0_QNJ_MODULE_FIRMWARE(IWL_22000_UCODE_API_MAX)); MODULE_FIRMWARE(IWL_22000_HR_A_F0_QNJ_MODULE_FIRMWARE(IWL_22000_UCODE_API_MAX));
MODULE_FIRMWARE(IWL_22000_HR_B_F0_QNJ_MODULE_FIRMWARE(IWL_22000_UCODE_API_MAX)); MODULE_FIRMWARE(IWL_22000_HR_B_F0_QNJ_MODULE_FIRMWARE(IWL_22000_UCODE_API_MAX));
MODULE_FIRMWARE(IWL_22000_HR_B_QNJ_MODULE_FIRMWARE(IWL_22000_UCODE_API_MAX)); MODULE_FIRMWARE(IWL_22000_HR_B_QNJ_MODULE_FIRMWARE(IWL_22000_UCODE_API_MAX));
MODULE_FIRMWARE(IWL_22000_JF_B0_QNJ_MODULE_FIRMWARE(IWL_22000_UCODE_API_MAX));
MODULE_FIRMWARE(IWL_22000_HR_A0_QNJ_MODULE_FIRMWARE(IWL_22000_UCODE_API_MAX)); MODULE_FIRMWARE(IWL_22000_HR_A0_QNJ_MODULE_FIRMWARE(IWL_22000_UCODE_API_MAX));
MODULE_FIRMWARE(IWL_22000_SU_Z0_MODULE_FIRMWARE(IWL_22000_UCODE_API_MAX)); MODULE_FIRMWARE(IWL_22000_SU_Z0_MODULE_FIRMWARE(IWL_22000_UCODE_API_MAX));
MODULE_FIRMWARE(IWL_QU_B_JF_B_MODULE_FIRMWARE(IWL_22000_UCODE_API_MAX)); MODULE_FIRMWARE(IWL_QU_B_JF_B_MODULE_FIRMWARE(IWL_22000_UCODE_API_MAX));
MODULE_FIRMWARE(IWL_QNJ_B_JF_B_MODULE_FIRMWARE(IWL_22000_UCODE_API_MAX));
MODULE_FIRMWARE(IWL_CC_A_MODULE_FIRMWARE(IWL_22000_UCODE_API_MAX)); MODULE_FIRMWARE(IWL_CC_A_MODULE_FIRMWARE(IWL_22000_UCODE_API_MAX));
MODULE_FIRMWARE(IWL_22000_SO_A_JF_B_MODULE_FIRMWARE(IWL_22000_UCODE_API_MAX));
MODULE_FIRMWARE(IWL_22000_SO_A_HR_B_MODULE_FIRMWARE(IWL_22000_UCODE_API_MAX));
MODULE_FIRMWARE(IWL_22000_SO_A_GF_A_MODULE_FIRMWARE(IWL_22000_UCODE_API_MAX));
MODULE_FIRMWARE(IWL_22000_TY_A_GF_A_MODULE_FIRMWARE(IWL_22000_UCODE_API_MAX));

View File

@ -57,7 +57,7 @@
#include "fw/file.h" #include "fw/file.h"
/* Highest firmware API version supported */ /* Highest firmware API version supported */
#define IWL9000_UCODE_API_MAX 43 #define IWL9000_UCODE_API_MAX 46
/* Lowest firmware API version supported */ /* Lowest firmware API version supported */
#define IWL9000_UCODE_API_MIN 30 #define IWL9000_UCODE_API_MIN 30

View File

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

Some files were not shown because too many files have changed in this diff Show More