]> asedeno.scripts.mit.edu Git - linux.git/commitdiff
octeontx2-af: Start/Stop traffic in CGX along with NPC
authorSubbaraya Sundeep <sbhatta@marvell.com>
Thu, 14 Nov 2019 05:26:33 +0000 (10:56 +0530)
committerDavid S. Miller <davem@davemloft.net>
Fri, 15 Nov 2019 02:09:16 +0000 (18:09 -0800)
Traffic for a CGX mapped NIXLF can be stopped by disabling entries
in NPC MCAM or by configuring CGX and mailbox messages exist for the
two options. If traffic is stopped at CGX then VFs of that PF are
also effected hence CGX traffic should be started/stopped by
tracking all the users of it. This patch implements that CGX users
tracking. CGX is also configured along with NPC if required.

Also removed a check which mandates even number of LBK VFs.

Signed-off-by: Subbaraya Sundeep <sbhatta@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/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 3985053fa217c43e2d352dde4977bb90a1774e72..5c190c3ce8987dab3c54a4b5f77adb35a1740151 100644 (file)
@@ -2364,18 +2364,6 @@ static int rvu_enable_sriov(struct rvu *rvu)
        if (vfs > chans)
                vfs = chans;
 
-       /* AF's VFs work in pairs and talk over consecutive loopback channels.
-        * Thus we want to enable maximum even number of VFs. In case
-        * odd number of VFs are available then the last VF on the list
-        * remains disabled.
-        */
-       if (vfs & 0x1) {
-               dev_warn(&pdev->dev,
-                        "Number of VFs should be even. Enabling %d out of %d.\n",
-                        vfs - 1, vfs);
-               vfs--;
-       }
-
        if (!vfs)
                return 0;
 
