octeontx2-af: Set NIX link credits based on max LMAC
authorSunil Goutham <sgoutham@marvell.com>
Thu, 14 Jul 2022 05:35:55 +0000 (11:05 +0530)
committerDavid S. Miller <davem@davemloft.net>
Fri, 15 Jul 2022 11:02:45 +0000 (12:02 +0100)
When number of LMACs active on a CGX/RPM are 3, then
current NIX link credit config based on per lmac fifo
length which inturn  is calculated as
'lmac_fifo_len = total_fifo_len / 3', is incorrect. In HW
one of the LMAC gets half of the FIFO and rest gets 1/4th.

Signed-off-by: Nithin Dabilpuram <ndabilpuram@marvell.com>
Signed-off-by: Sunil Goutham <sgoutham@marvell.com>
Signed-off-by: Geetha Sowjanya <gakula@marvell.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
drivers/net/ethernet/marvell/octeontx2/af/cgx.c
drivers/net/ethernet/marvell/octeontx2/af/lmac_common.h
drivers/net/ethernet/marvell/octeontx2/af/rpm.c
drivers/net/ethernet/marvell/octeontx2/af/rpm.h
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 85eb4a6..c8724bf 100644 (file)
@@ -498,6 +498,32 @@ static u8 cgx_get_lmac_type(void *cgxd, int lmac_id)
        return (cfg >> CGX_LMAC_TYPE_SHIFT) & CGX_LMAC_TYPE_MASK;
 }
 
