diff options
Diffstat (limited to 'drivers/net/octeontx2/rvu_af.c')
-rw-r--r-- | drivers/net/octeontx2/rvu_af.c | 171 |
1 files changed, 171 insertions, 0 deletions
diff --git a/drivers/net/octeontx2/rvu_af.c b/drivers/net/octeontx2/rvu_af.c new file mode 100644 index 0000000000..7750089a20 --- /dev/null +++ b/drivers/net/octeontx2/rvu_af.c @@ -0,0 +1,171 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Copyright (C) 2018 Marvell International Ltd. + */ + +#include <dm.h> +#include <errno.h> +#include <malloc.h> +#include <misc.h> +#include <net.h> +#include <pci_ids.h> +#include <linux/list.h> +#include <asm/io.h> +#include <asm/arch/board.h> +#include <asm/arch/csrs/csrs-npa.h> + +#include "nix.h" + +struct udevice *rvu_af_dev; + +inline struct rvu_af *get_af(void) +{ + return rvu_af_dev ? dev_get_priv(rvu_af_dev) : NULL; +} + +void rvu_get_lfid_for_pf(int pf, int *nixid, int *npaid) +{ + union nixx_af_rvu_lf_cfg_debug nix_lf_dbg; + union npa_af_rvu_lf_cfg_debug npa_lf_dbg; + union rvu_pf_func_s pf_func; + struct rvu_af *af = dev_get_priv(rvu_af_dev); + struct nix_af *nix_af = af->nix_af; + + pf_func.u = 0; + pf_func.s.pf = pf; + + nix_lf_dbg.u = 0; + nix_lf_dbg.s.pf_func = pf_func.u & 0xFFFF; + nix_lf_dbg.s.exec = 1; + nix_af_reg_write(nix_af, NIXX_AF_RVU_LF_CFG_DEBUG(), + nix_lf_dbg.u); + do { + nix_lf_dbg.u = nix_af_reg_read(nix_af, + NIXX_AF_RVU_LF_CFG_DEBUG()); + } while (nix_lf_dbg.s.exec); + + if (nix_lf_dbg.s.lf_valid) + *nixid = nix_lf_dbg.s.lf; + + debug("%s: nix lf_valid %d lf %d nixid %d\n", __func__, + nix_lf_dbg.s.lf_valid, nix_lf_dbg.s.lf, *nixid); + + npa_lf_dbg.u = 0; + npa_lf_dbg.s.pf_func = pf_func.u & 0xFFFF; + npa_lf_dbg.s.exec = 1; + npa_af_reg_write(nix_af->npa_af, NPA_AF_RVU_LF_CFG_DEBUG(), + npa_lf_dbg.u); + do { + npa_lf_dbg.u = npa_af_reg_read(nix_af->npa_af, + NPA_AF_RVU_LF_CFG_DEBUG()); + } while (npa_lf_dbg.s.exec); + + if (npa_lf_dbg.s.lf_valid) + *npaid = npa_lf_dbg.s.lf; + debug("%s: npa lf_valid %d lf %d npaid %d\n", __func__, + npa_lf_dbg.s.lf_valid, npa_lf_dbg.s.lf, *npaid); +} + +struct nix_af *rvu_af_init(struct rvu_af *rvu_af) +{ + struct nix_af *nix_af; + union rvu_af_addr_s block_addr; + int err; + + nix_af = (struct nix_af *)calloc(1, sizeof(struct nix_af)); + if (!nix_af) { + printf("%s: out of memory\n", __func__); + goto error; + } + + nix_af->dev = rvu_af->dev; + + block_addr.u = 0; + block_addr.s.block = RVU_BLOCK_ADDR_E_NIXX(0); + nix_af->nix_af_base = rvu_af->af_base + block_addr.u; + + nix_af->npa_af = (struct npa_af *)calloc(1, sizeof(struct npa_af)); + if (!nix_af->npa_af) { + printf("%s: out of memory\n", __func__); + goto error; + } + + block_addr.u = 0; + block_addr.s.block = RVU_BLOCK_ADDR_E_NPA; + nix_af->npa_af->npa_af_base = rvu_af->af_base + block_addr.u; + + block_addr.u = 0; + block_addr.s.block = RVU_BLOCK_ADDR_E_NPC; + nix_af->npc_af_base = rvu_af->af_base + block_addr.u; + + debug("%s: Setting up npa admin\n", __func__); + err = npa_af_setup(nix_af->npa_af); + if (err) { + printf("%s: Error %d setting up NPA admin\n", __func__, err); + goto error; + } + debug("%s: Setting up nix af\n", __func__); + err = nix_af_setup(nix_af); + if (err) { + printf("%s: Error %d setting up NIX admin\n", __func__, err); + goto error; + } + debug("%s: nix_af: %p\n", __func__, nix_af); + return nix_af; + +error: + if (nix_af->npa_af) { + free(nix_af->npa_af); + memset(nix_af, 0, sizeof(*nix_af)); + } + if (nix_af) + free(nix_af); + return NULL; +} + +int rvu_af_probe(struct udevice *dev) +{ + struct rvu_af *af_ptr = dev_get_priv(dev); + + af_ptr->af_base = dm_pci_map_bar(dev, PCI_BASE_ADDRESS_0, + PCI_REGION_MEM); + debug("%s RVU AF BAR %p\n", __func__, af_ptr->af_base); + af_ptr->dev = dev; + rvu_af_dev = dev; + + af_ptr->nix_af = rvu_af_init(af_ptr); + if (!af_ptr->nix_af) { + printf("%s: Error: could not initialize NIX AF\n", __func__); + return -1; + } + debug("%s: Done\n", __func__); + + return 0; +} + +int rvu_af_remove(struct udevice *dev) +{ + struct rvu_af *rvu_af = dev_get_priv(dev); + + nix_af_shutdown(rvu_af->nix_af); + npa_af_shutdown(rvu_af->nix_af->npa_af); + npc_af_shutdown(rvu_af->nix_af); + + debug("%s: rvu af down --\n", __func__); + return 0; +} + +U_BOOT_DRIVER(rvu_af) = { + .name = "rvu_af", + .id = UCLASS_MISC, + .probe = rvu_af_probe, + .remove = rvu_af_remove, + .priv_auto_alloc_size = sizeof(struct rvu_af), +}; + +static struct pci_device_id rvu_af_supported[] = { + { PCI_VDEVICE(CAVIUM, PCI_DEVICE_ID_CAVIUM_RVU_AF) }, + {} +}; + +U_BOOT_PCI_DEVICE(rvu_af, rvu_af_supported); |