]> git.proxmox.com Git - mirror_ubuntu-kernels.git/commitdiff
octeontx2-af: Set RVU PFs to CGX LMACs mapping
authorLinu Cherian <lcherian@marvell.com>
Wed, 10 Oct 2018 12:44:32 +0000 (18:14 +0530)
committerDavid S. Miller <davem@davemloft.net>
Wed, 10 Oct 2018 17:06:02 +0000 (10:06 -0700)
Each of the enabled CGX LMAC is considered a physical
interface and RVU PFs are mapped to these. VFs of these
SRIOV PFs will be virtual interfaces and share CGX LMAC
along with PF.

This mapping info will be used later on for Rx/Tx pkt steering.

Signed-off-by: Linu Cherian <lcherian@marvell.com>
Signed-off-by: Geetha sowjanya <gakula@marvell.com>
Signed-off-by: Sunil Goutham <sgoutham@marvell.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
drivers/net/ethernet/marvell/octeontx2/af/Makefile
drivers/net/ethernet/marvell/octeontx2/af/cgx.c
drivers/net/ethernet/marvell/octeontx2/af/cgx.h
drivers/net/ethernet/marvell/octeontx2/af/rvu.c
drivers/net/ethernet/marvell/octeontx2/af/rvu.h

index 8646421b9e45b27d0b84dd074dbd9f142ebb6150..eaac264244865c987e20780b7b81e307fe006b32 100644 (file)
@@ -7,4 +7,4 @@ obj-$(CONFIG_OCTEONTX2_MBOX) += octeontx2_mbox.o
 obj-$(CONFIG_OCTEONTX2_AF) += octeontx2_af.o
 
 octeontx2_mbox-y := mbox.o
-octeontx2_af-y := cgx.o rvu.o
+octeontx2_af-y := cgx.o rvu.o rvu_cgx.o
index c41d23f4f893c65678d068d5bec7abf6a8829c1a..6ecae80d50ac400535eb3c715321352904f10cfd 100644 (file)
@@ -28,8 +28,12 @@ struct cgx {
        void __iomem            *reg_base;
        struct pci_dev          *pdev;
        u8                      cgx_id;
+       u8                      lmac_count;
+       struct list_head        cgx_list;
 };
 
