Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit f55c1e66 authored by Doug Ledford's avatar Doug Ledford
Browse files

Merge branches 'rxe' and 'mlx' into k.o/for-next

Loading
Loading
Loading
Loading
+7 −6
Original line number Diff line number Diff line
@@ -3998,7 +3998,8 @@ static void iboe_mcast_work_handler(struct work_struct *work)
	kfree(mw);
}

static void cma_iboe_set_mgid(struct sockaddr *addr, union ib_gid *mgid)
static void cma_iboe_set_mgid(struct sockaddr *addr, union ib_gid *mgid,
			      enum ib_gid_type gid_type)
{
	struct sockaddr_in *sin = (struct sockaddr_in *)addr;
	struct sockaddr_in6 *sin6 = (struct sockaddr_in6 *)addr;
@@ -4008,8 +4009,8 @@ static void cma_iboe_set_mgid(struct sockaddr *addr, union ib_gid *mgid)
	} else if (addr->sa_family == AF_INET6) {
		memcpy(mgid, &sin6->sin6_addr, sizeof *mgid);
	} else {
		mgid->raw[0] = 0xff;
		mgid->raw[1] = 0x0e;
		mgid->raw[0] = (gid_type == IB_GID_TYPE_IB) ? 0xff : 0;
		mgid->raw[1] = (gid_type == IB_GID_TYPE_IB) ? 0x0e : 0;
		mgid->raw[2] = 0;
		mgid->raw[3] = 0;
		mgid->raw[4] = 0;
@@ -4050,7 +4051,9 @@ static int cma_iboe_join_multicast(struct rdma_id_private *id_priv,
		goto out1;
	}

	cma_iboe_set_mgid(addr, &mc->multicast.ib->rec.mgid);
	gid_type = id_priv->cma_dev->default_gid_type[id_priv->id.port_num -
		   rdma_start_port(id_priv->cma_dev->device)];
	cma_iboe_set_mgid(addr, &mc->multicast.ib->rec.mgid, gid_type);

	mc->multicast.ib->rec.pkey = cpu_to_be16(0xffff);
	if (id_priv->id.ps == RDMA_PS_UDP)
@@ -4066,8 +4069,6 @@ static int cma_iboe_join_multicast(struct rdma_id_private *id_priv,
	mc->multicast.ib->rec.hop_limit = 1;
	mc->multicast.ib->rec.mtu = iboe_get_mtu(ndev->mtu);

	gid_type = id_priv->cma_dev->default_gid_type[id_priv->id.port_num -
		   rdma_start_port(id_priv->cma_dev->device)];
	if (addr->sa_family == AF_INET) {
		if (gid_type == IB_GID_TYPE_ROCE_UDP_ENCAP) {
			mc->multicast.ib->rec.hop_limit = IPV6_DEFAULT_HOPLIMIT;
+14 −3
Original line number Diff line number Diff line
@@ -1383,8 +1383,9 @@ static int create_qp(struct ib_uverbs_file *file,
		attr.rwq_ind_tbl = ind_tbl;
	}

	if ((cmd_sz >= offsetof(typeof(*cmd), reserved1) +
		       sizeof(cmd->reserved1)) && cmd->reserved1) {
	if (cmd_sz > sizeof(*cmd) &&
	    !ib_is_udata_cleared(ucore, sizeof(*cmd),
				 cmd_sz - sizeof(*cmd))) {
		ret = -EOPNOTSUPP;
		goto err_put;
	}
@@ -1482,11 +1483,21 @@ static int create_qp(struct ib_uverbs_file *file,
				IB_QP_CREATE_MANAGED_SEND |
				IB_QP_CREATE_MANAGED_RECV |
				IB_QP_CREATE_SCATTER_FCS |
				IB_QP_CREATE_CVLAN_STRIPPING)) {
				IB_QP_CREATE_CVLAN_STRIPPING |
				IB_QP_CREATE_SOURCE_QPN)) {
		ret = -EINVAL;
		goto err_put;
	}

	if (attr.create_flags & IB_QP_CREATE_SOURCE_QPN) {
		if (!capable(CAP_NET_RAW)) {
			ret = -EPERM;
			goto err_put;
		}

		attr.source_qpn = cmd->source_qpn;
	}

	buf = (void *)cmd + sizeof(*cmd);
	if (cmd_sz > sizeof(*cmd))
		if (!(buf[0] == 0 && !memcmp(buf, buf + 1,
+56 −6
Original line number Diff line number Diff line
@@ -1244,6 +1244,18 @@ int ib_resolve_eth_dmac(struct ib_device *device,
	if (rdma_link_local_addr((struct in6_addr *)grh->dgid.raw)) {
		rdma_get_ll_mac((struct in6_addr *)grh->dgid.raw,
				ah_attr->roce.dmac);
		return 0;
	}
	if (rdma_is_multicast_addr((struct in6_addr *)ah_attr->grh.dgid.raw)) {
		if (ipv6_addr_v4mapped((struct in6_addr *)ah_attr->grh.dgid.raw)) {
			__be32 addr = 0;

			memcpy(&addr, ah_attr->grh.dgid.raw + 12, 4);
			ip_eth_mc_map(addr, (char *)ah_attr->roce.dmac);
		} else {
			ipv6_eth_mc_map((struct in6_addr *)ah_attr->grh.dgid.raw,
					(char *)ah_attr->roce.dmac);
		}
	} else {
		union ib_gid		sgid;
		struct ib_gid_attr	sgid_attr;
@@ -1569,15 +1581,53 @@ EXPORT_SYMBOL(ib_dealloc_fmr);

/* Multicast groups */

static bool is_valid_mcast_lid(struct ib_qp *qp, u16 lid)
{
	struct ib_qp_init_attr init_attr = {};
	struct ib_qp_attr attr = {};
	int num_eth_ports = 0;
	int port;

	/* If QP state >= init, it is assigned to a port and we can check this
	 * port only.
	 */
	if (!ib_query_qp(qp, &attr, IB_QP_STATE | IB_QP_PORT, &init_attr)) {
		if (attr.qp_state >= IB_QPS_INIT) {
			if (qp->device->get_link_layer(qp->device, attr.port_num) !=
			    IB_LINK_LAYER_INFINIBAND)
				return true;
			goto lid_check;
		}
	}

	/* Can't get a quick answer, iterate over all ports */
	for (port = 0; port < qp->device->phys_port_cnt; port++)
		if (qp->device->get_link_layer(qp->device, port) !=
		    IB_LINK_LAYER_INFINIBAND)
			num_eth_ports++;

	/* If we have at lease one Ethernet port, RoCE annex declares that
	 * multicast LID should be ignored. We can't tell at this step if the
	 * QP belongs to an IB or Ethernet port.
	 */
	if (num_eth_ports)
		return true;

	/* If all the ports are IB, we can check according to IB spec. */
lid_check:
	return !(lid < be16_to_cpu(IB_MULTICAST_LID_BASE) ||
		 lid == be16_to_cpu(IB_LID_PERMISSIVE));
}

int ib_attach_mcast(struct ib_qp *qp, union ib_gid *gid, u16 lid)
{
	int ret;

	if (!qp->device->attach_mcast)
		return -ENOSYS;
	if (gid->raw[0] != 0xff || qp->qp_type != IB_QPT_UD ||
	    lid < be16_to_cpu(IB_MULTICAST_LID_BASE) ||
	    lid == be16_to_cpu(IB_LID_PERMISSIVE))

	if (!rdma_is_multicast_addr((struct in6_addr *)gid->raw) ||
	    qp->qp_type != IB_QPT_UD || !is_valid_mcast_lid(qp, lid))
		return -EINVAL;

	ret = qp->device->attach_mcast(qp, gid, lid);
@@ -1593,9 +1643,9 @@ int ib_detach_mcast(struct ib_qp *qp, union ib_gid *gid, u16 lid)

	if (!qp->device->detach_mcast)
		return -ENOSYS;
	if (gid->raw[0] != 0xff || qp->qp_type != IB_QPT_UD ||
	    lid < be16_to_cpu(IB_MULTICAST_LID_BASE) ||
	    lid == be16_to_cpu(IB_LID_PERMISSIVE))

	if (!rdma_is_multicast_addr((struct in6_addr *)gid->raw) ||
	    qp->qp_type != IB_QPT_UD || !is_valid_mcast_lid(qp, lid))
		return -EINVAL;

	ret = qp->device->detach_mcast(qp, gid, lid);
+2 −0
Original line number Diff line number Diff line
@@ -218,6 +218,7 @@ struct ib_cq *mlx4_ib_create_cq(struct ib_device *ibdev,
			goto err_mtt;

		uar = &to_mucontext(context)->uar;
		cq->mcq.usage = MLX4_RES_USAGE_USER_VERBS;
	} else {
		err = mlx4_db_alloc(dev->dev, &cq->db, 1);
		if (err)
@@ -233,6 +234,7 @@ struct ib_cq *mlx4_ib_create_cq(struct ib_device *ibdev,
			goto err_db;

		uar = &dev->priv_uar;
		cq->mcq.usage = MLX4_RES_USAGE_DRIVER;
	}

	if (dev->eq_table)
+46 −2
Original line number Diff line number Diff line
@@ -81,6 +81,8 @@ static const char mlx4_ib_version[] =
	DRV_VERSION "\n";

static void do_slave_init(struct mlx4_ib_dev *ibdev, int slave, int do_init);
static enum rdma_link_layer mlx4_ib_port_link_layer(struct ib_device *device,
						    u8 port_num);

static struct workqueue_struct *wq;

@@ -552,6 +554,16 @@ static int mlx4_ib_query_device(struct ib_device *ibdev,
	props->timestamp_mask = 0xFFFFFFFFFFFFULL;
	props->max_ah = INT_MAX;

	if ((dev->dev->caps.flags2 & MLX4_DEV_CAP_FLAG2_RSS) &&
	    (mlx4_ib_port_link_layer(ibdev, 1) == IB_LINK_LAYER_ETHERNET ||
	     mlx4_ib_port_link_layer(ibdev, 2) == IB_LINK_LAYER_ETHERNET)) {
		props->rss_caps.max_rwq_indirection_tables = props->max_qp;
		props->rss_caps.max_rwq_indirection_table_size =
			dev->dev->caps.max_rss_tbl_sz;
		props->rss_caps.supported_qpts = 1 << IB_QPT_RAW_PACKET;
		props->max_wq_type_rq = props->max_qp;
	}

	if (!mlx4_is_slave(dev->dev))
		err = mlx4_get_internal_clock_params(dev->dev, &clock_params);

@@ -563,6 +575,13 @@ static int mlx4_ib_query_device(struct ib_device *ibdev,
		}
	}

	if (uhw->outlen >= resp.response_length +
	    sizeof(resp.max_inl_recv_sz)) {
		resp.response_length += sizeof(resp.max_inl_recv_sz);
		resp.max_inl_recv_sz  = dev->dev->caps.max_rq_sg *
			sizeof(struct mlx4_wqe_data_seg);
	}

	if (uhw->outlen) {
		err = ib_copy_to_udata(uhw, &resp, resp.response_length);
		if (err)
@@ -1069,6 +1088,9 @@ static struct ib_ucontext *mlx4_ib_alloc_ucontext(struct ib_device *ibdev,
	INIT_LIST_HEAD(&context->db_page_list);
	mutex_init(&context->db_page_mutex);

	INIT_LIST_HEAD(&context->wqn_ranges_list);
	mutex_init(&context->wqn_ranges_mutex);

	if (ibdev->uverbs_abi_ver == MLX4_IB_UVERBS_NO_DEV_CAPS_ABI_VERSION)
		err = ib_copy_to_udata(udata, &resp_v3, sizeof(resp_v3));
	else
@@ -2713,6 +2735,26 @@ static void *mlx4_ib_add(struct mlx4_dev *dev)
	ibdev->ib_dev.get_dev_fw_str    = get_fw_ver_str;
	ibdev->ib_dev.disassociate_ucontext = mlx4_ib_disassociate_ucontext;

	if ((dev->caps.flags2 & MLX4_DEV_CAP_FLAG2_RSS) &&
	    ((mlx4_ib_port_link_layer(&ibdev->ib_dev, 1) ==
	    IB_LINK_LAYER_ETHERNET) ||
	    (mlx4_ib_port_link_layer(&ibdev->ib_dev, 2) ==
	    IB_LINK_LAYER_ETHERNET))) {
		ibdev->ib_dev.create_wq		= mlx4_ib_create_wq;
		ibdev->ib_dev.modify_wq		= mlx4_ib_modify_wq;
		ibdev->ib_dev.destroy_wq	= mlx4_ib_destroy_wq;
		ibdev->ib_dev.create_rwq_ind_table  =
			mlx4_ib_create_rwq_ind_table;
		ibdev->ib_dev.destroy_rwq_ind_table =
			mlx4_ib_destroy_rwq_ind_table;
		ibdev->ib_dev.uverbs_ex_cmd_mask |=
			(1ull << IB_USER_VERBS_EX_CMD_CREATE_WQ)	  |
			(1ull << IB_USER_VERBS_EX_CMD_MODIFY_WQ)	  |
			(1ull << IB_USER_VERBS_EX_CMD_DESTROY_WQ)	  |
			(1ull << IB_USER_VERBS_EX_CMD_CREATE_RWQ_IND_TBL) |
			(1ull << IB_USER_VERBS_EX_CMD_DESTROY_RWQ_IND_TBL);
	}

	if (!mlx4_is_slave(ibdev->dev)) {
		ibdev->ib_dev.alloc_fmr		= mlx4_ib_fmr_alloc;
		ibdev->ib_dev.map_phys_fmr	= mlx4_ib_map_phys_fmr;
@@ -2772,7 +2814,8 @@ static void *mlx4_ib_add(struct mlx4_dev *dev)
		allocated = 0;
		if (mlx4_ib_port_link_layer(&ibdev->ib_dev, i + 1) ==
						IB_LINK_LAYER_ETHERNET) {
			err = mlx4_counter_alloc(ibdev->dev, &counter_index);
			err = mlx4_counter_alloc(ibdev->dev, &counter_index,
						 MLX4_RES_USAGE_DRIVER);
			/* if failed to allocate a new counter, use default */
			if (err)
				counter_index =
@@ -2827,7 +2870,8 @@ static void *mlx4_ib_add(struct mlx4_dev *dev)
		ibdev->steer_qpn_count = MLX4_IB_UC_MAX_NUM_QPS;
		err = mlx4_qp_reserve_range(dev, ibdev->steer_qpn_count,
					    MLX4_IB_UC_STEER_QPN_ALIGN,
					    &ibdev->steer_qpn_base, 0);
					    &ibdev->steer_qpn_base, 0,
					    MLX4_RES_USAGE_DRIVER);
		if (err)
			goto err_counter;

Loading