diff options
Diffstat (limited to 'drivers/infiniband/hw/ocrdma/ocrdma_ah.c')
-rw-r--r-- | drivers/infiniband/hw/ocrdma/ocrdma_ah.c | 38 |
1 files changed, 31 insertions, 7 deletions
diff --git a/drivers/infiniband/hw/ocrdma/ocrdma_ah.c b/drivers/infiniband/hw/ocrdma/ocrdma_ah.c index f3cc8c9e65ae..d812904f3984 100644 --- a/drivers/infiniband/hw/ocrdma/ocrdma_ah.c +++ b/drivers/infiniband/hw/ocrdma/ocrdma_ah.c | |||
@@ -29,19 +29,22 @@ | |||
29 | #include <net/netevent.h> | 29 | #include <net/netevent.h> |
30 | 30 | ||
31 | #include <rdma/ib_addr.h> | 31 | #include <rdma/ib_addr.h> |
32 | #include <rdma/ib_mad.h> | ||
32 | 33 | ||
33 | #include "ocrdma.h" | 34 | #include "ocrdma.h" |
34 | #include "ocrdma_verbs.h" | 35 | #include "ocrdma_verbs.h" |
35 | #include "ocrdma_ah.h" | 36 | #include "ocrdma_ah.h" |
36 | #include "ocrdma_hw.h" | 37 | #include "ocrdma_hw.h" |
38 | #include "ocrdma_stats.h" | ||
37 | 39 | ||
38 | #define OCRDMA_VID_PCP_SHIFT 0xD | 40 | #define OCRDMA_VID_PCP_SHIFT 0xD |
39 | 41 | ||
40 | 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, |
41 | 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) | ||
42 | { | 45 | { |
43 | int status = 0; | 46 | int status = 0; |
44 | u16 vlan_tag; bool vlan_enabled = false; | 47 | u16 vlan_tag; |
45 | struct ocrdma_eth_vlan eth; | 48 | struct ocrdma_eth_vlan eth; |
46 | struct ocrdma_grh grh; | 49 | struct ocrdma_grh grh; |
47 | int eth_sz; | 50 | int eth_sz; |
@@ -59,7 +62,7 @@ static inline int set_av_attr(struct ocrdma_dev *dev, struct ocrdma_ah *ah, | |||
59 | vlan_tag |= (dev->sl & 0x07) << OCRDMA_VID_PCP_SHIFT; | 62 | vlan_tag |= (dev->sl & 0x07) << OCRDMA_VID_PCP_SHIFT; |
60 | eth.vlan_tag = cpu_to_be16(vlan_tag); | 63 | eth.vlan_tag = cpu_to_be16(vlan_tag); |
61 | eth_sz = sizeof(struct ocrdma_eth_vlan); | 64 | eth_sz = sizeof(struct ocrdma_eth_vlan); |
62 | vlan_enabled = true; | 65 | *isvlan = true; |
63 | } else { | 66 | } else { |
64 | eth.eth_type = cpu_to_be16(OCRDMA_ROCE_ETH_TYPE); | 67 | eth.eth_type = cpu_to_be16(OCRDMA_ROCE_ETH_TYPE); |
65 | eth_sz = sizeof(struct ocrdma_eth_basic); | 68 | eth_sz = sizeof(struct ocrdma_eth_basic); |
@@ -82,7 +85,7 @@ static inline int set_av_attr(struct ocrdma_dev *dev, struct ocrdma_ah *ah, | |||
82 | /* Eth HDR */ | 85 | /* Eth HDR */ |
83 | memcpy(&ah->av->eth_hdr, ð, eth_sz); | 86 | memcpy(&ah->av->eth_hdr, ð, eth_sz); |
84 | memcpy((u8 *)ah->av + eth_sz, &grh, sizeof(struct ocrdma_grh)); | 87 | memcpy((u8 *)ah->av + eth_sz, &grh, sizeof(struct ocrdma_grh)); |
85 | if (vlan_enabled) | 88 | if (*isvlan) |
86 | ah->av->valid |= OCRDMA_AV_VLAN_VALID; | 89 | ah->av->valid |= OCRDMA_AV_VLAN_VALID; |
87 | ah->av->valid = cpu_to_le32(ah->av->valid); | 90 | ah->av->valid = cpu_to_le32(ah->av->valid); |
88 | return status; | 91 | return status; |
@@ -91,6 +94,7 @@ static inline int set_av_attr(struct ocrdma_dev *dev, struct ocrdma_ah *ah, | |||
91 | 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) |
92 | { | 95 | { |
93 | u32 *ahid_addr; | 96 | u32 *ahid_addr; |
97 | bool isvlan = false; | ||
94 | int status; | 98 | int status; |
95 | struct ocrdma_ah *ah; | 99 | struct ocrdma_ah *ah; |
96 | struct ocrdma_pd *pd = get_ocrdma_pd(ibpd); | 100 | struct ocrdma_pd *pd = get_ocrdma_pd(ibpd); |
@@ -127,15 +131,20 @@ struct ib_ah *ocrdma_create_ah(struct ib_pd *ibpd, struct ib_ah_attr *attr) | |||
127 | } | 131 | } |
128 | } | 132 | } |
129 | 133 | ||
130 | status = set_av_attr(dev, ah, attr, &sgid, pd->id); | 134 | status = set_av_attr(dev, ah, attr, &sgid, pd->id, &isvlan); |
131 | if (status) | 135 | if (status) |
132 | goto av_conf_err; | 136 | goto av_conf_err; |
133 | 137 | ||
134 | /* 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 */ |
135 | if ((pd->uctx) && (pd->uctx->ah_tbl.va)) { | 139 | if ((pd->uctx) && (pd->uctx->ah_tbl.va)) { |
136 | ahid_addr = pd->uctx->ah_tbl.va + attr->dlid; | 140 | ahid_addr = pd->uctx->ah_tbl.va + attr->dlid; |
137 | *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); | ||
138 | } | 146 | } |
147 | |||
139 | return &ah->ibah; | 148 | return &ah->ibah; |
140 | 149 | ||
141 | av_conf_err: | 150 | av_conf_err: |
@@ -191,5 +200,20 @@ int ocrdma_process_mad(struct ib_device *ibdev, | |||
191 | struct ib_grh *in_grh, | 200 | struct ib_grh *in_grh, |
192 | struct ib_mad *in_mad, struct ib_mad *out_mad) | 201 | struct ib_mad *in_mad, struct ib_mad *out_mad) |
193 | { | 202 | { |
194 | return IB_MAD_RESULT_SUCCESS; | 203 | int status; |
204 | struct ocrdma_dev *dev; | ||
205 | |||
206 | switch (in_mad->mad_hdr.mgmt_class) { | ||
207 | case IB_MGMT_CLASS_PERF_MGMT: | ||
208 | dev = get_ocrdma_dev(ibdev); | ||
209 | if (!ocrdma_pma_counters(dev, out_mad)) | ||
210 | status = IB_MAD_RESULT_SUCCESS | IB_MAD_RESULT_REPLY; | ||
211 | else | ||
212 | status = IB_MAD_RESULT_SUCCESS; | ||
213 | break; | ||
214 | default: | ||
215 | status = IB_MAD_RESULT_SUCCESS; | ||
216 | break; | ||
217 | } | ||
218 | return status; | ||
195 | } | 219 | } |