diff --git a/hif/inc/hif.h b/hif/inc/hif.h index 58e4c2ad7d40..5c8383fe10b7 100644 --- a/hif/inc/hif.h +++ b/hif/inc/hif.h @@ -407,6 +407,33 @@ enum hif_target_status { #define HIF_DATA_ATTR_SET_ENABLE_11H(attr, v) \ (attr |= (v & 0x01) << 30) +struct hif_ul_pipe_info { + unsigned int nentries; + unsigned int nentries_mask; + unsigned int sw_index; + unsigned int write_index; /* cached copy */ + unsigned int hw_index; /* cached copy */ + void *base_addr_owner_space; /* Host address space */ + qdf_dma_addr_t base_addr_CE_space; /* CE address space */ +}; + +struct hif_dl_pipe_info { + unsigned int nentries; + unsigned int nentries_mask; + unsigned int sw_index; + unsigned int write_index; /* cached copy */ + unsigned int hw_index; /* cached copy */ + void *base_addr_owner_space; /* Host address space */ + qdf_dma_addr_t base_addr_CE_space; /* CE address space */ +}; + +struct hif_pipe_addl_info { + uint32_t pci_mem; + uint32_t ctrl_addr; + struct hif_ul_pipe_info ul_pipe; + struct hif_dl_pipe_info dl_pipe; +}; + struct hif_bus_id; typedef struct hif_bus_id hif_bus_id; @@ -560,6 +587,14 @@ int hif_send_fast(struct hif_opaque_softc *osc, qdf_nbuf_t *nbuf_arr, uint32_t void hif_pkt_dl_len_set(void *hif_sc, unsigned int pkt_download_len); void hif_ce_war_disable(void); void hif_ce_war_enable(void); +void hif_disable_interrupt(struct hif_opaque_softc *osc, uint32_t pipe_num); +#ifdef QCA_NSS_WIFI_OFFLOAD_SUPPORT +struct hif_pipe_addl_info *hif_get_addl_pipe_info(struct hif_opaque_softc *osc, + struct hif_pipe_addl_info *hif_info, uint32_t pipe_number); +uint32_t hif_set_nss_wifiol_mode(struct hif_opaque_softc *osc, + uint32_t pipe_num); +int32_t hif_get_nss_wifiol_bypass_nw_process(struct hif_opaque_softc *osc); +#endif #ifdef __cplusplus } diff --git a/hif/src/ce/ce_main.c b/hif/src/ce/ce_main.c index 95b07423f73a..0e7485a76f17 100644 --- a/hif/src/ce/ce_main.c +++ b/hif/src/ce/ce_main.c @@ -967,10 +967,12 @@ ce_h2t_tx_ce_cleanup(struct CE_handle *ce_hdl) struct CE_ring_state *src_ring = ce_state->src_ring; struct hif_softc *sc = ce_state->scn; uint32_t sw_index, write_index; + if (hif_is_nss_wifi_enabled(sc)) + return; if (sc->fastpath_mode_on && ce_state->htt_tx_data) { - HIF_INFO("%s %d Fastpath mode ON, Cleaning up HTT Tx CE\n", - __func__, __LINE__); + HIF_INFO("%s %d Fastpath mode ON, Cleaning up HTT Tx CE", + __func__, __LINE__); sw_index = src_ring->sw_index; write_index = src_ring->sw_index; @@ -1621,12 +1623,19 @@ static int hif_post_recv_buffers(struct hif_softc *scn) { struct HIF_CE_state *hif_state = HIF_GET_CE_STATE(scn); int pipe_num, rv = 0; + struct CE_state *ce_state; A_TARGET_ACCESS_LIKELY(scn); for (pipe_num = 0; pipe_num < scn->ce_count; pipe_num++) { struct HIF_CE_pipe_info *pipe_info; - + ce_state = scn->ce_id_to_state[pipe_num]; pipe_info = &hif_state->pipe_info[pipe_num]; + + if (hif_is_nss_wifi_enabled(scn) && + ce_state && (ce_state->htt_rx_data)) { + continue; + } + if (hif_post_recv_buffers_for_pipe(pipe_info)) { rv = 1; goto done; @@ -1760,10 +1769,18 @@ void hif_buffer_cleanup(struct HIF_CE_state *hif_state) { int pipe_num; struct hif_softc *scn = HIF_GET_SOFTC(hif_state); + struct CE_state *ce_state; for (pipe_num = 0; pipe_num < scn->ce_count; pipe_num++) { struct HIF_CE_pipe_info *pipe_info; + ce_state = scn->ce_id_to_state[pipe_num]; + if (hif_is_nss_wifi_enabled(scn) && ce_state && + ((ce_state->htt_tx_data) || + (ce_state->htt_rx_data))) { + continue; + } + pipe_info = &hif_state->pipe_info[pipe_num]; hif_recv_buffer_cleanup_on_pipe(pipe_info); hif_send_buffer_cleanup_on_pipe(pipe_info); @@ -2053,6 +2070,7 @@ int hif_config_ce(struct hif_softc *scn) struct hif_opaque_softc *hif_hdl = GET_HIF_OPAQUE_HDL(scn); struct HIF_CE_pipe_info *pipe_info; int pipe_num; + struct CE_state *ce_state; #ifdef ADRASTEA_SHADOW_REGISTERS int i; #endif @@ -2070,12 +2088,12 @@ int hif_config_ce(struct hif_softc *scn) scn->ce_count = HOST_CE_COUNT; for (pipe_num = 0; pipe_num < scn->ce_count; pipe_num++) { struct CE_attr *attr; - pipe_info = &hif_state->pipe_info[pipe_num]; pipe_info->pipe_num = pipe_num; pipe_info->HIF_CE_state = hif_state; attr = &host_ce_config[pipe_num]; pipe_info->ce_hdl = ce_init(scn, pipe_num, attr); + ce_state = scn->ce_id_to_state[pipe_num]; QDF_ASSERT(pipe_info->ce_hdl != NULL); if (pipe_info->ce_hdl == NULL) { rv = QDF_STATUS_E_FAILURE; @@ -2090,6 +2108,10 @@ int hif_config_ce(struct hif_softc *scn) continue; } + if (hif_is_nss_wifi_enabled(scn) && ce_state && + (ce_state->htt_rx_data)) + continue; + pipe_info->buf_sz = (qdf_size_t) (attr->src_sz_max); qdf_spinlock_create(&pipe_info->recv_bufs_needed_lock); if (attr->dest_nentries > 0) { @@ -2675,3 +2697,68 @@ int hif_dump_ce_registers(struct hif_softc *scn) } return 0; } + +#ifdef QCA_NSS_WIFI_OFFLOAD_SUPPORT +struct hif_pipe_addl_info *hif_get_addl_pipe_info(struct hif_opaque_softc *osc, + struct hif_pipe_addl_info *hif_info, uint32_t pipe) +{ + struct hif_softc *scn = HIF_GET_SOFTC(osc); + struct hif_pci_softc *sc = HIF_GET_PCI_SOFTC(scn); + struct HIF_CE_state *hif_state = HIF_GET_CE_STATE(osc); + struct HIF_CE_pipe_info *pipe_info = &(hif_state->pipe_info[pipe]); + struct CE_handle *ce_hdl = pipe_info->ce_hdl; + struct CE_state *ce_state = (struct CE_state *)ce_hdl; + struct CE_ring_state *src_ring = ce_state->src_ring; + struct CE_ring_state *dest_ring = ce_state->dest_ring; + + if (src_ring) { + hif_info->ul_pipe.nentries = src_ring->nentries; + hif_info->ul_pipe.nentries_mask = src_ring->nentries_mask; + hif_info->ul_pipe.sw_index = src_ring->sw_index; + hif_info->ul_pipe.write_index = src_ring->write_index; + hif_info->ul_pipe.hw_index = src_ring->hw_index; + hif_info->ul_pipe.base_addr_CE_space = + src_ring->base_addr_CE_space; + hif_info->ul_pipe.base_addr_owner_space = + src_ring->base_addr_owner_space; + } + + + if (dest_ring) { + hif_info->dl_pipe.nentries = dest_ring->nentries; + hif_info->dl_pipe.nentries_mask = dest_ring->nentries_mask; + hif_info->dl_pipe.sw_index = dest_ring->sw_index; + hif_info->dl_pipe.write_index = dest_ring->write_index; + hif_info->dl_pipe.hw_index = dest_ring->hw_index; + hif_info->dl_pipe.base_addr_CE_space = + dest_ring->base_addr_CE_space; + hif_info->dl_pipe.base_addr_owner_space = + dest_ring->base_addr_owner_space; + } + + hif_info->pci_mem = pci_resource_start(sc->pdev, 0); + hif_info->ctrl_addr = ce_state->ctrl_addr; + + return hif_info; +} + +uint32_t hif_set_nss_wifiol_mode(struct hif_opaque_softc *osc, uint32_t mode) +{ + struct hif_softc *scn = HIF_GET_SOFTC(osc); + + scn->nss_wifi_ol_mode = mode; + return 0; +} + +#endif + +void hif_disable_interrupt(struct hif_opaque_softc *osc, uint32_t pipe_num) +{ + struct hif_softc *scn = HIF_GET_SOFTC(osc); + struct CE_state *CE_state = scn->ce_id_to_state[pipe_num]; + uint32_t ctrl_addr = CE_state->ctrl_addr; + + Q_TARGET_ACCESS_BEGIN(scn); + CE_COPY_COMPLETE_INTR_DISABLE(scn, ctrl_addr); + Q_TARGET_ACCESS_END(scn); +} diff --git a/hif/src/ce/ce_service.c b/hif/src/ce/ce_service.c index 98ac3965f2d0..60f29f1f694e 100644 --- a/hif/src/ce/ce_service.c +++ b/hif/src/ce/ce_service.c @@ -1764,6 +1764,9 @@ int ce_per_engine_service(struct hif_softc *scn, unsigned int CE_id) uint32_t toeplitz_hash_result; uint32_t mode = hif_get_conparam(scn); + if (hif_is_nss_wifi_enabled(scn) && (CE_state->htt_rx_data)) + return CE_state->receive_count; + if (Q_TARGET_ACCESS_BEGIN(scn) < 0) { HIF_ERROR("[premature rc=0]\n"); return 0; /* no work done */ diff --git a/hif/src/hif_main.h b/hif/src/hif_main.h index 4f7c297e290c..db6fd77808ef 100644 --- a/hif/src/hif_main.h +++ b/hif/src/hif_main.h @@ -140,8 +140,23 @@ struct hif_softc { #endif /* FEATURE_NAPI */ struct hif_driver_state_callbacks callbacks; uint32_t hif_con_param; +#ifdef QCA_NSS_WIFI_OFFLOAD_SUPPORT + uint32_t nss_wifi_ol_mode; +#endif }; +#ifdef QCA_NSS_WIFI_OFFLOAD_SUPPORT +static inline bool hif_is_nss_wifi_enabled(struct hif_softc *sc) +{ + return !!(sc->nss_wifi_ol_mode); +} +#else +static inline bool hif_is_nss_wifi_enabled(struct hif_softc *sc) +{ + return false; +} +#endif + A_target_id_t hif_get_target_id(struct hif_softc *scn); void hif_dump_pipe_debug_count(struct hif_softc *scn);