+static LIST_HEAD(cgx_list);
+
 /* Supported devices */
 static const struct pci_device_id cgx_id_table[] = {
        { PCI_DEVICE(PCI_VENDOR_ID_CAVIUM, PCI_DEVID_OCTEONTX2_CGX) },
@@ -38,6 +42,53 @@ static const struct pci_device_id cgx_id_table[] = {
 
 MODULE_DEVICE_TABLE(pci, cgx_id_table);
 
+static u64 cgx_read(struct cgx *cgx, u64 lmac, u64 offset)
+{
+       return readq(cgx->reg_base + (lmac << 18) + offset);
+}
+
+int cgx_get_cgx_cnt(void)
+{
+       struct cgx *cgx_dev;
+       int count = 0;
+
+       list_for_each_entry(cgx_dev, &cgx_list, cgx_list)
+               count++;
+
+       return count;
+}
+EXPORT_SYMBOL(cgx_get_cgx_cnt);
+
+int cgx_get_lmac_cnt(void *cgxd)
+{
+       struct cgx *cgx = cgxd;
+
+       if (!cgx)
+               return -ENODEV;
+
+       return cgx->lmac_count;
+}
+EXPORT_SYMBOL(cgx_get_lmac_cnt);
+
+void *cgx_get_pdata(int cgx_id)
+{
+       struct cgx *cgx_dev;
+
+       list_for_each_entry(cgx_dev, &cgx_list, cgx_list) {
+               if (cgx_dev->cgx_id == cgx_id)
+                       return cgx_dev;
+       }
+       return NULL;
+}
+EXPORT_SYMBOL(cgx_get_pdata);
+
+static void cgx_lmac_init(struct cgx *cgx)
+{
+       cgx->lmac_count = cgx_read(cgx, 0, CGXX_CMRX_RX_LMACS) & 0x7;
+       if (cgx->lmac_count > MAX_LMAC_PER_CGX)
+               cgx->lmac_count = MAX_LMAC_PER_CGX;
+}
+
 static int cgx_probe(struct pci_dev *pdev, const struct pci_device_id *id)
 {
        struct device *dev = &pdev->dev;
@@ -72,9 +123,14 @@ static int cgx_probe(struct pci_dev *pdev, const struct pci_device_id *id)
                goto err_release_regions;
        }
 
+       list_add(&cgx->cgx_list, &cgx_list);
+       cgx->cgx_id = cgx_get_cgx_cnt() - 1;
+       cgx_lmac_init(cgx);
+
        return 0;
 
 err_release_regions:
+       list_del(&cgx->cgx_list);
        pci_release_regions(pdev);
 err_disable_device:
        pci_disable_device(pdev);
@@ -84,6 +140,9 @@ err_disable_device:
 
 static void cgx_remove(struct pci_dev *pdev)
 {
+       struct cgx *cgx = pci_get_drvdata(pdev);
+
+       list_del(&cgx->cgx_list);
        pci_release_regions(pdev);
        pci_disable_device(pdev);
        pci_set_drvdata(pdev, NULL);
index a7d4b39ad746f446428a9d6ea137899c1c918b57..acdc16e89cb465da9948fc642ebcd7108c6992fc 100644 (file)
 #define CGX_H
 
  /* PCI device IDs */
-#define        PCI_DEVID_OCTEONTX2_CGX                 0xA059
+#define        PCI_DEVID_OCTEONTX2_CGX         0xA059
 
 /* PCI BAR nos */
-#define PCI_CFG_REG_BAR_NUM                    0
+#define PCI_CFG_REG_BAR_NUM            0
+
+#define MAX_CGX                                3
+#define MAX_LMAC_PER_CGX               4
+#define CGX_OFFSET(x)                  ((x) * MAX_LMAC_PER_CGX)
+
+/* Registers */
+#define CGXX_CMRX_RX_ID_MAP            0x060
+#define CGXX_CMRX_RX_LMACS             0x128
 
 extern struct pci_driver cgx_driver;
 
+int cgx_get_cgx_cnt(void);
+int cgx_get_lmac_cnt(void *cgxd);
+void *cgx_get_pdata(int cgx_id);
 #endif /* CGX_H */
index 72cb202b8b5af1ea6e7740cd12c2a135792d80d4..e9021a8138896deac3db8101d199ff174c41dc42 100644 (file)
@@ -1558,6 +1558,10 @@ static int rvu_probe(struct pci_dev *pdev, const struct pci_device_id *id)
        if (err)
                goto err_hwsetup;
 
+       err = rvu_cgx_probe(rvu);
+       if (err)
+               goto err_mbox;
+
        err = rvu_register_interrupts(rvu);
        if (err)
                goto err_mbox;
index 92c202295206b7dc99c3ea3f1d1269d7fb1c3a22..385f597c1fe3b42782a893d8c2a03f6138f89e25 100644 (file)
@@ -100,6 +100,16 @@ struct rvu {
        char                    *irq_name;
        bool                    *irq_allocated;
        dma_addr_t              msix_base_iova;
+
+       /* CGX */
+#define PF_CGXMAP_BASE         1 /* PF 0 is reserved for RVU PF */
+       u8                      cgx_mapped_pfs;
+       u8                      cgx_cnt; /* available cgx ports */
+       u8                      *pf2cgxlmac_map; /* pf to cgx_lmac map */
+       u16                     *cgxlmac2pf_map; /* bitmap of mapped pfs for
+                                                 * every cgx lmac port
+                                                 */
+       void                    **cgx_idmap; /* cgx id to cgx data map table */
 };
 
 static inline void rvu_write64(struct rvu *rvu, u64 block, u64 offset, u64 val)
@@ -138,4 +148,6 @@ int rvu_get_lf(struct rvu *rvu, struct rvu_block *block, u16 pcifunc, u16 slot);
 int rvu_get_blkaddr(struct rvu *rvu, int blktype, u16 pcifunc);
 int rvu_poll_reg(struct rvu *rvu, u64 block, u64 offset, u64 mask, bool zero);
 
+/* CGX APIs */
+int rvu_cgx_probe(struct rvu *rvu);
 #endif /* RVU_H */