Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 889711a0 authored by David S. Miller's avatar David S. Miller
Browse files

Merge tag 'wireless-drivers-next-for-davem-2017-02-01' of...

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



Kalle Valo says:

====================
wireless-drivers-next patches for 4.11

It's nice to see rt2x00 development has becoming active, for example
adding support for a new chip version. Also wcn36xx has been converted
to use the recently merged QCOM_SMD subsystem. Otherwise new features
and fixes it lots of drivers.

Major changes:

iwlwifi

* some more work in preparation for A000 family support
* add support for radiotap timestamps
* some work on our firmware debugging capabilities

wcn36xx

* convert to a proper QCOM_SMD driver (from the platform_driver interface)

ath10k

* VHT160 support
* dump Copy Engine registers during firmware crash
* search board file extension from SMBIOS

wil6210

* add disable_ap_sme module parameter

rt2x00

* support RT3352 with external PA
* support for RT3352 with 20MHz crystal
* add support for RT5350 WiSoC

brcmfmac

* add support for BCM43455 sdio device

rtl8xxxu

* add support for D-Link DWA-131 rev E1, TP-Link TL-WN822N v4 and others
====================

Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parents ff1176f6 7243a1af
Loading
Loading
Loading
Loading
+1 −1
Original line number Original line Diff line number Diff line
@@ -10607,7 +10607,7 @@ F: drivers/net/wireless/realtek/rtlwifi/
F:	drivers/net/wireless/realtek/rtlwifi/rtl8192ce/
F:	drivers/net/wireless/realtek/rtlwifi/rtl8192ce/


RTL8XXXU WIRELESS DRIVER (rtl8xxxu)
RTL8XXXU WIRELESS DRIVER (rtl8xxxu)
M:	Jes Sorensen <Jes.Sorensen@redhat.com>
M:	Jes Sorensen <Jes.Sorensen@gmail.com>
L:	linux-wireless@vger.kernel.org
L:	linux-wireless@vger.kernel.org
T:	git git://git.kernel.org/pub/scm/linux/kernel/git/jes/linux.git rtl8xxxu-devel
T:	git git://git.kernel.org/pub/scm/linux/kernel/git/jes/linux.git rtl8xxxu-devel
S:	Maintained
S:	Maintained
+15 −10
Original line number Original line Diff line number Diff line
@@ -136,17 +136,17 @@ static bool bcma_is_core_needed_early(u16 core_id)
	return false;
	return false;
}
}


