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 -----BEGIN PGP SIGNATURE----- Version: GnuPG v1 iQEcBAABAgAGBQJYkafBAAoJEG4XJFUm622b0EAH/3mFY0WDfdR/Ych29HX1M/Ao Bd5gQfKzHS8ANR56qqmxEbpLdBnBa8iNC0IS4RFsWVv6qMoEEOHDLeY5W9XsomWK i45fQN2XIdjBUOyDXUjsyz006cMe79VzRvFf9gfSekP8i8BCWQzyYC8VKt/F+6Sh yo9yA4Yv3zA3mA3yRKtxSjLm/6xUXCFVNshKGT0rXc/oEfIN6OnIC1k0p0xw2hhl GyLN6PSGOqcJc91+IoGOg4TaHzPdWJcWatuxGdQn8gKSDg0+gXaNh9Gtf4H/ojqp Fwt2Ckk5mgJYk/2TAuFRpRXNMTJznUhp4Tjp2AE7EVM0f5JujUbQuPblOVfLIYk= =vKKN -----END PGP SIGNATURE----- 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: David S. Miller <davem@davemloft.net>
This commit is contained in:
commit
889711a03e
@ -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
|
||||
|
@ -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;
|
||||
@ -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)
|
||||
{
|
||||
@ -169,7 +169,7 @@ 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;
|
||||
|
||||
@ -177,13 +177,13 @@ static int bcma_of_irq_parse(struct platform_device *parent,
|
||||
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);
|
||||
@ -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;
|
||||
@ -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;
|
||||
@ -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;
|
||||
@ -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;
|
||||
}
|
||||
@ -647,6 +651,7 @@ static int bcma_device_remove(struct device *dev)
|
||||
|
||||
if (adrv->remove)
|
||||
adrv->remove(core);
|
||||
put_device(dev);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -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);
|
||||
@ -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);
|
||||
@ -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);
|
||||
}
|
||||
|
@ -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 */
|
||||
@ -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? */
|
||||
|
@ -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"
|
||||
@ -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;
|
||||
@ -1053,6 +1121,9 @@ err:
|
||||
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",
|
||||
@ -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);
|
||||
|
||||
@ -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);
|
||||
|
@ -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 {
|
||||
@ -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);
|
||||
@ -419,6 +437,21 @@ 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;
|
||||
@ -426,6 +459,7 @@ struct ath10k_fw_crash_data {
|
||||
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 {
|
||||
@ -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;
|
||||
|
@ -41,6 +41,7 @@
|
||||
*/
|
||||
enum ath10k_fw_crash_dump_type {
|
||||
ATH10K_FW_CRASH_DUMP_REGISTERS = 0,
|
||||
ATH10K_FW_CRASH_DUMP_CE_DATA = 1,
|
||||
|
||||
ATH10K_FW_CRASH_DUMP_MAX,
|
||||
};
|
||||
@ -400,6 +401,7 @@ void ath10k_debug_fw_stats_process(struct ath10k *ar, struct sk_buff *skb)
|
||||
* prevent firmware from DoS-ing the host.
|
||||
*/
|
||||
ath10k_fw_stats_peers_free(&ar->debug.fw_stats.peers);
|
||||
ath10k_fw_extd_stats_peers_free(&ar->debug.fw_stats.peers_extd);
|
||||
ath10k_warn(ar, "dropping fw peer stats\n");
|
||||
goto free;
|
||||
}
|
||||
@ -410,10 +412,12 @@ void ath10k_debug_fw_stats_process(struct ath10k *ar, struct sk_buff *skb)
|
||||
goto free;
|
||||
}
|
||||
|
||||
if (!list_empty(&stats.peers))
|
||||
list_splice_tail_init(&stats.peers_extd,
|
||||
&ar->debug.fw_stats.peers_extd);
|
||||
|
||||
list_splice_tail_init(&stats.peers, &ar->debug.fw_stats.peers);
|
||||
list_splice_tail_init(&stats.vdevs, &ar->debug.fw_stats.vdevs);
|
||||
list_splice_tail_init(&stats.peers_extd,
|
||||
&ar->debug.fw_stats.peers_extd);
|
||||
}
|
||||
|
||||
complete(&ar->debug.fw_stats_complete);
|
||||
@ -726,6 +730,7 @@ static struct ath10k_dump_file_data *ath10k_build_dump_file(struct ath10k *ar,
|
||||
bool mark_read)
|
||||
{
|
||||
struct ath10k_fw_crash_data *crash_data = ar->debug.fw_crash_data;
|
||||
struct ath10k_ce_crash_hdr *ce_hdr;
|
||||
struct ath10k_dump_file_data *dump_data;
|
||||
struct ath10k_tlv_dump_data *dump_tlv;
|
||||
int hdr_len = sizeof(*dump_data);
|
||||
@ -734,6 +739,8 @@ static struct ath10k_dump_file_data *ath10k_build_dump_file(struct ath10k *ar,
|
||||
|
||||
len = hdr_len;
|
||||
len += sizeof(*dump_tlv) + sizeof(crash_data->registers);
|
||||
len += sizeof(*dump_tlv) + sizeof(*ce_hdr) +
|
||||
CE_COUNT * sizeof(ce_hdr->entries[0]);
|
||||
|
||||
sofar += hdr_len;
|
||||
|
||||
@ -792,6 +799,18 @@ static struct ath10k_dump_file_data *ath10k_build_dump_file(struct ath10k *ar,
|
||||
sizeof(crash_data->registers));
|
||||
sofar += sizeof(*dump_tlv) + sizeof(crash_data->registers);
|
||||
|
||||
dump_tlv = (struct ath10k_tlv_dump_data *)(buf + sofar);
|
||||
dump_tlv->type = cpu_to_le32(ATH10K_FW_CRASH_DUMP_CE_DATA);
|
||||
dump_tlv->tlv_len = cpu_to_le32(sizeof(*ce_hdr) +
|
||||
CE_COUNT * sizeof(ce_hdr->entries[0]));
|
||||
ce_hdr = (struct ath10k_ce_crash_hdr *)(dump_tlv->tlv_data);
|
||||
ce_hdr->ce_count = cpu_to_le32(CE_COUNT);
|
||||
memset(ce_hdr->reserved, 0, sizeof(ce_hdr->reserved));
|
||||
memcpy(ce_hdr->entries, crash_data->ce_crash_data,
|
||||
CE_COUNT * sizeof(ce_hdr->entries[0]));
|
||||
sofar += sizeof(*dump_tlv) + sizeof(*ce_hdr) +
|
||||
CE_COUNT * sizeof(ce_hdr->entries[0]);
|
||||
|
||||
ar->debug.fw_crash_data->crashed_since_read = !mark_read;
|
||||
|
||||
spin_unlock_bh(&ar->data_lock);
|
||||
|
@ -474,33 +474,16 @@ static void ath10k_htc_reset_endpoint_states(struct ath10k_htc *htc)
|
||||
}
|
||||
}
|
||||
|
||||
static void ath10k_htc_setup_target_buffer_assignments(struct ath10k_htc *htc)
|
||||
{
|
||||
struct ath10k_htc_svc_tx_credits *entry;
|
||||
|
||||
entry = &htc->service_tx_alloc[0];
|
||||
|
||||
/*
|
||||
* for PCIE allocate all credists/HTC buffers to WMI.
|
||||
* no buffers are used/required for data. data always
|
||||
* remains on host.
|
||||
*/
|
||||
entry++;
|
||||
entry->service_id = ATH10K_HTC_SVC_ID_WMI_CONTROL;
|
||||
entry->credit_allocation = htc->total_transmit_credits;
|
||||
}
|
||||
|
||||
static u8 ath10k_htc_get_credit_allocation(struct ath10k_htc *htc,
|
||||
u16 service_id)
|
||||
{
|
||||
u8 allocation = 0;
|
||||
int i;
|
||||
|
||||
for (i = 0; i < ATH10K_HTC_EP_COUNT; i++) {
|
||||
if (htc->service_tx_alloc[i].service_id == service_id)
|
||||
allocation =
|
||||
htc->service_tx_alloc[i].credit_allocation;
|
||||
}
|
||||
/* The WMI control service is the only service with flow control.
|
||||
* Let it have all transmit credits.
|
||||
*/
|
||||
if (service_id == ATH10K_HTC_SVC_ID_WMI_CONTROL)
|
||||
allocation = htc->total_transmit_credits;
|
||||
|
||||
return allocation;
|
||||
}
|
||||
@ -574,8 +557,6 @@ int ath10k_htc_wait_target(struct ath10k_htc *htc)
|
||||
return -ECOMM;
|
||||
}
|
||||
|
||||
ath10k_htc_setup_target_buffer_assignments(htc);
|
||||
|
||||
/* setup our pseudo HTC control endpoint connection */
|
||||
memset(&conn_req, 0, sizeof(conn_req));
|
||||
memset(&conn_resp, 0, sizeof(conn_resp));
|
||||
@ -726,12 +707,6 @@ setup:
|
||||
ep->max_tx_queue_depth = conn_req->max_send_queue_depth;
|
||||
ep->max_ep_message_len = __le16_to_cpu(resp_msg->max_msg_size);
|
||||
ep->tx_credits = tx_alloc;
|
||||
ep->tx_credit_size = htc->target_credit_size;
|
||||
ep->tx_credits_per_max_message = ep->max_ep_message_len /
|
||||
htc->target_credit_size;
|
||||
|
||||
if (ep->max_ep_message_len % htc->target_credit_size)
|
||||
ep->tx_credits_per_max_message++;
|
||||
|
||||
/* copy all the callbacks */
|
||||
ep->ep_ops = conn_req->ep_ops;
|
||||
|
@ -314,8 +314,6 @@ struct ath10k_htc_ep {
|
||||
|
||||
u8 seq_no; /* for debugging */
|
||||
int tx_credits;
|
||||
int tx_credit_size;
|
||||
int tx_credits_per_max_message;
|
||||
bool tx_credit_flow_enabled;
|
||||
};
|
||||
|
||||
@ -339,7 +337,6 @@ struct ath10k_htc {
|
||||
struct completion ctl_resp;
|
||||
|
||||
int total_transmit_credits;
|
||||
struct ath10k_htc_svc_tx_credits service_tx_alloc[ATH10K_HTC_EP_COUNT];
|
||||
int target_credit_size;
|
||||
};
|
||||
|
||||
|
@ -702,6 +702,10 @@ static void ath10k_htt_rx_h_rates(struct ath10k *ar,
|
||||
/* 80MHZ */
|
||||
case 2:
|
||||
status->vht_flag |= RX_VHT_FLAG_80MHZ;
|
||||
break;
|
||||
case 3:
|
||||
status->vht_flag |= RX_VHT_FLAG_160MHZ;
|
||||
break;
|
||||
}
|
||||
|
||||
status->flag |= RX_FLAG_VHT;
|
||||
@ -926,7 +930,7 @@ static void ath10k_process_rx(struct ath10k *ar,
|
||||
*status = *rx_status;
|
||||
|
||||
ath10k_dbg(ar, ATH10K_DBG_DATA,
|
||||
"rx skb %pK len %u peer %pM %s %s sn %u %s%s%s%s%s %srate_idx %u vht_nss %u freq %u band %u flag 0x%llx fcs-err %i mic-err %i amsdu-more %i\n",
|
||||
"rx skb %pK len %u peer %pM %s %s sn %u %s%s%s%s%s%s %srate_idx %u vht_nss %u freq %u band %u flag 0x%llx fcs-err %i mic-err %i amsdu-more %i\n",
|
||||
skb,
|
||||
skb->len,
|
||||
ieee80211_get_SA(hdr),
|
||||
@ -940,6 +944,7 @@ static void ath10k_process_rx(struct ath10k *ar,
|
||||
status->flag & RX_FLAG_VHT ? "vht" : "",
|
||||
status->flag & RX_FLAG_40MHZ ? "40" : "",
|
||||
status->vht_flag & RX_VHT_FLAG_80MHZ ? "80" : "",
|
||||
status->vht_flag & RX_VHT_FLAG_160MHZ ? "160" : "",
|
||||
status->flag & RX_FLAG_SHORT_GI ? "sgi " : "",
|
||||
status->rate_idx,
|
||||
status->vht_nss,
|
||||
@ -2231,6 +2236,8 @@ ath10k_update_per_peer_tx_stats(struct ath10k *ar,
|
||||
return;
|
||||
}
|
||||
|
||||
memset(&arsta->txrate, 0, sizeof(arsta->txrate));
|
||||
|
||||
if (txrate.flags == WMI_RATE_PREAMBLE_CCK ||
|
||||
txrate.flags == WMI_RATE_PREAMBLE_OFDM) {
|
||||
rate = ATH10K_HW_LEGACY_RATE(peer_stats->ratecode);
|
||||
@ -2245,7 +2252,7 @@ ath10k_update_per_peer_tx_stats(struct ath10k *ar,
|
||||
rate *= 10;
|
||||
if (rate == 60 && txrate.flags == WMI_RATE_PREAMBLE_CCK)
|
||||
rate = rate - 5;
|
||||
arsta->txrate.legacy = rate * 10;
|
||||
arsta->txrate.legacy = rate;
|
||||
} else if (txrate.flags == WMI_RATE_PREAMBLE_HT) {
|
||||
arsta->txrate.flags = RATE_INFO_FLAGS_MCS;
|
||||
arsta->txrate.mcs = txrate.mcs;
|
||||
|
@ -578,6 +578,9 @@ ath10k_rx_desc_get_l3_pad_bytes(struct ath10k_hw_params *hw,
|
||||
#define TARGET_10_4_IPHDR_PAD_CONFIG 1
|
||||
#define TARGET_10_4_QWRAP_CONFIG 0
|
||||
|
||||
/* Maximum number of Copy Engine's supported */
|
||||
#define CE_COUNT_MAX 12
|
||||
|
||||
/* Number of Copy Engines supported */
|
||||
#define CE_COUNT ar->hw_values->ce_count
|
||||
|
||||
|
@ -569,10 +569,14 @@ chan_to_phymode(const struct cfg80211_chan_def *chandef)
|
||||
case NL80211_CHAN_WIDTH_80:
|
||||
phymode = MODE_11AC_VHT80;
|
||||
break;
|
||||
case NL80211_CHAN_WIDTH_160:
|
||||
phymode = MODE_11AC_VHT160;
|
||||
break;
|
||||
case NL80211_CHAN_WIDTH_80P80:
|
||||
phymode = MODE_11AC_VHT80_80;
|
||||
break;
|
||||
case NL80211_CHAN_WIDTH_5:
|
||||
case NL80211_CHAN_WIDTH_10:
|
||||
case NL80211_CHAN_WIDTH_80P80:
|
||||
case NL80211_CHAN_WIDTH_160:
|
||||
phymode = MODE_UNKNOWN;
|
||||
break;
|
||||
}
|
||||
@ -971,6 +975,7 @@ static int ath10k_monitor_vdev_start(struct ath10k *ar, int vdev_id)
|
||||
arg.vdev_id = vdev_id;
|
||||
arg.channel.freq = channel->center_freq;
|
||||
arg.channel.band_center_freq1 = chandef->center_freq1;
|
||||
arg.channel.band_center_freq2 = chandef->center_freq2;
|
||||
|
||||
/* TODO setup this dynamically, what in case we
|
||||
don't have any vifs? */
|
||||
@ -1417,6 +1422,7 @@ static int ath10k_vdev_start_restart(struct ath10k_vif *arvif,
|
||||
|
||||
arg.channel.freq = chandef->chan->center_freq;
|
||||
arg.channel.band_center_freq1 = chandef->center_freq1;
|
||||
arg.channel.band_center_freq2 = chandef->center_freq2;
|
||||
arg.channel.mode = chan_to_phymode(chandef);
|
||||
|
||||
arg.channel.min_power = 0;
|
||||
@ -2480,6 +2486,9 @@ static void ath10k_peer_assoc_h_vht(struct ath10k *ar,
|
||||
if (sta->bandwidth == IEEE80211_STA_RX_BW_80)
|
||||
arg->peer_flags |= ar->wmi.peer_flags->bw80;
|
||||
|
||||
if (sta->bandwidth == IEEE80211_STA_RX_BW_160)
|
||||
arg->peer_flags |= ar->wmi.peer_flags->bw160;
|
||||
|
||||
arg->peer_vht_rates.rx_max_rate =
|
||||
__le16_to_cpu(vht_cap->vht_mcs.rx_highest);
|
||||
arg->peer_vht_rates.rx_mcs_set =
|
||||
@ -2533,6 +2542,33 @@ static bool ath10k_mac_sta_has_ofdm_only(struct ieee80211_sta *sta)
|
||||
ATH10K_MAC_FIRST_OFDM_RATE_IDX;
|
||||
}
|
||||
|
||||
static enum wmi_phy_mode ath10k_mac_get_phymode_vht(struct ath10k *ar,
|
||||
struct ieee80211_sta *sta)
|
||||
{
|
||||
if (sta->bandwidth == IEEE80211_STA_RX_BW_160) {
|
||||
switch (sta->vht_cap.cap & IEEE80211_VHT_CAP_SUPP_CHAN_WIDTH_MASK) {
|
||||
case IEEE80211_VHT_CAP_SUPP_CHAN_WIDTH_160MHZ:
|
||||
return MODE_11AC_VHT160;
|
||||
case IEEE80211_VHT_CAP_SUPP_CHAN_WIDTH_160_80PLUS80MHZ:
|
||||
return MODE_11AC_VHT80_80;
|
||||
default:
|
||||
/* not sure if this is a valid case? */
|
||||
return MODE_11AC_VHT160;
|
||||
}
|
||||
}
|
||||
|
||||
if (sta->bandwidth == IEEE80211_STA_RX_BW_80)
|
||||
return MODE_11AC_VHT80;
|
||||
|
||||
if (sta->bandwidth == IEEE80211_STA_RX_BW_40)
|
||||
return MODE_11AC_VHT40;
|
||||
|
||||
if (sta->bandwidth == IEEE80211_STA_RX_BW_20)
|
||||
return MODE_11AC_VHT20;
|
||||
|
||||
return MODE_UNKNOWN;
|
||||
}
|
||||
|
||||
static void ath10k_peer_assoc_h_phymode(struct ath10k *ar,
|
||||
struct ieee80211_vif *vif,
|
||||
struct ieee80211_sta *sta,
|
||||
@ -2579,12 +2615,7 @@ static void ath10k_peer_assoc_h_phymode(struct ath10k *ar,
|
||||
*/
|
||||
if (sta->vht_cap.vht_supported &&
|
||||
!ath10k_peer_assoc_h_vht_masked(vht_mcs_mask)) {
|
||||
if (sta->bandwidth == IEEE80211_STA_RX_BW_80)
|
||||
phymode = MODE_11AC_VHT80;
|
||||
else if (sta->bandwidth == IEEE80211_STA_RX_BW_40)
|
||||
phymode = MODE_11AC_VHT40;
|
||||
else if (sta->bandwidth == IEEE80211_STA_RX_BW_20)
|
||||
phymode = MODE_11AC_VHT20;
|
||||
phymode = ath10k_mac_get_phymode_vht(ar, sta);
|
||||
} else if (sta->ht_cap.ht_supported &&
|
||||
!ath10k_peer_assoc_h_ht_masked(ht_mcs_mask)) {
|
||||
if (sta->bandwidth >= IEEE80211_STA_RX_BW_40)
|
||||
@ -3774,6 +3805,9 @@ struct ieee80211_txq *ath10k_mac_txq_lookup(struct ath10k *ar,
|
||||
if (!peer)
|
||||
return NULL;
|
||||
|
||||
if (peer->removed)
|
||||
return NULL;
|
||||
|
||||
if (peer->sta)
|
||||
return peer->sta->txq[tid];
|
||||
else if (peer->vif)
|
||||
@ -4311,6 +4345,13 @@ static struct ieee80211_sta_vht_cap ath10k_create_vht_cap(struct ath10k *ar)
|
||||
vht_cap.cap |= val;
|
||||
}
|
||||
|
||||
/* Currently the firmware seems to be buggy, don't enable 80+80
|
||||
* mode until that's resolved.
|
||||
*/
|
||||
if ((ar->vht_cap_info & IEEE80211_VHT_CAP_SHORT_GI_160) &&
|
||||
!(ar->vht_cap_info & IEEE80211_VHT_CAP_SUPP_CHAN_WIDTH_160_80PLUS80MHZ))
|
||||
vht_cap.cap |= IEEE80211_VHT_CAP_SUPP_CHAN_WIDTH_160MHZ;
|
||||
|
||||
mcs_map = 0;
|
||||
for (i = 0; i < 8; i++) {
|
||||
if ((i < ar->num_rf_chains) && (ar->cfg_tx_chainmask & BIT(i)))
|
||||
@ -6969,6 +7010,9 @@ static void ath10k_sta_rc_update(struct ieee80211_hw *hw,
|
||||
bw = WMI_PEER_CHWIDTH_80MHZ;
|
||||
break;
|
||||
case IEEE80211_STA_RX_BW_160:
|
||||
bw = WMI_PEER_CHWIDTH_160MHZ;
|
||||
break;
|
||||
default:
|
||||
ath10k_warn(ar, "Invalid bandwidth %d in rc update for %pM\n",
|
||||
sta->bandwidth, sta->addr);
|
||||
bw = WMI_PEER_CHWIDTH_20MHZ;
|
||||
@ -7476,6 +7520,20 @@ ath10k_mac_op_switch_vif_chanctx(struct ieee80211_hw *hw,
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void ath10k_mac_op_sta_pre_rcu_remove(struct ieee80211_hw *hw,
|
||||
struct ieee80211_vif *vif,
|
||||
struct ieee80211_sta *sta)
|
||||
{
|
||||
struct ath10k *ar;
|
||||
struct ath10k_peer *peer;
|
||||
|
||||
ar = hw->priv;
|
||||
|
||||
list_for_each_entry(peer, &ar->peers, list)
|
||||
if (peer->sta == sta)
|
||||
peer->removed = true;
|
||||
}
|
||||
|
||||
static const struct ieee80211_ops ath10k_ops = {
|
||||
.tx = ath10k_mac_op_tx,
|
||||
.wake_tx_queue = ath10k_mac_op_wake_tx_queue,
|
||||
@ -7516,6 +7574,7 @@ static const struct ieee80211_ops ath10k_ops = {
|
||||
.assign_vif_chanctx = ath10k_mac_op_assign_vif_chanctx,
|
||||
.unassign_vif_chanctx = ath10k_mac_op_unassign_vif_chanctx,
|
||||
.switch_vif_chanctx = ath10k_mac_op_switch_vif_chanctx,
|
||||
.sta_pre_rcu_remove = ath10k_mac_op_sta_pre_rcu_remove,
|
||||
|
||||
CFG80211_TESTMODE_CMD(ath10k_tm_cmd)
|
||||
|
||||
|
@ -896,7 +896,7 @@ static int ath10k_pci_diag_read_mem(struct ath10k *ar, u32 address, void *data,
|
||||
*/
|
||||
alloc_nbytes = min_t(unsigned int, nbytes, DIAG_TRANSFER_LIMIT);
|
||||
|
||||
data_buf = (unsigned char *)dma_alloc_coherent(ar->dev,
|
||||
data_buf = (unsigned char *)dma_zalloc_coherent(ar->dev,
|
||||
alloc_nbytes,
|
||||
&ce_data_base,
|
||||
GFP_ATOMIC);
|
||||
@ -905,7 +905,6 @@ static int ath10k_pci_diag_read_mem(struct ath10k *ar, u32 address, void *data,
|
||||
ret = -ENOMEM;
|
||||
goto done;
|
||||
}
|
||||
memset(data_buf, 0, alloc_nbytes);
|
||||
|
||||
remaining_bytes = nbytes;
|
||||
ce_data = ce_data_base;
|
||||
@ -1474,6 +1473,7 @@ static void ath10k_pci_fw_crashed_dump(struct ath10k *ar)
|
||||
ath10k_err(ar, "firmware crashed! (uuid %s)\n", uuid);
|
||||
ath10k_print_driver_info(ar);
|
||||
ath10k_pci_dump_registers(ar, crash_data);
|
||||
ath10k_ce_dump_registers(ar, crash_data);
|
||||
|
||||
spin_unlock_bh(&ar->data_lock);
|
||||
|
||||
@ -1937,7 +1937,7 @@ static int ath10k_pci_wake_target_cpu(struct ath10k *ar)
|
||||
{
|
||||
u32 addr, val;
|
||||
|
||||
addr = SOC_CORE_BASE_ADDRESS | CORE_CTRL_ADDRESS;
|
||||
addr = SOC_CORE_BASE_ADDRESS + CORE_CTRL_ADDRESS;
|
||||
val = ath10k_pci_read32(ar, addr);
|
||||
val |= CORE_CTRL_CPU_INTR_MASK;
|
||||
ath10k_pci_write32(ar, addr, val);
|
||||
|
@ -24,11 +24,6 @@
|
||||
#include "ce.h"
|
||||
#include "ahb.h"
|
||||
|
||||
/*
|
||||
* maximum number of bytes that can be handled atomically by DiagRead/DiagWrite
|
||||
*/
|
||||
#define DIAG_TRANSFER_LIMIT 2048
|
||||
|
||||
/*
|
||||
* maximum number of bytes that can be
|
||||
* handled atomically by DiagRead/DiagWrite
|
||||
|
@ -3637,6 +3637,7 @@ static const struct wmi_peer_flags_map wmi_tlv_peer_flags_map = {
|
||||
.vht = WMI_TLV_PEER_VHT,
|
||||
.bw80 = WMI_TLV_PEER_80MHZ,
|
||||
.pmf = WMI_TLV_PEER_PMF,
|
||||
.bw160 = WMI_TLV_PEER_160MHZ,
|
||||
};
|
||||
|
||||
/************/
|
||||
|
@ -543,6 +543,7 @@ enum wmi_tlv_peer_flags {
|
||||
WMI_TLV_PEER_VHT = 0x02000000,
|
||||
WMI_TLV_PEER_80MHZ = 0x04000000,
|
||||
WMI_TLV_PEER_PMF = 0x08000000,
|
||||
WMI_TLV_PEER_160MHZ = 0x20000000,
|
||||
};
|
||||
|
||||
enum wmi_tlv_tag {
|
||||
|
@ -28,6 +28,7 @@
|
||||
#include "wmi-ops.h"
|
||||
#include "p2p.h"
|
||||
#include "hw.h"
|
||||
#include "hif.h"
|
||||
|
||||
#define ATH10K_WMI_BARRIER_ECHO_ID 0xBA991E9
|
||||
#define ATH10K_WMI_BARRIER_TIMEOUT_HZ (3 * HZ)
|
||||
@ -1574,6 +1575,7 @@ static const struct wmi_peer_flags_map wmi_peer_flags_map = {
|
||||
.bw80 = WMI_PEER_80MHZ,
|
||||
.vht_2g = WMI_PEER_VHT_2G,
|
||||
.pmf = WMI_PEER_PMF,
|
||||
.bw160 = WMI_PEER_160MHZ,
|
||||
};
|
||||
|
||||
static const struct wmi_peer_flags_map wmi_10x_peer_flags_map = {
|
||||
@ -1591,6 +1593,7 @@ static const struct wmi_peer_flags_map wmi_10x_peer_flags_map = {
|
||||
.spatial_mux = WMI_10X_PEER_SPATIAL_MUX,
|
||||
.vht = WMI_10X_PEER_VHT,
|
||||
.bw80 = WMI_10X_PEER_80MHZ,
|
||||
.bw160 = WMI_10X_PEER_160MHZ,
|
||||
};
|
||||
|
||||
static const struct wmi_peer_flags_map wmi_10_2_peer_flags_map = {
|
||||
@ -1610,6 +1613,7 @@ static const struct wmi_peer_flags_map wmi_10_2_peer_flags_map = {
|
||||
.bw80 = WMI_10_2_PEER_80MHZ,
|
||||
.vht_2g = WMI_10_2_PEER_VHT_2G,
|
||||
.pmf = WMI_10_2_PEER_PMF,
|
||||
.bw160 = WMI_10_2_PEER_160MHZ,
|
||||
};
|
||||
|
||||
void ath10k_wmi_put_wmi_channel(struct wmi_channel *ch,
|
||||
@ -1634,7 +1638,10 @@ void ath10k_wmi_put_wmi_channel(struct wmi_channel *ch,
|
||||
|
||||
ch->mhz = __cpu_to_le32(arg->freq);
|
||||
ch->band_center_freq1 = __cpu_to_le32(arg->band_center_freq1);
|
||||
ch->band_center_freq2 = 0;
|
||||
if (arg->mode == MODE_11AC_VHT80_80)
|
||||
ch->band_center_freq2 = __cpu_to_le32(arg->band_center_freq2);
|
||||
else
|
||||
ch->band_center_freq2 = 0;
|
||||
ch->min_power = arg->min_power;
|
||||
ch->max_power = arg->max_power;
|
||||
ch->reg_power = arg->max_reg_power;
|
||||
@ -2319,7 +2326,7 @@ int ath10k_wmi_event_mgmt_rx(struct ath10k *ar, struct sk_buff *skb)
|
||||
*/
|
||||
if (channel >= 1 && channel <= 14) {
|
||||
status->band = NL80211_BAND_2GHZ;
|
||||
} else if (channel >= 36 && channel <= 165) {
|
||||
} else if (channel >= 36 && channel <= 169) {
|
||||
status->band = NL80211_BAND_5GHZ;
|
||||
} else {
|
||||
/* Shouldn't happen unless list of advertised channels to
|
||||
|
@ -1728,8 +1728,10 @@ enum wmi_phy_mode {
|
||||
MODE_11AC_VHT20_2G = 11,
|
||||
MODE_11AC_VHT40_2G = 12,
|
||||
MODE_11AC_VHT80_2G = 13,
|
||||
MODE_UNKNOWN = 14,
|
||||
MODE_MAX = 14
|
||||
MODE_11AC_VHT80_80 = 14,
|
||||
MODE_11AC_VHT160 = 15,
|
||||
MODE_UNKNOWN = 16,
|
||||
MODE_MAX = 16
|
||||
};
|
||||
|
||||
static inline const char *ath10k_wmi_phymode_str(enum wmi_phy_mode mode)
|
||||
@ -1757,6 +1759,10 @@ static inline const char *ath10k_wmi_phymode_str(enum wmi_phy_mode mode)
|
||||
return "11ac-vht40";
|
||||
case MODE_11AC_VHT80:
|
||||
return "11ac-vht80";
|
||||
case MODE_11AC_VHT160:
|
||||
return "11ac-vht160";
|
||||
case MODE_11AC_VHT80_80:
|
||||
return "11ac-vht80+80";
|
||||
case MODE_11AC_VHT20_2G:
|
||||
return "11ac-vht20-2g";
|
||||
case MODE_11AC_VHT40_2G:
|
||||
@ -1811,6 +1817,7 @@ struct wmi_channel {
|
||||
struct wmi_channel_arg {
|
||||
u32 freq;
|
||||
u32 band_center_freq1;
|
||||
u32 band_center_freq2;
|
||||
bool passive;
|
||||
bool allow_ibss;
|
||||
bool allow_ht;
|
||||
@ -1875,9 +1882,18 @@ enum wmi_channel_change_cause {
|
||||
#define WMI_VHT_CAP_MAX_MPDU_LEN_MASK 0x00000003
|
||||
#define WMI_VHT_CAP_RX_LDPC 0x00000010
|
||||
#define WMI_VHT_CAP_SGI_80MHZ 0x00000020
|
||||
#define WMI_VHT_CAP_SGI_160MHZ 0x00000040
|
||||
#define WMI_VHT_CAP_TX_STBC 0x00000080
|
||||
#define WMI_VHT_CAP_RX_STBC_MASK 0x00000300
|
||||
#define WMI_VHT_CAP_RX_STBC_MASK_SHIFT 8
|
||||
#define WMI_VHT_CAP_SU_BFER 0x00000800
|
||||
#define WMI_VHT_CAP_SU_BFEE 0x00001000
|
||||
#define WMI_VHT_CAP_MAX_CS_ANT_MASK 0x0000E000
|
||||
#define WMI_VHT_CAP_MAX_CS_ANT_MASK_SHIFT 13
|
||||
#define WMI_VHT_CAP_MAX_SND_DIM_MASK 0x00070000
|
||||
#define WMI_VHT_CAP_MAX_SND_DIM_MASK_SHIFT 16
|
||||
#define WMI_VHT_CAP_MU_BFER 0x00080000
|
||||
#define WMI_VHT_CAP_MU_BFEE 0x00100000
|
||||
#define WMI_VHT_CAP_MAX_AMPDU_LEN_EXP 0x03800000
|
||||
#define WMI_VHT_CAP_MAX_AMPDU_LEN_EXP_SHIFT 23
|
||||
#define WMI_VHT_CAP_RX_FIXED_ANT 0x10000000
|
||||
@ -1926,6 +1942,8 @@ enum {
|
||||
REGDMN_MODE_11AC_VHT40PLUS = 0x40000, /* 5Ghz, VHT40 + channels */
|
||||
REGDMN_MODE_11AC_VHT40MINUS = 0x80000, /* 5Ghz VHT40 - channels */
|
||||
REGDMN_MODE_11AC_VHT80 = 0x100000, /* 5Ghz, VHT80 channels */
|
||||
REGDMN_MODE_11AC_VHT160 = 0x200000, /* 5Ghz, VHT160 channels */
|
||||
REGDMN_MODE_11AC_VHT80_80 = 0x400000, /* 5Ghz, VHT80+80 channels */
|
||||
REGDMN_MODE_ALL = 0xffffffff
|
||||
};
|
||||
|
||||
@ -5783,6 +5801,7 @@ enum wmi_peer_chwidth {
|
||||
WMI_PEER_CHWIDTH_20MHZ = 0,
|
||||
WMI_PEER_CHWIDTH_40MHZ = 1,
|
||||
WMI_PEER_CHWIDTH_80MHZ = 2,
|
||||
WMI_PEER_CHWIDTH_160MHZ = 3,
|
||||
};
|
||||
|
||||
enum wmi_peer_param {
|
||||
@ -5873,6 +5892,7 @@ struct wmi_peer_flags_map {
|
||||
u32 bw80;
|
||||
u32 vht_2g;
|
||||
u32 pmf;
|
||||
u32 bw160;
|
||||
};
|
||||
|
||||
enum wmi_peer_flags {
|
||||
@ -5892,6 +5912,7 @@ enum wmi_peer_flags {
|
||||
WMI_PEER_80MHZ = 0x04000000,
|
||||
WMI_PEER_VHT_2G = 0x08000000,
|
||||
WMI_PEER_PMF = 0x10000000,
|
||||
WMI_PEER_160MHZ = 0x20000000
|
||||
};
|
||||
|
||||
enum wmi_10x_peer_flags {
|
||||
@ -5909,6 +5930,7 @@ enum wmi_10x_peer_flags {
|
||||
WMI_10X_PEER_SPATIAL_MUX = 0x00200000,
|
||||
WMI_10X_PEER_VHT = 0x02000000,
|
||||
WMI_10X_PEER_80MHZ = 0x04000000,
|
||||
WMI_10X_PEER_160MHZ = 0x20000000
|
||||
};
|
||||
|
||||
enum wmi_10_2_peer_flags {
|
||||
@ -5928,6 +5950,7 @@ enum wmi_10_2_peer_flags {
|
||||
WMI_10_2_PEER_80MHZ = 0x04000000,
|
||||
WMI_10_2_PEER_VHT_2G = 0x08000000,
|
||||
WMI_10_2_PEER_PMF = 0x10000000,
|
||||
WMI_10_2_PEER_160MHZ = 0x20000000
|
||||
};
|
||||
|
||||
/*
|
||||
|
@ -502,8 +502,7 @@ ath5k_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd,
|
||||
break;
|
||||
return -EOPNOTSUPP;
|
||||
default:
|
||||
WARN_ON(1);
|
||||
return -EINVAL;
|
||||
return -EOPNOTSUPP;
|
||||
}
|
||||
|
||||
mutex_lock(&ah->lock);
|
||||
|
@ -713,7 +713,7 @@ static void ath6kl_sdio_cleanup_scatter(struct ath6kl *ar)
|
||||
* that the packet is properly freed?
|
||||
*/
|
||||
if (s_req->busrequest) {
|
||||
s_req->busrequest->scat_req = 0;
|
||||
s_req->busrequest->scat_req = NULL;
|
||||
ath6kl_sdio_free_bus_req(ar_sdio, s_req->busrequest);
|
||||
}
|
||||
kfree(s_req->virt_dma_buf);
|
||||
|
@ -3,8 +3,8 @@ config ATH9K_HW
|
||||
config ATH9K_COMMON
|
||||
tristate
|
||||
select ATH_COMMON
|
||||
select DEBUG_FS
|
||||
select RELAY
|
||||
config ATH9K_COMMON_DEBUG
|
||||
bool
|
||||
config ATH9K_DFS_DEBUGFS
|
||||
def_bool y
|
||||
depends on ATH9K_DEBUGFS && ATH9K_DFS_CERTIFIED
|
||||
@ -60,12 +60,14 @@ config ATH9K_DEBUGFS
|
||||
bool "Atheros ath9k debugging"
|
||||
depends on ATH9K && DEBUG_FS
|
||||
select MAC80211_DEBUGFS
|
||||
select ATH9K_COMMON_DEBUG
|
||||
select RELAY
|
||||
---help---
|
||||
Say Y, if you need access to ath9k's statistics for
|
||||
interrupts, rate control, etc.
|
||||
|
||||
Also required for changing debug message flags at run time.
|
||||
As well as access to the FFT/spectral data and TX99.
|
||||
|
||||
config ATH9K_STATION_STATISTICS
|
||||
bool "Detailed station statistics"
|
||||
@ -174,8 +176,11 @@ config ATH9K_HTC
|
||||
config ATH9K_HTC_DEBUGFS
|
||||
bool "Atheros ath9k_htc debugging"
|
||||
depends on ATH9K_HTC && DEBUG_FS
|
||||
select ATH9K_COMMON_DEBUG
|
||||
select RELAY
|
||||
---help---
|
||||
Say Y, if you need access to ath9k_htc's statistics.
|
||||
As well as access to the FFT/spectral data.
|
||||
|
||||
config ATH9K_HWRNG
|
||||
bool "Random number generator support"
|
||||
|
@ -60,8 +60,9 @@ obj-$(CONFIG_ATH9K_COMMON) += ath9k_common.o
|
||||
ath9k_common-y:= common.o \
|
||||
common-init.o \
|
||||
common-beacon.o \
|
||||
common-debug.o \
|
||||
common-spectral.o
|
||||
|
||||
ath9k_common-$(CONFIG_ATH9K_COMMON_DEBUG) += common-debug.o \
|
||||
common-spectral.o
|
||||
|
||||
ath9k_htc-y += htc_hst.o \
|
||||
hif_usb.o \
|
||||
|
@ -220,8 +220,8 @@ ar9002_set_txdesc(struct ath_hw *ah, void *ds, struct ath_tx_info *i)
|
||||
ads->ds_txstatus6 = ads->ds_txstatus7 = 0;
|
||||
ads->ds_txstatus8 = ads->ds_txstatus9 = 0;
|
||||
|
||||
ACCESS_ONCE(ads->ds_link) = i->link;
|
||||
ACCESS_ONCE(ads->ds_data) = i->buf_addr[0];
|
||||
WRITE_ONCE(ads->ds_link, i->link);
|
||||
WRITE_ONCE(ads->ds_data, i->buf_addr[0]);
|
||||
|
||||
ctl1 = i->buf_len[0] | (i->is_last ? 0 : AR_TxMore);
|
||||
ctl6 = SM(i->keytype, AR_EncrType);
|
||||
@ -235,26 +235,26 @@ ar9002_set_txdesc(struct ath_hw *ah, void *ds, struct ath_tx_info *i)
|
||||
|
||||
if ((i->is_first || i->is_last) &&
|
||||
i->aggr != AGGR_BUF_MIDDLE && i->aggr != AGGR_BUF_LAST) {
|
||||
ACCESS_ONCE(ads->ds_ctl2) = set11nTries(i->rates, 0)
|
||||
WRITE_ONCE(ads->ds_ctl2, set11nTries(i->rates, 0)
|
||||
| set11nTries(i->rates, 1)
|
||||
| set11nTries(i->rates, 2)
|
||||
| set11nTries(i->rates, 3)
|
||||
| (i->dur_update ? AR_DurUpdateEna : 0)
|
||||
| SM(0, AR_BurstDur);
|
||||
| SM(0, AR_BurstDur));
|
||||
|
||||
ACCESS_ONCE(ads->ds_ctl3) = set11nRate(i->rates, 0)
|
||||
WRITE_ONCE(ads->ds_ctl3, set11nRate(i->rates, 0)
|
||||
| set11nRate(i->rates, 1)
|
||||
| set11nRate(i->rates, 2)
|
||||
| set11nRate(i->rates, 3);
|
||||
| set11nRate(i->rates, 3));
|
||||
} else {
|
||||
ACCESS_ONCE(ads->ds_ctl2) = 0;
|
||||
ACCESS_ONCE(ads->ds_ctl3) = 0;
|
||||
WRITE_ONCE(ads->ds_ctl2, 0);
|
||||
WRITE_ONCE(ads->ds_ctl3, 0);
|
||||
}
|
||||
|
||||
if (!i->is_first) {
|
||||
ACCESS_ONCE(ads->ds_ctl0) = 0;
|
||||
ACCESS_ONCE(ads->ds_ctl1) = ctl1;
|
||||
ACCESS_ONCE(ads->ds_ctl6) = ctl6;
|
||||
WRITE_ONCE(ads->ds_ctl0, 0);
|
||||
WRITE_ONCE(ads->ds_ctl1, ctl1);
|
||||
WRITE_ONCE(ads->ds_ctl6, ctl6);
|
||||
return;
|
||||
}
|
||||
|
||||
@ -279,7 +279,7 @@ ar9002_set_txdesc(struct ath_hw *ah, void *ds, struct ath_tx_info *i)
|
||||
break;
|
||||
}
|
||||
|
||||
ACCESS_ONCE(ads->ds_ctl0) = (i->pkt_len & AR_FrameLen)
|
||||
WRITE_ONCE(ads->ds_ctl0, (i->pkt_len & AR_FrameLen)
|
||||
| (i->flags & ATH9K_TXDESC_VMF ? AR_VirtMoreFrag : 0)
|
||||
| SM(i->txpower[0], AR_XmitPower0)
|
||||
| (i->flags & ATH9K_TXDESC_VEOL ? AR_VEOL : 0)
|
||||
@ -287,29 +287,29 @@ ar9002_set_txdesc(struct ath_hw *ah, void *ds, struct ath_tx_info *i)
|
||||
| (i->keyix != ATH9K_TXKEYIX_INVALID ? AR_DestIdxValid : 0)
|
||||
| (i->flags & ATH9K_TXDESC_CLRDMASK ? AR_ClrDestMask : 0)
|
||||
| (i->flags & ATH9K_TXDESC_RTSENA ? AR_RTSEnable :
|
||||
(i->flags & ATH9K_TXDESC_CTSENA ? AR_CTSEnable : 0));
|
||||
(i->flags & ATH9K_TXDESC_CTSENA ? AR_CTSEnable : 0)));
|
||||
|
||||
ACCESS_ONCE(ads->ds_ctl1) = ctl1;
|
||||
ACCESS_ONCE(ads->ds_ctl6) = ctl6;
|
||||
WRITE_ONCE(ads->ds_ctl1, ctl1);
|
||||
WRITE_ONCE(ads->ds_ctl6, ctl6);
|
||||
|
||||
if (i->aggr == AGGR_BUF_MIDDLE || i->aggr == AGGR_BUF_LAST)
|
||||
return;
|
||||
|
||||
ACCESS_ONCE(ads->ds_ctl4) = set11nPktDurRTSCTS(i->rates, 0)
|
||||
| set11nPktDurRTSCTS(i->rates, 1);
|
||||
WRITE_ONCE(ads->ds_ctl4, set11nPktDurRTSCTS(i->rates, 0)
|
||||
| set11nPktDurRTSCTS(i->rates, 1));
|
||||
|
||||
ACCESS_ONCE(ads->ds_ctl5) = set11nPktDurRTSCTS(i->rates, 2)
|
||||
| set11nPktDurRTSCTS(i->rates, 3);
|
||||
WRITE_ONCE(ads->ds_ctl5, set11nPktDurRTSCTS(i->rates, 2)
|
||||
| set11nPktDurRTSCTS(i->rates, 3));
|
||||
|
||||
ACCESS_ONCE(ads->ds_ctl7) = set11nRateFlags(i->rates, 0)
|
||||
WRITE_ONCE(ads->ds_ctl7, set11nRateFlags(i->rates, 0)
|
||||
| set11nRateFlags(i->rates, 1)
|
||||
| set11nRateFlags(i->rates, 2)
|
||||
| set11nRateFlags(i->rates, 3)
|
||||
| SM(i->rtscts_rate, AR_RTSCTSRate);
|
||||
| SM(i->rtscts_rate, AR_RTSCTSRate));
|
||||
|
||||
ACCESS_ONCE(ads->ds_ctl9) = SM(i->txpower[1], AR_XmitPower1);
|
||||
ACCESS_ONCE(ads->ds_ctl10) = SM(i->txpower[2], AR_XmitPower2);
|
||||
ACCESS_ONCE(ads->ds_ctl11) = SM(i->txpower[3], AR_XmitPower3);
|
||||
WRITE_ONCE(ads->ds_ctl9, SM(i->txpower[1], AR_XmitPower1));
|
||||
WRITE_ONCE(ads->ds_ctl10, SM(i->txpower[2], AR_XmitPower2));
|
||||
WRITE_ONCE(ads->ds_ctl11, SM(i->txpower[3], AR_XmitPower3));
|
||||
}
|
||||
|
||||
static int ar9002_hw_proc_txdesc(struct ath_hw *ah, void *ds,
|
||||
@ -318,7 +318,7 @@ static int ar9002_hw_proc_txdesc(struct ath_hw *ah, void *ds,
|
||||
struct ar5416_desc *ads = AR5416DESC(ds);
|
||||
u32 status;
|
||||
|
||||
status = ACCESS_ONCE(ads->ds_txstatus9);
|
||||
status = READ_ONCE(ads->ds_txstatus9);
|
||||
if ((status & AR_TxDone) == 0)
|
||||
return -EINPROGRESS;
|
||||
|
||||
@ -332,7 +332,7 @@ static int ar9002_hw_proc_txdesc(struct ath_hw *ah, void *ds,
|
||||
ts->ts_rateindex = MS(status, AR_FinalTxIdx);
|
||||
ts->ts_seqnum = MS(status, AR_SeqNum);
|
||||
|
||||
status = ACCESS_ONCE(ads->ds_txstatus0);
|
||||
status = READ_ONCE(ads->ds_txstatus0);
|
||||
ts->ts_rssi_ctl0 = MS(status, AR_TxRSSIAnt00);
|
||||
ts->ts_rssi_ctl1 = MS(status, AR_TxRSSIAnt01);
|
||||
ts->ts_rssi_ctl2 = MS(status, AR_TxRSSIAnt02);
|
||||
@ -342,7 +342,7 @@ static int ar9002_hw_proc_txdesc(struct ath_hw *ah, void *ds,
|
||||
ts->ba_high = ads->AR_BaBitmapHigh;
|
||||
}
|
||||
|
||||
status = ACCESS_ONCE(ads->ds_txstatus1);
|
||||
status = READ_ONCE(ads->ds_txstatus1);
|
||||
if (status & AR_FrmXmitOK)
|
||||
ts->ts_status |= ATH9K_TX_ACKED;
|
||||
else {
|
||||
@ -371,7 +371,7 @@ static int ar9002_hw_proc_txdesc(struct ath_hw *ah, void *ds,
|
||||
ts->ts_longretry = MS(status, AR_DataFailCnt);
|
||||
ts->ts_virtcol = MS(status, AR_VirtRetryCnt);
|
||||
|
||||
status = ACCESS_ONCE(ads->ds_txstatus5);
|
||||
status = READ_ONCE(ads->ds_txstatus5);
|
||||
ts->ts_rssi = MS(status, AR_TxRSSICombined);
|
||||
ts->ts_rssi_ext0 = MS(status, AR_TxRSSIAnt10);
|
||||
ts->ts_rssi_ext1 = MS(status, AR_TxRSSIAnt11);
|
||||
@ -390,13 +390,13 @@ static int ar9002_hw_get_duration(struct ath_hw *ah, const void *ds, int index)
|
||||
|
||||
switch (index) {
|
||||
case 0:
|
||||
return MS(ACCESS_ONCE(ads->ds_ctl4), AR_PacketDur0);
|
||||
return MS(READ_ONCE(ads->ds_ctl4), AR_PacketDur0);
|
||||
case 1:
|
||||
return MS(ACCESS_ONCE(ads->ds_ctl4), AR_PacketDur1);
|
||||
return MS(READ_ONCE(ads->ds_ctl4), AR_PacketDur1);
|
||||
case 2:
|
||||
return MS(ACCESS_ONCE(ads->ds_ctl5), AR_PacketDur2);
|
||||
return MS(READ_ONCE(ads->ds_ctl5), AR_PacketDur2);
|
||||
case 3:
|
||||
return MS(ACCESS_ONCE(ads->ds_ctl5), AR_PacketDur3);
|
||||
return MS(READ_ONCE(ads->ds_ctl5), AR_PacketDur3);
|
||||
default:
|
||||
return -1;
|
||||
}
|
||||
|
@ -39,47 +39,47 @@ ar9003_set_txdesc(struct ath_hw *ah, void *ds, struct ath_tx_info *i)
|
||||
(i->qcu << AR_TxQcuNum_S) | desc_len;
|
||||
|
||||
checksum += val;
|
||||
ACCESS_ONCE(ads->info) = val;
|
||||
WRITE_ONCE(ads->info, val);
|
||||
|
||||
checksum += i->link;
|
||||
ACCESS_ONCE(ads->link) = i->link;
|
||||
WRITE_ONCE(ads->link, i->link);
|
||||
|
||||
checksum += i->buf_addr[0];
|
||||
ACCESS_ONCE(ads->data0) = i->buf_addr[0];
|
||||
WRITE_ONCE(ads->data0, i->buf_addr[0]);
|
||||
checksum += i->buf_addr[1];
|
||||
ACCESS_ONCE(ads->data1) = i->buf_addr[1];
|
||||
WRITE_ONCE(ads->data1, i->buf_addr[1]);
|
||||
checksum += i->buf_addr[2];
|
||||
ACCESS_ONCE(ads->data2) = i->buf_addr[2];
|
||||
WRITE_ONCE(ads->data2, i->buf_addr[2]);
|
||||
checksum += i->buf_addr[3];
|
||||
ACCESS_ONCE(ads->data3) = i->buf_addr[3];
|
||||
WRITE_ONCE(ads->data3, i->buf_addr[3]);
|
||||
|
||||
checksum += (val = (i->buf_len[0] << AR_BufLen_S) & AR_BufLen);
|
||||
ACCESS_ONCE(ads->ctl3) = val;
|
||||
WRITE_ONCE(ads->ctl3, val);
|
||||
checksum += (val = (i->buf_len[1] << AR_BufLen_S) & AR_BufLen);
|
||||
ACCESS_ONCE(ads->ctl5) = val;
|
||||
WRITE_ONCE(ads->ctl5, val);
|
||||
checksum += (val = (i->buf_len[2] << AR_BufLen_S) & AR_BufLen);
|
||||
ACCESS_ONCE(ads->ctl7) = val;
|
||||
WRITE_ONCE(ads->ctl7, val);
|
||||
checksum += (val = (i->buf_len[3] << AR_BufLen_S) & AR_BufLen);
|
||||
ACCESS_ONCE(ads->ctl9) = val;
|
||||
WRITE_ONCE(ads->ctl9, val);
|
||||
|
||||
checksum = (u16) (((checksum & 0xffff) + (checksum >> 16)) & 0xffff);
|
||||
ACCESS_ONCE(ads->ctl10) = checksum;
|
||||
WRITE_ONCE(ads->ctl10, checksum);
|
||||
|
||||
if (i->is_first || i->is_last) {
|
||||
ACCESS_ONCE(ads->ctl13) = set11nTries(i->rates, 0)
|
||||
WRITE_ONCE(ads->ctl13, set11nTries(i->rates, 0)
|
||||
| set11nTries(i->rates, 1)
|
||||
| set11nTries(i->rates, 2)
|
||||
| set11nTries(i->rates, 3)
|
||||
| (i->dur_update ? AR_DurUpdateEna : 0)
|
||||
| SM(0, AR_BurstDur);
|
||||
| SM(0, AR_BurstDur));
|
||||
|
||||
ACCESS_ONCE(ads->ctl14) = set11nRate(i->rates, 0)
|
||||
WRITE_ONCE(ads->ctl14, set11nRate(i->rates, 0)
|
||||
| set11nRate(i->rates, 1)
|
||||
| set11nRate(i->rates, 2)
|
||||
| set11nRate(i->rates, 3);
|
||||
| set11nRate(i->rates, 3));
|
||||
} else {
|
||||
ACCESS_ONCE(ads->ctl13) = 0;
|
||||
ACCESS_ONCE(ads->ctl14) = 0;
|
||||
WRITE_ONCE(ads->ctl13, 0);
|
||||
WRITE_ONCE(ads->ctl14, 0);
|
||||
}
|
||||
|
||||
ads->ctl20 = 0;
|
||||
@ -89,17 +89,17 @@ ar9003_set_txdesc(struct ath_hw *ah, void *ds, struct ath_tx_info *i)
|
||||
|
||||
ctl17 = SM(i->keytype, AR_EncrType);
|
||||
if (!i->is_first) {
|
||||
ACCESS_ONCE(ads->ctl11) = 0;
|
||||
ACCESS_ONCE(ads->ctl12) = i->is_last ? 0 : AR_TxMore;
|
||||
ACCESS_ONCE(ads->ctl15) = 0;
|
||||
ACCESS_ONCE(ads->ctl16) = 0;
|
||||
ACCESS_ONCE(ads->ctl17) = ctl17;
|
||||
ACCESS_ONCE(ads->ctl18) = 0;
|
||||
ACCESS_ONCE(ads->ctl19) = 0;
|
||||
WRITE_ONCE(ads->ctl11, 0);
|
||||
WRITE_ONCE(ads->ctl12, i->is_last ? 0 : AR_TxMore);
|
||||
WRITE_ONCE(ads->ctl15, 0);
|
||||
WRITE_ONCE(ads->ctl16, 0);
|
||||
WRITE_ONCE(ads->ctl17, ctl17);
|
||||
WRITE_ONCE(ads->ctl18, 0);
|
||||
WRITE_ONCE(ads->ctl19, 0);
|
||||
return;
|
||||
}
|
||||
|
||||
ACCESS_ONCE(ads->ctl11) = (i->pkt_len & AR_FrameLen)
|
||||
WRITE_ONCE(ads->ctl11, (i->pkt_len & AR_FrameLen)
|
||||
| (i->flags & ATH9K_TXDESC_VMF ? AR_VirtMoreFrag : 0)
|
||||
| SM(i->txpower[0], AR_XmitPower0)
|
||||
| (i->flags & ATH9K_TXDESC_VEOL ? AR_VEOL : 0)
|
||||
@ -107,7 +107,7 @@ ar9003_set_txdesc(struct ath_hw *ah, void *ds, struct ath_tx_info *i)
|
||||
| (i->flags & ATH9K_TXDESC_LOWRXCHAIN ? AR_LowRxChain : 0)
|
||||
| (i->flags & ATH9K_TXDESC_CLRDMASK ? AR_ClrDestMask : 0)
|
||||
| (i->flags & ATH9K_TXDESC_RTSENA ? AR_RTSEnable :
|
||||
(i->flags & ATH9K_TXDESC_CTSENA ? AR_CTSEnable : 0));
|
||||
(i->flags & ATH9K_TXDESC_CTSENA ? AR_CTSEnable : 0)));
|
||||
|
||||
ctl12 = (i->keyix != ATH9K_TXKEYIX_INVALID ?
|
||||
SM(i->keyix, AR_DestIdx) : 0)
|
||||
@ -135,26 +135,26 @@ ar9003_set_txdesc(struct ath_hw *ah, void *ds, struct ath_tx_info *i)
|
||||
val = (i->flags & ATH9K_TXDESC_PAPRD) >> ATH9K_TXDESC_PAPRD_S;
|
||||
ctl12 |= SM(val, AR_PAPRDChainMask);
|
||||
|
||||
ACCESS_ONCE(ads->ctl12) = ctl12;
|
||||
ACCESS_ONCE(ads->ctl17) = ctl17;
|
||||
WRITE_ONCE(ads->ctl12, ctl12);
|
||||
WRITE_ONCE(ads->ctl17, ctl17);
|
||||
|
||||
ACCESS_ONCE(ads->ctl15) = set11nPktDurRTSCTS(i->rates, 0)
|
||||
| set11nPktDurRTSCTS(i->rates, 1);
|
||||
WRITE_ONCE(ads->ctl15, set11nPktDurRTSCTS(i->rates, 0)
|
||||
| set11nPktDurRTSCTS(i->rates, 1));
|
||||
|
||||
ACCESS_ONCE(ads->ctl16) = set11nPktDurRTSCTS(i->rates, 2)
|
||||
| set11nPktDurRTSCTS(i->rates, 3);
|
||||
WRITE_ONCE(ads->ctl16, set11nPktDurRTSCTS(i->rates, 2)
|
||||
| set11nPktDurRTSCTS(i->rates, 3));
|
||||
|
||||
ACCESS_ONCE(ads->ctl18) = set11nRateFlags(i->rates, 0)
|
||||
WRITE_ONCE(ads->ctl18, set11nRateFlags(i->rates, 0)
|
||||
| set11nRateFlags(i->rates, 1)
|
||||
| set11nRateFlags(i->rates, 2)
|
||||
| set11nRateFlags(i->rates, 3)
|
||||
| SM(i->rtscts_rate, AR_RTSCTSRate);
|
||||
| SM(i->rtscts_rate, AR_RTSCTSRate));
|
||||
|
||||
ACCESS_ONCE(ads->ctl19) = AR_Not_Sounding;
|
||||
WRITE_ONCE(ads->ctl19, AR_Not_Sounding);
|
||||
|
||||
ACCESS_ONCE(ads->ctl20) = SM(i->txpower[1], AR_XmitPower1);
|
||||
ACCESS_ONCE(ads->ctl21) = SM(i->txpower[2], AR_XmitPower2);
|
||||
ACCESS_ONCE(ads->ctl22) = SM(i->txpower[3], AR_XmitPower3);
|
||||
WRITE_ONCE(ads->ctl20, SM(i->txpower[1], AR_XmitPower1));
|
||||
WRITE_ONCE(ads->ctl21, SM(i->txpower[2], AR_XmitPower2));
|
||||
WRITE_ONCE(ads->ctl22, SM(i->txpower[3], AR_XmitPower3));
|
||||
}
|
||||
|
||||
static u16 ar9003_calc_ptr_chksum(struct ar9003_txc *ads)
|
||||
@ -359,7 +359,7 @@ static int ar9003_hw_proc_txdesc(struct ath_hw *ah, void *ds,
|
||||
|
||||
ads = &ah->ts_ring[ah->ts_tail];
|
||||
|
||||
status = ACCESS_ONCE(ads->status8);
|
||||
status = READ_ONCE(ads->status8);
|
||||
if ((status & AR_TxDone) == 0)
|
||||
return -EINPROGRESS;
|
||||
|
||||
@ -385,7 +385,7 @@ static int ar9003_hw_proc_txdesc(struct ath_hw *ah, void *ds,
|
||||
|
||||
if (status & AR_TxOpExceeded)
|
||||
ts->ts_status |= ATH9K_TXERR_XTXOP;
|
||||
status = ACCESS_ONCE(ads->status2);
|
||||
status = READ_ONCE(ads->status2);
|
||||
ts->ts_rssi_ctl0 = MS(status, AR_TxRSSIAnt00);
|
||||
ts->ts_rssi_ctl1 = MS(status, AR_TxRSSIAnt01);
|
||||
ts->ts_rssi_ctl2 = MS(status, AR_TxRSSIAnt02);
|
||||
@ -395,7 +395,7 @@ static int ar9003_hw_proc_txdesc(struct ath_hw *ah, void *ds,
|
||||
ts->ba_high = ads->status6;
|
||||
}
|
||||
|
||||
status = ACCESS_ONCE(ads->status3);
|
||||
status = READ_ONCE(ads->status3);
|
||||
if (status & AR_ExcessiveRetries)
|
||||
ts->ts_status |= ATH9K_TXERR_XRETRY;
|
||||
if (status & AR_Filtered)
|
||||
@ -420,7 +420,7 @@ static int ar9003_hw_proc_txdesc(struct ath_hw *ah, void *ds,
|
||||
ts->ts_longretry = MS(status, AR_DataFailCnt);
|
||||
ts->ts_virtcol = MS(status, AR_VirtRetryCnt);
|
||||
|
||||
status = ACCESS_ONCE(ads->status7);
|
||||
status = READ_ONCE(ads->status7);
|
||||
ts->ts_rssi = MS(status, AR_TxRSSICombined);
|
||||
ts->ts_rssi_ext0 = MS(status, AR_TxRSSIAnt10);
|
||||
ts->ts_rssi_ext1 = MS(status, AR_TxRSSIAnt11);
|
||||
@ -437,13 +437,13 @@ static int ar9003_hw_get_duration(struct ath_hw *ah, const void *ds, int index)
|
||||
|
||||
switch (index) {
|
||||
case 0:
|
||||
return MS(ACCESS_ONCE(adc->ctl15), AR_PacketDur0);
|
||||
return MS(READ_ONCE(adc->ctl15), AR_PacketDur0);
|
||||
case 1:
|
||||
return MS(ACCESS_ONCE(adc->ctl15), AR_PacketDur1);
|
||||
return MS(READ_ONCE(adc->ctl15), AR_PacketDur1);
|
||||
case 2:
|
||||
return MS(ACCESS_ONCE(adc->ctl16), AR_PacketDur2);
|
||||
return MS(READ_ONCE(adc->ctl16), AR_PacketDur2);
|
||||
case 3:
|
||||
return MS(ACCESS_ONCE(adc->ctl16), AR_PacketDur3);
|
||||
return MS(READ_ONCE(adc->ctl16), AR_PacketDur3);
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
|
@ -60,6 +60,7 @@ struct ath_rx_stats {
|
||||
u32 rx_spectral;
|
||||
};
|
||||
|
||||
#ifdef CONFIG_ATH9K_COMMON_DEBUG
|
||||
void ath9k_cmn_debug_modal_eeprom(struct dentry *debugfs_phy,
|
||||
struct ath_hw *ah);
|
||||
void ath9k_cmn_debug_base_eeprom(struct dentry *debugfs_phy,
|
||||
@ -70,3 +71,29 @@ void ath9k_cmn_debug_recv(struct dentry *debugfs_phy,
|
||||
struct ath_rx_stats *rxstats);
|
||||
void ath9k_cmn_debug_phy_err(struct dentry *debugfs_phy,
|
||||
struct ath_rx_stats *rxstats);
|
||||
#else
|
||||
static inline void ath9k_cmn_debug_modal_eeprom(struct dentry *debugfs_phy,
|
||||
struct ath_hw *ah)
|
||||
{
|
||||
}
|
||||
|
||||
static inline void ath9k_cmn_debug_base_eeprom(struct dentry *debugfs_phy,
|
||||
struct ath_hw *ah)
|
||||
{
|
||||
}
|
||||
|
||||
static inline void ath9k_cmn_debug_stat_rx(struct ath_rx_stats *rxstats,
|
||||
struct ath_rx_status *rs)
|
||||
{
|
||||
}
|
||||
|
||||
static inline void ath9k_cmn_debug_recv(struct dentry *debugfs_phy,
|
||||
struct ath_rx_stats *rxstats)
|
||||
{
|
||||
}
|
||||
|
||||
static inline void ath9k_cmn_debug_phy_err(struct dentry *debugfs_phy,
|
||||
struct ath_rx_stats *rxstats)
|
||||
{
|
||||
}
|
||||
#endif /* CONFIG_ATH9K_COMMON_DEBUG */
|
||||
|
@ -1075,7 +1075,7 @@ static struct rchan_callbacks rfs_spec_scan_cb = {
|
||||
|
||||
void ath9k_cmn_spectral_deinit_debug(struct ath_spec_scan_priv *spec_priv)
|
||||
{
|
||||
if (IS_ENABLED(CONFIG_ATH9K_DEBUGFS) && spec_priv->rfs_chan_spec_scan) {
|
||||
if (spec_priv->rfs_chan_spec_scan) {
|
||||
relay_close(spec_priv->rfs_chan_spec_scan);
|
||||
spec_priv->rfs_chan_spec_scan = NULL;
|
||||
}
|
||||
|
@ -151,6 +151,7 @@ static inline u8 spectral_bitmap_weight(u8 *bins)
|
||||
return bins[0] & 0x3f;
|
||||
}
|
||||
|
||||
#ifdef CONFIG_ATH9K_COMMON_DEBUG
|
||||
void ath9k_cmn_spectral_init_debug(struct ath_spec_scan_priv *spec_priv, struct dentry *debugfs_phy);
|
||||
void ath9k_cmn_spectral_deinit_debug(struct ath_spec_scan_priv *spec_priv);
|
||||
|
||||
@ -161,5 +162,27 @@ int ath9k_cmn_spectral_scan_config(struct ath_common *common,
|
||||
enum spectral_mode spectral_mode);
|
||||
int ath_cmn_process_fft(struct ath_spec_scan_priv *spec_priv, struct ieee80211_hdr *hdr,
|
||||
struct ath_rx_status *rs, u64 tsf);
|
||||
#else
|
||||
static inline void ath9k_cmn_spectral_init_debug(struct ath_spec_scan_priv *spec_priv,
|
||||
struct dentry *debugfs_phy)
|
||||
{
|
||||
}
|
||||
|
||||
static inline void ath9k_cmn_spectral_deinit_debug(struct ath_spec_scan_priv *spec_priv)
|
||||
{
|
||||
}
|
||||
|
||||
static inline void ath9k_cmn_spectral_scan_trigger(struct ath_common *common,
|
||||
struct ath_spec_scan_priv *spec_priv)
|
||||
{
|
||||
}
|
||||
|
||||
static inline int ath_cmn_process_fft(struct ath_spec_scan_priv *spec_priv,
|
||||
struct ieee80211_hdr *hdr,
|
||||
struct ath_rx_status *rs, u64 tsf)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
#endif /* CONFIG_ATH9K_COMMON_DEBUG */
|
||||
|
||||
#endif /* SPECTRAL_H */
|
||||
|
@ -72,7 +72,7 @@ static bool ath9k_hw_4k_fill_eeprom(struct ath_hw *ah)
|
||||
return __ath9k_hw_4k_fill_eeprom(ah);
|
||||
}
|
||||
|
||||
#if defined(CONFIG_ATH9K_DEBUGFS) || defined(CONFIG_ATH9K_HTC_DEBUGFS)
|
||||
#ifdef CONFIG_ATH9K_COMMON_DEBUG
|
||||
static u32 ath9k_dump_4k_modal_eeprom(char *buf, u32 len, u32 size,
|
||||
struct modal_eep_4k_header *modal_hdr)
|
||||
{
|
||||
|
@ -75,7 +75,7 @@ static bool ath9k_hw_ar9287_fill_eeprom(struct ath_hw *ah)
|
||||
return __ath9k_hw_ar9287_fill_eeprom(ah);
|
||||
}
|
||||
|
||||
#if defined(CONFIG_ATH9K_DEBUGFS) || defined(CONFIG_ATH9K_HTC_DEBUGFS)
|
||||
#ifdef CONFIG_ATH9K_COMMON_DEBUG
|
||||
static u32 ar9287_dump_modal_eeprom(char *buf, u32 len, u32 size,
|
||||
struct modal_eep_ar9287_header *modal_hdr)
|
||||
{
|
||||
|
@ -131,7 +131,7 @@ static bool ath9k_hw_def_fill_eeprom(struct ath_hw *ah)
|
||||
return __ath9k_hw_def_fill_eeprom(ah);
|
||||
}
|
||||
|
||||
#if defined(CONFIG_ATH9K_DEBUGFS) || defined(CONFIG_ATH9K_HTC_DEBUGFS)
|
||||
#ifdef CONFIG_ATH9K_COMMON_DEBUG
|
||||
static u32 ath9k_def_dump_modal_eeprom(char *buf, u32 len, u32 size,
|
||||
struct modal_eep_header *modal_hdr)
|
||||
{
|
||||
|
@ -731,7 +731,7 @@ u32 ar9003_get_pll_sqsum_dvc(struct ath_hw *ah)
|
||||
udelay(100);
|
||||
|
||||
if (WARN_ON_ONCE(i >= 100)) {
|
||||
ath_err(common, "PLL4 meaurement not done\n");
|
||||
ath_err(common, "PLL4 measurement not done\n");
|
||||
break;
|
||||
}
|
||||
|
||||
|
@ -1,6 +1,8 @@
|
||||
config WCN36XX
|
||||
tristate "Qualcomm Atheros WCN3660/3680 support"
|
||||
depends on MAC80211 && HAS_DMA
|
||||
depends on QCOM_WCNSS_CTRL || QCOM_WCNSS_CTRL=n
|
||||
depends on QCOM_SMD || QCOM_SMD=n
|
||||
---help---
|
||||
This module adds support for wireless adapters based on
|
||||
Qualcomm Atheros WCN3660 and WCN3680 mobile chipsets.
|
||||
|
@ -23,6 +23,7 @@
|
||||
#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
|
||||
|
||||
#include <linux/interrupt.h>
|
||||
#include <linux/soc/qcom/smem_state.h>
|
||||
#include "wcn36xx.h"
|
||||
#include "txrx.h"
|
||||
|
||||
@ -151,9 +152,12 @@ int wcn36xx_dxe_alloc_ctl_blks(struct wcn36xx *wcn)
|
||||
goto out_err;
|
||||
|
||||
/* Initialize SMSM state Clear TX Enable RING EMPTY STATE */
|
||||
ret = wcn->ctrl_ops->smsm_change_state(
|
||||
WCN36XX_SMSM_WLAN_TX_ENABLE,
|
||||
WCN36XX_SMSM_WLAN_TX_RINGS_EMPTY);
|
||||
ret = qcom_smem_state_update_bits(wcn->tx_enable_state,
|
||||
WCN36XX_SMSM_WLAN_TX_ENABLE |
|
||||
WCN36XX_SMSM_WLAN_TX_RINGS_EMPTY,
|
||||
WCN36XX_SMSM_WLAN_TX_RINGS_EMPTY);
|
||||
if (ret)
|
||||
goto out_err;
|
||||
|
||||
return 0;
|
||||
|
||||
@ -678,9 +682,9 @@ int wcn36xx_dxe_tx_frame(struct wcn36xx *wcn,
|
||||
* notify chip about new frame through SMSM bus.
|
||||
*/
|
||||
if (is_low && vif_priv->pw_state == WCN36XX_BMPS) {
|
||||
wcn->ctrl_ops->smsm_change_state(
|
||||
0,
|
||||
WCN36XX_SMSM_WLAN_TX_ENABLE);
|
||||
qcom_smem_state_update_bits(wcn->tx_rings_empty_state,
|
||||
WCN36XX_SMSM_WLAN_TX_ENABLE,
|
||||
WCN36XX_SMSM_WLAN_TX_ENABLE);
|
||||
} else {
|
||||
/* indicate End Of Packet and generate interrupt on descriptor
|
||||
* done.
|
||||
|
@ -350,6 +350,8 @@ enum wcn36xx_hal_host_msg_type {
|
||||
|
||||
WCN36XX_HAL_AVOID_FREQ_RANGE_IND = 233,
|
||||
|
||||
WCN36XX_HAL_PRINT_REG_INFO_IND = 259,
|
||||
|
||||
WCN36XX_HAL_MSG_MAX = WCN36XX_HAL_MSG_TYPE_MAX_ENUM_SIZE
|
||||
};
|
||||
|
||||
@ -4703,4 +4705,18 @@ struct stats_class_b_ind {
|
||||
u32 rx_time_total;
|
||||
};
|
||||
|
||||
/* WCN36XX_HAL_PRINT_REG_INFO_IND */
|
||||
struct wcn36xx_hal_print_reg_info_ind {
|
||||
struct wcn36xx_hal_msg_header header;
|
||||
|
||||
u32 count;
|
||||
u32 scenario;
|
||||
u32 reason;
|
||||
|
||||
struct {
|
||||
u32 addr;
|
||||
u32 value;
|
||||
} regs[];
|
||||
} __packed;
|
||||
|
||||
#endif /* _HAL_H_ */
|
||||
|
@ -21,6 +21,10 @@
|
||||
#include <linux/platform_device.h>
|
||||
#include <linux/of_address.h>
|
||||
#include <linux/of_device.h>
|
||||
#include <linux/of_irq.h>
|
||||
#include <linux/soc/qcom/smd.h>
|
||||
#include <linux/soc/qcom/smem_state.h>
|
||||
#include <linux/soc/qcom/wcnss_ctrl.h>
|
||||
#include "wcn36xx.h"
|
||||
|
||||
unsigned int wcn36xx_dbg_mask;
|
||||
@ -564,23 +568,59 @@ out:
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void wcn36xx_sw_scan_start(struct ieee80211_hw *hw,
|
||||
struct ieee80211_vif *vif,
|
||||
const u8 *mac_addr)
|
||||
static void wcn36xx_hw_scan_worker(struct work_struct *work)
|
||||
{
|
||||
struct wcn36xx *wcn = hw->priv;
|
||||
struct wcn36xx *wcn = container_of(work, struct wcn36xx, scan_work);
|
||||
struct cfg80211_scan_request *req = wcn->scan_req;
|
||||
u8 channels[WCN36XX_HAL_PNO_MAX_NETW_CHANNELS_EX];
|
||||
struct cfg80211_scan_info scan_info = {};
|
||||
int i;
|
||||
|
||||
wcn36xx_dbg(WCN36XX_DBG_MAC, "mac80211 scan %d channels worker\n", req->n_channels);
|
||||
|
||||
for (i = 0; i < req->n_channels; i++)
|
||||
channels[i] = req->channels[i]->hw_value;
|
||||
|
||||
wcn36xx_smd_update_scan_params(wcn, channels, req->n_channels);
|
||||
|
||||
wcn36xx_smd_init_scan(wcn, HAL_SYS_MODE_SCAN);
|
||||
wcn36xx_smd_start_scan(wcn);
|
||||
for (i = 0; i < req->n_channels; i++) {
|
||||
wcn->scan_freq = req->channels[i]->center_freq;
|
||||
wcn->scan_band = req->channels[i]->band;
|
||||
|
||||
wcn36xx_smd_start_scan(wcn, req->channels[i]->hw_value);
|
||||
msleep(30);
|
||||
wcn36xx_smd_end_scan(wcn, req->channels[i]->hw_value);
|
||||
|
||||
wcn->scan_freq = 0;
|
||||
}
|
||||
wcn36xx_smd_finish_scan(wcn, HAL_SYS_MODE_SCAN);
|
||||
|
||||
scan_info.aborted = false;
|
||||
ieee80211_scan_completed(wcn->hw, &scan_info);
|
||||
|
||||
mutex_lock(&wcn->scan_lock);
|
||||
wcn->scan_req = NULL;
|
||||
mutex_unlock(&wcn->scan_lock);
|
||||
}
|
||||
|
||||
static void wcn36xx_sw_scan_complete(struct ieee80211_hw *hw,
|
||||
struct ieee80211_vif *vif)
|
||||
static int wcn36xx_hw_scan(struct ieee80211_hw *hw,
|
||||
struct ieee80211_vif *vif,
|
||||
struct ieee80211_scan_request *hw_req)
|
||||
{
|
||||
struct wcn36xx *wcn = hw->priv;
|
||||
|
||||
wcn36xx_smd_end_scan(wcn);
|
||||
wcn36xx_smd_finish_scan(wcn, HAL_SYS_MODE_SCAN);
|
||||
mutex_lock(&wcn->scan_lock);
|
||||
if (wcn->scan_req) {
|
||||
mutex_unlock(&wcn->scan_lock);
|
||||
return -EBUSY;
|
||||
}
|
||||
wcn->scan_req = &hw_req->req;
|
||||
mutex_unlock(&wcn->scan_lock);
|
||||
|
||||
schedule_work(&wcn->scan_work);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void wcn36xx_update_allowed_rates(struct ieee80211_sta *sta,
|
||||
@ -993,8 +1033,7 @@ static const struct ieee80211_ops wcn36xx_ops = {
|
||||
.configure_filter = wcn36xx_configure_filter,
|
||||
.tx = wcn36xx_tx,
|
||||
.set_key = wcn36xx_set_key,
|
||||
.sw_scan_start = wcn36xx_sw_scan_start,
|
||||
.sw_scan_complete = wcn36xx_sw_scan_complete,
|
||||
.hw_scan = wcn36xx_hw_scan,
|
||||
.bss_info_changed = wcn36xx_bss_info_changed,
|
||||
.set_rts_threshold = wcn36xx_set_rts_threshold,
|
||||
.sta_add = wcn36xx_sta_add,
|
||||
@ -1019,6 +1058,7 @@ static int wcn36xx_init_ieee80211(struct wcn36xx *wcn)
|
||||
ieee80211_hw_set(wcn->hw, SUPPORTS_PS);
|
||||
ieee80211_hw_set(wcn->hw, SIGNAL_DBM);
|
||||
ieee80211_hw_set(wcn->hw, HAS_RATE_CONTROL);
|
||||
ieee80211_hw_set(wcn->hw, SINGLE_SCAN_ON_ALL_BANDS);
|
||||
|
||||
wcn->hw->wiphy->interface_modes = BIT(NL80211_IFTYPE_STATION) |
|
||||
BIT(NL80211_IFTYPE_AP) |
|
||||
@ -1028,6 +1068,9 @@ static int wcn36xx_init_ieee80211(struct wcn36xx *wcn)
|
||||
wcn->hw->wiphy->bands[NL80211_BAND_2GHZ] = &wcn_band_2ghz;
|
||||
wcn->hw->wiphy->bands[NL80211_BAND_5GHZ] = &wcn_band_5ghz;
|
||||
|
||||
wcn->hw->wiphy->max_scan_ssids = WCN36XX_MAX_SCAN_SSIDS;
|
||||
wcn->hw->wiphy->max_scan_ie_len = WCN36XX_MAX_SCAN_IE_LEN;
|
||||
|
||||
wcn->hw->wiphy->cipher_suites = cipher_suites;
|
||||
wcn->hw->wiphy->n_cipher_suites = ARRAY_SIZE(cipher_suites);
|
||||
|
||||
@ -1058,8 +1101,7 @@ static int wcn36xx_platform_get_resources(struct wcn36xx *wcn,
|
||||
int ret;
|
||||
|
||||
/* Set TX IRQ */
|
||||
res = platform_get_resource_byname(pdev, IORESOURCE_IRQ,
|
||||
"wcnss_wlantx_irq");
|
||||
res = platform_get_resource_byname(pdev, IORESOURCE_IRQ, "tx");
|
||||
if (!res) {
|
||||
wcn36xx_err("failed to get tx_irq\n");
|
||||
return -ENOENT;
|
||||
@ -1067,14 +1109,29 @@ static int wcn36xx_platform_get_resources(struct wcn36xx *wcn,
|
||||
wcn->tx_irq = res->start;
|
||||
|
||||
/* Set RX IRQ */
|
||||
res = platform_get_resource_byname(pdev, IORESOURCE_IRQ,
|
||||
"wcnss_wlanrx_irq");
|
||||
res = platform_get_resource_byname(pdev, IORESOURCE_IRQ, "rx");
|
||||
if (!res) {
|
||||
wcn36xx_err("failed to get rx_irq\n");
|
||||
return -ENOENT;
|
||||
}
|
||||
wcn->rx_irq = res->start;
|
||||
|
||||
/* Acquire SMSM tx enable handle */
|
||||
wcn->tx_enable_state = qcom_smem_state_get(&pdev->dev,
|
||||
"tx-enable", &wcn->tx_enable_state_bit);
|
||||
if (IS_ERR(wcn->tx_enable_state)) {
|
||||
wcn36xx_err("failed to get tx-enable state\n");
|
||||
return PTR_ERR(wcn->tx_enable_state);
|
||||
}
|
||||
|
||||
/* Acquire SMSM tx rings empty handle */
|
||||
wcn->tx_rings_empty_state = qcom_smem_state_get(&pdev->dev,
|
||||
"tx-rings-empty", &wcn->tx_rings_empty_state_bit);
|
||||
if (IS_ERR(wcn->tx_rings_empty_state)) {
|
||||
wcn36xx_err("failed to get tx-rings-empty state\n");
|
||||
return PTR_ERR(wcn->tx_rings_empty_state);
|
||||
}
|
||||
|
||||
mmio_node = of_parse_phandle(pdev->dev.parent->of_node, "qcom,mmio", 0);
|
||||
if (!mmio_node) {
|
||||
wcn36xx_err("failed to acquire qcom,mmio reference\n");
|
||||
@ -1115,11 +1172,14 @@ static int wcn36xx_probe(struct platform_device *pdev)
|
||||
{
|
||||
struct ieee80211_hw *hw;
|
||||
struct wcn36xx *wcn;
|
||||
void *wcnss;
|
||||
int ret;
|
||||
u8 addr[ETH_ALEN];
|
||||
const u8 *addr;
|
||||
|
||||
wcn36xx_dbg(WCN36XX_DBG_MAC, "platform probe\n");
|
||||
|
||||
wcnss = dev_get_drvdata(pdev->dev.parent);
|
||||
|
||||
hw = ieee80211_alloc_hw(sizeof(struct wcn36xx), &wcn36xx_ops);
|
||||
if (!hw) {
|
||||
wcn36xx_err("failed to alloc hw\n");
|
||||
@ -1130,11 +1190,26 @@ static int wcn36xx_probe(struct platform_device *pdev)
|
||||
wcn = hw->priv;
|
||||
wcn->hw = hw;
|
||||
wcn->dev = &pdev->dev;
|
||||
wcn->ctrl_ops = pdev->dev.platform_data;
|
||||
|
||||
mutex_init(&wcn->hal_mutex);
|
||||
mutex_init(&wcn->scan_lock);
|
||||
|
||||
if (!wcn->ctrl_ops->get_hw_mac(addr)) {
|
||||
INIT_WORK(&wcn->scan_work, wcn36xx_hw_scan_worker);
|
||||
|
||||
wcn->smd_channel = qcom_wcnss_open_channel(wcnss, "WLAN_CTRL", wcn36xx_smd_rsp_process);
|
||||
if (IS_ERR(wcn->smd_channel)) {
|
||||
wcn36xx_err("failed to open WLAN_CTRL channel\n");
|
||||
ret = PTR_ERR(wcn->smd_channel);
|
||||
goto out_wq;
|
||||
}
|
||||
|
||||
qcom_smd_set_drvdata(wcn->smd_channel, hw);
|
||||
|
||||
addr = of_get_property(pdev->dev.of_node, "local-mac-address", &ret);
|
||||
if (addr && ret != ETH_ALEN) {
|
||||
wcn36xx_err("invalid local-mac-address\n");
|
||||
ret = -EINVAL;
|
||||
goto out_wq;
|
||||
} else if (addr) {
|
||||
wcn36xx_info("mac address: %pM\n", addr);
|
||||
SET_IEEE80211_PERM_ADDR(wcn->hw, addr);
|
||||
}
|
||||
@ -1158,6 +1233,7 @@ out_wq:
|
||||
out_err:
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int wcn36xx_remove(struct platform_device *pdev)
|
||||
{
|
||||
struct ieee80211_hw *hw = platform_get_drvdata(pdev);
|
||||
@ -1165,45 +1241,37 @@ static int wcn36xx_remove(struct platform_device *pdev)
|
||||
wcn36xx_dbg(WCN36XX_DBG_MAC, "platform remove\n");
|
||||
|
||||
release_firmware(wcn->nv);
|
||||
mutex_destroy(&wcn->hal_mutex);
|
||||
|
||||
ieee80211_unregister_hw(hw);
|
||||
|
||||
qcom_smem_state_put(wcn->tx_enable_state);
|
||||
qcom_smem_state_put(wcn->tx_rings_empty_state);
|
||||
|
||||
iounmap(wcn->dxe_base);
|
||||
iounmap(wcn->ccu_base);
|
||||
|
||||
mutex_destroy(&wcn->hal_mutex);
|
||||
ieee80211_free_hw(hw);
|
||||
|
||||
return 0;
|
||||
}
|
||||
static const struct platform_device_id wcn36xx_platform_id_table[] = {
|
||||
{
|
||||
.name = "wcn36xx",
|
||||
.driver_data = 0
|
||||
},
|
||||
|
||||
static const struct of_device_id wcn36xx_of_match[] = {
|
||||
{ .compatible = "qcom,wcnss-wlan" },
|
||||
{}
|
||||
};
|
||||
MODULE_DEVICE_TABLE(platform, wcn36xx_platform_id_table);
|
||||
MODULE_DEVICE_TABLE(of, wcn36xx_of_match);
|
||||
|
||||
static struct platform_driver wcn36xx_driver = {
|
||||
.probe = wcn36xx_probe,
|
||||
.remove = wcn36xx_remove,
|
||||
.driver = {
|
||||
.name = "wcn36xx",
|
||||
.of_match_table = wcn36xx_of_match,
|
||||
},
|
||||
.id_table = wcn36xx_platform_id_table,
|
||||
};
|
||||
|
||||
static int __init wcn36xx_init(void)
|
||||
{
|
||||
platform_driver_register(&wcn36xx_driver);
|
||||
return 0;
|
||||
}
|
||||
module_init(wcn36xx_init);
|
||||
|
||||
static void __exit wcn36xx_exit(void)
|
||||
{
|
||||
platform_driver_unregister(&wcn36xx_driver);
|
||||
}
|
||||
module_exit(wcn36xx_exit);
|
||||
module_platform_driver(wcn36xx_driver);
|
||||
|
||||
MODULE_LICENSE("Dual BSD/GPL");
|
||||
MODULE_AUTHOR("Eugene Krasnikov k.eugene.e@gmail.com");
|
||||
|
@ -19,6 +19,7 @@
|
||||
#include <linux/etherdevice.h>
|
||||
#include <linux/firmware.h>
|
||||
#include <linux/bitops.h>
|
||||
#include <linux/soc/qcom/smd.h>
|
||||
#include "smd.h"
|
||||
|
||||
struct wcn36xx_cfg_val {
|
||||
@ -253,7 +254,7 @@ static int wcn36xx_smd_send_and_wait(struct wcn36xx *wcn, size_t len)
|
||||
|
||||
init_completion(&wcn->hal_rsp_compl);
|
||||
start = jiffies;
|
||||
ret = wcn->ctrl_ops->tx(wcn->hal_buf, len);
|
||||
ret = qcom_smd_send(wcn->smd_channel, wcn->hal_buf, len);
|
||||
if (ret) {
|
||||
wcn36xx_err("HAL TX failed\n");
|
||||
goto out;
|
||||
@ -521,7 +522,7 @@ out:
|
||||
return ret;
|
||||
}
|
||||
|
||||
int wcn36xx_smd_start_scan(struct wcn36xx *wcn)
|
||||
int wcn36xx_smd_start_scan(struct wcn36xx *wcn, u8 scan_channel)
|
||||
{
|
||||
struct wcn36xx_hal_start_scan_req_msg msg_body;
|
||||
int ret = 0;
|
||||
@ -529,7 +530,7 @@ int wcn36xx_smd_start_scan(struct wcn36xx *wcn)
|
||||
mutex_lock(&wcn->hal_mutex);
|
||||
INIT_HAL_MSG(msg_body, WCN36XX_HAL_START_SCAN_REQ);
|
||||
|
||||
msg_body.scan_channel = WCN36XX_HW_CHANNEL(wcn);
|
||||
msg_body.scan_channel = scan_channel;
|
||||
|
||||
PREPARE_HAL_BUF(wcn->hal_buf, msg_body);
|
||||
|
||||
@ -551,7 +552,7 @@ out:
|
||||
return ret;
|
||||
}
|
||||
|
||||
int wcn36xx_smd_end_scan(struct wcn36xx *wcn)
|
||||
int wcn36xx_smd_end_scan(struct wcn36xx *wcn, u8 scan_channel)
|
||||
{
|
||||
struct wcn36xx_hal_end_scan_req_msg msg_body;
|
||||
int ret = 0;
|
||||
@ -559,7 +560,7 @@ int wcn36xx_smd_end_scan(struct wcn36xx *wcn)
|
||||
mutex_lock(&wcn->hal_mutex);
|
||||
INIT_HAL_MSG(msg_body, WCN36XX_HAL_END_SCAN_REQ);
|
||||
|
||||
msg_body.scan_channel = WCN36XX_HW_CHANNEL(wcn);
|
||||
msg_body.scan_channel = scan_channel;
|
||||
|
||||
PREPARE_HAL_BUF(wcn->hal_buf, msg_body);
|
||||
|
||||
@ -2108,6 +2109,30 @@ static int wcn36xx_smd_delete_sta_context_ind(struct wcn36xx *wcn,
|
||||
return -ENOENT;
|
||||
}
|
||||
|
||||
static int wcn36xx_smd_print_reg_info_ind(struct wcn36xx *wcn,
|
||||
void *buf,
|
||||
size_t len)
|
||||
{
|
||||
struct wcn36xx_hal_print_reg_info_ind *rsp = buf;
|
||||
int i;
|
||||
|
||||
if (len < sizeof(*rsp)) {
|
||||
wcn36xx_warn("Corrupted print reg info indication\n");
|
||||
return -EIO;
|
||||
}
|
||||
|
||||
wcn36xx_dbg(WCN36XX_DBG_HAL,
|
||||
"reginfo indication, scenario: 0x%x reason: 0x%x\n",
|
||||
rsp->scenario, rsp->reason);
|
||||
|
||||
for (i = 0; i < rsp->count; i++) {
|
||||
wcn36xx_dbg(WCN36XX_DBG_HAL, "\t0x%x: 0x%x\n",
|
||||
rsp->regs[i].addr, rsp->regs[i].value);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int wcn36xx_smd_update_cfg(struct wcn36xx *wcn, u32 cfg_id, u32 value)
|
||||
{
|
||||
struct wcn36xx_hal_update_cfg_req_msg msg_body, *body;
|
||||
@ -2180,9 +2205,12 @@ out:
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void wcn36xx_smd_rsp_process(struct wcn36xx *wcn, void *buf, size_t len)
|
||||
int wcn36xx_smd_rsp_process(struct qcom_smd_channel *channel,
|
||||
const void *buf, size_t len)
|
||||
{
|
||||
struct wcn36xx_hal_msg_header *msg_header = buf;
|
||||
const struct wcn36xx_hal_msg_header *msg_header = buf;
|
||||
struct ieee80211_hw *hw = qcom_smd_get_drvdata(channel);
|
||||
struct wcn36xx *wcn = hw->priv;
|
||||
struct wcn36xx_hal_ind_msg *msg_ind;
|
||||
wcn36xx_dbg_dump(WCN36XX_DBG_SMD_DUMP, "SMD <<< ", buf, len);
|
||||
|
||||
@ -2233,15 +2261,12 @@ static void wcn36xx_smd_rsp_process(struct wcn36xx *wcn, void *buf, size_t len)
|
||||
case WCN36XX_HAL_OTA_TX_COMPL_IND:
|
||||
case WCN36XX_HAL_MISSED_BEACON_IND:
|
||||
case WCN36XX_HAL_DELETE_STA_CONTEXT_IND:
|
||||
msg_ind = kmalloc(sizeof(*msg_ind) + len, GFP_KERNEL);
|
||||
case WCN36XX_HAL_PRINT_REG_INFO_IND:
|
||||
msg_ind = kmalloc(sizeof(*msg_ind) + len, GFP_ATOMIC);
|
||||
if (!msg_ind) {
|
||||
/*
|
||||
* FIXME: Do something smarter then just
|
||||
* printing an error.
|
||||
*/
|
||||
wcn36xx_err("Run out of memory while handling SMD_EVENT (%d)\n",
|
||||
msg_header->msg_type);
|
||||
break;
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
msg_ind->msg_len = len;
|
||||
@ -2257,6 +2282,8 @@ static void wcn36xx_smd_rsp_process(struct wcn36xx *wcn, void *buf, size_t len)
|
||||
wcn36xx_err("SMD_EVENT (%d) not supported\n",
|
||||
msg_header->msg_type);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
static void wcn36xx_ind_smd_work(struct work_struct *work)
|
||||
{
|
||||
@ -2294,6 +2321,11 @@ static void wcn36xx_ind_smd_work(struct work_struct *work)
|
||||
hal_ind_msg->msg,
|
||||
hal_ind_msg->msg_len);
|
||||
break;
|
||||
case WCN36XX_HAL_PRINT_REG_INFO_IND:
|
||||
wcn36xx_smd_print_reg_info_ind(wcn,
|
||||
hal_ind_msg->msg,
|
||||
hal_ind_msg->msg_len);
|
||||
break;
|
||||
default:
|
||||
wcn36xx_err("SMD_EVENT (%d) not supported\n",
|
||||
msg_header->msg_type);
|
||||
@ -2315,22 +2347,13 @@ int wcn36xx_smd_open(struct wcn36xx *wcn)
|
||||
INIT_LIST_HEAD(&wcn->hal_ind_queue);
|
||||
spin_lock_init(&wcn->hal_ind_lock);
|
||||
|
||||
ret = wcn->ctrl_ops->open(wcn, wcn36xx_smd_rsp_process);
|
||||
if (ret) {
|
||||
wcn36xx_err("failed to open control channel\n");
|
||||
goto free_wq;
|
||||
}
|
||||
return 0;
|
||||
|
||||
return ret;
|
||||
|
||||
free_wq:
|
||||
destroy_workqueue(wcn->hal_ind_wq);
|
||||
out:
|
||||
return ret;
|
||||
}
|
||||
|
||||
void wcn36xx_smd_close(struct wcn36xx *wcn)
|
||||
{
|
||||
wcn->ctrl_ops->close();
|
||||
destroy_workqueue(wcn->hal_ind_wq);
|
||||
}
|
||||
|
@ -51,6 +51,7 @@ struct wcn36xx_hal_ind_msg {
|
||||
};
|
||||
|
||||
struct wcn36xx;
|
||||
struct qcom_smd_channel;
|
||||
|
||||
int wcn36xx_smd_open(struct wcn36xx *wcn);
|
||||
void wcn36xx_smd_close(struct wcn36xx *wcn);
|
||||
@ -59,8 +60,8 @@ int wcn36xx_smd_load_nv(struct wcn36xx *wcn);
|
||||
int wcn36xx_smd_start(struct wcn36xx *wcn);
|
||||
int wcn36xx_smd_stop(struct wcn36xx *wcn);
|
||||
int wcn36xx_smd_init_scan(struct wcn36xx *wcn, enum wcn36xx_hal_sys_mode mode);
|
||||
int wcn36xx_smd_start_scan(struct wcn36xx *wcn);
|
||||
int wcn36xx_smd_end_scan(struct wcn36xx *wcn);
|
||||
int wcn36xx_smd_start_scan(struct wcn36xx *wcn, u8 scan_channel);
|
||||
int wcn36xx_smd_end_scan(struct wcn36xx *wcn, u8 scan_channel);
|
||||
int wcn36xx_smd_finish_scan(struct wcn36xx *wcn,
|
||||
enum wcn36xx_hal_sys_mode mode);
|
||||
int wcn36xx_smd_update_scan_params(struct wcn36xx *wcn, u8 *channels, size_t channel_count);
|
||||
@ -127,6 +128,10 @@ int wcn36xx_smd_del_ba(struct wcn36xx *wcn, u16 tid, u8 sta_index);
|
||||
int wcn36xx_smd_trigger_ba(struct wcn36xx *wcn, u8 sta_index);
|
||||
|
||||
int wcn36xx_smd_update_cfg(struct wcn36xx *wcn, u32 cfg_id, u32 value);
|
||||
|
||||
int wcn36xx_smd_rsp_process(struct qcom_smd_channel *channel,
|
||||
const void *buf, size_t len);
|
||||
|
||||
int wcn36xx_smd_set_mc_list(struct wcn36xx *wcn,
|
||||
struct ieee80211_vif *vif,
|
||||
struct wcn36xx_hal_rcv_flt_mc_addr_list_type *fp);
|
||||
|
@ -45,9 +45,20 @@ int wcn36xx_rx_skb(struct wcn36xx *wcn, struct sk_buff *skb)
|
||||
skb_put(skb, bd->pdu.mpdu_header_off + bd->pdu.mpdu_len);
|
||||
skb_pull(skb, bd->pdu.mpdu_header_off);
|
||||
|
||||
hdr = (struct ieee80211_hdr *) skb->data;
|
||||
fc = __le16_to_cpu(hdr->frame_control);
|
||||
sn = IEEE80211_SEQ_TO_SN(__le16_to_cpu(hdr->seq_ctrl));
|
||||
|
||||
/* When scanning associate beacons to this */
|
||||
if (ieee80211_is_beacon(hdr->frame_control) && wcn->scan_freq) {
|
||||
status.freq = wcn->scan_freq;
|
||||
status.band = wcn->scan_band;
|
||||
} else {
|
||||
status.freq = WCN36XX_CENTER_FREQ(wcn);
|
||||
status.band = WCN36XX_BAND(wcn);
|
||||
}
|
||||
|
||||
status.mactime = 10;
|
||||
status.freq = WCN36XX_CENTER_FREQ(wcn);
|
||||
status.band = WCN36XX_BAND(wcn);
|
||||
status.signal = -get_rssi0(bd);
|
||||
status.antenna = 1;
|
||||
status.rate_idx = 1;
|
||||
@ -61,10 +72,6 @@ int wcn36xx_rx_skb(struct wcn36xx *wcn, struct sk_buff *skb)
|
||||
|
||||
memcpy(IEEE80211_SKB_RXCB(skb), &status, sizeof(status));
|
||||
|
||||
hdr = (struct ieee80211_hdr *) skb->data;
|
||||
fc = __le16_to_cpu(hdr->frame_control);
|
||||
sn = IEEE80211_SEQ_TO_SN(__le16_to_cpu(hdr->seq_ctrl));
|
||||
|
||||
if (ieee80211_is_beacon(hdr->frame_control)) {
|
||||
wcn36xx_dbg(WCN36XX_DBG_BEACON, "beacon skb %p len %d fc %04x sn %d\n",
|
||||
skb, skb->len, fc, sn);
|
||||
|
@ -35,6 +35,9 @@
|
||||
/* How many frames until we start a-mpdu TX session */
|
||||
#define WCN36XX_AMPDU_START_THRESH 20
|
||||
|
||||
#define WCN36XX_MAX_SCAN_SSIDS 9
|
||||
#define WCN36XX_MAX_SCAN_IE_LEN 500
|
||||
|
||||
extern unsigned int wcn36xx_dbg_mask;
|
||||
|
||||
enum wcn36xx_debug_mask {
|
||||
@ -103,19 +106,6 @@ struct nv_data {
|
||||
u8 table;
|
||||
};
|
||||
|
||||
/* Interface for platform control path
|
||||
*
|
||||
* @open: hook must be called when wcn36xx wants to open control channel.
|
||||
* @tx: sends a buffer.
|
||||
*/
|
||||
struct wcn36xx_platform_ctrl_ops {
|
||||
int (*open)(void *drv_priv, void *rsp_cb);
|
||||
void (*close)(void);
|
||||
int (*tx)(char *buf, size_t len);
|
||||
int (*get_hw_mac)(u8 *addr);
|
||||
int (*smsm_change_state)(u32 clear_mask, u32 set_mask);
|
||||
};
|
||||
|
||||
/**
|
||||
* struct wcn36xx_vif - holds VIF related fields
|
||||
*
|
||||
@ -205,7 +195,13 @@ struct wcn36xx {
|
||||
void __iomem *ccu_base;
|
||||
void __iomem *dxe_base;
|
||||
|
||||
struct wcn36xx_platform_ctrl_ops *ctrl_ops;
|
||||
struct qcom_smd_channel *smd_channel;
|
||||
|
||||
struct qcom_smem_state *tx_enable_state;
|
||||
unsigned tx_enable_state_bit;
|
||||
struct qcom_smem_state *tx_rings_empty_state;
|
||||
unsigned tx_rings_empty_state_bit;
|
||||
|
||||
/*
|
||||
* smd_buf must be protected with smd_mutex to garantee
|
||||
* that all messages are sent one after another
|
||||
@ -219,6 +215,12 @@ struct wcn36xx {
|
||||
spinlock_t hal_ind_lock;
|
||||
struct list_head hal_ind_queue;
|
||||
|
||||
struct work_struct scan_work;
|
||||
struct cfg80211_scan_request *scan_req;
|
||||
int scan_freq;
|
||||
int scan_band;
|
||||
struct mutex scan_lock;
|
||||
|
||||
/* DXE channels */
|
||||
struct wcn36xx_dxe_ch dxe_tx_l_ch; /* TX low */
|
||||
struct wcn36xx_dxe_ch dxe_tx_h_ch; /* TX high */
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2012-2016 Qualcomm Atheros, Inc.
|
||||
* Copyright (c) 2012-2017 Qualcomm Atheros, Inc.
|
||||
*
|
||||
* Permission to use, copy, modify, and/or distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
@ -20,6 +20,10 @@
|
||||
|
||||
#define WIL_MAX_ROC_DURATION_MS 5000
|
||||
|
||||
bool disable_ap_sme;
|
||||
module_param(disable_ap_sme, bool, 0444);
|
||||
MODULE_PARM_DESC(disable_ap_sme, " let user space handle AP mode SME");
|
||||
|
||||
#define CHAN60G(_channel, _flags) { \
|
||||
.band = NL80211_BAND_60GHZ, \
|
||||
.center_freq = 56160 + (2160 * (_channel)), \
|
||||
@ -62,9 +66,16 @@ wil_mgmt_stypes[NUM_NL80211_IFTYPES] = {
|
||||
},
|
||||
[NL80211_IFTYPE_AP] = {
|
||||
.tx = BIT(IEEE80211_STYPE_ACTION >> 4) |
|
||||
BIT(IEEE80211_STYPE_PROBE_RESP >> 4),
|
||||
BIT(IEEE80211_STYPE_PROBE_RESP >> 4) |
|
||||
BIT(IEEE80211_STYPE_ASSOC_RESP >> 4) |
|
||||
BIT(IEEE80211_STYPE_DISASSOC >> 4),
|
||||
.rx = BIT(IEEE80211_STYPE_ACTION >> 4) |
|
||||
BIT(IEEE80211_STYPE_PROBE_REQ >> 4)
|
||||
BIT(IEEE80211_STYPE_PROBE_REQ >> 4) |
|
||||
BIT(IEEE80211_STYPE_ASSOC_REQ >> 4) |
|
||||
BIT(IEEE80211_STYPE_DISASSOC >> 4) |
|
||||
BIT(IEEE80211_STYPE_AUTH >> 4) |
|
||||
BIT(IEEE80211_STYPE_DEAUTH >> 4) |
|
||||
BIT(IEEE80211_STYPE_REASSOC_REQ >> 4)
|
||||
},
|
||||
[NL80211_IFTYPE_P2P_CLIENT] = {
|
||||
.tx = BIT(IEEE80211_STYPE_ACTION >> 4) |
|
||||
@ -194,7 +205,7 @@ static int wil_cfg80211_get_station(struct wiphy *wiphy,
|
||||
|
||||
int cid = wil_find_cid(wil, mac);
|
||||
|
||||
wil_dbg_misc(wil, "%s(%pM) CID %d\n", __func__, mac, cid);
|
||||
wil_dbg_misc(wil, "get_station: %pM CID %d\n", mac, cid);
|
||||
if (cid < 0)
|
||||
return cid;
|
||||
|
||||
@ -233,7 +244,7 @@ static int wil_cfg80211_dump_station(struct wiphy *wiphy,
|
||||
return -ENOENT;
|
||||
|
||||
ether_addr_copy(mac, wil->sta[cid].addr);
|
||||
wil_dbg_misc(wil, "%s(%pM) CID %d\n", __func__, mac, cid);
|
||||
wil_dbg_misc(wil, "dump_station: %pM CID %d\n", mac, cid);
|
||||
|
||||
rc = wil_cid_fill_sinfo(wil, cid, sinfo);
|
||||
|
||||
@ -250,16 +261,15 @@ wil_cfg80211_add_iface(struct wiphy *wiphy, const char *name,
|
||||
struct net_device *ndev = wil_to_ndev(wil);
|
||||
struct wireless_dev *p2p_wdev;
|
||||
|
||||
wil_dbg_misc(wil, "%s()\n", __func__);
|
||||
wil_dbg_misc(wil, "add_iface\n");
|
||||
|
||||
if (type != NL80211_IFTYPE_P2P_DEVICE) {
|
||||
wil_err(wil, "%s: unsupported iftype %d\n", __func__, type);
|
||||
wil_err(wil, "unsupported iftype %d\n", type);
|
||||
return ERR_PTR(-EINVAL);
|
||||
}
|
||||
|
||||
if (wil->p2p_wdev) {
|
||||
wil_err(wil, "%s: P2P_DEVICE interface already created\n",
|
||||
__func__);
|
||||
wil_err(wil, "P2P_DEVICE interface already created\n");
|
||||
return ERR_PTR(-EINVAL);
|
||||
}
|
||||
|
||||
@ -282,11 +292,10 @@ static int wil_cfg80211_del_iface(struct wiphy *wiphy,
|
||||
{
|
||||
struct wil6210_priv *wil = wiphy_to_wil(wiphy);
|
||||
|
||||
wil_dbg_misc(wil, "%s()\n", __func__);
|
||||
wil_dbg_misc(wil, "del_iface\n");
|
||||
|
||||
if (wdev != wil->p2p_wdev) {
|
||||
wil_err(wil, "%s: delete of incorrect interface 0x%p\n",
|
||||
__func__, wdev);
|
||||
wil_err(wil, "delete of incorrect interface 0x%p\n", wdev);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
@ -304,7 +313,7 @@ static int wil_cfg80211_change_iface(struct wiphy *wiphy,
|
||||
struct wireless_dev *wdev = wil_to_wdev(wil);
|
||||
int rc;
|
||||
|
||||
wil_dbg_misc(wil, "%s() type=%d\n", __func__, type);
|
||||
wil_dbg_misc(wil, "change_iface: type=%d\n", type);
|
||||
|
||||
if (netif_running(wil_to_ndev(wil)) && !wil_is_recovery_blocked(wil)) {
|
||||
wil_dbg_misc(wil, "interface is up. resetting...\n");
|
||||
@ -351,8 +360,7 @@ static int wil_cfg80211_scan(struct wiphy *wiphy,
|
||||
uint i, n;
|
||||
int rc;
|
||||
|
||||
wil_dbg_misc(wil, "%s(), wdev=0x%p iftype=%d\n",
|
||||
__func__, wdev, wdev->iftype);
|
||||
wil_dbg_misc(wil, "scan: wdev=0x%p iftype=%d\n", wdev, wdev->iftype);
|
||||
|
||||
/* check we are client side */
|
||||
switch (wdev->iftype) {
|
||||
@ -557,7 +565,7 @@ static int wil_cfg80211_connect(struct wiphy *wiphy,
|
||||
int rc = 0;
|
||||
enum ieee80211_bss_type bss_type = IEEE80211_BSS_TYPE_ESS;
|
||||
|
||||
wil_dbg_misc(wil, "%s()\n", __func__);
|
||||
wil_dbg_misc(wil, "connect\n");
|
||||
wil_print_connect_params(wil, sme);
|
||||
|
||||
if (test_bit(wil_status_fwconnecting, wil->status) ||
|
||||
@ -593,6 +601,7 @@ static int wil_cfg80211_connect(struct wiphy *wiphy,
|
||||
goto out;
|
||||
}
|
||||
wil->privacy = sme->privacy;
|
||||
wil->pbss = sme->pbss;
|
||||
|
||||
if (wil->privacy) {
|
||||
/* For secure assoc, remove old keys */
|
||||
@ -689,12 +698,11 @@ static int wil_cfg80211_disconnect(struct wiphy *wiphy,
|
||||
int rc;
|
||||
struct wil6210_priv *wil = wiphy_to_wil(wiphy);
|
||||
|
||||
wil_dbg_misc(wil, "%s(reason=%d)\n", __func__, reason_code);
|
||||
wil_dbg_misc(wil, "disconnect: reason=%d\n", reason_code);
|
||||
|
||||
if (!(test_bit(wil_status_fwconnecting, wil->status) ||
|
||||
test_bit(wil_status_fwconnected, wil->status))) {
|
||||
wil_err(wil, "%s: Disconnect was called while disconnected\n",
|
||||
__func__);
|
||||
wil_err(wil, "Disconnect was called while disconnected\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -702,7 +710,7 @@ static int wil_cfg80211_disconnect(struct wiphy *wiphy,
|
||||
WMI_DISCONNECT_EVENTID, NULL, 0,
|
||||
WIL6210_DISCONNECT_TO_MS);
|
||||
if (rc)
|
||||
wil_err(wil, "%s: disconnect error %d\n", __func__, rc);
|
||||
wil_err(wil, "disconnect error %d\n", rc);
|
||||
|
||||
return rc;
|
||||
}
|
||||
@ -750,7 +758,7 @@ int wil_cfg80211_mgmt_tx(struct wiphy *wiphy, struct wireless_dev *wdev,
|
||||
* different from currently "listened" channel and fail if it is.
|
||||
*/
|
||||
|
||||
wil_dbg_misc(wil, "%s()\n", __func__);
|
||||
wil_dbg_misc(wil, "mgmt_tx\n");
|
||||
print_hex_dump_bytes("mgmt tx frame ", DUMP_PREFIX_OFFSET, buf, len);
|
||||
|
||||
cmd = kmalloc(sizeof(*cmd) + len, GFP_KERNEL);
|
||||
@ -811,7 +819,7 @@ static enum wmi_key_usage wil_detect_key_usage(struct wil6210_priv *wil,
|
||||
break;
|
||||
}
|
||||
}
|
||||
wil_dbg_misc(wil, "%s() -> %s\n", __func__, key_usage_str[rc]);
|
||||
wil_dbg_misc(wil, "detect_key_usage: -> %s\n", key_usage_str[rc]);
|
||||
|
||||
return rc;
|
||||
}
|
||||
@ -916,13 +924,13 @@ static int wil_cfg80211_add_key(struct wiphy *wiphy,
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
wil_dbg_misc(wil, "%s(%pM %s[%d] PN %*phN)\n", __func__,
|
||||
wil_dbg_misc(wil, "add_key: %pM %s[%d] PN %*phN\n",
|
||||
mac_addr, key_usage_str[key_usage], key_index,
|
||||
params->seq_len, params->seq);
|
||||
|
||||
if (IS_ERR(cs)) {
|
||||
wil_err(wil, "Not connected, %s(%pM %s[%d] PN %*phN)\n",
|
||||
__func__, mac_addr, key_usage_str[key_usage], key_index,
|
||||
wil_err(wil, "Not connected, %pM %s[%d] PN %*phN\n",
|
||||
mac_addr, key_usage_str[key_usage], key_index,
|
||||
params->seq_len, params->seq);
|
||||
return -EINVAL;
|
||||
}
|
||||
@ -931,8 +939,8 @@ static int wil_cfg80211_add_key(struct wiphy *wiphy,
|
||||
|
||||
if (params->seq && params->seq_len != IEEE80211_GCMP_PN_LEN) {
|
||||
wil_err(wil,
|
||||
"Wrong PN len %d, %s(%pM %s[%d] PN %*phN)\n",
|
||||
params->seq_len, __func__, mac_addr,
|
||||
"Wrong PN len %d, %pM %s[%d] PN %*phN\n",
|
||||
params->seq_len, mac_addr,
|
||||
key_usage_str[key_usage], key_index,
|
||||
params->seq_len, params->seq);
|
||||
return -EINVAL;
|
||||
@ -956,11 +964,11 @@ static int wil_cfg80211_del_key(struct wiphy *wiphy,
|
||||
struct wil_sta_info *cs = wil_find_sta_by_key_usage(wil, key_usage,
|
||||
mac_addr);
|
||||
|
||||
wil_dbg_misc(wil, "%s(%pM %s[%d])\n", __func__, mac_addr,
|
||||
wil_dbg_misc(wil, "del_key: %pM %s[%d]\n", mac_addr,
|
||||
key_usage_str[key_usage], key_index);
|
||||
|
||||
if (IS_ERR(cs))
|
||||
wil_info(wil, "Not connected, %s(%pM %s[%d])\n", __func__,
|
||||
wil_info(wil, "Not connected, %pM %s[%d]\n",
|
||||
mac_addr, key_usage_str[key_usage], key_index);
|
||||
|
||||
if (!IS_ERR_OR_NULL(cs))
|
||||
@ -977,7 +985,7 @@ static int wil_cfg80211_set_default_key(struct wiphy *wiphy,
|
||||
{
|
||||
struct wil6210_priv *wil = wiphy_to_wil(wiphy);
|
||||
|
||||
wil_dbg_misc(wil, "%s: entered\n", __func__);
|
||||
wil_dbg_misc(wil, "set_default_key: entered\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -990,8 +998,9 @@ static int wil_remain_on_channel(struct wiphy *wiphy,
|
||||
struct wil6210_priv *wil = wiphy_to_wil(wiphy);
|
||||
int rc;
|
||||
|
||||
wil_dbg_misc(wil, "%s() center_freq=%d, duration=%d iftype=%d\n",
|
||||
__func__, chan->center_freq, duration, wdev->iftype);
|
||||
wil_dbg_misc(wil,
|
||||
"remain_on_channel: center_freq=%d, duration=%d iftype=%d\n",
|
||||
chan->center_freq, duration, wdev->iftype);
|
||||
|
||||
rc = wil_p2p_listen(wil, wdev, duration, chan, cookie);
|
||||
return rc;
|
||||
@ -1003,7 +1012,7 @@ static int wil_cancel_remain_on_channel(struct wiphy *wiphy,
|
||||
{
|
||||
struct wil6210_priv *wil = wiphy_to_wil(wiphy);
|
||||
|
||||
wil_dbg_misc(wil, "%s()\n", __func__);
|
||||
wil_dbg_misc(wil, "cancel_remain_on_channel\n");
|
||||
|
||||
return wil_p2p_cancel_listen(wil, cookie);
|
||||
}
|
||||
@ -1159,9 +1168,9 @@ static int _wil_cfg80211_start_ap(struct wiphy *wiphy,
|
||||
if (pbss)
|
||||
wmi_nettype = WMI_NETTYPE_P2P;
|
||||
|
||||
wil_dbg_misc(wil, "%s: is_go=%d\n", __func__, is_go);
|
||||
wil_dbg_misc(wil, "start_ap: is_go=%d\n", is_go);
|
||||
if (is_go && !pbss) {
|
||||
wil_err(wil, "%s: P2P GO must be in PBSS\n", __func__);
|
||||
wil_err(wil, "P2P GO must be in PBSS\n");
|
||||
return -ENOTSUPP;
|
||||
}
|
||||
|
||||
@ -1216,7 +1225,7 @@ static int wil_cfg80211_change_beacon(struct wiphy *wiphy,
|
||||
int rc;
|
||||
u32 privacy = 0;
|
||||
|
||||
wil_dbg_misc(wil, "%s()\n", __func__);
|
||||
wil_dbg_misc(wil, "change_beacon\n");
|
||||
wil_print_bcon_data(bcon);
|
||||
|
||||
if (bcon->tail &&
|
||||
@ -1255,7 +1264,7 @@ static int wil_cfg80211_start_ap(struct wiphy *wiphy,
|
||||
struct cfg80211_crypto_settings *crypto = &info->crypto;
|
||||
u8 hidden_ssid;
|
||||
|
||||
wil_dbg_misc(wil, "%s()\n", __func__);
|
||||
wil_dbg_misc(wil, "start_ap\n");
|
||||
|
||||
if (!channel) {
|
||||
wil_err(wil, "AP: No channel???\n");
|
||||
@ -1306,7 +1315,7 @@ static int wil_cfg80211_stop_ap(struct wiphy *wiphy,
|
||||
{
|
||||
struct wil6210_priv *wil = wiphy_to_wil(wiphy);
|
||||
|
||||
wil_dbg_misc(wil, "%s()\n", __func__);
|
||||
wil_dbg_misc(wil, "stop_ap\n");
|
||||
|
||||
netif_carrier_off(ndev);
|
||||
wil_set_recovery_state(wil, fw_recovery_idle);
|
||||
@ -1322,13 +1331,35 @@ static int wil_cfg80211_stop_ap(struct wiphy *wiphy,
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int wil_cfg80211_add_station(struct wiphy *wiphy,
|
||||
struct net_device *dev,
|
||||
const u8 *mac,
|
||||
struct station_parameters *params)
|
||||
{
|
||||
struct wil6210_priv *wil = wiphy_to_wil(wiphy);
|
||||
|
||||
wil_dbg_misc(wil, "add station %pM aid %d\n", mac, params->aid);
|
||||
|
||||
if (!disable_ap_sme) {
|
||||
wil_err(wil, "not supported with AP SME enabled\n");
|
||||
return -EOPNOTSUPP;
|
||||
}
|
||||
|
||||
if (params->aid > WIL_MAX_DMG_AID) {
|
||||
wil_err(wil, "invalid aid\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
return wmi_new_sta(wil, mac, params->aid);
|
||||
}
|
||||
|
||||
static int wil_cfg80211_del_station(struct wiphy *wiphy,
|
||||
struct net_device *dev,
|
||||
struct station_del_parameters *params)
|
||||
{
|
||||
struct wil6210_priv *wil = wiphy_to_wil(wiphy);
|
||||
|
||||
wil_dbg_misc(wil, "%s(%pM, reason=%d)\n", __func__, params->mac,
|
||||
wil_dbg_misc(wil, "del_station: %pM, reason=%d\n", params->mac,
|
||||
params->reason_code);
|
||||
|
||||
mutex_lock(&wil->mutex);
|
||||
@ -1338,6 +1369,52 @@ static int wil_cfg80211_del_station(struct wiphy *wiphy,
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int wil_cfg80211_change_station(struct wiphy *wiphy,
|
||||
struct net_device *dev,
|
||||
const u8 *mac,
|
||||
struct station_parameters *params)
|
||||
{
|
||||
struct wil6210_priv *wil = wiphy_to_wil(wiphy);
|
||||
int authorize;
|
||||
int cid, i;
|
||||
struct vring_tx_data *txdata = NULL;
|
||||
|
||||
wil_dbg_misc(wil, "change station %pM mask 0x%x set 0x%x\n", mac,
|
||||
params->sta_flags_mask, params->sta_flags_set);
|
||||
|
||||
if (!disable_ap_sme) {
|
||||
wil_dbg_misc(wil, "not supported with AP SME enabled\n");
|
||||
return -EOPNOTSUPP;
|
||||
}
|
||||
|
||||
if (!(params->sta_flags_mask & BIT(NL80211_STA_FLAG_AUTHORIZED)))
|
||||
return 0;
|
||||
|
||||
cid = wil_find_cid(wil, mac);
|
||||
if (cid < 0) {
|
||||
wil_err(wil, "station not found\n");
|
||||
return -ENOLINK;
|
||||
}
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(wil->vring2cid_tid); i++)
|
||||
if (wil->vring2cid_tid[i][0] == cid) {
|
||||
txdata = &wil->vring_tx_data[i];
|
||||
break;
|
||||
}
|
||||
|
||||
if (!txdata) {
|
||||
wil_err(wil, "vring data not found\n");
|
||||
return -ENOLINK;
|
||||
}
|
||||
|
||||
authorize = params->sta_flags_set & BIT(NL80211_STA_FLAG_AUTHORIZED);
|
||||
txdata->dot1x_open = authorize ? 1 : 0;
|
||||
wil_dbg_misc(wil, "cid %d vring %d authorize %d\n", cid, i,
|
||||
txdata->dot1x_open);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* probe_client handling */
|
||||
static void wil_probe_client_handle(struct wil6210_priv *wil,
|
||||
struct wil_probe_client_req *req)
|
||||
@ -1387,7 +1464,7 @@ void wil_probe_client_flush(struct wil6210_priv *wil)
|
||||
{
|
||||
struct wil_probe_client_req *req, *t;
|
||||
|
||||
wil_dbg_misc(wil, "%s()\n", __func__);
|
||||
wil_dbg_misc(wil, "probe_client_flush\n");
|
||||
|
||||
mutex_lock(&wil->probe_client_mutex);
|
||||
|
||||
@ -1407,7 +1484,7 @@ static int wil_cfg80211_probe_client(struct wiphy *wiphy,
|
||||
struct wil_probe_client_req *req;
|
||||
int cid = wil_find_cid(wil, peer);
|
||||
|
||||
wil_dbg_misc(wil, "%s(%pM => CID %d)\n", __func__, peer, cid);
|
||||
wil_dbg_misc(wil, "probe_client: %pM => CID %d\n", peer, cid);
|
||||
|
||||
if (cid < 0)
|
||||
return -ENOLINK;
|
||||
@ -1435,7 +1512,7 @@ static int wil_cfg80211_change_bss(struct wiphy *wiphy,
|
||||
struct wil6210_priv *wil = wiphy_to_wil(wiphy);
|
||||
|
||||
if (params->ap_isolate >= 0) {
|
||||
wil_dbg_misc(wil, "%s(ap_isolate %d => %d)\n", __func__,
|
||||
wil_dbg_misc(wil, "change_bss: ap_isolate %d => %d\n",
|
||||
wil->ap_isolate, params->ap_isolate);
|
||||
wil->ap_isolate = params->ap_isolate;
|
||||
}
|
||||
@ -1448,7 +1525,7 @@ static int wil_cfg80211_start_p2p_device(struct wiphy *wiphy,
|
||||
{
|
||||
struct wil6210_priv *wil = wiphy_to_wil(wiphy);
|
||||
|
||||
wil_dbg_misc(wil, "%s: entered\n", __func__);
|
||||
wil_dbg_misc(wil, "start_p2p_device: entered\n");
|
||||
wil->p2p.p2p_dev_started = 1;
|
||||
return 0;
|
||||
}
|
||||
@ -1462,7 +1539,7 @@ static void wil_cfg80211_stop_p2p_device(struct wiphy *wiphy,
|
||||
if (!p2p->p2p_dev_started)
|
||||
return;
|
||||
|
||||
wil_dbg_misc(wil, "%s: entered\n", __func__);
|
||||
wil_dbg_misc(wil, "stop_p2p_device: entered\n");
|
||||
mutex_lock(&wil->mutex);
|
||||
mutex_lock(&wil->p2p_wdev_mutex);
|
||||
wil_p2p_stop_radio_operations(wil);
|
||||
@ -1499,7 +1576,7 @@ static int wil_cfg80211_set_power_mgmt(struct wiphy *wiphy,
|
||||
return rc;
|
||||
}
|
||||
|
||||
static struct cfg80211_ops wil_cfg80211_ops = {
|
||||
static const struct cfg80211_ops wil_cfg80211_ops = {
|
||||
.add_virtual_intf = wil_cfg80211_add_iface,
|
||||
.del_virtual_intf = wil_cfg80211_del_iface,
|
||||
.scan = wil_cfg80211_scan,
|
||||
@ -1521,7 +1598,9 @@ static struct cfg80211_ops wil_cfg80211_ops = {
|
||||
.change_beacon = wil_cfg80211_change_beacon,
|
||||
.start_ap = wil_cfg80211_start_ap,
|
||||
.stop_ap = wil_cfg80211_stop_ap,
|
||||
.add_station = wil_cfg80211_add_station,
|
||||
.del_station = wil_cfg80211_del_station,
|
||||
.change_station = wil_cfg80211_change_station,
|
||||
.probe_client = wil_cfg80211_probe_client,
|
||||
.change_bss = wil_cfg80211_change_bss,
|
||||
/* P2P device */
|
||||
@ -1542,10 +1621,11 @@ static void wil_wiphy_init(struct wiphy *wiphy)
|
||||
BIT(NL80211_IFTYPE_P2P_GO) |
|
||||
BIT(NL80211_IFTYPE_P2P_DEVICE) |
|
||||
BIT(NL80211_IFTYPE_MONITOR);
|
||||
wiphy->flags |= WIPHY_FLAG_HAVE_AP_SME |
|
||||
WIPHY_FLAG_HAS_REMAIN_ON_CHANNEL |
|
||||
wiphy->flags |= WIPHY_FLAG_HAS_REMAIN_ON_CHANNEL |
|
||||
WIPHY_FLAG_AP_PROBE_RESP_OFFLOAD |
|
||||
WIPHY_FLAG_PS_ON_BY_DEFAULT;
|
||||
if (!disable_ap_sme)
|
||||
wiphy->flags |= WIPHY_FLAG_HAVE_AP_SME;
|
||||
dev_dbg(wiphy_dev(wiphy), "%s : flags = 0x%08x\n",
|
||||
__func__, wiphy->flags);
|
||||
wiphy->probe_resp_offload =
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2012-2016 Qualcomm Atheros, Inc.
|
||||
* Copyright (c) 2012-2017 Qualcomm Atheros, Inc.
|
||||
*
|
||||
* Permission to use, copy, modify, and/or distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
@ -364,13 +364,13 @@ static void wil6210_debugfs_init_offset(struct wil6210_priv *wil,
|
||||
}
|
||||
|
||||
static const struct dbg_off isr_off[] = {
|
||||
{"ICC", S_IRUGO | S_IWUSR, offsetof(struct RGF_ICR, ICC), doff_io32},
|
||||
{"ICR", S_IRUGO | S_IWUSR, offsetof(struct RGF_ICR, ICR), doff_io32},
|
||||
{"ICM", S_IRUGO | S_IWUSR, offsetof(struct RGF_ICR, ICM), doff_io32},
|
||||
{"ICS", S_IWUSR, offsetof(struct RGF_ICR, ICS), doff_io32},
|
||||
{"IMV", S_IRUGO | S_IWUSR, offsetof(struct RGF_ICR, IMV), doff_io32},
|
||||
{"IMS", S_IWUSR, offsetof(struct RGF_ICR, IMS), doff_io32},
|
||||
{"IMC", S_IWUSR, offsetof(struct RGF_ICR, IMC), doff_io32},
|
||||
{"ICC", 0644, offsetof(struct RGF_ICR, ICC), doff_io32},
|
||||
{"ICR", 0644, offsetof(struct RGF_ICR, ICR), doff_io32},
|
||||
{"ICM", 0644, offsetof(struct RGF_ICR, ICM), doff_io32},
|
||||
{"ICS", 0244, offsetof(struct RGF_ICR, ICS), doff_io32},
|
||||
{"IMV", 0644, offsetof(struct RGF_ICR, IMV), doff_io32},
|
||||
{"IMS", 0244, offsetof(struct RGF_ICR, IMS), doff_io32},
|
||||
{"IMC", 0244, offsetof(struct RGF_ICR, IMC), doff_io32},
|
||||
{},
|
||||
};
|
||||
|
||||
@ -390,9 +390,9 @@ static int wil6210_debugfs_create_ISR(struct wil6210_priv *wil,
|
||||
}
|
||||
|
||||
static const struct dbg_off pseudo_isr_off[] = {
|
||||
{"CAUSE", S_IRUGO, HOSTADDR(RGF_DMA_PSEUDO_CAUSE), doff_io32},
|
||||
{"MASK_SW", S_IRUGO, HOSTADDR(RGF_DMA_PSEUDO_CAUSE_MASK_SW), doff_io32},
|
||||
{"MASK_FW", S_IRUGO, HOSTADDR(RGF_DMA_PSEUDO_CAUSE_MASK_FW), doff_io32},
|
||||
{"CAUSE", 0444, HOSTADDR(RGF_DMA_PSEUDO_CAUSE), doff_io32},
|
||||
{"MASK_SW", 0444, HOSTADDR(RGF_DMA_PSEUDO_CAUSE_MASK_SW), doff_io32},
|
||||
{"MASK_FW", 0444, HOSTADDR(RGF_DMA_PSEUDO_CAUSE_MASK_FW), doff_io32},
|
||||
{},
|
||||
};
|
||||
|
||||
@ -411,40 +411,40 @@ static int wil6210_debugfs_create_pseudo_ISR(struct wil6210_priv *wil,
|
||||
}
|
||||
|
||||
static const struct dbg_off lgc_itr_cnt_off[] = {
|
||||
{"TRSH", S_IRUGO | S_IWUSR, HOSTADDR(RGF_DMA_ITR_CNT_TRSH), doff_io32},
|
||||
{"DATA", S_IRUGO | S_IWUSR, HOSTADDR(RGF_DMA_ITR_CNT_DATA), doff_io32},
|
||||
{"CTL", S_IRUGO | S_IWUSR, HOSTADDR(RGF_DMA_ITR_CNT_CRL), doff_io32},
|
||||
{"TRSH", 0644, HOSTADDR(RGF_DMA_ITR_CNT_TRSH), doff_io32},
|
||||
{"DATA", 0644, HOSTADDR(RGF_DMA_ITR_CNT_DATA), doff_io32},
|
||||
{"CTL", 0644, HOSTADDR(RGF_DMA_ITR_CNT_CRL), doff_io32},
|
||||
{},
|
||||
};
|
||||
|
||||
static const struct dbg_off tx_itr_cnt_off[] = {
|
||||
{"TRSH", S_IRUGO | S_IWUSR, HOSTADDR(RGF_DMA_ITR_TX_CNT_TRSH),
|
||||
{"TRSH", 0644, HOSTADDR(RGF_DMA_ITR_TX_CNT_TRSH),
|
||||
doff_io32},
|
||||
{"DATA", S_IRUGO | S_IWUSR, HOSTADDR(RGF_DMA_ITR_TX_CNT_DATA),
|
||||
{"DATA", 0644, HOSTADDR(RGF_DMA_ITR_TX_CNT_DATA),
|
||||
doff_io32},
|
||||
{"CTL", S_IRUGO | S_IWUSR, HOSTADDR(RGF_DMA_ITR_TX_CNT_CTL),
|
||||
{"CTL", 0644, HOSTADDR(RGF_DMA_ITR_TX_CNT_CTL),
|
||||
doff_io32},
|
||||
{"IDL_TRSH", S_IRUGO | S_IWUSR, HOSTADDR(RGF_DMA_ITR_TX_IDL_CNT_TRSH),
|
||||
{"IDL_TRSH", 0644, HOSTADDR(RGF_DMA_ITR_TX_IDL_CNT_TRSH),
|
||||
doff_io32},
|
||||
{"IDL_DATA", S_IRUGO | S_IWUSR, HOSTADDR(RGF_DMA_ITR_TX_IDL_CNT_DATA),
|
||||
{"IDL_DATA", 0644, HOSTADDR(RGF_DMA_ITR_TX_IDL_CNT_DATA),
|
||||
doff_io32},
|
||||
{"IDL_CTL", S_IRUGO | S_IWUSR, HOSTADDR(RGF_DMA_ITR_TX_IDL_CNT_CTL),
|
||||
{"IDL_CTL", 0644, HOSTADDR(RGF_DMA_ITR_TX_IDL_CNT_CTL),
|
||||
doff_io32},
|
||||
{},
|
||||
};
|
||||
|
||||
static const struct dbg_off rx_itr_cnt_off[] = {
|
||||
{"TRSH", S_IRUGO | S_IWUSR, HOSTADDR(RGF_DMA_ITR_RX_CNT_TRSH),
|
||||
{"TRSH", 0644, HOSTADDR(RGF_DMA_ITR_RX_CNT_TRSH),
|
||||
doff_io32},
|
||||
{"DATA", S_IRUGO | S_IWUSR, HOSTADDR(RGF_DMA_ITR_RX_CNT_DATA),
|
||||
{"DATA", 0644, HOSTADDR(RGF_DMA_ITR_RX_CNT_DATA),
|
||||
doff_io32},
|
||||
{"CTL", S_IRUGO | S_IWUSR, HOSTADDR(RGF_DMA_ITR_RX_CNT_CTL),
|
||||
{"CTL", 0644, HOSTADDR(RGF_DMA_ITR_RX_CNT_CTL),
|
||||
doff_io32},
|
||||
{"IDL_TRSH", S_IRUGO | S_IWUSR, HOSTADDR(RGF_DMA_ITR_RX_IDL_CNT_TRSH),
|
||||
{"IDL_TRSH", 0644, HOSTADDR(RGF_DMA_ITR_RX_IDL_CNT_TRSH),
|
||||
doff_io32},
|
||||
{"IDL_DATA", S_IRUGO | S_IWUSR, HOSTADDR(RGF_DMA_ITR_RX_IDL_CNT_DATA),
|
||||
{"IDL_DATA", 0644, HOSTADDR(RGF_DMA_ITR_RX_IDL_CNT_DATA),
|
||||
doff_io32},
|
||||
{"IDL_CTL", S_IRUGO | S_IWUSR, HOSTADDR(RGF_DMA_ITR_RX_IDL_CNT_CTL),
|
||||
{"IDL_CTL", 0644, HOSTADDR(RGF_DMA_ITR_RX_IDL_CNT_CTL),
|
||||
doff_io32},
|
||||
{},
|
||||
};
|
||||
@ -813,7 +813,7 @@ static ssize_t wil_write_file_txmgmt(struct file *file, const char __user *buf,
|
||||
rc = wil_cfg80211_mgmt_tx(wiphy, wdev, ¶ms, NULL);
|
||||
|
||||
kfree(frame);
|
||||
wil_info(wil, "%s() -> %d\n", __func__, rc);
|
||||
wil_info(wil, "-> %d\n", rc);
|
||||
|
||||
return len;
|
||||
}
|
||||
@ -855,7 +855,7 @@ static ssize_t wil_write_file_wmi(struct file *file, const char __user *buf,
|
||||
rc1 = wmi_send(wil, cmdid, cmd, cmdlen);
|
||||
kfree(wmi);
|
||||
|
||||
wil_info(wil, "%s(0x%04x[%d]) -> %d\n", __func__, cmdid, cmdlen, rc1);
|
||||
wil_info(wil, "0x%04x[%d] -> %d\n", cmdid, cmdlen, rc1);
|
||||
|
||||
return rc;
|
||||
}
|
||||
@ -1379,6 +1379,7 @@ __acquires(&p->tid_rx_lock) __releases(&p->tid_rx_lock)
|
||||
for (i = 0; i < ARRAY_SIZE(wil->sta); i++) {
|
||||
struct wil_sta_info *p = &wil->sta[i];
|
||||
char *status = "unknown";
|
||||
u8 aid = 0;
|
||||
|
||||
switch (p->status) {
|
||||
case wil_sta_unused:
|
||||
@ -1389,9 +1390,10 @@ __acquires(&p->tid_rx_lock) __releases(&p->tid_rx_lock)
|
||||
break;
|
||||
case wil_sta_connected:
|
||||
status = "connected";
|
||||
aid = p->aid;
|
||||
break;
|
||||
}
|
||||
seq_printf(s, "[%d] %pM %s\n", i, p->addr, status);
|
||||
seq_printf(s, "[%d] %pM %s AID %d\n", i, p->addr, status, aid);
|
||||
|
||||
if (p->status == wil_sta_connected) {
|
||||
spin_lock_bh(&p->tid_rx_lock);
|
||||
@ -1622,7 +1624,7 @@ static void wil6210_debugfs_init_blobs(struct wil6210_priv *wil,
|
||||
blob->data = (void * __force)wil->csr + HOSTADDR(map->host);
|
||||
blob->size = map->to - map->from;
|
||||
snprintf(name, sizeof(name), "blob_%s", map->name);
|
||||
wil_debugfs_create_ioblob(name, S_IRUGO, dbg, wil_blob);
|
||||
wil_debugfs_create_ioblob(name, 0444, dbg, wil_blob);
|
||||
}
|
||||
}
|
||||
|
||||
@ -1632,29 +1634,29 @@ static const struct {
|
||||
umode_t mode;
|
||||
const struct file_operations *fops;
|
||||
} dbg_files[] = {
|
||||
{"mbox", S_IRUGO, &fops_mbox},
|
||||
{"vrings", S_IRUGO, &fops_vring},
|
||||
{"stations", S_IRUGO, &fops_sta},
|
||||
{"desc", S_IRUGO, &fops_txdesc},
|
||||
{"bf", S_IRUGO, &fops_bf},
|
||||
{"ssid", S_IRUGO | S_IWUSR, &fops_ssid},
|
||||
{"mem_val", S_IRUGO, &fops_memread},
|
||||
{"reset", S_IWUSR, &fops_reset},
|
||||
{"rxon", S_IWUSR, &fops_rxon},
|
||||
{"tx_mgmt", S_IWUSR, &fops_txmgmt},
|
||||
{"wmi_send", S_IWUSR, &fops_wmi},
|
||||
{"back", S_IRUGO | S_IWUSR, &fops_back},
|
||||
{"pmccfg", S_IRUGO | S_IWUSR, &fops_pmccfg},
|
||||
{"pmcdata", S_IRUGO, &fops_pmcdata},
|
||||
{"temp", S_IRUGO, &fops_temp},
|
||||
{"freq", S_IRUGO, &fops_freq},
|
||||
{"link", S_IRUGO, &fops_link},
|
||||
{"info", S_IRUGO, &fops_info},
|
||||
{"recovery", S_IRUGO | S_IWUSR, &fops_recovery},
|
||||
{"led_cfg", S_IRUGO | S_IWUSR, &fops_led_cfg},
|
||||
{"led_blink_time", S_IRUGO | S_IWUSR, &fops_led_blink_time},
|
||||
{"fw_capabilities", S_IRUGO, &fops_fw_capabilities},
|
||||
{"fw_version", S_IRUGO, &fops_fw_version},
|
||||
{"mbox", 0444, &fops_mbox},
|
||||
{"vrings", 0444, &fops_vring},
|
||||
{"stations", 0444, &fops_sta},
|
||||
{"desc", 0444, &fops_txdesc},
|
||||
{"bf", 0444, &fops_bf},
|
||||
{"ssid", 0644, &fops_ssid},
|
||||
{"mem_val", 0644, &fops_memread},
|
||||
{"reset", 0244, &fops_reset},
|
||||
{"rxon", 0244, &fops_rxon},
|
||||
{"tx_mgmt", 0244, &fops_txmgmt},
|
||||
{"wmi_send", 0244, &fops_wmi},
|
||||
{"back", 0644, &fops_back},
|
||||
{"pmccfg", 0644, &fops_pmccfg},
|
||||
{"pmcdata", 0444, &fops_pmcdata},
|
||||
{"temp", 0444, &fops_temp},
|
||||
{"freq", 0444, &fops_freq},
|
||||
{"link", 0444, &fops_link},
|
||||
{"info", 0444, &fops_info},
|
||||
{"recovery", 0644, &fops_recovery},
|
||||
{"led_cfg", 0644, &fops_led_cfg},
|
||||
{"led_blink_time", 0644, &fops_led_blink_time},
|
||||
{"fw_capabilities", 0444, &fops_fw_capabilities},
|
||||
{"fw_version", 0444, &fops_fw_version},
|
||||
};
|
||||
|
||||
static void wil6210_debugfs_init_files(struct wil6210_priv *wil,
|
||||
@ -1693,30 +1695,32 @@ static void wil6210_debugfs_init_isr(struct wil6210_priv *wil,
|
||||
|
||||
/* fields in struct wil6210_priv */
|
||||
static const struct dbg_off dbg_wil_off[] = {
|
||||
WIL_FIELD(privacy, S_IRUGO, doff_u32),
|
||||
WIL_FIELD(status[0], S_IRUGO | S_IWUSR, doff_ulong),
|
||||
WIL_FIELD(hw_version, S_IRUGO, doff_x32),
|
||||
WIL_FIELD(recovery_count, S_IRUGO, doff_u32),
|
||||
WIL_FIELD(ap_isolate, S_IRUGO, doff_u32),
|
||||
WIL_FIELD(discovery_mode, S_IRUGO | S_IWUSR, doff_u8),
|
||||
WIL_FIELD(privacy, 0444, doff_u32),
|
||||
WIL_FIELD(status[0], 0644, doff_ulong),
|
||||
WIL_FIELD(hw_version, 0444, doff_x32),
|
||||
WIL_FIELD(recovery_count, 0444, doff_u32),
|
||||
WIL_FIELD(ap_isolate, 0444, doff_u32),
|
||||
WIL_FIELD(discovery_mode, 0644, doff_u8),
|
||||
WIL_FIELD(chip_revision, 0444, doff_u8),
|
||||
WIL_FIELD(abft_len, 0644, doff_u8),
|
||||
{},
|
||||
};
|
||||
|
||||
static const struct dbg_off dbg_wil_regs[] = {
|
||||
{"RGF_MAC_MTRL_COUNTER_0", S_IRUGO, HOSTADDR(RGF_MAC_MTRL_COUNTER_0),
|
||||
{"RGF_MAC_MTRL_COUNTER_0", 0444, HOSTADDR(RGF_MAC_MTRL_COUNTER_0),
|
||||
doff_io32},
|
||||
{"RGF_USER_USAGE_1", S_IRUGO, HOSTADDR(RGF_USER_USAGE_1), doff_io32},
|
||||
{"RGF_USER_USAGE_1", 0444, HOSTADDR(RGF_USER_USAGE_1), doff_io32},
|
||||
{},
|
||||
};
|
||||
|
||||
/* static parameters */
|
||||
static const struct dbg_off dbg_statics[] = {
|
||||
{"desc_index", S_IRUGO | S_IWUSR, (ulong)&dbg_txdesc_index, doff_u32},
|
||||
{"vring_index", S_IRUGO | S_IWUSR, (ulong)&dbg_vring_index, doff_u32},
|
||||
{"mem_addr", S_IRUGO | S_IWUSR, (ulong)&mem_addr, doff_u32},
|
||||
{"vring_idle_trsh", S_IRUGO | S_IWUSR, (ulong)&vring_idle_trsh,
|
||||
{"desc_index", 0644, (ulong)&dbg_txdesc_index, doff_u32},
|
||||
{"vring_index", 0644, (ulong)&dbg_vring_index, doff_u32},
|
||||
{"mem_addr", 0644, (ulong)&mem_addr, doff_u32},
|
||||
{"vring_idle_trsh", 0644, (ulong)&vring_idle_trsh,
|
||||
doff_u32},
|
||||
{"led_polarity", S_IRUGO | S_IWUSR, (ulong)&led_polarity, doff_u8},
|
||||
{"led_polarity", 0644, (ulong)&led_polarity, doff_u8},
|
||||
{},
|
||||
};
|
||||
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2014 Qualcomm Atheros, Inc.
|
||||
* Copyright (c) 2014,2017 Qualcomm Atheros, Inc.
|
||||
*
|
||||
* Permission to use, copy, modify, and/or distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
@ -27,7 +27,7 @@ static int wil_ethtoolops_begin(struct net_device *ndev)
|
||||
|
||||
mutex_lock(&wil->mutex);
|
||||
|
||||
wil_dbg_misc(wil, "%s()\n", __func__);
|
||||
wil_dbg_misc(wil, "ethtoolops_begin\n");
|
||||
|
||||
return 0;
|
||||
}
|
||||
@ -36,7 +36,7 @@ static void wil_ethtoolops_complete(struct net_device *ndev)
|
||||
{
|
||||
struct wil6210_priv *wil = ndev_to_wil(ndev);
|
||||
|
||||
wil_dbg_misc(wil, "%s()\n", __func__);
|
||||
wil_dbg_misc(wil, "ethtoolops_complete\n");
|
||||
|
||||
mutex_unlock(&wil->mutex);
|
||||
}
|
||||
@ -48,7 +48,7 @@ static int wil_ethtoolops_get_coalesce(struct net_device *ndev,
|
||||
u32 tx_itr_en, tx_itr_val = 0;
|
||||
u32 rx_itr_en, rx_itr_val = 0;
|
||||
|
||||
wil_dbg_misc(wil, "%s()\n", __func__);
|
||||
wil_dbg_misc(wil, "ethtoolops_get_coalesce\n");
|
||||
|
||||
tx_itr_en = wil_r(wil, RGF_DMA_ITR_TX_CNT_CTL);
|
||||
if (tx_itr_en & BIT_DMA_ITR_TX_CNT_CTL_EN)
|
||||
@ -68,7 +68,7 @@ static int wil_ethtoolops_set_coalesce(struct net_device *ndev,
|
||||
{
|
||||
struct wil6210_priv *wil = ndev_to_wil(ndev);
|
||||
|
||||
wil_dbg_misc(wil, "%s(rx %d usec, tx %d usec)\n", __func__,
|
||||
wil_dbg_misc(wil, "ethtoolops_set_coalesce: rx %d usec, tx %d usec\n",
|
||||
cp->rx_coalesce_usecs, cp->tx_coalesce_usecs);
|
||||
|
||||
if (wil->wdev->iftype == NL80211_IFTYPE_MONITOR) {
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2014-2015 Qualcomm Atheros, Inc.
|
||||
* Copyright (c) 2014-2015,2017 Qualcomm Atheros, Inc.
|
||||
*
|
||||
* Permission to use, copy, modify, and/or distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
@ -19,8 +19,9 @@
|
||||
#include "wil6210.h"
|
||||
#include "fw.h"
|
||||
|
||||
MODULE_FIRMWARE(WIL_FW_NAME);
|
||||
MODULE_FIRMWARE(WIL_FW2_NAME);
|
||||
MODULE_FIRMWARE(WIL_FW_NAME_DEFAULT);
|
||||
MODULE_FIRMWARE(WIL_FW_NAME_SPARROW_PLUS);
|
||||
MODULE_FIRMWARE(WIL_BOARD_FILE_NAME);
|
||||
|
||||
static
|
||||
void wil_memset_toio_32(volatile void __iomem *dst, u32 val,
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2014-2016 Qualcomm Atheros, Inc.
|
||||
* Copyright (c) 2014-2017 Qualcomm Atheros, Inc.
|
||||
*
|
||||
* Permission to use, copy, modify, and/or distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
@ -537,3 +537,22 @@ out:
|
||||
release_firmware(fw);
|
||||
return rc;
|
||||
}
|
||||
|
||||
/**
|
||||
* wil_fw_verify_file_exists - checks if firmware file exist
|
||||
*
|
||||
* @wil: driver context
|
||||
* @name: firmware file name
|
||||
*
|
||||
* return value - boolean, true for success, false for failure
|
||||
*/
|
||||
bool wil_fw_verify_file_exists(struct wil6210_priv *wil, const char *name)
|
||||
{
|
||||
const struct firmware *fw;
|
||||
int rc;
|
||||
|
||||
rc = request_firmware(&fw, name, wil_to_dev(wil));
|
||||
if (!rc)
|
||||
release_firmware(fw);
|
||||
return rc != -ENOENT;
|
||||
}
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2012-2016 Qualcomm Atheros, Inc.
|
||||
* Copyright (c) 2012-2017 Qualcomm Atheros, Inc.
|
||||
*
|
||||
* Permission to use, copy, modify, and/or distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
@ -94,7 +94,7 @@ static void wil6210_mask_irq_rx(struct wil6210_priv *wil)
|
||||
|
||||
static void wil6210_mask_irq_misc(struct wil6210_priv *wil, bool mask_halp)
|
||||
{
|
||||
wil_dbg_irq(wil, "%s: mask_halp(%s)\n", __func__,
|
||||
wil_dbg_irq(wil, "mask_irq_misc: mask_halp(%s)\n",
|
||||
mask_halp ? "true" : "false");
|
||||
|
||||
wil_w(wil, RGF_DMA_EP_MISC_ICR + offsetof(struct RGF_ICR, IMS),
|
||||
@ -103,7 +103,7 @@ static void wil6210_mask_irq_misc(struct wil6210_priv *wil, bool mask_halp)
|
||||
|
||||
void wil6210_mask_halp(struct wil6210_priv *wil)
|
||||
{
|
||||
wil_dbg_irq(wil, "%s()\n", __func__);
|
||||
wil_dbg_irq(wil, "mask_halp\n");
|
||||
|
||||
wil_w(wil, RGF_DMA_EP_MISC_ICR + offsetof(struct RGF_ICR, IMS),
|
||||
BIT_DMA_EP_MISC_ICR_HALP);
|
||||
@ -111,7 +111,7 @@ void wil6210_mask_halp(struct wil6210_priv *wil)
|
||||
|
||||
static void wil6210_mask_irq_pseudo(struct wil6210_priv *wil)
|
||||
{
|
||||
wil_dbg_irq(wil, "%s()\n", __func__);
|
||||
wil_dbg_irq(wil, "mask_irq_pseudo\n");
|
||||
|
||||
wil_w(wil, RGF_DMA_PSEUDO_CAUSE_MASK_SW, WIL6210_IRQ_DISABLE);
|
||||
|
||||
@ -134,7 +134,7 @@ void wil6210_unmask_irq_rx(struct wil6210_priv *wil)
|
||||
|
||||
static void wil6210_unmask_irq_misc(struct wil6210_priv *wil, bool unmask_halp)
|
||||
{
|
||||
wil_dbg_irq(wil, "%s: unmask_halp(%s)\n", __func__,
|
||||
wil_dbg_irq(wil, "unmask_irq_misc: unmask_halp(%s)\n",
|
||||
unmask_halp ? "true" : "false");
|
||||
|
||||
wil_w(wil, RGF_DMA_EP_MISC_ICR + offsetof(struct RGF_ICR, IMC),
|
||||
@ -143,7 +143,7 @@ static void wil6210_unmask_irq_misc(struct wil6210_priv *wil, bool unmask_halp)
|
||||
|
||||
static void wil6210_unmask_halp(struct wil6210_priv *wil)
|
||||
{
|
||||
wil_dbg_irq(wil, "%s()\n", __func__);
|
||||
wil_dbg_irq(wil, "unmask_halp\n");
|
||||
|
||||
wil_w(wil, RGF_DMA_EP_MISC_ICR + offsetof(struct RGF_ICR, IMC),
|
||||
BIT_DMA_EP_MISC_ICR_HALP);
|
||||
@ -151,7 +151,7 @@ static void wil6210_unmask_halp(struct wil6210_priv *wil)
|
||||
|
||||
static void wil6210_unmask_irq_pseudo(struct wil6210_priv *wil)
|
||||
{
|
||||
wil_dbg_irq(wil, "%s()\n", __func__);
|
||||
wil_dbg_irq(wil, "unmask_irq_pseudo\n");
|
||||
|
||||
set_bit(wil_status_irqen, wil->status);
|
||||
|
||||
@ -160,7 +160,7 @@ static void wil6210_unmask_irq_pseudo(struct wil6210_priv *wil)
|
||||
|
||||
void wil_mask_irq(struct wil6210_priv *wil)
|
||||
{
|
||||
wil_dbg_irq(wil, "%s()\n", __func__);
|
||||
wil_dbg_irq(wil, "mask_irq\n");
|
||||
|
||||
wil6210_mask_irq_tx(wil);
|
||||
wil6210_mask_irq_rx(wil);
|
||||
@ -170,7 +170,7 @@ void wil_mask_irq(struct wil6210_priv *wil)
|
||||
|
||||
void wil_unmask_irq(struct wil6210_priv *wil)
|
||||
{
|
||||
wil_dbg_irq(wil, "%s()\n", __func__);
|
||||
wil_dbg_irq(wil, "unmask_irq\n");
|
||||
|
||||
wil_w(wil, RGF_DMA_EP_RX_ICR + offsetof(struct RGF_ICR, ICC),
|
||||
WIL_ICR_ICC_VALUE);
|
||||
@ -187,7 +187,7 @@ void wil_unmask_irq(struct wil6210_priv *wil)
|
||||
|
||||
void wil_configure_interrupt_moderation(struct wil6210_priv *wil)
|
||||
{
|
||||
wil_dbg_irq(wil, "%s()\n", __func__);
|
||||
wil_dbg_irq(wil, "configure_interrupt_moderation\n");
|
||||
|
||||
/* disable interrupt moderation for monitor
|
||||
* to get better timestamp precision
|
||||
@ -400,7 +400,7 @@ static irqreturn_t wil6210_irq_misc(int irq, void *cookie)
|
||||
}
|
||||
|
||||
if (isr & BIT_DMA_EP_MISC_ICR_HALP) {
|
||||
wil_dbg_irq(wil, "%s: HALP IRQ invoked\n", __func__);
|
||||
wil_dbg_irq(wil, "irq_misc: HALP IRQ invoked\n");
|
||||
wil6210_mask_halp(wil);
|
||||
isr &= ~BIT_DMA_EP_MISC_ICR_HALP;
|
||||
complete(&wil->halp.comp);
|
||||
@ -599,7 +599,7 @@ void wil6210_clear_irq(struct wil6210_priv *wil)
|
||||
|
||||
void wil6210_set_halp(struct wil6210_priv *wil)
|
||||
{
|
||||
wil_dbg_irq(wil, "%s()\n", __func__);
|
||||
wil_dbg_irq(wil, "set_halp\n");
|
||||
|
||||
wil_w(wil, RGF_DMA_EP_MISC_ICR + offsetof(struct RGF_ICR, ICS),
|
||||
BIT_DMA_EP_MISC_ICR_HALP);
|
||||
@ -607,7 +607,7 @@ void wil6210_set_halp(struct wil6210_priv *wil)
|
||||
|
||||
void wil6210_clear_halp(struct wil6210_priv *wil)
|
||||
{
|
||||
wil_dbg_irq(wil, "%s()\n", __func__);
|
||||
wil_dbg_irq(wil, "clear_halp\n");
|
||||
|
||||
wil_w(wil, RGF_DMA_EP_MISC_ICR + offsetof(struct RGF_ICR, ICR),
|
||||
BIT_DMA_EP_MISC_ICR_HALP);
|
||||
@ -618,7 +618,7 @@ int wil6210_init_irq(struct wil6210_priv *wil, int irq, bool use_msi)
|
||||
{
|
||||
int rc;
|
||||
|
||||
wil_dbg_misc(wil, "%s(%s)\n", __func__, use_msi ? "MSI" : "INTx");
|
||||
wil_dbg_misc(wil, "init_irq: %s\n", use_msi ? "MSI" : "INTx");
|
||||
|
||||
rc = request_threaded_irq(irq, wil6210_hardirq,
|
||||
wil6210_thread_irq,
|
||||
@ -629,7 +629,7 @@ int wil6210_init_irq(struct wil6210_priv *wil, int irq, bool use_msi)
|
||||
|
||||
void wil6210_fini_irq(struct wil6210_priv *wil, int irq)
|
||||
{
|
||||
wil_dbg_misc(wil, "%s()\n", __func__);
|
||||
wil_dbg_misc(wil, "fini_irq:\n");
|
||||
|
||||
wil_mask_irq(wil);
|
||||
free_irq(irq, wil);
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2012-2016 Qualcomm Atheros, Inc.
|
||||
* Copyright (c) 2012-2017 Qualcomm Atheros, Inc.
|
||||
*
|
||||
* Permission to use, copy, modify, and/or distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
@ -27,23 +27,23 @@
|
||||
#define WAIT_FOR_SCAN_ABORT_MS 1000
|
||||
|
||||
bool debug_fw; /* = false; */
|
||||
module_param(debug_fw, bool, S_IRUGO);
|
||||
module_param(debug_fw, bool, 0444);
|
||||
MODULE_PARM_DESC(debug_fw, " do not perform card reset. For FW debug");
|
||||
|
||||
static bool oob_mode;
|
||||
module_param(oob_mode, bool, S_IRUGO);
|
||||
module_param(oob_mode, bool, 0444);
|
||||
MODULE_PARM_DESC(oob_mode,
|
||||
" enable out of the box (OOB) mode in FW, for diagnostics and certification");
|
||||
|
||||
bool no_fw_recovery;
|
||||
module_param(no_fw_recovery, bool, S_IRUGO | S_IWUSR);
|
||||
module_param(no_fw_recovery, bool, 0644);
|
||||
MODULE_PARM_DESC(no_fw_recovery, " disable automatic FW error recovery");
|
||||
|
||||
/* if not set via modparam, will be set to default value of 1/8 of
|
||||
* rx ring size during init flow
|
||||
*/
|
||||
unsigned short rx_ring_overflow_thrsh = WIL6210_RX_HIGH_TRSH_INIT;
|
||||
module_param(rx_ring_overflow_thrsh, ushort, S_IRUGO);
|
||||
module_param(rx_ring_overflow_thrsh, ushort, 0444);
|
||||
MODULE_PARM_DESC(rx_ring_overflow_thrsh,
|
||||
" RX ring overflow threshold in descriptors.");
|
||||
|
||||
@ -73,7 +73,7 @@ static const struct kernel_param_ops mtu_max_ops = {
|
||||
.get = param_get_uint,
|
||||
};
|
||||
|
||||
module_param_cb(mtu_max, &mtu_max_ops, &mtu_max, S_IRUGO);
|
||||
module_param_cb(mtu_max, &mtu_max_ops, &mtu_max, 0444);
|
||||
MODULE_PARM_DESC(mtu_max, " Max MTU value.");
|
||||
|
||||
static uint rx_ring_order = WIL_RX_RING_SIZE_ORDER_DEFAULT;
|
||||
@ -102,11 +102,11 @@ static const struct kernel_param_ops ring_order_ops = {
|
||||
.get = param_get_uint,
|
||||
};
|
||||
|
||||
module_param_cb(rx_ring_order, &ring_order_ops, &rx_ring_order, S_IRUGO);
|
||||
module_param_cb(rx_ring_order, &ring_order_ops, &rx_ring_order, 0444);
|
||||
MODULE_PARM_DESC(rx_ring_order, " Rx ring order; size = 1 << order");
|
||||
module_param_cb(tx_ring_order, &ring_order_ops, &tx_ring_order, S_IRUGO);
|
||||
module_param_cb(tx_ring_order, &ring_order_ops, &tx_ring_order, 0444);
|
||||
MODULE_PARM_DESC(tx_ring_order, " Tx ring order; size = 1 << order");
|
||||
module_param_cb(bcast_ring_order, &ring_order_ops, &bcast_ring_order, S_IRUGO);
|
||||
module_param_cb(bcast_ring_order, &ring_order_ops, &bcast_ring_order, 0444);
|
||||
MODULE_PARM_DESC(bcast_ring_order, " Bcast ring order; size = 1 << order");
|
||||
|
||||
#define RST_DELAY (20) /* msec, for loop in @wil_target_reset */
|
||||
@ -172,12 +172,16 @@ __acquires(&sta->tid_rx_lock) __releases(&sta->tid_rx_lock)
|
||||
struct wil_sta_info *sta = &wil->sta[cid];
|
||||
|
||||
might_sleep();
|
||||
wil_dbg_misc(wil, "%s(CID %d, status %d)\n", __func__, cid,
|
||||
sta->status);
|
||||
wil_dbg_misc(wil, "disconnect_cid: CID %d, status %d\n",
|
||||
cid, sta->status);
|
||||
/* inform upper/lower layers */
|
||||
if (sta->status != wil_sta_unused) {
|
||||
if (!from_event)
|
||||
wmi_disconnect_sta(wil, sta->addr, reason_code, true);
|
||||
if (!from_event) {
|
||||
bool del_sta = (wdev->iftype == NL80211_IFTYPE_AP) ?
|
||||
disable_ap_sme : false;
|
||||
wmi_disconnect_sta(wil, sta->addr, reason_code,
|
||||
true, del_sta);
|
||||
}
|
||||
|
||||
switch (wdev->iftype) {
|
||||
case NL80211_IFTYPE_AP:
|
||||
@ -237,7 +241,7 @@ static void _wil6210_disconnect(struct wil6210_priv *wil, const u8 *bssid,
|
||||
return;
|
||||
|
||||
might_sleep();
|
||||
wil_info(wil, "%s(bssid=%pM, reason=%d, ev%s)\n", __func__, bssid,
|
||||
wil_info(wil, "bssid=%pM, reason=%d, ev%s\n", bssid,
|
||||
reason_code, from_event ? "+" : "-");
|
||||
|
||||
/* Cases are:
|
||||
@ -347,7 +351,7 @@ static int wil_wait_for_recovery(struct wil6210_priv *wil)
|
||||
|
||||
void wil_set_recovery_state(struct wil6210_priv *wil, int state)
|
||||
{
|
||||
wil_dbg_misc(wil, "%s(%d -> %d)\n", __func__,
|
||||
wil_dbg_misc(wil, "set_recovery_state: %d -> %d\n",
|
||||
wil->recovery_state, state);
|
||||
|
||||
wil->recovery_state = state;
|
||||
@ -489,7 +493,7 @@ int wil_priv_init(struct wil6210_priv *wil)
|
||||
{
|
||||
uint i;
|
||||
|
||||
wil_dbg_misc(wil, "%s()\n", __func__);
|
||||
wil_dbg_misc(wil, "priv_init\n");
|
||||
|
||||
memset(wil->sta, 0, sizeof(wil->sta));
|
||||
for (i = 0; i < WIL6210_MAX_CID; i++)
|
||||
@ -564,7 +568,7 @@ out_wmi_wq:
|
||||
void wil6210_disconnect(struct wil6210_priv *wil, const u8 *bssid,
|
||||
u16 reason_code, bool from_event)
|
||||
{
|
||||
wil_dbg_misc(wil, "%s()\n", __func__);
|
||||
wil_dbg_misc(wil, "disconnect\n");
|
||||
|
||||
del_timer_sync(&wil->connect_timer);
|
||||
_wil6210_disconnect(wil, bssid, reason_code, from_event);
|
||||
@ -572,7 +576,7 @@ void wil6210_disconnect(struct wil6210_priv *wil, const u8 *bssid,
|
||||
|
||||
void wil_priv_deinit(struct wil6210_priv *wil)
|
||||
{
|
||||
wil_dbg_misc(wil, "%s()\n", __func__);
|
||||
wil_dbg_misc(wil, "priv_deinit\n");
|
||||
|
||||
wil_set_recovery_state(wil, fw_recovery_idle);
|
||||
del_timer_sync(&wil->scan_timer);
|
||||
@ -605,7 +609,7 @@ static inline void wil_release_cpu(struct wil6210_priv *wil)
|
||||
|
||||
static void wil_set_oob_mode(struct wil6210_priv *wil, bool enable)
|
||||
{
|
||||
wil_info(wil, "%s: enable=%d\n", __func__, enable);
|
||||
wil_info(wil, "enable=%d\n", enable);
|
||||
if (enable)
|
||||
wil_s(wil, RGF_USER_USAGE_6, BIT_USER_OOB_MODE);
|
||||
else
|
||||
@ -861,7 +865,7 @@ int wil_reset(struct wil6210_priv *wil, bool load_fw)
|
||||
{
|
||||
int rc;
|
||||
|
||||
wil_dbg_misc(wil, "%s()\n", __func__);
|
||||
wil_dbg_misc(wil, "reset\n");
|
||||
|
||||
WARN_ON(!mutex_is_locked(&wil->mutex));
|
||||
WARN_ON(test_bit(wil_status_napi_en, wil->status));
|
||||
@ -884,9 +888,8 @@ int wil_reset(struct wil6210_priv *wil, bool load_fw)
|
||||
rc = wil->platform_ops.notify(wil->platform_handle,
|
||||
WIL_PLATFORM_EVT_PRE_RESET);
|
||||
if (rc)
|
||||
wil_err(wil,
|
||||
"%s: PRE_RESET platform notify failed, rc %d\n",
|
||||
__func__, rc);
|
||||
wil_err(wil, "PRE_RESET platform notify failed, rc %d\n",
|
||||
rc);
|
||||
}
|
||||
|
||||
set_bit(wil_status_resetting, wil->status);
|
||||
@ -915,7 +918,10 @@ int wil_reset(struct wil6210_priv *wil, bool load_fw)
|
||||
flush_workqueue(wil->wmi_wq);
|
||||
|
||||
wil_bl_crash_info(wil, false);
|
||||
wil_disable_irq(wil);
|
||||
rc = wil_target_reset(wil);
|
||||
wil6210_clear_irq(wil);
|
||||
wil_enable_irq(wil);
|
||||
wil_rx_fini(wil);
|
||||
if (rc) {
|
||||
wil_bl_crash_info(wil, true);
|
||||
@ -930,16 +936,16 @@ int wil_reset(struct wil6210_priv *wil, bool load_fw)
|
||||
|
||||
wil_set_oob_mode(wil, oob_mode);
|
||||
if (load_fw) {
|
||||
wil_info(wil, "Use firmware <%s> + board <%s>\n", WIL_FW_NAME,
|
||||
WIL_FW2_NAME);
|
||||
wil_info(wil, "Use firmware <%s> + board <%s>\n",
|
||||
wil->wil_fw_name, WIL_BOARD_FILE_NAME);
|
||||
|
||||
wil_halt_cpu(wil);
|
||||
memset(wil->fw_version, 0, sizeof(wil->fw_version));
|
||||
/* Loading f/w from the file */
|
||||
rc = wil_request_firmware(wil, WIL_FW_NAME, true);
|
||||
rc = wil_request_firmware(wil, wil->wil_fw_name, true);
|
||||
if (rc)
|
||||
return rc;
|
||||
rc = wil_request_firmware(wil, WIL_FW2_NAME, true);
|
||||
rc = wil_request_firmware(wil, WIL_BOARD_FILE_NAME, true);
|
||||
if (rc)
|
||||
return rc;
|
||||
|
||||
@ -976,8 +982,7 @@ int wil_reset(struct wil6210_priv *wil, bool load_fw)
|
||||
/* check FW is responsive */
|
||||
rc = wmi_echo(wil);
|
||||
if (rc) {
|
||||
wil_err(wil, "%s: wmi_echo failed, rc %d\n",
|
||||
__func__, rc);
|
||||
wil_err(wil, "wmi_echo failed, rc %d\n", rc);
|
||||
return rc;
|
||||
}
|
||||
|
||||
@ -987,9 +992,8 @@ int wil_reset(struct wil6210_priv *wil, bool load_fw)
|
||||
rc = wil->platform_ops.notify(wil->platform_handle,
|
||||
WIL_PLATFORM_EVT_FW_RDY);
|
||||
if (rc) {
|
||||
wil_err(wil,
|
||||
"%s: FW_RDY notify failed, rc %d\n",
|
||||
__func__, rc);
|
||||
wil_err(wil, "FW_RDY notify failed, rc %d\n",
|
||||
rc);
|
||||
rc = 0;
|
||||
}
|
||||
}
|
||||
@ -1073,7 +1077,7 @@ int wil_up(struct wil6210_priv *wil)
|
||||
{
|
||||
int rc;
|
||||
|
||||
wil_dbg_misc(wil, "%s()\n", __func__);
|
||||
wil_dbg_misc(wil, "up\n");
|
||||
|
||||
mutex_lock(&wil->mutex);
|
||||
rc = __wil_up(wil);
|
||||
@ -1113,7 +1117,7 @@ int wil_down(struct wil6210_priv *wil)
|
||||
{
|
||||
int rc;
|
||||
|
||||
wil_dbg_misc(wil, "%s()\n", __func__);
|
||||
wil_dbg_misc(wil, "down\n");
|
||||
|
||||
wil_set_recovery_state(wil, fw_recovery_idle);
|
||||
mutex_lock(&wil->mutex);
|
||||
@ -1146,25 +1150,24 @@ void wil_halp_vote(struct wil6210_priv *wil)
|
||||
|
||||
mutex_lock(&wil->halp.lock);
|
||||
|
||||
wil_dbg_irq(wil, "%s: start, HALP ref_cnt (%d)\n", __func__,
|
||||
wil_dbg_irq(wil, "halp_vote: start, HALP ref_cnt (%d)\n",
|
||||
wil->halp.ref_cnt);
|
||||
|
||||
if (++wil->halp.ref_cnt == 1) {
|
||||
wil6210_set_halp(wil);
|
||||
rc = wait_for_completion_timeout(&wil->halp.comp, to_jiffies);
|
||||
if (!rc) {
|
||||
wil_err(wil, "%s: HALP vote timed out\n", __func__);
|
||||
wil_err(wil, "HALP vote timed out\n");
|
||||
/* Mask HALP as done in case the interrupt is raised */
|
||||
wil6210_mask_halp(wil);
|
||||
} else {
|
||||
wil_dbg_irq(wil,
|
||||
"%s: HALP vote completed after %d ms\n",
|
||||
__func__,
|
||||
"halp_vote: HALP vote completed after %d ms\n",
|
||||
jiffies_to_msecs(to_jiffies - rc));
|
||||
}
|
||||
}
|
||||
|
||||
wil_dbg_irq(wil, "%s: end, HALP ref_cnt (%d)\n", __func__,
|
||||
wil_dbg_irq(wil, "halp_vote: end, HALP ref_cnt (%d)\n",
|
||||
wil->halp.ref_cnt);
|
||||
|
||||
mutex_unlock(&wil->halp.lock);
|
||||
@ -1176,15 +1179,15 @@ void wil_halp_unvote(struct wil6210_priv *wil)
|
||||
|
||||
mutex_lock(&wil->halp.lock);
|
||||
|
||||
wil_dbg_irq(wil, "%s: start, HALP ref_cnt (%d)\n", __func__,
|
||||
wil_dbg_irq(wil, "halp_unvote: start, HALP ref_cnt (%d)\n",
|
||||
wil->halp.ref_cnt);
|
||||
|
||||
if (--wil->halp.ref_cnt == 0) {
|
||||
wil6210_clear_halp(wil);
|
||||
wil_dbg_irq(wil, "%s: HALP unvote\n", __func__);
|
||||
wil_dbg_irq(wil, "HALP unvote\n");
|
||||
}
|
||||
|
||||
wil_dbg_irq(wil, "%s: end, HALP ref_cnt (%d)\n", __func__,
|
||||
wil_dbg_irq(wil, "halp_unvote:end, HALP ref_cnt (%d)\n",
|
||||
wil->halp.ref_cnt);
|
||||
|
||||
mutex_unlock(&wil->halp.lock);
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2012-2016 Qualcomm Atheros, Inc.
|
||||
* Copyright (c) 2012-2017 Qualcomm Atheros, Inc.
|
||||
*
|
||||
* Permission to use, copy, modify, and/or distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
@ -22,10 +22,11 @@ static int wil_open(struct net_device *ndev)
|
||||
{
|
||||
struct wil6210_priv *wil = ndev_to_wil(ndev);
|
||||
|
||||
wil_dbg_misc(wil, "%s()\n", __func__);
|
||||
wil_dbg_misc(wil, "open\n");
|
||||
|
||||
if (debug_fw) {
|
||||
wil_err(wil, "%s() while in debug_fw mode\n", __func__);
|
||||
if (debug_fw ||
|
||||
test_bit(WMI_FW_CAPABILITY_WMI_ONLY, wil->fw_capabilities)) {
|
||||
wil_err(wil, "while in debug_fw or wmi_only mode\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
@ -36,7 +37,7 @@ static int wil_stop(struct net_device *ndev)
|
||||
{
|
||||
struct wil6210_priv *wil = ndev_to_wil(ndev);
|
||||
|
||||
wil_dbg_misc(wil, "%s()\n", __func__);
|
||||
wil_dbg_misc(wil, "stop\n");
|
||||
|
||||
return wil_down(wil);
|
||||
}
|
||||
@ -132,7 +133,7 @@ void *wil_if_alloc(struct device *dev)
|
||||
wil->wdev = wdev;
|
||||
wil->radio_wdev = wdev;
|
||||
|
||||
wil_dbg_misc(wil, "%s()\n", __func__);
|
||||
wil_dbg_misc(wil, "if_alloc\n");
|
||||
|
||||
rc = wil_priv_init(wil);
|
||||
if (rc) {
|
||||
@ -179,7 +180,7 @@ void wil_if_free(struct wil6210_priv *wil)
|
||||
{
|
||||
struct net_device *ndev = wil_to_ndev(wil);
|
||||
|
||||
wil_dbg_misc(wil, "%s()\n", __func__);
|
||||
wil_dbg_misc(wil, "if_free\n");
|
||||
|
||||
if (!ndev)
|
||||
return;
|
||||
@ -234,7 +235,7 @@ void wil_if_remove(struct wil6210_priv *wil)
|
||||
struct net_device *ndev = wil_to_ndev(wil);
|
||||
struct wireless_dev *wdev = wil_to_wdev(wil);
|
||||
|
||||
wil_dbg_misc(wil, "%s()\n", __func__);
|
||||
wil_dbg_misc(wil, "if_remove\n");
|
||||
|
||||
unregister_netdev(ndev);
|
||||
wiphy_unregister(wdev->wiphy);
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2014-2016 Qualcomm Atheros, Inc.
|
||||
* Copyright (c) 2014-2017 Qualcomm Atheros, Inc.
|
||||
*
|
||||
* Permission to use, copy, modify, and/or distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
@ -69,7 +69,7 @@ void wil_p2p_discovery_timer_fn(ulong x)
|
||||
{
|
||||
struct wil6210_priv *wil = (void *)x;
|
||||
|
||||
wil_dbg_misc(wil, "%s\n", __func__);
|
||||
wil_dbg_misc(wil, "p2p_discovery_timer_fn\n");
|
||||
|
||||
schedule_work(&wil->p2p.discovery_expired_work);
|
||||
}
|
||||
@ -80,27 +80,25 @@ int wil_p2p_search(struct wil6210_priv *wil,
|
||||
int rc;
|
||||
struct wil_p2p_info *p2p = &wil->p2p;
|
||||
|
||||
wil_dbg_misc(wil, "%s: channel %d\n",
|
||||
__func__, P2P_DMG_SOCIAL_CHANNEL);
|
||||
wil_dbg_misc(wil, "p2p_search: channel %d\n", P2P_DMG_SOCIAL_CHANNEL);
|
||||
|
||||
lockdep_assert_held(&wil->mutex);
|
||||
|
||||
if (p2p->discovery_started) {
|
||||
wil_err(wil, "%s: search failed. discovery already ongoing\n",
|
||||
__func__);
|
||||
wil_err(wil, "search failed. discovery already ongoing\n");
|
||||
rc = -EBUSY;
|
||||
goto out;
|
||||
}
|
||||
|
||||
rc = wmi_p2p_cfg(wil, P2P_DMG_SOCIAL_CHANNEL, P2P_DEFAULT_BI);
|
||||
if (rc) {
|
||||
wil_err(wil, "%s: wmi_p2p_cfg failed\n", __func__);
|
||||
wil_err(wil, "wmi_p2p_cfg failed\n");
|
||||
goto out;
|
||||
}
|
||||
|
||||
rc = wmi_set_ssid(wil, strlen(P2P_WILDCARD_SSID), P2P_WILDCARD_SSID);
|
||||
if (rc) {
|
||||
wil_err(wil, "%s: wmi_set_ssid failed\n", __func__);
|
||||
wil_err(wil, "wmi_set_ssid failed\n");
|
||||
goto out_stop;
|
||||
}
|
||||
|
||||
@ -108,8 +106,7 @@ int wil_p2p_search(struct wil6210_priv *wil,
|
||||
rc = wmi_set_ie(wil, WMI_FRAME_PROBE_REQ,
|
||||
request->ie_len, request->ie);
|
||||
if (rc) {
|
||||
wil_err(wil, "%s: wmi_set_ie(WMI_FRAME_PROBE_REQ) failed\n",
|
||||
__func__);
|
||||
wil_err(wil, "wmi_set_ie(WMI_FRAME_PROBE_REQ) failed\n");
|
||||
goto out_stop;
|
||||
}
|
||||
|
||||
@ -119,14 +116,13 @@ int wil_p2p_search(struct wil6210_priv *wil,
|
||||
rc = wmi_set_ie(wil, WMI_FRAME_PROBE_RESP,
|
||||
request->ie_len, request->ie);
|
||||
if (rc) {
|
||||
wil_err(wil, "%s: wmi_set_ie(WMI_FRAME_PROBE_RESP) failed\n",
|
||||
__func__);
|
||||
wil_err(wil, "wmi_set_ie(WMI_FRAME_PROBE_RESP) failed\n");
|
||||
goto out_stop;
|
||||
}
|
||||
|
||||
rc = wmi_start_search(wil);
|
||||
if (rc) {
|
||||
wil_err(wil, "%s: wmi_start_search failed\n", __func__);
|
||||
wil_err(wil, "wmi_start_search failed\n");
|
||||
goto out_stop;
|
||||
}
|
||||
|
||||
@ -153,12 +149,12 @@ int wil_p2p_listen(struct wil6210_priv *wil, struct wireless_dev *wdev,
|
||||
if (!chan)
|
||||
return -EINVAL;
|
||||
|
||||
wil_dbg_misc(wil, "%s: duration %d\n", __func__, duration);
|
||||
wil_dbg_misc(wil, "p2p_listen: duration %d\n", duration);
|
||||
|
||||
mutex_lock(&wil->mutex);
|
||||
|
||||
if (p2p->discovery_started) {
|
||||
wil_err(wil, "%s: discovery already ongoing\n", __func__);
|
||||
wil_err(wil, "discovery already ongoing\n");
|
||||
rc = -EBUSY;
|
||||
goto out;
|
||||
}
|
||||
@ -220,8 +216,8 @@ int wil_p2p_cancel_listen(struct wil6210_priv *wil, u64 cookie)
|
||||
mutex_lock(&wil->mutex);
|
||||
|
||||
if (cookie != p2p->cookie) {
|
||||
wil_info(wil, "%s: Cookie mismatch: 0x%016llx vs. 0x%016llx\n",
|
||||
__func__, p2p->cookie, cookie);
|
||||
wil_info(wil, "Cookie mismatch: 0x%016llx vs. 0x%016llx\n",
|
||||
p2p->cookie, cookie);
|
||||
mutex_unlock(&wil->mutex);
|
||||
return -ENOENT;
|
||||
}
|
||||
@ -231,7 +227,7 @@ int wil_p2p_cancel_listen(struct wil6210_priv *wil, u64 cookie)
|
||||
mutex_unlock(&wil->mutex);
|
||||
|
||||
if (!started) {
|
||||
wil_err(wil, "%s: listen not started\n", __func__);
|
||||
wil_err(wil, "listen not started\n");
|
||||
return -ENOENT;
|
||||
}
|
||||
|
||||
@ -253,7 +249,7 @@ void wil_p2p_listen_expired(struct work_struct *work)
|
||||
struct wil6210_priv, p2p);
|
||||
u8 started;
|
||||
|
||||
wil_dbg_misc(wil, "%s()\n", __func__);
|
||||
wil_dbg_misc(wil, "p2p_listen_expired\n");
|
||||
|
||||
mutex_lock(&wil->mutex);
|
||||
started = wil_p2p_stop_discovery(wil);
|
||||
@ -279,7 +275,7 @@ void wil_p2p_search_expired(struct work_struct *work)
|
||||
struct wil6210_priv, p2p);
|
||||
u8 started;
|
||||
|
||||
wil_dbg_misc(wil, "%s()\n", __func__);
|
||||
wil_dbg_misc(wil, "p2p_search_expired\n");
|
||||
|
||||
mutex_lock(&wil->mutex);
|
||||
started = wil_p2p_stop_discovery(wil);
|
||||
|
@ -23,7 +23,7 @@
|
||||
#include <linux/rtnetlink.h>
|
||||
|
||||
static bool use_msi = true;
|
||||
module_param(use_msi, bool, S_IRUGO);
|
||||
module_param(use_msi, bool, 0444);
|
||||
MODULE_PARM_DESC(use_msi, " Use MSI interrupt, default - true");
|
||||
|
||||
#ifdef CONFIG_PM
|
||||
@ -36,18 +36,38 @@ static int wil6210_pm_notify(struct notifier_block *notify_block,
|
||||
static
|
||||
void wil_set_capabilities(struct wil6210_priv *wil)
|
||||
{
|
||||
u32 rev_id = wil_r(wil, RGF_USER_JTAG_DEV_ID);
|
||||
u32 jtag_id = wil_r(wil, RGF_USER_JTAG_DEV_ID);
|
||||
u8 chip_revision = (wil_r(wil, RGF_USER_REVISION_ID) &
|
||||
RGF_USER_REVISION_ID_MASK);
|
||||
|
||||
bitmap_zero(wil->hw_capabilities, hw_capability_last);
|
||||
bitmap_zero(wil->fw_capabilities, WMI_FW_CAPABILITY_MAX);
|
||||
wil->wil_fw_name = WIL_FW_NAME_DEFAULT;
|
||||
wil->chip_revision = chip_revision;
|
||||
|
||||
switch (rev_id) {
|
||||
case JTAG_DEV_ID_SPARROW_B0:
|
||||
wil->hw_name = "Sparrow B0";
|
||||
wil->hw_version = HW_VER_SPARROW_B0;
|
||||
switch (jtag_id) {
|
||||
case JTAG_DEV_ID_SPARROW:
|
||||
switch (chip_revision) {
|
||||
case REVISION_ID_SPARROW_D0:
|
||||
wil->hw_name = "Sparrow D0";
|
||||
wil->hw_version = HW_VER_SPARROW_D0;
|
||||
if (wil_fw_verify_file_exists(wil,
|
||||
WIL_FW_NAME_SPARROW_PLUS))
|
||||
wil->wil_fw_name = WIL_FW_NAME_SPARROW_PLUS;
|
||||
break;
|
||||
case REVISION_ID_SPARROW_B0:
|
||||
wil->hw_name = "Sparrow B0";
|
||||
wil->hw_version = HW_VER_SPARROW_B0;
|
||||
break;
|
||||
default:
|
||||
wil->hw_name = "Unknown";
|
||||
wil->hw_version = HW_VER_UNKNOWN;
|
||||
break;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
wil_err(wil, "Unknown board hardware 0x%08x\n", rev_id);
|
||||
wil_err(wil, "Unknown board hardware, chip_id 0x%08x, chip_revision 0x%08x\n",
|
||||
jtag_id, chip_revision);
|
||||
wil->hw_name = "Unknown";
|
||||
wil->hw_version = HW_VER_UNKNOWN;
|
||||
}
|
||||
@ -55,7 +75,7 @@ void wil_set_capabilities(struct wil6210_priv *wil)
|
||||
wil_info(wil, "Board hardware is %s\n", wil->hw_name);
|
||||
|
||||
/* extract FW capabilities from file without loading the FW */
|
||||
wil_request_firmware(wil, WIL_FW_NAME, false);
|
||||
wil_request_firmware(wil, wil->wil_fw_name, false);
|
||||
}
|
||||
|
||||
void wil_disable_irq(struct wil6210_priv *wil)
|
||||
@ -79,8 +99,10 @@ static int wil_if_pcie_enable(struct wil6210_priv *wil)
|
||||
*/
|
||||
int msi_only = pdev->msi_enabled;
|
||||
bool _use_msi = use_msi;
|
||||
bool wmi_only = test_bit(WMI_FW_CAPABILITY_WMI_ONLY,
|
||||
wil->fw_capabilities);
|
||||
|
||||
wil_dbg_misc(wil, "%s()\n", __func__);
|
||||
wil_dbg_misc(wil, "if_pcie_enable, wmi_only %d\n", wmi_only);
|
||||
|
||||
pdev->msi_enabled = 0;
|
||||
|
||||
@ -103,9 +125,11 @@ static int wil_if_pcie_enable(struct wil6210_priv *wil)
|
||||
if (rc)
|
||||
goto stop_master;
|
||||
|
||||
/* need reset here to obtain MAC */
|
||||
/* need reset here to obtain MAC or in case of WMI-only FW, full reset
|
||||
* and fw loading takes place
|
||||
*/
|
||||
mutex_lock(&wil->mutex);
|
||||
rc = wil_reset(wil, false);
|
||||
rc = wil_reset(wil, wmi_only);
|
||||
mutex_unlock(&wil->mutex);
|
||||
if (rc)
|
||||
goto release_irq;
|
||||
@ -125,7 +149,7 @@ static int wil_if_pcie_disable(struct wil6210_priv *wil)
|
||||
{
|
||||
struct pci_dev *pdev = wil->pdev;
|
||||
|
||||
wil_dbg_misc(wil, "%s()\n", __func__);
|
||||
wil_dbg_misc(wil, "if_pcie_disable\n");
|
||||
|
||||
pci_clear_master(pdev);
|
||||
/* disable and release IRQ */
|
||||
@ -289,7 +313,7 @@ static void wil_pcie_remove(struct pci_dev *pdev)
|
||||
struct wil6210_priv *wil = pci_get_drvdata(pdev);
|
||||
void __iomem *csr = wil->csr;
|
||||
|
||||
wil_dbg_misc(wil, "%s()\n", __func__);
|
||||
wil_dbg_misc(wil, "pcie_remove\n");
|
||||
|
||||
#ifdef CONFIG_PM
|
||||
#ifdef CONFIG_PM_SLEEP
|
||||
@ -327,8 +351,7 @@ static int wil6210_suspend(struct device *dev, bool is_runtime)
|
||||
struct pci_dev *pdev = to_pci_dev(dev);
|
||||
struct wil6210_priv *wil = pci_get_drvdata(pdev);
|
||||
|
||||
wil_dbg_pm(wil, "%s(%s)\n", __func__,
|
||||
is_runtime ? "runtime" : "system");
|
||||
wil_dbg_pm(wil, "suspend: %s\n", is_runtime ? "runtime" : "system");
|
||||
|
||||
rc = wil_can_suspend(wil, is_runtime);
|
||||
if (rc)
|
||||
@ -354,8 +377,7 @@ static int wil6210_resume(struct device *dev, bool is_runtime)
|
||||
struct pci_dev *pdev = to_pci_dev(dev);
|
||||
struct wil6210_priv *wil = pci_get_drvdata(pdev);
|
||||
|
||||
wil_dbg_pm(wil, "%s(%s)\n", __func__,
|
||||
is_runtime ? "runtime" : "system");
|
||||
wil_dbg_pm(wil, "resume: %s\n", is_runtime ? "runtime" : "system");
|
||||
|
||||
/* allow master */
|
||||
pci_set_master(pdev);
|
||||
@ -375,7 +397,7 @@ static int wil6210_pm_notify(struct notifier_block *notify_block,
|
||||
int rc = 0;
|
||||
enum wil_platform_event evt;
|
||||
|
||||
wil_dbg_pm(wil, "%s: mode (%ld)\n", __func__, mode);
|
||||
wil_dbg_pm(wil, "pm_notify: mode (%ld)\n", mode);
|
||||
|
||||
switch (mode) {
|
||||
case PM_HIBERNATION_PREPARE:
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2014,2016 Qualcomm Atheros, Inc.
|
||||
* Copyright (c) 2014,2017 Qualcomm Atheros, Inc.
|
||||
*
|
||||
* Permission to use, copy, modify, and/or distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
@ -21,8 +21,7 @@ int wil_can_suspend(struct wil6210_priv *wil, bool is_runtime)
|
||||
int rc = 0;
|
||||
struct wireless_dev *wdev = wil->wdev;
|
||||
|
||||
wil_dbg_pm(wil, "%s(%s)\n", __func__,
|
||||
is_runtime ? "runtime" : "system");
|
||||
wil_dbg_pm(wil, "can_suspend: %s\n", is_runtime ? "runtime" : "system");
|
||||
|
||||
if (!netif_running(wil_to_ndev(wil))) {
|
||||
/* can always sleep when down */
|
||||
@ -59,7 +58,7 @@ int wil_can_suspend(struct wil6210_priv *wil, bool is_runtime)
|
||||
}
|
||||
|
||||
out:
|
||||
wil_dbg_pm(wil, "%s(%s) => %s (%d)\n", __func__,
|
||||
wil_dbg_pm(wil, "can_suspend: %s => %s (%d)\n",
|
||||
is_runtime ? "runtime" : "system", rc ? "No" : "Yes", rc);
|
||||
|
||||
return rc;
|
||||
@ -70,8 +69,7 @@ int wil_suspend(struct wil6210_priv *wil, bool is_runtime)
|
||||
int rc = 0;
|
||||
struct net_device *ndev = wil_to_ndev(wil);
|
||||
|
||||
wil_dbg_pm(wil, "%s(%s)\n", __func__,
|
||||
is_runtime ? "runtime" : "system");
|
||||
wil_dbg_pm(wil, "suspend: %s\n", is_runtime ? "runtime" : "system");
|
||||
|
||||
/* if netif up, hardware is alive, shut it down */
|
||||
if (ndev->flags & IFF_UP) {
|
||||
@ -86,7 +84,7 @@ int wil_suspend(struct wil6210_priv *wil, bool is_runtime)
|
||||
rc = wil->platform_ops.suspend(wil->platform_handle);
|
||||
|
||||
out:
|
||||
wil_dbg_pm(wil, "%s(%s) => %d\n", __func__,
|
||||
wil_dbg_pm(wil, "suspend: %s => %d\n",
|
||||
is_runtime ? "runtime" : "system", rc);
|
||||
return rc;
|
||||
}
|
||||
@ -96,8 +94,7 @@ int wil_resume(struct wil6210_priv *wil, bool is_runtime)
|
||||
int rc = 0;
|
||||
struct net_device *ndev = wil_to_ndev(wil);
|
||||
|
||||
wil_dbg_pm(wil, "%s(%s)\n", __func__,
|
||||
is_runtime ? "runtime" : "system");
|
||||
wil_dbg_pm(wil, "resume: %s\n", is_runtime ? "runtime" : "system");
|
||||
|
||||
if (wil->platform_ops.resume) {
|
||||
rc = wil->platform_ops.resume(wil->platform_handle);
|
||||
@ -115,7 +112,7 @@ int wil_resume(struct wil6210_priv *wil, bool is_runtime)
|
||||
rc = wil_up(wil);
|
||||
|
||||
out:
|
||||
wil_dbg_pm(wil, "%s(%s) => %d\n", __func__,
|
||||
wil_dbg_pm(wil, "resume: %s => %d\n",
|
||||
is_runtime ? "runtime" : "system", rc);
|
||||
return rc;
|
||||
}
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2012-2015 Qualcomm Atheros, Inc.
|
||||
* Copyright (c) 2012-2015,2017 Qualcomm Atheros, Inc.
|
||||
*
|
||||
* Permission to use, copy, modify, and/or distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
@ -60,7 +60,7 @@ void wil_pmc_alloc(struct wil6210_priv *wil,
|
||||
|
||||
if (wil_is_pmc_allocated(pmc)) {
|
||||
/* sanity check */
|
||||
wil_err(wil, "%s: ERROR pmc is already allocated\n", __func__);
|
||||
wil_err(wil, "ERROR pmc is already allocated\n");
|
||||
goto no_release_err;
|
||||
}
|
||||
if ((num_descriptors <= 0) || (descriptor_size <= 0)) {
|
||||
@ -90,21 +90,20 @@ void wil_pmc_alloc(struct wil6210_priv *wil,
|
||||
pmc->num_descriptors = num_descriptors;
|
||||
pmc->descriptor_size = descriptor_size;
|
||||
|
||||
wil_dbg_misc(wil, "%s: %d descriptors x %d bytes each\n",
|
||||
__func__, num_descriptors, descriptor_size);
|
||||
wil_dbg_misc(wil, "pmc_alloc: %d descriptors x %d bytes each\n",
|
||||
num_descriptors, descriptor_size);
|
||||
|
||||
/* allocate descriptors info list in pmc context*/
|
||||
pmc->descriptors = kcalloc(num_descriptors,
|
||||
sizeof(struct desc_alloc_info),
|
||||
GFP_KERNEL);
|
||||
if (!pmc->descriptors) {
|
||||
wil_err(wil, "%s: ERROR allocating pmc skb list\n", __func__);
|
||||
wil_err(wil, "ERROR allocating pmc skb list\n");
|
||||
goto no_release_err;
|
||||
}
|
||||
|
||||
wil_dbg_misc(wil,
|
||||
"%s: allocated descriptors info list %p\n",
|
||||
__func__, pmc->descriptors);
|
||||
wil_dbg_misc(wil, "pmc_alloc: allocated descriptors info list %p\n",
|
||||
pmc->descriptors);
|
||||
|
||||
/* Allocate pring buffer and descriptors.
|
||||
* vring->va should be aligned on its size rounded up to power of 2
|
||||
@ -116,15 +115,14 @@ void wil_pmc_alloc(struct wil6210_priv *wil,
|
||||
GFP_KERNEL);
|
||||
|
||||
wil_dbg_misc(wil,
|
||||
"%s: allocated pring %p => %pad. %zd x %d = total %zd bytes\n",
|
||||
__func__,
|
||||
"pmc_alloc: allocated pring %p => %pad. %zd x %d = total %zd bytes\n",
|
||||
pmc->pring_va, &pmc->pring_pa,
|
||||
sizeof(struct vring_tx_desc),
|
||||
num_descriptors,
|
||||
sizeof(struct vring_tx_desc) * num_descriptors);
|
||||
|
||||
if (!pmc->pring_va) {
|
||||
wil_err(wil, "%s: ERROR allocating pmc pring\n", __func__);
|
||||
wil_err(wil, "ERROR allocating pmc pring\n");
|
||||
goto release_pmc_skb_list;
|
||||
}
|
||||
|
||||
@ -143,9 +141,7 @@ void wil_pmc_alloc(struct wil6210_priv *wil,
|
||||
GFP_KERNEL);
|
||||
|
||||
if (unlikely(!pmc->descriptors[i].va)) {
|
||||
wil_err(wil,
|
||||
"%s: ERROR allocating pmc descriptor %d",
|
||||
__func__, i);
|
||||
wil_err(wil, "ERROR allocating pmc descriptor %d", i);
|
||||
goto release_pmc_skbs;
|
||||
}
|
||||
|
||||
@ -165,21 +161,21 @@ void wil_pmc_alloc(struct wil6210_priv *wil,
|
||||
*_d = *d;
|
||||
}
|
||||
|
||||
wil_dbg_misc(wil, "%s: allocated successfully\n", __func__);
|
||||
wil_dbg_misc(wil, "pmc_alloc: allocated successfully\n");
|
||||
|
||||
pmc_cmd.op = WMI_PMC_ALLOCATE;
|
||||
pmc_cmd.ring_size = cpu_to_le16(pmc->num_descriptors);
|
||||
pmc_cmd.mem_base = cpu_to_le64(pmc->pring_pa);
|
||||
|
||||
wil_dbg_misc(wil, "%s: send WMI_PMC_CMD with ALLOCATE op\n", __func__);
|
||||
wil_dbg_misc(wil, "pmc_alloc: send WMI_PMC_CMD with ALLOCATE op\n");
|
||||
pmc->last_cmd_status = wmi_send(wil,
|
||||
WMI_PMC_CMDID,
|
||||
&pmc_cmd,
|
||||
sizeof(pmc_cmd));
|
||||
if (pmc->last_cmd_status) {
|
||||
wil_err(wil,
|
||||
"%s: WMI_PMC_CMD with ALLOCATE op failed with status %d",
|
||||
__func__, pmc->last_cmd_status);
|
||||
"WMI_PMC_CMD with ALLOCATE op failed with status %d",
|
||||
pmc->last_cmd_status);
|
||||
goto release_pmc_skbs;
|
||||
}
|
||||
|
||||
@ -188,7 +184,7 @@ void wil_pmc_alloc(struct wil6210_priv *wil,
|
||||
return;
|
||||
|
||||
release_pmc_skbs:
|
||||
wil_err(wil, "%s: exit on error: Releasing skbs...\n", __func__);
|
||||
wil_err(wil, "exit on error: Releasing skbs...\n");
|
||||
for (i = 0; pmc->descriptors[i].va && i < num_descriptors; i++) {
|
||||
dma_free_coherent(dev,
|
||||
descriptor_size,
|
||||
@ -197,7 +193,7 @@ release_pmc_skbs:
|
||||
|
||||
pmc->descriptors[i].va = NULL;
|
||||
}
|
||||
wil_err(wil, "%s: exit on error: Releasing pring...\n", __func__);
|
||||
wil_err(wil, "exit on error: Releasing pring...\n");
|
||||
|
||||
dma_free_coherent(dev,
|
||||
sizeof(struct vring_tx_desc) * num_descriptors,
|
||||
@ -207,8 +203,7 @@ release_pmc_skbs:
|
||||
pmc->pring_va = NULL;
|
||||
|
||||
release_pmc_skb_list:
|
||||
wil_err(wil, "%s: exit on error: Releasing descriptors info list...\n",
|
||||
__func__);
|
||||
wil_err(wil, "exit on error: Releasing descriptors info list...\n");
|
||||
kfree(pmc->descriptors);
|
||||
pmc->descriptors = NULL;
|
||||
|
||||
@ -232,24 +227,23 @@ void wil_pmc_free(struct wil6210_priv *wil, int send_pmc_cmd)
|
||||
pmc->last_cmd_status = 0;
|
||||
|
||||
if (!wil_is_pmc_allocated(pmc)) {
|
||||
wil_dbg_misc(wil, "%s: Error, can't free - not allocated\n",
|
||||
__func__);
|
||||
wil_dbg_misc(wil,
|
||||
"pmc_free: Error, can't free - not allocated\n");
|
||||
pmc->last_cmd_status = -EPERM;
|
||||
mutex_unlock(&pmc->lock);
|
||||
return;
|
||||
}
|
||||
|
||||
if (send_pmc_cmd) {
|
||||
wil_dbg_misc(wil, "%s: send WMI_PMC_CMD with RELEASE op\n",
|
||||
__func__);
|
||||
wil_dbg_misc(wil, "send WMI_PMC_CMD with RELEASE op\n");
|
||||
pmc_cmd.op = WMI_PMC_RELEASE;
|
||||
pmc->last_cmd_status =
|
||||
wmi_send(wil, WMI_PMC_CMDID, &pmc_cmd,
|
||||
sizeof(pmc_cmd));
|
||||
if (pmc->last_cmd_status) {
|
||||
wil_err(wil,
|
||||
"%s WMI_PMC_CMD with RELEASE op failed, status %d",
|
||||
__func__, pmc->last_cmd_status);
|
||||
"WMI_PMC_CMD with RELEASE op failed, status %d",
|
||||
pmc->last_cmd_status);
|
||||
/* There's nothing we can do with this error.
|
||||
* Normally, it should never occur.
|
||||
* Continue to freeing all memory allocated for pmc.
|
||||
@ -261,8 +255,8 @@ void wil_pmc_free(struct wil6210_priv *wil, int send_pmc_cmd)
|
||||
size_t buf_size = sizeof(struct vring_tx_desc) *
|
||||
pmc->num_descriptors;
|
||||
|
||||
wil_dbg_misc(wil, "%s: free pring va %p\n",
|
||||
__func__, pmc->pring_va);
|
||||
wil_dbg_misc(wil, "pmc_free: free pring va %p\n",
|
||||
pmc->pring_va);
|
||||
dma_free_coherent(dev, buf_size, pmc->pring_va, pmc->pring_pa);
|
||||
|
||||
pmc->pring_va = NULL;
|
||||
@ -281,11 +275,11 @@ void wil_pmc_free(struct wil6210_priv *wil, int send_pmc_cmd)
|
||||
pmc->descriptors[i].pa);
|
||||
pmc->descriptors[i].va = NULL;
|
||||
}
|
||||
wil_dbg_misc(wil, "%s: free descriptor info %d/%d\n",
|
||||
__func__, i, pmc->num_descriptors);
|
||||
wil_dbg_misc(wil, "pmc_free: free descriptor info %d/%d\n", i,
|
||||
pmc->num_descriptors);
|
||||
wil_dbg_misc(wil,
|
||||
"%s: free pmc descriptors info list %p\n",
|
||||
__func__, pmc->descriptors);
|
||||
"pmc_free: free pmc descriptors info list %p\n",
|
||||
pmc->descriptors);
|
||||
kfree(pmc->descriptors);
|
||||
pmc->descriptors = NULL;
|
||||
} else {
|
||||
@ -301,7 +295,7 @@ void wil_pmc_free(struct wil6210_priv *wil, int send_pmc_cmd)
|
||||
*/
|
||||
int wil_pmc_last_cmd_status(struct wil6210_priv *wil)
|
||||
{
|
||||
wil_dbg_misc(wil, "%s: status %d\n", __func__,
|
||||
wil_dbg_misc(wil, "pmc_last_cmd_status: status %d\n",
|
||||
wil->pmc.last_cmd_status);
|
||||
|
||||
return wil->pmc.last_cmd_status;
|
||||
@ -324,7 +318,7 @@ ssize_t wil_pmc_read(struct file *filp, char __user *buf, size_t count,
|
||||
mutex_lock(&pmc->lock);
|
||||
|
||||
if (!wil_is_pmc_allocated(pmc)) {
|
||||
wil_err(wil, "%s: error, pmc is not allocated!\n", __func__);
|
||||
wil_err(wil, "error, pmc is not allocated!\n");
|
||||
pmc->last_cmd_status = -EPERM;
|
||||
mutex_unlock(&pmc->lock);
|
||||
return -EPERM;
|
||||
@ -333,8 +327,8 @@ ssize_t wil_pmc_read(struct file *filp, char __user *buf, size_t count,
|
||||
pmc_size = pmc->descriptor_size * pmc->num_descriptors;
|
||||
|
||||
wil_dbg_misc(wil,
|
||||
"%s: size %u, pos %lld\n",
|
||||
__func__, (unsigned)count, *f_pos);
|
||||
"pmc_read: size %u, pos %lld\n",
|
||||
(u32)count, *f_pos);
|
||||
|
||||
pmc->last_cmd_status = 0;
|
||||
|
||||
@ -343,15 +337,16 @@ ssize_t wil_pmc_read(struct file *filp, char __user *buf, size_t count,
|
||||
offset = *f_pos - (idx * pmc->descriptor_size);
|
||||
|
||||
if (*f_pos >= pmc_size) {
|
||||
wil_dbg_misc(wil, "%s: reached end of pmc buf: %lld >= %u\n",
|
||||
__func__, *f_pos, (unsigned)pmc_size);
|
||||
wil_dbg_misc(wil,
|
||||
"pmc_read: reached end of pmc buf: %lld >= %u\n",
|
||||
*f_pos, (u32)pmc_size);
|
||||
pmc->last_cmd_status = -ERANGE;
|
||||
goto out;
|
||||
}
|
||||
|
||||
wil_dbg_misc(wil,
|
||||
"%s: read from pos %lld (descriptor %llu, offset %llu) %zu bytes\n",
|
||||
__func__, *f_pos, idx, offset, count);
|
||||
"pmc_read: read from pos %lld (descriptor %llu, offset %llu) %zu bytes\n",
|
||||
*f_pos, idx, offset, count);
|
||||
|
||||
/* if no errors, return the copied byte count */
|
||||
retval = simple_read_from_buffer(buf,
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2014-2016 Qualcomm Atheros, Inc.
|
||||
* Copyright (c) 2014-2017 Qualcomm Atheros, Inc.
|
||||
*
|
||||
* Permission to use, copy, modify, and/or distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
@ -349,8 +349,8 @@ __acquires(&sta->tid_rx_lock) __releases(&sta->tid_rx_lock)
|
||||
rc = wmi_addba_rx_resp(wil, cid, tid, dialog_token, status,
|
||||
agg_amsdu, agg_wsize, agg_timeout);
|
||||
if (rc || (status != WLAN_STATUS_SUCCESS)) {
|
||||
wil_err(wil, "%s: do not apply ba, rc(%d), status(%d)\n",
|
||||
__func__, rc, status);
|
||||
wil_err(wil, "do not apply ba, rc(%d), status(%d)\n", rc,
|
||||
status);
|
||||
goto out;
|
||||
}
|
||||
|
||||
@ -387,7 +387,7 @@ int wil_addba_tx_request(struct wil6210_priv *wil, u8 ringid, u16 wsize)
|
||||
txdata->addba_in_progress = true;
|
||||
rc = wmi_addba(wil, ringid, agg_wsize, agg_timeout);
|
||||
if (rc) {
|
||||
wil_err(wil, "%s: wmi_addba failed, rc (%d)", __func__, rc);
|
||||
wil_err(wil, "wmi_addba failed, rc (%d)", rc);
|
||||
txdata->addba_in_progress = false;
|
||||
}
|
||||
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2012-2016 Qualcomm Atheros, Inc.
|
||||
* Copyright (c) 2012-2017 Qualcomm Atheros, Inc.
|
||||
*
|
||||
* Permission to use, copy, modify, and/or distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
@ -29,12 +29,12 @@
|
||||
#include "trace.h"
|
||||
|
||||
static bool rtap_include_phy_info;
|
||||
module_param(rtap_include_phy_info, bool, S_IRUGO);
|
||||
module_param(rtap_include_phy_info, bool, 0444);
|
||||
MODULE_PARM_DESC(rtap_include_phy_info,
|
||||
" Include PHY info in the radiotap header, default - no");
|
||||
|
||||
bool rx_align_2;
|
||||
module_param(rx_align_2, bool, S_IRUGO);
|
||||
module_param(rx_align_2, bool, 0444);
|
||||
MODULE_PARM_DESC(rx_align_2, " align Rx buffers on 4*n+2, default - no");
|
||||
|
||||
static inline uint wil_rx_snaplen(void)
|
||||
@ -112,7 +112,7 @@ static int wil_vring_alloc(struct wil6210_priv *wil, struct vring *vring)
|
||||
size_t sz = vring->size * sizeof(vring->va[0]);
|
||||
uint i;
|
||||
|
||||
wil_dbg_misc(wil, "%s()\n", __func__);
|
||||
wil_dbg_misc(wil, "vring_alloc:\n");
|
||||
|
||||
BUILD_BUG_ON(sizeof(vring->va[0]) != 32);
|
||||
|
||||
@ -745,7 +745,7 @@ void wil_rx_handle(struct wil6210_priv *wil, int *quota)
|
||||
wil_err(wil, "Rx IRQ while Rx not yet initialized\n");
|
||||
return;
|
||||
}
|
||||
wil_dbg_txrx(wil, "%s()\n", __func__);
|
||||
wil_dbg_txrx(wil, "rx_handle\n");
|
||||
while ((*quota > 0) && (NULL != (skb = wil_vring_reap_rx(wil, v)))) {
|
||||
(*quota)--;
|
||||
|
||||
@ -768,7 +768,7 @@ int wil_rx_init(struct wil6210_priv *wil, u16 size)
|
||||
struct vring *vring = &wil->vring_rx;
|
||||
int rc;
|
||||
|
||||
wil_dbg_misc(wil, "%s()\n", __func__);
|
||||
wil_dbg_misc(wil, "rx_init\n");
|
||||
|
||||
if (vring->va) {
|
||||
wil_err(wil, "Rx ring already allocated\n");
|
||||
@ -799,7 +799,7 @@ void wil_rx_fini(struct wil6210_priv *wil)
|
||||
{
|
||||
struct vring *vring = &wil->vring_rx;
|
||||
|
||||
wil_dbg_misc(wil, "%s()\n", __func__);
|
||||
wil_dbg_misc(wil, "rx_fini\n");
|
||||
|
||||
if (vring->va)
|
||||
wil_vring_free(wil, vring, 0);
|
||||
@ -851,7 +851,7 @@ int wil_vring_init_tx(struct wil6210_priv *wil, int id, int size,
|
||||
struct vring *vring = &wil->vring_tx[id];
|
||||
struct vring_tx_data *txdata = &wil->vring_tx_data[id];
|
||||
|
||||
wil_dbg_misc(wil, "%s() max_mpdu_size %d\n", __func__,
|
||||
wil_dbg_misc(wil, "vring_init_tx: max_mpdu_size %d\n",
|
||||
cmd.vring_cfg.tx_sw_ring.max_mpdu_size);
|
||||
lockdep_assert_held(&wil->mutex);
|
||||
|
||||
@ -931,7 +931,7 @@ int wil_vring_init_bcast(struct wil6210_priv *wil, int id, int size)
|
||||
struct vring *vring = &wil->vring_tx[id];
|
||||
struct vring_tx_data *txdata = &wil->vring_tx_data[id];
|
||||
|
||||
wil_dbg_misc(wil, "%s() max_mpdu_size %d\n", __func__,
|
||||
wil_dbg_misc(wil, "vring_init_bcast: max_mpdu_size %d\n",
|
||||
cmd.vring_cfg.tx_sw_ring.max_mpdu_size);
|
||||
lockdep_assert_held(&wil->mutex);
|
||||
|
||||
@ -993,7 +993,7 @@ void wil_vring_fini_tx(struct wil6210_priv *wil, int id)
|
||||
if (!vring->va)
|
||||
return;
|
||||
|
||||
wil_dbg_misc(wil, "%s() id=%d\n", __func__, id);
|
||||
wil_dbg_misc(wil, "vring_fini_tx: id=%d\n", id);
|
||||
|
||||
spin_lock_bh(&txdata->lock);
|
||||
txdata->dot1x_open = false;
|
||||
@ -1032,12 +1032,14 @@ static struct vring *wil_find_tx_ucast(struct wil6210_priv *wil,
|
||||
struct vring *v = &wil->vring_tx[i];
|
||||
struct vring_tx_data *txdata = &wil->vring_tx_data[i];
|
||||
|
||||
wil_dbg_txrx(wil, "%s(%pM) -> [%d]\n",
|
||||
__func__, eth->h_dest, i);
|
||||
wil_dbg_txrx(wil, "find_tx_ucast: (%pM) -> [%d]\n",
|
||||
eth->h_dest, i);
|
||||
if (v->va && txdata->enabled) {
|
||||
return v;
|
||||
} else {
|
||||
wil_dbg_txrx(wil, "vring[%d] not valid\n", i);
|
||||
wil_dbg_txrx(wil,
|
||||
"find_tx_ucast: vring[%d] not valid\n",
|
||||
i);
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
@ -1193,17 +1195,6 @@ found:
|
||||
return v;
|
||||
}
|
||||
|
||||
static struct vring *wil_find_tx_bcast(struct wil6210_priv *wil,
|
||||
struct sk_buff *skb)
|
||||
{
|
||||
struct wireless_dev *wdev = wil->wdev;
|
||||
|
||||
if (wdev->iftype != NL80211_IFTYPE_AP)
|
||||
return wil_find_tx_bcast_2(wil, skb);
|
||||
|
||||
return wil_find_tx_bcast_1(wil, skb);
|
||||
}
|
||||
|
||||
static int wil_tx_desc_map(struct vring_tx_desc *d, dma_addr_t pa, u32 len,
|
||||
int vring_index)
|
||||
{
|
||||
@ -1373,8 +1364,8 @@ static int __wil_tx_vring_tso(struct wil6210_priv *wil, struct vring *vring,
|
||||
int gso_type;
|
||||
int rc = -EINVAL;
|
||||
|
||||
wil_dbg_txrx(wil, "%s() %d bytes to vring %d\n",
|
||||
__func__, skb->len, vring_index);
|
||||
wil_dbg_txrx(wil, "tx_vring_tso: %d bytes to vring %d\n", skb->len,
|
||||
vring_index);
|
||||
|
||||
if (unlikely(!txdata->enabled))
|
||||
return -EINVAL;
|
||||
@ -1643,8 +1634,8 @@ static int __wil_tx_vring(struct wil6210_priv *wil, struct vring *vring,
|
||||
bool mcast = (vring_index == wil->bcast_vring);
|
||||
uint len = skb_headlen(skb);
|
||||
|
||||
wil_dbg_txrx(wil, "%s() %d bytes to vring %d\n",
|
||||
__func__, skb->len, vring_index);
|
||||
wil_dbg_txrx(wil, "tx_vring: %d bytes to vring %d\n", skb->len,
|
||||
vring_index);
|
||||
|
||||
if (unlikely(!txdata->enabled))
|
||||
return -EINVAL;
|
||||
@ -1884,7 +1875,7 @@ netdev_tx_t wil_start_xmit(struct sk_buff *skb, struct net_device *ndev)
|
||||
static bool pr_once_fw;
|
||||
int rc;
|
||||
|
||||
wil_dbg_txrx(wil, "%s()\n", __func__);
|
||||
wil_dbg_txrx(wil, "start_xmit\n");
|
||||
if (unlikely(!test_bit(wil_status_fwready, wil->status))) {
|
||||
if (!pr_once_fw) {
|
||||
wil_err(wil, "FW not ready\n");
|
||||
@ -1903,12 +1894,26 @@ netdev_tx_t wil_start_xmit(struct sk_buff *skb, struct net_device *ndev)
|
||||
pr_once_fw = false;
|
||||
|
||||
/* find vring */
|
||||
if (wil->wdev->iftype == NL80211_IFTYPE_STATION) {
|
||||
/* in STA mode (ESS), all to same VRING */
|
||||
if (wil->wdev->iftype == NL80211_IFTYPE_STATION && !wil->pbss) {
|
||||
/* in STA mode (ESS), all to same VRING (to AP) */
|
||||
vring = wil_find_tx_vring_sta(wil, skb);
|
||||
} else { /* direct communication, find matching VRING */
|
||||
vring = bcast ? wil_find_tx_bcast(wil, skb) :
|
||||
wil_find_tx_ucast(wil, skb);
|
||||
} else if (bcast) {
|
||||
if (wil->pbss)
|
||||
/* in pbss, no bcast VRING - duplicate skb in
|
||||
* all stations VRINGs
|
||||
*/
|
||||
vring = wil_find_tx_bcast_2(wil, skb);
|
||||
else if (wil->wdev->iftype == NL80211_IFTYPE_AP)
|
||||
/* AP has a dedicated bcast VRING */
|
||||
vring = wil_find_tx_bcast_1(wil, skb);
|
||||
else
|
||||
/* unexpected combination, fallback to duplicating
|
||||
* the skb in all stations VRINGs
|
||||
*/
|
||||
vring = wil_find_tx_bcast_2(wil, skb);
|
||||
} else {
|
||||
/* unicast, find specific VRING by dest. address */
|
||||
vring = wil_find_tx_ucast(wil, skb);
|
||||
}
|
||||
if (unlikely(!vring)) {
|
||||
wil_dbg_txrx(wil, "No Tx VRING found for %pM\n", eth->h_dest);
|
||||
@ -1982,7 +1987,7 @@ int wil_tx_complete(struct wil6210_priv *wil, int ringid)
|
||||
return 0;
|
||||
}
|
||||
|
||||
wil_dbg_txrx(wil, "%s(%d)\n", __func__, ringid);
|
||||
wil_dbg_txrx(wil, "tx_complete: (%d)\n", ringid);
|
||||
|
||||
used_before_complete = wil_vring_used_tx(vring);
|
||||
|
||||
|
@ -33,10 +33,12 @@ extern int agg_wsize;
|
||||
extern u32 vring_idle_trsh;
|
||||
extern bool rx_align_2;
|
||||
extern bool debug_fw;
|
||||
extern bool disable_ap_sme;
|
||||
|
||||
#define WIL_NAME "wil6210"
|
||||
#define WIL_FW_NAME "wil6210.fw" /* code */
|
||||
#define WIL_FW2_NAME "wil6210.brd" /* board & radio parameters */
|
||||
#define WIL_FW_NAME_DEFAULT "wil6210.fw" /* code Sparrow B0 */
|
||||
#define WIL_FW_NAME_SPARROW_PLUS "wil6210_sparrow_plus.fw" /* code Sparrow D0 */
|
||||
#define WIL_BOARD_FILE_NAME "wil6210.brd" /* board & radio parameters */
|
||||
|
||||
#define WIL_MAX_BUS_REQUEST_KBPS 800000 /* ~6.1Gbps */
|
||||
|
||||
@ -98,6 +100,9 @@ static inline u32 wil_mtu2macbuf(u32 mtu)
|
||||
#define WIL6210_RX_HIGH_TRSH_INIT (0)
|
||||
#define WIL6210_RX_HIGH_TRSH_DEFAULT \
|
||||
(1 << (WIL_RX_RING_SIZE_ORDER_DEFAULT - 3))
|
||||
#define WIL_MAX_DMG_AID 254 /* for DMG only 1-254 allowed (see
|
||||
* 802.11REVmc/D5.0, section 9.4.1.8)
|
||||
*/
|
||||
/* Hardware definitions begin */
|
||||
|
||||
/*
|
||||
@ -249,7 +254,12 @@ struct RGF_ICR {
|
||||
#define BIT_CAF_OSC_DIG_XTAL_STABLE BIT(0)
|
||||
|
||||
#define RGF_USER_JTAG_DEV_ID (0x880b34) /* device ID */
|
||||
#define JTAG_DEV_ID_SPARROW_B0 (0x2632072f)
|
||||
#define JTAG_DEV_ID_SPARROW (0x2632072f)
|
||||
|
||||
#define RGF_USER_REVISION_ID (0x88afe4)
|
||||
#define RGF_USER_REVISION_ID_MASK (3)
|
||||
#define REVISION_ID_SPARROW_B0 (0x0)
|
||||
#define REVISION_ID_SPARROW_D0 (0x3)
|
||||
|
||||
/* crash codes for FW/Ucode stored here */
|
||||
#define RGF_FW_ASSERT_CODE (0x91f020)
|
||||
@ -257,7 +267,8 @@ struct RGF_ICR {
|
||||
|
||||
enum {
|
||||
HW_VER_UNKNOWN,
|
||||
HW_VER_SPARROW_B0, /* JTAG_DEV_ID_SPARROW_B0 */
|
||||
HW_VER_SPARROW_B0, /* REVISION_ID_SPARROW_B0 */
|
||||
HW_VER_SPARROW_D0, /* REVISION_ID_SPARROW_D0 */
|
||||
};
|
||||
|
||||
/* popular locations */
|
||||
@ -512,6 +523,7 @@ struct wil_sta_info {
|
||||
unsigned long tid_rx_stop_requested[BITS_TO_LONGS(WIL_STA_TID_NUM)];
|
||||
struct wil_tid_crypto_rx tid_crypto_rx[WIL_STA_TID_NUM];
|
||||
struct wil_tid_crypto_rx group_crypto_rx;
|
||||
u8 aid; /* 1-254; 0 if unknown/not reported */
|
||||
};
|
||||
|
||||
enum {
|
||||
@ -583,7 +595,9 @@ struct wil6210_priv {
|
||||
DECLARE_BITMAP(status, wil_status_last);
|
||||
u8 fw_version[ETHTOOL_FWVERS_LEN];
|
||||
u32 hw_version;
|
||||
u8 chip_revision;
|
||||
const char *hw_name;
|
||||
const char *wil_fw_name;
|
||||
DECLARE_BITMAP(hw_capabilities, hw_capability_last);
|
||||
DECLARE_BITMAP(fw_capabilities, WMI_FW_CAPABILITY_MAX);
|
||||
u8 n_mids; /* number of additional MIDs as reported by FW */
|
||||
@ -653,6 +667,7 @@ struct wil6210_priv {
|
||||
struct dentry *debug;
|
||||
struct wil_blob_wrapper blobs[ARRAY_SIZE(fw_mapping)];
|
||||
u8 discovery_mode;
|
||||
u8 abft_len;
|
||||
|
||||
void *platform_handle;
|
||||
struct wil_platform_ops platform_ops;
|
||||
@ -816,8 +831,8 @@ int wmi_set_ie(struct wil6210_priv *wil, u8 type, u16 ie_len, const void *ie);
|
||||
int wmi_rx_chain_add(struct wil6210_priv *wil, struct vring *vring);
|
||||
int wmi_rxon(struct wil6210_priv *wil, bool on);
|
||||
int wmi_get_temperature(struct wil6210_priv *wil, u32 *t_m, u32 *t_r);
|
||||
int wmi_disconnect_sta(struct wil6210_priv *wil, const u8 *mac, u16 reason,
|
||||
bool full_disconnect);
|
||||
int wmi_disconnect_sta(struct wil6210_priv *wil, const u8 *mac,
|
||||
u16 reason, bool full_disconnect, bool del_sta);
|
||||
int wmi_addba(struct wil6210_priv *wil, u8 ringid, u8 size, u16 timeout);
|
||||
int wmi_delba_tx(struct wil6210_priv *wil, u8 ringid, u16 reason);
|
||||
int wmi_delba_rx(struct wil6210_priv *wil, u8 cidxtid, u16 reason);
|
||||
@ -827,6 +842,7 @@ int wmi_ps_dev_profile_cfg(struct wil6210_priv *wil,
|
||||
enum wmi_ps_profile_type ps_profile);
|
||||
int wmi_set_mgmt_retry(struct wil6210_priv *wil, u8 retry_short);
|
||||
int wmi_get_mgmt_retry(struct wil6210_priv *wil, u8 *retry_short);
|
||||
int wmi_new_sta(struct wil6210_priv *wil, const u8 *mac, u8 aid);
|
||||
int wil_addba_rx_request(struct wil6210_priv *wil, u8 cidxtid,
|
||||
u8 dialog_token, __le16 ba_param_set,
|
||||
__le16 ba_timeout, __le16 ba_seq_ctrl);
|
||||
@ -918,6 +934,7 @@ int wil_iftype_nl2wmi(enum nl80211_iftype type);
|
||||
int wil_ioctl(struct wil6210_priv *wil, void __user *data, int cmd);
|
||||
int wil_request_firmware(struct wil6210_priv *wil, const char *name,
|
||||
bool load);
|
||||
bool wil_fw_verify_file_exists(struct wil6210_priv *wil, const char *name);
|
||||
|
||||
int wil_can_suspend(struct wil6210_priv *wil, bool is_runtime);
|
||||
int wil_suspend(struct wil6210_priv *wil, bool is_runtime);
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2015 Qualcomm Atheros, Inc.
|
||||
* Copyright (c) 2015,2017 Qualcomm Atheros, Inc.
|
||||
*
|
||||
* Permission to use, copy, modify, and/or distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
@ -62,13 +62,13 @@ int wil_fw_copy_crash_dump(struct wil6210_priv *wil, void *dest, u32 size)
|
||||
u32 host_min, dump_size, offset, len;
|
||||
|
||||
if (wil_fw_get_crash_dump_bounds(wil, &dump_size, &host_min)) {
|
||||
wil_err(wil, "%s: fail to obtain crash dump size\n", __func__);
|
||||
wil_err(wil, "fail to obtain crash dump size\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (dump_size > size) {
|
||||
wil_err(wil, "%s: not enough space for dump. Need %d have %d\n",
|
||||
__func__, dump_size, size);
|
||||
wil_err(wil, "not enough space for dump. Need %d have %d\n",
|
||||
dump_size, size);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
@ -83,8 +83,9 @@ int wil_fw_copy_crash_dump(struct wil6210_priv *wil, void *dest, u32 size)
|
||||
len = map->to - map->from;
|
||||
offset = map->host - host_min;
|
||||
|
||||
wil_dbg_misc(wil, "%s() - dump %s, size %d, offset %d\n",
|
||||
__func__, fw_mapping[i].name, len, offset);
|
||||
wil_dbg_misc(wil,
|
||||
"fw_copy_crash_dump: - dump %s, size %d, offset %d\n",
|
||||
fw_mapping[i].name, len, offset);
|
||||
|
||||
wil_memcpy_fromio_32((void * __force)(dest + offset),
|
||||
(const void __iomem * __force)data, len);
|
||||
@ -99,7 +100,7 @@ void wil_fw_core_dump(struct wil6210_priv *wil)
|
||||
u32 fw_dump_size;
|
||||
|
||||
if (wil_fw_get_crash_dump_bounds(wil, &fw_dump_size, NULL)) {
|
||||
wil_err(wil, "%s: fail to get fw dump size\n", __func__);
|
||||
wil_err(wil, "fail to get fw dump size\n");
|
||||
return;
|
||||
}
|
||||
|
||||
@ -115,6 +116,5 @@ void wil_fw_core_dump(struct wil6210_priv *wil)
|
||||
* after 5 min
|
||||
*/
|
||||
dev_coredumpv(wil_to_dev(wil), fw_dump_data, fw_dump_size, GFP_KERNEL);
|
||||
wil_info(wil, "%s: fw core dumped, size %d bytes\n", __func__,
|
||||
fw_dump_size);
|
||||
wil_info(wil, "fw core dumped, size %d bytes\n", fw_dump_size);
|
||||
}
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2012-2016 Qualcomm Atheros, Inc.
|
||||
* Copyright (c) 2012-2017 Qualcomm Atheros, Inc.
|
||||
*
|
||||
* Permission to use, copy, modify, and/or distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
@ -24,16 +24,16 @@
|
||||
#include "trace.h"
|
||||
|
||||
static uint max_assoc_sta = WIL6210_MAX_CID;
|
||||
module_param(max_assoc_sta, uint, S_IRUGO | S_IWUSR);
|
||||
module_param(max_assoc_sta, uint, 0644);
|
||||
MODULE_PARM_DESC(max_assoc_sta, " Max number of stations associated to the AP");
|
||||
|
||||
int agg_wsize; /* = 0; */
|
||||
module_param(agg_wsize, int, S_IRUGO | S_IWUSR);
|
||||
module_param(agg_wsize, int, 0644);
|
||||
MODULE_PARM_DESC(agg_wsize, " Window size for Tx Block Ack after connect;"
|
||||
" 0 - use default; < 0 - don't auto-establish");
|
||||
|
||||
u8 led_id = WIL_LED_INVALID_ID;
|
||||
module_param(led_id, byte, S_IRUGO);
|
||||
module_param(led_id, byte, 0444);
|
||||
MODULE_PARM_DESC(led_id,
|
||||
" 60G device led enablement. Set the led ID (0-2) to enable");
|
||||
|
||||
@ -495,8 +495,8 @@ static void wmi_evt_connect(struct wil6210_priv *wil, int id, void *d, int len)
|
||||
}
|
||||
|
||||
ch = evt->channel + 1;
|
||||
wil_info(wil, "Connect %pM channel [%d] cid %d\n",
|
||||
evt->bssid, ch, evt->cid);
|
||||
wil_info(wil, "Connect %pM channel [%d] cid %d aid %d\n",
|
||||
evt->bssid, ch, evt->cid, evt->aid);
|
||||
wil_hex_dump_wmi("connect AI : ", DUMP_PREFIX_OFFSET, 16, 1,
|
||||
evt->assoc_info, len - sizeof(*evt), true);
|
||||
|
||||
@ -539,8 +539,8 @@ static void wmi_evt_connect(struct wil6210_priv *wil, int id, void *d, int len)
|
||||
} else if ((wdev->iftype == NL80211_IFTYPE_AP) ||
|
||||
(wdev->iftype == NL80211_IFTYPE_P2P_GO)) {
|
||||
if (wil->sta[evt->cid].status != wil_sta_unused) {
|
||||
wil_err(wil, "%s: AP: Invalid status %d for CID %d\n",
|
||||
__func__, wil->sta[evt->cid].status, evt->cid);
|
||||
wil_err(wil, "AP: Invalid status %d for CID %d\n",
|
||||
wil->sta[evt->cid].status, evt->cid);
|
||||
mutex_unlock(&wil->mutex);
|
||||
return;
|
||||
}
|
||||
@ -553,22 +553,19 @@ static void wmi_evt_connect(struct wil6210_priv *wil, int id, void *d, int len)
|
||||
|
||||
rc = wil_tx_init(wil, evt->cid);
|
||||
if (rc) {
|
||||
wil_err(wil, "%s: config tx vring failed for CID %d, rc (%d)\n",
|
||||
__func__, evt->cid, rc);
|
||||
wil_err(wil, "config tx vring failed for CID %d, rc (%d)\n",
|
||||
evt->cid, rc);
|
||||
wmi_disconnect_sta(wil, wil->sta[evt->cid].addr,
|
||||
WLAN_REASON_UNSPECIFIED, false);
|
||||
WLAN_REASON_UNSPECIFIED, false, false);
|
||||
} else {
|
||||
wil_info(wil, "%s: successful connection to CID %d\n",
|
||||
__func__, evt->cid);
|
||||
wil_info(wil, "successful connection to CID %d\n", evt->cid);
|
||||
}
|
||||
|
||||
if ((wdev->iftype == NL80211_IFTYPE_STATION) ||
|
||||
(wdev->iftype == NL80211_IFTYPE_P2P_CLIENT)) {
|
||||
if (rc) {
|
||||
netif_carrier_off(ndev);
|
||||
wil_err(wil,
|
||||
"%s: cfg80211_connect_result with failure\n",
|
||||
__func__);
|
||||
wil_err(wil, "cfg80211_connect_result with failure\n");
|
||||
cfg80211_connect_result(ndev, evt->bssid, NULL, 0,
|
||||
NULL, 0,
|
||||
WLAN_STATUS_UNSPECIFIED_FAILURE,
|
||||
@ -583,8 +580,12 @@ static void wmi_evt_connect(struct wil6210_priv *wil, int id, void *d, int len)
|
||||
}
|
||||
} else if ((wdev->iftype == NL80211_IFTYPE_AP) ||
|
||||
(wdev->iftype == NL80211_IFTYPE_P2P_GO)) {
|
||||
if (rc)
|
||||
if (rc) {
|
||||
if (disable_ap_sme)
|
||||
/* notify new_sta has failed */
|
||||
cfg80211_del_sta(ndev, evt->bssid, GFP_KERNEL);
|
||||
goto out;
|
||||
}
|
||||
|
||||
memset(&sinfo, 0, sizeof(sinfo));
|
||||
|
||||
@ -597,12 +598,13 @@ static void wmi_evt_connect(struct wil6210_priv *wil, int id, void *d, int len)
|
||||
|
||||
cfg80211_new_sta(ndev, evt->bssid, &sinfo, GFP_KERNEL);
|
||||
} else {
|
||||
wil_err(wil, "%s: unhandled iftype %d for CID %d\n",
|
||||
__func__, wdev->iftype, evt->cid);
|
||||
wil_err(wil, "unhandled iftype %d for CID %d\n", wdev->iftype,
|
||||
evt->cid);
|
||||
goto out;
|
||||
}
|
||||
|
||||
wil->sta[evt->cid].status = wil_sta_connected;
|
||||
wil->sta[evt->cid].aid = evt->aid;
|
||||
set_bit(wil_status_fwconnected, wil->status);
|
||||
wil_update_net_queues_bh(wil, NULL, false);
|
||||
|
||||
@ -687,6 +689,7 @@ static void wmi_evt_vring_en(struct wil6210_priv *wil, int id, void *d, int len)
|
||||
{
|
||||
struct wmi_vring_en_event *evt = d;
|
||||
u8 vri = evt->vring_index;
|
||||
struct wireless_dev *wdev = wil_to_wdev(wil);
|
||||
|
||||
wil_dbg_wmi(wil, "Enable vring %d\n", vri);
|
||||
|
||||
@ -694,7 +697,12 @@ static void wmi_evt_vring_en(struct wil6210_priv *wil, int id, void *d, int len)
|
||||
wil_err(wil, "Enable for invalid vring %d\n", vri);
|
||||
return;
|
||||
}
|
||||
wil->vring_tx_data[vri].dot1x_open = true;
|
||||
|
||||
if (wdev->iftype != NL80211_IFTYPE_AP || !disable_ap_sme)
|
||||
/* in AP mode with disable_ap_sme, this is done by
|
||||
* wil_cfg80211_change_station()
|
||||
*/
|
||||
wil->vring_tx_data[vri].dot1x_open = true;
|
||||
if (vri == wil->bcast_vring) /* no BA for bcast */
|
||||
return;
|
||||
if (agg_wsize >= 0)
|
||||
@ -919,8 +927,8 @@ void wmi_recv_cmd(struct wil6210_priv *wil)
|
||||
offsetof(struct wil6210_mbox_ctl, rx.tail), r->tail);
|
||||
|
||||
if (immed_reply) {
|
||||
wil_dbg_wmi(wil, "%s: Complete WMI 0x%04x\n",
|
||||
__func__, wil->reply_id);
|
||||
wil_dbg_wmi(wil, "recv_cmd: Complete WMI 0x%04x\n",
|
||||
wil->reply_id);
|
||||
kfree(evt);
|
||||
num_immed_reply++;
|
||||
complete(&wil->wmi_call);
|
||||
@ -934,7 +942,7 @@ void wmi_recv_cmd(struct wil6210_priv *wil)
|
||||
}
|
||||
}
|
||||
/* normally, 1 event per IRQ should be processed */
|
||||
wil_dbg_wmi(wil, "%s -> %d events queued, %d completed\n", __func__,
|
||||
wil_dbg_wmi(wil, "recv_cmd: -> %d events queued, %d completed\n",
|
||||
n - num_immed_reply, num_immed_reply);
|
||||
}
|
||||
|
||||
@ -950,6 +958,7 @@ int wmi_call(struct wil6210_priv *wil, u16 cmdid, void *buf, u16 len,
|
||||
wil->reply_id = reply_id;
|
||||
wil->reply_buf = reply;
|
||||
wil->reply_size = reply_size;
|
||||
reinit_completion(&wil->wmi_call);
|
||||
spin_unlock(&wil->wmi_ev_lock);
|
||||
|
||||
rc = __wmi_send(wil, cmdid, buf, len);
|
||||
@ -1069,6 +1078,8 @@ int wmi_pcp_start(struct wil6210_priv *wil, int bi, u8 wmi_nettype,
|
||||
.pcp_max_assoc_sta = max_assoc_sta,
|
||||
.hidden_ssid = hidden_ssid,
|
||||
.is_go = is_go,
|
||||
.disable_ap_sme = disable_ap_sme,
|
||||
.abft_len = wil->abft_len,
|
||||
};
|
||||
struct {
|
||||
struct wmi_cmd_hdr wmi;
|
||||
@ -1086,6 +1097,13 @@ int wmi_pcp_start(struct wil6210_priv *wil, int bi, u8 wmi_nettype,
|
||||
cmd.pcp_max_assoc_sta = WIL6210_MAX_CID;
|
||||
}
|
||||
|
||||
if (disable_ap_sme &&
|
||||
!test_bit(WMI_FW_CAPABILITY_DISABLE_AP_SME,
|
||||
wil->fw_capabilities)) {
|
||||
wil_err(wil, "disable_ap_sme not supported by FW\n");
|
||||
return -EOPNOTSUPP;
|
||||
}
|
||||
|
||||
/*
|
||||
* Processing time may be huge, in case of secure AP it takes about
|
||||
* 3500ms for FW to start AP
|
||||
@ -1352,7 +1370,7 @@ int wmi_rxon(struct wil6210_priv *wil, bool on)
|
||||
struct wmi_listen_started_event evt;
|
||||
} __packed reply;
|
||||
|
||||
wil_info(wil, "%s(%s)\n", __func__, on ? "on" : "off");
|
||||
wil_info(wil, "(%s)\n", on ? "on" : "off");
|
||||
|
||||
if (on) {
|
||||
rc = wmi_call(wil, WMI_START_LISTEN_CMDID, NULL, 0,
|
||||
@ -1456,12 +1474,15 @@ int wmi_get_temperature(struct wil6210_priv *wil, u32 *t_bb, u32 *t_rf)
|
||||
return 0;
|
||||
}
|
||||
|
||||
int wmi_disconnect_sta(struct wil6210_priv *wil, const u8 *mac, u16 reason,
|
||||
bool full_disconnect)
|
||||
int wmi_disconnect_sta(struct wil6210_priv *wil, const u8 *mac,
|
||||
u16 reason, bool full_disconnect, bool del_sta)
|
||||
{
|
||||
int rc;
|
||||
u16 reason_code;
|
||||
struct wmi_disconnect_sta_cmd cmd = {
|
||||
struct wmi_disconnect_sta_cmd disc_sta_cmd = {
|
||||
.disconnect_reason = cpu_to_le16(reason),
|
||||
};
|
||||
struct wmi_del_sta_cmd del_sta_cmd = {
|
||||
.disconnect_reason = cpu_to_le16(reason),
|
||||
};
|
||||
struct {
|
||||
@ -1469,12 +1490,19 @@ int wmi_disconnect_sta(struct wil6210_priv *wil, const u8 *mac, u16 reason,
|
||||
struct wmi_disconnect_event evt;
|
||||
} __packed reply;
|
||||
|
||||
ether_addr_copy(cmd.dst_mac, mac);
|
||||
wil_dbg_wmi(wil, "disconnect_sta: (%pM, reason %d)\n", mac, reason);
|
||||
|
||||
wil_dbg_wmi(wil, "%s(%pM, reason %d)\n", __func__, mac, reason);
|
||||
|
||||
rc = wmi_call(wil, WMI_DISCONNECT_STA_CMDID, &cmd, sizeof(cmd),
|
||||
WMI_DISCONNECT_EVENTID, &reply, sizeof(reply), 1000);
|
||||
if (del_sta) {
|
||||
ether_addr_copy(del_sta_cmd.dst_mac, mac);
|
||||
rc = wmi_call(wil, WMI_DEL_STA_CMDID, &del_sta_cmd,
|
||||
sizeof(del_sta_cmd), WMI_DISCONNECT_EVENTID,
|
||||
&reply, sizeof(reply), 1000);
|
||||
} else {
|
||||
ether_addr_copy(disc_sta_cmd.dst_mac, mac);
|
||||
rc = wmi_call(wil, WMI_DISCONNECT_STA_CMDID, &disc_sta_cmd,
|
||||
sizeof(disc_sta_cmd), WMI_DISCONNECT_EVENTID,
|
||||
&reply, sizeof(reply), 1000);
|
||||
}
|
||||
/* failure to disconnect in reasonable time treated as FW error */
|
||||
if (rc) {
|
||||
wil_fw_error_recovery(wil);
|
||||
@ -1507,8 +1535,8 @@ int wmi_addba(struct wil6210_priv *wil, u8 ringid, u8 size, u16 timeout)
|
||||
.amsdu = 0,
|
||||
};
|
||||
|
||||
wil_dbg_wmi(wil, "%s(ring %d size %d timeout %d)\n", __func__,
|
||||
ringid, size, timeout);
|
||||
wil_dbg_wmi(wil, "addba: (ring %d size %d timeout %d)\n", ringid, size,
|
||||
timeout);
|
||||
|
||||
return wmi_send(wil, WMI_VRING_BA_EN_CMDID, &cmd, sizeof(cmd));
|
||||
}
|
||||
@ -1520,8 +1548,7 @@ int wmi_delba_tx(struct wil6210_priv *wil, u8 ringid, u16 reason)
|
||||
.reason = cpu_to_le16(reason),
|
||||
};
|
||||
|
||||
wil_dbg_wmi(wil, "%s(ring %d reason %d)\n", __func__,
|
||||
ringid, reason);
|
||||
wil_dbg_wmi(wil, "delba_tx: (ring %d reason %d)\n", ringid, reason);
|
||||
|
||||
return wmi_send(wil, WMI_VRING_BA_DIS_CMDID, &cmd, sizeof(cmd));
|
||||
}
|
||||
@ -1533,8 +1560,8 @@ int wmi_delba_rx(struct wil6210_priv *wil, u8 cidxtid, u16 reason)
|
||||
.reason = cpu_to_le16(reason),
|
||||
};
|
||||
|
||||
wil_dbg_wmi(wil, "%s(CID %d TID %d reason %d)\n", __func__,
|
||||
cidxtid & 0xf, (cidxtid >> 4) & 0xf, reason);
|
||||
wil_dbg_wmi(wil, "delba_rx: (CID %d TID %d reason %d)\n", cidxtid & 0xf,
|
||||
(cidxtid >> 4) & 0xf, reason);
|
||||
|
||||
return wmi_send(wil, WMI_RCP_DELBA_CMDID, &cmd, sizeof(cmd));
|
||||
}
|
||||
@ -1686,11 +1713,29 @@ int wmi_abort_scan(struct wil6210_priv *wil)
|
||||
return rc;
|
||||
}
|
||||
|
||||
int wmi_new_sta(struct wil6210_priv *wil, const u8 *mac, u8 aid)
|
||||
{
|
||||
int rc;
|
||||
struct wmi_new_sta_cmd cmd = {
|
||||
.aid = aid,
|
||||
};
|
||||
|
||||
wil_dbg_wmi(wil, "new sta %pM, aid %d\n", mac, aid);
|
||||
|
||||
ether_addr_copy(cmd.dst_mac, mac);
|
||||
|
||||
rc = wmi_send(wil, WMI_NEW_STA_CMDID, &cmd, sizeof(cmd));
|
||||
if (rc)
|
||||
wil_err(wil, "Failed to send new sta (%d)\n", rc);
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
void wmi_event_flush(struct wil6210_priv *wil)
|
||||
{
|
||||
struct pending_wmi_event *evt, *t;
|
||||
|
||||
wil_dbg_wmi(wil, "%s()\n", __func__);
|
||||
wil_dbg_wmi(wil, "event_flush\n");
|
||||
|
||||
list_for_each_entry_safe(evt, t, &wil->pending_wmi_ev, list) {
|
||||
list_del(&evt->list);
|
||||
@ -1731,8 +1776,8 @@ static void wmi_event_handle(struct wil6210_priv *wil,
|
||||
WARN_ON(wil->reply_buf);
|
||||
wmi_evt_call_handler(wil, id, evt_data,
|
||||
len - sizeof(*wmi));
|
||||
wil_dbg_wmi(wil, "%s: Complete WMI 0x%04x\n",
|
||||
__func__, id);
|
||||
wil_dbg_wmi(wil, "event_handle: Complete WMI 0x%04x\n",
|
||||
id);
|
||||
complete(&wil->wmi_call);
|
||||
return;
|
||||
}
|
||||
@ -1779,11 +1824,11 @@ void wmi_event_worker(struct work_struct *work)
|
||||
struct pending_wmi_event *evt;
|
||||
struct list_head *lh;
|
||||
|
||||
wil_dbg_wmi(wil, "Start %s\n", __func__);
|
||||
wil_dbg_wmi(wil, "event_worker: Start\n");
|
||||
while ((lh = next_wmi_ev(wil)) != NULL) {
|
||||
evt = list_entry(lh, struct pending_wmi_event, list);
|
||||
wmi_event_handle(wil, &evt->event.hdr);
|
||||
kfree(evt);
|
||||
}
|
||||
wil_dbg_wmi(wil, "Finished %s\n", __func__);
|
||||
wil_dbg_wmi(wil, "event_worker: Finished\n");
|
||||
}
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2012-2016 Qualcomm Atheros, Inc.
|
||||
* Copyright (c) 2012-2017 Qualcomm Atheros, Inc.
|
||||
* Copyright (c) 2006-2012 Wilocity
|
||||
*
|
||||
* Permission to use, copy, modify, and/or distribute this software for any
|
||||
@ -56,6 +56,8 @@ enum wmi_fw_capability {
|
||||
WMI_FW_CAPABILITY_PS_CONFIG = 1,
|
||||
WMI_FW_CAPABILITY_RF_SECTORS = 2,
|
||||
WMI_FW_CAPABILITY_MGMT_RETRY_LIMIT = 3,
|
||||
WMI_FW_CAPABILITY_DISABLE_AP_SME = 4,
|
||||
WMI_FW_CAPABILITY_WMI_ONLY = 5,
|
||||
WMI_FW_CAPABILITY_MAX,
|
||||
};
|
||||
|
||||
@ -185,8 +187,11 @@ enum wmi_command_id {
|
||||
WMI_RS_CFG_CMDID = 0x921,
|
||||
WMI_GET_DETAILED_RS_RES_CMDID = 0x922,
|
||||
WMI_AOA_MEAS_CMDID = 0x923,
|
||||
WMI_BRP_SET_ANT_LIMIT_CMDID = 0x924,
|
||||
WMI_SET_MGMT_RETRY_LIMIT_CMDID = 0x930,
|
||||
WMI_GET_MGMT_RETRY_LIMIT_CMDID = 0x931,
|
||||
WMI_NEW_STA_CMDID = 0x935,
|
||||
WMI_DEL_STA_CMDID = 0x936,
|
||||
WMI_TOF_SESSION_START_CMDID = 0x991,
|
||||
WMI_TOF_GET_CAPABILITIES_CMDID = 0x992,
|
||||
WMI_TOF_SET_LCR_CMDID = 0x993,
|
||||
@ -543,7 +548,10 @@ struct wmi_pcp_start_cmd {
|
||||
u8 pcp_max_assoc_sta;
|
||||
u8 hidden_ssid;
|
||||
u8 is_go;
|
||||
u8 reserved0[7];
|
||||
u8 reserved0[5];
|
||||
/* abft_len override if non-0 */
|
||||
u8 abft_len;
|
||||
u8 disable_ap_sme;
|
||||
u8 network_type;
|
||||
u8 channel;
|
||||
u8 disable_sec_offload;
|
||||
@ -902,6 +910,18 @@ struct wmi_set_mgmt_retry_limit_cmd {
|
||||
u8 reserved[3];
|
||||
} __packed;
|
||||
|
||||
/* WMI_NEW_STA_CMDID */
|
||||
struct wmi_new_sta_cmd {
|
||||
u8 dst_mac[WMI_MAC_LEN];
|
||||
u8 aid;
|
||||
} __packed;
|
||||
|
||||
/* WMI_DEL_STA_CMDID */
|
||||
struct wmi_del_sta_cmd {
|
||||
u8 dst_mac[WMI_MAC_LEN];
|
||||
__le16 disconnect_reason;
|
||||
} __packed;
|
||||
|
||||
enum wmi_tof_burst_duration {
|
||||
WMI_TOF_BURST_DURATION_250_USEC = 2,
|
||||
WMI_TOF_BURST_DURATION_500_USEC = 3,
|
||||
@ -1067,6 +1087,7 @@ enum wmi_event_id {
|
||||
WMI_RS_CFG_DONE_EVENTID = 0x1921,
|
||||
WMI_GET_DETAILED_RS_RES_EVENTID = 0x1922,
|
||||
WMI_AOA_MEAS_EVENTID = 0x1923,
|
||||
WMI_BRP_SET_ANT_LIMIT_EVENTID = 0x1924,
|
||||
WMI_SET_MGMT_RETRY_LIMIT_EVENTID = 0x1930,
|
||||
WMI_GET_MGMT_RETRY_LIMIT_EVENTID = 0x1931,
|
||||
WMI_TOF_SESSION_END_EVENTID = 0x1991,
|
||||
@ -1287,12 +1308,13 @@ struct wmi_connect_event {
|
||||
u8 assoc_req_len;
|
||||
u8 assoc_resp_len;
|
||||
u8 cid;
|
||||
u8 reserved2[3];
|
||||
u8 aid;
|
||||
u8 reserved2[2];
|
||||
/* not in use */
|
||||
u8 assoc_info[0];
|
||||
} __packed;
|
||||
|
||||
/* WMI_DISCONNECT_EVENTID */
|
||||
/* disconnect_reason */
|
||||
enum wmi_disconnect_reason {
|
||||
WMI_DIS_REASON_NO_NETWORK_AVAIL = 0x01,
|
||||
/* bmiss */
|
||||
@ -1310,6 +1332,7 @@ enum wmi_disconnect_reason {
|
||||
WMI_DIS_REASON_IBSS_MERGE = 0x0E,
|
||||
};
|
||||
|
||||
/* WMI_DISCONNECT_EVENTID */
|
||||
struct wmi_disconnect_event {
|
||||
/* reason code, see 802.11 spec. */
|
||||
__le16 protocol_reason_status;
|
||||
@ -1759,6 +1782,42 @@ struct wmi_get_detailed_rs_res_event {
|
||||
u8 reserved[3];
|
||||
} __packed;
|
||||
|
||||
/* BRP antenna limit mode */
|
||||
enum wmi_brp_ant_limit_mode {
|
||||
/* Disable BRP force antenna limit */
|
||||
WMI_BRP_ANT_LIMIT_MODE_DISABLE = 0x00,
|
||||
/* Define maximal antennas limit. Only effective antennas will be
|
||||
* actually used
|
||||
*/
|
||||
WMI_BRP_ANT_LIMIT_MODE_EFFECTIVE = 0x01,
|
||||
/* Force a specific number of antennas */
|
||||
WMI_BRP_ANT_LIMIT_MODE_FORCE = 0x02,
|
||||
/* number of BRP antenna limit modes */
|
||||
WMI_BRP_ANT_LIMIT_MODES_NUM = 0x03,
|
||||
};
|
||||
|
||||
/* WMI_BRP_SET_ANT_LIMIT_CMDID */
|
||||
struct wmi_brp_set_ant_limit_cmd {
|
||||
/* connection id */
|
||||
u8 cid;
|
||||
/* enum wmi_brp_ant_limit_mode */
|
||||
u8 limit_mode;
|
||||
/* antenna limit count, 1-27
|
||||
* disable_mode - ignored
|
||||
* effective_mode - upper limit to number of antennas to be used
|
||||
* force_mode - exact number of antennas to be used
|
||||
*/
|
||||
u8 ant_limit;
|
||||
u8 reserved;
|
||||
} __packed;
|
||||
|
||||
/* WMI_BRP_SET_ANT_LIMIT_EVENTID */
|
||||
struct wmi_brp_set_ant_limit_event {
|
||||
/* wmi_fw_status */
|
||||
u8 status;
|
||||
u8 reserved[3];
|
||||
} __packed;
|
||||
|
||||
/* broadcast connection ID */
|
||||
#define WMI_LINK_MAINTAIN_CFG_CID_BROADCAST (0xFFFFFFFF)
|
||||
|
||||
|
@ -1104,6 +1104,7 @@ static const struct sdio_device_id brcmf_sdmmc_ids[] = {
|
||||
BRCMF_SDIO_DEVICE(SDIO_DEVICE_ID_BROADCOM_4339),
|
||||
BRCMF_SDIO_DEVICE(SDIO_DEVICE_ID_BROADCOM_43430),
|
||||
BRCMF_SDIO_DEVICE(SDIO_DEVICE_ID_BROADCOM_4345),
|
||||
BRCMF_SDIO_DEVICE(SDIO_DEVICE_ID_BROADCOM_43455),
|
||||
BRCMF_SDIO_DEVICE(SDIO_DEVICE_ID_BROADCOM_4354),
|
||||
BRCMF_SDIO_DEVICE(SDIO_DEVICE_ID_BROADCOM_4356),
|
||||
{ /* end: all zeroes */ }
|
||||
|
@ -218,9 +218,6 @@ int brcmf_bus_get_memdump(struct brcmf_bus *bus, void *data, size_t len)
|
||||
* interface functions from common layer
|
||||
*/
|
||||
|
||||
bool brcmf_c_prec_enq(struct device *dev, struct pktq *q, struct sk_buff *pkt,
|
||||
int prec);
|
||||
|
||||
/* Receive frame for delivery to OS. Callee disposes of rxp. */
|
||||
void brcmf_rx_frame(struct device *dev, struct sk_buff *rxp, bool handle_event);
|
||||
/* Receive async event packet from firmware. Callee disposes of rxp. */
|
||||
@ -241,13 +238,12 @@ void brcmf_txcomplete(struct device *dev, struct sk_buff *txp, bool success);
|
||||
/* Configure the "global" bus state used by upper layers */
|
||||
void brcmf_bus_change_state(struct brcmf_bus *bus, enum brcmf_bus_state state);
|
||||
|
||||
int brcmf_bus_start(struct device *dev);
|
||||
int brcmf_bus_started(struct device *dev);
|
||||
s32 brcmf_iovar_data_set(struct device *dev, char *name, void *data, u32 len);
|
||||
void brcmf_bus_add_txhdrlen(struct device *dev, uint len);
|
||||
|
||||
#ifdef CONFIG_BRCMFMAC_SDIO
|
||||
void brcmf_sdio_exit(void);
|
||||
void brcmf_sdio_init(void);
|
||||
void brcmf_sdio_register(void);
|
||||
#endif
|
||||
#ifdef CONFIG_BRCMFMAC_USB
|
||||
|
@ -138,7 +138,6 @@ static struct ieee80211_rate __wl_rates[] = {
|
||||
.band = NL80211_BAND_2GHZ, \
|
||||
.center_freq = (_freq), \
|
||||
.hw_value = (_channel), \
|
||||
.flags = IEEE80211_CHAN_DISABLED, \
|
||||
.max_antenna_gain = 0, \
|
||||
.max_power = 30, \
|
||||
}
|
||||
@ -147,7 +146,6 @@ static struct ieee80211_rate __wl_rates[] = {
|
||||
.band = NL80211_BAND_5GHZ, \
|
||||
.center_freq = 5000 + (5 * (_channel)), \
|
||||
.hw_value = (_channel), \
|
||||
.flags = IEEE80211_CHAN_DISABLED, \
|
||||
.max_antenna_gain = 0, \
|
||||
.max_power = 30, \
|
||||
}
|
||||
@ -328,7 +326,7 @@ u16 channel_to_chanspec(struct brcmu_d11inf *d11inf,
|
||||
* triples, returning a pointer to the substring whose first element
|
||||
* matches tag
|
||||
*/
|
||||
const struct brcmf_tlv *
|
||||
static const struct brcmf_tlv *
|
||||
brcmf_parse_tlvs(const void *buf, int buflen, uint key)
|
||||
{
|
||||
const struct brcmf_tlv *elt = buf;
|
||||
@ -3332,7 +3330,6 @@ brcmf_notify_sched_scan_results(struct brcmf_if *ifp,
|
||||
goto out_err;
|
||||
}
|
||||
|
||||
data += sizeof(struct brcmf_pno_scanresults_le);
|
||||
netinfo_start = brcmf_get_netinfo_array(pfn_result);
|
||||
|
||||
for (i = 0; i < result_count; i++) {
|
||||
@ -3480,8 +3477,7 @@ brcmf_wowl_nd_results(struct brcmf_if *ifp, const struct brcmf_event_msg *e,
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
data += sizeof(struct brcmf_pno_scanresults_le);
|
||||
netinfo = (struct brcmf_pno_net_info_le *)data;
|
||||
netinfo = brcmf_get_netinfo_array(pfn_result);
|
||||
memcpy(cfg->wowl.nd->ssid.ssid, netinfo->SSID, netinfo->SSID_len);
|
||||
cfg->wowl.nd->ssid.ssid_len = netinfo->SSID_len;
|
||||
cfg->wowl.nd->n_channels = 1;
|
||||
@ -5071,6 +5067,29 @@ static int brcmf_cfg80211_tdls_oper(struct wiphy *wiphy,
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int
|
||||
brcmf_cfg80211_update_conn_params(struct wiphy *wiphy,
|
||||
struct net_device *ndev,
|
||||
struct cfg80211_connect_params *sme,
|
||||
u32 changed)
|
||||
{
|
||||
struct brcmf_if *ifp;
|
||||
int err;
|
||||
|
||||
if (!(changed & UPDATE_ASSOC_IES))
|
||||
return 0;
|
||||
|
||||
ifp = netdev_priv(ndev);
|
||||
err = brcmf_vif_set_mgmt_ie(ifp->vif, BRCMF_VNDR_IE_ASSOCREQ_FLAG,
|
||||
sme->ie, sme->ie_len);
|
||||
if (err)
|
||||
brcmf_err("Set Assoc REQ IE Failed\n");
|
||||
else
|
||||
brcmf_dbg(TRACE, "Applied Vndr IEs for Assoc request\n");
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
#ifdef CONFIG_PM
|
||||
static int
|
||||
brcmf_cfg80211_set_rekey_data(struct wiphy *wiphy, struct net_device *ndev,
|
||||
@ -5138,6 +5157,7 @@ static struct cfg80211_ops brcmf_cfg80211_ops = {
|
||||
.crit_proto_start = brcmf_cfg80211_crit_proto_start,
|
||||
.crit_proto_stop = brcmf_cfg80211_crit_proto_stop,
|
||||
.tdls_oper = brcmf_cfg80211_tdls_oper,
|
||||
.update_connect_params = brcmf_cfg80211_update_conn_params,
|
||||
};
|
||||
|
||||
struct brcmf_cfg80211_vif *brcmf_alloc_vif(struct brcmf_cfg80211_info *cfg,
|
||||
@ -5825,7 +5845,6 @@ static int brcmf_construct_chaninfo(struct brcmf_cfg80211_info *cfg,
|
||||
u32 i, j;
|
||||
u32 total;
|
||||
u32 chaninfo;
|
||||
u32 index;
|
||||
|
||||
pbuf = kzalloc(BRCMF_DCMD_MEDLEN, GFP_KERNEL);
|
||||
|
||||
@ -5873,33 +5892,36 @@ static int brcmf_construct_chaninfo(struct brcmf_cfg80211_info *cfg,
|
||||
ch.bw == BRCMU_CHAN_BW_80)
|
||||
continue;
|
||||
|
||||
channel = band->channels;
|
||||
index = band->n_channels;
|
||||
channel = NULL;
|
||||
for (j = 0; j < band->n_channels; j++) {
|
||||
if (channel[j].hw_value == ch.control_ch_num) {
|
||||
index = j;
|
||||
if (band->channels[j].hw_value == ch.control_ch_num) {
|
||||
channel = &band->channels[j];
|
||||
break;
|
||||
}
|
||||
}
|
||||
channel[index].center_freq =
|
||||
ieee80211_channel_to_frequency(ch.control_ch_num,
|
||||
band->band);
|
||||
channel[index].hw_value = ch.control_ch_num;
|
||||
if (!channel) {
|
||||
/* It seems firmware supports some channel we never
|
||||
* considered. Something new in IEEE standard?
|
||||
*/
|
||||
brcmf_err("Ignoring unexpected firmware channel %d\n",
|
||||
ch.control_ch_num);
|
||||
continue;
|
||||
}
|
||||
|
||||
/* assuming the chanspecs order is HT20,
|
||||
* HT40 upper, HT40 lower, and VHT80.
|
||||
*/
|
||||
if (ch.bw == BRCMU_CHAN_BW_80) {
|
||||
channel[index].flags &= ~IEEE80211_CHAN_NO_80MHZ;
|
||||
channel->flags &= ~IEEE80211_CHAN_NO_80MHZ;
|
||||
} else if (ch.bw == BRCMU_CHAN_BW_40) {
|
||||
brcmf_update_bw40_channel_flag(&channel[index], &ch);
|
||||
brcmf_update_bw40_channel_flag(channel, &ch);
|
||||
} else {
|
||||
/* enable the channel and disable other bandwidths
|
||||
* for now as mentioned order assure they are enabled
|
||||
* for subsequent chanspecs.
|
||||
*/
|
||||
channel[index].flags = IEEE80211_CHAN_NO_HT40 |
|
||||
IEEE80211_CHAN_NO_80MHZ;
|
||||
channel->flags = IEEE80211_CHAN_NO_HT40 |
|
||||
IEEE80211_CHAN_NO_80MHZ;
|
||||
ch.bw = BRCMU_CHAN_BW_20;
|
||||
cfg->d11inf.encchspec(&ch);
|
||||
chaninfo = ch.chspec;
|
||||
@ -5907,11 +5929,11 @@ static int brcmf_construct_chaninfo(struct brcmf_cfg80211_info *cfg,
|
||||
&chaninfo);
|
||||
if (!err) {
|
||||
if (chaninfo & WL_CHAN_RADAR)
|
||||
channel[index].flags |=
|
||||
channel->flags |=
|
||||
(IEEE80211_CHAN_RADAR |
|
||||
IEEE80211_CHAN_NO_IR);
|
||||
if (chaninfo & WL_CHAN_PASSIVE)
|
||||
channel[index].flags |=
|
||||
channel->flags |=
|
||||
IEEE80211_CHAN_NO_IR;
|
||||
}
|
||||
}
|
||||
@ -6341,7 +6363,7 @@ static void brcmf_wiphy_pno_params(struct wiphy *wiphy)
|
||||
}
|
||||
|
||||
#ifdef CONFIG_PM
|
||||
static struct wiphy_wowlan_support brcmf_wowlan_support = {
|
||||
static const struct wiphy_wowlan_support brcmf_wowlan_support = {
|
||||
.flags = WIPHY_WOWLAN_MAGIC_PKT | WIPHY_WOWLAN_DISCONNECT,
|
||||
.n_patterns = BRCMF_WOWL_MAXPATTERNS,
|
||||
.pattern_max_len = BRCMF_WOWL_MAXPATTERNSIZE,
|
||||
@ -6354,19 +6376,29 @@ static void brcmf_wiphy_wowl_params(struct wiphy *wiphy, struct brcmf_if *ifp)
|
||||
{
|
||||
#ifdef CONFIG_PM
|
||||
struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
|
||||
struct wiphy_wowlan_support *wowl;
|
||||
|
||||
wowl = kmemdup(&brcmf_wowlan_support, sizeof(brcmf_wowlan_support),
|
||||
GFP_KERNEL);
|
||||
if (!wowl) {
|
||||
brcmf_err("only support basic wowlan features\n");
|
||||
wiphy->wowlan = &brcmf_wowlan_support;
|
||||
return;
|
||||
}
|
||||
|
||||
if (brcmf_feat_is_enabled(ifp, BRCMF_FEAT_PNO)) {
|
||||
if (brcmf_feat_is_enabled(ifp, BRCMF_FEAT_WOWL_ND)) {
|
||||
brcmf_wowlan_support.flags |= WIPHY_WOWLAN_NET_DETECT;
|
||||
wowl->flags |= WIPHY_WOWLAN_NET_DETECT;
|
||||
wowl->max_nd_match_sets = BRCMF_PNO_MAX_PFN_COUNT;
|
||||
init_waitqueue_head(&cfg->wowl.nd_data_wait);
|
||||
}
|
||||
}
|
||||
if (brcmf_feat_is_enabled(ifp, BRCMF_FEAT_WOWL_GTK)) {
|
||||
brcmf_wowlan_support.flags |= WIPHY_WOWLAN_SUPPORTS_GTK_REKEY;
|
||||
brcmf_wowlan_support.flags |= WIPHY_WOWLAN_GTK_REKEY_FAILURE;
|
||||
wowl->flags |= WIPHY_WOWLAN_SUPPORTS_GTK_REKEY;
|
||||
wowl->flags |= WIPHY_WOWLAN_GTK_REKEY_FAILURE;
|
||||
}
|
||||
|
||||
wiphy->wowlan = &brcmf_wowlan_support;
|
||||
wiphy->wowlan = wowl;
|
||||
#endif
|
||||
}
|
||||
|
||||
@ -6477,8 +6509,7 @@ static int brcmf_setup_wiphy(struct wiphy *wiphy, struct brcmf_if *ifp)
|
||||
wiphy->bands[NL80211_BAND_5GHZ] = band;
|
||||
}
|
||||
}
|
||||
err = brcmf_setup_wiphybands(wiphy);
|
||||
return err;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static s32 brcmf_config_dongle(struct brcmf_cfg80211_info *cfg)
|
||||
@ -6748,6 +6779,10 @@ static void brcmf_free_wiphy(struct wiphy *wiphy)
|
||||
kfree(wiphy->bands[NL80211_BAND_5GHZ]->channels);
|
||||
kfree(wiphy->bands[NL80211_BAND_5GHZ]);
|
||||
}
|
||||
#if IS_ENABLED(CONFIG_PM)
|
||||
if (wiphy->wowlan != &brcmf_wowlan_support)
|
||||
kfree(wiphy->wowlan);
|
||||
#endif
|
||||
wiphy_free(wiphy);
|
||||
}
|
||||
|
||||
@ -6843,6 +6878,12 @@ struct brcmf_cfg80211_info *brcmf_cfg80211_attach(struct brcmf_pub *drvr,
|
||||
goto priv_out;
|
||||
}
|
||||
|
||||
err = brcmf_setup_wiphybands(wiphy);
|
||||
if (err) {
|
||||
brcmf_err("Setting wiphy bands failed (%d)\n", err);
|
||||
goto wiphy_unreg_out;
|
||||
}
|
||||
|
||||
/* If cfg80211 didn't disable 40MHz HT CAP in wiphy_register(),
|
||||
* setup 40MHz in 2GHz band and enable OBSS scanning.
|
||||
*/
|
||||
|
@ -396,8 +396,6 @@ void brcmf_free_vif(struct brcmf_cfg80211_vif *vif);
|
||||
s32 brcmf_vif_set_mgmt_ie(struct brcmf_cfg80211_vif *vif, s32 pktflag,
|
||||
const u8 *vndr_ie_buf, u32 vndr_ie_len);
|
||||
s32 brcmf_vif_clear_mgmt_ies(struct brcmf_cfg80211_vif *vif);
|
||||
const struct brcmf_tlv *
|
||||
brcmf_parse_tlvs(const void *buf, int buflen, uint key);
|
||||
u16 channel_to_chanspec(struct brcmu_d11inf *d11inf,
|
||||
struct ieee80211_channel *ch);
|
||||
bool brcmf_get_vif_state_any(struct brcmf_cfg80211_info *cfg,
|
||||
|
@ -74,7 +74,7 @@ module_param_named(roamoff, brcmf_roamoff, int, S_IRUSR);
|
||||
MODULE_PARM_DESC(roamoff, "Do not use internal roaming engine");
|
||||
|
||||
#ifdef DEBUG
|
||||
/* always succeed brcmf_bus_start() */
|
||||
/* always succeed brcmf_bus_started() */
|
||||
static int brcmf_ignore_probe_fail;
|
||||
module_param_named(ignore_probe_fail, brcmf_ignore_probe_fail, int, 0);
|
||||
MODULE_PARM_DESC(ignore_probe_fail, "always succeed probe for debugging");
|
||||
@ -299,11 +299,9 @@ struct brcmf_mp_device *brcmf_get_module_param(struct device *dev,
|
||||
}
|
||||
}
|
||||
}
|
||||
if ((bus_type == BRCMF_BUSTYPE_SDIO) && (!found)) {
|
||||
/* No platform data for this device. In case of SDIO try OF
|
||||
* (Open Firwmare) Device Tree.
|
||||
*/
|
||||
brcmf_of_probe(dev, &settings->bus.sdio);
|
||||
if (!found) {
|
||||
/* No platform data for this device, try OF (Open Firwmare) */
|
||||
brcmf_of_probe(dev, bus_type, settings);
|
||||
}
|
||||
return settings;
|
||||
}
|
||||
|
@ -65,6 +65,8 @@ struct brcmf_mp_device {
|
||||
} bus;
|
||||
};
|
||||
|
||||
void brcmf_c_set_joinpref_default(struct brcmf_if *ifp);
|
||||
|
||||
struct brcmf_mp_device *brcmf_get_module_param(struct device *dev,
|
||||
enum brcmf_bus_type bus_type,
|
||||
u32 chip, u32 chiprev);
|
||||
|
@ -966,7 +966,7 @@ static int brcmf_revinfo_read(struct seq_file *s, void *data)
|
||||
return 0;
|
||||
}
|
||||
|
||||
int brcmf_bus_start(struct device *dev)
|
||||
int brcmf_bus_started(struct device *dev)
|
||||
{
|
||||
int ret = -1;
|
||||
struct brcmf_bus *bus_if = dev_get_drvdata(dev);
|
||||
@ -1075,16 +1075,6 @@ void brcmf_bus_add_txhdrlen(struct device *dev, uint len)
|
||||
}
|
||||
}
|
||||
|
||||
static void brcmf_bus_detach(struct brcmf_pub *drvr)
|
||||
{
|
||||
brcmf_dbg(TRACE, "Enter\n");
|
||||
|
||||
if (drvr) {
|
||||
/* Stop the bus module */
|
||||
brcmf_bus_stop(drvr->bus_if);
|
||||
}
|
||||
}
|
||||
|
||||
void brcmf_dev_reset(struct device *dev)
|
||||
{
|
||||
struct brcmf_bus *bus_if = dev_get_drvdata(dev);
|
||||
@ -1131,7 +1121,7 @@ void brcmf_detach(struct device *dev)
|
||||
|
||||
brcmf_fws_deinit(drvr);
|
||||
|
||||
brcmf_bus_detach(drvr);
|
||||
brcmf_bus_stop(drvr->bus_if);
|
||||
|
||||
brcmf_proto_detach(drvr);
|
||||
|
||||
|
@ -216,7 +216,6 @@ void brcmf_txflowblock_if(struct brcmf_if *ifp,
|
||||
void brcmf_txfinalize(struct brcmf_if *ifp, struct sk_buff *txp, bool success);
|
||||
void brcmf_netif_rx(struct brcmf_if *ifp, struct sk_buff *skb);
|
||||
void brcmf_net_setcarrier(struct brcmf_if *ifp, bool on);
|
||||
void brcmf_c_set_joinpref_default(struct brcmf_if *ifp);
|
||||
int __init brcmf_core_init(void);
|
||||
void __exit brcmf_core_exit(void);
|
||||
|
||||
|
@ -23,14 +23,17 @@
|
||||
#include "common.h"
|
||||
#include "of.h"
|
||||
|
||||
void brcmf_of_probe(struct device *dev, struct brcmfmac_sdio_pd *sdio)
|
||||
void brcmf_of_probe(struct device *dev, enum brcmf_bus_type bus_type,
|
||||
struct brcmf_mp_device *settings)
|
||||
{
|
||||
struct brcmfmac_sdio_pd *sdio = &settings->bus.sdio;
|
||||
struct device_node *np = dev->of_node;
|
||||
int irq;
|
||||
u32 irqf;
|
||||
u32 val;
|
||||
|
||||
if (!np || !of_device_is_compatible(np, "brcm,bcm4329-fmac"))
|
||||
if (!np || bus_type != BRCMF_BUSTYPE_SDIO ||
|
||||
!of_device_is_compatible(np, "brcm,bcm4329-fmac"))
|
||||
return;
|
||||
|
||||
if (of_property_read_u32(np, "brcm,drive-strength", &val) == 0)
|
||||
|
@ -14,9 +14,11 @@
|
||||
* CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
#ifdef CONFIG_OF
|
||||
void brcmf_of_probe(struct device *dev, struct brcmfmac_sdio_pd *sdio);
|
||||
void brcmf_of_probe(struct device *dev, enum brcmf_bus_type bus_type,
|
||||
struct brcmf_mp_device *settings);
|
||||
#else
|
||||
static void brcmf_of_probe(struct device *dev, struct brcmfmac_sdio_pd *sdio)
|
||||
static void brcmf_of_probe(struct device *dev, enum brcmf_bus_type bus_type,
|
||||
struct brcmf_mp_device *settings)
|
||||
{
|
||||
}
|
||||
#endif /* CONFIG_OF */
|
||||
|
@ -601,7 +601,6 @@ static void brcmf_pcie_attach(struct brcmf_pciedev_info *devinfo)
|
||||
{
|
||||
u32 config;
|
||||
|
||||
brcmf_pcie_select_core(devinfo, BCMA_CORE_PCIE2);
|
||||
/* BAR1 window may not be sized properly */
|
||||
brcmf_pcie_select_core(devinfo, BCMA_CORE_PCIE2);
|
||||
brcmf_pcie_write_reg32(devinfo, BRCMF_PCIE_PCIE2REG_CONFIGADDR, 0x4e0);
|
||||
@ -1572,7 +1571,7 @@ static int brcmf_pcie_attach_bus(struct brcmf_pciedev_info *devinfo)
|
||||
if (ret) {
|
||||
brcmf_err("brcmf_attach failed\n");
|
||||
} else {
|
||||
ret = brcmf_bus_start(&devinfo->pdev->dev);
|
||||
ret = brcmf_bus_started(&devinfo->pdev->dev);
|
||||
if (ret)
|
||||
brcmf_err("dongle is not responding\n");
|
||||
}
|
||||
|
@ -1661,7 +1661,7 @@ static u8 brcmf_sdio_rxglom(struct brcmf_sdio *bus, u8 rxseq)
|
||||
pfirst->len, pfirst->next,
|
||||
pfirst->prev);
|
||||
skb_unlink(pfirst, &bus->glom);
|
||||
if (brcmf_sdio_fromevntchan(pfirst->data))
|
||||
if (brcmf_sdio_fromevntchan(&dptr[SDPCM_HWHDR_LEN]))
|
||||
brcmf_rx_event(bus->sdiodev->dev, pfirst);
|
||||
else
|
||||
brcmf_rx_frame(bus->sdiodev->dev, pfirst,
|
||||
@ -4065,7 +4065,7 @@ static void brcmf_sdio_firmware_callback(struct device *dev,
|
||||
|
||||
sdio_release_host(sdiodev->func[1]);
|
||||
|
||||
err = brcmf_bus_start(dev);
|
||||
err = brcmf_bus_started(dev);
|
||||
if (err != 0) {
|
||||
brcmf_err("dongle is not responding\n");
|
||||
goto fail;
|
||||
|
@ -1148,7 +1148,7 @@ static int brcmf_usb_bus_setup(struct brcmf_usbdev_info *devinfo)
|
||||
if (ret)
|
||||
goto fail;
|
||||
|
||||
ret = brcmf_bus_start(devinfo->dev);
|
||||
ret = brcmf_bus_started(devinfo->dev);
|
||||
if (ret)
|
||||
goto fail;
|
||||
|
||||
|
@ -2310,7 +2310,7 @@ static ssize_t iwl_dbgfs_fw_restart_write(struct file *file,
|
||||
{
|
||||
struct iwl_priv *priv = file->private_data;
|
||||
bool restart_fw = iwlwifi_mod_params.restart_fw;
|
||||
int ret;
|
||||
int __maybe_unused ret;
|
||||
|
||||
iwlwifi_mod_params.restart_fw = true;
|
||||
|
||||
|
@ -163,7 +163,7 @@ int iwlagn_mac_setup_register(struct iwl_priv *priv,
|
||||
REGULATORY_DISABLE_BEACON_HINTS;
|
||||
|
||||
#ifdef CONFIG_PM_SLEEP
|
||||
if (priv->fw->img[IWL_UCODE_WOWLAN].sec[0].len &&
|
||||
if (priv->fw->img[IWL_UCODE_WOWLAN].num_sec &&
|
||||
priv->trans->ops->d3_suspend &&
|
||||
priv->trans->ops->d3_resume &&
|
||||
device_can_wakeup(priv->trans->dev)) {
|
||||
|
@ -364,7 +364,7 @@ static void rs_program_fix_rate(struct iwl_priv *priv,
|
||||
/*
|
||||
get the traffic load value for tid
|
||||
*/
|
||||
static u32 rs_tl_get_load(struct iwl_lq_sta *lq_data, u8 tid)
|
||||
static void rs_tl_get_load(struct iwl_lq_sta *lq_data, u8 tid)
|
||||
{
|
||||
u32 curr_time = jiffies_to_msecs(jiffies);
|
||||
u32 time_diff;
|
||||
@ -372,14 +372,14 @@ static u32 rs_tl_get_load(struct iwl_lq_sta *lq_data, u8 tid)
|
||||
struct iwl_traffic_load *tl = NULL;
|
||||
|
||||
if (tid >= IWL_MAX_TID_COUNT)
|
||||
return 0;
|
||||
return;
|
||||
|
||||
tl = &(lq_data->load[tid]);
|
||||
|
||||
curr_time -= curr_time % TID_ROUND_VALUE;
|
||||
|
||||
if (!(tl->queue_count))
|
||||
return 0;
|
||||
return;
|
||||
|
||||
time_diff = TIME_WRAP_AROUND(tl->time_stamp, curr_time);
|
||||
index = time_diff / TID_QUEUE_CELL_SPACING;
|
||||
@ -388,8 +388,6 @@ static u32 rs_tl_get_load(struct iwl_lq_sta *lq_data, u8 tid)
|
||||
/* TID_MAX_TIME_DIFF */
|
||||
if (index >= TID_QUEUE_MAX_SIZE)
|
||||
rs_tl_rm_old_stats(tl, curr_time);
|
||||
|
||||
return tl->total;
|
||||
}
|
||||
|
||||
static int rs_tl_turn_on_agg_for_tid(struct iwl_priv *priv,
|
||||
@ -397,7 +395,6 @@ static int rs_tl_turn_on_agg_for_tid(struct iwl_priv *priv,
|
||||
struct ieee80211_sta *sta)
|
||||
{
|
||||
int ret = -EAGAIN;
|
||||
u32 load;
|
||||
|
||||
/*
|
||||
* Don't create TX aggregation sessions when in high
|
||||
@ -410,7 +407,7 @@ static int rs_tl_turn_on_agg_for_tid(struct iwl_priv *priv,
|
||||
return ret;
|
||||
}
|
||||
|
||||
load = rs_tl_get_load(lq_data, tid);
|
||||
rs_tl_get_load(lq_data, tid);
|
||||
|
||||
IWL_DEBUG_HT(priv, "Starting Tx agg: STA: %pM tid: %d\n",
|
||||
sta->addr, tid);
|
||||
|
@ -407,7 +407,7 @@ int iwl_run_init_ucode(struct iwl_priv *priv)
|
||||
lockdep_assert_held(&priv->mutex);
|
||||
|
||||
/* No init ucode required? Curious, but maybe ok */
|
||||
if (!priv->fw->img[IWL_UCODE_INIT].sec[0].len)
|
||||
if (!priv->fw->img[IWL_UCODE_INIT].num_sec)
|
||||
return 0;
|
||||
|
||||
iwl_init_notification_wait(&priv->notif_wait, &calib_wait,
|
||||
|
@ -371,4 +371,4 @@ const struct iwl_cfg iwl6000_3agn_cfg = {
|
||||
MODULE_FIRMWARE(IWL6000_MODULE_FIRMWARE(IWL6000_UCODE_API_MAX));
|
||||
MODULE_FIRMWARE(IWL6050_MODULE_FIRMWARE(IWL6050_UCODE_API_MAX));
|
||||
MODULE_FIRMWARE(IWL6005_MODULE_FIRMWARE(IWL6000G2_UCODE_API_MAX));
|
||||
MODULE_FIRMWARE(IWL6030_MODULE_FIRMWARE(IWL6000G2B_UCODE_API_MAX));
|
||||
MODULE_FIRMWARE(IWL6030_MODULE_FIRMWARE(IWL6000G2_UCODE_API_MAX));
|
||||
|
@ -73,8 +73,8 @@
|
||||
/* Highest firmware API version supported */
|
||||
#define IWL7260_UCODE_API_MAX 17
|
||||
#define IWL7265_UCODE_API_MAX 17
|
||||
#define IWL7265D_UCODE_API_MAX 26
|
||||
#define IWL3168_UCODE_API_MAX 26
|
||||
#define IWL7265D_UCODE_API_MAX 28
|
||||
#define IWL3168_UCODE_API_MAX 28
|
||||
|
||||
/* Lowest firmware API version supported */
|
||||
#define IWL7260_UCODE_API_MIN 17
|
||||
|
@ -70,8 +70,8 @@
|
||||
#include "iwl-agn-hw.h"
|
||||
|
||||
/* Highest firmware API version supported */
|
||||
#define IWL8000_UCODE_API_MAX 26
|
||||
#define IWL8265_UCODE_API_MAX 26
|
||||
#define IWL8000_UCODE_API_MAX 28
|
||||
#define IWL8265_UCODE_API_MAX 28
|
||||
|
||||
/* Lowest firmware API version supported */
|
||||
#define IWL8000_UCODE_API_MIN 17
|
||||
|
@ -55,7 +55,7 @@
|
||||
#include "iwl-agn-hw.h"
|
||||
|
||||
/* Highest firmware API version supported */
|
||||
#define IWL9000_UCODE_API_MAX 26
|
||||
#define IWL9000_UCODE_API_MAX 28
|
||||
|
||||
/* Lowest firmware API version supported */
|
||||
#define IWL9000_UCODE_API_MIN 17
|
||||
|
@ -55,7 +55,7 @@
|
||||
#include "iwl-agn-hw.h"
|
||||
|
||||
/* Highest firmware API version supported */
|
||||
#define IWL_A000_UCODE_API_MAX 26
|
||||
#define IWL_A000_UCODE_API_MAX 28
|
||||
|
||||
/* Lowest firmware API version supported */
|
||||
#define IWL_A000_UCODE_API_MIN 24
|
||||
|
@ -166,8 +166,9 @@ static void iwl_free_fw_desc(struct iwl_drv *drv, struct fw_desc *desc)
|
||||
static void iwl_free_fw_img(struct iwl_drv *drv, struct fw_img *img)
|
||||
{
|
||||
int i;
|
||||
for (i = 0; i < IWL_UCODE_SECTION_MAX; i++)
|
||||
for (i = 0; i < img->num_sec; i++)
|
||||
iwl_free_fw_desc(drv, &img->sec[i]);
|
||||
kfree(img->sec);
|
||||
}
|
||||
|
||||
static void iwl_dealloc_ucode(struct iwl_drv *drv)
|
||||
@ -179,8 +180,7 @@ static void iwl_dealloc_ucode(struct iwl_drv *drv)
|
||||
kfree(drv->fw.dbg_conf_tlv[i]);
|
||||
for (i = 0; i < ARRAY_SIZE(drv->fw.dbg_trigger_tlv); i++)
|
||||
kfree(drv->fw.dbg_trigger_tlv[i]);
|
||||
for (i = 0; i < ARRAY_SIZE(drv->fw.dbg_mem_tlv); i++)
|
||||
kfree(drv->fw.dbg_mem_tlv[i]);
|
||||
kfree(drv->fw.dbg_mem_tlv);
|
||||
|
||||
for (i = 0; i < IWL_UCODE_TYPE_MAX; i++)
|
||||
iwl_free_fw_img(drv, drv->fw.img + i);
|
||||
@ -241,7 +241,7 @@ static int iwl_request_firmware(struct iwl_drv *drv, bool first)
|
||||
}
|
||||
|
||||
struct fw_img_parsing {
|
||||
struct fw_sec sec[IWL_UCODE_SECTION_MAX];
|
||||
struct fw_sec *sec;
|
||||
int sec_counter;
|
||||
};
|
||||
|
||||
@ -276,7 +276,8 @@ struct iwl_firmware_pieces {
|
||||
size_t dbg_conf_tlv_len[FW_DBG_CONF_MAX];
|
||||
struct iwl_fw_dbg_trigger_tlv *dbg_trigger_tlv[FW_DBG_TRIGGER_MAX];
|
||||
size_t dbg_trigger_tlv_len[FW_DBG_TRIGGER_MAX];
|
||||
struct iwl_fw_dbg_mem_seg_tlv *dbg_mem_tlv[FW_DBG_MEM_MAX];
|
||||
struct iwl_fw_dbg_mem_seg_tlv *dbg_mem_tlv;
|
||||
size_t n_dbg_mem_tlv;
|
||||
};
|
||||
|
||||
/*
|
||||
@ -290,11 +291,33 @@ static struct fw_sec *get_sec(struct iwl_firmware_pieces *pieces,
|
||||
return &pieces->img[type].sec[sec];
|
||||
}
|
||||
|
||||
static void alloc_sec_data(struct iwl_firmware_pieces *pieces,
|
||||
enum iwl_ucode_type type,
|
||||
int sec)
|
||||
{
|
||||
struct fw_img_parsing *img = &pieces->img[type];
|
||||
struct fw_sec *sec_memory;
|
||||
int size = sec + 1;
|
||||
size_t alloc_size = sizeof(*img->sec) * size;
|
||||
|
||||
if (img->sec && img->sec_counter >= size)
|
||||
return;
|
||||
|
||||
sec_memory = krealloc(img->sec, alloc_size, GFP_KERNEL);
|
||||
if (!sec_memory)
|
||||
return;
|
||||
|
||||
img->sec = sec_memory;
|
||||
img->sec_counter = size;
|
||||
}
|
||||
|
||||
static void set_sec_data(struct iwl_firmware_pieces *pieces,
|
||||
enum iwl_ucode_type type,
|
||||
int sec,
|
||||
const void *data)
|
||||
{
|
||||
alloc_sec_data(pieces, type, sec);
|
||||
|
||||
pieces->img[type].sec[sec].data = data;
|
||||
}
|
||||
|
||||
@ -303,6 +326,8 @@ static void set_sec_size(struct iwl_firmware_pieces *pieces,
|
||||
int sec,
|
||||
size_t size)
|
||||
{
|
||||
alloc_sec_data(pieces, type, sec);
|
||||
|
||||
pieces->img[type].sec[sec].size = size;
|
||||
}
|
||||
|
||||
@ -318,6 +343,8 @@ static void set_sec_offset(struct iwl_firmware_pieces *pieces,
|
||||
int sec,
|
||||
u32 offset)
|
||||
{
|
||||
alloc_sec_data(pieces, type, sec);
|
||||
|
||||
pieces->img[type].sec[sec].offset = offset;
|
||||
}
|
||||
|
||||
@ -383,6 +410,7 @@ static int iwl_store_ucode_sec(struct iwl_firmware_pieces *pieces,
|
||||
struct fw_img_parsing *img;
|
||||
struct fw_sec *sec;
|
||||
struct fw_sec_parsing *sec_parse;
|
||||
size_t alloc_size;
|
||||
|
||||
if (WARN_ON(!pieces || !data || type >= IWL_UCODE_TYPE_MAX))
|
||||
return -1;
|
||||
@ -390,6 +418,13 @@ static int iwl_store_ucode_sec(struct iwl_firmware_pieces *pieces,
|
||||
sec_parse = (struct fw_sec_parsing *)data;
|
||||
|
||||
img = &pieces->img[type];
|
||||
|
||||
alloc_size = sizeof(*img->sec) * (img->sec_counter + 1);
|
||||
sec = krealloc(img->sec, alloc_size, GFP_KERNEL);
|
||||
if (!sec)
|
||||
return -ENOMEM;
|
||||
img->sec = sec;
|
||||
|
||||
sec = &img->sec[img->sec_counter];
|
||||
|
||||
sec->offset = le32_to_cpu(sec_parse->offset);
|
||||
@ -1009,31 +1044,37 @@ static int iwl_parse_tlv_firmware(struct iwl_drv *drv,
|
||||
struct iwl_fw_dbg_mem_seg_tlv *dbg_mem =
|
||||
(void *)tlv_data;
|
||||
u32 type;
|
||||
size_t size;
|
||||
struct iwl_fw_dbg_mem_seg_tlv *n;
|
||||
|
||||
if (tlv_len != (sizeof(*dbg_mem)))
|
||||
goto invalid_tlv_len;
|
||||
|
||||
type = le32_to_cpu(dbg_mem->data_type);
|
||||
drv->fw.dbg_dynamic_mem = true;
|
||||
|
||||
if (type >= ARRAY_SIZE(drv->fw.dbg_mem_tlv)) {
|
||||
IWL_ERR(drv,
|
||||
"Skip unknown dbg mem segment: %u\n",
|
||||
dbg_mem->data_type);
|
||||
break;
|
||||
}
|
||||
|
||||
if (pieces->dbg_mem_tlv[type]) {
|
||||
IWL_ERR(drv,
|
||||
"Ignore duplicate mem segment: %u\n",
|
||||
dbg_mem->data_type);
|
||||
break;
|
||||
}
|
||||
|
||||
IWL_DEBUG_INFO(drv, "Found debug memory segment: %u\n",
|
||||
dbg_mem->data_type);
|
||||
|
||||
pieces->dbg_mem_tlv[type] = dbg_mem;
|
||||
switch (type & FW_DBG_MEM_TYPE_MASK) {
|
||||
case FW_DBG_MEM_TYPE_REGULAR:
|
||||
case FW_DBG_MEM_TYPE_PRPH:
|
||||
/* we know how to handle these */
|
||||
break;
|
||||
default:
|
||||
IWL_ERR(drv,
|
||||
"Found debug memory segment with invalid type: 0x%x\n",
|
||||
type);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
size = sizeof(*pieces->dbg_mem_tlv) *
|
||||
(pieces->n_dbg_mem_tlv + 1);
|
||||
n = krealloc(pieces->dbg_mem_tlv, size, GFP_KERNEL);
|
||||
if (!n)
|
||||
return -ENOMEM;
|
||||
pieces->dbg_mem_tlv = n;
|
||||
pieces->dbg_mem_tlv[pieces->n_dbg_mem_tlv] = *dbg_mem;
|
||||
pieces->n_dbg_mem_tlv++;
|
||||
break;
|
||||
}
|
||||
default:
|
||||
@ -1083,12 +1124,18 @@ static int iwl_alloc_ucode(struct iwl_drv *drv,
|
||||
enum iwl_ucode_type type)
|
||||
{
|
||||
int i;
|
||||
for (i = 0;
|
||||
i < IWL_UCODE_SECTION_MAX && get_sec_size(pieces, type, i);
|
||||
i++)
|
||||
if (iwl_alloc_fw_desc(drv, &(drv->fw.img[type].sec[i]),
|
||||
get_sec(pieces, type, i)))
|
||||
struct fw_desc *sec;
|
||||
|
||||
sec = kcalloc(pieces->img[type].sec_counter, sizeof(*sec), GFP_KERNEL);
|
||||
if (!sec)
|
||||
return -ENOMEM;
|
||||
drv->fw.img[type].sec = sec;
|
||||
drv->fw.img[type].num_sec = pieces->img[type].sec_counter;
|
||||
|
||||
for (i = 0; i < pieces->img[type].sec_counter; i++)
|
||||
if (iwl_alloc_fw_desc(drv, &sec[i], get_sec(pieces, type, i)))
|
||||
return -ENOMEM;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -1345,19 +1392,12 @@ static void iwl_req_fw_callback(const struct firmware *ucode_raw, void *context)
|
||||
}
|
||||
}
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(drv->fw.dbg_mem_tlv); i++) {
|
||||
if (pieces->dbg_mem_tlv[i]) {
|
||||
drv->fw.dbg_mem_tlv[i] =
|
||||
kmemdup(pieces->dbg_mem_tlv[i],
|
||||
sizeof(*drv->fw.dbg_mem_tlv[i]),
|
||||
GFP_KERNEL);
|
||||
if (!drv->fw.dbg_mem_tlv[i])
|
||||
goto out_free_fw;
|
||||
}
|
||||
}
|
||||
|
||||
/* Now that we can no longer fail, copy information */
|
||||
|
||||
drv->fw.dbg_mem_tlv = pieces->dbg_mem_tlv;
|
||||
pieces->dbg_mem_tlv = NULL;
|
||||
drv->fw.n_dbg_mem_tlv = pieces->n_dbg_mem_tlv;
|
||||
|
||||
/*
|
||||
* The (size - 16) / 12 formula is based on the information recorded
|
||||
* for each event, which is of mode 1 (including timestamp) for all
|
||||
@ -1441,25 +1481,27 @@ static void iwl_req_fw_callback(const struct firmware *ucode_raw, void *context)
|
||||
op->name, err);
|
||||
#endif
|
||||
}
|
||||
kfree(pieces);
|
||||
return;
|
||||
goto free;
|
||||
|
||||
try_again:
|
||||
/* try next, if any */
|
||||
release_firmware(ucode_raw);
|
||||
if (iwl_request_firmware(drv, false))
|
||||
goto out_unbind;
|
||||
kfree(pieces);
|
||||
return;
|
||||
goto free;
|
||||
|
||||
out_free_fw:
|
||||
IWL_ERR(drv, "failed to allocate pci memory\n");
|
||||
iwl_dealloc_ucode(drv);
|
||||
release_firmware(ucode_raw);
|
||||
out_unbind:
|
||||
kfree(pieces);
|
||||
complete(&drv->request_firmware_complete);
|
||||
device_release_driver(drv->trans->dev);
|
||||
free:
|
||||
for (i = 0; i < ARRAY_SIZE(pieces->img); i++)
|
||||
kfree(pieces->img[i].sec);
|
||||
kfree(pieces->dbg_mem_tlv);
|
||||
kfree(pieces);
|
||||
}
|
||||
|
||||
struct iwl_drv *iwl_drv_start(struct iwl_trans *trans,
|
||||
|
@ -379,7 +379,6 @@ enum iwl_ucode_tlv_capa {
|
||||
* For 16.0 uCode and above, there is no differentiation between sections,
|
||||
* just an offset to the HW address.
|
||||
*/
|
||||
#define IWL_UCODE_SECTION_MAX 16
|
||||
#define CPU1_CPU2_SEPARATOR_SECTION 0xFFFFCCCC
|
||||
#define PAGING_SEPARATOR_SECTION 0xAAAABBBB
|
||||
|
||||
@ -489,25 +488,22 @@ enum iwl_fw_dbg_monitor_mode {
|
||||
};
|
||||
|
||||
/**
|
||||
* enum iwl_fw_mem_seg_type - data types for dumping on error
|
||||
*
|
||||
* @FW_DBG_MEM_SMEM: the data type is SMEM
|
||||
* @FW_DBG_MEM_DCCM_LMAC: the data type is DCCM_LMAC
|
||||
* @FW_DBG_MEM_DCCM_UMAC: the data type is DCCM_UMAC
|
||||
* enum iwl_fw_mem_seg_type - memory segment type
|
||||
* @FW_DBG_MEM_TYPE_MASK: mask for the type indication
|
||||
* @FW_DBG_MEM_TYPE_REGULAR: regular memory
|
||||
* @FW_DBG_MEM_TYPE_PRPH: periphery memory (requires special reading)
|
||||
*/
|
||||
enum iwl_fw_dbg_mem_seg_type {
|
||||
FW_DBG_MEM_DCCM_LMAC = 0,
|
||||
FW_DBG_MEM_DCCM_UMAC,
|
||||
FW_DBG_MEM_SMEM,
|
||||
|
||||
/* Must be last */
|
||||
FW_DBG_MEM_MAX,
|
||||
enum iwl_fw_mem_seg_type {
|
||||
FW_DBG_MEM_TYPE_MASK = 0xff000000,
|
||||
FW_DBG_MEM_TYPE_REGULAR = 0x00000000,
|
||||
FW_DBG_MEM_TYPE_PRPH = 0x01000000,
|
||||
};
|
||||
|
||||
/**
|
||||
* struct iwl_fw_dbg_mem_seg_tlv - configures the debug data memory segments
|
||||
*
|
||||
* @data_type: enum %iwl_fw_mem_seg_type
|
||||
* @data_type: the memory segment type to record, see &enum iwl_fw_mem_seg_type
|
||||
* for what we care about
|
||||
* @ofs: the memory segment offset
|
||||
* @len: the memory segment length, in bytes
|
||||
*
|
||||
|
@ -132,7 +132,8 @@ struct fw_desc {
|
||||
};
|
||||
|
||||
struct fw_img {
|
||||
struct fw_desc sec[IWL_UCODE_SECTION_MAX];
|
||||
struct fw_desc *sec;
|
||||
int num_sec;
|
||||
bool is_dual_cpus;
|
||||
u32 paging_mem_size;
|
||||
};
|
||||
@ -295,8 +296,8 @@ struct iwl_fw {
|
||||
struct iwl_fw_dbg_conf_tlv *dbg_conf_tlv[FW_DBG_CONF_MAX];
|
||||
size_t dbg_conf_tlv_len[FW_DBG_CONF_MAX];
|
||||
struct iwl_fw_dbg_trigger_tlv *dbg_trigger_tlv[FW_DBG_TRIGGER_MAX];
|
||||
struct iwl_fw_dbg_mem_seg_tlv *dbg_mem_tlv[FW_DBG_MEM_MAX];
|
||||
bool dbg_dynamic_mem;
|
||||
struct iwl_fw_dbg_mem_seg_tlv *dbg_mem_tlv;
|
||||
size_t n_dbg_mem_tlv;
|
||||
size_t dbg_trigger_tlv_len[FW_DBG_TRIGGER_MAX];
|
||||
u8 dbg_dest_reg_num;
|
||||
struct iwl_gscan_capabilities gscan_capa;
|
||||
|
@ -1262,12 +1262,15 @@ static int __iwl_mvm_suspend(struct ieee80211_hw *hw,
|
||||
iwl_trans_d3_suspend(mvm->trans, test, !unified_image);
|
||||
out:
|
||||
if (ret < 0) {
|
||||
iwl_mvm_ref(mvm, IWL_MVM_REF_UCODE_DOWN);
|
||||
if (mvm->restart_fw > 0) {
|
||||
mvm->restart_fw--;
|
||||
ieee80211_restart_hw(mvm->hw);
|
||||
}
|
||||
iwl_mvm_free_nd(mvm);
|
||||
|
||||
if (!unified_image) {
|
||||
iwl_mvm_ref(mvm, IWL_MVM_REF_UCODE_DOWN);
|
||||
if (mvm->restart_fw > 0) {
|
||||
mvm->restart_fw--;
|
||||
ieee80211_restart_hw(mvm->hw);
|
||||
}
|
||||
}
|
||||
}
|
||||
out_noreset:
|
||||
mutex_unlock(&mvm->mutex);
|
||||
|
@ -798,7 +798,7 @@ static ssize_t iwl_dbgfs_drv_rx_stats_read(struct file *file,
|
||||
static ssize_t iwl_dbgfs_fw_restart_write(struct iwl_mvm *mvm, char *buf,
|
||||
size_t count, loff_t *ppos)
|
||||
{
|
||||
int ret;
|
||||
int __maybe_unused ret;
|
||||
|
||||
mutex_lock(&mvm->mutex);
|
||||
|
||||
|
@ -2075,7 +2075,7 @@ struct iwl_mu_group_mgmt_notif {
|
||||
* @system_time: system time on air rise
|
||||
* @tsf: TSF on air rise
|
||||
* @beacon_timestamp: beacon on air rise
|
||||
* @phy_flags: general phy flags: band, modulation, etc.
|
||||
* @band: band, matches &RX_RES_PHY_FLAGS_BAND_24 definition
|
||||
* @channel: channel this beacon was received on
|
||||
* @rates: rate in ucode internal format
|
||||
* @byte_count: frame's byte count
|
||||
@ -2084,12 +2084,12 @@ struct iwl_stored_beacon_notif {
|
||||
__le32 system_time;
|
||||
__le64 tsf;
|
||||
__le32 beacon_timestamp;
|
||||
__le16 phy_flags;
|
||||
__le16 band;
|
||||
__le16 channel;
|
||||
__le32 rates;
|
||||
__le32 byte_count;
|
||||
u8 data[MAX_STORED_BEACON_SIZE];
|
||||
} __packed; /* WOWLAN_STROED_BEACON_INFO_S_VER_1 */
|
||||
} __packed; /* WOWLAN_STROED_BEACON_INFO_S_VER_2 */
|
||||
|
||||
#define LQM_NUMBER_OF_STATIONS_IN_REPORT 16
|
||||
|
||||
|
@ -406,46 +406,63 @@ static const struct iwl_prph_range iwl_prph_dump_addr_9000[] = {
|
||||
{ .start = 0x00a02400, .end = 0x00a02758 },
|
||||
};
|
||||
|
||||
static u32 iwl_dump_prph(struct iwl_trans *trans,
|
||||
struct iwl_fw_error_dump_data **data,
|
||||
const struct iwl_prph_range *iwl_prph_dump_addr,
|
||||
u32 range_len)
|
||||
static void _iwl_read_prph_block(struct iwl_trans *trans, u32 start,
|
||||
u32 len_bytes, __le32 *data)
|
||||
{
|
||||
u32 i;
|
||||
|
||||
for (i = 0; i < len_bytes; i += 4)
|
||||
*data++ = cpu_to_le32(iwl_read_prph_no_grab(trans, start + i));
|
||||
}
|
||||
|
||||
static bool iwl_read_prph_block(struct iwl_trans *trans, u32 start,
|
||||
u32 len_bytes, __le32 *data)
|
||||
{
|
||||
unsigned long flags;
|
||||
bool success = false;
|
||||
|
||||
if (iwl_trans_grab_nic_access(trans, &flags)) {
|
||||
success = true;
|
||||
_iwl_read_prph_block(trans, start, len_bytes, data);
|
||||
iwl_trans_release_nic_access(trans, &flags);
|
||||
}
|
||||
|
||||
return success;
|
||||
}
|
||||
|
||||
static void iwl_dump_prph(struct iwl_trans *trans,
|
||||
struct iwl_fw_error_dump_data **data,
|
||||
const struct iwl_prph_range *iwl_prph_dump_addr,
|
||||
u32 range_len)
|
||||
{
|
||||
struct iwl_fw_error_dump_prph *prph;
|
||||
unsigned long flags;
|
||||
u32 prph_len = 0, i;
|
||||
u32 i;
|
||||
|
||||
if (!iwl_trans_grab_nic_access(trans, &flags))
|
||||
return 0;
|
||||
return;
|
||||
|
||||
for (i = 0; i < range_len; i++) {
|
||||
/* The range includes both boundaries */
|
||||
int num_bytes_in_chunk = iwl_prph_dump_addr[i].end -
|
||||
iwl_prph_dump_addr[i].start + 4;
|
||||
int reg;
|
||||
__le32 *val;
|
||||
|
||||
prph_len += sizeof(**data) + sizeof(*prph) + num_bytes_in_chunk;
|
||||
|
||||
(*data)->type = cpu_to_le32(IWL_FW_ERROR_DUMP_PRPH);
|
||||
(*data)->len = cpu_to_le32(sizeof(*prph) +
|
||||
num_bytes_in_chunk);
|
||||
prph = (void *)(*data)->data;
|
||||
prph->prph_start = cpu_to_le32(iwl_prph_dump_addr[i].start);
|
||||
val = (void *)prph->data;
|
||||
|
||||
for (reg = iwl_prph_dump_addr[i].start;
|
||||
reg <= iwl_prph_dump_addr[i].end;
|
||||
reg += 4)
|
||||
*val++ = cpu_to_le32(iwl_read_prph_no_grab(trans,
|
||||
reg));
|
||||
_iwl_read_prph_block(trans, iwl_prph_dump_addr[i].start,
|
||||
/* our range is inclusive, hence + 4 */
|
||||
iwl_prph_dump_addr[i].end -
|
||||
iwl_prph_dump_addr[i].start + 4,
|
||||
(void *)prph->data);
|
||||
|
||||
*data = iwl_fw_error_next_data(*data);
|
||||
}
|
||||
|
||||
iwl_trans_release_nic_access(trans, &flags);
|
||||
|
||||
return prph_len;
|
||||
}
|
||||
|
||||
/*
|
||||
@ -495,11 +512,10 @@ void iwl_mvm_fw_error_dump(struct iwl_mvm *mvm)
|
||||
struct iwl_mvm_dump_ptrs *fw_error_dump;
|
||||
struct scatterlist *sg_dump_data;
|
||||
u32 sram_len, sram_ofs;
|
||||
struct iwl_fw_dbg_mem_seg_tlv * const *fw_dbg_mem =
|
||||
mvm->fw->dbg_mem_tlv;
|
||||
const struct iwl_fw_dbg_mem_seg_tlv *fw_dbg_mem = mvm->fw->dbg_mem_tlv;
|
||||
u32 file_len, fifo_data_len = 0, prph_len = 0, radio_len = 0;
|
||||
u32 smem_len = mvm->fw->dbg_dynamic_mem ? 0 : mvm->cfg->smem_len;
|
||||
u32 sram2_len = mvm->fw->dbg_dynamic_mem ? 0 : mvm->cfg->dccm2_len;
|
||||
u32 smem_len = mvm->fw->n_dbg_mem_tlv ? 0 : mvm->cfg->smem_len;
|
||||
u32 sram2_len = mvm->fw->n_dbg_mem_tlv ? 0 : mvm->cfg->dccm2_len;
|
||||
bool monitor_dump_only = false;
|
||||
int i;
|
||||
|
||||
@ -624,10 +640,9 @@ void iwl_mvm_fw_error_dump(struct iwl_mvm *mvm)
|
||||
file_len += sizeof(*dump_data) + sizeof(*dump_mem) + sram2_len;
|
||||
|
||||
/* Make room for MEM segments */
|
||||
for (i = 0; i < ARRAY_SIZE(mvm->fw->dbg_mem_tlv); i++) {
|
||||
if (fw_dbg_mem[i])
|
||||
file_len += sizeof(*dump_data) + sizeof(*dump_mem) +
|
||||
le32_to_cpu(fw_dbg_mem[i]->len);
|
||||
for (i = 0; i < mvm->fw->n_dbg_mem_tlv; i++) {
|
||||
file_len += sizeof(*dump_data) + sizeof(*dump_mem) +
|
||||
le32_to_cpu(fw_dbg_mem[i].len);
|
||||
}
|
||||
|
||||
/* Make room for fw's virtual image pages, if it exists */
|
||||
@ -656,7 +671,7 @@ void iwl_mvm_fw_error_dump(struct iwl_mvm *mvm)
|
||||
file_len += sizeof(*dump_data) + sizeof(*dump_trig) +
|
||||
mvm->fw_dump_desc->len;
|
||||
|
||||
if (!mvm->fw->dbg_dynamic_mem)
|
||||
if (!mvm->fw->n_dbg_mem_tlv)
|
||||
file_len += sram_len + sizeof(*dump_mem);
|
||||
|
||||
dump_file = vzalloc(file_len);
|
||||
@ -708,7 +723,7 @@ void iwl_mvm_fw_error_dump(struct iwl_mvm *mvm)
|
||||
if (monitor_dump_only)
|
||||
goto dump_trans_data;
|
||||
|
||||
if (!mvm->fw->dbg_dynamic_mem) {
|
||||
if (!mvm->fw->n_dbg_mem_tlv) {
|
||||
dump_data->type = cpu_to_le32(IWL_FW_ERROR_DUMP_MEM);
|
||||
dump_data->len = cpu_to_le32(sram_len + sizeof(*dump_mem));
|
||||
dump_mem = (void *)dump_data->data;
|
||||
@ -719,22 +734,39 @@ void iwl_mvm_fw_error_dump(struct iwl_mvm *mvm)
|
||||
dump_data = iwl_fw_error_next_data(dump_data);
|
||||
}
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(mvm->fw->dbg_mem_tlv); i++) {
|
||||
if (fw_dbg_mem[i]) {
|
||||
u32 len = le32_to_cpu(fw_dbg_mem[i]->len);
|
||||
u32 ofs = le32_to_cpu(fw_dbg_mem[i]->ofs);
|
||||
for (i = 0; i < mvm->fw->n_dbg_mem_tlv; i++) {
|
||||
u32 len = le32_to_cpu(fw_dbg_mem[i].len);
|
||||
u32 ofs = le32_to_cpu(fw_dbg_mem[i].ofs);
|
||||
bool success;
|
||||
|
||||
dump_data->type = cpu_to_le32(IWL_FW_ERROR_DUMP_MEM);
|
||||
dump_data->len = cpu_to_le32(len +
|
||||
sizeof(*dump_mem));
|
||||
dump_mem = (void *)dump_data->data;
|
||||
dump_mem->type = fw_dbg_mem[i]->data_type;
|
||||
dump_mem->offset = cpu_to_le32(ofs);
|
||||
dump_data->type = cpu_to_le32(IWL_FW_ERROR_DUMP_MEM);
|
||||
dump_data->len = cpu_to_le32(len + sizeof(*dump_mem));
|
||||
dump_mem = (void *)dump_data->data;
|
||||
dump_mem->type = fw_dbg_mem[i].data_type;
|
||||
dump_mem->offset = cpu_to_le32(ofs);
|
||||
|
||||
switch (dump_mem->type & cpu_to_le32(FW_DBG_MEM_TYPE_MASK)) {
|
||||
case cpu_to_le32(FW_DBG_MEM_TYPE_REGULAR):
|
||||
iwl_trans_read_mem_bytes(mvm->trans, ofs,
|
||||
dump_mem->data,
|
||||
len);
|
||||
dump_data = iwl_fw_error_next_data(dump_data);
|
||||
success = true;
|
||||
break;
|
||||
case cpu_to_le32(FW_DBG_MEM_TYPE_PRPH):
|
||||
success = iwl_read_prph_block(mvm->trans, ofs, len,
|
||||
(void *)dump_mem->data);
|
||||
break;
|
||||
default:
|
||||
/*
|
||||
* shouldn't get here, we ignored this kind
|
||||
* of TLV earlier during the TLV parsing?!
|
||||
*/
|
||||
WARN_ON(1);
|
||||
success = false;
|
||||
}
|
||||
|
||||
if (success)
|
||||
dump_data = iwl_fw_error_next_data(dump_data);
|
||||
}
|
||||
|
||||
if (smem_len) {
|
||||
@ -816,11 +848,12 @@ dump_trans_data:
|
||||
sg_nents(sg_dump_data),
|
||||
fw_error_dump->op_mode_ptr,
|
||||
fw_error_dump->op_mode_len, 0);
|
||||
sg_pcopy_from_buffer(sg_dump_data,
|
||||
sg_nents(sg_dump_data),
|
||||
fw_error_dump->trans_ptr->data,
|
||||
fw_error_dump->trans_ptr->len,
|
||||
fw_error_dump->op_mode_len);
|
||||
if (fw_error_dump->trans_ptr)
|
||||
sg_pcopy_from_buffer(sg_dump_data,
|
||||
sg_nents(sg_dump_data),
|
||||
fw_error_dump->trans_ptr->data,
|
||||
fw_error_dump->trans_ptr->len,
|
||||
fw_error_dump->op_mode_len);
|
||||
dev_coredumpsg(mvm->trans->dev, sg_dump_data, file_len,
|
||||
GFP_KERNEL);
|
||||
}
|
||||
|
@ -190,7 +190,7 @@ static int iwl_fill_paging_mem(struct iwl_mvm *mvm, const struct fw_img *image)
|
||||
* CPU2 paging CSS
|
||||
* CPU2 paging image (including instruction and data)
|
||||
*/
|
||||
for (sec_idx = 0; sec_idx < IWL_UCODE_SECTION_MAX; sec_idx++) {
|
||||
for (sec_idx = 0; sec_idx < image->num_sec; sec_idx++) {
|
||||
if (image->sec[sec_idx].offset == PAGING_SEPARATOR_SECTION) {
|
||||
sec_idx++;
|
||||
break;
|
||||
@ -201,7 +201,7 @@ static int iwl_fill_paging_mem(struct iwl_mvm *mvm, const struct fw_img *image)
|
||||
* If paging is enabled there should be at least 2 more sections left
|
||||
* (one for CSS and one for Paging data)
|
||||
*/
|
||||
if (sec_idx >= ARRAY_SIZE(image->sec) - 1) {
|
||||
if (sec_idx >= image->num_sec - 1) {
|
||||
IWL_ERR(mvm, "Paging: Missing CSS and/or paging sections\n");
|
||||
iwl_free_fw_paging(mvm);
|
||||
return -EINVAL;
|
||||
@ -259,9 +259,7 @@ static int iwl_alloc_fw_paging_mem(struct iwl_mvm *mvm,
|
||||
{
|
||||
struct page *block;
|
||||
dma_addr_t phys = 0;
|
||||
int blk_idx = 0;
|
||||
int order, num_of_pages;
|
||||
int dma_enabled;
|
||||
int blk_idx, order, num_of_pages, size, dma_enabled;
|
||||
|
||||
if (mvm->fw_paging_db[0].fw_paging_block)
|
||||
return 0;
|
||||
@ -272,9 +270,8 @@ static int iwl_alloc_fw_paging_mem(struct iwl_mvm *mvm,
|
||||
BUILD_BUG_ON(BIT(BLOCK_2_EXP_SIZE) != PAGING_BLOCK_SIZE);
|
||||
|
||||
num_of_pages = image->paging_mem_size / FW_PAGING_SIZE;
|
||||
mvm->num_of_paging_blk = ((num_of_pages - 1) /
|
||||
NUM_OF_PAGE_PER_GROUP) + 1;
|
||||
|
||||
mvm->num_of_paging_blk =
|
||||
DIV_ROUND_UP(num_of_pages, NUM_OF_PAGE_PER_GROUP);
|
||||
mvm->num_of_pages_in_last_blk =
|
||||
num_of_pages -
|
||||
NUM_OF_PAGE_PER_GROUP * (mvm->num_of_paging_blk - 1);
|
||||
@ -284,46 +281,13 @@ static int iwl_alloc_fw_paging_mem(struct iwl_mvm *mvm,
|
||||
mvm->num_of_paging_blk,
|
||||
mvm->num_of_pages_in_last_blk);
|
||||
|
||||
/* allocate block of 4Kbytes for paging CSS */
|
||||
order = get_order(FW_PAGING_SIZE);
|
||||
block = alloc_pages(GFP_KERNEL, order);
|
||||
if (!block) {
|
||||
/* free all the previous pages since we failed */
|
||||
iwl_free_fw_paging(mvm);
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
mvm->fw_paging_db[blk_idx].fw_paging_block = block;
|
||||
mvm->fw_paging_db[blk_idx].fw_paging_size = FW_PAGING_SIZE;
|
||||
|
||||
if (dma_enabled) {
|
||||
phys = dma_map_page(mvm->trans->dev, block, 0,
|
||||
PAGE_SIZE << order, DMA_BIDIRECTIONAL);
|
||||
if (dma_mapping_error(mvm->trans->dev, phys)) {
|
||||
/*
|
||||
* free the previous pages and the current one since
|
||||
* we failed to map_page.
|
||||
*/
|
||||
iwl_free_fw_paging(mvm);
|
||||
return -ENOMEM;
|
||||
}
|
||||
mvm->fw_paging_db[blk_idx].fw_paging_phys = phys;
|
||||
} else {
|
||||
mvm->fw_paging_db[blk_idx].fw_paging_phys = PAGING_ADDR_SIG |
|
||||
blk_idx << BLOCK_2_EXP_SIZE;
|
||||
}
|
||||
|
||||
IWL_DEBUG_FW(mvm,
|
||||
"Paging: allocated 4K(CSS) bytes (order %d) for firmware paging.\n",
|
||||
order);
|
||||
|
||||
/*
|
||||
* allocate blocks in dram.
|
||||
* since that CSS allocated in fw_paging_db[0] loop start from index 1
|
||||
* Allocate CSS and paging blocks in dram.
|
||||
*/
|
||||
for (blk_idx = 1; blk_idx < mvm->num_of_paging_blk + 1; blk_idx++) {
|
||||
/* allocate block of PAGING_BLOCK_SIZE (32K) */
|
||||
order = get_order(PAGING_BLOCK_SIZE);
|
||||
for (blk_idx = 0; blk_idx < mvm->num_of_paging_blk + 1; blk_idx++) {
|
||||
/* For CSS allocate 4KB, for others PAGING_BLOCK_SIZE (32K) */
|
||||
size = blk_idx ? PAGING_BLOCK_SIZE : FW_PAGING_SIZE;
|
||||
order = get_order(size);
|
||||
block = alloc_pages(GFP_KERNEL, order);
|
||||
if (!block) {
|
||||
/* free all the previous pages since we failed */
|
||||
@ -332,7 +296,7 @@ static int iwl_alloc_fw_paging_mem(struct iwl_mvm *mvm,
|
||||
}
|
||||
|
||||
mvm->fw_paging_db[blk_idx].fw_paging_block = block;
|
||||
mvm->fw_paging_db[blk_idx].fw_paging_size = PAGING_BLOCK_SIZE;
|
||||
mvm->fw_paging_db[blk_idx].fw_paging_size = size;
|
||||
|
||||
if (dma_enabled) {
|
||||
phys = dma_map_page(mvm->trans->dev, block, 0,
|
||||
@ -353,9 +317,14 @@ static int iwl_alloc_fw_paging_mem(struct iwl_mvm *mvm,
|
||||
blk_idx << BLOCK_2_EXP_SIZE;
|
||||
}
|
||||
|
||||
IWL_DEBUG_FW(mvm,
|
||||
"Paging: allocated 32K bytes (order %d) for firmware paging.\n",
|
||||
order);
|
||||
if (!blk_idx)
|
||||
IWL_DEBUG_FW(mvm,
|
||||
"Paging: allocated 4K(CSS) bytes (order %d) for firmware paging.\n",
|
||||
order);
|
||||
else
|
||||
IWL_DEBUG_FW(mvm,
|
||||
"Paging: allocated 32K bytes (order %d) for firmware paging.\n",
|
||||
order);
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
@ -1565,7 +1565,7 @@ void iwl_mvm_rx_stored_beacon_notif(struct iwl_mvm *mvm,
|
||||
rx_status.flag |= RX_FLAG_MACTIME_PLCP_START;
|
||||
rx_status.device_timestamp = le32_to_cpu(sb->system_time);
|
||||
rx_status.band =
|
||||
(sb->phy_flags & cpu_to_le16(RX_RES_PHY_FLAGS_BAND_24)) ?
|
||||
(sb->band & cpu_to_le16(RX_RES_PHY_FLAGS_BAND_24)) ?
|
||||
NL80211_BAND_2GHZ : NL80211_BAND_5GHZ;
|
||||
rx_status.freq =
|
||||
ieee80211_channel_to_frequency(le16_to_cpu(sb->channel),
|
||||
|
@ -463,6 +463,13 @@ int iwl_mvm_mac_setup_register(struct iwl_mvm *mvm)
|
||||
IEEE80211_RADIOTAP_MCS_HAVE_STBC;
|
||||
hw->radiotap_vht_details |= IEEE80211_RADIOTAP_VHT_KNOWN_STBC |
|
||||
IEEE80211_RADIOTAP_VHT_KNOWN_BEAMFORMED;
|
||||
|
||||
hw->radiotap_timestamp.units_pos =
|
||||
IEEE80211_RADIOTAP_TIMESTAMP_UNIT_US |
|
||||
IEEE80211_RADIOTAP_TIMESTAMP_SPOS_PLCP_SIG_ACQ;
|
||||
/* this is the case for CCK frames, it's better (only 8) for OFDM */
|
||||
hw->radiotap_timestamp.accuracy = 22;
|
||||
|
||||
hw->rate_control_algorithm = "iwl-mvm-rs";
|
||||
hw->uapsd_queues = IWL_MVM_UAPSD_QUEUES;
|
||||
hw->uapsd_max_sp_len = IWL_UAPSD_MAX_SP;
|
||||
@ -670,7 +677,7 @@ int iwl_mvm_mac_setup_register(struct iwl_mvm *mvm)
|
||||
hw->wiphy->wowlan = &mvm->wowlan;
|
||||
}
|
||||
|
||||
if (mvm->fw->img[IWL_UCODE_WOWLAN].sec[0].len &&
|
||||
if (mvm->fw->img[IWL_UCODE_WOWLAN].num_sec &&
|
||||
mvm->trans->ops->d3_suspend &&
|
||||
mvm->trans->ops->d3_resume &&
|
||||
device_can_wakeup(mvm->trans->dev)) {
|
||||
|
@ -1657,8 +1657,8 @@ void iwl_mvm_enable_txq(struct iwl_mvm *mvm, int queue, int mac80211_queue,
|
||||
* Disable a TXQ.
|
||||
* Note that in non-DQA mode the %mac80211_queue and %tid params are ignored.
|
||||
*/
|
||||
void iwl_mvm_disable_txq(struct iwl_mvm *mvm, int queue, int mac80211_queue,
|
||||
u8 tid, u8 flags);
|
||||
int iwl_mvm_disable_txq(struct iwl_mvm *mvm, int queue, int mac80211_queue,
|
||||
u8 tid, u8 flags);
|
||||
int iwl_mvm_find_free_queue(struct iwl_mvm *mvm, u8 sta_id, u8 minq, u8 maxq);
|
||||
|
||||
/* Return a bitmask with all the hw supported queues, except for the
|
||||
|
@ -161,9 +161,6 @@ static bool rs_mimo_allow(struct iwl_mvm *mvm, struct ieee80211_sta *sta,
|
||||
struct rs_rate *rate,
|
||||
const struct rs_tx_column *next_col)
|
||||
{
|
||||
struct iwl_mvm_sta *mvmsta;
|
||||
struct iwl_mvm_vif *mvmvif;
|
||||
|
||||
if (!sta->ht_cap.ht_supported)
|
||||
return false;
|
||||
|
||||
@ -176,9 +173,6 @@ static bool rs_mimo_allow(struct iwl_mvm *mvm, struct ieee80211_sta *sta,
|
||||
if (!iwl_mvm_bt_coex_is_mimo_allowed(mvm, sta))
|
||||
return false;
|
||||
|
||||
mvmsta = iwl_mvm_sta_from_mac80211(sta);
|
||||
mvmvif = iwl_mvm_vif_from_mac80211(mvmsta->vif);
|
||||
|
||||
if (mvm->nvm_data->sku_cap_mimo_disabled)
|
||||
return false;
|
||||
|
||||
@ -3071,7 +3065,7 @@ static void iwl_mvm_reset_frame_stats(struct iwl_mvm *mvm)
|
||||
|
||||
void iwl_mvm_update_frame_stats(struct iwl_mvm *mvm, u32 rate, bool agg)
|
||||
{
|
||||
u8 nss = 0, mcs = 0;
|
||||
u8 nss = 0;
|
||||
|
||||
spin_lock(&mvm->drv_stats_lock);
|
||||
|
||||
@ -3099,11 +3093,9 @@ void iwl_mvm_update_frame_stats(struct iwl_mvm *mvm, u32 rate, bool agg)
|
||||
|
||||
if (rate & RATE_MCS_HT_MSK) {
|
||||
mvm->drv_rx_stats.ht_frames++;
|
||||
mcs = rate & RATE_HT_MCS_RATE_CODE_MSK;
|
||||
nss = ((rate & RATE_HT_MCS_NSS_MSK) >> RATE_HT_MCS_NSS_POS) + 1;
|
||||
} else if (rate & RATE_MCS_VHT_MSK) {
|
||||
mvm->drv_rx_stats.vht_frames++;
|
||||
mcs = rate & RATE_VHT_MCS_RATE_CODE_MSK;
|
||||
nss = ((rate & RATE_VHT_MCS_NSS_MSK) >>
|
||||
RATE_VHT_MCS_NSS_POS) + 1;
|
||||
} else {
|
||||
|
@ -621,12 +621,10 @@ void iwl_mvm_handle_rx_statistics(struct iwl_mvm *mvm,
|
||||
};
|
||||
int expected_size = iwl_mvm_has_new_rx_api(mvm) ? sizeof(*stats) :
|
||||
sizeof(struct iwl_notif_statistics_v10);
|
||||
u32 temperature;
|
||||
|
||||
if (iwl_rx_packet_payload_len(pkt) != expected_size)
|
||||
goto invalid;
|
||||
|
||||
temperature = le32_to_cpu(stats->general.radio_temperature);
|
||||
data.mac_id = stats->rx.general.mac_id;
|
||||
data.beacon_filter_average_energy =
|
||||
stats->general.beacon_filter_average_energy;
|
||||
|
@ -454,13 +454,6 @@ static int iwl_mvm_remove_sta_queue_marking(struct iwl_mvm *mvm, int queue)
|
||||
|
||||
rcu_read_unlock();
|
||||
|
||||
spin_lock_bh(&mvm->queue_info_lock);
|
||||
/* Unmap MAC queues and TIDs from this queue */
|
||||
mvm->queue_info[queue].hw_queue_to_mac80211 = 0;
|
||||
mvm->queue_info[queue].hw_queue_refcount = 0;
|
||||
mvm->queue_info[queue].tid_bitmap = 0;
|
||||
spin_unlock_bh(&mvm->queue_info_lock);
|
||||
|
||||
return disable_agg_tids;
|
||||
}
|
||||
|
||||
@ -755,28 +748,22 @@ static int iwl_mvm_sta_alloc_queue(struct iwl_mvm *mvm,
|
||||
* first
|
||||
*/
|
||||
if (using_inactive_queue) {
|
||||
struct iwl_scd_txq_cfg_cmd cmd = {
|
||||
.scd_queue = queue,
|
||||
.action = SCD_CFG_DISABLE_QUEUE,
|
||||
};
|
||||
u8 txq_curr_ac;
|
||||
|
||||
disable_agg_tids = iwl_mvm_remove_sta_queue_marking(mvm, queue);
|
||||
u8 txq_curr_ac, sta_id;
|
||||
|
||||
spin_lock_bh(&mvm->queue_info_lock);
|
||||
txq_curr_ac = mvm->queue_info[queue].mac80211_ac;
|
||||
cmd.sta_id = mvm->queue_info[queue].ra_sta_id;
|
||||
cmd.tx_fifo = iwl_mvm_ac_to_tx_fifo[txq_curr_ac];
|
||||
cmd.tid = mvm->queue_info[queue].txq_tid;
|
||||
sta_id = mvm->queue_info[queue].ra_sta_id;
|
||||
spin_unlock_bh(&mvm->queue_info_lock);
|
||||
|
||||
disable_agg_tids = iwl_mvm_remove_sta_queue_marking(mvm, queue);
|
||||
/* Disable the queue */
|
||||
if (disable_agg_tids)
|
||||
iwl_mvm_invalidate_sta_queue(mvm, queue,
|
||||
disable_agg_tids, false);
|
||||
iwl_trans_txq_disable(mvm->trans, queue, false);
|
||||
ret = iwl_mvm_send_cmd_pdu(mvm, SCD_QUEUE_CFG, 0, sizeof(cmd),
|
||||
&cmd);
|
||||
|
||||
ret = iwl_mvm_disable_txq(mvm, queue,
|
||||
mvmsta->vif->hw_queue[txq_curr_ac],
|
||||
tid, 0);
|
||||
if (ret) {
|
||||
IWL_ERR(mvm,
|
||||
"Failed to free inactive queue %d (ret=%d)\n",
|
||||
@ -791,7 +778,7 @@ static int iwl_mvm_sta_alloc_queue(struct iwl_mvm *mvm,
|
||||
}
|
||||
|
||||
/* If TXQ is allocated to another STA, update removal in FW */
|
||||
if (cmd.sta_id != mvmsta->sta_id)
|
||||
if (sta_id != mvmsta->sta_id)
|
||||
iwl_mvm_invalidate_sta_queue(mvm, queue, 0, true);
|
||||
}
|
||||
|
||||
@ -868,7 +855,6 @@ static void iwl_mvm_change_queue_owner(struct iwl_mvm *mvm, int queue)
|
||||
.scd_queue = queue,
|
||||
.action = SCD_CFG_UPDATE_QUEUE_TID,
|
||||
};
|
||||
s8 sta_id;
|
||||
int tid;
|
||||
unsigned long tid_bitmap;
|
||||
int ret;
|
||||
@ -876,7 +862,6 @@ static void iwl_mvm_change_queue_owner(struct iwl_mvm *mvm, int queue)
|
||||
lockdep_assert_held(&mvm->mutex);
|
||||
|
||||
spin_lock_bh(&mvm->queue_info_lock);
|
||||
sta_id = mvm->queue_info[queue].ra_sta_id;
|
||||
tid_bitmap = mvm->queue_info[queue].tid_bitmap;
|
||||
spin_unlock_bh(&mvm->queue_info_lock);
|
||||
|
||||
|
@ -102,14 +102,13 @@ iwl_mvm_bar_check_trigger(struct iwl_mvm *mvm, const u8 *addr,
|
||||
#define OPT_HDR(type, skb, off) \
|
||||
(type *)(skb_network_header(skb) + (off))
|
||||
|
||||
static void iwl_mvm_tx_csum(struct iwl_mvm *mvm, struct sk_buff *skb,
|
||||
struct ieee80211_hdr *hdr,
|
||||
struct ieee80211_tx_info *info,
|
||||
struct iwl_tx_cmd *tx_cmd)
|
||||
static u16 iwl_mvm_tx_csum(struct iwl_mvm *mvm, struct sk_buff *skb,
|
||||
struct ieee80211_hdr *hdr,
|
||||
struct ieee80211_tx_info *info)
|
||||
{
|
||||
u16 offload_assist = 0;
|
||||
#if IS_ENABLED(CONFIG_INET)
|
||||
u16 mh_len = ieee80211_hdrlen(hdr->frame_control);
|
||||
u16 offload_assist = le16_to_cpu(tx_cmd->offload_assist);
|
||||
u8 protocol = 0;
|
||||
|
||||
/*
|
||||
@ -117,7 +116,7 @@ static void iwl_mvm_tx_csum(struct iwl_mvm *mvm, struct sk_buff *skb,
|
||||
* compute it
|
||||
*/
|
||||
if (skb->ip_summed != CHECKSUM_PARTIAL || IWL_MVM_SW_TX_CSUM_OFFLOAD)
|
||||
return;
|
||||
goto out;
|
||||
|
||||
/* We do not expect to be requested to csum stuff we do not support */
|
||||
if (WARN_ONCE(!(mvm->hw->netdev_features & IWL_TX_CSUM_NETIF_FLAGS) ||
|
||||
@ -125,7 +124,7 @@ static void iwl_mvm_tx_csum(struct iwl_mvm *mvm, struct sk_buff *skb,
|
||||
skb->protocol != htons(ETH_P_IPV6)),
|
||||
"No support for requested checksum\n")) {
|
||||
skb_checksum_help(skb);
|
||||
return;
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (skb->protocol == htons(ETH_P_IP)) {
|
||||
@ -145,7 +144,7 @@ static void iwl_mvm_tx_csum(struct iwl_mvm *mvm, struct sk_buff *skb,
|
||||
protocol != NEXTHDR_HOP &&
|
||||
protocol != NEXTHDR_DEST) {
|
||||
skb_checksum_help(skb);
|
||||
return;
|
||||
goto out;
|
||||
}
|
||||
|
||||
hp = OPT_HDR(struct ipv6_opt_hdr, skb, off);
|
||||
@ -159,7 +158,7 @@ static void iwl_mvm_tx_csum(struct iwl_mvm *mvm, struct sk_buff *skb,
|
||||
if (protocol != IPPROTO_TCP && protocol != IPPROTO_UDP) {
|
||||
WARN_ON_ONCE(1);
|
||||
skb_checksum_help(skb);
|
||||
return;
|
||||
goto out;
|
||||
}
|
||||
|
||||
/* enable L4 csum */
|
||||
@ -191,8 +190,9 @@ static void iwl_mvm_tx_csum(struct iwl_mvm *mvm, struct sk_buff *skb,
|
||||
mh_len /= 2;
|
||||
offload_assist |= mh_len << TX_CMD_OFFLD_MH_SIZE;
|
||||
|
||||
tx_cmd->offload_assist = cpu_to_le16(offload_assist);
|
||||
out:
|
||||
#endif
|
||||
return offload_assist;
|
||||
}
|
||||
|
||||
/*
|
||||
@ -295,7 +295,52 @@ void iwl_mvm_set_tx_cmd(struct iwl_mvm *mvm, struct sk_buff *skb,
|
||||
!(tx_cmd->offload_assist & cpu_to_le16(BIT(TX_CMD_OFFLD_AMSDU))))
|
||||
tx_cmd->offload_assist |= cpu_to_le16(BIT(TX_CMD_OFFLD_PAD));
|
||||
|
||||
iwl_mvm_tx_csum(mvm, skb, hdr, info, tx_cmd);
|
||||
tx_cmd->offload_assist |=
|
||||
cpu_to_le16(iwl_mvm_tx_csum(mvm, skb, hdr, info));
|
||||
}
|
||||
|
||||
static u32 iwl_mvm_get_tx_rate(struct iwl_mvm *mvm,
|
||||
struct ieee80211_tx_info *info,
|
||||
struct ieee80211_sta *sta)
|
||||
{
|
||||
int rate_idx;
|
||||
u8 rate_plcp;
|
||||
u32 rate_flags;
|
||||
|
||||
/* HT rate doesn't make sense for a non data frame */
|
||||
WARN_ONCE(info->control.rates[0].flags & IEEE80211_TX_RC_MCS,
|
||||
"Got an HT rate (flags:0x%x/mcs:%d) for a non data frame\n",
|
||||
info->control.rates[0].flags,
|
||||
info->control.rates[0].idx);
|
||||
|
||||
rate_idx = info->control.rates[0].idx;
|
||||
/* if the rate isn't a well known legacy rate, take the lowest one */
|
||||
if (rate_idx < 0 || rate_idx >= IWL_RATE_COUNT_LEGACY)
|
||||
rate_idx = rate_lowest_index(
|
||||
&mvm->nvm_data->bands[info->band], sta);
|
||||
|
||||
/* For 5 GHZ band, remap mac80211 rate indices into driver indices */
|
||||
if (info->band == NL80211_BAND_5GHZ)
|
||||
rate_idx += IWL_FIRST_OFDM_RATE;
|
||||
|
||||
/* For 2.4 GHZ band, check that there is no need to remap */
|
||||
BUILD_BUG_ON(IWL_FIRST_CCK_RATE != 0);
|
||||
|
||||
/* Get PLCP rate for tx_cmd->rate_n_flags */
|
||||
rate_plcp = iwl_mvm_mac80211_idx_to_hwrate(rate_idx);
|
||||
|
||||
if (info->band == NL80211_BAND_2GHZ &&
|
||||
!iwl_mvm_bt_coex_is_shared_ant_avail(mvm))
|
||||
rate_flags = mvm->cfg->non_shared_ant << RATE_MCS_ANT_POS;
|
||||
else
|
||||
rate_flags =
|
||||
BIT(mvm->mgmt_last_antenna_idx) << RATE_MCS_ANT_POS;
|
||||
|
||||
/* Set CCK flag as needed */
|
||||
if ((rate_idx >= IWL_FIRST_CCK_RATE) && (rate_idx <= IWL_LAST_CCK_RATE))
|
||||
rate_flags |= RATE_MCS_CCK_MSK;
|
||||
|
||||
return (u32)rate_plcp | rate_flags;
|
||||
}
|
||||
|
||||
/*
|
||||
@ -305,10 +350,6 @@ void iwl_mvm_set_tx_cmd_rate(struct iwl_mvm *mvm, struct iwl_tx_cmd *tx_cmd,
|
||||
struct ieee80211_tx_info *info,
|
||||
struct ieee80211_sta *sta, __le16 fc)
|
||||
{
|
||||
u32 rate_flags;
|
||||
int rate_idx;
|
||||
u8 rate_plcp;
|
||||
|
||||
/* Set retry limit on RTS packets */
|
||||
tx_cmd->rts_retry_limit = IWL_RTS_DFAULT_RETRY_LIMIT;
|
||||
|
||||
@ -337,46 +378,12 @@ void iwl_mvm_set_tx_cmd_rate(struct iwl_mvm *mvm, struct iwl_tx_cmd *tx_cmd,
|
||||
cpu_to_le32(TX_CMD_FLG_ACK | TX_CMD_FLG_BAR);
|
||||
}
|
||||
|
||||
/* HT rate doesn't make sense for a non data frame */
|
||||
WARN_ONCE(info->control.rates[0].flags & IEEE80211_TX_RC_MCS,
|
||||
"Got an HT rate (flags:0x%x/mcs:%d) for a non data frame (fc:0x%x)\n",
|
||||
info->control.rates[0].flags,
|
||||
info->control.rates[0].idx,
|
||||
le16_to_cpu(fc));
|
||||
|
||||
rate_idx = info->control.rates[0].idx;
|
||||
/* if the rate isn't a well known legacy rate, take the lowest one */
|
||||
if (rate_idx < 0 || rate_idx >= IWL_RATE_COUNT_LEGACY)
|
||||
rate_idx = rate_lowest_index(
|
||||
&mvm->nvm_data->bands[info->band], sta);
|
||||
|
||||
/* For 5 GHZ band, remap mac80211 rate indices into driver indices */
|
||||
if (info->band == NL80211_BAND_5GHZ)
|
||||
rate_idx += IWL_FIRST_OFDM_RATE;
|
||||
|
||||
/* For 2.4 GHZ band, check that there is no need to remap */
|
||||
BUILD_BUG_ON(IWL_FIRST_CCK_RATE != 0);
|
||||
|
||||
/* Get PLCP rate for tx_cmd->rate_n_flags */
|
||||
rate_plcp = iwl_mvm_mac80211_idx_to_hwrate(rate_idx);
|
||||
|
||||
mvm->mgmt_last_antenna_idx =
|
||||
iwl_mvm_next_antenna(mvm, iwl_mvm_get_valid_tx_ant(mvm),
|
||||
mvm->mgmt_last_antenna_idx);
|
||||
|
||||
if (info->band == NL80211_BAND_2GHZ &&
|
||||
!iwl_mvm_bt_coex_is_shared_ant_avail(mvm))
|
||||
rate_flags = mvm->cfg->non_shared_ant << RATE_MCS_ANT_POS;
|
||||
else
|
||||
rate_flags =
|
||||
BIT(mvm->mgmt_last_antenna_idx) << RATE_MCS_ANT_POS;
|
||||
|
||||
/* Set CCK flag as needed */
|
||||
if ((rate_idx >= IWL_FIRST_CCK_RATE) && (rate_idx <= IWL_LAST_CCK_RATE))
|
||||
rate_flags |= RATE_MCS_CCK_MSK;
|
||||
|
||||
/* Set the rate in the TX cmd */
|
||||
tx_cmd->rate_n_flags = cpu_to_le32((u32)rate_plcp | rate_flags);
|
||||
tx_cmd->rate_n_flags = cpu_to_le32(iwl_mvm_get_tx_rate(mvm, info, sta));
|
||||
}
|
||||
|
||||
static inline void iwl_mvm_set_tx_cmd_pn(struct ieee80211_tx_info *info,
|
||||
|
@ -693,10 +693,6 @@ void iwl_mvm_enable_txq(struct iwl_mvm *mvm, int queue, int mac80211_queue,
|
||||
.tid = cfg->tid,
|
||||
};
|
||||
|
||||
/* Set sta_id in the command, if it exists */
|
||||
if (iwl_mvm_is_dqa_supported(mvm))
|
||||
cmd.sta_id = cfg->sta_id;
|
||||
|
||||
iwl_trans_txq_enable_cfg(mvm->trans, queue, ssn, NULL,
|
||||
wdg_timeout);
|
||||
WARN(iwl_mvm_send_cmd_pdu(mvm, SCD_QUEUE_CFG, 0, sizeof(cmd),
|
||||
@ -706,8 +702,8 @@ void iwl_mvm_enable_txq(struct iwl_mvm *mvm, int queue, int mac80211_queue,
|
||||
}
|
||||
}
|
||||
|
||||
void iwl_mvm_disable_txq(struct iwl_mvm *mvm, int queue, int mac80211_queue,
|
||||
u8 tid, u8 flags)
|
||||
int iwl_mvm_disable_txq(struct iwl_mvm *mvm, int queue, int mac80211_queue,
|
||||
u8 tid, u8 flags)
|
||||
{
|
||||
struct iwl_scd_txq_cfg_cmd cmd = {
|
||||
.scd_queue = queue,
|
||||
@ -720,7 +716,7 @@ void iwl_mvm_disable_txq(struct iwl_mvm *mvm, int queue, int mac80211_queue,
|
||||
|
||||
if (WARN_ON(mvm->queue_info[queue].hw_queue_refcount == 0)) {
|
||||
spin_unlock_bh(&mvm->queue_info_lock);
|
||||
return;
|
||||
return 0;
|
||||
}
|
||||
|
||||
mvm->queue_info[queue].tid_bitmap &= ~BIT(tid);
|
||||
@ -760,7 +756,7 @@ void iwl_mvm_disable_txq(struct iwl_mvm *mvm, int queue, int mac80211_queue,
|
||||
/* If the queue is still enabled - nothing left to do in this func */
|
||||
if (cmd.action == SCD_CFG_ENABLE_QUEUE) {
|
||||
spin_unlock_bh(&mvm->queue_info_lock);
|
||||
return;
|
||||
return 0;
|
||||
}
|
||||
|
||||
cmd.sta_id = mvm->queue_info[queue].ra_sta_id;
|
||||
@ -791,6 +787,8 @@ void iwl_mvm_disable_txq(struct iwl_mvm *mvm, int queue, int mac80211_queue,
|
||||
if (ret)
|
||||
IWL_ERR(mvm, "Failed to disable queue %d (ret=%d)\n",
|
||||
queue, ret);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -805,7 +805,7 @@ static int iwl_pcie_load_cpu_sections_8000(struct iwl_trans *trans,
|
||||
(*first_ucode_section)++;
|
||||
}
|
||||
|
||||
for (i = *first_ucode_section; i < IWL_UCODE_SECTION_MAX; i++) {
|
||||
for (i = *first_ucode_section; i < image->num_sec; i++) {
|
||||
last_read_idx = i;
|
||||
|
||||
/*
|
||||
@ -868,19 +868,15 @@ static int iwl_pcie_load_cpu_sections(struct iwl_trans *trans,
|
||||
int cpu,
|
||||
int *first_ucode_section)
|
||||
{
|
||||
int shift_param;
|
||||
int i, ret = 0;
|
||||
u32 last_read_idx = 0;
|
||||
|
||||
if (cpu == 1) {
|
||||
shift_param = 0;
|
||||
if (cpu == 1)
|
||||
*first_ucode_section = 0;
|
||||
} else {
|
||||
shift_param = 16;
|
||||
else
|
||||
(*first_ucode_section)++;
|
||||
}
|
||||
|
||||
for (i = *first_ucode_section; i < IWL_UCODE_SECTION_MAX; i++) {
|
||||
for (i = *first_ucode_section; i < image->num_sec; i++) {
|
||||
last_read_idx = i;
|
||||
|
||||
/*
|
||||
@ -1066,6 +1062,20 @@ static int iwl_pcie_load_given_ucode_8000(struct iwl_trans *trans,
|
||||
&first_ucode_section);
|
||||
}
|
||||
|
||||
static bool iwl_trans_check_hw_rf_kill(struct iwl_trans *trans)
|
||||
{
|
||||
bool hw_rfkill = iwl_is_rfkill_set(trans);
|
||||
|
||||
if (hw_rfkill)
|
||||
set_bit(STATUS_RFKILL, &trans->status);
|
||||
else
|
||||
clear_bit(STATUS_RFKILL, &trans->status);
|
||||
|
||||
iwl_trans_pcie_rf_kill(trans, hw_rfkill);
|
||||
|
||||
return hw_rfkill;
|
||||
}
|
||||
|
||||
static void _iwl_trans_pcie_stop_device(struct iwl_trans *trans, bool low_power)
|
||||
{
|
||||
struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans);
|
||||
@ -1208,12 +1218,7 @@ static int iwl_trans_pcie_start_fw(struct iwl_trans *trans,
|
||||
mutex_lock(&trans_pcie->mutex);
|
||||
|
||||
/* If platform's RF_KILL switch is NOT set to KILL */
|
||||
hw_rfkill = iwl_is_rfkill_set(trans);
|
||||
if (hw_rfkill)
|
||||
set_bit(STATUS_RFKILL, &trans->status);
|
||||
else
|
||||
clear_bit(STATUS_RFKILL, &trans->status);
|
||||
iwl_trans_pcie_rf_kill(trans, hw_rfkill);
|
||||
hw_rfkill = iwl_trans_check_hw_rf_kill(trans);
|
||||
if (hw_rfkill && !run_in_rfkill) {
|
||||
ret = -ERFKILL;
|
||||
goto out;
|
||||
@ -1261,13 +1266,7 @@ static int iwl_trans_pcie_start_fw(struct iwl_trans *trans,
|
||||
ret = iwl_pcie_load_given_ucode(trans, fw);
|
||||
|
||||
/* re-check RF-Kill state since we may have missed the interrupt */
|
||||
hw_rfkill = iwl_is_rfkill_set(trans);
|
||||
if (hw_rfkill)
|
||||
set_bit(STATUS_RFKILL, &trans->status);
|
||||
else
|
||||
clear_bit(STATUS_RFKILL, &trans->status);
|
||||
|
||||
iwl_trans_pcie_rf_kill(trans, hw_rfkill);
|
||||
hw_rfkill = iwl_trans_check_hw_rf_kill(trans);
|
||||
if (hw_rfkill && !run_in_rfkill)
|
||||
ret = -ERFKILL;
|
||||
|
||||
@ -1659,7 +1658,6 @@ static int iwl_pcie_init_msix_handler(struct pci_dev *pdev,
|
||||
static int _iwl_trans_pcie_start_hw(struct iwl_trans *trans, bool low_power)
|
||||
{
|
||||
struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans);
|
||||
bool hw_rfkill;
|
||||
int err;
|
||||
|
||||
lockdep_assert_held(&trans_pcie->mutex);
|
||||
@ -1683,13 +1681,8 @@ static int _iwl_trans_pcie_start_hw(struct iwl_trans *trans, bool low_power)
|
||||
/* Set is_down to false here so that...*/
|
||||
trans_pcie->is_down = false;
|
||||
|
||||
hw_rfkill = iwl_is_rfkill_set(trans);
|
||||
if (hw_rfkill)
|
||||
set_bit(STATUS_RFKILL, &trans->status);
|
||||
else
|
||||
clear_bit(STATUS_RFKILL, &trans->status);
|
||||
/* ... rfkill can call stop_device and set it false if needed */
|
||||
iwl_trans_pcie_rf_kill(trans, hw_rfkill);
|
||||
/* ...rfkill can call stop_device and set it false if needed */
|
||||
iwl_trans_check_hw_rf_kill(trans);
|
||||
|
||||
/* Make sure we sync here, because we'll need full access later */
|
||||
if (low_power)
|
||||
|
@ -305,7 +305,7 @@ int lbs_cmd_802_11_sleep_params(struct lbs_private *priv, uint16_t cmd_action,
|
||||
}
|
||||
|
||||
lbs_deb_leave_args(LBS_DEB_CMD, "ret %d", ret);
|
||||
return 0;
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int lbs_wait_for_ds_awake(struct lbs_private *priv)
|
||||
|
@ -101,13 +101,6 @@ mwifiex_11n_form_amsdu_txpd(struct mwifiex_private *priv,
|
||||
{
|
||||
struct txpd *local_tx_pd;
|
||||
struct mwifiex_txinfo *tx_info = MWIFIEX_SKB_TXCB(skb);
|
||||
unsigned int pad;
|
||||
int headroom = (priv->adapter->iface_type ==
|
||||
MWIFIEX_USB) ? 0 : INTF_HEADER_LEN;
|
||||
|
||||
pad = ((void *)skb->data - sizeof(*local_tx_pd) -
|
||||
headroom - NULL) & (MWIFIEX_DMA_ALIGN_SZ - 1);
|
||||
skb_push(skb, pad);
|
||||
|
||||
skb_push(skb, sizeof(*local_tx_pd));
|
||||
|
||||
@ -121,12 +114,10 @@ mwifiex_11n_form_amsdu_txpd(struct mwifiex_private *priv,
|
||||
local_tx_pd->bss_num = priv->bss_num;
|
||||
local_tx_pd->bss_type = priv->bss_type;
|
||||
/* Always zero as the data is followed by struct txpd */
|
||||
local_tx_pd->tx_pkt_offset = cpu_to_le16(sizeof(struct txpd) +
|
||||
pad);
|
||||
local_tx_pd->tx_pkt_offset = cpu_to_le16(sizeof(struct txpd));
|
||||
local_tx_pd->tx_pkt_type = cpu_to_le16(PKT_TYPE_AMSDU);
|
||||
local_tx_pd->tx_pkt_length = cpu_to_le16(skb->len -
|
||||
sizeof(*local_tx_pd) -
|
||||
pad);
|
||||
sizeof(*local_tx_pd));
|
||||
|
||||
if (tx_info->flags & MWIFIEX_BUF_FLAG_TDLS_PKT)
|
||||
local_tx_pd->flags |= MWIFIEX_TXPD_FLAGS_TDLS_PACKET;
|
||||
@ -190,7 +181,11 @@ mwifiex_11n_aggregate_pkt(struct mwifiex_private *priv,
|
||||
ra_list_flags);
|
||||
return -1;
|
||||
}
|
||||
skb_reserve(skb_aggr, MWIFIEX_MIN_DATA_HEADER_LEN);
|
||||
|
||||
/* skb_aggr->data already 64 byte align, just reserve bus interface
|
||||
* header and txpd.
|
||||
*/
|
||||
skb_reserve(skb_aggr, headroom + sizeof(struct txpd));
|
||||
tx_info_aggr = MWIFIEX_SKB_TXCB(skb_aggr);
|
||||
|
||||
memset(tx_info_aggr, 0, sizeof(*tx_info_aggr));
|
||||
|
@ -114,7 +114,8 @@ mwifiex_info_read(struct file *file, char __user *ubuf,
|
||||
if (GET_BSS_ROLE(priv) == MWIFIEX_BSS_ROLE_STA) {
|
||||
p += sprintf(p, "multicast_count=\"%d\"\n",
|
||||
netdev_mc_count(netdev));
|
||||
p += sprintf(p, "essid=\"%s\"\n", info.ssid.ssid);
|
||||
p += sprintf(p, "essid=\"%.*s\"\n", info.ssid.ssid_len,
|
||||
info.ssid.ssid);
|
||||
p += sprintf(p, "bssid=\"%pM\"\n", info.bssid);
|
||||
p += sprintf(p, "channel=\"%d\"\n", (int) info.bss_chan);
|
||||
p += sprintf(p, "country_code = \"%s\"\n", info.country_code);
|
||||
|
@ -550,6 +550,7 @@ enum mwifiex_channel_flags {
|
||||
#define EVENT_TX_DATA_PAUSE 0x00000055
|
||||
#define EVENT_EXT_SCAN_REPORT 0x00000058
|
||||
#define EVENT_RXBA_SYNC 0x00000059
|
||||
#define EVENT_UNKNOWN_DEBUG 0x00000063
|
||||
#define EVENT_BG_SCAN_STOPPED 0x00000065
|
||||
#define EVENT_REMAIN_ON_CHAN_EXPIRED 0x0000005f
|
||||
#define EVENT_MULTI_CHAN_INFO 0x0000006a
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user