mirror of
https://mirrors.bfsu.edu.cn/git/linux.git
synced 2024-12-25 03:55:09 +08:00
Merge ath-next from git://git.kernel.org/pub/scm/linux/kernel/git/kvalo/ath.git
ath.git patches for 4.11. Major changes: 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
This commit is contained in:
commit
7243a1af37
@ -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)
|
||||
|
||||
|
@ -1,7 +1,7 @@
|
||||
#ifndef __QCOM_SMEM_STATE__
|
||||
#define __QCOM_SMEM_STATE__
|
||||
|
||||
#include <linux/errno.h>
|
||||
#include <linux/err.h>
|
||||
|
||||
struct device_node;
|
||||
struct qcom_smem_state;
|
||||
|
Loading…
Reference in New Issue
Block a user