2 * Copyright (c) 2013-2015, Mellanox Technologies. All rights reserved.
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:
10 * Redistribution and use in source and binary forms, with or
11 * without modification, are permitted provided that the following
14 * - Redistributions of source code must retain the above
15 * copyright notice, this list of conditions and the following
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.
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
35 static void create_ib_ah(struct mlx5_ib_dev
*dev
, struct mlx5_ib_ah
*ah
,
36 struct rdma_ah_attr
*ah_attr
)
38 enum ib_gid_type gid_type
;
40 if (rdma_ah_get_ah_flags(ah_attr
) & IB_AH_GRH
) {
41 const struct ib_global_route
*grh
= rdma_ah_read_grh(ah_attr
);
43 memcpy(ah
->av
.rgid
, &grh
->dgid
, 16);
44 ah
->av
.grh_gid_fl
= cpu_to_be32(grh
->flow_label
|
46 grh
->sgid_index
<< 20);
47 ah
->av
.hop_limit
= grh
->hop_limit
;
48 ah
->av
.tclass
= grh
->traffic_class
;
51 ah
->av
.stat_rate_sl
= (rdma_ah_get_static_rate(ah_attr
) << 4);
53 if (ah_attr
->type
== RDMA_AH_ATTR_TYPE_ROCE
) {
54 gid_type
= ah_attr
->grh
.sgid_attr
->gid_type
;
56 memcpy(ah
->av
.rmac
, ah_attr
->roce
.dmac
,
57 sizeof(ah_attr
->roce
.dmac
));
59 mlx5_get_roce_udp_sport(dev
, ah_attr
->grh
.sgid_attr
);
60 ah
->av
.stat_rate_sl
|= (rdma_ah_get_sl(ah_attr
) & 0x7) << 1;
61 if (gid_type
== IB_GID_TYPE_ROCE_UDP_ENCAP
)
62 #define MLX5_ECN_ENABLED BIT(1)
63 ah
->av
.tclass
|= MLX5_ECN_ENABLED
;
65 ah
->av
.rlid
= cpu_to_be16(rdma_ah_get_dlid(ah_attr
));
66 ah
->av
.fl_mlid
= rdma_ah_get_path_bits(ah_attr
) & 0x7f;
67 ah
->av
.stat_rate_sl
|= (rdma_ah_get_sl(ah_attr
) & 0xf);
71 int mlx5_ib_create_ah(struct ib_ah
*ibah
, struct rdma_ah_attr
*ah_attr
,
72 u32 flags
, struct ib_udata
*udata
)
75 struct mlx5_ib_ah
*ah
= to_mah(ibah
);
76 struct mlx5_ib_dev
*dev
= to_mdev(ibah
->device
);
77 enum rdma_ah_attr_type ah_type
= ah_attr
->type
;
79 if ((ah_type
== RDMA_AH_ATTR_TYPE_ROCE
) &&
80 !(rdma_ah_get_ah_flags(ah_attr
) & IB_AH_GRH
))
83 if (ah_type
== RDMA_AH_ATTR_TYPE_ROCE
&& udata
) {
85 struct mlx5_ib_create_ah_resp resp
= {};
86 u32 min_resp_len
= offsetof(typeof(resp
), dmac
) +
89 if (udata
->outlen
< min_resp_len
)
92 resp
.response_length
= min_resp_len
;
94 memcpy(resp
.dmac
, ah_attr
->roce
.dmac
, ETH_ALEN
);
95 err
= ib_copy_to_udata(udata
, &resp
, resp
.response_length
);
100 create_ib_ah(dev
, ah
, ah_attr
);
104 int mlx5_ib_query_ah(struct ib_ah
*ibah
, struct rdma_ah_attr
*ah_attr
)
106 struct mlx5_ib_ah
*ah
= to_mah(ibah
);
109 memset(ah_attr
, 0, sizeof(*ah_attr
));
110 ah_attr
->type
= ibah
->type
;
112 tmp
= be32_to_cpu(ah
->av
.grh_gid_fl
);
113 if (tmp
& (1 << 30)) {
114 rdma_ah_set_grh(ah_attr
, NULL
,
119 rdma_ah_set_dgid_raw(ah_attr
, ah
->av
.rgid
);
121 rdma_ah_set_dlid(ah_attr
, be16_to_cpu(ah
->av
.rlid
));
122 rdma_ah_set_static_rate(ah_attr
, ah
->av
.stat_rate_sl
>> 4);
123 rdma_ah_set_sl(ah_attr
, ah
->av
.stat_rate_sl
& 0xf);
128 void mlx5_ib_destroy_ah(struct ib_ah
*ah
, u32 flags
)