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 struct ib_ah
*create_ib_ah(struct mlx5_ib_dev
*dev
,
36 struct mlx5_ib_ah
*ah
,
37 struct ib_ah_attr
*ah_attr
,
38 enum rdma_link_layer ll
)
40 if (ah_attr
->ah_flags
& IB_AH_GRH
) {
41 memcpy(ah
->av
.rgid
, &ah_attr
->grh
.dgid
, 16);
42 ah
->av
.grh_gid_fl
= cpu_to_be32(ah_attr
->grh
.flow_label
|
44 ah_attr
->grh
.sgid_index
<< 20);
45 ah
->av
.hop_limit
= ah_attr
->grh
.hop_limit
;
46 ah
->av
.tclass
= ah_attr
->grh
.traffic_class
;
49 ah
->av
.stat_rate_sl
= (ah_attr
->static_rate
<< 4);
51 if (ll
== IB_LINK_LAYER_ETHERNET
) {
52 memcpy(ah
->av
.rmac
, ah_attr
->dmac
, sizeof(ah_attr
->dmac
));
54 mlx5_get_roce_udp_sport(dev
,
56 ah_attr
->grh
.sgid_index
);
57 ah
->av
.stat_rate_sl
|= (ah_attr
->sl
& 0x7) << 1;
59 ah
->av
.rlid
= cpu_to_be16(ah_attr
->dlid
);
60 ah
->av
.fl_mlid
= ah_attr
->src_path_bits
& 0x7f;
61 ah
->av
.stat_rate_sl
|= (ah_attr
->sl
& 0xf);
67 struct ib_ah
*mlx5_ib_create_ah(struct ib_pd
*pd
, struct ib_ah_attr
*ah_attr
)
69 struct mlx5_ib_ah
*ah
;
70 struct mlx5_ib_dev
*dev
= to_mdev(pd
->device
);
71 enum rdma_link_layer ll
;
73 ll
= pd
->device
->get_link_layer(pd
->device
, ah_attr
->port_num
);
75 if (ll
== IB_LINK_LAYER_ETHERNET
&& !(ah_attr
->ah_flags
& IB_AH_GRH
))
76 return ERR_PTR(-EINVAL
);
78 ah
= kzalloc(sizeof(*ah
), GFP_ATOMIC
);
80 return ERR_PTR(-ENOMEM
);
82 return create_ib_ah(dev
, ah
, ah_attr
, ll
); /* never fails */
85 int mlx5_ib_query_ah(struct ib_ah
*ibah
, struct ib_ah_attr
*ah_attr
)
87 struct mlx5_ib_ah
*ah
= to_mah(ibah
);
90 memset(ah_attr
, 0, sizeof(*ah_attr
));
92 tmp
= be32_to_cpu(ah
->av
.grh_gid_fl
);
93 if (tmp
& (1 << 30)) {
94 ah_attr
->ah_flags
= IB_AH_GRH
;
95 ah_attr
->grh
.sgid_index
= (tmp
>> 20) & 0xff;
96 ah_attr
->grh
.flow_label
= tmp
& 0xfffff;
97 memcpy(&ah_attr
->grh
.dgid
, ah
->av
.rgid
, 16);
98 ah_attr
->grh
.hop_limit
= ah
->av
.hop_limit
;
99 ah_attr
->grh
.traffic_class
= ah
->av
.tclass
;
101 ah_attr
->dlid
= be16_to_cpu(ah
->av
.rlid
);
102 ah_attr
->static_rate
= ah
->av
.stat_rate_sl
>> 4;
103 ah_attr
->sl
= ah
->av
.stat_rate_sl
& 0xf;
108 int mlx5_ib_destroy_ah(struct ib_ah
*ah
)