1 // SPDX-License-Identifier: GPL-2.0 OR Linux-OpenIB
2 /* Copyright (c) 2019 Mellanox Technologies */
10 static int mlx5_devlink_flash_update(struct devlink
*devlink
,
11 const char *file_name
,
12 const char *component
,
13 struct netlink_ext_ack
*extack
)
15 struct mlx5_core_dev
*dev
= devlink_priv(devlink
);
16 const struct firmware
*fw
;
22 err
= request_firmware_direct(&fw
, file_name
, &dev
->pdev
->dev
);
26 return mlx5_firmware_flash(dev
, fw
, extack
);
29 static u8
mlx5_fw_ver_major(u32 version
)
31 return (version
>> 24) & 0xff;
34 static u8
mlx5_fw_ver_minor(u32 version
)
36 return (version
>> 16) & 0xff;
39 static u16
mlx5_fw_ver_subminor(u32 version
)
41 return version
& 0xffff;
44 #define DEVLINK_FW_STRING_LEN 32
47 mlx5_devlink_info_get(struct devlink
*devlink
, struct devlink_info_req
*req
,
48 struct netlink_ext_ack
*extack
)
50 struct mlx5_core_dev
*dev
= devlink_priv(devlink
);
51 char version_str
[DEVLINK_FW_STRING_LEN
];
52 u32 running_fw
, stored_fw
;
55 err
= devlink_info_driver_name_put(req
, DRIVER_NAME
);
59 err
= devlink_info_version_fixed_put(req
, "fw.psid", dev
->board_id
);
63 err
= mlx5_fw_version_query(dev
, &running_fw
, &stored_fw
);
67 snprintf(version_str
, sizeof(version_str
), "%d.%d.%04d",
68 mlx5_fw_ver_major(running_fw
), mlx5_fw_ver_minor(running_fw
),
69 mlx5_fw_ver_subminor(running_fw
));
70 err
= devlink_info_version_running_put(req
, "fw.version", version_str
);
74 /* no pending version, return running (stored) version */
76 stored_fw
= running_fw
;
78 snprintf(version_str
, sizeof(version_str
), "%d.%d.%04d",
79 mlx5_fw_ver_major(stored_fw
), mlx5_fw_ver_minor(stored_fw
),
80 mlx5_fw_ver_subminor(stored_fw
));
81 err
= devlink_info_version_stored_put(req
, "fw.version", version_str
);
88 static const struct devlink_ops mlx5_devlink_ops
= {
89 #ifdef CONFIG_MLX5_ESWITCH
90 .eswitch_mode_set
= mlx5_devlink_eswitch_mode_set
,
91 .eswitch_mode_get
= mlx5_devlink_eswitch_mode_get
,
92 .eswitch_inline_mode_set
= mlx5_devlink_eswitch_inline_mode_set
,
93 .eswitch_inline_mode_get
= mlx5_devlink_eswitch_inline_mode_get
,
94 .eswitch_encap_mode_set
= mlx5_devlink_eswitch_encap_mode_set
,
95 .eswitch_encap_mode_get
= mlx5_devlink_eswitch_encap_mode_get
,
97 .flash_update
= mlx5_devlink_flash_update
,
98 .info_get
= mlx5_devlink_info_get
,
101 struct devlink
*mlx5_devlink_alloc(void)
103 return devlink_alloc(&mlx5_devlink_ops
, sizeof(struct mlx5_core_dev
));
106 void mlx5_devlink_free(struct devlink
*devlink
)
108 devlink_free(devlink
);
111 static int mlx5_devlink_fs_mode_validate(struct devlink
*devlink
, u32 id
,
112 union devlink_param_value val
,
113 struct netlink_ext_ack
*extack
)
115 struct mlx5_core_dev
*dev
= devlink_priv(devlink
);
116 char *value
= val
.vstr
;
119 if (!strcmp(value
, "dmfs")) {
121 } else if (!strcmp(value
, "smfs")) {
125 eswitch_mode
= mlx5_eswitch_mode(dev
->priv
.eswitch
);
126 smfs_cap
= mlx5_fs_dr_is_supported(dev
);
130 NL_SET_ERR_MSG_MOD(extack
,
131 "Software managed steering is not supported by current device");
134 else if (eswitch_mode
== MLX5_ESWITCH_OFFLOADS
) {
135 NL_SET_ERR_MSG_MOD(extack
,
136 "Software managed steering is not supported when eswitch offloads enabled.");
140 NL_SET_ERR_MSG_MOD(extack
,
141 "Bad parameter: supported values are [\"dmfs\", \"smfs\"]");
148 static int mlx5_devlink_fs_mode_set(struct devlink
*devlink
, u32 id
,
149 struct devlink_param_gset_ctx
*ctx
)
151 struct mlx5_core_dev
*dev
= devlink_priv(devlink
);
152 enum mlx5_flow_steering_mode mode
;
154 if (!strcmp(ctx
->val
.vstr
, "smfs"))
155 mode
= MLX5_FLOW_STEERING_MODE_SMFS
;
157 mode
= MLX5_FLOW_STEERING_MODE_DMFS
;
158 dev
->priv
.steering
->mode
= mode
;
163 static int mlx5_devlink_fs_mode_get(struct devlink
*devlink
, u32 id
,
164 struct devlink_param_gset_ctx
*ctx
)
166 struct mlx5_core_dev
*dev
= devlink_priv(devlink
);
168 if (dev
->priv
.steering
->mode
== MLX5_FLOW_STEERING_MODE_SMFS
)
169 strcpy(ctx
->val
.vstr
, "smfs");
171 strcpy(ctx
->val
.vstr
, "dmfs");
175 enum mlx5_devlink_param_id
{
176 MLX5_DEVLINK_PARAM_ID_BASE
= DEVLINK_PARAM_GENERIC_ID_MAX
,
177 MLX5_DEVLINK_PARAM_FLOW_STEERING_MODE
,
180 static const struct devlink_param mlx5_devlink_params
[] = {
181 DEVLINK_PARAM_DRIVER(MLX5_DEVLINK_PARAM_FLOW_STEERING_MODE
,
182 "flow_steering_mode", DEVLINK_PARAM_TYPE_STRING
,
183 BIT(DEVLINK_PARAM_CMODE_RUNTIME
),
184 mlx5_devlink_fs_mode_get
, mlx5_devlink_fs_mode_set
,
185 mlx5_devlink_fs_mode_validate
),
188 static void mlx5_devlink_set_params_init_values(struct devlink
*devlink
)
190 struct mlx5_core_dev
*dev
= devlink_priv(devlink
);
191 union devlink_param_value value
;
193 if (dev
->priv
.steering
->mode
== MLX5_FLOW_STEERING_MODE_DMFS
)
194 strcpy(value
.vstr
, "dmfs");
196 strcpy(value
.vstr
, "smfs");
197 devlink_param_driverinit_value_set(devlink
,
198 MLX5_DEVLINK_PARAM_FLOW_STEERING_MODE
,
202 int mlx5_devlink_register(struct devlink
*devlink
, struct device
*dev
)
206 err
= devlink_register(devlink
, dev
);
210 err
= devlink_params_register(devlink
, mlx5_devlink_params
,
211 ARRAY_SIZE(mlx5_devlink_params
));
214 mlx5_devlink_set_params_init_values(devlink
);
215 devlink_params_publish(devlink
);
219 devlink_unregister(devlink
);
223 void mlx5_devlink_unregister(struct devlink
*devlink
)
225 devlink_params_unregister(devlink
, mlx5_devlink_params
,
226 ARRAY_SIZE(mlx5_devlink_params
));
227 devlink_unregister(devlink
);