Merge branch 'master' of git://git.kernel.org/pub/scm/linux/kernel/git/linville/wireless-next into for-davem

This commit is contained in:
John W. Linville 2014-05-02 13:47:50 -04:00
Родитель c25aaf814a 48d11dc379
Коммит 406a94d7fa
213 изменённых файлов: 6165 добавлений и 3535 удалений

Просмотреть файл

@ -100,6 +100,7 @@
!Finclude/net/cfg80211.h wdev_priv !Finclude/net/cfg80211.h wdev_priv
!Finclude/net/cfg80211.h ieee80211_iface_limit !Finclude/net/cfg80211.h ieee80211_iface_limit
!Finclude/net/cfg80211.h ieee80211_iface_combination !Finclude/net/cfg80211.h ieee80211_iface_combination
!Finclude/net/cfg80211.h cfg80211_check_combinations
</chapter> </chapter>
<chapter> <chapter>
<title>Actions and configuration</title> <title>Actions and configuration</title>

Просмотреть файл

@ -59,6 +59,8 @@ struct btmrvl_device {
}; };
struct btmrvl_adapter { struct btmrvl_adapter {
void *hw_regs_buf;
u8 *hw_regs;
u32 int_count; u32 int_count;
struct sk_buff_head tx_queue; struct sk_buff_head tx_queue;
u8 psmode; u8 psmode;
@ -140,7 +142,7 @@ void btmrvl_interrupt(struct btmrvl_private *priv);
bool btmrvl_check_evtpkt(struct btmrvl_private *priv, struct sk_buff *skb); bool btmrvl_check_evtpkt(struct btmrvl_private *priv, struct sk_buff *skb);
int btmrvl_process_event(struct btmrvl_private *priv, struct sk_buff *skb); int btmrvl_process_event(struct btmrvl_private *priv, struct sk_buff *skb);
int btmrvl_send_module_cfg_cmd(struct btmrvl_private *priv, int subcmd); int btmrvl_send_module_cfg_cmd(struct btmrvl_private *priv, u8 subcmd);
int btmrvl_send_hscfg_cmd(struct btmrvl_private *priv); int btmrvl_send_hscfg_cmd(struct btmrvl_private *priv);
int btmrvl_enable_ps(struct btmrvl_private *priv); int btmrvl_enable_ps(struct btmrvl_private *priv);
int btmrvl_prepare_command(struct btmrvl_private *priv); int btmrvl_prepare_command(struct btmrvl_private *priv);

Просмотреть файл

@ -24,6 +24,7 @@
#include <net/bluetooth/hci_core.h> #include <net/bluetooth/hci_core.h>
#include "btmrvl_drv.h" #include "btmrvl_drv.h"
#include "btmrvl_sdio.h"
#define VERSION "1.0" #define VERSION "1.0"
@ -201,7 +202,7 @@ static int btmrvl_send_sync_cmd(struct btmrvl_private *priv, u16 opcode,
return 0; return 0;
} }
int btmrvl_send_module_cfg_cmd(struct btmrvl_private *priv, int subcmd) int btmrvl_send_module_cfg_cmd(struct btmrvl_private *priv, u8 subcmd)
{ {
int ret; int ret;
@ -337,10 +338,25 @@ static int btmrvl_tx_pkt(struct btmrvl_private *priv, struct sk_buff *skb)
static void btmrvl_init_adapter(struct btmrvl_private *priv) static void btmrvl_init_adapter(struct btmrvl_private *priv)
{ {
int buf_size;
skb_queue_head_init(&priv->adapter->tx_queue); skb_queue_head_init(&priv->adapter->tx_queue);
priv->adapter->ps_state = PS_AWAKE; priv->adapter->ps_state = PS_AWAKE;
buf_size = ALIGN_SZ(SDIO_BLOCK_SIZE, BTSDIO_DMA_ALIGN);
priv->adapter->hw_regs_buf = kzalloc(buf_size, GFP_KERNEL);
if (!priv->adapter->hw_regs_buf) {
priv->adapter->hw_regs = NULL;
BT_ERR("Unable to allocate buffer for hw_regs.");
} else {
priv->adapter->hw_regs =
(u8 *)ALIGN_ADDR(priv->adapter->hw_regs_buf,
BTSDIO_DMA_ALIGN);
BT_DBG("hw_regs_buf=%p hw_regs=%p",
priv->adapter->hw_regs_buf, priv->adapter->hw_regs);
}
init_waitqueue_head(&priv->adapter->cmd_wait_q); init_waitqueue_head(&priv->adapter->cmd_wait_q);
} }
@ -348,6 +364,7 @@ static void btmrvl_free_adapter(struct btmrvl_private *priv)
{ {
skb_queue_purge(&priv->adapter->tx_queue); skb_queue_purge(&priv->adapter->tx_queue);
kfree(priv->adapter->hw_regs_buf);
kfree(priv->adapter); kfree(priv->adapter);
priv->adapter = NULL; priv->adapter = NULL;

Просмотреть файл

@ -64,6 +64,7 @@ static const struct btmrvl_sdio_card_reg btmrvl_reg_8688 = {
.io_port_0 = 0x00, .io_port_0 = 0x00,
.io_port_1 = 0x01, .io_port_1 = 0x01,
.io_port_2 = 0x02, .io_port_2 = 0x02,
.int_read_to_clear = false,
}; };
static const struct btmrvl_sdio_card_reg btmrvl_reg_87xx = { static const struct btmrvl_sdio_card_reg btmrvl_reg_87xx = {
.cfg = 0x00, .cfg = 0x00,
@ -80,6 +81,7 @@ static const struct btmrvl_sdio_card_reg btmrvl_reg_87xx = {
.io_port_0 = 0x78, .io_port_0 = 0x78,
.io_port_1 = 0x79, .io_port_1 = 0x79,
.io_port_2 = 0x7a, .io_port_2 = 0x7a,
.int_read_to_clear = false,
}; };
static const struct btmrvl_sdio_card_reg btmrvl_reg_88xx = { static const struct btmrvl_sdio_card_reg btmrvl_reg_88xx = {
@ -97,6 +99,9 @@ static const struct btmrvl_sdio_card_reg btmrvl_reg_88xx = {
.io_port_0 = 0xd8, .io_port_0 = 0xd8,
.io_port_1 = 0xd9, .io_port_1 = 0xd9,
.io_port_2 = 0xda, .io_port_2 = 0xda,
.int_read_to_clear = true,
.host_int_rsr = 0x01,
.card_misc_cfg = 0xcc,
}; };
static const struct btmrvl_sdio_device btmrvl_sdio_sd8688 = { static const struct btmrvl_sdio_device btmrvl_sdio_sd8688 = {
@ -667,6 +672,53 @@ static int btmrvl_sdio_process_int_status(struct btmrvl_private *priv)
return 0; return 0;
} }
static int btmrvl_sdio_read_to_clear(struct btmrvl_sdio_card *card, u8 *ireg)
{
struct btmrvl_adapter *adapter = card->priv->adapter;
int ret;
ret = sdio_readsb(card->func, adapter->hw_regs, 0, SDIO_BLOCK_SIZE);
if (ret) {
BT_ERR("sdio_readsb: read int hw_regs failed: %d", ret);
return ret;
}
*ireg = adapter->hw_regs[card->reg->host_intstatus];
BT_DBG("hw_regs[%#x]=%#x", card->reg->host_intstatus, *ireg);
return 0;
}
static int btmrvl_sdio_write_to_clear(struct btmrvl_sdio_card *card, u8 *ireg)
{
int ret;
*ireg = sdio_readb(card->func, card->reg->host_intstatus, &ret);
if (ret) {
BT_ERR("sdio_readb: read int status failed: %d", ret);
return ret;
}
if (*ireg) {
/*
* DN_LD_HOST_INT_STATUS and/or UP_LD_HOST_INT_STATUS
* Clear the interrupt status register and re-enable the
* interrupt.
*/
BT_DBG("int_status = 0x%x", *ireg);
sdio_writeb(card->func, ~(*ireg) & (DN_LD_HOST_INT_STATUS |
UP_LD_HOST_INT_STATUS),
card->reg->host_intstatus, &ret);
if (ret) {
BT_ERR("sdio_writeb: clear int status failed: %d", ret);
return ret;
}
}
return 0;
}
static void btmrvl_sdio_interrupt(struct sdio_func *func) static void btmrvl_sdio_interrupt(struct sdio_func *func)
{ {
struct btmrvl_private *priv; struct btmrvl_private *priv;
@ -684,28 +736,13 @@ static void btmrvl_sdio_interrupt(struct sdio_func *func)
priv = card->priv; priv = card->priv;
ireg = sdio_readb(card->func, card->reg->host_intstatus, &ret); if (card->reg->int_read_to_clear)
if (ret) { ret = btmrvl_sdio_read_to_clear(card, &ireg);
BT_ERR("sdio_readb: read int status register failed"); else
ret = btmrvl_sdio_write_to_clear(card, &ireg);
if (ret)
return; return;
}
if (ireg != 0) {
/*
* DN_LD_HOST_INT_STATUS and/or UP_LD_HOST_INT_STATUS
* Clear the interrupt status register and re-enable the
* interrupt.
*/
BT_DBG("ireg = 0x%x", ireg);
sdio_writeb(card->func, ~(ireg) & (DN_LD_HOST_INT_STATUS |
UP_LD_HOST_INT_STATUS),
card->reg->host_intstatus, &ret);
if (ret) {
BT_ERR("sdio_writeb: clear int status register failed");
return;
}
}
spin_lock_irqsave(&priv->driver_lock, flags); spin_lock_irqsave(&priv->driver_lock, flags);
sdio_ireg |= ireg; sdio_ireg |= ireg;
@ -777,6 +814,30 @@ static int btmrvl_sdio_register_dev(struct btmrvl_sdio_card *card)
BT_DBG("SDIO FUNC%d IO port: 0x%x", func->num, card->ioport); BT_DBG("SDIO FUNC%d IO port: 0x%x", func->num, card->ioport);
if (card->reg->int_read_to_clear) {
reg = sdio_readb(func, card->reg->host_int_rsr, &ret);
if (ret < 0) {
ret = -EIO;
goto release_irq;
}
sdio_writeb(func, reg | 0x3f, card->reg->host_int_rsr, &ret);
if (ret < 0) {
ret = -EIO;
goto release_irq;
}
reg = sdio_readb(func, card->reg->card_misc_cfg, &ret);
if (ret < 0) {
ret = -EIO;
goto release_irq;
}
sdio_writeb(func, reg | 0x10, card->reg->card_misc_cfg, &ret);
if (ret < 0) {
ret = -EIO;
goto release_irq;
}
}
sdio_set_drvdata(func, card); sdio_set_drvdata(func, card);
sdio_release_host(func); sdio_release_host(func);

Просмотреть файл

@ -78,6 +78,9 @@ struct btmrvl_sdio_card_reg {
u8 io_port_0; u8 io_port_0;
u8 io_port_1; u8 io_port_1;
u8 io_port_2; u8 io_port_2;
bool int_read_to_clear;
u8 host_int_rsr;
u8 card_misc_cfg;
}; };
struct btmrvl_sdio_card { struct btmrvl_sdio_card {

Просмотреть файл

@ -55,13 +55,6 @@ struct h4_struct {
struct sk_buff_head txq; struct sk_buff_head txq;
}; };
/* H4 receiver States */
#define H4_W4_PACKET_TYPE 0
#define H4_W4_EVENT_HDR 1
#define H4_W4_ACL_HDR 2
#define H4_W4_SCO_HDR 3
#define H4_W4_DATA 4
/* Initialize protocol */ /* Initialize protocol */
static int h4_open(struct hci_uart *hu) static int h4_open(struct hci_uart *hu)
{ {

Просмотреть файл

@ -1090,7 +1090,8 @@ static int ar5523_set_rts_threshold(struct ieee80211_hw *hw, u32 value)
return ret; return ret;
} }
static void ar5523_flush(struct ieee80211_hw *hw, u32 queues, bool drop) static void ar5523_flush(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
u32 queues, bool drop)
{ {
struct ar5523 *ar = hw->priv; struct ar5523 *ar = hw->priv;

Просмотреть файл

@ -175,7 +175,7 @@ int ath10k_bmi_write_memory(struct ath10k *ar,
return 0; 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; struct bmi_cmd cmd;
union bmi_resp resp; union bmi_resp resp;
@ -184,7 +184,7 @@ int ath10k_bmi_execute(struct ath10k *ar, u32 address, u32 *param)
int ret; int ret;
ath10k_dbg(ATH10K_DBG_BMI, "bmi execute address 0x%x param 0x%x\n", ath10k_dbg(ATH10K_DBG_BMI, "bmi execute address 0x%x param 0x%x\n",
address, *param); address, param);
if (ar->bmi.done_sent) { if (ar->bmi.done_sent) {
ath10k_warn("command disallowed\n"); 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.id = __cpu_to_le32(BMI_EXECUTE);
cmd.execute.addr = __cpu_to_le32(address); 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); ret = ath10k_hif_exchange_bmi_msg(ar, &cmd, cmdlen, &resp, &resplen);
if (ret) { if (ret) {
@ -204,10 +204,13 @@ int ath10k_bmi_execute(struct ath10k *ar, u32 address, u32 *param)
if (resplen < sizeof(resp.execute)) { if (resplen < sizeof(resp.execute)) {
ath10k_warn("invalid execute response length (%d)\n", ath10k_warn("invalid execute response length (%d)\n",
resplen); 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; return 0;
} }

Просмотреть файл

@ -217,7 +217,7 @@ int ath10k_bmi_write_memory(struct ath10k *ar, u32 address,
ret; \ 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_stream_start(struct ath10k *ar, u32 address);
int ath10k_bmi_lz_data(struct ath10k *ar, const void *buffer, u32 length); int ath10k_bmi_lz_data(struct ath10k *ar, const void *buffer, u32 length);
int ath10k_bmi_fast_download(struct ath10k *ar, u32 address, 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, static int ath10k_ce_init_src_ring(struct ath10k *ar,
unsigned int ce_id, unsigned int ce_id,
struct ath10k_ce_pipe *ce_state,
const struct ce_attr *attr) const struct ce_attr *attr)
{ {
struct ath10k_pci *ar_pci = ath10k_pci_priv(ar); struct ath10k_pci *ar_pci = ath10k_pci_priv(ar);
struct ath10k_ce_ring *src_ring; struct ath10k_ce_pipe *ce_state = &ar_pci->ce_states[ce_id];
unsigned int nentries = attr->src_nentries; struct ath10k_ce_ring *src_ring = ce_state->src_ring;
unsigned int ce_nbytes; u32 nentries, ctrl_addr = ath10k_ce_base_address(ce_id);
u32 ctrl_addr = ath10k_ce_base_address(ce_id);
dma_addr_t base_addr;
char *ptr;
nentries = roundup_pow_of_two(nentries); nentries = roundup_pow_of_two(attr->src_nentries);
if (ce_state->src_ring) { memset(src_ring->per_transfer_context, 0,
WARN_ON(ce_state->src_ring->nentries != nentries); nentries * sizeof(*src_ring->per_transfer_context));
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;
src_ring->sw_index = ath10k_ce_src_ring_read_index_get(ar, ctrl_addr); src_ring->sw_index = ath10k_ce_src_ring_read_index_get(ar, ctrl_addr);
src_ring->sw_index &= src_ring->nentries_mask; 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); ath10k_ce_src_ring_write_index_get(ar, ctrl_addr);
src_ring->write_index &= src_ring->nentries_mask; 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 * Legacy platforms that do not support cache
* coherent DMA are unsupported * coherent DMA are unsupported
*/ */
src_ring->base_addr_owner_space_unaligned = src_ring->base_addr_owner_space_unaligned =
pci_alloc_consistent(ar_pci->pdev, dma_alloc_coherent(ar->dev,
(nentries * sizeof(struct ce_desc) + (nentries * sizeof(struct ce_desc) +
CE_DESC_RING_ALIGN), CE_DESC_RING_ALIGN),
&base_addr); &base_addr, GFP_KERNEL);
if (!src_ring->base_addr_owner_space_unaligned) { if (!src_ring->base_addr_owner_space_unaligned) {
kfree(ce_state->src_ring); kfree(src_ring);
ce_state->src_ring = NULL; return ERR_PTR(-ENOMEM);
return -ENOMEM;
} }
src_ring->base_addr_ce_space_unaligned = base_addr; 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) + kmalloc((nentries * sizeof(struct ce_desc) +
CE_DESC_RING_ALIGN), GFP_KERNEL); CE_DESC_RING_ALIGN), GFP_KERNEL);
if (!src_ring->shadow_base_unaligned) { if (!src_ring->shadow_base_unaligned) {
pci_free_consistent(ar_pci->pdev, dma_free_coherent(ar->dev,
(nentries * sizeof(struct ce_desc) + (nentries * sizeof(struct ce_desc) +
CE_DESC_RING_ALIGN), CE_DESC_RING_ALIGN),
src_ring->base_addr_owner_space, src_ring->base_addr_owner_space,
src_ring->base_addr_ce_space); src_ring->base_addr_ce_space);
kfree(ce_state->src_ring); kfree(src_ring);
ce_state->src_ring = NULL; return ERR_PTR(-ENOMEM);
return -ENOMEM;
} }
src_ring->shadow_base = PTR_ALIGN( src_ring->shadow_base = PTR_ALIGN(
src_ring->shadow_base_unaligned, src_ring->shadow_base_unaligned,
CE_DESC_RING_ALIGN); CE_DESC_RING_ALIGN);
ath10k_ce_src_ring_base_addr_set(ar, ctrl_addr, return src_ring;
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;
} }
static int ath10k_ce_init_dest_ring(struct ath10k *ar, static struct ath10k_ce_ring *
unsigned int ce_id, ath10k_ce_alloc_dest_ring(struct ath10k *ar, unsigned int ce_id,
struct ath10k_ce_pipe *ce_state, const struct ce_attr *attr)
const struct ce_attr *attr)
{ {
struct ath10k_pci *ar_pci = ath10k_pci_priv(ar);
struct ath10k_ce_ring *dest_ring; struct ath10k_ce_ring *dest_ring;
unsigned int nentries = attr->dest_nentries; u32 nentries;
unsigned int ce_nbytes;
u32 ctrl_addr = ath10k_ce_base_address(ce_id);
dma_addr_t base_addr; 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) { dest_ring = kzalloc(sizeof(*dest_ring) +
WARN_ON(ce_state->dest_ring->nentries != nentries); (nentries *
return 0; 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 = nentries;
dest_ring->nentries_mask = nentries - 1; 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 * Legacy platforms that do not support cache
* coherent DMA are unsupported * coherent DMA are unsupported
*/ */
dest_ring->base_addr_owner_space_unaligned = dest_ring->base_addr_owner_space_unaligned =
pci_alloc_consistent(ar_pci->pdev, dma_alloc_coherent(ar->dev,
(nentries * sizeof(struct ce_desc) + (nentries * sizeof(struct ce_desc) +
CE_DESC_RING_ALIGN), CE_DESC_RING_ALIGN),
&base_addr); &base_addr, GFP_KERNEL);
if (!dest_ring->base_addr_owner_space_unaligned) { if (!dest_ring->base_addr_owner_space_unaligned) {
kfree(ce_state->dest_ring); kfree(dest_ring);
ce_state->dest_ring = NULL; return ERR_PTR(-ENOMEM);
return -ENOMEM;
} }
dest_ring->base_addr_ce_space_unaligned = base_addr; 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, dest_ring->base_addr_ce_space_unaligned,
CE_DESC_RING_ALIGN); CE_DESC_RING_ALIGN);
ath10k_ce_dest_ring_base_addr_set(ar, ctrl_addr, return dest_ring;
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;
} }
/* /*
@ -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 * initialization. It may be that only one side or the other is
* initialized by software/firmware. * initialized by software/firmware.
*/ */
struct ath10k_ce_pipe *ath10k_ce_init(struct ath10k *ar, int ath10k_ce_init_pipe(struct ath10k *ar, unsigned int ce_id,
unsigned int ce_id, const struct ce_attr *attr)
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; int ret;
/* /*
@ -1074,64 +1056,128 @@ struct ath10k_ce_pipe *ath10k_ce_init(struct ath10k *ar,
ret = ath10k_pci_wake(ar); ret = ath10k_pci_wake(ar);
if (ret) if (ret)
return NULL; return ret;
ce_state = ath10k_ce_init_state(ar, ce_id, attr); spin_lock_bh(&ar_pci->ce_lock);
if (!ce_state) { ce_state->ar = ar;
ath10k_err("Failed to initialize CE state for ID: %d\n", ce_id); ce_state->id = ce_id;
goto out; 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) { 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) { if (ret) {
ath10k_err("Failed to initialize CE src ring for ID: %d (%d)\n", ath10k_err("Failed to initialize CE src ring for ID: %d (%d)\n",
ce_id, ret); ce_id, ret);
ath10k_ce_deinit(ce_state);
ce_state = NULL;
goto out; goto out;
} }
} }
if (attr->dest_nentries) { 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) { if (ret) {
ath10k_err("Failed to initialize CE dest ring for ID: %d (%d)\n", ath10k_err("Failed to initialize CE dest ring for ID: %d (%d)\n",
ce_id, ret); ce_id, ret);
ath10k_ce_deinit(ce_state);
ce_state = NULL;
goto out; goto out;
} }
} }
out: out:
ath10k_pci_sleep(ar); 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_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) { if (ce_state->src_ring) {
kfree(ce_state->src_ring->shadow_base_unaligned); kfree(ce_state->src_ring->shadow_base_unaligned);
pci_free_consistent(ar_pci->pdev, dma_free_coherent(ar->dev,
(ce_state->src_ring->nentries * (ce_state->src_ring->nentries *
sizeof(struct ce_desc) + sizeof(struct ce_desc) +
CE_DESC_RING_ALIGN), CE_DESC_RING_ALIGN),
ce_state->src_ring->base_addr_owner_space, ce_state->src_ring->base_addr_owner_space,
ce_state->src_ring->base_addr_ce_space); ce_state->src_ring->base_addr_ce_space);
kfree(ce_state->src_ring); kfree(ce_state->src_ring);
} }
if (ce_state->dest_ring) { if (ce_state->dest_ring) {
pci_free_consistent(ar_pci->pdev, dma_free_coherent(ar->dev,
(ce_state->dest_ring->nentries * (ce_state->dest_ring->nentries *
sizeof(struct ce_desc) + sizeof(struct ce_desc) +
CE_DESC_RING_ALIGN), CE_DESC_RING_ALIGN),
ce_state->dest_ring->base_addr_owner_space, ce_state->dest_ring->base_addr_owner_space,
ce_state->dest_ring->base_addr_ce_space); ce_state->dest_ring->base_addr_ce_space);
kfree(ce_state->dest_ring); kfree(ce_state->dest_ring);
} }

Просмотреть файл

@ -104,7 +104,8 @@ struct ath10k_ce_ring {
void *shadow_base_unaligned; void *shadow_base_unaligned;
struct ce_desc *shadow_base; struct ce_desc *shadow_base;
void **per_transfer_context; /* keep last */
void *per_transfer_context[0];
}; };
struct ath10k_ce_pipe { struct ath10k_ce_pipe {
@ -210,10 +211,12 @@ int ath10k_ce_completed_send_next(struct ath10k_ce_pipe *ce_state,
/*==================CE Engine Initialization=======================*/ /*==================CE Engine Initialization=======================*/
/* Initialize an instance of a CE */ int ath10k_ce_init_pipe(struct ath10k *ar, unsigned int ce_id,
struct ath10k_ce_pipe *ath10k_ce_init(struct ath10k *ar, const struct ce_attr *attr);
unsigned int ce_id, void ath10k_ce_deinit_pipe(struct ath10k *ar, unsigned int ce_id);
const struct ce_attr *attr); 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=======================*/ /*==================CE Engine Shutdown=======================*/
/* /*
@ -236,8 +239,6 @@ int ath10k_ce_cancel_send_next(struct ath10k_ce_pipe *ce_state,
unsigned int *nbytesp, unsigned int *nbytesp,
unsigned int *transfer_idp); unsigned int *transfer_idp);
void ath10k_ce_deinit(struct ath10k_ce_pipe *ce_state);
/*==================CE Interrupt Handlers====================*/ /*==================CE Interrupt Handlers====================*/
void ath10k_ce_per_engine_service_any(struct ath10k *ar); void ath10k_ce_per_engine_service_any(struct ath10k *ar);
void ath10k_ce_per_engine_service(struct ath10k *ar, unsigned int ce_id); void ath10k_ce_per_engine_service(struct ath10k *ar, unsigned int ce_id);

Просмотреть файл

@ -249,30 +249,40 @@ exit:
static int ath10k_download_and_run_otp(struct ath10k *ar) static int ath10k_download_and_run_otp(struct ath10k *ar)
{ {
u32 address = ar->hw_params.patch_load_addr; u32 result, address = ar->hw_params.patch_load_addr;
u32 exec_param;
int ret; int ret;
/* OTP is optional */ /* 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; 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); ret = ath10k_bmi_fast_download(ar, address, ar->otp_data, ar->otp_len);
if (ret) { if (ret) {
ath10k_err("could not write otp (%d)\n", ret); ath10k_err("could not write otp (%d)\n", ret);
goto exit; return ret;
} }
exec_param = 0; ret = ath10k_bmi_execute(ar, address, 0, &result);
ret = ath10k_bmi_execute(ar, address, &exec_param);
if (ret) { if (ret) {
ath10k_err("could not execute otp (%d)\n", ret); ath10k_err("could not execute otp (%d)\n", ret);
goto exit; return ret;
} }
exit: ath10k_dbg(ATH10K_DBG_BOOT, "boot otp execute result %d\n", result);
return ret;
if (result != 0) {
ath10k_err("otp calibration failed: %d", result);
return -EINVAL;
}
return 0;
} }
static int ath10k_download_fw(struct ath10k *ar) 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) */ /* first fetch the firmware file (firmware-*.bin) */
ar->firmware = ath10k_fetch_fw_file(ar, ar->hw_params.fw.dir, name); ar->firmware = ath10k_fetch_fw_file(ar, ar->hw_params.fw.dir, name);
if (IS_ERR(ar->firmware)) { if (IS_ERR(ar->firmware)) {
ath10k_err("Could not fetch firmware file '%s': %ld\n", ath10k_err("could not fetch firmware file '%s/%s': %ld\n",
name, PTR_ERR(ar->firmware)); ar->hw_params.fw.dir, name, PTR_ERR(ar->firmware));
return 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; magic_len = strlen(ATH10K_FIRMWARE_MAGIC) + 1;
if (len < magic_len) { if (len < magic_len) {
ath10k_err("firmware image too small to contain magic: %zu\n", ath10k_err("firmware file '%s/%s' too small to contain magic: %zu\n",
len); ar->hw_params.fw.dir, name, len);
ret = -EINVAL; ret = -EINVAL;
goto err; goto err;
} }
if (memcmp(data, ATH10K_FIRMWARE_MAGIC, magic_len) != 0) { if (memcmp(data, ATH10K_FIRMWARE_MAGIC, magic_len) != 0) {
ath10k_err("Invalid firmware magic\n"); ath10k_err("invalid firmware magic\n");
ret = -EINVAL; ret = -EINVAL;
goto err; goto err;
} }
@ -430,7 +440,7 @@ static int ath10k_core_fetch_firmware_api_n(struct ath10k *ar, const char *name)
data += sizeof(*hdr); data += sizeof(*hdr);
if (len < ie_len) { 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); ie_id, len, ie_len);
ret = -EINVAL; ret = -EINVAL;
goto err; 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) { if (!ar->firmware_data || !ar->firmware_len) {
ath10k_warn("No ATH10K_FW_IE_FW_IMAGE found from %s, skipping\n", ath10k_warn("No ATH10K_FW_IE_FW_IMAGE found from '%s/%s', skipping\n",
name); ar->hw_params.fw.dir, name);
ret = -ENOMEDIUM; ret = -ENOMEDIUM;
goto err; 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); ar->hw_params.fw.board);
if (IS_ERR(ar->board)) { if (IS_ERR(ar->board)) {
ret = PTR_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; goto err;
} }
@ -549,19 +561,21 @@ static int ath10k_core_fetch_firmware_files(struct ath10k *ar)
{ {
int ret; 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); ret = ath10k_core_fetch_firmware_api_n(ar, ATH10K_FW_API2_FILE);
if (ret == 0) { if (ret == 0)
ar->fw_api = 2; goto success;
goto out;
} 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); ret = ath10k_core_fetch_firmware_api_1(ar);
if (ret) if (ret)
return ret; return ret;
ar->fw_api = 1; success:
out:
ath10k_dbg(ATH10K_DBG_BOOT, "using fw api %d\n", ar->fw_api); ath10k_dbg(ATH10K_DBG_BOOT, "using fw api %d\n", ar->fw_api);
return 0; return 0;
@ -572,16 +586,22 @@ static int ath10k_init_download_firmware(struct ath10k *ar)
int ret; int ret;
ret = ath10k_download_board_data(ar); ret = ath10k_download_board_data(ar);
if (ret) if (ret) {
ath10k_err("failed to download board data: %d\n", ret);
return ret; return ret;
}
ret = ath10k_download_and_run_otp(ar); ret = ath10k_download_and_run_otp(ar);
if (ret) if (ret) {
ath10k_err("failed to run otp: %d\n", ret);
return ret; return ret;
}
ret = ath10k_download_fw(ar); ret = ath10k_download_fw(ar);
if (ret) if (ret) {
ath10k_err("failed to download firmware: %d\n", ret);
return ret; return ret;
}
return ret; return ret;
} }
@ -835,9 +855,12 @@ int ath10k_core_start(struct ath10k *ar)
INIT_LIST_HEAD(&ar->arvifs); INIT_LIST_HEAD(&ar->arvifs);
if (!test_bit(ATH10K_FLAG_FIRST_BOOT_DONE, &ar->dev_flags)) if (!test_bit(ATH10K_FLAG_FIRST_BOOT_DONE, &ar->dev_flags))
ath10k_info("%s (0x%x) fw %s api %d htt %d.%d\n", ath10k_info("%s (0x%08x, 0x%08x) fw %s api %d htt %d.%d\n",
ar->hw_params.name, ar->target_version, ar->hw_params.name,
ar->hw->wiphy->fw_version, ar->fw_api, ar->target_version,
ar->chip_id,
ar->hw->wiphy->fw_version,
ar->fw_api,
ar->htt.target_version_major, ar->htt.target_version_major,
ar->htt.target_version_minor); ar->htt.target_version_minor);

Просмотреть файл

@ -119,6 +119,7 @@ struct ath10k_peer_stat {
u8 peer_macaddr[ETH_ALEN]; u8 peer_macaddr[ETH_ALEN];
u32 peer_rssi; u32 peer_rssi;
u32 peer_tx_rate; u32 peer_tx_rate;
u32 peer_rx_rate; /* 10x only */
}; };
struct ath10k_target_stats { struct ath10k_target_stats {
@ -130,6 +131,12 @@ struct ath10k_target_stats {
u32 cycle_count; u32 cycle_count;
u32 phy_err_count; u32 phy_err_count;
u32 chan_tx_power; 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 */ /* PDEV TX stats */
s32 comp_queued; s32 comp_queued;
@ -260,6 +267,8 @@ struct ath10k_vif {
u8 fixed_rate; u8 fixed_rate;
u8 fixed_nss; u8 fixed_nss;
u8 force_sgi; u8 force_sgi;
bool use_cts_prot;
int num_legacy_stations;
}; };
struct ath10k_vif_iter { struct ath10k_vif_iter {
@ -419,13 +428,18 @@ struct ath10k {
struct cfg80211_chan_def chandef; struct cfg80211_chan_def chandef;
int free_vdev_map; int free_vdev_map;
bool promisc;
bool monitor;
int monitor_vdev_id; int monitor_vdev_id;
bool monitor_enabled; bool monitor_started;
bool monitor_present;
unsigned int filter_flags; unsigned int filter_flags;
unsigned long dev_flags; unsigned long dev_flags;
u32 dfs_block_radar_events; 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 wmi_pdev_set_wmm_params_arg wmm_params;
struct completion install_key_done; struct completion install_key_done;

Просмотреть файл

@ -161,7 +161,7 @@ void ath10k_debug_read_target_stats(struct ath10k *ar,
u8 *tmp = ev->data; u8 *tmp = ev->data;
struct ath10k_target_stats *stats; struct ath10k_target_stats *stats;
int num_pdev_stats, num_vdev_stats, num_peer_stats; int num_pdev_stats, num_vdev_stats, num_peer_stats;
struct wmi_pdev_stats *ps; struct wmi_pdev_stats_10x *ps;
int i; int i;
spin_lock_bh(&ar->data_lock); 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 */ num_peer_stats = __le32_to_cpu(ev->num_peer_stats); /* 0 or max peers */
if (num_pdev_stats) { 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->ch_noise_floor = __le32_to_cpu(ps->chan_nf);
stats->tx_frame_count = __le32_to_cpu(ps->tx_frame_count); 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->phy_err_drop = __le32_to_cpu(ps->wal.rx.phy_err_drop);
stats->mpdu_errs = __le32_to_cpu(ps->wal.rx.mpdu_errs); 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 */ /* 0 or max vdevs */
@ -243,22 +254,29 @@ void ath10k_debug_read_target_stats(struct ath10k *ar,
} }
if (num_peer_stats) { if (num_peer_stats) {
struct wmi_peer_stats *peer_stats; struct wmi_peer_stats_10x *peer_stats;
struct ath10k_peer_stat *s; struct ath10k_peer_stat *s;
stats->peers = num_peer_stats; stats->peers = num_peer_stats;
for (i = 0; i < num_peer_stats; i++) { 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]; s = &stats->peer_stat[i];
WMI_MAC_ADDR_TO_CHAR_ARRAY(&peer_stats->peer_macaddr, memcpy(s->peer_macaddr, &peer_stats->peer_macaddr.addr,
s->peer_macaddr); ETH_ALEN);
s->peer_rssi = __le32_to_cpu(peer_stats->peer_rssi); s->peer_rssi = __le32_to_cpu(peer_stats->peer_rssi);
s->peer_tx_rate = s->peer_tx_rate =
__le32_to_cpu(peer_stats->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 *ar = file->private_data;
struct ath10k_target_stats *fw_stats; struct ath10k_target_stats *fw_stats;
char *buf = NULL; char *buf = NULL;
unsigned int len = 0, buf_len = 2500; unsigned int len = 0, buf_len = 8000;
ssize_t ret_cnt = 0; ssize_t ret_cnt = 0;
long left; long left;
int i; 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); "Cycle count", fw_stats->cycle_count);
len += scnprintf(buf + len, buf_len - len, "%30s %10u\n", len += scnprintf(buf + len, buf_len - len, "%30s %10u\n",
"PHY error count", fw_stats->phy_err_count); "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, "\n");
len += scnprintf(buf + len, buf_len - len, "%30s\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); "MPDU errors (FCS, MIC, ENC)", fw_stats->mpdu_errs);
len += scnprintf(buf + len, buf_len - len, "\n"); len += scnprintf(buf + len, buf_len - len, "\n");
len += scnprintf(buf + len, buf_len - len, "%30s\n", len += scnprintf(buf + len, buf_len - len, "%30s (%d)\n",
"ath10k PEER stats"); "ath10k PEER stats", fw_stats->peers);
len += scnprintf(buf + len, buf_len - len, "%30s\n\n", 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", len += scnprintf(buf + len, buf_len - len, "%30s %u\n",
"Peer TX rate", "Peer TX rate",
fw_stats->peer_stat[i].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"); len += scnprintf(buf + len, buf_len - len, "\n");
} }
spin_unlock_bh(&ar->data_lock); 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, char __user *user_buf,
size_t count, loff_t *ppos) size_t count, loff_t *ppos)
{ {
const char buf[] = "To simulate firmware crash write the keyword" const char buf[] = "To simulate firmware crash write one of the"
" `crash` to this file.\nThis will force firmware" " keywords to this file:\n `soft` - this will send"
" to report a crash to the host system.\n"; " 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)); 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, static ssize_t ath10k_write_simulate_fw_crash(struct file *file,
const char __user *user_buf, const char __user *user_buf,
size_t count, loff_t *ppos) size_t count, loff_t *ppos)
{ {
struct ath10k *ar = file->private_data; struct ath10k *ar = file->private_data;
char buf[32] = {}; char buf[32];
int ret; int ret;
mutex_lock(&ar->conf_mutex); mutex_lock(&ar->conf_mutex);
simple_write_to_buffer(buf, sizeof(buf) - 1, ppos, user_buf, count); simple_write_to_buffer(buf, sizeof(buf) - 1, ppos, user_buf, count);
if (strcmp(buf, "crash") && strcmp(buf, "crash\n")) {
ret = -EINVAL; /* make sure that buf is null terminated */
goto exit; buf[sizeof(buf) - 1] = 0;
}
if (ar->state != ATH10K_STATE_ON && if (ar->state != ATH10K_STATE_ON &&
ar->state != ATH10K_STATE_RESTARTED) { ar->state != ATH10K_STATE_RESTARTED) {
@ -479,14 +520,30 @@ static ssize_t ath10k_write_simulate_fw_crash(struct file *file,
goto exit; 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 (!strcmp(buf, "soft")) {
if (ret) ath10k_info("simulating soft firmware crash\n");
ath10k_warn("failed to force fw hang (%d)\n", ret); 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) if (ret) {
ret = count; ath10k_warn("failed to simulate firmware crash: %d\n", ret);
goto exit;
}
ret = count;
exit: exit:
mutex_unlock(&ar->conf_mutex); mutex_unlock(&ar->conf_mutex);

Просмотреть файл

@ -157,6 +157,9 @@ int ath10k_htc_send(struct ath10k_htc *htc,
goto err_pull; goto err_pull;
} }
ep->tx_credits -= credits; 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); spin_unlock_bh(&htc->tx_lock);
} }
@ -185,6 +188,9 @@ err_credits:
if (ep->tx_credit_flow_enabled) { if (ep->tx_credit_flow_enabled) {
spin_lock_bh(&htc->tx_lock); spin_lock_bh(&htc->tx_lock);
ep->tx_credits += credits; 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); spin_unlock_bh(&htc->tx_lock);
if (ep->ep_ops.ep_tx_credits) 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) if (report->eid >= ATH10K_HTC_EP_COUNT)
break; break;
ath10k_dbg(ATH10K_DBG_HTC, "ep %d got %d credits\n",
report->eid, report->credits);
ep = &htc->endpoint[report->eid]; ep = &htc->endpoint[report->eid];
ep->tx_credits += report->credits; 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) { if (ep->ep_ops.ep_tx_credits) {
spin_unlock_bh(&htc->tx_lock); spin_unlock_bh(&htc->tx_lock);
ep->ep_ops.ep_tx_credits(htc->ar); ep->ep_ops.ep_tx_credits(htc->ar);

Просмотреть файл

@ -21,6 +21,7 @@
#include <linux/bug.h> #include <linux/bug.h>
#include <linux/interrupt.h> #include <linux/interrupt.h>
#include <linux/dmapool.h> #include <linux/dmapool.h>
#include <net/mac80211.h>
#include "htc.h" #include "htc.h"
#include "rx_desc.h" #include "rx_desc.h"
@ -1172,23 +1173,6 @@ struct htt_peer_unmap_event {
u16 peer_id; 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 ath10k_htt_txbuf {
struct htt_data_tx_desc_frag frags[2]; struct htt_data_tx_desc_frag frags[2];
struct ath10k_htc_hdr htc_hdr; struct ath10k_htc_hdr htc_hdr;
@ -1289,6 +1273,9 @@ struct ath10k_htt {
struct tasklet_struct txrx_compl_task; struct tasklet_struct txrx_compl_task;
struct sk_buff_head tx_compl_q; struct sk_buff_head tx_compl_q;
struct sk_buff_head rx_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 #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, static int ath10k_htt_rx_amsdu_pop(struct ath10k_htt *htt,
u8 **fw_desc, int *fw_desc_len, u8 **fw_desc, int *fw_desc_len,
struct sk_buff **head_msdu, struct sk_buff **head_msdu,
@ -310,7 +311,7 @@ static int ath10k_htt_rx_amsdu_pop(struct ath10k_htt *htt,
if (htt->rx_confused) { if (htt->rx_confused) {
ath10k_warn("htt is confused. refusing rx\n"); ath10k_warn("htt is confused. refusing rx\n");
return 0; return -1;
} }
msdu = *head_msdu = ath10k_htt_rx_netbuf_pop(htt); 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; *tail_msdu = msdu;
if (*head_msdu == NULL)
msdu_chaining = -1;
/* /*
* Don't refill the ring yet. * Don't refill the ring yet.
* *
@ -636,6 +640,190 @@ struct amsdu_subframe_hdr {
__be16 len; __be16 len;
} __packed; } __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) static int ath10k_htt_rx_nwifi_hdrlen(struct ieee80211_hdr *hdr)
{ {
/* nwifi header is padded to 4 bytes. this fixes 4addr rx */ /* 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, 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 htt_rx_desc *rxd;
struct sk_buff *skb = skb_in;
struct sk_buff *first; struct sk_buff *first;
struct sk_buff *skb = info->skb;
enum rx_msdu_decap_format fmt; enum rx_msdu_decap_format fmt;
enum htt_rx_mpdu_encrypt_type enctype; enum htt_rx_mpdu_encrypt_type enctype;
struct ieee80211_hdr *hdr; struct ieee80211_hdr *hdr;
@ -728,24 +917,27 @@ static void ath10k_htt_rx_amsdu(struct ath10k_htt *htt,
break; break;
} }
info->skb = skb; skb_in = skb;
info->encrypt_type = enctype; ath10k_htt_rx_h_protected(htt, rx_status, skb_in, enctype);
skb = skb->next; skb = skb->next;
info->skb->next = NULL; skb_in->next = NULL;
if (skb) 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 /* FIXME: It might be nice to re-assemble the A-MSDU when there's a
* monitor interface active for sniffing purposes. */ * 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 htt_rx_desc *rxd;
struct ieee80211_hdr *hdr; struct ieee80211_hdr *hdr;
enum rx_msdu_decap_format fmt; 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; break;
} }
info->skb = skb; ath10k_htt_rx_h_protected(htt, rx_status, skb, enctype);
info->encrypt_type = enctype;
ath10k_process_rx(htt->ar, info); ath10k_process_rx(htt->ar, rx_status, skb);
}
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;
} }
static int ath10k_htt_rx_get_csum_state(struct sk_buff *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; 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, static void ath10k_htt_rx_handler(struct ath10k_htt *htt,
struct htt_rx_indication *rx) 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_indication_mpdu_range *mpdu_ranges;
struct htt_rx_desc *rxd;
enum htt_rx_mpdu_status status;
struct ieee80211_hdr *hdr; struct ieee80211_hdr *hdr;
int num_mpdu_ranges; int num_mpdu_ranges;
u32 attention;
int fw_desc_len; int fw_desc_len;
u8 *fw_desc; u8 *fw_desc;
bool channel_set;
int i, j; int i, j;
int ret;
lockdep_assert_held(&htt->rx_ring.lock); 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_len = __le16_to_cpu(rx->prefix.fw_rx_desc_bytes);
fw_desc = (u8 *)&rx->fw_desc; 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); HTT_RX_INDICATION_INFO1_NUM_MPDU_RANGES);
mpdu_ranges = htt_rx_ind_get_mpdu_ranges(rx); 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: ", ath10k_dbg_dump(ATH10K_DBG_HTT_DUMP, NULL, "htt rx ind: ",
rx, sizeof(*rx) + rx, sizeof(*rx) +
(sizeof(struct htt_rx_indication_mpdu_range) * (sizeof(struct htt_rx_indication_mpdu_range) *
num_mpdu_ranges)); num_mpdu_ranges));
for (i = 0; i < num_mpdu_ranges; i++) { 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++) { for (j = 0; j < mpdu_ranges[i].mpdu_count; j++) {
struct sk_buff *msdu_head, *msdu_tail; struct sk_buff *msdu_head, *msdu_tail;
enum htt_rx_mpdu_status status;
int msdu_chaining;
msdu_head = NULL; msdu_head = NULL;
msdu_tail = NULL; msdu_tail = NULL;
msdu_chaining = ath10k_htt_rx_amsdu_pop(htt, ret = ath10k_htt_rx_amsdu_pop(htt,
&fw_desc, &fw_desc,
&fw_desc_len, &fw_desc_len,
&msdu_head, &msdu_head,
&msdu_tail); &msdu_tail);
if (!msdu_head) { if (ret < 0) {
ath10k_warn("htt rx no data!\n"); ath10k_warn("failed to pop amsdu from htt rx ring %d\n",
continue; ret);
}
if (msdu_head->len == 0) {
ath10k_dbg(ATH10K_DBG_HTT,
"htt rx dropping due to zero-len\n");
ath10k_htt_rx_free_msdu_chain(msdu_head); ath10k_htt_rx_free_msdu_chain(msdu_head);
continue; continue;
} }
if (ath10k_htt_rx_has_decrypt_err(msdu_head)) { rxd = container_of((void *)msdu_head->data,
ath10k_dbg(ATH10K_DBG_HTT, struct htt_rx_desc,
"htt rx dropping due to decrypt-err\n"); 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); ath10k_htt_rx_free_msdu_chain(msdu_head);
continue; continue;
} }
status = info.status; if (ret > 0 &&
ath10k_unchain_msdu(msdu_head) < 0) {
/* 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");
ath10k_htt_rx_free_msdu_chain(msdu_head); ath10k_htt_rx_free_msdu_chain(msdu_head);
continue; continue;
} }
if (status != HTT_RX_IND_MPDU_STATUS_OK && if (attention & RX_ATTENTION_FLAGS_FCS_ERR)
status != HTT_RX_IND_MPDU_STATUS_TKIP_MIC_ERR && rx_status->flag |= RX_FLAG_FAILED_FCS_CRC;
status != HTT_RX_IND_MPDU_STATUS_ERR_INV_PEER && else
!htt->ar->monitor_enabled) { rx_status->flag &= ~RX_FLAG_FAILED_FCS_CRC;
ath10k_dbg(ATH10K_DBG_HTT,
"htt rx ignoring frame w/ status %d\n",
status);
ath10k_htt_rx_free_msdu_chain(msdu_head);
continue;
}
if (test_bit(ATH10K_CAC_RUNNING, &htt->ar->dev_flags)) { if (attention & RX_ATTENTION_FLAGS_TKIP_MIC_ERR)
ath10k_dbg(ATH10K_DBG_HTT, rx_status->flag |= RX_FLAG_MMIC_ERROR;
"htt rx CAC running\n"); else
ath10k_htt_rx_free_msdu_chain(msdu_head); rx_status->flag &= ~RX_FLAG_MMIC_ERROR;
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);
hdr = ath10k_htt_rx_skb_get_hdr(msdu_head); hdr = ath10k_htt_rx_skb_get_hdr(msdu_head);
if (ath10k_htt_rx_hdr_is_amsdu(hdr)) if (ath10k_htt_rx_hdr_is_amsdu(hdr))
ath10k_htt_rx_amsdu(htt, &info); ath10k_htt_rx_amsdu(htt, rx_status, msdu_head);
else 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 htt_rx_fragment_indication *frag)
{ {
struct sk_buff *msdu_head, *msdu_tail; struct sk_buff *msdu_head, *msdu_tail;
enum htt_rx_mpdu_encrypt_type enctype;
struct htt_rx_desc *rxd; struct htt_rx_desc *rxd;
enum rx_msdu_decap_format fmt; enum rx_msdu_decap_format fmt;
struct htt_rx_info info = {}; struct ieee80211_rx_status *rx_status = &htt->rx_status;
struct ieee80211_hdr *hdr; struct ieee80211_hdr *hdr;
int msdu_chaining; int ret;
bool tkip_mic_err; bool tkip_mic_err;
bool decrypt_err; bool decrypt_err;
u8 *fw_desc; u8 *fw_desc;
@ -1102,19 +1274,15 @@ static void ath10k_htt_rx_frag_handler(struct ath10k_htt *htt,
msdu_tail = NULL; msdu_tail = NULL;
spin_lock_bh(&htt->rx_ring.lock); spin_lock_bh(&htt->rx_ring.lock);
msdu_chaining = ath10k_htt_rx_amsdu_pop(htt, &fw_desc, &fw_desc_len, ret = ath10k_htt_rx_amsdu_pop(htt, &fw_desc, &fw_desc_len,
&msdu_head, &msdu_tail); &msdu_head, &msdu_tail);
spin_unlock_bh(&htt->rx_ring.lock); spin_unlock_bh(&htt->rx_ring.lock);
ath10k_dbg(ATH10K_DBG_HTT_DUMP, "htt rx frag ahead\n"); ath10k_dbg(ATH10K_DBG_HTT_DUMP, "htt rx frag ahead\n");
if (!msdu_head) { if (ret) {
ath10k_warn("htt rx frag no data\n"); ath10k_warn("failed to pop amsdu from httr rx ring for fragmented rx %d\n",
return; ret);
}
if (msdu_chaining || msdu_head != msdu_tail) {
ath10k_warn("aggregation with fragmentation?!\n");
ath10k_htt_rx_free_msdu_chain(msdu_head); ath10k_htt_rx_free_msdu_chain(msdu_head);
return; return;
} }
@ -1136,57 +1304,54 @@ static void ath10k_htt_rx_frag_handler(struct ath10k_htt *htt,
goto end; goto end;
} }
info.skb = msdu_head; enctype = MS(__le32_to_cpu(rxd->mpdu_start.info0),
info.status = HTT_RX_IND_MPDU_STATUS_OK; RX_MPDU_START_INFO0_ENCRYPT_TYPE);
info.encrypt_type = MS(__le32_to_cpu(rxd->mpdu_start.info0), ath10k_htt_rx_h_protected(htt, rx_status, msdu_head, enctype);
RX_MPDU_START_INFO0_ENCRYPT_TYPE); msdu_head->ip_summed = ath10k_htt_rx_get_csum_state(msdu_head);
info.skb->ip_summed = ath10k_htt_rx_get_csum_state(info.skb);
if (tkip_mic_err) { if (tkip_mic_err)
ath10k_warn("tkip mic error\n"); ath10k_warn("tkip mic error\n");
info.status = HTT_RX_IND_MPDU_STATUS_TKIP_MIC_ERR;
}
if (decrypt_err) { if (decrypt_err) {
ath10k_warn("decryption err in fragmented rx\n"); ath10k_warn("decryption err in fragmented rx\n");
dev_kfree_skb_any(info.skb); dev_kfree_skb_any(msdu_head);
goto end; goto end;
} }
if (info.encrypt_type != HTT_RX_MPDU_ENCRYPT_NONE) { if (enctype != HTT_RX_MPDU_ENCRYPT_NONE) {
hdrlen = ieee80211_hdrlen(hdr->frame_control); 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 */ /* It is more efficient to move the header than the payload */
memmove((void *)info.skb->data + paramlen, memmove((void *)msdu_head->data + paramlen,
(void *)info.skb->data, (void *)msdu_head->data,
hdrlen); hdrlen);
skb_pull(info.skb, paramlen); skb_pull(msdu_head, paramlen);
hdr = (struct ieee80211_hdr *)info.skb->data; hdr = (struct ieee80211_hdr *)msdu_head->data;
} }
/* remove trailing FCS */ /* remove trailing FCS */
trim = 4; trim = 4;
/* remove crypto trailer */ /* 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 */ /* last fragment of TKIP frags has MIC */
if (!ieee80211_has_morefrags(hdr->frame_control) && 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; 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"); 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; 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: ", ath10k_dbg_dump(ATH10K_DBG_HTT_DUMP, NULL, "htt rx frag mpdu: ",
info.skb->data, info.skb->len); msdu_head->data, msdu_head->len);
ath10k_process_rx(htt->ar, &info); ath10k_process_rx(htt->ar, rx_status, msdu_head);
end: end:
if (fw_desc_len > 0) { if (fw_desc_len > 0) {

Просмотреть файл

@ -28,6 +28,7 @@
#define QCA988X_HW_2_0_CHIP_ID_REV 0x2 #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_DIR "ath10k/QCA988X/hw2.0"
#define QCA988X_HW_2_0_FW_FILE "firmware.bin" #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_OTP_FILE "otp.bin"
#define QCA988X_HW_2_0_BOARD_DATA_FILE "board.bin" #define QCA988X_HW_2_0_BOARD_DATA_FILE "board.bin"
#define QCA988X_HW_2_0_PATCH_LOAD_ADDR 0x1234 #define QCA988X_HW_2_0_PATCH_LOAD_ADDR 0x1234

Разница между файлами не показана из-за своего большого размера Загрузить разницу

Просмотреть файл

@ -39,15 +39,27 @@ enum ath10k_pci_irq_mode {
ATH10K_PCI_IRQ_MSI = 2, ATH10K_PCI_IRQ_MSI = 2,
}; };
static unsigned int ath10k_target_ps; enum ath10k_pci_reset_mode {
static unsigned int ath10k_pci_irq_mode = ATH10K_PCI_IRQ_AUTO; ATH10K_PCI_RESET_AUTO = 0,
ATH10K_PCI_RESET_WARM_ONLY = 1,
};
module_param(ath10k_target_ps, uint, 0644); static unsigned int ath10k_pci_target_ps;
MODULE_PARM_DESC(ath10k_target_ps, "Enable ath10k Target (SoC) PS option"); 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_param_named(irq_mode, ath10k_pci_irq_mode, uint, 0644);
MODULE_PARM_DESC(irq_mode, "0: auto, 1: legacy, 2: msi (default: 0)"); 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) #define QCA988X_2_0_DEVICE_ID (0x003c)
static DEFINE_PCI_DEVICE_TABLE(ath10k_pci_id_table) = { 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 * 2) Buffer in DMA-able space
*/ */
orig_nbytes = nbytes; orig_nbytes = nbytes;
data_buf = (unsigned char *)pci_alloc_consistent(ar_pci->pdev, data_buf = (unsigned char *)dma_alloc_coherent(ar->dev,
orig_nbytes, orig_nbytes,
&ce_data_base); &ce_data_base,
GFP_ATOMIC);
if (!data_buf) { if (!data_buf) {
ret = -ENOMEM; ret = -ENOMEM;
@ -442,12 +455,12 @@ done:
__le32_to_cpu(((__le32 *)data_buf)[i]); __le32_to_cpu(((__le32 *)data_buf)[i]);
} }
} else } else
ath10k_dbg(ATH10K_DBG_PCI, "%s failure (0x%x)\n", ath10k_warn("failed to read diag value at 0x%x: %d\n",
__func__, address); address, ret);
if (data_buf) if (data_buf)
pci_free_consistent(ar_pci->pdev, orig_nbytes, dma_free_coherent(ar->dev, orig_nbytes, data_buf,
data_buf, ce_data_base); ce_data_base);
return ret; return ret;
} }
@ -490,9 +503,10 @@ static int ath10k_pci_diag_write_mem(struct ath10k *ar, u32 address,
* 2) Buffer in DMA-able space * 2) Buffer in DMA-able space
*/ */
orig_nbytes = nbytes; orig_nbytes = nbytes;
data_buf = (unsigned char *)pci_alloc_consistent(ar_pci->pdev, data_buf = (unsigned char *)dma_alloc_coherent(ar->dev,
orig_nbytes, orig_nbytes,
&ce_data_base); &ce_data_base,
GFP_ATOMIC);
if (!data_buf) { if (!data_buf) {
ret = -ENOMEM; ret = -ENOMEM;
goto done; goto done;
@ -588,13 +602,13 @@ static int ath10k_pci_diag_write_mem(struct ath10k *ar, u32 address,
done: done:
if (data_buf) { if (data_buf) {
pci_free_consistent(ar_pci->pdev, orig_nbytes, data_buf, dma_free_coherent(ar->dev, orig_nbytes, data_buf,
ce_data_base); ce_data_base);
} }
if (ret != 0) if (ret != 0)
ath10k_dbg(ATH10K_DBG_PCI, "%s failure (0x%x)\n", __func__, ath10k_warn("failed to write diag value at 0x%x: %d\n",
address); address, ret);
return ret; return ret;
} }
@ -803,6 +817,9 @@ unlock:
static u16 ath10k_pci_hif_get_free_queue_number(struct ath10k *ar, u8 pipe) static u16 ath10k_pci_hif_get_free_queue_number(struct ath10k *ar, u8 pipe)
{ {
struct ath10k_pci *ar_pci = ath10k_pci_priv(ar); 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); 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, static void ath10k_pci_hif_send_complete_check(struct ath10k *ar, u8 pipe,
int force) int force)
{ {
ath10k_dbg(ATH10K_DBG_PCI, "pci hif send complete check\n");
if (!force) { if (!force) {
int resources; 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); 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, memcpy(&ar_pci->msg_callbacks_current, callbacks,
sizeof(ar_pci->msg_callbacks_current)); 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; int ret = 0;
ath10k_dbg(ATH10K_DBG_PCI, "pci hif map service\n");
/* polling for received messages not supported */ /* polling for received messages not supported */
*dl_is_polled = 0; *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; 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, (void)ath10k_pci_hif_map_service_to_pipe(ar,
ATH10K_HTC_SVC_ID_RSVD_CTRL, ATH10K_HTC_SVC_ID_RSVD_CTRL,
ul_pipe, ul_pipe,
@ -1098,6 +1121,8 @@ static int ath10k_pci_hif_start(struct ath10k *ar)
struct ath10k_pci *ar_pci = ath10k_pci_priv(ar); struct ath10k_pci *ar_pci = ath10k_pci_priv(ar);
int ret, ret_early; int ret, ret_early;
ath10k_dbg(ATH10K_DBG_BOOT, "boot hif start\n");
ath10k_pci_free_early_irq(ar); ath10k_pci_free_early_irq(ar);
ath10k_pci_kill_tasklet(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) static void ath10k_pci_ce_deinit(struct ath10k *ar)
{ {
struct ath10k_pci *ar_pci = ath10k_pci_priv(ar); int i;
struct ath10k_pci_pipe *pipe_info;
int pipe_num;
for (pipe_num = 0; pipe_num < CE_COUNT; pipe_num++) { for (i = 0; i < CE_COUNT; i++)
pipe_info = &ar_pci->pipe_info[pipe_num]; ath10k_ce_deinit_pipe(ar, i);
if (pipe_info->ce_hdl) {
ath10k_ce_deinit(pipe_info->ce_hdl);
pipe_info->ce_hdl = NULL;
pipe_info->buf_sz = 0;
}
}
} }
static void ath10k_pci_hif_stop(struct ath10k *ar) 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); struct ath10k_pci *ar_pci = ath10k_pci_priv(ar);
int ret; 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); ret = ath10k_ce_disable_interrupts(ar);
if (ret) if (ret)
@ -1697,30 +1714,49 @@ static int ath10k_pci_init_config(struct ath10k *ar)
return 0; 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) static int ath10k_pci_ce_init(struct ath10k *ar)
{ {
struct ath10k_pci *ar_pci = ath10k_pci_priv(ar); struct ath10k_pci *ar_pci = ath10k_pci_priv(ar);
struct ath10k_pci_pipe *pipe_info; struct ath10k_pci_pipe *pipe_info;
const struct ce_attr *attr; const struct ce_attr *attr;
int pipe_num; int pipe_num, ret;
for (pipe_num = 0; pipe_num < CE_COUNT; pipe_num++) { for (pipe_num = 0; pipe_num < CE_COUNT; pipe_num++) {
pipe_info = &ar_pci->pipe_info[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->pipe_num = pipe_num;
pipe_info->hif_ce_state = ar; pipe_info->hif_ce_state = ar;
attr = &host_ce_config_wlan[pipe_num]; attr = &host_ce_config_wlan[pipe_num];
pipe_info->ce_hdl = ath10k_ce_init(ar, pipe_num, attr); ret = ath10k_ce_init_pipe(ar, pipe_num, attr);
if (pipe_info->ce_hdl == NULL) { if (ret) {
ath10k_err("failed to initialize CE for pipe: %d\n", ath10k_err("failed to initialize copy engine pipe %d: %d\n",
pipe_num); pipe_num, ret);
return ret;
/* It is safe to call it here. It checks if ce_hdl is
* valid for each pipe */
ath10k_pci_ce_deinit(ar);
return -1;
} }
if (pipe_num == CE_COUNT - 1) { 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) static void ath10k_pci_fw_interrupt_handler(struct ath10k *ar)
{ {
struct ath10k_pci *ar_pci = ath10k_pci_priv(ar); struct ath10k_pci *ar_pci = ath10k_pci_priv(ar);
u32 fw_indicator_address, fw_indicator; u32 fw_indicator;
ath10k_pci_wake(ar); 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) { if (fw_indicator & FW_IND_EVENT_PENDING) {
/* ACK: clear Target-side pending event */ /* 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); fw_indicator & ~FW_IND_EVENT_PENDING);
if (ar_pci->started) { 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) static int ath10k_pci_warm_reset(struct ath10k *ar)
{ {
struct ath10k_pci *ar_pci = ath10k_pci_priv(ar);
int ret = 0; int ret = 0;
u32 val; 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); ret = ath10k_do_pci_wake(ar);
if (ret) { if (ret) {
@ -1801,7 +1835,7 @@ static int ath10k_pci_warm_reset(struct ath10k *ar)
msleep(100); msleep(100);
/* clear fw indicator */ /* 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 */ /* clear target LF timer interrupts */
val = ath10k_pci_read32(ar, RTC_SOC_BASE_ADDRESS + 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"; irq_mode = "legacy";
if (!test_bit(ATH10K_FLAG_FIRST_BOOT_DONE, &ar->dev_flags)) 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; return 0;
@ -1956,6 +1992,8 @@ static int ath10k_pci_hif_power_up(struct ath10k *ar)
{ {
int ret; int ret;
ath10k_dbg(ATH10K_DBG_BOOT, "boot hif power up\n");
/* /*
* Hardware CUS232 version 2 has some issues with cold reset and the * Hardware CUS232 version 2 has some issues with cold reset and the
* preferred (and safer) way to perform a device reset is through a * 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); ret = __ath10k_pci_hif_power_up(ar, false);
if (ret) { 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); 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); ret = __ath10k_pci_hif_power_up(ar, true);
if (ret) { if (ret) {
ath10k_err("failed to power up target using cold reset too (%d)\n", 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); 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_free_early_irq(ar);
ath10k_pci_kill_tasklet(ar); ath10k_pci_kill_tasklet(ar);
ath10k_pci_deinit_irq(ar); ath10k_pci_deinit_irq(ar);
ath10k_pci_ce_deinit(ar);
ath10k_pci_warm_reset(ar); ath10k_pci_warm_reset(ar);
ath10k_pci_ce_deinit(ar);
if (!test_bit(ATH10K_PCI_FEATURE_SOC_POWER_SAVE, ar_pci->features)) if (!test_bit(ATH10K_PCI_FEATURE_SOC_POWER_SAVE, ar_pci->features))
ath10k_do_pci_sleep(ar); 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) static void ath10k_pci_early_irq_tasklet(unsigned long data)
{ {
struct ath10k *ar = (struct ath10k *)data; struct ath10k *ar = (struct ath10k *)data;
struct ath10k_pci *ar_pci = ath10k_pci_priv(ar);
u32 fw_ind; u32 fw_ind;
int ret; int ret;
@ -2148,9 +2192,9 @@ static void ath10k_pci_early_irq_tasklet(unsigned long data)
return; 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) { 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); fw_ind & ~FW_IND_EVENT_PENDING);
/* Some structures are unavailable during early boot or at /* 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) static int ath10k_pci_wait_for_target_init(struct ath10k *ar)
{ {
struct ath10k_pci *ar_pci = ath10k_pci_priv(ar); struct ath10k_pci *ar_pci = ath10k_pci_priv(ar);
int wait_limit = 300; /* 3 sec */ unsigned long timeout;
int ret; int ret;
u32 val;
ath10k_dbg(ATH10K_DBG_BOOT, "boot waiting target to initialise\n");
ret = ath10k_pci_wake(ar); ret = ath10k_pci_wake(ar);
if (ret) { 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; return ret;
} }
while (wait_limit-- && timeout = jiffies + msecs_to_jiffies(ATH10K_PCI_TARGET_WAIT);
!(ioread32(ar_pci->mem + FW_INDICATOR_ADDRESS) &
FW_IND_INITIALIZED)) { 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) if (ar_pci->num_msi_intrs == 0)
/* Fix potential race by repeating CORE_BASE writes */ /* Fix potential race by repeating CORE_BASE writes */
iowrite32(PCIE_INTR_FIRMWARE_MASK | ath10k_pci_soc_write32(ar, PCIE_INTR_ENABLE_ADDRESS,
PCIE_INTR_CE_MASK_ALL, PCIE_INTR_FIRMWARE_MASK |
ar_pci->mem + (SOC_CORE_BASE_ADDRESS | PCIE_INTR_CE_MASK_ALL);
PCIE_INTR_ENABLE_ADDRESS));
mdelay(10);
}
if (wait_limit < 0) { mdelay(10);
ath10k_err("target stalled\n"); } while (time_before(jiffies, timeout));
ret = -EIO;
if (val == 0xffffffff || !(val & FW_IND_INITIALIZED)) {
ath10k_err("failed to receive initialized event from target: %08x\n",
val);
ret = -ETIMEDOUT;
goto out; goto out;
} }
ath10k_dbg(ATH10K_DBG_BOOT, "boot target initialised\n");
out: out:
ath10k_pci_sleep(ar); ath10k_pci_sleep(ar);
return ret; return ret;
@ -2422,6 +2483,8 @@ static int ath10k_pci_cold_reset(struct ath10k *ar)
int i, ret; int i, ret;
u32 val; u32 val;
ath10k_dbg(ATH10K_DBG_BOOT, "boot cold reset\n");
ret = ath10k_do_pci_wake(ar); ret = ath10k_do_pci_wake(ar);
if (ret) { if (ret) {
ath10k_err("failed to wake up target: %d\n", 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_do_pci_sleep(ar);
ath10k_dbg(ATH10K_DBG_BOOT, "boot cold reset complete\n");
return 0; return 0;
} }
@ -2484,7 +2550,7 @@ static int ath10k_pci_probe(struct pci_dev *pdev,
struct ath10k_pci *ar_pci; struct ath10k_pci *ar_pci;
u32 lcr_val, chip_id; 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); ar_pci = kzalloc(sizeof(*ar_pci), GFP_KERNEL);
if (ar_pci == NULL) if (ar_pci == NULL)
@ -2503,7 +2569,7 @@ static int ath10k_pci_probe(struct pci_dev *pdev,
goto err_ar_pci; goto err_ar_pci;
} }
if (ath10k_target_ps) if (ath10k_pci_target_ps)
set_bit(ATH10K_PCI_FEATURE_SOC_POWER_SAVE, ar_pci->features); set_bit(ATH10K_PCI_FEATURE_SOC_POWER_SAVE, ar_pci->features);
ath10k_pci_dump_features(ar_pci); 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->ar = ar;
ar_pci->fw_indicator_address = FW_INDICATOR_ADDRESS;
atomic_set(&ar_pci->keep_awake_count, 0); atomic_set(&ar_pci->keep_awake_count, 0);
pci_set_drvdata(pdev, ar); pci_set_drvdata(pdev, ar);
@ -2594,16 +2659,24 @@ static int ath10k_pci_probe(struct pci_dev *pdev,
ath10k_do_pci_sleep(ar); 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); ath10k_dbg(ATH10K_DBG_BOOT, "boot pci_mem 0x%p\n", ar_pci->mem);
ret = ath10k_core_register(ar, chip_id); ret = ath10k_core_register(ar, chip_id);
if (ret) { if (ret) {
ath10k_err("failed to register driver core: %d\n", ret); ath10k_err("failed to register driver core: %d\n", ret);
goto err_iomap; goto err_free_ce;
} }
return 0; return 0;
err_free_ce:
ath10k_pci_free_ce(ar);
err_iomap: err_iomap:
pci_iounmap(pdev, mem); pci_iounmap(pdev, mem);
err_master: err_master:
@ -2626,7 +2699,7 @@ static void ath10k_pci_remove(struct pci_dev *pdev)
struct ath10k *ar = pci_get_drvdata(pdev); struct ath10k *ar = pci_get_drvdata(pdev);
struct ath10k_pci *ar_pci; struct ath10k_pci *ar_pci;
ath10k_dbg(ATH10K_DBG_PCI, "%s\n", __func__); ath10k_dbg(ATH10K_DBG_PCI, "pci remove\n");
if (!ar) if (!ar)
return; return;
@ -2639,6 +2712,7 @@ static void ath10k_pci_remove(struct pci_dev *pdev)
tasklet_kill(&ar_pci->msi_fw_err); tasklet_kill(&ar_pci->msi_fw_err);
ath10k_core_unregister(ar); ath10k_core_unregister(ar);
ath10k_pci_free_ce(ar);
pci_iounmap(pdev, ar_pci->mem); pci_iounmap(pdev, ar_pci->mem);
pci_release_region(pdev, BAR_NUM); pci_release_region(pdev, BAR_NUM);
@ -2680,6 +2754,5 @@ module_exit(ath10k_pci_exit);
MODULE_AUTHOR("Qualcomm Atheros"); MODULE_AUTHOR("Qualcomm Atheros");
MODULE_DESCRIPTION("Driver support for Atheros QCA988X PCIe devices"); MODULE_DESCRIPTION("Driver support for Atheros QCA988X PCIe devices");
MODULE_LICENSE("Dual BSD/GPL"); 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_FW_2_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_BOARD_DATA_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; 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 */ /* Copy Engine used for Diagnostic Accesses */
struct ath10k_ce_pipe *ce_diag; struct ath10k_ce_pipe *ce_diag;

Просмотреть файл

@ -100,189 +100,6 @@ exit:
wake_up(&htt->empty_tx_wq); 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, struct ath10k_peer *ath10k_peer_find(struct ath10k *ar, int vdev_id,
const u8 *addr) const u8 *addr)
{ {

Просмотреть файл

@ -21,7 +21,6 @@
void ath10k_txrx_tx_unref(struct ath10k_htt *htt, void ath10k_txrx_tx_unref(struct ath10k_htt *htt,
const struct htt_tx_done *tx_done); 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, struct ath10k_peer *ath10k_peer_find(struct ath10k *ar, int vdev_id,
const u8 *addr); 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; struct sk_buff *bcn;
int ret, vdev_id = 0; int ret, vdev_id = 0;
ath10k_dbg(ATH10K_DBG_MGMT, "WMI_HOST_SWBA_EVENTID\n");
ev = (struct wmi_host_swba_event *)skb->data; ev = (struct wmi_host_swba_event *)skb->data;
map = __le32_to_cpu(ev->vdev_map); map = __le32_to_cpu(ev->vdev_map);
ath10k_dbg(ATH10K_DBG_MGMT, "host swba:\n" ath10k_dbg(ATH10K_DBG_MGMT, "mgmt swba vdev_map 0x%x\n",
"-vdev map 0x%x\n",
ev->vdev_map); ev->vdev_map);
for (; map; map >>= 1, vdev_id++) { 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]; bcn_info = &ev->bcn_info[i];
ath10k_dbg(ATH10K_DBG_MGMT, ath10k_dbg(ATH10K_DBG_MGMT,
"-bcn_info[%d]:\n" "mgmt event bcn_info %d tim_len %d mcast %d changed %d num_ps_pending %d bitmap 0x%08x%08x%08x%08x\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",
i, i,
__le32_to_cpu(bcn_info->tim_info.tim_len), __le32_to_cpu(bcn_info->tim_info.tim_len),
__le32_to_cpu(bcn_info->tim_info.tim_mcast), __le32_to_cpu(bcn_info->tim_info.tim_mcast),
@ -2393,8 +2385,9 @@ int ath10k_wmi_connect_htc_service(struct ath10k *ar)
return 0; return 0;
} }
int ath10k_wmi_pdev_set_regdomain(struct ath10k *ar, u16 rd, u16 rd2g, static int ath10k_wmi_main_pdev_set_regdomain(struct ath10k *ar, u16 rd,
u16 rd5g, u16 ctl2g, u16 ctl5g) u16 rd2g, u16 rd5g, u16 ctl2g,
u16 ctl5g)
{ {
struct wmi_pdev_set_regdomain_cmd *cmd; struct wmi_pdev_set_regdomain_cmd *cmd;
struct sk_buff *skb; 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); 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, int ath10k_wmi_pdev_set_channel(struct ath10k *ar,
const struct wmi_channel_arg *arg) 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); __cpu_to_le32(arg->peer_vht_rates.tx_mcs_set);
ath10k_dbg(ATH10K_DBG_WMI, ath10k_dbg(ATH10K_DBG_WMI,
"wmi peer assoc vdev %d addr %pM\n", "wmi peer assoc vdev %d addr %pM (%s)\n",
arg->vdev_id, arg->addr); arg->vdev_id, arg->addr,
arg->peer_reassoc ? "reassociate" : "new");
return ath10k_wmi_cmd_send(ar, skb, ar->wmi.cmd->peer_assoc_cmdid); return ath10k_wmi_cmd_send(ar, skb, ar->wmi.cmd->peer_assoc_cmdid);
} }

Просмотреть файл

@ -198,16 +198,6 @@ struct wmi_mac_addr {
} __packed; } __packed;
} __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 { struct wmi_cmd_map {
u32 init_cmdid; u32 init_cmdid;
u32 start_scan_cmdid; u32 start_scan_cmdid;
@ -2185,6 +2175,31 @@ struct wmi_pdev_set_regdomain_cmd {
__le32 conformance_test_limit_5G; __le32 conformance_test_limit_5G;
} __packed; } __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 */ /* Command to set/unset chip in quiet mode */
struct wmi_pdev_set_quiet_cmd { struct wmi_pdev_set_quiet_cmd {
/* period in TUs */ /* period in TUs */
@ -2210,6 +2225,19 @@ enum ath10k_protmode {
ATH10K_PROT_RTSCTS = 2, /* RTS-CTS */ 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 { enum wmi_beacon_gen_mode {
WMI_BEACON_STAGGERED_MODE = 0, WMI_BEACON_STAGGERED_MODE = 0,
WMI_BEACON_BURST_MODE = 1 WMI_BEACON_BURST_MODE = 1
@ -2682,6 +2710,9 @@ struct wal_dbg_tx_stats {
/* wal pdev resets */ /* wal pdev resets */
__le32 pdev_resets; __le32 pdev_resets;
/* frames dropped due to non-availability of stateless TIDs */
__le32 stateless_tid_alloc_failure;
__le32 phy_underrun; __le32 phy_underrun;
/* MPDU is more than txop limit */ /* MPDU is more than txop limit */
@ -2738,13 +2769,21 @@ enum wmi_stats_id {
WMI_REQUEST_AP_STAT = 0x02 WMI_REQUEST_AP_STAT = 0x02
}; };
struct wlan_inst_rssi_args {
__le16 cfg_retry_count;
__le16 retry_count;
};
struct wmi_request_stats_cmd { struct wmi_request_stats_cmd {
__le32 stats_id; __le32 stats_id;
/* __le32 vdev_id;
* Space to add parameters like
* peer mac addr /* peer MAC address */
*/ struct wmi_mac_addr peer_macaddr;
/* Instantaneous RSSI arguments */
struct wlan_inst_rssi_args inst_rssi_args;
} __packed; } __packed;
/* Suspend option */ /* Suspend option */
@ -2795,7 +2834,7 @@ struct wmi_stats_event {
* PDEV statistics * PDEV statistics
* TODO: add all PDEV stats here * TODO: add all PDEV stats here
*/ */
struct wmi_pdev_stats { struct wmi_pdev_stats_old {
__le32 chan_nf; /* Channel noise floor */ __le32 chan_nf; /* Channel noise floor */
__le32 tx_frame_count; /* TX frame count */ __le32 tx_frame_count; /* TX frame count */
__le32 rx_frame_count; /* RX 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 */ struct wal_dbg_stats wal; /* WAL dbg stats */
} __packed; } __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 * VDEV statistics
* TODO: add all VDEV stats here * TODO: add all VDEV stats here
@ -2818,12 +2874,19 @@ struct wmi_vdev_stats {
* peer statistics. * peer statistics.
* TODO: add more stats * TODO: add more stats
*/ */
struct wmi_peer_stats { struct wmi_peer_stats_old {
struct wmi_mac_addr peer_macaddr; struct wmi_mac_addr peer_macaddr;
__le32 peer_rssi; __le32 peer_rssi;
__le32 peer_tx_rate; __le32 peer_tx_rate;
} __packed; } __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 { struct wmi_vdev_create_cmd {
__le32 vdev_id; __le32 vdev_id;
__le32 vdev_type; __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_suspend_target(struct ath10k *ar, u32 suspend_opt);
int ath10k_wmi_pdev_resume_target(struct ath10k *ar); int ath10k_wmi_pdev_resume_target(struct ath10k *ar);
int ath10k_wmi_pdev_set_regdomain(struct ath10k *ar, u16 rd, u16 rd2g, 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_pdev_set_param(struct ath10k *ar, u32 id, u32 value);
int ath10k_wmi_cmd_init(struct ath10k *ar); int ath10k_wmi_cmd_init(struct ath10k *ar);
int ath10k_wmi_start_scan(struct ath10k *ar, const struct wmi_start_scan_arg *); int ath10k_wmi_start_scan(struct ath10k *ar, const struct wmi_start_scan_arg *);

Просмотреть файл

@ -3709,8 +3709,8 @@ ath5k_hw_txpower(struct ath5k_hw *ah, struct ieee80211_channel *channel,
AR5K_REG_MS(AR5K_TUNE_MAX_TXPOWER, AR5K_TPC_CHIRP), AR5K_REG_MS(AR5K_TUNE_MAX_TXPOWER, AR5K_TPC_CHIRP),
AR5K_TPC); AR5K_TPC);
} else { } else {
ath5k_hw_reg_write(ah, AR5K_PHY_TXPOWER_RATE_MAX | ath5k_hw_reg_write(ah, AR5K_TUNE_MAX_TXPOWER,
AR5K_TUNE_MAX_TXPOWER, AR5K_PHY_TXPOWER_RATE_MAX); AR5K_PHY_TXPOWER_RATE_MAX);
} }
return 0; return 0;

Просмотреть файл

@ -1,11 +1,19 @@
config ATH6KL config ATH6KL
tristate "Atheros mobile chipsets support" 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 config ATH6KL_SDIO
tristate "Atheros ath6kl SDIO support" tristate "Atheros ath6kl SDIO support"
depends on ATH6KL depends on ATH6KL
depends on MMC depends on MMC
depends on CFG80211
---help--- ---help---
This module adds support for wireless adapters based on This module adds support for wireless adapters based on
Atheros AR6003 and AR6004 chipsets running over SDIO. If you Atheros AR6003 and AR6004 chipsets running over SDIO. If you
@ -17,25 +25,31 @@ config ATH6KL_USB
tristate "Atheros ath6kl USB support" tristate "Atheros ath6kl USB support"
depends on ATH6KL depends on ATH6KL
depends on USB depends on USB
depends on CFG80211
---help--- ---help---
This module adds support for wireless adapters based on This module adds support for wireless adapters based on
Atheros AR6004 chipset running over USB. This is still under Atheros AR6004 chipset and chipsets based on it running over
implementation and it isn't functional. If you choose to USB. If you choose to build it as a module, it will be
build it as a module, it will be called ath6kl_usb. called ath6kl_usb.
config ATH6KL_DEBUG config ATH6KL_DEBUG
bool "Atheros ath6kl debugging" bool "Atheros ath6kl debugging"
depends on ATH6KL depends on ATH6KL
---help--- ---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 config ATH6KL_TRACING
bool "Atheros ath6kl tracing support" bool "Atheros ath6kl tracing support"
depends on ATH6KL depends on ATH6KL
depends on EVENT_TRACING depends on EVENT_TRACING
---help--- ---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. 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 Enabling this makes it possible to change the regdomain in
the firmware. This can be only enabled if regulatory requirements the firmware. This can be only enabled if regulatory requirements
are taken into account. 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, ath6kl_dbg(ATH6KL_DBG_WLAN_CFG,
"added bss %pM to cfg80211\n", bssid); "added bss %pM to cfg80211\n", bssid);
kfree(ie); kfree(ie);
} else } else {
ath6kl_dbg(ATH6KL_DBG_WLAN_CFG, "cfg80211 already has a bss\n"); ath6kl_dbg(ATH6KL_DBG_WLAN_CFG, "cfg80211 already has a bss\n");
}
return bss; return bss;
} }
@ -970,7 +971,6 @@ static int ath6kl_set_probed_ssids(struct ath6kl *ar,
ssid_list[i].flag, ssid_list[i].flag,
ssid_list[i].ssid.ssid_len, ssid_list[i].ssid.ssid_len,
ssid_list[i].ssid.ssid); ssid_list[i].ssid.ssid);
} }
/* Make sure no old entries are left behind */ /* 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. */ /* Configure the patterns that we received from the user. */
for (i = 0; i < wow->n_patterns; i++) { for (i = 0; i < wow->n_patterns; i++) {
/* /*
* Convert given nl80211 specific mask value to equivalent * Convert given nl80211 specific mask value to equivalent
* driver specific mask value and send it to the chip along * 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) { if (p.prwise_crypto_type == 0) {
p.prwise_crypto_type = NONE_CRYPT; p.prwise_crypto_type = NONE_CRYPT;
ath6kl_set_cipher(vif, 0, true); 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); ath6kl_set_cipher(vif, info->crypto.ciphers_pairwise[0], true);
}
switch (info->crypto.cipher_group) { switch (info->crypto.cipher_group) {
case WLAN_CIPHER_SUITE_WEP40: 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) { if (info->inactivity_timeout) {
inactivity_timeout = info->inactivity_timeout; inactivity_timeout = info->inactivity_timeout;
if (ar->hw.flags & ATH6KL_HW_AP_INACTIVITY_MINS) 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(recovery_enable, uint, 0644);
module_param(heart_beat_poll, uint, 0644); module_param(heart_beat_poll, uint, 0644);
MODULE_PARM_DESC(recovery_enable, "Enable recovery from firmware error"); MODULE_PARM_DESC(recovery_enable, "Enable recovery from firmware error");
MODULE_PARM_DESC(heart_beat_poll, "Enable fw error detection periodic" \ MODULE_PARM_DESC(heart_beat_poll,
"polling. This also specifies the polling interval in" \ "Enable fw error detection periodic polling in msecs - Also set recovery_enable for this to be effective");
"msecs. Set reocvery_enable for this to be effective");
void ath6kl_core_tx_complete(struct ath6kl *ar, struct sk_buff *skb) 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_proc_registers *irq_proc_reg,
struct ath6kl_irq_enable_reg *irq_enable_reg) struct ath6kl_irq_enable_reg *irq_enable_reg)
{ {
ath6kl_dbg(ATH6KL_DBG_IRQ, ("<------- Register Table -------->\n")); ath6kl_dbg(ATH6KL_DBG_IRQ, ("<------- Register Table -------->\n"));
if (irq_proc_reg != NULL) { if (irq_proc_reg != NULL) {
@ -219,7 +218,6 @@ void ath6kl_dump_registers(struct ath6kl_device *dev,
"GMBOX lookahead alias 1: 0x%x\n", "GMBOX lookahead alias 1: 0x%x\n",
irq_proc_reg->rx_gmbox_lkahd_alias[1]); irq_proc_reg->rx_gmbox_lkahd_alias[1]);
} }
} }
if (irq_enable_reg != NULL) { if (irq_enable_reg != NULL) {
@ -1396,7 +1394,6 @@ static ssize_t ath6kl_create_qos_write(struct file *file,
const char __user *user_buf, const char __user *user_buf,
size_t count, loff_t *ppos) size_t count, loff_t *ppos)
{ {
struct ath6kl *ar = file->private_data; struct ath6kl *ar = file->private_data;
struct ath6kl_vif *vif; struct ath6kl_vif *vif;
char buf[200]; char buf[200];
@ -1575,7 +1572,6 @@ static ssize_t ath6kl_delete_qos_write(struct file *file,
const char __user *user_buf, const char __user *user_buf,
size_t count, loff_t *ppos) size_t count, loff_t *ppos)
{ {
struct ath6kl *ar = file->private_data; struct ath6kl *ar = file->private_data;
struct ath6kl_vif *vif; struct ath6kl_vif *vif;
char buf[100]; 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_proc_registers *irq_proc_reg,
struct ath6kl_irq_enable_reg *irq_en_reg) struct ath6kl_irq_enable_reg *irq_en_reg)
{ {
} }
static inline void dump_cred_dist_stats(struct htc_target *target) 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; buf = req->virt_dma_buf;
for (i = 0; i < req->scat_entries; i++) { for (i = 0; i < req->scat_entries; i++) {
if (from_dma) if (from_dma)
memcpy(req->scat_list[i].buf, buf, memcpy(req->scat_list[i].buf, buf,
req->scat_list[i].len); 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 + 2]),
le32_to_cpu(regdump_val[i + 3])); le32_to_cpu(regdump_val[i + 3]));
} }
} }
static int ath6kl_hif_proc_dbg_intr(struct ath6kl_device *dev) 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: fail_setup:
return status; return status;
} }

Просмотреть файл

@ -197,9 +197,9 @@ struct hif_scatter_req {
/* bounce buffer for upper layers to copy to/from */ /* bounce buffer for upper layers to copy to/from */
u8 *virt_dma_buf; u8 *virt_dma_buf;
struct hif_scatter_item scat_list[1];
u32 scat_q_depth; u32 scat_q_depth;
struct hif_scatter_item scat_list[0];
}; };
struct ath6kl_irq_proc_registers { 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) if (cur_ep_dist->endpoint == ENDPOINT_0)
continue; 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; cur_ep_dist->cred_norm = cur_ep_dist->cred_per_msg;
else { } else {
/* /*
* For the remaining data endpoints, we assume that * For the remaining data endpoints, we assume that
* each cred_per_msg are the same. We use a simple * 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 = (count * 3) >> 2;
count = max(count, cur_ep_dist->cred_per_msg); count = max(count, cur_ep_dist->cred_per_msg);
cur_ep_dist->cred_norm = count; cur_ep_dist->cred_norm = count;
} }
ath6kl_dbg(ATH6KL_DBG_CREDIT, 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, enum htc_endpoint_id eid, unsigned int len,
int *req_cred) int *req_cred)
{ {
*req_cred = (len > target->tgt_cred_sz) ? *req_cred = (len > target->tgt_cred_sz) ?
DIV_ROUND_UP(len, target->tgt_cred_sz) : 1; 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; unsigned int len;
while (true) { while (true) {
flags = 0; flags = 0;
if (list_empty(&endpoint->txq)) 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]; ac = target->dev->ar->ep2ac_map[endpoint->eid];
while (true) { while (true) {
if (list_empty(&endpoint->txq)) if (list_empty(&endpoint->txq))
break; break;
@ -1190,7 +1186,6 @@ static void ath6kl_htc_mbox_flush_txep(struct htc_target *target,
list_add_tail(&packet->list, &container); list_add_tail(&packet->list, &container);
htc_tx_complete(endpoint, &container); htc_tx_complete(endpoint, &container);
} }
} }
static void ath6kl_htc_flush_txep_all(struct htc_target *target) 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; ep_cb = ep->ep_cb;
for (j = 0; j < n_msg; j++) { for (j = 0; j < n_msg; j++) {
/* /*
* Reset flag, any packets allocated using the * Reset flag, any packets allocated using the
* rx_alloc() API cannot be recycled on * 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; packet = NULL;
else { } else {
packet = list_first_entry(&ep->rx_bufq, packet = list_first_entry(&ep->rx_bufq,
struct htc_packet, list); struct htc_packet, list);
list_del(&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); spin_lock_bh(&target->rx_lock);
for (i = 0; i < msg; i++) { for (i = 0; i < msg; i++) {
htc_hdr = (struct htc_frame_hdr *)&lk_ahds[i]; htc_hdr = (struct htc_frame_hdr *)&lk_ahds[i];
if (htc_hdr->eid >= ENDPOINT_MAX) { 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; lk_ahd = (struct htc_lookahead_report *) record_buf;
if ((lk_ahd->pre_valid == ((~lk_ahd->post_valid) & 0xFF)) && if ((lk_ahd->pre_valid == ((~lk_ahd->post_valid) & 0xFF)) &&
next_lk_ahds) { next_lk_ahds) {
ath6kl_dbg(ATH6KL_DBG_HTC, ath6kl_dbg(ATH6KL_DBG_HTC,
"htc rx lk_ahd found pre_valid 0x%x post_valid 0x%x\n", "htc rx lk_ahd found pre_valid 0x%x post_valid 0x%x\n",
lk_ahd->pre_valid, lk_ahd->post_valid); lk_ahd->pre_valid, lk_ahd->post_valid);
@ -1755,7 +1747,6 @@ static int htc_parse_trailer(struct htc_target *target,
} }
return 0; return 0;
} }
static int htc_proc_trailer(struct htc_target *target, static int htc_proc_trailer(struct htc_target *target,
@ -1776,7 +1767,6 @@ static int htc_proc_trailer(struct htc_target *target,
status = 0; status = 0;
while (len > 0) { while (len > 0) {
if (len < sizeof(struct htc_record_hdr)) { if (len < sizeof(struct htc_record_hdr)) {
status = -ENOMEM; status = -ENOMEM;
break; break;
@ -2098,7 +2088,6 @@ static int ath6kl_htc_rx_fetch(struct htc_target *target,
} }
if (!fetched_pkts) { if (!fetched_pkts) {
packet = list_first_entry(rx_pktq, struct htc_packet, packet = list_first_entry(rx_pktq, struct htc_packet,
list); list);
@ -2173,7 +2162,6 @@ int ath6kl_htc_rxmsg_pending_handler(struct htc_target *target,
look_aheads[0] = msg_look_ahead; look_aheads[0] = msg_look_ahead;
while (true) { while (true) {
/* /*
* First lookahead sets the expected endpoint IDs for all * First lookahead sets the expected endpoint IDs for all
* packets in a bundle. * packets in a bundle.
@ -2825,8 +2813,9 @@ static int ath6kl_htc_reset(struct htc_target *target)
packet->buf = packet->buf_start; packet->buf = packet->buf_start;
packet->endpoint = ENDPOINT_0; packet->endpoint = ENDPOINT_0;
list_add_tail(&packet->list, &target->free_ctrl_rxbuf); list_add_tail(&packet->list, &target->free_ctrl_rxbuf);
} else } else {
list_add_tail(&packet->list, &target->free_ctrl_txbuf); list_add_tail(&packet->list, &target->free_ctrl_txbuf);
}
} }
return 0; return 0;

Просмотреть файл

@ -137,7 +137,6 @@ static void get_htc_packet_credit_based(struct htc_target *target,
credits_required = 0; credits_required = 0;
} else { } else {
if (ep->cred_dist.credits < credits_required) if (ep->cred_dist.credits < credits_required)
break; break;
@ -169,7 +168,6 @@ static void get_htc_packet_credit_based(struct htc_target *target,
/* queue this packet into the caller's queue */ /* queue this packet into the caller's queue */
list_add_tail(&packet->list, queue); list_add_tail(&packet->list, queue);
} }
} }
static void get_htc_packet(struct htc_target *target, 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); list_add(&packet->list, pkt_queue);
break; break;
} }
} }
if (status != 0) { 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, list_for_each_entry_safe(packet, tmp_pkt,
txq, list) { txq, list) {
ath6kl_dbg(ATH6KL_DBG_HTC, ath6kl_dbg(ATH6KL_DBG_HTC,
"%s: Indicat overflowed TX pkts: %p\n", "%s: Indicat overflowed TX pkts: %p\n",
__func__, packet); __func__, packet);
@ -403,7 +399,6 @@ static enum htc_send_queue_result htc_try_send(struct htc_target *target,
list_move_tail(&packet->list, list_move_tail(&packet->list,
&send_queue); &send_queue);
} }
} }
if (list_empty(&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. * enough transmit resources.
*/ */
while (true) { while (true) {
if (get_queue_depth(&ep->txq) == 0) if (get_queue_depth(&ep->txq) == 0)
break; break;
@ -495,8 +489,8 @@ static enum htc_send_queue_result htc_try_send(struct htc_target *target,
} }
spin_lock_bh(&target->tx_lock); spin_lock_bh(&target->tx_lock);
} }
/* done with this endpoint, we can clear the count */ /* done with this endpoint, we can clear the count */
ep->tx_proc_cnt = 0; ep->tx_proc_cnt = 0;
spin_unlock_bh(&target->tx_lock); spin_unlock_bh(&target->tx_lock);
@ -1106,7 +1100,6 @@ free_skb:
dev_kfree_skb(skb); dev_kfree_skb(skb);
return status; return status;
} }
static void htc_flush_rx_queue(struct htc_target *target, 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; tx_alloc = 0;
} else { } else {
tx_alloc = htc_get_credit_alloc(target, conn_req->svc_id); tx_alloc = htc_get_credit_alloc(target, conn_req->svc_id);
if (tx_alloc == 0) { if (tx_alloc == 0) {
status = -ENOMEM; status = -ENOMEM;

Просмотреть файл

@ -1192,7 +1192,6 @@ static int ath6kl_upload_board_file(struct ath6kl *ar)
if (board_ext_address && if (board_ext_address &&
ar->fw_board_len == (board_data_size + board_ext_data_size)) { ar->fw_board_len == (board_data_size + board_ext_data_size)) {
/* write extended board data */ /* write extended board data */
ath6kl_dbg(ATH6KL_DBG_BOOT, ath6kl_dbg(ATH6KL_DBG_BOOT,
"writing extended board data to 0x%x (%d B)\n", "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) static int ath6kl_commit_ch_switch(struct ath6kl_vif *vif, u16 channel)
{ {
struct ath6kl *ar = vif->ar; struct ath6kl *ar = vif->ar;
vif->profile.ch = cpu_to_le16(channel); 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) static void ath6kl_check_ch_switch(struct ath6kl *ar, u16 channel)
{ {
struct ath6kl_vif *vif; struct ath6kl_vif *vif;
int res = 0; 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, cfg80211_michael_mic_failure(vif->ndev, sta->mac,
NL80211_KEYTYPE_PAIRWISE, keyid, NL80211_KEYTYPE_PAIRWISE, keyid,
tsc, GFP_KERNEL); tsc, GFP_KERNEL);
} else } else {
ath6kl_cfg80211_tkip_micerr_event(vif, keyid, ismcast); ath6kl_cfg80211_tkip_micerr_event(vif, keyid, ismcast);
}
} }
static void ath6kl_update_target_stats(struct ath6kl_vif *vif, u8 *ptr, u32 len) 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)) { if (test_bit(CONNECTED, &vif->flags)) {
netif_carrier_on(dev); netif_carrier_on(dev);
netif_wake_queue(dev); netif_wake_queue(dev);
} else } else {
netif_carrier_off(dev); netif_carrier_off(dev);
}
return 0; return 0;
} }
@ -1146,7 +1145,6 @@ static int ath6kl_set_features(struct net_device *dev,
dev->features = features | NETIF_F_RXCSUM; dev->features = features | NETIF_F_RXCSUM;
return err; return err;
} }
} }
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; int i, scat_req_sz, scat_list_sz, size;
u8 *virt_buf; 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; scat_req_sz = sizeof(*s_req) + scat_list_sz;
if (!virt_scat) 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); memcpy(tbuf, buf, len);
bounced = true; bounced = true;
} else } else {
tbuf = buf; tbuf = buf;
}
ret = ath6kl_sdio_io(ar_sdio->func, request, addr, tbuf, len); ret = ath6kl_sdio_io(ar_sdio->func, request, addr, tbuf, len);
if ((request & HIF_READ) && bounced) 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, static void __ath6kl_sdio_write_async(struct ath6kl_sdio *ar_sdio,
struct bus_request *req) struct bus_request *req)
{ {
if (req->scat_req) if (req->scat_req) {
ath6kl_sdio_scat_rw(ar_sdio, req); ath6kl_sdio_scat_rw(ar_sdio, req);
else { } else {
void *context; void *context;
int status; 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); list_add_tail(&s_req->list, &ar_sdio->scat_req);
spin_unlock_bh(&ar_sdio->scat_lock); spin_unlock_bh(&ar_sdio->scat_lock);
} }
/* scatter gather read write request */ /* 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", "hif-scatter: total len: %d scatter entries: %d\n",
scat_req->len, scat_req->scat_entries); 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); status = ath6kl_sdio_scat_rw(ar_sdio, scat_req->busrequest);
else { } else {
spin_lock_bh(&ar_sdio->wr_async_lock); spin_lock_bh(&ar_sdio->wr_async_lock);
list_add_tail(&scat_req->busrequest->list, &ar_sdio->wr_asyncq); list_add_tail(&scat_req->busrequest->list, &ar_sdio->wr_asyncq);
spin_unlock_bh(&ar_sdio->wr_async_lock); 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 || if (ar->suspend_mode == WLAN_POWER_STATE_WOW ||
(!ar->suspend_mode && wow)) { (!ar->suspend_mode && wow)) {
ret = ath6kl_set_sdio_pm_caps(ar); ret = ath6kl_set_sdio_pm_caps(ar);
if (ret) if (ret)
goto cut_pwr; 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 || if (ar->suspend_mode == WLAN_POWER_STATE_DEEP_SLEEP ||
!ar->suspend_mode || try_deepsleep) { !ar->suspend_mode || try_deepsleep) {
flags = sdio_get_host_pm_caps(func); flags = sdio_get_host_pm_caps(func);
if (!(flags & MMC_PM_KEEP_POWER)) if (!(flags & MMC_PM_KEEP_POWER))
goto cut_pwr; goto cut_pwr;
@ -1061,7 +1059,6 @@ static int ath6kl_sdio_bmi_credits(struct ath6kl *ar)
timeout = jiffies + msecs_to_jiffies(BMI_COMMUNICATION_TIMEOUT); timeout = jiffies + msecs_to_jiffies(BMI_COMMUNICATION_TIMEOUT);
while (time_before(jiffies, timeout) && !ar->bmi.cmd_credits) { while (time_before(jiffies, timeout) && !ar->bmi.cmd_credits) {
/* /*
* Hit the credit counter with a 4-byte access, the first byte * Hit the credit counter with a 4-byte access, the first byte
* read will hit the counter and cause a decrement, while the * 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 */ u32 hi_hp_rx_traffic_ratio; /* 0xd8 */
/* test applications flags */ /* test applications flags */
u32 hi_test_apps_related ; /* 0xdc */ u32 hi_test_apps_related; /* 0xdc */
/* location of test script */ /* location of test script */
u32 hi_ota_testscript; /* 0xe0 */ u32 hi_ota_testscript; /* 0xe0 */
/* location of CAL data */ /* location of CAL data */

Просмотреть файл

@ -125,8 +125,9 @@ static bool ath6kl_process_uapsdq(struct ath6kl_sta *conn,
*flags |= WMI_DATA_HDR_FLAGS_UAPSD; *flags |= WMI_DATA_HDR_FLAGS_UAPSD;
spin_unlock_bh(&conn->psq_lock); spin_unlock_bh(&conn->psq_lock);
return false; return false;
} else if (!conn->apsd_info) } else if (!conn->apsd_info) {
return false; return false;
}
if (test_bit(WMM_ENABLED, &vif->flags)) { if (test_bit(WMM_ENABLED, &vif->flags)) {
ether_type = be16_to_cpu(datap->h_proto); ether_type = be16_to_cpu(datap->h_proto);
@ -316,8 +317,9 @@ int ath6kl_control_tx(void *devt, struct sk_buff *skb,
cookie = NULL; cookie = NULL;
ath6kl_err("wmi ctrl ep full, dropping pkt : 0x%p, len:%d\n", ath6kl_err("wmi ctrl ep full, dropping pkt : 0x%p, len:%d\n",
skb, skb->len); skb, skb->len);
} else } else {
cookie = ath6kl_alloc_cookie(ar); cookie = ath6kl_alloc_cookie(ar);
}
if (cookie == NULL) { if (cookie == NULL) {
spin_unlock_bh(&ar->lock); 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); struct ath6kl_vif *vif = netdev_priv(dev);
u32 map_no = 0; u32 map_no = 0;
u16 htc_tag = ATH6KL_DATA_PKT_TAG; 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; bool chk_adhoc_ps_mapping = false;
int ret; int ret;
struct wmi_tx_meta_v2 meta_v2; 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) if (ret)
goto fail_tx; goto fail_tx;
} }
} else } else {
goto fail_tx; goto fail_tx;
}
spin_lock_bh(&ar->lock); spin_lock_bh(&ar->lock);
@ -702,7 +705,6 @@ void ath6kl_tx_complete(struct htc_target *target,
/* reap completed packets */ /* reap completed packets */
while (!list_empty(packet_queue)) { while (!list_empty(packet_queue)) {
packet = list_first_entry(packet_queue, struct htc_packet, packet = list_first_entry(packet_queue, struct htc_packet,
list); list);
list_del(&packet->list); list_del(&packet->list);
@ -1089,8 +1091,9 @@ static void aggr_deque_frms(struct aggr_info_conn *agg_conn, u8 tid,
else else
skb_queue_tail(&rxtid->q, node->skb); skb_queue_tail(&rxtid->q, node->skb);
node->skb = NULL; node->skb = NULL;
} else } else {
stats->num_hole++; stats->num_hole++;
}
rxtid->seq_next = ATH6KL_NEXT_SEQ_NO(rxtid->seq_next); rxtid->seq_next = ATH6KL_NEXT_SEQ_NO(rxtid->seq_next);
idx = AGGR_WIN_IDX(rxtid->seq_next, rxtid->hold_q_sz); 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; return is_queued;
spin_lock_bh(&rxtid->lock); 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) { if (rxtid->hold_q[idx].skb) {
/* /*
* There is a frame in the queue and no * 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; is_apsdq_empty_at_start = is_apsdq_empty;
while ((!is_apsdq_empty) && (num_frames_to_deliver)) { while ((!is_apsdq_empty) && (num_frames_to_deliver)) {
spin_lock_bh(&conn->psq_lock); spin_lock_bh(&conn->psq_lock);
skb = skb_dequeue(&conn->apsdq); skb = skb_dequeue(&conn->apsdq);
is_apsdq_empty = skb_queue_empty(&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) if (!conn)
return; return;
aggr_conn = conn->aggr_conn; aggr_conn = conn->aggr_conn;
} else } else {
aggr_conn = vif->aggr_cntxt->aggr_conn; aggr_conn = vif->aggr_cntxt->aggr_conn;
}
if (aggr_process_recv_frm(aggr_conn, tid, seq_no, if (aggr_process_recv_frm(aggr_conn, tid, seq_no,
is_amsdu, skb)) { is_amsdu, skb)) {
/* aggregation code will handle the skb */ /* aggregation code will handle the skb */
return; return;
} }
} else if (!is_broadcast_ether_addr(datap->h_dest)) } else if (!is_broadcast_ether_addr(datap->h_dest)) {
vif->net_stats.multicast++; vif->net_stats.multicast++;
}
ath6kl_deliver_frames_to_nw_stack(vif->ndev, skb); 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); sta = ath6kl_find_sta_by_aid(vif->ar, aid);
if (sta) if (sta)
aggr_conn = sta->aggr_conn; aggr_conn = sta->aggr_conn;
} else } else {
aggr_conn = vif->aggr_cntxt->aggr_conn; aggr_conn = vif->aggr_cntxt->aggr_conn;
}
if (!aggr_conn) if (!aggr_conn)
return; return;
@ -1766,7 +1771,6 @@ void aggr_conn_init(struct ath6kl_vif *vif, struct aggr_info *aggr_info,
skb_queue_head_init(&rxtid->q); skb_queue_head_init(&rxtid->q);
spin_lock_init(&rxtid->lock); spin_lock_init(&rxtid->lock);
} }
} }
struct aggr_info *aggr_init(struct ath6kl_vif *vif) 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); sta = ath6kl_find_sta_by_aid(vif->ar, aid);
if (sta) if (sta)
aggr_conn = sta->aggr_conn; aggr_conn = sta->aggr_conn;
} else } else {
aggr_conn = vif->aggr_cntxt->aggr_conn; aggr_conn = vif->aggr_cntxt->aggr_conn;
}
if (!aggr_conn) if (!aggr_conn)
return; return;

