qcacmn: Add PPE Tx/RX changes

Add support for:-
   1. PPE VP entry attach and detach.
   2. Per VAP PRI2TID Support
   3. Dump the PPE VP HW entries.
   4. Add tx completion handling for ppeds descriptors

Change-Id: I2a6d0be5bb556663a39a24d17b703877f3b5ad00
CRs-Fixed: 3276981
This commit is contained in:
Neelansh Mittal
2021-12-08 16:17:41 +05:30
committed by Madan Koyyalamudi
parent 878aebaac1
commit 83990186aa
10 changed files with 306 additions and 5 deletions

View File

@@ -1284,6 +1284,7 @@ enum cdp_pdev_param_type {
*
* @cdp_psoc_param_en_rate_stats: set rate stats enable/disable
* @cdp_psoc_param_en_nss_cfg: set nss cfg
* @cdp_psoc_param_ppeds_enabled: PPE-DS feature enable
* @cdp_ipa_enabled : set ipa mode
* @cdp_psoc_param_vdev_stats_hw_offload: Configure HW vdev stats offload
* @cdp_pdev_param_undecoded_metadata_enable: Undecoded metadata capture enable
@@ -1367,6 +1368,7 @@ typedef union cdp_config_param_t {
int cdp_psoc_param_en_nss_cfg;
int cdp_psoc_param_preferred_hw_mode;
bool cdp_psoc_param_pext_stats;
bool cdp_psoc_param_ppeds_enabled;
bool cdp_skip_bar_update;
bool cdp_ipa_enabled;
@@ -1513,6 +1515,7 @@ enum cdp_vdev_param_type {
* @CDP_IPA_ENABLE : set IPA enable mode.
* @CDP_CFG_VDEV_STATS_HW_OFFLOAD: HW Vdev stats config
* @CDP_UMAC_RST_SKEL_ENABLE: Enable Umac reset skeleton code for debug
* @CDP_CDP_PPEDS_ENABLE: PPEDS is enabled or not
*/
enum cdp_psoc_param_type {
CDP_ENABLE_RATE_STATS,
@@ -1523,6 +1526,7 @@ enum cdp_psoc_param_type {
CDP_CFG_VDEV_STATS_HW_OFFLOAD,
CDP_SAWF_ENABLE,
CDP_UMAC_RST_SKEL_ENABLE,
CDP_PPEDS_ENABLE,
};
#define TXRX_FW_STATS_TXSTATS 1

View File

@@ -2156,6 +2156,25 @@ struct cdp_sawf_ops {
};
#endif
#ifdef WLAN_SUPPORT_PPEDS
struct cdp_ppe_txrx_ops {
QDF_STATUS
(*ppeds_entry_attach)(struct cdp_soc_t *soc,
uint8_t vdev_id, void *vpai,
int32_t *ppe_vp_num);
QDF_STATUS
(*ppeds_enable_pri2tid)(struct cdp_soc_t *soc,
uint8_t vdev_id, bool val);
void (*ppeds_entry_detach)(struct cdp_soc_t *soc,
uint8_t vdev_id);
void (*ppeds_set_int_pri2tid)(struct cdp_soc_t *soc,
uint8_t *pri2tid);
void (*ppeds_update_int_pri2tid)(struct cdp_soc_t *soc,
uint8_t pri, uint8_t tid);
void (*ppeds_entry_dump)(struct cdp_soc_t *soc);
};
#endif /* WLAN_SUPPORT_PPEDS */
struct cdp_ops {
struct cdp_cmn_ops *cmn_drv_ops;
struct cdp_ctrl_ops *ctrl_ops;
@@ -2206,5 +2225,8 @@ struct cdp_ops {
#ifdef WLAN_SUPPORT_SCS
struct cdp_scs_ops *scs_ops;
#endif
#ifdef WLAN_SUPPORT_PPEDS
struct cdp_ppe_txrx_ops *ppe_ops;
#endif
};
#endif

159
dp/inc/cdp_txrx_ppe.h Normal file
View File

@@ -0,0 +1,159 @@
/*
* Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved.
*
* Permission to use, copy, modify, and/or distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
#ifndef _CDP_TXRX_PPE_H_
#define _CDP_TXRX_PPE_H_
/**
* cdp_ppesds_entry_attach() - attach the ppe vp interface.
* @soc: data path soc handle
* @vdev_id: vdev id
* @vpai: PPE VP opaque
* @ppe_vp_num: Allocated VP Port number
*
* return: qdf_status where vp entry got allocated or not.
*/
static inline
QDF_STATUS cdp_ppesds_entry_attach(struct cdp_soc_t *soc, uint8_t vdev_id,
void *vpai, int32_t *ppe_vp_num)
{
if (!soc || !soc->ops || !soc->ops->ppe_ops) {
QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_FATAL,
"%s invalid instance", __func__);
return QDF_STATUS_E_INVAL;
}
if (soc->ops->ppe_ops->ppeds_entry_attach) {
return soc->ops->ppe_ops->ppeds_entry_attach(soc, vdev_id,
vpai, ppe_vp_num);
}
return QDF_STATUS_E_NOSUPPORT;
}
/**
* cdp_ppesds_entry_detach() - Detach the PPE VP interface.
* @soc: data path soc handle
* @vdev_id: vdev ID
*
* return: void
*/
static inline
void cdp_ppesds_entry_detach(struct cdp_soc_t *soc, uint8_t vdev_id)
{
if (!soc || !soc->ops || !soc->ops->ppe_ops) {
QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_FATAL,
"%s invalid instance", __func__);
return;
}
if (soc->ops->ppe_ops->ppeds_entry_detach) {
return soc->ops->ppe_ops->ppeds_entry_detach
(soc, vdev_id);
}
}
/**
* cdp_ppesds_set_int_pri2tid() - Set the INT_PRI to TID
* @soc: data path soc handle
* @pri2tid: PRI2TID table
*
* return: void
*/
static inline
void cdp_ppesds_set_int_pri2tid(struct cdp_soc_t *soc,
uint8_t *pri2tid)
{
if (!soc || !soc->ops || !soc->ops->ppe_ops) {
QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_FATAL,
"%s invalid instance", __func__);
return;
}
if (soc->ops->ppe_ops->ppeds_set_int_pri2tid) {
return soc->ops->ppe_ops->ppeds_set_int_pri2tid
(soc, pri2tid);
}
}
/**
* cdp_ppesds_update_int_pri2tid() - Update the INT_PRI to TID
* @soc: data path soc handle
* @pri: Priority index
* @tid: TID mapped to the input priority
*
* return: void
*/
static inline
void cdp_ppesds_update_int_pri2tid(struct cdp_soc_t *soc,
uint8_t pri, uint8_t tid)
{
if (!soc || !soc->ops || !soc->ops->ppe_ops) {
QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_FATAL,
"%s invalid instance", __func__);
}
if (soc->ops->ppe_ops->ppeds_update_int_pri2tid) {
return soc->ops->ppe_ops->ppeds_update_int_pri2tid
(soc, pri, tid);
}
}
/**
* cdp_ppesds_entry_dump() - Dump the PPE VP entries
* @soc: data path soc handle
*
* return: void
*/
static inline
void cdp_ppesds_entry_dump(struct cdp_soc_t *soc)
{
if (!soc || !soc->ops || !soc->ops->ppe_ops) {
QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_FATAL,
"%s invalid instance", __func__);
return;
}
if (soc->ops->ppe_ops->ppeds_entry_dump)
soc->ops->ppe_ops->ppeds_entry_dump(soc);
}
/**
* cdp_ppesds_enable_pri2tid() - Enable PPE VP PRI2TID table
* @soc: data path soc handle
* @vdev_id: vdev id
* @val: Boolean value to enable/disable
*
* return: QDF_STATUS
*/
static inline
QDF_STATUS cdp_ppesds_enable_pri2tid(struct cdp_soc_t *soc,
uint8_t vdev_id, bool val)
{
if (!soc || !soc->ops || !soc->ops->ppe_ops) {
QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_FATAL,
"%s invalid instance", __func__);
return QDF_STATUS_E_INVAL;
}
if (soc->ops->ppe_ops->ppeds_enable_pri2tid) {
return soc->ops->ppe_ops->ppeds_enable_pri2tid(soc,
vdev_id, val);
}
return QDF_STATUS_E_NOSUPPORT;
}
#endif /* _CDP_TXRX_PPE_H_ */

