]> www.infradead.org Git - users/jedix/linux-maple.git/commitdiff
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 85eb4a6f4fcf977dbec0fc9389c054ef12ff5c71..c8724bfa86b0e089aae2580968c9680de8c9ee2e 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 f30581bf0688134f73ee1631cd0840e9f118c2f9..52b6016789fa42dffbaa21115dc7aee7e43d5042 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 9025825597a23b458a712910c8bd0c6bf778e79a..ef59de43b11e6dfbf62cae368a79b76597b1df2a 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 8247db8c1d363c9667cd8b18bd6a4bdbb60e1c42..c2bd6e54ea51e42c655feca962c506250a4bddc6 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 e5fdb7b6265152b0861e080773a062050a4693bc..d15bc443335dba20c2fcb07a62bbdc2a5b9bf4af 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 41c124b7aea9d0d11d37a55314fd37435d89a9ec..addc69f4b65c6dd1287a40ddab658908155130af 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 1d3323da693013f34f7e1569d95f3a9a2dd26ad8..0879a48411f31487597510370965680c2fd763d0 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);