static struct device_node *bcma_of_find_child_device(struct platform_device *parent,
static struct device_node *bcma_of_find_child_device(struct device *parent,
						     struct bcma_device *core)
						     struct bcma_device *core)
{
{
	struct device_node *node;
	struct device_node *node;
	u64 size;
	u64 size;
	const __be32 *reg;
	const __be32 *reg;


	if (!parent || !parent->dev.of_node)
	if (!parent->of_node)
		return NULL;
		return NULL;


	for_each_child_of_node(parent->dev.of_node, node) {
	for_each_child_of_node(parent->of_node, node) {
		reg = of_get_address(node, 0, &size, NULL);
		reg = of_get_address(node, 0, &size, NULL);
		if (!reg)
		if (!reg)
			continue;
			continue;
@@ -156,7 +156,7 @@ static struct device_node *bcma_of_find_child_device(struct platform_device *par
	return NULL;
	return NULL;
}
}


static int bcma_of_irq_parse(struct platform_device *parent,
static int bcma_of_irq_parse(struct device *parent,
			     struct bcma_device *core,
			     struct bcma_device *core,
			     struct of_phandle_args *out_irq, int num)
			     struct of_phandle_args *out_irq, int num)
{
{
@@ -169,7 +169,7 @@ static int bcma_of_irq_parse(struct platform_device *parent,
			return rc;
			return rc;
	}
	}


	out_irq->np = parent->dev.of_node;
	out_irq->np = parent->of_node;
	out_irq->args_count = 1;
	out_irq->args_count = 1;
	out_irq->args[0] = num;
	out_irq->args[0] = num;


@@ -177,13 +177,13 @@ static int bcma_of_irq_parse(struct platform_device *parent,
	return of_irq_parse_raw(laddr, out_irq);
	return of_irq_parse_raw(laddr, out_irq);
}
}


static unsigned int bcma_of_get_irq(struct platform_device *parent,
static unsigned int bcma_of_get_irq(struct device *parent,
				    struct bcma_device *core, int num)
				    struct bcma_device *core, int num)
{
{
	struct of_phandle_args out_irq;
	struct of_phandle_args out_irq;
	int ret;
	int ret;


	if (!IS_ENABLED(CONFIG_OF_IRQ) || !parent || !parent->dev.of_node)
	if (!IS_ENABLED(CONFIG_OF_IRQ) || !parent->of_node)
		return 0;
		return 0;


	ret = bcma_of_irq_parse(parent, core, &out_irq, num);
	ret = bcma_of_irq_parse(parent, core, &out_irq, num);
@@ -196,7 +196,7 @@ static unsigned int bcma_of_get_irq(struct platform_device *parent,
	return irq_create_of_mapping(&out_irq);
	return irq_create_of_mapping(&out_irq);
}
}


static void bcma_of_fill_device(struct platform_device *parent,
static void bcma_of_fill_device(struct device *parent,
				struct bcma_device *core)
				struct bcma_device *core)
{
{
	struct device_node *node;
	struct device_node *node;
@@ -227,7 +227,7 @@ unsigned int bcma_core_irq(struct bcma_device *core, int num)
			return mips_irq <= 4 ? mips_irq + 2 : 0;
			return mips_irq <= 4 ? mips_irq + 2 : 0;
		}
		}
		if (bus->host_pdev)
		if (bus->host_pdev)
			return bcma_of_get_irq(bus->host_pdev, core, num);
			return bcma_of_get_irq(&bus->host_pdev->dev, core, num);
		return 0;
		return 0;
	case BCMA_HOSTTYPE_SDIO:
	case BCMA_HOSTTYPE_SDIO:
		return 0;
		return 0;
@@ -253,7 +253,8 @@ void bcma_prepare_core(struct bcma_bus *bus, struct bcma_device *core)
		if (IS_ENABLED(CONFIG_OF) && bus->host_pdev) {
		if (IS_ENABLED(CONFIG_OF) && bus->host_pdev) {
			core->dma_dev = &bus->host_pdev->dev;
			core->dma_dev = &bus->host_pdev->dev;
			core->dev.parent = &bus->host_pdev->dev;
			core->dev.parent = &bus->host_pdev->dev;
			bcma_of_fill_device(bus->host_pdev, core);
			if (core->dev.parent)
				bcma_of_fill_device(core->dev.parent, core);
		} else {
		} else {
			core->dev.dma_mask = &core->dev.coherent_dma_mask;
			core->dev.dma_mask = &core->dev.coherent_dma_mask;
			core->dma_dev = &core->dev;
			core->dma_dev = &core->dev;
@@ -633,8 +634,11 @@ static int bcma_device_probe(struct device *dev)
					       drv);
					       drv);
	int err = 0;
	int err = 0;


	get_device(dev);
	if (adrv->probe)
	if (adrv->probe)
		err = adrv->probe(core);
		err = adrv->probe(core);
	if (err)
		put_device(dev);


	return err;
	return err;
}
}
@@ -647,6 +651,7 @@ static int bcma_device_remove(struct device *dev)


	if (adrv->remove)
	if (adrv->remove)
		adrv->remove(core);
		adrv->remove(core);
	put_device(dev);


	return 0;
	return 0;
}
}
+40 −8
Original line number Original line Diff line number Diff line
@@ -958,7 +958,7 @@ ath10k_ce_alloc_dest_ring(struct ath10k *ar, unsigned int ce_id,
	 * coherent DMA are unsupported
	 * coherent DMA are unsupported
	 */
	 */
	dest_ring->base_addr_owner_space_unaligned =
	dest_ring->base_addr_owner_space_unaligned =
		dma_alloc_coherent(ar->dev,
		dma_zalloc_coherent(ar->dev,
				   (nentries * sizeof(struct ce_desc) +
				   (nentries * sizeof(struct ce_desc) +
				    CE_DESC_RING_ALIGN),
				    CE_DESC_RING_ALIGN),
				   &base_addr, GFP_KERNEL);
				   &base_addr, GFP_KERNEL);
@@ -969,13 +969,6 @@ ath10k_ce_alloc_dest_ring(struct ath10k *ar, unsigned int ce_id,


	dest_ring->base_addr_ce_space_unaligned = base_addr;
	dest_ring->base_addr_ce_space_unaligned = base_addr;


	/*
	 * Correctly initialize memory to 0 to prevent garbage
	 * data crashing system when download firmware
	 */
	memset(dest_ring->base_addr_owner_space_unaligned, 0,
	       nentries * sizeof(struct ce_desc) + CE_DESC_RING_ALIGN);

	dest_ring->base_addr_owner_space = PTR_ALIGN(
	dest_ring->base_addr_owner_space = PTR_ALIGN(
			dest_ring->base_addr_owner_space_unaligned,
			dest_ring->base_addr_owner_space_unaligned,
			CE_DESC_RING_ALIGN);
			CE_DESC_RING_ALIGN);
@@ -1130,3 +1123,42 @@ void ath10k_ce_free_pipe(struct ath10k *ar, int ce_id)
	ce_state->src_ring = NULL;
	ce_state->src_ring = NULL;
	ce_state->dest_ring = NULL;
	ce_state->dest_ring = NULL;
}
}

