nfp: report NSP ABI version in ethtool FW version
authorJakub Kicinski <jakub.kicinski@netronome.com>
Sun, 19 Feb 2017 19:58:11 +0000 (11:58 -0800)
committerDavid S. Miller <davem@davemloft.net>
Mon, 20 Feb 2017 16:18:49 +0000 (11:18 -0500)
ethtool_drvinfo->fw_version can cantain multiple FW strings.
We already report NFD ABI version there, add NSP ABI version
if available (i.e. on PF) with 'sp:' prefix.

Signed-off-by: Jakub Kicinski <jakub.kicinski@netronome.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
drivers/net/ethernet/netronome/nfp/nfp_net.h
drivers/net/ethernet/netronome/nfp/nfp_net_ethtool.c
drivers/net/ethernet/netronome/nfp/nfp_net_main.c
drivers/net/ethernet/netronome/nfp/nfpcore/nfp.h
drivers/net/ethernet/netronome/nfp/nfpcore/nfp_nsp.c

index d37d2391b4feecaebad95c874be615ae6aeb7271..5a0fc09dd6ea2c6e95a96a2263c4f1f1240d9d7c 100644 (file)
                                 SKB_DATA_ALIGN(sizeof(struct skb_shared_info)))
 
 /* Forward declarations */
+struct nfp_cpp;
 struct nfp_net;
 struct nfp_net_r_vector;
 
@@ -492,6 +493,7 @@ struct nfp_stat_pair {
  * @rx_bar:             Pointer to mapped FL/RX queues
  * @debugfs_dir:       Device directory in debugfs
  * @port_list:         Entry on device port list
+ * @cpp:               CPP device handle if available
  */
 struct nfp_net {
        struct pci_dev *pdev;
@@ -579,6 +581,8 @@ struct nfp_net {
        struct dentry *debugfs_dir;
 
        struct list_head port_list;
+
+       struct nfp_cpp *cpp;
 };
 
 struct nfp_net_ring_set {
index 255f30252550902e75d4c14576a015db5883e5d4..48f623f685988f474020dd1ddbae1575a80b9b84 100644 (file)
@@ -47,6 +47,7 @@
 #include <linux/pci.h>
 #include <linux/ethtool.h>
 
+#include "nfpcore/nfp.h"
 #include "nfp_net_ctrl.h"
 #include "nfp_net.h"
 
@@ -127,19 +128,39 @@ static const struct _nfp_net_et_stats nfp_net_et_stats[] = {
 #define NN_ET_STATS_LEN (NN_ET_GLOBAL_STATS_LEN + NN_ET_RVEC_GATHER_STATS + \
                         NN_ET_RVEC_STATS_LEN + NN_ET_QUEUE_STATS_LEN)
 
+static void nfp_net_get_nspinfo(struct nfp_net *nn, char *version)
+{
+       struct nfp_nsp *nsp;
+
+       if (!nn->cpp)
+               return;
+
+       nsp = nfp_nsp_open(nn->cpp);
+       if (IS_ERR(nsp))
+               return;
+
+       snprintf(version, ETHTOOL_FWVERS_LEN, "sp:%hu.%hu",
+                nfp_nsp_get_abi_ver_major(nsp),
+                nfp_nsp_get_abi_ver_minor(nsp));
+
+       nfp_nsp_close(nsp);
+}
+
 static void nfp_net_get_drvinfo(struct net_device *netdev,
                                struct ethtool_drvinfo *drvinfo)
 {
+       char nsp_version[ETHTOOL_FWVERS_LEN] = {};
        struct nfp_net *nn = netdev_priv(netdev);
 
        strlcpy(drvinfo->driver, nn->pdev->driver->name,
                sizeof(drvinfo->driver));
        strlcpy(drvinfo->version, nfp_driver_version, sizeof(drvinfo->version));
 
+       nfp_net_get_nspinfo(nn, nsp_version);
        snprintf(drvinfo->fw_version, sizeof(drvinfo->fw_version),
-                "%d.%d.%d.%d",
+                "%d.%d.%d.%d %s",
                 nn->fw_ver.resv, nn->fw_ver.class,
-                nn->fw_ver.major, nn->fw_ver.minor);
+                nn->fw_ver.major, nn->fw_ver.minor, nsp_version);
        strlcpy(drvinfo->bus_info, pci_name(nn->pdev),
                sizeof(drvinfo->bus_info));
 
index eccd31003b0d103eee6cfa275679220b64318b45..3afcdc11480c82c7d19f2252cae29a40066cfef8 100644 (file)
@@ -303,6 +303,7 @@ nfp_net_pf_alloc_port_netdev(struct nfp_pf *pf, void __iomem *ctrl_bar,
        if (IS_ERR(nn))
                return nn;
 
+       nn->cpp = pf->cpp;
        nn->fw_ver = *fw_ver;
        nn->ctrl_bar = ctrl_bar;
        nn->tx_bar = tx_bar;
index 3d70a8578a988dd21262bb050ac16b5441f6fe63..540027973a74e9765f2c445b2c903804f0d46490 100644 (file)
@@ -40,6 +40,7 @@
 #define __NFP_H__
 
 #include <linux/device.h>
+#include <linux/types.h>
 
 #include "nfp_cpp.h"
 
@@ -54,6 +55,8 @@ struct firmware;
 
 struct nfp_nsp *nfp_nsp_open(struct nfp_cpp *cpp);
 void nfp_nsp_close(struct nfp_nsp *state);
+u16 nfp_nsp_get_abi_ver_major(struct nfp_nsp *state);
+u16 nfp_nsp_get_abi_ver_minor(struct nfp_nsp *state);
 int nfp_nsp_wait(struct nfp_nsp *state);
 int nfp_nsp_device_soft_reset(struct nfp_nsp *state);
 int nfp_nsp_load_fw(struct nfp_nsp *state, const struct firmware *fw);
index f2d737c3d1df40a1349e81a386017ef295f2fe91..34c50987c377c6e721d82621b51702457a629781 100644 (file)
@@ -182,6 +182,16 @@ void nfp_nsp_close(struct nfp_nsp *state)
        kfree(state);
 }
 
+u16 nfp_nsp_get_abi_ver_major(struct nfp_nsp *state)
+{
+       return state->ver.major;
+}
+
+u16 nfp_nsp_get_abi_ver_minor(struct nfp_nsp *state)
+{
+       return state->ver.minor;
+}
+
 static int
 nfp_nsp_wait_reg(struct nfp_cpp *cpp, u64 *reg,
                 u32 nsp_cpp, u64 addr, u64 mask, u64 val)