qcacmn: Add support for vlan tagged traffic in IPA offload

In IPA offload, both tagged and untagged traffic cannot be handled with
a single rx pipe. Hence, add support for 2nd RX pipe for tagged and
untagged traffic respectively.

Change-Id: I77ff633327696f66df42fb592492321c1591646b
CRs-Fixed: 3226021
Este commit está contenido en:
Himanshu Batra
2022-05-04 15:46:14 +05:30
cometido por Madan Koyyalamudi
padre 7c3316638a
commit 7be2cf3775
Se han modificado 7 ficheros con 802 adiciones y 38 borrados

Ver fichero

@@ -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;
}