diff options
| -rw-r--r-- | drivers/net/ethernet/mellanox/mlx5/core/ecpf.c | 24 | ||||
| -rw-r--r-- | drivers/net/ethernet/mellanox/mlx5/core/ecpf.h | 4 | ||||
| -rw-r--r-- | drivers/net/ethernet/mellanox/mlx5/core/esw/ipsec.c | 83 | ||||
| -rw-r--r-- | drivers/net/ethernet/mellanox/mlx5/core/eswitch.c | 157 | ||||
| -rw-r--r-- | drivers/net/ethernet/mellanox/mlx5/core/eswitch.h | 16 | ||||
| -rw-r--r-- | drivers/net/ethernet/mellanox/mlx5/core/eswitch_offloads.c | 38 | ||||
| -rw-r--r-- | drivers/net/ethernet/mellanox/mlx5/core/mlx5_core.h | 6 | ||||
| -rw-r--r-- | drivers/net/ethernet/mellanox/mlx5/core/pci_irq.c | 27 | ||||
| -rw-r--r-- | drivers/net/ethernet/mellanox/mlx5/core/sriov.c | 8 | ||||
| -rw-r--r-- | drivers/net/ethernet/mellanox/mlx5/core/vport.c | 12 |
10 files changed, 227 insertions, 148 deletions
diff --git a/drivers/net/ethernet/mellanox/mlx5/core/ecpf.c b/drivers/net/ethernet/mellanox/mlx5/core/ecpf.c index 15cb27aea2c9..350c47d3643b 100644 --- a/drivers/net/ethernet/mellanox/mlx5/core/ecpf.c +++ b/drivers/net/ethernet/mellanox/mlx5/core/ecpf.c @@ -18,25 +18,35 @@ static bool mlx5_ecpf_esw_admins_host_pf(const struct mlx5_core_dev *dev) return mlx5_core_is_ecpf_esw_manager(dev); } -int mlx5_cmd_host_pf_enable_hca(struct mlx5_core_dev *dev) +int mlx5_cmd_pf_enable_hca(struct mlx5_core_dev *dev, u16 vport_num) { u32 out[MLX5_ST_SZ_DW(enable_hca_out)] = {}; u32 in[MLX5_ST_SZ_DW(enable_hca_in)] = {}; + u16 vhca_id; MLX5_SET(enable_hca_in, in, opcode, MLX5_CMD_OP_ENABLE_HCA); - MLX5_SET(enable_hca_in, in, function_id, 0); - MLX5_SET(enable_hca_in, in, embedded_cpu_function, 0); - return mlx5_cmd_exec(dev, &in, sizeof(in), &out, sizeof(out)); + if (mlx5_vport_use_vhca_id_as_func_id(dev, vport_num, &vhca_id)) { + MLX5_SET(enable_hca_in, in, function_id, vhca_id); + MLX5_SET(enable_hca_in, in, function_id_type, 1); + } else { + MLX5_SET(enable_hca_in, in, function_id, vport_num); + } + return mlx5_cmd_exec(dev, in, sizeof(in), out, sizeof(out)); } -int mlx5_cmd_host_pf_disable_hca(struct mlx5_core_dev *dev) +int mlx5_cmd_pf_disable_hca(struct mlx5_core_dev *dev, u16 vport_num) { u32 out[MLX5_ST_SZ_DW(disable_hca_out)] = {}; u32 in[MLX5_ST_SZ_DW(disable_hca_in)] = {}; + u16 vhca_id; MLX5_SET(disable_hca_in, in, opcode, MLX5_CMD_OP_DISABLE_HCA); - MLX5_SET(disable_hca_in, in, function_id, 0); - MLX5_SET(disable_hca_in, in, embedded_cpu_function, 0); + if (mlx5_vport_use_vhca_id_as_func_id(dev, vport_num, &vhca_id)) { + MLX5_SET(disable_hca_in, in, function_id, vhca_id); + MLX5_SET(disable_hca_in, in, function_id_type, 1); + } else { + MLX5_SET(disable_hca_in, in, function_id, vport_num); + } return mlx5_cmd_exec(dev, in, sizeof(in), out, sizeof(out)); } diff --git a/drivers/net/ethernet/mellanox/mlx5/core/ecpf.h b/drivers/net/ethernet/mellanox/mlx5/core/ecpf.h index 40b6ad76dca6..d9f9a53b019b 100644 --- a/drivers/net/ethernet/mellanox/mlx5/core/ecpf.h +++ b/drivers/net/ethernet/mellanox/mlx5/core/ecpf.h @@ -17,8 +17,8 @@ bool mlx5_read_embedded_cpu(struct mlx5_core_dev *dev); int mlx5_ec_init(struct mlx5_core_dev *dev); void mlx5_ec_cleanup(struct mlx5_core_dev *dev); -int mlx5_cmd_host_pf_enable_hca(struct mlx5_core_dev *dev); -int mlx5_cmd_host_pf_disable_hca(struct mlx5_core_dev *dev); +int mlx5_cmd_pf_enable_hca(struct mlx5_core_dev *dev, u16 vport_num); +int mlx5_cmd_pf_disable_hca(struct mlx5_core_dev *dev, u16 vport_num); #else /* CONFIG_MLX5_ESWITCH */ diff --git a/drivers/net/ethernet/mellanox/mlx5/core/esw/ipsec.c b/drivers/net/ethernet/mellanox/mlx5/core/esw/ipsec.c index 4811b60ea430..2b5765ab60d1 100644 --- a/drivers/net/ethernet/mellanox/mlx5/core/esw/ipsec.c +++ b/drivers/net/ethernet/mellanox/mlx5/core/esw/ipsec.c @@ -81,38 +81,25 @@ free: static int esw_ipsec_vf_set_generic(struct mlx5_core_dev *dev, u16 vport_num, bool ipsec_ofld) { int query_sz = MLX5_ST_SZ_BYTES(query_hca_cap_out); - int set_sz = MLX5_ST_SZ_BYTES(set_hca_cap_in); - void *hca_cap, *query_cap, *cap; + void *query_cap, *hca_caps; int ret; if (!MLX5_CAP_GEN(dev, vhca_resource_manager)) return -EOPNOTSUPP; query_cap = kvzalloc(query_sz, GFP_KERNEL); - hca_cap = kvzalloc(set_sz, GFP_KERNEL); - if (!hca_cap || !query_cap) { - ret = -ENOMEM; - goto free; - } + if (!query_cap) + return -ENOMEM; ret = mlx5_vport_get_other_func_general_cap(dev, vport_num, query_cap); if (ret) goto free; - cap = MLX5_ADDR_OF(set_hca_cap_in, hca_cap, capability); - memcpy(cap, MLX5_ADDR_OF(query_hca_cap_out, query_cap, capability), - MLX5_UN_SZ_BYTES(hca_cap_union)); - MLX5_SET(cmd_hca_cap, cap, ipsec_offload, ipsec_ofld); + hca_caps = MLX5_ADDR_OF(query_hca_cap_out, query_cap, capability); + MLX5_SET(cmd_hca_cap, hca_caps, ipsec_offload, ipsec_ofld); - MLX5_SET(set_hca_cap_in, hca_cap, opcode, MLX5_CMD_OP_SET_HCA_CAP); - MLX5_SET(set_hca_cap_in, hca_cap, other_function, 1); - MLX5_SET(set_hca_cap_in, hca_cap, function_id, vport_num); - - MLX5_SET(set_hca_cap_in, hca_cap, op_mod, - MLX5_SET_HCA_CAP_OP_MOD_GENERAL_DEVICE << 1); - ret = mlx5_cmd_exec_in(dev, set_hca_cap, hca_cap); + ret = mlx5_vport_set_other_func_general_cap(dev, hca_caps, vport_num); free: - kvfree(hca_cap); kvfree(query_cap); return ret; } @@ -121,49 +108,37 @@ static int esw_ipsec_vf_set_bytype(struct mlx5_core_dev *dev, struct mlx5_vport bool enable, enum esw_vport_ipsec_offload type) { int query_sz = MLX5_ST_SZ_BYTES(query_hca_cap_out); - int set_sz = MLX5_ST_SZ_BYTES(set_hca_cap_in); - void *hca_cap, *query_cap, *cap; + void *query_cap, *hca_caps; int ret; if (!MLX5_CAP_GEN(dev, vhca_resource_manager)) return -EOPNOTSUPP; query_cap = kvzalloc(query_sz, GFP_KERNEL); - hca_cap = kvzalloc(set_sz, GFP_KERNEL); - if (!hca_cap || !query_cap) { - ret = -ENOMEM; - goto free; - } + if (!query_cap) + return -ENOMEM; ret = mlx5_vport_get_other_func_cap(dev, vport->vport, query_cap, MLX5_CAP_IPSEC); if (ret) goto free; - cap = MLX5_ADDR_OF(set_hca_cap_in, hca_cap, capability); - memcpy(cap, MLX5_ADDR_OF(query_hca_cap_out, query_cap, capability), - MLX5_UN_SZ_BYTES(hca_cap_union)); + hca_caps = MLX5_ADDR_OF(query_hca_cap_out, query_cap, capability); switch (type) { case MLX5_ESW_VPORT_IPSEC_CRYPTO_OFFLOAD: - MLX5_SET(ipsec_cap, cap, ipsec_crypto_offload, enable); + MLX5_SET(ipsec_cap, hca_caps, ipsec_crypto_offload, enable); break; case MLX5_ESW_VPORT_IPSEC_PACKET_OFFLOAD: - MLX5_SET(ipsec_cap, cap, ipsec_full_offload, enable); + MLX5_SET(ipsec_cap, hca_caps, ipsec_full_offload, enable); break; default: ret = -EOPNOTSUPP; goto free; } - MLX5_SET(set_hca_cap_in, hca_cap, opcode, MLX5_CMD_OP_SET_HCA_CAP); - MLX5_SET(set_hca_cap_in, hca_cap, other_function, 1); - MLX5_SET(set_hca_cap_in, hca_cap, function_id, vport->vport); - - MLX5_SET(set_hca_cap_in, hca_cap, op_mod, - MLX5_SET_HCA_CAP_OP_MOD_IPSEC << 1); - ret = mlx5_cmd_exec_in(dev, set_hca_cap, hca_cap); + ret = mlx5_vport_set_other_func_cap(dev, hca_caps, vport->vport, + MLX5_SET_HCA_CAP_OP_MOD_IPSEC); free: - kvfree(hca_cap); kvfree(query_cap); return ret; } @@ -171,34 +146,24 @@ free: static int esw_ipsec_vf_crypto_aux_caps_set(struct mlx5_core_dev *dev, u16 vport_num, bool enable) { int query_sz = MLX5_ST_SZ_BYTES(query_hca_cap_out); - int set_sz = MLX5_ST_SZ_BYTES(set_hca_cap_in); - struct mlx5_eswitch *esw = dev->priv.eswitch; - void *hca_cap, *query_cap, *cap; + void *query_cap, *hca_caps; int ret; query_cap = kvzalloc(query_sz, GFP_KERNEL); - hca_cap = kvzalloc(set_sz, GFP_KERNEL); - if (!hca_cap || !query_cap) { - ret = -ENOMEM; - goto free; - } + if (!query_cap) + return -ENOMEM; ret = mlx5_vport_get_other_func_cap(dev, vport_num, query_cap, MLX5_CAP_ETHERNET_OFFLOADS); if (ret) goto free; - cap = MLX5_ADDR_OF(set_hca_cap_in, hca_cap, capability); - memcpy(cap, MLX5_ADDR_OF(query_hca_cap_out, query_cap, capability), - MLX5_UN_SZ_BYTES(hca_cap_union)); - MLX5_SET(per_protocol_networking_offload_caps, cap, insert_trailer, enable); - MLX5_SET(set_hca_cap_in, hca_cap, opcode, MLX5_CMD_OP_SET_HCA_CAP); - MLX5_SET(set_hca_cap_in, hca_cap, other_function, 1); - MLX5_SET(set_hca_cap_in, hca_cap, function_id, vport_num); - MLX5_SET(set_hca_cap_in, hca_cap, op_mod, - MLX5_SET_HCA_CAP_OP_MOD_ETHERNET_OFFLOADS << 1); - ret = mlx5_cmd_exec_in(esw->dev, set_hca_cap, hca_cap); + hca_caps = MLX5_ADDR_OF(query_hca_cap_out, query_cap, capability); + MLX5_SET(per_protocol_networking_offload_caps, hca_caps, + insert_trailer, enable); + + ret = mlx5_vport_set_other_func_cap(dev, hca_caps, vport_num, + MLX5_SET_HCA_CAP_OP_MOD_ETHERNET_OFFLOADS); free: - kvfree(hca_cap); kvfree(query_cap); return ret; } @@ -209,7 +174,7 @@ static int esw_ipsec_vf_offload_set_bytype(struct mlx5_eswitch *esw, struct mlx5 struct mlx5_core_dev *dev = esw->dev; int err; - if (vport->vport == MLX5_VPORT_HOST_PF) + if (!mlx5_eswitch_is_vf_vport(esw, vport->vport)) return -EOPNOTSUPP; if (type == MLX5_ESW_VPORT_IPSEC_CRYPTO_OFFLOAD) { diff --git a/drivers/net/ethernet/mellanox/mlx5/core/eswitch.c b/drivers/net/ethernet/mellanox/mlx5/core/eswitch.c index 43c40353b2d8..206911817a04 100644 --- a/drivers/net/ethernet/mellanox/mlx5/core/eswitch.c +++ b/drivers/net/ethernet/mellanox/mlx5/core/eswitch.c @@ -958,7 +958,7 @@ int mlx5_esw_vport_enable(struct mlx5_eswitch *esw, struct mlx5_vport *vport, /* Sync with current vport context */ vport->enabled_events = enabled_events; vport->enabled = true; - if (vport->vport != MLX5_VPORT_HOST_PF && + if (mlx5_eswitch_is_vf_vport(esw, vport_num) && (vport->info.ipsec_crypto_enabled || vport->info.ipsec_packet_enabled)) esw->enabled_ipsec_vf_count++; @@ -1020,7 +1020,7 @@ void mlx5_esw_vport_disable(struct mlx5_eswitch *esw, struct mlx5_vport *vport) mlx5_esw_vport_vhca_id_unmap(esw, vport); } - if (vport->vport != MLX5_VPORT_HOST_PF && + if (mlx5_eswitch_is_vf_vport(esw, vport_num) && (vport->info.ipsec_crypto_enabled || vport->info.ipsec_packet_enabled)) esw->enabled_ipsec_vf_count--; @@ -1063,11 +1063,28 @@ static int eswitch_vport_event(struct notifier_block *nb, */ const u32 *mlx5_esw_query_functions(struct mlx5_core_dev *dev) { - int outlen = MLX5_ST_SZ_BYTES(query_esw_functions_out); + bool net_func_v1 = MLX5_CAP_GEN(dev, query_host_net_function_v1); u32 in[MLX5_ST_SZ_DW(query_esw_functions_in)] = {}; + int alloc_entries; + int outlen; u32 *out; int err; + if (net_func_v1) { + alloc_entries = MLX5_CAP_GEN(dev, + query_host_net_function_num_max); + alloc_entries = max(alloc_entries, 1); + MLX5_SET(query_esw_functions_in, in, op_mod, + MLX5_QUERY_ESW_FUNC_OP_MOD_LAYOUT_V1); + outlen = MLX5_BYTE_OFF(query_esw_functions_out, + net_function_params) + + alloc_entries * MLX5_UN_SZ_BYTES(net_function_params); + outlen = max_t(int, outlen, + MLX5_ST_SZ_BYTES(query_esw_functions_out)); + } else { + outlen = MLX5_ST_SZ_BYTES(query_esw_functions_out); + } + out = kvzalloc(outlen, GFP_KERNEL); if (!out) return ERR_PTR(-ENOMEM); @@ -1076,17 +1093,102 @@ const u32 *mlx5_esw_query_functions(struct mlx5_core_dev *dev) MLX5_CMD_OP_QUERY_ESW_FUNCTIONS); err = mlx5_cmd_exec(dev, in, sizeof(in), out, outlen); - if (!err) - return out; + if (err) + goto free; + + if (net_func_v1) { + int num_entries; + + num_entries = MLX5_GET(query_esw_functions_out, out, + net_function_num); + if (num_entries > alloc_entries) { + mlx5_core_warn(dev, "Got %d entries, max expected %d\n", + num_entries, alloc_entries); + err = -EINVAL; + goto free; + } + } + return out; + +free: kvfree(out); return ERR_PTR(err); } +static struct mlx5_esw_pf_info +mlx5_esw_host_pf_from_host_params(const void *entry) +{ + return (struct mlx5_esw_pf_info) { + .pf_not_exist = MLX5_GET(host_params_context, entry, + host_pf_not_exist), + .pf_disabled = MLX5_GET(host_params_context, entry, + host_pf_disabled), + .num_of_vfs = MLX5_GET(host_params_context, entry, + host_num_of_vfs), + .total_vfs = MLX5_GET(host_params_context, entry, + host_total_vfs), + .host_number = MLX5_GET(host_params_context, entry, + host_number), + }; +} + +static struct mlx5_esw_pf_info +mlx5_esw_host_pf_from_net_func_params(const u8 *entry, int num_entries) +{ + int i; + + for (i = 0; i < num_entries; i++) { + int pf_type, state; + + pf_type = MLX5_GET(network_function_params, entry, pci_pf_type); + if (pf_type != MLX5_PCI_PF_TYPE_EXTERNAL_HOST_PF) { + entry += MLX5_UN_SZ_BYTES(net_function_params); + continue; + } + + state = MLX5_GET(network_function_params, entry, vhca_state); + + return (struct mlx5_esw_pf_info) { + .pf_disabled = state != MLX5_VHCA_STATE_IN_USE, + .num_of_vfs = MLX5_GET(network_function_params, + entry, pci_num_vfs), + .total_vfs = MLX5_GET(network_function_params, + entry, pci_total_vfs), + .host_number = MLX5_GET(network_function_params, + entry, host_number), + }; + } + + /* No external host PF entry found */ + return (struct mlx5_esw_pf_info) { + .pf_not_exist = true, + .pf_disabled = true, + }; +} + +struct mlx5_esw_pf_info +mlx5_esw_get_host_pf_info(struct mlx5_core_dev *dev, const u32 *out) +{ + const void *entry; + + entry = MLX5_ADDR_OF(query_esw_functions_out, out, net_function_params); + + if (MLX5_CAP_GEN(dev, query_host_net_function_v1)) { + int num_entries = MLX5_GET(query_esw_functions_out, out, + net_function_num); + + return mlx5_esw_host_pf_from_net_func_params(entry, + num_entries); + } + + return mlx5_esw_host_pf_from_host_params(entry); +} + static int mlx5_esw_host_functions_enabled_query(struct mlx5_eswitch *esw) { + struct mlx5_esw_pf_info host_pf_info; const u32 *query_host_out; - void *host_params; if (!mlx5_core_is_ecpf_esw_manager(esw->dev)) return 0; @@ -1095,11 +1197,8 @@ static int mlx5_esw_host_functions_enabled_query(struct mlx5_eswitch *esw) if (IS_ERR(query_host_out)) return PTR_ERR(query_host_out); - host_params = MLX5_ADDR_OF(query_esw_functions_out, - query_host_out, net_function_params); - esw->esw_funcs.host_funcs_disabled = - MLX5_GET(host_params_context, host_params, - host_pf_not_exist); + host_pf_info = mlx5_esw_get_host_pf_info(esw->dev, query_host_out); + esw->esw_funcs.host_funcs_disabled = host_pf_info.pf_not_exist; kvfree(query_host_out); return 0; @@ -1353,7 +1452,7 @@ vf_err: return err; } -int mlx5_esw_host_pf_enable_hca(struct mlx5_core_dev *dev) +static int mlx5_esw_pf_enable_hca(struct mlx5_core_dev *dev, u16 vport_num) { struct mlx5_eswitch *esw = dev->priv.eswitch; struct mlx5_vport *vport; @@ -1362,15 +1461,15 @@ int mlx5_esw_host_pf_enable_hca(struct mlx5_core_dev *dev) if (!mlx5_core_is_ecpf(dev) || !mlx5_esw_allowed(esw)) return 0; - vport = mlx5_eswitch_get_vport(esw, MLX5_VPORT_HOST_PF); + vport = mlx5_eswitch_get_vport(esw, vport_num); if (IS_ERR(vport)) return PTR_ERR(vport); - /* Once vport and representor are ready, take out the external host PF - * out of initializing state. Enabling HCA clears the iser->initializing - * bit and host PF driver loading can progress. + /* Once vport and representor are ready, take the PF out of + * initializing state. Enabling HCA clears the iser->initializing + * bit and PF driver loading can progress. */ - err = mlx5_cmd_host_pf_enable_hca(dev); + err = mlx5_cmd_pf_enable_hca(dev, vport_num); if (err) return err; @@ -1379,7 +1478,7 @@ int mlx5_esw_host_pf_enable_hca(struct mlx5_core_dev *dev) return 0; } -int mlx5_esw_host_pf_disable_hca(struct mlx5_core_dev *dev) +static int mlx5_esw_pf_disable_hca(struct mlx5_core_dev *dev, u16 vport_num) { struct mlx5_eswitch *esw = dev->priv.eswitch; struct mlx5_vport *vport; @@ -1388,11 +1487,11 @@ int mlx5_esw_host_pf_disable_hca(struct mlx5_core_dev *dev) if (!mlx5_core_is_ecpf(dev) || !mlx5_esw_allowed(esw)) return 0; - vport = mlx5_eswitch_get_vport(esw, MLX5_VPORT_HOST_PF); + vport = mlx5_eswitch_get_vport(esw, vport_num); if (IS_ERR(vport)) return PTR_ERR(vport); - err = mlx5_cmd_host_pf_disable_hca(dev); + err = mlx5_cmd_pf_disable_hca(dev, vport_num); if (err) return err; @@ -1401,6 +1500,16 @@ int mlx5_esw_host_pf_disable_hca(struct mlx5_core_dev *dev) return 0; } +int mlx5_esw_host_pf_enable_hca(struct mlx5_core_dev *dev) +{ + return mlx5_esw_pf_enable_hca(dev, MLX5_VPORT_HOST_PF); +} + +int mlx5_esw_host_pf_disable_hca(struct mlx5_core_dev *dev) +{ + return mlx5_esw_pf_disable_hca(dev, MLX5_VPORT_HOST_PF); +} + /* mlx5_eswitch_enable_pf_vf_vports() enables vports of PF, ECPF and VFs * whichever are present on the eswitch. */ @@ -1523,7 +1632,7 @@ static void mlx5_eswitch_get_devlink_param(struct mlx5_eswitch *esw) static void mlx5_eswitch_update_num_of_vfs(struct mlx5_eswitch *esw, int num_vfs) { - void *host_params; + struct mlx5_esw_pf_info host_pf_info; const u32 *out; if (num_vfs < 0) @@ -1538,10 +1647,8 @@ mlx5_eswitch_update_num_of_vfs(struct mlx5_eswitch *esw, int num_vfs) if (IS_ERR(out)) return; - host_params = MLX5_ADDR_OF(query_esw_functions_out, out, - net_function_params); - esw->esw_funcs.num_vfs = MLX5_GET(host_params_context, host_params, - host_num_of_vfs); + host_pf_info = mlx5_esw_get_host_pf_info(esw->dev, out); + esw->esw_funcs.num_vfs = host_pf_info.num_of_vfs; if (mlx5_core_ec_sriov_enabled(esw->dev)) esw->esw_funcs.num_ec_vfs = num_vfs; diff --git a/drivers/net/ethernet/mellanox/mlx5/core/eswitch.h b/drivers/net/ethernet/mellanox/mlx5/core/eswitch.h index 291271afa96c..a5f832ed2251 100644 --- a/drivers/net/ethernet/mellanox/mlx5/core/eswitch.h +++ b/drivers/net/ethernet/mellanox/mlx5/core/eswitch.h @@ -71,6 +71,14 @@ struct mlx5_mapped_obj { }; }; +struct mlx5_esw_pf_info { + bool pf_not_exist; + bool pf_disabled; + u16 num_of_vfs; + u16 total_vfs; + u16 host_number; +}; + #ifdef CONFIG_MLX5_ESWITCH #define ESW_OFFLOADS_DEFAULT_NUM_GROUPS 15 @@ -649,6 +657,8 @@ bool mlx5_esw_multipath_prereq(struct mlx5_core_dev *dev0, struct mlx5_core_dev *dev1); const u32 *mlx5_esw_query_functions(struct mlx5_core_dev *dev); +struct mlx5_esw_pf_info mlx5_esw_get_host_pf_info(struct mlx5_core_dev *dev, + const u32 *out); int mlx5_esw_host_pf_enable_hca(struct mlx5_core_dev *dev); int mlx5_esw_host_pf_disable_hca(struct mlx5_core_dev *dev); @@ -976,6 +986,12 @@ static inline const u32 *mlx5_esw_query_functions(struct mlx5_core_dev *dev) return ERR_PTR(-EOPNOTSUPP); } +static inline struct mlx5_esw_pf_info +mlx5_esw_get_host_pf_info(struct mlx5_core_dev *dev, const u32 *out) +{ + return (struct mlx5_esw_pf_info) {}; +} + static inline struct mlx5_flow_handle * esw_add_restore_rule(struct mlx5_eswitch *esw, u32 tag) { diff --git a/drivers/net/ethernet/mellanox/mlx5/core/eswitch_offloads.c b/drivers/net/ethernet/mellanox/mlx5/core/eswitch_offloads.c index d95af87a4f5f..b06b10d443bd 100644 --- a/drivers/net/ethernet/mellanox/mlx5/core/eswitch_offloads.c +++ b/drivers/net/ethernet/mellanox/mlx5/core/eswitch_offloads.c @@ -3708,8 +3708,7 @@ static void esw_offloads_steering_cleanup(struct mlx5_eswitch *esw) static void esw_vfs_changed_event_handler(struct mlx5_eswitch *esw) { - bool host_pf_disabled; - void *host_params; + struct mlx5_esw_pf_info host_pf_info; u16 new_num_vfs; const u32 *out; @@ -3717,14 +3716,10 @@ static void esw_vfs_changed_event_handler(struct mlx5_eswitch *esw) if (IS_ERR(out)) return; - host_params = MLX5_ADDR_OF(query_esw_functions_out, out, - net_function_params); - new_num_vfs = MLX5_GET(host_params_context, host_params, - host_num_of_vfs); - host_pf_disabled = MLX5_GET(host_params_context, host_params, - host_pf_disabled); + host_pf_info = mlx5_esw_get_host_pf_info(esw->dev, out); + new_num_vfs = host_pf_info.num_of_vfs; - if (new_num_vfs == esw->esw_funcs.num_vfs || host_pf_disabled) + if (new_num_vfs == esw->esw_funcs.num_vfs || host_pf_info.pf_disabled) goto free; mlx5_esw_reps_block(esw); @@ -3826,8 +3821,8 @@ int mlx5_esw_funcs_changed_handler(struct notifier_block *nb, static int mlx5_esw_host_number_init(struct mlx5_eswitch *esw) { + struct mlx5_esw_pf_info host_pf_info; const u32 *query_host_out; - void *host_params; if (!mlx5_core_is_ecpf_esw_manager(esw->dev)) return 0; @@ -3837,10 +3832,8 @@ static int mlx5_esw_host_number_init(struct mlx5_eswitch *esw) return PTR_ERR(query_host_out); /* Mark non local controller with non zero controller number. */ - host_params = MLX5_ADDR_OF(query_esw_functions_out, - query_host_out, net_function_params); - esw->offloads.host_number = MLX5_GET(host_params_context, - host_params, host_number); + host_pf_info = mlx5_esw_get_host_pf_info(esw->dev, query_host_out); + esw->offloads.host_number = host_pf_info.host_number; kvfree(query_host_out); return 0; } @@ -4958,8 +4951,8 @@ int mlx5_devlink_port_fn_roce_set(struct devlink_port *port, bool enable, hca_caps = MLX5_ADDR_OF(query_hca_cap_out, query_ctx, capability); MLX5_SET(cmd_hca_cap, hca_caps, roce, enable); - err = mlx5_vport_set_other_func_cap(esw->dev, hca_caps, vport_num, - MLX5_SET_HCA_CAP_OP_MOD_GENERAL_DEVICE); + err = mlx5_vport_set_other_func_general_cap(esw->dev, hca_caps, + vport_num); if (err) { NL_SET_ERR_MSG_MOD(extack, "Failed setting HCA roce cap"); goto out_free; @@ -4980,9 +4973,8 @@ int mlx5_devlink_pf_port_fn_state_get(struct devlink_port *port, struct netlink_ext_ack *extack) { struct mlx5_vport *vport = mlx5_devlink_port_vport_get(port); + struct mlx5_esw_pf_info host_pf_info; const u32 *query_out; - void *host_params; - bool pf_disabled; if (vport->vport != MLX5_VPORT_HOST_PF) { NL_SET_ERR_MSG_MOD(extack, "State get is not supported for VF"); @@ -4996,13 +4988,11 @@ int mlx5_devlink_pf_port_fn_state_get(struct devlink_port *port, if (IS_ERR(query_out)) return PTR_ERR(query_out); - host_params = MLX5_ADDR_OF(query_esw_functions_out, query_out, - net_function_params); - pf_disabled = MLX5_GET(host_params_context, host_params, - host_pf_disabled); + host_pf_info = mlx5_esw_get_host_pf_info(vport->dev, query_out); - *opstate = pf_disabled ? DEVLINK_PORT_FN_OPSTATE_DETACHED : - DEVLINK_PORT_FN_OPSTATE_ATTACHED; + *opstate = host_pf_info.pf_disabled ? + DEVLINK_PORT_FN_OPSTATE_DETACHED : + DEVLINK_PORT_FN_OPSTATE_ATTACHED; kvfree(query_out); return 0; diff --git a/drivers/net/ethernet/mellanox/mlx5/core/mlx5_core.h b/drivers/net/ethernet/mellanox/mlx5/core/mlx5_core.h index d70907f499a9..51637e58a48b 100644 --- a/drivers/net/ethernet/mellanox/mlx5/core/mlx5_core.h +++ b/drivers/net/ethernet/mellanox/mlx5/core/mlx5_core.h @@ -452,11 +452,17 @@ void mlx5_unload_one_light(struct mlx5_core_dev *dev); void mlx5_query_nic_sw_system_image_guid(struct mlx5_core_dev *mdev, u8 *buf, u8 *len); +bool mlx5_vport_use_vhca_id_as_func_id(struct mlx5_core_dev *dev, + u16 vport_num, u16 *vhca_id); int mlx5_vport_set_other_func_cap(struct mlx5_core_dev *dev, const void *hca_cap, u16 vport, u16 opmod); #define mlx5_vport_get_other_func_general_cap(dev, vport, out) \ mlx5_vport_get_other_func_cap(dev, vport, out, MLX5_CAP_GENERAL) +#define mlx5_vport_set_other_func_general_cap(dev, hca_cap, vport) \ + mlx5_vport_set_other_func_cap(dev, hca_cap, vport, \ + MLX5_SET_HCA_CAP_OP_MOD_GENERAL_DEVICE) + static inline u32 mlx5_sriov_get_vf_total_msix(struct pci_dev *pdev) { struct mlx5_core_dev *dev = pci_get_drvdata(pdev); diff --git a/drivers/net/ethernet/mellanox/mlx5/core/pci_irq.c b/drivers/net/ethernet/mellanox/mlx5/core/pci_irq.c index e051b9a939ee..0f5b8bc7861e 100644 --- a/drivers/net/ethernet/mellanox/mlx5/core/pci_irq.c +++ b/drivers/net/ethernet/mellanox/mlx5/core/pci_irq.c @@ -87,9 +87,8 @@ int mlx5_set_msix_vec_count(struct mlx5_core_dev *dev, int function_id, int msix_vec_count) { int query_sz = MLX5_ST_SZ_BYTES(query_hca_cap_out); - int set_sz = MLX5_ST_SZ_BYTES(set_hca_cap_in); - void *hca_cap = NULL, *query_cap = NULL, *cap; int num_vf_msix, min_msix, max_msix; + void *query_cap, *hca_caps; bool ec_vf_function; int vport; int ret; @@ -111,11 +110,8 @@ int mlx5_set_msix_vec_count(struct mlx5_core_dev *dev, int function_id, return -EOVERFLOW; query_cap = kvzalloc(query_sz, GFP_KERNEL); - hca_cap = kvzalloc(set_sz, GFP_KERNEL); - if (!hca_cap || !query_cap) { - ret = -ENOMEM; - goto out; - } + if (!query_cap) + return -ENOMEM; ec_vf_function = mlx5_core_ec_sriov_enabled(dev); vport = mlx5_core_func_to_vport(dev, function_id, ec_vf_function); @@ -123,21 +119,12 @@ int mlx5_set_msix_vec_count(struct mlx5_core_dev *dev, int function_id, if (ret) goto out; - cap = MLX5_ADDR_OF(set_hca_cap_in, hca_cap, capability); - memcpy(cap, MLX5_ADDR_OF(query_hca_cap_out, query_cap, capability), - MLX5_UN_SZ_BYTES(hca_cap_union)); - MLX5_SET(cmd_hca_cap, cap, dynamic_msix_table_size, msix_vec_count); - - MLX5_SET(set_hca_cap_in, hca_cap, opcode, MLX5_CMD_OP_SET_HCA_CAP); - MLX5_SET(set_hca_cap_in, hca_cap, other_function, 1); - MLX5_SET(set_hca_cap_in, hca_cap, ec_vf_function, ec_vf_function); - MLX5_SET(set_hca_cap_in, hca_cap, function_id, function_id); + hca_caps = MLX5_ADDR_OF(query_hca_cap_out, query_cap, capability); + MLX5_SET(cmd_hca_cap, hca_caps, dynamic_msix_table_size, + msix_vec_count); - MLX5_SET(set_hca_cap_in, hca_cap, op_mod, - MLX5_SET_HCA_CAP_OP_MOD_GENERAL_DEVICE << 1); - ret = mlx5_cmd_exec_in(dev, set_hca_cap, hca_cap); + ret = mlx5_vport_set_other_func_general_cap(dev, hca_caps, vport); out: - kvfree(hca_cap); kvfree(query_cap); return ret; } diff --git a/drivers/net/ethernet/mellanox/mlx5/core/sriov.c b/drivers/net/ethernet/mellanox/mlx5/core/sriov.c index 6eb6026eadd6..0770b5d99c5d 100644 --- a/drivers/net/ethernet/mellanox/mlx5/core/sriov.c +++ b/drivers/net/ethernet/mellanox/mlx5/core/sriov.c @@ -273,8 +273,8 @@ void mlx5_sriov_detach(struct mlx5_core_dev *dev) static u16 mlx5_get_max_vfs(struct mlx5_core_dev *dev) { + struct mlx5_esw_pf_info host_pf_info; u16 host_total_vfs; - void *host_params; const u32 *out; if (mlx5_core_is_ecpf_esw_manager(dev)) { @@ -285,10 +285,8 @@ static u16 mlx5_get_max_vfs(struct mlx5_core_dev *dev) */ if (IS_ERR(out)) goto done; - host_params = MLX5_ADDR_OF(query_esw_functions_out, out, - net_function_params); - host_total_vfs = MLX5_GET(host_params_context, host_params, - host_total_vfs); + host_pf_info = mlx5_esw_get_host_pf_info(dev, out); + host_total_vfs = host_pf_info.total_vfs; kvfree(out); return host_total_vfs; } diff --git a/drivers/net/ethernet/mellanox/mlx5/core/vport.c b/drivers/net/ethernet/mellanox/mlx5/core/vport.c index 4effe37fd455..e0848f4e88dd 100644 --- a/drivers/net/ethernet/mellanox/mlx5/core/vport.c +++ b/drivers/net/ethernet/mellanox/mlx5/core/vport.c @@ -1283,8 +1283,8 @@ void mlx5_query_nic_sw_system_image_guid(struct mlx5_core_dev *mdev, u8 *buf, buf[(*len)++] = MLX5_CAP_GEN_2(mdev, load_balance_id); } -static bool mlx5_vport_use_vhca_id_as_func_id(struct mlx5_core_dev *dev, - u16 vport_num, u16 *vhca_id) +bool mlx5_vport_use_vhca_id_as_func_id(struct mlx5_core_dev *dev, + u16 vport_num, u16 *vhca_id) { if (!MLX5_CAP_GEN_2(dev, function_id_type_vhca_id)) return false; @@ -1336,7 +1336,7 @@ int mlx5_vport_get_vhca_id(struct mlx5_core_dev *dev, u16 vport, u16 *vhca_id) if (mlx5_esw_vport_vhca_id(dev->priv.eswitch, vport, vhca_id)) return 0; - query_ctx = kzalloc(query_out_sz, GFP_KERNEL); + query_ctx = kvzalloc(query_out_sz, GFP_KERNEL); if (!query_ctx) return -ENOMEM; @@ -1348,7 +1348,7 @@ int mlx5_vport_get_vhca_id(struct mlx5_core_dev *dev, u16 vport, u16 *vhca_id) *vhca_id = MLX5_GET(cmd_hca_cap, hca_caps, vhca_id); out_free: - kfree(query_ctx); + kvfree(query_ctx); return err; } EXPORT_SYMBOL_GPL(mlx5_vport_get_vhca_id); @@ -1363,7 +1363,7 @@ int mlx5_vport_set_other_func_cap(struct mlx5_core_dev *dev, const void *hca_cap void *set_ctx; int ret; - set_ctx = kzalloc(set_sz, GFP_KERNEL); + set_ctx = kvzalloc(set_sz, GFP_KERNEL); if (!set_ctx) return -ENOMEM; @@ -1392,6 +1392,6 @@ int mlx5_vport_set_other_func_cap(struct mlx5_core_dev *dev, const void *hca_cap MLX5_SET(set_hca_cap_in, set_ctx, function_id, function_id); ret = mlx5_cmd_exec_in(dev, set_hca_cap, set_ctx); - kfree(set_ctx); + kvfree(set_ctx); return ret; } |
