diff --git a/dp/wifi3.0/dp_htt.c b/dp/wifi3.0/dp_htt.c index e5688f7e5b..8ccf3f3033 100644 --- a/dp/wifi3.0/dp_htt.c +++ b/dp/wifi3.0/dp_htt.c @@ -549,6 +549,13 @@ int htt_srng_setup(struct htt_soc *soc, int mac_id, (lmac_id * HAL_MAX_RINGS_PER_LMAC))) { htt_ring_id = HTT_HOST2_TO_FW_RXBUF_RING; htt_ring_type = HTT_SW_TO_SW_RING; +#ifdef IPA_WDI3_RX_TWO_PIPES + } else if (srng_params.ring_id == + (HAL_SRNG_WMAC1_SW2RXDMA0_BUF3 + + (lmac_id * HAL_MAX_RINGS_PER_LMAC))) { + htt_ring_id = HTT_HOST3_TO_FW_RXBUF_RING; + htt_ring_type = HTT_SW_TO_SW_RING; +#endif #endif #else if (srng_params.ring_id == diff --git a/dp/wifi3.0/dp_ipa.c b/dp/wifi3.0/dp_ipa.c index 3034ce80cf..85db8858a0 100644 --- a/dp/wifi3.0/dp_ipa.c +++ b/dp/wifi3.0/dp_ipa.c @@ -1165,6 +1165,33 @@ static void dp_rx_ipa_uc_detach(struct dp_soc *soc, struct dp_pdev *pdev) qdf_mem_free_sgtable(&ipa_res->rx_refill_ring.sgtable); } +/* + * dp_rx_alt_ipa_uc_detach - free autonomy RX resources + * @soc: data path instance + * @pdev: core txrx pdev context + * + * This function will detach DP RX into main device context + * will free DP Rx resources. + * + * Return: none + */ +#ifdef IPA_WDI3_RX_TWO_PIPES +static void dp_rx_alt_ipa_uc_detach(struct dp_soc *soc, struct dp_pdev *pdev) +{ + struct dp_ipa_resources *ipa_res = &pdev->ipa_resource; + + if (!wlan_ipa_is_vlan_enabled()) + return; + + qdf_mem_free_sgtable(&ipa_res->rx_alt_rdy_ring.sgtable); + qdf_mem_free_sgtable(&ipa_res->rx_alt_refill_ring.sgtable); +} +#else +static inline +void dp_rx_alt_ipa_uc_detach(struct dp_soc *soc, struct dp_pdev *pdev) +{ } +#endif + int dp_ipa_uc_detach(struct dp_soc *soc, struct dp_pdev *pdev) { if (!wlan_cfg_is_ipa_enabled(soc->wlan_cfg_ctx)) @@ -1179,6 +1206,9 @@ int dp_ipa_uc_detach(struct dp_soc *soc, struct dp_pdev *pdev) /* RX resource detach */ dp_rx_ipa_uc_detach(soc, pdev); + /* Cleanup 2nd RX pipe resources */ + dp_rx_alt_ipa_uc_detach(soc, pdev); + return QDF_STATUS_SUCCESS; /* success */ } @@ -1356,6 +1386,85 @@ int dp_ipa_uc_attach(struct dp_soc *soc, struct dp_pdev *pdev) return QDF_STATUS_SUCCESS; /* success */ } +#ifdef IPA_WDI3_RX_TWO_PIPES +/* + * dp_ipa_rx_alt_ring_resource_setup() - setup IPA 2nd RX ring resources + * @soc: data path SoC handle + * @pdev: data path pdev handle + * + * Return: none + */ +static +void dp_ipa_rx_alt_ring_resource_setup(struct dp_soc *soc, struct dp_pdev *pdev) +{ + struct hal_soc *hal_soc = (struct hal_soc *)soc->hal_soc; + struct hal_srng *hal_srng; + struct hal_srng_params srng_params; + unsigned long addr_offset, dev_base_paddr; + qdf_dma_addr_t hp_addr; + + if (!wlan_ipa_is_vlan_enabled()) + return; + + dev_base_paddr = + (unsigned long) + ((struct hif_softc *)(hal_soc->hif_handle))->mem_pa; + + /* IPA REO_DEST Ring - HAL_SRNG_REO2SW3 */ + hal_srng = (struct hal_srng *) + soc->reo_dest_ring[IPA_ALT_REO_DEST_RING_IDX].hal_srng; + hal_get_srng_params(hal_soc_to_hal_soc_handle(hal_soc), + hal_srng_to_hal_ring_handle(hal_srng), + &srng_params); + + soc->ipa_uc_rx_rsc_alt.ipa_reo_ring_base_paddr = + srng_params.ring_base_paddr; + soc->ipa_uc_rx_rsc_alt.ipa_reo_ring_base_vaddr = + srng_params.ring_base_vaddr; + soc->ipa_uc_rx_rsc_alt.ipa_reo_ring_size = + (srng_params.num_entries * srng_params.entry_size) << 2; + addr_offset = (unsigned long)(hal_srng->u.dst_ring.tp_addr) - + (unsigned long)(hal_soc->dev_base_addr); + soc->ipa_uc_rx_rsc_alt.ipa_reo_tp_paddr = + (qdf_dma_addr_t)(addr_offset + dev_base_paddr); + + dp_info("IPA REO_DEST Ring addr_offset=%x, dev_base_paddr=%x, tp_paddr=%x paddr=%pK vaddr=%pK size= %u(%u bytes)", + (unsigned int)addr_offset, + (unsigned int)dev_base_paddr, + (unsigned int)(soc->ipa_uc_rx_rsc_alt.ipa_reo_tp_paddr), + (void *)soc->ipa_uc_rx_rsc_alt.ipa_reo_ring_base_paddr, + (void *)soc->ipa_uc_rx_rsc_alt.ipa_reo_ring_base_vaddr, + srng_params.num_entries, + soc->ipa_uc_rx_rsc_alt.ipa_reo_ring_size); + + hal_srng = (struct hal_srng *) + pdev->rx_refill_buf_ring3.hal_srng; + hal_get_srng_params(hal_soc_to_hal_soc_handle(hal_soc), + hal_srng_to_hal_ring_handle(hal_srng), + &srng_params); + soc->ipa_uc_rx_rsc_alt.ipa_rx_refill_buf_ring_base_paddr = + srng_params.ring_base_paddr; + soc->ipa_uc_rx_rsc_alt.ipa_rx_refill_buf_ring_base_vaddr = + srng_params.ring_base_vaddr; + soc->ipa_uc_rx_rsc_alt.ipa_rx_refill_buf_ring_size = + (srng_params.num_entries * srng_params.entry_size) << 2; + hp_addr = hal_srng_get_hp_addr(hal_soc_to_hal_soc_handle(hal_soc), + hal_srng_to_hal_ring_handle(hal_srng)); + soc->ipa_uc_rx_rsc_alt.ipa_rx_refill_buf_hp_paddr = + qdf_mem_paddr_from_dmaaddr(soc->osdev, hp_addr); + + dp_info("IPA REFILL_BUF Ring hp_paddr=%x paddr=%pK vaddr=%pK size= %u(%u bytes)", + (unsigned int)(soc->ipa_uc_rx_rsc_alt.ipa_rx_refill_buf_hp_paddr), + (void *)soc->ipa_uc_rx_rsc_alt.ipa_rx_refill_buf_ring_base_paddr, + (void *)soc->ipa_uc_rx_rsc_alt.ipa_rx_refill_buf_ring_base_vaddr, + srng_params.num_entries, + soc->ipa_uc_rx_rsc_alt.ipa_rx_refill_buf_ring_size); +} +#else +static inline +void dp_ipa_rx_alt_ring_resource_setup(struct dp_soc *soc, struct dp_pdev *pdev) +{ } +#endif /* * dp_ipa_ring_resource_setup() - setup IPA ring resources * @soc: data path SoC handle @@ -1510,9 +1619,51 @@ int dp_ipa_ring_resource_setup(struct dp_soc *soc, hal_reo_read_write_ctrl_ix(soc->hal_soc, false, &ix0, NULL, NULL, NULL); + dp_ipa_rx_alt_ring_resource_setup(soc, pdev); return 0; } +#ifdef IPA_WDI3_RX_TWO_PIPES +/* + * dp_ipa_rx_alt_ring_get_resource() - get IPA 2nd RX ring resources + * @pdev: data path pdev handle + * + * Return: Success if resourece is found + */ +static QDF_STATUS dp_ipa_rx_alt_ring_get_resource(struct dp_pdev *pdev) +{ + struct dp_soc *soc = pdev->soc; + struct dp_ipa_resources *ipa_res = &pdev->ipa_resource; + + if (!wlan_ipa_is_vlan_enabled()) + return QDF_STATUS_SUCCESS; + + dp_ipa_get_shared_mem_info(soc->osdev, &ipa_res->rx_alt_rdy_ring, + soc->ipa_uc_rx_rsc_alt.ipa_reo_ring_base_vaddr, + soc->ipa_uc_rx_rsc_alt.ipa_reo_ring_base_paddr, + soc->ipa_uc_rx_rsc_alt.ipa_reo_ring_size); + + dp_ipa_get_shared_mem_info( + soc->osdev, &ipa_res->rx_alt_refill_ring, + soc->ipa_uc_rx_rsc_alt.ipa_rx_refill_buf_ring_base_vaddr, + soc->ipa_uc_rx_rsc_alt.ipa_rx_refill_buf_ring_base_paddr, + soc->ipa_uc_rx_rsc_alt.ipa_rx_refill_buf_ring_size); + + if (!qdf_mem_get_dma_addr(soc->osdev, + &ipa_res->rx_alt_rdy_ring.mem_info) || + !qdf_mem_get_dma_addr(soc->osdev, + &ipa_res->rx_alt_refill_ring.mem_info)) + return QDF_STATUS_E_FAILURE; + + return QDF_STATUS_SUCCESS; +} +#else +static inline QDF_STATUS dp_ipa_rx_alt_ring_get_resource(struct dp_pdev *pdev) +{ + return QDF_STATUS_SUCCESS; +} +#endif + QDF_STATUS dp_ipa_get_resource(struct cdp_soc_t *soc_hdl, uint8_t pdev_id) { struct dp_soc *soc = cdp_soc_t_to_dp_soc(soc_hdl); @@ -1564,6 +1715,9 @@ QDF_STATUS dp_ipa_get_resource(struct cdp_soc_t *soc_hdl, uint8_t pdev_id) if (dp_ipa_tx_alt_ring_get_resource(pdev)) return QDF_STATUS_E_FAILURE; + if (dp_ipa_rx_alt_ring_get_resource(pdev)) + return QDF_STATUS_E_FAILURE; + return QDF_STATUS_SUCCESS; } @@ -1574,6 +1728,70 @@ QDF_STATUS dp_ipa_get_resource(struct cdp_soc_t *soc_hdl, uint8_t pdev_id) dp_ipa_set_tx_doorbell_paddr(soc, ipa_res) #endif +#ifdef IPA_WDI3_RX_TWO_PIPES +/* + * dp_ipa_map_rx_alt_ring_doorbell_paddr() - Map 2nd rx ring doorbell paddr + * @pdev: data path pdev handle + * + * Return: none + */ +static void dp_ipa_map_rx_alt_ring_doorbell_paddr(struct dp_pdev *pdev) +{ + struct dp_ipa_resources *ipa_res = &pdev->ipa_resource; + uint32_t rx_ready_doorbell_dmaaddr; + struct dp_soc *soc = pdev->soc; + struct hal_srng *reo_srng = (struct hal_srng *) + soc->reo_dest_ring[IPA_ALT_REO_DEST_RING_IDX].hal_srng; + int ret = 0; + + if (!wlan_ipa_is_vlan_enabled()) + return; + + if (qdf_mem_smmu_s1_enabled(soc->osdev)) { + ret = pld_smmu_map(soc->osdev->dev, + ipa_res->rx_alt_ready_doorbell_paddr, + &rx_ready_doorbell_dmaaddr, + sizeof(uint32_t)); + ipa_res->rx_alt_ready_doorbell_paddr = + rx_ready_doorbell_dmaaddr; + qdf_assert_always(!ret); + } + + hal_srng_dst_set_hp_paddr_confirm(reo_srng, + ipa_res->rx_alt_ready_doorbell_paddr); +} + +/* + * dp_ipa_unmap_rx_alt_ring_doorbell_paddr() - Unmap 2nd rx ring doorbell paddr + * @pdev: data path pdev handle + * + * Return: none + */ +static void dp_ipa_unmap_rx_alt_ring_doorbell_paddr(struct dp_pdev *pdev) +{ + struct dp_ipa_resources *ipa_res = &pdev->ipa_resource; + struct dp_soc *soc = pdev->soc; + int ret = 0; + + if (!wlan_ipa_is_vlan_enabled()) + return; + + if (!qdf_mem_smmu_s1_enabled(soc->osdev)) + return; + + ret = pld_smmu_unmap(soc->osdev->dev, + ipa_res->rx_alt_ready_doorbell_paddr, + sizeof(uint32_t)); + qdf_assert_always(!ret); +} +#else +static inline void dp_ipa_map_rx_alt_ring_doorbell_paddr(struct dp_pdev *pdev) +{ } + +static inline void dp_ipa_unmap_rx_alt_ring_doorbell_paddr(struct dp_pdev *pdev) +{ } +#endif + QDF_STATUS dp_ipa_set_doorbell_paddr(struct cdp_soc_t *soc_hdl, uint8_t pdev_id) { struct dp_soc *soc = cdp_soc_t_to_dp_soc(soc_hdl); @@ -1593,6 +1811,7 @@ QDF_STATUS dp_ipa_set_doorbell_paddr(struct cdp_soc_t *soc_hdl, uint8_t pdev_id) return QDF_STATUS_SUCCESS; dp_ipa_map_ring_doorbell_paddr(pdev); + dp_ipa_map_rx_alt_ring_doorbell_paddr(pdev); DP_IPA_SET_TX_DB_PADDR(soc, ipa_res); @@ -1776,7 +1995,10 @@ QDF_STATUS dp_ipa_enable_autonomy(struct cdp_soc_t *soc_hdl, uint8_t pdev_id) ix_map[0] = REO_REMAP_SW1; ix_map[1] = REO_REMAP_SW4; ix_map[2] = REO_REMAP_SW1; - ix_map[3] = REO_REMAP_SW4; + if (wlan_ipa_is_vlan_enabled()) + ix_map[3] = REO_REMAP_SW3; + else + ix_map[3] = REO_REMAP_SW4; ix_map[4] = REO_REMAP_SW4; ix_map[5] = REO_REMAP_RELEASE; ix_map[6] = REO_REMAP_FW; @@ -2064,6 +2286,208 @@ dp_ipa_wdi_rx_smmu_params(struct dp_soc *soc, soc->rx_pkt_tlv_size + L3_HEADER_PADDING; } +#ifdef IPA_WDI3_RX_TWO_PIPES +/* + * dp_ipa_wdi_rx_alt_pipe_smmu_params() - Setup 2nd rx pipe smmu params + * @soc: data path soc handle + * @ipa_res: ipa resource pointer + * @rx_smmu: smmu pipe info handle + * @over_gsi: flag for IPA offload over gsi + * @hdl: ipa registered handle + * + * Return: none + */ +static void +dp_ipa_wdi_rx_alt_pipe_smmu_params(struct dp_soc *soc, + struct dp_ipa_resources *ipa_res, + qdf_ipa_wdi_pipe_setup_info_smmu_t *rx_smmu, + bool over_gsi, + qdf_ipa_wdi_hdl_t hdl) +{ + if (!wlan_ipa_is_vlan_enabled()) + return; + + if (over_gsi) { + if (hdl == DP_IPA_HDL_FIRST) + QDF_IPA_WDI_SETUP_INFO_SMMU_CLIENT(rx_smmu) = + IPA_CLIENT_WLAN2_PROD1; + else if (hdl == DP_IPA_HDL_SECOND) + QDF_IPA_WDI_SETUP_INFO_SMMU_CLIENT(rx_smmu) = + IPA_CLIENT_WLAN3_PROD1; + } else { + QDF_IPA_WDI_SETUP_INFO_SMMU_CLIENT(rx_smmu) = + IPA_CLIENT_WLAN1_PROD; + } + + qdf_mem_copy(&QDF_IPA_WDI_SETUP_INFO_SMMU_TRANSFER_RING_BASE(rx_smmu), + &ipa_res->rx_alt_rdy_ring.sgtable, + sizeof(sgtable_t)); + QDF_IPA_WDI_SETUP_INFO_SMMU_TRANSFER_RING_SIZE(rx_smmu) = + qdf_mem_get_dma_size(soc->osdev, + &ipa_res->rx_alt_rdy_ring.mem_info); + /* REO Tail Pointer Address */ + QDF_IPA_WDI_SETUP_INFO_SMMU_TRANSFER_RING_DOORBELL_PA(rx_smmu) = + soc->ipa_uc_rx_rsc_alt.ipa_reo_tp_paddr; + QDF_IPA_WDI_SETUP_INFO_SMMU_IS_TXR_RN_DB_PCIE_ADDR(rx_smmu) = true; + + qdf_mem_copy(&QDF_IPA_WDI_SETUP_INFO_SMMU_EVENT_RING_BASE(rx_smmu), + &ipa_res->rx_alt_refill_ring.sgtable, + sizeof(sgtable_t)); + QDF_IPA_WDI_SETUP_INFO_SMMU_EVENT_RING_SIZE(rx_smmu) = + qdf_mem_get_dma_size(soc->osdev, + &ipa_res->rx_alt_refill_ring.mem_info); + + /* FW Head Pointer Address */ + QDF_IPA_WDI_SETUP_INFO_SMMU_EVENT_RING_DOORBELL_PA(rx_smmu) = + soc->ipa_uc_rx_rsc_alt.ipa_rx_refill_buf_hp_paddr; + QDF_IPA_WDI_SETUP_INFO_SMMU_IS_EVT_RN_DB_PCIE_ADDR(rx_smmu) = false; + + QDF_IPA_WDI_SETUP_INFO_SMMU_PKT_OFFSET(rx_smmu) = + soc->rx_pkt_tlv_size + L3_HEADER_PADDING; +} + +/* + * dp_ipa_wdi_rx_alt_pipe_smmu_params() - Setup 2nd rx pipe params + * @soc: data path soc handle + * @ipa_res: ipa resource pointer + * @rx: pipe info handle + * @over_gsi: flag for IPA offload over gsi + * @hdl: ipa registered handle + * + * Return: none + */ +static void dp_ipa_wdi_rx_alt_pipe_params(struct dp_soc *soc, + struct dp_ipa_resources *ipa_res, + qdf_ipa_wdi_pipe_setup_info_t *rx, + bool over_gsi, + qdf_ipa_wdi_hdl_t hdl) +{ + if (!wlan_ipa_is_vlan_enabled()) + return; + + if (over_gsi) { + if (hdl == DP_IPA_HDL_FIRST) + QDF_IPA_WDI_SETUP_INFO_SMMU_CLIENT(rx_smmu) = + IPA_CLIENT_WLAN2_PROD1; + else if (hdl == DP_IPA_HDL_SECOND) + QDF_IPA_WDI_SETUP_INFO_SMMU_CLIENT(rx_smmu) = + IPA_CLIENT_WLAN3_PROD1; + } else { + QDF_IPA_WDI_SETUP_INFO_CLIENT(rx) = + IPA_CLIENT_WLAN1_PROD; + } + + QDF_IPA_WDI_SETUP_INFO_TRANSFER_RING_BASE_PA(rx) = + qdf_mem_get_dma_addr(soc->osdev, + &ipa_res->rx_alt_rdy_ring.mem_info); + QDF_IPA_WDI_SETUP_INFO_TRANSFER_RING_SIZE(rx) = + qdf_mem_get_dma_size(soc->osdev, + &ipa_res->rx_alt_rdy_ring.mem_info); + + /* REO Tail Pointer Address */ + QDF_IPA_WDI_SETUP_INFO_TRANSFER_RING_DOORBELL_PA(rx) = + soc->ipa_uc_rx_rsc_alt.ipa_reo_tp_paddr; + QDF_IPA_WDI_SETUP_INFO_IS_TXR_RN_DB_PCIE_ADDR(rx) = true; + + QDF_IPA_WDI_SETUP_INFO_EVENT_RING_BASE_PA(rx) = + qdf_mem_get_dma_addr(soc->osdev, + &ipa_res->rx_alt_refill_ring.mem_info); + QDF_IPA_WDI_SETUP_INFO_EVENT_RING_SIZE(rx) = + qdf_mem_get_dma_size(soc->osdev, + &ipa_res->rx_alt_refill_ring.mem_info); + + /* FW Head Pointer Address */ + QDF_IPA_WDI_SETUP_INFO_EVENT_RING_DOORBELL_PA(rx) = + soc->ipa_uc_rx_rsc_alt.ipa_rx_refill_buf_hp_paddr; + QDF_IPA_WDI_SETUP_INFO_IS_EVT_RN_DB_PCIE_ADDR(rx) = false; + + QDF_IPA_WDI_SETUP_INFO_PKT_OFFSET(rx) = + soc->rx_pkt_tlv_size + L3_HEADER_PADDING; +} + +/* + * dp_ipa_setup_rx_alt_pipe() - Setup 2nd rx pipe for IPA offload + * @soc: data path soc handle + * @res: ipa resource pointer + * @in: pipe in handle + * @over_gsi: flag for IPA offload over gsi + * @hdl: ipa registered handle + * + * Return: none + */ +static void dp_ipa_setup_rx_alt_pipe(struct dp_soc *soc, + struct dp_ipa_resources *res, + qdf_ipa_wdi_conn_in_params_t *in, + bool over_gsi, + qdf_ipa_wdi_hdl_t hdl) +{ + qdf_ipa_wdi_pipe_setup_info_smmu_t *rx_smmu = NULL; + qdf_ipa_wdi_pipe_setup_info_t *rx = NULL; + qdf_ipa_ep_cfg_t *rx_cfg; + + if (!wlan_ipa_is_vlan_enabled()) + return; + + QDF_IPA_WDI_CONN_IN_PARAMS_IS_RX1_USED(in) = true; + if (qdf_mem_smmu_s1_enabled(soc->osdev)) { + rx_smmu = &QDF_IPA_WDI_CONN_IN_PARAMS_RX_ALT_SMMU(in); + rx_cfg = &QDF_IPA_WDI_SETUP_INFO_SMMU_EP_CFG(rx_smmu); + dp_ipa_wdi_rx_alt_pipe_smmu_params(soc, res, rx_smmu, + over_gsi, hdl); + } else { + rx = &QDF_IPA_WDI_CONN_IN_PARAMS_RX_ALT(in); + rx_cfg = &QDF_IPA_WDI_SETUP_INFO_SMMU_EP_CFG(rx); + dp_ipa_wdi_rx_alt_pipe_params(soc, res, rx, over_gsi, hdl); + } + + QDF_IPA_EP_CFG_NAT_EN(rx_cfg) = IPA_BYPASS_NAT; + /* Update with wds len(96) + 4 if wds support is enabled */ + if (ucfg_ipa_is_wds_enabled()) + QDF_IPA_EP_CFG_HDR_LEN(rx_cfg) = DP_IPA_UC_WLAN_RX_HDR_LEN_AST_VLAN; + else + QDF_IPA_EP_CFG_HDR_LEN(rx_cfg) = DP_IPA_UC_WLAN_TX_VLAN_HDR_LEN; + QDF_IPA_EP_CFG_HDR_OFST_PKT_SIZE_VALID(rx_cfg) = 1; + QDF_IPA_EP_CFG_HDR_OFST_PKT_SIZE(rx_cfg) = 0; + QDF_IPA_EP_CFG_HDR_ADDITIONAL_CONST_LEN(rx_cfg) = 0; + QDF_IPA_EP_CFG_HDR_OFST_METADATA_VALID(rx_cfg) = 0; + QDF_IPA_EP_CFG_HDR_METADATA_REG_VALID(rx_cfg) = 1; + QDF_IPA_EP_CFG_MODE(rx_cfg) = IPA_BASIC; + QDF_IPA_EP_CFG_HDR_LITTLE_ENDIAN(rx_cfg) = true; +} + +/* + * dp_ipa_set_rx_alt_pipe_db() - Setup 2nd rx pipe doorbell + * @res: ipa resource pointer + * @out: pipe out handle + * + * Return: none + */ +static void dp_ipa_set_rx_alt_pipe_db(struct dp_ipa_resources *res, + qdf_ipa_wdi_conn_out_params_t *out) +{ + if (!wlan_ipa_is_vlan_enabled()) + return; + + res->rx_alt_ready_doorbell_paddr = + QDF_IPA_WDI_CONN_OUT_PARAMS_RX_ALT_UC_DB_PA(out); + dp_debug("Setting DB 0x%x for RX alt pipe", + res->rx_alt_ready_doorbell_paddr); +} +#else +static inline +void dp_ipa_setup_rx_alt_pipe(struct dp_soc *soc, + struct dp_ipa_resources *res, + qdf_ipa_wdi_conn_in_params_t *in, + bool over_gsi, + qdf_ipa_wdi_hdl_t hdl) +{ } + +static inline +void dp_ipa_set_rx_alt_pipe_db(struct dp_ipa_resources *res, + qdf_ipa_wdi_conn_out_params_t *out) +{ } +#endif + QDF_STATUS dp_ipa_setup(struct cdp_soc_t *soc_hdl, uint8_t pdev_id, void *ipa_i2w_cb, void *ipa_w2i_cb, void *ipa_wdi_meter_notifier_cb, @@ -2174,6 +2598,9 @@ QDF_STATUS dp_ipa_setup(struct cdp_soc_t *soc_hdl, uint8_t pdev_id, else dp_ipa_wdi_rx_params(soc, ipa_res, rx, over_gsi); + /* setup 2nd rx pipe */ + dp_ipa_setup_rx_alt_pipe(soc, ipa_res, pipe_in, over_gsi, id); + QDF_IPA_WDI_CONN_IN_PARAMS_NOTIFY(pipe_in) = ipa_w2i_cb; QDF_IPA_WDI_CONN_IN_PARAMS_PRIV(pipe_in) = ipa_priv; QDF_IPA_WDI_CONN_IN_PARAMS_HANDLE(pipe_in) = hdl; @@ -2196,6 +2623,7 @@ QDF_STATUS dp_ipa_setup(struct cdp_soc_t *soc_hdl, uint8_t pdev_id, (unsigned int)QDF_IPA_WDI_CONN_OUT_PARAMS_RX_UC_DB_PA(&pipe_out)); dp_ipa_set_pipe_db(ipa_res, &pipe_out); + dp_ipa_set_rx_alt_pipe_db(ipa_res, &pipe_out); ipa_res->is_db_ddr_mapped = QDF_IPA_WDI_CONN_OUT_PARAMS_IS_DB_DDR_MAPPED(&pipe_out); @@ -2209,6 +2637,64 @@ QDF_STATUS dp_ipa_setup(struct cdp_soc_t *soc_hdl, uint8_t pdev_id, return QDF_STATUS_SUCCESS; } +#ifdef IPA_WDI3_RX_TWO_PIPES +/* + * dp_ipa_set_rx1_used() - Set rx1 used flag for 2nd rx offload ring + * @in: pipe in handle + * + * Return: none + */ +static inline +void dp_ipa_set_rx1_used(qdf_ipa_wdi_reg_intf_in_params_t *in) +{ + QDF_IPA_WDI_REG_INTF_IN_PARAMS_IS_RX1_USED(in) = true; +} + +/* + * dp_ipa_set_v4_vlan_hdr() - Set v4 vlan hdr + * @in: pipe in handle + * hdr: pointer to hdr + * + * Return: none + */ +static inline +void dp_ipa_set_v4_vlan_hdr(qdf_ipa_wdi_reg_intf_in_params_t *in, + qdf_ipa_wdi_hdr_info_t *hdr) +{ + qdf_mem_copy(&(QDF_IPA_WDI_REG_INTF_IN_PARAMS_HDR_INFO(in)[IPA_IP_v4_VLAN]), + hdr, sizeof(qdf_ipa_wdi_hdr_info_t)); +} + +/* + * dp_ipa_set_v6_vlan_hdr() - Set v6 vlan hdr + * @in: pipe in handle + * hdr: pointer to hdr + * + * Return: none + */ +static inline +void dp_ipa_set_v6_vlan_hdr(qdf_ipa_wdi_reg_intf_in_params_t *in, + qdf_ipa_wdi_hdr_info_t *hdr) +{ + qdf_mem_copy(&(QDF_IPA_WDI_REG_INTF_IN_PARAMS_HDR_INFO(in)[IPA_IP_v6_VLAN]), + hdr, sizeof(qdf_ipa_wdi_hdr_info_t)); +} +#else +static inline +void dp_ipa_set_rx1_used(qdf_ipa_wdi_reg_intf_in_params_t *in) +{ } + +static inline +void dp_ipa_set_v4_vlan_hdr(qdf_ipa_wdi_reg_intf_in_params_t *in, + qdf_ipa_wdi_hdr_info_t *hdr) +{ } + +static inline +void dp_ipa_set_v6_vlan_hdr(qdf_ipa_wdi_reg_intf_in_params_t *in, + qdf_ipa_wdi_hdr_info_t *hdr) +{ } +#endif + /** * dp_ipa_setup_iface() - Setup IPA header and register interface * @ifname: Interface name @@ -2231,6 +2717,8 @@ QDF_STATUS dp_ipa_setup_iface(char *ifname, uint8_t *mac_addr, qdf_ipa_wdi_hdr_info_t hdr_info; struct dp_ipa_uc_tx_hdr uc_tx_hdr; struct dp_ipa_uc_tx_hdr uc_tx_hdr_v6; + struct dp_ipa_uc_tx_vlan_hdr uc_tx_vlan_hdr; + struct dp_ipa_uc_tx_vlan_hdr uc_tx_vlan_hdr_v6; int ret = -EINVAL; qdf_mem_zero(&in, sizeof(qdf_ipa_wdi_reg_intf_in_params_t)); @@ -2258,6 +2746,7 @@ QDF_STATUS dp_ipa_setup_iface(char *ifname, uint8_t *mac_addr, QDF_IPA_WDI_REG_INTF_IN_PARAMS_META_DATA_MASK(&in) = WLAN_IPA_META_DATA_MASK; QDF_IPA_WDI_REG_INTF_IN_PARAMS_HANDLE(&in) = hdl; dp_ipa_setup_iface_session_id(&in, session_id); + dp_debug("registering for session_id: %u", session_id); /* IPV6 header */ if (is_ipv6_enabled) { @@ -2269,14 +2758,50 @@ QDF_STATUS dp_ipa_setup_iface(char *ifname, uint8_t *mac_addr, &hdr_info, sizeof(qdf_ipa_wdi_hdr_info_t)); } - dp_debug("registering for session_id: %u", session_id); + if (wlan_ipa_is_vlan_enabled()) { + /* Add vlan specific headers if vlan supporti is enabled */ + qdf_mem_zero(&hdr_info, sizeof(qdf_ipa_wdi_hdr_info_t)); + dp_ipa_set_rx1_used(&in); + qdf_ether_addr_copy(uc_tx_vlan_hdr.eth.h_source, mac_addr); + /* IPV4 Vlan header */ + uc_tx_vlan_hdr.eth.h_vlan_proto = qdf_htons(ETH_P_8021Q); + uc_tx_vlan_hdr.eth.h_vlan_encapsulated_proto = qdf_htons(ETH_P_IP); + + QDF_IPA_WDI_HDR_INFO_HDR(&hdr_info) = + (uint8_t *)&uc_tx_vlan_hdr; + QDF_IPA_WDI_HDR_INFO_HDR_LEN(&hdr_info) = + DP_IPA_UC_WLAN_TX_VLAN_HDR_LEN; + if (ucfg_ipa_is_wds_enabled()) + QDF_IPA_WDI_HDR_INFO_HDR_TYPE(&hdr_info) = + IPA_HDR_L2_802_1Q_AST; + else + QDF_IPA_WDI_HDR_INFO_HDR_TYPE(&hdr_info) = + IPA_HDR_L2_802_1Q; + + QDF_IPA_WDI_HDR_INFO_DST_MAC_ADDR_OFFSET(&hdr_info) = + DP_IPA_UC_WLAN_HDR_DES_MAC_OFFSET; + + dp_ipa_set_v4_vlan_hdr(&in, &hdr_info); + + /* IPV6 Vlan header */ + if (is_ipv6_enabled) { + qdf_mem_copy(&uc_tx_vlan_hdr_v6, &uc_tx_vlan_hdr, + DP_IPA_UC_WLAN_TX_VLAN_HDR_LEN); + uc_tx_vlan_hdr_v6.eth.h_vlan_proto = + qdf_htons(ETH_P_8021Q); + uc_tx_vlan_hdr_v6.eth.h_vlan_encapsulated_proto = + qdf_htons(ETH_P_IPV6); + QDF_IPA_WDI_HDR_INFO_HDR(&hdr_info) = + (uint8_t *)&uc_tx_vlan_hdr_v6; + dp_ipa_set_v6_vlan_hdr(&in, &hdr_info); + } + } ret = qdf_ipa_wdi_reg_intf(&in); - if (ret) { QDF_TRACE(QDF_MODULE_ID_TXRX, QDF_TRACE_LEVEL_ERROR, - "%s: ipa_wdi_reg_intf: register IPA interface falied: ret=%d", - __func__, ret); + "%s: ipa_wdi_reg_intf: register IPA interface falied: ret=%d", + __func__, ret); return QDF_STATUS_E_FAILURE; } @@ -2581,6 +3106,7 @@ QDF_STATUS dp_ipa_cleanup(struct cdp_soc_t *soc_hdl, uint8_t pdev_id, } dp_ipa_unmap_ring_doorbell_paddr(pdev); + dp_ipa_unmap_rx_alt_ring_doorbell_paddr(pdev); exit: return status; } diff --git a/dp/wifi3.0/dp_ipa.h b/dp/wifi3.0/dp_ipa.h index c4f353834b..dc6f5f6265 100644 --- a/dp/wifi3.0/dp_ipa.h +++ b/dp/wifi3.0/dp_ipa.h @@ -35,6 +35,9 @@ #define IPA_RX_REFILL_BUF_RING_IDX 2 +#define IPA_ALT_REO_DEST_RING_IDX 2 +#define IPA_RX_ALT_REFILL_BUF_RING_IDX 3 + /* Adding delay before disabling ipa pipes if any Tx Completions are pending */ #define TX_COMP_DRAIN_WAIT_MS 50 #define TX_COMP_DRAIN_WAIT_TIMEOUT_MS 100 @@ -64,6 +67,14 @@ struct dp_ipa_uc_tx_hdr { struct ethhdr eth; } __packed; +/** + * struct dp_ipa_uc_tx_hdr - full tx header registered to IPA hardware + * @eth: ether II header + */ +struct dp_ipa_uc_tx_vlan_hdr { + struct vlan_ethhdr eth; +} __packed; + /** * struct dp_ipa_uc_rx_hdr - full rx header registered to IPA hardware * @eth: ether II header @@ -73,11 +84,13 @@ struct dp_ipa_uc_rx_hdr { } __packed; #define DP_IPA_UC_WLAN_TX_HDR_LEN sizeof(struct dp_ipa_uc_tx_hdr) +#define DP_IPA_UC_WLAN_TX_VLAN_HDR_LEN sizeof(struct dp_ipa_uc_tx_vlan_hdr) #define DP_IPA_UC_WLAN_RX_HDR_LEN sizeof(struct dp_ipa_uc_rx_hdr) /* 28 + 16 + * 52 + */ #define DP_IPA_UC_WLAN_RX_HDR_LEN_AST 110 +#define DP_IPA_UC_WLAN_RX_HDR_LEN_AST_VLAN 114 #define DP_IPA_UC_WLAN_HDR_DES_MAC_OFFSET 0 #define DP_IPA_HDL_INVALID 0xFF diff --git a/dp/wifi3.0/dp_main.c b/dp/wifi3.0/dp_main.c index 698e2de530..23dd33d162 100644 --- a/dp/wifi3.0/dp_main.c +++ b/dp/wifi3.0/dp_main.c @@ -17,6 +17,7 @@ * PERFORMANCE OF THIS SOFTWARE. */ +#include #include #include #include @@ -4093,6 +4094,53 @@ static void dp_soc_disable_unused_mac_intr_mask(struct dp_soc *soc, group_number, 0x0); } +#ifdef IPA_OFFLOAD +#ifdef IPA_WDI3_RX_TWO_PIPES +/* + * dp_soc_reset_ipa_vlan_intr_mask() - reset interrupt mask for IPA offloaded + * ring for vlan tagged traffic + * @dp_soc - DP Soc handle + * + * Return: Return void + */ +static void dp_soc_reset_ipa_vlan_intr_mask(struct dp_soc *soc) +{ + uint8_t *grp_mask = NULL; + int group_number, mask; + + if (!wlan_ipa_is_vlan_enabled()) + return; + + grp_mask = &soc->wlan_cfg_ctx->int_rx_ring_mask[0]; + + group_number = dp_srng_find_ring_in_mask(IPA_ALT_REO_DEST_RING_IDX, grp_mask); + if (group_number < 0) { + dp_init_debug("%pK: ring not part of any group; ring_type: %d,ring_num %d", + soc, REO_DST, IPA_ALT_REO_DEST_RING_IDX); + return; + } + + mask = wlan_cfg_get_rx_ring_mask(soc->wlan_cfg_ctx, group_number); + + /* reset the interrupt mask for offloaded ring */ + mask &= (~(1 << IPA_ALT_REO_DEST_RING_IDX)); + + /* + * set the interrupt mask to zero for rx offloaded radio. + */ + wlan_cfg_set_rx_ring_mask(soc->wlan_cfg_ctx, group_number, mask); +} +#else +static inline +void dp_soc_reset_ipa_vlan_intr_mask(struct dp_soc *soc) +{ } +#endif /* IPA_WDI3_RX_TWO_PIPES */ +#else +static inline +void dp_soc_reset_ipa_vlan_intr_mask(struct dp_soc *soc) +{ } +#endif /* IPA_OFFLOAD */ + /* * dp_soc_reset_intr_mask() - reset interrupt mask * @dp_soc - DP Soc handle @@ -4249,10 +4297,21 @@ bool dp_reo_remap_config(struct dp_soc *soc, uint32_t *remap0, break; case CDP_ARCH_TYPE_LI: - hal_compute_reo_remap_ix2_ix3(soc->hal_soc, ring, - soc->num_reo_dest_rings - - USE_1_IPA_RX_REO_RING, remap1, - remap2); + if (wlan_ipa_is_vlan_enabled()) { + hal_compute_reo_remap_ix2_ix3( + soc->hal_soc, ring, + soc->num_reo_dest_rings - + USE_2_IPA_RX_REO_RINGS, remap1, + remap2); + + } else { + hal_compute_reo_remap_ix2_ix3( + soc->hal_soc, ring, + soc->num_reo_dest_rings - + USE_1_IPA_RX_REO_RING, remap1, + remap2); + } + hal_compute_reo_remap_ix0(soc->hal_soc, remap0); break; default: @@ -5043,6 +5102,101 @@ static int dp_setup_ipa_rx_refill_buf_ring(struct dp_soc *soc, return QDF_STATUS_SUCCESS; } +#ifdef IPA_WDI3_RX_TWO_PIPES +static int dp_setup_ipa_rx_alt_refill_buf_ring(struct dp_soc *soc, + struct dp_pdev *pdev) +{ + struct wlan_cfg_dp_soc_ctxt *soc_cfg_ctx; + int entries; + + if (wlan_cfg_is_ipa_enabled(soc->wlan_cfg_ctx) && + wlan_ipa_is_vlan_enabled()) { + soc_cfg_ctx = soc->wlan_cfg_ctx; + entries = + wlan_cfg_get_dp_soc_rxdma_refill_ring_size(soc_cfg_ctx); + + /* Setup second Rx refill buffer ring */ + if (dp_srng_alloc(soc, &pdev->rx_refill_buf_ring3, RXDMA_BUF, + entries, 0)) { + dp_init_err("%pK: alloc failed for 3rd rx refill ring", + soc); + return QDF_STATUS_E_FAILURE; + } + } + + return QDF_STATUS_SUCCESS; +} + +static int dp_init_ipa_rx_alt_refill_buf_ring(struct dp_soc *soc, + struct dp_pdev *pdev) +{ + if (wlan_cfg_is_ipa_enabled(soc->wlan_cfg_ctx) && + wlan_ipa_is_vlan_enabled()) { + if (dp_srng_init(soc, &pdev->rx_refill_buf_ring3, RXDMA_BUF, + IPA_RX_ALT_REFILL_BUF_RING_IDX, + pdev->pdev_id)) { + dp_init_err("%pK: init failed for 3rd rx refill ring", + soc); + return QDF_STATUS_E_FAILURE; + } + } + + return QDF_STATUS_SUCCESS; +} + +static void dp_deinit_ipa_rx_alt_refill_buf_ring(struct dp_soc *soc, + struct dp_pdev *pdev) +{ + if (wlan_cfg_is_ipa_enabled(soc->wlan_cfg_ctx) && + wlan_ipa_is_vlan_enabled()) + dp_srng_deinit(soc, &pdev->rx_refill_buf_ring3, RXDMA_BUF, 0); +} + +static void dp_free_ipa_rx_alt_refill_buf_ring(struct dp_soc *soc, + struct dp_pdev *pdev) +{ + if (wlan_cfg_is_ipa_enabled(soc->wlan_cfg_ctx) && + wlan_ipa_is_vlan_enabled()) + dp_srng_free(soc, &pdev->rx_refill_buf_ring3); +} +#else +static int dp_setup_ipa_rx_alt_refill_buf_ring(struct dp_soc *soc, + struct dp_pdev *pdev) +{ + return QDF_STATUS_SUCCESS; +} + +static int dp_init_ipa_rx_alt_refill_buf_ring(struct dp_soc *soc, + struct dp_pdev *pdev) +{ + return QDF_STATUS_SUCCESS; +} + +static void dp_deinit_ipa_rx_alt_refill_buf_ring(struct dp_soc *soc, + struct dp_pdev *pdev) +{ +} + +static void dp_free_ipa_rx_alt_refill_buf_ring(struct dp_soc *soc, + struct dp_pdev *pdev) +{ +} +#endif + +/** + * dp_deinit_ipa_rx_refill_buf_ring - deinit second Rx refill buffer ring + * @soc: data path instance + * @pdev: core txrx pdev context + * + * Return: void + */ +static void dp_deinit_ipa_rx_refill_buf_ring(struct dp_soc *soc, + struct dp_pdev *pdev) +{ + if (wlan_cfg_is_ipa_enabled(soc->wlan_cfg_ctx)) + dp_srng_deinit(soc, &pdev->rx_refill_buf_ring2, RXDMA_BUF, 0); +} + /** * dp_init_ipa_rx_refill_buf_ring - Init second Rx refill buffer ring * @soc: data path instance @@ -5062,21 +5216,13 @@ static int dp_init_ipa_rx_refill_buf_ring(struct dp_soc *soc, return QDF_STATUS_E_FAILURE; } } - return QDF_STATUS_SUCCESS; -} -/** - * dp_deinit_ipa_rx_refill_buf_ring - deinit second Rx refill buffer ring - * @soc: data path instance - * @pdev: core txrx pdev context - * - * Return: void - */ -static void dp_deinit_ipa_rx_refill_buf_ring(struct dp_soc *soc, - struct dp_pdev *pdev) -{ - if (wlan_cfg_is_ipa_enabled(soc->wlan_cfg_ctx)) - dp_srng_deinit(soc, &pdev->rx_refill_buf_ring2, RXDMA_BUF, 0); + if (dp_init_ipa_rx_alt_refill_buf_ring(soc, pdev)) { + dp_deinit_ipa_rx_refill_buf_ring(soc, pdev); + return QDF_STATUS_E_FAILURE; + } + + return QDF_STATUS_SUCCESS; } /** @@ -5114,6 +5260,22 @@ static void dp_free_ipa_rx_refill_buf_ring(struct dp_soc *soc, struct dp_pdev *pdev) { } + +static int dp_setup_ipa_rx_alt_refill_buf_ring(struct dp_soc *soc, + struct dp_pdev *pdev) +{ + return QDF_STATUS_SUCCESS; +} + +static void dp_deinit_ipa_rx_alt_refill_buf_ring(struct dp_soc *soc, + struct dp_pdev *pdev) +{ +} + +static void dp_free_ipa_rx_alt_refill_buf_ring(struct dp_soc *soc, + struct dp_pdev *pdev) +{ +} #endif #ifdef DP_TX_HW_DESC_HISTORY @@ -5439,7 +5601,17 @@ QDF_STATUS dp_pdev_attach_wifi3(struct cdp_soc_t *txrx_soc, soc->arch_ops.txrx_pdev_attach(pdev, params); + /* Setup third Rx refill buffer ring */ + if (dp_setup_ipa_rx_alt_refill_buf_ring(soc, pdev)) { + dp_init_err("%pK: dp_srng_alloc failed rxrefill3 ring", + soc); + goto fail6; + } + return QDF_STATUS_SUCCESS; + +fail6: + dp_monitor_pdev_detach(pdev); fail5: dp_rx_pdev_desc_pool_free(pdev); fail4: @@ -5591,6 +5763,7 @@ static void dp_pdev_deinit(struct cdp_pdev *txrx_pdev, int force) dp_pdev_srng_deinit(pdev); dp_ipa_uc_detach(pdev->soc, pdev); + dp_deinit_ipa_rx_alt_refill_buf_ring(pdev->soc, pdev); dp_deinit_ipa_rx_refill_buf_ring(pdev->soc, pdev); dp_rxdma_ring_cleanup(pdev->soc, pdev); @@ -5691,6 +5864,7 @@ static void dp_pdev_detach(struct cdp_pdev *txrx_pdev, int force) dp_monitor_pdev_detach(pdev); dp_rxdma_ring_free(pdev); dp_free_ipa_rx_refill_buf_ring(soc, pdev); + dp_free_ipa_rx_alt_refill_buf_ring(soc, pdev); dp_pdev_srng_free(pdev); soc->pdev_count--; @@ -6016,6 +6190,25 @@ dp_htt_setup_rxdma_err_dst_ring(struct dp_soc *soc, int mac_id, RXDMA_DST); } +#ifdef IPA_WDI3_RX_TWO_PIPES +static inline +void dp_rxdma_setup_refill_ring3(struct dp_soc *soc, + struct dp_pdev *pdev, + uint8_t idx) +{ + if (pdev->rx_refill_buf_ring3.hal_srng) + htt_srng_setup(soc->htt_handle, idx, + pdev->rx_refill_buf_ring3.hal_srng, + RXDMA_BUF); +} +#else +static inline +void dp_rxdma_setup_refill_ring3(struct dp_soc *soc, + struct dp_pdev *pdev, + uint8_t idx) +{ } +#endif + static QDF_STATUS dp_rxdma_ring_config(struct dp_soc *soc) { int i; @@ -6042,6 +6235,8 @@ static QDF_STATUS dp_rxdma_ring_config(struct dp_soc *soc) .hal_srng, RXDMA_BUF); + dp_rxdma_setup_refill_ring3(soc, pdev, i); + dp_update_num_mac_rings_for_dbs(soc, &max_mac_rings); dp_err("pdev_id %d max_mac_rings %d", pdev->pdev_id, max_mac_rings); @@ -15665,6 +15860,9 @@ static QDF_STATUS dp_pdev_init(struct cdp_soc_t *txrx_soc, dp_soc_reset_intr_mask(soc); } + /* Reset the cpu ring map if radio is NSS offloaded */ + dp_soc_reset_ipa_vlan_intr_mask(soc); + TAILQ_INIT(&pdev->vdev_list); qdf_spinlock_create(&pdev->vdev_list_lock); pdev->vdev_count = 0; diff --git a/dp/wifi3.0/dp_types.h b/dp/wifi3.0/dp_types.h index 45c35276dc..91ca891886 100644 --- a/dp/wifi3.0/dp_types.h +++ b/dp/wifi3.0/dp_types.h @@ -1722,6 +1722,21 @@ struct ipa_dp_tx_rsc { void **tx_buf_pool_vaddr_unaligned; qdf_dma_addr_t *tx_buf_pool_paddr_unaligned; }; + +/* IPA uC datapath offload Wlan Rx resources */ +struct ipa_dp_rx_rsc { + /* Resource info to be passed to IPA */ + qdf_dma_addr_t ipa_reo_ring_base_paddr; + void *ipa_reo_ring_base_vaddr; + uint32_t ipa_reo_ring_size; + qdf_dma_addr_t ipa_reo_tp_paddr; + + /* Resource info to be passed to firmware and IPA */ + qdf_dma_addr_t ipa_rx_refill_buf_ring_base_paddr; + void *ipa_rx_refill_buf_ring_base_vaddr; + uint32_t ipa_rx_refill_buf_ring_size; + qdf_dma_addr_t ipa_rx_refill_buf_hp_paddr; +}; #endif struct dp_tx_msdu_info_s; @@ -2252,21 +2267,10 @@ struct dp_soc { struct ipa_dp_tx_rsc ipa_uc_tx_rsc_alt; #endif - /* IPA uC datapath offload Wlan Rx resources */ - struct { - /* Resource info to be passed to IPA */ - qdf_dma_addr_t ipa_reo_ring_base_paddr; - void *ipa_reo_ring_base_vaddr; - uint32_t ipa_reo_ring_size; - qdf_dma_addr_t ipa_reo_tp_paddr; - - /* Resource info to be passed to firmware and IPA */ - qdf_dma_addr_t ipa_rx_refill_buf_ring_base_paddr; - void *ipa_rx_refill_buf_ring_base_vaddr; - uint32_t ipa_rx_refill_buf_ring_size; - qdf_dma_addr_t ipa_rx_refill_buf_hp_paddr; - } ipa_uc_rx_rsc; - + struct ipa_dp_rx_rsc ipa_uc_rx_rsc; +#ifdef IPA_WDI3_RX_TWO_PIPES + struct ipa_dp_rx_rsc ipa_uc_rx_rsc_alt; +#endif qdf_atomic_t ipa_pipes_enabled; bool ipa_first_tx_db_access; qdf_spinlock_t ipa_rx_buf_map_lock; @@ -2493,6 +2497,11 @@ struct dp_ipa_resources { qdf_dma_addr_t tx_alt_comp_doorbell_paddr; uint32_t *tx_alt_comp_doorbell_vaddr; #endif +#ifdef IPA_WDI3_RX_TWO_PIPES + qdf_shared_mem_t rx_alt_rdy_ring; + qdf_shared_mem_t rx_alt_refill_ring; + qdf_dma_addr_t rx_alt_ready_doorbell_paddr; +#endif }; #endif @@ -2795,6 +2804,10 @@ struct dp_pdev { /* Second ring used to replenish rx buffers */ struct dp_srng rx_refill_buf_ring2; +#ifdef IPA_WDI3_RX_TWO_PIPES + /* Third ring used to replenish rx buffers */ + struct dp_srng rx_refill_buf_ring3; +#endif /* Empty ring used by firmware to post rx buffers to the MAC */ struct dp_srng rx_mac_buf_ring[MAX_RX_MAC_RINGS]; diff --git a/hal/wifi3.0/hal_internal.h b/hal/wifi3.0/hal_internal.h index bbba190ffd..8d53b499f3 100644 --- a/hal/wifi3.0/hal_internal.h +++ b/hal/wifi3.0/hal_internal.h @@ -260,6 +260,9 @@ enum hal_srng_ring_id { #ifdef IPA_OFFLOAD HAL_SRNG_WMAC1_SW2RXDMA0_BUF1, HAL_SRNG_WMAC1_SW2RXDMA0_BUF2, +#ifdef IPA_WDI3_RX_TWO_PIPES + HAL_SRNG_WMAC1_SW2RXDMA0_BUF3, +#endif HAL_SRNG_WMAC1_SW2RXDMA1_BUF, #else HAL_SRNG_WMAC1_SW2RXDMA1_BUF, diff --git a/hal/wifi3.0/qcn9000/hal_9000.c b/hal/wifi3.0/qcn9000/hal_9000.c index f5e3760338..a6d69a58ad 100644 --- a/hal/wifi3.0/qcn9000/hal_9000.c +++ b/hal/wifi3.0/qcn9000/hal_9000.c @@ -2273,7 +2273,11 @@ struct hal_hw_srng_config hw_srng_table_9000[] = { { /* RXDMA_BUF */ .start_ring_id = HAL_SRNG_WMAC1_SW2RXDMA0_BUF0, #ifdef IPA_OFFLOAD +#ifdef IPA_WDI3_RX_TWO_PIPES + .max_rings = 4, +#else .max_rings = 3, +#endif #else .max_rings = 2, #endif