void ath10k_ce_dump_registers(struct ath10k *ar,
			      struct ath10k_fw_crash_data *crash_data)
{
	struct ath10k_pci *ar_pci = ath10k_pci_priv(ar);
	struct ath10k_ce_crash_data ce;
	u32 addr, id;

	lockdep_assert_held(&ar->data_lock);

	ath10k_err(ar, "Copy Engine register dump:\n");

	spin_lock_bh(&ar_pci->ce_lock);
	for (id = 0; id < CE_COUNT; id++) {
		addr = ath10k_ce_base_address(ar, id);
		ce.base_addr = cpu_to_le32(addr);

		ce.src_wr_idx =
			cpu_to_le32(ath10k_ce_src_ring_write_index_get(ar, addr));
		ce.src_r_idx =
			cpu_to_le32(ath10k_ce_src_ring_read_index_get(ar, addr));
		ce.dst_wr_idx =
			cpu_to_le32(ath10k_ce_dest_ring_write_index_get(ar, addr));
		ce.dst_r_idx =
			cpu_to_le32(ath10k_ce_dest_ring_read_index_get(ar, addr));

		if (crash_data)
			crash_data->ce_crash_data[id] = ce;

		ath10k_err(ar, "[%02d]: 0x%08x %3u %3u %3u %3u", id,
			   le32_to_cpu(ce.base_addr),
			   le32_to_cpu(ce.src_wr_idx),
			   le32_to_cpu(ce.src_r_idx),
			   le32_to_cpu(ce.dst_wr_idx),
			   le32_to_cpu(ce.dst_r_idx));
	}

	spin_unlock_bh(&ar_pci->ce_lock);
}
+2 −2
Original line number Original line Diff line number Diff line
@@ -20,8 +20,6 @@


#include "hif.h"
#include "hif.h"


/* Maximum number of Copy Engine's supported */
#define CE_COUNT_MAX 12
#define CE_HTT_H2T_MSG_SRC_NENTRIES 8192
#define CE_HTT_H2T_MSG_SRC_NENTRIES 8192


/* Descriptor rings must be aligned to this boundary */
/* Descriptor rings must be aligned to this boundary */
@@ -228,6 +226,8 @@ void ath10k_ce_per_engine_service_any(struct ath10k *ar);
void ath10k_ce_per_engine_service(struct ath10k *ar, unsigned int ce_id);
void ath10k_ce_per_engine_service(struct ath10k *ar, unsigned int ce_id);
int ath10k_ce_disable_interrupts(struct ath10k *ar);
int ath10k_ce_disable_interrupts(struct ath10k *ar);
void ath10k_ce_enable_interrupts(struct ath10k *ar);
void ath10k_ce_enable_interrupts(struct ath10k *ar);
void ath10k_ce_dump_registers(struct ath10k *ar,
			      struct ath10k_fw_crash_data *crash_data);


/* ce_attr.flags values */
/* ce_attr.flags values */
/* Use NonSnooping PCIe accesses? */
/* Use NonSnooping PCIe accesses? */
+81 −3
Original line number Original line Diff line number Diff line
@@ -18,6 +18,8 @@
#include <linux/module.h>
#include <linux/module.h>
#include <linux/firmware.h>
#include <linux/firmware.h>
#include <linux/of.h>
#include <linux/of.h>
#include <linux/dmi.h>
#include <linux/ctype.h>
#include <asm/byteorder.h>
#include <asm/byteorder.h>


#include "core.h"
#include "core.h"
@@ -707,6 +709,72 @@ static int ath10k_core_get_board_id_from_otp(struct ath10k *ar)
	return 0;
	return 0;
}
}


