nfp: refine the ABI of getting `sp_indiff` info
authorYinjun Zhang <yinjun.zhang@corigine.com>
Thu, 29 Sep 2022 08:58:30 +0000 (10:58 +0200)
committerJakub Kicinski <kuba@kernel.org>
Sat, 1 Oct 2022 01:47:52 +0000 (18:47 -0700)
Considering that whether application firmware is indifferent to
port speed is a firmware property instead of port property, now use
a new rtsym to get the property instead of parsing per-port tlv caps.
With this change, relevant code is moved to `nfp_main` layer.

Signed-off-by: Yinjun Zhang <yinjun.zhang@corigine.com>
Signed-off-by: Simon Horman <simon.horman@corigine.com>
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
drivers/net/ethernet/netronome/nfp/nfp_main.c
drivers/net/ethernet/netronome/nfp/nfp_main.h
drivers/net/ethernet/netronome/nfp/nfp_net_ctrl.c
drivers/net/ethernet/netronome/nfp/nfp_net_ctrl.h
drivers/net/ethernet/netronome/nfp/nfp_net_main.c

index 873429f7a6daeca8ad6db3c0590eb098e032f23f..91063f19c97df00f518aaacd3a9119008002b129 100644 (file)
@@ -691,6 +691,64 @@ static int nfp_pf_find_rtsyms(struct nfp_pf *pf)
        return 0;
 }
 
