|
@@ -3585,6 +3585,89 @@ QDF_STATUS hif_post_recv_buffers_for_pipe(struct HIF_CE_pipe_info *pipe_info)
|
|
|
return QDF_STATUS_SUCCESS;
|
|
|
}
|
|
|
|
|
|
+#ifdef FEATURE_DIRECT_LINK
|
|
|
+static QDF_STATUS
|
|
|
+hif_alloc_pages_for_direct_link_recv_pipe(struct HIF_CE_state *hif_ce_state,
|
|
|
+ int pipe_num)
|
|
|
+{
|
|
|
+ struct hif_softc *scn = HIF_GET_SOFTC(hif_ce_state);
|
|
|
+ struct service_to_pipe *tgt_svc_cfg;
|
|
|
+ struct HIF_CE_pipe_info *pipe_info;
|
|
|
+ int32_t recv_bufs_needed;
|
|
|
+ qdf_dma_addr_t dma_addr;
|
|
|
+ uint16_t num_elem_per_page;
|
|
|
+ uint16_t i;
|
|
|
+ bool is_found = false;
|
|
|
+
|
|
|
+ tgt_svc_cfg = hif_ce_state->tgt_svc_map;
|
|
|
+
|
|
|
+ for (i = 0; i < hif_ce_state->sz_tgt_svc_map; i++) {
|
|
|
+ if (tgt_svc_cfg[i].service_id != LPASS_DATA_MSG_SVC ||
|
|
|
+ tgt_svc_cfg[i].pipedir != PIPEDIR_IN ||
|
|
|
+ tgt_svc_cfg[i].pipenum != pipe_num)
|
|
|
+ continue;
|
|
|
+
|
|
|
+ pipe_info = &hif_ce_state->pipe_info[pipe_num];
|
|
|
+ recv_bufs_needed = atomic_read(&pipe_info->recv_bufs_needed);
|
|
|
+
|
|
|
+ if (!pipe_info->buf_sz || !recv_bufs_needed)
|
|
|
+ continue;
|
|
|
+
|
|
|
+ is_found = true;
|
|
|
+ break;
|
|
|
+ }
|
|
|
+
|
|
|
+ if (!is_found)
|
|
|
+ return QDF_STATUS_E_NOSUPPORT;
|
|
|
+
|
|
|
+ scn->dl_recv_pipe_num = pipe_num;
|
|
|
+
|
|
|
+ hif_prealloc_get_multi_pages(scn, QDF_DP_RX_DIRECT_LINK_CE_BUF_TYPE,
|
|
|
+ pipe_info->buf_sz, recv_bufs_needed,
|
|
|
+ &scn->dl_recv_pages, false);
|
|
|
+ if (!scn->dl_recv_pages.num_pages)
|
|
|
+ return QDF_STATUS_E_NOMEM;
|
|
|
+
|
|
|
+ num_elem_per_page = scn->dl_recv_pages.num_element_per_page;
|
|
|
+ for (i = 0; i < recv_bufs_needed; i++) {
|
|
|
+ dma_addr = scn->dl_recv_pages.dma_pages[i / num_elem_per_page].page_p_addr;
|
|
|
+ dma_addr += (i % num_elem_per_page) * pipe_info->buf_sz;
|
|
|
+ ce_recv_buf_enqueue(pipe_info->ce_hdl, NULL, dma_addr);
|
|
|
+ }
|
|
|
+
|
|
|
+ return QDF_STATUS_SUCCESS;
|
|
|
+}
|
|
|
+
|
|
|
+static QDF_STATUS
|
|
|
+hif_free_pages_for_direct_link_recv_pipe(struct HIF_CE_state *hif_ce_state,
|
|
|
+ int pipe_num)
|
|
|
+{
|
|
|
+ struct hif_softc *scn = HIF_GET_SOFTC(hif_ce_state);
|
|
|
+
|
|
|
+ if (pipe_num != scn->dl_recv_pipe_num)
|
|
|
+ return QDF_STATUS_E_NOSUPPORT;
|
|
|
+
|
|
|
+ hif_prealloc_put_multi_pages(scn, QDF_DP_RX_DIRECT_LINK_CE_BUF_TYPE,
|
|
|
+ &scn->dl_recv_pages, false);
|
|
|
+
|
|
|
+ return QDF_STATUS_SUCCESS;
|
|
|
+}
|
|
|
+#else
|
|
|
+static inline QDF_STATUS
|
|
|
+hif_alloc_pages_for_direct_link_recv_pipe(struct HIF_CE_state *hif_ce_state,
|
|
|
+ int pipe_num)
|
|
|
+{
|
|
|
+ return QDF_STATUS_E_NOSUPPORT;
|
|
|
+}
|
|
|
+
|
|
|
+static inline QDF_STATUS
|
|
|
+hif_free_pages_for_direct_link_recv_pipe(struct HIF_CE_state *hif_ce_state,
|
|
|
+ int pipe_num)
|
|
|
+{
|
|
|
+ return QDF_STATUS_E_NOSUPPORT;
|
|
|
+}
|
|
|
+#endif
|
|
|
+
|
|
|
/*
|
|
|
* Try to post all desired receive buffers for all pipes.
|
|
|
* Returns 0 for non fastpath rx copy engine as
|
|
@@ -3617,6 +3700,12 @@ static QDF_STATUS hif_post_recv_buffers(struct hif_softc *scn)
|
|
|
ce_state && (ce_state->htt_rx_data))
|
|
|
continue;
|
|
|
|
|
|
+ qdf_status =
|
|
|
+ hif_alloc_pages_for_direct_link_recv_pipe(hif_state,
|
|
|
+ pipe_num);
|
|
|
+ if (QDF_IS_STATUS_SUCCESS(qdf_status))
|
|
|
+ continue;
|
|
|
+
|
|
|
qdf_status = hif_post_recv_buffers_for_pipe(pipe_info);
|
|
|
if (!QDF_IS_STATUS_SUCCESS(qdf_status) && ce_state &&
|
|
|
ce_state->htt_rx_data &&
|
|
@@ -3667,6 +3756,7 @@ static void hif_recv_buffer_cleanup_on_pipe(struct HIF_CE_pipe_info *pipe_info)
|
|
|
qdf_nbuf_t netbuf;
|
|
|
qdf_dma_addr_t CE_data;
|
|
|
void *per_CE_context;
|
|
|
+ QDF_STATUS status;
|
|
|
|
|
|
buf_sz = pipe_info->buf_sz;
|
|
|
/* Unused Copy Engine */
|
|
@@ -3683,6 +3773,12 @@ static void hif_recv_buffer_cleanup_on_pipe(struct HIF_CE_pipe_info *pipe_info)
|
|
|
|
|
|
if (!scn->qdf_dev)
|
|
|
return;
|
|
|
+
|
|
|
+ status = hif_free_pages_for_direct_link_recv_pipe(hif_state,
|
|
|
+ pipe_info->pipe_num);
|
|
|
+ if (QDF_IS_STATUS_SUCCESS(status))
|
|
|
+ return;
|
|
|
+
|
|
|
while (ce_revoke_recv_next
|
|
|
(ce_hdl, &per_CE_context, (void **)&netbuf,
|
|
|
&CE_data) == QDF_STATUS_SUCCESS) {
|
|
@@ -5635,6 +5731,7 @@ void hif_log_ce_info(struct hif_softc *scn, uint8_t *data,
|
|
|
qdf_mem_copy(data + *offset, &info, size);
|
|
|
*offset = *offset + size;
|
|
|
}
|
|
|
+#endif
|
|
|
|
|
|
#ifdef FEATURE_DIRECT_LINK
|
|
|
QDF_STATUS
|
|
@@ -5687,4 +5784,3 @@ hif_get_direct_link_ce_srng_info(struct hif_opaque_softc *scn,
|
|
|
return QDF_STATUS_E_NOSUPPORT;
|
|
|
}
|
|
|
#endif
|
|
|
-#endif
|