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 __be16
mlx5_ah_get_udp_sport(const struct mlx5_ib_dev
*dev
,
36 const struct rdma_ah_attr
*ah_attr
)
38 enum ib_gid_type gid_type
= ah_attr
->grh
.sgid_attr
->gid_type
;
41 if ((gid_type
== IB_GID_TYPE_ROCE_UDP_ENCAP
) &&
42 (rdma_ah_get_ah_flags(ah_attr
) & IB_AH_GRH
) &&
43 (ah_attr
->grh
.flow_label
& IB_GRH_FLOWLABEL_MASK
))
45 rdma_flow_label_to_udp_sport(ah_attr
->grh
.flow_label
));
47 sport
= mlx5_get_roce_udp_sport_min(dev
,
48 ah_attr
->grh
.sgid_attr
);
53 static void create_ib_ah(struct mlx5_ib_dev
*dev
, struct mlx5_ib_ah
*ah
,
54 struct rdma_ah_init_attr
*init_attr
)
56 struct rdma_ah_attr
*ah_attr
= init_attr
->ah_attr
;
57 enum ib_gid_type gid_type
;
59 if (rdma_ah_get_ah_flags(ah_attr
) & IB_AH_GRH
) {
60 const struct ib_global_route
*grh
= rdma_ah_read_grh(ah_attr
);
62 memcpy(ah
->av
.rgid
, &grh
->dgid
, 16);
63 ah
->av
.grh_gid_fl
= cpu_to_be32(grh
->flow_label
|
65 grh
->sgid_index
<< 20);
66 ah
->av
.hop_limit
= grh
->hop_limit
;
67 ah
->av
.tclass
= grh
->traffic_class
;
70 ah
->av
.stat_rate_sl
= (rdma_ah_get_static_rate(ah_attr
) << 4);
72 if (ah_attr
->type
== RDMA_AH_ATTR_TYPE_ROCE
) {
73 if (init_attr
->xmit_slave
)
75 mlx5_lag_get_slave_port(dev
->mdev
,
76 init_attr
->xmit_slave
);
77 gid_type
= ah_attr
->grh
.sgid_attr
->gid_type
;
79 memcpy(ah
->av
.rmac
, ah_attr
->roce
.dmac
,
80 sizeof(ah_attr
->roce
.dmac
));
81 ah
->av
.udp_sport
= mlx5_ah_get_udp_sport(dev
, ah_attr
);
82 ah
->av
.stat_rate_sl
|= (rdma_ah_get_sl(ah_attr
) & 0x7) << 1;
83 if (gid_type
== IB_GID_TYPE_ROCE_UDP_ENCAP
)
84 #define MLX5_ECN_ENABLED BIT(1)
85 ah
->av
.tclass
|= MLX5_ECN_ENABLED
;
87 ah
->av
.rlid
= cpu_to_be16(rdma_ah_get_dlid(ah_attr
));
88 ah
->av
.fl_mlid
= rdma_ah_get_path_bits(ah_attr
) & 0x7f;
89 ah
->av
.stat_rate_sl
|= (rdma_ah_get_sl(ah_attr
) & 0xf);
93 int mlx5_ib_create_ah(struct ib_ah
*ibah
, struct rdma_ah_init_attr
*init_attr
,
94 struct ib_udata
*udata
)
97 struct rdma_ah_attr
*ah_attr
= init_attr
->ah_attr
;
98 struct mlx5_ib_ah
*ah
= to_mah(ibah
);
99 struct mlx5_ib_dev
*dev
= to_mdev(ibah
->device
);
100 enum rdma_ah_attr_type ah_type
= ah_attr
->type
;
102 if ((ah_type
== RDMA_AH_ATTR_TYPE_ROCE
) &&
103 !(rdma_ah_get_ah_flags(ah_attr
) & IB_AH_GRH
))
106 if (ah_type
== RDMA_AH_ATTR_TYPE_ROCE
&& udata
) {
108 struct mlx5_ib_create_ah_resp resp
= {};
110 offsetofend(struct mlx5_ib_create_ah_resp
, dmac
);
112 if (udata
->outlen
< min_resp_len
)
115 resp
.response_length
= min_resp_len
;
117 memcpy(resp
.dmac
, ah_attr
->roce
.dmac
, ETH_ALEN
);
118 err
= ib_copy_to_udata(udata
, &resp
, resp
.response_length
);
123 create_ib_ah(dev
, ah
, init_attr
);
127 int mlx5_ib_query_ah(struct ib_ah
*ibah
, struct rdma_ah_attr
*ah_attr
)
129 struct mlx5_ib_ah
*ah
= to_mah(ibah
);
132 memset(ah_attr
, 0, sizeof(*ah_attr
));
133 ah_attr
->type
= ibah
->type
;
135 tmp
= be32_to_cpu(ah
->av
.grh_gid_fl
);
136 if (tmp
& (1 << 30)) {
137 rdma_ah_set_grh(ah_attr
, NULL
,
142 rdma_ah_set_dgid_raw(ah_attr
, ah
->av
.rgid
);
144 rdma_ah_set_dlid(ah_attr
, be16_to_cpu(ah
->av
.rlid
));
145 rdma_ah_set_static_rate(ah_attr
, ah
->av
.stat_rate_sl
>> 4);
146 rdma_ah_set_sl(ah_attr
, ah
->av
.stat_rate_sl
& 0xf);