|
@@ -36,11 +36,9 @@ static unsigned int ath10k_target_ps;
|
|
|
module_param(ath10k_target_ps, uint, 0644);
|
|
|
MODULE_PARM_DESC(ath10k_target_ps, "Enable ath10k Target (SoC) PS option");
|
|
|
|
|
|
-#define QCA988X_1_0_DEVICE_ID (0xabcd)
|
|
|
#define QCA988X_2_0_DEVICE_ID (0x003c)
|
|
|
|
|
|
static DEFINE_PCI_DEVICE_TABLE(ath10k_pci_id_table) = {
|
|
|
- { PCI_VDEVICE(ATHEROS, QCA988X_1_0_DEVICE_ID) }, /* PCI-E QCA988X V1 */
|
|
|
{ PCI_VDEVICE(ATHEROS, QCA988X_2_0_DEVICE_ID) }, /* PCI-E QCA988X V2 */
|
|
|
{0}
|
|
|
};
|
|
@@ -50,9 +48,9 @@ static int ath10k_pci_diag_read_access(struct ath10k *ar, u32 address,
|
|
|
|
|
|
static void ath10k_pci_process_ce(struct ath10k *ar);
|
|
|
static int ath10k_pci_post_rx(struct ath10k *ar);
|
|
|
-static int ath10k_pci_post_rx_pipe(struct hif_ce_pipe_info *pipe_info,
|
|
|
+static int ath10k_pci_post_rx_pipe(struct ath10k_pci_pipe *pipe_info,
|
|
|
int num);
|
|
|
-static void ath10k_pci_rx_pipe_cleanup(struct hif_ce_pipe_info *pipe_info);
|
|
|
+static void ath10k_pci_rx_pipe_cleanup(struct ath10k_pci_pipe *pipe_info);
|
|
|
static void ath10k_pci_stop_ce(struct ath10k *ar);
|
|
|
static void ath10k_pci_device_reset(struct ath10k *ar);
|
|
|
static int ath10k_pci_reset_target(struct ath10k *ar);
|
|
@@ -60,43 +58,145 @@ static int ath10k_pci_start_intr(struct ath10k *ar);
|
|
|
static void ath10k_pci_stop_intr(struct ath10k *ar);
|
|
|
|
|
|
static const struct ce_attr host_ce_config_wlan[] = {
|
|
|
- /* host->target HTC control and raw streams */
|
|
|
- { /* CE0 */ CE_ATTR_FLAGS, 0, 16, 256, 0, NULL,},
|
|
|
- /* could be moved to share CE3 */
|
|
|
- /* target->host HTT + HTC control */
|
|
|
- { /* CE1 */ CE_ATTR_FLAGS, 0, 0, 512, 512, NULL,},
|
|
|
- /* target->host WMI */
|
|
|
- { /* CE2 */ CE_ATTR_FLAGS, 0, 0, 2048, 32, NULL,},
|
|
|
- /* host->target WMI */
|
|
|
- { /* CE3 */ CE_ATTR_FLAGS, 0, 32, 2048, 0, NULL,},
|
|
|
- /* host->target HTT */
|
|
|
- { /* CE4 */ CE_ATTR_FLAGS | CE_ATTR_DIS_INTR, 0,
|
|
|
- CE_HTT_H2T_MSG_SRC_NENTRIES, 256, 0, NULL,},
|
|
|
- /* unused */
|
|
|
- { /* CE5 */ CE_ATTR_FLAGS, 0, 0, 0, 0, NULL,},
|
|
|
- /* Target autonomous hif_memcpy */
|
|
|
- { /* CE6 */ CE_ATTR_FLAGS, 0, 0, 0, 0, NULL,},
|
|
|
- /* ce_diag, the Diagnostic Window */
|
|
|
- { /* CE7 */ CE_ATTR_FLAGS, 0, 2, DIAG_TRANSFER_LIMIT, 2, NULL,},
|
|
|
+ /* CE0: host->target HTC control and raw streams */
|
|
|
+ {
|
|
|
+ .flags = CE_ATTR_FLAGS,
|
|
|
+ .src_nentries = 16,
|
|
|
+ .src_sz_max = 256,
|
|
|
+ .dest_nentries = 0,
|
|
|
+ },
|
|
|
+
|
|
|
+ /* CE1: target->host HTT + HTC control */
|
|
|
+ {
|
|
|
+ .flags = CE_ATTR_FLAGS,
|
|
|
+ .src_nentries = 0,
|
|
|
+ .src_sz_max = 512,
|
|
|
+ .dest_nentries = 512,
|
|
|
+ },
|
|
|
+
|
|
|
+ /* CE2: target->host WMI */
|
|
|
+ {
|
|
|
+ .flags = CE_ATTR_FLAGS,
|
|
|
+ .src_nentries = 0,
|
|
|
+ .src_sz_max = 2048,
|
|
|
+ .dest_nentries = 32,
|
|
|
+ },
|
|
|
+
|
|
|
+ /* CE3: host->target WMI */
|
|
|
+ {
|
|
|
+ .flags = CE_ATTR_FLAGS,
|
|
|
+ .src_nentries = 32,
|
|
|
+ .src_sz_max = 2048,
|
|
|
+ .dest_nentries = 0,
|
|
|
+ },
|
|
|
+
|
|
|
+ /* CE4: host->target HTT */
|
|
|
+ {
|
|
|
+ .flags = CE_ATTR_FLAGS | CE_ATTR_DIS_INTR,
|
|
|
+ .src_nentries = CE_HTT_H2T_MSG_SRC_NENTRIES,
|
|
|
+ .src_sz_max = 256,
|
|
|
+ .dest_nentries = 0,
|
|
|
+ },
|
|
|
+
|
|
|
+ /* CE5: unused */
|
|
|
+ {
|
|
|
+ .flags = CE_ATTR_FLAGS,
|
|
|
+ .src_nentries = 0,
|
|
|
+ .src_sz_max = 0,
|
|
|
+ .dest_nentries = 0,
|
|
|
+ },
|
|
|
+
|
|
|
+ /* CE6: target autonomous hif_memcpy */
|
|
|
+ {
|
|
|
+ .flags = CE_ATTR_FLAGS,
|
|
|
+ .src_nentries = 0,
|
|
|
+ .src_sz_max = 0,
|
|
|
+ .dest_nentries = 0,
|
|
|
+ },
|
|
|
+
|
|
|
+ /* CE7: ce_diag, the Diagnostic Window */
|
|
|
+ {
|
|
|
+ .flags = CE_ATTR_FLAGS,
|
|
|
+ .src_nentries = 2,
|
|
|
+ .src_sz_max = DIAG_TRANSFER_LIMIT,
|
|
|
+ .dest_nentries = 2,
|
|
|
+ },
|
|
|
};
|
|
|
|
|
|
/* Target firmware's Copy Engine configuration. */
|
|
|
static const struct ce_pipe_config target_ce_config_wlan[] = {
|
|
|
- /* host->target HTC control and raw streams */
|
|
|
- { /* CE0 */ 0, PIPEDIR_OUT, 32, 256, CE_ATTR_FLAGS, 0,},
|
|
|
- /* target->host HTT + HTC control */
|
|
|
- { /* CE1 */ 1, PIPEDIR_IN, 32, 512, CE_ATTR_FLAGS, 0,},
|
|
|
- /* target->host WMI */
|
|
|
- { /* CE2 */ 2, PIPEDIR_IN, 32, 2048, CE_ATTR_FLAGS, 0,},
|
|
|
- /* host->target WMI */
|
|
|
- { /* CE3 */ 3, PIPEDIR_OUT, 32, 2048, CE_ATTR_FLAGS, 0,},
|
|
|
- /* host->target HTT */
|
|
|
- { /* CE4 */ 4, PIPEDIR_OUT, 256, 256, CE_ATTR_FLAGS, 0,},
|
|
|
+ /* CE0: host->target HTC control and raw streams */
|
|
|
+ {
|
|
|
+ .pipenum = 0,
|
|
|
+ .pipedir = PIPEDIR_OUT,
|
|
|
+ .nentries = 32,
|
|
|
+ .nbytes_max = 256,
|
|
|
+ .flags = CE_ATTR_FLAGS,
|
|
|
+ .reserved = 0,
|
|
|
+ },
|
|
|
+
|
|
|
+ /* CE1: target->host HTT + HTC control */
|
|
|
+ {
|
|
|
+ .pipenum = 1,
|
|
|
+ .pipedir = PIPEDIR_IN,
|
|
|
+ .nentries = 32,
|
|
|
+ .nbytes_max = 512,
|
|
|
+ .flags = CE_ATTR_FLAGS,
|
|
|
+ .reserved = 0,
|
|
|
+ },
|
|
|
+
|
|
|
+ /* CE2: target->host WMI */
|
|
|
+ {
|
|
|
+ .pipenum = 2,
|
|
|
+ .pipedir = PIPEDIR_IN,
|
|
|
+ .nentries = 32,
|
|
|
+ .nbytes_max = 2048,
|
|
|
+ .flags = CE_ATTR_FLAGS,
|
|
|
+ .reserved = 0,
|
|
|
+ },
|
|
|
+
|
|
|
+ /* CE3: host->target WMI */
|
|
|
+ {
|
|
|
+ .pipenum = 3,
|
|
|
+ .pipedir = PIPEDIR_OUT,
|
|
|
+ .nentries = 32,
|
|
|
+ .nbytes_max = 2048,
|
|
|
+ .flags = CE_ATTR_FLAGS,
|
|
|
+ .reserved = 0,
|
|
|
+ },
|
|
|
+
|
|
|
+ /* CE4: host->target HTT */
|
|
|
+ {
|
|
|
+ .pipenum = 4,
|
|
|
+ .pipedir = PIPEDIR_OUT,
|
|
|
+ .nentries = 256,
|
|
|
+ .nbytes_max = 256,
|
|
|
+ .flags = CE_ATTR_FLAGS,
|
|
|
+ .reserved = 0,
|
|
|
+ },
|
|
|
+
|
|
|
/* NB: 50% of src nentries, since tx has 2 frags */
|
|
|
- /* unused */
|
|
|
- { /* CE5 */ 5, PIPEDIR_OUT, 32, 2048, CE_ATTR_FLAGS, 0,},
|
|
|
- /* Reserved for target autonomous hif_memcpy */
|
|
|
- { /* CE6 */ 6, PIPEDIR_INOUT, 32, 4096, CE_ATTR_FLAGS, 0,},
|
|
|
+
|
|
|
+ /* CE5: unused */
|
|
|
+ {
|
|
|
+ .pipenum = 5,
|
|
|
+ .pipedir = PIPEDIR_OUT,
|
|
|
+ .nentries = 32,
|
|
|
+ .nbytes_max = 2048,
|
|
|
+ .flags = CE_ATTR_FLAGS,
|
|
|
+ .reserved = 0,
|
|
|
+ },
|
|
|
+
|
|
|
+ /* CE6: Reserved for target autonomous hif_memcpy */
|
|
|
+ {
|
|
|
+ .pipenum = 6,
|
|
|
+ .pipedir = PIPEDIR_INOUT,
|
|
|
+ .nentries = 32,
|
|
|
+ .nbytes_max = 4096,
|
|
|
+ .flags = CE_ATTR_FLAGS,
|
|
|
+ .reserved = 0,
|
|
|
+ },
|
|
|
+
|
|
|
/* CE7 used only by Host */
|
|
|
};
|
|
|
|
|
@@ -114,7 +214,7 @@ static int ath10k_pci_diag_read_mem(struct ath10k *ar, u32 address, void *data,
|
|
|
unsigned int completed_nbytes, orig_nbytes, remaining_bytes;
|
|
|
unsigned int id;
|
|
|
unsigned int flags;
|
|
|
- struct ce_state *ce_diag;
|
|
|
+ struct ath10k_ce_pipe *ce_diag;
|
|
|
/* Host buffer address in CE space */
|
|
|
u32 ce_data;
|
|
|
dma_addr_t ce_data_base = 0;
|
|
@@ -278,7 +378,7 @@ static int ath10k_pci_diag_write_mem(struct ath10k *ar, u32 address,
|
|
|
unsigned int completed_nbytes, orig_nbytes, remaining_bytes;
|
|
|
unsigned int id;
|
|
|
unsigned int flags;
|
|
|
- struct ce_state *ce_diag;
|
|
|
+ struct ath10k_ce_pipe *ce_diag;
|
|
|
void *data_buf = NULL;
|
|
|
u32 ce_data; /* Host buffer address in CE space */
|
|
|
dma_addr_t ce_data_base = 0;
|
|
@@ -437,7 +537,7 @@ static void ath10k_pci_wait(struct ath10k *ar)
|
|
|
ath10k_warn("Unable to wakeup target\n");
|
|
|
}
|
|
|
|
|
|
-void ath10k_do_pci_wake(struct ath10k *ar)
|
|
|
+int ath10k_do_pci_wake(struct ath10k *ar)
|
|
|
{
|
|
|
struct ath10k_pci *ar_pci = ath10k_pci_priv(ar);
|
|
|
void __iomem *pci_addr = ar_pci->mem;
|
|
@@ -453,18 +553,19 @@ void ath10k_do_pci_wake(struct ath10k *ar)
|
|
|
atomic_inc(&ar_pci->keep_awake_count);
|
|
|
|
|
|
if (ar_pci->verified_awake)
|
|
|
- return;
|
|
|
+ return 0;
|
|
|
|
|
|
for (;;) {
|
|
|
if (ath10k_pci_target_is_awake(ar)) {
|
|
|
ar_pci->verified_awake = true;
|
|
|
- break;
|
|
|
+ return 0;
|
|
|
}
|
|
|
|
|
|
if (tot_delay > PCIE_WAKE_TIMEOUT) {
|
|
|
- ath10k_warn("target takes too long to wake up (awake count %d)\n",
|
|
|
+ ath10k_warn("target took longer %d us to wake up (awake count %d)\n",
|
|
|
+ PCIE_WAKE_TIMEOUT,
|
|
|
atomic_read(&ar_pci->keep_awake_count));
|
|
|
- break;
|
|
|
+ return -ETIMEDOUT;
|
|
|
}
|
|
|
|
|
|
udelay(curr_delay);
|
|
@@ -493,7 +594,7 @@ void ath10k_do_pci_sleep(struct ath10k *ar)
|
|
|
* FIXME: Handle OOM properly.
|
|
|
*/
|
|
|
static inline
|
|
|
-struct ath10k_pci_compl *get_free_compl(struct hif_ce_pipe_info *pipe_info)
|
|
|
+struct ath10k_pci_compl *get_free_compl(struct ath10k_pci_pipe *pipe_info)
|
|
|
{
|
|
|
struct ath10k_pci_compl *compl = NULL;
|
|
|
|
|
@@ -511,7 +612,7 @@ exit:
|
|
|
}
|
|
|
|
|
|
/* Called by lower (CE) layer when a send to Target completes. */
|
|
|
-static void ath10k_pci_ce_send_done(struct ce_state *ce_state,
|
|
|
+static void ath10k_pci_ce_send_done(struct ath10k_ce_pipe *ce_state,
|
|
|
void *transfer_context,
|
|
|
u32 ce_data,
|
|
|
unsigned int nbytes,
|
|
@@ -519,7 +620,7 @@ static void ath10k_pci_ce_send_done(struct ce_state *ce_state,
|
|
|
{
|
|
|
struct ath10k *ar = ce_state->ar;
|
|
|
struct ath10k_pci *ar_pci = ath10k_pci_priv(ar);
|
|
|
- struct hif_ce_pipe_info *pipe_info = &ar_pci->pipe_info[ce_state->id];
|
|
|
+ struct ath10k_pci_pipe *pipe_info = &ar_pci->pipe_info[ce_state->id];
|
|
|
struct ath10k_pci_compl *compl;
|
|
|
bool process = false;
|
|
|
|
|
@@ -540,10 +641,10 @@ static void ath10k_pci_ce_send_done(struct ce_state *ce_state,
|
|
|
if (!compl)
|
|
|
break;
|
|
|
|
|
|
- compl->send_or_recv = HIF_CE_COMPLETE_SEND;
|
|
|
+ compl->state = ATH10K_PCI_COMPL_SEND;
|
|
|
compl->ce_state = ce_state;
|
|
|
compl->pipe_info = pipe_info;
|
|
|
- compl->transfer_context = transfer_context;
|
|
|
+ compl->skb = transfer_context;
|
|
|
compl->nbytes = nbytes;
|
|
|
compl->transfer_id = transfer_id;
|
|
|
compl->flags = 0;
|
|
@@ -573,7 +674,7 @@ static void ath10k_pci_ce_send_done(struct ce_state *ce_state,
|
|
|
}
|
|
|
|
|
|
/* Called by lower (CE) layer when data is received from the Target. */
|
|
|
-static void ath10k_pci_ce_recv_data(struct ce_state *ce_state,
|
|
|
+static void ath10k_pci_ce_recv_data(struct ath10k_ce_pipe *ce_state,
|
|
|
void *transfer_context, u32 ce_data,
|
|
|
unsigned int nbytes,
|
|
|
unsigned int transfer_id,
|
|
@@ -581,7 +682,7 @@ static void ath10k_pci_ce_recv_data(struct ce_state *ce_state,
|
|
|
{
|
|
|
struct ath10k *ar = ce_state->ar;
|
|
|
struct ath10k_pci *ar_pci = ath10k_pci_priv(ar);
|
|
|
- struct hif_ce_pipe_info *pipe_info = &ar_pci->pipe_info[ce_state->id];
|
|
|
+ struct ath10k_pci_pipe *pipe_info = &ar_pci->pipe_info[ce_state->id];
|
|
|
struct ath10k_pci_compl *compl;
|
|
|
struct sk_buff *skb;
|
|
|
|
|
@@ -590,10 +691,10 @@ static void ath10k_pci_ce_recv_data(struct ce_state *ce_state,
|
|
|
if (!compl)
|
|
|
break;
|
|
|
|
|
|
- compl->send_or_recv = HIF_CE_COMPLETE_RECV;
|
|
|
+ compl->state = ATH10K_PCI_COMPL_RECV;
|
|
|
compl->ce_state = ce_state;
|
|
|
compl->pipe_info = pipe_info;
|
|
|
- compl->transfer_context = transfer_context;
|
|
|
+ compl->skb = transfer_context;
|
|
|
compl->nbytes = nbytes;
|
|
|
compl->transfer_id = transfer_id;
|
|
|
compl->flags = flags;
|
|
@@ -625,8 +726,8 @@ static int ath10k_pci_hif_send_head(struct ath10k *ar, u8 pipe_id,
|
|
|
{
|
|
|
struct ath10k_skb_cb *skb_cb = ATH10K_SKB_CB(nbuf);
|
|
|
struct ath10k_pci *ar_pci = ath10k_pci_priv(ar);
|
|
|
- struct hif_ce_pipe_info *pipe_info = &(ar_pci->pipe_info[pipe_id]);
|
|
|
- struct ce_state *ce_hdl = pipe_info->ce_hdl;
|
|
|
+ struct ath10k_pci_pipe *pipe_info = &(ar_pci->pipe_info[pipe_id]);
|
|
|
+ struct ath10k_ce_pipe *ce_hdl = pipe_info->ce_hdl;
|
|
|
struct ce_sendlist sendlist;
|
|
|
unsigned int len;
|
|
|
u32 flags = 0;
|
|
@@ -670,7 +771,7 @@ static int ath10k_pci_hif_send_head(struct ath10k *ar, u8 pipe_id,
|
|
|
static u16 ath10k_pci_hif_get_free_queue_number(struct ath10k *ar, u8 pipe)
|
|
|
{
|
|
|
struct ath10k_pci *ar_pci = ath10k_pci_priv(ar);
|
|
|
- struct hif_ce_pipe_info *pipe_info = &(ar_pci->pipe_info[pipe]);
|
|
|
+ struct ath10k_pci_pipe *pipe_info = &(ar_pci->pipe_info[pipe]);
|
|
|
int ret;
|
|
|
|
|
|
spin_lock_bh(&pipe_info->pipe_lock);
|
|
@@ -764,9 +865,9 @@ static void ath10k_pci_hif_set_callbacks(struct ath10k *ar,
|
|
|
static int ath10k_pci_start_ce(struct ath10k *ar)
|
|
|
{
|
|
|
struct ath10k_pci *ar_pci = ath10k_pci_priv(ar);
|
|
|
- struct ce_state *ce_diag = ar_pci->ce_diag;
|
|
|
+ struct ath10k_ce_pipe *ce_diag = ar_pci->ce_diag;
|
|
|
const struct ce_attr *attr;
|
|
|
- struct hif_ce_pipe_info *pipe_info;
|
|
|
+ struct ath10k_pci_pipe *pipe_info;
|
|
|
struct ath10k_pci_compl *compl;
|
|
|
int i, pipe_num, completions, disable_interrupts;
|
|
|
|
|
@@ -805,15 +906,14 @@ static int ath10k_pci_start_ce(struct ath10k *ar)
|
|
|
continue;
|
|
|
|
|
|
for (i = 0; i < completions; i++) {
|
|
|
- compl = kmalloc(sizeof(struct ath10k_pci_compl),
|
|
|
- GFP_KERNEL);
|
|
|
+ compl = kmalloc(sizeof(*compl), GFP_KERNEL);
|
|
|
if (!compl) {
|
|
|
ath10k_warn("No memory for completion state\n");
|
|
|
ath10k_pci_stop_ce(ar);
|
|
|
return -ENOMEM;
|
|
|
}
|
|
|
|
|
|
- compl->send_or_recv = HIF_CE_COMPLETE_FREE;
|
|
|
+ compl->state = ATH10K_PCI_COMPL_FREE;
|
|
|
list_add_tail(&compl->list, &pipe_info->compl_free);
|
|
|
}
|
|
|
}
|
|
@@ -840,7 +940,7 @@ static void ath10k_pci_stop_ce(struct ath10k *ar)
|
|
|
* their associated resources */
|
|
|
spin_lock_bh(&ar_pci->compl_lock);
|
|
|
list_for_each_entry(compl, &ar_pci->compl_process, list) {
|
|
|
- skb = (struct sk_buff *)compl->transfer_context;
|
|
|
+ skb = compl->skb;
|
|
|
ATH10K_SKB_CB(skb)->is_aborted = true;
|
|
|
}
|
|
|
spin_unlock_bh(&ar_pci->compl_lock);
|
|
@@ -850,7 +950,7 @@ static void ath10k_pci_cleanup_ce(struct ath10k *ar)
|
|
|
{
|
|
|
struct ath10k_pci *ar_pci = ath10k_pci_priv(ar);
|
|
|
struct ath10k_pci_compl *compl, *tmp;
|
|
|
- struct hif_ce_pipe_info *pipe_info;
|
|
|
+ struct ath10k_pci_pipe *pipe_info;
|
|
|
struct sk_buff *netbuf;
|
|
|
int pipe_num;
|
|
|
|
|
@@ -861,7 +961,7 @@ static void ath10k_pci_cleanup_ce(struct ath10k *ar)
|
|
|
|
|
|
list_for_each_entry_safe(compl, tmp, &ar_pci->compl_process, list) {
|
|
|
list_del(&compl->list);
|
|
|
- netbuf = (struct sk_buff *)compl->transfer_context;
|
|
|
+ netbuf = compl->skb;
|
|
|
dev_kfree_skb_any(netbuf);
|
|
|
kfree(compl);
|
|
|
}
|
|
@@ -912,12 +1012,14 @@ static void ath10k_pci_process_ce(struct ath10k *ar)
|
|
|
list_del(&compl->list);
|
|
|
spin_unlock_bh(&ar_pci->compl_lock);
|
|
|
|
|
|
- if (compl->send_or_recv == HIF_CE_COMPLETE_SEND) {
|
|
|
+ switch (compl->state) {
|
|
|
+ case ATH10K_PCI_COMPL_SEND:
|
|
|
cb->tx_completion(ar,
|
|
|
- compl->transfer_context,
|
|
|
+ compl->skb,
|
|
|
compl->transfer_id);
|
|
|
send_done = 1;
|
|
|
- } else {
|
|
|
+ break;
|
|
|
+ case ATH10K_PCI_COMPL_RECV:
|
|
|
ret = ath10k_pci_post_rx_pipe(compl->pipe_info, 1);
|
|
|
if (ret) {
|
|
|
ath10k_warn("Unable to post recv buffer for pipe: %d\n",
|
|
@@ -925,7 +1027,7 @@ static void ath10k_pci_process_ce(struct ath10k *ar)
|
|
|
break;
|
|
|
}
|
|
|
|
|
|
- skb = (struct sk_buff *)compl->transfer_context;
|
|
|
+ skb = compl->skb;
|
|
|
nbytes = compl->nbytes;
|
|
|
|
|
|
ath10k_dbg(ATH10K_DBG_PCI,
|
|
@@ -944,9 +1046,17 @@ static void ath10k_pci_process_ce(struct ath10k *ar)
|
|
|
nbytes,
|
|
|
skb->len + skb_tailroom(skb));
|
|
|
}
|
|
|
+ break;
|
|
|
+ case ATH10K_PCI_COMPL_FREE:
|
|
|
+ ath10k_warn("free completion cannot be processed\n");
|
|
|
+ break;
|
|
|
+ default:
|
|
|
+ ath10k_warn("invalid completion state (%d)\n",
|
|
|
+ compl->state);
|
|
|
+ break;
|
|
|
}
|
|
|
|
|
|
- compl->send_or_recv = HIF_CE_COMPLETE_FREE;
|
|
|
+ compl->state = ATH10K_PCI_COMPL_FREE;
|
|
|
|
|
|
/*
|
|
|
* Add completion back to the pipe's free list.
|
|
@@ -1037,12 +1147,12 @@ static void ath10k_pci_hif_get_default_pipe(struct ath10k *ar,
|
|
|
&dl_is_polled);
|
|
|
}
|
|
|
|
|
|
-static int ath10k_pci_post_rx_pipe(struct hif_ce_pipe_info *pipe_info,
|
|
|
+static int ath10k_pci_post_rx_pipe(struct ath10k_pci_pipe *pipe_info,
|
|
|
int num)
|
|
|
{
|
|
|
struct ath10k *ar = pipe_info->hif_ce_state;
|
|
|
struct ath10k_pci *ar_pci = ath10k_pci_priv(ar);
|
|
|
- struct ce_state *ce_state = pipe_info->ce_hdl;
|
|
|
+ struct ath10k_ce_pipe *ce_state = pipe_info->ce_hdl;
|
|
|
struct sk_buff *skb;
|
|
|
dma_addr_t ce_data;
|
|
|
int i, ret = 0;
|
|
@@ -1097,7 +1207,7 @@ err:
|
|
|
static int ath10k_pci_post_rx(struct ath10k *ar)
|
|
|
{
|
|
|
struct ath10k_pci *ar_pci = ath10k_pci_priv(ar);
|
|
|
- struct hif_ce_pipe_info *pipe_info;
|
|
|
+ struct ath10k_pci_pipe *pipe_info;
|
|
|
const struct ce_attr *attr;
|
|
|
int pipe_num, ret = 0;
|
|
|
|
|
@@ -1147,11 +1257,11 @@ static int ath10k_pci_hif_start(struct ath10k *ar)
|
|
|
return 0;
|
|
|
}
|
|
|
|
|
|
-static void ath10k_pci_rx_pipe_cleanup(struct hif_ce_pipe_info *pipe_info)
|
|
|
+static void ath10k_pci_rx_pipe_cleanup(struct ath10k_pci_pipe *pipe_info)
|
|
|
{
|
|
|
struct ath10k *ar;
|
|
|
struct ath10k_pci *ar_pci;
|
|
|
- struct ce_state *ce_hdl;
|
|
|
+ struct ath10k_ce_pipe *ce_hdl;
|
|
|
u32 buf_sz;
|
|
|
struct sk_buff *netbuf;
|
|
|
u32 ce_data;
|
|
@@ -1179,11 +1289,11 @@ static void ath10k_pci_rx_pipe_cleanup(struct hif_ce_pipe_info *pipe_info)
|
|
|
}
|
|
|
}
|
|
|
|
|
|
-static void ath10k_pci_tx_pipe_cleanup(struct hif_ce_pipe_info *pipe_info)
|
|
|
+static void ath10k_pci_tx_pipe_cleanup(struct ath10k_pci_pipe *pipe_info)
|
|
|
{
|
|
|
struct ath10k *ar;
|
|
|
struct ath10k_pci *ar_pci;
|
|
|
- struct ce_state *ce_hdl;
|
|
|
+ struct ath10k_ce_pipe *ce_hdl;
|
|
|
struct sk_buff *netbuf;
|
|
|
u32 ce_data;
|
|
|
unsigned int nbytes;
|
|
@@ -1232,7 +1342,7 @@ static void ath10k_pci_buffer_cleanup(struct ath10k *ar)
|
|
|
int pipe_num;
|
|
|
|
|
|
for (pipe_num = 0; pipe_num < ar_pci->ce_count; pipe_num++) {
|
|
|
- struct hif_ce_pipe_info *pipe_info;
|
|
|
+ struct ath10k_pci_pipe *pipe_info;
|
|
|
|
|
|
pipe_info = &ar_pci->pipe_info[pipe_num];
|
|
|
ath10k_pci_rx_pipe_cleanup(pipe_info);
|
|
@@ -1243,7 +1353,7 @@ static void ath10k_pci_buffer_cleanup(struct ath10k *ar)
|
|
|
static void ath10k_pci_ce_deinit(struct ath10k *ar)
|
|
|
{
|
|
|
struct ath10k_pci *ar_pci = ath10k_pci_priv(ar);
|
|
|
- struct hif_ce_pipe_info *pipe_info;
|
|
|
+ struct ath10k_pci_pipe *pipe_info;
|
|
|
int pipe_num;
|
|
|
|
|
|
for (pipe_num = 0; pipe_num < ar_pci->ce_count; pipe_num++) {
|
|
@@ -1293,8 +1403,10 @@ static int ath10k_pci_hif_exchange_bmi_msg(struct ath10k *ar,
|
|
|
void *resp, u32 *resp_len)
|
|
|
{
|
|
|
struct ath10k_pci *ar_pci = ath10k_pci_priv(ar);
|
|
|
- struct ce_state *ce_tx = ar_pci->pipe_info[BMI_CE_NUM_TO_TARG].ce_hdl;
|
|
|
- struct ce_state *ce_rx = ar_pci->pipe_info[BMI_CE_NUM_TO_HOST].ce_hdl;
|
|
|
+ struct ath10k_pci_pipe *pci_tx = &ar_pci->pipe_info[BMI_CE_NUM_TO_TARG];
|
|
|
+ struct ath10k_pci_pipe *pci_rx = &ar_pci->pipe_info[BMI_CE_NUM_TO_HOST];
|
|
|
+ struct ath10k_ce_pipe *ce_tx = pci_tx->ce_hdl;
|
|
|
+ struct ath10k_ce_pipe *ce_rx = pci_rx->ce_hdl;
|
|
|
dma_addr_t req_paddr = 0;
|
|
|
dma_addr_t resp_paddr = 0;
|
|
|
struct bmi_xfer xfer = {};
|
|
@@ -1378,7 +1490,7 @@ err_dma:
|
|
|
return ret;
|
|
|
}
|
|
|
|
|
|
-static void ath10k_pci_bmi_send_done(struct ce_state *ce_state,
|
|
|
+static void ath10k_pci_bmi_send_done(struct ath10k_ce_pipe *ce_state,
|
|
|
void *transfer_context,
|
|
|
u32 data,
|
|
|
unsigned int nbytes,
|
|
@@ -1392,7 +1504,7 @@ static void ath10k_pci_bmi_send_done(struct ce_state *ce_state,
|
|
|
complete(&xfer->done);
|
|
|
}
|
|
|
|
|
|
-static void ath10k_pci_bmi_recv_data(struct ce_state *ce_state,
|
|
|
+static void ath10k_pci_bmi_recv_data(struct ath10k_ce_pipe *ce_state,
|
|
|
void *transfer_context,
|
|
|
u32 data,
|
|
|
unsigned int nbytes,
|
|
@@ -1679,7 +1791,7 @@ static int ath10k_pci_init_config(struct ath10k *ar)
|
|
|
static int ath10k_pci_ce_init(struct ath10k *ar)
|
|
|
{
|
|
|
struct ath10k_pci *ar_pci = ath10k_pci_priv(ar);
|
|
|
- struct hif_ce_pipe_info *pipe_info;
|
|
|
+ struct ath10k_pci_pipe *pipe_info;
|
|
|
const struct ce_attr *attr;
|
|
|
int pipe_num;
|
|
|
|
|
@@ -1895,7 +2007,7 @@ static const struct ath10k_hif_ops ath10k_pci_hif_ops = {
|
|
|
|
|
|
static void ath10k_pci_ce_tasklet(unsigned long ptr)
|
|
|
{
|
|
|
- struct hif_ce_pipe_info *pipe = (struct hif_ce_pipe_info *)ptr;
|
|
|
+ struct ath10k_pci_pipe *pipe = (struct ath10k_pci_pipe *)ptr;
|
|
|
struct ath10k_pci *ar_pci = pipe->ar_pci;
|
|
|
|
|
|
ath10k_ce_per_engine_service(ar_pci->ar, pipe->pipe_num);
|
|
@@ -2212,18 +2324,13 @@ static int ath10k_pci_reset_target(struct ath10k *ar)
|
|
|
|
|
|
static void ath10k_pci_device_reset(struct ath10k *ar)
|
|
|
{
|
|
|
- struct ath10k_pci *ar_pci = ath10k_pci_priv(ar);
|
|
|
- void __iomem *mem = ar_pci->mem;
|
|
|
int i;
|
|
|
u32 val;
|
|
|
|
|
|
if (!SOC_GLOBAL_RESET_ADDRESS)
|
|
|
return;
|
|
|
|
|
|
- if (!mem)
|
|
|
- return;
|
|
|
-
|
|
|
- ath10k_pci_reg_write32(mem, PCIE_SOC_WAKE_ADDRESS,
|
|
|
+ ath10k_pci_reg_write32(ar, PCIE_SOC_WAKE_ADDRESS,
|
|
|
PCIE_SOC_WAKE_V_MASK);
|
|
|
for (i = 0; i < ATH_PCI_RESET_WAIT_MAX; i++) {
|
|
|
if (ath10k_pci_target_is_awake(ar))
|
|
@@ -2232,12 +2339,12 @@ static void ath10k_pci_device_reset(struct ath10k *ar)
|
|
|
}
|
|
|
|
|
|
/* Put Target, including PCIe, into RESET. */
|
|
|
- val = ath10k_pci_reg_read32(mem, SOC_GLOBAL_RESET_ADDRESS);
|
|
|
+ val = ath10k_pci_reg_read32(ar, SOC_GLOBAL_RESET_ADDRESS);
|
|
|
val |= 1;
|
|
|
- ath10k_pci_reg_write32(mem, SOC_GLOBAL_RESET_ADDRESS, val);
|
|
|
+ ath10k_pci_reg_write32(ar, SOC_GLOBAL_RESET_ADDRESS, val);
|
|
|
|
|
|
for (i = 0; i < ATH_PCI_RESET_WAIT_MAX; i++) {
|
|
|
- if (ath10k_pci_reg_read32(mem, RTC_STATE_ADDRESS) &
|
|
|
+ if (ath10k_pci_reg_read32(ar, RTC_STATE_ADDRESS) &
|
|
|
RTC_STATE_COLD_RESET_MASK)
|
|
|
break;
|
|
|
msleep(1);
|
|
@@ -2245,16 +2352,16 @@ static void ath10k_pci_device_reset(struct ath10k *ar)
|
|
|
|
|
|
/* Pull Target, including PCIe, out of RESET. */
|
|
|
val &= ~1;
|
|
|
- ath10k_pci_reg_write32(mem, SOC_GLOBAL_RESET_ADDRESS, val);
|
|
|
+ ath10k_pci_reg_write32(ar, SOC_GLOBAL_RESET_ADDRESS, val);
|
|
|
|
|
|
for (i = 0; i < ATH_PCI_RESET_WAIT_MAX; i++) {
|
|
|
- if (!(ath10k_pci_reg_read32(mem, RTC_STATE_ADDRESS) &
|
|
|
+ if (!(ath10k_pci_reg_read32(ar, RTC_STATE_ADDRESS) &
|
|
|
RTC_STATE_COLD_RESET_MASK))
|
|
|
break;
|
|
|
msleep(1);
|
|
|
}
|
|
|
|
|
|
- ath10k_pci_reg_write32(mem, PCIE_SOC_WAKE_ADDRESS, PCIE_SOC_WAKE_RESET);
|
|
|
+ ath10k_pci_reg_write32(ar, PCIE_SOC_WAKE_ADDRESS, PCIE_SOC_WAKE_RESET);
|
|
|
}
|
|
|
|
|
|
static void ath10k_pci_dump_features(struct ath10k_pci *ar_pci)
|
|
@@ -2269,9 +2376,6 @@ static void ath10k_pci_dump_features(struct ath10k_pci *ar_pci)
|
|
|
case ATH10K_PCI_FEATURE_MSI_X:
|
|
|
ath10k_dbg(ATH10K_DBG_PCI, "device supports MSI-X\n");
|
|
|
break;
|
|
|
- case ATH10K_PCI_FEATURE_HW_1_0_WORKAROUND:
|
|
|
- ath10k_dbg(ATH10K_DBG_PCI, "QCA988X_1.0 workaround enabled\n");
|
|
|
- break;
|
|
|
case ATH10K_PCI_FEATURE_SOC_POWER_SAVE:
|
|
|
ath10k_dbg(ATH10K_DBG_PCI, "QCA98XX SoC power save enabled\n");
|
|
|
break;
|
|
@@ -2286,7 +2390,7 @@ static int ath10k_pci_probe(struct pci_dev *pdev,
|
|
|
int ret = 0;
|
|
|
struct ath10k *ar;
|
|
|
struct ath10k_pci *ar_pci;
|
|
|
- u32 lcr_val;
|
|
|
+ u32 lcr_val, chip_id;
|
|
|
|
|
|
ath10k_dbg(ATH10K_DBG_PCI, "%s\n", __func__);
|
|
|
|
|
@@ -2298,9 +2402,6 @@ static int ath10k_pci_probe(struct pci_dev *pdev,
|
|
|
ar_pci->dev = &pdev->dev;
|
|
|
|
|
|
switch (pci_dev->device) {
|
|
|
- case QCA988X_1_0_DEVICE_ID:
|
|
|
- set_bit(ATH10K_PCI_FEATURE_HW_1_0_WORKAROUND, ar_pci->features);
|
|
|
- break;
|
|
|
case QCA988X_2_0_DEVICE_ID:
|
|
|
set_bit(ATH10K_PCI_FEATURE_MSI_X, ar_pci->features);
|
|
|
break;
|
|
@@ -2322,10 +2423,6 @@ static int ath10k_pci_probe(struct pci_dev *pdev,
|
|
|
goto err_ar_pci;
|
|
|
}
|
|
|
|
|
|
- /* Enable QCA988X_1.0 HW workarounds */
|
|
|
- if (test_bit(ATH10K_PCI_FEATURE_HW_1_0_WORKAROUND, ar_pci->features))
|
|
|
- spin_lock_init(&ar_pci->hw_v1_workaround_lock);
|
|
|
-
|
|
|
ar_pci->ar = ar;
|
|
|
ar_pci->fw_indicator_address = FW_INDICATOR_ADDRESS;
|
|
|
atomic_set(&ar_pci->keep_awake_count, 0);
|
|
@@ -2395,9 +2492,18 @@ static int ath10k_pci_probe(struct pci_dev *pdev,
|
|
|
|
|
|
spin_lock_init(&ar_pci->ce_lock);
|
|
|
|
|
|
- ar_pci->cacheline_sz = dma_get_cache_alignment();
|
|
|
+ ret = ath10k_do_pci_wake(ar);
|
|
|
+ if (ret) {
|
|
|
+ ath10k_err("Failed to get chip id: %d\n", ret);
|
|
|
+ return ret;
|
|
|
+ }
|
|
|
+
|
|
|
+ chip_id = ath10k_pci_read32(ar,
|
|
|
+ RTC_SOC_BASE_ADDRESS + SOC_CHIP_ID_ADDRESS);
|
|
|
+
|
|
|
+ ath10k_do_pci_sleep(ar);
|
|
|
|
|
|
- ret = ath10k_core_register(ar);
|
|
|
+ ret = ath10k_core_register(ar, chip_id);
|
|
|
if (ret) {
|
|
|
ath10k_err("could not register driver core (%d)\n", ret);
|
|
|
goto err_iomap;
|
|
@@ -2483,9 +2589,6 @@ module_exit(ath10k_pci_exit);
|
|
|
MODULE_AUTHOR("Qualcomm Atheros");
|
|
|
MODULE_DESCRIPTION("Driver support for Atheros QCA988X PCIe devices");
|
|
|
MODULE_LICENSE("Dual BSD/GPL");
|
|
|
-MODULE_FIRMWARE(QCA988X_HW_1_0_FW_DIR "/" QCA988X_HW_1_0_FW_FILE);
|
|
|
-MODULE_FIRMWARE(QCA988X_HW_1_0_FW_DIR "/" QCA988X_HW_1_0_OTP_FILE);
|
|
|
-MODULE_FIRMWARE(QCA988X_HW_1_0_FW_DIR "/" QCA988X_HW_1_0_BOARD_DATA_FILE);
|
|
|
MODULE_FIRMWARE(QCA988X_HW_2_0_FW_DIR "/" QCA988X_HW_2_0_FW_FILE);
|
|
|
MODULE_FIRMWARE(QCA988X_HW_2_0_FW_DIR "/" QCA988X_HW_2_0_OTP_FILE);
|
|
|
MODULE_FIRMWARE(QCA988X_HW_2_0_FW_DIR "/" QCA988X_HW_2_0_BOARD_DATA_FILE);
|