Merge branch 'for-linville' of git://github.com/kvalo/ath
This commit is contained in:
commit
22b3b9578d
|
@ -175,7 +175,7 @@ int ath10k_bmi_write_memory(struct ath10k *ar,
|
|||
return 0;
|
||||
}
|
||||
|
||||
int ath10k_bmi_execute(struct ath10k *ar, u32 address, u32 *param)
|
||||
int ath10k_bmi_execute(struct ath10k *ar, u32 address, u32 param, u32 *result)
|
||||
{
|
||||
struct bmi_cmd cmd;
|
||||
union bmi_resp resp;
|
||||
|
@ -184,7 +184,7 @@ int ath10k_bmi_execute(struct ath10k *ar, u32 address, u32 *param)
|
|||
int ret;
|
||||
|
||||
ath10k_dbg(ATH10K_DBG_BMI, "bmi execute address 0x%x param 0x%x\n",
|
||||
address, *param);
|
||||
address, param);
|
||||
|
||||
if (ar->bmi.done_sent) {
|
||||
ath10k_warn("command disallowed\n");
|
||||
|
@ -193,7 +193,7 @@ int ath10k_bmi_execute(struct ath10k *ar, u32 address, u32 *param)
|
|||
|
||||
cmd.id = __cpu_to_le32(BMI_EXECUTE);
|
||||
cmd.execute.addr = __cpu_to_le32(address);
|
||||
cmd.execute.param = __cpu_to_le32(*param);
|
||||
cmd.execute.param = __cpu_to_le32(param);
|
||||
|
||||
ret = ath10k_hif_exchange_bmi_msg(ar, &cmd, cmdlen, &resp, &resplen);
|
||||
if (ret) {
|
||||
|
@ -204,10 +204,13 @@ int ath10k_bmi_execute(struct ath10k *ar, u32 address, u32 *param)
|
|||
if (resplen < sizeof(resp.execute)) {
|
||||
ath10k_warn("invalid execute response length (%d)\n",
|
||||
resplen);
|
||||
return ret;
|
||||
return -EIO;
|
||||
}
|
||||
|
||||
*param = __le32_to_cpu(resp.execute.result);
|
||||
*result = __le32_to_cpu(resp.execute.result);
|
||||
|
||||
ath10k_dbg(ATH10K_DBG_BMI, "bmi execute result 0x%x\n", *result);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
|
@ -217,7 +217,7 @@ int ath10k_bmi_write_memory(struct ath10k *ar, u32 address,
|
|||
ret; \
|
||||
})
|
||||
|
||||
int ath10k_bmi_execute(struct ath10k *ar, u32 address, u32 *param);
|
||||
int ath10k_bmi_execute(struct ath10k *ar, u32 address, u32 param, u32 *result);
|
||||
int ath10k_bmi_lz_stream_start(struct ath10k *ar, u32 address);
|
||||
int ath10k_bmi_lz_data(struct ath10k *ar, const void *buffer, u32 length);
|
||||
int ath10k_bmi_fast_download(struct ath10k *ar, u32 address,
|
||||
|
|
|
@ -840,35 +840,17 @@ void ath10k_ce_recv_cb_register(struct ath10k_ce_pipe *ce_state,
|
|||
|
||||
static int ath10k_ce_init_src_ring(struct ath10k *ar,
|
||||
unsigned int ce_id,
|
||||
struct ath10k_ce_pipe *ce_state,
|
||||
const struct ce_attr *attr)
|
||||
{
|
||||
struct ath10k_pci *ar_pci = ath10k_pci_priv(ar);
|
||||
struct ath10k_ce_ring *src_ring;
|
||||
unsigned int nentries = attr->src_nentries;
|
||||
unsigned int ce_nbytes;
|
||||
u32 ctrl_addr = ath10k_ce_base_address(ce_id);
|
||||
dma_addr_t base_addr;
|
||||
char *ptr;
|
||||
struct ath10k_ce_pipe *ce_state = &ar_pci->ce_states[ce_id];
|
||||
struct ath10k_ce_ring *src_ring = ce_state->src_ring;
|
||||
u32 nentries, ctrl_addr = ath10k_ce_base_address(ce_id);
|
||||
|
||||
nentries = roundup_pow_of_two(nentries);
|
||||
nentries = roundup_pow_of_two(attr->src_nentries);
|
||||
|
||||
if (ce_state->src_ring) {
|
||||
WARN_ON(ce_state->src_ring->nentries != nentries);
|
||||
return 0;
|
||||
}
|
||||
|
||||
ce_nbytes = sizeof(struct ath10k_ce_ring) + (nentries * sizeof(void *));
|
||||
ptr = kzalloc(ce_nbytes, GFP_KERNEL);
|
||||
if (ptr == NULL)
|
||||
return -ENOMEM;
|
||||
|
||||
ce_state->src_ring = (struct ath10k_ce_ring *)ptr;
|
||||
src_ring = ce_state->src_ring;
|
||||
|
||||
ptr += sizeof(struct ath10k_ce_ring);
|
||||
src_ring->nentries = nentries;
|
||||
src_ring->nentries_mask = nentries - 1;
|
||||
memset(src_ring->per_transfer_context, 0,
|
||||
nentries * sizeof(*src_ring->per_transfer_context));
|
||||
|
||||
src_ring->sw_index = ath10k_ce_src_ring_read_index_get(ar, ctrl_addr);
|
||||
src_ring->sw_index &= src_ring->nentries_mask;
|
||||
|
@ -878,21 +860,87 @@ static int ath10k_ce_init_src_ring(struct ath10k *ar,
|
|||
ath10k_ce_src_ring_write_index_get(ar, ctrl_addr);
|
||||
src_ring->write_index &= src_ring->nentries_mask;
|
||||
|
||||
src_ring->per_transfer_context = (void **)ptr;
|
||||
ath10k_ce_src_ring_base_addr_set(ar, ctrl_addr,
|
||||
src_ring->base_addr_ce_space);
|
||||
ath10k_ce_src_ring_size_set(ar, ctrl_addr, nentries);
|
||||
ath10k_ce_src_ring_dmax_set(ar, ctrl_addr, attr->src_sz_max);
|
||||
ath10k_ce_src_ring_byte_swap_set(ar, ctrl_addr, 0);
|
||||
ath10k_ce_src_ring_lowmark_set(ar, ctrl_addr, 0);
|
||||
ath10k_ce_src_ring_highmark_set(ar, ctrl_addr, nentries);
|
||||
|
||||
ath10k_dbg(ATH10K_DBG_BOOT,
|
||||
"boot init ce src ring id %d entries %d base_addr %p\n",
|
||||
ce_id, nentries, src_ring->base_addr_owner_space);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int ath10k_ce_init_dest_ring(struct ath10k *ar,
|
||||
unsigned int ce_id,
|
||||
const struct ce_attr *attr)
|
||||
{
|
||||
struct ath10k_pci *ar_pci = ath10k_pci_priv(ar);
|
||||
struct ath10k_ce_pipe *ce_state = &ar_pci->ce_states[ce_id];
|
||||
struct ath10k_ce_ring *dest_ring = ce_state->dest_ring;
|
||||
u32 nentries, ctrl_addr = ath10k_ce_base_address(ce_id);
|
||||
|
||||
nentries = roundup_pow_of_two(attr->dest_nentries);
|
||||
|
||||
memset(dest_ring->per_transfer_context, 0,
|
||||
nentries * sizeof(*dest_ring->per_transfer_context));
|
||||
|
||||
dest_ring->sw_index = ath10k_ce_dest_ring_read_index_get(ar, ctrl_addr);
|
||||
dest_ring->sw_index &= dest_ring->nentries_mask;
|
||||
dest_ring->write_index =
|
||||
ath10k_ce_dest_ring_write_index_get(ar, ctrl_addr);
|
||||
dest_ring->write_index &= dest_ring->nentries_mask;
|
||||
|
||||
ath10k_ce_dest_ring_base_addr_set(ar, ctrl_addr,
|
||||
dest_ring->base_addr_ce_space);
|
||||
ath10k_ce_dest_ring_size_set(ar, ctrl_addr, nentries);
|
||||
ath10k_ce_dest_ring_byte_swap_set(ar, ctrl_addr, 0);
|
||||
ath10k_ce_dest_ring_lowmark_set(ar, ctrl_addr, 0);
|
||||
ath10k_ce_dest_ring_highmark_set(ar, ctrl_addr, nentries);
|
||||
|
||||
ath10k_dbg(ATH10K_DBG_BOOT,
|
||||
"boot ce dest ring id %d entries %d base_addr %p\n",
|
||||
ce_id, nentries, dest_ring->base_addr_owner_space);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static struct ath10k_ce_ring *
|
||||
ath10k_ce_alloc_src_ring(struct ath10k *ar, unsigned int ce_id,
|
||||
const struct ce_attr *attr)
|
||||
{
|
||||
struct ath10k_ce_ring *src_ring;
|
||||
u32 nentries = attr->src_nentries;
|
||||
dma_addr_t base_addr;
|
||||
|
||||
nentries = roundup_pow_of_two(nentries);
|
||||
|
||||
src_ring = kzalloc(sizeof(*src_ring) +
|
||||
(nentries *
|
||||
sizeof(*src_ring->per_transfer_context)),
|
||||
GFP_KERNEL);
|
||||
if (src_ring == NULL)
|
||||
return ERR_PTR(-ENOMEM);
|
||||
|
||||
src_ring->nentries = nentries;
|
||||
src_ring->nentries_mask = nentries - 1;
|
||||
|
||||
/*
|
||||
* Legacy platforms that do not support cache
|
||||
* coherent DMA are unsupported
|
||||
*/
|
||||
src_ring->base_addr_owner_space_unaligned =
|
||||
pci_alloc_consistent(ar_pci->pdev,
|
||||
(nentries * sizeof(struct ce_desc) +
|
||||
CE_DESC_RING_ALIGN),
|
||||
&base_addr);
|
||||
dma_alloc_coherent(ar->dev,
|
||||
(nentries * sizeof(struct ce_desc) +
|
||||
CE_DESC_RING_ALIGN),
|
||||
&base_addr, GFP_KERNEL);
|
||||
if (!src_ring->base_addr_owner_space_unaligned) {
|
||||
kfree(ce_state->src_ring);
|
||||
ce_state->src_ring = NULL;
|
||||
return -ENOMEM;
|
||||
kfree(src_ring);
|
||||
return ERR_PTR(-ENOMEM);
|
||||
}
|
||||
|
||||
src_ring->base_addr_ce_space_unaligned = base_addr;
|
||||
|
@ -912,88 +960,54 @@ static int ath10k_ce_init_src_ring(struct ath10k *ar,
|
|||
kmalloc((nentries * sizeof(struct ce_desc) +
|
||||
CE_DESC_RING_ALIGN), GFP_KERNEL);
|
||||
if (!src_ring->shadow_base_unaligned) {
|
||||
pci_free_consistent(ar_pci->pdev,
|
||||
(nentries * sizeof(struct ce_desc) +
|
||||
CE_DESC_RING_ALIGN),
|
||||
src_ring->base_addr_owner_space,
|
||||
src_ring->base_addr_ce_space);
|
||||
kfree(ce_state->src_ring);
|
||||
ce_state->src_ring = NULL;
|
||||
return -ENOMEM;
|
||||
dma_free_coherent(ar->dev,
|
||||
(nentries * sizeof(struct ce_desc) +
|
||||
CE_DESC_RING_ALIGN),
|
||||
src_ring->base_addr_owner_space,
|
||||
src_ring->base_addr_ce_space);
|
||||
kfree(src_ring);
|
||||
return ERR_PTR(-ENOMEM);
|
||||
}
|
||||
|
||||
src_ring->shadow_base = PTR_ALIGN(
|
||||
src_ring->shadow_base_unaligned,
|
||||
CE_DESC_RING_ALIGN);
|
||||
|
||||
ath10k_ce_src_ring_base_addr_set(ar, ctrl_addr,
|
||||
src_ring->base_addr_ce_space);
|
||||
ath10k_ce_src_ring_size_set(ar, ctrl_addr, nentries);
|
||||
ath10k_ce_src_ring_dmax_set(ar, ctrl_addr, attr->src_sz_max);
|
||||
ath10k_ce_src_ring_byte_swap_set(ar, ctrl_addr, 0);
|
||||
ath10k_ce_src_ring_lowmark_set(ar, ctrl_addr, 0);
|
||||
ath10k_ce_src_ring_highmark_set(ar, ctrl_addr, nentries);
|
||||
|
||||
ath10k_dbg(ATH10K_DBG_BOOT,
|
||||
"boot ce src ring id %d entries %d base_addr %p\n",
|
||||
ce_id, nentries, src_ring->base_addr_owner_space);
|
||||
|
||||
return 0;
|
||||
return src_ring;
|
||||
}
|
||||
|
||||
static int ath10k_ce_init_dest_ring(struct ath10k *ar,
|
||||
unsigned int ce_id,
|
||||
struct ath10k_ce_pipe *ce_state,
|
||||
const struct ce_attr *attr)
|
||||
static struct ath10k_ce_ring *
|
||||
ath10k_ce_alloc_dest_ring(struct ath10k *ar, unsigned int ce_id,
|
||||
const struct ce_attr *attr)
|
||||
{
|
||||
struct ath10k_pci *ar_pci = ath10k_pci_priv(ar);
|
||||
struct ath10k_ce_ring *dest_ring;
|
||||
unsigned int nentries = attr->dest_nentries;
|
||||
unsigned int ce_nbytes;
|
||||
u32 ctrl_addr = ath10k_ce_base_address(ce_id);
|
||||
u32 nentries;
|
||||
dma_addr_t base_addr;
|
||||
char *ptr;
|
||||
|
||||
nentries = roundup_pow_of_two(nentries);
|
||||
nentries = roundup_pow_of_two(attr->dest_nentries);
|
||||
|
||||
if (ce_state->dest_ring) {
|
||||
WARN_ON(ce_state->dest_ring->nentries != nentries);
|
||||
return 0;
|
||||
}
|
||||
dest_ring = kzalloc(sizeof(*dest_ring) +
|
||||
(nentries *
|
||||
sizeof(*dest_ring->per_transfer_context)),
|
||||
GFP_KERNEL);
|
||||
if (dest_ring == NULL)
|
||||
return ERR_PTR(-ENOMEM);
|
||||
|
||||
ce_nbytes = sizeof(struct ath10k_ce_ring) + (nentries * sizeof(void *));
|
||||
ptr = kzalloc(ce_nbytes, GFP_KERNEL);
|
||||
if (ptr == NULL)
|
||||
return -ENOMEM;
|
||||
|
||||
ce_state->dest_ring = (struct ath10k_ce_ring *)ptr;
|
||||
dest_ring = ce_state->dest_ring;
|
||||
|
||||
ptr += sizeof(struct ath10k_ce_ring);
|
||||
dest_ring->nentries = nentries;
|
||||
dest_ring->nentries_mask = nentries - 1;
|
||||
|
||||
dest_ring->sw_index = ath10k_ce_dest_ring_read_index_get(ar, ctrl_addr);
|
||||
dest_ring->sw_index &= dest_ring->nentries_mask;
|
||||
dest_ring->write_index =
|
||||
ath10k_ce_dest_ring_write_index_get(ar, ctrl_addr);
|
||||
dest_ring->write_index &= dest_ring->nentries_mask;
|
||||
|
||||
dest_ring->per_transfer_context = (void **)ptr;
|
||||
|
||||
/*
|
||||
* Legacy platforms that do not support cache
|
||||
* coherent DMA are unsupported
|
||||
*/
|
||||
dest_ring->base_addr_owner_space_unaligned =
|
||||
pci_alloc_consistent(ar_pci->pdev,
|
||||
(nentries * sizeof(struct ce_desc) +
|
||||
CE_DESC_RING_ALIGN),
|
||||
&base_addr);
|
||||
dma_alloc_coherent(ar->dev,
|
||||
(nentries * sizeof(struct ce_desc) +
|
||||
CE_DESC_RING_ALIGN),
|
||||
&base_addr, GFP_KERNEL);
|
||||
if (!dest_ring->base_addr_owner_space_unaligned) {
|
||||
kfree(ce_state->dest_ring);
|
||||
ce_state->dest_ring = NULL;
|
||||
return -ENOMEM;
|
||||
kfree(dest_ring);
|
||||
return ERR_PTR(-ENOMEM);
|
||||
}
|
||||
|
||||
dest_ring->base_addr_ce_space_unaligned = base_addr;
|
||||
|
@ -1012,39 +1026,7 @@ static int ath10k_ce_init_dest_ring(struct ath10k *ar,
|
|||
dest_ring->base_addr_ce_space_unaligned,
|
||||
CE_DESC_RING_ALIGN);
|
||||
|
||||
ath10k_ce_dest_ring_base_addr_set(ar, ctrl_addr,
|
||||
dest_ring->base_addr_ce_space);
|
||||
ath10k_ce_dest_ring_size_set(ar, ctrl_addr, nentries);
|
||||
ath10k_ce_dest_ring_byte_swap_set(ar, ctrl_addr, 0);
|
||||
ath10k_ce_dest_ring_lowmark_set(ar, ctrl_addr, 0);
|
||||
ath10k_ce_dest_ring_highmark_set(ar, ctrl_addr, nentries);
|
||||
|
||||
ath10k_dbg(ATH10K_DBG_BOOT,
|
||||
"boot ce dest ring id %d entries %d base_addr %p\n",
|
||||
ce_id, nentries, dest_ring->base_addr_owner_space);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static struct ath10k_ce_pipe *ath10k_ce_init_state(struct ath10k *ar,
|
||||
unsigned int ce_id,
|
||||
const struct ce_attr *attr)
|
||||
{
|
||||
struct ath10k_pci *ar_pci = ath10k_pci_priv(ar);
|
||||
struct ath10k_ce_pipe *ce_state = &ar_pci->ce_states[ce_id];
|
||||
u32 ctrl_addr = ath10k_ce_base_address(ce_id);
|
||||
|
||||
spin_lock_bh(&ar_pci->ce_lock);
|
||||
|
||||
ce_state->ar = ar;
|
||||
ce_state->id = ce_id;
|
||||
ce_state->ctrl_addr = ctrl_addr;
|
||||
ce_state->attr_flags = attr->flags;
|
||||
ce_state->src_sz_max = attr->src_sz_max;
|
||||
|
||||
spin_unlock_bh(&ar_pci->ce_lock);
|
||||
|
||||
return ce_state;
|
||||
return dest_ring;
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -1054,11 +1036,11 @@ static struct ath10k_ce_pipe *ath10k_ce_init_state(struct ath10k *ar,
|
|||
* initialization. It may be that only one side or the other is
|
||||
* initialized by software/firmware.
|
||||
*/
|
||||
struct ath10k_ce_pipe *ath10k_ce_init(struct ath10k *ar,
|
||||
unsigned int ce_id,
|
||||
const struct ce_attr *attr)
|
||||
int ath10k_ce_init_pipe(struct ath10k *ar, unsigned int ce_id,
|
||||
const struct ce_attr *attr)
|
||||
{
|
||||
struct ath10k_ce_pipe *ce_state;
|
||||
struct ath10k_pci *ar_pci = ath10k_pci_priv(ar);
|
||||
struct ath10k_ce_pipe *ce_state = &ar_pci->ce_states[ce_id];
|
||||
int ret;
|
||||
|
||||
/*
|
||||
|
@ -1074,64 +1056,128 @@ struct ath10k_ce_pipe *ath10k_ce_init(struct ath10k *ar,
|
|||
|
||||
ret = ath10k_pci_wake(ar);
|
||||
if (ret)
|
||||
return NULL;
|
||||
return ret;
|
||||
|
||||
ce_state = ath10k_ce_init_state(ar, ce_id, attr);
|
||||
if (!ce_state) {
|
||||
ath10k_err("Failed to initialize CE state for ID: %d\n", ce_id);
|
||||
goto out;
|
||||
}
|
||||
spin_lock_bh(&ar_pci->ce_lock);
|
||||
ce_state->ar = ar;
|
||||
ce_state->id = ce_id;
|
||||
ce_state->ctrl_addr = ath10k_ce_base_address(ce_id);
|
||||
ce_state->attr_flags = attr->flags;
|
||||
ce_state->src_sz_max = attr->src_sz_max;
|
||||
spin_unlock_bh(&ar_pci->ce_lock);
|
||||
|
||||
if (attr->src_nentries) {
|
||||
ret = ath10k_ce_init_src_ring(ar, ce_id, ce_state, attr);
|
||||
ret = ath10k_ce_init_src_ring(ar, ce_id, attr);
|
||||
if (ret) {
|
||||
ath10k_err("Failed to initialize CE src ring for ID: %d (%d)\n",
|
||||
ce_id, ret);
|
||||
ath10k_ce_deinit(ce_state);
|
||||
ce_state = NULL;
|
||||
goto out;
|
||||
}
|
||||
}
|
||||
|
||||
if (attr->dest_nentries) {
|
||||
ret = ath10k_ce_init_dest_ring(ar, ce_id, ce_state, attr);
|
||||
ret = ath10k_ce_init_dest_ring(ar, ce_id, attr);
|
||||
if (ret) {
|
||||
ath10k_err("Failed to initialize CE dest ring for ID: %d (%d)\n",
|
||||
ce_id, ret);
|
||||
ath10k_ce_deinit(ce_state);
|
||||
ce_state = NULL;
|
||||
goto out;
|
||||
}
|
||||
}
|
||||
|
||||
out:
|
||||
ath10k_pci_sleep(ar);
|
||||
return ce_state;
|
||||
return ret;
|
||||
}
|
||||
|
||||
void ath10k_ce_deinit(struct ath10k_ce_pipe *ce_state)
|
||||
static void ath10k_ce_deinit_src_ring(struct ath10k *ar, unsigned int ce_id)
|
||||
{
|
||||
u32 ctrl_addr = ath10k_ce_base_address(ce_id);
|
||||
|
||||
ath10k_ce_src_ring_base_addr_set(ar, ctrl_addr, 0);
|
||||
ath10k_ce_src_ring_size_set(ar, ctrl_addr, 0);
|
||||
ath10k_ce_src_ring_dmax_set(ar, ctrl_addr, 0);
|
||||
ath10k_ce_src_ring_highmark_set(ar, ctrl_addr, 0);
|
||||
}
|
||||
|
||||
static void ath10k_ce_deinit_dest_ring(struct ath10k *ar, unsigned int ce_id)
|
||||
{
|
||||
u32 ctrl_addr = ath10k_ce_base_address(ce_id);
|
||||
|
||||
ath10k_ce_dest_ring_base_addr_set(ar, ctrl_addr, 0);
|
||||
ath10k_ce_dest_ring_size_set(ar, ctrl_addr, 0);
|
||||
ath10k_ce_dest_ring_highmark_set(ar, ctrl_addr, 0);
|
||||
}
|
||||
|
||||
void ath10k_ce_deinit_pipe(struct ath10k *ar, unsigned int ce_id)
|
||||
{
|
||||
int ret;
|
||||
|
||||
ret = ath10k_pci_wake(ar);
|
||||
if (ret)
|
||||
return;
|
||||
|
||||
ath10k_ce_deinit_src_ring(ar, ce_id);
|
||||
ath10k_ce_deinit_dest_ring(ar, ce_id);
|
||||
|
||||
ath10k_pci_sleep(ar);
|
||||
}
|
||||
|
||||
int ath10k_ce_alloc_pipe(struct ath10k *ar, int ce_id,
|
||||
const struct ce_attr *attr)
|
||||
{
|
||||
struct ath10k *ar = ce_state->ar;
|
||||
struct ath10k_pci *ar_pci = ath10k_pci_priv(ar);
|
||||
struct ath10k_ce_pipe *ce_state = &ar_pci->ce_states[ce_id];
|
||||
int ret;
|
||||
|
||||
if (attr->src_nentries) {
|
||||
ce_state->src_ring = ath10k_ce_alloc_src_ring(ar, ce_id, attr);
|
||||
if (IS_ERR(ce_state->src_ring)) {
|
||||
ret = PTR_ERR(ce_state->src_ring);
|
||||
ath10k_err("failed to allocate copy engine source ring %d: %d\n",
|
||||
ce_id, ret);
|
||||
ce_state->src_ring = NULL;
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
|
||||
if (attr->dest_nentries) {
|
||||
ce_state->dest_ring = ath10k_ce_alloc_dest_ring(ar, ce_id,
|
||||
attr);
|
||||
if (IS_ERR(ce_state->dest_ring)) {
|
||||
ret = PTR_ERR(ce_state->dest_ring);
|
||||
ath10k_err("failed to allocate copy engine destination ring %d: %d\n",
|
||||
ce_id, ret);
|
||||
ce_state->dest_ring = NULL;
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void ath10k_ce_free_pipe(struct ath10k *ar, int ce_id)
|
||||
{
|
||||
struct ath10k_pci *ar_pci = ath10k_pci_priv(ar);
|
||||
struct ath10k_ce_pipe *ce_state = &ar_pci->ce_states[ce_id];
|
||||
|
||||
if (ce_state->src_ring) {
|
||||
kfree(ce_state->src_ring->shadow_base_unaligned);
|
||||
pci_free_consistent(ar_pci->pdev,
|
||||
(ce_state->src_ring->nentries *
|
||||
sizeof(struct ce_desc) +
|
||||
CE_DESC_RING_ALIGN),
|
||||
ce_state->src_ring->base_addr_owner_space,
|
||||
ce_state->src_ring->base_addr_ce_space);
|
||||
dma_free_coherent(ar->dev,
|
||||
(ce_state->src_ring->nentries *
|
||||
sizeof(struct ce_desc) +
|
||||
CE_DESC_RING_ALIGN),
|
||||
ce_state->src_ring->base_addr_owner_space,
|
||||
ce_state->src_ring->base_addr_ce_space);
|
||||
kfree(ce_state->src_ring);
|
||||
}
|
||||
|
||||
if (ce_state->dest_ring) {
|
||||
pci_free_consistent(ar_pci->pdev,
|
||||
(ce_state->dest_ring->nentries *
|
||||
sizeof(struct ce_desc) +
|
||||
CE_DESC_RING_ALIGN),
|
||||
ce_state->dest_ring->base_addr_owner_space,
|
||||
ce_state->dest_ring->base_addr_ce_space);
|
||||
dma_free_coherent(ar->dev,
|
||||
(ce_state->dest_ring->nentries *
|
||||
sizeof(struct ce_desc) +
|
||||
CE_DESC_RING_ALIGN),
|
||||
ce_state->dest_ring->base_addr_owner_space,
|
||||
ce_state->dest_ring->base_addr_ce_space);
|
||||
kfree(ce_state->dest_ring);
|
||||
}
|
||||
|
||||
|
|
|
@ -104,7 +104,8 @@ struct ath10k_ce_ring {
|
|||
void *shadow_base_unaligned;
|
||||
struct ce_desc *shadow_base;
|
||||
|
||||
void **per_transfer_context;
|
||||
/* keep last */
|
||||
void *per_transfer_context[0];
|
||||
};
|
||||
|
||||
struct ath10k_ce_pipe {
|
||||
|
@ -210,10 +211,12 @@ int ath10k_ce_completed_send_next(struct ath10k_ce_pipe *ce_state,
|
|||
|
||||
/*==================CE Engine Initialization=======================*/
|
||||
|
||||
/* Initialize an instance of a CE */
|
||||
struct ath10k_ce_pipe *ath10k_ce_init(struct ath10k *ar,
|
||||
unsigned int ce_id,
|
||||
const struct ce_attr *attr);
|
||||
int ath10k_ce_init_pipe(struct ath10k *ar, unsigned int ce_id,
|
||||
const struct ce_attr *attr);
|
||||
void ath10k_ce_deinit_pipe(struct ath10k *ar, unsigned int ce_id);
|
||||
int ath10k_ce_alloc_pipe(struct ath10k *ar, int ce_id,
|
||||
const struct ce_attr *attr);
|
||||
void ath10k_ce_free_pipe(struct ath10k *ar, int ce_id);
|
||||
|
||||
/*==================CE Engine Shutdown=======================*/
|
||||
/*
|
||||
|
@ -236,8 +239,6 @@ int ath10k_ce_cancel_send_next(struct ath10k_ce_pipe *ce_state,
|
|||
unsigned int *nbytesp,
|
||||
unsigned int *transfer_idp);
|
||||
|
||||
void ath10k_ce_deinit(struct ath10k_ce_pipe *ce_state);
|
||||
|
||||
/*==================CE Interrupt Handlers====================*/
|
||||
void ath10k_ce_per_engine_service_any(struct ath10k *ar);
|
||||
void ath10k_ce_per_engine_service(struct ath10k *ar, unsigned int ce_id);
|
||||
|
|
|
@ -249,30 +249,40 @@ exit:
|
|||
|
||||
static int ath10k_download_and_run_otp(struct ath10k *ar)
|
||||
{
|
||||
u32 address = ar->hw_params.patch_load_addr;
|
||||
u32 exec_param;
|
||||
u32 result, address = ar->hw_params.patch_load_addr;
|
||||
int ret;
|
||||
|
||||
/* OTP is optional */
|
||||
|
||||
if (!ar->otp_data || !ar->otp_len)
|
||||
if (!ar->otp_data || !ar->otp_len) {
|
||||
ath10k_warn("Not running otp, calibration will be incorrect (otp-data %p otp_len %zd)!\n",
|
||||
ar->otp_data, ar->otp_len);
|
||||
return 0;
|
||||
}
|
||||
|
||||
ath10k_dbg(ATH10K_DBG_BOOT, "boot upload otp to 0x%x len %zd\n",
|
||||
address, ar->otp_len);
|
||||
|
||||
ret = ath10k_bmi_fast_download(ar, address, ar->otp_data, ar->otp_len);
|
||||
if (ret) {
|
||||
ath10k_err("could not write otp (%d)\n", ret);
|
||||
goto exit;
|
||||
return ret;
|
||||
}
|
||||
|
||||
exec_param = 0;
|
||||
ret = ath10k_bmi_execute(ar, address, &exec_param);
|
||||
ret = ath10k_bmi_execute(ar, address, 0, &result);
|
||||
if (ret) {
|
||||
ath10k_err("could not execute otp (%d)\n", ret);
|
||||
goto exit;
|
||||
return ret;
|
||||
}
|
||||
|
||||
exit:
|
||||
return ret;
|
||||
ath10k_dbg(ATH10K_DBG_BOOT, "boot otp execute result %d\n", result);
|
||||
|
||||
if (result != 0) {
|
||||
ath10k_err("otp calibration failed: %d", result);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int ath10k_download_fw(struct ath10k *ar)
|
||||
|
@ -389,8 +399,8 @@ static int ath10k_core_fetch_firmware_api_n(struct ath10k *ar, const char *name)
|
|||
/* first fetch the firmware file (firmware-*.bin) */
|
||||
ar->firmware = ath10k_fetch_fw_file(ar, ar->hw_params.fw.dir, name);
|
||||
if (IS_ERR(ar->firmware)) {
|
||||
ath10k_err("Could not fetch firmware file '%s': %ld\n",
|
||||
name, PTR_ERR(ar->firmware));
|
||||
ath10k_err("could not fetch firmware file '%s/%s': %ld\n",
|
||||
ar->hw_params.fw.dir, name, PTR_ERR(ar->firmware));
|
||||
return PTR_ERR(ar->firmware);
|
||||
}
|
||||
|
||||
|
@ -401,14 +411,14 @@ static int ath10k_core_fetch_firmware_api_n(struct ath10k *ar, const char *name)
|
|||
magic_len = strlen(ATH10K_FIRMWARE_MAGIC) + 1;
|
||||
|
||||
if (len < magic_len) {
|
||||
ath10k_err("firmware image too small to contain magic: %zu\n",
|
||||
len);
|
||||
ath10k_err("firmware file '%s/%s' too small to contain magic: %zu\n",
|
||||
ar->hw_params.fw.dir, name, len);
|
||||
ret = -EINVAL;
|
||||
goto err;
|
||||
}
|
||||
|
||||
if (memcmp(data, ATH10K_FIRMWARE_MAGIC, magic_len) != 0) {
|
||||
ath10k_err("Invalid firmware magic\n");
|
||||
ath10k_err("invalid firmware magic\n");
|
||||
ret = -EINVAL;
|
||||
goto err;
|
||||
}
|
||||
|
@ -430,7 +440,7 @@ static int ath10k_core_fetch_firmware_api_n(struct ath10k *ar, const char *name)
|
|||
data += sizeof(*hdr);
|
||||
|
||||
if (len < ie_len) {
|
||||
ath10k_err("Invalid length for FW IE %d (%zu < %zu)\n",
|
||||
ath10k_err("invalid length for FW IE %d (%zu < %zu)\n",
|
||||
ie_id, len, ie_len);
|
||||
ret = -EINVAL;
|
||||
goto err;
|
||||
|
@ -513,8 +523,8 @@ static int ath10k_core_fetch_firmware_api_n(struct ath10k *ar, const char *name)
|
|||
}
|
||||
|
||||
if (!ar->firmware_data || !ar->firmware_len) {
|
||||
ath10k_warn("No ATH10K_FW_IE_FW_IMAGE found from %s, skipping\n",
|
||||
name);
|
||||
ath10k_warn("No ATH10K_FW_IE_FW_IMAGE found from '%s/%s', skipping\n",
|
||||
ar->hw_params.fw.dir, name);
|
||||
ret = -ENOMEDIUM;
|
||||
goto err;
|
||||
}
|
||||
|
@ -531,7 +541,9 @@ static int ath10k_core_fetch_firmware_api_n(struct ath10k *ar, const char *name)
|
|||
ar->hw_params.fw.board);
|
||||
if (IS_ERR(ar->board)) {
|
||||
ret = PTR_ERR(ar->board);
|
||||
ath10k_err("could not fetch board data (%d)\n", ret);
|
||||
ath10k_err("could not fetch board data '%s/%s' (%d)\n",
|
||||
ar->hw_params.fw.dir, ar->hw_params.fw.board,
|
||||
ret);
|
||||
goto err;
|
||||
}
|
||||
|
||||
|
@ -549,19 +561,21 @@ static int ath10k_core_fetch_firmware_files(struct ath10k *ar)
|
|||
{
|
||||
int ret;
|
||||
|
||||
ar->fw_api = 2;
|
||||
ath10k_dbg(ATH10K_DBG_BOOT, "trying fw api %d\n", ar->fw_api);
|
||||
|
||||
ret = ath10k_core_fetch_firmware_api_n(ar, ATH10K_FW_API2_FILE);
|
||||
if (ret == 0) {
|
||||
ar->fw_api = 2;
|
||||
goto out;
|
||||
}
|
||||
if (ret == 0)
|
||||
goto success;
|
||||
|
||||
ar->fw_api = 1;
|
||||
ath10k_dbg(ATH10K_DBG_BOOT, "trying fw api %d\n", ar->fw_api);
|
||||
|
||||
ret = ath10k_core_fetch_firmware_api_1(ar);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
ar->fw_api = 1;
|
||||
|
||||
out:
|
||||
success:
|
||||
ath10k_dbg(ATH10K_DBG_BOOT, "using fw api %d\n", ar->fw_api);
|
||||
|
||||
return 0;
|
||||
|
@ -572,16 +586,22 @@ static int ath10k_init_download_firmware(struct ath10k *ar)
|
|||
int ret;
|
||||
|
||||
ret = ath10k_download_board_data(ar);
|
||||
if (ret)
|
||||
if (ret) {
|
||||
ath10k_err("failed to download board data: %d\n", ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
ret = ath10k_download_and_run_otp(ar);
|
||||
if (ret)
|
||||
if (ret) {
|
||||
ath10k_err("failed to run otp: %d\n", ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
ret = ath10k_download_fw(ar);
|
||||
if (ret)
|
||||
if (ret) {
|
||||
ath10k_err("failed to download firmware: %d\n", ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
@ -835,9 +855,12 @@ int ath10k_core_start(struct ath10k *ar)
|
|||
INIT_LIST_HEAD(&ar->arvifs);
|
||||
|
||||
if (!test_bit(ATH10K_FLAG_FIRST_BOOT_DONE, &ar->dev_flags))
|
||||
ath10k_info("%s (0x%x) fw %s api %d htt %d.%d\n",
|
||||
ar->hw_params.name, ar->target_version,
|
||||
ar->hw->wiphy->fw_version, ar->fw_api,
|
||||
ath10k_info("%s (0x%08x, 0x%08x) fw %s api %d htt %d.%d\n",
|
||||
ar->hw_params.name,
|
||||
ar->target_version,
|
||||
ar->chip_id,
|
||||
ar->hw->wiphy->fw_version,
|
||||
ar->fw_api,
|
||||
ar->htt.target_version_major,
|
||||
ar->htt.target_version_minor);
|
||||
|
||||
|
|
|
@ -119,6 +119,7 @@ struct ath10k_peer_stat {
|
|||
u8 peer_macaddr[ETH_ALEN];
|
||||
u32 peer_rssi;
|
||||
u32 peer_tx_rate;
|
||||
u32 peer_rx_rate; /* 10x only */
|
||||
};
|
||||
|
||||
struct ath10k_target_stats {
|
||||
|
@ -130,6 +131,12 @@ struct ath10k_target_stats {
|
|||
u32 cycle_count;
|
||||
u32 phy_err_count;
|
||||
u32 chan_tx_power;
|
||||
u32 ack_rx_bad;
|
||||
u32 rts_bad;
|
||||
u32 rts_good;
|
||||
u32 fcs_bad;
|
||||
u32 no_beacons;
|
||||
u32 mib_int_count;
|
||||
|
||||
/* PDEV TX stats */
|
||||
s32 comp_queued;
|
||||
|
@ -260,6 +267,8 @@ struct ath10k_vif {
|
|||
u8 fixed_rate;
|
||||
u8 fixed_nss;
|
||||
u8 force_sgi;
|
||||
bool use_cts_prot;
|
||||
int num_legacy_stations;
|
||||
};
|
||||
|
||||
struct ath10k_vif_iter {
|
||||
|
@ -419,13 +428,18 @@ struct ath10k {
|
|||
struct cfg80211_chan_def chandef;
|
||||
|
||||
int free_vdev_map;
|
||||
bool promisc;
|
||||
bool monitor;
|
||||
int monitor_vdev_id;
|
||||
bool monitor_enabled;
|
||||
bool monitor_present;
|
||||
bool monitor_started;
|
||||
unsigned int filter_flags;
|
||||
unsigned long dev_flags;
|
||||
u32 dfs_block_radar_events;
|
||||
|
||||
/* protected by conf_mutex */
|
||||
bool radar_enabled;
|
||||
int num_started_vdevs;
|
||||
|
||||
struct wmi_pdev_set_wmm_params_arg wmm_params;
|
||||
struct completion install_key_done;
|
||||
|
||||
|
|
|
@ -161,7 +161,7 @@ void ath10k_debug_read_target_stats(struct ath10k *ar,
|
|||
u8 *tmp = ev->data;
|
||||
struct ath10k_target_stats *stats;
|
||||
int num_pdev_stats, num_vdev_stats, num_peer_stats;
|
||||
struct wmi_pdev_stats *ps;
|
||||
struct wmi_pdev_stats_10x *ps;
|
||||
int i;
|
||||
|
||||
spin_lock_bh(&ar->data_lock);
|
||||
|
@ -173,7 +173,7 @@ void ath10k_debug_read_target_stats(struct ath10k *ar,
|
|||
num_peer_stats = __le32_to_cpu(ev->num_peer_stats); /* 0 or max peers */
|
||||
|
||||
if (num_pdev_stats) {
|
||||
ps = (struct wmi_pdev_stats *)tmp;
|
||||
ps = (struct wmi_pdev_stats_10x *)tmp;
|
||||
|
||||
stats->ch_noise_floor = __le32_to_cpu(ps->chan_nf);
|
||||
stats->tx_frame_count = __le32_to_cpu(ps->tx_frame_count);
|
||||
|
@ -228,7 +228,18 @@ void ath10k_debug_read_target_stats(struct ath10k *ar,
|
|||
stats->phy_err_drop = __le32_to_cpu(ps->wal.rx.phy_err_drop);
|
||||
stats->mpdu_errs = __le32_to_cpu(ps->wal.rx.mpdu_errs);
|
||||
|
||||
tmp += sizeof(struct wmi_pdev_stats);
|
||||
if (test_bit(ATH10K_FW_FEATURE_WMI_10X,
|
||||
ar->fw_features)) {
|
||||
stats->ack_rx_bad = __le32_to_cpu(ps->ack_rx_bad);
|
||||
stats->rts_bad = __le32_to_cpu(ps->rts_bad);
|
||||
stats->rts_good = __le32_to_cpu(ps->rts_good);
|
||||
stats->fcs_bad = __le32_to_cpu(ps->fcs_bad);
|
||||
stats->no_beacons = __le32_to_cpu(ps->no_beacons);
|
||||
stats->mib_int_count = __le32_to_cpu(ps->mib_int_count);
|
||||
tmp += sizeof(struct wmi_pdev_stats_10x);
|
||||
} else {
|
||||
tmp += sizeof(struct wmi_pdev_stats_old);
|
||||
}
|
||||
}
|
||||
|
||||
/* 0 or max vdevs */
|
||||
|
@ -243,22 +254,29 @@ void ath10k_debug_read_target_stats(struct ath10k *ar,
|
|||
}
|
||||
|
||||
if (num_peer_stats) {
|
||||
struct wmi_peer_stats *peer_stats;
|
||||
struct wmi_peer_stats_10x *peer_stats;
|
||||
struct ath10k_peer_stat *s;
|
||||
|
||||
stats->peers = num_peer_stats;
|
||||
|
||||
for (i = 0; i < num_peer_stats; i++) {
|
||||
peer_stats = (struct wmi_peer_stats *)tmp;
|
||||
peer_stats = (struct wmi_peer_stats_10x *)tmp;
|
||||
s = &stats->peer_stat[i];
|
||||
|
||||
WMI_MAC_ADDR_TO_CHAR_ARRAY(&peer_stats->peer_macaddr,
|
||||
s->peer_macaddr);
|
||||
memcpy(s->peer_macaddr, &peer_stats->peer_macaddr.addr,
|
||||
ETH_ALEN);
|
||||
s->peer_rssi = __le32_to_cpu(peer_stats->peer_rssi);
|
||||
s->peer_tx_rate =
|
||||
__le32_to_cpu(peer_stats->peer_tx_rate);
|
||||
if (test_bit(ATH10K_FW_FEATURE_WMI_10X,
|
||||
ar->fw_features)) {
|
||||
s->peer_rx_rate =
|
||||
__le32_to_cpu(peer_stats->peer_rx_rate);
|
||||
tmp += sizeof(struct wmi_peer_stats_10x);
|
||||
|
||||
tmp += sizeof(struct wmi_peer_stats);
|
||||
} else {
|
||||
tmp += sizeof(struct wmi_peer_stats_old);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -272,7 +290,7 @@ static ssize_t ath10k_read_fw_stats(struct file *file, char __user *user_buf,
|
|||
struct ath10k *ar = file->private_data;
|
||||
struct ath10k_target_stats *fw_stats;
|
||||
char *buf = NULL;
|
||||
unsigned int len = 0, buf_len = 2500;
|
||||
unsigned int len = 0, buf_len = 8000;
|
||||
ssize_t ret_cnt = 0;
|
||||
long left;
|
||||
int i;
|
||||
|
@ -320,6 +338,16 @@ static ssize_t ath10k_read_fw_stats(struct file *file, char __user *user_buf,
|
|||
"Cycle count", fw_stats->cycle_count);
|
||||
len += scnprintf(buf + len, buf_len - len, "%30s %10u\n",
|
||||
"PHY error count", fw_stats->phy_err_count);
|
||||
len += scnprintf(buf + len, buf_len - len, "%30s %10u\n",
|
||||
"RTS bad count", fw_stats->rts_bad);
|
||||
len += scnprintf(buf + len, buf_len - len, "%30s %10u\n",
|
||||
"RTS good count", fw_stats->rts_good);
|
||||
len += scnprintf(buf + len, buf_len - len, "%30s %10u\n",
|
||||
"FCS bad count", fw_stats->fcs_bad);
|
||||
len += scnprintf(buf + len, buf_len - len, "%30s %10u\n",
|
||||
"No beacon count", fw_stats->no_beacons);
|
||||
len += scnprintf(buf + len, buf_len - len, "%30s %10u\n",
|
||||
"MIB int count", fw_stats->mib_int_count);
|
||||
|
||||
len += scnprintf(buf + len, buf_len - len, "\n");
|
||||
len += scnprintf(buf + len, buf_len - len, "%30s\n",
|
||||
|
@ -411,8 +439,8 @@ static ssize_t ath10k_read_fw_stats(struct file *file, char __user *user_buf,
|
|||
"MPDU errors (FCS, MIC, ENC)", fw_stats->mpdu_errs);
|
||||
|
||||
len += scnprintf(buf + len, buf_len - len, "\n");
|
||||
len += scnprintf(buf + len, buf_len - len, "%30s\n",
|
||||
"ath10k PEER stats");
|
||||
len += scnprintf(buf + len, buf_len - len, "%30s (%d)\n",
|
||||
"ath10k PEER stats", fw_stats->peers);
|
||||
len += scnprintf(buf + len, buf_len - len, "%30s\n\n",
|
||||
"=================");
|
||||
|
||||
|
@ -425,6 +453,9 @@ static ssize_t ath10k_read_fw_stats(struct file *file, char __user *user_buf,
|
|||
len += scnprintf(buf + len, buf_len - len, "%30s %u\n",
|
||||
"Peer TX rate",
|
||||
fw_stats->peer_stat[i].peer_tx_rate);
|
||||
len += scnprintf(buf + len, buf_len - len, "%30s %u\n",
|
||||
"Peer RX rate",
|
||||
fw_stats->peer_stat[i].peer_rx_rate);
|
||||
len += scnprintf(buf + len, buf_len - len, "\n");
|
||||
}
|
||||
spin_unlock_bh(&ar->data_lock);
|
||||
|
@ -451,27 +482,37 @@ static ssize_t ath10k_read_simulate_fw_crash(struct file *file,
|
|||
char __user *user_buf,
|
||||
size_t count, loff_t *ppos)
|
||||
{
|
||||
const char buf[] = "To simulate firmware crash write the keyword"
|
||||
" `crash` to this file.\nThis will force firmware"
|
||||
" to report a crash to the host system.\n";
|
||||
const char buf[] = "To simulate firmware crash write one of the"
|
||||
" keywords to this file:\n `soft` - this will send"
|
||||
" WMI_FORCE_FW_HANG_ASSERT to firmware if FW"
|
||||
" supports that command.\n `hard` - this will send"
|
||||
" to firmware command with illegal parameters"
|
||||
" causing firmware crash.\n";
|
||||
|
||||
return simple_read_from_buffer(user_buf, count, ppos, buf, strlen(buf));
|
||||
}
|
||||
|
||||
/* Simulate firmware crash:
|
||||
* 'soft': Call wmi command causing firmware hang. This firmware hang is
|
||||
* recoverable by warm firmware reset.
|
||||
* 'hard': Force firmware crash by setting any vdev parameter for not allowed
|
||||
* vdev id. This is hard firmware crash because it is recoverable only by cold
|
||||
* firmware reset.
|
||||
*/
|
||||
static ssize_t ath10k_write_simulate_fw_crash(struct file *file,
|
||||
const char __user *user_buf,
|
||||
size_t count, loff_t *ppos)
|
||||
{
|
||||
struct ath10k *ar = file->private_data;
|
||||
char buf[32] = {};
|
||||
char buf[32];
|
||||
int ret;
|
||||
|
||||
mutex_lock(&ar->conf_mutex);
|
||||
|
||||
simple_write_to_buffer(buf, sizeof(buf) - 1, ppos, user_buf, count);
|
||||
if (strcmp(buf, "crash") && strcmp(buf, "crash\n")) {
|
||||
ret = -EINVAL;
|
||||
goto exit;
|
||||
}
|
||||
|
||||
/* make sure that buf is null terminated */
|
||||
buf[sizeof(buf) - 1] = 0;
|
||||
|
||||
if (ar->state != ATH10K_STATE_ON &&
|
||||
ar->state != ATH10K_STATE_RESTARTED) {
|
||||
|
@ -479,14 +520,30 @@ static ssize_t ath10k_write_simulate_fw_crash(struct file *file,
|
|||
goto exit;
|
||||
}
|
||||
|
||||
ath10k_info("simulating firmware crash\n");
|
||||
/* drop the possible '\n' from the end */
|
||||
if (buf[count - 1] == '\n') {
|
||||
buf[count - 1] = 0;
|
||||
count--;
|
||||
}
|
||||
|
||||
ret = ath10k_wmi_force_fw_hang(ar, WMI_FORCE_FW_HANG_ASSERT, 0);
|
||||
if (ret)
|
||||
ath10k_warn("failed to force fw hang (%d)\n", ret);
|
||||
if (!strcmp(buf, "soft")) {
|
||||
ath10k_info("simulating soft firmware crash\n");
|
||||
ret = ath10k_wmi_force_fw_hang(ar, WMI_FORCE_FW_HANG_ASSERT, 0);
|
||||
} else if (!strcmp(buf, "hard")) {
|
||||
ath10k_info("simulating hard firmware crash\n");
|
||||
ret = ath10k_wmi_vdev_set_param(ar, TARGET_NUM_VDEVS + 1,
|
||||
ar->wmi.vdev_param->rts_threshold, 0);
|
||||
} else {
|
||||
ret = -EINVAL;
|
||||
goto exit;
|
||||
}
|
||||
|
||||
if (ret == 0)
|
||||
ret = count;
|
||||
if (ret) {
|
||||
ath10k_warn("failed to simulate firmware crash: %d\n", ret);
|
||||
goto exit;
|
||||
}
|
||||
|
||||
ret = count;
|
||||
|
||||
exit:
|
||||
mutex_unlock(&ar->conf_mutex);
|
||||
|
|
|
@ -157,6 +157,9 @@ int ath10k_htc_send(struct ath10k_htc *htc,
|
|||
goto err_pull;
|
||||
}
|
||||
ep->tx_credits -= credits;
|
||||
ath10k_dbg(ATH10K_DBG_HTC,
|
||||
"htc ep %d consumed %d credits (total %d)\n",
|
||||
eid, credits, ep->tx_credits);
|
||||
spin_unlock_bh(&htc->tx_lock);
|
||||
}
|
||||
|
||||
|
@ -185,6 +188,9 @@ err_credits:
|
|||
if (ep->tx_credit_flow_enabled) {
|
||||
spin_lock_bh(&htc->tx_lock);
|
||||
ep->tx_credits += credits;
|
||||
ath10k_dbg(ATH10K_DBG_HTC,
|
||||
"htc ep %d reverted %d credits back (total %d)\n",
|
||||
eid, credits, ep->tx_credits);
|
||||
spin_unlock_bh(&htc->tx_lock);
|
||||
|
||||
if (ep->ep_ops.ep_tx_credits)
|
||||
|
@ -234,12 +240,12 @@ ath10k_htc_process_credit_report(struct ath10k_htc *htc,
|
|||
if (report->eid >= ATH10K_HTC_EP_COUNT)
|
||||
break;
|
||||
|
||||
ath10k_dbg(ATH10K_DBG_HTC, "ep %d got %d credits\n",
|
||||
report->eid, report->credits);
|
||||
|
||||
ep = &htc->endpoint[report->eid];
|
||||
ep->tx_credits += report->credits;
|
||||
|
||||
ath10k_dbg(ATH10K_DBG_HTC, "htc ep %d got %d credits (total %d)\n",
|
||||
report->eid, report->credits, ep->tx_credits);
|
||||
|
||||
if (ep->ep_ops.ep_tx_credits) {
|
||||
spin_unlock_bh(&htc->tx_lock);
|
||||
ep->ep_ops.ep_tx_credits(htc->ar);
|
||||
|
|
|
@ -21,6 +21,7 @@
|
|||
#include <linux/bug.h>
|
||||
#include <linux/interrupt.h>
|
||||
#include <linux/dmapool.h>
|
||||
#include <net/mac80211.h>
|
||||
|
||||
#include "htc.h"
|
||||
#include "rx_desc.h"
|
||||
|
@ -1172,23 +1173,6 @@ struct htt_peer_unmap_event {
|
|||
u16 peer_id;
|
||||
};
|
||||
|
||||
struct htt_rx_info {
|
||||
struct sk_buff *skb;
|
||||
enum htt_rx_mpdu_status status;
|
||||
enum htt_rx_mpdu_encrypt_type encrypt_type;
|
||||
s8 signal;
|
||||
struct {
|
||||
u8 info0;
|
||||
u32 info1;
|
||||
u32 info2;
|
||||
} rate;
|
||||
|
||||
u32 tsf;
|
||||
bool fcs_err;
|
||||
bool amsdu_more;
|
||||
bool mic_err;
|
||||
};
|
||||
|
||||
struct ath10k_htt_txbuf {
|
||||
struct htt_data_tx_desc_frag frags[2];
|
||||
struct ath10k_htc_hdr htc_hdr;
|
||||
|
@ -1289,6 +1273,9 @@ struct ath10k_htt {
|
|||
struct tasklet_struct txrx_compl_task;
|
||||
struct sk_buff_head tx_compl_q;
|
||||
struct sk_buff_head rx_compl_q;
|
||||
|
||||
/* rx_status template */
|
||||
struct ieee80211_rx_status rx_status;
|
||||
};
|
||||
|
||||
#define RX_HTT_HDR_STATUS_LEN 64
|
||||
|
|
|
@ -297,6 +297,7 @@ static void ath10k_htt_rx_free_msdu_chain(struct sk_buff *skb)
|
|||
}
|
||||
}
|
||||
|
||||
/* return: < 0 fatal error, 0 - non chained msdu, 1 chained msdu */
|
||||
static int ath10k_htt_rx_amsdu_pop(struct ath10k_htt *htt,
|
||||
u8 **fw_desc, int *fw_desc_len,
|
||||
struct sk_buff **head_msdu,
|
||||
|
@ -310,7 +311,7 @@ static int ath10k_htt_rx_amsdu_pop(struct ath10k_htt *htt,
|
|||
|
||||
if (htt->rx_confused) {
|
||||
ath10k_warn("htt is confused. refusing rx\n");
|
||||
return 0;
|
||||
return -1;
|
||||
}
|
||||
|
||||
msdu = *head_msdu = ath10k_htt_rx_netbuf_pop(htt);
|
||||
|
@ -442,6 +443,9 @@ static int ath10k_htt_rx_amsdu_pop(struct ath10k_htt *htt,
|
|||
}
|
||||
*tail_msdu = msdu;
|
||||
|
||||
if (*head_msdu == NULL)
|
||||
msdu_chaining = -1;
|
||||
|
||||
/*
|
||||
* Don't refill the ring yet.
|
||||
*
|
||||
|
@ -636,6 +640,190 @@ struct amsdu_subframe_hdr {
|
|||
__be16 len;
|
||||
} __packed;
|
||||
|
||||
static const u8 rx_legacy_rate_idx[] = {
|
||||
3, /* 0x00 - 11Mbps */
|
||||
2, /* 0x01 - 5.5Mbps */
|
||||
1, /* 0x02 - 2Mbps */
|
||||
0, /* 0x03 - 1Mbps */
|
||||
3, /* 0x04 - 11Mbps */
|
||||
2, /* 0x05 - 5.5Mbps */
|
||||
1, /* 0x06 - 2Mbps */
|
||||
0, /* 0x07 - 1Mbps */
|
||||
10, /* 0x08 - 48Mbps */
|
||||
8, /* 0x09 - 24Mbps */
|
||||
6, /* 0x0A - 12Mbps */
|
||||
4, /* 0x0B - 6Mbps */
|
||||
11, /* 0x0C - 54Mbps */
|
||||
9, /* 0x0D - 36Mbps */
|
||||
7, /* 0x0E - 18Mbps */
|
||||
5, /* 0x0F - 9Mbps */
|
||||
};
|
||||
|
||||
static void ath10k_htt_rx_h_rates(struct ath10k *ar,
|
||||
enum ieee80211_band band,
|
||||
u8 info0, u32 info1, u32 info2,
|
||||
struct ieee80211_rx_status *status)
|
||||
{
|
||||
u8 cck, rate, rate_idx, bw, sgi, mcs, nss;
|
||||
u8 preamble = 0;
|
||||
|
||||
/* Check if valid fields */
|
||||
if (!(info0 & HTT_RX_INDICATION_INFO0_START_VALID))
|
||||
return;
|
||||
|
||||
preamble = MS(info1, HTT_RX_INDICATION_INFO1_PREAMBLE_TYPE);
|
||||
|
||||
switch (preamble) {
|
||||
case HTT_RX_LEGACY:
|
||||
cck = info0 & HTT_RX_INDICATION_INFO0_LEGACY_RATE_CCK;
|
||||
rate = MS(info0, HTT_RX_INDICATION_INFO0_LEGACY_RATE);
|
||||
rate_idx = 0;
|
||||
|
||||
if (rate < 0x08 || rate > 0x0F)
|
||||
break;
|
||||
|
||||
switch (band) {
|
||||
case IEEE80211_BAND_2GHZ:
|
||||
if (cck)
|
||||
rate &= ~BIT(3);
|
||||
rate_idx = rx_legacy_rate_idx[rate];
|
||||
break;
|
||||
case IEEE80211_BAND_5GHZ:
|
||||
rate_idx = rx_legacy_rate_idx[rate];
|
||||
/* We are using same rate table registering
|
||||
HW - ath10k_rates[]. In case of 5GHz skip
|
||||
CCK rates, so -4 here */
|
||||
rate_idx -= 4;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
status->rate_idx = rate_idx;
|
||||
break;
|
||||
case HTT_RX_HT:
|
||||
case HTT_RX_HT_WITH_TXBF:
|
||||
/* HT-SIG - Table 20-11 in info1 and info2 */
|
||||
mcs = info1 & 0x1F;
|
||||
nss = mcs >> 3;
|
||||
bw = (info1 >> 7) & 1;
|
||||
sgi = (info2 >> 7) & 1;
|
||||
|
||||
status->rate_idx = mcs;
|
||||
status->flag |= RX_FLAG_HT;
|
||||
if (sgi)
|
||||
status->flag |= RX_FLAG_SHORT_GI;
|
||||
if (bw)
|
||||
status->flag |= RX_FLAG_40MHZ;
|
||||
break;
|
||||
case HTT_RX_VHT:
|
||||
case HTT_RX_VHT_WITH_TXBF:
|
||||
/* VHT-SIG-A1 in info 1, VHT-SIG-A2 in info2
|
||||
TODO check this */
|
||||
mcs = (info2 >> 4) & 0x0F;
|
||||
nss = ((info1 >> 10) & 0x07) + 1;
|
||||
bw = info1 & 3;
|
||||
sgi = info2 & 1;
|
||||
|
||||
status->rate_idx = mcs;
|
||||
status->vht_nss = nss;
|
||||
|
||||
if (sgi)
|
||||
status->flag |= RX_FLAG_SHORT_GI;
|
||||
|
||||
switch (bw) {
|
||||
/* 20MHZ */
|
||||
case 0:
|
||||
break;
|
||||
/* 40MHZ */
|
||||
case 1:
|
||||
status->flag |= RX_FLAG_40MHZ;
|
||||
break;
|
||||
/* 80MHZ */
|
||||
case 2:
|
||||
status->vht_flag |= RX_VHT_FLAG_80MHZ;
|
||||
}
|
||||
|
||||
status->flag |= RX_FLAG_VHT;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static void ath10k_htt_rx_h_protected(struct ath10k_htt *htt,
|
||||
struct ieee80211_rx_status *rx_status,
|
||||
struct sk_buff *skb,
|
||||
enum htt_rx_mpdu_encrypt_type enctype)
|
||||
{
|
||||
struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data;
|
||||
|
||||
|
||||
if (enctype == HTT_RX_MPDU_ENCRYPT_NONE) {
|
||||
rx_status->flag &= ~(RX_FLAG_DECRYPTED |
|
||||
RX_FLAG_IV_STRIPPED |
|
||||
RX_FLAG_MMIC_STRIPPED);
|
||||
return;
|
||||
}
|
||||
|
||||
rx_status->flag |= RX_FLAG_DECRYPTED |
|
||||
RX_FLAG_IV_STRIPPED |
|
||||
RX_FLAG_MMIC_STRIPPED;
|
||||
hdr->frame_control = __cpu_to_le16(__le16_to_cpu(hdr->frame_control) &
|
||||
~IEEE80211_FCTL_PROTECTED);
|
||||
}
|
||||
|
||||
static bool ath10k_htt_rx_h_channel(struct ath10k *ar,
|
||||
struct ieee80211_rx_status *status)
|
||||
{
|
||||
struct ieee80211_channel *ch;
|
||||
|
||||
spin_lock_bh(&ar->data_lock);
|
||||
ch = ar->scan_channel;
|
||||
if (!ch)
|
||||
ch = ar->rx_channel;
|
||||
spin_unlock_bh(&ar->data_lock);
|
||||
|
||||
if (!ch)
|
||||
return false;
|
||||
|
||||
status->band = ch->band;
|
||||
status->freq = ch->center_freq;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static void ath10k_process_rx(struct ath10k *ar,
|
||||
struct ieee80211_rx_status *rx_status,
|
||||
struct sk_buff *skb)
|
||||
{
|
||||
struct ieee80211_rx_status *status;
|
||||
|
||||
status = IEEE80211_SKB_RXCB(skb);
|
||||
*status = *rx_status;
|
||||
|
||||
ath10k_dbg(ATH10K_DBG_DATA,
|
||||
"rx skb %p len %u %s%s%s%s%s %srate_idx %u vht_nss %u freq %u band %u flag 0x%x fcs-err %imic-err %i\n",
|
||||
skb,
|
||||
skb->len,
|
||||
status->flag == 0 ? "legacy" : "",
|
||||
status->flag & RX_FLAG_HT ? "ht" : "",
|
||||
status->flag & RX_FLAG_VHT ? "vht" : "",
|
||||
status->flag & RX_FLAG_40MHZ ? "40" : "",
|
||||
status->vht_flag & RX_VHT_FLAG_80MHZ ? "80" : "",
|
||||
status->flag & RX_FLAG_SHORT_GI ? "sgi " : "",
|
||||
status->rate_idx,
|
||||
status->vht_nss,
|
||||
status->freq,
|
||||
status->band, status->flag,
|
||||
!!(status->flag & RX_FLAG_FAILED_FCS_CRC),
|
||||
!!(status->flag & RX_FLAG_MMIC_ERROR));
|
||||
ath10k_dbg_dump(ATH10K_DBG_HTT_DUMP, NULL, "rx skb: ",
|
||||
skb->data, skb->len);
|
||||
|
||||
ieee80211_rx(ar->hw, skb);
|
||||
}
|
||||
|
||||
static int ath10k_htt_rx_nwifi_hdrlen(struct ieee80211_hdr *hdr)
|
||||
{
|
||||
/* nwifi header is padded to 4 bytes. this fixes 4addr rx */
|
||||
|
@ -643,11 +831,12 @@ static int ath10k_htt_rx_nwifi_hdrlen(struct ieee80211_hdr *hdr)
|
|||
}
|
||||
|
||||
static void ath10k_htt_rx_amsdu(struct ath10k_htt *htt,
|
||||
struct htt_rx_info *info)
|
||||
struct ieee80211_rx_status *rx_status,
|
||||
struct sk_buff *skb_in)
|
||||
{
|
||||
struct htt_rx_desc *rxd;
|
||||
struct sk_buff *skb = skb_in;
|
||||
struct sk_buff *first;
|
||||
struct sk_buff *skb = info->skb;
|
||||
enum rx_msdu_decap_format fmt;
|
||||
enum htt_rx_mpdu_encrypt_type enctype;
|
||||
struct ieee80211_hdr *hdr;
|
||||
|
@ -728,24 +917,27 @@ static void ath10k_htt_rx_amsdu(struct ath10k_htt *htt,
|
|||
break;
|
||||
}
|
||||
|
||||
info->skb = skb;
|
||||
info->encrypt_type = enctype;
|
||||
skb_in = skb;
|
||||
ath10k_htt_rx_h_protected(htt, rx_status, skb_in, enctype);
|
||||
skb = skb->next;
|
||||
info->skb->next = NULL;
|
||||
skb_in->next = NULL;
|
||||
|
||||
if (skb)
|
||||
info->amsdu_more = true;
|
||||
rx_status->flag |= RX_FLAG_AMSDU_MORE;
|
||||
else
|
||||
rx_status->flag &= ~RX_FLAG_AMSDU_MORE;
|
||||
|
||||
ath10k_process_rx(htt->ar, info);
|
||||
ath10k_process_rx(htt->ar, rx_status, skb_in);
|
||||
}
|
||||
|
||||
/* FIXME: It might be nice to re-assemble the A-MSDU when there's a
|
||||
* monitor interface active for sniffing purposes. */
|
||||
}
|
||||
|
||||
static void ath10k_htt_rx_msdu(struct ath10k_htt *htt, struct htt_rx_info *info)
|
||||
static void ath10k_htt_rx_msdu(struct ath10k_htt *htt,
|
||||
struct ieee80211_rx_status *rx_status,
|
||||
struct sk_buff *skb)
|
||||
{
|
||||
struct sk_buff *skb = info->skb;
|
||||
struct htt_rx_desc *rxd;
|
||||
struct ieee80211_hdr *hdr;
|
||||
enum rx_msdu_decap_format fmt;
|
||||
|
@ -808,66 +1000,9 @@ static void ath10k_htt_rx_msdu(struct ath10k_htt *htt, struct htt_rx_info *info)
|
|||
break;
|
||||
}
|
||||
|
||||
info->skb = skb;
|
||||
info->encrypt_type = enctype;
|
||||
ath10k_htt_rx_h_protected(htt, rx_status, skb, enctype);
|
||||
|
||||
ath10k_process_rx(htt->ar, info);
|
||||
}
|
||||
|
||||
static bool ath10k_htt_rx_has_decrypt_err(struct sk_buff *skb)
|
||||
{
|
||||
struct htt_rx_desc *rxd;
|
||||
u32 flags;
|
||||
|
||||
rxd = (void *)skb->data - sizeof(*rxd);
|
||||
flags = __le32_to_cpu(rxd->attention.flags);
|
||||
|
||||
if (flags & RX_ATTENTION_FLAGS_DECRYPT_ERR)
|
||||
return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
static bool ath10k_htt_rx_has_fcs_err(struct sk_buff *skb)
|
||||
{
|
||||
struct htt_rx_desc *rxd;
|
||||
u32 flags;
|
||||
|
||||
rxd = (void *)skb->data - sizeof(*rxd);
|
||||
flags = __le32_to_cpu(rxd->attention.flags);
|
||||
|
||||
if (flags & RX_ATTENTION_FLAGS_FCS_ERR)
|
||||
return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
static bool ath10k_htt_rx_has_mic_err(struct sk_buff *skb)
|
||||
{
|
||||
struct htt_rx_desc *rxd;
|
||||
u32 flags;
|
||||
|
||||
rxd = (void *)skb->data - sizeof(*rxd);
|
||||
flags = __le32_to_cpu(rxd->attention.flags);
|
||||
|
||||
if (flags & RX_ATTENTION_FLAGS_TKIP_MIC_ERR)
|
||||
return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
static bool ath10k_htt_rx_is_mgmt(struct sk_buff *skb)
|
||||
{
|
||||
struct htt_rx_desc *rxd;
|
||||
u32 flags;
|
||||
|
||||
rxd = (void *)skb->data - sizeof(*rxd);
|
||||
flags = __le32_to_cpu(rxd->attention.flags);
|
||||
|
||||
if (flags & RX_ATTENTION_FLAGS_MGMT_TYPE)
|
||||
return true;
|
||||
|
||||
return false;
|
||||
ath10k_process_rx(htt->ar, rx_status, skb);
|
||||
}
|
||||
|
||||
static int ath10k_htt_rx_get_csum_state(struct sk_buff *skb)
|
||||
|
@ -952,21 +1087,73 @@ static int ath10k_unchain_msdu(struct sk_buff *msdu_head)
|
|||
return 0;
|
||||
}
|
||||
|
||||
static bool ath10k_htt_rx_amsdu_allowed(struct ath10k_htt *htt,
|
||||
struct sk_buff *head,
|
||||
enum htt_rx_mpdu_status status,
|
||||
bool channel_set,
|
||||
u32 attention)
|
||||
{
|
||||
if (head->len == 0) {
|
||||
ath10k_dbg(ATH10K_DBG_HTT,
|
||||
"htt rx dropping due to zero-len\n");
|
||||
return false;
|
||||
}
|
||||
|
||||
if (attention & RX_ATTENTION_FLAGS_DECRYPT_ERR) {
|
||||
ath10k_dbg(ATH10K_DBG_HTT,
|
||||
"htt rx dropping due to decrypt-err\n");
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!channel_set) {
|
||||
ath10k_warn("no channel configured; ignoring frame!\n");
|
||||
return false;
|
||||
}
|
||||
|
||||
/* Skip mgmt frames while we handle this in WMI */
|
||||
if (status == HTT_RX_IND_MPDU_STATUS_MGMT_CTRL ||
|
||||
attention & RX_ATTENTION_FLAGS_MGMT_TYPE) {
|
||||
ath10k_dbg(ATH10K_DBG_HTT, "htt rx mgmt ctrl\n");
|
||||
return false;
|
||||
}
|
||||
|
||||
if (status != HTT_RX_IND_MPDU_STATUS_OK &&
|
||||
status != HTT_RX_IND_MPDU_STATUS_TKIP_MIC_ERR &&
|
||||
status != HTT_RX_IND_MPDU_STATUS_ERR_INV_PEER &&
|
||||
!htt->ar->monitor_started) {
|
||||
ath10k_dbg(ATH10K_DBG_HTT,
|
||||
"htt rx ignoring frame w/ status %d\n",
|
||||
status);
|
||||
return false;
|
||||
}
|
||||
|
||||
if (test_bit(ATH10K_CAC_RUNNING, &htt->ar->dev_flags)) {
|
||||
ath10k_dbg(ATH10K_DBG_HTT,
|
||||
"htt rx CAC running\n");
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static void ath10k_htt_rx_handler(struct ath10k_htt *htt,
|
||||
struct htt_rx_indication *rx)
|
||||
{
|
||||
struct htt_rx_info info;
|
||||
struct ieee80211_rx_status *rx_status = &htt->rx_status;
|
||||
struct htt_rx_indication_mpdu_range *mpdu_ranges;
|
||||
struct htt_rx_desc *rxd;
|
||||
enum htt_rx_mpdu_status status;
|
||||
struct ieee80211_hdr *hdr;
|
||||
int num_mpdu_ranges;
|
||||
u32 attention;
|
||||
int fw_desc_len;
|
||||
u8 *fw_desc;
|
||||
bool channel_set;
|
||||
int i, j;
|
||||
int ret;
|
||||
|
||||
lockdep_assert_held(&htt->rx_ring.lock);
|
||||
|
||||
memset(&info, 0, sizeof(info));
|
||||
|
||||
fw_desc_len = __le16_to_cpu(rx->prefix.fw_rx_desc_bytes);
|
||||
fw_desc = (u8 *)&rx->fw_desc;
|
||||
|
||||
|
@ -974,106 +1161,90 @@ static void ath10k_htt_rx_handler(struct ath10k_htt *htt,
|
|||
HTT_RX_INDICATION_INFO1_NUM_MPDU_RANGES);
|
||||
mpdu_ranges = htt_rx_ind_get_mpdu_ranges(rx);
|
||||
|
||||
/* Fill this once, while this is per-ppdu */
|
||||
if (rx->ppdu.info0 & HTT_RX_INDICATION_INFO0_START_VALID) {
|
||||
memset(rx_status, 0, sizeof(*rx_status));
|
||||
rx_status->signal = ATH10K_DEFAULT_NOISE_FLOOR +
|
||||
rx->ppdu.combined_rssi;
|
||||
}
|
||||
|
||||
if (rx->ppdu.info0 & HTT_RX_INDICATION_INFO0_END_VALID) {
|
||||
/* TSF available only in 32-bit */
|
||||
rx_status->mactime = __le32_to_cpu(rx->ppdu.tsf) & 0xffffffff;
|
||||
rx_status->flag |= RX_FLAG_MACTIME_END;
|
||||
}
|
||||
|
||||
channel_set = ath10k_htt_rx_h_channel(htt->ar, rx_status);
|
||||
|
||||
if (channel_set) {
|
||||
ath10k_htt_rx_h_rates(htt->ar, rx_status->band,
|
||||
rx->ppdu.info0,
|
||||
__le32_to_cpu(rx->ppdu.info1),
|
||||
__le32_to_cpu(rx->ppdu.info2),
|
||||
rx_status);
|
||||
}
|
||||
|
||||
ath10k_dbg_dump(ATH10K_DBG_HTT_DUMP, NULL, "htt rx ind: ",
|
||||
rx, sizeof(*rx) +
|
||||
(sizeof(struct htt_rx_indication_mpdu_range) *
|
||||
num_mpdu_ranges));
|
||||
|
||||
for (i = 0; i < num_mpdu_ranges; i++) {
|
||||
info.status = mpdu_ranges[i].mpdu_range_status;
|
||||
status = mpdu_ranges[i].mpdu_range_status;
|
||||
|
||||
for (j = 0; j < mpdu_ranges[i].mpdu_count; j++) {
|
||||
struct sk_buff *msdu_head, *msdu_tail;
|
||||
enum htt_rx_mpdu_status status;
|
||||
int msdu_chaining;
|
||||
|
||||
msdu_head = NULL;
|
||||
msdu_tail = NULL;
|
||||
msdu_chaining = ath10k_htt_rx_amsdu_pop(htt,
|
||||
&fw_desc,
|
||||
&fw_desc_len,
|
||||
&msdu_head,
|
||||
&msdu_tail);
|
||||
ret = ath10k_htt_rx_amsdu_pop(htt,
|
||||
&fw_desc,
|
||||
&fw_desc_len,
|
||||
&msdu_head,
|
||||
&msdu_tail);
|
||||
|
||||
if (!msdu_head) {
|
||||
ath10k_warn("htt rx no data!\n");
|
||||
continue;
|
||||
}
|
||||
|
||||
if (msdu_head->len == 0) {
|
||||
ath10k_dbg(ATH10K_DBG_HTT,
|
||||
"htt rx dropping due to zero-len\n");
|
||||
if (ret < 0) {
|
||||
ath10k_warn("failed to pop amsdu from htt rx ring %d\n",
|
||||
ret);
|
||||
ath10k_htt_rx_free_msdu_chain(msdu_head);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (ath10k_htt_rx_has_decrypt_err(msdu_head)) {
|
||||
ath10k_dbg(ATH10K_DBG_HTT,
|
||||
"htt rx dropping due to decrypt-err\n");
|
||||
rxd = container_of((void *)msdu_head->data,
|
||||
struct htt_rx_desc,
|
||||
msdu_payload);
|
||||
attention = __le32_to_cpu(rxd->attention.flags);
|
||||
|
||||
if (!ath10k_htt_rx_amsdu_allowed(htt, msdu_head,
|
||||
status,
|
||||
channel_set,
|
||||
attention)) {
|
||||
ath10k_htt_rx_free_msdu_chain(msdu_head);
|
||||
continue;
|
||||
}
|
||||
|
||||
status = info.status;
|
||||
|
||||
/* Skip mgmt frames while we handle this in WMI */
|
||||
if (status == HTT_RX_IND_MPDU_STATUS_MGMT_CTRL ||
|
||||
ath10k_htt_rx_is_mgmt(msdu_head)) {
|
||||
ath10k_dbg(ATH10K_DBG_HTT, "htt rx mgmt ctrl\n");
|
||||
if (ret > 0 &&
|
||||
ath10k_unchain_msdu(msdu_head) < 0) {
|
||||
ath10k_htt_rx_free_msdu_chain(msdu_head);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (status != HTT_RX_IND_MPDU_STATUS_OK &&
|
||||
status != HTT_RX_IND_MPDU_STATUS_TKIP_MIC_ERR &&
|
||||
status != HTT_RX_IND_MPDU_STATUS_ERR_INV_PEER &&
|
||||
!htt->ar->monitor_enabled) {
|
||||
ath10k_dbg(ATH10K_DBG_HTT,
|
||||
"htt rx ignoring frame w/ status %d\n",
|
||||
status);
|
||||
ath10k_htt_rx_free_msdu_chain(msdu_head);
|
||||
continue;
|
||||
}
|
||||
if (attention & RX_ATTENTION_FLAGS_FCS_ERR)
|
||||
rx_status->flag |= RX_FLAG_FAILED_FCS_CRC;
|
||||
else
|
||||
rx_status->flag &= ~RX_FLAG_FAILED_FCS_CRC;
|
||||
|
||||
if (test_bit(ATH10K_CAC_RUNNING, &htt->ar->dev_flags)) {
|
||||
ath10k_dbg(ATH10K_DBG_HTT,
|
||||
"htt rx CAC running\n");
|
||||
ath10k_htt_rx_free_msdu_chain(msdu_head);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (msdu_chaining &&
|
||||
(ath10k_unchain_msdu(msdu_head) < 0)) {
|
||||
ath10k_htt_rx_free_msdu_chain(msdu_head);
|
||||
continue;
|
||||
}
|
||||
|
||||
info.skb = msdu_head;
|
||||
info.fcs_err = ath10k_htt_rx_has_fcs_err(msdu_head);
|
||||
info.mic_err = ath10k_htt_rx_has_mic_err(msdu_head);
|
||||
|
||||
if (info.fcs_err)
|
||||
ath10k_dbg(ATH10K_DBG_HTT,
|
||||
"htt rx has FCS err\n");
|
||||
|
||||
if (info.mic_err)
|
||||
ath10k_dbg(ATH10K_DBG_HTT,
|
||||
"htt rx has MIC err\n");
|
||||
|
||||
info.signal = ATH10K_DEFAULT_NOISE_FLOOR;
|
||||
info.signal += rx->ppdu.combined_rssi;
|
||||
|
||||
info.rate.info0 = rx->ppdu.info0;
|
||||
info.rate.info1 = __le32_to_cpu(rx->ppdu.info1);
|
||||
info.rate.info2 = __le32_to_cpu(rx->ppdu.info2);
|
||||
info.tsf = __le32_to_cpu(rx->ppdu.tsf);
|
||||
if (attention & RX_ATTENTION_FLAGS_TKIP_MIC_ERR)
|
||||
rx_status->flag |= RX_FLAG_MMIC_ERROR;
|
||||
else
|
||||
rx_status->flag &= ~RX_FLAG_MMIC_ERROR;
|
||||
|
||||
hdr = ath10k_htt_rx_skb_get_hdr(msdu_head);
|
||||
|
||||
if (ath10k_htt_rx_hdr_is_amsdu(hdr))
|
||||
ath10k_htt_rx_amsdu(htt, &info);
|
||||
ath10k_htt_rx_amsdu(htt, rx_status, msdu_head);
|
||||
else
|
||||
ath10k_htt_rx_msdu(htt, &info);
|
||||
ath10k_htt_rx_msdu(htt, rx_status, msdu_head);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1084,11 +1255,12 @@ static void ath10k_htt_rx_frag_handler(struct ath10k_htt *htt,
|
|||
struct htt_rx_fragment_indication *frag)
|
||||
{
|
||||
struct sk_buff *msdu_head, *msdu_tail;
|
||||
enum htt_rx_mpdu_encrypt_type enctype;
|
||||
struct htt_rx_desc *rxd;
|
||||
enum rx_msdu_decap_format fmt;
|
||||
struct htt_rx_info info = {};
|
||||
struct ieee80211_rx_status *rx_status = &htt->rx_status;
|
||||
struct ieee80211_hdr *hdr;
|
||||
int msdu_chaining;
|
||||
int ret;
|
||||
bool tkip_mic_err;
|
||||
bool decrypt_err;
|
||||
u8 *fw_desc;
|
||||
|
@ -1102,19 +1274,15 @@ static void ath10k_htt_rx_frag_handler(struct ath10k_htt *htt,
|
|||
msdu_tail = NULL;
|
||||
|
||||
spin_lock_bh(&htt->rx_ring.lock);
|
||||
msdu_chaining = ath10k_htt_rx_amsdu_pop(htt, &fw_desc, &fw_desc_len,
|
||||
&msdu_head, &msdu_tail);
|
||||
ret = ath10k_htt_rx_amsdu_pop(htt, &fw_desc, &fw_desc_len,
|
||||
&msdu_head, &msdu_tail);
|
||||
spin_unlock_bh(&htt->rx_ring.lock);
|
||||
|
||||
ath10k_dbg(ATH10K_DBG_HTT_DUMP, "htt rx frag ahead\n");
|
||||
|
||||
if (!msdu_head) {
|
||||
ath10k_warn("htt rx frag no data\n");
|
||||
return;
|
||||
}
|
||||
|
||||
if (msdu_chaining || msdu_head != msdu_tail) {
|
||||
ath10k_warn("aggregation with fragmentation?!\n");
|
||||
if (ret) {
|
||||
ath10k_warn("failed to pop amsdu from httr rx ring for fragmented rx %d\n",
|
||||
ret);
|
||||
ath10k_htt_rx_free_msdu_chain(msdu_head);
|
||||
return;
|
||||
}
|
||||
|
@ -1136,57 +1304,54 @@ static void ath10k_htt_rx_frag_handler(struct ath10k_htt *htt,
|
|||
goto end;
|
||||
}
|
||||
|
||||
info.skb = msdu_head;
|
||||
info.status = HTT_RX_IND_MPDU_STATUS_OK;
|
||||
info.encrypt_type = MS(__le32_to_cpu(rxd->mpdu_start.info0),
|
||||
RX_MPDU_START_INFO0_ENCRYPT_TYPE);
|
||||
info.skb->ip_summed = ath10k_htt_rx_get_csum_state(info.skb);
|
||||
enctype = MS(__le32_to_cpu(rxd->mpdu_start.info0),
|
||||
RX_MPDU_START_INFO0_ENCRYPT_TYPE);
|
||||
ath10k_htt_rx_h_protected(htt, rx_status, msdu_head, enctype);
|
||||
msdu_head->ip_summed = ath10k_htt_rx_get_csum_state(msdu_head);
|
||||
|
||||
if (tkip_mic_err) {
|
||||
if (tkip_mic_err)
|
||||
ath10k_warn("tkip mic error\n");
|
||||
info.status = HTT_RX_IND_MPDU_STATUS_TKIP_MIC_ERR;
|
||||
}
|
||||
|
||||
if (decrypt_err) {
|
||||
ath10k_warn("decryption err in fragmented rx\n");
|
||||
dev_kfree_skb_any(info.skb);
|
||||
dev_kfree_skb_any(msdu_head);
|
||||
goto end;
|
||||
}
|
||||
|
||||
if (info.encrypt_type != HTT_RX_MPDU_ENCRYPT_NONE) {
|
||||
if (enctype != HTT_RX_MPDU_ENCRYPT_NONE) {
|
||||
hdrlen = ieee80211_hdrlen(hdr->frame_control);
|
||||
paramlen = ath10k_htt_rx_crypto_param_len(info.encrypt_type);
|
||||
paramlen = ath10k_htt_rx_crypto_param_len(enctype);
|
||||
|
||||
/* It is more efficient to move the header than the payload */
|
||||
memmove((void *)info.skb->data + paramlen,
|
||||
(void *)info.skb->data,
|
||||
memmove((void *)msdu_head->data + paramlen,
|
||||
(void *)msdu_head->data,
|
||||
hdrlen);
|
||||
skb_pull(info.skb, paramlen);
|
||||
hdr = (struct ieee80211_hdr *)info.skb->data;
|
||||
skb_pull(msdu_head, paramlen);
|
||||
hdr = (struct ieee80211_hdr *)msdu_head->data;
|
||||
}
|
||||
|
||||
/* remove trailing FCS */
|
||||
trim = 4;
|
||||
|
||||
/* remove crypto trailer */
|
||||
trim += ath10k_htt_rx_crypto_tail_len(info.encrypt_type);
|
||||
trim += ath10k_htt_rx_crypto_tail_len(enctype);
|
||||
|
||||
/* last fragment of TKIP frags has MIC */
|
||||
if (!ieee80211_has_morefrags(hdr->frame_control) &&
|
||||
info.encrypt_type == HTT_RX_MPDU_ENCRYPT_TKIP_WPA)
|
||||
enctype == HTT_RX_MPDU_ENCRYPT_TKIP_WPA)
|
||||
trim += 8;
|
||||
|
||||
if (trim > info.skb->len) {
|
||||
if (trim > msdu_head->len) {
|
||||
ath10k_warn("htt rx fragment: trailer longer than the frame itself? drop\n");
|
||||
dev_kfree_skb_any(info.skb);
|
||||
dev_kfree_skb_any(msdu_head);
|
||||
goto end;
|
||||
}
|
||||
|
||||
skb_trim(info.skb, info.skb->len - trim);
|
||||
skb_trim(msdu_head, msdu_head->len - trim);
|
||||
|
||||
ath10k_dbg_dump(ATH10K_DBG_HTT_DUMP, NULL, "htt rx frag mpdu: ",
|
||||
info.skb->data, info.skb->len);
|
||||
ath10k_process_rx(htt->ar, &info);
|
||||
msdu_head->data, msdu_head->len);
|
||||
ath10k_process_rx(htt->ar, rx_status, msdu_head);
|
||||
|
||||
end:
|
||||
if (fw_desc_len > 0) {
|
||||
|
|
|
@ -28,6 +28,7 @@
|
|||
#define QCA988X_HW_2_0_CHIP_ID_REV 0x2
|
||||
#define QCA988X_HW_2_0_FW_DIR "ath10k/QCA988X/hw2.0"
|
||||
#define QCA988X_HW_2_0_FW_FILE "firmware.bin"
|
||||
#define QCA988X_HW_2_0_FW_2_FILE "firmware-2.bin"
|
||||
#define QCA988X_HW_2_0_OTP_FILE "otp.bin"
|
||||
#define QCA988X_HW_2_0_BOARD_DATA_FILE "board.bin"
|
||||
#define QCA988X_HW_2_0_PATCH_LOAD_ADDR 0x1234
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -39,15 +39,27 @@ enum ath10k_pci_irq_mode {
|
|||
ATH10K_PCI_IRQ_MSI = 2,
|
||||
};
|
||||
|
||||
static unsigned int ath10k_target_ps;
|
||||
static unsigned int ath10k_pci_irq_mode = ATH10K_PCI_IRQ_AUTO;
|
||||
enum ath10k_pci_reset_mode {
|
||||
ATH10K_PCI_RESET_AUTO = 0,
|
||||
ATH10K_PCI_RESET_WARM_ONLY = 1,
|
||||
};
|
||||
|
||||
module_param(ath10k_target_ps, uint, 0644);
|
||||
MODULE_PARM_DESC(ath10k_target_ps, "Enable ath10k Target (SoC) PS option");
|
||||
static unsigned int ath10k_pci_target_ps;
|
||||
static unsigned int ath10k_pci_irq_mode = ATH10K_PCI_IRQ_AUTO;
|
||||
static unsigned int ath10k_pci_reset_mode = ATH10K_PCI_RESET_AUTO;
|
||||
|
||||
module_param_named(target_ps, ath10k_pci_target_ps, uint, 0644);
|
||||
MODULE_PARM_DESC(target_ps, "Enable ath10k Target (SoC) PS option");
|
||||
|
||||
module_param_named(irq_mode, ath10k_pci_irq_mode, uint, 0644);
|
||||
MODULE_PARM_DESC(irq_mode, "0: auto, 1: legacy, 2: msi (default: 0)");
|
||||
|
||||
module_param_named(reset_mode, ath10k_pci_reset_mode, uint, 0644);
|
||||
MODULE_PARM_DESC(reset_mode, "0: auto, 1: warm only (default: 0)");
|
||||
|
||||
/* how long wait to wait for target to initialise, in ms */
|
||||
#define ATH10K_PCI_TARGET_WAIT 3000
|
||||
|
||||
#define QCA988X_2_0_DEVICE_ID (0x003c)
|
||||
|
||||
static DEFINE_PCI_DEVICE_TABLE(ath10k_pci_id_table) = {
|
||||
|
@ -346,9 +358,10 @@ static int ath10k_pci_diag_read_mem(struct ath10k *ar, u32 address, void *data,
|
|||
* 2) Buffer in DMA-able space
|
||||
*/
|
||||
orig_nbytes = nbytes;
|
||||
data_buf = (unsigned char *)pci_alloc_consistent(ar_pci->pdev,
|
||||
orig_nbytes,
|
||||
&ce_data_base);
|
||||
data_buf = (unsigned char *)dma_alloc_coherent(ar->dev,
|
||||
orig_nbytes,
|
||||
&ce_data_base,
|
||||
GFP_ATOMIC);
|
||||
|
||||
if (!data_buf) {
|
||||
ret = -ENOMEM;
|
||||
|
@ -442,12 +455,12 @@ done:
|
|||
__le32_to_cpu(((__le32 *)data_buf)[i]);
|
||||
}
|
||||
} else
|
||||
ath10k_dbg(ATH10K_DBG_PCI, "%s failure (0x%x)\n",
|
||||
__func__, address);
|
||||
ath10k_warn("failed to read diag value at 0x%x: %d\n",
|
||||
address, ret);
|
||||
|
||||
if (data_buf)
|
||||
pci_free_consistent(ar_pci->pdev, orig_nbytes,
|
||||
data_buf, ce_data_base);
|
||||
dma_free_coherent(ar->dev, orig_nbytes, data_buf,
|
||||
ce_data_base);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
@ -490,9 +503,10 @@ static int ath10k_pci_diag_write_mem(struct ath10k *ar, u32 address,
|
|||
* 2) Buffer in DMA-able space
|
||||
*/
|
||||
orig_nbytes = nbytes;
|
||||
data_buf = (unsigned char *)pci_alloc_consistent(ar_pci->pdev,
|
||||
orig_nbytes,
|
||||
&ce_data_base);
|
||||
data_buf = (unsigned char *)dma_alloc_coherent(ar->dev,
|
||||
orig_nbytes,
|
||||
&ce_data_base,
|
||||
GFP_ATOMIC);
|
||||
if (!data_buf) {
|
||||
ret = -ENOMEM;
|
||||
goto done;
|
||||
|
@ -588,13 +602,13 @@ static int ath10k_pci_diag_write_mem(struct ath10k *ar, u32 address,
|
|||
|
||||
done:
|
||||
if (data_buf) {
|
||||
pci_free_consistent(ar_pci->pdev, orig_nbytes, data_buf,
|
||||
ce_data_base);
|
||||
dma_free_coherent(ar->dev, orig_nbytes, data_buf,
|
||||
ce_data_base);
|
||||
}
|
||||
|
||||
if (ret != 0)
|
||||
ath10k_dbg(ATH10K_DBG_PCI, "%s failure (0x%x)\n", __func__,
|
||||
address);
|
||||
ath10k_warn("failed to write diag value at 0x%x: %d\n",
|
||||
address, ret);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
@ -803,6 +817,9 @@ unlock:
|
|||
static u16 ath10k_pci_hif_get_free_queue_number(struct ath10k *ar, u8 pipe)
|
||||
{
|
||||
struct ath10k_pci *ar_pci = ath10k_pci_priv(ar);
|
||||
|
||||
ath10k_dbg(ATH10K_DBG_PCI, "pci hif get free queue number\n");
|
||||
|
||||
return ath10k_ce_num_free_src_entries(ar_pci->pipe_info[pipe].ce_hdl);
|
||||
}
|
||||
|
||||
|
@ -854,6 +871,8 @@ static void ath10k_pci_hif_dump_area(struct ath10k *ar)
|
|||
static void ath10k_pci_hif_send_complete_check(struct ath10k *ar, u8 pipe,
|
||||
int force)
|
||||
{
|
||||
ath10k_dbg(ATH10K_DBG_PCI, "pci hif send complete check\n");
|
||||
|
||||
if (!force) {
|
||||
int resources;
|
||||
/*
|
||||
|
@ -880,7 +899,7 @@ static void ath10k_pci_hif_set_callbacks(struct ath10k *ar,
|
|||
{
|
||||
struct ath10k_pci *ar_pci = ath10k_pci_priv(ar);
|
||||
|
||||
ath10k_dbg(ATH10K_DBG_PCI, "%s\n", __func__);
|
||||
ath10k_dbg(ATH10K_DBG_PCI, "pci hif set callbacks\n");
|
||||
|
||||
memcpy(&ar_pci->msg_callbacks_current, callbacks,
|
||||
sizeof(ar_pci->msg_callbacks_current));
|
||||
|
@ -938,6 +957,8 @@ static int ath10k_pci_hif_map_service_to_pipe(struct ath10k *ar,
|
|||
{
|
||||
int ret = 0;
|
||||
|
||||
ath10k_dbg(ATH10K_DBG_PCI, "pci hif map service\n");
|
||||
|
||||
/* polling for received messages not supported */
|
||||
*dl_is_polled = 0;
|
||||
|
||||
|
@ -997,6 +1018,8 @@ static void ath10k_pci_hif_get_default_pipe(struct ath10k *ar,
|
|||
{
|
||||
int ul_is_polled, dl_is_polled;
|
||||
|
||||
ath10k_dbg(ATH10K_DBG_PCI, "pci hif get default pipe\n");
|
||||
|
||||
(void)ath10k_pci_hif_map_service_to_pipe(ar,
|
||||
ATH10K_HTC_SVC_ID_RSVD_CTRL,
|
||||
ul_pipe,
|
||||
|
@ -1098,6 +1121,8 @@ static int ath10k_pci_hif_start(struct ath10k *ar)
|
|||
struct ath10k_pci *ar_pci = ath10k_pci_priv(ar);
|
||||
int ret, ret_early;
|
||||
|
||||
ath10k_dbg(ATH10K_DBG_BOOT, "boot hif start\n");
|
||||
|
||||
ath10k_pci_free_early_irq(ar);
|
||||
ath10k_pci_kill_tasklet(ar);
|
||||
|
||||
|
@ -1233,18 +1258,10 @@ static void ath10k_pci_buffer_cleanup(struct ath10k *ar)
|
|||
|
||||
static void ath10k_pci_ce_deinit(struct ath10k *ar)
|
||||
{
|
||||
struct ath10k_pci *ar_pci = ath10k_pci_priv(ar);
|
||||
struct ath10k_pci_pipe *pipe_info;
|
||||
int pipe_num;
|
||||
int i;
|
||||
|
||||
for (pipe_num = 0; pipe_num < CE_COUNT; pipe_num++) {
|
||||
pipe_info = &ar_pci->pipe_info[pipe_num];
|
||||
if (pipe_info->ce_hdl) {
|
||||
ath10k_ce_deinit(pipe_info->ce_hdl);
|
||||
pipe_info->ce_hdl = NULL;
|
||||
pipe_info->buf_sz = 0;
|
||||
}
|
||||
}
|
||||
for (i = 0; i < CE_COUNT; i++)
|
||||
ath10k_ce_deinit_pipe(ar, i);
|
||||
}
|
||||
|
||||
static void ath10k_pci_hif_stop(struct ath10k *ar)
|
||||
|
@ -1252,7 +1269,7 @@ static void ath10k_pci_hif_stop(struct ath10k *ar)
|
|||
struct ath10k_pci *ar_pci = ath10k_pci_priv(ar);
|
||||
int ret;
|
||||
|
||||
ath10k_dbg(ATH10K_DBG_PCI, "%s\n", __func__);
|
||||
ath10k_dbg(ATH10K_DBG_BOOT, "boot hif stop\n");
|
||||
|
||||
ret = ath10k_ce_disable_interrupts(ar);
|
||||
if (ret)
|
||||
|
@ -1697,30 +1714,49 @@ static int ath10k_pci_init_config(struct ath10k *ar)
|
|||
return 0;
|
||||
}
|
||||
|
||||
static int ath10k_pci_alloc_ce(struct ath10k *ar)
|
||||
{
|
||||
int i, ret;
|
||||
|
||||
for (i = 0; i < CE_COUNT; i++) {
|
||||
ret = ath10k_ce_alloc_pipe(ar, i, &host_ce_config_wlan[i]);
|
||||
if (ret) {
|
||||
ath10k_err("failed to allocate copy engine pipe %d: %d\n",
|
||||
i, ret);
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void ath10k_pci_free_ce(struct ath10k *ar)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < CE_COUNT; i++)
|
||||
ath10k_ce_free_pipe(ar, i);
|
||||
}
|
||||
|
||||
static int ath10k_pci_ce_init(struct ath10k *ar)
|
||||
{
|
||||
struct ath10k_pci *ar_pci = ath10k_pci_priv(ar);
|
||||
struct ath10k_pci_pipe *pipe_info;
|
||||
const struct ce_attr *attr;
|
||||
int pipe_num;
|
||||
int pipe_num, ret;
|
||||
|
||||
for (pipe_num = 0; pipe_num < CE_COUNT; pipe_num++) {
|
||||
pipe_info = &ar_pci->pipe_info[pipe_num];
|
||||
pipe_info->ce_hdl = &ar_pci->ce_states[pipe_num];
|
||||
pipe_info->pipe_num = pipe_num;
|
||||
pipe_info->hif_ce_state = ar;
|
||||
attr = &host_ce_config_wlan[pipe_num];
|
||||
|
||||
pipe_info->ce_hdl = ath10k_ce_init(ar, pipe_num, attr);
|
||||
if (pipe_info->ce_hdl == NULL) {
|
||||
ath10k_err("failed to initialize CE for pipe: %d\n",
|
||||
pipe_num);
|
||||
|
||||
/* It is safe to call it here. It checks if ce_hdl is
|
||||
* valid for each pipe */
|
||||
ath10k_pci_ce_deinit(ar);
|
||||
return -1;
|
||||
ret = ath10k_ce_init_pipe(ar, pipe_num, attr);
|
||||
if (ret) {
|
||||
ath10k_err("failed to initialize copy engine pipe %d: %d\n",
|
||||
pipe_num, ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
if (pipe_num == CE_COUNT - 1) {
|
||||
|
@ -1741,16 +1777,15 @@ static int ath10k_pci_ce_init(struct ath10k *ar)
|
|||
static void ath10k_pci_fw_interrupt_handler(struct ath10k *ar)
|
||||
{
|
||||
struct ath10k_pci *ar_pci = ath10k_pci_priv(ar);
|
||||
u32 fw_indicator_address, fw_indicator;
|
||||
u32 fw_indicator;
|
||||
|
||||
ath10k_pci_wake(ar);
|
||||
|
||||
fw_indicator_address = ar_pci->fw_indicator_address;
|
||||
fw_indicator = ath10k_pci_read32(ar, fw_indicator_address);
|
||||
fw_indicator = ath10k_pci_read32(ar, FW_INDICATOR_ADDRESS);
|
||||
|
||||
if (fw_indicator & FW_IND_EVENT_PENDING) {
|
||||
/* ACK: clear Target-side pending event */
|
||||
ath10k_pci_write32(ar, fw_indicator_address,
|
||||
ath10k_pci_write32(ar, FW_INDICATOR_ADDRESS,
|
||||
fw_indicator & ~FW_IND_EVENT_PENDING);
|
||||
|
||||
if (ar_pci->started) {
|
||||
|
@ -1769,11 +1804,10 @@ static void ath10k_pci_fw_interrupt_handler(struct ath10k *ar)
|
|||
|
||||
static int ath10k_pci_warm_reset(struct ath10k *ar)
|
||||
{
|
||||
struct ath10k_pci *ar_pci = ath10k_pci_priv(ar);
|
||||
int ret = 0;
|
||||
u32 val;
|
||||
|
||||
ath10k_dbg(ATH10K_DBG_BOOT, "boot performing warm chip reset\n");
|
||||
ath10k_dbg(ATH10K_DBG_BOOT, "boot warm reset\n");
|
||||
|
||||
ret = ath10k_do_pci_wake(ar);
|
||||
if (ret) {
|
||||
|
@ -1801,7 +1835,7 @@ static int ath10k_pci_warm_reset(struct ath10k *ar)
|
|||
msleep(100);
|
||||
|
||||
/* clear fw indicator */
|
||||
ath10k_pci_write32(ar, ar_pci->fw_indicator_address, 0);
|
||||
ath10k_pci_write32(ar, FW_INDICATOR_ADDRESS, 0);
|
||||
|
||||
/* clear target LF timer interrupts */
|
||||
val = ath10k_pci_read32(ar, RTC_SOC_BASE_ADDRESS +
|
||||
|
@ -1934,7 +1968,9 @@ static int __ath10k_pci_hif_power_up(struct ath10k *ar, bool cold_reset)
|
|||
irq_mode = "legacy";
|
||||
|
||||
if (!test_bit(ATH10K_FLAG_FIRST_BOOT_DONE, &ar->dev_flags))
|
||||
ath10k_info("pci irq %s\n", irq_mode);
|
||||
ath10k_info("pci irq %s irq_mode %d reset_mode %d\n",
|
||||
irq_mode, ath10k_pci_irq_mode,
|
||||
ath10k_pci_reset_mode);
|
||||
|
||||
return 0;
|
||||
|
||||
|
@ -1956,6 +1992,8 @@ static int ath10k_pci_hif_power_up(struct ath10k *ar)
|
|||
{
|
||||
int ret;
|
||||
|
||||
ath10k_dbg(ATH10K_DBG_BOOT, "boot hif power up\n");
|
||||
|
||||
/*
|
||||
* Hardware CUS232 version 2 has some issues with cold reset and the
|
||||
* preferred (and safer) way to perform a device reset is through a
|
||||
|
@ -1966,9 +2004,14 @@ static int ath10k_pci_hif_power_up(struct ath10k *ar)
|
|||
*/
|
||||
ret = __ath10k_pci_hif_power_up(ar, false);
|
||||
if (ret) {
|
||||
ath10k_warn("failed to power up target using warm reset (%d), trying cold reset\n",
|
||||
ath10k_warn("failed to power up target using warm reset: %d\n",
|
||||
ret);
|
||||
|
||||
if (ath10k_pci_reset_mode == ATH10K_PCI_RESET_WARM_ONLY)
|
||||
return ret;
|
||||
|
||||
ath10k_warn("trying cold reset\n");
|
||||
|
||||
ret = __ath10k_pci_hif_power_up(ar, true);
|
||||
if (ret) {
|
||||
ath10k_err("failed to power up target using cold reset too (%d)\n",
|
||||
|
@ -1984,12 +2027,14 @@ static void ath10k_pci_hif_power_down(struct ath10k *ar)
|
|||
{
|
||||
struct ath10k_pci *ar_pci = ath10k_pci_priv(ar);
|
||||
|
||||
ath10k_dbg(ATH10K_DBG_BOOT, "boot hif power down\n");
|
||||
|
||||
ath10k_pci_free_early_irq(ar);
|
||||
ath10k_pci_kill_tasklet(ar);
|
||||
ath10k_pci_deinit_irq(ar);
|
||||
ath10k_pci_ce_deinit(ar);
|
||||
ath10k_pci_warm_reset(ar);
|
||||
|
||||
ath10k_pci_ce_deinit(ar);
|
||||
if (!test_bit(ATH10K_PCI_FEATURE_SOC_POWER_SAVE, ar_pci->features))
|
||||
ath10k_do_pci_sleep(ar);
|
||||
}
|
||||
|
@ -2137,7 +2182,6 @@ static irqreturn_t ath10k_pci_interrupt_handler(int irq, void *arg)
|
|||
static void ath10k_pci_early_irq_tasklet(unsigned long data)
|
||||
{
|
||||
struct ath10k *ar = (struct ath10k *)data;
|
||||
struct ath10k_pci *ar_pci = ath10k_pci_priv(ar);
|
||||
u32 fw_ind;
|
||||
int ret;
|
||||
|
||||
|
@ -2148,9 +2192,9 @@ static void ath10k_pci_early_irq_tasklet(unsigned long data)
|
|||
return;
|
||||
}
|
||||
|
||||
fw_ind = ath10k_pci_read32(ar, ar_pci->fw_indicator_address);
|
||||
fw_ind = ath10k_pci_read32(ar, FW_INDICATOR_ADDRESS);
|
||||
if (fw_ind & FW_IND_EVENT_PENDING) {
|
||||
ath10k_pci_write32(ar, ar_pci->fw_indicator_address,
|
||||
ath10k_pci_write32(ar, FW_INDICATOR_ADDRESS,
|
||||
fw_ind & ~FW_IND_EVENT_PENDING);
|
||||
|
||||
/* Some structures are unavailable during early boot or at
|
||||
|
@ -2385,33 +2429,50 @@ static int ath10k_pci_deinit_irq(struct ath10k *ar)
|
|||
static int ath10k_pci_wait_for_target_init(struct ath10k *ar)
|
||||
{
|
||||
struct ath10k_pci *ar_pci = ath10k_pci_priv(ar);
|
||||
int wait_limit = 300; /* 3 sec */
|
||||
unsigned long timeout;
|
||||
int ret;
|
||||
u32 val;
|
||||
|
||||
ath10k_dbg(ATH10K_DBG_BOOT, "boot waiting target to initialise\n");
|
||||
|
||||
ret = ath10k_pci_wake(ar);
|
||||
if (ret) {
|
||||
ath10k_err("failed to wake up target: %d\n", ret);
|
||||
ath10k_err("failed to wake up target for init: %d\n", ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
while (wait_limit-- &&
|
||||
!(ioread32(ar_pci->mem + FW_INDICATOR_ADDRESS) &
|
||||
FW_IND_INITIALIZED)) {
|
||||
timeout = jiffies + msecs_to_jiffies(ATH10K_PCI_TARGET_WAIT);
|
||||
|
||||
do {
|
||||
val = ath10k_pci_read32(ar, FW_INDICATOR_ADDRESS);
|
||||
|
||||
ath10k_dbg(ATH10K_DBG_BOOT, "boot target indicator %x\n", val);
|
||||
|
||||
/* target should never return this */
|
||||
if (val == 0xffffffff)
|
||||
continue;
|
||||
|
||||
if (val & FW_IND_INITIALIZED)
|
||||
break;
|
||||
|
||||
if (ar_pci->num_msi_intrs == 0)
|
||||
/* Fix potential race by repeating CORE_BASE writes */
|
||||
iowrite32(PCIE_INTR_FIRMWARE_MASK |
|
||||
PCIE_INTR_CE_MASK_ALL,
|
||||
ar_pci->mem + (SOC_CORE_BASE_ADDRESS |
|
||||
PCIE_INTR_ENABLE_ADDRESS));
|
||||
mdelay(10);
|
||||
}
|
||||
ath10k_pci_soc_write32(ar, PCIE_INTR_ENABLE_ADDRESS,
|
||||
PCIE_INTR_FIRMWARE_MASK |
|
||||
PCIE_INTR_CE_MASK_ALL);
|
||||
|
||||
if (wait_limit < 0) {
|
||||
ath10k_err("target stalled\n");
|
||||
ret = -EIO;
|
||||
mdelay(10);
|
||||
} while (time_before(jiffies, timeout));
|
||||
|
||||
if (val == 0xffffffff || !(val & FW_IND_INITIALIZED)) {
|
||||
ath10k_err("failed to receive initialized event from target: %08x\n",
|
||||
val);
|
||||
ret = -ETIMEDOUT;
|
||||
goto out;
|
||||
}
|
||||
|
||||
ath10k_dbg(ATH10K_DBG_BOOT, "boot target initialised\n");
|
||||
|
||||
out:
|
||||
ath10k_pci_sleep(ar);
|
||||
return ret;
|
||||
|
@ -2422,6 +2483,8 @@ static int ath10k_pci_cold_reset(struct ath10k *ar)
|
|||
int i, ret;
|
||||
u32 val;
|
||||
|
||||
ath10k_dbg(ATH10K_DBG_BOOT, "boot cold reset\n");
|
||||
|
||||
ret = ath10k_do_pci_wake(ar);
|
||||
if (ret) {
|
||||
ath10k_err("failed to wake up target: %d\n",
|
||||
|
@ -2453,6 +2516,9 @@ static int ath10k_pci_cold_reset(struct ath10k *ar)
|
|||
}
|
||||
|
||||
ath10k_do_pci_sleep(ar);
|
||||
|
||||
ath10k_dbg(ATH10K_DBG_BOOT, "boot cold reset complete\n");
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -2484,7 +2550,7 @@ static int ath10k_pci_probe(struct pci_dev *pdev,
|
|||
struct ath10k_pci *ar_pci;
|
||||
u32 lcr_val, chip_id;
|
||||
|
||||
ath10k_dbg(ATH10K_DBG_PCI, "%s\n", __func__);
|
||||
ath10k_dbg(ATH10K_DBG_PCI, "pci probe\n");
|
||||
|
||||
ar_pci = kzalloc(sizeof(*ar_pci), GFP_KERNEL);
|
||||
if (ar_pci == NULL)
|
||||
|
@ -2503,7 +2569,7 @@ static int ath10k_pci_probe(struct pci_dev *pdev,
|
|||
goto err_ar_pci;
|
||||
}
|
||||
|
||||
if (ath10k_target_ps)
|
||||
if (ath10k_pci_target_ps)
|
||||
set_bit(ATH10K_PCI_FEATURE_SOC_POWER_SAVE, ar_pci->features);
|
||||
|
||||
ath10k_pci_dump_features(ar_pci);
|
||||
|
@ -2516,7 +2582,6 @@ static int ath10k_pci_probe(struct pci_dev *pdev,
|
|||
}
|
||||
|
||||
ar_pci->ar = ar;
|
||||
ar_pci->fw_indicator_address = FW_INDICATOR_ADDRESS;
|
||||
atomic_set(&ar_pci->keep_awake_count, 0);
|
||||
|
||||
pci_set_drvdata(pdev, ar);
|
||||
|
@ -2594,16 +2659,24 @@ static int ath10k_pci_probe(struct pci_dev *pdev,
|
|||
|
||||
ath10k_do_pci_sleep(ar);
|
||||
|
||||
ret = ath10k_pci_alloc_ce(ar);
|
||||
if (ret) {
|
||||
ath10k_err("failed to allocate copy engine pipes: %d\n", ret);
|
||||
goto err_iomap;
|
||||
}
|
||||
|
||||
ath10k_dbg(ATH10K_DBG_BOOT, "boot pci_mem 0x%p\n", ar_pci->mem);
|
||||
|
||||
ret = ath10k_core_register(ar, chip_id);
|
||||
if (ret) {
|
||||
ath10k_err("failed to register driver core: %d\n", ret);
|
||||
goto err_iomap;
|
||||
goto err_free_ce;
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
||||
err_free_ce:
|
||||
ath10k_pci_free_ce(ar);
|
||||
err_iomap:
|
||||
pci_iounmap(pdev, mem);
|
||||
err_master:
|
||||
|
@ -2626,7 +2699,7 @@ static void ath10k_pci_remove(struct pci_dev *pdev)
|
|||
struct ath10k *ar = pci_get_drvdata(pdev);
|
||||
struct ath10k_pci *ar_pci;
|
||||
|
||||
ath10k_dbg(ATH10K_DBG_PCI, "%s\n", __func__);
|
||||
ath10k_dbg(ATH10K_DBG_PCI, "pci remove\n");
|
||||
|
||||
if (!ar)
|
||||
return;
|
||||
|
@ -2639,6 +2712,7 @@ static void ath10k_pci_remove(struct pci_dev *pdev)
|
|||
tasklet_kill(&ar_pci->msi_fw_err);
|
||||
|
||||
ath10k_core_unregister(ar);
|
||||
ath10k_pci_free_ce(ar);
|
||||
|
||||
pci_iounmap(pdev, ar_pci->mem);
|
||||
pci_release_region(pdev, BAR_NUM);
|
||||
|
@ -2680,6 +2754,5 @@ module_exit(ath10k_pci_exit);
|
|||
MODULE_AUTHOR("Qualcomm Atheros");
|
||||
MODULE_DESCRIPTION("Driver support for Atheros QCA988X PCIe devices");
|
||||
MODULE_LICENSE("Dual BSD/GPL");
|
||||
MODULE_FIRMWARE(QCA988X_HW_2_0_FW_DIR "/" QCA988X_HW_2_0_FW_FILE);
|
||||
MODULE_FIRMWARE(QCA988X_HW_2_0_FW_DIR "/" QCA988X_HW_2_0_OTP_FILE);
|
||||
MODULE_FIRMWARE(QCA988X_HW_2_0_FW_DIR "/" QCA988X_HW_2_0_FW_2_FILE);
|
||||
MODULE_FIRMWARE(QCA988X_HW_2_0_FW_DIR "/" QCA988X_HW_2_0_BOARD_DATA_FILE);
|
||||
|
|
|
@ -189,9 +189,6 @@ struct ath10k_pci {
|
|||
|
||||
struct ath10k_hif_cb msg_callbacks_current;
|
||||
|
||||
/* Target address used to signal a pending firmware event */
|
||||
u32 fw_indicator_address;
|
||||
|
||||
/* Copy Engine used for Diagnostic Accesses */
|
||||
struct ath10k_ce_pipe *ce_diag;
|
||||
|
||||
|
|
|
@ -100,189 +100,6 @@ exit:
|
|||
wake_up(&htt->empty_tx_wq);
|
||||
}
|
||||
|
||||
static const u8 rx_legacy_rate_idx[] = {
|
||||
3, /* 0x00 - 11Mbps */
|
||||
2, /* 0x01 - 5.5Mbps */
|
||||
1, /* 0x02 - 2Mbps */
|
||||
0, /* 0x03 - 1Mbps */
|
||||
3, /* 0x04 - 11Mbps */
|
||||
2, /* 0x05 - 5.5Mbps */
|
||||
1, /* 0x06 - 2Mbps */
|
||||
0, /* 0x07 - 1Mbps */
|
||||
10, /* 0x08 - 48Mbps */
|
||||
8, /* 0x09 - 24Mbps */
|
||||
6, /* 0x0A - 12Mbps */
|
||||
4, /* 0x0B - 6Mbps */
|
||||
11, /* 0x0C - 54Mbps */
|
||||
9, /* 0x0D - 36Mbps */
|
||||
7, /* 0x0E - 18Mbps */
|
||||
5, /* 0x0F - 9Mbps */
|
||||
};
|
||||
|
||||
static void process_rx_rates(struct ath10k *ar, struct htt_rx_info *info,
|
||||
enum ieee80211_band band,
|
||||
struct ieee80211_rx_status *status)
|
||||
{
|
||||
u8 cck, rate, rate_idx, bw, sgi, mcs, nss;
|
||||
u8 info0 = info->rate.info0;
|
||||
u32 info1 = info->rate.info1;
|
||||
u32 info2 = info->rate.info2;
|
||||
u8 preamble = 0;
|
||||
|
||||
/* Check if valid fields */
|
||||
if (!(info0 & HTT_RX_INDICATION_INFO0_START_VALID))
|
||||
return;
|
||||
|
||||
preamble = MS(info1, HTT_RX_INDICATION_INFO1_PREAMBLE_TYPE);
|
||||
|
||||
switch (preamble) {
|
||||
case HTT_RX_LEGACY:
|
||||
cck = info0 & HTT_RX_INDICATION_INFO0_LEGACY_RATE_CCK;
|
||||
rate = MS(info0, HTT_RX_INDICATION_INFO0_LEGACY_RATE);
|
||||
rate_idx = 0;
|
||||
|
||||
if (rate < 0x08 || rate > 0x0F)
|
||||
break;
|
||||
|
||||
switch (band) {
|
||||
case IEEE80211_BAND_2GHZ:
|
||||
if (cck)
|
||||
rate &= ~BIT(3);
|
||||
rate_idx = rx_legacy_rate_idx[rate];
|
||||
break;
|
||||
case IEEE80211_BAND_5GHZ:
|
||||
rate_idx = rx_legacy_rate_idx[rate];
|
||||
/* We are using same rate table registering
|
||||
HW - ath10k_rates[]. In case of 5GHz skip
|
||||
CCK rates, so -4 here */
|
||||
rate_idx -= 4;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
status->rate_idx = rate_idx;
|
||||
break;
|
||||
case HTT_RX_HT:
|
||||
case HTT_RX_HT_WITH_TXBF:
|
||||
/* HT-SIG - Table 20-11 in info1 and info2 */
|
||||
mcs = info1 & 0x1F;
|
||||
nss = mcs >> 3;
|
||||
bw = (info1 >> 7) & 1;
|
||||
sgi = (info2 >> 7) & 1;
|
||||
|
||||
status->rate_idx = mcs;
|
||||
status->flag |= RX_FLAG_HT;
|
||||
if (sgi)
|
||||
status->flag |= RX_FLAG_SHORT_GI;
|
||||
if (bw)
|
||||
status->flag |= RX_FLAG_40MHZ;
|
||||
break;
|
||||
case HTT_RX_VHT:
|
||||
case HTT_RX_VHT_WITH_TXBF:
|
||||
/* VHT-SIG-A1 in info 1, VHT-SIG-A2 in info2
|
||||
TODO check this */
|
||||
mcs = (info2 >> 4) & 0x0F;
|
||||
nss = ((info1 >> 10) & 0x07) + 1;
|
||||
bw = info1 & 3;
|
||||
sgi = info2 & 1;
|
||||
|
||||
status->rate_idx = mcs;
|
||||
status->vht_nss = nss;
|
||||
|
||||
if (sgi)
|
||||
status->flag |= RX_FLAG_SHORT_GI;
|
||||
|
||||
switch (bw) {
|
||||
/* 20MHZ */
|
||||
case 0:
|
||||
break;
|
||||
/* 40MHZ */
|
||||
case 1:
|
||||
status->flag |= RX_FLAG_40MHZ;
|
||||
break;
|
||||
/* 80MHZ */
|
||||
case 2:
|
||||
status->vht_flag |= RX_VHT_FLAG_80MHZ;
|
||||
}
|
||||
|
||||
status->flag |= RX_FLAG_VHT;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void ath10k_process_rx(struct ath10k *ar, struct htt_rx_info *info)
|
||||
{
|
||||
struct ieee80211_rx_status *status;
|
||||
struct ieee80211_channel *ch;
|
||||
struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)info->skb->data;
|
||||
|
||||
status = IEEE80211_SKB_RXCB(info->skb);
|
||||
memset(status, 0, sizeof(*status));
|
||||
|
||||
if (info->encrypt_type != HTT_RX_MPDU_ENCRYPT_NONE) {
|
||||
status->flag |= RX_FLAG_DECRYPTED | RX_FLAG_IV_STRIPPED |
|
||||
RX_FLAG_MMIC_STRIPPED;
|
||||
hdr->frame_control = __cpu_to_le16(
|
||||
__le16_to_cpu(hdr->frame_control) &
|
||||
~IEEE80211_FCTL_PROTECTED);
|
||||
}
|
||||
|
||||
if (info->mic_err)
|
||||
status->flag |= RX_FLAG_MMIC_ERROR;
|
||||
|
||||
if (info->fcs_err)
|
||||
status->flag |= RX_FLAG_FAILED_FCS_CRC;
|
||||
|
||||
if (info->amsdu_more)
|
||||
status->flag |= RX_FLAG_AMSDU_MORE;
|
||||
|
||||
status->signal = info->signal;
|
||||
|
||||
spin_lock_bh(&ar->data_lock);
|
||||
ch = ar->scan_channel;
|
||||
if (!ch)
|
||||
ch = ar->rx_channel;
|
||||
spin_unlock_bh(&ar->data_lock);
|
||||
|
||||
if (!ch) {
|
||||
ath10k_warn("no channel configured; ignoring frame!\n");
|
||||
dev_kfree_skb_any(info->skb);
|
||||
return;
|
||||
}
|
||||
|
||||
process_rx_rates(ar, info, ch->band, status);
|
||||
status->band = ch->band;
|
||||
status->freq = ch->center_freq;
|
||||
|
||||
if (info->rate.info0 & HTT_RX_INDICATION_INFO0_END_VALID) {
|
||||
/* TSF available only in 32-bit */
|
||||
status->mactime = info->tsf & 0xffffffff;
|
||||
status->flag |= RX_FLAG_MACTIME_END;
|
||||
}
|
||||
|
||||
ath10k_dbg(ATH10K_DBG_DATA,
|
||||
"rx skb %p len %u %s%s%s%s%s %srate_idx %u vht_nss %u freq %u band %u flag 0x%x fcs-err %i\n",
|
||||
info->skb,
|
||||
info->skb->len,
|
||||
status->flag == 0 ? "legacy" : "",
|
||||
status->flag & RX_FLAG_HT ? "ht" : "",
|
||||
status->flag & RX_FLAG_VHT ? "vht" : "",
|
||||
status->flag & RX_FLAG_40MHZ ? "40" : "",
|
||||
status->vht_flag & RX_VHT_FLAG_80MHZ ? "80" : "",
|
||||
status->flag & RX_FLAG_SHORT_GI ? "sgi " : "",
|
||||
status->rate_idx,
|
||||
status->vht_nss,
|
||||
status->freq,
|
||||
status->band, status->flag, info->fcs_err);
|
||||
ath10k_dbg_dump(ATH10K_DBG_HTT_DUMP, NULL, "rx skb: ",
|
||||
info->skb->data, info->skb->len);
|
||||
|
||||
ieee80211_rx(ar->hw, info->skb);
|
||||
}
|
||||
|
||||
struct ath10k_peer *ath10k_peer_find(struct ath10k *ar, int vdev_id,
|
||||
const u8 *addr)
|
||||
{
|
||||
|
|
|
@ -21,7 +21,6 @@
|
|||
|
||||
void ath10k_txrx_tx_unref(struct ath10k_htt *htt,
|
||||
const struct htt_tx_done *tx_done);
|
||||
void ath10k_process_rx(struct ath10k *ar, struct htt_rx_info *info);
|
||||
|
||||
struct ath10k_peer *ath10k_peer_find(struct ath10k *ar, int vdev_id,
|
||||
const u8 *addr);
|
||||
|
|
|
@ -1362,13 +1362,10 @@ static void ath10k_wmi_event_host_swba(struct ath10k *ar, struct sk_buff *skb)
|
|||
struct sk_buff *bcn;
|
||||
int ret, vdev_id = 0;
|
||||
|
||||
ath10k_dbg(ATH10K_DBG_MGMT, "WMI_HOST_SWBA_EVENTID\n");
|
||||
|
||||
ev = (struct wmi_host_swba_event *)skb->data;
|
||||
map = __le32_to_cpu(ev->vdev_map);
|
||||
|
||||
ath10k_dbg(ATH10K_DBG_MGMT, "host swba:\n"
|
||||
"-vdev map 0x%x\n",
|
||||
ath10k_dbg(ATH10K_DBG_MGMT, "mgmt swba vdev_map 0x%x\n",
|
||||
ev->vdev_map);
|
||||
|
||||
for (; map; map >>= 1, vdev_id++) {
|
||||
|
@ -1385,12 +1382,7 @@ static void ath10k_wmi_event_host_swba(struct ath10k *ar, struct sk_buff *skb)
|
|||
bcn_info = &ev->bcn_info[i];
|
||||
|
||||
ath10k_dbg(ATH10K_DBG_MGMT,
|
||||
"-bcn_info[%d]:\n"
|
||||
"--tim_len %d\n"
|
||||
"--tim_mcast %d\n"
|
||||
"--tim_changed %d\n"
|
||||
"--tim_num_ps_pending %d\n"
|
||||
"--tim_bitmap 0x%08x%08x%08x%08x\n",
|
||||
"mgmt event bcn_info %d tim_len %d mcast %d changed %d num_ps_pending %d bitmap 0x%08x%08x%08x%08x\n",
|
||||
i,
|
||||
__le32_to_cpu(bcn_info->tim_info.tim_len),
|
||||
__le32_to_cpu(bcn_info->tim_info.tim_mcast),
|
||||
|
@ -2393,8 +2385,9 @@ int ath10k_wmi_connect_htc_service(struct ath10k *ar)
|
|||
return 0;
|
||||
}
|
||||
|
||||
int ath10k_wmi_pdev_set_regdomain(struct ath10k *ar, u16 rd, u16 rd2g,
|
||||
u16 rd5g, u16 ctl2g, u16 ctl5g)
|
||||
static int ath10k_wmi_main_pdev_set_regdomain(struct ath10k *ar, u16 rd,
|
||||
u16 rd2g, u16 rd5g, u16 ctl2g,
|
||||
u16 ctl5g)
|
||||
{
|
||||
struct wmi_pdev_set_regdomain_cmd *cmd;
|
||||
struct sk_buff *skb;
|
||||
|
@ -2418,6 +2411,46 @@ int ath10k_wmi_pdev_set_regdomain(struct ath10k *ar, u16 rd, u16 rd2g,
|
|||
ar->wmi.cmd->pdev_set_regdomain_cmdid);
|
||||
}
|
||||
|
||||
static int ath10k_wmi_10x_pdev_set_regdomain(struct ath10k *ar, u16 rd,
|
||||
u16 rd2g, u16 rd5g,
|
||||
u16 ctl2g, u16 ctl5g,
|
||||
enum wmi_dfs_region dfs_reg)
|
||||
{
|
||||
struct wmi_pdev_set_regdomain_cmd_10x *cmd;
|
||||
struct sk_buff *skb;
|
||||
|
||||
skb = ath10k_wmi_alloc_skb(sizeof(*cmd));
|
||||
if (!skb)
|
||||
return -ENOMEM;
|
||||
|
||||
cmd = (struct wmi_pdev_set_regdomain_cmd_10x *)skb->data;
|
||||
cmd->reg_domain = __cpu_to_le32(rd);
|
||||
cmd->reg_domain_2G = __cpu_to_le32(rd2g);
|
||||
cmd->reg_domain_5G = __cpu_to_le32(rd5g);
|
||||
cmd->conformance_test_limit_2G = __cpu_to_le32(ctl2g);
|
||||
cmd->conformance_test_limit_5G = __cpu_to_le32(ctl5g);
|
||||
cmd->dfs_domain = __cpu_to_le32(dfs_reg);
|
||||
|
||||
ath10k_dbg(ATH10K_DBG_WMI,
|
||||
"wmi pdev regdomain rd %x rd2g %x rd5g %x ctl2g %x ctl5g %x dfs_region %x\n",
|
||||
rd, rd2g, rd5g, ctl2g, ctl5g, dfs_reg);
|
||||
|
||||
return ath10k_wmi_cmd_send(ar, skb,
|
||||
ar->wmi.cmd->pdev_set_regdomain_cmdid);
|
||||
}
|
||||
|
||||
int ath10k_wmi_pdev_set_regdomain(struct ath10k *ar, u16 rd, u16 rd2g,
|
||||
u16 rd5g, u16 ctl2g, u16 ctl5g,
|
||||
enum wmi_dfs_region dfs_reg)
|
||||
{
|
||||
if (test_bit(ATH10K_FW_FEATURE_WMI_10X, ar->fw_features))
|
||||
return ath10k_wmi_10x_pdev_set_regdomain(ar, rd, rd2g, rd5g,
|
||||
ctl2g, ctl5g, dfs_reg);
|
||||
else
|
||||
return ath10k_wmi_main_pdev_set_regdomain(ar, rd, rd2g, rd5g,
|
||||
ctl2g, ctl5g);
|
||||
}
|
||||
|
||||
int ath10k_wmi_pdev_set_channel(struct ath10k *ar,
|
||||
const struct wmi_channel_arg *arg)
|
||||
{
|
||||
|
@ -3456,8 +3489,9 @@ int ath10k_wmi_peer_assoc(struct ath10k *ar,
|
|||
__cpu_to_le32(arg->peer_vht_rates.tx_mcs_set);
|
||||
|
||||
ath10k_dbg(ATH10K_DBG_WMI,
|
||||
"wmi peer assoc vdev %d addr %pM\n",
|
||||
arg->vdev_id, arg->addr);
|
||||
"wmi peer assoc vdev %d addr %pM (%s)\n",
|
||||
arg->vdev_id, arg->addr,
|
||||
arg->peer_reassoc ? "reassociate" : "new");
|
||||
return ath10k_wmi_cmd_send(ar, skb, ar->wmi.cmd->peer_assoc_cmdid);
|
||||
}
|
||||
|
||||
|
|
|
@ -198,16 +198,6 @@ struct wmi_mac_addr {
|
|||
} __packed;
|
||||
} __packed;
|
||||
|
||||
/* macro to convert MAC address from WMI word format to char array */
|
||||
#define WMI_MAC_ADDR_TO_CHAR_ARRAY(pwmi_mac_addr, c_macaddr) do { \
|
||||
(c_macaddr)[0] = ((pwmi_mac_addr)->word0) & 0xff; \
|
||||
(c_macaddr)[1] = (((pwmi_mac_addr)->word0) >> 8) & 0xff; \
|
||||
(c_macaddr)[2] = (((pwmi_mac_addr)->word0) >> 16) & 0xff; \
|
||||
(c_macaddr)[3] = (((pwmi_mac_addr)->word0) >> 24) & 0xff; \
|
||||
(c_macaddr)[4] = ((pwmi_mac_addr)->word1) & 0xff; \
|
||||
(c_macaddr)[5] = (((pwmi_mac_addr)->word1) >> 8) & 0xff; \
|
||||
} while (0)
|
||||
|
||||
struct wmi_cmd_map {
|
||||
u32 init_cmdid;
|
||||
u32 start_scan_cmdid;
|
||||
|
@ -2185,6 +2175,31 @@ struct wmi_pdev_set_regdomain_cmd {
|
|||
__le32 conformance_test_limit_5G;
|
||||
} __packed;
|
||||
|
||||
enum wmi_dfs_region {
|
||||
/* Uninitialized dfs domain */
|
||||
WMI_UNINIT_DFS_DOMAIN = 0,
|
||||
|
||||
/* FCC3 dfs domain */
|
||||
WMI_FCC_DFS_DOMAIN = 1,
|
||||
|
||||
/* ETSI dfs domain */
|
||||
WMI_ETSI_DFS_DOMAIN = 2,
|
||||
|
||||
/*Japan dfs domain */
|
||||
WMI_MKK4_DFS_DOMAIN = 3,
|
||||
};
|
||||
|
||||
struct wmi_pdev_set_regdomain_cmd_10x {
|
||||
__le32 reg_domain;
|
||||
__le32 reg_domain_2G;
|
||||
__le32 reg_domain_5G;
|
||||
__le32 conformance_test_limit_2G;
|
||||
__le32 conformance_test_limit_5G;
|
||||
|
||||
/* dfs domain from wmi_dfs_region */
|
||||
__le32 dfs_domain;
|
||||
} __packed;
|
||||
|
||||
/* Command to set/unset chip in quiet mode */
|
||||
struct wmi_pdev_set_quiet_cmd {
|
||||
/* period in TUs */
|
||||
|
@ -2210,6 +2225,19 @@ enum ath10k_protmode {
|
|||
ATH10K_PROT_RTSCTS = 2, /* RTS-CTS */
|
||||
};
|
||||
|
||||
enum wmi_rtscts_profile {
|
||||
WMI_RTSCTS_FOR_NO_RATESERIES = 0,
|
||||
WMI_RTSCTS_FOR_SECOND_RATESERIES,
|
||||
WMI_RTSCTS_ACROSS_SW_RETRIES
|
||||
};
|
||||
|
||||
#define WMI_RTSCTS_ENABLED 1
|
||||
#define WMI_RTSCTS_SET_MASK 0x0f
|
||||
#define WMI_RTSCTS_SET_LSB 0
|
||||
|
||||
#define WMI_RTSCTS_PROFILE_MASK 0xf0
|
||||
#define WMI_RTSCTS_PROFILE_LSB 4
|
||||
|
||||
enum wmi_beacon_gen_mode {
|
||||
WMI_BEACON_STAGGERED_MODE = 0,
|
||||
WMI_BEACON_BURST_MODE = 1
|
||||
|
@ -2682,6 +2710,9 @@ struct wal_dbg_tx_stats {
|
|||
/* wal pdev resets */
|
||||
__le32 pdev_resets;
|
||||
|
||||
/* frames dropped due to non-availability of stateless TIDs */
|
||||
__le32 stateless_tid_alloc_failure;
|
||||
|
||||
__le32 phy_underrun;
|
||||
|
||||
/* MPDU is more than txop limit */
|
||||
|
@ -2738,13 +2769,21 @@ enum wmi_stats_id {
|
|||
WMI_REQUEST_AP_STAT = 0x02
|
||||
};
|
||||
|
||||
struct wlan_inst_rssi_args {
|
||||
__le16 cfg_retry_count;
|
||||
__le16 retry_count;
|
||||
};
|
||||
|
||||
struct wmi_request_stats_cmd {
|
||||
__le32 stats_id;
|
||||
|
||||
/*
|
||||
* Space to add parameters like
|
||||
* peer mac addr
|
||||
*/
|
||||
__le32 vdev_id;
|
||||
|
||||
/* peer MAC address */
|
||||
struct wmi_mac_addr peer_macaddr;
|
||||
|
||||
/* Instantaneous RSSI arguments */
|
||||
struct wlan_inst_rssi_args inst_rssi_args;
|
||||
} __packed;
|
||||
|
||||
/* Suspend option */
|
||||
|
@ -2795,7 +2834,7 @@ struct wmi_stats_event {
|
|||
* PDEV statistics
|
||||
* TODO: add all PDEV stats here
|
||||
*/
|
||||
struct wmi_pdev_stats {
|
||||
struct wmi_pdev_stats_old {
|
||||
__le32 chan_nf; /* Channel noise floor */
|
||||
__le32 tx_frame_count; /* TX frame count */
|
||||
__le32 rx_frame_count; /* RX frame count */
|
||||
|
@ -2806,6 +2845,23 @@ struct wmi_pdev_stats {
|
|||
struct wal_dbg_stats wal; /* WAL dbg stats */
|
||||
} __packed;
|
||||
|
||||
struct wmi_pdev_stats_10x {
|
||||
__le32 chan_nf; /* Channel noise floor */
|
||||
__le32 tx_frame_count; /* TX frame count */
|
||||
__le32 rx_frame_count; /* RX frame count */
|
||||
__le32 rx_clear_count; /* rx clear count */
|
||||
__le32 cycle_count; /* cycle count */
|
||||
__le32 phy_err_count; /* Phy error count */
|
||||
__le32 chan_tx_pwr; /* channel tx power */
|
||||
struct wal_dbg_stats wal; /* WAL dbg stats */
|
||||
__le32 ack_rx_bad;
|
||||
__le32 rts_bad;
|
||||
__le32 rts_good;
|
||||
__le32 fcs_bad;
|
||||
__le32 no_beacons;
|
||||
__le32 mib_int_count;
|
||||
} __packed;
|
||||
|
||||
/*
|
||||
* VDEV statistics
|
||||
* TODO: add all VDEV stats here
|
||||
|
@ -2818,12 +2874,19 @@ struct wmi_vdev_stats {
|
|||
* peer statistics.
|
||||
* TODO: add more stats
|
||||
*/
|
||||
struct wmi_peer_stats {
|
||||
struct wmi_peer_stats_old {
|
||||
struct wmi_mac_addr peer_macaddr;
|
||||
__le32 peer_rssi;
|
||||
__le32 peer_tx_rate;
|
||||
} __packed;
|
||||
|
||||
struct wmi_peer_stats_10x {
|
||||
struct wmi_mac_addr peer_macaddr;
|
||||
__le32 peer_rssi;
|
||||
__le32 peer_tx_rate;
|
||||
__le32 peer_rx_rate;
|
||||
} __packed;
|
||||
|
||||
struct wmi_vdev_create_cmd {
|
||||
__le32 vdev_id;
|
||||
__le32 vdev_type;
|
||||
|
@ -4202,7 +4265,8 @@ int ath10k_wmi_pdev_set_channel(struct ath10k *ar,
|
|||
int ath10k_wmi_pdev_suspend_target(struct ath10k *ar, u32 suspend_opt);
|
||||
int ath10k_wmi_pdev_resume_target(struct ath10k *ar);
|
||||
int ath10k_wmi_pdev_set_regdomain(struct ath10k *ar, u16 rd, u16 rd2g,
|
||||
u16 rd5g, u16 ctl2g, u16 ctl5g);
|
||||
u16 rd5g, u16 ctl2g, u16 ctl5g,
|
||||
enum wmi_dfs_region dfs_reg);
|
||||
int ath10k_wmi_pdev_set_param(struct ath10k *ar, u32 id, u32 value);
|
||||
int ath10k_wmi_cmd_init(struct ath10k *ar);
|
||||
int ath10k_wmi_start_scan(struct ath10k *ar, const struct wmi_start_scan_arg *);
|
||||
|
|
|
@ -1,11 +1,19 @@
|
|||
config ATH6KL
|
||||
tristate "Atheros mobile chipsets support"
|
||||
depends on CFG80211
|
||||
---help---
|
||||
This module adds core support for wireless adapters based on
|
||||
Atheros AR6003 and AR6004 chipsets. You still need separate
|
||||
bus drivers for USB and SDIO to be able to use real devices.
|
||||
|
||||
If you choose to build it as a module, it will be called
|
||||
ath6kl_core. Please note that AR6002 and AR6001 are not
|
||||
supported by this driver.
|
||||
|
||||
config ATH6KL_SDIO
|
||||
tristate "Atheros ath6kl SDIO support"
|
||||
depends on ATH6KL
|
||||
depends on MMC
|
||||
depends on CFG80211
|
||||
---help---
|
||||
This module adds support for wireless adapters based on
|
||||
Atheros AR6003 and AR6004 chipsets running over SDIO. If you
|
||||
|
@ -17,25 +25,31 @@ config ATH6KL_USB
|
|||
tristate "Atheros ath6kl USB support"
|
||||
depends on ATH6KL
|
||||
depends on USB
|
||||
depends on CFG80211
|
||||
---help---
|
||||
This module adds support for wireless adapters based on
|
||||
Atheros AR6004 chipset running over USB. This is still under
|
||||
implementation and it isn't functional. If you choose to
|
||||
build it as a module, it will be called ath6kl_usb.
|
||||
Atheros AR6004 chipset and chipsets based on it running over
|
||||
USB. If you choose to build it as a module, it will be
|
||||
called ath6kl_usb.
|
||||
|
||||
config ATH6KL_DEBUG
|
||||
bool "Atheros ath6kl debugging"
|
||||
depends on ATH6KL
|
||||
---help---
|
||||
Enables debug support
|
||||
Enables ath6kl debug support, including debug messages
|
||||
enabled with debug_mask module parameter and debugfs
|
||||
interface.
|
||||
|
||||
If unsure, say Y to make it easier to debug problems.
|
||||
|
||||
config ATH6KL_TRACING
|
||||
bool "Atheros ath6kl tracing support"
|
||||
depends on ATH6KL
|
||||
depends on EVENT_TRACING
|
||||
---help---
|
||||
Select this to ath6kl use tracing infrastructure.
|
||||
Select this to ath6kl use tracing infrastructure which, for
|
||||
example, can be enabled with help of trace-cmd. All debug
|
||||
messages and commands are delivered to using individually
|
||||
enablable trace points.
|
||||
|
||||
If unsure, say Y to make it easier to debug problems.
|
||||
|
||||
|
@ -47,3 +61,5 @@ config ATH6KL_REGDOMAIN
|
|||
Enabling this makes it possible to change the regdomain in
|
||||
the firmware. This can be only enabled if regulatory requirements
|
||||
are taken into account.
|
||||
|
||||
If unsure, say N.
|
||||
|
|
|
@ -724,8 +724,9 @@ ath6kl_add_bss_if_needed(struct ath6kl_vif *vif,
|
|||
ath6kl_dbg(ATH6KL_DBG_WLAN_CFG,
|
||||
"added bss %pM to cfg80211\n", bssid);
|
||||
kfree(ie);
|
||||
} else
|
||||
} else {
|
||||
ath6kl_dbg(ATH6KL_DBG_WLAN_CFG, "cfg80211 already has a bss\n");
|
||||
}
|
||||
|
||||
return bss;
|
||||
}
|
||||
|
@ -970,7 +971,6 @@ static int ath6kl_set_probed_ssids(struct ath6kl *ar,
|
|||
ssid_list[i].flag,
|
||||
ssid_list[i].ssid.ssid_len,
|
||||
ssid_list[i].ssid.ssid);
|
||||
|
||||
}
|
||||
|
||||
/* Make sure no old entries are left behind */
|
||||
|
@ -1897,7 +1897,6 @@ static int ath6kl_wow_usr(struct ath6kl *ar, struct ath6kl_vif *vif,
|
|||
|
||||
/* Configure the patterns that we received from the user. */
|
||||
for (i = 0; i < wow->n_patterns; i++) {
|
||||
|
||||
/*
|
||||
* Convert given nl80211 specific mask value to equivalent
|
||||
* driver specific mask value and send it to the chip along
|
||||
|
@ -2850,8 +2849,9 @@ static int ath6kl_start_ap(struct wiphy *wiphy, struct net_device *dev,
|
|||
if (p.prwise_crypto_type == 0) {
|
||||
p.prwise_crypto_type = NONE_CRYPT;
|
||||
ath6kl_set_cipher(vif, 0, true);
|
||||
} else if (info->crypto.n_ciphers_pairwise == 1)
|
||||
} else if (info->crypto.n_ciphers_pairwise == 1) {
|
||||
ath6kl_set_cipher(vif, info->crypto.ciphers_pairwise[0], true);
|
||||
}
|
||||
|
||||
switch (info->crypto.cipher_group) {
|
||||
case WLAN_CIPHER_SUITE_WEP40:
|
||||
|
@ -2897,7 +2897,6 @@ static int ath6kl_start_ap(struct wiphy *wiphy, struct net_device *dev,
|
|||
}
|
||||
|
||||
if (info->inactivity_timeout) {
|
||||
|
||||
inactivity_timeout = info->inactivity_timeout;
|
||||
|
||||
if (ar->hw.flags & ATH6KL_HW_AP_INACTIVITY_MINS)
|
||||
|
|
|
@ -45,9 +45,9 @@ module_param(testmode, uint, 0644);
|
|||
module_param(recovery_enable, uint, 0644);
|
||||
module_param(heart_beat_poll, uint, 0644);
|
||||
MODULE_PARM_DESC(recovery_enable, "Enable recovery from firmware error");
|
||||
MODULE_PARM_DESC(heart_beat_poll, "Enable fw error detection periodic" \
|
||||
"polling. This also specifies the polling interval in" \
|
||||
"msecs. Set reocvery_enable for this to be effective");
|
||||
MODULE_PARM_DESC(heart_beat_poll,
|
||||
"Enable fw error detection periodic polling in msecs - Also set recovery_enable for this to be effective");
|
||||
|
||||
|
||||
void ath6kl_core_tx_complete(struct ath6kl *ar, struct sk_buff *skb)
|
||||
{
|
||||
|
|
|
@ -172,7 +172,6 @@ void ath6kl_dump_registers(struct ath6kl_device *dev,
|
|||
struct ath6kl_irq_proc_registers *irq_proc_reg,
|
||||
struct ath6kl_irq_enable_reg *irq_enable_reg)
|
||||
{
|
||||
|
||||
ath6kl_dbg(ATH6KL_DBG_IRQ, ("<------- Register Table -------->\n"));
|
||||
|
||||
if (irq_proc_reg != NULL) {
|
||||
|
@ -219,7 +218,6 @@ void ath6kl_dump_registers(struct ath6kl_device *dev,
|
|||
"GMBOX lookahead alias 1: 0x%x\n",
|
||||
irq_proc_reg->rx_gmbox_lkahd_alias[1]);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
if (irq_enable_reg != NULL) {
|
||||
|
@ -1396,7 +1394,6 @@ static ssize_t ath6kl_create_qos_write(struct file *file,
|
|||
const char __user *user_buf,
|
||||
size_t count, loff_t *ppos)
|
||||
{
|
||||
|
||||
struct ath6kl *ar = file->private_data;
|
||||
struct ath6kl_vif *vif;
|
||||
char buf[200];
|
||||
|
@ -1575,7 +1572,6 @@ static ssize_t ath6kl_delete_qos_write(struct file *file,
|
|||
const char __user *user_buf,
|
||||
size_t count, loff_t *ppos)
|
||||
{
|
||||
|
||||
struct ath6kl *ar = file->private_data;
|
||||
struct ath6kl_vif *vif;
|
||||
char buf[100];
|
||||
|
|
|
@ -97,8 +97,8 @@ static inline void ath6kl_dump_registers(struct ath6kl_device *dev,
|
|||
struct ath6kl_irq_proc_registers *irq_proc_reg,
|
||||
struct ath6kl_irq_enable_reg *irq_en_reg)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
static inline void dump_cred_dist_stats(struct htc_target *target)
|
||||
{
|
||||
}
|
||||
|
|
|
@ -37,7 +37,6 @@ static int ath6kl_hif_cp_scat_dma_buf(struct hif_scatter_req *req,
|
|||
buf = req->virt_dma_buf;
|
||||
|
||||
for (i = 0; i < req->scat_entries; i++) {
|
||||
|
||||
if (from_dma)
|
||||
memcpy(req->scat_list[i].buf, buf,
|
||||
req->scat_list[i].len);
|
||||
|
@ -116,7 +115,6 @@ static void ath6kl_hif_dump_fw_crash(struct ath6kl *ar)
|
|||
le32_to_cpu(regdump_val[i + 2]),
|
||||
le32_to_cpu(regdump_val[i + 3]));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
static int ath6kl_hif_proc_dbg_intr(struct ath6kl_device *dev)
|
||||
|
@ -701,5 +699,4 @@ int ath6kl_hif_setup(struct ath6kl_device *dev)
|
|||
|
||||
fail_setup:
|
||||
return status;
|
||||
|
||||
}
|
||||
|
|
|
@ -197,9 +197,9 @@ struct hif_scatter_req {
|
|||
/* bounce buffer for upper layers to copy to/from */
|
||||
u8 *virt_dma_buf;
|
||||
|
||||
struct hif_scatter_item scat_list[1];
|
||||
|
||||
u32 scat_q_depth;
|
||||
|
||||
struct hif_scatter_item scat_list[0];
|
||||
};
|
||||
|
||||
struct ath6kl_irq_proc_registers {
|
||||
|
|
|
@ -112,9 +112,9 @@ static void ath6kl_credit_init(struct ath6kl_htc_credit_info *cred_info,
|
|||
if (cur_ep_dist->endpoint == ENDPOINT_0)
|
||||
continue;
|
||||
|
||||
if (cur_ep_dist->svc_id == WMI_CONTROL_SVC)
|
||||
if (cur_ep_dist->svc_id == WMI_CONTROL_SVC) {
|
||||
cur_ep_dist->cred_norm = cur_ep_dist->cred_per_msg;
|
||||
else {
|
||||
} else {
|
||||
/*
|
||||
* For the remaining data endpoints, we assume that
|
||||
* each cred_per_msg are the same. We use a simple
|
||||
|
@ -129,7 +129,6 @@ static void ath6kl_credit_init(struct ath6kl_htc_credit_info *cred_info,
|
|||
count = (count * 3) >> 2;
|
||||
count = max(count, cur_ep_dist->cred_per_msg);
|
||||
cur_ep_dist->cred_norm = count;
|
||||
|
||||
}
|
||||
|
||||
ath6kl_dbg(ATH6KL_DBG_CREDIT,
|
||||
|
@ -549,7 +548,6 @@ static int htc_check_credits(struct htc_target *target,
|
|||
enum htc_endpoint_id eid, unsigned int len,
|
||||
int *req_cred)
|
||||
{
|
||||
|
||||
*req_cred = (len > target->tgt_cred_sz) ?
|
||||
DIV_ROUND_UP(len, target->tgt_cred_sz) : 1;
|
||||
|
||||
|
@ -608,7 +606,6 @@ static void ath6kl_htc_tx_pkts_get(struct htc_target *target,
|
|||
unsigned int len;
|
||||
|
||||
while (true) {
|
||||
|
||||
flags = 0;
|
||||
|
||||
if (list_empty(&endpoint->txq))
|
||||
|
@ -889,7 +886,6 @@ static void ath6kl_htc_tx_from_queue(struct htc_target *target,
|
|||
ac = target->dev->ar->ep2ac_map[endpoint->eid];
|
||||
|
||||
while (true) {
|
||||
|
||||
if (list_empty(&endpoint->txq))
|
||||
break;
|
||||
|
||||
|
@ -1190,7 +1186,6 @@ static void ath6kl_htc_mbox_flush_txep(struct htc_target *target,
|
|||
list_add_tail(&packet->list, &container);
|
||||
htc_tx_complete(endpoint, &container);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
static void ath6kl_htc_flush_txep_all(struct htc_target *target)
|
||||
|
@ -1394,7 +1389,6 @@ static int ath6kl_htc_rx_setup(struct htc_target *target,
|
|||
|
||||
ep_cb = ep->ep_cb;
|
||||
for (j = 0; j < n_msg; j++) {
|
||||
|
||||
/*
|
||||
* Reset flag, any packets allocated using the
|
||||
* rx_alloc() API cannot be recycled on
|
||||
|
@ -1424,9 +1418,9 @@ static int ath6kl_htc_rx_setup(struct htc_target *target,
|
|||
}
|
||||
}
|
||||
|
||||
if (list_empty(&ep->rx_bufq))
|
||||
if (list_empty(&ep->rx_bufq)) {
|
||||
packet = NULL;
|
||||
else {
|
||||
} else {
|
||||
packet = list_first_entry(&ep->rx_bufq,
|
||||
struct htc_packet, list);
|
||||
list_del(&packet->list);
|
||||
|
@ -1487,7 +1481,6 @@ static int ath6kl_htc_rx_alloc(struct htc_target *target,
|
|||
spin_lock_bh(&target->rx_lock);
|
||||
|
||||
for (i = 0; i < msg; i++) {
|
||||
|
||||
htc_hdr = (struct htc_frame_hdr *)&lk_ahds[i];
|
||||
|
||||
if (htc_hdr->eid >= ENDPOINT_MAX) {
|
||||
|
@ -1708,7 +1701,6 @@ static int htc_parse_trailer(struct htc_target *target,
|
|||
lk_ahd = (struct htc_lookahead_report *) record_buf;
|
||||
if ((lk_ahd->pre_valid == ((~lk_ahd->post_valid) & 0xFF)) &&
|
||||
next_lk_ahds) {
|
||||
|
||||
ath6kl_dbg(ATH6KL_DBG_HTC,
|
||||
"htc rx lk_ahd found pre_valid 0x%x post_valid 0x%x\n",
|
||||
lk_ahd->pre_valid, lk_ahd->post_valid);
|
||||
|
@ -1755,7 +1747,6 @@ static int htc_parse_trailer(struct htc_target *target,
|
|||
}
|
||||
|
||||
return 0;
|
||||
|
||||
}
|
||||
|
||||
static int htc_proc_trailer(struct htc_target *target,
|
||||
|
@ -1776,7 +1767,6 @@ static int htc_proc_trailer(struct htc_target *target,
|
|||
status = 0;
|
||||
|
||||
while (len > 0) {
|
||||
|
||||
if (len < sizeof(struct htc_record_hdr)) {
|
||||
status = -ENOMEM;
|
||||
break;
|
||||
|
@ -2098,7 +2088,6 @@ static int ath6kl_htc_rx_fetch(struct htc_target *target,
|
|||
}
|
||||
|
||||
if (!fetched_pkts) {
|
||||
|
||||
packet = list_first_entry(rx_pktq, struct htc_packet,
|
||||
list);
|
||||
|
||||
|
@ -2173,7 +2162,6 @@ int ath6kl_htc_rxmsg_pending_handler(struct htc_target *target,
|
|||
look_aheads[0] = msg_look_ahead;
|
||||
|
||||
while (true) {
|
||||
|
||||
/*
|
||||
* First lookahead sets the expected endpoint IDs for all
|
||||
* packets in a bundle.
|
||||
|
@ -2825,8 +2813,9 @@ static int ath6kl_htc_reset(struct htc_target *target)
|
|||
packet->buf = packet->buf_start;
|
||||
packet->endpoint = ENDPOINT_0;
|
||||
list_add_tail(&packet->list, &target->free_ctrl_rxbuf);
|
||||
} else
|
||||
} else {
|
||||
list_add_tail(&packet->list, &target->free_ctrl_txbuf);
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
|
|
@ -137,7 +137,6 @@ static void get_htc_packet_credit_based(struct htc_target *target,
|
|||
credits_required = 0;
|
||||
|
||||
} else {
|
||||
|
||||
if (ep->cred_dist.credits < credits_required)
|
||||
break;
|
||||
|
||||
|
@ -169,7 +168,6 @@ static void get_htc_packet_credit_based(struct htc_target *target,
|
|||
/* queue this packet into the caller's queue */
|
||||
list_add_tail(&packet->list, queue);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
static void get_htc_packet(struct htc_target *target,
|
||||
|
@ -279,7 +277,6 @@ static int htc_issue_packets(struct htc_target *target,
|
|||
list_add(&packet->list, pkt_queue);
|
||||
break;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
if (status != 0) {
|
||||
|
@ -385,7 +382,6 @@ static enum htc_send_queue_result htc_try_send(struct htc_target *target,
|
|||
*/
|
||||
list_for_each_entry_safe(packet, tmp_pkt,
|
||||
txq, list) {
|
||||
|
||||
ath6kl_dbg(ATH6KL_DBG_HTC,
|
||||
"%s: Indicat overflowed TX pkts: %p\n",
|
||||
__func__, packet);
|
||||
|
@ -403,7 +399,6 @@ static enum htc_send_queue_result htc_try_send(struct htc_target *target,
|
|||
list_move_tail(&packet->list,
|
||||
&send_queue);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
if (list_empty(&send_queue)) {
|
||||
|
@ -454,7 +449,6 @@ static enum htc_send_queue_result htc_try_send(struct htc_target *target,
|
|||
* enough transmit resources.
|
||||
*/
|
||||
while (true) {
|
||||
|
||||
if (get_queue_depth(&ep->txq) == 0)
|
||||
break;
|
||||
|
||||
|
@ -495,8 +489,8 @@ static enum htc_send_queue_result htc_try_send(struct htc_target *target,
|
|||
}
|
||||
|
||||
spin_lock_bh(&target->tx_lock);
|
||||
|
||||
}
|
||||
|
||||
/* done with this endpoint, we can clear the count */
|
||||
ep->tx_proc_cnt = 0;
|
||||
spin_unlock_bh(&target->tx_lock);
|
||||
|
@ -1106,7 +1100,6 @@ free_skb:
|
|||
dev_kfree_skb(skb);
|
||||
|
||||
return status;
|
||||
|
||||
}
|
||||
|
||||
static void htc_flush_rx_queue(struct htc_target *target,
|
||||
|
@ -1258,7 +1251,6 @@ static int ath6kl_htc_pipe_conn_service(struct htc_target *target,
|
|||
tx_alloc = 0;
|
||||
|
||||
} else {
|
||||
|
||||
tx_alloc = htc_get_credit_alloc(target, conn_req->svc_id);
|
||||
if (tx_alloc == 0) {
|
||||
status = -ENOMEM;
|
||||
|
|
|
@ -1192,7 +1192,6 @@ static int ath6kl_upload_board_file(struct ath6kl *ar)
|
|||
|
||||
if (board_ext_address &&
|
||||
ar->fw_board_len == (board_data_size + board_ext_data_size)) {
|
||||
|
||||
/* write extended board data */
|
||||
ath6kl_dbg(ATH6KL_DBG_BOOT,
|
||||
"writing extended board data to 0x%x (%d B)\n",
|
||||
|
|
|
@ -571,7 +571,6 @@ void ath6kl_scan_complete_evt(struct ath6kl_vif *vif, int status)
|
|||
|
||||
static int ath6kl_commit_ch_switch(struct ath6kl_vif *vif, u16 channel)
|
||||
{
|
||||
|
||||
struct ath6kl *ar = vif->ar;
|
||||
|
||||
vif->profile.ch = cpu_to_le16(channel);
|
||||
|
@ -600,7 +599,6 @@ static int ath6kl_commit_ch_switch(struct ath6kl_vif *vif, u16 channel)
|
|||
|
||||
static void ath6kl_check_ch_switch(struct ath6kl *ar, u16 channel)
|
||||
{
|
||||
|
||||
struct ath6kl_vif *vif;
|
||||
int res = 0;
|
||||
|
||||
|
@ -692,9 +690,9 @@ void ath6kl_tkip_micerr_event(struct ath6kl_vif *vif, u8 keyid, bool ismcast)
|
|||
cfg80211_michael_mic_failure(vif->ndev, sta->mac,
|
||||
NL80211_KEYTYPE_PAIRWISE, keyid,
|
||||
tsc, GFP_KERNEL);
|
||||
} else
|
||||
} else {
|
||||
ath6kl_cfg80211_tkip_micerr_event(vif, keyid, ismcast);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
static void ath6kl_update_target_stats(struct ath6kl_vif *vif, u8 *ptr, u32 len)
|
||||
|
@ -1093,8 +1091,9 @@ static int ath6kl_open(struct net_device *dev)
|
|||
if (test_bit(CONNECTED, &vif->flags)) {
|
||||
netif_carrier_on(dev);
|
||||
netif_wake_queue(dev);
|
||||
} else
|
||||
} else {
|
||||
netif_carrier_off(dev);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -1146,7 +1145,6 @@ static int ath6kl_set_features(struct net_device *dev,
|
|||
dev->features = features | NETIF_F_RXCSUM;
|
||||
return err;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return err;
|
||||
|
|
|
@ -348,7 +348,7 @@ static int ath6kl_sdio_alloc_prep_scat_req(struct ath6kl_sdio *ar_sdio,
|
|||
int i, scat_req_sz, scat_list_sz, size;
|
||||
u8 *virt_buf;
|
||||
|
||||
scat_list_sz = (n_scat_entry - 1) * sizeof(struct hif_scatter_item);
|
||||
scat_list_sz = n_scat_entry * sizeof(struct hif_scatter_item);
|
||||
scat_req_sz = sizeof(*s_req) + scat_list_sz;
|
||||
|
||||
if (!virt_scat)
|
||||
|
@ -425,8 +425,9 @@ static int ath6kl_sdio_read_write_sync(struct ath6kl *ar, u32 addr, u8 *buf,
|
|||
memcpy(tbuf, buf, len);
|
||||
|
||||
bounced = true;
|
||||
} else
|
||||
} else {
|
||||
tbuf = buf;
|
||||
}
|
||||
|
||||
ret = ath6kl_sdio_io(ar_sdio->func, request, addr, tbuf, len);
|
||||
if ((request & HIF_READ) && bounced)
|
||||
|
@ -441,9 +442,9 @@ static int ath6kl_sdio_read_write_sync(struct ath6kl *ar, u32 addr, u8 *buf,
|
|||
static void __ath6kl_sdio_write_async(struct ath6kl_sdio *ar_sdio,
|
||||
struct bus_request *req)
|
||||
{
|
||||
if (req->scat_req)
|
||||
if (req->scat_req) {
|
||||
ath6kl_sdio_scat_rw(ar_sdio, req);
|
||||
else {
|
||||
} else {
|
||||
void *context;
|
||||
int status;
|
||||
|
||||
|
@ -656,7 +657,6 @@ static void ath6kl_sdio_scatter_req_add(struct ath6kl *ar,
|
|||
list_add_tail(&s_req->list, &ar_sdio->scat_req);
|
||||
|
||||
spin_unlock_bh(&ar_sdio->scat_lock);
|
||||
|
||||
}
|
||||
|
||||
/* scatter gather read write request */
|
||||
|
@ -674,9 +674,9 @@ static int ath6kl_sdio_async_rw_scatter(struct ath6kl *ar,
|
|||
"hif-scatter: total len: %d scatter entries: %d\n",
|
||||
scat_req->len, scat_req->scat_entries);
|
||||
|
||||
if (request & HIF_SYNCHRONOUS)
|
||||
if (request & HIF_SYNCHRONOUS) {
|
||||
status = ath6kl_sdio_scat_rw(ar_sdio, scat_req->busrequest);
|
||||
else {
|
||||
} else {
|
||||
spin_lock_bh(&ar_sdio->wr_async_lock);
|
||||
list_add_tail(&scat_req->busrequest->list, &ar_sdio->wr_asyncq);
|
||||
spin_unlock_bh(&ar_sdio->wr_async_lock);
|
||||
|
@ -856,7 +856,6 @@ static int ath6kl_sdio_suspend(struct ath6kl *ar, struct cfg80211_wowlan *wow)
|
|||
|
||||
if (ar->suspend_mode == WLAN_POWER_STATE_WOW ||
|
||||
(!ar->suspend_mode && wow)) {
|
||||
|
||||
ret = ath6kl_set_sdio_pm_caps(ar);
|
||||
if (ret)
|
||||
goto cut_pwr;
|
||||
|
@ -878,7 +877,6 @@ static int ath6kl_sdio_suspend(struct ath6kl *ar, struct cfg80211_wowlan *wow)
|
|||
|
||||
if (ar->suspend_mode == WLAN_POWER_STATE_DEEP_SLEEP ||
|
||||
!ar->suspend_mode || try_deepsleep) {
|
||||
|
||||
flags = sdio_get_host_pm_caps(func);
|
||||
if (!(flags & MMC_PM_KEEP_POWER))
|
||||
goto cut_pwr;
|
||||
|
@ -1061,7 +1059,6 @@ static int ath6kl_sdio_bmi_credits(struct ath6kl *ar)
|
|||
|
||||
timeout = jiffies + msecs_to_jiffies(BMI_COMMUNICATION_TIMEOUT);
|
||||
while (time_before(jiffies, timeout) && !ar->bmi.cmd_credits) {
|
||||
|
||||
/*
|
||||
* Hit the credit counter with a 4-byte access, the first byte
|
||||
* read will hit the counter and cause a decrement, while the
|
||||
|
|
|
@ -289,7 +289,7 @@ struct host_interest {
|
|||
u32 hi_hp_rx_traffic_ratio; /* 0xd8 */
|
||||
|
||||
/* test applications flags */
|
||||
u32 hi_test_apps_related ; /* 0xdc */
|
||||
u32 hi_test_apps_related; /* 0xdc */
|
||||
/* location of test script */
|
||||
u32 hi_ota_testscript; /* 0xe0 */
|
||||
/* location of CAL data */
|
||||
|
|
|
@ -125,8 +125,9 @@ static bool ath6kl_process_uapsdq(struct ath6kl_sta *conn,
|
|||
*flags |= WMI_DATA_HDR_FLAGS_UAPSD;
|
||||
spin_unlock_bh(&conn->psq_lock);
|
||||
return false;
|
||||
} else if (!conn->apsd_info)
|
||||
} else if (!conn->apsd_info) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (test_bit(WMM_ENABLED, &vif->flags)) {
|
||||
ether_type = be16_to_cpu(datap->h_proto);
|
||||
|
@ -316,8 +317,9 @@ int ath6kl_control_tx(void *devt, struct sk_buff *skb,
|
|||
cookie = NULL;
|
||||
ath6kl_err("wmi ctrl ep full, dropping pkt : 0x%p, len:%d\n",
|
||||
skb, skb->len);
|
||||
} else
|
||||
} else {
|
||||
cookie = ath6kl_alloc_cookie(ar);
|
||||
}
|
||||
|
||||
if (cookie == NULL) {
|
||||
spin_unlock_bh(&ar->lock);
|
||||
|
@ -359,7 +361,7 @@ int ath6kl_data_tx(struct sk_buff *skb, struct net_device *dev)
|
|||
struct ath6kl_vif *vif = netdev_priv(dev);
|
||||
u32 map_no = 0;
|
||||
u16 htc_tag = ATH6KL_DATA_PKT_TAG;
|
||||
u8 ac = 99 ; /* initialize to unmapped ac */
|
||||
u8 ac = 99; /* initialize to unmapped ac */
|
||||
bool chk_adhoc_ps_mapping = false;
|
||||
int ret;
|
||||
struct wmi_tx_meta_v2 meta_v2;
|
||||
|
@ -449,8 +451,9 @@ int ath6kl_data_tx(struct sk_buff *skb, struct net_device *dev)
|
|||
if (ret)
|
||||
goto fail_tx;
|
||||
}
|
||||
} else
|
||||
} else {
|
||||
goto fail_tx;
|
||||
}
|
||||
|
||||
spin_lock_bh(&ar->lock);
|
||||
|
||||
|
@ -702,7 +705,6 @@ void ath6kl_tx_complete(struct htc_target *target,
|
|||
|
||||
/* reap completed packets */
|
||||
while (!list_empty(packet_queue)) {
|
||||
|
||||
packet = list_first_entry(packet_queue, struct htc_packet,
|
||||
list);
|
||||
list_del(&packet->list);
|
||||
|
@ -1089,8 +1091,9 @@ static void aggr_deque_frms(struct aggr_info_conn *agg_conn, u8 tid,
|
|||
else
|
||||
skb_queue_tail(&rxtid->q, node->skb);
|
||||
node->skb = NULL;
|
||||
} else
|
||||
} else {
|
||||
stats->num_hole++;
|
||||
}
|
||||
|
||||
rxtid->seq_next = ATH6KL_NEXT_SEQ_NO(rxtid->seq_next);
|
||||
idx = AGGR_WIN_IDX(rxtid->seq_next, rxtid->hold_q_sz);
|
||||
|
@ -1211,7 +1214,7 @@ static bool aggr_process_recv_frm(struct aggr_info_conn *agg_conn, u8 tid,
|
|||
return is_queued;
|
||||
|
||||
spin_lock_bh(&rxtid->lock);
|
||||
for (idx = 0 ; idx < rxtid->hold_q_sz; idx++) {
|
||||
for (idx = 0; idx < rxtid->hold_q_sz; idx++) {
|
||||
if (rxtid->hold_q[idx].skb) {
|
||||
/*
|
||||
* There is a frame in the queue and no
|
||||
|
@ -1265,7 +1268,6 @@ static void ath6kl_uapsd_trigger_frame_rx(struct ath6kl_vif *vif,
|
|||
is_apsdq_empty_at_start = is_apsdq_empty;
|
||||
|
||||
while ((!is_apsdq_empty) && (num_frames_to_deliver)) {
|
||||
|
||||
spin_lock_bh(&conn->psq_lock);
|
||||
skb = skb_dequeue(&conn->apsdq);
|
||||
is_apsdq_empty = skb_queue_empty(&conn->apsdq);
|
||||
|
@ -1606,16 +1608,18 @@ void ath6kl_rx(struct htc_target *target, struct htc_packet *packet)
|
|||
if (!conn)
|
||||
return;
|
||||
aggr_conn = conn->aggr_conn;
|
||||
} else
|
||||
} else {
|
||||
aggr_conn = vif->aggr_cntxt->aggr_conn;
|
||||
}
|
||||
|
||||
if (aggr_process_recv_frm(aggr_conn, tid, seq_no,
|
||||
is_amsdu, skb)) {
|
||||
/* aggregation code will handle the skb */
|
||||
return;
|
||||
}
|
||||
} else if (!is_broadcast_ether_addr(datap->h_dest))
|
||||
} else if (!is_broadcast_ether_addr(datap->h_dest)) {
|
||||
vif->net_stats.multicast++;
|
||||
}
|
||||
|
||||
ath6kl_deliver_frames_to_nw_stack(vif->ndev, skb);
|
||||
}
|
||||
|
@ -1710,8 +1714,9 @@ void aggr_recv_addba_req_evt(struct ath6kl_vif *vif, u8 tid_mux, u16 seq_no,
|
|||
sta = ath6kl_find_sta_by_aid(vif->ar, aid);
|
||||
if (sta)
|
||||
aggr_conn = sta->aggr_conn;
|
||||
} else
|
||||
} else {
|
||||
aggr_conn = vif->aggr_cntxt->aggr_conn;
|
||||
}
|
||||
|
||||
if (!aggr_conn)
|
||||
return;
|
||||
|
@ -1766,7 +1771,6 @@ void aggr_conn_init(struct ath6kl_vif *vif, struct aggr_info *aggr_info,
|
|||
skb_queue_head_init(&rxtid->q);
|
||||
spin_lock_init(&rxtid->lock);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
struct aggr_info *aggr_init(struct ath6kl_vif *vif)
|
||||
|
@ -1806,8 +1810,9 @@ void aggr_recv_delba_req_evt(struct ath6kl_vif *vif, u8 tid_mux)
|
|||
sta = ath6kl_find_sta_by_aid(vif->ar, aid);
|
||||
if (sta)
|
||||
aggr_conn = sta->aggr_conn;
|
||||
} else
|
||||
} else {
|
||||
aggr_conn = vif->aggr_cntxt->aggr_conn;
|
||||
}
|
||||
|
||||
if (!aggr_conn)
|
||||
return;
|
||||
|
|
|
@ -236,7 +236,6 @@ static void ath6kl_usb_free_pipe_resources(struct ath6kl_usb_pipe *pipe)
|
|||
break;
|
||||
kfree(urb_context);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
static void ath6kl_usb_cleanup_pipe_resources(struct ath6kl_usb *ar_usb)
|
||||
|
@ -245,7 +244,6 @@ static void ath6kl_usb_cleanup_pipe_resources(struct ath6kl_usb *ar_usb)
|
|||
|
||||
for (i = 0; i < ATH6KL_USB_PIPE_MAX; i++)
|
||||
ath6kl_usb_free_pipe_resources(&ar_usb->pipes[i]);
|
||||
|
||||
}
|
||||
|
||||
static u8 ath6kl_usb_get_logical_pipe_num(struct ath6kl_usb *ar_usb,
|
||||
|
|
|
@ -289,8 +289,9 @@ int ath6kl_wmi_implicit_create_pstream(struct wmi *wmi, u8 if_idx,
|
|||
ath6kl_wmi_determine_user_priority(((u8 *) llc_hdr) +
|
||||
sizeof(struct ath6kl_llc_snap_hdr),
|
||||
layer2_priority);
|
||||
} else
|
||||
} else {
|
||||
usr_pri = layer2_priority & 0x7;
|
||||
}
|
||||
|
||||
/*
|
||||
* Queue the EAPOL frames in the same WMM_AC_VO queue
|
||||
|
@ -359,8 +360,9 @@ int ath6kl_wmi_dot11_hdr_remove(struct wmi *wmi, struct sk_buff *skb)
|
|||
hdr_size = roundup(sizeof(struct ieee80211_qos_hdr),
|
||||
sizeof(u32));
|
||||
skb_pull(skb, hdr_size);
|
||||
} else if (sub_type == cpu_to_le16(IEEE80211_STYPE_DATA))
|
||||
} else if (sub_type == cpu_to_le16(IEEE80211_STYPE_DATA)) {
|
||||
skb_pull(skb, sizeof(struct ieee80211_hdr_3addr));
|
||||
}
|
||||
|
||||
datap = skb->data;
|
||||
llc_hdr = (struct ath6kl_llc_snap_hdr *)(datap);
|
||||
|
@ -936,7 +938,6 @@ ath6kl_regd_find_country_by_rd(u16 regdmn)
|
|||
|
||||
static void ath6kl_wmi_regdomain_event(struct wmi *wmi, u8 *datap, int len)
|
||||
{
|
||||
|
||||
struct ath6kl_wmi_regdomain *ev;
|
||||
struct country_code_to_enum_rd *country = NULL;
|
||||
struct reg_dmn_pair_mapping *regpair = NULL;
|
||||
|
@ -946,10 +947,9 @@ static void ath6kl_wmi_regdomain_event(struct wmi *wmi, u8 *datap, int len)
|
|||
ev = (struct ath6kl_wmi_regdomain *) datap;
|
||||
reg_code = le32_to_cpu(ev->reg_code);
|
||||
|
||||
if ((reg_code >> ATH6KL_COUNTRY_RD_SHIFT) & COUNTRY_ERD_FLAG)
|
||||
if ((reg_code >> ATH6KL_COUNTRY_RD_SHIFT) & COUNTRY_ERD_FLAG) {
|
||||
country = ath6kl_regd_find_country((u16) reg_code);
|
||||
else if (!(((u16) reg_code & WORLD_SKU_MASK) == WORLD_SKU_PREFIX)) {
|
||||
|
||||
} else if (!(((u16) reg_code & WORLD_SKU_MASK) == WORLD_SKU_PREFIX)) {
|
||||
regpair = ath6kl_get_regpair((u16) reg_code);
|
||||
country = ath6kl_regd_find_country_by_rd((u16) reg_code);
|
||||
if (regpair)
|
||||
|
@ -1499,7 +1499,6 @@ static int ath6kl_wmi_cac_event_rx(struct wmi *wmi, u8 *datap, int len,
|
|||
|
||||
if ((reply->cac_indication == CAC_INDICATION_ADMISSION_RESP) &&
|
||||
(reply->status_code != IEEE80211_TSPEC_STATUS_ADMISS_ACCEPTED)) {
|
||||
|
||||
ts = (struct ieee80211_tspec_ie *) &(reply->tspec_suggestion);
|
||||
tsinfo = le16_to_cpu(ts->tsinfo);
|
||||
tsid = (tsinfo >> IEEE80211_WMM_IE_TSPEC_TID_SHIFT) &
|
||||
|
@ -1530,7 +1529,6 @@ static int ath6kl_wmi_cac_event_rx(struct wmi *wmi, u8 *datap, int len,
|
|||
* for delete qos stream from AP
|
||||
*/
|
||||
else if (reply->cac_indication == CAC_INDICATION_DELETE) {
|
||||
|
||||
ts = (struct ieee80211_tspec_ie *) &(reply->tspec_suggestion);
|
||||
tsinfo = le16_to_cpu(ts->tsinfo);
|
||||
ts_id = ((tsinfo >> IEEE80211_WMM_IE_TSPEC_TID_SHIFT) &
|
||||
|
@ -2479,7 +2477,6 @@ static int ath6kl_wmi_sync_point(struct wmi *wmi, u8 if_idx)
|
|||
goto free_data_skb;
|
||||
|
||||
for (index = 0; index < num_pri_streams; index++) {
|
||||
|
||||
if (WARN_ON(!data_sync_bufs[index].skb))
|
||||
goto free_data_skb;
|
||||
|
||||
|
@ -2704,7 +2701,6 @@ static void ath6kl_wmi_relinquish_implicit_pstream_credits(struct wmi *wmi)
|
|||
|
||||
for (i = 0; i < WMM_NUM_AC; i++) {
|
||||
if (stream_exist & (1 << i)) {
|
||||
|
||||
/*
|
||||
* FIXME: Is this lock & unlock inside
|
||||
* for loop correct? may need rework.
|
||||
|
@ -2870,8 +2866,9 @@ int ath6kl_wmi_set_host_sleep_mode_cmd(struct wmi *wmi, u8 if_idx,
|
|||
if (host_mode == ATH6KL_HOST_MODE_ASLEEP) {
|
||||
ath6kl_wmi_relinquish_implicit_pstream_credits(wmi);
|
||||
cmd->asleep = cpu_to_le32(1);
|
||||
} else
|
||||
} else {
|
||||
cmd->awake = cpu_to_le32(1);
|
||||
}
|
||||
|
||||
ret = ath6kl_wmi_cmd_send(wmi, if_idx, skb,
|
||||
WMI_SET_HOST_SLEEP_MODE_CMDID,
|
||||
|
|
|
@ -898,7 +898,6 @@ struct wmi_start_scan_cmd {
|
|||
* flags here
|
||||
*/
|
||||
enum wmi_scan_ctrl_flags_bits {
|
||||
|
||||
/* set if can scan in the connect cmd */
|
||||
CONNECT_SCAN_CTRL_FLAGS = 0x01,
|
||||
|
||||
|
|
Loading…
Reference in New Issue