qcacmn: Add support for getting CE srng info for Direct Link

Add support to fetch CE srng information used for
direct link datapath.

Change-Id: If38b892b28eba711d7949fa02926205dc601a50e
CRs-Fixed: 3317501
This commit is contained in:
Yeshwanth Sriram Guntuka
2022-08-25 19:16:50 +05:30
committed by Madan Koyyalamudi
parent e228622034
commit 9b059a3bc0
6 changed files with 267 additions and 14 deletions

View File

@@ -35,6 +35,14 @@
/* Ring index for WBM2SW2 release ring */ /* Ring index for WBM2SW2 release ring */
#define HAL_IPA_TX_COMP_RING_IDX 2 #define HAL_IPA_TX_COMP_RING_IDX 2
#if defined(CONFIG_SHADOW_V2) || defined(CONFIG_SHADOW_V3)
#define ignore_shadow false
#define CHECK_SHADOW_REGISTERS true
#else
#define ignore_shadow true
#define CHECK_SHADOW_REGISTERS false
#endif
/* calculate the register address offset from bar0 of shadow register x */ /* calculate the register address offset from bar0 of shadow register x */
#if defined(QCA_WIFI_QCA6390) || defined(QCA_WIFI_QCA6490) || \ #if defined(QCA_WIFI_QCA6390) || defined(QCA_WIFI_QCA6490) || \
defined(QCA_WIFI_KIWI) defined(QCA_WIFI_KIWI)
@@ -2606,9 +2614,17 @@ hal_srng_get_hp_addr(void *hal_soc,
struct hal_soc *hal = (struct hal_soc *)hal_soc; struct hal_soc *hal = (struct hal_soc *)hal_soc;
if (srng->ring_dir == HAL_SRNG_SRC_RING) { if (srng->ring_dir == HAL_SRNG_SRC_RING) {
return hal->shadow_wrptr_mem_paddr + if (srng->flags & HAL_SRNG_LMAC_RING)
((unsigned long)(srng->u.src_ring.hp_addr) - return hal->shadow_wrptr_mem_paddr +
(unsigned long)(hal->shadow_wrptr_mem_vaddr)); ((unsigned long)(srng->u.src_ring.hp_addr) -
(unsigned long)(hal->shadow_wrptr_mem_vaddr));
else if (ignore_shadow)
return (qdf_dma_addr_t)srng->u.src_ring.hp_addr;
else
return ((struct hif_softc *)hal->hif_handle)->mem_pa +
((unsigned long)srng->u.src_ring.hp_addr -
(unsigned long)hal->dev_base_addr);
} else { } else {
return hal->shadow_rdptr_mem_paddr + return hal->shadow_rdptr_mem_paddr +
((unsigned long)(srng->u.dst_ring.hp_addr) - ((unsigned long)(srng->u.dst_ring.hp_addr) -
@@ -2634,9 +2650,16 @@ hal_srng_get_tp_addr(void *hal_soc, hal_ring_handle_t hal_ring_hdl)
((unsigned long)(srng->u.src_ring.tp_addr) - ((unsigned long)(srng->u.src_ring.tp_addr) -
(unsigned long)(hal->shadow_rdptr_mem_vaddr)); (unsigned long)(hal->shadow_rdptr_mem_vaddr));
} else { } else {
return hal->shadow_wrptr_mem_paddr + if (srng->flags & HAL_SRNG_LMAC_RING)
((unsigned long)(srng->u.dst_ring.tp_addr) - return hal->shadow_wrptr_mem_paddr +
(unsigned long)(hal->shadow_wrptr_mem_vaddr)); ((unsigned long)(srng->u.dst_ring.tp_addr) -
(unsigned long)(hal->shadow_wrptr_mem_vaddr));
else if (ignore_shadow)
return (qdf_dma_addr_t)srng->u.dst_ring.tp_addr;
else
return ((struct hif_softc *)hal->hif_handle)->mem_pa +
((unsigned long)srng->u.dst_ring.tp_addr -
(unsigned long)hal->dev_base_addr);
} }
} }

View File

@@ -1431,14 +1431,6 @@ static inline void hal_srng_hw_init(struct hal_soc *hal,
hal_srng_dst_hw_init(hal, srng, idle_check); hal_srng_dst_hw_init(hal, srng, idle_check);
} }
#if defined(CONFIG_SHADOW_V2) || defined(CONFIG_SHADOW_V3)
#define ignore_shadow false
#define CHECK_SHADOW_REGISTERS true
#else
#define ignore_shadow true
#define CHECK_SHADOW_REGISTERS false
#endif
#ifdef WLAN_FEATURE_NEAR_FULL_IRQ #ifdef WLAN_FEATURE_NEAR_FULL_IRQ
/** /**
* hal_srng_is_near_full_irq_supported() - Check if near full irq is * hal_srng_is_near_full_irq_supported() - Check if near full irq is

View File

@@ -442,6 +442,38 @@ struct hif_target_info {
struct hif_opaque_softc { struct hif_opaque_softc {
}; };
/**
* struct hif_ce_ring_info - CE ring information
* @ring_id: ring id
* @ring_dir: ring direction
* @num_entries: number of entries in ring
* @entry_size: ring entry size
* @ring_base_paddr: srng base physical address
* @hp_paddr: head pointer physical address
* @tp_paddr: tail pointer physical address
*/
struct hif_ce_ring_info {
uint8_t ring_id;
uint8_t ring_dir;
uint32_t num_entries;
uint32_t entry_size;
uint64_t ring_base_paddr;
uint64_t hp_paddr;
uint64_t tp_paddr;
};
/**
* struct hif_direct_link_ce_info - Direct Link CE information
* @ce_id: CE ide
* @pipe_dir: Pipe direction
* @ring_info: ring information
*/
struct hif_direct_link_ce_info {
uint8_t ce_id;
uint8_t pipe_dir;
struct hif_ce_ring_info ring_info;
};
/** /**
* enum hif_event_type - Type of DP events to be recorded * enum hif_event_type - Type of DP events to be recorded
* @HIF_EVENT_IRQ_TRIGGER: IRQ trigger event * @HIF_EVENT_IRQ_TRIGGER: IRQ trigger event
@@ -2450,6 +2482,30 @@ QDF_STATUS hif_unregister_umac_reset_handler(struct hif_opaque_softc *hif_scn)
QDF_STATUS QDF_STATUS
hif_set_irq_config_by_ceid(struct hif_opaque_softc *scn, uint8_t ce_id, hif_set_irq_config_by_ceid(struct hif_opaque_softc *scn, uint8_t ce_id,
uint64_t addr, uint32_t data); uint64_t addr, uint32_t data);
/**
* hif_get_direct_link_ce_dest_srng_buffers() - Get Direct Link ce dest srng
* buffer information
* @hif_ctx: hif opaque handle
* @dma_addr: pointer to array of dma addresses
*
* Return: Number of buffers attached to the dest srng.
*/
uint16_t hif_get_direct_link_ce_dest_srng_buffers(struct hif_opaque_softc *scn,
uint64_t **dma_addr);
/**
* hif_get_direct_link_ce_srng_info() - Get Direct Link CE srng information
* @hif_ctx: hif opaque handle
* @info: Direct Link CEs information
* @max_ce_info_len: max array size of ce info
*
* Return: QDF status
*/
QDF_STATUS
hif_get_direct_link_ce_srng_info(struct hif_opaque_softc *scn,
struct hif_direct_link_ce_info *info,
uint8_t max_ce_info_len);
#else #else
static inline QDF_STATUS static inline QDF_STATUS
hif_set_irq_config_by_ceid(struct hif_opaque_softc *scn, uint8_t ce_id, hif_set_irq_config_by_ceid(struct hif_opaque_softc *scn, uint8_t ce_id,
@@ -2457,5 +2513,19 @@ hif_set_irq_config_by_ceid(struct hif_opaque_softc *scn, uint8_t ce_id,
{ {
return QDF_STATUS_SUCCESS; return QDF_STATUS_SUCCESS;
} }
static inline
uint16_t hif_get_direct_link_ce_dest_srng_buffers(struct hif_opaque_softc *scn)
{
return 0;
}
static inline QDF_STATUS
hif_get_direct_link_ce_srng_info(struct hif_opaque_softc *scn,
struct hif_direct_link_ce_info *info,
uint8_t max_ce_info_len)
{
return QDF_STATUS_SUCCESS;
}
#endif #endif
#endif /* _HIF_H_ */ #endif /* _HIF_H_ */

View File

@@ -601,6 +601,11 @@ struct ce_ops {
QDF_STATUS (*ce_set_irq_config_by_ceid)(struct hif_softc *scn, QDF_STATUS (*ce_set_irq_config_by_ceid)(struct hif_softc *scn,
uint8_t ce_id, uint64_t addr, uint8_t ce_id, uint64_t addr,
uint32_t data); uint32_t data);
uint16_t (*ce_get_direct_link_dest_buffers)(struct hif_softc *scn,
uint64_t **dma_addr);
QDF_STATUS (*ce_get_direct_link_ring_info)(struct hif_softc *scn,
struct hif_direct_link_ce_info *info,
uint8_t max_ce_info_len);
#endif #endif
}; };

View File

@@ -5322,5 +5322,36 @@ hif_set_irq_config_by_ceid(struct hif_opaque_softc *scn, uint8_t ce_id,
return QDF_STATUS_E_NOSUPPORT; return QDF_STATUS_E_NOSUPPORT;
} }
uint16_t hif_get_direct_link_ce_dest_srng_buffers(struct hif_opaque_softc *scn,
uint64_t **dma_addr)
{
struct hif_softc *hif_ctx = HIF_GET_SOFTC(scn);
struct HIF_CE_state *hif_state = HIF_GET_CE_STATE(scn);
struct ce_ops *ce_services = hif_state->ce_services;
if (ce_services->ce_get_direct_link_dest_buffers)
return ce_services->ce_get_direct_link_dest_buffers(hif_ctx,
dma_addr);
return 0;
}
QDF_STATUS
hif_get_direct_link_ce_srng_info(struct hif_opaque_softc *scn,
struct hif_direct_link_ce_info *info,
uint8_t max_ce_info_len)
{
struct hif_softc *hif_ctx = HIF_GET_SOFTC(scn);
struct HIF_CE_state *hif_state = HIF_GET_CE_STATE(scn);
struct ce_ops *ce_services = hif_state->ce_services;
if (ce_services->ce_get_direct_link_ring_info)
return ce_services->ce_get_direct_link_ring_info(hif_ctx,
info,
max_ce_info_len);
return QDF_STATUS_E_NOSUPPORT;
}
#endif #endif
#endif #endif

View File

@@ -1153,6 +1153,136 @@ ce_set_srng_msi_irq_config_by_ceid(struct hif_softc *scn, uint8_t ce_id,
return QDF_STATUS_SUCCESS; return QDF_STATUS_SUCCESS;
} }
static
uint16_t ce_get_direct_link_dest_srng_buffers(struct hif_softc *scn,
uint64_t **dma_addr)
{
struct HIF_CE_state *hif_state = HIF_GET_CE_STATE(scn);
struct CE_state *ce_state;
struct service_to_pipe *tgt_svc_cfg;
qdf_nbuf_t nbuf;
uint64_t *nbuf_dmaaddr = NULL;
uint32_t i;
uint32_t j = 0;
tgt_svc_cfg = hif_state->tgt_svc_map;
for (i = 0; i < hif_state->sz_tgt_svc_map; i++) {
if (tgt_svc_cfg[i].service_id != LPASS_DATA_MSG_SVC ||
tgt_svc_cfg[i].pipedir != PIPEDIR_IN)
continue;
ce_state = scn->ce_id_to_state[tgt_svc_cfg[i].pipenum];
if (!ce_state || !ce_state->dest_ring) {
hif_err("Direct Link CE pipe %d not initialized",
tgt_svc_cfg[i].pipenum);
return QDF_STATUS_E_FAILURE;
}
nbuf_dmaaddr = qdf_mem_malloc(sizeof(*nbuf_dmaaddr) *
ce_state->dest_ring->nentries);
if (!nbuf_dmaaddr)
return 0;
for (j = 0; j < ce_state->dest_ring->nentries; j++) {
nbuf = ce_state->dest_ring->per_transfer_context[j];
if (!nbuf)
break;
nbuf_dmaaddr[j] = QDF_NBUF_CB_PADDR(nbuf);
}
break;
}
*dma_addr = nbuf_dmaaddr;
return j;
}
/**
* ce_save_srng_info() - Get and save srng information
* @hif_ctx: hif context
* @srng_info: Direct Link CE srng information
* @srng_ctx: Direct Link CE srng context
*
* Return: QDF status
*/
static void
ce_save_srng_info(struct hif_softc *hif_ctx, struct hif_ce_ring_info *srng_info,
void *srng_ctx)
{
struct hal_srng_params params;
hal_get_srng_params(hif_ctx->hal_soc, srng_ctx, &params);
srng_info->ring_id = params.ring_id;
srng_info->ring_dir = params.ring_dir;
srng_info->num_entries = params.num_entries;
srng_info->entry_size = params.entry_size;
srng_info->ring_base_paddr = params.ring_base_paddr;
srng_info->hp_paddr =
hal_srng_get_hp_addr(hif_ctx->hal_soc, srng_ctx);
srng_info->tp_paddr =
hal_srng_get_tp_addr(hif_ctx->hal_soc, srng_ctx);
}
static
QDF_STATUS ce_get_direct_link_srng_info(struct hif_softc *scn,
struct hif_direct_link_ce_info *info,
uint8_t max_ce_info_len)
{
struct HIF_CE_state *hif_state = HIF_GET_CE_STATE(scn);
struct CE_state *ce_state;
struct service_to_pipe *tgt_svc_cfg;
uint8_t ce_info_idx = 0;
uint32_t i;
tgt_svc_cfg = hif_state->tgt_svc_map;
for (i = 0; i < hif_state->sz_tgt_svc_map; i++) {
if (tgt_svc_cfg[i].service_id != LPASS_DATA_MSG_SVC)
continue;
ce_state = scn->ce_id_to_state[tgt_svc_cfg[i].pipenum];
if (!ce_state) {
hif_err("Direct Link CE pipe %d not initialized",
tgt_svc_cfg[i].pipenum);
return QDF_STATUS_E_FAILURE;
}
if (ce_info_idx > max_ce_info_len)
return QDF_STATUS_E_FAILURE;
info[ce_info_idx].ce_id = ce_state->id;
info[ce_info_idx].pipe_dir = tgt_svc_cfg[i].pipedir;
if (ce_state->src_ring)
ce_save_srng_info(scn, &info[ce_info_idx].ring_info,
ce_state->src_ring->srng_ctx);
else
ce_save_srng_info(scn, &info[ce_info_idx].ring_info,
ce_state->dest_ring->srng_ctx);
ce_info_idx++;
if (!ce_state->status_ring)
continue;
if (ce_info_idx > max_ce_info_len)
return QDF_STATUS_E_FAILURE;
info[ce_info_idx].ce_id = ce_state->id;
info[ce_info_idx].pipe_dir = tgt_svc_cfg[i].pipedir;
ce_save_srng_info(scn, &info[ce_info_idx].ring_info,
ce_state->status_ring->srng_ctx);
ce_info_idx++;
}
return QDF_STATUS_SUCCESS;
}
#endif #endif
static struct ce_ops ce_service_srng = { static struct ce_ops ce_service_srng = {
@@ -1182,6 +1312,8 @@ static struct ce_ops ce_service_srng = {
#endif #endif
#ifdef FEATURE_DIRECT_LINK #ifdef FEATURE_DIRECT_LINK
.ce_set_irq_config_by_ceid = ce_set_srng_msi_irq_config_by_ceid, .ce_set_irq_config_by_ceid = ce_set_srng_msi_irq_config_by_ceid,
.ce_get_direct_link_dest_buffers = ce_get_direct_link_dest_srng_buffers,
.ce_get_direct_link_ring_info = ce_get_direct_link_srng_info,
#endif #endif
}; };