FILE
cmd.c
File preview with syntax highlighting.
linux-6.19.14/drivers/net/ethernet/mellanox/mlx5/core/steering/hws/cmd.c
1// SPDX-License-Identifier: GPL-2.0 OR Linux-OpenIB 2/* Copyright (c) 2024 NVIDIA Corporation & Affiliates */ 3 4#include "internal.h" 5 6static enum mlx5_ifc_flow_destination_type 7hws_cmd_dest_type_to_ifc_dest_type(enum mlx5_flow_destination_type type) 8{ 9 switch (type) { 10 case MLX5_FLOW_DESTINATION_TYPE_VPORT: 11 return MLX5_IFC_FLOW_DESTINATION_TYPE_VPORT; 12 case MLX5_FLOW_DESTINATION_TYPE_FLOW_TABLE: 13 return MLX5_IFC_FLOW_DESTINATION_TYPE_FLOW_TABLE; 14 case MLX5_FLOW_DESTINATION_TYPE_TIR: 15 return MLX5_IFC_FLOW_DESTINATION_TYPE_TIR; 16 case MLX5_FLOW_DESTINATION_TYPE_FLOW_SAMPLER: 17 return MLX5_IFC_FLOW_DESTINATION_TYPE_FLOW_SAMPLER; 18 case MLX5_FLOW_DESTINATION_TYPE_UPLINK: 19 return MLX5_IFC_FLOW_DESTINATION_TYPE_UPLINK; 20 case MLX5_FLOW_DESTINATION_TYPE_TABLE_TYPE: 21 return MLX5_IFC_FLOW_DESTINATION_TYPE_TABLE_TYPE; 22 case MLX5_FLOW_DESTINATION_TYPE_NONE: 23 case MLX5_FLOW_DESTINATION_TYPE_PORT: 24 case MLX5_FLOW_DESTINATION_TYPE_COUNTER: 25 case MLX5_FLOW_DESTINATION_TYPE_FLOW_TABLE_NUM: 26 case MLX5_FLOW_DESTINATION_TYPE_RANGE: 27 default: 28 pr_warn("HWS: unknown flow dest type %d\n", type); 29 return 0; 30 } 31}; 32 33static int hws_cmd_general_obj_destroy(struct mlx5_core_dev *mdev, 34 u32 object_type, 35 u32 object_id) 36{ 37 u32 in[MLX5_ST_SZ_DW(general_obj_in_cmd_hdr)] = {}; 38 u32 out[MLX5_ST_SZ_DW(general_obj_out_cmd_hdr)]; 39 40 MLX5_SET(general_obj_in_cmd_hdr, in, opcode, MLX5_CMD_OP_DESTROY_GENERAL_OBJECT); 41 MLX5_SET(general_obj_in_cmd_hdr, in, obj_type, object_type); 42 MLX5_SET(general_obj_in_cmd_hdr, in, obj_id, object_id); 43 44 return mlx5_cmd_exec(mdev, in, sizeof(in), out, sizeof(out)); 45} 46 47int mlx5hws_cmd_flow_table_create(struct mlx5_core_dev *mdev, 48 struct mlx5hws_cmd_ft_create_attr *ft_attr, 49 u32 *table_id) 50{ 51 u32 out[MLX5_ST_SZ_DW(create_flow_table_out)] = {0}; 52 u32 in[MLX5_ST_SZ_DW(create_flow_table_in)] = {0}; 53 void *ft_ctx; 54 int ret; 55 56 MLX5_SET(create_flow_table_in, in, opcode, MLX5_CMD_OP_CREATE_FLOW_TABLE); 57 MLX5_SET(create_flow_table_in, in, table_type, ft_attr->type); 58 MLX5_SET(create_flow_table_in, in, uid, ft_attr->uid); 59 60 ft_ctx = MLX5_ADDR_OF(create_flow_table_in, in, flow_table_context); 61 MLX5_SET(flow_table_context, ft_ctx, level, ft_attr->level); 62 MLX5_SET(flow_table_context, ft_ctx, rtc_valid, ft_attr->rtc_valid); 63 MLX5_SET(flow_table_context, ft_ctx, reformat_en, ft_attr->reformat_en); 64 MLX5_SET(flow_table_context, ft_ctx, decap_en, ft_attr->decap_en); 65 66 ret = mlx5_cmd_exec_inout(mdev, create_flow_table, in, out); 67 if (ret) 68 return ret; 69 70 *table_id = MLX5_GET(create_flow_table_out, out, table_id); 71 72 return 0; 73} 74 75int mlx5hws_cmd_flow_table_modify(struct mlx5_core_dev *mdev, 76 struct mlx5hws_cmd_ft_modify_attr *ft_attr, 77 u32 table_id) 78{ 79 u32 in[MLX5_ST_SZ_DW(modify_flow_table_in)] = {0}; 80 void *ft_ctx; 81 82 MLX5_SET(modify_flow_table_in, in, opcode, MLX5_CMD_OP_MODIFY_FLOW_TABLE); 83 MLX5_SET(modify_flow_table_in, in, table_type, ft_attr->type); 84 MLX5_SET(modify_flow_table_in, in, modify_field_select, ft_attr->modify_fs); 85 MLX5_SET(modify_flow_table_in, in, table_id, table_id); 86 87 ft_ctx = MLX5_ADDR_OF(modify_flow_table_in, in, flow_table_context); 88 89 MLX5_SET(flow_table_context, ft_ctx, table_miss_action, ft_attr->table_miss_action); 90 MLX5_SET(flow_table_context, ft_ctx, table_miss_id, ft_attr->table_miss_id); 91 MLX5_SET(flow_table_context, ft_ctx, hws.rtc_id_0, ft_attr->rtc_id_0); 92 MLX5_SET(flow_table_context, ft_ctx, hws.rtc_id_1, ft_attr->rtc_id_1); 93 94 return mlx5_cmd_exec_in(mdev, modify_flow_table, in); 95} 96 97int mlx5hws_cmd_flow_table_query(struct mlx5_core_dev *mdev, 98 u32 table_id, 99 struct mlx5hws_cmd_ft_query_attr *ft_attr, 100 u64 *icm_addr_0, u64 *icm_addr_1) 101{ 102 u32 out[MLX5_ST_SZ_DW(query_flow_table_out)] = {0}; 103 u32 in[MLX5_ST_SZ_DW(query_flow_table_in)] = {0}; 104 void *ft_ctx; 105 int ret; 106 107 MLX5_SET(query_flow_table_in, in, opcode, MLX5_CMD_OP_QUERY_FLOW_TABLE); 108 MLX5_SET(query_flow_table_in, in, table_type, ft_attr->type); 109 MLX5_SET(query_flow_table_in, in, table_id, table_id); 110 111 ret = mlx5_cmd_exec_inout(mdev, query_flow_table, in, out); 112 if (ret) 113 return ret; 114 115 ft_ctx = MLX5_ADDR_OF(query_flow_table_out, out, flow_table_context); 116 *icm_addr_0 = MLX5_GET64(flow_table_context, ft_ctx, sws.sw_owner_icm_root_0); 117 *icm_addr_1 = MLX5_GET64(flow_table_context, ft_ctx, sws.sw_owner_icm_root_1); 118 119 return ret; 120} 121 122int mlx5hws_cmd_flow_table_destroy(struct mlx5_core_dev *mdev, 123 u8 fw_ft_type, u32 table_id) 124{ 125 u32 in[MLX5_ST_SZ_DW(destroy_flow_table_in)] = {0}; 126 127 MLX5_SET(destroy_flow_table_in, in, opcode, MLX5_CMD_OP_DESTROY_FLOW_TABLE); 128 MLX5_SET(destroy_flow_table_in, in, table_type, fw_ft_type); 129 MLX5_SET(destroy_flow_table_in, in, table_id, table_id); 130 131 return mlx5_cmd_exec_in(mdev, destroy_flow_table, in); 132} 133 134static int hws_cmd_flow_group_create(struct mlx5_core_dev *mdev, 135 struct mlx5hws_cmd_fg_attr *fg_attr, 136 u32 *group_id) 137{ 138 u32 out[MLX5_ST_SZ_DW(create_flow_group_out)] = {0}; 139 int inlen = MLX5_ST_SZ_BYTES(create_flow_group_in); 140 u32 *in; 141 int ret; 142 143 in = kvzalloc(inlen, GFP_KERNEL); 144 if (!in) 145 return -ENOMEM; 146 147 MLX5_SET(create_flow_group_in, in, opcode, MLX5_CMD_OP_CREATE_FLOW_GROUP); 148 MLX5_SET(create_flow_group_in, in, table_type, fg_attr->table_type); 149 MLX5_SET(create_flow_group_in, in, table_id, fg_attr->table_id); 150 151 ret = mlx5_cmd_exec_inout(mdev, create_flow_group, in, out); 152 if (ret) 153 goto out; 154 155 *group_id = MLX5_GET(create_flow_group_out, out, group_id); 156 157out: 158 kvfree(in); 159 return ret; 160} 161 162static int hws_cmd_flow_group_destroy(struct mlx5_core_dev *mdev, 163 u32 ft_id, u32 fg_id, u8 ft_type) 164{ 165 u32 in[MLX5_ST_SZ_DW(destroy_flow_group_in)] = {}; 166 167 MLX5_SET(destroy_flow_group_in, in, opcode, MLX5_CMD_OP_DESTROY_FLOW_GROUP); 168 MLX5_SET(destroy_flow_group_in, in, table_type, ft_type); 169 MLX5_SET(destroy_flow_group_in, in, table_id, ft_id); 170 MLX5_SET(destroy_flow_group_in, in, group_id, fg_id); 171 172 return mlx5_cmd_exec_in(mdev, destroy_flow_group, in); 173} 174 175int mlx5hws_cmd_set_fte(struct mlx5_core_dev *mdev, 176 u32 table_type, 177 u32 table_id, 178 u32 group_id, 179 struct mlx5hws_cmd_set_fte_attr *fte_attr) 180{ 181 u32 out[MLX5_ST_SZ_DW(set_fte_out)] = {0}; 182 void *in_flow_context; 183 u32 dest_entry_sz; 184 u32 total_dest_sz; 185 u32 action_flags; 186 u8 *in_dests; 187 u32 inlen; 188 u32 *in; 189 int ret; 190 u32 i; 191 192 dest_entry_sz = fte_attr->extended_dest ? 193 MLX5_ST_SZ_BYTES(extended_dest_format) : 194 MLX5_ST_SZ_BYTES(dest_format); 195 total_dest_sz = dest_entry_sz * fte_attr->dests_num; 196 inlen = align((MLX5_ST_SZ_BYTES(set_fte_in) + total_dest_sz), DW_SIZE); 197 in = kzalloc(inlen, GFP_KERNEL); 198 if (!in) 199 return -ENOMEM; 200 201 MLX5_SET(set_fte_in, in, opcode, MLX5_CMD_OP_SET_FLOW_TABLE_ENTRY); 202 MLX5_SET(set_fte_in, in, table_type, table_type); 203 MLX5_SET(set_fte_in, in, table_id, table_id); 204 205 in_flow_context = MLX5_ADDR_OF(set_fte_in, in, flow_context); 206 MLX5_SET(flow_context, in_flow_context, group_id, group_id); 207 MLX5_SET(flow_context, in_flow_context, flow_source, fte_attr->flow_source); 208 MLX5_SET(flow_context, in_flow_context, extended_destination, fte_attr->extended_dest); 209 MLX5_SET(set_fte_in, in, ignore_flow_level, fte_attr->ignore_flow_level); 210 211 action_flags = fte_attr->action_flags; 212 MLX5_SET(flow_context, in_flow_context, action, action_flags); 213 214 if (action_flags & MLX5_FLOW_CONTEXT_ACTION_PACKET_REFORMAT) { 215 MLX5_SET(flow_context, in_flow_context, 216 packet_reformat_id, fte_attr->packet_reformat_id); 217 } 218 219 if (action_flags & (MLX5_FLOW_CONTEXT_ACTION_DECRYPT | MLX5_FLOW_CONTEXT_ACTION_ENCRYPT)) { 220 MLX5_SET(flow_context, in_flow_context, 221 encrypt_decrypt_type, fte_attr->encrypt_decrypt_type); 222 MLX5_SET(flow_context, in_flow_context, 223 encrypt_decrypt_obj_id, fte_attr->encrypt_decrypt_obj_id); 224 } 225 226 if (action_flags & MLX5_FLOW_CONTEXT_ACTION_FWD_DEST) { 227 in_dests = (u8 *)MLX5_ADDR_OF(flow_context, in_flow_context, destination); 228 229 for (i = 0; i < fte_attr->dests_num; i++) { 230 struct mlx5hws_cmd_set_fte_dest *dest = &fte_attr->dests[i]; 231 enum mlx5_ifc_flow_destination_type ifc_dest_type = 232 hws_cmd_dest_type_to_ifc_dest_type(dest->destination_type); 233 234 switch (dest->destination_type) { 235 case MLX5_FLOW_DESTINATION_TYPE_VPORT: 236 if (dest->ext_flags & MLX5HWS_CMD_EXT_DEST_ESW_OWNER_VHCA_ID) { 237 MLX5_SET(dest_format, in_dests, 238 destination_eswitch_owner_vhca_id_valid, 1); 239 MLX5_SET(dest_format, in_dests, 240 destination_eswitch_owner_vhca_id, 241 dest->esw_owner_vhca_id); 242 } 243 fallthrough; 244 case MLX5_FLOW_DESTINATION_TYPE_TIR: 245 case MLX5_FLOW_DESTINATION_TYPE_FLOW_TABLE: 246 MLX5_SET(dest_format, in_dests, destination_type, ifc_dest_type); 247 MLX5_SET(dest_format, in_dests, destination_id, 248 dest->destination_id); 249 if (dest->ext_flags & MLX5HWS_CMD_EXT_DEST_REFORMAT) { 250 MLX5_SET(dest_format, in_dests, packet_reformat, 1); 251 MLX5_SET(extended_dest_format, in_dests, packet_reformat_id, 252 dest->ext_reformat_id); 253 } 254 break; 255 case MLX5_FLOW_DESTINATION_TYPE_FLOW_SAMPLER: 256 MLX5_SET(dest_format, in_dests, 257 destination_type, ifc_dest_type); 258 MLX5_SET(dest_format, in_dests, destination_id, 259 dest->destination_id); 260 break; 261 default: 262 ret = -EOPNOTSUPP; 263 goto out; 264 } 265 266 in_dests = in_dests + dest_entry_sz; 267 } 268 MLX5_SET(flow_context, in_flow_context, destination_list_size, fte_attr->dests_num); 269 } 270 271 ret = mlx5_cmd_exec(mdev, in, inlen, out, sizeof(out)); 272 if (ret) 273 mlx5_core_err(mdev, "Failed creating FLOW_TABLE_ENTRY\n"); 274 275out: 276 kfree(in); 277 return ret; 278} 279 280int mlx5hws_cmd_delete_fte(struct mlx5_core_dev *mdev, 281 u32 table_type, 282 u32 table_id) 283{ 284 u32 in[MLX5_ST_SZ_DW(delete_fte_in)] = {}; 285 286 MLX5_SET(delete_fte_in, in, opcode, MLX5_CMD_OP_DELETE_FLOW_TABLE_ENTRY); 287 MLX5_SET(delete_fte_in, in, table_type, table_type); 288 MLX5_SET(delete_fte_in, in, table_id, table_id); 289 290 return mlx5_cmd_exec_in(mdev, delete_fte, in); 291} 292 293struct mlx5hws_cmd_forward_tbl * 294mlx5hws_cmd_forward_tbl_create(struct mlx5_core_dev *mdev, 295 struct mlx5hws_cmd_ft_create_attr *ft_attr, 296 struct mlx5hws_cmd_set_fte_attr *fte_attr) 297{ 298 struct mlx5hws_cmd_fg_attr fg_attr = {0}; 299 struct mlx5hws_cmd_forward_tbl *tbl; 300 int ret; 301 302 tbl = kzalloc(sizeof(*tbl), GFP_KERNEL); 303 if (!tbl) 304 return NULL; 305 306 ret = mlx5hws_cmd_flow_table_create(mdev, ft_attr, &tbl->ft_id); 307 if (ret) { 308 mlx5_core_err(mdev, "Failed to create FT\n"); 309 goto free_tbl; 310 } 311 312 fg_attr.table_id = tbl->ft_id; 313 fg_attr.table_type = ft_attr->type; 314 315 ret = hws_cmd_flow_group_create(mdev, &fg_attr, &tbl->fg_id); 316 if (ret) { 317 mlx5_core_err(mdev, "Failed to create FG\n"); 318 goto free_ft; 319 } 320 321 ret = mlx5hws_cmd_set_fte(mdev, ft_attr->type, 322 tbl->ft_id, tbl->fg_id, fte_attr); 323 if (ret) { 324 mlx5_core_err(mdev, "Failed to create FTE\n"); 325 goto free_fg; 326 } 327 328 tbl->type = ft_attr->type; 329 return tbl; 330 331free_fg: 332 hws_cmd_flow_group_destroy(mdev, tbl->ft_id, tbl->fg_id, ft_attr->type); 333free_ft: 334 mlx5hws_cmd_flow_table_destroy(mdev, ft_attr->type, tbl->ft_id); 335free_tbl: 336 kfree(tbl); 337 return NULL; 338} 339 340void mlx5hws_cmd_forward_tbl_destroy(struct mlx5_core_dev *mdev, 341 struct mlx5hws_cmd_forward_tbl *tbl) 342{ 343 mlx5hws_cmd_delete_fte(mdev, tbl->type, tbl->ft_id); 344 hws_cmd_flow_group_destroy(mdev, tbl->ft_id, tbl->fg_id, tbl->type); 345 mlx5hws_cmd_flow_table_destroy(mdev, tbl->type, tbl->ft_id); 346 kfree(tbl); 347} 348 349void mlx5hws_cmd_set_attr_connect_miss_tbl(struct mlx5hws_context *ctx, 350 u32 fw_ft_type, 351 enum mlx5hws_table_type type, 352 struct mlx5hws_cmd_ft_modify_attr *ft_attr) 353{ 354 u32 default_miss_tbl; 355 356 if (type != MLX5HWS_TABLE_TYPE_FDB) 357 return; 358 359 ft_attr->modify_fs = MLX5_IFC_MODIFY_FLOW_TABLE_MISS_ACTION; 360 ft_attr->type = fw_ft_type; 361 ft_attr->table_miss_action = MLX5_IFC_MODIFY_FLOW_TABLE_MISS_ACTION_GOTO_TBL; 362 363 default_miss_tbl = ctx->common_res.default_miss->ft_id; 364 if (!default_miss_tbl) { 365 pr_warn("HWS: no flow table ID for default miss\n"); 366 return; 367 } 368 369 ft_attr->table_miss_id = default_miss_tbl; 370} 371 372int mlx5hws_cmd_rtc_create(struct mlx5_core_dev *mdev, 373 struct mlx5hws_cmd_rtc_create_attr *rtc_attr, 374 u32 *rtc_id) 375{ 376 u32 out[MLX5_ST_SZ_DW(general_obj_out_cmd_hdr)] = {0}; 377 u32 in[MLX5_ST_SZ_DW(create_rtc_in)] = {0}; 378 void *attr; 379 int ret; 380 381 attr = MLX5_ADDR_OF(create_rtc_in, in, hdr); 382 MLX5_SET(general_obj_in_cmd_hdr, 383 attr, opcode, MLX5_CMD_OP_CREATE_GENERAL_OBJECT); 384 MLX5_SET(general_obj_in_cmd_hdr, 385 attr, obj_type, MLX5_OBJ_TYPE_RTC); 386 387 attr = MLX5_ADDR_OF(create_rtc_in, in, rtc); 388 MLX5_SET(rtc, attr, ste_format_0, rtc_attr->is_frst_jumbo ? 389 MLX5_IFC_RTC_STE_FORMAT_11DW : 390 MLX5_IFC_RTC_STE_FORMAT_8DW); 391 392 if (rtc_attr->is_scnd_range) { 393 MLX5_SET(rtc, attr, ste_format_1, MLX5_IFC_RTC_STE_FORMAT_RANGE); 394 MLX5_SET(rtc, attr, num_match_ste, 2); 395 } 396 397 MLX5_SET(rtc, attr, pd, rtc_attr->pd); 398 MLX5_SET(rtc, attr, update_method, rtc_attr->fw_gen_wqe); 399 MLX5_SET(rtc, attr, update_index_mode, rtc_attr->update_index_mode); 400 MLX5_SET(rtc, attr, access_index_mode, rtc_attr->access_index_mode); 401 MLX5_SET(rtc, attr, num_hash_definer, rtc_attr->num_hash_definer); 402 MLX5_SET(rtc, attr, log_depth, rtc_attr->log_depth); 403 MLX5_SET(rtc, attr, log_hash_size, rtc_attr->log_size); 404 MLX5_SET(rtc, attr, table_type, rtc_attr->table_type); 405 MLX5_SET(rtc, attr, num_hash_definer, rtc_attr->num_hash_definer); 406 MLX5_SET(rtc, attr, match_definer_0, rtc_attr->match_definer_0); 407 MLX5_SET(rtc, attr, match_definer_1, rtc_attr->match_definer_1); 408 MLX5_SET(rtc, attr, stc_id, rtc_attr->stc_base); 409 MLX5_SET(rtc, attr, ste_table_base_id, rtc_attr->ste_base); 410 MLX5_SET(rtc, attr, miss_flow_table_id, rtc_attr->miss_ft_id); 411 MLX5_SET(rtc, attr, reparse_mode, rtc_attr->reparse_mode); 412 413 ret = mlx5_cmd_exec(mdev, in, sizeof(in), out, sizeof(out)); 414 if (ret) { 415 mlx5_core_err(mdev, "Failed to create RTC\n"); 416 goto out; 417 } 418 419 *rtc_id = MLX5_GET(general_obj_out_cmd_hdr, out, obj_id); 420out: 421 return ret; 422} 423 424void mlx5hws_cmd_rtc_destroy(struct mlx5_core_dev *mdev, u32 rtc_id) 425{ 426 hws_cmd_general_obj_destroy(mdev, MLX5_OBJ_TYPE_RTC, rtc_id); 427} 428 429int mlx5hws_cmd_stc_create(struct mlx5_core_dev *mdev, 430 struct mlx5hws_cmd_stc_create_attr *stc_attr, 431 u32 *stc_id) 432{ 433 u32 out[MLX5_ST_SZ_DW(general_obj_out_cmd_hdr)] = {0}; 434 u32 in[MLX5_ST_SZ_DW(create_stc_in)] = {0}; 435 void *attr; 436 int ret; 437 438 attr = MLX5_ADDR_OF(create_stc_in, in, hdr); 439 MLX5_SET(general_obj_in_cmd_hdr, 440 attr, opcode, MLX5_CMD_OP_CREATE_GENERAL_OBJECT); 441 MLX5_SET(general_obj_in_cmd_hdr, 442 attr, obj_type, MLX5_OBJ_TYPE_STC); 443 MLX5_SET(general_obj_in_cmd_hdr, 444 attr, op_param.create.log_obj_range, stc_attr->log_obj_range); 445 446 attr = MLX5_ADDR_OF(create_stc_in, in, stc); 447 MLX5_SET(stc, attr, table_type, stc_attr->table_type); 448 449 ret = mlx5_cmd_exec(mdev, in, sizeof(in), out, sizeof(out)); 450 if (ret) { 451 mlx5_core_err(mdev, "Failed to create STC\n"); 452 goto out; 453 } 454 455 *stc_id = MLX5_GET(general_obj_out_cmd_hdr, out, obj_id); 456out: 457 return ret; 458} 459 460void mlx5hws_cmd_stc_destroy(struct mlx5_core_dev *mdev, u32 stc_id) 461{ 462 hws_cmd_general_obj_destroy(mdev, MLX5_OBJ_TYPE_STC, stc_id); 463} 464 465static int 466hws_cmd_stc_modify_set_stc_param(struct mlx5_core_dev *mdev, 467 struct mlx5hws_cmd_stc_modify_attr *stc_attr, 468 void *stc_param) 469{ 470 switch (stc_attr->action_type) { 471 case MLX5_IFC_STC_ACTION_TYPE_COUNTER: 472 MLX5_SET(stc_ste_param_flow_counter, stc_param, flow_counter_id, stc_attr->id); 473 break; 474 case MLX5_IFC_STC_ACTION_TYPE_JUMP_TO_TIR: 475 MLX5_SET(stc_ste_param_tir, stc_param, tirn, stc_attr->dest_tir_num); 476 break; 477 case MLX5_IFC_STC_ACTION_TYPE_JUMP_TO_FT: 478 MLX5_SET(stc_ste_param_table, stc_param, table_id, stc_attr->dest_table_id); 479 break; 480 case MLX5_IFC_STC_ACTION_TYPE_ACC_MODIFY_LIST: 481 MLX5_SET(stc_ste_param_header_modify_list, stc_param, 482 header_modify_pattern_id, stc_attr->modify_header.pattern_id); 483 MLX5_SET(stc_ste_param_header_modify_list, stc_param, 484 header_modify_argument_id, stc_attr->modify_header.arg_id); 485 break; 486 case MLX5_IFC_STC_ACTION_TYPE_HEADER_REMOVE: 487 MLX5_SET(stc_ste_param_remove, stc_param, action_type, 488 MLX5_MODIFICATION_TYPE_REMOVE); 489 MLX5_SET(stc_ste_param_remove, stc_param, decap, 490 stc_attr->remove_header.decap); 491 MLX5_SET(stc_ste_param_remove, stc_param, remove_start_anchor, 492 stc_attr->remove_header.start_anchor); 493 MLX5_SET(stc_ste_param_remove, stc_param, remove_end_anchor, 494 stc_attr->remove_header.end_anchor); 495 break; 496 case MLX5_IFC_STC_ACTION_TYPE_HEADER_INSERT: 497 MLX5_SET(stc_ste_param_insert, stc_param, action_type, 498 MLX5_MODIFICATION_TYPE_INSERT); 499 MLX5_SET(stc_ste_param_insert, stc_param, encap, 500 stc_attr->insert_header.encap); 501 MLX5_SET(stc_ste_param_insert, stc_param, inline_data, 502 stc_attr->insert_header.is_inline); 503 MLX5_SET(stc_ste_param_insert, stc_param, insert_anchor, 504 stc_attr->insert_header.insert_anchor); 505 /* HW gets the next 2 sizes in words */ 506 MLX5_SET(stc_ste_param_insert, stc_param, insert_size, 507 stc_attr->insert_header.header_size / W_SIZE); 508 MLX5_SET(stc_ste_param_insert, stc_param, insert_offset, 509 stc_attr->insert_header.insert_offset / W_SIZE); 510 MLX5_SET(stc_ste_param_insert, stc_param, insert_argument, 511 stc_attr->insert_header.arg_id); 512 break; 513 case MLX5_IFC_STC_ACTION_TYPE_COPY: 514 case MLX5_IFC_STC_ACTION_TYPE_SET: 515 case MLX5_IFC_STC_ACTION_TYPE_ADD: 516 case MLX5_IFC_STC_ACTION_TYPE_ADD_FIELD: 517 *(__be64 *)stc_param = stc_attr->modify_action.data; 518 break; 519 case MLX5_IFC_STC_ACTION_TYPE_JUMP_TO_VPORT: 520 case MLX5_IFC_STC_ACTION_TYPE_JUMP_TO_UPLINK: 521 MLX5_SET(stc_ste_param_vport, stc_param, vport_number, 522 stc_attr->vport.vport_num); 523 MLX5_SET(stc_ste_param_vport, stc_param, eswitch_owner_vhca_id, 524 stc_attr->vport.esw_owner_vhca_id); 525 MLX5_SET(stc_ste_param_vport, stc_param, eswitch_owner_vhca_id_valid, 526 stc_attr->vport.eswitch_owner_vhca_id_valid); 527 break; 528 case MLX5_IFC_STC_ACTION_TYPE_DROP: 529 case MLX5_IFC_STC_ACTION_TYPE_NOP: 530 case MLX5_IFC_STC_ACTION_TYPE_TAG: 531 case MLX5_IFC_STC_ACTION_TYPE_ALLOW: 532 break; 533 case MLX5_IFC_STC_ACTION_TYPE_ASO: 534 MLX5_SET(stc_ste_param_execute_aso, stc_param, aso_object_id, 535 stc_attr->aso.devx_obj_id); 536 MLX5_SET(stc_ste_param_execute_aso, stc_param, return_reg_id, 537 stc_attr->aso.return_reg_id); 538 MLX5_SET(stc_ste_param_execute_aso, stc_param, aso_type, 539 stc_attr->aso.aso_type); 540 break; 541 case MLX5_IFC_STC_ACTION_TYPE_JUMP_TO_STE_TABLE: 542 MLX5_SET(stc_ste_param_ste_table, stc_param, ste_obj_id, 543 stc_attr->ste_table.ste_obj_id); 544 MLX5_SET(stc_ste_param_ste_table, stc_param, match_definer_id, 545 stc_attr->ste_table.match_definer_id); 546 MLX5_SET(stc_ste_param_ste_table, stc_param, log_hash_size, 547 stc_attr->ste_table.log_hash_size); 548 break; 549 case MLX5_IFC_STC_ACTION_TYPE_REMOVE_WORDS: 550 MLX5_SET(stc_ste_param_remove_words, stc_param, action_type, 551 MLX5_MODIFICATION_TYPE_REMOVE_WORDS); 552 MLX5_SET(stc_ste_param_remove_words, stc_param, remove_start_anchor, 553 stc_attr->remove_words.start_anchor); 554 MLX5_SET(stc_ste_param_remove_words, stc_param, 555 remove_size, stc_attr->remove_words.num_of_words); 556 break; 557 case MLX5_IFC_STC_ACTION_TYPE_CRYPTO_IPSEC_ENCRYPTION: 558 MLX5_SET(stc_ste_param_ipsec_encrypt, stc_param, ipsec_object_id, 559 stc_attr->id); 560 break; 561 case MLX5_IFC_STC_ACTION_TYPE_CRYPTO_IPSEC_DECRYPTION: 562 MLX5_SET(stc_ste_param_ipsec_decrypt, stc_param, ipsec_object_id, 563 stc_attr->id); 564 break; 565 case MLX5_IFC_STC_ACTION_TYPE_TRAILER: 566 MLX5_SET(stc_ste_param_trailer, stc_param, command, 567 stc_attr->reformat_trailer.op); 568 MLX5_SET(stc_ste_param_trailer, stc_param, type, 569 stc_attr->reformat_trailer.type); 570 MLX5_SET(stc_ste_param_trailer, stc_param, length, 571 stc_attr->reformat_trailer.size); 572 break; 573 default: 574 mlx5_core_err(mdev, "Not supported type %d\n", stc_attr->action_type); 575 return -EINVAL; 576 } 577 return 0; 578} 579 580int mlx5hws_cmd_stc_modify(struct mlx5_core_dev *mdev, 581 u32 stc_id, 582 struct mlx5hws_cmd_stc_modify_attr *stc_attr) 583{ 584 u32 out[MLX5_ST_SZ_DW(general_obj_out_cmd_hdr)] = {0}; 585 u32 in[MLX5_ST_SZ_DW(create_stc_in)] = {0}; 586 void *stc_param; 587 void *attr; 588 int ret; 589 590 attr = MLX5_ADDR_OF(create_stc_in, in, hdr); 591 MLX5_SET(general_obj_in_cmd_hdr, 592 attr, opcode, MLX5_CMD_OP_MODIFY_GENERAL_OBJECT); 593 MLX5_SET(general_obj_in_cmd_hdr, 594 attr, obj_type, MLX5_OBJ_TYPE_STC); 595 MLX5_SET(general_obj_in_cmd_hdr, in, obj_id, stc_id); 596 MLX5_SET(general_obj_in_cmd_hdr, in, 597 op_param.query.obj_offset, stc_attr->stc_offset); 598 599 attr = MLX5_ADDR_OF(create_stc_in, in, stc); 600 MLX5_SET(stc, attr, ste_action_offset, stc_attr->action_offset); 601 MLX5_SET(stc, attr, action_type, stc_attr->action_type); 602 MLX5_SET(stc, attr, reparse_mode, stc_attr->reparse_mode); 603 MLX5_SET64(stc, attr, modify_field_select, 604 MLX5_IFC_MODIFY_STC_FIELD_SELECT_NEW_STC); 605 606 /* Set destination TIRN, TAG, FT ID, STE ID */ 607 stc_param = MLX5_ADDR_OF(stc, attr, stc_param); 608 ret = hws_cmd_stc_modify_set_stc_param(mdev, stc_attr, stc_param); 609 if (ret) 610 return ret; 611 612 ret = mlx5_cmd_exec(mdev, in, sizeof(in), out, sizeof(out)); 613 if (ret) 614 mlx5_core_err(mdev, "Failed to modify STC FW action_type %d\n", 615 stc_attr->action_type); 616 617 return ret; 618} 619 620int mlx5hws_cmd_arg_create(struct mlx5_core_dev *mdev, 621 u16 log_obj_range, 622 u32 pd, 623 u32 *arg_id) 624{ 625 u32 in[MLX5_ST_SZ_DW(create_modify_header_arg_in)] = {0}; 626 u32 out[MLX5_ST_SZ_DW(general_obj_out_cmd_hdr)] = {0}; 627 void *attr; 628 int ret; 629 630 attr = MLX5_ADDR_OF(create_modify_header_arg_in, in, hdr); 631 MLX5_SET(general_obj_in_cmd_hdr, 632 attr, opcode, MLX5_CMD_OP_CREATE_GENERAL_OBJECT); 633 MLX5_SET(general_obj_in_cmd_hdr, 634 attr, obj_type, MLX5_OBJ_TYPE_HEADER_MODIFY_ARGUMENT); 635 MLX5_SET(general_obj_in_cmd_hdr, 636 attr, op_param.create.log_obj_range, log_obj_range); 637 638 attr = MLX5_ADDR_OF(create_modify_header_arg_in, in, arg); 639 MLX5_SET(modify_header_arg, attr, access_pd, pd); 640 641 ret = mlx5_cmd_exec(mdev, in, sizeof(in), out, sizeof(out)); 642 if (ret) { 643 mlx5_core_err(mdev, "Failed to create ARG\n"); 644 goto out; 645 } 646 647 *arg_id = MLX5_GET(general_obj_out_cmd_hdr, out, obj_id); 648out: 649 return ret; 650} 651 652void mlx5hws_cmd_arg_destroy(struct mlx5_core_dev *mdev, 653 u32 arg_id) 654{ 655 hws_cmd_general_obj_destroy(mdev, MLX5_OBJ_TYPE_HEADER_MODIFY_ARGUMENT, arg_id); 656} 657 658int mlx5hws_cmd_header_modify_pattern_create(struct mlx5_core_dev *mdev, 659 u32 pattern_length, 660 u8 *actions, 661 u32 *ptrn_id) 662{ 663 u32 in[MLX5_ST_SZ_DW(create_header_modify_pattern_in)] = {0}; 664 u32 out[MLX5_ST_SZ_DW(general_obj_out_cmd_hdr)] = {0}; 665 int num_of_actions; 666 u64 *pattern_data; 667 void *pattern; 668 void *attr; 669 int ret; 670 int i; 671 672 if (pattern_length > MLX5_MAX_ACTIONS_DATA_IN_HEADER_MODIFY) { 673 mlx5_core_err(mdev, "Pattern length %d exceeds limit %d\n", 674 pattern_length, MLX5_MAX_ACTIONS_DATA_IN_HEADER_MODIFY); 675 return -EINVAL; 676 } 677 678 attr = MLX5_ADDR_OF(create_header_modify_pattern_in, in, hdr); 679 MLX5_SET(general_obj_in_cmd_hdr, 680 attr, opcode, MLX5_CMD_OP_CREATE_GENERAL_OBJECT); 681 MLX5_SET(general_obj_in_cmd_hdr, 682 attr, obj_type, MLX5_OBJ_TYPE_MODIFY_HDR_PATTERN); 683 684 pattern = MLX5_ADDR_OF(create_header_modify_pattern_in, in, pattern); 685 /* Pattern_length is in ddwords */ 686 MLX5_SET(header_modify_pattern_in, pattern, pattern_length, pattern_length / (2 * DW_SIZE)); 687 688 pattern_data = (u64 *)MLX5_ADDR_OF(header_modify_pattern_in, pattern, pattern_data); 689 memcpy(pattern_data, actions, pattern_length); 690 691 num_of_actions = pattern_length / MLX5HWS_MODIFY_ACTION_SIZE; 692 for (i = 0; i < num_of_actions; i++) { 693 int type; 694 695 type = MLX5_GET(set_action_in, &pattern_data[i], action_type); 696 if (type != MLX5_MODIFICATION_TYPE_COPY && 697 type != MLX5_MODIFICATION_TYPE_ADD_FIELD) 698 /* Action typ-copy use all bytes for control */ 699 MLX5_SET(set_action_in, &pattern_data[i], data, 0); 700 } 701 702 ret = mlx5_cmd_exec(mdev, in, sizeof(in), out, sizeof(out)); 703 if (ret) { 704 mlx5_core_err(mdev, "Failed to create header_modify_pattern\n"); 705 goto out; 706 } 707 708 *ptrn_id = MLX5_GET(general_obj_out_cmd_hdr, out, obj_id); 709out: 710 return ret; 711} 712 713void mlx5hws_cmd_header_modify_pattern_destroy(struct mlx5_core_dev *mdev, 714 u32 ptrn_id) 715{ 716 hws_cmd_general_obj_destroy(mdev, MLX5_OBJ_TYPE_MODIFY_HDR_PATTERN, ptrn_id); 717} 718 719int mlx5hws_cmd_ste_create(struct mlx5_core_dev *mdev, 720 struct mlx5hws_cmd_ste_create_attr *ste_attr, 721 u32 *ste_id) 722{ 723 u32 out[MLX5_ST_SZ_DW(general_obj_out_cmd_hdr)] = {0}; 724 u32 in[MLX5_ST_SZ_DW(create_ste_in)] = {0}; 725 void *attr; 726 int ret; 727 728 attr = MLX5_ADDR_OF(create_ste_in, in, hdr); 729 MLX5_SET(general_obj_in_cmd_hdr, 730 attr, opcode, MLX5_CMD_OP_CREATE_GENERAL_OBJECT); 731 MLX5_SET(general_obj_in_cmd_hdr, 732 attr, obj_type, MLX5_OBJ_TYPE_STE); 733 MLX5_SET(general_obj_in_cmd_hdr, 734 attr, op_param.create.log_obj_range, ste_attr->log_obj_range); 735 736 attr = MLX5_ADDR_OF(create_ste_in, in, ste); 737 MLX5_SET(ste, attr, table_type, ste_attr->table_type); 738 739 ret = mlx5_cmd_exec(mdev, in, sizeof(in), out, sizeof(out)); 740 if (ret) { 741 mlx5_core_err(mdev, "Failed to create STE\n"); 742 goto out; 743 } 744 745 *ste_id = MLX5_GET(general_obj_out_cmd_hdr, out, obj_id); 746out: 747 return ret; 748} 749 750void mlx5hws_cmd_ste_destroy(struct mlx5_core_dev *mdev, u32 ste_id) 751{ 752 hws_cmd_general_obj_destroy(mdev, MLX5_OBJ_TYPE_STE, ste_id); 753} 754 755int mlx5hws_cmd_definer_create(struct mlx5_core_dev *mdev, 756 struct mlx5hws_cmd_definer_create_attr *def_attr, 757 u32 *definer_id) 758{ 759 u32 out[MLX5_ST_SZ_DW(general_obj_out_cmd_hdr)] = {0}; 760 u32 in[MLX5_ST_SZ_DW(create_definer_in)] = {0}; 761 void *ptr; 762 int ret; 763 764 MLX5_SET(general_obj_in_cmd_hdr, 765 in, opcode, MLX5_CMD_OP_CREATE_GENERAL_OBJECT); 766 MLX5_SET(general_obj_in_cmd_hdr, 767 in, obj_type, MLX5_OBJ_TYPE_MATCH_DEFINER); 768 769 ptr = MLX5_ADDR_OF(create_definer_in, in, definer); 770 MLX5_SET(definer, ptr, format_id, MLX5_IFC_DEFINER_FORMAT_ID_SELECT); 771 772 MLX5_SET(definer, ptr, format_select_dw0, def_attr->dw_selector[0]); 773 MLX5_SET(definer, ptr, format_select_dw1, def_attr->dw_selector[1]); 774 MLX5_SET(definer, ptr, format_select_dw2, def_attr->dw_selector[2]); 775 MLX5_SET(definer, ptr, format_select_dw3, def_attr->dw_selector[3]); 776 MLX5_SET(definer, ptr, format_select_dw4, def_attr->dw_selector[4]); 777 MLX5_SET(definer, ptr, format_select_dw5, def_attr->dw_selector[5]); 778 MLX5_SET(definer, ptr, format_select_dw6, def_attr->dw_selector[6]); 779 MLX5_SET(definer, ptr, format_select_dw7, def_attr->dw_selector[7]); 780 MLX5_SET(definer, ptr, format_select_dw8, def_attr->dw_selector[8]); 781 782 MLX5_SET(definer, ptr, format_select_byte0, def_attr->byte_selector[0]); 783 MLX5_SET(definer, ptr, format_select_byte1, def_attr->byte_selector[1]); 784 MLX5_SET(definer, ptr, format_select_byte2, def_attr->byte_selector[2]); 785 MLX5_SET(definer, ptr, format_select_byte3, def_attr->byte_selector[3]); 786 MLX5_SET(definer, ptr, format_select_byte4, def_attr->byte_selector[4]); 787 MLX5_SET(definer, ptr, format_select_byte5, def_attr->byte_selector[5]); 788 MLX5_SET(definer, ptr, format_select_byte6, def_attr->byte_selector[6]); 789 MLX5_SET(definer, ptr, format_select_byte7, def_attr->byte_selector[7]); 790 791 ptr = MLX5_ADDR_OF(definer, ptr, match_mask); 792 memcpy(ptr, def_attr->match_mask, MLX5_FLD_SZ_BYTES(definer, match_mask)); 793 794 ret = mlx5_cmd_exec(mdev, in, sizeof(in), out, sizeof(out)); 795 if (ret) { 796 mlx5_core_err(mdev, "Failed to create Definer\n"); 797 goto out; 798 } 799 800 *definer_id = MLX5_GET(general_obj_out_cmd_hdr, out, obj_id); 801out: 802 return ret; 803} 804 805void mlx5hws_cmd_definer_destroy(struct mlx5_core_dev *mdev, 806 u32 definer_id) 807{ 808 hws_cmd_general_obj_destroy(mdev, MLX5_OBJ_TYPE_MATCH_DEFINER, definer_id); 809} 810 811int mlx5hws_cmd_packet_reformat_create(struct mlx5_core_dev *mdev, 812 struct mlx5hws_cmd_packet_reformat_create_attr *attr, 813 u32 *reformat_id) 814{ 815 u32 out[MLX5_ST_SZ_DW(alloc_packet_reformat_context_out)] = {0}; 816 size_t insz, cmd_data_sz, cmd_total_sz; 817 void *prctx; 818 void *pdata; 819 void *in; 820 int ret; 821 822 cmd_total_sz = MLX5_ST_SZ_BYTES(alloc_packet_reformat_context_in); 823 cmd_total_sz += MLX5_ST_SZ_BYTES(packet_reformat_context_in); 824 cmd_data_sz = MLX5_FLD_SZ_BYTES(packet_reformat_context_in, reformat_data); 825 insz = align(cmd_total_sz + attr->data_sz - cmd_data_sz, DW_SIZE); 826 in = kzalloc(insz, GFP_KERNEL); 827 if (!in) 828 return -ENOMEM; 829 830 MLX5_SET(alloc_packet_reformat_context_in, in, opcode, 831 MLX5_CMD_OP_ALLOC_PACKET_REFORMAT_CONTEXT); 832 833 prctx = MLX5_ADDR_OF(alloc_packet_reformat_context_in, in, 834 packet_reformat_context); 835 pdata = MLX5_ADDR_OF(packet_reformat_context_in, prctx, reformat_data); 836 837 MLX5_SET(packet_reformat_context_in, prctx, reformat_type, attr->type); 838 MLX5_SET(packet_reformat_context_in, prctx, reformat_param_0, attr->reformat_param_0); 839 MLX5_SET(packet_reformat_context_in, prctx, reformat_data_size, attr->data_sz); 840 memcpy(pdata, attr->data, attr->data_sz); 841 842 ret = mlx5_cmd_exec(mdev, in, insz, out, sizeof(out)); 843 if (ret) { 844 mlx5_core_err(mdev, "Failed to create packet reformat\n"); 845 goto out; 846 } 847 848 *reformat_id = MLX5_GET(alloc_packet_reformat_context_out, out, packet_reformat_id); 849out: 850 kfree(in); 851 return ret; 852} 853 854int mlx5hws_cmd_packet_reformat_destroy(struct mlx5_core_dev *mdev, 855 u32 reformat_id) 856{ 857 u32 out[MLX5_ST_SZ_DW(dealloc_packet_reformat_context_out)] = {0}; 858 u32 in[MLX5_ST_SZ_DW(dealloc_packet_reformat_context_in)] = {0}; 859 int ret; 860 861 MLX5_SET(dealloc_packet_reformat_context_in, in, opcode, 862 MLX5_CMD_OP_DEALLOC_PACKET_REFORMAT_CONTEXT); 863 MLX5_SET(dealloc_packet_reformat_context_in, in, 864 packet_reformat_id, reformat_id); 865 866 ret = mlx5_cmd_exec(mdev, in, sizeof(in), out, sizeof(out)); 867 if (ret) 868 mlx5_core_err(mdev, "Failed to destroy packet_reformat\n"); 869 870 return ret; 871} 872 873int mlx5hws_cmd_sq_modify_rdy(struct mlx5_core_dev *mdev, u32 sqn) 874{ 875 u32 out[MLX5_ST_SZ_DW(modify_sq_out)] = {0}; 876 u32 in[MLX5_ST_SZ_DW(modify_sq_in)] = {0}; 877 void *sqc = MLX5_ADDR_OF(modify_sq_in, in, ctx); 878 int ret; 879 880 MLX5_SET(modify_sq_in, in, opcode, MLX5_CMD_OP_MODIFY_SQ); 881 MLX5_SET(modify_sq_in, in, sqn, sqn); 882 MLX5_SET(modify_sq_in, in, sq_state, MLX5_SQC_STATE_RST); 883 MLX5_SET(sqc, sqc, state, MLX5_SQC_STATE_RDY); 884 885 ret = mlx5_cmd_exec(mdev, in, sizeof(in), out, sizeof(out)); 886 if (ret) 887 mlx5_core_err(mdev, "Failed to modify SQ\n"); 888 889 return ret; 890} 891 892int mlx5hws_cmd_generate_wqe(struct mlx5_core_dev *mdev, 893 struct mlx5hws_cmd_generate_wqe_attr *attr, 894 struct mlx5_cqe64 *ret_cqe) 895{ 896 u32 out[MLX5_ST_SZ_DW(generate_wqe_out)] = {0}; 897 u32 in[MLX5_ST_SZ_DW(generate_wqe_in)] = {0}; 898 u8 status; 899 void *ptr; 900 int ret; 901 902 MLX5_SET(generate_wqe_in, in, opcode, MLX5_CMD_OP_GENERATE_WQE); 903 MLX5_SET(generate_wqe_in, in, pdn, attr->pdn); 904 905 ptr = MLX5_ADDR_OF(generate_wqe_in, in, wqe_ctrl); 906 memcpy(ptr, attr->wqe_ctrl, MLX5_FLD_SZ_BYTES(generate_wqe_in, wqe_ctrl)); 907 908 ptr = MLX5_ADDR_OF(generate_wqe_in, in, wqe_gta_ctrl); 909 memcpy(ptr, attr->gta_ctrl, MLX5_FLD_SZ_BYTES(generate_wqe_in, wqe_gta_ctrl)); 910 911 ptr = MLX5_ADDR_OF(generate_wqe_in, in, wqe_gta_data_0); 912 memcpy(ptr, attr->gta_data_0, MLX5_FLD_SZ_BYTES(generate_wqe_in, wqe_gta_data_0)); 913 914 if (attr->gta_data_1) { 915 ptr = MLX5_ADDR_OF(generate_wqe_in, in, wqe_gta_data_1); 916 memcpy(ptr, attr->gta_data_1, MLX5_FLD_SZ_BYTES(generate_wqe_in, wqe_gta_data_1)); 917 } 918 919 ret = mlx5_cmd_exec(mdev, in, sizeof(in), out, sizeof(out)); 920 if (ret) { 921 mlx5_core_err(mdev, "Failed to write GTA WQE using FW\n"); 922 return ret; 923 } 924 925 status = MLX5_GET(generate_wqe_out, out, status); 926 if (status) { 927 mlx5_core_err(mdev, "Invalid FW CQE status %d\n", status); 928 return -EINVAL; 929 } 930 931 ptr = MLX5_ADDR_OF(generate_wqe_out, out, cqe_data); 932 memcpy(ret_cqe, ptr, sizeof(*ret_cqe)); 933 934 return ret; 935} 936 937int mlx5hws_cmd_query_caps(struct mlx5_core_dev *mdev, 938 struct mlx5hws_cmd_query_caps *caps) 939{ 940 u32 in[MLX5_ST_SZ_DW(query_hca_cap_in)] = {0}; 941 u32 out_size; 942 u32 *out; 943 int ret; 944 945 out_size = MLX5_ST_SZ_BYTES(query_hca_cap_out); 946 out = kzalloc(out_size, GFP_KERNEL); 947 if (!out) 948 return -ENOMEM; 949 950 MLX5_SET(query_hca_cap_in, in, opcode, MLX5_CMD_OP_QUERY_HCA_CAP); 951 MLX5_SET(query_hca_cap_in, in, op_mod, 952 MLX5_SET_HCA_CAP_OP_MOD_GENERAL_DEVICE | HCA_CAP_OPMOD_GET_CUR); 953 954 ret = mlx5_cmd_exec(mdev, in, sizeof(in), out, out_size); 955 if (ret) { 956 mlx5_core_err(mdev, "Failed to query device caps\n"); 957 goto out; 958 } 959 960 caps->wqe_based_update = 961 MLX5_GET(query_hca_cap_out, out, 962 capability.cmd_hca_cap.wqe_based_flow_table_update_cap); 963 964 caps->eswitch_manager = MLX5_GET(query_hca_cap_out, out, 965 capability.cmd_hca_cap.eswitch_manager); 966 967 caps->flex_protocols = MLX5_GET(query_hca_cap_out, out, 968 capability.cmd_hca_cap.flex_parser_protocols); 969 970 if (caps->flex_protocols & MLX5_FLEX_PARSER_GENEVE_TLV_OPTION_0_ENABLED) 971 caps->flex_parser_id_geneve_tlv_option_0 = 972 MLX5_GET(query_hca_cap_out, out, 973 capability.cmd_hca_cap.flex_parser_id_geneve_tlv_option_0); 974 975 if (caps->flex_protocols & MLX5_FLEX_PARSER_MPLS_OVER_GRE_ENABLED) 976 caps->flex_parser_id_mpls_over_gre = 977 MLX5_GET(query_hca_cap_out, out, 978 capability.cmd_hca_cap.flex_parser_id_outer_first_mpls_over_gre); 979 980 if (caps->flex_protocols & MLX5_FLEX_PARSER_MPLS_OVER_UDP_ENABLED) 981 caps->flex_parser_id_mpls_over_udp = 982 MLX5_GET(query_hca_cap_out, out, 983 capability.cmd_hca_cap.flex_parser_id_outer_first_mpls_over_udp_label); 984 985 caps->log_header_modify_argument_granularity = 986 MLX5_GET(query_hca_cap_out, out, 987 capability.cmd_hca_cap.log_header_modify_argument_granularity); 988 989 caps->log_header_modify_argument_granularity -= 990 MLX5_GET(query_hca_cap_out, out, 991 capability.cmd_hca_cap.log_header_modify_argument_granularity_offset); 992 993 caps->log_header_modify_argument_max_alloc = 994 MLX5_GET(query_hca_cap_out, out, 995 capability.cmd_hca_cap.log_header_modify_argument_max_alloc); 996 997 caps->definer_format_sup = 998 MLX5_GET64(query_hca_cap_out, out, 999 capability.cmd_hca_cap.match_definer_format_supported); 1000 1001 caps->vhca_id = MLX5_GET(query_hca_cap_out, out, 1002 capability.cmd_hca_cap.vhca_id); 1003 1004 caps->sq_ts_format = MLX5_GET(query_hca_cap_out, out, 1005 capability.cmd_hca_cap.sq_ts_format); 1006 1007 caps->ipsec_offload = MLX5_GET(query_hca_cap_out, out, 1008 capability.cmd_hca_cap.ipsec_offload); 1009 1010 MLX5_SET(query_hca_cap_in, in, op_mod, 1011 MLX5_GET_HCA_CAP_OP_MOD_GENERAL_DEVICE_2 | HCA_CAP_OPMOD_GET_CUR); 1012 1013 ret = mlx5_cmd_exec(mdev, in, sizeof(in), out, out_size); 1014 if (ret) { 1015 mlx5_core_err(mdev, "Failed to query device caps 2\n"); 1016 goto out; 1017 } 1018 1019 caps->full_dw_jumbo_support = 1020 MLX5_GET(query_hca_cap_out, out, 1021 capability.cmd_hca_cap_2.format_select_dw_8_6_ext); 1022 1023 caps->format_select_gtpu_dw_0 = 1024 MLX5_GET(query_hca_cap_out, out, 1025 capability.cmd_hca_cap_2.format_select_dw_gtpu_dw_0); 1026 1027 caps->format_select_gtpu_dw_1 = 1028 MLX5_GET(query_hca_cap_out, out, 1029 capability.cmd_hca_cap_2.format_select_dw_gtpu_dw_1); 1030 1031 caps->format_select_gtpu_dw_2 = 1032 MLX5_GET(query_hca_cap_out, out, 1033 capability.cmd_hca_cap_2.format_select_dw_gtpu_dw_2); 1034 1035 caps->format_select_gtpu_ext_dw_0 = 1036 MLX5_GET(query_hca_cap_out, out, 1037 capability.cmd_hca_cap_2.format_select_dw_gtpu_first_ext_dw_0); 1038 1039 caps->supp_type_gen_wqe = 1040 MLX5_GET(query_hca_cap_out, out, 1041 capability.cmd_hca_cap_2.generate_wqe_type); 1042 1043 caps->flow_table_hash_type = 1044 MLX5_GET(query_hca_cap_out, out, 1045 capability.cmd_hca_cap_2.flow_table_hash_type); 1046 1047 MLX5_SET(query_hca_cap_in, in, op_mod, 1048 MLX5_GET_HCA_CAP_OP_MOD_NIC_FLOW_TABLE | HCA_CAP_OPMOD_GET_CUR); 1049 1050 ret = mlx5_cmd_exec(mdev, in, sizeof(in), out, out_size); 1051 if (ret) { 1052 mlx5_core_err(mdev, "Failed to query flow table caps\n"); 1053 goto out; 1054 } 1055 1056 caps->nic_ft.max_level = 1057 MLX5_GET(query_hca_cap_out, out, 1058 capability.flow_table_nic_cap.flow_table_properties_nic_receive.max_ft_level); 1059 1060 caps->nic_ft.reparse = 1061 MLX5_GET(query_hca_cap_out, out, 1062 capability.flow_table_nic_cap.flow_table_properties_nic_receive.reparse); 1063 1064 caps->nic_ft.ignore_flow_level_rtc_valid = 1065 MLX5_GET(query_hca_cap_out, out, 1066 capability.flow_table_nic_cap.flow_table_properties_nic_receive.ignore_flow_level_rtc_valid); 1067 1068 caps->flex_parser_ok_bits_supp = 1069 MLX5_GET(query_hca_cap_out, out, 1070 capability.flow_table_nic_cap.flow_table_properties_nic_receive.ft_field_support.geneve_tlv_option_0_exist); 1071 1072 if (caps->wqe_based_update) { 1073 MLX5_SET(query_hca_cap_in, in, op_mod, 1074 MLX5_GET_HCA_CAP_OP_MOD_WQE_BASED_FLOW_TABLE | HCA_CAP_OPMOD_GET_CUR); 1075 1076 ret = mlx5_cmd_exec(mdev, in, sizeof(in), out, out_size); 1077 if (ret) { 1078 mlx5_core_err(mdev, "Failed to query WQE based FT caps\n"); 1079 goto out; 1080 } 1081 1082 caps->rtc_reparse_mode = 1083 MLX5_GET(query_hca_cap_out, out, 1084 capability.wqe_based_flow_table_cap.rtc_reparse_mode); 1085 1086 caps->ste_format = 1087 MLX5_GET(query_hca_cap_out, out, 1088 capability.wqe_based_flow_table_cap.ste_format); 1089 1090 caps->rtc_index_mode = 1091 MLX5_GET(query_hca_cap_out, out, 1092 capability.wqe_based_flow_table_cap.rtc_index_mode); 1093 1094 caps->rtc_log_depth_max = 1095 MLX5_GET(query_hca_cap_out, out, 1096 capability.wqe_based_flow_table_cap.rtc_log_depth_max); 1097 1098 caps->ste_alloc_log_max = 1099 MLX5_GET(query_hca_cap_out, out, 1100 capability.wqe_based_flow_table_cap.ste_alloc_log_max); 1101 1102 caps->ste_alloc_log_gran = 1103 MLX5_GET(query_hca_cap_out, out, 1104 capability.wqe_based_flow_table_cap.ste_alloc_log_granularity); 1105 1106 caps->trivial_match_definer = 1107 MLX5_GET(query_hca_cap_out, out, 1108 capability.wqe_based_flow_table_cap.trivial_match_definer); 1109 1110 caps->stc_alloc_log_max = 1111 MLX5_GET(query_hca_cap_out, out, 1112 capability.wqe_based_flow_table_cap.stc_alloc_log_max); 1113 1114 caps->stc_alloc_log_gran = 1115 MLX5_GET(query_hca_cap_out, out, 1116 capability.wqe_based_flow_table_cap.stc_alloc_log_granularity); 1117 1118 caps->rtc_hash_split_table = 1119 MLX5_GET(query_hca_cap_out, out, 1120 capability.wqe_based_flow_table_cap.rtc_hash_split_table); 1121 1122 caps->rtc_linear_lookup_table = 1123 MLX5_GET(query_hca_cap_out, out, 1124 capability.wqe_based_flow_table_cap.rtc_linear_lookup_table); 1125 1126 caps->access_index_mode = 1127 MLX5_GET(query_hca_cap_out, out, 1128 capability.wqe_based_flow_table_cap.access_index_mode); 1129 1130 caps->linear_match_definer = 1131 MLX5_GET(query_hca_cap_out, out, 1132 capability.wqe_based_flow_table_cap.linear_match_definer_reg_c3); 1133 1134 caps->rtc_max_hash_def_gen_wqe = 1135 MLX5_GET(query_hca_cap_out, out, 1136 capability.wqe_based_flow_table_cap.rtc_max_num_hash_definer_gen_wqe); 1137 1138 caps->supp_ste_format_gen_wqe = 1139 MLX5_GET(query_hca_cap_out, out, 1140 capability.wqe_based_flow_table_cap.ste_format_gen_wqe); 1141 1142 caps->fdb_tir_stc = 1143 MLX5_GET(query_hca_cap_out, out, 1144 capability.wqe_based_flow_table_cap.fdb_jump_to_tir_stc); 1145 } 1146 1147 if (caps->eswitch_manager) { 1148 MLX5_SET(query_hca_cap_in, in, op_mod, 1149 MLX5_GET_HCA_CAP_OP_MOD_ESW_FLOW_TABLE | HCA_CAP_OPMOD_GET_CUR); 1150 1151 ret = mlx5_cmd_exec(mdev, in, sizeof(in), out, out_size); 1152 if (ret) { 1153 mlx5_core_err(mdev, "Failed to query flow table esw caps\n"); 1154 goto out; 1155 } 1156 1157 caps->fdb_ft.max_level = 1158 MLX5_GET(query_hca_cap_out, out, 1159 capability.flow_table_nic_cap.flow_table_properties_nic_receive.max_ft_level); 1160 1161 caps->fdb_ft.reparse = 1162 MLX5_GET(query_hca_cap_out, out, 1163 capability.flow_table_nic_cap.flow_table_properties_nic_receive.reparse); 1164 1165 MLX5_SET(query_hca_cap_in, in, op_mod, 1166 MLX5_SET_HCA_CAP_OP_MOD_ESW | HCA_CAP_OPMOD_GET_CUR); 1167 1168 ret = mlx5_cmd_exec(mdev, in, sizeof(in), out, out_size); 1169 if (ret) { 1170 mlx5_core_err(mdev, "Failed to query eswitch capabilities\n"); 1171 goto out; 1172 } 1173 1174 if (MLX5_GET(query_hca_cap_out, out, 1175 capability.esw_cap.esw_manager_vport_number_valid)) 1176 caps->eswitch_manager_vport_number = 1177 MLX5_GET(query_hca_cap_out, out, 1178 capability.esw_cap.esw_manager_vport_number); 1179 1180 caps->merged_eswitch = MLX5_GET(query_hca_cap_out, out, 1181 capability.esw_cap.merged_eswitch); 1182 } 1183 1184 ret = mlx5_cmd_exec(mdev, in, sizeof(in), out, out_size); 1185 if (ret) { 1186 mlx5_core_err(mdev, "Failed to query device attributes\n"); 1187 goto out; 1188 } 1189 1190 snprintf(caps->fw_ver, sizeof(caps->fw_ver), "%d.%d.%d", 1191 fw_rev_maj(mdev), fw_rev_min(mdev), fw_rev_sub(mdev)); 1192 1193 caps->is_ecpf = mlx5_core_is_ecpf_esw_manager(mdev); 1194 1195out: 1196 kfree(out); 1197 return ret; 1198} 1199 1200int mlx5hws_cmd_query_gvmi(struct mlx5_core_dev *mdev, bool other_function, 1201 u16 vport_number, u16 *gvmi) 1202{ 1203 int err; 1204 1205 if (!other_function) { 1206 /* self vhca_id */ 1207 *gvmi = MLX5_CAP_GEN(mdev, vhca_id); 1208 return 0; 1209 } 1210 1211 err = mlx5_vport_get_vhca_id(mdev, vport_number, gvmi); 1212 if (err) { 1213 mlx5_core_err(mdev, "Failed to get vport vhca id for vport %d\n", 1214 vport_number); 1215 return err; 1216 } 1217 1218 return 0; 1219}
~/
Read-only file preview.