+int nfp_net_pf_get_app_id(struct nfp_pf *pf)
+{
+       return nfp_pf_rtsym_read_optional(pf, "_pf%u_net_app_id",
+                                         NFP_APP_CORE_NIC);
+}
+
+static u64 nfp_net_pf_get_app_cap(struct nfp_pf *pf)
+{
+       char name[32];
+       int err = 0;
+       u64 val;
+
+       snprintf(name, sizeof(name), "_pf%u_net_app_cap", nfp_cppcore_pcie_unit(pf->cpp));
+
+       val = nfp_rtsym_read_le(pf->rtbl, name, &err);
+       if (err) {
+               if (err != -ENOENT)
+                       nfp_err(pf->cpp, "Unable to read symbol %s\n", name);
+
+               return 0;
+       }
+
+       return val;
+}
+
+static int nfp_pf_cfg_hwinfo(struct nfp_pf *pf, bool sp_indiff)
+{
+       struct nfp_nsp *nsp;
+       char hwinfo[32];
+       int err;
+
+       nsp = nfp_nsp_open(pf->cpp);
+       if (IS_ERR(nsp))
+               return PTR_ERR(nsp);
+
+       snprintf(hwinfo, sizeof(hwinfo), "sp_indiff=%d", sp_indiff);
+       err = nfp_nsp_hwinfo_set(nsp, hwinfo, sizeof(hwinfo));
+       /* Not a fatal error, no need to return error to stop driver from loading */
+       if (err)
+               nfp_warn(pf->cpp, "HWinfo(sp_indiff=%d) set failed: %d\n", sp_indiff, err);
+
+       nfp_nsp_close(nsp);
+       return 0;
+}
+
+static int nfp_pf_nsp_cfg(struct nfp_pf *pf)
+{
+       bool sp_indiff = (nfp_net_pf_get_app_id(pf) == NFP_APP_FLOWER_NIC) ||
+                        (nfp_net_pf_get_app_cap(pf) & NFP_NET_APP_CAP_SP_INDIFF);
+
+       return nfp_pf_cfg_hwinfo(pf, sp_indiff);
+}
+
+static void nfp_pf_nsp_clean(struct nfp_pf *pf)
+{
+       nfp_pf_cfg_hwinfo(pf, false);
+}
+
 static int nfp_pci_probe(struct pci_dev *pdev,
                         const struct pci_device_id *pci_id)
 {
@@ -791,10 +849,14 @@ static int nfp_pci_probe(struct pci_dev *pdev,
                goto err_fw_unload;
        }
 
-       err = nfp_net_pci_probe(pf);
+       err = nfp_pf_nsp_cfg(pf);
        if (err)
                goto err_fw_unload;
 
+       err = nfp_net_pci_probe(pf);
+       if (err)
+               goto err_nsp_clean;
+
        err = nfp_hwmon_register(pf);
        if (err) {
                dev_err(&pdev->dev, "Failed to register hwmon info\n");
@@ -805,6 +867,8 @@ static int nfp_pci_probe(struct pci_dev *pdev,
 
 err_net_remove:
        nfp_net_pci_remove(pf);
+err_nsp_clean:
+       nfp_pf_nsp_clean(pf);
 err_fw_unload:
        kfree(pf->rtbl);
        nfp_mip_close(pf->mip);
@@ -844,6 +908,7 @@ static void __nfp_pci_shutdown(struct pci_dev *pdev, bool unload_fw)
 
        nfp_net_pci_remove(pf);
 
+       nfp_pf_nsp_clean(pf);
        vfree(pf->dumpspec);
        kfree(pf->rtbl);
        nfp_mip_close(pf->mip);
index 6805af186f1ba19824244eb0f8c1ab0ac0fcd5a1..afd3edfa242832a9a415982b34da5514f59f9df7 100644 (file)
@@ -65,7 +65,6 @@ struct nfp_dumpspec {
  * @num_vfs:           Number of SR-IOV VFs enabled
  * @fw_loaded:         Is the firmware loaded?
  * @unload_fw_on_remove:Do we need to unload firmware on driver removal?
- * @sp_indiff:         Is the firmware indifferent to physical port speed?
  * @ctrl_vnic:         Pointer to the control vNIC if available
  * @mip:               MIP handle
  * @rtbl:              RTsym table
@@ -115,7 +114,6 @@ struct nfp_pf {
 
        bool fw_loaded;
        bool unload_fw_on_remove;
-       bool sp_indiff;
 
        struct nfp_net *ctrl_vnic;
 
@@ -163,6 +161,7 @@ bool nfp_ctrl_tx(struct nfp_net *nn, struct sk_buff *skb);
 
 int nfp_pf_rtsym_read_optional(struct nfp_pf *pf, const char *format,
                               unsigned int default_val);
+int nfp_net_pf_get_app_id(struct nfp_pf *pf);
 u8 __iomem *
 nfp_pf_map_rtsym(struct nfp_pf *pf, const char *name, const char *sym_fmt,
                 unsigned int min_size, struct nfp_cpp_area **area);
index d81bd86970471b3ec5aaf4c1caa485ace27275c9..c3a763134e79fe5f96fc42b8a0a0c2711c111cbf 100644 (file)
@@ -148,14 +148,6 @@ int nfp_net_tlv_caps_parse(struct device *dev, u8 __iomem *ctrl_mem,
                                                          true))
                                return -EINVAL;
                        break;
-               case NFP_NET_CFG_TLV_TYPE_SP_INDIFF:
-                       if (length) {
-                               dev_err(dev, "Unexpected len of SP_INDIFF TLV:%u\n", length);
-                               return -EINVAL;
-                       }
-
-                       caps->sp_indiff = true;
-                       break;
                default:
                        if (!FIELD_GET(NFP_NET_CFG_TLV_HEADER_REQUIRED, hdr))
                                break;
index 1d53f721a1c82f9fd574e62e9c632e3b414e1989..6714d5e8fdab2117f1d0cab15274ce78e0bee8c9 100644 (file)
@@ -14,6 +14,9 @@
 
 #include <linux/types.h>
 
+/* 64-bit per app capabilities */
+#define NFP_NET_APP_CAP_SP_INDIFF      BIT_ULL(0) /* indifferent to port speed */
+
 /* Configuration BAR size.
  *
  * The configuration BAR is 8K in size, but due to
  * %NFP_NET_CFG_TLV_TYPE_CRYPTO_OPS_RX_SCAN:
  * Same as %NFP_NET_CFG_TLV_TYPE_CRYPTO_OPS, but crypto TLS does stream scan
  * RX sync, rather than kernel-assisted sync.
- *
- * %NFP_NET_CFG_TLV_TYPE_SP_INDIFF:
- * Empty, indicate the firmware is indifferent to port speed. Then no need to
- * reload driver and firmware when port speed is changed.
  */
 #define NFP_NET_CFG_TLV_TYPE_UNKNOWN           0
 #define NFP_NET_CFG_TLV_TYPE_RESERVED          1
 #define NFP_NET_CFG_TLV_TYPE_CRYPTO_OPS                11 /* see crypto/fw.h */
 #define NFP_NET_CFG_TLV_TYPE_VNIC_STATS                12
 #define NFP_NET_CFG_TLV_TYPE_CRYPTO_OPS_RX_SCAN        13
-#define NFP_NET_CFG_TLV_TYPE_SP_INDIFF         14
 
 struct device;
 
@@ -524,7 +522,6 @@ struct device;
  * @vnic_stats_off:    offset of vNIC stats area
  * @vnic_stats_cnt:    number of vNIC stats
  * @tls_resync_ss:     TLS resync will be performed via stream scan
- * @sp_indiff:         Firmware is indifferent to port speed
  */
 struct nfp_net_tlv_caps {
        u32 me_freq_mhz;
@@ -537,7 +534,6 @@ struct nfp_net_tlv_caps {
        unsigned int vnic_stats_off;
        unsigned int vnic_stats_cnt;
        unsigned int tls_resync_ss:1;
-       unsigned int sp_indiff:1;
 };
 
 int nfp_net_tlv_caps_parse(struct device *dev, u8 __iomem *ctrl_mem,
index f3852ba8099a4aef02098f32764e8cffeb022879..3bae92dc899ed03930f30b9de3fb0b0ce6b84f4a 100644 (file)
@@ -77,12 +77,6 @@ static int nfp_net_pf_get_num_ports(struct nfp_pf *pf)
        return nfp_pf_rtsym_read_optional(pf, "nfd_cfg_pf%u_num_ports", 1);
 }
 
-static int nfp_net_pf_get_app_id(struct nfp_pf *pf)
-{
-       return nfp_pf_rtsym_read_optional(pf, "_pf%u_net_app_id",
-                                         NFP_APP_CORE_NIC);
-}
-
 static void nfp_net_pf_free_vnic(struct nfp_pf *pf, struct nfp_net *nn)
 {
        if (nfp_net_is_data_vnic(nn))
@@ -206,7 +200,6 @@ nfp_net_pf_alloc_vnics(struct nfp_pf *pf, void __iomem *ctrl_bar,
                        nn->port->link_cb = nfp_net_refresh_port_table;
 
                ctrl_bar += NFP_PF_CSR_SLICE_SIZE;
-               pf->sp_indiff |= nn->tlv_caps.sp_indiff;
 
                /* Kill the vNIC if app init marked it as invalid */
                if (nn->port && nn->port->type == NFP_PORT_INVALID)
@@ -308,36 +301,6 @@ err_prev_deinit:
        return err;
 }
 
-static int nfp_net_pf_cfg_nsp(struct nfp_pf *pf, bool sp_indiff)
-{
-       struct nfp_nsp *nsp;
-       char hwinfo[32];
-       int err;
-
-       nsp = nfp_nsp_open(pf->cpp);
-       if (IS_ERR(nsp))
-               return PTR_ERR(nsp);
-
-       snprintf(hwinfo, sizeof(hwinfo), "sp_indiff=%d", sp_indiff);
-       err = nfp_nsp_hwinfo_set(nsp, hwinfo, sizeof(hwinfo));
-       /* Not a fatal error, no need to return error to stop driver from loading */
-       if (err)
-               nfp_warn(pf->cpp, "HWinfo(sp_indiff=%d) set failed: %d\n", sp_indiff, err);
-
-       nfp_nsp_close(nsp);
-       return 0;
-}
-
-static int nfp_net_pf_init_nsp(struct nfp_pf *pf)
-{
-       return nfp_net_pf_cfg_nsp(pf, pf->sp_indiff);
-}
-
-static void nfp_net_pf_clean_nsp(struct nfp_pf *pf)
-{
-       (void)nfp_net_pf_cfg_nsp(pf, false);
-}
-
 static int
 nfp_net_pf_app_init(struct nfp_pf *pf, u8 __iomem *qc_bar, unsigned int stride)
 {
@@ -349,8 +312,6 @@ nfp_net_pf_app_init(struct nfp_pf *pf, u8 __iomem *qc_bar, unsigned int stride)
        if (IS_ERR(pf->app))
                return PTR_ERR(pf->app);
 
-       pf->sp_indiff |= pf->app->type->id == NFP_APP_FLOWER_NIC;
-
        devl_lock(devlink);
        err = nfp_app_init(pf->app);
        devl_unlock(devlink);
@@ -813,13 +774,9 @@ int nfp_net_pci_probe(struct nfp_pf *pf)
        if (err)
                goto err_clean_ddir;
 
-       err = nfp_net_pf_init_nsp(pf);
-       if (err)
-               goto err_free_vnics;
-
        err = nfp_net_pf_alloc_irqs(pf);
        if (err)
-               goto err_clean_nsp;
+               goto err_free_vnics;
 
        err = nfp_net_pf_app_start(pf);
        if (err)
@@ -838,8 +795,6 @@ err_stop_app:
        nfp_net_pf_app_stop(pf);
 err_free_irqs:
        nfp_net_pf_free_irqs(pf);
-err_clean_nsp:
-       nfp_net_pf_clean_nsp(pf);
 err_free_vnics:
        nfp_net_pf_free_vnics(pf);
 err_clean_ddir:
@@ -870,7 +825,6 @@ void nfp_net_pci_remove(struct nfp_pf *pf)
                nfp_net_pf_free_vnic(pf, nn);
        }
 
-       nfp_net_pf_clean_nsp(pf);
        nfp_net_pf_app_stop(pf);
        /* stop app first, to avoid double free of ctrl vNIC's ddir */
        nfp_net_debugfs_dir_clean(&pf->ddir);