index 7370864c546cd805207296e8d659df60f4f4347a..b252d8683aa73b10ecee11288a533f1c4c6167b7 100644 (file)
@@ -179,6 +179,9 @@ struct rvu_pfvf {
        struct mcam_entry entry;
        int rxvlan_index;
        bool rxvlan;
+
+       bool    cgx_in_use; /* this PF/VF using CGX? */
+       int     cgx_users;  /* number of cgx users - used only by PFs */
 };
 
 struct nix_txsch {
@@ -306,6 +309,7 @@ struct rvu {
        struct                  workqueue_struct *cgx_evh_wq;
        spinlock_t              cgx_evq_lock; /* cgx event queue lock */
        struct list_head        cgx_evq_head; /* cgx event queue head */
+       struct mutex            cgx_cfg_lock; /* serialize cgx configuration */
 
        char mkex_pfl_name[MKEX_NAME_LEN]; /* Configured MKEX profile name */
 
@@ -410,6 +414,7 @@ int rvu_cgx_exit(struct rvu *rvu);
 void *rvu_cgx_pdata(u8 cgx_id, struct rvu *rvu);
 int rvu_cgx_config_rxtx(struct rvu *rvu, u16 pcifunc, bool start);
 void rvu_cgx_enadis_rx_bp(struct rvu *rvu, int pf, bool enable);
+int rvu_cgx_start_stop_io(struct rvu *rvu, u16 pcifunc, bool start);
 int rvu_cgx_nix_cuml_stats(struct rvu *rvu, void *cgxd, int lmac_id, int index,
                           int rxtxflag, u64 *stat);
 /* NPA APIs */
index 7e110b772aa582441404eb9d901c0270fd765044..0bbb2eb1446e9e37bd5c0ade46d0dc1f2c5639c1 100644 (file)
@@ -308,6 +308,8 @@ int rvu_cgx_init(struct rvu *rvu)
        if (err)
                return err;
 
+       mutex_init(&rvu->cgx_cfg_lock);
+
        /* Ensure event handler registration is completed, before
         * we turn on the links
         */
@@ -638,3 +640,50 @@ int rvu_cgx_nix_cuml_stats(struct rvu *rvu, void *cgxd, int lmac_id,
 
        return 0;
 }
+
+int rvu_cgx_start_stop_io(struct rvu *rvu, u16 pcifunc, bool start)
+{
+       struct rvu_pfvf *parent_pf, *pfvf;
+       int cgx_users, err = 0;
+
+       if (!is_pf_cgxmapped(rvu, rvu_get_pf(pcifunc)))
+               return 0;
+
+       parent_pf = &rvu->pf[rvu_get_pf(pcifunc)];
+       pfvf = rvu_get_pfvf(rvu, pcifunc);
+
+       mutex_lock(&rvu->cgx_cfg_lock);
+
+       if (start && pfvf->cgx_in_use)
+               goto exit;  /* CGX is already started hence nothing to do */
+       if (!start && !pfvf->cgx_in_use)
+               goto exit; /* CGX is already stopped hence nothing to do */
+
+       if (start) {
+               cgx_users = parent_pf->cgx_users;
+               parent_pf->cgx_users++;
+       } else {
+               parent_pf->cgx_users--;
+               cgx_users = parent_pf->cgx_users;
+       }
+
+       /* Start CGX when first of all NIXLFs is started.
+        * Stop CGX when last of all NIXLFs is stopped.
+        */
+       if (!cgx_users) {
+               err = rvu_cgx_config_rxtx(rvu, pcifunc & ~RVU_PFVF_FUNC_MASK,
+                                         start);
+               if (err) {
+                       dev_err(rvu->dev, "Unable to %s CGX\n",
+                               start ? "start" : "stop");
+                       /* Revert the usage count in case of error */
+                       parent_pf->cgx_users = start ? parent_pf->cgx_users  - 1
+                                              : parent_pf->cgx_users  + 1;
+                       goto exit;
+               }
+       }
+       pfvf->cgx_in_use = start;
+exit:
+       mutex_unlock(&rvu->cgx_cfg_lock);
+       return err;
+}
index 63190b89f7094e5f87459a96e0f26442de8f90a9..8a59f7d53fbff0cfe5dcaac13ad0346a496117f7 100644 (file)
@@ -194,6 +194,11 @@ static int nix_interface_init(struct rvu *rvu, u16 pcifunc, int type, int nixlf)
                break;
        case NIX_INTF_TYPE_LBK:
                vf = (pcifunc & RVU_PFVF_FUNC_MASK) - 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);
@@ -3120,7 +3125,8 @@ int rvu_mbox_handler_nix_lf_start_rx(struct rvu *rvu, struct msg_req *req,
                return err;
 
        rvu_npc_enable_default_entries(rvu, pcifunc, nixlf);
-       return 0;
+
+       return rvu_cgx_start_stop_io(rvu, pcifunc, true);
 }
 
 int rvu_mbox_handler_nix_lf_stop_rx(struct rvu *rvu, struct msg_req *req,
@@ -3134,7 +3140,8 @@ int rvu_mbox_handler_nix_lf_stop_rx(struct rvu *rvu, struct msg_req *req,
                return err;
 
        rvu_npc_disable_default_entries(rvu, pcifunc, nixlf);
-       return 0;
+
+       return rvu_cgx_start_stop_io(rvu, pcifunc, false);
 }
 
 void rvu_nix_lf_teardown(struct rvu *rvu, u16 pcifunc, int blkaddr, int nixlf)
@@ -3150,6 +3157,8 @@ void rvu_nix_lf_teardown(struct rvu *rvu, u16 pcifunc, int blkaddr, int nixlf)
        nix_rx_sync(rvu, blkaddr);
        nix_txschq_free(rvu, pcifunc);
 
+       rvu_cgx_start_stop_io(rvu, pcifunc, false);
+
        if (pfvf->sq_ctx) {
                ctx_req.ctype = NIX_AQ_CTYPE_SQ;
                err = nix_lf_hwctx_disable(rvu, &ctx_req);