Просмотреть файл

@ -236,7 +236,6 @@ static void ath6kl_usb_free_pipe_resources(struct ath6kl_usb_pipe *pipe)
break; break;
kfree(urb_context); kfree(urb_context);
} }
} }
static void ath6kl_usb_cleanup_pipe_resources(struct ath6kl_usb *ar_usb) 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++) for (i = 0; i < ATH6KL_USB_PIPE_MAX; i++)
ath6kl_usb_free_pipe_resources(&ar_usb->pipes[i]); ath6kl_usb_free_pipe_resources(&ar_usb->pipes[i]);
} }
static u8 ath6kl_usb_get_logical_pipe_num(struct ath6kl_usb *ar_usb, 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) + ath6kl_wmi_determine_user_priority(((u8 *) llc_hdr) +
sizeof(struct ath6kl_llc_snap_hdr), sizeof(struct ath6kl_llc_snap_hdr),
layer2_priority); layer2_priority);
} else } else {
usr_pri = layer2_priority & 0x7; usr_pri = layer2_priority & 0x7;
}
/* /*
* Queue the EAPOL frames in the same WMM_AC_VO queue * 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), hdr_size = roundup(sizeof(struct ieee80211_qos_hdr),
sizeof(u32)); sizeof(u32));
skb_pull(skb, hdr_size); 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)); skb_pull(skb, sizeof(struct ieee80211_hdr_3addr));
}
datap = skb->data; datap = skb->data;
llc_hdr = (struct ath6kl_llc_snap_hdr *)(datap); 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) static void ath6kl_wmi_regdomain_event(struct wmi *wmi, u8 *datap, int len)
{ {
struct ath6kl_wmi_regdomain *ev; struct ath6kl_wmi_regdomain *ev;
struct country_code_to_enum_rd *country = NULL; struct country_code_to_enum_rd *country = NULL;
struct reg_dmn_pair_mapping *regpair = 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; ev = (struct ath6kl_wmi_regdomain *) datap;
reg_code = le32_to_cpu(ev->reg_code); 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); 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); regpair = ath6kl_get_regpair((u16) reg_code);
country = ath6kl_regd_find_country_by_rd((u16) reg_code); country = ath6kl_regd_find_country_by_rd((u16) reg_code);
if (regpair) 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) && if ((reply->cac_indication == CAC_INDICATION_ADMISSION_RESP) &&
(reply->status_code != IEEE80211_TSPEC_STATUS_ADMISS_ACCEPTED)) { (reply->status_code != IEEE80211_TSPEC_STATUS_ADMISS_ACCEPTED)) {
ts = (struct ieee80211_tspec_ie *) &(reply->tspec_suggestion); ts = (struct ieee80211_tspec_ie *) &(reply->tspec_suggestion);
tsinfo = le16_to_cpu(ts->tsinfo); tsinfo = le16_to_cpu(ts->tsinfo);
tsid = (tsinfo >> IEEE80211_WMM_IE_TSPEC_TID_SHIFT) & 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 * for delete qos stream from AP
*/ */
else if (reply->cac_indication == CAC_INDICATION_DELETE) { else if (reply->cac_indication == CAC_INDICATION_DELETE) {
ts = (struct ieee80211_tspec_ie *) &(reply->tspec_suggestion); ts = (struct ieee80211_tspec_ie *) &(reply->tspec_suggestion);
tsinfo = le16_to_cpu(ts->tsinfo); tsinfo = le16_to_cpu(ts->tsinfo);
ts_id = ((tsinfo >> IEEE80211_WMM_IE_TSPEC_TID_SHIFT) & 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; goto free_data_skb;
for (index = 0; index < num_pri_streams; index++) { for (index = 0; index < num_pri_streams; index++) {
if (WARN_ON(!data_sync_bufs[index].skb)) if (WARN_ON(!data_sync_bufs[index].skb))
goto free_data_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++) { for (i = 0; i < WMM_NUM_AC; i++) {
if (stream_exist & (1 << i)) { if (stream_exist & (1 << i)) {
/* /*
* FIXME: Is this lock & unlock inside * FIXME: Is this lock & unlock inside
* for loop correct? may need rework. * 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) { if (host_mode == ATH6KL_HOST_MODE_ASLEEP) {
ath6kl_wmi_relinquish_implicit_pstream_credits(wmi); ath6kl_wmi_relinquish_implicit_pstream_credits(wmi);
cmd->asleep = cpu_to_le32(1); cmd->asleep = cpu_to_le32(1);
} else } else {
cmd->awake = cpu_to_le32(1); cmd->awake = cpu_to_le32(1);
}
ret = ath6kl_wmi_cmd_send(wmi, if_idx, skb, ret = ath6kl_wmi_cmd_send(wmi, if_idx, skb,
WMI_SET_HOST_SLEEP_MODE_CMDID, WMI_SET_HOST_SLEEP_MODE_CMDID,

Просмотреть файл

@ -898,7 +898,6 @@ struct wmi_start_scan_cmd {
* flags here * flags here
*/ */
enum wmi_scan_ctrl_flags_bits { enum wmi_scan_ctrl_flags_bits {
/* set if can scan in the connect cmd */ /* set if can scan in the connect cmd */
CONNECT_SCAN_CTRL_FLAGS = 0x01, CONNECT_SCAN_CTRL_FLAGS = 0x01,

Просмотреть файл

@ -410,7 +410,7 @@ static const u32 ar9300_2p2_baseband_core[][2] = {
{0x00009e30, 0x06336f77}, {0x00009e30, 0x06336f77},
{0x00009e34, 0x6af6532f}, {0x00009e34, 0x6af6532f},
{0x00009e38, 0x0cc80c00}, {0x00009e38, 0x0cc80c00},
{0x00009e40, 0x0d261820}, {0x00009e40, 0x0d261800},
{0x00009e4c, 0x00001004}, {0x00009e4c, 0x00001004},
{0x00009e50, 0x00ff03f1}, {0x00009e50, 0x00ff03f1},
{0x00009e54, 0x00000000}, {0x00009e54, 0x00000000},

Просмотреть файл

@ -592,7 +592,7 @@ static const u32 ar9331_1p1_baseband_core[][2] = {
{0x00009e30, 0x06336f77}, {0x00009e30, 0x06336f77},
{0x00009e34, 0x6af6532f}, {0x00009e34, 0x6af6532f},
{0x00009e38, 0x0cc80c00}, {0x00009e38, 0x0cc80c00},
{0x00009e40, 0x0d261820}, {0x00009e40, 0x0d261800},
{0x00009e4c, 0x00001004}, {0x00009e4c, 0x00001004},
{0x00009e50, 0x00ff03f1}, {0x00009e50, 0x00ff03f1},
{0x00009fc0, 0x803e4788}, {0x00009fc0, 0x803e4788},

Просмотреть файл

@ -231,7 +231,7 @@ static const u32 ar9331_1p2_baseband_core[][2] = {
{0x00009e30, 0x06336f77}, {0x00009e30, 0x06336f77},
{0x00009e34, 0x6af6532f}, {0x00009e34, 0x6af6532f},
{0x00009e38, 0x0cc80c00}, {0x00009e38, 0x0cc80c00},
{0x00009e40, 0x0d261820}, {0x00009e40, 0x0d261800},
{0x00009e4c, 0x00001004}, {0x00009e4c, 0x00001004},
{0x00009e50, 0x00ff03f1}, {0x00009e50, 0x00ff03f1},
{0x00009fc0, 0x803e4788}, {0x00009fc0, 0x803e4788},

Просмотреть файл

@ -318,7 +318,7 @@ static const u32 ar9340_1p0_baseband_core[][2] = {
{0x00009e30, 0x06336f77}, {0x00009e30, 0x06336f77},
{0x00009e34, 0x6af6532f}, {0x00009e34, 0x6af6532f},
{0x00009e38, 0x0cc80c00}, {0x00009e38, 0x0cc80c00},
{0x00009e40, 0x0d261820}, {0x00009e40, 0x0d261800},
{0x00009e4c, 0x00001004}, {0x00009e4c, 0x00001004},
{0x00009e50, 0x00ff03f1}, {0x00009e50, 0x00ff03f1},
{0x00009e54, 0x00000000}, {0x00009e54, 0x00000000},
@ -348,9 +348,9 @@ static const u32 ar9340_1p0_baseband_core[][2] = {
{0x0000a370, 0x00000000}, {0x0000a370, 0x00000000},
{0x0000a390, 0x00000001}, {0x0000a390, 0x00000001},
{0x0000a394, 0x00000444}, {0x0000a394, 0x00000444},
{0x0000a398, 0x00000000}, {0x0000a398, 0x001f0e0f},
{0x0000a39c, 0x210d0401}, {0x0000a39c, 0x0075393f},
{0x0000a3a0, 0xab9a7144}, {0x0000a3a0, 0xb79f6427},
{0x0000a3a4, 0x00000000}, {0x0000a3a4, 0x00000000},
{0x0000a3a8, 0xaaaaaaaa}, {0x0000a3a8, 0xaaaaaaaa},
{0x0000a3ac, 0x3c466478}, {0x0000a3ac, 0x3c466478},

Просмотреть файл

@ -257,9 +257,9 @@ static const u32 qca953x_1p0_baseband_core[][2] = {
{0x0000a370, 0x00000000}, {0x0000a370, 0x00000000},
{0x0000a390, 0x00000001}, {0x0000a390, 0x00000001},
{0x0000a394, 0x00000444}, {0x0000a394, 0x00000444},
{0x0000a398, 0x1f020503}, {0x0000a398, 0x001f0e0f},
{0x0000a39c, 0x29180c03}, {0x0000a39c, 0x0075393f},
{0x0000a3a0, 0x9a8b6844}, {0x0000a3a0, 0xb79f6427},
{0x0000a3a4, 0x000000ff}, {0x0000a3a4, 0x000000ff},
{0x0000a3a8, 0x6a6a6a6a}, {0x0000a3a8, 0x6a6a6a6a},
{0x0000a3ac, 0x6a6a6a6a}, {0x0000a3ac, 0x6a6a6a6a},

Просмотреть файл

@ -90,7 +90,7 @@ static const u32 ar9580_1p0_baseband_core[][2] = {
{0x00009e30, 0x06336f77}, {0x00009e30, 0x06336f77},
{0x00009e34, 0x6af6532f}, {0x00009e34, 0x6af6532f},
{0x00009e38, 0x0cc80c00}, {0x00009e38, 0x0cc80c00},
{0x00009e40, 0x0d261820}, {0x00009e40, 0x0d261800},
{0x00009e4c, 0x00001004}, {0x00009e4c, 0x00001004},
{0x00009e50, 0x00ff03f1}, {0x00009e50, 0x00ff03f1},
{0x00009e54, 0x00000000}, {0x00009e54, 0x00000000},

Просмотреть файл

@ -114,6 +114,9 @@ int ath_descdma_setup(struct ath_softc *sc, struct ath_descdma *dd,
#define ATH_TXFIFO_DEPTH 8 #define ATH_TXFIFO_DEPTH 8
#define ATH_TX_ERROR 0x01 #define ATH_TX_ERROR 0x01
/* Stop tx traffic 1ms before the GO goes away */
#define ATH_P2P_PS_STOP_TIME 1000
#define IEEE80211_SEQ_SEQ_SHIFT 4 #define IEEE80211_SEQ_SEQ_SHIFT 4
#define IEEE80211_SEQ_MAX 4096 #define IEEE80211_SEQ_MAX 4096
#define IEEE80211_WEP_IVLEN 3 #define IEEE80211_WEP_IVLEN 3
@ -367,11 +370,15 @@ void ath9k_release_buffered_frames(struct ieee80211_hw *hw,
/********/ /********/
struct ath_vif { struct ath_vif {
struct ieee80211_vif *vif;
struct ath_node mcast_node; struct ath_node mcast_node;
int av_bslot; int av_bslot;
bool primary_sta_vif; bool primary_sta_vif;
__le64 tsf_adjust; /* TSF adjustment for staggered beacons */ __le64 tsf_adjust; /* TSF adjustment for staggered beacons */
struct ath_buf *av_bcbuf; struct ath_buf *av_bcbuf;
/* P2P Client */
struct ieee80211_noa_data noa;
}; };
struct ath9k_vif_iter_data { struct ath9k_vif_iter_data {
@ -464,6 +471,8 @@ int ath_update_survey_stats(struct ath_softc *sc);
void ath_update_survey_nf(struct ath_softc *sc, int channel); void ath_update_survey_nf(struct ath_softc *sc, int channel);
void ath9k_queue_reset(struct ath_softc *sc, enum ath_reset_type type); void ath9k_queue_reset(struct ath_softc *sc, enum ath_reset_type type);
void ath_ps_full_sleep(unsigned long data); void ath_ps_full_sleep(unsigned long data);
void ath9k_p2p_ps_timer(void *priv);
void ath9k_update_p2p_ps(struct ath_softc *sc, struct ieee80211_vif *vif);
/**********/ /**********/
/* BTCOEX */ /* BTCOEX */
@ -714,6 +723,9 @@ struct ath_softc {
struct completion paprd_complete; struct completion paprd_complete;
wait_queue_head_t tx_wait; wait_queue_head_t tx_wait;
struct ath_gen_timer *p2p_ps_timer;
struct ath_vif *p2p_ps_vif;
unsigned long driver_data; unsigned long driver_data;
u8 gtt_cnt; u8 gtt_cnt;

Просмотреть файл

@ -589,6 +589,9 @@ static int ath9k_init_softc(u16 devid, struct ath_softc *sc,
if (ret) if (ret)
goto err_btcoex; goto err_btcoex;
sc->p2p_ps_timer = ath_gen_timer_alloc(sc->sc_ah, ath9k_p2p_ps_timer,
NULL, sc, AR_FIRST_NDP_TIMER);
ath9k_cmn_init_crypto(sc->sc_ah); ath9k_cmn_init_crypto(sc->sc_ah);
ath9k_init_misc(sc); ath9k_init_misc(sc);
ath_fill_led_pin(sc); ath_fill_led_pin(sc);
@ -644,13 +647,13 @@ static void ath9k_init_txpower_limits(struct ath_softc *sc)
static const struct ieee80211_iface_limit if_limits[] = { static const struct ieee80211_iface_limit if_limits[] = {
{ .max = 2048, .types = BIT(NL80211_IFTYPE_STATION) | { .max = 2048, .types = BIT(NL80211_IFTYPE_STATION) |
BIT(NL80211_IFTYPE_P2P_CLIENT) |
BIT(NL80211_IFTYPE_WDS) }, BIT(NL80211_IFTYPE_WDS) },
{ .max = 8, .types = { .max = 8, .types =
#ifdef CONFIG_MAC80211_MESH #ifdef CONFIG_MAC80211_MESH
BIT(NL80211_IFTYPE_MESH_POINT) | BIT(NL80211_IFTYPE_MESH_POINT) |
#endif #endif
BIT(NL80211_IFTYPE_AP) | BIT(NL80211_IFTYPE_AP) },
{ .max = 1, .types = BIT(NL80211_IFTYPE_P2P_CLIENT) |
BIT(NL80211_IFTYPE_P2P_GO) }, BIT(NL80211_IFTYPE_P2P_GO) },
}; };
@ -852,6 +855,9 @@ static void ath9k_deinit_softc(struct ath_softc *sc)
{ {
int i = 0; int i = 0;
if (sc->p2p_ps_timer)
ath_gen_timer_free(sc->sc_ah, sc->p2p_ps_timer);
ath9k_deinit_btcoex(sc); ath9k_deinit_btcoex(sc);
for (i = 0; i < ATH9K_NUM_TX_QUEUES; i++) for (i = 0; i < ATH9K_NUM_TX_QUEUES; i++)

Просмотреть файл

@ -261,6 +261,8 @@ static bool ath_complete_reset(struct ath_softc *sc, bool start)
sc->gtt_cnt = 0; sc->gtt_cnt = 0;
ieee80211_wake_queues(sc->hw); ieee80211_wake_queues(sc->hw);
ath9k_p2p_ps_timer(sc);
return true; return true;
} }
@ -1119,6 +1121,8 @@ static int ath9k_add_interface(struct ieee80211_hw *hw,
if (ath9k_uses_beacons(vif->type)) if (ath9k_uses_beacons(vif->type))
ath9k_beacon_assign_slot(sc, vif); ath9k_beacon_assign_slot(sc, vif);
avp->vif = vif;
an->sc = sc; an->sc = sc;
an->sta = NULL; an->sta = NULL;
an->vif = vif; an->vif = vif;
@ -1163,6 +1167,29 @@ static int ath9k_change_interface(struct ieee80211_hw *hw,
return 0; return 0;
} }
static void
ath9k_update_p2p_ps_timer(struct ath_softc *sc, struct ath_vif *avp)
{
struct ath_hw *ah = sc->sc_ah;
s32 tsf, target_tsf;
if (!avp || !avp->noa.has_next_tsf)
return;
ath9k_hw_gen_timer_stop(ah, sc->p2p_ps_timer);
tsf = ath9k_hw_gettsf32(sc->sc_ah);
target_tsf = avp->noa.next_tsf;
if (!avp->noa.absent)
target_tsf -= ATH_P2P_PS_STOP_TIME;
if (target_tsf - tsf < ATH_P2P_PS_STOP_TIME)
target_tsf = tsf + ATH_P2P_PS_STOP_TIME;
ath9k_hw_gen_timer_start(ah, sc->p2p_ps_timer, (u32) target_tsf, 1000000);
}
static void ath9k_remove_interface(struct ieee80211_hw *hw, static void ath9k_remove_interface(struct ieee80211_hw *hw,
struct ieee80211_vif *vif) struct ieee80211_vif *vif)
{ {
@ -1174,6 +1201,13 @@ static void ath9k_remove_interface(struct ieee80211_hw *hw,
mutex_lock(&sc->mutex); mutex_lock(&sc->mutex);
spin_lock_bh(&sc->sc_pcu_lock);
if (avp == sc->p2p_ps_vif) {
sc->p2p_ps_vif = NULL;
ath9k_update_p2p_ps_timer(sc, NULL);
}
spin_unlock_bh(&sc->sc_pcu_lock);
sc->nvifs--; sc->nvifs--;
sc->tx99_vif = NULL; sc->tx99_vif = NULL;
@ -1636,6 +1670,72 @@ static void ath9k_bss_assoc_iter(void *data, u8 *mac, struct ieee80211_vif *vif)
ath9k_set_assoc_state(sc, vif); ath9k_set_assoc_state(sc, vif);
} }
void ath9k_p2p_ps_timer(void *priv)
{
struct ath_softc *sc = priv;
struct ath_vif *avp = sc->p2p_ps_vif;
struct ieee80211_vif *vif;
struct ieee80211_sta *sta;
struct ath_node *an;
u32 tsf;
if (!avp)
return;
tsf = ath9k_hw_gettsf32(sc->sc_ah);
if (!avp->noa.absent)
tsf += ATH_P2P_PS_STOP_TIME;
if (!avp->noa.has_next_tsf ||
avp->noa.next_tsf - tsf > BIT(31))
ieee80211_update_p2p_noa(&avp->noa, tsf);
ath9k_update_p2p_ps_timer(sc, avp);
rcu_read_lock();
vif = avp->vif;
sta = ieee80211_find_sta(vif, vif->bss_conf.bssid);
if (!sta)
goto out;
an = (void *) sta->drv_priv;
if (an->sleeping == !!avp->noa.absent)
goto out;
an->sleeping = avp->noa.absent;
if (an->sleeping)
ath_tx_aggr_sleep(sta, sc, an);
else
ath_tx_aggr_wakeup(sc, an);
out:
rcu_read_unlock();
}
void ath9k_update_p2p_ps(struct ath_softc *sc, struct ieee80211_vif *vif)
{
struct ath_vif *avp = (void *)vif->drv_priv;
unsigned long flags;
u32 tsf;
if (!sc->p2p_ps_timer)
return;
if (vif->type != NL80211_IFTYPE_STATION || !vif->p2p)
return;
sc->p2p_ps_vif = avp;
spin_lock_irqsave(&sc->sc_pm_lock, flags);
if (!(sc->ps_flags & PS_BEACON_SYNC)) {
tsf = ath9k_hw_gettsf32(sc->sc_ah);
ieee80211_parse_p2p_noa(&vif->bss_conf.p2p_noa_attr, &avp->noa, tsf);
ath9k_update_p2p_ps_timer(sc, avp);
}
spin_unlock_irqrestore(&sc->sc_pm_lock, flags);
}
static void ath9k_bss_info_changed(struct ieee80211_hw *hw, static void ath9k_bss_info_changed(struct ieee80211_hw *hw,
struct ieee80211_vif *vif, struct ieee80211_vif *vif,
struct ieee80211_bss_conf *bss_conf, struct ieee80211_bss_conf *bss_conf,
@ -1710,6 +1810,12 @@ static void ath9k_bss_info_changed(struct ieee80211_hw *hw,
} }
} }
if (changed & BSS_CHANGED_P2P_PS) {
spin_lock_bh(&sc->sc_pcu_lock);
ath9k_update_p2p_ps(sc, vif);
spin_unlock_bh(&sc->sc_pcu_lock);
}
if (changed & CHECK_ANI) if (changed & CHECK_ANI)
ath_check_ani(sc); ath_check_ani(sc);
@ -1883,7 +1989,8 @@ static bool ath9k_has_tx_pending(struct ath_softc *sc)
return !!npend; return !!npend;
} }
static void ath9k_flush(struct ieee80211_hw *hw, u32 queues, bool drop) static void ath9k_flush(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
u32 queues, bool drop)
{ {
struct ath_softc *sc = hw->priv; struct ath_softc *sc = hw->priv;
struct ath_hw *ah = sc->sc_ah; struct ath_hw *ah = sc->sc_ah;

Просмотреть файл

@ -539,6 +539,9 @@ static void ath_rx_ps_beacon(struct ath_softc *sc, struct sk_buff *skb)
ath_dbg(common, PS, ath_dbg(common, PS,
"Reconfigure beacon timers based on synchronized timestamp\n"); "Reconfigure beacon timers based on synchronized timestamp\n");
ath9k_set_beacon(sc); ath9k_set_beacon(sc);
if (sc->p2p_ps_vif)
ath9k_update_p2p_ps(sc, sc->p2p_ps_vif->vif);
} }
if (ath_beacon_dtim_pending_cab(skb)) { if (ath_beacon_dtim_pending_cab(skb)) {

Просмотреть файл

@ -1707,7 +1707,9 @@ found:
return 0; return 0;
} }
static void carl9170_op_flush(struct ieee80211_hw *hw, u32 queues, bool drop) static void carl9170_op_flush(struct ieee80211_hw *hw,
struct ieee80211_vif *vif,
u32 queues, bool drop)
{ {
struct ar9170 *ar = hw->priv; struct ar9170 *ar = hw->priv;
unsigned int vid; unsigned int vid;

Просмотреть файл

@ -338,7 +338,7 @@ static irqreturn_t wil6210_irq_misc_thread(int irq, void *cookie)
} }
if (isr) if (isr)
wil_err(wil, "un-handled MISC ISR bits 0x%08x\n", isr); wil_dbg_irq(wil, "un-handled MISC ISR bits 0x%08x\n", isr);
wil->isr_misc = 0; wil->isr_misc = 0;

Просмотреть файл

@ -363,8 +363,8 @@ static int wil_wait_for_fw_ready(struct wil6210_priv *wil)
wil_err(wil, "Firmware not ready\n"); wil_err(wil, "Firmware not ready\n");
return -ETIME; return -ETIME;
} else { } else {
wil_dbg_misc(wil, "FW ready after %d ms\n", wil_info(wil, "FW ready after %d ms. HW version 0x%08x\n",
jiffies_to_msecs(to-left)); jiffies_to_msecs(to-left), wil->hw_version);
} }
return 0; return 0;
} }

Просмотреть файл

@ -74,8 +74,6 @@ static int wil_if_pcie_enable(struct wil6210_priv *wil)
if (rc) if (rc)
goto release_irq; goto release_irq;
wil_info(wil, "HW version: 0x%08x\n", wil->hw_version);
return 0; return 0;
release_irq: release_irq:

Просмотреть файл

@ -91,6 +91,22 @@ void wil_rx_reorder(struct wil6210_priv *wil, struct sk_buff *skb)
spin_lock(&r->reorder_lock); spin_lock(&r->reorder_lock);
/** Due to the race between WMI events, where BACK establishment
* reported, and data Rx, few packets may be pass up before reorder
* buffer get allocated. Catch up by pretending SSN is what we
* see in the 1-st Rx packet
*/
if (r->first_time) {
r->first_time = false;
if (seq != r->head_seq_num) {
wil_err(wil, "Error: 1-st frame with wrong sequence"
" %d, should be %d. Fixing...\n", seq,
r->head_seq_num);
r->head_seq_num = seq;
r->ssn = seq;
}
}
/* frame with out of date sequence number */ /* frame with out of date sequence number */
if (seq_less(seq, r->head_seq_num)) { if (seq_less(seq, r->head_seq_num)) {
dev_kfree_skb(skb); dev_kfree_skb(skb);
@ -162,6 +178,7 @@ struct wil_tid_ampdu_rx *wil_tid_ampdu_rx_alloc(struct wil6210_priv *wil,
r->head_seq_num = ssn; r->head_seq_num = ssn;
r->buf_size = size; r->buf_size = size;
r->stored_mpdu_num = 0; r->stored_mpdu_num = 0;
r->first_time = true;
return r; return r;
} }

Просмотреть файл

@ -35,7 +35,7 @@ static inline u32 WIL_GET_BITS(u32 x, int b0, int b1)
#define WIL6210_MEM_SIZE (2*1024*1024UL) #define WIL6210_MEM_SIZE (2*1024*1024UL)
#define WIL6210_RX_RING_SIZE (128) #define WIL6210_RX_RING_SIZE (128)
#define WIL6210_TX_RING_SIZE (128) #define WIL6210_TX_RING_SIZE (512)
#define WIL6210_MAX_TX_RINGS (24) /* HW limit */ #define WIL6210_MAX_TX_RINGS (24) /* HW limit */
#define WIL6210_MAX_CID (8) /* HW limit */ #define WIL6210_MAX_CID (8) /* HW limit */
#define WIL6210_NAPI_BUDGET (16) /* arbitrary */ #define WIL6210_NAPI_BUDGET (16) /* arbitrary */
@ -301,6 +301,7 @@ struct wil_tid_ampdu_rx {
u16 buf_size; u16 buf_size;
u16 timeout; u16 timeout;
u8 dialog_token; u8 dialog_token;
bool first_time; /* is it 1-st time this buffer used? */
}; };
struct wil6210_stats { struct wil6210_stats {

Просмотреть файл

@ -192,7 +192,7 @@ static int __wmi_send(struct wil6210_priv *wil, u16 cmdid, void *buf, u16 len)
might_sleep(); might_sleep();
if (!test_bit(wil_status_fwready, &wil->status)) { if (!test_bit(wil_status_fwready, &wil->status)) {
wil_err(wil, "FW not ready\n"); wil_err(wil, "WMI: cannot send command while FW not ready\n");
return -EAGAIN; return -EAGAIN;
} }
@ -276,8 +276,8 @@ static void wmi_evt_ready(struct wil6210_priv *wil, int id, void *d, int len)
wil->fw_version = le32_to_cpu(evt->sw_version); wil->fw_version = le32_to_cpu(evt->sw_version);
wil->n_mids = evt->numof_additional_mids; wil->n_mids = evt->numof_additional_mids;
wil_dbg_wmi(wil, "FW ver. %d; MAC %pM; %d MID's\n", wil->fw_version, wil_info(wil, "FW ver. %d; MAC %pM; %d MID's\n", wil->fw_version,
evt->mac, wil->n_mids); evt->mac, wil->n_mids);
if (!is_valid_ether_addr(ndev->dev_addr)) { if (!is_valid_ether_addr(ndev->dev_addr)) {
memcpy(ndev->dev_addr, evt->mac, ETH_ALEN); memcpy(ndev->dev_addr, evt->mac, ETH_ALEN);
@ -290,7 +290,7 @@ static void wmi_evt_ready(struct wil6210_priv *wil, int id, void *d, int len)
static void wmi_evt_fw_ready(struct wil6210_priv *wil, int id, void *d, static void wmi_evt_fw_ready(struct wil6210_priv *wil, int id, void *d,
int len) int len)
{ {
wil_dbg_wmi(wil, "WMI: FW ready\n"); wil_dbg_wmi(wil, "WMI: got FW ready event\n");
set_bit(wil_status_fwready, &wil->status); set_bit(wil_status_fwready, &wil->status);
/* reuse wmi_ready for the firmware ready indication */ /* reuse wmi_ready for the firmware ready indication */
@ -348,7 +348,7 @@ static void wmi_evt_scan_complete(struct wil6210_priv *wil, int id,
{ {
if (wil->scan_request) { if (wil->scan_request) {
struct wmi_scan_complete_event *data = d; struct wmi_scan_complete_event *data = d;
bool aborted = (data->status != 0); bool aborted = (data->status != WMI_SCAN_SUCCESS);
wil_dbg_wmi(wil, "SCAN_COMPLETE(0x%08x)\n", data->status); wil_dbg_wmi(wil, "SCAN_COMPLETE(0x%08x)\n", data->status);
cfg80211_scan_done(wil->scan_request, aborted); cfg80211_scan_done(wil->scan_request, aborted);
@ -802,6 +802,7 @@ int wmi_pcp_start(struct wil6210_priv *wil, int bi, u8 wmi_nettype, u8 chan)
.network_type = wmi_nettype, .network_type = wmi_nettype,
.disable_sec_offload = 1, .disable_sec_offload = 1,
.channel = chan - 1, .channel = chan - 1,
.pcp_max_assoc_sta = WIL6210_MAX_CID,
}; };
struct { struct {
struct wil6210_mbox_hdr_wmi wmi; struct wil6210_mbox_hdr_wmi wmi;

Просмотреть файл

@ -28,7 +28,7 @@
#define __WILOCITY_WMI_H__ #define __WILOCITY_WMI_H__
/* General */ /* General */
#define WILOCITY_MAX_ASSOC_STA (8)
#define WMI_MAC_LEN (6) #define WMI_MAC_LEN (6)
#define WMI_PROX_RANGE_NUM (3) #define WMI_PROX_RANGE_NUM (3)
@ -219,15 +219,6 @@ struct wmi_disconnect_sta_cmd {
__le16 disconnect_reason; __le16 disconnect_reason;
} __packed; } __packed;
/*
* WMI_RECONNECT_CMDID
*/
struct wmi_reconnect_cmd {
u8 channel; /* hint */
u8 reserved;
u8 bssid[WMI_MAC_LEN]; /* mandatory if set */
} __packed;
/* /*
* WMI_SET_PMK_CMDID * WMI_SET_PMK_CMDID
@ -296,11 +287,13 @@ enum wmi_scan_type {
WMI_LONG_SCAN = 0, WMI_LONG_SCAN = 0,
WMI_SHORT_SCAN = 1, WMI_SHORT_SCAN = 1,
WMI_PBC_SCAN = 2, WMI_PBC_SCAN = 2,
WMI_ACTIVE_SCAN = 3,
WMI_DIRECT_SCAN = 4,
}; };
struct wmi_start_scan_cmd { struct wmi_start_scan_cmd {
u8 reserved[8]; u8 direct_scan_mac_addr[6];
u8 reserved[2];
__le32 home_dwell_time; /* Max duration in the home channel(ms) */ __le32 home_dwell_time; /* Max duration in the home channel(ms) */
__le32 force_scan_interval; /* Time interval between scans (ms)*/ __le32 force_scan_interval; /* Time interval between scans (ms)*/
u8 scan_type; /* wmi_scan_type */ u8 scan_type; /* wmi_scan_type */
@ -332,6 +325,7 @@ struct wmi_probed_ssid_cmd {
u8 ssid[WMI_MAX_SSID_LEN]; u8 ssid[WMI_MAX_SSID_LEN];
} __packed; } __packed;
/* /*
* WMI_SET_APPIE_CMDID * WMI_SET_APPIE_CMDID
* Add Application specified IE to a management frame * Add Application specified IE to a management frame
@ -427,7 +421,7 @@ struct wmi_bcon_ctrl_cmd {
__le16 frag_num; __le16 frag_num;
__le64 ss_mask; __le64 ss_mask;
u8 network_type; u8 network_type;
u8 reserved; u8 pcp_max_assoc_sta;
u8 disable_sec_offload; u8 disable_sec_offload;
u8 disable_sec; u8 disable_sec;
} __packed; } __packed;
@ -450,7 +444,7 @@ enum wmi_port_role {
struct wmi_port_allocate_cmd { struct wmi_port_allocate_cmd {
u8 mac[WMI_MAC_LEN]; u8 mac[WMI_MAC_LEN];
u8 port_role; u8 port_role;
u8 midid; u8 mid;
} __packed; } __packed;
/* /*
@ -467,6 +461,7 @@ struct wmi_delete_port_cmd {
enum wmi_discovery_mode { enum wmi_discovery_mode {
WMI_DISCOVERY_MODE_NON_OFFLOAD = 0, WMI_DISCOVERY_MODE_NON_OFFLOAD = 0,
WMI_DISCOVERY_MODE_OFFLOAD = 1, WMI_DISCOVERY_MODE_OFFLOAD = 1,
WMI_DISCOVERY_MODE_PEER2PEER = 2,
}; };
struct wmi_p2p_cfg_cmd { struct wmi_p2p_cfg_cmd {
@ -493,7 +488,8 @@ struct wmi_power_mgmt_cfg_cmd {
*/ */
struct wmi_pcp_start_cmd { struct wmi_pcp_start_cmd {
__le16 bcon_interval; __le16 bcon_interval;
u8 reserved0[10]; u8 pcp_max_assoc_sta;
u8 reserved0[9];
u8 network_type; u8 network_type;
u8 channel; u8 channel;
u8 disable_sec_offload; u8 disable_sec_offload;
@ -857,6 +853,7 @@ enum wmi_event_id {
WMI_RF_MGMT_STATUS_EVENTID = 0x1853, WMI_RF_MGMT_STATUS_EVENTID = 0x1853,
WMI_BF_SM_MGMT_DONE_EVENTID = 0x1838, WMI_BF_SM_MGMT_DONE_EVENTID = 0x1838,
WMI_RX_MGMT_PACKET_EVENTID = 0x1840, WMI_RX_MGMT_PACKET_EVENTID = 0x1840,
WMI_TX_MGMT_PACKET_EVENTID = 0x1841,
/* Performance monitoring events */ /* Performance monitoring events */
WMI_DATA_PORT_OPEN_EVENTID = 0x1860, WMI_DATA_PORT_OPEN_EVENTID = 0x1860,
@ -1040,16 +1037,23 @@ enum wmi_disconnect_reason {
struct wmi_disconnect_event { struct wmi_disconnect_event {
__le16 protocol_reason_status; /* reason code, see 802.11 spec. */ __le16 protocol_reason_status; /* reason code, see 802.11 spec. */
u8 bssid[WMI_MAC_LEN]; /* set if known */ u8 bssid[WMI_MAC_LEN]; /* set if known */
u8 disconnect_reason; /* see wmi_disconnect_reason_e */ u8 disconnect_reason; /* see wmi_disconnect_reason */
u8 assoc_resp_len; u8 assoc_resp_len; /* not in use */
u8 assoc_info[0]; u8 assoc_info[0]; /* not in use */
} __packed; } __packed;
/* /*
* WMI_SCAN_COMPLETE_EVENTID * WMI_SCAN_COMPLETE_EVENTID
*/ */
enum scan_status {
WMI_SCAN_SUCCESS = 0,
WMI_SCAN_FAILED = 1,
WMI_SCAN_ABORTED = 2,
WMI_SCAN_REJECTED = 3,
};
struct wmi_scan_complete_event { struct wmi_scan_complete_event {
__le32 status; __le32 status; /* scan_status */
} __packed; } __packed;
/* /*
@ -1256,6 +1260,14 @@ struct wmi_rx_mgmt_info {
u8 channel; /* From Radio MNGR */ u8 channel; /* From Radio MNGR */
} __packed; } __packed;
/*
* WMI_TX_MGMT_PACKET_EVENTID
*/
struct wmi_tx_mgmt_packet_event {
u8 payload[0];
} __packed;
struct wmi_rx_mgmt_packet_event { struct wmi_rx_mgmt_packet_event {
struct wmi_rx_mgmt_info info; struct wmi_rx_mgmt_info info;
u8 payload[0]; u8 payload[0];

Просмотреть файл

@ -915,10 +915,6 @@ struct b43_wl {
char rng_name[30 + 1]; char rng_name[30 + 1];
#endif /* CONFIG_B43_HWRNG */ #endif /* CONFIG_B43_HWRNG */
/* List of all wireless devices on this chip */
struct list_head devlist;
u8 nr_devs;
bool radiotap_enabled; bool radiotap_enabled;
bool radio_enabled; bool radio_enabled;

Просмотреть файл

@ -1195,8 +1195,13 @@ static void b43_bcma_wireless_core_reset(struct b43_wldev *dev, bool gmode)
B43_BCMA_CLKCTLST_PHY_PLL_REQ; B43_BCMA_CLKCTLST_PHY_PLL_REQ;
u32 status = B43_BCMA_CLKCTLST_80211_PLL_ST | u32 status = B43_BCMA_CLKCTLST_80211_PLL_ST |
B43_BCMA_CLKCTLST_PHY_PLL_ST; B43_BCMA_CLKCTLST_PHY_PLL_ST;
u32 flags;
flags = B43_BCMA_IOCTL_PHY_CLKEN;
if (gmode)
flags |= B43_BCMA_IOCTL_GMODE;
b43_device_enable(dev, flags);
b43_device_enable(dev, B43_BCMA_IOCTL_PHY_CLKEN);
bcma_core_set_clockmode(dev->dev->bdev, BCMA_CLKMODE_FAST); bcma_core_set_clockmode(dev->dev->bdev, BCMA_CLKMODE_FAST);
b43_bcma_phy_reset(dev); b43_bcma_phy_reset(dev);
bcma_core_pll_ctl(dev->dev->bdev, req, status, true); bcma_core_pll_ctl(dev->dev->bdev, req, status, true);
@ -3735,40 +3740,35 @@ static int b43_switch_band(struct b43_wl *wl, struct ieee80211_channel *chan)
{ {
struct b43_wldev *up_dev = NULL; struct b43_wldev *up_dev = NULL;
struct b43_wldev *down_dev; struct b43_wldev *down_dev;
struct b43_wldev *d;
int err; int err;
bool uninitialized_var(gmode); bool uninitialized_var(gmode);
int prev_status; int prev_status;
/* Find a device and PHY which supports the band. */ /* Find a device and PHY which supports the band. */
list_for_each_entry(d, &wl->devlist, list) { switch (chan->band) {
switch (chan->band) { case IEEE80211_BAND_5GHZ:
case IEEE80211_BAND_5GHZ: if (wl->current_dev->phy.supports_5ghz) {
if (d->phy.supports_5ghz) { up_dev = wl->current_dev;
up_dev = d; gmode = false;
gmode = false;
}
break;
case IEEE80211_BAND_2GHZ:
if (d->phy.supports_2ghz) {
up_dev = d;
gmode = true;
}
break;
default:
B43_WARN_ON(1);
return -EINVAL;
} }
if (up_dev) break;
break; case IEEE80211_BAND_2GHZ:
if (wl->current_dev->phy.supports_2ghz) {
up_dev = wl->current_dev;
gmode = true;
}
break;
default:
B43_WARN_ON(1);
return -EINVAL;
} }
if (!up_dev) { if (!up_dev) {
b43err(wl, "Could not find a device for %s-GHz band operation\n", b43err(wl, "Could not find a device for %s-GHz band operation\n",
band_to_string(chan->band)); band_to_string(chan->band));
return -ENODEV; return -ENODEV;
} }
if ((up_dev == wl->current_dev) && if (!!wl->current_dev->phy.gmode == !!gmode) {
(!!wl->current_dev->phy.gmode == !!gmode)) {
/* This device is already running. */ /* This device is already running. */
return 0; return 0;
} }
@ -5178,7 +5178,6 @@ static int b43_wireless_core_attach(struct b43_wldev *dev)
} }
dev->phy.gmode = have_2ghz_phy; dev->phy.gmode = have_2ghz_phy;
dev->phy.radio_on = true;
b43_wireless_core_reset(dev, dev->phy.gmode); b43_wireless_core_reset(dev, dev->phy.gmode);
err = b43_phy_versioning(dev); err = b43_phy_versioning(dev);
@ -5270,7 +5269,6 @@ static void b43_one_core_detach(struct b43_bus_dev *dev)
b43_debugfs_remove_device(wldev); b43_debugfs_remove_device(wldev);
b43_wireless_core_detach(wldev); b43_wireless_core_detach(wldev);
list_del(&wldev->list); list_del(&wldev->list);
wl->nr_devs--;
b43_bus_set_wldev(dev, NULL); b43_bus_set_wldev(dev, NULL);
kfree(wldev); kfree(wldev);
} }
@ -5295,8 +5293,6 @@ static int b43_one_core_attach(struct b43_bus_dev *dev, struct b43_wl *wl)
if (err) if (err)
goto err_kfree_wldev; goto err_kfree_wldev;
list_add(&wldev->list, &wl->devlist);
wl->nr_devs++;
b43_bus_set_wldev(dev, wldev); b43_bus_set_wldev(dev, wldev);
b43_debugfs_add_device(wldev); b43_debugfs_add_device(wldev);
@ -5386,7 +5382,6 @@ static struct b43_wl *b43_wireless_init(struct b43_bus_dev *dev)
wl->hw = hw; wl->hw = hw;
mutex_init(&wl->mutex); mutex_init(&wl->mutex);
spin_lock_init(&wl->hardirq_lock); spin_lock_init(&wl->hardirq_lock);
INIT_LIST_HEAD(&wl->devlist);
INIT_WORK(&wl->beacon_update_trigger, b43_beacon_update_trigger_work); INIT_WORK(&wl->beacon_update_trigger, b43_beacon_update_trigger_work);
INIT_WORK(&wl->txpower_adjust_work, b43_phy_txpower_adjust_work); INIT_WORK(&wl->txpower_adjust_work, b43_phy_txpower_adjust_work);
INIT_WORK(&wl->tx_work, b43_tx_work); INIT_WORK(&wl->tx_work, b43_tx_work);
@ -5486,39 +5481,42 @@ int b43_ssb_probe(struct ssb_device *sdev, const struct ssb_device_id *id)
struct b43_bus_dev *dev; struct b43_bus_dev *dev;
struct b43_wl *wl; struct b43_wl *wl;
int err; int err;
int first = 0;
dev = b43_bus_dev_ssb_init(sdev); dev = b43_bus_dev_ssb_init(sdev);
if (!dev) if (!dev)
return -ENOMEM; return -ENOMEM;
wl = ssb_get_devtypedata(sdev); wl = ssb_get_devtypedata(sdev);
if (!wl) { if (wl) {
/* Probing the first core. Must setup common struct b43_wl */ b43err(NULL, "Dual-core devices are not supported\n");
first = 1; err = -ENOTSUPP;
b43_sprom_fixup(sdev->bus); goto err_ssb_kfree_dev;
wl = b43_wireless_init(dev);
if (IS_ERR(wl)) {
err = PTR_ERR(wl);
goto out;
}
ssb_set_devtypedata(sdev, wl);
B43_WARN_ON(ssb_get_devtypedata(sdev) != wl);
} }
b43_sprom_fixup(sdev->bus);
wl = b43_wireless_init(dev);
if (IS_ERR(wl)) {
err = PTR_ERR(wl);
goto err_ssb_kfree_dev;
}
ssb_set_devtypedata(sdev, wl);
B43_WARN_ON(ssb_get_devtypedata(sdev) != wl);
err = b43_one_core_attach(dev, wl); err = b43_one_core_attach(dev, wl);
if (err) if (err)
goto err_wireless_exit; goto err_ssb_wireless_exit;
/* setup and start work to load firmware */ /* setup and start work to load firmware */
INIT_WORK(&wl->firmware_load, b43_request_firmware); INIT_WORK(&wl->firmware_load, b43_request_firmware);
schedule_work(&wl->firmware_load); schedule_work(&wl->firmware_load);
out:
return err; return err;
err_wireless_exit: err_ssb_wireless_exit:
if (first) b43_wireless_exit(dev, wl);
b43_wireless_exit(dev, wl); err_ssb_kfree_dev:
kfree(dev);
return err; return err;
} }
@ -5546,13 +5544,8 @@ static void b43_ssb_remove(struct ssb_device *sdev)
/* Unregister HW RNG driver */ /* Unregister HW RNG driver */
b43_rng_exit(wl); b43_rng_exit(wl);
if (list_empty(&wl->devlist)) { b43_leds_unregister(wl);
b43_leds_unregister(wl); b43_wireless_exit(dev, wl);
/* Last core on the chip unregistered.
* We can destroy common struct b43_wl.
*/
b43_wireless_exit(dev, wl);
}
} }
static struct ssb_driver b43_ssb_driver = { static struct ssb_driver b43_ssb_driver = {

Просмотреть файл

@ -96,7 +96,7 @@ int b43_phy_init(struct b43_wldev *dev)
phy->channel = ops->get_default_chan(dev); phy->channel = ops->get_default_chan(dev);
ops->software_rfkill(dev, false); b43_software_rfkill(dev, false);
err = ops->init(dev); err = ops->init(dev);
if (err) { if (err) {
b43err(dev->wl, "PHY init failed\n"); b43err(dev->wl, "PHY init failed\n");
@ -116,7 +116,7 @@ err_phy_exit:
if (ops->exit) if (ops->exit)
ops->exit(dev); ops->exit(dev);
err_block_rf: err_block_rf:
ops->software_rfkill(dev, true); b43_software_rfkill(dev, true);
return err; return err;
} }
@ -125,7 +125,7 @@ void b43_phy_exit(struct b43_wldev *dev)
{ {
const struct b43_phy_operations *ops = dev->phy.ops; const struct b43_phy_operations *ops = dev->phy.ops;
ops->software_rfkill(dev, true); b43_software_rfkill(dev, true);
if (ops->exit) if (ops->exit)
ops->exit(dev); ops->exit(dev);
} }

Просмотреть файл

@ -1587,6 +1587,7 @@ static void b43_phy_initb5(struct b43_wldev *dev)
b43_write16(dev, 0x03E4, (b43_read16(dev, 0x03E4) & 0xFFC0) | 0x0004); b43_write16(dev, 0x03E4, (b43_read16(dev, 0x03E4) & 0xFFC0) | 0x0004);
} }
/* http://bcm-v4.sipsolutions.net/802.11/PHY/Init/B6 */
static void b43_phy_initb6(struct b43_wldev *dev) static void b43_phy_initb6(struct b43_wldev *dev)
{ {
struct b43_phy *phy = &dev->phy; struct b43_phy *phy = &dev->phy;
@ -1670,7 +1671,7 @@ static void b43_phy_initb6(struct b43_wldev *dev)
b43_radio_write16(dev, 0x50, 0x20); b43_radio_write16(dev, 0x50, 0x20);
} }
if (phy->radio_rev <= 2) { if (phy->radio_rev <= 2) {
b43_radio_write16(dev, 0x7C, 0x20); b43_radio_write16(dev, 0x50, 0x20);
b43_radio_write16(dev, 0x5A, 0x70); b43_radio_write16(dev, 0x5A, 0x70);
b43_radio_write16(dev, 0x5B, 0x7B); b43_radio_write16(dev, 0x5B, 0x7B);
b43_radio_write16(dev, 0x5C, 0xB0); b43_radio_write16(dev, 0x5C, 0xB0);
@ -1686,9 +1687,8 @@ static void b43_phy_initb6(struct b43_wldev *dev)
b43_phy_write(dev, 0x2A, 0x8AC0); b43_phy_write(dev, 0x2A, 0x8AC0);
b43_phy_write(dev, 0x0038, 0x0668); b43_phy_write(dev, 0x0038, 0x0668);
b43_set_txpower_g(dev, &gphy->bbatt, &gphy->rfatt, gphy->tx_control); b43_set_txpower_g(dev, &gphy->bbatt, &gphy->rfatt, gphy->tx_control);
if (phy->radio_rev <= 5) { if (phy->radio_rev == 4 || phy->radio_rev == 5)
b43_phy_maskset(dev, 0x5D, 0xFF80, 0x0003); b43_phy_maskset(dev, 0x5D, 0xFF80, 0x0003);
}
if (phy->radio_rev <= 2) if (phy->radio_rev <= 2)
b43_radio_write16(dev, 0x005D, 0x000D); b43_radio_write16(dev, 0x005D, 0x000D);

Просмотреть файл

@ -257,6 +257,72 @@ static void b43_nphy_rf_ctl_override(struct b43_wldev *dev, u16 field,
} }
} }
static void b43_nphy_rf_ctl_intc_override_rev7(struct b43_wldev *dev,
enum n_intc_override intc_override,
u16 value, u8 core_sel)
{
u16 reg, tmp, tmp2, val;
int core;
for (core = 0; core < 2; core++) {
if ((core_sel == 1 && core != 0) ||
(core_sel == 2 && core != 1))
continue;
reg = (core == 0) ? B43_NPHY_RFCTL_INTC1 : B43_NPHY_RFCTL_INTC2;
switch (intc_override) {
case N_INTC_OVERRIDE_OFF:
b43_phy_write(dev, reg, 0);
b43_nphy_force_rf_sequence(dev, B43_RFSEQ_RESET2RX);
break;
case N_INTC_OVERRIDE_TRSW:
b43_phy_maskset(dev, reg, ~0xC0, value << 6);
b43_phy_set(dev, reg, 0x400);
b43_phy_mask(dev, 0x2ff, ~0xC000 & 0xFFFF);
b43_phy_set(dev, 0x2ff, 0x2000);
b43_phy_set(dev, 0x2ff, 0x0001);
break;
case N_INTC_OVERRIDE_PA:
tmp = 0x0030;
if (b43_current_band(dev->wl) == IEEE80211_BAND_5GHZ)
val = value << 5;
else
val = value << 4;
b43_phy_maskset(dev, reg, ~tmp, val);
b43_phy_set(dev, reg, 0x1000);
break;
case N_INTC_OVERRIDE_EXT_LNA_PU:
if (b43_current_band(dev->wl) == IEEE80211_BAND_5GHZ) {
tmp = 0x0001;
tmp2 = 0x0004;
val = value;
} else {
tmp = 0x0004;
tmp2 = 0x0001;
val = value << 2;
}
b43_phy_maskset(dev, reg, ~tmp, val);
b43_phy_mask(dev, reg, ~tmp2);
break;
case N_INTC_OVERRIDE_EXT_LNA_GAIN:
if (b43_current_band(dev->wl) == IEEE80211_BAND_5GHZ) {
tmp = 0x0002;
tmp2 = 0x0008;
val = value << 1;
} else {
tmp = 0x0008;
tmp2 = 0x0002;
val = value << 3;
}
b43_phy_maskset(dev, reg, ~tmp, val);
b43_phy_mask(dev, reg, ~tmp2);
break;
}
}
}
/* http://bcm-v4.sipsolutions.net/802.11/PHY/N/RFCtrlIntcOverride */ /* http://bcm-v4.sipsolutions.net/802.11/PHY/N/RFCtrlIntcOverride */
static void b43_nphy_rf_ctl_intc_override(struct b43_wldev *dev, static void b43_nphy_rf_ctl_intc_override(struct b43_wldev *dev,
enum n_intc_override intc_override, enum n_intc_override intc_override,
@ -265,6 +331,12 @@ static void b43_nphy_rf_ctl_intc_override(struct b43_wldev *dev,
u8 i, j; u8 i, j;
u16 reg, tmp, val; u16 reg, tmp, val;
if (dev->phy.rev >= 7) {
b43_nphy_rf_ctl_intc_override_rev7(dev, intc_override, value,
core);
return;
}
B43_WARN_ON(dev->phy.rev < 3); B43_WARN_ON(dev->phy.rev < 3);
for (i = 0; i < 2; i++) { for (i = 0; i < 2; i++) {
@ -419,7 +491,8 @@ static void b43_nphy_stay_in_carrier_search(struct b43_wldev *dev, bool enable)
static const u16 clip[] = { 0xFFFF, 0xFFFF }; static const u16 clip[] = { 0xFFFF, 0xFFFF };
if (nphy->deaf_count++ == 0) { if (nphy->deaf_count++ == 0) {
nphy->classifier_state = b43_nphy_classifier(dev, 0, 0); nphy->classifier_state = b43_nphy_classifier(dev, 0, 0);
b43_nphy_classifier(dev, 0x7, 0); b43_nphy_classifier(dev, 0x7,
B43_NPHY_CLASSCTL_WAITEDEN);
b43_nphy_read_clip_detection(dev, nphy->clip_state); b43_nphy_read_clip_detection(dev, nphy->clip_state);
b43_nphy_write_clip_detection(dev, clip); b43_nphy_write_clip_detection(dev, clip);
} }
@ -734,9 +807,16 @@ static void b43_radio_2056_setup(struct b43_wldev *dev,
u16 bias, cbias; u16 bias, cbias;
u16 pag_boost, padg_boost, pgag_boost, mixg_boost; u16 pag_boost, padg_boost, pgag_boost, mixg_boost;
u16 paa_boost, pada_boost, pgaa_boost, mixa_boost; u16 paa_boost, pada_boost, pgaa_boost, mixa_boost;
bool is_pkg_fab_smic;
B43_WARN_ON(dev->phy.rev < 3); B43_WARN_ON(dev->phy.rev < 3);
is_pkg_fab_smic =
((dev->dev->chip_id == BCMA_CHIP_ID_BCM43224 ||
dev->dev->chip_id == BCMA_CHIP_ID_BCM43225 ||
dev->dev->chip_id == BCMA_CHIP_ID_BCM43421) &&
dev->dev->chip_pkg == BCMA_PKG_ID_BCM43224_FAB_SMIC);
b43_chantab_radio_2056_upload(dev, e); b43_chantab_radio_2056_upload(dev, e);
b2056_upload_syn_pll_cp2(dev, band == IEEE80211_BAND_5GHZ); b2056_upload_syn_pll_cp2(dev, band == IEEE80211_BAND_5GHZ);
@ -744,7 +824,8 @@ static void b43_radio_2056_setup(struct b43_wldev *dev,
b43_current_band(dev->wl) == IEEE80211_BAND_2GHZ) { b43_current_band(dev->wl) == IEEE80211_BAND_2GHZ) {
b43_radio_write(dev, B2056_SYN_PLL_LOOPFILTER1, 0x1F); b43_radio_write(dev, B2056_SYN_PLL_LOOPFILTER1, 0x1F);
b43_radio_write(dev, B2056_SYN_PLL_LOOPFILTER2, 0x1F); b43_radio_write(dev, B2056_SYN_PLL_LOOPFILTER2, 0x1F);
if (dev->dev->chip_id == 0x4716) { if (dev->dev->chip_id == BCMA_CHIP_ID_BCM4716 ||
dev->dev->chip_id == BCMA_CHIP_ID_BCM47162) {
b43_radio_write(dev, B2056_SYN_PLL_LOOPFILTER4, 0x14); b43_radio_write(dev, B2056_SYN_PLL_LOOPFILTER4, 0x14);
b43_radio_write(dev, B2056_SYN_PLL_CP2, 0); b43_radio_write(dev, B2056_SYN_PLL_CP2, 0);
} else { } else {
@ -752,6 +833,13 @@ static void b43_radio_2056_setup(struct b43_wldev *dev,
b43_radio_write(dev, B2056_SYN_PLL_CP2, 0x14); b43_radio_write(dev, B2056_SYN_PLL_CP2, 0x14);
} }
} }
if (sprom->boardflags2_hi & B43_BFH2_GPLL_WAR2 &&
b43_current_band(dev->wl) == IEEE80211_BAND_2GHZ) {
b43_radio_write(dev, B2056_SYN_PLL_LOOPFILTER1, 0x1f);
b43_radio_write(dev, B2056_SYN_PLL_LOOPFILTER2, 0x1f);
b43_radio_write(dev, B2056_SYN_PLL_LOOPFILTER4, 0x0b);
b43_radio_write(dev, B2056_SYN_PLL_CP2, 0x20);
}
if (sprom->boardflags2_lo & B43_BFL2_APLL_WAR && if (sprom->boardflags2_lo & B43_BFL2_APLL_WAR &&
b43_current_band(dev->wl) == IEEE80211_BAND_5GHZ) { b43_current_band(dev->wl) == IEEE80211_BAND_5GHZ) {
b43_radio_write(dev, B2056_SYN_PLL_LOOPFILTER1, 0x1F); b43_radio_write(dev, B2056_SYN_PLL_LOOPFILTER1, 0x1F);
@ -767,7 +855,8 @@ static void b43_radio_2056_setup(struct b43_wldev *dev,
b43_radio_write(dev, b43_radio_write(dev,
offset | B2056_TX_PADG_IDAC, 0xcc); offset | B2056_TX_PADG_IDAC, 0xcc);
if (dev->dev->chip_id == 0x4716) { if (dev->dev->chip_id == BCMA_CHIP_ID_BCM4716 ||
dev->dev->chip_id == BCMA_CHIP_ID_BCM47162) {
bias = 0x40; bias = 0x40;
cbias = 0x45; cbias = 0x45;
pag_boost = 0x5; pag_boost = 0x5;
@ -776,6 +865,10 @@ static void b43_radio_2056_setup(struct b43_wldev *dev,
} else { } else {
bias = 0x25; bias = 0x25;
cbias = 0x20; cbias = 0x20;
if (is_pkg_fab_smic) {
bias = 0x2a;
cbias = 0x38;
}
pag_boost = 0x4; pag_boost = 0x4;
pgag_boost = 0x03; pgag_boost = 0x03;
mixg_boost = 0x65; mixg_boost = 0x65;
@ -844,6 +937,8 @@ static void b43_radio_2056_setup(struct b43_wldev *dev,
mixa_boost = 0xF; mixa_boost = 0xF;
} }
cbias = is_pkg_fab_smic ? 0x35 : 0x30;
for (i = 0; i < 2; i++) { for (i = 0; i < 2; i++) {
offset = i ? B2056_TX1 : B2056_TX0; offset = i ? B2056_TX1 : B2056_TX0;
@ -862,11 +957,11 @@ static void b43_radio_2056_setup(struct b43_wldev *dev,
b43_radio_write(dev, b43_radio_write(dev,
offset | B2056_TX_PADA_CASCBIAS, 0x03); offset | B2056_TX_PADA_CASCBIAS, 0x03);
b43_radio_write(dev, b43_radio_write(dev,
offset | B2056_TX_INTPAA_IAUX_STAT, 0x50); offset | B2056_TX_INTPAA_IAUX_STAT, 0x30);
b43_radio_write(dev, b43_radio_write(dev,
offset | B2056_TX_INTPAA_IMAIN_STAT, 0x50); offset | B2056_TX_INTPAA_IMAIN_STAT, 0x30);
b43_radio_write(dev, b43_radio_write(dev,
offset | B2056_TX_INTPAA_CASCBIAS, 0x30); offset | B2056_TX_INTPAA_CASCBIAS, cbias);
} }
} }
@ -1164,23 +1259,20 @@ static void b43_nphy_run_samples(struct b43_wldev *dev, u16 samps, u16 loops,
u16 seq_mode; u16 seq_mode;
u32 tmp; u32 tmp;
if (nphy->hang_avoid) b43_nphy_stay_in_carrier_search(dev, true);
b43_nphy_stay_in_carrier_search(dev, true);
if ((nphy->bb_mult_save & 0x80000000) == 0) { if ((nphy->bb_mult_save & 0x80000000) == 0) {
tmp = b43_ntab_read(dev, B43_NTAB16(15, 87)); tmp = b43_ntab_read(dev, B43_NTAB16(15, 87));
nphy->bb_mult_save = (tmp & 0xFFFF) | 0x80000000; nphy->bb_mult_save = (tmp & 0xFFFF) | 0x80000000;
} }
/* TODO: add modify_bbmult argument */
if (!dev->phy.is_40mhz) if (!dev->phy.is_40mhz)
tmp = 0x6464; tmp = 0x6464;
else else
tmp = 0x4747; tmp = 0x4747;
b43_ntab_write(dev, B43_NTAB16(15, 87), tmp); b43_ntab_write(dev, B43_NTAB16(15, 87), tmp);
if (nphy->hang_avoid)
b43_nphy_stay_in_carrier_search(dev, false);
b43_phy_write(dev, B43_NPHY_SAMP_DEPCNT, (samps - 1)); b43_phy_write(dev, B43_NPHY_SAMP_DEPCNT, (samps - 1));
if (loops != 0xFFFF) if (loops != 0xFFFF)
@ -1213,6 +1305,8 @@ static void b43_nphy_run_samples(struct b43_wldev *dev, u16 samps, u16 loops,
b43err(dev->wl, "run samples timeout\n"); b43err(dev->wl, "run samples timeout\n");
b43_phy_write(dev, B43_NPHY_RFSEQMODE, seq_mode); b43_phy_write(dev, B43_NPHY_RFSEQMODE, seq_mode);
b43_nphy_stay_in_carrier_search(dev, false);
} }
/************************************************** /**************************************************
@ -1588,8 +1682,8 @@ static void b43_nphy_rev3_rssi_cal(struct b43_wldev *dev)
struct b43_phy_n *nphy = dev->phy.n; struct b43_phy_n *nphy = dev->phy.n;
u16 saved_regs_phy_rfctl[2]; u16 saved_regs_phy_rfctl[2];
u16 saved_regs_phy[13]; u16 saved_regs_phy[22];
u16 regs_to_store[] = { u16 regs_to_store_rev3[] = {
B43_NPHY_AFECTL_OVER1, B43_NPHY_AFECTL_OVER, B43_NPHY_AFECTL_OVER1, B43_NPHY_AFECTL_OVER,
B43_NPHY_AFECTL_C1, B43_NPHY_AFECTL_C2, B43_NPHY_AFECTL_C1, B43_NPHY_AFECTL_C2,
B43_NPHY_TXF_40CO_B1S1, B43_NPHY_RFCTL_OVER, B43_NPHY_TXF_40CO_B1S1, B43_NPHY_RFCTL_OVER,
@ -1598,6 +1692,20 @@ static void b43_nphy_rev3_rssi_cal(struct b43_wldev *dev)
B43_NPHY_RFCTL_LUT_TRSW_UP1, B43_NPHY_RFCTL_LUT_TRSW_UP2, B43_NPHY_RFCTL_LUT_TRSW_UP1, B43_NPHY_RFCTL_LUT_TRSW_UP2,
B43_NPHY_RFCTL_RSSIO1, B43_NPHY_RFCTL_RSSIO2 B43_NPHY_RFCTL_RSSIO1, B43_NPHY_RFCTL_RSSIO2
}; };
u16 regs_to_store_rev7[] = {
B43_NPHY_AFECTL_OVER1, B43_NPHY_AFECTL_OVER,
B43_NPHY_AFECTL_C1, B43_NPHY_AFECTL_C2,
B43_NPHY_TXF_40CO_B1S1, B43_NPHY_RFCTL_OVER,
0x342, 0x343, 0x346, 0x347,
0x2ff,
B43_NPHY_TXF_40CO_B1S0, B43_NPHY_TXF_40CO_B32S1,
B43_NPHY_RFCTL_CMD,
B43_NPHY_RFCTL_LUT_TRSW_UP1, B43_NPHY_RFCTL_LUT_TRSW_UP2,
0x340, 0x341, 0x344, 0x345,
B43_NPHY_RFCTL_RSSIO1, B43_NPHY_RFCTL_RSSIO2
};
u16 *regs_to_store;
int regs_amount;
u16 class; u16 class;
@ -1617,6 +1725,15 @@ static void b43_nphy_rev3_rssi_cal(struct b43_wldev *dev)
u8 rx_core_state; u8 rx_core_state;
int core, i, j, vcm; int core, i, j, vcm;
if (dev->phy.rev >= 7) {
regs_to_store = regs_to_store_rev7;
regs_amount = ARRAY_SIZE(regs_to_store_rev7);
} else {
regs_to_store = regs_to_store_rev3;
regs_amount = ARRAY_SIZE(regs_to_store_rev3);
}
BUG_ON(regs_amount > ARRAY_SIZE(saved_regs_phy));
class = b43_nphy_classifier(dev, 0, 0); class = b43_nphy_classifier(dev, 0, 0);
b43_nphy_classifier(dev, 7, 4); b43_nphy_classifier(dev, 7, 4);
b43_nphy_read_clip_detection(dev, clip_state); b43_nphy_read_clip_detection(dev, clip_state);
@ -1624,22 +1741,29 @@ static void b43_nphy_rev3_rssi_cal(struct b43_wldev *dev)
saved_regs_phy_rfctl[0] = b43_phy_read(dev, B43_NPHY_RFCTL_INTC1); saved_regs_phy_rfctl[0] = b43_phy_read(dev, B43_NPHY_RFCTL_INTC1);
saved_regs_phy_rfctl[1] = b43_phy_read(dev, B43_NPHY_RFCTL_INTC2); saved_regs_phy_rfctl[1] = b43_phy_read(dev, B43_NPHY_RFCTL_INTC2);
for (i = 0; i < ARRAY_SIZE(regs_to_store); i++) for (i = 0; i < regs_amount; i++)
saved_regs_phy[i] = b43_phy_read(dev, regs_to_store[i]); saved_regs_phy[i] = b43_phy_read(dev, regs_to_store[i]);
b43_nphy_rf_ctl_intc_override(dev, N_INTC_OVERRIDE_OFF, 0, 7); b43_nphy_rf_ctl_intc_override(dev, N_INTC_OVERRIDE_OFF, 0, 7);
b43_nphy_rf_ctl_intc_override(dev, N_INTC_OVERRIDE_TRSW, 1, 7); b43_nphy_rf_ctl_intc_override(dev, N_INTC_OVERRIDE_TRSW, 1, 7);
b43_nphy_rf_ctl_override(dev, 0x1, 0, 0, false);
b43_nphy_rf_ctl_override(dev, 0x2, 1, 0, false);
b43_nphy_rf_ctl_override(dev, 0x80, 1, 0, false);
b43_nphy_rf_ctl_override(dev, 0x40, 1, 0, false);
if (b43_current_band(dev->wl) == IEEE80211_BAND_5GHZ) { if (dev->phy.rev >= 7) {
b43_nphy_rf_ctl_override(dev, 0x20, 0, 0, false); /* TODO */
b43_nphy_rf_ctl_override(dev, 0x10, 1, 0, false); if (b43_current_band(dev->wl) == IEEE80211_BAND_5GHZ) {
} else {
}
} else { } else {
b43_nphy_rf_ctl_override(dev, 0x10, 0, 0, false); b43_nphy_rf_ctl_override(dev, 0x1, 0, 0, false);
b43_nphy_rf_ctl_override(dev, 0x20, 1, 0, false); b43_nphy_rf_ctl_override(dev, 0x2, 1, 0, false);
b43_nphy_rf_ctl_override(dev, 0x80, 1, 0, false);
b43_nphy_rf_ctl_override(dev, 0x40, 1, 0, false);
if (b43_current_band(dev->wl) == IEEE80211_BAND_5GHZ) {
b43_nphy_rf_ctl_override(dev, 0x20, 0, 0, false);
b43_nphy_rf_ctl_override(dev, 0x10, 1, 0, false);
} else {
b43_nphy_rf_ctl_override(dev, 0x10, 0, 0, false);
b43_nphy_rf_ctl_override(dev, 0x20, 1, 0, false);
}
} }
rx_core_state = b43_nphy_get_rx_core_state(dev); rx_core_state = b43_nphy_get_rx_core_state(dev);
@ -1654,8 +1778,11 @@ static void b43_nphy_rev3_rssi_cal(struct b43_wldev *dev)
/* Grab RSSI results for every possible VCM */ /* Grab RSSI results for every possible VCM */
for (vcm = 0; vcm < 8; vcm++) { for (vcm = 0; vcm < 8; vcm++) {
b43_radio_maskset(dev, r | B2056_RX_RSSI_MISC, 0xE3, if (dev->phy.rev >= 7)
vcm << 2); ;
else
b43_radio_maskset(dev, r | B2056_RX_RSSI_MISC,
0xE3, vcm << 2);
b43_nphy_poll_rssi(dev, N_RSSI_NB, results[vcm], 8); b43_nphy_poll_rssi(dev, N_RSSI_NB, results[vcm], 8);
} }
@ -1682,8 +1809,11 @@ static void b43_nphy_rev3_rssi_cal(struct b43_wldev *dev)
} }
/* Select the best VCM */ /* Select the best VCM */
b43_radio_maskset(dev, r | B2056_RX_RSSI_MISC, 0xE3, if (dev->phy.rev >= 7)
vcm_final << 2); ;
else
b43_radio_maskset(dev, r | B2056_RX_RSSI_MISC,
0xE3, vcm_final << 2);
for (i = 0; i < 4; i++) { for (i = 0; i < 4; i++) {
if (core != i / 2) if (core != i / 2)
@ -1736,9 +1866,9 @@ static void b43_nphy_rev3_rssi_cal(struct b43_wldev *dev)
b43_phy_set(dev, B43_NPHY_RFCTL_OVER, 0x1); b43_phy_set(dev, B43_NPHY_RFCTL_OVER, 0x1);
b43_phy_set(dev, B43_NPHY_RFCTL_CMD, B43_NPHY_RFCTL_CMD_RXTX); b43_phy_set(dev, B43_NPHY_RFCTL_CMD, B43_NPHY_RFCTL_CMD_RXTX);
b43_phy_mask(dev, B43_NPHY_TXF_40CO_B1S1, ~0x1); b43_phy_mask(dev, B43_NPHY_RFCTL_OVER, ~0x1);
for (i = 0; i < ARRAY_SIZE(regs_to_store); i++) for (i = 0; i < regs_amount; i++)
b43_phy_write(dev, regs_to_store[i], saved_regs_phy[i]); b43_phy_write(dev, regs_to_store[i], saved_regs_phy[i]);
/* Store for future configuration */ /* Store for future configuration */
@ -2494,8 +2624,8 @@ static void b43_nphy_workarounds_rev3plus(struct b43_wldev *dev)
struct ssb_sprom *sprom = dev->dev->bus_sprom; struct ssb_sprom *sprom = dev->dev->bus_sprom;
/* TX to RX */ /* TX to RX */
u8 tx2rx_events[8] = { 0x4, 0x3, 0x6, 0x5, 0x2, 0x1, 0x8, 0x1F }; u8 tx2rx_events[7] = { 0x4, 0x3, 0x5, 0x2, 0x1, 0x8, 0x1F };
u8 tx2rx_delays[8] = { 8, 4, 2, 2, 4, 4, 6, 1 }; u8 tx2rx_delays[7] = { 8, 4, 4, 4, 4, 6, 1 };
/* RX to TX */ /* RX to TX */
u8 rx2tx_events_ipa[9] = { 0x0, 0x1, 0x2, 0x8, 0x5, 0x6, 0xF, 0x3, u8 rx2tx_events_ipa[9] = { 0x0, 0x1, 0x2, 0x8, 0x5, 0x6, 0xF, 0x3,
0x1F }; 0x1F };
@ -2503,6 +2633,23 @@ static void b43_nphy_workarounds_rev3plus(struct b43_wldev *dev)
u8 rx2tx_events[9] = { 0x0, 0x1, 0x2, 0x8, 0x5, 0x6, 0x3, 0x4, 0x1F }; u8 rx2tx_events[9] = { 0x0, 0x1, 0x2, 0x8, 0x5, 0x6, 0x3, 0x4, 0x1F };
u8 rx2tx_delays[9] = { 8, 6, 6, 4, 4, 18, 42, 1, 1 }; u8 rx2tx_delays[9] = { 8, 6, 6, 4, 4, 18, 42, 1, 1 };
u16 vmids[5][4] = {
{ 0xa2, 0xb4, 0xb4, 0x89, }, /* 0 */
{ 0xb4, 0xb4, 0xb4, 0x24, }, /* 1 */
{ 0xa2, 0xb4, 0xb4, 0x74, }, /* 2 */
{ 0xa2, 0xb4, 0xb4, 0x270, }, /* 3 */
{ 0xa2, 0xb4, 0xb4, 0x00, }, /* 4 and 5 */
};
u16 gains[5][4] = {
{ 0x02, 0x02, 0x02, 0x00, }, /* 0 */
{ 0x02, 0x02, 0x02, 0x02, }, /* 1 */
{ 0x02, 0x02, 0x02, 0x04, }, /* 2 */
{ 0x02, 0x02, 0x02, 0x00, }, /* 3 */
{ 0x02, 0x02, 0x02, 0x00, }, /* 4 and 5 */
};
u16 *vmid, *gain;
u8 pdet_range;
u16 tmp16; u16 tmp16;
u32 tmp32; u32 tmp32;
@ -2561,7 +2708,71 @@ static void b43_nphy_workarounds_rev3plus(struct b43_wldev *dev)
b43_ntab_write(dev, B43_NTAB16(8, 0), 2); b43_ntab_write(dev, B43_NTAB16(8, 0), 2);
b43_ntab_write(dev, B43_NTAB16(8, 16), 2); b43_ntab_write(dev, B43_NTAB16(8, 16), 2);
/* TODO */ if (b43_current_band(dev->wl) == IEEE80211_BAND_2GHZ)
pdet_range = sprom->fem.ghz2.pdet_range;
else
pdet_range = sprom->fem.ghz5.pdet_range;
vmid = vmids[min_t(u16, pdet_range, 4)];
gain = gains[min_t(u16, pdet_range, 4)];
switch (pdet_range) {
case 3:
if (!(dev->phy.rev >= 4 &&
b43_current_band(dev->wl) == IEEE80211_BAND_2GHZ))
break;
/* FALL THROUGH */
case 0:
case 1:
b43_ntab_write_bulk(dev, B43_NTAB16(8, 0x08), 4, vmid);
b43_ntab_write_bulk(dev, B43_NTAB16(8, 0x18), 4, vmid);
b43_ntab_write_bulk(dev, B43_NTAB16(8, 0x0c), 4, gain);
b43_ntab_write_bulk(dev, B43_NTAB16(8, 0x1c), 4, gain);
break;
case 2:
if (dev->phy.rev >= 6) {
if (b43_current_band(dev->wl) == IEEE80211_BAND_2GHZ)
vmid[3] = 0x94;
else
vmid[3] = 0x8e;
gain[3] = 3;
} else if (dev->phy.rev == 5) {
vmid[3] = 0x84;
gain[3] = 2;
}
b43_ntab_write_bulk(dev, B43_NTAB16(8, 0x08), 4, vmid);
b43_ntab_write_bulk(dev, B43_NTAB16(8, 0x18), 4, vmid);
b43_ntab_write_bulk(dev, B43_NTAB16(8, 0x0c), 4, gain);
b43_ntab_write_bulk(dev, B43_NTAB16(8, 0x1c), 4, gain);
break;
case 4:
case 5:
if (b43_current_band(dev->wl) != IEEE80211_BAND_2GHZ) {
if (pdet_range == 4) {
vmid[3] = 0x8e;
tmp16 = 0x96;
gain[3] = 0x2;
} else {
vmid[3] = 0x89;
tmp16 = 0x89;
gain[3] = 0;
}
} else {
if (pdet_range == 4) {
vmid[3] = 0x89;
tmp16 = 0x8b;
gain[3] = 0x2;
} else {
vmid[3] = 0x74;
tmp16 = 0x70;
gain[3] = 0;
}
}
b43_ntab_write_bulk(dev, B43_NTAB16(8, 0x08), 4, vmid);
b43_ntab_write_bulk(dev, B43_NTAB16(8, 0x0c), 4, gain);
vmid[3] = tmp16;
b43_ntab_write_bulk(dev, B43_NTAB16(8, 0x18), 4, vmid);
b43_ntab_write_bulk(dev, B43_NTAB16(8, 0x1c), 4, gain);
break;
}
b43_radio_write(dev, B2056_RX0 | B2056_RX_MIXA_MAST_BIAS, 0x00); b43_radio_write(dev, B2056_RX0 | B2056_RX_MIXA_MAST_BIAS, 0x00);
b43_radio_write(dev, B2056_RX1 | B2056_RX_MIXA_MAST_BIAS, 0x00); b43_radio_write(dev, B2056_RX1 | B2056_RX_MIXA_MAST_BIAS, 0x00);
@ -2600,7 +2811,7 @@ static void b43_nphy_workarounds_rev3plus(struct b43_wldev *dev)
/* Dropped probably-always-true condition */ /* Dropped probably-always-true condition */
b43_phy_write(dev, B43_NPHY_ED_CRS40ASSERTTHRESH0, 0x03eb); b43_phy_write(dev, B43_NPHY_ED_CRS40ASSERTTHRESH0, 0x03eb);
b43_phy_write(dev, B43_NPHY_ED_CRS40ASSERTTHRESH1, 0x03eb); b43_phy_write(dev, B43_NPHY_ED_CRS40ASSERTTHRESH1, 0x03eb);
b43_phy_write(dev, B43_NPHY_ED_CRS40DEASSERTTHRESH1, 0x0341); b43_phy_write(dev, B43_NPHY_ED_CRS40DEASSERTTHRESH0, 0x0341);
b43_phy_write(dev, B43_NPHY_ED_CRS40DEASSERTTHRESH1, 0x0341); b43_phy_write(dev, B43_NPHY_ED_CRS40DEASSERTTHRESH1, 0x0341);
b43_phy_write(dev, B43_NPHY_ED_CRS20LASSERTTHRESH0, 0x042b); b43_phy_write(dev, B43_NPHY_ED_CRS20LASSERTTHRESH0, 0x042b);
b43_phy_write(dev, B43_NPHY_ED_CRS20LASSERTTHRESH1, 0x042b); b43_phy_write(dev, B43_NPHY_ED_CRS20LASSERTTHRESH1, 0x042b);
@ -3211,6 +3422,20 @@ static void b43_nphy_tx_prepare_adjusted_power_table(struct b43_wldev *dev)
u8 idx, delta; u8 idx, delta;
u8 i, stf_mode; u8 i, stf_mode;
/* Array adj_pwr_tbl corresponds to the hardware table. It consists of
* 21 groups, each containing 4 entries.
*
* First group has entries for CCK modulation.
* The rest of groups has 1 entry per modulation (SISO, CDD, STBC, SDM).
*
* Group 0 is for CCK
* Groups 1..4 use BPSK (group per coding rate)
* Groups 5..8 use QPSK (group per coding rate)
* Groups 9..12 use 16-QAM (group per coding rate)
* Groups 13..16 use 64-QAM (group per coding rate)
* Groups 17..20 are unknown
*/
for (i = 0; i < 4; i++) for (i = 0; i < 4; i++)
nphy->adj_pwr_tbl[i] = nphy->tx_power_offset[i]; nphy->adj_pwr_tbl[i] = nphy->tx_power_offset[i];
@ -3409,10 +3634,8 @@ static void b43_nphy_tx_power_ctl_setup(struct b43_wldev *dev)
} }
b43_nphy_tx_prepare_adjusted_power_table(dev); b43_nphy_tx_prepare_adjusted_power_table(dev);
/*
b43_ntab_write_bulk(dev, B43_NTAB16(26, 64), 84, nphy->adj_pwr_tbl); b43_ntab_write_bulk(dev, B43_NTAB16(26, 64), 84, nphy->adj_pwr_tbl);
b43_ntab_write_bulk(dev, B43_NTAB16(27, 64), 84, nphy->adj_pwr_tbl); b43_ntab_write_bulk(dev, B43_NTAB16(27, 64), 84, nphy->adj_pwr_tbl);
*/
if (nphy->hang_avoid) if (nphy->hang_avoid)
b43_nphy_stay_in_carrier_search(dev, false); b43_nphy_stay_in_carrier_search(dev, false);
@ -5124,7 +5347,7 @@ static int b43_phy_initn(struct b43_wldev *dev)
b43_phy_write(dev, B43_NPHY_TXMACIF_HOLDOFF, 0x0015); b43_phy_write(dev, B43_NPHY_TXMACIF_HOLDOFF, 0x0015);
b43_phy_write(dev, B43_NPHY_TXMACDELAY, 0x0320); b43_phy_write(dev, B43_NPHY_TXMACDELAY, 0x0320);
if (phy->rev >= 3 && phy->rev <= 6) if (phy->rev >= 3 && phy->rev <= 6)
b43_phy_write(dev, B43_NPHY_PLOAD_CSENSE_EXTLEN, 0x0014); b43_phy_write(dev, B43_NPHY_PLOAD_CSENSE_EXTLEN, 0x0032);
b43_nphy_tx_lp_fbw(dev); b43_nphy_tx_lp_fbw(dev);
if (phy->rev >= 3) if (phy->rev >= 3)
b43_nphy_spur_workaround(dev); b43_nphy_spur_workaround(dev);
@ -5441,8 +5664,11 @@ static u16 b43_nphy_op_radio_read(struct b43_wldev *dev, u16 reg)
{ {
/* Register 1 is a 32-bit register. */ /* Register 1 is a 32-bit register. */
B43_WARN_ON(reg == 1); B43_WARN_ON(reg == 1);
/* N-PHY needs 0x100 for read access */
reg |= 0x100; if (dev->phy.rev >= 7)
reg |= 0x200; /* Radio 0x2057 */
else
reg |= 0x100;
b43_write16(dev, B43_MMIO_RADIO_CONTROL, reg); b43_write16(dev, B43_MMIO_RADIO_CONTROL, reg);
return b43_read16(dev, B43_MMIO_RADIO_DATA_LOW); return b43_read16(dev, B43_MMIO_RADIO_DATA_LOW);

Просмотреть файл

@ -48,7 +48,7 @@ struct b2056_inittabs_pts {
unsigned int rx_length; unsigned int rx_length;
}; };
static const struct b2056_inittab_entry b2056_inittab_rev3_syn[] = { static const struct b2056_inittab_entry b2056_inittab_phy_rev3_syn[] = {
[B2056_SYN_RESERVED_ADDR2] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, [B2056_SYN_RESERVED_ADDR2] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
[B2056_SYN_RESERVED_ADDR3] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, [B2056_SYN_RESERVED_ADDR3] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
[B2056_SYN_RESERVED_ADDR4] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, [B2056_SYN_RESERVED_ADDR4] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
@ -232,7 +232,7 @@ static const struct b2056_inittab_entry b2056_inittab_rev3_syn[] = {
[B2056_SYN_LOGEN_TX_CMOS_VALID] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, [B2056_SYN_LOGEN_TX_CMOS_VALID] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
}; };
static const struct b2056_inittab_entry b2056_inittab_rev3_tx[] = { static const struct b2056_inittab_entry b2056_inittab_phy_rev3_tx[] = {
[B2056_TX_RESERVED_ADDR2] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, [B2056_TX_RESERVED_ADDR2] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
[B2056_TX_RESERVED_ADDR3] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, [B2056_TX_RESERVED_ADDR3] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
[B2056_TX_RESERVED_ADDR4] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, [B2056_TX_RESERVED_ADDR4] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
@ -380,7 +380,7 @@ static const struct b2056_inittab_entry b2056_inittab_rev3_tx[] = {
[B2056_TX_STATUS_TXLPF_RC] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, [B2056_TX_STATUS_TXLPF_RC] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
}; };
static const struct b2056_inittab_entry b2056_inittab_rev3_rx[] = { static const struct b2056_inittab_entry b2056_inittab_phy_rev3_rx[] = {
[B2056_RX_RESERVED_ADDR2] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, [B2056_RX_RESERVED_ADDR2] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
[B2056_RX_RESERVED_ADDR3] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, [B2056_RX_RESERVED_ADDR3] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
[B2056_RX_RESERVED_ADDR4] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, [B2056_RX_RESERVED_ADDR4] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
@ -530,7 +530,7 @@ static const struct b2056_inittab_entry b2056_inittab_rev3_rx[] = {
[B2056_RX_STATUS_HPC_RC] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, [B2056_RX_STATUS_HPC_RC] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
}; };
static const struct b2056_inittab_entry b2056_inittab_rev4_syn[] = { static const struct b2056_inittab_entry b2056_inittab_phy_rev4_syn[] = {
[B2056_SYN_RESERVED_ADDR2] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, [B2056_SYN_RESERVED_ADDR2] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
[B2056_SYN_RESERVED_ADDR3] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, [B2056_SYN_RESERVED_ADDR3] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
[B2056_SYN_RESERVED_ADDR4] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, [B2056_SYN_RESERVED_ADDR4] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
@ -714,7 +714,7 @@ static const struct b2056_inittab_entry b2056_inittab_rev4_syn[] = {
[B2056_SYN_LOGEN_TX_CMOS_VALID] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, [B2056_SYN_LOGEN_TX_CMOS_VALID] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
}; };
static const struct b2056_inittab_entry b2056_inittab_rev4_tx[] = { static const struct b2056_inittab_entry b2056_inittab_phy_rev4_tx[] = {
[B2056_TX_RESERVED_ADDR2] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, [B2056_TX_RESERVED_ADDR2] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
[B2056_TX_RESERVED_ADDR3] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, [B2056_TX_RESERVED_ADDR3] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
[B2056_TX_RESERVED_ADDR4] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, [B2056_TX_RESERVED_ADDR4] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
@ -862,7 +862,7 @@ static const struct b2056_inittab_entry b2056_inittab_rev4_tx[] = {
[B2056_TX_STATUS_TXLPF_RC] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, [B2056_TX_STATUS_TXLPF_RC] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
}; };
static const struct b2056_inittab_entry b2056_inittab_rev4_rx[] = { static const struct b2056_inittab_entry b2056_inittab_phy_rev4_rx[] = {
[B2056_RX_RESERVED_ADDR2] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, [B2056_RX_RESERVED_ADDR2] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
[B2056_RX_RESERVED_ADDR3] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, [B2056_RX_RESERVED_ADDR3] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
[B2056_RX_RESERVED_ADDR4] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, [B2056_RX_RESERVED_ADDR4] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
@ -1012,7 +1012,7 @@ static const struct b2056_inittab_entry b2056_inittab_rev4_rx[] = {
[B2056_RX_STATUS_HPC_RC] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, [B2056_RX_STATUS_HPC_RC] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
}; };
static const struct b2056_inittab_entry b2056_inittab_rev5_syn[] = { static const struct b2056_inittab_entry b2056_inittab_radio_rev5_syn[] = {
[B2056_SYN_RESERVED_ADDR2] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, [B2056_SYN_RESERVED_ADDR2] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
[B2056_SYN_RESERVED_ADDR3] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, [B2056_SYN_RESERVED_ADDR3] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
[B2056_SYN_RESERVED_ADDR4] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, [B2056_SYN_RESERVED_ADDR4] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
@ -1196,7 +1196,7 @@ static const struct b2056_inittab_entry b2056_inittab_rev5_syn[] = {
[B2056_SYN_LOGEN_TX_CMOS_VALID] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, [B2056_SYN_LOGEN_TX_CMOS_VALID] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
}; };
static const struct b2056_inittab_entry b2056_inittab_rev5_tx[] = { static const struct b2056_inittab_entry b2056_inittab_radio_rev5_tx[] = {
[B2056_TX_RESERVED_ADDR2] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, [B2056_TX_RESERVED_ADDR2] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
[B2056_TX_RESERVED_ADDR3] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, [B2056_TX_RESERVED_ADDR3] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
[B2056_TX_RESERVED_ADDR4] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, [B2056_TX_RESERVED_ADDR4] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
@ -1352,7 +1352,7 @@ static const struct b2056_inittab_entry b2056_inittab_rev5_tx[] = {
[B2056_TX_GMBB_IDAC7] = { .ghz5 = 0x0075, .ghz2 = 0x0075, UPLOAD, }, [B2056_TX_GMBB_IDAC7] = { .ghz5 = 0x0075, .ghz2 = 0x0075, UPLOAD, },
}; };
static const struct b2056_inittab_entry b2056_inittab_rev5_rx[] = { static const struct b2056_inittab_entry b2056_inittab_radio_rev5_rx[] = {
[B2056_RX_RESERVED_ADDR2] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, [B2056_RX_RESERVED_ADDR2] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
[B2056_RX_RESERVED_ADDR3] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, [B2056_RX_RESERVED_ADDR3] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
[B2056_RX_RESERVED_ADDR4] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, [B2056_RX_RESERVED_ADDR4] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
@ -1502,7 +1502,7 @@ static const struct b2056_inittab_entry b2056_inittab_rev5_rx[] = {
[B2056_RX_STATUS_HPC_RC] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, [B2056_RX_STATUS_HPC_RC] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
}; };
static const struct b2056_inittab_entry b2056_inittab_rev6_syn[] = { static const struct b2056_inittab_entry b2056_inittab_radio_rev6_syn[] = {
[B2056_SYN_RESERVED_ADDR2] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, [B2056_SYN_RESERVED_ADDR2] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
[B2056_SYN_RESERVED_ADDR3] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, [B2056_SYN_RESERVED_ADDR3] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
[B2056_SYN_RESERVED_ADDR4] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, [B2056_SYN_RESERVED_ADDR4] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
@ -1686,7 +1686,7 @@ static const struct b2056_inittab_entry b2056_inittab_rev6_syn[] = {
[B2056_SYN_LOGEN_TX_CMOS_VALID] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, [B2056_SYN_LOGEN_TX_CMOS_VALID] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
}; };
static const struct b2056_inittab_entry b2056_inittab_rev6_tx[] = { static const struct b2056_inittab_entry b2056_inittab_radio_rev6_tx[] = {
[B2056_TX_RESERVED_ADDR2] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, [B2056_TX_RESERVED_ADDR2] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
[B2056_TX_RESERVED_ADDR3] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, [B2056_TX_RESERVED_ADDR3] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
[B2056_TX_RESERVED_ADDR4] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, [B2056_TX_RESERVED_ADDR4] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
@ -1842,7 +1842,7 @@ static const struct b2056_inittab_entry b2056_inittab_rev6_tx[] = {
[B2056_TX_GMBB_IDAC7] = { .ghz5 = 0x0070, .ghz2 = 0x0070, NOUPLOAD, }, [B2056_TX_GMBB_IDAC7] = { .ghz5 = 0x0070, .ghz2 = 0x0070, NOUPLOAD, },
}; };
static const struct b2056_inittab_entry b2056_inittab_rev6_rx[] = { static const struct b2056_inittab_entry b2056_inittab_radio_rev6_rx[] = {
[B2056_RX_RESERVED_ADDR2] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, [B2056_RX_RESERVED_ADDR2] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
[B2056_RX_RESERVED_ADDR3] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, [B2056_RX_RESERVED_ADDR3] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
[B2056_RX_RESERVED_ADDR4] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, [B2056_RX_RESERVED_ADDR4] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
@ -1992,7 +1992,7 @@ static const struct b2056_inittab_entry b2056_inittab_rev6_rx[] = {
[B2056_RX_STATUS_HPC_RC] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, [B2056_RX_STATUS_HPC_RC] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
}; };
static const struct b2056_inittab_entry b2056_inittab_rev7_syn[] = { static const struct b2056_inittab_entry b2056_inittab_radio_rev7_9_syn[] = {
[B2056_SYN_RESERVED_ADDR2] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, [B2056_SYN_RESERVED_ADDR2] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
[B2056_SYN_RESERVED_ADDR3] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, [B2056_SYN_RESERVED_ADDR3] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
[B2056_SYN_RESERVED_ADDR4] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, [B2056_SYN_RESERVED_ADDR4] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
@ -2176,7 +2176,7 @@ static const struct b2056_inittab_entry b2056_inittab_rev7_syn[] = {
[B2056_SYN_LOGEN_TX_CMOS_VALID] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, [B2056_SYN_LOGEN_TX_CMOS_VALID] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
}; };
static const struct b2056_inittab_entry b2056_inittab_rev7_tx[] = { static const struct b2056_inittab_entry b2056_inittab_radio_rev7_9_tx[] = {
[B2056_TX_RESERVED_ADDR2] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, [B2056_TX_RESERVED_ADDR2] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
[B2056_TX_RESERVED_ADDR3] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, [B2056_TX_RESERVED_ADDR3] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
[B2056_TX_RESERVED_ADDR4] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, [B2056_TX_RESERVED_ADDR4] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
@ -2332,7 +2332,7 @@ static const struct b2056_inittab_entry b2056_inittab_rev7_tx[] = {
[B2056_TX_GMBB_IDAC7] = { .ghz5 = 0x0075, .ghz2 = 0x0075, UPLOAD, }, [B2056_TX_GMBB_IDAC7] = { .ghz5 = 0x0075, .ghz2 = 0x0075, UPLOAD, },
}; };
static const struct b2056_inittab_entry b2056_inittab_rev7_rx[] = { static const struct b2056_inittab_entry b2056_inittab_radio_rev7_9_rx[] = {
[B2056_RX_RESERVED_ADDR2] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, [B2056_RX_RESERVED_ADDR2] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
[B2056_RX_RESERVED_ADDR3] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, [B2056_RX_RESERVED_ADDR3] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
[B2056_RX_RESERVED_ADDR4] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, [B2056_RX_RESERVED_ADDR4] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
@ -2482,7 +2482,7 @@ static const struct b2056_inittab_entry b2056_inittab_rev7_rx[] = {
[B2056_RX_STATUS_HPC_RC] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, [B2056_RX_STATUS_HPC_RC] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
}; };
static const struct b2056_inittab_entry b2056_inittab_rev8_syn[] = { static const struct b2056_inittab_entry b2056_inittab_radio_rev8_syn[] = {
[B2056_SYN_RESERVED_ADDR2] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, [B2056_SYN_RESERVED_ADDR2] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
[B2056_SYN_RESERVED_ADDR3] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, [B2056_SYN_RESERVED_ADDR3] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
[B2056_SYN_RESERVED_ADDR4] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, [B2056_SYN_RESERVED_ADDR4] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
@ -2666,7 +2666,7 @@ static const struct b2056_inittab_entry b2056_inittab_rev8_syn[] = {
[B2056_SYN_LOGEN_TX_CMOS_VALID] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, [B2056_SYN_LOGEN_TX_CMOS_VALID] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
}; };
static const struct b2056_inittab_entry b2056_inittab_rev8_tx[] = { static const struct b2056_inittab_entry b2056_inittab_radio_rev8_tx[] = {
[B2056_TX_RESERVED_ADDR2] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, [B2056_TX_RESERVED_ADDR2] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
[B2056_TX_RESERVED_ADDR3] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, [B2056_TX_RESERVED_ADDR3] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
[B2056_TX_RESERVED_ADDR4] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, [B2056_TX_RESERVED_ADDR4] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
@ -2822,7 +2822,7 @@ static const struct b2056_inittab_entry b2056_inittab_rev8_tx[] = {
[B2056_TX_GMBB_IDAC7] = { .ghz5 = 0x0070, .ghz2 = 0x0070, NOUPLOAD, }, [B2056_TX_GMBB_IDAC7] = { .ghz5 = 0x0070, .ghz2 = 0x0070, NOUPLOAD, },
}; };
static const struct b2056_inittab_entry b2056_inittab_rev8_rx[] = { static const struct b2056_inittab_entry b2056_inittab_radio_rev8_rx[] = {
[B2056_RX_RESERVED_ADDR2] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, [B2056_RX_RESERVED_ADDR2] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
[B2056_RX_RESERVED_ADDR3] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, [B2056_RX_RESERVED_ADDR3] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
[B2056_RX_RESERVED_ADDR4] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, [B2056_RX_RESERVED_ADDR4] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
@ -2972,24 +2972,69 @@ static const struct b2056_inittab_entry b2056_inittab_rev8_rx[] = {
[B2056_RX_STATUS_HPC_RC] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, [B2056_RX_STATUS_HPC_RC] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
}; };
#define INITTABSPTS(prefix) \ static const struct b2056_inittab_entry b2056_inittab_radio_rev11_syn[] = {
.syn = prefix##_syn, \ [B2056_SYN_PLL_PFD] = { .ghz5 = 0x0006, .ghz2 = 0x0006, UPLOAD, },
.syn_length = ARRAY_SIZE(prefix##_syn), \ [B2056_SYN_PLL_CP2] = { .ghz5 = 0x003f, .ghz2 = 0x003f, UPLOAD, },
.tx = prefix##_tx, \ [B2056_SYN_PLL_LOOPFILTER1] = { .ghz5 = 0x0006, .ghz2 = 0x0006, UPLOAD, },
.tx_length = ARRAY_SIZE(prefix##_tx), \ [B2056_SYN_PLL_LOOPFILTER2] = { .ghz5 = 0x0006, .ghz2 = 0x0006, UPLOAD, },
.rx = prefix##_rx, \ [B2056_SYN_PLL_LOOPFILTER4] = { .ghz5 = 0x002b, .ghz2 = 0x002b, UPLOAD, },
.rx_length = ARRAY_SIZE(prefix##_rx) [B2056_SYN_PLL_VCO2] = { .ghz5 = 0x00f7, .ghz2 = 0x00f7, UPLOAD, },
[B2056_SYN_PLL_VCOCAL12] = { .ghz5 = 0x0007, .ghz2 = 0x0007, UPLOAD, },
static const struct b2056_inittabs_pts b2056_inittabs[] = { [B2056_SYN_LOGENBUF2] = { .ghz5 = 0x008f, .ghz2 = 0x008f, UPLOAD, },
[3] = { INITTABSPTS(b2056_inittab_rev3) },
[4] = { INITTABSPTS(b2056_inittab_rev4) },
[5] = { INITTABSPTS(b2056_inittab_rev5) },
[6] = { INITTABSPTS(b2056_inittab_rev6) },
[7] = { INITTABSPTS(b2056_inittab_rev7) },
[8] = { INITTABSPTS(b2056_inittab_rev8) },
[9] = { INITTABSPTS(b2056_inittab_rev7) },
}; };
static const struct b2056_inittab_entry b2056_inittab_radio_rev11_tx[] = {
[B2056_TX_PA_SPARE2] = { .ghz5 = 0x00ee, .ghz2 = 0x00ee, UPLOAD, },
[B2056_TX_INTPAA_IAUX_STAT] = { .ghz5 = 0x0050, .ghz2 = 0x0050, UPLOAD, },
[B2056_TX_INTPAA_IMAIN_STAT] = { .ghz5 = 0x0050, .ghz2 = 0x0050, UPLOAD, },
[B2056_TX_INTPAA_PASLOPE] = { .ghz5 = 0x00f0, .ghz2 = 0x00f0, UPLOAD, },
[B2056_TX_INTPAG_PASLOPE] = { .ghz5 = 0x00f0, .ghz2 = 0x00f0, UPLOAD, },
[B2056_TX_PADA_IDAC] = { .ghz5 = 0x00ff, .ghz2 = 0x00ff, UPLOAD, },
[B2056_TX_PADA_SLOPE] = { .ghz5 = 0x0070, .ghz2 = 0x0070, UPLOAD, },
[B2056_TX_PADG_SLOPE] = { .ghz5 = 0x0070, .ghz2 = 0x0070, UPLOAD, },
[B2056_TX_PGAA_IDAC] = { .ghz5 = 0x00ff, .ghz2 = 0x00ff, UPLOAD, },
[B2056_TX_PGAA_SLOPE] = { .ghz5 = 0x0077, .ghz2 = 0x0077, UPLOAD, },
[B2056_TX_PGAG_SLOPE] = { .ghz5 = 0x0077, .ghz2 = 0x0077, UPLOAD, },
[B2056_TX_GMBB_IDAC] = { .ghz5 = 0x0000, .ghz2 = 0x0000, UPLOAD, },
[B2056_TX_TXSPARE1] = { .ghz5 = 0x0030, .ghz2 = 0x0030, UPLOAD, },
};
static const struct b2056_inittab_entry b2056_inittab_radio_rev11_rx[] = {
[B2056_RX_BIASPOLE_LNAA1_IDAC] = { .ghz5 = 0x0017, .ghz2 = 0x0017, UPLOAD, },
[B2056_RX_LNAA2_IDAC] = { .ghz5 = 0x00ff, .ghz2 = 0x00ff, UPLOAD, },
[B2056_RX_BIASPOLE_LNAG1_IDAC] = { .ghz5 = 0x0017, .ghz2 = 0x0017, UPLOAD, },
[B2056_RX_LNAG2_IDAC] = { .ghz5 = 0x00f0, .ghz2 = 0x00f0, UPLOAD, },
[B2056_RX_MIXA_VCM] = { .ghz5 = 0x0055, .ghz2 = 0x0055, UPLOAD, },
[B2056_RX_MIXA_LOB_BIAS] = { .ghz5 = 0x0088, .ghz2 = 0x0088, UPLOAD, },
[B2056_RX_MIXA_BIAS_AUX] = { .ghz5 = 0x0007, .ghz2 = 0x0007, UPLOAD, },
[B2056_RX_MIXG_VCM] = { .ghz5 = 0x0055, .ghz2 = 0x0055, UPLOAD, },
[B2056_RX_TIA_IOPAMP] = { .ghz5 = 0x0026, .ghz2 = 0x0026, UPLOAD, },
[B2056_RX_TIA_QOPAMP] = { .ghz5 = 0x0026, .ghz2 = 0x0026, UPLOAD, },
[B2056_RX_TIA_IMISC] = { .ghz5 = 0x000f, .ghz2 = 0x000f, UPLOAD, },
[B2056_RX_TIA_QMISC] = { .ghz5 = 0x000f, .ghz2 = 0x000f, UPLOAD, },
[B2056_RX_RXLPF_OUTVCM] = { .ghz5 = 0x0004, .ghz2 = 0x0004, UPLOAD, },
[B2056_RX_VGA_BIAS_DCCANCEL] = { .ghz5 = 0x0000, .ghz2 = 0x0000, UPLOAD, },
[B2056_RX_RXSPARE3] = { .ghz5 = 0x0005, .ghz2 = 0x0005, UPLOAD, },
};
#define INITTABSPTS(prefix) \
static const struct b2056_inittabs_pts prefix = { \
.syn = prefix##_syn, \
.syn_length = ARRAY_SIZE(prefix##_syn), \
.tx = prefix##_tx, \
.tx_length = ARRAY_SIZE(prefix##_tx), \
.rx = prefix##_rx, \
.rx_length = ARRAY_SIZE(prefix##_rx), \
}
INITTABSPTS(b2056_inittab_phy_rev3);
INITTABSPTS(b2056_inittab_phy_rev4);
INITTABSPTS(b2056_inittab_radio_rev5);
INITTABSPTS(b2056_inittab_radio_rev6);
INITTABSPTS(b2056_inittab_radio_rev7_9);
INITTABSPTS(b2056_inittab_radio_rev8);
INITTABSPTS(b2056_inittab_radio_rev11);
#define RADIOREGS3(r00, r01, r02, r03, r04, r05, r06, r07, r08, r09, \ #define RADIOREGS3(r00, r01, r02, r03, r04, r05, r06, r07, r08, r09, \
r10, r11, r12, r13, r14, r15, r16, r17, r18, r19, \ r10, r11, r12, r13, r14, r15, r16, r17, r18, r19, \
r20, r21, r22, r23, r24, r25, r26, r27, r28, r29, \ r20, r21, r22, r23, r24, r25, r26, r27, r28, r29, \
@ -3041,7 +3086,7 @@ static const struct b2056_inittabs_pts b2056_inittabs[] = {
.phy_regs.phy_bw6 = r5 .phy_regs.phy_bw6 = r5
/* http://bcm-v4.sipsolutions.net/802.11/Radio/2056/ChannelTable */ /* http://bcm-v4.sipsolutions.net/802.11/Radio/2056/ChannelTable */
static const struct b43_nphy_channeltab_entry_rev3 b43_nphy_channeltab_rev3[] = { static const struct b43_nphy_channeltab_entry_rev3 b43_nphy_channeltab_phy_rev3[] = {
{ .freq = 4920, { .freq = 4920,
RADIOREGS3(0xff, 0x01, 0x01, 0x01, 0xec, 0x05, 0x05, 0x04, RADIOREGS3(0xff, 0x01, 0x01, 0x01, 0xec, 0x05, 0x05, 0x04,
0x0c, 0x01, 0x00, 0x00, 0x00, 0x8f, 0x0f, 0x00, 0x0c, 0x01, 0x00, 0x00, 0x00, 0x8f, 0x0f, 0x00,
@ -4036,7 +4081,7 @@ static const struct b43_nphy_channeltab_entry_rev3 b43_nphy_channeltab_rev3[] =
}, },
}; };
static const struct b43_nphy_channeltab_entry_rev3 b43_nphy_channeltab_rev4[] = { static const struct b43_nphy_channeltab_entry_rev3 b43_nphy_channeltab_phy_rev4[] = {
{ .freq = 4920, { .freq = 4920,
RADIOREGS3(0xff, 0x01, 0x01, 0x01, 0xec, 0x05, 0x05, 0x04, RADIOREGS3(0xff, 0x01, 0x01, 0x01, 0xec, 0x05, 0x05, 0x04,
0x0c, 0x01, 0x00, 0x00, 0x00, 0x8f, 0x0f, 0x00, 0x0c, 0x01, 0x00, 0x00, 0x00, 0x8f, 0x0f, 0x00,
@ -5031,7 +5076,7 @@ static const struct b43_nphy_channeltab_entry_rev3 b43_nphy_channeltab_rev4[] =
}, },
}; };
static const struct b43_nphy_channeltab_entry_rev3 b43_nphy_channeltab_rev5[] = { static const struct b43_nphy_channeltab_entry_rev3 b43_nphy_channeltab_radio_rev5[] = {
{ .freq = 4920, { .freq = 4920,
RADIOREGS3(0xff, 0x01, 0x01, 0x01, 0xec, 0x05, 0x05, 0x04, RADIOREGS3(0xff, 0x01, 0x01, 0x01, 0xec, 0x05, 0x05, 0x04,
0x0c, 0x01, 0x00, 0x00, 0x00, 0x8f, 0x0f, 0x00, 0x0c, 0x01, 0x00, 0x00, 0x00, 0x8f, 0x0f, 0x00,
@ -6026,7 +6071,7 @@ static const struct b43_nphy_channeltab_entry_rev3 b43_nphy_channeltab_rev5[] =
}, },
}; };
static const struct b43_nphy_channeltab_entry_rev3 b43_nphy_channeltab_rev6[] = { static const struct b43_nphy_channeltab_entry_rev3 b43_nphy_channeltab_radio_rev6[] = {
{ .freq = 4920, { .freq = 4920,
RADIOREGS3(0xff, 0x01, 0x01, 0x01, 0xec, 0x05, 0x05, 0x04, RADIOREGS3(0xff, 0x01, 0x01, 0x01, 0xec, 0x05, 0x05, 0x04,
0x0c, 0x01, 0x00, 0x00, 0x00, 0x8f, 0x0f, 0x00, 0x0c, 0x01, 0x00, 0x00, 0x00, 0x8f, 0x0f, 0x00,
@ -7021,7 +7066,7 @@ static const struct b43_nphy_channeltab_entry_rev3 b43_nphy_channeltab_rev6[] =
}, },
}; };
static const struct b43_nphy_channeltab_entry_rev3 b43_nphy_channeltab_rev7_9[] = { static const struct b43_nphy_channeltab_entry_rev3 b43_nphy_channeltab_radio_rev7_9[] = {
{ .freq = 4920, { .freq = 4920,
RADIOREGS3(0xff, 0x01, 0x01, 0x01, 0xec, 0x05, 0x05, 0x04, RADIOREGS3(0xff, 0x01, 0x01, 0x01, 0xec, 0x05, 0x05, 0x04,
0x0c, 0x01, 0x00, 0x00, 0x00, 0x8f, 0x0f, 0x00, 0x0c, 0x01, 0x00, 0x00, 0x00, 0x8f, 0x0f, 0x00,
@ -8016,7 +8061,7 @@ static const struct b43_nphy_channeltab_entry_rev3 b43_nphy_channeltab_rev7_9[]
}, },
}; };
static const struct b43_nphy_channeltab_entry_rev3 b43_nphy_channeltab_rev8[] = { static const struct b43_nphy_channeltab_entry_rev3 b43_nphy_channeltab_radio_rev8[] = {
{ .freq = 4920, { .freq = 4920,
RADIOREGS3(0xff, 0x01, 0x01, 0x01, 0xec, 0x05, 0x05, 0x04, RADIOREGS3(0xff, 0x01, 0x01, 0x01, 0xec, 0x05, 0x05, 0x04,
0x0c, 0x01, 0x00, 0x00, 0x00, 0x8f, 0x0f, 0x00, 0x0c, 0x01, 0x00, 0x00, 0x00, 0x8f, 0x0f, 0x00,
@ -9011,6 +9056,236 @@ static const struct b43_nphy_channeltab_entry_rev3 b43_nphy_channeltab_rev8[] =
}, },
}; };
static const struct b43_nphy_channeltab_entry_rev3 b43_nphy_channeltab_radio_rev11[] = {
{
.freq = 5180,
RADIOREGS3(0xb6, 0x01, 0x01, 0x02, 0x06, 0x05, 0x05, 0x02,
0x0c, 0x01, 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00,
0xff, 0xf9, 0x00, 0x06, 0x00, 0x77, 0x00, 0x0e,
0x00, 0x6f, 0x00, 0xf9, 0x00, 0x06, 0x00, 0x77,
0x00, 0x0e, 0x00, 0x6f, 0x00),
PHYREGS(0x081c, 0x0818, 0x0814, 0x01f9, 0x01fa, 0x01fb),
},
{
.freq = 5200,
RADIOREGS3(0xaf, 0x01, 0x01, 0x02, 0x08, 0x05, 0x05, 0x02,
0x0c, 0x01, 0x02, 0x02, 0x02, 0x8f, 0x0f, 0x00,
0xff, 0xf9, 0x00, 0x05, 0x00, 0x77, 0x00, 0x0d,
0x00, 0x6f, 0x00, 0xf9, 0x00, 0x05, 0x00, 0x77,
0x00, 0x0d, 0x00, 0x6f, 0x00),
PHYREGS(0x0824, 0x0820, 0x081c, 0x01f7, 0x01f8, 0x01f9),
},
{
.freq = 5220,
RADIOREGS3(0xa7, 0x01, 0x01, 0x02, 0x0a, 0x05, 0x05, 0x02,
0x0c, 0x01, 0x02, 0x02, 0x02, 0x8e, 0x0f, 0x00,
0xfe, 0xd8, 0x00, 0x05, 0x00, 0x77, 0x00, 0x0d,
0x00, 0x6f, 0x00, 0xd8, 0x00, 0x05, 0x00, 0x77,
0x00, 0x0d, 0x00, 0x6f, 0x00),
PHYREGS(0x082c, 0x0828, 0x0824, 0x01f5, 0x01f6, 0x01f7),
},
{
.freq = 5745,
RADIOREGS3(0xfe, 0x00, 0x02, 0x04, 0x7d, 0x05, 0x05, 0x02,
0x15, 0x01, 0x05, 0x05, 0x05, 0x87, 0x05, 0x00,
0x20, 0x30, 0x00, 0x00, 0x00, 0x77, 0x00, 0x06,
0x00, 0x6d, 0x00, 0x30, 0x00, 0x00, 0x00, 0x77,
0x00, 0x06, 0x00, 0x6d, 0x00),
PHYREGS(0x08fe, 0x08fa, 0x08f6, 0x01c8, 0x01c8, 0x01c9),
},
{
.freq = 5765,
RADIOREGS3(0xf8, 0x00, 0x02, 0x04, 0x81, 0x05, 0x05, 0x02,
0x15, 0x01, 0x05, 0x05, 0x05, 0x86, 0x05, 0x00,
0x10, 0x10, 0x00, 0x00, 0x00, 0x77, 0x00, 0x05,
0x00, 0x6c, 0x00, 0x10, 0x00, 0x00, 0x00, 0x77,
0x00, 0x05, 0x00, 0x6c, 0x00),
PHYREGS(0x0906, 0x0902, 0x08fe, 0x01c6, 0x01c7, 0x01c8),
},
{
.freq = 5785,
RADIOREGS3(0xf2, 0x00, 0x02, 0x04, 0x85, 0x05, 0x05, 0x02,
0x15, 0x01, 0x06, 0x06, 0x06, 0x86, 0x04, 0x00,
0x00, 0x10, 0x00, 0x00, 0x00, 0x77, 0x00, 0x05,
0x00, 0x6b, 0x00, 0x10, 0x00, 0x00, 0x00, 0x77,
0x00, 0x05, 0x00, 0x6b, 0x00),
PHYREGS(0x090e, 0x090a, 0x0906, 0x01c4, 0x01c5, 0x01c6),
},
{
.freq = 5805,
RADIOREGS3(0xed, 0x00, 0x02, 0x04, 0x89, 0x05, 0x05, 0x02,
0x15, 0x01, 0x06, 0x06, 0x06, 0x86, 0x04, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x77, 0x00, 0x05,
0x00, 0x6a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77,
0x00, 0x05, 0x00, 0x6a, 0x00),
PHYREGS(0x0916, 0x0912, 0x090e, 0x01c3, 0x01c4, 0x01c4),
},
{
.freq = 5825,
RADIOREGS3(0xed, 0x00, 0x02, 0x04, 0x8d, 0x05, 0x05, 0x02,
0x15, 0x01, 0x06, 0x06, 0x06, 0x86, 0x04, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x77, 0x00, 0x05,
0x00, 0x69, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77,
0x00, 0x05, 0x00, 0x69, 0x00),
PHYREGS(0x091e, 0x091a, 0x0916, 0x01c1, 0x01c2, 0x01c3),
},
{
.freq = 2412,
RADIOREGS3(0x00, 0x01, 0x03, 0x09, 0x6c, 0x06, 0x06, 0x04,
0x2b, 0x01, 0x04, 0x04, 0x04, 0x8f, 0x30, 0x00,
0x00, 0x00, 0x78, 0x00, 0x03, 0x00, 0x70, 0x00,
0x0b, 0x00, 0x0a, 0x00, 0x89, 0x00, 0x03, 0x00,
0x70, 0x00, 0x0b, 0x00, 0x0a),
PHYREGS(0x03c9, 0x03c5, 0x03c1, 0x043a, 0x043f, 0x0443),
},
{
.freq = 2417,
RADIOREGS3(0x00, 0x01, 0x03, 0x09, 0x71, 0x06, 0x06, 0x04,
0x2b, 0x01, 0x05, 0x05, 0x05, 0x8f, 0x30, 0x00,
0x00, 0x00, 0x78, 0x00, 0x03, 0x00, 0x70, 0x00,
0x0b, 0x00, 0x0a, 0x00, 0x89, 0x00, 0x03, 0x00,
0x70, 0x00, 0x0b, 0x00, 0x0a),
PHYREGS(0x03cb, 0x03c7, 0x03c3, 0x0438, 0x043d, 0x0441),
},
{
.freq = 2422,
RADIOREGS3(0x00, 0x01, 0x03, 0x09, 0x76, 0x06, 0x06, 0x04,
0x2b, 0x01, 0x05, 0x05, 0x05, 0x8f, 0x30, 0x00,
0x00, 0x00, 0x67, 0x00, 0x03, 0x00, 0x70, 0x00,
0x0b, 0x00, 0x0a, 0x00, 0x89, 0x00, 0x03, 0x00,
0x70, 0x00, 0x0b, 0x00, 0x0a),
PHYREGS(0x03cd, 0x03c9, 0x03c5, 0x0436, 0x043a, 0x043f),
},
{
.freq = 2427,
RADIOREGS3(0x00, 0x01, 0x03, 0x09, 0x7b, 0x06, 0x06, 0x04,
0x2b, 0x01, 0x05, 0x05, 0x05, 0x8f, 0x30, 0x00,
0x00, 0x00, 0x57, 0x00, 0x03, 0x00, 0x70, 0x00,
0x0a, 0x00, 0x0a, 0x00, 0x78, 0x00, 0x03, 0x00,
0x70, 0x00, 0x0a, 0x00, 0x0a),
PHYREGS(0x03cf, 0x03cb, 0x03c7, 0x0434, 0x0438, 0x043d),
},
{
.freq = 2432,
RADIOREGS3(0x00, 0x01, 0x03, 0x09, 0x80, 0x06, 0x06, 0x04,
0x2b, 0x01, 0x05, 0x05, 0x05, 0x8f, 0x30, 0x00,
0x00, 0x00, 0x56, 0x00, 0x03, 0x00, 0x70, 0x00,
0x0a, 0x00, 0x0a, 0x00, 0x77, 0x00, 0x03, 0x00,
0x70, 0x00, 0x0a, 0x00, 0x0a),
PHYREGS(0x03d1, 0x03cd, 0x03c9, 0x0431, 0x0436, 0x043a),
},
{
.freq = 2437,
RADIOREGS3(0x00, 0x01, 0x03, 0x09, 0x85, 0x06, 0x06, 0x04,
0x2b, 0x01, 0x05, 0x05, 0x05, 0x8f, 0x30, 0x00,
0x00, 0x00, 0x46, 0x00, 0x03, 0x00, 0x70, 0x00,
0x0a, 0x00, 0x0a, 0x00, 0x76, 0x00, 0x03, 0x00,
0x70, 0x00, 0x0a, 0x00, 0x0a),
PHYREGS(0x03d3, 0x03cf, 0x03cb, 0x042f, 0x0434, 0x0438),
},
{
.freq = 2442,
RADIOREGS3(0x00, 0x01, 0x03, 0x09, 0x8a, 0x06, 0x06, 0x04,
0x2b, 0x01, 0x05, 0x05, 0x05, 0x8f, 0x30, 0x00,
0x00, 0x00, 0x45, 0x00, 0x02, 0x00, 0x70, 0x00,
0x0a, 0x00, 0x0a, 0x00, 0x66, 0x00, 0x02, 0x00,
0x70, 0x00, 0x0a, 0x00, 0x0a),
PHYREGS(0x03d5, 0x03d1, 0x03cd, 0x042d, 0x0431, 0x0436),
},
{
.freq = 2447,
RADIOREGS3(0x00, 0x01, 0x03, 0x09, 0x8f, 0x06, 0x06, 0x04,
0x2b, 0x01, 0x06, 0x06, 0x06, 0x8f, 0x30, 0x00,
0x00, 0x00, 0x34, 0x00, 0x02, 0x00, 0x70, 0x00,
0x0a, 0x00, 0x09, 0x00, 0x55, 0x00, 0x02, 0x00,
0x70, 0x00, 0x0a, 0x00, 0x09),
PHYREGS(0x03d7, 0x03d3, 0x03cf, 0x042b, 0x042f, 0x0434),
},
{
.freq = 2452,
RADIOREGS3(0x00, 0x01, 0x03, 0x09, 0x94, 0x06, 0x06, 0x04,
0x2b, 0x01, 0x06, 0x06, 0x06, 0x8f, 0x30, 0x00,
0x00, 0x00, 0x23, 0x00, 0x02, 0x00, 0x70, 0x00,
0x0a, 0x00, 0x09, 0x00, 0x45, 0x00, 0x02, 0x00,
0x70, 0x00, 0x0a, 0x00, 0x09),
PHYREGS(0x03d9, 0x03d5, 0x03d1, 0x0429, 0x042d, 0x0431),
},
{
.freq = 2457,
RADIOREGS3(0x00, 0x01, 0x03, 0x09, 0x99, 0x06, 0x06, 0x04,
0x2b, 0x01, 0x06, 0x06, 0x06, 0x8f, 0x30, 0x00,
0x00, 0x00, 0x12, 0x00, 0x02, 0x00, 0x70, 0x00,
0x0a, 0x00, 0x09, 0x00, 0x34, 0x00, 0x02, 0x00,
0x70, 0x00, 0x0a, 0x00, 0x09),
PHYREGS(0x03db, 0x03d7, 0x03d3, 0x0427, 0x042b, 0x042f),
},
{
.freq = 2462,
RADIOREGS3(0x00, 0x01, 0x03, 0x09, 0x9e, 0x06, 0x06, 0x04,
0x2b, 0x01, 0x06, 0x06, 0x06, 0x8f, 0x30, 0x00,
0x00, 0x00, 0x02, 0x00, 0x02, 0x00, 0x70, 0x00,
0x09, 0x00, 0x09, 0x00, 0x33, 0x00, 0x02, 0x00,
0x70, 0x00, 0x09, 0x00, 0x09),
PHYREGS(0x03dd, 0x03d9, 0x03d5, 0x0424, 0x0429, 0x042d),
},
{
.freq = 2467,
RADIOREGS3(0x00, 0x01, 0x03, 0x09, 0xa3, 0x06, 0x06, 0x04,
0x2b, 0x01, 0x06, 0x06, 0x06, 0x8f, 0x30, 0x00,
0x00, 0x00, 0x01, 0x00, 0x02, 0x00, 0x70, 0x00,
0x09, 0x00, 0x09, 0x00, 0x22, 0x00, 0x02, 0x00,
0x70, 0x00, 0x09, 0x00, 0x09),
PHYREGS(0x03df, 0x03db, 0x03d7, 0x0422, 0x0427, 0x042b),
},
{
.freq = 2472,
RADIOREGS3(0x00, 0x01, 0x03, 0x09, 0xa8, 0x06, 0x06, 0x04,
0x2b, 0x01, 0x07, 0x07, 0x07, 0x8f, 0x30, 0x00,
0x00, 0x00, 0x01, 0x00, 0x02, 0x00, 0x70, 0x00,
0x09, 0x00, 0x09, 0x00, 0x11, 0x00, 0x02, 0x00,
0x70, 0x00, 0x09, 0x00, 0x09),
PHYREGS(0x03e1, 0x03dd, 0x03d9, 0x0420, 0x0424, 0x0429),
},
{
.freq = 2484,
RADIOREGS3(0xff, 0x01, 0x03, 0x09, 0xb4, 0x06, 0x06, 0x04,
0x2b, 0x01, 0x07, 0x07, 0x07, 0x8f, 0x20, 0x00,
0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x70, 0x00,
0x09, 0x00, 0x09, 0x00, 0x00, 0x00, 0x02, 0x00,
0x70, 0x00, 0x09, 0x00, 0x09),
PHYREGS(0x03e6, 0x03e2, 0x03de, 0x041b, 0x041f, 0x0424),
},
};
static const struct b2056_inittabs_pts
*b43_nphy_get_inittabs_rev3(struct b43_wldev *dev)
{
struct b43_phy *phy = &dev->phy;
switch (dev->phy.rev) {
case 3:
return &b2056_inittab_phy_rev3;
case 4:
return &b2056_inittab_phy_rev4;
default:
switch (phy->radio_rev) {
case 5:
return &b2056_inittab_radio_rev5;
case 6:
return &b2056_inittab_radio_rev6;
case 7:
case 9:
return &b2056_inittab_radio_rev7_9;
case 8:
return &b2056_inittab_radio_rev8;
case 11:
return &b2056_inittab_radio_rev11;
}
}
return NULL;
}
static void b2056_upload_inittab(struct b43_wldev *dev, bool ghz5, static void b2056_upload_inittab(struct b43_wldev *dev, bool ghz5,
bool ignore_uploadflag, u16 routing, bool ignore_uploadflag, u16 routing,
const struct b2056_inittab_entry *e, const struct b2056_inittab_entry *e,
@ -9037,11 +9312,11 @@ void b2056_upload_inittabs(struct b43_wldev *dev,
{ {
const struct b2056_inittabs_pts *pts; const struct b2056_inittabs_pts *pts;
if (dev->phy.rev >= ARRAY_SIZE(b2056_inittabs)) { pts = b43_nphy_get_inittabs_rev3(dev);
if (!pts) {
B43_WARN_ON(1); B43_WARN_ON(1);
return; return;
} }
pts = &b2056_inittabs[dev->phy.rev];
b2056_upload_inittab(dev, ghz5, ignore_uploadflag, b2056_upload_inittab(dev, ghz5, ignore_uploadflag,
B2056_SYN, pts->syn, pts->syn_length); B2056_SYN, pts->syn, pts->syn_length);
@ -9060,11 +9335,12 @@ void b2056_upload_syn_pll_cp2(struct b43_wldev *dev, bool ghz5)
const struct b2056_inittabs_pts *pts; const struct b2056_inittabs_pts *pts;
const struct b2056_inittab_entry *e; const struct b2056_inittab_entry *e;
if (dev->phy.rev >= ARRAY_SIZE(b2056_inittabs)) { pts = b43_nphy_get_inittabs_rev3(dev);
if (!pts) {
B43_WARN_ON(1); B43_WARN_ON(1);
return; return;
} }
pts = &b2056_inittabs[dev->phy.rev];
e = &pts->syn[B2056_SYN_PLL_CP2]; e = &pts->syn[B2056_SYN_PLL_CP2];
b43_radio_write(dev, B2056_SYN_PLL_CP2, ghz5 ? e->ghz5 : e->ghz2); b43_radio_write(dev, B2056_SYN_PLL_CP2, ghz5 ? e->ghz5 : e->ghz2);
@ -9073,38 +9349,46 @@ void b2056_upload_syn_pll_cp2(struct b43_wldev *dev, bool ghz5)
const struct b43_nphy_channeltab_entry_rev3 * const struct b43_nphy_channeltab_entry_rev3 *
b43_nphy_get_chantabent_rev3(struct b43_wldev *dev, u16 freq) b43_nphy_get_chantabent_rev3(struct b43_wldev *dev, u16 freq)
{ {
struct b43_phy *phy = &dev->phy;
const struct b43_nphy_channeltab_entry_rev3 *e; const struct b43_nphy_channeltab_entry_rev3 *e;
unsigned int length, i; unsigned int length, i;
switch (dev->phy.rev) { switch (phy->rev) {
case 3: case 3:
e = b43_nphy_channeltab_rev3; e = b43_nphy_channeltab_phy_rev3;
length = ARRAY_SIZE(b43_nphy_channeltab_rev3); length = ARRAY_SIZE(b43_nphy_channeltab_phy_rev3);
break; break;
case 4: case 4:
e = b43_nphy_channeltab_rev4; e = b43_nphy_channeltab_phy_rev4;
length = ARRAY_SIZE(b43_nphy_channeltab_rev4); length = ARRAY_SIZE(b43_nphy_channeltab_phy_rev4);
break;
case 5:
e = b43_nphy_channeltab_rev5;
length = ARRAY_SIZE(b43_nphy_channeltab_rev5);
break;
case 6:
e = b43_nphy_channeltab_rev6;
length = ARRAY_SIZE(b43_nphy_channeltab_rev6);
break;
case 7:
case 9:
e = b43_nphy_channeltab_rev7_9;
length = ARRAY_SIZE(b43_nphy_channeltab_rev7_9);
break;
case 8:
e = b43_nphy_channeltab_rev8;
length = ARRAY_SIZE(b43_nphy_channeltab_rev8);
break; break;
default: default:
B43_WARN_ON(1); switch (phy->radio_rev) {
return NULL; case 5:
e = b43_nphy_channeltab_radio_rev5;
length = ARRAY_SIZE(b43_nphy_channeltab_radio_rev5);
break;
case 6:
e = b43_nphy_channeltab_radio_rev6;
length = ARRAY_SIZE(b43_nphy_channeltab_radio_rev6);
break;
case 7:
case 9:
e = b43_nphy_channeltab_radio_rev7_9;
length = ARRAY_SIZE(b43_nphy_channeltab_radio_rev7_9);
break;
case 8:
e = b43_nphy_channeltab_radio_rev8;
length = ARRAY_SIZE(b43_nphy_channeltab_radio_rev8);
break;
case 11:
e = b43_nphy_channeltab_radio_rev11;
length = ARRAY_SIZE(b43_nphy_channeltab_radio_rev11);
break;
default:
B43_WARN_ON(1);
return NULL;
}
} }
for (i = 0; i < length; i++, e++) { for (i = 0; i < length; i++, e++) {

Просмотреть файл

@ -1627,74 +1627,7 @@ static const u32 b43_ntab_tdtrn_r3[] = {
0xfa58fc00, 0x0b64fc7e, 0x0800f7b6, 0x00f006be, 0xfa58fc00, 0x0b64fc7e, 0x0800f7b6, 0x00f006be,
}; };
static const u32 b43_ntab_noisevar0_r3[] = { static const u32 b43_ntab_noisevar_r3[] = {
0x02110211, 0x0000014d, 0x02110211, 0x0000014d,
0x02110211, 0x0000014d, 0x02110211, 0x0000014d,
0x02110211, 0x0000014d, 0x02110211, 0x0000014d,
0x02110211, 0x0000014d, 0x02110211, 0x0000014d,
0x02110211, 0x0000014d, 0x02110211, 0x0000014d,
0x02110211, 0x0000014d, 0x02110211, 0x0000014d,
0x02110211, 0x0000014d, 0x02110211, 0x0000014d,
0x02110211, 0x0000014d, 0x02110211, 0x0000014d,
0x02110211, 0x0000014d, 0x02110211, 0x0000014d,
0x02110211, 0x0000014d, 0x02110211, 0x0000014d,
0x02110211, 0x0000014d, 0x02110211, 0x0000014d,
0x02110211, 0x0000014d, 0x02110211, 0x0000014d,
0x02110211, 0x0000014d, 0x02110211, 0x0000014d,
0x02110211, 0x0000014d, 0x02110211, 0x0000014d,
0x02110211, 0x0000014d, 0x02110211, 0x0000014d,
0x02110211, 0x0000014d, 0x02110211, 0x0000014d,
0x02110211, 0x0000014d, 0x02110211, 0x0000014d,
0x02110211, 0x0000014d, 0x02110211, 0x0000014d,
0x02110211, 0x0000014d, 0x02110211, 0x0000014d,
0x02110211, 0x0000014d, 0x02110211, 0x0000014d,
0x02110211, 0x0000014d, 0x02110211, 0x0000014d,
0x02110211, 0x0000014d, 0x02110211, 0x0000014d,
0x02110211, 0x0000014d, 0x02110211, 0x0000014d,
0x02110211, 0x0000014d, 0x02110211, 0x0000014d,
0x02110211, 0x0000014d, 0x02110211, 0x0000014d,
0x02110211, 0x0000014d, 0x02110211, 0x0000014d,
0x02110211, 0x0000014d, 0x02110211, 0x0000014d,
0x02110211, 0x0000014d, 0x02110211, 0x0000014d,
0x02110211, 0x0000014d, 0x02110211, 0x0000014d,
0x02110211, 0x0000014d, 0x02110211, 0x0000014d,
0x02110211, 0x0000014d, 0x02110211, 0x0000014d,
0x02110211, 0x0000014d, 0x02110211, 0x0000014d,
0x02110211, 0x0000014d, 0x02110211, 0x0000014d,
0x02110211, 0x0000014d, 0x02110211, 0x0000014d,
0x02110211, 0x0000014d, 0x02110211, 0x0000014d,
0x02110211, 0x0000014d, 0x02110211, 0x0000014d,
0x02110211, 0x0000014d, 0x02110211, 0x0000014d,
0x02110211, 0x0000014d, 0x02110211, 0x0000014d,
0x02110211, 0x0000014d, 0x02110211, 0x0000014d,
0x02110211, 0x0000014d, 0x02110211, 0x0000014d,
0x02110211, 0x0000014d, 0x02110211, 0x0000014d,
0x02110211, 0x0000014d, 0x02110211, 0x0000014d,
0x02110211, 0x0000014d, 0x02110211, 0x0000014d,
0x02110211, 0x0000014d, 0x02110211, 0x0000014d,
0x02110211, 0x0000014d, 0x02110211, 0x0000014d,
0x02110211, 0x0000014d, 0x02110211, 0x0000014d,
0x02110211, 0x0000014d, 0x02110211, 0x0000014d,
0x02110211, 0x0000014d, 0x02110211, 0x0000014d,
0x02110211, 0x0000014d, 0x02110211, 0x0000014d,
0x02110211, 0x0000014d, 0x02110211, 0x0000014d,
0x02110211, 0x0000014d, 0x02110211, 0x0000014d,
0x02110211, 0x0000014d, 0x02110211, 0x0000014d,
0x02110211, 0x0000014d, 0x02110211, 0x0000014d,
0x02110211, 0x0000014d, 0x02110211, 0x0000014d,
0x02110211, 0x0000014d, 0x02110211, 0x0000014d,
0x02110211, 0x0000014d, 0x02110211, 0x0000014d,
0x02110211, 0x0000014d, 0x02110211, 0x0000014d,
0x02110211, 0x0000014d, 0x02110211, 0x0000014d,
0x02110211, 0x0000014d, 0x02110211, 0x0000014d,
0x02110211, 0x0000014d, 0x02110211, 0x0000014d,
0x02110211, 0x0000014d, 0x02110211, 0x0000014d,
0x02110211, 0x0000014d, 0x02110211, 0x0000014d,
0x02110211, 0x0000014d, 0x02110211, 0x0000014d,
0x02110211, 0x0000014d, 0x02110211, 0x0000014d,
};
static const u32 b43_ntab_noisevar1_r3[] = {
0x02110211, 0x0000014d, 0x02110211, 0x0000014d, 0x02110211, 0x0000014d, 0x02110211, 0x0000014d,
0x02110211, 0x0000014d, 0x02110211, 0x0000014d, 0x02110211, 0x0000014d, 0x02110211, 0x0000014d,
0x02110211, 0x0000014d, 0x02110211, 0x0000014d, 0x02110211, 0x0000014d, 0x02110211, 0x0000014d,
@ -3114,8 +3047,7 @@ static void b43_nphy_tables_init_rev3(struct b43_wldev *dev)
ntab_upload(dev, B43_NTAB_TMAP_R3, b43_ntab_tmap_r3); ntab_upload(dev, B43_NTAB_TMAP_R3, b43_ntab_tmap_r3);
ntab_upload(dev, B43_NTAB_INTLEVEL_R3, b43_ntab_intlevel_r3); ntab_upload(dev, B43_NTAB_INTLEVEL_R3, b43_ntab_intlevel_r3);
ntab_upload(dev, B43_NTAB_TDTRN_R3, b43_ntab_tdtrn_r3); ntab_upload(dev, B43_NTAB_TDTRN_R3, b43_ntab_tdtrn_r3);
ntab_upload(dev, B43_NTAB_NOISEVAR0_R3, b43_ntab_noisevar0_r3); ntab_upload(dev, B43_NTAB_NOISEVAR_R3, b43_ntab_noisevar_r3);
ntab_upload(dev, B43_NTAB_NOISEVAR1_R3, b43_ntab_noisevar1_r3);
ntab_upload(dev, B43_NTAB_MCS_R3, b43_ntab_mcs_r3); ntab_upload(dev, B43_NTAB_MCS_R3, b43_ntab_mcs_r3);
ntab_upload(dev, B43_NTAB_TDI20A0_R3, b43_ntab_tdi20a0_r3); ntab_upload(dev, B43_NTAB_TDI20A0_R3, b43_ntab_tdi20a0_r3);
ntab_upload(dev, B43_NTAB_TDI20A1_R3, b43_ntab_tdi20a1_r3); ntab_upload(dev, B43_NTAB_TDI20A1_R3, b43_ntab_tdi20a1_r3);

Просмотреть файл

@ -143,8 +143,7 @@ struct nphy_gain_ctl_workaround_entry *b43_nphy_get_gain_ctl_workaround_ent(
#define B43_NTAB_TMAP_R3 B43_NTAB32(12, 0) /* TM AP */ #define B43_NTAB_TMAP_R3 B43_NTAB32(12, 0) /* TM AP */
#define B43_NTAB_INTLEVEL_R3 B43_NTAB32(13, 0) /* INT LV */ #define B43_NTAB_INTLEVEL_R3 B43_NTAB32(13, 0) /* INT LV */
#define B43_NTAB_TDTRN_R3 B43_NTAB32(14, 0) /* TD TRN */ #define B43_NTAB_TDTRN_R3 B43_NTAB32(14, 0) /* TD TRN */
#define B43_NTAB_NOISEVAR0_R3 B43_NTAB32(16, 0) /* noise variance 0 */ #define B43_NTAB_NOISEVAR_R3 B43_NTAB32(16, 0) /* noise variance */
#define B43_NTAB_NOISEVAR1_R3 B43_NTAB32(16, 128) /* noise variance 1 */
#define B43_NTAB_MCS_R3 B43_NTAB16(18, 0) /* MCS */ #define B43_NTAB_MCS_R3 B43_NTAB16(18, 0) /* MCS */
#define B43_NTAB_TDI20A0_R3 B43_NTAB32(19, 128) /* TDI 20/0 */ #define B43_NTAB_TDI20A0_R3 B43_NTAB32(19, 128) /* TDI 20/0 */
#define B43_NTAB_TDI20A1_R3 B43_NTAB32(19, 256) /* TDI 20/1 */ #define B43_NTAB_TDI20A1_R3 B43_NTAB32(19, 256) /* TDI 20/1 */

Просмотреть файл

@ -441,7 +441,7 @@ static void b43_wa_altagc(struct b43_wldev *dev)
static void b43_wa_tr_ltov(struct b43_wldev *dev) /* TR Lookup Table Original Values */ static void b43_wa_tr_ltov(struct b43_wldev *dev) /* TR Lookup Table Original Values */
{ {
b43_gtab_write(dev, B43_GTAB_ORIGTR, 0, 0xC480); b43_gtab_write(dev, B43_GTAB_ORIGTR, 0, 0x7654);
} }
static void b43_wa_cpll_nonpilot(struct b43_wldev *dev) static void b43_wa_cpll_nonpilot(struct b43_wldev *dev)

Просмотреть файл

@ -897,7 +897,8 @@ static bool brcms_tx_flush_completed(struct brcms_info *wl)
return result; return result;
} }
static void brcms_ops_flush(struct ieee80211_hw *hw, u32 queues, bool drop) static void brcms_ops_flush(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
u32 queues, bool drop)
{ {
struct brcms_info *wl = hw->priv; struct brcms_info *wl = hw->priv;
int ret; int ret;

Просмотреть файл

@ -936,7 +936,8 @@ static int __cw1200_flush(struct cw1200_common *priv, bool drop)
return ret; return ret;
} }
void cw1200_flush(struct ieee80211_hw *hw, u32 queues, bool drop) void cw1200_flush(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
u32 queues, bool drop)
{ {
struct cw1200_common *priv = hw->priv; struct cw1200_common *priv = hw->priv;

Просмотреть файл

@ -40,7 +40,8 @@ int cw1200_set_key(struct ieee80211_hw *dev, enum set_key_cmd cmd,
int cw1200_set_rts_threshold(struct ieee80211_hw *hw, u32 value); int cw1200_set_rts_threshold(struct ieee80211_hw *hw, u32 value);
void cw1200_flush(struct ieee80211_hw *hw, u32 queues, bool drop); void cw1200_flush(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
u32 queues, bool drop);
u64 cw1200_prepare_multicast(struct ieee80211_hw *hw, u64 cw1200_prepare_multicast(struct ieee80211_hw *hw,
struct netdev_hw_addr_list *mc_list); struct netdev_hw_addr_list *mc_list);

Просмотреть файл

@ -573,7 +573,7 @@ il3945_hdl_rx(struct il_priv *il, struct il_rx_buf *rxb)
rx_status.flag |= RX_FLAG_SHORTPRE; rx_status.flag |= RX_FLAG_SHORTPRE;
if ((unlikely(rx_stats->phy_count > 20))) { if ((unlikely(rx_stats->phy_count > 20))) {
D_DROP("dsp size out of range [0,20]: %d/n", D_DROP("dsp size out of range [0,20]: %d\n",
rx_stats->phy_count); rx_stats->phy_count);
return; return;
} }

Просмотреть файл

@ -670,7 +670,7 @@ il4965_hdl_rx(struct il_priv *il, struct il_rx_buf *rxb)
} }
if ((unlikely(phy_res->cfg_phy_cnt > 20))) { if ((unlikely(phy_res->cfg_phy_cnt > 20))) {
D_DROP("dsp size out of range [0,20]: %d/n", D_DROP("dsp size out of range [0,20]: %d\n",
phy_res->cfg_phy_cnt); phy_res->cfg_phy_cnt);
return; return;
} }

Просмотреть файл

@ -4755,7 +4755,8 @@ out:
} }
EXPORT_SYMBOL(il_mac_change_interface); EXPORT_SYMBOL(il_mac_change_interface);
void il_mac_flush(struct ieee80211_hw *hw, u32 queues, bool drop) void il_mac_flush(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
u32 queues, bool drop)
{ {
struct il_priv *il = hw->priv; struct il_priv *il = hw->priv;
unsigned long timeout = jiffies + msecs_to_jiffies(500); unsigned long timeout = jiffies + msecs_to_jiffies(500);

Просмотреть файл

@ -1723,7 +1723,8 @@ void il_mac_remove_interface(struct ieee80211_hw *hw,
struct ieee80211_vif *vif); struct ieee80211_vif *vif);
int il_mac_change_interface(struct ieee80211_hw *hw, struct ieee80211_vif *vif, int il_mac_change_interface(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
enum nl80211_iftype newtype, bool newp2p); enum nl80211_iftype newtype, bool newp2p);
void il_mac_flush(struct ieee80211_hw *hw, u32 queues, bool drop); void il_mac_flush(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
u32 queues, bool drop);
int il_alloc_txq_mem(struct il_priv *il); int il_alloc_txq_mem(struct il_priv *il);
void il_free_txq_mem(struct il_priv *il); void il_free_txq_mem(struct il_priv *il);

Просмотреть файл

@ -180,7 +180,7 @@ void iwlagn_dev_txfifo_flush(struct iwl_priv *priv)
goto done; goto done;
} }
IWL_DEBUG_INFO(priv, "wait transmit/flush all frames\n"); IWL_DEBUG_INFO(priv, "wait transmit/flush all frames\n");
iwl_trans_wait_tx_queue_empty(priv->trans); iwl_trans_wait_tx_queue_empty(priv->trans, 0xffffffff);
done: done:
ieee80211_wake_queues(priv->hw); ieee80211_wake_queues(priv->hw);
mutex_unlock(&priv->mutex); mutex_unlock(&priv->mutex);

Просмотреть файл

@ -1091,7 +1091,8 @@ static void iwlagn_configure_filter(struct ieee80211_hw *hw,
FIF_BCN_PRBRESP_PROMISC | FIF_CONTROL; FIF_BCN_PRBRESP_PROMISC | FIF_CONTROL;
} }
static void iwlagn_mac_flush(struct ieee80211_hw *hw, u32 queues, bool drop) static void iwlagn_mac_flush(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
u32 queues, bool drop)
{ {
struct iwl_priv *priv = IWL_MAC80211_GET_DVM(hw); struct iwl_priv *priv = IWL_MAC80211_GET_DVM(hw);
@ -1119,7 +1120,7 @@ static void iwlagn_mac_flush(struct ieee80211_hw *hw, u32 queues, bool drop)
} }
} }
IWL_DEBUG_MAC80211(priv, "wait transmit/flush all frames\n"); IWL_DEBUG_MAC80211(priv, "wait transmit/flush all frames\n");
iwl_trans_wait_tx_queue_empty(priv->trans); iwl_trans_wait_tx_queue_empty(priv->trans, 0xffffffff);
done: done:
mutex_unlock(&priv->mutex); mutex_unlock(&priv->mutex);
IWL_DEBUG_MAC80211(priv, "leave\n"); IWL_DEBUG_MAC80211(priv, "leave\n");

Просмотреть файл

@ -2053,6 +2053,17 @@ static bool iwl_set_hw_rfkill_state(struct iwl_op_mode *op_mode, bool state)
return false; return false;
} }
static void iwl_napi_add(struct iwl_op_mode *op_mode,
struct napi_struct *napi,
struct net_device *napi_dev,
int (*poll)(struct napi_struct *, int),
int weight)
{
struct iwl_priv *priv = IWL_OP_MODE_GET_DVM(op_mode);
ieee80211_napi_add(priv->hw, napi, napi_dev, poll, weight);
}
static const struct iwl_op_mode_ops iwl_dvm_ops = { static const struct iwl_op_mode_ops iwl_dvm_ops = {
.start = iwl_op_mode_dvm_start, .start = iwl_op_mode_dvm_start,
.stop = iwl_op_mode_dvm_stop, .stop = iwl_op_mode_dvm_stop,
@ -2065,6 +2076,7 @@ static const struct iwl_op_mode_ops iwl_dvm_ops = {
.cmd_queue_full = iwl_cmd_queue_full, .cmd_queue_full = iwl_cmd_queue_full,
.nic_config = iwl_nic_config, .nic_config = iwl_nic_config,
.wimax_active = iwl_wimax_active, .wimax_active = iwl_wimax_active,
.napi_add = iwl_napi_add,
}; };
/***************************************************************************** /*****************************************************************************

Просмотреть файл

@ -62,6 +62,7 @@ static const struct iwl_base_params iwl1000_base_params = {
.led_compensation = 51, .led_compensation = 51,
.wd_timeout = IWL_WATCHDOG_DISABLED, .wd_timeout = IWL_WATCHDOG_DISABLED,
.max_event_log_size = 128, .max_event_log_size = 128,
.scd_chain_ext_wa = true,
}; };
static const struct iwl_ht_params iwl1000_ht_params = { static const struct iwl_ht_params iwl1000_ht_params = {

Просмотреть файл

@ -75,6 +75,7 @@ static const struct iwl_base_params iwl2000_base_params = {
.wd_timeout = IWL_DEF_WD_TIMEOUT, .wd_timeout = IWL_DEF_WD_TIMEOUT,
.max_event_log_size = 512, .max_event_log_size = 512,
.shadow_reg_enable = false, /* TODO: fix bugs using this feature */ .shadow_reg_enable = false, /* TODO: fix bugs using this feature */
.scd_chain_ext_wa = true,
}; };
@ -88,6 +89,7 @@ static const struct iwl_base_params iwl2030_base_params = {
.wd_timeout = IWL_LONG_WD_TIMEOUT, .wd_timeout = IWL_LONG_WD_TIMEOUT,
.max_event_log_size = 512, .max_event_log_size = 512,
.shadow_reg_enable = false, /* TODO: fix bugs using this feature */ .shadow_reg_enable = false, /* TODO: fix bugs using this feature */
.scd_chain_ext_wa = true,
}; };
static const struct iwl_ht_params iwl2000_ht_params = { static const struct iwl_ht_params iwl2000_ht_params = {

Просмотреть файл

@ -61,6 +61,7 @@ static const struct iwl_base_params iwl5000_base_params = {
.led_compensation = 51, .led_compensation = 51,
.wd_timeout = IWL_WATCHDOG_DISABLED, .wd_timeout = IWL_WATCHDOG_DISABLED,
.max_event_log_size = 512, .max_event_log_size = 512,
.scd_chain_ext_wa = true,
}; };
static const struct iwl_ht_params iwl5000_ht_params = { static const struct iwl_ht_params iwl5000_ht_params = {

Просмотреть файл

@ -85,6 +85,7 @@ static const struct iwl_base_params iwl6000_base_params = {
.wd_timeout = IWL_DEF_WD_TIMEOUT, .wd_timeout = IWL_DEF_WD_TIMEOUT,
.max_event_log_size = 512, .max_event_log_size = 512,
.shadow_reg_enable = false, /* TODO: fix bugs using this feature */ .shadow_reg_enable = false, /* TODO: fix bugs using this feature */
.scd_chain_ext_wa = true,
}; };
static const struct iwl_base_params iwl6050_base_params = { static const struct iwl_base_params iwl6050_base_params = {
@ -97,6 +98,7 @@ static const struct iwl_base_params iwl6050_base_params = {
.wd_timeout = IWL_DEF_WD_TIMEOUT, .wd_timeout = IWL_DEF_WD_TIMEOUT,
.max_event_log_size = 1024, .max_event_log_size = 1024,
.shadow_reg_enable = false, /* TODO: fix bugs using this feature */ .shadow_reg_enable = false, /* TODO: fix bugs using this feature */
.scd_chain_ext_wa = true,
}; };
static const struct iwl_base_params iwl6000_g2_base_params = { static const struct iwl_base_params iwl6000_g2_base_params = {
@ -109,6 +111,7 @@ static const struct iwl_base_params iwl6000_g2_base_params = {
.wd_timeout = IWL_LONG_WD_TIMEOUT, .wd_timeout = IWL_LONG_WD_TIMEOUT,
.max_event_log_size = 512, .max_event_log_size = 512,
.shadow_reg_enable = false, /* TODO: fix bugs using this feature */ .shadow_reg_enable = false, /* TODO: fix bugs using this feature */
.scd_chain_ext_wa = true,
}; };
static const struct iwl_ht_params iwl6000_ht_params = { static const struct iwl_ht_params iwl6000_ht_params = {

Просмотреть файл

@ -71,12 +71,12 @@
#define IWL3160_UCODE_API_MAX 9 #define IWL3160_UCODE_API_MAX 9
/* Oldest version we won't warn about */ /* Oldest version we won't warn about */
#define IWL7260_UCODE_API_OK 8 #define IWL7260_UCODE_API_OK 9
#define IWL3160_UCODE_API_OK 8 #define IWL3160_UCODE_API_OK 9
/* Lowest firmware API version supported */ /* Lowest firmware API version supported */
#define IWL7260_UCODE_API_MIN 7 #define IWL7260_UCODE_API_MIN 8
#define IWL3160_UCODE_API_MIN 7 #define IWL3160_UCODE_API_MIN 8
/* NVM versions */ /* NVM versions */
#define IWL7260_NVM_VERSION 0x0a1d #define IWL7260_NVM_VERSION 0x0a1d
@ -107,6 +107,7 @@ static const struct iwl_base_params iwl7000_base_params = {
.max_event_log_size = 512, .max_event_log_size = 512,
.shadow_reg_enable = true, .shadow_reg_enable = true,
.pcie_l1_allowed = true, .pcie_l1_allowed = true,
.apmg_wake_up_wa = true,
}; };
static const struct iwl_ht_params iwl7000_ht_params = { static const struct iwl_ht_params iwl7000_ht_params = {

Просмотреть файл

@ -146,6 +146,9 @@ static inline u8 num_of_ant(u8 mask)
* @wd_timeout: TX queues watchdog timeout * @wd_timeout: TX queues watchdog timeout
* @max_event_log_size: size of event log buffer size for ucode event logging * @max_event_log_size: size of event log buffer size for ucode event logging
* @shadow_reg_enable: HW shadow register support * @shadow_reg_enable: HW shadow register support
* @apmg_wake_up_wa: should the MAC access REQ be asserted when a command
* is in flight. This is due to a HW bug in 7260, 3160 and 7265.
* @scd_chain_ext_wa: should the chain extension feature in SCD be disabled.
*/ */
struct iwl_base_params { struct iwl_base_params {
int eeprom_size; int eeprom_size;
@ -160,6 +163,8 @@ struct iwl_base_params {
u32 max_event_log_size; u32 max_event_log_size;
const bool shadow_reg_enable; const bool shadow_reg_enable;
const bool pcie_l1_allowed; const bool pcie_l1_allowed;
const bool apmg_wake_up_wa;
const bool scd_chain_ext_wa;
}; };
/* /*

Просмотреть файл

@ -77,26 +77,21 @@
* @IWL_UCODE_TLV_FLAGS_UAPSD: This uCode image supports uAPSD * @IWL_UCODE_TLV_FLAGS_UAPSD: This uCode image supports uAPSD
* @IWL_UCODE_TLV_FLAGS_SHORT_BL: 16 entries of black list instead of 64 in scan * @IWL_UCODE_TLV_FLAGS_SHORT_BL: 16 entries of black list instead of 64 in scan
* offload profile config command. * offload profile config command.
* @IWL_UCODE_TLV_FLAGS_RX_ENERGY_API: supports rx signal strength api
* @IWL_UCODE_TLV_FLAGS_TIME_EVENT_API_V2: using the new time event API.
* @IWL_UCODE_TLV_FLAGS_D3_6_IPV6_ADDRS: D3 image supports up to six * @IWL_UCODE_TLV_FLAGS_D3_6_IPV6_ADDRS: D3 image supports up to six
* (rather than two) IPv6 addresses * (rather than two) IPv6 addresses
* @IWL_UCODE_TLV_FLAGS_BF_UPDATED: new beacon filtering API
* @IWL_UCODE_TLV_FLAGS_NO_BASIC_SSID: not sending a probe with the SSID element * @IWL_UCODE_TLV_FLAGS_NO_BASIC_SSID: not sending a probe with the SSID element
* from the probe request template. * from the probe request template.
* @IWL_UCODE_TLV_FLAGS_D3_CONTINUITY_API: modified D3 API to allow keeping
* connection when going back to D0
* @IWL_UCODE_TLV_FLAGS_NEW_NSOFFL_SMALL: new NS offload (small version) * @IWL_UCODE_TLV_FLAGS_NEW_NSOFFL_SMALL: new NS offload (small version)
* @IWL_UCODE_TLV_FLAGS_NEW_NSOFFL_LARGE: new NS offload (large version) * @IWL_UCODE_TLV_FLAGS_NEW_NSOFFL_LARGE: new NS offload (large version)
* @IWL_UCODE_TLV_FLAGS_SCHED_SCAN: this uCode image supports scheduled scan. * @IWL_UCODE_TLV_FLAGS_P2P_PM: P2P client supports PM as a stand alone MAC
* @IWL_UCODE_TLV_FLAGS_STA_KEY_CMD: new ADD_STA and ADD_STA_KEY command API
* @IWL_UCODE_TLV_FLAGS_DEVICE_PS_CMD: support device wide power command
* containing CAM (Continuous Active Mode) indication.
* @IWL_UCODE_TLV_FLAGS_P2P_BSS_PS_DCM: support power save on BSS station and * @IWL_UCODE_TLV_FLAGS_P2P_BSS_PS_DCM: support power save on BSS station and
* P2P client interfaces simultaneously if they are in different bindings. * P2P client interfaces simultaneously if they are in different bindings.
* @IWL_UCODE_TLV_FLAGS_P2P_BSS_PS_SCM: support power save on BSS station and
* P2P client interfaces simultaneously if they are in same bindings.
* @IWL_UCODE_TLV_FLAGS_P2P_PS_UAPSD: P2P client supports uAPSD power save * @IWL_UCODE_TLV_FLAGS_P2P_PS_UAPSD: P2P client supports uAPSD power save
* @IWL_UCODE_TLV_FLAGS_BCAST_FILTERING: uCode supports broadcast filtering. * @IWL_UCODE_TLV_FLAGS_BCAST_FILTERING: uCode supports broadcast filtering.
* @IWL_UCODE_TLV_FLAGS_GO_UAPSD: AP/GO interfaces support uAPSD clients * @IWL_UCODE_TLV_FLAGS_GO_UAPSD: AP/GO interfaces support uAPSD clients
* @IWL_UCODE_TLV_FLAGS_EBS_SUPPORT: this uCode image supports EBS.
*/ */
enum iwl_ucode_tlv_flag { enum iwl_ucode_tlv_flag {
IWL_UCODE_TLV_FLAGS_PAN = BIT(0), IWL_UCODE_TLV_FLAGS_PAN = BIT(0),
@ -104,22 +99,15 @@ enum iwl_ucode_tlv_flag {
IWL_UCODE_TLV_FLAGS_MFP = BIT(2), IWL_UCODE_TLV_FLAGS_MFP = BIT(2),
IWL_UCODE_TLV_FLAGS_P2P = BIT(3), IWL_UCODE_TLV_FLAGS_P2P = BIT(3),
IWL_UCODE_TLV_FLAGS_DW_BC_TABLE = BIT(4), IWL_UCODE_TLV_FLAGS_DW_BC_TABLE = BIT(4),
IWL_UCODE_TLV_FLAGS_NEWBT_COEX = BIT(5),
IWL_UCODE_TLV_FLAGS_PM_CMD_SUPPORT = BIT(6),
IWL_UCODE_TLV_FLAGS_SHORT_BL = BIT(7), IWL_UCODE_TLV_FLAGS_SHORT_BL = BIT(7),
IWL_UCODE_TLV_FLAGS_RX_ENERGY_API = BIT(8),
IWL_UCODE_TLV_FLAGS_TIME_EVENT_API_V2 = BIT(9),
IWL_UCODE_TLV_FLAGS_D3_6_IPV6_ADDRS = BIT(10), IWL_UCODE_TLV_FLAGS_D3_6_IPV6_ADDRS = BIT(10),
IWL_UCODE_TLV_FLAGS_BF_UPDATED = BIT(11),
IWL_UCODE_TLV_FLAGS_NO_BASIC_SSID = BIT(12), IWL_UCODE_TLV_FLAGS_NO_BASIC_SSID = BIT(12),
IWL_UCODE_TLV_FLAGS_D3_CONTINUITY_API = BIT(14),
IWL_UCODE_TLV_FLAGS_NEW_NSOFFL_SMALL = BIT(15), IWL_UCODE_TLV_FLAGS_NEW_NSOFFL_SMALL = BIT(15),
IWL_UCODE_TLV_FLAGS_NEW_NSOFFL_LARGE = BIT(16), IWL_UCODE_TLV_FLAGS_NEW_NSOFFL_LARGE = BIT(16),
IWL_UCODE_TLV_FLAGS_SCHED_SCAN = BIT(17), IWL_UCODE_TLV_FLAGS_P2P_PM = BIT(21),
IWL_UCODE_TLV_FLAGS_STA_KEY_CMD = BIT(19),
IWL_UCODE_TLV_FLAGS_DEVICE_PS_CMD = BIT(20),
IWL_UCODE_TLV_FLAGS_BSS_P2P_PS_DCM = BIT(22), IWL_UCODE_TLV_FLAGS_BSS_P2P_PS_DCM = BIT(22),
IWL_UCODE_TLV_FLAGS_UAPSD_SUPPORT = BIT(24), IWL_UCODE_TLV_FLAGS_BSS_P2P_PS_SCM = BIT(23),
IWL_UCODE_TLV_FLAGS_EBS_SUPPORT = BIT(25),
IWL_UCODE_TLV_FLAGS_P2P_PS_UAPSD = BIT(26), IWL_UCODE_TLV_FLAGS_P2P_PS_UAPSD = BIT(26),
IWL_UCODE_TLV_FLAGS_BCAST_FILTERING = BIT(29), IWL_UCODE_TLV_FLAGS_BCAST_FILTERING = BIT(29),
IWL_UCODE_TLV_FLAGS_GO_UAPSD = BIT(30), IWL_UCODE_TLV_FLAGS_GO_UAPSD = BIT(30),
@ -183,6 +171,7 @@ enum iwl_ucode_sec {
#define IWL_UCODE_SECTION_MAX 12 #define IWL_UCODE_SECTION_MAX 12
#define IWL_API_ARRAY_SIZE 1 #define IWL_API_ARRAY_SIZE 1
#define IWL_CAPABILITIES_ARRAY_SIZE 1 #define IWL_CAPABILITIES_ARRAY_SIZE 1
#define CPU1_CPU2_SEPARATOR_SECTION 0xFFFFCCCC
struct iwl_ucode_capabilities { struct iwl_ucode_capabilities {
u32 max_probe_length; u32 max_probe_length;

Просмотреть файл

@ -134,12 +134,13 @@ static const u8 iwl_nvm_channels_family_8000[] = {
149, 153, 157, 161, 165, 169, 173, 177, 181 149, 153, 157, 161, 165, 169, 173, 177, 181
}; };
#define IWL_NUM_CHANNELS ARRAY_SIZE(iwl_nvm_channels) #define IWL_NUM_CHANNELS ARRAY_SIZE(iwl_nvm_channels)
#define IWL_NUM_CHANNELS_FAMILY_8000 ARRAY_SIZE(iwl_nvm_channels_family_8000) #define IWL_NUM_CHANNELS_FAMILY_8000 ARRAY_SIZE(iwl_nvm_channels_family_8000)
#define NUM_2GHZ_CHANNELS 14 #define NUM_2GHZ_CHANNELS 14
#define FIRST_2GHZ_HT_MINUS 5 #define NUM_2GHZ_CHANNELS_FAMILY_8000 13
#define LAST_2GHZ_HT_PLUS 9 #define FIRST_2GHZ_HT_MINUS 5
#define LAST_5GHZ_HT 161 #define LAST_2GHZ_HT_PLUS 9
#define LAST_5GHZ_HT 161
#define DEFAULT_MAX_TX_POWER 16 #define DEFAULT_MAX_TX_POWER 16
@ -202,21 +203,23 @@ static int iwl_init_channel_map(struct device *dev, const struct iwl_cfg *cfg,
struct ieee80211_channel *channel; struct ieee80211_channel *channel;
u16 ch_flags; u16 ch_flags;
bool is_5ghz; bool is_5ghz;
int num_of_ch; int num_of_ch, num_2ghz_channels;
const u8 *nvm_chan; const u8 *nvm_chan;
if (cfg->device_family != IWL_DEVICE_FAMILY_8000) { if (cfg->device_family != IWL_DEVICE_FAMILY_8000) {
num_of_ch = IWL_NUM_CHANNELS; num_of_ch = IWL_NUM_CHANNELS;
nvm_chan = &iwl_nvm_channels[0]; nvm_chan = &iwl_nvm_channels[0];
num_2ghz_channels = NUM_2GHZ_CHANNELS;
} else { } else {
num_of_ch = IWL_NUM_CHANNELS_FAMILY_8000; num_of_ch = IWL_NUM_CHANNELS_FAMILY_8000;
nvm_chan = &iwl_nvm_channels_family_8000[0]; nvm_chan = &iwl_nvm_channels_family_8000[0];
num_2ghz_channels = NUM_2GHZ_CHANNELS_FAMILY_8000;
} }
for (ch_idx = 0; ch_idx < num_of_ch; ch_idx++) { for (ch_idx = 0; ch_idx < num_of_ch; ch_idx++) {
ch_flags = __le16_to_cpup(nvm_ch_flags + ch_idx); ch_flags = __le16_to_cpup(nvm_ch_flags + ch_idx);
if (ch_idx >= NUM_2GHZ_CHANNELS && if (ch_idx >= num_2ghz_channels &&
!data->sku_cap_band_52GHz_enable) !data->sku_cap_band_52GHz_enable)
ch_flags &= ~NVM_CHANNEL_VALID; ch_flags &= ~NVM_CHANNEL_VALID;
@ -225,7 +228,7 @@ static int iwl_init_channel_map(struct device *dev, const struct iwl_cfg *cfg,
"Ch. %d Flags %x [%sGHz] - No traffic\n", "Ch. %d Flags %x [%sGHz] - No traffic\n",
nvm_chan[ch_idx], nvm_chan[ch_idx],
ch_flags, ch_flags,
(ch_idx >= NUM_2GHZ_CHANNELS) ? (ch_idx >= num_2ghz_channels) ?
"5.2" : "2.4"); "5.2" : "2.4");
continue; continue;
} }
@ -234,7 +237,7 @@ static int iwl_init_channel_map(struct device *dev, const struct iwl_cfg *cfg,
n_channels++; n_channels++;
channel->hw_value = nvm_chan[ch_idx]; channel->hw_value = nvm_chan[ch_idx];
channel->band = (ch_idx < NUM_2GHZ_CHANNELS) ? channel->band = (ch_idx < num_2ghz_channels) ?
IEEE80211_BAND_2GHZ : IEEE80211_BAND_5GHZ; IEEE80211_BAND_2GHZ : IEEE80211_BAND_5GHZ;
channel->center_freq = channel->center_freq =
ieee80211_channel_to_frequency( ieee80211_channel_to_frequency(
@ -242,7 +245,7 @@ static int iwl_init_channel_map(struct device *dev, const struct iwl_cfg *cfg,
/* TODO: Need to be dependent to the NVM */ /* TODO: Need to be dependent to the NVM */
channel->flags = IEEE80211_CHAN_NO_HT40; channel->flags = IEEE80211_CHAN_NO_HT40;
if (ch_idx < NUM_2GHZ_CHANNELS && if (ch_idx < num_2ghz_channels &&
(ch_flags & NVM_CHANNEL_40MHZ)) { (ch_flags & NVM_CHANNEL_40MHZ)) {
if (nvm_chan[ch_idx] <= LAST_2GHZ_HT_PLUS) if (nvm_chan[ch_idx] <= LAST_2GHZ_HT_PLUS)
channel->flags &= ~IEEE80211_CHAN_NO_HT40PLUS; channel->flags &= ~IEEE80211_CHAN_NO_HT40PLUS;
@ -250,7 +253,7 @@ static int iwl_init_channel_map(struct device *dev, const struct iwl_cfg *cfg,
channel->flags &= ~IEEE80211_CHAN_NO_HT40MINUS; channel->flags &= ~IEEE80211_CHAN_NO_HT40MINUS;
} else if (nvm_chan[ch_idx] <= LAST_5GHZ_HT && } else if (nvm_chan[ch_idx] <= LAST_5GHZ_HT &&
(ch_flags & NVM_CHANNEL_40MHZ)) { (ch_flags & NVM_CHANNEL_40MHZ)) {
if ((ch_idx - NUM_2GHZ_CHANNELS) % 2 == 0) if ((ch_idx - num_2ghz_channels) % 2 == 0)
channel->flags &= ~IEEE80211_CHAN_NO_HT40PLUS; channel->flags &= ~IEEE80211_CHAN_NO_HT40PLUS;
else else
channel->flags &= ~IEEE80211_CHAN_NO_HT40MINUS; channel->flags &= ~IEEE80211_CHAN_NO_HT40MINUS;

Просмотреть файл

@ -63,6 +63,7 @@
#ifndef __iwl_op_mode_h__ #ifndef __iwl_op_mode_h__
#define __iwl_op_mode_h__ #define __iwl_op_mode_h__
#include <linux/netdevice.h>
#include <linux/debugfs.h> #include <linux/debugfs.h>
struct iwl_op_mode; struct iwl_op_mode;
@ -112,8 +113,11 @@ struct iwl_cfg;
* @stop: stop the op_mode. Must free all the memory allocated. * @stop: stop the op_mode. Must free all the memory allocated.
* May sleep * May sleep
* @rx: Rx notification to the op_mode. rxb is the Rx buffer itself. Cmd is the * @rx: Rx notification to the op_mode. rxb is the Rx buffer itself. Cmd is the
* HCMD this Rx responds to. * HCMD this Rx responds to. Can't sleep.
* This callback may sleep, it is called from a threaded IRQ handler. * @napi_add: NAPI initialisation. The transport is fully responsible for NAPI,
* but the higher layers need to know about it (in particular mac80211 to
* to able to call the right NAPI RX functions); this function is needed
* to eventually call netif_napi_add() with higher layer involvement.
* @queue_full: notifies that a HW queue is full. * @queue_full: notifies that a HW queue is full.
* Must be atomic and called with BH disabled. * Must be atomic and called with BH disabled.
* @queue_not_full: notifies that a HW queue is not full any more. * @queue_not_full: notifies that a HW queue is not full any more.
@ -143,6 +147,11 @@ struct iwl_op_mode_ops {
void (*stop)(struct iwl_op_mode *op_mode); void (*stop)(struct iwl_op_mode *op_mode);
int (*rx)(struct iwl_op_mode *op_mode, struct iwl_rx_cmd_buffer *rxb, int (*rx)(struct iwl_op_mode *op_mode, struct iwl_rx_cmd_buffer *rxb,
struct iwl_device_cmd *cmd); struct iwl_device_cmd *cmd);
void (*napi_add)(struct iwl_op_mode *op_mode,
struct napi_struct *napi,
struct net_device *napi_dev,
int (*poll)(struct napi_struct *, int),
int weight);
void (*queue_full)(struct iwl_op_mode *op_mode, int queue); void (*queue_full)(struct iwl_op_mode *op_mode, int queue);
void (*queue_not_full)(struct iwl_op_mode *op_mode, int queue); void (*queue_not_full)(struct iwl_op_mode *op_mode, int queue);
bool (*hw_rf_kill)(struct iwl_op_mode *op_mode, bool state); bool (*hw_rf_kill)(struct iwl_op_mode *op_mode, bool state);
@ -180,7 +189,6 @@ static inline int iwl_op_mode_rx(struct iwl_op_mode *op_mode,
struct iwl_rx_cmd_buffer *rxb, struct iwl_rx_cmd_buffer *rxb,
struct iwl_device_cmd *cmd) struct iwl_device_cmd *cmd)
{ {
might_sleep();
return op_mode->ops->rx(op_mode, rxb, cmd); return op_mode->ops->rx(op_mode, rxb, cmd);
} }
@ -249,4 +257,15 @@ static inline int iwl_op_mode_exit_d0i3(struct iwl_op_mode *op_mode)
return op_mode->ops->exit_d0i3(op_mode); return op_mode->ops->exit_d0i3(op_mode);
} }
static inline void iwl_op_mode_napi_add(struct iwl_op_mode *op_mode,
struct napi_struct *napi,
struct net_device *napi_dev,
int (*poll)(struct napi_struct *, int),
int weight)
{
if (!op_mode->ops->napi_add)
return;
op_mode->ops->napi_add(op_mode, napi, napi_dev, poll, weight);
}
#endif /* __iwl_op_mode_h__ */ #endif /* __iwl_op_mode_h__ */

Просмотреть файл

@ -348,4 +348,12 @@ enum secure_load_status_reg {
#define LMPM_SECURE_TIME_OUT (100) #define LMPM_SECURE_TIME_OUT (100)
/* Rx FIFO */
#define RXF_SIZE_ADDR (0xa00c88)
#define RXF_SIZE_BYTE_CND_POS (7)
#define RXF_SIZE_BYTE_CNT_MSK (0x3ff << RXF_SIZE_BYTE_CND_POS)
#define RXF_LD_FENCE_OFFSET_ADDR (0xa00c10)
#define RXF_FIFO_RD_FENCE_ADDR (0xa00c0c)
#endif /* __iwl_prph_h__ */ #endif /* __iwl_prph_h__ */

Просмотреть файл

@ -437,8 +437,7 @@ struct iwl_trans;
* this one. The op_mode must not configure the HCMD queue. May sleep. * this one. The op_mode must not configure the HCMD queue. May sleep.
* @txq_disable: de-configure a Tx queue to send AMPDUs * @txq_disable: de-configure a Tx queue to send AMPDUs
* Must be atomic * Must be atomic
* @wait_tx_queue_empty: wait until all tx queues are empty * @wait_tx_queue_empty: wait until tx queues are empty. May sleep.
* May sleep
* @dbgfs_register: add the dbgfs files under this directory. Files will be * @dbgfs_register: add the dbgfs files under this directory. Files will be
* automatically deleted. * automatically deleted.
* @write8: write a u8 to a register at offset ofs from the BAR * @write8: write a u8 to a register at offset ofs from the BAR
@ -490,7 +489,7 @@ struct iwl_trans_ops {
void (*txq_disable)(struct iwl_trans *trans, int queue); void (*txq_disable)(struct iwl_trans *trans, int queue);
int (*dbgfs_register)(struct iwl_trans *trans, struct dentry* dir); int (*dbgfs_register)(struct iwl_trans *trans, struct dentry* dir);
int (*wait_tx_queue_empty)(struct iwl_trans *trans); int (*wait_tx_queue_empty)(struct iwl_trans *trans, u32 txq_bm);
void (*write8)(struct iwl_trans *trans, u32 ofs, u8 val); void (*write8)(struct iwl_trans *trans, u32 ofs, u8 val);
void (*write32)(struct iwl_trans *trans, u32 ofs, u32 val); void (*write32)(struct iwl_trans *trans, u32 ofs, u32 val);
@ -759,12 +758,13 @@ static inline void iwl_trans_ac_txq_enable(struct iwl_trans *trans, int queue,
IWL_MAX_TID_COUNT, IWL_FRAME_LIMIT, 0); IWL_MAX_TID_COUNT, IWL_FRAME_LIMIT, 0);
} }
static inline int iwl_trans_wait_tx_queue_empty(struct iwl_trans *trans) static inline int iwl_trans_wait_tx_queue_empty(struct iwl_trans *trans,
u32 txq_bm)
{ {
if (unlikely(trans->state != IWL_TRANS_FW_ALIVE)) if (unlikely(trans->state != IWL_TRANS_FW_ALIVE))
IWL_ERR(trans, "%s bad state = %d", __func__, trans->state); IWL_ERR(trans, "%s bad state = %d", __func__, trans->state);
return trans->ops->wait_tx_queue_empty(trans); return trans->ops->wait_tx_queue_empty(trans, txq_bm);
} }
static inline int iwl_trans_dbgfs_register(struct iwl_trans *trans, static inline int iwl_trans_dbgfs_register(struct iwl_trans *trans,

Просмотреть файл

@ -104,11 +104,8 @@ static const u8 iwl_bt_prio_tbl[BT_COEX_PRIO_TBL_EVT_MAX] = {
#define BT_DISABLE_REDUCED_TXPOWER_THRESHOLD (-65) #define BT_DISABLE_REDUCED_TXPOWER_THRESHOLD (-65)
#define BT_ANTENNA_COUPLING_THRESHOLD (30) #define BT_ANTENNA_COUPLING_THRESHOLD (30)
int iwl_send_bt_prio_tbl(struct iwl_mvm *mvm) static int iwl_send_bt_prio_tbl(struct iwl_mvm *mvm)
{ {
if (!(mvm->fw->ucode_capa.flags & IWL_UCODE_TLV_FLAGS_NEWBT_COEX))
return 0;
return iwl_mvm_send_cmd_pdu(mvm, BT_COEX_PRIO_TABLE, CMD_SYNC, return iwl_mvm_send_cmd_pdu(mvm, BT_COEX_PRIO_TABLE, CMD_SYNC,
sizeof(struct iwl_bt_coex_prio_tbl_cmd), sizeof(struct iwl_bt_coex_prio_tbl_cmd),
&iwl_bt_prio_tbl); &iwl_bt_prio_tbl);
@ -573,8 +570,9 @@ int iwl_send_bt_init_conf(struct iwl_mvm *mvm)
int ret; int ret;
u32 flags; u32 flags;
if (!(mvm->fw->ucode_capa.flags & IWL_UCODE_TLV_FLAGS_NEWBT_COEX)) ret = iwl_send_bt_prio_tbl(mvm);
return 0; if (ret)
return ret;
bt_cmd = kzalloc(sizeof(*bt_cmd), GFP_KERNEL); bt_cmd = kzalloc(sizeof(*bt_cmd), GFP_KERNEL);
if (!bt_cmd) if (!bt_cmd)
@ -582,10 +580,12 @@ int iwl_send_bt_init_conf(struct iwl_mvm *mvm)
cmd.data[0] = bt_cmd; cmd.data[0] = bt_cmd;
bt_cmd->max_kill = 5; bt_cmd->max_kill = 5;
bt_cmd->bt4_antenna_isolation_thr = BT_ANTENNA_COUPLING_THRESHOLD, bt_cmd->bt4_antenna_isolation_thr = BT_ANTENNA_COUPLING_THRESHOLD;
bt_cmd->bt4_antenna_isolation = iwlwifi_mod_params.ant_coupling, bt_cmd->bt4_antenna_isolation = iwlwifi_mod_params.ant_coupling;
bt_cmd->bt4_tx_tx_delta_freq_thr = 15, bt_cmd->bt4_tx_tx_delta_freq_thr = 15;
bt_cmd->bt4_tx_rx_max_freq0 = 15, bt_cmd->bt4_tx_rx_max_freq0 = 15;
bt_cmd->override_primary_lut = BT_COEX_INVALID_LUT;
bt_cmd->override_secondary_lut = BT_COEX_INVALID_LUT;
flags = iwlwifi_mod_params.bt_coex_active ? flags = iwlwifi_mod_params.bt_coex_active ?
BT_COEX_NW : BT_COEX_DISABLE; BT_COEX_NW : BT_COEX_DISABLE;
@ -1215,6 +1215,17 @@ bool iwl_mvm_bt_coex_is_mimo_allowed(struct iwl_mvm *mvm,
return iwl_get_coex_type(mvm, mvmsta->vif) == BT_COEX_TIGHT_LUT; return iwl_get_coex_type(mvm, mvmsta->vif) == BT_COEX_TIGHT_LUT;
} }
bool iwl_mvm_bt_coex_is_tpc_allowed(struct iwl_mvm *mvm,
enum ieee80211_band band)
{
u32 bt_activity = le32_to_cpu(mvm->last_bt_notif.bt_activity_grading);
if (band != IEEE80211_BAND_2GHZ)
return false;
return bt_activity >= BT_LOW_TRAFFIC;
}
u8 iwl_mvm_bt_coex_tx_prio(struct iwl_mvm *mvm, struct ieee80211_hdr *hdr, u8 iwl_mvm_bt_coex_tx_prio(struct iwl_mvm *mvm, struct ieee80211_hdr *hdr,
struct ieee80211_tx_info *info, u8 ac) struct ieee80211_tx_info *info, u8 ac)
{ {
@ -1249,9 +1260,6 @@ u8 iwl_mvm_bt_coex_tx_prio(struct iwl_mvm *mvm, struct ieee80211_hdr *hdr,
void iwl_mvm_bt_coex_vif_change(struct iwl_mvm *mvm) void iwl_mvm_bt_coex_vif_change(struct iwl_mvm *mvm)
{ {
if (!(mvm->fw->ucode_capa.flags & IWL_UCODE_TLV_FLAGS_NEWBT_COEX))
return;
iwl_mvm_bt_coex_notif_handle(mvm); iwl_mvm_bt_coex_notif_handle(mvm);
} }

Просмотреть файл

@ -744,10 +744,8 @@ static int iwl_mvm_get_last_nonqos_seq(struct iwl_mvm *mvm,
int err; int err;
u32 size; u32 size;
if (mvm->fw->ucode_capa.flags & IWL_UCODE_TLV_FLAGS_D3_CONTINUITY_API) { cmd.data[0] = &query_cmd;
cmd.data[0] = &query_cmd; cmd.len[0] = sizeof(query_cmd);
cmd.len[0] = sizeof(query_cmd);
}
err = iwl_mvm_send_cmd(mvm, &cmd); err = iwl_mvm_send_cmd(mvm, &cmd);
if (err) if (err)
@ -758,10 +756,8 @@ static int iwl_mvm_get_last_nonqos_seq(struct iwl_mvm *mvm,
err = -EINVAL; err = -EINVAL;
} else { } else {
err = le16_to_cpup((__le16 *)cmd.resp_pkt->data); err = le16_to_cpup((__le16 *)cmd.resp_pkt->data);
/* new API returns next, not last-used seqno */ /* firmware returns next, not last-used seqno */
if (mvm->fw->ucode_capa.flags & err = (u16) (err - 0x10);
IWL_UCODE_TLV_FLAGS_D3_CONTINUITY_API)
err = (u16) (err - 0x10);
} }
iwl_free_resp(&cmd); iwl_free_resp(&cmd);
@ -785,10 +781,6 @@ void iwl_mvm_set_last_nonqos_seq(struct iwl_mvm *mvm, struct ieee80211_vif *vif)
mvmvif->seqno_valid = false; mvmvif->seqno_valid = false;
if (!(mvm->fw->ucode_capa.flags &
IWL_UCODE_TLV_FLAGS_D3_CONTINUITY_API))
return;
if (iwl_mvm_send_cmd_pdu(mvm, NON_QOS_TX_COUNTER_CMD, CMD_SYNC, if (iwl_mvm_send_cmd_pdu(mvm, NON_QOS_TX_COUNTER_CMD, CMD_SYNC,
sizeof(query_cmd), &query_cmd)) sizeof(query_cmd), &query_cmd))
IWL_ERR(mvm, "failed to set non-QoS seqno\n"); IWL_ERR(mvm, "failed to set non-QoS seqno\n");
@ -1082,6 +1074,15 @@ static int __iwl_mvm_suspend(struct ieee80211_hw *hw,
int iwl_mvm_suspend(struct ieee80211_hw *hw, struct cfg80211_wowlan *wowlan) int iwl_mvm_suspend(struct ieee80211_hw *hw, struct cfg80211_wowlan *wowlan)
{ {
struct iwl_mvm *mvm = IWL_MAC80211_GET_MVM(hw);
if (iwl_mvm_is_d0i3_supported(mvm)) {
mutex_lock(&mvm->d0i3_suspend_mutex);
__set_bit(D0I3_DEFER_WAKEUP, &mvm->d0i3_suspend_flags);
mutex_unlock(&mvm->d0i3_suspend_mutex);
return 0;
}
return __iwl_mvm_suspend(hw, wowlan, false); return __iwl_mvm_suspend(hw, wowlan, false);
} }
@ -1277,7 +1278,7 @@ static void iwl_mvm_set_tkip_rx_seq(struct tkip_sc *scs,
} }
static void iwl_mvm_set_key_rx_seq(struct ieee80211_key_conf *key, static void iwl_mvm_set_key_rx_seq(struct ieee80211_key_conf *key,
struct iwl_wowlan_status_v6 *status) struct iwl_wowlan_status *status)
{ {
union iwl_all_tsc_rsc *rsc = &status->gtk.rsc.all_tsc_rsc; union iwl_all_tsc_rsc *rsc = &status->gtk.rsc.all_tsc_rsc;
@ -1294,7 +1295,7 @@ static void iwl_mvm_set_key_rx_seq(struct ieee80211_key_conf *key,
} }
struct iwl_mvm_d3_gtk_iter_data { struct iwl_mvm_d3_gtk_iter_data {
struct iwl_wowlan_status_v6 *status; struct iwl_wowlan_status *status;
void *last_gtk; void *last_gtk;
u32 cipher; u32 cipher;
bool find_phase, unhandled_cipher; bool find_phase, unhandled_cipher;
@ -1370,7 +1371,7 @@ static void iwl_mvm_d3_update_gtks(struct ieee80211_hw *hw,
static bool iwl_mvm_setup_connection_keep(struct iwl_mvm *mvm, static bool iwl_mvm_setup_connection_keep(struct iwl_mvm *mvm,
struct ieee80211_vif *vif, struct ieee80211_vif *vif,
struct iwl_wowlan_status_v6 *status) struct iwl_wowlan_status *status)
{ {
struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif); struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif);
struct iwl_mvm_d3_gtk_iter_data gtkdata = { struct iwl_mvm_d3_gtk_iter_data gtkdata = {
@ -1468,7 +1469,7 @@ static bool iwl_mvm_query_wakeup_reasons(struct iwl_mvm *mvm,
.flags = CMD_SYNC | CMD_WANT_SKB, .flags = CMD_SYNC | CMD_WANT_SKB,
}; };
struct iwl_wowlan_status_data status; struct iwl_wowlan_status_data status;
struct iwl_wowlan_status_v6 *status_v6; struct iwl_wowlan_status *fw_status;
int ret, len, status_size, i; int ret, len, status_size, i;
bool keep; bool keep;
struct ieee80211_sta *ap_sta; struct ieee80211_sta *ap_sta;
@ -1505,10 +1506,7 @@ static bool iwl_mvm_query_wakeup_reasons(struct iwl_mvm *mvm,
if (!cmd.resp_pkt) if (!cmd.resp_pkt)
goto out_unlock; goto out_unlock;
if (mvm->fw->ucode_capa.flags & IWL_UCODE_TLV_FLAGS_D3_CONTINUITY_API) status_size = sizeof(*fw_status);
status_size = sizeof(struct iwl_wowlan_status_v6);
else
status_size = sizeof(struct iwl_wowlan_status_v4);
len = iwl_rx_packet_payload_len(cmd.resp_pkt); len = iwl_rx_packet_payload_len(cmd.resp_pkt);
if (len < status_size) { if (len < status_size) {
@ -1516,35 +1514,18 @@ static bool iwl_mvm_query_wakeup_reasons(struct iwl_mvm *mvm,
goto out_free_resp; goto out_free_resp;
} }
if (mvm->fw->ucode_capa.flags & IWL_UCODE_TLV_FLAGS_D3_CONTINUITY_API) { fw_status = (void *)cmd.resp_pkt->data;
status_v6 = (void *)cmd.resp_pkt->data;
status.pattern_number = le16_to_cpu(status_v6->pattern_number); status.pattern_number = le16_to_cpu(fw_status->pattern_number);
for (i = 0; i < 8; i++) for (i = 0; i < 8; i++)
status.qos_seq_ctr[i] = status.qos_seq_ctr[i] =
le16_to_cpu(status_v6->qos_seq_ctr[i]); le16_to_cpu(fw_status->qos_seq_ctr[i]);
status.wakeup_reasons = le32_to_cpu(status_v6->wakeup_reasons); status.wakeup_reasons = le32_to_cpu(fw_status->wakeup_reasons);
status.wake_packet_length = status.wake_packet_length =
le32_to_cpu(status_v6->wake_packet_length); le32_to_cpu(fw_status->wake_packet_length);
status.wake_packet_bufsize = status.wake_packet_bufsize =
le32_to_cpu(status_v6->wake_packet_bufsize); le32_to_cpu(fw_status->wake_packet_bufsize);
status.wake_packet = status_v6->wake_packet; status.wake_packet = fw_status->wake_packet;
} else {
struct iwl_wowlan_status_v4 *status_v4;
status_v6 = NULL;
status_v4 = (void *)cmd.resp_pkt->data;
status.pattern_number = le16_to_cpu(status_v4->pattern_number);
for (i = 0; i < 8; i++)
status.qos_seq_ctr[i] =
le16_to_cpu(status_v4->qos_seq_ctr[i]);
status.wakeup_reasons = le32_to_cpu(status_v4->wakeup_reasons);
status.wake_packet_length =
le32_to_cpu(status_v4->wake_packet_length);
status.wake_packet_bufsize =
le32_to_cpu(status_v4->wake_packet_bufsize);
status.wake_packet = status_v4->wake_packet;
}
if (len != status_size + ALIGN(status.wake_packet_bufsize, 4)) { if (len != status_size + ALIGN(status.wake_packet_bufsize, 4)) {
IWL_ERR(mvm, "Invalid WoWLAN status response!\n"); IWL_ERR(mvm, "Invalid WoWLAN status response!\n");
@ -1571,7 +1552,7 @@ static bool iwl_mvm_query_wakeup_reasons(struct iwl_mvm *mvm,
iwl_mvm_report_wakeup_reasons(mvm, vif, &status); iwl_mvm_report_wakeup_reasons(mvm, vif, &status);
keep = iwl_mvm_setup_connection_keep(mvm, vif, status_v6); keep = iwl_mvm_setup_connection_keep(mvm, vif, fw_status);
iwl_free_resp(&cmd); iwl_free_resp(&cmd);
return keep; return keep;
@ -1674,6 +1655,19 @@ int iwl_mvm_resume(struct ieee80211_hw *hw)
{ {
struct iwl_mvm *mvm = IWL_MAC80211_GET_MVM(hw); struct iwl_mvm *mvm = IWL_MAC80211_GET_MVM(hw);
if (iwl_mvm_is_d0i3_supported(mvm)) {
bool exit_now;
mutex_lock(&mvm->d0i3_suspend_mutex);
__clear_bit(D0I3_DEFER_WAKEUP, &mvm->d0i3_suspend_flags);
exit_now = __test_and_clear_bit(D0I3_PENDING_WAKEUP,
&mvm->d0i3_suspend_flags);
mutex_unlock(&mvm->d0i3_suspend_mutex);
if (exit_now)
_iwl_mvm_exit_d0i3(mvm);
return 0;
}
return __iwl_mvm_resume(mvm, false); return __iwl_mvm_resume(mvm, false);
} }

Просмотреть файл

@ -103,10 +103,6 @@ static void iwl_dbgfs_update_pm(struct iwl_mvm *mvm,
IWL_DEBUG_POWER(mvm, "tx_data_timeout=%d\n", val); IWL_DEBUG_POWER(mvm, "tx_data_timeout=%d\n", val);
dbgfs_pm->tx_data_timeout = val; dbgfs_pm->tx_data_timeout = val;
break; break;
case MVM_DEBUGFS_PM_DISABLE_POWER_OFF:
IWL_DEBUG_POWER(mvm, "disable_power_off=%d\n", val);
dbgfs_pm->disable_power_off = val;
break;
case MVM_DEBUGFS_PM_LPRX_ENA: case MVM_DEBUGFS_PM_LPRX_ENA:
IWL_DEBUG_POWER(mvm, "lprx %s\n", val ? "enabled" : "disabled"); IWL_DEBUG_POWER(mvm, "lprx %s\n", val ? "enabled" : "disabled");
dbgfs_pm->lprx_ena = val; dbgfs_pm->lprx_ena = val;
@ -154,12 +150,6 @@ static ssize_t iwl_dbgfs_pm_params_write(struct ieee80211_vif *vif, char *buf,
if (sscanf(buf + 16, "%d", &val) != 1) if (sscanf(buf + 16, "%d", &val) != 1)
return -EINVAL; return -EINVAL;
param = MVM_DEBUGFS_PM_TX_DATA_TIMEOUT; param = MVM_DEBUGFS_PM_TX_DATA_TIMEOUT;
} else if (!strncmp("disable_power_off=", buf, 18) &&
!(mvm->fw->ucode_capa.flags &
IWL_UCODE_TLV_FLAGS_DEVICE_PS_CMD)) {
if (sscanf(buf + 18, "%d", &val) != 1)
return -EINVAL;
param = MVM_DEBUGFS_PM_DISABLE_POWER_OFF;
} else if (!strncmp("lprx=", buf, 5)) { } else if (!strncmp("lprx=", buf, 5)) {
if (sscanf(buf + 5, "%d", &val) != 1) if (sscanf(buf + 5, "%d", &val) != 1)
return -EINVAL; return -EINVAL;
@ -592,8 +582,7 @@ void iwl_mvm_vif_dbgfs_register(struct iwl_mvm *mvm, struct ieee80211_vif *vif)
return; return;
} }
if ((mvm->fw->ucode_capa.flags & IWL_UCODE_TLV_FLAGS_PM_CMD_SUPPORT) && if (iwlmvm_mod_params.power_scheme != IWL_POWER_SCHEME_CAM &&
iwlmvm_mod_params.power_scheme != IWL_POWER_SCHEME_CAM &&
((vif->type == NL80211_IFTYPE_STATION && !vif->p2p) || ((vif->type == NL80211_IFTYPE_STATION && !vif->p2p) ||
(vif->type == NL80211_IFTYPE_STATION && vif->p2p && (vif->type == NL80211_IFTYPE_STATION && vif->p2p &&
mvm->fw->ucode_capa.flags & IWL_UCODE_TLV_FLAGS_BSS_P2P_PS_DCM))) mvm->fw->ucode_capa.flags & IWL_UCODE_TLV_FLAGS_BSS_P2P_PS_DCM)))

Просмотреть файл

@ -136,9 +136,6 @@ static int iwl_dbgfs_fw_error_dump_open(struct inode *inode, struct file *file)
file->private_data = mvm->fw_error_dump; file->private_data = mvm->fw_error_dump;
mvm->fw_error_dump = NULL; mvm->fw_error_dump = NULL;
kfree(mvm->fw_error_sram);
mvm->fw_error_sram = NULL;
mvm->fw_error_sram_len = 0;
ret = 0; ret = 0;
out: out:
@ -1004,6 +1001,7 @@ static ssize_t iwl_dbgfs_d0i3_refs_read(struct file *file,
PRINT_MVM_REF(IWL_MVM_REF_P2P_CLIENT); PRINT_MVM_REF(IWL_MVM_REF_P2P_CLIENT);
PRINT_MVM_REF(IWL_MVM_REF_AP_IBSS); PRINT_MVM_REF(IWL_MVM_REF_AP_IBSS);
PRINT_MVM_REF(IWL_MVM_REF_USER); PRINT_MVM_REF(IWL_MVM_REF_USER);
PRINT_MVM_REF(IWL_MVM_REF_EXIT_WORK);
return simple_read_from_buffer(user_buf, count, ppos, buf, pos); return simple_read_from_buffer(user_buf, count, ppos, buf, pos);
} }
@ -1108,9 +1106,9 @@ MVM_DEBUGFS_READ_WRITE_FILE_OPS(scan_ant_rxchain, 8);
MVM_DEBUGFS_READ_WRITE_FILE_OPS(d0i3_refs, 8); MVM_DEBUGFS_READ_WRITE_FILE_OPS(d0i3_refs, 8);
static const struct file_operations iwl_dbgfs_fw_error_dump_ops = { static const struct file_operations iwl_dbgfs_fw_error_dump_ops = {
.open = iwl_dbgfs_fw_error_dump_open, .open = iwl_dbgfs_fw_error_dump_open,
.read = iwl_dbgfs_fw_error_dump_read, .read = iwl_dbgfs_fw_error_dump_read,
.release = iwl_dbgfs_fw_error_dump_release, .release = iwl_dbgfs_fw_error_dump_release,
}; };
#ifdef CONFIG_IWLWIFI_BCAST_FILTERING #ifdef CONFIG_IWLWIFI_BCAST_FILTERING
@ -1138,9 +1136,8 @@ int iwl_mvm_dbgfs_register(struct iwl_mvm *mvm, struct dentry *dbgfs_dir)
MVM_DEBUGFS_ADD_FILE(fw_error_dump, dbgfs_dir, S_IRUSR); MVM_DEBUGFS_ADD_FILE(fw_error_dump, dbgfs_dir, S_IRUSR);
MVM_DEBUGFS_ADD_FILE(bt_notif, dbgfs_dir, S_IRUSR); MVM_DEBUGFS_ADD_FILE(bt_notif, dbgfs_dir, S_IRUSR);
MVM_DEBUGFS_ADD_FILE(bt_cmd, dbgfs_dir, S_IRUSR); MVM_DEBUGFS_ADD_FILE(bt_cmd, dbgfs_dir, S_IRUSR);
if (mvm->fw->ucode_capa.flags & IWL_UCODE_TLV_FLAGS_DEVICE_PS_CMD) MVM_DEBUGFS_ADD_FILE(disable_power_off, mvm->debugfs_dir,
MVM_DEBUGFS_ADD_FILE(disable_power_off, mvm->debugfs_dir, S_IRUSR | S_IWUSR);
S_IRUSR | S_IWUSR);
MVM_DEBUGFS_ADD_FILE(fw_rx_stats, mvm->debugfs_dir, S_IRUSR); MVM_DEBUGFS_ADD_FILE(fw_rx_stats, mvm->debugfs_dir, S_IRUSR);
MVM_DEBUGFS_ADD_FILE(drv_rx_stats, mvm->debugfs_dir, S_IRUSR); MVM_DEBUGFS_ADD_FILE(drv_rx_stats, mvm->debugfs_dir, S_IRUSR);
MVM_DEBUGFS_ADD_FILE(fw_restart, mvm->debugfs_dir, S_IWUSR); MVM_DEBUGFS_ADD_FILE(fw_restart, mvm->debugfs_dir, S_IWUSR);

Просмотреть файл

@ -141,7 +141,8 @@ enum iwl_bt_coex_lut_type {
BT_COEX_TX_DIS_LUT, BT_COEX_TX_DIS_LUT,
BT_COEX_MAX_LUT, BT_COEX_MAX_LUT,
}; BT_COEX_INVALID_LUT = 0xff,
}; /* BT_COEX_DECISION_LUT_INDEX_API_E_VER_1 */
#define BT_COEX_LUT_SIZE (12) #define BT_COEX_LUT_SIZE (12)
#define BT_COEX_CORUN_LUT_SIZE (32) #define BT_COEX_CORUN_LUT_SIZE (32)
@ -154,19 +155,23 @@ enum iwl_bt_coex_lut_type {
* @flags:&enum iwl_bt_coex_flags * @flags:&enum iwl_bt_coex_flags
* @max_kill: * @max_kill:
* @bt_reduced_tx_power: enum %iwl_bt_reduced_tx_power * @bt_reduced_tx_power: enum %iwl_bt_reduced_tx_power
* @bt4_antenna_isolation: * @override_primary_lut: enum %iwl_bt_coex_lut_type: BT_COEX_INVALID_LUT
* @bt4_antenna_isolation_thr: * should be set by default
* @bt4_tx_tx_delta_freq_thr: * @override_secondary_lut: enum %iwl_bt_coex_lut_type: BT_COEX_INVALID_LUT
* @bt4_tx_rx_max_freq0: * should be set by default
* @bt_prio_boost: * @bt4_antenna_isolation: antenna isolation
* @bt4_antenna_isolation_thr: antenna threshold value
* @bt4_tx_tx_delta_freq_thr: TxTx delta frequency
* @bt4_tx_rx_max_freq0: TxRx max frequency
* @bt_prio_boost: BT priority boost registers
* @wifi_tx_prio_boost: SW boost of wifi tx priority * @wifi_tx_prio_boost: SW boost of wifi tx priority
* @wifi_rx_prio_boost: SW boost of wifi rx priority * @wifi_rx_prio_boost: SW boost of wifi rx priority
* @kill_ack_msk: * @kill_ack_msk: kill ACK mask. 1 - Tx ACK, 0 - kill Tx of ACK.
* @kill_cts_msk: * @kill_cts_msk: kill CTS mask. 1 - Tx CTS, 0 - kill Tx of CTS.
* @decision_lut: * @decision_lut: PTA decision LUT, per Prio-Ch
* @bt4_multiprio_lut: * @bt4_multiprio_lut: multi priority LUT configuration
* @bt4_corun_lut20: * @bt4_corun_lut20: co-running 20 MHz LUT configuration
* @bt4_corun_lut40: * @bt4_corun_lut40: co-running 40 MHz LUT configuration
* @valid_bit_msk: enum %iwl_bt_coex_valid_bit_msk * @valid_bit_msk: enum %iwl_bt_coex_valid_bit_msk
* *
* The structure is used for the BT_COEX command. * The structure is used for the BT_COEX command.
@ -175,7 +180,8 @@ struct iwl_bt_coex_cmd {
__le32 flags; __le32 flags;
u8 max_kill; u8 max_kill;
u8 bt_reduced_tx_power; u8 bt_reduced_tx_power;
u8 reserved[2]; u8 override_primary_lut;
u8 override_secondary_lut;
u8 bt4_antenna_isolation; u8 bt4_antenna_isolation;
u8 bt4_antenna_isolation_thr; u8 bt4_antenna_isolation_thr;
@ -194,7 +200,7 @@ struct iwl_bt_coex_cmd {
__le32 bt4_corun_lut40[BT_COEX_CORUN_LUT_SIZE]; __le32 bt4_corun_lut40[BT_COEX_CORUN_LUT_SIZE];
__le32 valid_bit_msk; __le32 valid_bit_msk;
} __packed; /* BT_COEX_CMD_API_S_VER_3 */ } __packed; /* BT_COEX_CMD_API_S_VER_5 */
/** /**
* struct iwl_bt_coex_ci_cmd - bt coex channel inhibition command * struct iwl_bt_coex_ci_cmd - bt coex channel inhibition command
@ -282,7 +288,7 @@ enum iwl_bt_activity_grading {
BT_ON_NO_CONNECTION = 1, BT_ON_NO_CONNECTION = 1,
BT_LOW_TRAFFIC = 2, BT_LOW_TRAFFIC = 2,
BT_HIGH_TRAFFIC = 3, BT_HIGH_TRAFFIC = 3,
}; }; /* BT_COEX_BT_ACTIVITY_GRADING_API_E_VER_1 */
/** /**
* struct iwl_bt_coex_profile_notif - notification about BT coex * struct iwl_bt_coex_profile_notif - notification about BT coex
@ -310,7 +316,7 @@ struct iwl_bt_coex_profile_notif {
__le32 primary_ch_lut; __le32 primary_ch_lut;
__le32 secondary_ch_lut; __le32 secondary_ch_lut;
__le32 bt_activity_grading; __le32 bt_activity_grading;
} __packed; /* BT_COEX_PROFILE_NTFY_API_S_VER_2 */ } __packed; /* BT_COEX_PROFILE_NTFY_API_S_VER_3 */
enum iwl_bt_coex_prio_table_event { enum iwl_bt_coex_prio_table_event {
BT_COEX_PRIO_TBL_EVT_INIT_CALIB1 = 0, BT_COEX_PRIO_TBL_EVT_INIT_CALIB1 = 0,

Просмотреть файл

@ -345,21 +345,6 @@ enum iwl_wowlan_wakeup_reason {
IWL_WOWLAN_WAKEUP_BY_REM_WAKE_WAKEUP_PACKET = BIT(12), IWL_WOWLAN_WAKEUP_BY_REM_WAKE_WAKEUP_PACKET = BIT(12),
}; /* WOWLAN_WAKE_UP_REASON_API_E_VER_2 */ }; /* WOWLAN_WAKE_UP_REASON_API_E_VER_2 */
struct iwl_wowlan_status_v4 {
__le64 replay_ctr;
__le16 pattern_number;
__le16 non_qos_seq_ctr;
__le16 qos_seq_ctr[8];
__le32 wakeup_reasons;
__le32 rekey_status;
__le32 num_of_gtk_rekeys;
__le32 transmitted_ndps;
__le32 received_beacons;
__le32 wake_packet_length;
__le32 wake_packet_bufsize;
u8 wake_packet[]; /* can be truncated from _length to _bufsize */
} __packed; /* WOWLAN_STATUSES_API_S_VER_4 */
struct iwl_wowlan_gtk_status { struct iwl_wowlan_gtk_status {
u8 key_index; u8 key_index;
u8 reserved[3]; u8 reserved[3];
@ -368,7 +353,7 @@ struct iwl_wowlan_gtk_status {
struct iwl_wowlan_rsc_tsc_params_cmd rsc; struct iwl_wowlan_rsc_tsc_params_cmd rsc;
} __packed; } __packed;
struct iwl_wowlan_status_v6 { struct iwl_wowlan_status {
struct iwl_wowlan_gtk_status gtk; struct iwl_wowlan_gtk_status gtk;
__le64 replay_ctr; __le64 replay_ctr;
__le16 pattern_number; __le16 pattern_number;

Просмотреть файл

@ -334,7 +334,7 @@ enum {
*/ */
struct iwl_lq_cmd { struct iwl_lq_cmd {
u8 sta_id; u8 sta_id;
u8 reserved1; u8 reduced_tpc;
u16 control; u16 control;
/* LINK_QUAL_GENERAL_PARAMS_API_S_VER_1 */ /* LINK_QUAL_GENERAL_PARAMS_API_S_VER_1 */
u8 flags; u8 flags;

Просмотреть файл

@ -169,8 +169,12 @@ enum iwl_scan_type {
SCAN_TYPE_DISCOVERY_FORCED = 6, SCAN_TYPE_DISCOVERY_FORCED = 6,
}; /* SCAN_ACTIVITY_TYPE_E_VER_1 */ }; /* SCAN_ACTIVITY_TYPE_E_VER_1 */
/* Maximal number of channels to scan */ /**
#define MAX_NUM_SCAN_CHANNELS 0x24 * Maximal number of channels to scan
* it should be equal to:
* max(IWL_NUM_CHANNELS, IWL_NUM_CHANNELS_FAMILY_8000)
*/
#define MAX_NUM_SCAN_CHANNELS 50
/** /**
* struct iwl_scan_cmd - scan request command * struct iwl_scan_cmd - scan request command
@ -534,13 +538,16 @@ struct iwl_scan_offload_schedule {
* *
* IWL_SCAN_OFFLOAD_FLAG_PASS_ALL: pass all results - no filtering. * IWL_SCAN_OFFLOAD_FLAG_PASS_ALL: pass all results - no filtering.
* IWL_SCAN_OFFLOAD_FLAG_CACHED_CHANNEL: add cached channels to partial scan. * IWL_SCAN_OFFLOAD_FLAG_CACHED_CHANNEL: add cached channels to partial scan.
* IWL_SCAN_OFFLOAD_FLAG_ENERGY_SCAN: use energy based scan before partial scan * IWL_SCAN_OFFLOAD_FLAG_EBS_QUICK_MODE: EBS duration is 100mSec - typical
* on A band. * beacon period. Finding channel activity in this mode is not guaranteed.
* IWL_SCAN_OFFLOAD_FLAG_EBS_ACCURATE_MODE: EBS duration is 200mSec.
* Assuming beacon period is 100ms finding channel activity is guaranteed.
*/ */
enum iwl_scan_offload_flags { enum iwl_scan_offload_flags {
IWL_SCAN_OFFLOAD_FLAG_PASS_ALL = BIT(0), IWL_SCAN_OFFLOAD_FLAG_PASS_ALL = BIT(0),
IWL_SCAN_OFFLOAD_FLAG_CACHED_CHANNEL = BIT(2), IWL_SCAN_OFFLOAD_FLAG_CACHED_CHANNEL = BIT(2),
IWL_SCAN_OFFLOAD_FLAG_ENERGY_SCAN = BIT(3), IWL_SCAN_OFFLOAD_FLAG_EBS_QUICK_MODE = BIT(5),
IWL_SCAN_OFFLOAD_FLAG_EBS_ACCURATE_MODE = BIT(6),
}; };
/** /**
@ -563,17 +570,24 @@ enum iwl_scan_offload_compleate_status {
IWL_SCAN_OFFLOAD_ABORTED = 2, IWL_SCAN_OFFLOAD_ABORTED = 2,
}; };
enum iwl_scan_ebs_status {
IWL_SCAN_EBS_SUCCESS,
IWL_SCAN_EBS_FAILED,
IWL_SCAN_EBS_CHAN_NOT_FOUND,
};
/** /**
* iwl_scan_offload_complete - SCAN_OFFLOAD_COMPLETE_NTF_API_S_VER_1 * iwl_scan_offload_complete - SCAN_OFFLOAD_COMPLETE_NTF_API_S_VER_1
* @last_schedule_line: last schedule line executed (fast or regular) * @last_schedule_line: last schedule line executed (fast or regular)
* @last_schedule_iteration: last scan iteration executed before scan abort * @last_schedule_iteration: last scan iteration executed before scan abort
* @status: enum iwl_scan_offload_compleate_status * @status: enum iwl_scan_offload_compleate_status
* @ebs_status: last EBS status, see IWL_SCAN_EBS_*
*/ */
struct iwl_scan_offload_complete { struct iwl_scan_offload_complete {
u8 last_schedule_line; u8 last_schedule_line;
u8 last_schedule_iteration; u8 last_schedule_iteration;
u8 status; u8 status;
u8 reserved; u8 ebs_status;
} __packed; } __packed;
/** /**

Просмотреть файл

@ -255,22 +255,19 @@ struct iwl_mvm_keyinfo {
} __packed; } __packed;
/** /**
* struct iwl_mvm_add_sta_cmd_v5 - Add/modify a station in the fw's sta table. * struct iwl_mvm_add_sta_cmd - Add/modify a station in the fw's sta table.
* ( REPLY_ADD_STA = 0x18 ) * ( REPLY_ADD_STA = 0x18 )
* @add_modify: 1: modify existing, 0: add new station * @add_modify: 1: modify existing, 0: add new station
* @unicast_tx_key_id: unicast tx key id. Relevant only when unicast key sent * @awake_acs:
* @multicast_tx_key_id: multicast tx key id. Relevant only when multicast key * @tid_disable_tx: is tid BIT(tid) enabled for Tx. Clear BIT(x) to enable
* sent * AMPDU for tid x. Set %STA_MODIFY_TID_DISABLE_TX to change this field.
* @mac_id_n_color: the Mac context this station belongs to * @mac_id_n_color: the Mac context this station belongs to
* @addr[ETH_ALEN]: station's MAC address * @addr[ETH_ALEN]: station's MAC address
* @sta_id: index of station in uCode's station table * @sta_id: index of station in uCode's station table
* @modify_mask: STA_MODIFY_*, selects which parameters to modify vs. leave * @modify_mask: STA_MODIFY_*, selects which parameters to modify vs. leave
* alone. 1 - modify, 0 - don't change. * alone. 1 - modify, 0 - don't change.
* @key: look at %iwl_mvm_keyinfo
* @station_flags: look at %iwl_sta_flags * @station_flags: look at %iwl_sta_flags
* @station_flags_msk: what of %station_flags have changed * @station_flags_msk: what of %station_flags have changed
* @tid_disable_tx: is tid BIT(tid) enabled for Tx. Clear BIT(x) to enable
* AMPDU for tid x. Set %STA_MODIFY_TID_DISABLE_TX to change this field.
* @add_immediate_ba_tid: tid for which to add block-ack support (Rx) * @add_immediate_ba_tid: tid for which to add block-ack support (Rx)
* Set %STA_MODIFY_ADD_BA_TID to use this field, and also set * Set %STA_MODIFY_ADD_BA_TID to use this field, and also set
* add_immediate_ba_ssn. * add_immediate_ba_ssn.
@ -294,40 +291,7 @@ struct iwl_mvm_keyinfo {
* ADD_STA sets up the table entry for one station, either creating a new * ADD_STA sets up the table entry for one station, either creating a new
* entry, or modifying a pre-existing one. * entry, or modifying a pre-existing one.
*/ */
struct iwl_mvm_add_sta_cmd_v5 { struct iwl_mvm_add_sta_cmd {
u8 add_modify;
u8 unicast_tx_key_id;
u8 multicast_tx_key_id;
u8 reserved1;
__le32 mac_id_n_color;
u8 addr[ETH_ALEN];
__le16 reserved2;
u8 sta_id;
u8 modify_mask;
__le16 reserved3;
struct iwl_mvm_keyinfo key;
__le32 station_flags;
__le32 station_flags_msk;
__le16 tid_disable_tx;
__le16 reserved4;
u8 add_immediate_ba_tid;
u8 remove_immediate_ba_tid;
__le16 add_immediate_ba_ssn;
__le16 sleep_tx_count;
__le16 sleep_state_flags;
__le16 assoc_id;
__le16 beamform_flags;
__le32 tfd_queue_msk;
} __packed; /* ADD_STA_CMD_API_S_VER_5 */
/**
* struct iwl_mvm_add_sta_cmd_v7 - Add / modify a station
* VER_7 of this command is quite similar to VER_5 except
* exclusion of all fields related to the security key installation.
* It only differs from VER_6 by the "awake_acs" field that is
* reserved and ignored in VER_6.
*/
struct iwl_mvm_add_sta_cmd_v7 {
u8 add_modify; u8 add_modify;
u8 awake_acs; u8 awake_acs;
__le16 tid_disable_tx; __le16 tid_disable_tx;

Некоторые файлы не были показаны из-за слишком большого количества измененных файлов Показать больше