diff --git a/drivers/net/ethernet/netronome/nfp/nfp_app.c b/drivers/net/ethernet/netronome/nfp/nfp_app.c index de07517da1bd..396b93f54823 100644 --- a/drivers/net/ethernet/netronome/nfp/nfp_app.c +++ b/drivers/net/ethernet/netronome/nfp/nfp_app.c @@ -35,6 +35,7 @@ #include #include "nfpcore/nfp_cpp.h" +#include "nfpcore/nfp_nffw.h" #include "nfp_app.h" #include "nfp_main.h" @@ -43,6 +44,13 @@ static const struct nfp_app_type *apps[] = { &app_bpf, }; +const char *nfp_app_mip_name(struct nfp_app *app) +{ + if (!app || !app->pf->mip) + return ""; + return nfp_mip_name(app->pf->mip); +} + struct sk_buff *nfp_app_ctrl_msg_alloc(struct nfp_app *app, unsigned int size) { struct sk_buff *skb; diff --git a/drivers/net/ethernet/netronome/nfp/nfp_app.h b/drivers/net/ethernet/netronome/nfp/nfp_app.h index 3fbf68f8577c..f5e373fa8c3b 100644 --- a/drivers/net/ethernet/netronome/nfp/nfp_app.h +++ b/drivers/net/ethernet/netronome/nfp/nfp_app.h @@ -216,6 +216,7 @@ static inline void nfp_app_ctrl_rx(struct nfp_app *app, struct sk_buff *skb) app->type->ctrl_msg_rx(app, skb); } +const char *nfp_app_mip_name(struct nfp_app *app); struct sk_buff *nfp_app_ctrl_msg_alloc(struct nfp_app *app, unsigned int size); struct nfp_app *nfp_app_alloc(struct nfp_pf *pf, enum nfp_app_id id); diff --git a/drivers/net/ethernet/netronome/nfp/nfp_app_nic.c b/drivers/net/ethernet/netronome/nfp/nfp_app_nic.c index 1a33ad9f4170..83c65e6291ee 100644 --- a/drivers/net/ethernet/netronome/nfp/nfp_app_nic.c +++ b/drivers/net/ethernet/netronome/nfp/nfp_app_nic.c @@ -80,7 +80,7 @@ int nfp_app_nic_vnic_init(struct nfp_app *app, struct nfp_net *nn, if (err) return err < 0 ? err : 0; - nfp_net_get_mac_addr(nn, app->cpp, id); + nfp_net_get_mac_addr(app->pf, nn, id); return 0; } diff --git a/drivers/net/ethernet/netronome/nfp/nfp_main.c b/drivers/net/ethernet/netronome/nfp/nfp_main.c index 0c2e64d217b5..4e59dcb78c36 100644 --- a/drivers/net/ethernet/netronome/nfp/nfp_main.c +++ b/drivers/net/ethernet/netronome/nfp/nfp_main.c @@ -77,7 +77,7 @@ static int nfp_pcie_sriov_read_nfd_limit(struct nfp_pf *pf) { int err; - pf->limit_vfs = nfp_rtsym_read_le(pf->cpp, "nfd_vf_cfg_max_vfs", &err); + pf->limit_vfs = nfp_rtsym_read_le(pf->rtbl, "nfd_vf_cfg_max_vfs", &err); if (!err) return pci_sriov_set_totalvfs(pf->pdev, pf->limit_vfs); @@ -170,7 +170,7 @@ nfp_net_fw_find(struct pci_dev *pdev, struct nfp_pf *pf) return NULL; } - fw_model = nfp_hwinfo_lookup(pf->cpp, "assembly.partno"); + fw_model = nfp_hwinfo_lookup(pf->hwinfo, "assembly.partno"); if (!fw_model) { dev_err(&pdev->dev, "Error: can't read part number\n"); return NULL; @@ -358,21 +358,26 @@ static int nfp_pci_probe(struct pci_dev *pdev, goto err_disable_msix; } + pf->hwinfo = nfp_hwinfo_read(pf->cpp); + dev_info(&pdev->dev, "Assembly: %s%s%s-%s CPLD: %s\n", - nfp_hwinfo_lookup(pf->cpp, "assembly.vendor"), - nfp_hwinfo_lookup(pf->cpp, "assembly.partno"), - nfp_hwinfo_lookup(pf->cpp, "assembly.serial"), - nfp_hwinfo_lookup(pf->cpp, "assembly.revision"), - nfp_hwinfo_lookup(pf->cpp, "cpld.version")); + nfp_hwinfo_lookup(pf->hwinfo, "assembly.vendor"), + nfp_hwinfo_lookup(pf->hwinfo, "assembly.partno"), + nfp_hwinfo_lookup(pf->hwinfo, "assembly.serial"), + nfp_hwinfo_lookup(pf->hwinfo, "assembly.revision"), + nfp_hwinfo_lookup(pf->hwinfo, "cpld.version")); err = devlink_register(devlink, &pdev->dev); if (err) - goto err_cpp_free; + goto err_hwinfo_free; err = nfp_nsp_init(pdev, pf); if (err) goto err_devlink_unreg; + pf->mip = nfp_mip_open(pf->cpp); + pf->rtbl = __nfp_rtsym_table_read(pf->cpp, pf->mip); + err = nfp_pcie_sriov_read_nfd_limit(pf); if (err) goto err_fw_unload; @@ -394,13 +399,16 @@ static int nfp_pci_probe(struct pci_dev *pdev, err_sriov_unlimit: pci_sriov_set_totalvfs(pf->pdev, 0); err_fw_unload: + kfree(pf->rtbl); + nfp_mip_close(pf->mip); if (pf->fw_loaded) nfp_fw_unload(pf); kfree(pf->eth_tbl); kfree(pf->nspi); err_devlink_unreg: devlink_unregister(devlink); -err_cpp_free: +err_hwinfo_free: + kfree(pf->hwinfo); nfp_cpp_free(pf->cpp); err_disable_msix: pci_set_drvdata(pdev, NULL); @@ -430,10 +438,13 @@ static void nfp_pci_remove(struct pci_dev *pdev) devlink_unregister(devlink); + kfree(pf->rtbl); + nfp_mip_close(pf->mip); if (pf->fw_loaded) nfp_fw_unload(pf); pci_set_drvdata(pdev, NULL); + kfree(pf->hwinfo); nfp_cpp_free(pf->cpp); kfree(pf->eth_tbl); diff --git a/drivers/net/ethernet/netronome/nfp/nfp_main.h b/drivers/net/ethernet/netronome/nfp/nfp_main.h index 37832853b0b3..88724f8d0dcd 100644 --- a/drivers/net/ethernet/netronome/nfp/nfp_main.h +++ b/drivers/net/ethernet/netronome/nfp/nfp_main.h @@ -54,8 +54,11 @@ struct pci_dev; struct nfp_cpp; struct nfp_cpp_area; struct nfp_eth_table; +struct nfp_hwinfo; +struct nfp_mip; struct nfp_net; struct nfp_nsp_identify; +struct nfp_rtsym_table; /** * struct nfp_pf - NFP PF-specific device structure @@ -70,6 +73,9 @@ struct nfp_nsp_identify; * @num_vfs: Number of SR-IOV VFs enabled * @fw_loaded: Is the firmware loaded? * @ctrl_vnic: Pointer to the control vNIC if available + * @mip: MIP handle + * @rtbl: RTsym table + * @hwinfo: HWInfo table * @eth_tbl: NSP ETH table * @nspi: NSP identification info * @hwmon_dev: pointer to hwmon device @@ -101,6 +107,9 @@ struct nfp_pf { struct nfp_net *ctrl_vnic; + const struct nfp_mip *mip; + struct nfp_rtsym_table *rtbl; + struct nfp_hwinfo *hwinfo; struct nfp_eth_table *eth_tbl; struct nfp_nsp_identify *nspi; @@ -130,7 +139,7 @@ void nfp_hwmon_unregister(struct nfp_pf *pf); struct nfp_eth_table_port * nfp_net_find_port(struct nfp_eth_table *eth_tbl, unsigned int id); void -nfp_net_get_mac_addr(struct nfp_net *nn, struct nfp_cpp *cpp, unsigned int id); +nfp_net_get_mac_addr(struct nfp_pf *pf, struct nfp_net *nn, unsigned int id); bool nfp_ctrl_tx(struct nfp_net *nn, struct sk_buff *skb); diff --git a/drivers/net/ethernet/netronome/nfp/nfp_net_ethtool.c b/drivers/net/ethernet/netronome/nfp/nfp_net_ethtool.c index 83664ca25213..6e31355c3567 100644 --- a/drivers/net/ethernet/netronome/nfp/nfp_net_ethtool.c +++ b/drivers/net/ethernet/netronome/nfp/nfp_net_ethtool.c @@ -166,10 +166,10 @@ static void nfp_net_get_drvinfo(struct net_device *netdev, nfp_net_get_nspinfo(nn->app, nsp_version); snprintf(drvinfo->fw_version, sizeof(drvinfo->fw_version), - "%d.%d.%d.%d %s %s", + "%d.%d.%d.%d %s %s %s", nn->fw_ver.resv, nn->fw_ver.class, nn->fw_ver.major, nn->fw_ver.minor, nsp_version, - nfp_app_name(nn->app)); + nfp_app_mip_name(nn->app), nfp_app_name(nn->app)); strlcpy(drvinfo->bus_info, pci_name(nn->pdev), sizeof(drvinfo->bus_info)); diff --git a/drivers/net/ethernet/netronome/nfp/nfp_net_main.c b/drivers/net/ethernet/netronome/nfp/nfp_net_main.c index 5f27703060c2..bc2bc0886176 100644 --- a/drivers/net/ethernet/netronome/nfp/nfp_net_main.c +++ b/drivers/net/ethernet/netronome/nfp/nfp_net_main.c @@ -63,13 +63,13 @@ #define NFP_PF_CSR_SLICE_SIZE (32 * 1024) -static int nfp_is_ready(struct nfp_cpp *cpp) +static int nfp_is_ready(struct nfp_pf *pf) { const char *cp; long state; int err; - cp = nfp_hwinfo_lookup(cpp, "board.state"); + cp = nfp_hwinfo_lookup(pf->hwinfo, "board.state"); if (!cp) return 0; @@ -134,15 +134,15 @@ static u8 __iomem *nfp_net_map_area(struct nfp_cpp *cpp, /** * nfp_net_get_mac_addr() - Get the MAC address. + * @pf: NFP PF handle * @nn: NFP Network structure - * @cpp: NFP CPP handle * @id: NFP port id * * First try to get the MAC address from NSP ETH table. If that * fails try HWInfo. As a last resort generate a random address. */ void -nfp_net_get_mac_addr(struct nfp_net *nn, struct nfp_cpp *cpp, unsigned int id) +nfp_net_get_mac_addr(struct nfp_pf *pf, struct nfp_net *nn, unsigned int id) { struct nfp_eth_table_port *eth_port; struct nfp_net_dp *dp = &nn->dp; @@ -159,7 +159,7 @@ nfp_net_get_mac_addr(struct nfp_net *nn, struct nfp_cpp *cpp, unsigned int id) snprintf(name, sizeof(name), "eth%d.mac", id); - mac_str = nfp_hwinfo_lookup(cpp, name); + mac_str = nfp_hwinfo_lookup(pf->hwinfo, name); if (!mac_str) { dev_warn(dp->dev, "Can't lookup MAC address. Generate\n"); eth_hw_addr_random(dp->netdev); @@ -201,7 +201,7 @@ nfp_net_pf_rtsym_read_optional(struct nfp_pf *pf, const char *format, snprintf(name, sizeof(name), format, nfp_cppcore_pcie_unit(pf->cpp)); - val = nfp_rtsym_read_le(pf->cpp, name, &err); + val = nfp_rtsym_read_le(pf->rtbl, name, &err); if (err) { if (err == -ENOENT) return default_val; @@ -234,7 +234,7 @@ nfp_net_pf_map_rtsym(struct nfp_pf *pf, const char *name, const char *sym_fmt, snprintf(pf_symbol, sizeof(pf_symbol), sym_fmt, nfp_cppcore_pcie_unit(pf->cpp)); - sym = nfp_rtsym_lookup(pf->cpp, pf_symbol); + sym = nfp_rtsym_lookup(pf->rtbl, pf_symbol); if (!sym) { nfp_err(pf->cpp, "Failed to find PF symbol %s\n", pf_symbol); return (u8 __iomem *)ERR_PTR(-ENOENT); @@ -713,7 +713,7 @@ int nfp_net_pci_probe(struct nfp_pf *pf) INIT_WORK(&pf->port_refresh_work, nfp_net_refresh_vnics); /* Verify that the board has completed initialization */ - if (!nfp_is_ready(pf->cpp)) { + if (!nfp_is_ready(pf)) { nfp_err(pf->cpp, "NFP is not ready for NIC operation.\n"); return -EINVAL; } @@ -813,6 +813,7 @@ int nfp_net_pci_probe(struct nfp_pf *pf) nfp_cpp_area_release_free(pf->data_vnic_bar); err_unlock: mutex_unlock(&pf->lock); + cancel_work_sync(&pf->port_refresh_work); return err; } diff --git a/drivers/net/ethernet/netronome/nfp/nfpcore/nfp.h b/drivers/net/ethernet/netronome/nfp/nfpcore/nfp.h index 94641b4c2c55..1a8d04a1e113 100644 --- a/drivers/net/ethernet/netronome/nfp/nfpcore/nfp.h +++ b/drivers/net/ethernet/netronome/nfp/nfpcore/nfp.h @@ -46,7 +46,9 @@ /* Implemented in nfp_hwinfo.c */ -const char *nfp_hwinfo_lookup(struct nfp_cpp *cpp, const char *lookup); +struct nfp_hwinfo; +struct nfp_hwinfo *nfp_hwinfo_read(struct nfp_cpp *cpp); +const char *nfp_hwinfo_lookup(struct nfp_hwinfo *hwinfo, const char *lookup); /* Implemented in nfp_nsp.c, low level functions */ diff --git a/drivers/net/ethernet/netronome/nfp/nfpcore/nfp_cpp.h b/drivers/net/ethernet/netronome/nfp/nfpcore/nfp_cpp.h index 0a46c0984e68..25a967158ce9 100644 --- a/drivers/net/ethernet/netronome/nfp/nfpcore/nfp_cpp.h +++ b/drivers/net/ethernet/netronome/nfp/nfpcore/nfp_cpp.h @@ -222,13 +222,6 @@ u32 nfp_cpp_model(struct nfp_cpp *cpp); u16 nfp_cpp_interface(struct nfp_cpp *cpp); int nfp_cpp_serial(struct nfp_cpp *cpp, const u8 **serial); -void *nfp_hwinfo_cache(struct nfp_cpp *cpp); -void nfp_hwinfo_cache_set(struct nfp_cpp *cpp, void *val); -void *nfp_rtsym_cache(struct nfp_cpp *cpp); -void nfp_rtsym_cache_set(struct nfp_cpp *cpp, void *val); - -void nfp_nffw_cache_flush(struct nfp_cpp *cpp); - struct nfp_cpp_area *nfp_cpp_area_alloc_with_name(struct nfp_cpp *cpp, u32 cpp_id, const char *name, diff --git a/drivers/net/ethernet/netronome/nfp/nfpcore/nfp_cppcore.c b/drivers/net/ethernet/netronome/nfp/nfpcore/nfp_cppcore.c index 5672d309d07d..9b69dcf87be9 100644 --- a/drivers/net/ethernet/netronome/nfp/nfpcore/nfp_cppcore.c +++ b/drivers/net/ethernet/netronome/nfp/nfpcore/nfp_cppcore.c @@ -76,10 +76,6 @@ struct nfp_cpp_resource { * @serial: chip serial number * @imb_cat_table: CPP Mapping Table * - * Following fields can be used only in probe() or with rtnl held: - * @hwinfo: HWInfo database fetched from the device - * @rtsym: firmware run time symbols - * * Following fields use explicit locking: * @resource_list: NFP CPP resource list * @resource_lock: protects @resource_list @@ -107,9 +103,6 @@ struct nfp_cpp { struct mutex area_cache_mutex; struct list_head area_cache_list; - - void *hwinfo; - void *rtsym; }; /* Element of the area_cache_list */ @@ -233,9 +226,6 @@ void nfp_cpp_free(struct nfp_cpp *cpp) if (cpp->op->free) cpp->op->free(cpp); - kfree(cpp->hwinfo); - kfree(cpp->rtsym); - device_unregister(&cpp->dev); kfree(cpp); @@ -276,39 +266,6 @@ int nfp_cpp_serial(struct nfp_cpp *cpp, const u8 **serial) return sizeof(cpp->serial); } -void *nfp_hwinfo_cache(struct nfp_cpp *cpp) -{ - return cpp->hwinfo; -} - -void nfp_hwinfo_cache_set(struct nfp_cpp *cpp, void *val) -{ - cpp->hwinfo = val; -} - -void *nfp_rtsym_cache(struct nfp_cpp *cpp) -{ - return cpp->rtsym; -} - -void nfp_rtsym_cache_set(struct nfp_cpp *cpp, void *val) -{ - cpp->rtsym = val; -} - -/** - * nfp_nffw_cache_flush() - Flush cached firmware information - * @cpp: NFP CPP handle - * - * Flush cached firmware information. This function should be called - * every time firmware is loaded on unloaded. - */ -void nfp_nffw_cache_flush(struct nfp_cpp *cpp) -{ - kfree(nfp_rtsym_cache(cpp)); - nfp_rtsym_cache_set(cpp, NULL); -} - /** * nfp_cpp_area_alloc_with_name() - allocate a new CPP area * @cpp: CPP device handle diff --git a/drivers/net/ethernet/netronome/nfp/nfpcore/nfp_hwinfo.c b/drivers/net/ethernet/netronome/nfp/nfpcore/nfp_hwinfo.c index 8d8f311ffa6e..4f24aff1e772 100644 --- a/drivers/net/ethernet/netronome/nfp/nfpcore/nfp_hwinfo.c +++ b/drivers/net/ethernet/netronome/nfp/nfpcore/nfp_hwinfo.c @@ -178,7 +178,8 @@ hwinfo_db_validate(struct nfp_cpp *cpp, struct nfp_hwinfo *db, u32 len) return hwinfo_db_walk(cpp, db, size); } -static int hwinfo_try_fetch(struct nfp_cpp *cpp, size_t *cpp_size) +static struct nfp_hwinfo * +hwinfo_try_fetch(struct nfp_cpp *cpp, size_t *cpp_size) { struct nfp_hwinfo *header; struct nfp_resource *res; @@ -196,7 +197,7 @@ static int hwinfo_try_fetch(struct nfp_cpp *cpp, size_t *cpp_size) nfp_resource_release(res); if (*cpp_size < HWINFO_SIZE_MIN) - return -ENOENT; + return NULL; } else if (PTR_ERR(res) == -ENOENT) { /* Try getting the HWInfo table from the 'classic' location */ cpp_id = NFP_CPP_ISLAND_ID(NFP_CPP_TARGET_MU, @@ -204,101 +205,86 @@ static int hwinfo_try_fetch(struct nfp_cpp *cpp, size_t *cpp_size) cpp_addr = 0x30000; *cpp_size = 0x0e000; } else { - return PTR_ERR(res); + return NULL; } db = kmalloc(*cpp_size + 1, GFP_KERNEL); if (!db) - return -ENOMEM; + return NULL; err = nfp_cpp_read(cpp, cpp_id, cpp_addr, db, *cpp_size); - if (err != *cpp_size) { - kfree(db); - return err < 0 ? err : -EIO; - } + if (err != *cpp_size) + goto exit_free; header = (void *)db; - if (nfp_hwinfo_is_updating(header)) { - kfree(db); - return -EBUSY; - } + if (nfp_hwinfo_is_updating(header)) + goto exit_free; if (le32_to_cpu(header->version) != NFP_HWINFO_VERSION_2) { nfp_err(cpp, "Unknown HWInfo version: 0x%08x\n", le32_to_cpu(header->version)); - kfree(db); - return -EINVAL; + goto exit_free; } /* NULL-terminate for safety */ db[*cpp_size] = '\0'; - nfp_hwinfo_cache_set(cpp, db); - - return 0; + return (void *)db; +exit_free: + kfree(db); + return NULL; } -static int hwinfo_fetch(struct nfp_cpp *cpp, size_t *hwdb_size) +static struct nfp_hwinfo *hwinfo_fetch(struct nfp_cpp *cpp, size_t *hwdb_size) { const unsigned long wait_until = jiffies + HWINFO_WAIT * HZ; + struct nfp_hwinfo *db; int err; for (;;) { const unsigned long start_time = jiffies; - err = hwinfo_try_fetch(cpp, hwdb_size); - if (!err) - return 0; + db = hwinfo_try_fetch(cpp, hwdb_size); + if (db) + return db; err = msleep_interruptible(100); if (err || time_after(start_time, wait_until)) { nfp_err(cpp, "NFP access error\n"); - return -EIO; + return NULL; } } } -static int nfp_hwinfo_load(struct nfp_cpp *cpp) +struct nfp_hwinfo *nfp_hwinfo_read(struct nfp_cpp *cpp) { struct nfp_hwinfo *db; size_t hwdb_size = 0; int err; - err = hwinfo_fetch(cpp, &hwdb_size); - if (err) - return err; + db = hwinfo_fetch(cpp, &hwdb_size); + if (!db) + return NULL; - db = nfp_hwinfo_cache(cpp); err = hwinfo_db_validate(cpp, db, hwdb_size); if (err) { kfree(db); - nfp_hwinfo_cache_set(cpp, NULL); - return err; + return NULL; } - return 0; + return db; } /** * nfp_hwinfo_lookup() - Find a value in the HWInfo table by name - * @cpp: NFP CPP handle + * @hwinfo: NFP HWinfo table * @lookup: HWInfo name to search for * * Return: Value of the HWInfo name, or NULL */ -const char *nfp_hwinfo_lookup(struct nfp_cpp *cpp, const char *lookup) +const char *nfp_hwinfo_lookup(struct nfp_hwinfo *hwinfo, const char *lookup) { const char *key, *val, *end; - struct nfp_hwinfo *hwinfo; - int err; - - hwinfo = nfp_hwinfo_cache(cpp); - if (!hwinfo) { - err = nfp_hwinfo_load(cpp); - if (err) - return NULL; - hwinfo = nfp_hwinfo_cache(cpp); - } if (!hwinfo || !lookup) return NULL; diff --git a/drivers/net/ethernet/netronome/nfp/nfpcore/nfp_mip.c b/drivers/net/ethernet/netronome/nfp/nfpcore/nfp_mip.c index 3d15dd03647e..5f193fe2d69e 100644 --- a/drivers/net/ethernet/netronome/nfp/nfpcore/nfp_mip.c +++ b/drivers/net/ethernet/netronome/nfp/nfpcore/nfp_mip.c @@ -141,6 +141,8 @@ const struct nfp_mip *nfp_mip_open(struct nfp_cpp *cpp) return NULL; } + mip->name[sizeof(mip->name) - 1] = 0; + return mip; } @@ -149,6 +151,11 @@ void nfp_mip_close(const struct nfp_mip *mip) kfree(mip); } +const char *nfp_mip_name(const struct nfp_mip *mip) +{ + return mip->name; +} + /** * nfp_mip_symtab() - Get the address and size of the MIP symbol table * @mip: MIP handle diff --git a/drivers/net/ethernet/netronome/nfp/nfpcore/nfp_nffw.h b/drivers/net/ethernet/netronome/nfp/nfpcore/nfp_nffw.h index 988badd230d1..d27d29782a12 100644 --- a/drivers/net/ethernet/netronome/nfp/nfpcore/nfp_nffw.h +++ b/drivers/net/ethernet/netronome/nfp/nfpcore/nfp_nffw.h @@ -55,6 +55,7 @@ struct nfp_mip; const struct nfp_mip *nfp_mip_open(struct nfp_cpp *cpp); void nfp_mip_close(const struct nfp_mip *mip); +const char *nfp_mip_name(const struct nfp_mip *mip); void nfp_mip_symtab(const struct nfp_mip *mip, u32 *addr, u32 *size); void nfp_mip_strtab(const struct nfp_mip *mip, u32 *addr, u32 *size); @@ -87,9 +88,16 @@ struct nfp_rtsym { int domain; }; -int nfp_rtsym_count(struct nfp_cpp *cpp); -const struct nfp_rtsym *nfp_rtsym_get(struct nfp_cpp *cpp, int idx); -const struct nfp_rtsym *nfp_rtsym_lookup(struct nfp_cpp *cpp, const char *name); -u64 nfp_rtsym_read_le(struct nfp_cpp *cpp, const char *name, int *error); +struct nfp_rtsym_table; + +struct nfp_rtsym_table *nfp_rtsym_table_read(struct nfp_cpp *cpp); +struct nfp_rtsym_table * +__nfp_rtsym_table_read(struct nfp_cpp *cpp, const struct nfp_mip *mip); +int nfp_rtsym_count(struct nfp_rtsym_table *rtbl); +const struct nfp_rtsym *nfp_rtsym_get(struct nfp_rtsym_table *rtbl, int idx); +const struct nfp_rtsym * +nfp_rtsym_lookup(struct nfp_rtsym_table *rtbl, const char *name); +u64 nfp_rtsym_read_le(struct nfp_rtsym_table *rtbl, const char *name, + int *error); #endif /* NFP_NFFW_H */ diff --git a/drivers/net/ethernet/netronome/nfp/nfpcore/nfp_nsp.c b/drivers/net/ethernet/netronome/nfp/nfpcore/nfp_nsp.c index eefdb756d74e..37364555c42b 100644 --- a/drivers/net/ethernet/netronome/nfp/nfpcore/nfp_nsp.c +++ b/drivers/net/ethernet/netronome/nfp/nfpcore/nfp_nsp.c @@ -474,13 +474,7 @@ int nfp_nsp_wait(struct nfp_nsp *state) int nfp_nsp_device_soft_reset(struct nfp_nsp *state) { - int err; - - err = nfp_nsp_command(state, SPCODE_SOFT_RESET, 0, 0, 0); - - nfp_nffw_cache_flush(state->cpp); - - return err; + return nfp_nsp_command(state, SPCODE_SOFT_RESET, 0, 0, 0); } int nfp_nsp_load_fw(struct nfp_nsp *state, const struct firmware *fw) diff --git a/drivers/net/ethernet/netronome/nfp/nfpcore/nfp_rtsym.c b/drivers/net/ethernet/netronome/nfp/nfpcore/nfp_rtsym.c index 0e3870ecfb8c..203f9cbae0fb 100644 --- a/drivers/net/ethernet/netronome/nfp/nfpcore/nfp_rtsym.c +++ b/drivers/net/ethernet/netronome/nfp/nfpcore/nfp_rtsym.c @@ -65,7 +65,8 @@ struct nfp_rtsym_entry { __le32 size_lo; }; -struct nfp_rtsym_cache { +struct nfp_rtsym_table { + struct nfp_cpp *cpp; int num; char *strtab; struct nfp_rtsym symtab[]; @@ -78,7 +79,7 @@ static int nfp_meid(u8 island_id, u8 menum) } static void -nfp_rtsym_sw_entry_init(struct nfp_rtsym_cache *cache, u32 strtab_size, +nfp_rtsym_sw_entry_init(struct nfp_rtsym_table *cache, u32 strtab_size, struct nfp_rtsym *sw, struct nfp_rtsym_entry *fw) { sw->type = fw->type; @@ -106,26 +107,36 @@ nfp_rtsym_sw_entry_init(struct nfp_rtsym_cache *cache, u32 strtab_size, sw->domain = -1; } -static int nfp_rtsymtab_probe(struct nfp_cpp *cpp) +struct nfp_rtsym_table *nfp_rtsym_table_read(struct nfp_cpp *cpp) +{ + struct nfp_rtsym_table *rtbl; + const struct nfp_mip *mip; + + mip = nfp_mip_open(cpp); + rtbl = __nfp_rtsym_table_read(cpp, mip); + nfp_mip_close(mip); + + return rtbl; +} + +struct nfp_rtsym_table * +__nfp_rtsym_table_read(struct nfp_cpp *cpp, const struct nfp_mip *mip) { const u32 dram = NFP_CPP_ID(NFP_CPP_TARGET_MU, NFP_CPP_ACTION_RW, 0) | NFP_ISL_EMEM0; u32 strtab_addr, symtab_addr, strtab_size, symtab_size; struct nfp_rtsym_entry *rtsymtab; - struct nfp_rtsym_cache *cache; - const struct nfp_mip *mip; + struct nfp_rtsym_table *cache; int err, n, size; - mip = nfp_mip_open(cpp); if (!mip) - return -EIO; + return NULL; nfp_mip_strtab(mip, &strtab_addr, &strtab_size); nfp_mip_symtab(mip, &symtab_addr, &symtab_size); - nfp_mip_close(mip); if (!symtab_size || !strtab_size || symtab_size % sizeof(*rtsymtab)) - return -ENXIO; + return NULL; /* Align to 64 bits */ symtab_size = round_up(symtab_size, 8); @@ -133,27 +144,26 @@ static int nfp_rtsymtab_probe(struct nfp_cpp *cpp) rtsymtab = kmalloc(symtab_size, GFP_KERNEL); if (!rtsymtab) - return -ENOMEM; + return NULL; size = sizeof(*cache); size += symtab_size / sizeof(*rtsymtab) * sizeof(struct nfp_rtsym); size += strtab_size + 1; cache = kmalloc(size, GFP_KERNEL); - if (!cache) { - err = -ENOMEM; - goto err_free_rtsym_raw; - } + if (!cache) + goto exit_free_rtsym_raw; + cache->cpp = cpp; cache->num = symtab_size / sizeof(*rtsymtab); cache->strtab = (void *)&cache->symtab[cache->num]; err = nfp_cpp_read(cpp, dram, symtab_addr, rtsymtab, symtab_size); if (err != symtab_size) - goto err_free_cache; + goto exit_free_cache; err = nfp_cpp_read(cpp, dram, strtab_addr, cache->strtab, strtab_size); if (err != strtab_size) - goto err_free_cache; + goto exit_free_cache; cache->strtab[strtab_size] = '\0'; for (n = 0; n < cache->num; n++) @@ -161,97 +171,71 @@ static int nfp_rtsymtab_probe(struct nfp_cpp *cpp) &cache->symtab[n], &rtsymtab[n]); kfree(rtsymtab); - nfp_rtsym_cache_set(cpp, cache); - return 0; -err_free_cache: + return cache; + +exit_free_cache: kfree(cache); -err_free_rtsym_raw: +exit_free_rtsym_raw: kfree(rtsymtab); - return err; -} - -static struct nfp_rtsym_cache *nfp_rtsym(struct nfp_cpp *cpp) -{ - struct nfp_rtsym_cache *cache; - int err; - - cache = nfp_rtsym_cache(cpp); - if (cache) - return cache; - - err = nfp_rtsymtab_probe(cpp); - if (err < 0) - return ERR_PTR(err); - - return nfp_rtsym_cache(cpp); + return NULL; } /** * nfp_rtsym_count() - Get the number of RTSYM descriptors - * @cpp: NFP CPP handle + * @rtbl: NFP RTsym table * - * Return: Number of RTSYM descriptors, or -ERRNO + * Return: Number of RTSYM descriptors */ -int nfp_rtsym_count(struct nfp_cpp *cpp) +int nfp_rtsym_count(struct nfp_rtsym_table *rtbl) { - struct nfp_rtsym_cache *cache; - - cache = nfp_rtsym(cpp); - if (IS_ERR(cache)) - return PTR_ERR(cache); - - return cache->num; + if (!rtbl) + return -EINVAL; + return rtbl->num; } /** * nfp_rtsym_get() - Get the Nth RTSYM descriptor - * @cpp: NFP CPP handle + * @rtbl: NFP RTsym table * @idx: Index (0-based) of the RTSYM descriptor * * Return: const pointer to a struct nfp_rtsym descriptor, or NULL */ -const struct nfp_rtsym *nfp_rtsym_get(struct nfp_cpp *cpp, int idx) +const struct nfp_rtsym *nfp_rtsym_get(struct nfp_rtsym_table *rtbl, int idx) { - struct nfp_rtsym_cache *cache; - - cache = nfp_rtsym(cpp); - if (IS_ERR(cache)) + if (!rtbl) + return NULL; + if (idx >= rtbl->num) return NULL; - if (idx >= cache->num) - return NULL; - - return &cache->symtab[idx]; + return &rtbl->symtab[idx]; } /** * nfp_rtsym_lookup() - Return the RTSYM descriptor for a symbol name - * @cpp: NFP CPP handle + * @rtbl: NFP RTsym table * @name: Symbol name * * Return: const pointer to a struct nfp_rtsym descriptor, or NULL */ -const struct nfp_rtsym *nfp_rtsym_lookup(struct nfp_cpp *cpp, const char *name) +const struct nfp_rtsym * +nfp_rtsym_lookup(struct nfp_rtsym_table *rtbl, const char *name) { - struct nfp_rtsym_cache *cache; int n; - cache = nfp_rtsym(cpp); - if (IS_ERR(cache)) + if (!rtbl) return NULL; - for (n = 0; n < cache->num; n++) { - if (strcmp(name, cache->symtab[n].name) == 0) - return &cache->symtab[n]; - } + for (n = 0; n < rtbl->num; n++) + if (strcmp(name, rtbl->symtab[n].name) == 0) + return &rtbl->symtab[n]; return NULL; } /** * nfp_rtsym_read_le() - Read a simple unsigned scalar value from symbol - * @cpp: NFP CPP handle + * @rtbl: NFP RTsym table * @name: Symbol name * @error: Poniter to error code (optional) * @@ -261,14 +245,15 @@ const struct nfp_rtsym *nfp_rtsym_lookup(struct nfp_cpp *cpp, const char *name) * * Return: value read, on error sets the error and returns ~0ULL. */ -u64 nfp_rtsym_read_le(struct nfp_cpp *cpp, const char *name, int *error) +u64 nfp_rtsym_read_le(struct nfp_rtsym_table *rtbl, const char *name, + int *error) { const struct nfp_rtsym *sym; u32 val32, id; u64 val; int err; - sym = nfp_rtsym_lookup(cpp, name); + sym = nfp_rtsym_lookup(rtbl, name); if (!sym) { err = -ENOENT; goto exit; @@ -278,14 +263,14 @@ u64 nfp_rtsym_read_le(struct nfp_cpp *cpp, const char *name, int *error) switch (sym->size) { case 4: - err = nfp_cpp_readl(cpp, id, sym->addr, &val32); + err = nfp_cpp_readl(rtbl->cpp, id, sym->addr, &val32); val = val32; break; case 8: - err = nfp_cpp_readq(cpp, id, sym->addr, &val); + err = nfp_cpp_readq(rtbl->cpp, id, sym->addr, &val); break; default: - nfp_err(cpp, + nfp_err(rtbl->cpp, "rtsym '%s' unsupported or non-scalar size: %lld\n", name, sym->size); err = -EINVAL;