]> git.baikalelectronics.ru Git - kernel.git/commitdiff
octeontx2-af: Map NIX block from CGX connection
authorSubbaraya Sundeep <sbhatta@marvell.com>
Thu, 29 Oct 2020 05:15:43 +0000 (10:45 +0530)
committerJakub Kicinski <kuba@kernel.org>
Sat, 31 Oct 2020 21:16:46 +0000 (14:16 -0700)
Firmware configures NIX block mapping for all CGXs
to achieve maximum throughput. This patch reads
the configuration and create mapping between RVU
PF and NIX blocks. And for LBK VFs assign NIX0 for
even numbered VFs and NIX1 for odd numbered VFs.

Signed-off-by: Subbaraya Sundeep <sbhatta@marvell.com>
Signed-off-by: Sunil Goutham <sgoutham@marvell.com>
Signed-off-by: Rakesh Babu <rsaladi2@marvell.com>
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
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
drivers/net/ethernet/marvell/octeontx2/af/rvu_cgx.c
drivers/net/ethernet/marvell/octeontx2/af/rvu_nix.c

index 8f17e26dca538cad2966bc2b86846c390c0df929..7d0f96290943780d5401a40a45e01e438db8494f 100644 (file)
@@ -145,6 +145,16 @@ int cgx_get_cgxid(void *cgxd)
        return cgx->cgx_id;
 }
 
+u8 cgx_lmac_get_p2x(int cgx_id, int lmac_id)
+{
+       struct cgx *cgx_dev = cgx_get_pdata(cgx_id);
+       u64 cfg;
+
+       cfg = cgx_read(cgx_dev, lmac_id, CGXX_CMRX_CFG);
+
+       return (cfg & CMR_P2X_SEL_MASK) >> CMR_P2X_SEL_SHIFT;
+}
+
 /* Ensure the required lock for event queue(where asynchronous events are
  * posted) is acquired before calling this API. Else an asynchronous event(with
  * latest link status) can reach the destination before this function returns
@@ -814,8 +824,7 @@ static int cgx_lmac_verify_fwi_version(struct cgx *cgx)
        minor_ver = FIELD_GET(RESP_MINOR_VER, resp);
        dev_dbg(dev, "Firmware command interface version = %d.%d\n",
                major_ver, minor_ver);
-       if (major_ver != CGX_FIRMWARE_MAJOR_VER ||
-           minor_ver != CGX_FIRMWARE_MINOR_VER)
+       if (major_ver != CGX_FIRMWARE_MAJOR_VER)
                return -EIO;
        else
                return 0;
index 27ca3291682bc031d84f0943a2490375472da6fd..bcfc3e5f66bb4230216b8ffb4d6273c5b92a55f7 100644 (file)
 
 /* Registers */
 #define CGXX_CMRX_CFG                  0x00
+#define CMR_P2X_SEL_MASK               GENMASK_ULL(61, 59)
+#define CMR_P2X_SEL_SHIFT              59ULL
+#define CMR_P2X_SEL_NIX0               1ULL
+#define CMR_P2X_SEL_NIX1               2ULL
 #define CMR_EN                         BIT_ULL(55)
 #define DATA_PKT_TX_EN                 BIT_ULL(53)
 #define DATA_PKT_RX_EN                 BIT_ULL(54)
