octeontx2-af: cn10k: Set NIX DWRR MTU for CN10KB silicon
authorSunil Goutham <sgoutham@marvell.com>
Mon, 12 Jun 2023 06:04:21 +0000 (11:34 +0530)
committerDavid S. Miller <davem@davemloft.net>
Tue, 13 Jun 2023 08:54:57 +0000 (09:54 +0100)
The DWRR MTU config added for SDP and RPM/LBK links on CN10K
silicon is further extended on CK10KB silicon variant and made
it configurable. Now there are 4 DWRR MTU config to choose while
setting transmit scheduler's RR_WEIGHT.

Here we are reserving one config for each of RPM, SDP and LBK.
NIXX_AF_DWRR_MTUX(0) ---> RPM
NIXX_AF_DWRR_MTUX(1) ---> SDP
NIXX_AF_DWRR_MTUX(2) ---> LBK

PF/VF drivers can choose the DWRR_MTU to be used by setting
SMQX_CFG[pkt_link_type] to one of above. TLx_SCHEDULE[RR_WEIGHT]
is to be as configured 'quantum / 2^DWRR_MTUX[MTU]'. DWRR_MTU
of each link is exposed to PF/VF drivers via mailbox for
RR_WEIGHT calculation.

Signed-off-by: Sunil Goutham <sgoutham@marvell.com>
Signed-off-by: Geetha sowjanya <gakula@marvell.com>
Signed-off-by: Naveen Mamindlapalli <naveenm@marvell.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
drivers/net/ethernet/marvell/octeontx2/af/common.h
drivers/net/ethernet/marvell/octeontx2/af/mbox.h
drivers/net/ethernet/marvell/octeontx2/af/rvu.h
drivers/net/ethernet/marvell/octeontx2/af/rvu_devlink.c
drivers/net/ethernet/marvell/octeontx2/af/rvu_nix.c
drivers/net/ethernet/marvell/octeontx2/af/rvu_reg.h
drivers/net/ethernet/marvell/octeontx2/nic/otx2_common.c
drivers/net/ethernet/marvell/octeontx2/nic/otx2_common.h

