|
@@ -84,3 +84,262 @@ void mlx5_query_nic_vport_mac_address(struct mlx5_core_dev *mdev, u8 *addr)
|
|
|
kvfree(out);
|
|
|
}
|
|
|
EXPORT_SYMBOL(mlx5_query_nic_vport_mac_address);
|
|
|
+
|
|
|
+int mlx5_query_hca_vport_gid(struct mlx5_core_dev *dev, u8 other_vport,
|
|
|
+ u8 port_num, u16 vf_num, u16 gid_index,
|
|
|
+ union ib_gid *gid)
|
|
|
+{
|
|
|
+ int in_sz = MLX5_ST_SZ_BYTES(query_hca_vport_gid_in);
|
|
|
+ int out_sz = MLX5_ST_SZ_BYTES(query_hca_vport_gid_out);
|
|
|
+ int is_group_manager;
|
|
|
+ void *out = NULL;
|
|
|
+ void *in = NULL;
|
|
|
+ union ib_gid *tmp;
|
|
|
+ int tbsz;
|
|
|
+ int nout;
|
|
|
+ int err;
|
|
|
+
|
|
|
+ is_group_manager = MLX5_CAP_GEN(dev, vport_group_manager);
|
|
|
+ tbsz = mlx5_get_gid_table_len(MLX5_CAP_GEN(dev, gid_table_size));
|
|
|
+ mlx5_core_dbg(dev, "vf_num %d, index %d, gid_table_size %d\n",
|
|
|
+ vf_num, gid_index, tbsz);
|
|
|
+
|
|
|
+ if (gid_index > tbsz && gid_index != 0xffff)
|
|
|
+ return -EINVAL;
|
|
|
+
|
|
|
+ if (gid_index == 0xffff)
|
|
|
+ nout = tbsz;
|
|
|
+ else
|
|
|
+ nout = 1;
|
|
|
+
|
|
|
+ out_sz += nout * sizeof(*gid);
|
|
|
+
|
|
|
+ in = kzalloc(in_sz, GFP_KERNEL);
|
|
|
+ out = kzalloc(out_sz, GFP_KERNEL);
|
|
|
+ if (!in || !out) {
|
|
|
+ err = -ENOMEM;
|
|
|
+ goto out;
|
|
|
+ }
|
|
|
+
|
|
|
+ MLX5_SET(query_hca_vport_gid_in, in, opcode, MLX5_CMD_OP_QUERY_HCA_VPORT_GID);
|
|
|
+ if (other_vport) {
|
|
|
+ if (is_group_manager) {
|
|
|
+ MLX5_SET(query_hca_vport_gid_in, in, vport_number, vf_num);
|
|
|
+ MLX5_SET(query_hca_vport_gid_in, in, other_vport, 1);
|
|
|
+ } else {
|
|
|
+ err = -EPERM;
|
|
|
+ goto out;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ MLX5_SET(query_hca_vport_gid_in, in, gid_index, gid_index);
|
|
|
+
|
|
|
+ if (MLX5_CAP_GEN(dev, num_ports) == 2)
|
|
|
+ MLX5_SET(query_hca_vport_gid_in, in, port_num, port_num);
|
|
|
+
|
|
|
+ err = mlx5_cmd_exec(dev, in, in_sz, out, out_sz);
|
|
|
+ if (err)
|
|
|
+ goto out;
|
|
|
+
|
|
|
+ err = mlx5_cmd_status_to_err_v2(out);
|
|
|
+ if (err)
|
|
|
+ goto out;
|
|
|
+
|
|
|
+ tmp = out + MLX5_ST_SZ_BYTES(query_hca_vport_gid_out);
|
|
|
+ gid->global.subnet_prefix = tmp->global.subnet_prefix;
|
|
|
+ gid->global.interface_id = tmp->global.interface_id;
|
|
|
+
|
|
|
+out:
|
|
|
+ kfree(in);
|
|
|
+ kfree(out);
|
|
|
+ return err;
|
|
|
+}
|
|
|
+EXPORT_SYMBOL_GPL(mlx5_query_hca_vport_gid);
|
|
|
+
|
|
|
+int mlx5_query_hca_vport_pkey(struct mlx5_core_dev *dev, u8 other_vport,
|
|
|
+ u8 port_num, u16 vf_num, u16 pkey_index,
|
|
|
+ u16 *pkey)
|
|
|
+{
|
|
|
+ int in_sz = MLX5_ST_SZ_BYTES(query_hca_vport_pkey_in);
|
|
|
+ int out_sz = MLX5_ST_SZ_BYTES(query_hca_vport_pkey_out);
|
|
|
+ int is_group_manager;
|
|
|
+ void *out = NULL;
|
|
|
+ void *in = NULL;
|
|
|
+ void *pkarr;
|
|
|
+ int nout;
|
|
|
+ int tbsz;
|
|
|
+ int err;
|
|
|
+ int i;
|
|
|
+
|
|
|
+ is_group_manager = MLX5_CAP_GEN(dev, vport_group_manager);
|
|
|
+
|
|
|
+ tbsz = mlx5_to_sw_pkey_sz(MLX5_CAP_GEN(dev, pkey_table_size));
|
|
|
+ if (pkey_index > tbsz && pkey_index != 0xffff)
|
|
|
+ return -EINVAL;
|
|
|
+
|
|
|
+ if (pkey_index == 0xffff)
|
|
|
+ nout = tbsz;
|
|
|
+ else
|
|
|
+ nout = 1;
|
|
|
+
|
|
|
+ out_sz += nout * MLX5_ST_SZ_BYTES(pkey);
|
|
|
+
|
|
|
+ in = kzalloc(in_sz, GFP_KERNEL);
|
|
|
+ out = kzalloc(out_sz, GFP_KERNEL);
|
|
|
+ if (!in || !out) {
|
|
|
+ err = -ENOMEM;
|
|
|
+ goto out;
|
|
|
+ }
|
|
|
+
|
|
|
+ MLX5_SET(query_hca_vport_pkey_in, in, opcode, MLX5_CMD_OP_QUERY_HCA_VPORT_PKEY);
|
|
|
+ if (other_vport) {
|
|
|
+ if (is_group_manager) {
|
|
|
+ MLX5_SET(query_hca_vport_pkey_in, in, vport_number, vf_num);
|
|
|
+ MLX5_SET(query_hca_vport_pkey_in, in, other_vport, 1);
|
|
|
+ } else {
|
|
|
+ err = -EPERM;
|
|
|
+ goto out;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ MLX5_SET(query_hca_vport_pkey_in, in, pkey_index, pkey_index);
|
|
|
+
|
|
|
+ if (MLX5_CAP_GEN(dev, num_ports) == 2)
|
|
|
+ MLX5_SET(query_hca_vport_pkey_in, in, port_num, port_num);
|
|
|
+
|
|
|
+ err = mlx5_cmd_exec(dev, in, in_sz, out, out_sz);
|
|
|
+ if (err)
|
|
|
+ goto out;
|
|
|
+
|
|
|
+ err = mlx5_cmd_status_to_err_v2(out);
|
|
|
+ if (err)
|
|
|
+ goto out;
|
|
|
+
|
|
|
+ pkarr = MLX5_ADDR_OF(query_hca_vport_pkey_out, out, pkey);
|
|
|
+ for (i = 0; i < nout; i++, pkey++, pkarr += MLX5_ST_SZ_BYTES(pkey))
|
|
|
+ *pkey = MLX5_GET_PR(pkey, pkarr, pkey);
|
|
|
+
|
|
|
+out:
|
|
|
+ kfree(in);
|
|
|
+ kfree(out);
|
|
|
+ return err;
|
|
|
+}
|
|
|
+EXPORT_SYMBOL_GPL(mlx5_query_hca_vport_pkey);
|
|
|
+
|
|
|
+int mlx5_query_hca_vport_context(struct mlx5_core_dev *dev,
|
|
|
+ u8 other_vport, u8 port_num,
|
|
|
+ u16 vf_num,
|
|
|
+ struct mlx5_hca_vport_context *rep)
|
|
|
+{
|
|
|
+ int out_sz = MLX5_ST_SZ_BYTES(query_hca_vport_context_out);
|
|
|
+ int in[MLX5_ST_SZ_DW(query_hca_vport_context_in)];
|
|
|
+ int is_group_manager;
|
|
|
+ void *out;
|
|
|
+ void *ctx;
|
|
|
+ int err;
|
|
|
+
|
|
|
+ is_group_manager = MLX5_CAP_GEN(dev, vport_group_manager);
|
|
|
+
|
|
|
+ memset(in, 0, sizeof(in));
|
|
|
+ out = kzalloc(out_sz, GFP_KERNEL);
|
|
|
+ if (!out)
|
|
|
+ return -ENOMEM;
|
|
|
+
|
|
|
+ MLX5_SET(query_hca_vport_context_in, in, opcode, MLX5_CMD_OP_QUERY_HCA_VPORT_CONTEXT);
|
|
|
+
|
|
|
+ if (other_vport) {
|
|
|
+ if (is_group_manager) {
|
|
|
+ MLX5_SET(query_hca_vport_context_in, in, other_vport, 1);
|
|
|
+ MLX5_SET(query_hca_vport_context_in, in, vport_number, vf_num);
|
|
|
+ } else {
|
|
|
+ err = -EPERM;
|
|
|
+ goto ex;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ if (MLX5_CAP_GEN(dev, num_ports) == 2)
|
|
|
+ MLX5_SET(query_hca_vport_context_in, in, port_num, port_num);
|
|
|
+
|
|
|
+ err = mlx5_cmd_exec(dev, in, sizeof(in), out, out_sz);
|
|
|
+ if (err)
|
|
|
+ goto ex;
|
|
|
+ err = mlx5_cmd_status_to_err_v2(out);
|
|
|
+ if (err)
|
|
|
+ goto ex;
|
|
|
+
|
|
|
+ ctx = MLX5_ADDR_OF(query_hca_vport_context_out, out, hca_vport_context);
|
|
|
+ rep->field_select = MLX5_GET_PR(hca_vport_context, ctx, field_select);
|
|
|
+ rep->sm_virt_aware = MLX5_GET_PR(hca_vport_context, ctx, sm_virt_aware);
|
|
|
+ rep->has_smi = MLX5_GET_PR(hca_vport_context, ctx, has_smi);
|
|
|
+ rep->has_raw = MLX5_GET_PR(hca_vport_context, ctx, has_raw);
|
|
|
+ rep->policy = MLX5_GET_PR(hca_vport_context, ctx, vport_state_policy);
|
|
|
+ rep->phys_state = MLX5_GET_PR(hca_vport_context, ctx,
|
|
|
+ port_physical_state);
|
|
|
+ rep->vport_state = MLX5_GET_PR(hca_vport_context, ctx, vport_state);
|
|
|
+ rep->port_physical_state = MLX5_GET_PR(hca_vport_context, ctx,
|
|
|
+ port_physical_state);
|
|
|
+ rep->port_guid = MLX5_GET64_PR(hca_vport_context, ctx, port_guid);
|
|
|
+ rep->node_guid = MLX5_GET64_PR(hca_vport_context, ctx, node_guid);
|
|
|
+ rep->cap_mask1 = MLX5_GET_PR(hca_vport_context, ctx, cap_mask1);
|
|
|
+ rep->cap_mask1_perm = MLX5_GET_PR(hca_vport_context, ctx,
|
|
|
+ cap_mask1_field_select);
|
|
|
+ rep->cap_mask2 = MLX5_GET_PR(hca_vport_context, ctx, cap_mask2);
|
|
|
+ rep->cap_mask2_perm = MLX5_GET_PR(hca_vport_context, ctx,
|
|
|
+ cap_mask2_field_select);
|
|
|
+ rep->lid = MLX5_GET_PR(hca_vport_context, ctx, lid);
|
|
|
+ rep->init_type_reply = MLX5_GET_PR(hca_vport_context, ctx,
|
|
|
+ init_type_reply);
|
|
|
+ rep->lmc = MLX5_GET_PR(hca_vport_context, ctx, lmc);
|
|
|
+ rep->subnet_timeout = MLX5_GET_PR(hca_vport_context, ctx,
|
|
|
+ subnet_timeout);
|
|
|
+ rep->sm_lid = MLX5_GET_PR(hca_vport_context, ctx, sm_lid);
|
|
|
+ rep->sm_sl = MLX5_GET_PR(hca_vport_context, ctx, sm_sl);
|
|
|
+ rep->qkey_violation_counter = MLX5_GET_PR(hca_vport_context, ctx,
|
|
|
+ qkey_violation_counter);
|
|
|
+ rep->pkey_violation_counter = MLX5_GET_PR(hca_vport_context, ctx,
|
|
|
+ pkey_violation_counter);
|
|
|
+ rep->grh_required = MLX5_GET_PR(hca_vport_context, ctx, grh_required);
|
|
|
+ rep->sys_image_guid = MLX5_GET64_PR(hca_vport_context, ctx,
|
|
|
+ system_image_guid);
|
|
|
+
|
|
|
+ex:
|
|
|
+ kfree(out);
|
|
|
+ return err;
|
|
|
+}
|
|
|
+EXPORT_SYMBOL_GPL(mlx5_query_hca_vport_context);
|
|
|
+
|
|
|
+int mlx5_query_hca_vport_system_image_guid(struct mlx5_core_dev *dev,
|
|
|
+ __be64 *sys_image_guid)
|
|
|
+{
|
|
|
+ struct mlx5_hca_vport_context *rep;
|
|
|
+ int err;
|
|
|
+
|
|
|
+ rep = kzalloc(sizeof(*rep), GFP_KERNEL);
|
|
|
+ if (!rep)
|
|
|
+ return -ENOMEM;
|
|
|
+
|
|
|
+ err = mlx5_query_hca_vport_context(dev, 0, 1, 0, rep);
|
|
|
+ if (!err)
|
|
|
+ *sys_image_guid = rep->sys_image_guid;
|
|
|
+
|
|
|
+ kfree(rep);
|
|
|
+ return err;
|
|
|
+}
|
|
|
+EXPORT_SYMBOL_GPL(mlx5_query_hca_vport_system_image_guid);
|
|
|
+
|
|
|
+int mlx5_query_hca_vport_node_guid(struct mlx5_core_dev *dev,
|
|
|
+ u64 *node_guid)
|
|
|
+{
|
|
|
+ struct mlx5_hca_vport_context *rep;
|
|
|
+ int err;
|
|
|
+
|
|
|
+ rep = kzalloc(sizeof(*rep), GFP_KERNEL);
|
|
|
+ if (!rep)
|
|
|
+ return -ENOMEM;
|
|
|
+
|
|
|
+ err = mlx5_query_hca_vport_context(dev, 0, 1, 0, rep);
|
|
|
+ if (!err)
|
|
|
+ *node_guid = rep->node_guid;
|
|
|
+
|
|
|
+ kfree(rep);
|
|
|
+ return err;
|
|
|
+}
|
|
|
+EXPORT_SYMBOL_GPL(mlx5_query_hca_vport_node_guid);
|