common/cnxk: add SSO HWS interface
authorPavan Nikhilesh <pbhagavatula@marvell.com>
Tue, 6 Apr 2021 14:41:38 +0000 (20:11 +0530)
committerJerin Jacob <jerinj@marvell.com>
Fri, 9 Apr 2021 06:32:24 +0000 (08:32 +0200)
Add SSO HWS interface for setting/unsetting links, retrieving
base address and nanoseconds to getwork timeout.

Signed-off-by: Pavan Nikhilesh <pbhagavatula@marvell.com>
Acked-by: Nithin Dabilpuram <ndabilpuram@marvell.com>
drivers/common/cnxk/roc_sso.c
drivers/common/cnxk/roc_sso.h
drivers/common/cnxk/roc_sso_priv.h
drivers/common/cnxk/version.map

index 6875b08..ba9dc3b 100644 (file)
@@ -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:
index 4f37f14..7236045 100644 (file)
@@ -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_ */
index 1ab3f5b..ad35be1 100644 (file)
@@ -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 {
index 054c6bd..8206f0f 100644 (file)
@@ -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;