OSDN Git Service

Merge branch 'mlx5-next' of git://git.kernel.org/pub/scm/linux/kernel/git/mellanox...
[uclinux-h8/linux.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 {
256         struct mlx5e_priv *priv = netdev_priv(netdev);
257
258         return mlx5e_ethtool_get_coalesce(priv, coal);
259 }
260
261 static int mlx5e_rep_set_coalesce(struct net_device *netdev,
262                                   struct ethtool_coalesce *coal)
263 {
264         struct mlx5e_priv *priv = netdev_priv(netdev);
265
266         return mlx5e_ethtool_set_coalesce(priv, coal);
267 }
268
269 static u32 mlx5e_rep_get_rxfh_key_size(struct net_device *netdev)
270 {
271         struct mlx5e_priv *priv = netdev_priv(netdev);
272
273         return mlx5e_ethtool_get_rxfh_key_size(priv);
274 }
275
276 static u32 mlx5e_rep_get_rxfh_indir_size(struct net_device *netdev)
277 {
278         struct mlx5e_priv *priv = netdev_priv(netdev);
279
280         return mlx5e_ethtool_get_rxfh_indir_size(priv);
281 }
282
283 static const struct ethtool_ops mlx5e_rep_ethtool_ops = {
284         .supported_coalesce_params = ETHTOOL_COALESCE_USECS |
285                                      ETHTOOL_COALESCE_MAX_FRAMES |
286                                      ETHTOOL_COALESCE_USE_ADAPTIVE,
287         .get_drvinfo       = mlx5e_rep_get_drvinfo,
288         .get_link          = ethtool_op_get_link,
289         .get_strings       = mlx5e_rep_get_strings,
290         .get_sset_count    = mlx5e_rep_get_sset_count,
291         .get_ethtool_stats = mlx5e_rep_get_ethtool_stats,
292         .get_ringparam     = mlx5e_rep_get_ringparam,
293         .set_ringparam     = mlx5e_rep_set_ringparam,
294         .get_channels      = mlx5e_rep_get_channels,
295         .set_channels      = mlx5e_rep_set_channels,
296         .get_coalesce      = mlx5e_rep_get_coalesce,
297         .set_coalesce      = mlx5e_rep_set_coalesce,
298         .get_rxfh_key_size   = mlx5e_rep_get_rxfh_key_size,
299         .get_rxfh_indir_size = mlx5e_rep_get_rxfh_indir_size,
300 };
301
302 static void mlx5e_sqs2vport_stop(struct mlx5_eswitch *esw,
303                                  struct mlx5_eswitch_rep *rep)
304 {
305         struct mlx5e_rep_sq *rep_sq, *tmp;
306         struct mlx5e_rep_priv *rpriv;
307
308         if (esw->mode != MLX5_ESWITCH_OFFLOADS)
309                 return;
310
311         rpriv = mlx5e_rep_to_rep_priv(rep);
312         list_for_each_entry_safe(rep_sq, tmp, &rpriv->vport_sqs_list, list) {
313                 mlx5_eswitch_del_send_to_vport_rule(rep_sq->send_to_vport_rule);
314                 if (rep_sq->send_to_vport_rule_peer)
315                         mlx5_eswitch_del_send_to_vport_rule(rep_sq->send_to_vport_rule_peer);
316                 list_del(&rep_sq->list);
317                 kfree(rep_sq);
318         }
319 }
320
321 static int mlx5e_sqs2vport_start(struct mlx5_eswitch *esw,
322                                  struct mlx5_eswitch_rep *rep,
323                                  u32 *sqns_array, int sqns_num)
324 {
325         struct mlx5_eswitch *peer_esw = NULL;
326         struct mlx5_flow_handle *flow_rule;
327         struct mlx5e_rep_priv *rpriv;
328         struct mlx5e_rep_sq *rep_sq;
329         int err;
330         int i;
331
332         if (esw->mode != MLX5_ESWITCH_OFFLOADS)
333                 return 0;
334
335         rpriv = mlx5e_rep_to_rep_priv(rep);
336         if (mlx5_devcom_is_paired(esw->dev->priv.devcom, MLX5_DEVCOM_ESW_OFFLOADS))
337                 peer_esw = mlx5_devcom_get_peer_data(esw->dev->priv.devcom,
338                                                      MLX5_DEVCOM_ESW_OFFLOADS);
339
340         for (i = 0; i < sqns_num; i++) {
341                 rep_sq = kzalloc(sizeof(*rep_sq), GFP_KERNEL);
342                 if (!rep_sq) {
343                         err = -ENOMEM;
344                         goto out_err;
345                 }
346
347                 /* Add re-inject rule to the PF/representor sqs */
348                 flow_rule = mlx5_eswitch_add_send_to_vport_rule(esw, esw, rep,
349                                                                 sqns_array[i]);
350                 if (IS_ERR(flow_rule)) {
351                         err = PTR_ERR(flow_rule);
352                         kfree(rep_sq);
353                         goto out_err;
354                 }
355                 rep_sq->send_to_vport_rule = flow_rule;
356                 rep_sq->sqn = sqns_array[i];
357
358                 if (peer_esw) {
359                         flow_rule = mlx5_eswitch_add_send_to_vport_rule(peer_esw, esw,
360                                                                         rep, sqns_array[i]);
361                         if (IS_ERR(flow_rule)) {
362                                 err = PTR_ERR(flow_rule);
363                                 mlx5_eswitch_del_send_to_vport_rule(rep_sq->send_to_vport_rule);
364                                 kfree(rep_sq);
365                                 goto out_err;
366                         }
367                         rep_sq->send_to_vport_rule_peer = flow_rule;
368                 }
369
370                 list_add(&rep_sq->list, &rpriv->vport_sqs_list);
371         }
372
373         if (peer_esw)
374                 mlx5_devcom_release_peer_data(esw->dev->priv.devcom, MLX5_DEVCOM_ESW_OFFLOADS);
375
376         return 0;
377
378 out_err:
379         mlx5e_sqs2vport_stop(esw, rep);
380
381         if (peer_esw)
382                 mlx5_devcom_release_peer_data(esw->dev->priv.devcom, MLX5_DEVCOM_ESW_OFFLOADS);
383
384         return err;
385 }
386
387 int mlx5e_add_sqs_fwd_rules(struct mlx5e_priv *priv)
388 {
389         struct mlx5_eswitch *esw = priv->mdev->priv.eswitch;
390         struct mlx5e_rep_priv *rpriv = priv->ppriv;
391         struct mlx5_eswitch_rep *rep = rpriv->rep;
392         struct mlx5e_channel *c;
393         int n, tc, num_sqs = 0;
394         int err = -ENOMEM;
395         u32 *sqs;
396
397         sqs = kcalloc(priv->channels.num * priv->channels.params.num_tc, sizeof(*sqs), GFP_KERNEL);
398         if (!sqs)
399                 goto out;
400
401         for (n = 0; n < priv->channels.num; n++) {
402                 c = priv->channels.c[n];
403                 for (tc = 0; tc < c->num_tc; tc++)
404                         sqs[num_sqs++] = c->sq[tc].sqn;
405         }
406
407         err = mlx5e_sqs2vport_start(esw, rep, sqs, num_sqs);
408         kfree(sqs);
409
410 out:
411         if (err)
412                 netdev_warn(priv->netdev, "Failed to add SQs FWD rules %d\n", err);
413         return err;
414 }
415
416 void mlx5e_remove_sqs_fwd_rules(struct mlx5e_priv *priv)
417 {
418         struct mlx5_eswitch *esw = priv->mdev->priv.eswitch;
419         struct mlx5e_rep_priv *rpriv = priv->ppriv;
420         struct mlx5_eswitch_rep *rep = rpriv->rep;
421
422         mlx5e_sqs2vport_stop(esw, rep);
423 }
424
425 static int mlx5e_rep_open(struct net_device *dev)
426 {
427         struct mlx5e_priv *priv = netdev_priv(dev);
428         struct mlx5e_rep_priv *rpriv = priv->ppriv;
429         struct mlx5_eswitch_rep *rep = rpriv->rep;
430         int err;
431
432         mutex_lock(&priv->state_lock);
433         err = mlx5e_open_locked(dev);
434         if (err)
435                 goto unlock;
436
437         if (!mlx5_modify_vport_admin_state(priv->mdev,
438                                            MLX5_VPORT_STATE_OP_MOD_ESW_VPORT,
439                                            rep->vport, 1,
440                                            MLX5_VPORT_ADMIN_STATE_UP))
441                 netif_carrier_on(dev);
442
443 unlock:
444         mutex_unlock(&priv->state_lock);
445         return err;
446 }
447
448 static int mlx5e_rep_close(struct net_device *dev)
449 {
450         struct mlx5e_priv *priv = netdev_priv(dev);
451         struct mlx5e_rep_priv *rpriv = priv->ppriv;
452         struct mlx5_eswitch_rep *rep = rpriv->rep;
453         int ret;
454
455         mutex_lock(&priv->state_lock);
456         mlx5_modify_vport_admin_state(priv->mdev,
457                                       MLX5_VPORT_STATE_OP_MOD_ESW_VPORT,
458                                       rep->vport, 1,
459                                       MLX5_VPORT_ADMIN_STATE_DOWN);
460         ret = mlx5e_close_locked(dev);
461         mutex_unlock(&priv->state_lock);
462         return ret;
463 }
464
465 bool mlx5e_is_uplink_rep(struct mlx5e_priv *priv)
466 {
467         struct mlx5e_rep_priv *rpriv = priv->ppriv;
468         struct mlx5_eswitch_rep *rep;
469
470         if (!MLX5_ESWITCH_MANAGER(priv->mdev))
471                 return false;
472
473         if (!rpriv) /* non vport rep mlx5e instances don't use this field */
474                 return false;
475
476         rep = rpriv->rep;
477         return (rep->vport == MLX5_VPORT_UPLINK);
478 }
479
480 bool mlx5e_rep_has_offload_stats(const struct net_device *dev, int attr_id)
481 {
482         switch (attr_id) {
483         case IFLA_OFFLOAD_XSTATS_CPU_HIT:
484                         return true;
485         }
486
487         return false;
488 }
489
490 static int
491 mlx5e_get_sw_stats64(const struct net_device *dev,
492                      struct rtnl_link_stats64 *stats)
493 {
494         struct mlx5e_priv *priv = netdev_priv(dev);
495
496         mlx5e_fold_sw_stats64(priv, stats);
497         return 0;
498 }
499
500 int mlx5e_rep_get_offload_stats(int attr_id, const struct net_device *dev,
501                                 void *sp)
502 {
503         switch (attr_id) {
504         case IFLA_OFFLOAD_XSTATS_CPU_HIT:
505                 return mlx5e_get_sw_stats64(dev, sp);
506         }
507
508         return -EINVAL;
509 }
510
511 static void
512 mlx5e_rep_get_stats(struct net_device *dev, struct rtnl_link_stats64 *stats)
513 {
514         struct mlx5e_priv *priv = netdev_priv(dev);
515
516         /* update HW stats in background for next time */
517         mlx5e_queue_update_stats(priv);
518         memcpy(stats, &priv->stats.vf_vport, sizeof(*stats));
519 }
520
521 static int mlx5e_rep_change_mtu(struct net_device *netdev, int new_mtu)
522 {
523         return mlx5e_change_mtu(netdev, new_mtu, NULL);
524 }
525
526 static struct devlink_port *mlx5e_rep_get_devlink_port(struct net_device *netdev)
527 {
528         struct mlx5e_priv *priv = netdev_priv(netdev);
529         struct mlx5e_rep_priv *rpriv = priv->ppriv;
530         struct mlx5_core_dev *dev = priv->mdev;
531
532         return mlx5_esw_offloads_devlink_port(dev->priv.eswitch, rpriv->rep->vport);
533 }
534
535 static int mlx5e_rep_change_carrier(struct net_device *dev, bool new_carrier)
536 {
537         struct mlx5e_priv *priv = netdev_priv(dev);
538         struct mlx5e_rep_priv *rpriv = priv->ppriv;
539         struct mlx5_eswitch_rep *rep = rpriv->rep;
540         int err;
541
542         if (new_carrier) {
543                 err = mlx5_modify_vport_admin_state(priv->mdev, MLX5_VPORT_STATE_OP_MOD_ESW_VPORT,
544                                                     rep->vport, 1, MLX5_VPORT_ADMIN_STATE_UP);
545                 if (err)
546                         return err;
547                 netif_carrier_on(dev);
548         } else {
549                 err = mlx5_modify_vport_admin_state(priv->mdev, MLX5_VPORT_STATE_OP_MOD_ESW_VPORT,
550                                                     rep->vport, 1, MLX5_VPORT_ADMIN_STATE_DOWN);
551                 if (err)
552                         return err;
553                 netif_carrier_off(dev);
554         }
555         return 0;
556 }
557
558 static const struct net_device_ops mlx5e_netdev_ops_rep = {
559         .ndo_open                = mlx5e_rep_open,
560         .ndo_stop                = mlx5e_rep_close,
561         .ndo_start_xmit          = mlx5e_xmit,
562         .ndo_setup_tc            = mlx5e_rep_setup_tc,
563         .ndo_get_devlink_port    = mlx5e_rep_get_devlink_port,
564         .ndo_get_stats64         = mlx5e_rep_get_stats,
565         .ndo_has_offload_stats   = mlx5e_rep_has_offload_stats,
566         .ndo_get_offload_stats   = mlx5e_rep_get_offload_stats,
567         .ndo_change_mtu          = mlx5e_rep_change_mtu,
568         .ndo_change_carrier      = mlx5e_rep_change_carrier,
569 };
570
571 bool mlx5e_eswitch_uplink_rep(const struct net_device *netdev)
572 {
573         return netdev->netdev_ops == &mlx5e_netdev_ops &&
574                mlx5e_is_uplink_rep(netdev_priv(netdev));
575 }
576
577 bool mlx5e_eswitch_vf_rep(const struct net_device *netdev)
578 {
579         return netdev->netdev_ops == &mlx5e_netdev_ops_rep;
580 }
581
582 static void mlx5e_build_rep_params(struct net_device *netdev)
583 {
584         struct mlx5e_priv *priv = netdev_priv(netdev);
585         struct mlx5e_rep_priv *rpriv = priv->ppriv;
586         struct mlx5_eswitch_rep *rep = rpriv->rep;
587         struct mlx5_core_dev *mdev = priv->mdev;
588         struct mlx5e_params *params;
589
590         u8 cq_period_mode = MLX5_CAP_GEN(mdev, cq_period_start_from_cqe) ?
591                                          MLX5_CQ_PERIOD_MODE_START_FROM_CQE :
592                                          MLX5_CQ_PERIOD_MODE_START_FROM_EQE;
593
594         priv->max_nch = mlx5e_calc_max_nch(priv, priv->profile);
595         params = &priv->channels.params;
596
597         params->num_channels = MLX5E_REP_PARAMS_DEF_NUM_CHANNELS;
598         params->hard_mtu    = MLX5E_ETH_HARD_MTU;
599         params->sw_mtu      = netdev->mtu;
600
601         /* SQ */
602         if (rep->vport == MLX5_VPORT_UPLINK)
603                 params->log_sq_size = MLX5E_PARAMS_DEFAULT_LOG_SQ_SIZE;
604         else
605                 params->log_sq_size = MLX5E_REP_PARAMS_DEF_LOG_SQ_SIZE;
606
607         /* RQ */
608         mlx5e_build_rq_params(mdev, params);
609
610         /* CQ moderation params */
611         params->rx_dim_enabled = MLX5_CAP_GEN(mdev, cq_moderation);
612         mlx5e_set_rx_cq_mode_params(params, cq_period_mode);
613
614         params->num_tc                = 1;
615         params->tunneled_offload_en = false;
616
617         mlx5_query_min_inline(mdev, &params->tx_min_inline_mode);
618 }
619
620 static void mlx5e_build_rep_netdev(struct net_device *netdev,
621                                    struct mlx5_core_dev *mdev)
622 {
623         SET_NETDEV_DEV(netdev, mdev->device);
624         netdev->netdev_ops = &mlx5e_netdev_ops_rep;
625         eth_hw_addr_random(netdev);
626         netdev->ethtool_ops = &mlx5e_rep_ethtool_ops;
627
628         netdev->watchdog_timeo    = 15 * HZ;
629
630 #if IS_ENABLED(CONFIG_MLX5_CLS_ACT)
631         netdev->hw_features    |= NETIF_F_HW_TC;
632 #endif
633         netdev->hw_features    |= NETIF_F_SG;
634         netdev->hw_features    |= NETIF_F_IP_CSUM;
635         netdev->hw_features    |= NETIF_F_IPV6_CSUM;
636         netdev->hw_features    |= NETIF_F_GRO;
637         netdev->hw_features    |= NETIF_F_TSO;
638         netdev->hw_features    |= NETIF_F_TSO6;
639         netdev->hw_features    |= NETIF_F_RXCSUM;
640
641         netdev->features |= netdev->hw_features;
642         netdev->features |= NETIF_F_VLAN_CHALLENGED;
643         netdev->features |= NETIF_F_NETNS_LOCAL;
644 }
645
646 static int mlx5e_init_rep(struct mlx5_core_dev *mdev,
647                           struct net_device *netdev)
648 {
649         struct mlx5e_priv *priv = netdev_priv(netdev);
650
651         mlx5e_build_rep_params(netdev);
652         mlx5e_timestamp_init(priv);
653
654         return 0;
655 }
656
657 static int mlx5e_init_ul_rep(struct mlx5_core_dev *mdev,
658                              struct net_device *netdev)
659 {
660         struct mlx5e_priv *priv = netdev_priv(netdev);
661         int err;
662
663         err = mlx5e_ipsec_init(priv);
664         if (err)
665                 mlx5_core_err(mdev, "Uplink rep IPsec initialization failed, %d\n", err);
666
667         mlx5e_vxlan_set_netdev_info(priv);
668         return mlx5e_init_rep(mdev, netdev);
669 }
670
671 static void mlx5e_cleanup_rep(struct mlx5e_priv *priv)
672 {
673         mlx5e_ipsec_cleanup(priv);
674 }
675
676 static int mlx5e_create_rep_ttc_table(struct mlx5e_priv *priv)
677 {
678         struct mlx5e_rep_priv *rpriv = priv->ppriv;
679         struct mlx5_eswitch_rep *rep = rpriv->rep;
680         struct ttc_params ttc_params = {};
681         int err;
682
683         priv->fs.ns = mlx5_get_flow_namespace(priv->mdev,
684                                               MLX5_FLOW_NAMESPACE_KERNEL);
685
686         /* The inner_ttc in the ttc params is intentionally not set */
687         mlx5e_set_ttc_params(priv, &ttc_params, false);
688
689         if (rep->vport != MLX5_VPORT_UPLINK)
690                 /* To give uplik rep TTC a lower level for chaining from root ft */
691                 ttc_params.ft_attr.level = MLX5E_TTC_FT_LEVEL + 1;
692
693         priv->fs.ttc = mlx5_create_ttc_table(priv->mdev, &ttc_params);
694         if (IS_ERR(priv->fs.ttc)) {
695                 err = PTR_ERR(priv->fs.ttc);
696                 netdev_err(priv->netdev, "Failed to create rep ttc table, err=%d\n",
697                            err);
698                 return err;
699         }
700         return 0;
701 }
702
703 static int mlx5e_create_rep_root_ft(struct mlx5e_priv *priv)
704 {
705         struct mlx5e_rep_priv *rpriv = priv->ppriv;
706         struct mlx5_eswitch_rep *rep = rpriv->rep;
707         struct mlx5_flow_table_attr ft_attr = {};
708         struct mlx5_flow_namespace *ns;
709         int err = 0;
710
711         if (rep->vport != MLX5_VPORT_UPLINK) {
712                 /* non uplik reps will skip any bypass tables and go directly to
713                  * their own ttc
714                  */
715                 rpriv->root_ft = mlx5_get_ttc_flow_table(priv->fs.ttc);
716                 return 0;
717         }
718
719         /* uplink root ft will be used to auto chain, to ethtool or ttc tables */
720         ns = mlx5_get_flow_namespace(priv->mdev, MLX5_FLOW_NAMESPACE_OFFLOADS);
721         if (!ns) {
722                 netdev_err(priv->netdev, "Failed to get reps offloads namespace\n");
723                 return -EOPNOTSUPP;
724         }
725
726         ft_attr.max_fte = 0; /* Empty table, miss rule will always point to next table */
727         ft_attr.prio = 1;
728         ft_attr.level = 1;
729
730         rpriv->root_ft = mlx5_create_flow_table(ns, &ft_attr);
731         if (IS_ERR(rpriv->root_ft)) {
732                 err = PTR_ERR(rpriv->root_ft);
733                 rpriv->root_ft = NULL;
734         }
735
736         return err;
737 }
738
739 static void mlx5e_destroy_rep_root_ft(struct mlx5e_priv *priv)
740 {
741         struct mlx5e_rep_priv *rpriv = priv->ppriv;
742         struct mlx5_eswitch_rep *rep = rpriv->rep;
743
744         if (rep->vport != MLX5_VPORT_UPLINK)
745                 return;
746         mlx5_destroy_flow_table(rpriv->root_ft);
747 }
748
749 static int mlx5e_create_rep_vport_rx_rule(struct mlx5e_priv *priv)
750 {
751         struct mlx5_eswitch *esw = priv->mdev->priv.eswitch;
752         struct mlx5e_rep_priv *rpriv = priv->ppriv;
753         struct mlx5_eswitch_rep *rep = rpriv->rep;
754         struct mlx5_flow_handle *flow_rule;
755         struct mlx5_flow_destination dest;
756
757         dest.type = MLX5_FLOW_DESTINATION_TYPE_FLOW_TABLE;
758         dest.ft = rpriv->root_ft;
759
760         flow_rule = mlx5_eswitch_create_vport_rx_rule(esw, rep->vport, &dest);
761         if (IS_ERR(flow_rule))
762                 return PTR_ERR(flow_rule);
763         rpriv->vport_rx_rule = flow_rule;
764         return 0;
765 }
766
767 static void rep_vport_rx_rule_destroy(struct mlx5e_priv *priv)
768 {
769         struct mlx5e_rep_priv *rpriv = priv->ppriv;
770
771         if (!rpriv->vport_rx_rule)
772                 return;
773
774         mlx5_del_flow_rules(rpriv->vport_rx_rule);
775         rpriv->vport_rx_rule = NULL;
776 }
777
778 int mlx5e_rep_bond_update(struct mlx5e_priv *priv, bool cleanup)
779 {
780         rep_vport_rx_rule_destroy(priv);
781
782         return cleanup ? 0 : mlx5e_create_rep_vport_rx_rule(priv);
783 }
784
785 static int mlx5e_init_rep_rx(struct mlx5e_priv *priv)
786 {
787         struct mlx5_core_dev *mdev = priv->mdev;
788         struct mlx5e_lro_param lro_param;
789         int err;
790
791         priv->rx_res = mlx5e_rx_res_alloc();
792         if (!priv->rx_res)
793                 return -ENOMEM;
794
795         mlx5e_init_l2_addr(priv);
796
797         err = mlx5e_open_drop_rq(priv, &priv->drop_rq);
798         if (err) {
799                 mlx5_core_err(mdev, "open drop rq failed, %d\n", err);
800                 return err;
801         }
802
803         lro_param = mlx5e_get_lro_param(&priv->channels.params);
804         err = mlx5e_rx_res_init(priv->rx_res, priv->mdev, 0,
805                                 priv->max_nch, priv->drop_rq.rqn, &lro_param,
806                                 priv->channels.params.num_channels);
807         if (err)
808                 goto err_close_drop_rq;
809
810         err = mlx5e_create_rep_ttc_table(priv);
811         if (err)
812                 goto err_destroy_rx_res;
813
814         err = mlx5e_create_rep_root_ft(priv);
815         if (err)
816                 goto err_destroy_ttc_table;
817
818         err = mlx5e_create_rep_vport_rx_rule(priv);
819         if (err)
820                 goto err_destroy_root_ft;
821
822         mlx5e_ethtool_init_steering(priv);
823
824         return 0;
825
826 err_destroy_root_ft:
827         mlx5e_destroy_rep_root_ft(priv);
828 err_destroy_ttc_table:
829         mlx5_destroy_ttc_table(priv->fs.ttc);
830 err_destroy_rx_res:
831         mlx5e_rx_res_destroy(priv->rx_res);
832 err_close_drop_rq:
833         mlx5e_close_drop_rq(&priv->drop_rq);
834         mlx5e_rx_res_free(priv->rx_res);
835         priv->rx_res = NULL;
836         return err;
837 }
838
839 static void mlx5e_cleanup_rep_rx(struct mlx5e_priv *priv)
840 {
841         mlx5e_ethtool_cleanup_steering(priv);
842         rep_vport_rx_rule_destroy(priv);
843         mlx5e_destroy_rep_root_ft(priv);
844         mlx5_destroy_ttc_table(priv->fs.ttc);
845         mlx5e_rx_res_destroy(priv->rx_res);
846         mlx5e_close_drop_rq(&priv->drop_rq);
847         mlx5e_rx_res_free(priv->rx_res);
848         priv->rx_res = NULL;
849 }
850
851 static int mlx5e_init_ul_rep_rx(struct mlx5e_priv *priv)
852 {
853         mlx5e_create_q_counters(priv);
854         return mlx5e_init_rep_rx(priv);
855 }
856
857 static void mlx5e_cleanup_ul_rep_rx(struct mlx5e_priv *priv)
858 {
859         mlx5e_cleanup_rep_rx(priv);
860         mlx5e_destroy_q_counters(priv);
861 }
862
863 static int mlx5e_init_uplink_rep_tx(struct mlx5e_rep_priv *rpriv)
864 {
865         struct mlx5_rep_uplink_priv *uplink_priv;
866         struct net_device *netdev;
867         struct mlx5e_priv *priv;
868         int err;
869
870         netdev = rpriv->netdev;
871         priv = netdev_priv(netdev);
872         uplink_priv = &rpriv->uplink_priv;
873
874         err = mlx5e_rep_tc_init(rpriv);
875         if (err)
876                 return err;
877
878         mlx5_init_port_tun_entropy(&uplink_priv->tun_entropy, priv->mdev);
879
880         mlx5e_rep_bond_init(rpriv);
881         err = mlx5e_rep_tc_netdevice_event_register(rpriv);
882         if (err) {
883                 mlx5_core_err(priv->mdev, "Failed to register netdev notifier, err: %d\n",
884                               err);
885                 goto err_event_reg;
886         }
887
888         return 0;
889
890 err_event_reg:
891         mlx5e_rep_bond_cleanup(rpriv);
892         mlx5e_rep_tc_cleanup(rpriv);
893         return err;
894 }
895
896 static int mlx5e_init_rep_tx(struct mlx5e_priv *priv)
897 {
898         struct mlx5e_rep_priv *rpriv = priv->ppriv;
899         int err;
900
901         err = mlx5e_create_tises(priv);
902         if (err) {
903                 mlx5_core_warn(priv->mdev, "create tises failed, %d\n", err);
904                 return err;
905         }
906
907         if (rpriv->rep->vport == MLX5_VPORT_UPLINK) {
908                 err = mlx5e_init_uplink_rep_tx(rpriv);
909                 if (err)
910                         goto destroy_tises;
911         }
912
913         return 0;
914
915 destroy_tises:
916         mlx5e_destroy_tises(priv);
917         return err;
918 }
919
920 static void mlx5e_cleanup_uplink_rep_tx(struct mlx5e_rep_priv *rpriv)
921 {
922         mlx5e_rep_tc_netdevice_event_unregister(rpriv);
923         mlx5e_rep_bond_cleanup(rpriv);
924         mlx5e_rep_tc_cleanup(rpriv);
925 }
926
927 static void mlx5e_cleanup_rep_tx(struct mlx5e_priv *priv)
928 {
929         struct mlx5e_rep_priv *rpriv = priv->ppriv;
930
931         mlx5e_destroy_tises(priv);
932
933         if (rpriv->rep->vport == MLX5_VPORT_UPLINK)
934                 mlx5e_cleanup_uplink_rep_tx(rpriv);
935 }
936
937 static void mlx5e_rep_enable(struct mlx5e_priv *priv)
938 {
939         struct mlx5e_rep_priv *rpriv = priv->ppriv;
940
941         mlx5e_set_netdev_mtu_boundaries(priv);
942         mlx5e_rep_neigh_init(rpriv);
943 }
944
945 static void mlx5e_rep_disable(struct mlx5e_priv *priv)
946 {
947         struct mlx5e_rep_priv *rpriv = priv->ppriv;
948
949         mlx5e_rep_neigh_cleanup(rpriv);
950 }
951
952 static int mlx5e_update_rep_rx(struct mlx5e_priv *priv)
953 {
954         return 0;
955 }
956
957 static int uplink_rep_async_event(struct notifier_block *nb, unsigned long event, void *data)
958 {
959         struct mlx5e_priv *priv = container_of(nb, struct mlx5e_priv, events_nb);
960
961         if (event == MLX5_EVENT_TYPE_PORT_CHANGE) {
962                 struct mlx5_eqe *eqe = data;
963
964                 switch (eqe->sub_type) {
965                 case MLX5_PORT_CHANGE_SUBTYPE_DOWN:
966                 case MLX5_PORT_CHANGE_SUBTYPE_ACTIVE:
967                         queue_work(priv->wq, &priv->update_carrier_work);
968                         break;
969                 default:
970                         return NOTIFY_DONE;
971                 }
972
973                 return NOTIFY_OK;
974         }
975
976         if (event == MLX5_DEV_EVENT_PORT_AFFINITY)
977                 return mlx5e_rep_tc_event_port_affinity(priv);
978
979         return NOTIFY_DONE;
980 }
981
982 static void mlx5e_uplink_rep_enable(struct mlx5e_priv *priv)
983 {
984         struct mlx5e_rep_priv *rpriv = priv->ppriv;
985         struct net_device *netdev = priv->netdev;
986         struct mlx5_core_dev *mdev = priv->mdev;
987         u16 max_mtu;
988
989         netdev->min_mtu = ETH_MIN_MTU;
990         mlx5_query_port_max_mtu(priv->mdev, &max_mtu, 1);
991         netdev->max_mtu = MLX5E_HW2SW_MTU(&priv->channels.params, max_mtu);
992         mlx5e_set_dev_port_mtu(priv);
993
994         mlx5e_rep_tc_enable(priv);
995
996         if (MLX5_CAP_GEN(mdev, uplink_follow))
997                 mlx5_modify_vport_admin_state(mdev, MLX5_VPORT_STATE_OP_MOD_UPLINK,
998                                               0, 0, MLX5_VPORT_ADMIN_STATE_AUTO);
999         mlx5_lag_add_netdev(mdev, netdev);
1000         priv->events_nb.notifier_call = uplink_rep_async_event;
1001         mlx5_notifier_register(mdev, &priv->events_nb);
1002         mlx5e_dcbnl_initialize(priv);
1003         mlx5e_dcbnl_init_app(priv);
1004         mlx5e_rep_neigh_init(rpriv);
1005         mlx5e_rep_bridge_init(priv);
1006
1007         netdev->wanted_features |= NETIF_F_HW_TC;
1008
1009         rtnl_lock();
1010         if (netif_running(netdev))
1011                 mlx5e_open(netdev);
1012         netif_device_attach(netdev);
1013         rtnl_unlock();
1014 }
1015
1016 static void mlx5e_uplink_rep_disable(struct mlx5e_priv *priv)
1017 {
1018         struct mlx5e_rep_priv *rpriv = priv->ppriv;
1019         struct mlx5_core_dev *mdev = priv->mdev;
1020
1021         rtnl_lock();
1022         if (netif_running(priv->netdev))
1023                 mlx5e_close(priv->netdev);
1024         netif_device_detach(priv->netdev);
1025         rtnl_unlock();
1026
1027         mlx5e_rep_bridge_cleanup(priv);
1028         mlx5e_rep_neigh_cleanup(rpriv);
1029         mlx5e_dcbnl_delete_app(priv);
1030         mlx5_notifier_unregister(mdev, &priv->events_nb);
1031         mlx5e_rep_tc_disable(priv);
1032         mlx5_lag_remove_netdev(mdev, priv->netdev);
1033 }
1034
1035 static MLX5E_DEFINE_STATS_GRP(sw_rep, 0);
1036 static MLX5E_DEFINE_STATS_GRP(vport_rep, MLX5E_NDO_UPDATE_STATS);
1037
1038 /* The stats groups order is opposite to the update_stats() order calls */
1039 static mlx5e_stats_grp_t mlx5e_rep_stats_grps[] = {
1040         &MLX5E_STATS_GRP(sw_rep),
1041         &MLX5E_STATS_GRP(vport_rep),
1042 };
1043
1044 static unsigned int mlx5e_rep_stats_grps_num(struct mlx5e_priv *priv)
1045 {
1046         return ARRAY_SIZE(mlx5e_rep_stats_grps);
1047 }
1048
1049 /* The stats groups order is opposite to the update_stats() order calls */
1050 static mlx5e_stats_grp_t mlx5e_ul_rep_stats_grps[] = {
1051         &MLX5E_STATS_GRP(sw),
1052         &MLX5E_STATS_GRP(qcnt),
1053         &MLX5E_STATS_GRP(vnic_env),
1054         &MLX5E_STATS_GRP(vport),
1055         &MLX5E_STATS_GRP(802_3),
1056         &MLX5E_STATS_GRP(2863),
1057         &MLX5E_STATS_GRP(2819),
1058         &MLX5E_STATS_GRP(phy),
1059         &MLX5E_STATS_GRP(eth_ext),
1060         &MLX5E_STATS_GRP(pcie),
1061         &MLX5E_STATS_GRP(per_prio),
1062         &MLX5E_STATS_GRP(pme),
1063         &MLX5E_STATS_GRP(channels),
1064         &MLX5E_STATS_GRP(per_port_buff_congest),
1065 };
1066
1067 static unsigned int mlx5e_ul_rep_stats_grps_num(struct mlx5e_priv *priv)
1068 {
1069         return ARRAY_SIZE(mlx5e_ul_rep_stats_grps);
1070 }
1071
1072 static const struct mlx5e_profile mlx5e_rep_profile = {
1073         .init                   = mlx5e_init_rep,
1074         .cleanup                = mlx5e_cleanup_rep,
1075         .init_rx                = mlx5e_init_rep_rx,
1076         .cleanup_rx             = mlx5e_cleanup_rep_rx,
1077         .init_tx                = mlx5e_init_rep_tx,
1078         .cleanup_tx             = mlx5e_cleanup_rep_tx,
1079         .enable                 = mlx5e_rep_enable,
1080         .disable                = mlx5e_rep_disable,
1081         .update_rx              = mlx5e_update_rep_rx,
1082         .update_stats           = mlx5e_stats_update_ndo_stats,
1083         .rx_handlers            = &mlx5e_rx_handlers_rep,
1084         .max_tc                 = 1,
1085         .rq_groups              = MLX5E_NUM_RQ_GROUPS(REGULAR),
1086         .stats_grps             = mlx5e_rep_stats_grps,
1087         .stats_grps_num         = mlx5e_rep_stats_grps_num,
1088         .rx_ptp_support         = false,
1089 };
1090
1091 static const struct mlx5e_profile mlx5e_uplink_rep_profile = {
1092         .init                   = mlx5e_init_ul_rep,
1093         .cleanup                = mlx5e_cleanup_rep,
1094         .init_rx                = mlx5e_init_ul_rep_rx,
1095         .cleanup_rx             = mlx5e_cleanup_ul_rep_rx,
1096         .init_tx                = mlx5e_init_rep_tx,
1097         .cleanup_tx             = mlx5e_cleanup_rep_tx,
1098         .enable                 = mlx5e_uplink_rep_enable,
1099         .disable                = mlx5e_uplink_rep_disable,
1100         .update_rx              = mlx5e_update_rep_rx,
1101         .update_stats           = mlx5e_stats_update_ndo_stats,
1102         .update_carrier         = mlx5e_update_carrier,
1103         .rx_handlers            = &mlx5e_rx_handlers_rep,
1104         .max_tc                 = MLX5E_MAX_NUM_TC,
1105         /* XSK is needed so we can replace profile with NIC netdev */
1106         .rq_groups              = MLX5E_NUM_RQ_GROUPS(XSK),
1107         .stats_grps             = mlx5e_ul_rep_stats_grps,
1108         .stats_grps_num         = mlx5e_ul_rep_stats_grps_num,
1109         .rx_ptp_support         = false,
1110 };
1111
1112 /* e-Switch vport representors */
1113 static int
1114 mlx5e_vport_uplink_rep_load(struct mlx5_core_dev *dev, struct mlx5_eswitch_rep *rep)
1115 {
1116         struct mlx5e_priv *priv = netdev_priv(mlx5_uplink_netdev_get(dev));
1117         struct mlx5e_rep_priv *rpriv = mlx5e_rep_to_rep_priv(rep);
1118         struct devlink_port *dl_port;
1119         int err;
1120
1121         rpriv->netdev = priv->netdev;
1122
1123         err = mlx5e_netdev_change_profile(priv, &mlx5e_uplink_rep_profile,
1124                                           rpriv);
1125         if (err)
1126                 return err;
1127
1128         dl_port = mlx5_esw_offloads_devlink_port(dev->priv.eswitch, rpriv->rep->vport);
1129         if (dl_port)
1130                 devlink_port_type_eth_set(dl_port, rpriv->netdev);
1131
1132         return 0;
1133 }
1134
1135 static void
1136 mlx5e_vport_uplink_rep_unload(struct mlx5e_rep_priv *rpriv)
1137 {
1138         struct net_device *netdev = rpriv->netdev;
1139         struct devlink_port *dl_port;
1140         struct mlx5_core_dev *dev;
1141         struct mlx5e_priv *priv;
1142
1143         priv = netdev_priv(netdev);
1144         dev = priv->mdev;
1145
1146         dl_port = mlx5_esw_offloads_devlink_port(dev->priv.eswitch, rpriv->rep->vport);
1147         if (dl_port)
1148                 devlink_port_type_clear(dl_port);
1149         mlx5e_netdev_attach_nic_profile(priv);
1150 }
1151
1152 static int
1153 mlx5e_vport_vf_rep_load(struct mlx5_core_dev *dev, struct mlx5_eswitch_rep *rep)
1154 {
1155         struct mlx5e_rep_priv *rpriv = mlx5e_rep_to_rep_priv(rep);
1156         const struct mlx5e_profile *profile;
1157         struct devlink_port *dl_port;
1158         struct net_device *netdev;
1159         struct mlx5e_priv *priv;
1160         unsigned int txqs, rxqs;
1161         int nch, err;
1162
1163         profile = &mlx5e_rep_profile;
1164         nch = mlx5e_get_max_num_channels(dev);
1165         txqs = nch * profile->max_tc;
1166         rxqs = nch * profile->rq_groups;
1167         netdev = mlx5e_create_netdev(dev, txqs, rxqs);
1168         if (!netdev) {
1169                 mlx5_core_warn(dev,
1170                                "Failed to create representor netdev for vport %d\n",
1171                                rep->vport);
1172                 return -EINVAL;
1173         }
1174
1175         mlx5e_build_rep_netdev(netdev, dev);
1176         rpriv->netdev = netdev;
1177
1178         priv = netdev_priv(netdev);
1179         priv->profile = profile;
1180         priv->ppriv = rpriv;
1181         err = profile->init(dev, netdev);
1182         if (err) {
1183                 netdev_warn(netdev, "rep profile init failed, %d\n", err);
1184                 goto err_destroy_netdev;
1185         }
1186
1187         err = mlx5e_attach_netdev(netdev_priv(netdev));
1188         if (err) {
1189                 netdev_warn(netdev,
1190                             "Failed to attach representor netdev for vport %d\n",
1191                             rep->vport);
1192                 goto err_cleanup_profile;
1193         }
1194
1195         err = register_netdev(netdev);
1196         if (err) {
1197                 netdev_warn(netdev,
1198                             "Failed to register representor netdev for vport %d\n",
1199                             rep->vport);
1200                 goto err_detach_netdev;
1201         }
1202
1203         dl_port = mlx5_esw_offloads_devlink_port(dev->priv.eswitch, rpriv->rep->vport);
1204         if (dl_port)
1205                 devlink_port_type_eth_set(dl_port, netdev);
1206         return 0;
1207
1208 err_detach_netdev:
1209         mlx5e_detach_netdev(netdev_priv(netdev));
1210
1211 err_cleanup_profile:
1212         priv->profile->cleanup(priv);
1213
1214 err_destroy_netdev:
1215         mlx5e_destroy_netdev(netdev_priv(netdev));
1216         return err;
1217 }
1218
1219 static int
1220 mlx5e_vport_rep_load(struct mlx5_core_dev *dev, struct mlx5_eswitch_rep *rep)
1221 {
1222         struct mlx5e_rep_priv *rpriv;
1223         int err;
1224
1225         rpriv = kzalloc(sizeof(*rpriv), GFP_KERNEL);
1226         if (!rpriv)
1227                 return -ENOMEM;
1228
1229         /* rpriv->rep to be looked up when profile->init() is called */
1230         rpriv->rep = rep;
1231         rep->rep_data[REP_ETH].priv = rpriv;
1232         INIT_LIST_HEAD(&rpriv->vport_sqs_list);
1233
1234         if (rep->vport == MLX5_VPORT_UPLINK)
1235                 err = mlx5e_vport_uplink_rep_load(dev, rep);
1236         else
1237                 err = mlx5e_vport_vf_rep_load(dev, rep);
1238
1239         if (err)
1240                 kfree(rpriv);
1241
1242         return err;
1243 }
1244
1245 static void
1246 mlx5e_vport_rep_unload(struct mlx5_eswitch_rep *rep)
1247 {
1248         struct mlx5e_rep_priv *rpriv = mlx5e_rep_to_rep_priv(rep);
1249         struct net_device *netdev = rpriv->netdev;
1250         struct mlx5e_priv *priv = netdev_priv(netdev);
1251         struct mlx5_core_dev *dev = priv->mdev;
1252         struct devlink_port *dl_port;
1253         void *ppriv = priv->ppriv;
1254
1255         if (rep->vport == MLX5_VPORT_UPLINK) {
1256                 mlx5e_vport_uplink_rep_unload(rpriv);
1257                 goto free_ppriv;
1258         }
1259
1260         dl_port = mlx5_esw_offloads_devlink_port(dev->priv.eswitch, rpriv->rep->vport);
1261         if (dl_port)
1262                 devlink_port_type_clear(dl_port);
1263         unregister_netdev(netdev);
1264         mlx5e_detach_netdev(priv);
1265         priv->profile->cleanup(priv);
1266         mlx5e_destroy_netdev(priv);
1267 free_ppriv:
1268         kfree(ppriv); /* mlx5e_rep_priv */
1269 }
1270
1271 static void *mlx5e_vport_rep_get_proto_dev(struct mlx5_eswitch_rep *rep)
1272 {
1273         struct mlx5e_rep_priv *rpriv;
1274
1275         rpriv = mlx5e_rep_to_rep_priv(rep);
1276
1277         return rpriv->netdev;
1278 }
1279
1280 static void mlx5e_vport_rep_event_unpair(struct mlx5_eswitch_rep *rep)
1281 {
1282         struct mlx5e_rep_priv *rpriv;
1283         struct mlx5e_rep_sq *rep_sq;
1284
1285         rpriv = mlx5e_rep_to_rep_priv(rep);
1286         list_for_each_entry(rep_sq, &rpriv->vport_sqs_list, list) {
1287                 if (!rep_sq->send_to_vport_rule_peer)
1288                         continue;
1289                 mlx5_eswitch_del_send_to_vport_rule(rep_sq->send_to_vport_rule_peer);
1290                 rep_sq->send_to_vport_rule_peer = NULL;
1291         }
1292 }
1293
1294 static int mlx5e_vport_rep_event_pair(struct mlx5_eswitch *esw,
1295                                       struct mlx5_eswitch_rep *rep,
1296                                       struct mlx5_eswitch *peer_esw)
1297 {
1298         struct mlx5_flow_handle *flow_rule;
1299         struct mlx5e_rep_priv *rpriv;
1300         struct mlx5e_rep_sq *rep_sq;
1301
1302         rpriv = mlx5e_rep_to_rep_priv(rep);
1303         list_for_each_entry(rep_sq, &rpriv->vport_sqs_list, list) {
1304                 if (rep_sq->send_to_vport_rule_peer)
1305                         continue;
1306                 flow_rule = mlx5_eswitch_add_send_to_vport_rule(peer_esw, esw, rep, rep_sq->sqn);
1307                 if (IS_ERR(flow_rule))
1308                         goto err_out;
1309                 rep_sq->send_to_vport_rule_peer = flow_rule;
1310         }
1311
1312         return 0;
1313 err_out:
1314         mlx5e_vport_rep_event_unpair(rep);
1315         return PTR_ERR(flow_rule);
1316 }
1317
1318 static int mlx5e_vport_rep_event(struct mlx5_eswitch *esw,
1319                                  struct mlx5_eswitch_rep *rep,
1320                                  enum mlx5_switchdev_event event,
1321                                  void *data)
1322 {
1323         int err = 0;
1324
1325         if (event == MLX5_SWITCHDEV_EVENT_PAIR)
1326                 err = mlx5e_vport_rep_event_pair(esw, rep, data);
1327         else if (event == MLX5_SWITCHDEV_EVENT_UNPAIR)
1328                 mlx5e_vport_rep_event_unpair(rep);
1329
1330         return err;
1331 }
1332
1333 static const struct mlx5_eswitch_rep_ops rep_ops = {
1334         .load = mlx5e_vport_rep_load,
1335         .unload = mlx5e_vport_rep_unload,
1336         .get_proto_dev = mlx5e_vport_rep_get_proto_dev,
1337         .event = mlx5e_vport_rep_event,
1338 };
1339
1340 static int mlx5e_rep_probe(struct auxiliary_device *adev,
1341                            const struct auxiliary_device_id *id)
1342 {
1343         struct mlx5_adev *edev = container_of(adev, struct mlx5_adev, adev);
1344         struct mlx5_core_dev *mdev = edev->mdev;
1345         struct mlx5_eswitch *esw;
1346
1347         esw = mdev->priv.eswitch;
1348         mlx5_eswitch_register_vport_reps(esw, &rep_ops, REP_ETH);
1349         return 0;
1350 }
1351
1352 static void mlx5e_rep_remove(struct auxiliary_device *adev)
1353 {
1354         struct mlx5_adev *vdev = container_of(adev, struct mlx5_adev, adev);
1355         struct mlx5_core_dev *mdev = vdev->mdev;
1356         struct mlx5_eswitch *esw;
1357
1358         esw = mdev->priv.eswitch;
1359         mlx5_eswitch_unregister_vport_reps(esw, REP_ETH);
1360 }
1361
1362 static const struct auxiliary_device_id mlx5e_rep_id_table[] = {
1363         { .name = MLX5_ADEV_NAME ".eth-rep", },
1364         {},
1365 };
1366
1367 MODULE_DEVICE_TABLE(auxiliary, mlx5e_rep_id_table);
1368
1369 static struct auxiliary_driver mlx5e_rep_driver = {
1370         .name = "eth-rep",
1371         .probe = mlx5e_rep_probe,
1372         .remove = mlx5e_rep_remove,
1373         .id_table = mlx5e_rep_id_table,
1374 };
1375
1376 int mlx5e_rep_init(void)
1377 {
1378         return auxiliary_driver_register(&mlx5e_rep_driver);
1379 }
1380
1381 void mlx5e_rep_cleanup(void)
1382 {
1383         auxiliary_driver_unregister(&mlx5e_rep_driver);
1384 }