Skip to content

Commit 2811ba5

Browse files
Achiad Shochatdledford
authored andcommitted
IB/mlx5: Add RoCE fields to Address Vector
Set the address handle and QP address path fields according to the link layer type (IB/Eth). Signed-off-by: Achiad Shochat <[email protected]> Signed-off-by: Doug Ledford <[email protected]>
1 parent 3cca260 commit 2811ba5

File tree

5 files changed

+96
-25
lines changed

5 files changed

+96
-25
lines changed

drivers/infiniband/hw/mlx5/ah.c

Lines changed: 26 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -32,8 +32,10 @@
3232

3333
#include "mlx5_ib.h"
3434

35-
struct ib_ah *create_ib_ah(struct ib_ah_attr *ah_attr,
36-
struct mlx5_ib_ah *ah)
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)
3739
{
3840
if (ah_attr->ah_flags & IB_AH_GRH) {
3941
memcpy(ah->av.rgid, &ah_attr->grh.dgid, 16);
@@ -44,22 +46,40 @@ struct ib_ah *create_ib_ah(struct ib_ah_attr *ah_attr,
4446
ah->av.tclass = ah_attr->grh.traffic_class;
4547
}
4648

47-
ah->av.rlid = cpu_to_be16(ah_attr->dlid);
48-
ah->av.fl_mlid = ah_attr->src_path_bits & 0x7f;
49-
ah->av.stat_rate_sl = (ah_attr->static_rate << 4) | (ah_attr->sl & 0xf);
49+
ah->av.stat_rate_sl = (ah_attr->static_rate << 4);
50+
51+
if (ll == IB_LINK_LAYER_ETHERNET) {
52+
memcpy(ah->av.rmac, ah_attr->dmac, sizeof(ah_attr->dmac));
53+
ah->av.udp_sport =
54+
mlx5_get_roce_udp_sport(dev,
55+
ah_attr->port_num,
56+
ah_attr->grh.sgid_index);
57+
ah->av.stat_rate_sl |= (ah_attr->sl & 0x7) << 1;
58+
} else {
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);
62+
}
5063

5164
return &ah->ibah;
5265
}
5366

5467
struct ib_ah *mlx5_ib_create_ah(struct ib_pd *pd, struct ib_ah_attr *ah_attr)
5568
{
5669
struct mlx5_ib_ah *ah;
70+
struct mlx5_ib_dev *dev = to_mdev(pd->device);
71+
enum rdma_link_layer ll;
72+
73+
ll = pd->device->get_link_layer(pd->device, ah_attr->port_num);
74+
75+
if (ll == IB_LINK_LAYER_ETHERNET && !(ah_attr->ah_flags & IB_AH_GRH))
76+
return ERR_PTR(-EINVAL);
5777

5878
ah = kzalloc(sizeof(*ah), GFP_ATOMIC);
5979
if (!ah)
6080
return ERR_PTR(-ENOMEM);
6181

62-
return create_ib_ah(ah_attr, ah); /* never fails */
82+
return create_ib_ah(dev, ah, ah_attr, ll); /* never fails */
6383
}
6484

6585
int mlx5_ib_query_ah(struct ib_ah *ibah, struct ib_ah_attr *ah_attr)

drivers/infiniband/hw/mlx5/main.c

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,7 @@
4141
#include <linux/sched.h>
4242
#include <rdma/ib_user_verbs.h>
4343
#include <rdma/ib_addr.h>
44+
#include <rdma/ib_cache.h>
4445
#include <linux/mlx5/vport.h>
4546
#include <rdma/ib_smi.h>
4647
#include <rdma/ib_umem.h>
@@ -252,6 +253,26 @@ static int mlx5_ib_del_gid(struct ib_device *device, u8 port_num,
252253
return set_roce_addr(device, port_num, index, NULL, NULL);
253254
}
254255

