diff options
Diffstat (limited to 'drivers/infiniband/hw/mlx4/cq.c')
| -rw-r--r-- | drivers/infiniband/hw/mlx4/cq.c | 52 | 
1 files changed, 40 insertions, 12 deletions
diff --git a/drivers/infiniband/hw/mlx4/cq.c b/drivers/infiniband/hw/mlx4/cq.c index d5e60f44ba5..1066eec854a 100644 --- a/drivers/infiniband/hw/mlx4/cq.c +++ b/drivers/infiniband/hw/mlx4/cq.c @@ -102,7 +102,7 @@ static int mlx4_ib_alloc_cq_buf(struct mlx4_ib_dev *dev, struct mlx4_ib_cq_buf *  	int err;  	err = mlx4_buf_alloc(dev->dev, nent * dev->dev->caps.cqe_size, -			     PAGE_SIZE * 2, &buf->buf); +			     PAGE_SIZE * 2, &buf->buf, GFP_KERNEL);  	if (err)  		goto out; @@ -113,7 +113,7 @@ static int mlx4_ib_alloc_cq_buf(struct mlx4_ib_dev *dev, struct mlx4_ib_cq_buf *  	if (err)  		goto err_buf; -	err = mlx4_buf_write_mtt(dev->dev, &buf->mtt, &buf->buf); +	err = mlx4_buf_write_mtt(dev->dev, &buf->mtt, &buf->buf, GFP_KERNEL);  	if (err)  		goto err_mtt; @@ -209,7 +209,7 @@ struct ib_cq *mlx4_ib_create_cq(struct ib_device *ibdev, int entries, int vector  		uar = &to_mucontext(context)->uar;  	} else { -		err = mlx4_db_alloc(dev->dev, &cq->db, 1); +		err = mlx4_db_alloc(dev->dev, &cq->db, 1, GFP_KERNEL);  		if (err)  			goto err_cq; @@ -324,7 +324,7 @@ static int mlx4_ib_get_outstanding_cqes(struct mlx4_ib_cq *cq)  	u32 i;  	i = cq->mcq.cons_index; -	while (get_sw_cqe(cq, i & cq->ibcq.cqe)) +	while (get_sw_cqe(cq, i))  		++i;  	return i - cq->mcq.cons_index; @@ -365,7 +365,7 @@ int mlx4_ib_resize_cq(struct ib_cq *ibcq, int entries, struct ib_udata *udata)  	mutex_lock(&cq->resize_mutex); -	if (entries < 1 || entries > dev->dev->caps.max_cqes) { +	if (entries < 1) {  		err = -EINVAL;  		goto out;  	} @@ -376,6 +376,11 @@ int mlx4_ib_resize_cq(struct ib_cq *ibcq, int entries, struct ib_udata *udata)  		goto out;  	} +	if (entries > dev->dev->caps.max_cqes) { +		err = -EINVAL; +		goto out; +	} +  	if (ibcq->uobject) {  		err = mlx4_alloc_resize_umem(dev, cq, entries, udata);  		if (err) @@ -559,7 +564,7 @@ static int mlx4_ib_ipoib_csum_ok(__be16 status, __be16 checksum)  }  static int use_tunnel_data(struct mlx4_ib_qp *qp, struct mlx4_ib_cq *cq, struct ib_wc *wc, -			   unsigned tail, struct mlx4_cqe *cqe) +			   unsigned tail, struct mlx4_cqe *cqe, int is_eth)  {  	struct mlx4_ib_proxy_sqp_hdr *hdr; @@ -569,12 +574,20 @@ static int use_tunnel_data(struct mlx4_ib_qp *qp, struct mlx4_ib_cq *cq, struct  				   DMA_FROM_DEVICE);  	hdr = (struct mlx4_ib_proxy_sqp_hdr *) (qp->sqp_proxy_rcv[tail].addr);  	wc->pkey_index	= be16_to_cpu(hdr->tun.pkey_index); -	wc->slid	= be16_to_cpu(hdr->tun.slid_mac_47_32); -	wc->sl		= (u8) (be16_to_cpu(hdr->tun.sl_vid) >> 12);  	wc->src_qp	= be32_to_cpu(hdr->tun.flags_src_qp) & 0xFFFFFF;  	wc->wc_flags   |= (hdr->tun.g_ml_path & 0x80) ? (IB_WC_GRH) : 0;  	wc->dlid_path_bits = 0; +	if (is_eth) { +		wc->vlan_id = be16_to_cpu(hdr->tun.sl_vid); +		memcpy(&(wc->smac[0]), (char *)&hdr->tun.mac_31_0, 4); +		memcpy(&(wc->smac[4]), (char *)&hdr->tun.slid_mac_47_32, 2); +		wc->wc_flags |= (IB_WC_WITH_VLAN | IB_WC_WITH_SMAC); +	} else { +		wc->slid        = be16_to_cpu(hdr->tun.slid_mac_47_32); +		wc->sl          = (u8) (be16_to_cpu(hdr->tun.sl_vid) >> 12); +	} +  	return 0;  } @@ -589,6 +602,7 @@ static int mlx4_ib_poll_one(struct mlx4_ib_cq *cq,  	struct mlx4_srq *msrq = NULL;  	int is_send;  	int is_error; +	int is_eth;  	u32 g_mlpath_rqpn;  	u16 wqe_ctr;  	unsigned tail = 0; @@ -773,11 +787,15 @@ repoll:  			break;  		} +		is_eth = (rdma_port_get_link_layer(wc->qp->device, +						  (*cur_qp)->port) == +			  IB_LINK_LAYER_ETHERNET);  		if (mlx4_is_mfunc(to_mdev(cq->ibcq.device)->dev)) {  			if ((*cur_qp)->mlx4_ib_qp_type &  			    (MLX4_IB_QPT_PROXY_SMI_OWNER |  			     MLX4_IB_QPT_PROXY_SMI | MLX4_IB_QPT_PROXY_GSI)) -				return use_tunnel_data(*cur_qp, cq, wc, tail, cqe); +				return use_tunnel_data(*cur_qp, cq, wc, tail, +						       cqe, is_eth);  		}  		wc->slid	   = be16_to_cpu(cqe->rlid); @@ -788,11 +806,21 @@ repoll:  		wc->pkey_index     = be32_to_cpu(cqe->immed_rss_invalid) & 0x7f;  		wc->wc_flags	  |= mlx4_ib_ipoib_csum_ok(cqe->status,  					cqe->checksum) ? IB_WC_IP_CSUM_OK : 0; -		if (rdma_port_get_link_layer(wc->qp->device, -				(*cur_qp)->port) == IB_LINK_LAYER_ETHERNET) +		if (is_eth) {  			wc->sl  = be16_to_cpu(cqe->sl_vid) >> 13; -		else +			if (be32_to_cpu(cqe->vlan_my_qpn) & +					MLX4_CQE_VLAN_PRESENT_MASK) { +				wc->vlan_id = be16_to_cpu(cqe->sl_vid) & +					MLX4_CQE_VID_MASK; +			} else { +				wc->vlan_id = 0xffff; +			} +			memcpy(wc->smac, cqe->smac, ETH_ALEN); +			wc->wc_flags |= (IB_WC_WITH_VLAN | IB_WC_WITH_SMAC); +		} else {  			wc->sl  = be16_to_cpu(cqe->sl_vid) >> 12; +			wc->vlan_id = 0xffff; +		}  	}  	return 0;  | 
