AI Trajectory


Trajectory: (Expand/Collapse All)
Seq Timestamp Type Name Duration
0/0 2026/07/07 21:40 flow patch-triage
0m Args:
null

Results:
{
  "EnableConfigs": null,
  "FocusSymbols": [],
  "Reasoning": "The patch only modifies the Mellanox mlx5 hardware driver (specifically the PSP offload feature). Since this driver requires physical Mellanox ConnectX hardware and is not emulated in virtualized environments like QEMU or GCE, the code paths are unreachable during fuzzing.",
  "WorthFuzzing": false
}

1/1 2026/07/07 21:40 action read-patch-diff
0m Args:
null

Results:
{
  "PatchDiff": "commit e792dd051b035d14bfdb55b8db64623fc84b8bb8\nAuthor: syz-cluster \u003ctriage@syzkaller.com\u003e\nDate:   Tue Jul 7 21:40:52 2026 +0000\n\n    syz-cluster: applied patch under review\n\ndiff --git a/drivers/net/ethernet/mellanox/mlx5/core/en.h b/drivers/net/ethernet/mellanox/mlx5/core/en.h\nindex 2270e2e550dd9e..3cc7283b6215e1 100644\n--- a/drivers/net/ethernet/mellanox/mlx5/core/en.h\n+++ b/drivers/net/ethernet/mellanox/mlx5/core/en.h\n@@ -1016,7 +1016,7 @@ struct mlx5e_profile {\n \tvoid\t(*cleanup_rx)(struct mlx5e_priv *priv);\n \tint\t(*init_tx)(struct mlx5e_priv *priv);\n \tvoid\t(*cleanup_tx)(struct mlx5e_priv *priv);\n-\tvoid\t(*enable)(struct mlx5e_priv *priv);\n+\tint\t(*enable)(struct mlx5e_priv *priv);\n \tvoid\t(*disable)(struct mlx5e_priv *priv);\n \tint\t(*update_rx)(struct mlx5e_priv *priv);\n \tvoid\t(*update_stats)(struct mlx5e_priv *priv);\ndiff --git a/drivers/net/ethernet/mellanox/mlx5/core/en/fs.h b/drivers/net/ethernet/mellanox/mlx5/core/en/fs.h\nindex 091b80a67189dd..4973fb473ff020 100644\n--- a/drivers/net/ethernet/mellanox/mlx5/core/en/fs.h\n+++ b/drivers/net/ethernet/mellanox/mlx5/core/en/fs.h\n@@ -88,13 +88,18 @@ enum {\n #ifdef CONFIG_MLX5_EN_ARFS\n \tMLX5E_ARFS_FT_LEVEL = MLX5E_INNER_TTC_FT_LEVEL + 1,\n #endif\n-#if defined(CONFIG_MLX5_EN_IPSEC) || defined(CONFIG_MLX5_EN_PSP)\n+#if defined(CONFIG_MLX5_EN_IPSEC)\n \tMLX5E_ACCEL_FS_ESP_FT_LEVEL = MLX5E_INNER_TTC_FT_LEVEL + 1,\n \tMLX5E_ACCEL_FS_ESP_FT_ERR_LEVEL,\n \tMLX5E_ACCEL_FS_POL_FT_LEVEL,\n \tMLX5E_ACCEL_FS_POL_MISS_FT_LEVEL,\n \tMLX5E_ACCEL_FS_ESP_FT_ROCE_LEVEL,\n #endif\n+#if defined(CONFIG_MLX5_EN_PSP)\n+\tMLX5E_ACCEL_FS_PSP_FT_LEVEL = MLX5E_INNER_TTC_FT_LEVEL + 1,\n+\tMLX5E_ACCEL_FS_PSP_ERR_FT_LEVEL,\n+\tMLX5E_ACCEL_FS_PSP_RX_FT_LEVEL,\n+#endif\n };\n \n struct mlx5e_flow_steering;\ndiff --git a/drivers/net/ethernet/mellanox/mlx5/core/en_accel/en_accel.h b/drivers/net/ethernet/mellanox/mlx5/core/en_accel/en_accel.h\nindex b526b3898c22e0..3f212e46fc2f9e 100644\n--- a/drivers/net/ethernet/mellanox/mlx5/core/en_accel/en_accel.h\n+++ b/drivers/net/ethernet/mellanox/mlx5/core/en_accel/en_accel.h\n@@ -220,18 +220,7 @@ static inline void mlx5e_accel_tx_finish(struct mlx5e_txqsq *sq,\n \n static inline int mlx5e_accel_init_rx(struct mlx5e_priv *priv)\n {\n-\tint err;\n-\n-\terr = mlx5_accel_psp_fs_init_rx_tables(priv);\n-\tif (err)\n-\t\tgoto out;\n-\n-\terr = mlx5e_ktls_init_rx(priv);\n-\tif (err)\n-\t\tmlx5_accel_psp_fs_cleanup_rx_tables(priv);\n-\n-out:\n-\treturn err;\n+\treturn mlx5e_ktls_init_rx(priv);\n }\n \n static inline void mlx5e_accel_cleanup_rx(struct mlx5e_priv *priv)\n@@ -242,12 +231,6 @@ static inline void mlx5e_accel_cleanup_rx(struct mlx5e_priv *priv)\n \n static inline int mlx5e_accel_init_tx(struct mlx5e_priv *priv)\n {\n-\tint err;\n-\n-\terr = mlx5_accel_psp_fs_init_tx_tables(priv);\n-\tif (err)\n-\t\treturn err;\n-\n \treturn mlx5e_ktls_init_tx(priv);\n }\n \ndiff --git a/drivers/net/ethernet/mellanox/mlx5/core/en_accel/psp.c b/drivers/net/ethernet/mellanox/mlx5/core/en_accel/psp.c\nindex d9adb993e64d95..73b232379263aa 100644\n--- a/drivers/net/ethernet/mellanox/mlx5/core/en_accel/psp.c\n+++ b/drivers/net/ethernet/mellanox/mlx5/core/en_accel/psp.c\n@@ -21,51 +21,52 @@ enum accel_psp_syndrome {\n \tPSP_BAD_TRAILER,\n };\n \n-struct mlx5e_psp_tx {\n+struct mlx5e_psp_tx_table {\n \tstruct mlx5_flow_namespace *ns;\n \tstruct mlx5_flow_table *ft;\n \tstruct mlx5_flow_group *fg;\n \tstruct mlx5_flow_handle *rule;\n-\tstruct mutex mutex; /* Protect PSP TX steering */\n-\tu32 refcnt;\n-\tstruct mlx5_fc *tx_counter;\n };\n \n-struct mlx5e_psp_rx_err {\n+struct mlx5e_psp_rx_check_table {\n \tstruct mlx5_flow_table *ft;\n+\tstruct mlx5_flow_group *drop_group;\n \tstruct mlx5_flow_handle *rule;\n \tstruct mlx5_flow_handle *auth_fail_rule;\n \tstruct mlx5_flow_handle *err_rule;\n \tstruct mlx5_flow_handle *bad_rule;\n-\tstruct mlx5_modify_hdr *copy_modify_hdr;\n };\n \n-struct mlx5e_accel_fs_psp_prot {\n+struct mlx5e_psp_rx_decrypt_table {\n \tstruct mlx5_flow_table *ft;\n \tstruct mlx5_flow_group *miss_group;\n \tstruct mlx5_flow_handle *miss_rule;\n \tstruct mlx5_modify_hdr *rx_modify_hdr;\n-\tstruct mlx5_flow_destination default_dest;\n-\tstruct mlx5e_psp_rx_err rx_err;\n-\tu32 refcnt;\n-\tstruct mutex prot_mutex; /* protect ESP4/ESP6 protocol */\n-\tstruct mlx5_flow_handle *def_rule;\n+\tstruct mlx5_flow_handle *rule;\n };\n \n-struct mlx5e_accel_fs_psp {\n-\tstruct mlx5e_accel_fs_psp_prot fs_prot[ACCEL_FS_PSP_NUM_TYPES];\n-\tstruct mlx5_fc *rx_counter;\n-\tstruct mlx5_fc *rx_auth_fail_counter;\n-\tstruct mlx5_fc *rx_err_counter;\n-\tstruct mlx5_fc *rx_bad_counter;\n+struct mlx5e_psp_rx_table {\n+\tstruct mlx5_flow_table *ft;\n+\tstruct mlx5_flow_group *miss_group;\n+\tstruct mlx5_flow_handle *miss_rule;\n+\tstruct mlx5_flow_handle *udp_rules[ACCEL_FS_PSP_NUM_TYPES];\n };\n \n struct mlx5e_psp_fs {\n \tstruct mlx5_core_dev *mdev;\n-\tstruct mlx5e_psp_tx *tx_fs;\n-\t/* Rx manage */\n+\tstruct mlx5_fc *tx_counter;\n+\tstruct mlx5e_psp_tx_table tx;\n+\n+\t/* Rx */\n \tstruct mlx5e_flow_steering *fs;\n-\tstruct mlx5e_accel_fs_psp *rx_fs;\n+\tstruct mlx5_fc *rx_counter;\n+\tstruct mlx5_fc *rx_auth_fail_counter;\n+\tstruct mlx5_fc *rx_err_counter;\n+\tstruct mlx5_fc *rx_bad_counter;\n+\n+\tstruct mlx5e_psp_rx_decrypt_table decrypt[ACCEL_FS_PSP_NUM_TYPES];\n+\tstruct mlx5e_psp_rx_check_table check;\n+\tstruct mlx5e_psp_rx_table rx;\n };\n \n /* PSP RX flow steering */\n@@ -77,44 +78,200 @@ static enum mlx5_traffic_types fs_psp2tt(enum accel_fs_psp_type i)\n \treturn MLX5_TT_IPV6_UDP;\n }\n \n-static void accel_psp_fs_rx_err_del_rules(struct mlx5e_psp_fs *fs,\n-\t\t\t\t\t  struct mlx5e_psp_rx_err *rx_err)\n+static int accel_psp_fs_create_ft(struct mlx5e_psp_fs *fs,\n+\t\t\t\t  struct mlx5_flow_table_attr *ft_attr,\n+\t\t\t\t  struct mlx5_flow_table **ft)\n+{\n+\tstruct mlx5_flow_namespace *ns = mlx5e_fs_get_ns(fs-\u003efs, false);\n+\tint err = 0;\n+\n+\t*ft = mlx5_create_auto_grouped_flow_table(ns, ft_attr);\n+\tif (IS_ERR(*ft)) {\n+\t\terr = PTR_ERR(*ft);\n+\t\t*ft = NULL;\n+\t}\n+\n+\treturn err;\n+}\n+\n+static void accel_psp_fs_destroy_ft(struct mlx5_flow_table **table)\n {\n-\tif (rx_err-\u003ebad_rule) {\n-\t\tmlx5_del_flow_rules(rx_err-\u003ebad_rule);\n-\t\trx_err-\u003ebad_rule = NULL;\n+\tif (*table) {\n+\t\tmlx5_destroy_flow_table(*table);\n+\t\t*table = NULL;\n \t}\n+}\n \n-\tif (rx_err-\u003eerr_rule) {\n-\t\tmlx5_del_flow_rules(rx_err-\u003eerr_rule);\n-\t\trx_err-\u003eerr_rule = NULL;\n+static void accel_psp_fs_del_flow_rule(struct mlx5_flow_handle **rule)\n+{\n+\tif (*rule) {\n+\t\tmlx5_del_flow_rules(*rule);\n+\t\t*rule = NULL;\n \t}\n+}\n+\n+static int accel_psp_fs_create_miss_group(struct mlx5_flow_table *ft,\n+\t\t\t\t\t  struct mlx5_flow_group **group)\n+{\n+\tint inlen = MLX5_ST_SZ_BYTES(create_flow_group_in);\n+\tu32 *in = kvzalloc(inlen, GFP_KERNEL);\n+\tint err = 0;\n \n-\tif (rx_err-\u003eauth_fail_rule) {\n-\t\tmlx5_del_flow_rules(rx_err-\u003eauth_fail_rule);\n-\t\trx_err-\u003eauth_fail_rule = NULL;\n+\tif (!in)\n+\t\treturn -ENOMEM;\n+\n+\tMLX5_SET(create_flow_group_in, in, start_flow_index, ft-\u003emax_fte - 1);\n+\tMLX5_SET(create_flow_group_in, in, end_flow_index, ft-\u003emax_fte - 1);\n+\t*group = mlx5_create_flow_group(ft, in);\n+\tif (IS_ERR(*group)) {\n+\t\terr = PTR_ERR(*group);\n+\t\t*group = NULL;\n \t}\n+\tkvfree(in);\n \n-\tif (rx_err-\u003erule) {\n-\t\tmlx5_del_flow_rules(rx_err-\u003erule);\n-\t\trx_err-\u003erule = NULL;\n+\treturn err;\n+}\n+\n+static void accel_psp_fs_destroy_flow_group(struct mlx5_flow_group **group)\n+{\n+\tif (*group) {\n+\t\tmlx5_destroy_flow_group(*group);\n+\t\t*group = NULL;\n \t}\n+}\n+\n+static int accel_psp_fs_create_counter(struct mlx5_core_dev *dev,\n+\t\t\t\t       struct mlx5_fc **counter)\n+{\n+\t*counter = mlx5_fc_create(dev, false);\n+\tif (IS_ERR(*counter)) {\n+\t\tint err = PTR_ERR(*counter);\n+\n+\t\t*counter = NULL;\n+\t\treturn err;\n+\t}\n+\n+\treturn 0;\n+}\n \n-\tif (rx_err-\u003ecopy_modify_hdr) {\n-\t\tmlx5_modify_header_dealloc(fs-\u003emdev, rx_err-\u003ecopy_modify_hdr);\n-\t\trx_err-\u003ecopy_modify_hdr = NULL;\n+static void accel_psp_fs_destroy_counter(struct mlx5_core_dev *dev,\n+\t\t\t\t\t struct mlx5_fc **counter)\n+{\n+\tif (*counter) {\n+\t\tmlx5_fc_destroy(dev, *counter);\n+\t\t*counter = NULL;\n \t}\n }\n \n-static void accel_psp_fs_rx_err_destroy_ft(struct mlx5e_psp_fs *fs,\n-\t\t\t\t\t   struct mlx5e_psp_rx_err *rx_err)\n+static void accel_psp_fs_rx_ft_destroy(struct mlx5e_psp_rx_table *rx)\n+{\n+\tint i;\n+\n+\tfor (i = 0; i \u003c ACCEL_FS_PSP_NUM_TYPES; i++)\n+\t\taccel_psp_fs_del_flow_rule(\u0026rx-\u003eudp_rules[i]);\n+\taccel_psp_fs_del_flow_rule(\u0026rx-\u003emiss_rule);\n+\taccel_psp_fs_destroy_flow_group(\u0026rx-\u003emiss_group);\n+\taccel_psp_fs_destroy_ft(\u0026rx-\u003eft);\n+}\n+\n+static int accel_psp_fs_rx_ft_create(struct mlx5e_psp_fs *fs,\n+\t\t\t\t     struct mlx5e_psp_rx_table *rx)\n {\n-\taccel_psp_fs_rx_err_del_rules(fs, rx_err);\n+\tstruct mlx5_ttc_table *ttc = mlx5e_fs_get_ttc(fs-\u003efs, false);\n+\tstruct mlx5_flow_destination dest[2] = {};\n+\tstruct mlx5_flow_table_attr ft_attr = {};\n+\tstruct mlx5_core_dev *mdev = fs-\u003emdev;\n+\tMLX5_DECLARE_FLOW_ACT(flow_act);\n+\tstruct mlx5_flow_handle *rule;\n+\tstruct mlx5_flow_spec *spec;\n+\tint i, err = 0;\n+\n+\tspec = kzalloc_obj(*spec);\n+\tif (!spec)\n+\t\treturn -ENOMEM;\n+\n+\tft_attr.max_fte = 1 + ACCEL_FS_PSP_NUM_TYPES;\n+\tft_attr.level = MLX5E_ACCEL_FS_PSP_RX_FT_LEVEL;\n+\tft_attr.prio = MLX5E_NIC_PRIO;\n+\tft_attr.autogroup.num_reserved_entries = 1;\n+\terr = accel_psp_fs_create_ft(fs, \u0026ft_attr, \u0026rx-\u003eft);\n+\tif (err) {\n+\t\tmlx5_core_err(mdev, \"fail to create psp rx ft err=%d\\n\", err);\n+\t\tgoto out_err;\n+\t}\n \n-\tif (rx_err-\u003eft) {\n-\t\tmlx5_destroy_flow_table(rx_err-\u003eft);\n-\t\trx_err-\u003eft = NULL;\n+\terr = accel_psp_fs_create_miss_group(rx-\u003eft, \u0026rx-\u003emiss_group);\n+\tif (err) {\n+\t\tmlx5_core_err(mdev, \"fail to create psp rx miss_group err=%d\\n\",\n+\t\t\t      err);\n+\t\tgoto out_err;\n \t}\n+\n+\t/* Add miss rule */\n+\tflow_act.action = MLX5_FLOW_CONTEXT_ACTION_FWD_DEST |\n+\t\tMLX5_FLOW_CONTEXT_ACTION_COUNT;\n+\tflow_act.flags = FLOW_ACT_IGNORE_FLOW_LEVEL;\n+\tdest[0].type = MLX5_FLOW_DESTINATION_TYPE_FLOW_TABLE;\n+\tdest[0].ft = mlx5_get_ttc_flow_table(ttc);\n+\tdest[1].type = MLX5_FLOW_DESTINATION_TYPE_COUNTER;\n+\tdest[1].counter = fs-\u003erx_counter;\n+\trule = mlx5_add_flow_rules(rx-\u003eft, NULL, \u0026flow_act, dest, 2);\n+\tif (IS_ERR(rule)) {\n+\t\terr = PTR_ERR(rule);\n+\t\tmlx5_core_err(mdev, \"fail to create psp rx rule, err=%d\\n\",\n+\t\t\t      err);\n+\t\tgoto out_err;\n+\t}\n+\trx-\u003emiss_rule = rule;\n+\n+\t/* Add UDP v4/v6 rules */\n+\tspec-\u003ematch_criteria_enable = MLX5_MATCH_OUTER_HEADERS;\n+\tMLX5_SET_TO_ONES(fte_match_param, spec-\u003ematch_criteria,\n+\t\t\t outer_headers.ip_version);\n+\tMLX5_SET_TO_ONES(fte_match_set_lyr_2_4, spec-\u003ematch_criteria,\n+\t\t\t ip_protocol);\n+\tMLX5_SET(fte_match_set_lyr_2_4, spec-\u003ematch_value, ip_protocol,\n+\t\t IPPROTO_UDP);\n+\tflow_act.action = MLX5_FLOW_CONTEXT_ACTION_FWD_DEST |\n+\t\tMLX5_FLOW_CONTEXT_ACTION_COUNT;\n+\tflow_act.flags = 0;\n+\tfor (i = 0; i \u003c ACCEL_FS_PSP_NUM_TYPES; i++) {\n+\t\tint version = i == ACCEL_FS_PSP4 ? 4 : 6;\n+\n+\t\tMLX5_SET(fte_match_param, spec-\u003ematch_value,\n+\t\t\t outer_headers.ip_version, version);\n+\t\tdest[0] = mlx5_ttc_get_default_dest(ttc, fs_psp2tt(i));\n+\t\tdest[1].type = MLX5_FLOW_DESTINATION_TYPE_COUNTER;\n+\t\tdest[1].counter = fs-\u003erx_counter;\n+\t\trule = mlx5_add_flow_rules(rx-\u003eft, spec, \u0026flow_act, dest,\n+\t\t\t\t\t   2);\n+\t\tif (IS_ERR(rule)) {\n+\t\t\terr = PTR_ERR(rule);\n+\t\t\tmlx5_core_err(mdev,\n+\t\t\t\t      \"fail to create psp rx UDP%d rule err=%d\\n\",\n+\t\t\t\t      version, err);\n+\t\t\tgoto out_err;\n+\t\t}\n+\t\trx-\u003eudp_rules[i] = rule;\n+\t}\n+\tgoto out_spec;\n+\n+out_err:\n+\taccel_psp_fs_rx_ft_destroy(rx);\n+out_spec:\n+\tkvfree(spec);\n+\treturn err;\n+}\n+\n+static\n+void accel_psp_fs_rx_check_ft_destroy(struct mlx5e_psp_rx_check_table *check)\n+{\n+\taccel_psp_fs_del_flow_rule(\u0026check-\u003ebad_rule);\n+\taccel_psp_fs_del_flow_rule(\u0026check-\u003eerr_rule);\n+\taccel_psp_fs_del_flow_rule(\u0026check-\u003eauth_fail_rule);\n+\taccel_psp_fs_del_flow_rule(\u0026check-\u003erule);\n+\taccel_psp_fs_destroy_flow_group(\u0026check-\u003edrop_group);\n+\taccel_psp_fs_destroy_ft(\u0026check-\u003eft);\n }\n \n static void accel_psp_setup_syndrome_match(struct mlx5_flow_spec *spec,\n@@ -129,15 +286,35 @@ static void accel_psp_setup_syndrome_match(struct mlx5_flow_spec *spec,\n \tMLX5_SET(fte_match_set_misc2, misc_params_2, psp_syndrome, syndrome);\n }\n \n-static int accel_psp_fs_rx_err_add_rule(struct mlx5e_psp_fs *fs,\n-\t\t\t\t\tstruct mlx5e_accel_fs_psp_prot *fs_prot,\n-\t\t\t\t\tstruct mlx5e_psp_rx_err *rx_err)\n+static int accel_psp_add_drop_rule(struct mlx5_flow_table *ft,\n+\t\t\t\t   struct mlx5_flow_spec *spec,\n+\t\t\t\t   struct mlx5_fc *counter,\n+\t\t\t\t   struct mlx5_flow_handle **rule)\n {\n-\tu8 action[MLX5_UN_SZ_BYTES(set_add_copy_action_in_auto)] = {};\n+\tstruct mlx5_flow_destination dest = {};\n+\tstruct mlx5_flow_act flow_act = {};\n+\tint err = 0;\n+\n+\tflow_act.action = MLX5_FLOW_CONTEXT_ACTION_DROP |\n+\t\t\t  MLX5_FLOW_CONTEXT_ACTION_COUNT;\n+\tdest.type = MLX5_FLOW_DESTINATION_TYPE_COUNTER;\n+\tdest.counter = counter;\n+\t*rule = mlx5_add_flow_rules(ft, spec, \u0026flow_act, \u0026dest, 1);\n+\tif (IS_ERR(*rule)) {\n+\t\terr = PTR_ERR(*rule);\n+\t\t*rule = NULL;\n+\t}\n+\treturn err;\n+}\n+\n+static\n+int accel_psp_fs_rx_check_ft_create(struct mlx5e_psp_fs *fs,\n+\t\t\t\t    struct mlx5e_psp_rx_check_table *check)\n+{\n+\tstruct mlx5_flow_table_attr ft_attr = {};\n+\tstruct mlx5_flow_destination dest = {};\n \tstruct mlx5_core_dev *mdev = fs-\u003emdev;\n-\tstruct mlx5_flow_destination dest[2];\n \tstruct mlx5_flow_act flow_act = {};\n-\tstruct mlx5_modify_hdr *modify_hdr;\n \tstruct mlx5_flow_handle *fte;\n \tstruct mlx5_flow_spec *spec;\n \tint err = 0;\n@@ -146,174 +323,97 @@ static int accel_psp_fs_rx_err_add_rule(struct mlx5e_psp_fs *fs,\n \tif (!spec)\n \t\treturn -ENOMEM;\n \n-\t/* Action to copy 7 bit psp_syndrome to regB[23:29] */\n-\tMLX5_SET(copy_action_in, action, action_type, MLX5_ACTION_TYPE_COPY);\n-\tMLX5_SET(copy_action_in, action, src_field, MLX5_ACTION_IN_FIELD_PSP_SYNDROME);\n-\tMLX5_SET(copy_action_in, action, src_offset, 0);\n-\tMLX5_SET(copy_action_in, action, length, 7);\n-\tMLX5_SET(copy_action_in, action, dst_field, MLX5_ACTION_IN_FIELD_METADATA_REG_B);\n-\tMLX5_SET(copy_action_in, action, dst_offset, 23);\n+\tft_attr.max_fte = 4;\n+\tft_attr.autogroup.num_reserved_entries = 1;\n+\tft_attr.autogroup.max_num_groups = 2;\n+\tft_attr.level = MLX5E_ACCEL_FS_PSP_ERR_FT_LEVEL;\n+\tft_attr.prio = MLX5E_NIC_PRIO;\n+\terr = accel_psp_fs_create_ft(fs, \u0026ft_attr, \u0026check-\u003eft);\n+\tif (err) {\n+\t\tmlx5_core_err(fs-\u003emdev,\n+\t\t\t      \"fail to create psp rx check ft err=%d\\n\", err);\n+\t\tgoto out_err;\n+\t}\n \n-\tmodify_hdr = mlx5_modify_header_alloc(mdev, MLX5_FLOW_NAMESPACE_KERNEL,\n-\t\t\t\t\t      1, action);\n-\tif (IS_ERR(modify_hdr)) {\n-\t\terr = PTR_ERR(modify_hdr);\n-\t\tmlx5_core_err(mdev,\n-\t\t\t      \"fail to alloc psp copy modify_header_id err=%d\\n\", err);\n-\t\tgoto out_spec;\n+\terr = accel_psp_fs_create_miss_group(check-\u003eft, \u0026check-\u003edrop_group);\n+\tif (err) {\n+\t\tmlx5_core_err(fs-\u003emdev,\n+\t\t\t      \"fail to create psp rx check drop group err=%d\\n\",\n+\t\t\t      err);\n+\t\tgoto out_err;\n \t}\n \n \taccel_psp_setup_syndrome_match(spec, PSP_OK);\n \t/* create fte */\n-\tflow_act.action = MLX5_FLOW_CONTEXT_ACTION_MOD_HDR |\n-\t\t\t  MLX5_FLOW_CONTEXT_ACTION_FWD_DEST |\n-\t\t\t  MLX5_FLOW_CONTEXT_ACTION_COUNT;\n-\tflow_act.modify_hdr = modify_hdr;\n-\tdest[0].type = fs_prot-\u003edefault_dest.type;\n-\tdest[0].ft = fs_prot-\u003edefault_dest.ft;\n-\tdest[1].type = MLX5_FLOW_DESTINATION_TYPE_COUNTER;\n-\tdest[1].counter = fs-\u003erx_fs-\u003erx_counter;\n-\tfte = mlx5_add_flow_rules(rx_err-\u003eft, spec, \u0026flow_act, dest, 2);\n+\tflow_act.action = MLX5_FLOW_CONTEXT_ACTION_FWD_DEST;\n+\tdest.type = MLX5_FLOW_DESTINATION_TYPE_FLOW_TABLE;\n+\tdest.ft = fs-\u003erx.ft;\n+\tfte = mlx5_add_flow_rules(check-\u003eft, spec, \u0026flow_act, \u0026dest, 1);\n \tif (IS_ERR(fte)) {\n \t\terr = PTR_ERR(fte);\n-\t\tmlx5_core_err(mdev, \"fail to add psp rx err copy rule err=%d\\n\", err);\n-\t\tgoto out;\n+\t\tmlx5_core_err(mdev, \"fail to add psp rx check ok rule err=%d\\n\",\n+\t\t\t      err);\n+\t\tgoto out_err;\n \t}\n-\trx_err-\u003erule = fte;\n+\tcheck-\u003erule = fte;\n \n \t/* add auth fail drop rule */\n \tmemset(spec, 0, sizeof(*spec));\n-\tmemset(\u0026flow_act, 0, sizeof(flow_act));\n \taccel_psp_setup_syndrome_match(spec, PSP_ICV_FAIL);\n-\t/* create fte */\n-\tflow_act.action = MLX5_FLOW_CONTEXT_ACTION_DROP |\n-\t\t\t  MLX5_FLOW_CONTEXT_ACTION_COUNT;\n-\tdest[0].type = MLX5_FLOW_DESTINATION_TYPE_COUNTER;\n-\tdest[0].counter = fs-\u003erx_fs-\u003erx_auth_fail_counter;\n-\tfte = mlx5_add_flow_rules(rx_err-\u003eft, spec, \u0026flow_act, dest, 1);\n-\tif (IS_ERR(fte)) {\n-\t\terr = PTR_ERR(fte);\n-\t\tmlx5_core_err(mdev, \"fail to add psp rx auth fail drop rule err=%d\\n\",\n+\terr = accel_psp_add_drop_rule(check-\u003eft, spec,\n+\t\t\t\t      fs-\u003erx_auth_fail_counter,\n+\t\t\t\t      \u0026check-\u003eauth_fail_rule);\n+\tif (err) {\n+\t\tmlx5_core_err(mdev,\n+\t\t\t      \"fail to add psp rx check auth fail drop rule err=%d\\n\",\n \t\t\t      err);\n-\t\tgoto out_drop_rule;\n+\t\tgoto out_err;\n \t}\n-\trx_err-\u003eauth_fail_rule = fte;\n \n \t/* add framing drop rule */\n \tmemset(spec, 0, sizeof(*spec));\n-\tmemset(\u0026flow_act, 0, sizeof(flow_act));\n \taccel_psp_setup_syndrome_match(spec, PSP_BAD_TRAILER);\n-\t/* create fte */\n-\tflow_act.action = MLX5_FLOW_CONTEXT_ACTION_DROP |\n-\t\t\t  MLX5_FLOW_CONTEXT_ACTION_COUNT;\n-\tdest[0].type = MLX5_FLOW_DESTINATION_TYPE_COUNTER;\n-\tdest[0].counter = fs-\u003erx_fs-\u003erx_err_counter;\n-\tfte = mlx5_add_flow_rules(rx_err-\u003eft, spec, \u0026flow_act, dest, 1);\n-\tif (IS_ERR(fte)) {\n-\t\terr = PTR_ERR(fte);\n-\t\tmlx5_core_err(mdev, \"fail to add psp rx framing err drop rule err=%d\\n\",\n+\terr = accel_psp_add_drop_rule(check-\u003eft, spec, fs-\u003erx_err_counter,\n+\t\t\t\t      \u0026check-\u003eerr_rule);\n+\tif (err) {\n+\t\tmlx5_core_err(mdev,\n+\t\t\t      \"fail to add psp rx check framing drop rule err=%d\\n\",\n \t\t\t      err);\n-\t\tgoto out_drop_auth_fail_rule;\n+\t\tgoto out_err;\n \t}\n-\trx_err-\u003eerr_rule = fte;\n \n \t/* add misc. errors drop rule */\n \tmemset(spec, 0, sizeof(*spec));\n-\tmemset(\u0026flow_act, 0, sizeof(flow_act));\n-\t/* create fte */\n-\tflow_act.action = MLX5_FLOW_CONTEXT_ACTION_DROP |\n-\t\t\t  MLX5_FLOW_CONTEXT_ACTION_COUNT;\n-\tdest[0].type = MLX5_FLOW_DESTINATION_TYPE_COUNTER;\n-\tdest[0].counter = fs-\u003erx_fs-\u003erx_bad_counter;\n-\tfte = mlx5_add_flow_rules(rx_err-\u003eft, spec, \u0026flow_act, dest, 1);\n-\tif (IS_ERR(fte)) {\n-\t\terr = PTR_ERR(fte);\n-\t\tmlx5_core_err(mdev, \"fail to add psp rx misc. err drop rule err=%d\\n\",\n+\terr = accel_psp_add_drop_rule(check-\u003eft, spec, fs-\u003erx_bad_counter,\n+\t\t\t\t      \u0026check-\u003ebad_rule);\n+\tif (err) {\n+\t\tmlx5_core_err(mdev,\n+\t\t\t      \"fail to add psp rx check misc. err drop rule err=%d\\n\",\n \t\t\t      err);\n-\t\tgoto out_drop_error_rule;\n+\t\tgoto out_err;\n \t}\n-\trx_err-\u003ebad_rule = fte;\n-\n-\trx_err-\u003ecopy_modify_hdr = modify_hdr;\n \n \tgoto out_spec;\n \n-out_drop_error_rule:\n-\tmlx5_del_flow_rules(rx_err-\u003eerr_rule);\n-\trx_err-\u003eerr_rule = NULL;\n-out_drop_auth_fail_rule:\n-\tmlx5_del_flow_rules(rx_err-\u003eauth_fail_rule);\n-\trx_err-\u003eauth_fail_rule = NULL;\n-out_drop_rule:\n-\tmlx5_del_flow_rules(rx_err-\u003erule);\n-\trx_err-\u003erule = NULL;\n-out:\n-\tmlx5_modify_header_dealloc(mdev, modify_hdr);\n+out_err:\n+\taccel_psp_fs_rx_check_ft_destroy(check);\n out_spec:\n \tkfree(spec);\n \treturn err;\n }\n \n-static int accel_psp_fs_rx_err_create_ft(struct mlx5e_psp_fs *fs,\n-\t\t\t\t\t struct mlx5e_accel_fs_psp_prot *fs_prot,\n-\t\t\t\t\t struct mlx5e_psp_rx_err *rx_err)\n+static void\n+accel_psp_fs_rx_decrypt_ft_destroy(struct mlx5e_psp_fs *fs,\n+\t\t\t\t   struct mlx5e_psp_rx_decrypt_table *decrypt)\n {\n-\tstruct mlx5_flow_namespace *ns = mlx5e_fs_get_ns(fs-\u003efs, false);\n-\tstruct mlx5_flow_table_attr ft_attr = {};\n-\tstruct mlx5_flow_table *ft;\n-\tint err;\n-\n-\tft_attr.max_fte = 2;\n-\tft_attr.autogroup.max_num_groups = 2;\n-\tft_attr.level = MLX5E_ACCEL_FS_ESP_FT_ERR_LEVEL; // MLX5E_ACCEL_FS_TCP_FT_LEVEL\n-\tft_attr.prio = MLX5E_NIC_PRIO;\n-\tft = mlx5_create_auto_grouped_flow_table(ns, \u0026ft_attr);\n-\tif (IS_ERR(ft)) {\n-\t\terr = PTR_ERR(ft);\n-\t\tmlx5_core_err(fs-\u003emdev, \"fail to create psp rx inline ft err=%d\\n\", err);\n-\t\treturn err;\n-\t}\n-\n-\trx_err-\u003eft = ft;\n-\terr = accel_psp_fs_rx_err_add_rule(fs, fs_prot, rx_err);\n-\tif (err)\n-\t\tgoto out_err;\n-\n-\treturn 0;\n-\n-out_err:\n-\tmlx5_destroy_flow_table(ft);\n-\trx_err-\u003eft = NULL;\n-\treturn err;\n-}\n-\n-static void accel_psp_fs_rx_fs_destroy(struct mlx5e_psp_fs *fs,\n-\t\t\t\t       struct mlx5e_accel_fs_psp_prot *fs_prot)\n-{\n-\tif (fs_prot-\u003edef_rule) {\n-\t\tmlx5_del_flow_rules(fs_prot-\u003edef_rule);\n-\t\tfs_prot-\u003edef_rule = NULL;\n-\t}\n-\n-\tif (fs_prot-\u003erx_modify_hdr) {\n-\t\tmlx5_modify_header_dealloc(fs-\u003emdev, fs_prot-\u003erx_modify_hdr);\n-\t\tfs_prot-\u003erx_modify_hdr = NULL;\n-\t}\n-\n-\tif (fs_prot-\u003emiss_rule) {\n-\t\tmlx5_del_flow_rules(fs_prot-\u003emiss_rule);\n-\t\tfs_prot-\u003emiss_rule = NULL;\n-\t}\n-\n-\tif (fs_prot-\u003emiss_group) {\n-\t\tmlx5_destroy_flow_group(fs_prot-\u003emiss_group);\n-\t\tfs_prot-\u003emiss_group = NULL;\n-\t}\n-\n-\tif (fs_prot-\u003eft) {\n-\t\tmlx5_destroy_flow_table(fs_prot-\u003eft);\n-\t\tfs_prot-\u003eft = NULL;\n+\taccel_psp_fs_del_flow_rule(\u0026decrypt-\u003erule);\n+\tif (decrypt-\u003erx_modify_hdr) {\n+\t\tmlx5_modify_header_dealloc(fs-\u003emdev, decrypt-\u003erx_modify_hdr);\n+\t\tdecrypt-\u003erx_modify_hdr = NULL;\n \t}\n+\taccel_psp_fs_del_flow_rule(\u0026decrypt-\u003emiss_rule);\n+\taccel_psp_fs_destroy_flow_group(\u0026decrypt-\u003emiss_group);\n+\taccel_psp_fs_destroy_ft(\u0026decrypt-\u003eft);\n }\n \n static void setup_fte_udp_psp(struct mlx5_flow_spec *spec, u16 udp_port)\n@@ -325,70 +425,64 @@ static void setup_fte_udp_psp(struct mlx5_flow_spec *spec, u16 udp_port)\n \tMLX5_SET(fte_match_set_lyr_2_4, spec-\u003ematch_value, ip_protocol, IPPROTO_UDP);\n }\n \n-static int accel_psp_fs_rx_create_ft(struct mlx5e_psp_fs *fs,\n-\t\t\t\t     struct mlx5e_accel_fs_psp_prot *fs_prot)\n+static int\n+accel_psp_fs_rx_decrypt_ft_create(struct mlx5e_psp_fs *fs,\n+\t\t\t\t  struct mlx5e_psp_rx_decrypt_table *decrypt,\n+\t\t\t\t  struct mlx5_flow_destination *default_dest)\n {\n-\tstruct mlx5_flow_namespace *ns = mlx5e_fs_get_ns(fs-\u003efs, false);\n \tu8 action[MLX5_UN_SZ_BYTES(set_add_copy_action_in_auto)] = {};\n-\tint inlen = MLX5_ST_SZ_BYTES(create_flow_group_in);\n \tstruct mlx5_modify_hdr *modify_hdr = NULL;\n \tstruct mlx5_flow_table_attr ft_attr = {};\n \tstruct mlx5_flow_destination dest = {};\n \tstruct mlx5_core_dev *mdev = fs-\u003emdev;\n-\tstruct mlx5_flow_group *miss_group;\n \tMLX5_DECLARE_FLOW_ACT(flow_act);\n \tstruct mlx5_flow_handle *rule;\n \tstruct mlx5_flow_spec *spec;\n-\tstruct mlx5_flow_table *ft;\n-\tu32 *flow_group_in;\n \tint err = 0;\n \n-\tflow_group_in = kvzalloc(inlen, GFP_KERNEL);\n \tspec = kvzalloc_obj(*spec);\n-\tif (!flow_group_in || !spec) {\n-\t\terr = -ENOMEM;\n-\t\tgoto out;\n-\t}\n+\tif (!spec)\n+\t\treturn -ENOMEM;\n \n \t/* Create FT */\n \tft_attr.max_fte = 2;\n-\tft_attr.level = MLX5E_ACCEL_FS_ESP_FT_LEVEL;\n-\tft_attr.prio = MLX5E_NIC_PRIO;\n+\tft_attr.level = MLX5E_ACCEL_FS_PSP_FT_LEVEL;\n \tft_attr.autogroup.num_reserved_entries = 1;\n \tft_attr.autogroup.max_num_groups = 1;\n-\tft = mlx5_create_auto_grouped_flow_table(ns, \u0026ft_attr);\n-\tif (IS_ERR(ft)) {\n-\t\terr = PTR_ERR(ft);\n-\t\tmlx5_core_err(mdev, \"fail to create psp rx ft err=%d\\n\", err);\n+\tft_attr.prio = MLX5E_NIC_PRIO;\n+\terr = accel_psp_fs_create_ft(fs, \u0026ft_attr, \u0026decrypt-\u003eft);\n+\tif (err) {\n+\t\tmlx5_core_err(mdev, \"fail to create psp rx decrypt ft err=%d\\n\",\n+\t\t\t      err);\n \t\tgoto out_err;\n \t}\n-\tfs_prot-\u003eft = ft;\n \n \t/* Create miss_group */\n-\tMLX5_SET(create_flow_group_in, flow_group_in, start_flow_index, ft-\u003emax_fte - 1);\n-\tMLX5_SET(create_flow_group_in, flow_group_in, end_flow_index, ft-\u003emax_fte - 1);\n-\tmiss_group = mlx5_create_flow_group(ft, flow_group_in);\n-\tif (IS_ERR(miss_group)) {\n-\t\terr = PTR_ERR(miss_group);\n-\t\tmlx5_core_err(mdev, \"fail to create psp rx miss_group err=%d\\n\", err);\n+\terr = accel_psp_fs_create_miss_group(decrypt-\u003eft, \u0026decrypt-\u003emiss_group);\n+\tif (err) {\n+\t\tmlx5_core_err(mdev,\n+\t\t\t      \"fail to create psp rx decrypt miss_group err=%d\\n\",\n+\t\t\t      err);\n \t\tgoto out_err;\n \t}\n-\tfs_prot-\u003emiss_group = miss_group;\n \n \t/* Create miss rule */\n-\trule = mlx5_add_flow_rules(ft, spec, \u0026flow_act, \u0026fs_prot-\u003edefault_dest, 1);\n+\tflow_act.action = MLX5_FLOW_CONTEXT_ACTION_FWD_DEST;\n+\trule = mlx5_add_flow_rules(decrypt-\u003eft, spec, \u0026flow_act, default_dest,\n+\t\t\t\t   1);\n \tif (IS_ERR(rule)) {\n \t\terr = PTR_ERR(rule);\n-\t\tmlx5_core_err(mdev, \"fail to create psp rx miss_rule err=%d\\n\", err);\n+\t\tmlx5_core_err(mdev,\n+\t\t\t      \"fail to create psp rx decrypt miss_rule err=%d\\n\",\n+\t\t\t      err);\n \t\tgoto out_err;\n \t}\n-\tfs_prot-\u003emiss_rule = rule;\n+\tdecrypt-\u003emiss_rule = rule;\n \n-\t/* Add default Rx psp rule */\n+\t/* Add PSP RX decrypt rule */\n \tsetup_fte_udp_psp(spec, PSP_DEFAULT_UDP_PORT);\n \tflow_act.crypto.type = MLX5_FLOW_CONTEXT_ENCRYPT_DECRYPT_TYPE_PSP;\n \t/* Set bit[31, 30] PSP marker */\n-\t/* Set bit[29-23] psp_syndrome is set in error FT */\n #define MLX5E_PSP_MARKER_BIT (BIT(30) | BIT(31))\n \tMLX5_SET(set_action_in, action, action_type, MLX5_ACTION_TYPE_SET);\n \tMLX5_SET(set_action_in, action, field, MLX5_ACTION_IN_FIELD_METADATA_REG_B);\n@@ -403,275 +497,159 @@ static int accel_psp_fs_rx_create_ft(struct mlx5e_psp_fs *fs,\n \t\tmodify_hdr = NULL;\n \t\tgoto out_err;\n \t}\n-\tfs_prot-\u003erx_modify_hdr = modify_hdr;\n+\tdecrypt-\u003erx_modify_hdr = modify_hdr;\n \n \tflow_act.action = MLX5_FLOW_CONTEXT_ACTION_FWD_DEST |\n \t\t\t  MLX5_FLOW_CONTEXT_ACTION_CRYPTO_DECRYPT |\n \t\t\t  MLX5_FLOW_CONTEXT_ACTION_MOD_HDR;\n \tflow_act.modify_hdr = modify_hdr;\n \tdest.type = MLX5_FLOW_DESTINATION_TYPE_FLOW_TABLE;\n-\tdest.ft = fs_prot-\u003erx_err.ft;\n-\trule = mlx5_add_flow_rules(fs_prot-\u003eft, spec, \u0026flow_act, \u0026dest, 1);\n+\tdest.ft = fs-\u003echeck.ft;\n+\trule = mlx5_add_flow_rules(decrypt-\u003eft, spec, \u0026flow_act, \u0026dest, 1);\n \tif (IS_ERR(rule)) {\n \t\terr = PTR_ERR(rule);\n-\t\tmlx5_core_err(mdev,\n-\t\t\t      \"fail to add psp rule Rx decryption, err=%d, flow_act.action = %#04X\\n\",\n-\t\t\t      err, flow_act.action);\n+\t\tmlx5_core_err(mdev, \"fail to add psp rx decrypt rule, err=%d\\n\",\n+\t\t\t      err);\n \t\tgoto out_err;\n \t}\n \n-\tfs_prot-\u003edef_rule = rule;\n-\tgoto out;\n+\tdecrypt-\u003erule = rule;\n+\tgoto out_spec;\n \n out_err:\n-\taccel_psp_fs_rx_fs_destroy(fs, fs_prot);\n-out:\n-\tkvfree(flow_group_in);\n+\taccel_psp_fs_rx_decrypt_ft_destroy(fs, decrypt);\n+out_spec:\n \tkvfree(spec);\n \treturn err;\n }\n \n-static int accel_psp_fs_rx_destroy(struct mlx5e_psp_fs *fs, enum accel_fs_psp_type type)\n+static void accel_psp_fs_rx_destroy(struct mlx5e_psp_fs *fs)\n {\n-\tstruct mlx5e_accel_fs_psp_prot *fs_prot;\n-\tstruct mlx5e_accel_fs_psp *accel_psp;\n-\n-\taccel_psp = fs-\u003erx_fs;\n-\n-\t/* The netdev unreg already happened, so all offloaded rule are already removed */\n-\tfs_prot = \u0026accel_psp-\u003efs_prot[type];\n-\n-\taccel_psp_fs_rx_fs_destroy(fs, fs_prot);\n-\n-\taccel_psp_fs_rx_err_destroy_ft(fs, \u0026fs_prot-\u003erx_err);\n+\tstruct mlx5_ttc_table *ttc = mlx5e_fs_get_ttc(fs-\u003efs, false);\n+\tint i;\n \n-\treturn 0;\n+\t/* disconnect */\n+\tfor (i = 0; i \u003c ACCEL_FS_PSP_NUM_TYPES; i++) {\n+\t\tmlx5_ttc_fwd_default_dest(ttc, fs_psp2tt(i));\n+\t\taccel_psp_fs_rx_decrypt_ft_destroy(fs, \u0026fs-\u003edecrypt[i]);\n+\t}\n+\taccel_psp_fs_rx_check_ft_destroy(\u0026fs-\u003echeck);\n+\taccel_psp_fs_rx_ft_destroy(\u0026fs-\u003erx);\n }\n \n-static int accel_psp_fs_rx_create(struct mlx5e_psp_fs *fs, enum accel_fs_psp_type type)\n+static int accel_psp_fs_rx_create(struct mlx5e_psp_fs *fs,\n+\t\t\t\t  struct netlink_ext_ack *extack)\n {\n \tstruct mlx5_ttc_table *ttc = mlx5e_fs_get_ttc(fs-\u003efs, false);\n-\tstruct mlx5e_accel_fs_psp_prot *fs_prot;\n-\tstruct mlx5e_accel_fs_psp *accel_psp;\n-\tint err;\n-\n-\taccel_psp = fs-\u003erx_fs;\n-\tfs_prot = \u0026accel_psp-\u003efs_prot[type];\n+\tint i, err;\n \n-\tfs_prot-\u003edefault_dest = mlx5_ttc_get_default_dest(ttc, fs_psp2tt(type));\n-\n-\terr = accel_psp_fs_rx_err_create_ft(fs, fs_prot, \u0026fs_prot-\u003erx_err);\n-\tif (err)\n+\terr = accel_psp_fs_rx_ft_create(fs, \u0026fs-\u003erx);\n+\tif (err) {\n+\t\tNL_SET_ERR_MSG(extack, \"Failed creating RX steering table\");\n \t\treturn err;\n+\t}\n \n-\terr = accel_psp_fs_rx_create_ft(fs, fs_prot);\n-\tif (err)\n-\t\taccel_psp_fs_rx_err_destroy_ft(fs, \u0026fs_prot-\u003erx_err);\n-\n-\treturn err;\n-}\n-\n-static int accel_psp_fs_rx_ft_get(struct mlx5e_psp_fs *fs, enum accel_fs_psp_type type)\n-{\n-\tstruct mlx5e_accel_fs_psp_prot *fs_prot;\n-\tstruct mlx5_flow_destination dest = {};\n-\tstruct mlx5e_accel_fs_psp *accel_psp;\n-\tstruct mlx5_ttc_table *ttc;\n-\tint err = 0;\n-\n-\tif (!fs || !fs-\u003erx_fs)\n-\t\treturn -EINVAL;\n-\n-\tttc = mlx5e_fs_get_ttc(fs-\u003efs, false);\n-\taccel_psp = fs-\u003erx_fs;\n-\tfs_prot = \u0026accel_psp-\u003efs_prot[type];\n-\tmutex_lock(\u0026fs_prot-\u003eprot_mutex);\n-\tif (fs_prot-\u003erefcnt++)\n-\t\tgoto out;\n-\n-\t/* create FT */\n-\terr = accel_psp_fs_rx_create(fs, type);\n+\terr = accel_psp_fs_rx_check_ft_create(fs, \u0026fs-\u003echeck);\n \tif (err) {\n-\t\tfs_prot-\u003erefcnt--;\n-\t\tgoto out;\n+\t\tNL_SET_ERR_MSG(extack,\n+\t\t\t       \"Failed creating RX check steering table\");\n+\t\tgoto err_ft;\n \t}\n \n-\t/* connect */\n-\tdest.type = MLX5_FLOW_DESTINATION_TYPE_FLOW_TABLE;\n-\tdest.ft = fs_prot-\u003eft;\n-\tmlx5_ttc_fwd_dest(ttc, fs_psp2tt(type), \u0026dest);\n-\n-out:\n-\tmutex_unlock(\u0026fs_prot-\u003eprot_mutex);\n-\treturn err;\n-}\n-\n-static void accel_psp_fs_rx_ft_put(struct mlx5e_psp_fs *fs, enum accel_fs_psp_type type)\n-{\n-\tstruct mlx5_ttc_table *ttc = mlx5e_fs_get_ttc(fs-\u003efs, false);\n-\tstruct mlx5e_accel_fs_psp_prot *fs_prot;\n-\tstruct mlx5e_accel_fs_psp *accel_psp;\n-\n-\taccel_psp = fs-\u003erx_fs;\n-\tfs_prot = \u0026accel_psp-\u003efs_prot[type];\n-\tmutex_lock(\u0026fs_prot-\u003eprot_mutex);\n-\tif (--fs_prot-\u003erefcnt)\n-\t\tgoto out;\n-\n-\t/* disconnect */\n-\tmlx5_ttc_fwd_default_dest(ttc, fs_psp2tt(type));\n+\tfor (i = 0; i \u003c ACCEL_FS_PSP_NUM_TYPES; i++) {\n+\t\tstruct mlx5_flow_destination dest;\n+\n+\t\tdest = mlx5_ttc_get_default_dest(ttc, fs_psp2tt(i));\n+\t\terr = accel_psp_fs_rx_decrypt_ft_create(fs, \u0026fs-\u003edecrypt[i],\n+\t\t\t\t\t\t\t\u0026dest);\n+\t\tif (err) {\n+\t\t\tNL_SET_ERR_MSG(extack,\n+\t\t\t\t       \"Failed creating RX decrypt steering table\");\n+\t\t\tgoto err_decrypt_ft;\n+\t\t}\n+\n+\t\tdest.type = MLX5_FLOW_DESTINATION_TYPE_FLOW_TABLE;\n+\t\tdest.ft = fs-\u003edecrypt[i].ft;\n+\t\tmlx5_ttc_fwd_dest(ttc, fs_psp2tt(i), \u0026dest);\n+\t}\n \n-\t/* remove FT */\n-\taccel_psp_fs_rx_destroy(fs, type);\n+\treturn 0;\n \n-out:\n-\tmutex_unlock(\u0026fs_prot-\u003eprot_mutex);\n+err_decrypt_ft:\n+\twhile (--i \u003e= 0) {\n+\t\tmlx5_ttc_fwd_default_dest(ttc, fs_psp2tt(i));\n+\t\taccel_psp_fs_rx_decrypt_ft_destroy(fs, \u0026fs-\u003edecrypt[i]);\n+\t}\n+\taccel_psp_fs_rx_check_ft_destroy(\u0026fs-\u003echeck);\n+err_ft:\n+\taccel_psp_fs_rx_ft_destroy(\u0026fs-\u003erx);\n+\treturn err;\n }\n \n-static void accel_psp_fs_cleanup_rx(struct mlx5e_psp_fs *fs)\n+static void accel_psp_fs_rx_cleanup(struct mlx5e_psp_fs *fs)\n {\n-\tstruct mlx5e_accel_fs_psp_prot *fs_prot;\n-\tstruct mlx5e_accel_fs_psp *accel_psp;\n-\tenum accel_fs_psp_type i;\n-\n-\tif (!fs-\u003erx_fs)\n-\t\treturn;\n-\n-\taccel_psp = fs-\u003erx_fs;\n-\tmlx5_fc_destroy(fs-\u003emdev, accel_psp-\u003erx_bad_counter);\n-\tmlx5_fc_destroy(fs-\u003emdev, accel_psp-\u003erx_err_counter);\n-\tmlx5_fc_destroy(fs-\u003emdev, accel_psp-\u003erx_auth_fail_counter);\n-\tmlx5_fc_destroy(fs-\u003emdev, accel_psp-\u003erx_counter);\n-\tfor (i = 0; i \u003c ACCEL_FS_PSP_NUM_TYPES; i++) {\n-\t\tfs_prot = \u0026accel_psp-\u003efs_prot[i];\n-\t\tmutex_destroy(\u0026fs_prot-\u003eprot_mutex);\n-\t\tWARN_ON(fs_prot-\u003erefcnt);\n-\t}\n-\tkfree(fs-\u003erx_fs);\n-\tfs-\u003erx_fs = NULL;\n+\taccel_psp_fs_destroy_counter(fs-\u003emdev, \u0026fs-\u003erx_bad_counter);\n+\taccel_psp_fs_destroy_counter(fs-\u003emdev, \u0026fs-\u003erx_err_counter);\n+\taccel_psp_fs_destroy_counter(fs-\u003emdev, \u0026fs-\u003erx_auth_fail_counter);\n+\taccel_psp_fs_destroy_counter(fs-\u003emdev, \u0026fs-\u003erx_counter);\n }\n \n-static int accel_psp_fs_init_rx(struct mlx5e_psp_fs *fs)\n+static int accel_psp_fs_rx_init(struct mlx5e_psp_fs *fs)\n {\n-\tstruct mlx5e_accel_fs_psp_prot *fs_prot;\n-\tstruct mlx5e_accel_fs_psp *accel_psp;\n \tstruct mlx5_core_dev *mdev = fs-\u003emdev;\n-\tstruct mlx5_fc *flow_counter;\n-\tenum accel_fs_psp_type i;\n \tint err;\n \n-\taccel_psp = kzalloc_obj(*accel_psp);\n-\tif (!accel_psp)\n-\t\treturn -ENOMEM;\n-\n-\tfor (i = 0; i \u003c ACCEL_FS_PSP_NUM_TYPES; i++) {\n-\t\tfs_prot = \u0026accel_psp-\u003efs_prot[i];\n-\t\tmutex_init(\u0026fs_prot-\u003eprot_mutex);\n-\t}\n-\n-\tflow_counter = mlx5_fc_create(mdev, false);\n-\tif (IS_ERR(flow_counter)) {\n+\terr = accel_psp_fs_create_counter(mdev, \u0026fs-\u003erx_counter);\n+\tif (err) {\n \t\tmlx5_core_warn(mdev,\n-\t\t\t       \"fail to create psp rx flow counter err=%pe\\n\",\n-\t\t\t       flow_counter);\n-\t\terr = PTR_ERR(flow_counter);\n+\t\t\t       \"fail to create psp rx flow counter err=%d\\n\",\n+\t\t\t       err);\n \t\tgoto out_err;\n \t}\n-\taccel_psp-\u003erx_counter = flow_counter;\n \n-\tflow_counter = mlx5_fc_create(mdev, false);\n-\tif (IS_ERR(flow_counter)) {\n+\terr = accel_psp_fs_create_counter(mdev, \u0026fs-\u003erx_auth_fail_counter);\n+\tif (err) {\n \t\tmlx5_core_warn(mdev,\n-\t\t\t       \"fail to create psp rx auth fail flow counter err=%pe\\n\",\n-\t\t\t       flow_counter);\n-\t\terr = PTR_ERR(flow_counter);\n-\t\tgoto out_counter_err;\n+\t\t\t       \"fail to create psp rx auth fail flow counter err=%d\\n\",\n+\t\t\t       err);\n+\t\tgoto out_err;\n \t}\n-\taccel_psp-\u003erx_auth_fail_counter = flow_counter;\n \n-\tflow_counter = mlx5_fc_create(mdev, false);\n-\tif (IS_ERR(flow_counter)) {\n+\terr = accel_psp_fs_create_counter(mdev, \u0026fs-\u003erx_err_counter);\n+\tif (err) {\n \t\tmlx5_core_warn(mdev,\n-\t\t\t       \"fail to create psp rx error flow counter err=%pe\\n\",\n-\t\t\t       flow_counter);\n-\t\terr = PTR_ERR(flow_counter);\n-\t\tgoto out_auth_fail_counter_err;\n+\t\t\t       \"fail to create psp rx error flow counter err=%d\\n\",\n+\t\t\t       err);\n+\t\tgoto out_err;\n \t}\n-\taccel_psp-\u003erx_err_counter = flow_counter;\n \n-\tflow_counter = mlx5_fc_create(mdev, false);\n-\tif (IS_ERR(flow_counter)) {\n+\terr = accel_psp_fs_create_counter(mdev, \u0026fs-\u003erx_bad_counter);\n+\tif (err) {\n \t\tmlx5_core_warn(mdev,\n-\t\t\t       \"fail to create psp rx bad flow counter err=%pe\\n\",\n-\t\t\t       flow_counter);\n-\t\terr = PTR_ERR(flow_counter);\n-\t\tgoto out_err_counter_err;\n+\t\t\t       \"fail to create psp rx bad flow counter err=%d\\n\",\n+\t\t\t       err);\n+\t\tgoto out_err;\n \t}\n-\taccel_psp-\u003erx_bad_counter = flow_counter;\n-\n-\tfs-\u003erx_fs = accel_psp;\n \n \treturn 0;\n \n-out_err_counter_err:\n-\tmlx5_fc_destroy(mdev, accel_psp-\u003erx_err_counter);\n-\taccel_psp-\u003erx_err_counter = NULL;\n-out_auth_fail_counter_err:\n-\tmlx5_fc_destroy(mdev, accel_psp-\u003erx_auth_fail_counter);\n-\taccel_psp-\u003erx_auth_fail_counter = NULL;\n-out_counter_err:\n-\tmlx5_fc_destroy(mdev, accel_psp-\u003erx_counter);\n-\taccel_psp-\u003erx_counter = NULL;\n out_err:\n-\tfor (i = 0; i \u003c ACCEL_FS_PSP_NUM_TYPES; i++) {\n-\t\tfs_prot = \u0026accel_psp-\u003efs_prot[i];\n-\t\tmutex_destroy(\u0026fs_prot-\u003eprot_mutex);\n-\t}\n-\tkfree(accel_psp);\n-\tfs-\u003erx_fs = NULL;\n-\n+\taccel_psp_fs_rx_cleanup(fs);\n \treturn err;\n }\n \n void mlx5_accel_psp_fs_cleanup_rx_tables(struct mlx5e_priv *priv)\n {\n-\tint i;\n-\n \tif (!priv-\u003epsp)\n \t\treturn;\n \n-\tfor (i = 0; i \u003c ACCEL_FS_PSP_NUM_TYPES; i++)\n-\t\taccel_psp_fs_rx_ft_put(priv-\u003epsp-\u003efs, i);\n-}\n-\n-int mlx5_accel_psp_fs_init_rx_tables(struct mlx5e_priv *priv)\n-{\n-\tstruct mlx5e_psp_fs *fs;\n-\tint err, i;\n-\n-\tif (!priv-\u003epsp)\n-\t\treturn 0;\n-\n-\tfs = priv-\u003epsp-\u003efs;\n-\tfor (i = 0; i \u003c ACCEL_FS_PSP_NUM_TYPES; i++) {\n-\t\terr = accel_psp_fs_rx_ft_get(fs, i);\n-\t\tif (err)\n-\t\t\tgoto out_err;\n-\t}\n-\n-\treturn 0;\n-\n-out_err:\n-\ti--;\n-\twhile (i \u003e= 0) {\n-\t\taccel_psp_fs_rx_ft_put(fs, i);\n-\t\t--i;\n-\t}\n-\n-\treturn err;\n+\tnetdev_lock(priv-\u003enetdev);\n+\taccel_psp_fs_rx_destroy(priv-\u003epsp-\u003efs);\n+\tnetdev_unlock(priv-\u003enetdev);\n }\n \n-static int accel_psp_fs_tx_create_ft_table(struct mlx5e_psp_fs *fs)\n+static int accel_psp_fs_tx_ft_create(struct mlx5e_psp_fs *fs,\n+\t\t\t\t     struct mlx5e_psp_tx_table *tx)\n {\n \tint inlen = MLX5_ST_SZ_BYTES(create_flow_group_in);\n \tstruct mlx5_flow_table_attr ft_attr = {};\n@@ -681,7 +659,6 @@ static int accel_psp_fs_tx_create_ft_table(struct mlx5e_psp_fs *fs)\n \tu32 *in, *mc, *outer_headers_c;\n \tstruct mlx5_flow_handle *rule;\n \tstruct mlx5_flow_spec *spec;\n-\tstruct mlx5e_psp_tx *tx_fs;\n \tstruct mlx5_flow_table *ft;\n \tstruct mlx5_flow_group *fg;\n \tint err = 0;\n@@ -700,8 +677,7 @@ static int accel_psp_fs_tx_create_ft_table(struct mlx5e_psp_fs *fs)\n \tft_attr.level = MLX5E_PSP_LEVEL;\n \tft_attr.autogroup.max_num_groups = 1;\n \n-\ttx_fs = fs-\u003etx_fs;\n-\tft = mlx5_create_flow_table(tx_fs-\u003ens, \u0026ft_attr);\n+\tft = mlx5_create_flow_table(tx-\u003ens, \u0026ft_attr);\n \tif (IS_ERR(ft)) {\n \t\terr = PTR_ERR(ft);\n \t\tmlx5_core_err(mdev, \"PSP: fail to add psp tx flow table, err = %d\\n\", err);\n@@ -727,7 +703,7 @@ static int accel_psp_fs_tx_create_ft_table(struct mlx5e_psp_fs *fs)\n \t\t\t  MLX5_FLOW_CONTEXT_ACTION_CRYPTO_ENCRYPT |\n \t\t\t  MLX5_FLOW_CONTEXT_ACTION_COUNT;\n \tdest.type = MLX5_FLOW_DESTINATION_TYPE_COUNTER;\n-\tdest.counter = tx_fs-\u003etx_counter;\n+\tdest.counter = fs-\u003etx_counter;\n \trule = mlx5_add_flow_rules(ft, spec, \u0026flow_act, \u0026dest, 1);\n \tif (IS_ERR(rule)) {\n \t\terr = PTR_ERR(rule);\n@@ -735,9 +711,9 @@ static int accel_psp_fs_tx_create_ft_table(struct mlx5e_psp_fs *fs)\n \t\tgoto err_add_flow_rule;\n \t}\n \n-\ttx_fs-\u003eft = ft;\n-\ttx_fs-\u003efg = fg;\n-\ttx_fs-\u003erule = rule;\n+\ttx-\u003eft = ft;\n+\ttx-\u003efg = fg;\n+\ttx-\u003erule = rule;\n \tgoto out;\n \n err_add_flow_rule:\n@@ -750,87 +726,35 @@ static int accel_psp_fs_tx_create_ft_table(struct mlx5e_psp_fs *fs)\n \treturn err;\n }\n \n-static void accel_psp_fs_tx_destroy(struct mlx5e_psp_tx *tx_fs)\n+static void accel_psp_fs_tx_ft_destroy(struct mlx5e_psp_tx_table *tx)\n {\n-\tif (!tx_fs-\u003eft)\n-\t\treturn;\n-\n-\tmlx5_del_flow_rules(tx_fs-\u003erule);\n-\tmlx5_destroy_flow_group(tx_fs-\u003efg);\n-\tmlx5_destroy_flow_table(tx_fs-\u003eft);\n+\taccel_psp_fs_del_flow_rule(\u0026tx-\u003erule);\n+\taccel_psp_fs_destroy_flow_group(\u0026tx-\u003efg);\n+\taccel_psp_fs_destroy_ft(\u0026tx-\u003eft);\n }\n \n-static int accel_psp_fs_tx_ft_get(struct mlx5e_psp_fs *fs)\n+static void accel_psp_fs_tx_cleanup(struct mlx5e_psp_fs *fs)\n {\n-\tstruct mlx5e_psp_tx *tx_fs = fs-\u003etx_fs;\n-\tint err = 0;\n-\n-\tmutex_lock(\u0026tx_fs-\u003emutex);\n-\tif (tx_fs-\u003erefcnt++)\n-\t\tgoto out;\n-\n-\terr = accel_psp_fs_tx_create_ft_table(fs);\n-\tif (err)\n-\t\ttx_fs-\u003erefcnt--;\n-out:\n-\tmutex_unlock(\u0026tx_fs-\u003emutex);\n-\treturn err;\n+\taccel_psp_fs_destroy_counter(fs-\u003emdev, \u0026fs-\u003etx_counter);\n }\n \n-static void accel_psp_fs_tx_ft_put(struct mlx5e_psp_fs *fs)\n-{\n-\tstruct mlx5e_psp_tx *tx_fs = fs-\u003etx_fs;\n-\n-\tmutex_lock(\u0026tx_fs-\u003emutex);\n-\tif (--tx_fs-\u003erefcnt)\n-\t\tgoto out;\n-\n-\taccel_psp_fs_tx_destroy(tx_fs);\n-out:\n-\tmutex_unlock(\u0026tx_fs-\u003emutex);\n-}\n-\n-static void accel_psp_fs_cleanup_tx(struct mlx5e_psp_fs *fs)\n-{\n-\tstruct mlx5e_psp_tx *tx_fs = fs-\u003etx_fs;\n-\n-\tif (!tx_fs)\n-\t\treturn;\n-\n-\tmlx5_fc_destroy(fs-\u003emdev, tx_fs-\u003etx_counter);\n-\tmutex_destroy(\u0026tx_fs-\u003emutex);\n-\tWARN_ON(tx_fs-\u003erefcnt);\n-\tkfree(tx_fs);\n-\tfs-\u003etx_fs = NULL;\n-}\n-\n-static int accel_psp_fs_init_tx(struct mlx5e_psp_fs *fs)\n+static int accel_psp_fs_tx_init(struct mlx5e_psp_fs *fs)\n {\n \tstruct mlx5_core_dev *mdev = fs-\u003emdev;\n-\tstruct mlx5_flow_namespace *ns;\n-\tstruct mlx5_fc *flow_counter;\n-\tstruct mlx5e_psp_tx *tx_fs;\n+\tint err;\n \n-\tns = mlx5_get_flow_namespace(mdev, MLX5_FLOW_NAMESPACE_EGRESS_IPSEC);\n-\tif (!ns)\n+\tfs-\u003etx.ns = mlx5_get_flow_namespace(mdev,\n+\t\t\t\t\t    MLX5_FLOW_NAMESPACE_EGRESS_IPSEC);\n+\tif (!fs-\u003etx.ns)\n \t\treturn -EOPNOTSUPP;\n \n-\ttx_fs = kzalloc_obj(*tx_fs);\n-\tif (!tx_fs)\n-\t\treturn -ENOMEM;\n-\n-\tflow_counter = mlx5_fc_create(mdev, false);\n-\tif (IS_ERR(flow_counter)) {\n+\terr = accel_psp_fs_create_counter(mdev, \u0026fs-\u003etx_counter);\n+\tif (err) {\n \t\tmlx5_core_warn(mdev,\n-\t\t\t       \"fail to create psp tx flow counter err=%pe\\n\",\n-\t\t\t       flow_counter);\n-\t\tkfree(tx_fs);\n-\t\treturn PTR_ERR(flow_counter);\n+\t\t\t       \"fail to create psp tx flow counter err=%d\\n\",\n+\t\t\t       err);\n+\t\treturn err;\n \t}\n-\ttx_fs-\u003etx_counter = flow_counter;\n-\tmutex_init(\u0026tx_fs-\u003emutex);\n-\ttx_fs-\u003ens = ns;\n-\tfs-\u003etx_fs = tx_fs;\n \treturn 0;\n }\n \n@@ -838,32 +762,29 @@ static void\n mlx5e_accel_psp_fs_get_stats_fill(struct mlx5e_priv *priv,\n \t\t\t\t  struct mlx5e_psp_stats *stats)\n {\n-\tstruct mlx5e_psp_tx *tx_fs = priv-\u003epsp-\u003efs-\u003etx_fs;\n+\tstruct mlx5e_psp_fs *fs = priv-\u003epsp-\u003efs;\n \tstruct mlx5_core_dev *mdev = priv-\u003emdev;\n-\tstruct mlx5e_accel_fs_psp *accel_psp;\n-\n-\taccel_psp = (struct mlx5e_accel_fs_psp *)priv-\u003epsp-\u003efs-\u003erx_fs;\n \n-\tif (tx_fs-\u003etx_counter)\n-\t\tmlx5_fc_query(mdev, tx_fs-\u003etx_counter, \u0026stats-\u003epsp_tx_pkts,\n+\tif (fs-\u003etx_counter)\n+\t\tmlx5_fc_query(mdev, fs-\u003etx_counter, \u0026stats-\u003epsp_tx_pkts,\n \t\t\t      \u0026stats-\u003epsp_tx_bytes);\n \n-\tif (accel_psp-\u003erx_counter)\n-\t\tmlx5_fc_query(mdev, accel_psp-\u003erx_counter, \u0026stats-\u003epsp_rx_pkts,\n+\tif (fs-\u003erx_counter)\n+\t\tmlx5_fc_query(mdev, fs-\u003erx_counter, \u0026stats-\u003epsp_rx_pkts,\n \t\t\t      \u0026stats-\u003epsp_rx_bytes);\n \n-\tif (accel_psp-\u003erx_auth_fail_counter)\n-\t\tmlx5_fc_query(mdev, accel_psp-\u003erx_auth_fail_counter,\n+\tif (fs-\u003erx_auth_fail_counter)\n+\t\tmlx5_fc_query(mdev, fs-\u003erx_auth_fail_counter,\n \t\t\t      \u0026stats-\u003epsp_rx_pkts_auth_fail,\n \t\t\t      \u0026stats-\u003epsp_rx_bytes_auth_fail);\n \n-\tif (accel_psp-\u003erx_err_counter)\n-\t\tmlx5_fc_query(mdev, accel_psp-\u003erx_err_counter,\n+\tif (fs-\u003erx_err_counter)\n+\t\tmlx5_fc_query(mdev, fs-\u003erx_err_counter,\n \t\t\t      \u0026stats-\u003epsp_rx_pkts_frame_err,\n \t\t\t      \u0026stats-\u003epsp_rx_bytes_frame_err);\n \n-\tif (accel_psp-\u003erx_bad_counter)\n-\t\tmlx5_fc_query(mdev, accel_psp-\u003erx_bad_counter,\n+\tif (fs-\u003erx_bad_counter)\n+\t\tmlx5_fc_query(mdev, fs-\u003erx_bad_counter,\n \t\t\t      \u0026stats-\u003epsp_rx_pkts_drop,\n \t\t\t      \u0026stats-\u003epsp_rx_bytes_drop);\n }\n@@ -873,21 +794,15 @@ void mlx5_accel_psp_fs_cleanup_tx_tables(struct mlx5e_priv *priv)\n \tif (!priv-\u003epsp)\n \t\treturn;\n \n-\taccel_psp_fs_tx_ft_put(priv-\u003epsp-\u003efs);\n-}\n-\n-int mlx5_accel_psp_fs_init_tx_tables(struct mlx5e_priv *priv)\n-{\n-\tif (!priv-\u003epsp)\n-\t\treturn 0;\n-\n-\treturn accel_psp_fs_tx_ft_get(priv-\u003epsp-\u003efs);\n+\tnetdev_lock(priv-\u003enetdev);\n+\taccel_psp_fs_tx_ft_destroy(\u0026priv-\u003epsp-\u003efs-\u003etx);\n+\tnetdev_unlock(priv-\u003enetdev);\n }\n \n static void mlx5e_accel_psp_fs_cleanup(struct mlx5e_psp_fs *fs)\n {\n-\taccel_psp_fs_cleanup_rx(fs);\n-\taccel_psp_fs_cleanup_tx(fs);\n+\taccel_psp_fs_rx_cleanup(fs);\n+\taccel_psp_fs_tx_cleanup(fs);\n \tkfree(fs);\n }\n \n@@ -901,29 +816,63 @@ static struct mlx5e_psp_fs *mlx5e_accel_psp_fs_init(struct mlx5e_priv *priv)\n \t\treturn ERR_PTR(-ENOMEM);\n \n \tfs-\u003emdev = priv-\u003emdev;\n-\terr = accel_psp_fs_init_tx(fs);\n+\terr = accel_psp_fs_tx_init(fs);\n \tif (err)\n \t\tgoto err_tx;\n \n \tfs-\u003efs = priv-\u003efs;\n-\terr = accel_psp_fs_init_rx(fs);\n+\terr = accel_psp_fs_rx_init(fs);\n \tif (err)\n \t\tgoto err_rx;\n \n \treturn fs;\n \n err_rx:\n-\taccel_psp_fs_cleanup_tx(fs);\n+\taccel_psp_fs_tx_cleanup(fs);\n err_tx:\n \tkfree(fs);\n \treturn ERR_PTR(err);\n }\n \n+static int accel_psp_fs_create(struct mlx5e_priv *priv,\n+\t\t\t       struct netlink_ext_ack *extack)\n+{\n+\tint err;\n+\n+\terr = accel_psp_fs_rx_create(priv-\u003epsp-\u003efs, extack);\n+\tif (err)\n+\t\treturn err;\n+\n+\terr = accel_psp_fs_tx_ft_create(priv-\u003epsp-\u003efs, \u0026priv-\u003epsp-\u003efs-\u003etx);\n+\tif (err) {\n+\t\tNL_SET_ERR_MSG(extack, \"Failed creating TX steering table\");\n+\t\taccel_psp_fs_rx_destroy(priv-\u003epsp-\u003efs);\n+\t}\n+\treturn err;\n+}\n+\n+static void accel_psp_fs_destroy(struct mlx5e_priv *priv)\n+{\n+\taccel_psp_fs_tx_ft_destroy(\u0026priv-\u003epsp-\u003efs-\u003etx);\n+\taccel_psp_fs_rx_destroy(priv-\u003epsp-\u003efs);\n+}\n+\n static int\n mlx5e_psp_set_config(struct psp_dev *psd, struct psp_dev_config *conf,\n \t\t     struct netlink_ext_ack *extack)\n {\n-\treturn 0; /* TODO: this should actually do things to the device */\n+\tstruct mlx5e_priv *priv = netdev_priv(psd-\u003emain_netdev);\n+\tbool psp_enabled = psd-\u003econfig.versions;\n+\tbool enable_psp = conf-\u003eversions;\n+\tint err = 0;\n+\n+\tnetdev_lock(priv-\u003enetdev);\n+\tif (!psp_enabled \u0026\u0026 enable_psp)\n+\t\terr = accel_psp_fs_create(priv, extack);\n+\telse if (psp_enabled \u0026\u0026 !enable_psp)\n+\t\taccel_psp_fs_destroy(priv);\n+\tnetdev_unlock(priv-\u003enetdev);\n+\treturn err;\n }\n \n static int\n@@ -1072,21 +1021,21 @@ void mlx5e_psp_unregister(struct mlx5e_priv *priv)\n {\n \tstruct mlx5e_psp *psp = priv-\u003epsp;\n \n-\tif (!psp || !psp-\u003epsp)\n+\tif (!psp || !psp-\u003epsd)\n \t\treturn;\n \n-\tpsp_dev_unregister(psp-\u003epsp);\n-\tpsp-\u003epsp = NULL;\n+\tpsp_dev_unregister(psp-\u003epsd);\n+\tpsp-\u003epsd = NULL;\n }\n \n-void mlx5e_psp_register(struct mlx5e_priv *priv)\n+int mlx5e_psp_register(struct mlx5e_priv *priv)\n {\n \tstruct mlx5e_psp *psp = priv-\u003epsp;\n \tstruct psp_dev *psd;\n \n \t/* FW Caps missing */\n \tif (!priv-\u003epsp)\n-\t\treturn;\n+\t\treturn 0;\n \n \tpsp-\u003ecaps.assoc_drv_spc = sizeof(u32);\n \tpsp-\u003ecaps.versions = 1 \u003c\u003c PSP_VERSION_HDR0_AES_GCM_128;\n@@ -1098,9 +1047,11 @@ void mlx5e_psp_register(struct mlx5e_priv *priv)\n \tif (IS_ERR(psd)) {\n \t\tmlx5_core_err(priv-\u003emdev, \"PSP failed to register due to %pe\\n\",\n \t\t\t      psd);\n-\t\treturn;\n+\t\treturn PTR_ERR(psd);\n \t}\n-\tpsp-\u003epsp = psd;\n+\tpsp-\u003epsd = psd;\n+\n+\treturn 0;\n }\n \n int mlx5e_psp_init(struct mlx5e_priv *priv)\ndiff --git a/drivers/net/ethernet/mellanox/mlx5/core/en_accel/psp.h b/drivers/net/ethernet/mellanox/mlx5/core/en_accel/psp.h\nindex 6b62fef0d9a738..3f441e7dd55ac0 100644\n--- a/drivers/net/ethernet/mellanox/mlx5/core/en_accel/psp.h\n+++ b/drivers/net/ethernet/mellanox/mlx5/core/en_accel/psp.h\n@@ -23,7 +23,7 @@ struct mlx5e_psp_stats {\n };\n \n struct mlx5e_psp {\n-\tstruct psp_dev *psp;\n+\tstruct psp_dev *psd;\n \tstruct psp_dev_caps caps;\n \tstruct mlx5e_psp_fs *fs;\n \tatomic_t tx_key_cnt;\n@@ -43,33 +43,21 @@ static inline bool mlx5_is_psp_device(struct mlx5_core_dev *mdev)\n \treturn true;\n }\n \n-int mlx5_accel_psp_fs_init_rx_tables(struct mlx5e_priv *priv);\n void mlx5_accel_psp_fs_cleanup_rx_tables(struct mlx5e_priv *priv);\n-int mlx5_accel_psp_fs_init_tx_tables(struct mlx5e_priv *priv);\n void mlx5_accel_psp_fs_cleanup_tx_tables(struct mlx5e_priv *priv);\n-void mlx5e_psp_register(struct mlx5e_priv *priv);\n+int mlx5e_psp_register(struct mlx5e_priv *priv);\n void mlx5e_psp_unregister(struct mlx5e_priv *priv);\n int mlx5e_psp_init(struct mlx5e_priv *priv);\n void mlx5e_psp_cleanup(struct mlx5e_priv *priv);\n #else\n-static inline int mlx5_accel_psp_fs_init_rx_tables(struct mlx5e_priv *priv)\n-{\n-\treturn 0;\n-}\n-\n static inline void mlx5_accel_psp_fs_cleanup_rx_tables(struct mlx5e_priv *priv) { }\n-static inline int mlx5_accel_psp_fs_init_tx_tables(struct mlx5e_priv *priv)\n-{\n-\treturn 0;\n-}\n-\n static inline void mlx5_accel_psp_fs_cleanup_tx_tables(struct mlx5e_priv *priv) { }\n static inline bool mlx5_is_psp_device(struct mlx5_core_dev *mdev)\n {\n \treturn false;\n }\n \n-static inline void mlx5e_psp_register(struct mlx5e_priv *priv) { }\n+static inline int mlx5e_psp_register(struct mlx5e_priv *priv) { return 0; }\n static inline void mlx5e_psp_unregister(struct mlx5e_priv *priv) { }\n static inline int mlx5e_psp_init(struct mlx5e_priv *priv) { return 0; }\n static inline void mlx5e_psp_cleanup(struct mlx5e_priv *priv) { }\ndiff --git a/drivers/net/ethernet/mellanox/mlx5/core/en_accel/psp_rxtx.c b/drivers/net/ethernet/mellanox/mlx5/core/en_accel/psp_rxtx.c\nindex ef7f5338540fdf..348fd7a962615a 100644\n--- a/drivers/net/ethernet/mellanox/mlx5/core/en_accel/psp_rxtx.c\n+++ b/drivers/net/ethernet/mellanox/mlx5/core/en_accel/psp_rxtx.c\n@@ -14,12 +14,6 @@\n #include \"en_accel/psp_rxtx.h\"\n #include \"en_accel/psp.h\"\n \n-enum {\n-\tMLX5E_PSP_OFFLOAD_RX_SYNDROME_DECRYPTED,\n-\tMLX5E_PSP_OFFLOAD_RX_SYNDROME_AUTH_FAILED,\n-\tMLX5E_PSP_OFFLOAD_RX_SYNDROME_BAD_TRAILER,\n-};\n-\n static void mlx5e_psp_set_swp(struct sk_buff *skb,\n \t\t\t      struct mlx5e_accel_tx_psp_state *psp_st,\n \t\t\t      struct mlx5_wqe_eth_seg *eseg)\n@@ -122,16 +116,11 @@ static bool mlx5e_psp_set_state(struct mlx5e_priv *priv,\n bool mlx5e_psp_offload_handle_rx_skb(struct net_device *netdev, struct sk_buff *skb,\n \t\t\t\t     struct mlx5_cqe64 *cqe)\n {\n-\tu32 psp_meta_data = be32_to_cpu(cqe-\u003eft_metadata);\n \tstruct mlx5e_priv *priv = netdev_priv(netdev);\n-\tu16 dev_id = priv-\u003epsp-\u003epsp-\u003eid;\n+\tu16 dev_id = priv-\u003epsp-\u003epsd-\u003eid;\n \tbool strip_icv = true;\n \tu8 generation = 0;\n \n-\t/* TBD: report errors as SW counters to ethtool, any further handling ? */\n-\tif (MLX5_PSP_METADATA_SYNDROME(psp_meta_data) != MLX5E_PSP_OFFLOAD_RX_SYNDROME_DECRYPTED)\n-\t\tgoto drop;\n-\n \tif (psp_dev_rcv(skb, dev_id, generation, strip_icv))\n \t\tgoto drop;\n \ndiff --git a/drivers/net/ethernet/mellanox/mlx5/core/en_accel/psp_rxtx.h b/drivers/net/ethernet/mellanox/mlx5/core/en_accel/psp_rxtx.h\nindex 70289c921bd6b3..2b080c39cc37ed 100644\n--- a/drivers/net/ethernet/mellanox/mlx5/core/en_accel/psp_rxtx.h\n+++ b/drivers/net/ethernet/mellanox/mlx5/core/en_accel/psp_rxtx.h\n@@ -10,9 +10,8 @@\n #include \"en.h\"\n #include \"en/txrx.h\"\n \n-/* Bit30: PSP marker, Bit29-23: PSP syndrome, Bit22-0: PSP obj id */\n+/* Bit30: PSP marker, Bit22-0: PSP obj id */\n #define MLX5_PSP_METADATA_MARKER(metadata)  ((((metadata) \u003e\u003e 30) \u0026 0x3) == 0x3)\n-#define MLX5_PSP_METADATA_SYNDROME(metadata) (((metadata) \u003e\u003e 23) \u0026 GENMASK(6, 0))\n #define MLX5_PSP_METADATA_HANDLE(metadata)  ((metadata) \u0026 GENMASK(22, 0))\n \n struct mlx5e_accel_tx_psp_state {\ndiff --git a/drivers/net/ethernet/mellanox/mlx5/core/en_main.c b/drivers/net/ethernet/mellanox/mlx5/core/en_main.c\nindex 775f0c6e55c955..2cb48b24d5eac5 100644\n--- a/drivers/net/ethernet/mellanox/mlx5/core/en_main.c\n+++ b/drivers/net/ethernet/mellanox/mlx5/core/en_main.c\n@@ -6191,7 +6191,7 @@ static int mlx5e_init_nic_tx(struct mlx5e_priv *priv)\n \treturn 0;\n }\n \n-static void mlx5e_nic_enable(struct mlx5e_priv *priv)\n+static int mlx5e_nic_enable(struct mlx5e_priv *priv)\n {\n \tstruct net_device *netdev = priv-\u003enetdev;\n \tstruct mlx5_core_dev *mdev = priv-\u003emdev;\n@@ -6199,7 +6199,9 @@ static void mlx5e_nic_enable(struct mlx5e_priv *priv)\n \n \tmlx5e_fs_init_l2_addr(priv-\u003efs, netdev);\n \tmlx5e_ipsec_init(priv);\n-\tmlx5e_psp_register(priv);\n+\terr = mlx5e_psp_register(priv);\n+\tif (err)\n+\t\tgoto out_ipsec_cleanup;\n \n \terr = mlx5e_macsec_init(priv);\n \tif (err)\n@@ -6222,7 +6224,7 @@ static void mlx5e_nic_enable(struct mlx5e_priv *priv)\n \tmlx5e_pcie_cong_event_init(priv);\n \tmlx5e_hv_vhca_stats_create(priv);\n \tif (netdev-\u003ereg_state != NETREG_REGISTERED)\n-\t\treturn;\n+\t\treturn 0;\n \tmlx5e_dcbnl_init_app(priv);\n \n \tmlx5e_nic_set_rx_mode(priv);\n@@ -6235,6 +6237,12 @@ static void mlx5e_nic_enable(struct mlx5e_priv *priv)\n \tnetdev_unlock(netdev);\n \tnetif_device_attach(netdev);\n \trtnl_unlock();\n+\n+\treturn 0;\n+\n+out_ipsec_cleanup:\n+\tmlx5e_ipsec_cleanup(priv);\n+\treturn err;\n }\n \n static void mlx5e_nic_disable(struct mlx5e_priv *priv)\n@@ -6616,13 +6624,18 @@ int mlx5e_attach_netdev(struct mlx5e_priv *priv)\n \tif (err)\n \t\tgoto err_cleanup_tx;\n \n-\tif (profile-\u003eenable)\n-\t\tprofile-\u003eenable(priv);\n+\tif (profile-\u003eenable) {\n+\t\terr = profile-\u003eenable(priv);\n+\t\tif (err)\n+\t\t\tgoto err_cleanup_rx;\n+\t}\n \n \tmlx5e_update_features(priv-\u003enetdev);\n \n \treturn 0;\n \n+err_cleanup_rx:\n+\tprofile-\u003ecleanup_rx(priv);\n err_cleanup_tx:\n \tprofile-\u003ecleanup_tx(priv);\n \ndiff --git a/drivers/net/ethernet/mellanox/mlx5/core/en_rep.c b/drivers/net/ethernet/mellanox/mlx5/core/en_rep.c\nindex c8b76d301c92cf..603051ab1eaa4f 100644\n--- a/drivers/net/ethernet/mellanox/mlx5/core/en_rep.c\n+++ b/drivers/net/ethernet/mellanox/mlx5/core/en_rep.c\n@@ -1262,9 +1262,11 @@ static void mlx5e_cleanup_rep_tx(struct mlx5e_priv *priv)\n \tmlx5e_rep_neigh_cleanup(rpriv);\n }\n \n-static void mlx5e_rep_enable(struct mlx5e_priv *priv)\n+static int mlx5e_rep_enable(struct mlx5e_priv *priv)\n {\n \tmlx5e_set_netdev_mtu_boundaries(priv);\n+\n+\treturn 0;\n }\n \n static void mlx5e_rep_disable(struct mlx5e_priv *priv)\n@@ -1322,7 +1324,7 @@ static int uplink_rep_async_event(struct notifier_block *nb, unsigned long event\n \treturn NOTIFY_DONE;\n }\n \n-static void mlx5e_uplink_rep_enable(struct mlx5e_priv *priv)\n+static int mlx5e_uplink_rep_enable(struct mlx5e_priv *priv)\n {\n \tstruct net_device *netdev = priv-\u003enetdev;\n \tstruct mlx5_core_dev *mdev = priv-\u003emdev;\n@@ -1357,6 +1359,8 @@ static void mlx5e_uplink_rep_enable(struct mlx5e_priv *priv)\n \tnetdev_unlock(netdev);\n \tnetif_device_attach(netdev);\n \trtnl_unlock();\n+\n+\treturn 0;\n }\n \n static void mlx5e_uplink_rep_disable(struct mlx5e_priv *priv)\n"
}

