nfp: save the MU locality field offset
authorJakub Kicinski <jakub.kicinski@netronome.com>
Tue, 28 Aug 2018 20:20:40 +0000 (13:20 -0700)
committerDavid S. Miller <davem@davemloft.net>
Tue, 28 Aug 2018 23:01:47 +0000 (16:01 -0700)
We will soon need the MU locality field offset much more
often than just for decoding MIP address.  Save it in nfp_cpp
for quick access.  Note that we can already reuse the target
config from nfp_cpp, no need to do the XPB read.

Signed-off-by: Jakub Kicinski <jakub.kicinski@netronome.com>
Reviewed-by: Francois H. Theron <francois.theron@netronome.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
drivers/net/ethernet/netronome/nfp/nfpcore/nfp_cpp.h
drivers/net/ethernet/netronome/nfp/nfpcore/nfp_cppcore.c
drivers/net/ethernet/netronome/nfp/nfpcore/nfp_nffw.c

index af19fe9f493465a39f0eb3a7a6e87470fe276298..991b8ed7e036079f1f0f67528d1d84f9f2652fc4 100644 (file)
@@ -233,6 +233,7 @@ void nfp_cpp_free(struct nfp_cpp *cpp);
 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);
+unsigned int nfp_cpp_mu_locality_lsb(struct nfp_cpp *cpp);
 
 struct nfp_cpp_area *nfp_cpp_area_alloc_with_name(struct nfp_cpp *cpp,
                                                  u32 cpp_id,
index 73de57a09800d7d0c482e64d22995a3aa6c06613..f7e1d79e735fdd475a495f33250026b449ca0a4d 100644 (file)
@@ -75,6 +75,7 @@ struct nfp_cpp_resource {
  * @interface:         chip interface id we are using to reach it
  * @serial:            chip serial number
  * @imb_cat_table:     CPP Mapping Table
+ * @mu_locality_lsb:   MU access type bit offset
  *
  * Following fields use explicit locking:
  * @resource_list:     NFP CPP resource list
@@ -100,6 +101,7 @@ struct nfp_cpp {
        wait_queue_head_t waitq;
 
        u32 imb_cat_table[16];
+       unsigned int mu_locality_lsb;
 
        struct mutex area_cache_mutex;
        struct list_head area_cache_list;
@@ -266,6 +268,34 @@ int nfp_cpp_serial(struct nfp_cpp *cpp, const u8 **serial)
        return sizeof(cpp->serial);
 }
 
+#define NFP_IMB_TGTADDRESSMODECFG_MODE_of(_x)          (((_x) >> 13) & 0x7)
+#define NFP_IMB_TGTADDRESSMODECFG_ADDRMODE             BIT(12)
+#define   NFP_IMB_TGTADDRESSMODECFG_ADDRMODE_32_BIT    0
+#define   NFP_IMB_TGTADDRESSMODECFG_ADDRMODE_40_BIT    BIT(12)
+
+static int nfp_cpp_set_mu_locality_lsb(struct nfp_cpp *cpp)
+{
+       unsigned int mode, addr40;
+       u32 imbcppat;
+       int res;
+
+       imbcppat = cpp->imb_cat_table[NFP_CPP_TARGET_MU];
+       mode = NFP_IMB_TGTADDRESSMODECFG_MODE_of(imbcppat);
+       addr40 = !!(imbcppat & NFP_IMB_TGTADDRESSMODECFG_ADDRMODE);
+
+       res = nfp_cppat_mu_locality_lsb(mode, addr40);
+       if (res < 0)
+               return res;
+       cpp->mu_locality_lsb = res;
+
+       return 0;
+}
+
+unsigned int nfp_cpp_mu_locality_lsb(struct nfp_cpp *cpp)
+{
+       return cpp->mu_locality_lsb;
+}
+
 /**
  * nfp_cpp_area_alloc_with_name() - allocate a new CPP area
  * @cpp:       CPP device handle
@@ -1241,6 +1271,12 @@ nfp_cpp_from_operations(const struct nfp_cpp_operations *ops,
        nfp_cpp_readl(cpp, arm, NFP_ARM_GCSR + NFP_ARM_GCSR_SOFTMODEL3,
                      &mask[1]);
 
+       err = nfp_cpp_set_mu_locality_lsb(cpp);
+       if (err < 0) {
+               dev_err(parent, "Can't calculate MU locality bit offset\n");
+               goto err_out;
+       }
+
        dev_info(cpp->dev.parent, "Model: 0x%08x, SN: %pM, Ifc: 0x%04x\n",
                 nfp_cpp_model(cpp), cpp->serial, nfp_cpp_interface(cpp));
 
index 40510860341b8f349bcda48c330dd8e957872820..a164fbc85cd3ed0bbe8c77788f156a2d87e38950 100644 (file)
@@ -156,29 +156,6 @@ static u64 nffw_fwinfo_mip_offset_get(const struct nffw_fwinfo *fi)
        return (mip_off_hi & 0xFF) << 32 | le32_to_cpu(fi->mip_offset_lo);
 }
 
-#define NFP_IMB_TGTADDRESSMODECFG_MODE_of(_x)          (((_x) >> 13) & 0x7)
-#define NFP_IMB_TGTADDRESSMODECFG_ADDRMODE             BIT(12)
-#define   NFP_IMB_TGTADDRESSMODECFG_ADDRMODE_32_BIT    0
-#define   NFP_IMB_TGTADDRESSMODECFG_ADDRMODE_40_BIT    BIT(12)
-
-static int nfp_mip_mu_locality_lsb(struct nfp_cpp *cpp)
-{
-       unsigned int mode, addr40;
-       u32 xpbaddr, imbcppat;
-       int err;
-
-       /* Hardcoded XPB IMB Base, island 0 */
-       xpbaddr = 0x000a0000 + NFP_CPP_TARGET_MU * 4;
-       err = nfp_xpb_readl(cpp, xpbaddr, &imbcppat);
-       if (err < 0)
-               return err;
-
-       mode = NFP_IMB_TGTADDRESSMODECFG_MODE_of(imbcppat);
-       addr40 = !!(imbcppat & NFP_IMB_TGTADDRESSMODECFG_ADDRMODE);
-
-       return nfp_cppat_mu_locality_lsb(mode, addr40);
-}
-
 static unsigned int
 nffw_res_fwinfos(struct nfp_nffw_info_data *fwinf, struct nffw_fwinfo **arr)
 {
@@ -304,14 +281,7 @@ int nfp_nffw_info_mip_first(struct nfp_nffw_info *state, u32 *cpp_id, u64 *off)
        *off = nffw_fwinfo_mip_offset_get(fwinfo);
 
        if (nffw_fwinfo_mip_mu_da_get(fwinfo)) {
-               int locality_off;
-
-               if (NFP_CPP_ID_TARGET_of(*cpp_id) != NFP_CPP_TARGET_MU)
-                       return 0;
-
-               locality_off = nfp_mip_mu_locality_lsb(state->cpp);
-               if (locality_off < 0)
-                       return locality_off;
+               int locality_off = nfp_cpp_mu_locality_lsb(state->cpp);
 
                *off &= ~(NFP_MU_ADDR_ACCESS_TYPE_MASK << locality_off);
                *off |= NFP_MU_ADDR_ACCESS_TYPE_DIRECT << locality_off;