* Create meter rules. * * @param[in] dev * Pointer to Ethernet device. * @param[in] meter_id * Meter id. * @param[in] params * Pointer to rte meter parameters. * @param[in] shared * Meter shared with other flow or not. * @param[out] error * Pointer to rte meter error structure. * * @return * 0 on success, a negative errno value otherwise and rte_errno is set. */
| 1367 | * 0 on success, a negative errno value otherwise and rte_errno is set. |
| 1368 | */ |
| 1369 | static int |
| 1370 | mlx5_flow_meter_create(struct rte_eth_dev *dev, uint32_t meter_id, |
| 1371 | struct rte_mtr_params *params, int shared, |
| 1372 | struct rte_mtr_error *error) |
| 1373 | { |
| 1374 | struct mlx5_priv *priv = dev->data->dev_private; |
| 1375 | struct mlx5_legacy_flow_meters *fms = &priv->flow_meters; |
| 1376 | struct mlx5_flow_meter_profile *fmp; |
| 1377 | struct mlx5_flow_meter_info *fm; |
| 1378 | /* GCC fails to infer legacy_fm is set when !priv->sh->meter_aso_en. */ |
| 1379 | struct mlx5_legacy_flow_meter *legacy_fm = NULL; |
| 1380 | struct mlx5_flow_meter_policy *mtr_policy = NULL; |
| 1381 | struct mlx5_indexed_pool_config flow_ipool_cfg = { |
| 1382 | .size = 0, |
| 1383 | .trunk_size = 64, |
| 1384 | .need_lock = 1, |
| 1385 | .type = "mlx5_flow_mtr_flow_id_pool", |
| 1386 | }; |
| 1387 | struct mlx5_aso_mtr *aso_mtr; |
| 1388 | uint32_t mtr_idx, policy_idx; |
| 1389 | union mlx5_l3t_data data; |
| 1390 | int ret; |
| 1391 | uint8_t domain_bitmap; |
| 1392 | uint8_t mtr_id_bits; |
| 1393 | uint8_t mtr_reg_bits = priv->mtr_reg_share ? |
| 1394 | MLX5_MTR_IDLE_BITS_IN_COLOR_REG : MLX5_REG_BITS; |
| 1395 | |
| 1396 | if (!priv->mtr_en) |
| 1397 | return -rte_mtr_error_set(error, ENOTSUP, |
| 1398 | RTE_MTR_ERROR_TYPE_UNSPECIFIED, NULL, |
| 1399 | "Meter is not supported"); |
| 1400 | /* Validate the parameters. */ |
| 1401 | ret = mlx5_flow_meter_validate(priv, meter_id, params, error); |
| 1402 | if (ret) |
| 1403 | return ret; |
| 1404 | /* Meter profile must exist. */ |
| 1405 | fmp = mlx5_flow_meter_profile_find(priv, params->meter_profile_id); |
| 1406 | if (fmp == NULL) |
| 1407 | return -rte_mtr_error_set(error, ENOENT, |
| 1408 | RTE_MTR_ERROR_TYPE_METER_PROFILE_ID, |
| 1409 | NULL, "Meter profile id not valid."); |
| 1410 | /* Meter policy must exist. */ |
| 1411 | if (params->meter_policy_id == priv->sh->mtrmng->def_policy_id) { |
| 1412 | __atomic_fetch_add |
| 1413 | (&priv->sh->mtrmng->def_policy_ref_cnt, |
| 1414 | 1, __ATOMIC_RELAXED); |
| 1415 | domain_bitmap = MLX5_MTR_ALL_DOMAIN_BIT; |
| 1416 | if (!priv->sh->config.dv_esw_en) |
| 1417 | domain_bitmap &= ~MLX5_MTR_DOMAIN_TRANSFER_BIT; |
| 1418 | } else { |
| 1419 | if (!priv->sh->meter_aso_en) |
| 1420 | return -rte_mtr_error_set(error, ENOTSUP, |
| 1421 | RTE_MTR_ERROR_TYPE_UNSPECIFIED, NULL, |
| 1422 | "Part of the policies cannot be " |
| 1423 | "supported without ASO "); |
| 1424 | mtr_policy = mlx5_flow_meter_policy_find(dev, |
| 1425 | params->meter_policy_id, &policy_idx); |
| 1426 | if (!mtr_policy) |
nothing calls this directly
no test coverage detected