.. | .. |
---|
32 | 32 | |
---|
33 | 33 | #include "mlx5_ib.h" |
---|
34 | 34 | |
---|
35 | | -static struct ib_ah *create_ib_ah(struct mlx5_ib_dev *dev, |
---|
36 | | - struct mlx5_ib_ah *ah, |
---|
37 | | - struct rdma_ah_attr *ah_attr) |
---|
| 35 | +static __be16 mlx5_ah_get_udp_sport(const struct mlx5_ib_dev *dev, |
---|
| 36 | + const struct rdma_ah_attr *ah_attr) |
---|
38 | 37 | { |
---|
| 38 | + enum ib_gid_type gid_type = ah_attr->grh.sgid_attr->gid_type; |
---|
| 39 | + __be16 sport; |
---|
| 40 | + |
---|
| 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)) |
---|
| 44 | + sport = cpu_to_be16( |
---|
| 45 | + rdma_flow_label_to_udp_sport(ah_attr->grh.flow_label)); |
---|
| 46 | + else |
---|
| 47 | + sport = mlx5_get_roce_udp_sport_min(dev, |
---|
| 48 | + ah_attr->grh.sgid_attr); |
---|
| 49 | + |
---|
| 50 | + return sport; |
---|
| 51 | +} |
---|
| 52 | + |
---|
| 53 | +static void create_ib_ah(struct mlx5_ib_dev *dev, struct mlx5_ib_ah *ah, |
---|
| 54 | + struct rdma_ah_init_attr *init_attr) |
---|
| 55 | +{ |
---|
| 56 | + struct rdma_ah_attr *ah_attr = init_attr->ah_attr; |
---|
39 | 57 | enum ib_gid_type gid_type; |
---|
40 | 58 | |
---|
41 | 59 | if (rdma_ah_get_ah_flags(ah_attr) & IB_AH_GRH) { |
---|
.. | .. |
---|
52 | 70 | ah->av.stat_rate_sl = (rdma_ah_get_static_rate(ah_attr) << 4); |
---|
53 | 71 | |
---|
54 | 72 | if (ah_attr->type == RDMA_AH_ATTR_TYPE_ROCE) { |
---|
| 73 | + if (init_attr->xmit_slave) |
---|
| 74 | + ah->xmit_port = |
---|
| 75 | + mlx5_lag_get_slave_port(dev->mdev, |
---|
| 76 | + init_attr->xmit_slave); |
---|
55 | 77 | gid_type = ah_attr->grh.sgid_attr->gid_type; |
---|
56 | 78 | |
---|
57 | 79 | memcpy(ah->av.rmac, ah_attr->roce.dmac, |
---|
58 | 80 | sizeof(ah_attr->roce.dmac)); |
---|
59 | | - ah->av.udp_sport = |
---|
60 | | - mlx5_get_roce_udp_sport(dev, ah_attr->grh.sgid_attr); |
---|
| 81 | + ah->av.udp_sport = mlx5_ah_get_udp_sport(dev, ah_attr); |
---|
61 | 82 | ah->av.stat_rate_sl |= (rdma_ah_get_sl(ah_attr) & 0x7) << 1; |
---|
62 | 83 | if (gid_type == IB_GID_TYPE_ROCE_UDP_ENCAP) |
---|
63 | 84 | #define MLX5_ECN_ENABLED BIT(1) |
---|
.. | .. |
---|
67 | 88 | ah->av.fl_mlid = rdma_ah_get_path_bits(ah_attr) & 0x7f; |
---|
68 | 89 | ah->av.stat_rate_sl |= (rdma_ah_get_sl(ah_attr) & 0xf); |
---|
69 | 90 | } |
---|
70 | | - |
---|
71 | | - return &ah->ibah; |
---|
72 | 91 | } |
---|
73 | 92 | |
---|
74 | | -struct ib_ah *mlx5_ib_create_ah(struct ib_pd *pd, struct rdma_ah_attr *ah_attr, |
---|
75 | | - struct ib_udata *udata) |
---|
| 93 | +int mlx5_ib_create_ah(struct ib_ah *ibah, struct rdma_ah_init_attr *init_attr, |
---|
| 94 | + struct ib_udata *udata) |
---|
76 | 95 | |
---|
77 | 96 | { |
---|
78 | | - struct mlx5_ib_ah *ah; |
---|
79 | | - struct mlx5_ib_dev *dev = to_mdev(pd->device); |
---|
| 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); |
---|
80 | 100 | enum rdma_ah_attr_type ah_type = ah_attr->type; |
---|
81 | 101 | |
---|
82 | 102 | if ((ah_type == RDMA_AH_ATTR_TYPE_ROCE) && |
---|
83 | 103 | !(rdma_ah_get_ah_flags(ah_attr) & IB_AH_GRH)) |
---|
84 | | - return ERR_PTR(-EINVAL); |
---|
| 104 | + return -EINVAL; |
---|
85 | 105 | |
---|
86 | 106 | if (ah_type == RDMA_AH_ATTR_TYPE_ROCE && udata) { |
---|
87 | 107 | int err; |
---|
88 | 108 | struct mlx5_ib_create_ah_resp resp = {}; |
---|
89 | | - u32 min_resp_len = offsetof(typeof(resp), dmac) + |
---|
90 | | - sizeof(resp.dmac); |
---|
| 109 | + u32 min_resp_len = |
---|
| 110 | + offsetofend(struct mlx5_ib_create_ah_resp, dmac); |
---|
91 | 111 | |
---|
92 | 112 | if (udata->outlen < min_resp_len) |
---|
93 | | - return ERR_PTR(-EINVAL); |
---|
| 113 | + return -EINVAL; |
---|
94 | 114 | |
---|
95 | 115 | resp.response_length = min_resp_len; |
---|
96 | 116 | |
---|
97 | 117 | memcpy(resp.dmac, ah_attr->roce.dmac, ETH_ALEN); |
---|
98 | 118 | err = ib_copy_to_udata(udata, &resp, resp.response_length); |
---|
99 | 119 | if (err) |
---|
100 | | - return ERR_PTR(err); |
---|
| 120 | + return err; |
---|
101 | 121 | } |
---|
102 | 122 | |
---|
103 | | - ah = kzalloc(sizeof(*ah), GFP_ATOMIC); |
---|
104 | | - if (!ah) |
---|
105 | | - return ERR_PTR(-ENOMEM); |
---|
106 | | - |
---|
107 | | - return create_ib_ah(dev, ah, ah_attr); /* never fails */ |
---|
| 123 | + create_ib_ah(dev, ah, init_attr); |
---|
| 124 | + return 0; |
---|
108 | 125 | } |
---|
109 | 126 | |
---|
110 | 127 | int mlx5_ib_query_ah(struct ib_ah *ibah, struct rdma_ah_attr *ah_attr) |
---|
.. | .. |
---|
128 | 145 | rdma_ah_set_static_rate(ah_attr, ah->av.stat_rate_sl >> 4); |
---|
129 | 146 | rdma_ah_set_sl(ah_attr, ah->av.stat_rate_sl & 0xf); |
---|
130 | 147 | |
---|
131 | | - return 0; |
---|
132 | | -} |
---|
133 | | - |
---|
134 | | -int mlx5_ib_destroy_ah(struct ib_ah *ah) |
---|
135 | | -{ |
---|
136 | | - kfree(to_mah(ah)); |
---|
137 | 148 | return 0; |
---|
138 | 149 | } |
---|