示例#1
0
int mlx5_set_nic_vport_mc_list(struct mlx5_core_dev *mdev, int vport,
			       u64 *addr_list, size_t addr_list_len)
{
	void *in, *ctx;
	int  inlen = MLX5_ST_SZ_BYTES(modify_nic_vport_context_in)
		  + MLX5_ST_SZ_BYTES(mac_address_layout) * (int)addr_list_len;
	int err;
	size_t i;
	int max_list_sz = 1 << MLX5_CAP_GEN_MAX(mdev, log_max_current_mc_list);

	if ((int)addr_list_len > max_list_sz) {
		mlx5_core_warn(mdev, "Requested list size (%d) > (%d) max_list_size\n",
			       (int)addr_list_len, max_list_sz);
		return -ENOSPC;
	}

	in = mlx5_vzalloc(inlen);
	if (!in) {
		mlx5_core_warn(mdev, "failed to allocate inbox\n");
		return -ENOMEM;
	}

	MLX5_SET(modify_nic_vport_context_in, in, vport_number, vport);
	if (vport)
		MLX5_SET(modify_nic_vport_context_in, in,
			 other_vport, 1);
	MLX5_SET(modify_nic_vport_context_in, in,
		 field_select.addresses_list, 1);

	ctx = MLX5_ADDR_OF(modify_nic_vport_context_in, in, nic_vport_context);

	MLX5_SET(nic_vport_context, ctx, allowed_list_type,
		 MLX5_NIC_VPORT_LIST_TYPE_MC);
	MLX5_SET(nic_vport_context, ctx, allowed_list_size, addr_list_len);

	for (i = 0; i < addr_list_len; i++) {
		u8 *mac_lout = (u8 *)MLX5_ADDR_OF(nic_vport_context, ctx,
						  current_uc_mac_address[i]);
		u8 *mac_ptr = (u8 *)MLX5_ADDR_OF(mac_address_layout, mac_lout,
						 mac_addr_47_32);
		ether_addr_copy(mac_ptr, (u8 *)&addr_list[i]);
	}

	err = mlx5_modify_nic_vport_context(mdev, in, inlen);

	kvfree(in);

	return err;
}
示例#2
0
int mlx5_set_nic_vport_vlan_list(struct mlx5_core_dev *dev, u16 vport,
				 u16 *vlan_list, int list_len)
{
	void *in, *ctx;
	int i, err;
	int  inlen = MLX5_ST_SZ_BYTES(modify_nic_vport_context_in)
		+ MLX5_ST_SZ_BYTES(vlan_layout) * (int)list_len;

	int max_list_size = 1 << MLX5_CAP_GEN_MAX(dev, log_max_vlan_list);

	if (list_len > max_list_size) {
		mlx5_core_warn(dev, "Requested list size (%d) > (%d) max_list_size\n",
			       list_len, max_list_size);
		return -ENOSPC;
	}

	in = mlx5_vzalloc(inlen);
	if (!in) {
		mlx5_core_warn(dev, "failed to allocate inbox\n");
		return -ENOMEM;
	}

	MLX5_SET(modify_nic_vport_context_in, in, vport_number, vport);
	if (vport)
		MLX5_SET(modify_nic_vport_context_in, in,
			 other_vport, 1);
	MLX5_SET(modify_nic_vport_context_in, in,
		 field_select.addresses_list, 1);

	ctx = MLX5_ADDR_OF(modify_nic_vport_context_in, in, nic_vport_context);

	MLX5_SET(nic_vport_context, ctx, allowed_list_type,
		 MLX5_NIC_VPORT_LIST_TYPE_VLAN);
	MLX5_SET(nic_vport_context, ctx, allowed_list_size, list_len);

	for (i = 0; i < list_len; i++) {
		u8 *vlan_lout = MLX5_ADDR_OF(nic_vport_context, ctx,
					 current_uc_mac_address[i]);
		MLX5_SET(vlan_layout, vlan_lout, vlan, vlan_list[i]);
	}

	err = mlx5_modify_nic_vport_context(dev, in, inlen);

	kvfree(in);
	return err;
}
示例#3
0
int mlx5_query_nic_vport_mac_list(struct mlx5_core_dev *dev,
				  u16 vport,
				  enum mlx5_list_type list_type,
				  u8 addr_list[][ETH_ALEN],
				  int *list_size)
{
	u32 in[MLX5_ST_SZ_DW(query_nic_vport_context_in)] = {0};
	void *nic_vport_ctx;
	int max_list_size;
	int req_list_size;
	int out_sz;
	void *out;
	int err;
	int i;

	req_list_size = *list_size;

	max_list_size = (list_type == MLX5_NIC_VPORT_LIST_TYPE_UC) ?
			1 << MLX5_CAP_GEN_MAX(dev, log_max_current_uc_list) :
			1 << MLX5_CAP_GEN_MAX(dev, log_max_current_mc_list);

	if (req_list_size > max_list_size) {
		mlx5_core_warn(dev, "Requested list size (%d) > (%d) max_list_size\n",
			       req_list_size, max_list_size);
		req_list_size = max_list_size;
	}

	out_sz = MLX5_ST_SZ_BYTES(modify_nic_vport_context_in) +
		 req_list_size * MLX5_ST_SZ_BYTES(mac_address_layout);

	out = kzalloc(out_sz, GFP_KERNEL);
	if (!out)
		return -ENOMEM;

	MLX5_SET(query_nic_vport_context_in, in, opcode,
		 MLX5_CMD_OP_QUERY_NIC_VPORT_CONTEXT);
	MLX5_SET(query_nic_vport_context_in, in, allowed_list_type, list_type);
	MLX5_SET(query_nic_vport_context_in, in, vport_number, vport);

	if (vport)
		MLX5_SET(query_nic_vport_context_in, in, other_vport, 1);

	err = mlx5_cmd_exec(dev, in, sizeof(in), out, out_sz);
	if (err)
		goto out;

	nic_vport_ctx = MLX5_ADDR_OF(query_nic_vport_context_out, out,
				     nic_vport_context);
	req_list_size = MLX5_GET(nic_vport_context, nic_vport_ctx,
				 allowed_list_size);

	*list_size = req_list_size;
	for (i = 0; i < req_list_size; i++) {
		u8 *mac_addr = MLX5_ADDR_OF(nic_vport_context,
					nic_vport_ctx,
					current_uc_mac_address[i]) + 2;
		ether_addr_copy(addr_list[i], mac_addr);
	}
out:
	kfree(out);
	return err;
}
示例#4
0
int mlx5_query_nic_vport_vlan_list(struct mlx5_core_dev *dev,
				   u32 vport,
				   u16 *vlan_list,
				   int *list_size)
{
	u32 in[MLX5_ST_SZ_DW(query_nic_vport_context_in)];
	void *nic_vport_ctx;
	int max_list_size;
	int req_list_size;
	int out_sz;
	void *out;
	void *vlan_addr;
	int err;
	int i;

	req_list_size = *list_size;

	max_list_size = 1 << MLX5_CAP_GEN_MAX(dev, log_max_vlan_list);

	if (req_list_size > max_list_size) {
		mlx5_core_warn(dev, "Requested list size (%d) > (%d) max_list_size\n",
			       req_list_size, max_list_size);
		req_list_size = max_list_size;
	}

	out_sz = MLX5_ST_SZ_BYTES(modify_nic_vport_context_in) +
		 req_list_size * MLX5_ST_SZ_BYTES(vlan_layout);

	memset(in, 0, sizeof(in));
	out = kzalloc(out_sz, GFP_KERNEL);
	if (!out)
		return -ENOMEM;

	MLX5_SET(query_nic_vport_context_in, in, opcode,
		 MLX5_CMD_OP_QUERY_NIC_VPORT_CONTEXT);
	MLX5_SET(query_nic_vport_context_in, in, allowed_list_type,
		 MLX5_NIC_VPORT_CONTEXT_ALLOWED_LIST_TYPE_VLAN_LIST);
	MLX5_SET(query_nic_vport_context_in, in, vport_number, vport);

	if (vport)
		MLX5_SET(query_nic_vport_context_in, in, other_vport, 1);

	err = mlx5_cmd_exec_check_status(dev, in, sizeof(in), out, out_sz);
	if (err)
		goto out;

	nic_vport_ctx = MLX5_ADDR_OF(query_nic_vport_context_out, out,
				     nic_vport_context);
	req_list_size = MLX5_GET(nic_vport_context, nic_vport_ctx,
				 allowed_list_size);

	*list_size = req_list_size;
	for (i = 0; i < req_list_size; i++) {
		vlan_addr = MLX5_ADDR_OF(nic_vport_context, nic_vport_ctx,
					 current_uc_mac_address[i]);
		vlan_list[i] = MLX5_GET(vlan_layout, vlan_addr, vlan);
	}
out:
	kfree(out);
	return err;
}