common/cnxk: support SSO IRQ

Add support to registering and un-registering SSO HWS and
HWGRP IRQs.

Signed-off-by: Pavan Nikhilesh <pbhagavatula@marvell.com>
Acked-by: Nithin Dabilpuram <ndabilpuram@marvell.com>
This commit is contained in:
Pavan Nikhilesh 2021-04-06 20:11:40 +05:30 committed by Jerin Jacob
parent 111a612205
commit 84ed1a5b4b
4 changed files with 220 additions and 0 deletions

View File

@ -40,5 +40,6 @@ sources = files('roc_dev.c',
'roc_npc_utils.c',
'roc_platform.c',
'roc_sso.c',
'roc_sso_irq.c',
'roc_utils.c')
includes += include_directories('../../bus/pci')

View File

@ -185,6 +185,27 @@ sso_hws_link_modify(uint8_t hws, uintptr_t base, struct plt_bitmap *bmp,
}
}
static int
sso_msix_fill(struct roc_sso *roc_sso, uint16_t nb_hws, uint16_t nb_hwgrp)
{
struct sso *sso = roc_sso_to_sso_priv(roc_sso);
struct msix_offset_rsp *rsp;
struct dev *dev = &sso->dev;
int i, rc;
mbox_alloc_msg_msix_offset(dev->mbox);
rc = mbox_process_msg(dev->mbox, (void **)&rsp);
if (rc < 0)
return rc;
for (i = 0; i < nb_hws; i++)
sso->hws_msix_offset[i] = rsp->ssow_msixoff[i];
for (i = 0; i < nb_hwgrp; i++)
sso->hwgrp_msix_offset[i] = rsp->sso_msixoff[i];
return 0;
}
/* Public Functions. */
uintptr_t
roc_sso_hws_base_get(struct roc_sso *roc_sso, uint8_t hws)
@ -363,6 +384,7 @@ roc_sso_hwgrp_set_priority(struct roc_sso *roc_sso, uint16_t hwgrp,
int
roc_sso_rsrc_init(struct roc_sso *roc_sso, uint8_t nb_hws, uint16_t nb_hwgrp)
{
struct sso *sso = roc_sso_to_sso_priv(roc_sso);
struct sso_lf_alloc_rsp *rsp_hwgrp;
int rc;
@ -400,10 +422,25 @@ roc_sso_rsrc_init(struct roc_sso *roc_sso, uint8_t nb_hws, uint16_t nb_hwgrp)
roc_sso->xae_waes = rsp_hwgrp->xaq_wq_entries;
roc_sso->iue = rsp_hwgrp->in_unit_entries;
rc = sso_msix_fill(roc_sso, nb_hws, nb_hwgrp);
if (rc < 0) {
plt_err("Unable to get MSIX offsets for SSO LFs");
goto sso_msix_fail;
}
rc = sso_register_irqs_priv(roc_sso, &sso->pci_dev->intr_handle, nb_hws,
nb_hwgrp);
if (rc < 0) {
plt_err("Failed to register SSO LF IRQs");
goto sso_msix_fail;
}
roc_sso->nb_hwgrp = nb_hwgrp;
roc_sso->nb_hws = nb_hws;
return 0;
sso_msix_fail:
sso_lf_free(roc_sso, SSO_LF_TYPE_HWGRP, nb_hwgrp);
hwgrp_alloc_fail:
sso_lf_free(roc_sso, SSO_LF_TYPE_HWS, nb_hws);
hws_alloc_fail:
@ -416,9 +453,13 @@ roc_sso_rsrc_init(struct roc_sso *roc_sso, uint8_t nb_hws, uint16_t nb_hwgrp)
void
roc_sso_rsrc_fini(struct roc_sso *roc_sso)
{
struct sso *sso = roc_sso_to_sso_priv(roc_sso);
if (!roc_sso->nb_hws && !roc_sso->nb_hwgrp)
return;
sso_unregister_irqs_priv(roc_sso, &sso->pci_dev->intr_handle,
roc_sso->nb_hws, roc_sso->nb_hwgrp);
sso_lf_free(roc_sso, SSO_LF_TYPE_HWS, roc_sso->nb_hws);
sso_lf_free(roc_sso, SSO_LF_TYPE_HWGRP, roc_sso->nb_hwgrp);

View File

@ -0,0 +1,164 @@
/* SPDX-License-Identifier: BSD-3-Clause
* Copyright(C) 2021 Marvell.
*/
#include "roc_api.h"
#include "roc_priv.h"
static void
sso_hwgrp_irq(void *param)
{
struct sso_rsrc *rsrc = param;
uint64_t intr;
intr = plt_read64(rsrc->base + SSO_LF_GGRP_INT);
if (intr == 0)
return;
plt_err("GGRP %d GGRP_INT=0x%" PRIx64 "", rsrc->rsrc_id, intr);
/* Clear interrupt */
plt_write64(intr, rsrc->base + SSO_LF_GGRP_INT);
}
static int
sso_hwgrp_register_irq(struct plt_intr_handle *handle, uint16_t ggrp_msixoff,
struct sso_rsrc *rsrc)
{
int rc, vec;
vec = ggrp_msixoff + SSO_LF_INT_VEC_GRP;
/* Clear err interrupt */
plt_write64(~0ull, rsrc->base + SSO_LF_GGRP_INT_ENA_W1C);
/* Set used interrupt vectors */
rc = dev_irq_register(handle, sso_hwgrp_irq, (void *)rsrc, vec);
/* Enable hw interrupt */
plt_write64(~0ull, rsrc->base + SSO_LF_GGRP_INT_ENA_W1S);
return rc;
}
static void
sso_hws_irq(void *param)
{
struct sso_rsrc *rsrc = param;
uint64_t intr;
intr = plt_read64(rsrc->base + SSOW_LF_GWS_INT);
if (intr == 0)
return;
plt_err("GWS %d GWS_INT=0x%" PRIx64 "", rsrc->rsrc_id, intr);
/* Clear interrupt */
plt_write64(intr, rsrc->base + SSOW_LF_GWS_INT);
}
static int
sso_hws_register_irq(struct plt_intr_handle *handle, uint16_t hws_msixoff,
struct sso_rsrc *rsrc)
{
int rc, vec;
vec = hws_msixoff + SSOW_LF_INT_VEC_IOP;
/* Clear err interrupt */
plt_write64(~0ull, rsrc->base + SSOW_LF_GWS_INT_ENA_W1C);
/* Set used interrupt vectors */
rc = dev_irq_register(handle, sso_hws_irq, (void *)rsrc, vec);
/* Enable hw interrupt */
plt_write64(~0ull, rsrc->base + SSOW_LF_GWS_INT_ENA_W1S);
return rc;
}
int
sso_register_irqs_priv(struct roc_sso *roc_sso, struct plt_intr_handle *handle,
uint16_t nb_hws, uint16_t nb_hwgrp)
{
struct sso *sso = roc_sso_to_sso_priv(roc_sso);
struct dev *dev = &sso->dev;
int i, rc = SSO_ERR_PARAM;
for (i = 0; i < nb_hws; i++) {
if (sso->hws_msix_offset[i] == MSIX_VECTOR_INVALID) {
plt_err("Invalid SSO HWS MSIX offset[%d] vector 0x%x",
i, sso->hws_msix_offset[i]);
goto fail;
}
}
for (i = 0; i < nb_hwgrp; i++) {
if (sso->hwgrp_msix_offset[i] == MSIX_VECTOR_INVALID) {
plt_err("Invalid SSO HWGRP MSIX offset[%d] vector 0x%x",
i, sso->hwgrp_msix_offset[i]);
goto fail;
}
}
for (i = 0; i < nb_hws; i++) {
uintptr_t base =
dev->bar2 + (RVU_BLOCK_ADDR_SSOW << 20 | i << 12);
sso->hws_rsrc[i].rsrc_id = i;
sso->hws_rsrc[i].base = base;
rc = sso_hws_register_irq(handle, sso->hws_msix_offset[i],
&sso->hws_rsrc[i]);
}
for (i = 0; i < nb_hwgrp; i++) {
uintptr_t base =
dev->bar2 + (RVU_BLOCK_ADDR_SSO << 20 | i << 12);
sso->hwgrp_rsrc[i].rsrc_id = i;
sso->hwgrp_rsrc[i].base = base;
rc = sso_hwgrp_register_irq(handle, sso->hwgrp_msix_offset[i],
&sso->hwgrp_rsrc[i]);
}
fail:
return rc;
}
static void
sso_hwgrp_unregister_irq(struct plt_intr_handle *handle, uint16_t ggrp_msixoff,
struct sso_rsrc *rsrc)
{
int vec;
vec = ggrp_msixoff + SSO_LF_INT_VEC_GRP;
/* Clear err interrupt */
plt_write64(~0ull, rsrc->base + SSO_LF_GGRP_INT_ENA_W1C);
dev_irq_unregister(handle, sso_hwgrp_irq, (void *)rsrc, vec);
}
static void
sso_hws_unregister_irq(struct plt_intr_handle *handle, uint16_t gws_msixoff,
struct sso_rsrc *rsrc)
{
int vec;
vec = gws_msixoff + SSOW_LF_INT_VEC_IOP;
/* Clear err interrupt */
plt_write64(~0ull, rsrc->base + SSOW_LF_GWS_INT_ENA_W1C);
dev_irq_unregister(handle, sso_hws_irq, (void *)rsrc, vec);
}
void
sso_unregister_irqs_priv(struct roc_sso *roc_sso,
struct plt_intr_handle *handle, uint16_t nb_hws,
uint16_t nb_hwgrp)
{
struct sso *sso = roc_sso_to_sso_priv(roc_sso);
int i;
for (i = 0; i < nb_hwgrp; i++)
sso_hwgrp_unregister_irq(handle, sso->hwgrp_msix_offset[i],
&sso->hwgrp_rsrc[i]);
for (i = 0; i < nb_hws; i++)
sso_hws_unregister_irq(handle, sso->hws_msix_offset[i],
&sso->hws_rsrc[i]);
}

View File

@ -13,6 +13,12 @@ struct sso_rsrc {
struct sso {
struct plt_pci_device *pci_dev;
struct dev dev;
/* Interrupt handler args. */
struct sso_rsrc hws_rsrc[MAX_RVU_BLKLF_CNT];
struct sso_rsrc hwgrp_rsrc[MAX_RVU_BLKLF_CNT];
/* MSIX offsets */
uint16_t hws_msix_offset[MAX_RVU_BLKLF_CNT];
uint16_t hwgrp_msix_offset[MAX_RVU_BLKLF_CNT];
/* SSO link mapping. */
struct plt_bitmap **link_map;
void *link_map_mem;
@ -33,4 +39,12 @@ roc_sso_to_sso_priv(struct roc_sso *roc_sso)
return (struct sso *)&roc_sso->reserved[0];
}
/* SSO IRQ */
int sso_register_irqs_priv(struct roc_sso *roc_sso,
struct plt_intr_handle *handle, uint16_t nb_hws,
uint16_t nb_hwgrp);
void sso_unregister_irqs_priv(struct roc_sso *roc_sso,
struct plt_intr_handle *handle, uint16_t nb_hws,
uint16_t nb_hwgrp);
#endif /* _ROC_SSO_PRIV_H_ */