2/1 2026/07/07 21:40 agent patch-evaluator
0m Model:
gemini-3.1-pro-preview

Args:
null

Results:
{
  "EnableConfigs": null,
  "FocusSymbols": [],
  "Reasoning": "The patch only modifies the Mellanox mlx5 hardware driver (specifically the PSP offload feature). Since this driver requires physical Mellanox ConnectX hardware and is not emulated in virtualized environments like QEMU or GCE, the code paths are unreachable during fuzzing.",
  "WorthFuzzing": false
}

Instruction:
You are an expert Linux kernel maintainer.
Your job is to review a provided patch series and determine
if it makes functional changes to the kernel that should be fuzzed.

IMPORTANT: The changes have ALREADY been applied and committed as the HEAD commit in
your workspace. Do NOT rely on your internal knowledge of the kernel. You must actively
use your code access tools to examine the actual source code and confirm any assumptions.

Return WorthFuzzing=false if the patch only contains:
- Modifications to Documentation/, Kconfig files, or code comments.
- Purely decorative changes, such as logging (e.g., pr_err, printk) or tracepoints.
- Changes to numeric constants or macros that do not functionally alter execution flow.
- Code paths that are impossible to reach in virtualized environments like GCE or QEMU,
even when utilizing software-emulated hardware (e.g., usb gadget, mac80211_hwsim).

