0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017
0018
0019
0020
0021
0022
0023
0024
0025
0026
0027
0028
0029
0030
0031
0032
0033
0034
0035
0036
0037
0038
0039
0040
0041
0042
0043 #include <net/neighbour.h>
0044 #include <net/netevent.h>
0045
0046 #include <rdma/ib_addr.h>
0047 #include <rdma/ib_mad.h>
0048 #include <rdma/ib_cache.h>
0049
0050 #include "ocrdma.h"
0051 #include "ocrdma_verbs.h"
0052 #include "ocrdma_ah.h"
0053 #include "ocrdma_hw.h"
0054 #include "ocrdma_stats.h"
0055
0056 #define OCRDMA_VID_PCP_SHIFT 0xD
0057
0058 static u16 ocrdma_hdr_type_to_proto_num(int devid, u8 hdr_type)
0059 {
0060 switch (hdr_type) {
0061 case OCRDMA_L3_TYPE_IB_GRH:
0062 return (u16)ETH_P_IBOE;
0063 case OCRDMA_L3_TYPE_IPV4:
0064 return (u16)0x0800;
0065 case OCRDMA_L3_TYPE_IPV6:
0066 return (u16)0x86dd;
0067 default:
0068 pr_err("ocrdma%d: Invalid network header\n", devid);
0069 return 0;
0070 }
0071 }
0072
0073 static inline int set_av_attr(struct ocrdma_dev *dev, struct ocrdma_ah *ah,
0074 struct rdma_ah_attr *attr, const union ib_gid *sgid,
0075 int pdid, bool *isvlan, u16 vlan_tag)
0076 {
0077 int status;
0078 struct ocrdma_eth_vlan eth;
0079 struct ocrdma_grh grh;
0080 int eth_sz;
0081 u16 proto_num = 0;
0082 u8 nxthdr = 0x11;
0083 struct iphdr ipv4;
0084 const struct ib_global_route *ib_grh;
0085 union {
0086 struct sockaddr_in _sockaddr_in;
0087 struct sockaddr_in6 _sockaddr_in6;
0088 } sgid_addr, dgid_addr;
0089
0090 memset(ð, 0, sizeof(eth));
0091 memset(&grh, 0, sizeof(grh));
0092
0093
0094 proto_num = ocrdma_hdr_type_to_proto_num(dev->id, ah->hdr_type);
0095 if (!proto_num)
0096 return -EINVAL;
0097 nxthdr = (proto_num == ETH_P_IBOE) ? 0x1b : 0x11;
0098
0099 if (!vlan_tag || (vlan_tag > 0xFFF))
0100 vlan_tag = dev->pvid;
0101 if (vlan_tag || dev->pfc_state) {
0102 if (!vlan_tag) {
0103 pr_err("ocrdma%d:Using VLAN with PFC is recommended\n",
0104 dev->id);
0105 pr_err("ocrdma%d:Using VLAN 0 for this connection\n",
0106 dev->id);
0107 }
0108 eth.eth_type = cpu_to_be16(0x8100);
0109 eth.roce_eth_type = cpu_to_be16(proto_num);
0110 vlan_tag |= (dev->sl & 0x07) << OCRDMA_VID_PCP_SHIFT;
0111 eth.vlan_tag = cpu_to_be16(vlan_tag);
0112 eth_sz = sizeof(struct ocrdma_eth_vlan);
0113 *isvlan = true;
0114 } else {
0115 eth.eth_type = cpu_to_be16(proto_num);
0116 eth_sz = sizeof(struct ocrdma_eth_basic);
0117 }
0118
0119 memcpy(ð.smac[0], &dev->nic_info.mac_addr[0], ETH_ALEN);
0120 status = ocrdma_resolve_dmac(dev, attr, ð.dmac[0]);
0121 if (status)
0122 return status;
0123 ib_grh = rdma_ah_read_grh(attr);
0124 ah->sgid_index = ib_grh->sgid_index;
0125
0126 memcpy(&ah->av->eth_hdr, ð, eth_sz);
0127 if (ah->hdr_type == RDMA_NETWORK_IPV4) {
0128 *((__be16 *)&ipv4) = htons((4 << 12) | (5 << 8) |
0129 ib_grh->traffic_class);
0130 ipv4.id = cpu_to_be16(pdid);
0131 ipv4.frag_off = htons(IP_DF);
0132 ipv4.tot_len = htons(0);
0133 ipv4.ttl = ib_grh->hop_limit;
0134 ipv4.protocol = nxthdr;
0135 rdma_gid2ip((struct sockaddr *)&sgid_addr, sgid);
0136 ipv4.saddr = sgid_addr._sockaddr_in.sin_addr.s_addr;
0137 rdma_gid2ip((struct sockaddr*)&dgid_addr, &ib_grh->dgid);
0138 ipv4.daddr = dgid_addr._sockaddr_in.sin_addr.s_addr;
0139 memcpy((u8 *)ah->av + eth_sz, &ipv4, sizeof(struct iphdr));
0140 } else {
0141 memcpy(&grh.sgid[0], sgid->raw, sizeof(union ib_gid));
0142 grh.tclass_flow = cpu_to_be32((6 << 28) |
0143 (ib_grh->traffic_class << 24) |
0144 ib_grh->flow_label);
0145 memcpy(&grh.dgid[0], ib_grh->dgid.raw,
0146 sizeof(ib_grh->dgid.raw));
0147 grh.pdid_hoplimit = cpu_to_be32((pdid << 16) |
0148 (nxthdr << 8) |
0149 ib_grh->hop_limit);
0150 memcpy((u8 *)ah->av + eth_sz, &grh, sizeof(struct ocrdma_grh));
0151 }
0152 if (*isvlan)
0153 ah->av->valid |= OCRDMA_AV_VLAN_VALID;
0154 ah->av->valid = cpu_to_le32(ah->av->valid);
0155 return status;
0156 }
0157
0158 int ocrdma_create_ah(struct ib_ah *ibah, struct rdma_ah_init_attr *init_attr,
0159 struct ib_udata *udata)
0160 {
0161 u32 *ahid_addr;
0162 int status;
0163 struct ocrdma_ah *ah = get_ocrdma_ah(ibah);
0164 bool isvlan = false;
0165 u16 vlan_tag = 0xffff;
0166 const struct ib_gid_attr *sgid_attr;
0167 struct ocrdma_pd *pd = get_ocrdma_pd(ibah->pd);
0168 struct rdma_ah_attr *attr = init_attr->ah_attr;
0169 struct ocrdma_dev *dev = get_ocrdma_dev(ibah->device);
0170
0171 if ((attr->type != RDMA_AH_ATTR_TYPE_ROCE) ||
0172 !(rdma_ah_get_ah_flags(attr) & IB_AH_GRH))
0173 return -EINVAL;
0174
0175 if (atomic_cmpxchg(&dev->update_sl, 1, 0))
0176 ocrdma_init_service_level(dev);
0177
0178 sgid_attr = attr->grh.sgid_attr;
0179 status = rdma_read_gid_l2_fields(sgid_attr, &vlan_tag, NULL);
0180 if (status)
0181 return status;
0182
0183 status = ocrdma_alloc_av(dev, ah);
0184 if (status)
0185 goto av_err;
0186
0187
0188 ah->hdr_type = rdma_gid_attr_network_type(sgid_attr);
0189
0190 status = set_av_attr(dev, ah, attr, &sgid_attr->gid, pd->id,
0191 &isvlan, vlan_tag);
0192 if (status)
0193 goto av_conf_err;
0194
0195
0196 if ((pd->uctx) && (pd->uctx->ah_tbl.va)) {
0197 ahid_addr = pd->uctx->ah_tbl.va + rdma_ah_get_dlid(attr);
0198 *ahid_addr = 0;
0199 *ahid_addr |= ah->id & OCRDMA_AH_ID_MASK;
0200 if (ocrdma_is_udp_encap_supported(dev)) {
0201 *ahid_addr |= ((u32)ah->hdr_type &
0202 OCRDMA_AH_L3_TYPE_MASK) <<
0203 OCRDMA_AH_L3_TYPE_SHIFT;
0204 }
0205 if (isvlan)
0206 *ahid_addr |= (OCRDMA_AH_VLAN_VALID_MASK <<
0207 OCRDMA_AH_VLAN_VALID_SHIFT);
0208 }
0209
0210 return 0;
0211
0212 av_conf_err:
0213 ocrdma_free_av(dev, ah);
0214 av_err:
0215 return status;
0216 }
0217
0218 int ocrdma_destroy_ah(struct ib_ah *ibah, u32 flags)
0219 {
0220 struct ocrdma_ah *ah = get_ocrdma_ah(ibah);
0221 struct ocrdma_dev *dev = get_ocrdma_dev(ibah->device);
0222
0223 ocrdma_free_av(dev, ah);
0224 return 0;
0225 }
0226
0227 int ocrdma_query_ah(struct ib_ah *ibah, struct rdma_ah_attr *attr)
0228 {
0229 struct ocrdma_ah *ah = get_ocrdma_ah(ibah);
0230 struct ocrdma_av *av = ah->av;
0231 struct ocrdma_grh *grh;
0232
0233 attr->type = ibah->type;
0234 if (ah->av->valid & OCRDMA_AV_VALID) {
0235 grh = (struct ocrdma_grh *)((u8 *)ah->av +
0236 sizeof(struct ocrdma_eth_vlan));
0237 rdma_ah_set_sl(attr, be16_to_cpu(av->eth_hdr.vlan_tag) >> 13);
0238 } else {
0239 grh = (struct ocrdma_grh *)((u8 *)ah->av +
0240 sizeof(struct ocrdma_eth_basic));
0241 rdma_ah_set_sl(attr, 0);
0242 }
0243 rdma_ah_set_grh(attr, NULL,
0244 be32_to_cpu(grh->tclass_flow) & 0xffffffff,
0245 ah->sgid_index,
0246 be32_to_cpu(grh->pdid_hoplimit) & 0xff,
0247 be32_to_cpu(grh->tclass_flow) >> 24);
0248 rdma_ah_set_dgid_raw(attr, &grh->dgid[0]);
0249 return 0;
0250 }
0251
0252 int ocrdma_process_mad(struct ib_device *ibdev, int process_mad_flags,
0253 u32 port_num, const struct ib_wc *in_wc,
0254 const struct ib_grh *in_grh, const struct ib_mad *in,
0255 struct ib_mad *out, size_t *out_mad_size,
0256 u16 *out_mad_pkey_index)
0257 {
0258 int status = IB_MAD_RESULT_SUCCESS;
0259 struct ocrdma_dev *dev;
0260
0261 if (in->mad_hdr.mgmt_class == IB_MGMT_CLASS_PERF_MGMT) {
0262 dev = get_ocrdma_dev(ibdev);
0263 ocrdma_pma_counters(dev, out);
0264 status |= IB_MAD_RESULT_REPLY;
0265 }
0266
0267 return status;
0268 }