static void ath10k_core_check_bdfext(const struct dmi_header *hdr, void *data)
{
	struct ath10k *ar = data;
	const char *bdf_ext;
	const char *magic = ATH10K_SMBIOS_BDF_EXT_MAGIC;
	u8 bdf_enabled;
	int i;

	if (hdr->type != ATH10K_SMBIOS_BDF_EXT_TYPE)
		return;

	if (hdr->length != ATH10K_SMBIOS_BDF_EXT_LENGTH) {
		ath10k_dbg(ar, ATH10K_DBG_BOOT,
			   "wrong smbios bdf ext type length (%d).\n",
			   hdr->length);
		return;
	}

	bdf_enabled = *((u8 *)hdr + ATH10K_SMBIOS_BDF_EXT_OFFSET);
	if (!bdf_enabled) {
		ath10k_dbg(ar, ATH10K_DBG_BOOT, "bdf variant name not found.\n");
		return;
	}

	/* Only one string exists (per spec) */
	bdf_ext = (char *)hdr + hdr->length;

	if (memcmp(bdf_ext, magic, strlen(magic)) != 0) {
		ath10k_dbg(ar, ATH10K_DBG_BOOT,
			   "bdf variant magic does not match.\n");
		return;
	}

	for (i = 0; i < strlen(bdf_ext); i++) {
		if (!isascii(bdf_ext[i]) || !isprint(bdf_ext[i])) {
			ath10k_dbg(ar, ATH10K_DBG_BOOT,
				   "bdf variant name contains non ascii chars.\n");
			return;
		}
	}

	/* Copy extension name without magic suffix */
	if (strscpy(ar->id.bdf_ext, bdf_ext + strlen(magic),
		    sizeof(ar->id.bdf_ext)) < 0) {
		ath10k_dbg(ar, ATH10K_DBG_BOOT,
			   "bdf variant string is longer than the buffer can accommodate (variant: %s)\n",
			    bdf_ext);
		return;
	}

	ath10k_dbg(ar, ATH10K_DBG_BOOT,
		   "found and validated bdf variant smbios_type 0x%x bdf %s\n",
		   ATH10K_SMBIOS_BDF_EXT_TYPE, bdf_ext);
}

static int ath10k_core_check_smbios(struct ath10k *ar)
{
	ar->id.bdf_ext[0] = '\0';
	dmi_walk(ath10k_core_check_bdfext, ar);

	if (ar->id.bdf_ext[0] == '\0')
		return -ENODATA;

	return 0;
}

static int ath10k_download_and_run_otp(struct ath10k *ar)
static int ath10k_download_and_run_otp(struct ath10k *ar)
{
{
	u32 result, address = ar->hw_params.patch_load_addr;
	u32 result, address = ar->hw_params.patch_load_addr;
@@ -1053,6 +1121,9 @@ static int ath10k_core_fetch_board_data_api_n(struct ath10k *ar,
static int ath10k_core_create_board_name(struct ath10k *ar, char *name,
static int ath10k_core_create_board_name(struct ath10k *ar, char *name,
					 size_t name_len)
					 size_t name_len)
{
{
	/* strlen(',variant=') + strlen(ar->id.bdf_ext) */
	char variant[9 + ATH10K_SMBIOS_BDF_EXT_STR_LENGTH];

	if (ar->id.bmi_ids_valid) {
	if (ar->id.bmi_ids_valid) {
		scnprintf(name, name_len,
		scnprintf(name, name_len,
			  "bus=%s,bmi-chip-id=%d,bmi-board-id=%d",
			  "bus=%s,bmi-chip-id=%d,bmi-board-id=%d",
@@ -1062,12 +1133,15 @@ static int ath10k_core_create_board_name(struct ath10k *ar, char *name,
		goto out;
		goto out;
	}
	}


	if (ar->id.bdf_ext[0] != '\0')
		scnprintf(variant, sizeof(variant), ",variant=%s",
			  ar->id.bdf_ext);

	scnprintf(name, name_len,
	scnprintf(name, name_len,
		  "bus=%s,vendor=%04x,device=%04x,subsystem-vendor=%04x,subsystem-device=%04x",
		  "bus=%s,vendor=%04x,device=%04x,subsystem-vendor=%04x,subsystem-device=%04x%s",
		  ath10k_bus_str(ar->hif.bus),
		  ath10k_bus_str(ar->hif.bus),
		  ar->id.vendor, ar->id.device,
		  ar->id.vendor, ar->id.device,
		  ar->id.subsystem_vendor, ar->id.subsystem_device);
		  ar->id.subsystem_vendor, ar->id.subsystem_device, variant);

out:
out:
	ath10k_dbg(ar, ATH10K_DBG_BOOT, "boot using board name '%s'\n", name);
	ath10k_dbg(ar, ATH10K_DBG_BOOT, "boot using board name '%s'\n", name);


@@ -2128,6 +2202,10 @@ static int ath10k_core_probe_fw(struct ath10k *ar)
		goto err_free_firmware_files;
		goto err_free_firmware_files;
	}
	}


	ret = ath10k_core_check_smbios(ar);
	if (ret)
		ath10k_dbg(ar, ATH10K_DBG_BOOT, "bdf variant name not set.\n");

	ret = ath10k_core_fetch_board_file(ar);
	ret = ath10k_core_fetch_board_file(ar);
	if (ret) {
	if (ret) {
		ath10k_err(ar, "failed to fetch board file: %d\n", ret);
		ath10k_err(ar, "failed to fetch board file: %d\n", ret);
Loading