256+
__be16 mlx5_get_roce_udp_sport(struct mlx5_ib_dev *dev, u8 port_num,
257+
int index)
258+
{
259+
struct ib_gid_attr attr;
260+
union ib_gid gid;
261+
262+
if (ib_get_cached_gid(&dev->ib_dev, port_num, index, &gid, &attr))
263+
return 0;
264+
265+
if (!attr.ndev)
266+
return 0;
267+
268+
dev_put(attr.ndev);
269+
270+
if (attr.gid_type != IB_GID_TYPE_ROCE_UDP_ENCAP)
271+
return 0;
272+
273+
return cpu_to_be16(MLX5_CAP_ROCE(dev->mdev, r_roce_min_src_udp_port));
274+
}
275+
255276
static int mlx5_use_mad_ifc(struct mlx5_ib_dev *dev)
256277
{
257278
return !dev->mdev->issi;

drivers/infiniband/hw/mlx5/mlx5_ib.h

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -517,8 +517,6 @@ void mlx5_ib_free_srq_wqe(struct mlx5_ib_srq *srq, int wqe_index);
517517
int mlx5_MAD_IFC(struct mlx5_ib_dev *dev, int ignore_mkey, int ignore_bkey,
518518
u8 port, const struct ib_wc *in_wc, const struct ib_grh *in_grh,
519519
const void *in_mad, void *response_mad);
520-
struct ib_ah *create_ib_ah(struct ib_ah_attr *ah_attr,
521-
struct mlx5_ib_ah *ah);
522520
struct ib_ah *mlx5_ib_create_ah(struct ib_pd *pd, struct ib_ah_attr *ah_attr);
523521
int mlx5_ib_query_ah(struct ib_ah *ibah, struct ib_ah_attr *ah_attr);
524522
int mlx5_ib_destroy_ah(struct ib_ah *ah);
@@ -647,6 +645,9 @@ static inline void mlx5_ib_qp_enable_pagefaults(struct mlx5_ib_qp *qp) {}
647645

648646
#endif /* CONFIG_INFINIBAND_ON_DEMAND_PAGING */
649647

648+
__be16 mlx5_get_roce_udp_sport(struct mlx5_ib_dev *dev, u8 port_num,
649+
int index);
650+
650651
static inline void init_query_mad(struct ib_smp *mad)
651652
{
652653
mad->base_version = 1;

drivers/infiniband/hw/mlx5/qp.c

Lines changed: 31 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@
3232

3333
#include <linux/module.h>
3434
#include <rdma/ib_umem.h>
35+
#include <rdma/ib_cache.h>
3536
#include "mlx5_ib.h"
3637
#include "user.h"
3738

@@ -1364,17 +1365,12 @@ static int mlx5_set_path(struct mlx5_ib_dev *dev, const struct ib_ah_attr *ah,
13641365
struct mlx5_qp_path *path, u8 port, int attr_mask,
13651366
u32 path_flags, const struct ib_qp_attr *attr)
13661367
{
1368+
enum rdma_link_layer ll = rdma_port_get_link_layer(&dev->ib_dev, port);
13671369
int err;
13681370

1369-
path->fl = (path_flags & MLX5_PATH_FLAG_FL) ? 0x80 : 0;
1370-
path->free_ar = (path_flags & MLX5_PATH_FLAG_FREE_AR) ? 0x80 : 0;
1371-
13721371
if (attr_mask & IB_QP_PKEY_INDEX)
13731372
path->pkey_index = attr->pkey_index;
13741373

1375-
path->grh_mlid = ah->src_path_bits & 0x7f;
1376-
path->rlid = cpu_to_be16(ah->dlid);
1377-
13781374
if (ah->ah_flags & IB_AH_GRH) {
13791375
if (ah->grh.sgid_index >=
13801376
dev->mdev->port_caps[port - 1].gid_table_len) {
@@ -1383,7 +1379,27 @@ static int mlx5_set_path(struct mlx5_ib_dev *dev, const struct ib_ah_attr *ah,
13831379
dev->mdev->port_caps[port - 1].gid_table_len);
13841380
return -EINVAL;
13851381
}
1386-
path->grh_mlid |= 1 << 7;
1382+
}
1383+
1384+
if (ll == IB_LINK_LAYER_ETHERNET) {
1385+
if (!(ah->ah_flags & IB_AH_GRH))
1386+
return -EINVAL;
1387+
memcpy(path->rmac, ah->dmac, sizeof(ah->dmac));
1388+
path->udp_sport = mlx5_get_roce_udp_sport(dev, port,
1389+
ah->grh.sgid_index);
1390+
path->dci_cfi_prio_sl = (ah->sl & 0x7) << 4;
1391+
} else {
1392+
path->fl = (path_flags & MLX5_PATH_FLAG_FL) ? 0x80 : 0;
1393+
path->free_ar = (path_flags & MLX5_PATH_FLAG_FREE_AR) ? 0x80 :
1394+
0;
1395+
path->rlid = cpu_to_be16(ah->dlid);
1396+
path->grh_mlid = ah->src_path_bits & 0x7f;
1397+
if (ah->ah_flags & IB_AH_GRH)
1398+
path->grh_mlid |= 1 << 7;
1399+
path->dci_cfi_prio_sl = ah->sl & 0xf;
1400+
}
1401+
1402+
if (ah->ah_flags & IB_AH_GRH) {
13871403
path->mgid_index = ah->grh.sgid_index;
13881404
path->hop_limit = ah->grh.hop_limit;
13891405
path->tclass_flowlabel =
@@ -1401,8 +1417,6 @@ static int mlx5_set_path(struct mlx5_ib_dev *dev, const struct ib_ah_attr *ah,
14011417
if (attr_mask & IB_QP_TIMEOUT)
14021418
path->ackto_lt = attr->timeout << 3;
14031419

1404-
path->sl = ah->sl & 0xf;
1405-
14061420
return 0;
14071421
}
14081422

@@ -1765,15 +1779,21 @@ int mlx5_ib_modify_qp(struct ib_qp *ibqp, struct ib_qp_attr *attr,
17651779
enum ib_qp_state cur_state, new_state;
17661780
int err = -EINVAL;
17671781
int port;
1782+
enum rdma_link_layer ll = IB_LINK_LAYER_UNSPECIFIED;
17681783

17691784
mutex_lock(&qp->mutex);
17701785

17711786
cur_state = attr_mask & IB_QP_CUR_STATE ? attr->cur_qp_state : qp->state;
17721787
new_state = attr_mask & IB_QP_STATE ? attr->qp_state : cur_state;
17731788

1789+
if (!(cur_state == new_state && cur_state == IB_QPS_RESET)) {
1790+
port = attr_mask & IB_QP_PORT ? attr->port_num : qp->port;
1791+
ll = dev->ib_dev.get_link_layer(&dev->ib_dev, port);
1792+
}
1793+
17741794
if (ibqp->qp_type != MLX5_IB_QPT_REG_UMR &&
17751795
!ib_modify_qp_is_ok(cur_state, new_state, ibqp->qp_type, attr_mask,
1776-
IB_LINK_LAYER_UNSPECIFIED))
1796+
ll))
17771797
goto out;
17781798

17791799
if ((attr_mask & IB_QP_PORT) &&
@@ -3003,7 +3023,7 @@ static void to_ib_ah_attr(struct mlx5_ib_dev *ibdev, struct ib_ah_attr *ib_ah_at
30033023
ib_ah_attr->port_num > MLX5_CAP_GEN(dev, num_ports))
30043024
return;
30053025

3006-
ib_ah_attr->sl = path->sl & 0xf;
3026+
ib_ah_attr->sl = path->dci_cfi_prio_sl & 0xf;
30073027

30083028
ib_ah_attr->dlid = be16_to_cpu(path->rlid);
30093029
ib_ah_attr->src_path_bits = path->grh_mlid & 0x7f;

include/linux/mlx5/qp.h

Lines changed: 15 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -248,8 +248,12 @@ struct mlx5_av {
248248
__be32 dqp_dct;
249249
u8 stat_rate_sl;
250250
u8 fl_mlid;
251-
__be16 rlid;
252-
u8 reserved0[10];
251+
union {
252+
__be16 rlid;
253+
__be16 udp_sport;
254+
};
255+
u8 reserved0[4];
256+
u8 rmac[6];
253257
u8 tclass;
254258
u8 hop_limit;
255259
__be32 grh_gid_fl;
@@ -456,11 +460,16 @@ struct mlx5_qp_path {
456460
u8 static_rate;
457461
u8 hop_limit;
458462
__be32 tclass_flowlabel;
459-
u8 rgid[16];
460-
u8 rsvd1[4];
461-
u8 sl;
463+
union {
464+
u8 rgid[16];
465+
u8 rip[16];
466+
};
467+
u8 f_dscp_ecn_prio;
468+
u8 ecn_dscp;
469+
__be16 udp_sport;
470+
u8 dci_cfi_prio_sl;
462471
u8 port;
463-
u8 rsvd2[6];
472+
u8 rmac[6];
464473
};
465474

466475
struct mlx5_qp_context {

0 commit comments

Comments
 (0)