| .. | .. |
|---|
| 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 | } |
|---|