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 | } |
