blob: e6bde32a83f345a096220112ec0b26a0c9ba2ef5 [file] [log] [blame]
Eli Cohene126ba92013-07-07 17:25:49 +03001/*
Saeed Mahameed6cf0a152015-04-02 17:07:30 +03002 * Copyright (c) 2013-2015, Mellanox Technologies. All rights reserved.
Eli Cohene126ba92013-07-07 17:25:49 +03003 *
4 * This software is available to you under a choice of one of two
5 * licenses. You may choose to be licensed under the terms of the GNU
6 * General Public License (GPL) Version 2, available from the file
7 * COPYING in the main directory of this source tree, or the
8 * OpenIB.org BSD license below:
9 *
10 * Redistribution and use in source and binary forms, with or
11 * without modification, are permitted provided that the following
12 * conditions are met:
13 *
14 * - Redistributions of source code must retain the above
15 * copyright notice, this list of conditions and the following
16 * disclaimer.
17 *
18 * - Redistributions in binary form must reproduce the above
19 * copyright notice, this list of conditions and the following
20 * disclaimer in the documentation and/or other materials
21 * provided with the distribution.
22 *
23 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
24 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
25 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
26 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
27 * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
28 * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
29 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
30 * SOFTWARE.
31 */
32
33#include "mlx5_ib.h"
34
Achiad Shochat2811ba52015-12-23 18:47:24 +020035static struct ib_ah *create_ib_ah(struct mlx5_ib_dev *dev,
36 struct mlx5_ib_ah *ah,
Dasaratharaman Chandramouli44c58482017-04-29 14:41:29 -040037 struct rdma_ah_attr *ah_attr)
Eli Cohene126ba92013-07-07 17:25:49 +030038{
Majd Dibbinyea8af0d2018-03-22 15:34:03 +020039 enum ib_gid_type gid_type;
40 int err;
41
Dasaratharaman Chandramoulid8966fc2017-04-29 14:41:28 -040042 if (rdma_ah_get_ah_flags(ah_attr) & IB_AH_GRH) {
43 const struct ib_global_route *grh = rdma_ah_read_grh(ah_attr);
44
45 memcpy(ah->av.rgid, &grh->dgid, 16);
46 ah->av.grh_gid_fl = cpu_to_be32(grh->flow_label |
Eli Cohene126ba92013-07-07 17:25:49 +030047 (1 << 30) |
Dasaratharaman Chandramoulid8966fc2017-04-29 14:41:28 -040048 grh->sgid_index << 20);
49 ah->av.hop_limit = grh->hop_limit;
50 ah->av.tclass = grh->traffic_class;
Eli Cohene126ba92013-07-07 17:25:49 +030051 }
52
Dasaratharaman Chandramoulid8966fc2017-04-29 14:41:28 -040053 ah->av.stat_rate_sl = (rdma_ah_get_static_rate(ah_attr) << 4);
Achiad Shochat2811ba52015-12-23 18:47:24 +020054
Dasaratharaman Chandramouli44c58482017-04-29 14:41:29 -040055 if (ah_attr->type == RDMA_AH_ATTR_TYPE_ROCE) {
Majd Dibbinyea8af0d2018-03-22 15:34:03 +020056 err = mlx5_get_roce_gid_type(dev, ah_attr->port_num,
57 ah_attr->grh.sgid_index,
58 &gid_type);
59 if (err)
60 return ERR_PTR(err);
61
Dasaratharaman Chandramouli44c58482017-04-29 14:41:29 -040062 memcpy(ah->av.rmac, ah_attr->roce.dmac,
63 sizeof(ah_attr->roce.dmac));
Achiad Shochat2811ba52015-12-23 18:47:24 +020064 ah->av.udp_sport =
Dasaratharaman Chandramoulid8966fc2017-04-29 14:41:28 -040065 mlx5_get_roce_udp_sport(dev,
66 rdma_ah_get_port_num(ah_attr),
67 rdma_ah_read_grh(ah_attr)->sgid_index);
68 ah->av.stat_rate_sl |= (rdma_ah_get_sl(ah_attr) & 0x7) << 1;
Majd Dibbinyea8af0d2018-03-22 15:34:03 +020069 if (gid_type == IB_GID_TYPE_ROCE_UDP_ENCAP)
70#define MLX5_ECN_ENABLED BIT(1)
71 ah->av.tclass |= MLX5_ECN_ENABLED;
Achiad Shochat2811ba52015-12-23 18:47:24 +020072 } else {
Dasaratharaman Chandramoulid8966fc2017-04-29 14:41:28 -040073 ah->av.rlid = cpu_to_be16(rdma_ah_get_dlid(ah_attr));
74 ah->av.fl_mlid = rdma_ah_get_path_bits(ah_attr) & 0x7f;
75 ah->av.stat_rate_sl |= (rdma_ah_get_sl(ah_attr) & 0xf);
Achiad Shochat2811ba52015-12-23 18:47:24 +020076 }
Eli Cohene126ba92013-07-07 17:25:49 +030077
78 return &ah->ibah;
79}
80
Dasaratharaman Chandramouli90898852017-04-29 14:41:18 -040081struct ib_ah *mlx5_ib_create_ah(struct ib_pd *pd, struct rdma_ah_attr *ah_attr,
Moni Shoua477864c2016-11-23 08:23:24 +020082 struct ib_udata *udata)
83
Eli Cohene126ba92013-07-07 17:25:49 +030084{
85 struct mlx5_ib_ah *ah;
Achiad Shochat2811ba52015-12-23 18:47:24 +020086 struct mlx5_ib_dev *dev = to_mdev(pd->device);
Dasaratharaman Chandramouli44c58482017-04-29 14:41:29 -040087 enum rdma_ah_attr_type ah_type = ah_attr->type;
Achiad Shochat2811ba52015-12-23 18:47:24 +020088
Dasaratharaman Chandramouli44c58482017-04-29 14:41:29 -040089 if ((ah_type == RDMA_AH_ATTR_TYPE_ROCE) &&
Dasaratharaman Chandramoulid8966fc2017-04-29 14:41:28 -040090 !(rdma_ah_get_ah_flags(ah_attr) & IB_AH_GRH))
Achiad Shochat2811ba52015-12-23 18:47:24 +020091 return ERR_PTR(-EINVAL);
Eli Cohene126ba92013-07-07 17:25:49 +030092
Dasaratharaman Chandramouli44c58482017-04-29 14:41:29 -040093 if (ah_type == RDMA_AH_ATTR_TYPE_ROCE && udata) {
Moni Shoua5097e712016-11-23 08:23:25 +020094 int err;
95 struct mlx5_ib_create_ah_resp resp = {};
96 u32 min_resp_len = offsetof(typeof(resp), dmac) +
97 sizeof(resp.dmac);
98
99 if (udata->outlen < min_resp_len)
100 return ERR_PTR(-EINVAL);
101
102 resp.response_length = min_resp_len;
103
Dasaratharaman Chandramouli44c58482017-04-29 14:41:29 -0400104 memcpy(resp.dmac, ah_attr->roce.dmac, ETH_ALEN);
Moni Shoua5097e712016-11-23 08:23:25 +0200105 err = ib_copy_to_udata(udata, &resp, resp.response_length);
106 if (err)
107 return ERR_PTR(err);
108 }
109
Eli Cohene126ba92013-07-07 17:25:49 +0300110 ah = kzalloc(sizeof(*ah), GFP_ATOMIC);
111 if (!ah)
112 return ERR_PTR(-ENOMEM);
113
Dasaratharaman Chandramouli44c58482017-04-29 14:41:29 -0400114 return create_ib_ah(dev, ah, ah_attr); /* never fails */
Eli Cohene126ba92013-07-07 17:25:49 +0300115}
116
Dasaratharaman Chandramouli90898852017-04-29 14:41:18 -0400117int mlx5_ib_query_ah(struct ib_ah *ibah, struct rdma_ah_attr *ah_attr)
Eli Cohene126ba92013-07-07 17:25:49 +0300118{
119 struct mlx5_ib_ah *ah = to_mah(ibah);
120 u32 tmp;
121
122 memset(ah_attr, 0, sizeof(*ah_attr));
Dasaratharaman Chandramouli44c58482017-04-29 14:41:29 -0400123 ah_attr->type = ibah->type;
Eli Cohene126ba92013-07-07 17:25:49 +0300124
125 tmp = be32_to_cpu(ah->av.grh_gid_fl);
126 if (tmp & (1 << 30)) {
Dasaratharaman Chandramoulid8966fc2017-04-29 14:41:28 -0400127 rdma_ah_set_grh(ah_attr, NULL,
128 tmp & 0xfffff,
129 (tmp >> 20) & 0xff,
130 ah->av.hop_limit,
131 ah->av.tclass);
132 rdma_ah_set_dgid_raw(ah_attr, ah->av.rgid);
Eli Cohene126ba92013-07-07 17:25:49 +0300133 }
Dasaratharaman Chandramoulid8966fc2017-04-29 14:41:28 -0400134 rdma_ah_set_dlid(ah_attr, be16_to_cpu(ah->av.rlid));
135 rdma_ah_set_static_rate(ah_attr, ah->av.stat_rate_sl >> 4);
136 rdma_ah_set_sl(ah_attr, ah->av.stat_rate_sl & 0xf);
Eli Cohene126ba92013-07-07 17:25:49 +0300137
138 return 0;
139}
140
141int mlx5_ib_destroy_ah(struct ib_ah *ah)
142{
143 kfree(to_mah(ah));
144 return 0;
145}