Skip to content

Commit

Permalink
Merge tag 'wireless-drivers-next-for-davem-2017-02-01' of git://git.k…
Browse files Browse the repository at this point in the history
…ernel.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: David S. Miller <davem@davemloft.net>
  • Loading branch information
David S. Miller committed Feb 1, 2017
2 parents ff1176f + 7243a1a commit 889711a
Show file tree
Hide file tree
Showing 156 changed files with 2,847 additions and 2,526 deletions.
2 changes: 1 addition & 1 deletion MAINTAINERS
Original file line number Diff line number Diff line change
Expand Up @@ -10607,7 +10607,7 @@ F: drivers/net/wireless/realtek/rtlwifi/
F: drivers/net/wireless/realtek/rtlwifi/rtl8192ce/

RTL8XXXU WIRELESS DRIVER (rtl8xxxu)
M: Jes Sorensen <Jes.Sorensen@redhat.com>
M: Jes Sorensen <Jes.Sorensen@gmail.com>
L: linux-wireless@vger.kernel.org
T: git git://git.kernel.org/pub/scm/linux/kernel/git/jes/linux.git rtl8xxxu-devel
S: Maintained
Expand Down
25 changes: 15 additions & 10 deletions drivers/bcma/main.c
Original file line number Diff line number Diff line change
Expand Up @@ -136,17 +136,17 @@ static bool bcma_is_core_needed_early(u16 core_id)
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 device_node *node;
u64 size;
const __be32 *reg;

if (!parent || !parent->dev.of_node)
if (!parent->of_node)
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);
if (!reg)
continue;
Expand All @@ -156,7 +156,7 @@ static struct device_node *bcma_of_find_child_device(struct platform_device *par
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 of_phandle_args *out_irq, int num)
{
Expand All @@ -169,21 +169,21 @@ static int bcma_of_irq_parse(struct platform_device *parent,
return rc;
}

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

laddr[0] = cpu_to_be32(core->addr);
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 of_phandle_args out_irq;
int ret;

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

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

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

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

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

return 0;
}
Expand Down
48 changes: 40 additions & 8 deletions drivers/net/wireless/ath/ath10k/ce.c
Original file line number Diff line number Diff line change
Expand Up @@ -958,7 +958,7 @@ ath10k_ce_alloc_dest_ring(struct ath10k *ar, unsigned int ce_id,
* coherent DMA are unsupported
*/
dest_ring->base_addr_owner_space_unaligned =
dma_alloc_coherent(ar->dev,
dma_zalloc_coherent(ar->dev,
(nentries * sizeof(struct ce_desc) +
CE_DESC_RING_ALIGN),
&base_addr, GFP_KERNEL);
Expand All @@ -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;

/*
* 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_unaligned,
CE_DESC_RING_ALIGN);
Expand Down Expand Up @@ -1130,3 +1123,42 @@ void ath10k_ce_free_pipe(struct ath10k *ar, int ce_id)
ce_state->src_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);
}
4 changes: 2 additions & 2 deletions drivers/net/wireless/ath/ath10k/ce.h
Original file line number Diff line number Diff line change
Expand Up @@ -20,8 +20,6 @@

#include "hif.h"

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

/* Descriptor rings must be aligned to this boundary */
Expand Down Expand Up @@ -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);
int ath10k_ce_disable_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 */
/* Use NonSnooping PCIe accesses? */
Expand Down
84 changes: 81 additions & 3 deletions drivers/net/wireless/ath/ath10k/core.c
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,8 @@
#include <linux/module.h>
#include <linux/firmware.h>
#include <linux/of.h>
#include <linux/dmi.h>
#include <linux/ctype.h>
#include <asm/byteorder.h>

#include "core.h"
Expand Down Expand Up @@ -707,6 +709,72 @@ static int ath10k_core_get_board_id_from_otp(struct ath10k *ar)
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)
{
u32 result, address = ar->hw_params.patch_load_addr;
Expand Down Expand Up @@ -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,
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) {
scnprintf(name, name_len,
"bus=%s,bmi-chip-id=%d,bmi-board-id=%d",
Expand All @@ -1062,12 +1133,15 @@ static int ath10k_core_create_board_name(struct ath10k *ar, char *name,
goto out;
}

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

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),
ar->id.vendor, ar->id.device,
ar->id.subsystem_vendor, ar->id.subsystem_device);

ar->id.subsystem_vendor, ar->id.subsystem_device, variant);
out:
ath10k_dbg(ar, ATH10K_DBG_BOOT, "boot using board name '%s'\n", name);

Expand Down Expand Up @@ -2128,6 +2202,10 @@ static int ath10k_core_probe_fw(struct ath10k *ar)
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);
if (ret) {
ath10k_err(ar, "failed to fetch board file: %d\n", ret);
Expand Down
36 changes: 36 additions & 0 deletions drivers/net/wireless/ath/ath10k/core.h
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,23 @@
#define ATH10K_NAPI_BUDGET 64
#define ATH10K_NAPI_QUOTA_LIMIT 60

/* SMBIOS type containing Board Data File Name Extension */
#define ATH10K_SMBIOS_BDF_EXT_TYPE 0xF8

/* SMBIOS type structure length (excluding strings-set) */
#define ATH10K_SMBIOS_BDF_EXT_LENGTH 0x9

/* Offset pointing to Board Data File Name Extension */
#define ATH10K_SMBIOS_BDF_EXT_OFFSET 0x8

/* Board Data File Name Extension string length.
* String format: BDF_<Customer ID>_<Extension>\0
*/
#define ATH10K_SMBIOS_BDF_EXT_STR_LENGTH 0x20

/* The magic used by QCA spec */
#define ATH10K_SMBIOS_BDF_EXT_MAGIC "BDF_"

struct ath10k;

enum ath10k_bus {
Expand Down Expand Up @@ -314,6 +331,7 @@ struct ath10k_peer {
struct ieee80211_vif *vif;
struct ieee80211_sta *sta;

bool removed;
int vdev_id;
u8 addr[ETH_ALEN];
DECLARE_BITMAP(peer_ids, ATH10K_MAX_NUM_PEER_IDS);
Expand Down Expand Up @@ -419,13 +437,29 @@ struct ath10k_vif_iter {
struct ath10k_vif *arvif;
};

/* Copy Engine register dump, protected by ce-lock */
struct ath10k_ce_crash_data {
__le32 base_addr;
__le32 src_wr_idx;
__le32 src_r_idx;
__le32 dst_wr_idx;
__le32 dst_r_idx;
};

struct ath10k_ce_crash_hdr {
__le32 ce_count;
__le32 reserved[3]; /* for future use */
struct ath10k_ce_crash_data entries[];
};

/* used for crash-dump storage, protected by data-lock */
struct ath10k_fw_crash_data {
bool crashed_since_read;

uuid_le uuid;
struct timespec timestamp;
__le32 registers[REG_DUMP_COUNT_QCA988X];
struct ath10k_ce_crash_data ce_crash_data[CE_COUNT_MAX];
};

struct ath10k_debug {
Expand Down Expand Up @@ -781,6 +815,8 @@ struct ath10k {
bool bmi_ids_valid;
u8 bmi_board_id;
u8 bmi_chip_id;

char bdf_ext[ATH10K_SMBIOS_BDF_EXT_STR_LENGTH];
} id;

int fw_api;
Expand Down
Loading

0 comments on commit 889711a

Please sign in to comment.