View File

@@ -30,6 +30,9 @@
#include "dp_mon.h"
#endif
#include <hal_be_api.h>
#ifdef WLAN_SUPPORT_PPEDS
#include "be/dp_ppeds.h"
#endif
/* Generic AST entry aging timer value */
#define DP_AST_AGING_TIMER_DEFAULT_MS 5000
@@ -62,6 +65,15 @@ static struct wlan_cfg_tcl_wbm_ring_num_map g_tcl_wbm_map_array[MAX_TCL_DATA_RIN
#endif
#ifdef WLAN_SUPPORT_PPEDS
static struct cdp_ppe_txrx_ops dp_ops_ppe_be = {
.ppeds_entry_attach = dp_ppeds_attach_vdev_be,
.ppeds_entry_detach = dp_ppeds_detach_vdev_be,
.ppeds_set_int_pri2tid = dp_ppeds_set_int_pri2tid_be,
.ppeds_update_int_pri2tid = dp_ppeds_update_int_pri2tid_be,
.ppeds_entry_dump = dp_ppeds_dump_ppe_vp_tbl_be,
.ppeds_enable_pri2tid = dp_ppeds_vdev_enable_pri2tid_be,
};
static void dp_ppeds_rings_status(struct dp_soc *soc)
{
struct dp_soc_be *be_soc = dp_get_be_soc_from_dp_soc(soc);
@@ -456,11 +468,58 @@ dp_hw_cookie_conversion_deinit(struct dp_soc_be *be_soc,
}
#endif
#ifdef WLAN_SUPPORT_PPEDS
static QDF_STATUS dp_soc_ppe_attach_be(struct dp_soc *soc)
{
struct dp_soc_be *be_soc = dp_get_be_soc_from_dp_soc(soc);
struct cdp_ops *cdp_ops = soc->cdp_soc.ops;
/*
* Check if PPE DS is enabled.
*/
if (!wlan_cfg_get_dp_soc_is_ppe_enabled(soc->wlan_cfg_ctx))
return QDF_STATUS_SUCCESS;
if (dp_ppeds_attach_soc_be(be_soc) != QDF_STATUS_SUCCESS)
return QDF_STATUS_SUCCESS;
cdp_ops->ppe_ops = &dp_ops_ppe_be;
return QDF_STATUS_SUCCESS;
}
static QDF_STATUS dp_soc_ppe_detach_be(struct dp_soc *soc)
{
struct dp_soc_be *be_soc = dp_get_be_soc_from_dp_soc(soc);
struct cdp_ops *cdp_ops = soc->cdp_soc.ops;
if (!wlan_cfg_get_dp_soc_is_ppe_enabled(soc->wlan_cfg_ctx))
return QDF_STATUS_E_FAILURE;
dp_ppeds_detach_soc_be(be_soc);
cdp_ops->ppe_ops = NULL;
return QDF_STATUS_SUCCESS;
}
#else
static inline QDF_STATUS dp_soc_ppe_attach_be(struct dp_soc *soc)
{
return QDF_STATUS_SUCCESS;
}
static inline QDF_STATUS dp_soc_ppe_detach_be(struct dp_soc *soc)
{
return QDF_STATUS_SUCCESS;
}
#endif /* WLAN_SUPPORT_PPEDS */
static QDF_STATUS dp_soc_detach_be(struct dp_soc *soc)
{
struct dp_soc_be *be_soc = dp_get_be_soc_from_dp_soc(soc);
int i = 0;
dp_soc_ppe_detach_be(soc);
for (i = 0; i < MAX_TXDESC_POOLS; i++)
dp_hw_cookie_conversion_detach(be_soc,
@@ -586,6 +645,10 @@ static QDF_STATUS dp_soc_attach_be(struct dp_soc *soc,
dp_soc_mlo_fill_params(soc, params);
qdf_status = dp_soc_ppe_attach_be(soc);
if (!QDF_IS_STATUS_SUCCESS(qdf_status))
goto fail;
for (i = 0; i < MAX_TXDESC_POOLS; i++) {
num_entries = wlan_cfg_get_num_tx_desc(soc->wlan_cfg_ctx);
qdf_status =
@@ -1262,6 +1325,12 @@ static QDF_STATUS dp_soc_ppe_srng_init(struct dp_soc *soc)
soc->ctrl_psoc,
WLAN_MD_DP_SRNG_PPE_RELEASE,
"ppe_release_ring");
#ifdef WLAN_SUPPORT_PPEDS
if (dp_ppeds_register_soc_be(be_soc)) {
dp_err("%pK: ppeds registration failed", soc);
goto fail;
}
#endif
return QDF_STATUS_SUCCESS;
fail:
@@ -2063,8 +2132,12 @@ void dp_initialize_arch_ops_be(struct dp_arch_ops *arch_ops)
#ifdef WLAN_SUPPORT_PPEDS
arch_ops->dp_txrx_ppeds_rings_status = dp_ppeds_rings_status;
arch_ops->txrx_soc_ppeds_start = dp_ppeds_start_soc_be;
arch_ops->txrx_soc_ppeds_stop = dp_ppeds_stop_soc_be;
#else
arch_ops->dp_txrx_ppeds_rings_status = NULL;
arch_ops->txrx_soc_ppeds_start = NULL;
arch_ops->txrx_soc_ppeds_stop = NULL;
#endif
dp_init_near_full_arch_ops_be(arch_ops);

View File

@@ -118,11 +118,6 @@ enum CMEM_MEM_CLIENTS {
#define DP_CMEM_OFFSET_TO_PPT_ID(offset) \
((offset) / DP_CC_PPT_ENTRY_SIZE_4K_ALIGNED)
/* The MAX PPE PRI2TID */
#ifdef WLAN_SUPPORT_PPEDS
#define DP_TX_INT_PRI2TID_MAX 15
#endif
/**
* struct dp_spt_page_desc - secondary page table page descriptors
* @next: pointer to next linked SPT page Desc
@@ -237,6 +232,7 @@ struct dp_ppe_vp_profile {
* @ppe_vp_tbl_lock: PPE VP table lock
* @num_ppe_vp_entries : Number of PPE VP entries
* @ipa_bank_id: TCL bank id used by IPA
* @ppeds_handle: PPEDS soc instance handle
*/
struct dp_soc_be {
struct dp_soc soc;
@@ -256,6 +252,7 @@ struct dp_soc_be {
struct dp_srng ppe2tcl_ring;
struct dp_srng ppe_release_ring;
struct dp_ppe_vp_tbl_entry *ppe_vp_tbl;
void *ppeds_handle;
qdf_mutex_t ppe_vp_tbl_lock;
uint8_t num_ppe_vp_entries;
#endif

View File

@@ -6231,6 +6231,9 @@ static void dp_soc_deinit(void *txrx_soc)
qdf_atomic_set(&soc->cmn_init_done, 0);
if (soc->arch_ops.txrx_soc_ppeds_stop)
soc->arch_ops.txrx_soc_ppeds_stop(soc);
soc->arch_ops.txrx_soc_deinit(soc);
dp_monitor_soc_deinit(soc);
@@ -11035,6 +11038,10 @@ static QDF_STATUS dp_get_psoc_param(struct cdp_soc_t *cdp_soc,
case CDP_UMAC_RST_SKEL_ENABLE:
val->cdp_umac_rst_skel = dp_umac_rst_skel_enable_get(soc);
break;
case CDP_PPEDS_ENABLE:
val->cdp_psoc_param_ppeds_enabled =
wlan_cfg_get_dp_soc_is_ppe_enabled(soc->wlan_cfg_ctx);
break;
default:
dp_warn("Invalid param");
break;
@@ -15432,6 +15439,13 @@ void *dp_soc_init(struct dp_soc *soc, HTC_HANDLE htc_handle,
goto fail6;
}
if (soc->arch_ops.txrx_soc_ppeds_start) {
if (soc->arch_ops.txrx_soc_ppeds_start(soc)) {
dp_init_err("%pK: ppeds start failed", soc);
goto fail7;
}
}
wlan_cfg_set_rx_hash(soc->wlan_cfg_ctx,
cfg_get(soc->ctrl_psoc, CFG_DP_RX_HASH));
soc->cce_disable = false;
@@ -15517,6 +15531,8 @@ void *dp_soc_init(struct dp_soc *soc, HTC_HANDLE htc_handle,
soc->vdev_stats_id_map = 0;
return soc;
fail7:
dp_soc_tx_desc_sw_pools_deinit(soc);
fail6:
htt_soc_htc_dealloc(soc->htt_handle);
fail5:

View File

@@ -5201,6 +5201,19 @@ dp_tx_comp_process_desc_list(struct dp_soc *soc,
desc = next;
continue;
}
if (desc->flags & DP_TX_DESC_FLAG_PPEDS) {
if (qdf_likely(txrx_peer))
dp_tx_update_peer_basic_stats(txrx_peer,
desc->length,
desc->tx_status,
false);
qdf_nbuf_free(desc->nbuf);
dp_tx_desc_free(soc, desc, desc->pool_id);
desc = next;
continue;
}
if (qdf_likely(desc->flags & DP_TX_DESC_FLAG_SIMPLE)) {
struct dp_pdev *pdev = desc->pdev;
@@ -5424,6 +5437,10 @@ more_data:
continue;
}
tx_desc->buffer_src = buffer_src;
if (tx_desc->flags & DP_TX_DESC_FLAG_PPEDS)
goto add_to_pool2;
/*
* If the release source is FW, process the HTT status
*/
@@ -5489,6 +5506,7 @@ more_data:
add_to_pool:
DP_HIST_PACKET_COUNT_INC(tx_desc->pdev->pdev_id);
add_to_pool2:
/* First ring descriptor on the cycle */
if (!head_desc) {
head_desc = tx_desc;

View File

@@ -60,6 +60,12 @@
#define DP_TX_DESC_FLAG_TX_COMP_ERR 0x1000
#define DP_TX_DESC_FLAG_FLUSH 0x2000
#define DP_TX_DESC_FLAG_TRAFFIC_END_IND 0x4000
/*
* Since the Tx descriptor flag is of only 16-bit and no more bit is free for
* any new flag, therefore for time being overloading PPEDS flag with that of
* FLUSH flag.
*/
#define DP_TX_DESC_FLAG_PPEDS 0x2000
#define DP_TX_EXT_DESC_FLAG_METADATA_VALID 0x1

View File

@@ -458,6 +458,7 @@ enum dp_ctxt_type {
/**
* enum dp_desc_type - source type for multiple pages allocation
* @DP_TX_DESC_TYPE: DP SW TX descriptor
* @DP_TX_PPEDS_DESC_TYPE: DP PPE-DS Tx descriptor
* @DP_TX_EXT_DESC_TYPE: DP TX msdu extension descriptor
* @DP_TX_EXT_DESC_LINK_TYPE: DP link descriptor for msdu ext_desc
* @DP_TX_TSO_DESC_TYPE: DP TX TSO descriptor
@@ -469,6 +470,7 @@ enum dp_ctxt_type {
*/
enum dp_desc_type {
DP_TX_DESC_TYPE,
DP_TX_PPEDS_DESC_TYPE,
DP_TX_EXT_DESC_TYPE,
DP_TX_EXT_DESC_LINK_TYPE,
DP_TX_TSO_DESC_TYPE,
@@ -1992,6 +1994,8 @@ struct dp_arch_ops {
int8_t (*ipa_get_bank_id)(struct dp_soc *soc);
#endif
void (*dp_txrx_ppeds_rings_status)(struct dp_soc *soc);
QDF_STATUS (*txrx_soc_ppeds_start)(struct dp_soc *soc);
void (*txrx_soc_ppeds_stop)(struct dp_soc *soc);
};
/**

View File

@@ -629,6 +629,8 @@ void dp_initialize_arch_ops_li(struct dp_arch_ops *arch_ops)
arch_ops->peer_get_reo_hash = dp_peer_get_reo_hash_li;
arch_ops->reo_remap_config = dp_reo_remap_config_li;
arch_ops->dp_txrx_ppeds_rings_status = NULL;
arch_ops->txrx_soc_ppeds_start = NULL;
arch_ops->txrx_soc_ppeds_stop = NULL;
}
#ifdef QCA_DP_TX_HW_SW_NBUF_DESC_PREFETCH