1*4882a593Smuzhiyun // SPDX-License-Identifier: GPL-2.0 OR Linux-OpenIB
2*4882a593Smuzhiyun /*
3*4882a593Smuzhiyun * Copyright (c) 2016 Mellanox Technologies Ltd. All rights reserved.
4*4882a593Smuzhiyun * Copyright (c) 2015 System Fabric Works, Inc. All rights reserved.
5*4882a593Smuzhiyun */
6*4882a593Smuzhiyun
7*4882a593Smuzhiyun #include "rxe.h"
8*4882a593Smuzhiyun #include "rxe_loc.h"
9*4882a593Smuzhiyun
rxe_init_av(struct rdma_ah_attr * attr,struct rxe_av * av)10*4882a593Smuzhiyun void rxe_init_av(struct rdma_ah_attr *attr, struct rxe_av *av)
11*4882a593Smuzhiyun {
12*4882a593Smuzhiyun rxe_av_from_attr(rdma_ah_get_port_num(attr), av, attr);
13*4882a593Smuzhiyun rxe_av_fill_ip_info(av, attr);
14*4882a593Smuzhiyun memcpy(av->dmac, attr->roce.dmac, ETH_ALEN);
15*4882a593Smuzhiyun }
16*4882a593Smuzhiyun
rxe_av_chk_attr(struct rxe_dev * rxe,struct rdma_ah_attr * attr)17*4882a593Smuzhiyun int rxe_av_chk_attr(struct rxe_dev *rxe, struct rdma_ah_attr *attr)
18*4882a593Smuzhiyun {
19*4882a593Smuzhiyun const struct ib_global_route *grh = rdma_ah_read_grh(attr);
20*4882a593Smuzhiyun struct rxe_port *port;
21*4882a593Smuzhiyun int type;
22*4882a593Smuzhiyun
23*4882a593Smuzhiyun port = &rxe->port;
24*4882a593Smuzhiyun
25*4882a593Smuzhiyun if (rdma_ah_get_ah_flags(attr) & IB_AH_GRH) {
26*4882a593Smuzhiyun if (grh->sgid_index > port->attr.gid_tbl_len) {
27*4882a593Smuzhiyun pr_warn("invalid sgid index = %d\n",
28*4882a593Smuzhiyun grh->sgid_index);
29*4882a593Smuzhiyun return -EINVAL;
30*4882a593Smuzhiyun }
31*4882a593Smuzhiyun
32*4882a593Smuzhiyun type = rdma_gid_attr_network_type(grh->sgid_attr);
33*4882a593Smuzhiyun if (type < RDMA_NETWORK_IPV4 ||
34*4882a593Smuzhiyun type > RDMA_NETWORK_IPV6) {
35*4882a593Smuzhiyun pr_warn("invalid network type for rdma_rxe = %d\n",
36*4882a593Smuzhiyun type);
37*4882a593Smuzhiyun return -EINVAL;
38*4882a593Smuzhiyun }
39*4882a593Smuzhiyun }
40*4882a593Smuzhiyun
41*4882a593Smuzhiyun return 0;
42*4882a593Smuzhiyun }
43*4882a593Smuzhiyun
rxe_av_from_attr(u8 port_num,struct rxe_av * av,struct rdma_ah_attr * attr)44*4882a593Smuzhiyun void rxe_av_from_attr(u8 port_num, struct rxe_av *av,
45*4882a593Smuzhiyun struct rdma_ah_attr *attr)
46*4882a593Smuzhiyun {
47*4882a593Smuzhiyun const struct ib_global_route *grh = rdma_ah_read_grh(attr);
48*4882a593Smuzhiyun
49*4882a593Smuzhiyun memset(av, 0, sizeof(*av));
50*4882a593Smuzhiyun memcpy(av->grh.dgid.raw, grh->dgid.raw, sizeof(grh->dgid.raw));
51*4882a593Smuzhiyun av->grh.flow_label = grh->flow_label;
52*4882a593Smuzhiyun av->grh.sgid_index = grh->sgid_index;
53*4882a593Smuzhiyun av->grh.hop_limit = grh->hop_limit;
54*4882a593Smuzhiyun av->grh.traffic_class = grh->traffic_class;
55*4882a593Smuzhiyun av->port_num = port_num;
56*4882a593Smuzhiyun }
57*4882a593Smuzhiyun
rxe_av_to_attr(struct rxe_av * av,struct rdma_ah_attr * attr)58*4882a593Smuzhiyun void rxe_av_to_attr(struct rxe_av *av, struct rdma_ah_attr *attr)
59*4882a593Smuzhiyun {
60*4882a593Smuzhiyun struct ib_global_route *grh = rdma_ah_retrieve_grh(attr);
61*4882a593Smuzhiyun
62*4882a593Smuzhiyun attr->type = RDMA_AH_ATTR_TYPE_ROCE;
63*4882a593Smuzhiyun
64*4882a593Smuzhiyun memcpy(grh->dgid.raw, av->grh.dgid.raw, sizeof(av->grh.dgid.raw));
65*4882a593Smuzhiyun grh->flow_label = av->grh.flow_label;
66*4882a593Smuzhiyun grh->sgid_index = av->grh.sgid_index;
67*4882a593Smuzhiyun grh->hop_limit = av->grh.hop_limit;
68*4882a593Smuzhiyun grh->traffic_class = av->grh.traffic_class;
69*4882a593Smuzhiyun
70*4882a593Smuzhiyun rdma_ah_set_ah_flags(attr, IB_AH_GRH);
71*4882a593Smuzhiyun rdma_ah_set_port_num(attr, av->port_num);
72*4882a593Smuzhiyun }
73*4882a593Smuzhiyun
rxe_av_fill_ip_info(struct rxe_av * av,struct rdma_ah_attr * attr)74*4882a593Smuzhiyun void rxe_av_fill_ip_info(struct rxe_av *av, struct rdma_ah_attr *attr)
75*4882a593Smuzhiyun {
76*4882a593Smuzhiyun const struct ib_gid_attr *sgid_attr = attr->grh.sgid_attr;
77*4882a593Smuzhiyun int ibtype;
78*4882a593Smuzhiyun int type;
79*4882a593Smuzhiyun
80*4882a593Smuzhiyun rdma_gid2ip((struct sockaddr *)&av->sgid_addr, &sgid_attr->gid);
81*4882a593Smuzhiyun rdma_gid2ip((struct sockaddr *)&av->dgid_addr,
82*4882a593Smuzhiyun &rdma_ah_read_grh(attr)->dgid);
83*4882a593Smuzhiyun
84*4882a593Smuzhiyun ibtype = rdma_gid_attr_network_type(sgid_attr);
85*4882a593Smuzhiyun
86*4882a593Smuzhiyun switch (ibtype) {
87*4882a593Smuzhiyun case RDMA_NETWORK_IPV4:
88*4882a593Smuzhiyun type = RXE_NETWORK_TYPE_IPV4;
89*4882a593Smuzhiyun break;
90*4882a593Smuzhiyun case RDMA_NETWORK_IPV6:
91*4882a593Smuzhiyun type = RXE_NETWORK_TYPE_IPV6;
92*4882a593Smuzhiyun break;
93*4882a593Smuzhiyun default:
94*4882a593Smuzhiyun /* not reached - checked in rxe_av_chk_attr */
95*4882a593Smuzhiyun type = 0;
96*4882a593Smuzhiyun break;
97*4882a593Smuzhiyun }
98*4882a593Smuzhiyun
99*4882a593Smuzhiyun av->network_type = type;
100*4882a593Smuzhiyun }
101*4882a593Smuzhiyun
rxe_get_av(struct rxe_pkt_info * pkt)102*4882a593Smuzhiyun struct rxe_av *rxe_get_av(struct rxe_pkt_info *pkt)
103*4882a593Smuzhiyun {
104*4882a593Smuzhiyun if (!pkt || !pkt->qp)
105*4882a593Smuzhiyun return NULL;
106*4882a593Smuzhiyun
107*4882a593Smuzhiyun if (qp_type(pkt->qp) == IB_QPT_RC || qp_type(pkt->qp) == IB_QPT_UC)
108*4882a593Smuzhiyun return &pkt->qp->pri_av;
109*4882a593Smuzhiyun
110*4882a593Smuzhiyun return (pkt->wqe) ? &pkt->wqe->av : NULL;
111*4882a593Smuzhiyun }
112