1 // SPDX-License-Identifier: GPL-2.0 OR Linux-OpenIB
3 * Copyright (c) 2018 Mellanox Technologies. All rights reserved.
6 #include <linux/mlx5/vport.h>
11 mlx5_ib_set_vport_rep(struct mlx5_core_dev
*dev
, struct mlx5_eswitch_rep
*rep
)
13 struct mlx5_ib_dev
*ibdev
;
16 ibdev
= mlx5_ib_get_uplink_ibdev(dev
->priv
.eswitch
);
17 vport_index
= rep
->vport_index
;
19 ibdev
->port
[vport_index
].rep
= rep
;
20 rep
->rep_data
[REP_IB
].priv
= ibdev
;
21 write_lock(&ibdev
->port
[vport_index
].roce
.netdev_lock
);
22 ibdev
->port
[vport_index
].roce
.netdev
=
23 mlx5_ib_get_rep_netdev(dev
->priv
.eswitch
, rep
->vport
);
24 write_unlock(&ibdev
->port
[vport_index
].roce
.netdev_lock
);
30 mlx5_ib_vport_rep_load(struct mlx5_core_dev
*dev
, struct mlx5_eswitch_rep
*rep
)
32 int num_ports
= mlx5_eswitch_get_total_vports(dev
);
33 const struct mlx5_ib_profile
*profile
;
34 struct mlx5_ib_dev
*ibdev
;
37 if (rep
->vport
== MLX5_VPORT_UPLINK
)
38 profile
= &uplink_rep_profile
;
40 return mlx5_ib_set_vport_rep(dev
, rep
);
42 ibdev
= ib_alloc_device(mlx5_ib_dev
, ib_dev
);
46 ibdev
->port
= kcalloc(num_ports
, sizeof(*ibdev
->port
),
49 ib_dealloc_device(&ibdev
->ib_dev
);
54 vport_index
= rep
->vport_index
;
55 ibdev
->port
[vport_index
].rep
= rep
;
56 ibdev
->port
[vport_index
].roce
.netdev
=
57 mlx5_ib_get_rep_netdev(dev
->priv
.eswitch
, rep
->vport
);
59 ibdev
->num_ports
= num_ports
;
61 if (!__mlx5_ib_add(ibdev
, profile
))
64 rep
->rep_data
[REP_IB
].priv
= ibdev
;
70 mlx5_ib_vport_rep_unload(struct mlx5_eswitch_rep
*rep
)
72 struct mlx5_ib_dev
*dev
= mlx5_ib_rep_to_dev(rep
);
73 struct mlx5_ib_port
*port
;
75 port
= &dev
->port
[rep
->vport_index
];
76 write_lock(&port
->roce
.netdev_lock
);
77 port
->roce
.netdev
= NULL
;
78 write_unlock(&port
->roce
.netdev_lock
);
79 rep
->rep_data
[REP_IB
].priv
= NULL
;
82 if (rep
->vport
== MLX5_VPORT_UPLINK
)
83 __mlx5_ib_remove(dev
, dev
->profile
, MLX5_IB_STAGE_MAX
);
86 static void *mlx5_ib_vport_get_proto_dev(struct mlx5_eswitch_rep
*rep
)
88 return mlx5_ib_rep_to_dev(rep
);
91 static const struct mlx5_eswitch_rep_ops rep_ops
= {
92 .load
= mlx5_ib_vport_rep_load
,
93 .unload
= mlx5_ib_vport_rep_unload
,
94 .get_proto_dev
= mlx5_ib_vport_get_proto_dev
,
97 void mlx5_ib_register_vport_reps(struct mlx5_core_dev
*mdev
)
99 struct mlx5_eswitch
*esw
= mdev
->priv
.eswitch
;
101 mlx5_eswitch_register_vport_reps(esw
, &rep_ops
, REP_IB
);
104 void mlx5_ib_unregister_vport_reps(struct mlx5_core_dev
*mdev
)
106 struct mlx5_eswitch
*esw
= mdev
->priv
.eswitch
;
108 mlx5_eswitch_unregister_vport_reps(esw
, REP_IB
);
111 u8
mlx5_ib_eswitch_mode(struct mlx5_eswitch
*esw
)
113 return mlx5_eswitch_mode(esw
);
116 struct mlx5_ib_dev
*mlx5_ib_get_rep_ibdev(struct mlx5_eswitch
*esw
,
119 return mlx5_eswitch_get_proto_dev(esw
, vport_num
, REP_IB
);
122 struct net_device
*mlx5_ib_get_rep_netdev(struct mlx5_eswitch
*esw
,
125 return mlx5_eswitch_get_proto_dev(esw
, vport_num
, REP_ETH
);
128 struct mlx5_ib_dev
*mlx5_ib_get_uplink_ibdev(struct mlx5_eswitch
*esw
)
130 return mlx5_eswitch_uplink_get_proto_dev(esw
, REP_IB
);
133 struct mlx5_eswitch_rep
*mlx5_ib_vport_rep(struct mlx5_eswitch
*esw
,
136 return mlx5_eswitch_vport_rep(esw
, vport_num
);
139 struct mlx5_flow_handle
*create_flow_rule_vport_sq(struct mlx5_ib_dev
*dev
,
140 struct mlx5_ib_sq
*sq
,
143 struct mlx5_eswitch
*esw
= dev
->mdev
->priv
.eswitch
;
144 struct mlx5_eswitch_rep
*rep
;
146 if (!dev
->is_rep
|| !port
)
149 if (!dev
->port
[port
- 1].rep
)
150 return ERR_PTR(-EINVAL
);
152 rep
= dev
->port
[port
- 1].rep
;
154 return mlx5_eswitch_add_send_to_vport_rule(esw
, rep
->vport
,