#define NIX_MAX_BPF_COUNT_MID_LAYER 8
#define NIX_MAX_BPF_COUNT_TOP_LAYER 1
+#define NIX_BPF_PRECOLOR_GEN_TABLE_SIZE 16
+#define NIX_BPF_PRECOLOR_VLAN_TABLE_SIZE 16
+#define NIX_BPF_PRECOLOR_DSCP_TABLE_SIZE 64
+
#define NIX_BPF_LEVEL_F_MASK \
(ROC_NIX_BPF_LEVEL_F_LEAF | ROC_NIX_BPF_LEVEL_F_MID | \
ROC_NIX_BPF_LEVEL_F_TOP)
+#define NIX_RD_STATS(val) plt_read64(nix->base + NIX_LF_RX_STATX(val))
+#define NIX_RST_STATS(val) plt_write64(0, nix->base + NIX_LF_RX_STATX(val))
+
static uint8_t sw_to_hw_lvl_map[] = {NIX_RX_BAND_PROF_LAYER_LEAF,
NIX_RX_BAND_PROF_LAYER_MIDDLE,
NIX_RX_BAND_PROF_LAYER_TOP};
static inline uint64_t
meter_rate_to_nix(uint64_t value, uint64_t *exponent_p, uint64_t *mantissa_p,
- uint64_t *div_exp_p)
+ uint64_t *div_exp_p, uint32_t timeunit_p)
{
uint64_t div_exp, exponent, mantissa;
+ uint32_t time_us = timeunit_p;
/* Boundary checks */
if (value < NIX_BPF_RATE_MIN || value > NIX_BPF_RATE_MAX)
return 0;
- if (value <= NIX_BPF_RATE(0, 0, 0)) {
+ if (value <= NIX_BPF_RATE(time_us, 0, 0, 0)) {
/* Calculate rate div_exp and mantissa using
* the following formula:
*
*mantissa_p = mantissa;
/* Calculate real rate value */
- return NIX_BPF_RATE(exponent, mantissa, div_exp);
+ return NIX_BPF_RATE(time_us, exponent, mantissa, div_exp);
}
static inline uint64_t
return NIX_BPF_BURST(exponent, mantissa);
}
+static inline void
+nix_lf_bpf_dump(__io struct nix_band_prof_s *bpf)
+{
+ plt_dump("W0: cir_mantissa \t\t\t%d\nW0: pebs_mantissa \t\t\t0x%03x",
+ bpf->cir_mantissa, bpf->pebs_mantissa);
+ plt_dump("W0: peir_mantissa \t\t\t\t%d\nW0: cbs_exponent \t\t\t%d",
+ bpf->peir_mantissa, bpf->cbs_exponent);
+ plt_dump("W0: cir_exponent \t\t\t%d\nW0: pebs_exponent \t\t\t%d",
+ bpf->cir_exponent, bpf->pebs_exponent);
+ plt_dump("W0: peir_exponent \t\t\t%d\n", bpf->peir_exponent);
+ plt_dump("W0: tnl_ena \t\t\t%d\n", bpf->tnl_ena);
+ plt_dump("W0: icolor \t\t\t%d\n", bpf->icolor);
+ plt_dump("W0: pc_mode \t\t\t%d\n", bpf->pc_mode);
+ plt_dump("W1: hl_en \t\t%d\nW1: band_prof_id \t\t%d", bpf->hl_en,
+ bpf->band_prof_id);
+ plt_dump("W1: meter_algo \t\t%d\nW1: rc_action \t\t%d", bpf->meter_algo,
+ bpf->rc_action);
+ plt_dump("W1: yc_action \t\t\t%d\nW1: gc_action \t\t\t%d",
+ bpf->yc_action, bpf->gc_action);
+ plt_dump("W1: adjust_mantissa\t\t\t%d\nW1: adjust_exponent \t\t\t%d",
+ bpf->adjust_mantissa, bpf->adjust_exponent);
+ plt_dump("W1: rdiv \t\t\t%d\n", bpf->rdiv);
+ plt_dump("W1: l_select \t\t%d\nW2: lmode \t\t%d", bpf->l_sellect,
+ bpf->lmode);
+ plt_dump("W1: cbs_mantissa \t\t\t%d\n", bpf->cbs_mantissa);
+ plt_dump("W2: tsa \t\t\t0x%" PRIx64 "\n", (uint64_t)bpf->ts);
+ plt_dump("W3: c_accum \t\t%d\nW3: pe_accum \t\t%d", bpf->c_accum,
+ bpf->pe_accum);
+ plt_dump("W4: green_pkt_pass \t\t\t0x%" PRIx64 "",
+ (uint64_t)bpf->green_pkt_pass);
+ plt_dump("W5: yellow_pkt_pass \t\t\t0x%" PRIx64 "",
+ (uint64_t)bpf->yellow_pkt_pass);
+ plt_dump("W6: red_pkt_pass \t\t\t0x%" PRIx64 "",
+ (uint64_t)bpf->red_pkt_pass);
+ plt_dump("W7: green_octs_pass \t\t\t0x%" PRIx64 "",
+ (uint64_t)bpf->green_octs_pass);
+ plt_dump("W8: yellow_octs_pass \t\t\t0x%" PRIx64 "",
+ (uint64_t)bpf->yellow_octs_pass);
+ plt_dump("W9: red_octs_pass \t\t\t0x%" PRIx64 "",
+ (uint64_t)bpf->red_octs_pass);
+ plt_dump("W10: green_pkt_drop \t\t\t0x%" PRIx64 "",
+ (uint64_t)bpf->green_pkt_drop);
+ plt_dump("W11: yellow_pkt_drop \t\t\t0x%" PRIx64 "",
+ (uint64_t)bpf->yellow_pkt_drop);
+ plt_dump("W12: red_pkt_drop \t\t\t0x%" PRIx64 "",
+ (uint64_t)bpf->red_pkt_drop);
+ plt_dump("W13: green_octs_drop \t\t\t0x%" PRIx64 "",
+ (uint64_t)bpf->green_octs_drop);
+ plt_dump("W14: yellow_octs_drop \t\t\t0x%" PRIx64 "",
+ (uint64_t)bpf->yellow_octs_drop);
+ plt_dump("W15: red_octs_drop \t\t\t0x%" PRIx64 "",
+ (uint64_t)bpf->red_octs_drop);
+}
+
+static inline void
+nix_precolor_conv_table_write(struct roc_nix *roc_nix, uint64_t val,
+ uint32_t off)
+{
+ struct nix *nix = roc_nix_to_nix_priv(roc_nix);
+ int64_t *addr;
+
+ addr = PLT_PTR_ADD(nix->base, off);
+ /* FIXME: Currently writing to this register throwing kernel dump.
+ * plt_write64(val, addr);
+ */
+ PLT_SET_USED(val);
+ PLT_SET_USED(addr);
+}
+
+static uint8_t
+nix_precolor_vlan_table_update(struct roc_nix *roc_nix,
+ struct roc_nix_bpf_precolor *tbl)
+{
+ uint64_t val = 0, i;
+ uint8_t tn_ena;
+ uint32_t off;
+
+ for (i = 0; i < tbl->count; i++)
+ val |= (((uint64_t)tbl->color[i]) << (2 * i));
+
+ if (tbl->mode == ROC_NIX_BPF_PC_MODE_VLAN_INNER) {
+ off = NIX_LF_RX_VLAN1_COLOR_CONV;
+ tn_ena = true;
+ } else {
+ off = NIX_LF_RX_VLAN0_COLOR_CONV;
+ tn_ena = false;
+ }
+
+ nix_precolor_conv_table_write(roc_nix, val, off);
+ return tn_ena;
+}
+
+static uint8_t
+nix_precolor_inner_dscp_table_update(struct roc_nix *roc_nix,
+ struct roc_nix_bpf_precolor *tbl)
+{
+ uint64_t val_lo = 0, val_hi = 0, i, j;
+
+ for (i = 0, j = 0; i < (tbl->count / 2); i++, j++)
+ val_lo |= (((uint64_t)tbl->color[i]) << (2 * j));
+
+ for (j = 0; i < tbl->count; i++, j++)
+ val_hi |= (((uint64_t)tbl->color[i]) << (2 * j));
+
+ nix_precolor_conv_table_write(roc_nix, val_lo,
+ NIX_LF_RX_IIP_COLOR_CONV_LO);
+ nix_precolor_conv_table_write(roc_nix, val_hi,
+ NIX_LF_RX_IIP_COLOR_CONV_HI);
+
+ return true;
+}
+
+static uint8_t
+nix_precolor_outer_dscp_table_update(struct roc_nix *roc_nix,
+ struct roc_nix_bpf_precolor *tbl)
+{
+ uint64_t val_lo = 0, val_hi = 0, i, j;
+
+ for (i = 0, j = 0; i < (tbl->count / 2); i++, j++)
+ val_lo |= (((uint64_t)tbl->color[i]) << (2 * j));
+
+ for (j = 0; i < tbl->count; i++, j++)
+ val_hi |= (((uint64_t)tbl->color[i]) << (2 * j));
+
+ nix_precolor_conv_table_write(roc_nix, val_lo,
+ NIX_LF_RX_OIP_COLOR_CONV_LO);
+ nix_precolor_conv_table_write(roc_nix, val_hi,
+ NIX_LF_RX_OIP_COLOR_CONV_HI);
+
+ return false;
+}
+
+static uint8_t
+nix_precolor_gen_table_update(struct roc_nix *roc_nix,
+ struct roc_nix_bpf_precolor *tbl)
+{
+ uint64_t val = 0, i;
+ uint8_t tn_ena;
+ uint32_t off;
+
+ for (i = 0; i < tbl->count; i++)
+ val |= (((uint64_t)tbl->color[i]) << (2 * i));
+
+ if (tbl->mode == ROC_NIX_BPF_PC_MODE_GEN_INNER) {
+ off = NIX_LF_RX_GEN_COLOR_CONVX(1);
+ tn_ena = true;
+ } else {
+ off = NIX_LF_RX_GEN_COLOR_CONVX(0);
+ tn_ena = false;
+ }
+
+ nix_precolor_conv_table_write(roc_nix, val, off);
+ return tn_ena;
+}
+
uint8_t
roc_nix_bpf_level_to_idx(enum roc_nix_bpf_level_flag level_f)
{
return idx;
}
+uint8_t
+roc_nix_bpf_stats_to_idx(enum roc_nix_bpf_stats level_f)
+{
+ uint8_t idx;
+
+ if (level_f & ROC_NIX_BPF_GREEN_PKT_F_PASS)
+ idx = 0;
+ else if (level_f & ROC_NIX_BPF_GREEN_OCTS_F_PASS)
+ idx = 1;
+ else if (level_f & ROC_NIX_BPF_GREEN_PKT_F_DROP)
+ idx = 2;
+ else if (level_f & ROC_NIX_BPF_GREEN_OCTS_F_DROP)
+ idx = 3;
+ else if (level_f & ROC_NIX_BPF_YELLOW_PKT_F_PASS)
+ idx = 4;
+ else if (level_f & ROC_NIX_BPF_YELLOW_OCTS_F_PASS)
+ idx = 5;
+ else if (level_f & ROC_NIX_BPF_YELLOW_PKT_F_DROP)
+ idx = 6;
+ else if (level_f & ROC_NIX_BPF_YELLOW_OCTS_F_DROP)
+ idx = 7;
+ else if (level_f & ROC_NIX_BPF_RED_PKT_F_PASS)
+ idx = 8;
+ else if (level_f & ROC_NIX_BPF_RED_OCTS_F_PASS)
+ idx = 9;
+ else if (level_f & ROC_NIX_BPF_RED_PKT_F_DROP)
+ idx = 10;
+ else if (level_f & ROC_NIX_BPF_RED_OCTS_F_DROP)
+ idx = 11;
+ else
+ idx = ROC_NIX_BPF_STATS_MAX;
+ return idx;
+}
+
+int
+roc_nix_bpf_timeunit_get(struct roc_nix *roc_nix, uint32_t *time_unit)
+{
+ struct nix_bandprof_get_hwinfo_rsp *rsp;
+ struct mbox *mbox = get_mbox(roc_nix);
+ struct msg_req *req;
+ int rc = -ENOSPC;
+
+ if (roc_model_is_cn9k())
+ return NIX_ERR_HW_NOTSUP;
+
+ req = mbox_alloc_msg_nix_bandprof_get_hwinfo(mbox);
+ if (req == NULL)
+ goto exit;
+
+ rc = mbox_process_msg(mbox, (void *)&rsp);
+ if (rc)
+ goto exit;
+
+ *time_unit = rsp->policer_timeunit;
+
+exit:
+ return rc;
+}
+
int
roc_nix_bpf_count_get(struct roc_nix *roc_nix, uint8_t lvl_mask,
uint16_t count[ROC_NIX_BPF_LEVEL_MAX])
{
uint8_t mask = lvl_mask & NIX_BPF_LEVEL_F_MASK;
+ struct nix_bandprof_get_hwinfo_rsp *rsp;
+ struct mbox *mbox = get_mbox(roc_nix);
uint8_t leaf_idx, mid_idx, top_idx;
-
- PLT_SET_USED(roc_nix);
+ struct msg_req *req;
+ int rc = -ENOSPC;
if (roc_model_is_cn9k())
return NIX_ERR_HW_NOTSUP;
if (!mask)
return NIX_ERR_PARAM;
- /* Currently No MBOX interface is available to get number
- * of bandwidth profiles. So numbers per level are hard coded,
- * considering 3 RPM blocks and each block has 4 LMAC's.
- * So total 12 physical interfaces are in system. Each interface
- * supports following bandwidth profiles.
- */
+ req = mbox_alloc_msg_nix_bandprof_get_hwinfo(mbox);
+ if (req == NULL)
+ goto exit;
+
+ rc = mbox_process_msg(mbox, (void *)&rsp);
+ if (rc)
+ goto exit;
leaf_idx = roc_nix_bpf_level_to_idx(mask & ROC_NIX_BPF_LEVEL_F_LEAF);
mid_idx = roc_nix_bpf_level_to_idx(mask & ROC_NIX_BPF_LEVEL_F_MID);
top_idx = roc_nix_bpf_level_to_idx(mask & ROC_NIX_BPF_LEVEL_F_TOP);
if (leaf_idx != ROC_NIX_BPF_LEVEL_IDX_INVALID)
- count[leaf_idx] = NIX_MAX_BPF_COUNT_LEAF_LAYER;
+ count[leaf_idx] = rsp->prof_count[sw_to_hw_lvl_map[leaf_idx]];
if (mid_idx != ROC_NIX_BPF_LEVEL_IDX_INVALID)
- count[mid_idx] = NIX_MAX_BPF_COUNT_MID_LAYER;
+ count[mid_idx] = rsp->prof_count[sw_to_hw_lvl_map[mid_idx]];
if (top_idx != ROC_NIX_BPF_LEVEL_IDX_INVALID)
- count[top_idx] = NIX_MAX_BPF_COUNT_TOP_LAYER;
+ count[top_idx] = rsp->prof_count[sw_to_hw_lvl_map[top_idx]];
- return 0;
+exit:
+ return rc;
}
int
uint64_t exponent_p = 0, mantissa_p = 0, div_exp_p = 0;
struct mbox *mbox = get_mbox(roc_nix);
struct nix_cn10k_aq_enq_req *aq;
+ uint32_t policer_timeunit;
uint8_t level_idx;
+ int rc;
if (roc_model_is_cn9k())
return NIX_ERR_HW_NOTSUP;
if (!cfg)
return NIX_ERR_PARAM;
+ rc = roc_nix_bpf_timeunit_get(roc_nix, &policer_timeunit);
+ if (rc)
+ return rc;
+
level_idx = roc_nix_bpf_level_to_idx(lvl_flag);
if (level_idx == ROC_NIX_BPF_LEVEL_IDX_INVALID)
return NIX_ERR_PARAM;
switch (cfg->alg) {
case ROC_NIX_BPF_ALGO_2697:
meter_rate_to_nix(cfg->algo2697.cir, &exponent_p, &mantissa_p,
- &div_exp_p);
+ &div_exp_p, policer_timeunit);
aq->prof.cir_mantissa = mantissa_p;
aq->prof.cir_exponent = exponent_p;
case ROC_NIX_BPF_ALGO_2698:
meter_rate_to_nix(cfg->algo2698.cir, &exponent_p, &mantissa_p,
- &div_exp_p);
+ &div_exp_p, policer_timeunit);
aq->prof.cir_mantissa = mantissa_p;
aq->prof.cir_exponent = exponent_p;
meter_rate_to_nix(cfg->algo2698.pir, &exponent_p, &mantissa_p,
- &div_exp_p);
+ &div_exp_p, policer_timeunit);
aq->prof.peir_mantissa = mantissa_p;
aq->prof.peir_exponent = exponent_p;
case ROC_NIX_BPF_ALGO_4115:
meter_rate_to_nix(cfg->algo4115.cir, &exponent_p, &mantissa_p,
- &div_exp_p);
+ &div_exp_p, policer_timeunit);
aq->prof.cir_mantissa = mantissa_p;
aq->prof.cir_exponent = exponent_p;
meter_rate_to_nix(cfg->algo4115.eir, &exponent_p, &mantissa_p,
- &div_exp_p);
+ &div_exp_p, policer_timeunit);
aq->prof.peir_mantissa = mantissa_p;
aq->prof.peir_exponent = exponent_p;
exit:
return rc;
}
+
+int
+roc_nix_bpf_dump(struct roc_nix *roc_nix, uint16_t id,
+ enum roc_nix_bpf_level_flag lvl_flag)
+{
+ struct mbox *mbox = get_mbox(roc_nix);
+ struct nix_cn10k_aq_enq_rsp *rsp;
+ struct nix_cn10k_aq_enq_req *aq;
+ uint8_t level_idx;
+ int rc;
+
+ if (roc_model_is_cn9k())
+ return NIX_ERR_HW_NOTSUP;
+
+ level_idx = roc_nix_bpf_level_to_idx(lvl_flag);
+ if (level_idx == ROC_NIX_BPF_LEVEL_IDX_INVALID)
+ return NIX_ERR_PARAM;
+
+ aq = mbox_alloc_msg_nix_cn10k_aq_enq(mbox);
+ if (aq == NULL)
+ return -ENOSPC;
+ aq->qidx = (sw_to_hw_lvl_map[level_idx] << 14 | id);
+ aq->ctype = NIX_AQ_CTYPE_BAND_PROF;
+ aq->op = NIX_AQ_INSTOP_READ;
+ rc = mbox_process_msg(mbox, (void *)&rsp);
+ if (!rc) {
+ plt_dump("============= band prof id =%d ===============", id);
+ nix_lf_bpf_dump(&rsp->prof);
+ }
+
+ return rc;
+}
+
+int
+roc_nix_bpf_pre_color_tbl_setup(struct roc_nix *roc_nix, uint16_t id,
+ enum roc_nix_bpf_level_flag lvl_flag,
+ struct roc_nix_bpf_precolor *tbl)
+{
+ struct mbox *mbox = get_mbox(roc_nix);
+ struct nix_cn10k_aq_enq_req *aq;
+ uint8_t pc_mode, tn_ena;
+ uint8_t level_idx;
+ int rc;
+
+ if (!tbl || !tbl->count)
+ return NIX_ERR_PARAM;
+
+ if (roc_model_is_cn9k())
+ return NIX_ERR_HW_NOTSUP;
+
+ level_idx = roc_nix_bpf_level_to_idx(lvl_flag);
+ if (level_idx == ROC_NIX_BPF_LEVEL_IDX_INVALID)
+ return NIX_ERR_PARAM;
+
+ switch (tbl->mode) {
+ case ROC_NIX_BPF_PC_MODE_VLAN_INNER:
+ case ROC_NIX_BPF_PC_MODE_VLAN_OUTER:
+ if (tbl->count != NIX_BPF_PRECOLOR_VLAN_TABLE_SIZE) {
+ plt_err("Table size must be %d",
+ NIX_BPF_PRECOLOR_VLAN_TABLE_SIZE);
+ rc = NIX_ERR_PARAM;
+ goto exit;
+ }
+ tn_ena = nix_precolor_vlan_table_update(roc_nix, tbl);
+ pc_mode = NIX_RX_BAND_PROF_PC_MODE_VLAN;
+ break;
+ case ROC_NIX_BPF_PC_MODE_DSCP_INNER:
+ if (tbl->count != NIX_BPF_PRECOLOR_DSCP_TABLE_SIZE) {
+ plt_err("Table size must be %d",
+ NIX_BPF_PRECOLOR_DSCP_TABLE_SIZE);
+ rc = NIX_ERR_PARAM;
+ goto exit;
+ }
+ tn_ena = nix_precolor_inner_dscp_table_update(roc_nix, tbl);
+ pc_mode = NIX_RX_BAND_PROF_PC_MODE_DSCP;
+ break;
+ case ROC_NIX_BPF_PC_MODE_DSCP_OUTER:
+ if (tbl->count != NIX_BPF_PRECOLOR_DSCP_TABLE_SIZE) {
+ plt_err("Table size must be %d",
+ NIX_BPF_PRECOLOR_DSCP_TABLE_SIZE);
+ rc = NIX_ERR_PARAM;
+ goto exit;
+ }
+ tn_ena = nix_precolor_outer_dscp_table_update(roc_nix, tbl);
+ pc_mode = NIX_RX_BAND_PROF_PC_MODE_DSCP;
+ break;
+ case ROC_NIX_BPF_PC_MODE_GEN_INNER:
+ case ROC_NIX_BPF_PC_MODE_GEN_OUTER:
+ if (tbl->count != NIX_BPF_PRECOLOR_GEN_TABLE_SIZE) {
+ plt_err("Table size must be %d",
+ NIX_BPF_PRECOLOR_GEN_TABLE_SIZE);
+ rc = NIX_ERR_PARAM;
+ goto exit;
+ }
+
+ tn_ena = nix_precolor_gen_table_update(roc_nix, tbl);
+ pc_mode = NIX_RX_BAND_PROF_PC_MODE_GEN;
+ break;
+ default:
+ rc = NIX_ERR_PARAM;
+ goto exit;
+ }
+
+ /* Update corresponding bandwidth profile too */
+ aq = mbox_alloc_msg_nix_cn10k_aq_enq(mbox);
+ if (aq == NULL)
+ return -ENOSPC;
+ aq->qidx = (sw_to_hw_lvl_map[level_idx] << 14) | id;
+ aq->ctype = NIX_AQ_CTYPE_BAND_PROF;
+ aq->op = NIX_AQ_INSTOP_WRITE;
+ aq->prof.pc_mode = pc_mode;
+ aq->prof.tnl_ena = tn_ena;
+ aq->prof_mask.pc_mode = ~(aq->prof_mask.pc_mode);
+ aq->prof_mask.tnl_ena = ~(aq->prof_mask.tnl_ena);
+
+ return mbox_process(mbox);
+
+exit:
+ return rc;
+}
+
+int
+roc_nix_bpf_connect(struct roc_nix *roc_nix,
+ enum roc_nix_bpf_level_flag lvl_flag, uint16_t src_id,
+ uint16_t dst_id)
+{
+ struct mbox *mbox = get_mbox(roc_nix);
+ struct nix_cn10k_aq_enq_req *aq;
+ uint8_t level_idx;
+
+ if (roc_model_is_cn9k())
+ return NIX_ERR_HW_NOTSUP;
+
+ level_idx = roc_nix_bpf_level_to_idx(lvl_flag);
+ if (level_idx == ROC_NIX_BPF_LEVEL_IDX_INVALID)
+ return NIX_ERR_PARAM;
+
+ aq = mbox_alloc_msg_nix_cn10k_aq_enq(mbox);
+ if (aq == NULL)
+ return -ENOSPC;
+ aq->qidx = (sw_to_hw_lvl_map[level_idx] << 14) | src_id;
+ aq->ctype = NIX_AQ_CTYPE_BAND_PROF;
+ aq->op = NIX_AQ_INSTOP_WRITE;
+
+ if (dst_id == ROC_NIX_BPF_ID_INVALID) {
+ aq->prof.hl_en = false;
+ aq->prof_mask.hl_en = ~(aq->prof_mask.hl_en);
+ } else {
+ aq->prof.hl_en = true;
+ aq->prof.band_prof_id = dst_id;
+ aq->prof_mask.hl_en = ~(aq->prof_mask.hl_en);
+ aq->prof_mask.band_prof_id = ~(aq->prof_mask.band_prof_id);
+ }
+
+ return mbox_process(mbox);
+}
+
+int
+roc_nix_bpf_stats_read(struct roc_nix *roc_nix, uint16_t id, uint64_t mask,
+ enum roc_nix_bpf_level_flag lvl_flag,
+ uint64_t stats[ROC_NIX_BPF_STATS_MAX])
+{
+ uint8_t yellow_pkt_pass, yellow_octs_pass, yellow_pkt_drop;
+ uint8_t green_octs_drop, yellow_octs_drop, red_octs_drop;
+ uint8_t green_pkt_pass, green_octs_pass, green_pkt_drop;
+ uint8_t red_pkt_pass, red_octs_pass, red_pkt_drop;
+ struct mbox *mbox = get_mbox(roc_nix);
+ struct nix_cn10k_aq_enq_rsp *rsp;
+ struct nix_cn10k_aq_enq_req *aq;
+ uint8_t level_idx;
+ int rc;
+
+ if (roc_model_is_cn9k())
+ return NIX_ERR_HW_NOTSUP;
+
+ level_idx = roc_nix_bpf_level_to_idx(lvl_flag);
+ if (level_idx == ROC_NIX_BPF_LEVEL_IDX_INVALID)
+ return NIX_ERR_PARAM;
+
+ aq = mbox_alloc_msg_nix_cn10k_aq_enq(mbox);
+ if (aq == NULL)
+ return -ENOSPC;
+ aq->qidx = (sw_to_hw_lvl_map[level_idx] << 14 | id);
+ aq->ctype = NIX_AQ_CTYPE_BAND_PROF;
+ aq->op = NIX_AQ_INSTOP_READ;
+ rc = mbox_process_msg(mbox, (void *)&rsp);
+ if (rc)
+ return rc;
+
+ green_pkt_pass =
+ roc_nix_bpf_stats_to_idx(mask & ROC_NIX_BPF_GREEN_PKT_F_PASS);
+ green_octs_pass =
+ roc_nix_bpf_stats_to_idx(mask & ROC_NIX_BPF_GREEN_OCTS_F_PASS);
+ green_pkt_drop =
+ roc_nix_bpf_stats_to_idx(mask & ROC_NIX_BPF_GREEN_PKT_F_DROP);
+ green_octs_drop =
+ roc_nix_bpf_stats_to_idx(mask & ROC_NIX_BPF_GREEN_OCTS_F_DROP);
+ yellow_pkt_pass =
+ roc_nix_bpf_stats_to_idx(mask & ROC_NIX_BPF_YELLOW_PKT_F_PASS);
+ yellow_octs_pass =
+ roc_nix_bpf_stats_to_idx(mask & ROC_NIX_BPF_YELLOW_OCTS_F_PASS);
+ yellow_pkt_drop =
+ roc_nix_bpf_stats_to_idx(mask & ROC_NIX_BPF_YELLOW_PKT_F_DROP);
+ yellow_octs_drop =
+ roc_nix_bpf_stats_to_idx(mask & ROC_NIX_BPF_YELLOW_OCTS_F_DROP);
+ red_pkt_pass =
+ roc_nix_bpf_stats_to_idx(mask & ROC_NIX_BPF_RED_PKT_F_PASS);
+ red_octs_pass =
+ roc_nix_bpf_stats_to_idx(mask & ROC_NIX_BPF_RED_OCTS_F_PASS);
+ red_pkt_drop =
+ roc_nix_bpf_stats_to_idx(mask & ROC_NIX_BPF_RED_PKT_F_DROP);
+ red_octs_drop =
+ roc_nix_bpf_stats_to_idx(mask & ROC_NIX_BPF_RED_OCTS_F_DROP);
+
+ if (green_pkt_pass != ROC_NIX_BPF_STATS_MAX)
+ stats[green_pkt_pass] = rsp->prof.green_pkt_pass;
+
+ if (green_octs_pass != ROC_NIX_BPF_STATS_MAX)
+ stats[green_octs_pass] = rsp->prof.green_octs_pass;
+
+ if (green_pkt_drop != ROC_NIX_BPF_STATS_MAX)
+ stats[green_pkt_drop] = rsp->prof.green_pkt_drop;
+
+ if (green_octs_drop != ROC_NIX_BPF_STATS_MAX)
+ stats[green_octs_drop] = rsp->prof.green_octs_pass;
+
+ if (yellow_pkt_pass != ROC_NIX_BPF_STATS_MAX)
+ stats[yellow_pkt_pass] = rsp->prof.yellow_pkt_pass;
+
+ if (yellow_octs_pass != ROC_NIX_BPF_STATS_MAX)
+ stats[yellow_octs_pass] = rsp->prof.yellow_octs_pass;
+
+ if (yellow_pkt_drop != ROC_NIX_BPF_STATS_MAX)
+ stats[yellow_pkt_drop] = rsp->prof.yellow_pkt_drop;
+
+ if (yellow_octs_drop != ROC_NIX_BPF_STATS_MAX)
+ stats[yellow_octs_drop] = rsp->prof.yellow_octs_drop;
+
+ if (red_pkt_pass != ROC_NIX_BPF_STATS_MAX)
+ stats[red_pkt_pass] = rsp->prof.red_pkt_pass;
+
+ if (red_octs_pass != ROC_NIX_BPF_STATS_MAX)
+ stats[red_octs_pass] = rsp->prof.red_octs_pass;
+
+ if (red_pkt_drop != ROC_NIX_BPF_STATS_MAX)
+ stats[red_pkt_drop] = rsp->prof.red_pkt_drop;
+
+ if (red_octs_drop != ROC_NIX_BPF_STATS_MAX)
+ stats[red_octs_drop] = rsp->prof.red_octs_drop;
+
+ return 0;
+}
+
+int
+roc_nix_bpf_stats_reset(struct roc_nix *roc_nix, uint16_t id, uint64_t mask,
+ enum roc_nix_bpf_level_flag lvl_flag)
+{
+ struct mbox *mbox = get_mbox(roc_nix);
+ struct nix_cn10k_aq_enq_req *aq;
+ uint8_t level_idx;
+
+ if (roc_model_is_cn9k())
+ return NIX_ERR_HW_NOTSUP;
+
+ level_idx = roc_nix_bpf_level_to_idx(lvl_flag);
+ if (level_idx == ROC_NIX_BPF_LEVEL_IDX_INVALID)
+ return NIX_ERR_PARAM;
+
+ aq = mbox_alloc_msg_nix_cn10k_aq_enq(mbox);
+ if (aq == NULL)
+ return -ENOSPC;
+ aq->qidx = (sw_to_hw_lvl_map[level_idx] << 14 | id);
+ aq->ctype = NIX_AQ_CTYPE_BAND_PROF;
+ aq->op = NIX_AQ_INSTOP_WRITE;
+
+ if (mask & ROC_NIX_BPF_GREEN_PKT_F_PASS) {
+ aq->prof.green_pkt_pass = 0;
+ aq->prof_mask.green_pkt_pass = ~(aq->prof_mask.green_pkt_pass);
+ }
+ if (mask & ROC_NIX_BPF_GREEN_OCTS_F_PASS) {
+ aq->prof.green_octs_pass = 0;
+ aq->prof_mask.green_octs_pass =
+ ~(aq->prof_mask.green_octs_pass);
+ }
+ if (mask & ROC_NIX_BPF_GREEN_PKT_F_DROP) {
+ aq->prof.green_pkt_drop = 0;
+ aq->prof_mask.green_pkt_drop = ~(aq->prof_mask.green_pkt_drop);
+ }
+ if (mask & ROC_NIX_BPF_GREEN_OCTS_F_DROP) {
+ aq->prof.green_octs_drop = 0;
+ aq->prof_mask.green_octs_drop =
+ ~(aq->prof_mask.green_octs_drop);
+ }
+ if (mask & ROC_NIX_BPF_YELLOW_PKT_F_PASS) {
+ aq->prof.yellow_pkt_pass = 0;
+ aq->prof_mask.yellow_pkt_pass =
+ ~(aq->prof_mask.yellow_pkt_pass);
+ }
+ if (mask & ROC_NIX_BPF_YELLOW_OCTS_F_PASS) {
+ aq->prof.yellow_octs_pass = 0;
+ aq->prof_mask.yellow_octs_pass =
+ ~(aq->prof_mask.yellow_octs_pass);
+ }
+ if (mask & ROC_NIX_BPF_YELLOW_PKT_F_DROP) {
+ aq->prof.yellow_pkt_drop = 0;
+ aq->prof_mask.yellow_pkt_drop =
+ ~(aq->prof_mask.yellow_pkt_drop);
+ }
+ if (mask & ROC_NIX_BPF_YELLOW_OCTS_F_DROP) {
+ aq->prof.yellow_octs_drop = 0;
+ aq->prof_mask.yellow_octs_drop =
+ ~(aq->prof_mask.yellow_octs_drop);
+ }
+ if (mask & ROC_NIX_BPF_RED_PKT_F_PASS) {
+ aq->prof.red_pkt_pass = 0;
+ aq->prof_mask.red_pkt_pass = ~(aq->prof_mask.red_pkt_pass);
+ }
+ if (mask & ROC_NIX_BPF_RED_OCTS_F_PASS) {
+ aq->prof.red_octs_pass = 0;
+ aq->prof_mask.red_octs_pass = ~(aq->prof_mask.red_octs_pass);
+ }
+ if (mask & ROC_NIX_BPF_RED_PKT_F_DROP) {
+ aq->prof.red_pkt_drop = 0;
+ aq->prof_mask.red_pkt_drop = ~(aq->prof_mask.red_pkt_drop);
+ }
+ if (mask & ROC_NIX_BPF_RED_OCTS_F_DROP) {
+ aq->prof.red_octs_drop = 0;
+ aq->prof_mask.red_octs_drop = ~(aq->prof_mask.red_octs_drop);
+ }
+
+ return mbox_process(mbox);
+}
+
+int
+roc_nix_bpf_lf_stats_read(struct roc_nix *roc_nix, uint64_t mask,
+ uint64_t stats[ROC_NIX_BPF_STATS_MAX])
+{
+ uint8_t yellow_pkt_pass, yellow_octs_pass, yellow_pkt_drop;
+ uint8_t green_octs_drop, yellow_octs_drop, red_octs_drop;
+ uint8_t green_pkt_pass, green_octs_pass, green_pkt_drop;
+ uint8_t red_pkt_pass, red_octs_pass, red_pkt_drop;
+ struct nix *nix = roc_nix_to_nix_priv(roc_nix);
+
+ green_pkt_pass =
+ roc_nix_bpf_stats_to_idx(mask & ROC_NIX_BPF_GREEN_PKT_F_PASS);
+ green_octs_pass =
+ roc_nix_bpf_stats_to_idx(mask & ROC_NIX_BPF_GREEN_OCTS_F_PASS);
+ green_pkt_drop =
+ roc_nix_bpf_stats_to_idx(mask & ROC_NIX_BPF_GREEN_PKT_F_DROP);
+ green_octs_drop =
+ roc_nix_bpf_stats_to_idx(mask & ROC_NIX_BPF_GREEN_OCTS_F_DROP);
+ yellow_pkt_pass =
+ roc_nix_bpf_stats_to_idx(mask & ROC_NIX_BPF_YELLOW_PKT_F_PASS);
+ yellow_octs_pass =
+ roc_nix_bpf_stats_to_idx(mask & ROC_NIX_BPF_YELLOW_OCTS_F_PASS);
+ yellow_pkt_drop =
+ roc_nix_bpf_stats_to_idx(mask & ROC_NIX_BPF_YELLOW_PKT_F_DROP);
+ yellow_octs_drop =
+ roc_nix_bpf_stats_to_idx(mask & ROC_NIX_BPF_YELLOW_OCTS_F_DROP);
+ red_pkt_pass =
+ roc_nix_bpf_stats_to_idx(mask & ROC_NIX_BPF_RED_PKT_F_PASS);
+ red_octs_pass =
+ roc_nix_bpf_stats_to_idx(mask & ROC_NIX_BPF_RED_OCTS_F_PASS);
+ red_pkt_drop =
+ roc_nix_bpf_stats_to_idx(mask & ROC_NIX_BPF_RED_PKT_F_DROP);
+ red_octs_drop =
+ roc_nix_bpf_stats_to_idx(mask & ROC_NIX_BPF_RED_OCTS_F_DROP);
+
+ if (green_pkt_pass != ROC_NIX_BPF_STATS_MAX) {
+ stats[green_pkt_pass] =
+ NIX_RD_STATS(NIX_STAT_LF_RX_RX_GC_OCTS_PASSED);
+ }
+
+ if (green_octs_pass != ROC_NIX_BPF_STATS_MAX) {
+ stats[green_octs_pass] =
+ NIX_RD_STATS(NIX_STAT_LF_RX_RX_YC_PKTS_PASSED);
+ }
+
+ if (green_pkt_drop != ROC_NIX_BPF_STATS_MAX) {
+ stats[green_pkt_drop] =
+ NIX_RD_STATS(NIX_STAT_LF_RX_RX_GC_OCTS_DROP);
+ }
+
+ if (green_octs_drop != ROC_NIX_BPF_STATS_MAX) {
+ stats[green_octs_drop] =
+ NIX_RD_STATS(NIX_STAT_LF_RX_RX_YC_PKTS_DROP);
+ }
+
+ if (yellow_pkt_pass != ROC_NIX_BPF_STATS_MAX) {
+ stats[yellow_pkt_pass] =
+ NIX_RD_STATS(NIX_STAT_LF_RX_RX_GC_PKTS_PASSED);
+ }
+
+ if (yellow_octs_pass != ROC_NIX_BPF_STATS_MAX) {
+ stats[yellow_octs_pass] =
+ NIX_RD_STATS(NIX_STAT_LF_RX_RX_RC_OCTS_PASSED);
+ }
+
+ if (yellow_pkt_drop != ROC_NIX_BPF_STATS_MAX) {
+ stats[yellow_pkt_drop] =
+ NIX_RD_STATS(NIX_STAT_LF_RX_RX_GC_PKTS_DROP);
+ }
+
+ if (yellow_octs_drop != ROC_NIX_BPF_STATS_MAX) {
+ stats[yellow_octs_drop] =
+ NIX_RD_STATS(NIX_STAT_LF_RX_RX_RC_OCTS_DROP);
+ }
+
+ if (red_pkt_pass != ROC_NIX_BPF_STATS_MAX) {
+ stats[red_pkt_pass] =
+ NIX_RD_STATS(NIX_STAT_LF_RX_RX_YC_OCTS_PASSED);
+ }
+
+ if (red_octs_pass != ROC_NIX_BPF_STATS_MAX) {
+ stats[red_octs_pass] =
+ NIX_RD_STATS(NIX_STAT_LF_RX_RX_RC_PKTS_PASSED);
+ }
+
+ if (red_pkt_drop != ROC_NIX_BPF_STATS_MAX) {
+ stats[red_pkt_drop] =
+ NIX_RD_STATS(NIX_STAT_LF_RX_RX_YC_OCTS_DROP);
+ }
+
+ if (red_octs_drop != ROC_NIX_BPF_STATS_MAX) {
+ stats[red_octs_drop] =
+ NIX_RD_STATS(NIX_STAT_LF_RX_RX_RC_PKTS_DROP);
+ }
+
+ return 0;
+}
+
+int
+roc_nix_bpf_lf_stats_reset(struct roc_nix *roc_nix, uint64_t mask)
+{
+ struct nix *nix = roc_nix_to_nix_priv(roc_nix);
+
+ if (mask & ROC_NIX_BPF_GREEN_PKT_F_PASS)
+ NIX_RST_STATS(ROC_NIX_BPF_GREEN_PKT_F_PASS);
+ if (mask & ROC_NIX_BPF_GREEN_OCTS_F_PASS)
+ NIX_RST_STATS(ROC_NIX_BPF_GREEN_OCTS_F_PASS);
+ if (mask & ROC_NIX_BPF_GREEN_PKT_F_DROP)
+ NIX_RST_STATS(ROC_NIX_BPF_GREEN_PKT_F_DROP);
+ if (mask & ROC_NIX_BPF_GREEN_OCTS_F_DROP)
+ NIX_RST_STATS(ROC_NIX_BPF_GREEN_OCTS_F_DROP);
+ if (mask & ROC_NIX_BPF_YELLOW_PKT_F_PASS)
+ NIX_RST_STATS(ROC_NIX_BPF_YELLOW_PKT_F_PASS);
+ if (mask & ROC_NIX_BPF_YELLOW_OCTS_F_PASS)
+ NIX_RST_STATS(ROC_NIX_BPF_YELLOW_OCTS_F_PASS);
+ if (mask & ROC_NIX_BPF_YELLOW_PKT_F_DROP)
+ NIX_RST_STATS(ROC_NIX_BPF_YELLOW_PKT_F_DROP);
+ if (mask & ROC_NIX_BPF_YELLOW_OCTS_F_DROP)
+ NIX_RST_STATS(ROC_NIX_BPF_YELLOW_OCTS_F_DROP);
+ if (mask & ROC_NIX_BPF_RED_PKT_F_PASS)
+ NIX_RST_STATS(ROC_NIX_BPF_RED_PKT_F_PASS);
+ if (mask & ROC_NIX_BPF_RED_OCTS_F_PASS)
+ NIX_RST_STATS(ROC_NIX_BPF_RED_OCTS_F_PASS);
+ if (mask & ROC_NIX_BPF_RED_PKT_F_DROP)
+ NIX_RST_STATS(ROC_NIX_BPF_RED_PKT_F_DROP);
+ if (mask & ROC_NIX_BPF_RED_OCTS_F_DROP)
+ NIX_RST_STATS(ROC_NIX_BPF_RED_OCTS_F_DROP);
+
+ return 0;
+}