@@ -142,5 +146,6 @@ int cgx_lmac_get_pause_frm(void *cgxd, int lmac_id,
 int cgx_lmac_set_pause_frm(void *cgxd, int lmac_id,
                           u8 tx_pause, u8 rx_pause);
 void cgx_lmac_ptp_config(void *cgxd, int lmac_id, bool enable);
+u8 cgx_lmac_get_p2x(int cgx_id, int lmac_id);
 
 #endif /* CGX_H */
index 79b9553c61f89976c0c7ad5f3f4166b1dd1e5c77..f2dbc9aea30b923f900f2ff3a2de8c38b205e059 100644 (file)
@@ -1252,6 +1252,58 @@ int rvu_mbox_handler_detach_resources(struct rvu *rvu,
        return rvu_detach_rsrcs(rvu, detach, detach->hdr.pcifunc);
 }
 
+static int rvu_get_nix_blkaddr(struct rvu *rvu, u16 pcifunc)
+{
+       struct rvu_pfvf *pfvf = rvu_get_pfvf(rvu, pcifunc);
+       int blkaddr = BLKADDR_NIX0, vf;
+       struct rvu_pfvf *pf;
+
+       /* All CGX mapped PFs are set with assigned NIX block during init */
+       if (is_pf_cgxmapped(rvu, rvu_get_pf(pcifunc))) {
+               pf = rvu_get_pfvf(rvu, pcifunc & ~RVU_PFVF_FUNC_MASK);
+               blkaddr = pf->nix_blkaddr;
+       } else if (is_afvf(pcifunc)) {
+               vf = pcifunc - 1;
+               /* Assign NIX based on VF number. All even numbered VFs get
+                * NIX0 and odd numbered gets NIX1
+                */
+               blkaddr = (vf & 1) ? BLKADDR_NIX1 : BLKADDR_NIX0;
+               /* NIX1 is not present on all silicons */
+               if (!is_block_implemented(rvu->hw, BLKADDR_NIX1))
+                       blkaddr = BLKADDR_NIX0;
+       }
+
+       switch (blkaddr) {
+       case BLKADDR_NIX1:
+               pfvf->nix_blkaddr = BLKADDR_NIX1;
+               break;
+       case BLKADDR_NIX0:
+       default:
+               pfvf->nix_blkaddr = BLKADDR_NIX0;
+               break;
+       }
+
+       return pfvf->nix_blkaddr;
+}
+
+static int rvu_get_attach_blkaddr(struct rvu *rvu, int blktype, u16 pcifunc)
+{
+       int blkaddr;
+
+       switch (blktype) {
+       case BLKTYPE_NIX:
+               blkaddr = rvu_get_nix_blkaddr(rvu, pcifunc);
+               break;
+       default:
+               return rvu_get_blkaddr(rvu, blktype, 0);
+       };
+
+       if (is_block_implemented(rvu->hw, blkaddr))
+               return blkaddr;
+
+       return -ENODEV;
+}
+
 static void rvu_attach_block(struct rvu *rvu, int pcifunc,
                             int blktype, int num_lfs)
 {
@@ -1265,7 +1317,7 @@ static void rvu_attach_block(struct rvu *rvu, int pcifunc,
        if (!num_lfs)
                return;
 
-       blkaddr = rvu_get_blkaddr(rvu, blktype, 0);
+       blkaddr = rvu_get_attach_blkaddr(rvu, blktype, pcifunc);
        if (blkaddr < 0)
                return;
 
@@ -1294,9 +1346,9 @@ static int rvu_check_rsrc_availability(struct rvu *rvu,
                                       struct rsrc_attach *req, u16 pcifunc)
 {
        struct rvu_pfvf *pfvf = rvu_get_pfvf(rvu, pcifunc);
+       int free_lfs, mappedlfs, blkaddr;
        struct rvu_hwinfo *hw = rvu->hw;
        struct rvu_block *block;
-       int free_lfs, mappedlfs;
 
        /* Only one NPA LF can be attached */
        if (req->npalf && !is_blktype_attached(pfvf, BLKTYPE_NPA)) {
@@ -1313,7 +1365,10 @@ static int rvu_check_rsrc_availability(struct rvu *rvu,
 
        /* Only one NIX LF can be attached */
        if (req->nixlf && !is_blktype_attached(pfvf, BLKTYPE_NIX)) {
-               block = &hw->block[BLKADDR_NIX0];
+               blkaddr = rvu_get_attach_blkaddr(rvu, BLKTYPE_NIX, pcifunc);
+               if (blkaddr < 0)
+                       return blkaddr;
+               block = &hw->block[blkaddr];
                free_lfs = rvu_rsrc_free_count(&block->lf);
                if (!free_lfs)
                        goto fail;
index a419075a93286783b78e1f2fa0a4f511b5a29db9..5d0815bd9a810816ea55d21d78638a3fd1de731d 100644 (file)
@@ -184,6 +184,8 @@ struct rvu_pfvf {
 
        bool    cgx_in_use; /* this PF/VF using CGX? */
        int     cgx_users;  /* number of cgx users - used only by PFs */
+
+       u8      nix_blkaddr; /* BLKADDR_NIX0/1 assigned to this PF */
 };
 
 struct nix_txsch {
index fa9152ff5e2a08715b707b1d61ec6d4b07c40de1..d298b935717784e5ba3bdf3344a0898e624a5759 100644 (file)
@@ -74,6 +74,20 @@ void *rvu_cgx_pdata(u8 cgx_id, struct rvu *rvu)
        return rvu->cgx_idmap[cgx_id];
 }
 
+/* Based on P2X connectivity find mapped NIX block for a PF */
+static void rvu_map_cgx_nix_block(struct rvu *rvu, int pf,
+                                 int cgx_id, int lmac_id)
+{
+       struct rvu_pfvf *pfvf = &rvu->pf[pf];
+       u8 p2x;
+
+       p2x = cgx_lmac_get_p2x(cgx_id, lmac_id);
+       /* Firmware sets P2X_SELECT as either NIX0 or NIX1 */
+       pfvf->nix_blkaddr = BLKADDR_NIX0;
+       if (p2x == CMR_P2X_SEL_NIX1)
+               pfvf->nix_blkaddr = BLKADDR_NIX1;
+}
+
 static int rvu_map_cgx_lmac_pf(struct rvu *rvu)
 {
        struct npc_pkind *pkind = &rvu->hw->pkind;
@@ -117,6 +131,7 @@ static int rvu_map_cgx_lmac_pf(struct rvu *rvu)
                        rvu->cgxlmac2pf_map[CGX_OFFSET(cgx) + lmac] = 1 << pf;
                        free_pkind = rvu_alloc_rsrc(&pkind->rsrc);
                        pkind->pfchan_map[free_pkind] = ((pf) & 0x3F) << 16;
+                       rvu_map_cgx_nix_block(rvu, pf, cgx, lmac);
                        rvu->cgx_mapped_pfs++;
                }
        }
index 096c2e02f9a0d7a292939471749c0ba9d8af58ae..6b8c964b6a247569b64f3c8483d6cd768c0f0f68 100644 (file)
@@ -213,8 +213,8 @@ static bool is_valid_txschq(struct rvu *rvu, int blkaddr,
 static int nix_interface_init(struct rvu *rvu, u16 pcifunc, int type, int nixlf)
 {
        struct rvu_pfvf *pfvf = rvu_get_pfvf(rvu, pcifunc);
+       int pkind, pf, vf, lbkid;
        u8 cgx_id, lmac_id;
-       int pkind, pf, vf;
        int err;
 
        pf = rvu_get_pf(pcifunc);
@@ -247,13 +247,24 @@ static int nix_interface_init(struct rvu *rvu, u16 pcifunc, int type, int nixlf)
        case NIX_INTF_TYPE_LBK:
                vf = (pcifunc & RVU_PFVF_FUNC_MASK) - 1;
 
+               /* If NIX1 block is present on the silicon then NIXes are
+                * assigned alternatively for lbk interfaces. NIX0 should
+                * send packets on lbk link 1 channels and NIX1 should send
+                * on lbk link 0 channels for the communication between
+                * NIX0 and NIX1.
+                */
+               lbkid = 0;
+               if (rvu->hw->lbk_links > 1)
+                       lbkid = vf & 0x1 ? 0 : 1;
+
                /* Note that AF's VFs work in pairs and talk over consecutive
                 * loopback channels.Therefore if odd number of AF VFs are
                 * enabled then the last VF remains with no pair.
                 */
-               pfvf->rx_chan_base = NIX_CHAN_LBK_CHX(0, vf);
-               pfvf->tx_chan_base = vf & 0x1 ? NIX_CHAN_LBK_CHX(0, vf - 1) :
-                                               NIX_CHAN_LBK_CHX(0, vf + 1);
+               pfvf->rx_chan_base = NIX_CHAN_LBK_CHX(lbkid, vf);
+               pfvf->tx_chan_base = vf & 0x1 ?
+                                       NIX_CHAN_LBK_CHX(lbkid, vf - 1) :
+                                       NIX_CHAN_LBK_CHX(lbkid, vf + 1);
                pfvf->rx_chan_cnt = 1;
                pfvf->tx_chan_cnt = 1;
                rvu_npc_install_promisc_entry(rvu, pcifunc, nixlf,
@@ -3183,7 +3194,7 @@ static int rvu_nix_block_init(struct rvu *rvu, struct nix_hw *nix_hw)
        hw->cgx = (cfg >> 12) & 0xF;
        hw->lmac_per_cgx = (cfg >> 8) & 0xF;
        hw->cgx_links = hw->cgx * hw->lmac_per_cgx;
-       hw->lbk_links = 1;
+       hw->lbk_links = (cfg >> 24) & 0xF;
        hw->sdp_links = 1;
 
        /* Initialize admin queue */