aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/infiniband/hw/ocrdma/ocrdma_ah.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/infiniband/hw/ocrdma/ocrdma_ah.c')
-rw-r--r--drivers/infiniband/hw/ocrdma/ocrdma_ah.c38
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
40static inline int set_av_attr(struct ocrdma_dev *dev, struct ocrdma_ah *ah, 42static 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, eth_sz); 86 memcpy(&ah->av->eth_hdr, &eth, 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,
91struct ib_ah *ocrdma_create_ah(struct ib_pd *ibpd, struct ib_ah_attr *attr) 94struct 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
141av_conf_err: 150av_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}