index f5bf719..2436c1f 100644 (file)
@@ -145,6 +145,13 @@ enum nix_scheduler {
 #define TXSCH_TL1_DFLT_RR_PRIO         (0x7ull)
 #define CN10K_MAX_DWRR_WEIGHT          16384 /* Weight is 14bit on CN10K */
 
+/* Don't change the order as on CN10K (except CN10KB)
+ * SMQX_CFG[SDP] value should be 1 for SDP flows.
+ */
+#define SMQ_LINK_TYPE_RPM              0
+#define SMQ_LINK_TYPE_SDP              1
+#define SMQ_LINK_TYPE_LBK              2
+
 /* Min/Max packet sizes, excluding FCS */
 #define        NIC_HW_MIN_FRS                  40
 #define        NIC_HW_MAX_FRS                  9212
index 671fcf8..1794ef0 100644 (file)
@@ -1245,7 +1245,9 @@ struct nix_hw_info {
        u16 min_mtu;
        u32 rpm_dwrr_mtu;
        u32 sdp_dwrr_mtu;
-       u64 rsvd[16]; /* Add reserved fields for future expansion */
+       u32 lbk_dwrr_mtu;
+       u32 rsvd32[1];
+       u64 rsvd[15]; /* Add reserved fields for future expansion */
 };
 
 struct nix_bandprof_alloc_req {
index d655bf0..12e644b 100644 (file)
@@ -346,6 +346,7 @@ struct hw_cap {
        bool    per_pf_mbox_regs; /* PF mbox specified in per PF registers ? */
        bool    programmable_chans; /* Channels programmable ? */
        bool    ipolicer;
+       bool    nix_multiple_dwrr_mtu;   /* Multiple DWRR_MTU to choose from */
        bool    npc_hash_extract; /* Hash extract enabled ? */
        bool    npc_exact_match_enabled; /* Exact match supported ? */
 };
@@ -802,6 +803,7 @@ int nix_aq_context_read(struct rvu *rvu, struct nix_hw *nix_hw,
                        struct nix_cn10k_aq_enq_rsp *aq_rsp,
                        u16 pcifunc, u8 ctype, u32 qidx);
 int rvu_get_nix_blkaddr(struct rvu *rvu, u16 pcifunc);
+int nix_get_dwrr_mtu_reg(struct rvu_hwinfo *hw, int smq_link_type);
 u32 convert_dwrr_mtu_to_bytes(u8 dwrr_mtu);
 u32 convert_bytes_to_dwrr_mtu(u32 bytes);
 
index 5485496..41df5ac 100644 (file)
@@ -1413,7 +1413,8 @@ static int rvu_af_dl_dwrr_mtu_set(struct devlink *devlink, u32 id,
        u64 dwrr_mtu;
 
        dwrr_mtu = convert_bytes_to_dwrr_mtu(ctx->val.vu32);
-       rvu_write64(rvu, BLKADDR_NIX0, NIX_AF_DWRR_RPM_MTU, dwrr_mtu);
+       rvu_write64(rvu, BLKADDR_NIX0,
+                   nix_get_dwrr_mtu_reg(rvu->hw, SMQ_LINK_TYPE_RPM), dwrr_mtu);
 
        return 0;
 }
@@ -1428,7 +1429,8 @@ static int rvu_af_dl_dwrr_mtu_get(struct devlink *devlink, u32 id,
        if (!rvu->hw->cap.nix_common_dwrr_mtu)
                return -EOPNOTSUPP;
 
-       dwrr_mtu = rvu_read64(rvu, BLKADDR_NIX0, NIX_AF_DWRR_RPM_MTU);
+       dwrr_mtu = rvu_read64(rvu, BLKADDR_NIX0,
+                             nix_get_dwrr_mtu_reg(rvu->hw, SMQ_LINK_TYPE_RPM));
        ctx->val.vu32 = convert_dwrr_mtu_to_bytes(dwrr_mtu);
 
        return 0;
index ee52b86..f069d13 100644 (file)
@@ -191,6 +191,18 @@ struct nix_hw *get_nix_hw(struct rvu_hwinfo *hw, int blkaddr)
        return NULL;
 }
 
+int nix_get_dwrr_mtu_reg(struct rvu_hwinfo *hw, int smq_link_type)
+{
+       if (hw->cap.nix_multiple_dwrr_mtu)
+               return NIX_AF_DWRR_MTUX(smq_link_type);
+
+       if (smq_link_type == SMQ_LINK_TYPE_SDP)
+               return NIX_AF_DWRR_SDP_MTU;
+
+       /* Here it's same reg for RPM and LBK */
+       return NIX_AF_DWRR_RPM_MTU;
+}
+
 u32 convert_dwrr_mtu_to_bytes(u8 dwrr_mtu)
 {
        dwrr_mtu &= 0x1FULL;
@@ -3191,10 +3203,16 @@ static int nix_setup_txschq(struct rvu *rvu, struct nix_hw *nix_hw, int blkaddr)
        }
 
        /* Setup a default value of 8192 as DWRR MTU */
-       if (rvu->hw->cap.nix_common_dwrr_mtu) {
-               rvu_write64(rvu, blkaddr, NIX_AF_DWRR_RPM_MTU,
+       if (rvu->hw->cap.nix_common_dwrr_mtu ||
+           rvu->hw->cap.nix_multiple_dwrr_mtu) {
+               rvu_write64(rvu, blkaddr,
+                           nix_get_dwrr_mtu_reg(rvu->hw, SMQ_LINK_TYPE_RPM),
                            convert_bytes_to_dwrr_mtu(8192));
-               rvu_write64(rvu, blkaddr, NIX_AF_DWRR_SDP_MTU,
+               rvu_write64(rvu, blkaddr,
+                           nix_get_dwrr_mtu_reg(rvu->hw, SMQ_LINK_TYPE_LBK),
+                           convert_bytes_to_dwrr_mtu(8192));
+               rvu_write64(rvu, blkaddr,
+                           nix_get_dwrr_mtu_reg(rvu->hw, SMQ_LINK_TYPE_SDP),
                            convert_bytes_to_dwrr_mtu(8192));
        }
 
@@ -3292,19 +3310,28 @@ int rvu_mbox_handler_nix_get_hw_info(struct rvu *rvu, struct msg_req *req,
 
        rsp->min_mtu = NIC_HW_MIN_FRS;
 
-       if (!rvu->hw->cap.nix_common_dwrr_mtu) {
+       if (!rvu->hw->cap.nix_common_dwrr_mtu &&
+           !rvu->hw->cap.nix_multiple_dwrr_mtu) {
                /* Return '1' on OTx2 */
                rsp->rpm_dwrr_mtu = 1;
                rsp->sdp_dwrr_mtu = 1;
+               rsp->lbk_dwrr_mtu = 1;
                return 0;
        }
 
-       dwrr_mtu = rvu_read64(rvu, BLKADDR_NIX0, NIX_AF_DWRR_RPM_MTU);
+       /* Return DWRR_MTU for TLx_SCHEDULE[RR_WEIGHT] config */
+       dwrr_mtu = rvu_read64(rvu, blkaddr,
+                             nix_get_dwrr_mtu_reg(rvu->hw, SMQ_LINK_TYPE_RPM));
        rsp->rpm_dwrr_mtu = convert_dwrr_mtu_to_bytes(dwrr_mtu);
 
-       dwrr_mtu = rvu_read64(rvu, BLKADDR_NIX0, NIX_AF_DWRR_SDP_MTU);
+       dwrr_mtu = rvu_read64(rvu, blkaddr,
+                             nix_get_dwrr_mtu_reg(rvu->hw, SMQ_LINK_TYPE_SDP));
        rsp->sdp_dwrr_mtu = convert_dwrr_mtu_to_bytes(dwrr_mtu);
 
+       dwrr_mtu = rvu_read64(rvu, blkaddr,
+                             nix_get_dwrr_mtu_reg(rvu->hw, SMQ_LINK_TYPE_LBK));
+       rsp->lbk_dwrr_mtu = convert_dwrr_mtu_to_bytes(dwrr_mtu);
+
        return 0;
 }
 
@@ -4371,8 +4398,11 @@ static void rvu_nix_setup_capabilities(struct rvu *rvu, int blkaddr)
         * Check if HW uses a common MTU for all DWRR quantum configs.
         * On OcteonTx2 this register field is '0'.
         */
-       if (((hw_const >> 56) & 0x10) == 0x10)
+       if ((((hw_const >> 56) & 0x10) == 0x10) && !(hw_const & BIT_ULL(61)))
                hw->cap.nix_common_dwrr_mtu = true;
+
+       if (hw_const & BIT_ULL(61))
+               hw->cap.nix_multiple_dwrr_mtu = true;
 }
 
 static int rvu_nix_block_init(struct rvu *rvu, struct nix_hw *nix_hw)
index 7007f0b..b42e631 100644 (file)
 #define NIX_AF_DEBUG_NPC_RESP_DATAX(a)          (0x680 | (a) << 3)
 #define NIX_AF_SMQX_CFG(a)                      (0x700 | (a) << 16)
 #define NIX_AF_SQM_DBG_CTL_STATUS               (0x750)
-#define NIX_AF_DWRR_SDP_MTU                     (0x790)
+#define NIX_AF_DWRR_SDP_MTU                     (0x790) /* All CN10K except CN10KB */
+#define NIX_AF_DWRR_MTUX(a)                    (0x790 | (a) << 16) /* Only for CN10KB */
 #define NIX_AF_DWRR_RPM_MTU                     (0x7A0)
 #define NIX_AF_PSE_CHANNEL_LEVEL                (0x800)
 #define NIX_AF_PSE_SHAPER_CFG                   (0x810)
index a79cb68..77c8f65 100644 (file)
@@ -8,6 +8,7 @@
 #include <linux/interrupt.h>
 #include <linux/pci.h>
 #include <net/tso.h>
+#include <linux/bitfield.h>
 
 #include "otx2_reg.h"
 #include "otx2_common.h"
@@ -642,6 +643,10 @@ int otx2_txschq_config(struct otx2_nic *pfvf, int lvl, int prio, bool txschq_for
                req->regval[0] = ((u64)pfvf->tx_max_pktlen << 8) | OTX2_MIN_MTU;
                req->regval[0] |= (0x20ULL << 51) | (0x80ULL << 39) |
                                  (0x2ULL << 36);
+               /* Set link type for DWRR MTU selection on CN10K silicons */
+               if (!is_dev_otx2(pfvf->pdev))
+                       req->regval[0] |= FIELD_PREP(GENMASK_ULL(58, 57),
+                                               (u64)hw->smq_link_type);
                req->num_regs++;
                /* MDQ config */
                parent = schq_list[NIX_TXSCH_LVL_TL4][prio];
@@ -1824,6 +1829,17 @@ void otx2_set_cints_affinity(struct otx2_nic *pfvf)
        }
 }
 
+static u32 get_dwrr_mtu(struct otx2_nic *pfvf, struct nix_hw_info *hw)
+{
+       if (is_otx2_lbkvf(pfvf->pdev)) {
+               pfvf->hw.smq_link_type = SMQ_LINK_TYPE_LBK;
+               return hw->lbk_dwrr_mtu;
+       }
+
+       pfvf->hw.smq_link_type = SMQ_LINK_TYPE_RPM;
+       return hw->rpm_dwrr_mtu;
+}
+
 u16 otx2_get_max_mtu(struct otx2_nic *pfvf)
 {
        struct nix_hw_info *rsp;
@@ -1853,7 +1869,7 @@ u16 otx2_get_max_mtu(struct otx2_nic *pfvf)
                max_mtu = rsp->max_mtu - 8 - OTX2_ETH_HLEN;
 
                /* Also save DWRR MTU, needed for DWRR weight calculation */
-               pfvf->hw.dwrr_mtu = rsp->rpm_dwrr_mtu;
+               pfvf->hw.dwrr_mtu = get_dwrr_mtu(pfvf, rsp);
                if (!pfvf->hw.dwrr_mtu)
                        pfvf->hw.dwrr_mtu = 1;
        }
index a9ed15d..ba80911 100644 (file)
@@ -227,6 +227,7 @@ struct otx2_hw {
        u16                     txschq_list[NIX_TXSCH_LVL_CNT][MAX_TXSCHQ_PER_FUNC];
        u16                     matchall_ipolicer;
        u32                     dwrr_mtu;
+       u8                      smq_link_type;
 
        /* HW settings, coalescing etc */
        u16                     rx_chan_base;