diff options
| author | Devesh Sharma <devesh.sharma@emulex.com> | 2014-12-18 03:43:07 -0500 |
|---|---|---|
| committer | Roland Dreier <roland@purestorage.com> | 2015-02-18 11:31:05 -0500 |
| commit | 29565f2f09d79efeab324bda0631def14a755047 (patch) | |
| tree | 355c3a65c3b4f0b915a9cdc502ede7bf499cf944 | |
| parent | d2b8f7b1f87948f5b4198d9ca52733eb9ff9e4be (diff) | |
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: Mitesh Ahuja <mitesh.ahuja@emulex.com>
Signed-off-by: Devesh Sharma <devesh.sharma@emulex.com>
Signed-off-by: Roland Dreier <roland@purestorage.com>
| -rw-r--r-- | drivers/infiniband/hw/ocrdma/ocrdma_ah.c | 19 | ||||
| -rw-r--r-- | drivers/infiniband/hw/ocrdma/ocrdma_ah.h | 6 | ||||
| -rw-r--r-- | drivers/infiniband/hw/ocrdma/ocrdma_sli.h | 1 | ||||
| -rw-r--r-- | drivers/infiniband/hw/ocrdma/ocrdma_verbs.c | 2 |
4 files changed, 22 insertions, 6 deletions
diff --git a/drivers/infiniband/hw/ocrdma/ocrdma_ah.c b/drivers/infiniband/hw/ocrdma/ocrdma_ah.c index b80b57b40043..d812904f3984 100644 --- a/drivers/infiniband/hw/ocrdma/ocrdma_ah.c +++ b/drivers/infiniband/hw/ocrdma/ocrdma_ah.c | |||
| @@ -40,10 +40,11 @@ | |||
| 40 | #define OCRDMA_VID_PCP_SHIFT 0xD | 40 | #define OCRDMA_VID_PCP_SHIFT 0xD |
| 41 | 41 | ||
| 42 | static inline int set_av_attr(struct ocrdma_dev *dev, struct ocrdma_ah *ah, | 42 | static inline int set_av_attr(struct ocrdma_dev *dev, struct ocrdma_ah *ah, |
| 43 | struct ib_ah_attr *attr, union ib_gid *sgid, int pdid) | 43 | struct ib_ah_attr *attr, union ib_gid *sgid, |
| 44 | int pdid, bool *isvlan) | ||
| 44 | { | 45 | { |
| 45 | int status = 0; | 46 | int status = 0; |
| 46 | u16 vlan_tag; bool vlan_enabled = false; | 47 | u16 vlan_tag; |
| 47 | struct ocrdma_eth_vlan eth; | 48 | struct ocrdma_eth_vlan eth; |
| 48 | struct ocrdma_grh grh; | 49 | struct ocrdma_grh grh; |
| 49 | int eth_sz; | 50 | int eth_sz; |
| @@ -61,7 +62,7 @@ static inline int set_av_attr(struct ocrdma_dev *dev, struct ocrdma_ah *ah, | |||
| 61 | vlan_tag |= (dev->sl & 0x07) << OCRDMA_VID_PCP_SHIFT; | 62 | vlan_tag |= (dev->sl & 0x07) << OCRDMA_VID_PCP_SHIFT; |
| 62 | eth.vlan_tag = cpu_to_be16(vlan_tag); | 63 | eth.vlan_tag = cpu_to_be16(vlan_tag); |
| 63 | eth_sz = sizeof(struct ocrdma_eth_vlan); | 64 | eth_sz = sizeof(struct ocrdma_eth_vlan); |
| 64 | vlan_enabled = true; | 65 | *isvlan = true; |
| 65 | } else { | 66 | } else { |
| 66 | eth.eth_type = cpu_to_be16(OCRDMA_ROCE_ETH_TYPE); | 67 | eth.eth_type = cpu_to_be16(OCRDMA_ROCE_ETH_TYPE); |
| 67 | eth_sz = sizeof(struct ocrdma_eth_basic); | 68 | 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 | /* Eth HDR */ | 85 | /* Eth HDR */ |
| 85 | memcpy(&ah->av->eth_hdr, ð, eth_sz); | 86 | memcpy(&ah->av->eth_hdr, ð, eth_sz); |
| 86 | memcpy((u8 *)ah->av + eth_sz, &grh, sizeof(struct ocrdma_grh)); | 87 | memcpy((u8 *)ah->av + eth_sz, &grh, sizeof(struct ocrdma_grh)); |
| 87 | if (vlan_enabled) | 88 | if (*isvlan) |
| 88 | ah->av->valid |= OCRDMA_AV_VLAN_VALID; | 89 | ah->av->valid |= OCRDMA_AV_VLAN_VALID; |
| 89 | ah->av->valid = cpu_to_le32(ah->av->valid); | 90 | ah->av->valid = cpu_to_le32(ah->av->valid); |
| 90 | return status; | 91 | return status; |
| @@ -93,6 +94,7 @@ static inline int set_av_attr(struct ocrdma_dev *dev, struct ocrdma_ah *ah, | |||
| 93 | struct ib_ah *ocrdma_create_ah(struct ib_pd *ibpd, struct ib_ah_attr *attr) | 94 | struct ib_ah *ocrdma_create_ah(struct ib_pd *ibpd, struct ib_ah_attr *attr) |
| 94 | { | 95 | { |
| 95 | u32 *ahid_addr; | 96 | u32 *ahid_addr; |
| 97 | bool isvlan = false; | ||
| 96 | int status; | 98 | int status; |
| 97 | struct ocrdma_ah *ah; | 99 | struct ocrdma_ah *ah; |
| 98 | struct ocrdma_pd *pd = get_ocrdma_pd(ibpd); | 100 | 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 | } | 131 | } |
| 130 | } | 132 | } |
| 131 | 133 | ||
| 132 | status = set_av_attr(dev, ah, attr, &sgid, pd->id); | 134 | status = set_av_attr(dev, ah, attr, &sgid, pd->id, &isvlan); |
| 133 | if (status) | 135 | if (status) |
| 134 | goto av_conf_err; | 136 | goto av_conf_err; |
| 135 | 137 | ||
| 136 | /* if pd is for the user process, pass the ah_id to user space */ | 138 | /* if pd is for the user process, pass the ah_id to user space */ |
| 137 | if ((pd->uctx) && (pd->uctx->ah_tbl.va)) { | 139 | if ((pd->uctx) && (pd->uctx->ah_tbl.va)) { |
| 138 | ahid_addr = pd->uctx->ah_tbl.va + attr->dlid; | 140 | ahid_addr = pd->uctx->ah_tbl.va + attr->dlid; |
| 139 | *ahid_addr = ah->id; | 141 | *ahid_addr = 0; |
| 142 | *ahid_addr |= ah->id & OCRDMA_AH_ID_MASK; | ||
| 143 | if (isvlan) | ||
| 144 | *ahid_addr |= (OCRDMA_AH_VLAN_VALID_MASK << | ||
| 145 | OCRDMA_AH_VLAN_VALID_SHIFT); | ||
| 140 | } | 146 | } |
| 147 | |||
| 141 | return &ah->ibah; | 148 | return &ah->ibah; |
| 142 | 149 | ||
| 143 | av_conf_err: | 150 | av_conf_err: |
diff --git a/drivers/infiniband/hw/ocrdma/ocrdma_ah.h b/drivers/infiniband/hw/ocrdma/ocrdma_ah.h index 8ac49e7f96d1..726a87cf22dc 100644 --- a/drivers/infiniband/hw/ocrdma/ocrdma_ah.h +++ b/drivers/infiniband/hw/ocrdma/ocrdma_ah.h | |||
| @@ -28,6 +28,12 @@ | |||
| 28 | #ifndef __OCRDMA_AH_H__ | 28 | #ifndef __OCRDMA_AH_H__ |
| 29 | #define __OCRDMA_AH_H__ | 29 | #define __OCRDMA_AH_H__ |
| 30 | 30 | ||
| 31 | enum { | ||
| 32 | OCRDMA_AH_ID_MASK = 0x3FF, | ||
| 33 | OCRDMA_AH_VLAN_VALID_MASK = 0x01, | ||
| 34 | OCRDMA_AH_VLAN_VALID_SHIFT = 0x1F | ||
| 35 | }; | ||
| 36 | |||
| 31 | struct ib_ah *ocrdma_create_ah(struct ib_pd *, struct ib_ah_attr *); | 37 | struct ib_ah *ocrdma_create_ah(struct ib_pd *, struct ib_ah_attr *); |
| 32 | int ocrdma_destroy_ah(struct ib_ah *); | 38 | int ocrdma_destroy_ah(struct ib_ah *); |
| 33 | int ocrdma_query_ah(struct ib_ah *, struct ib_ah_attr *); | 39 | int ocrdma_query_ah(struct ib_ah *, struct ib_ah_attr *); |
diff --git a/drivers/infiniband/hw/ocrdma/ocrdma_sli.h b/drivers/infiniband/hw/ocrdma/ocrdma_sli.h index 801883aa4145..243c87c8bd65 100644 --- a/drivers/infiniband/hw/ocrdma/ocrdma_sli.h +++ b/drivers/infiniband/hw/ocrdma/ocrdma_sli.h | |||
| @@ -1734,6 +1734,7 @@ enum { | |||
| 1734 | OCRDMA_FLAG_FENCE_R = 0x8, | 1734 | OCRDMA_FLAG_FENCE_R = 0x8, |
| 1735 | OCRDMA_FLAG_SOLICIT = 0x10, | 1735 | OCRDMA_FLAG_SOLICIT = 0x10, |
| 1736 | OCRDMA_FLAG_IMM = 0x20, | 1736 | OCRDMA_FLAG_IMM = 0x20, |
| 1737 | OCRDMA_FLAG_AH_VLAN_PR = 0x40, | ||
| 1737 | 1738 | ||
| 1738 | /* Stag flags */ | 1739 | /* Stag flags */ |
| 1739 | OCRDMA_LKEY_FLAG_LOCAL_WR = 0x1, | 1740 | OCRDMA_LKEY_FLAG_LOCAL_WR = 0x1, |
diff --git a/drivers/infiniband/hw/ocrdma/ocrdma_verbs.c b/drivers/infiniband/hw/ocrdma/ocrdma_verbs.c index 4d5f581af49a..5f656b936de4 100644 --- a/drivers/infiniband/hw/ocrdma/ocrdma_verbs.c +++ b/drivers/infiniband/hw/ocrdma/ocrdma_verbs.c | |||
| @@ -1937,6 +1937,8 @@ static void ocrdma_build_ud_hdr(struct ocrdma_qp *qp, | |||
| 1937 | else | 1937 | else |
| 1938 | ud_hdr->qkey = wr->wr.ud.remote_qkey; | 1938 | ud_hdr->qkey = wr->wr.ud.remote_qkey; |
| 1939 | ud_hdr->rsvd_ahid = ah->id; | 1939 | ud_hdr->rsvd_ahid = ah->id; |
| 1940 | if (ah->av->valid & OCRDMA_AV_VLAN_VALID) | ||
| 1941 | hdr->cw |= (OCRDMA_FLAG_AH_VLAN_PR << OCRDMA_WQE_FLAGS_SHIFT); | ||
| 1940 | } | 1942 | } |
| 1941 | 1943 | ||
| 1942 | static void ocrdma_build_sges(struct ocrdma_hdr_wqe *hdr, | 1944 | static void ocrdma_build_sges(struct ocrdma_hdr_wqe *hdr, |
