+ sw_acc_tbl_entry->pkt_count += FLOW_CNTR_PKTS(stats[i],
+ dparms);
+ sw_acc_tbl_entry->byte_count += FLOW_CNTR_BYTES(stats[i],
+ dparms);
+ }
+
+ return rc;
+}
+
+static int32_t
+ulp_fc_tf_flow_stat_get(struct bnxt_ulp_context *ctxt,
+ struct ulp_flow_db_res_params *res,
+ struct rte_flow_query_count *qcount)
+{
+ struct tf *tfp;
+ struct bnxt_ulp_device_params *dparms;
+ struct tf_get_tbl_entry_parms parms = { 0 };
+ struct tf_set_tbl_entry_parms sparms = { 0 };
+ enum tf_tbl_type stype = TF_TBL_TYPE_ACT_STATS_64;
+ uint64_t stats = 0;
+ uint32_t dev_id = 0;
+ int32_t rc = 0;
+
+ tfp = bnxt_ulp_cntxt_tfp_get(ctxt, BNXT_ULP_SHARED_SESSION_NO);
+ if (!tfp) {
+ BNXT_TF_DBG(ERR, "Failed to get the truflow pointer\n");
+ return -EINVAL;
+ }
+
+ if (bnxt_ulp_cntxt_dev_id_get(ctxt, &dev_id)) {
+ BNXT_TF_DBG(DEBUG, "Failed to get device id\n");
+ bnxt_ulp_cntxt_entry_release();
+ return -EINVAL;
+ }
+
+ dparms = bnxt_ulp_device_params_get(dev_id);
+ if (!dparms) {
+ BNXT_TF_DBG(DEBUG, "Failed to device parms\n");
+ bnxt_ulp_cntxt_entry_release();
+ return -EINVAL;
+ }
+ parms.dir = res->direction;
+ parms.type = stype;
+ parms.idx = res->resource_hndl;
+ parms.data_sz_in_bytes = sizeof(uint64_t);
+ parms.data = (uint8_t *)&stats;
+ rc = tf_get_tbl_entry(tfp, &parms);
+ if (rc) {
+ PMD_DRV_LOG(ERR,
+ "Get failed for id:0x%x rc:%d\n",
+ parms.idx, rc);
+ return rc;
+ }
+ qcount->hits = FLOW_CNTR_PKTS(stats, dparms);
+ if (qcount->hits)
+ qcount->hits_set = 1;
+ qcount->bytes = FLOW_CNTR_BYTES(stats, dparms);
+ if (qcount->bytes)
+ qcount->bytes_set = 1;
+
+ if (qcount->reset) {
+ stats = 0;
+ sparms.dir = res->direction;
+ sparms.type = stype;
+ sparms.idx = res->resource_hndl;
+ sparms.data = (uint8_t *)&stats;
+ sparms.data_sz_in_bytes = sizeof(uint64_t);
+ rc = tf_set_tbl_entry(tfp, &sparms);
+ if (rc) {
+ PMD_DRV_LOG(ERR, "Set failed for id:0x%x rc:%d\n",
+ sparms.idx, rc);
+ return rc;
+ }
+ }
+ return rc;
+}
+
+static int ulp_get_single_flow_stat(struct bnxt_ulp_context *ctxt,
+ struct tf *tfp,
+ struct bnxt_ulp_fc_info *fc_info,
+ enum tf_dir dir,
+ uint32_t hw_cntr_id,
+ struct bnxt_ulp_device_params *dparms)
+{
+ int rc = 0;
+ struct tf_get_tbl_entry_parms parms = { 0 };
+ enum tf_tbl_type stype = TF_TBL_TYPE_ACT_STATS_64; /* TBD:Template? */
+ struct sw_acc_counter *sw_acc_tbl_entry = NULL, *t_sw;
+ uint64_t stats = 0;
+ uint32_t sw_cntr_indx = 0;
+
+ parms.dir = dir;
+ parms.type = stype;
+ parms.idx = hw_cntr_id;
+ /*
+ * TODO:
+ * Size of an entry needs to obtained from template
+ */
+ parms.data_sz_in_bytes = sizeof(uint64_t);
+ parms.data = (uint8_t *)&stats;
+ rc = tf_get_tbl_entry(tfp, &parms);
+ if (rc) {
+ PMD_DRV_LOG(ERR,
+ "Get failed for id:0x%x rc:%d\n",
+ parms.idx, rc);
+ return rc;
+ }
+
+ /* TBD - Get PKT/BYTE COUNT SHIFT/MASK from Template */
+ sw_cntr_indx = hw_cntr_id - fc_info->shadow_hw_tbl[dir].start_idx;
+ sw_acc_tbl_entry = &fc_info->sw_acc_tbl[dir][sw_cntr_indx];
+ /* Some dpdk applications may accumulate the flow counters while some
+ * may not. In cases where the application is accumulating the counters
+ * the PMD need not do the accumulation itself and viceversa to report
+ * the correct flow counters.
+ */
+ if (ctxt->cfg_data->accum_stats) {
+ sw_acc_tbl_entry->pkt_count += FLOW_CNTR_PKTS(stats, dparms);
+ sw_acc_tbl_entry->byte_count += FLOW_CNTR_BYTES(stats, dparms);
+ } else {
+ sw_acc_tbl_entry->pkt_count = FLOW_CNTR_PKTS(stats, dparms);
+ sw_acc_tbl_entry->byte_count = FLOW_CNTR_BYTES(stats, dparms);
+ }
+
+ /* Update the parent counters if it is child flow */
+ if (sw_acc_tbl_entry->parent_flow_id) {
+ /* Update the parent counters */
+ t_sw = sw_acc_tbl_entry;
+ if (ulp_flow_db_parent_flow_count_update(ctxt,
+ t_sw->parent_flow_id,
+ t_sw->pkt_count,
+ t_sw->byte_count)) {
+ PMD_DRV_LOG(ERR, "Error updating parent counters\n");
+ }