Import backports-3.15.9-1.
PREFIX=http://www.kernel.org/pub/linux/kernel/projects/backports
rm -rf *
curl -L $PREFIX/stable/v3.15.9/backports-3.15.9-1.tar.xz |
tar Jxv --strip-components=1
Change-Id: Ia2049728ce71ad466714b243f933d88081c1ebb0
diff --git a/.local-symbols b/.local-symbols
index b7d5942..3cf12dc 100644
--- a/.local-symbols
+++ b/.local-symbols
@@ -311,6 +311,7 @@
ETHERNET=
MDIO=
SUNGEM_PHY=
+CX_ECAT=
DNET=
JME=
KORINA=
diff --git a/MAINTAINERS b/MAINTAINERS
index 6dc67b1..6c484ac 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -537,7 +537,7 @@
F: arch/alpha/
ALTERA TRIPLE SPEED ETHERNET DRIVER
-M: Vince Bridgers <vbridgers2013@gmail.com
+M: Vince Bridgers <vbridgers2013@gmail.com>
L: netdev@vger.kernel.org
L: nios2-dev@lists.rocketboards.org (moderated for non-subscribers)
S: Maintained
@@ -1893,14 +1893,15 @@
S: Supported
F: drivers/net/ethernet/broadcom/bnx2x/
-BROADCOM BCM281XX/BCM11XXX ARM ARCHITECTURE
+BROADCOM BCM281XX/BCM11XXX/BCM216XX ARM ARCHITECTURE
M: Christian Daudt <bcm@fixthebug.org>
M: Matt Porter <mporter@linaro.org>
L: bcm-kernel-feedback-list@broadcom.com
-T: git git://git.github.com/broadcom/bcm11351
+T: git git://github.com/broadcom/mach-bcm
S: Maintained
F: arch/arm/mach-bcm/
F: arch/arm/boot/dts/bcm113*
+F: arch/arm/boot/dts/bcm216*
F: arch/arm/boot/dts/bcm281*
F: arch/arm/configs/bcm_defconfig
F: drivers/mmc/host/sdhci_bcm_kona.c
@@ -2245,12 +2246,6 @@
S: Maintained
F: drivers/usb/host/ohci-ep93xx.c
-CIRRUS LOGIC CS4270 SOUND DRIVER
-M: Timur Tabi <timur@tabi.org>
-L: alsa-devel@alsa-project.org (moderated for non-subscribers)
-S: Odd Fixes
-F: sound/soc/codecs/cs4270*
-
CIRRUS LOGIC AUDIO CODEC DRIVERS
M: Brian Austin <brian.austin@cirrus.com>
M: Paul Handrigan <Paul.Handrigan@cirrus.com>
@@ -3158,10 +3153,9 @@
F: drivers/scsi/eata_pio.*
EBTABLES
-M: Bart De Schuymer <bart.de.schuymer@pandora.be>
L: netfilter-devel@vger.kernel.org
W: http://ebtables.sourceforge.net/
-S: Maintained
+S: Orphan
F: include/linux/netfilter_bridge/ebt_*.h
F: include/uapi/linux/netfilter_bridge/ebt_*.h
F: net/bridge/netfilter/ebt*.c
@@ -3485,6 +3479,12 @@
F: drivers/extcon/
F: Documentation/extcon/
+EXYNOS DP DRIVER
+M: Jingoo Han <jg1.han@samsung.com>
+L: dri-devel@lists.freedesktop.org
+S: Maintained
+F: drivers/gpu/drm/exynos/exynos_dp*
+
EXYNOS MIPI DISPLAY DRIVERS
M: Inki Dae <inki.dae@samsung.com>
M: Donghwa Lee <dh09.lee@samsung.com>
@@ -3550,7 +3550,7 @@
F: include/uapi/scsi/fc/
FILE LOCKING (flock() and fcntl()/lockf())
-M: Jeff Layton <jlayton@redhat.com>
+M: Jeff Layton <jlayton@poochiereds.net>
M: J. Bruce Fields <bfields@fieldses.org>
L: linux-fsdevel@vger.kernel.org
S: Maintained
@@ -4812,6 +4812,14 @@
S: Maintained
T: git git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip.git irq/core
F: kernel/irq/
+
+IRQCHIP DRIVERS
+M: Thomas Gleixner <tglx@linutronix.de>
+M: Jason Cooper <jason@lakedaemon.net>
+L: linux-kernel@vger.kernel.org
+S: Maintained
+T: git git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip.git irq/core
+T: git git://git.infradead.org/users/jcooper/linux.git irqchip/core
F: drivers/irqchip/
IRQ DOMAINS (IRQ NUMBER MAPPING LIBRARY)
@@ -5108,14 +5116,19 @@
KERNEL VIRTUAL MACHINE (KVM) FOR ARM
M: Christoffer Dall <christoffer.dall@linaro.org>
+M: Marc Zyngier <marc.zyngier@arm.com>
+L: linux-arm-kernel@lists.infradead.org (moderated for non-subscribers)
L: kvmarm@lists.cs.columbia.edu
W: http://systems.cs.columbia.edu/projects/kvm-arm
S: Supported
F: arch/arm/include/uapi/asm/kvm*
F: arch/arm/include/asm/kvm*
F: arch/arm/kvm/
+F: virt/kvm/arm/
+F: include/kvm/arm_*
KERNEL VIRTUAL MACHINE FOR ARM64 (KVM/arm64)
+M: Christoffer Dall <christoffer.dall@linaro.org>
M: Marc Zyngier <marc.zyngier@arm.com>
L: linux-arm-kernel@lists.infradead.org (moderated for non-subscribers)
L: kvmarm@lists.cs.columbia.edu
@@ -5479,15 +5492,15 @@
F: drivers/hwmon/ltc4261.c
LTP (Linux Test Project)
-M: Shubham Goyal <shubham@linux.vnet.ibm.com>
M: Mike Frysinger <vapier@gentoo.org>
M: Cyril Hrubis <chrubis@suse.cz>
-M: Caspar Zhang <caspar@casparzhang.com>
M: Wanlong Gao <gaowanlong@cn.fujitsu.com>
+M: Jan Stancek <jstancek@redhat.com>
+M: Stanislav Kholmanskikh <stanislav.kholmanskikh@oracle.com>
+M: Alexey Kodanev <alexey.kodanev@oracle.com>
L: ltp-list@lists.sourceforge.net (subscribers-only)
-W: http://ltp.sourceforge.net/
+W: http://linux-test-project.github.io/
T: git git://github.com/linux-test-project/ltp.git
-T: git git://ltp.git.sourceforge.net/gitroot/ltp/ltp-dev
S: Maintained
M32R ARCHITECTURE
@@ -6500,10 +6513,10 @@
F: arch/openrisc/
OPENVSWITCH
-M: Jesse Gross <jesse@nicira.com>
+M: Pravin Shelar <pshelar@nicira.com>
L: dev@openvswitch.org
W: http://openvswitch.org
-T: git git://git.kernel.org/pub/scm/linux/kernel/git/jesse/openvswitch.git
+T: git git://git.kernel.org/pub/scm/linux/kernel/git/pshelar/openvswitch.git
S: Maintained
F: net/openvswitch/
@@ -6782,7 +6795,7 @@
M: Peter Zijlstra <a.p.zijlstra@chello.nl>
M: Paul Mackerras <paulus@samba.org>
M: Ingo Molnar <mingo@redhat.com>
-M: Arnaldo Carvalho de Melo <acme@ghostprotocols.net>
+M: Arnaldo Carvalho de Melo <acme@kernel.org>
L: linux-kernel@vger.kernel.org
T: git git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip.git perf/core
S: Supported
@@ -7277,7 +7290,6 @@
RALINK RT2X00 WIRELESS LAN DRIVER
P: rt2x00 project
M: Ivo van Doorn <IvDoorn@gmail.com>
-M: Gertjan van Wingerde <gwingerde@gmail.com>
M: Helmut Schaa <helmut.schaa@googlemail.com>
L: linux-wireless@vger.kernel.org
L: users@rt2x00.serialmonkey.com (moderated for non-subscribers)
@@ -7293,7 +7305,7 @@
F: drivers/block/brd.c
RANDOM NUMBER DRIVER
-M: Theodore Ts'o" <tytso@mit.edu>
+M: "Theodore Ts'o" <tytso@mit.edu>
S: Maintained
F: drivers/char/random.c
@@ -7392,6 +7404,14 @@
F: Documentation/rpmsg.txt
F: include/linux/rpmsg.h
+RESET CONTROLLER FRAMEWORK
+M: Philipp Zabel <p.zabel@pengutronix.de>
+S: Maintained
+F: drivers/reset/
+F: Documentation/devicetree/bindings/reset/
+F: include/linux/reset.h
+F: include/linux/reset-controller.h
+
RFKILL
M: Johannes Berg <johannes@sipsolutions.net>
L: linux-wireless@vger.kernel.org
@@ -7674,7 +7694,6 @@
SAMSUNG SXGBE DRIVERS
M: Byungho An <bh74.an@samsung.com>
M: Girish K S <ks.giri@samsung.com>
-M: Siva Reddy Kallam <siva.kallam@samsung.com>
M: Vipul Pandya <vipul.pandya@samsung.com>
S: Supported
L: netdev@vger.kernel.org
@@ -8315,7 +8334,7 @@
SPEAR PLATFORM SUPPORT
M: Viresh Kumar <viresh.linux@gmail.com>
-M: Shiraz Hashim <shiraz.hashim@st.com>
+M: Shiraz Hashim <shiraz.linux.kernel@gmail.com>
L: spear-devel@list.st.com
L: linux-arm-kernel@lists.infradead.org (moderated for non-subscribers)
W: http://www.st.com/spear
@@ -9098,6 +9117,9 @@
TURBOCHANNEL SUBSYSTEM
M: "Maciej W. Rozycki" <macro@linux-mips.org>
+M: Ralf Baechle <ralf@linux-mips.org>
+L: linux-mips@linux-mips.org
+Q: http://patchwork.linux-mips.org/project/linux-mips/list/
S: Maintained
F: drivers/tc/
F: include/linux/tc.h
@@ -9951,7 +9973,7 @@
F: drivers/net/hamradio/z8530.h
ZBUD COMPRESSED PAGE ALLOCATOR
-M: Seth Jennings <sjenning@linux.vnet.ibm.com>
+M: Seth Jennings <sjennings@variantweb.net>
L: linux-mm@kvack.org
S: Maintained
F: mm/zbud.c
@@ -9996,7 +10018,7 @@
F: include/linux/zsmalloc.h
ZSWAP COMPRESSED SWAP CACHING
-M: Seth Jennings <sjenning@linux.vnet.ibm.com>
+M: Seth Jennings <sjennings@variantweb.net>
L: linux-mm@kvack.org
S: Maintained
F: mm/zswap.c
diff --git a/backport-include/linux/device.h b/backport-include/linux/device.h
index 3f57bd9..d347b16 100644
--- a/backport-include/linux/device.h
+++ b/backport-include/linux/device.h
@@ -102,14 +102,16 @@
#define device_release_driver LINUX_BACKPORT(device_release_driver)
#endif /* LINUX_VERSION_CODE <= KERNEL_VERSION(3,6,0) */
-#if LINUX_VERSION_CODE < KERNEL_VERSION(3,11,0)
+#if LINUX_VERSION_CODE < KERNEL_VERSION(3,11,0) && RHEL_RELEASE_CODE < RHEL_RELEASE_VERSION(7,0)
#ifndef DEVICE_ATTR_RO
#define DEVICE_ATTR_RO(_name) \
struct device_attribute dev_attr_ ## _name = __ATTR_RO(_name);
#endif
+#ifndef DEVICE_ATTR_RW
#define DEVICE_ATTR_RW(_name) \
struct device_attribute dev_attr_ ## _name = __ATTR_RW(_name)
#endif
+#endif
#define ATTRIBUTE_GROUPS_BACKPORT(_name) \
static struct BP_ATTR_GRP_STRUCT _name##_dev_attrs[ARRAY_SIZE(_name##_attrs)];\
diff --git a/backport-include/linux/dma-mapping.h b/backport-include/linux/dma-mapping.h
index 9b2bc90..fdc3331 100644
--- a/backport-include/linux/dma-mapping.h
+++ b/backport-include/linux/dma-mapping.h
@@ -22,6 +22,7 @@
* as the DMA API guarantees that the coherent DMA mask can be set to
* the same or smaller than the streaming DMA mask.
*/
+#define dma_set_mask_and_coherent LINUX_BACKPORT(dma_set_mask_and_coherent)
static inline int dma_set_mask_and_coherent(struct device *dev, u64 mask)
{
int rc = dma_set_mask(dev, mask);
diff --git a/backport-include/linux/if.h b/backport-include/linux/if.h
deleted file mode 100644
index 1045466..0000000
--- a/backport-include/linux/if.h
+++ /dev/null
@@ -1,27 +0,0 @@
-#ifndef _BACKPORT_LINUX_IF_H
-#define _BACKPORT_LINUX_IF_H
-#include_next <linux/if.h>
-#include <linux/version.h>
-
-/* mask IFF_DONT_BRIDGE as RHEL6 backports this */
-#if !defined(IFF_DONT_BRIDGE)
-#define IFF_DONT_BRIDGE 0x800 /* disallow bridging this ether dev */
-#endif
-
-#ifndef IFF_TX_SKB_SHARING
-#define IFF_TX_SKB_SHARING 0x10000
-#endif
-
-#ifndef IFF_LIVE_ADDR_CHANGE
-#define IFF_LIVE_ADDR_CHANGE 0x100000
-#endif
-
-#ifndef IFF_SUPP_NOFCS
-#define IFF_SUPP_NOFCS 0x80000 /* device supports sending custom FCS */
-#endif
-
-#ifndef IFF_UNICAST_FLT
-#define IFF_UNICAST_FLT 0x20000 /* Supports unicast filtering */
-#endif
-
-#endif /* _BACKPORT_LINUX_IF_H */
diff --git a/backport-include/linux/net.h b/backport-include/linux/net.h
index 385f807..0e436d4 100644
--- a/backport-include/linux/net.h
+++ b/backport-include/linux/net.h
@@ -64,7 +64,7 @@
* may affect tracing. My recommendation is that if you have a need for
* static keys you just require at least 3.5 to remain sane.
*/
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,5,0)
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,5,0) && !defined(net_get_random_once)
#define __BACKPORT_NET_GET_RANDOM_ONCE 1
#endif
#endif /* ___NET_RANDOM_STATIC_KEY_INIT */
diff --git a/backport-include/linux/netdevice.h b/backport-include/linux/netdevice.h
index 04b310d..e856073 100644
--- a/backport-include/linux/netdevice.h
+++ b/backport-include/linux/netdevice.h
@@ -156,4 +156,16 @@
#define napi_gro_flush(napi, old) napi_gro_flush(napi)
#endif
+#ifndef IFF_LIVE_ADDR_CHANGE
+#define IFF_LIVE_ADDR_CHANGE 0x100000
+#endif
+
+#ifndef IFF_SUPP_NOFCS
+#define IFF_SUPP_NOFCS 0x80000 /* device supports sending custom FCS */
+#endif
+
+#ifndef IFF_UNICAST_FLT
+#define IFF_UNICAST_FLT 0x20000 /* Supports unicast filtering */
+#endif
+
#endif /* __BACKPORT_NETDEVICE_H */
diff --git a/backport-include/linux/skbuff.h b/backport-include/linux/skbuff.h
index fae13b7..2576faf 100644
--- a/backport-include/linux/skbuff.h
+++ b/backport-include/linux/skbuff.h
@@ -327,7 +327,7 @@
}
#endif /* LINUX_VERSION_CODE < KERNEL_VERSION(3,2,0) */
-#if LINUX_VERSION_CODE < KERNEL_VERSION(3,14,0)
+#if LINUX_VERSION_CODE < KERNEL_VERSION(3,14,0) && RHEL_RELEASE_CODE < RHEL_RELEASE_VERSION(7,0)
/*
* Packet hash types specify the type of hash in skb_set_hash.
*
diff --git a/compat/Kconfig b/compat/Kconfig
index 103e3e8..60615a8 100644
--- a/compat/Kconfig
+++ b/compat/Kconfig
@@ -129,6 +129,8 @@
you probably shouldn't enable it.
config BACKPORT_CRYPTO_CCM
+ depends on CRYPTO_AEAD
+ depends on CRYPTO_CTR
bool
config BACKPORT_BUILD_CRYPTO_CCM
diff --git a/compat/backport-3.15.c b/compat/backport-3.15.c
index 545e0c2..4094e27 100644
--- a/compat/backport-3.15.c
+++ b/compat/backport-3.15.c
@@ -12,6 +12,7 @@
#include <linux/kernel.h>
#include <linux/device.h>
#include <linux/of.h>
+#include <linux/string.h>
#include <net/net_namespace.h>
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,5,0))
diff --git a/compat/dma-shared-helpers.c b/compat/dma-shared-helpers.c
index f76cf06..2ada681 100644
--- a/compat/dma-shared-helpers.c
+++ b/compat/dma-shared-helpers.c
@@ -20,6 +20,7 @@
#endif /* LINUX_VERSION_CODE <= KERNEL_VERSION(3,6,0) */
#endif /* LINUX_VERSION_CODE >= KERNEL_VERSION(3,3,0) */
+#if RHEL_RELEASE_CODE < RHEL_RELEASE_VERSION(7,0)
/*
* Create scatter-list for the already allocated DMA buffer.
*/
@@ -37,3 +38,4 @@
return 0;
}
EXPORT_SYMBOL_GPL(dma_common_get_sgtable);
+#endif /* RHEL_RELEASE_CODE < RHEL_RELEASE_VERSION(7,0) */
diff --git a/drivers/bcma/main.c b/drivers/bcma/main.c
index a6610e6..d234e5f 100644
--- a/drivers/bcma/main.c
+++ b/drivers/bcma/main.c
@@ -491,9 +491,7 @@
{
int err;
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,12,0)
init_bcma_device_attrs();
-#endif
err = bus_register(&bcma_bus_type);
if (err)
return err;
diff --git a/drivers/bluetooth/ath3k.c b/drivers/bluetooth/ath3k.c
index 286512d..f152508 100644
--- a/drivers/bluetooth/ath3k.c
+++ b/drivers/bluetooth/ath3k.c
@@ -82,6 +82,7 @@
{ USB_DEVICE(0x04CA, 0x3004) },
{ USB_DEVICE(0x04CA, 0x3005) },
{ USB_DEVICE(0x04CA, 0x3006) },
+ { USB_DEVICE(0x04CA, 0x3007) },
{ USB_DEVICE(0x04CA, 0x3008) },
{ USB_DEVICE(0x04CA, 0x300b) },
{ USB_DEVICE(0x0930, 0x0219) },
@@ -89,7 +90,6 @@
{ USB_DEVICE(0x0b05, 0x17d0) },
{ USB_DEVICE(0x0CF3, 0x0036) },
{ USB_DEVICE(0x0CF3, 0x3004) },
- { USB_DEVICE(0x0CF3, 0x3005) },
{ USB_DEVICE(0x0CF3, 0x3008) },
{ USB_DEVICE(0x0CF3, 0x311D) },
{ USB_DEVICE(0x0CF3, 0x311E) },
@@ -131,6 +131,7 @@
{ USB_DEVICE(0x04ca, 0x3004), .driver_info = BTUSB_ATH3012 },
{ USB_DEVICE(0x04ca, 0x3005), .driver_info = BTUSB_ATH3012 },
{ USB_DEVICE(0x04ca, 0x3006), .driver_info = BTUSB_ATH3012 },
+ { USB_DEVICE(0x04ca, 0x3007), .driver_info = BTUSB_ATH3012 },
{ USB_DEVICE(0x04ca, 0x3008), .driver_info = BTUSB_ATH3012 },
{ USB_DEVICE(0x04ca, 0x300b), .driver_info = BTUSB_ATH3012 },
{ USB_DEVICE(0x0930, 0x0219), .driver_info = BTUSB_ATH3012 },
@@ -138,7 +139,6 @@
{ USB_DEVICE(0x0b05, 0x17d0), .driver_info = BTUSB_ATH3012 },
{ USB_DEVICE(0x0CF3, 0x0036), .driver_info = BTUSB_ATH3012 },
{ USB_DEVICE(0x0cf3, 0x3004), .driver_info = BTUSB_ATH3012 },
- { USB_DEVICE(0x0cf3, 0x3005), .driver_info = BTUSB_ATH3012 },
{ USB_DEVICE(0x0cf3, 0x3008), .driver_info = BTUSB_ATH3012 },
{ USB_DEVICE(0x0cf3, 0x311D), .driver_info = BTUSB_ATH3012 },
{ USB_DEVICE(0x0cf3, 0x311E), .driver_info = BTUSB_ATH3012 },
diff --git a/drivers/bluetooth/btusb.c b/drivers/bluetooth/btusb.c
index 0141e80..e388b5c 100644
--- a/drivers/bluetooth/btusb.c
+++ b/drivers/bluetooth/btusb.c
@@ -152,6 +152,7 @@
{ USB_DEVICE(0x04ca, 0x3004), .driver_info = BTUSB_ATH3012 },
{ USB_DEVICE(0x04ca, 0x3005), .driver_info = BTUSB_ATH3012 },
{ USB_DEVICE(0x04ca, 0x3006), .driver_info = BTUSB_ATH3012 },
+ { USB_DEVICE(0x04ca, 0x3007), .driver_info = BTUSB_ATH3012 },
{ USB_DEVICE(0x04ca, 0x3008), .driver_info = BTUSB_ATH3012 },
{ USB_DEVICE(0x04ca, 0x300b), .driver_info = BTUSB_ATH3012 },
{ USB_DEVICE(0x0930, 0x0219), .driver_info = BTUSB_ATH3012 },
@@ -159,7 +160,6 @@
{ USB_DEVICE(0x0b05, 0x17d0), .driver_info = BTUSB_ATH3012 },
{ USB_DEVICE(0x0cf3, 0x0036), .driver_info = BTUSB_ATH3012 },
{ USB_DEVICE(0x0cf3, 0x3004), .driver_info = BTUSB_ATH3012 },
- { USB_DEVICE(0x0cf3, 0x3005), .driver_info = BTUSB_ATH3012 },
{ USB_DEVICE(0x0cf3, 0x3008), .driver_info = BTUSB_ATH3012 },
{ USB_DEVICE(0x0cf3, 0x311d), .driver_info = BTUSB_ATH3012 },
{ USB_DEVICE(0x0cf3, 0x311e), .driver_info = BTUSB_ATH3012 },
@@ -1485,10 +1485,8 @@
if (id->driver_info & BTUSB_BCM92035)
hdev->setup = btusb_setup_bcm92035;
- if (id->driver_info & BTUSB_INTEL) {
- usb_enable_autosuspend(data->udev);
+ if (id->driver_info & BTUSB_INTEL)
hdev->setup = btusb_setup_intel;
- }
/* Interface numbers are hardcoded in the specification */
data->isoc = usb_ifnum_to_if(data->udev, 1);
diff --git a/drivers/bluetooth/hci_h5.c b/drivers/bluetooth/hci_h5.c
index 04680ea..fede8ca 100644
--- a/drivers/bluetooth/hci_h5.c
+++ b/drivers/bluetooth/hci_h5.c
@@ -406,6 +406,7 @@
H5_HDR_PKT_TYPE(hdr) != HCI_3WIRE_LINK_PKT) {
BT_ERR("Non-link packet received in non-active state");
h5_reset_rx(h5);
+ return 0;
}
h5->rx_func = h5_rx_payload;
diff --git a/drivers/bluetooth/hci_ldisc.c b/drivers/bluetooth/hci_ldisc.c
index 928fdda..f829b36 100644
--- a/drivers/bluetooth/hci_ldisc.c
+++ b/drivers/bluetooth/hci_ldisc.c
@@ -118,10 +118,6 @@
int hci_uart_tx_wakeup(struct hci_uart *hu)
{
- struct tty_struct *tty = hu->tty;
- struct hci_dev *hdev = hu->hdev;
- struct sk_buff *skb;
-
if (test_and_set_bit(HCI_UART_SENDING, &hu->tx_state)) {
set_bit(HCI_UART_TX_WAKEUP, &hu->tx_state);
return 0;
@@ -129,6 +125,22 @@
BT_DBG("");
+ schedule_work(&hu->write_work);
+
+ return 0;
+}
+
+static void hci_uart_write_work(struct work_struct *work)
+{
+ struct hci_uart *hu = container_of(work, struct hci_uart, write_work);
+ struct tty_struct *tty = hu->tty;
+ struct hci_dev *hdev = hu->hdev;
+ struct sk_buff *skb;
+
+ /* REVISIT: should we cope with bad skbs or ->write() returning
+ * and error value ?
+ */
+
restart:
clear_bit(HCI_UART_TX_WAKEUP, &hu->tx_state);
@@ -153,7 +165,6 @@
goto restart;
clear_bit(HCI_UART_SENDING, &hu->tx_state);
- return 0;
}
static void hci_uart_init_work(struct work_struct *work)
@@ -282,6 +293,7 @@
tty->receive_room = 65536;
INIT_WORK(&hu->init_ready, hci_uart_init_work);
+ INIT_WORK(&hu->write_work, hci_uart_write_work);
spin_lock_init(&hu->rx_lock);
@@ -319,6 +331,8 @@
if (hdev)
hci_uart_close(hdev);
+ cancel_work_sync(&hu->write_work);
+
if (test_and_clear_bit(HCI_UART_PROTO_SET, &hu->flags)) {
if (hdev) {
if (test_bit(HCI_UART_REGISTERED, &hu->flags))
diff --git a/drivers/bluetooth/hci_uart.h b/drivers/bluetooth/hci_uart.h
index dc2489d..1cbe8bd 100644
--- a/drivers/bluetooth/hci_uart.h
+++ b/drivers/bluetooth/hci_uart.h
@@ -68,6 +68,7 @@
unsigned long hdev_flags;
struct work_struct init_ready;
+ struct work_struct write_work;
struct hci_uart_proto *proto;
void *priv;
diff --git a/drivers/media/dvb-core/dvb-usb-ids.h b/drivers/media/dvb-core/dvb-usb-ids.h
index 1bdc0e7..80643ef 100644
--- a/drivers/media/dvb-core/dvb-usb-ids.h
+++ b/drivers/media/dvb-core/dvb-usb-ids.h
@@ -361,6 +361,7 @@
#define USB_PID_FRIIO_WHITE 0x0001
#define USB_PID_TVWAY_PLUS 0x0002
#define USB_PID_SVEON_STV20 0xe39d
+#define USB_PID_SVEON_STV20_RTL2832U 0xd39d
#define USB_PID_SVEON_STV22 0xe401
#define USB_PID_SVEON_STV22_IT9137 0xe411
#define USB_PID_AZUREWAVE_AZ6027 0x3275
@@ -375,4 +376,5 @@
#define USB_PID_CTVDIGDUAL_V2 0xe410
#define USB_PID_PCTV_2002E 0x025c
#define USB_PID_PCTV_2002E_SE 0x025d
+#define USB_PID_SVEON_STV27 0xd3af
#endif
diff --git a/drivers/media/dvb-frontends/tda10071.c b/drivers/media/dvb-frontends/tda10071.c
index 522fe00..49874e7 100644
--- a/drivers/media/dvb-frontends/tda10071.c
+++ b/drivers/media/dvb-frontends/tda10071.c
@@ -668,6 +668,7 @@
struct dtv_frontend_properties *c = &fe->dtv_property_cache;
int ret, i;
u8 mode, rolloff, pilot, inversion, div;
+ fe_modulation_t modulation;
dev_dbg(&priv->i2c->dev,
"%s: delivery_system=%d modulation=%d frequency=%d symbol_rate=%d inversion=%d pilot=%d rolloff=%d\n",
@@ -702,10 +703,13 @@
switch (c->delivery_system) {
case SYS_DVBS:
+ modulation = QPSK;
rolloff = 0;
pilot = 2;
break;
case SYS_DVBS2:
+ modulation = c->modulation;
+
switch (c->rolloff) {
case ROLLOFF_20:
rolloff = 2;
@@ -750,7 +754,7 @@
for (i = 0, mode = 0xff; i < ARRAY_SIZE(TDA10071_MODCOD); i++) {
if (c->delivery_system == TDA10071_MODCOD[i].delivery_system &&
- c->modulation == TDA10071_MODCOD[i].modulation &&
+ modulation == TDA10071_MODCOD[i].modulation &&
c->fec_inner == TDA10071_MODCOD[i].fec) {
mode = TDA10071_MODCOD[i].val;
dev_dbg(&priv->i2c->dev, "%s: mode found=%02x\n",
diff --git a/drivers/media/i2c/ov7670.c b/drivers/media/i2c/ov7670.c
index 2252b77..ce7e384 100644
--- a/drivers/media/i2c/ov7670.c
+++ b/drivers/media/i2c/ov7670.c
@@ -1109,7 +1109,7 @@
* windows that fall outside that.
*/
for (i = 0; i < n_win_sizes; i++) {
- struct ov7670_win_size *win = &info->devtype->win_sizes[index];
+ struct ov7670_win_size *win = &info->devtype->win_sizes[i];
if (info->min_width && win->width < info->min_width)
continue;
if (info->min_height && win->height < info->min_height)
diff --git a/drivers/media/i2c/s5c73m3/s5c73m3-core.c b/drivers/media/i2c/s5c73m3/s5c73m3-core.c
index a445930..ee0f57e 100644
--- a/drivers/media/i2c/s5c73m3/s5c73m3-core.c
+++ b/drivers/media/i2c/s5c73m3/s5c73m3-core.c
@@ -1616,7 +1616,7 @@
if (ret < 0)
return -EINVAL;
- node_ep = v4l2_of_get_next_endpoint(node, NULL);
+ node_ep = of_graph_get_next_endpoint(node, NULL);
if (!node_ep) {
dev_warn(dev, "no endpoint defined for node: %s\n",
node->full_name);
diff --git a/drivers/media/media-device.c b/drivers/media/media-device.c
index d5a7a13..703560f 100644
--- a/drivers/media/media-device.c
+++ b/drivers/media/media-device.c
@@ -93,6 +93,7 @@
struct media_entity *ent;
struct media_entity_desc u_ent;
+ memset(&u_ent, 0, sizeof(u_ent));
if (copy_from_user(&u_ent.id, &uent->id, sizeof(u_ent.id)))
return -EFAULT;
diff --git a/drivers/media/pci/ivtv/ivtv-alsa-pcm.c b/drivers/media/pci/ivtv/ivtv-alsa-pcm.c
index e1863db..7a9b98b 100644
--- a/drivers/media/pci/ivtv/ivtv-alsa-pcm.c
+++ b/drivers/media/pci/ivtv/ivtv-alsa-pcm.c
@@ -159,6 +159,12 @@
/* Instruct the CX2341[56] to start sending packets */
snd_ivtv_lock(itvsc);
+
+ if (ivtv_init_on_first_open(itv)) {
+ snd_ivtv_unlock(itvsc);
+ return -ENXIO;
+ }
+
s = &itv->streams[IVTV_ENC_STREAM_TYPE_PCM];
v4l2_fh_init(&item.fh, s->vdev);
diff --git a/drivers/media/pci/saa7134/saa7134-video.c b/drivers/media/pci/saa7134/saa7134-video.c
index 0d87b91..e091489 100644
--- a/drivers/media/pci/saa7134/saa7134-video.c
+++ b/drivers/media/pci/saa7134/saa7134-video.c
@@ -1243,6 +1243,7 @@
videobuf_streamoff(&dev->cap);
res_free(dev, fh, RESOURCE_VIDEO);
videobuf_mmap_free(&dev->cap);
+ INIT_LIST_HEAD(&dev->cap.stream);
}
if (dev->cap.read_buf) {
buffer_release(&dev->cap, dev->cap.read_buf);
@@ -1254,6 +1255,7 @@
videobuf_stop(&dev->vbi);
res_free(dev, fh, RESOURCE_VBI);
videobuf_mmap_free(&dev->vbi);
+ INIT_LIST_HEAD(&dev->vbi.stream);
}
/* ts-capture will not work in planar mode, so turn it off Hac: 04.05*/
@@ -1987,17 +1989,12 @@
enum v4l2_buf_type type)
{
struct saa7134_dev *dev = video_drvdata(file);
- int err;
int res = saa7134_resource(file);
if (res != RESOURCE_EMPRESS)
pm_qos_remove_request(&dev->qos_request);
- err = videobuf_streamoff(saa7134_queue(file));
- if (err < 0)
- return err;
- res_free(dev, priv, res);
- return 0;
+ return videobuf_streamoff(saa7134_queue(file));
}
EXPORT_SYMBOL_GPL(saa7134_streamoff);
diff --git a/drivers/media/platform/Kconfig b/drivers/media/platform/Kconfig
index ec6ae57..ae8387a 100644
--- a/drivers/media/platform/Kconfig
+++ b/drivers/media/platform/Kconfig
@@ -61,7 +61,7 @@
depends on !BACKPORT_KERNEL_3_4
tristate "Support for timberdale Video In/LogiWIN"
depends on m
- depends on VIDEO_V4L2 && I2C && DMADEVICES
+ depends on MFD_TIMBERDALE && VIDEO_V4L2 && I2C && DMADEVICES
depends on DMA_ENGINE
depends on TIMB_DMA
select VIDEO_ADV7180
diff --git a/drivers/media/platform/davinci/vpbe_display.c b/drivers/media/platform/davinci/vpbe_display.c
index b4f12d0..6567082 100644
--- a/drivers/media/platform/davinci/vpbe_display.c
+++ b/drivers/media/platform/davinci/vpbe_display.c
@@ -372,18 +372,32 @@
{
struct vpbe_fh *fh = vb2_get_drv_priv(vq);
struct vpbe_layer *layer = fh->layer;
+ struct vpbe_display *disp = fh->disp_dev;
+ unsigned long flags;
if (!vb2_is_streaming(vq))
return 0;
/* release all active buffers */
+ spin_lock_irqsave(&disp->dma_queue_lock, flags);
+ if (layer->cur_frm == layer->next_frm) {
+ vb2_buffer_done(&layer->cur_frm->vb, VB2_BUF_STATE_ERROR);
+ } else {
+ if (layer->cur_frm != NULL)
+ vb2_buffer_done(&layer->cur_frm->vb,
+ VB2_BUF_STATE_ERROR);
+ if (layer->next_frm != NULL)
+ vb2_buffer_done(&layer->next_frm->vb,
+ VB2_BUF_STATE_ERROR);
+ }
+
while (!list_empty(&layer->dma_queue)) {
layer->next_frm = list_entry(layer->dma_queue.next,
struct vpbe_disp_buffer, list);
list_del(&layer->next_frm->list);
vb2_buffer_done(&layer->next_frm->vb, VB2_BUF_STATE_ERROR);
}
-
+ spin_unlock_irqrestore(&disp->dma_queue_lock, flags);
return 0;
}
diff --git a/drivers/media/platform/davinci/vpfe_capture.c b/drivers/media/platform/davinci/vpfe_capture.c
index d762246..0379cb9 100644
--- a/drivers/media/platform/davinci/vpfe_capture.c
+++ b/drivers/media/platform/davinci/vpfe_capture.c
@@ -734,6 +734,8 @@
}
vpfe_dev->io_usrs = 0;
vpfe_dev->numbuffers = config_params.numbuffers;
+ videobuf_stop(&vpfe_dev->buffer_queue);
+ videobuf_mmap_free(&vpfe_dev->buffer_queue);
}
/* Decrement device usrs counter */
diff --git a/drivers/media/platform/davinci/vpif_capture.c b/drivers/media/platform/davinci/vpif_capture.c
index 756da78..8dea0b8 100644
--- a/drivers/media/platform/davinci/vpif_capture.c
+++ b/drivers/media/platform/davinci/vpif_capture.c
@@ -358,8 +358,31 @@
common = &ch->common[VPIF_VIDEO_INDEX];
+ /* Disable channel as per its device type and channel id */
+ if (VPIF_CHANNEL0_VIDEO == ch->channel_id) {
+ enable_channel0(0);
+ channel0_intr_enable(0);
+ }
+ if ((VPIF_CHANNEL1_VIDEO == ch->channel_id) ||
+ (2 == common->started)) {
+ enable_channel1(0);
+ channel1_intr_enable(0);
+ }
+ common->started = 0;
+
/* release all active buffers */
spin_lock_irqsave(&common->irqlock, flags);
+ if (common->cur_frm == common->next_frm) {
+ vb2_buffer_done(&common->cur_frm->vb, VB2_BUF_STATE_ERROR);
+ } else {
+ if (common->cur_frm != NULL)
+ vb2_buffer_done(&common->cur_frm->vb,
+ VB2_BUF_STATE_ERROR);
+ if (common->next_frm != NULL)
+ vb2_buffer_done(&common->next_frm->vb,
+ VB2_BUF_STATE_ERROR);
+ }
+
while (!list_empty(&common->dma_queue)) {
common->next_frm = list_entry(common->dma_queue.next,
struct vpif_cap_buffer, list);
@@ -933,17 +956,6 @@
if (fh->io_allowed[VPIF_VIDEO_INDEX]) {
/* Reset io_usrs member of channel object */
common->io_usrs = 0;
- /* Disable channel as per its device type and channel id */
- if (VPIF_CHANNEL0_VIDEO == ch->channel_id) {
- enable_channel0(0);
- channel0_intr_enable(0);
- }
- if ((VPIF_CHANNEL1_VIDEO == ch->channel_id) ||
- (2 == common->started)) {
- enable_channel1(0);
- channel1_intr_enable(0);
- }
- common->started = 0;
/* Free buffers allocated */
vb2_queue_release(&common->buffer_queue);
vb2_dma_contig_cleanup_ctx(common->alloc_ctx);
diff --git a/drivers/media/platform/davinci/vpif_display.c b/drivers/media/platform/davinci/vpif_display.c
index 0ac841e..aed41ed 100644
--- a/drivers/media/platform/davinci/vpif_display.c
+++ b/drivers/media/platform/davinci/vpif_display.c
@@ -320,8 +320,31 @@
common = &ch->common[VPIF_VIDEO_INDEX];
+ /* Disable channel */
+ if (VPIF_CHANNEL2_VIDEO == ch->channel_id) {
+ enable_channel2(0);
+ channel2_intr_enable(0);
+ }
+ if ((VPIF_CHANNEL3_VIDEO == ch->channel_id) ||
+ (2 == common->started)) {
+ enable_channel3(0);
+ channel3_intr_enable(0);
+ }
+ common->started = 0;
+
/* release all active buffers */
spin_lock_irqsave(&common->irqlock, flags);
+ if (common->cur_frm == common->next_frm) {
+ vb2_buffer_done(&common->cur_frm->vb, VB2_BUF_STATE_ERROR);
+ } else {
+ if (common->cur_frm != NULL)
+ vb2_buffer_done(&common->cur_frm->vb,
+ VB2_BUF_STATE_ERROR);
+ if (common->next_frm != NULL)
+ vb2_buffer_done(&common->next_frm->vb,
+ VB2_BUF_STATE_ERROR);
+ }
+
while (!list_empty(&common->dma_queue)) {
common->next_frm = list_entry(common->dma_queue.next,
struct vpif_disp_buffer, list);
@@ -773,18 +796,6 @@
if (fh->io_allowed[VPIF_VIDEO_INDEX]) {
/* Reset io_usrs member of channel object */
common->io_usrs = 0;
- /* Disable channel */
- if (VPIF_CHANNEL2_VIDEO == ch->channel_id) {
- enable_channel2(0);
- channel2_intr_enable(0);
- }
- if ((VPIF_CHANNEL3_VIDEO == ch->channel_id) ||
- (2 == common->started)) {
- enable_channel3(0);
- channel3_intr_enable(0);
- }
- common->started = 0;
-
/* Free buffers allocated */
vb2_queue_release(&common->buffer_queue);
vb2_dma_contig_cleanup_ctx(common->alloc_ctx);
diff --git a/drivers/media/platform/exynos4-is/fimc-core.c b/drivers/media/platform/exynos4-is/fimc-core.c
index da2fc86..25dbf5b 100644
--- a/drivers/media/platform/exynos4-is/fimc-core.c
+++ b/drivers/media/platform/exynos4-is/fimc-core.c
@@ -122,7 +122,7 @@
}, {
.name = "YUV 4:2:2 planar, Y/Cb/Cr",
.fourcc = V4L2_PIX_FMT_YUV422P,
- .depth = { 12 },
+ .depth = { 16 },
.color = FIMC_FMT_YCBYCR422,
.memplanes = 1,
.colplanes = 3,
diff --git a/drivers/media/platform/exynos4-is/fimc-is.c b/drivers/media/platform/exynos4-is/fimc-is.c
index 128b73b..5476dce 100644
--- a/drivers/media/platform/exynos4-is/fimc-is.c
+++ b/drivers/media/platform/exynos4-is/fimc-is.c
@@ -367,6 +367,9 @@
{
struct device *dev = &is->pdev->dev;
+ if (is->memory.vaddr == NULL)
+ return;
+
dma_free_coherent(dev, is->memory.size, is->memory.vaddr,
is->memory.paddr);
}
diff --git a/drivers/media/platform/exynos4-is/media-dev.c b/drivers/media/platform/exynos4-is/media-dev.c
index e62211a..6e2d604 100644
--- a/drivers/media/platform/exynos4-is/media-dev.c
+++ b/drivers/media/platform/exynos4-is/media-dev.c
@@ -1520,7 +1520,7 @@
}
#else
#define fimc_md_register_clk_provider(fmd) (0)
-#define fimc_md_unregister_clk_provider(fmd) (0)
+#define fimc_md_unregister_clk_provider(fmd)
#endif
static int subdev_notifier_bound(struct v4l2_async_notifier *notifier,
diff --git a/drivers/media/platform/exynos4-is/media-dev.h b/drivers/media/platform/exynos4-is/media-dev.h
index ee1e251..58c4945 100644
--- a/drivers/media/platform/exynos4-is/media-dev.h
+++ b/drivers/media/platform/exynos4-is/media-dev.h
@@ -94,7 +94,9 @@
};
struct cam_clk {
+#ifdef CONFIG_COMMON_CLK
struct clk_hw hw;
+#endif
struct fimc_md *fmd;
};
#define to_cam_clk(_hw) container_of(_hw, struct cam_clk, hw)
@@ -142,7 +144,9 @@
struct cam_clk_provider {
struct clk *clks[FIMC_MAX_CAMCLKS];
+#ifdef CONFIG_COMMON_CLK
struct clk_onecell_data clk_data;
+#endif
struct device_node *of_node;
struct cam_clk camclk[FIMC_MAX_CAMCLKS];
int num_clocks;
diff --git a/drivers/media/tuners/fc2580.c b/drivers/media/tuners/fc2580.c
index 3aecaf4..f0c9c42 100644
--- a/drivers/media/tuners/fc2580.c
+++ b/drivers/media/tuners/fc2580.c
@@ -195,7 +195,7 @@
f_ref = 2UL * priv->cfg->clock / r_val;
n_val = div_u64_rem(f_vco, f_ref, &k_val);
- k_val_reg = 1UL * k_val * (1 << 20) / f_ref;
+ k_val_reg = div_u64(1ULL * k_val * (1 << 20), f_ref);
ret = fc2580_wr_reg(priv, 0x18, r18_val | ((k_val_reg >> 16) & 0xff));
if (ret < 0)
@@ -348,8 +348,8 @@
if (ret < 0)
goto err;
- ret = fc2580_wr_reg(priv, 0x37, 1UL * priv->cfg->clock * \
- fc2580_if_filter_lut[i].mul / 1000000000);
+ ret = fc2580_wr_reg(priv, 0x37, div_u64(1ULL * priv->cfg->clock *
+ fc2580_if_filter_lut[i].mul, 1000000000));
if (ret < 0)
goto err;
diff --git a/drivers/media/tuners/fc2580_priv.h b/drivers/media/tuners/fc2580_priv.h
index be38a9e..646c994 100644
--- a/drivers/media/tuners/fc2580_priv.h
+++ b/drivers/media/tuners/fc2580_priv.h
@@ -22,6 +22,7 @@
#define FC2580_PRIV_H
#include "fc2580.h"
+#include <linux/math64.h>
struct fc2580_reg_val {
u8 reg;
diff --git a/drivers/media/usb/dvb-usb-v2/Makefile b/drivers/media/usb/dvb-usb-v2/Makefile
index 0c4ae31..2e9bc9a 100644
--- a/drivers/media/usb/dvb-usb-v2/Makefile
+++ b/drivers/media/usb/dvb-usb-v2/Makefile
@@ -41,4 +41,3 @@
ccflags-y += -I$(backport_srctree)/drivers/media/dvb-frontends
ccflags-y += -I$(backport_srctree)/drivers/media/tuners
ccflags-y += -I$(backport_srctree)/drivers/media/common
-ccflags-y += -I$(backport_srctree)/drivers/staging/media/rtl2832u_sdr
diff --git a/drivers/media/usb/dvb-usb-v2/af9035.c b/drivers/media/usb/dvb-usb-v2/af9035.c
index 9233c17..ca75f80 100644
--- a/drivers/media/usb/dvb-usb-v2/af9035.c
+++ b/drivers/media/usb/dvb-usb-v2/af9035.c
@@ -704,15 +704,41 @@
if (ret < 0)
goto err;
- if (tmp == 0x00)
- dev_dbg(&d->udev->dev,
- "%s: [%d]tuner not set, using default\n",
- __func__, i);
- else
- state->af9033_config[i].tuner = tmp;
-
dev_dbg(&d->udev->dev, "%s: [%d]tuner=%02x\n",
- __func__, i, state->af9033_config[i].tuner);
+ __func__, i, tmp);
+
+ /* tuner sanity check */
+ if (state->chip_type == 0x9135) {
+ if (state->chip_version == 0x02) {
+ /* IT9135 BX (v2) */
+ switch (tmp) {
+ case AF9033_TUNER_IT9135_60:
+ case AF9033_TUNER_IT9135_61:
+ case AF9033_TUNER_IT9135_62:
+ state->af9033_config[i].tuner = tmp;
+ break;
+ }
+ } else {
+ /* IT9135 AX (v1) */
+ switch (tmp) {
+ case AF9033_TUNER_IT9135_38:
+ case AF9033_TUNER_IT9135_51:
+ case AF9033_TUNER_IT9135_52:
+ state->af9033_config[i].tuner = tmp;
+ break;
+ }
+ }
+ } else {
+ /* AF9035 */
+ state->af9033_config[i].tuner = tmp;
+ }
+
+ if (state->af9033_config[i].tuner != tmp) {
+ dev_info(&d->udev->dev,
+ "%s: [%d] overriding tuner from %02x to %02x\n",
+ KBUILD_MODNAME, i, tmp,
+ state->af9033_config[i].tuner);
+ }
switch (state->af9033_config[i].tuner) {
case AF9033_TUNER_TUA9001:
diff --git a/drivers/media/usb/dvb-usb-v2/rtl28xxu.c b/drivers/media/usb/dvb-usb-v2/rtl28xxu.c
index fcf578a..459d6fa 100644
--- a/drivers/media/usb/dvb-usb-v2/rtl28xxu.c
+++ b/drivers/media/usb/dvb-usb-v2/rtl28xxu.c
@@ -24,7 +24,6 @@
#include "rtl2830.h"
#include "rtl2832.h"
-#include "rtl2832_sdr.h"
#include "qt1010.h"
#include "mt2060.h"
@@ -36,6 +35,45 @@
#include "tua9001.h"
#include "r820t.h"
+/*
+ * RTL2832_SDR module is in staging. That logic is added in order to avoid any
+ * hard dependency to drivers/staging/ directory as we want compile mainline
+ * driver even whole staging directory is missing.
+ */
+#include <media/v4l2-subdev.h>
+
+#if IS_ENABLED(CONFIG_DVB_RTL2832_SDR)
+struct dvb_frontend *rtl2832_sdr_attach(struct dvb_frontend *fe,
+ struct i2c_adapter *i2c, const struct rtl2832_config *cfg,
+ struct v4l2_subdev *sd);
+#else
+static inline struct dvb_frontend *rtl2832_sdr_attach(struct dvb_frontend *fe,
+ struct i2c_adapter *i2c, const struct rtl2832_config *cfg,
+ struct v4l2_subdev *sd)
+{
+ return NULL;
+}
+#endif
+
+#ifdef CPTCFG_MEDIA_ATTACH
+#define dvb_attach_sdr(FUNCTION, ARGS...) ({ \
+ void *__r = NULL; \
+ typeof(&FUNCTION) __a = symbol_request(FUNCTION); \
+ if (__a) { \
+ __r = (void *) __a(ARGS); \
+ if (__r == NULL) \
+ symbol_put(FUNCTION); \
+ } \
+ __r; \
+})
+
+#else
+#define dvb_attach_sdr(FUNCTION, ARGS...) ({ \
+ FUNCTION(ARGS); \
+})
+
+#endif
+
static int rtl28xxu_disable_rc;
module_param_named(disable_rc, rtl28xxu_disable_rc, int, 0644);
MODULE_PARM_DESC(disable_rc, "disable RTL2832U remote controller");
@@ -908,7 +946,7 @@
adap->fe[0]->ops.tuner_ops.get_rf_strength;
/* attach SDR */
- dvb_attach(rtl2832_sdr_attach, adap->fe[0], &d->i2c_adap,
+ dvb_attach_sdr(rtl2832_sdr_attach, adap->fe[0], &d->i2c_adap,
&rtl28xxu_rtl2832_fc0012_config, NULL);
break;
case TUNER_RTL2832_FC0013:
@@ -920,7 +958,7 @@
adap->fe[0]->ops.tuner_ops.get_rf_strength;
/* attach SDR */
- dvb_attach(rtl2832_sdr_attach, adap->fe[0], &d->i2c_adap,
+ dvb_attach_sdr(rtl2832_sdr_attach, adap->fe[0], &d->i2c_adap,
&rtl28xxu_rtl2832_fc0013_config, NULL);
break;
case TUNER_RTL2832_E4000: {
@@ -951,7 +989,7 @@
i2c_set_adapdata(i2c_adap_internal, d);
/* attach SDR */
- dvb_attach(rtl2832_sdr_attach, adap->fe[0],
+ dvb_attach_sdr(rtl2832_sdr_attach, adap->fe[0],
i2c_adap_internal,
&rtl28xxu_rtl2832_e4000_config, sd);
}
@@ -982,7 +1020,7 @@
adap->fe[0]->ops.tuner_ops.get_rf_strength;
/* attach SDR */
- dvb_attach(rtl2832_sdr_attach, adap->fe[0], &d->i2c_adap,
+ dvb_attach_sdr(rtl2832_sdr_attach, adap->fe[0], &d->i2c_adap,
&rtl28xxu_rtl2832_r820t_config, NULL);
break;
case TUNER_RTL2832_R828D:
@@ -1499,6 +1537,12 @@
&rtl2832u_props, "Crypto ReDi PC 50 A", NULL) },
{ DVB_USB_DEVICE(USB_VID_KYE, 0x707f,
&rtl2832u_props, "Genius TVGo DVB-T03", NULL) },
+ { DVB_USB_DEVICE(USB_VID_KWORLD_2, 0xd395,
+ &rtl2832u_props, "Peak DVB-T USB", NULL) },
+ { DVB_USB_DEVICE(USB_VID_KWORLD_2, USB_PID_SVEON_STV20_RTL2832U,
+ &rtl2832u_props, "Sveon STV20", NULL) },
+ { DVB_USB_DEVICE(USB_VID_KWORLD_2, USB_PID_SVEON_STV27,
+ &rtl2832u_props, "Sveon STV27", NULL) },
/* RTL2832P devices: */
{ DVB_USB_DEVICE(USB_VID_HANFTEK, 0x0131,
diff --git a/drivers/media/usb/gspca/pac7302.c b/drivers/media/usb/gspca/pac7302.c
index 37a7f76..1f44c74 100644
--- a/drivers/media/usb/gspca/pac7302.c
+++ b/drivers/media/usb/gspca/pac7302.c
@@ -928,6 +928,7 @@
{USB_DEVICE(0x093a, 0x2620)},
{USB_DEVICE(0x093a, 0x2621)},
{USB_DEVICE(0x093a, 0x2622), .driver_info = FL_VFLIP},
+ {USB_DEVICE(0x093a, 0x2623), .driver_info = FL_VFLIP},
{USB_DEVICE(0x093a, 0x2624), .driver_info = FL_VFLIP},
{USB_DEVICE(0x093a, 0x2625)},
{USB_DEVICE(0x093a, 0x2626)},
diff --git a/drivers/media/usb/gspca/sonixb.c b/drivers/media/usb/gspca/sonixb.c
index 7277dbd..ecbcb39 100644
--- a/drivers/media/usb/gspca/sonixb.c
+++ b/drivers/media/usb/gspca/sonixb.c
@@ -1430,10 +1430,8 @@
{USB_DEVICE(0x0c45, 0x600d), SB(PAS106, 101)},
{USB_DEVICE(0x0c45, 0x6011), SB(OV6650, 101)},
{USB_DEVICE(0x0c45, 0x6019), SB(OV7630, 101)},
-#if !IS_ENABLED(CONFIG_USB_SN9C102)
{USB_DEVICE(0x0c45, 0x6024), SB(TAS5130CXX, 102)},
{USB_DEVICE(0x0c45, 0x6025), SB(TAS5130CXX, 102)},
-#endif
{USB_DEVICE(0x0c45, 0x6027), SB(OV7630, 101)}, /* Genius Eye 310 */
{USB_DEVICE(0x0c45, 0x6028), SB(PAS202, 102)},
{USB_DEVICE(0x0c45, 0x6029), SB(PAS106, 102)},
diff --git a/drivers/media/usb/hdpvr/hdpvr-video.c b/drivers/media/usb/hdpvr/hdpvr-video.c
index 0500c41..6bce01a 100644
--- a/drivers/media/usb/hdpvr/hdpvr-video.c
+++ b/drivers/media/usb/hdpvr/hdpvr-video.c
@@ -82,7 +82,7 @@
}
/*=========================================================================*/
-/* bufffer bits */
+/* buffer bits */
/* function expects dev->io_mutex to be hold by caller */
int hdpvr_cancel_queue(struct hdpvr_device *dev)
@@ -926,7 +926,7 @@
case V4L2_CID_MPEG_AUDIO_ENCODING:
if (dev->flags & HDPVR_FLAG_AC3_CAP) {
opt->audio_codec = ctrl->val;
- return hdpvr_set_audio(dev, opt->audio_input,
+ return hdpvr_set_audio(dev, opt->audio_input + 1,
opt->audio_codec);
}
return 0;
@@ -1198,7 +1198,7 @@
v4l2_ctrl_new_std_menu(hdl, &hdpvr_ctrl_ops,
V4L2_CID_MPEG_AUDIO_ENCODING,
ac3 ? V4L2_MPEG_AUDIO_ENCODING_AC3 : V4L2_MPEG_AUDIO_ENCODING_AAC,
- 0x7, V4L2_MPEG_AUDIO_ENCODING_AAC);
+ 0x7, ac3 ? dev->options.audio_codec : V4L2_MPEG_AUDIO_ENCODING_AAC);
v4l2_ctrl_new_std_menu(hdl, &hdpvr_ctrl_ops,
V4L2_CID_MPEG_VIDEO_ENCODING,
V4L2_MPEG_VIDEO_ENCODING_MPEG_4_AVC, 0x3,
diff --git a/drivers/media/usb/stk1160/stk1160-core.c b/drivers/media/usb/stk1160/stk1160-core.c
index 34a26e0..03504dc 100644
--- a/drivers/media/usb/stk1160/stk1160-core.c
+++ b/drivers/media/usb/stk1160/stk1160-core.c
@@ -67,17 +67,25 @@
{
int ret;
int pipe = usb_rcvctrlpipe(dev->udev, 0);
+ u8 *buf;
*value = 0;
+
+ buf = kmalloc(sizeof(u8), GFP_KERNEL);
+ if (!buf)
+ return -ENOMEM;
ret = usb_control_msg(dev->udev, pipe, 0x00,
USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
- 0x00, reg, value, sizeof(u8), HZ);
+ 0x00, reg, buf, sizeof(u8), HZ);
if (ret < 0) {
stk1160_err("read failed on reg 0x%x (%d)\n",
reg, ret);
+ kfree(buf);
return ret;
}
+ *value = *buf;
+ kfree(buf);
return 0;
}
diff --git a/drivers/media/usb/stk1160/stk1160.h b/drivers/media/usb/stk1160/stk1160.h
index c26b2fa..b49d758 100644
--- a/drivers/media/usb/stk1160/stk1160.h
+++ b/drivers/media/usb/stk1160/stk1160.h
@@ -143,7 +143,6 @@
int num_alt;
struct stk1160_isoc_ctl isoc_ctl;
- char urb_buf[255]; /* urb control msg buffer */
/* frame properties */
int width; /* current frame width */
diff --git a/drivers/media/usb/uvc/uvc_video.c b/drivers/media/usb/uvc/uvc_video.c
index 8d52baf..8496811 100644
--- a/drivers/media/usb/uvc/uvc_video.c
+++ b/drivers/media/usb/uvc/uvc_video.c
@@ -361,6 +361,14 @@
* Clocks and timestamps
*/
+static inline void uvc_video_get_ts(struct timespec *ts)
+{
+ if (uvc_clock_param == CLOCK_MONOTONIC)
+ ktime_get_ts(ts);
+ else
+ ktime_get_real_ts(ts);
+}
+
static void
uvc_video_clock_decode(struct uvc_streaming *stream, struct uvc_buffer *buf,
const __u8 *data, int len)
@@ -420,7 +428,7 @@
stream->clock.last_sof = dev_sof;
host_sof = usb_get_current_frame_number(stream->dev->udev);
- ktime_get_ts(&ts);
+ uvc_video_get_ts(&ts);
/* The UVC specification allows device implementations that can't obtain
* the USB frame number to keep their own frame counters as long as they
@@ -1011,10 +1019,7 @@
return -ENODATA;
}
- if (uvc_clock_param == CLOCK_MONOTONIC)
- ktime_get_ts(&ts);
- else
- ktime_get_real_ts(&ts);
+ uvc_video_get_ts(&ts);
buf->buf.v4l2_buf.sequence = stream->sequence;
buf->buf.v4l2_buf.timestamp.tv_sec = ts.tv_sec;
diff --git a/drivers/media/v4l2-core/v4l2-compat-ioctl32.c b/drivers/media/v4l2-core/v4l2-compat-ioctl32.c
index 04b2daf..7e2411c 100644
--- a/drivers/media/v4l2-core/v4l2-compat-ioctl32.c
+++ b/drivers/media/v4l2-core/v4l2-compat-ioctl32.c
@@ -178,6 +178,9 @@
static int __get_v4l2_format32(struct v4l2_format *kp, struct v4l2_format32 __user *up)
{
+ if (get_user(kp->type, &up->type))
+ return -EFAULT;
+
switch (kp->type) {
case V4L2_BUF_TYPE_VIDEO_CAPTURE:
case V4L2_BUF_TYPE_VIDEO_OUTPUT:
@@ -204,17 +207,16 @@
static int get_v4l2_format32(struct v4l2_format *kp, struct v4l2_format32 __user *up)
{
- if (!access_ok(VERIFY_READ, up, sizeof(struct v4l2_format32)) ||
- get_user(kp->type, &up->type))
- return -EFAULT;
+ if (!access_ok(VERIFY_READ, up, sizeof(struct v4l2_format32)))
+ return -EFAULT;
return __get_v4l2_format32(kp, up);
}
static int get_v4l2_create32(struct v4l2_create_buffers *kp, struct v4l2_create_buffers32 __user *up)
{
if (!access_ok(VERIFY_READ, up, sizeof(struct v4l2_create_buffers32)) ||
- copy_from_user(kp, up, offsetof(struct v4l2_create_buffers32, format.fmt)))
- return -EFAULT;
+ copy_from_user(kp, up, offsetof(struct v4l2_create_buffers32, format)))
+ return -EFAULT;
return __get_v4l2_format32(&kp->format, &up->format);
}
diff --git a/drivers/media/v4l2-core/v4l2-dev.c b/drivers/media/v4l2-core/v4l2-dev.c
index b4dd5ac..147dc8e 100644
--- a/drivers/media/v4l2-core/v4l2-dev.c
+++ b/drivers/media/v4l2-core/v4l2-dev.c
@@ -1023,9 +1023,7 @@
return ret;
}
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,11,0)
init_video_device_attrs();
-#endif
ret = class_register(&video_class);
if (ret < 0) {
unregister_chrdev_region(dev, VIDEO_NUM_DEVICES);
diff --git a/drivers/media/v4l2-core/v4l2-dv-timings.c b/drivers/media/v4l2-core/v4l2-dv-timings.c
index 48b20df..eb3850c 100644
--- a/drivers/media/v4l2-core/v4l2-dv-timings.c
+++ b/drivers/media/v4l2-core/v4l2-dv-timings.c
@@ -599,10 +599,10 @@
aspect.denominator = 9;
} else if (ratio == 34) {
aspect.numerator = 4;
- aspect.numerator = 3;
+ aspect.denominator = 3;
} else if (ratio == 68) {
aspect.numerator = 15;
- aspect.numerator = 9;
+ aspect.denominator = 9;
} else {
aspect.numerator = hor_landscape + 99;
aspect.denominator = 100;
diff --git a/drivers/net/ethernet/Kconfig b/drivers/net/ethernet/Kconfig
index 088fa54..c59c561 100644
--- a/drivers/net/ethernet/Kconfig
+++ b/drivers/net/ethernet/Kconfig
@@ -37,6 +37,21 @@
#source "drivers/net/ethernet/chelsio/Kconfig"
#source "drivers/net/ethernet/cirrus/Kconfig"
#source "drivers/net/ethernet/cisco/Kconfig"
+
+config CX_ECAT
+ depends on n
+ tristate "Beckhoff CX5020 EtherCAT master support"
+ depends on m
+ depends on PCI
+ depends on X86 || COMPILE_TEST
+ ---help---
+ Driver for EtherCAT master module located on CCAT FPGA
+ that can be found on Beckhoff CX5020, and possibly other of CX
+ Beckhoff CX series industrial PCs.
+
+ To compile this driver as a module, choose M here. The module
+ will be called ec_bhf.
+
#source "drivers/net/ethernet/davicom/Kconfig"
config DNET
diff --git a/drivers/net/ethernet/Makefile b/drivers/net/ethernet/Makefile
index 26c3e6b..5f236a8 100644
--- a/drivers/net/ethernet/Makefile
+++ b/drivers/net/ethernet/Makefile
@@ -21,6 +21,7 @@
#obj-$(CONFIG_NET_VENDOR_CHELSIO) += chelsio/
#obj-$(CONFIG_NET_VENDOR_CIRRUS) += cirrus/
#obj-$(CONFIG_NET_VENDOR_CISCO) += cisco/
+#obj-$(CPTCFG_CX_ECAT) += ec_bhf.o
#obj-$(CONFIG_DM9000) += davicom/
#obj-$(CPTCFG_DNET) += dnet.o
#obj-$(CONFIG_NET_VENDOR_DEC) += dec/
diff --git a/drivers/net/ethernet/intel/igb/e1000_82575.c b/drivers/net/ethernet/intel/igb/e1000_82575.c
index cc72362..311dd13 100644
--- a/drivers/net/ethernet/intel/igb/e1000_82575.c
+++ b/drivers/net/ethernet/intel/igb/e1000_82575.c
@@ -1489,6 +1489,13 @@
s32 ret_val;
u16 i, rar_count = mac->rar_entry_count;
+ if ((hw->mac.type >= e1000_i210) &&
+ !(igb_get_flash_presence_i210(hw))) {
+ ret_val = igb_pll_workaround_i210(hw);
+ if (ret_val)
+ return ret_val;
+ }
+
/* Initialize identification LED */
ret_val = igb_id_led_init(hw);
if (ret_val) {
diff --git a/drivers/net/ethernet/intel/igb/e1000_defines.h b/drivers/net/ethernet/intel/igb/e1000_defines.h
index b05bf92..25d2361 100644
--- a/drivers/net/ethernet/intel/igb/e1000_defines.h
+++ b/drivers/net/ethernet/intel/igb/e1000_defines.h
@@ -49,14 +49,15 @@
#define E1000_CTRL_EXT_SDP3_DIR 0x00000800 /* SDP3 Data direction */
/* Physical Func Reset Done Indication */
-#define E1000_CTRL_EXT_PFRSTD 0x00004000
-#define E1000_CTRL_EXT_LINK_MODE_MASK 0x00C00000
-#define E1000_CTRL_EXT_LINK_MODE_PCIE_SERDES 0x00C00000
-#define E1000_CTRL_EXT_LINK_MODE_1000BASE_KX 0x00400000
-#define E1000_CTRL_EXT_LINK_MODE_SGMII 0x00800000
-#define E1000_CTRL_EXT_LINK_MODE_GMII 0x00000000
-#define E1000_CTRL_EXT_EIAME 0x01000000
-#define E1000_CTRL_EXT_IRCA 0x00000001
+#define E1000_CTRL_EXT_PFRSTD 0x00004000
+#define E1000_CTRL_EXT_SDLPE 0X00040000 /* SerDes Low Power Enable */
+#define E1000_CTRL_EXT_LINK_MODE_MASK 0x00C00000
+#define E1000_CTRL_EXT_LINK_MODE_PCIE_SERDES 0x00C00000
+#define E1000_CTRL_EXT_LINK_MODE_1000BASE_KX 0x00400000
+#define E1000_CTRL_EXT_LINK_MODE_SGMII 0x00800000
+#define E1000_CTRL_EXT_LINK_MODE_GMII 0x00000000
+#define E1000_CTRL_EXT_EIAME 0x01000000
+#define E1000_CTRL_EXT_IRCA 0x00000001
/* Interrupt delay cancellation */
/* Driver loaded bit for FW */
#define E1000_CTRL_EXT_DRV_LOAD 0x10000000
@@ -65,6 +66,7 @@
/* packet buffer parity error detection enabled */
/* descriptor FIFO parity error detection enable */
#define E1000_CTRL_EXT_PBA_CLR 0x80000000 /* PBA Clear */
+#define E1000_CTRL_EXT_PHYPDEN 0x00100000
#define E1000_I2CCMD_REG_ADDR_SHIFT 16
#define E1000_I2CCMD_PHY_ADDR_SHIFT 24
#define E1000_I2CCMD_OPCODE_READ 0x08000000
diff --git a/drivers/net/ethernet/intel/igb/e1000_hw.h b/drivers/net/ethernet/intel/igb/e1000_hw.h
index 99902f8..dfd4021 100644
--- a/drivers/net/ethernet/intel/igb/e1000_hw.h
+++ b/drivers/net/ethernet/intel/igb/e1000_hw.h
@@ -571,4 +571,7 @@
/* These functions must be implemented by drivers */
s32 igb_read_pcie_cap_reg(struct e1000_hw *hw, u32 reg, u16 *value);
s32 igb_write_pcie_cap_reg(struct e1000_hw *hw, u32 reg, u16 *value);
+
+void igb_read_pci_cfg(struct e1000_hw *hw, u32 reg, u16 *value);
+void igb_write_pci_cfg(struct e1000_hw *hw, u32 reg, u16 *value);
#endif /* _E1000_HW_H_ */
diff --git a/drivers/net/ethernet/intel/igb/e1000_i210.c b/drivers/net/ethernet/intel/igb/e1000_i210.c
index db96339..9e2c433 100644
--- a/drivers/net/ethernet/intel/igb/e1000_i210.c
+++ b/drivers/net/ethernet/intel/igb/e1000_i210.c
@@ -365,7 +365,7 @@
word_address = INVM_DWORD_TO_WORD_ADDRESS(invm_dword);
if (word_address == address) {
*data = INVM_DWORD_TO_WORD_DATA(invm_dword);
- hw_dbg("Read INVM Word 0x%02x = %x",
+ hw_dbg("Read INVM Word 0x%02x = %x\n",
address, *data);
status = E1000_SUCCESS;
break;
@@ -836,3 +836,69 @@
}
return ret_val;
}
+
+/**
+ * igb_pll_workaround_i210
+ * @hw: pointer to the HW structure
+ *
+ * Works around an errata in the PLL circuit where it occasionally
+ * provides the wrong clock frequency after power up.
+ **/
+s32 igb_pll_workaround_i210(struct e1000_hw *hw)
+{
+ s32 ret_val;
+ u32 wuc, mdicnfg, ctrl, ctrl_ext, reg_val;
+ u16 nvm_word, phy_word, pci_word, tmp_nvm;
+ int i;
+
+ /* Get and set needed register values */
+ wuc = rd32(E1000_WUC);
+ mdicnfg = rd32(E1000_MDICNFG);
+ reg_val = mdicnfg & ~E1000_MDICNFG_EXT_MDIO;
+ wr32(E1000_MDICNFG, reg_val);
+
+ /* Get data from NVM, or set default */
+ ret_val = igb_read_invm_word_i210(hw, E1000_INVM_AUTOLOAD,
+ &nvm_word);
+ if (ret_val)
+ nvm_word = E1000_INVM_DEFAULT_AL;
+ tmp_nvm = nvm_word | E1000_INVM_PLL_WO_VAL;
+ for (i = 0; i < E1000_MAX_PLL_TRIES; i++) {
+ /* check current state directly from internal PHY */
+ igb_read_phy_reg_gs40g(hw, (E1000_PHY_PLL_FREQ_PAGE |
+ E1000_PHY_PLL_FREQ_REG), &phy_word);
+ if ((phy_word & E1000_PHY_PLL_UNCONF)
+ != E1000_PHY_PLL_UNCONF) {
+ ret_val = 0;
+ break;
+ } else {
+ ret_val = -E1000_ERR_PHY;
+ }
+ /* directly reset the internal PHY */
+ ctrl = rd32(E1000_CTRL);
+ wr32(E1000_CTRL, ctrl|E1000_CTRL_PHY_RST);
+
+ ctrl_ext = rd32(E1000_CTRL_EXT);
+ ctrl_ext |= (E1000_CTRL_EXT_PHYPDEN | E1000_CTRL_EXT_SDLPE);
+ wr32(E1000_CTRL_EXT, ctrl_ext);
+
+ wr32(E1000_WUC, 0);
+ reg_val = (E1000_INVM_AUTOLOAD << 4) | (tmp_nvm << 16);
+ wr32(E1000_EEARBC_I210, reg_val);
+
+ igb_read_pci_cfg(hw, E1000_PCI_PMCSR, &pci_word);
+ pci_word |= E1000_PCI_PMCSR_D3;
+ igb_write_pci_cfg(hw, E1000_PCI_PMCSR, &pci_word);
+ usleep_range(1000, 2000);
+ pci_word &= ~E1000_PCI_PMCSR_D3;
+ igb_write_pci_cfg(hw, E1000_PCI_PMCSR, &pci_word);
+ reg_val = (E1000_INVM_AUTOLOAD << 4) | (nvm_word << 16);
+ wr32(E1000_EEARBC_I210, reg_val);
+
+ /* restore WUC register */
+ wr32(E1000_WUC, wuc);
+ }
+ /* restore MDICNFG setting */
+ wr32(E1000_MDICNFG, mdicnfg);
+ return ret_val;
+}
diff --git a/drivers/net/ethernet/intel/igb/e1000_i210.h b/drivers/net/ethernet/intel/igb/e1000_i210.h
index 907fe99..8205e19 100644
--- a/drivers/net/ethernet/intel/igb/e1000_i210.h
+++ b/drivers/net/ethernet/intel/igb/e1000_i210.h
@@ -36,6 +36,7 @@
s32 igb_write_xmdio_reg(struct e1000_hw *hw, u16 addr, u8 dev_addr, u16 data);
s32 igb_init_nvm_params_i210(struct e1000_hw *hw);
bool igb_get_flash_presence_i210(struct e1000_hw *hw);
+s32 igb_pll_workaround_i210(struct e1000_hw *hw);
#define E1000_STM_OPCODE 0xDB00
#define E1000_EEPROM_FLASH_SIZE_WORD 0x11
@@ -81,4 +82,15 @@
#define NVM_LED_1_CFG_DEFAULT_I211 0x0184
#define NVM_LED_0_2_CFG_DEFAULT_I211 0x200C
+/* PLL Defines */
+#define E1000_PCI_PMCSR 0x44
+#define E1000_PCI_PMCSR_D3 0x03
+#define E1000_MAX_PLL_TRIES 5
+#define E1000_PHY_PLL_UNCONF 0xFF
+#define E1000_PHY_PLL_FREQ_PAGE 0xFC0000
+#define E1000_PHY_PLL_FREQ_REG 0x000E
+#define E1000_INVM_DEFAULT_AL 0x202F
+#define E1000_INVM_AUTOLOAD 0x0A
+#define E1000_INVM_PLL_WO_VAL 0x0010
+
#endif
diff --git a/drivers/net/ethernet/intel/igb/e1000_mac.c b/drivers/net/ethernet/intel/igb/e1000_mac.c
index 5910a93..1e0c404 100644
--- a/drivers/net/ethernet/intel/igb/e1000_mac.c
+++ b/drivers/net/ethernet/intel/igb/e1000_mac.c
@@ -929,11 +929,10 @@
*/
if (hw->fc.requested_mode == e1000_fc_full) {
hw->fc.current_mode = e1000_fc_full;
- hw_dbg("Flow Control = FULL.\r\n");
+ hw_dbg("Flow Control = FULL.\n");
} else {
hw->fc.current_mode = e1000_fc_rx_pause;
- hw_dbg("Flow Control = "
- "RX PAUSE frames only.\r\n");
+ hw_dbg("Flow Control = RX PAUSE frames only.\n");
}
}
/* For receiving PAUSE frames ONLY.
@@ -948,7 +947,7 @@
(mii_nway_lp_ability_reg & NWAY_LPAR_PAUSE) &&
(mii_nway_lp_ability_reg & NWAY_LPAR_ASM_DIR)) {
hw->fc.current_mode = e1000_fc_tx_pause;
- hw_dbg("Flow Control = TX PAUSE frames only.\r\n");
+ hw_dbg("Flow Control = TX PAUSE frames only.\n");
}
/* For transmitting PAUSE frames ONLY.
*
@@ -962,7 +961,7 @@
!(mii_nway_lp_ability_reg & NWAY_LPAR_PAUSE) &&
(mii_nway_lp_ability_reg & NWAY_LPAR_ASM_DIR)) {
hw->fc.current_mode = e1000_fc_rx_pause;
- hw_dbg("Flow Control = RX PAUSE frames only.\r\n");
+ hw_dbg("Flow Control = RX PAUSE frames only.\n");
}
/* Per the IEEE spec, at this point flow control should be
* disabled. However, we want to consider that we could
@@ -988,10 +987,10 @@
(hw->fc.requested_mode == e1000_fc_tx_pause) ||
(hw->fc.strict_ieee)) {
hw->fc.current_mode = e1000_fc_none;
- hw_dbg("Flow Control = NONE.\r\n");
+ hw_dbg("Flow Control = NONE.\n");
} else {
hw->fc.current_mode = e1000_fc_rx_pause;
- hw_dbg("Flow Control = RX PAUSE frames only.\r\n");
+ hw_dbg("Flow Control = RX PAUSE frames only.\n");
}
/* Now we need to do one last check... If we auto-
diff --git a/drivers/net/ethernet/intel/igb/e1000_regs.h b/drivers/net/ethernet/intel/igb/e1000_regs.h
index bdb246e..8ded9a1 100644
--- a/drivers/net/ethernet/intel/igb/e1000_regs.h
+++ b/drivers/net/ethernet/intel/igb/e1000_regs.h
@@ -69,6 +69,7 @@
#define E1000_PBA 0x01000 /* Packet Buffer Allocation - RW */
#define E1000_PBS 0x01008 /* Packet Buffer Size */
#define E1000_EEMNGCTL 0x01010 /* MNG EEprom Control */
+#define E1000_EEARBC_I210 0x12024 /* EEPROM Auto Read Bus Control */
#define E1000_EEWR 0x0102C /* EEPROM Write Register - RW */
#define E1000_I2CCMD 0x01028 /* SFPI2C Command Register - RW */
#define E1000_FRTIMER 0x01048 /* Free Running Timer - RW */
diff --git a/drivers/net/ethernet/intel/igb/igb_main.c b/drivers/net/ethernet/intel/igb/igb_main.c
index 49c1e1d..359add6 100644
--- a/drivers/net/ethernet/intel/igb/igb_main.c
+++ b/drivers/net/ethernet/intel/igb/igb_main.c
@@ -5214,8 +5214,10 @@
rcu_read_lock();
for (i = 0; i < adapter->num_rx_queues; i++) {
- u32 rqdpc = rd32(E1000_RQDPC(i));
struct igb_ring *ring = adapter->rx_ring[i];
+ u32 rqdpc = rd32(E1000_RQDPC(i));
+ if (hw->mac.type >= e1000_i210)
+ wr32(E1000_RQDPC(i), 0);
if (rqdpc) {
ring->rx_stats.drops += rqdpc;
@@ -7223,6 +7225,20 @@
}
}
+void igb_read_pci_cfg(struct e1000_hw *hw, u32 reg, u16 *value)
+{
+ struct igb_adapter *adapter = hw->back;
+
+ pci_read_config_word(adapter->pdev, reg, value);
+}
+
+void igb_write_pci_cfg(struct e1000_hw *hw, u32 reg, u16 *value)
+{
+ struct igb_adapter *adapter = hw->back;
+
+ pci_write_config_word(adapter->pdev, reg, *value);
+}
+
s32 igb_read_pcie_cap_reg(struct e1000_hw *hw, u32 reg, u16 *value)
{
struct igb_adapter *adapter = hw->back;
@@ -7606,6 +7622,8 @@
if (netif_running(netdev))
igb_close(netdev);
+ else
+ igb_reset(adapter);
igb_clear_interrupt_scheme(adapter);
diff --git a/drivers/net/ethernet/intel/igb/igb_ptp.c b/drivers/net/ethernet/intel/igb/igb_ptp.c
index 9209d65..ab25e49 100644
--- a/drivers/net/ethernet/intel/igb/igb_ptp.c
+++ b/drivers/net/ethernet/intel/igb/igb_ptp.c
@@ -389,7 +389,7 @@
adapter->ptp_tx_skb = NULL;
clear_bit_unlock(__IGB_PTP_TX_IN_PROGRESS, &adapter->state);
adapter->tx_hwtstamp_timeouts++;
- dev_warn(&adapter->pdev->dev, "clearing Tx timestamp hang");
+ dev_warn(&adapter->pdev->dev, "clearing Tx timestamp hang\n");
return;
}
@@ -451,7 +451,7 @@
rd32(E1000_RXSTMPH);
adapter->last_rx_ptp_check = jiffies;
adapter->rx_hwtstamp_cleared++;
- dev_warn(&adapter->pdev->dev, "clearing Rx timestamp hang");
+ dev_warn(&adapter->pdev->dev, "clearing Rx timestamp hang\n");
}
}
diff --git a/drivers/net/usb/cdc_mbim.c b/drivers/net/usb/cdc_mbim.c
index 21f9cc0..1adf24c 100644
--- a/drivers/net/usb/cdc_mbim.c
+++ b/drivers/net/usb/cdc_mbim.c
@@ -120,6 +120,16 @@
cdc_ncm_unbind(dev, intf);
}
+/* verify that the ethernet protocol is IPv4 or IPv6 */
+static bool is_ip_proto(__be16 proto)
+{
+ switch (proto) {
+ case htons(ETH_P_IP):
+ case htons(ETH_P_IPV6):
+ return true;
+ }
+ return false;
+}
static struct sk_buff *cdc_mbim_tx_fixup(struct usbnet *dev, struct sk_buff *skb, gfp_t flags)
{
@@ -128,6 +138,7 @@
struct cdc_ncm_ctx *ctx = info->ctx;
__le32 sign = cpu_to_le32(USB_CDC_MBIM_NDP16_IPS_SIGN);
u16 tci = 0;
+ bool is_ip;
u8 *c;
if (!ctx)
@@ -137,25 +148,32 @@
if (skb->len <= ETH_HLEN)
goto error;
+ /* Some applications using e.g. packet sockets will
+ * bypass the VLAN acceleration and create tagged
+ * ethernet frames directly. We primarily look for
+ * the accelerated out-of-band tag, but fall back if
+ * required
+ */
+ skb_reset_mac_header(skb);
+ if (vlan_get_tag(skb, &tci) < 0 && skb->len > VLAN_ETH_HLEN &&
+ __vlan_get_tag(skb, &tci) == 0) {
+ is_ip = is_ip_proto(vlan_eth_hdr(skb)->h_vlan_encapsulated_proto);
+ skb_pull(skb, VLAN_ETH_HLEN);
+ } else {
+ is_ip = is_ip_proto(eth_hdr(skb)->h_proto);
+ skb_pull(skb, ETH_HLEN);
+ }
+
/* mapping VLANs to MBIM sessions:
* no tag => IPS session <0>
* 1 - 255 => IPS session <vlanid>
* 256 - 511 => DSS session <vlanid - 256>
* 512 - 4095 => unsupported, drop
*/
- vlan_get_tag(skb, &tci);
-
switch (tci & 0x0f00) {
case 0x0000: /* VLAN ID 0 - 255 */
- /* verify that datagram is IPv4 or IPv6 */
- skb_reset_mac_header(skb);
- switch (eth_hdr(skb)->h_proto) {
- case htons(ETH_P_IP):
- case htons(ETH_P_IPV6):
- break;
- default:
+ if (!is_ip)
goto error;
- }
c = (u8 *)&sign;
c[3] = tci;
break;
@@ -169,7 +187,6 @@
"unsupported tci=0x%04x\n", tci);
goto error;
}
- skb_pull(skb, ETH_HLEN);
}
spin_lock_bh(&ctx->mtx);
@@ -205,17 +222,23 @@
return;
/* need to send the NA on the VLAN dev, if any */
- if (tci)
+ rcu_read_lock();
+ if (tci) {
netdev = __vlan_find_dev_deep(dev->net, htons(ETH_P_8021Q),
tci);
- else
+ if (!netdev) {
+ rcu_read_unlock();
+ return;
+ }
+ } else {
netdev = dev->net;
- if (!netdev)
- return;
+ }
+ dev_hold(netdev);
+ rcu_read_unlock();
in6_dev = in6_dev_get(netdev);
if (!in6_dev)
- return;
+ goto out;
is_router = !!in6_dev->cnf.forwarding;
in6_dev_put(in6_dev);
@@ -225,6 +248,8 @@
true /* solicited */,
false /* override */,
true /* inc_opt */);
+out:
+ dev_put(netdev);
}
static bool is_neigh_solicit(u8 *buf, size_t len)
diff --git a/drivers/net/usb/cdc_ncm.c b/drivers/net/usb/cdc_ncm.c
index 2bb0faa..751bc06 100644
--- a/drivers/net/usb/cdc_ncm.c
+++ b/drivers/net/usb/cdc_ncm.c
@@ -785,7 +785,7 @@
skb_out->len > CDC_NCM_MIN_TX_PKT)
memset(skb_put(skb_out, ctx->tx_max - skb_out->len), 0,
ctx->tx_max - skb_out->len);
- else if ((skb_out->len % dev->maxpacket) == 0)
+ else if (skb_out->len < ctx->tx_max && (skb_out->len % dev->maxpacket) == 0)
*skb_put(skb_out, 1) = 0; /* force short packet */
/* set final frame length */
diff --git a/drivers/net/usb/qmi_wwan.c b/drivers/net/usb/qmi_wwan.c
index cc52c1d..80fa223 100644
--- a/drivers/net/usb/qmi_wwan.c
+++ b/drivers/net/usb/qmi_wwan.c
@@ -667,8 +667,25 @@
{QMI_FIXED_INTF(0x05c6, 0x9084, 4)},
{QMI_FIXED_INTF(0x05c6, 0x920d, 0)},
{QMI_FIXED_INTF(0x05c6, 0x920d, 5)},
+ {QMI_FIXED_INTF(0x0846, 0x68a2, 8)},
{QMI_FIXED_INTF(0x12d1, 0x140c, 1)}, /* Huawei E173 */
{QMI_FIXED_INTF(0x12d1, 0x14ac, 1)}, /* Huawei E1820 */
+ {QMI_FIXED_INTF(0x16d8, 0x6003, 0)}, /* CMOTech 6003 */
+ {QMI_FIXED_INTF(0x16d8, 0x6007, 0)}, /* CMOTech CHE-628S */
+ {QMI_FIXED_INTF(0x16d8, 0x6008, 0)}, /* CMOTech CMU-301 */
+ {QMI_FIXED_INTF(0x16d8, 0x6280, 0)}, /* CMOTech CHU-628 */
+ {QMI_FIXED_INTF(0x16d8, 0x7001, 0)}, /* CMOTech CHU-720S */
+ {QMI_FIXED_INTF(0x16d8, 0x7002, 0)}, /* CMOTech 7002 */
+ {QMI_FIXED_INTF(0x16d8, 0x7003, 4)}, /* CMOTech CHU-629K */
+ {QMI_FIXED_INTF(0x16d8, 0x7004, 3)}, /* CMOTech 7004 */
+ {QMI_FIXED_INTF(0x16d8, 0x7006, 5)}, /* CMOTech CGU-629 */
+ {QMI_FIXED_INTF(0x16d8, 0x700a, 4)}, /* CMOTech CHU-629S */
+ {QMI_FIXED_INTF(0x16d8, 0x7211, 0)}, /* CMOTech CHU-720I */
+ {QMI_FIXED_INTF(0x16d8, 0x7212, 0)}, /* CMOTech 7212 */
+ {QMI_FIXED_INTF(0x16d8, 0x7213, 0)}, /* CMOTech 7213 */
+ {QMI_FIXED_INTF(0x16d8, 0x7251, 1)}, /* CMOTech 7251 */
+ {QMI_FIXED_INTF(0x16d8, 0x7252, 1)}, /* CMOTech 7252 */
+ {QMI_FIXED_INTF(0x16d8, 0x7253, 1)}, /* CMOTech 7253 */
{QMI_FIXED_INTF(0x19d2, 0x0002, 1)},
{QMI_FIXED_INTF(0x19d2, 0x0012, 1)},
{QMI_FIXED_INTF(0x19d2, 0x0017, 3)},
@@ -725,21 +742,44 @@
{QMI_FIXED_INTF(0x19d2, 0x1424, 2)},
{QMI_FIXED_INTF(0x19d2, 0x1425, 2)},
{QMI_FIXED_INTF(0x19d2, 0x1426, 2)}, /* ZTE MF91 */
+ {QMI_FIXED_INTF(0x19d2, 0x1428, 2)}, /* Telewell TW-LTE 4G v2 */
{QMI_FIXED_INTF(0x19d2, 0x2002, 4)}, /* ZTE (Vodafone) K3765-Z */
{QMI_FIXED_INTF(0x0f3d, 0x68a2, 8)}, /* Sierra Wireless MC7700 */
{QMI_FIXED_INTF(0x114f, 0x68a2, 8)}, /* Sierra Wireless MC7750 */
{QMI_FIXED_INTF(0x1199, 0x68a2, 8)}, /* Sierra Wireless MC7710 in QMI mode */
{QMI_FIXED_INTF(0x1199, 0x68a2, 19)}, /* Sierra Wireless MC7710 in QMI mode */
+ {QMI_FIXED_INTF(0x1199, 0x68c0, 8)}, /* Sierra Wireless MC73xx */
+ {QMI_FIXED_INTF(0x1199, 0x68c0, 10)}, /* Sierra Wireless MC73xx */
{QMI_FIXED_INTF(0x1199, 0x901c, 8)}, /* Sierra Wireless EM7700 */
+ {QMI_FIXED_INTF(0x1199, 0x901f, 8)}, /* Sierra Wireless EM7355 */
+ {QMI_FIXED_INTF(0x1199, 0x9041, 8)}, /* Sierra Wireless MC7305/MC7355 */
{QMI_FIXED_INTF(0x1199, 0x9051, 8)}, /* Netgear AirCard 340U */
+ {QMI_FIXED_INTF(0x1199, 0x9053, 8)}, /* Sierra Wireless Modem */
+ {QMI_FIXED_INTF(0x1199, 0x9054, 8)}, /* Sierra Wireless Modem */
+ {QMI_FIXED_INTF(0x1199, 0x9055, 8)}, /* Netgear AirCard 341U */
+ {QMI_FIXED_INTF(0x1199, 0x9056, 8)}, /* Sierra Wireless Modem */
+ {QMI_FIXED_INTF(0x1199, 0x9057, 8)},
+ {QMI_FIXED_INTF(0x1199, 0x9061, 8)}, /* Sierra Wireless Modem */
{QMI_FIXED_INTF(0x1bbb, 0x011e, 4)}, /* Telekom Speedstick LTE II (Alcatel One Touch L100V LTE) */
+ {QMI_FIXED_INTF(0x1bbb, 0x0203, 2)}, /* Alcatel L800MA */
{QMI_FIXED_INTF(0x2357, 0x0201, 4)}, /* TP-LINK HSUPA Modem MA180 */
{QMI_FIXED_INTF(0x2357, 0x9000, 4)}, /* TP-LINK MA260 */
{QMI_FIXED_INTF(0x1bc7, 0x1200, 5)}, /* Telit LE920 */
{QMI_FIXED_INTF(0x1bc7, 0x1201, 2)}, /* Telit LE920 */
- {QMI_FIXED_INTF(0x0b3c, 0xc005, 6)}, /* Olivetti Olicard 200 */
+ {QMI_FIXED_INTF(0x0b3c, 0xc000, 4)}, /* Olivetti Olicard 100 */
+ {QMI_FIXED_INTF(0x0b3c, 0xc001, 4)}, /* Olivetti Olicard 120 */
+ {QMI_FIXED_INTF(0x0b3c, 0xc002, 4)}, /* Olivetti Olicard 140 */
+ {QMI_FIXED_INTF(0x0b3c, 0xc004, 6)}, /* Olivetti Olicard 155 */
+ {QMI_FIXED_INTF(0x0b3c, 0xc005, 6)}, /* Olivetti Olicard 200 */
+ {QMI_FIXED_INTF(0x0b3c, 0xc00a, 6)}, /* Olivetti Olicard 160 */
+ {QMI_FIXED_INTF(0x0b3c, 0xc00b, 4)}, /* Olivetti Olicard 500 */
{QMI_FIXED_INTF(0x1e2d, 0x0060, 4)}, /* Cinterion PLxx */
{QMI_FIXED_INTF(0x1e2d, 0x0053, 4)}, /* Cinterion PHxx,PXxx */
+ {QMI_FIXED_INTF(0x413c, 0x81a2, 8)}, /* Dell Wireless 5806 Gobi(TM) 4G LTE Mobile Broadband Card */
+ {QMI_FIXED_INTF(0x413c, 0x81a3, 8)}, /* Dell Wireless 5570 HSPA+ (42Mbps) Mobile Broadband Card */
+ {QMI_FIXED_INTF(0x413c, 0x81a4, 8)}, /* Dell Wireless 5570e HSPA+ (42Mbps) Mobile Broadband Card */
+ {QMI_FIXED_INTF(0x413c, 0x81a8, 8)}, /* Dell Wireless 5808 Gobi(TM) 4G LTE Mobile Broadband Card */
+ {QMI_FIXED_INTF(0x413c, 0x81a9, 8)}, /* Dell Wireless 5808e Gobi(TM) 4G LTE Mobile Broadband Card */
/* 4. Gobi 1000 devices */
{QMI_GOBI1K_DEVICE(0x05c6, 0x9212)}, /* Acer Gobi Modem Device */
diff --git a/drivers/net/wireless/ath/ath10k/bmi.c b/drivers/net/wireless/ath/ath10k/bmi.c
index 17d221a..a1f0996 100644
--- a/drivers/net/wireless/ath/ath10k/bmi.c
+++ b/drivers/net/wireless/ath/ath10k/bmi.c
@@ -175,7 +175,7 @@
return 0;
}
-int ath10k_bmi_execute(struct ath10k *ar, u32 address, u32 param, u32 *result)
+int ath10k_bmi_execute(struct ath10k *ar, u32 address, u32 *param)
{
struct bmi_cmd cmd;
union bmi_resp resp;
@@ -184,7 +184,7 @@
int ret;
ath10k_dbg(ATH10K_DBG_BMI, "bmi execute address 0x%x param 0x%x\n",
- address, param);
+ address, *param);
if (ar->bmi.done_sent) {
ath10k_warn("command disallowed\n");
@@ -193,7 +193,7 @@
cmd.id = __cpu_to_le32(BMI_EXECUTE);
cmd.execute.addr = __cpu_to_le32(address);
- cmd.execute.param = __cpu_to_le32(param);
+ cmd.execute.param = __cpu_to_le32(*param);
ret = ath10k_hif_exchange_bmi_msg(ar, &cmd, cmdlen, &resp, &resplen);
if (ret) {
@@ -204,13 +204,10 @@
if (resplen < sizeof(resp.execute)) {
ath10k_warn("invalid execute response length (%d)\n",
resplen);
- return -EIO;
+ return ret;
}
- *result = __le32_to_cpu(resp.execute.result);
-
- ath10k_dbg(ATH10K_DBG_BMI, "bmi execute result 0x%x\n", *result);
-
+ *param = __le32_to_cpu(resp.execute.result);
return 0;
}
diff --git a/drivers/net/wireless/ath/ath10k/bmi.h b/drivers/net/wireless/ath/ath10k/bmi.h
index 3a9bdf5..8d81ce1 100644
--- a/drivers/net/wireless/ath/ath10k/bmi.h
+++ b/drivers/net/wireless/ath/ath10k/bmi.h
@@ -217,7 +217,7 @@
ret; \
})
-int ath10k_bmi_execute(struct ath10k *ar, u32 address, u32 param, u32 *result);
+int ath10k_bmi_execute(struct ath10k *ar, u32 address, u32 *param);
int ath10k_bmi_lz_stream_start(struct ath10k *ar, u32 address);
int ath10k_bmi_lz_data(struct ath10k *ar, const void *buffer, u32 length);
int ath10k_bmi_fast_download(struct ath10k *ar, u32 address,
diff --git a/drivers/net/wireless/ath/ath10k/ce.c b/drivers/net/wireless/ath/ath10k/ce.c
index 1e4cad8..a79499c 100644
--- a/drivers/net/wireless/ath/ath10k/ce.c
+++ b/drivers/net/wireless/ath/ath10k/ce.c
@@ -840,17 +840,35 @@
static int ath10k_ce_init_src_ring(struct ath10k *ar,
unsigned int ce_id,
+ struct ath10k_ce_pipe *ce_state,
const struct ce_attr *attr)
{
struct ath10k_pci *ar_pci = ath10k_pci_priv(ar);
- struct ath10k_ce_pipe *ce_state = &ar_pci->ce_states[ce_id];
- struct ath10k_ce_ring *src_ring = ce_state->src_ring;
- u32 nentries, ctrl_addr = ath10k_ce_base_address(ce_id);
+ struct ath10k_ce_ring *src_ring;
+ unsigned int nentries = attr->src_nentries;
+ unsigned int ce_nbytes;
+ u32 ctrl_addr = ath10k_ce_base_address(ce_id);
+ dma_addr_t base_addr;
+ char *ptr;
- nentries = roundup_pow_of_two(attr->src_nentries);
+ nentries = roundup_pow_of_two(nentries);
- memset(src_ring->per_transfer_context, 0,
- nentries * sizeof(*src_ring->per_transfer_context));
+ if (ce_state->src_ring) {
+ WARN_ON(ce_state->src_ring->nentries != nentries);
+ return 0;
+ }
+
+ ce_nbytes = sizeof(struct ath10k_ce_ring) + (nentries * sizeof(void *));
+ ptr = kzalloc(ce_nbytes, GFP_KERNEL);
+ if (ptr == NULL)
+ return -ENOMEM;
+
+ ce_state->src_ring = (struct ath10k_ce_ring *)ptr;
+ src_ring = ce_state->src_ring;
+
+ ptr += sizeof(struct ath10k_ce_ring);
+ src_ring->nentries = nentries;
+ src_ring->nentries_mask = nentries - 1;
src_ring->sw_index = ath10k_ce_src_ring_read_index_get(ar, ctrl_addr);
src_ring->sw_index &= src_ring->nentries_mask;
@@ -860,87 +878,21 @@
ath10k_ce_src_ring_write_index_get(ar, ctrl_addr);
src_ring->write_index &= src_ring->nentries_mask;
- ath10k_ce_src_ring_base_addr_set(ar, ctrl_addr,
- src_ring->base_addr_ce_space);
- 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_byte_swap_set(ar, ctrl_addr, 0);
- ath10k_ce_src_ring_lowmark_set(ar, ctrl_addr, 0);
- ath10k_ce_src_ring_highmark_set(ar, ctrl_addr, nentries);
-
- ath10k_dbg(ATH10K_DBG_BOOT,
- "boot init ce src ring id %d entries %d base_addr %p\n",
- ce_id, nentries, src_ring->base_addr_owner_space);
-
- return 0;
-}
-
-static int ath10k_ce_init_dest_ring(struct ath10k *ar,
- unsigned int ce_id,
- const struct ce_attr *attr)
-{
- struct ath10k_pci *ar_pci = ath10k_pci_priv(ar);
- struct ath10k_ce_pipe *ce_state = &ar_pci->ce_states[ce_id];
- struct ath10k_ce_ring *dest_ring = ce_state->dest_ring;
- u32 nentries, ctrl_addr = ath10k_ce_base_address(ce_id);
-
- nentries = roundup_pow_of_two(attr->dest_nentries);
-
- memset(dest_ring->per_transfer_context, 0,
- nentries * sizeof(*dest_ring->per_transfer_context));
-
- dest_ring->sw_index = ath10k_ce_dest_ring_read_index_get(ar, ctrl_addr);
- dest_ring->sw_index &= dest_ring->nentries_mask;
- dest_ring->write_index =
- ath10k_ce_dest_ring_write_index_get(ar, ctrl_addr);
- dest_ring->write_index &= dest_ring->nentries_mask;
-
- ath10k_ce_dest_ring_base_addr_set(ar, ctrl_addr,
- dest_ring->base_addr_ce_space);
- 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_lowmark_set(ar, ctrl_addr, 0);
- ath10k_ce_dest_ring_highmark_set(ar, ctrl_addr, nentries);
-
- ath10k_dbg(ATH10K_DBG_BOOT,
- "boot ce dest ring id %d entries %d base_addr %p\n",
- ce_id, nentries, dest_ring->base_addr_owner_space);
-
- return 0;
-}
-
-static struct ath10k_ce_ring *
-ath10k_ce_alloc_src_ring(struct ath10k *ar, unsigned int ce_id,
- const struct ce_attr *attr)
-{
- struct ath10k_ce_ring *src_ring;
- u32 nentries = attr->src_nentries;
- dma_addr_t base_addr;
-
- nentries = roundup_pow_of_two(nentries);
-
- src_ring = kzalloc(sizeof(*src_ring) +
- (nentries *
- sizeof(*src_ring->per_transfer_context)),
- GFP_KERNEL);
- if (src_ring == NULL)
- return ERR_PTR(-ENOMEM);
-
- src_ring->nentries = nentries;
- src_ring->nentries_mask = nentries - 1;
+ src_ring->per_transfer_context = (void **)ptr;
/*
* Legacy platforms that do not support cache
* coherent DMA are unsupported
*/
src_ring->base_addr_owner_space_unaligned =
- dma_alloc_coherent(ar->dev,
- (nentries * sizeof(struct ce_desc) +
- CE_DESC_RING_ALIGN),
- &base_addr, GFP_KERNEL);
+ pci_alloc_consistent(ar_pci->pdev,
+ (nentries * sizeof(struct ce_desc) +
+ CE_DESC_RING_ALIGN),
+ &base_addr);
if (!src_ring->base_addr_owner_space_unaligned) {
- kfree(src_ring);
- return ERR_PTR(-ENOMEM);
+ kfree(ce_state->src_ring);
+ ce_state->src_ring = NULL;
+ return -ENOMEM;
}
src_ring->base_addr_ce_space_unaligned = base_addr;
@@ -960,54 +912,88 @@
kmalloc((nentries * sizeof(struct ce_desc) +
CE_DESC_RING_ALIGN), GFP_KERNEL);
if (!src_ring->shadow_base_unaligned) {
- dma_free_coherent(ar->dev,
- (nentries * sizeof(struct ce_desc) +
- CE_DESC_RING_ALIGN),
- src_ring->base_addr_owner_space,
- src_ring->base_addr_ce_space);
- kfree(src_ring);
- return ERR_PTR(-ENOMEM);
+ pci_free_consistent(ar_pci->pdev,
+ (nentries * sizeof(struct ce_desc) +
+ CE_DESC_RING_ALIGN),
+ src_ring->base_addr_owner_space,
+ src_ring->base_addr_ce_space);
+ kfree(ce_state->src_ring);
+ ce_state->src_ring = NULL;
+ return -ENOMEM;
}
src_ring->shadow_base = PTR_ALIGN(
src_ring->shadow_base_unaligned,
CE_DESC_RING_ALIGN);
- return src_ring;
+ ath10k_ce_src_ring_base_addr_set(ar, ctrl_addr,
+ src_ring->base_addr_ce_space);
+ 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_byte_swap_set(ar, ctrl_addr, 0);
+ ath10k_ce_src_ring_lowmark_set(ar, ctrl_addr, 0);
+ ath10k_ce_src_ring_highmark_set(ar, ctrl_addr, nentries);
+
+ ath10k_dbg(ATH10K_DBG_BOOT,
+ "boot ce src ring id %d entries %d base_addr %p\n",
+ ce_id, nentries, src_ring->base_addr_owner_space);
+
+ return 0;
}
-static struct ath10k_ce_ring *
-ath10k_ce_alloc_dest_ring(struct ath10k *ar, unsigned int ce_id,
- const struct ce_attr *attr)
+static int ath10k_ce_init_dest_ring(struct ath10k *ar,
+ unsigned int ce_id,
+ struct ath10k_ce_pipe *ce_state,
+ const struct ce_attr *attr)
{
+ struct ath10k_pci *ar_pci = ath10k_pci_priv(ar);
struct ath10k_ce_ring *dest_ring;
- u32 nentries;
+ unsigned int nentries = attr->dest_nentries;
+ unsigned int ce_nbytes;
+ u32 ctrl_addr = ath10k_ce_base_address(ce_id);
dma_addr_t base_addr;
+ char *ptr;
- nentries = roundup_pow_of_two(attr->dest_nentries);
+ nentries = roundup_pow_of_two(nentries);
- dest_ring = kzalloc(sizeof(*dest_ring) +
- (nentries *
- sizeof(*dest_ring->per_transfer_context)),
- GFP_KERNEL);
- if (dest_ring == NULL)
- return ERR_PTR(-ENOMEM);
+ if (ce_state->dest_ring) {
+ WARN_ON(ce_state->dest_ring->nentries != nentries);
+ return 0;
+ }
+ ce_nbytes = sizeof(struct ath10k_ce_ring) + (nentries * sizeof(void *));
+ ptr = kzalloc(ce_nbytes, GFP_KERNEL);
+ if (ptr == NULL)
+ return -ENOMEM;
+
+ ce_state->dest_ring = (struct ath10k_ce_ring *)ptr;
+ dest_ring = ce_state->dest_ring;
+
+ ptr += sizeof(struct ath10k_ce_ring);
dest_ring->nentries = nentries;
dest_ring->nentries_mask = nentries - 1;
+ dest_ring->sw_index = ath10k_ce_dest_ring_read_index_get(ar, ctrl_addr);
+ dest_ring->sw_index &= dest_ring->nentries_mask;
+ dest_ring->write_index =
+ ath10k_ce_dest_ring_write_index_get(ar, ctrl_addr);
+ dest_ring->write_index &= dest_ring->nentries_mask;
+
+ dest_ring->per_transfer_context = (void **)ptr;
+
/*
* Legacy platforms that do not support cache
* coherent DMA are unsupported
*/
dest_ring->base_addr_owner_space_unaligned =
- dma_alloc_coherent(ar->dev,
- (nentries * sizeof(struct ce_desc) +
- CE_DESC_RING_ALIGN),
- &base_addr, GFP_KERNEL);
+ pci_alloc_consistent(ar_pci->pdev,
+ (nentries * sizeof(struct ce_desc) +
+ CE_DESC_RING_ALIGN),
+ &base_addr);
if (!dest_ring->base_addr_owner_space_unaligned) {
- kfree(dest_ring);
- return ERR_PTR(-ENOMEM);
+ kfree(ce_state->dest_ring);
+ ce_state->dest_ring = NULL;
+ return -ENOMEM;
}
dest_ring->base_addr_ce_space_unaligned = base_addr;
@@ -1026,7 +1012,39 @@
dest_ring->base_addr_ce_space_unaligned,
CE_DESC_RING_ALIGN);
- return dest_ring;
+ ath10k_ce_dest_ring_base_addr_set(ar, ctrl_addr,
+ dest_ring->base_addr_ce_space);
+ 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_lowmark_set(ar, ctrl_addr, 0);
+ ath10k_ce_dest_ring_highmark_set(ar, ctrl_addr, nentries);
+
+ ath10k_dbg(ATH10K_DBG_BOOT,
+ "boot ce dest ring id %d entries %d base_addr %p\n",
+ ce_id, nentries, dest_ring->base_addr_owner_space);
+
+ return 0;
+}
+
+static struct ath10k_ce_pipe *ath10k_ce_init_state(struct ath10k *ar,
+ unsigned int ce_id,
+ const struct ce_attr *attr)
+{
+ struct ath10k_pci *ar_pci = ath10k_pci_priv(ar);
+ struct ath10k_ce_pipe *ce_state = &ar_pci->ce_states[ce_id];
+ u32 ctrl_addr = ath10k_ce_base_address(ce_id);
+
+ spin_lock_bh(&ar_pci->ce_lock);
+
+ ce_state->ar = ar;
+ ce_state->id = ce_id;
+ ce_state->ctrl_addr = ctrl_addr;
+ ce_state->attr_flags = attr->flags;
+ ce_state->src_sz_max = attr->src_sz_max;
+
+ spin_unlock_bh(&ar_pci->ce_lock);
+
+ return ce_state;
}
/*
@@ -1036,11 +1054,11 @@
* initialization. It may be that only one side or the other is
* initialized by software/firmware.
*/
-int ath10k_ce_init_pipe(struct ath10k *ar, unsigned int ce_id,
- const struct ce_attr *attr)
+struct ath10k_ce_pipe *ath10k_ce_init(struct ath10k *ar,
+ unsigned int ce_id,
+ const struct ce_attr *attr)
{
- struct ath10k_pci *ar_pci = ath10k_pci_priv(ar);
- struct ath10k_ce_pipe *ce_state = &ar_pci->ce_states[ce_id];
+ struct ath10k_ce_pipe *ce_state;
int ret;
/*
@@ -1056,128 +1074,64 @@
ret = ath10k_pci_wake(ar);
if (ret)
- return ret;
+ return NULL;
- spin_lock_bh(&ar_pci->ce_lock);
- ce_state->ar = ar;
- ce_state->id = ce_id;
- ce_state->ctrl_addr = ath10k_ce_base_address(ce_id);
- ce_state->attr_flags = attr->flags;
- ce_state->src_sz_max = attr->src_sz_max;
- spin_unlock_bh(&ar_pci->ce_lock);
+ ce_state = ath10k_ce_init_state(ar, ce_id, attr);
+ if (!ce_state) {
+ ath10k_err("Failed to initialize CE state for ID: %d\n", ce_id);
+ goto out;
+ }
if (attr->src_nentries) {
- ret = ath10k_ce_init_src_ring(ar, ce_id, attr);
+ ret = ath10k_ce_init_src_ring(ar, ce_id, ce_state, attr);
if (ret) {
ath10k_err("Failed to initialize CE src ring for ID: %d (%d)\n",
ce_id, ret);
+ ath10k_ce_deinit(ce_state);
+ ce_state = NULL;
goto out;
}
}
if (attr->dest_nentries) {
- ret = ath10k_ce_init_dest_ring(ar, ce_id, attr);
+ ret = ath10k_ce_init_dest_ring(ar, ce_id, ce_state, attr);
if (ret) {
ath10k_err("Failed to initialize CE dest ring for ID: %d (%d)\n",
ce_id, ret);
+ ath10k_ce_deinit(ce_state);
+ ce_state = NULL;
goto out;
}
}
out:
ath10k_pci_sleep(ar);
- return ret;
+ return ce_state;
}
-static void ath10k_ce_deinit_src_ring(struct ath10k *ar, unsigned int ce_id)
+void ath10k_ce_deinit(struct ath10k_ce_pipe *ce_state)
{
- u32 ctrl_addr = ath10k_ce_base_address(ce_id);
-
- ath10k_ce_src_ring_base_addr_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_highmark_set(ar, ctrl_addr, 0);
-}
-
-static void ath10k_ce_deinit_dest_ring(struct ath10k *ar, unsigned int ce_id)
-{
- u32 ctrl_addr = ath10k_ce_base_address(ce_id);
-
- ath10k_ce_dest_ring_base_addr_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);
-}
-
-void ath10k_ce_deinit_pipe(struct ath10k *ar, unsigned int ce_id)
-{
- int ret;
-
- ret = ath10k_pci_wake(ar);
- if (ret)
- return;
-
- ath10k_ce_deinit_src_ring(ar, ce_id);
- ath10k_ce_deinit_dest_ring(ar, ce_id);
-
- ath10k_pci_sleep(ar);
-}
-
-int ath10k_ce_alloc_pipe(struct ath10k *ar, int ce_id,
- const struct ce_attr *attr)
-{
+ struct ath10k *ar = ce_state->ar;
struct ath10k_pci *ar_pci = ath10k_pci_priv(ar);
- struct ath10k_ce_pipe *ce_state = &ar_pci->ce_states[ce_id];
- int ret;
-
- if (attr->src_nentries) {
- ce_state->src_ring = ath10k_ce_alloc_src_ring(ar, ce_id, attr);
- if (IS_ERR(ce_state->src_ring)) {
- ret = PTR_ERR(ce_state->src_ring);
- ath10k_err("failed to allocate copy engine source ring %d: %d\n",
- ce_id, ret);
- ce_state->src_ring = NULL;
- return ret;
- }
- }
-
- if (attr->dest_nentries) {
- ce_state->dest_ring = ath10k_ce_alloc_dest_ring(ar, ce_id,
- attr);
- if (IS_ERR(ce_state->dest_ring)) {
- ret = PTR_ERR(ce_state->dest_ring);
- ath10k_err("failed to allocate copy engine destination ring %d: %d\n",
- ce_id, ret);
- ce_state->dest_ring = NULL;
- return ret;
- }
- }
-
- return 0;
-}
-
-void ath10k_ce_free_pipe(struct ath10k *ar, int ce_id)
-{
- struct ath10k_pci *ar_pci = ath10k_pci_priv(ar);
- struct ath10k_ce_pipe *ce_state = &ar_pci->ce_states[ce_id];
if (ce_state->src_ring) {
kfree(ce_state->src_ring->shadow_base_unaligned);
- dma_free_coherent(ar->dev,
- (ce_state->src_ring->nentries *
- sizeof(struct ce_desc) +
- CE_DESC_RING_ALIGN),
- ce_state->src_ring->base_addr_owner_space,
- ce_state->src_ring->base_addr_ce_space);
+ pci_free_consistent(ar_pci->pdev,
+ (ce_state->src_ring->nentries *
+ sizeof(struct ce_desc) +
+ CE_DESC_RING_ALIGN),
+ ce_state->src_ring->base_addr_owner_space,
+ ce_state->src_ring->base_addr_ce_space);
kfree(ce_state->src_ring);
}
if (ce_state->dest_ring) {
- dma_free_coherent(ar->dev,
- (ce_state->dest_ring->nentries *
- sizeof(struct ce_desc) +
- CE_DESC_RING_ALIGN),
- ce_state->dest_ring->base_addr_owner_space,
- ce_state->dest_ring->base_addr_ce_space);
+ pci_free_consistent(ar_pci->pdev,
+ (ce_state->dest_ring->nentries *
+ sizeof(struct ce_desc) +
+ CE_DESC_RING_ALIGN),
+ ce_state->dest_ring->base_addr_owner_space,
+ ce_state->dest_ring->base_addr_ce_space);
kfree(ce_state->dest_ring);
}
diff --git a/drivers/net/wireless/ath/ath10k/ce.h b/drivers/net/wireless/ath/ath10k/ce.h
index fd0bc35..8eb7f99 100644
--- a/drivers/net/wireless/ath/ath10k/ce.h
+++ b/drivers/net/wireless/ath/ath10k/ce.h
@@ -104,8 +104,7 @@
void *shadow_base_unaligned;
struct ce_desc *shadow_base;
- /* keep last */
- void *per_transfer_context[0];
+ void **per_transfer_context;
};
struct ath10k_ce_pipe {
@@ -211,12 +210,10 @@
/*==================CE Engine Initialization=======================*/
-int ath10k_ce_init_pipe(struct ath10k *ar, unsigned int ce_id,
- const struct ce_attr *attr);
-void ath10k_ce_deinit_pipe(struct ath10k *ar, unsigned int ce_id);
-int ath10k_ce_alloc_pipe(struct ath10k *ar, int ce_id,
- const struct ce_attr *attr);
-void ath10k_ce_free_pipe(struct ath10k *ar, int ce_id);
+/* Initialize an instance of a CE */
+struct ath10k_ce_pipe *ath10k_ce_init(struct ath10k *ar,
+ unsigned int ce_id,
+ const struct ce_attr *attr);
/*==================CE Engine Shutdown=======================*/
/*
@@ -239,6 +236,8 @@
unsigned int *nbytesp,
unsigned int *transfer_idp);
+void ath10k_ce_deinit(struct ath10k_ce_pipe *ce_state);
+
/*==================CE Interrupt Handlers====================*/
void ath10k_ce_per_engine_service_any(struct ath10k *ar);
void ath10k_ce_per_engine_service(struct ath10k *ar, unsigned int ce_id);
diff --git a/drivers/net/wireless/ath/ath10k/core.c b/drivers/net/wireless/ath/ath10k/core.c
index 75b3dfb..ebc5fc2 100644
--- a/drivers/net/wireless/ath/ath10k/core.c
+++ b/drivers/net/wireless/ath/ath10k/core.c
@@ -249,40 +249,30 @@
static int ath10k_download_and_run_otp(struct ath10k *ar)
{
- u32 result, address = ar->hw_params.patch_load_addr;
+ u32 address = ar->hw_params.patch_load_addr;
+ u32 exec_param;
int ret;
/* OTP is optional */
- if (!ar->otp_data || !ar->otp_len) {
- ath10k_warn("Not running otp, calibration will be incorrect (otp-data %p otp_len %zd)!\n",
- ar->otp_data, ar->otp_len);
+ if (!ar->otp_data || !ar->otp_len)
return 0;
- }
-
- ath10k_dbg(ATH10K_DBG_BOOT, "boot upload otp to 0x%x len %zd\n",
- address, ar->otp_len);
ret = ath10k_bmi_fast_download(ar, address, ar->otp_data, ar->otp_len);
if (ret) {
ath10k_err("could not write otp (%d)\n", ret);
- return ret;
+ goto exit;
}
- ret = ath10k_bmi_execute(ar, address, 0, &result);
+ exec_param = 0;
+ ret = ath10k_bmi_execute(ar, address, &exec_param);
if (ret) {
ath10k_err("could not execute otp (%d)\n", ret);
- return ret;
+ goto exit;
}
- ath10k_dbg(ATH10K_DBG_BOOT, "boot otp execute result %d\n", result);
-
- if (result != 0) {
- ath10k_err("otp calibration failed: %d", result);
- return -EINVAL;
- }
-
- return 0;
+exit:
+ return ret;
}
static int ath10k_download_fw(struct ath10k *ar)
@@ -399,8 +389,8 @@
/* first fetch the firmware file (firmware-*.bin) */
ar->firmware = ath10k_fetch_fw_file(ar, ar->hw_params.fw.dir, name);
if (IS_ERR(ar->firmware)) {
- ath10k_err("could not fetch firmware file '%s/%s': %ld\n",
- ar->hw_params.fw.dir, name, PTR_ERR(ar->firmware));
+ ath10k_err("Could not fetch firmware file '%s': %ld\n",
+ name, PTR_ERR(ar->firmware));
return PTR_ERR(ar->firmware);
}
@@ -411,14 +401,14 @@
magic_len = strlen(ATH10K_FIRMWARE_MAGIC) + 1;
if (len < magic_len) {
- ath10k_err("firmware file '%s/%s' too small to contain magic: %zu\n",
- ar->hw_params.fw.dir, name, len);
+ ath10k_err("firmware image too small to contain magic: %zu\n",
+ len);
ret = -EINVAL;
goto err;
}
if (memcmp(data, ATH10K_FIRMWARE_MAGIC, magic_len) != 0) {
- ath10k_err("invalid firmware magic\n");
+ ath10k_err("Invalid firmware magic\n");
ret = -EINVAL;
goto err;
}
@@ -440,7 +430,7 @@
data += sizeof(*hdr);
if (len < ie_len) {
- ath10k_err("invalid length for FW IE %d (%zu < %zu)\n",
+ ath10k_err("Invalid length for FW IE %d (%zu < %zu)\n",
ie_id, len, ie_len);
ret = -EINVAL;
goto err;
@@ -523,8 +513,8 @@
}
if (!ar->firmware_data || !ar->firmware_len) {
- ath10k_warn("No ATH10K_FW_IE_FW_IMAGE found from '%s/%s', skipping\n",
- ar->hw_params.fw.dir, name);
+ ath10k_warn("No ATH10K_FW_IE_FW_IMAGE found from %s, skipping\n",
+ name);
ret = -ENOMEDIUM;
goto err;
}
@@ -541,9 +531,7 @@
ar->hw_params.fw.board);
if (IS_ERR(ar->board)) {
ret = PTR_ERR(ar->board);
- ath10k_err("could not fetch board data '%s/%s' (%d)\n",
- ar->hw_params.fw.dir, ar->hw_params.fw.board,
- ret);
+ ath10k_err("could not fetch board data (%d)\n", ret);
goto err;
}
@@ -561,21 +549,19 @@
{
int ret;
- ar->fw_api = 2;
- ath10k_dbg(ATH10K_DBG_BOOT, "trying fw api %d\n", ar->fw_api);
-
ret = ath10k_core_fetch_firmware_api_n(ar, ATH10K_FW_API2_FILE);
- if (ret == 0)
- goto success;
-
- ar->fw_api = 1;
- ath10k_dbg(ATH10K_DBG_BOOT, "trying fw api %d\n", ar->fw_api);
+ if (ret == 0) {
+ ar->fw_api = 2;
+ goto out;
+ }
ret = ath10k_core_fetch_firmware_api_1(ar);
if (ret)
return ret;
-success:
+ ar->fw_api = 1;
+
+out:
ath10k_dbg(ATH10K_DBG_BOOT, "using fw api %d\n", ar->fw_api);
return 0;
@@ -586,22 +572,16 @@
int ret;
ret = ath10k_download_board_data(ar);
- if (ret) {
- ath10k_err("failed to download board data: %d\n", ret);
+ if (ret)
return ret;
- }
ret = ath10k_download_and_run_otp(ar);
- if (ret) {
- ath10k_err("failed to run otp: %d\n", ret);
+ if (ret)
return ret;
- }
ret = ath10k_download_fw(ar);
- if (ret) {
- ath10k_err("failed to download firmware: %d\n", ret);
+ if (ret)
return ret;
- }
return ret;
}
@@ -680,8 +660,8 @@
switch (ar->state) {
case ATH10K_STATE_ON:
- ar->state = ATH10K_STATE_RESTARTING;
ath10k_halt(ar);
+ ar->state = ATH10K_STATE_RESTARTING;
ieee80211_restart_hw(ar->hw);
break;
case ATH10K_STATE_OFF:
@@ -855,12 +835,9 @@
INIT_LIST_HEAD(&ar->arvifs);
if (!test_bit(ATH10K_FLAG_FIRST_BOOT_DONE, &ar->dev_flags))
- ath10k_info("%s (0x%08x, 0x%08x) fw %s api %d htt %d.%d\n",
- ar->hw_params.name,
- ar->target_version,
- ar->chip_id,
- ar->hw->wiphy->fw_version,
- ar->fw_api,
+ ath10k_info("%s (0x%x) fw %s api %d htt %d.%d\n",
+ ar->hw_params.name, ar->target_version,
+ ar->hw->wiphy->fw_version, ar->fw_api,
ar->htt.target_version_major,
ar->htt.target_version_minor);
@@ -908,9 +885,7 @@
lockdep_assert_held(&ar->conf_mutex);
/* try to suspend target */
- if (ar->state != ATH10K_STATE_RESTARTING)
- ath10k_wait_for_suspend(ar, WMI_PDEV_SUSPEND_AND_DISABLE_INTR);
-
+ ath10k_wait_for_suspend(ar, WMI_PDEV_SUSPEND_AND_DISABLE_INTR);
ath10k_debug_stop(ar);
ath10k_htc_stop(&ar->htc);
ath10k_htt_detach(&ar->htt);
diff --git a/drivers/net/wireless/ath/ath10k/core.h b/drivers/net/wireless/ath/ath10k/core.h
index 9b86e57..80aa5a4 100644
--- a/drivers/net/wireless/ath/ath10k/core.h
+++ b/drivers/net/wireless/ath/ath10k/core.h
@@ -119,7 +119,6 @@
u8 peer_macaddr[ETH_ALEN];
u32 peer_rssi;
u32 peer_tx_rate;
- u32 peer_rx_rate; /* 10x only */
};
struct ath10k_target_stats {
@@ -131,12 +130,6 @@
u32 cycle_count;
u32 phy_err_count;
u32 chan_tx_power;
- u32 ack_rx_bad;
- u32 rts_bad;
- u32 rts_good;
- u32 fcs_bad;
- u32 no_beacons;
- u32 mib_int_count;
/* PDEV TX stats */
s32 comp_queued;
@@ -267,8 +260,6 @@
u8 fixed_rate;
u8 fixed_nss;
u8 force_sgi;
- bool use_cts_prot;
- int num_legacy_stations;
};
struct ath10k_vif_iter {
@@ -428,18 +419,13 @@
struct cfg80211_chan_def chandef;
int free_vdev_map;
- bool promisc;
- bool monitor;
int monitor_vdev_id;
- bool monitor_started;
+ bool monitor_enabled;
+ bool monitor_present;
unsigned int filter_flags;
unsigned long dev_flags;
u32 dfs_block_radar_events;
- /* protected by conf_mutex */
- bool radar_enabled;
- int num_started_vdevs;
-
struct wmi_pdev_set_wmm_params_arg wmm_params;
struct completion install_key_done;
diff --git a/drivers/net/wireless/ath/ath10k/debug.c b/drivers/net/wireless/ath/ath10k/debug.c
index 0386550..a84691e 100644
--- a/drivers/net/wireless/ath/ath10k/debug.c
+++ b/drivers/net/wireless/ath/ath10k/debug.c
@@ -161,7 +161,7 @@
u8 *tmp = ev->data;
struct ath10k_target_stats *stats;
int num_pdev_stats, num_vdev_stats, num_peer_stats;
- struct wmi_pdev_stats_10x *ps;
+ struct wmi_pdev_stats *ps;
int i;
spin_lock_bh(&ar->data_lock);
@@ -173,7 +173,7 @@
num_peer_stats = __le32_to_cpu(ev->num_peer_stats); /* 0 or max peers */
if (num_pdev_stats) {
- ps = (struct wmi_pdev_stats_10x *)tmp;
+ ps = (struct wmi_pdev_stats *)tmp;
stats->ch_noise_floor = __le32_to_cpu(ps->chan_nf);
stats->tx_frame_count = __le32_to_cpu(ps->tx_frame_count);
@@ -228,18 +228,7 @@
stats->phy_err_drop = __le32_to_cpu(ps->wal.rx.phy_err_drop);
stats->mpdu_errs = __le32_to_cpu(ps->wal.rx.mpdu_errs);
- if (test_bit(ATH10K_FW_FEATURE_WMI_10X,
- ar->fw_features)) {
- stats->ack_rx_bad = __le32_to_cpu(ps->ack_rx_bad);
- stats->rts_bad = __le32_to_cpu(ps->rts_bad);
- stats->rts_good = __le32_to_cpu(ps->rts_good);
- stats->fcs_bad = __le32_to_cpu(ps->fcs_bad);
- stats->no_beacons = __le32_to_cpu(ps->no_beacons);
- stats->mib_int_count = __le32_to_cpu(ps->mib_int_count);
- tmp += sizeof(struct wmi_pdev_stats_10x);
- } else {
- tmp += sizeof(struct wmi_pdev_stats_old);
- }
+ tmp += sizeof(struct wmi_pdev_stats);
}
/* 0 or max vdevs */
@@ -254,29 +243,22 @@
}
if (num_peer_stats) {
- struct wmi_peer_stats_10x *peer_stats;
+ struct wmi_peer_stats *peer_stats;
struct ath10k_peer_stat *s;
stats->peers = num_peer_stats;
for (i = 0; i < num_peer_stats; i++) {
- peer_stats = (struct wmi_peer_stats_10x *)tmp;
+ peer_stats = (struct wmi_peer_stats *)tmp;
s = &stats->peer_stat[i];
- memcpy(s->peer_macaddr, &peer_stats->peer_macaddr.addr,
- ETH_ALEN);
+ WMI_MAC_ADDR_TO_CHAR_ARRAY(&peer_stats->peer_macaddr,
+ s->peer_macaddr);
s->peer_rssi = __le32_to_cpu(peer_stats->peer_rssi);
s->peer_tx_rate =
__le32_to_cpu(peer_stats->peer_tx_rate);
- if (test_bit(ATH10K_FW_FEATURE_WMI_10X,
- ar->fw_features)) {
- s->peer_rx_rate =
- __le32_to_cpu(peer_stats->peer_rx_rate);
- tmp += sizeof(struct wmi_peer_stats_10x);
- } else {
- tmp += sizeof(struct wmi_peer_stats_old);
- }
+ tmp += sizeof(struct wmi_peer_stats);
}
}
@@ -290,7 +272,7 @@
struct ath10k *ar = file->private_data;
struct ath10k_target_stats *fw_stats;
char *buf = NULL;
- unsigned int len = 0, buf_len = 8000;
+ unsigned int len = 0, buf_len = 2500;
ssize_t ret_cnt = 0;
long left;
int i;
@@ -338,16 +320,6 @@
"Cycle count", fw_stats->cycle_count);
len += scnprintf(buf + len, buf_len - len, "%30s %10u\n",
"PHY error count", fw_stats->phy_err_count);
- len += scnprintf(buf + len, buf_len - len, "%30s %10u\n",
- "RTS bad count", fw_stats->rts_bad);
- len += scnprintf(buf + len, buf_len - len, "%30s %10u\n",
- "RTS good count", fw_stats->rts_good);
- len += scnprintf(buf + len, buf_len - len, "%30s %10u\n",
- "FCS bad count", fw_stats->fcs_bad);
- len += scnprintf(buf + len, buf_len - len, "%30s %10u\n",
- "No beacon count", fw_stats->no_beacons);
- len += scnprintf(buf + len, buf_len - len, "%30s %10u\n",
- "MIB int count", fw_stats->mib_int_count);
len += scnprintf(buf + len, buf_len - len, "\n");
len += scnprintf(buf + len, buf_len - len, "%30s\n",
@@ -439,8 +411,8 @@
"MPDU errors (FCS, MIC, ENC)", fw_stats->mpdu_errs);
len += scnprintf(buf + len, buf_len - len, "\n");
- len += scnprintf(buf + len, buf_len - len, "%30s (%d)\n",
- "ath10k PEER stats", fw_stats->peers);
+ len += scnprintf(buf + len, buf_len - len, "%30s\n",
+ "ath10k PEER stats");
len += scnprintf(buf + len, buf_len - len, "%30s\n\n",
"=================");
@@ -453,9 +425,6 @@
len += scnprintf(buf + len, buf_len - len, "%30s %u\n",
"Peer TX rate",
fw_stats->peer_stat[i].peer_tx_rate);
- len += scnprintf(buf + len, buf_len - len, "%30s %u\n",
- "Peer RX rate",
- fw_stats->peer_stat[i].peer_rx_rate);
len += scnprintf(buf + len, buf_len - len, "\n");
}
spin_unlock_bh(&ar->data_lock);
@@ -482,37 +451,27 @@
char __user *user_buf,
size_t count, loff_t *ppos)
{
- const char buf[] = "To simulate firmware crash write one of the"
- " keywords to this file:\n `soft` - this will send"
- " WMI_FORCE_FW_HANG_ASSERT to firmware if FW"
- " supports that command.\n `hard` - this will send"
- " to firmware command with illegal parameters"
- " causing firmware crash.\n";
-
+ const char buf[] = "To simulate firmware crash write the keyword"
+ " `crash` to this file.\nThis will force firmware"
+ " to report a crash to the host system.\n";
return simple_read_from_buffer(user_buf, count, ppos, buf, strlen(buf));
}
-/* Simulate firmware crash:
- * 'soft': Call wmi command causing firmware hang. This firmware hang is
- * recoverable by warm firmware reset.
- * 'hard': Force firmware crash by setting any vdev parameter for not allowed
- * vdev id. This is hard firmware crash because it is recoverable only by cold
- * firmware reset.
- */
static ssize_t ath10k_write_simulate_fw_crash(struct file *file,
const char __user *user_buf,
size_t count, loff_t *ppos)
{
struct ath10k *ar = file->private_data;
- char buf[32];
+ char buf[32] = {};
int ret;
mutex_lock(&ar->conf_mutex);
simple_write_to_buffer(buf, sizeof(buf) - 1, ppos, user_buf, count);
-
- /* make sure that buf is null terminated */
- buf[sizeof(buf) - 1] = 0;
+ if (strcmp(buf, "crash") && strcmp(buf, "crash\n")) {
+ ret = -EINVAL;
+ goto exit;
+ }
if (ar->state != ATH10K_STATE_ON &&
ar->state != ATH10K_STATE_RESTARTED) {
@@ -520,30 +479,14 @@
goto exit;
}
- /* drop the possible '\n' from the end */
- if (buf[count - 1] == '\n') {
- buf[count - 1] = 0;
- count--;
- }
+ ath10k_info("simulating firmware crash\n");
- if (!strcmp(buf, "soft")) {
- ath10k_info("simulating soft firmware crash\n");
- ret = ath10k_wmi_force_fw_hang(ar, WMI_FORCE_FW_HANG_ASSERT, 0);
- } else if (!strcmp(buf, "hard")) {
- ath10k_info("simulating hard firmware crash\n");
- ret = ath10k_wmi_vdev_set_param(ar, TARGET_NUM_VDEVS + 1,
- ar->wmi.vdev_param->rts_threshold, 0);
- } else {
- ret = -EINVAL;
- goto exit;
- }
+ ret = ath10k_wmi_force_fw_hang(ar, WMI_FORCE_FW_HANG_ASSERT, 0);
+ if (ret)
+ ath10k_warn("failed to force fw hang (%d)\n", ret);
- if (ret) {
- ath10k_warn("failed to simulate firmware crash: %d\n", ret);
- goto exit;
- }
-
- ret = count;
+ if (ret == 0)
+ ret = count;
exit:
mutex_unlock(&ar->conf_mutex);
diff --git a/drivers/net/wireless/ath/ath10k/htc.c b/drivers/net/wireless/ath/ath10k/htc.c
index 5b58dbb..7f1bccd 100644
--- a/drivers/net/wireless/ath/ath10k/htc.c
+++ b/drivers/net/wireless/ath/ath10k/htc.c
@@ -157,9 +157,6 @@
goto err_pull;
}
ep->tx_credits -= credits;
- ath10k_dbg(ATH10K_DBG_HTC,
- "htc ep %d consumed %d credits (total %d)\n",
- eid, credits, ep->tx_credits);
spin_unlock_bh(&htc->tx_lock);
}
@@ -188,9 +185,6 @@
if (ep->tx_credit_flow_enabled) {
spin_lock_bh(&htc->tx_lock);
ep->tx_credits += credits;
- ath10k_dbg(ATH10K_DBG_HTC,
- "htc ep %d reverted %d credits back (total %d)\n",
- eid, credits, ep->tx_credits);
spin_unlock_bh(&htc->tx_lock);
if (ep->ep_ops.ep_tx_credits)
@@ -240,12 +234,12 @@
if (report->eid >= ATH10K_HTC_EP_COUNT)
break;
+ ath10k_dbg(ATH10K_DBG_HTC, "ep %d got %d credits\n",
+ report->eid, report->credits);
+
ep = &htc->endpoint[report->eid];
ep->tx_credits += report->credits;
- ath10k_dbg(ATH10K_DBG_HTC, "htc ep %d got %d credits (total %d)\n",
- report->eid, report->credits, ep->tx_credits);
-
if (ep->ep_ops.ep_tx_credits) {
spin_unlock_bh(&htc->tx_lock);
ep->ep_ops.ep_tx_credits(htc->ar);
diff --git a/drivers/net/wireless/ath/ath10k/htt.h b/drivers/net/wireless/ath/ath10k/htt.h
index 645a563..654867f 100644
--- a/drivers/net/wireless/ath/ath10k/htt.h
+++ b/drivers/net/wireless/ath/ath10k/htt.h
@@ -21,7 +21,6 @@
#include <linux/bug.h>
#include <linux/interrupt.h>
#include <linux/dmapool.h>
-#include <net/mac80211.h>
#include "htc.h"
#include "rx_desc.h"
@@ -1173,6 +1172,23 @@
u16 peer_id;
};
+struct htt_rx_info {
+ struct sk_buff *skb;
+ enum htt_rx_mpdu_status status;
+ enum htt_rx_mpdu_encrypt_type encrypt_type;
+ s8 signal;
+ struct {
+ u8 info0;
+ u32 info1;
+ u32 info2;
+ } rate;
+
+ u32 tsf;
+ bool fcs_err;
+ bool amsdu_more;
+ bool mic_err;
+};
+
struct ath10k_htt_txbuf {
struct htt_data_tx_desc_frag frags[2];
struct ath10k_htc_hdr htc_hdr;
@@ -1273,9 +1289,6 @@
struct tasklet_struct txrx_compl_task;
struct sk_buff_head tx_compl_q;
struct sk_buff_head rx_compl_q;
-
- /* rx_status template */
- struct ieee80211_rx_status rx_status;
};
#define RX_HTT_HDR_STATUS_LEN 64
diff --git a/drivers/net/wireless/ath/ath10k/htt_rx.c b/drivers/net/wireless/ath/ath10k/htt_rx.c
index f85a3cf..cdcbe2d 100644
--- a/drivers/net/wireless/ath/ath10k/htt_rx.c
+++ b/drivers/net/wireless/ath/ath10k/htt_rx.c
@@ -297,7 +297,6 @@
}
}
-/* return: < 0 fatal error, 0 - non chained msdu, 1 chained msdu */
static int ath10k_htt_rx_amsdu_pop(struct ath10k_htt *htt,
u8 **fw_desc, int *fw_desc_len,
struct sk_buff **head_msdu,
@@ -311,7 +310,7 @@
if (htt->rx_confused) {
ath10k_warn("htt is confused. refusing rx\n");
- return -1;
+ return 0;
}
msdu = *head_msdu = ath10k_htt_rx_netbuf_pop(htt);
@@ -443,9 +442,6 @@
}
*tail_msdu = msdu;
- if (*head_msdu == NULL)
- msdu_chaining = -1;
-
/*
* Don't refill the ring yet.
*
@@ -640,190 +636,6 @@
__be16 len;
} __packed;
-static const u8 rx_legacy_rate_idx[] = {
- 3, /* 0x00 - 11Mbps */
- 2, /* 0x01 - 5.5Mbps */
- 1, /* 0x02 - 2Mbps */
- 0, /* 0x03 - 1Mbps */
- 3, /* 0x04 - 11Mbps */
- 2, /* 0x05 - 5.5Mbps */
- 1, /* 0x06 - 2Mbps */
- 0, /* 0x07 - 1Mbps */
- 10, /* 0x08 - 48Mbps */
- 8, /* 0x09 - 24Mbps */
- 6, /* 0x0A - 12Mbps */
- 4, /* 0x0B - 6Mbps */
- 11, /* 0x0C - 54Mbps */
- 9, /* 0x0D - 36Mbps */
- 7, /* 0x0E - 18Mbps */
- 5, /* 0x0F - 9Mbps */
-};
-
-static void ath10k_htt_rx_h_rates(struct ath10k *ar,
- enum ieee80211_band band,
- u8 info0, u32 info1, u32 info2,
- struct ieee80211_rx_status *status)
-{
- u8 cck, rate, rate_idx, bw, sgi, mcs, nss;
- u8 preamble = 0;
-
- /* Check if valid fields */
- if (!(info0 & HTT_RX_INDICATION_INFO0_START_VALID))
- return;
-
- preamble = MS(info1, HTT_RX_INDICATION_INFO1_PREAMBLE_TYPE);
-
- switch (preamble) {
- case HTT_RX_LEGACY:
- cck = info0 & HTT_RX_INDICATION_INFO0_LEGACY_RATE_CCK;
- rate = MS(info0, HTT_RX_INDICATION_INFO0_LEGACY_RATE);
- rate_idx = 0;
-
- if (rate < 0x08 || rate > 0x0F)
- break;
-
- switch (band) {
- case IEEE80211_BAND_2GHZ:
- if (cck)
- rate &= ~BIT(3);
- rate_idx = rx_legacy_rate_idx[rate];
- break;
- case IEEE80211_BAND_5GHZ:
- rate_idx = rx_legacy_rate_idx[rate];
- /* We are using same rate table registering
- HW - ath10k_rates[]. In case of 5GHz skip
- CCK rates, so -4 here */
- rate_idx -= 4;
- break;
- default:
- break;
- }
-
- status->rate_idx = rate_idx;
- break;
- case HTT_RX_HT:
- case HTT_RX_HT_WITH_TXBF:
- /* HT-SIG - Table 20-11 in info1 and info2 */
- mcs = info1 & 0x1F;
- nss = mcs >> 3;
- bw = (info1 >> 7) & 1;
- sgi = (info2 >> 7) & 1;
-
- status->rate_idx = mcs;
- status->flag |= RX_FLAG_HT;
- if (sgi)
- status->flag |= RX_FLAG_SHORT_GI;
- if (bw)
- status->flag |= RX_FLAG_40MHZ;
- break;
- case HTT_RX_VHT:
- case HTT_RX_VHT_WITH_TXBF:
- /* VHT-SIG-A1 in info 1, VHT-SIG-A2 in info2
- TODO check this */
- mcs = (info2 >> 4) & 0x0F;
- nss = ((info1 >> 10) & 0x07) + 1;
- bw = info1 & 3;
- sgi = info2 & 1;
-
- status->rate_idx = mcs;
- status->vht_nss = nss;
-
- if (sgi)
- status->flag |= RX_FLAG_SHORT_GI;
-
- switch (bw) {
- /* 20MHZ */
- case 0:
- break;
- /* 40MHZ */
- case 1:
- status->flag |= RX_FLAG_40MHZ;
- break;
- /* 80MHZ */
- case 2:
- status->vht_flag |= RX_VHT_FLAG_80MHZ;
- }
-
- status->flag |= RX_FLAG_VHT;
- break;
- default:
- break;
- }
-}
-
-static void ath10k_htt_rx_h_protected(struct ath10k_htt *htt,
- struct ieee80211_rx_status *rx_status,
- struct sk_buff *skb,
- enum htt_rx_mpdu_encrypt_type enctype)
-{
- struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data;
-
-
- if (enctype == HTT_RX_MPDU_ENCRYPT_NONE) {
- rx_status->flag &= ~(RX_FLAG_DECRYPTED |
- RX_FLAG_IV_STRIPPED |
- RX_FLAG_MMIC_STRIPPED);
- return;
- }
-
- rx_status->flag |= RX_FLAG_DECRYPTED |
- RX_FLAG_IV_STRIPPED |
- RX_FLAG_MMIC_STRIPPED;
- hdr->frame_control = __cpu_to_le16(__le16_to_cpu(hdr->frame_control) &
- ~IEEE80211_FCTL_PROTECTED);
-}
-
-static bool ath10k_htt_rx_h_channel(struct ath10k *ar,
- struct ieee80211_rx_status *status)
-{
- struct ieee80211_channel *ch;
-
- spin_lock_bh(&ar->data_lock);
- ch = ar->scan_channel;
- if (!ch)
- ch = ar->rx_channel;
- spin_unlock_bh(&ar->data_lock);
-
- if (!ch)
- return false;
-
- status->band = ch->band;
- status->freq = ch->center_freq;
-
- return true;
-}
-
-static void ath10k_process_rx(struct ath10k *ar,
- struct ieee80211_rx_status *rx_status,
- struct sk_buff *skb)
-{
- struct ieee80211_rx_status *status;
-
- status = IEEE80211_SKB_RXCB(skb);
- *status = *rx_status;
-
- ath10k_dbg(ATH10K_DBG_DATA,
- "rx skb %p len %u %s%s%s%s%s %srate_idx %u vht_nss %u freq %u band %u flag 0x%x fcs-err %imic-err %i\n",
- skb,
- skb->len,
- status->flag == 0 ? "legacy" : "",
- status->flag & RX_FLAG_HT ? "ht" : "",
- status->flag & RX_FLAG_VHT ? "vht" : "",
- status->flag & RX_FLAG_40MHZ ? "40" : "",
- status->vht_flag & RX_VHT_FLAG_80MHZ ? "80" : "",
- status->flag & RX_FLAG_SHORT_GI ? "sgi " : "",
- status->rate_idx,
- status->vht_nss,
- status->freq,
- status->band, status->flag,
- !!(status->flag & RX_FLAG_FAILED_FCS_CRC),
- !!(status->flag & RX_FLAG_MMIC_ERROR));
- ath10k_dbg_dump(ATH10K_DBG_HTT_DUMP, NULL, "rx skb: ",
- skb->data, skb->len);
-
- ieee80211_rx(ar->hw, skb);
-}
-
static int ath10k_htt_rx_nwifi_hdrlen(struct ieee80211_hdr *hdr)
{
/* nwifi header is padded to 4 bytes. this fixes 4addr rx */
@@ -831,12 +643,11 @@
}
static void ath10k_htt_rx_amsdu(struct ath10k_htt *htt,
- struct ieee80211_rx_status *rx_status,
- struct sk_buff *skb_in)
+ struct htt_rx_info *info)
{
struct htt_rx_desc *rxd;
- struct sk_buff *skb = skb_in;
struct sk_buff *first;
+ struct sk_buff *skb = info->skb;
enum rx_msdu_decap_format fmt;
enum htt_rx_mpdu_encrypt_type enctype;
struct ieee80211_hdr *hdr;
@@ -917,27 +728,24 @@
break;
}
- skb_in = skb;
- ath10k_htt_rx_h_protected(htt, rx_status, skb_in, enctype);
+ info->skb = skb;
+ info->encrypt_type = enctype;
skb = skb->next;
- skb_in->next = NULL;
+ info->skb->next = NULL;
if (skb)
- rx_status->flag |= RX_FLAG_AMSDU_MORE;
- else
- rx_status->flag &= ~RX_FLAG_AMSDU_MORE;
+ info->amsdu_more = true;
- ath10k_process_rx(htt->ar, rx_status, skb_in);
+ ath10k_process_rx(htt->ar, info);
}
/* FIXME: It might be nice to re-assemble the A-MSDU when there's a
* monitor interface active for sniffing purposes. */
}
-static void ath10k_htt_rx_msdu(struct ath10k_htt *htt,
- struct ieee80211_rx_status *rx_status,
- struct sk_buff *skb)
+static void ath10k_htt_rx_msdu(struct ath10k_htt *htt, struct htt_rx_info *info)
{
+ struct sk_buff *skb = info->skb;
struct htt_rx_desc *rxd;
struct ieee80211_hdr *hdr;
enum rx_msdu_decap_format fmt;
@@ -1000,9 +808,66 @@
break;
}
- ath10k_htt_rx_h_protected(htt, rx_status, skb, enctype);
+ info->skb = skb;
+ info->encrypt_type = enctype;
- ath10k_process_rx(htt->ar, rx_status, skb);
+ ath10k_process_rx(htt->ar, info);
+}
+
+static bool ath10k_htt_rx_has_decrypt_err(struct sk_buff *skb)
+{
+ struct htt_rx_desc *rxd;
+ u32 flags;
+
+ rxd = (void *)skb->data - sizeof(*rxd);
+ flags = __le32_to_cpu(rxd->attention.flags);
+
+ if (flags & RX_ATTENTION_FLAGS_DECRYPT_ERR)
+ return true;
+
+ return false;
+}
+
+static bool ath10k_htt_rx_has_fcs_err(struct sk_buff *skb)
+{
+ struct htt_rx_desc *rxd;
+ u32 flags;
+
+ rxd = (void *)skb->data - sizeof(*rxd);
+ flags = __le32_to_cpu(rxd->attention.flags);
+
+ if (flags & RX_ATTENTION_FLAGS_FCS_ERR)
+ return true;
+
+ return false;
+}
+
+static bool ath10k_htt_rx_has_mic_err(struct sk_buff *skb)
+{
+ struct htt_rx_desc *rxd;
+ u32 flags;
+
+ rxd = (void *)skb->data - sizeof(*rxd);
+ flags = __le32_to_cpu(rxd->attention.flags);
+
+ if (flags & RX_ATTENTION_FLAGS_TKIP_MIC_ERR)
+ return true;
+
+ return false;
+}
+
+static bool ath10k_htt_rx_is_mgmt(struct sk_buff *skb)
+{
+ struct htt_rx_desc *rxd;
+ u32 flags;
+
+ rxd = (void *)skb->data - sizeof(*rxd);
+ flags = __le32_to_cpu(rxd->attention.flags);
+
+ if (flags & RX_ATTENTION_FLAGS_MGMT_TYPE)
+ return true;
+
+ return false;
}
static int ath10k_htt_rx_get_csum_state(struct sk_buff *skb)
@@ -1087,73 +952,21 @@
return 0;
}
-static bool ath10k_htt_rx_amsdu_allowed(struct ath10k_htt *htt,
- struct sk_buff *head,
- enum htt_rx_mpdu_status status,
- bool channel_set,
- u32 attention)
-{
- if (head->len == 0) {
- ath10k_dbg(ATH10K_DBG_HTT,
- "htt rx dropping due to zero-len\n");
- return false;
- }
-
- if (attention & RX_ATTENTION_FLAGS_DECRYPT_ERR) {
- ath10k_dbg(ATH10K_DBG_HTT,
- "htt rx dropping due to decrypt-err\n");
- return false;
- }
-
- if (!channel_set) {
- ath10k_warn("no channel configured; ignoring frame!\n");
- return false;
- }
-
- /* Skip mgmt frames while we handle this in WMI */
- if (status == HTT_RX_IND_MPDU_STATUS_MGMT_CTRL ||
- attention & RX_ATTENTION_FLAGS_MGMT_TYPE) {
- ath10k_dbg(ATH10K_DBG_HTT, "htt rx mgmt ctrl\n");
- return false;
- }
-
- if (status != HTT_RX_IND_MPDU_STATUS_OK &&
- status != HTT_RX_IND_MPDU_STATUS_TKIP_MIC_ERR &&
- status != HTT_RX_IND_MPDU_STATUS_ERR_INV_PEER &&
- !htt->ar->monitor_started) {
- ath10k_dbg(ATH10K_DBG_HTT,
- "htt rx ignoring frame w/ status %d\n",
- status);
- return false;
- }
-
- if (test_bit(ATH10K_CAC_RUNNING, &htt->ar->dev_flags)) {
- ath10k_dbg(ATH10K_DBG_HTT,
- "htt rx CAC running\n");
- return false;
- }
-
- return true;
-}
-
static void ath10k_htt_rx_handler(struct ath10k_htt *htt,
struct htt_rx_indication *rx)
{
- struct ieee80211_rx_status *rx_status = &htt->rx_status;
+ struct htt_rx_info info;
struct htt_rx_indication_mpdu_range *mpdu_ranges;
- struct htt_rx_desc *rxd;
- enum htt_rx_mpdu_status status;
struct ieee80211_hdr *hdr;
int num_mpdu_ranges;
- u32 attention;
int fw_desc_len;
u8 *fw_desc;
- bool channel_set;
int i, j;
- int ret;
lockdep_assert_held(&htt->rx_ring.lock);
+ memset(&info, 0, sizeof(info));
+
fw_desc_len = __le16_to_cpu(rx->prefix.fw_rx_desc_bytes);
fw_desc = (u8 *)&rx->fw_desc;
@@ -1161,90 +974,106 @@
HTT_RX_INDICATION_INFO1_NUM_MPDU_RANGES);
mpdu_ranges = htt_rx_ind_get_mpdu_ranges(rx);
- /* Fill this once, while this is per-ppdu */
- if (rx->ppdu.info0 & HTT_RX_INDICATION_INFO0_START_VALID) {
- memset(rx_status, 0, sizeof(*rx_status));
- rx_status->signal = ATH10K_DEFAULT_NOISE_FLOOR +
- rx->ppdu.combined_rssi;
- }
-
- if (rx->ppdu.info0 & HTT_RX_INDICATION_INFO0_END_VALID) {
- /* TSF available only in 32-bit */
- rx_status->mactime = __le32_to_cpu(rx->ppdu.tsf) & 0xffffffff;
- rx_status->flag |= RX_FLAG_MACTIME_END;
- }
-
- channel_set = ath10k_htt_rx_h_channel(htt->ar, rx_status);
-
- if (channel_set) {
- ath10k_htt_rx_h_rates(htt->ar, rx_status->band,
- rx->ppdu.info0,
- __le32_to_cpu(rx->ppdu.info1),
- __le32_to_cpu(rx->ppdu.info2),
- rx_status);
- }
-
ath10k_dbg_dump(ATH10K_DBG_HTT_DUMP, NULL, "htt rx ind: ",
rx, sizeof(*rx) +
(sizeof(struct htt_rx_indication_mpdu_range) *
num_mpdu_ranges));
for (i = 0; i < num_mpdu_ranges; i++) {
- status = mpdu_ranges[i].mpdu_range_status;
+ info.status = mpdu_ranges[i].mpdu_range_status;
for (j = 0; j < mpdu_ranges[i].mpdu_count; j++) {
struct sk_buff *msdu_head, *msdu_tail;
+ enum htt_rx_mpdu_status status;
+ int msdu_chaining;
msdu_head = NULL;
msdu_tail = NULL;
- ret = ath10k_htt_rx_amsdu_pop(htt,
- &fw_desc,
- &fw_desc_len,
- &msdu_head,
- &msdu_tail);
+ msdu_chaining = ath10k_htt_rx_amsdu_pop(htt,
+ &fw_desc,
+ &fw_desc_len,
+ &msdu_head,
+ &msdu_tail);
- if (ret < 0) {
- ath10k_warn("failed to pop amsdu from htt rx ring %d\n",
- ret);
+ if (!msdu_head) {
+ ath10k_warn("htt rx no data!\n");
+ continue;
+ }
+
+ if (msdu_head->len == 0) {
+ ath10k_dbg(ATH10K_DBG_HTT,
+ "htt rx dropping due to zero-len\n");
ath10k_htt_rx_free_msdu_chain(msdu_head);
continue;
}
- rxd = container_of((void *)msdu_head->data,
- struct htt_rx_desc,
- msdu_payload);
- attention = __le32_to_cpu(rxd->attention.flags);
-
- if (!ath10k_htt_rx_amsdu_allowed(htt, msdu_head,
- status,
- channel_set,
- attention)) {
+ if (ath10k_htt_rx_has_decrypt_err(msdu_head)) {
+ ath10k_dbg(ATH10K_DBG_HTT,
+ "htt rx dropping due to decrypt-err\n");
ath10k_htt_rx_free_msdu_chain(msdu_head);
continue;
}
- if (ret > 0 &&
- ath10k_unchain_msdu(msdu_head) < 0) {
+ status = info.status;
+
+ /* Skip mgmt frames while we handle this in WMI */
+ if (status == HTT_RX_IND_MPDU_STATUS_MGMT_CTRL ||
+ ath10k_htt_rx_is_mgmt(msdu_head)) {
+ ath10k_dbg(ATH10K_DBG_HTT, "htt rx mgmt ctrl\n");
ath10k_htt_rx_free_msdu_chain(msdu_head);
continue;
}
- if (attention & RX_ATTENTION_FLAGS_FCS_ERR)
- rx_status->flag |= RX_FLAG_FAILED_FCS_CRC;
- else
- rx_status->flag &= ~RX_FLAG_FAILED_FCS_CRC;
+ if (status != HTT_RX_IND_MPDU_STATUS_OK &&
+ status != HTT_RX_IND_MPDU_STATUS_TKIP_MIC_ERR &&
+ status != HTT_RX_IND_MPDU_STATUS_ERR_INV_PEER &&
+ !htt->ar->monitor_enabled) {
+ ath10k_dbg(ATH10K_DBG_HTT,
+ "htt rx ignoring frame w/ status %d\n",
+ status);
+ ath10k_htt_rx_free_msdu_chain(msdu_head);
+ continue;
+ }
- if (attention & RX_ATTENTION_FLAGS_TKIP_MIC_ERR)
- rx_status->flag |= RX_FLAG_MMIC_ERROR;
- else
- rx_status->flag &= ~RX_FLAG_MMIC_ERROR;
+ if (test_bit(ATH10K_CAC_RUNNING, &htt->ar->dev_flags)) {
+ ath10k_dbg(ATH10K_DBG_HTT,
+ "htt rx CAC running\n");
+ ath10k_htt_rx_free_msdu_chain(msdu_head);
+ continue;
+ }
+
+ if (msdu_chaining &&
+ (ath10k_unchain_msdu(msdu_head) < 0)) {
+ ath10k_htt_rx_free_msdu_chain(msdu_head);
+ continue;
+ }
+
+ info.skb = msdu_head;
+ info.fcs_err = ath10k_htt_rx_has_fcs_err(msdu_head);
+ info.mic_err = ath10k_htt_rx_has_mic_err(msdu_head);
+
+ if (info.fcs_err)
+ ath10k_dbg(ATH10K_DBG_HTT,
+ "htt rx has FCS err\n");
+
+ if (info.mic_err)
+ ath10k_dbg(ATH10K_DBG_HTT,
+ "htt rx has MIC err\n");
+
+ info.signal = ATH10K_DEFAULT_NOISE_FLOOR;
+ info.signal += rx->ppdu.combined_rssi;
+
+ info.rate.info0 = rx->ppdu.info0;
+ info.rate.info1 = __le32_to_cpu(rx->ppdu.info1);
+ info.rate.info2 = __le32_to_cpu(rx->ppdu.info2);
+ info.tsf = __le32_to_cpu(rx->ppdu.tsf);
hdr = ath10k_htt_rx_skb_get_hdr(msdu_head);
if (ath10k_htt_rx_hdr_is_amsdu(hdr))
- ath10k_htt_rx_amsdu(htt, rx_status, msdu_head);
+ ath10k_htt_rx_amsdu(htt, &info);
else
- ath10k_htt_rx_msdu(htt, rx_status, msdu_head);
+ ath10k_htt_rx_msdu(htt, &info);
}
}
@@ -1255,12 +1084,11 @@
struct htt_rx_fragment_indication *frag)
{
struct sk_buff *msdu_head, *msdu_tail;
- enum htt_rx_mpdu_encrypt_type enctype;
struct htt_rx_desc *rxd;
enum rx_msdu_decap_format fmt;
- struct ieee80211_rx_status *rx_status = &htt->rx_status;
+ struct htt_rx_info info = {};
struct ieee80211_hdr *hdr;
- int ret;
+ int msdu_chaining;
bool tkip_mic_err;
bool decrypt_err;
u8 *fw_desc;
@@ -1274,15 +1102,19 @@
msdu_tail = NULL;
spin_lock_bh(&htt->rx_ring.lock);
- ret = ath10k_htt_rx_amsdu_pop(htt, &fw_desc, &fw_desc_len,
- &msdu_head, &msdu_tail);
+ msdu_chaining = ath10k_htt_rx_amsdu_pop(htt, &fw_desc, &fw_desc_len,
+ &msdu_head, &msdu_tail);
spin_unlock_bh(&htt->rx_ring.lock);
ath10k_dbg(ATH10K_DBG_HTT_DUMP, "htt rx frag ahead\n");
- if (ret) {
- ath10k_warn("failed to pop amsdu from httr rx ring for fragmented rx %d\n",
- ret);
+ if (!msdu_head) {
+ ath10k_warn("htt rx frag no data\n");
+ return;
+ }
+
+ if (msdu_chaining || msdu_head != msdu_tail) {
+ ath10k_warn("aggregation with fragmentation?!\n");
ath10k_htt_rx_free_msdu_chain(msdu_head);
return;
}
@@ -1304,54 +1136,57 @@
goto end;
}
- enctype = MS(__le32_to_cpu(rxd->mpdu_start.info0),
- RX_MPDU_START_INFO0_ENCRYPT_TYPE);
- ath10k_htt_rx_h_protected(htt, rx_status, msdu_head, enctype);
- msdu_head->ip_summed = ath10k_htt_rx_get_csum_state(msdu_head);
+ info.skb = msdu_head;
+ info.status = HTT_RX_IND_MPDU_STATUS_OK;
+ info.encrypt_type = MS(__le32_to_cpu(rxd->mpdu_start.info0),
+ RX_MPDU_START_INFO0_ENCRYPT_TYPE);
+ info.skb->ip_summed = ath10k_htt_rx_get_csum_state(info.skb);
- if (tkip_mic_err)
+ if (tkip_mic_err) {
ath10k_warn("tkip mic error\n");
+ info.status = HTT_RX_IND_MPDU_STATUS_TKIP_MIC_ERR;
+ }
if (decrypt_err) {
ath10k_warn("decryption err in fragmented rx\n");
- dev_kfree_skb_any(msdu_head);
+ dev_kfree_skb_any(info.skb);
goto end;
}
- if (enctype != HTT_RX_MPDU_ENCRYPT_NONE) {
+ if (info.encrypt_type != HTT_RX_MPDU_ENCRYPT_NONE) {
hdrlen = ieee80211_hdrlen(hdr->frame_control);
- paramlen = ath10k_htt_rx_crypto_param_len(enctype);
+ paramlen = ath10k_htt_rx_crypto_param_len(info.encrypt_type);
/* It is more efficient to move the header than the payload */
- memmove((void *)msdu_head->data + paramlen,
- (void *)msdu_head->data,
+ memmove((void *)info.skb->data + paramlen,
+ (void *)info.skb->data,
hdrlen);
- skb_pull(msdu_head, paramlen);
- hdr = (struct ieee80211_hdr *)msdu_head->data;
+ skb_pull(info.skb, paramlen);
+ hdr = (struct ieee80211_hdr *)info.skb->data;
}
/* remove trailing FCS */
trim = 4;
/* remove crypto trailer */
- trim += ath10k_htt_rx_crypto_tail_len(enctype);
+ trim += ath10k_htt_rx_crypto_tail_len(info.encrypt_type);
/* last fragment of TKIP frags has MIC */
if (!ieee80211_has_morefrags(hdr->frame_control) &&
- enctype == HTT_RX_MPDU_ENCRYPT_TKIP_WPA)
+ info.encrypt_type == HTT_RX_MPDU_ENCRYPT_TKIP_WPA)
trim += 8;
- if (trim > msdu_head->len) {
+ if (trim > info.skb->len) {
ath10k_warn("htt rx fragment: trailer longer than the frame itself? drop\n");
- dev_kfree_skb_any(msdu_head);
+ dev_kfree_skb_any(info.skb);
goto end;
}
- skb_trim(msdu_head, msdu_head->len - trim);
+ skb_trim(info.skb, info.skb->len - trim);
ath10k_dbg_dump(ATH10K_DBG_HTT_DUMP, NULL, "htt rx frag mpdu: ",
- msdu_head->data, msdu_head->len);
- ath10k_process_rx(htt->ar, rx_status, msdu_head);
+ info.skb->data, info.skb->len);
+ ath10k_process_rx(htt->ar, &info);
end:
if (fw_desc_len > 0) {
diff --git a/drivers/net/wireless/ath/ath10k/hw.h b/drivers/net/wireless/ath/ath10k/hw.h
index 007e855..35fc44e 100644
--- a/drivers/net/wireless/ath/ath10k/hw.h
+++ b/drivers/net/wireless/ath/ath10k/hw.h
@@ -28,7 +28,6 @@
#define QCA988X_HW_2_0_CHIP_ID_REV 0x2
#define QCA988X_HW_2_0_FW_DIR "ath10k/QCA988X/hw2.0"
#define QCA988X_HW_2_0_FW_FILE "firmware.bin"
-#define QCA988X_HW_2_0_FW_2_FILE "firmware-2.bin"
#define QCA988X_HW_2_0_OTP_FILE "otp.bin"
#define QCA988X_HW_2_0_BOARD_DATA_FILE "board.bin"
#define QCA988X_HW_2_0_PATCH_LOAD_ADDR 0x1234
diff --git a/drivers/net/wireless/ath/ath10k/mac.c b/drivers/net/wireless/ath/ath10k/mac.c
index 5307dee..348a639 100644
--- a/drivers/net/wireless/ath/ath10k/mac.c
+++ b/drivers/net/wireless/ath/ath10k/mac.c
@@ -165,7 +165,7 @@
first_errno = ret;
if (ret)
- ath10k_warn("failed to remove peer wep key %d: %d\n",
+ ath10k_warn("could not remove peer wep key %d (%d)\n",
i, ret);
peer->keys[i] = NULL;
@@ -213,8 +213,7 @@
first_errno = ret;
if (ret)
- ath10k_warn("failed to remove key for %pM: %d\n",
- addr, ret);
+ ath10k_warn("could not remove key for %pM\n", addr);
}
return first_errno;
@@ -324,14 +323,14 @@
ret = ath10k_wmi_peer_create(ar, vdev_id, addr);
if (ret) {
- ath10k_warn("failed to create wmi peer %pM on vdev %i: %i\n",
+ ath10k_warn("Failed to create wmi peer %pM on vdev %i: %i\n",
addr, vdev_id, ret);
return ret;
}
ret = ath10k_wait_for_peer_created(ar, vdev_id, addr);
if (ret) {
- ath10k_warn("failed to wait for created wmi peer %pM on vdev %i: %i\n",
+ ath10k_warn("Failed to wait for created wmi peer %pM on vdev %i: %i\n",
addr, vdev_id, ret);
return ret;
}
@@ -352,7 +351,7 @@
ret = ath10k_wmi_pdev_set_param(ar, param,
ATH10K_KICKOUT_THRESHOLD);
if (ret) {
- ath10k_warn("failed to set kickout threshold on vdev %i: %d\n",
+ ath10k_warn("Failed to set kickout threshold on vdev %i: %d\n",
arvif->vdev_id, ret);
return ret;
}
@@ -361,7 +360,7 @@
ret = ath10k_wmi_vdev_set_param(ar, arvif->vdev_id, param,
ATH10K_KEEPALIVE_MIN_IDLE);
if (ret) {
- ath10k_warn("failed to set keepalive minimum idle time on vdev %i: %d\n",
+ ath10k_warn("Failed to set keepalive minimum idle time on vdev %i : %d\n",
arvif->vdev_id, ret);
return ret;
}
@@ -370,7 +369,7 @@
ret = ath10k_wmi_vdev_set_param(ar, arvif->vdev_id, param,
ATH10K_KEEPALIVE_MAX_IDLE);
if (ret) {
- ath10k_warn("failed to set keepalive maximum idle time on vdev %i: %d\n",
+ ath10k_warn("Failed to set keepalive maximum idle time on vdev %i: %d\n",
arvif->vdev_id, ret);
return ret;
}
@@ -379,7 +378,7 @@
ret = ath10k_wmi_vdev_set_param(ar, arvif->vdev_id, param,
ATH10K_KEEPALIVE_MAX_UNRESPONSIVE);
if (ret) {
- ath10k_warn("failed to set keepalive maximum unresponsive time on vdev %i: %d\n",
+ ath10k_warn("Failed to set keepalive maximum unresponsive time on vdev %i: %d\n",
arvif->vdev_id, ret);
return ret;
}
@@ -489,310 +488,6 @@
return 0;
}
-static bool ath10k_monitor_is_enabled(struct ath10k *ar)
-{
- lockdep_assert_held(&ar->conf_mutex);
-
- ath10k_dbg(ATH10K_DBG_MAC,
- "mac monitor refs: promisc %d monitor %d cac %d\n",
- ar->promisc, ar->monitor,
- test_bit(ATH10K_CAC_RUNNING, &ar->dev_flags));
-
- return ar->promisc || ar->monitor ||
- test_bit(ATH10K_CAC_RUNNING, &ar->dev_flags);
-}
-
-static int ath10k_monitor_vdev_start(struct ath10k *ar, int vdev_id)
-{
- struct cfg80211_chan_def *chandef = &ar->chandef;
- struct ieee80211_channel *channel = chandef->chan;
- struct wmi_vdev_start_request_arg arg = {};
- int ret = 0;
-
- lockdep_assert_held(&ar->conf_mutex);
-
- arg.vdev_id = vdev_id;
- arg.channel.freq = channel->center_freq;
- arg.channel.band_center_freq1 = chandef->center_freq1;
-
- /* TODO setup this dynamically, what in case we
- don't have any vifs? */
- arg.channel.mode = chan_to_phymode(chandef);
- arg.channel.chan_radar =
- !!(channel->flags & IEEE80211_CHAN_RADAR);
-
- arg.channel.min_power = 0;
- arg.channel.max_power = channel->max_power * 2;
- arg.channel.max_reg_power = channel->max_reg_power * 2;
- arg.channel.max_antenna_gain = channel->max_antenna_gain * 2;
-
- ret = ath10k_wmi_vdev_start(ar, &arg);
- if (ret) {
- ath10k_warn("failed to request monitor vdev %i start: %d\n",
- vdev_id, ret);
- return ret;
- }
-
- ret = ath10k_vdev_setup_sync(ar);
- if (ret) {
- ath10k_warn("failed to synchronize setup for monitor vdev %i: %d\n",
- vdev_id, ret);
- return ret;
- }
-
- ret = ath10k_wmi_vdev_up(ar, vdev_id, 0, ar->mac_addr);
- if (ret) {
- ath10k_warn("failed to put up monitor vdev %i: %d\n",
- vdev_id, ret);
- goto vdev_stop;
- }
-
- ar->monitor_vdev_id = vdev_id;
-
- ath10k_dbg(ATH10K_DBG_MAC, "mac monitor vdev %i started\n",
- ar->monitor_vdev_id);
- return 0;
-
-vdev_stop:
- ret = ath10k_wmi_vdev_stop(ar, ar->monitor_vdev_id);
- if (ret)
- ath10k_warn("failed to stop monitor vdev %i after start failure: %d\n",
- ar->monitor_vdev_id, ret);
-
- return ret;
-}
-
-static int ath10k_monitor_vdev_stop(struct ath10k *ar)
-{
- int ret = 0;
-
- lockdep_assert_held(&ar->conf_mutex);
-
- ret = ath10k_wmi_vdev_down(ar, ar->monitor_vdev_id);
- if (ret)
- ath10k_warn("failed to put down monitor vdev %i: %d\n",
- ar->monitor_vdev_id, ret);
-
- ret = ath10k_wmi_vdev_stop(ar, ar->monitor_vdev_id);
- if (ret)
- ath10k_warn("failed to to request monitor vdev %i stop: %d\n",
- ar->monitor_vdev_id, ret);
-
- ret = ath10k_vdev_setup_sync(ar);
- if (ret)
- ath10k_warn("failed to synchronise monitor vdev %i: %d\n",
- ar->monitor_vdev_id, ret);
-
- ath10k_dbg(ATH10K_DBG_MAC, "mac monitor vdev %i stopped\n",
- ar->monitor_vdev_id);
- return ret;
-}
-
-static int ath10k_monitor_vdev_create(struct ath10k *ar)
-{
- int bit, ret = 0;
-
- lockdep_assert_held(&ar->conf_mutex);
-
- bit = ffs(ar->free_vdev_map);
- if (bit == 0) {
- ath10k_warn("failed to find free vdev id for monitor vdev\n");
- return -ENOMEM;
- }
-
- ar->monitor_vdev_id = bit - 1;
- ar->free_vdev_map &= ~(1 << ar->monitor_vdev_id);
-
- ret = ath10k_wmi_vdev_create(ar, ar->monitor_vdev_id,
- WMI_VDEV_TYPE_MONITOR,
- 0, ar->mac_addr);
- if (ret) {
- ath10k_warn("failed to request monitor vdev %i creation: %d\n",
- ar->monitor_vdev_id, ret);
- goto vdev_fail;
- }
-
- ath10k_dbg(ATH10K_DBG_MAC, "mac monitor vdev %d created\n",
- ar->monitor_vdev_id);
-
- return 0;
-
-vdev_fail:
- /*
- * Restore the ID to the global map.
- */
- ar->free_vdev_map |= 1 << (ar->monitor_vdev_id);
- return ret;
-}
-
-static int ath10k_monitor_vdev_delete(struct ath10k *ar)
-{
- int ret = 0;
-
- lockdep_assert_held(&ar->conf_mutex);
-
- ret = ath10k_wmi_vdev_delete(ar, ar->monitor_vdev_id);
- if (ret) {
- ath10k_warn("failed to request wmi monitor vdev %i removal: %d\n",
- ar->monitor_vdev_id, ret);
- return ret;
- }
-
- ar->free_vdev_map |= 1 << (ar->monitor_vdev_id);
-
- ath10k_dbg(ATH10K_DBG_MAC, "mac monitor vdev %d deleted\n",
- ar->monitor_vdev_id);
- return ret;
-}
-
-static int ath10k_monitor_start(struct ath10k *ar)
-{
- int ret;
-
- lockdep_assert_held(&ar->conf_mutex);
-
- if (!ath10k_monitor_is_enabled(ar)) {
- ath10k_warn("trying to start monitor with no references\n");
- return 0;
- }
-
- if (ar->monitor_started) {
- ath10k_dbg(ATH10K_DBG_MAC, "mac monitor already started\n");
- return 0;
- }
-
- ret = ath10k_monitor_vdev_create(ar);
- if (ret) {
- ath10k_warn("failed to create monitor vdev: %d\n", ret);
- return ret;
- }
-
- ret = ath10k_monitor_vdev_start(ar, ar->monitor_vdev_id);
- if (ret) {
- ath10k_warn("failed to start monitor vdev: %d\n", ret);
- ath10k_monitor_vdev_delete(ar);
- return ret;
- }
-
- ar->monitor_started = true;
- ath10k_dbg(ATH10K_DBG_MAC, "mac monitor started\n");
-
- return 0;
-}
-
-static void ath10k_monitor_stop(struct ath10k *ar)
-{
- int ret;
-
- lockdep_assert_held(&ar->conf_mutex);
-
- if (ath10k_monitor_is_enabled(ar)) {
- ath10k_dbg(ATH10K_DBG_MAC,
- "mac monitor will be stopped later\n");
- return;
- }
-
- if (!ar->monitor_started) {
- ath10k_dbg(ATH10K_DBG_MAC,
- "mac monitor probably failed to start earlier\n");
- return;
- }
-
- ret = ath10k_monitor_vdev_stop(ar);
- if (ret)
- ath10k_warn("failed to stop monitor vdev: %d\n", ret);
-
- ret = ath10k_monitor_vdev_delete(ar);
- if (ret)
- ath10k_warn("failed to delete monitor vdev: %d\n", ret);
-
- ar->monitor_started = false;
- ath10k_dbg(ATH10K_DBG_MAC, "mac monitor stopped\n");
-}
-
-static int ath10k_recalc_rtscts_prot(struct ath10k_vif *arvif)
-{
- struct ath10k *ar = arvif->ar;
- u32 vdev_param, rts_cts = 0;
-
- lockdep_assert_held(&ar->conf_mutex);
-
- vdev_param = ar->wmi.vdev_param->enable_rtscts;
-
- if (arvif->use_cts_prot || arvif->num_legacy_stations > 0)
- rts_cts |= SM(WMI_RTSCTS_ENABLED, WMI_RTSCTS_SET);
-
- if (arvif->num_legacy_stations > 0)
- rts_cts |= SM(WMI_RTSCTS_ACROSS_SW_RETRIES,
- WMI_RTSCTS_PROFILE);
-
- return ath10k_wmi_vdev_set_param(ar, arvif->vdev_id, vdev_param,
- rts_cts);
-}
-
-static int ath10k_start_cac(struct ath10k *ar)
-{
- int ret;
-
- lockdep_assert_held(&ar->conf_mutex);
-
- set_bit(ATH10K_CAC_RUNNING, &ar->dev_flags);
-
- ret = ath10k_monitor_start(ar);
- if (ret) {
- ath10k_warn("failed to start monitor (cac): %d\n", ret);
- clear_bit(ATH10K_CAC_RUNNING, &ar->dev_flags);
- return ret;
- }
-
- ath10k_dbg(ATH10K_DBG_MAC, "mac cac start monitor vdev %d\n",
- ar->monitor_vdev_id);
-
- return 0;
-}
-
-static int ath10k_stop_cac(struct ath10k *ar)
-{
- lockdep_assert_held(&ar->conf_mutex);
-
- /* CAC is not running - do nothing */
- if (!test_bit(ATH10K_CAC_RUNNING, &ar->dev_flags))
- return 0;
-
- clear_bit(ATH10K_CAC_RUNNING, &ar->dev_flags);
- ath10k_monitor_stop(ar);
-
- ath10k_dbg(ATH10K_DBG_MAC, "mac cac finished\n");
-
- return 0;
-}
-
-static void ath10k_recalc_radar_detection(struct ath10k *ar)
-{
- int ret;
-
- lockdep_assert_held(&ar->conf_mutex);
-
- ath10k_stop_cac(ar);
-
- if (!ar->radar_enabled)
- return;
-
- if (ar->num_started_vdevs > 0)
- return;
-
- ret = ath10k_start_cac(ar);
- if (ret) {
- /*
- * Not possible to start CAC on current channel so starting
- * radiation is not allowed, make this channel DFS_UNAVAILABLE
- * by indicating that radar was detected.
- */
- ath10k_warn("failed to start CAC: %d\n", ret);
- ieee80211_radar_detected(ar->hw);
- }
-}
-
static int ath10k_vdev_start(struct ath10k_vif *arvif)
{
struct ath10k *ar = arvif->ar;
@@ -837,21 +532,18 @@
ret = ath10k_wmi_vdev_start(ar, &arg);
if (ret) {
- ath10k_warn("failed to start WMI vdev %i: %d\n",
+ ath10k_warn("WMI vdev %i start failed: ret %d\n",
arg.vdev_id, ret);
return ret;
}
ret = ath10k_vdev_setup_sync(ar);
if (ret) {
- ath10k_warn("failed to synchronise setup for vdev %i: %d\n",
+ ath10k_warn("vdev %i setup failed %d\n",
arg.vdev_id, ret);
return ret;
}
- ar->num_started_vdevs++;
- ath10k_recalc_radar_detection(ar);
-
return ret;
}
@@ -866,28 +558,288 @@
ret = ath10k_wmi_vdev_stop(ar, arvif->vdev_id);
if (ret) {
- ath10k_warn("failed to stop WMI vdev %i: %d\n",
+ ath10k_warn("WMI vdev %i stop failed: ret %d\n",
arvif->vdev_id, ret);
return ret;
}
ret = ath10k_vdev_setup_sync(ar);
if (ret) {
- ath10k_warn("failed to syncronise setup for vdev %i: %d\n",
+ ath10k_warn("vdev %i setup sync failed %d\n",
arvif->vdev_id, ret);
return ret;
}
- WARN_ON(ar->num_started_vdevs == 0);
+ return ret;
+}
- if (ar->num_started_vdevs != 0) {
- ar->num_started_vdevs--;
- ath10k_recalc_radar_detection(ar);
+static int ath10k_monitor_start(struct ath10k *ar, int vdev_id)
+{
+ struct cfg80211_chan_def *chandef = &ar->chandef;
+ struct ieee80211_channel *channel = chandef->chan;
+ struct wmi_vdev_start_request_arg arg = {};
+ int ret = 0;
+
+ lockdep_assert_held(&ar->conf_mutex);
+
+ if (!ar->monitor_present) {
+ ath10k_warn("mac montor stop -- monitor is not present\n");
+ return -EINVAL;
}
+ arg.vdev_id = vdev_id;
+ arg.channel.freq = channel->center_freq;
+ arg.channel.band_center_freq1 = chandef->center_freq1;
+
+ /* TODO setup this dynamically, what in case we
+ don't have any vifs? */
+ arg.channel.mode = chan_to_phymode(chandef);
+ arg.channel.chan_radar =
+ !!(channel->flags & IEEE80211_CHAN_RADAR);
+
+ arg.channel.min_power = 0;
+ arg.channel.max_power = channel->max_power * 2;
+ arg.channel.max_reg_power = channel->max_reg_power * 2;
+ arg.channel.max_antenna_gain = channel->max_antenna_gain * 2;
+
+ ret = ath10k_wmi_vdev_start(ar, &arg);
+ if (ret) {
+ ath10k_warn("Monitor vdev %i start failed: ret %d\n",
+ vdev_id, ret);
+ return ret;
+ }
+
+ ret = ath10k_vdev_setup_sync(ar);
+ if (ret) {
+ ath10k_warn("Monitor vdev %i setup failed %d\n",
+ vdev_id, ret);
+ return ret;
+ }
+
+ ret = ath10k_wmi_vdev_up(ar, vdev_id, 0, ar->mac_addr);
+ if (ret) {
+ ath10k_warn("Monitor vdev %i up failed: %d\n",
+ vdev_id, ret);
+ goto vdev_stop;
+ }
+
+ ar->monitor_vdev_id = vdev_id;
+ ar->monitor_enabled = true;
+
+ return 0;
+
+vdev_stop:
+ ret = ath10k_wmi_vdev_stop(ar, ar->monitor_vdev_id);
+ if (ret)
+ ath10k_warn("Monitor vdev %i stop failed: %d\n",
+ ar->monitor_vdev_id, ret);
+
return ret;
}
+static int ath10k_monitor_stop(struct ath10k *ar)
+{
+ int ret = 0;
+
+ lockdep_assert_held(&ar->conf_mutex);
+
+ if (!ar->monitor_present) {
+ ath10k_warn("mac montor stop -- monitor is not present\n");
+ return -EINVAL;
+ }
+
+ if (!ar->monitor_enabled) {
+ ath10k_warn("mac montor stop -- monitor is not enabled\n");
+ return -EINVAL;
+ }
+
+ ret = ath10k_wmi_vdev_down(ar, ar->monitor_vdev_id);
+ if (ret)
+ ath10k_warn("Monitor vdev %i down failed: %d\n",
+ ar->monitor_vdev_id, ret);
+
+ ret = ath10k_wmi_vdev_stop(ar, ar->monitor_vdev_id);
+ if (ret)
+ ath10k_warn("Monitor vdev %i stop failed: %d\n",
+ ar->monitor_vdev_id, ret);
+
+ ret = ath10k_vdev_setup_sync(ar);
+ if (ret)
+ ath10k_warn("Monitor_down sync failed, vdev %i: %d\n",
+ ar->monitor_vdev_id, ret);
+
+ ar->monitor_enabled = false;
+ return ret;
+}
+
+static int ath10k_monitor_create(struct ath10k *ar)
+{
+ int bit, ret = 0;
+
+ lockdep_assert_held(&ar->conf_mutex);
+
+ if (ar->monitor_present) {
+ ath10k_warn("Monitor mode already enabled\n");
+ return 0;
+ }
+
+ bit = ffs(ar->free_vdev_map);
+ if (bit == 0) {
+ ath10k_warn("No free VDEV slots\n");
+ return -ENOMEM;
+ }
+
+ ar->monitor_vdev_id = bit - 1;
+ ar->free_vdev_map &= ~(1 << ar->monitor_vdev_id);
+
+ ret = ath10k_wmi_vdev_create(ar, ar->monitor_vdev_id,
+ WMI_VDEV_TYPE_MONITOR,
+ 0, ar->mac_addr);
+ if (ret) {
+ ath10k_warn("WMI vdev %i monitor create failed: ret %d\n",
+ ar->monitor_vdev_id, ret);
+ goto vdev_fail;
+ }
+
+ ath10k_dbg(ATH10K_DBG_MAC, "mac monitor vdev %d created\n",
+ ar->monitor_vdev_id);
+
+ ar->monitor_present = true;
+ return 0;
+
+vdev_fail:
+ /*
+ * Restore the ID to the global map.
+ */
+ ar->free_vdev_map |= 1 << (ar->monitor_vdev_id);
+ return ret;
+}
+
+static int ath10k_monitor_destroy(struct ath10k *ar)
+{
+ int ret = 0;
+
+ lockdep_assert_held(&ar->conf_mutex);
+
+ if (!ar->monitor_present)
+ return 0;
+
+ ret = ath10k_wmi_vdev_delete(ar, ar->monitor_vdev_id);
+ if (ret) {
+ ath10k_warn("WMI vdev %i monitor delete failed: %d\n",
+ ar->monitor_vdev_id, ret);
+ return ret;
+ }
+
+ ar->free_vdev_map |= 1 << (ar->monitor_vdev_id);
+ ar->monitor_present = false;
+
+ ath10k_dbg(ATH10K_DBG_MAC, "mac monitor vdev %d deleted\n",
+ ar->monitor_vdev_id);
+ return ret;
+}
+
+static int ath10k_start_cac(struct ath10k *ar)
+{
+ int ret;
+
+ lockdep_assert_held(&ar->conf_mutex);
+
+ set_bit(ATH10K_CAC_RUNNING, &ar->dev_flags);
+
+ ret = ath10k_monitor_create(ar);
+ if (ret) {
+ clear_bit(ATH10K_CAC_RUNNING, &ar->dev_flags);
+ return ret;
+ }
+
+ ret = ath10k_monitor_start(ar, ar->monitor_vdev_id);
+ if (ret) {
+ clear_bit(ATH10K_CAC_RUNNING, &ar->dev_flags);
+ ath10k_monitor_destroy(ar);
+ return ret;
+ }
+
+ ath10k_dbg(ATH10K_DBG_MAC, "mac cac start monitor vdev %d\n",
+ ar->monitor_vdev_id);
+
+ return 0;
+}
+
+static int ath10k_stop_cac(struct ath10k *ar)
+{
+ lockdep_assert_held(&ar->conf_mutex);
+
+ /* CAC is not running - do nothing */
+ if (!test_bit(ATH10K_CAC_RUNNING, &ar->dev_flags))
+ return 0;
+
+ ath10k_monitor_stop(ar);
+ ath10k_monitor_destroy(ar);
+ clear_bit(ATH10K_CAC_RUNNING, &ar->dev_flags);
+
+ ath10k_dbg(ATH10K_DBG_MAC, "mac cac finished\n");
+
+ return 0;
+}
+
+static const char *ath10k_dfs_state(enum nl80211_dfs_state dfs_state)
+{
+ switch (dfs_state) {
+ case NL80211_DFS_USABLE:
+ return "USABLE";
+ case NL80211_DFS_UNAVAILABLE:
+ return "UNAVAILABLE";
+ case NL80211_DFS_AVAILABLE:
+ return "AVAILABLE";
+ default:
+ WARN_ON(1);
+ return "bug";
+ }
+}
+
+static void ath10k_config_radar_detection(struct ath10k *ar)
+{
+ struct ieee80211_channel *chan = ar->hw->conf.chandef.chan;
+ bool radar = ar->hw->conf.radar_enabled;
+ bool chan_radar = !!(chan->flags & IEEE80211_CHAN_RADAR);
+ enum nl80211_dfs_state dfs_state = chan->dfs_state;
+ int ret;
+
+ lockdep_assert_held(&ar->conf_mutex);
+
+ ath10k_dbg(ATH10K_DBG_MAC,
+ "mac radar config update: chan %dMHz radar %d chan radar %d chan state %s\n",
+ chan->center_freq, radar, chan_radar,
+ ath10k_dfs_state(dfs_state));
+
+ /*
+ * It's safe to call it even if CAC is not started.
+ * This call here guarantees changing channel, etc. will stop CAC.
+ */
+ ath10k_stop_cac(ar);
+
+ if (!radar)
+ return;
+
+ if (!chan_radar)
+ return;
+
+ if (dfs_state != NL80211_DFS_USABLE)
+ return;
+
+ ret = ath10k_start_cac(ar);
+ if (ret) {
+ /*
+ * Not possible to start CAC on current channel so starting
+ * radiation is not allowed, make this channel DFS_UNAVAILABLE
+ * by indicating that radar was detected.
+ */
+ ath10k_warn("failed to start CAC (%d)\n", ret);
+ ieee80211_radar_detected(ar->hw);
+ }
+}
+
static void ath10k_control_beaconing(struct ath10k_vif *arvif,
struct ieee80211_bss_conf *info)
{
@@ -928,7 +880,7 @@
ret = ath10k_wmi_vdev_up(arvif->ar, arvif->vdev_id, arvif->aid,
arvif->bssid);
if (ret) {
- ath10k_warn("failed to bring up vdev %d: %i\n",
+ ath10k_warn("Failed to bring up vdev %d: %i\n",
arvif->vdev_id, ret);
ath10k_vdev_stop(arvif);
return;
@@ -952,7 +904,7 @@
if (!info->ibss_joined) {
ret = ath10k_peer_delete(arvif->ar, arvif->vdev_id, self_peer);
if (ret)
- ath10k_warn("failed to delete IBSS self peer %pM for vdev %d: %d\n",
+ ath10k_warn("Failed to delete IBSS self peer:%pM for VDEV:%d ret:%d\n",
self_peer, arvif->vdev_id, ret);
if (is_zero_ether_addr(arvif->bssid))
@@ -961,7 +913,7 @@
ret = ath10k_peer_delete(arvif->ar, arvif->vdev_id,
arvif->bssid);
if (ret) {
- ath10k_warn("failed to delete IBSS BSSID peer %pM for vdev %d: %d\n",
+ ath10k_warn("Failed to delete IBSS BSSID peer:%pM for VDEV:%d ret:%d\n",
arvif->bssid, arvif->vdev_id, ret);
return;
}
@@ -973,7 +925,7 @@
ret = ath10k_peer_create(arvif->ar, arvif->vdev_id, self_peer);
if (ret) {
- ath10k_warn("failed to create IBSS self peer %pM for vdev %d: %d\n",
+ ath10k_warn("Failed to create IBSS self peer:%pM for VDEV:%d ret:%d\n",
self_peer, arvif->vdev_id, ret);
return;
}
@@ -982,7 +934,7 @@
ret = ath10k_wmi_vdev_set_param(arvif->ar, arvif->vdev_id, vdev_param,
ATH10K_DEFAULT_ATIM);
if (ret)
- ath10k_warn("failed to set IBSS ATIM for vdev %d: %d\n",
+ ath10k_warn("Failed to set IBSS ATIM for VDEV:%d ret:%d\n",
arvif->vdev_id, ret);
}
@@ -1009,7 +961,7 @@
ret = ath10k_wmi_set_sta_ps_param(ar, arvif->vdev_id, param,
conf->dynamic_ps_timeout);
if (ret) {
- ath10k_warn("failed to set inactivity time for vdev %d: %i\n",
+ ath10k_warn("Failed to set inactivity time for vdev %d: %i\n",
arvif->vdev_id, ret);
return ret;
}
@@ -1022,8 +974,8 @@
ret = ath10k_wmi_set_psmode(ar, arvif->vdev_id, psmode);
if (ret) {
- ath10k_warn("failed to set PS Mode %d for vdev %d: %d\n",
- psmode, arvif->vdev_id, ret);
+ ath10k_warn("Failed to set PS Mode: %d for VDEV: %d\n",
+ psmode, arvif->vdev_id);
return ret;
}
@@ -1477,7 +1429,7 @@
ap_sta = ieee80211_find_sta(vif, bss_conf->bssid);
if (!ap_sta) {
- ath10k_warn("failed to find station entry for bss %pM vdev %i\n",
+ ath10k_warn("Failed to find station entry for %pM, vdev %i\n",
bss_conf->bssid, arvif->vdev_id);
rcu_read_unlock();
return;
@@ -1490,7 +1442,7 @@
ret = ath10k_peer_assoc_prepare(ar, arvif, ap_sta,
bss_conf, &peer_arg);
if (ret) {
- ath10k_warn("failed to prepare peer assoc for %pM vdev %i: %d\n",
+ ath10k_warn("Peer assoc prepare failed for %pM vdev %i\n: %d",
bss_conf->bssid, arvif->vdev_id, ret);
rcu_read_unlock();
return;
@@ -1500,7 +1452,7 @@
ret = ath10k_wmi_peer_assoc(ar, &peer_arg);
if (ret) {
- ath10k_warn("failed to run peer assoc for %pM vdev %i: %d\n",
+ ath10k_warn("Peer assoc failed for %pM vdev %i\n: %d",
bss_conf->bssid, arvif->vdev_id, ret);
return;
}
@@ -1521,7 +1473,7 @@
ret = ath10k_wmi_vdev_up(ar, arvif->vdev_id, arvif->aid, arvif->bssid);
if (ret) {
- ath10k_warn("failed to set vdev %d up: %d\n",
+ ath10k_warn("VDEV: %d up failed: ret %d\n",
arvif->vdev_id, ret);
return;
}
@@ -1572,7 +1524,7 @@
}
static int ath10k_station_assoc(struct ath10k *ar, struct ath10k_vif *arvif,
- struct ieee80211_sta *sta, bool reassoc)
+ struct ieee80211_sta *sta)
{
struct wmi_peer_assoc_complete_arg peer_arg;
int ret = 0;
@@ -1581,46 +1533,34 @@
ret = ath10k_peer_assoc_prepare(ar, arvif, sta, NULL, &peer_arg);
if (ret) {
- ath10k_warn("failed to prepare WMI peer assoc for %pM vdev %i: %i\n",
+ ath10k_warn("WMI peer assoc prepare failed for %pM vdev %i: %i\n",
sta->addr, arvif->vdev_id, ret);
return ret;
}
- peer_arg.peer_reassoc = reassoc;
ret = ath10k_wmi_peer_assoc(ar, &peer_arg);
if (ret) {
- ath10k_warn("failed to run peer assoc for STA %pM vdev %i: %d\n",
+ ath10k_warn("Peer assoc failed for STA %pM vdev %i: %d\n",
sta->addr, arvif->vdev_id, ret);
return ret;
}
ret = ath10k_setup_peer_smps(ar, arvif, sta->addr, &sta->ht_cap);
if (ret) {
- ath10k_warn("failed to setup peer SMPS for vdev %d: %d\n",
- arvif->vdev_id, ret);
+ ath10k_warn("failed to setup peer SMPS for vdev: %d\n", ret);
return ret;
}
- if (!sta->wme) {
- arvif->num_legacy_stations++;
- ret = ath10k_recalc_rtscts_prot(arvif);
- if (ret) {
- ath10k_warn("failed to recalculate rts/cts prot for vdev %d: %d\n",
- arvif->vdev_id, ret);
- return ret;
- }
- }
-
ret = ath10k_install_peer_wep_keys(arvif, sta->addr);
if (ret) {
- ath10k_warn("failed to install peer wep keys for vdev %i: %d\n",
+ ath10k_warn("could not install peer wep keys for vdev %i: %d\n",
arvif->vdev_id, ret);
return ret;
}
ret = ath10k_peer_assoc_qos_ap(ar, arvif, sta);
if (ret) {
- ath10k_warn("failed to set qos params for STA %pM for vdev %i: %d\n",
+ ath10k_warn("could not set qos params for STA %pM for vdev %i: %d\n",
sta->addr, arvif->vdev_id, ret);
return ret;
}
@@ -1635,19 +1575,9 @@
lockdep_assert_held(&ar->conf_mutex);
- if (!sta->wme) {
- arvif->num_legacy_stations--;
- ret = ath10k_recalc_rtscts_prot(arvif);
- if (ret) {
- ath10k_warn("failed to recalculate rts/cts prot for vdev %d: %d\n",
- arvif->vdev_id, ret);
- return ret;
- }
- }
-
ret = ath10k_clear_peer_keys(arvif, sta->addr);
if (ret) {
- ath10k_warn("failed to clear all peer wep keys for vdev %i: %d\n",
+ ath10k_warn("could not clear all peer wep keys for vdev %i: %d\n",
arvif->vdev_id, ret);
return ret;
}
@@ -1755,44 +1685,19 @@
return ret;
}
-static enum wmi_dfs_region
-ath10k_mac_get_dfs_region(enum nl80211_dfs_regions dfs_region)
-{
- switch (dfs_region) {
- case NL80211_DFS_UNSET:
- return WMI_UNINIT_DFS_DOMAIN;
- case NL80211_DFS_FCC:
- return WMI_FCC_DFS_DOMAIN;
- case NL80211_DFS_ETSI:
- return WMI_ETSI_DFS_DOMAIN;
- case NL80211_DFS_JP:
- return WMI_MKK4_DFS_DOMAIN;
- }
- return WMI_UNINIT_DFS_DOMAIN;
-}
-
static void ath10k_regd_update(struct ath10k *ar)
{
struct reg_dmn_pair_mapping *regpair;
int ret;
- enum wmi_dfs_region wmi_dfs_reg;
- enum nl80211_dfs_regions nl_dfs_reg;
lockdep_assert_held(&ar->conf_mutex);
ret = ath10k_update_channel_list(ar);
if (ret)
- ath10k_warn("failed to update channel list: %d\n", ret);
+ ath10k_warn("could not update channel list (%d)\n", ret);
regpair = ar->ath_common.regulatory.regpair;
- if (config_enabled(CPTCFG_ATH10K_DFS_CERTIFIED) && ar->dfs_detector) {
- nl_dfs_reg = ar->dfs_detector->region;
- wmi_dfs_reg = ath10k_mac_get_dfs_region(nl_dfs_reg);
- } else {
- wmi_dfs_reg = WMI_UNINIT_DFS_DOMAIN;
- }
-
/* Target allows setting up per-band regdomain but ath_common provides
* a combined one only */
ret = ath10k_wmi_pdev_set_regdomain(ar,
@@ -1800,10 +1705,9 @@
regpair->reg_domain, /* 2ghz */
regpair->reg_domain, /* 5ghz */
regpair->reg_2ghz_ctl,
- regpair->reg_5ghz_ctl,
- wmi_dfs_reg);
+ regpair->reg_5ghz_ctl);
if (ret)
- ath10k_warn("failed to set pdev regdomain: %d\n", ret);
+ ath10k_warn("could not set pdev regdomain (%d)\n", ret);
}
static void ath10k_reg_notifier(struct wiphy *wiphy,
@@ -1821,7 +1725,7 @@
result = ar->dfs_detector->set_dfs_domain(ar->dfs_detector,
request->dfs_region);
if (!result)
- ath10k_warn("DFS region 0x%X not supported, will trigger radar for every pulse\n",
+ ath10k_warn("dfs region 0x%X not supported, will trigger radar for every pulse\n",
request->dfs_region);
}
@@ -1855,10 +1759,10 @@
if (info->control.vif)
return ath10k_vif_to_arvif(info->control.vif)->vdev_id;
- if (ar->monitor_started)
+ if (ar->monitor_enabled)
return ar->monitor_vdev_id;
- ath10k_warn("failed to resolve vdev id\n");
+ ath10k_warn("could not resolve vdev id\n");
return 0;
}
@@ -1899,9 +1803,7 @@
arvif->ar->wmi.vdev_param->def_keyid,
keyidx);
if (ret) {
- ath10k_warn("failed to update wep key index for vdev %d: %d\n",
- arvif->vdev_id,
- ret);
+ ath10k_warn("could not update wep keyidx (%d)\n", ret);
return;
}
@@ -1977,7 +1879,7 @@
ar->fw_features)) {
if (skb_queue_len(&ar->wmi_mgmt_tx_queue) >=
ATH10K_MAX_NUM_MGMT_PENDING) {
- ath10k_warn("reached WMI management tranmist queue limit\n");
+ ath10k_warn("wmi mgmt_tx queue limit reached\n");
ret = -EBUSY;
goto exit;
}
@@ -2001,7 +1903,7 @@
exit:
if (ret) {
- ath10k_warn("failed to transmit packet, dropping: %d\n", ret);
+ ath10k_warn("tx failed (%d). dropping packet.\n", ret);
ieee80211_free_txskb(ar->hw, skb);
}
}
@@ -2062,7 +1964,7 @@
if (!peer) {
ret = ath10k_peer_create(ar, vdev_id, peer_addr);
if (ret)
- ath10k_warn("failed to create peer %pM on vdev %d: %d\n",
+ ath10k_warn("peer %pM on vdev %d not created (%d)\n",
peer_addr, vdev_id, ret);
}
@@ -2082,7 +1984,7 @@
if (!peer) {
ret = ath10k_peer_delete(ar, vdev_id, peer_addr);
if (ret)
- ath10k_warn("failed to delete peer %pM on vdev %d: %d\n",
+ ath10k_warn("peer %pM on vdev %d not deleted (%d)\n",
peer_addr, vdev_id, ret);
}
@@ -2116,8 +2018,7 @@
ret = ath10k_wmi_mgmt_tx(ar, skb);
if (ret) {
- ath10k_warn("failed to transmit management frame via WMI: %d\n",
- ret);
+ ath10k_warn("wmi mgmt_tx failed (%d)\n", ret);
ieee80211_free_txskb(ar->hw, skb);
}
}
@@ -2142,7 +2043,7 @@
return;
}
- ath10k_warn("scan timed out, firmware problem?\n");
+ ath10k_warn("scan timeout. resetting. fw issue?\n");
if (ar->scan.is_roc)
ieee80211_remain_on_channel_expired(ar->hw);
@@ -2178,7 +2079,7 @@
ret = ath10k_wmi_stop_scan(ar, &arg);
if (ret) {
- ath10k_warn("failed to stop wmi scan: %d\n", ret);
+ ath10k_warn("could not submit wmi stop scan (%d)\n", ret);
spin_lock_bh(&ar->data_lock);
ar->scan.in_progress = false;
ath10k_offchan_tx_purge(ar);
@@ -2198,7 +2099,7 @@
spin_lock_bh(&ar->data_lock);
if (ar->scan.in_progress) {
- ath10k_warn("failed to stop scan, it's still in progress\n");
+ ath10k_warn("could not stop scan. its still in progress\n");
ar->scan.in_progress = false;
ath10k_offchan_tx_purge(ar);
ret = -ETIMEDOUT;
@@ -2291,17 +2192,9 @@
*/
void ath10k_halt(struct ath10k *ar)
{
- struct ath10k_vif *arvif;
-
lockdep_assert_held(&ar->conf_mutex);
- if (ath10k_monitor_is_enabled(ar)) {
- clear_bit(ATH10K_CAC_RUNNING, &ar->dev_flags);
- ar->promisc = false;
- ar->monitor = false;
- ath10k_monitor_stop(ar);
- }
-
+ ath10k_stop_cac(ar);
del_timer_sync(&ar->scan.timeout);
ath10k_offchan_tx_purge(ar);
ath10k_mgmt_over_wmi_tx_purge(ar);
@@ -2315,17 +2208,6 @@
ar->scan.in_progress = false;
ieee80211_scan_completed(ar->hw, true);
}
-
- list_for_each_entry(arvif, &ar->arvifs, list) {
- if (!arvif->beacon)
- continue;
-
- dma_unmap_single(arvif->ar->dev,
- ATH10K_SKB_CB(arvif->beacon)->paddr,
- arvif->beacon->len, DMA_TO_DEVICE);
- dev_kfree_skb_any(arvif->beacon);
- arvif->beacon = NULL;
- }
spin_unlock_bh(&ar->data_lock);
}
@@ -2344,14 +2226,14 @@
ret = ath10k_hif_power_up(ar);
if (ret) {
- ath10k_err("Could not init hif: %d\n", ret);
+ ath10k_err("could not init hif (%d)\n", ret);
ar->state = ATH10K_STATE_OFF;
goto exit;
}
ret = ath10k_core_start(ar);
if (ret) {
- ath10k_err("Could not init core: %d\n", ret);
+ ath10k_err("could not init core (%d)\n", ret);
ath10k_hif_power_down(ar);
ar->state = ATH10K_STATE_OFF;
goto exit;
@@ -2364,11 +2246,13 @@
ret = ath10k_wmi_pdev_set_param(ar, ar->wmi.pdev_param->pmf_qos, 1);
if (ret)
- ath10k_warn("failed to enable PMF QOS: %d\n", ret);
+ ath10k_warn("could not enable WMI_PDEV_PARAM_PMF_QOS (%d)\n",
+ ret);
ret = ath10k_wmi_pdev_set_param(ar, ar->wmi.pdev_param->dynamic_bw, 1);
if (ret)
- ath10k_warn("failed to enable dynamic BW: %d\n", ret);
+ ath10k_warn("could not init WMI_PDEV_PARAM_DYNAMIC_BW (%d)\n",
+ ret);
/*
* By default FW set ARP frames ac to voice (6). In that case ARP
@@ -2382,12 +2266,11 @@
ret = ath10k_wmi_pdev_set_param(ar,
ar->wmi.pdev_param->arp_ac_override, 0);
if (ret) {
- ath10k_warn("failed to set arp ac override parameter: %d\n",
+ ath10k_warn("could not set arp ac override parameter: %d\n",
ret);
goto exit;
}
- ar->num_started_vdevs = 0;
ath10k_regd_update(ar);
ret = 0;
@@ -2426,7 +2309,7 @@
list_for_each_entry(arvif, &ar->arvifs, list) {
ret = ath10k_mac_vif_setup_ps(arvif);
if (ret) {
- ath10k_warn("failed to setup powersave: %d\n", ret);
+ ath10k_warn("could not setup powersave (%d)\n", ret);
break;
}
}
@@ -2460,6 +2343,7 @@
static void ath10k_config_chan(struct ath10k *ar)
{
struct ath10k_vif *arvif;
+ bool monitor_was_enabled;
int ret;
lockdep_assert_held(&ar->conf_mutex);
@@ -2473,8 +2357,10 @@
/* First stop monitor interface. Some FW versions crash if there's a
* lone monitor interface. */
- if (ar->monitor_started)
- ath10k_monitor_vdev_stop(ar);
+ monitor_was_enabled = ar->monitor_enabled;
+
+ if (ar->monitor_enabled)
+ ath10k_monitor_stop(ar);
list_for_each_entry(arvif, &ar->arvifs, list) {
if (!arvif->is_started)
@@ -2485,7 +2371,7 @@
ret = ath10k_vdev_stop(arvif);
if (ret) {
- ath10k_warn("failed to stop vdev %d: %d\n",
+ ath10k_warn("could not stop vdev %d (%d)\n",
arvif->vdev_id, ret);
continue;
}
@@ -2502,7 +2388,7 @@
ret = ath10k_vdev_start(arvif);
if (ret) {
- ath10k_warn("failed to start vdev %d: %d\n",
+ ath10k_warn("could not start vdev %d (%d)\n",
arvif->vdev_id, ret);
continue;
}
@@ -2513,14 +2399,14 @@
ret = ath10k_wmi_vdev_up(arvif->ar, arvif->vdev_id, arvif->aid,
arvif->bssid);
if (ret) {
- ath10k_warn("failed to bring vdev up %d: %d\n",
+ ath10k_warn("could not bring vdev up %d (%d)\n",
arvif->vdev_id, ret);
continue;
}
}
- if (ath10k_monitor_is_enabled(ar))
- ath10k_monitor_vdev_start(ar, ar->monitor_vdev_id);
+ if (monitor_was_enabled)
+ ath10k_monitor_start(ar, ar->monitor_vdev_id);
}
static int ath10k_config(struct ieee80211_hw *hw, u32 changed)
@@ -2534,17 +2420,15 @@
if (changed & IEEE80211_CONF_CHANGE_CHANNEL) {
ath10k_dbg(ATH10K_DBG_MAC,
- "mac config channel %dMHz flags 0x%x radar %d\n",
+ "mac config channel %d mhz flags 0x%x\n",
conf->chandef.chan->center_freq,
- conf->chandef.chan->flags,
- conf->radar_enabled);
+ conf->chandef.chan->flags);
spin_lock_bh(&ar->data_lock);
ar->rx_channel = conf->chandef.chan;
spin_unlock_bh(&ar->data_lock);
- ar->radar_enabled = conf->radar_enabled;
- ath10k_recalc_radar_detection(ar);
+ ath10k_config_radar_detection(ar);
if (!cfg80211_chandef_identical(&ar->chandef, &conf->chandef)) {
ar->chandef = conf->chandef;
@@ -2560,14 +2444,14 @@
ret = ath10k_wmi_pdev_set_param(ar, param,
hw->conf.power_level * 2);
if (ret)
- ath10k_warn("failed to set 2g txpower %d: %d\n",
+ ath10k_warn("mac failed to set 2g txpower %d (%d)\n",
hw->conf.power_level, ret);
param = ar->wmi.pdev_param->txpower_limit5g;
ret = ath10k_wmi_pdev_set_param(ar, param,
hw->conf.power_level * 2);
if (ret)
- ath10k_warn("failed to set 5g txpower %d: %d\n",
+ ath10k_warn("mac failed to set 5g txpower %d (%d)\n",
hw->conf.power_level, ret);
}
@@ -2575,19 +2459,10 @@
ath10k_config_ps(ar);
if (changed & IEEE80211_CONF_CHANGE_MONITOR) {
- if (conf->flags & IEEE80211_CONF_MONITOR && !ar->monitor) {
- ar->monitor = true;
- ret = ath10k_monitor_start(ar);
- if (ret) {
- ath10k_warn("failed to start monitor (config): %d\n",
- ret);
- ar->monitor = false;
- }
- } else if (!(conf->flags & IEEE80211_CONF_MONITOR) &&
- ar->monitor) {
- ar->monitor = false;
- ath10k_monitor_stop(ar);
- }
+ if (conf->flags & IEEE80211_CONF_MONITOR)
+ ret = ath10k_monitor_create(ar);
+ else
+ ret = ath10k_monitor_destroy(ar);
}
mutex_unlock(&ar->conf_mutex);
@@ -2622,6 +2497,12 @@
INIT_WORK(&arvif->wep_key_work, ath10k_tx_wep_key_work);
INIT_LIST_HEAD(&arvif->list);
+ if ((vif->type == NL80211_IFTYPE_MONITOR) && ar->monitor_present) {
+ ath10k_warn("Only one monitor interface allowed\n");
+ ret = -EBUSY;
+ goto err;
+ }
+
bit = ffs(ar->free_vdev_map);
if (bit == 0) {
ret = -EBUSY;
@@ -2664,7 +2545,7 @@
ret = ath10k_wmi_vdev_create(ar, arvif->vdev_id, arvif->vdev_type,
arvif->vdev_subtype, vif->addr);
if (ret) {
- ath10k_warn("failed to create WMI vdev %i: %d\n",
+ ath10k_warn("WMI vdev %i create failed: ret %d\n",
arvif->vdev_id, ret);
goto err;
}
@@ -2676,7 +2557,7 @@
ret = ath10k_wmi_vdev_set_param(ar, 0, vdev_param,
arvif->def_wep_key_idx);
if (ret) {
- ath10k_warn("failed to set vdev %i default key id: %d\n",
+ ath10k_warn("Failed to set vdev %i default keyid: %d\n",
arvif->vdev_id, ret);
goto err_vdev_delete;
}
@@ -2686,7 +2567,7 @@
ATH10K_HW_TXRX_NATIVE_WIFI);
/* 10.X firmware does not support this VDEV parameter. Do not warn */
if (ret && ret != -EOPNOTSUPP) {
- ath10k_warn("failed to set vdev %i TX encapsulation: %d\n",
+ ath10k_warn("Failed to set vdev %i TX encap: %d\n",
arvif->vdev_id, ret);
goto err_vdev_delete;
}
@@ -2694,14 +2575,14 @@
if (arvif->vdev_type == WMI_VDEV_TYPE_AP) {
ret = ath10k_peer_create(ar, arvif->vdev_id, vif->addr);
if (ret) {
- ath10k_warn("failed to create vdev %i peer for AP: %d\n",
+ ath10k_warn("Failed to create vdev %i peer for AP: %d\n",
arvif->vdev_id, ret);
goto err_vdev_delete;
}
ret = ath10k_mac_set_kickout(arvif);
if (ret) {
- ath10k_warn("failed to set vdev %i kickout parameters: %d\n",
+ ath10k_warn("Failed to set vdev %i kickout parameters: %d\n",
arvif->vdev_id, ret);
goto err_peer_delete;
}
@@ -2713,7 +2594,7 @@
ret = ath10k_wmi_set_sta_ps_param(ar, arvif->vdev_id,
param, value);
if (ret) {
- ath10k_warn("failed to set vdev %i RX wake policy: %d\n",
+ ath10k_warn("Failed to set vdev %i RX wake policy: %d\n",
arvif->vdev_id, ret);
goto err_peer_delete;
}
@@ -2723,7 +2604,7 @@
ret = ath10k_wmi_set_sta_ps_param(ar, arvif->vdev_id,
param, value);
if (ret) {
- ath10k_warn("failed to set vdev %i TX wake thresh: %d\n",
+ ath10k_warn("Failed to set vdev %i TX wake thresh: %d\n",
arvif->vdev_id, ret);
goto err_peer_delete;
}
@@ -2733,7 +2614,7 @@
ret = ath10k_wmi_set_sta_ps_param(ar, arvif->vdev_id,
param, value);
if (ret) {
- ath10k_warn("failed to set vdev %i PSPOLL count: %d\n",
+ ath10k_warn("Failed to set vdev %i PSPOLL count: %d\n",
arvif->vdev_id, ret);
goto err_peer_delete;
}
@@ -2741,18 +2622,21 @@
ret = ath10k_mac_set_rts(arvif, ar->hw->wiphy->rts_threshold);
if (ret) {
- ath10k_warn("failed to set rts threshold for vdev %d: %d\n",
+ ath10k_warn("failed to set rts threshold for vdev %d (%d)\n",
arvif->vdev_id, ret);
goto err_peer_delete;
}
ret = ath10k_mac_set_frag(arvif, ar->hw->wiphy->frag_threshold);
if (ret) {
- ath10k_warn("failed to set frag threshold for vdev %d: %d\n",
+ ath10k_warn("failed to set frag threshold for vdev %d (%d)\n",
arvif->vdev_id, ret);
goto err_peer_delete;
}
+ if (arvif->vdev_type == WMI_VDEV_TYPE_MONITOR)
+ ar->monitor_present = true;
+
mutex_unlock(&ar->conf_mutex);
return 0;
@@ -2784,9 +2668,6 @@
spin_lock_bh(&ar->data_lock);
if (arvif->beacon) {
- dma_unmap_single(arvif->ar->dev,
- ATH10K_SKB_CB(arvif->beacon)->paddr,
- arvif->beacon->len, DMA_TO_DEVICE);
dev_kfree_skb_any(arvif->beacon);
arvif->beacon = NULL;
}
@@ -2798,7 +2679,7 @@
if (arvif->vdev_type == WMI_VDEV_TYPE_AP) {
ret = ath10k_peer_delete(arvif->ar, arvif->vdev_id, vif->addr);
if (ret)
- ath10k_warn("failed to remove peer for AP vdev %i: %d\n",
+ ath10k_warn("Failed to remove peer for AP vdev %i: %d\n",
arvif->vdev_id, ret);
kfree(arvif->u.ap.noa_data);
@@ -2809,9 +2690,12 @@
ret = ath10k_wmi_vdev_delete(ar, arvif->vdev_id);
if (ret)
- ath10k_warn("failed to delete WMI vdev %i: %d\n",
+ ath10k_warn("WMI vdev %i delete failed: %d\n",
arvif->vdev_id, ret);
+ if (arvif->vdev_type == WMI_VDEV_TYPE_MONITOR)
+ ar->monitor_present = false;
+
ath10k_peer_cleanup(ar, arvif->vdev_id);
mutex_unlock(&ar->conf_mutex);
@@ -2844,17 +2728,28 @@
*total_flags &= SUPPORTED_FILTERS;
ar->filter_flags = *total_flags;
- if (ar->filter_flags & FIF_PROMISC_IN_BSS && !ar->promisc) {
- ar->promisc = true;
- ret = ath10k_monitor_start(ar);
- if (ret) {
- ath10k_warn("failed to start monitor (promisc): %d\n",
- ret);
- ar->promisc = false;
- }
- } else if (!(ar->filter_flags & FIF_PROMISC_IN_BSS) && ar->promisc) {
- ar->promisc = false;
- ath10k_monitor_stop(ar);
+ /* Monitor must not be started if it wasn't created first.
+ * Promiscuous mode may be started on a non-monitor interface - in
+ * such case the monitor vdev is not created so starting the
+ * monitor makes no sense. Since ath10k uses no special RX filters
+ * (only BSS filter in STA mode) there's no need for any special
+ * action here. */
+ if ((ar->filter_flags & FIF_PROMISC_IN_BSS) &&
+ !ar->monitor_enabled && ar->monitor_present) {
+ ath10k_dbg(ATH10K_DBG_MAC, "mac monitor %d start\n",
+ ar->monitor_vdev_id);
+
+ ret = ath10k_monitor_start(ar, ar->monitor_vdev_id);
+ if (ret)
+ ath10k_warn("Unable to start monitor mode\n");
+ } else if (!(ar->filter_flags & FIF_PROMISC_IN_BSS) &&
+ ar->monitor_enabled && ar->monitor_present) {
+ ath10k_dbg(ATH10K_DBG_MAC, "mac monitor %d stop\n",
+ ar->monitor_vdev_id);
+
+ ret = ath10k_monitor_stop(ar);
+ if (ret)
+ ath10k_warn("Unable to stop monitor mode\n");
}
mutex_unlock(&ar->conf_mutex);
@@ -2885,7 +2780,7 @@
arvif->vdev_id, arvif->beacon_interval);
if (ret)
- ath10k_warn("failed to set beacon interval for vdev %d: %i\n",
+ ath10k_warn("Failed to set beacon interval for vdev %d: %i\n",
arvif->vdev_id, ret);
}
@@ -2898,7 +2793,7 @@
ret = ath10k_wmi_pdev_set_param(ar, pdev_param,
WMI_BEACON_STAGGERED_MODE);
if (ret)
- ath10k_warn("failed to set beacon mode for vdev %d: %i\n",
+ ath10k_warn("Failed to set beacon mode for vdev %d: %i\n",
arvif->vdev_id, ret);
}
@@ -2913,7 +2808,7 @@
ret = ath10k_wmi_vdev_set_param(ar, arvif->vdev_id, vdev_param,
arvif->dtim_period);
if (ret)
- ath10k_warn("failed to set dtim period for vdev %d: %i\n",
+ ath10k_warn("Failed to set dtim period for vdev %d: %i\n",
arvif->vdev_id, ret);
}
@@ -2934,7 +2829,7 @@
ret = ath10k_peer_create(ar, arvif->vdev_id,
info->bssid);
if (ret)
- ath10k_warn("failed to add peer %pM for vdev %d when changing bssid: %i\n",
+ ath10k_warn("Failed to add peer %pM for vdev %d when changing bssid: %i\n",
info->bssid, arvif->vdev_id, ret);
if (vif->type == NL80211_IFTYPE_STATION) {
@@ -2973,13 +2868,20 @@
ath10k_control_beaconing(arvif, info);
if (changed & BSS_CHANGED_ERP_CTS_PROT) {
- arvif->use_cts_prot = info->use_cts_prot;
- ath10k_dbg(ATH10K_DBG_MAC, "mac vdev %d cts_prot %d\n",
- arvif->vdev_id, info->use_cts_prot);
+ u32 cts_prot;
+ if (info->use_cts_prot)
+ cts_prot = 1;
+ else
+ cts_prot = 0;
- ret = ath10k_recalc_rtscts_prot(arvif);
+ ath10k_dbg(ATH10K_DBG_MAC, "mac vdev %d cts_prot %d\n",
+ arvif->vdev_id, cts_prot);
+
+ vdev_param = ar->wmi.vdev_param->enable_rtscts;
+ ret = ath10k_wmi_vdev_set_param(ar, arvif->vdev_id, vdev_param,
+ cts_prot);
if (ret)
- ath10k_warn("failed to recalculate rts/cts prot for vdev %d: %d\n",
+ ath10k_warn("Failed to set CTS prot for vdev %d: %d\n",
arvif->vdev_id, ret);
}
@@ -2998,7 +2900,7 @@
ret = ath10k_wmi_vdev_set_param(ar, arvif->vdev_id, vdev_param,
slottime);
if (ret)
- ath10k_warn("failed to set erp slot for vdev %d: %i\n",
+ ath10k_warn("Failed to set erp slot for vdev %d: %i\n",
arvif->vdev_id, ret);
}
@@ -3017,7 +2919,7 @@
ret = ath10k_wmi_vdev_set_param(ar, arvif->vdev_id, vdev_param,
preamble);
if (ret)
- ath10k_warn("failed to set preamble for vdev %d: %i\n",
+ ath10k_warn("Failed to set preamble for vdev %d: %i\n",
arvif->vdev_id, ret);
}
@@ -3088,7 +2990,7 @@
ret = ath10k_start_scan(ar, &arg);
if (ret) {
- ath10k_warn("failed to start hw scan: %d\n", ret);
+ ath10k_warn("could not start hw scan (%d)\n", ret);
spin_lock_bh(&ar->data_lock);
ar->scan.in_progress = false;
spin_unlock_bh(&ar->data_lock);
@@ -3108,7 +3010,8 @@
mutex_lock(&ar->conf_mutex);
ret = ath10k_abort_scan(ar);
if (ret) {
- ath10k_warn("failed to abort scan: %d\n", ret);
+ ath10k_warn("couldn't abort scan (%d). forcefully sending scan completion to mac80211\n",
+ ret);
ieee80211_scan_completed(hw, 1 /* aborted */);
}
mutex_unlock(&ar->conf_mutex);
@@ -3186,7 +3089,7 @@
if (!peer) {
if (cmd == SET_KEY) {
- ath10k_warn("failed to install key for non-existent peer %pM\n",
+ ath10k_warn("cannot install key for non-existent peer %pM\n",
peer_addr);
ret = -EOPNOTSUPP;
goto exit;
@@ -3209,7 +3112,7 @@
ret = ath10k_install_key(arvif, key, cmd, peer_addr);
if (ret) {
- ath10k_warn("failed to install key for vdev %i peer %pM: %d\n",
+ ath10k_warn("key installation failed for vdev %i peer %pM: %d\n",
arvif->vdev_id, peer_addr, ret);
goto exit;
}
@@ -3224,7 +3127,7 @@
peer->keys[key->keyidx] = NULL;
else if (peer == NULL)
/* impossible unless FW goes crazy */
- ath10k_warn("Peer %pM disappeared!\n", peer_addr);
+ ath10k_warn("peer %pM disappeared!\n", peer_addr);
spin_unlock_bh(&ar->data_lock);
exit:
@@ -3292,16 +3195,6 @@
sta->addr, smps, err);
}
- if (changed & IEEE80211_RC_SUPP_RATES_CHANGED) {
- ath10k_dbg(ATH10K_DBG_MAC, "mac update sta %pM supp rates\n",
- sta->addr);
-
- err = ath10k_station_assoc(ar, arvif, sta, true);
- if (err)
- ath10k_warn("failed to reassociate station: %pM\n",
- sta->addr);
- }
-
mutex_unlock(&ar->conf_mutex);
}
@@ -3343,7 +3236,7 @@
max_num_peers = TARGET_NUM_PEERS;
if (ar->num_peers >= max_num_peers) {
- ath10k_warn("number of peers exceeded: peers number %d (max peers %d)\n",
+ ath10k_warn("Number of peers exceeded: peers number %d (max peers %d)\n",
ar->num_peers, max_num_peers);
ret = -ENOBUFS;
goto exit;
@@ -3355,7 +3248,7 @@
ret = ath10k_peer_create(ar, arvif->vdev_id, sta->addr);
if (ret)
- ath10k_warn("failed to add peer %pM for vdev %d when adding a new sta: %i\n",
+ ath10k_warn("Failed to add peer %pM for vdev %d when adding a new sta: %i\n",
sta->addr, arvif->vdev_id, ret);
} else if ((old_state == IEEE80211_STA_NONE &&
new_state == IEEE80211_STA_NOTEXIST)) {
@@ -3367,7 +3260,7 @@
arvif->vdev_id, sta->addr);
ret = ath10k_peer_delete(ar, arvif->vdev_id, sta->addr);
if (ret)
- ath10k_warn("failed to delete peer %pM for vdev %d: %i\n",
+ ath10k_warn("Failed to delete peer %pM for vdev %d: %i\n",
sta->addr, arvif->vdev_id, ret);
if (vif->type == NL80211_IFTYPE_STATION)
@@ -3382,9 +3275,9 @@
ath10k_dbg(ATH10K_DBG_MAC, "mac sta %pM associated\n",
sta->addr);
- ret = ath10k_station_assoc(ar, arvif, sta, false);
+ ret = ath10k_station_assoc(ar, arvif, sta);
if (ret)
- ath10k_warn("failed to associate station %pM for vdev %i: %i\n",
+ ath10k_warn("Failed to associate station %pM for vdev %i: %i\n",
sta->addr, arvif->vdev_id, ret);
} else if (old_state == IEEE80211_STA_ASSOC &&
new_state == IEEE80211_STA_AUTH &&
@@ -3398,7 +3291,7 @@
ret = ath10k_station_disassoc(ar, arvif, sta);
if (ret)
- ath10k_warn("failed to disassociate station: %pM vdev %i: %i\n",
+ ath10k_warn("Failed to disassociate station: %pM vdev %i ret %i\n",
sta->addr, arvif->vdev_id, ret);
}
exit:
@@ -3446,7 +3339,7 @@
WMI_STA_PS_PARAM_UAPSD,
arvif->u.sta.uapsd);
if (ret) {
- ath10k_warn("failed to set uapsd params: %d\n", ret);
+ ath10k_warn("could not set uapsd params %d\n", ret);
goto exit;
}
@@ -3459,7 +3352,7 @@
WMI_STA_PS_PARAM_RX_WAKE_POLICY,
value);
if (ret)
- ath10k_warn("failed to set rx wake param: %d\n", ret);
+ ath10k_warn("could not set rx wake param %d\n", ret);
exit:
return ret;
@@ -3509,13 +3402,13 @@
/* FIXME: FW accepts wmm params per hw, not per vif */
ret = ath10k_wmi_pdev_set_wmm_params(ar, &ar->wmm_params);
if (ret) {
- ath10k_warn("failed to set wmm params: %d\n", ret);
+ ath10k_warn("could not set wmm params %d\n", ret);
goto exit;
}
ret = ath10k_conf_tx_uapsd(ar, vif, ac, params->uapsd);
if (ret)
- ath10k_warn("failed to set sta uapsd: %d\n", ret);
+ ath10k_warn("could not set sta uapsd %d\n", ret);
exit:
mutex_unlock(&ar->conf_mutex);
@@ -3568,7 +3461,7 @@
ret = ath10k_start_scan(ar, &arg);
if (ret) {
- ath10k_warn("failed to start roc scan: %d\n", ret);
+ ath10k_warn("could not start roc scan (%d)\n", ret);
spin_lock_bh(&ar->data_lock);
ar->scan.in_progress = false;
spin_unlock_bh(&ar->data_lock);
@@ -3577,7 +3470,7 @@
ret = wait_for_completion_timeout(&ar->scan.on_channel, 3*HZ);
if (ret == 0) {
- ath10k_warn("failed to switch to channel for roc scan\n");
+ ath10k_warn("could not switch to channel for roc scan\n");
ath10k_abort_scan(ar);
ret = -ETIMEDOUT;
goto exit;
@@ -3618,7 +3511,7 @@
ret = ath10k_mac_set_rts(arvif, value);
if (ret) {
- ath10k_warn("failed to set rts threshold for vdev %d: %d\n",
+ ath10k_warn("could not set rts threshold for vdev %d (%d)\n",
arvif->vdev_id, ret);
break;
}
@@ -3641,7 +3534,7 @@
ret = ath10k_mac_set_rts(arvif, value);
if (ret) {
- ath10k_warn("failed to set fragmentation threshold for vdev %d: %d\n",
+ ath10k_warn("could not set fragmentation threshold for vdev %d (%d)\n",
arvif->vdev_id, ret);
break;
}
@@ -3680,7 +3573,7 @@
}), ATH10K_FLUSH_TIMEOUT_HZ);
if (ret <= 0 || skip)
- ath10k_warn("failed to flush transmit queue (skip %i ar-state %i): %i\n",
+ ath10k_warn("tx not flushed (skip %i ar-state %i): %i\n",
skip, ar->state, ret);
skip:
@@ -3715,7 +3608,7 @@
ret = ath10k_hif_suspend(ar);
if (ret) {
- ath10k_warn("failed to suspend hif: %d\n", ret);
+ ath10k_warn("could not suspend hif (%d)\n", ret);
goto resume;
}
@@ -3724,7 +3617,7 @@
resume:
ret = ath10k_wmi_pdev_resume_target(ar);
if (ret)
- ath10k_warn("failed to resume target: %d\n", ret);
+ ath10k_warn("could not resume target (%d)\n", ret);
ret = 1;
exit:
@@ -3741,14 +3634,14 @@
ret = ath10k_hif_resume(ar);
if (ret) {
- ath10k_warn("failed to resume hif: %d\n", ret);
+ ath10k_warn("could not resume hif (%d)\n", ret);
ret = 1;
goto exit;
}
ret = ath10k_wmi_pdev_resume_target(ar);
if (ret) {
- ath10k_warn("failed to resume target: %d\n", ret);
+ ath10k_warn("could not resume target (%d)\n", ret);
ret = 1;
goto exit;
}
@@ -4071,7 +3964,7 @@
ret = ath10k_wmi_vdev_set_param(ar, arvif->vdev_id,
vdev_param, fixed_rate);
if (ret) {
- ath10k_warn("failed to set fixed rate param 0x%02x: %d\n",
+ ath10k_warn("Could not set fixed_rate param 0x%02x: %d\n",
fixed_rate, ret);
ret = -EINVAL;
goto exit;
@@ -4084,7 +3977,7 @@
vdev_param, fixed_nss);
if (ret) {
- ath10k_warn("failed to set fixed nss param %d: %d\n",
+ ath10k_warn("Could not set fixed_nss param %d: %d\n",
fixed_nss, ret);
ret = -EINVAL;
goto exit;
@@ -4097,7 +3990,7 @@
force_sgi);
if (ret) {
- ath10k_warn("failed to set sgi param %d: %d\n",
+ ath10k_warn("Could not set sgi param %d: %d\n",
force_sgi, ret);
ret = -EINVAL;
goto exit;
@@ -4133,7 +4026,7 @@
}
if (fixed_rate == WMI_FIXED_RATE_NONE && force_sgi) {
- ath10k_warn("failed to force SGI usage for default rate settings\n");
+ ath10k_warn("Could not force SGI usage for default rate settings\n");
return -EINVAL;
}
@@ -4179,8 +4072,8 @@
bw = WMI_PEER_CHWIDTH_80MHZ;
break;
case IEEE80211_STA_RX_BW_160:
- ath10k_warn("Invalid bandwith %d in rc update for %pM\n",
- sta->bandwidth, sta->addr);
+ ath10k_warn("mac sta rc update for %pM: invalid bw %d\n",
+ sta->addr, sta->bandwidth);
bw = WMI_PEER_CHWIDTH_20MHZ;
break;
}
@@ -4206,8 +4099,8 @@
smps = WMI_PEER_SMPS_DYNAMIC;
break;
case IEEE80211_SMPS_NUM_MODES:
- ath10k_warn("Invalid smps %d in sta rc update for %pM\n",
- sta->smps_mode, sta->addr);
+ ath10k_warn("mac sta rc update for %pM: invalid smps: %d\n",
+ sta->addr, sta->smps_mode);
smps = WMI_PEER_SMPS_PS_NONE;
break;
}
@@ -4215,6 +4108,15 @@
arsta->smps = smps;
}
+ if (changed & IEEE80211_RC_SUPP_RATES_CHANGED) {
+ /* FIXME: Not implemented. Probably the only way to do it would
+ * be to re-assoc the peer. */
+ changed &= ~IEEE80211_RC_SUPP_RATES_CHANGED;
+ ath10k_dbg(ATH10K_DBG_MAC,
+ "mac sta rc update for %pM: changing supported rates not implemented\n",
+ sta->addr);
+ }
+
arsta->changed |= changed;
spin_unlock_bh(&ar->data_lock);
@@ -4614,6 +4516,7 @@
IEEE80211_HW_REPORTS_TX_ACK_STATUS |
IEEE80211_HW_HAS_RATE_CONTROL |
IEEE80211_HW_SUPPORTS_STATIC_SMPS |
+ IEEE80211_HW_WANT_MONITOR_VIF |
IEEE80211_HW_AP_LINK_PS |
IEEE80211_HW_SPECTRUM_MGMT;
@@ -4667,19 +4570,19 @@
NL80211_DFS_UNSET);
if (!ar->dfs_detector)
- ath10k_warn("failed to initialise DFS pattern detector\n");
+ ath10k_warn("dfs pattern detector init failed\n");
}
ret = ath_regd_init(&ar->ath_common.regulatory, ar->hw->wiphy,
ath10k_reg_notifier);
if (ret) {
- ath10k_err("failed to initialise regulatory: %i\n", ret);
+ ath10k_err("Regulatory initialization failed: %i\n", ret);
goto err_free;
}
ret = ieee80211_register_hw(ar->hw);
if (ret) {
- ath10k_err("failed to register ieee80211: %d\n", ret);
+ ath10k_err("ieee80211 registration failed: %d\n", ret);
goto err_free;
}
diff --git a/drivers/net/wireless/ath/ath10k/pci.c b/drivers/net/wireless/ath/ath10k/pci.c
index 66b1f30..9d242d8 100644
--- a/drivers/net/wireless/ath/ath10k/pci.c
+++ b/drivers/net/wireless/ath/ath10k/pci.c
@@ -39,27 +39,15 @@
ATH10K_PCI_IRQ_MSI = 2,
};
-enum ath10k_pci_reset_mode {
- ATH10K_PCI_RESET_AUTO = 0,
- ATH10K_PCI_RESET_WARM_ONLY = 1,
-};
-
-static unsigned int ath10k_pci_target_ps;
+static unsigned int ath10k_target_ps;
static unsigned int ath10k_pci_irq_mode = ATH10K_PCI_IRQ_AUTO;
-static unsigned int ath10k_pci_reset_mode = ATH10K_PCI_RESET_AUTO;
-module_param_named(target_ps, ath10k_pci_target_ps, uint, 0644);
-MODULE_PARM_DESC(target_ps, "Enable ath10k Target (SoC) PS option");
+module_param(ath10k_target_ps, uint, 0644);
+MODULE_PARM_DESC(ath10k_target_ps, "Enable ath10k Target (SoC) PS option");
module_param_named(irq_mode, ath10k_pci_irq_mode, uint, 0644);
MODULE_PARM_DESC(irq_mode, "0: auto, 1: legacy, 2: msi (default: 0)");
-module_param_named(reset_mode, ath10k_pci_reset_mode, uint, 0644);
-MODULE_PARM_DESC(reset_mode, "0: auto, 1: warm only (default: 0)");
-
-/* how long wait to wait for target to initialise, in ms */
-#define ATH10K_PCI_TARGET_WAIT 3000
-
#define QCA988X_2_0_DEVICE_ID (0x003c)
static DEFINE_PCI_DEVICE_TABLE(ath10k_pci_id_table) = {
@@ -358,10 +346,9 @@
* 2) Buffer in DMA-able space
*/
orig_nbytes = nbytes;
- data_buf = (unsigned char *)dma_alloc_coherent(ar->dev,
- orig_nbytes,
- &ce_data_base,
- GFP_ATOMIC);
+ data_buf = (unsigned char *)pci_alloc_consistent(ar_pci->pdev,
+ orig_nbytes,
+ &ce_data_base);
if (!data_buf) {
ret = -ENOMEM;
@@ -455,12 +442,12 @@
__le32_to_cpu(((__le32 *)data_buf)[i]);
}
} else
- ath10k_warn("failed to read diag value at 0x%x: %d\n",
- address, ret);
+ ath10k_dbg(ATH10K_DBG_PCI, "%s failure (0x%x)\n",
+ __func__, address);
if (data_buf)
- dma_free_coherent(ar->dev, orig_nbytes, data_buf,
- ce_data_base);
+ pci_free_consistent(ar_pci->pdev, orig_nbytes,
+ data_buf, ce_data_base);
return ret;
}
@@ -503,10 +490,9 @@
* 2) Buffer in DMA-able space
*/
orig_nbytes = nbytes;
- data_buf = (unsigned char *)dma_alloc_coherent(ar->dev,
- orig_nbytes,
- &ce_data_base,
- GFP_ATOMIC);
+ data_buf = (unsigned char *)pci_alloc_consistent(ar_pci->pdev,
+ orig_nbytes,
+ &ce_data_base);
if (!data_buf) {
ret = -ENOMEM;
goto done;
@@ -602,13 +588,13 @@
done:
if (data_buf) {
- dma_free_coherent(ar->dev, orig_nbytes, data_buf,
- ce_data_base);
+ pci_free_consistent(ar_pci->pdev, orig_nbytes, data_buf,
+ ce_data_base);
}
if (ret != 0)
- ath10k_warn("failed to write diag value at 0x%x: %d\n",
- address, ret);
+ ath10k_dbg(ATH10K_DBG_PCI, "%s failure (0x%x)\n", __func__,
+ address);
return ret;
}
@@ -817,9 +803,6 @@
static u16 ath10k_pci_hif_get_free_queue_number(struct ath10k *ar, u8 pipe)
{
struct ath10k_pci *ar_pci = ath10k_pci_priv(ar);
-
- ath10k_dbg(ATH10K_DBG_PCI, "pci hif get free queue number\n");
-
return ath10k_ce_num_free_src_entries(ar_pci->pipe_info[pipe].ce_hdl);
}
@@ -871,8 +854,6 @@
static void ath10k_pci_hif_send_complete_check(struct ath10k *ar, u8 pipe,
int force)
{
- ath10k_dbg(ATH10K_DBG_PCI, "pci hif send complete check\n");
-
if (!force) {
int resources;
/*
@@ -899,7 +880,7 @@
{
struct ath10k_pci *ar_pci = ath10k_pci_priv(ar);
- ath10k_dbg(ATH10K_DBG_PCI, "pci hif set callbacks\n");
+ ath10k_dbg(ATH10K_DBG_PCI, "%s\n", __func__);
memcpy(&ar_pci->msg_callbacks_current, callbacks,
sizeof(ar_pci->msg_callbacks_current));
@@ -957,8 +938,6 @@
{
int ret = 0;
- ath10k_dbg(ATH10K_DBG_PCI, "pci hif map service\n");
-
/* polling for received messages not supported */
*dl_is_polled = 0;
@@ -1018,8 +997,6 @@
{
int ul_is_polled, dl_is_polled;
- ath10k_dbg(ATH10K_DBG_PCI, "pci hif get default pipe\n");
-
(void)ath10k_pci_hif_map_service_to_pipe(ar,
ATH10K_HTC_SVC_ID_RSVD_CTRL,
ul_pipe,
@@ -1121,8 +1098,6 @@
struct ath10k_pci *ar_pci = ath10k_pci_priv(ar);
int ret, ret_early;
- ath10k_dbg(ATH10K_DBG_BOOT, "boot hif start\n");
-
ath10k_pci_free_early_irq(ar);
ath10k_pci_kill_tasklet(ar);
@@ -1258,10 +1233,18 @@
static void ath10k_pci_ce_deinit(struct ath10k *ar)
{
- int i;
+ struct ath10k_pci *ar_pci = ath10k_pci_priv(ar);
+ struct ath10k_pci_pipe *pipe_info;
+ int pipe_num;
- for (i = 0; i < CE_COUNT; i++)
- ath10k_ce_deinit_pipe(ar, i);
+ for (pipe_num = 0; pipe_num < CE_COUNT; pipe_num++) {
+ pipe_info = &ar_pci->pipe_info[pipe_num];
+ if (pipe_info->ce_hdl) {
+ ath10k_ce_deinit(pipe_info->ce_hdl);
+ pipe_info->ce_hdl = NULL;
+ pipe_info->buf_sz = 0;
+ }
+ }
}
static void ath10k_pci_hif_stop(struct ath10k *ar)
@@ -1269,7 +1252,7 @@
struct ath10k_pci *ar_pci = ath10k_pci_priv(ar);
int ret;
- ath10k_dbg(ATH10K_DBG_BOOT, "boot hif stop\n");
+ ath10k_dbg(ATH10K_DBG_PCI, "%s\n", __func__);
ret = ath10k_ce_disable_interrupts(ar);
if (ret)
@@ -1714,49 +1697,30 @@
return 0;
}
-static int ath10k_pci_alloc_ce(struct ath10k *ar)
-{
- int i, ret;
- for (i = 0; i < CE_COUNT; i++) {
- ret = ath10k_ce_alloc_pipe(ar, i, &host_ce_config_wlan[i]);
- if (ret) {
- ath10k_err("failed to allocate copy engine pipe %d: %d\n",
- i, ret);
- return ret;
- }
- }
-
- return 0;
-}
-
-static void ath10k_pci_free_ce(struct ath10k *ar)
-{
- int i;
-
- for (i = 0; i < CE_COUNT; i++)
- ath10k_ce_free_pipe(ar, i);
-}
static int ath10k_pci_ce_init(struct ath10k *ar)
{
struct ath10k_pci *ar_pci = ath10k_pci_priv(ar);
struct ath10k_pci_pipe *pipe_info;
const struct ce_attr *attr;
- int pipe_num, ret;
+ int pipe_num;
for (pipe_num = 0; pipe_num < CE_COUNT; pipe_num++) {
pipe_info = &ar_pci->pipe_info[pipe_num];
- pipe_info->ce_hdl = &ar_pci->ce_states[pipe_num];
pipe_info->pipe_num = pipe_num;
pipe_info->hif_ce_state = ar;
attr = &host_ce_config_wlan[pipe_num];
- ret = ath10k_ce_init_pipe(ar, pipe_num, attr);
- if (ret) {
- ath10k_err("failed to initialize copy engine pipe %d: %d\n",
- pipe_num, ret);
- return ret;
+ pipe_info->ce_hdl = ath10k_ce_init(ar, pipe_num, attr);
+ if (pipe_info->ce_hdl == NULL) {
+ ath10k_err("failed to initialize CE for pipe: %d\n",
+ pipe_num);
+
+ /* It is safe to call it here. It checks if ce_hdl is
+ * valid for each pipe */
+ ath10k_pci_ce_deinit(ar);
+ return -1;
}
if (pipe_num == CE_COUNT - 1) {
@@ -1777,15 +1741,16 @@
static void ath10k_pci_fw_interrupt_handler(struct ath10k *ar)
{
struct ath10k_pci *ar_pci = ath10k_pci_priv(ar);
- u32 fw_indicator;
+ u32 fw_indicator_address, fw_indicator;
ath10k_pci_wake(ar);
- fw_indicator = ath10k_pci_read32(ar, FW_INDICATOR_ADDRESS);
+ fw_indicator_address = ar_pci->fw_indicator_address;
+ fw_indicator = ath10k_pci_read32(ar, fw_indicator_address);
if (fw_indicator & FW_IND_EVENT_PENDING) {
/* ACK: clear Target-side pending event */
- ath10k_pci_write32(ar, FW_INDICATOR_ADDRESS,
+ ath10k_pci_write32(ar, fw_indicator_address,
fw_indicator & ~FW_IND_EVENT_PENDING);
if (ar_pci->started) {
@@ -1804,10 +1769,11 @@
static int ath10k_pci_warm_reset(struct ath10k *ar)
{
+ struct ath10k_pci *ar_pci = ath10k_pci_priv(ar);
int ret = 0;
u32 val;
- ath10k_dbg(ATH10K_DBG_BOOT, "boot warm reset\n");
+ ath10k_dbg(ATH10K_DBG_BOOT, "boot performing warm chip reset\n");
ret = ath10k_do_pci_wake(ar);
if (ret) {
@@ -1835,7 +1801,7 @@
msleep(100);
/* clear fw indicator */
- ath10k_pci_write32(ar, FW_INDICATOR_ADDRESS, 0);
+ ath10k_pci_write32(ar, ar_pci->fw_indicator_address, 0);
/* clear target LF timer interrupts */
val = ath10k_pci_read32(ar, RTC_SOC_BASE_ADDRESS +
@@ -1968,9 +1934,7 @@
irq_mode = "legacy";
if (!test_bit(ATH10K_FLAG_FIRST_BOOT_DONE, &ar->dev_flags))
- ath10k_info("pci irq %s irq_mode %d reset_mode %d\n",
- irq_mode, ath10k_pci_irq_mode,
- ath10k_pci_reset_mode);
+ ath10k_info("pci irq %s\n", irq_mode);
return 0;
@@ -1992,8 +1956,6 @@
{
int ret;
- ath10k_dbg(ATH10K_DBG_BOOT, "boot hif power up\n");
-
/*
* Hardware CUS232 version 2 has some issues with cold reset and the
* preferred (and safer) way to perform a device reset is through a
@@ -2004,14 +1966,9 @@
*/
ret = __ath10k_pci_hif_power_up(ar, false);
if (ret) {
- ath10k_warn("failed to power up target using warm reset: %d\n",
+ ath10k_warn("failed to power up target using warm reset (%d), trying cold reset\n",
ret);
- if (ath10k_pci_reset_mode == ATH10K_PCI_RESET_WARM_ONLY)
- return ret;
-
- ath10k_warn("trying cold reset\n");
-
ret = __ath10k_pci_hif_power_up(ar, true);
if (ret) {
ath10k_err("failed to power up target using cold reset too (%d)\n",
@@ -2027,14 +1984,12 @@
{
struct ath10k_pci *ar_pci = ath10k_pci_priv(ar);
- ath10k_dbg(ATH10K_DBG_BOOT, "boot hif power down\n");
-
ath10k_pci_free_early_irq(ar);
ath10k_pci_kill_tasklet(ar);
ath10k_pci_deinit_irq(ar);
- ath10k_pci_ce_deinit(ar);
ath10k_pci_warm_reset(ar);
+ ath10k_pci_ce_deinit(ar);
if (!test_bit(ATH10K_PCI_FEATURE_SOC_POWER_SAVE, ar_pci->features))
ath10k_do_pci_sleep(ar);
}
@@ -2182,6 +2137,7 @@
static void ath10k_pci_early_irq_tasklet(unsigned long data)
{
struct ath10k *ar = (struct ath10k *)data;
+ struct ath10k_pci *ar_pci = ath10k_pci_priv(ar);
u32 fw_ind;
int ret;
@@ -2192,9 +2148,9 @@
return;
}
- fw_ind = ath10k_pci_read32(ar, FW_INDICATOR_ADDRESS);
+ fw_ind = ath10k_pci_read32(ar, ar_pci->fw_indicator_address);
if (fw_ind & FW_IND_EVENT_PENDING) {
- ath10k_pci_write32(ar, FW_INDICATOR_ADDRESS,
+ ath10k_pci_write32(ar, ar_pci->fw_indicator_address,
fw_ind & ~FW_IND_EVENT_PENDING);
/* Some structures are unavailable during early boot or at
@@ -2429,66 +2385,33 @@
static int ath10k_pci_wait_for_target_init(struct ath10k *ar)
{
struct ath10k_pci *ar_pci = ath10k_pci_priv(ar);
- unsigned long timeout;
+ int wait_limit = 300; /* 3 sec */
int ret;
- u32 val;
-
- ath10k_dbg(ATH10K_DBG_BOOT, "boot waiting target to initialise\n");
ret = ath10k_pci_wake(ar);
if (ret) {
- ath10k_err("failed to wake up target for init: %d\n", ret);
+ ath10k_err("failed to wake up target: %d\n", ret);
return ret;
}
- timeout = jiffies + msecs_to_jiffies(ATH10K_PCI_TARGET_WAIT);
-
- do {
- val = ath10k_pci_read32(ar, FW_INDICATOR_ADDRESS);
-
- ath10k_dbg(ATH10K_DBG_BOOT, "boot target indicator %x\n", val);
-
- /* target should never return this */
- if (val == 0xffffffff)
- continue;
-
- /* the device has crashed so don't bother trying anymore */
- if (val & FW_IND_EVENT_PENDING)
- break;
-
- if (val & FW_IND_INITIALIZED)
- break;
-
+ while (wait_limit-- &&
+ !(ioread32(ar_pci->mem + FW_INDICATOR_ADDRESS) &
+ FW_IND_INITIALIZED)) {
if (ar_pci->num_msi_intrs == 0)
/* Fix potential race by repeating CORE_BASE writes */
- ath10k_pci_soc_write32(ar, PCIE_INTR_ENABLE_ADDRESS,
- PCIE_INTR_FIRMWARE_MASK |
- PCIE_INTR_CE_MASK_ALL);
-
+ iowrite32(PCIE_INTR_FIRMWARE_MASK |
+ PCIE_INTR_CE_MASK_ALL,
+ ar_pci->mem + (SOC_CORE_BASE_ADDRESS |
+ PCIE_INTR_ENABLE_ADDRESS));
mdelay(10);
- } while (time_before(jiffies, timeout));
+ }
- if (val == 0xffffffff) {
- ath10k_err("failed to read device register, device is gone\n");
+ if (wait_limit < 0) {
+ ath10k_err("target stalled\n");
ret = -EIO;
goto out;
}
- if (val & FW_IND_EVENT_PENDING) {
- ath10k_warn("device has crashed during init\n");
- ret = -ECOMM;
- goto out;
- }
-
- if (!(val & FW_IND_INITIALIZED)) {
- ath10k_err("failed to receive initialized event from target: %08x\n",
- val);
- ret = -ETIMEDOUT;
- goto out;
- }
-
- ath10k_dbg(ATH10K_DBG_BOOT, "boot target initialised\n");
-
out:
ath10k_pci_sleep(ar);
return ret;
@@ -2499,8 +2422,6 @@
int i, ret;
u32 val;
- ath10k_dbg(ATH10K_DBG_BOOT, "boot cold reset\n");
-
ret = ath10k_do_pci_wake(ar);
if (ret) {
ath10k_err("failed to wake up target: %d\n",
@@ -2532,9 +2453,6 @@
}
ath10k_do_pci_sleep(ar);
-
- ath10k_dbg(ATH10K_DBG_BOOT, "boot cold reset complete\n");
-
return 0;
}
@@ -2566,7 +2484,7 @@
struct ath10k_pci *ar_pci;
u32 lcr_val, chip_id;
- ath10k_dbg(ATH10K_DBG_PCI, "pci probe\n");
+ ath10k_dbg(ATH10K_DBG_PCI, "%s\n", __func__);
ar_pci = kzalloc(sizeof(*ar_pci), GFP_KERNEL);
if (ar_pci == NULL)
@@ -2585,7 +2503,7 @@
goto err_ar_pci;
}
- if (ath10k_pci_target_ps)
+ if (ath10k_target_ps)
set_bit(ATH10K_PCI_FEATURE_SOC_POWER_SAVE, ar_pci->features);
ath10k_pci_dump_features(ar_pci);
@@ -2598,6 +2516,7 @@
}
ar_pci->ar = ar;
+ ar_pci->fw_indicator_address = FW_INDICATOR_ADDRESS;
atomic_set(&ar_pci->keep_awake_count, 0);
pci_set_drvdata(pdev, ar);
@@ -2675,24 +2594,16 @@
ath10k_do_pci_sleep(ar);
- ret = ath10k_pci_alloc_ce(ar);
- if (ret) {
- ath10k_err("failed to allocate copy engine pipes: %d\n", ret);
- goto err_iomap;
- }
-
ath10k_dbg(ATH10K_DBG_BOOT, "boot pci_mem 0x%p\n", ar_pci->mem);
ret = ath10k_core_register(ar, chip_id);
if (ret) {
ath10k_err("failed to register driver core: %d\n", ret);
- goto err_free_ce;
+ goto err_iomap;
}
return 0;
-err_free_ce:
- ath10k_pci_free_ce(ar);
err_iomap:
pci_iounmap(pdev, mem);
err_master:
@@ -2715,7 +2626,7 @@
struct ath10k *ar = pci_get_drvdata(pdev);
struct ath10k_pci *ar_pci;
- ath10k_dbg(ATH10K_DBG_PCI, "pci remove\n");
+ ath10k_dbg(ATH10K_DBG_PCI, "%s\n", __func__);
if (!ar)
return;
@@ -2728,7 +2639,6 @@
tasklet_kill(&ar_pci->msi_fw_err);
ath10k_core_unregister(ar);
- ath10k_pci_free_ce(ar);
pci_iounmap(pdev, ar_pci->mem);
pci_release_region(pdev, BAR_NUM);
@@ -2770,5 +2680,6 @@
MODULE_AUTHOR("Qualcomm Atheros");
MODULE_DESCRIPTION("Driver support for Atheros QCA988X PCIe devices");
MODULE_LICENSE("Dual BSD/GPL");
-MODULE_FIRMWARE(QCA988X_HW_2_0_FW_DIR "/" QCA988X_HW_2_0_FW_2_FILE);
+MODULE_FIRMWARE(QCA988X_HW_2_0_FW_DIR "/" QCA988X_HW_2_0_FW_FILE);
+MODULE_FIRMWARE(QCA988X_HW_2_0_FW_DIR "/" QCA988X_HW_2_0_OTP_FILE);
MODULE_FIRMWARE(QCA988X_HW_2_0_FW_DIR "/" QCA988X_HW_2_0_BOARD_DATA_FILE);
diff --git a/drivers/net/wireless/ath/ath10k/pci.h b/drivers/net/wireless/ath/ath10k/pci.h
index dfdebb4..b43fdb4 100644
--- a/drivers/net/wireless/ath/ath10k/pci.h
+++ b/drivers/net/wireless/ath/ath10k/pci.h
@@ -189,6 +189,9 @@
struct ath10k_hif_cb msg_callbacks_current;
+ /* Target address used to signal a pending firmware event */
+ u32 fw_indicator_address;
+
/* Copy Engine used for Diagnostic Accesses */
struct ath10k_ce_pipe *ce_diag;
diff --git a/drivers/net/wireless/ath/ath10k/txrx.c b/drivers/net/wireless/ath/ath10k/txrx.c
index 82669a7..0541dd9 100644
--- a/drivers/net/wireless/ath/ath10k/txrx.c
+++ b/drivers/net/wireless/ath/ath10k/txrx.c
@@ -100,6 +100,189 @@
wake_up(&htt->empty_tx_wq);
}
+static const u8 rx_legacy_rate_idx[] = {
+ 3, /* 0x00 - 11Mbps */
+ 2, /* 0x01 - 5.5Mbps */
+ 1, /* 0x02 - 2Mbps */
+ 0, /* 0x03 - 1Mbps */
+ 3, /* 0x04 - 11Mbps */
+ 2, /* 0x05 - 5.5Mbps */
+ 1, /* 0x06 - 2Mbps */
+ 0, /* 0x07 - 1Mbps */
+ 10, /* 0x08 - 48Mbps */
+ 8, /* 0x09 - 24Mbps */
+ 6, /* 0x0A - 12Mbps */
+ 4, /* 0x0B - 6Mbps */
+ 11, /* 0x0C - 54Mbps */
+ 9, /* 0x0D - 36Mbps */
+ 7, /* 0x0E - 18Mbps */
+ 5, /* 0x0F - 9Mbps */
+};
+
+static void process_rx_rates(struct ath10k *ar, struct htt_rx_info *info,
+ enum ieee80211_band band,
+ struct ieee80211_rx_status *status)
+{
+ u8 cck, rate, rate_idx, bw, sgi, mcs, nss;
+ u8 info0 = info->rate.info0;
+ u32 info1 = info->rate.info1;
+ u32 info2 = info->rate.info2;
+ u8 preamble = 0;
+
+ /* Check if valid fields */
+ if (!(info0 & HTT_RX_INDICATION_INFO0_START_VALID))
+ return;
+
+ preamble = MS(info1, HTT_RX_INDICATION_INFO1_PREAMBLE_TYPE);
+
+ switch (preamble) {
+ case HTT_RX_LEGACY:
+ cck = info0 & HTT_RX_INDICATION_INFO0_LEGACY_RATE_CCK;
+ rate = MS(info0, HTT_RX_INDICATION_INFO0_LEGACY_RATE);
+ rate_idx = 0;
+
+ if (rate < 0x08 || rate > 0x0F)
+ break;
+
+ switch (band) {
+ case IEEE80211_BAND_2GHZ:
+ if (cck)
+ rate &= ~BIT(3);
+ rate_idx = rx_legacy_rate_idx[rate];
+ break;
+ case IEEE80211_BAND_5GHZ:
+ rate_idx = rx_legacy_rate_idx[rate];
+ /* We are using same rate table registering
+ HW - ath10k_rates[]. In case of 5GHz skip
+ CCK rates, so -4 here */
+ rate_idx -= 4;
+ break;
+ default:
+ break;
+ }
+
+ status->rate_idx = rate_idx;
+ break;
+ case HTT_RX_HT:
+ case HTT_RX_HT_WITH_TXBF:
+ /* HT-SIG - Table 20-11 in info1 and info2 */
+ mcs = info1 & 0x1F;
+ nss = mcs >> 3;
+ bw = (info1 >> 7) & 1;
+ sgi = (info2 >> 7) & 1;
+
+ status->rate_idx = mcs;
+ status->flag |= RX_FLAG_HT;
+ if (sgi)
+ status->flag |= RX_FLAG_SHORT_GI;
+ if (bw)
+ status->flag |= RX_FLAG_40MHZ;
+ break;
+ case HTT_RX_VHT:
+ case HTT_RX_VHT_WITH_TXBF:
+ /* VHT-SIG-A1 in info 1, VHT-SIG-A2 in info2
+ TODO check this */
+ mcs = (info2 >> 4) & 0x0F;
+ nss = ((info1 >> 10) & 0x07) + 1;
+ bw = info1 & 3;
+ sgi = info2 & 1;
+
+ status->rate_idx = mcs;
+ status->vht_nss = nss;
+
+ if (sgi)
+ status->flag |= RX_FLAG_SHORT_GI;
+
+ switch (bw) {
+ /* 20MHZ */
+ case 0:
+ break;
+ /* 40MHZ */
+ case 1:
+ status->flag |= RX_FLAG_40MHZ;
+ break;
+ /* 80MHZ */
+ case 2:
+ status->vht_flag |= RX_VHT_FLAG_80MHZ;
+ }
+
+ status->flag |= RX_FLAG_VHT;
+ break;
+ default:
+ break;
+ }
+}
+
+void ath10k_process_rx(struct ath10k *ar, struct htt_rx_info *info)
+{
+ struct ieee80211_rx_status *status;
+ struct ieee80211_channel *ch;
+ struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)info->skb->data;
+
+ status = IEEE80211_SKB_RXCB(info->skb);
+ memset(status, 0, sizeof(*status));
+
+ if (info->encrypt_type != HTT_RX_MPDU_ENCRYPT_NONE) {
+ status->flag |= RX_FLAG_DECRYPTED | RX_FLAG_IV_STRIPPED |
+ RX_FLAG_MMIC_STRIPPED;
+ hdr->frame_control = __cpu_to_le16(
+ __le16_to_cpu(hdr->frame_control) &
+ ~IEEE80211_FCTL_PROTECTED);
+ }
+
+ if (info->mic_err)
+ status->flag |= RX_FLAG_MMIC_ERROR;
+
+ if (info->fcs_err)
+ status->flag |= RX_FLAG_FAILED_FCS_CRC;
+
+ if (info->amsdu_more)
+ status->flag |= RX_FLAG_AMSDU_MORE;
+
+ status->signal = info->signal;
+
+ spin_lock_bh(&ar->data_lock);
+ ch = ar->scan_channel;
+ if (!ch)
+ ch = ar->rx_channel;
+ spin_unlock_bh(&ar->data_lock);
+
+ if (!ch) {
+ ath10k_warn("no channel configured; ignoring frame!\n");
+ dev_kfree_skb_any(info->skb);
+ return;
+ }
+
+ process_rx_rates(ar, info, ch->band, status);
+ status->band = ch->band;
+ status->freq = ch->center_freq;
+
+ if (info->rate.info0 & HTT_RX_INDICATION_INFO0_END_VALID) {
+ /* TSF available only in 32-bit */
+ status->mactime = info->tsf & 0xffffffff;
+ status->flag |= RX_FLAG_MACTIME_END;
+ }
+
+ ath10k_dbg(ATH10K_DBG_DATA,
+ "rx skb %p len %u %s%s%s%s%s %srate_idx %u vht_nss %u freq %u band %u flag 0x%x fcs-err %i\n",
+ info->skb,
+ info->skb->len,
+ status->flag == 0 ? "legacy" : "",
+ status->flag & RX_FLAG_HT ? "ht" : "",
+ status->flag & RX_FLAG_VHT ? "vht" : "",
+ status->flag & RX_FLAG_40MHZ ? "40" : "",
+ status->vht_flag & RX_VHT_FLAG_80MHZ ? "80" : "",
+ status->flag & RX_FLAG_SHORT_GI ? "sgi " : "",
+ status->rate_idx,
+ status->vht_nss,
+ status->freq,
+ status->band, status->flag, info->fcs_err);
+ ath10k_dbg_dump(ATH10K_DBG_HTT_DUMP, NULL, "rx skb: ",
+ info->skb->data, info->skb->len);
+
+ ieee80211_rx(ar->hw, info->skb);
+}
+
struct ath10k_peer *ath10k_peer_find(struct ath10k *ar, int vdev_id,
const u8 *addr)
{
diff --git a/drivers/net/wireless/ath/ath10k/txrx.h b/drivers/net/wireless/ath/ath10k/txrx.h
index aee3e20..356dc9c 100644
--- a/drivers/net/wireless/ath/ath10k/txrx.h
+++ b/drivers/net/wireless/ath/ath10k/txrx.h
@@ -21,6 +21,7 @@
void ath10k_txrx_tx_unref(struct ath10k_htt *htt,
const struct htt_tx_done *tx_done);
+void ath10k_process_rx(struct ath10k *ar, struct htt_rx_info *info);
struct ath10k_peer *ath10k_peer_find(struct ath10k *ar, int vdev_id,
const u8 *addr);
diff --git a/drivers/net/wireless/ath/ath10k/wmi.c b/drivers/net/wireless/ath/ath10k/wmi.c
index 0a2d04c..beac30d 100644
--- a/drivers/net/wireless/ath/ath10k/wmi.c
+++ b/drivers/net/wireless/ath/ath10k/wmi.c
@@ -1362,10 +1362,13 @@
struct sk_buff *bcn;
int ret, vdev_id = 0;
+ ath10k_dbg(ATH10K_DBG_MGMT, "WMI_HOST_SWBA_EVENTID\n");
+
ev = (struct wmi_host_swba_event *)skb->data;
map = __le32_to_cpu(ev->vdev_map);
- ath10k_dbg(ATH10K_DBG_MGMT, "mgmt swba vdev_map 0x%x\n",
+ ath10k_dbg(ATH10K_DBG_MGMT, "host swba:\n"
+ "-vdev map 0x%x\n",
ev->vdev_map);
for (; map; map >>= 1, vdev_id++) {
@@ -1382,7 +1385,12 @@
bcn_info = &ev->bcn_info[i];
ath10k_dbg(ATH10K_DBG_MGMT,
- "mgmt event bcn_info %d tim_len %d mcast %d changed %d num_ps_pending %d bitmap 0x%08x%08x%08x%08x\n",
+ "-bcn_info[%d]:\n"
+ "--tim_len %d\n"
+ "--tim_mcast %d\n"
+ "--tim_changed %d\n"
+ "--tim_num_ps_pending %d\n"
+ "--tim_bitmap 0x%08x%08x%08x%08x\n",
i,
__le32_to_cpu(bcn_info->tim_info.tim_len),
__le32_to_cpu(bcn_info->tim_info.tim_mcast),
@@ -1431,7 +1439,6 @@
ATH10K_SKB_CB(arvif->beacon)->paddr,
arvif->beacon->len, DMA_TO_DEVICE);
dev_kfree_skb_any(arvif->beacon);
- arvif->beacon = NULL;
}
ATH10K_SKB_CB(bcn)->paddr = dma_map_single(arvif->ar->dev,
@@ -1441,7 +1448,6 @@
ATH10K_SKB_CB(bcn)->paddr);
if (ret) {
ath10k_warn("failed to map beacon: %d\n", ret);
- dev_kfree_skb_any(bcn);
goto skip;
}
@@ -2387,9 +2393,8 @@
return 0;
}
-static int ath10k_wmi_main_pdev_set_regdomain(struct ath10k *ar, u16 rd,
- u16 rd2g, u16 rd5g, u16 ctl2g,
- u16 ctl5g)
+int ath10k_wmi_pdev_set_regdomain(struct ath10k *ar, u16 rd, u16 rd2g,
+ u16 rd5g, u16 ctl2g, u16 ctl5g)
{
struct wmi_pdev_set_regdomain_cmd *cmd;
struct sk_buff *skb;
@@ -2413,46 +2418,6 @@
ar->wmi.cmd->pdev_set_regdomain_cmdid);
}
-static int ath10k_wmi_10x_pdev_set_regdomain(struct ath10k *ar, u16 rd,
- u16 rd2g, u16 rd5g,
- u16 ctl2g, u16 ctl5g,
- enum wmi_dfs_region dfs_reg)
-{
- struct wmi_pdev_set_regdomain_cmd_10x *cmd;
- struct sk_buff *skb;
-
- skb = ath10k_wmi_alloc_skb(sizeof(*cmd));
- if (!skb)
- return -ENOMEM;
-
- cmd = (struct wmi_pdev_set_regdomain_cmd_10x *)skb->data;
- cmd->reg_domain = __cpu_to_le32(rd);
- cmd->reg_domain_2G = __cpu_to_le32(rd2g);
- cmd->reg_domain_5G = __cpu_to_le32(rd5g);
- cmd->conformance_test_limit_2G = __cpu_to_le32(ctl2g);
- cmd->conformance_test_limit_5G = __cpu_to_le32(ctl5g);
- cmd->dfs_domain = __cpu_to_le32(dfs_reg);
-
- ath10k_dbg(ATH10K_DBG_WMI,
- "wmi pdev regdomain rd %x rd2g %x rd5g %x ctl2g %x ctl5g %x dfs_region %x\n",
- rd, rd2g, rd5g, ctl2g, ctl5g, dfs_reg);
-
- return ath10k_wmi_cmd_send(ar, skb,
- ar->wmi.cmd->pdev_set_regdomain_cmdid);
-}
-
-int ath10k_wmi_pdev_set_regdomain(struct ath10k *ar, u16 rd, u16 rd2g,
- u16 rd5g, u16 ctl2g, u16 ctl5g,
- enum wmi_dfs_region dfs_reg)
-{
- if (test_bit(ATH10K_FW_FEATURE_WMI_10X, ar->fw_features))
- return ath10k_wmi_10x_pdev_set_regdomain(ar, rd, rd2g, rd5g,
- ctl2g, ctl5g, dfs_reg);
- else
- return ath10k_wmi_main_pdev_set_regdomain(ar, rd, rd2g, rd5g,
- ctl2g, ctl5g);
-}
-
int ath10k_wmi_pdev_set_channel(struct ath10k *ar,
const struct wmi_channel_arg *arg)
{
@@ -3491,9 +3456,8 @@
__cpu_to_le32(arg->peer_vht_rates.tx_mcs_set);
ath10k_dbg(ATH10K_DBG_WMI,
- "wmi peer assoc vdev %d addr %pM (%s)\n",
- arg->vdev_id, arg->addr,
- arg->peer_reassoc ? "reassociate" : "new");
+ "wmi peer assoc vdev %d addr %pM\n",
+ arg->vdev_id, arg->addr);
return ath10k_wmi_cmd_send(ar, skb, ar->wmi.cmd->peer_assoc_cmdid);
}
diff --git a/drivers/net/wireless/ath/ath10k/wmi.h b/drivers/net/wireless/ath/ath10k/wmi.h
index ae83822..4fcc96a 100644
--- a/drivers/net/wireless/ath/ath10k/wmi.h
+++ b/drivers/net/wireless/ath/ath10k/wmi.h
@@ -198,6 +198,16 @@
} __packed;
} __packed;
+/* macro to convert MAC address from WMI word format to char array */
+#define WMI_MAC_ADDR_TO_CHAR_ARRAY(pwmi_mac_addr, c_macaddr) do { \
+ (c_macaddr)[0] = ((pwmi_mac_addr)->word0) & 0xff; \
+ (c_macaddr)[1] = (((pwmi_mac_addr)->word0) >> 8) & 0xff; \
+ (c_macaddr)[2] = (((pwmi_mac_addr)->word0) >> 16) & 0xff; \
+ (c_macaddr)[3] = (((pwmi_mac_addr)->word0) >> 24) & 0xff; \
+ (c_macaddr)[4] = ((pwmi_mac_addr)->word1) & 0xff; \
+ (c_macaddr)[5] = (((pwmi_mac_addr)->word1) >> 8) & 0xff; \
+ } while (0)
+
struct wmi_cmd_map {
u32 init_cmdid;
u32 start_scan_cmdid;
@@ -2175,31 +2185,6 @@
__le32 conformance_test_limit_5G;
} __packed;
-enum wmi_dfs_region {
- /* Uninitialized dfs domain */
- WMI_UNINIT_DFS_DOMAIN = 0,
-
- /* FCC3 dfs domain */
- WMI_FCC_DFS_DOMAIN = 1,
-
- /* ETSI dfs domain */
- WMI_ETSI_DFS_DOMAIN = 2,
-
- /*Japan dfs domain */
- WMI_MKK4_DFS_DOMAIN = 3,
-};
-
-struct wmi_pdev_set_regdomain_cmd_10x {
- __le32 reg_domain;
- __le32 reg_domain_2G;
- __le32 reg_domain_5G;
- __le32 conformance_test_limit_2G;
- __le32 conformance_test_limit_5G;
-
- /* dfs domain from wmi_dfs_region */
- __le32 dfs_domain;
-} __packed;
-
/* Command to set/unset chip in quiet mode */
struct wmi_pdev_set_quiet_cmd {
/* period in TUs */
@@ -2225,19 +2210,6 @@
ATH10K_PROT_RTSCTS = 2, /* RTS-CTS */
};
-enum wmi_rtscts_profile {
- WMI_RTSCTS_FOR_NO_RATESERIES = 0,
- WMI_RTSCTS_FOR_SECOND_RATESERIES,
- WMI_RTSCTS_ACROSS_SW_RETRIES
-};
-
-#define WMI_RTSCTS_ENABLED 1
-#define WMI_RTSCTS_SET_MASK 0x0f
-#define WMI_RTSCTS_SET_LSB 0
-
-#define WMI_RTSCTS_PROFILE_MASK 0xf0
-#define WMI_RTSCTS_PROFILE_LSB 4
-
enum wmi_beacon_gen_mode {
WMI_BEACON_STAGGERED_MODE = 0,
WMI_BEACON_BURST_MODE = 1
@@ -2710,9 +2682,6 @@
/* wal pdev resets */
__le32 pdev_resets;
- /* frames dropped due to non-availability of stateless TIDs */
- __le32 stateless_tid_alloc_failure;
-
__le32 phy_underrun;
/* MPDU is more than txop limit */
@@ -2769,21 +2738,13 @@
WMI_REQUEST_AP_STAT = 0x02
};
-struct wlan_inst_rssi_args {
- __le16 cfg_retry_count;
- __le16 retry_count;
-};
-
struct wmi_request_stats_cmd {
__le32 stats_id;
- __le32 vdev_id;
-
- /* peer MAC address */
- struct wmi_mac_addr peer_macaddr;
-
- /* Instantaneous RSSI arguments */
- struct wlan_inst_rssi_args inst_rssi_args;
+ /*
+ * Space to add parameters like
+ * peer mac addr
+ */
} __packed;
/* Suspend option */
@@ -2834,7 +2795,7 @@
* PDEV statistics
* TODO: add all PDEV stats here
*/
-struct wmi_pdev_stats_old {
+struct wmi_pdev_stats {
__le32 chan_nf; /* Channel noise floor */
__le32 tx_frame_count; /* TX frame count */
__le32 rx_frame_count; /* RX frame count */
@@ -2845,23 +2806,6 @@
struct wal_dbg_stats wal; /* WAL dbg stats */
} __packed;
-struct wmi_pdev_stats_10x {
- __le32 chan_nf; /* Channel noise floor */
- __le32 tx_frame_count; /* TX frame count */
- __le32 rx_frame_count; /* RX frame count */
- __le32 rx_clear_count; /* rx clear count */
- __le32 cycle_count; /* cycle count */
- __le32 phy_err_count; /* Phy error count */
- __le32 chan_tx_pwr; /* channel tx power */
- struct wal_dbg_stats wal; /* WAL dbg stats */
- __le32 ack_rx_bad;
- __le32 rts_bad;
- __le32 rts_good;
- __le32 fcs_bad;
- __le32 no_beacons;
- __le32 mib_int_count;
-} __packed;
-
/*
* VDEV statistics
* TODO: add all VDEV stats here
@@ -2874,19 +2818,12 @@
* peer statistics.
* TODO: add more stats
*/
-struct wmi_peer_stats_old {
+struct wmi_peer_stats {
struct wmi_mac_addr peer_macaddr;
__le32 peer_rssi;
__le32 peer_tx_rate;
} __packed;
-struct wmi_peer_stats_10x {
- struct wmi_mac_addr peer_macaddr;
- __le32 peer_rssi;
- __le32 peer_tx_rate;
- __le32 peer_rx_rate;
-} __packed;
-
struct wmi_vdev_create_cmd {
__le32 vdev_id;
__le32 vdev_type;
@@ -4265,8 +4202,7 @@
int ath10k_wmi_pdev_suspend_target(struct ath10k *ar, u32 suspend_opt);
int ath10k_wmi_pdev_resume_target(struct ath10k *ar);
int ath10k_wmi_pdev_set_regdomain(struct ath10k *ar, u16 rd, u16 rd2g,
- u16 rd5g, u16 ctl2g, u16 ctl5g,
- enum wmi_dfs_region dfs_reg);
+ u16 rd5g, u16 ctl2g, u16 ctl5g);
int ath10k_wmi_pdev_set_param(struct ath10k *ar, u32 id, u32 value);
int ath10k_wmi_cmd_init(struct ath10k *ar);
int ath10k_wmi_start_scan(struct ath10k *ar, const struct wmi_start_scan_arg *);
diff --git a/drivers/net/wireless/ath/ath6kl/Kconfig b/drivers/net/wireless/ath/ath6kl/Kconfig
index b8a1f9d..9bbe593 100644
--- a/drivers/net/wireless/ath/ath6kl/Kconfig
+++ b/drivers/net/wireless/ath/ath6kl/Kconfig
@@ -1,21 +1,13 @@
config ATH6KL
tristate "Atheros mobile chipsets support"
depends on m
- depends on CFG80211
- ---help---
- This module adds core support for wireless adapters based on
- Atheros AR6003 and AR6004 chipsets. You still need separate
- bus drivers for USB and SDIO to be able to use real devices.
-
- If you choose to build it as a module, it will be called
- ath6kl_core. Please note that AR6002 and AR6001 are not
- supported by this driver.
config ATH6KL_SDIO
tristate "Atheros ath6kl SDIO support"
depends on m
depends on ATH6KL
depends on MMC
+ depends on CFG80211
---help---
This module adds support for wireless adapters based on
Atheros AR6003 and AR6004 chipsets running over SDIO. If you
@@ -28,31 +20,25 @@
depends on m
depends on ATH6KL
depends on USB
+ depends on CFG80211
---help---
This module adds support for wireless adapters based on
- Atheros AR6004 chipset and chipsets based on it running over
- USB. If you choose to build it as a module, it will be
- called ath6kl_usb.
+ Atheros AR6004 chipset running over USB. This is still under
+ implementation and it isn't functional. If you choose to
+ build it as a module, it will be called ath6kl_usb.
config ATH6KL_DEBUG
bool "Atheros ath6kl debugging"
depends on ATH6KL
---help---
- Enables ath6kl debug support, including debug messages
- enabled with debug_mask module parameter and debugfs
- interface.
-
- If unsure, say Y to make it easier to debug problems.
+ Enables debug support
config ATH6KL_TRACING
bool "Atheros ath6kl tracing support"
depends on ATH6KL
depends on EVENT_TRACING
---help---
- Select this to ath6kl use tracing infrastructure which, for
- example, can be enabled with help of trace-cmd. All debug
- messages and commands are delivered to using individually
- enablable trace points.
+ Select this to ath6kl use tracing infrastructure.
If unsure, say Y to make it easier to debug problems.
@@ -64,5 +50,3 @@
Enabling this makes it possible to change the regdomain in
the firmware. This can be only enabled if regulatory requirements
are taken into account.
-
- If unsure, say N.
diff --git a/drivers/net/wireless/ath/ath6kl/cfg80211.c b/drivers/net/wireless/ath/ath6kl/cfg80211.c
index d9316da..9b2f884 100644
--- a/drivers/net/wireless/ath/ath6kl/cfg80211.c
+++ b/drivers/net/wireless/ath/ath6kl/cfg80211.c
@@ -724,9 +724,8 @@
ath6kl_dbg(ATH6KL_DBG_WLAN_CFG,
"added bss %pM to cfg80211\n", bssid);
kfree(ie);
- } else {
+ } else
ath6kl_dbg(ATH6KL_DBG_WLAN_CFG, "cfg80211 already has a bss\n");
- }
return bss;
}
@@ -971,6 +970,7 @@
ssid_list[i].flag,
ssid_list[i].ssid.ssid_len,
ssid_list[i].ssid.ssid);
+
}
/* Make sure no old entries are left behind */
@@ -1897,6 +1897,7 @@
/* Configure the patterns that we received from the user. */
for (i = 0; i < wow->n_patterns; i++) {
+
/*
* Convert given nl80211 specific mask value to equivalent
* driver specific mask value and send it to the chip along
@@ -2849,9 +2850,8 @@
if (p.prwise_crypto_type == 0) {
p.prwise_crypto_type = NONE_CRYPT;
ath6kl_set_cipher(vif, 0, true);
- } else if (info->crypto.n_ciphers_pairwise == 1) {
+ } else if (info->crypto.n_ciphers_pairwise == 1)
ath6kl_set_cipher(vif, info->crypto.ciphers_pairwise[0], true);
- }
switch (info->crypto.cipher_group) {
case WLAN_CIPHER_SUITE_WEP40:
@@ -2897,6 +2897,7 @@
}
if (info->inactivity_timeout) {
+
inactivity_timeout = info->inactivity_timeout;
if (ar->hw.flags & ATH6KL_HW_AP_INACTIVITY_MINS)
diff --git a/drivers/net/wireless/ath/ath6kl/core.c b/drivers/net/wireless/ath/ath6kl/core.c
index b0b6520..4b46adb 100644
--- a/drivers/net/wireless/ath/ath6kl/core.c
+++ b/drivers/net/wireless/ath/ath6kl/core.c
@@ -45,9 +45,9 @@
module_param(recovery_enable, uint, 0644);
module_param(heart_beat_poll, uint, 0644);
MODULE_PARM_DESC(recovery_enable, "Enable recovery from firmware error");
-MODULE_PARM_DESC(heart_beat_poll,
- "Enable fw error detection periodic polling in msecs - Also set recovery_enable for this to be effective");
-
+MODULE_PARM_DESC(heart_beat_poll, "Enable fw error detection periodic" \
+ "polling. This also specifies the polling interval in" \
+ "msecs. Set reocvery_enable for this to be effective");
void ath6kl_core_tx_complete(struct ath6kl *ar, struct sk_buff *skb)
{
diff --git a/drivers/net/wireless/ath/ath6kl/debug.c b/drivers/net/wireless/ath/ath6kl/debug.c
index f596535..986d61f 100644
--- a/drivers/net/wireless/ath/ath6kl/debug.c
+++ b/drivers/net/wireless/ath/ath6kl/debug.c
@@ -172,6 +172,7 @@
struct ath6kl_irq_proc_registers *irq_proc_reg,
struct ath6kl_irq_enable_reg *irq_enable_reg)
{
+
ath6kl_dbg(ATH6KL_DBG_IRQ, ("<------- Register Table -------->\n"));
if (irq_proc_reg != NULL) {
@@ -218,6 +219,7 @@
"GMBOX lookahead alias 1: 0x%x\n",
irq_proc_reg->rx_gmbox_lkahd_alias[1]);
}
+
}
if (irq_enable_reg != NULL) {
@@ -1394,6 +1396,7 @@
const char __user *user_buf,
size_t count, loff_t *ppos)
{
+
struct ath6kl *ar = file->private_data;
struct ath6kl_vif *vif;
char buf[200];
@@ -1572,6 +1575,7 @@
const char __user *user_buf,
size_t count, loff_t *ppos)
{
+
struct ath6kl *ar = file->private_data;
struct ath6kl_vif *vif;
char buf[100];
diff --git a/drivers/net/wireless/ath/ath6kl/debug.h b/drivers/net/wireless/ath/ath6kl/debug.h
index 01debd4..6a3b64a 100644
--- a/drivers/net/wireless/ath/ath6kl/debug.h
+++ b/drivers/net/wireless/ath/ath6kl/debug.h
@@ -97,8 +97,8 @@
struct ath6kl_irq_proc_registers *irq_proc_reg,
struct ath6kl_irq_enable_reg *irq_en_reg)
{
-}
+}
static inline void dump_cred_dist_stats(struct htc_target *target)
{
}
diff --git a/drivers/net/wireless/ath/ath6kl/hif.c b/drivers/net/wireless/ath/ath6kl/hif.c
index 18c0708..fea7709 100644
--- a/drivers/net/wireless/ath/ath6kl/hif.c
+++ b/drivers/net/wireless/ath/ath6kl/hif.c
@@ -37,6 +37,7 @@
buf = req->virt_dma_buf;
for (i = 0; i < req->scat_entries; i++) {
+
if (from_dma)
memcpy(req->scat_list[i].buf, buf,
req->scat_list[i].len);
@@ -115,6 +116,7 @@
le32_to_cpu(regdump_val[i + 2]),
le32_to_cpu(regdump_val[i + 3]));
}
+
}
static int ath6kl_hif_proc_dbg_intr(struct ath6kl_device *dev)
@@ -699,4 +701,5 @@
fail_setup:
return status;
+
}
diff --git a/drivers/net/wireless/ath/ath6kl/hif.h b/drivers/net/wireless/ath/ath6kl/hif.h
index dc6bd8c..61f6b21 100644
--- a/drivers/net/wireless/ath/ath6kl/hif.h
+++ b/drivers/net/wireless/ath/ath6kl/hif.h
@@ -197,9 +197,9 @@
/* bounce buffer for upper layers to copy to/from */
u8 *virt_dma_buf;
- u32 scat_q_depth;
+ struct hif_scatter_item scat_list[1];
- struct hif_scatter_item scat_list[0];
+ u32 scat_q_depth;
};
struct ath6kl_irq_proc_registers {
diff --git a/drivers/net/wireless/ath/ath6kl/htc_mbox.c b/drivers/net/wireless/ath/ath6kl/htc_mbox.c
index e481f14..65e5b71 100644
--- a/drivers/net/wireless/ath/ath6kl/htc_mbox.c
+++ b/drivers/net/wireless/ath/ath6kl/htc_mbox.c
@@ -112,9 +112,9 @@
if (cur_ep_dist->endpoint == ENDPOINT_0)
continue;
- if (cur_ep_dist->svc_id == WMI_CONTROL_SVC) {
+ if (cur_ep_dist->svc_id == WMI_CONTROL_SVC)
cur_ep_dist->cred_norm = cur_ep_dist->cred_per_msg;
- } else {
+ else {
/*
* For the remaining data endpoints, we assume that
* each cred_per_msg are the same. We use a simple
@@ -129,6 +129,7 @@
count = (count * 3) >> 2;
count = max(count, cur_ep_dist->cred_per_msg);
cur_ep_dist->cred_norm = count;
+
}
ath6kl_dbg(ATH6KL_DBG_CREDIT,
@@ -548,6 +549,7 @@
enum htc_endpoint_id eid, unsigned int len,
int *req_cred)
{
+
*req_cred = (len > target->tgt_cred_sz) ?
DIV_ROUND_UP(len, target->tgt_cred_sz) : 1;
@@ -606,6 +608,7 @@
unsigned int len;
while (true) {
+
flags = 0;
if (list_empty(&endpoint->txq))
@@ -886,6 +889,7 @@
ac = target->dev->ar->ep2ac_map[endpoint->eid];
while (true) {
+
if (list_empty(&endpoint->txq))
break;
@@ -1186,6 +1190,7 @@
list_add_tail(&packet->list, &container);
htc_tx_complete(endpoint, &container);
}
+
}
static void ath6kl_htc_flush_txep_all(struct htc_target *target)
@@ -1389,6 +1394,7 @@
ep_cb = ep->ep_cb;
for (j = 0; j < n_msg; j++) {
+
/*
* Reset flag, any packets allocated using the
* rx_alloc() API cannot be recycled on
@@ -1418,9 +1424,9 @@
}
}
- if (list_empty(&ep->rx_bufq)) {
+ if (list_empty(&ep->rx_bufq))
packet = NULL;
- } else {
+ else {
packet = list_first_entry(&ep->rx_bufq,
struct htc_packet, list);
list_del(&packet->list);
@@ -1481,6 +1487,7 @@
spin_lock_bh(&target->rx_lock);
for (i = 0; i < msg; i++) {
+
htc_hdr = (struct htc_frame_hdr *)&lk_ahds[i];
if (htc_hdr->eid >= ENDPOINT_MAX) {
@@ -1701,6 +1708,7 @@
lk_ahd = (struct htc_lookahead_report *) record_buf;
if ((lk_ahd->pre_valid == ((~lk_ahd->post_valid) & 0xFF)) &&
next_lk_ahds) {
+
ath6kl_dbg(ATH6KL_DBG_HTC,
"htc rx lk_ahd found pre_valid 0x%x post_valid 0x%x\n",
lk_ahd->pre_valid, lk_ahd->post_valid);
@@ -1747,6 +1755,7 @@
}
return 0;
+
}
static int htc_proc_trailer(struct htc_target *target,
@@ -1767,6 +1776,7 @@
status = 0;
while (len > 0) {
+
if (len < sizeof(struct htc_record_hdr)) {
status = -ENOMEM;
break;
@@ -2088,6 +2098,7 @@
}
if (!fetched_pkts) {
+
packet = list_first_entry(rx_pktq, struct htc_packet,
list);
@@ -2162,6 +2173,7 @@
look_aheads[0] = msg_look_ahead;
while (true) {
+
/*
* First lookahead sets the expected endpoint IDs for all
* packets in a bundle.
@@ -2813,9 +2825,8 @@
packet->buf = packet->buf_start;
packet->endpoint = ENDPOINT_0;
list_add_tail(&packet->list, &target->free_ctrl_rxbuf);
- } else {
+ } else
list_add_tail(&packet->list, &target->free_ctrl_txbuf);
- }
}
return 0;
diff --git a/drivers/net/wireless/ath/ath6kl/htc_pipe.c b/drivers/net/wireless/ath/ath6kl/htc_pipe.c
index 756fe52..67aa924 100644
--- a/drivers/net/wireless/ath/ath6kl/htc_pipe.c
+++ b/drivers/net/wireless/ath/ath6kl/htc_pipe.c
@@ -137,6 +137,7 @@
credits_required = 0;
} else {
+
if (ep->cred_dist.credits < credits_required)
break;
@@ -168,6 +169,7 @@
/* queue this packet into the caller's queue */
list_add_tail(&packet->list, queue);
}
+
}
static void get_htc_packet(struct htc_target *target,
@@ -277,6 +279,7 @@
list_add(&packet->list, pkt_queue);
break;
}
+
}
if (status != 0) {
@@ -382,6 +385,7 @@
*/
list_for_each_entry_safe(packet, tmp_pkt,
txq, list) {
+
ath6kl_dbg(ATH6KL_DBG_HTC,
"%s: Indicat overflowed TX pkts: %p\n",
__func__, packet);
@@ -399,6 +403,7 @@
list_move_tail(&packet->list,
&send_queue);
}
+
}
if (list_empty(&send_queue)) {
@@ -449,6 +454,7 @@
* enough transmit resources.
*/
while (true) {
+
if (get_queue_depth(&ep->txq) == 0)
break;
@@ -489,8 +495,8 @@
}
spin_lock_bh(&target->tx_lock);
- }
+ }
/* done with this endpoint, we can clear the count */
ep->tx_proc_cnt = 0;
spin_unlock_bh(&target->tx_lock);
@@ -1100,6 +1106,7 @@
dev_kfree_skb(skb);
return status;
+
}
static void htc_flush_rx_queue(struct htc_target *target,
@@ -1251,6 +1258,7 @@
tx_alloc = 0;
} else {
+
tx_alloc = htc_get_credit_alloc(target, conn_req->svc_id);
if (tx_alloc == 0) {
status = -ENOMEM;
diff --git a/drivers/net/wireless/ath/ath6kl/init.c b/drivers/net/wireless/ath/ath6kl/init.c
index d5ef211..4f316bd 100644
--- a/drivers/net/wireless/ath/ath6kl/init.c
+++ b/drivers/net/wireless/ath/ath6kl/init.c
@@ -1192,6 +1192,7 @@
if (board_ext_address &&
ar->fw_board_len == (board_data_size + board_ext_data_size)) {
+
/* write extended board data */
ath6kl_dbg(ATH6KL_DBG_BOOT,
"writing extended board data to 0x%x (%d B)\n",
diff --git a/drivers/net/wireless/ath/ath6kl/main.c b/drivers/net/wireless/ath/ath6kl/main.c
index d565546..5839fc2 100644
--- a/drivers/net/wireless/ath/ath6kl/main.c
+++ b/drivers/net/wireless/ath/ath6kl/main.c
@@ -571,6 +571,7 @@
static int ath6kl_commit_ch_switch(struct ath6kl_vif *vif, u16 channel)
{
+
struct ath6kl *ar = vif->ar;
vif->profile.ch = cpu_to_le16(channel);
@@ -599,6 +600,7 @@
static void ath6kl_check_ch_switch(struct ath6kl *ar, u16 channel)
{
+
struct ath6kl_vif *vif;
int res = 0;
@@ -690,9 +692,9 @@
cfg80211_michael_mic_failure(vif->ndev, sta->mac,
NL80211_KEYTYPE_PAIRWISE, keyid,
tsc, GFP_KERNEL);
- } else {
+ } else
ath6kl_cfg80211_tkip_micerr_event(vif, keyid, ismcast);
- }
+
}
static void ath6kl_update_target_stats(struct ath6kl_vif *vif, u8 *ptr, u32 len)
@@ -1091,9 +1093,8 @@
if (test_bit(CONNECTED, &vif->flags)) {
netif_carrier_on(dev);
netif_wake_queue(dev);
- } else {
+ } else
netif_carrier_off(dev);
- }
return 0;
}
@@ -1145,6 +1146,7 @@
dev->features = features | NETIF_F_RXCSUM;
return err;
}
+
}
return err;
diff --git a/drivers/net/wireless/ath/ath6kl/sdio.c b/drivers/net/wireless/ath/ath6kl/sdio.c
index 339d89f..7126bdd 100644
--- a/drivers/net/wireless/ath/ath6kl/sdio.c
+++ b/drivers/net/wireless/ath/ath6kl/sdio.c
@@ -348,7 +348,7 @@
int i, scat_req_sz, scat_list_sz, size;
u8 *virt_buf;
- scat_list_sz = n_scat_entry * sizeof(struct hif_scatter_item);
+ scat_list_sz = (n_scat_entry - 1) * sizeof(struct hif_scatter_item);
scat_req_sz = sizeof(*s_req) + scat_list_sz;
if (!virt_scat)
@@ -425,9 +425,8 @@
memcpy(tbuf, buf, len);
bounced = true;
- } else {
+ } else
tbuf = buf;
- }
ret = ath6kl_sdio_io(ar_sdio->func, request, addr, tbuf, len);
if ((request & HIF_READ) && bounced)
@@ -442,9 +441,9 @@
static void __ath6kl_sdio_write_async(struct ath6kl_sdio *ar_sdio,
struct bus_request *req)
{
- if (req->scat_req) {
+ if (req->scat_req)
ath6kl_sdio_scat_rw(ar_sdio, req);
- } else {
+ else {
void *context;
int status;
@@ -657,6 +656,7 @@
list_add_tail(&s_req->list, &ar_sdio->scat_req);
spin_unlock_bh(&ar_sdio->scat_lock);
+
}
/* scatter gather read write request */
@@ -674,9 +674,9 @@
"hif-scatter: total len: %d scatter entries: %d\n",
scat_req->len, scat_req->scat_entries);
- if (request & HIF_SYNCHRONOUS) {
+ if (request & HIF_SYNCHRONOUS)
status = ath6kl_sdio_scat_rw(ar_sdio, scat_req->busrequest);
- } else {
+ else {
spin_lock_bh(&ar_sdio->wr_async_lock);
list_add_tail(&scat_req->busrequest->list, &ar_sdio->wr_asyncq);
spin_unlock_bh(&ar_sdio->wr_async_lock);
@@ -856,6 +856,7 @@
if (ar->suspend_mode == WLAN_POWER_STATE_WOW ||
(!ar->suspend_mode && wow)) {
+
ret = ath6kl_set_sdio_pm_caps(ar);
if (ret)
goto cut_pwr;
@@ -877,6 +878,7 @@
if (ar->suspend_mode == WLAN_POWER_STATE_DEEP_SLEEP ||
!ar->suspend_mode || try_deepsleep) {
+
flags = sdio_get_host_pm_caps(func);
if (!(flags & MMC_PM_KEEP_POWER))
goto cut_pwr;
@@ -1059,6 +1061,7 @@
timeout = jiffies + msecs_to_jiffies(BMI_COMMUNICATION_TIMEOUT);
while (time_before(jiffies, timeout) && !ar->bmi.cmd_credits) {
+
/*
* Hit the credit counter with a 4-byte access, the first byte
* read will hit the counter and cause a decrement, while the
diff --git a/drivers/net/wireless/ath/ath6kl/target.h b/drivers/net/wireless/ath/ath6kl/target.h
index d5eeeae..a580a62 100644
--- a/drivers/net/wireless/ath/ath6kl/target.h
+++ b/drivers/net/wireless/ath/ath6kl/target.h
@@ -289,7 +289,7 @@
u32 hi_hp_rx_traffic_ratio; /* 0xd8 */
/* test applications flags */
- u32 hi_test_apps_related; /* 0xdc */
+ u32 hi_test_apps_related ; /* 0xdc */
/* location of test script */
u32 hi_ota_testscript; /* 0xe0 */
/* location of CAL data */
diff --git a/drivers/net/wireless/ath/ath6kl/txrx.c b/drivers/net/wireless/ath/ath6kl/txrx.c
index 40432fe..ebb2404 100644
--- a/drivers/net/wireless/ath/ath6kl/txrx.c
+++ b/drivers/net/wireless/ath/ath6kl/txrx.c
@@ -125,9 +125,8 @@
*flags |= WMI_DATA_HDR_FLAGS_UAPSD;
spin_unlock_bh(&conn->psq_lock);
return false;
- } else if (!conn->apsd_info) {
+ } else if (!conn->apsd_info)
return false;
- }
if (test_bit(WMM_ENABLED, &vif->flags)) {
ether_type = be16_to_cpu(datap->h_proto);
@@ -317,9 +316,8 @@
cookie = NULL;
ath6kl_err("wmi ctrl ep full, dropping pkt : 0x%p, len:%d\n",
skb, skb->len);
- } else {
+ } else
cookie = ath6kl_alloc_cookie(ar);
- }
if (cookie == NULL) {
spin_unlock_bh(&ar->lock);
@@ -361,7 +359,7 @@
struct ath6kl_vif *vif = netdev_priv(dev);
u32 map_no = 0;
u16 htc_tag = ATH6KL_DATA_PKT_TAG;
- u8 ac = 99; /* initialize to unmapped ac */
+ u8 ac = 99 ; /* initialize to unmapped ac */
bool chk_adhoc_ps_mapping = false;
int ret;
struct wmi_tx_meta_v2 meta_v2;
@@ -451,9 +449,8 @@
if (ret)
goto fail_tx;
}
- } else {
+ } else
goto fail_tx;
- }
spin_lock_bh(&ar->lock);
@@ -705,6 +702,7 @@
/* reap completed packets */
while (!list_empty(packet_queue)) {
+
packet = list_first_entry(packet_queue, struct htc_packet,
list);
list_del(&packet->list);
@@ -1091,9 +1089,8 @@
else
skb_queue_tail(&rxtid->q, node->skb);
node->skb = NULL;
- } else {
+ } else
stats->num_hole++;
- }
rxtid->seq_next = ATH6KL_NEXT_SEQ_NO(rxtid->seq_next);
idx = AGGR_WIN_IDX(rxtid->seq_next, rxtid->hold_q_sz);
@@ -1214,7 +1211,7 @@
return is_queued;
spin_lock_bh(&rxtid->lock);
- for (idx = 0; idx < rxtid->hold_q_sz; idx++) {
+ for (idx = 0 ; idx < rxtid->hold_q_sz; idx++) {
if (rxtid->hold_q[idx].skb) {
/*
* There is a frame in the queue and no
@@ -1268,6 +1265,7 @@
is_apsdq_empty_at_start = is_apsdq_empty;
while ((!is_apsdq_empty) && (num_frames_to_deliver)) {
+
spin_lock_bh(&conn->psq_lock);
skb = skb_dequeue(&conn->apsdq);
is_apsdq_empty = skb_queue_empty(&conn->apsdq);
@@ -1608,18 +1606,16 @@
if (!conn)
return;
aggr_conn = conn->aggr_conn;
- } else {
+ } else
aggr_conn = vif->aggr_cntxt->aggr_conn;
- }
if (aggr_process_recv_frm(aggr_conn, tid, seq_no,
is_amsdu, skb)) {
/* aggregation code will handle the skb */
return;
}
- } else if (!is_broadcast_ether_addr(datap->h_dest)) {
+ } else if (!is_broadcast_ether_addr(datap->h_dest))
vif->net_stats.multicast++;
- }
ath6kl_deliver_frames_to_nw_stack(vif->ndev, skb);
}
@@ -1714,9 +1710,8 @@
sta = ath6kl_find_sta_by_aid(vif->ar, aid);
if (sta)
aggr_conn = sta->aggr_conn;
- } else {
+ } else
aggr_conn = vif->aggr_cntxt->aggr_conn;
- }
if (!aggr_conn)
return;
@@ -1771,6 +1766,7 @@
skb_queue_head_init(&rxtid->q);
spin_lock_init(&rxtid->lock);
}
+
}
struct aggr_info *aggr_init(struct ath6kl_vif *vif)
@@ -1810,9 +1806,8 @@
sta = ath6kl_find_sta_by_aid(vif->ar, aid);
if (sta)
aggr_conn = sta->aggr_conn;
- } else {
+ } else
aggr_conn = vif->aggr_cntxt->aggr_conn;
- }
if (!aggr_conn)
return;
diff --git a/drivers/net/wireless/ath/ath6kl/usb.c b/drivers/net/wireless/ath/ath6kl/usb.c
index 96fd113..689133b 100644
--- a/drivers/net/wireless/ath/ath6kl/usb.c
+++ b/drivers/net/wireless/ath/ath6kl/usb.c
@@ -236,6 +236,7 @@
break;
kfree(urb_context);
}
+
}
static void ath6kl_usb_cleanup_pipe_resources(struct ath6kl_usb *ar_usb)
@@ -244,6 +245,7 @@
for (i = 0; i < ATH6KL_USB_PIPE_MAX; i++)
ath6kl_usb_free_pipe_resources(&ar_usb->pipes[i]);
+
}
static u8 ath6kl_usb_get_logical_pipe_num(struct ath6kl_usb *ar_usb,
diff --git a/drivers/net/wireless/ath/ath6kl/wmi.c b/drivers/net/wireless/ath/ath6kl/wmi.c
index 0c0e1e3..8b4ce28 100644
--- a/drivers/net/wireless/ath/ath6kl/wmi.c
+++ b/drivers/net/wireless/ath/ath6kl/wmi.c
@@ -289,9 +289,8 @@
ath6kl_wmi_determine_user_priority(((u8 *) llc_hdr) +
sizeof(struct ath6kl_llc_snap_hdr),
layer2_priority);
- } else {
+ } else
usr_pri = layer2_priority & 0x7;
- }
/*
* Queue the EAPOL frames in the same WMM_AC_VO queue
@@ -360,9 +359,8 @@
hdr_size = roundup(sizeof(struct ieee80211_qos_hdr),
sizeof(u32));
skb_pull(skb, hdr_size);
- } else if (sub_type == cpu_to_le16(IEEE80211_STYPE_DATA)) {
+ } else if (sub_type == cpu_to_le16(IEEE80211_STYPE_DATA))
skb_pull(skb, sizeof(struct ieee80211_hdr_3addr));
- }
datap = skb->data;
llc_hdr = (struct ath6kl_llc_snap_hdr *)(datap);
@@ -938,6 +936,7 @@
static void ath6kl_wmi_regdomain_event(struct wmi *wmi, u8 *datap, int len)
{
+
struct ath6kl_wmi_regdomain *ev;
struct country_code_to_enum_rd *country = NULL;
struct reg_dmn_pair_mapping *regpair = NULL;
@@ -947,9 +946,10 @@
ev = (struct ath6kl_wmi_regdomain *) datap;
reg_code = le32_to_cpu(ev->reg_code);
- if ((reg_code >> ATH6KL_COUNTRY_RD_SHIFT) & COUNTRY_ERD_FLAG) {
+ if ((reg_code >> ATH6KL_COUNTRY_RD_SHIFT) & COUNTRY_ERD_FLAG)
country = ath6kl_regd_find_country((u16) reg_code);
- } else if (!(((u16) reg_code & WORLD_SKU_MASK) == WORLD_SKU_PREFIX)) {
+ else if (!(((u16) reg_code & WORLD_SKU_MASK) == WORLD_SKU_PREFIX)) {
+
regpair = ath6kl_get_regpair((u16) reg_code);
country = ath6kl_regd_find_country_by_rd((u16) reg_code);
if (regpair)
@@ -1499,6 +1499,7 @@
if ((reply->cac_indication == CAC_INDICATION_ADMISSION_RESP) &&
(reply->status_code != IEEE80211_TSPEC_STATUS_ADMISS_ACCEPTED)) {
+
ts = (struct ieee80211_tspec_ie *) &(reply->tspec_suggestion);
tsinfo = le16_to_cpu(ts->tsinfo);
tsid = (tsinfo >> IEEE80211_WMM_IE_TSPEC_TID_SHIFT) &
@@ -1529,6 +1530,7 @@
* for delete qos stream from AP
*/
else if (reply->cac_indication == CAC_INDICATION_DELETE) {
+
ts = (struct ieee80211_tspec_ie *) &(reply->tspec_suggestion);
tsinfo = le16_to_cpu(ts->tsinfo);
ts_id = ((tsinfo >> IEEE80211_WMM_IE_TSPEC_TID_SHIFT) &
@@ -2477,6 +2479,7 @@
goto free_data_skb;
for (index = 0; index < num_pri_streams; index++) {
+
if (WARN_ON(!data_sync_bufs[index].skb))
goto free_data_skb;
@@ -2701,6 +2704,7 @@
for (i = 0; i < WMM_NUM_AC; i++) {
if (stream_exist & (1 << i)) {
+
/*
* FIXME: Is this lock & unlock inside
* for loop correct? may need rework.
@@ -2866,9 +2870,8 @@
if (host_mode == ATH6KL_HOST_MODE_ASLEEP) {
ath6kl_wmi_relinquish_implicit_pstream_credits(wmi);
cmd->asleep = cpu_to_le32(1);
- } else {
+ } else
cmd->awake = cpu_to_le32(1);
- }
ret = ath6kl_wmi_cmd_send(wmi, if_idx, skb,
WMI_SET_HOST_SLEEP_MODE_CMDID,
diff --git a/drivers/net/wireless/ath/ath6kl/wmi.h b/drivers/net/wireless/ath/ath6kl/wmi.h
index 1f05ecd..b5f2265 100644
--- a/drivers/net/wireless/ath/ath6kl/wmi.h
+++ b/drivers/net/wireless/ath/ath6kl/wmi.h
@@ -898,6 +898,7 @@
* flags here
*/
enum wmi_scan_ctrl_flags_bits {
+
/* set if can scan in the connect cmd */
CONNECT_SCAN_CTRL_FLAGS = 0x01,
diff --git a/drivers/net/wireless/ath/ath9k/ahb.c b/drivers/net/wireless/ath/ath9k/ahb.c
index a0398fe..be3eb2a 100644
--- a/drivers/net/wireless/ath/ath9k/ahb.c
+++ b/drivers/net/wireless/ath/ath9k/ahb.c
@@ -86,7 +86,6 @@
int irq;
int ret = 0;
struct ath_hw *ah;
- struct ath_common *common;
char hw_name[64];
if (!dev_get_platdata(&pdev->dev)) {
@@ -146,9 +145,6 @@
wiphy_info(hw->wiphy, "%s mem=0x%lx, irq=%d\n",
hw_name, (unsigned long)mem, irq);
- common = ath9k_hw_common(sc->sc_ah);
- /* Will be cleared in ath9k_start() */
- set_bit(ATH_OP_INVALID, &common->op_flags);
return 0;
err_irq:
diff --git a/drivers/net/wireless/ath/ath9k/ani.c b/drivers/net/wireless/ath/ath9k/ani.c
index 6d47783..ba502a2 100644
--- a/drivers/net/wireless/ath/ath9k/ani.c
+++ b/drivers/net/wireless/ath/ath9k/ani.c
@@ -155,6 +155,9 @@
ATH9K_ANI_RSSI_THR_LOW,
ATH9K_ANI_RSSI_THR_HIGH);
+ if (AR_SREV_9100(ah) && immunityLevel < ATH9K_ANI_OFDM_DEF_LEVEL)
+ immunityLevel = ATH9K_ANI_OFDM_DEF_LEVEL;
+
if (!scan)
aniState->ofdmNoiseImmunityLevel = immunityLevel;
@@ -235,6 +238,9 @@
BEACON_RSSI(ah), ATH9K_ANI_RSSI_THR_LOW,
ATH9K_ANI_RSSI_THR_HIGH);
+ if (AR_SREV_9100(ah) && immunityLevel < ATH9K_ANI_CCK_DEF_LEVEL)
+ immunityLevel = ATH9K_ANI_CCK_DEF_LEVEL;
+
if (ah->opmode == NL80211_IFTYPE_STATION &&
BEACON_RSSI(ah) <= ATH9K_ANI_RSSI_THR_LOW &&
immunityLevel > ATH9K_ANI_CCK_MAX_LEVEL_LOW_RSSI)
diff --git a/drivers/net/wireless/ath/ath9k/ath9k.h b/drivers/net/wireless/ath/ath9k/ath9k.h
index c23831e..bbc24c8 100644
--- a/drivers/net/wireless/ath/ath9k/ath9k.h
+++ b/drivers/net/wireless/ath/ath9k/ath9k.h
@@ -114,9 +114,6 @@
#define ATH_TXFIFO_DEPTH 8
#define ATH_TX_ERROR 0x01
-/* Stop tx traffic 1ms before the GO goes away */
-#define ATH_P2P_PS_STOP_TIME 1000
-
#define IEEE80211_SEQ_SEQ_SHIFT 4
#define IEEE80211_SEQ_MAX 4096
#define IEEE80211_WEP_IVLEN 3
@@ -254,7 +251,6 @@
s8 bar_index;
bool sched;
- bool paused;
bool active;
};
@@ -370,15 +366,11 @@
/********/
struct ath_vif {
- struct ieee80211_vif *vif;
struct ath_node mcast_node;
int av_bslot;
bool primary_sta_vif;
__le64 tsf_adjust; /* TSF adjustment for staggered beacons */
struct ath_buf *av_bcbuf;
-
- /* P2P Client */
- struct ieee80211_noa_data noa;
};
struct ath9k_vif_iter_data {
@@ -471,8 +463,6 @@
void ath_update_survey_nf(struct ath_softc *sc, int channel);
void ath9k_queue_reset(struct ath_softc *sc, enum ath_reset_type type);
void ath_ps_full_sleep(unsigned long data);
-void ath9k_p2p_ps_timer(void *priv);
-void ath9k_update_p2p_ps(struct ath_softc *sc, struct ieee80211_vif *vif);
/**********/
/* BTCOEX */
@@ -723,9 +713,6 @@
struct completion paprd_complete;
wait_queue_head_t tx_wait;
- struct ath_gen_timer *p2p_ps_timer;
- struct ath_vif *p2p_ps_vif;
-
unsigned long driver_data;
u8 gtt_cnt;
diff --git a/drivers/net/wireless/ath/ath9k/debug_sta.c b/drivers/net/wireless/ath/ath9k/debug_sta.c
index d76e6e0..ffca918 100644
--- a/drivers/net/wireless/ath/ath9k/debug_sta.c
+++ b/drivers/net/wireless/ath/ath9k/debug_sta.c
@@ -72,7 +72,7 @@
ath_txq_lock(sc, txq);
if (tid->active) {
len += scnprintf(buf + len, size - len,
- "%3d%11d%10d%10d%10d%10d%9d%6d%8d\n",
+ "%3d%11d%10d%10d%10d%10d%9d%6d\n",
tid->tidno,
tid->seq_start,
tid->seq_next,
@@ -80,8 +80,7 @@
tid->baw_head,
tid->baw_tail,
tid->bar_index,
- tid->sched,
- tid->paused);
+ tid->sched);
}
ath_txq_unlock(sc, txq);
}
diff --git a/drivers/net/wireless/ath/ath9k/htc_drv_main.c b/drivers/net/wireless/ath/ath9k/htc_drv_main.c
index 37ee21a..a55213c 100644
--- a/drivers/net/wireless/ath/ath9k/htc_drv_main.c
+++ b/drivers/net/wireless/ath/ath9k/htc_drv_main.c
@@ -95,8 +95,10 @@
if ((vif->type == NL80211_IFTYPE_AP ||
vif->type == NL80211_IFTYPE_MESH_POINT) &&
- bss_conf->enable_beacon)
+ bss_conf->enable_beacon) {
priv->reconfig_beacon = true;
+ priv->rearm_ani = true;
+ }
if (bss_conf->assoc) {
priv->rearm_ani = true;
@@ -257,6 +259,7 @@
ath9k_htc_ps_wakeup(priv);
+ ath9k_htc_stop_ani(priv);
del_timer_sync(&priv->tx.cleanup_timer);
ath9k_htc_tx_drain(priv);
diff --git a/drivers/net/wireless/ath/ath9k/init.c b/drivers/net/wireless/ath/ath9k/init.c
index 8894e96..a58e7c7 100644
--- a/drivers/net/wireless/ath/ath9k/init.c
+++ b/drivers/net/wireless/ath/ath9k/init.c
@@ -589,9 +589,6 @@
if (ret)
goto err_btcoex;
- sc->p2p_ps_timer = ath_gen_timer_alloc(sc->sc_ah, ath9k_p2p_ps_timer,
- NULL, sc, AR_FIRST_NDP_TIMER);
-
ath9k_cmn_init_crypto(sc->sc_ah);
ath9k_init_misc(sc);
ath_fill_led_pin(sc);
@@ -647,13 +644,13 @@
static const struct ieee80211_iface_limit if_limits[] = {
{ .max = 2048, .types = BIT(NL80211_IFTYPE_STATION) |
+ BIT(NL80211_IFTYPE_P2P_CLIENT) |
BIT(NL80211_IFTYPE_WDS) },
{ .max = 8, .types =
#ifdef CPTCFG_MAC80211_MESH
BIT(NL80211_IFTYPE_MESH_POINT) |
#endif
- BIT(NL80211_IFTYPE_AP) },
- { .max = 1, .types = BIT(NL80211_IFTYPE_P2P_CLIENT) |
+ BIT(NL80211_IFTYPE_AP) |
BIT(NL80211_IFTYPE_P2P_GO) },
};
@@ -786,6 +783,9 @@
common = ath9k_hw_common(ah);
ath9k_set_hw_capab(sc, hw);
+ /* Will be cleared in ath9k_start() */
+ set_bit(ATH_OP_INVALID, &common->op_flags);
+
/* Initialize regulatory */
error = ath_regd_init(&common->regulatory, sc->hw->wiphy,
ath9k_reg_notifier);
@@ -855,9 +855,6 @@
{
int i = 0;
- if (sc->p2p_ps_timer)
- ath_gen_timer_free(sc->sc_ah, sc->p2p_ps_timer);
-
ath9k_deinit_btcoex(sc);
for (i = 0; i < ATH9K_NUM_TX_QUEUES; i++)
diff --git a/drivers/net/wireless/ath/ath9k/main.c b/drivers/net/wireless/ath/ath9k/main.c
index 77118d1..a3af527 100644
--- a/drivers/net/wireless/ath/ath9k/main.c
+++ b/drivers/net/wireless/ath/ath9k/main.c
@@ -261,8 +261,6 @@
sc->gtt_cnt = 0;
ieee80211_wake_queues(sc->hw);
- ath9k_p2p_ps_timer(sc);
-
return true;
}
@@ -1121,8 +1119,6 @@
if (ath9k_uses_beacons(vif->type))
ath9k_beacon_assign_slot(sc, vif);
- avp->vif = vif;
-
an->sc = sc;
an->sta = NULL;
an->vif = vif;
@@ -1167,29 +1163,6 @@
return 0;
}
-static void
-ath9k_update_p2p_ps_timer(struct ath_softc *sc, struct ath_vif *avp)
-{
- struct ath_hw *ah = sc->sc_ah;
- s32 tsf, target_tsf;
-
- if (!avp || !avp->noa.has_next_tsf)
- return;
-
- ath9k_hw_gen_timer_stop(ah, sc->p2p_ps_timer);
-
- tsf = ath9k_hw_gettsf32(sc->sc_ah);
-
- target_tsf = avp->noa.next_tsf;
- if (!avp->noa.absent)
- target_tsf -= ATH_P2P_PS_STOP_TIME;
-
- if (target_tsf - tsf < ATH_P2P_PS_STOP_TIME)
- target_tsf = tsf + ATH_P2P_PS_STOP_TIME;
-
- ath9k_hw_gen_timer_start(ah, sc->p2p_ps_timer, (u32) target_tsf, 1000000);
-}
-
static void ath9k_remove_interface(struct ieee80211_hw *hw,
struct ieee80211_vif *vif)
{
@@ -1201,13 +1174,6 @@
mutex_lock(&sc->mutex);
- spin_lock_bh(&sc->sc_pcu_lock);
- if (avp == sc->p2p_ps_vif) {
- sc->p2p_ps_vif = NULL;
- ath9k_update_p2p_ps_timer(sc, NULL);
- }
- spin_unlock_bh(&sc->sc_pcu_lock);
-
sc->nvifs--;
sc->tx99_vif = NULL;
@@ -1670,72 +1636,6 @@
ath9k_set_assoc_state(sc, vif);
}
-void ath9k_p2p_ps_timer(void *priv)
-{
- struct ath_softc *sc = priv;
- struct ath_vif *avp = sc->p2p_ps_vif;
- struct ieee80211_vif *vif;
- struct ieee80211_sta *sta;
- struct ath_node *an;
- u32 tsf;
-
- if (!avp)
- return;
-
- tsf = ath9k_hw_gettsf32(sc->sc_ah);
- if (!avp->noa.absent)
- tsf += ATH_P2P_PS_STOP_TIME;
-
- if (!avp->noa.has_next_tsf ||
- avp->noa.next_tsf - tsf > BIT(31))
- ieee80211_update_p2p_noa(&avp->noa, tsf);
-
- ath9k_update_p2p_ps_timer(sc, avp);
-
- rcu_read_lock();
-
- vif = avp->vif;
- sta = ieee80211_find_sta(vif, vif->bss_conf.bssid);
- if (!sta)
- goto out;
-
- an = (void *) sta->drv_priv;
- if (an->sleeping == !!avp->noa.absent)
- goto out;
-
- an->sleeping = avp->noa.absent;
- if (an->sleeping)
- ath_tx_aggr_sleep(sta, sc, an);
- else
- ath_tx_aggr_wakeup(sc, an);
-
-out:
- rcu_read_unlock();
-}
-
-void ath9k_update_p2p_ps(struct ath_softc *sc, struct ieee80211_vif *vif)
-{
- struct ath_vif *avp = (void *)vif->drv_priv;
- unsigned long flags;
- u32 tsf;
-
- if (!sc->p2p_ps_timer)
- return;
-
- if (vif->type != NL80211_IFTYPE_STATION || !vif->p2p)
- return;
-
- sc->p2p_ps_vif = avp;
-
- spin_lock_irqsave(&sc->sc_pm_lock, flags);
- if (!(sc->ps_flags & PS_BEACON_SYNC)) {
- tsf = ath9k_hw_gettsf32(sc->sc_ah);
- ieee80211_parse_p2p_noa(&vif->bss_conf.p2p_noa_attr, &avp->noa, tsf);
- ath9k_update_p2p_ps_timer(sc, avp);
- }
- spin_unlock_irqrestore(&sc->sc_pm_lock, flags);
-}
-
static void ath9k_bss_info_changed(struct ieee80211_hw *hw,
struct ieee80211_vif *vif,
struct ieee80211_bss_conf *bss_conf,
@@ -1810,12 +1710,6 @@
}
}
- if (changed & BSS_CHANGED_P2P_PS) {
- spin_lock_bh(&sc->sc_pcu_lock);
- ath9k_update_p2p_ps(sc, vif);
- spin_unlock_bh(&sc->sc_pcu_lock);
- }
-
if (changed & CHECK_ANI)
ath_check_ani(sc);
diff --git a/drivers/net/wireless/ath/ath9k/pci.c b/drivers/net/wireless/ath/ath9k/pci.c
index 25304ad..914dbc6 100644
--- a/drivers/net/wireless/ath/ath9k/pci.c
+++ b/drivers/net/wireless/ath/ath9k/pci.c
@@ -784,7 +784,6 @@
{
struct ath_softc *sc;
struct ieee80211_hw *hw;
- struct ath_common *common;
u8 csz;
u32 val;
int ret = 0;
@@ -877,10 +876,6 @@
wiphy_info(hw->wiphy, "%s mem=0x%lx, irq=%d\n",
hw_name, (unsigned long)sc->mem, pdev->irq);
- /* Will be cleared in ath9k_start() */
- common = ath9k_hw_common(sc->sc_ah);
- set_bit(ATH_OP_INVALID, &common->op_flags);
-
return 0;
err_init:
diff --git a/drivers/net/wireless/ath/ath9k/recv.c b/drivers/net/wireless/ath/ath9k/recv.c
index 8200560..5c2b89e 100644
--- a/drivers/net/wireless/ath/ath9k/recv.c
+++ b/drivers/net/wireless/ath/ath9k/recv.c
@@ -539,9 +539,6 @@
ath_dbg(common, PS,
"Reconfigure beacon timers based on synchronized timestamp\n");
ath9k_set_beacon(sc);
-
- if (sc->p2p_ps_vif)
- ath9k_update_p2p_ps(sc, sc->p2p_ps_vif->vif);
}
if (ath_beacon_dtim_pending_cab(skb)) {
@@ -978,6 +975,7 @@
u64 tsf = 0;
unsigned long flags;
dma_addr_t new_buf_addr;
+ unsigned int budget = 512;
if (edma)
dma_type = DMA_BIDIRECTIONAL;
@@ -1116,15 +1114,17 @@
}
requeue:
list_add_tail(&bf->list, &sc->rx.rxbuf);
- if (flush)
- continue;
if (edma) {
ath_rx_edma_buf_link(sc, qtype);
} else {
ath_rx_buf_relink(sc, bf);
- ath9k_hw_rxena(ah);
+ if (!flush)
+ ath9k_hw_rxena(ah);
}
+
+ if (!budget--)
+ break;
} while (1);
if (!(ah->imask & ATH9K_INT_RXEOL)) {
diff --git a/drivers/net/wireless/ath/ath9k/xmit.c b/drivers/net/wireless/ath/ath9k/xmit.c
index bbce929..59503b0 100644
--- a/drivers/net/wireless/ath/ath9k/xmit.c
+++ b/drivers/net/wireless/ath/ath9k/xmit.c
@@ -107,9 +107,6 @@
{
struct ath_atx_ac *ac = tid->ac;
- if (tid->paused)
- return;
-
if (tid->sched)
return;
@@ -890,6 +887,15 @@
tx_info = IEEE80211_SKB_CB(skb);
tx_info->flags &= ~IEEE80211_TX_CTL_CLEAR_PS_FILT;
+
+ /*
+ * No aggregation session is running, but there may be frames
+ * from a previous session or a failed attempt in the queue.
+ * Send them out as normal data frames
+ */
+ if (!tid->active)
+ tx_info->flags &= ~IEEE80211_TX_CTL_AMPDU;
+
if (!(tx_info->flags & IEEE80211_TX_CTL_AMPDU)) {
bf->bf_state.bf_type = 0;
return bf;
@@ -1407,7 +1413,6 @@
ath_tx_tid_change_state(sc, txtid);
txtid->active = true;
- txtid->paused = true;
*ssn = txtid->seq_start = txtid->seq_next;
txtid->bar_index = -1;
@@ -1427,7 +1432,6 @@
ath_txq_lock(sc, txq);
txtid->active = false;
- txtid->paused = false;
ath_tx_flush_tid(sc, txtid);
ath_tx_tid_change_state(sc, txtid);
ath_txq_unlock_complete(sc, txq);
@@ -1487,7 +1491,7 @@
ath_txq_lock(sc, txq);
ac->clear_ps_filter = true;
- if (!tid->paused && ath_tid_has_buffered(tid)) {
+ if (ath_tid_has_buffered(tid)) {
ath_tx_queue_tid(txq, tid);
ath_txq_schedule(sc, txq);
}
@@ -1510,7 +1514,6 @@
ath_txq_lock(sc, txq);
tid->baw_size = IEEE80211_MIN_AMPDU_BUF << sta->ht_cap.ampdu_factor;
- tid->paused = false;
if (ath_tid_has_buffered(tid)) {
ath_tx_queue_tid(txq, tid);
@@ -1544,8 +1547,6 @@
continue;
tid = ATH_AN_2_TID(an, i);
- if (tid->paused)
- continue;
ath_txq_lock(sc, tid->ac->txq);
while (nframes > 0) {
@@ -1844,9 +1845,6 @@
list_del(&tid->list);
tid->sched = false;
- if (tid->paused)
- continue;
-
if (ath_tx_sched_aggr(sc, txq, tid, &stop))
sent = true;
@@ -2698,7 +2696,6 @@
tid->baw_size = WME_MAX_BA;
tid->baw_head = tid->baw_tail = 0;
tid->sched = false;
- tid->paused = false;
tid->active = false;
__skb_queue_head_init(&tid->buf_q);
__skb_queue_head_init(&tid->retry_q);
diff --git a/drivers/net/wireless/ath/wil6210/interrupt.c b/drivers/net/wireless/ath/wil6210/interrupt.c
index f887563..4e7d10c 100644
--- a/drivers/net/wireless/ath/wil6210/interrupt.c
+++ b/drivers/net/wireless/ath/wil6210/interrupt.c
@@ -338,7 +338,7 @@
}
if (isr)
- wil_dbg_irq(wil, "un-handled MISC ISR bits 0x%08x\n", isr);
+ wil_err(wil, "un-handled MISC ISR bits 0x%08x\n", isr);
wil->isr_misc = 0;
diff --git a/drivers/net/wireless/ath/wil6210/main.c b/drivers/net/wireless/ath/wil6210/main.c
index 1b265fd..95f4efe 100644
--- a/drivers/net/wireless/ath/wil6210/main.c
+++ b/drivers/net/wireless/ath/wil6210/main.c
@@ -363,8 +363,8 @@
wil_err(wil, "Firmware not ready\n");
return -ETIME;
} else {
- wil_info(wil, "FW ready after %d ms. HW version 0x%08x\n",
- jiffies_to_msecs(to-left), wil->hw_version);
+ wil_dbg_misc(wil, "FW ready after %d ms\n",
+ jiffies_to_msecs(to-left));
}
return 0;
}
diff --git a/drivers/net/wireless/ath/wil6210/pcie_bus.c b/drivers/net/wireless/ath/wil6210/pcie_bus.c
index 0660884..f1e1bb3 100644
--- a/drivers/net/wireless/ath/wil6210/pcie_bus.c
+++ b/drivers/net/wireless/ath/wil6210/pcie_bus.c
@@ -74,6 +74,8 @@
if (rc)
goto release_irq;
+ wil_info(wil, "HW version: 0x%08x\n", wil->hw_version);
+
return 0;
release_irq:
diff --git a/drivers/net/wireless/ath/wil6210/rx_reorder.c b/drivers/net/wireless/ath/wil6210/rx_reorder.c
index ec29954..d04629f 100644
--- a/drivers/net/wireless/ath/wil6210/rx_reorder.c
+++ b/drivers/net/wireless/ath/wil6210/rx_reorder.c
@@ -91,22 +91,6 @@
spin_lock(&r->reorder_lock);
- /** Due to the race between WMI events, where BACK establishment
- * reported, and data Rx, few packets may be pass up before reorder
- * buffer get allocated. Catch up by pretending SSN is what we
- * see in the 1-st Rx packet
- */
- if (r->first_time) {
- r->first_time = false;
- if (seq != r->head_seq_num) {
- wil_err(wil, "Error: 1-st frame with wrong sequence"
- " %d, should be %d. Fixing...\n", seq,
- r->head_seq_num);
- r->head_seq_num = seq;
- r->ssn = seq;
- }
- }
-
/* frame with out of date sequence number */
if (seq_less(seq, r->head_seq_num)) {
dev_kfree_skb(skb);
@@ -178,7 +162,6 @@
r->head_seq_num = ssn;
r->buf_size = size;
r->stored_mpdu_num = 0;
- r->first_time = true;
return r;
}
diff --git a/drivers/net/wireless/ath/wil6210/wil6210.h b/drivers/net/wireless/ath/wil6210/wil6210.h
index d3b8659..2a2dec7 100644
--- a/drivers/net/wireless/ath/wil6210/wil6210.h
+++ b/drivers/net/wireless/ath/wil6210/wil6210.h
@@ -35,7 +35,7 @@
#define WIL6210_MEM_SIZE (2*1024*1024UL)
#define WIL6210_RX_RING_SIZE (128)
-#define WIL6210_TX_RING_SIZE (512)
+#define WIL6210_TX_RING_SIZE (128)
#define WIL6210_MAX_TX_RINGS (24) /* HW limit */
#define WIL6210_MAX_CID (8) /* HW limit */
#define WIL6210_NAPI_BUDGET (16) /* arbitrary */
@@ -301,7 +301,6 @@
u16 buf_size;
u16 timeout;
u8 dialog_token;
- bool first_time; /* is it 1-st time this buffer used? */
};
struct wil6210_stats {
diff --git a/drivers/net/wireless/ath/wil6210/wmi.c b/drivers/net/wireless/ath/wil6210/wmi.c
index e9a11cb..2ba56ee 100644
--- a/drivers/net/wireless/ath/wil6210/wmi.c
+++ b/drivers/net/wireless/ath/wil6210/wmi.c
@@ -192,7 +192,7 @@
might_sleep();
if (!test_bit(wil_status_fwready, &wil->status)) {
- wil_err(wil, "WMI: cannot send command while FW not ready\n");
+ wil_err(wil, "FW not ready\n");
return -EAGAIN;
}
@@ -276,8 +276,8 @@
wil->fw_version = le32_to_cpu(evt->sw_version);
wil->n_mids = evt->numof_additional_mids;
- wil_info(wil, "FW ver. %d; MAC %pM; %d MID's\n", wil->fw_version,
- evt->mac, wil->n_mids);
+ wil_dbg_wmi(wil, "FW ver. %d; MAC %pM; %d MID's\n", wil->fw_version,
+ evt->mac, wil->n_mids);
if (!is_valid_ether_addr(ndev->dev_addr)) {
memcpy(ndev->dev_addr, evt->mac, ETH_ALEN);
@@ -290,7 +290,7 @@
static void wmi_evt_fw_ready(struct wil6210_priv *wil, int id, void *d,
int len)
{
- wil_dbg_wmi(wil, "WMI: got FW ready event\n");
+ wil_dbg_wmi(wil, "WMI: FW ready\n");
set_bit(wil_status_fwready, &wil->status);
/* reuse wmi_ready for the firmware ready indication */
@@ -348,7 +348,7 @@
{
if (wil->scan_request) {
struct wmi_scan_complete_event *data = d;
- bool aborted = (data->status != WMI_SCAN_SUCCESS);
+ bool aborted = (data->status != 0);
wil_dbg_wmi(wil, "SCAN_COMPLETE(0x%08x)\n", data->status);
cfg80211_scan_done(wil->scan_request, aborted);
@@ -802,7 +802,6 @@
.network_type = wmi_nettype,
.disable_sec_offload = 1,
.channel = chan - 1,
- .pcp_max_assoc_sta = WIL6210_MAX_CID,
};
struct {
struct wil6210_mbox_hdr_wmi wmi;
diff --git a/drivers/net/wireless/ath/wil6210/wmi.h b/drivers/net/wireless/ath/wil6210/wmi.h
index 17334c8..50b8528 100644
--- a/drivers/net/wireless/ath/wil6210/wmi.h
+++ b/drivers/net/wireless/ath/wil6210/wmi.h
@@ -28,7 +28,7 @@
#define __WILOCITY_WMI_H__
/* General */
-#define WILOCITY_MAX_ASSOC_STA (8)
+
#define WMI_MAC_LEN (6)
#define WMI_PROX_RANGE_NUM (3)
@@ -219,6 +219,15 @@
__le16 disconnect_reason;
} __packed;
+/*
+ * WMI_RECONNECT_CMDID
+ */
+struct wmi_reconnect_cmd {
+ u8 channel; /* hint */
+ u8 reserved;
+ u8 bssid[WMI_MAC_LEN]; /* mandatory if set */
+} __packed;
+
/*
* WMI_SET_PMK_CMDID
@@ -287,13 +296,11 @@
WMI_LONG_SCAN = 0,
WMI_SHORT_SCAN = 1,
WMI_PBC_SCAN = 2,
- WMI_ACTIVE_SCAN = 3,
- WMI_DIRECT_SCAN = 4,
};
struct wmi_start_scan_cmd {
- u8 direct_scan_mac_addr[6];
- u8 reserved[2];
+ u8 reserved[8];
+
__le32 home_dwell_time; /* Max duration in the home channel(ms) */
__le32 force_scan_interval; /* Time interval between scans (ms)*/
u8 scan_type; /* wmi_scan_type */
@@ -325,7 +332,6 @@
u8 ssid[WMI_MAX_SSID_LEN];
} __packed;
-
/*
* WMI_SET_APPIE_CMDID
* Add Application specified IE to a management frame
@@ -421,7 +427,7 @@
__le16 frag_num;
__le64 ss_mask;
u8 network_type;
- u8 pcp_max_assoc_sta;
+ u8 reserved;
u8 disable_sec_offload;
u8 disable_sec;
} __packed;
@@ -444,7 +450,7 @@
struct wmi_port_allocate_cmd {
u8 mac[WMI_MAC_LEN];
u8 port_role;
- u8 mid;
+ u8 midid;
} __packed;
/*
@@ -461,7 +467,6 @@
enum wmi_discovery_mode {
WMI_DISCOVERY_MODE_NON_OFFLOAD = 0,
WMI_DISCOVERY_MODE_OFFLOAD = 1,
- WMI_DISCOVERY_MODE_PEER2PEER = 2,
};
struct wmi_p2p_cfg_cmd {
@@ -488,8 +493,7 @@
*/
struct wmi_pcp_start_cmd {
__le16 bcon_interval;
- u8 pcp_max_assoc_sta;
- u8 reserved0[9];
+ u8 reserved0[10];
u8 network_type;
u8 channel;
u8 disable_sec_offload;
@@ -853,7 +857,6 @@
WMI_RF_MGMT_STATUS_EVENTID = 0x1853,
WMI_BF_SM_MGMT_DONE_EVENTID = 0x1838,
WMI_RX_MGMT_PACKET_EVENTID = 0x1840,
- WMI_TX_MGMT_PACKET_EVENTID = 0x1841,
/* Performance monitoring events */
WMI_DATA_PORT_OPEN_EVENTID = 0x1860,
@@ -1037,23 +1040,16 @@
struct wmi_disconnect_event {
__le16 protocol_reason_status; /* reason code, see 802.11 spec. */
u8 bssid[WMI_MAC_LEN]; /* set if known */
- u8 disconnect_reason; /* see wmi_disconnect_reason */
- u8 assoc_resp_len; /* not in use */
- u8 assoc_info[0]; /* not in use */
+ u8 disconnect_reason; /* see wmi_disconnect_reason_e */
+ u8 assoc_resp_len;
+ u8 assoc_info[0];
} __packed;
/*
* WMI_SCAN_COMPLETE_EVENTID
*/
-enum scan_status {
- WMI_SCAN_SUCCESS = 0,
- WMI_SCAN_FAILED = 1,
- WMI_SCAN_ABORTED = 2,
- WMI_SCAN_REJECTED = 3,
-};
-
struct wmi_scan_complete_event {
- __le32 status; /* scan_status */
+ __le32 status;
} __packed;
/*
@@ -1260,14 +1256,6 @@
u8 channel; /* From Radio MNGR */
} __packed;
-
-/*
- * WMI_TX_MGMT_PACKET_EVENTID
- */
-struct wmi_tx_mgmt_packet_event {
- u8 payload[0];
-} __packed;
-
struct wmi_rx_mgmt_packet_event {
struct wmi_rx_mgmt_info info;
u8 payload[0];
diff --git a/drivers/net/wireless/b43/b43.h b/drivers/net/wireless/b43/b43.h
index a1f4475..a9583cb 100644
--- a/drivers/net/wireless/b43/b43.h
+++ b/drivers/net/wireless/b43/b43.h
@@ -915,6 +915,10 @@
char rng_name[30 + 1];
#endif /* CPTCFG_B43_HWRNG */
+ /* List of all wireless devices on this chip */
+ struct list_head devlist;
+ u8 nr_devs;
+
bool radiotap_enabled;
bool radio_enabled;
diff --git a/drivers/net/wireless/b43/main.c b/drivers/net/wireless/b43/main.c
index ae9e52d..e5ce452 100644
--- a/drivers/net/wireless/b43/main.c
+++ b/drivers/net/wireless/b43/main.c
@@ -3735,35 +3735,40 @@
{
struct b43_wldev *up_dev = NULL;
struct b43_wldev *down_dev;
+ struct b43_wldev *d;
int err;
bool uninitialized_var(gmode);
int prev_status;
/* Find a device and PHY which supports the band. */
- switch (chan->band) {
- case IEEE80211_BAND_5GHZ:
- if (wl->current_dev->phy.supports_5ghz) {
- up_dev = wl->current_dev;
- gmode = false;
+ list_for_each_entry(d, &wl->devlist, list) {
+ switch (chan->band) {
+ case IEEE80211_BAND_5GHZ:
+ if (d->phy.supports_5ghz) {
+ up_dev = d;
+ gmode = false;
+ }
+ break;
+ case IEEE80211_BAND_2GHZ:
+ if (d->phy.supports_2ghz) {
+ up_dev = d;
+ gmode = true;
+ }
+ break;
+ default:
+ B43_WARN_ON(1);
+ return -EINVAL;
}
- break;
- case IEEE80211_BAND_2GHZ:
- if (wl->current_dev->phy.supports_2ghz) {
- up_dev = wl->current_dev;
- gmode = true;
- }
- break;
- default:
- B43_WARN_ON(1);
- return -EINVAL;
+ if (up_dev)
+ break;
}
-
if (!up_dev) {
b43err(wl, "Could not find a device for %s-GHz band operation\n",
band_to_string(chan->band));
return -ENODEV;
}
- if (!!wl->current_dev->phy.gmode == !!gmode) {
+ if ((up_dev == wl->current_dev) &&
+ (!!wl->current_dev->phy.gmode == !!gmode)) {
/* This device is already running. */
return 0;
}
@@ -5265,6 +5270,7 @@
b43_debugfs_remove_device(wldev);
b43_wireless_core_detach(wldev);
list_del(&wldev->list);
+ wl->nr_devs--;
b43_bus_set_wldev(dev, NULL);
kfree(wldev);
}
@@ -5289,6 +5295,8 @@
if (err)
goto err_kfree_wldev;
+ list_add(&wldev->list, &wl->devlist);
+ wl->nr_devs++;
b43_bus_set_wldev(dev, wldev);
b43_debugfs_add_device(wldev);
@@ -5378,6 +5386,7 @@
wl->hw = hw;
mutex_init(&wl->mutex);
spin_lock_init(&wl->hardirq_lock);
+ INIT_LIST_HEAD(&wl->devlist);
INIT_WORK(&wl->beacon_update_trigger, b43_beacon_update_trigger_work);
INIT_WORK(&wl->txpower_adjust_work, b43_phy_txpower_adjust_work);
INIT_WORK(&wl->tx_work, b43_tx_work);
@@ -5477,42 +5486,39 @@
struct b43_bus_dev *dev;
struct b43_wl *wl;
int err;
+ int first = 0;
dev = b43_bus_dev_ssb_init(sdev);
if (!dev)
return -ENOMEM;
wl = ssb_get_devtypedata(sdev);
- if (wl) {
- b43err(NULL, "Dual-core devices are not supported\n");
- err = -ENOTSUPP;
- goto err_ssb_kfree_dev;
+ if (!wl) {
+ /* Probing the first core. Must setup common struct b43_wl */
+ first = 1;
+ b43_sprom_fixup(sdev->bus);
+ wl = b43_wireless_init(dev);
+ if (IS_ERR(wl)) {
+ err = PTR_ERR(wl);
+ goto out;
+ }
+ ssb_set_devtypedata(sdev, wl);
+ B43_WARN_ON(ssb_get_devtypedata(sdev) != wl);
}
-
- b43_sprom_fixup(sdev->bus);
-
- wl = b43_wireless_init(dev);
- if (IS_ERR(wl)) {
- err = PTR_ERR(wl);
- goto err_ssb_kfree_dev;
- }
- ssb_set_devtypedata(sdev, wl);
- B43_WARN_ON(ssb_get_devtypedata(sdev) != wl);
-
err = b43_one_core_attach(dev, wl);
if (err)
- goto err_ssb_wireless_exit;
+ goto err_wireless_exit;
/* setup and start work to load firmware */
INIT_WORK(&wl->firmware_load, b43_request_firmware);
schedule_work(&wl->firmware_load);
+ out:
return err;
-err_ssb_wireless_exit:
- b43_wireless_exit(dev, wl);
-err_ssb_kfree_dev:
- kfree(dev);
+ err_wireless_exit:
+ if (first)
+ b43_wireless_exit(dev, wl);
return err;
}
@@ -5540,8 +5546,13 @@
/* Unregister HW RNG driver */
b43_rng_exit(wl);
- b43_leds_unregister(wl);
- b43_wireless_exit(dev, wl);
+ if (list_empty(&wl->devlist)) {
+ b43_leds_unregister(wl);
+ /* Last core on the chip unregistered.
+ * We can destroy common struct b43_wl.
+ */
+ b43_wireless_exit(dev, wl);
+ }
}
static struct ssb_driver b43_ssb_driver = {
diff --git a/drivers/net/wireless/b43/phy_g.c b/drivers/net/wireless/b43/phy_g.c
index 8f5c14b..12f467b 100644
--- a/drivers/net/wireless/b43/phy_g.c
+++ b/drivers/net/wireless/b43/phy_g.c
@@ -1587,7 +1587,6 @@
b43_write16(dev, 0x03E4, (b43_read16(dev, 0x03E4) & 0xFFC0) | 0x0004);
}
-/* http://bcm-v4.sipsolutions.net/802.11/PHY/Init/B6 */
static void b43_phy_initb6(struct b43_wldev *dev)
{
struct b43_phy *phy = &dev->phy;
@@ -1671,7 +1670,7 @@
b43_radio_write16(dev, 0x50, 0x20);
}
if (phy->radio_rev <= 2) {
- b43_radio_write16(dev, 0x50, 0x20);
+ b43_radio_write16(dev, 0x7C, 0x20);
b43_radio_write16(dev, 0x5A, 0x70);
b43_radio_write16(dev, 0x5B, 0x7B);
b43_radio_write16(dev, 0x5C, 0xB0);
@@ -1687,8 +1686,9 @@
b43_phy_write(dev, 0x2A, 0x8AC0);
b43_phy_write(dev, 0x0038, 0x0668);
b43_set_txpower_g(dev, &gphy->bbatt, &gphy->rfatt, gphy->tx_control);
- if (phy->radio_rev == 4 || phy->radio_rev == 5)
+ if (phy->radio_rev <= 5) {
b43_phy_maskset(dev, 0x5D, 0xFF80, 0x0003);
+ }
if (phy->radio_rev <= 2)
b43_radio_write16(dev, 0x005D, 0x000D);
diff --git a/drivers/net/wireless/b43/phy_n.c b/drivers/net/wireless/b43/phy_n.c
index b4ddc3d..961b62d 100644
--- a/drivers/net/wireless/b43/phy_n.c
+++ b/drivers/net/wireless/b43/phy_n.c
@@ -257,72 +257,6 @@
}
}
-static void b43_nphy_rf_ctl_intc_override_rev7(struct b43_wldev *dev,
- enum n_intc_override intc_override,
- u16 value, u8 core_sel)
-{
- u16 reg, tmp, tmp2, val;
- int core;
-
- for (core = 0; core < 2; core++) {
- if ((core_sel == 1 && core != 0) ||
- (core_sel == 2 && core != 1))
- continue;
-
- reg = (core == 0) ? B43_NPHY_RFCTL_INTC1 : B43_NPHY_RFCTL_INTC2;
-
- switch (intc_override) {
- case N_INTC_OVERRIDE_OFF:
- b43_phy_write(dev, reg, 0);
- b43_nphy_force_rf_sequence(dev, B43_RFSEQ_RESET2RX);
- break;
- case N_INTC_OVERRIDE_TRSW:
- b43_phy_maskset(dev, reg, ~0xC0, value << 6);
- b43_phy_set(dev, reg, 0x400);
-
- b43_phy_mask(dev, 0x2ff, ~0xC000 & 0xFFFF);
- b43_phy_set(dev, 0x2ff, 0x2000);
- b43_phy_set(dev, 0x2ff, 0x0001);
- break;
- case N_INTC_OVERRIDE_PA:
- tmp = 0x0030;
- if (b43_current_band(dev->wl) == IEEE80211_BAND_5GHZ)
- val = value << 5;
- else
- val = value << 4;
- b43_phy_maskset(dev, reg, ~tmp, val);
- b43_phy_set(dev, reg, 0x1000);
- break;
- case N_INTC_OVERRIDE_EXT_LNA_PU:
- if (b43_current_band(dev->wl) == IEEE80211_BAND_5GHZ) {
- tmp = 0x0001;
- tmp2 = 0x0004;
- val = value;
- } else {
- tmp = 0x0004;
- tmp2 = 0x0001;
- val = value << 2;
- }
- b43_phy_maskset(dev, reg, ~tmp, val);
- b43_phy_mask(dev, reg, ~tmp2);
- break;
- case N_INTC_OVERRIDE_EXT_LNA_GAIN:
- if (b43_current_band(dev->wl) == IEEE80211_BAND_5GHZ) {
- tmp = 0x0002;
- tmp2 = 0x0008;
- val = value << 1;
- } else {
- tmp = 0x0008;
- tmp2 = 0x0002;
- val = value << 3;
- }
- b43_phy_maskset(dev, reg, ~tmp, val);
- b43_phy_mask(dev, reg, ~tmp2);
- break;
- }
- }
-}
-
/* http://bcm-v4.sipsolutions.net/802.11/PHY/N/RFCtrlIntcOverride */
static void b43_nphy_rf_ctl_intc_override(struct b43_wldev *dev,
enum n_intc_override intc_override,
@@ -331,12 +265,6 @@
u8 i, j;
u16 reg, tmp, val;
- if (dev->phy.rev >= 7) {
- b43_nphy_rf_ctl_intc_override_rev7(dev, intc_override, value,
- core);
- return;
- }
-
B43_WARN_ON(dev->phy.rev < 3);
for (i = 0; i < 2; i++) {
@@ -491,8 +419,7 @@
static const u16 clip[] = { 0xFFFF, 0xFFFF };
if (nphy->deaf_count++ == 0) {
nphy->classifier_state = b43_nphy_classifier(dev, 0, 0);
- b43_nphy_classifier(dev, 0x7,
- B43_NPHY_CLASSCTL_WAITEDEN);
+ b43_nphy_classifier(dev, 0x7, 0);
b43_nphy_read_clip_detection(dev, nphy->clip_state);
b43_nphy_write_clip_detection(dev, clip);
}
@@ -1237,20 +1164,23 @@
u16 seq_mode;
u32 tmp;
- b43_nphy_stay_in_carrier_search(dev, true);
+ if (nphy->hang_avoid)
+ b43_nphy_stay_in_carrier_search(dev, true);
if ((nphy->bb_mult_save & 0x80000000) == 0) {
tmp = b43_ntab_read(dev, B43_NTAB16(15, 87));
nphy->bb_mult_save = (tmp & 0xFFFF) | 0x80000000;
}
- /* TODO: add modify_bbmult argument */
if (!dev->phy.is_40mhz)
tmp = 0x6464;
else
tmp = 0x4747;
b43_ntab_write(dev, B43_NTAB16(15, 87), tmp);
+ if (nphy->hang_avoid)
+ b43_nphy_stay_in_carrier_search(dev, false);
+
b43_phy_write(dev, B43_NPHY_SAMP_DEPCNT, (samps - 1));
if (loops != 0xFFFF)
@@ -1283,8 +1213,6 @@
b43err(dev->wl, "run samples timeout\n");
b43_phy_write(dev, B43_NPHY_RFSEQMODE, seq_mode);
-
- b43_nphy_stay_in_carrier_search(dev, false);
}
/**************************************************
@@ -1660,8 +1588,8 @@
struct b43_phy_n *nphy = dev->phy.n;
u16 saved_regs_phy_rfctl[2];
- u16 saved_regs_phy[22];
- u16 regs_to_store_rev3[] = {
+ u16 saved_regs_phy[13];
+ u16 regs_to_store[] = {
B43_NPHY_AFECTL_OVER1, B43_NPHY_AFECTL_OVER,
B43_NPHY_AFECTL_C1, B43_NPHY_AFECTL_C2,
B43_NPHY_TXF_40CO_B1S1, B43_NPHY_RFCTL_OVER,
@@ -1670,20 +1598,6 @@
B43_NPHY_RFCTL_LUT_TRSW_UP1, B43_NPHY_RFCTL_LUT_TRSW_UP2,
B43_NPHY_RFCTL_RSSIO1, B43_NPHY_RFCTL_RSSIO2
};
- u16 regs_to_store_rev7[] = {
- B43_NPHY_AFECTL_OVER1, B43_NPHY_AFECTL_OVER,
- B43_NPHY_AFECTL_C1, B43_NPHY_AFECTL_C2,
- B43_NPHY_TXF_40CO_B1S1, B43_NPHY_RFCTL_OVER,
- 0x342, 0x343, 0x346, 0x347,
- 0x2ff,
- B43_NPHY_TXF_40CO_B1S0, B43_NPHY_TXF_40CO_B32S1,
- B43_NPHY_RFCTL_CMD,
- B43_NPHY_RFCTL_LUT_TRSW_UP1, B43_NPHY_RFCTL_LUT_TRSW_UP2,
- 0x340, 0x341, 0x344, 0x345,
- B43_NPHY_RFCTL_RSSIO1, B43_NPHY_RFCTL_RSSIO2
- };
- u16 *regs_to_store;
- int regs_amount;
u16 class;
@@ -1703,15 +1617,6 @@
u8 rx_core_state;
int core, i, j, vcm;
- if (dev->phy.rev >= 7) {
- regs_to_store = regs_to_store_rev7;
- regs_amount = ARRAY_SIZE(regs_to_store_rev7);
- } else {
- regs_to_store = regs_to_store_rev3;
- regs_amount = ARRAY_SIZE(regs_to_store_rev3);
- }
- BUG_ON(regs_amount > ARRAY_SIZE(saved_regs_phy));
-
class = b43_nphy_classifier(dev, 0, 0);
b43_nphy_classifier(dev, 7, 4);
b43_nphy_read_clip_detection(dev, clip_state);
@@ -1719,29 +1624,22 @@
saved_regs_phy_rfctl[0] = b43_phy_read(dev, B43_NPHY_RFCTL_INTC1);
saved_regs_phy_rfctl[1] = b43_phy_read(dev, B43_NPHY_RFCTL_INTC2);
- for (i = 0; i < regs_amount; i++)
+ for (i = 0; i < ARRAY_SIZE(regs_to_store); i++)
saved_regs_phy[i] = b43_phy_read(dev, regs_to_store[i]);
b43_nphy_rf_ctl_intc_override(dev, N_INTC_OVERRIDE_OFF, 0, 7);
b43_nphy_rf_ctl_intc_override(dev, N_INTC_OVERRIDE_TRSW, 1, 7);
+ b43_nphy_rf_ctl_override(dev, 0x1, 0, 0, false);
+ b43_nphy_rf_ctl_override(dev, 0x2, 1, 0, false);
+ b43_nphy_rf_ctl_override(dev, 0x80, 1, 0, false);
+ b43_nphy_rf_ctl_override(dev, 0x40, 1, 0, false);
- if (dev->phy.rev >= 7) {
- /* TODO */
- if (b43_current_band(dev->wl) == IEEE80211_BAND_5GHZ) {
- } else {
- }
+ if (b43_current_band(dev->wl) == IEEE80211_BAND_5GHZ) {
+ b43_nphy_rf_ctl_override(dev, 0x20, 0, 0, false);
+ b43_nphy_rf_ctl_override(dev, 0x10, 1, 0, false);
} else {
- b43_nphy_rf_ctl_override(dev, 0x1, 0, 0, false);
- b43_nphy_rf_ctl_override(dev, 0x2, 1, 0, false);
- b43_nphy_rf_ctl_override(dev, 0x80, 1, 0, false);
- b43_nphy_rf_ctl_override(dev, 0x40, 1, 0, false);
- if (b43_current_band(dev->wl) == IEEE80211_BAND_5GHZ) {
- b43_nphy_rf_ctl_override(dev, 0x20, 0, 0, false);
- b43_nphy_rf_ctl_override(dev, 0x10, 1, 0, false);
- } else {
- b43_nphy_rf_ctl_override(dev, 0x10, 0, 0, false);
- b43_nphy_rf_ctl_override(dev, 0x20, 1, 0, false);
- }
+ b43_nphy_rf_ctl_override(dev, 0x10, 0, 0, false);
+ b43_nphy_rf_ctl_override(dev, 0x20, 1, 0, false);
}
rx_core_state = b43_nphy_get_rx_core_state(dev);
@@ -1756,11 +1654,8 @@
/* Grab RSSI results for every possible VCM */
for (vcm = 0; vcm < 8; vcm++) {
- if (dev->phy.rev >= 7)
- ;
- else
- b43_radio_maskset(dev, r | B2056_RX_RSSI_MISC,
- 0xE3, vcm << 2);
+ b43_radio_maskset(dev, r | B2056_RX_RSSI_MISC, 0xE3,
+ vcm << 2);
b43_nphy_poll_rssi(dev, N_RSSI_NB, results[vcm], 8);
}
@@ -1787,11 +1682,8 @@
}
/* Select the best VCM */
- if (dev->phy.rev >= 7)
- ;
- else
- b43_radio_maskset(dev, r | B2056_RX_RSSI_MISC,
- 0xE3, vcm_final << 2);
+ b43_radio_maskset(dev, r | B2056_RX_RSSI_MISC, 0xE3,
+ vcm_final << 2);
for (i = 0; i < 4; i++) {
if (core != i / 2)
@@ -1844,9 +1736,9 @@
b43_phy_set(dev, B43_NPHY_RFCTL_OVER, 0x1);
b43_phy_set(dev, B43_NPHY_RFCTL_CMD, B43_NPHY_RFCTL_CMD_RXTX);
- b43_phy_mask(dev, B43_NPHY_RFCTL_OVER, ~0x1);
+ b43_phy_mask(dev, B43_NPHY_TXF_40CO_B1S1, ~0x1);
- for (i = 0; i < regs_amount; i++)
+ for (i = 0; i < ARRAY_SIZE(regs_to_store); i++)
b43_phy_write(dev, regs_to_store[i], saved_regs_phy[i]);
/* Store for future configuration */
@@ -2602,8 +2494,8 @@
struct ssb_sprom *sprom = dev->dev->bus_sprom;
/* TX to RX */
- u8 tx2rx_events[7] = { 0x4, 0x3, 0x5, 0x2, 0x1, 0x8, 0x1F };
- u8 tx2rx_delays[7] = { 8, 4, 4, 4, 4, 6, 1 };
+ u8 tx2rx_events[8] = { 0x4, 0x3, 0x6, 0x5, 0x2, 0x1, 0x8, 0x1F };
+ u8 tx2rx_delays[8] = { 8, 4, 2, 2, 4, 4, 6, 1 };
/* RX to TX */
u8 rx2tx_events_ipa[9] = { 0x0, 0x1, 0x2, 0x8, 0x5, 0x6, 0xF, 0x3,
0x1F };
@@ -2611,23 +2503,6 @@
u8 rx2tx_events[9] = { 0x0, 0x1, 0x2, 0x8, 0x5, 0x6, 0x3, 0x4, 0x1F };
u8 rx2tx_delays[9] = { 8, 6, 6, 4, 4, 18, 42, 1, 1 };
- u16 vmids[5][4] = {
- { 0xa2, 0xb4, 0xb4, 0x89, }, /* 0 */
- { 0xb4, 0xb4, 0xb4, 0x24, }, /* 1 */
- { 0xa2, 0xb4, 0xb4, 0x74, }, /* 2 */
- { 0xa2, 0xb4, 0xb4, 0x270, }, /* 3 */
- { 0xa2, 0xb4, 0xb4, 0x00, }, /* 4 and 5 */
- };
- u16 gains[5][4] = {
- { 0x02, 0x02, 0x02, 0x00, }, /* 0 */
- { 0x02, 0x02, 0x02, 0x02, }, /* 1 */
- { 0x02, 0x02, 0x02, 0x04, }, /* 2 */
- { 0x02, 0x02, 0x02, 0x00, }, /* 3 */
- { 0x02, 0x02, 0x02, 0x00, }, /* 4 and 5 */
- };
- u16 *vmid, *gain;
-
- u8 pdet_range;
u16 tmp16;
u32 tmp32;
@@ -2686,71 +2561,7 @@
b43_ntab_write(dev, B43_NTAB16(8, 0), 2);
b43_ntab_write(dev, B43_NTAB16(8, 16), 2);
- if (b43_current_band(dev->wl) == IEEE80211_BAND_2GHZ)
- pdet_range = sprom->fem.ghz2.pdet_range;
- else
- pdet_range = sprom->fem.ghz5.pdet_range;
- vmid = vmids[min_t(u16, pdet_range, 4)];
- gain = gains[min_t(u16, pdet_range, 4)];
- switch (pdet_range) {
- case 3:
- if (!(dev->phy.rev >= 4 &&
- b43_current_band(dev->wl) == IEEE80211_BAND_2GHZ))
- break;
- /* FALL THROUGH */
- case 0:
- case 1:
- b43_ntab_write_bulk(dev, B43_NTAB16(8, 0x08), 4, vmid);
- b43_ntab_write_bulk(dev, B43_NTAB16(8, 0x18), 4, vmid);
- b43_ntab_write_bulk(dev, B43_NTAB16(8, 0x0c), 4, gain);
- b43_ntab_write_bulk(dev, B43_NTAB16(8, 0x1c), 4, gain);
- break;
- case 2:
- if (dev->phy.rev >= 6) {
- if (b43_current_band(dev->wl) == IEEE80211_BAND_2GHZ)
- vmid[3] = 0x94;
- else
- vmid[3] = 0x8e;
- gain[3] = 3;
- } else if (dev->phy.rev == 5) {
- vmid[3] = 0x84;
- gain[3] = 2;
- }
- b43_ntab_write_bulk(dev, B43_NTAB16(8, 0x08), 4, vmid);
- b43_ntab_write_bulk(dev, B43_NTAB16(8, 0x18), 4, vmid);
- b43_ntab_write_bulk(dev, B43_NTAB16(8, 0x0c), 4, gain);
- b43_ntab_write_bulk(dev, B43_NTAB16(8, 0x1c), 4, gain);
- break;
- case 4:
- case 5:
- if (b43_current_band(dev->wl) != IEEE80211_BAND_2GHZ) {
- if (pdet_range == 4) {
- vmid[3] = 0x8e;
- tmp16 = 0x96;
- gain[3] = 0x2;
- } else {
- vmid[3] = 0x89;
- tmp16 = 0x89;
- gain[3] = 0;
- }
- } else {
- if (pdet_range == 4) {
- vmid[3] = 0x89;
- tmp16 = 0x8b;
- gain[3] = 0x2;
- } else {
- vmid[3] = 0x74;
- tmp16 = 0x70;
- gain[3] = 0;
- }
- }
- b43_ntab_write_bulk(dev, B43_NTAB16(8, 0x08), 4, vmid);
- b43_ntab_write_bulk(dev, B43_NTAB16(8, 0x0c), 4, gain);
- vmid[3] = tmp16;
- b43_ntab_write_bulk(dev, B43_NTAB16(8, 0x18), 4, vmid);
- b43_ntab_write_bulk(dev, B43_NTAB16(8, 0x1c), 4, gain);
- break;
- }
+ /* TODO */
b43_radio_write(dev, B2056_RX0 | B2056_RX_MIXA_MAST_BIAS, 0x00);
b43_radio_write(dev, B2056_RX1 | B2056_RX_MIXA_MAST_BIAS, 0x00);
@@ -2789,7 +2600,7 @@
/* Dropped probably-always-true condition */
b43_phy_write(dev, B43_NPHY_ED_CRS40ASSERTTHRESH0, 0x03eb);
b43_phy_write(dev, B43_NPHY_ED_CRS40ASSERTTHRESH1, 0x03eb);
- b43_phy_write(dev, B43_NPHY_ED_CRS40DEASSERTTHRESH0, 0x0341);
+ b43_phy_write(dev, B43_NPHY_ED_CRS40DEASSERTTHRESH1, 0x0341);
b43_phy_write(dev, B43_NPHY_ED_CRS40DEASSERTTHRESH1, 0x0341);
b43_phy_write(dev, B43_NPHY_ED_CRS20LASSERTTHRESH0, 0x042b);
b43_phy_write(dev, B43_NPHY_ED_CRS20LASSERTTHRESH1, 0x042b);
@@ -3400,20 +3211,6 @@
u8 idx, delta;
u8 i, stf_mode;
- /* Array adj_pwr_tbl corresponds to the hardware table. It consists of
- * 21 groups, each containing 4 entries.
- *
- * First group has entries for CCK modulation.
- * The rest of groups has 1 entry per modulation (SISO, CDD, STBC, SDM).
- *
- * Group 0 is for CCK
- * Groups 1..4 use BPSK (group per coding rate)
- * Groups 5..8 use QPSK (group per coding rate)
- * Groups 9..12 use 16-QAM (group per coding rate)
- * Groups 13..16 use 64-QAM (group per coding rate)
- * Groups 17..20 are unknown
- */
-
for (i = 0; i < 4; i++)
nphy->adj_pwr_tbl[i] = nphy->tx_power_offset[i];
@@ -3612,8 +3409,10 @@
}
b43_nphy_tx_prepare_adjusted_power_table(dev);
+ /*
b43_ntab_write_bulk(dev, B43_NTAB16(26, 64), 84, nphy->adj_pwr_tbl);
b43_ntab_write_bulk(dev, B43_NTAB16(27, 64), 84, nphy->adj_pwr_tbl);
+ */
if (nphy->hang_avoid)
b43_nphy_stay_in_carrier_search(dev, false);
@@ -5325,7 +5124,7 @@
b43_phy_write(dev, B43_NPHY_TXMACIF_HOLDOFF, 0x0015);
b43_phy_write(dev, B43_NPHY_TXMACDELAY, 0x0320);
if (phy->rev >= 3 && phy->rev <= 6)
- b43_phy_write(dev, B43_NPHY_PLOAD_CSENSE_EXTLEN, 0x0032);
+ b43_phy_write(dev, B43_NPHY_PLOAD_CSENSE_EXTLEN, 0x0014);
b43_nphy_tx_lp_fbw(dev);
if (phy->rev >= 3)
b43_nphy_spur_workaround(dev);
@@ -5642,11 +5441,8 @@
{
/* Register 1 is a 32-bit register. */
B43_WARN_ON(reg == 1);
-
- if (dev->phy.rev >= 7)
- reg |= 0x200; /* Radio 0x2057 */
- else
- reg |= 0x100;
+ /* N-PHY needs 0x100 for read access */
+ reg |= 0x100;
b43_write16(dev, B43_MMIO_RADIO_CONTROL, reg);
return b43_read16(dev, B43_MMIO_RADIO_DATA_LOW);
diff --git a/drivers/net/wireless/b43/radio_2056.c b/drivers/net/wireless/b43/radio_2056.c
index a07e4ca..b4fd934 100644
--- a/drivers/net/wireless/b43/radio_2056.c
+++ b/drivers/net/wireless/b43/radio_2056.c
@@ -48,7 +48,7 @@
unsigned int rx_length;
};
-static const struct b2056_inittab_entry b2056_inittab_phy_rev3_syn[] = {
+static const struct b2056_inittab_entry b2056_inittab_rev3_syn[] = {
[B2056_SYN_RESERVED_ADDR2] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
[B2056_SYN_RESERVED_ADDR3] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
[B2056_SYN_RESERVED_ADDR4] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
@@ -232,7 +232,7 @@
[B2056_SYN_LOGEN_TX_CMOS_VALID] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
};
-static const struct b2056_inittab_entry b2056_inittab_phy_rev3_tx[] = {
+static const struct b2056_inittab_entry b2056_inittab_rev3_tx[] = {
[B2056_TX_RESERVED_ADDR2] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
[B2056_TX_RESERVED_ADDR3] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
[B2056_TX_RESERVED_ADDR4] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
@@ -380,7 +380,7 @@
[B2056_TX_STATUS_TXLPF_RC] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
};
-static const struct b2056_inittab_entry b2056_inittab_phy_rev3_rx[] = {
+static const struct b2056_inittab_entry b2056_inittab_rev3_rx[] = {
[B2056_RX_RESERVED_ADDR2] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
[B2056_RX_RESERVED_ADDR3] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
[B2056_RX_RESERVED_ADDR4] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
@@ -530,7 +530,7 @@
[B2056_RX_STATUS_HPC_RC] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
};
-static const struct b2056_inittab_entry b2056_inittab_phy_rev4_syn[] = {
+static const struct b2056_inittab_entry b2056_inittab_rev4_syn[] = {
[B2056_SYN_RESERVED_ADDR2] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
[B2056_SYN_RESERVED_ADDR3] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
[B2056_SYN_RESERVED_ADDR4] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
@@ -714,7 +714,7 @@
[B2056_SYN_LOGEN_TX_CMOS_VALID] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
};
-static const struct b2056_inittab_entry b2056_inittab_phy_rev4_tx[] = {
+static const struct b2056_inittab_entry b2056_inittab_rev4_tx[] = {
[B2056_TX_RESERVED_ADDR2] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
[B2056_TX_RESERVED_ADDR3] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
[B2056_TX_RESERVED_ADDR4] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
@@ -862,7 +862,7 @@
[B2056_TX_STATUS_TXLPF_RC] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
};
-static const struct b2056_inittab_entry b2056_inittab_phy_rev4_rx[] = {
+static const struct b2056_inittab_entry b2056_inittab_rev4_rx[] = {
[B2056_RX_RESERVED_ADDR2] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
[B2056_RX_RESERVED_ADDR3] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
[B2056_RX_RESERVED_ADDR4] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
@@ -1012,7 +1012,7 @@
[B2056_RX_STATUS_HPC_RC] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
};
-static const struct b2056_inittab_entry b2056_inittab_radio_rev5_syn[] = {
+static const struct b2056_inittab_entry b2056_inittab_rev5_syn[] = {
[B2056_SYN_RESERVED_ADDR2] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
[B2056_SYN_RESERVED_ADDR3] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
[B2056_SYN_RESERVED_ADDR4] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
@@ -1196,7 +1196,7 @@
[B2056_SYN_LOGEN_TX_CMOS_VALID] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
};
-static const struct b2056_inittab_entry b2056_inittab_radio_rev5_tx[] = {
+static const struct b2056_inittab_entry b2056_inittab_rev5_tx[] = {
[B2056_TX_RESERVED_ADDR2] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
[B2056_TX_RESERVED_ADDR3] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
[B2056_TX_RESERVED_ADDR4] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
@@ -1352,7 +1352,7 @@
[B2056_TX_GMBB_IDAC7] = { .ghz5 = 0x0075, .ghz2 = 0x0075, UPLOAD, },
};
-static const struct b2056_inittab_entry b2056_inittab_radio_rev5_rx[] = {
+static const struct b2056_inittab_entry b2056_inittab_rev5_rx[] = {
[B2056_RX_RESERVED_ADDR2] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
[B2056_RX_RESERVED_ADDR3] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
[B2056_RX_RESERVED_ADDR4] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
@@ -1502,7 +1502,7 @@
[B2056_RX_STATUS_HPC_RC] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
};
-static const struct b2056_inittab_entry b2056_inittab_radio_rev6_syn[] = {
+static const struct b2056_inittab_entry b2056_inittab_rev6_syn[] = {
[B2056_SYN_RESERVED_ADDR2] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
[B2056_SYN_RESERVED_ADDR3] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
[B2056_SYN_RESERVED_ADDR4] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
@@ -1686,7 +1686,7 @@
[B2056_SYN_LOGEN_TX_CMOS_VALID] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
};
-static const struct b2056_inittab_entry b2056_inittab_radio_rev6_tx[] = {
+static const struct b2056_inittab_entry b2056_inittab_rev6_tx[] = {
[B2056_TX_RESERVED_ADDR2] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
[B2056_TX_RESERVED_ADDR3] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
[B2056_TX_RESERVED_ADDR4] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
@@ -1842,7 +1842,7 @@
[B2056_TX_GMBB_IDAC7] = { .ghz5 = 0x0070, .ghz2 = 0x0070, NOUPLOAD, },
};
-static const struct b2056_inittab_entry b2056_inittab_radio_rev6_rx[] = {
+static const struct b2056_inittab_entry b2056_inittab_rev6_rx[] = {
[B2056_RX_RESERVED_ADDR2] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
[B2056_RX_RESERVED_ADDR3] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
[B2056_RX_RESERVED_ADDR4] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
@@ -1992,7 +1992,7 @@
[B2056_RX_STATUS_HPC_RC] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
};
-static const struct b2056_inittab_entry b2056_inittab_radio_rev7_9_syn[] = {
+static const struct b2056_inittab_entry b2056_inittab_rev7_syn[] = {
[B2056_SYN_RESERVED_ADDR2] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
[B2056_SYN_RESERVED_ADDR3] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
[B2056_SYN_RESERVED_ADDR4] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
@@ -2176,7 +2176,7 @@
[B2056_SYN_LOGEN_TX_CMOS_VALID] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
};
-static const struct b2056_inittab_entry b2056_inittab_radio_rev7_9_tx[] = {
+static const struct b2056_inittab_entry b2056_inittab_rev7_tx[] = {
[B2056_TX_RESERVED_ADDR2] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
[B2056_TX_RESERVED_ADDR3] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
[B2056_TX_RESERVED_ADDR4] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
@@ -2332,7 +2332,7 @@
[B2056_TX_GMBB_IDAC7] = { .ghz5 = 0x0075, .ghz2 = 0x0075, UPLOAD, },
};
-static const struct b2056_inittab_entry b2056_inittab_radio_rev7_9_rx[] = {
+static const struct b2056_inittab_entry b2056_inittab_rev7_rx[] = {
[B2056_RX_RESERVED_ADDR2] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
[B2056_RX_RESERVED_ADDR3] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
[B2056_RX_RESERVED_ADDR4] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
@@ -2482,7 +2482,7 @@
[B2056_RX_STATUS_HPC_RC] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
};
-static const struct b2056_inittab_entry b2056_inittab_radio_rev8_syn[] = {
+static const struct b2056_inittab_entry b2056_inittab_rev8_syn[] = {
[B2056_SYN_RESERVED_ADDR2] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
[B2056_SYN_RESERVED_ADDR3] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
[B2056_SYN_RESERVED_ADDR4] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
@@ -2666,7 +2666,7 @@
[B2056_SYN_LOGEN_TX_CMOS_VALID] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
};
-static const struct b2056_inittab_entry b2056_inittab_radio_rev8_tx[] = {
+static const struct b2056_inittab_entry b2056_inittab_rev8_tx[] = {
[B2056_TX_RESERVED_ADDR2] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
[B2056_TX_RESERVED_ADDR3] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
[B2056_TX_RESERVED_ADDR4] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
@@ -2822,7 +2822,7 @@
[B2056_TX_GMBB_IDAC7] = { .ghz5 = 0x0070, .ghz2 = 0x0070, NOUPLOAD, },
};
-static const struct b2056_inittab_entry b2056_inittab_radio_rev8_rx[] = {
+static const struct b2056_inittab_entry b2056_inittab_rev8_rx[] = {
[B2056_RX_RESERVED_ADDR2] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
[B2056_RX_RESERVED_ADDR3] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
[B2056_RX_RESERVED_ADDR4] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
@@ -2972,68 +2972,23 @@
[B2056_RX_STATUS_HPC_RC] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
};
-static const struct b2056_inittab_entry b2056_inittab_radio_rev11_syn[] = {
- [B2056_SYN_PLL_PFD] = { .ghz5 = 0x0006, .ghz2 = 0x0006, UPLOAD, },
- [B2056_SYN_PLL_CP2] = { .ghz5 = 0x003f, .ghz2 = 0x003f, UPLOAD, },
- [B2056_SYN_PLL_LOOPFILTER1] = { .ghz5 = 0x0006, .ghz2 = 0x0006, UPLOAD, },
- [B2056_SYN_PLL_LOOPFILTER2] = { .ghz5 = 0x0006, .ghz2 = 0x0006, UPLOAD, },
- [B2056_SYN_PLL_LOOPFILTER4] = { .ghz5 = 0x002b, .ghz2 = 0x002b, UPLOAD, },
- [B2056_SYN_PLL_VCO2] = { .ghz5 = 0x00f7, .ghz2 = 0x00f7, UPLOAD, },
- [B2056_SYN_PLL_VCOCAL12] = { .ghz5 = 0x0007, .ghz2 = 0x0007, UPLOAD, },
- [B2056_SYN_LOGENBUF2] = { .ghz5 = 0x008f, .ghz2 = 0x008f, UPLOAD, },
-};
-
-static const struct b2056_inittab_entry b2056_inittab_radio_rev11_tx[] = {
- [B2056_TX_PA_SPARE2] = { .ghz5 = 0x00ee, .ghz2 = 0x00ee, UPLOAD, },
- [B2056_TX_INTPAA_IAUX_STAT] = { .ghz5 = 0x0050, .ghz2 = 0x0050, UPLOAD, },
- [B2056_TX_INTPAA_IMAIN_STAT] = { .ghz5 = 0x0050, .ghz2 = 0x0050, UPLOAD, },
- [B2056_TX_INTPAA_PASLOPE] = { .ghz5 = 0x00f0, .ghz2 = 0x00f0, UPLOAD, },
- [B2056_TX_INTPAG_PASLOPE] = { .ghz5 = 0x00f0, .ghz2 = 0x00f0, UPLOAD, },
- [B2056_TX_PADA_IDAC] = { .ghz5 = 0x00ff, .ghz2 = 0x00ff, UPLOAD, },
- [B2056_TX_PADA_SLOPE] = { .ghz5 = 0x0070, .ghz2 = 0x0070, UPLOAD, },
- [B2056_TX_PADG_SLOPE] = { .ghz5 = 0x0070, .ghz2 = 0x0070, UPLOAD, },
- [B2056_TX_PGAA_IDAC] = { .ghz5 = 0x00ff, .ghz2 = 0x00ff, UPLOAD, },
- [B2056_TX_PGAA_SLOPE] = { .ghz5 = 0x0077, .ghz2 = 0x0077, UPLOAD, },
- [B2056_TX_PGAG_SLOPE] = { .ghz5 = 0x0077, .ghz2 = 0x0077, UPLOAD, },
- [B2056_TX_GMBB_IDAC] = { .ghz5 = 0x0000, .ghz2 = 0x0000, UPLOAD, },
- [B2056_TX_TXSPARE1] = { .ghz5 = 0x0030, .ghz2 = 0x0030, UPLOAD, },
-};
-
-static const struct b2056_inittab_entry b2056_inittab_radio_rev11_rx[] = {
- [B2056_RX_BIASPOLE_LNAA1_IDAC] = { .ghz5 = 0x0017, .ghz2 = 0x0017, UPLOAD, },
- [B2056_RX_LNAA2_IDAC] = { .ghz5 = 0x00ff, .ghz2 = 0x00ff, UPLOAD, },
- [B2056_RX_BIASPOLE_LNAG1_IDAC] = { .ghz5 = 0x0017, .ghz2 = 0x0017, UPLOAD, },
- [B2056_RX_LNAG2_IDAC] = { .ghz5 = 0x00f0, .ghz2 = 0x00f0, UPLOAD, },
- [B2056_RX_MIXA_VCM] = { .ghz5 = 0x0055, .ghz2 = 0x0055, UPLOAD, },
- [B2056_RX_MIXA_LOB_BIAS] = { .ghz5 = 0x0088, .ghz2 = 0x0088, UPLOAD, },
- [B2056_RX_MIXA_BIAS_AUX] = { .ghz5 = 0x0007, .ghz2 = 0x0007, UPLOAD, },
- [B2056_RX_MIXG_VCM] = { .ghz5 = 0x0055, .ghz2 = 0x0055, UPLOAD, },
- [B2056_RX_TIA_IOPAMP] = { .ghz5 = 0x0026, .ghz2 = 0x0026, UPLOAD, },
- [B2056_RX_TIA_QOPAMP] = { .ghz5 = 0x0026, .ghz2 = 0x0026, UPLOAD, },
- [B2056_RX_TIA_IMISC] = { .ghz5 = 0x000f, .ghz2 = 0x000f, UPLOAD, },
- [B2056_RX_TIA_QMISC] = { .ghz5 = 0x000f, .ghz2 = 0x000f, UPLOAD, },
- [B2056_RX_RXLPF_OUTVCM] = { .ghz5 = 0x0004, .ghz2 = 0x0004, UPLOAD, },
- [B2056_RX_VGA_BIAS_DCCANCEL] = { .ghz5 = 0x0000, .ghz2 = 0x0000, UPLOAD, },
- [B2056_RX_RXSPARE3] = { .ghz5 = 0x0005, .ghz2 = 0x0005, UPLOAD, },
-};
-
#define INITTABSPTS(prefix) \
- static const struct b2056_inittabs_pts prefix = { \
- .syn = prefix##_syn, \
- .syn_length = ARRAY_SIZE(prefix##_syn), \
- .tx = prefix##_tx, \
- .tx_length = ARRAY_SIZE(prefix##_tx), \
- .rx = prefix##_rx, \
- .rx_length = ARRAY_SIZE(prefix##_rx), \
- }
+ .syn = prefix##_syn, \
+ .syn_length = ARRAY_SIZE(prefix##_syn), \
+ .tx = prefix##_tx, \
+ .tx_length = ARRAY_SIZE(prefix##_tx), \
+ .rx = prefix##_rx, \
+ .rx_length = ARRAY_SIZE(prefix##_rx)
-INITTABSPTS(b2056_inittab_phy_rev3);
-INITTABSPTS(b2056_inittab_phy_rev4);
-INITTABSPTS(b2056_inittab_radio_rev5);
-INITTABSPTS(b2056_inittab_radio_rev6);
-INITTABSPTS(b2056_inittab_radio_rev7_9);
-INITTABSPTS(b2056_inittab_radio_rev8);
-INITTABSPTS(b2056_inittab_radio_rev11);
+static const struct b2056_inittabs_pts b2056_inittabs[] = {
+ [3] = { INITTABSPTS(b2056_inittab_rev3) },
+ [4] = { INITTABSPTS(b2056_inittab_rev4) },
+ [5] = { INITTABSPTS(b2056_inittab_rev5) },
+ [6] = { INITTABSPTS(b2056_inittab_rev6) },
+ [7] = { INITTABSPTS(b2056_inittab_rev7) },
+ [8] = { INITTABSPTS(b2056_inittab_rev8) },
+ [9] = { INITTABSPTS(b2056_inittab_rev7) },
+};
#define RADIOREGS3(r00, r01, r02, r03, r04, r05, r06, r07, r08, r09, \
r10, r11, r12, r13, r14, r15, r16, r17, r18, r19, \
@@ -3086,7 +3041,7 @@
.phy_regs.phy_bw6 = r5
/* http://bcm-v4.sipsolutions.net/802.11/Radio/2056/ChannelTable */
-static const struct b43_nphy_channeltab_entry_rev3 b43_nphy_channeltab_phy_rev3[] = {
+static const struct b43_nphy_channeltab_entry_rev3 b43_nphy_channeltab_rev3[] = {
{ .freq = 4920,
RADIOREGS3(0xff, 0x01, 0x01, 0x01, 0xec, 0x05, 0x05, 0x04,
0x0c, 0x01, 0x00, 0x00, 0x00, 0x8f, 0x0f, 0x00,
@@ -4081,7 +4036,7 @@
},
};
-static const struct b43_nphy_channeltab_entry_rev3 b43_nphy_channeltab_phy_rev4[] = {
+static const struct b43_nphy_channeltab_entry_rev3 b43_nphy_channeltab_rev4[] = {
{ .freq = 4920,
RADIOREGS3(0xff, 0x01, 0x01, 0x01, 0xec, 0x05, 0x05, 0x04,
0x0c, 0x01, 0x00, 0x00, 0x00, 0x8f, 0x0f, 0x00,
@@ -5076,7 +5031,7 @@
},
};
-static const struct b43_nphy_channeltab_entry_rev3 b43_nphy_channeltab_radio_rev5[] = {
+static const struct b43_nphy_channeltab_entry_rev3 b43_nphy_channeltab_rev5[] = {
{ .freq = 4920,
RADIOREGS3(0xff, 0x01, 0x01, 0x01, 0xec, 0x05, 0x05, 0x04,
0x0c, 0x01, 0x00, 0x00, 0x00, 0x8f, 0x0f, 0x00,
@@ -6071,7 +6026,7 @@
},
};
-static const struct b43_nphy_channeltab_entry_rev3 b43_nphy_channeltab_radio_rev6[] = {
+static const struct b43_nphy_channeltab_entry_rev3 b43_nphy_channeltab_rev6[] = {
{ .freq = 4920,
RADIOREGS3(0xff, 0x01, 0x01, 0x01, 0xec, 0x05, 0x05, 0x04,
0x0c, 0x01, 0x00, 0x00, 0x00, 0x8f, 0x0f, 0x00,
@@ -7066,7 +7021,7 @@
},
};
-static const struct b43_nphy_channeltab_entry_rev3 b43_nphy_channeltab_radio_rev7_9[] = {
+static const struct b43_nphy_channeltab_entry_rev3 b43_nphy_channeltab_rev7_9[] = {
{ .freq = 4920,
RADIOREGS3(0xff, 0x01, 0x01, 0x01, 0xec, 0x05, 0x05, 0x04,
0x0c, 0x01, 0x00, 0x00, 0x00, 0x8f, 0x0f, 0x00,
@@ -8061,7 +8016,7 @@
},
};
-static const struct b43_nphy_channeltab_entry_rev3 b43_nphy_channeltab_radio_rev8[] = {
+static const struct b43_nphy_channeltab_entry_rev3 b43_nphy_channeltab_rev8[] = {
{ .freq = 4920,
RADIOREGS3(0xff, 0x01, 0x01, 0x01, 0xec, 0x05, 0x05, 0x04,
0x0c, 0x01, 0x00, 0x00, 0x00, 0x8f, 0x0f, 0x00,
@@ -9056,236 +9011,6 @@
},
};
-static const struct b43_nphy_channeltab_entry_rev3 b43_nphy_channeltab_radio_rev11[] = {
- {
- .freq = 5180,
- RADIOREGS3(0xb6, 0x01, 0x01, 0x02, 0x06, 0x05, 0x05, 0x02,
- 0x0c, 0x01, 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00,
- 0xff, 0xf9, 0x00, 0x06, 0x00, 0x77, 0x00, 0x0e,
- 0x00, 0x6f, 0x00, 0xf9, 0x00, 0x06, 0x00, 0x77,
- 0x00, 0x0e, 0x00, 0x6f, 0x00),
- PHYREGS(0x081c, 0x0818, 0x0814, 0x01f9, 0x01fa, 0x01fb),
- },
- {
- .freq = 5200,
- RADIOREGS3(0xaf, 0x01, 0x01, 0x02, 0x08, 0x05, 0x05, 0x02,
- 0x0c, 0x01, 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00,
- 0xff, 0xf9, 0x00, 0x05, 0x00, 0x77, 0x00, 0x0d,
- 0x00, 0x6f, 0x00, 0xf9, 0x00, 0x05, 0x00, 0x77,
- 0x00, 0x0d, 0x00, 0x6f, 0x00),
- PHYREGS(0x0824, 0x0820, 0x081c, 0x01f7, 0x01f8, 0x01f9),
- },
- {
- .freq = 5220,
- RADIOREGS3(0xa7, 0x01, 0x01, 0x02, 0x0a, 0x05, 0x05, 0x02,
- 0x0c, 0x01, 0x02, 0x02, 0x02, 0x8e, 0x0f, 0x00,
- 0xfe, 0xd8, 0x00, 0x05, 0x00, 0x77, 0x00, 0x0d,
- 0x00, 0x6f, 0x00, 0xd8, 0x00, 0x05, 0x00, 0x77,
- 0x00, 0x0d, 0x00, 0x6f, 0x00),
- PHYREGS(0x082c, 0x0828, 0x0824, 0x01f5, 0x01f6, 0x01f7),
- },
- {
- .freq = 5745,
- RADIOREGS3(0xfe, 0x00, 0x02, 0x04, 0x7d, 0x05, 0x05, 0x02,
- 0x15, 0x01, 0x05, 0x05, 0x05, 0x87, 0x05, 0x00,
- 0x20, 0x30, 0x00, 0x00, 0x00, 0x77, 0x00, 0x06,
- 0x00, 0x6d, 0x00, 0x30, 0x00, 0x00, 0x00, 0x77,
- 0x00, 0x06, 0x00, 0x6d, 0x00),
- PHYREGS(0x08fe, 0x08fa, 0x08f6, 0x01c8, 0x01c8, 0x01c9),
- },
- {
- .freq = 5765,
- RADIOREGS3(0xf8, 0x00, 0x02, 0x04, 0x81, 0x05, 0x05, 0x02,
- 0x15, 0x01, 0x05, 0x05, 0x05, 0x86, 0x05, 0x00,
- 0x10, 0x10, 0x00, 0x00, 0x00, 0x77, 0x00, 0x05,
- 0x00, 0x6c, 0x00, 0x10, 0x00, 0x00, 0x00, 0x77,
- 0x00, 0x05, 0x00, 0x6c, 0x00),
- PHYREGS(0x0906, 0x0902, 0x08fe, 0x01c6, 0x01c7, 0x01c8),
- },
- {
- .freq = 5785,
- RADIOREGS3(0xf2, 0x00, 0x02, 0x04, 0x85, 0x05, 0x05, 0x02,
- 0x15, 0x01, 0x06, 0x06, 0x06, 0x86, 0x04, 0x00,
- 0x00, 0x10, 0x00, 0x00, 0x00, 0x77, 0x00, 0x05,
- 0x00, 0x6b, 0x00, 0x10, 0x00, 0x00, 0x00, 0x77,
- 0x00, 0x05, 0x00, 0x6b, 0x00),
- PHYREGS(0x090e, 0x090a, 0x0906, 0x01c4, 0x01c5, 0x01c6),
- },
- {
- .freq = 5805,
- RADIOREGS3(0xed, 0x00, 0x02, 0x04, 0x89, 0x05, 0x05, 0x02,
- 0x15, 0x01, 0x06, 0x06, 0x06, 0x86, 0x04, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x77, 0x00, 0x05,
- 0x00, 0x6a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77,
- 0x00, 0x05, 0x00, 0x6a, 0x00),
- PHYREGS(0x0916, 0x0912, 0x090e, 0x01c3, 0x01c4, 0x01c4),
- },
- {
- .freq = 5825,
- RADIOREGS3(0xed, 0x00, 0x02, 0x04, 0x8d, 0x05, 0x05, 0x02,
- 0x15, 0x01, 0x06, 0x06, 0x06, 0x86, 0x04, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x77, 0x00, 0x05,
- 0x00, 0x69, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77,
- 0x00, 0x05, 0x00, 0x69, 0x00),
- PHYREGS(0x091e, 0x091a, 0x0916, 0x01c1, 0x01c2, 0x01c3),
- },
- {
- .freq = 2412,
- RADIOREGS3(0x00, 0x01, 0x03, 0x09, 0x6c, 0x06, 0x06, 0x04,
- 0x2b, 0x01, 0x04, 0x04, 0x04, 0x8f, 0x30, 0x00,
- 0x00, 0x00, 0x78, 0x00, 0x03, 0x00, 0x70, 0x00,
- 0x0b, 0x00, 0x0a, 0x00, 0x89, 0x00, 0x03, 0x00,
- 0x70, 0x00, 0x0b, 0x00, 0x0a),
- PHYREGS(0x03c9, 0x03c5, 0x03c1, 0x043a, 0x043f, 0x0443),
- },
- {
- .freq = 2417,
- RADIOREGS3(0x00, 0x01, 0x03, 0x09, 0x71, 0x06, 0x06, 0x04,
- 0x2b, 0x01, 0x05, 0x05, 0x05, 0x8f, 0x30, 0x00,
- 0x00, 0x00, 0x78, 0x00, 0x03, 0x00, 0x70, 0x00,
- 0x0b, 0x00, 0x0a, 0x00, 0x89, 0x00, 0x03, 0x00,
- 0x70, 0x00, 0x0b, 0x00, 0x0a),
- PHYREGS(0x03cb, 0x03c7, 0x03c3, 0x0438, 0x043d, 0x0441),
- },
- {
- .freq = 2422,
- RADIOREGS3(0x00, 0x01, 0x03, 0x09, 0x76, 0x06, 0x06, 0x04,
- 0x2b, 0x01, 0x05, 0x05, 0x05, 0x8f, 0x30, 0x00,
- 0x00, 0x00, 0x67, 0x00, 0x03, 0x00, 0x70, 0x00,
- 0x0b, 0x00, 0x0a, 0x00, 0x89, 0x00, 0x03, 0x00,
- 0x70, 0x00, 0x0b, 0x00, 0x0a),
- PHYREGS(0x03cd, 0x03c9, 0x03c5, 0x0436, 0x043a, 0x043f),
- },
- {
- .freq = 2427,
- RADIOREGS3(0x00, 0x01, 0x03, 0x09, 0x7b, 0x06, 0x06, 0x04,
- 0x2b, 0x01, 0x05, 0x05, 0x05, 0x8f, 0x30, 0x00,
- 0x00, 0x00, 0x57, 0x00, 0x03, 0x00, 0x70, 0x00,
- 0x0a, 0x00, 0x0a, 0x00, 0x78, 0x00, 0x03, 0x00,
- 0x70, 0x00, 0x0a, 0x00, 0x0a),
- PHYREGS(0x03cf, 0x03cb, 0x03c7, 0x0434, 0x0438, 0x043d),
- },
- {
- .freq = 2432,
- RADIOREGS3(0x00, 0x01, 0x03, 0x09, 0x80, 0x06, 0x06, 0x04,
- 0x2b, 0x01, 0x05, 0x05, 0x05, 0x8f, 0x30, 0x00,
- 0x00, 0x00, 0x56, 0x00, 0x03, 0x00, 0x70, 0x00,
- 0x0a, 0x00, 0x0a, 0x00, 0x77, 0x00, 0x03, 0x00,
- 0x70, 0x00, 0x0a, 0x00, 0x0a),
- PHYREGS(0x03d1, 0x03cd, 0x03c9, 0x0431, 0x0436, 0x043a),
- },
- {
- .freq = 2437,
- RADIOREGS3(0x00, 0x01, 0x03, 0x09, 0x85, 0x06, 0x06, 0x04,
- 0x2b, 0x01, 0x05, 0x05, 0x05, 0x8f, 0x30, 0x00,
- 0x00, 0x00, 0x46, 0x00, 0x03, 0x00, 0x70, 0x00,
- 0x0a, 0x00, 0x0a, 0x00, 0x76, 0x00, 0x03, 0x00,
- 0x70, 0x00, 0x0a, 0x00, 0x0a),
- PHYREGS(0x03d3, 0x03cf, 0x03cb, 0x042f, 0x0434, 0x0438),
- },
- {
- .freq = 2442,
- RADIOREGS3(0x00, 0x01, 0x03, 0x09, 0x8a, 0x06, 0x06, 0x04,
- 0x2b, 0x01, 0x05, 0x05, 0x05, 0x8f, 0x30, 0x00,
- 0x00, 0x00, 0x45, 0x00, 0x02, 0x00, 0x70, 0x00,
- 0x0a, 0x00, 0x0a, 0x00, 0x66, 0x00, 0x02, 0x00,
- 0x70, 0x00, 0x0a, 0x00, 0x0a),
- PHYREGS(0x03d5, 0x03d1, 0x03cd, 0x042d, 0x0431, 0x0436),
- },
- {
- .freq = 2447,
- RADIOREGS3(0x00, 0x01, 0x03, 0x09, 0x8f, 0x06, 0x06, 0x04,
- 0x2b, 0x01, 0x06, 0x06, 0x06, 0x8f, 0x30, 0x00,
- 0x00, 0x00, 0x34, 0x00, 0x02, 0x00, 0x70, 0x00,
- 0x0a, 0x00, 0x09, 0x00, 0x55, 0x00, 0x02, 0x00,
- 0x70, 0x00, 0x0a, 0x00, 0x09),
- PHYREGS(0x03d7, 0x03d3, 0x03cf, 0x042b, 0x042f, 0x0434),
- },
- {
- .freq = 2452,
- RADIOREGS3(0x00, 0x01, 0x03, 0x09, 0x94, 0x06, 0x06, 0x04,
- 0x2b, 0x01, 0x06, 0x06, 0x06, 0x8f, 0x30, 0x00,
- 0x00, 0x00, 0x23, 0x00, 0x02, 0x00, 0x70, 0x00,
- 0x0a, 0x00, 0x09, 0x00, 0x45, 0x00, 0x02, 0x00,
- 0x70, 0x00, 0x0a, 0x00, 0x09),
- PHYREGS(0x03d9, 0x03d5, 0x03d1, 0x0429, 0x042d, 0x0431),
- },
- {
- .freq = 2457,
- RADIOREGS3(0x00, 0x01, 0x03, 0x09, 0x99, 0x06, 0x06, 0x04,
- 0x2b, 0x01, 0x06, 0x06, 0x06, 0x8f, 0x30, 0x00,
- 0x00, 0x00, 0x12, 0x00, 0x02, 0x00, 0x70, 0x00,
- 0x0a, 0x00, 0x09, 0x00, 0x34, 0x00, 0x02, 0x00,
- 0x70, 0x00, 0x0a, 0x00, 0x09),
- PHYREGS(0x03db, 0x03d7, 0x03d3, 0x0427, 0x042b, 0x042f),
- },
- {
- .freq = 2462,
- RADIOREGS3(0x00, 0x01, 0x03, 0x09, 0x9e, 0x06, 0x06, 0x04,
- 0x2b, 0x01, 0x06, 0x06, 0x06, 0x8f, 0x30, 0x00,
- 0x00, 0x00, 0x02, 0x00, 0x02, 0x00, 0x70, 0x00,
- 0x09, 0x00, 0x09, 0x00, 0x33, 0x00, 0x02, 0x00,
- 0x70, 0x00, 0x09, 0x00, 0x09),
- PHYREGS(0x03dd, 0x03d9, 0x03d5, 0x0424, 0x0429, 0x042d),
- },
- {
- .freq = 2467,
- RADIOREGS3(0x00, 0x01, 0x03, 0x09, 0xa3, 0x06, 0x06, 0x04,
- 0x2b, 0x01, 0x06, 0x06, 0x06, 0x8f, 0x30, 0x00,
- 0x00, 0x00, 0x01, 0x00, 0x02, 0x00, 0x70, 0x00,
- 0x09, 0x00, 0x09, 0x00, 0x22, 0x00, 0x02, 0x00,
- 0x70, 0x00, 0x09, 0x00, 0x09),
- PHYREGS(0x03df, 0x03db, 0x03d7, 0x0422, 0x0427, 0x042b),
- },
- {
- .freq = 2472,
- RADIOREGS3(0x00, 0x01, 0x03, 0x09, 0xa8, 0x06, 0x06, 0x04,
- 0x2b, 0x01, 0x07, 0x07, 0x07, 0x8f, 0x30, 0x00,
- 0x00, 0x00, 0x01, 0x00, 0x02, 0x00, 0x70, 0x00,
- 0x09, 0x00, 0x09, 0x00, 0x11, 0x00, 0x02, 0x00,
- 0x70, 0x00, 0x09, 0x00, 0x09),
- PHYREGS(0x03e1, 0x03dd, 0x03d9, 0x0420, 0x0424, 0x0429),
- },
- {
- .freq = 2484,
- RADIOREGS3(0xff, 0x01, 0x03, 0x09, 0xb4, 0x06, 0x06, 0x04,
- 0x2b, 0x01, 0x07, 0x07, 0x07, 0x8f, 0x20, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x70, 0x00,
- 0x09, 0x00, 0x09, 0x00, 0x00, 0x00, 0x02, 0x00,
- 0x70, 0x00, 0x09, 0x00, 0x09),
- PHYREGS(0x03e6, 0x03e2, 0x03de, 0x041b, 0x041f, 0x0424),
- },
-};
-
-static const struct b2056_inittabs_pts
-*b43_nphy_get_inittabs_rev3(struct b43_wldev *dev)
-{
- struct b43_phy *phy = &dev->phy;
-
- switch (dev->phy.rev) {
- case 3:
- return &b2056_inittab_phy_rev3;
- case 4:
- return &b2056_inittab_phy_rev4;
- default:
- switch (phy->radio_rev) {
- case 5:
- return &b2056_inittab_radio_rev5;
- case 6:
- return &b2056_inittab_radio_rev6;
- case 7:
- case 9:
- return &b2056_inittab_radio_rev7_9;
- case 8:
- return &b2056_inittab_radio_rev8;
- case 11:
- return &b2056_inittab_radio_rev11;
- }
- }
-
- return NULL;
-}
-
static void b2056_upload_inittab(struct b43_wldev *dev, bool ghz5,
bool ignore_uploadflag, u16 routing,
const struct b2056_inittab_entry *e,
@@ -9312,11 +9037,11 @@
{
const struct b2056_inittabs_pts *pts;
- pts = b43_nphy_get_inittabs_rev3(dev);
- if (!pts) {
+ if (dev->phy.rev >= ARRAY_SIZE(b2056_inittabs)) {
B43_WARN_ON(1);
return;
}
+ pts = &b2056_inittabs[dev->phy.rev];
b2056_upload_inittab(dev, ghz5, ignore_uploadflag,
B2056_SYN, pts->syn, pts->syn_length);
@@ -9335,12 +9060,11 @@
const struct b2056_inittabs_pts *pts;
const struct b2056_inittab_entry *e;
- pts = b43_nphy_get_inittabs_rev3(dev);
- if (!pts) {
+ if (dev->phy.rev >= ARRAY_SIZE(b2056_inittabs)) {
B43_WARN_ON(1);
return;
}
-
+ pts = &b2056_inittabs[dev->phy.rev];
e = &pts->syn[B2056_SYN_PLL_CP2];
b43_radio_write(dev, B2056_SYN_PLL_CP2, ghz5 ? e->ghz5 : e->ghz2);
@@ -9349,46 +9073,38 @@
const struct b43_nphy_channeltab_entry_rev3 *
b43_nphy_get_chantabent_rev3(struct b43_wldev *dev, u16 freq)
{
- struct b43_phy *phy = &dev->phy;
const struct b43_nphy_channeltab_entry_rev3 *e;
unsigned int length, i;
- switch (phy->rev) {
+ switch (dev->phy.rev) {
case 3:
- e = b43_nphy_channeltab_phy_rev3;
- length = ARRAY_SIZE(b43_nphy_channeltab_phy_rev3);
+ e = b43_nphy_channeltab_rev3;
+ length = ARRAY_SIZE(b43_nphy_channeltab_rev3);
break;
case 4:
- e = b43_nphy_channeltab_phy_rev4;
- length = ARRAY_SIZE(b43_nphy_channeltab_phy_rev4);
+ e = b43_nphy_channeltab_rev4;
+ length = ARRAY_SIZE(b43_nphy_channeltab_rev4);
+ break;
+ case 5:
+ e = b43_nphy_channeltab_rev5;
+ length = ARRAY_SIZE(b43_nphy_channeltab_rev5);
+ break;
+ case 6:
+ e = b43_nphy_channeltab_rev6;
+ length = ARRAY_SIZE(b43_nphy_channeltab_rev6);
+ break;
+ case 7:
+ case 9:
+ e = b43_nphy_channeltab_rev7_9;
+ length = ARRAY_SIZE(b43_nphy_channeltab_rev7_9);
+ break;
+ case 8:
+ e = b43_nphy_channeltab_rev8;
+ length = ARRAY_SIZE(b43_nphy_channeltab_rev8);
break;
default:
- switch (phy->radio_rev) {
- case 5:
- e = b43_nphy_channeltab_radio_rev5;
- length = ARRAY_SIZE(b43_nphy_channeltab_radio_rev5);
- break;
- case 6:
- e = b43_nphy_channeltab_radio_rev6;
- length = ARRAY_SIZE(b43_nphy_channeltab_radio_rev6);
- break;
- case 7:
- case 9:
- e = b43_nphy_channeltab_radio_rev7_9;
- length = ARRAY_SIZE(b43_nphy_channeltab_radio_rev7_9);
- break;
- case 8:
- e = b43_nphy_channeltab_radio_rev8;
- length = ARRAY_SIZE(b43_nphy_channeltab_radio_rev8);
- break;
- case 11:
- e = b43_nphy_channeltab_radio_rev11;
- length = ARRAY_SIZE(b43_nphy_channeltab_radio_rev11);
- break;
- default:
- B43_WARN_ON(1);
- return NULL;
- }
+ B43_WARN_ON(1);
+ return NULL;
}
for (i = 0; i < length; i++, e++) {
diff --git a/drivers/net/wireless/b43/tables_nphy.c b/drivers/net/wireless/b43/tables_nphy.c
index 50d03ff..94c755f 100644
--- a/drivers/net/wireless/b43/tables_nphy.c
+++ b/drivers/net/wireless/b43/tables_nphy.c
@@ -1627,7 +1627,74 @@
0xfa58fc00, 0x0b64fc7e, 0x0800f7b6, 0x00f006be,
};
-static const u32 b43_ntab_noisevar_r3[] = {
+static const u32 b43_ntab_noisevar0_r3[] = {
+ 0x02110211, 0x0000014d, 0x02110211, 0x0000014d,
+ 0x02110211, 0x0000014d, 0x02110211, 0x0000014d,
+ 0x02110211, 0x0000014d, 0x02110211, 0x0000014d,
+ 0x02110211, 0x0000014d, 0x02110211, 0x0000014d,
+ 0x02110211, 0x0000014d, 0x02110211, 0x0000014d,
+ 0x02110211, 0x0000014d, 0x02110211, 0x0000014d,
+ 0x02110211, 0x0000014d, 0x02110211, 0x0000014d,
+ 0x02110211, 0x0000014d, 0x02110211, 0x0000014d,
+ 0x02110211, 0x0000014d, 0x02110211, 0x0000014d,
+ 0x02110211, 0x0000014d, 0x02110211, 0x0000014d,
+ 0x02110211, 0x0000014d, 0x02110211, 0x0000014d,
+ 0x02110211, 0x0000014d, 0x02110211, 0x0000014d,
+ 0x02110211, 0x0000014d, 0x02110211, 0x0000014d,
+ 0x02110211, 0x0000014d, 0x02110211, 0x0000014d,
+ 0x02110211, 0x0000014d, 0x02110211, 0x0000014d,
+ 0x02110211, 0x0000014d, 0x02110211, 0x0000014d,
+ 0x02110211, 0x0000014d, 0x02110211, 0x0000014d,
+ 0x02110211, 0x0000014d, 0x02110211, 0x0000014d,
+ 0x02110211, 0x0000014d, 0x02110211, 0x0000014d,
+ 0x02110211, 0x0000014d, 0x02110211, 0x0000014d,
+ 0x02110211, 0x0000014d, 0x02110211, 0x0000014d,
+ 0x02110211, 0x0000014d, 0x02110211, 0x0000014d,
+ 0x02110211, 0x0000014d, 0x02110211, 0x0000014d,
+ 0x02110211, 0x0000014d, 0x02110211, 0x0000014d,
+ 0x02110211, 0x0000014d, 0x02110211, 0x0000014d,
+ 0x02110211, 0x0000014d, 0x02110211, 0x0000014d,
+ 0x02110211, 0x0000014d, 0x02110211, 0x0000014d,
+ 0x02110211, 0x0000014d, 0x02110211, 0x0000014d,
+ 0x02110211, 0x0000014d, 0x02110211, 0x0000014d,
+ 0x02110211, 0x0000014d, 0x02110211, 0x0000014d,
+ 0x02110211, 0x0000014d, 0x02110211, 0x0000014d,
+ 0x02110211, 0x0000014d, 0x02110211, 0x0000014d,
+ 0x02110211, 0x0000014d, 0x02110211, 0x0000014d,
+ 0x02110211, 0x0000014d, 0x02110211, 0x0000014d,
+ 0x02110211, 0x0000014d, 0x02110211, 0x0000014d,
+ 0x02110211, 0x0000014d, 0x02110211, 0x0000014d,
+ 0x02110211, 0x0000014d, 0x02110211, 0x0000014d,
+ 0x02110211, 0x0000014d, 0x02110211, 0x0000014d,
+ 0x02110211, 0x0000014d, 0x02110211, 0x0000014d,
+ 0x02110211, 0x0000014d, 0x02110211, 0x0000014d,
+ 0x02110211, 0x0000014d, 0x02110211, 0x0000014d,
+ 0x02110211, 0x0000014d, 0x02110211, 0x0000014d,
+ 0x02110211, 0x0000014d, 0x02110211, 0x0000014d,
+ 0x02110211, 0x0000014d, 0x02110211, 0x0000014d,
+ 0x02110211, 0x0000014d, 0x02110211, 0x0000014d,
+ 0x02110211, 0x0000014d, 0x02110211, 0x0000014d,
+ 0x02110211, 0x0000014d, 0x02110211, 0x0000014d,
+ 0x02110211, 0x0000014d, 0x02110211, 0x0000014d,
+ 0x02110211, 0x0000014d, 0x02110211, 0x0000014d,
+ 0x02110211, 0x0000014d, 0x02110211, 0x0000014d,
+ 0x02110211, 0x0000014d, 0x02110211, 0x0000014d,
+ 0x02110211, 0x0000014d, 0x02110211, 0x0000014d,
+ 0x02110211, 0x0000014d, 0x02110211, 0x0000014d,
+ 0x02110211, 0x0000014d, 0x02110211, 0x0000014d,
+ 0x02110211, 0x0000014d, 0x02110211, 0x0000014d,
+ 0x02110211, 0x0000014d, 0x02110211, 0x0000014d,
+ 0x02110211, 0x0000014d, 0x02110211, 0x0000014d,
+ 0x02110211, 0x0000014d, 0x02110211, 0x0000014d,
+ 0x02110211, 0x0000014d, 0x02110211, 0x0000014d,
+ 0x02110211, 0x0000014d, 0x02110211, 0x0000014d,
+ 0x02110211, 0x0000014d, 0x02110211, 0x0000014d,
+ 0x02110211, 0x0000014d, 0x02110211, 0x0000014d,
+ 0x02110211, 0x0000014d, 0x02110211, 0x0000014d,
+ 0x02110211, 0x0000014d, 0x02110211, 0x0000014d,
+};
+
+static const u32 b43_ntab_noisevar1_r3[] = {
0x02110211, 0x0000014d, 0x02110211, 0x0000014d,
0x02110211, 0x0000014d, 0x02110211, 0x0000014d,
0x02110211, 0x0000014d, 0x02110211, 0x0000014d,
@@ -3047,7 +3114,8 @@
ntab_upload(dev, B43_NTAB_TMAP_R3, b43_ntab_tmap_r3);
ntab_upload(dev, B43_NTAB_INTLEVEL_R3, b43_ntab_intlevel_r3);
ntab_upload(dev, B43_NTAB_TDTRN_R3, b43_ntab_tdtrn_r3);
- ntab_upload(dev, B43_NTAB_NOISEVAR_R3, b43_ntab_noisevar_r3);
+ ntab_upload(dev, B43_NTAB_NOISEVAR0_R3, b43_ntab_noisevar0_r3);
+ ntab_upload(dev, B43_NTAB_NOISEVAR1_R3, b43_ntab_noisevar1_r3);
ntab_upload(dev, B43_NTAB_MCS_R3, b43_ntab_mcs_r3);
ntab_upload(dev, B43_NTAB_TDI20A0_R3, b43_ntab_tdi20a0_r3);
ntab_upload(dev, B43_NTAB_TDI20A1_R3, b43_ntab_tdi20a1_r3);
diff --git a/drivers/net/wireless/b43/tables_nphy.h b/drivers/net/wireless/b43/tables_nphy.h
index 3a58aee..9ff33ad 100644
--- a/drivers/net/wireless/b43/tables_nphy.h
+++ b/drivers/net/wireless/b43/tables_nphy.h
@@ -143,7 +143,8 @@
#define B43_NTAB_TMAP_R3 B43_NTAB32(12, 0) /* TM AP */
#define B43_NTAB_INTLEVEL_R3 B43_NTAB32(13, 0) /* INT LV */
#define B43_NTAB_TDTRN_R3 B43_NTAB32(14, 0) /* TD TRN */
-#define B43_NTAB_NOISEVAR_R3 B43_NTAB32(16, 0) /* noise variance */
+#define B43_NTAB_NOISEVAR0_R3 B43_NTAB32(16, 0) /* noise variance 0 */
+#define B43_NTAB_NOISEVAR1_R3 B43_NTAB32(16, 128) /* noise variance 1 */
#define B43_NTAB_MCS_R3 B43_NTAB16(18, 0) /* MCS */
#define B43_NTAB_TDI20A0_R3 B43_NTAB32(19, 128) /* TDI 20/0 */
#define B43_NTAB_TDI20A1_R3 B43_NTAB32(19, 256) /* TDI 20/1 */
diff --git a/drivers/net/wireless/b43/wa.c b/drivers/net/wireless/b43/wa.c
index c218c08..9b1a038 100644
--- a/drivers/net/wireless/b43/wa.c
+++ b/drivers/net/wireless/b43/wa.c
@@ -441,7 +441,7 @@
static void b43_wa_tr_ltov(struct b43_wldev *dev) /* TR Lookup Table Original Values */
{
- b43_gtab_write(dev, B43_GTAB_ORIGTR, 0, 0x7654);
+ b43_gtab_write(dev, B43_GTAB_ORIGTR, 0, 0xC480);
}
static void b43_wa_cpll_nonpilot(struct b43_wldev *dev)
diff --git a/drivers/net/wireless/b43/xmit.c b/drivers/net/wireless/b43/xmit.c
index 31adb8c..22d050f 100644
--- a/drivers/net/wireless/b43/xmit.c
+++ b/drivers/net/wireless/b43/xmit.c
@@ -811,9 +811,13 @@
break;
case B43_PHYTYPE_G:
status.band = IEEE80211_BAND_2GHZ;
- /* chanid is the radio channel cookie value as used
- * to tune the radio. */
- status.freq = chanid + 2400;
+ /* Somewhere between 478.104 and 508.1084 firmware for G-PHY
+ * has been modified to be compatible with N-PHY and others.
+ */
+ if (dev->fw.rev >= 508)
+ status.freq = ieee80211_channel_to_frequency(chanid, status.band);
+ else
+ status.freq = chanid + 2400;
break;
case B43_PHYTYPE_N:
case B43_PHYTYPE_LP:
diff --git a/drivers/net/wireless/brcm80211/brcmfmac/chip.c b/drivers/net/wireless/brcm80211/brcmfmac/chip.c
index df130ef..c7c9f15 100644
--- a/drivers/net/wireless/brcm80211/brcmfmac/chip.c
+++ b/drivers/net/wireless/brcm80211/brcmfmac/chip.c
@@ -303,10 +303,10 @@
ci = core->chip;
- /* if core is already in reset, just return */
+ /* if core is already in reset, skip reset */
regdata = ci->ops->read32(ci->ctx, core->wrapbase + BCMA_RESET_CTL);
if ((regdata & BCMA_RESET_CTL_RESET) != 0)
- return;
+ goto in_reset_configure;
/* configure reset */
ci->ops->write32(ci->ctx, core->wrapbase + BCMA_IOCTL,
@@ -322,6 +322,7 @@
SPINWAIT(ci->ops->read32(ci->ctx, core->wrapbase + BCMA_RESET_CTL) !=
BCMA_RESET_CTL_RESET, 300);
+in_reset_configure:
/* in-reset configure */
ci->ops->write32(ci->ctx, core->wrapbase + BCMA_IOCTL,
reset | BCMA_IOCTL_FGC | BCMA_IOCTL_CLK);
diff --git a/drivers/net/wireless/brcm80211/brcmfmac/wl_cfg80211.c b/drivers/net/wireless/brcm80211/brcmfmac/wl_cfg80211.c
index 0f95984..6a73f06 100644
--- a/drivers/net/wireless/brcm80211/brcmfmac/wl_cfg80211.c
+++ b/drivers/net/wireless/brcm80211/brcmfmac/wl_cfg80211.c
@@ -4948,7 +4948,7 @@
if (!err) {
/* only set 2G bandwidth using bw_cap command */
band_bwcap.band = cpu_to_le32(WLC_BAND_2G);
- band_bwcap.bw_cap = cpu_to_le32(WLC_BW_40MHZ_BIT);
+ band_bwcap.bw_cap = cpu_to_le32(WLC_BW_CAP_40MHZ);
err = brcmf_fil_iovar_data_set(ifp, "bw_cap", &band_bwcap,
sizeof(band_bwcap));
} else {
diff --git a/drivers/net/wireless/iwlwifi/dvm/lib.c b/drivers/net/wireless/iwlwifi/dvm/lib.c
index d169228..576f7ee 100644
--- a/drivers/net/wireless/iwlwifi/dvm/lib.c
+++ b/drivers/net/wireless/iwlwifi/dvm/lib.c
@@ -180,7 +180,7 @@
goto done;
}
IWL_DEBUG_INFO(priv, "wait transmit/flush all frames\n");
- iwl_trans_wait_tx_queue_empty(priv->trans, 0xffffffff);
+ iwl_trans_wait_tx_queue_empty(priv->trans);
done:
ieee80211_wake_queues(priv->hw);
mutex_unlock(&priv->mutex);
diff --git a/drivers/net/wireless/iwlwifi/dvm/mac80211.c b/drivers/net/wireless/iwlwifi/dvm/mac80211.c
index 865b031..4111717 100644
--- a/drivers/net/wireless/iwlwifi/dvm/mac80211.c
+++ b/drivers/net/wireless/iwlwifi/dvm/mac80211.c
@@ -1119,7 +1119,7 @@
}
}
IWL_DEBUG_MAC80211(priv, "wait transmit/flush all frames\n");
- iwl_trans_wait_tx_queue_empty(priv->trans, 0xffffffff);
+ iwl_trans_wait_tx_queue_empty(priv->trans);
done:
mutex_unlock(&priv->mutex);
IWL_DEBUG_MAC80211(priv, "leave\n");
diff --git a/drivers/net/wireless/iwlwifi/dvm/main.c b/drivers/net/wireless/iwlwifi/dvm/main.c
index 4c6c118..424c21f 100644
--- a/drivers/net/wireless/iwlwifi/dvm/main.c
+++ b/drivers/net/wireless/iwlwifi/dvm/main.c
@@ -2053,17 +2053,6 @@
return false;
}
-static void iwl_napi_add(struct iwl_op_mode *op_mode,
- struct napi_struct *napi,
- struct net_device *napi_dev,
- int (*poll)(struct napi_struct *, int),
- int weight)
-{
- struct iwl_priv *priv = IWL_OP_MODE_GET_DVM(op_mode);
-
- ieee80211_napi_add(priv->hw, napi, napi_dev, poll, weight);
-}
-
static const struct iwl_op_mode_ops iwl_dvm_ops = {
.start = iwl_op_mode_dvm_start,
.stop = iwl_op_mode_dvm_stop,
@@ -2076,7 +2065,6 @@
.cmd_queue_full = iwl_cmd_queue_full,
.nic_config = iwl_nic_config,
.wimax_active = iwl_wimax_active,
- .napi_add = iwl_napi_add,
};
/*****************************************************************************
diff --git a/drivers/net/wireless/iwlwifi/dvm/rxon.c b/drivers/net/wireless/iwlwifi/dvm/rxon.c
index eaa438d..92a284a 100644
--- a/drivers/net/wireless/iwlwifi/dvm/rxon.c
+++ b/drivers/net/wireless/iwlwifi/dvm/rxon.c
@@ -1068,13 +1068,6 @@
/* recalculate basic rates */
iwl_calc_basic_rates(priv, ctx);
- /*
- * force CTS-to-self frames protection if RTS-CTS is not preferred
- * one aggregation protection method
- */
- if (!priv->hw_params.use_rts_for_aggregation)
- ctx->staging.flags |= RXON_FLG_SELF_CTS_EN;
-
if ((ctx->vif && ctx->vif->bss_conf.use_short_slot) ||
!(ctx->staging.flags & RXON_FLG_BAND_24G_MSK))
ctx->staging.flags |= RXON_FLG_SHORT_SLOT_MSK;
@@ -1480,11 +1473,6 @@
else
ctx->staging.flags &= ~RXON_FLG_TGG_PROTECT_MSK;
- if (bss_conf->use_cts_prot)
- ctx->staging.flags |= RXON_FLG_SELF_CTS_EN;
- else
- ctx->staging.flags &= ~RXON_FLG_SELF_CTS_EN;
-
memcpy(ctx->staging.bssid_addr, bss_conf->bssid, ETH_ALEN);
if (vif->type == NL80211_IFTYPE_AP ||
diff --git a/drivers/net/wireless/iwlwifi/iwl-1000.c b/drivers/net/wireless/iwlwifi/iwl-1000.c
index c3817fa..854ba84 100644
--- a/drivers/net/wireless/iwlwifi/iwl-1000.c
+++ b/drivers/net/wireless/iwlwifi/iwl-1000.c
@@ -62,7 +62,6 @@
.led_compensation = 51,
.wd_timeout = IWL_WATCHDOG_DISABLED,
.max_event_log_size = 128,
- .scd_chain_ext_wa = true,
};
static const struct iwl_ht_params iwl1000_ht_params = {
diff --git a/drivers/net/wireless/iwlwifi/iwl-2000.c b/drivers/net/wireless/iwlwifi/iwl-2000.c
index 21e5d08..3e63323 100644
--- a/drivers/net/wireless/iwlwifi/iwl-2000.c
+++ b/drivers/net/wireless/iwlwifi/iwl-2000.c
@@ -75,7 +75,6 @@
.wd_timeout = IWL_DEF_WD_TIMEOUT,
.max_event_log_size = 512,
.shadow_reg_enable = false, /* TODO: fix bugs using this feature */
- .scd_chain_ext_wa = true,
};
@@ -89,7 +88,6 @@
.wd_timeout = IWL_LONG_WD_TIMEOUT,
.max_event_log_size = 512,
.shadow_reg_enable = false, /* TODO: fix bugs using this feature */
- .scd_chain_ext_wa = true,
};
static const struct iwl_ht_params iwl2000_ht_params = {
diff --git a/drivers/net/wireless/iwlwifi/iwl-5000.c b/drivers/net/wireless/iwlwifi/iwl-5000.c
index 332bbed..6674f2c 100644
--- a/drivers/net/wireless/iwlwifi/iwl-5000.c
+++ b/drivers/net/wireless/iwlwifi/iwl-5000.c
@@ -61,7 +61,6 @@
.led_compensation = 51,
.wd_timeout = IWL_WATCHDOG_DISABLED,
.max_event_log_size = 512,
- .scd_chain_ext_wa = true,
};
static const struct iwl_ht_params iwl5000_ht_params = {
diff --git a/drivers/net/wireless/iwlwifi/iwl-6000.c b/drivers/net/wireless/iwlwifi/iwl-6000.c
index 8f2c3c8..8048de9 100644
--- a/drivers/net/wireless/iwlwifi/iwl-6000.c
+++ b/drivers/net/wireless/iwlwifi/iwl-6000.c
@@ -85,7 +85,6 @@
.wd_timeout = IWL_DEF_WD_TIMEOUT,
.max_event_log_size = 512,
.shadow_reg_enable = false, /* TODO: fix bugs using this feature */
- .scd_chain_ext_wa = true,
};
static const struct iwl_base_params iwl6050_base_params = {
@@ -98,7 +97,6 @@
.wd_timeout = IWL_DEF_WD_TIMEOUT,
.max_event_log_size = 1024,
.shadow_reg_enable = false, /* TODO: fix bugs using this feature */
- .scd_chain_ext_wa = true,
};
static const struct iwl_base_params iwl6000_g2_base_params = {
@@ -111,7 +109,6 @@
.wd_timeout = IWL_LONG_WD_TIMEOUT,
.max_event_log_size = 512,
.shadow_reg_enable = false, /* TODO: fix bugs using this feature */
- .scd_chain_ext_wa = true,
};
static const struct iwl_ht_params iwl6000_ht_params = {
diff --git a/drivers/net/wireless/iwlwifi/iwl-7000.c b/drivers/net/wireless/iwlwifi/iwl-7000.c
index f73de23..4c2d4ef 100644
--- a/drivers/net/wireless/iwlwifi/iwl-7000.c
+++ b/drivers/net/wireless/iwlwifi/iwl-7000.c
@@ -71,12 +71,12 @@
#define IWL3160_UCODE_API_MAX 9
/* Oldest version we won't warn about */
-#define IWL7260_UCODE_API_OK 9
-#define IWL3160_UCODE_API_OK 9
+#define IWL7260_UCODE_API_OK 8
+#define IWL3160_UCODE_API_OK 8
/* Lowest firmware API version supported */
-#define IWL7260_UCODE_API_MIN 8
-#define IWL3160_UCODE_API_MIN 8
+#define IWL7260_UCODE_API_MIN 7
+#define IWL3160_UCODE_API_MIN 7
/* NVM versions */
#define IWL7260_NVM_VERSION 0x0a1d
@@ -107,7 +107,6 @@
.max_event_log_size = 512,
.shadow_reg_enable = true,
.pcie_l1_allowed = true,
- .apmg_wake_up_wa = true,
};
static const struct iwl_ht_params iwl7000_ht_params = {
diff --git a/drivers/net/wireless/iwlwifi/iwl-config.h b/drivers/net/wireless/iwlwifi/iwl-config.h
index 00aed5d..8cabf87 100644
--- a/drivers/net/wireless/iwlwifi/iwl-config.h
+++ b/drivers/net/wireless/iwlwifi/iwl-config.h
@@ -146,9 +146,6 @@
* @wd_timeout: TX queues watchdog timeout
* @max_event_log_size: size of event log buffer size for ucode event logging
* @shadow_reg_enable: HW shadow register support
- * @apmg_wake_up_wa: should the MAC access REQ be asserted when a command
- * is in flight. This is due to a HW bug in 7260, 3160 and 7265.
- * @scd_chain_ext_wa: should the chain extension feature in SCD be disabled.
*/
struct iwl_base_params {
int eeprom_size;
@@ -163,8 +160,6 @@
u32 max_event_log_size;
const bool shadow_reg_enable;
const bool pcie_l1_allowed;
- const bool apmg_wake_up_wa;
- const bool scd_chain_ext_wa;
};
/*
diff --git a/drivers/net/wireless/iwlwifi/iwl-fw.h b/drivers/net/wireless/iwlwifi/iwl-fw.h
index f5927d0..d14f193 100644
--- a/drivers/net/wireless/iwlwifi/iwl-fw.h
+++ b/drivers/net/wireless/iwlwifi/iwl-fw.h
@@ -77,21 +77,26 @@
* @IWL_UCODE_TLV_FLAGS_UAPSD: This uCode image supports uAPSD
* @IWL_UCODE_TLV_FLAGS_SHORT_BL: 16 entries of black list instead of 64 in scan
* offload profile config command.
+ * @IWL_UCODE_TLV_FLAGS_RX_ENERGY_API: supports rx signal strength api
+ * @IWL_UCODE_TLV_FLAGS_TIME_EVENT_API_V2: using the new time event API.
* @IWL_UCODE_TLV_FLAGS_D3_6_IPV6_ADDRS: D3 image supports up to six
* (rather than two) IPv6 addresses
+ * @IWL_UCODE_TLV_FLAGS_BF_UPDATED: new beacon filtering API
* @IWL_UCODE_TLV_FLAGS_NO_BASIC_SSID: not sending a probe with the SSID element
* from the probe request template.
+ * @IWL_UCODE_TLV_FLAGS_D3_CONTINUITY_API: modified D3 API to allow keeping
+ * connection when going back to D0
* @IWL_UCODE_TLV_FLAGS_NEW_NSOFFL_SMALL: new NS offload (small version)
* @IWL_UCODE_TLV_FLAGS_NEW_NSOFFL_LARGE: new NS offload (large version)
- * @IWL_UCODE_TLV_FLAGS_P2P_PM: P2P client supports PM as a stand alone MAC
+ * @IWL_UCODE_TLV_FLAGS_SCHED_SCAN: this uCode image supports scheduled scan.
+ * @IWL_UCODE_TLV_FLAGS_STA_KEY_CMD: new ADD_STA and ADD_STA_KEY command API
+ * @IWL_UCODE_TLV_FLAGS_DEVICE_PS_CMD: support device wide power command
+ * containing CAM (Continuous Active Mode) indication.
* @IWL_UCODE_TLV_FLAGS_P2P_BSS_PS_DCM: support power save on BSS station and
* P2P client interfaces simultaneously if they are in different bindings.
- * @IWL_UCODE_TLV_FLAGS_P2P_BSS_PS_SCM: support power save on BSS station and
- * P2P client interfaces simultaneously if they are in same bindings.
* @IWL_UCODE_TLV_FLAGS_P2P_PS_UAPSD: P2P client supports uAPSD power save
* @IWL_UCODE_TLV_FLAGS_BCAST_FILTERING: uCode supports broadcast filtering.
* @IWL_UCODE_TLV_FLAGS_GO_UAPSD: AP/GO interfaces support uAPSD clients
- * @IWL_UCODE_TLV_FLAGS_EBS_SUPPORT: this uCode image supports EBS.
*/
enum iwl_ucode_tlv_flag {
IWL_UCODE_TLV_FLAGS_PAN = BIT(0),
@@ -99,15 +104,22 @@
IWL_UCODE_TLV_FLAGS_MFP = BIT(2),
IWL_UCODE_TLV_FLAGS_P2P = BIT(3),
IWL_UCODE_TLV_FLAGS_DW_BC_TABLE = BIT(4),
+ IWL_UCODE_TLV_FLAGS_NEWBT_COEX = BIT(5),
+ IWL_UCODE_TLV_FLAGS_PM_CMD_SUPPORT = BIT(6),
IWL_UCODE_TLV_FLAGS_SHORT_BL = BIT(7),
+ IWL_UCODE_TLV_FLAGS_RX_ENERGY_API = BIT(8),
+ IWL_UCODE_TLV_FLAGS_TIME_EVENT_API_V2 = BIT(9),
IWL_UCODE_TLV_FLAGS_D3_6_IPV6_ADDRS = BIT(10),
+ IWL_UCODE_TLV_FLAGS_BF_UPDATED = BIT(11),
IWL_UCODE_TLV_FLAGS_NO_BASIC_SSID = BIT(12),
+ IWL_UCODE_TLV_FLAGS_D3_CONTINUITY_API = BIT(14),
IWL_UCODE_TLV_FLAGS_NEW_NSOFFL_SMALL = BIT(15),
IWL_UCODE_TLV_FLAGS_NEW_NSOFFL_LARGE = BIT(16),
- IWL_UCODE_TLV_FLAGS_P2P_PM = BIT(21),
+ IWL_UCODE_TLV_FLAGS_SCHED_SCAN = BIT(17),
+ IWL_UCODE_TLV_FLAGS_STA_KEY_CMD = BIT(19),
+ IWL_UCODE_TLV_FLAGS_DEVICE_PS_CMD = BIT(20),
IWL_UCODE_TLV_FLAGS_BSS_P2P_PS_DCM = BIT(22),
- IWL_UCODE_TLV_FLAGS_BSS_P2P_PS_SCM = BIT(23),
- IWL_UCODE_TLV_FLAGS_EBS_SUPPORT = BIT(25),
+ IWL_UCODE_TLV_FLAGS_UAPSD_SUPPORT = BIT(24),
IWL_UCODE_TLV_FLAGS_P2P_PS_UAPSD = BIT(26),
IWL_UCODE_TLV_FLAGS_BCAST_FILTERING = BIT(29),
IWL_UCODE_TLV_FLAGS_GO_UAPSD = BIT(30),
@@ -171,7 +183,6 @@
#define IWL_UCODE_SECTION_MAX 12
#define IWL_API_ARRAY_SIZE 1
#define IWL_CAPABILITIES_ARRAY_SIZE 1
-#define CPU1_CPU2_SEPARATOR_SECTION 0xFFFFCCCC
struct iwl_ucode_capabilities {
u32 max_probe_length;
diff --git a/drivers/net/wireless/iwlwifi/iwl-nvm-parse.c b/drivers/net/wireless/iwlwifi/iwl-nvm-parse.c
index 4049c0d..6be30c6 100644
--- a/drivers/net/wireless/iwlwifi/iwl-nvm-parse.c
+++ b/drivers/net/wireless/iwlwifi/iwl-nvm-parse.c
@@ -134,13 +134,12 @@
149, 153, 157, 161, 165, 169, 173, 177, 181
};
-#define IWL_NUM_CHANNELS ARRAY_SIZE(iwl_nvm_channels)
+#define IWL_NUM_CHANNELS ARRAY_SIZE(iwl_nvm_channels)
#define IWL_NUM_CHANNELS_FAMILY_8000 ARRAY_SIZE(iwl_nvm_channels_family_8000)
-#define NUM_2GHZ_CHANNELS 14
-#define NUM_2GHZ_CHANNELS_FAMILY_8000 13
-#define FIRST_2GHZ_HT_MINUS 5
-#define LAST_2GHZ_HT_PLUS 9
-#define LAST_5GHZ_HT 161
+#define NUM_2GHZ_CHANNELS 14
+#define FIRST_2GHZ_HT_MINUS 5
+#define LAST_2GHZ_HT_PLUS 9
+#define LAST_5GHZ_HT 161
#define DEFAULT_MAX_TX_POWER 16
@@ -203,23 +202,21 @@
struct ieee80211_channel *channel;
u16 ch_flags;
bool is_5ghz;
- int num_of_ch, num_2ghz_channels;
+ int num_of_ch;
const u8 *nvm_chan;
if (cfg->device_family != IWL_DEVICE_FAMILY_8000) {
num_of_ch = IWL_NUM_CHANNELS;
nvm_chan = &iwl_nvm_channels[0];
- num_2ghz_channels = NUM_2GHZ_CHANNELS;
} else {
num_of_ch = IWL_NUM_CHANNELS_FAMILY_8000;
nvm_chan = &iwl_nvm_channels_family_8000[0];
- num_2ghz_channels = NUM_2GHZ_CHANNELS_FAMILY_8000;
}
for (ch_idx = 0; ch_idx < num_of_ch; ch_idx++) {
ch_flags = __le16_to_cpup(nvm_ch_flags + ch_idx);
- if (ch_idx >= num_2ghz_channels &&
+ if (ch_idx >= NUM_2GHZ_CHANNELS &&
!data->sku_cap_band_52GHz_enable)
ch_flags &= ~NVM_CHANNEL_VALID;
@@ -228,7 +225,7 @@
"Ch. %d Flags %x [%sGHz] - No traffic\n",
nvm_chan[ch_idx],
ch_flags,
- (ch_idx >= num_2ghz_channels) ?
+ (ch_idx >= NUM_2GHZ_CHANNELS) ?
"5.2" : "2.4");
continue;
}
@@ -237,7 +234,7 @@
n_channels++;
channel->hw_value = nvm_chan[ch_idx];
- channel->band = (ch_idx < num_2ghz_channels) ?
+ channel->band = (ch_idx < NUM_2GHZ_CHANNELS) ?
IEEE80211_BAND_2GHZ : IEEE80211_BAND_5GHZ;
channel->center_freq =
ieee80211_channel_to_frequency(
@@ -245,7 +242,7 @@
/* TODO: Need to be dependent to the NVM */
channel->flags = IEEE80211_CHAN_NO_HT40;
- if (ch_idx < num_2ghz_channels &&
+ if (ch_idx < NUM_2GHZ_CHANNELS &&
(ch_flags & NVM_CHANNEL_40MHZ)) {
if (nvm_chan[ch_idx] <= LAST_2GHZ_HT_PLUS)
channel->flags &= ~IEEE80211_CHAN_NO_HT40PLUS;
@@ -253,7 +250,7 @@
channel->flags &= ~IEEE80211_CHAN_NO_HT40MINUS;
} else if (nvm_chan[ch_idx] <= LAST_5GHZ_HT &&
(ch_flags & NVM_CHANNEL_40MHZ)) {
- if ((ch_idx - num_2ghz_channels) % 2 == 0)
+ if ((ch_idx - NUM_2GHZ_CHANNELS) % 2 == 0)
channel->flags &= ~IEEE80211_CHAN_NO_HT40PLUS;
else
channel->flags &= ~IEEE80211_CHAN_NO_HT40MINUS;
diff --git a/drivers/net/wireless/iwlwifi/iwl-op-mode.h b/drivers/net/wireless/iwlwifi/iwl-op-mode.h
index 99785c8..ea29504 100644
--- a/drivers/net/wireless/iwlwifi/iwl-op-mode.h
+++ b/drivers/net/wireless/iwlwifi/iwl-op-mode.h
@@ -63,7 +63,6 @@
#ifndef __iwl_op_mode_h__
#define __iwl_op_mode_h__
-#include <linux/netdevice.h>
#include <linux/debugfs.h>
struct iwl_op_mode;
@@ -113,11 +112,8 @@
* @stop: stop the op_mode. Must free all the memory allocated.
* May sleep
* @rx: Rx notification to the op_mode. rxb is the Rx buffer itself. Cmd is the
- * HCMD this Rx responds to. Can't sleep.
- * @napi_add: NAPI initialisation. The transport is fully responsible for NAPI,
- * but the higher layers need to know about it (in particular mac80211 to
- * to able to call the right NAPI RX functions); this function is needed
- * to eventually call netif_napi_add() with higher layer involvement.
+ * HCMD this Rx responds to.
+ * This callback may sleep, it is called from a threaded IRQ handler.
* @queue_full: notifies that a HW queue is full.
* Must be atomic and called with BH disabled.
* @queue_not_full: notifies that a HW queue is not full any more.
@@ -147,11 +143,6 @@
void (*stop)(struct iwl_op_mode *op_mode);
int (*rx)(struct iwl_op_mode *op_mode, struct iwl_rx_cmd_buffer *rxb,
struct iwl_device_cmd *cmd);
- void (*napi_add)(struct iwl_op_mode *op_mode,
- struct napi_struct *napi,
- struct net_device *napi_dev,
- int (*poll)(struct napi_struct *, int),
- int weight);
void (*queue_full)(struct iwl_op_mode *op_mode, int queue);
void (*queue_not_full)(struct iwl_op_mode *op_mode, int queue);
bool (*hw_rf_kill)(struct iwl_op_mode *op_mode, bool state);
@@ -189,6 +180,7 @@
struct iwl_rx_cmd_buffer *rxb,
struct iwl_device_cmd *cmd)
{
+ might_sleep();
return op_mode->ops->rx(op_mode, rxb, cmd);
}
@@ -257,15 +249,4 @@
return op_mode->ops->exit_d0i3(op_mode);
}
-static inline void iwl_op_mode_napi_add(struct iwl_op_mode *op_mode,
- struct napi_struct *napi,
- struct net_device *napi_dev,
- int (*poll)(struct napi_struct *, int),
- int weight)
-{
- if (!op_mode->ops->napi_add)
- return;
- op_mode->ops->napi_add(op_mode, napi, napi_dev, poll, weight);
-}
-
#endif /* __iwl_op_mode_h__ */
diff --git a/drivers/net/wireless/iwlwifi/iwl-prph.h b/drivers/net/wireless/iwlwifi/iwl-prph.h
index 7793110..5f657c5 100644
--- a/drivers/net/wireless/iwlwifi/iwl-prph.h
+++ b/drivers/net/wireless/iwlwifi/iwl-prph.h
@@ -348,12 +348,4 @@
#define LMPM_SECURE_TIME_OUT (100)
-/* Rx FIFO */
-#define RXF_SIZE_ADDR (0xa00c88)
-#define RXF_SIZE_BYTE_CND_POS (7)
-#define RXF_SIZE_BYTE_CNT_MSK (0x3ff << RXF_SIZE_BYTE_CND_POS)
-
-#define RXF_LD_FENCE_OFFSET_ADDR (0xa00c10)
-#define RXF_FIFO_RD_FENCE_ADDR (0xa00c0c)
-
#endif /* __iwl_prph_h__ */
diff --git a/drivers/net/wireless/iwlwifi/iwl-trans.h b/drivers/net/wireless/iwlwifi/iwl-trans.h
index 22fd94e..8cdb0dd 100644
--- a/drivers/net/wireless/iwlwifi/iwl-trans.h
+++ b/drivers/net/wireless/iwlwifi/iwl-trans.h
@@ -437,7 +437,8 @@
* this one. The op_mode must not configure the HCMD queue. May sleep.
* @txq_disable: de-configure a Tx queue to send AMPDUs
* Must be atomic
- * @wait_tx_queue_empty: wait until tx queues are empty. May sleep.
+ * @wait_tx_queue_empty: wait until all tx queues are empty
+ * May sleep
* @dbgfs_register: add the dbgfs files under this directory. Files will be
* automatically deleted.
* @write8: write a u8 to a register at offset ofs from the BAR
@@ -489,7 +490,7 @@
void (*txq_disable)(struct iwl_trans *trans, int queue);
int (*dbgfs_register)(struct iwl_trans *trans, struct dentry* dir);
- int (*wait_tx_queue_empty)(struct iwl_trans *trans, u32 txq_bm);
+ int (*wait_tx_queue_empty)(struct iwl_trans *trans);
void (*write8)(struct iwl_trans *trans, u32 ofs, u8 val);
void (*write32)(struct iwl_trans *trans, u32 ofs, u32 val);
@@ -758,13 +759,12 @@
IWL_MAX_TID_COUNT, IWL_FRAME_LIMIT, 0);
}
-static inline int iwl_trans_wait_tx_queue_empty(struct iwl_trans *trans,
- u32 txq_bm)
+static inline int iwl_trans_wait_tx_queue_empty(struct iwl_trans *trans)
{
if (unlikely(trans->state != IWL_TRANS_FW_ALIVE))
IWL_ERR(trans, "%s bad state = %d", __func__, trans->state);
- return trans->ops->wait_tx_queue_empty(trans, txq_bm);
+ return trans->ops->wait_tx_queue_empty(trans);
}
static inline int iwl_trans_dbgfs_register(struct iwl_trans *trans,
diff --git a/drivers/net/wireless/iwlwifi/mvm/coex.c b/drivers/net/wireless/iwlwifi/mvm/coex.c
index 8f4b03d..0489314 100644
--- a/drivers/net/wireless/iwlwifi/mvm/coex.c
+++ b/drivers/net/wireless/iwlwifi/mvm/coex.c
@@ -104,8 +104,11 @@
#define BT_DISABLE_REDUCED_TXPOWER_THRESHOLD (-65)
#define BT_ANTENNA_COUPLING_THRESHOLD (30)
-static int iwl_send_bt_prio_tbl(struct iwl_mvm *mvm)
+int iwl_send_bt_prio_tbl(struct iwl_mvm *mvm)
{
+ if (!(mvm->fw->ucode_capa.flags & IWL_UCODE_TLV_FLAGS_NEWBT_COEX))
+ return 0;
+
return iwl_mvm_send_cmd_pdu(mvm, BT_COEX_PRIO_TABLE, CMD_SYNC,
sizeof(struct iwl_bt_coex_prio_tbl_cmd),
&iwl_bt_prio_tbl);
@@ -570,9 +573,8 @@
int ret;
u32 flags;
- ret = iwl_send_bt_prio_tbl(mvm);
- if (ret)
- return ret;
+ if (!(mvm->fw->ucode_capa.flags & IWL_UCODE_TLV_FLAGS_NEWBT_COEX))
+ return 0;
bt_cmd = kzalloc(sizeof(*bt_cmd), GFP_KERNEL);
if (!bt_cmd)
@@ -580,12 +582,10 @@
cmd.data[0] = bt_cmd;
bt_cmd->max_kill = 5;
- bt_cmd->bt4_antenna_isolation_thr = BT_ANTENNA_COUPLING_THRESHOLD;
- bt_cmd->bt4_antenna_isolation = iwlwifi_mod_params.ant_coupling;
- bt_cmd->bt4_tx_tx_delta_freq_thr = 15;
- bt_cmd->bt4_tx_rx_max_freq0 = 15;
- bt_cmd->override_primary_lut = BT_COEX_INVALID_LUT;
- bt_cmd->override_secondary_lut = BT_COEX_INVALID_LUT;
+ bt_cmd->bt4_antenna_isolation_thr = BT_ANTENNA_COUPLING_THRESHOLD,
+ bt_cmd->bt4_antenna_isolation = iwlwifi_mod_params.ant_coupling,
+ bt_cmd->bt4_tx_tx_delta_freq_thr = 15,
+ bt_cmd->bt4_tx_rx_max_freq0 = 15,
flags = iwlwifi_mod_params.bt_coex_active ?
BT_COEX_NW : BT_COEX_DISABLE;
@@ -611,14 +611,14 @@
bt_cmd->flags |= cpu_to_le32(BT_COEX_SYNC2SCO);
if (IWL_MVM_BT_COEX_CORUNNING) {
- bt_cmd->valid_bit_msk = cpu_to_le32(BT_VALID_CORUN_LUT_20 |
- BT_VALID_CORUN_LUT_40);
+ bt_cmd->valid_bit_msk |= cpu_to_le32(BT_VALID_CORUN_LUT_20 |
+ BT_VALID_CORUN_LUT_40);
bt_cmd->flags |= cpu_to_le32(BT_COEX_CORUNNING);
}
if (IWL_MVM_BT_COEX_MPLUT) {
bt_cmd->flags |= cpu_to_le32(BT_COEX_MPLUT);
- bt_cmd->valid_bit_msk = cpu_to_le32(BT_VALID_MULTI_PRIO_LUT);
+ bt_cmd->valid_bit_msk |= cpu_to_le32(BT_VALID_MULTI_PRIO_LUT);
}
if (mvm->cfg->bt_shared_single_ant)
@@ -1215,17 +1215,6 @@
return iwl_get_coex_type(mvm, mvmsta->vif) == BT_COEX_TIGHT_LUT;
}
-bool iwl_mvm_bt_coex_is_tpc_allowed(struct iwl_mvm *mvm,
- enum ieee80211_band band)
-{
- u32 bt_activity = le32_to_cpu(mvm->last_bt_notif.bt_activity_grading);
-
- if (band != IEEE80211_BAND_2GHZ)
- return false;
-
- return bt_activity >= BT_LOW_TRAFFIC;
-}
-
u8 iwl_mvm_bt_coex_tx_prio(struct iwl_mvm *mvm, struct ieee80211_hdr *hdr,
struct ieee80211_tx_info *info, u8 ac)
{
@@ -1260,6 +1249,9 @@
void iwl_mvm_bt_coex_vif_change(struct iwl_mvm *mvm)
{
+ if (!(mvm->fw->ucode_capa.flags & IWL_UCODE_TLV_FLAGS_NEWBT_COEX))
+ return;
+
iwl_mvm_bt_coex_notif_handle(mvm);
}
diff --git a/drivers/net/wireless/iwlwifi/mvm/d3.c b/drivers/net/wireless/iwlwifi/mvm/d3.c
index 957e626..778c321 100644
--- a/drivers/net/wireless/iwlwifi/mvm/d3.c
+++ b/drivers/net/wireless/iwlwifi/mvm/d3.c
@@ -744,8 +744,10 @@
int err;
u32 size;
- cmd.data[0] = &query_cmd;
- cmd.len[0] = sizeof(query_cmd);
+ if (mvm->fw->ucode_capa.flags & IWL_UCODE_TLV_FLAGS_D3_CONTINUITY_API) {
+ cmd.data[0] = &query_cmd;
+ cmd.len[0] = sizeof(query_cmd);
+ }
err = iwl_mvm_send_cmd(mvm, &cmd);
if (err)
@@ -756,8 +758,10 @@
err = -EINVAL;
} else {
err = le16_to_cpup((__le16 *)cmd.resp_pkt->data);
- /* firmware returns next, not last-used seqno */
- err = (u16) (err - 0x10);
+ /* new API returns next, not last-used seqno */
+ if (mvm->fw->ucode_capa.flags &
+ IWL_UCODE_TLV_FLAGS_D3_CONTINUITY_API)
+ err = (u16) (err - 0x10);
}
iwl_free_resp(&cmd);
@@ -781,6 +785,10 @@
mvmvif->seqno_valid = false;
+ if (!(mvm->fw->ucode_capa.flags &
+ IWL_UCODE_TLV_FLAGS_D3_CONTINUITY_API))
+ return;
+
if (iwl_mvm_send_cmd_pdu(mvm, NON_QOS_TX_COUNTER_CMD, CMD_SYNC,
sizeof(query_cmd), &query_cmd))
IWL_ERR(mvm, "failed to set non-QoS seqno\n");
@@ -1074,15 +1082,6 @@
int iwl_mvm_suspend(struct ieee80211_hw *hw, struct cfg80211_wowlan *wowlan)
{
- struct iwl_mvm *mvm = IWL_MAC80211_GET_MVM(hw);
-
- if (iwl_mvm_is_d0i3_supported(mvm)) {
- mutex_lock(&mvm->d0i3_suspend_mutex);
- __set_bit(D0I3_DEFER_WAKEUP, &mvm->d0i3_suspend_flags);
- mutex_unlock(&mvm->d0i3_suspend_mutex);
- return 0;
- }
-
return __iwl_mvm_suspend(hw, wowlan, false);
}
@@ -1278,7 +1277,7 @@
}
static void iwl_mvm_set_key_rx_seq(struct ieee80211_key_conf *key,
- struct iwl_wowlan_status *status)
+ struct iwl_wowlan_status_v6 *status)
{
union iwl_all_tsc_rsc *rsc = &status->gtk.rsc.all_tsc_rsc;
@@ -1295,7 +1294,7 @@
}
struct iwl_mvm_d3_gtk_iter_data {
- struct iwl_wowlan_status *status;
+ struct iwl_wowlan_status_v6 *status;
void *last_gtk;
u32 cipher;
bool find_phase, unhandled_cipher;
@@ -1371,7 +1370,7 @@
static bool iwl_mvm_setup_connection_keep(struct iwl_mvm *mvm,
struct ieee80211_vif *vif,
- struct iwl_wowlan_status *status)
+ struct iwl_wowlan_status_v6 *status)
{
struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif);
struct iwl_mvm_d3_gtk_iter_data gtkdata = {
@@ -1469,7 +1468,7 @@
.flags = CMD_SYNC | CMD_WANT_SKB,
};
struct iwl_wowlan_status_data status;
- struct iwl_wowlan_status *fw_status;
+ struct iwl_wowlan_status_v6 *status_v6;
int ret, len, status_size, i;
bool keep;
struct ieee80211_sta *ap_sta;
@@ -1506,7 +1505,10 @@
if (!cmd.resp_pkt)
goto out_unlock;
- status_size = sizeof(*fw_status);
+ if (mvm->fw->ucode_capa.flags & IWL_UCODE_TLV_FLAGS_D3_CONTINUITY_API)
+ status_size = sizeof(struct iwl_wowlan_status_v6);
+ else
+ status_size = sizeof(struct iwl_wowlan_status_v4);
len = iwl_rx_packet_payload_len(cmd.resp_pkt);
if (len < status_size) {
@@ -1514,18 +1516,35 @@
goto out_free_resp;
}
- fw_status = (void *)cmd.resp_pkt->data;
+ if (mvm->fw->ucode_capa.flags & IWL_UCODE_TLV_FLAGS_D3_CONTINUITY_API) {
+ status_v6 = (void *)cmd.resp_pkt->data;
- status.pattern_number = le16_to_cpu(fw_status->pattern_number);
- for (i = 0; i < 8; i++)
- status.qos_seq_ctr[i] =
- le16_to_cpu(fw_status->qos_seq_ctr[i]);
- status.wakeup_reasons = le32_to_cpu(fw_status->wakeup_reasons);
- status.wake_packet_length =
- le32_to_cpu(fw_status->wake_packet_length);
- status.wake_packet_bufsize =
- le32_to_cpu(fw_status->wake_packet_bufsize);
- status.wake_packet = fw_status->wake_packet;
+ status.pattern_number = le16_to_cpu(status_v6->pattern_number);
+ for (i = 0; i < 8; i++)
+ status.qos_seq_ctr[i] =
+ le16_to_cpu(status_v6->qos_seq_ctr[i]);
+ status.wakeup_reasons = le32_to_cpu(status_v6->wakeup_reasons);
+ status.wake_packet_length =
+ le32_to_cpu(status_v6->wake_packet_length);
+ status.wake_packet_bufsize =
+ le32_to_cpu(status_v6->wake_packet_bufsize);
+ status.wake_packet = status_v6->wake_packet;
+ } else {
+ struct iwl_wowlan_status_v4 *status_v4;
+ status_v6 = NULL;
+ status_v4 = (void *)cmd.resp_pkt->data;
+
+ status.pattern_number = le16_to_cpu(status_v4->pattern_number);
+ for (i = 0; i < 8; i++)
+ status.qos_seq_ctr[i] =
+ le16_to_cpu(status_v4->qos_seq_ctr[i]);
+ status.wakeup_reasons = le32_to_cpu(status_v4->wakeup_reasons);
+ status.wake_packet_length =
+ le32_to_cpu(status_v4->wake_packet_length);
+ status.wake_packet_bufsize =
+ le32_to_cpu(status_v4->wake_packet_bufsize);
+ status.wake_packet = status_v4->wake_packet;
+ }
if (len != status_size + ALIGN(status.wake_packet_bufsize, 4)) {
IWL_ERR(mvm, "Invalid WoWLAN status response!\n");
@@ -1552,7 +1571,7 @@
iwl_mvm_report_wakeup_reasons(mvm, vif, &status);
- keep = iwl_mvm_setup_connection_keep(mvm, vif, fw_status);
+ keep = iwl_mvm_setup_connection_keep(mvm, vif, status_v6);
iwl_free_resp(&cmd);
return keep;
@@ -1655,19 +1674,6 @@
{
struct iwl_mvm *mvm = IWL_MAC80211_GET_MVM(hw);
- if (iwl_mvm_is_d0i3_supported(mvm)) {
- bool exit_now;
-
- mutex_lock(&mvm->d0i3_suspend_mutex);
- __clear_bit(D0I3_DEFER_WAKEUP, &mvm->d0i3_suspend_flags);
- exit_now = __test_and_clear_bit(D0I3_PENDING_WAKEUP,
- &mvm->d0i3_suspend_flags);
- mutex_unlock(&mvm->d0i3_suspend_mutex);
- if (exit_now)
- _iwl_mvm_exit_d0i3(mvm);
- return 0;
- }
-
return __iwl_mvm_resume(mvm, false);
}
diff --git a/drivers/net/wireless/iwlwifi/mvm/debugfs-vif.c b/drivers/net/wireless/iwlwifi/mvm/debugfs-vif.c
index 6047cfd..9b59e1d 100644
--- a/drivers/net/wireless/iwlwifi/mvm/debugfs-vif.c
+++ b/drivers/net/wireless/iwlwifi/mvm/debugfs-vif.c
@@ -103,6 +103,10 @@
IWL_DEBUG_POWER(mvm, "tx_data_timeout=%d\n", val);
dbgfs_pm->tx_data_timeout = val;
break;
+ case MVM_DEBUGFS_PM_DISABLE_POWER_OFF:
+ IWL_DEBUG_POWER(mvm, "disable_power_off=%d\n", val);
+ dbgfs_pm->disable_power_off = val;
+ break;
case MVM_DEBUGFS_PM_LPRX_ENA:
IWL_DEBUG_POWER(mvm, "lprx %s\n", val ? "enabled" : "disabled");
dbgfs_pm->lprx_ena = val;
@@ -150,6 +154,12 @@
if (sscanf(buf + 16, "%d", &val) != 1)
return -EINVAL;
param = MVM_DEBUGFS_PM_TX_DATA_TIMEOUT;
+ } else if (!strncmp("disable_power_off=", buf, 18) &&
+ !(mvm->fw->ucode_capa.flags &
+ IWL_UCODE_TLV_FLAGS_DEVICE_PS_CMD)) {
+ if (sscanf(buf + 18, "%d", &val) != 1)
+ return -EINVAL;
+ param = MVM_DEBUGFS_PM_DISABLE_POWER_OFF;
} else if (!strncmp("lprx=", buf, 5)) {
if (sscanf(buf + 5, "%d", &val) != 1)
return -EINVAL;
@@ -582,7 +592,8 @@
return;
}
- if (iwlmvm_mod_params.power_scheme != IWL_POWER_SCHEME_CAM &&
+ if ((mvm->fw->ucode_capa.flags & IWL_UCODE_TLV_FLAGS_PM_CMD_SUPPORT) &&
+ iwlmvm_mod_params.power_scheme != IWL_POWER_SCHEME_CAM &&
((vif->type == NL80211_IFTYPE_STATION && !vif->p2p) ||
(vif->type == NL80211_IFTYPE_STATION && vif->p2p &&
mvm->fw->ucode_capa.flags & IWL_UCODE_TLV_FLAGS_BSS_P2P_PS_DCM)))
diff --git a/drivers/net/wireless/iwlwifi/mvm/debugfs.c b/drivers/net/wireless/iwlwifi/mvm/debugfs.c
index a21dfd3..ea3fc82 100644
--- a/drivers/net/wireless/iwlwifi/mvm/debugfs.c
+++ b/drivers/net/wireless/iwlwifi/mvm/debugfs.c
@@ -136,6 +136,9 @@
file->private_data = mvm->fw_error_dump;
mvm->fw_error_dump = NULL;
+ kfree(mvm->fw_error_sram);
+ mvm->fw_error_sram = NULL;
+ mvm->fw_error_sram_len = 0;
ret = 0;
out:
@@ -1001,7 +1004,6 @@
PRINT_MVM_REF(IWL_MVM_REF_P2P_CLIENT);
PRINT_MVM_REF(IWL_MVM_REF_AP_IBSS);
PRINT_MVM_REF(IWL_MVM_REF_USER);
- PRINT_MVM_REF(IWL_MVM_REF_EXIT_WORK);
return simple_read_from_buffer(user_buf, count, ppos, buf, pos);
}
@@ -1106,9 +1108,9 @@
MVM_DEBUGFS_READ_WRITE_FILE_OPS(d0i3_refs, 8);
static const struct file_operations iwl_dbgfs_fw_error_dump_ops = {
- .open = iwl_dbgfs_fw_error_dump_open,
- .read = iwl_dbgfs_fw_error_dump_read,
- .release = iwl_dbgfs_fw_error_dump_release,
+ .open = iwl_dbgfs_fw_error_dump_open,
+ .read = iwl_dbgfs_fw_error_dump_read,
+ .release = iwl_dbgfs_fw_error_dump_release,
};
#ifdef CPTCFG_IWLWIFI_BCAST_FILTERING
@@ -1136,8 +1138,9 @@
MVM_DEBUGFS_ADD_FILE(fw_error_dump, dbgfs_dir, S_IRUSR);
MVM_DEBUGFS_ADD_FILE(bt_notif, dbgfs_dir, S_IRUSR);
MVM_DEBUGFS_ADD_FILE(bt_cmd, dbgfs_dir, S_IRUSR);
- MVM_DEBUGFS_ADD_FILE(disable_power_off, mvm->debugfs_dir,
- S_IRUSR | S_IWUSR);
+ if (mvm->fw->ucode_capa.flags & IWL_UCODE_TLV_FLAGS_DEVICE_PS_CMD)
+ MVM_DEBUGFS_ADD_FILE(disable_power_off, mvm->debugfs_dir,
+ S_IRUSR | S_IWUSR);
MVM_DEBUGFS_ADD_FILE(fw_rx_stats, mvm->debugfs_dir, S_IRUSR);
MVM_DEBUGFS_ADD_FILE(drv_rx_stats, mvm->debugfs_dir, S_IRUSR);
MVM_DEBUGFS_ADD_FILE(fw_restart, mvm->debugfs_dir, S_IWUSR);
diff --git a/drivers/net/wireless/iwlwifi/mvm/fw-api-coex.h b/drivers/net/wireless/iwlwifi/mvm/fw-api-coex.h
index 5fe82c2..21877e5 100644
--- a/drivers/net/wireless/iwlwifi/mvm/fw-api-coex.h
+++ b/drivers/net/wireless/iwlwifi/mvm/fw-api-coex.h
@@ -141,8 +141,7 @@
BT_COEX_TX_DIS_LUT,
BT_COEX_MAX_LUT,
- BT_COEX_INVALID_LUT = 0xff,
-}; /* BT_COEX_DECISION_LUT_INDEX_API_E_VER_1 */
+};
#define BT_COEX_LUT_SIZE (12)
#define BT_COEX_CORUN_LUT_SIZE (32)
@@ -155,23 +154,19 @@
* @flags:&enum iwl_bt_coex_flags
* @max_kill:
* @bt_reduced_tx_power: enum %iwl_bt_reduced_tx_power
- * @override_primary_lut: enum %iwl_bt_coex_lut_type: BT_COEX_INVALID_LUT
- * should be set by default
- * @override_secondary_lut: enum %iwl_bt_coex_lut_type: BT_COEX_INVALID_LUT
- * should be set by default
- * @bt4_antenna_isolation: antenna isolation
- * @bt4_antenna_isolation_thr: antenna threshold value
- * @bt4_tx_tx_delta_freq_thr: TxTx delta frequency
- * @bt4_tx_rx_max_freq0: TxRx max frequency
- * @bt_prio_boost: BT priority boost registers
+ * @bt4_antenna_isolation:
+ * @bt4_antenna_isolation_thr:
+ * @bt4_tx_tx_delta_freq_thr:
+ * @bt4_tx_rx_max_freq0:
+ * @bt_prio_boost:
* @wifi_tx_prio_boost: SW boost of wifi tx priority
* @wifi_rx_prio_boost: SW boost of wifi rx priority
- * @kill_ack_msk: kill ACK mask. 1 - Tx ACK, 0 - kill Tx of ACK.
- * @kill_cts_msk: kill CTS mask. 1 - Tx CTS, 0 - kill Tx of CTS.
- * @decision_lut: PTA decision LUT, per Prio-Ch
- * @bt4_multiprio_lut: multi priority LUT configuration
- * @bt4_corun_lut20: co-running 20 MHz LUT configuration
- * @bt4_corun_lut40: co-running 40 MHz LUT configuration
+ * @kill_ack_msk:
+ * @kill_cts_msk:
+ * @decision_lut:
+ * @bt4_multiprio_lut:
+ * @bt4_corun_lut20:
+ * @bt4_corun_lut40:
* @valid_bit_msk: enum %iwl_bt_coex_valid_bit_msk
*
* The structure is used for the BT_COEX command.
@@ -180,8 +175,7 @@
__le32 flags;
u8 max_kill;
u8 bt_reduced_tx_power;
- u8 override_primary_lut;
- u8 override_secondary_lut;
+ u8 reserved[2];
u8 bt4_antenna_isolation;
u8 bt4_antenna_isolation_thr;
@@ -200,7 +194,7 @@
__le32 bt4_corun_lut40[BT_COEX_CORUN_LUT_SIZE];
__le32 valid_bit_msk;
-} __packed; /* BT_COEX_CMD_API_S_VER_5 */
+} __packed; /* BT_COEX_CMD_API_S_VER_3 */
/**
* struct iwl_bt_coex_ci_cmd - bt coex channel inhibition command
@@ -288,7 +282,7 @@
BT_ON_NO_CONNECTION = 1,
BT_LOW_TRAFFIC = 2,
BT_HIGH_TRAFFIC = 3,
-}; /* BT_COEX_BT_ACTIVITY_GRADING_API_E_VER_1 */
+};
/**
* struct iwl_bt_coex_profile_notif - notification about BT coex
@@ -316,7 +310,7 @@
__le32 primary_ch_lut;
__le32 secondary_ch_lut;
__le32 bt_activity_grading;
-} __packed; /* BT_COEX_PROFILE_NTFY_API_S_VER_3 */
+} __packed; /* BT_COEX_PROFILE_NTFY_API_S_VER_2 */
enum iwl_bt_coex_prio_table_event {
BT_COEX_PRIO_TBL_EVT_INIT_CALIB1 = 0,
diff --git a/drivers/net/wireless/iwlwifi/mvm/fw-api-d3.h b/drivers/net/wireless/iwlwifi/mvm/fw-api-d3.h
index 13696fe..10fcc1a 100644
--- a/drivers/net/wireless/iwlwifi/mvm/fw-api-d3.h
+++ b/drivers/net/wireless/iwlwifi/mvm/fw-api-d3.h
@@ -345,6 +345,21 @@
IWL_WOWLAN_WAKEUP_BY_REM_WAKE_WAKEUP_PACKET = BIT(12),
}; /* WOWLAN_WAKE_UP_REASON_API_E_VER_2 */
+struct iwl_wowlan_status_v4 {
+ __le64 replay_ctr;
+ __le16 pattern_number;
+ __le16 non_qos_seq_ctr;
+ __le16 qos_seq_ctr[8];
+ __le32 wakeup_reasons;
+ __le32 rekey_status;
+ __le32 num_of_gtk_rekeys;
+ __le32 transmitted_ndps;
+ __le32 received_beacons;
+ __le32 wake_packet_length;
+ __le32 wake_packet_bufsize;
+ u8 wake_packet[]; /* can be truncated from _length to _bufsize */
+} __packed; /* WOWLAN_STATUSES_API_S_VER_4 */
+
struct iwl_wowlan_gtk_status {
u8 key_index;
u8 reserved[3];
@@ -353,7 +368,7 @@
struct iwl_wowlan_rsc_tsc_params_cmd rsc;
} __packed;
-struct iwl_wowlan_status {
+struct iwl_wowlan_status_v6 {
struct iwl_wowlan_gtk_status gtk;
__le64 replay_ctr;
__le16 pattern_number;
diff --git a/drivers/net/wireless/iwlwifi/mvm/fw-api-rs.h b/drivers/net/wireless/iwlwifi/mvm/fw-api-rs.h
index 8bb5b94..39148b5 100644
--- a/drivers/net/wireless/iwlwifi/mvm/fw-api-rs.h
+++ b/drivers/net/wireless/iwlwifi/mvm/fw-api-rs.h
@@ -334,7 +334,7 @@
*/
struct iwl_lq_cmd {
u8 sta_id;
- u8 reduced_tpc;
+ u8 reserved1;
u16 control;
/* LINK_QUAL_GENERAL_PARAMS_API_S_VER_1 */
u8 flags;
diff --git a/drivers/net/wireless/iwlwifi/mvm/fw-api-scan.h b/drivers/net/wireless/iwlwifi/mvm/fw-api-scan.h
index 6174c02..d73a89e 100644
--- a/drivers/net/wireless/iwlwifi/mvm/fw-api-scan.h
+++ b/drivers/net/wireless/iwlwifi/mvm/fw-api-scan.h
@@ -169,12 +169,8 @@
SCAN_TYPE_DISCOVERY_FORCED = 6,
}; /* SCAN_ACTIVITY_TYPE_E_VER_1 */
-/**
- * Maximal number of channels to scan
- * it should be equal to:
- * max(IWL_NUM_CHANNELS, IWL_NUM_CHANNELS_FAMILY_8000)
- */
-#define MAX_NUM_SCAN_CHANNELS 50
+/* Maximal number of channels to scan */
+#define MAX_NUM_SCAN_CHANNELS 0x24
/**
* struct iwl_scan_cmd - scan request command
@@ -187,9 +183,9 @@
* this number of packets were received (typically 1)
* @passive2active: is auto switching from passive to active during scan allowed
* @rxchain_sel_flags: RXON_RX_CHAIN_*
- * @max_out_time: in usecs, max out of serving channel time
+ * @max_out_time: in TUs, max out of serving channel time
* @suspend_time: how long to pause scan when returning to service channel:
- * bits 0-19: beacon interal in usecs (suspend before executing)
+ * bits 0-19: beacon interal in TUs (suspend before executing)
* bits 20-23: reserved
* bits 24-31: number of beacons (suspend between channels)
* @rxon_flags: RXON_FLG_*
@@ -387,8 +383,8 @@
* @quiet_plcp_th: quiet channel num of packets threshold
* @good_CRC_th: passive to active promotion threshold
* @rx_chain: RXON rx chain.
- * @max_out_time: max uSec to be out of assoceated channel
- * @suspend_time: pause scan this long when returning to service channel
+ * @max_out_time: max TUs to be out of assoceated channel
+ * @suspend_time: pause scan this TUs when returning to service channel
* @flags: RXON flags
* @filter_flags: RXONfilter
* @tx_cmd: tx command for active scan; for 2GHz and for 5GHz.
@@ -538,16 +534,13 @@
*
* IWL_SCAN_OFFLOAD_FLAG_PASS_ALL: pass all results - no filtering.
* IWL_SCAN_OFFLOAD_FLAG_CACHED_CHANNEL: add cached channels to partial scan.
- * IWL_SCAN_OFFLOAD_FLAG_EBS_QUICK_MODE: EBS duration is 100mSec - typical
- * beacon period. Finding channel activity in this mode is not guaranteed.
- * IWL_SCAN_OFFLOAD_FLAG_EBS_ACCURATE_MODE: EBS duration is 200mSec.
- * Assuming beacon period is 100ms finding channel activity is guaranteed.
+ * IWL_SCAN_OFFLOAD_FLAG_ENERGY_SCAN: use energy based scan before partial scan
+ * on A band.
*/
enum iwl_scan_offload_flags {
IWL_SCAN_OFFLOAD_FLAG_PASS_ALL = BIT(0),
IWL_SCAN_OFFLOAD_FLAG_CACHED_CHANNEL = BIT(2),
- IWL_SCAN_OFFLOAD_FLAG_EBS_QUICK_MODE = BIT(5),
- IWL_SCAN_OFFLOAD_FLAG_EBS_ACCURATE_MODE = BIT(6),
+ IWL_SCAN_OFFLOAD_FLAG_ENERGY_SCAN = BIT(3),
};
/**
@@ -570,24 +563,17 @@
IWL_SCAN_OFFLOAD_ABORTED = 2,
};
-enum iwl_scan_ebs_status {
- IWL_SCAN_EBS_SUCCESS,
- IWL_SCAN_EBS_FAILED,
- IWL_SCAN_EBS_CHAN_NOT_FOUND,
-};
-
/**
* iwl_scan_offload_complete - SCAN_OFFLOAD_COMPLETE_NTF_API_S_VER_1
* @last_schedule_line: last schedule line executed (fast or regular)
* @last_schedule_iteration: last scan iteration executed before scan abort
* @status: enum iwl_scan_offload_compleate_status
- * @ebs_status: last EBS status, see IWL_SCAN_EBS_*
*/
struct iwl_scan_offload_complete {
u8 last_schedule_line;
u8 last_schedule_iteration;
u8 status;
- u8 ebs_status;
+ u8 reserved;
} __packed;
/**
diff --git a/drivers/net/wireless/iwlwifi/mvm/fw-api-sta.h b/drivers/net/wireless/iwlwifi/mvm/fw-api-sta.h
index 39cebee..d636478 100644
--- a/drivers/net/wireless/iwlwifi/mvm/fw-api-sta.h
+++ b/drivers/net/wireless/iwlwifi/mvm/fw-api-sta.h
@@ -255,19 +255,22 @@
} __packed;
/**
- * struct iwl_mvm_add_sta_cmd - Add/modify a station in the fw's sta table.
+ * struct iwl_mvm_add_sta_cmd_v5 - Add/modify a station in the fw's sta table.
* ( REPLY_ADD_STA = 0x18 )
* @add_modify: 1: modify existing, 0: add new station
- * @awake_acs:
- * @tid_disable_tx: is tid BIT(tid) enabled for Tx. Clear BIT(x) to enable
- * AMPDU for tid x. Set %STA_MODIFY_TID_DISABLE_TX to change this field.
+ * @unicast_tx_key_id: unicast tx key id. Relevant only when unicast key sent
+ * @multicast_tx_key_id: multicast tx key id. Relevant only when multicast key
+ * sent
* @mac_id_n_color: the Mac context this station belongs to
* @addr[ETH_ALEN]: station's MAC address
* @sta_id: index of station in uCode's station table
* @modify_mask: STA_MODIFY_*, selects which parameters to modify vs. leave
* alone. 1 - modify, 0 - don't change.
+ * @key: look at %iwl_mvm_keyinfo
* @station_flags: look at %iwl_sta_flags
* @station_flags_msk: what of %station_flags have changed
+ * @tid_disable_tx: is tid BIT(tid) enabled for Tx. Clear BIT(x) to enable
+ * AMPDU for tid x. Set %STA_MODIFY_TID_DISABLE_TX to change this field.
* @add_immediate_ba_tid: tid for which to add block-ack support (Rx)
* Set %STA_MODIFY_ADD_BA_TID to use this field, and also set
* add_immediate_ba_ssn.
@@ -291,7 +294,40 @@
* ADD_STA sets up the table entry for one station, either creating a new
* entry, or modifying a pre-existing one.
*/
-struct iwl_mvm_add_sta_cmd {
+struct iwl_mvm_add_sta_cmd_v5 {
+ u8 add_modify;
+ u8 unicast_tx_key_id;
+ u8 multicast_tx_key_id;
+ u8 reserved1;
+ __le32 mac_id_n_color;
+ u8 addr[ETH_ALEN];
+ __le16 reserved2;
+ u8 sta_id;
+ u8 modify_mask;
+ __le16 reserved3;
+ struct iwl_mvm_keyinfo key;
+ __le32 station_flags;
+ __le32 station_flags_msk;
+ __le16 tid_disable_tx;
+ __le16 reserved4;
+ u8 add_immediate_ba_tid;
+ u8 remove_immediate_ba_tid;
+ __le16 add_immediate_ba_ssn;
+ __le16 sleep_tx_count;
+ __le16 sleep_state_flags;
+ __le16 assoc_id;
+ __le16 beamform_flags;
+ __le32 tfd_queue_msk;
+} __packed; /* ADD_STA_CMD_API_S_VER_5 */
+
+/**
+ * struct iwl_mvm_add_sta_cmd_v7 - Add / modify a station
+ * VER_7 of this command is quite similar to VER_5 except
+ * exclusion of all fields related to the security key installation.
+ * It only differs from VER_6 by the "awake_acs" field that is
+ * reserved and ignored in VER_6.
+ */
+struct iwl_mvm_add_sta_cmd_v7 {
u8 add_modify;
u8 awake_acs;
__le16 tid_disable_tx;
diff --git a/drivers/net/wireless/iwlwifi/mvm/fw-api-tx.h b/drivers/net/wireless/iwlwifi/mvm/fw-api-tx.h
index 6cc5f52..8e122f3 100644
--- a/drivers/net/wireless/iwlwifi/mvm/fw-api-tx.h
+++ b/drivers/net/wireless/iwlwifi/mvm/fw-api-tx.h
@@ -482,8 +482,7 @@
u8 pa_integ_res_b[3];
u8 pa_integ_res_c[3];
__le16 measurement_req_id;
- u8 reduced_tpc;
- u8 reserved;
+ __le16 reserved;
__le32 tfd_info;
__le16 seq_ctl;
diff --git a/drivers/net/wireless/iwlwifi/mvm/fw-api.h b/drivers/net/wireless/iwlwifi/mvm/fw-api.h
index 309a9b9..6e75b52 100644
--- a/drivers/net/wireless/iwlwifi/mvm/fw-api.h
+++ b/drivers/net/wireless/iwlwifi/mvm/fw-api.h
@@ -71,7 +71,6 @@
#include "fw-api-power.h"
#include "fw-api-d3.h"
#include "fw-api-coex.h"
-#include "fw-api-scan.h"
/* maximal number of Tx queues in any platform */
#define IWL_MVM_MAX_QUEUES 20
@@ -605,7 +604,52 @@
TE_V1_NOTIF_INTERNAL_FRAG_END = BIT(7),
}; /* MAC_EVENT_ACTION_API_E_VER_2 */
-/* Time event - defines for command API */
+
+/**
+ * struct iwl_time_event_cmd_api_v1 - configuring Time Events
+ * with struct MAC_TIME_EVENT_DATA_API_S_VER_1 (see also
+ * with version 2. determined by IWL_UCODE_TLV_FLAGS)
+ * ( TIME_EVENT_CMD = 0x29 )
+ * @id_and_color: ID and color of the relevant MAC
+ * @action: action to perform, one of FW_CTXT_ACTION_*
+ * @id: this field has two meanings, depending on the action:
+ * If the action is ADD, then it means the type of event to add.
+ * For all other actions it is the unique event ID assigned when the
+ * event was added by the FW.
+ * @apply_time: When to start the Time Event (in GP2)
+ * @max_delay: maximum delay to event's start (apply time), in TU
+ * @depends_on: the unique ID of the event we depend on (if any)
+ * @interval: interval between repetitions, in TU
+ * @interval_reciprocal: 2^32 / interval
+ * @duration: duration of event in TU
+ * @repeat: how many repetitions to do, can be TE_REPEAT_ENDLESS
+ * @dep_policy: one of TE_V1_INDEPENDENT, TE_V1_DEP_OTHER, TE_V1_DEP_TSF
+ * and TE_V1_EVENT_SOCIOPATHIC
+ * @is_present: 0 or 1, are we present or absent during the Time Event
+ * @max_frags: maximal number of fragments the Time Event can be divided to
+ * @notify: notifications using TE_V1_NOTIF_* (whom to notify when)
+ */
+struct iwl_time_event_cmd_v1 {
+ /* COMMON_INDEX_HDR_API_S_VER_1 */
+ __le32 id_and_color;
+ __le32 action;
+ __le32 id;
+ /* MAC_TIME_EVENT_DATA_API_S_VER_1 */
+ __le32 apply_time;
+ __le32 max_delay;
+ __le32 dep_policy;
+ __le32 depends_on;
+ __le32 is_present;
+ __le32 max_frags;
+ __le32 interval;
+ __le32 interval_reciprocal;
+ __le32 duration;
+ __le32 repeat;
+ __le32 notify;
+} __packed; /* MAC_TIME_EVENT_CMD_API_S_VER_1 */
+
+
+/* Time event - defines for command API v2 */
/*
* @TE_V2_FRAG_NONE: fragmentation of the time event is NOT allowed.
@@ -636,7 +680,7 @@
#define TE_V2_PLACEMENT_POS 12
#define TE_V2_ABSENCE_POS 15
-/* Time event policy values
+/* Time event policy values (for time event cmd api v2)
* A notification (both event and fragment) includes a status indicating weather
* the FW was able to schedule the event or not. For fragment start/end
* notification the status is always success. There is no start/end fragment
@@ -683,7 +727,7 @@
};
/**
- * struct iwl_time_event_cmd_api - configuring Time Events
+ * struct iwl_time_event_cmd_api_v2 - configuring Time Events
* with struct MAC_TIME_EVENT_DATA_API_S_VER_2 (see also
* with version 1. determined by IWL_UCODE_TLV_FLAGS)
* ( TIME_EVENT_CMD = 0x29 )
@@ -706,7 +750,7 @@
* TE_EVENT_SOCIOPATHIC
* using TE_ABSENCE and using TE_NOTIF_*
*/
-struct iwl_time_event_cmd {
+struct iwl_time_event_cmd_v2 {
/* COMMON_INDEX_HDR_API_S_VER_1 */
__le32 id_and_color;
__le32 action;
diff --git a/drivers/net/wireless/iwlwifi/mvm/fw-error-dump.h b/drivers/net/wireless/iwlwifi/mvm/fw-error-dump.h
index f381908..58c8941 100644
--- a/drivers/net/wireless/iwlwifi/mvm/fw-error-dump.h
+++ b/drivers/net/wireless/iwlwifi/mvm/fw-error-dump.h
@@ -71,12 +71,10 @@
* enum iwl_fw_error_dump_type - types of data in the dump file
* @IWL_FW_ERROR_DUMP_SRAM:
* @IWL_FW_ERROR_DUMP_REG:
- * @IWL_FW_ERROR_DUMP_RXF:
*/
enum iwl_fw_error_dump_type {
IWL_FW_ERROR_DUMP_SRAM = 0,
IWL_FW_ERROR_DUMP_REG = 1,
- IWL_FW_ERROR_DUMP_RXF = 2,
IWL_FW_ERROR_DUMP_MAX,
};
@@ -91,7 +89,7 @@
__le32 type;
__le32 len;
__u8 data[];
-} __packed;
+} __packed __aligned(4);
/**
* struct iwl_fw_error_dump_file - the layout of the header of the file
@@ -103,6 +101,6 @@
__le32 barker;
__le32 file_len;
u8 data[0];
-} __packed;
+} __packed __aligned(4);
#endif /* __fw_error_dump_h__ */
diff --git a/drivers/net/wireless/iwlwifi/mvm/fw.c b/drivers/net/wireless/iwlwifi/mvm/fw.c
index 3d99cf5..7ce2006 100644
--- a/drivers/net/wireless/iwlwifi/mvm/fw.c
+++ b/drivers/net/wireless/iwlwifi/mvm/fw.c
@@ -288,7 +288,7 @@
goto error;
}
- ret = iwl_send_bt_init_conf(mvm);
+ ret = iwl_send_bt_prio_tbl(mvm);
if (ret)
goto error;
@@ -424,6 +424,10 @@
if (ret)
goto error;
+ ret = iwl_send_bt_prio_tbl(mvm);
+ if (ret)
+ goto error;
+
ret = iwl_send_bt_init_conf(mvm);
if (ret)
goto error;
@@ -464,6 +468,12 @@
/* Initialize tx backoffs to the minimal possible */
iwl_mvm_tt_tx_backoff(mvm, 0);
+ if (!(mvm->fw->ucode_capa.flags & IWL_UCODE_TLV_FLAGS_PM_CMD_SUPPORT)) {
+ ret = iwl_power_legacy_set_cam_mode(mvm);
+ if (ret)
+ goto error;
+ }
+
ret = iwl_mvm_power_update_device(mvm);
if (ret)
goto error;
diff --git a/drivers/net/wireless/iwlwifi/mvm/mac-ctxt.c b/drivers/net/wireless/iwlwifi/mvm/mac-ctxt.c
index 7110ec2..c3c8194 100644
--- a/drivers/net/wireless/iwlwifi/mvm/mac-ctxt.c
+++ b/drivers/net/wireless/iwlwifi/mvm/mac-ctxt.c
@@ -667,10 +667,9 @@
if (vif->bss_conf.qos)
cmd->qos_flags |= cpu_to_le32(MAC_QOS_FLG_UPDATE_EDCA);
- if (vif->bss_conf.use_cts_prot) {
+ if (vif->bss_conf.use_cts_prot)
cmd->protection_flags |= cpu_to_le32(MAC_PROT_FLG_TGG_PROTECT);
- cmd->protection_flags |= cpu_to_le32(MAC_PROT_FLG_SELF_CTS_EN);
- }
+
IWL_DEBUG_RATE(mvm, "use_cts_prot %d, ht_operation_mode %d\n",
vif->bss_conf.use_cts_prot,
vif->bss_conf.ht_operation_mode);
diff --git a/drivers/net/wireless/iwlwifi/mvm/mac80211.c b/drivers/net/wireless/iwlwifi/mvm/mac80211.c
index 2101afb..4d36700 100644
--- a/drivers/net/wireless/iwlwifi/mvm/mac80211.c
+++ b/drivers/net/wireless/iwlwifi/mvm/mac80211.c
@@ -276,7 +276,6 @@
IEEE80211_HW_AMPDU_AGGREGATION |
IEEE80211_HW_TIMING_BEACON_ONLY |
IEEE80211_HW_CONNECTION_MONITOR |
- IEEE80211_HW_SUPPORTS_UAPSD |
IEEE80211_HW_SUPPORTS_DYNAMIC_SMPS |
IEEE80211_HW_SUPPORTS_STATIC_SMPS;
@@ -286,8 +285,6 @@
IEEE80211_RADIOTAP_MCS_HAVE_STBC;
hw->radiotap_vht_details |= IEEE80211_RADIOTAP_VHT_KNOWN_STBC;
hw->rate_control_algorithm = "iwl-mvm-rs";
- hw->uapsd_queues = IWL_UAPSD_AC_INFO;
- hw->uapsd_max_sp_len = IWL_UAPSD_MAX_SP;
/*
* Enable 11w if advertised by firmware and software crypto
@@ -298,9 +295,11 @@
!iwlwifi_mod_params.sw_crypto)
hw->flags |= IEEE80211_HW_MFP_CAPABLE;
- /* Disable uAPSD due to firmware issues */
- if (true)
- hw->flags &= ~IEEE80211_HW_SUPPORTS_UAPSD;
+ if (0 && mvm->fw->ucode_capa.flags & IWL_UCODE_TLV_FLAGS_UAPSD_SUPPORT) {
+ hw->flags |= IEEE80211_HW_SUPPORTS_UAPSD;
+ hw->uapsd_queues = IWL_UAPSD_AC_INFO;
+ hw->uapsd_max_sp_len = IWL_UAPSD_MAX_SP;
+ }
hw->sta_data_size = sizeof(struct iwl_mvm_sta);
hw->vif_data_size = sizeof(struct iwl_mvm_vif);
@@ -310,8 +309,11 @@
BIT(NL80211_IFTYPE_P2P_CLIENT) |
BIT(NL80211_IFTYPE_AP) |
BIT(NL80211_IFTYPE_P2P_GO) |
- BIT(NL80211_IFTYPE_P2P_DEVICE) |
- BIT(NL80211_IFTYPE_ADHOC);
+ BIT(NL80211_IFTYPE_P2P_DEVICE);
+
+ /* IBSS has bugs in older versions */
+ if (IWL_UCODE_API(mvm->fw->ucode_ver) >= 8)
+ hw->wiphy->interface_modes |= BIT(NL80211_IFTYPE_ADHOC);
hw->wiphy->flags |= WIPHY_FLAG_IBSS_RSN;
hw->wiphy->regulatory_flags |= REGULATORY_CUSTOM_REG |
@@ -363,11 +365,14 @@
else
hw->wiphy->flags &= ~WIPHY_FLAG_PS_ON_BY_DEFAULT;
- hw->wiphy->flags |= WIPHY_FLAG_SUPPORTS_SCHED_SCAN;
- hw->wiphy->max_sched_scan_ssids = PROBE_OPTION_MAX;
- hw->wiphy->max_match_sets = IWL_SCAN_MAX_PROFILES;
- /* we create the 802.11 header and zero length SSID IE. */
- hw->wiphy->max_sched_scan_ie_len = SCAN_OFFLOAD_PROBE_REQ_SIZE - 24 - 2;
+ if (mvm->fw->ucode_capa.flags & IWL_UCODE_TLV_FLAGS_SCHED_SCAN) {
+ hw->wiphy->flags |= WIPHY_FLAG_SUPPORTS_SCHED_SCAN;
+ hw->wiphy->max_sched_scan_ssids = PROBE_OPTION_MAX;
+ hw->wiphy->max_match_sets = IWL_SCAN_MAX_PROFILES;
+ /* we create the 802.11 header and zero length SSID IE. */
+ hw->wiphy->max_sched_scan_ie_len =
+ SCAN_OFFLOAD_PROBE_REQ_SIZE - 24 - 2;
+ }
hw->wiphy->features |= NL80211_FEATURE_P2P_GO_CTWIN |
NL80211_FEATURE_P2P_GO_OPPPS;
@@ -381,11 +386,7 @@
}
#ifdef CONFIG_PM_SLEEP
- if (iwl_mvm_is_d0i3_supported(mvm) &&
- device_can_wakeup(mvm->trans->dev)) {
- mvm->wowlan.flags = WIPHY_WOWLAN_ANY;
- hw->wiphy->wowlan = &mvm->wowlan;
- } else if (mvm->fw->img[IWL_UCODE_WOWLAN].sec[0].len &&
+ if (mvm->fw->img[IWL_UCODE_WOWLAN].sec[0].len &&
mvm->trans->ops->d3_suspend &&
mvm->trans->ops->d3_resume &&
device_can_wakeup(mvm->trans->dev)) {
@@ -825,8 +826,9 @@
if (ret)
goto out_remove_mac;
- if (!mvm->bf_allowed_vif &&
- vif->type == NL80211_IFTYPE_STATION && !vif->p2p) {
+ if (!mvm->bf_allowed_vif && false &&
+ vif->type == NL80211_IFTYPE_STATION && !vif->p2p &&
+ mvm->fw->ucode_capa.flags & IWL_UCODE_TLV_FLAGS_BF_UPDATED){
mvm->bf_allowed_vif = mvmvif;
vif->driver_flags |= IEEE80211_VIF_BEACON_FILTER |
IEEE80211_VIF_SUPPORTS_CQM_RSSI;
@@ -1005,7 +1007,7 @@
memcpy(cmd->bssid, vif->bss_conf.bssid, ETH_ALEN);
len = roundup(sizeof(*cmd) + cmd->count * ETH_ALEN, 4);
- ret = iwl_mvm_send_cmd_pdu(mvm, MCAST_FILTER_CMD, CMD_SYNC, len, cmd);
+ ret = iwl_mvm_send_cmd_pdu(mvm, MCAST_FILTER_CMD, CMD_ASYNC, len, cmd);
if (ret)
IWL_ERR(mvm, "mcast filter cmd error. ret=%d\n", ret);
}
@@ -1021,7 +1023,7 @@
if (WARN_ON_ONCE(!mvm->mcast_filter_cmd))
return;
- ieee80211_iterate_active_interfaces(
+ ieee80211_iterate_active_interfaces_atomic(
mvm->hw, IEEE80211_IFACE_ITER_NORMAL,
iwl_mvm_mc_iface_iterator, &iter_data);
}
@@ -1221,10 +1223,6 @@
if (!(mvm->fw->ucode_capa.flags & IWL_UCODE_TLV_FLAGS_BCAST_FILTERING))
return 0;
- /* bcast filtering isn't supported for P2P client */
- if (vif->p2p)
- return 0;
-
if (!iwl_mvm_bcast_filter_build_cmd(mvm, &cmd))
return 0;
@@ -1699,11 +1697,6 @@
ret = iwl_mvm_add_sta(mvm, vif, sta);
} else if (old_state == IEEE80211_STA_NONE &&
new_state == IEEE80211_STA_AUTH) {
- /*
- * EBS may be disabled due to previous failures reported by FW.
- * Reset EBS status here assuming environment has been changed.
- */
- mvm->last_ebs_successful = true;
ret = 0;
} else if (old_state == IEEE80211_STA_AUTH &&
new_state == IEEE80211_STA_ASSOC) {
@@ -1814,6 +1807,11 @@
mutex_lock(&mvm->mutex);
+ if (!iwl_mvm_is_idle(mvm)) {
+ ret = -EBUSY;
+ goto out;
+ }
+
switch (mvm->scan_status) {
case IWL_MVM_SCAN_OS:
IWL_DEBUG_SCAN(mvm, "Stopping previous scan for sched_scan\n");
diff --git a/drivers/net/wireless/iwlwifi/mvm/mvm.h b/drivers/net/wireless/iwlwifi/mvm/mvm.h
index 928f188..d615baf 100644
--- a/drivers/net/wireless/iwlwifi/mvm/mvm.h
+++ b/drivers/net/wireless/iwlwifi/mvm/mvm.h
@@ -164,6 +164,7 @@
MVM_DEBUGFS_PM_SKIP_DTIM_PERIODS = BIT(2),
MVM_DEBUGFS_PM_RX_DATA_TIMEOUT = BIT(3),
MVM_DEBUGFS_PM_TX_DATA_TIMEOUT = BIT(4),
+ MVM_DEBUGFS_PM_DISABLE_POWER_OFF = BIT(5),
MVM_DEBUGFS_PM_LPRX_ENA = BIT(6),
MVM_DEBUGFS_PM_LPRX_RSSI_THRESHOLD = BIT(7),
MVM_DEBUGFS_PM_SNOOZE_ENABLE = BIT(8),
@@ -176,6 +177,7 @@
u32 tx_data_timeout;
bool skip_over_dtim;
u8 skip_dtim_periods;
+ bool disable_power_off;
bool lprx_ena;
u32 lprx_rssi_threshold;
bool snooze_ena;
@@ -230,7 +232,6 @@
IWL_MVM_REF_USER,
IWL_MVM_REF_TX,
IWL_MVM_REF_TX_AGG,
- IWL_MVM_REF_EXIT_WORK,
IWL_MVM_REF_COUNT,
};
@@ -264,7 +265,6 @@
* @uploaded: indicates the MAC context has been added to the device
* @ap_ibss_active: indicates that AP/IBSS is configured and that the interface
* should get quota etc.
- * @pm_enabled - Indicate if MAC power management is allowed
* @monitor_active: indicates that monitor context is configured, and that the
* interface should get quota etc.
* @low_latency: indicates that this interface is in low-latency mode
@@ -283,7 +283,6 @@
bool uploaded;
bool ap_ibss_active;
- bool pm_enabled;
bool monitor_active;
bool low_latency;
struct iwl_mvm_vif_bf_data bf_data;
@@ -452,11 +451,6 @@
int last_frame_idx;
};
-enum {
- D0I3_DEFER_WAKEUP,
- D0I3_PENDING_WAKEUP,
-};
-
struct iwl_mvm {
/* for logger access */
struct device *dev;
@@ -541,8 +535,6 @@
/* Internal station */
struct iwl_mvm_int_sta aux_sta;
- bool last_ebs_successful;
-
u8 scan_last_antenna_idx; /* to toggle TX between antennas */
u8 mgmt_last_antenna_idx;
@@ -586,8 +578,6 @@
void *fw_error_dump;
void *fw_error_sram;
u32 fw_error_sram_len;
- u32 *fw_error_rxf;
- u32 fw_error_rxf_len;
struct led_classdev led;
@@ -611,9 +601,6 @@
bool d0i3_offloading;
struct work_struct d0i3_exit_work;
struct sk_buff_head d0i3_tx;
- /* protect d0i3_suspend_flags */
- struct mutex d0i3_suspend_mutex;
- unsigned long d0i3_suspend_flags;
/* sync d0i3_tx queue and IWL_MVM_STATUS_IN_D0I3 status flag */
spinlock_t d0i3_tx_lock;
wait_queue_head_t d0i3_exit_waitq;
@@ -642,6 +629,8 @@
/* Indicate if device power save is allowed */
bool ps_disabled;
+ /* Indicate if device power management is allowed */
+ bool pm_disabled;
};
/* Extract MVM priv from op_mode and _hw */
@@ -716,7 +705,6 @@
#ifdef CPTCFG_IWLWIFI_DEBUGFS
void iwl_mvm_fw_error_dump(struct iwl_mvm *mvm);
void iwl_mvm_fw_error_sram_dump(struct iwl_mvm *mvm);
-void iwl_mvm_fw_error_rxf_dump(struct iwl_mvm *mvm);
#endif
u8 first_antenna(u8 mask);
u8 iwl_mvm_next_antenna(struct iwl_mvm *mvm, u8 valid, u8 last_idx);
@@ -886,6 +874,8 @@
int rs_pretty_print_rate(char *buf, const u32 rate);
/* power management */
+int iwl_power_legacy_set_cam_mode(struct iwl_mvm *mvm);
+
int iwl_mvm_power_update_device(struct iwl_mvm *mvm);
int iwl_mvm_power_update_mac(struct iwl_mvm *mvm, struct ieee80211_vif *vif);
int iwl_mvm_power_mac_dbgfs_read(struct iwl_mvm *mvm, struct ieee80211_vif *vif,
@@ -932,9 +922,9 @@
void iwl_mvm_ref(struct iwl_mvm *mvm, enum iwl_mvm_ref_type ref_type);
void iwl_mvm_unref(struct iwl_mvm *mvm, enum iwl_mvm_ref_type ref_type);
void iwl_mvm_d0i3_enable_tx(struct iwl_mvm *mvm, __le16 *qos_seq);
-int _iwl_mvm_exit_d0i3(struct iwl_mvm *mvm);
/* BT Coex */
+int iwl_send_bt_prio_tbl(struct iwl_mvm *mvm);
int iwl_send_bt_init_conf(struct iwl_mvm *mvm);
int iwl_mvm_rx_bt_coex_notif(struct iwl_mvm *mvm,
struct iwl_rx_cmd_buffer *rxb,
@@ -946,8 +936,6 @@
struct ieee80211_sta *sta);
bool iwl_mvm_bt_coex_is_mimo_allowed(struct iwl_mvm *mvm,
struct ieee80211_sta *sta);
-bool iwl_mvm_bt_coex_is_tpc_allowed(struct iwl_mvm *mvm,
- enum ieee80211_band band);
u8 iwl_mvm_bt_coex_tx_prio(struct iwl_mvm *mvm, struct ieee80211_hdr *hdr,
struct ieee80211_tx_info *info, u8 ac);
int iwl_mvm_bt_coex_reduced_txp(struct iwl_mvm *mvm, u8 sta_id, bool enable);
@@ -1015,6 +1003,9 @@
return mvmvif->low_latency;
}
+/* Assoc status */
+bool iwl_mvm_is_idle(struct iwl_mvm *mvm);
+
/* Thermal management and CT-kill */
void iwl_mvm_tt_tx_backoff(struct iwl_mvm *mvm, u32 backoff);
void iwl_mvm_tt_handler(struct iwl_mvm *mvm);
diff --git a/drivers/net/wireless/iwlwifi/mvm/ops.c b/drivers/net/wireless/iwlwifi/mvm/ops.c
index dc547af..8e82120 100644
--- a/drivers/net/wireless/iwlwifi/mvm/ops.c
+++ b/drivers/net/wireless/iwlwifi/mvm/ops.c
@@ -402,7 +402,6 @@
mvm->sf_state = SF_UNINIT;
mutex_init(&mvm->mutex);
- mutex_init(&mvm->d0i3_suspend_mutex);
spin_lock_init(&mvm->async_handlers_lock);
INIT_LIST_HEAD(&mvm->time_event_list);
INIT_LIST_HEAD(&mvm->async_handlers_list);
@@ -539,7 +538,6 @@
kfree(mvm->scan_cmd);
vfree(mvm->fw_error_dump);
kfree(mvm->fw_error_sram);
- kfree(mvm->fw_error_rxf);
kfree(mvm->mcast_filter_cmd);
mvm->mcast_filter_cmd = NULL;
@@ -823,9 +821,8 @@
return;
file_len = mvm->fw_error_sram_len +
- mvm->fw_error_rxf_len +
sizeof(*dump_file) +
- sizeof(*dump_data) * 2;
+ sizeof(*dump_data);
dump_file = vmalloc(file_len);
if (!dump_file)
@@ -836,12 +833,7 @@
dump_file->barker = cpu_to_le32(IWL_FW_ERROR_DUMP_BARKER);
dump_file->file_len = cpu_to_le32(file_len);
dump_data = (void *)dump_file->data;
- dump_data->type = cpu_to_le32(IWL_FW_ERROR_DUMP_RXF);
- dump_data->len = cpu_to_le32(mvm->fw_error_rxf_len);
- memcpy(dump_data->data, mvm->fw_error_rxf, mvm->fw_error_rxf_len);
-
- dump_data = (void *)((u8 *)dump_data->data + mvm->fw_error_rxf_len);
- dump_data->type = cpu_to_le32(IWL_FW_ERROR_DUMP_SRAM);
+ dump_data->type = IWL_FW_ERROR_DUMP_SRAM;
dump_data->len = cpu_to_le32(mvm->fw_error_sram_len);
/*
@@ -850,14 +842,6 @@
* mvm->fw_error_sram right now.
*/
memcpy(dump_data->data, mvm->fw_error_sram, mvm->fw_error_sram_len);
-
- kfree(mvm->fw_error_rxf);
- mvm->fw_error_rxf = NULL;
- mvm->fw_error_rxf_len = 0;
-
- kfree(mvm->fw_error_sram);
- mvm->fw_error_sram = NULL;
- mvm->fw_error_sram_len = 0;
}
#endif
@@ -869,7 +853,6 @@
#ifdef CPTCFG_IWLWIFI_DEBUGFS
iwl_mvm_fw_error_sram_dump(mvm);
- iwl_mvm_fw_error_rxf_dump(mvm);
#endif
iwl_mvm_nic_restart(mvm);
@@ -1145,7 +1128,7 @@
.id = WOWLAN_GET_STATUSES,
.flags = CMD_SYNC | CMD_HIGH_PRIO | CMD_WANT_SKB,
};
- struct iwl_wowlan_status *status;
+ struct iwl_wowlan_status_v6 *status;
int ret;
u32 disconnection_reasons, wakeup_reasons;
__le16 *qos_seq = NULL;
@@ -1175,27 +1158,18 @@
iwl_free_resp(&get_status_cmd);
out:
iwl_mvm_d0i3_enable_tx(mvm, qos_seq);
- iwl_mvm_unref(mvm, IWL_MVM_REF_EXIT_WORK);
mutex_unlock(&mvm->mutex);
}
-int _iwl_mvm_exit_d0i3(struct iwl_mvm *mvm)
+static int iwl_mvm_exit_d0i3(struct iwl_op_mode *op_mode)
{
+ struct iwl_mvm *mvm = IWL_OP_MODE_GET_MVM(op_mode);
u32 flags = CMD_ASYNC | CMD_HIGH_PRIO | CMD_SEND_IN_IDLE |
CMD_WAKE_UP_TRANS;
int ret;
IWL_DEBUG_RPM(mvm, "MVM exiting D0i3\n");
- mutex_lock(&mvm->d0i3_suspend_mutex);
- if (test_bit(D0I3_DEFER_WAKEUP, &mvm->d0i3_suspend_flags)) {
- IWL_DEBUG_RPM(mvm, "Deferring d0i3 exit until resume\n");
- __set_bit(D0I3_PENDING_WAKEUP, &mvm->d0i3_suspend_flags);
- mutex_unlock(&mvm->d0i3_suspend_mutex);
- return 0;
- }
- mutex_unlock(&mvm->d0i3_suspend_mutex);
-
ret = iwl_mvm_send_cmd_pdu(mvm, D0I3_END_CMD, flags, 0, NULL);
if (ret)
goto out;
@@ -1209,25 +1183,6 @@
return ret;
}
-static int iwl_mvm_exit_d0i3(struct iwl_op_mode *op_mode)
-{
- struct iwl_mvm *mvm = IWL_OP_MODE_GET_MVM(op_mode);
-
- iwl_mvm_ref(mvm, IWL_MVM_REF_EXIT_WORK);
- return _iwl_mvm_exit_d0i3(mvm);
-}
-
-static void iwl_mvm_napi_add(struct iwl_op_mode *op_mode,
- struct napi_struct *napi,
- struct net_device *napi_dev,
- int (*poll)(struct napi_struct *, int),
- int weight)
-{
- struct iwl_mvm *mvm = IWL_OP_MODE_GET_MVM(op_mode);
-
- ieee80211_napi_add(mvm->hw, napi, napi_dev, poll, weight);
-}
-
static const struct iwl_op_mode_ops iwl_mvm_ops = {
.start = iwl_op_mode_mvm_start,
.stop = iwl_op_mode_mvm_stop,
@@ -1241,5 +1196,4 @@
.nic_config = iwl_mvm_nic_config,
.enter_d0i3 = iwl_mvm_enter_d0i3,
.exit_d0i3 = iwl_mvm_exit_d0i3,
- .napi_add = iwl_mvm_napi_add,
};
diff --git a/drivers/net/wireless/iwlwifi/mvm/power.c b/drivers/net/wireless/iwlwifi/mvm/power.c
index 6af7671..24a08b7 100644
--- a/drivers/net/wireless/iwlwifi/mvm/power.c
+++ b/drivers/net/wireless/iwlwifi/mvm/power.c
@@ -268,30 +268,6 @@
IWL_MVM_PS_HEAVY_RX_THLD_PERCENT;
}
-static bool iwl_mvm_power_allow_uapsd(struct iwl_mvm *mvm,
- struct ieee80211_vif *vif)
-{
- struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif);
-
- if (!memcmp(mvmvif->uapsd_misbehaving_bssid, vif->bss_conf.bssid,
- ETH_ALEN))
- return false;
-
- if (vif->p2p &&
- !(mvm->fw->ucode_capa.flags & IWL_UCODE_TLV_FLAGS_P2P_PS_UAPSD))
- return false;
- /*
- * Avoid using uAPSD if P2P client is associated to GO that uses
- * opportunistic power save. This is due to current FW limitation.
- */
- if (vif->p2p &&
- (vif->bss_conf.p2p_noa_attr.oppps_ctwindow &
- IEEE80211_P2P_OPPPS_ENABLE_BIT))
- return false;
-
- return true;
-}
-
static void iwl_mvm_power_build_cmd(struct iwl_mvm *mvm,
struct ieee80211_vif *vif,
struct iwl_mac_power_cmd *cmd)
@@ -304,6 +280,7 @@
bool radar_detect = false;
struct iwl_mvm_vif *mvmvif __maybe_unused =
iwl_mvm_vif_from_mac80211(vif);
+ bool allow_uapsd = true;
cmd->id_and_color = cpu_to_le32(FW_CMD_ID_AND_COLOR(mvmvif->id,
mvmvif->color));
@@ -326,8 +303,13 @@
cmd->flags |= cpu_to_le16(POWER_FLAGS_POWER_SAVE_ENA_MSK);
+#ifdef CPTCFG_IWLWIFI_DEBUGFS
+ if (mvmvif->dbgfs_pm.mask & MVM_DEBUGFS_PM_DISABLE_POWER_OFF &&
+ mvmvif->dbgfs_pm.disable_power_off)
+ cmd->flags &= cpu_to_le16(~POWER_FLAGS_POWER_SAVE_ENA_MSK);
+#endif
if (!vif->bss_conf.ps || iwl_mvm_vif_low_latency(mvmvif) ||
- !mvmvif->pm_enabled)
+ mvm->pm_disabled)
return;
cmd->flags |= cpu_to_le16(POWER_FLAGS_POWER_MANAGEMENT_ENA_MSK);
@@ -369,7 +351,23 @@
cpu_to_le32(IWL_MVM_WOWLAN_PS_TX_DATA_TIMEOUT);
}
- if (iwl_mvm_power_allow_uapsd(mvm, vif))
+ if (!memcmp(mvmvif->uapsd_misbehaving_bssid, vif->bss_conf.bssid,
+ ETH_ALEN))
+ allow_uapsd = false;
+
+ if (vif->p2p &&
+ !(mvm->fw->ucode_capa.flags & IWL_UCODE_TLV_FLAGS_P2P_PS_UAPSD))
+ allow_uapsd = false;
+ /*
+ * Avoid using uAPSD if P2P client is associated to GO that uses
+ * opportunistic power save. This is due to current FW limitation.
+ */
+ if (vif->p2p &&
+ vif->bss_conf.p2p_noa_attr.oppps_ctwindow &
+ IEEE80211_P2P_OPPPS_ENABLE_BIT)
+ allow_uapsd = false;
+
+ if (allow_uapsd)
iwl_mvm_power_configure_uapsd(mvm, vif, cmd);
#ifdef CPTCFG_IWLWIFI_DEBUGFS
@@ -423,6 +421,13 @@
{
struct iwl_mac_power_cmd cmd = {};
+ if (vif->type != NL80211_IFTYPE_STATION)
+ return 0;
+
+ if (vif->p2p &&
+ !(mvm->fw->ucode_capa.flags & IWL_UCODE_TLV_FLAGS_BSS_P2P_PS_DCM))
+ return 0;
+
iwl_mvm_power_build_cmd(mvm, vif, &cmd);
iwl_mvm_power_log(mvm, &cmd);
#ifdef CPTCFG_IWLWIFI_DEBUGFS
@@ -439,6 +444,12 @@
.flags = cpu_to_le16(DEVICE_POWER_FLAGS_POWER_SAVE_ENA_MSK),
};
+ if (!(mvm->fw->ucode_capa.flags & IWL_UCODE_TLV_FLAGS_PM_CMD_SUPPORT))
+ return 0;
+
+ if (!(mvm->fw->ucode_capa.flags & IWL_UCODE_TLV_FLAGS_DEVICE_PS_CMD))
+ return 0;
+
if (iwlmvm_mod_params.power_scheme == IWL_POWER_SCHEME_CAM)
mvm->ps_disabled = true;
@@ -497,69 +508,86 @@
return 0;
}
-struct iwl_power_vifs {
+struct iwl_power_constraint {
struct ieee80211_vif *bf_vif;
struct ieee80211_vif *bss_vif;
struct ieee80211_vif *p2p_vif;
- struct ieee80211_vif *ap_vif;
- struct ieee80211_vif *monitor_vif;
- bool p2p_active;
- bool bss_active;
- bool ap_active;
- bool monitor_active;
+ u16 bss_phyctx_id;
+ u16 p2p_phyctx_id;
+ bool pm_disabled;
+ bool ps_disabled;
+ struct iwl_mvm *mvm;
};
static void iwl_mvm_power_iterator(void *_data, u8 *mac,
struct ieee80211_vif *vif)
{
struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif);
- struct iwl_power_vifs *power_iterator = _data;
+ struct iwl_power_constraint *power_iterator = _data;
+ struct iwl_mvm *mvm = power_iterator->mvm;
- mvmvif->pm_enabled = false;
switch (ieee80211_vif_type_p2p(vif)) {
case NL80211_IFTYPE_P2P_DEVICE:
break;
case NL80211_IFTYPE_P2P_GO:
case NL80211_IFTYPE_AP:
- /* only a single MAC of the same type */
- WARN_ON(power_iterator->ap_vif);
- power_iterator->ap_vif = vif;
- if (mvmvif->phy_ctxt)
- if (mvmvif->phy_ctxt->id < MAX_PHYS)
- power_iterator->ap_active = true;
+ /* no BSS power mgmt if we have an active AP */
+ if (mvmvif->ap_ibss_active)
+ power_iterator->pm_disabled = true;
break;
case NL80211_IFTYPE_MONITOR:
- /* only a single MAC of the same type */
- WARN_ON(power_iterator->monitor_vif);
- power_iterator->monitor_vif = vif;
- if (mvmvif->phy_ctxt)
- if (mvmvif->phy_ctxt->id < MAX_PHYS)
- power_iterator->monitor_active = true;
+ /* no BSS power mgmt and no device power save */
+ power_iterator->pm_disabled = true;
+ power_iterator->ps_disabled = true;
break;
case NL80211_IFTYPE_P2P_CLIENT:
- /* only a single MAC of the same type */
+ if (mvmvif->phy_ctxt)
+ power_iterator->p2p_phyctx_id = mvmvif->phy_ctxt->id;
+
+ /* we should have only one P2P vif */
WARN_ON(power_iterator->p2p_vif);
power_iterator->p2p_vif = vif;
- if (mvmvif->phy_ctxt)
- if (mvmvif->phy_ctxt->id < MAX_PHYS)
- power_iterator->p2p_active = true;
+
+ IWL_DEBUG_POWER(mvm, "p2p: p2p_id=%d, bss_id=%d\n",
+ power_iterator->p2p_phyctx_id,
+ power_iterator->bss_phyctx_id);
+ if (!(mvm->fw->ucode_capa.flags &
+ IWL_UCODE_TLV_FLAGS_BSS_P2P_PS_DCM)) {
+ /* no BSS power mgmt if we have a P2P client*/
+ power_iterator->pm_disabled = true;
+ } else if (power_iterator->p2p_phyctx_id < MAX_PHYS &&
+ power_iterator->bss_phyctx_id < MAX_PHYS &&
+ power_iterator->p2p_phyctx_id ==
+ power_iterator->bss_phyctx_id) {
+ power_iterator->pm_disabled = true;
+ }
break;
case NL80211_IFTYPE_STATION:
- /* only a single MAC of the same type */
+ if (mvmvif->phy_ctxt)
+ power_iterator->bss_phyctx_id = mvmvif->phy_ctxt->id;
+
+ /* we should have only one BSS vif */
WARN_ON(power_iterator->bss_vif);
power_iterator->bss_vif = vif;
- if (mvmvif->phy_ctxt)
- if (mvmvif->phy_ctxt->id < MAX_PHYS)
- power_iterator->bss_active = true;
if (mvmvif->bf_data.bf_enabled &&
!WARN_ON(power_iterator->bf_vif))
power_iterator->bf_vif = vif;
+ IWL_DEBUG_POWER(mvm, "bss: p2p_id=%d, bss_id=%d\n",
+ power_iterator->p2p_phyctx_id,
+ power_iterator->bss_phyctx_id);
+ if (mvm->fw->ucode_capa.flags &
+ IWL_UCODE_TLV_FLAGS_BSS_P2P_PS_DCM &&
+ (power_iterator->p2p_phyctx_id < MAX_PHYS &&
+ power_iterator->bss_phyctx_id < MAX_PHYS &&
+ power_iterator->p2p_phyctx_id ==
+ power_iterator->bss_phyctx_id))
+ power_iterator->pm_disabled = true;
break;
default:
@@ -568,118 +596,70 @@
}
static void
-iwl_mvm_power_set_pm(struct iwl_mvm *mvm,
- struct iwl_power_vifs *vifs)
+iwl_mvm_power_get_global_constraint(struct iwl_mvm *mvm,
+ struct iwl_power_constraint *constraint)
{
- struct iwl_mvm_vif *bss_mvmvif = NULL;
- struct iwl_mvm_vif *p2p_mvmvif = NULL;
- struct iwl_mvm_vif *ap_mvmvif = NULL;
- bool client_same_channel = false;
- bool ap_same_channel = false;
-
lockdep_assert_held(&mvm->mutex);
- /* get vifs info + set pm_enable to false */
+ if (iwlmvm_mod_params.power_scheme == IWL_POWER_SCHEME_CAM) {
+ constraint->pm_disabled = true;
+ constraint->ps_disabled = true;
+ }
+
ieee80211_iterate_active_interfaces_atomic(mvm->hw,
IEEE80211_IFACE_ITER_NORMAL,
- iwl_mvm_power_iterator, vifs);
-
- if (vifs->bss_vif)
- bss_mvmvif = iwl_mvm_vif_from_mac80211(vifs->bss_vif);
-
- if (vifs->p2p_vif)
- p2p_mvmvif = iwl_mvm_vif_from_mac80211(vifs->p2p_vif);
-
- if (vifs->ap_vif)
- ap_mvmvif = iwl_mvm_vif_from_mac80211(vifs->ap_vif);
-
- /* enable PM on bss if bss stand alone */
- if (vifs->bss_active && !vifs->p2p_active && !vifs->ap_active) {
- bss_mvmvif->pm_enabled = true;
- return;
- }
-
- /* enable PM on p2p if p2p stand alone */
- if (vifs->p2p_active && !vifs->bss_active && !vifs->ap_active) {
- if (mvm->fw->ucode_capa.flags & IWL_UCODE_TLV_FLAGS_P2P_PM)
- p2p_mvmvif->pm_enabled = true;
- return;
- }
-
- if (vifs->bss_active && vifs->p2p_active)
- client_same_channel = (bss_mvmvif->phy_ctxt->id ==
- p2p_mvmvif->phy_ctxt->id);
- if (vifs->bss_active && vifs->ap_active)
- ap_same_channel = (bss_mvmvif->phy_ctxt->id ==
- ap_mvmvif->phy_ctxt->id);
-
- /* bss is not stand alone: enable PM if alone on its channel */
- if (vifs->bss_active && !(client_same_channel || ap_same_channel) &&
- (mvm->fw->ucode_capa.flags & IWL_UCODE_TLV_FLAGS_BSS_P2P_PS_DCM)) {
- bss_mvmvif->pm_enabled = true;
- return;
- }
-
- /*
- * There is only one channel in the system and there are only
- * bss and p2p clients that share it
- */
- if (client_same_channel && !vifs->ap_active &&
- (mvm->fw->ucode_capa.flags & IWL_UCODE_TLV_FLAGS_BSS_P2P_PS_SCM)) {
- /* share same channel*/
- bss_mvmvif->pm_enabled = true;
- if (mvm->fw->ucode_capa.flags & IWL_UCODE_TLV_FLAGS_P2P_PM)
- p2p_mvmvif->pm_enabled = true;
- }
+ iwl_mvm_power_iterator, constraint);
}
int iwl_mvm_power_update_mac(struct iwl_mvm *mvm, struct ieee80211_vif *vif)
{
- struct iwl_mvm_vif *mvmvif;
- struct iwl_power_vifs vifs = {};
+ struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif);
+ struct iwl_power_constraint constraint = {
+ .p2p_phyctx_id = MAX_PHYS,
+ .bss_phyctx_id = MAX_PHYS,
+ .mvm = mvm,
+ };
bool ba_enable;
int ret;
lockdep_assert_held(&mvm->mutex);
- iwl_mvm_power_set_pm(mvm, &vifs);
-
- /* disable PS if CAM */
- if (iwlmvm_mod_params.power_scheme == IWL_POWER_SCHEME_CAM) {
- mvm->ps_disabled = true;
- } else {
- /* don't update device power state unless we add / remove monitor */
- if (vifs.monitor_vif) {
- if (vifs.monitor_active)
- mvm->ps_disabled = true;
- ret = iwl_mvm_power_update_device(mvm);
- if (ret)
- return ret;
- }
- }
-
- if (vifs.bss_vif) {
- ret = iwl_mvm_power_send_cmd(mvm, vifs.bss_vif);
- if (ret)
- return ret;
- }
-
- if (vifs.p2p_vif) {
- ret = iwl_mvm_power_send_cmd(mvm, vifs.p2p_vif);
- if (ret)
- return ret;
- }
-
- if (!vifs.bf_vif)
+ if (!(mvm->fw->ucode_capa.flags & IWL_UCODE_TLV_FLAGS_PM_CMD_SUPPORT))
return 0;
- vif = vifs.bf_vif;
+ iwl_mvm_power_get_global_constraint(mvm, &constraint);
+ mvm->ps_disabled = constraint.ps_disabled;
+ mvm->pm_disabled = constraint.pm_disabled;
+
+ /* don't update device power state unless we add / remove monitor */
+ if (vif->type == NL80211_IFTYPE_MONITOR) {
+ ret = iwl_mvm_power_update_device(mvm);
+ if (ret)
+ return ret;
+ }
+
+ if (constraint.bss_vif) {
+ ret = iwl_mvm_power_send_cmd(mvm, constraint.bss_vif);
+ if (ret)
+ return ret;
+ }
+
+ if (constraint.p2p_vif) {
+ ret = iwl_mvm_power_send_cmd(mvm, constraint.p2p_vif);
+ if (ret)
+ return ret;
+ }
+
+ if (!constraint.bf_vif)
+ return 0;
+
+ vif = constraint.bf_vif;
mvmvif = iwl_mvm_vif_from_mac80211(vif);
- ba_enable = !(!mvmvif->pm_enabled || mvm->ps_disabled ||
+ ba_enable = !(constraint.pm_disabled || constraint.ps_disabled ||
!vif->bss_conf.ps || iwl_mvm_vif_low_latency(mvmvif));
- return iwl_mvm_update_beacon_abort(mvm, vifs.bf_vif, ba_enable);
+ return iwl_mvm_update_beacon_abort(mvm, constraint.bf_vif, ba_enable);
}
#ifdef CPTCFG_IWLWIFI_DEBUGFS
@@ -691,10 +671,19 @@
struct iwl_mac_power_cmd cmd = {};
int pos = 0;
+ if (WARN_ON(!(mvm->fw->ucode_capa.flags &
+ IWL_UCODE_TLV_FLAGS_PM_CMD_SUPPORT)))
+ return 0;
+
mutex_lock(&mvm->mutex);
memcpy(&cmd, &mvmvif->mac_pwr_cmd, sizeof(cmd));
mutex_unlock(&mvm->mutex);
+ if (!(mvm->fw->ucode_capa.flags & IWL_UCODE_TLV_FLAGS_DEVICE_PS_CMD))
+ pos += scnprintf(buf+pos, bufsz-pos, "disable_power_off = %d\n",
+ (cmd.flags &
+ cpu_to_le16(POWER_FLAGS_POWER_SAVE_ENA_MSK)) ?
+ 0 : 1);
pos += scnprintf(buf+pos, bufsz-pos, "power_scheme = %d\n",
iwlmvm_mod_params.power_scheme);
pos += scnprintf(buf+pos, bufsz-pos, "flags = 0x%x\n",
@@ -837,7 +826,8 @@
struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif);
int ret;
- if (vif->type != NL80211_IFTYPE_STATION || vif->p2p)
+ if (!(mvm->fw->ucode_capa.flags & IWL_UCODE_TLV_FLAGS_BF_UPDATED) ||
+ vif->type != NL80211_IFTYPE_STATION || vif->p2p)
return 0;
ret = iwl_mvm_beacon_filter_send_cmd(mvm, &cmd, flags);
@@ -924,3 +914,13 @@
return iwl_mvm_enable_beacon_filter(mvm, vif, flags);
}
+
+int iwl_power_legacy_set_cam_mode(struct iwl_mvm *mvm)
+{
+ struct iwl_powertable_cmd cmd = {
+ .keep_alive_seconds = POWER_KEEP_ALIVE_PERIOD_SEC,
+ };
+
+ return iwl_mvm_send_cmd_pdu(mvm, POWER_TABLE_CMD, CMD_SYNC,
+ sizeof(cmd), &cmd);
+}
diff --git a/drivers/net/wireless/iwlwifi/mvm/rs.c b/drivers/net/wireless/iwlwifi/mvm/rs.c
index 2ac2bd6..f0ecfe9 100644
--- a/drivers/net/wireless/iwlwifi/mvm/rs.c
+++ b/drivers/net/wireless/iwlwifi/mvm/rs.c
@@ -527,9 +527,6 @@
IWL_DEBUG_RATE(mvm, "Clearing up window stats\n");
for (i = 0; i < IWL_RATE_COUNT; i++)
rs_rate_scale_clear_window(&tbl->win[i]);
-
- for (i = 0; i < ARRAY_SIZE(tbl->tpc_win); i++)
- rs_rate_scale_clear_window(&tbl->tpc_win[i]);
}
static inline u8 rs_is_valid_ant(u8 valid_antenna, u8 ant_type)
@@ -659,34 +656,17 @@
return 0;
}
-static int rs_collect_tx_data(struct iwl_lq_sta *lq_sta,
- struct iwl_scale_tbl_info *tbl,
- int scale_index, int attempts, int successes,
- u8 reduced_txp)
+static int rs_collect_tx_data(struct iwl_scale_tbl_info *tbl,
+ int scale_index, int attempts, int successes)
{
struct iwl_rate_scale_data *window = NULL;
- int ret;
if (scale_index < 0 || scale_index >= IWL_RATE_COUNT)
return -EINVAL;
- if (tbl->column != RS_COLUMN_INVALID) {
- lq_sta->tx_stats[tbl->column][scale_index].total += attempts;
- lq_sta->tx_stats[tbl->column][scale_index].success += successes;
- }
-
/* Select window for current tx bit rate */
window = &(tbl->win[scale_index]);
- ret = _rs_collect_tx_data(tbl, scale_index, attempts, successes,
- window);
- if (ret)
- return ret;
-
- if (WARN_ON_ONCE(reduced_txp > TPC_MAX_REDUCTION))
- return -EINVAL;
-
- window = &tbl->tpc_win[reduced_txp];
return _rs_collect_tx_data(tbl, scale_index, attempts, successes,
window);
}
@@ -1020,7 +1000,6 @@
u32 ucode_rate;
struct rs_rate rate;
struct iwl_scale_tbl_info *curr_tbl, *other_tbl, *tmp_tbl;
- u8 reduced_txp = (uintptr_t)info->status.status_driver_data[0];
/* Treat uninitialized rate scaling data same as non-existing. */
if (!lq_sta) {
@@ -1162,10 +1141,9 @@
if (info->flags & IEEE80211_TX_STAT_AMPDU) {
ucode_rate = le32_to_cpu(table->rs_table[0]);
rs_rate_from_ucode_rate(ucode_rate, info->band, &rate);
- rs_collect_tx_data(lq_sta, curr_tbl, rate.index,
+ rs_collect_tx_data(curr_tbl, rate.index,
info->status.ampdu_len,
- info->status.ampdu_ack_len,
- reduced_txp);
+ info->status.ampdu_ack_len);
/* Update success/fail counts if not searching for new mode */
if (lq_sta->rs_state == RS_STATE_STAY_IN_COLUMN) {
@@ -1198,9 +1176,8 @@
else
continue;
- rs_collect_tx_data(lq_sta, tmp_tbl, rate.index, 1,
- i < retries ? 0 : legacy_success,
- reduced_txp);
+ rs_collect_tx_data(tmp_tbl, rate.index, 1,
+ i < retries ? 0 : legacy_success);
}
/* Update success/fail counts if not searching for new mode */
@@ -1211,7 +1188,6 @@
}
/* The last TX rate is cached in lq_sta; it's set in if/else above */
lq_sta->last_rate_n_flags = ucode_rate;
- IWL_DEBUG_RATE(mvm, "reduced txpower: %d\n", reduced_txp);
done:
/* See if there's a better rate or modulation mode to try. */
if (sta && sta->supp_rates[sband->band])
@@ -1793,198 +1769,6 @@
return action;
}
-static void rs_get_adjacent_txp(struct iwl_mvm *mvm, int index,
- int *weaker, int *stronger)
-{
- *weaker = index + TPC_TX_POWER_STEP;
- if (*weaker > TPC_MAX_REDUCTION)
- *weaker = TPC_INVALID;
-
- *stronger = index - TPC_TX_POWER_STEP;
- if (*stronger < 0)
- *stronger = TPC_INVALID;
-}
-
-static bool rs_tpc_allowed(struct iwl_mvm *mvm, struct rs_rate *rate,
- enum ieee80211_band band)
-{
- int index = rate->index;
-
- /*
- * allow tpc only if power management is enabled, or bt coex
- * activity grade allows it and we are on 2.4Ghz.
- */
- if (iwlmvm_mod_params.power_scheme == IWL_POWER_SCHEME_CAM &&
- !iwl_mvm_bt_coex_is_tpc_allowed(mvm, band))
- return false;
-
- IWL_DEBUG_RATE(mvm, "check rate, table type: %d\n", rate->type);
- if (is_legacy(rate))
- return index == IWL_RATE_54M_INDEX;
- if (is_ht(rate))
- return index == IWL_RATE_MCS_7_INDEX;
- if (is_vht(rate))
- return index == IWL_RATE_MCS_7_INDEX ||
- index == IWL_RATE_MCS_8_INDEX ||
- index == IWL_RATE_MCS_9_INDEX;
-
- WARN_ON_ONCE(1);
- return false;
-}
-
-enum tpc_action {
- TPC_ACTION_STAY,
- TPC_ACTION_DECREASE,
- TPC_ACTION_INCREASE,
- TPC_ACTION_NO_RESTIRCTION,
-};
-
-static enum tpc_action rs_get_tpc_action(struct iwl_mvm *mvm,
- s32 sr, int weak, int strong,
- int current_tpt,
- int weak_tpt, int strong_tpt)
-{
- /* stay until we have valid tpt */
- if (current_tpt == IWL_INVALID_VALUE) {
- IWL_DEBUG_RATE(mvm, "no current tpt. stay.\n");
- return TPC_ACTION_STAY;
- }
-
- /* Too many failures, increase txp */
- if (sr <= TPC_SR_FORCE_INCREASE || current_tpt == 0) {
- IWL_DEBUG_RATE(mvm, "increase txp because of weak SR\n");
- return TPC_ACTION_NO_RESTIRCTION;
- }
-
- /* try decreasing first if applicable */
- if (weak != TPC_INVALID) {
- if (weak_tpt == IWL_INVALID_VALUE &&
- (strong_tpt == IWL_INVALID_VALUE ||
- current_tpt >= strong_tpt)) {
- IWL_DEBUG_RATE(mvm,
- "no weak txp measurement. decrease txp\n");
- return TPC_ACTION_DECREASE;
- }
-
- if (weak_tpt > current_tpt) {
- IWL_DEBUG_RATE(mvm,
- "lower txp has better tpt. decrease txp\n");
- return TPC_ACTION_DECREASE;
- }
- }
-
- /* next, increase if needed */
- if (sr < TPC_SR_NO_INCREASE && strong != TPC_INVALID) {
- if (weak_tpt == IWL_INVALID_VALUE &&
- strong_tpt != IWL_INVALID_VALUE &&
- current_tpt < strong_tpt) {
- IWL_DEBUG_RATE(mvm,
- "higher txp has better tpt. increase txp\n");
- return TPC_ACTION_INCREASE;
- }
-
- if (weak_tpt < current_tpt &&
- (strong_tpt == IWL_INVALID_VALUE ||
- strong_tpt > current_tpt)) {
- IWL_DEBUG_RATE(mvm,
- "lower txp has worse tpt. increase txp\n");
- return TPC_ACTION_INCREASE;
- }
- }
-
- IWL_DEBUG_RATE(mvm, "no need to increase or decrease txp - stay\n");
- return TPC_ACTION_STAY;
-}
-
-static bool rs_tpc_perform(struct iwl_mvm *mvm,
- struct ieee80211_sta *sta,
- struct iwl_lq_sta *lq_sta,
- struct iwl_scale_tbl_info *tbl)
-{
- struct iwl_mvm_sta *mvm_sta = (void *)sta->drv_priv;
- struct ieee80211_vif *vif = mvm_sta->vif;
- struct ieee80211_chanctx_conf *chanctx_conf;
- enum ieee80211_band band;
- struct iwl_rate_scale_data *window;
- struct rs_rate *rate = &tbl->rate;
- enum tpc_action action;
- s32 sr;
- u8 cur = lq_sta->lq.reduced_tpc;
- int current_tpt;
- int weak, strong;
- int weak_tpt = IWL_INVALID_VALUE, strong_tpt = IWL_INVALID_VALUE;
-
-#ifdef CPTCFG_MAC80211_DEBUGFS
- if (lq_sta->dbg_fixed_txp_reduction <= TPC_MAX_REDUCTION) {
- IWL_DEBUG_RATE(mvm, "fixed tpc: %d",
- lq_sta->dbg_fixed_txp_reduction);
- lq_sta->lq.reduced_tpc = lq_sta->dbg_fixed_txp_reduction;
- return cur != lq_sta->dbg_fixed_txp_reduction;
- }
-#endif
-
- rcu_read_lock();
- chanctx_conf = rcu_dereference(vif->chanctx_conf);
- if (WARN_ON(!chanctx_conf))
- band = IEEE80211_NUM_BANDS;
- else
- band = chanctx_conf->def.chan->band;
- rcu_read_unlock();
-
- if (!rs_tpc_allowed(mvm, rate, band)) {
- IWL_DEBUG_RATE(mvm,
- "tpc is not allowed. remove txp restrictions");
- lq_sta->lq.reduced_tpc = TPC_NO_REDUCTION;
- return cur != TPC_NO_REDUCTION;
- }
-
- rs_get_adjacent_txp(mvm, cur, &weak, &strong);
-
- /* Collect measured throughputs for current and adjacent rates */
- window = tbl->tpc_win;
- sr = window[cur].success_ratio;
- current_tpt = window[cur].average_tpt;
- if (weak != TPC_INVALID)
- weak_tpt = window[weak].average_tpt;
- if (strong != TPC_INVALID)
- strong_tpt = window[strong].average_tpt;
-
- IWL_DEBUG_RATE(mvm,
- "(TPC: %d): cur_tpt %d SR %d weak %d strong %d weak_tpt %d strong_tpt %d\n",
- cur, current_tpt, sr, weak, strong,
- weak_tpt, strong_tpt);
-
- action = rs_get_tpc_action(mvm, sr, weak, strong,
- current_tpt, weak_tpt, strong_tpt);
-
- /* override actions if we are on the edge */
- if (weak == TPC_INVALID && action == TPC_ACTION_DECREASE) {
- IWL_DEBUG_RATE(mvm, "already in lowest txp, stay");
- action = TPC_ACTION_STAY;
- } else if (strong == TPC_INVALID &&
- (action == TPC_ACTION_INCREASE ||
- action == TPC_ACTION_NO_RESTIRCTION)) {
- IWL_DEBUG_RATE(mvm, "already in highest txp, stay");
- action = TPC_ACTION_STAY;
- }
-
- switch (action) {
- case TPC_ACTION_DECREASE:
- lq_sta->lq.reduced_tpc = weak;
- return true;
- case TPC_ACTION_INCREASE:
- lq_sta->lq.reduced_tpc = strong;
- return true;
- case TPC_ACTION_NO_RESTIRCTION:
- lq_sta->lq.reduced_tpc = TPC_NO_REDUCTION;
- return true;
- case TPC_ACTION_STAY:
- /* do nothing */
- break;
- }
- return false;
-}
-
/*
* Do rate scaling and search for new modulation mode.
*/
@@ -2235,8 +2019,6 @@
break;
case RS_ACTION_STAY:
/* No change */
- update_lq = rs_tpc_perform(mvm, sta, lq_sta, tbl);
- break;
default:
break;
}
@@ -2696,7 +2478,6 @@
lq_sta->is_agg = 0;
#ifdef CPTCFG_MAC80211_DEBUGFS
lq_sta->dbg_fixed_rate = 0;
- lq_sta->dbg_fixed_txp_reduction = TPC_INVALID;
#endif
#ifdef CPTCFG_IWLWIFI_DEBUGFS
iwl_mvm_reset_frame_stats(mvm, &mvm->drv_rx_stats);
@@ -2872,7 +2653,6 @@
rs_build_rates_table_from_fixed(mvm, lq_cmd,
lq_sta->band,
lq_sta->dbg_fixed_rate);
- lq_cmd->reduced_tpc = 0;
ant = (lq_sta->dbg_fixed_rate & RATE_MCS_ANT_ABC_MSK) >>
RATE_MCS_ANT_POS;
} else
@@ -3003,6 +2783,7 @@
size_t buf_size;
u32 parsed_rate;
+
mvm = lq_sta->drv;
memset(buf, 0, sizeof(buf));
buf_size = min(count, sizeof(buf) - 1);
@@ -3075,7 +2856,6 @@
lq_sta->lq.agg_disable_start_th,
lq_sta->lq.agg_frame_cnt_limit);
- desc += sprintf(buff+desc, "reduced tpc=%d\n", lq_sta->lq.reduced_tpc);
desc += sprintf(buff+desc,
"Start idx [0]=0x%x [1]=0x%x [2]=0x%x [3]=0x%x\n",
lq_sta->lq.initial_rate_index[0],
@@ -3148,94 +2928,6 @@
.llseek = default_llseek,
};
-static ssize_t rs_sta_dbgfs_drv_tx_stats_read(struct file *file,
- char __user *user_buf,
- size_t count, loff_t *ppos)
-{
- static const char * const column_name[] = {
- [RS_COLUMN_LEGACY_ANT_A] = "LEGACY_ANT_A",
- [RS_COLUMN_LEGACY_ANT_B] = "LEGACY_ANT_B",
- [RS_COLUMN_SISO_ANT_A] = "SISO_ANT_A",
- [RS_COLUMN_SISO_ANT_B] = "SISO_ANT_B",
- [RS_COLUMN_SISO_ANT_A_SGI] = "SISO_ANT_A_SGI",
- [RS_COLUMN_SISO_ANT_B_SGI] = "SISO_ANT_B_SGI",
- [RS_COLUMN_MIMO2] = "MIMO2",
- [RS_COLUMN_MIMO2_SGI] = "MIMO2_SGI",
- };
-
- static const char * const rate_name[] = {
- [IWL_RATE_1M_INDEX] = "1M",
- [IWL_RATE_2M_INDEX] = "2M",
- [IWL_RATE_5M_INDEX] = "5.5M",
- [IWL_RATE_11M_INDEX] = "11M",
- [IWL_RATE_6M_INDEX] = "6M|MCS0",
- [IWL_RATE_9M_INDEX] = "9M",
- [IWL_RATE_12M_INDEX] = "12M|MCS1",
- [IWL_RATE_18M_INDEX] = "18M|MCS2",
- [IWL_RATE_24M_INDEX] = "24M|MCS3",
- [IWL_RATE_36M_INDEX] = "36M|MCS4",
- [IWL_RATE_48M_INDEX] = "48M|MCS5",
- [IWL_RATE_54M_INDEX] = "54M|MCS6",
- [IWL_RATE_MCS_7_INDEX] = "MCS7",
- [IWL_RATE_MCS_8_INDEX] = "MCS8",
- [IWL_RATE_MCS_9_INDEX] = "MCS9",
- };
-
- char *buff, *pos, *endpos;
- int col, rate;
- ssize_t ret;
- struct iwl_lq_sta *lq_sta = file->private_data;
- struct rs_rate_stats *stats;
- static const size_t bufsz = 1024;
-
- buff = kmalloc(bufsz, GFP_KERNEL);
- if (!buff)
- return -ENOMEM;
-
- pos = buff;
- endpos = pos + bufsz;
-
- pos += scnprintf(pos, endpos - pos, "COLUMN,");
- for (rate = 0; rate < IWL_RATE_COUNT; rate++)
- pos += scnprintf(pos, endpos - pos, "%s,", rate_name[rate]);
- pos += scnprintf(pos, endpos - pos, "\n");
-
- for (col = 0; col < RS_COLUMN_COUNT; col++) {
- pos += scnprintf(pos, endpos - pos,
- "%s,", column_name[col]);
-
- for (rate = 0; rate < IWL_RATE_COUNT; rate++) {
- stats = &(lq_sta->tx_stats[col][rate]);
- pos += scnprintf(pos, endpos - pos,
- "%llu/%llu,",
- stats->success,
- stats->total);
- }
- pos += scnprintf(pos, endpos - pos, "\n");
- }
-
- ret = simple_read_from_buffer(user_buf, count, ppos, buff, pos - buff);
- kfree(buff);
- return ret;
-}
-
-static ssize_t rs_sta_dbgfs_drv_tx_stats_write(struct file *file,
- const char __user *user_buf,
- size_t count, loff_t *ppos)
-{
- struct iwl_lq_sta *lq_sta = file->private_data;
- memset(lq_sta->tx_stats, 0, sizeof(lq_sta->tx_stats));
-
- return count;
-}
-
-static const struct file_operations rs_sta_dbgfs_drv_tx_stats_ops = {
- .read = rs_sta_dbgfs_drv_tx_stats_read,
- .write = rs_sta_dbgfs_drv_tx_stats_write,
- .open = simple_open,
- .llseek = default_llseek,
-};
-
static void rs_add_debugfs(void *mvm, void *mvm_sta, struct dentry *dir)
{
struct iwl_lq_sta *lq_sta = mvm_sta;
@@ -3245,15 +2937,9 @@
lq_sta->rs_sta_dbgfs_stats_table_file =
debugfs_create_file("rate_stats_table", S_IRUSR, dir,
lq_sta, &rs_sta_dbgfs_stats_table_ops);
- lq_sta->rs_sta_dbgfs_drv_tx_stats_file =
- debugfs_create_file("drv_tx_stats", S_IRUSR | S_IWUSR, dir,
- lq_sta, &rs_sta_dbgfs_drv_tx_stats_ops);
lq_sta->rs_sta_dbgfs_tx_agg_tid_en_file =
debugfs_create_u8("tx_agg_tid_enable", S_IRUSR | S_IWUSR, dir,
&lq_sta->tx_agg_tid_en);
- lq_sta->rs_sta_dbgfs_reduced_txp_file =
- debugfs_create_u8("reduced_tpc", S_IRUSR | S_IWUSR, dir,
- &lq_sta->dbg_fixed_txp_reduction);
}
static void rs_remove_debugfs(void *mvm, void *mvm_sta)
@@ -3261,9 +2947,7 @@
struct iwl_lq_sta *lq_sta = mvm_sta;
debugfs_remove(lq_sta->rs_sta_dbgfs_scale_table_file);
debugfs_remove(lq_sta->rs_sta_dbgfs_stats_table_file);
- debugfs_remove(lq_sta->rs_sta_dbgfs_drv_tx_stats_file);
debugfs_remove(lq_sta->rs_sta_dbgfs_tx_agg_tid_en_file);
- debugfs_remove(lq_sta->rs_sta_dbgfs_reduced_txp_file);
}
#endif
diff --git a/drivers/net/wireless/iwlwifi/mvm/rs.h b/drivers/net/wireless/iwlwifi/mvm/rs.h
index aa3b630..3f090ed 100644
--- a/drivers/net/wireless/iwlwifi/mvm/rs.h
+++ b/drivers/net/wireless/iwlwifi/mvm/rs.h
@@ -158,13 +158,6 @@
#define RS_SR_FORCE_DECREASE 1920 /* 15% */
#define RS_SR_NO_DECREASE 10880 /* 85% */
-#define TPC_SR_FORCE_INCREASE 9600 /* 75% */
-#define TPC_SR_NO_INCREASE 10880 /* 85% */
-#define TPC_TX_POWER_STEP 3
-#define TPC_MAX_REDUCTION 15
-#define TPC_NO_REDUCTION 0
-#define TPC_INVALID 0xff
-
#define LINK_QUAL_AGG_TIME_LIMIT_DEF (4000) /* 4 milliseconds */
#define LINK_QUAL_AGG_TIME_LIMIT_MAX (8000)
#define LINK_QUAL_AGG_TIME_LIMIT_MIN (100)
@@ -273,16 +266,9 @@
RS_COLUMN_MIMO2_SGI,
RS_COLUMN_LAST = RS_COLUMN_MIMO2_SGI,
- RS_COLUMN_COUNT = RS_COLUMN_LAST + 1,
RS_COLUMN_INVALID,
};
-/* Packet stats per rate */
-struct rs_rate_stats {
- u64 success;
- u64 total;
-};
-
/**
* struct iwl_scale_tbl_info -- tx params and success history for all rates
*
@@ -294,8 +280,6 @@
enum rs_column column;
const u16 *expected_tpt; /* throughput metrics; expected_tpt_G, etc. */
struct iwl_rate_scale_data win[IWL_RATE_COUNT]; /* rate histories */
- /* per txpower-reduction history */
- struct iwl_rate_scale_data tpc_win[TPC_MAX_REDUCTION + 1];
};
enum {
@@ -331,8 +315,6 @@
bool is_vht;
enum ieee80211_band band;
- struct rs_rate_stats tx_stats[RS_COLUMN_COUNT][IWL_RATE_COUNT];
-
/* The following are bitmaps of rates; IWL_RATE_6M_MASK, etc. */
unsigned long active_legacy_rate;
unsigned long active_siso_rate;
@@ -352,11 +334,8 @@
#ifdef CPTCFG_MAC80211_DEBUGFS
struct dentry *rs_sta_dbgfs_scale_table_file;
struct dentry *rs_sta_dbgfs_stats_table_file;
- struct dentry *rs_sta_dbgfs_drv_tx_stats_file;
struct dentry *rs_sta_dbgfs_tx_agg_tid_en_file;
- struct dentry *rs_sta_dbgfs_reduced_txp_file;
u32 dbg_fixed_rate;
- u8 dbg_fixed_txp_reduction;
#endif
struct iwl_mvm *drv;
@@ -366,9 +345,6 @@
u32 last_rate_n_flags;
/* packets destined for this STA are aggregated */
u8 is_agg;
-
- /* tx power reduce for this sta */
- int tpc_reduce;
};
/* Initialize station's rate scaling information after adding station */
diff --git a/drivers/net/wireless/iwlwifi/mvm/rx.c b/drivers/net/wireless/iwlwifi/mvm/rx.c
index f3f49b0..a98cc6d 100644
--- a/drivers/net/wireless/iwlwifi/mvm/rx.c
+++ b/drivers/net/wireless/iwlwifi/mvm/rx.c
@@ -60,6 +60,7 @@
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*****************************************************************************/
#include "iwl-trans.h"
+
#include "mvm.h"
#include "fw-api.h"
@@ -129,7 +130,42 @@
memcpy(IEEE80211_SKB_RXCB(skb), stats, sizeof(*stats));
- ieee80211_rx(mvm->hw, skb);
+ ieee80211_rx_ni(mvm->hw, skb);
+}
+
+static void iwl_mvm_calc_rssi(struct iwl_mvm *mvm,
+ struct iwl_rx_phy_info *phy_info,
+ struct ieee80211_rx_status *rx_status)
+{
+ int rssi_a, rssi_b, rssi_a_dbm, rssi_b_dbm, max_rssi_dbm;
+ u32 agc_a, agc_b;
+ u32 val;
+
+ val = le32_to_cpu(phy_info->non_cfg_phy[IWL_RX_INFO_AGC_IDX]);
+ agc_a = (val & IWL_OFDM_AGC_A_MSK) >> IWL_OFDM_AGC_A_POS;
+ agc_b = (val & IWL_OFDM_AGC_B_MSK) >> IWL_OFDM_AGC_B_POS;
+
+ val = le32_to_cpu(phy_info->non_cfg_phy[IWL_RX_INFO_RSSI_AB_IDX]);
+ rssi_a = (val & IWL_OFDM_RSSI_INBAND_A_MSK) >> IWL_OFDM_RSSI_A_POS;
+ rssi_b = (val & IWL_OFDM_RSSI_INBAND_B_MSK) >> IWL_OFDM_RSSI_B_POS;
+
+ /*
+ * dBm = rssi dB - agc dB - constant.
+ * Higher AGC (higher radio gain) means lower signal.
+ */
+ rssi_a_dbm = rssi_a - IWL_RSSI_OFFSET - agc_a;
+ rssi_b_dbm = rssi_b - IWL_RSSI_OFFSET - agc_b;
+ max_rssi_dbm = max_t(int, rssi_a_dbm, rssi_b_dbm);
+
+ IWL_DEBUG_STATS(mvm, "Rssi In A %d B %d Max %d AGCA %d AGCB %d\n",
+ rssi_a_dbm, rssi_b_dbm, max_rssi_dbm, agc_a, agc_b);
+
+ rx_status->signal = max_rssi_dbm;
+ rx_status->chains = (le16_to_cpu(phy_info->phy_flags) &
+ RX_RES_PHY_FLAGS_ANTENNA)
+ >> RX_RES_PHY_FLAGS_ANTENNA_POS;
+ rx_status->chain_signal[0] = rssi_a_dbm;
+ rx_status->chain_signal[1] = rssi_b_dbm;
}
/*
@@ -301,7 +337,10 @@
*/
/*rx_status.flag |= RX_FLAG_MACTIME_MPDU;*/
- iwl_mvm_get_signal_strength(mvm, phy_info, &rx_status);
+ if (mvm->fw->ucode_capa.flags & IWL_UCODE_TLV_FLAGS_RX_ENERGY_API)
+ iwl_mvm_get_signal_strength(mvm, phy_info, &rx_status);
+ else
+ iwl_mvm_calc_rssi(mvm, phy_info, &rx_status);
IWL_DEBUG_STATS_LIMIT(mvm, "Rssi %d, TSF %llu\n", rx_status.signal,
(unsigned long long)rx_status.mactime);
@@ -355,8 +394,6 @@
rx_status.rate_idx = rate_n_flags & RATE_VHT_MCS_RATE_CODE_MSK;
rx_status.flag |= RX_FLAG_VHT;
rx_status.flag |= stbc << RX_FLAG_STBC_SHIFT;
- if (rate_n_flags & RATE_MCS_BF_MSK)
- rx_status.vht_flag |= RX_VHT_FLAG_BF;
} else {
rx_status.rate_idx =
iwl_mvm_legacy_rate_to_mac80211_idx(rate_n_flags,
diff --git a/drivers/net/wireless/iwlwifi/mvm/scan.c b/drivers/net/wireless/iwlwifi/mvm/scan.c
index 63e7b16..c28de54 100644
--- a/drivers/net/wireless/iwlwifi/mvm/scan.c
+++ b/drivers/net/wireless/iwlwifi/mvm/scan.c
@@ -277,51 +277,22 @@
IEEE80211_IFACE_ITER_NORMAL,
iwl_mvm_scan_condition_iterator,
&global_bound);
- /*
- * Under low latency traffic passive scan is fragmented meaning
- * that dwell on a particular channel will be fragmented. Each fragment
- * dwell time is 20ms and fragments period is 105ms. Skipping to next
- * channel will be delayed by the same period - 105ms. So suspend_time
- * parameter describing both fragments and channels skipping periods is
- * set to 105ms. This value is chosen so that overall passive scan
- * duration will not be too long. Max_out_time in this case is set to
- * 70ms, so for active scanning operating channel will be left for 70ms
- * while for passive still for 20ms (fragment dwell).
- */
- if (global_bound) {
- if (!iwl_mvm_low_latency(mvm)) {
- params->suspend_time = ieee80211_tu_to_usec(100);
- params->max_out_time = ieee80211_tu_to_usec(600);
- } else {
- params->suspend_time = ieee80211_tu_to_usec(105);
- /* P2P doesn't support fragmented passive scan, so
- * configure max_out_time to be at least longest dwell
- * time for passive scan.
- */
- if (vif->type == NL80211_IFTYPE_STATION && !vif->p2p) {
- params->max_out_time = ieee80211_tu_to_usec(70);
- params->passive_fragmented = true;
- } else {
- u32 passive_dwell;
- /*
- * Use band G so that passive channel dwell time
- * will be assigned with maximum value.
- */
- band = IEEE80211_BAND_2GHZ;
- passive_dwell = iwl_mvm_get_passive_dwell(band);
- params->max_out_time =
- ieee80211_tu_to_usec(passive_dwell);
- }
- }
+ if (!global_bound)
+ goto not_bound;
+
+ params->suspend_time = 100;
+ params->max_out_time = 600;
+
+ if (iwl_mvm_low_latency(mvm)) {
+ params->suspend_time = 250;
+ params->max_out_time = 250;
}
+not_bound:
+
for (band = IEEE80211_BAND_2GHZ; band < IEEE80211_NUM_BANDS; band++) {
- if (params->passive_fragmented)
- params->dwell[band].passive = 20;
- else
- params->dwell[band].passive =
- iwl_mvm_get_passive_dwell(band);
+ params->dwell[band].passive = iwl_mvm_get_passive_dwell(band);
params->dwell[band].active = iwl_mvm_get_active_dwell(band,
n_ssids);
}
@@ -348,10 +319,7 @@
struct iwl_mvm_scan_params params = {};
lockdep_assert_held(&mvm->mutex);
-
- /* we should have failed registration if scan_cmd was NULL */
- if (WARN_ON(mvm->scan_cmd == NULL))
- return -ENOMEM;
+ BUG_ON(mvm->scan_cmd == NULL);
IWL_DEBUG_SCAN(mvm, "Handling mac80211 scan request\n");
mvm->scan_status = IWL_MVM_SCAN_OS;
@@ -570,13 +538,9 @@
/* scan status must be locked for proper checking */
lockdep_assert_held(&mvm->mutex);
- IWL_DEBUG_SCAN(mvm,
- "Scheduled scan completed, status %s EBS status %s:%d\n",
+ IWL_DEBUG_SCAN(mvm, "Scheduled scan completed, status %s\n",
scan_notif->status == IWL_SCAN_OFFLOAD_COMPLETED ?
- "completed" : "aborted", scan_notif->ebs_status ==
- IWL_SCAN_EBS_SUCCESS ? "success" : "failed",
- scan_notif->ebs_status);
-
+ "completed" : "aborted");
/* only call mac80211 completion if the stop was initiated by FW */
if (mvm->scan_status == IWL_MVM_SCAN_SCHED) {
@@ -584,8 +548,6 @@
ieee80211_sched_scan_stopped(mvm->hw);
}
- mvm->last_ebs_successful = !scan_notif->ebs_status;
-
return 0;
}
@@ -770,7 +732,7 @@
int band_2ghz = mvm->nvm_data->bands[IEEE80211_BAND_2GHZ].n_channels;
int band_5ghz = mvm->nvm_data->bands[IEEE80211_BAND_5GHZ].n_channels;
int head = 0;
- int tail = band_2ghz + band_5ghz;
+ int tail = band_2ghz + band_5ghz - 1;
u32 ssid_bitmap;
int cmd_len;
int ret;
@@ -922,11 +884,6 @@
scan_req.flags |= cpu_to_le16(IWL_SCAN_OFFLOAD_FLAG_PASS_ALL);
}
- if (mvm->last_ebs_successful &&
- mvm->fw->ucode_capa.flags & IWL_UCODE_TLV_FLAGS_EBS_SUPPORT)
- scan_req.flags |=
- cpu_to_le16(IWL_SCAN_OFFLOAD_FLAG_EBS_ACCURATE_MODE);
-
return iwl_mvm_send_cmd_pdu(mvm, SCAN_OFFLOAD_REQUEST_CMD, CMD_SYNC,
sizeof(scan_req), &scan_req);
}
diff --git a/drivers/net/wireless/iwlwifi/mvm/sf.c b/drivers/net/wireless/iwlwifi/mvm/sf.c
index 7edfd15..88809b2 100644
--- a/drivers/net/wireless/iwlwifi/mvm/sf.c
+++ b/drivers/net/wireless/iwlwifi/mvm/sf.c
@@ -237,6 +237,9 @@
.sta_vif_ap_sta_id = IWL_MVM_STATION_COUNT,
};
+ if (IWL_UCODE_API(mvm->fw->ucode_ver) < 8)
+ return 0;
+
/*
* Ignore the call if we are in HW Restart flow, or if the handled
* vif is a p2p device.
diff --git a/drivers/net/wireless/iwlwifi/mvm/sta.c b/drivers/net/wireless/iwlwifi/mvm/sta.c
index 3e11b9d..f339ef8 100644
--- a/drivers/net/wireless/iwlwifi/mvm/sta.c
+++ b/drivers/net/wireless/iwlwifi/mvm/sta.c
@@ -66,6 +66,115 @@
#include "sta.h"
#include "rs.h"
+static void iwl_mvm_add_sta_cmd_v7_to_v5(struct iwl_mvm_add_sta_cmd_v7 *cmd_v7,
+ struct iwl_mvm_add_sta_cmd_v5 *cmd_v5)
+{
+ memset(cmd_v5, 0, sizeof(*cmd_v5));
+
+ cmd_v5->add_modify = cmd_v7->add_modify;
+ cmd_v5->tid_disable_tx = cmd_v7->tid_disable_tx;
+ cmd_v5->mac_id_n_color = cmd_v7->mac_id_n_color;
+ memcpy(cmd_v5->addr, cmd_v7->addr, ETH_ALEN);
+ cmd_v5->sta_id = cmd_v7->sta_id;
+ cmd_v5->modify_mask = cmd_v7->modify_mask;
+ cmd_v5->station_flags = cmd_v7->station_flags;
+ cmd_v5->station_flags_msk = cmd_v7->station_flags_msk;
+ cmd_v5->add_immediate_ba_tid = cmd_v7->add_immediate_ba_tid;
+ cmd_v5->remove_immediate_ba_tid = cmd_v7->remove_immediate_ba_tid;
+ cmd_v5->add_immediate_ba_ssn = cmd_v7->add_immediate_ba_ssn;
+ cmd_v5->sleep_tx_count = cmd_v7->sleep_tx_count;
+ cmd_v5->sleep_state_flags = cmd_v7->sleep_state_flags;
+ cmd_v5->assoc_id = cmd_v7->assoc_id;
+ cmd_v5->beamform_flags = cmd_v7->beamform_flags;
+ cmd_v5->tfd_queue_msk = cmd_v7->tfd_queue_msk;
+}
+
+static void
+iwl_mvm_add_sta_key_to_add_sta_cmd_v5(struct iwl_mvm_add_sta_key_cmd *key_cmd,
+ struct iwl_mvm_add_sta_cmd_v5 *sta_cmd,
+ u32 mac_id_n_color)
+{
+ memset(sta_cmd, 0, sizeof(*sta_cmd));
+
+ sta_cmd->sta_id = key_cmd->sta_id;
+ sta_cmd->add_modify = STA_MODE_MODIFY;
+ sta_cmd->modify_mask = STA_MODIFY_KEY;
+ sta_cmd->mac_id_n_color = cpu_to_le32(mac_id_n_color);
+
+ sta_cmd->key.key_offset = key_cmd->key_offset;
+ sta_cmd->key.key_flags = key_cmd->key_flags;
+ memcpy(sta_cmd->key.key, key_cmd->key, sizeof(sta_cmd->key.key));
+ sta_cmd->key.tkip_rx_tsc_byte2 = key_cmd->tkip_rx_tsc_byte2;
+ memcpy(sta_cmd->key.tkip_rx_ttak, key_cmd->tkip_rx_ttak,
+ sizeof(sta_cmd->key.tkip_rx_ttak));
+}
+
+static int iwl_mvm_send_add_sta_cmd_status(struct iwl_mvm *mvm,
+ struct iwl_mvm_add_sta_cmd_v7 *cmd,
+ int *status)
+{
+ struct iwl_mvm_add_sta_cmd_v5 cmd_v5;
+
+ if (mvm->fw->ucode_capa.flags & IWL_UCODE_TLV_FLAGS_STA_KEY_CMD)
+ return iwl_mvm_send_cmd_pdu_status(mvm, ADD_STA, sizeof(*cmd),
+ cmd, status);
+
+ iwl_mvm_add_sta_cmd_v7_to_v5(cmd, &cmd_v5);
+
+ return iwl_mvm_send_cmd_pdu_status(mvm, ADD_STA, sizeof(cmd_v5),
+ &cmd_v5, status);
+}
+
+static int iwl_mvm_send_add_sta_cmd(struct iwl_mvm *mvm, u32 flags,
+ struct iwl_mvm_add_sta_cmd_v7 *cmd)
+{
+ struct iwl_mvm_add_sta_cmd_v5 cmd_v5;
+
+ if (mvm->fw->ucode_capa.flags & IWL_UCODE_TLV_FLAGS_STA_KEY_CMD)
+ return iwl_mvm_send_cmd_pdu(mvm, ADD_STA, flags,
+ sizeof(*cmd), cmd);
+
+ iwl_mvm_add_sta_cmd_v7_to_v5(cmd, &cmd_v5);
+
+ return iwl_mvm_send_cmd_pdu(mvm, ADD_STA, flags, sizeof(cmd_v5),
+ &cmd_v5);
+}
+
+static int
+iwl_mvm_send_add_sta_key_cmd_status(struct iwl_mvm *mvm,
+ struct iwl_mvm_add_sta_key_cmd *cmd,
+ u32 mac_id_n_color,
+ int *status)
+{
+ struct iwl_mvm_add_sta_cmd_v5 sta_cmd;
+
+ if (mvm->fw->ucode_capa.flags & IWL_UCODE_TLV_FLAGS_STA_KEY_CMD)
+ return iwl_mvm_send_cmd_pdu_status(mvm, ADD_STA_KEY,
+ sizeof(*cmd), cmd, status);
+
+ iwl_mvm_add_sta_key_to_add_sta_cmd_v5(cmd, &sta_cmd, mac_id_n_color);
+
+ return iwl_mvm_send_cmd_pdu_status(mvm, ADD_STA, sizeof(sta_cmd),
+ &sta_cmd, status);
+}
+
+static int iwl_mvm_send_add_sta_key_cmd(struct iwl_mvm *mvm,
+ u32 flags,
+ struct iwl_mvm_add_sta_key_cmd *cmd,
+ u32 mac_id_n_color)
+{
+ struct iwl_mvm_add_sta_cmd_v5 sta_cmd;
+
+ if (mvm->fw->ucode_capa.flags & IWL_UCODE_TLV_FLAGS_STA_KEY_CMD)
+ return iwl_mvm_send_cmd_pdu(mvm, ADD_STA_KEY, flags,
+ sizeof(*cmd), cmd);
+
+ iwl_mvm_add_sta_key_to_add_sta_cmd_v5(cmd, &sta_cmd, mac_id_n_color);
+
+ return iwl_mvm_send_cmd_pdu(mvm, ADD_STA, flags, sizeof(sta_cmd),
+ &sta_cmd);
+}
+
static int iwl_mvm_find_free_sta_id(struct iwl_mvm *mvm,
enum nl80211_iftype iftype)
{
@@ -98,7 +207,7 @@
bool update)
{
struct iwl_mvm_sta *mvm_sta = (void *)sta->drv_priv;
- struct iwl_mvm_add_sta_cmd add_sta_cmd;
+ struct iwl_mvm_add_sta_cmd_v7 add_sta_cmd;
int ret;
u32 status;
u32 agg_size = 0, mpdu_dens = 0;
@@ -186,8 +295,7 @@
cpu_to_le32(mpdu_dens << STA_FLG_AGG_MPDU_DENS_SHIFT);
status = ADD_STA_SUCCESS;
- ret = iwl_mvm_send_cmd_pdu_status(mvm, ADD_STA, sizeof(add_sta_cmd),
- &add_sta_cmd, &status);
+ ret = iwl_mvm_send_add_sta_cmd_status(mvm, &add_sta_cmd, &status);
if (ret)
return ret;
@@ -272,7 +380,7 @@
int iwl_mvm_drain_sta(struct iwl_mvm *mvm, struct iwl_mvm_sta *mvmsta,
bool drain)
{
- struct iwl_mvm_add_sta_cmd cmd = {};
+ struct iwl_mvm_add_sta_cmd_v7 cmd = {};
int ret;
u32 status;
@@ -285,8 +393,7 @@
cmd.station_flags_msk = cpu_to_le32(STA_FLG_DRAIN_FLOW);
status = ADD_STA_SUCCESS;
- ret = iwl_mvm_send_cmd_pdu_status(mvm, ADD_STA, sizeof(cmd),
- &cmd, &status);
+ ret = iwl_mvm_send_add_sta_cmd_status(mvm, &cmd, &status);
if (ret)
return ret;
@@ -391,7 +498,7 @@
sta_id);
continue;
}
- RCU_INIT_POINTER(mvm->fw_id_to_mac_id[sta_id], NULL);
+ rcu_assign_pointer(mvm->fw_id_to_mac_id[sta_id], NULL);
clear_bit(sta_id, mvm->sta_drained);
}
@@ -413,6 +520,14 @@
/* flush its queues here since we are freeing mvm_sta */
ret = iwl_mvm_flush_tx_path(mvm, mvm_sta->tfd_queue_msk, true);
+ /*
+ * Put a non-NULL since the fw station isn't removed.
+ * It will be removed after the MAC will be set as
+ * unassoc.
+ */
+ rcu_assign_pointer(mvm->fw_id_to_mac_id[mvm_sta->sta_id],
+ ERR_PTR(-EINVAL));
+
/* if we are associated - we can't remove the AP STA now */
if (vif->bss_conf.assoc)
return ret;
@@ -442,7 +557,7 @@
} else {
spin_unlock_bh(&mvm_sta->lock);
ret = iwl_mvm_rm_sta_common(mvm, mvm_sta->sta_id);
- RCU_INIT_POINTER(mvm->fw_id_to_mac_id[mvm_sta->sta_id], NULL);
+ rcu_assign_pointer(mvm->fw_id_to_mac_id[mvm_sta->sta_id], NULL);
}
return ret;
@@ -456,7 +571,7 @@
lockdep_assert_held(&mvm->mutex);
- RCU_INIT_POINTER(mvm->fw_id_to_mac_id[sta_id], NULL);
+ rcu_assign_pointer(mvm->fw_id_to_mac_id[sta_id], NULL);
return ret;
}
@@ -478,7 +593,7 @@
void iwl_mvm_dealloc_int_sta(struct iwl_mvm *mvm, struct iwl_mvm_int_sta *sta)
{
- RCU_INIT_POINTER(mvm->fw_id_to_mac_id[sta->sta_id], NULL);
+ rcu_assign_pointer(mvm->fw_id_to_mac_id[sta->sta_id], NULL);
memset(sta, 0, sizeof(struct iwl_mvm_int_sta));
sta->sta_id = IWL_MVM_STATION_COUNT;
}
@@ -488,13 +603,13 @@
const u8 *addr,
u16 mac_id, u16 color)
{
- struct iwl_mvm_add_sta_cmd cmd;
+ struct iwl_mvm_add_sta_cmd_v7 cmd;
int ret;
u32 status;
lockdep_assert_held(&mvm->mutex);
- memset(&cmd, 0, sizeof(cmd));
+ memset(&cmd, 0, sizeof(struct iwl_mvm_add_sta_cmd_v7));
cmd.sta_id = sta->sta_id;
cmd.mac_id_n_color = cpu_to_le32(FW_CMD_ID_AND_COLOR(mac_id,
color));
@@ -504,8 +619,7 @@
if (addr)
memcpy(cmd.addr, addr, ETH_ALEN);
- ret = iwl_mvm_send_cmd_pdu_status(mvm, ADD_STA, sizeof(cmd),
- &cmd, &status);
+ ret = iwl_mvm_send_add_sta_cmd_status(mvm, &cmd, &status);
if (ret)
return ret;
@@ -639,7 +753,7 @@
int tid, u16 ssn, bool start)
{
struct iwl_mvm_sta *mvm_sta = (void *)sta->drv_priv;
- struct iwl_mvm_add_sta_cmd cmd = {};
+ struct iwl_mvm_add_sta_cmd_v7 cmd = {};
int ret;
u32 status;
@@ -663,8 +777,7 @@
STA_MODIFY_REMOVE_BA_TID;
status = ADD_STA_SUCCESS;
- ret = iwl_mvm_send_cmd_pdu_status(mvm, ADD_STA, sizeof(cmd),
- &cmd, &status);
+ ret = iwl_mvm_send_add_sta_cmd_status(mvm, &cmd, &status);
if (ret)
return ret;
@@ -699,7 +812,7 @@
int tid, u8 queue, bool start)
{
struct iwl_mvm_sta *mvm_sta = (void *)sta->drv_priv;
- struct iwl_mvm_add_sta_cmd cmd = {};
+ struct iwl_mvm_add_sta_cmd_v7 cmd = {};
int ret;
u32 status;
@@ -721,8 +834,7 @@
cmd.tid_disable_tx = cpu_to_le16(mvm_sta->tid_disable_agg);
status = ADD_STA_SUCCESS;
- ret = iwl_mvm_send_cmd_pdu_status(mvm, ADD_STA, sizeof(cmd),
- &cmd, &status);
+ ret = iwl_mvm_send_add_sta_cmd_status(mvm, &cmd, &status);
if (ret)
return ret;
@@ -1017,11 +1129,12 @@
u8 sta_id, u32 tkip_iv32, u16 *tkip_p1k,
u32 cmd_flags)
{
- struct iwl_mvm_add_sta_key_cmd cmd = {};
__le16 key_flags;
+ struct iwl_mvm_add_sta_key_cmd cmd = {};
int ret, status;
u16 keyidx;
int i;
+ u32 mac_id_n_color = mvm_sta->mac_id_n_color;
keyidx = (keyconf->keyidx << STA_KEY_FLG_KEYID_POS) &
STA_KEY_FLG_KEYID_MSK;
@@ -1054,11 +1167,12 @@
status = ADD_STA_SUCCESS;
if (cmd_flags == CMD_SYNC)
- ret = iwl_mvm_send_cmd_pdu_status(mvm, ADD_STA_KEY, sizeof(cmd),
- &cmd, &status);
+ ret = iwl_mvm_send_add_sta_key_cmd_status(mvm, &cmd,
+ mac_id_n_color,
+ &status);
else
- ret = iwl_mvm_send_cmd_pdu(mvm, ADD_STA_KEY, CMD_ASYNC,
- sizeof(cmd), &cmd);
+ ret = iwl_mvm_send_add_sta_key_cmd(mvm, CMD_ASYNC, &cmd,
+ mac_id_n_color);
switch (status) {
case ADD_STA_SUCCESS:
@@ -1285,8 +1399,9 @@
cmd.sta_id = sta_id;
status = ADD_STA_SUCCESS;
- ret = iwl_mvm_send_cmd_pdu_status(mvm, ADD_STA_KEY, sizeof(cmd),
- &cmd, &status);
+ ret = iwl_mvm_send_add_sta_key_cmd_status(mvm, &cmd,
+ mvm_sta->mac_id_n_color,
+ &status);
switch (status) {
case ADD_STA_SUCCESS:
@@ -1333,7 +1448,7 @@
struct ieee80211_sta *sta)
{
struct iwl_mvm_sta *mvmsta = iwl_mvm_sta_from_mac80211(sta);
- struct iwl_mvm_add_sta_cmd cmd = {
+ struct iwl_mvm_add_sta_cmd_v7 cmd = {
.add_modify = STA_MODE_MODIFY,
.sta_id = mvmsta->sta_id,
.station_flags_msk = cpu_to_le32(STA_FLG_PS),
@@ -1341,7 +1456,7 @@
};
int ret;
- ret = iwl_mvm_send_cmd_pdu(mvm, ADD_STA, CMD_ASYNC, sizeof(cmd), &cmd);
+ ret = iwl_mvm_send_add_sta_cmd(mvm, CMD_ASYNC, &cmd);
if (ret)
IWL_ERR(mvm, "Failed to send ADD_STA command (%d)\n", ret);
}
@@ -1353,7 +1468,7 @@
bool agg)
{
struct iwl_mvm_sta *mvmsta = iwl_mvm_sta_from_mac80211(sta);
- struct iwl_mvm_add_sta_cmd cmd = {
+ struct iwl_mvm_add_sta_cmd_v7 cmd = {
.add_modify = STA_MODE_MODIFY,
.sta_id = mvmsta->sta_id,
.modify_mask = STA_MODIFY_SLEEPING_STA_TX_COUNT,
@@ -1423,7 +1538,7 @@
cmd.sleep_state_flags |= cpu_to_le16(STA_SLEEP_STATE_UAPSD);
}
- ret = iwl_mvm_send_cmd_pdu(mvm, ADD_STA, CMD_ASYNC, sizeof(cmd), &cmd);
+ ret = iwl_mvm_send_add_sta_cmd(mvm, CMD_ASYNC, &cmd);
if (ret)
IWL_ERR(mvm, "Failed to send ADD_STA command (%d)\n", ret);
}
diff --git a/drivers/net/wireless/iwlwifi/mvm/sta.h b/drivers/net/wireless/iwlwifi/mvm/sta.h
index e5e3071..2ed84c4 100644
--- a/drivers/net/wireless/iwlwifi/mvm/sta.h
+++ b/drivers/net/wireless/iwlwifi/mvm/sta.h
@@ -253,8 +253,6 @@
* This is basically (last acked packet++).
* @rate_n_flags: Rate at which Tx was attempted. Holds the data between the
* Tx response (TX_CMD), and the block ack notification (COMPRESSED_BA).
- * @reduced_tpc: Reduced tx power. Holds the data between the
- * Tx response (TX_CMD), and the block ack notification (COMPRESSED_BA).
* @state: state of the BA agreement establishment / tear down.
* @txq_id: Tx queue used by the BA session
* @ssn: the first packet to be sent in AGG HW queue in Tx AGG start flow, or
@@ -267,7 +265,6 @@
u16 next_reclaimed;
/* The rest is Tx AGG related */
u32 rate_n_flags;
- u8 reduced_tpc;
enum iwl_mvm_agg_state state;
u16 txq_id;
u16 ssn;
diff --git a/drivers/net/wireless/iwlwifi/mvm/time-event.c b/drivers/net/wireless/iwlwifi/mvm/time-event.c
index a940293..6133124 100644
--- a/drivers/net/wireless/iwlwifi/mvm/time-event.c
+++ b/drivers/net/wireless/iwlwifi/mvm/time-event.c
@@ -273,10 +273,67 @@
return true;
}
+/* used to convert from time event API v2 to v1 */
+#define TE_V2_DEP_POLICY_MSK (TE_V2_DEP_OTHER | TE_V2_DEP_TSF |\
+ TE_V2_EVENT_SOCIOPATHIC)
+static inline u16 te_v2_get_notify(__le16 policy)
+{
+ return le16_to_cpu(policy) & TE_V2_NOTIF_MSK;
+}
+
+static inline u16 te_v2_get_dep_policy(__le16 policy)
+{
+ return (le16_to_cpu(policy) & TE_V2_DEP_POLICY_MSK) >>
+ TE_V2_PLACEMENT_POS;
+}
+
+static inline u16 te_v2_get_absence(__le16 policy)
+{
+ return (le16_to_cpu(policy) & TE_V2_ABSENCE) >> TE_V2_ABSENCE_POS;
+}
+
+static void iwl_mvm_te_v2_to_v1(const struct iwl_time_event_cmd_v2 *cmd_v2,
+ struct iwl_time_event_cmd_v1 *cmd_v1)
+{
+ cmd_v1->id_and_color = cmd_v2->id_and_color;
+ cmd_v1->action = cmd_v2->action;
+ cmd_v1->id = cmd_v2->id;
+ cmd_v1->apply_time = cmd_v2->apply_time;
+ cmd_v1->max_delay = cmd_v2->max_delay;
+ cmd_v1->depends_on = cmd_v2->depends_on;
+ cmd_v1->interval = cmd_v2->interval;
+ cmd_v1->duration = cmd_v2->duration;
+ if (cmd_v2->repeat == TE_V2_REPEAT_ENDLESS)
+ cmd_v1->repeat = cpu_to_le32(TE_V1_REPEAT_ENDLESS);
+ else
+ cmd_v1->repeat = cpu_to_le32(cmd_v2->repeat);
+ cmd_v1->max_frags = cpu_to_le32(cmd_v2->max_frags);
+ cmd_v1->interval_reciprocal = 0; /* unused */
+
+ cmd_v1->dep_policy = cpu_to_le32(te_v2_get_dep_policy(cmd_v2->policy));
+ cmd_v1->is_present = cpu_to_le32(!te_v2_get_absence(cmd_v2->policy));
+ cmd_v1->notify = cpu_to_le32(te_v2_get_notify(cmd_v2->policy));
+}
+
+static int iwl_mvm_send_time_event_cmd(struct iwl_mvm *mvm,
+ const struct iwl_time_event_cmd_v2 *cmd)
+{
+ struct iwl_time_event_cmd_v1 cmd_v1;
+
+ if (mvm->fw->ucode_capa.flags & IWL_UCODE_TLV_FLAGS_TIME_EVENT_API_V2)
+ return iwl_mvm_send_cmd_pdu(mvm, TIME_EVENT_CMD, CMD_SYNC,
+ sizeof(*cmd), cmd);
+
+ iwl_mvm_te_v2_to_v1(cmd, &cmd_v1);
+ return iwl_mvm_send_cmd_pdu(mvm, TIME_EVENT_CMD, CMD_SYNC,
+ sizeof(cmd_v1), &cmd_v1);
+}
+
+
static int iwl_mvm_time_event_send_add(struct iwl_mvm *mvm,
struct ieee80211_vif *vif,
struct iwl_mvm_time_event_data *te_data,
- struct iwl_time_event_cmd *te_cmd)
+ struct iwl_time_event_cmd_v2 *te_cmd)
{
static const u8 time_event_response[] = { TIME_EVENT_CMD };
struct iwl_notification_wait wait_time_event;
@@ -312,8 +369,7 @@
ARRAY_SIZE(time_event_response),
iwl_mvm_time_event_response, te_data);
- ret = iwl_mvm_send_cmd_pdu(mvm, TIME_EVENT_CMD, CMD_SYNC,
- sizeof(*te_cmd), te_cmd);
+ ret = iwl_mvm_send_time_event_cmd(mvm, te_cmd);
if (ret) {
IWL_ERR(mvm, "Couldn't send TIME_EVENT_CMD: %d\n", ret);
iwl_remove_notification(&mvm->notif_wait, &wait_time_event);
@@ -341,7 +397,7 @@
{
struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif);
struct iwl_mvm_time_event_data *te_data = &mvmvif->time_event_data;
- struct iwl_time_event_cmd time_cmd = {};
+ struct iwl_time_event_cmd_v2 time_cmd = {};
lockdep_assert_held(&mvm->mutex);
@@ -397,7 +453,7 @@
struct iwl_mvm_vif *mvmvif,
struct iwl_mvm_time_event_data *te_data)
{
- struct iwl_time_event_cmd time_cmd = {};
+ struct iwl_time_event_cmd_v2 time_cmd = {};
u32 id, uid;
int ret;
@@ -434,8 +490,7 @@
cpu_to_le32(FW_CMD_ID_AND_COLOR(mvmvif->id, mvmvif->color));
IWL_DEBUG_TE(mvm, "Removing TE 0x%x\n", le32_to_cpu(time_cmd.id));
- ret = iwl_mvm_send_cmd_pdu(mvm, TIME_EVENT_CMD, CMD_SYNC,
- sizeof(time_cmd), &time_cmd);
+ ret = iwl_mvm_send_time_event_cmd(mvm, &time_cmd);
if (WARN_ON(ret))
return;
}
@@ -455,7 +510,7 @@
{
struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif);
struct iwl_mvm_time_event_data *te_data = &mvmvif->time_event_data;
- struct iwl_time_event_cmd time_cmd = {};
+ struct iwl_time_event_cmd_v2 time_cmd = {};
lockdep_assert_held(&mvm->mutex);
if (te_data->running) {
diff --git a/drivers/net/wireless/iwlwifi/mvm/tt.c b/drivers/net/wireless/iwlwifi/mvm/tt.c
index 39a3e03..7a99fa3 100644
--- a/drivers/net/wireless/iwlwifi/mvm/tt.c
+++ b/drivers/net/wireless/iwlwifi/mvm/tt.c
@@ -468,14 +468,13 @@
}
if (params->support_tx_backoff) {
- tx_backoff = tt->min_backoff;
+ tx_backoff = 0;
for (i = 0; i < TT_TX_BACKOFF_SIZE; i++) {
if (temperature < params->tx_backoff[i].temperature)
break;
- tx_backoff = max(tt->min_backoff,
- params->tx_backoff[i].backoff);
+ tx_backoff = params->tx_backoff[i].backoff;
}
- if (tx_backoff != tt->min_backoff)
+ if (tx_backoff != 0)
throttle_enable = true;
if (tt->tx_backoff != tx_backoff)
iwl_mvm_tt_tx_backoff(mvm, tx_backoff);
@@ -485,8 +484,7 @@
IWL_WARN(mvm,
"Due to high temperature thermal throttling initiated\n");
tt->throttle = true;
- } else if (tt->throttle && !tt->dynamic_smps &&
- tt->tx_backoff == tt->min_backoff &&
+ } else if (tt->throttle && !tt->dynamic_smps && tt->tx_backoff == 0 &&
temperature <= params->tx_protection_exit) {
IWL_WARN(mvm,
"Temperature is back to normal thermal throttling stopped\n");
diff --git a/drivers/net/wireless/iwlwifi/mvm/tx.c b/drivers/net/wireless/iwlwifi/mvm/tx.c
index 1ca41f8..13dedae 100644
--- a/drivers/net/wireless/iwlwifi/mvm/tx.c
+++ b/drivers/net/wireless/iwlwifi/mvm/tx.c
@@ -636,11 +636,7 @@
seq_ctl = le16_to_cpu(hdr->seq_ctrl);
}
- BUILD_BUG_ON(ARRAY_SIZE(info->status.status_driver_data) < 1);
- info->status.status_driver_data[0] =
- (void *)(uintptr_t)tx_resp->reduced_tpc;
-
- ieee80211_tx_status(mvm->hw, skb);
+ ieee80211_tx_status_ni(mvm->hw, skb);
}
if (txq_id >= mvm->first_agg_queue) {
@@ -819,7 +815,6 @@
struct iwl_mvm_sta *mvmsta = iwl_mvm_sta_from_mac80211(sta);
mvmsta->tid_data[tid].rate_n_flags =
le32_to_cpu(tx_resp->initial_rate);
- mvmsta->tid_data[tid].reduced_tpc = tx_resp->reduced_tpc;
}
rcu_read_unlock();
@@ -933,8 +928,6 @@
info->status.ampdu_len = ba_notif->txed;
iwl_mvm_hwrate_to_tx_status(tid_data->rate_n_flags,
info);
- info->status.status_driver_data[0] =
- (void *)(uintptr_t)tid_data->reduced_tpc;
}
}
@@ -944,7 +937,7 @@
while (!skb_queue_empty(&reclaimed_skbs)) {
skb = __skb_dequeue(&reclaimed_skbs);
- ieee80211_tx_status(mvm->hw, skb);
+ ieee80211_tx_status_ni(mvm->hw, skb);
}
return 0;
diff --git a/drivers/net/wireless/iwlwifi/mvm/utils.c b/drivers/net/wireless/iwlwifi/mvm/utils.c
index 2997824..cda99a1 100644
--- a/drivers/net/wireless/iwlwifi/mvm/utils.c
+++ b/drivers/net/wireless/iwlwifi/mvm/utils.c
@@ -64,7 +64,6 @@
#include "iwl-debug.h"
#include "iwl-io.h"
-#include "iwl-prph.h"
#include "mvm.h"
#include "fw-api-rs.h"
@@ -470,8 +469,6 @@
mvm->status, table.valid);
}
- /* Do not change this output - scripts rely on it */
-
IWL_ERR(mvm, "Loaded firmware version: %s\n", mvm->fw->fw_version);
trace_iwlwifi_dev_ucode_error(trans->dev, table.error_id, table.tsf_low,
@@ -525,7 +522,7 @@
u32 ofs, sram_len;
void *sram;
- if (!mvm->ucode_loaded || mvm->fw_error_sram || mvm->fw_error_dump)
+ if (!mvm->ucode_loaded || mvm->fw_error_sram)
return;
img = &mvm->fw->img[mvm->cur_ucode];
@@ -541,47 +538,6 @@
mvm->fw_error_sram_len = sram_len;
}
-void iwl_mvm_fw_error_rxf_dump(struct iwl_mvm *mvm)
-{
- int i, reg_val;
- unsigned long flags;
-
- if (!mvm->ucode_loaded || mvm->fw_error_rxf || mvm->fw_error_dump)
- return;
-
- /* reading buffer size */
- reg_val = iwl_trans_read_prph(mvm->trans, RXF_SIZE_ADDR);
- mvm->fw_error_rxf_len =
- (reg_val & RXF_SIZE_BYTE_CNT_MSK) >> RXF_SIZE_BYTE_CND_POS;
-
- /* the register holds the value divided by 128 */
- mvm->fw_error_rxf_len = mvm->fw_error_rxf_len << 7;
-
- if (!mvm->fw_error_rxf_len)
- return;
-
- mvm->fw_error_rxf = kzalloc(mvm->fw_error_rxf_len, GFP_ATOMIC);
- if (!mvm->fw_error_rxf) {
- mvm->fw_error_rxf_len = 0;
- return;
- }
-
- if (!iwl_trans_grab_nic_access(mvm->trans, false, &flags)) {
- kfree(mvm->fw_error_rxf);
- mvm->fw_error_rxf = NULL;
- mvm->fw_error_rxf_len = 0;
- return;
- }
-
- for (i = 0; i < (mvm->fw_error_rxf_len / sizeof(u32)); i++) {
- iwl_trans_write_prph(mvm->trans, RXF_LD_FENCE_OFFSET_ADDR,
- i * sizeof(u32));
- mvm->fw_error_rxf[i] =
- iwl_trans_read_prph(mvm->trans, RXF_FIFO_RD_FENCE_ADDR);
- }
- iwl_trans_release_nic_access(mvm->trans, &flags);
-}
-
/**
* iwl_mvm_send_lq_cmd() - Send link quality command
* @init: This command is sent as part of station initialization right
@@ -688,3 +644,22 @@
return result;
}
+
+static void iwl_mvm_idle_iter(void *_data, u8 *mac, struct ieee80211_vif *vif)
+{
+ bool *idle = _data;
+
+ if (!vif->bss_conf.idle)
+ *idle = false;
+}
+
+bool iwl_mvm_is_idle(struct iwl_mvm *mvm)
+{
+ bool idle = true;
+
+ ieee80211_iterate_active_interfaces_atomic(
+ mvm->hw, IEEE80211_IFACE_ITER_NORMAL,
+ iwl_mvm_idle_iter, &idle);
+
+ return idle;
+}
diff --git a/drivers/net/wireless/iwlwifi/pcie/drv.c b/drivers/net/wireless/iwlwifi/pcie/drv.c
index 936e43d..aba94b1 100644
--- a/drivers/net/wireless/iwlwifi/pcie/drv.c
+++ b/drivers/net/wireless/iwlwifi/pcie/drv.c
@@ -367,6 +367,7 @@
{IWL_PCI_DEVICE(0x095A, 0x5012, iwl7265_2ac_cfg)},
{IWL_PCI_DEVICE(0x095A, 0x5412, iwl7265_2ac_cfg)},
{IWL_PCI_DEVICE(0x095A, 0x5410, iwl7265_2ac_cfg)},
+ {IWL_PCI_DEVICE(0x095A, 0x5510, iwl7265_2ac_cfg)},
{IWL_PCI_DEVICE(0x095A, 0x5400, iwl7265_2ac_cfg)},
{IWL_PCI_DEVICE(0x095A, 0x1010, iwl7265_2ac_cfg)},
{IWL_PCI_DEVICE(0x095A, 0x5000, iwl7265_2n_cfg)},
@@ -380,7 +381,7 @@
{IWL_PCI_DEVICE(0x095A, 0x9110, iwl7265_2ac_cfg)},
{IWL_PCI_DEVICE(0x095A, 0x9112, iwl7265_2ac_cfg)},
{IWL_PCI_DEVICE(0x095A, 0x9210, iwl7265_2ac_cfg)},
- {IWL_PCI_DEVICE(0x095A, 0x9200, iwl7265_2ac_cfg)},
+ {IWL_PCI_DEVICE(0x095B, 0x9200, iwl7265_2ac_cfg)},
{IWL_PCI_DEVICE(0x095A, 0x9510, iwl7265_2ac_cfg)},
{IWL_PCI_DEVICE(0x095A, 0x9310, iwl7265_2ac_cfg)},
{IWL_PCI_DEVICE(0x095A, 0x9410, iwl7265_2ac_cfg)},
diff --git a/drivers/net/wireless/iwlwifi/pcie/internal.h b/drivers/net/wireless/iwlwifi/pcie/internal.h
index adf782d..1c4ef85 100644
--- a/drivers/net/wireless/iwlwifi/pcie/internal.h
+++ b/drivers/net/wireless/iwlwifi/pcie/internal.h
@@ -102,7 +102,7 @@
u32 write_actual;
struct list_head rx_free;
struct list_head rx_used;
- bool need_update;
+ int need_update;
struct iwl_rb_status *rb_stts;
dma_addr_t rb_stts_dma;
spinlock_t lock;
@@ -231,7 +231,7 @@
spinlock_t lock;
struct timer_list stuck_timer;
struct iwl_trans_pcie *trans_pcie;
- bool need_update;
+ u8 need_update;
u8 active;
bool ampdu;
};
@@ -270,9 +270,6 @@
struct iwl_trans *trans;
struct iwl_drv *drv;
- struct net_device napi_dev;
- struct napi_struct napi;
-
/* INT ICT Table */
__le32 *ict_tbl;
dma_addr_t ict_tbl_dma;
@@ -365,7 +362,7 @@
void iwl_trans_pcie_txq_disable(struct iwl_trans *trans, int queue);
int iwl_trans_pcie_tx(struct iwl_trans *trans, struct sk_buff *skb,
struct iwl_device_cmd *dev_cmd, int txq_id);
-void iwl_pcie_txq_check_wrptrs(struct iwl_trans *trans);
+void iwl_pcie_txq_inc_wr_ptr(struct iwl_trans *trans, struct iwl_txq *txq);
int iwl_trans_pcie_send_hcmd(struct iwl_trans *trans, struct iwl_host_cmd *cmd);
void iwl_pcie_hcmd_complete(struct iwl_trans *trans,
struct iwl_rx_cmd_buffer *rxb, int handler_status);
diff --git a/drivers/net/wireless/iwlwifi/pcie/rx.c b/drivers/net/wireless/iwlwifi/pcie/rx.c
index 4a26a08..fdfa396 100644
--- a/drivers/net/wireless/iwlwifi/pcie/rx.c
+++ b/drivers/net/wireless/iwlwifi/pcie/rx.c
@@ -145,13 +145,15 @@
/*
* iwl_pcie_rxq_inc_wr_ptr - Update the write pointer for the RX queue
*/
-static void iwl_pcie_rxq_inc_wr_ptr(struct iwl_trans *trans)
+static void iwl_pcie_rxq_inc_wr_ptr(struct iwl_trans *trans,
+ struct iwl_rxq *rxq)
{
- struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans);
- struct iwl_rxq *rxq = &trans_pcie->rxq;
u32 reg;
- lockdep_assert_held(&rxq->lock);
+ spin_lock(&rxq->lock);
+
+ if (rxq->need_update == 0)
+ goto exit_unlock;
/*
* explicitly wake up the NIC if:
@@ -167,27 +169,13 @@
reg);
iwl_set_bit(trans, CSR_GP_CNTRL,
CSR_GP_CNTRL_REG_FLAG_MAC_ACCESS_REQ);
- rxq->need_update = true;
- return;
+ goto exit_unlock;
}
}
rxq->write_actual = round_down(rxq->write, 8);
iwl_write32(trans, FH_RSCSR_CHNL0_WPTR, rxq->write_actual);
-}
-
-static void iwl_pcie_rxq_check_wrptr(struct iwl_trans *trans)
-{
- struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans);
- struct iwl_rxq *rxq = &trans_pcie->rxq;
-
- spin_lock(&rxq->lock);
-
- if (!rxq->need_update)
- goto exit_unlock;
-
- iwl_pcie_rxq_inc_wr_ptr(trans);
- rxq->need_update = false;
+ rxq->need_update = 0;
exit_unlock:
spin_unlock(&rxq->lock);
@@ -248,8 +236,9 @@
* Increment device's write pointer in multiples of 8. */
if (rxq->write_actual != (rxq->write & ~0x7)) {
spin_lock(&rxq->lock);
- iwl_pcie_rxq_inc_wr_ptr(trans);
+ rxq->need_update = 1;
spin_unlock(&rxq->lock);
+ iwl_pcie_rxq_inc_wr_ptr(trans, rxq);
}
}
@@ -373,9 +362,20 @@
* Also restock the Rx queue via iwl_pcie_rxq_restock.
* This is called as a scheduled work item (except for during initialization)
*/
-static void iwl_pcie_rx_replenish(struct iwl_trans *trans, gfp_t gfp)
+static void iwl_pcie_rx_replenish(struct iwl_trans *trans)
{
- iwl_pcie_rxq_alloc_rbs(trans, gfp);
+ struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans);
+
+ iwl_pcie_rxq_alloc_rbs(trans, GFP_KERNEL);
+
+ spin_lock(&trans_pcie->irq_lock);
+ iwl_pcie_rxq_restock(trans);
+ spin_unlock(&trans_pcie->irq_lock);
+}
+
+static void iwl_pcie_rx_replenish_now(struct iwl_trans *trans)
+{
+ iwl_pcie_rxq_alloc_rbs(trans, GFP_ATOMIC);
iwl_pcie_rxq_restock(trans);
}
@@ -385,7 +385,7 @@
struct iwl_trans_pcie *trans_pcie =
container_of(data, struct iwl_trans_pcie, rx_replenish);
- iwl_pcie_rx_replenish(trans_pcie->trans, GFP_KERNEL);
+ iwl_pcie_rx_replenish(trans_pcie->trans);
}
static int iwl_pcie_rx_alloc(struct iwl_trans *trans)
@@ -521,13 +521,14 @@
memset(rxq->rb_stts, 0, sizeof(*rxq->rb_stts));
spin_unlock(&rxq->lock);
- iwl_pcie_rx_replenish(trans, GFP_KERNEL);
+ iwl_pcie_rx_replenish(trans);
iwl_pcie_rx_hw_init(trans, rxq);
- spin_lock(&rxq->lock);
- iwl_pcie_rxq_inc_wr_ptr(trans);
- spin_unlock(&rxq->lock);
+ spin_lock(&trans_pcie->irq_lock);
+ rxq->need_update = 1;
+ iwl_pcie_rxq_inc_wr_ptr(trans, rxq);
+ spin_unlock(&trans_pcie->irq_lock);
return 0;
}
@@ -672,6 +673,7 @@
/* Reuse the page if possible. For notification packets and
* SKBs that fail to Rx correctly, add them back into the
* rx_free list for reuse later. */
+ spin_lock(&rxq->lock);
if (rxb->page != NULL) {
rxb->page_dma =
dma_map_page(trans->dev, rxb->page, 0,
@@ -692,6 +694,7 @@
}
} else
list_add_tail(&rxb->list, &rxq->rx_used);
+ spin_unlock(&rxq->lock);
}
/*
@@ -706,8 +709,6 @@
u32 count = 8;
int total_empty;
-restart:
- spin_lock(&rxq->lock);
/* uCode's read index (stored in shared DRAM) indicates the last Rx
* buffer that the driver may process (last buffer filled by ucode). */
r = le16_to_cpu(ACCESS_ONCE(rxq->rb_stts->closed_rb_num)) & 0x0FFF;
@@ -742,25 +743,18 @@
count++;
if (count >= 8) {
rxq->read = i;
- spin_unlock(&rxq->lock);
- iwl_pcie_rx_replenish(trans, GFP_ATOMIC);
+ iwl_pcie_rx_replenish_now(trans);
count = 0;
- goto restart;
}
}
}
/* Backtrack one entry */
rxq->read = i;
- spin_unlock(&rxq->lock);
-
if (fill_rx)
- iwl_pcie_rx_replenish(trans, GFP_ATOMIC);
+ iwl_pcie_rx_replenish_now(trans);
else
iwl_pcie_rxq_restock(trans);
-
- if (trans_pcie->napi.poll)
- napi_gro_flush(&trans_pcie->napi, false);
}
/*
@@ -882,6 +876,7 @@
struct isr_statistics *isr_stats = &trans_pcie->isr_stats;
u32 inta = 0;
u32 handled = 0;
+ u32 i;
lock_map_acquire(&trans->sync_cmd_lockdep_map);
@@ -1033,8 +1028,9 @@
/* uCode wakes up after power-down sleep */
if (inta & CSR_INT_BIT_WAKEUP) {
IWL_DEBUG_ISR(trans, "Wakeup interrupt\n");
- iwl_pcie_rxq_check_wrptr(trans);
- iwl_pcie_txq_check_wrptrs(trans);
+ iwl_pcie_rxq_inc_wr_ptr(trans, &trans_pcie->rxq);
+ for (i = 0; i < trans->cfg->base_params->num_of_queues; i++)
+ iwl_pcie_txq_inc_wr_ptr(trans, &trans_pcie->txq[i]);
isr_stats->wakeup++;
@@ -1072,6 +1068,8 @@
iwl_write8(trans, CSR_INT_PERIODIC_REG,
CSR_INT_PERIODIC_DIS);
+ iwl_pcie_rx_handle(trans);
+
/*
* Enable periodic interrupt in 8 msec only if we received
* real RX interrupt (instead of just periodic int), to catch
@@ -1084,10 +1082,6 @@
CSR_INT_PERIODIC_ENA);
isr_stats->rx++;
-
- local_bh_disable();
- iwl_pcie_rx_handle(trans);
- local_bh_enable();
}
/* This "Tx" DMA channel is used only for loading uCode */
diff --git a/drivers/net/wireless/iwlwifi/pcie/trans.c b/drivers/net/wireless/iwlwifi/pcie/trans.c
index 803ac2b..fbc55cf 100644
--- a/drivers/net/wireless/iwlwifi/pcie/trans.c
+++ b/drivers/net/wireless/iwlwifi/pcie/trans.c
@@ -103,6 +103,7 @@
/* PCI registers */
#define PCI_CFG_RETRY_TIMEOUT 0x041
+#define CPU1_CPU2_SEPARATOR_SECTION 0xFFFFCCCC
static void iwl_pcie_apm_config(struct iwl_trans *trans)
{
@@ -453,6 +454,7 @@
{
int ret;
int t = 0;
+ int iter;
IWL_DEBUG_INFO(trans, "iwl_trans_prepare_card_hw enter\n");
@@ -461,18 +463,23 @@
if (ret >= 0)
return 0;
- /* If HW is not ready, prepare the conditions to check again */
- iwl_set_bit(trans, CSR_HW_IF_CONFIG_REG,
- CSR_HW_IF_CONFIG_REG_PREPARE);
+ for (iter = 0; iter < 10; iter++) {
+ /* If HW is not ready, prepare the conditions to check again */
+ iwl_set_bit(trans, CSR_HW_IF_CONFIG_REG,
+ CSR_HW_IF_CONFIG_REG_PREPARE);
- do {
- ret = iwl_pcie_set_hw_ready(trans);
- if (ret >= 0)
- return 0;
+ do {
+ ret = iwl_pcie_set_hw_ready(trans);
+ if (ret >= 0)
+ return 0;
- usleep_range(200, 1000);
- t += 200;
- } while (t < 150000);
+ usleep_range(200, 1000);
+ t += 200;
+ } while (t < 150000);
+ msleep(25);
+ }
+
+ IWL_DEBUG_INFO(trans, "got NIC after %d iterations\n", iter);
return ret;
}
@@ -1052,12 +1059,6 @@
iwl_trans_pcie_write32(trans, HBUS_TARG_PRPH_WDAT, val);
}
-static int iwl_pcie_dummy_napi_poll(struct napi_struct *napi, int budget)
-{
- WARN_ON(1);
- return 0;
-}
-
static void iwl_trans_pcie_configure(struct iwl_trans *trans,
const struct iwl_trans_config *trans_cfg)
{
@@ -1084,18 +1085,6 @@
trans_pcie->command_names = trans_cfg->command_names;
trans_pcie->bc_table_dword = trans_cfg->bc_table_dword;
-
- /* Initialize NAPI here - it should be before registering to mac80211
- * in the opmode but after the HW struct is allocated.
- * As this function may be called again in some corner cases don't
- * do anything if NAPI was already initialized.
- */
- if (!trans_pcie->napi.poll && trans->op_mode->ops->napi_add) {
- init_dummy_netdev(&trans_pcie->napi_dev);
- iwl_op_mode_napi_add(trans->op_mode, &trans_pcie->napi,
- &trans_pcie->napi_dev,
- iwl_pcie_dummy_napi_poll, 64);
- }
}
void iwl_trans_pcie_free(struct iwl_trans *trans)
@@ -1116,9 +1105,6 @@
pci_disable_device(trans_pcie->pci_dev);
kmem_cache_destroy(trans->dev_cmd_pool);
- if (trans_pcie->napi.poll)
- netif_napi_del(&trans_pcie->napi);
-
kfree(trans);
}
@@ -1257,7 +1243,7 @@
#define IWL_FLUSH_WAIT_MS 2000
-static int iwl_trans_pcie_wait_txq_empty(struct iwl_trans *trans, u32 txq_bm)
+static int iwl_trans_pcie_wait_txq_empty(struct iwl_trans *trans)
{
struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans);
struct iwl_txq *txq;
@@ -1270,31 +1256,13 @@
/* waiting for all the tx frames complete might take a while */
for (cnt = 0; cnt < trans->cfg->base_params->num_of_queues; cnt++) {
- u8 wr_ptr;
-
if (cnt == trans_pcie->cmd_queue)
continue;
- if (!test_bit(cnt, trans_pcie->queue_used))
- continue;
- if (!(BIT(cnt) & txq_bm))
- continue;
-
- IWL_DEBUG_TX_QUEUES(trans, "Emptying queue %d...\n", cnt);
txq = &trans_pcie->txq[cnt];
q = &txq->q;
- wr_ptr = ACCESS_ONCE(q->write_ptr);
-
- while (q->read_ptr != ACCESS_ONCE(q->write_ptr) &&
- !time_after(jiffies,
- now + msecs_to_jiffies(IWL_FLUSH_WAIT_MS))) {
- u8 write_ptr = ACCESS_ONCE(q->write_ptr);
-
- if (WARN_ONCE(wr_ptr != write_ptr,
- "WR pointer moved while flushing %d -> %d\n",
- wr_ptr, write_ptr))
- return -ETIMEDOUT;
+ while (q->read_ptr != q->write_ptr && !time_after(jiffies,
+ now + msecs_to_jiffies(IWL_FLUSH_WAIT_MS)))
msleep(1);
- }
if (q->read_ptr != q->write_ptr) {
IWL_ERR(trans,
@@ -1302,7 +1270,6 @@
ret = -ETIMEDOUT;
break;
}
- IWL_DEBUG_TX_QUEUES(trans, "Queue %d is now empty.\n", cnt);
}
if (!ret)
@@ -1788,6 +1755,10 @@
* PCI Tx retries from interfering with C3 CPU state */
pci_write_config_byte(pdev, PCI_CFG_RETRY_TIMEOUT, 0x00);
+ trans->dev = &pdev->dev;
+ trans_pcie->pci_dev = pdev;
+ iwl_disable_interrupts(trans);
+
err = pci_enable_msi(pdev);
if (err) {
dev_err(&pdev->dev, "pci_enable_msi failed(0X%x)\n", err);
@@ -1799,8 +1770,6 @@
}
}
- trans->dev = &pdev->dev;
- trans_pcie->pci_dev = pdev;
trans->hw_rev = iwl_read32(trans, CSR_HW_REV);
trans->hw_id = (pdev->device << 16) + pdev->subsystem_device;
snprintf(trans->hw_id_str, sizeof(trans->hw_id_str),
@@ -1826,8 +1795,6 @@
goto out_pci_disable_msi;
}
- trans_pcie->inta_mask = CSR_INI_SET_MASK;
-
if (iwl_pcie_alloc_ict(trans))
goto out_free_cmd_pool;
@@ -1839,6 +1806,8 @@
goto out_free_ict;
}
+ trans_pcie->inta_mask = CSR_INI_SET_MASK;
+
return trans;
out_free_ict:
diff --git a/drivers/net/wireless/iwlwifi/pcie/tx.c b/drivers/net/wireless/iwlwifi/pcie/tx.c
index dde6031..3b0c72c 100644
--- a/drivers/net/wireless/iwlwifi/pcie/tx.c
+++ b/drivers/net/wireless/iwlwifi/pcie/tx.c
@@ -287,14 +287,14 @@
/*
* iwl_pcie_txq_inc_wr_ptr - Send new write index to hardware
*/
-static void iwl_pcie_txq_inc_wr_ptr(struct iwl_trans *trans,
- struct iwl_txq *txq)
+void iwl_pcie_txq_inc_wr_ptr(struct iwl_trans *trans, struct iwl_txq *txq)
{
struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans);
u32 reg = 0;
int txq_id = txq->q.id;
- lockdep_assert_held(&txq->lock);
+ if (txq->need_update == 0)
+ return;
/*
* explicitly wake up the NIC if:
@@ -317,7 +317,6 @@
txq_id, reg);
iwl_set_bit(trans, CSR_GP_CNTRL,
CSR_GP_CNTRL_REG_FLAG_MAC_ACCESS_REQ);
- txq->need_update = true;
return;
}
}
@@ -328,23 +327,8 @@
*/
IWL_DEBUG_TX(trans, "Q:%d WR: 0x%x\n", txq_id, txq->q.write_ptr);
iwl_write32(trans, HBUS_TARG_WRPTR, txq->q.write_ptr | (txq_id << 8));
-}
-void iwl_pcie_txq_check_wrptrs(struct iwl_trans *trans)
-{
- struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans);
- int i;
-
- for (i = 0; i < trans->cfg->base_params->num_of_queues; i++) {
- struct iwl_txq *txq = &trans_pcie->txq[i];
-
- spin_lock(&txq->lock);
- if (trans_pcie->txq[i].need_update) {
- iwl_pcie_txq_inc_wr_ptr(trans, txq);
- trans_pcie->txq[i].need_update = false;
- }
- spin_unlock(&txq->lock);
- }
+ txq->need_update = 0;
}
static inline dma_addr_t iwl_pcie_tfd_tb_get_addr(struct iwl_tfd *tfd, u8 idx)
@@ -558,7 +542,7 @@
{
int ret;
- txq->need_update = false;
+ txq->need_update = 0;
/* TFD_QUEUE_SIZE_MAX must be power-of-two size, otherwise
* iwl_queue_inc_wrap and iwl_queue_dec_wrap are broken. */
@@ -696,8 +680,7 @@
/* The chain extension of the SCD doesn't work well. This feature is
* enabled by default by the HW, so we need to disable it manually.
*/
- if (trans->cfg->base_params->scd_chain_ext_wa)
- iwl_write_prph(trans, SCD_CHAINEXT_EN, 0);
+ iwl_write_prph(trans, SCD_CHAINEXT_EN, 0);
iwl_trans_ac_txq_enable(trans, trans_pcie->cmd_queue,
trans_pcie->cmd_fifo);
@@ -1045,8 +1028,7 @@
}
}
- if (trans->cfg->base_params->apmg_wake_up_wa &&
- q->read_ptr == q->write_ptr) {
+ if (q->read_ptr == q->write_ptr) {
spin_lock_irqsave(&trans_pcie->reg_lock, flags);
WARN_ON(!trans_pcie->cmd_in_flight);
trans_pcie->cmd_in_flight = false;
@@ -1410,6 +1392,8 @@
kfree(txq->entries[idx].free_buf);
txq->entries[idx].free_buf = dup_buf;
+ txq->need_update = 1;
+
trace_iwlwifi_dev_hcmd(trans->dev, cmd, cmd_size, &out_cmd->hdr);
/* start timer if queue currently empty */
@@ -1421,11 +1405,9 @@
/*
* wake up the NIC to make sure that the firmware will see the host
* command - we will let the NIC sleep once all the host commands
- * returned. This needs to be done only on NICs that have
- * apmg_wake_up_wa set.
+ * returned.
*/
- if (trans->cfg->base_params->apmg_wake_up_wa &&
- !trans_pcie->cmd_in_flight) {
+ if (!trans_pcie->cmd_in_flight) {
trans_pcie->cmd_in_flight = true;
__iwl_trans_pcie_set_bit(trans, CSR_GP_CNTRL,
CSR_GP_CNTRL_REG_FLAG_MAC_ACCESS_REQ);
@@ -1679,7 +1661,7 @@
dma_addr_t tb0_phys, tb1_phys, scratch_phys;
void *tb1_addr;
u16 len, tb1_len, tb2_len;
- bool wait_write_ptr;
+ u8 wait_write_ptr = 0;
__le16 fc = hdr->frame_control;
u8 hdr_len = ieee80211_hdrlen(fc);
u16 wifi_seq;
@@ -1780,7 +1762,12 @@
trace_iwlwifi_dev_tx_data(trans->dev, skb,
skb->data + hdr_len, tb2_len);
- wait_write_ptr = ieee80211_has_morefrags(fc);
+ if (!ieee80211_has_morefrags(fc)) {
+ txq->need_update = 1;
+ } else {
+ wait_write_ptr = 1;
+ txq->need_update = 0;
+ }
/* start timer if queue currently empty */
if (txq->need_update && q->read_ptr == q->write_ptr &&
@@ -1789,18 +1776,21 @@
/* Tell device the write index *just past* this latest filled TFD */
q->write_ptr = iwl_queue_inc_wrap(q->write_ptr, q->n_bd);
- if (!wait_write_ptr)
- iwl_pcie_txq_inc_wr_ptr(trans, txq);
+ iwl_pcie_txq_inc_wr_ptr(trans, txq);
/*
* At this point the frame is "transmitted" successfully
- * and we will get a TX status notification eventually.
+ * and we will get a TX status notification eventually,
+ * regardless of the value of ret. "ret" only indicates
+ * whether or not we should update the write pointer.
*/
if (iwl_queue_space(q) < q->high_mark) {
- if (wait_write_ptr)
+ if (wait_write_ptr) {
+ txq->need_update = 1;
iwl_pcie_txq_inc_wr_ptr(trans, txq);
- else
+ } else {
iwl_stop_queue(trans, txq);
+ }
}
spin_unlock(&txq->lock);
return 0;
diff --git a/drivers/net/wireless/mwifiex/11ac.c b/drivers/net/wireless/mwifiex/11ac.c
index 706831d..c92f27a 100644
--- a/drivers/net/wireless/mwifiex/11ac.c
+++ b/drivers/net/wireless/mwifiex/11ac.c
@@ -212,7 +212,8 @@
sizeof(struct mwifiex_ie_types_header));
memcpy((u8 *)vht_op +
sizeof(struct mwifiex_ie_types_header),
- (u8 *)bss_desc->bcn_vht_oper,
+ (u8 *)bss_desc->bcn_vht_oper +
+ sizeof(struct ieee_types_header),
le16_to_cpu(vht_op->header.len));
/* negotiate the channel width and central freq
diff --git a/drivers/net/wireless/mwifiex/11n.c b/drivers/net/wireless/mwifiex/11n.c
index 2bd07d6..d14ead8 100644
--- a/drivers/net/wireless/mwifiex/11n.c
+++ b/drivers/net/wireless/mwifiex/11n.c
@@ -345,7 +345,8 @@
memcpy((u8 *) ht_info +
sizeof(struct mwifiex_ie_types_header),
- (u8 *)bss_desc->bcn_ht_oper,
+ (u8 *) bss_desc->bcn_ht_oper +
+ sizeof(struct ieee_types_header),
le16_to_cpu(ht_info->header.len));
if (!(sband->ht_cap.cap &
diff --git a/drivers/net/wireless/mwifiex/11n_aggr.c b/drivers/net/wireless/mwifiex/11n_aggr.c
index 860dfe7..6321170 100644
--- a/drivers/net/wireless/mwifiex/11n_aggr.c
+++ b/drivers/net/wireless/mwifiex/11n_aggr.c
@@ -160,7 +160,6 @@
int pad = 0, ret;
struct mwifiex_tx_param tx_param;
struct txpd *ptx_pd = NULL;
- struct timeval tv;
int headroom = adapter->iface_type == MWIFIEX_USB ? 0 : INTF_HEADER_LEN;
skb_src = skb_peek(&pra_list->skb_head);
@@ -185,9 +184,6 @@
tx_info_aggr->bss_num = tx_info_src->bss_num;
skb_aggr->priority = skb_src->priority;
- do_gettimeofday(&tv);
- skb_aggr->tstamp = timeval_to_ktime(tv);
-
do {
/* Check if AMSDU can accommodate this MSDU */
if (skb_tailroom(skb_aggr) < (skb_src->len + LLC_SNAP_LEN))
@@ -240,11 +236,18 @@
ret = adapter->if_ops.host_to_card(adapter, MWIFIEX_USB_EP_DATA,
skb_aggr, NULL);
} else {
- if (skb_src)
- tx_param.next_pkt_len =
- skb_src->len + sizeof(struct txpd);
- else
- tx_param.next_pkt_len = 0;
+ /*
+ * Padding per MSDU will affect the length of next
+ * packet and hence the exact length of next packet
+ * is uncertain here.
+ *
+ * Also, aggregation of transmission buffer, while
+ * downloading the data to the card, wont gain much
+ * on the AMSDU packets as the AMSDU packets utilizes
+ * the transmission buffer space to the maximum
+ * (adapter->tx_buf_size).
+ */
+ tx_param.next_pkt_len = 0;
ret = adapter->if_ops.host_to_card(adapter, MWIFIEX_TYPE_DATA,
skb_aggr, &tx_param);
diff --git a/drivers/net/wireless/mwifiex/README b/drivers/net/wireless/mwifiex/README
index 3b55ce5..b9242c3 100644
--- a/drivers/net/wireless/mwifiex/README
+++ b/drivers/net/wireless/mwifiex/README
@@ -200,11 +200,4 @@
cat getlog
-fw_dump
- This command is used to dump firmware memory into files.
- Separate file will be created for each memory segment.
- Usage:
-
- cat fw_dump
-
===============================================================================
diff --git a/drivers/net/wireless/mwifiex/cmdevt.c b/drivers/net/wireless/mwifiex/cmdevt.c
index 421322f..1062c91 100644
--- a/drivers/net/wireless/mwifiex/cmdevt.c
+++ b/drivers/net/wireless/mwifiex/cmdevt.c
@@ -955,14 +955,13 @@
adapter->cmd_wait_q.status = -ETIMEDOUT;
wake_up_interruptible(&adapter->cmd_wait_q.wait);
mwifiex_cancel_pending_ioctl(adapter);
+ /* reset cmd_sent flag to unblock new commands */
+ adapter->cmd_sent = false;
}
}
if (adapter->hw_status == MWIFIEX_HW_STATUS_INITIALIZING)
mwifiex_init_fw_complete(adapter);
- if (adapter->if_ops.fw_dump)
- adapter->if_ops.fw_dump(adapter);
-
if (adapter->if_ops.card_reset)
adapter->if_ops.card_reset(adapter);
}
diff --git a/drivers/net/wireless/mwifiex/debugfs.c b/drivers/net/wireless/mwifiex/debugfs.c
index 7b419bb..b8a49aa 100644
--- a/drivers/net/wireless/mwifiex/debugfs.c
+++ b/drivers/net/wireless/mwifiex/debugfs.c
@@ -257,29 +257,6 @@
}
/*
- * Proc firmware dump read handler.
- *
- * This function is called when the 'fw_dump' file is opened for
- * reading.
- * This function dumps firmware memory in different files
- * (ex. DTCM, ITCM, SQRAM etc.) based on the the segments for
- * debugging.
- */
-static ssize_t
-mwifiex_fw_dump_read(struct file *file, char __user *ubuf,
- size_t count, loff_t *ppos)
-{
- struct mwifiex_private *priv = file->private_data;
-
- if (!priv->adapter->if_ops.fw_dump)
- return -EIO;
-
- priv->adapter->if_ops.fw_dump(priv->adapter);
-
- return 0;
-}
-
-/*
* Proc getlog file read handler.
*
* This function is called when the 'getlog' file is opened for reading
@@ -722,7 +699,6 @@
MWIFIEX_DFS_FILE_READ_OPS(info);
MWIFIEX_DFS_FILE_READ_OPS(debug);
MWIFIEX_DFS_FILE_READ_OPS(getlog);
-MWIFIEX_DFS_FILE_READ_OPS(fw_dump);
MWIFIEX_DFS_FILE_OPS(regrdwr);
MWIFIEX_DFS_FILE_OPS(rdeeprom);
@@ -746,7 +722,6 @@
MWIFIEX_DFS_ADD_FILE(getlog);
MWIFIEX_DFS_ADD_FILE(regrdwr);
MWIFIEX_DFS_ADD_FILE(rdeeprom);
- MWIFIEX_DFS_ADD_FILE(fw_dump);
}
/*
diff --git a/drivers/net/wireless/mwifiex/decl.h b/drivers/net/wireless/mwifiex/decl.h
index 3691b7c..51e0f6d 100644
--- a/drivers/net/wireless/mwifiex/decl.h
+++ b/drivers/net/wireless/mwifiex/decl.h
@@ -42,12 +42,12 @@
#define MWIFIEX_MAX_TX_BASTREAM_SUPPORTED 2
#define MWIFIEX_MAX_RX_BASTREAM_SUPPORTED 16
-#define MWIFIEX_STA_AMPDU_DEF_TXWINSIZE 64
-#define MWIFIEX_STA_AMPDU_DEF_RXWINSIZE 64
+#define MWIFIEX_STA_AMPDU_DEF_TXWINSIZE 16
+#define MWIFIEX_STA_AMPDU_DEF_RXWINSIZE 32
#define MWIFIEX_UAP_AMPDU_DEF_TXWINSIZE 32
#define MWIFIEX_UAP_AMPDU_DEF_RXWINSIZE 16
-#define MWIFIEX_11AC_STA_AMPDU_DEF_TXWINSIZE 64
-#define MWIFIEX_11AC_STA_AMPDU_DEF_RXWINSIZE 64
+#define MWIFIEX_11AC_STA_AMPDU_DEF_TXWINSIZE 32
+#define MWIFIEX_11AC_STA_AMPDU_DEF_RXWINSIZE 48
#define MWIFIEX_11AC_UAP_AMPDU_DEF_TXWINSIZE 48
#define MWIFIEX_11AC_UAP_AMPDU_DEF_RXWINSIZE 32
diff --git a/drivers/net/wireless/mwifiex/ioctl.h b/drivers/net/wireless/mwifiex/ioctl.h
index 1b57672..ee494db 100644
--- a/drivers/net/wireless/mwifiex/ioctl.h
+++ b/drivers/net/wireless/mwifiex/ioctl.h
@@ -303,7 +303,7 @@
u32 rx_ant;
};
-#define MWIFIEX_NUM_OF_CMD_BUFFER 50
+#define MWIFIEX_NUM_OF_CMD_BUFFER 20
#define MWIFIEX_SIZE_OF_CMD_BUFFER 2048
enum {
diff --git a/drivers/net/wireless/mwifiex/main.c b/drivers/net/wireless/mwifiex/main.c
index 6ff6390..f674ebf 100644
--- a/drivers/net/wireless/mwifiex/main.c
+++ b/drivers/net/wireless/mwifiex/main.c
@@ -521,6 +521,7 @@
release_firmware(adapter->firmware);
adapter->firmware = NULL;
}
+ complete(&adapter->fw_load);
if (init_failed)
mwifiex_free_adapter(adapter);
up(sem);
@@ -534,6 +535,7 @@
{
int ret;
+ init_completion(&adapter->fw_load);
ret = request_firmware_nowait(THIS_MODULE, 1, adapter->fw_name,
adapter->dev, GFP_KERNEL, adapter,
mwifiex_fw_dpc);
@@ -645,6 +647,7 @@
}
tx_info = MWIFIEX_SKB_TXCB(skb);
+ memset(tx_info, 0, sizeof(*tx_info));
tx_info->bss_num = priv->bss_num;
tx_info->bss_type = priv->bss_type;
tx_info->pkt_len = skb->len;
@@ -745,7 +748,7 @@
return &priv->stats;
}
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,15,0)
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,14,0)
static u16
mwifiex_netdev_select_wmm_queue(struct net_device *dev, struct sk_buff *skb,
void *accel_priv, select_queue_fallback_t fallback)
@@ -890,8 +893,6 @@
goto err_kmalloc;
INIT_WORK(&adapter->main_work, mwifiex_main_work_queue);
- if (adapter->if_ops.iface_work)
- INIT_WORK(&adapter->iface_work, adapter->if_ops.iface_work);
/* Register the device. Fill up the private data structure with relevant
information from the card. */
diff --git a/drivers/net/wireless/mwifiex/main.h b/drivers/net/wireless/mwifiex/main.h
index d70457b..d53e1e8 100644
--- a/drivers/net/wireless/mwifiex/main.h
+++ b/drivers/net/wireless/mwifiex/main.h
@@ -672,9 +672,7 @@
int (*init_fw_port) (struct mwifiex_adapter *);
int (*dnld_fw) (struct mwifiex_adapter *, struct mwifiex_fw_image *);
void (*card_reset) (struct mwifiex_adapter *);
- void (*fw_dump)(struct mwifiex_adapter *);
int (*clean_pcie_ring) (struct mwifiex_adapter *adapter);
- void (*iface_work)(struct work_struct *work);
};
struct mwifiex_adapter {
@@ -789,6 +787,7 @@
struct mwifiex_wait_queue cmd_wait_q;
u8 scan_wait_q_woken;
spinlock_t queue_lock; /* lock for tx queues */
+ struct completion fw_load;
u8 country_code[IEEE80211_COUNTRY_STRING_LEN];
u16 max_mgmt_ie_index;
u8 scan_delay_cnt;
@@ -810,7 +809,6 @@
bool ext_scan;
u8 fw_api_ver;
u8 fw_key_api_major_ver, fw_key_api_minor_ver;
- struct work_struct iface_work;
};
int mwifiex_init_lock_list(struct mwifiex_adapter *adapter);
diff --git a/drivers/net/wireless/mwifiex/pcie.c b/drivers/net/wireless/mwifiex/pcie.c
index 51989b3..a7e8b96 100644
--- a/drivers/net/wireless/mwifiex/pcie.c
+++ b/drivers/net/wireless/mwifiex/pcie.c
@@ -37,9 +37,6 @@
static struct semaphore add_remove_card_sem;
-/* enum mwifiex_pcie_work_flags bitmap */
-static unsigned long pcie_work_flags;
-
static int
mwifiex_map_pci_memory(struct mwifiex_adapter *adapter, struct sk_buff *skb,
size_t size, int flags)
@@ -224,7 +221,8 @@
if (!adapter || !adapter->priv_num)
return;
- cancel_work_sync(&adapter->iface_work);
+ /* In case driver is removed when asynchronous FW load is in progress */
+ wait_for_completion(&adapter->fw_load);
if (user_rmmod) {
#ifdef CONFIG_PM_SLEEP
@@ -312,17 +310,6 @@
return 0;
}
-/* This function reads u8 data from PCIE card register. */
-static int mwifiex_read_reg_byte(struct mwifiex_adapter *adapter,
- int reg, u8 *data)
-{
- struct pcie_service_card *card = adapter->card;
-
- *data = ioread8(card->pci_mmap1 + reg);
-
- return 0;
-}
-
/*
* This function adds delay loop to ensure FW is awake before proceeding.
*/
@@ -2188,215 +2175,6 @@
return 0;
}
-/* This function read/write firmware */
-static enum rdwr_status
-mwifiex_pcie_rdwr_firmware(struct mwifiex_adapter *adapter, u8 doneflag)
-{
- int ret, tries;
- u8 ctrl_data;
-
- ret = mwifiex_write_reg(adapter, DEBUG_DUMP_CTRL_REG, DEBUG_HOST_READY);
- if (ret) {
- dev_err(adapter->dev, "PCIE write err\n");
- return RDWR_STATUS_FAILURE;
- }
-
- for (tries = 0; tries < MAX_POLL_TRIES; tries++) {
- mwifiex_read_reg_byte(adapter, DEBUG_DUMP_CTRL_REG, &ctrl_data);
- if (ctrl_data == DEBUG_FW_DONE)
- return RDWR_STATUS_SUCCESS;
- if (doneflag && ctrl_data == doneflag)
- return RDWR_STATUS_DONE;
- if (ctrl_data != DEBUG_HOST_READY) {
- dev_info(adapter->dev,
- "The ctrl reg was changed, re-try again!\n");
- mwifiex_write_reg(adapter, DEBUG_DUMP_CTRL_REG,
- DEBUG_HOST_READY);
- if (ret) {
- dev_err(adapter->dev, "PCIE write err\n");
- return RDWR_STATUS_FAILURE;
- }
- }
- usleep_range(100, 200);
- }
-
- dev_err(adapter->dev, "Fail to pull ctrl_data\n");
- return RDWR_STATUS_FAILURE;
-}
-
-/* This function dump firmware memory to file */
-static void mwifiex_pcie_fw_dump_work(struct work_struct *work)
-{
- struct mwifiex_adapter *adapter =
- container_of(work, struct mwifiex_adapter, iface_work);
- unsigned int reg, reg_start, reg_end;
- u8 *dbg_ptr;
- struct timeval t;
- u8 dump_num = 0, idx, i, read_reg, doneflag = 0;
- enum rdwr_status stat;
- u32 memory_size;
- u8 filename[MAX_FULL_NAME_LEN];
- mm_segment_t fs;
- loff_t pos;
- u8 *end_ptr;
- u8 *name_prefix = "/var/log/fw_dump_";
- struct memory_type_mapping mem_type_mapping_tbl[] = {
- {"ITCM", NULL, NULL, 0xF0},
- {"DTCM", NULL, NULL, 0xF1},
- {"SQRAM", NULL, NULL, 0xF2},
- {"IRAM", NULL, NULL, 0xF3},
- };
-
- if (!adapter) {
- dev_err(adapter->dev, "Could not dump firmwware info\n");
- return;
- }
-
- do_gettimeofday(&t);
- dev_info(adapter->dev, "== mwifiex firmware dump start: %u.%06u ==\n",
- (u32)t.tv_sec, (u32)t.tv_usec);
-
- /* Read the number of the memories which will dump */
- stat = mwifiex_pcie_rdwr_firmware(adapter, doneflag);
- if (stat == RDWR_STATUS_FAILURE)
- goto done;
-
- reg = DEBUG_DUMP_START_REG;
- mwifiex_read_reg_byte(adapter, reg, &dump_num);
-
- /* Read the length of every memory which will dump */
- for (idx = 0; idx < dump_num; idx++) {
- struct memory_type_mapping *entry = &mem_type_mapping_tbl[idx];
-
- stat = mwifiex_pcie_rdwr_firmware(adapter, doneflag);
- if (stat == RDWR_STATUS_FAILURE)
- goto done;
-
- memory_size = 0;
- reg = DEBUG_DUMP_START_REG;
- for (i = 0; i < 4; i++) {
- mwifiex_read_reg_byte(adapter, reg, &read_reg);
- memory_size |= (read_reg << (i * 8));
- reg++;
- }
-
- if (memory_size == 0) {
- dev_info(adapter->dev, "Firmware dump Finished!\n");
- break;
- }
-
- dev_info(adapter->dev,
- "%s_SIZE=0x%x\n", entry->mem_name, memory_size);
- entry->mem_ptr = vmalloc(memory_size + 1);
- if (!entry->mem_ptr) {
- dev_err(adapter->dev,
- "Vmalloc %s failed\n", entry->mem_name);
- goto done;
- }
- dbg_ptr = entry->mem_ptr;
- end_ptr = dbg_ptr + memory_size;
-
- doneflag = entry->done_flag;
- do_gettimeofday(&t);
- dev_info(adapter->dev, "Start %s output %u.%06u, please wait...\n",
- entry->mem_name, (u32)t.tv_sec, (u32)t.tv_usec);
-
- do {
- stat = mwifiex_pcie_rdwr_firmware(adapter, doneflag);
- if (RDWR_STATUS_FAILURE == stat)
- goto done;
-
- reg_start = DEBUG_DUMP_START_REG;
- reg_end = DEBUG_DUMP_END_REG;
- for (reg = reg_start; reg <= reg_end; reg++) {
- mwifiex_read_reg_byte(adapter, reg, dbg_ptr);
- if (dbg_ptr < end_ptr)
- dbg_ptr++;
- else
- dev_err(adapter->dev,
- "Allocated buf not enough\n");
- }
-
- if (stat != RDWR_STATUS_DONE)
- continue;
-
- dev_info(adapter->dev, "%s done: size=0x%lx\n",
- entry->mem_name, dbg_ptr - entry->mem_ptr);
- memset(filename, 0, sizeof(filename));
- memcpy(filename, name_prefix, strlen(name_prefix));
- strcat(filename, entry->mem_name);
- do_gettimeofday(&t);
- entry->file_mem = filp_open(filename, O_CREAT | O_RDWR,
- 0644);
- if (IS_ERR(entry->file_mem)) {
- dev_info(adapter->dev,
- "Create %s file failed at %s, opening another dir /tmp\n",
- entry->mem_name, filename);
- memset(filename, 0, sizeof(filename));
- sprintf(filename, "%s%s", "/tmp/fw_dump_",
- entry->mem_name);
- entry->file_mem =
- filp_open(filename,
- O_CREAT | O_RDWR, 0644);
- }
- if (!IS_ERR(entry->file_mem)) {
- dev_info(adapter->dev,
- "Start to save the output : %u.%06u, please wait...\n",
- (u32)t.tv_sec, (u32)t.tv_usec);
- fs = get_fs();
- set_fs(KERNEL_DS);
- pos = 0;
- vfs_write(entry->file_mem,
- (char __user *)entry->mem_ptr,
- memory_size, &pos);
- filp_close(entry->file_mem, NULL);
- set_fs(fs);
- dev_info(adapter->dev,
- "The output %s have been saved to file successfully!\n",
- entry->mem_name);
- } else {
- dev_err(adapter->dev,
- "Failed to create file %s\n", filename);
- }
- vfree(entry->mem_ptr);
- entry->mem_ptr = NULL;
- break;
- } while (true);
- }
- do_gettimeofday(&t);
- dev_info(adapter->dev, "== mwifiex firmware dump end: %u.%06u ==\n",
- (u32)t.tv_sec, (u32)t.tv_usec);
-
-done:
- for (idx = 0; idx < ARRAY_SIZE(mem_type_mapping_tbl); idx++) {
- struct memory_type_mapping *entry = &mem_type_mapping_tbl[idx];
-
- if (entry->mem_ptr) {
- vfree(entry->mem_ptr);
- entry->mem_ptr = NULL;
- }
- }
-
- return;
-}
-
-static void mwifiex_pcie_work(struct work_struct *work)
-{
- if (test_and_clear_bit(MWIFIEX_PCIE_WORK_FW_DUMP, &pcie_work_flags))
- mwifiex_pcie_fw_dump_work(work);
-}
-
-/* This function dumps FW information */
-static void mwifiex_pcie_fw_dump(struct mwifiex_adapter *adapter)
-{
- if (test_bit(MWIFIEX_PCIE_WORK_FW_DUMP, &pcie_work_flags))
- return;
-
- set_bit(MWIFIEX_PCIE_WORK_FW_DUMP, &pcie_work_flags);
-
- schedule_work(&adapter->iface_work);
-}
-
/*
* This function initializes the PCI-E host memory space, WCB rings, etc.
*
@@ -2618,8 +2396,6 @@
.cleanup_mpa_buf = NULL,
.init_fw_port = mwifiex_pcie_init_fw_port,
.clean_pcie_ring = mwifiex_clean_pcie_ring_buf,
- .fw_dump = mwifiex_pcie_fw_dump,
- .iface_work = mwifiex_pcie_work,
};
/*
diff --git a/drivers/net/wireless/mwifiex/pcie.h b/drivers/net/wireless/mwifiex/pcie.h
index 3abba32..e8ec561 100644
--- a/drivers/net/wireless/mwifiex/pcie.h
+++ b/drivers/net/wireless/mwifiex/pcie.h
@@ -100,28 +100,6 @@
#define MWIFIEX_DEF_SLEEP_COOKIE 0xBEEFBEEF
#define MWIFIEX_MAX_DELAY_COUNT 5
-#define DEBUG_DUMP_CTRL_REG 0xCF4
-#define DEBUG_DUMP_START_REG 0xCF8
-#define DEBUG_DUMP_END_REG 0xCFF
-#define DEBUG_HOST_READY 0xEE
-#define DEBUG_FW_DONE 0xFF
-
-#define MAX_NAME_LEN 8
-#define MAX_FULL_NAME_LEN 32
-
-struct memory_type_mapping {
- u8 mem_name[MAX_NAME_LEN];
- u8 *mem_ptr;
- struct file *file_mem;
- u8 done_flag;
-};
-
-enum rdwr_status {
- RDWR_STATUS_SUCCESS = 0,
- RDWR_STATUS_FAILURE = 1,
- RDWR_STATUS_DONE = 2
-};
-
struct mwifiex_pcie_card_reg {
u16 cmd_addr_lo;
u16 cmd_addr_hi;
@@ -344,9 +322,4 @@
return 0;
}
-
-enum mwifiex_pcie_work_flags {
- MWIFIEX_PCIE_WORK_FW_DUMP,
-};
-
#endif /* _MWIFIEX_PCIE_H */
diff --git a/drivers/net/wireless/mwifiex/scan.c b/drivers/net/wireless/mwifiex/scan.c
index d75f4eb..7b3af3d 100644
--- a/drivers/net/wireless/mwifiex/scan.c
+++ b/drivers/net/wireless/mwifiex/scan.c
@@ -29,6 +29,9 @@
#define MWIFIEX_MAX_CHANNELS_PER_SPECIFIC_SCAN 14
#define MWIFIEX_DEF_CHANNELS_PER_SCAN_CMD 4
+#define MWIFIEX_LIMIT_1_CHANNEL_PER_SCAN_CMD 15
+#define MWIFIEX_LIMIT_2_CHANNELS_PER_SCAN_CMD 27
+#define MWIFIEX_LIMIT_3_CHANNELS_PER_SCAN_CMD 35
/* Memory needed to store a max sized Channel List TLV for a firmware scan */
#define CHAN_TLV_MAX_SIZE (sizeof(struct mwifiex_ie_types_header) \
@@ -1052,10 +1055,20 @@
/*
* In associated state we will reduce the number of channels scanned per
- * scan command to 1 to avoid any traffic delay/loss.
+ * scan command to avoid any traffic delay/loss. This number is decided
+ * based on total number of channels to be scanned due to constraints
+ * of command buffers.
*/
- if (priv->media_connected)
+ if (priv->media_connected) {
+ if (chan_num < MWIFIEX_LIMIT_1_CHANNEL_PER_SCAN_CMD)
*max_chan_per_scan = 1;
+ else if (chan_num < MWIFIEX_LIMIT_2_CHANNELS_PER_SCAN_CMD)
+ *max_chan_per_scan = 2;
+ else if (chan_num < MWIFIEX_LIMIT_3_CHANNELS_PER_SCAN_CMD)
+ *max_chan_per_scan = 3;
+ else
+ *max_chan_per_scan = 4;
+ }
}
/*
@@ -1340,17 +1353,23 @@
bss_entry->beacon_buf);
break;
case WLAN_EID_BSS_COEX_2040:
- bss_entry->bcn_bss_co_2040 = current_ptr;
- bss_entry->bss_co_2040_offset =
- (u16) (current_ptr - bss_entry->beacon_buf);
+ bss_entry->bcn_bss_co_2040 = current_ptr +
+ sizeof(struct ieee_types_header);
+ bss_entry->bss_co_2040_offset = (u16) (current_ptr +
+ sizeof(struct ieee_types_header) -
+ bss_entry->beacon_buf);
break;
case WLAN_EID_EXT_CAPABILITY:
- bss_entry->bcn_ext_cap = current_ptr;
- bss_entry->ext_cap_offset =
- (u16) (current_ptr - bss_entry->beacon_buf);
+ bss_entry->bcn_ext_cap = current_ptr +
+ sizeof(struct ieee_types_header);
+ bss_entry->ext_cap_offset = (u16) (current_ptr +
+ sizeof(struct ieee_types_header) -
+ bss_entry->beacon_buf);
break;
case WLAN_EID_OPMODE_NOTIF:
- bss_entry->oper_mode = (void *)current_ptr;
+ bss_entry->oper_mode =
+ (void *)(current_ptr +
+ sizeof(struct ieee_types_header));
bss_entry->oper_mode_offset =
(u16)((u8 *)bss_entry->oper_mode -
bss_entry->beacon_buf);
diff --git a/drivers/net/wireless/mwifiex/sdio.c b/drivers/net/wireless/mwifiex/sdio.c
index a1773d3..d206f04 100644
--- a/drivers/net/wireless/mwifiex/sdio.c
+++ b/drivers/net/wireless/mwifiex/sdio.c
@@ -85,8 +85,6 @@
card->supports_sdio_new_mode = data->supports_sdio_new_mode;
card->has_control_mask = data->has_control_mask;
card->tx_buf_size = data->tx_buf_size;
- card->mp_tx_agg_buf_size = data->mp_tx_agg_buf_size;
- card->mp_rx_agg_buf_size = data->mp_rx_agg_buf_size;
}
sdio_claim_host(func);
@@ -179,6 +177,9 @@
if (!adapter || !adapter->priv_num)
return;
+ /* In case driver is removed when asynchronous FW load is in progress */
+ wait_for_completion(&adapter->fw_load);
+
if (user_rmmod) {
if (adapter->is_suspended)
mwifiex_sdio_resume(adapter->dev);
@@ -1841,8 +1842,8 @@
card->mpa_rx.len_arr = kzalloc(sizeof(*card->mpa_rx.len_arr) *
card->mp_agg_pkt_limit, GFP_KERNEL);
ret = mwifiex_alloc_sdio_mpa_buffers(adapter,
- card->mp_tx_agg_buf_size,
- card->mp_rx_agg_buf_size);
+ SDIO_MP_TX_AGGR_DEF_BUF_SIZE,
+ SDIO_MP_RX_AGGR_DEF_BUF_SIZE);
if (ret) {
dev_err(adapter->dev, "failed to alloc sdio mp-a buffers\n");
kfree(card->mp_regs);
diff --git a/drivers/net/wireless/mwifiex/sdio.h b/drivers/net/wireless/mwifiex/sdio.h
index 6eea30b..c71201b 100644
--- a/drivers/net/wireless/mwifiex/sdio.h
+++ b/drivers/net/wireless/mwifiex/sdio.h
@@ -64,8 +64,10 @@
#define UP_LD_CMD_PORT_HOST_INT_STATUS (0x40U)
#define DN_LD_CMD_PORT_HOST_INT_STATUS (0x80U)
-#define MWIFIEX_MP_AGGR_BUF_SIZE_16K (16384)
-#define MWIFIEX_MP_AGGR_BUF_SIZE_32K (32768)
+#define SDIO_MP_TX_AGGR_DEF_BUF_SIZE (8192) /* 8K */
+
+/* Multi port RX aggregation buffer size */
+#define SDIO_MP_RX_AGGR_DEF_BUF_SIZE (16384) /* 16K */
/* Misc. Config Register : Auto Re-enable interrupts */
#define AUTO_RE_ENABLE_INT BIT(4)
@@ -232,8 +234,6 @@
bool supports_sdio_new_mode;
bool has_control_mask;
u16 tx_buf_size;
- u32 mp_tx_agg_buf_size;
- u32 mp_rx_agg_buf_size;
u32 mp_rd_bitmap;
u32 mp_wr_bitmap;
@@ -258,8 +258,6 @@
bool supports_sdio_new_mode;
bool has_control_mask;
u16 tx_buf_size;
- u32 mp_tx_agg_buf_size;
- u32 mp_rx_agg_buf_size;
};
static const struct mwifiex_sdio_card_reg mwifiex_reg_sd87xx = {
@@ -317,8 +315,6 @@
.supports_sdio_new_mode = false,
.has_control_mask = true,
.tx_buf_size = MWIFIEX_TX_DATA_BUF_SIZE_2K,
- .mp_tx_agg_buf_size = MWIFIEX_MP_AGGR_BUF_SIZE_16K,
- .mp_rx_agg_buf_size = MWIFIEX_MP_AGGR_BUF_SIZE_16K,
};
static const struct mwifiex_sdio_device mwifiex_sdio_sd8787 = {
@@ -329,8 +325,6 @@
.supports_sdio_new_mode = false,
.has_control_mask = true,
.tx_buf_size = MWIFIEX_TX_DATA_BUF_SIZE_2K,
- .mp_tx_agg_buf_size = MWIFIEX_MP_AGGR_BUF_SIZE_16K,
- .mp_rx_agg_buf_size = MWIFIEX_MP_AGGR_BUF_SIZE_16K,
};
static const struct mwifiex_sdio_device mwifiex_sdio_sd8797 = {
@@ -341,8 +335,6 @@
.supports_sdio_new_mode = false,
.has_control_mask = true,
.tx_buf_size = MWIFIEX_TX_DATA_BUF_SIZE_2K,
- .mp_tx_agg_buf_size = MWIFIEX_MP_AGGR_BUF_SIZE_16K,
- .mp_rx_agg_buf_size = MWIFIEX_MP_AGGR_BUF_SIZE_16K,
};
static const struct mwifiex_sdio_device mwifiex_sdio_sd8897 = {
@@ -353,8 +345,6 @@
.supports_sdio_new_mode = true,
.has_control_mask = false,
.tx_buf_size = MWIFIEX_TX_DATA_BUF_SIZE_4K,
- .mp_tx_agg_buf_size = MWIFIEX_MP_AGGR_BUF_SIZE_32K,
- .mp_rx_agg_buf_size = MWIFIEX_MP_AGGR_BUF_SIZE_32K,
};
/*
diff --git a/drivers/net/wireless/mwifiex/uap_cmd.c b/drivers/net/wireless/mwifiex/uap_cmd.c
index 3264355..9be6544 100644
--- a/drivers/net/wireless/mwifiex/uap_cmd.c
+++ b/drivers/net/wireless/mwifiex/uap_cmd.c
@@ -175,19 +175,17 @@
switch (GET_RXSTBC(cap_info)) {
case MWIFIEX_RX_STBC1:
/* HT_CAP 1X1 mode */
- bss_cfg->ht_cap.mcs.rx_mask[0] = 0xff;
+ memset(&bss_cfg->ht_cap.mcs, 0xff, 1);
break;
case MWIFIEX_RX_STBC12: /* fall through */
case MWIFIEX_RX_STBC123:
/* HT_CAP 2X2 mode */
- bss_cfg->ht_cap.mcs.rx_mask[0] = 0xff;
- bss_cfg->ht_cap.mcs.rx_mask[1] = 0xff;
+ memset(&bss_cfg->ht_cap.mcs, 0xff, 2);
break;
default:
dev_warn(priv->adapter->dev,
"Unsupported RX-STBC, default to 2x2\n");
- bss_cfg->ht_cap.mcs.rx_mask[0] = 0xff;
- bss_cfg->ht_cap.mcs.rx_mask[1] = 0xff;
+ memset(&bss_cfg->ht_cap.mcs, 0xff, 2);
break;
}
priv->ap_11n_enabled = 1;
diff --git a/drivers/net/wireless/mwifiex/usb.c b/drivers/net/wireless/mwifiex/usb.c
index a8ce813..edbe4af 100644
--- a/drivers/net/wireless/mwifiex/usb.c
+++ b/drivers/net/wireless/mwifiex/usb.c
@@ -22,9 +22,9 @@
#define USB_VERSION "1.0"
-static u8 user_rmmod;
static struct mwifiex_if_ops usb_ops;
static struct semaphore add_remove_card_sem;
+static struct usb_card_rec *usb_card;
static struct usb_device_id mwifiex_usb_table[] = {
/* 8797 */
@@ -532,38 +532,28 @@
static void mwifiex_usb_disconnect(struct usb_interface *intf)
{
struct usb_card_rec *card = usb_get_intfdata(intf);
- struct mwifiex_adapter *adapter;
- if (!card || !card->adapter) {
- pr_err("%s: card or card->adapter is NULL\n", __func__);
+ if (!card) {
+ pr_err("%s: card is NULL\n", __func__);
return;
}
- adapter = card->adapter;
- if (!adapter->priv_num)
- return;
-
- if (user_rmmod) {
-#ifdef CONFIG_PM
- if (adapter->is_suspended)
- mwifiex_usb_resume(intf);
-#endif
-
- mwifiex_deauthenticate_all(adapter);
-
- mwifiex_init_shutdown_fw(mwifiex_get_priv(adapter,
- MWIFIEX_BSS_ROLE_ANY),
- MWIFIEX_FUNC_SHUTDOWN);
- }
-
mwifiex_usb_free(card);
- dev_dbg(adapter->dev, "%s: removing card\n", __func__);
- mwifiex_remove_card(adapter, &add_remove_card_sem);
+ if (card->adapter) {
+ struct mwifiex_adapter *adapter = card->adapter;
+
+ if (!adapter->priv_num)
+ return;
+
+ dev_dbg(adapter->dev, "%s: removing card\n", __func__);
+ mwifiex_remove_card(adapter, &add_remove_card_sem);
+ }
usb_set_intfdata(intf, NULL);
usb_put_dev(interface_to_usbdev(intf));
kfree(card);
+ usb_card = NULL;
return;
}
@@ -575,7 +565,6 @@
.id_table = mwifiex_usb_table,
.suspend = mwifiex_usb_suspend,
.resume = mwifiex_usb_resume,
- .soft_unbind = 1,
};
static int mwifiex_usb_tx_init(struct mwifiex_adapter *adapter)
@@ -773,6 +762,7 @@
card->adapter = adapter;
adapter->dev = &card->udev->dev;
+ usb_card = card;
switch (le16_to_cpu(card->udev->descriptor.idProduct)) {
case USB8897_PID_1:
@@ -1035,8 +1025,25 @@
if (!down_interruptible(&add_remove_card_sem))
up(&add_remove_card_sem);
- /* set the flag as user is removing this module */
- user_rmmod = 1;
+ if (usb_card && usb_card->adapter) {
+ struct mwifiex_adapter *adapter = usb_card->adapter;
+
+ /* In case driver is removed when asynchronous FW downloading is
+ * in progress
+ */
+ wait_for_completion(&adapter->fw_load);
+
+#ifdef CONFIG_PM
+ if (adapter->is_suspended)
+ mwifiex_usb_resume(usb_card->intf);
+#endif
+
+ mwifiex_deauthenticate_all(adapter);
+
+ mwifiex_init_shutdown_fw(mwifiex_get_priv(adapter,
+ MWIFIEX_BSS_ROLE_ANY),
+ MWIFIEX_FUNC_SHUTDOWN);
+ }
usb_deregister(&mwifiex_usb_driver);
}
diff --git a/drivers/net/wireless/mwifiex/wmm.c b/drivers/net/wireless/mwifiex/wmm.c
index 94b6c74..0a7cc74 100644
--- a/drivers/net/wireless/mwifiex/wmm.c
+++ b/drivers/net/wireless/mwifiex/wmm.c
@@ -426,6 +426,15 @@
priv->tos_to_tid_inv[i];
}
+ priv->aggr_prio_tbl[6].amsdu
+ = priv->aggr_prio_tbl[6].ampdu_ap
+ = priv->aggr_prio_tbl[6].ampdu_user
+ = BA_STREAM_NOT_ALLOWED;
+
+ priv->aggr_prio_tbl[7].amsdu = priv->aggr_prio_tbl[7].ampdu_ap
+ = priv->aggr_prio_tbl[7].ampdu_user
+ = BA_STREAM_NOT_ALLOWED;
+
mwifiex_set_ba_params(priv);
mwifiex_reset_11n_rx_seq_num(priv);
diff --git a/drivers/net/wireless/rt2x00/rt2500pci.c b/drivers/net/wireless/rt2x00/rt2500pci.c
index 6fedefc..70a658a 100644
--- a/drivers/net/wireless/rt2x00/rt2500pci.c
+++ b/drivers/net/wireless/rt2x00/rt2500pci.c
@@ -1681,8 +1681,13 @@
/*
* Detect if this device has an hardware controlled radio.
*/
- if (rt2x00_get_field16(eeprom, EEPROM_ANTENNA_HARDWARE_RADIO))
+ if (rt2x00_get_field16(eeprom, EEPROM_ANTENNA_HARDWARE_RADIO)) {
__set_bit(CAPABILITY_HW_BUTTON, &rt2x00dev->cap_flags);
+ /*
+ * On this device RFKILL initialized during probe does not work.
+ */
+ __set_bit(REQUIRE_DELAYED_RFKILL, &rt2x00dev->cap_flags);
+ }
/*
* Check if the BBP tuning should be enabled.
diff --git a/drivers/net/wireless/rt2x00/rt2800lib.c b/drivers/net/wireless/rt2x00/rt2800lib.c
index 4437b0a..e6e1939 100644
--- a/drivers/net/wireless/rt2x00/rt2800lib.c
+++ b/drivers/net/wireless/rt2x00/rt2800lib.c
@@ -1005,9 +1005,10 @@
entry->skb->len + padding_len);
/*
- * Restore beaconing state.
+ * Enable beaconing again.
*/
- rt2800_register_write(rt2x00dev, BCN_TIME_CFG, orig_reg);
+ rt2x00_set_field32(®, BCN_TIME_CFG_BEACON_GEN, 1);
+ rt2800_register_write(rt2x00dev, BCN_TIME_CFG, reg);
/*
* Clean up beacon skb.
@@ -1038,14 +1039,13 @@
void rt2800_clear_beacon(struct queue_entry *entry)
{
struct rt2x00_dev *rt2x00dev = entry->queue->rt2x00dev;
- u32 orig_reg, reg;
+ u32 reg;
/*
* Disable beaconing while we are reloading the beacon data,
* otherwise we might be sending out invalid data.
*/
- rt2800_register_read(rt2x00dev, BCN_TIME_CFG, &orig_reg);
- reg = orig_reg;
+ rt2800_register_read(rt2x00dev, BCN_TIME_CFG, ®);
rt2x00_set_field32(®, BCN_TIME_CFG_BEACON_GEN, 0);
rt2800_register_write(rt2x00dev, BCN_TIME_CFG, reg);
@@ -1055,9 +1055,10 @@
rt2800_clear_beacon_register(rt2x00dev, entry->entry_idx);
/*
- * Restore beaconing state.
+ * Enabled beaconing again.
*/
- rt2800_register_write(rt2x00dev, BCN_TIME_CFG, orig_reg);
+ rt2x00_set_field32(®, BCN_TIME_CFG_BEACON_GEN, 1);
+ rt2800_register_write(rt2x00dev, BCN_TIME_CFG, reg);
}
EXPORT_SYMBOL_GPL(rt2800_clear_beacon);
diff --git a/drivers/net/wireless/rt2x00/rt2x00.h b/drivers/net/wireless/rt2x00/rt2x00.h
index a38c736..dee5022 100644
--- a/drivers/net/wireless/rt2x00/rt2x00.h
+++ b/drivers/net/wireless/rt2x00/rt2x00.h
@@ -693,6 +693,7 @@
REQUIRE_SW_SEQNO,
REQUIRE_HT_TX_DESC,
REQUIRE_PS_AUTOWAKE,
+ REQUIRE_DELAYED_RFKILL,
/*
* Capabilities
diff --git a/drivers/net/wireless/rt2x00/rt2x00dev.c b/drivers/net/wireless/rt2x00/rt2x00dev.c
index c3b67c7..42072d8 100644
--- a/drivers/net/wireless/rt2x00/rt2x00dev.c
+++ b/drivers/net/wireless/rt2x00/rt2x00dev.c
@@ -1126,9 +1126,10 @@
return;
/*
- * Unregister extra components.
+ * Stop rfkill polling.
*/
- rt2x00rfkill_unregister(rt2x00dev);
+ if (test_bit(REQUIRE_DELAYED_RFKILL, &rt2x00dev->cap_flags))
+ rt2x00rfkill_unregister(rt2x00dev);
/*
* Allow the HW to uninitialize.
@@ -1166,6 +1167,12 @@
set_bit(DEVICE_STATE_INITIALIZED, &rt2x00dev->flags);
+ /*
+ * Start rfkill polling.
+ */
+ if (test_bit(REQUIRE_DELAYED_RFKILL, &rt2x00dev->cap_flags))
+ rt2x00rfkill_register(rt2x00dev);
+
return 0;
}
@@ -1375,7 +1382,12 @@
rt2x00link_register(rt2x00dev);
rt2x00leds_register(rt2x00dev);
rt2x00debug_register(rt2x00dev);
- rt2x00rfkill_register(rt2x00dev);
+
+ /*
+ * Start rfkill polling.
+ */
+ if (!test_bit(REQUIRE_DELAYED_RFKILL, &rt2x00dev->cap_flags))
+ rt2x00rfkill_register(rt2x00dev);
return 0;
@@ -1391,6 +1403,12 @@
clear_bit(DEVICE_STATE_PRESENT, &rt2x00dev->flags);
/*
+ * Stop rfkill polling.
+ */
+ if (!test_bit(REQUIRE_DELAYED_RFKILL, &rt2x00dev->cap_flags))
+ rt2x00rfkill_unregister(rt2x00dev);
+
+ /*
* Disable radio.
*/
rt2x00lib_disable_radio(rt2x00dev);
diff --git a/drivers/net/wireless/rt2x00/rt2x00mac.c b/drivers/net/wireless/rt2x00/rt2x00mac.c
index 74b9c41..42dd72c 100644
--- a/drivers/net/wireless/rt2x00/rt2x00mac.c
+++ b/drivers/net/wireless/rt2x00/rt2x00mac.c
@@ -487,6 +487,8 @@
crypto.cipher = rt2x00crypto_key_to_cipher(key);
if (crypto.cipher == CIPHER_NONE)
return -EOPNOTSUPP;
+ if (crypto.cipher == CIPHER_TKIP && rt2x00_is_usb(rt2x00dev))
+ return -EOPNOTSUPP;
crypto.cmd = cmd;
@@ -621,20 +623,18 @@
bss_conf->bssid);
/*
- * Update the beacon. This is only required on USB devices. PCI
- * devices fetch beacons periodically.
- */
- if (changes & BSS_CHANGED_BEACON && rt2x00_is_usb(rt2x00dev))
- rt2x00queue_update_beacon(rt2x00dev, vif);
-
- /*
* Start/stop beaconing.
*/
if (changes & BSS_CHANGED_BEACON_ENABLED) {
if (!bss_conf->enable_beacon && intf->enable_beacon) {
- rt2x00queue_clear_beacon(rt2x00dev, vif);
rt2x00dev->intf_beaconing--;
intf->enable_beacon = false;
+ /*
+ * Clear beacon in the H/W for this vif. This is needed
+ * to disable beaconing on this particular interface
+ * and keep it running on other interfaces.
+ */
+ rt2x00queue_clear_beacon(rt2x00dev, vif);
if (rt2x00dev->intf_beaconing == 0) {
/*
@@ -645,11 +645,15 @@
rt2x00queue_stop_queue(rt2x00dev->bcn);
mutex_unlock(&intf->beacon_skb_mutex);
}
-
-
} else if (bss_conf->enable_beacon && !intf->enable_beacon) {
rt2x00dev->intf_beaconing++;
intf->enable_beacon = true;
+ /*
+ * Upload beacon to the H/W. This is only required on
+ * USB devices. PCI devices fetch beacons periodically.
+ */
+ if (rt2x00_is_usb(rt2x00dev))
+ rt2x00queue_update_beacon(rt2x00dev, vif);
if (rt2x00dev->intf_beaconing == 1) {
/*
diff --git a/drivers/net/wireless/rt2x00/rt61pci.c b/drivers/net/wireless/rt2x00/rt61pci.c
index e4c2580..b61f86f 100644
--- a/drivers/net/wireless/rt2x00/rt61pci.c
+++ b/drivers/net/wireless/rt2x00/rt61pci.c
@@ -2031,14 +2031,13 @@
static void rt61pci_clear_beacon(struct queue_entry *entry)
{
struct rt2x00_dev *rt2x00dev = entry->queue->rt2x00dev;
- u32 orig_reg, reg;
+ u32 reg;
/*
* Disable beaconing while we are reloading the beacon data,
* otherwise we might be sending out invalid data.
*/
- rt2x00mmio_register_read(rt2x00dev, TXRX_CSR9, &orig_reg);
- reg = orig_reg;
+ rt2x00mmio_register_read(rt2x00dev, TXRX_CSR9, ®);
rt2x00_set_field32(®, TXRX_CSR9_BEACON_GEN, 0);
rt2x00mmio_register_write(rt2x00dev, TXRX_CSR9, reg);
@@ -2049,9 +2048,10 @@
HW_BEACON_OFFSET(entry->entry_idx), 0);
/*
- * Restore global beaconing state.
+ * Enable beaconing again.
*/
- rt2x00mmio_register_write(rt2x00dev, TXRX_CSR9, orig_reg);
+ rt2x00_set_field32(®, TXRX_CSR9_BEACON_GEN, 1);
+ rt2x00mmio_register_write(rt2x00dev, TXRX_CSR9, reg);
}
/*
diff --git a/drivers/net/wireless/rt2x00/rt73usb.c b/drivers/net/wireless/rt2x00/rt73usb.c
index 80d48e9..c3d02c4 100644
--- a/drivers/net/wireless/rt2x00/rt73usb.c
+++ b/drivers/net/wireless/rt2x00/rt73usb.c
@@ -1597,14 +1597,13 @@
{
struct rt2x00_dev *rt2x00dev = entry->queue->rt2x00dev;
unsigned int beacon_base;
- u32 orig_reg, reg;
+ u32 reg;
/*
* Disable beaconing while we are reloading the beacon data,
* otherwise we might be sending out invalid data.
*/
- rt2x00usb_register_read(rt2x00dev, TXRX_CSR9, &orig_reg);
- reg = orig_reg;
+ rt2x00usb_register_read(rt2x00dev, TXRX_CSR9, ®);
rt2x00_set_field32(®, TXRX_CSR9_BEACON_GEN, 0);
rt2x00usb_register_write(rt2x00dev, TXRX_CSR9, reg);
@@ -1615,9 +1614,10 @@
rt2x00usb_register_write(rt2x00dev, beacon_base, 0);
/*
- * Restore beaconing state.
+ * Enable beaconing again.
*/
- rt2x00usb_register_write(rt2x00dev, TXRX_CSR9, orig_reg);
+ rt2x00_set_field32(®, TXRX_CSR9_BEACON_GEN, 1);
+ rt2x00usb_register_write(rt2x00dev, TXRX_CSR9, reg);
}
static int rt73usb_get_tx_data_len(struct queue_entry *entry)
diff --git a/drivers/net/wireless/rtl818x/rtl8180/Makefile b/drivers/net/wireless/rtl818x/rtl8180/Makefile
index 487a40a..b3441ea 100644
--- a/drivers/net/wireless/rtl818x/rtl8180/Makefile
+++ b/drivers/net/wireless/rtl818x/rtl8180/Makefile
@@ -1,5 +1,5 @@
-rtl818x_pci-objs := dev.o rtl8225.o sa2400.o max2820.o grf5101.o rtl8225se.o
+rtl8180-objs := dev.o rtl8225.o sa2400.o max2820.o grf5101.o rtl8225se.o
-obj-$(CPTCFG_RTL8180) += rtl818x_pci.o
+obj-$(CPTCFG_RTL8180) += rtl8180.o
ccflags-y += -I$(backport_srctree)/drivers/net/wireless/rtl818x
diff --git a/drivers/net/wireless/rtl818x/rtl8180/dev.c b/drivers/net/wireless/rtl818x/rtl8180/dev.c
index 50d69b1..98d8256 100644
--- a/drivers/net/wireless/rtl818x/rtl8180/dev.c
+++ b/drivers/net/wireless/rtl818x/rtl8180/dev.c
@@ -683,8 +683,9 @@
struct rtl8180_priv *priv = dev->priv;
if (priv->chip_family == RTL818X_CHIP_FAMILY_RTL8187SE) {
- rtl818x_iowrite32(priv, &priv->map->IMR,
- IMR_TBDER | IMR_TBDOK |
+ rtl818x_iowrite32(priv, &priv->map->IMR, IMR_TMGDOK |
+ IMR_TBDER | IMR_THPDER |
+ IMR_THPDER | IMR_THPDOK |
IMR_TVODER | IMR_TVODOK |
IMR_TVIDER | IMR_TVIDOK |
IMR_TBEDER | IMR_TBEDOK |
@@ -910,10 +911,7 @@
reg32 &= 0x00ffff00;
reg32 |= 0xb8000054;
rtl818x_iowrite32(priv, &priv->map->RF_PARA, reg32);
- } else
- /* stop unused queus (no dma alloc) */
- rtl818x_iowrite8(priv, &priv->map->TX_DMA_POLLING,
- (1<<1) | (1<<2));
+ }
priv->rf->init(dev);
diff --git a/drivers/net/wireless/rtl818x/rtl818x.h b/drivers/net/wireless/rtl818x/rtl818x.h
index 7abef95..45ea4e1 100644
--- a/drivers/net/wireless/rtl818x/rtl818x.h
+++ b/drivers/net/wireless/rtl818x/rtl818x.h
@@ -334,9 +334,9 @@
* I don't like to introduce a ton of "reserved"..
* They are for RTL8187SE
*/
-#define REG_ADDR1(addr) ((u8 __iomem *)priv->map + (addr))
-#define REG_ADDR2(addr) ((__le16 __iomem *)priv->map + ((addr) >> 1))
-#define REG_ADDR4(addr) ((__le32 __iomem *)priv->map + ((addr) >> 2))
+#define REG_ADDR1(addr) ((u8 __iomem *)priv->map + addr)
+#define REG_ADDR2(addr) ((__le16 __iomem *)priv->map + (addr >> 1))
+#define REG_ADDR4(addr) ((__le32 __iomem *)priv->map + (addr >> 2))
#define FEMR_SE REG_ADDR2(0x1D4)
#define ARFR REG_ADDR2(0x1E0)
diff --git a/drivers/net/wireless/rtlwifi/rtl8188ee/trx.c b/drivers/net/wireless/rtlwifi/rtl8188ee/trx.c
index 06ef47c..5b4c225 100644
--- a/drivers/net/wireless/rtlwifi/rtl8188ee/trx.c
+++ b/drivers/net/wireless/rtlwifi/rtl8188ee/trx.c
@@ -293,7 +293,7 @@
u8 *psaddr;
__le16 fc;
u16 type, ufc;
- bool match_bssid, packet_toself, packet_beacon, addr;
+ bool match_bssid, packet_toself, packet_beacon = false, addr;
tmp_buf = skb->data + pstatus->rx_drvinfo_size + pstatus->rx_bufshift;
diff --git a/drivers/net/wireless/rtlwifi/rtl8192cu/hw.c b/drivers/net/wireless/rtlwifi/rtl8192cu/hw.c
index 68b5c7e..07cb06d 100644
--- a/drivers/net/wireless/rtlwifi/rtl8192cu/hw.c
+++ b/drivers/net/wireless/rtlwifi/rtl8192cu/hw.c
@@ -1001,7 +1001,7 @@
err = _rtl92cu_init_mac(hw);
if (err) {
RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, "init mac failed!\n");
- return err;
+ goto exit;
}
err = rtl92c_download_fw(hw);
if (err) {
diff --git a/drivers/net/wireless/rtlwifi/rtl8192se/trx.c b/drivers/net/wireless/rtlwifi/rtl8192se/trx.c
index 36b48be..2b3c78b 100644
--- a/drivers/net/wireless/rtlwifi/rtl8192se/trx.c
+++ b/drivers/net/wireless/rtlwifi/rtl8192se/trx.c
@@ -49,6 +49,12 @@
if (ieee80211_is_nullfunc(fc))
return QSLT_HIGH;
+ /* Kernel commit 1bf4bbb4024dcdab changed EAPOL packets to use
+ * queue V0 at priority 7; however, the RTL8192SE appears to have
+ * that queue at priority 6
+ */
+ if (skb->priority == 7)
+ return QSLT_VO;
return skb->priority;
}
diff --git a/drivers/regulator/core.c b/drivers/regulator/core.c
index bee732d..3e40b5f 100644
--- a/drivers/regulator/core.c
+++ b/drivers/regulator/core.c
@@ -3792,9 +3792,7 @@
{
int ret;
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,11,0)
init_regulator_dev_attrs();
-#endif
ret = class_register(®ulator_class);
debugfs_root = debugfs_create_dir("regulator", NULL);
diff --git a/drivers/regulator/pbias-regulator.c b/drivers/regulator/pbias-regulator.c
index ded3b35..6d38be3 100644
--- a/drivers/regulator/pbias-regulator.c
+++ b/drivers/regulator/pbias-regulator.c
@@ -38,66 +38,24 @@
struct pbias_regulator_data {
struct regulator_desc desc;
void __iomem *pbias_addr;
- unsigned int pbias_reg;
struct regulator_dev *dev;
struct regmap *syscon;
const struct pbias_reg_info *info;
int voltage;
};
-static int pbias_regulator_set_voltage(struct regulator_dev *dev,
- int min_uV, int max_uV, unsigned *selector)
-{
- struct pbias_regulator_data *data = rdev_get_drvdata(dev);
- const struct pbias_reg_info *info = data->info;
- int ret, vmode;
-
- if (min_uV <= 1800000)
- vmode = 0;
- else if (min_uV > 1800000)
- vmode = info->vmode;
-
- ret = regmap_update_bits(data->syscon, data->pbias_reg,
- info->vmode, vmode);
-
- return ret;
-}
-
-static int pbias_regulator_get_voltage(struct regulator_dev *rdev)
-{
- struct pbias_regulator_data *data = rdev_get_drvdata(rdev);
- const struct pbias_reg_info *info = data->info;
- int value, voltage;
-
- regmap_read(data->syscon, data->pbias_reg, &value);
- value &= info->vmode;
-
- voltage = value ? 3000000 : 1800000;
-
- return voltage;
-}
+static const unsigned int pbias_volt_table[] = {
+ 1800000,
+ 3000000
+};
static int pbias_regulator_enable(struct regulator_dev *rdev)
{
struct pbias_regulator_data *data = rdev_get_drvdata(rdev);
const struct pbias_reg_info *info = data->info;
- int ret;
- ret = regmap_update_bits(data->syscon, data->pbias_reg,
- info->enable_mask, info->enable);
-
- return ret;
-}
-
-static int pbias_regulator_disable(struct regulator_dev *rdev)
-{
- struct pbias_regulator_data *data = rdev_get_drvdata(rdev);
- const struct pbias_reg_info *info = data->info;
- int ret;
-
- ret = regmap_update_bits(data->syscon, data->pbias_reg,
- info->enable_mask, 0);
- return ret;
+ return regmap_update_bits(data->syscon, rdev->desc->enable_reg,
+ info->enable_mask, info->enable);
}
static int pbias_regulator_is_enable(struct regulator_dev *rdev)
@@ -106,17 +64,18 @@
const struct pbias_reg_info *info = data->info;
int value;
- regmap_read(data->syscon, data->pbias_reg, &value);
+ regmap_read(data->syscon, rdev->desc->enable_reg, &value);
- return (value & info->enable_mask) == info->enable_mask;
+ return (value & info->enable_mask) == info->enable;
}
static struct regulator_ops pbias_regulator_voltage_ops = {
- .set_voltage = pbias_regulator_set_voltage,
- .get_voltage = pbias_regulator_get_voltage,
- .enable = pbias_regulator_enable,
- .disable = pbias_regulator_disable,
- .is_enabled = pbias_regulator_is_enable,
+ .list_voltage = regulator_list_voltage_table,
+ .get_voltage_sel = regulator_get_voltage_sel_regmap,
+ .set_voltage_sel = regulator_set_voltage_sel_regmap,
+ .enable = pbias_regulator_enable,
+ .disable = regulator_disable_regmap,
+ .is_enabled = pbias_regulator_is_enable,
};
static const struct pbias_reg_info pbias_mmc_omap2430 = {
@@ -192,6 +151,7 @@
if (IS_ERR(syscon))
return PTR_ERR(syscon);
+ cfg.regmap = syscon;
cfg.dev = &pdev->dev;
for (idx = 0; idx < PBIAS_NUM_REGS && data_idx < count; idx++) {
@@ -207,15 +167,19 @@
if (!res)
return -EINVAL;
- drvdata[data_idx].pbias_reg = res->start;
drvdata[data_idx].syscon = syscon;
drvdata[data_idx].info = info;
drvdata[data_idx].desc.name = info->name;
drvdata[data_idx].desc.owner = THIS_MODULE;
drvdata[data_idx].desc.type = REGULATOR_VOLTAGE;
drvdata[data_idx].desc.ops = &pbias_regulator_voltage_ops;
+ drvdata[data_idx].desc.volt_table = pbias_volt_table;
drvdata[data_idx].desc.n_voltages = 2;
drvdata[data_idx].desc.enable_time = info->enable_time;
+ drvdata[data_idx].desc.vsel_reg = res->start;
+ drvdata[data_idx].desc.vsel_mask = info->vmode;
+ drvdata[data_idx].desc.enable_reg = res->start;
+ drvdata[data_idx].desc.enable_mask = info->enable_mask;
cfg.init_data = pbias_matches[idx].init_data;
cfg.driver_data = &drvdata[data_idx];
diff --git a/drivers/regulator/s2mpa01.c b/drivers/regulator/s2mpa01.c
index f19a30f..fdd68dd 100644
--- a/drivers/regulator/s2mpa01.c
+++ b/drivers/regulator/s2mpa01.c
@@ -116,7 +116,6 @@
ramp_delay = s2mpa01->ramp_delay16;
ramp_shift = S2MPA01_BUCK16_RAMP_SHIFT;
- ramp_reg = S2MPA01_REG_RAMP1;
break;
case S2MPA01_BUCK2:
enable_shift = S2MPA01_BUCK2_RAMP_EN_SHIFT;
@@ -192,11 +191,15 @@
if (!ramp_enable)
goto ramp_disable;
- ret = regmap_update_bits(rdev->regmap, S2MPA01_REG_RAMP1,
- 1 << enable_shift, 1 << enable_shift);
- if (ret) {
- dev_err(&rdev->dev, "failed to enable ramp rate\n");
- return ret;
+ /* Ramp delay can be enabled/disabled only for buck[1234] */
+ if (rdev_get_id(rdev) >= S2MPA01_BUCK1 &&
+ rdev_get_id(rdev) <= S2MPA01_BUCK4) {
+ ret = regmap_update_bits(rdev->regmap, S2MPA01_REG_RAMP1,
+ 1 << enable_shift, 1 << enable_shift);
+ if (ret) {
+ dev_err(&rdev->dev, "failed to enable ramp rate\n");
+ return ret;
+ }
}
ramp_val = get_ramp_delay(ramp_delay);
diff --git a/drivers/regulator/s2mps11.c b/drivers/regulator/s2mps11.c
index e713c16..aaca37e 100644
--- a/drivers/regulator/s2mps11.c
+++ b/drivers/regulator/s2mps11.c
@@ -202,11 +202,16 @@
if (!ramp_enable)
goto ramp_disable;
- ret = regmap_update_bits(rdev->regmap, S2MPS11_REG_RAMP,
- 1 << enable_shift, 1 << enable_shift);
- if (ret) {
- dev_err(&rdev->dev, "failed to enable ramp rate\n");
- return ret;
+ /* Ramp delay can be enabled/disabled only for buck[2346] */
+ if ((rdev_get_id(rdev) >= S2MPS11_BUCK2 &&
+ rdev_get_id(rdev) <= S2MPS11_BUCK4) ||
+ rdev_get_id(rdev) == S2MPS11_BUCK6) {
+ ret = regmap_update_bits(rdev->regmap, S2MPS11_REG_RAMP,
+ 1 << enable_shift, 1 << enable_shift);
+ if (ret) {
+ dev_err(&rdev->dev, "failed to enable ramp rate\n");
+ return ret;
+ }
}
ramp_val = get_ramp_delay(ramp_delay);
diff --git a/drivers/regulator/tps65218-regulator.c b/drivers/regulator/tps65218-regulator.c
index cec72fa..676e3fb 100644
--- a/drivers/regulator/tps65218-regulator.c
+++ b/drivers/regulator/tps65218-regulator.c
@@ -226,7 +226,7 @@
1, -1, -1, TPS65218_REG_ENABLE1,
TPS65218_ENABLE1_DC6_EN, NULL, NULL, 0),
TPS65218_REGULATOR("LDO1", TPS65218_LDO_1, tps65218_ldo1_dcdc34_ops, 64,
- TPS65218_REG_CONTROL_DCDC4,
+ TPS65218_REG_CONTROL_LDO1,
TPS65218_CONTROL_LDO1_MASK, TPS65218_REG_ENABLE2,
TPS65218_ENABLE2_LDO1_EN, NULL, ldo1_dcdc3_ranges,
2),
@@ -257,6 +257,7 @@
config.init_data = init_data;
config.driver_data = tps;
config.regmap = tps->regmap;
+ config.of_node = pdev->dev.of_node;
rdev = devm_regulator_register(&pdev->dev, ®ulators[id], &config);
if (IS_ERR(rdev)) {
diff --git a/drivers/ssb/main.c b/drivers/ssb/main.c
index 1f45f2b..bec5e83 100644
--- a/drivers/ssb/main.c
+++ b/drivers/ssb/main.c
@@ -1470,9 +1470,7 @@
/* See the comment at the ssb_is_early_boot definition */
ssb_is_early_boot = 0;
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,12,0)
init_ssb_device_attrs();
-#endif
err = bus_register(&ssb_bustype);
if (err)
return err;
diff --git a/include/net/bluetooth/mgmt.h b/include/net/bluetooth/mgmt.h
index d4b571c..b0b381b 100644
--- a/include/net/bluetooth/mgmt.h
+++ b/include/net/bluetooth/mgmt.h
@@ -181,6 +181,9 @@
} __packed;
#define MGMT_LOAD_LINK_KEYS_SIZE 3
+#define MGMT_LTK_UNAUTHENTICATED 0x00
+#define MGMT_LTK_AUTHENTICATED 0x01
+
struct mgmt_ltk_info {
struct mgmt_addr_info addr;
__u8 type;
diff --git a/include/net/cfg80211.h b/include/net/cfg80211.h
index a9f1c0c..4a2868a 100644
--- a/include/net/cfg80211.h
+++ b/include/net/cfg80211.h
@@ -3672,6 +3672,18 @@
void cfg80211_sched_scan_stopped(struct wiphy *wiphy);
/**
+ * cfg80211_sched_scan_stopped_rtnl - notify that the scheduled scan has stopped
+ *
+ * @wiphy: the wiphy on which the scheduled scan stopped
+ *
+ * The driver can call this function to inform cfg80211 that the
+ * scheduled scan had to be stopped, for whatever reason. The driver
+ * is then called back via the sched_scan_stop operation when done.
+ * This function should be called with rtnl locked.
+ */
+void cfg80211_sched_scan_stopped_rtnl(struct wiphy *wiphy);
+
+/**
* cfg80211_inform_bss_width_frame - inform cfg80211 of a received BSS frame
*
* @wiphy: the wiphy reporting the BSS
diff --git a/include/uapi/linux/nl80211.h b/include/uapi/linux/nl80211.h
index 1ba9d62..194c1ea 100644
--- a/include/uapi/linux/nl80211.h
+++ b/include/uapi/linux/nl80211.h
@@ -3856,6 +3856,8 @@
* @NL80211_FEATURE_CELL_BASE_REG_HINTS: This driver has been tested
* to work properly to suppport receiving regulatory hints from
* cellular base stations.
+ * @NL80211_FEATURE_P2P_DEVICE_NEEDS_CHANNEL: (no longer available, only
+ * here to reserve the value for API/ABI compatibility)
* @NL80211_FEATURE_SAE: This driver supports simultaneous authentication of
* equals (SAE) with user space SME (NL80211_CMD_AUTHENTICATE) in station
* mode
@@ -3897,7 +3899,7 @@
NL80211_FEATURE_HT_IBSS = 1 << 1,
NL80211_FEATURE_INACTIVITY_TIMER = 1 << 2,
NL80211_FEATURE_CELL_BASE_REG_HINTS = 1 << 3,
- /* bit 4 is reserved - don't use */
+ NL80211_FEATURE_P2P_DEVICE_NEEDS_CHANNEL = 1 << 4,
NL80211_FEATURE_SAE = 1 << 5,
NL80211_FEATURE_LOW_PRIORITY_SCAN = 1 << 6,
NL80211_FEATURE_SCAN_FLUSH = 1 << 7,
diff --git a/include/uapi/linux/usb/cdc-wdm.h b/include/uapi/linux/usb/cdc-wdm.h
index f03134f..0dc132e 100644
--- a/include/uapi/linux/usb/cdc-wdm.h
+++ b/include/uapi/linux/usb/cdc-wdm.h
@@ -9,6 +9,8 @@
#ifndef _UAPI__LINUX_USB_CDC_WDM_H
#define _UAPI__LINUX_USB_CDC_WDM_H
+#include <linux/types.h>
+
/*
* This IOCTL is used to retrieve the wMaxCommand for the device,
* defining the message limit for both reading and writing.
diff --git a/net/bluetooth/6lowpan.c b/net/bluetooth/6lowpan.c
index 73492b9..8796ffa 100644
--- a/net/bluetooth/6lowpan.c
+++ b/net/bluetooth/6lowpan.c
@@ -420,12 +420,18 @@
return 0;
}
-static void get_dest_bdaddr(struct in6_addr *ip6_daddr,
- bdaddr_t *addr, u8 *addr_type)
+static u8 get_addr_type_from_eui64(u8 byte)
{
- u8 *eui64;
+ /* Is universal(0) or local(1) bit, */
+ if (byte & 0x02)
+ return ADDR_LE_DEV_RANDOM;
- eui64 = ip6_daddr->s6_addr + 8;
+ return ADDR_LE_DEV_PUBLIC;
+}
+
+static void copy_to_bdaddr(struct in6_addr *ip6_daddr, bdaddr_t *addr)
+{
+ u8 *eui64 = ip6_daddr->s6_addr + 8;
addr->b[0] = eui64[7];
addr->b[1] = eui64[6];
@@ -433,16 +439,19 @@
addr->b[3] = eui64[2];
addr->b[4] = eui64[1];
addr->b[5] = eui64[0];
+}
- addr->b[5] ^= 2;
+static void convert_dest_bdaddr(struct in6_addr *ip6_daddr,
+ bdaddr_t *addr, u8 *addr_type)
+{
+ copy_to_bdaddr(ip6_daddr, addr);
- /* Set universal/local bit to 0 */
- if (addr->b[5] & 1) {
- addr->b[5] &= ~1;
- *addr_type = ADDR_LE_DEV_PUBLIC;
- } else {
- *addr_type = ADDR_LE_DEV_RANDOM;
- }
+ /* We need to toggle the U/L bit that we got from IPv6 address
+ * so that we get the proper address and type of the BD address.
+ */
+ addr->b[5] ^= 0x02;
+
+ *addr_type = get_addr_type_from_eui64(addr->b[5]);
}
static int header_create(struct sk_buff *skb, struct net_device *netdev,
@@ -473,9 +482,11 @@
/* Get destination BT device from skb.
* If there is no such peer then discard the packet.
*/
- get_dest_bdaddr(&hdr->daddr, &addr, &addr_type);
+ convert_dest_bdaddr(&hdr->daddr, &addr, &addr_type);
- BT_DBG("dest addr %pMR type %d", &addr, addr_type);
+ BT_DBG("dest addr %pMR type %s IP %pI6c", &addr,
+ addr_type == ADDR_LE_DEV_PUBLIC ? "PUBLIC" : "RANDOM",
+ &hdr->daddr);
read_lock_irqsave(&devices_lock, flags);
peer = peer_lookup_ba(dev, &addr, addr_type);
@@ -556,7 +567,7 @@
} else {
unsigned long flags;
- get_dest_bdaddr(&lowpan_cb(skb)->addr, &addr, &addr_type);
+ convert_dest_bdaddr(&lowpan_cb(skb)->addr, &addr, &addr_type);
eui64_addr = lowpan_cb(skb)->addr.s6_addr + 8;
dev = lowpan_dev(netdev);
@@ -564,8 +575,10 @@
peer = peer_lookup_ba(dev, &addr, addr_type);
read_unlock_irqrestore(&devices_lock, flags);
- BT_DBG("xmit from %s to %pMR (%pI6c) peer %p", netdev->name,
- &addr, &lowpan_cb(skb)->addr, peer);
+ BT_DBG("xmit %s to %pMR type %s IP %pI6c peer %p",
+ netdev->name, &addr,
+ addr_type == ADDR_LE_DEV_PUBLIC ? "PUBLIC" : "RANDOM",
+ &lowpan_cb(skb)->addr, peer);
if (peer && peer->conn)
err = send_pkt(peer->conn, netdev->dev_addr,
@@ -620,13 +633,13 @@
eui[6] = addr[1];
eui[7] = addr[0];
- eui[0] ^= 2;
-
- /* Universal/local bit set, RFC 4291 */
+ /* Universal/local bit set, BT 6lowpan draft ch. 3.2.1 */
if (addr_type == ADDR_LE_DEV_PUBLIC)
- eui[0] |= 1;
+ eui[0] &= ~0x02;
else
- eui[0] &= ~1;
+ eui[0] |= 0x02;
+
+ BT_DBG("type %d addr %*phC", addr_type, 8, eui);
}
static void set_dev_addr(struct net_device *netdev, bdaddr_t *addr,
@@ -634,7 +647,6 @@
{
netdev->addr_assign_type = NET_ADDR_PERM;
set_addr(netdev->dev_addr, addr->b, addr_type);
- netdev->dev_addr[0] ^= 2;
}
static void ifup(struct net_device *netdev)
@@ -684,13 +696,6 @@
memcpy(&peer->eui64_addr, (u8 *)&peer->peer_addr.s6_addr + 8,
EUI64_ADDR_LEN);
- peer->eui64_addr[0] ^= 2; /* second bit-flip (Universe/Local)
- * is done according RFC2464
- */
-
- raw_dump_inline(__func__, "peer IPv6 address",
- (unsigned char *)&peer->peer_addr, 16);
- raw_dump_inline(__func__, "peer EUI64 address", peer->eui64_addr, 8);
write_lock_irqsave(&devices_lock, flags);
INIT_LIST_HEAD(&peer->list);
diff --git a/net/bluetooth/hci_conn.c b/net/bluetooth/hci_conn.c
index d958e2d..ea72cc0 100644
--- a/net/bluetooth/hci_conn.c
+++ b/net/bluetooth/hci_conn.c
@@ -584,11 +584,6 @@
if (hci_update_random_address(req, false, &own_addr_type))
return;
- /* Save the address type used for this connnection attempt so we able
- * to retrieve this information if we need it.
- */
- conn->src_type = own_addr_type;
-
cp.scan_interval = cpu_to_le16(hdev->le_scan_interval);
cp.scan_window = cpu_to_le16(hdev->le_scan_window);
bacpy(&cp.peer_addr, &conn->dst);
@@ -819,14 +814,17 @@
if (!test_and_set_bit(HCI_CONN_AUTH_PEND, &conn->flags)) {
struct hci_cp_auth_requested cp;
- /* encrypt must be pending if auth is also pending */
- set_bit(HCI_CONN_ENCRYPT_PEND, &conn->flags);
-
cp.handle = cpu_to_le16(conn->handle);
hci_send_cmd(conn->hdev, HCI_OP_AUTH_REQUESTED,
sizeof(cp), &cp);
- if (conn->key_type != 0xff)
+
+ /* If we're already encrypted set the REAUTH_PEND flag,
+ * otherwise set the ENCRYPT_PEND.
+ */
+ if (conn->link_mode & HCI_LM_ENCRYPT)
set_bit(HCI_CONN_REAUTH_PEND, &conn->flags);
+ else
+ set_bit(HCI_CONN_ENCRYPT_PEND, &conn->flags);
}
return 0;
diff --git a/net/bluetooth/hci_event.c b/net/bluetooth/hci_event.c
index 4977491..40357c8 100644
--- a/net/bluetooth/hci_event.c
+++ b/net/bluetooth/hci_event.c
@@ -48,6 +48,10 @@
smp_mb__after_clear_bit(); /* wake_up_bit advises about this barrier */
wake_up_bit(&hdev->flags, HCI_INQUIRY);
+ hci_dev_lock(hdev);
+ hci_discovery_set_state(hdev, DISCOVERY_STOPPED);
+ hci_dev_unlock(hdev);
+
hci_conn_check_pending(hdev);
}
@@ -1342,6 +1346,7 @@
* is requested.
*/
if (!hci_conn_ssp_enabled(conn) && !(conn->auth_type & 0x01) &&
+ conn->pending_sec_level != BT_SECURITY_FIPS &&
conn->pending_sec_level != BT_SECURITY_HIGH &&
conn->pending_sec_level != BT_SECURITY_MEDIUM)
return 0;
@@ -2957,7 +2962,8 @@
}
if (key->type == HCI_LK_COMBINATION && key->pin_len < 16 &&
- conn->pending_sec_level == BT_SECURITY_HIGH) {
+ (conn->pending_sec_level == BT_SECURITY_HIGH ||
+ conn->pending_sec_level == BT_SECURITY_FIPS)) {
BT_DBG("%s ignoring key unauthenticated for high security",
hdev->name);
goto not_found;
@@ -3330,6 +3336,12 @@
if (!conn)
goto unlock;
+ /* For BR/EDR the necessary steps are taken through the
+ * auth_complete event.
+ */
+ if (conn->type != LE_LINK)
+ goto unlock;
+
if (!ev->status)
conn->sec_level = conn->pending_sec_level;
@@ -3495,8 +3507,11 @@
/* If we're not the initiators request authorization to
* proceed from user space (mgmt_user_confirm with
- * confirm_hint set to 1). */
- if (!test_bit(HCI_CONN_AUTH_PEND, &conn->flags)) {
+ * confirm_hint set to 1). The exception is if neither
+ * side had MITM in which case we do auto-accept.
+ */
+ if (!test_bit(HCI_CONN_AUTH_PEND, &conn->flags) &&
+ (loc_mitm || rem_mitm)) {
BT_DBG("Confirming auto-accept as acceptor");
confirm_hint = 1;
goto confirm;
diff --git a/net/bluetooth/l2cap_core.c b/net/bluetooth/l2cap_core.c
index a1e5bb7..1c97b7a 100644
--- a/net/bluetooth/l2cap_core.c
+++ b/net/bluetooth/l2cap_core.c
@@ -1657,7 +1657,13 @@
kfree_skb(conn->rx_skb);
skb_queue_purge(&conn->pending_rx);
- flush_work(&conn->pending_rx_work);
+
+ /* We can not call flush_work(&conn->pending_rx_work) here since we
+ * might block if we are running on a worker from the same workqueue
+ * pending_rx_work is waiting on.
+ */
+ if (work_pending(&conn->pending_rx_work))
+ cancel_work_sync(&conn->pending_rx_work);
l2cap_unregister_all_users(conn);
@@ -7519,9 +7525,9 @@
l2cap_debugfs = debugfs_create_file("l2cap", 0444, bt_debugfs,
NULL, &l2cap_debugfs_fops);
- debugfs_create_u16("l2cap_le_max_credits", 0466, bt_debugfs,
+ debugfs_create_u16("l2cap_le_max_credits", 0644, bt_debugfs,
&le_max_credits);
- debugfs_create_u16("l2cap_le_default_mps", 0466, bt_debugfs,
+ debugfs_create_u16("l2cap_le_default_mps", 0644, bt_debugfs,
&le_default_mps);
bt_6lowpan_init();
diff --git a/net/bluetooth/l2cap_sock.c b/net/bluetooth/l2cap_sock.c
index dffa57c..f0f2601 100644
--- a/net/bluetooth/l2cap_sock.c
+++ b/net/bluetooth/l2cap_sock.c
@@ -787,11 +787,6 @@
/*change security for LE channels */
if (chan->scid == L2CAP_CID_ATT) {
- if (!conn->hcon->out) {
- err = -EINVAL;
- break;
- }
-
if (smp_conn_security(conn->hcon, sec.level))
break;
sk->sk_state = BT_CONFIG;
@@ -1180,13 +1175,16 @@
/* Check for backlog size */
if (sk_acceptq_is_full(parent)) {
BT_DBG("backlog full %d", parent->sk_ack_backlog);
+ release_sock(parent);
return NULL;
}
sk = l2cap_sock_alloc(sock_net(parent), NULL, BTPROTO_L2CAP,
GFP_ATOMIC);
- if (!sk)
+ if (!sk) {
+ release_sock(parent);
return NULL;
+ }
bt_sock_reclassify_lock(sk, BTPROTO_L2CAP);
diff --git a/net/bluetooth/mgmt.c b/net/bluetooth/mgmt.c
index d2d4e0d..a88cb33 100644
--- a/net/bluetooth/mgmt.c
+++ b/net/bluetooth/mgmt.c
@@ -1045,6 +1045,43 @@
}
}
+static void hci_stop_discovery(struct hci_request *req)
+{
+ struct hci_dev *hdev = req->hdev;
+ struct hci_cp_remote_name_req_cancel cp;
+ struct inquiry_entry *e;
+
+ switch (hdev->discovery.state) {
+ case DISCOVERY_FINDING:
+ if (test_bit(HCI_INQUIRY, &hdev->flags)) {
+ hci_req_add(req, HCI_OP_INQUIRY_CANCEL, 0, NULL);
+ } else {
+ cancel_delayed_work(&hdev->le_scan_disable);
+ hci_req_add_le_scan_disable(req);
+ }
+
+ break;
+
+ case DISCOVERY_RESOLVING:
+ e = hci_inquiry_cache_lookup_resolve(hdev, BDADDR_ANY,
+ NAME_PENDING);
+ if (!e)
+ return;
+
+ bacpy(&cp.bdaddr, &e->data.bdaddr);
+ hci_req_add(req, HCI_OP_REMOTE_NAME_REQ_CANCEL, sizeof(cp),
+ &cp);
+
+ break;
+
+ default:
+ /* Passive scanning */
+ if (test_bit(HCI_LE_SCAN, &hdev->dev_flags))
+ hci_req_add_le_scan_disable(req);
+ break;
+ }
+}
+
static int clean_up_hci_state(struct hci_dev *hdev)
{
struct hci_request req;
@@ -1061,9 +1098,7 @@
if (test_bit(HCI_ADVERTISING, &hdev->dev_flags))
disable_advertising(&req);
- if (test_bit(HCI_LE_SCAN, &hdev->dev_flags)) {
- hci_req_add_le_scan_disable(&req);
- }
+ hci_stop_discovery(&req);
list_for_each_entry(conn, &hdev->conn_hash.list, list) {
struct hci_cp_disconnect dc;
@@ -2997,8 +3032,13 @@
}
if (addr->type == BDADDR_LE_PUBLIC || addr->type == BDADDR_LE_RANDOM) {
- /* Continue with pairing via SMP */
+ /* Continue with pairing via SMP. The hdev lock must be
+ * released as SMP may try to recquire it for crypto
+ * purposes.
+ */
+ hci_dev_unlock(hdev);
err = smp_user_confirm_reply(conn, mgmt_op, passkey);
+ hci_dev_lock(hdev);
if (!err)
err = cmd_complete(sk, hdev->id, mgmt_op,
@@ -3570,8 +3610,6 @@
{
struct mgmt_cp_stop_discovery *mgmt_cp = data;
struct pending_cmd *cmd;
- struct hci_cp_remote_name_req_cancel cp;
- struct inquiry_entry *e;
struct hci_request req;
int err;
@@ -3601,52 +3639,22 @@
hci_req_init(&req, hdev);
- switch (hdev->discovery.state) {
- case DISCOVERY_FINDING:
- if (test_bit(HCI_INQUIRY, &hdev->flags)) {
- hci_req_add(&req, HCI_OP_INQUIRY_CANCEL, 0, NULL);
- } else {
- cancel_delayed_work(&hdev->le_scan_disable);
+ hci_stop_discovery(&req);
- hci_req_add_le_scan_disable(&req);
- }
-
- break;
-
- case DISCOVERY_RESOLVING:
- e = hci_inquiry_cache_lookup_resolve(hdev, BDADDR_ANY,
- NAME_PENDING);
- if (!e) {
- mgmt_pending_remove(cmd);
- err = cmd_complete(sk, hdev->id,
- MGMT_OP_STOP_DISCOVERY, 0,
- &mgmt_cp->type,
- sizeof(mgmt_cp->type));
- hci_discovery_set_state(hdev, DISCOVERY_STOPPED);
- goto unlock;
- }
-
- bacpy(&cp.bdaddr, &e->data.bdaddr);
- hci_req_add(&req, HCI_OP_REMOTE_NAME_REQ_CANCEL, sizeof(cp),
- &cp);
-
- break;
-
- default:
- BT_DBG("unknown discovery state %u", hdev->discovery.state);
-
- mgmt_pending_remove(cmd);
- err = cmd_complete(sk, hdev->id, MGMT_OP_STOP_DISCOVERY,
- MGMT_STATUS_FAILED, &mgmt_cp->type,
- sizeof(mgmt_cp->type));
+ err = hci_req_run(&req, stop_discovery_complete);
+ if (!err) {
+ hci_discovery_set_state(hdev, DISCOVERY_STOPPING);
goto unlock;
}
- err = hci_req_run(&req, stop_discovery_complete);
- if (err < 0)
- mgmt_pending_remove(cmd);
- else
- hci_discovery_set_state(hdev, DISCOVERY_STOPPING);
+ mgmt_pending_remove(cmd);
+
+ /* If no HCI commands were sent we're done */
+ if (err == -ENODATA) {
+ err = cmd_complete(sk, hdev->id, MGMT_OP_STOP_DISCOVERY, 0,
+ &mgmt_cp->type, sizeof(mgmt_cp->type));
+ hci_discovery_set_state(hdev, DISCOVERY_STOPPED);
+ }
unlock:
hci_dev_unlock(hdev);
@@ -4530,7 +4538,7 @@
for (i = 0; i < key_count; i++) {
struct mgmt_ltk_info *key = &cp->keys[i];
- u8 type, addr_type;
+ u8 type, addr_type, authenticated;
if (key->addr.type == BDADDR_LE_PUBLIC)
addr_type = ADDR_LE_DEV_PUBLIC;
@@ -4542,8 +4550,19 @@
else
type = HCI_SMP_LTK_SLAVE;
+ switch (key->type) {
+ case MGMT_LTK_UNAUTHENTICATED:
+ authenticated = 0x00;
+ break;
+ case MGMT_LTK_AUTHENTICATED:
+ authenticated = 0x01;
+ break;
+ default:
+ continue;
+ }
+
hci_add_ltk(hdev, &key->addr.bdaddr, addr_type, type,
- key->type, key->val, key->enc_size, key->ediv,
+ authenticated, key->val, key->enc_size, key->ediv,
key->rand);
}
@@ -5005,6 +5024,14 @@
mgmt_event(MGMT_EV_NEW_LINK_KEY, hdev, &ev, sizeof(ev), NULL);
}
+static u8 mgmt_ltk_type(struct smp_ltk *ltk)
+{
+ if (ltk->authenticated)
+ return MGMT_LTK_AUTHENTICATED;
+
+ return MGMT_LTK_UNAUTHENTICATED;
+}
+
void mgmt_new_ltk(struct hci_dev *hdev, struct smp_ltk *key, bool persistent)
{
struct mgmt_ev_new_long_term_key ev;
@@ -5030,7 +5057,7 @@
bacpy(&ev.key.addr.bdaddr, &key->bdaddr);
ev.key.addr.type = link_to_bdaddr(LE_LINK, key->bdaddr_type);
- ev.key.type = key->authenticated;
+ ev.key.type = mgmt_ltk_type(key);
ev.key.enc_size = key->enc_size;
ev.key.ediv = key->ediv;
ev.key.rand = key->rand;
diff --git a/net/bluetooth/smp.c b/net/bluetooth/smp.c
index dfb4e11..863425a 100644
--- a/net/bluetooth/smp.c
+++ b/net/bluetooth/smp.c
@@ -533,7 +533,7 @@
hci_le_start_enc(hcon, ediv, rand, stk);
hcon->enc_key_size = smp->enc_key_size;
} else {
- u8 stk[16];
+ u8 stk[16], auth;
__le64 rand = 0;
__le16 ediv = 0;
@@ -545,8 +545,13 @@
memset(stk + smp->enc_key_size, 0,
SMP_MAX_ENC_KEY_SIZE - smp->enc_key_size);
+ if (hcon->pending_sec_level == BT_SECURITY_HIGH)
+ auth = 1;
+ else
+ auth = 0;
+
hci_add_ltk(hcon->hdev, &hcon->dst, hcon->dst_type,
- HCI_SMP_STK_SLAVE, 0, stk, smp->enc_key_size,
+ HCI_SMP_STK_SLAVE, auth, stk, smp->enc_key_size,
ediv, rand);
}
@@ -908,10 +913,11 @@
authreq = seclevel_to_authreq(sec_level);
- /* hcon->auth_type is set by pair_device in mgmt.c. If the MITM
- * flag is set we should also set it for the SMP request.
+ /* Require MITM if IO Capability allows or the security level
+ * requires it.
*/
- if ((hcon->auth_type & 0x01))
+ if (hcon->io_capability != HCI_IO_NO_INPUT_OUTPUT ||
+ sec_level > BT_SECURITY_MEDIUM)
authreq |= SMP_AUTH_MITM;
if (hcon->link_mode & HCI_LM_MASTER) {
diff --git a/net/ieee802154/wpan-class.c b/net/ieee802154/wpan-class.c
index 979e3cc..b3ef831 100644
--- a/net/ieee802154/wpan-class.c
+++ b/net/ieee802154/wpan-class.c
@@ -206,9 +206,7 @@
static int __init wpan_phy_class_init(void)
{
int rc;
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,11,0)
init_pmib_attrs();
-#endif
rc = class_register(&wpan_phy_class);
if (rc)
goto err;
diff --git a/net/mac80211/debugfs_netdev.c b/net/mac80211/debugfs_netdev.c
index 3da74ae..ff4fa15 100644
--- a/net/mac80211/debugfs_netdev.c
+++ b/net/mac80211/debugfs_netdev.c
@@ -34,8 +34,7 @@
ssize_t ret = -EINVAL;
read_lock(&dev_base_lock);
- if (sdata->dev->reg_state == NETREG_REGISTERED)
- ret = (*format)(sdata, buf, sizeof(buf));
+ ret = (*format)(sdata, buf, sizeof(buf));
read_unlock(&dev_base_lock);
if (ret >= 0)
@@ -62,8 +61,7 @@
ret = -ENODEV;
rtnl_lock();
- if (sdata->dev->reg_state == NETREG_REGISTERED)
- ret = (*write)(sdata, buf, count);
+ ret = (*write)(sdata, buf, count);
rtnl_unlock();
return ret;
diff --git a/net/mac80211/ibss.c b/net/mac80211/ibss.c
index 06d2878..53cf876 100644
--- a/net/mac80211/ibss.c
+++ b/net/mac80211/ibss.c
@@ -1648,6 +1648,7 @@
sdata->u.ibss.control_port = params->control_port;
sdata->u.ibss.userspace_handles_dfs = params->userspace_handles_dfs;
sdata->u.ibss.basic_rates = params->basic_rates;
+ sdata->u.ibss.last_scan_completed = jiffies;
/* fix basic_rates if channel does not support these rates */
rate_flags = ieee80211_chandef_rate_flags(¶ms->chandef);
diff --git a/net/mac80211/ieee80211_i.h b/net/mac80211/ieee80211_i.h
index 249089e..37602d1 100644
--- a/net/mac80211/ieee80211_i.h
+++ b/net/mac80211/ieee80211_i.h
@@ -317,6 +317,7 @@
bool started, abort, hw_begun, notified;
bool to_be_freed;
+ bool on_channel;
unsigned long hw_start_time;
diff --git a/net/mac80211/iface.c b/net/mac80211/iface.c
index 85f41dd..bf68628 100644
--- a/net/mac80211/iface.c
+++ b/net/mac80211/iface.c
@@ -1052,7 +1052,7 @@
ieee80211_teardown_sdata(IEEE80211_DEV_TO_SUB_IF(dev));
}
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,15,0)
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,14,0)
static u16 ieee80211_netdev_select_queue(struct net_device *dev,
struct sk_buff *skb,
void *accel_priv,
@@ -1080,7 +1080,7 @@
.ndo_select_queue = ieee80211_netdev_select_queue,
};
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,15,0)
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,14,0)
static u16 ieee80211_monitor_select_queue(struct net_device *dev,
struct sk_buff *skb,
void *accel_priv,
@@ -1776,7 +1776,6 @@
}
mutex_unlock(&local->iflist_mtx);
unregister_netdevice_many(&unreg_list);
- list_del(&unreg_list);
list_for_each_entry_safe(sdata, tmp, &wdev_list, list) {
list_del(&sdata->list);
diff --git a/net/mac80211/mlme.c b/net/mac80211/mlme.c
index dee50ae..27600a9 100644
--- a/net/mac80211/mlme.c
+++ b/net/mac80211/mlme.c
@@ -3598,18 +3598,24 @@
sdata_lock(sdata);
- if (ifmgd->auth_data) {
+ if (ifmgd->auth_data || ifmgd->assoc_data) {
+ const u8 *bssid = ifmgd->auth_data ?
+ ifmgd->auth_data->bss->bssid :
+ ifmgd->assoc_data->bss->bssid;
+
/*
- * If we are trying to authenticate while suspending, cfg80211
- * won't know and won't actually abort those attempts, thus we
- * need to do that ourselves.
+ * If we are trying to authenticate / associate while suspending,
+ * cfg80211 won't know and won't actually abort those attempts,
+ * thus we need to do that ourselves.
*/
- ieee80211_send_deauth_disassoc(sdata,
- ifmgd->auth_data->bss->bssid,
+ ieee80211_send_deauth_disassoc(sdata, bssid,
IEEE80211_STYPE_DEAUTH,
WLAN_REASON_DEAUTH_LEAVING,
false, frame_buf);
- ieee80211_destroy_auth_data(sdata, false);
+ if (ifmgd->assoc_data)
+ ieee80211_destroy_assoc_data(sdata, false);
+ if (ifmgd->auth_data)
+ ieee80211_destroy_auth_data(sdata, false);
cfg80211_tx_mlme_mgmt(sdata->dev, frame_buf,
IEEE80211_DEAUTH_FRAME_LEN);
}
diff --git a/net/mac80211/offchannel.c b/net/mac80211/offchannel.c
index 6fb3855..7a17dec 100644
--- a/net/mac80211/offchannel.c
+++ b/net/mac80211/offchannel.c
@@ -333,7 +333,7 @@
container_of(work, struct ieee80211_roc_work, work.work);
struct ieee80211_sub_if_data *sdata = roc->sdata;
struct ieee80211_local *local = sdata->local;
- bool started;
+ bool started, on_channel;
mutex_lock(&local->mtx);
@@ -354,14 +354,26 @@
if (!roc->started) {
struct ieee80211_roc_work *dep;
- /* start this ROC */
- ieee80211_offchannel_stop_vifs(local);
+ WARN_ON(local->use_chanctx);
- /* switch channel etc */
+ /* If actually operating on the desired channel (with at least
+ * 20 MHz channel width) don't stop all the operations but still
+ * treat it as though the ROC operation started properly, so
+ * other ROC operations won't interfere with this one.
+ */
+ roc->on_channel = roc->chan == local->_oper_chandef.chan &&
+ local->_oper_chandef.width != NL80211_CHAN_WIDTH_5 &&
+ local->_oper_chandef.width != NL80211_CHAN_WIDTH_10;
+
+ /* start this ROC */
ieee80211_recalc_idle(local);
- local->tmp_channel = roc->chan;
- ieee80211_hw_config(local, 0);
+ if (!roc->on_channel) {
+ ieee80211_offchannel_stop_vifs(local);
+
+ local->tmp_channel = roc->chan;
+ ieee80211_hw_config(local, 0);
+ }
/* tell userspace or send frame */
ieee80211_handle_roc_started(roc);
@@ -380,9 +392,10 @@
finish:
list_del(&roc->list);
started = roc->started;
+ on_channel = roc->on_channel;
ieee80211_roc_notify_destroy(roc, !roc->abort);
- if (started) {
+ if (started && !on_channel) {
ieee80211_flush_queues(local, NULL);
local->tmp_channel = NULL;
diff --git a/net/mac80211/rx.c b/net/mac80211/rx.c
index 274ac84..342e3d5 100644
--- a/net/mac80211/rx.c
+++ b/net/mac80211/rx.c
@@ -1231,7 +1231,8 @@
if (ether_addr_equal(bssid, rx->sdata->u.ibss.bssid) &&
test_sta_flag(sta, WLAN_STA_AUTHORIZED)) {
sta->last_rx = jiffies;
- if (ieee80211_is_data(hdr->frame_control)) {
+ if (ieee80211_is_data(hdr->frame_control) &&
+ !is_multicast_ether_addr(hdr->addr1)) {
sta->last_rx_rate_idx = status->rate_idx;
sta->last_rx_rate_flag = status->flag;
sta->last_rx_rate_vht_flag = status->vht_flag;
diff --git a/net/mac80211/sta_info.c b/net/mac80211/sta_info.c
index d462a65..bba2df3 100644
--- a/net/mac80211/sta_info.c
+++ b/net/mac80211/sta_info.c
@@ -240,6 +240,7 @@
sta_dbg(sta->sdata, "Destroyed STA %pM\n", sta->sta.addr);
+ kfree(rcu_dereference_raw(sta->sta.rates));
kfree(sta);
}
@@ -1148,7 +1149,8 @@
atomic_dec(&ps->num_sta_ps);
/* This station just woke up and isn't aware of our SMPS state */
- if (!ieee80211_smps_is_restrictive(sta->known_smps_mode,
+ if (!ieee80211_vif_is_mesh(&sdata->vif) &&
+ !ieee80211_smps_is_restrictive(sta->known_smps_mode,
sdata->smps_mode) &&
sta->known_smps_mode != sdata->bss->req_smps &&
sta_info_tx_streams(sta) != 1) {
diff --git a/net/mac80211/status.c b/net/mac80211/status.c
index 00ba90b..60cb7a6 100644
--- a/net/mac80211/status.c
+++ b/net/mac80211/status.c
@@ -314,10 +314,9 @@
!is_multicast_ether_addr(hdr->addr1))
txflags |= IEEE80211_RADIOTAP_F_TX_FAIL;
- if ((info->status.rates[0].flags & IEEE80211_TX_RC_USE_RTS_CTS) ||
- (info->status.rates[0].flags & IEEE80211_TX_RC_USE_CTS_PROTECT))
+ if (info->status.rates[0].flags & IEEE80211_TX_RC_USE_CTS_PROTECT)
txflags |= IEEE80211_RADIOTAP_F_TX_CTS;
- else if (info->status.rates[0].flags & IEEE80211_TX_RC_USE_RTS_CTS)
+ if (info->status.rates[0].flags & IEEE80211_TX_RC_USE_RTS_CTS)
txflags |= IEEE80211_RADIOTAP_F_TX_RTS;
put_unaligned_le16(txflags, pos);
diff --git a/net/mac80211/trace.h b/net/mac80211/trace.h
index 7f489e2..b73377d 100644
--- a/net/mac80211/trace.h
+++ b/net/mac80211/trace.h
@@ -21,10 +21,10 @@
#define VIF_ENTRY __field(enum nl80211_iftype, vif_type) __field(void *, sdata) \
__field(bool, p2p) \
- __string(vif_name, sdata->dev ? sdata->dev->name : "<nodev>")
+ __string(vif_name, sdata->name)
#define VIF_ASSIGN __entry->vif_type = sdata->vif.type; __entry->sdata = sdata; \
__entry->p2p = sdata->vif.p2p; \
- __assign_str(vif_name, sdata->dev ? sdata->dev->name : sdata->name)
+ __assign_str(vif_name, sdata->name)
#define VIF_PR_FMT " vif:%s(%d%s)"
#define VIF_PR_ARG __get_str(vif_name), __entry->vif_type, __entry->p2p ? "/p2p" : ""
diff --git a/net/mac80211/tx.c b/net/mac80211/tx.c
index e209559..fcebd5e 100644
--- a/net/mac80211/tx.c
+++ b/net/mac80211/tx.c
@@ -414,6 +414,9 @@
if (ieee80211_has_order(hdr->frame_control))
return TX_CONTINUE;
+ if (ieee80211_is_probe_req(hdr->frame_control))
+ return TX_CONTINUE;
+
if (tx->local->hw.flags & IEEE80211_HW_QUEUE_CONTROL)
info->hw_queue = tx->sdata->vif.cab_queue;
@@ -463,6 +466,7 @@
{
struct sta_info *sta = tx->sta;
struct ieee80211_tx_info *info = IEEE80211_SKB_CB(tx->skb);
+ struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)tx->skb->data;
struct ieee80211_local *local = tx->local;
if (unlikely(!sta))
@@ -473,6 +477,12 @@
!(info->flags & IEEE80211_TX_CTL_NO_PS_BUFFER))) {
int ac = skb_get_queue_mapping(tx->skb);
+ if (ieee80211_is_mgmt(hdr->frame_control) &&
+ !ieee80211_is_bufferable_mmpdu(hdr->frame_control)) {
+ info->flags |= IEEE80211_TX_CTL_NO_PS_BUFFER;
+ return TX_CONTINUE;
+ }
+
ps_dbg(sta->sdata, "STA %pM aid %d: PS buffer for AC %d\n",
sta->sta.addr, sta->sta.aid, ac);
if (tx->local->total_ps_buffered >= TOTAL_MAX_TX_BUFFER)
@@ -531,19 +541,9 @@
static ieee80211_tx_result debug_noinline
ieee80211_tx_h_ps_buf(struct ieee80211_tx_data *tx)
{
- struct ieee80211_tx_info *info = IEEE80211_SKB_CB(tx->skb);
- struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)tx->skb->data;
-
if (unlikely(tx->flags & IEEE80211_TX_PS_BUFFERED))
return TX_CONTINUE;
- if (ieee80211_is_mgmt(hdr->frame_control) &&
- !ieee80211_is_bufferable_mmpdu(hdr->frame_control)) {
- if (tx->flags & IEEE80211_TX_UNICAST)
- info->flags |= IEEE80211_TX_CTL_NO_PS_BUFFER;
- return TX_CONTINUE;
- }
-
if (tx->flags & IEEE80211_TX_UNICAST)
return ieee80211_tx_h_unicast_ps_buf(tx);
else
diff --git a/net/mac80211/util.c b/net/mac80211/util.c
index 275c94f..3c36583 100644
--- a/net/mac80211/util.c
+++ b/net/mac80211/util.c
@@ -1780,7 +1780,7 @@
mutex_unlock(&local->mtx);
if (sched_scan_stopped)
- cfg80211_sched_scan_stopped(local->hw.wiphy);
+ cfg80211_sched_scan_stopped_rtnl(local->hw.wiphy);
/*
* If this is for hw restart things are still running.
diff --git a/net/mac80211/vht.c b/net/mac80211/vht.c
index e9e36a2..9265adf 100644
--- a/net/mac80211/vht.c
+++ b/net/mac80211/vht.c
@@ -129,9 +129,12 @@
if (!vht_cap_ie || !sband->vht_cap.vht_supported)
return;
- /* A VHT STA must support 40 MHz */
- if (!(sta->sta.ht_cap.cap & IEEE80211_HT_CAP_SUP_WIDTH_20_40))
- return;
+ /*
+ * A VHT STA must support 40 MHz, but if we verify that here
+ * then we break a few things - some APs (e.g. Netgear R6300v2
+ * and others based on the BCM4360 chipset) will unset this
+ * capability bit when operating in 20 MHz.
+ */
vht_cap->vht_supported = true;
diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c
index a67c8c8..087e8cc 100644
--- a/net/wireless/nl80211.c
+++ b/net/wireless/nl80211.c
@@ -1470,18 +1470,17 @@
}
CMD(start_p2p_device, START_P2P_DEVICE);
CMD(set_mcast_rate, SET_MCAST_RATE);
+#ifdef CPTCFG_NL80211_TESTMODE
+ CMD(testmode_cmd, TESTMODE);
+#endif
if (state->split) {
CMD(crit_proto_start, CRIT_PROTOCOL_START);
CMD(crit_proto_stop, CRIT_PROTOCOL_STOP);
if (dev->wiphy.flags & WIPHY_FLAG_HAS_CHANNEL_SWITCH)
CMD(channel_switch, CHANNEL_SWITCH);
+ CMD(set_qos_map, SET_QOS_MAP);
}
- CMD(set_qos_map, SET_QOS_MAP);
-
-#ifdef CPTCFG_NL80211_TESTMODE
- CMD(testmode_cmd, TESTMODE);
-#endif
-
+ /* add into the if now */
#undef CMD
if (dev->ops->connect || dev->ops->auth) {
diff --git a/net/wireless/scan.c b/net/wireless/scan.c
index cfb4952..410a1af 100644
--- a/net/wireless/scan.c
+++ b/net/wireless/scan.c
@@ -284,14 +284,22 @@
}
EXPORT_SYMBOL(cfg80211_sched_scan_results);
-void cfg80211_sched_scan_stopped(struct wiphy *wiphy)
+void cfg80211_sched_scan_stopped_rtnl(struct wiphy *wiphy)
{
struct cfg80211_registered_device *rdev = wiphy_to_dev(wiphy);
+ ASSERT_RTNL();
+
trace_cfg80211_sched_scan_stopped(wiphy);
- rtnl_lock();
__cfg80211_stop_sched_scan(rdev, true);
+}
+EXPORT_SYMBOL(cfg80211_sched_scan_stopped_rtnl);
+
+void cfg80211_sched_scan_stopped(struct wiphy *wiphy)
+{
+ rtnl_lock();
+ cfg80211_sched_scan_stopped_rtnl(wiphy);
rtnl_unlock();
}
EXPORT_SYMBOL(cfg80211_sched_scan_stopped);
diff --git a/net/wireless/sme.c b/net/wireless/sme.c
index ced7328..37600fe 100644
--- a/net/wireless/sme.c
+++ b/net/wireless/sme.c
@@ -234,7 +234,6 @@
NULL, 0, NULL, 0,
WLAN_STATUS_UNSPECIFIED_FAILURE,
false, NULL);
- cfg80211_sme_free(wdev);
}
wdev_unlock(wdev);
}
@@ -648,6 +647,7 @@
cfg80211_unhold_bss(bss_from_pub(bss));
cfg80211_put_bss(wdev->wiphy, bss);
}
+ cfg80211_sme_free(wdev);
return;
}
diff --git a/net/wireless/sysfs.c b/net/wireless/sysfs.c
index 7d3162b..c5d39ed 100644
--- a/net/wireless/sysfs.c
+++ b/net/wireless/sysfs.c
@@ -170,9 +170,7 @@
int wiphy_sysfs_init(void)
{
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,11,0)
init_ieee80211_attrs();
-#endif
return class_register(&ieee80211_class);
}
diff --git a/net/wireless/trace.h b/net/wireless/trace.h
index 45f2977..f0db2c4 100644
--- a/net/wireless/trace.h
+++ b/net/wireless/trace.h
@@ -2072,7 +2072,8 @@
MAC_ASSIGN(addr, addr);
__entry->key_type = key_type;
__entry->key_id = key_id;
- memcpy(__entry->tsc, tsc, 6);
+ if (tsc)
+ memcpy(__entry->tsc, tsc, 6);
),
TP_printk(NETDEV_PR_FMT ", " MAC_PR_FMT ", key type: %d, key id: %d, tsc: %pm",
NETDEV_PR_ARG, MAC_PR_ARG(addr), __entry->key_type,
diff --git a/versions b/versions
index 88c26b6..7bb645f 100644
--- a/versions
+++ b/versions
@@ -1,3 +1,3 @@
-BACKPORTS_VERSION="backports-20140320-17-g2a25483"
-BACKPORTED_KERNEL_VERSION="v3.15-rc1-237-gd9bc4b9"
+BACKPORTS_VERSION="v3.15.9-1-0-g3c01584"
+BACKPORTED_KERNEL_VERSION="v3.15.9-0-g0617859"
BACKPORTED_KERNEL_NAME="Linux"