[PATCH 09/15] soc: octeontx2: Configure block LF's MSIX vector offset

2018-08-28 Thread sunil . kovvuri
From: Sunil Goutham 

Firmware configures a certain number of MSIX vectors to each of
enabled RVU PF/VF. When a block LF is attached to a PF/VF, number
of MSIX vectors needed by that LF are set aside (out of PF/VF's
total MSIX vectors) and LF's msix_offset is configured in HW.

Also added support for a RVU PF/VF to retrieve that block LF's
MSIX vector offset information from AF via mbox.

Signed-off-by: Sunil Goutham 
---
 drivers/soc/marvell/octeontx2/mbox.h   |  18 ++
 drivers/soc/marvell/octeontx2/rvu.c| 333 -
 drivers/soc/marvell/octeontx2/rvu.h|   7 +
 drivers/soc/marvell/octeontx2/rvu_struct.h |   2 +
 4 files changed, 357 insertions(+), 3 deletions(-)

diff --git a/drivers/soc/marvell/octeontx2/mbox.h 
b/drivers/soc/marvell/octeontx2/mbox.h
index 7280d49..bedf0ee 100644
--- a/drivers/soc/marvell/octeontx2/mbox.h
+++ b/drivers/soc/marvell/octeontx2/mbox.h
@@ -122,6 +122,7 @@ static inline struct mbox_msghdr 
*otx2_mbox_alloc_msg(struct otx2_mbox *mbox,
 M(READY,   0x001, msg_req, ready_msg_rsp)  \
 M(ATTACH_RESOURCES,0x002, rsrc_attach, msg_rsp)\
 M(DETACH_RESOURCES,0x003, rsrc_detach, msg_rsp)\
+M(MSIX_OFFSET, 0x004, msg_req, msix_offset_rsp)\
 /* CGX mbox IDs (range 0x200 - 0x3FF) */   \
 /* NPA mbox IDs (range 0x400 - 0x5FF) */   \
 /* SSO/SSOW mbox IDs (range 0x600 - 0x7FF) */  \
@@ -190,4 +191,21 @@ struct rsrc_detach {
u8 cptlfs:1;
 };
 
+#define MSIX_VECTOR_INVALID0x
+#define MAX_RVU_BLKLF_CNT  256
+
+struct msix_offset_rsp {
+   struct mbox_msghdr hdr;
+   u16  npa_msixoff;
+   u16  nix_msixoff;
+   u8   sso;
+   u8   ssow;
+   u8   timlfs;
+   u8   cptlfs;
+   u16  sso_msixoff[MAX_RVU_BLKLF_CNT];
+   u16  ssow_msixoff[MAX_RVU_BLKLF_CNT];
+   u16  timlf_msixoff[MAX_RVU_BLKLF_CNT];
+   u16  cptlf_msixoff[MAX_RVU_BLKLF_CNT];
+};
+
 #endif /* MBOX_H */
diff --git a/drivers/soc/marvell/octeontx2/rvu.c 
b/drivers/soc/marvell/octeontx2/rvu.c
index 39dc45d..8ac3524 100644
--- a/drivers/soc/marvell/octeontx2/rvu.c
+++ b/drivers/soc/marvell/octeontx2/rvu.c
@@ -24,6 +24,11 @@
 
 static int rvu_get_hwvf(struct rvu *rvu, int pcifunc);
 
+static void rvu_set_msix_offset(struct rvu *rvu, struct rvu_pfvf *pfvf,
+   struct rvu_block *block, int lf);
+static void rvu_clear_msix_offset(struct rvu *rvu, struct rvu_pfvf *pfvf,
+ struct rvu_block *block, int lf);
+
 /* Supported devices */
 static const struct pci_device_id rvu_id_table[] = {
{ PCI_DEVICE(PCI_VENDOR_ID_CAVIUM, PCI_DEVID_OCTEONTX2_RVU_AF) },
@@ -75,6 +80,45 @@ int rvu_alloc_rsrc(struct rsrc_bmap *rsrc)
return id;
 }
 
+static int rvu_alloc_rsrc_contig(struct rsrc_bmap *rsrc, int nrsrc)
+{
+   int start;
+
+   if (!rsrc->bmap)
+   return -EINVAL;
+
+   start = bitmap_find_next_zero_area(rsrc->bmap, rsrc->max, 0, nrsrc, 0);
+   if (start >= rsrc->max)
+   return -ENOSPC;
+
+   bitmap_set(rsrc->bmap, start, nrsrc);
+   return start;
+}
+
+static void rvu_free_rsrc_contig(struct rsrc_bmap *rsrc, int nrsrc, int start)
+{
+   if (!rsrc->bmap)
+   return;
+   if (start >= rsrc->max)
+   return;
+
+   bitmap_clear(rsrc->bmap, start, nrsrc);
+}
+
+static bool rvu_rsrc_check_contig(struct rsrc_bmap *rsrc, int nrsrc)
+{
+   int start;
+
+   if (!rsrc->bmap)
+   return false;
+
+   start = bitmap_find_next_zero_area(rsrc->bmap, rsrc->max, 0, nrsrc, 0);
+   if (start >= rsrc->max)
+   return false;
+
+   return true;
+}
+
 void rvu_free_rsrc(struct rsrc_bmap *rsrc, int id)
 {
if (!rsrc->bmap)
@@ -103,6 +147,26 @@ int rvu_alloc_bitmap(struct rsrc_bmap *rsrc)
return 0;
 }
 
+/* Get block LF's HW index from a PF_FUNC's block slot number */
+int rvu_get_lf(struct rvu *rvu, struct rvu_block *block, u16 pcifunc, u16 slot)
+{
+   int lf;
+   u16 match = 0;
+
+   spin_lock(>rsrc_lock);
+   for (lf = 0; lf < block->lf.max; lf++) {
+   if (block->fn_map[lf] == pcifunc) {
+   if (slot == match) {
+   spin_unlock(>rsrc_lock);
+   return lf;
+   }
+   match++;
+   }
+   }
+   spin_unlock(>rsrc_lock);
+   return -ENODEV;
+}
+
 /* Convert BLOCK_TYPE_E to a BLOCK_ADDR_E.
  * Some silicon variants of OcteonTX2 supports
  * multiple blocks of same type.
@@ -237,6 +301,16 @@ inline int rvu_get_pf(u16 pcifunc)
return (pcifunc >> RVU_PFVF_PF_SHIFT) & RVU_PFVF_PF_MASK;
 }
 
+void rvu_get_pf_numvfs(struct rvu *rvu, int pf, int *numvfs, int *hwvf)
+{
+   u64 cfg;
+
+   /* Get numVFs attached to this 

[PATCH 09/15] soc: octeontx2: Configure block LF's MSIX vector offset

2018-08-28 Thread sunil . kovvuri
From: Sunil Goutham 

Firmware configures a certain number of MSIX vectors to each of
enabled RVU PF/VF. When a block LF is attached to a PF/VF, number
of MSIX vectors needed by that LF are set aside (out of PF/VF's
total MSIX vectors) and LF's msix_offset is configured in HW.

Also added support for a RVU PF/VF to retrieve that block LF's
MSIX vector offset information from AF via mbox.

Signed-off-by: Sunil Goutham 
---
 drivers/soc/marvell/octeontx2/mbox.h   |  18 ++
 drivers/soc/marvell/octeontx2/rvu.c| 333 -
 drivers/soc/marvell/octeontx2/rvu.h|   7 +
 drivers/soc/marvell/octeontx2/rvu_struct.h |   2 +
 4 files changed, 357 insertions(+), 3 deletions(-)

diff --git a/drivers/soc/marvell/octeontx2/mbox.h 
b/drivers/soc/marvell/octeontx2/mbox.h
index 7280d49..bedf0ee 100644
--- a/drivers/soc/marvell/octeontx2/mbox.h
+++ b/drivers/soc/marvell/octeontx2/mbox.h
@@ -122,6 +122,7 @@ static inline struct mbox_msghdr 
*otx2_mbox_alloc_msg(struct otx2_mbox *mbox,
 M(READY,   0x001, msg_req, ready_msg_rsp)  \
 M(ATTACH_RESOURCES,0x002, rsrc_attach, msg_rsp)\
 M(DETACH_RESOURCES,0x003, rsrc_detach, msg_rsp)\
+M(MSIX_OFFSET, 0x004, msg_req, msix_offset_rsp)\
 /* CGX mbox IDs (range 0x200 - 0x3FF) */   \
 /* NPA mbox IDs (range 0x400 - 0x5FF) */   \
 /* SSO/SSOW mbox IDs (range 0x600 - 0x7FF) */  \
@@ -190,4 +191,21 @@ struct rsrc_detach {
u8 cptlfs:1;
 };
 
+#define MSIX_VECTOR_INVALID0x
+#define MAX_RVU_BLKLF_CNT  256
+
+struct msix_offset_rsp {
+   struct mbox_msghdr hdr;
+   u16  npa_msixoff;
+   u16  nix_msixoff;
+   u8   sso;
+   u8   ssow;
+   u8   timlfs;
+   u8   cptlfs;
+   u16  sso_msixoff[MAX_RVU_BLKLF_CNT];
+   u16  ssow_msixoff[MAX_RVU_BLKLF_CNT];
+   u16  timlf_msixoff[MAX_RVU_BLKLF_CNT];
+   u16  cptlf_msixoff[MAX_RVU_BLKLF_CNT];
+};
+
 #endif /* MBOX_H */
diff --git a/drivers/soc/marvell/octeontx2/rvu.c 
b/drivers/soc/marvell/octeontx2/rvu.c
index 39dc45d..8ac3524 100644
--- a/drivers/soc/marvell/octeontx2/rvu.c
+++ b/drivers/soc/marvell/octeontx2/rvu.c
@@ -24,6 +24,11 @@
 
 static int rvu_get_hwvf(struct rvu *rvu, int pcifunc);
 
+static void rvu_set_msix_offset(struct rvu *rvu, struct rvu_pfvf *pfvf,
+   struct rvu_block *block, int lf);
+static void rvu_clear_msix_offset(struct rvu *rvu, struct rvu_pfvf *pfvf,
+ struct rvu_block *block, int lf);
+
 /* Supported devices */
 static const struct pci_device_id rvu_id_table[] = {
{ PCI_DEVICE(PCI_VENDOR_ID_CAVIUM, PCI_DEVID_OCTEONTX2_RVU_AF) },
@@ -75,6 +80,45 @@ int rvu_alloc_rsrc(struct rsrc_bmap *rsrc)
return id;
 }
 
+static int rvu_alloc_rsrc_contig(struct rsrc_bmap *rsrc, int nrsrc)
+{
+   int start;
+
+   if (!rsrc->bmap)
+   return -EINVAL;
+
+   start = bitmap_find_next_zero_area(rsrc->bmap, rsrc->max, 0, nrsrc, 0);
+   if (start >= rsrc->max)
+   return -ENOSPC;
+
+   bitmap_set(rsrc->bmap, start, nrsrc);
+   return start;
+}
+
+static void rvu_free_rsrc_contig(struct rsrc_bmap *rsrc, int nrsrc, int start)
+{
+   if (!rsrc->bmap)
+   return;
+   if (start >= rsrc->max)
+   return;
+
+   bitmap_clear(rsrc->bmap, start, nrsrc);
+}
+
+static bool rvu_rsrc_check_contig(struct rsrc_bmap *rsrc, int nrsrc)
+{
+   int start;
+
+   if (!rsrc->bmap)
+   return false;
+
+   start = bitmap_find_next_zero_area(rsrc->bmap, rsrc->max, 0, nrsrc, 0);
+   if (start >= rsrc->max)
+   return false;
+
+   return true;
+}
+
 void rvu_free_rsrc(struct rsrc_bmap *rsrc, int id)
 {
if (!rsrc->bmap)
@@ -103,6 +147,26 @@ int rvu_alloc_bitmap(struct rsrc_bmap *rsrc)
return 0;
 }
 
+/* Get block LF's HW index from a PF_FUNC's block slot number */
+int rvu_get_lf(struct rvu *rvu, struct rvu_block *block, u16 pcifunc, u16 slot)
+{
+   int lf;
+   u16 match = 0;
+
+   spin_lock(>rsrc_lock);
+   for (lf = 0; lf < block->lf.max; lf++) {
+   if (block->fn_map[lf] == pcifunc) {
+   if (slot == match) {
+   spin_unlock(>rsrc_lock);
+   return lf;
+   }
+   match++;
+   }
+   }
+   spin_unlock(>rsrc_lock);
+   return -ENODEV;
+}
+
 /* Convert BLOCK_TYPE_E to a BLOCK_ADDR_E.
  * Some silicon variants of OcteonTX2 supports
  * multiple blocks of same type.
@@ -237,6 +301,16 @@ inline int rvu_get_pf(u16 pcifunc)
return (pcifunc >> RVU_PFVF_PF_SHIFT) & RVU_PFVF_PF_MASK;
 }
 
+void rvu_get_pf_numvfs(struct rvu *rvu, int pf, int *numvfs, int *hwvf)
+{
+   u64 cfg;
+
+   /* Get numVFs attached to this