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_eswitch_uplink_get_proto_dev(dev
->priv
.eswitch
, REP_IB
);
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
;
38 if (rep
->vport
== MLX5_VPORT_UPLINK
)
39 profile
= &raw_eth_profile
;
41 return mlx5_ib_set_vport_rep(dev
, rep
);
43 ibdev
= ib_alloc_device(mlx5_ib_dev
, ib_dev
);
47 ibdev
->port
= kcalloc(num_ports
, sizeof(*ibdev
->port
),
55 vport_index
= rep
->vport_index
;
56 ibdev
->port
[vport_index
].rep
= rep
;
57 ibdev
->port
[vport_index
].roce
.netdev
=
58 mlx5_ib_get_rep_netdev(dev
->priv
.eswitch
, rep
->vport
);
60 ibdev
->num_ports
= num_ports
;
62 ret
= __mlx5_ib_add(ibdev
, profile
);
66 rep
->rep_data
[REP_IB
].priv
= ibdev
;
73 ib_dealloc_device(&ibdev
->ib_dev
);
77 static void *mlx5_ib_rep_to_dev(struct mlx5_eswitch_rep
*rep
)
79 return rep
->rep_data
[REP_IB
].priv
;
83 mlx5_ib_vport_rep_unload(struct mlx5_eswitch_rep
*rep
)
85 struct mlx5_ib_dev
*dev
= mlx5_ib_rep_to_dev(rep
);
86 struct mlx5_ib_port
*port
;
88 port
= &dev
->port
[rep
->vport_index
];
89 write_lock(&port
->roce
.netdev_lock
);
90 port
->roce
.netdev
= NULL
;
91 write_unlock(&port
->roce
.netdev_lock
);
92 rep
->rep_data
[REP_IB
].priv
= NULL
;
95 if (rep
->vport
== MLX5_VPORT_UPLINK
)
96 __mlx5_ib_remove(dev
, dev
->profile
, MLX5_IB_STAGE_MAX
);
99 static const struct mlx5_eswitch_rep_ops rep_ops
= {
100 .load
= mlx5_ib_vport_rep_load
,
101 .unload
= mlx5_ib_vport_rep_unload
,
102 .get_proto_dev
= mlx5_ib_rep_to_dev
,
105 struct net_device
*mlx5_ib_get_rep_netdev(struct mlx5_eswitch
*esw
,
108 return mlx5_eswitch_get_proto_dev(esw
, vport_num
, REP_ETH
);
111 struct mlx5_flow_handle
*create_flow_rule_vport_sq(struct mlx5_ib_dev
*dev
,
112 struct mlx5_ib_sq
*sq
,
115 struct mlx5_eswitch
*esw
= dev
->mdev
->priv
.eswitch
;
116 struct mlx5_eswitch_rep
*rep
;
118 if (!dev
->is_rep
|| !port
)
121 if (!dev
->port
[port
- 1].rep
)
122 return ERR_PTR(-EINVAL
);
124 rep
= dev
->port
[port
- 1].rep
;
126 return mlx5_eswitch_add_send_to_vport_rule(esw
, rep
->vport
,
130 static int mlx5r_rep_probe(struct auxiliary_device
*adev
,
131 const struct auxiliary_device_id
*id
)
133 struct mlx5_adev
*idev
= container_of(adev
, struct mlx5_adev
, adev
);
134 struct mlx5_core_dev
*mdev
= idev
->mdev
;
135 struct mlx5_eswitch
*esw
;
137 esw
= mdev
->priv
.eswitch
;
138 mlx5_eswitch_register_vport_reps(esw
, &rep_ops
, REP_IB
);
142 static void mlx5r_rep_remove(struct auxiliary_device
*adev
)
144 struct mlx5_adev
*idev
= container_of(adev
, struct mlx5_adev
, adev
);
145 struct mlx5_core_dev
*mdev
= idev
->mdev
;
146 struct mlx5_eswitch
*esw
;
148 esw
= mdev
->priv
.eswitch
;
149 mlx5_eswitch_unregister_vport_reps(esw
, REP_IB
);
152 static const struct auxiliary_device_id mlx5r_rep_id_table
[] = {
153 { .name
= MLX5_ADEV_NAME
".rdma-rep", },
157 MODULE_DEVICE_TABLE(auxiliary
, mlx5r_rep_id_table
);
159 static struct auxiliary_driver mlx5r_rep_driver
= {
161 .probe
= mlx5r_rep_probe
,
162 .remove
= mlx5r_rep_remove
,
163 .id_table
= mlx5r_rep_id_table
,
166 int mlx5r_rep_init(void)
168 return auxiliary_driver_register(&mlx5r_rep_driver
);
171 void mlx5r_rep_cleanup(void)
173 auxiliary_driver_unregister(&mlx5r_rep_driver
);