Re: [PATCH V2 for-next 08/15] RDMA/bnxt_re: Add vlan tag for untagged RoCE traffic when PFC is configured

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



On Wed, May 17, 2017 at 02:19:44AM -0700, Selvin Xavier wrote:
> From: Kalesh AP <kalesh-anakkur.purayil@xxxxxxxxxxxx>
>
> Current implementation does not program vlan header insertion
> in RoCE packet if no vlan is configured. Firmware does not add
> prority when there is no vlan tag in the packet. Modify the code
> to insert vlan header when PFC is enabled on the interface.
>
> v1 -> v2:
> 	Avoid unnecessary memcpy while populating smac and gid

Not in commit message please.

>
> Signed-off-by: Kalesh AP <kalesh-anakkur.purayil@xxxxxxxxxxxx>
> Signed-off-by: Selvin Xavier <selvin.xavier@xxxxxxxxxxxx>
> ---
>  drivers/infiniband/hw/bnxt_re/main.c      | 53 ++++++++++++++++++++---
>  drivers/infiniband/hw/bnxt_re/qplib_res.c | 10 +++++
>  drivers/infiniband/hw/bnxt_re/qplib_res.h |  2 +
>  drivers/infiniband/hw/bnxt_re/qplib_sp.c  | 71 +++++++++++++++++++++++++++----
>  drivers/infiniband/hw/bnxt_re/qplib_sp.h  |  2 +
>  drivers/infiniband/hw/bnxt_re/roce_hsi.h  |  4 +-
>  6 files changed, 125 insertions(+), 17 deletions(-)
>
> diff --git a/drivers/infiniband/hw/bnxt_re/main.c b/drivers/infiniband/hw/bnxt_re/main.c
> index 99a54fd..fd61949 100644
> --- a/drivers/infiniband/hw/bnxt_re/main.c
> +++ b/drivers/infiniband/hw/bnxt_re/main.c
> @@ -840,6 +840,42 @@ static void bnxt_re_dev_stop(struct bnxt_re_dev *rdev)
>  	mutex_unlock(&rdev->qp_lock);
>  }
>
> +static int bnxt_re_update_gid(struct bnxt_re_dev *rdev)
> +{
> +	struct bnxt_qplib_sgid_tbl *sgid_tbl = &rdev->qplib_res.sgid_tbl;
> +	struct bnxt_qplib_gid gid;
> +	u16 gid_idx, index;
> +	int rc = 0;
> +
> +	if (!test_bit(BNXT_RE_FLAG_IBDEV_REGISTERED, &rdev->flags))
> +		return 0;
> +
> +	if (!sgid_tbl) {
> +		dev_err(rdev_to_dev(rdev), "QPLIB: SGID table not allocated");
> +		return -EINVAL;
> +	}
> +
> +	for (index = 0; index < sgid_tbl->active; index++) {
> +		gid_idx = sgid_tbl->hw_id[index];
> +
> +		if (!memcmp(&sgid_tbl->tbl[index], &bnxt_qplib_gid_zero,
> +			    sizeof(bnxt_qplib_gid_zero)))
> +			continue;
> +		/* need to modify the VLAN enable setting of non VLAN GID only
> +		 * as setting is done for VLAN GID while adding GID
> +		 */
> +		if (sgid_tbl->vlan[index])
> +			continue;
> +
> +		memcpy(&gid, &sgid_tbl->tbl[index], sizeof(gid));
> +
> +		rc = bnxt_qplib_update_sgid(sgid_tbl, &gid, gid_idx,
> +					    rdev->qplib_res.netdev->dev_addr);
> +	}
> +
> +	return rc;
> +}
> +
>  static u32 bnxt_re_get_priority_mask(struct bnxt_re_dev *rdev)
>  {
>  	u32 prio_map = 0, tmp_map = 0;
> @@ -859,8 +895,6 @@ static u32 bnxt_re_get_priority_mask(struct bnxt_re_dev *rdev)
>  	tmp_map = dcb_ieee_getapp_mask(netdev, &app);
>  	prio_map |= tmp_map;
>
> -	if (!prio_map)
> -		prio_map = -EFAULT;
>  	return prio_map;
>  }
>
> @@ -886,10 +920,7 @@ static int bnxt_re_setup_qos(struct bnxt_re_dev *rdev)
>  	int rc;
>
>  	/* Get priority for roce */
> -	rc = bnxt_re_get_priority_mask(rdev);
> -	if (rc < 0)
> -		return rc;
> -	prio_map = (u8)rc;
> +	prio_map = bnxt_re_get_priority_mask(rdev);
>
>  	if (prio_map == rdev->cur_prio_map)
>  		return 0;
> @@ -911,6 +942,16 @@ static int bnxt_re_setup_qos(struct bnxt_re_dev *rdev)
>  		return rc;
>  	}
>
> +	/* Actual priorities are not programmed as they are already
> +	 * done by L2 driver; just enable or disable priority vlan tagging
> +	 */
> +	if ((prio_map == 0 && rdev->qplib_res.prio) ||
> +	    (prio_map != 0 && !rdev->qplib_res.prio)) {
> +		rdev->qplib_res.prio = prio_map ? true : false;
> +
> +		bnxt_re_update_gid(rdev);
> +	}
> +
>  	return 0;
>  }
>
> diff --git a/drivers/infiniband/hw/bnxt_re/qplib_res.c b/drivers/infiniband/hw/bnxt_re/qplib_res.c
> index 62447b3..4e10170 100644
> --- a/drivers/infiniband/hw/bnxt_re/qplib_res.c
> +++ b/drivers/infiniband/hw/bnxt_re/qplib_res.c
> @@ -468,9 +468,11 @@ static void bnxt_qplib_free_sgid_tbl(struct bnxt_qplib_res *res,
>  	kfree(sgid_tbl->tbl);
>  	kfree(sgid_tbl->hw_id);
>  	kfree(sgid_tbl->ctx);
> +	kfree(sgid_tbl->vlan);
>  	sgid_tbl->tbl = NULL;
>  	sgid_tbl->hw_id = NULL;
>  	sgid_tbl->ctx = NULL;
> +	sgid_tbl->vlan = NULL;
>  	sgid_tbl->max = 0;
>  	sgid_tbl->active = 0;
>  }
> @@ -491,8 +493,15 @@ static int bnxt_qplib_alloc_sgid_tbl(struct bnxt_qplib_res *res,
>  	if (!sgid_tbl->ctx)
>  		goto out_free2;
>
> +	sgid_tbl->vlan = kcalloc(max, sizeof(u8), GFP_KERNEL);
> +	if (!sgid_tbl->vlan)
> +		goto out_free3;
> +
>  	sgid_tbl->max = max;
>  	return 0;
> +out_free3:
> +	kfree(sgid_tbl->ctx);
> +	sgid_tbl->ctx = NULL;
>  out_free2:
>  	kfree(sgid_tbl->hw_id);
>  	sgid_tbl->hw_id = NULL;
> @@ -514,6 +523,7 @@ static void bnxt_qplib_cleanup_sgid_tbl(struct bnxt_qplib_res *res,
>  	}
>  	memset(sgid_tbl->tbl, 0, sizeof(struct bnxt_qplib_gid) * sgid_tbl->max);
>  	memset(sgid_tbl->hw_id, -1, sizeof(u16) * sgid_tbl->max);
> +	memset(sgid_tbl->vlan, 0, sizeof(u8) * sgid_tbl->max);
>  	sgid_tbl->active = 0;
>  }
>
> diff --git a/drivers/infiniband/hw/bnxt_re/qplib_res.h b/drivers/infiniband/hw/bnxt_re/qplib_res.h
> index 2e48555..e872075 100644
> --- a/drivers/infiniband/hw/bnxt_re/qplib_res.h
> +++ b/drivers/infiniband/hw/bnxt_re/qplib_res.h
> @@ -116,6 +116,7 @@ struct bnxt_qplib_sgid_tbl {
>  	u16				max;
>  	u16				active;
>  	void				*ctx;
> +	u8				*vlan;
>  };
>
>  struct bnxt_qplib_pkey_tbl {
> @@ -188,6 +189,7 @@ struct bnxt_qplib_res {
>  	struct bnxt_qplib_sgid_tbl	sgid_tbl;
>  	struct bnxt_qplib_pkey_tbl	pkey_tbl;
>  	struct bnxt_qplib_dpi_tbl	dpi_tbl;
> +	bool				prio;
>  };
>
>  #define to_bnxt_qplib(ptr, type, member)	\
> diff --git a/drivers/infiniband/hw/bnxt_re/qplib_sp.c b/drivers/infiniband/hw/bnxt_re/qplib_sp.c
> index fde18cf..36f45ff 100644
> --- a/drivers/infiniband/hw/bnxt_re/qplib_sp.c
> +++ b/drivers/infiniband/hw/bnxt_re/qplib_sp.c
> @@ -197,6 +197,7 @@ int bnxt_qplib_del_sgid(struct bnxt_qplib_sgid_tbl *sgid_tbl,
>  	}
>  	memcpy(&sgid_tbl->tbl[index], &bnxt_qplib_gid_zero,
>  	       sizeof(bnxt_qplib_gid_zero));
> +	sgid_tbl->vlan[index] = 0;
>  	sgid_tbl->active--;
>  	dev_dbg(&res->pdev->dev,
>  		"QPLIB: SGID deleted hw_id[0x%x] = 0x%x active = 0x%x",
> @@ -249,25 +250,33 @@ int bnxt_qplib_add_sgid(struct bnxt_qplib_sgid_tbl *sgid_tbl,
>  		struct cmdq_add_gid req;
>  		struct creq_add_gid_resp resp;
>  		u16 cmd_flags = 0;
> -		u32 temp32[4];
> -		u16 temp16[3];
> +		u32 *temp32;
> +		u16 *temp16;
>  		int rc;
>
>  		RCFW_CMD_PREP(req, ADD_GID, cmd_flags);
>
> -		memcpy(temp32, gid->data, sizeof(struct bnxt_qplib_gid));
> +		temp32 = (u32 *)gid->data;
>  		req.gid[0] = cpu_to_be32(temp32[3]);
>  		req.gid[1] = cpu_to_be32(temp32[2]);
>  		req.gid[2] = cpu_to_be32(temp32[1]);
>  		req.gid[3] = cpu_to_be32(temp32[0]);

You can completely remove tmep* variables and use directly.

> -		if (vlan_id != 0xFFFF)
> -			req.vlan = cpu_to_le16((vlan_id &
> -					CMDQ_ADD_GID_VLAN_VLAN_ID_MASK) |
> -					CMDQ_ADD_GID_VLAN_TPID_TPID_8100 |
> -					CMDQ_ADD_GID_VLAN_VLAN_EN);
> +		/*
> +		 * driver should ensure that all RoCE traffic is always VLAN
> +		 * tagged if RoCE traffic is running on non-zero VLAN ID or
> +		 * RoCE traffic is running on non-zero Priority.
> +		 */
> +		if ((vlan_id != 0xFFFF) || res->prio) {
> +			if (vlan_id != 0xFFFF)
> +				req.vlan = cpu_to_le16
> +				(vlan_id & CMDQ_ADD_GID_VLAN_VLAN_ID_MASK);
> +			req.vlan |= cpu_to_le16
> +					(CMDQ_ADD_GID_VLAN_TPID_TPID_8100 |
> +					 CMDQ_ADD_GID_VLAN_VLAN_EN);
> +		}
>
>  		/* MAC in network format */
> -		memcpy(temp16, smac, 6);
> +		temp16 = (u16 *)smac;
>  		req.src_mac[0] = cpu_to_be16(temp16[0]);
>  		req.src_mac[1] = cpu_to_be16(temp16[1]);
>  		req.src_mac[2] = cpu_to_be16(temp16[2]);
> @@ -281,6 +290,9 @@ int bnxt_qplib_add_sgid(struct bnxt_qplib_sgid_tbl *sgid_tbl,
>  	/* Add GID to the sgid_tbl */
>  	memcpy(&sgid_tbl->tbl[free_idx], gid, sizeof(*gid));
>  	sgid_tbl->active++;
> +	if (vlan_id != 0xFFFF)
> +		sgid_tbl->vlan[free_idx] = 1;
> +
>  	dev_dbg(&res->pdev->dev,
>  		"QPLIB: SGID added hw_id[0x%x] = 0x%x active = 0x%x",
>  		 free_idx, sgid_tbl->hw_id[free_idx], sgid_tbl->active);
> @@ -290,6 +302,47 @@ int bnxt_qplib_add_sgid(struct bnxt_qplib_sgid_tbl *sgid_tbl,
>  	return 0;
>  }
>
> +int bnxt_qplib_update_sgid(struct bnxt_qplib_sgid_tbl *sgid_tbl,
> +			   struct bnxt_qplib_gid *gid, u16 gid_idx,
> +			   u8 *smac)
> +{
> +	struct bnxt_qplib_res *res = to_bnxt_qplib(sgid_tbl,
> +						   struct bnxt_qplib_res,
> +						   sgid_tbl);
> +	struct bnxt_qplib_rcfw *rcfw = res->rcfw;
> +	struct creq_modify_gid_resp resp;
> +	struct cmdq_modify_gid req;
> +	int rc;
> +	u16 cmd_flags = 0;
> +	u32 *temp32;
> +	u16 *temp16;
> +
> +	RCFW_CMD_PREP(req, MODIFY_GID, cmd_flags);
> +
> +	temp32 = (u32 *)gid->data;
> +	req.gid[0] = cpu_to_be32(temp32[3]);
> +	req.gid[1] = cpu_to_be32(temp32[2]);
> +	req.gid[2] = cpu_to_be32(temp32[1]);
> +	req.gid[3] = cpu_to_be32(temp32[0]);
> +	if (res->prio) {
> +		req.vlan |= cpu_to_le16
> +			(CMDQ_ADD_GID_VLAN_TPID_TPID_8100 |
> +			 CMDQ_ADD_GID_VLAN_VLAN_EN);
> +	}
> +
> +	/* MAC in network format */
> +	temp16 = (u16 *)smac;
> +	req.src_mac[0] = cpu_to_be16(temp16[0]);
> +	req.src_mac[1] = cpu_to_be16(temp16[1]);
> +	req.src_mac[2] = cpu_to_be16(temp16[2]);
> +
> +	req.gid_index = cpu_to_le16(gid_idx);
> +
> +	rc = bnxt_qplib_rcfw_send_message(rcfw, (void *)&req,
> +					  (void *)&resp, NULL, 0);
> +	return rc;
> +}
> +
>  /* pkeys */
>  int bnxt_qplib_get_pkey(struct bnxt_qplib_res *res,
>  			struct bnxt_qplib_pkey_tbl *pkey_tbl, u16 index,
> diff --git a/drivers/infiniband/hw/bnxt_re/qplib_sp.h b/drivers/infiniband/hw/bnxt_re/qplib_sp.h
> index a543f95..e3a3ed9 100644
> --- a/drivers/infiniband/hw/bnxt_re/qplib_sp.h
> +++ b/drivers/infiniband/hw/bnxt_re/qplib_sp.h
> @@ -132,6 +132,8 @@ int bnxt_qplib_del_sgid(struct bnxt_qplib_sgid_tbl *sgid_tbl,
>  int bnxt_qplib_add_sgid(struct bnxt_qplib_sgid_tbl *sgid_tbl,
>  			struct bnxt_qplib_gid *gid, u8 *mac, u16 vlan_id,
>  			bool update, u32 *index);
> +int bnxt_qplib_update_sgid(struct bnxt_qplib_sgid_tbl *sgid_tbl,
> +			   struct bnxt_qplib_gid *gid, u16 gid_idx, u8 *smac);
>  int bnxt_qplib_get_pkey(struct bnxt_qplib_res *res,
>  			struct bnxt_qplib_pkey_tbl *pkey_tbl, u16 index,
>  			u16 *pkey);
> diff --git a/drivers/infiniband/hw/bnxt_re/roce_hsi.h b/drivers/infiniband/hw/bnxt_re/roce_hsi.h
> index fc23477..eeb55b2 100644
> --- a/drivers/infiniband/hw/bnxt_re/roce_hsi.h
> +++ b/drivers/infiniband/hw/bnxt_re/roce_hsi.h
> @@ -1473,8 +1473,8 @@ struct cmdq_modify_gid {
>  	u8 resp_size;
>  	u8 reserved8;
>  	__le64 resp_addr;
> -	__le32 gid[4];
> -	__le16 src_mac[3];
> +	__be32 gid[4];
> +	__be16 src_mac[3];
>  	__le16 vlan;
>  	#define CMDQ_MODIFY_GID_VLAN_VLAN_ID_MASK		    0xfffUL
>  	#define CMDQ_MODIFY_GID_VLAN_VLAN_ID_SFT		    0
> --
> 2.5.5
>
> --
> To unsubscribe from this list: send the line "unsubscribe linux-rdma" in
> the body of a message to majordomo@xxxxxxxxxxxxxxx
> More majordomo info at  http://vger.kernel.org/majordomo-info.html

Attachment: signature.asc
Description: PGP signature


[Index of Archives]     [Linux USB Devel]     [Video for Linux]     [Linux Audio Users]     [Photo]     [Yosemite News]     [Yosemite Photos]     [Linux Kernel]     [Linux SCSI]     [XFree86]
  Powered by Linux