+static u32 cgx_get_lmac_fifo_len(void *cgxd, int lmac_id)
+{
+       struct cgx *cgx = cgxd;
+       u8 num_lmacs;
+       u32 fifo_len;
+
+       fifo_len = cgx->mac_ops->fifo_len;
+       num_lmacs = cgx->mac_ops->get_nr_lmacs(cgx);
+
+       switch (num_lmacs) {
+       case 1:
+               return fifo_len;
+       case 2:
+               return fifo_len / 2;
+       case 3:
+               /* LMAC0 gets half of the FIFO, reset 1/4th */
+               if (lmac_id == 0)
+                       return fifo_len / 2;
+               return fifo_len / 4;
+       case 4:
+       default:
+               return fifo_len / 4;
+       }
+       return 0;
+}
+
 /* Configure CGX LMAC in internal loopback mode */
 int cgx_lmac_internal_loopback(void *cgxd, int lmac_id, bool enable)
 {
@@ -1704,6 +1730,7 @@ static struct mac_ops     cgx_mac_ops    = {
        .tx_stats_cnt   =       18,
        .get_nr_lmacs   =       cgx_get_nr_lmacs,
        .get_lmac_type  =       cgx_get_lmac_type,
+       .lmac_fifo_len  =       cgx_get_lmac_fifo_len,
        .mac_lmac_intl_lbk =    cgx_lmac_internal_loopback,
        .mac_get_rx_stats  =    cgx_get_rx_stats,
        .mac_get_tx_stats  =    cgx_get_tx_stats,
index f30581b..52b6016 100644 (file)
@@ -80,6 +80,7 @@ struct mac_ops {
         */
        int                     (*get_nr_lmacs)(void *cgx);
        u8                      (*get_lmac_type)(void *cgx, int lmac_id);
+       u32                     (*lmac_fifo_len)(void *cgx, int lmac_id);
        int                     (*mac_lmac_intl_lbk)(void *cgx, int lmac_id,
                                                     bool enable);
        /* Register Stats related functions */
index 9025825..ef59de4 100644 (file)
@@ -22,6 +22,7 @@ static struct mac_ops rpm_mac_ops   = {
        .tx_stats_cnt   =       34,
        .get_nr_lmacs   =       rpm_get_nr_lmacs,
        .get_lmac_type  =       rpm_get_lmac_type,
+       .lmac_fifo_len  =       rpm_get_lmac_fifo_len,
        .mac_lmac_intl_lbk =    rpm_lmac_internal_loopback,
        .mac_get_rx_stats  =    rpm_get_rx_stats,
        .mac_get_tx_stats  =    rpm_get_tx_stats,
@@ -350,6 +351,35 @@ u8 rpm_get_lmac_type(void *rpmd, int lmac_id)
        return err;
 }
 
+u32 rpm_get_lmac_fifo_len(void *rpmd, int lmac_id)
+{
+       rpm_t *rpm = rpmd;
+       u64 hi_perf_lmac;
+       u8 num_lmacs;
+       u32 fifo_len;
+
+       fifo_len = rpm->mac_ops->fifo_len;
+       num_lmacs = rpm->mac_ops->get_nr_lmacs(rpm);
+
+       switch (num_lmacs) {
+       case 1:
+               return fifo_len;
+       case 2:
+               return fifo_len / 2;
+       case 3:
+               /* LMAC marked as hi_perf gets half of the FIFO and rest 1/4th */
+               hi_perf_lmac = rpm_read(rpm, 0, CGXX_CMRX_RX_LMACS);
+               hi_perf_lmac = (hi_perf_lmac >> 4) & 0x3ULL;
+               if (lmac_id == hi_perf_lmac)
+                       return fifo_len / 2;
+               return fifo_len / 4;
+       case 4:
+       default:
+               return fifo_len / 4;
+       }
+       return 0;
+}
+
 int rpm_lmac_internal_loopback(void *rpmd, int lmac_id, bool enable)
 {
        rpm_t *rpm = rpmd;
index 8247db8..c2bd6e5 100644 (file)
@@ -75,6 +75,7 @@
 /* Function Declarations */
 int rpm_get_nr_lmacs(void *rpmd);
 u8 rpm_get_lmac_type(void *rpmd, int lmac_id);
+u32 rpm_get_lmac_fifo_len(void *rpmd, int lmac_id);
 int rpm_lmac_internal_loopback(void *rpmd, int lmac_id, bool enable);
 void rpm_lmac_enadis_rx_pause_fwding(void *rpmd, int lmac_id, bool enable);
 int rpm_lmac_get_pause_frm_status(void *cgxd, int lmac_id, u8 *tx_pause,
index e5fdb7b..d15bc44 100644 (file)
@@ -827,7 +827,7 @@ int rvu_cgx_config_tx(void *cgxd, int lmac_id, bool enable);
 int rvu_cgx_prio_flow_ctrl_cfg(struct rvu *rvu, u16 pcifunc, u8 tx_pause, u8 rx_pause,
                               u16 pfc_en);
 int rvu_cgx_cfg_pause_frm(struct rvu *rvu, u16 pcifunc, u8 tx_pause, u8 rx_pause);
-
+u32 rvu_cgx_get_lmac_fifolen(struct rvu *rvu, int cgx, int lmac);
 int npc_get_nixlf_mcam_index(struct npc_mcam *mcam, u16 pcifunc, int nixlf,
                             int type);
 bool is_mcam_entry_enabled(struct rvu *rvu, struct npc_mcam *mcam, int blkaddr,
index 41c124b..addc69f 100644 (file)
@@ -861,6 +861,22 @@ u32 rvu_cgx_get_fifolen(struct rvu *rvu)
        return fifo_len;
 }
 
+u32 rvu_cgx_get_lmac_fifolen(struct rvu *rvu, int cgx, int lmac)
+{
+       struct mac_ops *mac_ops;
+       void *cgxd;
+
+       cgxd = rvu_cgx_pdata(cgx, rvu);
+       if (!cgxd)
+               return 0;
+
+       mac_ops = get_mac_ops(cgxd);
+       if (!mac_ops->lmac_fifo_len)
+               return 0;
+
+       return mac_ops->lmac_fifo_len(cgxd, lmac);
+}
+
 static int rvu_cgx_config_intlbk(struct rvu *rvu, u16 pcifunc, bool en)
 {
        int pf = rvu_get_pf(pcifunc);
index 1d3323d..0879a48 100644 (file)
@@ -4010,9 +4010,13 @@ linkcfg:
                return 0;
 
        /* Update transmit credits for CGX links */
-       lmac_fifo_len =
-               rvu_cgx_get_fifolen(rvu) /
-               cgx_get_lmac_cnt(rvu_cgx_pdata(cgx, rvu));
+       lmac_fifo_len = rvu_cgx_get_lmac_fifolen(rvu, cgx, lmac);
+       if (!lmac_fifo_len) {
+               dev_err(rvu->dev,
+                       "%s: Failed to get CGX/RPM%d:LMAC%d FIFO size\n",
+                       __func__, cgx, lmac);
+               return 0;
+       }
        return nix_config_link_credits(rvu, blkaddr, link, pcifunc,
                                       (lmac_fifo_len - req->maxlen) / 16);
 }
@@ -4064,7 +4068,10 @@ static void nix_link_config(struct rvu *rvu, int blkaddr,
        struct rvu_hwinfo *hw = rvu->hw;
        int cgx, lmac_cnt, slink, link;
        u16 lbk_max_frs, lmac_max_frs;
+       unsigned long lmac_bmap;
        u64 tx_credits, cfg;
+       u64 lmac_fifo_len;
+       int iter;
 
        rvu_get_lbk_link_max_frs(rvu, &lbk_max_frs);
        rvu_get_lmac_link_max_frs(rvu, &lmac_max_frs);
@@ -4098,12 +4105,23 @@ static void nix_link_config(struct rvu *rvu, int blkaddr,
                /* Skip when cgx is not available or lmac cnt is zero */
                if (lmac_cnt <= 0)
                        continue;
-               tx_credits = ((rvu_cgx_get_fifolen(rvu) / lmac_cnt) -
-                              lmac_max_frs) / 16;
-               /* Enable credits and set credit pkt count to max allowed */
-               cfg =  (tx_credits << 12) | (0x1FF << 2) | BIT_ULL(1);
                slink = cgx * hw->lmac_per_cgx;
-               for (link = slink; link < (slink + lmac_cnt); link++) {
+
+               /* Get LMAC id's from bitmap */
+               lmac_bmap = cgx_get_lmac_bmap(rvu_cgx_pdata(cgx, rvu));
+               for_each_set_bit(iter, &lmac_bmap, MAX_LMAC_PER_CGX) {
+                       lmac_fifo_len = rvu_cgx_get_lmac_fifolen(rvu, cgx, iter);
+                       if (!lmac_fifo_len) {
+                               dev_err(rvu->dev,
+                                       "%s: Failed to get CGX/RPM%d:LMAC%d FIFO size\n",
+                                       __func__, cgx, iter);
+                               continue;
+                       }
+                       tx_credits = (lmac_fifo_len - lmac_max_frs) / 16;
+                       /* Enable credits and set credit pkt count to max allowed */
+                       cfg =  (tx_credits << 12) | (0x1FF << 2) | BIT_ULL(1);
+
+                       link = iter + slink;
                        nix_hw->tx_credits[link] = tx_credits;
                        rvu_write64(rvu, blkaddr,
                                    NIX_AF_TX_LINKX_NORM_CREDIT(link), cfg);