If it modifies reachable core kernel logic, drivers, or architectures, use your code search
tools to verify the code can be executed, then return WorthFuzzing=true.

When returning WorthFuzzing=true, you MUST ALSO:
1. Extract any specific kernel functions that should be heavily fuzzed into FocusSymbols.
   Avoid listing generic hot-path functions to prevent skewed test distributions.
2. Identify any specific CONFIG_ options required to properly test this new/modified feature.
   Go and look into the Kconfig files and check for ifdefs around the code, do not make assumptions.
   Do not list too generic configs (we already have them enabled). Only list those that
   specifically cover the modified code. List them in the EnableConfigs output array,
   and DO NOT add a 'CONFIG_' prefix (e.g., return "NET_IPV4" instead of "CONFIG_NET_IPV4").
Prefer calling several tools at the same time to save round-trips.


Use set-results tool to provide results of the analysis.
It must be called exactly once before the final reply.
Ignore results of this tool.

Prompt:
For your convenience, here is the diff of the changes:
commit e792dd051b035d14bfdb55b8db64623fc84b8bb8
Author: syz-cluster <triage@syzkaller.com>
Date:   Tue Jul 7 21:40:52 2026 +0000

    syz-cluster: applied patch under review

diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en.h b/drivers/net/ethernet/mellanox/mlx5/core/en.h
index 2270e2e550dd9e..3cc7283b6215e1 100644
--- a/drivers/net/ethernet/mellanox/mlx5/core/en.h
+++ b/drivers/net/ethernet/mellanox/mlx5/core/en.h
@@ -1016,7 +1016,7 @@ struct mlx5e_profile {
 	void	(*cleanup_rx)(struct mlx5e_priv *priv);
 	int	(*init_tx)(struct mlx5e_priv *priv);
 	void	(*cleanup_tx)(struct mlx5e_priv *priv);
-	void	(*enable)(struct mlx5e_priv *priv);
+	int	(*enable)(struct mlx5e_priv *priv);
 	void	(*disable)(struct mlx5e_priv *priv);
 	int	(*update_rx)(struct mlx5e_priv *priv);
 	void	(*update_stats)(struct mlx5e_priv *priv);
diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en/fs.h b/drivers/net/ethernet/mellanox/mlx5/core/en/fs.h
index 091b80a67189dd..4973fb473ff020 100644
--- a/drivers/net/ethernet/mellanox/mlx5/core/en/fs.h
+++ b/drivers/net/ethernet/mellanox/mlx5/core/en/fs.h
@@ -88,13 +88,18 @@ enum {
 #ifdef CONFIG_MLX5_EN_ARFS
 	MLX5E_ARFS_FT_LEVEL = MLX5E_INNER_TTC_FT_LEVEL + 1,
 #endif
-#if defined(CONFIG_MLX5_EN_IPSEC) || defined(CONFIG_MLX5_EN_PSP)
+#if defined(CONFIG_MLX5_EN_IPSEC)
 	MLX5E_ACCEL_FS_ESP_FT_LEVEL = MLX5E_INNER_TTC_FT_LEVEL + 1,
 	MLX5E_ACCEL_FS_ESP_FT_ERR_LEVEL,
 	MLX5E_ACCEL_FS_POL_FT_LEVEL,
 	MLX5E_ACCEL_FS_POL_MISS_FT_LEVEL,
 	MLX5E_ACCEL_FS_ESP_FT_ROCE_LEVEL,
 #endif
+#if defined(CONFIG_MLX5_EN_PSP)
+	MLX5E_ACCEL_FS_PSP_FT_LEVEL = MLX5E_INNER_TTC_FT_LEVEL + 1,
+	MLX5E_ACCEL_FS_PSP_ERR_FT_LEVEL,
+	MLX5E_ACCEL_FS_PSP_RX_FT_LEVEL,
+#endif
 };
 
 struct mlx5e_flow_steering;
diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en_accel/en_accel.h b/drivers/net/ethernet/mellanox/mlx5/core/en_accel/en_accel.h
index b526b3898c22e0..3f212e46fc2f9e 100644
--- a/drivers/net/ethernet/mellanox/mlx5/core/en_accel/en_accel.h
+++ b/drivers/net/ethernet/mellanox/mlx5/core/en_accel/en_accel.h
@@ -220,18 +220,7 @@ static inline void mlx5e_accel_tx_finish(struct mlx5e_txqsq *sq,
 
 static inline int mlx5e_accel_init_rx(struct mlx5e_priv *priv)
 {
-	int err;
-
-	err = mlx5_accel_psp_fs_init_rx_tables(priv);
-	if (err)
-		goto out;
-
-	err = mlx5e_ktls_init_rx(priv);
-	if (err)
-		mlx5_accel_psp_fs_cleanup_rx_tables(priv);
-
-out:
-	return err;
+	return mlx5e_ktls_init_rx(priv);
 }
 
 static inline void mlx5e_accel_cleanup_rx(struct mlx5e_priv *priv)
@@ -242,12 +231,6 @@ static inline void mlx5e_accel_cleanup_rx(struct mlx5e_priv *priv)
 
 static inline int mlx5e_accel_init_tx(struct mlx5e_priv *priv)
 {
-	int err;
-
-	err = mlx5_accel_psp_fs_init_tx_tables(priv);
-	if (err)
-		return err;
-
 	return mlx5e_ktls_init_tx(priv);
 }
 
diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en_accel/psp.c b/drivers/net/ethernet/mellanox/mlx5/core/en_accel/psp.c
index d9adb993e64d95..73b232379263aa 100644
--- a/drivers/net/ethernet/mellanox/mlx5/core/en_accel/psp.c
+++ b/drivers/net/ethernet/mellanox/mlx5/core/en_accel/psp.c
@@ -21,51 +21,52 @@ enum accel_psp_syndrome {
 	PSP_BAD_TRAILER,
 };
 
-struct mlx5e_psp_tx {
+struct mlx5e_psp_tx_table {
 	struct mlx5_flow_namespace *ns;
 	struct mlx5_flow_table *ft;
 	struct mlx5_flow_group *fg;
 	struct mlx5_flow_handle *rule;
-	struct mutex mutex; /* Protect PSP TX steering */
-	u32 refcnt;
-	struct mlx5_fc *tx_counter;
 };
 
-struct mlx5e_psp_rx_err {
+struct mlx5e_psp_rx_check_table {
 	struct mlx5_flow_table *ft;
+	struct mlx5_flow_group *drop_group;
 	struct mlx5_flow_handle *rule;
 	struct mlx5_flow_handle *auth_fail_rule;
 	struct mlx5_flow_handle *err_rule;
 	struct mlx5_flow_handle *bad_rule;
-	struct mlx5_modify_hdr *copy_modify_hdr;
 };
 
-struct mlx5e_accel_fs_psp_prot {
+struct mlx5e_psp_rx_decrypt_table {
 	struct mlx5_flow_table *ft;
 	struct mlx5_flow_group *miss_group;
 	struct mlx5_flow_handle *miss_rule;
 	struct mlx5_modify_hdr *rx_modify_hdr;
-	struct mlx5_flow_destination default_dest;
-	struct mlx5e_psp_rx_err rx_err;
-	u32 refcnt;
-	struct mutex prot_mutex; /* protect ESP4/ESP6 protocol */
-	struct mlx5_flow_handle *def_rule;
+	struct mlx5_flow_handle *rule;
 };
 
-struct mlx5e_accel_fs_psp {
-	struct mlx5e_accel_fs_psp_prot fs_prot[ACCEL_FS_PSP_NUM_TYPES];
-	struct mlx5_fc *rx_counter;
-	struct mlx5_fc *rx_auth_fail_counter;
-	struct mlx5_fc *rx_err_counter;
-	struct mlx5_fc *rx_bad_counter;
+struct mlx5e_psp_rx_table {
+	struct mlx5_flow_table *ft;
+	struct mlx5_flow_group *miss_group;
+	struct mlx5_flow_handle *miss_rule;
+	struct mlx5_flow_handle *udp_rules[ACCEL_FS_PSP_NUM_TYPES];
 };
 
 struct mlx5e_psp_fs {
 	struct mlx5_core_dev *mdev;
-	struct mlx5e_psp_tx *tx_fs;
-	/* Rx manage */
+	struct mlx5_fc *tx_counter;
+	struct mlx5e_psp_tx_table tx;
+
+	/* Rx */
 	struct mlx5e_flow_steering *fs;
-	struct mlx5e_accel_fs_psp *rx_fs;
+	struct mlx5_fc *rx_counter;
+	struct mlx5_fc *rx_auth_fail_counter;
+	struct mlx5_fc *rx_err_counter;
+	struct mlx5_fc *rx_bad_counter;
+
+	struct mlx5e_psp_rx_decrypt_table decrypt[ACCEL_FS_PSP_NUM_TYPES];
+	struct mlx5e_psp_rx_check_table check;
+	struct mlx5e_psp_rx_table rx;
 };
 
 /* PSP RX flow steering */
@@ -77,44 +78,200 @@ static enum mlx5_traffic_types fs_psp2tt(enum accel_fs_psp_type i)
 	return MLX5_TT_IPV6_UDP;
 }
 
-static void accel_psp_fs_rx_err_del_rules(struct mlx5e_psp_fs *fs,
-					  struct mlx5e_psp_rx_err *rx_err)
+static int accel_psp_fs_create_ft(struct mlx5e_psp_fs *fs,
+				  struct mlx5_flow_table_attr *ft_attr,
+				  struct mlx5_flow_table **ft)
+{
+	struct mlx5_flow_namespace *ns = mlx5e_fs_get_ns(fs->fs, false);
+	int err = 0;
+
+	*ft = mlx5_create_auto_grouped_flow_table(ns, ft_attr);
+	if (IS_ERR(*ft)) {
+		err = PTR_ERR(*ft);
+		*ft = NULL;
+	}
+
+	return err;
+}
+
+static void accel_psp_fs_destroy_ft(struct mlx5_flow_table **table)
 {
-	if (rx_err->bad_rule) {
-		mlx5_del_flow_rules(rx_err->bad_rule);
-		rx_err->bad_rule = NULL;
+	if (*table) {
+		mlx5_destroy_flow_table(*table);
+		*table = NULL;
 	}
+}
 
-	if (rx_err->err_rule) {
-		mlx5_del_flow_rules(rx_err->err_rule);
-		rx_err->err_rule = NULL;
+static void accel_psp_fs_del_flow_rule(struct mlx5_flow_handle **rule)
+{
+	if (*rule) {
+		mlx5_del_flow_rules(*rule);
+		*rule = NULL;
 	}
+}
+
+static int accel_psp_fs_create_miss_group(struct mlx5_flow_table *ft,
+					  struct mlx5_flow_group **group)
+{
+	int inlen = MLX5_ST_SZ_BYTES(create_flow_group_in);
+	u32 *in = kvzalloc(inlen, GFP_KERNEL);
+	int err = 0;
 
-	if (rx_err->auth_fail_rule) {
-		mlx5_del_flow_rules(rx_err->auth_fail_rule);
-		rx_err->auth_fail_rule = NULL;
+	if (!in)
+		return -ENOMEM;
+
+	MLX5_SET(create_flow_group_in, in, start_flow_index, ft->max_fte - 1);
+	MLX5_SET(create_flow_group_in, in, end_flow_index, ft->max_fte - 1);
+	*group = mlx5_create_flow_group(ft, in);
+	if (IS_ERR(*group)) {
+		err = PTR_ERR(*group);
+		*group = NULL;
 	}
+	kvfree(in);
 
-	if (rx_err->rule) {
-		mlx5_del_flow_rules(rx_err->rule);
-		rx_err->rule = NULL;
+	return err;
+}
+
+static void accel_psp_fs_destroy_flow_group(struct mlx5_flow_group **group)
+{
+	if (*group) {
+		mlx5_destroy_flow_group(*group);
+		*group = NULL;
 	}
+}
+
+static int accel_psp_fs_create_counter(struct mlx5_core_dev *dev,
+				       struct mlx5_fc **counter)
+{
+	*counter = mlx5_fc_create(dev, false);
+	if (IS_ERR(*counter)) {
+		int err = PTR_ERR(*counter);
+
+		*counter = NULL;
+		return err;
+	}
+
+	return 0;
+}
 
-	if (rx_err->copy_modify_hdr) {
-		mlx5_modify_header_dealloc(fs->mdev, rx_err->copy_modify_hdr);
-		rx_err->copy_modify_hdr = NULL;
+static void accel_psp_fs_destroy_counter(struct mlx5_core_dev *dev,
+					 struct mlx5_fc **counter)
+{
+	if (*counter) {
+		mlx5_fc_destroy(dev, *counter);
+		*counter = NULL;
 	}
 }
 
-static void accel_psp_fs_rx_err_destroy_ft(struct mlx5e_psp_fs *fs,
-					   struct mlx5e_psp_rx_err *rx_err)
+static void accel_psp_fs_rx_ft_destroy(struct mlx5e_psp_rx_table *rx)
+{
+	int i;
+
+	for (i = 0; i < ACCEL_FS_PSP_NUM_TYPES; i++)
+		accel_psp_fs_del_flow_rule(&rx->udp_rules[i]);
+	accel_psp_fs_del_flow_rule(&rx->miss_rule);
+	accel_psp_fs_destroy_flow_group(&rx->miss_group);
+	accel_psp_fs_destroy_ft(&rx->ft);
+}
+
+static int accel_psp_fs_rx_ft_create(struct mlx5e_psp_fs *fs,
+				     struct mlx5e_psp_rx_table *rx)
 {
-	accel_psp_fs_rx_err_del_rules(fs, rx_err);
+	struct mlx5_ttc_table *ttc = mlx5e_fs_get_ttc(fs->fs, false);
+	struct mlx5_flow_destination dest[2] = {};
+	struct mlx5_flow_table_attr ft_attr = {};
+	struct mlx5_core_dev *mdev = fs->mdev;
+	MLX5_DECLARE_FLOW_ACT(flow_act);
+	struct mlx5_flow_handle *rule;
+	struct mlx5_flow_spec *spec;
+	int i, err = 0;
+
+	spec = kzalloc_obj(*spec);
+	if (!spec)
+		return -ENOMEM;
+
+	ft_attr.max_fte = 1 + ACCEL_FS_PSP_NUM_TYPES;
+	ft_attr.level = MLX5E_ACCEL_FS_PSP_RX_FT_LEVEL;
+	ft_attr.prio = MLX5E_NIC_PRIO;
+	ft_attr.autogroup.num_reserved_entries = 1;
+	err = accel_psp_fs_create_ft(fs, &ft_attr, &rx->ft);
+	if (err) {
+		mlx5_core_err(mdev, "fail to create psp rx ft err=%d\n", err);
+		goto out_err;
+	}
 
-	if (rx_err->ft) {
-		mlx5_destroy_flow_table(rx_err->ft);
-		rx_err->ft = NULL;
+	err = accel_psp_fs_create_miss_group(rx->ft, &rx->miss_group);
+	if (err) {
+		mlx5_core_err(mdev, "fail to create psp rx miss_group err=%d\n",
+			      err);
+		goto out_err;
 	}
+
+	/* Add miss rule */
+	flow_act.action = MLX5_FLOW_CONTEXT_ACTION_FWD_DEST |
+		MLX5_FLOW_CONTEXT_ACTION_COUNT;
+	flow_act.flags = FLOW_ACT_IGNORE_FLOW_LEVEL;
+	dest[0].type = MLX5_FLOW_DESTINATION_TYPE_FLOW_TABLE;
+	dest[0].ft = mlx5_get_ttc_flow_table(ttc);
+	dest[1].type = MLX5_FLOW_DESTINATION_TYPE_COUNTER;
+	dest[1].counter = fs->rx_counter;
+	rule = mlx5_add_flow_rules(rx->ft, NULL, &flow_act, dest, 2);
+	if (IS_ERR(rule)) {
+		err = PTR_ERR(rule);
+		mlx5_core_err(mdev, "fail to create psp rx rule, err=%d\n",
+			      err);
+		goto out_err;
+	}
+	rx->miss_rule = rule;
+
+	/* Add UDP v4/v6 rules */
+	spec->match_criteria_enable = MLX5_MATCH_OUTER_HEADERS;
+	MLX5_SET_TO_ONES(fte_match_param, spec->match_criteria,
+			 outer_headers.ip_version);
+	MLX5_SET_TO_ONES(fte_match_set_lyr_2_4, spec->match_criteria,
+			 ip_protocol);
+	MLX5_SET(fte_match_set_lyr_2_4, spec->match_value, ip_protocol,
+		 IPPROTO_UDP);
+	flow_act.action = MLX5_FLOW_CONTEXT_ACTION_FWD_DEST |
+		MLX5_FLOW_CONTEXT_ACTION_COUNT;
+	flow_act.flags = 0;
+	for (i = 0; i < ACCEL_FS_PSP_NUM_TYPES; i++) {
+		int version = i == ACCEL_FS_PSP4 ? 4 : 6;
+
+		MLX5_SET(fte_match_param, spec->match_value,
+			 outer_headers.ip_version, version);
+		dest[0] = mlx5_ttc_get_default_dest(ttc, fs_psp2tt(i));
+		dest[1].type = MLX5_FLOW_DESTINATION_TYPE_COUNTER;
+		dest[1].counter = fs->rx_counter;
+		rule = mlx5_add_flow_rules(rx->ft, spec, &flow_act, dest,
+					   2);
+		if (IS_ERR(rule)) {
+			err = PTR_ERR(rule);
+			mlx5_core_err(mdev,
+				      "fail to create psp rx UDP%d rule err=%d\n",
+				      version, err);
+			goto out_err;
+		}
+		rx->udp_rules[i] = rule;
+	}
+	goto out_spec;
+
+out_err:
+	accel_psp_fs_rx_ft_destroy(rx);
+out_spec:
+	kvfree(spec);
+	return err;
+}
+
+static
+void accel_psp_fs_rx_check_ft_destroy(struct mlx5e_psp_rx_check_table *check)
+{
+	accel_psp_fs_del_flow_rule(&check->bad_rule);
+	accel_psp_fs_del_flow_rule(&check->err_rule);
+	accel_psp_fs_del_flow_rule(&check->auth_fail_rule);
+	accel_psp_fs_del_flow_rule(&check->rule);
+	accel_psp_fs_destroy_flow_group(&check->drop_group);
+	accel_psp_fs_destroy_ft(&check->ft);
 }
 
 static void accel_psp_setup_syndrome_match(struct mlx5_flow_spec *spec,
@@ -129,15 +286,35 @@ static void accel_psp_setup_syndrome_match(struct mlx5_flow_spec *spec,
 	MLX5_SET(fte_match_set_misc2, misc_params_2, psp_syndrome, syndrome);
 }
 
-static int accel_psp_fs_rx_err_add_rule(struct mlx5e_psp_fs *fs,
-					struct mlx5e_accel_fs_psp_prot *fs_prot,
-					struct mlx5e_psp_rx_err *rx_err)
+static int accel_psp_add_drop_rule(struct mlx5_flow_table *ft,
+				   struct mlx5_flow_spec *spec,
+				   struct mlx5_fc *counter,
+				   struct mlx5_flow_handle **rule)
 {
-	u8 action[MLX5_UN_SZ_BYTES(set_add_copy_action_in_auto)] = {};
+	struct mlx5_flow_destination dest = {};
+	struct mlx5_flow_act flow_act = {};
+	int err = 0;
+
+	flow_act.action = MLX5_FLOW_CONTEXT_ACTION_DROP |
+			  MLX5_FLOW_CONTEXT_ACTION_COUNT;
+	dest.type = MLX5_FLOW_DESTINATION_TYPE_COUNTER;
+	dest.counter = counter;
+	*rule = mlx5_add_flow_rules(ft, spec, &flow_act, &dest, 1);
+	if (IS_ERR(*rule)) {
+		err = PTR_ERR(*rule);
+		*rule = NULL;
+	}
+	return err;
+}
+
+static
+int accel_psp_fs_rx_check_ft_create(struct mlx5e_psp_fs *fs,
+				    struct mlx5e_psp_rx_check_table *check)
+{
+	struct mlx5_flow_table_attr ft_attr = {};
+	struct mlx5_flow_destination dest = {};
 	struct mlx5_core_dev *mdev = fs->mdev;
-	struct mlx5_flow_destination dest[2];
 	struct mlx5_flow_act flow_act = {};
-	struct mlx5_modify_hdr *modify_hdr;
 	struct mlx5_flow_handle *fte;
 	struct mlx5_flow_spec *spec;
 	int err = 0;
@@ -146,174 +323,97 @@ static int accel_psp_fs_rx_err_add_rule(struct mlx5e_psp_fs *fs,
 	if (!spec)
 		return -ENOMEM;
 
-	/* Action to copy 7 bit psp_syndrome to regB[23:29] */
-	MLX5_SET(copy_action_in, action, action_type, MLX5_ACTION_TYPE_COPY);
-	MLX5_SET(copy_action_in, action, src_field, MLX5_ACTION_IN_FIELD_PSP_SYNDROME);
-	MLX5_SET(copy_action_in, action, src_offset, 0);
-	MLX5_SET(copy_action_in, action, length, 7);
-	MLX5_SET(copy_action_in, action, dst_field, MLX5_ACTION_IN_FIELD_METADATA_REG_B);
-	MLX5_SET(copy_action_in, action, dst_offset, 23);
+	ft_attr.max_fte = 4;
+	ft_attr.autogroup.num_reserved_entries = 1;
+	ft_attr.autogroup.max_num_groups = 2;
+	ft_attr.level = MLX5E_ACCEL_FS_PSP_ERR_FT_LEVEL;
+	ft_attr.prio = MLX5E_NIC_PRIO;
+	err = accel_psp_fs_create_ft(fs, &ft_attr, &check->ft);
+	if (err) {
+		mlx5_core_err(fs->mdev,
+			      "fail to create psp rx check ft err=%d\n", err);
+		goto out_err;
+	}
 
-	modify_hdr = mlx5_modify_header_alloc(mdev, MLX5_FLOW_NAMESPACE_KERNEL,
-					      1, action);
-	if (IS_ERR(modify_hdr)) {
-		err = PTR_ERR(modify_hdr);
-		mlx5_core_err(mdev,
-			      "fail to alloc psp copy modify_header_id err=%d\n", err);
-		goto out_spec;
+	err = accel_psp_fs_create_miss_group(check->ft, &check->drop_group);
+	if (err) {
+		mlx5_core_err(fs->mdev,
+			      "fail to create psp rx check drop group err=%d\n",
+			      err);
+		goto out_err;
 	}
 
 	accel_psp_setup_syndrome_match(spec, PSP_OK);
 	/* create fte */
-	flow_act.action = MLX5_FLOW_CONTEXT_ACTION_MOD_HDR |
-			  MLX5_FLOW_CONTEXT_ACTION_FWD_DEST |
-			  MLX5_FLOW_CONTEXT_ACTION_COUNT;
-	flow_act.modify_hdr = modify_hdr;
-	dest[0].type = fs_prot->default_dest.type;
-	dest[0].ft = fs_prot->default_dest.ft;
-	dest[1].type = MLX5_FLOW_DESTINATION_TYPE_COUNTER;
-	dest[1].counter = fs->rx_fs->rx_counter;
-	fte = mlx5_add_flow_rules(rx_err->ft, spec, &flow_act, dest, 2);
+	flow_act.action = MLX5_FLOW_CONTEXT_ACTION_FWD_DEST;
+	dest.type = MLX5_FLOW_DESTINATION_TYPE_FLOW_TABLE;
+	dest.ft = fs->rx.ft;
+	fte = mlx5_add_flow_rules(check->ft, spec, &flow_act, &dest, 1);
 	if (IS_ERR(fte)) {
 		err = PTR_ERR(fte);
-		mlx5_core_err(mdev, "fail to add psp rx err copy rule err=%d\n", err);
-		goto out;
+		mlx5_core_err(mdev, "fail to add psp rx check ok rule err=%d\n",
+			      err);
+		goto out_err;
 	}
-	rx_err->rule = fte;
+	check->rule = fte;
 
 	/* add auth fail drop rule */
 	memset(spec, 0, sizeof(*spec));
-	memset(&flow_act, 0, sizeof(flow_act));
 	accel_psp_setup_syndrome_match(spec, PSP_ICV_FAIL);
-	/* create fte */
-	flow_act.action = MLX5_FLOW_CONTEXT_ACTION_DROP |
-			  MLX5_FLOW_CONTEXT_ACTION_COUNT;
-	dest[0].type = MLX5_FLOW_DESTINATION_TYPE_COUNTER;
-	dest[0].counter = fs->rx_fs->rx_auth_fail_counter;
-	fte = mlx5_add_flow_rules(rx_err->ft, spec, &flow_act, dest, 1);
-	if (IS_ERR(fte)) {
-		err = PTR_ERR(fte);
-		mlx5_core_err(mdev, "fail to add psp rx auth fail drop rule err=%d\n",
+	err = accel_psp_add_drop_rule(check->ft, spec,
+				      fs->rx_auth_fail_counter,
+				      &check->auth_fail_rule);
+	if (err) {
+		mlx5_core_err(mdev,
+			      "fail to add psp rx check auth fail drop rule err=%d\n",
 			      err);
-		goto out_drop_rule;
+		goto out_err;
 	}
-	rx_err->auth_fail_rule = fte;
 
 	/* add framing drop rule */
 	memset(spec, 0, sizeof(*spec));
-	memset(&flow_act, 0, sizeof(flow_act));
 	accel_psp_setup_syndrome_match(spec, PSP_BAD_TRAILER);
-	/* create fte */
-	flow_act.action = MLX5_FLOW_CONTEXT_ACTION_DROP |
-			  MLX5_FLOW_CONTEXT_ACTION_COUNT;
-	dest[0].type = MLX5_FLOW_DESTINATION_TYPE_COUNTER;
-	dest[0].counter = fs->rx_fs->rx_err_counter;
-	fte = mlx5_add_flow_rules(rx_err->ft, spec, &flow_act, dest, 1);
-	if (IS_ERR(fte)) {
-		err = PTR_ERR(fte);
-		mlx5_core_err(mdev, "fail to add psp rx framing err drop rule err=%d\n",
+	err = accel_psp_add_drop_rule(check->ft, spec, fs->rx_err_counter,
+				      &check->err_rule);
+	if (err) {
+		mlx5_core_err(mdev,
+			      "fail to add psp rx check framing drop rule err=%d\n",
 			      err);
-		goto out_drop_auth_fail_rule;
+		goto out_err;
 	}
-	rx_err->err_rule = fte;
 
 	/* add misc. errors drop rule */
 	memset(spec, 0, sizeof(*spec));
-	memset(&flow_act, 0, sizeof(flow_act));
-	/* create fte */
-	flow_act.action = MLX5_FLOW_CONTEXT_ACTION_DROP |
-			  MLX5_FLOW_CONTEXT_ACTION_COUNT;
-	dest[0].type = MLX5_FLOW_DESTINATION_TYPE_COUNTER;
-	dest[0].counter = fs->rx_fs->rx_bad_counter;
-	fte = mlx5_add_flow_rules(rx_err->ft, spec, &flow_act, dest, 1);
-	if (IS_ERR(fte)) {
-		err = PTR_ERR(fte);
-		mlx5_core_err(mdev, "fail to add psp rx misc. err drop rule err=%d\n",
+	err = accel_psp_add_drop_rule(check->ft, spec, fs->rx_bad_counter,
+				      &check->bad_rule);
+	if (err) {
+		mlx5_core_err(mdev,
+			      "fail to add psp rx check misc. err drop rule err=%d\n",
 			      err);
-		goto out_drop_error_rule;
+		goto out_err;
 	}
-	rx_err->bad_rule = fte;
-
-	rx_err->copy_modify_hdr = modify_hdr;
 
 	goto out_spec;
 
-out_drop_error_rule:
-	mlx5_del_flow_rules(rx_err->err_rule);
-	rx_err->err_rule = NULL;
-out_drop_auth_fail_rule:
-	mlx5_del_flow_rules(rx_err->auth_fail_rule);
-	rx_err->auth_fail_rule = NULL;
-out_drop_rule:
-	mlx5_del_flow_rules(rx_err->rule);
-	rx_err->rule = NULL;
-out:
-	mlx5_modify_header_dealloc(mdev, modify_hdr);
+out_err:
+	accel_psp_fs_rx_check_ft_destroy(check);
 out_spec:
 	kfree(spec);
 	return err;
 }
 
-static int accel_psp_fs_rx_err_create_ft(struct mlx5e_psp_fs *fs,
-					 struct mlx5e_accel_fs_psp_prot *fs_prot,
-					 struct mlx5e_psp_rx_err *rx_err)
+static void
+accel_psp_fs_rx_decrypt_ft_destroy(struct mlx5e_psp_fs *fs,
+				   struct mlx5e_psp_rx_decrypt_table *decrypt)
 {
-	struct mlx5_flow_namespace *ns = mlx5e_fs_get_ns(fs->fs, false);
-	struct mlx5_flow_table_attr ft_attr = {};
-	struct mlx5_flow_table *ft;
-	int err;
-
-	ft_attr.max_fte = 2;
-	ft_attr.autogroup.max_num_groups = 2;
-	ft_attr.level = MLX5E_ACCEL_FS_ESP_FT_ERR_LEVEL; // MLX5E_ACCEL_FS_TCP_FT_LEVEL
-	ft_attr.prio = MLX5E_NIC_PRIO;
-	ft = mlx5_create_auto_grouped_flow_table(ns, &ft_attr);
-	if (IS_ERR(ft)) {
-		err = PTR_ERR(ft);
-		mlx5_core_err(fs->mdev, "fail to create psp rx inline ft err=%d\n", err);
-		return err;
-	}
-
-	rx_err->ft = ft;
-	err = accel_psp_fs_rx_err_add_rule(fs, fs_prot, rx_err);
-	if (err)
-		goto out_err;
-
-	return 0;
-
-out_err:
-	mlx5_destroy_flow_table(ft);
-	rx_err->ft = NULL;
-	return err;
-}
-
-static void accel_psp_fs_rx_fs_destroy(struct mlx5e_psp_fs *fs,
-				       struct mlx5e_accel_fs_psp_prot *fs_prot)
-{
-	if (fs_prot->def_rule) {
-		mlx5_del_flow_rules(fs_prot->def_rule);
-		fs_prot->def_rule = NULL;
-	}
-
-	if (fs_prot->rx_modify_hdr) {
-		mlx5_modify_header_dealloc(fs->mdev, fs_prot->rx_modify_hdr);
-		fs_prot->rx_modify_hdr = NULL;
-	}
-
-	if (fs_prot->miss_rule) {
-		mlx5_del_flow_rules(fs_prot->miss_rule);
-		fs_prot->miss_rule = NULL;
-	}
-
-	if (fs_prot->miss_group) {
-		mlx5_destroy_flow_group(fs_prot->miss_group);
-		fs_prot->miss_group = NULL;
-	}
-
-	if (fs_prot->ft) {
-		mlx5_destroy_flow_table(fs_prot->ft);
-		fs_prot->ft = NULL;
+	accel_psp_fs_del_flow_rule(&decrypt->rule);
+	if (decrypt->rx_modify_hdr) {
+		mlx5_modify_header_dealloc(fs->mdev, decrypt->rx_modify_hdr);
+		decrypt->rx_modify_hdr = NULL;
 	}
+	accel_psp_fs_del_flow_rule(&decrypt->miss_rule);
+	accel_psp_fs_destroy_flow_group(&decrypt->miss_group);
+	accel_psp_fs_destroy_ft(&decrypt->ft);
 }
 
 static void setup_fte_udp_psp(struct mlx5_flow_spec *spec, u16 udp_port)
@@ -325,70 +425,64 @@ static void setup_fte_udp_psp(struct mlx5_flow_spec *spec, u16 udp_port)
 	MLX5_SET(fte_match_set_lyr_2_4, spec->match_value, ip_protocol, IPPROTO_UDP);
 }
 
-static int accel_psp_fs_rx_create_ft(struct mlx5e_psp_fs *fs,
-				     struct mlx5e_accel_fs_psp_prot *fs_prot)
+static int
+accel_psp_fs_rx_decrypt_ft_create(struct mlx5e_psp_fs *fs,
+				  struct mlx5e_psp_rx_decrypt_table *decrypt,
+				  struct mlx5_flow_destination *default_dest)
 {
-	struct mlx5_flow_namespace *ns = mlx5e_fs_get_ns(fs->fs, false);
 	u8 action[MLX5_UN_SZ_BYTES(set_add_copy_action_in_auto)] = {};
-	int inlen = MLX5_ST_SZ_BYTES(create_flow_group_in);
 	struct mlx5_modify_hdr *modify_hdr = NULL;
 	struct mlx5_flow_table_attr ft_attr = {};
 	struct mlx5_flow_destination dest = {};
 	struct mlx5_core_dev *mdev = fs->mdev;
-	struct mlx5_flow_group *miss_group;
 	MLX5_DECLARE_FLOW_ACT(flow_act);
 	struct mlx5_flow_handle *rule;
 	struct mlx5_flow_spec *spec;
-	struct mlx5_flow_table *ft;
-	u32 *flow_group_in;
 	int err = 0;
 
-	flow_group_in = kvzalloc(inlen, GFP_KERNEL);
 	spec = kvzalloc_obj(*spec);
-	if (!flow_group_in || !spec) {
-		err = -ENOMEM;
-		goto out;
-	}
+	if (!spec)
+		return -ENOMEM;
 
 	/* Create FT */
 	ft_attr.max_fte = 2;
-	ft_attr.level = MLX5E_ACCEL_FS_ESP_FT_LEVEL;
-	ft_attr.prio = MLX5E_NIC_PRIO;
+	ft_attr.level = MLX5E_ACCEL_FS_PSP_FT_LEVEL;
 	ft_attr.autogroup.num_reserved_entries = 1;
 	ft_attr.autogroup.max_num_groups = 1;
-	ft = mlx5_create_auto_grouped_flow_table(ns, &ft_attr);
-	if (IS_ERR(ft)) {
-		err = PTR_ERR(ft);
-		mlx5_core_err(mdev, "fail to create psp rx ft err=%d\n", err);
+	ft_attr.prio = MLX5E_NIC_PRIO;
+	err = accel_psp_fs_create_ft(fs, &ft_attr, &decrypt->ft);
+	if (err) {
+		mlx5_core_err(mdev, "fail to create psp rx decrypt ft err=%d\n",
+			      err);
 		goto out_err;
 	}
-	fs_prot->ft = ft;
 
 	/* Create miss_group */
-	MLX5_SET(create_flow_group_in, flow_group_in, start_flow_index, ft->max_fte - 1);
-	MLX5_SET(create_flow_group_in, flow_group_in, end_flow_index, ft->max_fte - 1);
-	miss_group = mlx5_create_flow_group(ft, flow_group_in);
-	if (IS_ERR(miss_group)) {
-		err = PTR_ERR(miss_group);
-		mlx5_core_err(mdev, "fail to create psp rx miss_group err=%d\n", err);
+	err = accel_psp_fs_create_miss_group(decrypt->ft, &decrypt->miss_group);
+	if (err) {
+		mlx5_core_err(mdev,
+			      "fail to create psp rx decrypt miss_group err=%d\n",
+			      err);
 		goto out_err;
 	}
-	fs_prot->miss_group = miss_group;
 
 	/* Create miss rule */
-	rule = mlx5_add_flow_rules(ft, spec, &flow_act, &fs_prot->default_dest, 1);
+	flow_act.action = MLX5_FLOW_CONTEXT_ACTION_FWD_DEST;
+	rule = mlx5_add_flow_rules(decrypt->ft, spec, &flow_act, default_dest,
+				   1);
 	if (IS_ERR(rule)) {
 		err = PTR_ERR(rule);
-		mlx5_core_err(mdev, "fail to create psp rx miss_rule err=%d\n", err);
+		mlx5_core_err(mdev,
+			      "fail to create psp rx decrypt miss_rule err=%d\n",
+			      err);
 		goto out_err;
 	}
-	fs_prot->miss_rule = rule;
+	decrypt->miss_rule = rule;
 
-	/* Add default Rx psp rule */
+	/* Add PSP RX decrypt rule */
 	setup_fte_udp_psp(spec, PSP_DEFAULT_UDP_PORT);
 	flow_act.crypto.type = MLX5_FLOW_CONTEXT_ENCRYPT_DECRYPT_TYPE_PSP;
 	/* Set bit[31, 30] PSP marker */
-	/* Set bit[29-23] psp_syndrome is set in error FT */
 #define MLX5E_PSP_MARKER_BIT (BIT(30) | BIT(31))
 	MLX5_SET(set_action_in, action, action_type, MLX5_ACTION_TYPE_SET);
 	MLX5_SET(set_action_in, action, field, MLX5_ACTION_IN_FIELD_METADATA_REG_B);
@@ -403,275 +497,159 @@ static int accel_psp_fs_rx_create_ft(struct mlx5e_psp_fs *fs,
 		modify_hdr = NULL;
 		goto out_err;
 	}
-	fs_prot->rx_modify_hdr = modify_hdr;
+	decrypt->rx_modify_hdr = modify_hdr;
 
 	flow_act.action = MLX5_FLOW_CONTEXT_ACTION_FWD_DEST |
 			  MLX5_FLOW_CONTEXT_ACTION_CRYPTO_DECRYPT |
 			  MLX5_FLOW_CONTEXT_ACTION_MOD_HDR;
 	flow_act.modify_hdr = modify_hdr;
 	dest.type = MLX5_FLOW_DESTINATION_TYPE_FLOW_TABLE;
-	dest.ft = fs_prot->rx_err.ft;
-	rule = mlx5_add_flow_rules(fs_prot->ft, spec, &flow_act, &dest, 1);
+	dest.ft = fs->check.ft;
+	rule = mlx5_add_flow_rules(decrypt->ft, spec, &flow_act, &dest, 1);
 	if (IS_ERR(rule)) {
 		err = PTR_ERR(rule);
-		mlx5_core_err(mdev,
-			      "fail to add psp rule Rx decryption, err=%d, flow_act.action = %#04X\n",
-			      err, flow_act.action);
+		mlx5_core_err(mdev, "fail to add psp rx decrypt rule, err=%d\n",
+			      err);
 		goto out_err;
 	}
 
-	fs_prot->def_rule = rule;
-	goto out;
+	decrypt->rule = rule;
+	goto out_spec;
 
 out_err:
-	accel_psp_fs_rx_fs_destroy(fs, fs_prot);
-out:
-	kvfree(flow_group_in);
+	accel_psp_fs_rx_decrypt_ft_destroy(fs, decrypt);
+out_spec:
 	kvfree(spec);
 	return err;
 }
 
-static int accel_psp_fs_rx_destroy(struct mlx5e_psp_fs *fs, enum accel_fs_psp_type type)
+static void accel_psp_fs_rx_destroy(struct mlx5e_psp_fs *fs)
 {
-	struct mlx5e_accel_fs_psp_prot *fs_prot;
-	struct mlx5e_accel_fs_psp *accel_psp;
-
-	accel_psp = fs->rx_fs;
-
-	/* The netdev unreg already happened, so all offloaded rule are already removed */
-	fs_prot = &accel_psp->fs_prot[type];
-
-	accel_psp_fs_rx_fs_destroy(fs, fs_prot);
-
-	accel_psp_fs_rx_err_destroy_ft(fs, &fs_prot->rx_err);
+	struct mlx5_ttc_table *ttc = mlx5e_fs_get_ttc(fs->fs, false);
+	int i;
 
-	return 0;
+	/* disconnect */
+	for (i = 0; i < ACCEL_FS_PSP_NUM_TYPES; i++) {
+		mlx5_ttc_fwd_default_dest(ttc, fs_psp2tt(i));
+		accel_psp_fs_rx_decrypt_ft_destroy(fs, &fs->decrypt[i]);
+	}
+	accel_psp_fs_rx_check_ft_destroy(&fs->check);
+	accel_psp_fs_rx_ft_destroy(&fs->rx);
 }
 
-static int accel_psp_fs_rx_create(struct mlx5e_psp_fs *fs, enum accel_fs_psp_type type)
+static int accel_psp_fs_rx_create(struct mlx5e_psp_fs *fs,
+				  struct netlink_ext_ack *extack)
 {
 	struct mlx5_ttc_table *ttc = mlx5e_fs_get_ttc(fs->fs, false);
-	struct mlx5e_accel_fs_psp_prot *fs_prot;
-	struct mlx5e_accel_fs_psp *accel_psp;
-	int err;
-
-	accel_psp = fs->rx_fs;
-	fs_prot = &accel_psp->fs_prot[type];
+	int i, err;
 
-	fs_prot->default_dest = mlx5_ttc_get_default_dest(ttc, fs_psp2tt(type));
-
-	err = accel_psp_fs_rx_err_create_ft(fs, fs_prot, &fs_prot->rx_err);
-	if (err)
+	err = accel_psp_fs_rx_ft_create(fs, &fs->rx);
+	if (err) {
+		NL_SET_ERR_MSG(extack, "Failed creating RX steering table");
 		return err;
+	}
 
-	err = accel_psp_fs_rx_create_ft(fs, fs_prot);
-	if (err)
-		accel_psp_fs_rx_err_destroy_ft(fs, &fs_prot->rx_err);
-
-	return err;
-}
-
-static int accel_psp_fs_rx_ft_get(struct mlx5e_psp_fs *fs, enum accel_fs_psp_type type)
-{
-	struct mlx5e_accel_fs_psp_prot *fs_prot;
-	struct mlx5_flow_destination dest = {};
-	struct mlx5e_accel_fs_psp *accel_psp;
-	struct mlx5_ttc_table *ttc;
-	int err = 0;
-
-	if (!fs || !fs->rx_fs)
-		return -EINVAL;
-
-	ttc = mlx5e_fs_get_ttc(fs->fs, false);
-	accel_psp = fs->rx_fs;
-	fs_prot = &accel_psp->fs_prot[type];
-	mutex_lock(&fs_prot->prot_mutex);
-	if (fs_prot->refcnt++)
-		goto out;
-
-	/* create FT */
-	err = accel_psp_fs_rx_create(fs, type);
+	err = accel_psp_fs_rx_check_ft_create(fs, &fs->check);
 	if (err) {
-		fs_prot->refcnt--;
-		goto out;
+		NL_SET_ERR_MSG(extack,
+			       "Failed creating RX check steering table");
+		goto err_ft;
 	}
 
-	/* connect */
-	dest.type = MLX5_FLOW_DESTINATION_TYPE_FLOW_TABLE;
-	dest.ft = fs_prot->ft;
-	mlx5_ttc_fwd_dest(ttc, fs_psp2tt(type), &dest);
-
-out:
-	mutex_unlock(&fs_prot->prot_mutex);
-	return err;
-}
-
-static void accel_psp_fs_rx_ft_put(struct mlx5e_psp_fs *fs, enum accel_fs_psp_type type)
-{
-	struct mlx5_ttc_table *ttc = mlx5e_fs_get_ttc(fs->fs, false);
-	struct mlx5e_accel_fs_psp_prot *fs_prot;
-	struct mlx5e_accel_fs_psp *accel_psp;
-
-	accel_psp = fs->rx_fs;
-	fs_prot = &accel_psp->fs_prot[type];
-	mutex_lock(&fs_prot->prot_mutex);
-	if (--fs_prot->refcnt)
-		goto out;
-
-	/* disconnect */
-	mlx5_ttc_fwd_default_dest(ttc, fs_psp2tt(type));
+	for (i = 0; i < ACCEL_FS_PSP_NUM_TYPES; i++) {
+		struct mlx5_flow_destination dest;
+
+		dest = mlx5_ttc_get_default_dest(ttc, fs_psp2tt(i));
+		err = accel_psp_fs_rx_decrypt_ft_create(fs, &fs->decrypt[i],
+							&dest);
+		if (err) {
+			NL_SET_ERR_MSG(extack,
+				       "Failed creating RX decrypt steering table");
+			goto err_decrypt_ft;
+		}
+
+		dest.type = MLX5_FLOW_DESTINATION_TYPE_FLOW_TABLE;
+		dest.ft = fs->decrypt[i].ft;
+		mlx5_ttc_fwd_dest(ttc, fs_psp2tt(i), &dest);
+	}
 
-	/* remove FT */
-	accel_psp_fs_rx_destroy(fs, type);
+	return 0;
 
-out:
-	mutex_unlock(&fs_prot->prot_mutex);
+err_decrypt_ft:
+	while (--i >= 0) {
+		mlx5_ttc_fwd_default_dest(ttc, fs_psp2tt(i));
+		accel_psp_fs_rx_decrypt_ft_destroy(fs, &fs->decrypt[i]);
+	}
+	accel_psp_fs_rx_check_ft_destroy(&fs->check);
+err_ft:
+	accel_psp_fs_rx_ft_destroy(&fs->rx);
+	return err;
 }
 
-static void accel_psp_fs_cleanup_rx(struct mlx5e_psp_fs *fs)
+static void accel_psp_fs_rx_cleanup(struct mlx5e_psp_fs *fs)
 {
-	struct mlx5e_accel_fs_psp_prot *fs_prot;
-	struct mlx5e_accel_fs_psp *accel_psp;
-	enum accel_fs_psp_type i;
-
-	if (!fs->rx_fs)
-		return;
-
-	accel_psp = fs->rx_fs;
-	mlx5_fc_destroy(fs->mdev, accel_psp->rx_bad_counter);
-	mlx5_fc_destroy(fs->mdev, accel_psp->rx_err_counter);
-	mlx5_fc_destroy(fs->mdev, accel_psp->rx_auth_fail_counter);
-	mlx5_fc_destroy(fs->mdev, accel_psp->rx_counter);
-	for (i = 0; i < ACCEL_FS_PSP_NUM_TYPES; i++) {
-		fs_prot = &accel_psp->fs_prot[i];
-		mutex_destroy(&fs_prot->prot_mutex);
-		WARN_ON(fs_prot->refcnt);
-	}
-	kfree(fs->rx_fs);
-	fs->rx_fs = NULL;
+	accel_psp_fs_destroy_counter(fs->mdev, &fs->rx_bad_counter);
+	accel_psp_fs_destroy_counter(fs->mdev, &fs->rx_err_counter);
+	accel_psp_fs_destroy_counter(fs->mdev, &fs->rx_auth_fail_counter);
+	accel_psp_fs_destroy_counter(fs->mdev, &fs->rx_counter);
 }
 
-static int accel_psp_fs_init_rx(struct mlx5e_psp_fs *fs)
+static int accel_psp_fs_rx_init(struct mlx5e_psp_fs *fs)
 {
-	struct mlx5e_accel_fs_psp_prot *fs_prot;
-	struct mlx5e_accel_fs_psp *accel_psp;
 	struct mlx5_core_dev *mdev = fs->mdev;
-	struct mlx5_fc *flow_counter;
-	enum accel_fs_psp_type i;
 	int err;
 
-	accel_psp = kzalloc_obj(*accel_psp);
-	if (!accel_psp)
-		return -ENOMEM;
-
-	for (i = 0; i < ACCEL_FS_PSP_NUM_TYPES; i++) {
-		fs_prot = &accel_psp->fs_prot[i];
-		mutex_init(&fs_prot->prot_mutex);
-	}
-
-	flow_counter = mlx5_fc_create(mdev, false);
-	if (IS_ERR(flow_counter)) {
+	err = accel_psp_fs_create_counter(mdev, &fs->rx_counter);
+	if (err) {
 		mlx5_core_warn(mdev,
-			       "fail to create psp rx flow counter err=%pe\n",
-			       flow_counter);
-		err = PTR_ERR(flow_counter);
+			       "fail to create psp rx flow counter err=%d\n",
+			       err);
 		goto out_err;
 	}
-	accel_psp->rx_counter = flow_counter;
 
-	flow_counter = mlx5_fc_create(mdev, false);
-	if (IS_ERR(flow_counter)) {
+	err = accel_psp_fs_create_counter(mdev, &fs->rx_auth_fail_counter);
+	if (err) {
 		mlx5_core_warn(mdev,
-			       "fail to create psp rx auth fail flow counter err=%pe\n",
-			       flow_counter);
-		err = PTR_ERR(flow_counter);
-		goto out_counter_err;
+			       "fail to create psp rx auth fail flow counter err=%d\n",
+			       err);
+		goto out_err;
 	}
-	accel_psp->rx_auth_fail_counter = flow_counter;
 
-	flow_counter = mlx5_fc_create(mdev, false);
-	if (IS_ERR(flow_counter)) {
+	err = accel_psp_fs_create_counter(mdev, &fs->rx_err_counter);
+	if (err) {
 		mlx5_core_warn(mdev,
-			       "fail to create psp rx error flow counter err=%pe\n",
-			       flow_counter);
-		err = PTR_ERR(flow_counter);
-		goto out_auth_fail_counter_err;
+			       "fail to create psp rx error flow counter err=%d\n",
+			       err);
+		goto out_err;
 	}
-	accel_psp->rx_err_counter = flow_counter;
 
-	flow_counter = mlx5_fc_create(mdev, false);
-	if (IS_ERR(flow_counter)) {
+	err = accel_psp_fs_create_counter(mdev, &fs->rx_bad_counter);
+	if (err) {
 		mlx5_core_warn(mdev,
-			       "fail to create psp rx bad flow counter err=%pe\n",
-			       flow_counter);
-		err = PTR_ERR(flow_counter);
-		goto out_err_counter_err;
+			       "fail to create psp rx bad flow counter err=%d\n",
+			       err);
+		goto out_err;
 	}
-	accel_psp->rx_bad_counter = flow_counter;
-
-	fs->rx_fs = accel_psp;
 
 	return 0;
 
-out_err_counter_err:
-	mlx5_fc_destroy(mdev, accel_psp->rx_err_counter);
-	accel_psp->rx_err_counter = NULL;
-out_auth_fail_counter_err:
-	mlx5_fc_destroy(mdev, accel_psp->rx_auth_fail_counter);
-	accel_psp->rx_auth_fail_counter = NULL;
-out_counter_err:
-	mlx5_fc_destroy(mdev, accel_psp->rx_counter);
-	accel_psp->rx_counter = NULL;
 out_err:
-	for (i = 0; i < ACCEL_FS_PSP_NUM_TYPES; i++) {
-		fs_prot = &accel_psp->fs_prot[i];
-		mutex_destroy(&fs_prot->prot_mutex);
-	}
-	kfree(accel_psp);
-	fs->rx_fs = NULL;
-
+	accel_psp_fs_rx_cleanup(fs);
 	return err;
 }
 
 void mlx5_accel_psp_fs_cleanup_rx_tables(struct mlx5e_priv *priv)
 {
-	int i;
-
 	if (!priv->psp)
 		return;
 
-	for (i = 0; i < ACCEL_FS_PSP_NUM_TYPES; i++)
-		accel_psp_fs_rx_ft_put(priv->psp->fs, i);
-}
-
-int mlx5_accel_psp_fs_init_rx_tables(struct mlx5e_priv *priv)
-{
-	struct mlx5e_psp_fs *fs;
-	int err, i;
-
-	if (!priv->psp)
-		return 0;
-
-	fs = priv->psp->fs;
-	for (i = 0; i < ACCEL_FS_PSP_NUM_TYPES; i++) {
-		err = accel_psp_fs_rx_ft_get(fs, i);
-		if (err)
-			goto out_err;
-	}
-
-	return 0;
-
-out_err:
-	i--;
-	while (i >= 0) {
-		accel_psp_fs_rx_ft_put(fs, i);
-		--i;
-	}
-
-	return err;
+	netdev_lock(priv->netdev);
+	accel_psp_fs_rx_destroy(priv->psp->fs);
+	netdev_unlock(priv->netdev);
 }
 
-static int accel_psp_fs_tx_create_ft_table(struct mlx5e_psp_fs *fs)
+static int accel_psp_fs_tx_ft_create(struct mlx5e_psp_fs *fs,
+				     struct mlx5e_psp_tx_table *tx)
 {
 	int inlen = MLX5_ST_SZ_BYTES(create_flow_group_in);
 	struct mlx5_flow_table_attr ft_attr = {};
@@ -681,7 +659,6 @@ static int accel_psp_fs_tx_create_ft_table(struct mlx5e_psp_fs *fs)
 	u32 *in, *mc, *outer_headers_c;
 	struct mlx5_flow_handle *rule;
 	struct mlx5_flow_spec *spec;
-	struct mlx5e_psp_tx *tx_fs;
 	struct mlx5_flow_table *ft;
 	struct mlx5_flow_group *fg;
 	int err = 0;
@@ -700,8 +677,7 @@ static int accel_psp_fs_tx_create_ft_table(struct mlx5e_psp_fs *fs)
 	ft_attr.level = MLX5E_PSP_LEVEL;
 	ft_attr.autogroup.max_num_groups = 1;
 
-	tx_fs = fs->tx_fs;
-	ft = mlx5_create_flow_table(tx_fs->ns, &ft_attr);
+	ft = mlx5_create_flow_table(tx->ns, &ft_attr);
 	if (IS_ERR(ft)) {
 		err = PTR_ERR(ft);
 		mlx5_core_err(mdev, "PSP: fail to add psp tx flow table, err = %d\n", err);
@@ -727,7 +703,7 @@ static int accel_psp_fs_tx_create_ft_table(struct mlx5e_psp_fs *fs)
 			  MLX5_FLOW_CONTEXT_ACTION_CRYPTO_ENCRYPT |
 			  MLX5_FLOW_CONTEXT_ACTION_COUNT;
 	dest.type = MLX5_FLOW_DESTINATION_TYPE_COUNTER;
-	dest.counter = tx_fs->tx_counter;
+	dest.counter = fs->tx_counter;
 	rule = mlx5_add_flow_rules(ft, spec, &flow_act, &dest, 1);
 	if (IS_ERR(rule)) {
 		err = PTR_ERR(rule);
@@ -735,9 +711,9 @@ static int accel_psp_fs_tx_create_ft_table(struct mlx5e_psp_fs *fs)
 		goto err_add_flow_rule;
 	}
 
-	tx_fs->ft = ft;
-	tx_fs->fg = fg;
-	tx_fs->rule = rule;
+	tx->ft = ft;
+	tx->fg = fg;
+	tx->rule = rule;
 	goto out;
 
 err_add_flow_rule:
@@ -750,87 +726,35 @@ static int accel_psp_fs_tx_create_ft_table(struct mlx5e_psp_fs *fs)
 	return err;
 }
 
-static void accel_psp_fs_tx_destroy(struct mlx5e_psp_tx *tx_fs)
+static void accel_psp_fs_tx_ft_destroy(struct mlx5e_psp_tx_table *tx)
 {
-	if (!tx_fs->ft)
-		return;
-
-	mlx5_del_flow_rules(tx_fs->rule);
-	mlx5_destroy_flow_group(tx_fs->fg);
-	mlx5_destroy_flow_table(tx_fs->ft);
+	accel_psp_fs_del_flow_rule(&tx->rule);
+	accel_psp_fs_destroy_flow_group(&tx->fg);
+	accel_psp_fs_destroy_ft(&tx->ft);
 }
 
-static int accel_psp_fs_tx_ft_get(struct mlx5e_psp_fs *fs)
+static void accel_psp_fs_tx_cleanup(struct mlx5e_psp_fs *fs)
 {
-	struct mlx5e_psp_tx *tx_fs = fs->tx_fs;
-	int err = 0;
-
-	mutex_lock(&tx_fs->mutex);
-	if (tx_fs->refcnt++)
-		goto out;
-
-	err = accel_psp_fs_tx_create_ft_table(fs);
-	if (err)
-		tx_fs->refcnt--;
-out:
-	mutex_unlock(&tx_fs->mutex);
-	return err;
+	accel_psp_fs_destroy_counter(fs->mdev, &fs->tx_counter);
 }
 
-static void accel_psp_fs_tx_ft_put(struct mlx5e_psp_fs *fs)
-{
-	struct mlx5e_psp_tx *tx_fs = fs->tx_fs;
-
-	mutex_lock(&tx_fs->mutex);
-	if (--tx_fs->refcnt)
-		goto out;
-
-	accel_psp_fs_tx_destroy(tx_fs);
-out:
-	mutex_unlock(&tx_fs->mutex);
-}
-
-static void accel_psp_fs_cleanup_tx(struct mlx5e_psp_fs *fs)
-{
-	struct mlx5e_psp_tx *tx_fs = fs->tx_fs;
-
-	if (!tx_fs)
-		return;
-
-	mlx5_fc_destroy(fs->mdev, tx_fs->tx_counter);
-	mutex_destroy(&tx_fs->mutex);
-	WARN_ON(tx_fs->refcnt);
-	kfree(tx_fs);
-	fs->tx_fs = NULL;
-}
-
-static int accel_psp_fs_init_tx(struct mlx5e_psp_fs *fs)
+static int accel_psp_fs_tx_init(struct mlx5e_psp_fs *fs)
 {
 	struct mlx5_core_dev *mdev = fs->mdev;
-	struct mlx5_flow_namespace *ns;
-	struct mlx5_fc *flow_counter;
-	struct mlx5e_psp_tx *tx_fs;
+	int err;
 
-	ns = mlx5_get_flow_namespace(mdev, MLX5_FLOW_NAMESPACE_EGRESS_IPSEC);
-	if (!ns)
+	fs->tx.ns = mlx5_get_flow_namespace(mdev,
+					    MLX5_FLOW_NAMESPACE_EGRESS_IPSEC);
+	if (!fs->tx.ns)
 		return -EOPNOTSUPP;
 
-	tx_fs = kzalloc_obj(*tx_fs);
-	if (!tx_fs)
-		return -ENOMEM;
-
-	flow_counter = mlx5_fc_create(mdev, false);
-	if (IS_ERR(flow_counter)) {
+	err = accel_psp_fs_create_counter(mdev, &fs->tx_counter);
+	if (err) {
 		mlx5_core_warn(mdev,
-			       "fail to create psp tx flow counter err=%pe\n",
-			       flow_counter);
-		kfree(tx_fs);
-		return PTR_ERR(flow_counter);
+			       "fail to create psp tx flow counter err=%d\n",
+			       err);
+		return err;
 	}
-	tx_fs->tx_counter = flow_counter;
-	mutex_init(&tx_fs->mutex);
-	tx_fs->ns = ns;
-	fs->tx_fs = tx_fs;
 	return 0;
 }
 
@@ -838,32 +762,29 @@ static void
 mlx5e_accel_psp_fs_get_stats_fill(struct mlx5e_priv *priv,
 				  struct mlx5e_psp_stats *stats)
 {
-	struct mlx5e_psp_tx *tx_fs = priv->psp->fs->tx_fs;
+	struct mlx5e_psp_fs *fs = priv->psp->fs;
 	struct mlx5_core_dev *mdev = priv->mdev;
-	struct mlx5e_accel_fs_psp *accel_psp;
-
-	accel_psp = (struct mlx5e_accel_fs_psp *)priv->psp->fs->rx_fs;
 
-	if (tx_fs->tx_counter)
-		mlx5_fc_query(mdev, tx_fs->tx_counter, &stats->psp_tx_pkts,
+	if (fs->tx_counter)
+		mlx5_fc_query(mdev, fs->tx_counter, &stats->psp_tx_pkts,
 			      &stats->psp_tx_bytes);
 
-	if (accel_psp->rx_counter)
-		mlx5_fc_query(mdev, accel_psp->rx_counter, &stats->psp_rx_pkts,
+	if (fs->rx_counter)
+		mlx5_fc_query(mdev, fs->rx_counter, &stats->psp_rx_pkts,
 			      &stats->psp_rx_bytes);
 
-	if (accel_psp->rx_auth_fail_counter)
-		mlx5_fc_query(mdev, accel_psp->rx_auth_fail_counter,
+	if (fs->rx_auth_fail_counter)
+		mlx5_fc_query(mdev, fs->rx_auth_fail_counter,
 			      &stats->psp_rx_pkts_auth_fail,
 			      &stats->psp_rx_bytes_auth_fail);
 
-	if (accel_psp->rx_err_counter)
-		mlx5_fc_query(mdev, accel_psp->rx_err_counter,
+	if (fs->rx_err_counter)
+		mlx5_fc_query(mdev, fs->rx_err_counter,
 			      &stats->psp_rx_pkts_frame_err,
 			      &stats->psp_rx_bytes_frame_err);
 
-	if (accel_psp->rx_bad_counter)
-		mlx5_fc_query(mdev, accel_psp->rx_bad_counter,
+	if (fs->rx_bad_counter)
+		mlx5_fc_query(mdev, fs->rx_bad_counter,
 			      &stats->psp_rx_pkts_drop,
 			      &stats->psp_rx_bytes_drop);
 }
@@ -873,21 +794,15 @@ void mlx5_accel_psp_fs_cleanup_tx_tables(struct mlx5e_priv *priv)
 	if (!priv->psp)
 		return;
 
-	accel_psp_fs_tx_ft_put(priv->psp->fs);
-}
-
-int mlx5_accel_psp_fs_init_tx_tables(struct mlx5e_priv *priv)
-{
-	if (!priv->psp)
-		return 0;
-
-	return accel_psp_fs_tx_ft_get(priv->psp->fs);
+	netdev_lock(priv->netdev);
+	accel_psp_fs_tx_ft_destroy(&priv->psp->fs->tx);
+	netdev_unlock(priv->netdev);
 }
 
 static void mlx5e_accel_psp_fs_cleanup(struct mlx5e_psp_fs *fs)
 {
-	accel_psp_fs_cleanup_rx(fs);
-	accel_psp_fs_cleanup_tx(fs);
+	accel_psp_fs_rx_cleanup(fs);
+	accel_psp_fs_tx_cleanup(fs);
 	kfree(fs);
 }
 
@@ -901,29 +816,63 @@ static struct mlx5e_psp_fs *mlx5e_accel_psp_fs_init(struct mlx5e_priv *priv)
 		return ERR_PTR(-ENOMEM);
 
 	fs->mdev = priv->mdev;
-	err = accel_psp_fs_init_tx(fs);
+	err = accel_psp_fs_tx_init(fs);
 	if (err)
 		goto err_tx;
 
 	fs->fs = priv->fs;
-	err = accel_psp_fs_init_rx(fs);
+	err = accel_psp_fs_rx_init(fs);
 	if (err)
 		goto err_rx;
 
 	return fs;
 
 err_rx:
-	accel_psp_fs_cleanup_tx(fs);
+	accel_psp_fs_tx_cleanup(fs);
 err_tx:
 	kfree(fs);
 	return ERR_PTR(err);
 }
 
+static int accel_psp_fs_create(struct mlx5e_priv *priv,
+			       struct netlink_ext_ack *extack)
+{
+	int err;
+
+	err = accel_psp_fs_rx_create(priv->psp->fs, extack);
+	if (err)
+		return err;
+
+	err = accel_psp_fs_tx_ft_create(priv->psp->fs, &priv->psp->fs->tx);
+	if (err) {
+		NL_SET_ERR_MSG(extack, "Failed creating TX steering table");
+		accel_psp_fs_rx_destroy(priv->psp->fs);
+	}
+	return err;
+}
+
+static void accel_psp_fs_destroy(struct mlx5e_priv *priv)
+{
+	accel_psp_fs_tx_ft_destroy(&priv->psp->fs->tx);
+	accel_psp_fs_rx_destroy(priv->psp->fs);
+}
+
 static int
 mlx5e_psp_set_config(struct psp_dev *psd, struct psp_dev_config *conf,
 		     struct netlink_ext_ack *extack)
 {
-	return 0; /* TODO: this should actually do things to the device */
+	struct mlx5e_priv *priv = netdev_priv(psd->main_netdev);
+	bool psp_enabled = psd->config.versions;
+	bool enable_psp = conf->versions;
+	int err = 0;
+
+	netdev_lock(priv->netdev);
+	if (!psp_enabled && enable_psp)
+		err = accel_psp_fs_create(priv, extack);
+	else if (psp_enabled && !enable_psp)
+		accel_psp_fs_destroy(priv);
+	netdev_unlock(priv->netdev);
+	return err;
 }
 
 static int
@@ -1072,21 +1021,21 @@ void mlx5e_psp_unregister(struct mlx5e_priv *priv)
 {
 	struct mlx5e_psp *psp = priv->psp;
 
-	if (!psp || !psp->psp)
+	if (!psp || !psp->psd)
 		return;
 
-	psp_dev_unregister(psp->psp);
-	psp->psp = NULL;
+	psp_dev_unregister(psp->psd);
+	psp->psd = NULL;
 }
 
-void mlx5e_psp_register(struct mlx5e_priv *priv)
+int mlx5e_psp_register(struct mlx5e_priv *priv)
 {
 	struct mlx5e_psp *psp = priv->psp;
 	struct psp_dev *psd;
 
 	/* FW Caps missing */
 	if (!priv->psp)
-		return;
+		return 0;
 
 	psp->caps.assoc_drv_spc = sizeof(u32);
 	psp->caps.versions = 1 << PSP_VERSION_HDR0_AES_GCM_128;
@@ -1098,9 +1047,11 @@ void mlx5e_psp_register(struct mlx5e_priv *priv)
 	if (IS_ERR(psd)) {
 		mlx5_core_err(priv->mdev, "PSP failed to register due to %pe\n",
 			      psd);
-		return;
+		return PTR_ERR(psd);
 	}
-	psp->psp = psd;
+	psp->psd = psd;
+
+	return 0;
 }
 
 int mlx5e_psp_init(struct mlx5e_priv *priv)
diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en_accel/psp.h b/drivers/net/ethernet/mellanox/mlx5/core/en_accel/psp.h
index 6b62fef0d9a738..3f441e7dd55ac0 100644
--- a/drivers/net/ethernet/mellanox/mlx5/core/en_accel/psp.h
+++ b/drivers/net/ethernet/mellanox/mlx5/core/en_accel/psp.h
@@ -23,7 +23,7 @@ struct mlx5e_psp_stats {
 };
 
 struct mlx5e_psp {
-	struct psp_dev *psp;
+	struct psp_dev *psd;
 	struct psp_dev_caps caps;
 	struct mlx5e_psp_fs *fs;
 	atomic_t tx_key_cnt;
@@ -43,33 +43,21 @@ static inline bool mlx5_is_psp_device(struct mlx5_core_dev *mdev)
 	return true;
 }
 
-int mlx5_accel_psp_fs_init_rx_tables(struct mlx5e_priv *priv);
 void mlx5_accel_psp_fs_cleanup_rx_tables(struct mlx5e_priv *priv);
-int mlx5_accel_psp_fs_init_tx_tables(struct mlx5e_priv *priv);
 void mlx5_accel_psp_fs_cleanup_tx_tables(struct mlx5e_priv *priv);
-void mlx5e_psp_register(struct mlx5e_priv *priv);
+int mlx5e_psp_register(struct mlx5e_priv *priv);
 void mlx5e_psp_unregister(struct mlx5e_priv *priv);
 int mlx5e_psp_init(struct mlx5e_priv *priv);
 void mlx5e_psp_cleanup(struct mlx5e_priv *priv);
 #else
-static inline int mlx5_accel_psp_fs_init_rx_tables(struct mlx5e_priv *priv)
-{
-	return 0;
-}
-
 static inline void mlx5_accel_psp_fs_cleanup_rx_tables(struct mlx5e_priv *priv) { }
-static inline int mlx5_accel_psp_fs_init_tx_tables(struct mlx5e_priv *priv)
-{
-	return 0;
-}
-
 static inline void mlx5_accel_psp_fs_cleanup_tx_tables(struct mlx5e_priv *priv) { }
 static inline bool mlx5_is_psp_device(struct mlx5_core_dev *mdev)
 {
 	return false;
 }
 
-static inline void mlx5e_psp_register(struct mlx5e_priv *priv) { }
+static inline int mlx5e_psp_register(struct mlx5e_priv *priv) { return 0; }
 static inline void mlx5e_psp_unregister(struct mlx5e_priv *priv) { }
 static inline int mlx5e_psp_init(struct mlx5e_priv *priv) { return 0; }
 static inline void mlx5e_psp_cleanup(struct mlx5e_priv *priv) { }
diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en_accel/psp_rxtx.c b/drivers/net/ethernet/mellanox/mlx5/core/en_accel/psp_rxtx.c
index ef7f5338540fdf..348fd7a962615a 100644
--- a/drivers/net/ethernet/mellanox/mlx5/core/en_accel/psp_rxtx.c
+++ b/drivers/net/ethernet/mellanox/mlx5/core/en_accel/psp_rxtx.c
@@ -14,12 +14,6 @@
 #include "en_accel/psp_rxtx.h"
 #include "en_accel/psp.h"
 
-enum {
-	MLX5E_PSP_OFFLOAD_RX_SYNDROME_DECRYPTED,
-	MLX5E_PSP_OFFLOAD_RX_SYNDROME_AUTH_FAILED,
-	MLX5E_PSP_OFFLOAD_RX_SYNDROME_BAD_TRAILER,
-};
-
 static void mlx5e_psp_set_swp(struct sk_buff *skb,
 			      struct mlx5e_accel_tx_psp_state *psp_st,
 			      struct mlx5_wqe_eth_seg *eseg)
@@ -122,16 +116,11 @@ static bool mlx5e_psp_set_state(struct mlx5e_priv *priv,
 bool mlx5e_psp_offload_handle_rx_skb(struct net_device *netdev, struct sk_buff *skb,
 				     struct mlx5_cqe64 *cqe)
 {
-	u32 psp_meta_data = be32_to_cpu(cqe->ft_metadata);
 	struct mlx5e_priv *priv = netdev_priv(netdev);
-	u16 dev_id = priv->psp->psp->id;
+	u16 dev_id = priv->psp->psd->id;
 	bool strip_icv = true;
 	u8 generation = 0;
 
-	/* TBD: report errors as SW counters to ethtool, any further handling ? */
-	if (MLX5_PSP_METADATA_SYNDROME(psp_meta_data) != MLX5E_PSP_OFFLOAD_RX_SYNDROME_DECRYPTED)
-		goto drop;
-
 	if (psp_dev_rcv(skb, dev_id, generation, strip_icv))
 		goto drop;
 
diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en_accel/psp_rxtx.h b/drivers/net/ethernet/mellanox/mlx5/core/en_accel/psp_rxtx.h
index 70289c921bd6b3..2b080c39cc37ed 100644
--- a/drivers/net/ethernet/mellanox/mlx5/core/en_accel/psp_rxtx.h
+++ b/drivers/net/ethernet/mellanox/mlx5/core/en_accel/psp_rxtx.h
@@ -10,9 +10,8 @@
 #include "en.h"
 #include "en/txrx.h"
 
-/* Bit30: PSP marker, Bit29-23: PSP syndrome, Bit22-0: PSP obj id */
+/* Bit30: PSP marker, Bit22-0: PSP obj id */
 #define MLX5_PSP_METADATA_MARKER(metadata)  ((((metadata) >> 30) & 0x3) == 0x3)
-#define MLX5_PSP_METADATA_SYNDROME(metadata) (((metadata) >> 23) & GENMASK(6, 0))
 #define MLX5_PSP_METADATA_HANDLE(metadata)  ((metadata) & GENMASK(22, 0))
 
 struct mlx5e_accel_tx_psp_state {
diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en_main.c b/drivers/net/ethernet/mellanox/mlx5/core/en_main.c
index 775f0c6e55c955..2cb48b24d5eac5 100644
--- a/drivers/net/ethernet/mellanox/mlx5/core/en_main.c
+++ b/drivers/net/ethernet/mellanox/mlx5/core/en_main.c
@@ -6191,7 +6191,7 @@ static int mlx5e_init_nic_tx(struct mlx5e_priv *priv)
 	return 0;
 }
 
-static void mlx5e_nic_enable(struct mlx5e_priv *priv)
+static int mlx5e_nic_enable(struct mlx5e_priv *priv)
 {
 	struct net_device *netdev = priv->netdev;
 	struct mlx5_core_dev *mdev = priv->mdev;
@@ -6199,7 +6199,9 @@ static void mlx5e_nic_enable(struct mlx5e_priv *priv)
 
 	mlx5e_fs_init_l2_addr(priv->fs, netdev);
 	mlx5e_ipsec_init(priv);
-	mlx5e_psp_register(priv);
+	err = mlx5e_psp_register(priv);
+	if (err)
+		goto out_ipsec_cleanup;
 
 	err = mlx5e_macsec_init(priv);
 	if (err)
@@ -6222,7 +6224,7 @@ static void mlx5e_nic_enable(struct mlx5e_priv *priv)
 	mlx5e_pcie_cong_event_init(priv);
 	mlx5e_hv_vhca_stats_create(priv);
 	if (netdev->reg_state != NETREG_REGISTERED)
-		return;
+		return 0;
 	mlx5e_dcbnl_init_app(priv);
 
 	mlx5e_nic_set_rx_mode(priv);
@@ -6235,6 +6237,12 @@ static void mlx5e_nic_enable(struct mlx5e_priv *priv)
 	netdev_unlock(netdev);
 	netif_device_attach(netdev);
 	rtnl_unlock();
+
+	return 0;
+
+out_ipsec_cleanup:
+	mlx5e_ipsec_cleanup(priv);
+	return err;
 }
 
 static void mlx5e_nic_disable(struct mlx5e_priv *priv)
@@ -6616,13 +6624,18 @@ int mlx5e_attach_netdev(struct mlx5e_priv *priv)
 	if (err)
 		goto err_cleanup_tx;
 
-	if (profile->enable)
-		profile->enable(priv);
+	if (profile->enable) {
+		err = profile->enable(priv);
+		if (err)
+			goto err_cleanup_rx;
+	}
 
 	mlx5e_update_features(priv->netdev);
 
 	return 0;
 
+err_cleanup_rx:
+	profile->cleanup_rx(priv);
 err_cleanup_tx:
 	profile->cleanup_tx(priv);
 
diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en_rep.c b/drivers/net/ethernet/mellanox/mlx5/core/en_rep.c
index c8b76d301c92cf..603051ab1eaa4f 100644
--- a/drivers/net/ethernet/mellanox/mlx5/core/en_rep.c
+++ b/drivers/net/ethernet/mellanox/mlx5/core/en_rep.c
@@ -1262,9 +1262,11 @@ static void mlx5e_cleanup_rep_tx(struct mlx5e_priv *priv)
 	mlx5e_rep_neigh_cleanup(rpriv);
 }
 
-static void mlx5e_rep_enable(struct mlx5e_priv *priv)
+static int mlx5e_rep_enable(struct mlx5e_priv *priv)
 {
 	mlx5e_set_netdev_mtu_boundaries(priv);
+
+	return 0;
 }
 
 static void mlx5e_rep_disable(struct mlx5e_priv *priv)
@@ -1322,7 +1324,7 @@ static int uplink_rep_async_event(struct notifier_block *nb, unsigned long event
 	return NOTIFY_DONE;
 }
 
-static void mlx5e_uplink_rep_enable(struct mlx5e_priv *priv)
+static int mlx5e_uplink_rep_enable(struct mlx5e_priv *priv)
 {
 	struct net_device *netdev = priv->netdev;
 	struct mlx5_core_dev *mdev = priv->mdev;
@@ -1357,6 +1359,8 @@ static void mlx5e_uplink_rep_enable(struct mlx5e_priv *priv)
 	netdev_unlock(netdev);
 	netif_device_attach(netdev);
 	rtnl_unlock();
+
+	return 0;
 }
 
 static void mlx5e_uplink_rep_disable(struct mlx5e_priv *priv)

3/2 2026/07/07 21:40 llm patch-evaluator
0m Model:
gemini-3.1-pro-preview

Args:
null

Results:
null

Tokens:
							input: 24792
							output: 40
							thoughts: 457
						

Thoughts:
**Analyzing the Reachability of a Mellanox mlx5 Driver Patch**

Okay, so I've got this patch – seems like it tweaks the Mellanox mlx5 driver, specifically the PSP offload stuff. It touches a bunch of files: `psp.c`, `psp.h`, `psp_rxtx.c`, `en_main.c`, `en_rep.c`, `en.h`, and `fs.h`. Basically, it’s altering how flow steering rules are made and handled when we're offloading PSP tasks. It also looks like a callback in the `mlx5e_profile` is returning an `int` now instead of `void`.

My immediate concern is: Can I even *test* this patch in a virtualized environment? The mlx5 driver *requires* specific Mellanox hardware – ConnectX-4, 5, 6, or 7. Syzkaller, which is my go-to fuzzing tool, doesn't have Mellanox hardware. So, can QEMU emulate mlx5? I know QEMU emulates several NICs, like e1000, rtl8139, virtio-net, vmxnet3, and igb, but not usually mlx5 natively. I might be able to find a custom configuration, but it's not standard. There's no standard software emulation, either, since it's a hardware driver.

Syzkaller does have clever emulation mechanisms for other devices – it has `syz_usb_connect` for USB, `mac80211_hwsim` for wifi, `vkms` for DRM, and `vivid` for V4L2. For ethernet, it uses `tun`/`tap` or `veth`. But I don’t think there is a direct equivalent for emulating PCIe devices like mlx5.

So, realistically, it looks like this patch is unreachable within a standard Syzkaller setup. I'll need to go back and double-check to make absolutely sure there's no subtle way to trigger this mlx5 code without physical hardware. Is there some kind of mock driver or simulation layer? I'll run a kernel search for "mlx5" and see what it turns up.



4/2 2026/07/07 21:41 tool grepper
0m Args:
{
  "Expression": "mlx5_core_dev",
  "PathPrefix": "drivers/net/ethernet/mellanox/mlx5/"
}

Results:
{
  "Output": "\nFull output is too long, showing 500 out of 12338 lines.\nUse more precise expression if possible.\n\ndrivers/net/ethernet/mellanox/mlx5/core/alloc.c=58=struct mlx5_dma_pool {\n--\ndrivers/net/ethernet/mellanox/mlx5/core/alloc.c-61-\tstruct list_head page_list;\ndrivers/net/ethernet/mellanox/mlx5/core/alloc.c:62:\tstruct mlx5_core_dev *dev;\ndrivers/net/ethernet/mellanox/mlx5/core/alloc.c-63-\tint node;\n--\ndrivers/net/ethernet/mellanox/mlx5/core/alloc.c=79=struct mlx5_dma_pool_stats {\n--\ndrivers/net/ethernet/mellanox/mlx5/core/alloc.c-89-\ndrivers/net/ethernet/mellanox/mlx5/core/alloc.c:90:static void *mlx5_dma_zalloc_coherent_node(struct mlx5_core_dev *dev,\ndrivers/net/ethernet/mellanox/mlx5/core/alloc.c-91-\t\t\t\t\t   size_t size, dma_addr_t *dma_handle,\n--\ndrivers/net/ethernet/mellanox/mlx5/core/alloc.c=109=static void mlx5_dma_pool_destroy(struct mlx5_dma_pool *pool)\n--\ndrivers/net/ethernet/mellanox/mlx5/core/alloc.c-114-\ndrivers/net/ethernet/mellanox/mlx5/core/alloc.c:115:static struct mlx5_dma_pool *mlx5_dma_pool_create(struct mlx5_core_dev *dev,\ndrivers/net/ethernet/mellanox/mlx5/core/alloc.c-116-\t\t\t\t\t\t  int node, u8 block_shift)\n--\ndrivers/net/ethernet/mellanox/mlx5/core/alloc.c=133=mlx5_dma_pool_page_alloc(struct mlx5_dma_pool *pool)\n--\ndrivers/net/ethernet/mellanox/mlx5/core/alloc.c-162-\ndrivers/net/ethernet/mellanox/mlx5/core/alloc.c:163:static void mlx5_dma_pool_page_free(struct mlx5_core_dev *dev,\ndrivers/net/ethernet/mellanox/mlx5/core/alloc.c-164-\t\t\t\t    struct mlx5_dma_pool_page *page)\n--\ndrivers/net/ethernet/mellanox/mlx5/core/alloc.c=283=static struct mlx5_frag_buf_node_pools *\ndrivers/net/ethernet/mellanox/mlx5/core/alloc.c:284:mlx5_frag_buf_node_pools_create(struct mlx5_core_dev *dev, int node)\ndrivers/net/ethernet/mellanox/mlx5/core/alloc.c-285-{\n--\ndrivers/net/ethernet/mellanox/mlx5/core/alloc.c=307=mlx5_frag_buf_dma_pools_debugfs_show(struct seq_file *file, void *priv)\ndrivers/net/ethernet/mellanox/mlx5/core/alloc.c-308-{\ndrivers/net/ethernet/mellanox/mlx5/core/alloc.c:309:\tstruct mlx5_core_dev *dev = file-\u003eprivate;\ndrivers/net/ethernet/mellanox/mlx5/core/alloc.c-310-\tint node;\n--\ndrivers/net/ethernet/mellanox/mlx5/core/alloc.c=336=DEFINE_SHOW_ATTRIBUTE(mlx5_frag_buf_dma_pools_debugfs);\ndrivers/net/ethernet/mellanox/mlx5/core/alloc.c-337-\ndrivers/net/ethernet/mellanox/mlx5/core/alloc.c:338:void mlx5_frag_buf_pools_cleanup(struct mlx5_core_dev *dev)\ndrivers/net/ethernet/mellanox/mlx5/core/alloc.c-339-{\n--\ndrivers/net/ethernet/mellanox/mlx5/core/alloc.c-358-\ndrivers/net/ethernet/mellanox/mlx5/core/alloc.c:359:int mlx5_frag_buf_pools_init(struct mlx5_core_dev *dev)\ndrivers/net/ethernet/mellanox/mlx5/core/alloc.c-360-{\n--\ndrivers/net/ethernet/mellanox/mlx5/core/alloc.c-387-\ndrivers/net/ethernet/mellanox/mlx5/core/alloc.c:388:int mlx5_frag_buf_alloc_node(struct mlx5_core_dev *dev, int size,\ndrivers/net/ethernet/mellanox/mlx5/core/alloc.c-389-\t\t\t     struct mlx5_frag_buf *buf, int node)\n--\ndrivers/net/ethernet/mellanox/mlx5/core/alloc.c=425=EXPORT_SYMBOL_GPL(mlx5_frag_buf_alloc_node);\ndrivers/net/ethernet/mellanox/mlx5/core/alloc.c-426-\ndrivers/net/ethernet/mellanox/mlx5/core/alloc.c:427:void mlx5_frag_buf_free(struct mlx5_core_dev *dev, struct mlx5_frag_buf *buf)\ndrivers/net/ethernet/mellanox/mlx5/core/alloc.c-428-{\n--\ndrivers/net/ethernet/mellanox/mlx5/core/alloc.c=445=EXPORT_SYMBOL_GPL(mlx5_frag_buf_free);\ndrivers/net/ethernet/mellanox/mlx5/core/alloc.c-446-\ndrivers/net/ethernet/mellanox/mlx5/core/alloc.c:447:static struct mlx5_db_pgdir *mlx5_alloc_db_pgdir(struct mlx5_core_dev *dev,\ndrivers/net/ethernet/mellanox/mlx5/core/alloc.c-448-\t\t\t\t\t\t int node)\n--\ndrivers/net/ethernet/mellanox/mlx5/core/alloc.c=476=static int mlx5_alloc_db_from_pgdir(struct mlx5_db_pgdir *pgdir,\n--\ndrivers/net/ethernet/mellanox/mlx5/core/alloc.c-500-\ndrivers/net/ethernet/mellanox/mlx5/core/alloc.c:501:int mlx5_db_alloc_node(struct mlx5_core_dev *dev, struct mlx5_db *db, int node)\ndrivers/net/ethernet/mellanox/mlx5/core/alloc.c-502-{\n--\ndrivers/net/ethernet/mellanox/mlx5/core/alloc.c=528=EXPORT_SYMBOL_GPL(mlx5_db_alloc_node);\ndrivers/net/ethernet/mellanox/mlx5/core/alloc.c-529-\ndrivers/net/ethernet/mellanox/mlx5/core/alloc.c:530:void mlx5_db_free(struct mlx5_core_dev *dev, struct mlx5_db *db)\ndrivers/net/ethernet/mellanox/mlx5/core/alloc.c-531-{\n--\ndrivers/net/ethernet/mellanox/mlx5/core/cmd.c=283=static void poll_timeout(struct mlx5_cmd_work_ent *ent)\ndrivers/net/ethernet/mellanox/mlx5/core/cmd.c-284-{\ndrivers/net/ethernet/mellanox/mlx5/core/cmd.c:285:\tstruct mlx5_core_dev *dev = container_of(ent-\u003ecmd, struct mlx5_core_dev, cmd);\ndrivers/net/ethernet/mellanox/mlx5/core/cmd.c-286-\tu64 cmd_to_ms = mlx5_tout_ms(dev, CMD);\n--\ndrivers/net/ethernet/mellanox/mlx5/core/cmd.c=331=static void dump_buf(void *buf, int size, int data_only, int offset, int idx)\n--\ndrivers/net/ethernet/mellanox/mlx5/core/cmd.c-346-\ndrivers/net/ethernet/mellanox/mlx5/core/cmd.c:347:static int mlx5_internal_err_ret_value(struct mlx5_core_dev *dev, u16 op,\ndrivers/net/ethernet/mellanox/mlx5/core/cmd.c-348-\t\t\t\t       u32 *synd, u8 *status)\n--\ndrivers/net/ethernet/mellanox/mlx5/core/cmd.c=793=static int cmd_status_to_err(u8 status)\n--\ndrivers/net/ethernet/mellanox/mlx5/core/cmd.c-816-\ndrivers/net/ethernet/mellanox/mlx5/core/cmd.c:817:void mlx5_cmd_out_err(struct mlx5_core_dev *dev, u16 opcode, u16 op_mod, void *out)\ndrivers/net/ethernet/mellanox/mlx5/core/cmd.c-818-{\n--\ndrivers/net/ethernet/mellanox/mlx5/core/cmd.c=827=EXPORT_SYMBOL(mlx5_cmd_out_err);\ndrivers/net/ethernet/mellanox/mlx5/core/cmd.c-828-\ndrivers/net/ethernet/mellanox/mlx5/core/cmd.c:829:static void cmd_status_print(struct mlx5_core_dev *dev, void *in, void *out)\ndrivers/net/ethernet/mellanox/mlx5/core/cmd.c-830-{\n--\ndrivers/net/ethernet/mellanox/mlx5/core/cmd.c-844-\ndrivers/net/ethernet/mellanox/mlx5/core/cmd.c:845:int mlx5_cmd_check(struct mlx5_core_dev *dev, int err, void *in, void *out)\ndrivers/net/ethernet/mellanox/mlx5/core/cmd.c-846-{\n--\ndrivers/net/ethernet/mellanox/mlx5/core/cmd.c=872=EXPORT_SYMBOL(mlx5_cmd_check);\ndrivers/net/ethernet/mellanox/mlx5/core/cmd.c-873-\ndrivers/net/ethernet/mellanox/mlx5/core/cmd.c:874:static void dump_command(struct mlx5_core_dev *dev,\ndrivers/net/ethernet/mellanox/mlx5/core/cmd.c-875-\t\t\t struct mlx5_cmd_work_ent *ent, int input)\n--\ndrivers/net/ethernet/mellanox/mlx5/core/cmd.c-931-\ndrivers/net/ethernet/mellanox/mlx5/core/cmd.c:932:static void mlx5_cmd_comp_handler(struct mlx5_core_dev *dev, u64 vec, bool forced);\ndrivers/net/ethernet/mellanox/mlx5/core/cmd.c-933-\ndrivers/net/ethernet/mellanox/mlx5/core/cmd.c=934=static void cb_timeout_handler(struct work_struct *work)\n--\ndrivers/net/ethernet/mellanox/mlx5/core/cmd.c-939-\t\t\t\t\t\t     cb_timeout_work);\ndrivers/net/ethernet/mellanox/mlx5/core/cmd.c:940:\tstruct mlx5_core_dev *dev = container_of(ent-\u003ecmd, struct mlx5_core_dev,\ndrivers/net/ethernet/mellanox/mlx5/core/cmd.c-941-\t\t\t\t\t\t cmd);\n--\ndrivers/net/ethernet/mellanox/mlx5/core/cmd.c-960-\ndrivers/net/ethernet/mellanox/mlx5/core/cmd.c:961:static void free_msg(struct mlx5_core_dev *dev, struct mlx5_cmd_msg *msg);\ndrivers/net/ethernet/mellanox/mlx5/core/cmd.c:962:static void mlx5_free_cmd_msg(struct mlx5_core_dev *dev,\ndrivers/net/ethernet/mellanox/mlx5/core/cmd.c-963-\t\t\t      struct mlx5_cmd_msg *msg);\n--\ndrivers/net/ethernet/mellanox/mlx5/core/cmd.c=965=static bool opcode_allowed(struct mlx5_cmd *cmd, u16 opcode)\n--\ndrivers/net/ethernet/mellanox/mlx5/core/cmd.c-972-\ndrivers/net/ethernet/mellanox/mlx5/core/cmd.c:973:bool mlx5_cmd_is_down(struct mlx5_core_dev *dev)\ndrivers/net/ethernet/mellanox/mlx5/core/cmd.c-974-{\n--\ndrivers/net/ethernet/mellanox/mlx5/core/cmd.c=980=static void cmd_work_handler(struct work_struct *work)\n--\ndrivers/net/ethernet/mellanox/mlx5/core/cmd.c-985-\tstruct mlx5_cmd_layout *lay;\ndrivers/net/ethernet/mellanox/mlx5/core/cmd.c:986:\tstruct mlx5_core_dev *dev;\ndrivers/net/ethernet/mellanox/mlx5/core/cmd.c-987-\tunsigned long timeout;\n--\ndrivers/net/ethernet/mellanox/mlx5/core/cmd.c-993-\ndrivers/net/ethernet/mellanox/mlx5/core/cmd.c:994:\tdev = container_of(cmd, struct mlx5_core_dev, cmd);\ndrivers/net/ethernet/mellanox/mlx5/core/cmd.c-995-\ttimeout = msecs_to_jiffies(mlx5_tout_ms(dev, CMD));\n--\ndrivers/net/ethernet/mellanox/mlx5/core/cmd.c=1140=enum {\n--\ndrivers/net/ethernet/mellanox/mlx5/core/cmd.c-1143-\ndrivers/net/ethernet/mellanox/mlx5/core/cmd.c:1144:static void wait_func_handle_exec_timeout(struct mlx5_core_dev *dev,\ndrivers/net/ethernet/mellanox/mlx5/core/cmd.c-1145-\t\t\t\t\t  struct mlx5_cmd_work_ent *ent)\n--\ndrivers/net/ethernet/mellanox/mlx5/core/cmd.c-1168-\ndrivers/net/ethernet/mellanox/mlx5/core/cmd.c:1169:static int wait_func(struct mlx5_core_dev *dev, struct mlx5_cmd_work_ent *ent)\ndrivers/net/ethernet/mellanox/mlx5/core/cmd.c-1170-{\n--\ndrivers/net/ethernet/mellanox/mlx5/core/cmd.c-1215- */\ndrivers/net/ethernet/mellanox/mlx5/core/cmd.c:1216:static bool mlx5_cmd_all_stalled(struct mlx5_core_dev *dev)\ndrivers/net/ethernet/mellanox/mlx5/core/cmd.c-1217-{\n--\ndrivers/net/ethernet/mellanox/mlx5/core/cmd.c-1258- */\ndrivers/net/ethernet/mellanox/mlx5/core/cmd.c:1259:static int mlx5_cmd_invoke(struct mlx5_core_dev *dev, struct mlx5_cmd_msg *in,\ndrivers/net/ethernet/mellanox/mlx5/core/cmd.c-1260-\t\t\t   struct mlx5_cmd_msg *out, void *uout, int uout_size,\n--\ndrivers/net/ethernet/mellanox/mlx5/core/cmd.c=1337=static ssize_t dbg_write(struct file *filp, const char __user *buf,\n--\ndrivers/net/ethernet/mellanox/mlx5/core/cmd.c-1339-{\ndrivers/net/ethernet/mellanox/mlx5/core/cmd.c:1340:\tstruct mlx5_core_dev *dev = filp-\u003eprivate_data;\ndrivers/net/ethernet/mellanox/mlx5/core/cmd.c-1341-\tstruct mlx5_cmd_debug *dbg = \u0026dev-\u003ecmd.dbg;\n--\ndrivers/net/ethernet/mellanox/mlx5/core/cmd.c=1404=static int mlx5_copy_from_msg(void *to, struct mlx5_cmd_msg *from, int size)\n--\ndrivers/net/ethernet/mellanox/mlx5/core/cmd.c-1436-\ndrivers/net/ethernet/mellanox/mlx5/core/cmd.c:1437:static struct mlx5_cmd_mailbox *alloc_cmd_box(struct mlx5_core_dev *dev,\ndrivers/net/ethernet/mellanox/mlx5/core/cmd.c-1438-\t\t\t\t\t      gfp_t flags)\n--\ndrivers/net/ethernet/mellanox/mlx5/core/cmd.c-1457-\ndrivers/net/ethernet/mellanox/mlx5/core/cmd.c:1458:static void free_cmd_box(struct mlx5_core_dev *dev,\ndrivers/net/ethernet/mellanox/mlx5/core/cmd.c-1459-\t\t\t struct mlx5_cmd_mailbox *mailbox)\n--\ndrivers/net/ethernet/mellanox/mlx5/core/cmd.c-1464-\ndrivers/net/ethernet/mellanox/mlx5/core/cmd.c:1465:static struct mlx5_cmd_msg *mlx5_alloc_cmd_msg(struct mlx5_core_dev *dev,\ndrivers/net/ethernet/mellanox/mlx5/core/cmd.c-1466-\t\t\t\t\t       gfp_t flags, int size,\n--\ndrivers/net/ethernet/mellanox/mlx5/core/cmd.c-1511-\ndrivers/net/ethernet/mellanox/mlx5/core/cmd.c:1512:static void mlx5_free_cmd_msg(struct mlx5_core_dev *dev,\ndrivers/net/ethernet/mellanox/mlx5/core/cmd.c-1513-\t\t\t      struct mlx5_cmd_msg *msg)\n--\ndrivers/net/ethernet/mellanox/mlx5/core/cmd.c=1526=static ssize_t data_write(struct file *filp, const char __user *buf,\n--\ndrivers/net/ethernet/mellanox/mlx5/core/cmd.c-1528-{\ndrivers/net/ethernet/mellanox/mlx5/core/cmd.c:1529:\tstruct mlx5_core_dev *dev = filp-\u003eprivate_data;\ndrivers/net/ethernet/mellanox/mlx5/core/cmd.c-1530-\tstruct mlx5_cmd_debug *dbg = \u0026dev-\u003ecmd.dbg;\n--\ndrivers/net/ethernet/mellanox/mlx5/core/cmd.c=1550=static ssize_t data_read(struct file *filp, char __user *buf, size_t count,\n--\ndrivers/net/ethernet/mellanox/mlx5/core/cmd.c-1552-{\ndrivers/net/ethernet/mellanox/mlx5/core/cmd.c:1553:\tstruct mlx5_core_dev *dev = filp-\u003eprivate_data;\ndrivers/net/ethernet/mellanox/mlx5/core/cmd.c-1554-\tstruct mlx5_cmd_debug *dbg = \u0026dev-\u003ecmd.dbg;\n--\ndrivers/net/ethernet/mellanox/mlx5/core/cmd.c=1570=static ssize_t outlen_read(struct file *filp, char __user *buf, size_t count,\n--\ndrivers/net/ethernet/mellanox/mlx5/core/cmd.c-1572-{\ndrivers/net/ethernet/mellanox/mlx5/core/cmd.c:1573:\tstruct mlx5_core_dev *dev = filp-\u003eprivate_data;\ndrivers/net/ethernet/mellanox/mlx5/core/cmd.c-1574-\tstruct mlx5_cmd_debug *dbg = \u0026dev-\u003ecmd.dbg;\n--\ndrivers/net/ethernet/mellanox/mlx5/core/cmd.c=1585=static ssize_t outlen_write(struct file *filp, const char __user *buf,\n--\ndrivers/net/ethernet/mellanox/mlx5/core/cmd.c-1587-{\ndrivers/net/ethernet/mellanox/mlx5/core/cmd.c:1588:\tstruct mlx5_core_dev *dev = filp-\u003eprivate_data;\ndrivers/net/ethernet/mellanox/mlx5/core/cmd.c-1589-\tstruct mlx5_cmd_debug *dbg = \u0026dev-\u003ecmd.dbg;\n--\ndrivers/net/ethernet/mellanox/mlx5/core/cmd.c=1621=static const struct file_operations olfops = {\n--\ndrivers/net/ethernet/mellanox/mlx5/core/cmd.c-1627-\ndrivers/net/ethernet/mellanox/mlx5/core/cmd.c:1628:static void set_wqname(struct mlx5_core_dev *dev)\ndrivers/net/ethernet/mellanox/mlx5/core/cmd.c-1629-{\n--\ndrivers/net/ethernet/mellanox/mlx5/core/cmd.c-1635-\ndrivers/net/ethernet/mellanox/mlx5/core/cmd.c:1636:static void clean_debug_files(struct mlx5_core_dev *dev)\ndrivers/net/ethernet/mellanox/mlx5/core/cmd.c-1637-{\n--\ndrivers/net/ethernet/mellanox/mlx5/core/cmd.c-1645-\ndrivers/net/ethernet/mellanox/mlx5/core/cmd.c:1646:static void create_debugfs_files(struct mlx5_core_dev *dev)\ndrivers/net/ethernet/mellanox/mlx5/core/cmd.c-1647-{\n--\ndrivers/net/ethernet/mellanox/mlx5/core/cmd.c-1658-\ndrivers/net/ethernet/mellanox/mlx5/core/cmd.c:1659:void mlx5_cmd_allowed_opcode(struct mlx5_core_dev *dev, u16 opcode)\ndrivers/net/ethernet/mellanox/mlx5/core/cmd.c-1660-{\n--\ndrivers/net/ethernet/mellanox/mlx5/core/cmd.c-1674-\ndrivers/net/ethernet/mellanox/mlx5/core/cmd.c:1675:static void mlx5_cmd_change_mod(struct mlx5_core_dev *dev, int mode)\ndrivers/net/ethernet/mellanox/mlx5/core/cmd.c-1676-{\n--\ndrivers/net/ethernet/mellanox/mlx5/core/cmd.c=1691=static int cmd_comp_notifier(struct notifier_block *nb,\n--\ndrivers/net/ethernet/mellanox/mlx5/core/cmd.c-1693-{\ndrivers/net/ethernet/mellanox/mlx5/core/cmd.c:1694:\tstruct mlx5_core_dev *dev;\ndrivers/net/ethernet/mellanox/mlx5/core/cmd.c-1695-\tstruct mlx5_cmd *cmd;\n--\ndrivers/net/ethernet/mellanox/mlx5/core/cmd.c-1698-\tcmd = mlx5_nb_cof(nb, struct mlx5_cmd, nb);\ndrivers/net/ethernet/mellanox/mlx5/core/cmd.c:1699:\tdev = container_of(cmd, struct mlx5_core_dev, cmd);\ndrivers/net/ethernet/mellanox/mlx5/core/cmd.c-1700-\teqe = data;\n--\ndrivers/net/ethernet/mellanox/mlx5/core/cmd.c-1708-}\ndrivers/net/ethernet/mellanox/mlx5/core/cmd.c:1709:void mlx5_cmd_use_events(struct mlx5_core_dev *dev)\ndrivers/net/ethernet/mellanox/mlx5/core/cmd.c-1710-{\n--\ndrivers/net/ethernet/mellanox/mlx5/core/cmd.c-1715-\ndrivers/net/ethernet/mellanox/mlx5/core/cmd.c:1716:void mlx5_cmd_use_polling(struct mlx5_core_dev *dev)\ndrivers/net/ethernet/mellanox/mlx5/core/cmd.c-1717-{\n--\ndrivers/net/ethernet/mellanox/mlx5/core/cmd.c-1721-\ndrivers/net/ethernet/mellanox/mlx5/core/cmd.c:1722:static void free_msg(struct mlx5_core_dev *dev, struct mlx5_cmd_msg *msg)\ndrivers/net/ethernet/mellanox/mlx5/core/cmd.c-1723-{\n--\ndrivers/net/ethernet/mellanox/mlx5/core/cmd.c-1734-\ndrivers/net/ethernet/mellanox/mlx5/core/cmd.c:1735:static void mlx5_cmd_comp_handler(struct mlx5_core_dev *dev, u64 vec, bool forced)\ndrivers/net/ethernet/mellanox/mlx5/core/cmd.c-1736-{\n--\ndrivers/net/ethernet/mellanox/mlx5/core/cmd.c-1838-\ndrivers/net/ethernet/mellanox/mlx5/core/cmd.c:1839:static void mlx5_cmd_trigger_completions(struct mlx5_core_dev *dev)\ndrivers/net/ethernet/mellanox/mlx5/core/cmd.c-1840-{\n--\ndrivers/net/ethernet/mellanox/mlx5/core/cmd.c-1873-\ndrivers/net/ethernet/mellanox/mlx5/core/cmd.c:1874:void mlx5_cmd_flush(struct mlx5_core_dev *dev)\ndrivers/net/ethernet/mellanox/mlx5/core/cmd.c-1875-{\n--\ndrivers/net/ethernet/mellanox/mlx5/core/cmd.c-1896-\ndrivers/net/ethernet/mellanox/mlx5/core/cmd.c:1897:static struct mlx5_cmd_msg *alloc_msg(struct mlx5_core_dev *dev, int in_size,\ndrivers/net/ethernet/mellanox/mlx5/core/cmd.c-1898-\t\t\t\t      gfp_t gfp)\n--\ndrivers/net/ethernet/mellanox/mlx5/core/cmd.c=1935=static int is_manage_pages(void *in)\n--\ndrivers/net/ethernet/mellanox/mlx5/core/cmd.c-1939-\ndrivers/net/ethernet/mellanox/mlx5/core/cmd.c:1940:static bool mlx5_has_privileged_uid(struct mlx5_core_dev *dev)\ndrivers/net/ethernet/mellanox/mlx5/core/cmd.c-1941-{\n--\ndrivers/net/ethernet/mellanox/mlx5/core/cmd.c-1944-\ndrivers/net/ethernet/mellanox/mlx5/core/cmd.c:1945:static bool mlx5_cmd_is_privileged_uid(struct mlx5_core_dev *dev,\ndrivers/net/ethernet/mellanox/mlx5/core/cmd.c-1946-\t\t\t\t       u16 uid)\n--\ndrivers/net/ethernet/mellanox/mlx5/core/cmd.c-1954- */\ndrivers/net/ethernet/mellanox/mlx5/core/cmd.c:1955:static int cmd_exec(struct mlx5_core_dev *dev, void *in, int in_size, void *out,\ndrivers/net/ethernet/mellanox/mlx5/core/cmd.c-1956-\t\t    int out_size, mlx5_cmd_cbk_t callback, void *context,\n--\ndrivers/net/ethernet/mellanox/mlx5/core/cmd.c-2035-\ndrivers/net/ethernet/mellanox/mlx5/core/cmd.c:2036:static void mlx5_cmd_err_trace(struct mlx5_core_dev *dev, u16 opcode, u16 op_mod, void *out)\ndrivers/net/ethernet/mellanox/mlx5/core/cmd.c-2037-{\n--\ndrivers/net/ethernet/mellanox/mlx5/core/cmd.c-2045-\ndrivers/net/ethernet/mellanox/mlx5/core/cmd.c:2046:static void cmd_status_log(struct mlx5_core_dev *dev, u16 opcode, u8 status,\ndrivers/net/ethernet/mellanox/mlx5/core/cmd.c-2047-\t\t\t   u32 syndrome, int err)\n--\ndrivers/net/ethernet/mellanox/mlx5/core/cmd.c-2071-/* preserve -EREMOTEIO for outbox.status != OK, otherwise return err as is */\ndrivers/net/ethernet/mellanox/mlx5/core/cmd.c:2072:static int cmd_status_err(struct mlx5_core_dev *dev, int err, u16 opcode, u16 op_mod, void *out)\ndrivers/net/ethernet/mellanox/mlx5/core/cmd.c-2073-{\n--\ndrivers/net/ethernet/mellanox/mlx5/core/cmd.c-2106- */\ndrivers/net/ethernet/mellanox/mlx5/core/cmd.c:2107:int mlx5_cmd_do(struct mlx5_core_dev *dev, void *in, int in_size, void *out, int out_size)\ndrivers/net/ethernet/mellanox/mlx5/core/cmd.c-2108-{\n--\ndrivers/net/ethernet/mellanox/mlx5/core/cmd.c=2115=EXPORT_SYMBOL(mlx5_cmd_do);\n--\ndrivers/net/ethernet/mellanox/mlx5/core/cmd.c-2128- */\ndrivers/net/ethernet/mellanox/mlx5/core/cmd.c:2129:int mlx5_cmd_exec(struct mlx5_core_dev *dev, void *in, int in_size, void *out,\ndrivers/net/ethernet/mellanox/mlx5/core/cmd.c-2130-\t\t  int out_size)\n--\ndrivers/net/ethernet/mellanox/mlx5/core/cmd.c=2136=EXPORT_SYMBOL(mlx5_cmd_exec);\n--\ndrivers/net/ethernet/mellanox/mlx5/core/cmd.c-2151- */\ndrivers/net/ethernet/mellanox/mlx5/core/cmd.c:2152:int mlx5_cmd_exec_polling(struct mlx5_core_dev *dev, void *in, int in_size,\ndrivers/net/ethernet/mellanox/mlx5/core/cmd.c-2153-\t\t\t  void *out, int out_size)\n--\ndrivers/net/ethernet/mellanox/mlx5/core/cmd.c=2162=EXPORT_SYMBOL(mlx5_cmd_exec_polling);\ndrivers/net/ethernet/mellanox/mlx5/core/cmd.c-2163-\ndrivers/net/ethernet/mellanox/mlx5/core/cmd.c:2164:void mlx5_cmd_init_async_ctx(struct mlx5_core_dev *dev,\ndrivers/net/ethernet/mellanox/mlx5/core/cmd.c-2165-\t\t\t     struct mlx5_async_ctx *ctx)\n--\ndrivers/net/ethernet/mellanox/mlx5/core/cmd.c=2189=static void mlx5_cmd_exec_cb_handler(int status, void *_work)\n--\ndrivers/net/ethernet/mellanox/mlx5/core/cmd.c-2192-\tstruct mlx5_async_ctx *ctx;\ndrivers/net/ethernet/mellanox/mlx5/core/cmd.c:2193:\tstruct mlx5_core_dev *dev;\ndrivers/net/ethernet/mellanox/mlx5/core/cmd.c-2194-\tbool throttle_locked;\n--\ndrivers/net/ethernet/mellanox/mlx5/core/cmd.c=2214=int mlx5_cmd_exec_cb(struct mlx5_async_ctx *ctx, void *in, int in_size,\n--\ndrivers/net/ethernet/mellanox/mlx5/core/cmd.c-2217-{\ndrivers/net/ethernet/mellanox/mlx5/core/cmd.c:2218:\tstruct mlx5_core_dev *dev = ctx-\u003edev;\ndrivers/net/ethernet/mellanox/mlx5/core/cmd.c-2219-\tu16 uid;\n--\ndrivers/net/ethernet/mellanox/mlx5/core/cmd.c=2268=EXPORT_SYMBOL(mlx5_cmd_exec_cb);\ndrivers/net/ethernet/mellanox/mlx5/core/cmd.c-2269-\ndrivers/net/ethernet/mellanox/mlx5/core/cmd.c:2270:int mlx5_cmd_allow_other_vhca_access(struct mlx5_core_dev *dev,\ndrivers/net/ethernet/mellanox/mlx5/core/cmd.c-2271-\t\t\t\t     struct mlx5_cmd_allow_other_vhca_access_attr *attr)\n--\ndrivers/net/ethernet/mellanox/mlx5/core/cmd.c-2289-\ndrivers/net/ethernet/mellanox/mlx5/core/cmd.c:2290:int mlx5_cmd_alias_obj_create(struct mlx5_core_dev *dev,\ndrivers/net/ethernet/mellanox/mlx5/core/cmd.c-2291-\t\t\t      struct mlx5_cmd_alias_obj_create_attr *alias_attr,\n--\ndrivers/net/ethernet/mellanox/mlx5/core/cmd.c-2325-\ndrivers/net/ethernet/mellanox/mlx5/core/cmd.c:2326:int mlx5_cmd_alias_obj_destroy(struct mlx5_core_dev *dev, u32 obj_id,\ndrivers/net/ethernet/mellanox/mlx5/core/cmd.c-2327-\t\t\t       u16 obj_type)\n--\ndrivers/net/ethernet/mellanox/mlx5/core/cmd.c-2338-\ndrivers/net/ethernet/mellanox/mlx5/core/cmd.c:2339:static void destroy_msg_cache(struct mlx5_core_dev *dev)\ndrivers/net/ethernet/mellanox/mlx5/core/cmd.c-2340-{\n--\ndrivers/net/ethernet/mellanox/mlx5/core/cmd.c=2359=static unsigned cmd_cache_ent_size[MLX5_NUM_COMMAND_CACHES] = {\n--\ndrivers/net/ethernet/mellanox/mlx5/core/cmd.c-2366-\ndrivers/net/ethernet/mellanox/mlx5/core/cmd.c:2367:static void create_msg_cache(struct mlx5_core_dev *dev)\ndrivers/net/ethernet/mellanox/mlx5/core/cmd.c-2368-{\n--\ndrivers/net/ethernet/mellanox/mlx5/core/cmd.c-2392-\ndrivers/net/ethernet/mellanox/mlx5/core/cmd.c:2393:static int alloc_cmd_page(struct mlx5_core_dev *dev, struct mlx5_cmd *cmd)\ndrivers/net/ethernet/mellanox/mlx5/core/cmd.c-2394-{\n--\ndrivers/net/ethernet/mellanox/mlx5/core/cmd.c-2421-\ndrivers/net/ethernet/mellanox/mlx5/core/cmd.c:2422:static void free_cmd_page(struct mlx5_core_dev *dev, struct mlx5_cmd *cmd)\ndrivers/net/ethernet/mellanox/mlx5/core/cmd.c-2423-{\n--\ndrivers/net/ethernet/mellanox/mlx5/core/cmd.c-2427-\ndrivers/net/ethernet/mellanox/mlx5/core/cmd.c:2428:static u16 cmdif_rev(struct mlx5_core_dev *dev)\ndrivers/net/ethernet/mellanox/mlx5/core/cmd.c-2429-{\n--\ndrivers/net/ethernet/mellanox/mlx5/core/cmd.c-2432-\ndrivers/net/ethernet/mellanox/mlx5/core/cmd.c:2433:int mlx5_cmd_init(struct mlx5_core_dev *dev)\ndrivers/net/ethernet/mellanox/mlx5/core/cmd.c-2434-{\n--\ndrivers/net/ethernet/mellanox/mlx5/core/cmd.c-2453-\ndrivers/net/ethernet/mellanox/mlx5/core/cmd.c:2454:void mlx5_cmd_cleanup(struct mlx5_core_dev *dev)\ndrivers/net/ethernet/mellanox/mlx5/core/cmd.c-2455-{\n--\ndrivers/net/ethernet/mellanox/mlx5/core/cmd.c-2461-\ndrivers/net/ethernet/mellanox/mlx5/core/cmd.c:2462:int mlx5_cmd_enable(struct mlx5_core_dev *dev)\ndrivers/net/ethernet/mellanox/mlx5/core/cmd.c-2463-{\n--\ndrivers/net/ethernet/mellanox/mlx5/core/cmd.c-2547-\ndrivers/net/ethernet/mellanox/mlx5/core/cmd.c:2548:void mlx5_cmd_disable(struct mlx5_core_dev *dev)\ndrivers/net/ethernet/mellanox/mlx5/core/cmd.c-2549-{\n--\ndrivers/net/ethernet/mellanox/mlx5/core/cmd.c-2559-\ndrivers/net/ethernet/mellanox/mlx5/core/cmd.c:2560:void mlx5_cmd_set_state(struct mlx5_core_dev *dev,\ndrivers/net/ethernet/mellanox/mlx5/core/cmd.c-2561-\t\t\tenum mlx5_cmdif_state cmdif_state)\n--\ndrivers/net/ethernet/mellanox/mlx5/core/cmd.c-2565-\ndrivers/net/ethernet/mellanox/mlx5/core/cmd.c:2566:int mlx5_cmd_add_privileged_uid(struct mlx5_core_dev *dev, u16 uid)\ndrivers/net/ethernet/mellanox/mlx5/core/cmd.c-2567-{\n--\ndrivers/net/ethernet/mellanox/mlx5/core/cmd.c=2571=EXPORT_SYMBOL(mlx5_cmd_add_privileged_uid);\ndrivers/net/ethernet/mellanox/mlx5/core/cmd.c-2572-\ndrivers/net/ethernet/mellanox/mlx5/core/cmd.c:2573:void mlx5_cmd_remove_privileged_uid(struct mlx5_core_dev *dev, u16 uid)\ndrivers/net/ethernet/mellanox/mlx5/core/cmd.c-2574-{\n--\ndrivers/net/ethernet/mellanox/mlx5/core/cq.c=100=static void mlx5_core_cq_dummy_cb(struct mlx5_core_cq *cq, struct mlx5_eqe *eqe)\n--\ndrivers/net/ethernet/mellanox/mlx5/core/cq.c-107-/* Callers must verify outbox status in case of err */\ndrivers/net/ethernet/mellanox/mlx5/core/cq.c:108:int mlx5_create_cq(struct mlx5_core_dev *dev, struct mlx5_core_cq *cq,\ndrivers/net/ethernet/mellanox/mlx5/core/cq.c-109-\t\t   u32 *in, int inlen, u32 *out, int outlen)\n--\ndrivers/net/ethernet/mellanox/mlx5/core/cq.c=178=EXPORT_SYMBOL(mlx5_create_cq);\n--\ndrivers/net/ethernet/mellanox/mlx5/core/cq.c-180-/* oubox is checked and err val is normalized */\ndrivers/net/ethernet/mellanox/mlx5/core/cq.c:181:int mlx5_core_create_cq(struct mlx5_core_dev *dev, struct mlx5_core_cq *cq,\ndrivers/net/ethernet/mellanox/mlx5/core/cq.c-182-\t\t\tu32 *in, int inlen, u32 *out, int outlen)\n--\ndrivers/net/ethernet/mellanox/mlx5/core/cq.c=188=EXPORT_SYMBOL(mlx5_core_create_cq);\ndrivers/net/ethernet/mellanox/mlx5/core/cq.c-189-\ndrivers/net/ethernet/mellanox/mlx5/core/cq.c:190:int mlx5_core_destroy_cq(struct mlx5_core_dev *dev, struct mlx5_core_cq *cq)\ndrivers/net/ethernet/mellanox/mlx5/core/cq.c-191-{\n--\ndrivers/net/ethernet/mellanox/mlx5/core/cq.c=213=EXPORT_SYMBOL(mlx5_core_destroy_cq);\ndrivers/net/ethernet/mellanox/mlx5/core/cq.c-214-\ndrivers/net/ethernet/mellanox/mlx5/core/cq.c:215:int mlx5_core_query_cq(struct mlx5_core_dev *dev, struct mlx5_core_cq *cq,\ndrivers/net/ethernet/mellanox/mlx5/core/cq.c-216-\t\t       u32 *out)\n--\ndrivers/net/ethernet/mellanox/mlx5/core/cq.c=224=EXPORT_SYMBOL(mlx5_core_query_cq);\ndrivers/net/ethernet/mellanox/mlx5/core/cq.c-225-\ndrivers/net/ethernet/mellanox/mlx5/core/cq.c:226:int mlx5_core_modify_cq(struct mlx5_core_dev *dev, struct mlx5_core_cq *cq,\ndrivers/net/ethernet/mellanox/mlx5/core/cq.c-227-\t\t\tu32 *in, int inlen)\n--\ndrivers/net/ethernet/mellanox/mlx5/core/cq.c=235=EXPORT_SYMBOL(mlx5_core_modify_cq);\ndrivers/net/ethernet/mellanox/mlx5/core/cq.c-236-\ndrivers/net/ethernet/mellanox/mlx5/core/cq.c:237:int mlx5_core_modify_cq_moderation(struct mlx5_core_dev *dev,\ndrivers/net/ethernet/mellanox/mlx5/core/cq.c-238-\t\t\t\t   struct mlx5_core_cq *cq,\n--\ndrivers/net/ethernet/mellanox/mlx5/core/debugfs.c=96=void mlx5_unregister_debugfs(void)\n--\ndrivers/net/ethernet/mellanox/mlx5/core/debugfs.c-100-\ndrivers/net/ethernet/mellanox/mlx5/core/debugfs.c:101:struct dentry *mlx5_debugfs_get_dev_root(struct mlx5_core_dev *dev)\ndrivers/net/ethernet/mellanox/mlx5/core/debugfs.c-102-{\n--\ndrivers/net/ethernet/mellanox/mlx5/core/debugfs.c=105=EXPORT_SYMBOL(mlx5_debugfs_get_dev_root);\ndrivers/net/ethernet/mellanox/mlx5/core/debugfs.c-106-\ndrivers/net/ethernet/mellanox/mlx5/core/debugfs.c:107:void mlx5_qp_debugfs_init(struct mlx5_core_dev *dev)\ndrivers/net/ethernet/mellanox/mlx5/core/debugfs.c-108-{\n--\ndrivers/net/ethernet/mellanox/mlx5/core/debugfs.c=111=EXPORT_SYMBOL(mlx5_qp_debugfs_init);\ndrivers/net/ethernet/mellanox/mlx5/core/debugfs.c-112-\ndrivers/net/ethernet/mellanox/mlx5/core/debugfs.c:113:void mlx5_qp_debugfs_cleanup(struct mlx5_core_dev *dev)\ndrivers/net/ethernet/mellanox/mlx5/core/debugfs.c-114-{\n--\ndrivers/net/ethernet/mellanox/mlx5/core/debugfs.c=117=EXPORT_SYMBOL(mlx5_qp_debugfs_cleanup);\ndrivers/net/ethernet/mellanox/mlx5/core/debugfs.c-118-\ndrivers/net/ethernet/mellanox/mlx5/core/debugfs.c:119:void mlx5_eq_debugfs_init(struct mlx5_core_dev *dev)\ndrivers/net/ethernet/mellanox/mlx5/core/debugfs.c-120-{\n--\ndrivers/net/ethernet/mellanox/mlx5/core/debugfs.c-123-\ndrivers/net/ethernet/mellanox/mlx5/core/debugfs.c:124:void mlx5_eq_debugfs_cleanup(struct mlx5_core_dev *dev)\ndrivers/net/ethernet/mellanox/mlx5/core/debugfs.c-125-{\n--\ndrivers/net/ethernet/mellanox/mlx5/core/debugfs.c=202=mlx5_cmdif_alloc_stats(struct xarray *stats_xa, int opcode)\n--\ndrivers/net/ethernet/mellanox/mlx5/core/debugfs.c-218-\ndrivers/net/ethernet/mellanox/mlx5/core/debugfs.c:219:void mlx5_cmdif_debugfs_init(struct mlx5_core_dev *dev)\ndrivers/net/ethernet/mellanox/mlx5/core/debugfs.c-220-{\n--\ndrivers/net/ethernet/mellanox/mlx5/core/debugfs.c-258-\ndrivers/net/ethernet/mellanox/mlx5/core/debugfs.c:259:void mlx5_cmdif_debugfs_cleanup(struct mlx5_core_dev *dev)\ndrivers/net/ethernet/mellanox/mlx5/core/debugfs.c-260-{\n--\ndrivers/net/ethernet/mellanox/mlx5/core/debugfs.c-269-\ndrivers/net/ethernet/mellanox/mlx5/core/debugfs.c:270:void mlx5_cq_debugfs_init(struct mlx5_core_dev *dev)\ndrivers/net/ethernet/mellanox/mlx5/core/debugfs.c-271-{\n--\ndrivers/net/ethernet/mellanox/mlx5/core/debugfs.c-274-\ndrivers/net/ethernet/mellanox/mlx5/core/debugfs.c:275:void mlx5_cq_debugfs_cleanup(struct mlx5_core_dev *dev)\ndrivers/net/ethernet/mellanox/mlx5/core/debugfs.c-276-{\n--\ndrivers/net/ethernet/mellanox/mlx5/core/debugfs.c-279-\ndrivers/net/ethernet/mellanox/mlx5/core/debugfs.c:280:void mlx5_pages_debugfs_init(struct mlx5_core_dev *dev)\ndrivers/net/ethernet/mellanox/mlx5/core/debugfs.c-281-{\n--\ndrivers/net/ethernet/mellanox/mlx5/core/debugfs.c-293-\ndrivers/net/ethernet/mellanox/mlx5/core/debugfs.c:294:void mlx5_pages_debugfs_cleanup(struct mlx5_core_dev *dev)\ndrivers/net/ethernet/mellanox/mlx5/core/debugfs.c-295-{\n--\ndrivers/net/ethernet/mellanox/mlx5/core/debugfs.c-298-\ndrivers/net/ethernet/mellanox/mlx5/core/debugfs.c:299:void mlx5_pages_by_func_type_debugfs_init(struct mlx5_core_dev *dev)\ndrivers/net/ethernet/mellanox/mlx5/core/debugfs.c-300-{\n--\ndrivers/net/ethernet/mellanox/mlx5/core/debugfs.c-322-\ndrivers/net/ethernet/mellanox/mlx5/core/debugfs.c:323:void mlx5_pages_by_func_type_debugfs_cleanup(struct mlx5_core_dev *dev)\ndrivers/net/ethernet/mellanox/mlx5/core/debugfs.c-324-{\n--\ndrivers/net/ethernet/mellanox/mlx5/core/debugfs.c-336-\ndrivers/net/ethernet/mellanox/mlx5/core/debugfs.c:337:static u64 qp_read_field(struct mlx5_core_dev *dev, struct mlx5_core_qp *qp,\ndrivers/net/ethernet/mellanox/mlx5/core/debugfs.c-338-\t\t\t int index, int *is_str)\n--\ndrivers/net/ethernet/mellanox/mlx5/core/debugfs.c-416-\ndrivers/net/ethernet/mellanox/mlx5/core/debugfs.c:417:static u64 eq_read_field(struct mlx5_core_dev *dev, struct mlx5_eq *eq,\ndrivers/net/ethernet/mellanox/mlx5/core/debugfs.c-418-\t\t\t int index)\n--\ndrivers/net/ethernet/mellanox/mlx5/core/debugfs.c-456-\ndrivers/net/ethernet/mellanox/mlx5/core/debugfs.c:457:static u64 cq_read_field(struct mlx5_core_dev *dev, struct mlx5_core_cq *cq,\ndrivers/net/ethernet/mellanox/mlx5/core/debugfs.c-458-\t\t\t int index)\n--\ndrivers/net/ethernet/mellanox/mlx5/core/debugfs.c=532=static const struct file_operations fops = {\n--\ndrivers/net/ethernet/mellanox/mlx5/core/debugfs.c-537-\ndrivers/net/ethernet/mellanox/mlx5/core/debugfs.c:538:static int add_res_tree(struct mlx5_core_dev *dev, enum dbg_rsc_type type,\ndrivers/net/ethernet/mellanox/mlx5/core/debugfs.c-539-\t\t\tstruct dentry *root, struct mlx5_rsc_debug **dbg,\n--\ndrivers/net/ethernet/mellanox/mlx5/core/debugfs.c=566=static void rem_res_tree(struct mlx5_rsc_debug *d)\n--\ndrivers/net/ethernet/mellanox/mlx5/core/debugfs.c-571-\ndrivers/net/ethernet/mellanox/mlx5/core/debugfs.c:572:int mlx5_debug_qp_add(struct mlx5_core_dev *dev, struct mlx5_core_qp *qp)\ndrivers/net/ethernet/mellanox/mlx5/core/debugfs.c-573-{\n--\ndrivers/net/ethernet/mellanox/mlx5/core/debugfs.c=587=EXPORT_SYMBOL(mlx5_debug_qp_add);\ndrivers/net/ethernet/mellanox/mlx5/core/debugfs.c-588-\ndrivers/net/ethernet/mellanox/mlx5/core/debugfs.c:589:void mlx5_debug_qp_remove(struct mlx5_core_dev *dev, struct mlx5_core_qp *qp)\ndrivers/net/ethernet/mellanox/mlx5/core/debugfs.c-590-{\n--\ndrivers/net/ethernet/mellanox/mlx5/core/debugfs.c=597=EXPORT_SYMBOL(mlx5_debug_qp_remove);\ndrivers/net/ethernet/mellanox/mlx5/core/debugfs.c-598-\ndrivers/net/ethernet/mellanox/mlx5/core/debugfs.c:599:int mlx5_debug_eq_add(struct mlx5_core_dev *dev, struct mlx5_eq *eq)\n\n"
}

5/2 2026/07/07 21:41 llm patch-evaluator
0m Model:
gemini-3.1-pro-preview

Args:
null

Results:
null

Tokens:
							input: 39852
							output: 25
							thoughts: 408
						

Thoughts:
**Analyzing the Reachability of `mlx5_core_dev` Code with Syzkaller**

Okay, so the output shows that `mlx5_core_dev` is significantly present in the `drivers/net/ethernet/mellanox/mlx5/core/` directory. My immediate question is, how can syzkaller possibly trigger this code? It's all about system calls for syzkaller, right? The issue is pretty obvious: without the Mellanox hardware, the driver simply won't probe. No probe, no `mlx5_core_dev`, no code execution.

Is there any kind of netlink magic that could bypass the hardware requirement? Nope, mlx5 is a PCI driver. It needs that PCI device to get off the ground. No PCI device, no probe, no netdev, dead end.

Wait, doesn't syzkaller have something to emulate PCI devices, like `syz_pci_device_add`? No, that's not right. It has `syz_usb_connect` for USB, but no generic PCI emulator. I need to make sure I'm not missing anything. Did syzkaller introduce some clever PCI emulation through `vhci` or something similar? Nope.

Okay, let's step back. I thought I remembered seeing something like `syz_pci_device_add`. Nope, not in syzkaller.

Let's cut to the chase and find out if Syzkaller fuzzed mlx5. Looks like it doesn't, because it needs the hardware.

But wait! Hold on a second, the prompt says:

"Code paths that are impossible to reach in virtualized environments like GCE or QEMU, even when utilizing software-emulated hardware (e.g., usb gadget, mac80211_hwsim)."

"If it modifies reachable core kernel logic, drivers, or architectures, use your code search tools to verify the code can be executed, then return WorthFuzzing=true."

This is crucial. The prompt makes a clear distinction between reachable and unreachable code. It seems like the goal is to evaluate reachability in a QEMU-like environment.

Now, I'm going to double check for software emulation of mlx5.



6/2 2026/07/07 21:41 tool grepper
0m Args:
{
  "Expression": "mlx5.*emul",
  "PathPrefix": ""
}

Results:
{
  "Output": "include/linux/mlx5/mlx5_ifc.h=1347=struct mlx5_ifc_device_event_cap_bits {\n--\ninclude/linux/mlx5/mlx5_ifc.h-1352-\ninclude/linux/mlx5/mlx5_ifc.h:1353:struct mlx5_ifc_virtio_emulation_cap_bits {\ninclude/linux/mlx5/mlx5_ifc.h-1354-\tu8         desc_tunnel_offload_type[0x1];\n--\ninclude/linux/mlx5/mlx5_ifc.h=3852=union mlx5_ifc_hca_cap_union_bits {\n--\ninclude/linux/mlx5/mlx5_ifc.h-3869-\tstruct mlx5_ifc_device_mem_cap_bits device_mem_cap;\ninclude/linux/mlx5/mlx5_ifc.h:3870:\tstruct mlx5_ifc_virtio_emulation_cap_bits virtio_emulation_cap;\ninclude/linux/mlx5/mlx5_ifc.h-3871-\tstruct mlx5_ifc_tlp_dev_emu_capabilities_bits tlp_dev_emu_capabilities;\n"
}

7/2 2026/07/07 21:41 llm patch-evaluator
0m Model:
gemini-3.1-pro-preview

Args:
null

Results:
null

Tokens:
							input: 41103
							output: 25
							thoughts: 104
						

Thoughts:
**Navigating the Virtio and MLX5 Landscape**

Okay, hold on a second. I'm going down the wrong path here. `virtio_emulation_cap` is specifically for hardware offloading within virtio, not for simulating mlx5 in a software context. That's a critical distinction.

Now, the real question is: how can I actually get to the bottom of the `mlx5e_psp_set_config` function? I know it's being called, but I need to understand its entry points. Ah, right, it's called as a callback within `psp_dev_config`. So, `mlx5e_psp_set_config` is part of a callback in `psp_dev_config`.

But I'm missing something fundamental: what exactly is this `psp_dev` structure that triggers this callback? Time to go back to basics. I need to consult the source code. I should find it defined in `include/linux/psp.h`, or something similar within the kernel's include files. That should give me the context I need to proceed.



8/2 2026/07/07 21:41 tool grepper
0m Args:
{
  "Expression": "psp_dev_config",
  "PathPrefix": ""
}

Results:
{
  "Output": "drivers/net/ethernet/mellanox/mlx5/core/en_accel/psp.c=860=static int\ndrivers/net/ethernet/mellanox/mlx5/core/en_accel/psp.c:861:mlx5e_psp_set_config(struct psp_dev *psd, struct psp_dev_config *conf,\ndrivers/net/ethernet/mellanox/mlx5/core/en_accel/psp.c-862-\t\t     struct netlink_ext_ack *extack)\n--\ndrivers/net/netdevsim/psp.c=121=static int\ndrivers/net/netdevsim/psp.c:122:nsim_psp_set_config(struct psp_dev *psd, struct psp_dev_config *conf,\ndrivers/net/netdevsim/psp.c-123-\t\t    struct netlink_ext_ack *extack)\n--\ninclude/net/psp/types.h=14=struct psphdr {\n--\ninclude/net/psp/types.h-39-/**\ninclude/net/psp/types.h:40: * struct psp_dev_config - PSP device configuration\ninclude/net/psp/types.h-41- * @versions: PSP versions enabled on the device\ninclude/net/psp/types.h-42- */\ninclude/net/psp/types.h:43:struct psp_dev_config {\ninclude/net/psp/types.h-44-\tu32 versions;\n--\ninclude/net/psp/types.h=89=struct psp_dev {\n--\ninclude/net/psp/types.h-104-\ninclude/net/psp/types.h:105:\tstruct psp_dev_config config;\ninclude/net/psp/types.h-106-\n--\ninclude/net/psp/types.h=195=struct psp_dev_ops {\n--\ninclude/net/psp/types.h-200-\t */\ninclude/net/psp/types.h:201:\tint (*set_config)(struct psp_dev *psd, struct psp_dev_config *conf,\ninclude/net/psp/types.h-202-\t\t\t  struct netlink_ext_ack *extack);\n--\nnet/psp/psp_nl.c=398=int psp_nl_dev_set_doit(struct sk_buff *skb, struct genl_info *info)\n--\nnet/psp/psp_nl.c-400-\tstruct psp_dev *psd = info-\u003euser_ptr[0];\nnet/psp/psp_nl.c:401:\tstruct psp_dev_config new_config;\nnet/psp/psp_nl.c-402-\tstruct sk_buff *rsp;\n"
}

9/2 2026/07/07 21:41 llm patch-evaluator
0m Model:
gemini-3.1-pro-preview

Args:
null

Results:
null

Tokens:
							input: 42178
							output: 26
							thoughts: 388
						

Thoughts:
**WorthFuzzing Assessment: mlx5 Driver Patch**

Okay, so I'm looking at this patch and it touches `netdevsim`, specifically `nsim_psp_set_config`. But the core of the change is buried deep in the Mellanox `mlx5` driver, in `psp.c`. Immediately, my expert brain flags a potential issue: this is Mellanox hardware-dependent. Syzkaller's standard environment, be it GCE or QEMU, isn't going to magically conjure up a Mellanox card, right? I start to think about whether there's some clever PCI device injection, or perhaps a virtual probe mechanism for the Mellanox driver.

Let me think, does `netdevsim` somehow use `mlx5`? No, completely separate drivers. This means those `mlx5` changes are almost certainly unreachable in typical syzkaller setups.

Now, let's go back and carefully review the provided prompt's criteria for a "WorthFuzzing=false" determination. It specifies unreachable code paths in virtualized environments. And that is exactly what we have here. The patch includes hardware-specific code that requires a Mellanox PCI device, which, as far as I know, is not emulated within syzkaller's QEMU environment. The `mlx5` driver is not reachable and it is a hard requirement.

Unless there is some obscure virtual bus that allows syzkaller to reach PCI device drivers. Wait a minute, no, `mlx5` is a PCI device driver, there is no way around that.

Ok, last check - Let's see if there is any `syz_` pseudo-syscall specifically for `mlx5`...



10/2 2026/07/07 21:41 tool grepper
0m Error:
no matches

Args:
{
  "Expression": "syz_.*mlx5",
  "PathPrefix": ""
}

Results:
{
  "error": "no matches"
}

11/2 2026/07/07 21:41 llm patch-evaluator
0m Model:
gemini-3.1-pro-preview

Args:
null

Results:
null

Tokens:
							input: 42973
							output: 89
							thoughts: 409
						

Thoughts:
**My Assessment of the Patch's Fuzzing Potential**

Okay, so the initial assessment is a firm "no." Is there even a remote possibility this could be fuzzed effectively? No, the hardware drivers for PCI devices, particularly those like the Mellanox drivers, are not realistically reachable without proper QEMU emulation. Therefore, I will set `WorthFuzzing=false`.

Let me quickly double-check that there aren't any sneaky core kernel modifications hidden in here. Okay, the diff is only touching files within:
`drivers/net/ethernet/mellanox/mlx5/core/en.h`
`drivers/net/ethernet/mellanox/mlx5/core/en/fs.h`
`drivers/net/ethernet/mellanox/mlx5/core/en_accel/en_accel.h`
`drivers/net/ethernet/mellanox/mlx5/core/en_accel/psp.c`
`drivers/net/ethernet/mellanox/mlx5/core/en_accel/psp.h`
`drivers/net/ethernet/mellanox/mlx5/core/en_accel/psp_rxtx.c`
`drivers/net/ethernet/mellanox/mlx5/core/en_accel/psp_rxtx.h`
`drivers/net/ethernet/mellanox/mlx5/core/en_main.c`
`drivers/net/ethernet/mellanox/mlx5/core/en_rep.c`

Yep, it's all contained within the `drivers/net/ethernet/mellanox/mlx5/` directory. So, it's purely a Mellanox hardware driver patch.

I've got the response.
`WorthFuzzing: false`

The rationale? The patch *only* modifies the Mellanox `mlx5` hardware driver, and it looks specifically to the PSP offload feature. Because this driver fundamentally requires physical Mellanox ConnectX hardware to be present, and it's not emulated or simulated in virtualized environments like QEMU or Google Compute Engine, the code paths simply *won't* be exercised during fuzzing.



12/2 2026/07/07 21:41 tool set-results
0m Args:
{
  "EnableConfigs": [],
  "FocusSymbols": [],
  "Reasoning": "The patch only modifies the Mellanox mlx5 hardware driver (specifically the PSP offload feature). Since this driver requires physical Mellanox ConnectX hardware and is not emulated in virtualized environments like QEMU or GCE, the code paths are unreachable during fuzzing.",
  "WorthFuzzing": false
}

Results:
{
  "EnableConfigs": null,
  "FocusSymbols": [],
  "Reasoning": "The patch only modifies the Mellanox mlx5 hardware driver (specifically the PSP offload feature). Since this driver requires physical Mellanox ConnectX hardware and is not emulated in virtualized environments like QEMU or GCE, the code paths are unreachable during fuzzing.",
  "WorthFuzzing": false
}

LLM Calls Summary:
Total Calls Total Tokens Avg Tokens Total Duration (Seconds) Avg Duration (Seconds)
Tool Calls Summary:
Total Calls Total Duration (Seconds) Avg Duration (Seconds)