|
@@ -106,6 +106,8 @@ static int ath10k_pci_bmi_wait(struct ath10k_ce_pipe *tx_pipe,
|
|
|
static int ath10k_pci_qca99x0_chip_reset(struct ath10k *ar);
|
|
|
static void ath10k_pci_htc_tx_cb(struct ath10k_ce_pipe *ce_state);
|
|
|
static void ath10k_pci_htc_rx_cb(struct ath10k_ce_pipe *ce_state);
|
|
|
+static void ath10k_pci_htt_tx_cb(struct ath10k_ce_pipe *ce_state);
|
|
|
+static void ath10k_pci_htt_rx_cb(struct ath10k_ce_pipe *ce_state);
|
|
|
|
|
|
static const struct ce_attr host_ce_config_wlan[] = {
|
|
|
/* CE0: host->target HTC control and raw streams */
|
|
@@ -150,15 +152,16 @@ static const struct ce_attr host_ce_config_wlan[] = {
|
|
|
.src_nentries = CE_HTT_H2T_MSG_SRC_NENTRIES,
|
|
|
.src_sz_max = 256,
|
|
|
.dest_nentries = 0,
|
|
|
- .send_cb = ath10k_pci_htc_tx_cb,
|
|
|
+ .send_cb = ath10k_pci_htt_tx_cb,
|
|
|
},
|
|
|
|
|
|
- /* CE5: unused */
|
|
|
+ /* CE5: target->host HTT (HIF->HTT) */
|
|
|
{
|
|
|
.flags = CE_ATTR_FLAGS,
|
|
|
.src_nentries = 0,
|
|
|
- .src_sz_max = 0,
|
|
|
- .dest_nentries = 0,
|
|
|
+ .src_sz_max = 512,
|
|
|
+ .dest_nentries = 512,
|
|
|
+ .recv_cb = ath10k_pci_htt_rx_cb,
|
|
|
},
|
|
|
|
|
|
/* CE6: target autonomous hif_memcpy */
|
|
@@ -264,12 +267,12 @@ static const struct ce_pipe_config target_ce_config_wlan[] = {
|
|
|
|
|
|
/* NB: 50% of src nentries, since tx has 2 frags */
|
|
|
|
|
|
- /* CE5: unused */
|
|
|
+ /* CE5: target->host HTT (HIF->HTT) */
|
|
|
{
|
|
|
.pipenum = __cpu_to_le32(5),
|
|
|
- .pipedir = __cpu_to_le32(PIPEDIR_OUT),
|
|
|
+ .pipedir = __cpu_to_le32(PIPEDIR_IN),
|
|
|
.nentries = __cpu_to_le32(32),
|
|
|
- .nbytes_max = __cpu_to_le32(2048),
|
|
|
+ .nbytes_max = __cpu_to_le32(512),
|
|
|
.flags = __cpu_to_le32(CE_ATTR_FLAGS),
|
|
|
.reserved = __cpu_to_le32(0),
|
|
|
},
|
|
@@ -403,7 +406,7 @@ static const struct service_to_pipe target_service_to_ce_map_wlan[] = {
|
|
|
{
|
|
|
__cpu_to_le32(ATH10K_HTC_SVC_ID_HTT_DATA_MSG),
|
|
|
__cpu_to_le32(PIPEDIR_IN), /* in = DL = target -> host */
|
|
|
- __cpu_to_le32(1),
|
|
|
+ __cpu_to_le32(5),
|
|
|
},
|
|
|
|
|
|
/* (Additions here) */
|
|
@@ -1125,8 +1128,9 @@ static void ath10k_pci_htc_tx_cb(struct ath10k_ce_pipe *ce_state)
|
|
|
ath10k_htc_tx_completion_handler(ar, skb);
|
|
|
}
|
|
|
|
|
|
-/* Called by lower (CE) layer when data is received from the Target. */
|
|
|
-static void ath10k_pci_htc_rx_cb(struct ath10k_ce_pipe *ce_state)
|
|
|
+static void ath10k_pci_process_rx_cb(struct ath10k_ce_pipe *ce_state,
|
|
|
+ void (*callback)(struct ath10k *ar,
|
|
|
+ struct sk_buff *skb))
|
|
|
{
|
|
|
struct ath10k *ar = ce_state->ar;
|
|
|
struct ath10k_pci *ar_pci = ath10k_pci_priv(ar);
|
|
@@ -1165,12 +1169,56 @@ static void ath10k_pci_htc_rx_cb(struct ath10k_ce_pipe *ce_state)
|
|
|
ath10k_dbg_dump(ar, ATH10K_DBG_PCI_DUMP, NULL, "pci rx: ",
|
|
|
skb->data, skb->len);
|
|
|
|
|
|
- ath10k_htc_rx_completion_handler(ar, skb);
|
|
|
+ callback(ar, skb);
|
|
|
}
|
|
|
|
|
|
ath10k_pci_rx_post_pipe(pipe_info);
|
|
|
}
|
|
|
|
|
|
+/* Called by lower (CE) layer when data is received from the Target. */
|
|
|
+static void ath10k_pci_htc_rx_cb(struct ath10k_ce_pipe *ce_state)
|
|
|
+{
|
|
|
+ ath10k_pci_process_rx_cb(ce_state, ath10k_htc_rx_completion_handler);
|
|
|
+}
|
|
|
+
|
|
|
+/* Called by lower (CE) layer when a send to HTT Target completes. */
|
|
|
+static void ath10k_pci_htt_tx_cb(struct ath10k_ce_pipe *ce_state)
|
|
|
+{
|
|
|
+ struct ath10k *ar = ce_state->ar;
|
|
|
+ struct sk_buff *skb;
|
|
|
+ u32 ce_data;
|
|
|
+ unsigned int nbytes;
|
|
|
+ unsigned int transfer_id;
|
|
|
+
|
|
|
+ while (ath10k_ce_completed_send_next(ce_state, (void **)&skb, &ce_data,
|
|
|
+ &nbytes, &transfer_id) == 0) {
|
|
|
+ /* no need to call tx completion for NULL pointers */
|
|
|
+ if (!skb)
|
|
|
+ continue;
|
|
|
+
|
|
|
+ dma_unmap_single(ar->dev, ATH10K_SKB_CB(skb)->paddr,
|
|
|
+ skb->len, DMA_TO_DEVICE);
|
|
|
+ ath10k_htt_hif_tx_complete(ar, skb);
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+static void ath10k_pci_htt_rx_deliver(struct ath10k *ar, struct sk_buff *skb)
|
|
|
+{
|
|
|
+ skb_pull(skb, sizeof(struct ath10k_htc_hdr));
|
|
|
+ ath10k_htt_t2h_msg_handler(ar, skb);
|
|
|
+}
|
|
|
+
|
|
|
+/* Called by lower (CE) layer when HTT data is received from the Target. */
|
|
|
+static void ath10k_pci_htt_rx_cb(struct ath10k_ce_pipe *ce_state)
|
|
|
+{
|
|
|
+ /* CE4 polling needs to be done whenever CE pipe which transports
|
|
|
+ * HTT Rx (target->host) is processed.
|
|
|
+ */
|
|
|
+ ath10k_ce_per_engine_service(ce_state->ar, 4);
|
|
|
+
|
|
|
+ ath10k_pci_process_rx_cb(ce_state, ath10k_pci_htt_rx_deliver);
|
|
|
+}
|
|
|
+
|
|
|
static int ath10k_pci_hif_tx_sg(struct ath10k *ar, u8 pipe_id,
|
|
|
struct ath10k_hif_sg_item *items, int n_items)
|
|
|
{
|