@@ -12,6 +12,7 @@
#include "rte_version.h"
#include "rte_ethdev.h"
+#include "rte_mtr.h"
#include "bnxt.h"
#include "ulp_template_db_enum.h"
@@ -231,6 +232,10 @@ struct bnxt_ulp_core_ops {
int32_t
(*ulp_vfr_session_fid_rem)(struct bnxt_ulp_context *ulp_ctx,
uint16_t rep_fid);
+
+ int32_t
+ (*ulp_mtr_cap_get)(struct bnxt *bp,
+ struct rte_mtr_capabilities *cap);
};
extern const struct bnxt_ulp_core_ops bnxt_ulp_tf_core_ops;
@@ -566,9 +571,6 @@ bnxt_ulp_cntxt_ecpri_udp_port_set(struct bnxt_ulp_context *ulp_ctx,
unsigned int
bnxt_ulp_cntxt_ecpri_udp_port_get(struct bnxt_ulp_context *ulp_ctx);
-int32_t
-bnxt_flow_meter_init(struct bnxt *bp);
-
uint32_t
bnxt_ulp_cntxt_convert_dev_id(uint32_t ulp_dev_id);
@@ -618,4 +620,8 @@ bnxt_ulp_vfr_session_fid_add(struct bnxt_ulp_context *ulp_ctx,
int32_t
bnxt_ulp_vfr_session_fid_rem(struct bnxt_ulp_context *ulp_ctx,
uint16_t vfr_fid);
+
+int32_t
+bnxt_flow_mtr_init(struct bnxt *bp __rte_unused);
+
#endif /* _BNXT_ULP_H_ */
@@ -40,122 +40,24 @@
/**
* Meter init status
*/
-int bnxt_meter_initialized;
+int bnxt_mtr_initialized;
-/**
- * Internal api to config global config.
- * returns 0 on success.
- */
-static int32_t
-bnxt_meter_global_cfg_update(struct bnxt *bp,
- enum tf_dir dir,
- enum tf_global_config_type type,
- uint32_t offset,
- uint32_t value,
- uint32_t set_flag)
-{
- uint32_t global_cfg = 0;
- struct tf_global_cfg_parms parms = { 0 };
- struct tf *tfp;
- int32_t rc = 0;
-
- parms.dir = dir,
- parms.type = type,
- parms.offset = offset,
- parms.config = (uint8_t *)&global_cfg,
- parms.config_sz_in_bytes = sizeof(global_cfg);
-
- tfp = bnxt_ulp_bp_tfp_get(bp, BNXT_ULP_SESSION_TYPE_DEFAULT);
- rc = tf_get_global_cfg(tfp, &parms);
- if (rc) {
- BNXT_DRV_DBG(ERR, "Failed to get global cfg 0x%x rc:%d\n",
- type, rc);
- return rc;
- }
-
- if (set_flag)
- global_cfg |= value;
- else
- global_cfg &= ~value;
-
- rc = tf_set_global_cfg(tfp, &parms);
- if (rc) {
- BNXT_DRV_DBG(ERR, "Failed to set global cfg 0x%x rc:%d\n",
- type, rc);
- return rc;
- }
- return rc;
-}
-
-/**
- * When a port is initialized by dpdk. This functions is called
- * to enable the meter and initializes the meter global configurations.
- */
-#define BNXT_THOR_FMTCR_NUM_MET_MET_1K (0x7UL << 20)
-#define BNXT_THOR_FMTCR_CNTRS_ENABLE (0x1UL << 25)
-#define BNXT_THOR_FMTCR_INTERVAL_1K (1024)
int32_t
-bnxt_flow_meter_init(struct bnxt *bp)
+bnxt_flow_mtr_init(struct bnxt *bp __rte_unused)
{
- int rc = 0;
-
- /*
- * Enable metering. Set the meter global configuration register.
- * Set number of meter to 1K. Disable the drop counter for now.
- */
- rc = bnxt_meter_global_cfg_update(bp, TF_DIR_RX, TF_METER_CFG,
- 0,
- BNXT_THOR_FMTCR_NUM_MET_MET_1K,
- 1);
- if (rc) {
- BNXT_DRV_DBG(ERR, "Failed to set rx meter configuration\n");
- goto jump_to_error;
- }
-
- rc = bnxt_meter_global_cfg_update(bp, TF_DIR_TX, TF_METER_CFG,
- 0,
- BNXT_THOR_FMTCR_NUM_MET_MET_1K,
- 1);
- if (rc) {
- BNXT_DRV_DBG(ERR, "Failed to set tx meter configuration\n");
- goto jump_to_error;
- }
-
/*
- * Set meter refresh rate to 1024 clock cycle. This value works for
- * most bit rates especially for high rates.
- */
- rc = bnxt_meter_global_cfg_update(bp, TF_DIR_RX, TF_METER_INTERVAL_CFG,
- 0,
- BNXT_THOR_FMTCR_INTERVAL_1K,
- 1);
- if (rc) {
- BNXT_DRV_DBG(ERR, "Failed to set rx meter interval\n");
- goto jump_to_error;
- }
-
- rc = bnxt_meter_global_cfg_update(bp, TF_DIR_TX, TF_METER_INTERVAL_CFG,
- 0,
- BNXT_THOR_FMTCR_INTERVAL_1K,
- 1);
- if (rc) {
- BNXT_DRV_DBG(ERR, "Failed to set tx meter interval\n");
- goto jump_to_error;
- }
-
- bnxt_meter_initialized = 1;
+ ** Enable metering. The meter refresh interval is set to 1K
+ ** in FW. The meters is set to drop packet and meter cache is
+ ** enabled by HW default.
+ **/
+ bnxt_mtr_initialized = 1;
BNXT_DRV_DBG(DEBUG, "Bnxt flow meter has been initialized\n");
- return rc;
-
-jump_to_error:
- return rc;
+ return 0;
}
/**
* Get meter capabilities.
*/
-#define MAX_FLOW_PER_METER 1024
-#define MAX_METER_RATE_100GBPS ((1ULL << 30) * 100 / 8)
static int
bnxt_flow_mtr_cap_get(struct rte_eth_dev *dev,
struct rte_mtr_capabilities *cap,
@@ -163,11 +65,9 @@ bnxt_flow_mtr_cap_get(struct rte_eth_dev *dev,
{
struct bnxt *bp = dev->data->dev_private;
uint32_t ulp_dev_id = BNXT_ULP_DEVICE_ID_LAST;
- struct tf_get_session_info_parms iparms;
- struct tf *tfp;
int32_t rc = 0;
- if (!bnxt_meter_initialized)
+ if (!bnxt_mtr_initialized)
return -rte_mtr_error_set(error, ENOTSUP,
RTE_MTR_ERROR_TYPE_UNSPECIFIED,
NULL,
@@ -180,35 +80,12 @@ bnxt_flow_mtr_cap_get(struct rte_eth_dev *dev,
NULL,
"Unable to get device id from ulp");
- /* Get number of meter reserved for this session */
- memset(&iparms, 0, sizeof(iparms));
- tfp = bnxt_ulp_bp_tfp_get(bp, BNXT_ULP_SESSION_TYPE_DEFAULT);
- rc = tf_get_session_info(tfp, &iparms);
- if (rc != 0)
+ rc = bp->ulp_ctx->ops->ulp_mtr_cap_get(bp, cap);
+ if (rc)
return -rte_mtr_error_set(error, ENOTSUP,
RTE_MTR_ERROR_TYPE_UNSPECIFIED,
NULL,
- "Failed to get session resource info");
-
- memset(cap, 0, sizeof(struct rte_mtr_capabilities));
-
- cap->n_max = iparms.session_info.tbl[TF_DIR_RX].info[TF_TBL_TYPE_METER_INST].stride;
- if (!cap->n_max)
- return -rte_mtr_error_set(error, ENOTSUP,
- RTE_MTR_ERROR_TYPE_UNSPECIFIED, NULL,
- "Meter is not supported");
-
- cap->srtcm_rfc2697_byte_mode_supported = 1;
- cap->n_shared_max = cap->n_max;
- /* No meter is identical */
- cap->identical = 1;
- cap->shared_identical = 1;
- cap->shared_n_flows_per_mtr_max = MAX_FLOW_PER_METER;
- cap->chaining_n_mtrs_per_flow_max = 1; /* Chaining is not supported. */
- cap->meter_srtcm_rfc2697_n_max = cap->n_max;
- cap->meter_rate_max = MAX_METER_RATE_100GBPS;
- /* No stats supported now */
- cap->stats_mask = 0;
+ "Unable to get meter capabilities");
return 0;
}
@@ -218,9 +95,8 @@ bnxt_flow_mtr_cap_get(struct rte_eth_dev *dev,
*/
#define BNXT_CPU_CLOCK 800
#define MEGA 1000000
-#define NUM_BIT_PER_BYTE 8
static inline void
-bnxt_ulp_flow_meter_xir_calc(int64_t xir, uint32_t *reg)
+bnxt_ulp_flow_mtr_xir_calc(int64_t xir, uint32_t *reg)
{
int64_t temp;
uint16_t m = 0;
@@ -248,7 +124,7 @@ bnxt_ulp_flow_meter_xir_calc(int64_t xir, uint32_t *reg)
* = round(b*2^(38-e) - 2^11)
*
*/
- m = xir * (1 << (38 - e)) / BNXT_CPU_CLOCK / MEGA - (1 << 11);
+ m = (xir * (1 << (38 - e)) / BNXT_CPU_CLOCK / (MEGA / 10) + 5) / 10 - (1 << 11);
*reg = ((m & 0x7FF) << 6) | (e & 0x3F);
swap = (uint8_t *)reg;
*reg = swap[0] << 16 | swap[1] << 8 | swap[2];
@@ -258,7 +134,7 @@ bnxt_ulp_flow_meter_xir_calc(int64_t xir, uint32_t *reg)
* Calculate mantissa and exponent for cbs / ebs reg.
*/
static inline void
-bnxt_ulp_flow_meter_xbs_calc(int64_t xbs, uint16_t *reg)
+bnxt_ulp_flow_mtr_xbs_calc(int64_t xbs, uint16_t *reg)
{
uint16_t m = 0;
uint16_t e = 0;
@@ -288,7 +164,7 @@ bnxt_ulp_flow_meter_xbs_calc(int64_t xbs, uint16_t *reg)
* Parse the meter profile.
*/
static inline int
-bnxt_ulp_meter_profile_parse(struct ulp_rte_act_prop *act_prop,
+bnxt_ulp_mtr_profile_parse(struct ulp_rte_act_prop *act_prop,
const struct rte_mtr_meter_profile *profile,
struct rte_mtr_error *error)
{
@@ -357,22 +233,22 @@ bnxt_ulp_meter_profile_parse(struct ulp_rte_act_prop *act_prop,
NULL,
"PIR must be equal to or greater than CIR");
- bnxt_ulp_flow_meter_xir_calc(cir, &cir_reg);
+ bnxt_ulp_flow_mtr_xir_calc(cir, &cir_reg);
memcpy(&act_prop->act_details[BNXT_ULP_ACT_PROP_IDX_METER_PROF_CIR],
&cir_reg,
BNXT_ULP_ACT_PROP_SZ_METER_PROF_CIR);
- bnxt_ulp_flow_meter_xir_calc(eir, &eir_reg);
+ bnxt_ulp_flow_mtr_xir_calc(eir, &eir_reg);
memcpy(&act_prop->act_details[BNXT_ULP_ACT_PROP_IDX_METER_PROF_EIR],
&eir_reg,
BNXT_ULP_ACT_PROP_SZ_METER_PROF_EIR);
- bnxt_ulp_flow_meter_xbs_calc(cbs, &cbs_reg);
+ bnxt_ulp_flow_mtr_xbs_calc(cbs, &cbs_reg);
memcpy(&act_prop->act_details[BNXT_ULP_ACT_PROP_IDX_METER_PROF_CBS],
&cbs_reg,
BNXT_ULP_ACT_PROP_SZ_METER_PROF_CBS);
- bnxt_ulp_flow_meter_xbs_calc(ebs, &ebs_reg);
+ bnxt_ulp_flow_mtr_xbs_calc(ebs, &ebs_reg);
memcpy(&act_prop->act_details[BNXT_ULP_ACT_PROP_IDX_METER_PROF_EBS],
&ebs_reg,
BNXT_ULP_ACT_PROP_SZ_METER_PROF_EBS);
@@ -392,8 +268,8 @@ bnxt_ulp_meter_profile_parse(struct ulp_rte_act_prop *act_prop,
* Add MTR profile.
*/
static int
-bnxt_flow_meter_profile_add(struct rte_eth_dev *dev,
- uint32_t meter_profile_id,
+bnxt_flow_mtr_profile_add(struct rte_eth_dev *dev,
+ uint32_t mtr_profile_id,
struct rte_mtr_meter_profile *profile,
struct rte_mtr_error *error)
{
@@ -406,7 +282,7 @@ bnxt_flow_meter_profile_add(struct rte_eth_dev *dev,
int ret;
uint32_t tmp_profile_id;
- if (!bnxt_meter_initialized)
+ if (!bnxt_mtr_initialized)
return -rte_mtr_error_set(error, ENOTSUP,
RTE_MTR_ERROR_TYPE_UNSPECIFIED,
NULL,
@@ -426,12 +302,12 @@ bnxt_flow_meter_profile_add(struct rte_eth_dev *dev,
/* not direction from rte_mtr. Set ingress by default */
params.dir_attr |= BNXT_ULP_FLOW_ATTR_INGRESS;
- tmp_profile_id = tfp_cpu_to_be_32(meter_profile_id);
+ tmp_profile_id = tfp_cpu_to_be_32(mtr_profile_id);
memcpy(&act_prop->act_details[BNXT_ULP_ACT_PROP_IDX_METER_PROF_ID],
&tmp_profile_id,
BNXT_ULP_ACT_PROP_SZ_METER_PROF_ID);
- ret = bnxt_ulp_meter_profile_parse(act_prop, profile, error);
+ ret = bnxt_ulp_mtr_profile_parse(act_prop, profile, error);
if (ret)
goto parse_error;
@@ -478,8 +354,8 @@ bnxt_flow_meter_profile_add(struct rte_eth_dev *dev,
* Delete meter profile.
*/
static int
-bnxt_flow_meter_profile_delete(struct rte_eth_dev *dev,
- uint32_t meter_profile_id,
+bnxt_flow_mtr_profile_delete(struct rte_eth_dev *dev,
+ uint32_t mtr_profile_id,
struct rte_mtr_error *error)
{
struct bnxt_ulp_context *ulp_ctx;
@@ -491,7 +367,7 @@ bnxt_flow_meter_profile_delete(struct rte_eth_dev *dev,
int ret;
uint32_t tmp_profile_id;
- if (!bnxt_meter_initialized)
+ if (!bnxt_mtr_initialized)
return -rte_mtr_error_set(error, ENOTSUP,
RTE_MTR_ERROR_TYPE_UNSPECIFIED,
NULL,
@@ -512,7 +388,7 @@ bnxt_flow_meter_profile_delete(struct rte_eth_dev *dev,
/* not direction from rte_mtr. Set ingress by default */
params.dir_attr |= BNXT_ULP_FLOW_ATTR_INGRESS;
- tmp_profile_id = tfp_cpu_to_be_32(meter_profile_id);
+ tmp_profile_id = tfp_cpu_to_be_32(mtr_profile_id);
memcpy(&act_prop->act_details[BNXT_ULP_ACT_PROP_IDX_METER_PROF_ID],
&tmp_profile_id,
BNXT_ULP_ACT_PROP_SZ_METER_PROF_ID);
@@ -547,7 +423,7 @@ bnxt_flow_meter_profile_delete(struct rte_eth_dev *dev,
goto parse_error;
BNXT_DRV_DBG(DEBUG, "Bnxt flow meter profile %d deleted\n",
- meter_profile_id);
+ mtr_profile_id);
return 0;
@@ -562,7 +438,7 @@ bnxt_flow_meter_profile_delete(struct rte_eth_dev *dev,
* Create meter.
*/
static int
-bnxt_flow_meter_create(struct rte_eth_dev *dev, uint32_t meter_id,
+bnxt_flow_mtr_create(struct rte_eth_dev *dev, uint32_t mtr_id,
struct rte_mtr_params *params, int shared __rte_unused,
struct rte_mtr_error *error)
{
@@ -572,11 +448,11 @@ bnxt_flow_meter_create(struct rte_eth_dev *dev, uint32_t meter_id,
struct bnxt_ulp_mapper_parms mparms = { 0 };
uint32_t act_tid;
uint16_t func_id;
- bool meter_en = params->meter_enable ? true : false;
+ bool mtr_en = params->meter_enable ? true : false;
int ret;
- uint32_t tmp_meter_id, tmp_profile_id;
+ uint32_t tmp_mtr_id, tmp_profile_id;
- if (!bnxt_meter_initialized)
+ if (!bnxt_mtr_initialized)
return -rte_mtr_error_set(error, ENOTSUP,
RTE_MTR_ERROR_TYPE_UNSPECIFIED,
NULL,
@@ -596,9 +472,9 @@ bnxt_flow_meter_create(struct rte_eth_dev *dev, uint32_t meter_id,
/* not direction from rte_mtr. Set ingress by default */
pparams.dir_attr |= BNXT_ULP_FLOW_ATTR_INGRESS;
- tmp_meter_id = tfp_cpu_to_be_32(meter_id);
+ tmp_mtr_id = tfp_cpu_to_be_32(mtr_id);
memcpy(&act_prop->act_details[BNXT_ULP_ACT_PROP_IDX_METER_INST_ID],
- &tmp_meter_id,
+ &tmp_mtr_id,
BNXT_ULP_ACT_PROP_SZ_METER_INST_ID);
tmp_profile_id = tfp_cpu_to_be_32(params->meter_profile_id);
@@ -607,7 +483,7 @@ bnxt_flow_meter_create(struct rte_eth_dev *dev, uint32_t meter_id,
BNXT_ULP_ACT_PROP_SZ_METER_PROF_ID);
memcpy(&act_prop->act_details[BNXT_ULP_ACT_PROP_IDX_METER_INST_MTR_VAL],
- &meter_en,
+ &mtr_en,
BNXT_ULP_ACT_PROP_SZ_METER_INST_MTR_VAL);
ret = ulp_matcher_action_match(&pparams, &act_tid);
@@ -639,7 +515,7 @@ bnxt_flow_meter_create(struct rte_eth_dev *dev, uint32_t meter_id,
if (ret)
goto parse_error;
- BNXT_DRV_DBG(DEBUG, "Bnxt flow meter %d is created\n", meter_id);
+ BNXT_DRV_DBG(DEBUG, "Bnxt flow meter %d is created\n", mtr_id);
return 0;
parse_error:
@@ -653,8 +529,8 @@ bnxt_flow_meter_create(struct rte_eth_dev *dev, uint32_t meter_id,
* Destroy meter.
*/
static int
-bnxt_flow_meter_destroy(struct rte_eth_dev *dev,
- uint32_t meter_id,
+bnxt_flow_mtr_destroy(struct rte_eth_dev *dev,
+ uint32_t mtr_id,
struct rte_mtr_error *error)
{
struct bnxt_ulp_context *ulp_ctx;
@@ -664,9 +540,9 @@ bnxt_flow_meter_destroy(struct rte_eth_dev *dev,
uint32_t act_tid;
uint16_t func_id;
int ret;
- uint32_t tmp_meter_id;
+ uint32_t tmp_mtr_id;
- if (!bnxt_meter_initialized)
+ if (!bnxt_mtr_initialized)
return -rte_mtr_error_set(error, ENOTSUP,
RTE_MTR_ERROR_TYPE_UNSPECIFIED,
NULL,
@@ -687,9 +563,9 @@ bnxt_flow_meter_destroy(struct rte_eth_dev *dev,
/* not direction from rte_mtr. Set ingress by default */
pparams.dir_attr |= BNXT_ULP_FLOW_ATTR_INGRESS;
- tmp_meter_id = tfp_cpu_to_be_32(meter_id);
+ tmp_mtr_id = tfp_cpu_to_be_32(mtr_id);
memcpy(&act_prop->act_details[BNXT_ULP_ACT_PROP_IDX_METER_INST_ID],
- &tmp_meter_id,
+ &tmp_mtr_id,
BNXT_ULP_ACT_PROP_SZ_METER_INST_ID);
ret = ulp_matcher_action_match(&pparams, &act_tid);
@@ -721,7 +597,7 @@ bnxt_flow_meter_destroy(struct rte_eth_dev *dev,
if (ret)
goto parse_error;
- BNXT_DRV_DBG(DEBUG, "Bnxt flow meter %d is deleted\n", meter_id);
+ BNXT_DRV_DBG(DEBUG, "Bnxt flow meter %d is deleted\n", mtr_id);
return 0;
parse_error:
@@ -735,8 +611,8 @@ bnxt_flow_meter_destroy(struct rte_eth_dev *dev,
* Set meter valid/invalid.
*/
static int
-bnxt_flow_meter_enable_set(struct rte_eth_dev *dev,
- uint32_t meter_id,
+bnxt_flow_mtr_enable_set(struct rte_eth_dev *dev,
+ uint32_t mtr_id,
uint8_t val,
struct rte_mtr_error *error)
{
@@ -747,9 +623,9 @@ bnxt_flow_meter_enable_set(struct rte_eth_dev *dev,
uint32_t act_tid;
uint16_t func_id;
int ret;
- uint32_t tmp_meter_id;
+ uint32_t tmp_mtr_id;
- if (!bnxt_meter_initialized)
+ if (!bnxt_mtr_initialized)
return -rte_mtr_error_set(error, ENOTSUP,
RTE_MTR_ERROR_TYPE_UNSPECIFIED,
NULL,
@@ -770,9 +646,9 @@ bnxt_flow_meter_enable_set(struct rte_eth_dev *dev,
/* not direction from rte_mtr. Set ingress by default */
pparams.dir_attr |= BNXT_ULP_FLOW_ATTR_INGRESS;
- tmp_meter_id = tfp_cpu_to_be_32(meter_id);
+ tmp_mtr_id = tfp_cpu_to_be_32(mtr_id);
memcpy(&act_prop->act_details[BNXT_ULP_ACT_PROP_IDX_METER_INST_ID],
- &tmp_meter_id,
+ &tmp_mtr_id,
BNXT_ULP_ACT_PROP_SZ_METER_INST_ID);
act_prop->act_details[BNXT_ULP_ACT_PROP_IDX_METER_INST_MTR_VAL_UPDATE] = 1;
act_prop->act_details[BNXT_ULP_ACT_PROP_IDX_METER_INST_MTR_VAL] = val;
@@ -807,7 +683,7 @@ bnxt_flow_meter_enable_set(struct rte_eth_dev *dev,
goto parse_error;
BNXT_DRV_DBG(DEBUG, "Bnxt flow meter %d is %s\n",
- meter_id, val ? "enabled" : "disabled");
+ mtr_id, val ? "enabled" : "disabled");
return 0;
parse_error:
@@ -821,31 +697,31 @@ bnxt_flow_meter_enable_set(struct rte_eth_dev *dev,
* Enable flow meter.
*/
static int
-bnxt_flow_meter_enable(struct rte_eth_dev *dev,
- uint32_t meter_id,
+bnxt_flow_mtr_enable(struct rte_eth_dev *dev,
+ uint32_t mtr_id,
struct rte_mtr_error *error)
{
- return bnxt_flow_meter_enable_set(dev, meter_id, 1, error);
+ return bnxt_flow_mtr_enable_set(dev, mtr_id, 1, error);
}
/**
* Disable flow meter.
*/
static int
-bnxt_flow_meter_disable(struct rte_eth_dev *dev,
- uint32_t meter_id,
+bnxt_flow_mtr_disable(struct rte_eth_dev *dev,
+ uint32_t mtr_id,
struct rte_mtr_error *error)
{
- return bnxt_flow_meter_enable_set(dev, meter_id, 0, error);
+ return bnxt_flow_mtr_enable_set(dev, mtr_id, 0, error);
}
/**
* Update meter profile.
*/
static int
-bnxt_flow_meter_profile_update(struct rte_eth_dev *dev __rte_unused,
- uint32_t meter_id __rte_unused,
- uint32_t meter_profile_id __rte_unused,
+bnxt_flow_mtr_profile_update(struct rte_eth_dev *dev __rte_unused,
+ uint32_t mtr_id __rte_unused,
+ uint32_t mtr_profile_id __rte_unused,
struct rte_mtr_error *error)
{
return -rte_mtr_error_set(error, ENOTSUP,
@@ -858,8 +734,8 @@ bnxt_flow_meter_profile_update(struct rte_eth_dev *dev __rte_unused,
* Udate meter stats mask.
*/
static int
-bnxt_flow_meter_stats_update(struct rte_eth_dev *dev __rte_unused,
- uint32_t meter_id __rte_unused,
+bnxt_flow_mtr_stats_update(struct rte_eth_dev *dev __rte_unused,
+ uint32_t mtr_id __rte_unused,
uint64_t stats_mask __rte_unused,
struct rte_mtr_error *error)
{
@@ -873,8 +749,8 @@ bnxt_flow_meter_stats_update(struct rte_eth_dev *dev __rte_unused,
* Read meter statistics.
*/
static int
-bnxt_flow_meter_stats_read(struct rte_eth_dev *dev __rte_unused,
- uint32_t meter_id __rte_unused,
+bnxt_flow_mtr_stats_read(struct rte_eth_dev *dev __rte_unused,
+ uint32_t mtr_id __rte_unused,
struct rte_mtr_stats *stats __rte_unused,
uint64_t *stats_mask __rte_unused,
int clear __rte_unused,
@@ -888,19 +764,19 @@ bnxt_flow_meter_stats_read(struct rte_eth_dev *dev __rte_unused,
static const struct rte_mtr_ops bnxt_flow_mtr_ops = {
.capabilities_get = bnxt_flow_mtr_cap_get,
- .meter_profile_add = bnxt_flow_meter_profile_add,
- .meter_profile_delete = bnxt_flow_meter_profile_delete,
+ .meter_profile_add = bnxt_flow_mtr_profile_add,
+ .meter_profile_delete = bnxt_flow_mtr_profile_delete,
.meter_policy_validate = NULL,
.meter_policy_add = NULL,
.meter_policy_delete = NULL,
- .create = bnxt_flow_meter_create,
- .destroy = bnxt_flow_meter_destroy,
- .meter_enable = bnxt_flow_meter_enable,
- .meter_disable = bnxt_flow_meter_disable,
- .meter_profile_update = bnxt_flow_meter_profile_update,
+ .create = bnxt_flow_mtr_create,
+ .destroy = bnxt_flow_mtr_destroy,
+ .meter_enable = bnxt_flow_mtr_enable,
+ .meter_disable = bnxt_flow_mtr_disable,
+ .meter_profile_update = bnxt_flow_mtr_profile_update,
.meter_dscp_table_update = NULL,
- .stats_update = bnxt_flow_meter_stats_update,
- .stats_read = bnxt_flow_meter_stats_read,
+ .stats_update = bnxt_flow_mtr_stats_update,
+ .stats_read = bnxt_flow_mtr_stats_read,
};
/**
@@ -910,5 +786,6 @@ int
bnxt_flow_meter_ops_get(struct rte_eth_dev *dev __rte_unused, void *arg)
{
*(const struct rte_mtr_ops **)arg = &bnxt_flow_mtr_ops;
+
return 0;
}
@@ -9,6 +9,8 @@
#include <rte_flow_driver.h>
#include <rte_tailq.h>
#include <rte_spinlock.h>
+#include <rte_mtr.h>
+#include <rte_version.h>
#include "bnxt.h"
#include "bnxt_ulp.h"
@@ -1316,6 +1318,65 @@ ulp_tf_global_cfg_update(struct bnxt *bp,
return rc;
}
+/**
+ * When a port is initialized by dpdk. This functions is called
+ * to enable the meter and initializes the meter global configurations.
+ */
+#define BNXT_THOR_FMTCR_NUM_MET_MET_1K (0x7UL << 20)
+#define BNXT_THOR_FMTCR_CNTRS_ENABLE (0x1UL << 25)
+#define BNXT_THOR_FMTCR_INTERVAL_1K (1024)
+static int32_t
+ulp_tf_flow_mtr_init(struct bnxt *bp)
+{
+ int rc = 0;
+
+ /*
+ * Enable metering. Set the meter global configuration register.
+ * Set number of meter to 1K. Disable the drop counter for now.
+ */
+ rc = ulp_tf_global_cfg_update(bp, TF_DIR_RX, TF_METER_CFG,
+ 0,
+ BNXT_THOR_FMTCR_NUM_MET_MET_1K,
+ 1);
+ if (rc) {
+ BNXT_DRV_DBG(ERR, "Failed to set rx meter configuration\n");
+ goto jump_to_error;
+ }
+
+ rc = ulp_tf_global_cfg_update(bp, TF_DIR_TX, TF_METER_CFG,
+ 0,
+ BNXT_THOR_FMTCR_NUM_MET_MET_1K,
+ 1);
+ if (rc) {
+ BNXT_DRV_DBG(ERR, "Failed to set tx meter configuration\n");
+ goto jump_to_error;
+ }
+
+ /*
+ * Set meter refresh rate to 1024 clock cycle. This value works for
+ * most bit rates especially for high rates.
+ */
+ rc = ulp_tf_global_cfg_update(bp, TF_DIR_RX, TF_METER_INTERVAL_CFG,
+ 0,
+ BNXT_THOR_FMTCR_INTERVAL_1K,
+ 1);
+ if (rc) {
+ BNXT_DRV_DBG(ERR, "Failed to set rx meter interval\n");
+ goto jump_to_error;
+ }
+
+ rc = bnxt_flow_mtr_init(bp);
+ if (rc) {
+ BNXT_DRV_DBG(ERR, "Failed to config meter\n");
+ goto jump_to_error;
+ }
+
+ return rc;
+
+jump_to_error:
+ return rc;
+}
+
/*
* When a port is deinit'ed by dpdk. This function is called
* and this function clears the ULP context and rest of the
@@ -1498,7 +1559,7 @@ ulp_tf_init(struct bnxt *bp,
}
if (ulp_dev_id == BNXT_ULP_DEVICE_ID_THOR) {
- rc = bnxt_flow_meter_init(bp);
+ rc = ulp_tf_flow_mtr_init(bp);
if (rc) {
BNXT_DRV_DBG(ERR, "Failed to config meter\n");
goto jump_to_error;
@@ -1513,11 +1574,59 @@ ulp_tf_init(struct bnxt *bp,
return rc;
}
+/**
+ * Get meter capabilities.
+ */
+#define MAX_FLOW_PER_METER 1024
+#define MAX_METER_RATE_100GBPS ((1ULL << 30) * 100 / 8)
+static int
+ulp_tf_mtr_cap_get(struct bnxt *bp,
+ struct rte_mtr_capabilities *cap)
+{
+ struct tf_get_session_info_parms iparms;
+ struct tf *tfp;
+ int32_t rc = 0;
+
+ /* Get number of meter reserved for this session */
+ memset(&iparms, 0, sizeof(iparms));
+ tfp = bnxt_ulp_bp_tfp_get(bp, BNXT_ULP_SESSION_TYPE_DEFAULT);
+ rc = tf_get_session_info(tfp, &iparms);
+ if (rc != 0) {
+ BNXT_DRV_DBG(ERR, "Failed to get session resource info\n");
+ return rc;
+ }
+
+ memset(cap, 0, sizeof(struct rte_mtr_capabilities));
+
+ cap->n_max = iparms.session_info.tbl[TF_DIR_RX].info[TF_TBL_TYPE_METER_INST].stride;
+ if (!cap->n_max) {
+ BNXT_DRV_DBG(ERR, "Meter is not supported\n");
+ return -EINVAL;
+ }
+
+#if (RTE_VERSION_NUM(21, 05, 0, 0) <= RTE_VERSION)
+ cap->srtcm_rfc2697_byte_mode_supported = 1;
+#endif
+ cap->n_shared_max = cap->n_max;
+ /* No meter is identical */
+ cap->identical = 1;
+ cap->shared_identical = 1;
+ cap->shared_n_flows_per_mtr_max = MAX_FLOW_PER_METER;
+ cap->chaining_n_mtrs_per_flow_max = 1; /* Chaining is not supported. */
+ cap->meter_srtcm_rfc2697_n_max = cap->n_max;
+ cap->meter_rate_max = MAX_METER_RATE_100GBPS;
+ /* No stats supported now */
+ cap->stats_mask = 0;
+
+ return 0;
+}
+
const struct bnxt_ulp_core_ops bnxt_ulp_tf_core_ops = {
.ulp_ctx_attach = ulp_tf_ctx_attach,
.ulp_ctx_detach = ulp_tf_ctx_detach,
.ulp_deinit = ulp_tf_deinit,
.ulp_init = ulp_tf_init,
.ulp_vfr_session_fid_add = NULL,
- .ulp_vfr_session_fid_rem = NULL
+ .ulp_vfr_session_fid_rem = NULL,
+ .ulp_mtr_cap_get = ulp_tf_mtr_cap_get
};
@@ -9,6 +9,8 @@
#include <rte_flow_driver.h>
#include <rte_tailq.h>
#include <rte_spinlock.h>
+#include <rte_mtr.h>
+#include <rte_version.h>
#include "bnxt.h"
#include "bnxt_ulp.h"
@@ -1017,6 +1019,20 @@ ulp_tfc_init(struct bnxt *bp,
goto jump_to_error;
}
+ rc = bnxt_ulp_cntxt_dev_id_get(bp->ulp_ctx, &ulp_dev_id);
+ if (rc) {
+ BNXT_DRV_DBG(ERR, "Unable to get device id from ulp.\n");
+ return rc;
+ }
+
+ if (ulp_dev_id == BNXT_ULP_DEVICE_ID_THOR2) {
+ rc = bnxt_flow_mtr_init(bp);
+ if (rc) {
+ BNXT_DRV_DBG(ERR, "Failed to config meter\n");
+ goto jump_to_error;
+ }
+ }
+
BNXT_DRV_DBG(DEBUG, "ulp ctx has been initialized\n");
return rc;
@@ -1025,11 +1041,40 @@ ulp_tfc_init(struct bnxt *bp,
return rc;
}
+/**
+ * Get meter capabilities.
+ */
+#define MAX_FLOW_PER_METER 1024
+#define MAX_NUM_METER 1024
+#define MAX_METER_RATE_200GBPS ((1ULL << 31) * 100 / 8)
+static int
+ulp_tfc_mtr_cap_get(struct bnxt *bp __rte_unused,
+ struct rte_mtr_capabilities *cap)
+{
+#if (RTE_VERSION_NUM(21, 05, 0, 0) <= RTE_VERSION)
+ cap->srtcm_rfc2697_byte_mode_supported = 1;
+#endif
+ cap->n_max = MAX_NUM_METER;
+ cap->n_shared_max = cap->n_max;
+ /* No meter is identical */
+ cap->identical = 1;
+ cap->shared_identical = 1;
+ cap->shared_n_flows_per_mtr_max = MAX_FLOW_PER_METER;
+ cap->chaining_n_mtrs_per_flow_max = 1; /* Chaining is not supported. */
+ cap->meter_srtcm_rfc2697_n_max = cap->n_max;
+ cap->meter_rate_max = MAX_METER_RATE_200GBPS;
+ /* No stats supported now */
+ cap->stats_mask = 0;
+
+ return 0;
+}
+
const struct bnxt_ulp_core_ops bnxt_ulp_tfc_core_ops = {
.ulp_ctx_attach = ulp_tfc_ctx_attach,
.ulp_ctx_detach = ulp_tfc_ctx_detach,
.ulp_deinit = ulp_tfc_deinit,
.ulp_init = ulp_tfc_init,
.ulp_vfr_session_fid_add = ulp_tfc_vfr_session_fid_add,
- .ulp_vfr_session_fid_rem = ulp_tfc_vfr_session_fid_rem
+ .ulp_vfr_session_fid_rem = ulp_tfc_vfr_session_fid_rem,
+ .ulp_mtr_cap_get = ulp_tfc_mtr_cap_get
};
@@ -3401,13 +3401,11 @@ ulp_rte_meter_act_handler(const struct rte_flow_action *action_item,
}
meter = action_item->conf;
- if (meter) {
- /* validate the mtr_id and update the reference counter */
- tmp_meter_id = tfp_cpu_to_be_32(meter->mtr_id);
- memcpy(&act_prop->act_details[BNXT_ULP_ACT_PROP_IDX_METER],
- &tmp_meter_id,
- BNXT_ULP_ACT_PROP_SZ_METER);
- }
+ /* validate the mtr_id and update the reference counter */
+ tmp_meter_id = tfp_cpu_to_be_32(meter->mtr_id);
+ memcpy(&act_prop->act_details[BNXT_ULP_ACT_PROP_IDX_METER],
+ &tmp_meter_id,
+ BNXT_ULP_ACT_PROP_SZ_METER);
/* set the meter action header bit */
ULP_BITMAP_SET(params->act_bitmap.bits, BNXT_ULP_ACT_BIT_METER);