Merge tag 'drm-misc-next-2021-10-14' of git://anongit.freedesktop.org/drm/drm-misc...
[linux-2.6-microblaze.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         /* Set an initial non-zero value, so that mlx5e_select_queue won't
622          * divide by zero if called before first activating channels.
623          */
624         priv->num_tc_x_num_ch = params->num_channels * params->mqprio.num_tc;
625
626         mlx5_query_min_inline(mdev, &params->tx_min_inline_mode);
627 }
628
629 static void mlx5e_build_rep_netdev(struct net_device *netdev,
630                                    struct mlx5_core_dev *mdev)
631 {
632         SET_NETDEV_DEV(netdev, mdev->device);
633         netdev->netdev_ops = &mlx5e_netdev_ops_rep;
634         eth_hw_addr_random(netdev);
635         netdev->ethtool_ops = &mlx5e_rep_ethtool_ops;
636
637         netdev->watchdog_timeo    = 15 * HZ;
638
639 #if IS_ENABLED(CONFIG_MLX5_CLS_ACT)
640         netdev->hw_features    |= NETIF_F_HW_TC;
641 #endif
642         netdev->hw_features    |= NETIF_F_SG;
643         netdev->hw_features    |= NETIF_F_IP_CSUM;
644         netdev->hw_features    |= NETIF_F_IPV6_CSUM;
645         netdev->hw_features    |= NETIF_F_GRO;
646         netdev->hw_features    |= NETIF_F_TSO;
647         netdev->hw_features    |= NETIF_F_TSO6;
648         netdev->hw_features    |= NETIF_F_RXCSUM;
649
650         netdev->features |= netdev->hw_features;
651         netdev->features |= NETIF_F_NETNS_LOCAL;
652 }
653
654 static int mlx5e_init_rep(struct mlx5_core_dev *mdev,
655                           struct net_device *netdev)
656 {
657         struct mlx5e_priv *priv = netdev_priv(netdev);
658
659         mlx5e_build_rep_params(netdev);
660         mlx5e_timestamp_init(priv);
661
662         return 0;
663 }
664
665 static int mlx5e_init_ul_rep(struct mlx5_core_dev *mdev,
666                              struct net_device *netdev)
667 {
668         struct mlx5e_priv *priv = netdev_priv(netdev);
669         int err;
670
671         err = mlx5e_ipsec_init(priv);
672         if (err)
673                 mlx5_core_err(mdev, "Uplink rep IPsec initialization failed, %d\n", err);
674
675         mlx5e_vxlan_set_netdev_info(priv);
676         return mlx5e_init_rep(mdev, netdev);
677 }
678
679 static void mlx5e_cleanup_rep(struct mlx5e_priv *priv)
680 {
681         mlx5e_ipsec_cleanup(priv);
682 }
683
684 static int mlx5e_create_rep_ttc_table(struct mlx5e_priv *priv)
685 {
686         struct mlx5e_rep_priv *rpriv = priv->ppriv;
687         struct mlx5_eswitch_rep *rep = rpriv->rep;
688         struct ttc_params ttc_params = {};
689         int err;
690
691         priv->fs.ns = mlx5_get_flow_namespace(priv->mdev,
692                                               MLX5_FLOW_NAMESPACE_KERNEL);
693
694         /* The inner_ttc in the ttc params is intentionally not set */
695         mlx5e_set_ttc_params(priv, &ttc_params, false);
696
697         if (rep->vport != MLX5_VPORT_UPLINK)
698                 /* To give uplik rep TTC a lower level for chaining from root ft */
699                 ttc_params.ft_attr.level = MLX5E_TTC_FT_LEVEL + 1;
700
701         priv->fs.ttc = mlx5_create_ttc_table(priv->mdev, &ttc_params);
702         if (IS_ERR(priv->fs.ttc)) {
703                 err = PTR_ERR(priv->fs.ttc);
704                 netdev_err(priv->netdev, "Failed to create rep ttc table, err=%d\n",
705                            err);
706                 return err;
707         }
708         return 0;
709 }
710
711 static int mlx5e_create_rep_root_ft(struct mlx5e_priv *priv)
712 {
713         struct mlx5e_rep_priv *rpriv = priv->ppriv;
714         struct mlx5_eswitch_rep *rep = rpriv->rep;
715         struct mlx5_flow_table_attr ft_attr = {};
716         struct mlx5_flow_namespace *ns;
717         int err = 0;
718
719         if (rep->vport != MLX5_VPORT_UPLINK) {
720                 /* non uplik reps will skip any bypass tables and go directly to
721                  * their own ttc
722                  */
723                 rpriv->root_ft = mlx5_get_ttc_flow_table(priv->fs.ttc);
724                 return 0;
725         }
726
727         /* uplink root ft will be used to auto chain, to ethtool or ttc tables */
728         ns = mlx5_get_flow_namespace(priv->mdev, MLX5_FLOW_NAMESPACE_OFFLOADS);
729         if (!ns) {
730                 netdev_err(priv->netdev, "Failed to get reps offloads namespace\n");
731                 return -EOPNOTSUPP;
732         }
733
734         ft_attr.max_fte = 0; /* Empty table, miss rule will always point to next table */
735         ft_attr.prio = 1;
736         ft_attr.level = 1;
737
738         rpriv->root_ft = mlx5_create_flow_table(ns, &ft_attr);
739         if (IS_ERR(rpriv->root_ft)) {
740                 err = PTR_ERR(rpriv->root_ft);
741                 rpriv->root_ft = NULL;
742         }
743
744         return err;
745 }
746
747 static void mlx5e_destroy_rep_root_ft(struct mlx5e_priv *priv)
748 {
749         struct mlx5e_rep_priv *rpriv = priv->ppriv;
750         struct mlx5_eswitch_rep *rep = rpriv->rep;
751
752         if (rep->vport != MLX5_VPORT_UPLINK)
753                 return;
754         mlx5_destroy_flow_table(rpriv->root_ft);
755 }
756
757 static int mlx5e_create_rep_vport_rx_rule(struct mlx5e_priv *priv)
758 {
759         struct mlx5_eswitch *esw = priv->mdev->priv.eswitch;
760         struct mlx5e_rep_priv *rpriv = priv->ppriv;
761         struct mlx5_eswitch_rep *rep = rpriv->rep;
762         struct mlx5_flow_handle *flow_rule;
763         struct mlx5_flow_destination dest;
764
765         dest.type = MLX5_FLOW_DESTINATION_TYPE_FLOW_TABLE;
766         dest.ft = rpriv->root_ft;
767
768         flow_rule = mlx5_eswitch_create_vport_rx_rule(esw, rep->vport, &dest);
769         if (IS_ERR(flow_rule))
770                 return PTR_ERR(flow_rule);
771         rpriv->vport_rx_rule = flow_rule;
772         return 0;
773 }
774
775 static void rep_vport_rx_rule_destroy(struct mlx5e_priv *priv)
776 {
777         struct mlx5e_rep_priv *rpriv = priv->ppriv;
778
779         if (!rpriv->vport_rx_rule)
780                 return;
781
782         mlx5_del_flow_rules(rpriv->vport_rx_rule);
783         rpriv->vport_rx_rule = NULL;
784 }
785
786 int mlx5e_rep_bond_update(struct mlx5e_priv *priv, bool cleanup)
787 {
788         rep_vport_rx_rule_destroy(priv);
789
790         return cleanup ? 0 : mlx5e_create_rep_vport_rx_rule(priv);
791 }
792
793 static int mlx5e_init_rep_rx(struct mlx5e_priv *priv)
794 {
795         struct mlx5_core_dev *mdev = priv->mdev;
796         struct mlx5e_lro_param lro_param;
797         int err;
798
799         priv->rx_res = mlx5e_rx_res_alloc();
800         if (!priv->rx_res)
801                 return -ENOMEM;
802
803         mlx5e_init_l2_addr(priv);
804
805         err = mlx5e_open_drop_rq(priv, &priv->drop_rq);
806         if (err) {
807                 mlx5_core_err(mdev, "open drop rq failed, %d\n", err);
808                 return err;
809         }
810
811         lro_param = mlx5e_get_lro_param(&priv->channels.params);
812         err = mlx5e_rx_res_init(priv->rx_res, priv->mdev, 0,
813                                 priv->max_nch, priv->drop_rq.rqn, &lro_param,
814                                 priv->channels.params.num_channels);
815         if (err)
816                 goto err_close_drop_rq;
817
818         err = mlx5e_create_rep_ttc_table(priv);
819         if (err)
820                 goto err_destroy_rx_res;
821
822         err = mlx5e_create_rep_root_ft(priv);
823         if (err)
824                 goto err_destroy_ttc_table;
825
826         err = mlx5e_create_rep_vport_rx_rule(priv);
827         if (err)
828                 goto err_destroy_root_ft;
829
830         mlx5e_ethtool_init_steering(priv);
831
832         return 0;
833
834 err_destroy_root_ft:
835         mlx5e_destroy_rep_root_ft(priv);
836 err_destroy_ttc_table:
837         mlx5_destroy_ttc_table(priv->fs.ttc);
838 err_destroy_rx_res:
839         mlx5e_rx_res_destroy(priv->rx_res);
840 err_close_drop_rq:
841         mlx5e_close_drop_rq(&priv->drop_rq);
842         mlx5e_rx_res_free(priv->rx_res);
843         priv->rx_res = NULL;
844         return err;
845 }
846
847 static void mlx5e_cleanup_rep_rx(struct mlx5e_priv *priv)
848 {
849         mlx5e_ethtool_cleanup_steering(priv);
850         rep_vport_rx_rule_destroy(priv);
851         mlx5e_destroy_rep_root_ft(priv);
852         mlx5_destroy_ttc_table(priv->fs.ttc);
853         mlx5e_rx_res_destroy(priv->rx_res);
854         mlx5e_close_drop_rq(&priv->drop_rq);
855         mlx5e_rx_res_free(priv->rx_res);
856         priv->rx_res = NULL;
857 }
858
859 static int mlx5e_init_ul_rep_rx(struct mlx5e_priv *priv)
860 {
861         mlx5e_create_q_counters(priv);
862         return mlx5e_init_rep_rx(priv);
863 }
864
865 static void mlx5e_cleanup_ul_rep_rx(struct mlx5e_priv *priv)
866 {
867         mlx5e_cleanup_rep_rx(priv);
868         mlx5e_destroy_q_counters(priv);
869 }
870
871 static int mlx5e_init_uplink_rep_tx(struct mlx5e_rep_priv *rpriv)
872 {
873         struct mlx5_rep_uplink_priv *uplink_priv;
874         struct net_device *netdev;
875         struct mlx5e_priv *priv;
876         int err;
877
878         netdev = rpriv->netdev;
879         priv = netdev_priv(netdev);
880         uplink_priv = &rpriv->uplink_priv;
881
882         err = mlx5e_rep_tc_init(rpriv);
883         if (err)
884                 return err;
885
886         mlx5_init_port_tun_entropy(&uplink_priv->tun_entropy, priv->mdev);
887
888         mlx5e_rep_bond_init(rpriv);
889         err = mlx5e_rep_tc_netdevice_event_register(rpriv);
890         if (err) {
891                 mlx5_core_err(priv->mdev, "Failed to register netdev notifier, err: %d\n",
892                               err);
893                 goto err_event_reg;
894         }
895
896         return 0;
897
898 err_event_reg:
899         mlx5e_rep_bond_cleanup(rpriv);
900         mlx5e_rep_tc_cleanup(rpriv);
901         return err;
902 }
903
904 static int mlx5e_init_rep_tx(struct mlx5e_priv *priv)
905 {
906         struct mlx5e_rep_priv *rpriv = priv->ppriv;
907         int err;
908
909         err = mlx5e_create_tises(priv);
910         if (err) {
911                 mlx5_core_warn(priv->mdev, "create tises failed, %d\n", err);
912                 return err;
913         }
914
915         if (rpriv->rep->vport == MLX5_VPORT_UPLINK) {
916                 err = mlx5e_init_uplink_rep_tx(rpriv);
917                 if (err)
918                         goto destroy_tises;
919         }
920
921         return 0;
922
923 destroy_tises:
924         mlx5e_destroy_tises(priv);
925         return err;
926 }
927
928 static void mlx5e_cleanup_uplink_rep_tx(struct mlx5e_rep_priv *rpriv)
929 {
930         mlx5e_rep_tc_netdevice_event_unregister(rpriv);
931         mlx5e_rep_bond_cleanup(rpriv);
932         mlx5e_rep_tc_cleanup(rpriv);
933 }
934
935 static void mlx5e_cleanup_rep_tx(struct mlx5e_priv *priv)
936 {
937         struct mlx5e_rep_priv *rpriv = priv->ppriv;
938
939         mlx5e_destroy_tises(priv);
940
941         if (rpriv->rep->vport == MLX5_VPORT_UPLINK)
942                 mlx5e_cleanup_uplink_rep_tx(rpriv);
943 }
944
945 static void mlx5e_rep_enable(struct mlx5e_priv *priv)
946 {
947         struct mlx5e_rep_priv *rpriv = priv->ppriv;
948
949         mlx5e_set_netdev_mtu_boundaries(priv);
950         mlx5e_rep_neigh_init(rpriv);
951 }
952
953 static void mlx5e_rep_disable(struct mlx5e_priv *priv)
954 {
955         struct mlx5e_rep_priv *rpriv = priv->ppriv;
956
957         mlx5e_rep_neigh_cleanup(rpriv);
958 }
959
960 static int mlx5e_update_rep_rx(struct mlx5e_priv *priv)
961 {
962         return 0;
963 }
964
965 static int uplink_rep_async_event(struct notifier_block *nb, unsigned long event, void *data)
966 {
967         struct mlx5e_priv *priv = container_of(nb, struct mlx5e_priv, events_nb);
968
969         if (event == MLX5_EVENT_TYPE_PORT_CHANGE) {
970                 struct mlx5_eqe *eqe = data;
971
972                 switch (eqe->sub_type) {
973                 case MLX5_PORT_CHANGE_SUBTYPE_DOWN:
974                 case MLX5_PORT_CHANGE_SUBTYPE_ACTIVE:
975                         queue_work(priv->wq, &priv->update_carrier_work);
976                         break;
977                 default:
978                         return NOTIFY_DONE;
979                 }
980
981                 return NOTIFY_OK;
982         }
983
984         if (event == MLX5_DEV_EVENT_PORT_AFFINITY)
985                 return mlx5e_rep_tc_event_port_affinity(priv);
986
987         return NOTIFY_DONE;
988 }
989
990 static void mlx5e_uplink_rep_enable(struct mlx5e_priv *priv)
991 {
992         struct mlx5e_rep_priv *rpriv = priv->ppriv;
993         struct net_device *netdev = priv->netdev;
994         struct mlx5_core_dev *mdev = priv->mdev;
995         u16 max_mtu;
996
997         netdev->min_mtu = ETH_MIN_MTU;
998         mlx5_query_port_max_mtu(priv->mdev, &max_mtu, 1);
999         netdev->max_mtu = MLX5E_HW2SW_MTU(&priv->channels.params, max_mtu);
1000         mlx5e_set_dev_port_mtu(priv);
1001
1002         mlx5e_rep_tc_enable(priv);
1003
1004         if (MLX5_CAP_GEN(mdev, uplink_follow))
1005                 mlx5_modify_vport_admin_state(mdev, MLX5_VPORT_STATE_OP_MOD_UPLINK,
1006                                               0, 0, MLX5_VPORT_ADMIN_STATE_AUTO);
1007         mlx5_lag_add_netdev(mdev, netdev);
1008         priv->events_nb.notifier_call = uplink_rep_async_event;
1009         mlx5_notifier_register(mdev, &priv->events_nb);
1010         mlx5e_dcbnl_initialize(priv);
1011         mlx5e_dcbnl_init_app(priv);
1012         mlx5e_rep_neigh_init(rpriv);
1013         mlx5e_rep_bridge_init(priv);
1014
1015         netdev->wanted_features |= NETIF_F_HW_TC;
1016
1017         rtnl_lock();
1018         if (netif_running(netdev))
1019                 mlx5e_open(netdev);
1020         netif_device_attach(netdev);
1021         rtnl_unlock();
1022 }
1023
1024 static void mlx5e_uplink_rep_disable(struct mlx5e_priv *priv)
1025 {
1026         struct mlx5e_rep_priv *rpriv = priv->ppriv;
1027         struct mlx5_core_dev *mdev = priv->mdev;
1028
1029         rtnl_lock();
1030         if (netif_running(priv->netdev))
1031                 mlx5e_close(priv->netdev);
1032         netif_device_detach(priv->netdev);
1033         rtnl_unlock();
1034
1035         mlx5e_rep_bridge_cleanup(priv);
1036         mlx5e_rep_neigh_cleanup(rpriv);
1037         mlx5e_dcbnl_delete_app(priv);
1038         mlx5_notifier_unregister(mdev, &priv->events_nb);
1039         mlx5e_rep_tc_disable(priv);
1040         mlx5_lag_remove_netdev(mdev, priv->netdev);
1041 }
1042
1043 static MLX5E_DEFINE_STATS_GRP(sw_rep, 0);
1044 static MLX5E_DEFINE_STATS_GRP(vport_rep, MLX5E_NDO_UPDATE_STATS);
1045
1046 /* The stats groups order is opposite to the update_stats() order calls */
1047 static mlx5e_stats_grp_t mlx5e_rep_stats_grps[] = {
1048         &MLX5E_STATS_GRP(sw_rep),
1049         &MLX5E_STATS_GRP(vport_rep),
1050 };
1051
1052 static unsigned int mlx5e_rep_stats_grps_num(struct mlx5e_priv *priv)
1053 {
1054         return ARRAY_SIZE(mlx5e_rep_stats_grps);
1055 }
1056
1057 /* The stats groups order is opposite to the update_stats() order calls */
1058 static mlx5e_stats_grp_t mlx5e_ul_rep_stats_grps[] = {
1059         &MLX5E_STATS_GRP(sw),
1060         &MLX5E_STATS_GRP(qcnt),
1061         &MLX5E_STATS_GRP(vnic_env),
1062         &MLX5E_STATS_GRP(vport),
1063         &MLX5E_STATS_GRP(802_3),
1064         &MLX5E_STATS_GRP(2863),
1065         &MLX5E_STATS_GRP(2819),
1066         &MLX5E_STATS_GRP(phy),
1067         &MLX5E_STATS_GRP(eth_ext),
1068         &MLX5E_STATS_GRP(pcie),
1069         &MLX5E_STATS_GRP(per_prio),
1070         &MLX5E_STATS_GRP(pme),
1071         &MLX5E_STATS_GRP(channels),
1072         &MLX5E_STATS_GRP(per_port_buff_congest),
1073 };
1074
1075 static unsigned int mlx5e_ul_rep_stats_grps_num(struct mlx5e_priv *priv)
1076 {
1077         return ARRAY_SIZE(mlx5e_ul_rep_stats_grps);
1078 }
1079
1080 static const struct mlx5e_profile mlx5e_rep_profile = {
1081         .init                   = mlx5e_init_rep,
1082         .cleanup                = mlx5e_cleanup_rep,
1083         .init_rx                = mlx5e_init_rep_rx,
1084         .cleanup_rx             = mlx5e_cleanup_rep_rx,
1085         .init_tx                = mlx5e_init_rep_tx,
1086         .cleanup_tx             = mlx5e_cleanup_rep_tx,
1087         .enable                 = mlx5e_rep_enable,
1088         .disable                = mlx5e_rep_disable,
1089         .update_rx              = mlx5e_update_rep_rx,
1090         .update_stats           = mlx5e_stats_update_ndo_stats,
1091         .rx_handlers            = &mlx5e_rx_handlers_rep,
1092         .max_tc                 = 1,
1093         .rq_groups              = MLX5E_NUM_RQ_GROUPS(REGULAR),
1094         .stats_grps             = mlx5e_rep_stats_grps,
1095         .stats_grps_num         = mlx5e_rep_stats_grps_num,
1096         .rx_ptp_support         = false,
1097 };
1098
1099 static const struct mlx5e_profile mlx5e_uplink_rep_profile = {
1100         .init                   = mlx5e_init_ul_rep,
1101         .cleanup                = mlx5e_cleanup_rep,
1102         .init_rx                = mlx5e_init_ul_rep_rx,
1103         .cleanup_rx             = mlx5e_cleanup_ul_rep_rx,
1104         .init_tx                = mlx5e_init_rep_tx,
1105         .cleanup_tx             = mlx5e_cleanup_rep_tx,
1106         .enable                 = mlx5e_uplink_rep_enable,
1107         .disable                = mlx5e_uplink_rep_disable,
1108         .update_rx              = mlx5e_update_rep_rx,
1109         .update_stats           = mlx5e_stats_update_ndo_stats,
1110         .update_carrier         = mlx5e_update_carrier,
1111         .rx_handlers            = &mlx5e_rx_handlers_rep,
1112         .max_tc                 = MLX5E_MAX_NUM_TC,
1113         /* XSK is needed so we can replace profile with NIC netdev */
1114         .rq_groups              = MLX5E_NUM_RQ_GROUPS(XSK),
1115         .stats_grps             = mlx5e_ul_rep_stats_grps,
1116         .stats_grps_num         = mlx5e_ul_rep_stats_grps_num,
1117         .rx_ptp_support         = false,
1118 };
1119
1120 /* e-Switch vport representors */
1121 static int
1122 mlx5e_vport_uplink_rep_load(struct mlx5_core_dev *dev, struct mlx5_eswitch_rep *rep)
1123 {
1124         struct mlx5e_priv *priv = netdev_priv(mlx5_uplink_netdev_get(dev));
1125         struct mlx5e_rep_priv *rpriv = mlx5e_rep_to_rep_priv(rep);
1126         struct devlink_port *dl_port;
1127         int err;
1128
1129         rpriv->netdev = priv->netdev;
1130
1131         err = mlx5e_netdev_change_profile(priv, &mlx5e_uplink_rep_profile,
1132                                           rpriv);
1133         if (err)
1134                 return err;
1135
1136         dl_port = mlx5_esw_offloads_devlink_port(dev->priv.eswitch, rpriv->rep->vport);
1137         if (dl_port)
1138                 devlink_port_type_eth_set(dl_port, rpriv->netdev);
1139
1140         return 0;
1141 }
1142
1143 static void
1144 mlx5e_vport_uplink_rep_unload(struct mlx5e_rep_priv *rpriv)
1145 {
1146         struct net_device *netdev = rpriv->netdev;
1147         struct devlink_port *dl_port;
1148         struct mlx5_core_dev *dev;
1149         struct mlx5e_priv *priv;
1150
1151         priv = netdev_priv(netdev);
1152         dev = priv->mdev;
1153
1154         dl_port = mlx5_esw_offloads_devlink_port(dev->priv.eswitch, rpriv->rep->vport);
1155         if (dl_port)
1156                 devlink_port_type_clear(dl_port);
1157         mlx5e_netdev_attach_nic_profile(priv);
1158 }
1159
1160 static int
1161 mlx5e_vport_vf_rep_load(struct mlx5_core_dev *dev, struct mlx5_eswitch_rep *rep)
1162 {
1163         struct mlx5e_rep_priv *rpriv = mlx5e_rep_to_rep_priv(rep);
1164         const struct mlx5e_profile *profile;
1165         struct devlink_port *dl_port;
1166         struct net_device *netdev;
1167         struct mlx5e_priv *priv;
1168         unsigned int txqs, rxqs;
1169         int nch, err;
1170
1171         profile = &mlx5e_rep_profile;
1172         nch = mlx5e_get_max_num_channels(dev);
1173         txqs = nch * profile->max_tc;
1174         rxqs = nch * profile->rq_groups;
1175         netdev = mlx5e_create_netdev(dev, profile, txqs, rxqs);
1176         if (!netdev) {
1177                 mlx5_core_warn(dev,
1178                                "Failed to create representor netdev for vport %d\n",
1179                                rep->vport);
1180                 return -EINVAL;
1181         }
1182
1183         mlx5e_build_rep_netdev(netdev, dev);
1184         rpriv->netdev = netdev;
1185
1186         priv = netdev_priv(netdev);
1187         priv->profile = profile;
1188         priv->ppriv = rpriv;
1189         err = profile->init(dev, netdev);
1190         if (err) {
1191                 netdev_warn(netdev, "rep profile init failed, %d\n", err);
1192                 goto err_destroy_netdev;
1193         }
1194
1195         err = mlx5e_attach_netdev(netdev_priv(netdev));
1196         if (err) {
1197                 netdev_warn(netdev,
1198                             "Failed to attach representor netdev for vport %d\n",
1199                             rep->vport);
1200                 goto err_cleanup_profile;
1201         }
1202
1203         err = register_netdev(netdev);
1204         if (err) {
1205                 netdev_warn(netdev,
1206                             "Failed to register representor netdev for vport %d\n",
1207                             rep->vport);
1208                 goto err_detach_netdev;
1209         }
1210
1211         dl_port = mlx5_esw_offloads_devlink_port(dev->priv.eswitch, rpriv->rep->vport);
1212         if (dl_port)
1213                 devlink_port_type_eth_set(dl_port, netdev);
1214         return 0;
1215
1216 err_detach_netdev:
1217         mlx5e_detach_netdev(netdev_priv(netdev));
1218
1219 err_cleanup_profile:
1220         priv->profile->cleanup(priv);
1221
1222 err_destroy_netdev:
1223         mlx5e_destroy_netdev(netdev_priv(netdev));
1224         return err;
1225 }
1226
1227 static int
1228 mlx5e_vport_rep_load(struct mlx5_core_dev *dev, struct mlx5_eswitch_rep *rep)
1229 {
1230         struct mlx5e_rep_priv *rpriv;
1231         int err;
1232
1233         rpriv = kzalloc(sizeof(*rpriv), GFP_KERNEL);
1234         if (!rpriv)
1235                 return -ENOMEM;
1236
1237         /* rpriv->rep to be looked up when profile->init() is called */
1238         rpriv->rep = rep;
1239         rep->rep_data[REP_ETH].priv = rpriv;
1240         INIT_LIST_HEAD(&rpriv->vport_sqs_list);
1241
1242         if (rep->vport == MLX5_VPORT_UPLINK)
1243                 err = mlx5e_vport_uplink_rep_load(dev, rep);
1244         else
1245                 err = mlx5e_vport_vf_rep_load(dev, rep);
1246
1247         if (err)
1248                 kfree(rpriv);
1249
1250         return err;
1251 }
1252
1253 static void
1254 mlx5e_vport_rep_unload(struct mlx5_eswitch_rep *rep)
1255 {
1256         struct mlx5e_rep_priv *rpriv = mlx5e_rep_to_rep_priv(rep);
1257         struct net_device *netdev = rpriv->netdev;
1258         struct mlx5e_priv *priv = netdev_priv(netdev);
1259         struct mlx5_core_dev *dev = priv->mdev;
1260         struct devlink_port *dl_port;
1261         void *ppriv = priv->ppriv;
1262
1263         if (rep->vport == MLX5_VPORT_UPLINK) {
1264                 mlx5e_vport_uplink_rep_unload(rpriv);
1265                 goto free_ppriv;
1266         }
1267
1268         dl_port = mlx5_esw_offloads_devlink_port(dev->priv.eswitch, rpriv->rep->vport);
1269         if (dl_port)
1270                 devlink_port_type_clear(dl_port);
1271         unregister_netdev(netdev);
1272         mlx5e_detach_netdev(priv);
1273         priv->profile->cleanup(priv);
1274         mlx5e_destroy_netdev(priv);
1275 free_ppriv:
1276         kfree(ppriv); /* mlx5e_rep_priv */
1277 }
1278
1279 static void *mlx5e_vport_rep_get_proto_dev(struct mlx5_eswitch_rep *rep)
1280 {
1281         struct mlx5e_rep_priv *rpriv;
1282
1283         rpriv = mlx5e_rep_to_rep_priv(rep);
1284
1285         return rpriv->netdev;
1286 }
1287
1288 static void mlx5e_vport_rep_event_unpair(struct mlx5_eswitch_rep *rep)
1289 {
1290         struct mlx5e_rep_priv *rpriv;
1291         struct mlx5e_rep_sq *rep_sq;
1292
1293         rpriv = mlx5e_rep_to_rep_priv(rep);
1294         list_for_each_entry(rep_sq, &rpriv->vport_sqs_list, list) {
1295                 if (!rep_sq->send_to_vport_rule_peer)
1296                         continue;
1297                 mlx5_eswitch_del_send_to_vport_rule(rep_sq->send_to_vport_rule_peer);
1298                 rep_sq->send_to_vport_rule_peer = NULL;
1299         }
1300 }
1301
1302 static int mlx5e_vport_rep_event_pair(struct mlx5_eswitch *esw,
1303                                       struct mlx5_eswitch_rep *rep,
1304                                       struct mlx5_eswitch *peer_esw)
1305 {
1306         struct mlx5_flow_handle *flow_rule;
1307         struct mlx5e_rep_priv *rpriv;
1308         struct mlx5e_rep_sq *rep_sq;
1309
1310         rpriv = mlx5e_rep_to_rep_priv(rep);
1311         list_for_each_entry(rep_sq, &rpriv->vport_sqs_list, list) {
1312                 if (rep_sq->send_to_vport_rule_peer)
1313                         continue;
1314                 flow_rule = mlx5_eswitch_add_send_to_vport_rule(peer_esw, esw, rep, rep_sq->sqn);
1315                 if (IS_ERR(flow_rule))
1316                         goto err_out;
1317                 rep_sq->send_to_vport_rule_peer = flow_rule;
1318         }
1319
1320         return 0;
1321 err_out:
1322         mlx5e_vport_rep_event_unpair(rep);
1323         return PTR_ERR(flow_rule);
1324 }
1325
1326 static int mlx5e_vport_rep_event(struct mlx5_eswitch *esw,
1327                                  struct mlx5_eswitch_rep *rep,
1328                                  enum mlx5_switchdev_event event,
1329                                  void *data)
1330 {
1331         int err = 0;
1332
1333         if (event == MLX5_SWITCHDEV_EVENT_PAIR)
1334                 err = mlx5e_vport_rep_event_pair(esw, rep, data);
1335         else if (event == MLX5_SWITCHDEV_EVENT_UNPAIR)
1336                 mlx5e_vport_rep_event_unpair(rep);
1337
1338         return err;
1339 }
1340
1341 static const struct mlx5_eswitch_rep_ops rep_ops = {
1342         .load = mlx5e_vport_rep_load,
1343         .unload = mlx5e_vport_rep_unload,
1344         .get_proto_dev = mlx5e_vport_rep_get_proto_dev,
1345         .event = mlx5e_vport_rep_event,
1346 };
1347
1348 static int mlx5e_rep_probe(struct auxiliary_device *adev,
1349                            const struct auxiliary_device_id *id)
1350 {
1351         struct mlx5_adev *edev = container_of(adev, struct mlx5_adev, adev);
1352         struct mlx5_core_dev *mdev = edev->mdev;
1353         struct mlx5_eswitch *esw;
1354
1355         esw = mdev->priv.eswitch;
1356         mlx5_eswitch_register_vport_reps(esw, &rep_ops, REP_ETH);
1357         return 0;
1358 }
1359
1360 static void mlx5e_rep_remove(struct auxiliary_device *adev)
1361 {
1362         struct mlx5_adev *vdev = container_of(adev, struct mlx5_adev, adev);
1363         struct mlx5_core_dev *mdev = vdev->mdev;
1364         struct mlx5_eswitch *esw;
1365
1366         esw = mdev->priv.eswitch;
1367         mlx5_eswitch_unregister_vport_reps(esw, REP_ETH);
1368 }
1369
1370 static const struct auxiliary_device_id mlx5e_rep_id_table[] = {
1371         { .name = MLX5_ADEV_NAME ".eth-rep", },
1372         {},
1373 };
1374
1375 MODULE_DEVICE_TABLE(auxiliary, mlx5e_rep_id_table);
1376
1377 static struct auxiliary_driver mlx5e_rep_driver = {
1378         .name = "eth-rep",
1379         .probe = mlx5e_rep_probe,
1380         .remove = mlx5e_rep_remove,
1381         .id_table = mlx5e_rep_id_table,
1382 };
1383
1384 int mlx5e_rep_init(void)
1385 {
1386         return auxiliary_driver_register(&mlx5e_rep_driver);
1387 }
1388
1389 void mlx5e_rep_cleanup(void)
1390 {
1391         auxiliary_driver_unregister(&mlx5e_rep_driver);
1392 }