0439203fc7d9df519bf52ac69aec5834253e7546
[platform/kernel/linux-starfive.git] / drivers / net / ethernet / mellanox / mlx5 / core / en_rep.c
1 /*
2  * Copyright (c) 2016, Mellanox Technologies. All rights reserved.
3  *
4  * This software is available to you under a choice of one of two
5  * licenses.  You may choose to be licensed under the terms of the GNU
6  * General Public License (GPL) Version 2, available from the file
7  * COPYING in the main directory of this source tree, or the
8  * OpenIB.org BSD license below:
9  *
10  *     Redistribution and use in source and binary forms, with or
11  *     without modification, are permitted provided that the following
12  *     conditions are met:
13  *
14  *      - Redistributions of source code must retain the above
15  *        copyright notice, this list of conditions and the following
16  *        disclaimer.
17  *
18  *      - Redistributions in binary form must reproduce the above
19  *        copyright notice, this list of conditions and the following
20  *        disclaimer in the documentation and/or other materials
21  *        provided with the distribution.
22  *
23  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
24  * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
25  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
26  * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
27  * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
28  * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
29  * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
30  * SOFTWARE.
31  */
32
33 #include <linux/mlx5/fs.h>
34 #include <net/switchdev.h>
35 #include <net/pkt_cls.h>
36 #include <net/act_api.h>
37 #include <net/devlink.h>
38 #include <net/ipv6_stubs.h>
39
40 #include "eswitch.h"
41 #include "en.h"
42 #include "en_rep.h"
43 #include "en/params.h"
44 #include "en/txrx.h"
45 #include "en_tc.h"
46 #include "en/rep/tc.h"
47 #include "en/rep/neigh.h"
48 #include "en/rep/bridge.h"
49 #include "en/devlink.h"
50 #include "fs_core.h"
51 #include "lib/mlx5.h"
52 #include "lib/devcom.h"
53 #define CREATE_TRACE_POINTS
54 #include "diag/en_rep_tracepoint.h"
55 #include "en_accel/ipsec.h"
56
57 #define MLX5E_REP_PARAMS_DEF_LOG_SQ_SIZE \
58         max(0x7, MLX5E_PARAMS_MINIMUM_LOG_SQ_SIZE)
59 #define MLX5E_REP_PARAMS_DEF_NUM_CHANNELS 1
60
61 static const char mlx5e_rep_driver_name[] = "mlx5e_rep";
62
63 static void mlx5e_rep_get_drvinfo(struct net_device *dev,
64                                   struct ethtool_drvinfo *drvinfo)
65 {
66         struct mlx5e_priv *priv = netdev_priv(dev);
67         struct mlx5_core_dev *mdev = priv->mdev;
68
69         strlcpy(drvinfo->driver, mlx5e_rep_driver_name,
70                 sizeof(drvinfo->driver));
71         snprintf(drvinfo->fw_version, sizeof(drvinfo->fw_version),
72                  "%d.%d.%04d (%.16s)",
73                  fw_rev_maj(mdev), fw_rev_min(mdev),
74                  fw_rev_sub(mdev), mdev->board_id);
75 }
76
77 static const struct counter_desc sw_rep_stats_desc[] = {
78         { MLX5E_DECLARE_STAT(struct mlx5e_sw_stats, rx_packets) },
79         { MLX5E_DECLARE_STAT(struct mlx5e_sw_stats, rx_bytes) },
80         { MLX5E_DECLARE_STAT(struct mlx5e_sw_stats, tx_packets) },
81         { MLX5E_DECLARE_STAT(struct mlx5e_sw_stats, tx_bytes) },
82 };
83
84 struct vport_stats {
85         u64 vport_rx_packets;
86         u64 vport_tx_packets;
87         u64 vport_rx_bytes;
88         u64 vport_tx_bytes;
89 };
90
91 static const struct counter_desc vport_rep_stats_desc[] = {
92         { MLX5E_DECLARE_STAT(struct vport_stats, vport_rx_packets) },
93         { MLX5E_DECLARE_STAT(struct vport_stats, vport_rx_bytes) },
94         { MLX5E_DECLARE_STAT(struct vport_stats, vport_tx_packets) },
95         { MLX5E_DECLARE_STAT(struct vport_stats, vport_tx_bytes) },
96 };
97
98 #define NUM_VPORT_REP_SW_COUNTERS ARRAY_SIZE(sw_rep_stats_desc)
99 #define NUM_VPORT_REP_HW_COUNTERS ARRAY_SIZE(vport_rep_stats_desc)
100
101 static MLX5E_DECLARE_STATS_GRP_OP_NUM_STATS(sw_rep)
102 {
103         return NUM_VPORT_REP_SW_COUNTERS;
104 }
105
106 static MLX5E_DECLARE_STATS_GRP_OP_FILL_STRS(sw_rep)
107 {
108         int i;
109
110         for (i = 0; i < NUM_VPORT_REP_SW_COUNTERS; i++)
111                 strcpy(data + (idx++) * ETH_GSTRING_LEN,
112                        sw_rep_stats_desc[i].format);
113         return idx;
114 }
115
116 static MLX5E_DECLARE_STATS_GRP_OP_FILL_STATS(sw_rep)
117 {
118         int i;
119
120         for (i = 0; i < NUM_VPORT_REP_SW_COUNTERS; i++)
121                 data[idx++] = MLX5E_READ_CTR64_CPU(&priv->stats.sw,
122                                                    sw_rep_stats_desc, i);
123         return idx;
124 }
125
126 static MLX5E_DECLARE_STATS_GRP_OP_UPDATE_STATS(sw_rep)
127 {
128         struct mlx5e_sw_stats *s = &priv->stats.sw;
129         struct rtnl_link_stats64 stats64 = {};
130
131         memset(s, 0, sizeof(*s));
132         mlx5e_fold_sw_stats64(priv, &stats64);
133
134         s->rx_packets = stats64.rx_packets;
135         s->rx_bytes   = stats64.rx_bytes;
136         s->tx_packets = stats64.tx_packets;
137         s->tx_bytes   = stats64.tx_bytes;
138         s->tx_queue_dropped = stats64.tx_dropped;
139 }
140
141 static MLX5E_DECLARE_STATS_GRP_OP_NUM_STATS(vport_rep)
142 {
143         return NUM_VPORT_REP_HW_COUNTERS;
144 }
145
146 static MLX5E_DECLARE_STATS_GRP_OP_FILL_STRS(vport_rep)
147 {
148         int i;
149
150         for (i = 0; i < NUM_VPORT_REP_HW_COUNTERS; i++)
151                 strcpy(data + (idx++) * ETH_GSTRING_LEN, vport_rep_stats_desc[i].format);
152         return idx;
153 }
154
155 static MLX5E_DECLARE_STATS_GRP_OP_FILL_STATS(vport_rep)
156 {
157         int i;
158
159         for (i = 0; i < NUM_VPORT_REP_HW_COUNTERS; i++)
160                 data[idx++] = MLX5E_READ_CTR64_CPU(&priv->stats.vf_vport,
161                                                    vport_rep_stats_desc, i);
162         return idx;
163 }
164
165 static MLX5E_DECLARE_STATS_GRP_OP_UPDATE_STATS(vport_rep)
166 {
167         struct mlx5_eswitch *esw = priv->mdev->priv.eswitch;
168         struct mlx5e_rep_priv *rpriv = priv->ppriv;
169         struct mlx5_eswitch_rep *rep = rpriv->rep;
170         struct rtnl_link_stats64 *vport_stats;
171         struct ifla_vf_stats vf_stats;
172         int err;
173
174         err = mlx5_eswitch_get_vport_stats(esw, rep->vport, &vf_stats);
175         if (err) {
176                 netdev_warn(priv->netdev, "vport %d error %d reading stats\n",
177                             rep->vport, err);
178                 return;
179         }
180
181         vport_stats = &priv->stats.vf_vport;
182         /* flip tx/rx as we are reporting the counters for the switch vport */
183         vport_stats->rx_packets = vf_stats.tx_packets;
184         vport_stats->rx_bytes   = vf_stats.tx_bytes;
185         vport_stats->tx_packets = vf_stats.rx_packets;
186         vport_stats->tx_bytes   = vf_stats.rx_bytes;
187 }
188
189 static void mlx5e_rep_get_strings(struct net_device *dev,
190                                   u32 stringset, uint8_t *data)
191 {
192         struct mlx5e_priv *priv = netdev_priv(dev);
193
194         switch (stringset) {
195         case ETH_SS_STATS:
196                 mlx5e_stats_fill_strings(priv, data);
197                 break;
198         }
199 }
200
201 static void mlx5e_rep_get_ethtool_stats(struct net_device *dev,
202                                         struct ethtool_stats *stats, u64 *data)
203 {
204         struct mlx5e_priv *priv = netdev_priv(dev);
205
206         mlx5e_ethtool_get_ethtool_stats(priv, stats, data);
207 }
208
209 static int mlx5e_rep_get_sset_count(struct net_device *dev, int sset)
210 {
211         struct mlx5e_priv *priv = netdev_priv(dev);
212
213         switch (sset) {
214         case ETH_SS_STATS:
215                 return mlx5e_stats_total_num(priv);
216         default:
217                 return -EOPNOTSUPP;
218         }
219 }
220
221 static void mlx5e_rep_get_ringparam(struct net_device *dev,
222                                 struct ethtool_ringparam *param)
223 {
224         struct mlx5e_priv *priv = netdev_priv(dev);
225
226         mlx5e_ethtool_get_ringparam(priv, param);
227 }
228
229 static int mlx5e_rep_set_ringparam(struct net_device *dev,
230                                struct ethtool_ringparam *param)
231 {
232         struct mlx5e_priv *priv = netdev_priv(dev);
233
234         return mlx5e_ethtool_set_ringparam(priv, param);
235 }
236
237 static void mlx5e_rep_get_channels(struct net_device *dev,
238                                    struct ethtool_channels *ch)
239 {
240         struct mlx5e_priv *priv = netdev_priv(dev);
241
242         mlx5e_ethtool_get_channels(priv, ch);
243 }
244
245 static int mlx5e_rep_set_channels(struct net_device *dev,
246                                   struct ethtool_channels *ch)
247 {
248         struct mlx5e_priv *priv = netdev_priv(dev);
249
250         return mlx5e_ethtool_set_channels(priv, ch);
251 }
252
253 static int mlx5e_rep_get_coalesce(struct net_device *netdev,
254                                   struct ethtool_coalesce *coal,
255                                   struct kernel_ethtool_coalesce *kernel_coal,
256                                   struct netlink_ext_ack *extack)
257 {
258         struct mlx5e_priv *priv = netdev_priv(netdev);
259
260         return mlx5e_ethtool_get_coalesce(priv, coal);
261 }
262
263 static int mlx5e_rep_set_coalesce(struct net_device *netdev,
264                                   struct ethtool_coalesce *coal,
265                                   struct kernel_ethtool_coalesce *kernel_coal,
266                                   struct netlink_ext_ack *extack)
267 {
268         struct mlx5e_priv *priv = netdev_priv(netdev);
269
270         return mlx5e_ethtool_set_coalesce(priv, coal);
271 }
272
273 static u32 mlx5e_rep_get_rxfh_key_size(struct net_device *netdev)
274 {
275         struct mlx5e_priv *priv = netdev_priv(netdev);
276
277         return mlx5e_ethtool_get_rxfh_key_size(priv);
278 }
279
280 static u32 mlx5e_rep_get_rxfh_indir_size(struct net_device *netdev)
281 {
282         struct mlx5e_priv *priv = netdev_priv(netdev);
283
284         return mlx5e_ethtool_get_rxfh_indir_size(priv);
285 }
286
287 static const struct ethtool_ops mlx5e_rep_ethtool_ops = {
288         .supported_coalesce_params = ETHTOOL_COALESCE_USECS |
289                                      ETHTOOL_COALESCE_MAX_FRAMES |
290                                      ETHTOOL_COALESCE_USE_ADAPTIVE,
291         .get_drvinfo       = mlx5e_rep_get_drvinfo,
292         .get_link          = ethtool_op_get_link,
293         .get_strings       = mlx5e_rep_get_strings,
294         .get_sset_count    = mlx5e_rep_get_sset_count,
295         .get_ethtool_stats = mlx5e_rep_get_ethtool_stats,
296         .get_ringparam     = mlx5e_rep_get_ringparam,
297         .set_ringparam     = mlx5e_rep_set_ringparam,
298         .get_channels      = mlx5e_rep_get_channels,
299         .set_channels      = mlx5e_rep_set_channels,
300         .get_coalesce      = mlx5e_rep_get_coalesce,
301         .set_coalesce      = mlx5e_rep_set_coalesce,
302         .get_rxfh_key_size   = mlx5e_rep_get_rxfh_key_size,
303         .get_rxfh_indir_size = mlx5e_rep_get_rxfh_indir_size,
304 };
305
306 static void mlx5e_sqs2vport_stop(struct mlx5_eswitch *esw,
307                                  struct mlx5_eswitch_rep *rep)
308 {
309         struct mlx5e_rep_sq *rep_sq, *tmp;
310         struct mlx5e_rep_priv *rpriv;
311
312         if (esw->mode != MLX5_ESWITCH_OFFLOADS)
313                 return;
314
315         rpriv = mlx5e_rep_to_rep_priv(rep);
316         list_for_each_entry_safe(rep_sq, tmp, &rpriv->vport_sqs_list, list) {
317                 mlx5_eswitch_del_send_to_vport_rule(rep_sq->send_to_vport_rule);
318                 if (rep_sq->send_to_vport_rule_peer)
319                         mlx5_eswitch_del_send_to_vport_rule(rep_sq->send_to_vport_rule_peer);
320                 list_del(&rep_sq->list);
321                 kfree(rep_sq);
322         }
323 }
324
325 static int mlx5e_sqs2vport_start(struct mlx5_eswitch *esw,
326                                  struct mlx5_eswitch_rep *rep,
327                                  u32 *sqns_array, int sqns_num)
328 {
329         struct mlx5_eswitch *peer_esw = NULL;
330         struct mlx5_flow_handle *flow_rule;
331         struct mlx5e_rep_priv *rpriv;
332         struct mlx5e_rep_sq *rep_sq;
333         int err;
334         int i;
335
336         if (esw->mode != MLX5_ESWITCH_OFFLOADS)
337                 return 0;
338
339         rpriv = mlx5e_rep_to_rep_priv(rep);
340         if (mlx5_devcom_is_paired(esw->dev->priv.devcom, MLX5_DEVCOM_ESW_OFFLOADS))
341                 peer_esw = mlx5_devcom_get_peer_data(esw->dev->priv.devcom,
342                                                      MLX5_DEVCOM_ESW_OFFLOADS);
343
344         for (i = 0; i < sqns_num; i++) {
345                 rep_sq = kzalloc(sizeof(*rep_sq), GFP_KERNEL);
346                 if (!rep_sq) {
347                         err = -ENOMEM;
348                         goto out_err;
349                 }
350
351                 /* Add re-inject rule to the PF/representor sqs */
352                 flow_rule = mlx5_eswitch_add_send_to_vport_rule(esw, esw, rep,
353                                                                 sqns_array[i]);
354                 if (IS_ERR(flow_rule)) {
355                         err = PTR_ERR(flow_rule);
356                         kfree(rep_sq);
357                         goto out_err;
358                 }
359                 rep_sq->send_to_vport_rule = flow_rule;
360                 rep_sq->sqn = sqns_array[i];
361
362                 if (peer_esw) {
363                         flow_rule = mlx5_eswitch_add_send_to_vport_rule(peer_esw, esw,
364                                                                         rep, sqns_array[i]);
365                         if (IS_ERR(flow_rule)) {
366                                 err = PTR_ERR(flow_rule);
367                                 mlx5_eswitch_del_send_to_vport_rule(rep_sq->send_to_vport_rule);
368                                 kfree(rep_sq);
369                                 goto out_err;
370                         }
371                         rep_sq->send_to_vport_rule_peer = flow_rule;
372                 }
373
374                 list_add(&rep_sq->list, &rpriv->vport_sqs_list);
375         }
376
377         if (peer_esw)
378                 mlx5_devcom_release_peer_data(esw->dev->priv.devcom, MLX5_DEVCOM_ESW_OFFLOADS);
379
380         return 0;
381
382 out_err:
383         mlx5e_sqs2vport_stop(esw, rep);
384
385         if (peer_esw)
386                 mlx5_devcom_release_peer_data(esw->dev->priv.devcom, MLX5_DEVCOM_ESW_OFFLOADS);
387
388         return err;
389 }
390
391 int mlx5e_add_sqs_fwd_rules(struct mlx5e_priv *priv)
392 {
393         struct mlx5_eswitch *esw = priv->mdev->priv.eswitch;
394         struct mlx5e_rep_priv *rpriv = priv->ppriv;
395         struct mlx5_eswitch_rep *rep = rpriv->rep;
396         struct mlx5e_channel *c;
397         int n, tc, num_sqs = 0;
398         int err = -ENOMEM;
399         u32 *sqs;
400
401         sqs = kcalloc(priv->channels.num * mlx5e_get_dcb_num_tc(&priv->channels.params),
402                       sizeof(*sqs), GFP_KERNEL);
403         if (!sqs)
404                 goto out;
405
406         for (n = 0; n < priv->channels.num; n++) {
407                 c = priv->channels.c[n];
408                 for (tc = 0; tc < c->num_tc; tc++)
409                         sqs[num_sqs++] = c->sq[tc].sqn;
410         }
411
412         err = mlx5e_sqs2vport_start(esw, rep, sqs, num_sqs);
413         kfree(sqs);
414
415 out:
416         if (err)
417                 netdev_warn(priv->netdev, "Failed to add SQs FWD rules %d\n", err);
418         return err;
419 }
420
421 void mlx5e_remove_sqs_fwd_rules(struct mlx5e_priv *priv)
422 {
423         struct mlx5_eswitch *esw = priv->mdev->priv.eswitch;
424         struct mlx5e_rep_priv *rpriv = priv->ppriv;
425         struct mlx5_eswitch_rep *rep = rpriv->rep;
426
427         mlx5e_sqs2vport_stop(esw, rep);
428 }
429
430 static int mlx5e_rep_open(struct net_device *dev)
431 {
432         struct mlx5e_priv *priv = netdev_priv(dev);
433         struct mlx5e_rep_priv *rpriv = priv->ppriv;
434         struct mlx5_eswitch_rep *rep = rpriv->rep;
435         int err;
436
437         mutex_lock(&priv->state_lock);
438         err = mlx5e_open_locked(dev);
439         if (err)
440                 goto unlock;
441
442         if (!mlx5_modify_vport_admin_state(priv->mdev,
443                                            MLX5_VPORT_STATE_OP_MOD_ESW_VPORT,
444                                            rep->vport, 1,
445                                            MLX5_VPORT_ADMIN_STATE_UP))
446                 netif_carrier_on(dev);
447
448 unlock:
449         mutex_unlock(&priv->state_lock);
450         return err;
451 }
452
453 static int mlx5e_rep_close(struct net_device *dev)
454 {
455         struct mlx5e_priv *priv = netdev_priv(dev);
456         struct mlx5e_rep_priv *rpriv = priv->ppriv;
457         struct mlx5_eswitch_rep *rep = rpriv->rep;
458         int ret;
459
460         mutex_lock(&priv->state_lock);
461         mlx5_modify_vport_admin_state(priv->mdev,
462                                       MLX5_VPORT_STATE_OP_MOD_ESW_VPORT,
463                                       rep->vport, 1,
464                                       MLX5_VPORT_ADMIN_STATE_DOWN);
465         ret = mlx5e_close_locked(dev);
466         mutex_unlock(&priv->state_lock);
467         return ret;
468 }
469
470 bool mlx5e_is_uplink_rep(struct mlx5e_priv *priv)
471 {
472         struct mlx5e_rep_priv *rpriv = priv->ppriv;
473         struct mlx5_eswitch_rep *rep;
474
475         if (!MLX5_ESWITCH_MANAGER(priv->mdev))
476                 return false;
477
478         if (!rpriv) /* non vport rep mlx5e instances don't use this field */
479                 return false;
480
481         rep = rpriv->rep;
482         return (rep->vport == MLX5_VPORT_UPLINK);
483 }
484
485 bool mlx5e_rep_has_offload_stats(const struct net_device *dev, int attr_id)
486 {
487         switch (attr_id) {
488         case IFLA_OFFLOAD_XSTATS_CPU_HIT:
489                         return true;
490         }
491
492         return false;
493 }
494
495 static int
496 mlx5e_get_sw_stats64(const struct net_device *dev,
497                      struct rtnl_link_stats64 *stats)
498 {
499         struct mlx5e_priv *priv = netdev_priv(dev);
500
501         mlx5e_fold_sw_stats64(priv, stats);
502         return 0;
503 }
504
505 int mlx5e_rep_get_offload_stats(int attr_id, const struct net_device *dev,
506                                 void *sp)
507 {
508         switch (attr_id) {
509         case IFLA_OFFLOAD_XSTATS_CPU_HIT:
510                 return mlx5e_get_sw_stats64(dev, sp);
511         }
512
513         return -EINVAL;
514 }
515
516 static void
517 mlx5e_rep_get_stats(struct net_device *dev, struct rtnl_link_stats64 *stats)
518 {
519         struct mlx5e_priv *priv = netdev_priv(dev);
520
521         /* update HW stats in background for next time */
522         mlx5e_queue_update_stats(priv);
523         memcpy(stats, &priv->stats.vf_vport, sizeof(*stats));
524 }
525
526 static int mlx5e_rep_change_mtu(struct net_device *netdev, int new_mtu)
527 {
528         return mlx5e_change_mtu(netdev, new_mtu, NULL);
529 }
530
531 static struct devlink_port *mlx5e_rep_get_devlink_port(struct net_device *netdev)
532 {
533         struct mlx5e_priv *priv = netdev_priv(netdev);
534         struct mlx5e_rep_priv *rpriv = priv->ppriv;
535         struct mlx5_core_dev *dev = priv->mdev;
536
537         return mlx5_esw_offloads_devlink_port(dev->priv.eswitch, rpriv->rep->vport);
538 }
539
540 static int mlx5e_rep_change_carrier(struct net_device *dev, bool new_carrier)
541 {
542         struct mlx5e_priv *priv = netdev_priv(dev);
543         struct mlx5e_rep_priv *rpriv = priv->ppriv;
544         struct mlx5_eswitch_rep *rep = rpriv->rep;
545         int err;
546
547         if (new_carrier) {
548                 err = mlx5_modify_vport_admin_state(priv->mdev, MLX5_VPORT_STATE_OP_MOD_ESW_VPORT,
549                                                     rep->vport, 1, MLX5_VPORT_ADMIN_STATE_UP);
550                 if (err)
551                         return err;
552                 netif_carrier_on(dev);
553         } else {
554                 err = mlx5_modify_vport_admin_state(priv->mdev, MLX5_VPORT_STATE_OP_MOD_ESW_VPORT,
555                                                     rep->vport, 1, MLX5_VPORT_ADMIN_STATE_DOWN);
556                 if (err)
557                         return err;
558                 netif_carrier_off(dev);
559         }
560         return 0;
561 }
562
563 static const struct net_device_ops mlx5e_netdev_ops_rep = {
564         .ndo_open                = mlx5e_rep_open,
565         .ndo_stop                = mlx5e_rep_close,
566         .ndo_start_xmit          = mlx5e_xmit,
567         .ndo_setup_tc            = mlx5e_rep_setup_tc,
568         .ndo_get_devlink_port    = mlx5e_rep_get_devlink_port,
569         .ndo_get_stats64         = mlx5e_rep_get_stats,
570         .ndo_has_offload_stats   = mlx5e_rep_has_offload_stats,
571         .ndo_get_offload_stats   = mlx5e_rep_get_offload_stats,
572         .ndo_change_mtu          = mlx5e_rep_change_mtu,
573         .ndo_change_carrier      = mlx5e_rep_change_carrier,
574 };
575
576 bool mlx5e_eswitch_uplink_rep(const struct net_device *netdev)
577 {
578         return netdev->netdev_ops == &mlx5e_netdev_ops &&
579                mlx5e_is_uplink_rep(netdev_priv(netdev));
580 }
581
582 bool mlx5e_eswitch_vf_rep(const struct net_device *netdev)
583 {
584         return netdev->netdev_ops == &mlx5e_netdev_ops_rep;
585 }
586
587 static void mlx5e_build_rep_params(struct net_device *netdev)
588 {
589         struct mlx5e_priv *priv = netdev_priv(netdev);
590         struct mlx5e_rep_priv *rpriv = priv->ppriv;
591         struct mlx5_eswitch_rep *rep = rpriv->rep;
592         struct mlx5_core_dev *mdev = priv->mdev;
593         struct mlx5e_params *params;
594
595         u8 cq_period_mode = MLX5_CAP_GEN(mdev, cq_period_start_from_cqe) ?
596                                          MLX5_CQ_PERIOD_MODE_START_FROM_CQE :
597                                          MLX5_CQ_PERIOD_MODE_START_FROM_EQE;
598
599         params = &priv->channels.params;
600
601         params->num_channels = MLX5E_REP_PARAMS_DEF_NUM_CHANNELS;
602         params->hard_mtu    = MLX5E_ETH_HARD_MTU;
603         params->sw_mtu      = netdev->mtu;
604
605         /* SQ */
606         if (rep->vport == MLX5_VPORT_UPLINK)
607                 params->log_sq_size = MLX5E_PARAMS_DEFAULT_LOG_SQ_SIZE;
608         else
609                 params->log_sq_size = MLX5E_REP_PARAMS_DEF_LOG_SQ_SIZE;
610
611         /* RQ */
612         mlx5e_build_rq_params(mdev, params);
613
614         /* CQ moderation params */
615         params->rx_dim_enabled = MLX5_CAP_GEN(mdev, cq_moderation);
616         mlx5e_set_rx_cq_mode_params(params, cq_period_mode);
617
618         params->mqprio.num_tc       = 1;
619         params->tunneled_offload_en = false;
620
621         mlx5_query_min_inline(mdev, &params->tx_min_inline_mode);
622 }
623
624 static void mlx5e_build_rep_netdev(struct net_device *netdev,
625                                    struct mlx5_core_dev *mdev)
626 {
627         SET_NETDEV_DEV(netdev, mdev->device);
628         netdev->netdev_ops = &mlx5e_netdev_ops_rep;
629         eth_hw_addr_random(netdev);
630         netdev->ethtool_ops = &mlx5e_rep_ethtool_ops;
631
632         netdev->watchdog_timeo    = 15 * HZ;
633
634 #if IS_ENABLED(CONFIG_MLX5_CLS_ACT)
635         netdev->hw_features    |= NETIF_F_HW_TC;
636 #endif
637         netdev->hw_features    |= NETIF_F_SG;
638         netdev->hw_features    |= NETIF_F_IP_CSUM;
639         netdev->hw_features    |= NETIF_F_IPV6_CSUM;
640         netdev->hw_features    |= NETIF_F_GRO;
641         netdev->hw_features    |= NETIF_F_TSO;
642         netdev->hw_features    |= NETIF_F_TSO6;
643         netdev->hw_features    |= NETIF_F_RXCSUM;
644
645         netdev->features |= netdev->hw_features;
646         netdev->features |= NETIF_F_NETNS_LOCAL;
647 }
648
649 static int mlx5e_init_rep(struct mlx5_core_dev *mdev,
650                           struct net_device *netdev)
651 {
652         struct mlx5e_priv *priv = netdev_priv(netdev);
653
654         mlx5e_build_rep_params(netdev);
655         mlx5e_timestamp_init(priv);
656
657         return 0;
658 }
659
660 static int mlx5e_init_ul_rep(struct mlx5_core_dev *mdev,
661                              struct net_device *netdev)
662 {
663         struct mlx5e_priv *priv = netdev_priv(netdev);
664         int err;
665
666         err = mlx5e_ipsec_init(priv);
667         if (err)
668                 mlx5_core_err(mdev, "Uplink rep IPsec initialization failed, %d\n", err);
669
670         mlx5e_vxlan_set_netdev_info(priv);
671         return mlx5e_init_rep(mdev, netdev);
672 }
673
674 static void mlx5e_cleanup_rep(struct mlx5e_priv *priv)
675 {
676         mlx5e_ipsec_cleanup(priv);
677 }
678
679 static int mlx5e_create_rep_ttc_table(struct mlx5e_priv *priv)
680 {
681         struct mlx5e_rep_priv *rpriv = priv->ppriv;
682         struct mlx5_eswitch_rep *rep = rpriv->rep;
683         struct ttc_params ttc_params = {};
684         int err;
685
686         priv->fs.ns = mlx5_get_flow_namespace(priv->mdev,
687                                               MLX5_FLOW_NAMESPACE_KERNEL);
688
689         /* The inner_ttc in the ttc params is intentionally not set */
690         mlx5e_set_ttc_params(priv, &ttc_params, false);
691
692         if (rep->vport != MLX5_VPORT_UPLINK)
693                 /* To give uplik rep TTC a lower level for chaining from root ft */
694                 ttc_params.ft_attr.level = MLX5E_TTC_FT_LEVEL + 1;
695
696         priv->fs.ttc = mlx5_create_ttc_table(priv->mdev, &ttc_params);
697         if (IS_ERR(priv->fs.ttc)) {
698                 err = PTR_ERR(priv->fs.ttc);
699                 netdev_err(priv->netdev, "Failed to create rep ttc table, err=%d\n",
700                            err);
701                 return err;
702         }
703         return 0;
704 }
705
706 static int mlx5e_create_rep_root_ft(struct mlx5e_priv *priv)
707 {
708         struct mlx5e_rep_priv *rpriv = priv->ppriv;
709         struct mlx5_eswitch_rep *rep = rpriv->rep;
710         struct mlx5_flow_table_attr ft_attr = {};
711         struct mlx5_flow_namespace *ns;
712         int err = 0;
713
714         if (rep->vport != MLX5_VPORT_UPLINK) {
715                 /* non uplik reps will skip any bypass tables and go directly to
716                  * their own ttc
717                  */
718                 rpriv->root_ft = mlx5_get_ttc_flow_table(priv->fs.ttc);
719                 return 0;
720         }
721
722         /* uplink root ft will be used to auto chain, to ethtool or ttc tables */
723         ns = mlx5_get_flow_namespace(priv->mdev, MLX5_FLOW_NAMESPACE_OFFLOADS);
724         if (!ns) {
725                 netdev_err(priv->netdev, "Failed to get reps offloads namespace\n");
726                 return -EOPNOTSUPP;
727         }
728
729         ft_attr.max_fte = 0; /* Empty table, miss rule will always point to next table */
730         ft_attr.prio = 1;
731         ft_attr.level = 1;
732
733         rpriv->root_ft = mlx5_create_flow_table(ns, &ft_attr);
734         if (IS_ERR(rpriv->root_ft)) {
735                 err = PTR_ERR(rpriv->root_ft);
736                 rpriv->root_ft = NULL;
737         }
738
739         return err;
740 }
741
742 static void mlx5e_destroy_rep_root_ft(struct mlx5e_priv *priv)
743 {
744         struct mlx5e_rep_priv *rpriv = priv->ppriv;
745         struct mlx5_eswitch_rep *rep = rpriv->rep;
746
747         if (rep->vport != MLX5_VPORT_UPLINK)
748                 return;
749         mlx5_destroy_flow_table(rpriv->root_ft);
750 }
751
752 static int mlx5e_create_rep_vport_rx_rule(struct mlx5e_priv *priv)
753 {
754         struct mlx5_eswitch *esw = priv->mdev->priv.eswitch;
755         struct mlx5e_rep_priv *rpriv = priv->ppriv;
756         struct mlx5_eswitch_rep *rep = rpriv->rep;
757         struct mlx5_flow_handle *flow_rule;
758         struct mlx5_flow_destination dest;
759
760         dest.type = MLX5_FLOW_DESTINATION_TYPE_FLOW_TABLE;
761         dest.ft = rpriv->root_ft;
762
763         flow_rule = mlx5_eswitch_create_vport_rx_rule(esw, rep->vport, &dest);
764         if (IS_ERR(flow_rule))
765                 return PTR_ERR(flow_rule);
766         rpriv->vport_rx_rule = flow_rule;
767         return 0;
768 }
769
770 static void rep_vport_rx_rule_destroy(struct mlx5e_priv *priv)
771 {
772         struct mlx5e_rep_priv *rpriv = priv->ppriv;
773
774         if (!rpriv->vport_rx_rule)
775                 return;
776
777         mlx5_del_flow_rules(rpriv->vport_rx_rule);
778         rpriv->vport_rx_rule = NULL;
779 }
780
781 int mlx5e_rep_bond_update(struct mlx5e_priv *priv, bool cleanup)
782 {
783         rep_vport_rx_rule_destroy(priv);
784
785         return cleanup ? 0 : mlx5e_create_rep_vport_rx_rule(priv);
786 }
787
788 static int mlx5e_init_rep_rx(struct mlx5e_priv *priv)
789 {
790         struct mlx5_core_dev *mdev = priv->mdev;
791         struct mlx5e_lro_param lro_param;
792         int err;
793
794         priv->rx_res = mlx5e_rx_res_alloc();
795         if (!priv->rx_res)
796                 return -ENOMEM;
797
798         mlx5e_init_l2_addr(priv);
799
800         err = mlx5e_open_drop_rq(priv, &priv->drop_rq);
801         if (err) {
802                 mlx5_core_err(mdev, "open drop rq failed, %d\n", err);
803                 return err;
804         }
805
806         lro_param = mlx5e_get_lro_param(&priv->channels.params);
807         err = mlx5e_rx_res_init(priv->rx_res, priv->mdev, 0,
808                                 priv->max_nch, priv->drop_rq.rqn, &lro_param,
809                                 priv->channels.params.num_channels);
810         if (err)
811                 goto err_close_drop_rq;
812
813         err = mlx5e_create_rep_ttc_table(priv);
814         if (err)
815                 goto err_destroy_rx_res;
816
817         err = mlx5e_create_rep_root_ft(priv);
818         if (err)
819                 goto err_destroy_ttc_table;
820
821         err = mlx5e_create_rep_vport_rx_rule(priv);
822         if (err)
823                 goto err_destroy_root_ft;
824
825         mlx5e_ethtool_init_steering(priv);
826
827         return 0;
828
829 err_destroy_root_ft:
830         mlx5e_destroy_rep_root_ft(priv);
831 err_destroy_ttc_table:
832         mlx5_destroy_ttc_table(priv->fs.ttc);
833 err_destroy_rx_res:
834         mlx5e_rx_res_destroy(priv->rx_res);
835 err_close_drop_rq:
836         mlx5e_close_drop_rq(&priv->drop_rq);
837         mlx5e_rx_res_free(priv->rx_res);
838         priv->rx_res = NULL;
839         return err;
840 }
841
842 static void mlx5e_cleanup_rep_rx(struct mlx5e_priv *priv)
843 {
844         mlx5e_ethtool_cleanup_steering(priv);
845         rep_vport_rx_rule_destroy(priv);
846         mlx5e_destroy_rep_root_ft(priv);
847         mlx5_destroy_ttc_table(priv->fs.ttc);
848         mlx5e_rx_res_destroy(priv->rx_res);
849         mlx5e_close_drop_rq(&priv->drop_rq);
850         mlx5e_rx_res_free(priv->rx_res);
851         priv->rx_res = NULL;
852 }
853
854 static int mlx5e_init_ul_rep_rx(struct mlx5e_priv *priv)
855 {
856         mlx5e_create_q_counters(priv);
857         return mlx5e_init_rep_rx(priv);
858 }
859
860 static void mlx5e_cleanup_ul_rep_rx(struct mlx5e_priv *priv)
861 {
862         mlx5e_cleanup_rep_rx(priv);
863         mlx5e_destroy_q_counters(priv);
864 }
865
866 static int mlx5e_init_uplink_rep_tx(struct mlx5e_rep_priv *rpriv)
867 {
868         struct mlx5_rep_uplink_priv *uplink_priv;
869         struct net_device *netdev;
870         struct mlx5e_priv *priv;
871         int err;
872
873         netdev = rpriv->netdev;
874         priv = netdev_priv(netdev);
875         uplink_priv = &rpriv->uplink_priv;
876
877         err = mlx5e_rep_tc_init(rpriv);
878         if (err)
879                 return err;
880
881         mlx5_init_port_tun_entropy(&uplink_priv->tun_entropy, priv->mdev);
882
883         mlx5e_rep_bond_init(rpriv);
884         err = mlx5e_rep_tc_netdevice_event_register(rpriv);
885         if (err) {
886                 mlx5_core_err(priv->mdev, "Failed to register netdev notifier, err: %d\n",
887                               err);
888                 goto err_event_reg;
889         }
890
891         return 0;
892
893 err_event_reg:
894         mlx5e_rep_bond_cleanup(rpriv);
895         mlx5e_rep_tc_cleanup(rpriv);
896         return err;
897 }
898
899 static int mlx5e_init_rep_tx(struct mlx5e_priv *priv)
900 {
901         struct mlx5e_rep_priv *rpriv = priv->ppriv;
902         int err;
903
904         err = mlx5e_create_tises(priv);
905         if (err) {
906                 mlx5_core_warn(priv->mdev, "create tises failed, %d\n", err);
907                 return err;
908         }
909
910         if (rpriv->rep->vport == MLX5_VPORT_UPLINK) {
911                 err = mlx5e_init_uplink_rep_tx(rpriv);
912                 if (err)
913                         goto destroy_tises;
914         }
915
916         return 0;
917
918 destroy_tises:
919         mlx5e_destroy_tises(priv);
920         return err;
921 }
922
923 static void mlx5e_cleanup_uplink_rep_tx(struct mlx5e_rep_priv *rpriv)
924 {
925         mlx5e_rep_tc_netdevice_event_unregister(rpriv);
926         mlx5e_rep_bond_cleanup(rpriv);
927         mlx5e_rep_tc_cleanup(rpriv);
928 }
929
930 static void mlx5e_cleanup_rep_tx(struct mlx5e_priv *priv)
931 {
932         struct mlx5e_rep_priv *rpriv = priv->ppriv;
933
934         mlx5e_destroy_tises(priv);
935
936         if (rpriv->rep->vport == MLX5_VPORT_UPLINK)
937                 mlx5e_cleanup_uplink_rep_tx(rpriv);
938 }
939
940 static void mlx5e_rep_enable(struct mlx5e_priv *priv)
941 {
942         struct mlx5e_rep_priv *rpriv = priv->ppriv;
943
944         mlx5e_set_netdev_mtu_boundaries(priv);
945         mlx5e_rep_neigh_init(rpriv);
946 }
947
948 static void mlx5e_rep_disable(struct mlx5e_priv *priv)
949 {
950         struct mlx5e_rep_priv *rpriv = priv->ppriv;
951
952         mlx5e_rep_neigh_cleanup(rpriv);
953 }
954
955 static int mlx5e_update_rep_rx(struct mlx5e_priv *priv)
956 {
957         return 0;
958 }
959
960 static int uplink_rep_async_event(struct notifier_block *nb, unsigned long event, void *data)
961 {
962         struct mlx5e_priv *priv = container_of(nb, struct mlx5e_priv, events_nb);
963
964         if (event == MLX5_EVENT_TYPE_PORT_CHANGE) {
965                 struct mlx5_eqe *eqe = data;
966
967                 switch (eqe->sub_type) {
968                 case MLX5_PORT_CHANGE_SUBTYPE_DOWN:
969                 case MLX5_PORT_CHANGE_SUBTYPE_ACTIVE:
970                         queue_work(priv->wq, &priv->update_carrier_work);
971                         break;
972                 default:
973                         return NOTIFY_DONE;
974                 }
975
976                 return NOTIFY_OK;
977         }
978
979         if (event == MLX5_DEV_EVENT_PORT_AFFINITY)
980                 return mlx5e_rep_tc_event_port_affinity(priv);
981
982         return NOTIFY_DONE;
983 }
984
985 static void mlx5e_uplink_rep_enable(struct mlx5e_priv *priv)
986 {
987         struct mlx5e_rep_priv *rpriv = priv->ppriv;
988         struct net_device *netdev = priv->netdev;
989         struct mlx5_core_dev *mdev = priv->mdev;
990         u16 max_mtu;
991
992         netdev->min_mtu = ETH_MIN_MTU;
993         mlx5_query_port_max_mtu(priv->mdev, &max_mtu, 1);
994         netdev->max_mtu = MLX5E_HW2SW_MTU(&priv->channels.params, max_mtu);
995         mlx5e_set_dev_port_mtu(priv);
996
997         mlx5e_rep_tc_enable(priv);
998
999         if (MLX5_CAP_GEN(mdev, uplink_follow))
1000                 mlx5_modify_vport_admin_state(mdev, MLX5_VPORT_STATE_OP_MOD_UPLINK,
1001                                               0, 0, MLX5_VPORT_ADMIN_STATE_AUTO);
1002         mlx5_lag_add_netdev(mdev, netdev);
1003         priv->events_nb.notifier_call = uplink_rep_async_event;
1004         mlx5_notifier_register(mdev, &priv->events_nb);
1005         mlx5e_dcbnl_initialize(priv);
1006         mlx5e_dcbnl_init_app(priv);
1007         mlx5e_rep_neigh_init(rpriv);
1008         mlx5e_rep_bridge_init(priv);
1009
1010         netdev->wanted_features |= NETIF_F_HW_TC;
1011
1012         rtnl_lock();
1013         if (netif_running(netdev))
1014                 mlx5e_open(netdev);
1015         netif_device_attach(netdev);
1016         rtnl_unlock();
1017 }
1018
1019 static void mlx5e_uplink_rep_disable(struct mlx5e_priv *priv)
1020 {
1021         struct mlx5e_rep_priv *rpriv = priv->ppriv;
1022         struct mlx5_core_dev *mdev = priv->mdev;
1023
1024         rtnl_lock();
1025         if (netif_running(priv->netdev))
1026                 mlx5e_close(priv->netdev);
1027         netif_device_detach(priv->netdev);
1028         rtnl_unlock();
1029
1030         mlx5e_rep_bridge_cleanup(priv);
1031         mlx5e_rep_neigh_cleanup(rpriv);
1032         mlx5e_dcbnl_delete_app(priv);
1033         mlx5_notifier_unregister(mdev, &priv->events_nb);
1034         mlx5e_rep_tc_disable(priv);
1035         mlx5_lag_remove_netdev(mdev, priv->netdev);
1036 }
1037
1038 static MLX5E_DEFINE_STATS_GRP(sw_rep, 0);
1039 static MLX5E_DEFINE_STATS_GRP(vport_rep, MLX5E_NDO_UPDATE_STATS);
1040
1041 /* The stats groups order is opposite to the update_stats() order calls */
1042 static mlx5e_stats_grp_t mlx5e_rep_stats_grps[] = {
1043         &MLX5E_STATS_GRP(sw_rep),
1044         &MLX5E_STATS_GRP(vport_rep),
1045 };
1046
1047 static unsigned int mlx5e_rep_stats_grps_num(struct mlx5e_priv *priv)
1048 {
1049         return ARRAY_SIZE(mlx5e_rep_stats_grps);
1050 }
1051
1052 /* The stats groups order is opposite to the update_stats() order calls */
1053 static mlx5e_stats_grp_t mlx5e_ul_rep_stats_grps[] = {
1054         &MLX5E_STATS_GRP(sw),
1055         &MLX5E_STATS_GRP(qcnt),
1056         &MLX5E_STATS_GRP(vnic_env),
1057         &MLX5E_STATS_GRP(vport),
1058         &MLX5E_STATS_GRP(802_3),
1059         &MLX5E_STATS_GRP(2863),
1060         &MLX5E_STATS_GRP(2819),
1061         &MLX5E_STATS_GRP(phy),
1062         &MLX5E_STATS_GRP(eth_ext),
1063         &MLX5E_STATS_GRP(pcie),
1064         &MLX5E_STATS_GRP(per_prio),
1065         &MLX5E_STATS_GRP(pme),
1066         &MLX5E_STATS_GRP(channels),
1067         &MLX5E_STATS_GRP(per_port_buff_congest),
1068 };
1069
1070 static unsigned int mlx5e_ul_rep_stats_grps_num(struct mlx5e_priv *priv)
1071 {
1072         return ARRAY_SIZE(mlx5e_ul_rep_stats_grps);
1073 }
1074
1075 static const struct mlx5e_profile mlx5e_rep_profile = {
1076         .init                   = mlx5e_init_rep,
1077         .cleanup                = mlx5e_cleanup_rep,
1078         .init_rx                = mlx5e_init_rep_rx,
1079         .cleanup_rx             = mlx5e_cleanup_rep_rx,
1080         .init_tx                = mlx5e_init_rep_tx,
1081         .cleanup_tx             = mlx5e_cleanup_rep_tx,
1082         .enable                 = mlx5e_rep_enable,
1083         .disable                = mlx5e_rep_disable,
1084         .update_rx              = mlx5e_update_rep_rx,
1085         .update_stats           = mlx5e_stats_update_ndo_stats,
1086         .rx_handlers            = &mlx5e_rx_handlers_rep,
1087         .max_tc                 = 1,
1088         .rq_groups              = MLX5E_NUM_RQ_GROUPS(REGULAR),
1089         .stats_grps             = mlx5e_rep_stats_grps,
1090         .stats_grps_num         = mlx5e_rep_stats_grps_num,
1091         .rx_ptp_support         = false,
1092 };
1093
1094 static const struct mlx5e_profile mlx5e_uplink_rep_profile = {
1095         .init                   = mlx5e_init_ul_rep,
1096         .cleanup                = mlx5e_cleanup_rep,
1097         .init_rx                = mlx5e_init_ul_rep_rx,
1098         .cleanup_rx             = mlx5e_cleanup_ul_rep_rx,
1099         .init_tx                = mlx5e_init_rep_tx,
1100         .cleanup_tx             = mlx5e_cleanup_rep_tx,
1101         .enable                 = mlx5e_uplink_rep_enable,
1102         .disable                = mlx5e_uplink_rep_disable,
1103         .update_rx              = mlx5e_update_rep_rx,
1104         .update_stats           = mlx5e_stats_update_ndo_stats,
1105         .update_carrier         = mlx5e_update_carrier,
1106         .rx_handlers            = &mlx5e_rx_handlers_rep,
1107         .max_tc                 = MLX5E_MAX_NUM_TC,
1108         /* XSK is needed so we can replace profile with NIC netdev */
1109         .rq_groups              = MLX5E_NUM_RQ_GROUPS(XSK),
1110         .stats_grps             = mlx5e_ul_rep_stats_grps,
1111         .stats_grps_num         = mlx5e_ul_rep_stats_grps_num,
1112         .rx_ptp_support         = false,
1113 };
1114
1115 /* e-Switch vport representors */
1116 static int
1117 mlx5e_vport_uplink_rep_load(struct mlx5_core_dev *dev, struct mlx5_eswitch_rep *rep)
1118 {
1119         struct mlx5e_priv *priv = netdev_priv(mlx5_uplink_netdev_get(dev));
1120         struct mlx5e_rep_priv *rpriv = mlx5e_rep_to_rep_priv(rep);
1121         struct devlink_port *dl_port;
1122         int err;
1123
1124         rpriv->netdev = priv->netdev;
1125
1126         err = mlx5e_netdev_change_profile(priv, &mlx5e_uplink_rep_profile,
1127                                           rpriv);
1128         if (err)
1129                 return err;
1130
1131         dl_port = mlx5_esw_offloads_devlink_port(dev->priv.eswitch, rpriv->rep->vport);
1132         if (dl_port)
1133                 devlink_port_type_eth_set(dl_port, rpriv->netdev);
1134
1135         return 0;
1136 }
1137
1138 static void
1139 mlx5e_vport_uplink_rep_unload(struct mlx5e_rep_priv *rpriv)
1140 {
1141         struct net_device *netdev = rpriv->netdev;
1142         struct devlink_port *dl_port;
1143         struct mlx5_core_dev *dev;
1144         struct mlx5e_priv *priv;
1145
1146         priv = netdev_priv(netdev);
1147         dev = priv->mdev;
1148
1149         dl_port = mlx5_esw_offloads_devlink_port(dev->priv.eswitch, rpriv->rep->vport);
1150         if (dl_port)
1151                 devlink_port_type_clear(dl_port);
1152         mlx5e_netdev_attach_nic_profile(priv);
1153 }
1154
1155 static int
1156 mlx5e_vport_vf_rep_load(struct mlx5_core_dev *dev, struct mlx5_eswitch_rep *rep)
1157 {
1158         struct mlx5e_rep_priv *rpriv = mlx5e_rep_to_rep_priv(rep);
1159         const struct mlx5e_profile *profile;
1160         struct devlink_port *dl_port;
1161         struct net_device *netdev;
1162         struct mlx5e_priv *priv;
1163         unsigned int txqs, rxqs;
1164         int nch, err;
1165
1166         profile = &mlx5e_rep_profile;
1167         nch = mlx5e_get_max_num_channels(dev);
1168         txqs = nch * profile->max_tc;
1169         rxqs = nch * profile->rq_groups;
1170         netdev = mlx5e_create_netdev(dev, profile, txqs, rxqs);
1171         if (!netdev) {
1172                 mlx5_core_warn(dev,
1173                                "Failed to create representor netdev for vport %d\n",
1174                                rep->vport);
1175                 return -EINVAL;
1176         }
1177
1178         mlx5e_build_rep_netdev(netdev, dev);
1179         rpriv->netdev = netdev;
1180
1181         priv = netdev_priv(netdev);
1182         priv->profile = profile;
1183         priv->ppriv = rpriv;
1184         err = profile->init(dev, netdev);
1185         if (err) {
1186                 netdev_warn(netdev, "rep profile init failed, %d\n", err);
1187                 goto err_destroy_netdev;
1188         }
1189
1190         err = mlx5e_attach_netdev(netdev_priv(netdev));
1191         if (err) {
1192                 netdev_warn(netdev,
1193                             "Failed to attach representor netdev for vport %d\n",
1194                             rep->vport);
1195                 goto err_cleanup_profile;
1196         }
1197
1198         err = register_netdev(netdev);
1199         if (err) {
1200                 netdev_warn(netdev,
1201                             "Failed to register representor netdev for vport %d\n",
1202                             rep->vport);
1203                 goto err_detach_netdev;
1204         }
1205
1206         dl_port = mlx5_esw_offloads_devlink_port(dev->priv.eswitch, rpriv->rep->vport);
1207         if (dl_port)
1208                 devlink_port_type_eth_set(dl_port, netdev);
1209         return 0;
1210
1211 err_detach_netdev:
1212         mlx5e_detach_netdev(netdev_priv(netdev));
1213
1214 err_cleanup_profile:
1215         priv->profile->cleanup(priv);
1216
1217 err_destroy_netdev:
1218         mlx5e_destroy_netdev(netdev_priv(netdev));
1219         return err;
1220 }
1221
1222 static int
1223 mlx5e_vport_rep_load(struct mlx5_core_dev *dev, struct mlx5_eswitch_rep *rep)
1224 {
1225         struct mlx5e_rep_priv *rpriv;
1226         int err;
1227
1228         rpriv = kzalloc(sizeof(*rpriv), GFP_KERNEL);
1229         if (!rpriv)
1230                 return -ENOMEM;
1231
1232         /* rpriv->rep to be looked up when profile->init() is called */
1233         rpriv->rep = rep;
1234         rep->rep_data[REP_ETH].priv = rpriv;
1235         INIT_LIST_HEAD(&rpriv->vport_sqs_list);
1236
1237         if (rep->vport == MLX5_VPORT_UPLINK)
1238                 err = mlx5e_vport_uplink_rep_load(dev, rep);
1239         else
1240                 err = mlx5e_vport_vf_rep_load(dev, rep);
1241
1242         if (err)
1243                 kfree(rpriv);
1244
1245         return err;
1246 }
1247
1248 static void
1249 mlx5e_vport_rep_unload(struct mlx5_eswitch_rep *rep)
1250 {
1251         struct mlx5e_rep_priv *rpriv = mlx5e_rep_to_rep_priv(rep);
1252         struct net_device *netdev = rpriv->netdev;
1253         struct mlx5e_priv *priv = netdev_priv(netdev);
1254         struct mlx5_core_dev *dev = priv->mdev;
1255         struct devlink_port *dl_port;
1256         void *ppriv = priv->ppriv;
1257
1258         if (rep->vport == MLX5_VPORT_UPLINK) {
1259                 mlx5e_vport_uplink_rep_unload(rpriv);
1260                 goto free_ppriv;
1261         }
1262
1263         dl_port = mlx5_esw_offloads_devlink_port(dev->priv.eswitch, rpriv->rep->vport);
1264         if (dl_port)
1265                 devlink_port_type_clear(dl_port);
1266         unregister_netdev(netdev);
1267         mlx5e_detach_netdev(priv);
1268         priv->profile->cleanup(priv);
1269         mlx5e_destroy_netdev(priv);
1270 free_ppriv:
1271         kfree(ppriv); /* mlx5e_rep_priv */
1272 }
1273
1274 static void *mlx5e_vport_rep_get_proto_dev(struct mlx5_eswitch_rep *rep)
1275 {
1276         struct mlx5e_rep_priv *rpriv;
1277
1278         rpriv = mlx5e_rep_to_rep_priv(rep);
1279
1280         return rpriv->netdev;
1281 }
1282
1283 static void mlx5e_vport_rep_event_unpair(struct mlx5_eswitch_rep *rep)
1284 {
1285         struct mlx5e_rep_priv *rpriv;
1286         struct mlx5e_rep_sq *rep_sq;
1287
1288         rpriv = mlx5e_rep_to_rep_priv(rep);
1289         list_for_each_entry(rep_sq, &rpriv->vport_sqs_list, list) {
1290                 if (!rep_sq->send_to_vport_rule_peer)
1291                         continue;
1292                 mlx5_eswitch_del_send_to_vport_rule(rep_sq->send_to_vport_rule_peer);
1293                 rep_sq->send_to_vport_rule_peer = NULL;
1294         }
1295 }
1296
1297 static int mlx5e_vport_rep_event_pair(struct mlx5_eswitch *esw,
1298                                       struct mlx5_eswitch_rep *rep,
1299                                       struct mlx5_eswitch *peer_esw)
1300 {
1301         struct mlx5_flow_handle *flow_rule;
1302         struct mlx5e_rep_priv *rpriv;
1303         struct mlx5e_rep_sq *rep_sq;
1304
1305         rpriv = mlx5e_rep_to_rep_priv(rep);
1306         list_for_each_entry(rep_sq, &rpriv->vport_sqs_list, list) {
1307                 if (rep_sq->send_to_vport_rule_peer)
1308                         continue;
1309                 flow_rule = mlx5_eswitch_add_send_to_vport_rule(peer_esw, esw, rep, rep_sq->sqn);
1310                 if (IS_ERR(flow_rule))
1311                         goto err_out;
1312                 rep_sq->send_to_vport_rule_peer = flow_rule;
1313         }
1314
1315         return 0;
1316 err_out:
1317         mlx5e_vport_rep_event_unpair(rep);
1318         return PTR_ERR(flow_rule);
1319 }
1320
1321 static int mlx5e_vport_rep_event(struct mlx5_eswitch *esw,
1322                                  struct mlx5_eswitch_rep *rep,
1323                                  enum mlx5_switchdev_event event,
1324                                  void *data)
1325 {
1326         int err = 0;
1327
1328         if (event == MLX5_SWITCHDEV_EVENT_PAIR)
1329                 err = mlx5e_vport_rep_event_pair(esw, rep, data);
1330         else if (event == MLX5_SWITCHDEV_EVENT_UNPAIR)
1331                 mlx5e_vport_rep_event_unpair(rep);
1332
1333         return err;
1334 }
1335
1336 static const struct mlx5_eswitch_rep_ops rep_ops = {
1337         .load = mlx5e_vport_rep_load,
1338         .unload = mlx5e_vport_rep_unload,
1339         .get_proto_dev = mlx5e_vport_rep_get_proto_dev,
1340         .event = mlx5e_vport_rep_event,
1341 };
1342
1343 static int mlx5e_rep_probe(struct auxiliary_device *adev,
1344                            const struct auxiliary_device_id *id)
1345 {
1346         struct mlx5_adev *edev = container_of(adev, struct mlx5_adev, adev);
1347         struct mlx5_core_dev *mdev = edev->mdev;
1348         struct mlx5_eswitch *esw;
1349
1350         esw = mdev->priv.eswitch;
1351         mlx5_eswitch_register_vport_reps(esw, &rep_ops, REP_ETH);
1352         return 0;
1353 }
1354
1355 static void mlx5e_rep_remove(struct auxiliary_device *adev)
1356 {
1357         struct mlx5_adev *vdev = container_of(adev, struct mlx5_adev, adev);
1358         struct mlx5_core_dev *mdev = vdev->mdev;
1359         struct mlx5_eswitch *esw;
1360
1361         esw = mdev->priv.eswitch;
1362         mlx5_eswitch_unregister_vport_reps(esw, REP_ETH);
1363 }
1364
1365 static const struct auxiliary_device_id mlx5e_rep_id_table[] = {
1366         { .name = MLX5_ADEV_NAME ".eth-rep", },
1367         {},
1368 };
1369
1370 MODULE_DEVICE_TABLE(auxiliary, mlx5e_rep_id_table);
1371
1372 static struct auxiliary_driver mlx5e_rep_driver = {
1373         .name = "eth-rep",
1374         .probe = mlx5e_rep_probe,
1375         .remove = mlx5e_rep_remove,
1376         .id_table = mlx5e_rep_id_table,
1377 };
1378
1379 int mlx5e_rep_init(void)
1380 {
1381         return auxiliary_driver_register(&mlx5e_rep_driver);
1382 }
1383
1384 void mlx5e_rep_cleanup(void)
1385 {
1386         auxiliary_driver_unregister(&mlx5e_rep_driver);
1387 }