1 | // SPDX-License-Identifier: GPL-2.0-only |
---|---|
2 | /* |
3 | * Copyright (c) 2024, Microsoft Corporation. All rights reserved. |
4 | */ |
5 | |
6 | #include "mana_ib.h" |
7 | |
8 | int mana_ib_create_ah(struct ib_ah *ibah, struct rdma_ah_init_attr *attr, |
9 | struct ib_udata *udata) |
10 | { |
11 | struct mana_ib_dev *mdev = container_of(ibah->device, struct mana_ib_dev, ib_dev); |
12 | struct mana_ib_ah *ah = container_of(ibah, struct mana_ib_ah, ibah); |
13 | struct rdma_ah_attr *ah_attr = attr->ah_attr; |
14 | const struct ib_global_route *grh; |
15 | enum rdma_network_type ntype; |
16 | |
17 | if (ah_attr->type != RDMA_AH_ATTR_TYPE_ROCE || |
18 | !(rdma_ah_get_ah_flags(attr: ah_attr) & IB_AH_GRH)) |
19 | return -EINVAL; |
20 | |
21 | if (udata) |
22 | return -EINVAL; |
23 | |
24 | ah->av = dma_pool_zalloc(pool: mdev->av_pool, GFP_ATOMIC, handle: &ah->dma_handle); |
25 | if (!ah->av) |
26 | return -ENOMEM; |
27 | |
28 | grh = rdma_ah_read_grh(attr: ah_attr); |
29 | ntype = rdma_gid_attr_network_type(attr: grh->sgid_attr); |
30 | |
31 | copy_in_reverse(dst: ah->av->dest_mac, src: ah_attr->roce.dmac, ETH_ALEN); |
32 | ah->av->udp_src_port = rdma_flow_label_to_udp_sport(fl: grh->flow_label); |
33 | ah->av->hop_limit = grh->hop_limit; |
34 | ah->av->dscp = (grh->traffic_class >> 2) & 0x3f; |
35 | ah->av->is_ipv6 = (ntype == RDMA_NETWORK_IPV6); |
36 | |
37 | if (ah->av->is_ipv6) { |
38 | copy_in_reverse(dst: ah->av->dest_ip, src: grh->dgid.raw, size: 16); |
39 | copy_in_reverse(dst: ah->av->src_ip, src: grh->sgid_attr->gid.raw, size: 16); |
40 | } else { |
41 | ah->av->dest_ip[10] = 0xFF; |
42 | ah->av->dest_ip[11] = 0xFF; |
43 | copy_in_reverse(dst: &ah->av->dest_ip[12], src: &grh->dgid.raw[12], size: 4); |
44 | copy_in_reverse(dst: &ah->av->src_ip[12], src: &grh->sgid_attr->gid.raw[12], size: 4); |
45 | } |
46 | |
47 | return 0; |
48 | } |
49 | |
50 | int mana_ib_destroy_ah(struct ib_ah *ibah, u32 flags) |
51 | { |
52 | struct mana_ib_dev *mdev = container_of(ibah->device, struct mana_ib_dev, ib_dev); |
53 | struct mana_ib_ah *ah = container_of(ibah, struct mana_ib_ah, ibah); |
54 | |
55 | dma_pool_free(pool: mdev->av_pool, vaddr: ah->av, addr: ah->dma_handle); |
56 | |
57 | return 0; |
58 | } |
59 |