@@ -145,6 +145,13 @@ enum nix_scheduler {
#define TXSCH_TL1_DFLT_RR_PRIO (0x1ull)
#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
@@ -1237,7 +1237,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 {
@@ -344,6 +344,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 ? */
};
@@ -785,6 +786,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);
@@ -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;
@@ -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;
@@ -3125,10 +3137,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));
}
@@ -3226,19 +3244,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;
}
@@ -4305,8 +4332,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)
@@ -271,7 +271,8 @@
#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)
@@ -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"
@@ -616,6 +617,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];
@@ -1734,6 +1739,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;
@@ -1763,7 +1779,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;
}
@@ -209,6 +209,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;