From 46ee7b23462fa7b5281243516bacb83696fa110f Mon Sep 17 00:00:00 2001 From: Pavan Nikhilesh Date: Tue, 6 Apr 2021 20:11:38 +0530 Subject: [PATCH] common/cnxk: add SSO HWS interface Add SSO HWS interface for setting/unsetting links, retrieving base address and nanoseconds to getwork timeout. Signed-off-by: Pavan Nikhilesh Acked-by: Nithin Dabilpuram --- drivers/common/cnxk/roc_sso.c | 128 ++++++++++++++++++++++++++++- drivers/common/cnxk/roc_sso.h | 6 ++ drivers/common/cnxk/roc_sso_priv.h | 3 + drivers/common/cnxk/version.map | 4 + 4 files changed, 140 insertions(+), 1 deletion(-) diff --git a/drivers/common/cnxk/roc_sso.c b/drivers/common/cnxk/roc_sso.c index 6875b08a99..ba9dc3b9df 100644 --- a/drivers/common/cnxk/roc_sso.c +++ b/drivers/common/cnxk/roc_sso.c @@ -152,6 +152,104 @@ sso_rsrc_get(struct roc_sso *roc_sso) return 0; } +static void +sso_hws_link_modify(uint8_t hws, uintptr_t base, struct plt_bitmap *bmp, + uint16_t hwgrp[], uint16_t n, uint16_t enable) +{ + uint64_t reg; + int i, j, k; + + i = 0; + while (n) { + uint64_t mask[4] = { + 0x8000, + 0x8000, + 0x8000, + 0x8000, + }; + + k = n % 4; + k = k ? k : 4; + for (j = 0; j < k; j++) { + mask[j] = hwgrp[i + j] | enable << 14; + enable ? plt_bitmap_set(bmp, hwgrp[i + j]) : + plt_bitmap_clear(bmp, hwgrp[i + j]); + plt_sso_dbg("HWS %d Linked to HWGRP %d", hws, + hwgrp[i + j]); + } + + n -= j; + i += j; + reg = mask[0] | mask[1] << 16 | mask[2] << 32 | mask[3] << 48; + plt_write64(reg, base + SSOW_LF_GWS_GRPMSK_CHG); + } +} + +/* Public Functions. */ +uintptr_t +roc_sso_hws_base_get(struct roc_sso *roc_sso, uint8_t hws) +{ + struct dev *dev = &roc_sso_to_sso_priv(roc_sso)->dev; + + return dev->bar2 + (RVU_BLOCK_ADDR_SSOW << 20 | hws << 12); +} + +uint64_t +roc_sso_ns_to_gw(struct roc_sso *roc_sso, uint64_t ns) +{ + struct dev *dev = &roc_sso_to_sso_priv(roc_sso)->dev; + uint64_t current_us, current_ns, new_ns; + uintptr_t base; + + base = dev->bar2 + (RVU_BLOCK_ADDR_SSOW << 20); + current_us = plt_read64(base + SSOW_LF_GWS_NW_TIM); + /* From HRM, table 14-19: + * The SSOW_LF_GWS_NW_TIM[NW_TIM] period is specified in n-1 notation. + */ + current_us += 1; + + /* From HRM, table 14-1: + * SSOW_LF_GWS_NW_TIM[NW_TIM] specifies the minimum timeout. The SSO + * hardware times out a GET_WORK request within 2 usec of the minimum + * timeout specified by SSOW_LF_GWS_NW_TIM[NW_TIM]. + */ + current_us += 2; + current_ns = current_us * 1E3; + new_ns = (ns - PLT_MIN(ns, current_ns)); + new_ns = !new_ns ? 1 : new_ns; + return (new_ns * plt_tsc_hz()) / 1E9; +} + +int +roc_sso_hws_link(struct roc_sso *roc_sso, uint8_t hws, uint16_t hwgrp[], + uint16_t nb_hwgrp) +{ + struct dev *dev = &roc_sso_to_sso_priv(roc_sso)->dev; + struct sso *sso; + uintptr_t base; + + sso = roc_sso_to_sso_priv(roc_sso); + base = dev->bar2 + (RVU_BLOCK_ADDR_SSOW << 20 | hws << 12); + sso_hws_link_modify(hws, base, sso->link_map[hws], hwgrp, nb_hwgrp, 1); + + return nb_hwgrp; +} + +int +roc_sso_hws_unlink(struct roc_sso *roc_sso, uint8_t hws, uint16_t hwgrp[], + uint16_t nb_hwgrp) +{ + struct dev *dev = &roc_sso_to_sso_priv(roc_sso)->dev; + struct sso *sso; + uintptr_t base; + + sso = roc_sso_to_sso_priv(roc_sso); + base = dev->bar2 + (RVU_BLOCK_ADDR_SSOW << 20 | hws << 12); + sso_hws_link_modify(hws, base, sso->link_map[hws], hwgrp, nb_hwgrp, 0); + + return nb_hwgrp; +} + int roc_sso_rsrc_init(struct roc_sso *roc_sso, uint8_t nb_hws, uint16_t nb_hwgrp) { @@ -225,8 +323,10 @@ int roc_sso_dev_init(struct roc_sso *roc_sso) { struct plt_pci_device *pci_dev; + uint32_t link_map_sz; struct sso *sso; - int rc; + void *link_mem; + int i, rc; if (roc_sso == NULL || roc_sso->pci_dev == NULL) return SSO_ERR_PARAM; @@ -249,12 +349,38 @@ roc_sso_dev_init(struct roc_sso *roc_sso) } rc = -ENOMEM; + sso->link_map = + plt_zmalloc(sizeof(struct plt_bitmap *) * roc_sso->max_hws, 0); + if (sso->link_map == NULL) { + plt_err("Failed to allocate memory for link_map array"); + goto rsrc_fail; + } + + link_map_sz = plt_bitmap_get_memory_footprint(roc_sso->max_hwgrp); + sso->link_map_mem = plt_zmalloc(link_map_sz * roc_sso->max_hws, 0); + if (sso->link_map_mem == NULL) { + plt_err("Failed to get link_map memory"); + goto rsrc_fail; + } + + link_mem = sso->link_map_mem; + for (i = 0; i < roc_sso->max_hws; i++) { + sso->link_map[i] = plt_bitmap_init(roc_sso->max_hwgrp, link_mem, + link_map_sz); + if (sso->link_map[i] == NULL) { + plt_err("Failed to allocate link map"); + goto link_mem_free; + } + link_mem = PLT_PTR_ADD(link_mem, link_map_sz); + } idev_sso_pffunc_set(sso->dev.pf_func); sso->pci_dev = pci_dev; sso->dev.drv_inited = true; roc_sso->lmt_base = sso->dev.lmt_base; return 0; +link_mem_free: + plt_free(sso->link_map_mem); rsrc_fail: rc |= dev_fini(&sso->dev, pci_dev); fail: diff --git a/drivers/common/cnxk/roc_sso.h b/drivers/common/cnxk/roc_sso.h index 4f37f148fa..72360458c1 100644 --- a/drivers/common/cnxk/roc_sso.h +++ b/drivers/common/cnxk/roc_sso.h @@ -30,5 +30,11 @@ int __roc_api roc_sso_dev_fini(struct roc_sso *roc_sso); int __roc_api roc_sso_rsrc_init(struct roc_sso *roc_sso, uint8_t nb_hws, uint16_t nb_hwgrp); void __roc_api roc_sso_rsrc_fini(struct roc_sso *roc_sso); +uint64_t __roc_api roc_sso_ns_to_gw(struct roc_sso *roc_sso, uint64_t ns); +int __roc_api roc_sso_hws_link(struct roc_sso *roc_sso, uint8_t hws, + uint16_t hwgrp[], uint16_t nb_hwgrp); +int __roc_api roc_sso_hws_unlink(struct roc_sso *roc_sso, uint8_t hws, + uint16_t hwgrp[], uint16_t nb_hwgrp); +uintptr_t __roc_api roc_sso_hws_base_get(struct roc_sso *roc_sso, uint8_t hws); #endif /* _ROC_SSOW_H_ */ diff --git a/drivers/common/cnxk/roc_sso_priv.h b/drivers/common/cnxk/roc_sso_priv.h index 1ab3f5b688..ad35be1a42 100644 --- a/drivers/common/cnxk/roc_sso_priv.h +++ b/drivers/common/cnxk/roc_sso_priv.h @@ -13,6 +13,9 @@ struct sso_rsrc { struct sso { struct plt_pci_device *pci_dev; struct dev dev; + /* SSO link mapping. */ + struct plt_bitmap **link_map; + void *link_map_mem; } __plt_cache_aligned; enum sso_err_status { diff --git a/drivers/common/cnxk/version.map b/drivers/common/cnxk/version.map index 054c6bdb8e..8206f0fe62 100644 --- a/drivers/common/cnxk/version.map +++ b/drivers/common/cnxk/version.map @@ -175,6 +175,10 @@ INTERNAL { roc_plt_init_cb_register; roc_sso_dev_fini; roc_sso_dev_init; + roc_sso_hws_base_get; + roc_sso_hws_link; + roc_sso_hws_unlink; + roc_sso_ns_to_gw; roc_sso_rsrc_fini; roc_sso_rsrc_init; -- 2.20.1