Commit 29565f2f authored by Devesh Sharma's avatar Devesh Sharma Committed by Roland Dreier

RDMA/ocrdma: set vlan present bit for user AH

For the AH that describs a VLAN interface details, vlan present bit
needs to be set during posting a WQE. This patch adds the code to
allow it happening.
Signed-off-by: default avatarMitesh Ahuja <mitesh.ahuja@emulex.com>
Signed-off-by: default avatarDevesh Sharma <devesh.sharma@emulex.com>
Signed-off-by: default avatarRoland Dreier <roland@purestorage.com>
parent d2b8f7b1
...@@ -40,10 +40,11 @@ ...@@ -40,10 +40,11 @@
#define OCRDMA_VID_PCP_SHIFT 0xD #define OCRDMA_VID_PCP_SHIFT 0xD
static inline int set_av_attr(struct ocrdma_dev *dev, struct ocrdma_ah *ah, static inline int set_av_attr(struct ocrdma_dev *dev, struct ocrdma_ah *ah,
struct ib_ah_attr *attr, union ib_gid *sgid, int pdid) struct ib_ah_attr *attr, union ib_gid *sgid,
int pdid, bool *isvlan)
{ {
int status = 0; int status = 0;
u16 vlan_tag; bool vlan_enabled = false; u16 vlan_tag;
struct ocrdma_eth_vlan eth; struct ocrdma_eth_vlan eth;
struct ocrdma_grh grh; struct ocrdma_grh grh;
int eth_sz; int eth_sz;
...@@ -61,7 +62,7 @@ static inline int set_av_attr(struct ocrdma_dev *dev, struct ocrdma_ah *ah, ...@@ -61,7 +62,7 @@ static inline int set_av_attr(struct ocrdma_dev *dev, struct ocrdma_ah *ah,
vlan_tag |= (dev->sl & 0x07) << OCRDMA_VID_PCP_SHIFT; vlan_tag |= (dev->sl & 0x07) << OCRDMA_VID_PCP_SHIFT;
eth.vlan_tag = cpu_to_be16(vlan_tag); eth.vlan_tag = cpu_to_be16(vlan_tag);
eth_sz = sizeof(struct ocrdma_eth_vlan); eth_sz = sizeof(struct ocrdma_eth_vlan);
vlan_enabled = true; *isvlan = true;
} else { } else {
eth.eth_type = cpu_to_be16(OCRDMA_ROCE_ETH_TYPE); eth.eth_type = cpu_to_be16(OCRDMA_ROCE_ETH_TYPE);
eth_sz = sizeof(struct ocrdma_eth_basic); eth_sz = sizeof(struct ocrdma_eth_basic);
...@@ -84,7 +85,7 @@ static inline int set_av_attr(struct ocrdma_dev *dev, struct ocrdma_ah *ah, ...@@ -84,7 +85,7 @@ static inline int set_av_attr(struct ocrdma_dev *dev, struct ocrdma_ah *ah,
/* Eth HDR */ /* Eth HDR */
memcpy(&ah->av->eth_hdr, &eth, eth_sz); memcpy(&ah->av->eth_hdr, &eth, eth_sz);
memcpy((u8 *)ah->av + eth_sz, &grh, sizeof(struct ocrdma_grh)); memcpy((u8 *)ah->av + eth_sz, &grh, sizeof(struct ocrdma_grh));
if (vlan_enabled) if (*isvlan)
ah->av->valid |= OCRDMA_AV_VLAN_VALID; ah->av->valid |= OCRDMA_AV_VLAN_VALID;
ah->av->valid = cpu_to_le32(ah->av->valid); ah->av->valid = cpu_to_le32(ah->av->valid);
return status; return status;
...@@ -93,6 +94,7 @@ static inline int set_av_attr(struct ocrdma_dev *dev, struct ocrdma_ah *ah, ...@@ -93,6 +94,7 @@ static inline int set_av_attr(struct ocrdma_dev *dev, struct ocrdma_ah *ah,
struct ib_ah *ocrdma_create_ah(struct ib_pd *ibpd, struct ib_ah_attr *attr) struct ib_ah *ocrdma_create_ah(struct ib_pd *ibpd, struct ib_ah_attr *attr)
{ {
u32 *ahid_addr; u32 *ahid_addr;
bool isvlan = false;
int status; int status;
struct ocrdma_ah *ah; struct ocrdma_ah *ah;
struct ocrdma_pd *pd = get_ocrdma_pd(ibpd); struct ocrdma_pd *pd = get_ocrdma_pd(ibpd);
...@@ -129,15 +131,20 @@ struct ib_ah *ocrdma_create_ah(struct ib_pd *ibpd, struct ib_ah_attr *attr) ...@@ -129,15 +131,20 @@ struct ib_ah *ocrdma_create_ah(struct ib_pd *ibpd, struct ib_ah_attr *attr)
} }
} }
status = set_av_attr(dev, ah, attr, &sgid, pd->id); status = set_av_attr(dev, ah, attr, &sgid, pd->id, &isvlan);
if (status) if (status)
goto av_conf_err; goto av_conf_err;
/* if pd is for the user process, pass the ah_id to user space */ /* if pd is for the user process, pass the ah_id to user space */
if ((pd->uctx) && (pd->uctx->ah_tbl.va)) { if ((pd->uctx) && (pd->uctx->ah_tbl.va)) {
ahid_addr = pd->uctx->ah_tbl.va + attr->dlid; ahid_addr = pd->uctx->ah_tbl.va + attr->dlid;
*ahid_addr = ah->id; *ahid_addr = 0;
*ahid_addr |= ah->id & OCRDMA_AH_ID_MASK;
if (isvlan)
*ahid_addr |= (OCRDMA_AH_VLAN_VALID_MASK <<
OCRDMA_AH_VLAN_VALID_SHIFT);
} }
return &ah->ibah; return &ah->ibah;
av_conf_err: av_conf_err:
......
...@@ -28,6 +28,12 @@ ...@@ -28,6 +28,12 @@
#ifndef __OCRDMA_AH_H__ #ifndef __OCRDMA_AH_H__
#define __OCRDMA_AH_H__ #define __OCRDMA_AH_H__
enum {
OCRDMA_AH_ID_MASK = 0x3FF,
OCRDMA_AH_VLAN_VALID_MASK = 0x01,
OCRDMA_AH_VLAN_VALID_SHIFT = 0x1F
};
struct ib_ah *ocrdma_create_ah(struct ib_pd *, struct ib_ah_attr *); struct ib_ah *ocrdma_create_ah(struct ib_pd *, struct ib_ah_attr *);
int ocrdma_destroy_ah(struct ib_ah *); int ocrdma_destroy_ah(struct ib_ah *);
int ocrdma_query_ah(struct ib_ah *, struct ib_ah_attr *); int ocrdma_query_ah(struct ib_ah *, struct ib_ah_attr *);
......
...@@ -1734,6 +1734,7 @@ enum { ...@@ -1734,6 +1734,7 @@ enum {
OCRDMA_FLAG_FENCE_R = 0x8, OCRDMA_FLAG_FENCE_R = 0x8,
OCRDMA_FLAG_SOLICIT = 0x10, OCRDMA_FLAG_SOLICIT = 0x10,
OCRDMA_FLAG_IMM = 0x20, OCRDMA_FLAG_IMM = 0x20,
OCRDMA_FLAG_AH_VLAN_PR = 0x40,
/* Stag flags */ /* Stag flags */
OCRDMA_LKEY_FLAG_LOCAL_WR = 0x1, OCRDMA_LKEY_FLAG_LOCAL_WR = 0x1,
......
...@@ -1937,6 +1937,8 @@ static void ocrdma_build_ud_hdr(struct ocrdma_qp *qp, ...@@ -1937,6 +1937,8 @@ static void ocrdma_build_ud_hdr(struct ocrdma_qp *qp,
else else
ud_hdr->qkey = wr->wr.ud.remote_qkey; ud_hdr->qkey = wr->wr.ud.remote_qkey;
ud_hdr->rsvd_ahid = ah->id; ud_hdr->rsvd_ahid = ah->id;
if (ah->av->valid & OCRDMA_AV_VLAN_VALID)
hdr->cw |= (OCRDMA_FLAG_AH_VLAN_PR << OCRDMA_WQE_FLAGS_SHIFT);
} }
static void ocrdma_build_sges(struct ocrdma_hdr_wqe *hdr, static void ocrdma_build_sges(struct ocrdma_hdr_wqe *hdr,
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment